Move to edition=2018

This commit is contained in:
Kevin Hamacher 2020-02-14 11:23:31 +01:00
parent 50471f1ec6
commit ddb1da4367
10 changed files with 119 additions and 118 deletions

View File

@ -2,6 +2,7 @@
name = "gbc" name = "gbc"
version = "0.1.0" version = "0.1.0"
authors = ["Kevin Hamacher <kevin.hamacher@rub.de>"] authors = ["Kevin Hamacher <kevin.hamacher@rub.de>"]
edition = '2018'
[dependencies] [dependencies]
sdl2 = "*" sdl2 = "*"

View File

@ -18,17 +18,17 @@ enum RamSize {
} }
pub struct Cartridge { pub struct Cartridge {
mbc: Box<super::mbc::mbc::MBC>, mbc: Box<dyn super::mbc::mbc::MBC>,
savefile: Option<String>, savefile: Option<String>,
} }
impl Cartridge { impl Cartridge {
pub fn new(rom: Box<[u8]>, save_file: Option<String>) -> Cartridge { pub fn new(rom: Box<[u8]>, save_file: Option<String>) -> Cartridge {
let mbc_type: MemoryBankControllerType = match rom[0x0147] { let mbc_type: MemoryBankControllerType = match rom[0x0147] {
0x00 | 0x08...0x09 => MemoryBankControllerType::None, 0x00 | 0x08..=0x09 => MemoryBankControllerType::None,
0x01...0x03 => MemoryBankControllerType::MBC1, 0x01..=0x03 => MemoryBankControllerType::MBC1,
0x05...0x06 => MemoryBankControllerType::MBC2, 0x05..=0x06 => MemoryBankControllerType::MBC2,
0x0F...0x13 => MemoryBankControllerType::MBC3, 0x0F..=0x13 => MemoryBankControllerType::MBC3,
// 0xFF => MemoryBankControllerType::HuC1, // 0xFF => MemoryBankControllerType::HuC1,
_ => panic!("Unsupported MBC type: {:02X}", rom[0x0147]), _ => panic!("Unsupported MBC type: {:02X}", rom[0x0147]),
}; };
@ -37,7 +37,7 @@ impl Cartridge {
let rom_banks: u16 = match rom[0x0148] { let rom_banks: u16 = match rom[0x0148] {
0x00 => 0, 0x00 => 0,
0x01...0x07 => 2u16.pow(rom[0x0148] as u32 + 1), 0x01..=0x07 => 2u16.pow(rom[0x0148] as u32 + 1),
0x52 => 72, 0x52 => 72,
0x53 => 80, 0x53 => 80,
0x54 => 96, 0x54 => 96,
@ -57,7 +57,7 @@ impl Cartridge {
let ram = Cartridge::load_savefile(&save_file, ram_size); 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::None => Box::new(super::mbc::mbc::NoMBC::new(rom, ram)),
MemoryBankControllerType::MBC1 => Box::new(super::mbc::mbc1::MBC1::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)), MemoryBankControllerType::MBC2 => Box::new(super::mbc::mbc2::MBC2::new(rom, ram)),

View File

@ -155,7 +155,7 @@ impl CPU {
self.set_clear_flag(FLAG_C, new > old || (new == old && c == 1)); self.set_clear_flag(FLAG_C, new > old || (new == old && c == 1));
self.set_clear_flag( self.set_clear_flag(
FLAG_H, 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; self.ip += 1;
match instruction { match instruction {
0x00...0x07 => { 0x00..=0x07 => {
let reg_id = (instruction - 0x00) as usize; let reg_id = (instruction - 0x00) as usize;
let val = self.get_8bit_reg(reg_id); let val = self.get_8bit_reg(reg_id);
if self.debug { if self.debug {
@ -212,7 +212,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); self.clear_flag(FLAG_H);
} }
0x08...0x0F => { 0x08..=0x0F => {
let reg_id = (instruction - 0x08) as usize; let reg_id = (instruction - 0x08) as usize;
let val = self.get_8bit_reg(reg_id); let val = self.get_8bit_reg(reg_id);
if self.debug { if self.debug {
@ -230,7 +230,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); self.clear_flag(FLAG_H);
} }
0x10...0x17 => { 0x10..=0x17 => {
let reg_id = (instruction - 0x10) as usize; let reg_id = (instruction - 0x10) as usize;
let val = self.get_8bit_reg(reg_id); let val = self.get_8bit_reg(reg_id);
if self.debug { if self.debug {
@ -250,7 +250,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); self.clear_flag(FLAG_H);
} }
0x18...0x1F => { 0x18..=0x1F => {
// RR // RR
let reg_id = (instruction - 0x18) as usize; let reg_id = (instruction - 0x18) as usize;
let val = self.get_8bit_reg(reg_id); let val = self.get_8bit_reg(reg_id);
@ -271,7 +271,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); self.clear_flag(FLAG_H);
} }
0x20...0x27 => { 0x20..=0x27 => {
let reg_id = (instruction - 0x20) as usize; let reg_id = (instruction - 0x20) as usize;
if self.debug { if self.debug {
println!("SLA {}", REG_NAMES[reg_id]); println!("SLA {}", REG_NAMES[reg_id]);
@ -282,7 +282,7 @@ impl CPU {
self.set_clear_flag(FLAG_Z, v & 0x7F == 0); self.set_clear_flag(FLAG_Z, v & 0x7F == 0);
self.set_8bit_reg(reg_id, v << 1); self.set_8bit_reg(reg_id, v << 1);
} }
0x28...0x2F => { 0x28..=0x2F => {
let reg_id = (instruction - 0x28) as usize; let reg_id = (instruction - 0x28) as usize;
if self.debug { if self.debug {
println!("SRA {}", REG_NAMES[reg_id]); 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_Z, nv == 0);
self.set_clear_flag(FLAG_C, v & 1 == 1); self.set_clear_flag(FLAG_C, v & 1 == 1);
} }
0x30...0x37 => { 0x30..=0x37 => {
let reg_id = (instruction - 0x30) as usize; let reg_id = (instruction - 0x30) as usize;
if self.debug { if self.debug {
println!("SWAP {}", REG_NAMES[reg_id]); println!("SWAP {}", REG_NAMES[reg_id]);
@ -304,7 +304,7 @@ impl CPU {
self.flags = 0; self.flags = 0;
self.set_clear_flag(FLAG_Z, v == 0); self.set_clear_flag(FLAG_Z, v == 0);
} }
0x38...0x3F => { 0x38..=0x3F => {
let reg_id = (instruction - 0x38) as usize; let reg_id = (instruction - 0x38) as usize;
if self.debug { if self.debug {
println!("SRL {}", REG_NAMES[reg_id]); println!("SRL {}", REG_NAMES[reg_id]);
@ -318,7 +318,7 @@ impl CPU {
} }
// Bits // Bits
0x40...0x47 => { 0x40..=0x47 => {
// Test 0th bit // Test 0th bit
let reg_id = (instruction - 0x40) as usize; let reg_id = (instruction - 0x40) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -329,7 +329,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x48...0x4F => { 0x48..=0x4F => {
// Test 1th bit // Test 1th bit
let reg_id = (instruction - 0x48) as usize; let reg_id = (instruction - 0x48) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -340,7 +340,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x50...0x57 => { 0x50..=0x57 => {
// Test 2th bit // Test 2th bit
let reg_id = (instruction - 0x50) as usize; let reg_id = (instruction - 0x50) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -351,7 +351,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x58...0x5F => { 0x58..=0x5F => {
// Test 3th bit // Test 3th bit
let reg_id = (instruction - 0x58) as usize; let reg_id = (instruction - 0x58) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -362,7 +362,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x60...0x67 => { 0x60..=0x67 => {
// Test 4th bit // Test 4th bit
let reg_id = (instruction - 0x60) as usize; let reg_id = (instruction - 0x60) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -373,7 +373,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x68...0x6F => { 0x68..=0x6F => {
// Test 5th bit // Test 5th bit
let reg_id = (instruction - 0x68) as usize; let reg_id = (instruction - 0x68) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -384,7 +384,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x70...0x77 => { 0x70..=0x77 => {
// Test 6th bit // Test 6th bit
let reg_id = (instruction - 0x70) as usize; let reg_id = (instruction - 0x70) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -395,7 +395,7 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.set_flag(FLAG_H); self.set_flag(FLAG_H);
} }
0x78...0x7F => { 0x78..=0x7F => {
// Test 7th bit // Test 7th bit
let reg_id = (instruction - 0x78) as usize; let reg_id = (instruction - 0x78) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -408,7 +408,7 @@ impl CPU {
} }
// Reset bits // Reset bits
0x80...0x87 => { 0x80..=0x87 => {
// Reset 0th bit // Reset 0th bit
let reg_id = (instruction - 0x80) as usize; let reg_id = (instruction - 0x80) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 0));
} }
0x88...0x8F => { 0x88..=0x8F => {
// Reset 1th bit // Reset 1th bit
let reg_id = (instruction - 0x88) as usize; let reg_id = (instruction - 0x88) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 1));
} }
0x90...0x97 => { 0x90..=0x97 => {
// Reset 2nd bit // Reset 2nd bit
let reg_id = (instruction - 0x90) as usize; let reg_id = (instruction - 0x90) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 2));
} }
0x98...0x9F => { 0x98..=0x9F => {
// Reset 3th bit // Reset 3th bit
let reg_id = (instruction - 0x98) as usize; let reg_id = (instruction - 0x98) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 3));
} }
0xA0...0xA7 => { 0xA0..=0xA7 => {
// Reset 4th bit // Reset 4th bit
let reg_id = (instruction - 0xA0) as usize; let reg_id = (instruction - 0xA0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 4));
} }
0xA8...0xAF => { 0xA8..=0xAF => {
// Reset 5th bit // Reset 5th bit
let reg_id = (instruction - 0xA8) as usize; let reg_id = (instruction - 0xA8) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 5));
} }
0xB0...0xB7 => { 0xB0..=0xB7 => {
// Reset 6th bit // Reset 6th bit
let reg_id = (instruction - 0xB0) as usize; let reg_id = (instruction - 0xB0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content & !(1 << 6));
} }
0xB8...0xBF => { 0xB8..=0xBF => {
// Reset 7th bit // Reset 7th bit
let reg_id = (instruction - 0xB8) as usize; let reg_id = (instruction - 0xB8) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -482,7 +482,7 @@ impl CPU {
} }
// Set bits // Set bits
0xC0...0xC7 => { 0xC0..=0xC7 => {
// Set 0th bit // Set 0th bit
let reg_id = (instruction - 0xC0) as usize; let reg_id = (instruction - 0xC0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 0));
} }
0xC8...0xCF => { 0xC8..=0xCF => {
// Set 1th bit // Set 1th bit
let reg_id = (instruction - 0xC8) as usize; let reg_id = (instruction - 0xC8) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 1));
} }
0xD0...0xD7 => { 0xD0..=0xD7 => {
// Set 2nd bit // Set 2nd bit
let reg_id = (instruction - 0xD0) as usize; let reg_id = (instruction - 0xD0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 2));
} }
0xD8...0xDF => { 0xD8..=0xDF => {
// Set 3th bit // Set 3th bit
let reg_id = (instruction - 0xD8) as usize; let reg_id = (instruction - 0xD8) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 3));
} }
0xE0...0xE7 => { 0xE0..=0xE7 => {
// Set 4th bit // Set 4th bit
let reg_id = (instruction - 0xE0) as usize; let reg_id = (instruction - 0xE0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 4));
} }
0xE8...0xEF => { 0xE8..=0xEF => {
// Set 5th bit // Set 5th bit
let reg_id = (instruction - 0xE8) as usize; let reg_id = (instruction - 0xE8) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 5));
} }
0xF0...0xF7 => { 0xF0..=0xF7 => {
// Set 6th bit // Set 6th bit
let reg_id = (instruction - 0xF0) as usize; let reg_id = (instruction - 0xF0) as usize;
let reg_content = self.get_8bit_reg(reg_id); 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)); self.set_8bit_reg(reg_id, reg_content | (1 << 6));
} }
0xF8...0xFF => { 0xF8..=0xFF => {
// Set 7th bit // Set 7th bit
let reg_id = (instruction - 0xF8) as usize; let reg_id = (instruction - 0xF8) as usize;
let reg_content = self.get_8bit_reg(reg_id); let reg_content = self.get_8bit_reg(reg_id);
@ -1270,14 +1270,14 @@ impl CPU {
} }
// LDs // LDs
0x40...0x47 => self.ld_r_r(REG_N_B, (instruction - 0x40) 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), 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), 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), 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), 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), 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), 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), 0x78..=0x7F => self.ld_r_r(REG_N_A, (instruction - 0x78) as usize),
// HALT // HALT
0x76 => { 0x76 => {
@ -1289,7 +1289,7 @@ impl CPU {
} }
// ADD // ADD
0x80...0x87 => { 0x80..=0x87 => {
let reg_id = (instruction - 0x80) as usize; let reg_id = (instruction - 0x80) as usize;
if self.debug { if self.debug {
println!("ADD {}", REG_NAMES[reg_id]); println!("ADD {}", REG_NAMES[reg_id]);
@ -1300,7 +1300,7 @@ impl CPU {
} }
// ADC // ADC
0x88...0x8F => { 0x88..=0x8F => {
let reg_id = (instruction - 0x88) as usize; let reg_id = (instruction - 0x88) as usize;
if self.debug { if self.debug {
println!("ADC {}", REG_NAMES[reg_id]); println!("ADC {}", REG_NAMES[reg_id]);
@ -1312,7 +1312,7 @@ impl CPU {
} }
// SUBs // SUBs
0x90...0x97 => { 0x90..=0x97 => {
let reg_id = (instruction - 0x90) as usize; let reg_id = (instruction - 0x90) as usize;
if self.debug { if self.debug {
println!("SUB {}", REG_NAMES[reg_id]); println!("SUB {}", REG_NAMES[reg_id]);
@ -1323,7 +1323,7 @@ impl CPU {
} }
// SBC // SBC
0x98...0x9F => { 0x98..=0x9F => {
let reg_id = (instruction - 0x98) as usize; let reg_id = (instruction - 0x98) as usize;
if self.debug { if self.debug {
println!("SBC {}", REG_NAMES[reg_id]); println!("SBC {}", REG_NAMES[reg_id]);
@ -1334,7 +1334,7 @@ impl CPU {
} }
// AND // AND
0xA0...0xA7 => { 0xA0..=0xA7 => {
let reg_id = (instruction - 0xA0) as usize; let reg_id = (instruction - 0xA0) as usize;
if self.debug { if self.debug {
println!("AND {}", REG_NAMES[reg_id]); println!("AND {}", REG_NAMES[reg_id]);
@ -1350,7 +1350,7 @@ impl CPU {
} }
// XOR // XOR
0xA8...0xAF => { 0xA8..=0xAF => {
let reg_id = (instruction - 0xA8) as usize; let reg_id = (instruction - 0xA8) as usize;
if self.debug { if self.debug {
println!("XOR {}", REG_NAMES[reg_id]); println!("XOR {}", REG_NAMES[reg_id]);
@ -1366,7 +1366,7 @@ impl CPU {
} }
// OR // OR
0xB0...0xB7 => { 0xB0..=0xB7 => {
let reg_id = (instruction - 0xB0) as usize; let reg_id = (instruction - 0xB0) as usize;
if self.debug { if self.debug {
println!("OR {}", REG_NAMES[reg_id]); println!("OR {}", REG_NAMES[reg_id]);
@ -1382,7 +1382,7 @@ impl CPU {
} }
// CP // CP
0xB8...0xBF => { 0xB8..=0xBF => {
let reg_id = (instruction - 0xB8) as usize; let reg_id = (instruction - 0xB8) as usize;
if self.debug { if self.debug {
println!("CP {}", REG_NAMES[reg_id]); println!("CP {}", REG_NAMES[reg_id]);
@ -1584,7 +1584,7 @@ impl CPU {
self.interconnect.write_byte(addr, self.regs[REG_A]); self.interconnect.write_byte(addr, self.regs[REG_A]);
16 16
} }
0xEB...0xED => panic!("NON-EXISTING OPCODE"), 0xEB..=0xED => panic!("NON-EXISTING OPCODE"),
0xEE => { 0xEE => {
let arg = self.load_args(1)[0]; let arg = self.load_args(1)[0];
if self.debug { if self.debug {

View File

@ -272,8 +272,8 @@ impl Display {
#[inline] #[inline]
pub fn write_byte(&mut self, addr: u16, val: u8) { pub fn write_byte(&mut self, addr: u16, val: u8) {
match addr { match addr {
0x8000...0x9FFF => self.vram[(addr - 0x8000) as usize] = val, 0x8000..=0x9FFF => self.vram[(addr - 0x8000) as usize] = val,
0xFE00...0xFE9F => self.oam[(addr - 0xFE00) as usize] = val, 0xFE00..=0xFE9F => self.oam[(addr - 0xFE00) as usize] = val,
0xFF40 => self.control = val, 0xFF40 => self.control = val,
0xFF41 => self.status = val, 0xFF41 => self.status = val,
0xFF42 => self.scrolly = val, 0xFF42 => self.scrolly = val,
@ -302,8 +302,8 @@ impl Display {
#[inline] #[inline]
pub fn read_byte(&self, addr: u16) -> u8 { pub fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x8000...0x9FFF => self.vram[(addr - 0x8000) as usize], 0x8000..=0x9FFF => self.vram[(addr - 0x8000) as usize],
0xFE00...0xFE9F => self.oam[(addr - 0xFE00) as usize], 0xFE00..=0xFE9F => self.oam[(addr - 0xFE00) as usize],
0xFF40 => self.control, 0xFF40 => self.control,
0xFF41 => self.status, 0xFF41 => self.status,
0xFF42 => self.scrolly, 0xFF42 => self.scrolly,

View File

@ -258,21 +258,21 @@ impl Interconnect {
// TODO: if some flag set, use bios, otherwise only use rom // TODO: if some flag set, use bios, otherwise only use rom
// For now, just use bios // For now, just use bios
match addr { match addr {
0x0000...0x100 => { 0x0000..=0x100 => {
if self.disable_bootrom == 0 { if self.disable_bootrom == 0 {
self.bios[addr as usize] self.bios[addr as usize]
} else { } else {
self.cartridge.read_byte(addr) self.cartridge.read_byte(addr)
} }
} }
0x100...0x7FFF => self.cartridge.read_byte(addr), 0x100..=0x7FFF => self.cartridge.read_byte(addr),
0x8000...0x9FFF => self.display.read_byte(addr), 0x8000..=0x9FFF => self.display.read_byte(addr),
0xA000...0xBFFF => self.cartridge.read_byte(addr), 0xA000..=0xBFFF => self.cartridge.read_byte(addr),
0xC000...0xCFFF => self.ram[(addr - 0xC000) as usize], 0xC000..=0xCFFF => self.ram[(addr - 0xC000) as usize],
0xD000...0xDFFF => { 0xD000..=0xDFFF => {
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000] 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 => { 0xFF00 => {
if self.joy_switch & KEY_REGULAR == 0 { if self.joy_switch & KEY_REGULAR == 0 {
self.joy_regular_keys self.joy_regular_keys
@ -283,15 +283,15 @@ impl Interconnect {
0x3F 0x3F
} }
} }
0xFF01...0xFF02 => self.serial.read_byte(addr), 0xFF01..=0xFF02 => self.serial.read_byte(addr),
0xFF04...0xFF07 => self.timer.read_byte(addr), 0xFF04..=0xFF07 => self.timer.read_byte(addr),
0xFF0F => { 0xFF0F => {
// println!("Reading IF: {:02X}", self.interrupt_request_flags); // println!("Reading IF: {:02X}", self.interrupt_request_flags);
self.interrupt_request_flags self.interrupt_request_flags
} }
0xFF10...0xFF26 => self.sound.read_byte(addr), 0xFF10..=0xFF26 => self.sound.read_byte(addr),
0xFF30...0xFF3F => self.sound.read_byte(addr), 0xFF30..=0xFF3F => self.sound.read_byte(addr),
0xFF40...0xFF4B => self.display.read_byte(addr), 0xFF40..=0xFF4B => self.display.read_byte(addr),
0xFF50 => self.disable_bootrom, 0xFF50 => self.disable_bootrom,
0xFF51 => self.vram_dma_source_high, 0xFF51 => self.vram_dma_source_high,
0xFF52 => self.vram_dma_source_low, 0xFF52 => self.vram_dma_source_low,
@ -300,7 +300,7 @@ impl Interconnect {
0xFF55 => self.vram_dma_length, 0xFF55 => self.vram_dma_length,
0xFF56 => self.infrared_com_port, 0xFF56 => self.infrared_com_port,
0xFF70 => self.wram_bank, 0xFF70 => self.wram_bank,
0xFF80...0xFFFE => self.hiram[(addr - 0xFF80) as usize], 0xFF80..=0xFFFE => self.hiram[(addr - 0xFF80) as usize],
0xFFFF => self.interrupt, 0xFFFF => self.interrupt,
_ => { _ => {
println!("Read from {:04X} not supported.", addr); println!("Read from {:04X} not supported.", addr);
@ -326,31 +326,31 @@ impl Interconnect {
*/ */
match addr { match addr {
0x0000...0x7FFF => self.cartridge.write_byte(addr, val), 0x0000..=0x7FFF => self.cartridge.write_byte(addr, val),
0x8000...0x9FFF => self.display.write_byte(addr, val), 0x8000..=0x9FFF => self.display.write_byte(addr, val),
0xA000...0xBFFF => self.cartridge.write_byte(addr, val), 0xA000..=0xBFFF => self.cartridge.write_byte(addr, val),
0xC000...0xCFFF => { 0xC000..=0xCFFF => {
self.ram[(addr - 0xC000) as usize] = val; self.ram[(addr - 0xC000) as usize] = val;
} }
0xD000...0xDFFF => { 0xD000..=0xDFFF => {
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000] = val; 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 => { 0xFF00 => {
// Joystick select // Joystick select
self.joy_switch = val; self.joy_switch = val;
} }
0xFF01...0xFF02 => self.serial.write_byte(addr, val), 0xFF01..=0xFF02 => self.serial.write_byte(addr, val),
0xFF04...0xFF07 => self.timer.write_byte(addr, val), 0xFF04..=0xFF07 => self.timer.write_byte(addr, val),
0xFF0F => { 0xFF0F => {
self.interrupt_request_flags = val; self.interrupt_request_flags = val;
} }
0xFF10...0xFF26 => { 0xFF10..=0xFF26 => {
self.sound.write_byte(addr, val); 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 // Exclude DMA transfer, we will do this below
0xFF40...0xFF45 | 0xFF47...0xFF4B => { 0xFF40..=0xFF45 | 0xFF47..=0xFF4B => {
self.display.write_byte(addr, val); self.display.write_byte(addr, val);
} }
0xFF46 => { 0xFF46 => {
@ -404,7 +404,7 @@ impl Interconnect {
} }
} }
} }
0xFF80...0xFFFE => { 0xFF80..=0xFFFE => {
self.hiram[(addr - 0xFF80) as usize] = val; self.hiram[(addr - 0xFF80) as usize] = val;
} }
0xFFFF => { 0xFFFF => {

View File

@ -43,14 +43,14 @@ fn main() {
} }
pub fn read_file<P: AsRef<Path>>(rom_path: P) -> Result<Box<[u8]>, io::Error> { 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(); 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()) Ok(buf.into_boxed_slice())
} }
pub fn write_file<P: AsRef<Path>>(path: P, data: &Box<[u8]>) -> Result<(), io::Error> { pub fn write_file<P: AsRef<Path>>(path: P, data: &Box<[u8]>) -> Result<(), io::Error> {
let mut file = try!(fs::File::create(path)); let mut file = r#try!(fs::File::create(path));
try!(file.write(&data)); r#try!(file.write(&data));
Ok(()) Ok(())
} }

View File

@ -30,8 +30,8 @@ impl MBC for NoMBC {
fn read_byte(&self, addr: u16) -> u8 { fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x0000...0x7FFF => self.rom[addr as usize], 0x0000..=0x7FFF => self.rom[addr as usize],
0xA000...0xBFFF => { 0xA000..=0xBFFF => {
// TODO: Check for ram // TODO: Check for ram
let addr = (addr as usize) - 0xA000; let addr = (addr as usize) - 0xA000;

View File

@ -49,14 +49,14 @@ impl MBC for MBC1 {
fn read_byte(&self, addr: u16) -> u8 { fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x0000...0x3FFF => self.rom[addr as usize], 0x0000..=0x3FFF => self.rom[addr as usize],
0x4000...0x7FFF => { 0x4000..=0x7FFF => {
let addr = addr - 0x4000; let addr = addr - 0x4000;
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000; let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
let val: u8 = self.rom[abs_addr]; let val: u8 = self.rom[abs_addr];
val val
} }
0xA000...0xBFFF => { 0xA000..=0xBFFF => {
let addr = addr - 0xA000; let addr = addr - 0xA000;
println!("Access [{:02X}] {:04X}", self.active_ram_bank(), addr); println!("Access [{:02X}] {:04X}", self.active_ram_bank(), addr);
self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize] 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) { fn write_byte(&mut self, addr: u16, val: u8) {
match addr { match addr {
0x0000...0x1FFF => match val { 0x0000..=0x1FFF => match val {
0x0A => self.ram_enable = true, 0x0A => self.ram_enable = true,
0x00 => self.ram_enable = false, 0x00 => self.ram_enable = false,
_ => println!("Unknown MBC1 value {:02X} for {:04X}", val, addr), _ => println!("Unknown MBC1 value {:02X} for {:04X}", val, addr),
}, },
0x2000...0x3FFF => { 0x2000..=0x3FFF => {
if val != 0 { if val != 0 {
self.rom_bank_no = val & 0x1F; self.rom_bank_no = val & 0x1F;
} else { } else {
@ -82,11 +82,11 @@ impl MBC for MBC1 {
} }
println!("MBC1: Selecting bank {:02X}", self.rom_bank_no); println!("MBC1: Selecting bank {:02X}", self.rom_bank_no);
} }
0x4000...0x5FFF => { 0x4000..=0x5FFF => {
// Upper ROM bank / RAM bank select // Upper ROM bank / RAM bank select
self.bank_no_high = val & 3; self.bank_no_high = val & 3;
} }
0x6000...0x7FFF => { 0x6000..=0x7FFF => {
// Select upper ROM bytes or RAM bytes // Select upper ROM bytes or RAM bytes
match val { match val {
0 => self.bank_mode = BankMode::RomBankMode, 0 => self.bank_mode = BankMode::RomBankMode,

View File

@ -29,14 +29,14 @@ impl MBC for MBC2 {
fn read_byte(&self, addr: u16) -> u8 { fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x0000...0x3FFF => self.rom[addr as usize], 0x0000..=0x3FFF => self.rom[addr as usize],
0x4000...0x7FFF => { 0x4000..=0x7FFF => {
let addr = addr - 0x4000; let addr = addr - 0x4000;
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000; let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
let val: u8 = self.rom[abs_addr]; let val: u8 = self.rom[abs_addr];
val val
} }
0xA000...0xA1FF => { 0xA000..=0xA1FF => {
let addr = addr - 0xA000; let addr = addr - 0xA000;
self.ram[addr as usize] & 0x0F self.ram[addr as usize] & 0x0F
} }
@ -48,7 +48,7 @@ impl MBC for MBC2 {
fn write_byte(&mut self, addr: u16, val: u8) { fn write_byte(&mut self, addr: u16, val: u8) {
match addr { match addr {
0x0000...0x1FFF => { 0x0000..=0x1FFF => {
// To enable the ram, the LSB of the higher byte must be 0 // To enable the ram, the LSB of the higher byte must be 0
if addr & 0x0100 == 0 { if addr & 0x0100 == 0 {
match val { match val {
@ -60,7 +60,7 @@ impl MBC for MBC2 {
println!("MBC2: Write {:02X} to {:04X} has no effect", val, addr); println!("MBC2: Write {:02X} to {:04X} has no effect", val, addr);
} }
} }
0x2000...0x3FFF => { 0x2000..=0x3FFF => {
if addr & 0x0100 == 1 { if addr & 0x0100 == 1 {
self.rom_bank_no = val & 0x0F; self.rom_bank_no = val & 0x0F;
println!("MBC2: Selecting bank {:02X}", self.rom_bank_no); println!("MBC2: Selecting bank {:02X}", self.rom_bank_no);

View File

@ -34,20 +34,20 @@ impl MBC for MBC3 {
fn read_byte(&self, addr: u16) -> u8 { fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x0000...0x3FFF => self.rom[addr as usize], 0x0000..=0x3FFF => self.rom[addr as usize],
0x4000...0x7FFF => { 0x4000..=0x7FFF => {
let addr = addr - 0x4000; let addr = addr - 0x4000;
let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000; let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000;
let val: u8 = self.rom[abs_addr]; let val: u8 = self.rom[abs_addr];
val val
} }
0xA000...0xBFFF => { 0xA000..=0xBFFF => {
let addr = addr - 0xA000; let addr = addr - 0xA000;
match self.active_ram_bank() { match self.active_ram_bank() {
0x00...0x03 => { 0x00..=0x03 => {
self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize] self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize]
} }
0x08...0x0C => { 0x08..=0x0C => {
// TODO // TODO
println!("MBC3: Ignoring RTC read"); println!("MBC3: Ignoring RTC read");
0 0
@ -66,21 +66,21 @@ impl MBC for MBC3 {
fn write_byte(&mut self, addr: u16, val: u8) { fn write_byte(&mut self, addr: u16, val: u8) {
match addr { match addr {
0x0000...0x1FFF => match val { 0x0000..=0x1FFF => match val {
0x0A => self.ram_rtc_enabled = true, 0x0A => self.ram_rtc_enabled = true,
0x00 => self.ram_rtc_enabled = false, 0x00 => self.ram_rtc_enabled = false,
_ => println!("MBC3: Unknown MBC value {:02X} for {:04X}", val, addr), _ => println!("MBC3: Unknown MBC value {:02X} for {:04X}", val, addr),
}, },
0x2000...0x3FFF => self.rom_bank_no = val & 0x7F, 0x2000..=0x3FFF => self.rom_bank_no = val & 0x7F,
0x4000...0x5FFF => { 0x4000..=0x5FFF => {
// RAM bank select // RAM bank select
match val { match val {
0x00...0x03 => self.ram_bank_no = val, 0x00..=0x03 => self.ram_bank_no = val,
0x08...0x0C => self.ram_bank_no = val, 0x08..=0x0C => self.ram_bank_no = val,
_ => panic!("MBC3: Unknown RAM bank {:02X}", val), _ => panic!("MBC3: Unknown RAM bank {:02X}", val),
} }
} }
0x6000...0x7FFF => { 0x6000..=0x7FFF => {
// Latch clock data // Latch clock data
match val { match val {
0x00 => println!("latch = 0"), 0x00 => println!("latch = 0"),
@ -88,14 +88,14 @@ impl MBC for MBC3 {
_ => panic!("MBC3: Unknown latch value {:02X}", val), _ => panic!("MBC3: Unknown latch value {:02X}", val),
} }
} }
0xA000...0xBFFF => { 0xA000..=0xBFFF => {
let addr = addr - 0xA000; let addr = addr - 0xA000;
match self.active_ram_bank() { match self.active_ram_bank() {
0x00...0x03 => { 0x00..=0x03 => {
let active_bank = self.active_ram_bank() as usize; let active_bank = self.active_ram_bank() as usize;
self.ram[active_bank * 0x2000 + addr as usize] = val; self.ram[active_bank * 0x2000 + addr as usize] = val;
} }
0x08...0x0C => { 0x08..=0x0C => {
// TODO // TODO
println!("MBC3: Ignoring RTC write ({:02X})", val); println!("MBC3: Ignoring RTC write ({:02X})", val);
} }