@@ -62,7 +62,48 @@ enum AppEvent {
6262/// The VRAM we share in a very hazardous way with the OS.
6363///
6464/// Big enough for 640x480 @ 256 colour.
65- static mut FRAMEBUFFER : [ u8 ; 307200 ] = [ 0u8 ; 307200 ] ;
65+ // static mut FRAMEBUFFER: [u8; 307200] = [0u8; 307200];
66+ static FRAMEBUFFER : Framebuffer < { 640 * 480 } > = Framebuffer :: new ( ) ;
67+
68+ struct Framebuffer < const N : usize > {
69+ contents : std:: cell:: UnsafeCell < [ u8 ; N ] > ,
70+ }
71+
72+ impl < const N : usize > Framebuffer < N > {
73+ const fn new ( ) -> Framebuffer < N > {
74+ Framebuffer {
75+ contents : std:: cell:: UnsafeCell :: new ( [ 0u8 ; N ] ) ,
76+ }
77+ }
78+
79+ fn write_at ( & self , offset : usize , value : u8 ) {
80+ if offset > std:: mem:: size_of_val ( & self . contents ) {
81+ panic ! ( "Out of bounds framebuffer write" ) ;
82+ }
83+ unsafe {
84+ let array_ptr = self . contents . get ( ) as * mut u8 ;
85+ let byte_ptr = array_ptr. add ( offset) ;
86+ byte_ptr. write_volatile ( value) ;
87+ }
88+ }
89+
90+ fn get_at ( & self , offset : usize ) -> u8 {
91+ if offset > std:: mem:: size_of_val ( & self . contents ) {
92+ panic ! ( "Out of bounds framebuffer read" ) ;
93+ }
94+ unsafe {
95+ let array_ptr = self . contents . get ( ) as * const u8 ;
96+ let byte_ptr = array_ptr. add ( offset) ;
97+ byte_ptr. read_volatile ( )
98+ }
99+ }
100+
101+ fn get_pointer ( & self ) -> * mut u8 {
102+ self . contents . get ( ) as * mut u8
103+ }
104+ }
105+
106+ unsafe impl < const N : usize > Sync for Framebuffer < N > { }
66107
67108/// Scale the display to make it readable on a modern monitor
68109const SCALE_FACTOR : f32 = 2.0 ;
@@ -655,7 +696,7 @@ static EV_QUEUE: std::sync::Mutex<Option<std::sync::mpsc::Receiver<AppEvent>>> =
655696
656697/// The entry point to our program.
657698///
658- /// We set up a game window using ggez . The event loop pumps in this thread.
699+ /// We set up a game window using PixEngine . The event loop pumps in this thread.
659700///
660701/// We then load the OS from the `so` file given, and jump to it in a new thread.
661702fn main ( ) {
@@ -666,13 +707,16 @@ fn main() {
666707
667708 * BOOT_TIME . lock ( ) . unwrap ( ) = Some ( std:: time:: Instant :: now ( ) ) ;
668709
710+ let white_on_black = common:: video:: Attr :: new (
711+ common:: video:: TextForegroundColour :: WHITE ,
712+ common:: video:: TextBackgroundColour :: BLACK ,
713+ false ,
714+ ) ;
669715 for char_idx in 0 ..( 80 * 60 ) {
670- unsafe {
671- // Blank
672- FRAMEBUFFER [ char_idx * 2 ] = b' ' ;
673- // White on Black
674- FRAMEBUFFER [ ( char_idx * 2 ) + 1 ] = 0xF0 ;
675- }
716+ // Blank
717+ FRAMEBUFFER . write_at ( char_idx * 2 , b' ' ) ;
718+ // White on Black
719+ FRAMEBUFFER . write_at ( ( char_idx * 2 ) + 1 , white_on_black. as_u8 ( ) ) ;
676720 }
677721
678722 // Process args
@@ -926,11 +970,9 @@ extern "C" fn video_get_mode() -> common::video::Mode {
926970/// to provide the 'basic' text buffer experience from reserves, so this
927971/// function will never return `null` on start-up.
928972extern "C" fn video_get_framebuffer ( ) -> * mut u8 {
929- unsafe {
930- let p = FRAMEBUFFER . as_mut_ptr ( ) ;
931- debug ! ( "video_get_framebuffer() -> {:p}" , p) ;
932- p
933- }
973+ let p = FRAMEBUFFER . get_pointer ( ) ;
974+ debug ! ( "video_get_framebuffer() -> {:p}" , p) ;
975+ p
934976}
935977
936978/// Set the framebuffer address.
@@ -1022,24 +1064,24 @@ fn convert_keycode(key: Key) -> common::hid::KeyCode {
10221064 match key {
10231065 Key :: Backspace => common:: hid:: KeyCode :: Backspace ,
10241066 Key :: Tab => common:: hid:: KeyCode :: Tab ,
1025- Key :: Return => common:: hid:: KeyCode :: Enter ,
1067+ Key :: Return => common:: hid:: KeyCode :: Return ,
10261068 Key :: Escape => common:: hid:: KeyCode :: Escape ,
10271069 Key :: Space => common:: hid:: KeyCode :: Spacebar ,
10281070 // Key::Exclaim => common::hid::KeyCode::Exclaim,
10291071 // Key::Quotedbl => common::hid::KeyCode::Quotedbl,
1030- // Key::Hash => common::hid::KeyCode::Hash ,
1072+ Key :: Hash => common:: hid:: KeyCode :: Oem7 ,
10311073 // Key::Dollar => common::hid::KeyCode::Dollar,
10321074 // Key::Percent => common::hid::KeyCode::Percent,
10331075 // Key::Ampersand => common::hid::KeyCode::Ampersand,
1034- // Key::Quote => common::hid::KeyCode::Quote ,
1076+ Key :: Quote => common:: hid:: KeyCode :: Oem3 ,
10351077 // Key::LeftParen => common::hid::KeyCode::LeftParen,
10361078 // Key::RightParen => common::hid::KeyCode::RightParen,
10371079 // Key::Asterisk => common::hid::KeyCode::Asterisk,
10381080 // Key::Plus => common::hid::KeyCode::Plus,
1039- Key :: Comma => common:: hid:: KeyCode :: Comma ,
1040- Key :: Minus => common:: hid:: KeyCode :: Minus ,
1041- Key :: Period => common:: hid:: KeyCode :: Fullstop ,
1042- Key :: Slash => common:: hid:: KeyCode :: Slash ,
1081+ Key :: Comma => common:: hid:: KeyCode :: OemComma ,
1082+ Key :: Minus => common:: hid:: KeyCode :: OemMinus ,
1083+ Key :: Period => common:: hid:: KeyCode :: OemPeriod ,
1084+ Key :: Slash => common:: hid:: KeyCode :: Oem2 ,
10431085 Key :: Num0 => common:: hid:: KeyCode :: Key0 ,
10441086 Key :: Num1 => common:: hid:: KeyCode :: Key1 ,
10451087 Key :: Num2 => common:: hid:: KeyCode :: Key2 ,
@@ -1051,18 +1093,18 @@ fn convert_keycode(key: Key) -> common::hid::KeyCode {
10511093 Key :: Num8 => common:: hid:: KeyCode :: Key8 ,
10521094 Key :: Num9 => common:: hid:: KeyCode :: Key9 ,
10531095 // Key::Colon => common::hid::KeyCode::Colon,
1054- Key :: Semicolon => common:: hid:: KeyCode :: SemiColon ,
1096+ Key :: Semicolon => common:: hid:: KeyCode :: Oem1 ,
10551097 // Key::Less => common::hid::KeyCode::Less,
1056- Key :: Equals => common:: hid:: KeyCode :: Equals ,
1098+ Key :: Equals => common:: hid:: KeyCode :: OemPlus ,
10571099 // Key::Greater => common::hid::KeyCode::Greater,
10581100 // Key::Question => common::hid::KeyCode::Question,
10591101 // Key::At => common::hid::KeyCode::At,
1060- // Key::LeftBracket => common::hid::KeyCode::LeftBracket ,
1061- // Key::Backslash => common::hid::KeyCode::Backslash ,
1062- // Key::RightBracket => common::hid::KeyCode::RightBracket ,
1102+ Key :: LeftBracket => common:: hid:: KeyCode :: Oem4 ,
1103+ Key :: Backslash => common:: hid:: KeyCode :: Oem5 ,
1104+ Key :: RightBracket => common:: hid:: KeyCode :: Oem6 ,
10631105 // Key::Caret => common::hid::KeyCode::Caret,
10641106 // Key::Underscore => common::hid::KeyCode::Underscore,
1065- // Key::Backquote => common::hid::KeyCode::Backquote ,
1107+ Key :: Backquote => common:: hid:: KeyCode :: Oem8 ,
10661108 Key :: A => common:: hid:: KeyCode :: A ,
10671109 Key :: B => common:: hid:: KeyCode :: B ,
10681110 Key :: C => common:: hid:: KeyCode :: C ,
@@ -1116,10 +1158,10 @@ fn convert_keycode(key: Key) -> common::hid::KeyCode {
11161158 Key :: Down => common:: hid:: KeyCode :: ArrowDown ,
11171159 Key :: Up => common:: hid:: KeyCode :: ArrowUp ,
11181160 Key :: NumLock => common:: hid:: KeyCode :: NumpadLock ,
1119- Key :: KpDivide => common:: hid:: KeyCode :: NumpadSlash ,
1120- Key :: KpMultiply => common:: hid:: KeyCode :: NumpadStar ,
1121- Key :: KpMinus => common:: hid:: KeyCode :: NumpadMinus ,
1122- Key :: KpPlus => common:: hid:: KeyCode :: NumpadPlus ,
1161+ Key :: KpDivide => common:: hid:: KeyCode :: NumpadDivide ,
1162+ Key :: KpMultiply => common:: hid:: KeyCode :: NumpadMultiply ,
1163+ Key :: KpMinus => common:: hid:: KeyCode :: NumpadSubtract ,
1164+ Key :: KpPlus => common:: hid:: KeyCode :: NumpadAdd ,
11231165 Key :: KpEnter => common:: hid:: KeyCode :: NumpadEnter ,
11241166 Key :: Kp1 => common:: hid:: KeyCode :: Numpad1 ,
11251167 Key :: Kp2 => common:: hid:: KeyCode :: Numpad2 ,
@@ -1134,14 +1176,14 @@ fn convert_keycode(key: Key) -> common::hid::KeyCode {
11341176 Key :: KpPeriod => common:: hid:: KeyCode :: NumpadPeriod ,
11351177 // Key::KpEquals => common::hid::KeyCode::KpEquals,
11361178 // Key::KpComma => common::hid::KeyCode::KpComma,
1137- Key :: LCtrl => common:: hid:: KeyCode :: ControlLeft ,
1138- Key :: LShift => common:: hid:: KeyCode :: ShiftLeft ,
1139- Key :: LAlt => common:: hid:: KeyCode :: AltLeft ,
1140- Key :: LGui => common:: hid:: KeyCode :: WindowsLeft ,
1141- Key :: RCtrl => common:: hid:: KeyCode :: ControlRight ,
1142- Key :: RShift => common:: hid:: KeyCode :: ShiftRight ,
1143- Key :: RAlt => common:: hid:: KeyCode :: AltRight ,
1144- Key :: RGui => common:: hid:: KeyCode :: WindowsRight ,
1179+ Key :: LCtrl => common:: hid:: KeyCode :: LControl ,
1180+ Key :: LShift => common:: hid:: KeyCode :: LShift ,
1181+ Key :: LAlt => common:: hid:: KeyCode :: LAlt ,
1182+ Key :: LGui => common:: hid:: KeyCode :: LWin ,
1183+ Key :: RCtrl => common:: hid:: KeyCode :: RControl ,
1184+ Key :: RShift => common:: hid:: KeyCode :: RShift ,
1185+ Key :: RAlt => common:: hid:: KeyCode :: RAltGr ,
1186+ Key :: RGui => common:: hid:: KeyCode :: RWin ,
11451187 _ => common:: hid:: KeyCode :: X ,
11461188 }
11471189}
@@ -1214,7 +1256,7 @@ unsafe extern "C" fn video_set_whole_palette(
12141256
12151257extern "C" fn i2c_bus_get_info ( _i2c_bus : u8 ) -> common:: Option < common:: i2c:: BusInfo > {
12161258 debug ! ( "i2c_bus_get_info" ) ;
1217- unimplemented ! ( ) ;
1259+ common :: Option :: None
12181260}
12191261
12201262extern "C" fn i2c_write_read (
@@ -1225,69 +1267,68 @@ extern "C" fn i2c_write_read(
12251267 _rx : common:: ApiBuffer ,
12261268) -> common:: Result < ( ) > {
12271269 debug ! ( "i2c_write_read" ) ;
1228- unimplemented ! ( ) ;
1270+ common :: Result :: Err ( common :: Error :: Unimplemented )
12291271}
12301272
12311273extern "C" fn audio_mixer_channel_get_info (
12321274 _audio_mixer_id : u8 ,
1233- ) -> common:: Result < common:: audio:: MixerChannelInfo > {
1275+ ) -> common:: Option < common:: audio:: MixerChannelInfo > {
12341276 debug ! ( "audio_mixer_channel_get_info" ) ;
1235- unimplemented ! ( ) ;
1277+ common :: Option :: None
12361278}
12371279
12381280extern "C" fn audio_mixer_channel_set_level ( _audio_mixer_id : u8 , _level : u8 ) -> common:: Result < ( ) > {
12391281 debug ! ( "audio_mixer_channel_set_level" ) ;
1240- unimplemented ! ( ) ;
1282+ common :: Result :: Err ( common :: Error :: Unimplemented )
12411283}
12421284
12431285extern "C" fn audio_output_set_config ( _config : common:: audio:: Config ) -> common:: Result < ( ) > {
12441286 debug ! ( "audio_output_set_config" ) ;
1245- unimplemented ! ( ) ;
1287+ common :: Result :: Err ( common :: Error :: Unimplemented )
12461288}
12471289
12481290extern "C" fn audio_output_get_config ( ) -> common:: Result < common:: audio:: Config > {
12491291 debug ! ( "audio_output_get_config" ) ;
1250- unimplemented ! ( ) ;
1292+ common :: Result :: Err ( common :: Error :: Unimplemented )
12511293}
12521294
12531295unsafe extern "C" fn audio_output_data ( _samples : common:: ApiByteSlice ) -> common:: Result < usize > {
12541296 debug ! ( "audio_output_data" ) ;
1255- unimplemented ! ( ) ;
1297+ common :: Result :: Err ( common :: Error :: Unimplemented )
12561298}
12571299
12581300extern "C" fn audio_output_get_space ( ) -> common:: Result < usize > {
12591301 debug ! ( "audio_output_get_space" ) ;
1260- unimplemented ! ( ) ;
1302+ common :: Result :: Err ( common :: Error :: Unimplemented )
12611303}
12621304
12631305extern "C" fn audio_input_set_config ( _config : common:: audio:: Config ) -> common:: Result < ( ) > {
12641306 debug ! ( "audio_input_set_config" ) ;
1265- unimplemented ! ( ) ;
1307+ common :: Result :: Err ( common :: Error :: Unimplemented )
12661308}
12671309
12681310extern "C" fn audio_input_get_config ( ) -> common:: Result < common:: audio:: Config > {
12691311 debug ! ( "audio_input_get_config" ) ;
1270- unimplemented ! ( ) ;
1312+ common :: Result :: Err ( common :: Error :: Unimplemented )
12711313}
12721314
12731315extern "C" fn audio_input_data ( _samples : common:: ApiBuffer ) -> common:: Result < usize > {
12741316 debug ! ( "audio_input_data" ) ;
1275- unimplemented ! ( ) ;
1317+ common :: Result :: Err ( common :: Error :: Unimplemented )
12761318}
12771319
12781320extern "C" fn audio_input_get_count ( ) -> common:: Result < usize > {
12791321 debug ! ( "audio_input_get_count" ) ;
1280- unimplemented ! ( ) ;
1322+ common :: Result :: Err ( common :: Error :: Unimplemented )
12811323}
12821324
12831325extern "C" fn bus_select ( _periperal_id : common:: Option < u8 > ) {
12841326 debug ! ( "bus_select" ) ;
1285- unimplemented ! ( ) ;
12861327}
12871328
12881329extern "C" fn bus_get_info ( _periperal_id : u8 ) -> common:: Option < common:: bus:: PeripheralInfo > {
12891330 debug ! ( "bus_get_info" ) ;
1290- unimplemented ! ( ) ;
1331+ common :: Option :: None
12911332}
12921333
12931334extern "C" fn bus_write_read (
@@ -1296,12 +1337,12 @@ extern "C" fn bus_write_read(
12961337 _rx : common:: ApiBuffer ,
12971338) -> common:: Result < ( ) > {
12981339 debug ! ( "bus_write_read" ) ;
1299- unimplemented ! ( ) ;
1340+ common :: Result :: Err ( common :: Error :: Unimplemented )
13001341}
13011342
13021343extern "C" fn bus_exchange ( _buffer : common:: ApiBuffer ) -> common:: Result < ( ) > {
13031344 debug ! ( "bus_exchange" ) ;
1304- unimplemented ! ( ) ;
1345+ common :: Result :: Err ( common :: Error :: Unimplemented )
13051346}
13061347
13071348extern "C" fn time_ticks_get ( ) -> common:: Ticks {
@@ -1508,10 +1549,10 @@ impl AppState for MyApp {
15081549 let byte_offset = usize:: from ( cell_no) * 2 ;
15091550 let x = col * 8 ;
15101551 let y = row * font_height;
1511- let glyph = unsafe { * FRAMEBUFFER . get_unchecked ( byte_offset) } ;
1512- let attr = unsafe { * FRAMEBUFFER . get_unchecked ( byte_offset + 1 ) } ;
1513- let fg_idx = ( attr >> 3 ) & 0b1111 ;
1514- let bg_idx = attr & 0b111 ;
1552+ let glyph = FRAMEBUFFER . get_at ( byte_offset) ;
1553+ let attr = common :: video :: Attr ( FRAMEBUFFER . get_at ( byte_offset + 1 ) ) ;
1554+ let fg_idx = attr. fg ( ) . as_u8 ( ) ;
1555+ let bg_idx = attr. bg ( ) . as_u8 ( ) ;
15151556 let bg =
15161557 RGBColour :: from_packed ( PALETTE [ usize:: from ( bg_idx) ] . load ( Ordering :: SeqCst ) ) ;
15171558 let glyph_box = rect ! ( i32 :: from( x) , i32 :: from( y) , 8i32 , font_height as i32 , ) ;
0 commit comments