diff --git a/Gaming/inc/Game.h b/Gaming/inc/Game.h index d49ac12..bd67309 100644 --- a/Gaming/inc/Game.h +++ b/Gaming/inc/Game.h @@ -3,19 +3,20 @@ #include #include #include -#include #include #include #include -#include "GameController.h" #include "SDLWrapper.h" class Configuration; namespace Gaming { + + class GameController; + class Game : public EightBit::Device { public: Game(); @@ -28,10 +29,10 @@ namespace Gaming { virtual float fps() const = 0; virtual bool useVsync() const = 0; - virtual int windowWidth() const noexcept { return displayWidth() * displayScale(); } - virtual int windowHeight() const noexcept { return displayHeight() * displayScale(); } - virtual int displayWidth() const noexcept { return rasterWidth(); } - virtual int displayHeight() const noexcept { return rasterHeight(); } + virtual int windowWidth() const noexcept; + virtual int windowHeight() const noexcept; + virtual int displayWidth() const noexcept; + virtual int displayHeight() const noexcept; virtual int displayScale() const noexcept = 0; virtual int rasterWidth() const noexcept = 0; virtual int rasterHeight() const noexcept = 0; @@ -67,19 +68,8 @@ namespace Gaming { void toggleFullscreen(); - std::shared_ptr gameController(const int which) const { - const auto i = m_gameControllers.find(which); - if (i == m_gameControllers.cend()) - throw std::runtime_error("Unknown controller"); - return i->second; - } - - int mappedController(const SDL_JoystickID which) const { - const auto i = m_mappedControllers.find(which); - if (i == m_mappedControllers.cend()) - throw std::runtime_error("Unknown joystick"); - return i->second; - } + std::shared_ptr gameController(int which) const; + int mappedController(const SDL_JoystickID which) const; int chooseControllerIndex(int who) const; std::shared_ptr chooseController(int who) const; diff --git a/Gaming/inc/SDLWrapper.h b/Gaming/inc/SDLWrapper.h index 316835d..eed2ecb 100644 --- a/Gaming/inc/SDLWrapper.h +++ b/Gaming/inc/SDLWrapper.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + namespace Gaming { class SDLWrapper final { public: diff --git a/Gaming/src/Game.cpp b/Gaming/src/Game.cpp index e4f42a0..d92d5a9 100644 --- a/Gaming/src/Game.cpp +++ b/Gaming/src/Game.cpp @@ -1,12 +1,30 @@ #include "stdafx.h" #include "Game.h" +#include "GameController.h" + namespace Gaming { Game::Game() {} Game::~Game() {} +int Game::windowWidth() const noexcept { + return displayWidth() * displayScale(); +} + +int Game::windowHeight() const noexcept { + return displayHeight() * displayScale(); +} + +int Game::displayWidth() const noexcept { + return rasterWidth(); +} + +int Game::displayHeight() const noexcept { + return rasterHeight(); +} + void Game::raisePOWER() { Device::raisePOWER(); @@ -168,6 +186,20 @@ void Game::addJoystick(SDL_Event& e) { SDL_Log("Joystick device %d added (%zd controllers)", which, m_gameControllers.size()); } +std::shared_ptr Game::gameController(const int which) const { + const auto i = m_gameControllers.find(which); + if (i == m_gameControllers.cend()) + throw std::runtime_error("Unknown controller"); + return i->second; +} + +int Game::mappedController(const SDL_JoystickID which) const { + const auto i = m_mappedControllers.find(which); + if (i == m_mappedControllers.cend()) + throw std::runtime_error("Unknown joystick"); + return i->second; +} + // -1 if no controllers, otherwise index int Game::chooseControllerIndex(const int who) const { const auto count = m_gameControllers.size(); diff --git a/LR35902/inc/LR35902.h b/LR35902/inc/LR35902.h index cfaf6fa..07467b1 100644 --- a/LR35902/inc/LR35902.h +++ b/LR35902/inc/LR35902.h @@ -40,7 +40,7 @@ namespace EightBit { Signal MachineTicked; void tickMachine(const int extra) { for (int i = 0; i < extra; ++i) tickMachine(); } - void tickMachine() { tick(4); MachineTicked.fire(EventArgs::empty()); } + void tickMachine() { tick(4); MachineTicked.fire(); } protected: int execute() final; diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 842ca9d..6ea4188 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -32,15 +32,15 @@ namespace EightBit { Signal ExecutedInstruction; int execute() final; - int step() final; + [[nodiscard]] int step() final; - auto& X() { return x; } - auto& Y() { return y; } - auto& A() { return a; } - auto& S() { return s; } + [[nodiscard]] auto& X() { return x; } + [[nodiscard]] auto& Y() { return y; } + [[nodiscard]] auto& A() { return a; } + [[nodiscard]] auto& S() { return s; } - auto& P() { return p; } - const auto& P() const { return p; } + [[nodiscard]] auto& P() { return p; } + [[nodiscard]] const auto& P() const { return p; } DECLARE_PIN_INPUT(NMI) DECLARE_PIN_INPUT(SO) @@ -49,21 +49,21 @@ namespace EightBit { DECLARE_PIN_OUTPUT(RW) protected: - virtual void handleRESET() final; - virtual void handleINT() final; + void handleRESET() final; + void handleINT() final; - virtual void busWrite() final; - virtual uint8_t busRead() final; + void busWrite() final; + [[nodiscard]] uint8_t busRead() final; - virtual uint8_t sub(uint8_t operand, uint8_t data, int borrow = 0); - uint8_t sbc(uint8_t operand, uint8_t data); - uint8_t sub_b(uint8_t operand, uint8_t data, int borrow); - uint8_t sub_d(uint8_t operand, uint8_t data, int borrow); + [[nodiscard]] virtual uint8_t sub(uint8_t operand, uint8_t data, int borrow = 0); + [[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t data); + [[nodiscard]] uint8_t sub_b(uint8_t operand, uint8_t data, int borrow); + [[nodiscard]] uint8_t sub_d(uint8_t operand, uint8_t data, int borrow); - virtual uint8_t add(uint8_t operand, uint8_t data, int carry = 0); - uint8_t adc(uint8_t operand, uint8_t data); - uint8_t add_b(uint8_t operand, uint8_t data, int carry); - uint8_t add_d(uint8_t operand, uint8_t data, int carry); + [[nodiscard]] virtual uint8_t add(uint8_t operand, uint8_t data, int carry = 0); + [[nodiscard]] uint8_t adc(uint8_t operand, uint8_t data); + [[nodiscard]] uint8_t add_b(uint8_t operand, uint8_t data, int carry); + [[nodiscard]] uint8_t add_d(uint8_t operand, uint8_t data, int carry); private: const uint8_t IRQvector = 0xfe; // IRQ vector @@ -75,25 +75,25 @@ namespace EightBit { void interrupt(); - virtual void push(uint8_t value) final; - virtual uint8_t pop() final; + void push(uint8_t value) final; + [[nodiscard]] uint8_t pop() final; // Dummy stack push, used during RESET void dummyPush(uint8_t value); // Addressing modes - register16_t Address_Absolute(); - uint8_t Address_ZeroPage(); - register16_t Address_ZeroPageIndirect(); - register16_t Address_Indirect(); - uint8_t Address_ZeroPageX(); - uint8_t Address_ZeroPageY(); - std::pair Address_AbsoluteX(); - std::pair Address_AbsoluteY(); - register16_t Address_IndexedIndirectX(); - std::pair Address_IndirectIndexedY(); - register16_t Address_relative_byte(); + [[nodiscard]] register16_t Address_Absolute(); + [[nodiscard]] uint8_t Address_ZeroPage(); + [[nodiscard]] register16_t Address_ZeroPageIndirect(); + [[nodiscard]] register16_t Address_Indirect(); + [[nodiscard]] uint8_t Address_ZeroPageX(); + [[nodiscard]] uint8_t Address_ZeroPageY(); + [[nodiscard]] std::pair Address_AbsoluteX(); + [[nodiscard]] std::pair Address_AbsoluteY(); + [[nodiscard]] register16_t Address_IndexedIndirectX(); + [[nodiscard]] std::pair Address_IndirectIndexedY(); + [[nodiscard]] register16_t Address_relative_byte(); // Addressing modes, read @@ -121,19 +121,19 @@ namespace EightBit { // Flag checking - auto interruptMasked() const { return P() & IF; } - auto decimal() const { return P() & DF; } + [[nodiscard]] auto interruptMasked() const { return P() & IF; } + [[nodiscard]] auto decimal() const { return P() & DF; } - auto negative() const { return P() & NF; } - auto zero() const { return P() & ZF; } - auto overflow() const { return P() & VF; } - auto carry() const { return P() & CF; } + [[nodiscard]] auto negative() const { return P() & NF; } + [[nodiscard]] auto zero() const { return P() & ZF; } + [[nodiscard]] auto overflow() const { return P() & VF; } + [[nodiscard]] auto carry() const { return P() & CF; } // Miscellaneous void branch(int condition); - auto through(const uint8_t data) { + [[nodiscard]] auto through(const uint8_t data) { adjustNZ(data); return data; } @@ -146,20 +146,20 @@ namespace EightBit { // Instruction implementations - uint8_t andr(uint8_t operand, uint8_t data); - uint8_t asl(uint8_t value); + [[nodiscard]] uint8_t andr(uint8_t operand, uint8_t data); + [[nodiscard]] uint8_t asl(uint8_t value); void bit(uint8_t operand, uint8_t data); void cmp(uint8_t first, uint8_t second); - uint8_t dec(uint8_t value); - uint8_t eorr(uint8_t operand, uint8_t data); - uint8_t inc(uint8_t value); + [[nodiscard]] uint8_t dec(uint8_t value); + [[nodiscard]] uint8_t eorr(uint8_t operand, uint8_t data); + [[nodiscard]] uint8_t inc(uint8_t value); void jsr(); - uint8_t lsr(uint8_t value); - uint8_t orr(uint8_t operand, uint8_t data); + [[nodiscard]] uint8_t lsr(uint8_t value); + [[nodiscard]] uint8_t orr(uint8_t operand, uint8_t data); void php(); void plp(); - uint8_t rol(uint8_t operand); - uint8_t ror(uint8_t operand); + [[nodiscard]] uint8_t rol(uint8_t operand); + [[nodiscard]] uint8_t ror(uint8_t operand); void rti(); void rts(); diff --git a/M6502/src/Profiler.cpp b/M6502/src/Profiler.cpp index c0ee9f2..57b9cc0 100644 --- a/M6502/src/Profiler.cpp +++ b/M6502/src/Profiler.cpp @@ -17,15 +17,15 @@ EightBit::Profiler::Profiler(MOS6502& targetProcessor, Disassembly& disassembler } void EightBit::Profiler::Generate() { - StartingOutput.fire(EventArgs::empty()); + StartingOutput.fire(); EmitProfileInformation(); - StartingOutput.fire(EventArgs::empty()); + StartingOutput.fire(); } void EightBit::Profiler::EmitProfileInformation() { { - StartingLineOutput.fire(EventArgs::empty()); + StartingLineOutput.fire(); // For each memory address for (int address = 0; address < 0x10000; ++address) { // If there are any cycles associated @@ -37,11 +37,11 @@ void EightBit::Profiler::EmitProfileInformation() { EmitLine.fire(event); } } - FinishedLineOutput.fire(EventArgs::empty()); + FinishedLineOutput.fire(); } { - StartingScopeOutput.fire(EventArgs::empty()); + StartingScopeOutput.fire(); for (auto& scopeCycle : scopeCycles) { auto name = scopeCycle.first; auto cycles = scopeCycle.second; @@ -50,7 +50,7 @@ void EightBit::Profiler::EmitProfileInformation() { ProfileScopeEventArgs event(name, cycles, count); EmitScope.fire(event); } - FinishedScopeOutput.fire(EventArgs::empty()); + FinishedScopeOutput.fire(); } } diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index bdacdd1..f55205c 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -120,45 +120,45 @@ int EightBit::MOS6502::execute() { case 0x05: A() = orr(A(), AM_ZeroPage()); break; // ORA (zero page) case 0x06: memoryReadModifyWrite(asl(AM_ZeroPage())); break; // ASL (zero page) case 0x07: slo(AM_ZeroPage()); break; // *SLO (zero page) - case 0x08: memoryRead(); php(); break; // PHP (implied) + case 0x08: memoryRead(); php(); break; // PHP (implied) case 0x09: A() = orr(A(), AM_Immediate()); break; // ORA (immediate) case 0x0a: memoryRead(); A() = asl(A()); break; // ASL A (implied) - case 0x0b: anc(AM_Immediate()); break; // *ANC (immediate) + case 0x0b: anc(AM_Immediate()); break; // *ANC (immediate) case 0x0c: AM_Absolute(); break; // *NOP (absolute) case 0x0d: A() = orr(A(), AM_Absolute()); break; // ORA (absolute) case 0x0e: memoryReadModifyWrite(asl(AM_Absolute())); break; // ASL (absolute) case 0x0f: slo(AM_Absolute()); break; // *SLO (absolute) - case 0x10: branch(!negative()); break; // BPL (relative) + case 0x10: branch(!negative()); break; // BPL (relative) case 0x11: A() = orr(A(), AM_IndirectIndexedY()); break; // ORA (indirect indexed Y) case 0x12: break; case 0x13: slo(AM_IndirectIndexedY()); break; // *SLO (indirect indexed Y) case 0x14: AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x15: A() = orr(A(), AM_ZeroPageX()); break; // ORA (zero page, X) case 0x16: memoryReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (zero page, X) - case 0x17: slo(AM_ZeroPageX()); break; // *SLO (zero page, X) + case 0x17: slo(AM_ZeroPageX()); break; // *SLO (zero page, X) case 0x18: memoryRead(); P() = clearBit(P(), CF); break; // CLC (implied) case 0x19: A() = orr(A(), AM_AbsoluteY()); break; // ORA (absolute, Y) case 0x1a: memoryRead(); break; // *NOP (implied) - case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y) + case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y) case 0x1c: AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x1d: A() = orr(A(), AM_AbsoluteX()); break; // ORA (absolute, X) case 0x1e: memoryReadModifyWrite(asl(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ASL (absolute, X) - case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X) + case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X) case 0x20: jsr(); break; // JSR (absolute) case 0x21: A() = andr(A(), AM_IndexedIndirectX()); break; // AND (indexed indirect X) case 0x22: break; case 0x23: rla(AM_IndexedIndirectX()); break; // *RLA (indexed indirect X) - case 0x24: bit(A(), AM_ZeroPage()); break; // BIT (zero page) + case 0x24: bit(A(), AM_ZeroPage()); break; // BIT (zero page) case 0x25: A() = andr(A(), AM_ZeroPage()); break; // AND (zero page) case 0x26: memoryReadModifyWrite(rol(AM_ZeroPage())); break; // ROL (zero page) case 0x27: rla(AM_ZeroPage()); break; // *RLA (zero page) case 0x28: memoryRead(); getBytePaged(1, S()); plp(); break; // PLP (implied) - case 0x29: A() = andr(A(), AM_Immediate()); break; // AND (immediate) + case 0x29: A() = andr(A(), AM_Immediate()); break; // AND (immediate) case 0x2a: memoryRead(); A() = rol(A()); break; // ROL A (implied) - case 0x2b: anc(AM_Immediate()); break; // *ANC (immediate) - case 0x2c: bit(A(), AM_Absolute()); break; // BIT (absolute) + case 0x2b: anc(AM_Immediate()); break; // *ANC (immediate) + case 0x2c: bit(A(), AM_Absolute()); break; // BIT (absolute) case 0x2d: A() = andr(A(), AM_Absolute()); break; // AND (absolute) case 0x2e: memoryReadModifyWrite(rol(AM_Absolute())); break; // ROL (absolute) case 0x2f: rla(AM_Absolute()); break; // *RLA (absolute) @@ -168,19 +168,19 @@ int EightBit::MOS6502::execute() { case 0x32: break; case 0x33: rla(AM_IndirectIndexedY()); break; // *RLA (indirect indexed Y) case 0x34: AM_ZeroPageX(); break; // *NOP (zero page, X) - case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X) + case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X) case 0x36: memoryReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (zero page, X) - case 0x37: rla(AM_ZeroPageX()); break; // *RLA (zero page, X) - case 0x38: memoryRead(); P() = setBit(P(), CF); break; // SEC (implied) - case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y) + case 0x37: rla(AM_ZeroPageX()); break; // *RLA (zero page, X) + case 0x38: memoryRead(); P() = setBit(P(), CF); break; // SEC (implied) + case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y) case 0x3a: memoryRead(); break; // *NOP (implied) - case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y) + case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y) case 0x3c: AM_AbsoluteX(); break; // *NOP (absolute, X) - case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X) + case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X) case 0x3e: memoryReadModifyWrite(rol(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROL (absolute, X) - case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X) + case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X) - case 0x40: memoryRead(); rti(); break; // RTI (implied) + case 0x40: memoryRead(); rti(); break; // RTI (implied) case 0x41: A() = eorr(A(), AM_IndexedIndirectX()); break; // EOR (indexed indirect X) case 0x42: break; case 0x43: sre(AM_IndexedIndirectX()); break; // *SRE (indexed indirect X) @@ -188,33 +188,33 @@ int EightBit::MOS6502::execute() { case 0x45: A() = eorr(A(), AM_ZeroPage()); break; // EOR (zero page) case 0x46: memoryReadModifyWrite(lsr(AM_ZeroPage())); break; // LSR (zero page) case 0x47: sre(AM_ZeroPage()); break; // *SRE (zero page) - case 0x48: memoryRead(); push(A()); break; // PHA (implied) - case 0x49: A() = eorr(A(), AM_Immediate()); break; // EOR (immediate) + case 0x48: memoryRead(); push(A()); break; // PHA (implied) + case 0x49: A() = eorr(A(), AM_Immediate()); break; // EOR (immediate) case 0x4a: memoryRead(); A() = lsr(A()); break; // LSR A (implied) - case 0x4b: asr(AM_Immediate()); break; // *ASR (immediate) + case 0x4b: asr(AM_Immediate()); break; // *ASR (immediate) case 0x4c: jump(Address_Absolute()); break; // JMP (absolute) case 0x4d: A() = eorr(A(), AM_Absolute()); break; // EOR (absolute) case 0x4e: memoryReadModifyWrite(lsr(AM_Absolute())); break; // LSR (absolute) case 0x4f: sre(AM_Absolute()); break; // *SRE (absolute) - case 0x50: branch(!overflow()); break; // BVC (relative) + case 0x50: branch(!overflow()); break; // BVC (relative) case 0x51: A() = eorr(A(), AM_IndirectIndexedY()); break; // EOR (indirect indexed Y) case 0x52: break; case 0x53: sre(AM_IndirectIndexedY()); break; // *SRE (indirect indexed Y) case 0x54: AM_ZeroPageX(); break; // *NOP (zero page, X) - case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X) + case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X) case 0x56: memoryReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (zero page, X) - case 0x57: sre(AM_ZeroPageX()); break; // *SRE (zero page, X) + case 0x57: sre(AM_ZeroPageX()); break; // *SRE (zero page, X) case 0x58: memoryRead(); P() = clearBit(P(), IF); break; // CLI (implied) - case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y) + case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y) case 0x5a: memoryRead(); break; // *NOP (implied) - case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y) + case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y) case 0x5c: AM_AbsoluteX(); break; // *NOP (absolute, X) - case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X) + case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X) case 0x5e: memoryReadModifyWrite(lsr(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // LSR (absolute, X) - case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X) + case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X) - case 0x60: memoryRead(); rts(); break; // RTS (implied) + case 0x60: memoryRead(); rts(); break; // RTS (implied) case 0x61: A() = adc(A(), AM_IndexedIndirectX()); break; // ADC (indexed indirect X) case 0x62: break; case 0x63: rra(AM_IndexedIndirectX()); break; // *RRA (indexed indirect X) @@ -225,7 +225,7 @@ int EightBit::MOS6502::execute() { case 0x68: memoryRead(); getBytePaged(1, S()); A() = through(pop()); break; // PLA (implied) case 0x69: A() = adc(A(), AM_Immediate()); break; // ADC (immediate) case 0x6a: memoryRead(); A() = ror(A()); break; // ROR A (implied) - case 0x6b: arr(AM_Immediate()); break; // *ARR (immediate) + case 0x6b: arr(AM_Immediate()); break; // *ARR (immediate) case 0x6c: jump(Address_Indirect()); break; // JMP (indirect) case 0x6d: A() = adc(A(), AM_Absolute()); break; // ADC (absolute) case 0x6e: memoryReadModifyWrite(ror(AM_Absolute())); break; // ROR (absolute) @@ -238,15 +238,15 @@ int EightBit::MOS6502::execute() { case 0x74: AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x75: A() = adc(A(), AM_ZeroPageX()); break; // ADC (zero page, X) case 0x76: memoryReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (zero page, X) - case 0x77: rra(AM_ZeroPageX()); break; // *RRA (zero page, X) - case 0x78: memoryRead(); P() = setBit(P(), IF); break; // SEI (implied) + case 0x77: rra(AM_ZeroPageX()); break; // *RRA (zero page, X) + case 0x78: memoryRead(); P() = setBit(P(), IF); break; // SEI (implied) case 0x79: A() = adc(A(), AM_AbsoluteY()); break; // ADC (absolute, Y) case 0x7a: memoryRead(); break; // *NOP (implied) - case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y) + case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y) case 0x7c: AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x7d: A() = adc(A(), AM_AbsoluteX()); break; // ADC (absolute, X) case 0x7e: memoryReadModifyWrite(ror(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROR (absolute, X) - case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X) + case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X) case 0x80: AM_Immediate(); break; // *NOP (immediate) case 0x81: memoryWrite(Address_IndexedIndirectX(), A()); break; // STA (indexed indirect X) @@ -266,19 +266,19 @@ int EightBit::MOS6502::execute() { case 0x8f: memoryWrite(Address_Absolute(), A() & X()); break; // *SAX (absolute) case 0x90: branch(!carry()); break; // BCC (relative) - case 0x91: AM_IndirectIndexedY(); memoryWrite(A()); break; // STA (indirect indexed Y) + case 0x91: AM_IndirectIndexedY(); memoryWrite(A()); break; // STA (indirect indexed Y) case 0x92: break; case 0x93: break; case 0x94: memoryWrite(Address_ZeroPageX(), Y()); break; // STY (zero page, X) case 0x95: memoryWrite(Address_ZeroPageX(), A()); break; // STA (zero page, X) case 0x96: memoryWrite(Address_ZeroPageY(), X()); break; // STX (zero page, Y) - case 0x97: memoryWrite(Address_ZeroPageY(), A() & X()); break; // *SAX (zero page, Y) + case 0x97: memoryWrite(Address_ZeroPageY(), A() & X()); break; // *SAX (zero page, Y) case 0x98: memoryRead(); A() = through(Y()); break; // TYA (implied) - case 0x99: sta_AbsoluteY(); break; // STA (absolute, Y) - case 0x9a: memoryRead(); S() = X(); break; // TXS (implied) + case 0x99: sta_AbsoluteY(); break; // STA (absolute, Y) + case 0x9a: memoryRead(); S() = X(); break; // TXS (implied) case 0x9b: break; case 0x9c: break; - case 0x9d: sta_AbsoluteX(); break; // STA (absolute, X) + case 0x9d: sta_AbsoluteX(); break; // STA (absolute, X) case 0x9e: break; case 0x9f: break; @@ -293,20 +293,20 @@ int EightBit::MOS6502::execute() { case 0xa8: memoryRead(); Y() = through(A()); break; // TAY (implied) case 0xa9: A() = through(AM_Immediate()); break; // LDA (immediate) case 0xaa: memoryRead(); X() = through(A()); break; // TAX (implied) - case 0xab: A() = X() = through(AM_Immediate()); break; // *ATX (immediate) + case 0xab: A() = X() = through(AM_Immediate()); break; // *ATX (immediate) case 0xac: Y() = through(AM_Absolute()); break; // LDY (absolute) case 0xad: A() = through(AM_Absolute()); break; // LDA (absolute) case 0xae: X() = through(AM_Absolute()); break; // LDX (absolute) case 0xaf: A() = X() = through(AM_Absolute()); break; // *LAX (absolute) - case 0xb0: branch(carry()); break; // BCS (relative) + case 0xb0: branch(carry()); break; // BCS (relative) case 0xb1: A() = through(AM_IndirectIndexedY()); break; // LDA (indirect indexed Y) case 0xb2: break; case 0xb3: A() = X() = through(AM_IndirectIndexedY()); break; // *LAX (indirect indexed Y) case 0xb4: Y() = through(AM_ZeroPageX()); break; // LDY (zero page, X) case 0xb5: A() = through(AM_ZeroPageX()); break; // LDA (zero page, X) case 0xb6: X() = through(AM_ZeroPageY()); break; // LDX (zero page, Y) - case 0xb7: A() = X() = through(AM_ZeroPageY()); break; // *LAX (zero page, Y) + case 0xb7: A() = X() = through(AM_ZeroPageY()); break; // *LAX (zero page, Y) case 0xb8: memoryRead(); P() = clearBit(P(), VF); break; // CLV (implied) case 0xb9: A() = through(AM_AbsoluteY()); break; // LDA (absolute, Y) case 0xba: memoryRead(); X() = through(S()); break; // TSX (implied) @@ -314,47 +314,47 @@ int EightBit::MOS6502::execute() { case 0xbc: Y() = through(AM_AbsoluteX()); break; // LDY (absolute, X) case 0xbd: A() = through(AM_AbsoluteX()); break; // LDA (absolute, X) case 0xbe: X() = through(AM_AbsoluteY()); break; // LDX (absolute, Y) - case 0xbf: A() = X() = through(AM_AbsoluteY()); break; // *LAX (absolute, Y) + case 0xbf: A() = X() = through(AM_AbsoluteY()); break; // *LAX (absolute, Y) case 0xc0: cmp(Y(), AM_Immediate()); break; // CPY (immediate) - case 0xc1: cmp(A(), AM_IndexedIndirectX()); break; // CMP (indexed indirect X) + case 0xc1: cmp(A(), AM_IndexedIndirectX()); break; // CMP (indexed indirect X) case 0xc2: AM_Immediate(); break; // *NOP (immediate) case 0xc3: dcp(AM_IndexedIndirectX()); break; // *DCP (indexed indirect X) - case 0xc4: cmp(Y(), AM_ZeroPage()); break; // CPY (zero page) - case 0xc5: cmp(A(), AM_ZeroPage()); break; // CMP (zero page) + case 0xc4: cmp(Y(), AM_ZeroPage()); break; // CPY (zero page) + case 0xc5: cmp(A(), AM_ZeroPage()); break; // CMP (zero page) case 0xc6: memoryReadModifyWrite(dec(AM_ZeroPage())); break; // DEC (zero page) case 0xc7: dcp(AM_ZeroPage()); break; // *DCP (zero page) case 0xc8: memoryRead(); Y() = inc(Y()); break; // INY (implied) case 0xc9: cmp(A(), AM_Immediate()); break; // CMP (immediate) case 0xca: memoryRead(); X() = dec(X()); break; // DEX (implied) - case 0xcb: axs(AM_Immediate()); break; // *AXS (immediate) - case 0xcc: cmp(Y(), AM_Absolute()); break; // CPY (absolute) - case 0xcd: cmp(A(), AM_Absolute()); break; // CMP (absolute) + case 0xcb: axs(AM_Immediate()); break; // *AXS (immediate) + case 0xcc: cmp(Y(), AM_Absolute()); break; // CPY (absolute) + case 0xcd: cmp(A(), AM_Absolute()); break; // CMP (absolute) case 0xce: memoryReadModifyWrite(dec(AM_Absolute())); break; // DEC (absolute) case 0xcf: dcp(AM_Absolute()); break; // *DCP (absolute) - case 0xd0: branch(!zero()); break; // BNE (relative) - case 0xd1: cmp(A(), AM_IndirectIndexedY()); break; // CMP (indirect indexed Y) + case 0xd0: branch(!zero()); break; // BNE (relative) + case 0xd1: cmp(A(), AM_IndirectIndexedY()); break; // CMP (indirect indexed Y) case 0xd2: break; case 0xd3: dcp(AM_IndirectIndexedY()); break; // *DCP (indirect indexed Y) case 0xd4: AM_ZeroPageX(); break; // *NOP (zero page, X) case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (zero page, X) case 0xd6: memoryReadModifyWrite(dec(AM_ZeroPageX())); break; // DEC (zero page, X) - case 0xd7: dcp(AM_ZeroPageX()); break; // *DCP (zero page, X) + case 0xd7: dcp(AM_ZeroPageX()); break; // *DCP (zero page, X) case 0xd8: memoryRead(); P() = clearBit(P(), DF); break; // CLD (implied) case 0xd9: cmp(A(), AM_AbsoluteY()); break; // CMP (absolute, Y) case 0xda: memoryRead(); break; // *NOP (implied) - case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y) + case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y) case 0xdc: AM_AbsoluteX(); break; // *NOP (absolute, X) case 0xdd: cmp(A(), AM_AbsoluteX()); break; // CMP (absolute, X) case 0xde: memoryReadModifyWrite(dec(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // DEC (absolute, X) - case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X) + case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X) case 0xe0: cmp(X(), AM_Immediate()); break; // CPX (immediate) case 0xe1: A() = sbc(A(), AM_IndexedIndirectX()); break; // SBC (indexed indirect X) case 0xe2: AM_Immediate(); break; // *NOP (immediate) case 0xe3: isb(AM_IndexedIndirectX()); break; // *ISB (indexed indirect X) - case 0xe4: cmp(X(), AM_ZeroPage()); break; // CPX (zero page) + case 0xe4: cmp(X(), AM_ZeroPage()); break; // CPX (zero page) case 0xe5: A() = sbc(A(), AM_ZeroPage()); break; // SBC (zero page) case 0xe6: memoryReadModifyWrite(inc(AM_ZeroPage())); break; // INC (zero page) case 0xe7: isb(AM_ZeroPage()); break; // *ISB (zero page) @@ -362,7 +362,7 @@ int EightBit::MOS6502::execute() { case 0xe9: A() = sbc(A(), AM_Immediate()); break; // SBC (immediate) case 0xea: memoryRead(); break; // NOP (implied) case 0xeb: A() = sbc(A(), AM_Immediate()); break; // *SBC (immediate) - case 0xec: cmp(X(), AM_Absolute()); break; // CPX (absolute) + case 0xec: cmp(X(), AM_Absolute()); break; // CPX (absolute) case 0xed: A() = sbc(A(), AM_Absolute()); break; // SBC (absolute) case 0xee: memoryReadModifyWrite(inc(AM_Absolute())); break; // INC (absolute) case 0xef: isb(AM_Absolute()); break; // *ISB (absolute) @@ -374,15 +374,15 @@ int EightBit::MOS6502::execute() { case 0xf4: AM_ZeroPageX(); break; // *NOP (zero page, X) case 0xf5: A() = sbc(A(), AM_ZeroPageX()); break; // SBC (zero page, X) case 0xf6: memoryReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (zero page, X) - case 0xf7: isb(AM_ZeroPageX()); break; // *ISB (zero page, X) - case 0xf8: memoryRead(); P() = setBit(P(), DF); break; // SED (implied) + case 0xf7: isb(AM_ZeroPageX()); break; // *ISB (zero page, X) + case 0xf8: memoryRead(); P() = setBit(P(), DF); break; // SED (implied) case 0xf9: A() = sbc(A(), AM_AbsoluteY()); break; // SBC (absolute, Y) case 0xfa: memoryRead(); break; // *NOP (implied) - case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y) + case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y) case 0xfc: AM_AbsoluteX(); break; // *NOP (absolute, X) case 0xfd: A() = sbc(A(), AM_AbsoluteX()); break; // SBC (absolute, X) case 0xfe: memoryReadModifyWrite(inc(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // INC (absolute, X) - case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X) + case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X) } ASSUME(cycles() > 0); diff --git a/M6532/src/M6532.cpp b/M6532/src/M6532.cpp index 2598837..a9d1bb8 100644 --- a/M6532/src/M6532.cpp +++ b/M6532/src/M6532.cpp @@ -23,7 +23,7 @@ void EightBit::M6532::step() { if (!activated()) return; - Accessing.fire(EventArgs::empty()); + Accessing.fire(); if (lowered(RES())) { reset(); @@ -120,7 +120,7 @@ void EightBit::M6532::step() { } } - Accessed.fire(EventArgs::empty()); + Accessed.fire(); } void EightBit::M6532::reset() { diff --git a/MC6809/inc/Disassembly.h b/MC6809/inc/Disassembly.h index 0ebaff8..157d5e7 100644 --- a/MC6809/inc/Disassembly.h +++ b/MC6809/inc/Disassembly.h @@ -12,11 +12,24 @@ namespace EightBit { public: Disassembly(Bus& bus, mc6809& processor); - bool ignore(); + [[nodiscard]] bool ignore(); - std::string trace(uint16_t current); - std::string trace(register16_t current); - std::string trace(); + [[nodiscard]] std::string trace(uint16_t current); + [[nodiscard]] std::string disassemble(uint16_t current); + + [[nodiscard]] std::string trace(register16_t current); + [[nodiscard]] std::string disassemble(register16_t current); + + [[nodiscard]] std::string trace(); + [[nodiscard]] std::string disassemble(); + + static [[nodiscard]] std::string dump_Flags(uint8_t value); + static [[nodiscard]] std::string dump_ByteValue(uint8_t value); + static [[nodiscard]] std::string dump_RelativeValue(int8_t value); + static [[nodiscard]] std::string dump_WordValue(uint16_t value); + static [[nodiscard]] std::string dump_WordValue(register16_t value); + static [[nodiscard]] std::string dump_RelativeValue(int16_t value); + static [[nodiscard]] std::string dump_RelativeValue(register16_t value); private: Bus& m_bus; @@ -27,63 +40,50 @@ namespace EightBit { bool m_prefix10 = false; bool m_prefix11 = false; - static std::string dump_Flags(uint8_t value); - static std::string dump_ByteValue(uint8_t value); - static std::string dump_RelativeValue(int8_t value); - static std::string dump_WordValue(uint16_t value); - static std::string dump_WordValue(register16_t value); - static std::string dump_RelativeValue(int16_t value); - static std::string dump_RelativeValue(register16_t value); - - std::string disassemble(uint16_t current); - std::string disassemble(register16_t current); - std::string disassemble(); - static void dump(std::ostream& out, int value, int width); - mc6809& CPU() { return m_cpu; } + [[nodiscard]] mc6809& CPU() { return m_cpu; } + [[nodiscard]] Bus& BUS() { return m_bus; } - uint8_t getByte(uint16_t address); - uint16_t getWord(uint16_t address); + [[nodiscard]] uint8_t getByte(uint16_t address); + [[nodiscard]] uint16_t getWord(uint16_t address); - std::string disassembleUnprefixed(); - std::string disassemble10(); - std::string disassemble11(); + [[nodiscard]] std::string disassembleUnprefixed(); + [[nodiscard]] std::string disassemble10(); + [[nodiscard]] std::string disassemble11(); // - std::string RR(int which); - std::string wrapIndirect(std::string what, bool indirect); + [[nodiscard]] std::string RR(int which); + [[nodiscard]] std::string wrapIndirect(std::string what, bool indirect); - std::string Address_direct(std::string mnemomic); - std::string Address_indexed(std::string mnemomic); - std::string Address_extended(std::string mnemomic); - std::string Address_relative_byte(std::string mnemomic); - std::string Address_relative_word(std::string mnemomic); + [[nodiscard]] std::string Address_direct(std::string mnemomic); + [[nodiscard]] std::string Address_indexed(std::string mnemomic); + [[nodiscard]] std::string Address_extended(std::string mnemomic); + [[nodiscard]] std::string Address_relative_byte(std::string mnemomic); + [[nodiscard]] std::string Address_relative_word(std::string mnemomic); - std::string AM_immediate_byte(std::string mnemomic); - std::string AM_immediate_word(std::string mnemomic); + [[nodiscard]] std::string AM_immediate_byte(std::string mnemomic); + [[nodiscard]] std::string AM_immediate_word(std::string mnemomic); // - std::string branchShort(std::string mnemomic); - std::string branchLong(std::string mnemomic); + [[nodiscard]] std::string branchShort(std::string mnemomic); + [[nodiscard]] std::string branchLong(std::string mnemomic); // - std::string referenceTransfer8(int specifier); - std::string referenceTransfer16(int specifier); - std::string tfr(std::string mnemomic); + [[nodiscard]] std::string referenceTransfer8(int specifier); + [[nodiscard]] std::string referenceTransfer16(int specifier); + [[nodiscard]] std::string tfr(std::string mnemomic); // - std::string pulS(); - std::string pulU(); - std::string pshS(); - std::string pshU(); - std::string pulX(std::string mnemomic, std::string upon); - std::string pshX(std::string mnemomic, std::string upon); - - Bus& BUS() { return m_bus; } + [[nodiscard]] std::string pulS(); + [[nodiscard]] std::string pulU(); + [[nodiscard]] std::string pshS(); + [[nodiscard]] std::string pshU(); + [[nodiscard]] std::string pulX(std::string mnemomic, std::string upon); + [[nodiscard]] std::string pshX(std::string mnemomic, std::string upon); }; } \ No newline at end of file diff --git a/MC6809/inc/ProfileLineEventArgs.h b/MC6809/inc/ProfileLineEventArgs.h new file mode 100644 index 0000000..7101120 --- /dev/null +++ b/MC6809/inc/ProfileLineEventArgs.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +namespace EightBit { + class ProfileLineEventArgs + { + private: + int m_address; + std::string m_source; + uint64_t m_cycles; + + public: + ProfileLineEventArgs(int address, std::string source, uint64_t cycles) + : m_address(address), m_source(source), m_cycles(cycles) {} + + int address() const { return m_address; } + const std::string& source() const { return m_source; } + uint64_t cycles() const { return m_cycles; } + }; +} \ No newline at end of file diff --git a/MC6809/inc/Profiler.h b/MC6809/inc/Profiler.h new file mode 100644 index 0000000..d9f97a0 --- /dev/null +++ b/MC6809/inc/Profiler.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include "ProfileLineEventArgs.h" + +namespace EightBit { + + class Disassembly; + class mc6809; + + class Profiler { + public: + std::array instructionCounts; + std::array addressProfiles; + std::array addressCounts; + + mc6809& processor; + Disassembly& disassembler; + + Profiler(mc6809& processor, Disassembly& disassembler); + + Signal StartingOutput; + Signal FinishedOutput; + + Signal EmitLine; + + void addInstruction(uint8_t instruction); + void addAddress(uint16_t address, int cycles); + + void Generate(); + + private: + void EmitProfileInformation(); + }; +} \ No newline at end of file diff --git a/MC6809/src/Disassembly.cpp b/MC6809/src/Disassembly.cpp index 6825835..6dedff0 100644 --- a/MC6809/src/Disassembly.cpp +++ b/MC6809/src/Disassembly.cpp @@ -146,39 +146,39 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x3a: output << "\tABX"; break; // ABX (inherent) // ADC - case 0x89: output << AM_immediate_byte("ADCA"); break; // ADC (ADCA immediate) + case 0x89: output << AM_immediate_byte("ADCA"); break; // ADC (ADCA immediate) case 0x99: output << Address_direct("ADCA"); break; // ADC (ADCA direct) case 0xa9: output << Address_indexed("ADCA"); break; // ADC (ADCA indexed) case 0xb9: output << Address_extended("ADCA"); break; // ADC (ADCA extended) - case 0xc9: output << AM_immediate_byte("ADCB"); break; // ADC (ADCB immediate) + case 0xc9: output << AM_immediate_byte("ADCB"); break; // ADC (ADCB immediate) case 0xd9: output << Address_direct("ADCB"); break; // ADC (ADCB direct) case 0xe9: output << Address_indexed("ADCB"); break; // ADC (ADCB indexed) case 0xf9: output << Address_extended("ADCB"); break; // ADC (ADCB extended) // ADD case 0x8b: output << Address_extended("ADDA"); break; // ADD (ADDA immediate) - case 0x9b: output << Address_direct("ADDA"); break; // ADD (ADDA direct) + case 0x9b: output << Address_direct("ADDA"); break; // ADD (ADDA direct) case 0xab: output << Address_indexed("ADDA"); break; // ADD (ADDA indexed) case 0xbb: output << Address_extended("ADDA"); break; // ADD (ADDA extended) case 0xcb: output << Address_extended("ADDB"); break; // ADD (ADDB immediate) - case 0xdb: output << Address_direct("ADDB"); break; // ADD (ADDB direct) + case 0xdb: output << Address_direct("ADDB"); break; // ADD (ADDB direct) case 0xeb: output << Address_indexed("ADDB"); break; // ADD (ADDB indexed) case 0xfb: output << Address_extended("ADDB"); break; // ADD (ADDB extended) case 0xc3: output << AM_immediate_word("ADDD"); break; // ADD (ADDD immediate) - case 0xd3: output << Address_direct("ADDD"); break; // ADD (ADDD direct) + case 0xd3: output << Address_direct("ADDD"); break; // ADD (ADDD direct) case 0xe3: output << Address_indexed("ADDD"); break; // ADD (ADDD indexed) case 0xf3: output << Address_extended("ADDD"); break; // ADD (ADDD extended) // AND - case 0x84: output << AM_immediate_byte("ANDA"); break; // AND (ANDA immediate) + case 0x84: output << AM_immediate_byte("ANDA"); break; // AND (ANDA immediate) case 0x94: output << Address_direct("ANDA"); break; // AND (ANDA direct) case 0xa4: output << Address_indexed("ANDA"); break; // AND (ANDA indexed) case 0xb4: output << Address_extended("ANDA"); break; // AND (ANDA extended) - case 0xc4: output << AM_immediate_byte("ANDB"); break; // AND (ANDB immediate) + case 0xc4: output << AM_immediate_byte("ANDB"); break; // AND (ANDB immediate) case 0xd4: output << Address_direct("ANDB"); break; // AND (ANDB direct) case 0xe4: output << Address_indexed("ANDB"); break; // AND (ANDB indexed) case 0xf4: output << Address_extended("ANDB"); break; // AND (ANDB extended) @@ -186,32 +186,32 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x1c: output << AM_immediate_byte("ANDCC"); break; // AND (ANDCC immediate) // ASL/LSL - case 0x08: output << Address_direct("ASL"); break; // ASL (direct) + case 0x08: output << Address_direct("ASL"); break; // ASL (direct) case 0x48: output << "\tASLA\t"; break; // ASL (ASLA inherent) case 0x58: output << "\tASLB\t"; break; // ASL (ASLB inherent) case 0x68: output << Address_indexed("ASL"); break; // ASL (indexed) case 0x78: output << Address_extended("ASL"); break; // ASL (extended) // ASR - case 0x07: output << Address_direct("ASR"); break; // ASR (direct) + case 0x07: output << Address_direct("ASR"); break; // ASR (direct) case 0x47: output << "\tASRA\t"; break; // ASR (ASRA inherent) case 0x57: output << "\tASRB\t"; break; // ASR (ASRB inherent) case 0x67: output << Address_indexed("ASR"); break; // ASR (indexed) case 0x77: output << Address_extended("ASR"); break; // ASR (extended) // BIT - case 0x85: output << AM_immediate_byte("BITA"); break; // BIT (BITA immediate) + case 0x85: output << AM_immediate_byte("BITA"); break; // BIT (BITA immediate) case 0x95: output << Address_direct("BITA"); break; // BIT (BITA direct) case 0xa5: output << Address_indexed("BITA"); break; // BIT (BITA indexed) case 0xb5: output << Address_extended("BITA"); break; // BIT (BITA extended) - case 0xc5: output << AM_immediate_byte("BITB"); break; // BIT (BITB immediate) + case 0xc5: output << AM_immediate_byte("BITB"); break; // BIT (BITB immediate) case 0xd5: output << Address_direct("BITB"); break; // BIT (BITB direct) case 0xe5: output << Address_indexed("BITB"); break; // BIT (BITB indexed) case 0xf5: output << Address_extended("BITB"); break; // BIT (BITB extended) // CLR - case 0x0f: output << Address_direct("CLR"); break; // CLR (direct) + case 0x0f: output << Address_direct("CLR"); break; // CLR (direct) case 0x4f: output << "\tCLRA\t"; break; // CLR (CLRA implied) case 0x5f: output << "\tCLRB\t"; break; // CLR (CLRB implied) case 0x6f: output << Address_indexed("CLR"); break; // CLR (indexed) @@ -220,25 +220,25 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { // CMP // CMPA - case 0x81: output << AM_immediate_byte("CMPA"); break; // CMP (CMPA, immediate) + case 0x81: output << AM_immediate_byte("CMPA"); break; // CMP (CMPA, immediate) case 0x91: output << Address_direct("CMPA"); break; // CMP (CMPA, direct) case 0xa1: output << Address_indexed("CMPA"); break; // CMP (CMPA, indexed) case 0xb1: output << Address_extended("CMPA"); break; // CMP (CMPA, extended) // CMPB - case 0xc1: output << AM_immediate_byte("CMPB"); break; // CMP (CMPB, immediate) + case 0xc1: output << AM_immediate_byte("CMPB"); break; // CMP (CMPB, immediate) case 0xd1: output << Address_direct("CMPB"); break; // CMP (CMPB, direct) case 0xe1: output << Address_indexed("CMPB"); break; // CMP (CMPB, indexed) case 0xf1: output << Address_extended("CMPB"); break; // CMP (CMPB, extended) // CMPX - case 0x8c: output << AM_immediate_word("CMPX"); break; // CMP (CMPX, immediate) + case 0x8c: output << AM_immediate_word("CMPX"); break; // CMP (CMPX, immediate) case 0x9c: output << Address_direct("CMPX"); break; // CMP (CMPX, direct) case 0xac: output << Address_indexed("CMPX"); break; // CMP (CMPX, indexed) case 0xbc: output << Address_extended("CMPX"); break; // CMP (CMPX, extended) // COM - case 0x03: output << Address_direct("COM"); break; // COM (direct) + case 0x03: output << Address_direct("COM"); break; // COM (direct) case 0x43: output << "\tCOMA\t"; break; // COM (COMA inherent) case 0x53: output << "\tCOMB\t"; break; // COM (COMB inherent) case 0x63: output << Address_indexed("COM"); break; // COM (indexed) @@ -251,7 +251,7 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x19: output << "\tDAA"; break; // DAA (inherent) // DEC - case 0x0a: output << Address_direct("DEC"); break; // DEC (direct) + case 0x0a: output << Address_direct("DEC"); break; // DEC (direct) case 0x4a: output << "\tDECA\t"; break; // DEC (DECA inherent) case 0x5a: output << "\tDECB\t"; break; // DEC (DECB inherent) case 0x6a: output << Address_indexed("DEC"); break; // DEC (indexed) @@ -260,13 +260,13 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { // EOR // EORA - case 0x88: output << AM_immediate_byte("EORA"); break; // EOR (EORA immediate) + case 0x88: output << AM_immediate_byte("EORA"); break; // EOR (EORA immediate) case 0x98: output << Address_direct("EORA"); break; // EOR (EORA direct) case 0xa8: output << Address_indexed("EORA"); break; // EOR (EORA indexed) case 0xb8: output << Address_extended("EORA"); break; // EOR (EORA extended) // EORB - case 0xc8: output << AM_immediate_byte("EORB"); break; // EOR (EORB immediate) + case 0xc8: output << AM_immediate_byte("EORB"); break; // EOR (EORB immediate) case 0xd8: output << Address_direct("EORB"); break; // EOR (EORB direct) case 0xe8: output << Address_indexed("EORB"); break; // EOR (EORB indexed) case 0xf8: output << Address_extended("EORB"); break; // EOR (EORB extended) @@ -275,19 +275,19 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x1e: output << tfr("EXG"); break; // EXG (R1,R2 immediate) // INC - case 0x0c: output << Address_direct("INC"); break; // INC (direct) + case 0x0c: output << Address_direct("INC"); break; // INC (direct) case 0x4c: output << "\tINCA\t";; break; // INC (INCA inherent) case 0x5c: output << "\tINCB\t";; break; // INC (INCB inherent) case 0x6c: output << Address_indexed("INC"); break; // INC (indexed) case 0x7c: output << Address_extended("INC"); break; // INC (extended) // JMP - case 0x0e: output << Address_direct("JMP"); break; // JMP (direct) + case 0x0e: output << Address_direct("JMP"); break; // JMP (direct) case 0x6e: output << Address_indexed("JMP"); break; // JMP (indexed) case 0x7e: output << Address_extended("JMP"); break; // JMP (extended) // JSR - case 0x9d: output << Address_direct("JSR"); break; // JSR (direct) + case 0x9d: output << Address_direct("JSR"); break; // JSR (direct) case 0xad: output << Address_indexed("JSR"); break; // JSR (indexed) case 0xbd: output << Address_extended("JSR"); break; // JSR (extended) @@ -295,31 +295,31 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { // LDA case 0x86: output << AM_immediate_byte("LDA"); break; // LD (LDA immediate) - case 0x96: output << Address_direct("LDA"); break; // LD (LDA direct) + case 0x96: output << Address_direct("LDA"); break; // LD (LDA direct) case 0xa6: output << Address_indexed("LDA"); break; // LD (LDA indexed) case 0xb6: output << Address_extended("LDA"); break; // LD (LDA extended) // LDB case 0xc6: output << AM_immediate_byte("LDB"); break; // LD (LDB immediate) - case 0xd6: output << Address_direct("LDB"); break; // LD (LDB direct) + case 0xd6: output << Address_direct("LDB"); break; // LD (LDB direct) case 0xe6: output << Address_indexed("LDB"); break; // LD (LDB indexed) case 0xf6: output << Address_extended("LDB"); break; // LD (LDB extended) // LDD case 0xcc: output << AM_immediate_word("LDD"); break; // LD (LDD immediate) - case 0xdc: output << Address_direct("LDD"); break; // LD (LDD direct) + case 0xdc: output << Address_direct("LDD"); break; // LD (LDD direct) case 0xec: output << Address_indexed("LDD"); break; // LD (LDD indexed) case 0xfc: output << Address_extended("LDD"); break; // LD (LDD extended) // LDU case 0xce: output << AM_immediate_word("LDU"); break; // LD (LDU immediate) - case 0xde: output << Address_direct("LDU"); break; // LD (LDU direct) + case 0xde: output << Address_direct("LDU"); break; // LD (LDU direct) case 0xee: output << Address_indexed("LDU"); break; // LD (LDU indexed) case 0xfe: output << Address_extended("LDU"); break; // LD (LDU extended) // LDX case 0x8e: output << AM_immediate_word("LDX"); break; // LD (LDX immediate) - case 0x9e: output << Address_direct("LDX"); break; // LD (LDX direct) + case 0x9e: output << Address_direct("LDX"); break; // LD (LDX direct) case 0xae: output << Address_indexed("LDX"); break; // LD (LDX indexed) case 0xbe: output << Address_extended("LDX"); break; // LD (LDX extended) @@ -330,41 +330,41 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x33: output << Address_indexed("LEAU"); break; // LEA (LEAU indexed) // LSR - case 0x04: output << Address_direct("LSR"); break; // LSR (direct) + case 0x04: output << Address_direct("LSR"); break; // LSR (direct) case 0x44: output << "\tLSRA\t"; break; // LSR (LSRA inherent) case 0x54: output << "\tLSRB\t"; break; // LSR (LSRB inherent) case 0x64: output << Address_indexed("LSR"); break; // LSR (indexed) case 0x74: output << Address_extended("LSR"); break; // LSR (extended) // MUL - case 0x3d: output << "\tMUL\t"; break; // MUL (inherent) + case 0x3d: output << "\tMUL\t"; break; // MUL (inherent) // NEG - case 0x00: output << Address_direct("NEG"); break; // NEG (direct) + case 0x00: output << Address_direct("NEG"); break; // NEG (direct) case 0x40: output << "\tNEGA\t"; break; // NEG (NEGA, inherent) case 0x50: output << "\tNEGB\t"; break; // NEG (NEGB, inherent) case 0x60: output << Address_indexed("NEG"); break; // NEG (indexed) case 0x70: output << Address_extended("NEG"); break; // NEG (extended) // NOP - case 0x12: output << "\tNOP\t"; break; // NOP (inherent) + case 0x12: output << "\tNOP\t"; break; // NOP (inherent) // OR // ORA case 0x8a: output << AM_immediate_byte("ORA"); break; // OR (ORA immediate) - case 0x9a: output << Address_direct("ORA"); break; // OR (ORA direct) + case 0x9a: output << Address_direct("ORA"); break; // OR (ORA direct) case 0xaa: output << Address_indexed("ORA"); break; // OR (ORA indexed) case 0xba: output << Address_extended("ORA"); break; // OR (ORA extended) // ORB case 0xca: output << AM_immediate_byte("ORB"); break; // OR (ORB immediate) - case 0xda: output << Address_direct("ORB"); break; // OR (ORB direct) + case 0xda: output << Address_direct("ORB"); break; // OR (ORB direct) case 0xea: output << Address_indexed("ORB"); break; // OR (ORB indexed) case 0xfa: output << Address_extended("ORB"); break; // OR (ORB extended) // ORCC - case 0x1a: output << AM_immediate_byte("ORCC"); break; // OR (ORCC immediate) + case 0x1a: output << AM_immediate_byte("ORCC"); break; // OR (ORCC immediate) // PSH case 0x34: output << pshS(); break; // PSH (PSHS immediate) @@ -375,91 +375,91 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x37: output << pulU(); break; // PUL (PULU immediate) // ROL - case 0x09: output << Address_direct("ROL"); break; // ROL (direct) + case 0x09: output << Address_direct("ROL"); break; // ROL (direct) case 0x49: output << "\tROLA\t"; break; // ROL (ROLA inherent) case 0x59: output << "\tROLB\t"; break; // ROL (ROLB inherent) case 0x69: output << Address_indexed("ROL"); break; // ROL (indexed) case 0x79: output << Address_extended("ROL"); break; // ROL (extended) // ROR - case 0x06: output << Address_direct("ROR"); break; // ROR (direct) + case 0x06: output << Address_direct("ROR"); break; // ROR (direct) case 0x46: output << "\tRORA\t"; break; // ROR (RORA inherent) case 0x56: output << "\tRORB\t"; break; // ROR (RORB inherent) case 0x66: output << Address_indexed("ROR"); break; // ROR (indexed) case 0x76: output << Address_extended("ROR"); break; // ROR (extended) // RTI - case 0x3B: output << "\tRTI\t"; break; // RTI (inherent) + case 0x3B: output << "\tRTI\t"; break; // RTI (inherent) // RTS - case 0x39: output << "\tRTS\t"; break; // RTS (inherent) + case 0x39: output << "\tRTS\t"; break; // RTS (inherent) // SBC // SBCA - case 0x82: output << AM_immediate_byte("SBCA"); break; // SBC (SBCA immediate) + case 0x82: output << AM_immediate_byte("SBCA"); break; // SBC (SBCA immediate) case 0x92: output << Address_direct("SBCA"); break; // SBC (SBCA direct) case 0xa2: output << Address_indexed("SBCA"); break; // SBC (SBCA indexed) case 0xb2: output << Address_extended("SBCA"); break; // SBC (SBCA extended) // SBCB - case 0xc2: output << AM_immediate_byte("SBCB"); break; // SBC (SBCB immediate) + case 0xc2: output << AM_immediate_byte("SBCB"); break; // SBC (SBCB immediate) case 0xd2: output << Address_direct("SBCB"); break; // SBC (SBCB direct) case 0xe2: output << Address_indexed("SBCB"); break; // SBC (SBCB indexed) case 0xf2: output << Address_extended("SBCB"); break; // SBC (SBCB extended) // SEX - case 0x1d: output << "\tSEX\t"; break; // SEX (inherent) + case 0x1d: output << "\tSEX\t"; break; // SEX (inherent) // ST // STA - case 0x97: output << Address_direct("STA"); break; // ST (STA direct) + case 0x97: output << Address_direct("STA"); break; // ST (STA direct) case 0xa7: output << Address_indexed("STA"); break; // ST (STA indexed) case 0xb7: output << Address_extended("STA"); break; // ST (STA extended) // STB - case 0xd7: output << Address_direct("STB"); break; // ST (STB direct) + case 0xd7: output << Address_direct("STB"); break; // ST (STB direct) case 0xe7: output << Address_indexed("STB"); break; // ST (STB indexed) case 0xf7: output << Address_extended("STB"); break; // ST (STB extended) // STD - case 0xdd: output << Address_direct("STD"); break; // ST (STD direct) + case 0xdd: output << Address_direct("STD"); break; // ST (STD direct) case 0xed: output << Address_indexed("STD"); break; // ST (STD indexed) case 0xfd: output << Address_extended("STD"); break; // ST (STD extended) // STU - case 0xdf: output << Address_direct("STU"); break; // ST (STU direct) + case 0xdf: output << Address_direct("STU"); break; // ST (STU direct) case 0xef: output << Address_indexed("STU"); break; // ST (STU indexed) case 0xff: output << Address_extended("STU"); break; // ST (STU extended) // STX - case 0x9f: output << Address_direct("STX"); break; // ST (STX direct) + case 0x9f: output << Address_direct("STX"); break; // ST (STX direct) case 0xaf: output << Address_indexed("STX"); break; // ST (STX indexed) case 0xbf: output << Address_extended("STX"); break; // ST (STX extended) // SUB // SUBA - case 0x80: output << AM_immediate_byte("SUBA"); break; // SUB (SUBA immediate) + case 0x80: output << AM_immediate_byte("SUBA"); break; // SUB (SUBA immediate) case 0x90: output << Address_direct("SUBA"); break; // SUB (SUBA direct) case 0xa0: output << Address_indexed("SUBA"); break; // SUB (SUBA indexed) case 0xb0: output << Address_extended("SUBA"); break; // SUB (SUBA extended) // SUBB - case 0xc0: output << AM_immediate_byte("SUBB"); break; // SUB (SUBB immediate) + case 0xc0: output << AM_immediate_byte("SUBB"); break; // SUB (SUBB immediate) case 0xd0: output << Address_direct("SUBB"); break; // SUB (SUBB direct) case 0xe0: output << Address_indexed("SUBB"); break; // SUB (SUBB indexed) case 0xf0: output << Address_extended("SUBB"); break; // SUB (SUBB extended) // SUBD - case 0x83: output << AM_immediate_word("SUBD"); break; // SUB (SUBD immediate) + case 0x83: output << AM_immediate_word("SUBD"); break; // SUB (SUBD immediate) case 0x93: output << Address_direct("SUBD"); break; // SUB (SUBD direct) case 0xa3: output << Address_indexed("SUBD"); break; // SUB (SUBD indexed) case 0xb3: output << Address_extended("SUBD"); break; // SUB (SUBD extended) // SWI - case 0x3f: output << "\tSWI\t"; break; // SWI (inherent) + case 0x3f: output << "\tSWI\t"; break; // SWI (inherent) // SYNC case 0x13: output << "\tSYNC\t"; break; // SYNC (inherent) @@ -468,7 +468,7 @@ std::string EightBit::Disassembly::disassembleUnprefixed() { case 0x1f: output << tfr("TFR"); break; // TFR (immediate) // TST - case 0x0d: output << Address_direct("TST"); break; // TST (direct) + case 0x0d: output << Address_direct("TST"); break; // TST (direct) case 0x4d: output << "\tTSTA\t"; break; // TST (TSTA inherent) case 0x5d: output << "\tTSTB\t"; break; // TST (TSTB inherent) case 0x6d: output << Address_indexed("TST"); break; // TST (indexed) @@ -516,13 +516,13 @@ std::string EightBit::Disassembly::disassemble10() { // CMP // CMPD - case 0x83: output << AM_immediate_word("CMPD"); break; // CMP (CMPD, immediate) + case 0x83: output << AM_immediate_word("CMPD"); break; // CMP (CMPD, immediate) case 0x93: output << Address_direct("CMPD"); break; // CMP (CMPD, direct) case 0xa3: output << Address_indexed("CMPD"); break; // CMP (CMPD, indexed) case 0xb3: output << Address_extended("CMPD"); break; // CMP (CMPD, extended) // CMPY - case 0x8c: output << AM_immediate_word("CMPY"); break; // CMP (CMPY, immediate) + case 0x8c: output << AM_immediate_word("CMPY"); break; // CMP (CMPY, immediate) case 0x9c: output << Address_direct("CMPY"); break; // CMP (CMPY, direct) case 0xac: output << Address_indexed("CMPY"); break; // CMP (CMPY, indexed) case 0xbc: output << Address_extended("CMPY"); break; // CMP (CMPY, extended) @@ -531,13 +531,13 @@ std::string EightBit::Disassembly::disassemble10() { // LDS case 0xce: output << AM_immediate_word("LDS"); break; // LD (LDS immediate) - case 0xde: output << Address_direct("LDS"); break; // LD (LDS direct) + case 0xde: output << Address_direct("LDS"); break; // LD (LDS direct) case 0xee: output << Address_indexed("LDS"); break; // LD (LDS indexed) case 0xfe: output << Address_extended("LDS"); break; // LD (LDS extended) // LDY case 0x8e: output << AM_immediate_word("LDY"); break; // LD (LDY immediate) - case 0x9e: output << Address_direct("LDY"); break; // LD (LDY direct) + case 0x9e: output << Address_direct("LDY"); break; // LD (LDY direct) case 0xae: output << Address_indexed("LDY"); break; // LD (LDY indexed) case 0xbe: output << Address_extended("LDY"); break; // LD (LDY extended) @@ -560,7 +560,7 @@ std::string EightBit::Disassembly::disassemble10() { case 0x2f: output << branchLong("LBLE"); break; // BLE (LBLE relative) // STS - case 0xdf: output << Address_direct("STS"); break; // ST (STS direct) + case 0xdf: output << Address_direct("STS"); break; // ST (STS direct) case 0xef: output << Address_indexed("STS"); break; // ST (STS indexed) case 0xff: output << Address_extended("STS"); break; // ST (STS extended) @@ -593,13 +593,13 @@ std::string EightBit::Disassembly::disassemble11() { // CMP // CMPU - case 0x83: output << AM_immediate_word("CMPU"); break; // CMP (CMPU, immediate) + case 0x83: output << AM_immediate_word("CMPU"); break; // CMP (CMPU, immediate) case 0x93: output << Address_direct("CMPU"); break; // CMP (CMPU, direct) case 0xa3: output << Address_indexed("CMPU"); break; // CMP (CMPU, indexed) case 0xb3: output << Address_extended("CMPU"); break; // CMP (CMPU, extended) // CMPS - case 0x8c: output << AM_immediate_word("CMPS"); break; // CMP (CMPS, immediate) + case 0x8c: output << AM_immediate_word("CMPS"); break; // CMP (CMPS, immediate) case 0x9c: output << Address_direct("CMPS"); break; // CMP (CMPS, direct) case 0xac: output << Address_indexed("CMPS"); break; // CMP (CMPS, indexed) case 0xbc: output << Address_extended("CMPS"); break; // CMP (CMPS, extended) diff --git a/MC6809/src/MC6809.vcxproj b/MC6809/src/MC6809.vcxproj index 79e36e3..a52e78a 100644 --- a/MC6809/src/MC6809.vcxproj +++ b/MC6809/src/MC6809.vcxproj @@ -21,11 +21,14 @@ + + + Create Create diff --git a/MC6809/src/MC6809.vcxproj.filters b/MC6809/src/MC6809.vcxproj.filters index 9e68e67..b5eeffa 100644 --- a/MC6809/src/MC6809.vcxproj.filters +++ b/MC6809/src/MC6809.vcxproj.filters @@ -20,6 +20,12 @@ Header Files + + Header Files + + + Header Files + @@ -31,5 +37,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/MC6809/src/Profiler.cpp b/MC6809/src/Profiler.cpp new file mode 100644 index 0000000..af46199 --- /dev/null +++ b/MC6809/src/Profiler.cpp @@ -0,0 +1,41 @@ +#include "stdafx.h" +#include "Profiler.h" + +#include "Disassembly.h" + +EightBit::Profiler::Profiler(mc6809& targetProcessor, Disassembly& disassemblerTarget) +: processor(targetProcessor), + disassembler(disassemblerTarget) { + instructionCounts.fill(0); + addressProfiles.fill(0); + addressCounts.fill(0); +} + +void EightBit::Profiler::Generate() { + StartingOutput.fire(); + EmitProfileInformation(); + StartingOutput.fire(); +} + +void EightBit::Profiler::EmitProfileInformation() { + // For each memory address + for (int address = 0; address < 0x10000; ++address) { + // If there are any cycles associated + auto cycles = addressProfiles[address]; + if (cycles > 0) { + // Dump a profile/disassembly line + auto source = disassembler.disassemble(address); + ProfileLineEventArgs event(address, source, cycles); + EmitLine.fire(event); + } + } +} + +void EightBit::Profiler::addInstruction(uint8_t instruction) { + ++instructionCounts[instruction]; +} + +void EightBit::Profiler::addAddress(uint16_t address, int cycles) { + addressCounts[address]++; + addressProfiles[address] += cycles; +} diff --git a/MC6809/test/Board.cpp b/MC6809/test/Board.cpp index 0c3299d..6d2157e 100644 --- a/MC6809/test/Board.cpp +++ b/MC6809/test/Board.cpp @@ -27,6 +27,14 @@ void Board::raisePOWER() { } void Board::lowerPOWER() { + + if (m_configuration.isProfileMode()) { + m_profiler.EmitLine.connect([this](EightBit::ProfileLineEventArgs line) { + std::cout << EightBit::Disassembly::dump_WordValue(line.address()) << " " << line.source() << std::endl; + }); + m_profiler.Generate(); + } + ACIA().lowerPOWER(); CPU().lowerPOWER(); EightBit::Bus::lowerPOWER(); @@ -71,6 +79,15 @@ void Board::initialise() { } }); + if (m_configuration.isProfileMode()) { + m_cpu.ExecutingInstruction.connect([this](EightBit::mc6809& cpu) { + m_profiler.addInstruction(peek(cpu.PC())); + }); + m_cpu.ExecutedInstruction.connect([this](EightBit::mc6809& cpu) { + m_profiler.addAddress(cpu.PC().word, cpu.cycles()); + }); + } + if (m_configuration.isDebugMode()) { // MC6809 disassembly wiring CPU().ExecutingInstruction.connect([this] (EightBit::mc6809& cpu) { diff --git a/MC6809/test/Board.h b/MC6809/test/Board.h index b581054..cc38469 100644 --- a/MC6809/test/Board.h +++ b/MC6809/test/Board.h @@ -11,6 +11,7 @@ #include #include #include +#include class Board : public EightBit::Bus { public: @@ -38,6 +39,7 @@ private: EightBit::mc6809 m_cpu = *this; EightBit::Disassembly m_disassembler = { *this, m_cpu }; + EightBit::Profiler m_profiler = { m_cpu, m_disassembler }; uint64_t m_totalCycleCount = 0UL; int64_t m_frameCycleCount = 0L; diff --git a/MC6809/test/Configuration.h b/MC6809/test/Configuration.h index 2613a4d..4ebed5b 100644 --- a/MC6809/test/Configuration.h +++ b/MC6809/test/Configuration.h @@ -14,6 +14,9 @@ public: bool isDebugMode() const { return m_debugMode; } void setDebugMode(bool value) { m_debugMode = value; } + bool isProfileMode() const { return m_profileMode; } + void setProfileMode(bool value) { m_profileMode = value; } + bool terminatesEarly() const { return m_terminatesEarly; } void setTerminatesEarly(bool value) { m_terminatesEarly = value; } @@ -21,6 +24,7 @@ public: private: bool m_debugMode = false; + bool m_profileMode = false; bool m_terminatesEarly = false; std::string m_romDirectory = "roms\\searle"; }; diff --git a/MC6809/unittest/Board.cpp b/MC6809/unittest/Board.cpp index e93dd67..eac0d9b 100644 --- a/MC6809/unittest/Board.cpp +++ b/MC6809/unittest/Board.cpp @@ -25,20 +25,17 @@ void Board::lowerPOWER() { } void Board::initialise() { - //CPU().ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Debug, this, std::placeholders::_1)); - //CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_Debug, this, std::placeholders::_1)); + CPU().ExecutingInstruction.connect([this](EightBit::mc6809& cpu) { + m_disassembleAt = CPU().PC(); + m_ignoreDisassembly = m_disassembler.ignore(); + }); + + CPU().ExecutedInstruction.connect([this](EightBit::mc6809& cpu) { + if (!m_ignoreDisassembly) + std::cout << m_disassembler.trace(m_disassembleAt) << " " << std::endl; + }); } EightBit::MemoryMapping Board::mapping(uint16_t) { return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; } - -void Board::Cpu_ExecutingInstruction_Debug(EightBit::mc6809&) { - m_disassembleAt = CPU().PC(); - m_ignoreDisassembly = m_disassembler.ignore(); -} - -void Board::Cpu_ExecutedInstruction_Debug(EightBit::mc6809&) { - if (!m_ignoreDisassembly) - std::cout << m_disassembler.trace(m_disassembleAt) << " " << std::endl; -} diff --git a/MC6809/unittest/Board.h b/MC6809/unittest/Board.h index edae038..2e7c3ad 100644 --- a/MC6809/unittest/Board.h +++ b/MC6809/unittest/Board.h @@ -5,19 +5,19 @@ #include #include -class Board : public EightBit::Bus { +class Board final : public EightBit::Bus { public: Board(); EightBit::mc6809& CPU() { return m_cpu; } - virtual void raisePOWER() final; - virtual void lowerPOWER() final; + void raisePOWER() final; + void lowerPOWER() final; protected: - virtual void initialise() final; + void initialise() final; - virtual EightBit::MemoryMapping mapping(uint16_t address) final; + EightBit::MemoryMapping mapping(uint16_t address) final; private: EightBit::Ram m_ram = 0x10000; // 0000 - FFFF, 64K RAM @@ -27,7 +27,4 @@ private: // The m_disassembleAt and m_ignoreDisassembly are used to skip pin events EightBit::register16_t m_disassembleAt = 0x0000; bool m_ignoreDisassembly = false; - - void Cpu_ExecutingInstruction_Debug(EightBit::mc6809&); - void Cpu_ExecutedInstruction_Debug(EightBit::mc6809&); }; diff --git a/MC6850/inc/MC6850.h b/MC6850/inc/MC6850.h index bac5d78..0d77f1c 100644 --- a/MC6850/inc/MC6850.h +++ b/MC6850/inc/MC6850.h @@ -10,42 +10,42 @@ namespace EightBit { public: mc6850(); - // +--------+----------------------------------------------------------------------------------+ - // | | Buffer address | - // | +------------------+------------------+--------------------+-----------------------+ - // | | _ | _ | _ | _ | - // | Data | RS * R/W | RS * R/W | RS * R/W | RS * R/W | - // | Bus | (high)(low) | (high)(high) | (low)(low) | (low)(low) | - // | Line | Transmit | Receive | | | - // | Number | Data | Data | Control | Status | - // | | Register | Register | register | register | - // | +------------------+------------------+--------------------+-----------------------+ - // | | (Write only) + (Read only) + (Write only) | (Read only) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 0 | Data bit 0* | Data bit 0 | Counter divide | Receive data register | - // | | | | select 1 (CR0) | full (RDRF) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 1 | Data bit 1 | Data bit 1 | Counter divide | Transmit data register| - // | | | | select 2 (CR1) | empty (TDRE) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 2 | Data bit 2 | Data bit 2 | Word select 1 | Data carrier detect | - // | | | | (CR2) | (DCD active) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 3 | Data bit 3 | Data bit 3 | Word select 1 | Clear to send | - // | | | | (CR3) | (CTS active) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 4 | Data bit 4 | Data bit 4 | Word select 1 | Framing error | - // | | | | (CR4) | (FE) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 5 | Data bit 5 | Data bit 5 | Transmit control 1 | Receiver overrun | - // | | | | (CR5) | (OVRN) | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 6 | Data bit 6 | Data bit 6 | Transmit control 2 | Parity error (PE) | - // | | | | (CR6) | | - // +--------+------------------+------------------+--------------------+-----------------------+ - // | 7 | Data bit 7*** | Data bit 7** | Receive interrupt | Interrupt request | - // | | | | enable (CR7) | (IRQ active) | - // +--------+------------------+------------------+--------------------+-----------------------+ + // +--------+----------------------------------------------------------------------------------+ + // | | Buffer address | + // | +------------------+------------------+--------------------+-----------------------+ + // | | _ | _ | _ | _ | + // | Data | RS * R/W | RS * R/W | RS * R/W | RS * R/W | + // | Bus | (high)(low) | (high)(high) | (low)(low) | (low)(low) | + // | Line | Transmit | Receive | | | + // | Number | Data | Data | Control | Status | + // | | Register | Register | Register | register | + // | +------------------+------------------+--------------------+-----------------------+ + // | | (Write only) | (Read only) | (Write only) | (Read only) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 0 | Data bit 0* | Data bit 0 | Counter divide | Receive data register | + // | | | | select 1 (CR0) | full (RDRF) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 1 | Data bit 1 | Data bit 1 | Counter divide | Transmit data register| + // | | | | select 2 (CR1) | empty (TDRE) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 2 | Data bit 2 | Data bit 2 | Word select 1 | Data carrier detect | + // | | | | (CR2) | (DCD active) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 3 | Data bit 3 | Data bit 3 | Word select 1 | Clear to send | + // | | | | (CR3) | (CTS active) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 4 | Data bit 4 | Data bit 4 | Word select 1 | Framing error | + // | | | | (CR4) | (FE) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 5 | Data bit 5 | Data bit 5 | Transmit control 1 | Receiver overrun | + // | | | | (CR5) | (OVRN) | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 6 | Data bit 6 | Data bit 6 | Transmit control 2 | Parity error (PE) | + // | | | | (CR6) | | + // +--------+------------------+------------------+--------------------+-----------------------+ + // | 7 | Data bit 7*** | Data bit 7** | Receive interrupt | Interrupt request | + // | | | | enable (CR7) | (IRQ active) | + // +--------+------------------+------------------+--------------------+-----------------------+ // * Leading bit = LSB = Bit 0 // ** Data bit will be zero in 7-bit plus parity modes // *** Data bit is "don't care" in 7-bit plus parity modes @@ -84,7 +84,7 @@ namespace EightBit { // CR5 and CR6 enum TransmitterControl { ReadyLowInterruptDisabled = 0b00, - ReadyLowInterruptEnabled = 0b01, + ReadyLowInterruptEnabled = 0b01, ReadyHighInterruptDisabled = 0b10, ReadyLowInterruptDisabledTransmitBreak = 0b11, }; @@ -284,10 +284,10 @@ namespace EightBit { bool m_statusRead = false; // Control registers - CounterDivideSelect m_counterDivide = One; - WordSelect m_wordSelect = SevenEvenTwo; - TransmitterControl m_transmitControl = ReadyLowInterruptDisabled; - ReceiveControl m_receiveControl = ReceiveInterruptDisable; + CounterDivideSelect m_counterDivide = CounterDivideSelect::One; + WordSelect m_wordSelect = WordSelect::SevenEvenTwo; + TransmitterControl m_transmitControl = TransmitterControl::ReadyLowInterruptDisabled; + ReceiveControl m_receiveControl = ReceiveControl::ReceiveInterruptDisable; // Status registers bool m_statusRDRF = false; diff --git a/MC6850/src/MC6850.cpp b/MC6850/src/MC6850.cpp index fb8b250..3050bfd 100644 Binary files a/MC6850/src/MC6850.cpp and b/MC6850/src/MC6850.cpp differ diff --git a/Z80/inc/Disassembler.h b/Z80/inc/Disassembler.h index f77288b..a29c11d 100644 --- a/Z80/inc/Disassembler.h +++ b/Z80/inc/Disassembler.h @@ -15,7 +15,7 @@ namespace EightBit { static std::string state(Z80& cpu); std::string disassemble(Z80& cpu); - static std::string flag(uint8_t value, int flag, const std::string& represents); + static std::string flag(uint8_t value, int flag, std::string represents); static std::string flags(uint8_t value); static std::string hex(uint8_t value); static std::string hex(uint16_t value); diff --git a/Z80/src/Disassembler.cpp b/Z80/src/Disassembler.cpp index 51cfb95..0a45948 100644 --- a/Z80/src/Disassembler.cpp +++ b/Z80/src/Disassembler.cpp @@ -726,7 +726,7 @@ void EightBit::Disassembler::disassembleOther( } } -std::string EightBit::Disassembler::flag(uint8_t value, int flag, const std::string& represents) { +std::string EightBit::Disassembler::flag(uint8_t value, int flag, const std::string represents) { std::ostringstream output; output << (value & flag ? represents : "-"); return output.str(); diff --git a/inc/Device.h b/inc/Device.h index 7d44dcd..a2564ad 100644 --- a/inc/Device.h +++ b/inc/Device.h @@ -103,7 +103,7 @@ namespace EightBit { virtual ~Device() = default; - [[nodiscard]] bool powered() noexcept { return raised(POWER()); } + [[nodiscard]] bool powered() const noexcept { return raised(POWER()); } DECLARE_PIN_INPUT(POWER)