Skip to content

Commit 9052e9e

Browse files
Pico updates (#5)
* Make `memory_get_region` FFI safe. * Change Time to use nanoseconds. You can't use 60 Hz ticks on a system with a 70 Hz video output. * Ensure Mode supports Eq and Ord * Add text_width and text_height to Mode. Also fix formatting.
1 parent 32847a1 commit 9052e9e

File tree

3 files changed

+37
-12
lines changed

3 files changed

+37
-12
lines changed

src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ pub struct Api {
172172
///
173173
/// If the region number given is invalid, the function returns `(null,
174174
/// 0)`.
175-
pub memory_get_region: extern "C" fn(region: u8) -> (*mut u8, usize),
175+
pub memory_get_region: extern "C" fn(
176+
region: u8,
177+
out_start: *mut *mut u8,
178+
out_len: *mut usize,
179+
) -> crate::Result<()>,
176180
}
177181

178182
// End of file

src/types.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,10 @@ pub struct ApiBuffer<'a> {
120120
#[repr(C)]
121121
#[derive(Debug, Clone)]
122122
pub struct Time {
123-
/// Seconds since 2000-01-01T00:00:00Z
124-
pub seconds_since_epoch: u32,
125-
/// Number of 60 Hz frames that have elapsed since the current second
126-
/// began [0..59].
127-
pub frames_since_second: u8,
123+
/// Seconds since the epoch
124+
pub secs: u32,
125+
/// Nanoseconds since the last second rolled over
126+
pub nsecs: u32,
128127
}
129128

130129
// ============================================================================
@@ -290,13 +289,16 @@ impl<'a> From<&'a mut [u8]> for ApiBuffer<'a> {
290289

291290
impl core::fmt::Display for Time {
292291
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
292+
let timestamp: chrono::DateTime<chrono::Utc> = self.into();
293+
write!(f, "{}", timestamp)
294+
}
295+
}
296+
297+
impl From<&Time> for chrono::DateTime<chrono::Utc> {
298+
fn from(time: &Time) -> Self {
293299
use chrono::prelude::*;
294300
let our_epoch = Utc.ymd(2001, 1, 1).and_hms(0, 0, 0).timestamp();
295-
let time = chrono::Utc.timestamp(
296-
i64::from(self.seconds_since_epoch) + our_epoch,
297-
((u32::from(self.frames_since_second) * 1_000_000) / 60) * 1_000,
298-
);
299-
write!(f, "{}", time)
301+
chrono::Utc.timestamp(i64::from(time.secs) + our_epoch, time.nsecs)
300302
}
301303
}
302304

src/video.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
/// A Neotron BIOS may support multiple video modes. Each is described using
4343
/// an instance of this type.
4444
#[repr(transparent)]
45-
#[derive(Copy, Clone, Debug)]
45+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
4646
pub struct Mode(u8);
4747

4848
/// Describes the format of the video memory.
@@ -187,6 +187,25 @@ impl Mode {
187187
}
188188
}
189189

190+
/// Gets how big a line is in glyph-attribute pairs.
191+
pub const fn text_width(self) -> Option<u16> {
192+
let horizontal_pixels = self.horizontal_pixels();
193+
194+
match self.format() {
195+
Format::Text8x8 | Format::Text8x16 => Some(horizontal_pixels / 8),
196+
_ => None,
197+
}
198+
}
199+
200+
/// Gets how many rows of text are on screen.
201+
pub const fn text_height(self) -> Option<u16> {
202+
match self.format() {
203+
Format::Text8x8 => Some(self.vertical_lines() / 8),
204+
Format::Text8x16 => Some(self.vertical_lines() / 16),
205+
_ => None,
206+
}
207+
}
208+
190209
/// Gets how big the frame is, in bytes.
191210
pub const fn frame_size_bytes(self) -> usize {
192211
let line_size = self.line_size_bytes();

0 commit comments

Comments
 (0)