Add WriteLong to Memory, CPU

This commit is contained in:
scawful
2023-12-10 02:14:30 -05:00
parent 231ef4678a
commit 519f0320ac
6 changed files with 78 additions and 14 deletions

View File

@@ -806,6 +806,7 @@ void CPU::ExecuteInstruction(uint8_t opcode) {
case 0x20: // JSR Absolute
{
operand = Absolute(AccessType::Control);
PB = (operand >> 16);
JSR(operand);
break;
}
@@ -904,7 +905,7 @@ void CPU::ExecuteInstruction(uint8_t opcode) {
case 0xBD: // LDA Absolute Indexed, X
{
operand = AbsoluteIndexedX();
LDA(operand);
LDA(operand, false, false, true);
break;
}
case 0xBF: // LDA Absolute Long Indexed, X
@@ -1321,9 +1322,11 @@ void CPU::ExecuteInstruction(uint8_t opcode) {
STA(operand);
break;
case 0x97: // STA DP Indirect Long Indexed, Y
{
operand = DirectPageIndirectLongIndexedY();
STA(operand);
break;
}
case 0x99: // STA Absolute Indexed, Y
operand = AbsoluteIndexedY();
STA(operand);
@@ -1510,7 +1513,8 @@ void CPU::LogInstructions(uint16_t PC, uint8_t opcode, uint16_t operand,
<< "$" << std::uppercase << std::setw(2) << std::setfill('0')
<< static_cast<int>(PB) << ":" << std::hex << PC;
std::cout << " \033[1;32m"
<< ": 0x" << std::hex << static_cast<int>(opcode) << " ";
<< ": 0x" << std::hex << std::uppercase << std::setw(2)
<< std::setfill('0') << static_cast<int>(opcode) << " ";
std::cout << " \033[1;35m" << opcode_to_mnemonic.at(opcode) << " "
<< "\033[0m";
@@ -1526,7 +1530,53 @@ void CPU::LogInstructions(uint16_t PC, uint8_t opcode, uint16_t operand,
std::cout << std::hex << std::setw(4) << std::setfill('0')
<< static_cast<int>(operand);
}
bool x_indexing, y_indexing;
auto x_indexed_instruction_opcodes = {0x15, 0x16, 0x17, 0x55, 0x56,
0x57, 0xD5, 0xD6, 0xD7, 0xF5,
0xF6, 0xF7, 0xBD};
auto y_indexed_instruction_opcodes = {0x19, 0x97, 0x1D, 0x59, 0x5D, 0x99,
0x9D, 0xB9, 0xD9, 0xDD, 0xF9, 0xFD};
if (std::find(x_indexed_instruction_opcodes.begin(),
x_indexed_instruction_opcodes.end(),
opcode) != x_indexed_instruction_opcodes.end()) {
x_indexing = true;
} else {
x_indexing = false;
}
if (std::find(y_indexed_instruction_opcodes.begin(),
y_indexed_instruction_opcodes.end(),
opcode) != y_indexed_instruction_opcodes.end()) {
y_indexing = true;
} else {
y_indexing = false;
}
if (x_indexing) {
std::cout << ", X";
}
if (y_indexing) {
std::cout << ", Y";
}
}
// Log the registers and flags.
std::cout << std::right;
std::cout << "\033[1;33m"
<< " A:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(A);
std::cout << " X:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(X);
std::cout << " Y:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(Y);
std::cout << " S:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(status);
std::cout << " DB:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(DB);
std::cout << " D:" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(D);
std::cout << std::endl;
}
}
@@ -1548,7 +1598,6 @@ uint8_t CPU::GetInstructionLength(uint8_t opcode) {
case 0xFC: // JSR Absolute Indexed Indirect
case 0xDC: // JMP Absolute Indirect Long
case 0x6B: // RTL
case 0x82: // BRL Relative Long
PC = next_pc_;
return 0;
@@ -1559,7 +1608,7 @@ uint8_t CPU::GetInstructionLength(uint8_t opcode) {
case 0x60: // RTS
PC = last_call_frame_;
return 0;
return 3;
// Branch Instructions (BCC, BCS, BNE, BEQ, etc.)
case 0x90: // BCC near

View File

@@ -160,7 +160,7 @@ class CPU : public Memory, public Loggable, public core::ExperimentFlags {
// Low: First operand byte
//
// LDA addr
uint16_t Absolute(AccessType access_type = AccessType::Data);
uint32_t Absolute(AccessType access_type = AccessType::Data);
// Effective Address:
// The Data Bank Register is concatened with the 16-bit operand
@@ -342,6 +342,9 @@ class CPU : public Memory, public Loggable, public core::ExperimentFlags {
void WriteWord(uint32_t address, uint16_t value) override {
memory.WriteWord(address, value);
}
void WriteLong(uint32_t address, uint32_t value) {
memory.WriteLong(address, value);
}
uint8_t FetchByte() {
uint32_t address = (PB << 16) | PC + 1;
@@ -498,7 +501,8 @@ class CPU : public Memory, public Loggable, public core::ExperimentFlags {
void JSL(uint32_t address);
// LDA: Load accumulator
void LDA(uint16_t address, bool immediate = false, bool direct_page = false);
void LDA(uint16_t address, bool immediate = false, bool direct_page = false,
bool data_bank = false);
// LDX: Load X register
void LDX(uint16_t address, bool immediate = false);

View File

@@ -4,7 +4,7 @@ namespace yaze {
namespace app {
namespace emu {
uint16_t CPU::Absolute(CPU::AccessType access_type) {
uint32_t CPU::Absolute(CPU::AccessType access_type) {
auto operand = FetchWord();
uint32_t bank =
(access_type == CPU::AccessType::Data) ? (DB << 16) : (PB << 16);

View File

@@ -361,7 +361,7 @@ void CPU::JSL(uint32_t address) {
next_pc_ = address; // Set program counter to the new address
}
void CPU::LDA(uint16_t address, bool isImmediate, bool direct_page) {
void CPU::LDA(uint16_t address, bool isImmediate, bool direct_page, bool data_bank) {
uint8_t bank = PB;
if (direct_page) {
bank = 0;
@@ -628,7 +628,9 @@ void CPU::RTL() {
PB = memory.PopByte();
}
void CPU::RTS() { last_call_frame_ = memory.PopWord(); }
void CPU::RTS() {
last_call_frame_ = memory.PopWord();
}
void CPU::SBC(uint32_t value, bool isImmediate) {
uint16_t operand;

View File

@@ -117,6 +117,7 @@ class Memory {
virtual void WriteByte(uint32_t address, uint8_t value) = 0;
virtual void WriteWord(uint32_t address, uint16_t value) = 0;
virtual void WriteLong(uint32_t address, uint32_t value) = 0;
virtual void PushByte(uint8_t value) = 0;
virtual uint8_t PopByte() = 0;
@@ -263,6 +264,12 @@ class MemoryImpl : public Memory, public Loggable {
memory_.at(mapped_address) = value & 0xFF;
memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
}
void WriteLong(uint32_t address, uint32_t value) override {
uint32_t mapped_address = GetMappedAddress(address);
memory_.at(mapped_address) = value & 0xFF;
memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
memory_.at(mapped_address + 2) = (value >> 16) & 0xFF;
}
// Stack operations
void PushByte(uint8_t value) override {
@@ -347,11 +354,11 @@ class MemoryImpl : public Memory, public Loggable {
}
if (bank <= 0x3F) {
if (offset <= 0x1FFF) {
if (address <= 0x1FFF) {
return (0x7E << 16) + offset; // Shadow RAM
} else if (offset <= 0x5FFF) {
} else if (address <= 0x5FFF) {
return (bank << 16) + (offset - 0x2000) + 0x2000; // Hardware Registers
} else if (offset <= 0x7FFF) {
} else if (address <= 0x7FFF) {
return offset - 0x6000 + 0x6000; // Expansion RAM
} else {
// Return lorom mapping

View File

@@ -34,6 +34,7 @@ class MockMemory : public Memory {
MOCK_METHOD2(WriteByte, void(uint32_t address, uint8_t value));
MOCK_METHOD2(WriteWord, void(uint32_t address, uint16_t value));
MOCK_METHOD2(WriteLong, void(uint32_t address, uint32_t value));
MOCK_METHOD1(PushByte, void(uint8_t value));
MOCK_METHOD0(PopByte, uint8_t());
@@ -173,8 +174,9 @@ class MockMemory : public Memory {
return value;
});
ON_CALL(*this, SP()).WillByDefault([this]() { return SP_; });
ON_CALL(*this, SetSP(::testing::_))
.WillByDefault([this](uint16_t value) { SP_ = value; });
ON_CALL(*this, SetSP(::testing::_)).WillByDefault([this](uint16_t value) {
SP_ = value;
});
ON_CALL(*this, ClearMemory()).WillByDefault([this]() {
memory_.resize(64000, 0x00);
});