forked from koniifer/ableos
Compare commits
7 commits
kodin/keyb
...
master
Author | SHA1 | Date | |
---|---|---|---|
koniifer | a7517005de | ||
koniifer | e3f7a2d455 | ||
koniifer | 19992595fc | ||
koniifer | f7b970eaf0 | ||
koniifer | c752028c73 | ||
koniifer | 8577920d90 | ||
12ee3a9b87 |
592
Cargo.lock
generated
592
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@ kiam = "0.1.1"
|
|||
|
||||
[dependencies.limine]
|
||||
version = "0.1"
|
||||
git = "https://github.com/limine-bootloader/limine-rs"
|
||||
#git = "https://github.com/limine-bootloader/limine-rs"
|
||||
|
||||
[dependencies.crossbeam-queue]
|
||||
version = "0.3"
|
||||
|
|
|
@ -226,6 +226,33 @@ pub fn hardware_random_u64() -> u64 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn hardware_random_u32() -> u32 {
|
||||
use {log::trace, rdrand::RdRand};
|
||||
let gen = RdRand::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u32().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("RDRand not supported.");
|
||||
// Try rdseed
|
||||
let gen = RdSeed::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u32().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("Neither RDRand or RDSeed are supported")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_edid() {}
|
||||
|
||||
pub fn register_dump() {
|
||||
|
|
|
@ -12,7 +12,8 @@ use crate::alloc::string::ToString;
|
|||
|
||||
/// Enumerate PCI devices and run initialisation routines on ones we support
|
||||
pub fn init(device_tree: &mut DeviceTree) {
|
||||
device_tree.devices
|
||||
device_tree
|
||||
.devices
|
||||
.insert("Unidentified PCI".to_string(), alloc::vec![]);
|
||||
let mut devices = alloc::vec![];
|
||||
|
||||
|
@ -23,6 +24,7 @@ pub fn init(device_tree: &mut DeviceTree) {
|
|||
let id = device_info.device_id.id;
|
||||
use Vendor::*;
|
||||
let (dev_type, dev_name) = match (vendor, id) {
|
||||
(VMWareInc, 1029) => ("GPUs", "SVGAII PCI GPU"),
|
||||
(Qemu, 4369) => ("GPUs", "QEMU VGA"),
|
||||
(VirtIO, 4176) => ("GPUs", "VirtIO PCI GPU"),
|
||||
(CirrusLogic, 184) => ("GPUs", "Cirrus SVGA"), //GD 5446?
|
||||
|
@ -269,8 +271,7 @@ impl Display for Vendor {
|
|||
|
||||
use core::fmt::Display;
|
||||
|
||||
use x86_64::instructions::port::Port;
|
||||
use crate::device_tree::DeviceTree;
|
||||
use {crate::device_tree::DeviceTree, x86_64::instructions::port::Port};
|
||||
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
|
|
@ -86,54 +86,94 @@ pub fn handler(vm: &mut Vm) {
|
|||
Ok(_) => {}
|
||||
Err(_) => {}
|
||||
}
|
||||
//
|
||||
}
|
||||
3 => {
|
||||
unsafe fn x86_in(address: u16) -> u8 {
|
||||
x86_64::instructions::port::Port::new(address).read()
|
||||
}
|
||||
unsafe fn x86_in_16(address: u16) -> u16 {
|
||||
x86_64::instructions::port::Port::new(address).read()
|
||||
}
|
||||
unsafe fn x86_in_32(address: u16) -> u32 {
|
||||
x86_64::instructions::port::Port::new(address).read()
|
||||
}
|
||||
unsafe fn x86_out(address: u16, value: u8) {
|
||||
x86_64::instructions::port::Port::new(address).write(value);
|
||||
}
|
||||
unsafe fn x86_out_16(address: u16, value: u16) {
|
||||
x86_64::instructions::port::Port::new(address).write(value);
|
||||
}
|
||||
unsafe fn x86_out_32(address: u16, value: u32) {
|
||||
x86_64::instructions::port::Port::new(address).write(value);
|
||||
}
|
||||
|
||||
let mut msg_vec = block_read(mem_addr, length);
|
||||
let msg_type = msg_vec[0];
|
||||
msg_vec.remove(0);
|
||||
match msg_type {
|
||||
0 => {
|
||||
let mut addr = msg_vec[0] as u16;
|
||||
0 => 'wow: {
|
||||
let size = match msg_vec[0] {
|
||||
0 => 1,
|
||||
1 => 2,
|
||||
2 => 4,
|
||||
_ => {
|
||||
error!("Tried to write more than 32 bits");
|
||||
break 'wow;
|
||||
}
|
||||
};
|
||||
msg_vec.remove(0);
|
||||
|
||||
let addr2 = msg_vec[0] as u16;
|
||||
let addr = u16::from_le_bytes(msg_vec[0..2].try_into().unwrap());
|
||||
msg_vec.remove(0);
|
||||
|
||||
addr = ((addr) << 8) | addr2;
|
||||
|
||||
let value = unsafe { x86_in(addr) };
|
||||
|
||||
msg_vec.remove(0);
|
||||
let value = unsafe {
|
||||
match size {
|
||||
1 => x86_in(addr) as u64,
|
||||
2 => x86_in_16(addr) as u64,
|
||||
4 => x86_in_32(addr) as u64,
|
||||
_ => panic!("how?"),
|
||||
}
|
||||
};
|
||||
msg_vec.clear();
|
||||
trace!("Read the value {} from address {}", value, addr);
|
||||
vm.registers[1] = hbvm::value::Value(value as u64);
|
||||
vm.registers[1] = hbvm::value::Value(value);
|
||||
}
|
||||
1 => {
|
||||
let mut addr = msg_vec[0] as u16;
|
||||
1 => 'wow: {
|
||||
let size = match msg_vec[0] {
|
||||
0 => 1,
|
||||
1 => 2,
|
||||
2 => 4,
|
||||
_ => {
|
||||
error!("Tried to write more than 32 bits");
|
||||
break 'wow;
|
||||
}
|
||||
};
|
||||
msg_vec.remove(0);
|
||||
|
||||
let addr2 = msg_vec[0] as u16;
|
||||
let addr = u16::from_le_bytes(msg_vec[0..2].try_into().unwrap());
|
||||
msg_vec.remove(0);
|
||||
|
||||
addr = ((addr) << 8) | addr2;
|
||||
|
||||
let value = msg_vec[0];
|
||||
msg_vec.remove(0);
|
||||
trace!("Setting the address {} to {}", addr, value);
|
||||
unsafe { x86_out(addr, value) };
|
||||
trace!("Setting address {}", addr);
|
||||
unsafe {
|
||||
match size {
|
||||
1 => x86_out(addr, msg_vec[0]),
|
||||
2 => x86_out_16(
|
||||
addr,
|
||||
u16::from_le_bytes(msg_vec[0..2].try_into().unwrap()),
|
||||
),
|
||||
4 => x86_out_32(
|
||||
addr,
|
||||
u32::from_le_bytes(msg_vec[0..4].try_into().unwrap()),
|
||||
),
|
||||
_ => panic!("How?"),
|
||||
}
|
||||
}
|
||||
msg_vec.clear();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// source of rng
|
||||
4 => {
|
||||
vm.registers[1] = hbvm::value::Value(crate::arch::hardware_random_u64());
|
||||
vm.registers[1] = hbvm::value::Value(crate::arch::hardware_random_u32() as u64);
|
||||
}
|
||||
buffer_id => {
|
||||
let mut buffs = IPC_BUFFERS.lock();
|
||||
|
@ -147,7 +187,7 @@ pub fn handler(vm: &mut Vm) {
|
|||
msg_vec.push(value);
|
||||
}
|
||||
buff.push(msg_vec.clone());
|
||||
info!(
|
||||
debug!(
|
||||
"Message {:?} has been sent to Buffer({})",
|
||||
msg_vec, buffer_id
|
||||
);
|
||||
|
@ -191,7 +231,7 @@ pub fn handler(vm: &mut Vm) {
|
|||
}
|
||||
}
|
||||
|
||||
info!("Recieve {:?} from Buffer({})", msg, buffer_id);
|
||||
debug!("Recieve {:?} from Buffer({})", msg, buffer_id);
|
||||
}
|
||||
}
|
||||
5 => {
|
||||
|
|
|
@ -9,7 +9,11 @@ use {
|
|||
|
||||
pub fn init() -> Result<(), SetLoggerError> {
|
||||
log::set_logger(&crate::logger::Logger)?;
|
||||
log::set_max_level(log::LevelFilter::Debug);
|
||||
if cfg!(debug_assertions) {
|
||||
log::set_max_level(log::LevelFilter::Debug);
|
||||
} else {
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
}
|
||||
|
||||
Lazy::force(&TERMINAL_LOGGER);
|
||||
|
||||
|
|
|
@ -22,10 +22,13 @@ fn main() -> Result<(), Error> {
|
|||
match args.next().as_deref() {
|
||||
Some("build" | "b") => {
|
||||
let mut release = false;
|
||||
let mut debuginfo = false;
|
||||
let mut target = Target::X86_64;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
} else if arg == "-d" || arg == "--debuginfo" {
|
||||
debuginfo = true;
|
||||
} else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
} else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
|
||||
|
@ -35,14 +38,17 @@ fn main() -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
build(release, target).change_context(Error::Build)
|
||||
build(release, target, debuginfo).change_context(Error::Build)
|
||||
}
|
||||
Some("run" | "r") => {
|
||||
let mut release = false;
|
||||
let mut debuginfo = false;
|
||||
let mut target = Target::X86_64;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
} else if arg == "-d" || arg == "--debuginfo" {
|
||||
debuginfo = true;
|
||||
} else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
} else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
|
||||
|
@ -52,7 +58,7 @@ fn main() -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
build(release, target)?;
|
||||
build(release, target, debuginfo)?;
|
||||
run(release, target)
|
||||
}
|
||||
Some("help" | "h") => {
|
||||
|
@ -270,7 +276,7 @@ fn copy_file_to_img(fpath: &str, fs: &FileSystem<File>) {
|
|||
.expect("Copy failed");
|
||||
}
|
||||
|
||||
fn build(release: bool, target: Target) -> Result<(), Error> {
|
||||
fn build(release: bool, target: Target, debuginfo: bool) -> Result<(), Error> {
|
||||
let fs = get_fs().change_context(Error::Io)?;
|
||||
let mut com = Command::new("cargo");
|
||||
com.current_dir("kernel");
|
||||
|
@ -278,6 +284,9 @@ fn build(release: bool, target: Target) -> Result<(), Error> {
|
|||
if release {
|
||||
com.arg("-r");
|
||||
}
|
||||
if debuginfo {
|
||||
com.env("RUSTFLAGS", "-Cdebug-assertions=true");
|
||||
}
|
||||
|
||||
if target == Target::Riscv64Virt {
|
||||
com.args(["--target", "targets/riscv64-virt-ableos.json"]);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
software := @use("rel:software.hb")
|
|
@ -1,16 +0,0 @@
|
|||
.{buffer} := @use("../../stn/src/lib.hb")
|
||||
|
||||
test := fn(): int {
|
||||
buffer_id := buffer.search("XGraphics\0")
|
||||
msg := "\0"
|
||||
buffer.send_message(msg, buffer_id)
|
||||
return 0
|
||||
}
|
||||
|
||||
put_pixel := fn(): int {
|
||||
return 0
|
||||
}
|
||||
|
||||
sync := fn(): int {
|
||||
return 0
|
||||
}
|
|
@ -5,19 +5,19 @@ receive_message := fn(buffer_id: int, memory_map_location: ^u8, length: int): ^u
|
|||
}
|
||||
|
||||
send_message := fn(msg: ^u8, buffer_id: int): void {
|
||||
msg_length := string.length(msg)
|
||||
msg_length := @inline(string.length, msg)
|
||||
@eca(i32, 3, buffer_id, msg, msg_length)
|
||||
return
|
||||
}
|
||||
|
||||
create := fn(msg: ^u8): int {
|
||||
msg_length := string.length(msg);
|
||||
msg_length := @inline(string.length, msg);
|
||||
*msg = 0
|
||||
return @eca(int, 3, 0, msg, msg_length)
|
||||
}
|
||||
|
||||
search := fn(msg: ^u8): int {
|
||||
msg_length := string.length(msg);
|
||||
msg_length := @inline(string.length, msg);
|
||||
*msg = 3
|
||||
|
||||
return @eca(int, 3, 0, msg, msg_length)
|
||||
|
|
|
@ -2,7 +2,7 @@ string := @use("rel:string.hb")
|
|||
buffer := @use("rel:buffer.hb")
|
||||
|
||||
log := fn(message: ^u8, level: u8): void {
|
||||
message_length := string.length(message);
|
||||
message_length := @inline(string.length, message);
|
||||
*(message + message_length) = level
|
||||
@eca(i32, 3, 1, message, message_length + 1)
|
||||
return
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
SIZEOF_INT := 31
|
||||
|
||||
abs := fn(x: int): int {
|
||||
mask := x >> 31
|
||||
mask := x >> SIZEOF_INT
|
||||
return (x ^ mask) - mask
|
||||
}
|
||||
min := fn(a: int, b: int): int {
|
||||
return b + (a - b & a - b >> 31)
|
||||
c := a - b
|
||||
return b + (c & c >> SIZEOF_INT)
|
||||
}
|
||||
max := fn(a: int, b: int): int {
|
||||
c := a - b
|
||||
return a - (c & c >> SIZEOF_INT)
|
||||
}
|
|
@ -17,19 +17,38 @@ release_page := fn(ptr: ^u8, page_count: u8): void {
|
|||
return @eca(void, 3, 2, msg, 12)
|
||||
}
|
||||
|
||||
outb := fn(addr_high: u8, addr_low: u8, value: u8): void {
|
||||
msg := "\0\0\0\0";
|
||||
outb := fn(addr: u16, value: u8): void {
|
||||
msg := "\0\0\0\0\0";
|
||||
*msg = 1;
|
||||
*(msg + 1) = addr_high;
|
||||
*(msg + 2) = addr_low;
|
||||
*(msg + 3) = value
|
||||
@eca(void, 3, 3, msg, 4)
|
||||
*(msg + 1) = 0;
|
||||
*@as(^u16, @bitcast(msg + 2)) = addr;
|
||||
*(msg + 4) = value
|
||||
@eca(void, 3, 3, msg, 5)
|
||||
return
|
||||
}
|
||||
|
||||
inb := fn(addr_high: u8, addr_low: u8): u8 {
|
||||
inb := fn(addr: u16): u8 {
|
||||
msg := "\0\0\0\0";
|
||||
*(msg + 1) = addr_high;
|
||||
*(msg + 2) = addr_low
|
||||
return @eca(u8, 3, 3, msg, 3)
|
||||
*msg = 0;
|
||||
*(msg + 1) = 0;
|
||||
*@as(^u16, @bitcast(msg + 2)) = addr
|
||||
return @eca(u8, 3, 3, msg, 4)
|
||||
}
|
||||
|
||||
outl := fn(addr: u16, value: u32): void {
|
||||
msg := "\0\0\0\0\0\0\0\0";
|
||||
*msg = 1;
|
||||
*(msg + 1) = 2;
|
||||
*@as(^u16, @bitcast(msg + 2)) = addr;
|
||||
*@as(^u32, @bitcast(msg + 4)) = value
|
||||
@eca(void, 3, 3, msg, 8)
|
||||
return
|
||||
}
|
||||
|
||||
inl := fn(addr: u16): u32 {
|
||||
msg := "\0\0\0\0";
|
||||
*msg = 0;
|
||||
*(msg + 1) = 2;
|
||||
*@as(^u16, @bitcast(msg + 2)) = addr
|
||||
return @eca(u32, 3, 3, msg, 4)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
uint_64 := fn(min: uint, max: uint): uint {
|
||||
rng := @eca(uint, 3, 4)
|
||||
integer := fn(min: int, max: int): int {
|
||||
rng := @eca(int, 3, 4)
|
||||
|
||||
if min != 0 | max != 0 {
|
||||
return rng % (max - min + 1) + min
|
||||
|
|
|
@ -1,51 +1,38 @@
|
|||
length := fn(ptr: ^u8): int {
|
||||
len := 0
|
||||
loop if *ptr == 0 break else {
|
||||
len += 1
|
||||
ptr += 1
|
||||
}
|
||||
loop if *(ptr + len) == 0 break else len += 1
|
||||
return len
|
||||
}
|
||||
|
||||
display_int := fn(num: int, p: ^u8): ^u8 {
|
||||
i := 0
|
||||
if num == 0 {
|
||||
set(p, 48)
|
||||
*p = 48
|
||||
return p
|
||||
}
|
||||
loop {
|
||||
if num == 0 break
|
||||
set(p + i, num % 10 + 48)
|
||||
loop if num == 0 break else {
|
||||
*(p + i) = num % 10 + 48
|
||||
num /= 10
|
||||
i += 1
|
||||
}
|
||||
reverse(p)
|
||||
//null terminate
|
||||
set(p + i, 0)
|
||||
@inline(reverse, p);
|
||||
*(p + i) = 0
|
||||
return p
|
||||
}
|
||||
|
||||
reverse := fn(s: ^u8): void {
|
||||
//reverse a string, don't remove digits
|
||||
len := 0
|
||||
loop {
|
||||
if *(s + len) == 0 break
|
||||
len += 1
|
||||
}
|
||||
loop if *(s + len) == 0 break else len += 1
|
||||
i := 0
|
||||
j := len - 1
|
||||
loop {
|
||||
if i >= j break
|
||||
temp := *(s + i);
|
||||
temp := 0
|
||||
loop if i >= j break else {
|
||||
temp = *(s + i);
|
||||
*(s + i) = *(s + j);
|
||||
*(s + j) = temp
|
||||
i += 1
|
||||
j -= 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
set := fn(change: ^u8, new: int): void {
|
||||
*change = new
|
||||
return
|
||||
}
|
|
@ -5,7 +5,7 @@ serial_print := fn(ptr: ^u8): void {
|
|||
letter := 0
|
||||
loop if *ptr == 0 break else {
|
||||
letter = *ptr
|
||||
memory.outb(3, 248, letter)
|
||||
memory.outb(0xF803, letter)
|
||||
ptr += 1
|
||||
}
|
||||
return
|
||||
|
@ -13,8 +13,8 @@ serial_print := fn(ptr: ^u8): void {
|
|||
|
||||
serial_println := fn(ptr: ^u8): void {
|
||||
serial_print(ptr)
|
||||
memory.outb(3, 248, 12)
|
||||
memory.outb(3, 248, 13)
|
||||
memory.outb(0xF803, 12)
|
||||
memory.outb(0xF803, 13)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ main := fn(): int {
|
|||
mem := memory.request_page(1)
|
||||
|
||||
loop {
|
||||
ptr := @eca(int, 4, a, mem, 4096)
|
||||
ptr := @eca(int, 4, a, mem, 0x1000)
|
||||
if ptr == 0 {
|
||||
serial_println("No message\0")
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
stn := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{log, string, memory, buffer} := stn
|
||||
.{memory, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
main := fn(): int {
|
||||
// shuts down ableOS
|
||||
//memory.outb(0, 244, 0)
|
||||
//memory.outb(0xF400, 0)
|
||||
|
||||
a := memory.inb(0, 70)
|
||||
b := memory.inb(0, 71)
|
||||
a := memory.inb(0x4600)
|
||||
b := memory.inb(0x4700)
|
||||
|
||||
c := buffer.search("XNumber\0")
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ LIGHTBLUE := ColorBGRA.{b: 255, g: 0, r: 0, a: 255}
|
|||
LIGHTMAGENTA := ColorBGRA.{b: 255, g: 0, r: 255, a: 255}
|
||||
LIGHTCYAN := ColorBGRA.{b: 255, g: 255, r: 0, a: 255}
|
||||
|
||||
// i have no clue if this works. please don't me ask how it works. -aurlex
|
||||
// i have no clue if this works. please don't me ask how it works. -koniifer
|
||||
blend := fn(fg: ColorBGRA, bg: ColorBGRA): ColorBGRA {
|
||||
s := fg + bg
|
||||
m := s - ((fg ^ bg) & 16843008) & 16843008
|
||||
return (m >> 8 | 16777216 * (s < fg)) * 255 | s - m
|
||||
m := s - ((fg ^ bg) & 0x1010100) & 0x1010100
|
||||
return (m >> 8 | 0x1000000 * (s < fg)) * 0xFF | s - m
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
.{draw_pixel, screenidx, Transform, Point, Rect, Buffer, FB_WIDTH} := @use("rel:lib.hb")
|
||||
ColorBGRA := @use("rel:color.hb").ColorBGRA
|
||||
math := @use("../../../libraries/stn/src/lib.hb").math
|
||||
.{draw_pixel, screenidx, Transform, Point, Rect, Buffer, FB_WIDTH} := @use("rel:lib.hb");
|
||||
.{math} := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{ColorBGRA} := @use("rel:color.hb")
|
||||
|
||||
/* draws a filled rectangle to the screen
|
||||
will be optimised later */
|
||||
rect_fill := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA): void {
|
||||
n := 0
|
||||
loop if n == tr.height * tr.width break else {
|
||||
*(buffer.write + screenidx(.(n % tr.width + pos.x, n / tr.width + pos.y))) = color
|
||||
*(buffer.write + @inline(screenidx, .(n % tr.width + pos.x, n / tr.width + pos.y))) = color
|
||||
n += 1
|
||||
}
|
||||
return
|
||||
|
@ -22,13 +22,13 @@ rect_line := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA, thi
|
|||
y = pos.y
|
||||
x = pos.x
|
||||
loop if y == pos.y + tr.height break else {
|
||||
*(buffer.write + pos.x + t + FB_WIDTH * y) = color;
|
||||
*(buffer.write + pos.x + tr.width - t + FB_WIDTH * y) = color
|
||||
*(buffer.write + @inline(screenidx, .(pos.x + t, y))) = color;
|
||||
*(buffer.write + @inline(screenidx, .(pos.x + tr.width - t, y))) = color
|
||||
y += 1
|
||||
}
|
||||
loop if x == pos.x + tr.width break else {
|
||||
*(buffer.write + x + (pos.y + t) * FB_WIDTH) = color;
|
||||
*(buffer.write + x + (pos.y + tr.height - t) * FB_WIDTH) = color
|
||||
*(buffer.write + @inline(screenidx, .(x, pos.y + t))) = color;
|
||||
*(buffer.write + @inline(screenidx, .(x, pos.y + tr.height - t))) = color
|
||||
x += 1
|
||||
}
|
||||
t += 1
|
||||
|
@ -49,7 +49,7 @@ line_low := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void {
|
|||
y := p0.y
|
||||
x := p0.x
|
||||
loop if x == p1.x break else {
|
||||
*(buffer.write + x + y * FB_WIDTH) = color
|
||||
*(buffer.write + @inline(screenidx, .(x, y))) = color
|
||||
if D > 0 {
|
||||
y += yi
|
||||
D += 2 * (dy - dx)
|
||||
|
@ -73,7 +73,7 @@ line_high := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void {
|
|||
x := p0.x
|
||||
y := p0.y
|
||||
loop if y == p1.y break else {
|
||||
*(buffer.write + x + y * FB_WIDTH) = color
|
||||
*(buffer.write + @inline(screenidx, .(x, y))) = color
|
||||
if D > 0 {
|
||||
x += xi
|
||||
D += 2 * (dx - dy)
|
||||
|
@ -88,17 +88,17 @@ line_high := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void {
|
|||
/* implementation of Bresenham's line algorithm
|
||||
TODO: thickness, might need better math library */
|
||||
line := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA, thickness: int): void {
|
||||
if math.abs(p1.y - p0.y) < math.abs(p1.x - p0.x) {
|
||||
if @inline(math.abs, p1.y - p0.y) < @inline(math.abs, p1.x - p0.x) {
|
||||
if p0.x > p1.x {
|
||||
line_low(buffer, p1, p0, color)
|
||||
@inline(line_low, buffer, p1, p0, color)
|
||||
} else {
|
||||
line_low(buffer, p0, p1, color)
|
||||
@inline(line_low, buffer, p0, p1, color)
|
||||
}
|
||||
} else {
|
||||
if p0.y > p1.y {
|
||||
line_high(buffer, p1, p0, color)
|
||||
@inline(line_high, buffer, p1, p0, color)
|
||||
} else {
|
||||
line_high(buffer, p0, p1, color)
|
||||
@inline(line_high, buffer, p0, p1, color)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
19
sysdata/programs/fb_driver/src/examples/buffers.hb
Normal file
19
sysdata/programs/fb_driver/src/examples/buffers.hb
Normal file
|
@ -0,0 +1,19 @@
|
|||
.{front_buffer_ptr, front_buffer_copy, get_front_buffer, Buffer} := @use("../lib.hb");
|
||||
|
||||
example := fn(): void {
|
||||
// you can get the raw frontbuffer pointer using
|
||||
raw_buffer := front_buffer_ptr
|
||||
// this buffer is the one that you write individual pixels to
|
||||
|
||||
// you can gete the copy frontbuffer pointer using
|
||||
copy_buffer := front_buffer_copy
|
||||
/* this buffer is used for massive writing
|
||||
operations by taking advantage of
|
||||
static copying */
|
||||
|
||||
// you can construct a buffer like so
|
||||
buffer := Buffer.{write: raw_buffer, copy: copy_buffer}
|
||||
// this is the operation that get_front_buffer does
|
||||
same_buffer := get_front_buffer()
|
||||
return
|
||||
}
|
|
@ -12,7 +12,7 @@ example := fn(): void {
|
|||
color := ColorBGRA.(0, 255, 0, 255)
|
||||
/* have to explicitly say 0 is a u8, or we do something crazy to the colors.
|
||||
looks like a compiler bug */
|
||||
n := @as(i8, @as(u8, 0)) - 1
|
||||
n := @as(u8, 0) - 1
|
||||
loop {
|
||||
clear(buffer, color)
|
||||
present(buffer)
|
17
sysdata/programs/fb_driver/src/examples/random.hb
Normal file
17
sysdata/programs/fb_driver/src/examples/random.hb
Normal file
|
@ -0,0 +1,17 @@
|
|||
.{clear, get_front_buffer, screenidx} := @use("../lib.hb");
|
||||
.{ColorBGRA} := @use("../color.hb");
|
||||
.{random} := @use("../../../../libraries/stn/src/lib.hb")
|
||||
|
||||
example := fn(): void {
|
||||
buffer := get_front_buffer()
|
||||
clear(buffer)
|
||||
loop {
|
||||
x := random.integer(0, 1024)
|
||||
y := random.integer(0, 768)
|
||||
r := random.integer(0, 255)
|
||||
g := random.integer(0, 75)
|
||||
b := random.integer(0, 155);
|
||||
*(buffer.write + @inline(screenidx, .(x, y))) = ColorBGRA.(b, g, r, 255)
|
||||
}
|
||||
return
|
||||
}
|
|
@ -1,53 +1,48 @@
|
|||
.{memory, log, math} := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{memory, math} := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{ColorBGRA, blend} := @use("rel:color.hb")
|
||||
|
||||
FB_WIDTH := 1024
|
||||
FB_HEIGHT := 768
|
||||
FB_PIXELS := FB_WIDTH * FB_HEIGHT
|
||||
FB_BYTES := FB_PIXELS << 2
|
||||
// actual enforced max copy size is (1 << 16) - 1, but this was faster
|
||||
MAX_COPY_SIZE := 6144
|
||||
// see stn.math.min, cant use here due to compiler bug (reg id leaked)
|
||||
COPY_PIXELS := MAX_COPY_SIZE + (FB_BYTES - MAX_COPY_SIZE & FB_BYTES - MAX_COPY_SIZE >> 31) >> 2
|
||||
// actual enforced max copy size is 0xFFFF, but this was faster
|
||||
MAX_COPY_SIZE := 0x1800
|
||||
COPY_PIXELS := math.min(MAX_COPY_SIZE, FB_BYTES) >> 2
|
||||
PARTITIONS := FB_PIXELS / COPY_PIXELS
|
||||
TOTAL_PAGES := 1 + FB_BYTES >> 12
|
||||
|
||||
Buffer := struct {write: ^ColorBGRA, copy: ^[ColorBGRA; COPY_PIXELS]}
|
||||
Point := struct {x: int, y: int}
|
||||
Transform := struct {width: int, height: int}
|
||||
Rect := struct {p1: Point, p2: Point}
|
||||
|
||||
front_buffer_ptr := @as(^ColorBGRA, @bitcast(18446603339442421760))
|
||||
front_buffer_ptr := @as(^ColorBGRA, @bitcast(0xFFFF8000C0000000))
|
||||
front_buffer_copy := @as(^[ColorBGRA; COPY_PIXELS], @bitcast(front_buffer_ptr))
|
||||
|
||||
get_front_buffer := fn(): Buffer {
|
||||
// trying to return front_buffer_ptr or front_buffer_copy causes reg id leak
|
||||
return Buffer.{write: @as(^ColorBGRA, @bitcast(18446603339442421760)), copy: @as(^[ColorBGRA; COPY_PIXELS], @bitcast(18446603339442421760))}
|
||||
buffer := Buffer.{write: front_buffer_ptr, copy: front_buffer_copy}
|
||||
return buffer
|
||||
}
|
||||
/* this is separate to create_raw_buffer because returning a Buffer from
|
||||
create_raw_buffer causes reg id leak */
|
||||
create_buffer := fn(): Buffer {
|
||||
ptr := create_raw_buffer()
|
||||
ptr_copy := @as(^[ColorBGRA; COPY_PIXELS], @bitcast(ptr))
|
||||
// same here, bitcasting inside the struct literal causes reg id leak
|
||||
buffer := Buffer.{write: ptr, copy: ptr_copy}
|
||||
ptr := @inline(create_raw_buffer)
|
||||
buffer := Buffer.{write: ptr, copy: @as(^[ColorBGRA; COPY_PIXELS], @bitcast(ptr))}
|
||||
return buffer
|
||||
}
|
||||
create_raw_buffer := fn(): ^ColorBGRA {
|
||||
// helps to trace allocation bugs
|
||||
log.info("Creating buffer. This will allocate.\0")
|
||||
if TOTAL_PAGES <= 255 {
|
||||
return @bitcast(memory.request_page(TOTAL_PAGES))
|
||||
if TOTAL_PAGES <= 0xFF {
|
||||
return @bitcast(@inline(memory.request_page, TOTAL_PAGES))
|
||||
}
|
||||
ptr := memory.request_page(255)
|
||||
remaining := TOTAL_PAGES - 255
|
||||
ptr := @inline(memory.request_page, 255)
|
||||
remaining := TOTAL_PAGES - 0xFF
|
||||
loop if remaining <= 0 break else {
|
||||
if remaining < 255 {
|
||||
if remaining < 0xFF {
|
||||
memory.request_page(remaining)
|
||||
} else {
|
||||
memory.request_page(255)
|
||||
memory.request_page(0xFF)
|
||||
}
|
||||
remaining -= 255
|
||||
remaining -= 0xFF
|
||||
}
|
||||
return @bitcast(ptr)
|
||||
}
|
||||
|
@ -69,11 +64,11 @@ clear := fn(buffer: Buffer, color: ColorBGRA): void {
|
|||
}
|
||||
// only required to be called when using a back buffer. if using single-buffered rendering, do not call this.
|
||||
present := fn(buffer: Buffer): void {
|
||||
offset := 0
|
||||
n := 0
|
||||
// copy chunks of the read buffer to the front buffer
|
||||
loop if offset >= PARTITIONS break else {
|
||||
*(front_buffer_copy + offset) = *(buffer.copy + offset)
|
||||
offset += 1
|
||||
loop if n >= PARTITIONS break else {
|
||||
*(front_buffer_copy + n) = *(buffer.copy + n)
|
||||
n += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -88,13 +83,6 @@ composite := fn(buffer1: Buffer, buffer2: Buffer): void {
|
|||
}
|
||||
return
|
||||
}
|
||||
// really need to be able to inline this please - aurlex
|
||||
screenidx := fn(pos: Point): int {
|
||||
return pos.x + FB_WIDTH * pos.y
|
||||
}
|
||||
point2rect := fn(pos: Point, tr: Transform): Rect {
|
||||
return .(pos, .(pos.x + tr.x, pos.y + tr.y))
|
||||
}
|
||||
rect2point := fn(rect: Rect): struct {point: Point, transform: Transform} {
|
||||
return .(.(0, 0), .(0, 0))
|
||||
}
|
|
@ -1,20 +1,6 @@
|
|||
.{log, memory, string, buffer} := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{front_buffer_ptr, screenidx, ColorBGRA, Point} := @use("./lib.hb")
|
||||
.{example} := @use("./examples/lines.hb")
|
||||
|
||||
main := fn(): int {
|
||||
buffer_id := buffer.create("XGraphics\0")
|
||||
memmap := memory.request_page(1)
|
||||
x := 0
|
||||
loop {
|
||||
msg := buffer.receive_message(buffer_id, memmap, 0)
|
||||
if msg != 0 {
|
||||
log.info("Hello, Framebuffer!\0")
|
||||
}
|
||||
loop if x == 4096 {
|
||||
*(memmap + x) = 0
|
||||
x += 1
|
||||
}
|
||||
x = 0
|
||||
}
|
||||
@inline(example)
|
||||
return 0
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "fb_driver_stresstest"
|
||||
authors = ["aurlex"]
|
||||
|
||||
[dependants.libraries]
|
||||
|
||||
[dependants.binaries]
|
||||
hblang.version = "1.0.0"
|
||||
|
||||
[build]
|
||||
command = "hblang src/main.hb"
|
|
@ -1,19 +0,0 @@
|
|||
.{front_buffer_ptr, front_buffer_copy, get_front_buffer, Buffer} := @use("../lib.hb");
|
||||
|
||||
example := fn(): void {
|
||||
// you can get the raw frontbuffer pointer using
|
||||
raw_buffer := front_buffer_ptr
|
||||
// this buffer is the one that you write individual pixels to
|
||||
|
||||
// you can gete the copy frontbuffer pointer using
|
||||
copy_buffer := copy_buffer_ptr
|
||||
/* this buffer is used for massive writing
|
||||
operations by taking advantage of
|
||||
static copying */
|
||||
|
||||
// you can construct a buffer like so
|
||||
buffer := Buffer.{write: raw_buffer, copy: copy_buffer}
|
||||
// this is the operation that get_front_buffer does
|
||||
same_buffer := get_front_buffer()
|
||||
return
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
.{test, put_pixel, sync} := @use("../../../libraries/render/src/lib.hb").software
|
||||
|
||||
main := fn(): int {
|
||||
test()
|
||||
return 0
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
# PS/2 Driver
|
||||
This program is a simple driver to read keypresses from a PS/2 Keyboard
|
||||
Also will contain an abstraction for the PS/2 controller in general so the Mouse code will probably also live here...maybe
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "ps2_driver"
|
||||
authors = ["Talha Qamar"]
|
||||
|
||||
[dependants.libraries]
|
||||
|
||||
[dependants.binaries]
|
||||
hblang.version = "1.0.0"
|
||||
|
||||
[build]
|
||||
command = "hblang src/main.hb"
|
|
@ -1,97 +0,0 @@
|
|||
.{memory, log, string, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
init := fn(): void {
|
||||
send_byte_to_controller(173)
|
||||
send_byte_to_controller(167)
|
||||
|
||||
// flush output buffer
|
||||
memory.inb(0, 96)
|
||||
|
||||
send_byte_to_controller(32)
|
||||
config_byte := read_byte()
|
||||
log.info("What\0")
|
||||
|
||||
// TODO: We just assume there's a second device here and set up the
|
||||
// controller as such. We should probably look for the second device FIRST
|
||||
// The OSWiki has a page about this
|
||||
// https://wiki.osdev.org/%228042%22_PS/2_Controller#Step_7:_Determine_If_There_Are_2_Channels
|
||||
config_byte &= 32
|
||||
send_byte_to_controller(96)
|
||||
send_byte(config_byte)
|
||||
|
||||
if perform_self_test() {
|
||||
log.info("PS/2 Controller self test successful\0")
|
||||
send_byte_to_controller(171)
|
||||
if read_byte() != 0 {
|
||||
log.error("PS/2 First port test failed\0")
|
||||
}
|
||||
send_byte_to_controller(169)
|
||||
if read_byte() != 0 {
|
||||
log.error("PS/2 Second port test failed\0")
|
||||
}
|
||||
} else {
|
||||
log.error("PS/2 Controller self test failed\0")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
perform_self_test := fn(): bool {
|
||||
send_byte_to_controller(32)
|
||||
config_byte := read_byte()
|
||||
|
||||
send_byte_to_controller(170)
|
||||
response := read_byte()
|
||||
|
||||
send_byte_to_controller(96)
|
||||
send_byte(config_byte)
|
||||
return response == 85
|
||||
}
|
||||
|
||||
send_byte_to_controller := fn(byte: u8): void {
|
||||
loop {
|
||||
status := memory.inb(0, 100)
|
||||
// Bitwise OR with 1011 1111
|
||||
// If the second bit was set in the status register,
|
||||
// status is now equal to 255
|
||||
status |= 191
|
||||
|
||||
if status != 255 {
|
||||
memory.outb(0, 100, byte)
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
send_byte := fn(byte: u8): void {
|
||||
loop {
|
||||
status := memory.inb(0, 100)
|
||||
// Bitwise OR with 1011 1111
|
||||
// If the second bit was set in the status register,
|
||||
// status is now equal to 255
|
||||
status |= 191
|
||||
|
||||
if status != 255 {
|
||||
memory.outb(0, 96, byte)
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
read_byte := fn(): u8 {
|
||||
ptr := memory.request_page(1)
|
||||
loop {
|
||||
status := memory.inb(0, 100)
|
||||
// Bitwise OR with 0111 1111
|
||||
// If the first bit was set in the status register,
|
||||
// status is now equal to 255
|
||||
status |= 127
|
||||
str := string.display_int(status, ptr)
|
||||
log.info(ptr)
|
||||
|
||||
if status == 255 {
|
||||
return memory.inb(0, 96)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
.{memory, log, string, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
controller := @use("./controller.hb")
|
||||
|
||||
main := fn(): int {
|
||||
log.info("PS/2 Driver Loaded\0")
|
||||
controller.init()
|
||||
return 0
|
||||
// if send_byte(238) == 238 {
|
||||
// log.info("PS/2 Keyboard Echoed\0")
|
||||
// }
|
||||
// if send_byte(244) == 250 {
|
||||
// log.info("Enabled scanning\0")
|
||||
// }
|
||||
// buf := buffer.create("XKeyboard\0")
|
||||
// ptr := memory.request_page(1)
|
||||
// prev_input := 250
|
||||
// loop {
|
||||
// input := memory.inb(0, 96)
|
||||
// if input == prev_input {
|
||||
// continue
|
||||
// }
|
||||
// prev_input = input
|
||||
// keycode_str := string.display_int(input, ptr)
|
||||
// log.info(string.display_int(buf))
|
||||
// buffer.send_message(keycode_str, buf)
|
||||
// }
|
||||
// return 0
|
||||
}
|
|
@ -1,14 +1,11 @@
|
|||
stn := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{string, memory, buffer} := stn
|
||||
|
||||
frame_buffer := @as(^u8, @bitcast(18446603339442421760))
|
||||
.{string, memory, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
log_info := fn(): void {
|
||||
a := buffer.search("XNumber\0")
|
||||
if a == 0 {
|
||||
} else {
|
||||
msg := "XABC\0"
|
||||
msg_length := string.length(msg)
|
||||
msg_length := @inline(string.length, msg)
|
||||
@eca(void, 3, a, msg, msg_length)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
stn := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{log, string, memory, buffer} := stn
|
||||
.{log, string, memory, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
service_search := fn(): void {
|
||||
a := "\{01}\0"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "time_driver"
|
||||
authors = ["SamBuckley"]
|
||||
|
||||
[dependants.libraries]
|
||||
|
||||
[dependants.binaries]
|
||||
hblang.version = "1.0.0"
|
||||
|
||||
[build]
|
||||
command = "hblang src/main.hb"
|
|
@ -1,22 +0,0 @@
|
|||
stn := @use("../../../libraries/stn/src/lib.hb")
|
||||
log := stn.log
|
||||
mem := stn.memory
|
||||
s := stn.string
|
||||
page := 0
|
||||
|
||||
main := fn(): void {
|
||||
page += mem.request_page(1)
|
||||
port_str := "\0\0\{47}\0"
|
||||
a := @eca(u8, 3, 3, port_str, 4)
|
||||
|
||||
n := 5000000
|
||||
loop {
|
||||
if n == 0 break
|
||||
n -= 1
|
||||
stack_reclamation_edge_case := 0
|
||||
}
|
||||
td := s.display_int(a, page)
|
||||
log.debug(td)
|
||||
|
||||
return
|
||||
}
|
|
@ -23,9 +23,6 @@ resolution = "1024x768x24"
|
|||
[boot.limine.ableos.modules.a_serial_driver]
|
||||
path = "boot:///a_serial_driver.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.ps2_driver]
|
||||
path = "boot:///ps2_driver.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.diskio_driver]
|
||||
path = "boot:///diskio_driver.hbf"
|
||||
|
||||
|
@ -34,6 +31,3 @@ path = "boot:///fb_driver.hbf"
|
|||
|
||||
[boot.limine.ableos.modules.serial_driver_test]
|
||||
path = "boot:///serial_driver_test.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.fb_driver_stresstest]
|
||||
path = "boot:///fb_driver_stresstest.hbf"
|
Loading…
Reference in a new issue