Skip to content

Commit 4f88cef

Browse files
Move video modes into main function struct.
Also added some thoughts on Video RAM and memory regions.
1 parent 0127bfe commit 4f88cef

File tree

2 files changed

+526
-94
lines changed

2 files changed

+526
-94
lines changed

src/lib.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,6 @@ pub struct Api {
103103
/// fix). The BIOS should push the time out to the battery-backed Real
104104
/// Time Clock, if it has one.
105105
pub time_set: extern "C" fn(time: Time),
106-
/// Get the memory address for the video buffer.
107-
///
108-
/// Currently this only supports text mode. Each character on screen uses
109-
/// two consecutive bytes - one for the glyph and one for the attribute.
110-
pub video_memory_info_get:
111-
extern "C" fn(address: &mut *mut u8, width_cols: &mut u8, height_rows: &mut u8),
112106
/// Get the configuration data block.
113107
///
114108
/// Configuration data is, to the BIOS, just a block of bytes of a given
@@ -119,6 +113,66 @@ pub struct Api {
119113
///
120114
/// See `configuration_get`.
121115
pub configuration_set: extern "C" fn(buffer: ApiByteSlice) -> crate::Result<()>,
116+
/// Does this Neotron BIOS support this video mode?
117+
pub video_is_valid_mode: extern "C" fn(mode: video::Mode) -> bool,
118+
/// Switch to a new video mode.
119+
///
120+
/// The contents of the screen are undefined after a call to this function.
121+
///
122+
/// If the BIOS does not have enough reserved RAM (or dedicated VRAM) to
123+
/// support this mode, the change will succeed but a subsequent call to
124+
/// `video_get_framebuffer` will return `null`. You must then supply a
125+
/// pointer to a block of size `Mode::frame_size_bytes()` to
126+
/// `video_set_framebuffer` before any video will appear.
127+
pub video_set_mode: extern "C" fn(mode: video::Mode) -> crate::Result<()>,
128+
/// Returns the video mode the BIOS is currently in.
129+
///
130+
/// The OS should call this function immediately after start-up and note
131+
/// the value - this is the `default` video mode which can always be
132+
/// serviced without supplying extra RAM.
133+
pub video_get_mode: extern "C" fn() -> video::Mode,
134+
/// Get the framebuffer address.
135+
///
136+
/// We can write through this address to the video framebuffer. The
137+
/// meaning of the data we write, and the size of the region we are
138+
/// allowed to write to, is a function of the current video mode (see
139+
/// `video_get_mode`).
140+
///
141+
/// This function will return `null` if the BIOS isn't able to support the
142+
/// current video mode from its memory reserves. If that happens, you will
143+
/// need to use some OS RAM or Application RAM and provide that as a
144+
/// framebuffer to `video_set_framebuffer`. The BIOS will always be able
145+
/// to provide the 'basic' text buffer experience from reserves, so this
146+
/// function will never return `null` on start-up.
147+
pub video_get_framebuffer: extern "C" fn() -> *mut u8,
148+
/// Set the framebuffer address.
149+
///
150+
/// Tell the BIOS where it should start fetching pixel or textual data
151+
/// from (depending on the current video mode).
152+
///
153+
/// This value is forgotten after a video mode change and must be
154+
/// re-supplied.
155+
pub video_set_framebuffer: extern "C" fn(*mut u8) -> crate::Result<()>,
156+
/// Find out how large a given region of memory is.
157+
///
158+
/// The first region is the 'application region' and is defined to always
159+
/// start at address `0x2000_0400` (that is, 1 KiB into main SRAM) on a
160+
/// standard Cortex-M system. This application region stops just before
161+
/// the BIOS reserved memory, at the top of the internal SRAM.
162+
///
163+
/// Other regions may be located at other addresses (e.g. external DRAM or
164+
/// PSRAM).
165+
///
166+
/// The OS will always load non-relocatable applications into the bottom
167+
/// of Region 0. It can allocate OS specific structures from any other
168+
/// Region (if any), or from the top of Region 0 (although this reduces
169+
/// the maximum application space available). The OS will prefer lower
170+
/// numbered regions (other than Region 0), so faster memory should be
171+
/// listed first.
172+
///
173+
/// If the region number given is invalid, the function returns `(null,
174+
/// 0)`.
175+
pub memory_get_region: extern "C" fn(region: u8) -> (*mut u8, usize),
122176
}
123177

124178
// End of file

0 commit comments

Comments
 (0)