mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
INC, INX and INY instructions
This commit is contained in:
@@ -199,11 +199,11 @@ impl CPU {
|
||||
self.registers.increment_pc(bytes); self.cycles += cycles;
|
||||
}
|
||||
|
||||
pub fn increment_cycles_dec(&mut self, addressing_mode: AddressingMode) {
|
||||
pub fn increment_cycles_inc_dec(&mut self, addressing_mode: AddressingMode) {
|
||||
self.increment_cycles_shift(addressing_mode);
|
||||
}
|
||||
|
||||
pub fn increment_cycles_dec_index(&mut self) {
|
||||
pub fn increment_cycles_inc_dec_index(&mut self) {
|
||||
self.registers.increment_pc(1); self.cycles += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ impl CPU {
|
||||
let result = self.do_dec(value).to_u32() as u8;
|
||||
self.set_8bit_to_address(bus, addressing_mode, result);
|
||||
}
|
||||
self.increment_cycles_dec(addressing_mode);
|
||||
self.increment_cycles_inc_dec(addressing_mode);
|
||||
}
|
||||
|
||||
fn dex(&mut self) {
|
||||
@@ -141,7 +141,7 @@ impl CPU {
|
||||
let result = self.do_dec(self.registers.x).to_u32() as u8;
|
||||
self.registers.set_low_x(result);
|
||||
}
|
||||
self.increment_cycles_dec_index();
|
||||
self.increment_cycles_inc_dec_index();
|
||||
}
|
||||
|
||||
fn dey(&mut self) {
|
||||
@@ -151,7 +151,51 @@ impl CPU {
|
||||
let result = self.do_dec(self.registers.y).to_u32() as u8;
|
||||
self.registers.set_low_y(result);
|
||||
}
|
||||
self.increment_cycles_dec_index();
|
||||
self.increment_cycles_inc_dec_index();
|
||||
}
|
||||
|
||||
fn do_inc<T: SnesNum>(&mut self, target: T) -> T {
|
||||
let (result, affected_flags) = alu::adc_bin(target, T::from_u32(1), false);
|
||||
for flag in affected_flags {
|
||||
match flag {
|
||||
Flags::Negative(_) | Flags::Zero(_) => self.registers.set_flags(&[flag]),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn inc(&mut self, bus: &mut Bus, addressing_mode: AddressingMode) {
|
||||
if self.registers.is_16bit_mode() {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let result = self.do_inc(value).to_u32() as u16;
|
||||
self.set_16bit_to_address(bus, addressing_mode, result);
|
||||
} else {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let result = self.do_inc(value).to_u32() as u8;
|
||||
self.set_8bit_to_address(bus, addressing_mode, result);
|
||||
}
|
||||
self.increment_cycles_inc_dec(addressing_mode);
|
||||
}
|
||||
|
||||
fn inx(&mut self) {
|
||||
if self.registers.is_16bit_index() {
|
||||
self.registers.x = self.do_inc(self.registers.x);
|
||||
} else {
|
||||
let result = self.do_inc(self.registers.x).to_u32() as u8;
|
||||
self.registers.set_low_x(result);
|
||||
}
|
||||
self.increment_cycles_inc_dec_index();
|
||||
}
|
||||
|
||||
fn iny(&mut self) {
|
||||
if self.registers.is_16bit_index() {
|
||||
self.registers.y = self.do_inc(self.registers.y);
|
||||
} else {
|
||||
let result = self.do_inc(self.registers.y).to_u32() as u8;
|
||||
self.registers.set_low_y(result);
|
||||
}
|
||||
self.increment_cycles_inc_dec_index();
|
||||
}
|
||||
|
||||
fn do_comp<T: SnesNum>(&mut self, target: T, value: T) {
|
||||
@@ -543,6 +587,16 @@ impl CPU {
|
||||
0x57 => self.eor(bus, A::DirectPageIndirectLongIndexed(I::Y)),
|
||||
0x43 => self.eor(bus, A::StackRelative),
|
||||
0x53 => self.eor(bus, A::StackRelativeIndirectIndexed(I::Y)),
|
||||
// INC
|
||||
0x1A => self.inc(bus, A::Accumulator),
|
||||
0xEE => self.inc(bus, A::Absolute),
|
||||
0xE6 => self.inc(bus, A::DirectPage),
|
||||
0xFE => self.inc(bus, A::AbsoluteIndexed(I::X)),
|
||||
0xF6 => self.inc(bus, A::DirectPageIndexed(I::X)),
|
||||
// INX
|
||||
0xE8 => self.inx(),
|
||||
// INY
|
||||
0xC8 => self.iny(),
|
||||
_ => println!("Invalid opcode: {:02X}", opcode),
|
||||
}
|
||||
}
|
||||
@@ -1164,4 +1218,48 @@ mod cpu_instructions_tests {
|
||||
assert!(!cpu.registers.get_negative_flag());
|
||||
assert!(cpu.registers.get_zero_flag());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inc() {
|
||||
let mut cpu = CPU::new();
|
||||
let mut bus = Bus::new();
|
||||
cpu.registers.a = 0x0001;
|
||||
cpu.registers.pbr = 0x00;
|
||||
cpu.registers.pc = 0x0000;
|
||||
cpu.registers.set_memory_select_flag(true);
|
||||
cpu.inc(&mut bus, AddressingMode::Accumulator);
|
||||
assert_eq!(cpu.registers.a, 2);
|
||||
assert_eq!(cpu.registers.pc, 0x01);
|
||||
assert_eq!(cpu.cycles, 2);
|
||||
assert!(!cpu.registers.get_negative_flag());
|
||||
assert!(!cpu.registers.get_zero_flag());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inx() {
|
||||
let mut cpu = CPU::new();
|
||||
cpu.registers.x = 0x0001;
|
||||
cpu.registers.pbr = 0x00;
|
||||
cpu.registers.pc = 0x0000;
|
||||
cpu.inx();
|
||||
assert_eq!(cpu.registers.x, 2);
|
||||
assert_eq!(cpu.registers.pc, 0x01);
|
||||
assert_eq!(cpu.cycles, 2);
|
||||
assert!(!cpu.registers.get_negative_flag());
|
||||
assert!(!cpu.registers.get_zero_flag());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iny() {
|
||||
let mut cpu = CPU::new();
|
||||
cpu.registers.y = 0x0001;
|
||||
cpu.registers.pbr = 0x00;
|
||||
cpu.registers.pc = 0x0000;
|
||||
cpu.iny();
|
||||
assert_eq!(cpu.registers.y, 2);
|
||||
assert_eq!(cpu.registers.pc, 0x01);
|
||||
assert_eq!(cpu.cycles, 2);
|
||||
assert!(!cpu.registers.get_negative_flag());
|
||||
assert!(!cpu.registers.get_zero_flag());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user