Skip to content

Commit

Permalink
SPC700: implement CALL/TCALL
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Nov 23, 2023
1 parent 45d0b9f commit a4d96da
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 17 deletions.
48 changes: 48 additions & 0 deletions src/snes/cpu_spc700/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ where
lo | hi << 8
}

/// Call to an address
fn call(&mut self, addr: SpcAddress) {
self.push16(self.regs.read(Register::PC));
self.regs.write(Register::PC, addr);
}

/// Executes an instruction.
fn execute_instruction(&mut self, instr: &Instruction) -> Result<()> {
match instr.def.instr_type {
Expand Down Expand Up @@ -240,6 +246,12 @@ where
InstructionType::LSR => self.op_lsr(instr),
InstructionType::PUSH => self.op_push(instr),
InstructionType::POP => self.op_pop(instr),
InstructionType::CALL => {
self.tick_bus(1)?;
self.call(instr.imm16());
self.tick_bus(2)
}
InstructionType::TCALL => self.op_tcall(instr),
_ => todo!(),
}
}
Expand Down Expand Up @@ -772,4 +784,40 @@ where
self.regs.write(reg, val.into());
Ok(())
}

/// TCALL
fn op_tcall(&mut self, instr: &Instruction) -> Result<()> {
let iaddr = match instr.def.operands[0] {
Operand::ImpliedNum(0) => 0xFFDE,
Operand::ImpliedNum(1) => 0xFFDC,
Operand::ImpliedNum(2) => 0xFFDA,
Operand::ImpliedNum(3) => 0xFFD8,
Operand::ImpliedNum(4) => 0xFFD6,
Operand::ImpliedNum(5) => 0xFFD4,
Operand::ImpliedNum(6) => 0xFFD2,
Operand::ImpliedNum(7) => 0xFFD0,
Operand::ImpliedNum(8) => 0xFFCE,
Operand::ImpliedNum(9) => 0xFFCC,
Operand::ImpliedNum(10) => 0xFFCA,
Operand::ImpliedNum(11) => 0xFFC8,
Operand::ImpliedNum(12) => 0xFFC6,
Operand::ImpliedNum(13) => 0xFFC4,
Operand::ImpliedNum(14) => 0xFFC2,
Operand::ImpliedNum(15) => 0xFFC0,
_ => unreachable!(),
};

// Discarded read
self.read_tick(self.regs.read(Register::PC));
self.tick_bus(1)?;

// Stack push happens before following the
// address indirection.
self.push16(self.regs.read(Register::PC));
self.tick_bus(1)?;

let addr = self.read16_tick(iaddr);
self.regs.write(Register::PC, addr);
Ok(())
}
}
34 changes: 17 additions & 17 deletions src/test/processortests_spc700.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn run_testcase(testcase: &Value, check_trace: bool, multi_steps: bool) {
}

cpu_test!(instr_00, 0x00);
//cpu_test!(instr_01, 0x01);
cpu_test!(instr_01, 0x01);
cpu_test!(instr_02, 0x02);
//cpu_test!(instr_03, 0x03);
cpu_test!(instr_04, 0x04);
Expand All @@ -194,7 +194,7 @@ cpu_test!(instr_0d, 0x0d);
//cpu_test!(instr_0e, 0x0e);
//cpu_test!(instr_0f, 0x0f);
//cpu_test!(instr_10, 0x10);
//cpu_test!(instr_11, 0x11);
cpu_test!(instr_11, 0x11);
cpu_test!(instr_12, 0x12);
//cpu_test!(instr_13, 0x13);
cpu_test!(instr_14, 0x14);
Expand All @@ -212,7 +212,7 @@ cpu_test!(instr_1d, 0x1d);
cpu_test!(instr_1e, 0x1e);
//cpu_test!(instr_1f, 0x1f);
cpu_test!(instr_20, 0x20);
//cpu_test!(instr_21, 0x21);
cpu_test!(instr_21, 0x21);
cpu_test!(instr_22, 0x22);
//cpu_test!(instr_23, 0x23);
cpu_test!(instr_24, 0x24);
Expand All @@ -230,7 +230,7 @@ cpu_test!(instr_2d, 0x2d);
//cpu_test!(instr_2e, 0x2e);
//cpu_test!(instr_2f, 0x2f);
//cpu_test!(instr_30, 0x30);
//cpu_test!(instr_31, 0x31);
cpu_test!(instr_31, 0x31);
cpu_test!(instr_32, 0x32);
//cpu_test!(instr_33, 0x33);
cpu_test!(instr_34, 0x34);
Expand All @@ -246,9 +246,9 @@ cpu_test_no_trace!(instr_39, 0x39);
//cpu_test!(instr_3c, 0x3c);
cpu_test!(instr_3d, 0x3d);
cpu_test!(instr_3e, 0x3e);
//cpu_test!(instr_3f, 0x3f);
cpu_test!(instr_3f, 0x3f);
cpu_test!(instr_40, 0x40);
//cpu_test!(instr_41, 0x41);
cpu_test!(instr_41, 0x41);
cpu_test!(instr_42, 0x42);
//cpu_test!(instr_43, 0x43);
cpu_test!(instr_44, 0x44);
Expand All @@ -266,7 +266,7 @@ cpu_test!(instr_4d, 0x4d);
//cpu_test!(instr_4e, 0x4e);
//cpu_test!(instr_4f, 0x4f);
//cpu_test!(instr_50, 0x50);
//cpu_test!(instr_51, 0x51);
cpu_test!(instr_51, 0x51);
cpu_test!(instr_52, 0x52);
//cpu_test!(instr_53, 0x53);
cpu_test!(instr_54, 0x54);
Expand All @@ -284,7 +284,7 @@ cpu_test!(instr_5d, 0x5d);
cpu_test!(instr_5e, 0x5e);
//cpu_test!(instr_5f, 0x5f);
cpu_test!(instr_60, 0x60);
//cpu_test!(instr_61, 0x61);
cpu_test!(instr_61, 0x61);
cpu_test!(instr_62, 0x62);
//cpu_test!(instr_63, 0x63);
cpu_test!(instr_64, 0x64);
Expand All @@ -301,7 +301,7 @@ cpu_test!(instr_6d, 0x6d);
//cpu_test!(instr_6e, 0x6e);
//cpu_test!(instr_6f, 0x6f);
//cpu_test!(instr_70, 0x70);
//cpu_test!(instr_71, 0x71);
cpu_test!(instr_71, 0x71);
cpu_test!(instr_72, 0x72);
//cpu_test!(instr_73, 0x73);
cpu_test!(instr_74, 0x74);
Expand All @@ -318,7 +318,7 @@ cpu_test!(instr_7d, 0x7d);
cpu_test!(instr_7e, 0x7e);
//cpu_test!(instr_7f, 0x7f);
cpu_test!(instr_80, 0x80);
//cpu_test!(instr_81, 0x81);
cpu_test!(instr_81, 0x81);
cpu_test!(instr_82, 0x82);
//cpu_test!(instr_83, 0x83);
cpu_test!(instr_84, 0x84);
Expand All @@ -335,7 +335,7 @@ cpu_test!(instr_8d, 0x8d);
cpu_test!(instr_8e, 0x8e);
cpu_test!(instr_8f, 0x8f);
//cpu_test!(instr_90, 0x90);
//cpu_test!(instr_91, 0x91);
cpu_test!(instr_91, 0x91);
cpu_test!(instr_92, 0x92);
//cpu_test!(instr_93, 0x93);
cpu_test!(instr_94, 0x94);
Expand All @@ -352,7 +352,7 @@ cpu_test!(instr_9d, 0x9d);
//cpu_test!(instr_9e, 0x9e);
cpu_test!(instr_9f, 0x9f);
cpu_test!(instr_a0, 0xa0);
//cpu_test!(instr_a1, 0xa1);
cpu_test!(instr_a1, 0xa1);
cpu_test!(instr_a2, 0xa2);
//cpu_test!(instr_a3, 0xa3);
cpu_test!(instr_a4, 0xa4);
Expand All @@ -370,7 +370,7 @@ cpu_test!(instr_ae, 0xae);
// Wait during fetch
cpu_test_no_trace!(instr_af, 0xaf);
//cpu_test!(instr_b0, 0xb0);
//cpu_test!(instr_b1, 0xb1);
cpu_test!(instr_b1, 0xb1);
cpu_test!(instr_b2, 0xb2);
//cpu_test!(instr_b3, 0xb3);
cpu_test!(instr_b4, 0xb4);
Expand All @@ -387,7 +387,7 @@ cpu_test!(instr_bd, 0xbd);
//cpu_test!(instr_be, 0xbe);
cpu_test!(instr_bf, 0xbf);
cpu_test!(instr_c0, 0xc0);
//cpu_test!(instr_c1, 0xc1);
cpu_test!(instr_c1, 0xc1);
cpu_test!(instr_c2, 0xc2);
//cpu_test!(instr_c3, 0xc3);
cpu_test!(instr_c4, 0xc4);
Expand All @@ -403,7 +403,7 @@ cpu_test!(instr_cd, 0xcd);
cpu_test!(instr_ce, 0xce);
//cpu_test!(instr_cf, 0xcf);
//cpu_test!(instr_d0, 0xd0);
//cpu_test!(instr_d1, 0xd1);
cpu_test!(instr_d1, 0xd1);
cpu_test!(instr_d2, 0xd2);
//cpu_test!(instr_d3, 0xd3);
cpu_test!(instr_d4, 0xd4);
Expand All @@ -420,7 +420,7 @@ cpu_test!(instr_dd, 0xdd);
//cpu_test!(instr_de, 0xde);
//cpu_test!(instr_df, 0xdf);
cpu_test!(instr_e0, 0xe0);
//cpu_test!(instr_e1, 0xe1);
cpu_test!(instr_e1, 0xe1);
cpu_test!(instr_e2, 0xe2);
//cpu_test!(instr_e3, 0xe3);
cpu_test!(instr_e4, 0xe4);
Expand All @@ -436,7 +436,7 @@ cpu_test!(instr_ed, 0xed);
cpu_test!(instr_ee, 0xee);
//cpu_test!(instr_ef, 0xef);
//cpu_test!(instr_f0, 0xf0);
//cpu_test!(instr_f1, 0xf1);
cpu_test!(instr_f1, 0xf1);
cpu_test!(instr_f2, 0xf2);
//cpu_test!(instr_f3, 0xf3);
cpu_test!(instr_f4, 0xf4);
Expand Down

0 comments on commit a4d96da

Please sign in to comment.