bootrom boot

This commit is contained in:
Alex Janka 2023-01-18 12:46:15 +11:00
parent 9533768bd9
commit d1dae1aa73

View file

@ -4,7 +4,10 @@ mod processor;
use clap::Parser;
use processor::CPU;
use std::{fs, io};
use std::{
fs,
io::{self, stdout, Write},
};
/// Simple program to greet a person
#[derive(Parser, Debug)]
@ -43,6 +46,8 @@ union Register {
}
pub struct Memory {
bootrom: ROM,
bootrom_enabled: bool,
rom: ROM,
vram: [u8; 8192],
ram: [u8; 8192],
@ -50,11 +55,14 @@ pub struct Memory {
cpu_ram: [u8; 128],
oam: [u8; 160],
ime: bool,
io: [u8; 76],
}
impl Memory {
fn init(rom: ROM) -> Self {
fn init(bootrom: ROM, bootrom_enabled: bool, rom: ROM) -> Self {
Self {
bootrom,
bootrom_enabled,
rom,
vram: [0x0; 8192],
ram: [0x0; 8192],
@ -62,6 +70,7 @@ impl Memory {
cpu_ram: [0x0; 128],
oam: [0x0; 160],
ime: false,
io: [0x0; 76],
}
}
@ -70,6 +79,9 @@ impl Memory {
0x0..0x8000 => {
// rom access
// todo - switchable rom banks
if self.bootrom_enabled && (address as usize) < self.bootrom.len() {
return self.bootrom[address as usize];
}
return self.rom[address as usize];
}
0x8000..0xA000 => {
@ -88,13 +100,14 @@ impl Memory {
return self.oam[(address - 0xFE00) as usize];
}
0xFEA0..0xFF00 => {
panic!("empty space read")
return 0x0;
}
0xFF00..0xFF4C => {
panic!("I/O read");
return self.io[(address - 0xFF00) as usize];
}
0xFF4C..0xFF80 => {
panic!("empty space 2 read");
// println!("empty space 2 read");
return 0x0;
}
0xFF80..0xFFFF => {
return self.cpu_ram[(address - 0xFF80) as usize];
@ -109,7 +122,7 @@ impl Memory {
match address {
0x0..0x8000 => {
// change this with MBC code...
println!("tried to write {:#5X} at {:#X}", data, address);
// println!("tried to write {:#5X} at {:#X}", data, address);
}
0x8000..0xA000 => {
self.vram[(address - 0x8000) as usize] = data;
@ -127,19 +140,24 @@ impl Memory {
self.oam[(address - 0xFE00) as usize] = data;
}
0xFEA0..0xFF00 => {
panic!("empty space write")
// println!("empty space write: {:#X} to addr {:#X}", data, address);
}
0xFF00..0xFF4C => {
panic!("I/O write");
if address == 0xFF02 && data == 0x81 {
print!("{}", self.get(0xFF01) as char);
stdout().flush().unwrap();
}
self.io[(address - 0xFF00) as usize] = data;
}
0xFF4C..0xFF80 => {
panic!("empty space 2 write");
// println!("empty space 2 write: {:#X} to addr {:#X}", data, address);
}
0xFF80..0xFFFF => {
self.cpu_ram[(address - 0xFF80) as usize] = data;
}
0xFFFF => match data {
0x0 => self.ime = false,
0x1 => self.ime = true,
_ => panic!("wrote weird number to ime: {:#X}", data),
},
}
@ -175,26 +193,39 @@ fn main() {
let rom: ROM = fs::read(args.rom).expect("Could not load ROM");
let bootrom: ROM = fs::read(args.bootrom).expect("Could not load BootROM");
let mut state = State::default();
let run_rom = if args.run_bootrom {
if args.run_bootrom {
state.pc = Register { as_u16: 0x0 };
bootrom
} else {
rom
};
}
let mut cpu = CPU {
memory: Memory::init(run_rom),
memory: Memory::init(bootrom, args.run_bootrom, rom),
state,
last_instruction: 0x0,
last_instruction_addr: 0x0,
};
#[allow(unused_variables)]
let mut cycle_num = 0;
match args.step_by {
Some(step_size) => loop {
for _ in 0..step_size {
cycle_num += 1;
cpu.exec_next();
println!(
"exec {:#4X} from {:#4X}",
cpu.last_instruction, cpu.last_instruction_addr
);
}
print!(
" ...{} cycles - press enter to continue\r",
cycle_num
);
stdout().flush().unwrap();
pause();
},
None => loop {
cpu.exec_next()
cycle_num += 1;
print_cycles(&cycle_num);
cpu.exec_next();
},
}
}
@ -203,3 +234,17 @@ fn main() {
fn pause() {
io::stdin().read_line(&mut String::new()).unwrap();
}
#[allow(dead_code)]
fn print_cycles(cycles: &i32) {
if *cycles % 456 != 0 {
return;
}
let instructions_per_second = 400000;
print!(
"cycle {} - approx {} seconds on real hardware\r",
cycles,
cycles / instructions_per_second
);
stdout().flush().unwrap();
}