Skip to content

Commit 3836cd0

Browse files
Add 8x8 font.
Also supports mode switching and 400 line mode.
1 parent 7768017 commit 3836cd0

6 files changed

Lines changed: 2500 additions & 76 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rp-pico = "0.3"
1515
# Cortex-M run-time (or start-up) code
1616
cortex-m-rt = "0.7"
1717
# The BIOS to OS API
18-
neotron-common-bios = "0.1.0"
18+
neotron-common-bios = "0.4.0"
1919
# For time keeping/handling
2020
embedded-time = "0.12"
2121
# For the RP2040 bootloader

src/flash1002.bin

2.27 KB
Binary file not shown.

src/main.rs

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub mod vga;
4343
// Imports
4444
// -----------------------------------------------------------------------------
4545

46+
use common::MemoryRegion;
4647
use core::fmt::Write;
4748
use cortex_m_rt::entry;
4849
use 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

230230
fn 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.
411415
pub 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
}

src/vga/font.rs renamed to src/vga/font16.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
//! OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3030
//! SUCH DAMAGE.
3131
32-
/// Width of the font in pixels
33-
pub const WIDTH_PX: usize = 8;
34-
35-
/// Height of the font in pixels
36-
pub const HEIGHT_PX: usize = 16;
32+
/// An 8x16 font
33+
pub static FONT: super::Font = super::Font {
34+
height: 16,
35+
data: &DATA,
36+
};
3737

3838
/// Our font data - arranged as 256 glyphs of 1 byte/row x 16 row/glyph.
39-
pub static DATA: [u8; 256 * HEIGHT_PX] = [
39+
static DATA: [u8; 256 * 16] = [
4040
// Char::Null
4141
0b0000_0000,
4242
0b0000_0000,

0 commit comments

Comments
 (0)