mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-03-17 16:29:59 +00:00
Merge branch 'master' of https://github.com/MoleskiCoder/EightBit into master
This commit is contained in:
commit
502c554e84
@ -3,19 +3,20 @@
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <Device.h>
|
||||
|
||||
#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> 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> gameController(int which) const;
|
||||
int mappedController(const SDL_JoystickID which) const;
|
||||
|
||||
int chooseControllerIndex(int who) const;
|
||||
std::shared_ptr<GameController> chooseController(int who) const;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Gaming {
|
||||
class SDLWrapper final {
|
||||
public:
|
||||
|
@ -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<GameController> 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();
|
||||
|
@ -40,7 +40,7 @@ namespace EightBit {
|
||||
Signal<EventArgs> 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;
|
||||
|
@ -32,15 +32,15 @@ namespace EightBit {
|
||||
Signal<MOS6502> 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<register16_t, uint8_t> Address_AbsoluteX();
|
||||
std::pair<register16_t, uint8_t> Address_AbsoluteY();
|
||||
register16_t Address_IndexedIndirectX();
|
||||
std::pair<register16_t, uint8_t> 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<register16_t, uint8_t> Address_AbsoluteX();
|
||||
[[nodiscard]] std::pair<register16_t, uint8_t> Address_AbsoluteY();
|
||||
[[nodiscard]] register16_t Address_IndexedIndirectX();
|
||||
[[nodiscard]] std::pair<register16_t, uint8_t> 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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
22
MC6809/inc/ProfileLineEventArgs.h
Normal file
22
MC6809/inc/ProfileLineEventArgs.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
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; }
|
||||
};
|
||||
}
|
41
MC6809/inc/Profiler.h
Normal file
41
MC6809/inc/Profiler.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
#include <EventArgs.h>
|
||||
#include <Signal.h>
|
||||
|
||||
#include "ProfileLineEventArgs.h"
|
||||
|
||||
namespace EightBit {
|
||||
|
||||
class Disassembly;
|
||||
class mc6809;
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
std::array<uint64_t, 0x100> instructionCounts;
|
||||
std::array<uint64_t, 0x10000> addressProfiles;
|
||||
std::array<uint64_t, 0x10000> addressCounts;
|
||||
|
||||
mc6809& processor;
|
||||
Disassembly& disassembler;
|
||||
|
||||
Profiler(mc6809& processor, Disassembly& disassembler);
|
||||
|
||||
Signal<EventArgs> StartingOutput;
|
||||
Signal<EventArgs> FinishedOutput;
|
||||
|
||||
Signal<ProfileLineEventArgs> EmitLine;
|
||||
|
||||
void addInstruction(uint8_t instruction);
|
||||
void addAddress(uint16_t address, int cycles);
|
||||
|
||||
void Generate();
|
||||
|
||||
private:
|
||||
void EmitProfileInformation();
|
||||
};
|
||||
}
|
@ -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)
|
||||
|
@ -21,11 +21,14 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\inc\Disassembly.h" />
|
||||
<ClInclude Include="..\inc\mc6809.h" />
|
||||
<ClInclude Include="..\inc\ProfileLineEventArgs.h" />
|
||||
<ClInclude Include="..\inc\Profiler.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Disassembly.cpp" />
|
||||
<ClCompile Include="mc6809.cpp" />
|
||||
<ClCompile Include="Profiler.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
|
@ -20,6 +20,12 @@
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\ProfileLineEventArgs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Profiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@ -31,5 +37,8 @@
|
||||
<ClCompile Include="Disassembly.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Profiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
41
MC6809/src/Profiler.cpp
Normal file
41
MC6809/src/Profiler.cpp
Normal file
@ -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;
|
||||
}
|
@ -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) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <Disassembly.h>
|
||||
#include <MC6850.h>
|
||||
#include <UnusedMemory.h>
|
||||
#include <Profiler.h>
|
||||
|
||||
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;
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -5,19 +5,19 @@
|
||||
#include <mc6809.h>
|
||||
#include <Disassembly.h>
|
||||
|
||||
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&);
|
||||
};
|
||||
|
@ -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;
|
||||
|
Binary file not shown.
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user