1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Completes test of a vectored interrupt.

Correcting issues uncovered.
This commit is contained in:
Thomas Harte 2019-05-02 00:00:09 -04:00
parent bb07206c55
commit 93616a4903
2 changed files with 26 additions and 9 deletions

View File

@ -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<uint16_t> &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 {

View File

@ -1810,18 +1810,18 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> 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 <class T, bool dtack_is_implicit, bool signal_will_perform> 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();