|
|
|
@ -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]
|
|
|
|
|