From 636896a7fd68266397457db94d26313e4aca4adc Mon Sep 17 00:00:00 2001 From: D4VID Date: Sat, 21 Jun 2025 20:57:14 +0200 Subject: [PATCH] Modded text display --- lwcpu/.cargo/config.toml | 8 ++++ lwcpu/.vscode/settings.json | 5 +++ lwcpu/src/lib.rs | 77 +++++++++++++++++++++++++++++++++++++ test/src/main.rs | 14 ++++++- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 lwcpu/.cargo/config.toml create mode 100644 lwcpu/.vscode/settings.json diff --git a/lwcpu/.cargo/config.toml b/lwcpu/.cargo/config.toml new file mode 100644 index 0000000..6dfb735 --- /dev/null +++ b/lwcpu/.cargo/config.toml @@ -0,0 +1,8 @@ +[build] +target = "riscv32i-unknown-none-elf" + +[target.riscv32i-unknown-none-elf] +rustflags = [ + "-C", "link-arg=-Tmemory.x", + "-C", "link-arg=-Tlink.x", +] diff --git a/lwcpu/.vscode/settings.json b/lwcpu/.vscode/settings.json new file mode 100644 index 0000000..1f30ed8 --- /dev/null +++ b/lwcpu/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.check.allTargets": false, + "rust-analyzer.cargo.allTargets": false, + "rust-analyzer.cargo.target": "riscv32i-unknown-none-elf" +} diff --git a/lwcpu/src/lib.rs b/lwcpu/src/lib.rs index 9a97b27..d220a87 100644 --- a/lwcpu/src/lib.rs +++ b/lwcpu/src/lib.rs @@ -11,6 +11,7 @@ pub const KEYBOARD_OFFSET : u32 = 0x10; pub const CHAR_CONTROL_OFFSET : u32 = 0x20; pub const SCREEN_CONTROL_OFFSET : u32 = 0x22; pub const CHAR_DISPLAY_OFFSET : u32 = 0x24; +pub const TEXT_DISPLAY_OFFSET : u32 = 0x28; // cheeseutil modded display 64x64 characters pub const AUDIO_MAIN_OFFSET : u32 = 0x30; pub const SCREEN_OFFSET : u32 = 0x80; @@ -21,6 +22,7 @@ pub const CHAR_DISPLAY_POINTER : *mut u8 = (BASE_POINTER + CHAR_DISPLAY_OFFSE pub const KEYBOARD_POINTER : *mut u32 = (BASE_POINTER + KEYBOARD_OFFSET) as *mut u32; pub const SCREEN_CONTROL_POINTER : *mut u16 = (BASE_POINTER + SCREEN_CONTROL_OFFSET) as *mut u16; pub const CHAR_CONTROL_POINTER : *mut u16 = (BASE_POINTER + CHAR_CONTROL_OFFSET) as *mut u16; +pub const TEXT_DISPLAY_POINTER : *mut u8 = (BASE_POINTER + TEXT_DISPLAY_OFFSET) as *mut u8; pub const AUDIO_MAIN_POINTER : *mut u32 = (BASE_POINTER + AUDIO_MAIN_OFFSET) as *mut u32; pub const SCREEN_POINTER : *mut u32 = (BASE_POINTER + SCREEN_OFFSET) as *mut u32; @@ -141,6 +143,81 @@ impl core::fmt::Write for CharDisplay { } } +pub struct TextDisplay { + pos: u16 +} +impl TextDisplay { + const CLEAR : u8 = 0b00000001; + const SET_CHAR : u8 = 0b00000010; + const SET_CURSOR : u8 = 0b00000100; + const BLINK : u8 = 0b00001000; + const SCROLL_UP : u8 = 0b00010000; + // const SCROLL_DOWN : u8 = 0b00100000; + // const SCROLL_LEFT : u8 = 0b01000000; + // const SCROLL_RIGHT : u8 = 0b10000000; + + #[inline] + pub fn init(&mut self, blink: bool) { + unsafe { + let control_ptr = TEXT_DISPLAY_POINTER.offset(3); + write_volatile(control_ptr, Self::CLEAR); + match blink { + true => { + write_volatile(control_ptr, Self::BLINK); + }, + false => { + write_volatile(control_ptr, 0); + }, + } + } + } + #[inline] + pub fn put_char(&mut self, ch: u8) { + unsafe { + let control_ptr = TEXT_DISPLAY_POINTER.offset(3); + let control = read_volatile(control_ptr); + + if ch == b'\n' { + if self.pos >= 63*64 { // last row + write_volatile(control_ptr, Self::SCROLL_UP); + write_volatile(control_ptr, control); + } else { + self.pos += 64; // increment row + } + self.pos &= !63u16; // set column to 0 + return; + } + + write_volatile(TEXT_DISPLAY_POINTER as *mut u16, self.pos); + write_volatile(TEXT_DISPLAY_POINTER.offset(2), ch); + write_volatile(control_ptr, Self::SET_CHAR); + write_volatile(control_ptr, control); + + self.pos += 1; + + write_volatile(TEXT_DISPLAY_POINTER as *mut u16, self.pos); + + write_volatile(control_ptr, Self::SET_CURSOR); + write_volatile(control_ptr, control); + } + } +} +impl Default for TextDisplay { + #[inline] + fn default() -> Self { + Self { pos: 0 } + } +} +impl core::fmt::Write for TextDisplay { + #[inline] + fn write_str(&mut self, s: &str) -> core::fmt::Result { + for ch in s.bytes() { + self.put_char(ch); + } + return Ok(()); + } +} + pub struct NumberDisplay {} impl NumberDisplay { #[inline] diff --git a/test/src/main.rs b/test/src/main.rs index e047f3e..ecc4dd0 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -2,7 +2,7 @@ #![no_main] use core::{fmt::Write, panic::PanicInfo, ptr::{read_volatile, write_volatile}}; -use lwcpu::{NumberDisplay, Screen, ScreenMode, CharDisplay, SCREEN_POINTER}; +use lwcpu::{CharDisplay, NumberDisplay, Screen, ScreenMode, TextDisplay, SCREEN_POINTER}; use riscv_rt::entry; #[panic_handler] @@ -16,8 +16,20 @@ fn panic_handler(_info: &PanicInfo) -> ! { const HELLO_WORLD: &str = " Hello world!"; +#[inline(never)] +fn test_text_display() { + let mut text = TextDisplay::default(); + text.init(true); + text.write_str("Lmao yeet\nlook at this!\nI have a text display I can type into.\nSo cool!!!").ok(); + for _ in 0..100 { + text.write_str("aaa\n").ok(); + } +} + #[entry] fn main() -> ! { + test_text_display(); + NumberDisplay::display_number(0); Screen::init(ScreenMode::Buffered); let mut text = CharDisplay{};