@@ -43,6 +43,7 @@ pub mod vga;
4343// Imports
4444// -----------------------------------------------------------------------------
4545
46+ use common:: MemoryRegion ;
4647use core:: fmt:: Write ;
4748use cortex_m_rt:: entry;
4849use defmt:: info;
@@ -222,14 +223,13 @@ fn main() -> ! {
222223 sign_on ( & mut delay) ;
223224
224225 // Now jump to the OS
225- let flash_os_start = unsafe { & mut _flash_os_start as * mut u32 as usize } ;
226- let code: & common:: OsStartFn = unsafe { :: core:: mem:: transmute ( flash_os_start) } ;
226+ let code: & common:: OsStartFn = unsafe { :: core:: mem:: transmute ( & _flash_os_start) } ;
227227 code ( & API_CALLS ) ;
228228}
229229
230230fn sign_on ( delay : & mut cortex_m:: delay:: Delay ) {
231231 static LICENCE_TEXT : & str = "\
232- Copyright © Jonathan 'theJPster' Pallant and the Neotron Developers, 2021 \n \
232+ Copyright © Jonathan 'theJPster' Pallant and the Neotron Developers, 2022 \n \
233233 \n \
234234 This program is free software: you can redistribute it and/or modify\n \
235235 it under the terms of the GNU General Public License as published by\n \
@@ -249,7 +249,7 @@ fn sign_on(delay: &mut cortex_m::delay::Delay) {
249249 tc. set_text_buffer ( unsafe { & mut vga:: GLYPH_ATTR_ARRAY } ) ;
250250
251251 // A crude way to clear the screen
252- for _col in 0 ..vga:: NUM_TEXT_ROWS {
252+ for _col in 0 ..vga:: MAX_TEXT_ROWS {
253253 writeln ! ( & tc) . unwrap ( ) ;
254254 }
255255
@@ -267,7 +267,7 @@ fn sign_on(delay: &mut cortex_m::delay::Delay) {
267267 }
268268
269269 // A crude way to clear the screen
270- for _col in 0 ..vga:: NUM_TEXT_ROWS {
270+ for _col in 0 ..vga:: MAX_TEXT_ROWS {
271271 writeln ! ( & tc) . unwrap ( ) ;
272272 }
273273 tc. move_to ( 0 , 0 ) ;
@@ -399,8 +399,12 @@ pub extern "C" fn video_is_valid_mode(mode: common::video::Mode) -> bool {
399399/// `video_get_framebuffer` will return `null`. You must then supply a
400400/// pointer to a block of size `Mode::frame_size_bytes()` to
401401/// `video_set_framebuffer` before any video will appear.
402- pub extern "C" fn video_set_mode ( _mode : common:: video:: Mode ) -> common:: Result < ( ) > {
403- common:: Result :: Err ( common:: Error :: Unimplemented )
402+ pub extern "C" fn video_set_mode ( mode : common:: video:: Mode ) -> common:: Result < ( ) > {
403+ if vga:: set_video_mode ( mode) {
404+ common:: Result :: Ok ( ( ) )
405+ } else {
406+ common:: Result :: Err ( common:: Error :: UnsupportedConfiguration ( 0 ) )
407+ }
404408}
405409
406410/// Returns the video mode the BIOS is currently in.
@@ -409,10 +413,7 @@ pub extern "C" fn video_set_mode(_mode: common::video::Mode) -> common::Result<(
409413/// the value - this is the `default` video mode which can always be
410414/// serviced without supplying extra RAM.
411415pub extern "C" fn video_get_mode ( ) -> common:: video:: Mode {
412- common:: video:: Mode :: new (
413- common:: video:: Timing :: T640x480 ,
414- common:: video:: Format :: Text8x16 ,
415- )
416+ vga:: get_video_mode ( )
416417}
417418
418419/// Get the framebuffer address.
@@ -434,12 +435,16 @@ pub extern "C" fn video_get_framebuffer() -> *mut u8 {
434435
435436/// Set the framebuffer address.
436437///
437- /// Tell the BIOS where it should start fetching pixel or textual data
438- /// from (depending on the current video mode).
438+ /// Tell the BIOS where it should start fetching pixel or textual data from
439+ /// (depending on the current video mode).
439440///
440- /// This value is forgotten after a video mode change and must be
441- /// re-supplied.
442- pub extern "C" fn video_set_framebuffer ( _buffer : * mut u8 ) -> common:: Result < ( ) > {
441+ /// This value is forgotten after a video mode change and must be re-supplied.
442+ ///
443+ /// # Safety
444+ ///
445+ /// The pointer must point to enough video memory to handle the current video
446+ /// mode, and any future video mode you set.
447+ pub unsafe extern "C" fn video_set_framebuffer ( _buffer : * const u8 ) -> common:: Result < ( ) > {
443448 common:: Result :: Err ( common:: Error :: Unimplemented )
444449}
445450
@@ -461,31 +466,15 @@ pub extern "C" fn video_set_framebuffer(_buffer: *mut u8) -> common::Result<()>
461466/// (other than Region 0), so faster memory should be listed first.
462467///
463468/// If the region number given is invalid, the function returns `(null, 0)`.
464- ///
465- #[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
466- pub extern "C" fn memory_get_region (
467- region : u8 ,
468- out_start : * mut * mut u8 ,
469- out_len : * mut usize ,
470- ) -> common:: Result < ( ) > {
471- // The clippy allow is because the API isn't marked as 'unsafe', and so we
472- // can't mark this function as 'unsafe'.
469+ pub extern "C" fn memory_get_region ( region : u8 ) -> common:: Result < common:: MemoryRegion > {
473470 match region {
474- // Application Region
475471 0 => {
476- if !out_start. is_null ( ) {
477- unsafe {
478- let ram_os_start = & mut _ram_os_start as * mut u32 as * mut u8 ;
479- out_start. write ( ram_os_start) ;
480- }
481- }
482- if !out_len. is_null ( ) {
483- unsafe {
484- let ram_os_len = & mut _ram_os_len as * const u32 as usize ;
485- out_len. write ( ram_os_len) ;
486- }
487- }
488- common:: Result :: Ok ( ( ) )
472+ // Application Region
473+ common:: Result :: Ok ( MemoryRegion {
474+ start : unsafe { & mut _ram_os_start as * mut u32 } as * mut u8 ,
475+ length : unsafe { & mut _ram_os_len as * const u32 } as usize ,
476+ kind : common:: MemoryKind :: Ram ,
477+ } )
489478 }
490479 _ => common:: Result :: Err ( common:: Error :: InvalidDevice ) ,
491480 }
0 commit comments