Don't expose the bus via the CPU any more: if a component needs the bus, it should be prepared to hold a reference to it.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-10-20 20:52:41 +01:00
parent 9b0cc4542f
commit 1b2ddd8843
19 changed files with 131 additions and 103 deletions

View File

@ -5,12 +5,14 @@
#include <sstream> #include <sstream>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <Intel8080.h> #include <Bus.h>
#include "Intel8080.h"
namespace EightBit { namespace EightBit {
class Disassembler { class Disassembler {
public: public:
Disassembler() noexcept; Disassembler(Bus& bus) noexcept;
static std::string state(Intel8080& cpu); static std::string state(Intel8080& cpu);
std::string disassemble(Intel8080& cpu); std::string disassemble(Intel8080& cpu);
@ -25,6 +27,7 @@ namespace EightBit {
private: private:
mutable boost::format m_formatter; mutable boost::format m_formatter;
Bus& m_bus;
void disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc); void disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc);
@ -43,5 +46,7 @@ namespace EightBit {
static std::string cc(int flag); static std::string cc(int flag);
static std::string alu(int which); static std::string alu(int which);
static std::string alu2(int which); static std::string alu2(int which);
Bus& BUS() { return m_bus; }
}; };
} }

View File

@ -8,7 +8,8 @@
#include <iomanip> #include <iomanip>
#include <bitset> #include <bitset>
EightBit::Disassembler::Disassembler() noexcept { EightBit::Disassembler::Disassembler(Bus& bus) noexcept
: m_bus(bus) {
// Disable exceptions where too many format arguments are available // Disable exceptions where too many format arguments are available
m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
} }
@ -168,8 +169,7 @@ std::string EightBit::Disassembler::disassemble(Intel8080& cpu) {
void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc) { void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080& cpu, uint16_t pc) {
auto& bus = cpu.BUS(); auto opcode = BUS().peek(pc);
auto opcode = bus.peek(pc);
output << hex(opcode); output << hex(opcode);
@ -180,11 +180,11 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080&
auto p = (y & 0b110) >> 1; auto p = (y & 0b110) >> 1;
auto q = (y & 1); auto q = (y & 1);
auto immediate = bus.peek(pc + 1); auto immediate = BUS().peek(pc + 1);
auto absolute = cpu.peekWord(pc + 1).word; auto absolute = cpu.peekWord(pc + 1).word;
auto displacement = (int8_t)immediate; auto displacement = (int8_t)immediate;
auto relative = pc + displacement + 2; auto relative = pc + displacement + 2;
auto indexedImmediate = bus.peek(pc + 1); auto indexedImmediate = BUS().peek(pc + 1);
auto dumpCount = 0; auto dumpCount = 0;
@ -196,7 +196,7 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080&
x, y, z, p, q); x, y, z, p, q);
for (int i = 0; i < dumpCount; ++i) for (int i = 0; i < dumpCount; ++i)
output << hex(bus.peek(pc + i + 1)); output << hex(BUS().peek(pc + i + 1));
output << '\t'; output << '\t';
m_formatter.parse(specification); m_formatter.parse(specification);

View File

@ -6,7 +6,8 @@
Board::Board(const Configuration& configuration) Board::Board(const Configuration& configuration)
: m_configuration(configuration), : m_configuration(configuration),
m_cpu(EightBit::Intel8080(*this, m_ports)) { m_cpu(EightBit::Intel8080(*this, m_ports)),
m_disassembler(*this) {
} }
void Board::initialise() { void Board::initialise() {

View File

@ -157,7 +157,7 @@ void Fuse::TestRunner::checkMemory() {
for (int i = 0; i < bytes.size(); ++i) { for (int i = 0; i < bytes.size(); ++i) {
auto expected = bytes[i]; auto expected = bytes[i];
uint16_t address = memoryDatum.address + i; uint16_t address = memoryDatum.address + i;
auto actual = m_cpu.BUS().peek(address); auto actual = peek(address);
if (expected != actual) { if (expected != actual) {
m_failed = true; m_failed = true;
if (first) { if (first) {

View File

@ -5,6 +5,8 @@
#include <sstream> #include <sstream>
#include <boost/format.hpp> #include <boost/format.hpp>
#include "GameBoyBus.h"
namespace EightBit { namespace EightBit {
namespace GameBoy { namespace GameBoy {
@ -13,7 +15,7 @@ namespace EightBit {
class Disassembler { class Disassembler {
public: public:
Disassembler() noexcept; Disassembler(Bus& bus) noexcept;
static std::string state(LR35902& cpu); static std::string state(LR35902& cpu);
std::string disassemble(LR35902& cpu); std::string disassemble(LR35902& cpu);
@ -36,6 +38,8 @@ namespace EightBit {
Unused, // Unused! Unused, // Unused!
}; };
Bus& m_bus;
mutable boost::format m_formatter; mutable boost::format m_formatter;
bool m_prefixCB = false; bool m_prefixCB = false;
@ -65,6 +69,8 @@ namespace EightBit {
std::string R(int r) const; std::string R(int r) const;
static std::string cc(int flag); static std::string cc(int flag);
static std::string alu(int which); static std::string alu(int which);
Bus& BUS() { return m_bus; }
}; };
} }
} }

View File

@ -4,6 +4,7 @@
#include <cstdint> #include <cstdint>
#include "Disassembler.h" #include "Disassembler.h"
#include "GameBoyBus.h"
namespace EightBit { namespace EightBit {
namespace GameBoy { namespace GameBoy {
@ -12,7 +13,7 @@ namespace EightBit {
class Profiler { class Profiler {
public: public:
Profiler(LR35902& cpu); Profiler(Bus& bus, LR35902& cpu);
void add(uint16_t address, uint8_t instruction); void add(uint16_t address, uint8_t instruction);
@ -21,8 +22,8 @@ namespace EightBit {
private: private:
std::array<uint64_t, 0x100> m_instructions; std::array<uint64_t, 0x100> m_instructions;
std::array<uint64_t, 0x10000> m_addresses; std::array<uint64_t, 0x10000> m_addresses;
Bus& m_bus;
LR35902& m_cpu; LR35902& m_cpu;
Disassembler m_disassembler; Disassembler m_disassembler;
void dumpInstructionProfiles() const; void dumpInstructionProfiles() const;

View File

@ -9,7 +9,8 @@
#include "LR35902.h" #include "LR35902.h"
#include "IoRegisters.h" #include "IoRegisters.h"
EightBit::GameBoy::Disassembler::Disassembler() noexcept { EightBit::GameBoy::Disassembler::Disassembler(Bus& bus) noexcept
: m_bus(bus) {
// Disable exceptions where too many format arguments are available // Disable exceptions where too many format arguments are available
m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
} }
@ -148,8 +149,7 @@ std::string EightBit::GameBoy::Disassembler::disassemble(LR35902& cpu) {
void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR35902& cpu, uint16_t pc) { void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR35902& cpu, uint16_t pc) {
auto& bus = cpu.BUS(); auto opcode = BUS().peek(pc);
auto opcode = bus.peek(pc);
// hex opcode // hex opcode
output << hex(opcode); output << hex(opcode);
@ -161,11 +161,11 @@ void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR
auto p = (y & 0b110) >> 1; auto p = (y & 0b110) >> 1;
auto q = (y & 1); auto q = (y & 1);
auto immediate = bus.peek(pc + 1); auto immediate = BUS().peek(pc + 1);
auto absolute = cpu.peekWord(pc + 1).word; auto absolute = cpu.peekWord(pc + 1).word;
auto displacement = (int8_t)immediate; auto displacement = (int8_t)immediate;
auto relative = pc + displacement + 2; auto relative = pc + displacement + 2;
auto indexedImmediate = bus.peek(pc + 1); auto indexedImmediate = BUS().peek(pc + 1);
auto dumpCount = 0; auto dumpCount = 0;
auto ioRegister = IoRegister::Unused; auto ioRegister = IoRegister::Unused;
@ -184,7 +184,7 @@ void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR
x, y, z, p, q); x, y, z, p, q);
for (int i = 0; i < dumpCount; ++i) for (int i = 0; i < dumpCount; ++i)
output << hex(bus.peek(pc + i + 1)); output << hex(BUS().peek(pc + i + 1));
output << '\t'; output << '\t';
m_formatter.parse(specification); m_formatter.parse(specification);

View File

@ -2,8 +2,10 @@
#include "Profiler.h" #include "Profiler.h"
#include "LR35902.h" #include "LR35902.h"
EightBit::GameBoy::Profiler::Profiler(LR35902& cpu) EightBit::GameBoy::Profiler::Profiler(Bus& bus, LR35902& cpu)
: m_cpu(cpu) { : m_bus(bus),
m_cpu(cpu),
m_disassembler(bus) {
std::fill(m_instructions.begin(), m_instructions.end(), 0); std::fill(m_instructions.begin(), m_instructions.end(), 0);
std::fill(m_addresses.begin(), m_addresses.end(), 0); std::fill(m_addresses.begin(), m_addresses.end(), 0);
} }

View File

@ -9,15 +9,16 @@
namespace EightBit { namespace EightBit {
class Disassembly { class Disassembly {
public: public:
Disassembly(MOS6502& processor, const Symbols& symbols); Disassembly(Bus& bus, MOS6502& processor, const Symbols& symbols);
std::string disassemble(uint16_t current) const; std::string disassemble(uint16_t current);
static std::string dump_Flags(uint8_t value); static std::string dump_Flags(uint8_t value);
static std::string dump_ByteValue(uint8_t value); static std::string dump_ByteValue(uint8_t value);
static std::string dump_WordValue(uint16_t value); static std::string dump_WordValue(uint16_t value);
private: private:
Bus& m_bus;
MOS6502& processor; MOS6502& processor;
const Symbols& symbols; const Symbols& symbols;
@ -27,119 +28,119 @@ namespace EightBit {
return "\t" + instruction; return "\t" + instruction;
} }
std::string disassemble_Absolute(const std::string& instruction) const { std::string disassemble_Absolute(const std::string& instruction) {
return AM_Absolute_dump() + "\t" + instruction + " " + AM_Absolute(); return AM_Absolute_dump() + "\t" + instruction + " " + AM_Absolute();
} }
std::string disassemble_Indirect(const std::string& instruction) const { std::string disassemble_Indirect(const std::string& instruction) {
return AM_Absolute_dump() + "\t" + instruction + " (" + AM_Absolute() + ")"; return AM_Absolute_dump() + "\t" + instruction + " (" + AM_Absolute() + ")";
} }
std::string disassemble_Relative(const std::string& instruction, uint16_t address) const { std::string disassemble_Relative(const std::string& instruction, uint16_t address) {
return AM_Immediate_dump() + "\t" + instruction + " $" + dump_WordValue(address); return AM_Immediate_dump() + "\t" + instruction + " $" + dump_WordValue(address);
} }
std::string disassemble_Immediate(const std::string& instruction) const { std::string disassemble_Immediate(const std::string& instruction) {
return AM_Immediate_dump() + "\t" + instruction + " " + AM_Immediate(); return AM_Immediate_dump() + "\t" + instruction + " " + AM_Immediate();
} }
std::string disassemble_AM_00(int bbb, const std::string& instruction) const { std::string disassemble_AM_00(int bbb, const std::string& instruction) {
return AM_00_dump(bbb) + "\t" + instruction + " " + AM_00(bbb); return AM_00_dump(bbb) + "\t" + instruction + " " + AM_00(bbb);
} }
std::string disassemble_AM_01(int bbb, const std::string& instruction) const { std::string disassemble_AM_01(int bbb, const std::string& instruction) {
return AM_01_dump(bbb) + "\t" + instruction + " " + AM_01(bbb); return AM_01_dump(bbb) + "\t" + instruction + " " + AM_01(bbb);
} }
std::string disassemble_AM_10(int bbb, const std::string& instruction) const { std::string disassemble_AM_10(int bbb, const std::string& instruction) {
return AM_10_dump(bbb) + "\t" + instruction + " " + AM_10(bbb); return AM_10_dump(bbb) + "\t" + instruction + " " + AM_10(bbb);
} }
std::string disassemble_AM_10_x(int bbb, const std::string& instruction) const { std::string disassemble_AM_10_x(int bbb, const std::string& instruction) {
return AM_10_x_dump(bbb) + "\t" + instruction + " " + AM_10_x(bbb); return AM_10_x_dump(bbb) + "\t" + instruction + " " + AM_10_x(bbb);
} }
std::string disassemble_AM_11(int bbb, const std::string& instruction) const { std::string disassemble_AM_11(int bbb, const std::string& instruction) {
return AM_11_dump(bbb) + "\t" + instruction + " " + AM_11(bbb); return AM_11_dump(bbb) + "\t" + instruction + " " + AM_11(bbb);
} }
std::string disassemble_AM_11_x(int bbb, const std::string& instruction) const { std::string disassemble_AM_11_x(int bbb, const std::string& instruction) {
return AM_11_x_dump(bbb) + "\t" + instruction + " " + AM_11_x(bbb); return AM_11_x_dump(bbb) + "\t" + instruction + " " + AM_11_x(bbb);
} }
std::string AM_Immediate_dump() const { std::string AM_Immediate_dump() {
return dump_Byte(m_address + 1); return dump_Byte(m_address + 1);
} }
std::string AM_Immediate() const { std::string AM_Immediate() {
return "#$" + AM_Immediate_dump(); return "#$" + AM_Immediate_dump();
} }
std::string AM_Absolute_dump() const { std::string AM_Absolute_dump() {
return dump_DByte(m_address + 1); return dump_DByte(m_address + 1);
} }
std::string AM_Absolute() const { std::string AM_Absolute() {
return "$" + dump_Word(m_address + 1); return "$" + dump_Word(m_address + 1);
} }
std::string AM_ZeroPage_dump() const { std::string AM_ZeroPage_dump() {
return dump_Byte(m_address + 1); return dump_Byte(m_address + 1);
} }
std::string AM_ZeroPage() const { std::string AM_ZeroPage() {
return "$" + dump_Byte(m_address + 1); return "$" + dump_Byte(m_address + 1);
} }
std::string AM_ZeroPageX_dump() const { std::string AM_ZeroPageX_dump() {
return AM_ZeroPage_dump(); return AM_ZeroPage_dump();
} }
std::string AM_ZeroPageX() const { std::string AM_ZeroPageX() {
return AM_ZeroPage() + ",X"; return AM_ZeroPage() + ",X";
} }
std::string AM_ZeroPageY_dump() const { std::string AM_ZeroPageY_dump() {
return AM_ZeroPage_dump(); return AM_ZeroPage_dump();
} }
std::string AM_ZeroPageY() const { std::string AM_ZeroPageY() {
return AM_ZeroPage() + ",Y"; return AM_ZeroPage() + ",Y";
} }
std::string AM_AbsoluteX_dump() const { std::string AM_AbsoluteX_dump() {
return AM_Absolute_dump(); return AM_Absolute_dump();
} }
std::string AM_AbsoluteX() const { std::string AM_AbsoluteX() {
return AM_Absolute() + ",X"; return AM_Absolute() + ",X";
} }
std::string AM_AbsoluteY_dump() const { std::string AM_AbsoluteY_dump() {
return AM_Absolute_dump(); return AM_Absolute_dump();
} }
std::string AM_AbsoluteY() const { std::string AM_AbsoluteY() {
return AM_Absolute() + ",Y"; return AM_Absolute() + ",Y";
} }
std::string AM_IndexedIndirectX_dump() const { std::string AM_IndexedIndirectX_dump() {
return AM_ZeroPage_dump(); return AM_ZeroPage_dump();
} }
std::string AM_IndexedIndirectX() const { std::string AM_IndexedIndirectX() {
return "($" + dump_Byte(m_address + 1) + ",X)"; return "($" + dump_Byte(m_address + 1) + ",X)";
} }
std::string AM_IndirectIndexedY_dump() const { std::string AM_IndirectIndexedY_dump() {
return AM_ZeroPage_dump(); return AM_ZeroPage_dump();
} }
std::string AM_IndirectIndexedY() const { std::string AM_IndirectIndexedY() {
return "($" + dump_Byte(m_address + 1) + "),Y"; return "($" + dump_Byte(m_address + 1) + "),Y";
} }
std::string AM_00_dump(int bbb) const { std::string AM_00_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate_dump(); return AM_Immediate_dump();
@ -160,7 +161,7 @@ namespace EightBit {
} }
} }
std::string AM_00(int bbb) const { std::string AM_00(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -181,7 +182,7 @@ namespace EightBit {
} }
} }
std::string AM_01_dump(int bbb) const { std::string AM_01_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX_dump(); return AM_IndexedIndirectX_dump();
@ -204,7 +205,7 @@ namespace EightBit {
} }
} }
std::string AM_01(int bbb) const { std::string AM_01(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX(); return AM_IndexedIndirectX();
@ -227,7 +228,7 @@ namespace EightBit {
} }
} }
std::string AM_10_dump(int bbb) const { std::string AM_10_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate_dump(); return AM_Immediate_dump();
@ -249,7 +250,7 @@ namespace EightBit {
} }
} }
std::string AM_10(int bbb) const { std::string AM_10(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -271,7 +272,7 @@ namespace EightBit {
} }
} }
std::string AM_10_x_dump(int bbb) const { std::string AM_10_x_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate_dump(); return AM_Immediate_dump();
@ -293,7 +294,7 @@ namespace EightBit {
} }
} }
std::string AM_10_x(int bbb) const { std::string AM_10_x(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -315,7 +316,7 @@ namespace EightBit {
} }
} }
std::string AM_11_dump(int bbb) const { std::string AM_11_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX_dump(); return AM_IndexedIndirectX_dump();
@ -338,7 +339,7 @@ namespace EightBit {
} }
} }
std::string AM_11_x_dump(int bbb) const { std::string AM_11_x_dump(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX_dump(); return AM_IndexedIndirectX_dump();
@ -361,7 +362,7 @@ namespace EightBit {
} }
} }
std::string AM_11(int bbb) const { std::string AM_11(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX(); return AM_IndexedIndirectX();
@ -384,7 +385,7 @@ namespace EightBit {
} }
} }
std::string AM_11_x(int bbb) const { std::string AM_11_x(int bbb) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX(); return AM_IndexedIndirectX();
@ -409,16 +410,18 @@ namespace EightBit {
static void dump(std::ostream& out, int value, int width); static void dump(std::ostream& out, int value, int width);
uint8_t getByte(uint16_t address) const; uint8_t getByte(uint16_t address);
uint16_t getWord(uint16_t address) const; uint16_t getWord(uint16_t address);
std::string dump_Byte(uint16_t address) const; std::string dump_Byte(uint16_t address);
std::string dump_DByte(uint16_t address) const; std::string dump_DByte(uint16_t address);
std::string dump_Word(uint16_t address) const; std::string dump_Word(uint16_t address);
std::string convertAddress(uint16_t address) const; std::string convertAddress(uint16_t address) const;
std::string convertAddress(uint8_t address) const; std::string convertAddress(uint8_t address) const;
std::string convertConstant(uint16_t constant) const; std::string convertConstant(uint16_t constant);
std::string convertConstant(uint8_t constant) const; std::string convertConstant(uint8_t constant) const;
Bus& BUS() { return m_bus; }
}; };
} }

View File

@ -27,7 +27,7 @@ namespace EightBit {
std::map<std::string, uint64_t> scopeCycles; std::map<std::string, uint64_t> scopeCycles;
MOS6502& processor; MOS6502& processor;
const Disassembly& disassembler; Disassembly& disassembler;
const Symbols& symbols; const Symbols& symbols;
Profiler(MOS6502& processor, Disassembly& disassembler, Symbols& symbols); Profiler(MOS6502& processor, Disassembly& disassembler, Symbols& symbols);

View File

@ -7,8 +7,9 @@
using namespace std::placeholders; using namespace std::placeholders;
EightBit::Disassembly::Disassembly(MOS6502& targetProcessor, const Symbols& targetSymbols) EightBit::Disassembly::Disassembly(Bus& bus, MOS6502& targetProcessor, const Symbols& targetSymbols)
: processor(targetProcessor), : m_bus(bus),
processor(targetProcessor),
symbols(targetSymbols) { symbols(targetSymbols) {
} }
@ -41,19 +42,17 @@ std::string EightBit::Disassembly::dump_WordValue(uint16_t value) {
return output.str(); return output.str();
} }
std::string EightBit::Disassembly::disassemble(uint16_t current) const { std::string EightBit::Disassembly::disassemble(uint16_t current) {
m_address = current; m_address = current;
std::ostringstream output; std::ostringstream output;
auto& bus = processor.BUS(); auto cell = BUS().peek(current);
auto cell = bus.peek(current);
output << dump_ByteValue(cell) << " "; output << dump_ByteValue(cell) << " ";
auto byte = bus.peek(current + 1); auto byte = BUS().peek(current + 1);
uint16_t relative = processor.PC().word + 2 + (int8_t)byte; uint16_t relative = processor.PC().word + 2 + (int8_t)byte;
auto aaa = (cell & 0b11100000) >> 5; auto aaa = (cell & 0b11100000) >> 5;
@ -468,25 +467,25 @@ std::string EightBit::Disassembly::disassemble(uint16_t current) const {
//// ////
uint8_t EightBit::Disassembly::getByte(uint16_t address) const { uint8_t EightBit::Disassembly::getByte(uint16_t address) {
return processor.BUS().peek(address); return BUS().peek(address);
} }
uint16_t EightBit::Disassembly::getWord(uint16_t address) const { uint16_t EightBit::Disassembly::getWord(uint16_t address) {
return processor.peekWord(address).word; return processor.peekWord(address).word;
} }
//// ////
std::string EightBit::Disassembly::dump_Byte(uint16_t address) const { std::string EightBit::Disassembly::dump_Byte(uint16_t address) {
return dump_ByteValue(getByte(address)); return dump_ByteValue(getByte(address));
} }
std::string EightBit::Disassembly::dump_DByte(uint16_t address) const { std::string EightBit::Disassembly::dump_DByte(uint16_t address) {
return dump_Byte(address) + " " + dump_Byte(address + 1); return dump_Byte(address) + " " + dump_Byte(address + 1);
} }
std::string EightBit::Disassembly::dump_Word(uint16_t address) const { std::string EightBit::Disassembly::dump_Word(uint16_t address) {
return dump_WordValue(getWord(address)); return dump_WordValue(getWord(address));
} }
@ -510,7 +509,7 @@ std::string EightBit::Disassembly::convertAddress(uint8_t address) const {
return output.str(); return output.str();
} }
std::string EightBit::Disassembly::convertConstant(uint16_t constant) const { std::string EightBit::Disassembly::convertConstant(uint16_t constant) {
auto label = symbols.getConstants().find(constant); auto label = symbols.getConstants().find(constant);
if (label != symbols.getConstants().end()) if (label != symbols.getConstants().end())
return label->second; return label->second;

View File

@ -10,7 +10,7 @@
Board::Board(const Configuration& configuration) Board::Board(const Configuration& configuration)
: m_configuration(configuration), : m_configuration(configuration),
m_cpu(EightBit::MOS6502(*this)), m_cpu(EightBit::MOS6502(*this)),
m_disassembler(m_cpu, m_symbols), m_disassembler(*this, m_cpu, m_symbols),
m_profiler(m_cpu, m_disassembler, m_symbols) {} m_profiler(m_cpu, m_disassembler, m_symbols) {}
void Board::initialise() { void Board::initialise() {
@ -74,12 +74,12 @@ void Board::Cpu_ExecutingInstruction_Profile(const EightBit::MOS6502& cpu) {
void Board::Cpu_ExecutedInstruction_StopLoop(EightBit::MOS6502& cpu) { void Board::Cpu_ExecutedInstruction_StopLoop(EightBit::MOS6502& cpu) {
auto pc = cpu.PC().word; auto pc = cpu.PC().word;
if (m_oldPC == pc) { if (m_oldPC != pc) {
m_oldPC = pc;
} else {
CPU().powerOff(); CPU().powerOff();
auto test = peek(0x0200); auto test = peek(0x0200);
std::cout << std::endl << "** Test=" << std::hex << (int)test; std::cout << std::endl << "** Test=" << std::hex << (int)test;
} else {
m_oldPC = pc;
} }
} }

View File

@ -3,12 +3,14 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <Bus.h>
#include "mc6809.h" #include "mc6809.h"
namespace EightBit { namespace EightBit {
class Disassembly final { class Disassembly final {
public: public:
Disassembly(mc6809& processor); Disassembly(Bus& bus, mc6809& processor);
bool ignore(); bool ignore();
@ -17,6 +19,7 @@ namespace EightBit {
std::string trace(); std::string trace();
private: private:
Bus& m_bus;
mc6809& m_cpu; mc6809& m_cpu;
mutable uint16_t m_address = 0xffff; mutable uint16_t m_address = 0xffff;
@ -80,5 +83,7 @@ namespace EightBit {
std::string pshU(); std::string pshU();
std::string pulX(std::string mnemomic, std::string upon); std::string pulX(std::string mnemomic, std::string upon);
std::string pshX(std::string mnemomic, std::string upon); std::string pshX(std::string mnemomic, std::string upon);
Bus& BUS() { return m_bus; }
}; };
} }

View File

@ -8,8 +8,9 @@
using namespace std::placeholders; using namespace std::placeholders;
EightBit::Disassembly::Disassembly(mc6809& targetProcessor) EightBit::Disassembly::Disassembly(Bus& bus, mc6809& targetProcessor)
: m_cpu(targetProcessor) { : m_bus(bus),
m_cpu(targetProcessor) {
} }
std::string EightBit::Disassembly::dump_Flags(uint8_t value) { std::string EightBit::Disassembly::dump_Flags(uint8_t value) {
@ -878,7 +879,7 @@ std::string EightBit::Disassembly::tfr(std::string mnemomic) {
//// ////
uint8_t EightBit::Disassembly::getByte(uint16_t address) { uint8_t EightBit::Disassembly::getByte(uint16_t address) {
return CPU().BUS().peek(address); return BUS().peek(address);
} }
uint16_t EightBit::Disassembly::getWord(uint16_t address) { uint16_t EightBit::Disassembly::getWord(uint16_t address) {

View File

@ -4,7 +4,7 @@
Board::Board(const Configuration& configuration) Board::Board(const Configuration& configuration)
: m_configuration(configuration), : m_configuration(configuration),
m_cpu(EightBit::mc6809(*this)), m_cpu(EightBit::mc6809(*this)),
m_disassembler(m_cpu) { m_disassembler(*this, m_cpu) {
std::vector<uint8_t> content(m_unused2000.size()); std::vector<uint8_t> content(m_unused2000.size());
std::fill(content.begin(), content.end(), 0xff); std::fill(content.begin(), content.end(), 0xff);
m_unused2000.load(content); m_unused2000.load(content);

View File

@ -2,14 +2,15 @@
#include <string> #include <string>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <Bus.h>
namespace EightBit { namespace EightBit {
class Z80; class Z80;
class Disassembler { class Disassembler final {
public: public:
Disassembler() noexcept; Disassembler(Bus& bus) noexcept;
static std::string state(Z80& cpu); static std::string state(Z80& cpu);
std::string disassemble(Z80& cpu); std::string disassemble(Z80& cpu);
@ -29,6 +30,7 @@ namespace EightBit {
bool m_prefixDD = false; bool m_prefixDD = false;
bool m_prefixED = false; bool m_prefixED = false;
bool m_prefixFD = false; bool m_prefixFD = false;
Bus& m_bus;
void disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc); void disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc);
@ -64,5 +66,7 @@ namespace EightBit {
std::string R(int r) const; std::string R(int r) const;
static std::string cc(int flag); static std::string cc(int flag);
static std::string alu(int which); static std::string alu(int which);
Bus& BUS() { return m_bus; }
}; };
} }

View File

@ -10,7 +10,8 @@
#include "Z80.h" #include "Z80.h"
EightBit::Disassembler::Disassembler() noexcept { EightBit::Disassembler::Disassembler(Bus& bus) noexcept
: m_bus(bus) {
// Disable exceptions where too many format arguments are available // Disable exceptions where too many format arguments are available
m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
} }
@ -180,8 +181,7 @@ std::string EightBit::Disassembler::disassemble(Z80& cpu) {
void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc) { void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc) {
auto& bus = cpu.BUS(); auto opcode = BUS().peek(pc);
auto opcode = bus.peek(pc);
const auto& decoded = cpu.getDecodedOpcode(opcode); const auto& decoded = cpu.getDecodedOpcode(opcode);
@ -192,11 +192,11 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u
auto p = decoded.p; auto p = decoded.p;
auto q = decoded.q; auto q = decoded.q;
auto immediate = bus.peek(pc + 1); auto immediate = BUS().peek(pc + 1);
auto absolute = cpu.peekWord(pc + 1).word; auto absolute = cpu.peekWord(pc + 1).word;
auto displacement = (int8_t)immediate; auto displacement = (int8_t)immediate;
auto relative = pc + displacement + 2; auto relative = pc + displacement + 2;
auto indexedImmediate = bus.peek(pc + 1); auto indexedImmediate = BUS().peek(pc + 1);
auto dumpCount = 0; auto dumpCount = 0;
@ -221,7 +221,7 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u
x, y, z, p, q); x, y, z, p, q);
for (int i = 0; i < dumpCount; ++i) for (int i = 0; i < dumpCount; ++i)
output << hex(bus.peek(pc + i + 1)); output << hex(BUS().peek(pc + i + 1));
auto outputFormatSpecification = !m_prefixDD; auto outputFormatSpecification = !m_prefixDD;
if (m_prefixDD) { if (m_prefixDD) {

View File

@ -6,6 +6,7 @@
Board::Board(const Configuration& configuration) Board::Board(const Configuration& configuration)
: m_configuration(configuration), : m_configuration(configuration),
m_cpu(EightBit::Z80(*this, m_ports)), m_cpu(EightBit::Z80(*this, m_ports)),
m_disassembler(*this),
m_profiler(m_cpu, m_disassembler) { m_profiler(m_cpu, m_disassembler) {
} }

View File

@ -15,8 +15,6 @@ namespace EightBit {
// x: sign extend this b-bit number to r // x: sign extend this b-bit number to r
static int8_t signExtend(int b, uint8_t x); static int8_t signExtend(int b, uint8_t x);
Bus& BUS() { return m_bus; }
register16_t& PC() { return m_pc; } register16_t& PC() { return m_pc; }
PinLevel& RESET() { return m_resetLine; } PinLevel& RESET() { return m_resetLine; }
@ -40,6 +38,8 @@ namespace EightBit {
Processor(Bus& memory); Processor(Bus& memory);
virtual ~Processor() = default; virtual ~Processor() = default;
Bus& BUS() { return m_bus; }
bool halted() { return lowered(HALT()); } bool halted() { return lowered(HALT()); }
void halt() { --PC(); lower(HALT()); } void halt() { --PC(); lower(HALT()); }
void proceed() { ++PC(); raise(HALT()); } void proceed() { ++PC(); raise(HALT()); }