mirror of
https://github.com/FranLMSP/snes.git
synced 2026-10-03 16:05:18 -04:00
adc direct page
This commit is contained in:
+83
-15
@@ -144,7 +144,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn adc_const(&mut self, bus: &Bus) {
|
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.registers.pc = self.registers.pc.wrapping_add(2);
|
||||||
self.cycles += 2;
|
self.cycles += 2;
|
||||||
if self.registers.get_memory_select_flag() {
|
if self.registers.get_memory_select_flag() {
|
||||||
@@ -158,7 +158,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn adc_addr(&mut self, bus: &Bus) {
|
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.registers.pc = self.registers.pc.wrapping_add(3);
|
||||||
self.cycles += 4;
|
self.cycles += 4;
|
||||||
if self.registers.get_memory_select_flag() {
|
if self.registers.get_memory_select_flag() {
|
||||||
@@ -172,7 +172,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn adc_long(&mut self, bus: &Bus) {
|
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.registers.pc = self.registers.pc.wrapping_add(4);
|
||||||
self.cycles += 5;
|
self.cycles += 5;
|
||||||
if self.registers.get_memory_select_flag() {
|
if self.registers.get_memory_select_flag() {
|
||||||
@@ -185,17 +185,39 @@ impl CPU {
|
|||||||
self.adc(value as u16);
|
self.adc(value as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_absolute(&self, bus: &Bus) -> u16 {
|
fn adc_dp(&mut self, bus: &Bus) {
|
||||||
let pc = self.registers.pc as u32;
|
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)
|
(bus.read(pc + 1) as u16) | ((bus.read(pc + 2) as u16) << 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_absolute_long(&self, bus: &Bus) -> u32 {
|
fn get_absolute_long(&self, bus: &Bus) -> u32 {
|
||||||
let pc = self.registers.pc as 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)
|
(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.
|
// If the "m" flag is set to 1, read only 8 bits.
|
||||||
// Otherwise, read 16 bits
|
// Otherwise, read 16 bits
|
||||||
let address = self.registers.get_pc_address();
|
let address = self.registers.get_pc_address();
|
||||||
@@ -211,6 +233,7 @@ impl CPU {
|
|||||||
0x69 => self.adc_const(bus),
|
0x69 => self.adc_const(bus),
|
||||||
0x6D => self.adc_addr(bus),
|
0x6D => self.adc_addr(bus),
|
||||||
0x6F => self.adc_long(bus),
|
0x6F => self.adc_long(bus),
|
||||||
|
0x65 => self.adc_dp(bus),
|
||||||
_ => todo!("Missing opcode implementation: {:02X}", opcode),
|
_ => todo!("Missing opcode implementation: {:02X}", opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,40 +251,85 @@ mod cpu_instructions_tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_immediate() {
|
fn test_get_immediate() {
|
||||||
let mut bus = Bus::new();
|
let mut bus = Bus::new();
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
cpu.registers.set_memory_select_flag(true);
|
cpu.registers.set_memory_select_flag(true);
|
||||||
cpu.registers.pc = 0x0000;
|
cpu.registers.pc = 0x0000;
|
||||||
|
cpu.registers.pbr = 0x00;
|
||||||
// write to WRAM
|
// write to WRAM
|
||||||
bus.write(0x00_0001, 0x01);
|
bus.write(0x00_0001, 0x01);
|
||||||
bus.write(0x00_0002, 0x02);
|
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);
|
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]
|
#[test]
|
||||||
fn test_read_absolute() {
|
fn test_get_absolute() {
|
||||||
let mut bus = Bus::new();
|
let mut bus = Bus::new();
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
cpu.registers.pc = 0x0000;
|
cpu.registers.pc = 0x0000;
|
||||||
|
cpu.registers.pbr = 0x00;
|
||||||
// write to WRAM
|
// write to WRAM
|
||||||
bus.write(0x00_0001, 0x01);
|
bus.write(0x00_0001, 0x01);
|
||||||
bus.write(0x00_0002, 0x02);
|
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]
|
#[test]
|
||||||
fn test_read_absolute_long() {
|
fn test_get_absolute_long() {
|
||||||
let mut bus = Bus::new();
|
let mut bus = Bus::new();
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
cpu.registers.pc = 0x0000;
|
cpu.registers.pc = 0x0000;
|
||||||
|
cpu.registers.pbr = 0x00;
|
||||||
// write to WRAM
|
// write to WRAM
|
||||||
bus.write(0x00_0001, 0x01);
|
bus.write(0x00_0001, 0x01);
|
||||||
bus.write(0x00_0002, 0x02);
|
bus.write(0x00_0002, 0x02);
|
||||||
bus.write(0x00_0003, 0x03);
|
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]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user