Fixed a missunderstanding of the pbr use

This commit is contained in:
Anonymus Raccoon
2020-03-26 23:54:10 +01:00
parent 80ebfa8064
commit c9a40be3e2
7 changed files with 95 additions and 62 deletions

View File

@@ -9,50 +9,54 @@ namespace ComSquare::CPU
{
uint24_t CPU::_getImmediateAddr8Bits()
{
return this->_registers.pac++;
uint24_t ret = this->_registers.pac;
this->_registers.pc++;
return ret;
}
uint24_t CPU::_getImmediateAddrForA()
{
uint24_t effective = this->_registers.pac++;
uint24_t effective = this->_registers.pac;
this->_registers.pc++;
if (!this->_registers.p.m)
this->_registers.pac++;
this->_registers.pc++;
return effective;
}
uint24_t CPU::_getImmediateAddrForX()
{
uint24_t effective = this->_registers.pac++;
uint24_t effective = this->_registers.pac;
this->_registers.pc++;
if (!this->_registers.p.x_b)
this->_registers.pac++;
this->_registers.pc++;
return effective;
}
uint24_t CPU::_getDirectAddr()
{
uint8_t addr = this->_bus->read(this->_registers.pac++);
uint8_t addr = this->readPC();
return this->_registers.d + addr;
}
uint24_t CPU::_getAbsoluteAddr()
{
uint24_t addr = this->_registers.dbr << 16u;
addr += this->_bus->read(this->_registers.pac++);
addr += this->_bus->read(this->_registers.pac++) << 8u;
addr += this->readPC();
addr += this->readPC() << 8u;
return addr;
}
uint24_t CPU::_getAbsoluteLongAddr()
{
uint24_t addr = this->_bus->read(this->_registers.pac++);
addr += this->_bus->read(this->_registers.pac++) << 8u;
addr += this->_bus->read(this->_registers.pac++) << 16u;
uint24_t addr = this->readPC();
addr += this->readPC() << 8u;
addr += this->readPC() << 16u;
return addr;
}
uint24_t CPU::_getDirectIndirectIndexedYAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
uint24_t base = this->_bus->read(dp);
base += this->_bus->read(dp + 1) << 8u;
base += this->_registers.dbr << 16u;
@@ -63,7 +67,7 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectIndexedYLongAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
uint24_t base = this->_bus->read(dp);
base += this->_bus->read(dp + 1) << 8u;
base += this->_bus->read(dp + 2) << 16u;
@@ -72,7 +76,7 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectIndexedXAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
dp += this->_registers.x;
uint24_t base = this->_bus->read(dp);
base += this->_bus->read(dp + 1) << 8u;
@@ -82,22 +86,22 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndexedByXAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
dp += this->_registers.x;
return dp;
}
uint24_t CPU::_getDirectIndexedByYAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
dp += this->_registers.y;
return dp;
}
uint24_t CPU::_getAbsoluteIndexedByXAddr()
{
uint16_t abs = this->_bus->read(this->_registers.pac++);
abs += this->_bus->read(this->_registers.pac++) << 8u;
uint16_t abs = this->readPC();
abs += this->readPC() << 8u;
uint24_t effective = abs + (this->_registers.dbr << 16u);
if ((effective & 0x80000000u) == (((effective + this->_registers.x) & 0x80000000u)))
this->_hasIndexCrossedPageBoundary = true;
@@ -106,8 +110,8 @@ namespace ComSquare::CPU
uint24_t CPU::_getAbsoluteIndexedByYAddr()
{
uint16_t abs = this->_bus->read(this->_registers.pac++);
abs += this->_bus->read(this->_registers.pac++) << 8u;
uint16_t abs = this->readPC();
abs += this->readPC() << 8u;
uint24_t effective = abs + (this->_registers.dbr << 16u);
if ((effective & 0x80000000u) == (((effective + this->_registers.y) & 0x80000000u)))
this->_hasIndexCrossedPageBoundary = true;
@@ -116,32 +120,32 @@ namespace ComSquare::CPU
uint24_t CPU::_getAbsoluteIndexedByXLongAddr()
{
uint24_t lng = this->_bus->read(this->_registers.pac++);
lng += this->_bus->read(this->_registers.pac++) << 8u;
lng += this->_bus->read(this->_registers.pac++) << 16u;
uint24_t lng = this->readPC();
lng += this->readPC() << 8u;
lng += this->readPC() << 16u;
return lng + this->_registers.x;
}
uint24_t CPU::_getProgramCounterRelativeAddr()
{
uint24_t pc = this->_registers.pac;
int8_t mod = this->_bus->read(this->_registers.pac++);
int8_t mod = this->readPC();
return pc + mod;
}
uint24_t CPU::_getProgramCounterRelativeLongAddr()
{
uint24_t pc = this->_registers.pac;
uint8_t val1 = this->_bus->read(this->_registers.pac++);
uint8_t val2 = this->_bus->read(this->_registers.pac++);
uint8_t val1 = this->readPC();
uint8_t val2 = this->readPC();
int16_t mod = val2 > 0x7F ? (static_cast<char>(val2) * 256 - val1) : (val1 | val2 << 8u);
return pc + mod;
}
uint24_t CPU::_getAbsoluteIndirectAddr()
{
uint16_t abs = this->_bus->read(this->_registers.pac++);
abs += this->_bus->read(this->_registers.pac++) << 8u;
uint16_t abs = this->readPC();
abs += this->readPC() << 8u;
uint24_t effective = this->_bus->read(abs);
effective += this->_bus->read(abs + 1) << 8u;
return effective;
@@ -149,8 +153,8 @@ namespace ComSquare::CPU
uint24_t CPU::_getAbsoluteIndirectIndexedByXAddr()
{
uint24_t abs = this->_bus->read(this->_registers.pac++);
abs += this->_bus->read(this->_registers.pac++) << 8u;
uint24_t abs = this->readPC();
abs += this->readPC() << 8u;
abs += this->_registers.x;
uint24_t effective = this->_bus->read(abs);
effective += this->_bus->read(abs + 1) << 8u;
@@ -159,7 +163,7 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
uint24_t effective = this->_bus->read(dp);
effective += this->_bus->read(dp + 1) << 8u;
effective += this->_registers.dbr << 16u;
@@ -168,7 +172,7 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectLongAddr()
{
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint16_t dp = this->readPC() + this->_registers.d;
uint24_t effective = this->_bus->read(dp);
effective += this->_bus->read(++dp) << 8u;
effective += this->_bus->read(++dp) << 16u;
@@ -177,12 +181,12 @@ namespace ComSquare::CPU
uint24_t CPU::_getStackRelativeAddr()
{
return this->_bus->read(this->_registers.pac++) + this->_registers.s;
return this->readPC() + this->_registers.s;
}
uint24_t CPU::_getStackRelativeIndirectIndexedYAddr()
{
uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s;
uint24_t base = this->readPC() + this->_registers.s;
base += this->_registers.dbr << 16u;
return base + this->_registers.y;
}

View File

@@ -195,12 +195,21 @@ namespace ComSquare::CPU
}
}
uint8_t CPU::readPC()
{
uint8_t ret = this->_bus->read(this->_registers.pac);
this->_registers.pc++;
return ret;
}
unsigned CPU::update()
{
unsigned cycles = 0;
for (int i = 0; i < 0xFF; i++)
cycles += this->_executeInstruction(this->_bus->read(this->_registers.pac++));
for (int i = 0; i < 0xFF; i++) {
cycles += this->_executeInstruction(this->readPC());
this->_registers.pc++;
}
return cycles;
}

View File

@@ -253,6 +253,8 @@ namespace ComSquare::CPU
//! @brief Pop 16 bits of data from the stack.
uint16_t _pop16();
//! @brief Return the data at the program bank concatenated with the program counter. It also increment the program counter (the program bank is not incremented on overflows).
uint8_t readPC();
//! @brief Execute a single instruction.
//! @return The number of CPU cycles that the instruction took.

View File

@@ -259,48 +259,48 @@ namespace ComSquare::CPU
int CPU::BCC(uint24_t valueAddr)
{
if (!this->_registers.p.c)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return !this->_registers.p.c;
}
int CPU::BCS(uint24_t valueAddr)
{
if (this->_registers.p.c)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return this->_registers.p.c;
}
int CPU::BEQ(uint24_t valueAddr)
{
if (this->_registers.p.z)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return this->_registers.p.z;
}
int CPU::BNE(uint24_t valueAddr)
{
if (!this->_registers.p.z)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return !this->_registers.p.z;
}
int CPU::BMI(uint24_t valueAddr)
{
if (this->_registers.p.n)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return this->_registers.p.n;
}
int CPU::BPL(uint24_t valueAddr)
{
if (!this->_registers.p.n)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return !this->_registers.p.n;
}
int CPU::BRA(uint24_t valueAddr)
{
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return true;
}
@@ -309,21 +309,21 @@ namespace ComSquare::CPU
unsigned value = this->_bus->read(valueAddr);
value += this->_bus->read(valueAddr + 1) << 8u;
this->_registers.pac += static_cast<int16_t>(value);
this->_registers.pc += static_cast<int16_t>(value);
return true;
}
int CPU::BVC(uint24_t valueAddr)
{
if (!this->_registers.p.v)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return !this->_registers.p.v;
}
int CPU::BVS(uint24_t valueAddr)
{
if (this->_registers.p.v)
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
this->_registers.pc += static_cast<int8_t>(this->_bus->read(valueAddr));
return this->_registers.p.v;
}

View File

@@ -31,10 +31,7 @@ namespace ComSquare::Debugger
this->_ui.disasembly->verticalHeader()->hide();
this->_ui.disasembly->horizontalHeader()->hide();
this->_ui.disasembly->horizontalHeader()->setStretchLastSection(true);
// uint24_t pc = 0x80800; // The first byte of the ROM //TODO make this work for other rom mapping.
// while (pc < 0x80800 + this->_cartridgeHeader.romSize)
// this->_disassembledInstructions.insert(pc, this->_parseInstruction(pc));
this->disassembledInstructions = this->_disassemble(0x808000, this->_cartridgeHeader.romSize);
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
@@ -59,7 +56,7 @@ namespace ComSquare::Debugger
if (this->_isPaused)
return 0xFF;
if (this->_isStepping)
return this->_executeInstruction(this->_bus->read(this->_registers.pac++));
return this->_executeInstruction(this->readPC());
return CPU::update();
} catch (InvalidOpcode &e) {
if (!this->_isPaused)
@@ -77,7 +74,8 @@ namespace ComSquare::Debugger
this->_isStepping = false;
this->_isPaused = true;
}
this->_ui.logger->append((this->_parseInstruction(this->_registers.pac - 1).toString() + " - " + Utility::to_hex(opcode)).c_str());
uint24_t pc = (this->_registers.pbr << 16u) | (this->_registers.pc - 1u);
this->_ui.logger->append((this->_parseInstruction(pc).toString() + " - " + Utility::to_hex(opcode)).c_str());
unsigned ret = CPU::_executeInstruction(opcode);
this->_updateRegistersPanel();
return ret;
@@ -137,6 +135,19 @@ namespace ComSquare::Debugger
return str;
}
std::vector<DisassembledInstruction> CPUDebug::_disassemble(uint24_t pc, uint24_t length)
{
std::vector<DisassembledInstruction> map;
uint24_t endAddr = pc + length;
while (pc < endAddr) {
DisassembledInstruction instruction = this->_parseInstruction(pc);
map.push_back(instruction);
pc += instruction.size;
}
return map;
}
void CPUDebug::clearHistory()
{
this->_ui.logger->clear();
@@ -220,7 +231,7 @@ namespace ComSquare::Debugger
uint24_t opcode = this->_bus->read(pc++, true);
Instruction instruction = this->_instructions[opcode];
std::string argument = this->_getInstructionParameter(instruction, pc);
return DisassembledInstruction(instruction, argument, opcode);
return DisassembledInstruction(instruction, pc, argument, opcode);
}
std::string CPUDebug::_getInstructionParameter(Instruction &instruction, uint24_t pc)
@@ -260,8 +271,8 @@ namespace ComSquare::Debugger
this->_window->activateWindow();
}
DisassembledInstruction::DisassembledInstruction(const CPU::Instruction &instruction, std::string arg, uint8_t op)
: CPU::Instruction(instruction), argument(std::move(arg)), opcode(op) {}
DisassembledInstruction::DisassembledInstruction(const CPU::Instruction &instruction, uint24_t addr, std::string arg, uint8_t op)
: CPU::Instruction(instruction), address(addr), argument(std::move(arg)), opcode(op) {}
std::string DisassembledInstruction::toString()
{
@@ -278,12 +289,17 @@ int DisassemblyModel::columnCount(const QModelIndex &) const
int DisassemblyModel::rowCount(const QModelIndex &) const
{
return 5;
return this->_cpu.disassembledInstructions.size();
}
QVariant DisassemblyModel::data(const QModelIndex &, int role) const
QVariant DisassemblyModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[index.row()];
switch (index.column()) {
case 0:
return QString(ComSquare::Utility::to_hex(instruction.address).c_str());
}
return QString();
}

View File

@@ -39,10 +39,11 @@ public:
namespace ComSquare::Debugger
{
struct DisassembledInstruction : public CPU::Instruction {
uint24_t address;
std::string argument;
uint8_t opcode;
DisassembledInstruction(const CPU::Instruction &instruction, std::string argument, uint8_t opcode);
DisassembledInstruction(const CPU::Instruction &instruction, uint24_t address, std::string argument, uint8_t opcode);
DisassembledInstruction(const DisassembledInstruction &) = default;
DisassembledInstruction &operator=(const DisassembledInstruction &) = default;
~DisassembledInstruction() = default;
@@ -59,8 +60,6 @@ namespace ComSquare::Debugger
Ui::CPUView _ui;
//! @brief The disassembly viewer's model.
DisassemblyModel _model;
//! @brief The list of disassembled instructions to show on the debugger.
std::map<uint24_t, DisassembledInstruction> _disassembledInstructions;
//! @brief If this is set to true, the execution of the CPU will be paused.
bool _isPaused = true;
//! @brief If this is set to true, the CPU will execute one instruction and pause itself.
@@ -75,6 +74,8 @@ namespace ComSquare::Debugger
std::string _getInstructionParameter(ComSquare::CPU::Instruction &instruction, uint24_t pc);
//! @brief Get a printable string representing the flags.
std::string _getFlagsString();
//! @brief Disassemble part of the memory (using the bus) and parse it to a map of address and disassembled instruction.
std::vector<DisassembledInstruction> _disassemble(uint24_t startAddr, uint24_t size);
//! @brief Update the register's panel (accumulator, stack pointer...)
void _updateRegistersPanel();
@@ -104,7 +105,8 @@ namespace ComSquare::Debugger
void clearHistory();
//! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU.
void disableDebugger();
public:
//! @brief The list of disassembled instructions to show on the debugger.
std::vector<DisassembledInstruction> disassembledInstructions;
//! @brief Update the UI when reseting the CPU.
int RESB(uint24_t) override;
//! @brief Convert a basic CPU to a debugging CPU.

View File

@@ -42,7 +42,7 @@ Test(AddrMode, ImmediateBankChange)
snes.cpu->_registers.pac = 0x00FFFF;
snes.cpu->_registers.p.m = true;
cr_assert_eq(snes.cpu->_getImmediateAddrForA(), 0x00FFFF);
cr_assert_eq(snes.cpu->_registers.pac, 0x010000);
cr_assert_eq(snes.cpu->_registers.pac, 0x000000);
}
Test(AddrMode, Direct)