diff --git a/src/cpu.rs b/src/cpu.rs index 0894e21..51b3cce 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -875,9 +875,11 @@ impl CPU { pub fn run_instruction(&mut self) { //self.debug = !self.interconnect.is_boot_rom(); + /* if self.ip == 0x553 { self.debug = true; } + */ // Check for interrupts. // TODO: Make this right if self.ime { diff --git a/src/display.rs b/src/display.rs index f06e4dd..7300a65 100644 --- a/src/display.rs +++ b/src/display.rs @@ -334,8 +334,9 @@ impl Display { } else { tile_base_addr = 0x0800; // This set goes from -127 to 127. + // TODO: Fix this. (?) let s_tid: i8 = tile_id as i8; - tile_id = (128u8 as i8 + s_tid) as u8; + tile_id = ((128u8 as i8).wrapping_add(s_tid)) as u8; // panic!("OH MY GOD, this wasn't tested yet"); } diff --git a/src/interconnect.rs b/src/interconnect.rs index c483a71..075cfa3 100644 --- a/src/interconnect.rs +++ b/src/interconnect.rs @@ -54,6 +54,7 @@ pub struct Interconnect { vram_dma_source_low: u8, vram_dma_destination_high: u8, vram_dma_destination_low: u8, + vram_dma_length: u8, joy_regular_keys: u8, joy_special_keys: u8, @@ -82,6 +83,7 @@ impl Interconnect { vram_dma_source_low: 0, vram_dma_destination_high: 0, vram_dma_destination_low: 0, + vram_dma_length: 0, // No keys pushed by default joy_regular_keys: 0x0F, @@ -227,8 +229,7 @@ impl Interconnect { 0xFF53 => self.vram_dma_destination_high, 0xFF54 => self.vram_dma_destination_low, 0xFF55 => { - println!("Read from 0xFF55 (DMA length/mode/start) not fully supported"); - 0xFF + self.vram_dma_length } 0xFF56 => { self.infrared_com_port @@ -303,31 +304,38 @@ impl Interconnect { self.disable_bootrom = val; }, 0xFF51 => self.vram_dma_source_high = val, - 0xFF52 => self.vram_dma_source_low = val, - 0xFF53 => self.vram_dma_destination_high = val, - 0xFF54 => self.vram_dma_destination_low = val, + 0xFF52 => self.vram_dma_source_low = val & 0xF0, + 0xFF53 => self.vram_dma_destination_high = val & 0x1F, + 0xFF54 => self.vram_dma_destination_low = val & 0xF0, 0xFF55 => { let src: u16 = ((self.vram_dma_source_high as u16) << 8) | self.vram_dma_source_low as u16; - let dst: u16 = ((self.vram_dma_destination_high as u16) << 8) | self.vram_dma_destination_low as u16; + let mut dst: u16 = ((self.vram_dma_destination_high as u16) << 8) | self.vram_dma_destination_low as u16; + + dst += 0x8000; println!("VRAM DMA transfer from {:04X} to {:04X}; {:02X}", src, dst, val); let len: u16 = ((val & 0x7F) + 1) as u16 * 0x10 - 1; for i in 0..len { let v = self.read_byte(src.wrapping_add(i)); self.write_byte(dst.wrapping_add(i), v); } + + // DMA done + self.vram_dma_length = val | 0x80; } 0xFF56 => { self.infrared_com_port = val; }, 0xFF70 => { - println!("Set wram bank to {:02X}", val); - if val > 7 { - panic!("R u sure this is correct?"); - } - if val == 0 { - self.wram_bank = 1; - } else { - self.wram_bank = val; + if self.wram_bank != val { + println!("Switching wram bank to {:02X}", val); + if val > 7 { + panic!("R u sure this is correct?"); + } + if val == 0 { + self.wram_bank = 1; + } else { + self.wram_bank = val; + } } } 0xFF80 ... 0xFFFE => { diff --git a/src/mbc/mbc3.rs b/src/mbc/mbc3.rs index f1fe7d8..e076ab8 100644 --- a/src/mbc/mbc3.rs +++ b/src/mbc/mbc3.rs @@ -3,14 +3,9 @@ use super::mbc::MBC; pub struct MBC3 { rom: Box<[u8]>, ram: Box<[u8]>, - bank_no: u8, - ram_rtc_enabled: bool, + rom_bank_no: u8, ram_bank_no: u8, - - rom_banks: u16, - - bank_mode: u8, - bank_no_high: u8, + ram_rtc_enabled: bool, } impl MBC3 { @@ -18,14 +13,19 @@ impl MBC3 { MBC3 { rom: rom, ram: ram, - bank_no: 0, - ram_rtc_enabled: false, + rom_bank_no: 0, ram_bank_no: 0, - rom_banks: 0, - bank_mode: 0, - bank_no_high: 0, + ram_rtc_enabled: false, } } + fn active_rom_bank(&self) -> u8 { + self.rom_bank_no + } + + fn active_ram_bank(&self) -> u8 { + self.ram_bank_no + } + } impl MBC for MBC3 { @@ -34,24 +34,27 @@ impl MBC for MBC3 { 0x0000 ... 0x3FFF => self.rom[addr as usize], 0x4000 ... 0x7FFF => { let addr = addr - 0x4000; - // println!("BankNo: {:02X}", self.bank_no); - let abs_addr: usize = addr as usize + self.bank_no as usize * 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 => { - // TODO: Safty checks? Or let rust handle this? let addr = addr - 0xA000; - if self.ram_bank_no < 4 { - println!("Access [{:02X}] {:04X}", self.ram_bank_no, addr); - self.ram[self.ram_bank_no as usize * 0x2000 + addr as usize] - } else { - println!("Ignoring RTC read"); - 0 + match self.active_ram_bank() { + 0x00 ... 0x03 => { + println!("MBC3: Access RAM [{:02X}] {:04X}", self.ram_bank_no, addr); + self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize] + } + 0x08 ... 0x0C => { + // TODO + println!("MBC3: Ignoring RTC read"); + 0 + } + _ => panic!("MBC3: Accessing unknown RAM bank {:02X}", self.active_ram_bank()) } } _ => { - panic!("Cartride: Unable to read from {:04X}", addr); + panic!("MBC3: Unable to read from {:04X}", addr); } } } @@ -62,29 +65,39 @@ impl MBC for MBC3 { match val { 0x0A => self.ram_rtc_enabled = true, 0x00 => self.ram_rtc_enabled = false, - _ => println!("Unknown MBC value {:02X} for {:04X}", val, addr) + _ => println!("MBC3: Unknown MBC value {:02X} for {:04X}", val, addr) } }, - 0x2000 ... 0x3FFF => self.bank_no = val & 0x7F, + 0x2000 ... 0x3FFF => self.rom_bank_no = val & 0x7F, 0x4000 ... 0x5FFF => { // RAM bank select match val { - 0x00 ... 0x03 => self.ram_bank_no = 0, //val, - 0x08 ... 0x0C => self.ram_bank_no = val, // RTC clock values, TODO - _ => panic!("Unknown MBC3 RAM BANK NO: {:02X}", val) + 0x00 ... 0x03 => self.ram_bank_no = val, + 0x08 ... 0x0C => self.ram_bank_no = val, + _ => panic!("MBC3: Unknown RAM bank {:02X}", val) } - }, 0x6000 ... 0x7FFF => { - // Latch clock data, ignore. + // Latch clock data + match val { + 0x00 => println!("latch = 0"), + 0x01 => println!("latch = 1"), // TODO: This should copy the current clock to the register + _ => panic!("MBC3: Unknown latch value {:02X}", val) + } }, 0xA000 ... 0xBFFF => { - // TODO: Safty checks? Or let rust handle this? let addr = addr - 0xA000; - if self.ram_bank_no < 4 { - self.ram[self.ram_bank_no as usize * 0x2000 + addr as usize] = val; - } else { - println!("Ignoring RTC write"); + match self.active_ram_bank() { + 0x00 ... 0x03 => { + println!("MBC3: Writing RAM [{:02X}] {:04X} = {:02X}", self.ram_bank_no, addr, val); + let active_bank = self.active_ram_bank() as usize; + self.ram[active_bank * 0x2000 + addr as usize] = val; + } + 0x08 ... 0x0C => { + // TODO + println!("MBC3: Ignoring RTC write ({:02X})", val); + } + _ => panic!("MBC3: Writing unknown RAM bank {:02X}", self.active_ram_bank()) } } _ => panic!("MBC3: Writing {:02X} to {:04X} not supported", val, addr),