mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-23 00:29:47 +00:00
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:
parent
9b0cc4542f
commit
1b2ddd8843
@ -5,12 +5,14 @@
|
||||
#include <sstream>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <Intel8080.h>
|
||||
#include <Bus.h>
|
||||
|
||||
#include "Intel8080.h"
|
||||
|
||||
namespace EightBit {
|
||||
class Disassembler {
|
||||
public:
|
||||
Disassembler() noexcept;
|
||||
Disassembler(Bus& bus) noexcept;
|
||||
|
||||
static std::string state(Intel8080& cpu);
|
||||
std::string disassemble(Intel8080& cpu);
|
||||
@ -25,6 +27,7 @@ namespace EightBit {
|
||||
|
||||
private:
|
||||
mutable boost::format m_formatter;
|
||||
Bus& m_bus;
|
||||
|
||||
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 alu(int which);
|
||||
static std::string alu2(int which);
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
};
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
#include <iomanip>
|
||||
#include <bitset>
|
||||
|
||||
EightBit::Disassembler::Disassembler() noexcept {
|
||||
EightBit::Disassembler::Disassembler(Bus& bus) noexcept
|
||||
: m_bus(bus) {
|
||||
// Disable exceptions where too many format arguments are available
|
||||
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) {
|
||||
|
||||
auto& bus = cpu.BUS();
|
||||
auto opcode = bus.peek(pc);
|
||||
auto opcode = BUS().peek(pc);
|
||||
|
||||
output << hex(opcode);
|
||||
|
||||
@ -180,11 +180,11 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080&
|
||||
auto p = (y & 0b110) >> 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 displacement = (int8_t)immediate;
|
||||
auto relative = pc + displacement + 2;
|
||||
auto indexedImmediate = bus.peek(pc + 1);
|
||||
auto indexedImmediate = BUS().peek(pc + 1);
|
||||
|
||||
auto dumpCount = 0;
|
||||
|
||||
@ -196,7 +196,7 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Intel8080&
|
||||
x, y, z, p, q);
|
||||
|
||||
for (int i = 0; i < dumpCount; ++i)
|
||||
output << hex(bus.peek(pc + i + 1));
|
||||
output << hex(BUS().peek(pc + i + 1));
|
||||
|
||||
output << '\t';
|
||||
m_formatter.parse(specification);
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
Board::Board(const 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() {
|
||||
|
@ -157,7 +157,7 @@ void Fuse::TestRunner::checkMemory() {
|
||||
for (int i = 0; i < bytes.size(); ++i) {
|
||||
auto expected = bytes[i];
|
||||
uint16_t address = memoryDatum.address + i;
|
||||
auto actual = m_cpu.BUS().peek(address);
|
||||
auto actual = peek(address);
|
||||
if (expected != actual) {
|
||||
m_failed = true;
|
||||
if (first) {
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <sstream>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "GameBoyBus.h"
|
||||
|
||||
namespace EightBit {
|
||||
|
||||
namespace GameBoy {
|
||||
@ -13,7 +15,7 @@ namespace EightBit {
|
||||
|
||||
class Disassembler {
|
||||
public:
|
||||
Disassembler() noexcept;
|
||||
Disassembler(Bus& bus) noexcept;
|
||||
|
||||
static std::string state(LR35902& cpu);
|
||||
std::string disassemble(LR35902& cpu);
|
||||
@ -36,6 +38,8 @@ namespace EightBit {
|
||||
Unused, // Unused!
|
||||
};
|
||||
|
||||
Bus& m_bus;
|
||||
|
||||
mutable boost::format m_formatter;
|
||||
bool m_prefixCB = false;
|
||||
|
||||
@ -65,6 +69,8 @@ namespace EightBit {
|
||||
std::string R(int r) const;
|
||||
static std::string cc(int flag);
|
||||
static std::string alu(int which);
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
};
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "Disassembler.h"
|
||||
#include "GameBoyBus.h"
|
||||
|
||||
namespace EightBit {
|
||||
namespace GameBoy {
|
||||
@ -12,7 +13,7 @@ namespace EightBit {
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
Profiler(LR35902& cpu);
|
||||
Profiler(Bus& bus, LR35902& cpu);
|
||||
|
||||
void add(uint16_t address, uint8_t instruction);
|
||||
|
||||
@ -21,8 +22,8 @@ namespace EightBit {
|
||||
private:
|
||||
std::array<uint64_t, 0x100> m_instructions;
|
||||
std::array<uint64_t, 0x10000> m_addresses;
|
||||
Bus& m_bus;
|
||||
LR35902& m_cpu;
|
||||
|
||||
Disassembler m_disassembler;
|
||||
|
||||
void dumpInstructionProfiles() const;
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include "LR35902.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
|
||||
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) {
|
||||
|
||||
auto& bus = cpu.BUS();
|
||||
auto opcode = bus.peek(pc);
|
||||
auto opcode = BUS().peek(pc);
|
||||
|
||||
// hex opcode
|
||||
output << hex(opcode);
|
||||
@ -161,11 +161,11 @@ void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR
|
||||
auto p = (y & 0b110) >> 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 displacement = (int8_t)immediate;
|
||||
auto relative = pc + displacement + 2;
|
||||
auto indexedImmediate = bus.peek(pc + 1);
|
||||
auto indexedImmediate = BUS().peek(pc + 1);
|
||||
|
||||
auto dumpCount = 0;
|
||||
auto ioRegister = IoRegister::Unused;
|
||||
@ -184,7 +184,7 @@ void EightBit::GameBoy::Disassembler::disassemble(std::ostringstream& output, LR
|
||||
x, y, z, p, q);
|
||||
|
||||
for (int i = 0; i < dumpCount; ++i)
|
||||
output << hex(bus.peek(pc + i + 1));
|
||||
output << hex(BUS().peek(pc + i + 1));
|
||||
|
||||
output << '\t';
|
||||
m_formatter.parse(specification);
|
||||
|
@ -2,8 +2,10 @@
|
||||
#include "Profiler.h"
|
||||
#include "LR35902.h"
|
||||
|
||||
EightBit::GameBoy::Profiler::Profiler(LR35902& cpu)
|
||||
: m_cpu(cpu) {
|
||||
EightBit::GameBoy::Profiler::Profiler(Bus& bus, LR35902& cpu)
|
||||
: m_bus(bus),
|
||||
m_cpu(cpu),
|
||||
m_disassembler(bus) {
|
||||
std::fill(m_instructions.begin(), m_instructions.end(), 0);
|
||||
std::fill(m_addresses.begin(), m_addresses.end(), 0);
|
||||
}
|
||||
|
@ -9,15 +9,16 @@
|
||||
namespace EightBit {
|
||||
class Disassembly {
|
||||
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_ByteValue(uint8_t value);
|
||||
static std::string dump_WordValue(uint16_t value);
|
||||
|
||||
private:
|
||||
Bus& m_bus;
|
||||
MOS6502& processor;
|
||||
const Symbols& symbols;
|
||||
|
||||
@ -27,119 +28,119 @@ namespace EightBit {
|
||||
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();
|
||||
}
|
||||
|
||||
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() + ")";
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::string AM_Immediate_dump() const {
|
||||
std::string AM_Immediate_dump() {
|
||||
return dump_Byte(m_address + 1);
|
||||
}
|
||||
|
||||
std::string AM_Immediate() const {
|
||||
std::string AM_Immediate() {
|
||||
return "#$" + AM_Immediate_dump();
|
||||
}
|
||||
|
||||
std::string AM_Absolute_dump() const {
|
||||
std::string AM_Absolute_dump() {
|
||||
return dump_DByte(m_address + 1);
|
||||
}
|
||||
|
||||
std::string AM_Absolute() const {
|
||||
std::string AM_Absolute() {
|
||||
return "$" + dump_Word(m_address + 1);
|
||||
}
|
||||
|
||||
std::string AM_ZeroPage_dump() const {
|
||||
std::string AM_ZeroPage_dump() {
|
||||
return dump_Byte(m_address + 1);
|
||||
}
|
||||
|
||||
std::string AM_ZeroPage() const {
|
||||
std::string AM_ZeroPage() {
|
||||
return "$" + dump_Byte(m_address + 1);
|
||||
}
|
||||
|
||||
std::string AM_ZeroPageX_dump() const {
|
||||
std::string AM_ZeroPageX_dump() {
|
||||
return AM_ZeroPage_dump();
|
||||
}
|
||||
|
||||
std::string AM_ZeroPageX() const {
|
||||
std::string AM_ZeroPageX() {
|
||||
return AM_ZeroPage() + ",X";
|
||||
}
|
||||
|
||||
std::string AM_ZeroPageY_dump() const {
|
||||
std::string AM_ZeroPageY_dump() {
|
||||
return AM_ZeroPage_dump();
|
||||
}
|
||||
|
||||
std::string AM_ZeroPageY() const {
|
||||
std::string AM_ZeroPageY() {
|
||||
return AM_ZeroPage() + ",Y";
|
||||
}
|
||||
|
||||
std::string AM_AbsoluteX_dump() const {
|
||||
std::string AM_AbsoluteX_dump() {
|
||||
return AM_Absolute_dump();
|
||||
}
|
||||
|
||||
std::string AM_AbsoluteX() const {
|
||||
std::string AM_AbsoluteX() {
|
||||
return AM_Absolute() + ",X";
|
||||
}
|
||||
|
||||
std::string AM_AbsoluteY_dump() const {
|
||||
std::string AM_AbsoluteY_dump() {
|
||||
return AM_Absolute_dump();
|
||||
}
|
||||
|
||||
std::string AM_AbsoluteY() const {
|
||||
std::string AM_AbsoluteY() {
|
||||
return AM_Absolute() + ",Y";
|
||||
}
|
||||
|
||||
std::string AM_IndexedIndirectX_dump() const {
|
||||
std::string AM_IndexedIndirectX_dump() {
|
||||
return AM_ZeroPage_dump();
|
||||
}
|
||||
|
||||
std::string AM_IndexedIndirectX() const {
|
||||
std::string AM_IndexedIndirectX() {
|
||||
return "($" + dump_Byte(m_address + 1) + ",X)";
|
||||
}
|
||||
|
||||
std::string AM_IndirectIndexedY_dump() const {
|
||||
std::string AM_IndirectIndexedY_dump() {
|
||||
return AM_ZeroPage_dump();
|
||||
}
|
||||
|
||||
std::string AM_IndirectIndexedY() const {
|
||||
std::string AM_IndirectIndexedY() {
|
||||
return "($" + dump_Byte(m_address + 1) + "),Y";
|
||||
}
|
||||
|
||||
std::string AM_00_dump(int bbb) const {
|
||||
std::string AM_00_dump(int bbb) {
|
||||
switch (bbb) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
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) {
|
||||
case 0b000:
|
||||
return AM_IndexedIndirectX();
|
||||
@ -409,16 +410,18 @@ namespace EightBit {
|
||||
|
||||
static void dump(std::ostream& out, int value, int width);
|
||||
|
||||
uint8_t getByte(uint16_t address) const;
|
||||
uint16_t getWord(uint16_t address) const;
|
||||
uint8_t getByte(uint16_t address);
|
||||
uint16_t getWord(uint16_t address);
|
||||
|
||||
std::string dump_Byte(uint16_t address) const;
|
||||
std::string dump_DByte(uint16_t address) const;
|
||||
std::string dump_Word(uint16_t address) const;
|
||||
std::string dump_Byte(uint16_t address);
|
||||
std::string dump_DByte(uint16_t address);
|
||||
std::string dump_Word(uint16_t address);
|
||||
|
||||
std::string convertAddress(uint16_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;
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
};
|
||||
}
|
@ -27,7 +27,7 @@ namespace EightBit {
|
||||
std::map<std::string, uint64_t> scopeCycles;
|
||||
|
||||
MOS6502& processor;
|
||||
const Disassembly& disassembler;
|
||||
Disassembly& disassembler;
|
||||
const Symbols& symbols;
|
||||
|
||||
Profiler(MOS6502& processor, Disassembly& disassembler, Symbols& symbols);
|
||||
|
@ -7,8 +7,9 @@
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
EightBit::Disassembly::Disassembly(MOS6502& targetProcessor, const Symbols& targetSymbols)
|
||||
: processor(targetProcessor),
|
||||
EightBit::Disassembly::Disassembly(Bus& bus, MOS6502& targetProcessor, const Symbols& targetSymbols)
|
||||
: m_bus(bus),
|
||||
processor(targetProcessor),
|
||||
symbols(targetSymbols) {
|
||||
}
|
||||
|
||||
@ -41,19 +42,17 @@ std::string EightBit::Disassembly::dump_WordValue(uint16_t value) {
|
||||
return output.str();
|
||||
}
|
||||
|
||||
std::string EightBit::Disassembly::disassemble(uint16_t current) const {
|
||||
std::string EightBit::Disassembly::disassemble(uint16_t current) {
|
||||
|
||||
m_address = current;
|
||||
|
||||
std::ostringstream output;
|
||||
|
||||
auto& bus = processor.BUS();
|
||||
|
||||
auto cell = bus.peek(current);
|
||||
auto cell = BUS().peek(current);
|
||||
|
||||
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;
|
||||
|
||||
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 {
|
||||
return processor.BUS().peek(address);
|
||||
uint8_t EightBit::Disassembly::getByte(uint16_t 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;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
std::string EightBit::Disassembly::dump_Byte(uint16_t address) const {
|
||||
std::string EightBit::Disassembly::dump_Byte(uint16_t 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);
|
||||
}
|
||||
|
||||
std::string EightBit::Disassembly::dump_Word(uint16_t address) const {
|
||||
std::string EightBit::Disassembly::dump_Word(uint16_t address) {
|
||||
return dump_WordValue(getWord(address));
|
||||
}
|
||||
|
||||
@ -510,7 +509,7 @@ std::string EightBit::Disassembly::convertAddress(uint8_t address) const {
|
||||
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);
|
||||
if (label != symbols.getConstants().end())
|
||||
return label->second;
|
||||
|
@ -10,7 +10,7 @@
|
||||
Board::Board(const Configuration& configuration)
|
||||
: m_configuration(configuration),
|
||||
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) {}
|
||||
|
||||
void Board::initialise() {
|
||||
@ -74,12 +74,12 @@ void Board::Cpu_ExecutingInstruction_Profile(const EightBit::MOS6502& cpu) {
|
||||
void Board::Cpu_ExecutedInstruction_StopLoop(EightBit::MOS6502& cpu) {
|
||||
|
||||
auto pc = cpu.PC().word;
|
||||
if (m_oldPC == pc) {
|
||||
if (m_oldPC != pc) {
|
||||
m_oldPC = pc;
|
||||
} else {
|
||||
CPU().powerOff();
|
||||
auto test = peek(0x0200);
|
||||
std::cout << std::endl << "** Test=" << std::hex << (int)test;
|
||||
} else {
|
||||
m_oldPC = pc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,14 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <Bus.h>
|
||||
|
||||
#include "mc6809.h"
|
||||
|
||||
namespace EightBit {
|
||||
class Disassembly final {
|
||||
public:
|
||||
Disassembly(mc6809& processor);
|
||||
Disassembly(Bus& bus, mc6809& processor);
|
||||
|
||||
bool ignore();
|
||||
|
||||
@ -17,6 +19,7 @@ namespace EightBit {
|
||||
std::string trace();
|
||||
|
||||
private:
|
||||
Bus& m_bus;
|
||||
mc6809& m_cpu;
|
||||
|
||||
mutable uint16_t m_address = 0xffff;
|
||||
@ -80,5 +83,7 @@ namespace EightBit {
|
||||
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; }
|
||||
};
|
||||
}
|
@ -8,8 +8,9 @@
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
EightBit::Disassembly::Disassembly(mc6809& targetProcessor)
|
||||
: m_cpu(targetProcessor) {
|
||||
EightBit::Disassembly::Disassembly(Bus& bus, mc6809& targetProcessor)
|
||||
: m_bus(bus),
|
||||
m_cpu(targetProcessor) {
|
||||
}
|
||||
|
||||
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) {
|
||||
return CPU().BUS().peek(address);
|
||||
return BUS().peek(address);
|
||||
}
|
||||
|
||||
uint16_t EightBit::Disassembly::getWord(uint16_t address) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
Board::Board(const Configuration& configuration)
|
||||
: m_configuration(configuration),
|
||||
m_cpu(EightBit::mc6809(*this)),
|
||||
m_disassembler(m_cpu) {
|
||||
m_disassembler(*this, m_cpu) {
|
||||
std::vector<uint8_t> content(m_unused2000.size());
|
||||
std::fill(content.begin(), content.end(), 0xff);
|
||||
m_unused2000.load(content);
|
||||
|
@ -2,14 +2,15 @@
|
||||
|
||||
#include <string>
|
||||
#include <boost/format.hpp>
|
||||
#include <Bus.h>
|
||||
|
||||
namespace EightBit {
|
||||
|
||||
class Z80;
|
||||
|
||||
class Disassembler {
|
||||
class Disassembler final {
|
||||
public:
|
||||
Disassembler() noexcept;
|
||||
Disassembler(Bus& bus) noexcept;
|
||||
|
||||
static std::string state(Z80& cpu);
|
||||
std::string disassemble(Z80& cpu);
|
||||
@ -29,6 +30,7 @@ namespace EightBit {
|
||||
bool m_prefixDD = false;
|
||||
bool m_prefixED = false;
|
||||
bool m_prefixFD = false;
|
||||
Bus& m_bus;
|
||||
|
||||
void disassemble(std::ostringstream& output, Z80& cpu, uint16_t pc);
|
||||
|
||||
@ -64,5 +66,7 @@ namespace EightBit {
|
||||
std::string R(int r) const;
|
||||
static std::string cc(int flag);
|
||||
static std::string alu(int which);
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
};
|
||||
}
|
@ -10,7 +10,8 @@
|
||||
|
||||
#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
|
||||
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) {
|
||||
|
||||
auto& bus = cpu.BUS();
|
||||
auto opcode = bus.peek(pc);
|
||||
auto opcode = BUS().peek(pc);
|
||||
|
||||
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 q = decoded.q;
|
||||
|
||||
auto immediate = bus.peek(pc + 1);
|
||||
auto immediate = BUS().peek(pc + 1);
|
||||
auto absolute = cpu.peekWord(pc + 1).word;
|
||||
auto displacement = (int8_t)immediate;
|
||||
auto relative = pc + displacement + 2;
|
||||
auto indexedImmediate = bus.peek(pc + 1);
|
||||
auto indexedImmediate = BUS().peek(pc + 1);
|
||||
|
||||
auto dumpCount = 0;
|
||||
|
||||
@ -221,7 +221,7 @@ void EightBit::Disassembler::disassemble(std::ostringstream& output, Z80& cpu, u
|
||||
x, y, z, p, q);
|
||||
|
||||
for (int i = 0; i < dumpCount; ++i)
|
||||
output << hex(bus.peek(pc + i + 1));
|
||||
output << hex(BUS().peek(pc + i + 1));
|
||||
|
||||
auto outputFormatSpecification = !m_prefixDD;
|
||||
if (m_prefixDD) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
Board::Board(const Configuration& configuration)
|
||||
: m_configuration(configuration),
|
||||
m_cpu(EightBit::Z80(*this, m_ports)),
|
||||
m_disassembler(*this),
|
||||
m_profiler(m_cpu, m_disassembler) {
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,6 @@ namespace EightBit {
|
||||
// x: sign extend this b-bit number to r
|
||||
static int8_t signExtend(int b, uint8_t x);
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
|
||||
register16_t& PC() { return m_pc; }
|
||||
|
||||
PinLevel& RESET() { return m_resetLine; }
|
||||
@ -40,6 +38,8 @@ namespace EightBit {
|
||||
Processor(Bus& memory);
|
||||
virtual ~Processor() = default;
|
||||
|
||||
Bus& BUS() { return m_bus; }
|
||||
|
||||
bool halted() { return lowered(HALT()); }
|
||||
void halt() { --PC(); lower(HALT()); }
|
||||
void proceed() { ++PC(); raise(HALT()); }
|
||||
|
Loading…
Reference in New Issue
Block a user