Move to edition=2018
This commit is contained in:
parent
50471f1ec6
commit
ddb1da4367
@ -2,6 +2,7 @@
|
||||
name = "gbc"
|
||||
version = "0.1.0"
|
||||
authors = ["Kevin Hamacher <kevin.hamacher@rub.de>"]
|
||||
edition = '2018'
|
||||
|
||||
[dependencies]
|
||||
sdl2 = "*"
|
||||
|
||||
@ -18,17 +18,17 @@ enum RamSize {
|
||||
}
|
||||
|
||||
pub struct Cartridge {
|
||||
mbc: Box<super::mbc::mbc::MBC>,
|
||||
mbc: Box<dyn super::mbc::mbc::MBC>,
|
||||
savefile: Option<String>,
|
||||
}
|
||||
|
||||
impl Cartridge {
|
||||
pub fn new(rom: Box<[u8]>, save_file: Option<String>) -> Cartridge {
|
||||
let mbc_type: MemoryBankControllerType = match rom[0x0147] {
|
||||
0x00 | 0x08...0x09 => MemoryBankControllerType::None,
|
||||
0x01...0x03 => MemoryBankControllerType::MBC1,
|
||||
0x05...0x06 => MemoryBankControllerType::MBC2,
|
||||
0x0F...0x13 => MemoryBankControllerType::MBC3,
|
||||
0x00 | 0x08..=0x09 => MemoryBankControllerType::None,
|
||||
0x01..=0x03 => MemoryBankControllerType::MBC1,
|
||||
0x05..=0x06 => MemoryBankControllerType::MBC2,
|
||||
0x0F..=0x13 => MemoryBankControllerType::MBC3,
|
||||
// 0xFF => MemoryBankControllerType::HuC1,
|
||||
_ => panic!("Unsupported MBC type: {:02X}", rom[0x0147]),
|
||||
};
|
||||
@ -37,7 +37,7 @@ impl Cartridge {
|
||||
|
||||
let rom_banks: u16 = match rom[0x0148] {
|
||||
0x00 => 0,
|
||||
0x01...0x07 => 2u16.pow(rom[0x0148] as u32 + 1),
|
||||
0x01..=0x07 => 2u16.pow(rom[0x0148] as u32 + 1),
|
||||
0x52 => 72,
|
||||
0x53 => 80,
|
||||
0x54 => 96,
|
||||
@ -57,7 +57,7 @@ impl Cartridge {
|
||||
|
||||
let ram = Cartridge::load_savefile(&save_file, ram_size);
|
||||
|
||||
let mbc: Box<super::mbc::mbc::MBC> = match mbc_type {
|
||||
let mbc: Box<dyn super::mbc::mbc::MBC> = match mbc_type {
|
||||
MemoryBankControllerType::None => Box::new(super::mbc::mbc::NoMBC::new(rom, ram)),
|
||||
MemoryBankControllerType::MBC1 => Box::new(super::mbc::mbc1::MBC1::new(rom, ram)),
|
||||
MemoryBankControllerType::MBC2 => Box::new(super::mbc::mbc2::MBC2::new(rom, ram)),
|
||||
|
||||
100
src/cpu.rs
100
src/cpu.rs
@ -155,7 +155,7 @@ impl CPU {
|
||||
self.set_clear_flag(FLAG_C, new > old || (new == old && c == 1));
|
||||
self.set_clear_flag(
|
||||
FLAG_H,
|
||||
((old & 0x0F).wrapping_sub((val & 0x0F)).wrapping_sub(c)) > 0x0F,
|
||||
((old & 0x0F).wrapping_sub(val & 0x0F).wrapping_sub(c)) > 0x0F,
|
||||
);
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ impl CPU {
|
||||
self.ip += 1;
|
||||
|
||||
match instruction {
|
||||
0x00...0x07 => {
|
||||
0x00..=0x07 => {
|
||||
let reg_id = (instruction - 0x00) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
if self.debug {
|
||||
@ -212,7 +212,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
}
|
||||
0x08...0x0F => {
|
||||
0x08..=0x0F => {
|
||||
let reg_id = (instruction - 0x08) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
if self.debug {
|
||||
@ -230,7 +230,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
}
|
||||
0x10...0x17 => {
|
||||
0x10..=0x17 => {
|
||||
let reg_id = (instruction - 0x10) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
if self.debug {
|
||||
@ -250,7 +250,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
}
|
||||
0x18...0x1F => {
|
||||
0x18..=0x1F => {
|
||||
// RR
|
||||
let reg_id = (instruction - 0x18) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
@ -271,7 +271,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
}
|
||||
0x20...0x27 => {
|
||||
0x20..=0x27 => {
|
||||
let reg_id = (instruction - 0x20) as usize;
|
||||
if self.debug {
|
||||
println!("SLA {}", REG_NAMES[reg_id]);
|
||||
@ -282,7 +282,7 @@ impl CPU {
|
||||
self.set_clear_flag(FLAG_Z, v & 0x7F == 0);
|
||||
self.set_8bit_reg(reg_id, v << 1);
|
||||
}
|
||||
0x28...0x2F => {
|
||||
0x28..=0x2F => {
|
||||
let reg_id = (instruction - 0x28) as usize;
|
||||
if self.debug {
|
||||
println!("SRA {}", REG_NAMES[reg_id]);
|
||||
@ -294,7 +294,7 @@ impl CPU {
|
||||
self.set_clear_flag(FLAG_Z, nv == 0);
|
||||
self.set_clear_flag(FLAG_C, v & 1 == 1);
|
||||
}
|
||||
0x30...0x37 => {
|
||||
0x30..=0x37 => {
|
||||
let reg_id = (instruction - 0x30) as usize;
|
||||
if self.debug {
|
||||
println!("SWAP {}", REG_NAMES[reg_id]);
|
||||
@ -304,7 +304,7 @@ impl CPU {
|
||||
self.flags = 0;
|
||||
self.set_clear_flag(FLAG_Z, v == 0);
|
||||
}
|
||||
0x38...0x3F => {
|
||||
0x38..=0x3F => {
|
||||
let reg_id = (instruction - 0x38) as usize;
|
||||
if self.debug {
|
||||
println!("SRL {}", REG_NAMES[reg_id]);
|
||||
@ -318,7 +318,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// Bits
|
||||
0x40...0x47 => {
|
||||
0x40..=0x47 => {
|
||||
// Test 0th bit
|
||||
let reg_id = (instruction - 0x40) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -329,7 +329,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x48...0x4F => {
|
||||
0x48..=0x4F => {
|
||||
// Test 1th bit
|
||||
let reg_id = (instruction - 0x48) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -340,7 +340,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x50...0x57 => {
|
||||
0x50..=0x57 => {
|
||||
// Test 2th bit
|
||||
let reg_id = (instruction - 0x50) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -351,7 +351,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x58...0x5F => {
|
||||
0x58..=0x5F => {
|
||||
// Test 3th bit
|
||||
let reg_id = (instruction - 0x58) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -362,7 +362,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x60...0x67 => {
|
||||
0x60..=0x67 => {
|
||||
// Test 4th bit
|
||||
let reg_id = (instruction - 0x60) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -373,7 +373,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x68...0x6F => {
|
||||
0x68..=0x6F => {
|
||||
// Test 5th bit
|
||||
let reg_id = (instruction - 0x68) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -384,7 +384,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x70...0x77 => {
|
||||
0x70..=0x77 => {
|
||||
// Test 6th bit
|
||||
let reg_id = (instruction - 0x70) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -395,7 +395,7 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
}
|
||||
0x78...0x7F => {
|
||||
0x78..=0x7F => {
|
||||
// Test 7th bit
|
||||
let reg_id = (instruction - 0x78) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -408,7 +408,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// Reset bits
|
||||
0x80...0x87 => {
|
||||
0x80..=0x87 => {
|
||||
// Reset 0th bit
|
||||
let reg_id = (instruction - 0x80) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -417,7 +417,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 0));
|
||||
}
|
||||
0x88...0x8F => {
|
||||
0x88..=0x8F => {
|
||||
// Reset 1th bit
|
||||
let reg_id = (instruction - 0x88) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -426,7 +426,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 1));
|
||||
}
|
||||
0x90...0x97 => {
|
||||
0x90..=0x97 => {
|
||||
// Reset 2nd bit
|
||||
let reg_id = (instruction - 0x90) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -435,7 +435,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 2));
|
||||
}
|
||||
0x98...0x9F => {
|
||||
0x98..=0x9F => {
|
||||
// Reset 3th bit
|
||||
let reg_id = (instruction - 0x98) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -444,7 +444,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 3));
|
||||
}
|
||||
0xA0...0xA7 => {
|
||||
0xA0..=0xA7 => {
|
||||
// Reset 4th bit
|
||||
let reg_id = (instruction - 0xA0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -453,7 +453,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 4));
|
||||
}
|
||||
0xA8...0xAF => {
|
||||
0xA8..=0xAF => {
|
||||
// Reset 5th bit
|
||||
let reg_id = (instruction - 0xA8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -462,7 +462,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 5));
|
||||
}
|
||||
0xB0...0xB7 => {
|
||||
0xB0..=0xB7 => {
|
||||
// Reset 6th bit
|
||||
let reg_id = (instruction - 0xB0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -471,7 +471,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content & !(1 << 6));
|
||||
}
|
||||
0xB8...0xBF => {
|
||||
0xB8..=0xBF => {
|
||||
// Reset 7th bit
|
||||
let reg_id = (instruction - 0xB8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -482,7 +482,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// Set bits
|
||||
0xC0...0xC7 => {
|
||||
0xC0..=0xC7 => {
|
||||
// Set 0th bit
|
||||
let reg_id = (instruction - 0xC0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -491,7 +491,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 0));
|
||||
}
|
||||
0xC8...0xCF => {
|
||||
0xC8..=0xCF => {
|
||||
// Set 1th bit
|
||||
let reg_id = (instruction - 0xC8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -500,7 +500,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 1));
|
||||
}
|
||||
0xD0...0xD7 => {
|
||||
0xD0..=0xD7 => {
|
||||
// Set 2nd bit
|
||||
let reg_id = (instruction - 0xD0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -509,7 +509,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 2));
|
||||
}
|
||||
0xD8...0xDF => {
|
||||
0xD8..=0xDF => {
|
||||
// Set 3th bit
|
||||
let reg_id = (instruction - 0xD8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -518,7 +518,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 3));
|
||||
}
|
||||
0xE0...0xE7 => {
|
||||
0xE0..=0xE7 => {
|
||||
// Set 4th bit
|
||||
let reg_id = (instruction - 0xE0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -527,7 +527,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 4));
|
||||
}
|
||||
0xE8...0xEF => {
|
||||
0xE8..=0xEF => {
|
||||
// Set 5th bit
|
||||
let reg_id = (instruction - 0xE8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -536,7 +536,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 5));
|
||||
}
|
||||
0xF0...0xF7 => {
|
||||
0xF0..=0xF7 => {
|
||||
// Set 6th bit
|
||||
let reg_id = (instruction - 0xF0) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -545,7 +545,7 @@ impl CPU {
|
||||
}
|
||||
self.set_8bit_reg(reg_id, reg_content | (1 << 6));
|
||||
}
|
||||
0xF8...0xFF => {
|
||||
0xF8..=0xFF => {
|
||||
// Set 7th bit
|
||||
let reg_id = (instruction - 0xF8) as usize;
|
||||
let reg_content = self.get_8bit_reg(reg_id);
|
||||
@ -1270,14 +1270,14 @@ impl CPU {
|
||||
}
|
||||
|
||||
// LDs
|
||||
0x40...0x47 => self.ld_r_r(REG_N_B, (instruction - 0x40) as usize),
|
||||
0x48...0x4F => self.ld_r_r(REG_N_C, (instruction - 0x48) as usize),
|
||||
0x50...0x57 => self.ld_r_r(REG_N_D, (instruction - 0x50) as usize),
|
||||
0x58...0x5F => self.ld_r_r(REG_N_E, (instruction - 0x58) as usize),
|
||||
0x60...0x67 => self.ld_r_r(REG_N_H, (instruction - 0x60) as usize),
|
||||
0x68...0x6F => self.ld_r_r(REG_N_L, (instruction - 0x68) as usize),
|
||||
0x70...0x75 | 0x77 => self.ld_r_r(REG_N_HL, (instruction - 0x70) as usize),
|
||||
0x78...0x7F => self.ld_r_r(REG_N_A, (instruction - 0x78) as usize),
|
||||
0x40..=0x47 => self.ld_r_r(REG_N_B, (instruction - 0x40) as usize),
|
||||
0x48..=0x4F => self.ld_r_r(REG_N_C, (instruction - 0x48) as usize),
|
||||
0x50..=0x57 => self.ld_r_r(REG_N_D, (instruction - 0x50) as usize),
|
||||
0x58..=0x5F => self.ld_r_r(REG_N_E, (instruction - 0x58) as usize),
|
||||
0x60..=0x67 => self.ld_r_r(REG_N_H, (instruction - 0x60) as usize),
|
||||
0x68..=0x6F => self.ld_r_r(REG_N_L, (instruction - 0x68) as usize),
|
||||
0x70..=0x75 | 0x77 => self.ld_r_r(REG_N_HL, (instruction - 0x70) as usize),
|
||||
0x78..=0x7F => self.ld_r_r(REG_N_A, (instruction - 0x78) as usize),
|
||||
|
||||
// HALT
|
||||
0x76 => {
|
||||
@ -1289,7 +1289,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// ADD
|
||||
0x80...0x87 => {
|
||||
0x80..=0x87 => {
|
||||
let reg_id = (instruction - 0x80) as usize;
|
||||
if self.debug {
|
||||
println!("ADD {}", REG_NAMES[reg_id]);
|
||||
@ -1300,7 +1300,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// ADC
|
||||
0x88...0x8F => {
|
||||
0x88..=0x8F => {
|
||||
let reg_id = (instruction - 0x88) as usize;
|
||||
if self.debug {
|
||||
println!("ADC {}", REG_NAMES[reg_id]);
|
||||
@ -1312,7 +1312,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// SUBs
|
||||
0x90...0x97 => {
|
||||
0x90..=0x97 => {
|
||||
let reg_id = (instruction - 0x90) as usize;
|
||||
if self.debug {
|
||||
println!("SUB {}", REG_NAMES[reg_id]);
|
||||
@ -1323,7 +1323,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// SBC
|
||||
0x98...0x9F => {
|
||||
0x98..=0x9F => {
|
||||
let reg_id = (instruction - 0x98) as usize;
|
||||
if self.debug {
|
||||
println!("SBC {}", REG_NAMES[reg_id]);
|
||||
@ -1334,7 +1334,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// AND
|
||||
0xA0...0xA7 => {
|
||||
0xA0..=0xA7 => {
|
||||
let reg_id = (instruction - 0xA0) as usize;
|
||||
if self.debug {
|
||||
println!("AND {}", REG_NAMES[reg_id]);
|
||||
@ -1350,7 +1350,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// XOR
|
||||
0xA8...0xAF => {
|
||||
0xA8..=0xAF => {
|
||||
let reg_id = (instruction - 0xA8) as usize;
|
||||
if self.debug {
|
||||
println!("XOR {}", REG_NAMES[reg_id]);
|
||||
@ -1366,7 +1366,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// OR
|
||||
0xB0...0xB7 => {
|
||||
0xB0..=0xB7 => {
|
||||
let reg_id = (instruction - 0xB0) as usize;
|
||||
if self.debug {
|
||||
println!("OR {}", REG_NAMES[reg_id]);
|
||||
@ -1382,7 +1382,7 @@ impl CPU {
|
||||
}
|
||||
|
||||
// CP
|
||||
0xB8...0xBF => {
|
||||
0xB8..=0xBF => {
|
||||
let reg_id = (instruction - 0xB8) as usize;
|
||||
if self.debug {
|
||||
println!("CP {}", REG_NAMES[reg_id]);
|
||||
@ -1584,7 +1584,7 @@ impl CPU {
|
||||
self.interconnect.write_byte(addr, self.regs[REG_A]);
|
||||
16
|
||||
}
|
||||
0xEB...0xED => panic!("NON-EXISTING OPCODE"),
|
||||
0xEB..=0xED => panic!("NON-EXISTING OPCODE"),
|
||||
0xEE => {
|
||||
let arg = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
|
||||
@ -272,8 +272,8 @@ impl Display {
|
||||
#[inline]
|
||||
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
||||
match addr {
|
||||
0x8000...0x9FFF => self.vram[(addr - 0x8000) as usize] = val,
|
||||
0xFE00...0xFE9F => self.oam[(addr - 0xFE00) as usize] = val,
|
||||
0x8000..=0x9FFF => self.vram[(addr - 0x8000) as usize] = val,
|
||||
0xFE00..=0xFE9F => self.oam[(addr - 0xFE00) as usize] = val,
|
||||
0xFF40 => self.control = val,
|
||||
0xFF41 => self.status = val,
|
||||
0xFF42 => self.scrolly = val,
|
||||
@ -302,8 +302,8 @@ impl Display {
|
||||
#[inline]
|
||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
||||
match addr {
|
||||
0x8000...0x9FFF => self.vram[(addr - 0x8000) as usize],
|
||||
0xFE00...0xFE9F => self.oam[(addr - 0xFE00) as usize],
|
||||
0x8000..=0x9FFF => self.vram[(addr - 0x8000) as usize],
|
||||
0xFE00..=0xFE9F => self.oam[(addr - 0xFE00) as usize],
|
||||
0xFF40 => self.control,
|
||||
0xFF41 => self.status,
|
||||
0xFF42 => self.scrolly,
|
||||
|
||||
@ -258,21 +258,21 @@ impl Interconnect {
|
||||
// TODO: if some flag set, use bios, otherwise only use rom
|
||||
// For now, just use bios
|
||||
match addr {
|
||||
0x0000...0x100 => {
|
||||
0x0000..=0x100 => {
|
||||
if self.disable_bootrom == 0 {
|
||||
self.bios[addr as usize]
|
||||
} else {
|
||||
self.cartridge.read_byte(addr)
|
||||
}
|
||||
}
|
||||
0x100...0x7FFF => self.cartridge.read_byte(addr),
|
||||
0x8000...0x9FFF => self.display.read_byte(addr),
|
||||
0xA000...0xBFFF => self.cartridge.read_byte(addr),
|
||||
0xC000...0xCFFF => self.ram[(addr - 0xC000) as usize],
|
||||
0xD000...0xDFFF => {
|
||||
0x100..=0x7FFF => self.cartridge.read_byte(addr),
|
||||
0x8000..=0x9FFF => self.display.read_byte(addr),
|
||||
0xA000..=0xBFFF => self.cartridge.read_byte(addr),
|
||||
0xC000..=0xCFFF => self.ram[(addr - 0xC000) as usize],
|
||||
0xD000..=0xDFFF => {
|
||||
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000]
|
||||
}
|
||||
0xE000...0xEFFF => self.ram[(addr - 0xE000) as usize],
|
||||
0xE000..=0xEFFF => self.ram[(addr - 0xE000) as usize],
|
||||
0xFF00 => {
|
||||
if self.joy_switch & KEY_REGULAR == 0 {
|
||||
self.joy_regular_keys
|
||||
@ -283,15 +283,15 @@ impl Interconnect {
|
||||
0x3F
|
||||
}
|
||||
}
|
||||
0xFF01...0xFF02 => self.serial.read_byte(addr),
|
||||
0xFF04...0xFF07 => self.timer.read_byte(addr),
|
||||
0xFF01..=0xFF02 => self.serial.read_byte(addr),
|
||||
0xFF04..=0xFF07 => self.timer.read_byte(addr),
|
||||
0xFF0F => {
|
||||
// println!("Reading IF: {:02X}", self.interrupt_request_flags);
|
||||
self.interrupt_request_flags
|
||||
}
|
||||
0xFF10...0xFF26 => self.sound.read_byte(addr),
|
||||
0xFF30...0xFF3F => self.sound.read_byte(addr),
|
||||
0xFF40...0xFF4B => self.display.read_byte(addr),
|
||||
0xFF10..=0xFF26 => self.sound.read_byte(addr),
|
||||
0xFF30..=0xFF3F => self.sound.read_byte(addr),
|
||||
0xFF40..=0xFF4B => self.display.read_byte(addr),
|
||||
0xFF50 => self.disable_bootrom,
|
||||
0xFF51 => self.vram_dma_source_high,
|
||||
0xFF52 => self.vram_dma_source_low,
|
||||
@ -300,7 +300,7 @@ impl Interconnect {
|
||||
0xFF55 => self.vram_dma_length,
|
||||
0xFF56 => self.infrared_com_port,
|
||||
0xFF70 => self.wram_bank,
|
||||
0xFF80...0xFFFE => self.hiram[(addr - 0xFF80) as usize],
|
||||
0xFF80..=0xFFFE => self.hiram[(addr - 0xFF80) as usize],
|
||||
0xFFFF => self.interrupt,
|
||||
_ => {
|
||||
println!("Read from {:04X} not supported.", addr);
|
||||
@ -326,31 +326,31 @@ impl Interconnect {
|
||||
*/
|
||||
|
||||
match addr {
|
||||
0x0000...0x7FFF => self.cartridge.write_byte(addr, val),
|
||||
0x8000...0x9FFF => self.display.write_byte(addr, val),
|
||||
0xA000...0xBFFF => self.cartridge.write_byte(addr, val),
|
||||
0xC000...0xCFFF => {
|
||||
0x0000..=0x7FFF => self.cartridge.write_byte(addr, val),
|
||||
0x8000..=0x9FFF => self.display.write_byte(addr, val),
|
||||
0xA000..=0xBFFF => self.cartridge.write_byte(addr, val),
|
||||
0xC000..=0xCFFF => {
|
||||
self.ram[(addr - 0xC000) as usize] = val;
|
||||
}
|
||||
0xD000...0xDFFF => {
|
||||
0xD000..=0xDFFF => {
|
||||
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000] = val;
|
||||
}
|
||||
0xFE00...0xFE9F => self.display.write_byte(addr, val), // OAM
|
||||
0xFE00..=0xFE9F => self.display.write_byte(addr, val), // OAM
|
||||
0xFF00 => {
|
||||
// Joystick select
|
||||
self.joy_switch = val;
|
||||
}
|
||||
0xFF01...0xFF02 => self.serial.write_byte(addr, val),
|
||||
0xFF04...0xFF07 => self.timer.write_byte(addr, val),
|
||||
0xFF01..=0xFF02 => self.serial.write_byte(addr, val),
|
||||
0xFF04..=0xFF07 => self.timer.write_byte(addr, val),
|
||||
0xFF0F => {
|
||||
self.interrupt_request_flags = val;
|
||||
}
|
||||
0xFF10...0xFF26 => {
|
||||
0xFF10..=0xFF26 => {
|
||||
self.sound.write_byte(addr, val);
|
||||
}
|
||||
0xFF30...0xFF3F => self.sound.write_byte(addr, val),
|
||||
0xFF30..=0xFF3F => self.sound.write_byte(addr, val),
|
||||
// Exclude DMA transfer, we will do this below
|
||||
0xFF40...0xFF45 | 0xFF47...0xFF4B => {
|
||||
0xFF40..=0xFF45 | 0xFF47..=0xFF4B => {
|
||||
self.display.write_byte(addr, val);
|
||||
}
|
||||
0xFF46 => {
|
||||
@ -404,7 +404,7 @@ impl Interconnect {
|
||||
}
|
||||
}
|
||||
}
|
||||
0xFF80...0xFFFE => {
|
||||
0xFF80..=0xFFFE => {
|
||||
self.hiram[(addr - 0xFF80) as usize] = val;
|
||||
}
|
||||
0xFFFF => {
|
||||
|
||||
@ -43,14 +43,14 @@ fn main() {
|
||||
}
|
||||
|
||||
pub fn read_file<P: AsRef<Path>>(rom_path: P) -> Result<Box<[u8]>, io::Error> {
|
||||
let mut file = try!(fs::File::open(rom_path));
|
||||
let mut file = r#try!(fs::File::open(rom_path));
|
||||
let mut buf = Vec::new();
|
||||
try!(file.read_to_end(&mut buf));
|
||||
r#try!(file.read_to_end(&mut buf));
|
||||
Ok(buf.into_boxed_slice())
|
||||
}
|
||||
|
||||
pub fn write_file<P: AsRef<Path>>(path: P, data: &Box<[u8]>) -> Result<(), io::Error> {
|
||||
let mut file = try!(fs::File::create(path));
|
||||
try!(file.write(&data));
|
||||
let mut file = r#try!(fs::File::create(path));
|
||||
r#try!(file.write(&data));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -30,8 +30,8 @@ impl MBC for NoMBC {
|
||||
|
||||
fn read_byte(&self, addr: u16) -> u8 {
|
||||
match addr {
|
||||
0x0000...0x7FFF => self.rom[addr as usize],
|
||||
0xA000...0xBFFF => {
|
||||
0x0000..=0x7FFF => self.rom[addr as usize],
|
||||
0xA000..=0xBFFF => {
|
||||
// TODO: Check for ram
|
||||
let addr = (addr as usize) - 0xA000;
|
||||
|
||||
|
||||
@ -49,14 +49,14 @@ impl MBC for MBC1 {
|
||||
|
||||
fn read_byte(&self, addr: u16) -> u8 {
|
||||
match addr {
|
||||
0x0000...0x3FFF => self.rom[addr as usize],
|
||||
0x4000...0x7FFF => {
|
||||
0x0000..=0x3FFF => self.rom[addr as usize],
|
||||
0x4000..=0x7FFF => {
|
||||
let addr = addr - 0x4000;
|
||||
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
|
||||
let val: u8 = self.rom[abs_addr];
|
||||
val
|
||||
}
|
||||
0xA000...0xBFFF => {
|
||||
0xA000..=0xBFFF => {
|
||||
let addr = addr - 0xA000;
|
||||
println!("Access [{:02X}] {:04X}", self.active_ram_bank(), addr);
|
||||
self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize]
|
||||
@ -69,12 +69,12 @@ impl MBC for MBC1 {
|
||||
|
||||
fn write_byte(&mut self, addr: u16, val: u8) {
|
||||
match addr {
|
||||
0x0000...0x1FFF => match val {
|
||||
0x0000..=0x1FFF => match val {
|
||||
0x0A => self.ram_enable = true,
|
||||
0x00 => self.ram_enable = false,
|
||||
_ => println!("Unknown MBC1 value {:02X} for {:04X}", val, addr),
|
||||
},
|
||||
0x2000...0x3FFF => {
|
||||
0x2000..=0x3FFF => {
|
||||
if val != 0 {
|
||||
self.rom_bank_no = val & 0x1F;
|
||||
} else {
|
||||
@ -82,11 +82,11 @@ impl MBC for MBC1 {
|
||||
}
|
||||
println!("MBC1: Selecting bank {:02X}", self.rom_bank_no);
|
||||
}
|
||||
0x4000...0x5FFF => {
|
||||
0x4000..=0x5FFF => {
|
||||
// Upper ROM bank / RAM bank select
|
||||
self.bank_no_high = val & 3;
|
||||
}
|
||||
0x6000...0x7FFF => {
|
||||
0x6000..=0x7FFF => {
|
||||
// Select upper ROM bytes or RAM bytes
|
||||
match val {
|
||||
0 => self.bank_mode = BankMode::RomBankMode,
|
||||
|
||||
@ -29,14 +29,14 @@ impl MBC for MBC2 {
|
||||
|
||||
fn read_byte(&self, addr: u16) -> u8 {
|
||||
match addr {
|
||||
0x0000...0x3FFF => self.rom[addr as usize],
|
||||
0x4000...0x7FFF => {
|
||||
0x0000..=0x3FFF => self.rom[addr as usize],
|
||||
0x4000..=0x7FFF => {
|
||||
let addr = addr - 0x4000;
|
||||
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
|
||||
let val: u8 = self.rom[abs_addr];
|
||||
val
|
||||
}
|
||||
0xA000...0xA1FF => {
|
||||
0xA000..=0xA1FF => {
|
||||
let addr = addr - 0xA000;
|
||||
self.ram[addr as usize] & 0x0F
|
||||
}
|
||||
@ -48,7 +48,7 @@ impl MBC for MBC2 {
|
||||
|
||||
fn write_byte(&mut self, addr: u16, val: u8) {
|
||||
match addr {
|
||||
0x0000...0x1FFF => {
|
||||
0x0000..=0x1FFF => {
|
||||
// To enable the ram, the LSB of the higher byte must be 0
|
||||
if addr & 0x0100 == 0 {
|
||||
match val {
|
||||
@ -60,7 +60,7 @@ impl MBC for MBC2 {
|
||||
println!("MBC2: Write {:02X} to {:04X} has no effect", val, addr);
|
||||
}
|
||||
}
|
||||
0x2000...0x3FFF => {
|
||||
0x2000..=0x3FFF => {
|
||||
if addr & 0x0100 == 1 {
|
||||
self.rom_bank_no = val & 0x0F;
|
||||
println!("MBC2: Selecting bank {:02X}", self.rom_bank_no);
|
||||
|
||||
@ -34,20 +34,20 @@ impl MBC for MBC3 {
|
||||
|
||||
fn read_byte(&self, addr: u16) -> u8 {
|
||||
match addr {
|
||||
0x0000...0x3FFF => self.rom[addr as usize],
|
||||
0x4000...0x7FFF => {
|
||||
0x0000..=0x3FFF => self.rom[addr as usize],
|
||||
0x4000..=0x7FFF => {
|
||||
let addr = addr - 0x4000;
|
||||
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
|
||||
let val: u8 = self.rom[abs_addr];
|
||||
val
|
||||
}
|
||||
0xA000...0xBFFF => {
|
||||
0xA000..=0xBFFF => {
|
||||
let addr = addr - 0xA000;
|
||||
match self.active_ram_bank() {
|
||||
0x00...0x03 => {
|
||||
0x00..=0x03 => {
|
||||
self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize]
|
||||
}
|
||||
0x08...0x0C => {
|
||||
0x08..=0x0C => {
|
||||
// TODO
|
||||
println!("MBC3: Ignoring RTC read");
|
||||
0
|
||||
@ -66,21 +66,21 @@ impl MBC for MBC3 {
|
||||
|
||||
fn write_byte(&mut self, addr: u16, val: u8) {
|
||||
match addr {
|
||||
0x0000...0x1FFF => match val {
|
||||
0x0000..=0x1FFF => match val {
|
||||
0x0A => self.ram_rtc_enabled = true,
|
||||
0x00 => self.ram_rtc_enabled = false,
|
||||
_ => println!("MBC3: Unknown MBC value {:02X} for {:04X}", val, addr),
|
||||
},
|
||||
0x2000...0x3FFF => self.rom_bank_no = val & 0x7F,
|
||||
0x4000...0x5FFF => {
|
||||
0x2000..=0x3FFF => self.rom_bank_no = val & 0x7F,
|
||||
0x4000..=0x5FFF => {
|
||||
// RAM bank select
|
||||
match val {
|
||||
0x00...0x03 => self.ram_bank_no = val,
|
||||
0x08...0x0C => self.ram_bank_no = val,
|
||||
0x00..=0x03 => self.ram_bank_no = val,
|
||||
0x08..=0x0C => self.ram_bank_no = val,
|
||||
_ => panic!("MBC3: Unknown RAM bank {:02X}", val),
|
||||
}
|
||||
}
|
||||
0x6000...0x7FFF => {
|
||||
0x6000..=0x7FFF => {
|
||||
// Latch clock data
|
||||
match val {
|
||||
0x00 => println!("latch = 0"),
|
||||
@ -88,14 +88,14 @@ impl MBC for MBC3 {
|
||||
_ => panic!("MBC3: Unknown latch value {:02X}", val),
|
||||
}
|
||||
}
|
||||
0xA000...0xBFFF => {
|
||||
0xA000..=0xBFFF => {
|
||||
let addr = addr - 0xA000;
|
||||
match self.active_ram_bank() {
|
||||
0x00...0x03 => {
|
||||
0x00..=0x03 => {
|
||||
let active_bank = self.active_ram_bank() as usize;
|
||||
self.ram[active_bank * 0x2000 + addr as usize] = val;
|
||||
}
|
||||
0x08...0x0C => {
|
||||
0x08..=0x0C => {
|
||||
// TODO
|
||||
println!("MBC3: Ignoring RTC write ({:02X})", val);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user