diff --git a/bench/programs_rust/fpga-lib/src/interface.rs b/bench/programs_rust/fpga-lib/src/interface.rs new file mode 100644 index 0000000..b6e0863 --- /dev/null +++ b/bench/programs_rust/fpga-lib/src/interface.rs @@ -0,0 +1,28 @@ +pub struct Buttons {} + +impl Buttons +{ + pub unsafe fn get_button(button_id: u8) -> bool + { + unsafe { *LED_IP_ADDRESS >> (button_id) & 0b1 == 0b1 } + } +} + +pub struct Leds {} + +impl Leds +{ + pub unsafe fn set_led(led_id: u8, state: bool) + { + if state + { + unsafe { *LED_IP_ADDRESS |= (state as u32) << (led_id + 4) } + } + else + { + unsafe { *LED_IP_ADDRESS &= !((state as u32) << (led_id + 4)) } + } + } +} + +pub const LED_IP_ADDRESS: *mut u32 = 0x30000000 as *mut u32; diff --git a/bench/programs_rust/fpga-lib/src/lib.rs b/bench/programs_rust/fpga-lib/src/lib.rs index 7c3af85..f1124dc 100644 --- a/bench/programs_rust/fpga-lib/src/lib.rs +++ b/bench/programs_rust/fpga-lib/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] +pub mod interface; pub mod register; pub mod vga; @@ -7,8 +8,10 @@ pub mod vga; macro_rules! panic_handler { () => { #[panic_handler] - fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} + fn panic(_info: &core::panic::PanicInfo) -> ! + { + loop + {} } }; } diff --git a/bench/programs_rust/fpga-lib/src/vga.rs b/bench/programs_rust/fpga-lib/src/vga.rs index fbe790c..03b4ff4 100644 --- a/bench/programs_rust/fpga-lib/src/vga.rs +++ b/bench/programs_rust/fpga-lib/src/vga.rs @@ -41,17 +41,14 @@ impl VGA /// # Safety /// `x` must be less than `WIDTH` and `y` must be less than `HEIGHT` - #[inline(never)] pub unsafe fn draw_char(x: u16, y: u16, c: char, color: Color) { let c = if (c as u8 > b'~') || ((c as u8) < b' ') { - unsafe { Self::write_pixel_unsafe(x, y, RED) }; b'/' - b' ' } else { - unsafe { Self::write_pixel_unsafe(x, y, GREEN) }; c as u8 - b' ' }; @@ -66,12 +63,48 @@ impl VGA let xx = x + i; let yy = y + j; - // if xx < (WIDTH as u16) - // && yy < (HEIGHT as u16) - // && unsafe { Self::font_plate_index(char_x as u16 + i, char_y as u16 + j) } - if unsafe { Self::font_plate_index(char_x as u16 + i, char_y as u16 + j) } + if xx < (WIDTH as u16) + && yy < (HEIGHT as u16) + && unsafe { Self::font_plate_index(char_x as u16 + i, char_y as u16 + j) } { - // //unsafe { Self::write_pixel_unsafe(xx, yy, color) } + unsafe { Self::write_pixel_unsafe(xx, yy, color) } + } + } + } + } + + pub unsafe fn draw_char_bg(x: u16, y: u16, c: char, color: Color, bg_color: Color) + { + let c = if (c as u8 > b'~') || ((c as u8) < b' ') + { + b'/' - b' ' + } + else + { + c as u8 - b' ' + }; + + // Get char position within font plate + let char_x = (c as usize % 32) * FONT_WIDTH; + let char_y = (c as usize / 32) * FONT_HEIGHT; + + for i in 0..(FONT_WIDTH as u16) + { + for j in 0..(FONT_HEIGHT as u16) + { + let xx = x + i; + let yy = y + j; + + if xx < (WIDTH as u16) && yy < (HEIGHT as u16) + { + if unsafe { Self::font_plate_index(char_x as u16 + i, char_y as u16 + j) } + { + unsafe { Self::write_pixel_unsafe(xx, yy, color) } + } + else + { + unsafe { Self::write_pixel_unsafe(xx, yy, bg_color) } + } } } } @@ -81,7 +114,7 @@ impl VGA /// The text must have a length that can fit within a `u16` pub unsafe fn draw_string(x: u16, y: u16, str: &str, color: Color) { - str.bytes().enumerate().for_each(|(i, c)| unsafe { + str.chars().enumerate().for_each(|(i, c)| unsafe { Self::draw_char(x + i as u16 * (FONT_WIDTH as u16), y, c as char, color) }); } diff --git a/bench/programs_rust/hello-rust/src/main.rs b/bench/programs_rust/hello-rust/src/main.rs index 2827ebb..85c5ac4 100644 --- a/bench/programs_rust/hello-rust/src/main.rs +++ b/bench/programs_rust/hello-rust/src/main.rs @@ -4,87 +4,39 @@ use core::arch::asm; use fpga_lib::{ + interface::{Buttons, Leds}, panic_handler, register::X31, - vga::{BLUE, FONT_WIDTH, GREEN, RED, VGA, WHITE}, + vga::{BLACK, BLUE, FONT_WIDTH, GREEN, RED, VGA, WHITE}, }; panic_handler! {} -#[inline(never)] -pub fn magic(x: &mut u16, y: &mut u16, z: &mut bool, i: u16, j: u16) -{ - if *x > i && *y < 198 && *z - { - unsafe { VGA::write_pixel_unsafe(i, j, GREEN) }; - } - else - { - unsafe { VGA::write_pixel_unsafe(i, j, RED) }; - } - - //*x += 1; - *y -= 1; -} - #[unsafe(no_mangle)] pub extern "C" fn main() -> ! { - let mut x = core::hint::black_box(100u16); - let mut y = core::hint::black_box(192); - let mut z = core::hint::black_box(true); - - let x = core::hint::black_box(&mut x); - let y = core::hint::black_box(&mut y); - let z = core::hint::black_box(&mut z); - - for i in 0..(*x) - { - magic(x, y, z, i, i); - } - - // if (c as u8 > b'~') || ((c as u8) < b' ') - // { - // X31::write_const::<0x01>(); - // } - // else - // { - // X31::write_const::<0xFFFFFFFFFFFFFFFF>(); - // }; - // - // if (c as u8 > b'~') || ((c as u8) < b' ') - // { - // X31::write_const::<0x01>(); - // } - // else - // { - // X31::write_const::<0xFFFFFFFFFFFFFFFF>(); - // }; - - // for i in 0..100 - // { - // unsafe { VGA::write_pixel_unsafe(i, i, WHITE) }; - // } - // - // let mut a = core::hint::black_box(true); - // let mut x = core::hint::black_box(121); - // let mut y = core::hint::black_box(221); - // for i in 0..100 - // { - // if i < x && i < y && a - // { - // unsafe { - // //VGA::write_pixel_unsafe(i, i, WHITE); - // } - // } - // } - - // let mut a = core::hint::black_box(true); - // if a - // { - // X31::write_const::<0xdead1ffffffff>(); - // } - loop - {} + { + unsafe { + VGA::draw_string(10, 10, "Running RUST !", GREEN); + VGA::draw_string(10, 23, "LedIp state :", RED); + + for i in 0..4 + { + VGA::draw_char(10 + i * 16, 46, 'B', RED); + VGA::draw_char(16 + i * 16, 46, (b'0' + i as u8) as char, RED); + + if Buttons::get_button(i as u8) + { + Leds::set_led(i as u8, true); + VGA::draw_char_bg(10 + i * 16, 59, '1', GREEN, BLACK); + } + else + { + Leds::set_led(i as u8, false); + VGA::draw_char_bg(10 + i * 16, 59, '0', RED, BLACK); + } + } + } + } }