Skip to main content

risc96_rs/
lib.rs

1#![no_std]
2
3pub const FB_WIDTH: usize = 320;
4pub const FB_HEIGHT: usize = 224;
5pub const FB_PIXELS: usize = FB_WIDTH * FB_HEIGHT;
6
7pub const AUDIO_SAMPLE_RATE: usize = 48_000;
8pub const AUDIO_CHANNELS: usize = 2;
9pub const AUDIO_FRAMES_PER_VIDEO_FRAME: usize = 800;
10pub const AUDIO_SAMPLES: usize = AUDIO_FRAMES_PER_VIDEO_FRAME * AUDIO_CHANNELS;
11
12pub const CONTROLLER_BUTTONS: usize = 12;
13
14const SYS_GET_FRAMEBUFFER: usize = 500;
15const SYS_GET_AUDIOBUFFER: usize = 501;
16const SYS_CONTROLLER_1: usize = 502;
17const SYS_CONTROLLER_2: usize = 503;
18const SYS_CONTROLLER_3: usize = 504;
19const SYS_CONTROLLER_4: usize = 505;
20const SYS_PRESENT: usize = 506;
21
22#[repr(u8)]
23#[derive(Copy, Clone)]
24pub enum Button {
25    Up = 0,
26    Down = 1,
27    Left = 2,
28    Right = 3,
29    A = 4,
30    B = 5,
31    X = 6,
32    Y = 7,
33    L1 = 8,
34    R1 = 9,
35    Start = 10,
36    Select = 11,
37}
38
39#[inline]
40fn syscall0(sysno: usize) -> usize {
41    #[cfg(target_arch = "riscv32")]
42    {
43        let mut a0: usize;
44        unsafe {
45            core::arch::asm!(
46                "ecall",
47                in("a7") sysno,
48                lateout("a0") a0,
49                options(nostack)
50            );
51        }
52        a0
53    }
54
55    #[cfg(not(target_arch = "riscv32"))]
56    {
57        let _ = sysno;
58        0
59    }
60}
61
62#[inline]
63pub fn framebuffer() -> *mut u32 {
64    syscall0(SYS_GET_FRAMEBUFFER) as *mut u32
65}
66
67#[inline]
68pub fn audiobuffer() -> *mut i16 {
69    syscall0(SYS_GET_AUDIOBUFFER) as *mut i16
70}
71
72#[inline]
73pub fn controller_1() -> *const u8 {
74    syscall0(SYS_CONTROLLER_1) as *const u8
75}
76
77#[inline]
78pub fn controller_2() -> *const u8 {
79    syscall0(SYS_CONTROLLER_2) as *const u8
80}
81
82#[inline]
83pub fn controller_3() -> *const u8 {
84    syscall0(SYS_CONTROLLER_3) as *const u8
85}
86
87#[inline]
88pub fn controller_4() -> *const u8 {
89    syscall0(SYS_CONTROLLER_4) as *const u8
90}
91
92#[inline]
93pub fn present() {
94    let _ = syscall0(SYS_PRESENT);
95}
96
97#[inline]
98pub fn rgb(r: u8, g: u8, b: u8) -> u32 {
99    ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
100}
101
102#[inline]
103pub fn button_level(packed: *const u8, button: Button) -> u8 {
104    let bit = (button as usize) * 2;
105    let byte_index = bit >> 3;
106    let shift = bit & 7;
107
108    unsafe { ((*packed.add(byte_index) >> shift) & 0x3) as u8 }
109}