From 8460192ab3c8c9030f73a7accc4b2b041fa096fd Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Wed, 29 Jun 2022 22:36:47 -0500 Subject: [PATCH] adc direct page --- snes-core/src/cpu.rs | 98 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/snes-core/src/cpu.rs b/snes-core/src/cpu.rs index f4c07f9..555b59a 100644 --- a/snes-core/src/cpu.rs +++ b/snes-core/src/cpu.rs @@ -144,7 +144,7 @@ impl CPU { } fn adc_const(&mut self, bus: &Bus) { - let value = self.read_immediate(bus); + let value = self.get_immediate(bus); self.registers.pc = self.registers.pc.wrapping_add(2); self.cycles += 2; if self.registers.get_memory_select_flag() { @@ -158,7 +158,7 @@ impl CPU { } fn adc_addr(&mut self, bus: &Bus) { - let address = ((self.registers.pbr as u32) << 16) | (self.read_absolute(bus) as u32); + let address = ((self.registers.pbr as u32) << 16) | (self.get_absolute(bus) as u32); self.registers.pc = self.registers.pc.wrapping_add(3); self.cycles += 4; if self.registers.get_memory_select_flag() { @@ -172,7 +172,7 @@ impl CPU { } fn adc_long(&mut self, bus: &Bus) { - let address = self.read_absolute_long(bus); + let address = self.get_absolute_long(bus); self.registers.pc = self.registers.pc.wrapping_add(4); self.cycles += 5; if self.registers.get_memory_select_flag() { @@ -185,17 +185,39 @@ impl CPU { self.adc(value as u16); } - fn read_absolute(&self, bus: &Bus) -> u16 { - let pc = self.registers.pc as u32; + fn adc_dp(&mut self, bus: &Bus) { + let address = self.get_direct_page(bus); + self.registers.pc = self.registers.pc.wrapping_add(2); + self.cycles += 3; + if self.registers.get_memory_select_flag() { + self.cycles += 1; + } + if address != 0 { + self.cycles += 1; + } + if self.registers.get_decimal_mode_flag() { + self.cycles += 1; + } + let value = bus.read(address as u32); + self.adc(value as u16); + } + + fn get_absolute(&self, bus: &Bus) -> u16 { + let pc = self.registers.get_pc_address(); (bus.read(pc + 1) as u16) | ((bus.read(pc + 2) as u16) << 8) } - fn read_absolute_long(&self, bus: &Bus) -> u32 { - let pc = self.registers.pc as u32; + fn get_absolute_long(&self, bus: &Bus) -> u32 { + let pc = self.registers.get_pc_address(); (bus.read(pc + 1) as u32) | ((bus.read(pc + 2) as u32) << 8) | ((bus.read(pc + 3) as u32) << 16) } - fn read_immediate(&self, bus: &Bus) -> u16 { + fn get_direct_page(&self, bus: &Bus) -> u8 { + let pc = self.registers.get_pc_address(); + bus.read(pc + 1) + } + + fn get_immediate(&self, bus: &Bus) -> u16 { // If the "m" flag is set to 1, read only 8 bits. // Otherwise, read 16 bits let address = self.registers.get_pc_address(); @@ -211,6 +233,7 @@ impl CPU { 0x69 => self.adc_const(bus), 0x6D => self.adc_addr(bus), 0x6F => self.adc_long(bus), + 0x65 => self.adc_dp(bus), _ => todo!("Missing opcode implementation: {:02X}", opcode), } } @@ -228,40 +251,85 @@ mod cpu_instructions_tests { use super::*; #[test] - fn test_read_immediate() { + fn test_get_immediate() { let mut bus = Bus::new(); let mut cpu = CPU::new(); cpu.registers.set_memory_select_flag(true); cpu.registers.pc = 0x0000; + cpu.registers.pbr = 0x00; // write to WRAM bus.write(0x00_0001, 0x01); bus.write(0x00_0002, 0x02); - assert_eq!(cpu.read_immediate(&bus), 0x0001); + assert_eq!(cpu.get_immediate(&bus), 0x0001); cpu.registers.set_memory_select_flag(false); - assert_eq!(cpu.read_immediate(&bus), 0x0201); + assert_eq!(cpu.get_immediate(&bus), 0x0201); + + cpu.registers.set_memory_select_flag(true); + cpu.registers.pc = 0x0010; + cpu.registers.pbr = 0x7E; + // write to WRAM + bus.write(0x7E_0011, 0x01); + bus.write(0x7E_0012, 0x02); + assert_eq!(cpu.get_immediate(&bus), 0x0001); + cpu.registers.set_memory_select_flag(false); + assert_eq!(cpu.get_immediate(&bus), 0x0201); } #[test] - fn test_read_absolute() { + fn test_get_absolute() { let mut bus = Bus::new(); let mut cpu = CPU::new(); cpu.registers.pc = 0x0000; + cpu.registers.pbr = 0x00; // write to WRAM bus.write(0x00_0001, 0x01); bus.write(0x00_0002, 0x02); - assert_eq!(cpu.read_absolute(&bus), 0x0201); + assert_eq!(cpu.get_absolute(&bus), 0x0201); + + cpu.registers.pc = 0x0010; + cpu.registers.pbr = 0x7E; + // write to WRAM + bus.write(0x7E_0011, 0x01); + bus.write(0x7E_0012, 0x02); + assert_eq!(cpu.get_absolute(&bus), 0x0201); } #[test] - fn test_read_absolute_long() { + fn test_get_absolute_long() { let mut bus = Bus::new(); let mut cpu = CPU::new(); cpu.registers.pc = 0x0000; + cpu.registers.pbr = 0x00; // write to WRAM bus.write(0x00_0001, 0x01); bus.write(0x00_0002, 0x02); bus.write(0x00_0003, 0x03); - assert_eq!(cpu.read_absolute_long(&bus), 0x030201); + assert_eq!(cpu.get_absolute_long(&bus), 0x030201); + + cpu.registers.pc = 0x0010; + cpu.registers.pbr = 0x7E; + // write to WRAM + bus.write(0x7E_0011, 0x01); + bus.write(0x7E_0012, 0x02); + bus.write(0x7E_0013, 0x03); + assert_eq!(cpu.get_absolute_long(&bus), 0x030201); + } + + #[test] + fn test_get_direct_page() { + let mut bus = Bus::new(); + let mut cpu = CPU::new(); + cpu.registers.pc = 0x0000; + cpu.registers.pbr = 0x00; + // write to WRAM + bus.write(0x00_0001, 0x01); + assert_eq!(cpu.get_direct_page(&bus), 0x01); + + cpu.registers.pc = 0x0010; + cpu.registers.pbr = 0x7E; + // write to WRAM + bus.write(0x7E_0011, 0x01); + assert_eq!(cpu.get_direct_page(&bus), 0x01); } #[test]