diff --git a/InstructionSets/M68k/Executor.hpp b/InstructionSets/M68k/Executor.hpp index b2abd9c61..9f38c7b23 100644 --- a/InstructionSets/M68k/Executor.hpp +++ b/InstructionSets/M68k/Executor.hpp @@ -46,6 +46,7 @@ template class Executor { void decline_branch() {} void did_update_status(); void bsr(uint32_t offset); + void jsr(uint32_t offset); // TODO: ownership of this shouldn't be here. struct Registers { diff --git a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp index 683512f91..1f30d5cf3 100644 --- a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp +++ b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp @@ -371,6 +371,13 @@ void Executor::bsr(uint32_t offset) { program_counter_.l = instruction_address_ + offset; } +template +void Executor::jsr(uint32_t address) { + address_[7].l -= 4; + bus_handler_.template write(address_[7].l, program_counter_.l); + program_counter_.l = address; +} + } } diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index c72e45be8..ae1b5d5c8 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -408,6 +408,11 @@ template < flow_controller.set_pc(src.l); break; + // JSR: jump to EA(0), pushing the current PC to the stack. + case Operation::JSR: + flow_controller.jsr(src.l); + break; + /* MOVE.b, MOVE.l and MOVE.w: move the least significant byte or word, or the entire long word, and set negative, zero, overflow and carry as appropriate. diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index ff484f148..19e16d4ed 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -260,9 +260,10 @@ template uint8_t ope // // No operands are fetched or stored. + // (which means that source and destination will appear as their effective addresses) // - case Operation::LEA: - case Operation::PEA: + case Operation::LEA: case Operation::PEA: + case Operation::JMP: case Operation::JSR: return 0; // @@ -291,6 +292,7 @@ template uint8_t ope case Operation::NEGb: case Operation::NEGw: case Operation::NEGl: case Operation::NEGXb: case Operation::NEGXw: case Operation::NEGXl: case Operation::EXTbtow: case Operation::EXTwtol: + case Operation::SWAP: return FetchOp1 | StoreOp1; // @@ -331,6 +333,8 @@ template uint8_t ope case Operation::ORb: case Operation::ORw: case Operation::ORl: case Operation::ANDb: case Operation::ANDw: case Operation::ANDl: case Operation::EORb: case Operation::EORw: case Operation::EORl: + case Operation::DIVU: case Operation::DIVS: + case Operation::MULU: case Operation::MULS: return FetchOp1 | FetchOp2 | StoreOp2; // case Operation::MOVEMw: diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index e8befd407..3ea04e089 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -36,13 +36,24 @@ // addq_subq // addx_subx // bcc +// cmp +// dbcc_scc +// eori_andi_ori -// Skipped for now: +// Skipped for now, for implying a more granular decoder: +// // btst_bchg_bclr_bset +// chk +// +// And for uncertainty around the test result status register correctness: +// +// divu_divs +// eor_and_or (which invokes BCD) +// exg (also BCD) - (void)setUp { // To limit tests run to a subset of files and/or of tests, uncomment and fill in below. - _fileSet = [NSSet setWithArray:@[@"chk.json"]]; + _fileSet = [NSSet setWithArray:@[@"ext.json", @"jmp_jsr.json"]]; // _testSet = [NSSet setWithArray:@[@"Bcc 6206"]]; // _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]]; // _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];