diff --git a/Intel8080/inc/Disassembler.h b/Intel8080/inc/Disassembler.h index 993fbe0..e0985a7 100644 --- a/Intel8080/inc/Disassembler.h +++ b/Intel8080/inc/Disassembler.h @@ -12,8 +12,8 @@ namespace EightBit { public: Disassembler(); - static std::string state(Intel8080& cpu); - std::string disassemble(Intel8080& cpu); + static std::string state(const Intel8080& cpu); + std::string disassemble(const Intel8080& cpu); static std::string flag(uint8_t value, int flag, std::string represents, std::string off = "-"); static std::string flags(uint8_t value); @@ -26,7 +26,7 @@ namespace EightBit { private: mutable boost::format m_formatter; - void disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc); + void disassemble(std::ostringstream& output, const Intel8080& cpu, uint16_t pc); void disassemble( std::ostringstream& output, diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index 01caad2..41c562e 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -29,9 +29,13 @@ namespace EightBit { virtual int execute(uint8_t opcode) final; virtual int step() final; + virtual register16_t AF() const final; virtual register16_t& AF() final; + virtual register16_t BC() const final; virtual register16_t& BC() final; + virtual register16_t DE() const final; virtual register16_t& DE() final; + virtual register16_t HL() const final; virtual register16_t& HL() final; protected: @@ -101,6 +105,21 @@ namespace EightBit { } } + register16_t RP(int rp) const { + switch (rp) { + case 0b00: + return BC(); + case 0b01: + return DE(); + case 0b10: + return HL(); + case 0b11: + return SP(); + default: + UNREACHABLE; + } + } + register16_t& RP(int rp) { switch (rp) { case 0b00: @@ -116,6 +135,21 @@ namespace EightBit { } } + register16_t RP2(int rp) const { + switch (rp) { + case 0b00: + return BC(); + case 0b01: + return DE(); + case 0b10: + return HL(); + case 0b11: + return AF(); + default: + UNREACHABLE; + } + } + register16_t& RP2(int rp) { switch (rp) { case 0b00: diff --git a/Intel8080/src/Disassembler.cpp b/Intel8080/src/Disassembler.cpp index 9b5537f..bf05a98 100644 --- a/Intel8080/src/Disassembler.cpp +++ b/Intel8080/src/Disassembler.cpp @@ -13,7 +13,7 @@ EightBit::Disassembler::Disassembler() { m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); } -std::string EightBit::Disassembler::state(Intel8080& cpu) { +std::string EightBit::Disassembler::state(const Intel8080& cpu) { auto pc = cpu.PC(); auto sp = cpu.SP(); @@ -160,13 +160,13 @@ std::string EightBit::Disassembler::alu2(int which) { throw std::logic_error("Unhandled alu operation"); } -std::string EightBit::Disassembler::disassemble(Intel8080& cpu) { +std::string EightBit::Disassembler::disassemble(const Intel8080& cpu) { std::ostringstream output; disassemble(output, cpu, cpu.PC().word); return output.str(); } -void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc) { +void EightBit::Disassembler::disassemble(std::ostringstream& output, const Intel8080& cpu, uint16_t pc) { auto& bus = cpu.BUS(); auto opcode = bus.peek(pc); diff --git a/Intel8080/src/Intel8080.cpp b/Intel8080/src/Intel8080.cpp index 9e39b6d..87e1cf4 100644 --- a/Intel8080/src/Intel8080.cpp +++ b/Intel8080/src/Intel8080.cpp @@ -7,19 +7,37 @@ EightBit::Intel8080::Intel8080(Bus& bus, InputOutput& ports) } EightBit::register16_t& EightBit::Intel8080::AF() { - auto& f = af.low; - f = (f | Bit1) & ~(Bit5 | Bit3); + af.low = (af.low | Bit1) & ~(Bit5 | Bit3); return af; } +EightBit::register16_t EightBit::Intel8080::AF() const { + register16_t returned; + returned.low = (af.low | Bit1) & ~(Bit5 | Bit3); + returned.high = af.high; + return returned; +} + +EightBit::register16_t EightBit::Intel8080::BC() const { + return bc; +} + EightBit::register16_t& EightBit::Intel8080::BC() { return bc; } +EightBit::register16_t EightBit::Intel8080::DE() const { + return de; +} + EightBit::register16_t& EightBit::Intel8080::DE() { return de; } +EightBit::register16_t EightBit::Intel8080::HL() const { + return hl; +} + EightBit::register16_t& EightBit::Intel8080::HL() { return hl; } @@ -240,7 +258,7 @@ void EightBit::Intel8080::xhtl(register16_t& operand) { void EightBit::Intel8080::writePort(uint8_t port, uint8_t data) { BUS().ADDRESS().low = port; BUS().ADDRESS().high = data; - BUS().placeDATA(data); + BUS().DATA() = data; writePort(); } @@ -256,7 +274,7 @@ void EightBit::Intel8080::readPort(uint8_t port, uint8_t& a) { } void EightBit::Intel8080::readPort() { - BUS().placeDATA(m_ports.read(BUS().ADDRESS().low)); + BUS().DATA() = m_ports.read(BUS().ADDRESS().low); } int EightBit::Intel8080::step() { diff --git a/Intel8080/test/Board.cpp b/Intel8080/test/Board.cpp index d0c5dfc..4a595e8 100644 --- a/Intel8080/test/Board.cpp +++ b/Intel8080/test/Board.cpp @@ -33,9 +33,8 @@ void Board::initialise() { CPU().PC() = m_configuration.getStartAddress(); } -void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080&) { - auto pc = CPU().PC(); - switch (pc.word) { +void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080& cpu) { + switch (cpu.PC().word) { case 0x0: // CP/M warm start CPU().powerOff(); if (m_configuration.isProfileMode()) { @@ -50,11 +49,10 @@ void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080&) { } } -void Board::bdos() { - auto c = CPU().C(); - switch (c) { +void Board::bdos() const { + switch (CPU().C()) { case 0x2: { - auto character = CPU().E(); + const auto character = CPU().E(); std::cout << character; break; } @@ -68,13 +66,13 @@ void Board::bdos() { void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Intel8080& cpu) { - const auto pc = CPU().PC(); + const auto pc = cpu.PC(); m_profiler.addAddress(pc.word); m_profiler.addInstruction(peek(pc.word)); } -void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080&) { +void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080& cpu) { std::cerr << EightBit::Disassembler::state(CPU()) diff --git a/Intel8080/test/Board.h b/Intel8080/test/Board.h index 840fccd..26f0cac 100644 --- a/Intel8080/test/Board.h +++ b/Intel8080/test/Board.h @@ -15,6 +15,7 @@ public: Board(const Configuration& configuration); EightBit::Intel8080& CPU() { return m_cpu; } + const EightBit::Intel8080& CPU() const { return m_cpu; } void initialise(); @@ -24,6 +25,11 @@ protected: return m_ram.reference(address); } + virtual uint8_t reference(uint16_t address, bool& rom) const { + rom = false; + return m_ram.reference(address); + } + private: const Configuration& m_configuration; EightBit::Ram m_ram = 0x10000; @@ -34,8 +40,8 @@ private: void Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080& cpu); - void Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080& cpuEvent); - void Cpu_ExecutingInstruction_Profile(const EightBit::Intel8080& cpuEvent); + void Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080& cpu); + void Cpu_ExecutingInstruction_Profile(const EightBit::Intel8080& cpu); - void bdos(); + void bdos() const; }; diff --git a/LR35902/fusetest_LR35902/FuseTestRunner.h b/LR35902/fusetest_LR35902/FuseTestRunner.h index ab21be3..559e3b8 100644 --- a/LR35902/fusetest_LR35902/FuseTestRunner.h +++ b/LR35902/fusetest_LR35902/FuseTestRunner.h @@ -42,6 +42,11 @@ namespace Fuse { return m_ram.reference(address); } + virtual uint8_t reference(uint16_t address, bool& rom) const { + rom = false; + return m_ram.reference(address); + } + public: TestRunner(const Test& test, const ExpectedTestResult& expected); diff --git a/LR35902/inc/GameBoyBus.h b/LR35902/inc/GameBoyBus.h index 74d0d75..37eb3ef 100644 --- a/LR35902/inc/GameBoyBus.h +++ b/LR35902/inc/GameBoyBus.h @@ -36,9 +36,13 @@ namespace EightBit { Bus(); LR35902& CPU() { return m_cpu; } + const LR35902& CPU() const { return m_cpu; } Ram& VRAM() { return m_videoRam; } + const Ram& VRAM() const { return m_videoRam; } Ram& OAMRAM() { return m_oamRam; } + const Ram& OAMRAM() const { return m_oamRam; } IoRegisters& IO() { return m_ioPorts; } + const IoRegisters& IO() const { return m_ioPorts; } void reset(); @@ -56,6 +60,7 @@ namespace EightBit { protected: virtual uint8_t& reference(uint16_t address, bool& rom); + virtual uint8_t reference(uint16_t address, bool& rom) const; private: LR35902 m_cpu; diff --git a/LR35902/inc/LR35902.h b/LR35902/inc/LR35902.h index ca42282..36fb2d8 100644 --- a/LR35902/inc/LR35902.h +++ b/LR35902/inc/LR35902.h @@ -35,8 +35,18 @@ namespace EightBit { return af; } + register16_t AF() const final { + register16_t returned; + returned.low = higherNibble(af.low); + returned.high = af.high; + return returned; + } + + virtual register16_t BC() const final { return bc; } virtual register16_t& BC() final { return bc; } + virtual register16_t DE() const final { return de; } virtual register16_t& DE() final { return de; } + virtual register16_t HL() const final { return hl; } virtual register16_t& HL() final { return hl; } int singleStep(); diff --git a/LR35902/src/GameBoyBus.cpp b/LR35902/src/GameBoyBus.cpp index 71ec445..40db049 100644 --- a/LR35902/src/GameBoyBus.cpp +++ b/LR35902/src/GameBoyBus.cpp @@ -148,7 +148,7 @@ void EightBit::GameBoy::Bus::validateCartridgeType() { } } -uint8_t& EightBit::GameBoy::Bus::reference(uint16_t address, bool& rom) { +uint8_t EightBit::GameBoy::Bus::reference(uint16_t address, bool& rom) const { rom = true; if ((address < 0x100) && IO().bootRomEnabled()) @@ -162,7 +162,7 @@ uint8_t& EightBit::GameBoy::Bus::reference(uint16_t address, bool& rom) { if (address < 0xa000) return VRAM().reference(address - 0x8000); if (address < 0xc000) - return m_ramBanks.size() == 0 ? rom = true, placeDATA(0xff) : m_ramBanks[m_ramBank].reference(address - 0xa000); + return m_ramBanks.size() == 0 ? rom = true, 0xff : m_ramBanks[m_ramBank].reference(address - 0xa000); if (address < 0xe000) return m_lowInternalRam.reference(address - 0xc000); if (address < 0xfe00) @@ -170,7 +170,35 @@ uint8_t& EightBit::GameBoy::Bus::reference(uint16_t address, bool& rom) { if (address < 0xfea0) return OAMRAM().reference(address - 0xfe00); if (address < IoRegisters::BASE) - return rom = true, placeDATA(0xff); + return rom = true, 0xff; + if (address < 0xff80) + return IO().reference(address - IoRegisters::BASE); + return m_highInternalRam.reference(address - 0xff80); +} + +uint8_t& EightBit::GameBoy::Bus::reference(uint16_t address, bool& rom) { + + rom = true; + if ((address < 0x100) && IO().bootRomEnabled()) + return DATA() = m_bootRom.reference(address); + if ((address < 0x4000) && gameRomEnabled()) + return DATA() = m_gameRomBanks[0].reference(address); + if ((address < 0x8000) && gameRomEnabled()) + return DATA() = m_gameRomBanks[m_romBank].reference(address - 0x4000); + + rom = false; + if (address < 0xa000) + return VRAM().reference(address - 0x8000); + if (address < 0xc000) + return m_ramBanks.size() == 0 ? rom = true, DATA() = 0xff : m_ramBanks[m_ramBank].reference(address - 0xa000); + if (address < 0xe000) + return m_lowInternalRam.reference(address - 0xc000); + if (address < 0xfe00) + return m_lowInternalRam.reference(address - 0xe000); // Low internal RAM mirror + if (address < 0xfea0) + return OAMRAM().reference(address - 0xfe00); + if (address < IoRegisters::BASE) + return rom = true, DATA() = 0xff; if (address < 0xff80) return IO().reference(address - IoRegisters::BASE); return m_highInternalRam.reference(address - 0xff80); diff --git a/LR35902/src/LR35902.cpp b/LR35902/src/LR35902.cpp index 87c60c6..d6eabe4 100644 --- a/LR35902/src/LR35902.cpp +++ b/LR35902/src/LR35902.cpp @@ -290,7 +290,7 @@ int EightBit::GameBoy::LR35902::singleStep() { m_bus.IO().poke(IoRegisters::IF, 0); lower(INT()); const int index = EightBit::findFirstSet(masked); - BUS().placeDATA(0x38 + (index << 3)); + BUS().DATA() = 0x38 + (index << 3); } else { if (halted()) proceed(); diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index c2ef9e5..8f1e2f3 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -33,12 +33,18 @@ namespace EightBit { virtual int step() final; virtual void powerOn() override; + uint8_t X() const { return x; } uint8_t& X() { return x; } + uint8_t Y() const { return y; } uint8_t& Y() { return y; } + uint8_t A() const { return a; } uint8_t& A() { return a; } + uint8_t S() const { return s; } uint8_t& S() { return s; } + uint8_t P() const { return p; } uint8_t& P() { return p; } + PinLevel SO() const { return m_soLine; } // In PinLevel& SO() { return m_soLine; } // In protected: @@ -330,6 +336,6 @@ namespace EightBit { PinLevel m_soLine = Low; - register16_t m_intermediate = { { 0, 0 } };; + register16_t m_intermediate = { { 0, 0 } }; }; } \ No newline at end of file diff --git a/M6502/test/Board.cpp b/M6502/test/Board.cpp index 03bdc34..7b3f0d5 100644 --- a/M6502/test/Board.cpp +++ b/M6502/test/Board.cpp @@ -9,14 +9,9 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration), - m_ram(0x10000), m_cpu(EightBit::MOS6502(*this)), - m_symbols(""), m_disassembler(m_cpu, m_symbols), - m_profiler(m_cpu, m_disassembler, m_symbols), - m_oldPC(0xffff), - m_stopped(false) { -} + m_profiler(m_cpu, m_disassembler, m_symbols) {} void Board::initialise() { @@ -76,7 +71,7 @@ void Board::Cpu_ExecutingInstruction_Profile(const EightBit::MOS6502& cpu) { void Board::Cpu_ExecutedInstruction_StopLoop(const EightBit::MOS6502& cpu) { - auto pc = CPU().PC().word; + auto pc = cpu.PC().word; if (m_oldPC == pc) { CPU().powerOff(); auto test = peek(0x0200); @@ -88,7 +83,7 @@ void Board::Cpu_ExecutedInstruction_StopLoop(const EightBit::MOS6502& cpu) { void Board::Cpu_ExecutingInstruction_Debug(const EightBit::MOS6502& cpu) { - auto address = CPU().PC().word; + auto address = cpu.PC().word; auto cell = peek(address); std::cout << std::hex; diff --git a/M6502/test/Board.h b/M6502/test/Board.h index b7d676e..cc38afe 100644 --- a/M6502/test/Board.h +++ b/M6502/test/Board.h @@ -25,18 +25,23 @@ protected: return m_ram.reference(address); } + virtual uint8_t reference(uint16_t address, bool& rom) const { + rom = false; + return m_ram.reference(address); + } + private: const Configuration& m_configuration; - EightBit::Ram m_ram; + EightBit::Ram m_ram = 0x10000; EightBit::MOS6502 m_cpu; - EightBit::Symbols m_symbols; + EightBit::Symbols m_symbols = ""; EightBit::Disassembly m_disassembler; EightBit::Profiler m_profiler; - uint16_t m_oldPC; - bool m_stopped; - uint64_t m_pollCounter; - uint64_t m_pollInterval; + uint16_t m_oldPC = 0xffff; + bool m_stopped = false; + uint64_t m_pollCounter = 0UL; + uint64_t m_pollInterval = 0UL; void pollKeyboard(); diff --git a/Z80/fusetest_Z80/FuseTestRunner.h b/Z80/fusetest_Z80/FuseTestRunner.h index 67c6516..a9fd22d 100644 --- a/Z80/fusetest_Z80/FuseTestRunner.h +++ b/Z80/fusetest_Z80/FuseTestRunner.h @@ -41,6 +41,11 @@ namespace Fuse { return m_ram.reference(address); } + virtual uint8_t reference(uint16_t address, bool& rom) const { + rom = false; + return m_ram.reference(address); + } + public: TestRunner(const Test& test, const ExpectedTestResult& expected); diff --git a/Z80/inc/Disassembler.h b/Z80/inc/Disassembler.h index 92539b0..399b604 100644 --- a/Z80/inc/Disassembler.h +++ b/Z80/inc/Disassembler.h @@ -11,8 +11,8 @@ namespace EightBit { public: Disassembler(); - static std::string state(Z80& cpu); - std::string disassemble(Z80& cpu); + static std::string state(const Z80& cpu); + std::string disassemble(const Z80& cpu); static std::string flag(uint8_t value, int flag, const std::string& represents); static std::string flags(uint8_t value); @@ -30,29 +30,29 @@ namespace EightBit { bool m_prefixED; bool m_prefixFD; - void disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc); + void disassemble(std::ostringstream& output, const Z80& cpu, uint16_t pc); void disassembleCB( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, int x, int y, int z, - int p, int q); + int p, int q) const; void disassembleED( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, int x, int y, int z, - int p, int q); + int p, int q) const; void disassembleOther( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 3c2a9ce..e45a33f 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -51,28 +51,44 @@ namespace EightBit { Signal ExecutingInstruction; PinLevel& M1() { return m_m1Line; } // Out + PinLevel M1() const { return m_m1Line; } virtual int execute(uint8_t opcode) final; virtual int step() final; virtual register16_t& AF() final; + virtual register16_t AF() const final; virtual register16_t& BC() final; + virtual register16_t BC() const final; virtual register16_t& DE() final; + virtual register16_t DE() const final; virtual register16_t& HL() final; + virtual register16_t HL() const final; register16_t& IX() { return m_ix; } + register16_t IX() const { return m_ix; } uint8_t& IXH() { return IX().high; } + uint8_t IXH() const { return IX().high; } uint8_t& IXL() { return IX().low; } + uint8_t IXL() const { return IX().low; } register16_t& IY() { return m_iy; } + register16_t IY() const { return m_iy; } uint8_t& IYH() { return IY().high; } + uint8_t IYH() const { return IY().high; } uint8_t& IYL() { return IY().low; } + uint8_t IYL() const { return IY().low; } refresh_t& REFRESH() { return m_refresh; } + refresh_t REFRESH() const { return m_refresh; } uint8_t& IV() { return iv; } + uint8_t IV() const { return iv; } int& IM() { return m_interruptMode; } + int IM() const { return m_interruptMode; } bool& IFF1() { return m_iff1; } + bool IFF1() const { return m_iff1; } bool& IFF2() { return m_iff2; } + bool IFF2() const { return m_iff2; } void exx() { m_registerSet ^= 1; @@ -258,6 +274,23 @@ namespace EightBit { } } + register16_t RP(const int rp) const { + ASSUME(rp >= 0); + ASSUME(rp <= 3); + switch (rp) { + case 0: + return BC(); + case 1: + return DE(); + case 2: + return HL2(); + case 3: + return SP(); + default: + UNREACHABLE; + } + } + register16_t& HL2() { if (LIKELY(!m_displaced)) return HL(); @@ -267,6 +300,15 @@ namespace EightBit { return IY(); } + register16_t HL2() const { + if (LIKELY(!m_displaced)) + return HL(); + if (m_prefixDD) + return IX(); + // Must be FD prefix + return IY(); + } + register16_t& RP2(const int rp) { ASSUME(rp >= 0); ASSUME(rp <= 3); @@ -284,6 +326,23 @@ namespace EightBit { } } + register16_t RP2(const int rp) const { + ASSUME(rp >= 0); + ASSUME(rp <= 3); + switch (rp) { + case 0: + return BC(); + case 1: + return DE(); + case 2: + return HL2(); + case 3: + return AF(); + default: + UNREACHABLE; + } + } + static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) { setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation)); } diff --git a/Z80/src/Disassembler.cpp b/Z80/src/Disassembler.cpp index 03d0381..6722380 100644 --- a/Z80/src/Disassembler.cpp +++ b/Z80/src/Disassembler.cpp @@ -15,7 +15,7 @@ EightBit::Disassembler::Disassembler() { m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); } -std::string EightBit::Disassembler::state(Z80& cpu) { +std::string EightBit::Disassembler::state(const Z80& cpu) { auto pc = cpu.PC(); auto sp = cpu.SP(); @@ -171,14 +171,14 @@ std::string EightBit::Disassembler::alu(int which) { throw std::logic_error("Unhandled alu operation"); } -std::string EightBit::Disassembler::disassemble(Z80& cpu) { +std::string EightBit::Disassembler::disassemble(const Z80& cpu) { m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; std::ostringstream output; disassemble(output, cpu, cpu.PC().word); return output.str(); } -void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc) { +void EightBit::Disassembler::disassemble(std::ostringstream& output, const Z80& cpu, uint16_t pc) { auto& bus = cpu.BUS(); auto opcode = bus.peek(pc); @@ -239,12 +239,12 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u void EightBit::Disassembler::disassembleCB( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, int x, int y, int z, - int p, int q) { + int p, int q) const { switch (x) { case 0: // rot[y] r[z] @@ -289,12 +289,12 @@ void EightBit::Disassembler::disassembleCB( void EightBit::Disassembler::disassembleED( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, int x, int y, int z, - int p, int q) { + int p, int q) const { switch (x) { case 0: case 3: @@ -423,7 +423,7 @@ void EightBit::Disassembler::disassembleED( void EightBit::Disassembler::disassembleOther( std::ostringstream& output, - Z80& cpu, + const Z80& cpu, uint16_t pc, std::string& specification, int& dumpCount, diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 4dd9d37..2755246 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -8,18 +8,34 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports) m_ports(ports) { } +EightBit::register16_t EightBit::Z80::AF() const { + return m_accumulatorFlags[m_accumulatorFlagsSet]; +} + EightBit::register16_t& EightBit::Z80::AF() { return m_accumulatorFlags[m_accumulatorFlagsSet]; } +EightBit::register16_t EightBit::Z80::BC() const { + return m_registers[m_registerSet][BC_IDX]; +} + EightBit::register16_t& EightBit::Z80::BC() { return m_registers[m_registerSet][BC_IDX]; } +EightBit::register16_t EightBit::Z80::DE() const { + return m_registers[m_registerSet][DE_IDX]; +} + EightBit::register16_t& EightBit::Z80::DE() { return m_registers[m_registerSet][DE_IDX]; } +EightBit::register16_t EightBit::Z80::HL() const { + return m_registers[m_registerSet][HL_IDX]; +} + EightBit::register16_t& EightBit::Z80::HL() { return m_registers[m_registerSet][HL_IDX]; } @@ -621,7 +637,7 @@ void EightBit::Z80::writePort(const uint8_t port, const uint8_t data) { BUS().ADDRESS().low = port; BUS().ADDRESS().high = data; MEMPTR() = BUS().ADDRESS(); - BUS().placeDATA(data); + BUS().DATA() = data; writePort(); ++MEMPTR().low; } @@ -640,7 +656,7 @@ void EightBit::Z80::readPort(const uint8_t port, uint8_t& a) { } void EightBit::Z80::readPort() { - BUS().placeDATA(m_ports.read(BUS().ADDRESS().low)); + BUS().DATA() = m_ports.read(BUS().ADDRESS().low); } int EightBit::Z80::step() { @@ -844,22 +860,22 @@ void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y, case 1: switch (z) { case 0: // Input from port with 16-bit address - MEMPTR() = BUS().ADDRESS() = BC(); - ++MEMPTR().word; + MEMPTR() = BUS().ADDRESS() = BC(); + ++MEMPTR().word; readPort(); - if (LIKELY(y != 6)) // IN r[y],(C) + if (LIKELY(y != 6)) // IN r[y],(C) R(y, a, BUS().DATA()); adjustSZPXY(f, BUS().DATA()); - clearFlag(f, NF | HC); - addCycles(12); + clearFlag(f, NF | HC); + addCycles(12); break; case 1: // Output to port with 16-bit address MEMPTR() = BUS().ADDRESS() = BC(); ++MEMPTR().word; if (UNLIKELY(y == 6)) // OUT (C),0 - BUS().placeDATA(0); + BUS().DATA() = 0; else // OUT (C),r[y] - BUS().placeDATA(R(y, a)); + BUS().DATA() = R(y, a); writePort(); addCycles(12); break; @@ -1140,7 +1156,8 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int case 0: // LD (BC),A MEMPTR() = BUS().ADDRESS() = BC(); ++MEMPTR().word; - BUS().write(a); + BUS().DATA() = a; + BUS().write(); MEMPTR().high = a; addCycles(7); break; diff --git a/Z80/test/Board.cpp b/Z80/test/Board.cpp index 6579e48..ac48f5f 100644 --- a/Z80/test/Board.cpp +++ b/Z80/test/Board.cpp @@ -34,13 +34,12 @@ void Board::initialise() { CPU().PC() = m_configuration.getStartAddress(); } -void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Z80&) { - if (UNLIKELY(EightBit::Processor::lowered(m_cpu.HALT()))) - m_cpu.powerOff(); - auto pc = m_cpu.PC(); - switch (pc.word) { +void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Z80& cpu) { + if (UNLIKELY(EightBit::Processor::lowered(cpu.HALT()))) + CPU().powerOff(); + switch (cpu.PC().word) { case 0x0: // CP/M warm start - m_cpu.powerOff(); + CPU().powerOff(); if (m_configuration.isProfileMode()) { m_profiler.dump(); } @@ -53,16 +52,13 @@ void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Z80&) { } } -void Board::bdos() { - auto c = m_cpu.C(); - switch (c) { - case 0x2: { - auto character = m_cpu.E(); - std::cout << character; +void Board::bdos() const { + switch (CPU().C()) { + case 0x2: + std::cout << CPU().E(); break; - } case 0x9: - for (uint16_t i = m_cpu.DE().word; peek(i) != '$'; ++i) { + for (uint16_t i = CPU().DE().word; peek(i) != '$'; ++i) { std::cout << peek(i); } break; @@ -71,7 +67,7 @@ void Board::bdos() { void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpu) { - const auto pc = m_cpu.PC(); + const auto pc = cpu.PC(); m_profiler.addAddress(pc.word); m_profiler.addInstruction(peek(pc.word)); @@ -80,8 +76,8 @@ void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpu) { void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Z80& cpu) { std::cerr - << EightBit::Disassembler::state(m_cpu) + << EightBit::Disassembler::state(cpu) << "\t" - << m_disassembler.disassemble(m_cpu) + << m_disassembler.disassemble(cpu) << '\n'; } diff --git a/Z80/test/Board.h b/Z80/test/Board.h index 1f6f6a2..b2c56c7 100644 --- a/Z80/test/Board.h +++ b/Z80/test/Board.h @@ -17,6 +17,7 @@ public: Board(const Configuration& configuration); EightBit::Z80& CPU() { return m_cpu; } + const EightBit::Z80& CPU() const { return m_cpu; } void initialise(); @@ -26,6 +27,11 @@ protected: return m_ram.reference(address); } + virtual uint8_t reference(uint16_t address, bool& rom) const { + rom = false; + return m_ram.reference(address); + } + private: const Configuration& m_configuration; EightBit::Ram m_ram = 0x10000; @@ -36,8 +42,8 @@ private: void Cpu_ExecutingInstruction_Cpm(const EightBit::Z80& cpu); - void Cpu_ExecutingInstruction_Debug(const EightBit::Z80& cpuEvent); - void Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpuEvent); + void Cpu_ExecutingInstruction_Debug(const EightBit::Z80& cpu); + void Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpu); - void bdos(); + void bdos() const; }; diff --git a/inc/Bus.h b/inc/Bus.h index 9424119..8b0cef2 100644 --- a/inc/Bus.h +++ b/inc/Bus.h @@ -16,32 +16,34 @@ namespace EightBit { Signal ReadingByte; Signal ReadByte; - register16_t& ADDRESS(); - uint8_t& DATA(); + register16_t& ADDRESS() { return m_address; } + register16_t ADDRESS() const { return m_address; } + uint8_t& DATA() { return m_data; } + uint8_t DATA() const { return m_data; } - uint8_t& placeDATA(uint8_t value); - uint8_t& referenceDATA(uint8_t& value); - - uint8_t peek(uint16_t address); + uint8_t peek(uint16_t address) const; void poke(uint16_t address, uint8_t value); - uint16_t peekWord(uint16_t address); + uint16_t peekWord(uint16_t address) const; uint8_t read(); uint8_t read(uint16_t offset); uint8_t read(register16_t address); + void write(); void write(uint8_t value); void write(uint16_t offset, uint8_t value); void write(register16_t address, uint8_t value); protected: virtual uint8_t& reference(uint16_t address, bool& rom) = 0; + virtual uint8_t reference(uint16_t address, bool& rom) const = 0; + uint8_t& reference(); + uint8_t reference() const; private: - uint8_t* m_data = nullptr; + uint8_t m_data = 0xff; register16_t m_address{ { 0xff, 0xff } }; - uint8_t m_temporary = 0xff; // Used to simulate ROM }; } diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index ff4a023..ad1c45e 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -37,24 +37,38 @@ namespace EightBit { } register16_t& MEMPTR() { return m_memptr; } + register16_t MEMPTR() const { return m_memptr; } register16_t& SP() { return m_sp; } + register16_t SP() const { return m_sp; } virtual register16_t& AF() = 0; + virtual register16_t AF() const = 0; uint8_t& A() { return AF().high; } + uint8_t A() const { return AF().high; } uint8_t& F() { return AF().low; } + uint8_t F() const { return AF().low; } virtual register16_t& BC() = 0; + virtual register16_t BC() const = 0; uint8_t& B() { return BC().high; } + uint8_t B() const { return BC().high; } uint8_t& C() { return BC().low; } + uint8_t C() const { return BC().low; } virtual register16_t& DE() = 0; + virtual register16_t DE() const = 0; uint8_t& D() { return DE().high; } + uint8_t D() const { return DE().high; } uint8_t& E() { return DE().low; } + uint8_t E() const { return DE().low; } virtual register16_t& HL() = 0; + virtual register16_t HL() const = 0; uint8_t& H() { return HL().high; } + uint8_t H() const { return HL().high; } uint8_t& L() { return HL().low; } + uint8_t L() const { return HL().low; } protected: IntelProcessor(Bus& bus); diff --git a/inc/Memory.h b/inc/Memory.h index 25ceac1..87ac0b4 100644 --- a/inc/Memory.h +++ b/inc/Memory.h @@ -34,15 +34,16 @@ namespace EightBit { return limit; } - protected: - std::vector& BYTES() { return m_bytes; } - - uint8_t read(const uint16_t address) const { - return m_bytes[address]; + uint8_t peek(const uint16_t address) const { + return BYTES()[address]; } - void write(const uint16_t address, const uint8_t value) { - m_bytes[address] = value; + protected: + std::vector& BYTES() { return m_bytes; } + const std::vector& BYTES() const { return m_bytes; } + + void poke(const uint16_t address, const uint8_t value) { + BYTES()[address] = value; } private: diff --git a/inc/Processor.h b/inc/Processor.h index 053a249..dbdfb29 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -68,16 +68,27 @@ namespace EightBit { static int demoteNibble(const int value) { return highNibble(value); } Bus& BUS() { return m_bus; } + const Bus& BUS() const { return m_bus; } register16_t& PC() { return m_pc; } + register16_t PC() const { return m_pc; } - PinLevel& RESET() { return m_resetLine; } // In - PinLevel& HALT() { return m_haltLine; } // Out - PinLevel& INT() { return m_intLine; } // In - PinLevel& NMI() { return m_nmiLine; } // In - PinLevel& POWER() { return m_powerLine; } // In + PinLevel& RESET() { return m_resetLine; } + PinLevel RESET() const { return m_resetLine; } // In - bool powered() { return raised(POWER()); } + PinLevel& HALT() { return m_haltLine; } + PinLevel HALT() const { return m_haltLine; } // Out + + PinLevel& INT() { return m_intLine; } + PinLevel INT() const { return m_intLine; } // In + + PinLevel& NMI() { return m_nmiLine; } + PinLevel NMI() const { return m_nmiLine; } // In + + PinLevel& POWER() { return m_powerLine; } + PinLevel POWER() const { return m_powerLine; } // In + + bool powered() const { return raised(POWER()); } virtual void powerOn() { raise(POWER()); raise(HALT()); reset(); } void powerOff() { lower(POWER()); } @@ -104,7 +115,7 @@ namespace EightBit { virtual void reset(); - bool halted() { return lowered(HALT()); } + bool halted() const { return lowered(HALT()); } void halt() { --PC().word; lower(HALT()); } void proceed() { ++PC().word; raise(HALT()); } diff --git a/inc/Ram.h b/inc/Ram.h index 5040a33..5d0190c 100644 --- a/inc/Ram.h +++ b/inc/Ram.h @@ -10,16 +10,16 @@ namespace EightBit { : Memory(size) { } - uint8_t peek(const uint16_t address) const { - return read(address); - } - - void poke(const uint16_t address, const uint8_t value) { - write(address, value); - } - uint8_t& reference(const uint16_t address) { return BYTES()[address]; } + + uint8_t reference(uint16_t address) const { + return peek(address); + } + + void poke(uint16_t address, uint8_t value) { + Memory::poke(address, value); + } }; } diff --git a/inc/Rom.h b/inc/Rom.h index 8a1b45a..e5fc81b 100644 --- a/inc/Rom.h +++ b/inc/Rom.h @@ -10,12 +10,8 @@ namespace EightBit { : Memory(size) { } - uint8_t peek(const uint16_t address) const { - return read(address); - } - - uint8_t& reference(const uint16_t address) { - return BYTES()[address]; + uint8_t reference(uint16_t address) const { + return peek(address); } }; } diff --git a/src/Bus.cpp b/src/Bus.cpp index ddfabe0..2b24347 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -3,26 +3,7 @@ #include "EightBitCompilerDefinitions.h" -EightBit::register16_t& EightBit::Bus::ADDRESS() { - return m_address; -} - -uint8_t& EightBit::Bus::DATA() { - return *m_data; -} - -uint8_t& EightBit::Bus::placeDATA(const uint8_t value) { - m_temporary = value; - m_data = &m_temporary; - return DATA(); -} - -uint8_t& EightBit::Bus::referenceDATA(uint8_t& value) { - m_data = &value; - return DATA(); -} - -uint8_t EightBit::Bus::peek(const uint16_t address) { +uint8_t EightBit::Bus::peek(const uint16_t address) const { bool rom; return reference(address, rom); } @@ -32,7 +13,7 @@ void EightBit::Bus::poke(const uint16_t address, const uint8_t value) { reference(address, rom) = value; } -uint16_t EightBit::Bus::peekWord(const uint16_t address) { +uint16_t EightBit::Bus::peekWord(const uint16_t address) const { register16_t returned; returned.low = peek(address); returned.high = peek(address + 1); @@ -41,9 +22,9 @@ uint16_t EightBit::Bus::peekWord(const uint16_t address) { uint8_t EightBit::Bus::read() { ReadingByte.fire(ADDRESS().word); - const auto returned = reference(); + DATA() = reference(); ReadByte.fire(ADDRESS().word); - return returned; + return DATA(); } uint8_t EightBit::Bus::read(const uint16_t offset) { @@ -56,12 +37,17 @@ uint8_t EightBit::Bus::read(const register16_t address) { return read(); } -void EightBit::Bus::write(const uint8_t value) { +void EightBit::Bus::write() { WritingByte.fire(ADDRESS().word); - reference() = value; + reference() = DATA(); WrittenByte.fire(ADDRESS().word); } +void EightBit::Bus::write(const uint8_t value) { + DATA() = value; + write(); +} + void EightBit::Bus::write(const uint16_t offset, const uint8_t value) { ADDRESS().word = offset; write(value); @@ -72,8 +58,12 @@ void EightBit::Bus::write(const register16_t address, const uint8_t value) { write(value); } +uint8_t EightBit::Bus::reference() const { + bool rom; + return reference(ADDRESS().word, rom); +} + uint8_t& EightBit::Bus::reference() { bool rom; - auto& value = reference(ADDRESS().word, rom); - return rom ? placeDATA(value) : referenceDATA(value); + return reference(ADDRESS().word, rom); }