bootrom boot
This commit is contained in:
parent
9533768bd9
commit
d1dae1aa73
1 changed files with 61 additions and 16 deletions
77
src/main.rs
77
src/main.rs
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue