diff --git a/OSBindings/Mac/Clock SignalTests/QLTests.mm b/OSBindings/Mac/Clock SignalTests/QLTests.mm index 4e5396333..010d130c2 100644 --- a/OSBindings/Mac/Clock SignalTests/QLTests.mm +++ b/OSBindings/Mac/Clock SignalTests/QLTests.mm @@ -38,13 +38,11 @@ class QL: public CPU::MC68000::BusHandler { // addresses in order for /RESET to work properly. RAM otherwise fills the first // 512kb of the address space. Trying to write to ROM raises a bus error. - const bool is_peripheral = false;//word_address > (0xff0000 >> 1); - const bool is_rom = word_address < (0xc000 >> 1); + const bool is_peripheral = word_address >= (rom_.size() + ram_.size()); + const bool is_rom = word_address < rom_.size(); uint16_t *const base = is_rom ? rom_.data() : ram_.data(); - if(is_rom) { - word_address &= 0xbfff; - } else { - word_address &= 0x3ffff; + if(!is_rom) { + word_address %= ram_.size(); } using Microcycle = CPU::MC68000::Microcycle; @@ -81,12 +79,12 @@ class QL: public CPU::MC68000::BusHandler { case Microcycle::SelectWord: assert(!(is_rom && !is_peripheral)); // printf("[word w %08x <- %04x] ", *cycle.address, cycle.value->full); - base[word_address] = cycle.value->full; + if(!is_peripheral) base[word_address] = cycle.value->full; break; case Microcycle::SelectByte: assert(!(is_rom && !is_peripheral)); // printf("[byte w %08x <- %02x] ", *cycle.address, (cycle.value->full >> cycle.byte_shift()) & 0xff); - base[word_address] = (cycle.value->full & cycle.byte_mask()) | (base[word_address] & (0xffff ^ cycle.byte_mask())); + if(!is_peripheral) base[word_address] = (cycle.value->full & cycle.byte_mask()) | (base[word_address] & (0xffff ^ cycle.byte_mask())); break; } } @@ -98,7 +96,7 @@ class QL: public CPU::MC68000::BusHandler { CPU::MC68000::Processor m68000_; std::vector rom_; - std::array ram_; + std::array ram_; }; @interface QLTests : XCTestCase @@ -116,7 +114,7 @@ class QL: public CPU::MC68000::BusHandler { - (void)testStartup { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. - _machine->run_for(HalfCycles(400000)); + _machine->run_for(HalfCycles(40000000)); } @end diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 14bfa8690..da195a916 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -52,12 +52,12 @@ template void Processor: // no instruction was ongoing. Either way, do a standard instruction operation. // TODO: unless an interrupt is pending, or the trap flag is set. - std::cout << std::setw(8) << std::right; +/* std::cout << std::setw(8) << std::right; std::cout << (extend_flag_ ? 'x' : '-') << (negative_flag_ ? 'n' : '-') << (zero_result_ ? '-' : 'z'); std::cout << (overflow_flag_ ? 'v' : '-') << (carry_flag_ ? 'c' : '-') << '\t'; for(int c = 0; c < 8; ++ c) std::cout << "d" << c << ":" << data_[c].full << " "; for(int c = 0; c < 8; ++ c) std::cout << "a" << c << ":" << address_[c].full << " "; - std::cout << std::endl; + std::cout << std::endl;*/ decoded_instruction_ = prefetch_queue_.halves.high.full; if(!instructions[decoded_instruction_].micro_operations) { @@ -65,7 +65,7 @@ template void Processor: std::cerr << "68000 Abilities exhausted; can't manage instruction " << std::hex << decoded_instruction_ << " from " << (program_counter_.full - 4) << std::endl; return; } else { - std::cout << std::hex << (program_counter_.full - 4) << ": " << std::setw(4) << decoded_instruction_ << '\t'; + std::cout << std::hex << (program_counter_.full - 4) << ": " << std::setw(4) << decoded_instruction_ << '\n'; } active_program_ = &instructions[decoded_instruction_]; diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index ca6f858b2..84c4618c3 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -2188,6 +2188,8 @@ struct ProcessorStorageConstructor { op(Action::PerformOperation, seq("np")); break; + case bw(PreDec): + op(int(is_byte_access ? Action::Decrement1 : Action::Decrement2) | MicroOp::SourceMask, seq("n")); case bw(Ind): case bw(PostInc): op(Action::None, seq("nr", { a(ea_register) }, !is_byte_access)); @@ -2197,6 +2199,8 @@ struct ProcessorStorageConstructor { } break; + case l(PreDec): + op(int(Action::Decrement4) | MicroOp::SourceMask, seq("n")); case l(Ind): case l(PostInc): op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr", { ea(0), ea(0) }));