From 93616a4903f2ed67b0a68b0c252f45cf7b611422 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 2 May 2019 00:00:09 -0400 Subject: [PATCH] Completes test of a vectored interrupt. Correcting issues uncovered. --- .../Mac/Clock SignalTests/68000Tests.mm | 28 +++++++++++++++---- .../Implementation/68000Implementation.hpp | 7 +++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index 2c09d106d..4e53384ec 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -27,11 +27,11 @@ class RAM68000: public CPU::MC68000::BusHandler { ram_[0] = 0; ram_[1] = 0xffff; ram_[2] = 0; - ram_[3] = 0x0400; + ram_[3] = 0x1000; } void set_program(const std::vector &program) { - memcpy(&ram_[512], program.data(), program.size() * sizeof(uint16_t)); + memcpy(&ram_[0x1000 >> 1], program.data(), program.size() * sizeof(uint16_t)); } void will_perform(uint32_t address, uint16_t opcode) { @@ -39,7 +39,7 @@ class RAM68000: public CPU::MC68000::BusHandler { } void run_for_instructions(int count) { - instructions_remaining_ = count + 1; + instructions_remaining_ = count; while(instructions_remaining_) { run_for(HalfCycles(2)); } @@ -66,12 +66,13 @@ class RAM68000: public CPU::MC68000::BusHandler { case Microcycle::SelectWord | Microcycle::Read: cycle.value->full = ram_[word_address]; + printf("r %04x from %08x \n", cycle.value->full, *cycle.address); break; case Microcycle::SelectByte | Microcycle::Read: cycle.value->halves.low = ram_[word_address] >> cycle.byte_shift(); break; case Microcycle::SelectWord: - printf("w %08x of %02x\n", *cycle.address, cycle.value->full); + printf("w %08x of %04x\n", *cycle.address, cycle.value->full); ram_[word_address] = cycle.value->full; break; case Microcycle::SelectByte: @@ -292,13 +293,28 @@ class CPU::MC68000::ProcessorStorageTests { - (void)testVectoredInterrupt { _machine->set_program({ - 0x46f8, 0x2000, // MOVE $2000, SR + 0x46fc, 0x2000, // MOVE.w #$2000, SR + 0x4e71, // NOP + 0x4e71, // NOP + 0x4e71, // NOP 0x4e71, // NOP 0x4e71, // NOP }); - _machine->run_for_instructions(1); + + // Set the vector that will be supplied back to the start of the + // program; this will ensure no further exceptions following + // the interrupt. + const auto vector = _machine->ram_at(40); + vector[0] = 0x0000; + vector[1] = 0x1004; + + _machine->run_for_instructions(3); _machine->processor().set_interrupt_level(1); _machine->run_for_instructions(1); + + const auto state = _machine->processor().get_state(); + XCTAssert(state.program_counter == 0x1008); // i.e. the interrupt happened, the instruction performed was the one at 1004, and therefore + // by the wonders of prefetch the program counter is now at 1008. } - (void)testOpcodeCoverage { diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index bf8a22667..a6173a637 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -1810,18 +1810,18 @@ template void Proces case int(MicroOp::Action::PrepareINTVector): // Bus error => spurious interrupt. if(bus_error_) { - effective_address_[0].full = 24 << 4; + effective_address_[0].full = 24 << 2; break; } // Valid peripheral address => autovectored interrupt. if(is_peripheral_address_) { - effective_address_[0].full = (24 + accepted_interrupt_level_) << 4; + effective_address_[0].full = (24 + accepted_interrupt_level_) << 2; break; } // Otherwise, the vector is whatever we were just told it is. - effective_address_[0].full = source_bus_data_[0].halves.low.halves.low << 4; + effective_address_[0].full = source_bus_data_[0].halves.low.halves.low << 2; // Let bus error go back to causing exceptions. is_starting_interrupt_ = false; @@ -2010,6 +2010,7 @@ template ProcessorSt memcpy(state.address, address_, sizeof(state.address)); state.user_stack_pointer = stack_pointers_[0].full; state.supervisor_stack_pointer = stack_pointers_[1].full; + state.program_counter = program_counter_.full; state.status = get_status();