diff --git a/InstructionSets/6809/OperationMapper.hpp b/InstructionSets/6809/OperationMapper.hpp index 002746706..99f35dfc1 100644 --- a/InstructionSets/6809/OperationMapper.hpp +++ b/InstructionSets/6809/OperationMapper.hpp @@ -309,7 +309,7 @@ auto OperationMapper::dispatch(SchedulerT &s) { O::None, O::DAA, O::ORCC, O::None, O::ANDCC, O::SEX, O::EXG, O::TFR, }; static constexpr AddressingMode specific_modes[] = { - AM::Variant, AM::Variant, AM::Inherent, AM::Inherent, + AM::Variant, AM::Variant, AM::Inherent, AM::Specialised, AM::Illegal, AM::Illegal, AM::Relative16, AM::Relative16, AM::Illegal, AM::Inherent, AM::Immediate8, AM::Illegal, AM::Immediate8, AM::Inherent, AM::Immediate8, AM::Immediate8, diff --git a/OSBindings/Mac/Clock SignalTests/6809Tests.mm b/OSBindings/Mac/Clock SignalTests/6809Tests.mm index 11d59412f..0ccfd056c 100644 --- a/OSBindings/Mac/Clock SignalTests/6809Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/6809Tests.mm @@ -10,6 +10,7 @@ #import #include "Processors/6809/6809.hpp" +#include "NSData+dataWithContentsOfGZippedFile.h" #include @@ -17,7 +18,7 @@ namespace { // This is a proto-single-step-tests file; I don't yet know the full veracity of its // source and it doesn't include bus activity. -NSString *const testFile = @"/Users/thomasharte/Scratch/6809tests.json"; +NSString *const testFile = @"/Users/thomasharte/Scratch/6809tests.json.gz"; struct M6809Capture { std::unordered_map ram; @@ -32,14 +33,16 @@ struct M6809Capture { const AddressT address, CPU::M6809::data_t value ) { - if constexpr (CPU::M6809::is_read(read_write)) { - const auto entry = ram.find(address); - if(entry == ram.end()) { - throw -1; + if constexpr (read_write != CPU::M6809::ReadWrite::NoData) { + if constexpr (CPU::M6809::is_read(read_write)) { + const auto entry = ram.find(address); + if(entry == ram.end()) { + throw -1; + } + value = entry->second; + } else { + ram[address] = value; } - value = entry->second; - } else { - ram[address] = value; } return Cycles(0); @@ -114,7 +117,8 @@ struct M6809Traits { // Unimplemented by me. case CWAI: - case SYNC: return; +// case SYNC: + return; // Considered invalid by the test set. case RESET: return; @@ -257,7 +261,7 @@ struct M6809Traits { } - (void)testCaptures { - NSData *data = [NSData dataWithContentsOfFile:testFile]; + NSData *data = [NSData dataWithContentsOfGZippedFile:testFile]; NSArray *tests = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; for(NSDictionary *test in tests) { diff --git a/Processors/6809/6809.hpp b/Processors/6809/6809.hpp index 0065f5937..478a14f45 100644 --- a/Processors/6809/6809.hpp +++ b/Processors/6809/6809.hpp @@ -314,6 +314,11 @@ struct Processor { registers_.cc.set(true); reset_spin: + case ResumePoint::ResetSpin: + if(time_ <= 0) { + resume_point_ = ResumePoint::ResetSpin; + return; + } if(exceptions_ & (Exception::Halt | Exception::DMABusReq | Exception::Reset)) { inactive_bus(); goto reset_spin; @@ -525,6 +530,9 @@ struct Processor { case Operation::RESET: goto swi_reset_nmi_irq; + case Operation::SYNC: + goto sync; + default: __builtin_unreachable(); } @@ -765,6 +773,30 @@ struct Processor { read(BusState::Normal, Literal(address_.full), registers_.pc.halves.low, ++address_.full); goto fetch_decode; + sync: + case ResumePoint::Sync: + // Always consider taking a break here, regardless of selected pause precision; otherwise there's + // a risk of never exiting. + if(time_ <= 0) { + resume_point_ = ResumePoint::Sync; + return; + } + + if(!(exceptions_ & (Exception::NMI | Exception::IRQ | Exception::FIRQ))) { + time_ -= Cycles(1); + time_ -= + bus_handler_.template perform< + BusPhase::FullCycle, + ReadWrite::NoData, + BusState::SyncAcknowledge + >(Address::Fixed<0xffff>(), Data::NoValue()); + + goto sync; + } + + // TODO: understand the requirement that an interrupt be signalled for at least 3 cycles. + + goto fetch_decode; // // Access atoms. @@ -829,6 +861,8 @@ private: enum ResumePoint { FetchDecode, + ResetSpin, + Sync, Max, }; using Operation = InstructionSet::M6809::Operation;