From cae34d61d175b26ac7e3feb23d33e0174e37e285 Mon Sep 17 00:00:00 2001 From: "Adrian.Conlon" Date: Thu, 7 Sep 2017 01:04:09 +0100 Subject: [PATCH] Ensure the Z80 unit tests run successfully to completion. Signed-off-by: Adrian.Conlon --- Z80/fusetest_Z80/FuseRegisterState.h | 2 +- Z80/fusetest_Z80/FuseTestRunner.cpp | 9 +++-- Z80/fusetest_Z80/FuseTestRunner.h | 17 ++++++--- Z80/inc/Z80.h | 2 +- Z80/src/Disassembler.cpp | 12 +++---- Z80/src/Z80.cpp | 52 ++++++++++++++-------------- Z80/test/Board.cpp | 23 ++++++------ Z80/test/Board.h | 27 +++++++++------ Z80/test/Configuration.h | 2 +- 9 files changed, 79 insertions(+), 67 deletions(-) diff --git a/Z80/fusetest_Z80/FuseRegisterState.h b/Z80/fusetest_Z80/FuseRegisterState.h index 4f36b65..70d4a96 100644 --- a/Z80/fusetest_Z80/FuseRegisterState.h +++ b/Z80/fusetest_Z80/FuseRegisterState.h @@ -4,7 +4,7 @@ #include #include -#include "Memory.h" +#include namespace Fuse { class RegisterState { diff --git a/Z80/fusetest_Z80/FuseTestRunner.cpp b/Z80/fusetest_Z80/FuseTestRunner.cpp index 8bb13f3..f335bb4 100644 --- a/Z80/fusetest_Z80/FuseTestRunner.cpp +++ b/Z80/fusetest_Z80/FuseTestRunner.cpp @@ -5,11 +5,10 @@ Fuse::TestRunner::TestRunner(const Test& test, const ExpectedTestResult& expected) : m_test(test), m_expected(expected), - m_memory(0xffff), - m_cpu(m_memory, m_ports), + m_ram(0x10000), + m_cpu(*this, m_ports), m_failed(false), m_unimplemented(false) { - m_memory.clear(); m_cpu.initialise(); } @@ -57,7 +56,7 @@ void Fuse::TestRunner::initialiseMemory() { auto address = memoryDatum.address; auto bytes = memoryDatum.bytes; for (int i = 0; i < bytes.size(); ++i) - m_memory.poke(address + i, bytes[i]); + poke(address + i, bytes[i]); } } @@ -304,7 +303,7 @@ void Fuse::TestRunner::checkMemory() { for (int i = 0; i < bytes.size(); ++i) { auto expected = bytes[i]; uint16_t address = memoryDatum.address + i; - auto actual = m_cpu.getMemory().peek(address); + auto actual = peek(address); if (expected != actual) { m_failed = true; if (first) { diff --git a/Z80/fusetest_Z80/FuseTestRunner.h b/Z80/fusetest_Z80/FuseTestRunner.h index 3842638..57618d5 100644 --- a/Z80/fusetest_Z80/FuseTestRunner.h +++ b/Z80/fusetest_Z80/FuseTestRunner.h @@ -3,12 +3,13 @@ #include "FuseTest.h" #include "FuseExpectedTestResult.h" -#include "Memory.h" -#include "InputOutput.h" -#include "Z80.h" +#include +#include +#include +#include namespace Fuse { - class TestRunner { + class TestRunner : public EightBit::Bus { private: const Test& m_test; const ExpectedTestResult& m_expected; @@ -16,7 +17,7 @@ namespace Fuse { bool m_failed; bool m_unimplemented; - EightBit::Memory m_memory; + EightBit::Ram m_ram; EightBit::InputOutput m_ports; EightBit::Z80 m_cpu; @@ -34,6 +35,12 @@ namespace Fuse { const std::string& lowDescription, EightBit::register16_t actual, EightBit::register16_t expected) const; + protected: + virtual uint8_t& reference(uint16_t address, bool& rom) { + rom = false; + return m_ram.reference(address); + } + public: TestRunner(const Test& test, const ExpectedTestResult& expected); diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 2658d5f..25286b0 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -42,7 +42,7 @@ namespace EightBit { CF = Bit0, }; - Z80(Memory& memory, InputOutput& ports); + Z80(Bus& bus, InputOutput& ports); Signal ExecutingInstruction; diff --git a/Z80/src/Disassembler.cpp b/Z80/src/Disassembler.cpp index a1a10ce..7b9ca78 100644 --- a/Z80/src/Disassembler.cpp +++ b/Z80/src/Disassembler.cpp @@ -178,8 +178,8 @@ std::string EightBit::Disassembler::disassemble(Z80& cpu) { void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc) { - auto& memory = cpu.getMemory(); - auto opcode = memory.peek(pc); + auto& bus = cpu.BUS(); + auto opcode = bus.peek(pc); const auto& decoded = cpu.getDecodedOpcode(opcode); @@ -190,11 +190,11 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u auto p = decoded.p; auto q = decoded.q; - auto immediate = memory.peek(pc + 1); - auto absolute = memory.peekWord(pc + 1); + auto immediate = bus.peek(pc + 1); + auto absolute = bus.peekWord(pc + 1); auto displacement = (int8_t)immediate; auto relative = pc + displacement + 2; - auto indexedImmediate = memory.peek(pc + 1); + auto indexedImmediate = bus.peek(pc + 1); auto dumpCount = 0; @@ -219,7 +219,7 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u x, y, z, p, q); for (int i = 0; i < dumpCount; ++i) - output << hex(memory.peek(pc + i + 1)); + output << hex(bus.peek(pc + i + 1)); auto outputFormatSpecification = !m_prefixDD; if (m_prefixDD) { diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 0c66b73..a669257 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -5,8 +5,8 @@ #pragma region Reset and initialisation -EightBit::Z80::Z80(Memory& memory, InputOutput& ports) -: IntelProcessor(memory), +EightBit::Z80::Z80(Bus& bus, InputOutput& ports) +: IntelProcessor(bus), m_ports(ports), m_registerSet(0), m_accumulatorFlagsSet(0), @@ -509,7 +509,7 @@ void EightBit::Z80::xhtl(register16_t& operand) { MEMPTR().low = getByte(SP()); setByte(operand.low); operand.low = MEMPTR().low; - m_memory.ADDRESS().word++; + BUS().ADDRESS().word++; MEMPTR().high = getByte(); setByte(operand.high); operand.high = MEMPTR().high; @@ -615,20 +615,20 @@ bool EightBit::Z80::lddr(uint8_t a, uint8_t& f) { #pragma region Block input instructions void EightBit::Z80::ini(uint8_t& f) { - MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR() = BUS().ADDRESS() = BC(); MEMPTR().word++; readPort(); - auto value = m_memory.DATA(); + auto value = BUS().DATA(); setByte(HL().word++, value); decrement(f, B()); setFlag(f, NF); } void EightBit::Z80::ind(uint8_t& f) { - MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR() = BUS().ADDRESS() = BC(); MEMPTR().word--; readPort(); - auto value = m_memory.DATA(); + auto value = BUS().DATA(); setByte(HL().word--, value); decrement(f, B()); setFlag(f, NF); @@ -650,7 +650,7 @@ bool EightBit::Z80::indr(uint8_t& f) { void EightBit::Z80::blockOut(uint8_t& f) { auto value = getByte(); - m_memory.ADDRESS() = BC(); + BUS().ADDRESS() = BC(); writePort(); decrement(f, B()); setFlag(f, NF, value & Bit7); @@ -659,13 +659,13 @@ void EightBit::Z80::blockOut(uint8_t& f) { } void EightBit::Z80::outi(uint8_t& f) { - m_memory.ADDRESS().word = HL().word++; + BUS().ADDRESS().word = HL().word++; blockOut(f); MEMPTR().word = BC().word + 1; } void EightBit::Z80::outd(uint8_t& f) { - m_memory.ADDRESS().word = HL().word--; + BUS().ADDRESS().word = HL().word--; blockOut(f); MEMPTR().word = BC().word - 1; } @@ -711,29 +711,29 @@ void EightBit::Z80::rld(uint8_t& a, uint8_t& f) { #pragma region I/O instructions void EightBit::Z80::writePort(uint8_t port, uint8_t data) { - m_memory.ADDRESS().low = port; - m_memory.ADDRESS().high = data; - MEMPTR() = m_memory.ADDRESS(); - m_memory.placeDATA(data); + BUS().ADDRESS().low = port; + BUS().ADDRESS().high = data; + MEMPTR() = BUS().ADDRESS(); + BUS().placeDATA(data); writePort(); MEMPTR().low++; } void EightBit::Z80::writePort() { - m_ports.write(m_memory.ADDRESS().low, m_memory.DATA()); + m_ports.write(BUS().ADDRESS().low, BUS().DATA()); } void EightBit::Z80::readPort(uint8_t port, uint8_t& a) { - m_memory.ADDRESS().low = port; - m_memory.ADDRESS().high = a; - MEMPTR() = m_memory.ADDRESS(); + BUS().ADDRESS().low = port; + BUS().ADDRESS().high = a; + MEMPTR() = BUS().ADDRESS(); readPort(); - a = m_memory.DATA(); + a = BUS().DATA(); MEMPTR().low++; } void EightBit::Z80::readPort() { - m_memory.placeDATA(m_ports.read(m_memory.ADDRESS().low)); + BUS().placeDATA(m_ports.read(BUS().ADDRESS().low)); } #pragma endregion I/O instructions @@ -893,22 +893,22 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { case 1: switch (z) { case 0: // Input from port with 16-bit address - MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR() = BUS().ADDRESS() = BC(); MEMPTR().word++; readPort(); if (y != 6) // IN r[y],(C) - R(y, a, m_memory.DATA()); - adjustSZPXY(f, m_memory.DATA()); + R(y, a, BUS().DATA()); + adjustSZPXY(f, BUS().DATA()); clearFlag(f, NF | HC); cycles += 12; break; case 1: // Output to port with 16-bit address - MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR() = BUS().ADDRESS() = BC(); MEMPTR().word++; if (y == 6) // OUT (C),0 - m_memory.placeDATA(0); + BUS().placeDATA(0); else // OUT (C),r[y] - m_memory.placeDATA(R(y, a)); + BUS().placeDATA(R(y, a)); writePort(); cycles += 12; break; diff --git a/Z80/test/Board.cpp b/Z80/test/Board.cpp index 0b2827b..3136d69 100644 --- a/Z80/test/Board.cpp +++ b/Z80/test/Board.cpp @@ -4,23 +4,22 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration), - m_memory(0x3fff), - m_cpu(EightBit::Z80(m_memory, m_ports)), + m_ram(0x10000), + m_cpu(EightBit::Z80(*this, m_ports)), m_profiler(m_cpu, m_disassembler) { } void Board::initialise() { - m_memory.clear(); auto romDirectory = m_configuration.getRomDirectory(); - //m_memory.loadRam(romDirectory + "/prelim.com", 0x100); // Bartholomew preliminary - //m_memory.loadRam(romDirectory + "/zexdoc.com", 0x100); // Cringle/Bartholomew - m_memory.loadRam(romDirectory + "/zexall.com", 0x100); // Cringle/Bartholomew - //m_memory.loadRam(romDirectory + "/CPUTEST.COM", 0x100); // SuperSoft diagnostics - //m_memory.loadRam(romDirectory + "/TEST.COM", 0x100); // Microcosm + //m_ram.load(romDirectory + "/prelim.com", 0x100); // Bartholomew preliminary + //m_ram.load(romDirectory + "/zexdoc.com", 0x100); // Cringle/Bartholomew + m_ram.load(romDirectory + "/zexall.com", 0x100); // Cringle/Bartholomew + //m_ram.load(romDirectory + "/CPUTEST.COM", 0x100); // SuperSoft diagnostics + //m_ram.load(romDirectory + "/TEST.COM", 0x100); // Microcosm - m_memory.poke(5, 0xc9); // ret + poke(5, 0xc9); // ret m_cpu.ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Cpm, this, std::placeholders::_1)); if (m_configuration.isProfileMode()) { @@ -61,8 +60,8 @@ void Board::bdos() { break; } case 0x9: - for (uint16_t i = m_cpu.DE().word; m_memory.peek(i) != '$'; ++i) { - std::cout << m_memory.peek(i); + for (uint16_t i = m_cpu.DE().word; peek(i) != '$'; ++i) { + std::cout << peek(i); } break; } @@ -73,7 +72,7 @@ void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpu) { const auto pc = m_cpu.PC(); m_profiler.addAddress(pc.word); - m_profiler.addInstruction(m_memory.peek(pc.word)); + m_profiler.addInstruction(peek(pc.word)); } void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Z80& cpu) { diff --git a/Z80/test/Board.h b/Z80/test/Board.h index 0c7c4be..97fb1ec 100644 --- a/Z80/test/Board.h +++ b/Z80/test/Board.h @@ -2,26 +2,33 @@ #include -#include "Memory.h" -#include "InputOutput.h" -#include "Configuration.h" -#include "Profiler.h" -#include "EventArgs.h" -#include "Disassembler.h" -#include "Z80.h" +#include +#include +#include +#include +#include +#include +#include -class Board { +#include "Configuration.h" + +class Board : public EightBit::Bus { public: Board(const Configuration& configuration); - EightBit::Memory& Memory() { return m_memory; } EightBit::Z80& CPU() { return m_cpu; } void initialise(); +protected: + virtual uint8_t& reference(uint16_t address, bool& rom) { + rom = false; + return m_ram.reference(address); + } + private: const Configuration& m_configuration; - EightBit::Memory m_memory; + EightBit::Ram m_ram; EightBit::InputOutput m_ports; EightBit::Z80 m_cpu; EightBit::Disassembler m_disassembler; diff --git a/Z80/test/Configuration.h b/Z80/test/Configuration.h index 0e6cee8..d5d2717 100644 --- a/Z80/test/Configuration.h +++ b/Z80/test/Configuration.h @@ -2,7 +2,7 @@ #include -#include "Memory.h" +#include class Configuration { public: