Refactor STA Instructions
This commit is contained in:
159
src/cpu.cpp
159
src/cpu.cpp
@@ -586,6 +586,21 @@ void CPU::STZ_ToAddress(const uint32_t address, const int base_cycles_8bit, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPU::WriteRegisterToAddress(const uint32_t address, const uint16_t value, const bool isMemoryFlag, const int baseCycles) {
|
||||||
|
if (isMemoryFlag) {
|
||||||
|
WriteByte(address, value & 0xFF);
|
||||||
|
cycles += baseCycles;
|
||||||
|
} else {
|
||||||
|
WriteWord(address, value);
|
||||||
|
cycles += baseCycles + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU::WriteWithDirectPagePenalty(const uint32_t address, const uint16_t value, const bool isMemoryFlag, const int baseCycles) {
|
||||||
|
WriteRegisterToAddress(address, value, isMemoryFlag, baseCycles);
|
||||||
|
if (D & 0xFF) cycles++;
|
||||||
|
}
|
||||||
|
|
||||||
void CPU::ExecuteInstruction() {
|
void CPU::ExecuteInstruction() {
|
||||||
switch (const uint8_t opcode = bus->Read(PC++)) {
|
switch (const uint8_t opcode = bus->Read(PC++)) {
|
||||||
// ADC - Add with Carry
|
// ADC - Add with Carry
|
||||||
@@ -1125,13 +1140,7 @@ void CPU::STA_AbsoluteX() {
|
|||||||
const uint32_t address = base + X;
|
const uint32_t address = base + X;
|
||||||
PC += 3;
|
PC += 3;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteRegisterToAddress(address, A, P & FLAG_M, 5);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 5;
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_AbsoluteY() {
|
void CPU::STA_AbsoluteY() {
|
||||||
@@ -1139,13 +1148,7 @@ void CPU::STA_AbsoluteY() {
|
|||||||
const uint32_t address = base + Y;
|
const uint32_t address = base + Y;
|
||||||
PC += 3;
|
PC += 3;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteRegisterToAddress(address, A, P & FLAG_M, 5);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 5;
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_DirectPage() {
|
void CPU::STA_DirectPage() {
|
||||||
@@ -1153,15 +1156,7 @@ void CPU::STA_DirectPage() {
|
|||||||
const uint32_t address = (D + offset) & 0xFFFF;
|
const uint32_t address = (D + offset) & 0xFFFF;
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteWithDirectPagePenalty(address, A, P & FLAG_M, 3);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 3;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 4;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_DirectPageX() {
|
void CPU::STA_DirectPageX() {
|
||||||
@@ -1169,15 +1164,7 @@ void CPU::STA_DirectPageX() {
|
|||||||
const uint32_t address = (D + offset + X) & 0xFFFF;
|
const uint32_t address = (D + offset + X) & 0xFFFF;
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteWithDirectPagePenalty(address, A, P & FLAG_M, 4);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 4;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 5;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_IndirectDirectPage() {
|
void CPU::STA_IndirectDirectPage() {
|
||||||
@@ -1186,15 +1173,7 @@ void CPU::STA_IndirectDirectPage() {
|
|||||||
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteWithDirectPagePenalty(address, A, P & FLAG_M, 5);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 5;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 6;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_IndirectDirectPageY() {
|
void CPU::STA_IndirectDirectPageY() {
|
||||||
@@ -1204,15 +1183,7 @@ void CPU::STA_IndirectDirectPageY() {
|
|||||||
const uint32_t address = base + Y;
|
const uint32_t address = base + Y;
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteWithDirectPagePenalty(address, A, P & FLAG_M, 6);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 6;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 7;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_DirectPageIndirectX() {
|
void CPU::STA_DirectPageIndirectX() {
|
||||||
@@ -1221,122 +1192,66 @@ void CPU::STA_DirectPageIndirectX() {
|
|||||||
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteWithDirectPagePenalty(address, A, P & FLAG_M, 7);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 6;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 7;
|
|
||||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_Long() {
|
void CPU::STA_Long() {
|
||||||
const uint32_t address = ReadByte(PC + 1) | (ReadByte(PC + 2) << 8) | (ReadByte(PC + 3) << 16);
|
const uint32_t address = ReadByte(PC + 1) |
|
||||||
|
(ReadByte(PC + 2) << 8) |
|
||||||
|
(ReadByte(PC + 3) << 16);
|
||||||
PC += 4;
|
PC += 4;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteRegisterToAddress(address, A, P & FLAG_M, 5);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 5;
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_LongX() {
|
void CPU::STA_LongX() {
|
||||||
const uint32_t base = ReadByte(PC + 1) | (ReadByte(PC + 2) << 8) | (ReadByte(PC + 3) << 16);
|
const uint32_t base = ReadByte(PC + 1) |
|
||||||
|
(ReadByte(PC + 2) << 8) |
|
||||||
|
(ReadByte(PC + 3) << 16);
|
||||||
const uint32_t address = base + X;
|
const uint32_t address = base + X;
|
||||||
PC += 4;
|
PC += 4;
|
||||||
|
|
||||||
if (P & FLAG_M) { // 8-bit mode
|
WriteRegisterToAddress(address, A, P & FLAG_M, 6);
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 6;
|
|
||||||
} else { // 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 7;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_StackRelative() {
|
void CPU::STA_StackRelative() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t address = SP + offset;
|
const uint32_t address = SP + offset;
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
WriteRegisterToAddress(address, A, P & FLAG_M, 4);
|
||||||
// 8-bit mode
|
|
||||||
WriteByte(address, A & 0xFF);
|
|
||||||
cycles += 4;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
WriteWord(address, A);
|
|
||||||
cycles += 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_DirectPageIndirectLong() {
|
void CPU::STA_DirectPageIndirectLong() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t indirect_addr = D + offset;
|
const uint32_t indirect_addr = D + offset;
|
||||||
|
|
||||||
const uint32_t target_address = ReadByte(indirect_addr) |
|
const uint32_t target_address = ReadByte(indirect_addr) |
|
||||||
(ReadByte(indirect_addr + 1) << 8) |
|
(ReadByte(indirect_addr + 1) << 8) |
|
||||||
(ReadByte(indirect_addr + 2) << 16);
|
(ReadByte(indirect_addr + 2) << 16);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
WriteWithDirectPagePenalty(target_address, A, P & FLAG_M, 6);
|
||||||
// 8-bit mode
|
|
||||||
WriteByte(target_address, A & 0xFF);
|
|
||||||
cycles += 6;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
WriteWord(target_address, A);
|
|
||||||
cycles += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_StackRelativeIndirectY() {
|
void CPU::STA_StackRelativeIndirectY() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t indirect_addr = SP + offset;
|
const uint32_t indirect_addr = SP + offset;
|
||||||
|
|
||||||
const uint16_t base_address = ReadWord(indirect_addr);
|
const uint16_t base_address = ReadWord(indirect_addr);
|
||||||
|
|
||||||
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
|
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
|
||||||
const uint32_t target_address = (DB << 16) | (base_address + y_offset);
|
const uint32_t target_address = (DB << 16) | (base_address + y_offset);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
WriteRegisterToAddress(target_address, A, P & FLAG_M, 7);
|
||||||
// 8-bit mode
|
|
||||||
WriteByte(target_address, A & 0xFF);
|
|
||||||
cycles += 7;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
WriteWord(target_address, A);
|
|
||||||
cycles += 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STA_DirectPageIndirectLongY() {
|
void CPU::STA_DirectPageIndirectLongY() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t indirect_addr = D + offset;
|
const uint32_t indirect_addr = D + offset;
|
||||||
|
|
||||||
const uint32_t base_address = ReadByte(indirect_addr) |
|
const uint32_t base_address = ReadByte(indirect_addr) |
|
||||||
(ReadByte(indirect_addr + 1) << 8) |
|
(ReadByte(indirect_addr + 1) << 8) |
|
||||||
(ReadByte(indirect_addr + 2) << 16);
|
(ReadByte(indirect_addr + 2) << 16);
|
||||||
|
|
||||||
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
|
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
|
||||||
const uint32_t target_address = base_address + y_offset;
|
const uint32_t target_address = base_address + y_offset;
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
WriteWithDirectPagePenalty(target_address, A, P & FLAG_M, 6);
|
||||||
// 8-bit mode
|
|
||||||
WriteByte(target_address, A & 0xFF);
|
|
||||||
cycles += 6;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
WriteWord(target_address, A);
|
|
||||||
cycles += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// STX - Store X Register
|
// STX - Store X Register
|
||||||
@@ -1370,8 +1285,8 @@ void CPU::STX_DirectPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU::STX_DirectPageY() {
|
void CPU::STX_DirectPageY() {
|
||||||
uint8_t offset = ReadByte(PC + 1);
|
const uint8_t offset = ReadByte(PC + 1);
|
||||||
uint32_t address = (D + offset + Y) & 0xFFFF;
|
const uint32_t address = (D + offset + Y) & 0xFFFF;
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_X) { // 8-bit mode
|
if (P & FLAG_X) { // 8-bit mode
|
||||||
@@ -1387,7 +1302,7 @@ void CPU::STX_DirectPageY() {
|
|||||||
|
|
||||||
// STY - Store Y Register
|
// STY - Store Y Register
|
||||||
void CPU::STY_Absolute() {
|
void CPU::STY_Absolute() {
|
||||||
uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||||
PC += 3;
|
PC += 3;
|
||||||
|
|
||||||
if (P & FLAG_X) { // 8-bit mode
|
if (P & FLAG_X) { // 8-bit mode
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class CPU {
|
|||||||
// Helper method to check for decimal mode adjustment
|
// Helper method to check for decimal mode adjustment
|
||||||
static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit);
|
static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit);
|
||||||
|
|
||||||
|
// Helpers for LD* Instructions
|
||||||
void LDA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base,
|
void LDA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base,
|
||||||
uint16_t offset);
|
uint16_t offset);
|
||||||
|
|
||||||
@@ -99,6 +100,10 @@ class CPU {
|
|||||||
// General STZ Logic
|
// General STZ Logic
|
||||||
void STZ_ToAddress(uint32_t address, int base_cycles_8bit, int base_cycles_16bit);
|
void STZ_ToAddress(uint32_t address, int base_cycles_8bit, int base_cycles_16bit);
|
||||||
|
|
||||||
|
// ST* Helpers
|
||||||
|
void WriteWithDirectPagePenalty(uint32_t address, uint16_t value, bool isMemoryFlag, int baseCycles);
|
||||||
|
void WriteRegisterToAddress(uint32_t address, uint16_t value, bool isMemoryFlag, int baseCycles);
|
||||||
|
|
||||||
// Helper methods for ASL stuff
|
// Helper methods for ASL stuff
|
||||||
void UpdateASLFlags8(uint8_t original_value, uint8_t result);
|
void UpdateASLFlags8(uint8_t original_value, uint8_t result);
|
||||||
void UpdateASLFlags16(uint16_t original_value, uint16_t result);
|
void UpdateASLFlags16(uint16_t original_value, uint16_t result);
|
||||||
|
|||||||
Reference in New Issue
Block a user