From 9bc2b48d9b217a82fc77d67914c4b1bf5ded2b88 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 26 May 2017 23:23:33 -0400 Subject: [PATCH] Found a form I like for indexed addressing, applying it only where obvious for now. Which eliminates more than a couple of hundred of remaining failures. --- .../Mac/Clock SignalTests/FUSETests.swift | 47 ++++++++++--------- Processors/Z80/Z80.hpp | 40 +++++++++++----- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/FUSETests.swift b/OSBindings/Mac/Clock SignalTests/FUSETests.swift index d80883731..1c5452e0a 100644 --- a/OSBindings/Mac/Clock SignalTests/FUSETests.swift +++ b/OSBindings/Mac/Clock SignalTests/FUSETests.swift @@ -57,19 +57,19 @@ fileprivate struct RegisterState { de = UInt16(dictionary["de"] as! NSNumber) hl = UInt16(dictionary["hl"] as! NSNumber) - afDash = UInt16((dictionary["afDash"] as! NSNumber).int32Value) - bcDash = UInt16((dictionary["bcDash"] as! NSNumber).int32Value) - deDash = UInt16((dictionary["deDash"] as! NSNumber).int32Value) - hlDash = UInt16((dictionary["hlDash"] as! NSNumber).int32Value) + afDash = UInt16(dictionary["afDash"] as! NSNumber) + bcDash = UInt16(dictionary["bcDash"] as! NSNumber) + deDash = UInt16(dictionary["deDash"] as! NSNumber) + hlDash = UInt16(dictionary["hlDash"] as! NSNumber) - ix = UInt16((dictionary["ix"] as! NSNumber).int32Value) - iy = UInt16((dictionary["iy"] as! NSNumber).int32Value) + ix = UInt16(dictionary["ix"] as! NSNumber) + iy = UInt16(dictionary["iy"] as! NSNumber) - sp = UInt16((dictionary["sp"] as! NSNumber).int32Value) - pc = UInt16((dictionary["pc"] as! NSNumber).int32Value) + sp = UInt16(dictionary["sp"] as! NSNumber) + pc = UInt16(dictionary["pc"] as! NSNumber) - i = UInt8((dictionary["i"] as! NSNumber).int32Value) - r = UInt8((dictionary["r"] as! NSNumber).int32Value) + i = UInt8(dictionary["i"] as! NSNumber) + r = UInt8(dictionary["r"] as! NSNumber) iff1 = (dictionary["iff1"] as! NSNumber).boolValue iff2 = (dictionary["iff2"] as! NSNumber).boolValue @@ -151,10 +151,17 @@ class FUSETests: XCTestCase { XCTAssert(inputArray != nil && outputArray != nil) var index = 0 - var failures = 0 +// var failures = 0 for item in inputArray { let itemDictionary = item as! [String: Any] let outputDictionary = outputArray[index] as! [String: Any] + index = index + 1 + + let name = itemDictionary["name"] as! String + +// if name != "fd86" { +// continue +// } let initialState = RegisterState(dictionary: itemDictionary["state"] as! [String: Any]) let targetState = RegisterState(dictionary: outputDictionary["state"] as! [String: Any]) @@ -175,22 +182,20 @@ class FUSETests: XCTestCase { } } - machine.runForNumber(ofCycles: Int32(initialState.tStates)) - machine.runToNextInstruction() + machine.runForNumber(ofCycles: Int32(targetState.tStates)) let finalState = RegisterState(machine: machine) - XCTAssertEqual(finalState, targetState, "Failed \(itemDictionary["name"] as! String)") - if finalState != targetState { - failures = failures + 1 - if failures == 5 { - return - } - } + XCTAssert(finalState == targetState, "Failed \(name)") +// if finalState != targetState { +// failures = failures + 1 +// if failures == 5 { +// return +// } +// } // TODO compare bus operations and final memory state - index = index + 1 } } } diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index 3c24babb7..f9b1e54a5 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -133,6 +133,8 @@ struct MicroOp { CalculateRSTDestination, + IndexedPlaceHolder, + None }; Type type; @@ -192,6 +194,9 @@ template class Processor: public MicroOpScheduler { #define XX {MicroOp::None, 0} +#define INDEX() {MicroOp::IndexedPlaceHolder}, FETCH(temp8_, pc_), WAIT(5), {MicroOp::CalculateIndexAddress, &index} +#define IR_ADDR() (add_offsets ? temp16_ : index) + /// Fetches into x from address y, and then increments y. #define FETCH(x, y) {MicroOp::BusOperation, nullptr, nullptr, {Read, 3, &y.full, &x}}, {MicroOp::Increment16, &y.full} /// Fetches into x from address y. @@ -221,14 +226,14 @@ template class Processor: public MicroOpScheduler { #define LD(a, b) Program({MicroOp::Move8, &b, &a}) #define LD_GROUP(r) \ - LD(r, bc_.bytes.high), LD(r, bc_.bytes.low), LD(r, de_.bytes.high), LD(r, de_.bytes.low), \ + LD(r, bc_.bytes.high), LD(r, bc_.bytes.low), LD(r, de_.bytes.high), LD(r, de_.bytes.low), \ LD(r, index.bytes.high), LD(r, index.bytes.low), Program(FETCHL(r, index)), LD(r, a_) #define OP_GROUP(op) \ Program({MicroOp::op, &bc_.bytes.high}), Program({MicroOp::op, &bc_.bytes.low}), \ Program({MicroOp::op, &de_.bytes.high}), Program({MicroOp::op, &de_.bytes.low}), \ Program({MicroOp::op, &index.bytes.high}), Program({MicroOp::op, &index.bytes.low}), \ - Program(FETCHL(temp8_, index), {MicroOp::op, &temp8_}), \ + Program(INDEX(), FETCHL(temp8_, IR_ADDR()), {MicroOp::op, &temp8_}), \ Program({MicroOp::op, &a_}) #define ADD16(d, s) Program(WAIT(4), WAIT(3), {MicroOp::ADD16, &s.full, &d.full}) @@ -240,7 +245,7 @@ template class Processor: public MicroOpScheduler { typedef MicroOp InstructionTable[256][20]; - void assemble_page(InstructionPage &target, InstructionTable &table) { + void assemble_page(InstructionPage &target, InstructionTable &table, bool add_offsets) { size_t number_of_micro_ops = 0; size_t lengths[256]; @@ -259,9 +264,21 @@ template class Processor: public MicroOpScheduler { // Copy in all programs and set pointers. size_t destination = 0; for(int c = 0; c < 256; c++) { - memcpy(&target.all_operations[destination], table[c], lengths[c] * sizeof(MicroOp)); target.instructions[c] = &target.all_operations[destination]; - destination += lengths[c]; + if(c == 0x86) + printf("!"); + for(int t = 0; t < lengths[c];) { + // If an index placeholder is hit then drop it, and if offsets aren't being added, + // then also drop the indexing that follows and which is assumed here to be four + // micro-ops in length. Coupled to the INDEX() macro. + if(table[c][t].type == MicroOp::IndexedPlaceHolder) { + t++; + if(!add_offsets) t += 4; + } + target.all_operations[destination] = table[c][t]; + destination++; + t++; + } } } @@ -325,7 +342,7 @@ template class Processor: public MicroOpScheduler { NOP_ROW(), /* 0xe0 */ NOP_ROW(), /* 0xf0 */ }; - assemble_page(target, ed_program_table); + assemble_page(target, ed_program_table, false); #undef NOP_ROW } @@ -389,8 +406,8 @@ template class Processor: public MicroOpScheduler { /* 0x30 JR NC */ JR(TestNC), /* 0x31 LD SP, nn */ Program(FETCH16(sp_, pc_)), /* 0x32 LD (nn), A */ Program(FETCH16(temp16_, pc_), STOREL(a_, temp16_)), /* 0x33 INC SP */ Program(WAIT(2), {MicroOp::Increment16, &sp_.full}), - /* 0x34 INC (HL) */ Program(FETCHL(temp8_, hl_), WAIT(1), {MicroOp::Increment8, &temp8_}, STOREL(temp8_, hl_)), - /* 0x35 DEC (HL) */ Program(FETCHL(temp8_, hl_), WAIT(1), {MicroOp::Decrement8, &temp8_}, STOREL(temp8_, hl_)), + /* 0x34 INC (HL) */ Program( FETCHL(temp8_, index), WAIT(1), {MicroOp::Increment8, &temp8_}, STOREL(temp8_, index)), + /* 0x35 DEC (HL) */ Program(FETCHL(temp8_, index), WAIT(1), {MicroOp::Decrement8, &temp8_}, STOREL(temp8_, index)), /* 0x36 LD (HL), n */ Program(FETCH(temp8_, pc_), STOREL(temp8_, index)), /* 0x37 SCF */ Program({MicroOp::SCF}), /* 0x38 JR C */ JR(TestC), @@ -494,7 +511,7 @@ template class Processor: public MicroOpScheduler { /* 0xfe CP n */ Program(FETCH(temp8_, pc_), {MicroOp::CP8, &temp8_}), /* 0xff RST 38h */ RST(), }; - assemble_page(target, base_program_table); + assemble_page(target, base_program_table, add_offsets); } void assemble_fetch_decode_execute() { @@ -523,8 +540,8 @@ template class Processor: public MicroOpScheduler { public: Processor() : MicroOpScheduler() { assemble_base_page(base_page_, hl_, false); - assemble_base_page(dd_page_, ix_, false); - assemble_base_page(fd_page_, iy_, false); + assemble_base_page(dd_page_, ix_, true); + assemble_base_page(fd_page_, iy_, true); assemble_ed_page(ed_page_); assemble_fetch_decode_execute(); } @@ -568,7 +585,6 @@ template class Processor: public MicroOpScheduler { if(number_of_cycles_ < operation->machine_cycle.length) { schedule_program_program_counter_--; return; } number_of_cycles_ -= operation->machine_cycle.length; number_of_cycles_ -= static_cast(this)->perform_machine_cycle(&operation->machine_cycle); - if(number_of_cycles_ <= 0) return; break; case MicroOp::MoveToNextProgram: move_to_next_program();