diff --git a/Cargo.lock b/Cargo.lock index c7b2722..25cd7bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,12 +350,12 @@ checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc2e0cc5b36f84f9d5bb82b6f48e6b29869746d5" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc2e0cc5b36f84f9d5bb82b6f48e6b29869746d5" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" dependencies = [ "hashbrown 0.15.0", "hbbytecode", @@ -367,7 +367,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc2e0cc5b36f84f9d5bb82b6f48e6b29869746d5" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" dependencies = [ "hbbytecode", ] diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs index 8d67692..0d077d3 100644 --- a/kernel/src/holeybytes/ecah.rs +++ b/kernel/src/holeybytes/ecah.rs @@ -97,7 +97,8 @@ pub fn handler(vm: &mut Vm) { match msg_type { 0 => unsafe { let size = msg_vec[1]; - let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); + let addr = + u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked()); let value = match size { 0 => x86_in::(addr) as u64, 1 => x86_in::(addr) as u64, @@ -109,7 +110,8 @@ pub fn handler(vm: &mut Vm) { }, 1 => unsafe { let size = msg_vec[1]; - let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); + let addr = + u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked()); // info!("Setting address {}", addr); match size { @@ -173,7 +175,7 @@ pub fn handler(vm: &mut Vm) { Ok(msg) => msg, Err(_) => return, }; - if msg.len() > max_length.try_into().unwrap() { + if msg.len() > unsafe { max_length.try_into().unwrap_unchecked() } { info!("{}", max_length); error!("Message is too long to map in."); } else { diff --git a/kernel/src/holeybytes/kernel_services/mem_serve.rs b/kernel/src/holeybytes/kernel_services/mem_serve.rs index 935ca9b..f08a81f 100644 --- a/kernel/src/holeybytes/kernel_services/mem_serve.rs +++ b/kernel/src/holeybytes/kernel_services/mem_serve.rs @@ -24,6 +24,75 @@ fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryS Ok(()) } +#[inline(always)] +unsafe fn memcpy(mut dest: *mut u8, mut src: *const u8, mut count: usize) { + if count < 16 { + src.copy_to_nonoverlapping(dest, count); + return; + } + + // let dest_misalignment = dest as usize & 7; + // if dest_misalignment != 0 { + // let align_bytes = 8 - dest_misalignment; + // src.copy_to_nonoverlapping(dest, align_bytes); + // dest = dest.add(align_bytes); + // src = src.add(align_bytes); + // count -= align_bytes; + // } + + while count >= 8 { + if (src as usize) & 7 == 0 && (dest as usize) & 7 == 0 { + *(dest as *mut u64) = *(src as *const u64); + } else { + src.copy_to_nonoverlapping(dest, 8); + } + dest = dest.add(8); + src = src.add(8); + count -= 8; + } + + if count > 0 { + src.copy_to_nonoverlapping(dest, count); + } +} + +#[inline(always)] +unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) { + let mut remaining = count * size; + + if remaining < 16 { + src.copy_to_nonoverlapping(dest, remaining); + return; + } + + let mut buffer = [0u8; 64]; + let mut buffer_size = size; + src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size); + + while buffer_size * 2 <= 64 { + buffer + .as_mut_ptr() + .copy_to_nonoverlapping(buffer.as_mut_ptr().add(buffer_size), buffer_size); + buffer_size *= 2; + } + + let buffer_ptr = buffer.as_ptr() as *const u64; + while remaining >= 8 { + if (dest as usize) & 7 == 0 { + *(dest as *mut u64) = *buffer_ptr; + } else { + buffer.as_ptr().copy_to_nonoverlapping(dest, 8); + } + dest = dest.add(8); + remaining -= 8; + } + + if remaining > 0 { + buffer.as_ptr().copy_to_nonoverlapping(dest, remaining); + } +} + +#[inline(always)] pub fn memory_msg_handler( vm: &mut Vm, mem_addr: u64, @@ -32,40 +101,37 @@ pub fn memory_msg_handler( let msg_vec = block_read(mem_addr, length); let msg_type = msg_vec[0]; match msg_type { - 0 => { + 0 => unsafe { let page_count = msg_vec[1]; let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap(); let mptr: u64 = u64::from_le_bytes(mptr_raw); log::debug!("Allocating {} pages @ {:x}", page_count, mptr); - let ptr = unsafe { - alloc(Layout::from_size_align_unchecked( - page_count as usize * 4096, - 4096, - )) - }; + let ptr = alloc(Layout::from_size_align_unchecked( + page_count as usize * 4096, + 4096, + )); vm.registers[1] = hbvm::value::Value(ptr as u64); log::debug!("Kernel ptr: {:x}", ptr as u64); - } + }, - 1 => { + 1 => unsafe { let page_count = msg_vec[1]; let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap(); let mptr: u64 = u64::from_le_bytes(mptr_raw); log::debug!("Deallocating {} pages @ {:x}", page_count, mptr); - unsafe { - dealloc( - mptr as *mut u8, - Layout::from_size_align_unchecked(page_count as usize * 4096, 4096), - ) - } - } + + dealloc( + mptr as *mut u8, + Layout::from_size_align_unchecked(page_count as usize * 4096, 4096), + ) + }, 2 => { use MemoryQuotaType::*; - let quota_type = match msg_vec[0] { + let quota_type = match msg_vec[1] { 0 => NoQuota, 1 => SoftQuota, 2 => HardQuota, @@ -82,10 +148,25 @@ pub fn memory_msg_handler( ) } 3 => { - let page_count = msg_vec[0]; + let page_count = msg_vec[1]; log::debug!(" {} pages", page_count); } + 4 => unsafe { + let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize; + let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8; + let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8; + memcpy(dest, src, count); + }, + 5 => unsafe { + let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize; + let size = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as usize; + let src = + u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *const u8; + let dest = u64::from_le_bytes(msg_vec[25..33].try_into().unwrap_unchecked()) as *mut u8; + + memset(dest, src, count, size); + }, _ => { log::debug!("Unknown memory service message type: {}", msg_type); } diff --git a/kernel/src/holeybytes/mem.rs b/kernel/src/holeybytes/mem.rs index 79a3614..94d6583 100644 --- a/kernel/src/holeybytes/mem.rs +++ b/kernel/src/holeybytes/mem.rs @@ -37,7 +37,6 @@ impl hbvm::mem::Memory for Memory { target: *mut u8, count: usize, ) -> Result<(), hbvm::mem::LoadError> { - // if addr.get() % 4096 == 0 {} core::ptr::copy_nonoverlapping(addr.get() as *const u8, target, count); Ok(()) } diff --git a/known_bugs.md b/known_bugs.md new file mode 100644 index 0000000..bdb8fca --- /dev/null +++ b/known_bugs.md @@ -0,0 +1,2 @@ +# i did not know where to put this +- memcpy / memset cause crash on debug builds due to ptr misalignment that is not present on release builds \ No newline at end of file diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index 4420c29..9963774 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -395,12 +395,7 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> { "-parallel", "none", "-monitor", "none", "-machine", accel, - "-cpu", - if accel != "accel=tcg" { - "host" - } else { - "Broadwell-v4" - }, + "-cpu", "max", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", ]); } diff --git a/sysdata/libraries/dt_api/README.md b/sysdata/libraries/dt_api/README.md deleted file mode 100644 index 61d4547..0000000 --- a/sysdata/libraries/dt_api/README.md +++ /dev/null @@ -1 +0,0 @@ -# dt_api \ No newline at end of file diff --git a/sysdata/libraries/dt_api/src/lib.hb b/sysdata/libraries/dt_api/src/lib.hb deleted file mode 100644 index 8f2dffe..0000000 --- a/sysdata/libraries/dt_api/src/lib.hb +++ /dev/null @@ -1,6 +0,0 @@ -.{string} := @use("../../stn/src/lib.hb") - -dt_get := fn(query: ^u8): int { - length := string.length(query) - return @eca(3, 5, query, length) -} \ No newline at end of file diff --git a/sysdata/libraries/horizon_api/src/lib.hb b/sysdata/libraries/horizon_api/src/lib.hb index c3a53ff..cc374ca 100644 --- a/sysdata/libraries/horizon_api/src/lib.hb +++ b/sysdata/libraries/horizon_api/src/lib.hb @@ -3,12 +3,16 @@ stn := @use("../../stn/src/lib.hb"); input := @use("../../intouch/src/lib.hb") +widgets := @use("widgets.hb") + WindowID := struct { host_id: int, window_id: int, } -create_window := fn(channel: int): void { +VoidWindowID := WindowID.(0, 0) + +create_window := fn(channel: int): WindowID { // get the horizon buffer // request a new window and provide the callback buffer // wait to recieve a message @@ -16,10 +20,12 @@ create_window := fn(channel: int): void { windowing_system_buffer := buffer.search("XHorizon\0") if windowing_system_buffer == 0 { - return + return VoidWindowID } else { msg := "\{01}\0" msg_length := 2 - return @eca(3, windowing_system_buffer, msg, msg_length) + + @as(void, @eca(3, windowing_system_buffer, msg, msg_length)) + return WindowID.(1, 0) } } \ No newline at end of file diff --git a/sysdata/libraries/horizon_api/src/widgets.hb b/sysdata/libraries/horizon_api/src/widgets.hb new file mode 100644 index 0000000..04574f2 --- /dev/null +++ b/sysdata/libraries/horizon_api/src/widgets.hb @@ -0,0 +1,20 @@ +// Widget types + +// End types + +LayoutChildHorizontalFirst := 0 +LayoutChildVerticalFirst := 1 + +Size := struct { + min_width: int, + max_width: int, + min_height: int, + max_height: int, +} + +Widget := struct { + size: Size, + clickable: bool, + layout: u8, + a: bool, +} \ No newline at end of file diff --git a/sysdata/libraries/ignim/src/application.hb b/sysdata/libraries/ignim/src/application.hb index f3f22d8..4837740 100644 --- a/sysdata/libraries/ignim/src/application.hb +++ b/sysdata/libraries/ignim/src/application.hb @@ -7,7 +7,7 @@ ApplicationInfo := struct { pNext: ^int, application_name: ^u8, application_version: int, - engine_name: int, + engine_name: ^u8, engine_version: int, api_version: int, } diff --git a/sysdata/libraries/intouch/src/keycodes.hb b/sysdata/libraries/intouch/src/keycodes.hb index b5fbc3d..f0273bd 100644 --- a/sysdata/libraries/intouch/src/keycodes.hb +++ b/sysdata/libraries/intouch/src/keycodes.hb @@ -64,4 +64,4 @@ RightSuper := KeyCode.(312) Mode := KeyCode.(313) /* Multi-key compose key */ -Compose := KeyCode.(314) +Compose := KeyCode.(314) \ No newline at end of file diff --git a/sysdata/libraries/render/src/image.hb b/sysdata/libraries/render/src/image.hb new file mode 100644 index 0000000..ee43be2 --- /dev/null +++ b/sysdata/libraries/render/src/image.hb @@ -0,0 +1,51 @@ +.{Color} := @use("./lib.hb"); +.{memory, log} := @use("../../stn/src/lib.hb") + +Image := struct { + buf: ^Color, + width: i32, + height: i32, +} + +BitmapFileHeader := packed struct { + img_type: u16, + size: u32, + reserved_1: u16, + reserved_2: u16, + offset: u32, +} + +BitmapInfoHeader := packed struct { + size: u32, + width: i32, + height: i32, + planes: u16, + bits: u16, + compression: u32, + image_size: u32, + x_resolution: i32, + y_resolution: i32, + n_colours: u32, + important_colours: u32, +} + +BitmapColorHeader := packed struct { + red_mask: u32, + green_mask: u32, + blue_mask: u32, + alpha_mask: u32, + color_space_type: u32, + unused: u32, +} + +from_bmp := fn(bmp: ^u8): Image { + file_header := @as(^BitmapFileHeader, @bitcast(bmp)) + if file_header.img_type != 0x4D42 { + log.error("failed to load bmp image: not a bmp image, idiot\0") + return @as(Image, idk) + } + info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader))) + bmp += file_header.offset + + return .(@bitcast(bmp), @bitcast(info_header.width), @bitcast(info_header.height)) +} \ No newline at end of file diff --git a/sysdata/libraries/render/src/lib.hb b/sysdata/libraries/render/src/lib.hb index 7300319..1162478 100644 --- a/sysdata/libraries/render/src/lib.hb +++ b/sysdata/libraries/render/src/lib.hb @@ -1,5 +1,6 @@ svga := @use("svga.hb") software := @use("software.hb") +image := @use("image.hb") // default mode mode := software @@ -8,23 +9,24 @@ init := mode.init doublebuffer := mode.doublebuffer // Colours -Color := mode.Color -white := mode.white -black := mode.black -gray := mode.gray -red := mode.red -green := mode.green -yellow := mode.yellow -blue := mode.blue -magenta := mode.magenta -cyan := mode.cyan -light_gray := mode.light_gray -light_red := mode.light_red -light_green := mode.light_green -light_yellow := mode.light_yellow -light_blue := mode.light_blue -light_magenta := mode.light_magenta -light_cyan := mode.light_cyan +Color := packed struct {b: u8, g: u8, r: u8, a: u8} +Image := image.Image +white := Color.(255, 255, 255, 255) +black := Color.(0, 0, 0, 255) +gray := Color.(127, 127, 127, 255) +red := Color.(0, 0, 205, 255) +green := Color.(0, 205, 0, 255) +yellow := Color.(0, 205, 205, 255) +blue := Color.(205, 0, 0, 255) +magenta := Color.(205, 0, 205, 255) +cyan := Color.(205, 205, 0, 255) +light_gray := Color.(229, 229, 229, 255) +light_red := Color.(0, 0, 255, 255) +light_green := Color.(0, 255, 0, 255) +light_yellow := Color.(0, 255, 255, 255) +light_blue := Color.(255, 0, 0, 255) +light_magenta := Color.(255, 0, 255, 255) +light_cyan := Color.(255, 255, 0, 255) // Drawing put_pixel := mode.put_pixel @@ -35,7 +37,11 @@ put_line := mode.put_line put_vline := mode.put_vline put_hline := mode.put_hline clear := mode.clear -put_img := mode.put_img +put_image := mode.put_image +// thanks peony for these three! +put_trirect := mode.put_trirect +put_vline := mode.put_vline +put_hline := mode.put_hline // Display width := mode.width @@ -44,10 +50,4 @@ dimensions := mode.dimensions set_height := mode.set_height set_width := mode.set_width set_dimensions := mode.set_dimensions -sync := mode.sync - -// Trash Image -Image := struct { - start: ^Color, - end: ^Color, -} \ No newline at end of file +sync := mode.sync \ No newline at end of file diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb index 87b1bdb..6d13efe 100644 --- a/sysdata/libraries/render/src/software.hb +++ b/sysdata/libraries/render/src/software.hb @@ -1,62 +1,31 @@ -.{math, memory} := @use("../../stn/src/lib.hb"); -.{dt_get} := @use("../../dt_api/src/lib.hb"); -.{Image} := @use("lib.hb"); +.{math, memory, dt} := @use("../../stn/src/lib.hb"); +.{Color, Image} := @use("lib.hb"); .{Vec2} := math -Color := struct {b: u8, g: u8, r: u8, a: u8} -white := Color.(255, 255, 255, 255) -black := Color.(0, 0, 0, 255) -gray := Color.(127, 127, 127, 255) -red := Color.(0, 0, 205, 255) -green := Color.(0, 205, 0, 255) -yellow := Color.(0, 205, 205, 255) -blue := Color.(205, 0, 0, 255) -magenta := Color.(205, 0, 205, 255) -cyan := Color.(205, 205, 0, 255) -light_gray := Color.(229, 229, 229, 255) -light_red := Color.(0, 0, 255, 255) -light_green := Color.(0, 255, 0, 255) -light_yellow := Color.(0, 255, 255, 255) -light_blue := Color.(255, 0, 0, 255) -light_magenta := Color.(255, 0, 255, 255) -light_cyan := Color.(255, 255, 0, 255) - -// might not work for some resolutions, but needs to be comptime because... -copy_pixels := 0xC000 >> 2 - ctx := @as(Context, idk) -// some of these are redudant holdovers from fb_driver -// will keep them for future work if necessary Context := struct { fb: ^Color, bb: ^Color, buf: ^Color, width: int, height: int, - partitions: int, pixels: int, - bb_pages: int, double_buffer: bool, } init := fn(): void { - width := dt_get("framebuffer/fb0/width\0") - height := dt_get("framebuffer/fb0/height\0") + width := dt.get(int, "framebuffer/fb0/width\0") + height := dt.get(int, "framebuffer/fb0/height\0") pixels := width * height - bytes := pixels << 2 - partitions := pixels / copy_pixels - pages := 1 + bytes >> 12 - back_buffer := create_back_buffer(pages) + back_buffer := memory.alloc(Color, pixels * @bitcast(@sizeof(Color))) ctx = Context.{ - fb: dt_get("framebuffer/fb0/ptr\0"), + fb: dt.get(^Color, "framebuffer/fb0/ptr\0"), bb: back_buffer, buf: back_buffer, width, height, - partitions, pixels, - bb_pages: pages, double_buffer: true, } return @@ -72,60 +41,12 @@ doublebuffer := fn(enable: bool): void { return } -create_back_buffer := fn(pages: int): ^Color { - if pages <= 0xFF { - return @bitcast(@inline(memory.request_page, pages)) - } - ptr := @inline(memory.request_page, 255) - remaining := pages - 0xFF - loop if remaining <= 0 break else { - if remaining < 0xFF { - memory.request_page(remaining) - } else { - memory.request_page(0xFF) - } - remaining -= 0xFF - } - return @bitcast(ptr) -} - clear := fn(color: Color): void { - cursor := ctx.buf - boundary := cursor + 512 - loop if cursor == boundary break else { - *cursor = color - cursor += 1 - } - boundary += 512 * 7 - loop if cursor == boundary break else { - *@as(^[Color; 512], @bitcast(cursor)) = *@as(^[Color; 512], @bitcast(ctx.buf)) - cursor += 512 - } - boundary += copy_pixels - 4096 - loop if cursor == boundary break else { - *@as(^[Color; 4096], @bitcast(cursor)) = *@as(^[Color; 4096], @bitcast(ctx.buf)) - cursor += 4096 - } - boundary += (ctx.partitions - 1) * copy_pixels - loop if cursor == boundary break else { - *@as(^[Color; copy_pixels], @bitcast(cursor)) = *@as(^[Color; copy_pixels], @bitcast(ctx.buf)) - cursor += @sizeof([u8; copy_pixels]) - } - return + return @inline(memory.set, Color, &color, ctx.buf, @bitcast(ctx.pixels)) } sync := fn(): void { - if ctx.double_buffer { - bb := ctx.buf - fb := ctx.fb - boundary := bb + ctx.pixels - loop if bb >= boundary break else { - *@as(^[Color; copy_pixels], @bitcast(fb)) = *@as(^[Color; copy_pixels], @bitcast(bb)) - bb += copy_pixels - fb += copy_pixels - } - } - return + return @inline(memory.copy, Color, ctx.buf, ctx.fb, @bitcast(ctx.pixels)) } width := fn(): int { @@ -149,55 +70,31 @@ put_pixel := fn(pos: Vec2(int), color: Color): void { } put_filled_rect := fn(pos: Vec2(int), tr: Vec2(int), color: Color): void { - x := pos.x - y := pos.y - end := pos + tr - loop if x == end.x break else { - loop if y == end.y break else { - *(ctx.buf + @inline(screenidx, x, y)) = color - y += 1 - } - x += 1 - y = pos.y + start_idx := @inline(screenidx, pos.x, pos.y) + end_idx := @inline(screenidx, pos.x, pos.y + tr.y) + + loop if start_idx >= end_idx break else { + @inline(memory.set, Color, &color, ctx.buf + start_idx, @bitcast(tr.x)) + start_idx += ctx.width } + return } put_rect := fn(pos: Vec2(int), tr: Vec2(int), color: Color): void { - x := pos.x - y := pos.y - end := pos + tr - loop if y == end.y break else { - *(ctx.buf + @inline(screenidx, x, y)) = color; - *(ctx.buf + @inline(screenidx, x + tr.x, y)) = color - y += 1 - } - y = pos.y - loop if x == end.x break else { - *(ctx.buf + @inline(screenidx, x, y)) = color; - *(ctx.buf + @inline(screenidx, x, y + tr.y)) = color - x += 1 - } - return -} + start_idx := @inline(screenidx, pos.x, pos.y) + end_idx := @inline(screenidx, pos.x, pos.y + tr.y) + right_start_idx := @inline(screenidx, pos.x + tr.x, pos.y) -put_trirect := fn(pos: Vec2(int), size: Vec2(int), color0: Color, color1: Color): void { - step := Vec2(int).(1, 1) - if size.x < 0 { - step.x = -1 - } - if size.y < 0 { - step.y = size.y / size.x + loop if start_idx > end_idx break else { + *(ctx.buf + start_idx) = color; + *(ctx.buf + right_start_idx) = color + start_idx += ctx.width + right_start_idx += ctx.width } - start_y := pos.y - target := pos + size - - loop if pos.x == target.x break else { - put_vline(pos.x, pos.y, target.y, color0) - put_vline(pos.x, pos.y, start_y, color1) - pos += step - } + @inline(memory.set, Color, &color, ctx.buf + @inline(screenidx, pos.x, pos.y), @bitcast(tr.x + 1)) + @inline(memory.set, Color, &color, ctx.buf + @inline(screenidx, pos.x, pos.y + tr.y), @bitcast(tr.x + 1)) return } @@ -315,6 +212,78 @@ set_dimensions := fn(new: Vec2(int)): void { return } -put_img := fn(img: Image, pos: Vec2(int)): void { +put_image := fn(image: Image, pos: Vec2(int)): void { + // y := 0 + // loop if y == image.height break else { + // @inline(memory.copy, Color, image.buf + y * image.width, ctx.buf + @inline(screenidx, pos.x, pos.y + image.height - y), @intcast(image.width)) + // y += 1 + // } + // return + + start_idx := @inline(screenidx, pos.x, pos.y) + end_idx := @inline(screenidx, pos.x, pos.y + image.height) + cursor := image.width * image.height + + loop if start_idx >= end_idx break else { + @inline(memory.copy, Color, image.buf + cursor, ctx.buf + start_idx, @intcast(image.width)) + start_idx += ctx.width + cursor -= image.width + } + return +} + +// peony-made +put_trirect := fn(pos: Vec2(int), size: Vec2(int), color0: Color, color1: Color): void { + step := Vec2(int).(1, 1) + if size.x < 0 { + step.x = -1 + } + if size.y < 0 { + step.y = size.y / size.x + } + + start_y := pos.y + target := pos + size + + loop if pos.x == target.x break else { + put_vline(pos.x, pos.y, target.y, color0) + @inline(put_vline, pos.x, pos.y, start_y, color1) + pos += step + } + + return +} + +// peony-made +put_vline := fn(x: int, y0: int, y1: int, color: Color): void { + if y1 < y0 { + tmp := y0 + y0 = y1 + y1 = tmp + } + y := y0 + + loop if y == y1 break else { + *(ctx.buf + @inline(screenidx, x, y)) = color + y += 1 + } + + return +} + +// peony-made +put_hline := fn(y: int, x0: int, x1: int, color: Color): void { + if x1 < x0 { + tmp := x0 + x0 = x1 + x1 = tmp + } + x := x0 + + loop if x == x1 break else { + *(ctx.buf + @inline(screenidx, x, y)) = color + x += 1 + } + return } \ No newline at end of file diff --git a/sysdata/libraries/render/src/svga.hb b/sysdata/libraries/render/src/svga.hb index 0790198..033d762 100644 --- a/sysdata/libraries/render/src/svga.hb +++ b/sysdata/libraries/render/src/svga.hb @@ -1,23 +1,5 @@ -.{Vec2, Image} := @use("lib.hb") -// .{pci, memory, string, log} := @use("../../stn/src/lib.hb"); - -Color := struct {b: u8, g: u8, r: u8, a: u8} -white := Color.(255, 255, 255, 255) -black := Color.(0, 0, 0, 255) -gray := Color.(127, 127, 127, 255) -red := Color.(0, 0, 205, 255) -green := Color.(0, 205, 0, 255) -yellow := Color.(0, 205, 205, 255) -blue := Color.(205, 0, 0, 255) -magenta := Color.(205, 0, 205, 255) -cyan := Color.(205, 205, 0, 255) -light_gray := Color.(229, 229, 229, 255) -light_red := Color.(0, 0, 255, 255) -light_green := Color.(0, 255, 0, 255) -light_yellow := Color.(0, 255, 255, 255) -light_blue := Color.(255, 0, 0, 255) -light_magenta := Color.(255, 0, 255, 255) -light_cyan := Color.(255, 255, 0, 255) +.{Vec2} := @use("../../stn/src/lib.hb").math; +.{Image, Color} := @use("lib.hb") clear := fn(color: Color): void { return @@ -79,6 +61,18 @@ init := fn(): void { return } -put_img := fn(img: Image, pos: Vec2(int)): void { +put_image := fn(img: Image, pos: Vec2(int)): void { + return +} + +put_trirect := fn(pos: Vec2(int), size: Vec2(int), color0: Color, color1: Color): void { + return +} + +put_vline := fn(x: int, y0: int, y1: int, color: Color): void { + return +} + +put_hline := fn(y: int, x0: int, x1: int, color: Color): void { return } \ No newline at end of file diff --git a/sysdata/libraries/stn/src/dt.hb b/sysdata/libraries/stn/src/dt.hb new file mode 100644 index 0000000..160d537 --- /dev/null +++ b/sysdata/libraries/stn/src/dt.hb @@ -0,0 +1,5 @@ +.{string} := @use("../../stn/src/lib.hb") + +get := fn($Expr: type, query: ^u8): Expr { + return @eca(3, 5, query, @inline(string.length, query)) +} \ No newline at end of file diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb index 09ff85d..6c67d45 100644 --- a/sysdata/libraries/stn/src/lib.hb +++ b/sysdata/libraries/stn/src/lib.hb @@ -1,9 +1,9 @@ acs := @use("acs.hb") - string := @use("string.hb") log := @use("log.hb") memory := @use("memory.hb") buffer := @use("buffer.hb") math := @use("math.hb") random := @use("random.hb") -file := @use("file_io.hb") \ No newline at end of file +file := @use("file_io.hb") +dt := @use("dt.hb") \ No newline at end of file diff --git a/sysdata/libraries/stn/src/memory.hb b/sysdata/libraries/stn/src/memory.hb index 4cbdd6d..9167b32 100644 --- a/sysdata/libraries/stn/src/memory.hb +++ b/sysdata/libraries/stn/src/memory.hb @@ -1,3 +1,24 @@ +PAGE_SIZE := 4096 +MAX_ALLOC := 0xFF + +alloc := fn($Expr: type, bytes: int): ^Expr { + pages := (1 + bytes) / PAGE_SIZE + if pages <= MAX_ALLOC { + return @bitcast(@inline(request_page, pages)) + } + ptr := @inline(request_page, 0xFF) + remaining := pages - MAX_ALLOC + loop if remaining <= 0 break else { + if remaining < MAX_ALLOC { + request_page(remaining) + } else { + request_page(MAX_ALLOC) + } + remaining -= MAX_ALLOC + } + return @bitcast(ptr) +} + request_page := fn(page_count: u8): ^u8 { msg := "\{00}\{01}xxxxxxxx\0" msg_page_count := msg + 1; @@ -36,4 +57,14 @@ outl := fn(addr: u16, value: u32): void { inl := fn(addr: u16): u32 { return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg)) +} + +CopyMsg := packed struct {a: u8, count: uint, src: uint, dest: ^u8} +copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { + return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg)) +} + +SetMsg := packed struct {a: u8, count: uint, size: uint, src: ^u8, dest: ^u8} +set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { + return @eca(3, 2, &SetMsg.(5, count, @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg)) } \ No newline at end of file diff --git a/sysdata/programs/dt_buffer_test/src/main.hb b/sysdata/programs/dt_buffer_test/src/main.hb index 4d4d14c..ce42ef0 100644 --- a/sysdata/programs/dt_buffer_test/src/main.hb +++ b/sysdata/programs/dt_buffer_test/src/main.hb @@ -1,14 +1,13 @@ -dt_api := @use("../../../libraries/dt_api/src/lib.hb"); -.{dt_get} := dt_api +.{dt} := @use("../../../libraries/stn/src/lib.hb") main := fn(): int { - dt_api.dt_get("framebuffer/fb0/width\0") - dt_api.dt_get("cpu/cpu0/architecture\0") + dt.get(int, "framebuffer/fb0/width\0") + dt.get(int, "cpu/cpu0/architecture\0") // Checking if the first detected serial port is memory mapped or port mapped // 0 -> memory mapped // 1 -> port mapped - dt_get("serial_ports/sp0/mapping\0") + dt.get(int, "serial_ports/sp0/mapping\0") return 0 } \ No newline at end of file diff --git a/sysdata/programs/render_example/src/examples/able.bmp b/sysdata/programs/render_example/src/examples/able.bmp new file mode 100644 index 0000000..7de373d Binary files /dev/null and b/sysdata/programs/render_example/src/examples/able.bmp differ diff --git a/sysdata/programs/render_example/src/examples/image.hb b/sysdata/programs/render_example/src/examples/image.hb new file mode 100644 index 0000000..689fbb7 --- /dev/null +++ b/sysdata/programs/render_example/src/examples/image.hb @@ -0,0 +1,31 @@ +.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math +render := @use("../../../../libraries/render/src/lib.hb") + +/* expected result: + a cute image bounces around the screen */ + +bmp := @embed("./able.bmp") + +example := fn(): void { + render.init() + image := render.image.from_bmp(@bitcast(&bmp)) + vel := Vec2(int).(1, 1) + pos := Vec2(int).(100, 100) + width := render.width() + height := render.height() + loop { + render.put_image(image, pos) + render.sync() + render.clear(render.black) + + if pos.x == 0 | pos.x == width - image.width { + vel.x = -vel.x + } + if pos.y == 0 | pos.y == height - image.height { + vel.y = -vel.y + } + + pos += vel + } + return +} \ No newline at end of file diff --git a/sysdata/programs/render_example/src/examples/mini.bmp b/sysdata/programs/render_example/src/examples/mini.bmp new file mode 100644 index 0000000..7e0b4ce Binary files /dev/null and b/sysdata/programs/render_example/src/examples/mini.bmp differ diff --git a/sysdata/programs/render_example/src/examples/strobe.hb b/sysdata/programs/render_example/src/examples/strobe.hb deleted file mode 100644 index 4681cc5..0000000 --- a/sysdata/programs/render_example/src/examples/strobe.hb +++ /dev/null @@ -1,15 +0,0 @@ -render := @use("../../../../libraries/render/src/lib.hb") - -/* expected result: (EPILEPSY WARNING) - the screen rapidly flashes red then black */ - -example := fn(): void { - render.init() - loop { - render.clear(render.red) - render.sync() - render.clear(render.yellow) - render.sync() - } - return -} \ No newline at end of file diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb index 5d15c24..1ce2d4e 100644 --- a/sysdata/programs/render_example/src/main.hb +++ b/sysdata/programs/render_example/src/main.hb @@ -1,4 +1,4 @@ -.{example} := @use("./examples/tactical_screen.hb") +.{example} := @use("./examples/image.hb") main := fn(): void { @inline(example) diff --git a/sysdata/programs/svga_driver/src/device.hb b/sysdata/programs/svga_driver/src/device.hb index daf98e4..741d9e4 100644 --- a/sysdata/programs/svga_driver/src/device.hb +++ b/sysdata/programs/svga_driver/src/device.hb @@ -2,9 +2,7 @@ stn := @use("../../../libraries/stn/src/lib.hb"); .{string, memory, buffer, log} := stn pci := @use("../../../libraries/pci/src/lib.hb"); -.{PCIAddress, get_ids, config_read32} := pci; - -.{dt_get} := @use("../../../libraries/dt_api/src/lib.hb") +.{PCIAddress, get_ids, config_read32} := pci reg := @use("./reg.hb") diff --git a/sysdata/programs/tetris/meta.toml b/sysdata/programs/tetris/meta.toml deleted file mode 100644 index d2a5f97..0000000 --- a/sysdata/programs/tetris/meta.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "tetris" -authors = ["peony"] - -[dependants.libraries] - -[dependants.binaries] -hblang.version = "1.0.0" - -[build] -command = "hblang src/main.hb" diff --git a/sysdata/programs/tetris/src/main.hb b/sysdata/programs/tetris/src/main.hb index 65aebf3..f4eaa3b 100644 --- a/sysdata/programs/tetris/src/main.hb +++ b/sysdata/programs/tetris/src/main.hb @@ -25,4 +25,4 @@ main := fn(): void { } } return -} \ No newline at end of file +} diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index 48aa105..a3c2ecd 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -6,8 +6,8 @@ verbose = false interface_resolution = "1600x900x24" # interface_resolution = "640x480x32" # Terminal related settings -term_wallpaper = "boot:///background.bmp" -# term_wallpaper = "boot:///empty-background.bmp" +# term_wallpaper = "boot:///background.bmp" +term_wallpaper = "boot:///empty-background.bmp" term_background = "008080" [boot.limine.ableos] @@ -35,11 +35,11 @@ path = "boot:///render_example.hbf" # [boot.limine.ableos.modules.serial_driver_test] # path = "boot:///serial_driver_test.hbf" -# [boot.limine.ableos.modules.horizon] -# path = "boot:///horizon.hbf" +[boot.limine.ableos.modules.horizon] +path = "boot:///horizon.hbf" -# [boot.limine.ableos.modules.horizon_testing_program] -# path = "boot:///horizon_testing_program.hbf" +[boot.limine.ableos.modules.horizon_testing_program] +path = "boot:///horizon_testing_program.hbf" # [boot.limine.ableos.modules.dt_buffer_test] # path = "boot:///dt_buffer_test.hbf"