Skip to content

Commit

Permalink
SPC700: implement ADDW
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Nov 24, 2023
1 parent ede7064 commit 5e5a6e2
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
29 changes: 27 additions & 2 deletions src/snes/cpu_spc700/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ where
InstructionType::BVC => self.op_branch(instr, !self.regs.test_flag(Flag::V)),
InstructionType::BVS => self.op_branch(instr, self.regs.test_flag(Flag::V)),
InstructionType::BRA => self.op_branch(instr, true),
InstructionType::ADDW => self.op_addw(instr),
_ => todo!(),
}
}
Expand Down Expand Up @@ -548,7 +549,7 @@ where

let c = if self.regs.test_flag(Flag::C) { 1 } else { 0 };
let result = a as u16 + b as u16 + c as u16;
let result_h = (((a & 0x0F) + (b & 0x0F) + c) & 0x10) == 0x10;
let result_h = (a ^ b ^ result as u8) & 0x10 != 0;
let result_v = !(a ^ b) & (a ^ result as u8) & 0x80 != 0;

match instr.def.operands[0] {
Expand Down Expand Up @@ -580,7 +581,7 @@ where

let c = if self.regs.test_flag(Flag::C) { 1 } else { 0 };
let result = a as i16 + (!b) as i16 + c as i16;
let result_h = (((a & 0x0F) + (!b & 0x0F) + c) & 0x10) == 0x10;
let result_h = (a ^ !b ^ result as u8) & 0x10 != 0;
let result_v = !(a ^ !b) & (a ^ result as u8) & 0x80 != 0;

match instr.def.operands[0] {
Expand Down Expand Up @@ -878,4 +879,28 @@ where
self.tick_bus(2)?;
Ok(())
}

/// ADDW
fn op_addw(&mut self, instr: &Instruction) -> Result<()> {
let a = self.regs.read(Register::YA);
// Only direct page mode
let b = self.read16_tick_a8_delay(self.map_pageflag(instr.imm8(0)));

let (result, result_c) = a.overflowing_add(b);

// Half-carry on high byte
let result_h = (a ^ b ^ result) & 0x1000 != 0;
let result_v = !(a ^ b) & (a ^ result) & 0x8000 != 0;

self.regs.write(Register::YA, result);
self.regs.write_flags(&[
(Flag::C, result_c),
(Flag::H, result_h),
(Flag::V, result_v),
(Flag::N, (result & 0x8000) != 0),
(Flag::Z, result == 0),
]);

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/snes/cpu_spc700/instruction_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ pub const INSTRUCTION_TABLE: [InstructionDef; 256] = [
"ADDW YA, @",
InstructionType::ADDW,
2,
[Operand::None, Operand::DirectPage]
[Operand::Register(Register::YA), Operand::DirectPage]
),
// 0x7B - ROR d+X
// N.....ZC, 2 bytes, 5 cycles
Expand Down
2 changes: 1 addition & 1 deletion src/test/processortests_spc700.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ cpu_test!(instr_77, 0x77);
cpu_test!(instr_78, 0x78);
// Read indirection during fetch
cpu_test_no_trace!(instr_79, 0x79);
//cpu_test!(instr_7a, 0x7a);
cpu_test!(instr_7a, 0x7a);
//cpu_test!(instr_7b, 0x7b);
//cpu_test!(instr_7c, 0x7c);
cpu_test!(instr_7d, 0x7d);
Expand Down

0 comments on commit 5e5a6e2

Please sign in to comment.