add all other interrupts

This commit is contained in:
Corwin Kuiper 2021-06-23 23:01:51 +01:00
parent 30c5a0eea9
commit b98e6cbb02

View file

@ -74,21 +74,55 @@ impl InterruptRoot {
} }
} }
static mut INTERRUPT_TABLE: Interrupts = Interrupts { static mut INTERRUPT_TABLE: Interrupts = Interrupts::new();
vblank: InterruptRoot::new(),
hblank: InterruptRoot::new(),
};
#[no_mangle] #[no_mangle]
pub extern "C" fn __RUST_INTERRUPT_HANDLER(interrupt: u16) { pub extern "C" fn __RUST_INTERRUPT_HANDLER(interrupt: u16) {
if interrupt & 1 != 0 { for i in 0..=13_u8 {
unsafe { INTERRUPT_TABLE.vblank.trigger_interrupts() }; if (1 << (i as u16)) & interrupt != 0 {
}; let interrupt = unsafe { core::mem::transmute(i) };
let root = interrupt_to_root(interrupt);
root.trigger_interrupts();
}
}
} }
struct Interrupts { struct Interrupts {
vblank: InterruptRoot, vblank: InterruptRoot,
hblank: InterruptRoot, hblank: InterruptRoot,
vcounter: InterruptRoot,
timer0: InterruptRoot,
timer1: InterruptRoot,
timer2: InterruptRoot,
timer3: InterruptRoot,
serial: InterruptRoot,
dma0: InterruptRoot,
dma1: InterruptRoot,
dma2: InterruptRoot,
dma3: InterruptRoot,
keypad: InterruptRoot,
gamepak: InterruptRoot,
}
impl Interrupts {
const fn new() -> Self {
Interrupts {
vblank: InterruptRoot::new(),
hblank: InterruptRoot::new(),
vcounter: InterruptRoot::new(),
timer0: InterruptRoot::new(),
timer1: InterruptRoot::new(),
timer2: InterruptRoot::new(),
timer3: InterruptRoot::new(),
serial: InterruptRoot::new(),
dma0: InterruptRoot::new(),
dma1: InterruptRoot::new(),
dma2: InterruptRoot::new(),
dma3: InterruptRoot::new(),
keypad: InterruptRoot::new(),
gamepak: InterruptRoot::new(),
}
}
} }
pub struct InterruptClosureBounded<'a> { pub struct InterruptClosureBounded<'a> {
@ -134,6 +168,25 @@ impl Drop for InterruptClosure {
} }
} }
fn interrupt_to_root(interrupt: Interrupt) -> &'static InterruptRoot {
match interrupt {
Interrupt::VBlank => unsafe { &INTERRUPT_TABLE.vblank },
Interrupt::HBlank => unsafe { &INTERRUPT_TABLE.hblank },
Interrupt::VCounter => unsafe { &INTERRUPT_TABLE.vcounter },
Interrupt::Timer0 => unsafe { &INTERRUPT_TABLE.timer0 },
Interrupt::Timer1 => unsafe { &INTERRUPT_TABLE.timer1 },
Interrupt::Timer2 => unsafe { &INTERRUPT_TABLE.timer2 },
Interrupt::Timer3 => unsafe { &INTERRUPT_TABLE.timer3 },
Interrupt::Serial => unsafe { &INTERRUPT_TABLE.serial },
Interrupt::Dma0 => unsafe { &INTERRUPT_TABLE.dma0 },
Interrupt::Dma1 => unsafe { &INTERRUPT_TABLE.dma1 },
Interrupt::Dma2 => unsafe { &INTERRUPT_TABLE.dma2 },
Interrupt::Dma3 => unsafe { &INTERRUPT_TABLE.dma3 },
Interrupt::Keypad => unsafe { &INTERRUPT_TABLE.keypad },
Interrupt::Gamepak => unsafe { &INTERRUPT_TABLE.gamepak },
}
}
fn get_interrupt_handle_root<'a>( fn get_interrupt_handle_root<'a>(
f: &'a mut dyn FnMut(), f: &'a mut dyn FnMut(),
root: &InterruptRoot, root: &InterruptRoot,
@ -150,12 +203,7 @@ fn get_interrupt_handle_root<'a>(
} }
pub fn get_interrupt_handle(f: &mut dyn FnMut(), interrupt: Interrupt) -> InterruptClosureBounded { pub fn get_interrupt_handle(f: &mut dyn FnMut(), interrupt: Interrupt) -> InterruptClosureBounded {
let root = match interrupt { let root = interrupt_to_root(interrupt);
Interrupt::VBlank => unsafe { &INTERRUPT_TABLE.vblank },
_ => unimplemented!(
"sorry, I haven't yet added this interrupt. Please request it if you need it"
),
};
get_interrupt_handle_root(f, root) get_interrupt_handle_root(f, root)
} }