#![no_std]
pub const FB_WIDTH: usize = 320;
pub const FB_HEIGHT: usize = 224;
pub const FB_PIXELS: usize = FB_WIDTH * FB_HEIGHT;
pub const AUDIO_SAMPLE_RATE: usize = 48_000;
pub const AUDIO_CHANNELS: usize = 2;
pub const AUDIO_FRAMES_PER_VIDEO_FRAME: usize = 800;
pub const AUDIO_SAMPLES: usize = AUDIO_FRAMES_PER_VIDEO_FRAME * AUDIO_CHANNELS;
pub const CONTROLLER_BUTTONS: usize = 12;
const SYS_GET_FRAMEBUFFER: usize = 500;
const SYS_GET_AUDIOBUFFER: usize = 501;
const SYS_CONTROLLER_1: usize = 502;
const SYS_CONTROLLER_2: usize = 503;
const SYS_CONTROLLER_3: usize = 504;
const SYS_CONTROLLER_4: usize = 505;
const SYS_PRESENT: usize = 506;
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum Button {
Up = 0,
Down = 1,
Left = 2,
Right = 3,
A = 4,
B = 5,
X = 6,
Y = 7,
L1 = 8,
R1 = 9,
Start = 10,
Select = 11,
}
#[inline]
fn syscall0(sysno: usize) -> usize {
#[cfg(target_arch = "riscv32")]
{
let mut a0: usize;
unsafe {
core::arch::asm!(
"ecall",
in("a7") sysno,
lateout("a0") a0,
options(nostack)
);
}
a0
}
#[cfg(not(target_arch = "riscv32"))]
{
let _ = sysno;
0
}
}
#[inline]
pub fn framebuffer() -> *mut u32 {
syscall0(SYS_GET_FRAMEBUFFER) as *mut u32
}
#[inline]
pub fn audiobuffer() -> *mut i16 {
syscall0(SYS_GET_AUDIOBUFFER) as *mut i16
}
#[inline]
pub fn controller_1() -> *const u8 {
syscall0(SYS_CONTROLLER_1) as *const u8
}
#[inline]
pub fn controller_2() -> *const u8 {
syscall0(SYS_CONTROLLER_2) as *const u8
}
#[inline]
pub fn controller_3() -> *const u8 {
syscall0(SYS_CONTROLLER_3) as *const u8
}
#[inline]
pub fn controller_4() -> *const u8 {
syscall0(SYS_CONTROLLER_4) as *const u8
}
#[inline]
pub fn present() {
let _ = syscall0(SYS_PRESENT);
}
#[inline]
pub fn rgb(r: u8, g: u8, b: u8) -> u32 {
((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
}
#[inline]
pub fn button_level(packed: *const u8, button: Button) -> u8 {
let bit = (button as usize) * 2;
let byte_index = bit >> 3;
let shift = bit & 7;
unsafe { ((*packed.add(byte_index) >> shift) & 0x3) as u8 }
}