use trapezoid_core::cpu::{BusLine, Cpu, CpuBusProvider};
struct Bus {
kseg1: [u8; 0x10000],
is_done: bool,
}
impl BusLine for Bus {
fn read_u32(&mut self, addr: u32) -> Result<u32, String> {
match addr {
0xBFC00000..=0xBFC0FFFF => {
let offset = addr - 0xBFC00000;
let word = u32::from_le_bytes([
self.kseg1[offset as usize],
self.kseg1[(offset + 1) as usize],
self.kseg1[(offset + 2) as usize],
self.kseg1[(offset + 3) as usize],
]);
Ok(word)
}
_ => Err(format!("Unimplemented read at address {:08X}", addr)),
}
}
fn read_u8(&mut self, addr: u32) -> Result<u8, String> {
match addr {
0xBFC00000..=0xBFC0FFFF => {
let offset = addr - 0xBFC00000;
Ok(self.kseg1[offset as usize])
}
_ => Err(format!("Unimplemented read at address {:08X}", addr)),
}
}
fn write_u32(&mut self, addr: u32, data: u32) -> Result<(), String> {
match addr {
0xBFC00000..=0xBFC0FFFF => {
let offset = addr - 0xBFC00000;
self.kseg1[offset as usize] = data as u8;
self.kseg1[(offset + 1) as usize] = (data >> 8) as u8;
self.kseg1[(offset + 2) as usize] = (data >> 16) as u8;
self.kseg1[(offset + 3) as usize] = (data >> 24) as u8;
Ok(())
}
_ => Err(format!("Unimplemented write at address {:08X}", addr)),
}
}
fn write_u8(&mut self, addr: u32, data: u8) -> Result<(), String> {
match addr {
0x0 => {
println!("Write to address 0x0: {:08X}, exiting", data);
self.is_done = data != 0x0;
Ok(())
}
0x4 => {
print!("{}", data as char);
Ok(())
}
_ => Err(format!("Unimplemented write at address {:08X}", addr)),
}
}
}
impl CpuBusProvider for Bus {
fn pending_interrupts(&self) -> bool {
false
}
fn should_run_dma(&self) -> bool {
false
}
}
const CODE: [u8; 136] = [
0x17, 0x00, 0xf0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xbd, 0x27,
0x04, 0x00, 0xbf, 0xaf, 0x00, 0x00, 0xbe, 0xaf, 0x25, 0xf0, 0xa0, 0x03, 0x08, 0x00, 0xa0, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x90, 0x01, 0x00, 0x84, 0x24,
0xff, 0xff, 0xa5, 0x20, 0x04, 0x00, 0x02, 0xa0, 0x07, 0x00, 0xf0, 0x0b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x25, 0xe8, 0xc0, 0x03, 0x00, 0x00, 0xbe, 0x8f, 0x04, 0x00, 0xbf, 0x8f,
0x08, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0xbf, 0x1d, 0x3c, 0x00, 0xe0, 0xbd, 0x37, 0xc0, 0xbf, 0x04, 0x3c, 0x00, 0xd0, 0x84, 0x34,
0x0e, 0x00, 0xa5, 0x24, 0x03, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, 0xa0,
];
const STRING_TO_PRINT: &[u8; 15] = b"Hello, world!\n\0";
fn main() {
env_logger::init();
let mut cpu = Cpu::new();
let mut kseg1 = [0; 0x10000];
kseg1[0..CODE.len()].copy_from_slice(&CODE);
kseg1[0xD000..0xD000 + STRING_TO_PRINT.len()].copy_from_slice(STRING_TO_PRINT);
let mut bus = Bus {
kseg1,
is_done: false,
};
let mut total_cycles = 0;
while !bus.is_done {
let (n_cycles, _cpu_state) = cpu.clock(&mut bus, 1);
total_cycles += n_cycles;
}
println!("Total cycles: {}", total_cycles);
}