More refactoring of functions
This commit is contained in:
203
src/cpu.cpp
203
src/cpu.cpp
@@ -201,6 +201,22 @@ uint16_t CPU::AdjustDecimal(const uint16_t binary_result, const bool is_16bit) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPU::LDA_Mem(const uint32_t address, const int base_cycles, const bool addDPExtraCycle = false, const bool addPageCrossCycle = false, const uint16_t base = 0, const uint16_t offset = 0) {
|
||||||
|
if (P & FLAG_M) {
|
||||||
|
const uint8_t value = ReadByte(address);
|
||||||
|
A = (A & 0xFF00) | value;
|
||||||
|
UpdateNZ8(value);
|
||||||
|
cycles += base_cycles;
|
||||||
|
} else {
|
||||||
|
A = ReadWord(address);
|
||||||
|
UpdateNZ16(A);
|
||||||
|
cycles += base_cycles + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addDPExtraCycle && (D & 0xFF)) cycles++;
|
||||||
|
if (addPageCrossCycle && ((base & 0xFF00) != ((base + offset) & 0xFF00))) cycles++;
|
||||||
|
}
|
||||||
|
|
||||||
void CPU::UpdateASLFlags8(const uint8_t original_value, const uint8_t result) {
|
void CPU::UpdateASLFlags8(const uint8_t original_value, const uint8_t result) {
|
||||||
if (original_value & 0x80) {
|
if (original_value & 0x80) {
|
||||||
P |= FLAG_C;
|
P |= FLAG_C;
|
||||||
@@ -922,215 +938,70 @@ void CPU::LDA_Absolute() {
|
|||||||
const uint16_t address = ReadWord(PC);
|
const uint16_t address = ReadWord(PC);
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(address, 4);
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 4;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_AbsoluteX() {
|
void CPU::LDA_AbsoluteX() {
|
||||||
const uint16_t base_address = ReadWord(PC);
|
const uint16_t base = ReadWord(PC);
|
||||||
PC += 2;
|
PC += 2;
|
||||||
const uint32_t address = base_address + X;
|
|
||||||
|
|
||||||
// Page boundary crossing adds a cycle in some cases
|
LDA_Mem(base + X, 4, false, true, base, X);
|
||||||
if ((base_address & 0xFF00) != (address & 0xFF00)) {
|
|
||||||
cycles++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 4;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_AbsoluteY() {
|
void CPU::LDA_AbsoluteY() {
|
||||||
uint16_t base_address = ReadWord(PC);
|
const uint16_t base = ReadWord(PC);
|
||||||
PC += 2;
|
PC += 2;
|
||||||
uint32_t address = base_address + Y;
|
|
||||||
|
|
||||||
// Page boundary crossing adds a cycle
|
LDA_Mem(base + Y, 4, false, true, base, Y);
|
||||||
if ((base_address & 0xFF00) != (address & 0xFF00)) {
|
|
||||||
cycles++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
|
||||||
// 8-bit mode
|
|
||||||
uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 4;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_DirectPage() {
|
void CPU::LDA_DirectPage() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t address = D + offset;
|
LDA_Mem(D + offset, 3, true);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
|
||||||
// 8-bit mode
|
|
||||||
uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 3;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra cycle if D register is not page-aligned
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_DirectPageX() {
|
void CPU::LDA_DirectPageX() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t address = D + offset + (P & FLAG_X ? (X & 0xFF) : X);
|
const uint16_t x_offset = (P & FLAG_X) ? (X & 0xFF) : X;
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(D + offset + x_offset, 4, true);
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 4;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra cycle if D register is not page-aligned
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_IndirectDirectPage() {
|
void CPU::LDA_IndirectDirectPage() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t pointer_address = D + offset;
|
const uint32_t ptr = D + offset;
|
||||||
const uint16_t address = ReadWord(pointer_address);
|
const uint16_t address = ReadWord(ptr);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(address, 5, true);
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 5;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra cycle if D register is not page-aligned
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_IndirectDirectPageY() {
|
void CPU::LDA_IndirectDirectPageY() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t pointer_address = D + offset;
|
const uint32_t ptr = D + offset;
|
||||||
const uint16_t base_address = ReadWord(pointer_address);
|
const uint16_t base = ReadWord(ptr);
|
||||||
const uint32_t address = base_address + Y;
|
|
||||||
|
|
||||||
// Page boundary crossing adds a cycle
|
LDA_Mem(base + Y, 5, true, true, base, Y);
|
||||||
if ((base_address & 0xFF00) != (address & 0xFF00)) {
|
|
||||||
cycles++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 5;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra cycle if D register is not page-aligned
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_DirectPageIndirectX() {
|
void CPU::LDA_DirectPageIndirectX() {
|
||||||
const uint8_t offset = ReadByte(PC++);
|
const uint8_t offset = ReadByte(PC++);
|
||||||
const uint32_t pointer_address = D + offset + (P & FLAG_X ? (X & 0xFF) : X);
|
const uint16_t x_offset = (P & FLAG_X) ? (X & 0xFF) : X;
|
||||||
const uint16_t address = ReadWord(pointer_address);
|
const uint32_t ptr = D + offset + x_offset;
|
||||||
|
const uint16_t address = ReadWord(ptr);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(address, 6, true);
|
||||||
// 8-bit mode
|
|
||||||
uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 6;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra cycle if D register is not page-aligned
|
|
||||||
if (D & 0xFF) cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_Long() {
|
void CPU::LDA_Long() {
|
||||||
const uint32_t address = ReadByte(PC++) | (ReadByte(PC++) << 8) | (ReadByte(PC++) << 16);
|
const uint32_t address = ReadByte(PC++) | (ReadByte(PC++) << 8) | (ReadByte(PC++) << 16);
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(address, 5);
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 5;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::LDA_LongX() {
|
void CPU::LDA_LongX() {
|
||||||
const uint32_t base_address = ReadByte(PC++) | (ReadByte(PC++) << 8) | (ReadByte(PC++) << 16);
|
const uint32_t base = ReadByte(PC++) | (ReadByte(PC++) << 8) | (ReadByte(PC++) << 16);
|
||||||
const uint32_t address = base_address + X;
|
|
||||||
|
|
||||||
if (P & FLAG_M) {
|
LDA_Mem(base + X, 5);
|
||||||
// 8-bit mode
|
|
||||||
const uint8_t value = ReadByte(address);
|
|
||||||
A = (A & 0xFF00) | value;
|
|
||||||
UpdateNZ8(value);
|
|
||||||
cycles += 5;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
A = ReadWord(address);
|
|
||||||
UpdateNZ16(A);
|
|
||||||
cycles += 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load X Register Instructions
|
// Load X Register Instructions
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ 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);
|
||||||
|
|
||||||
|
void LDA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base,
|
||||||
|
uint16_t offset);
|
||||||
|
|
||||||
// General ORA Logic
|
// General ORA Logic
|
||||||
void ORA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base_address,
|
void ORA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base_address,
|
||||||
uint16_t offset);
|
uint16_t offset);
|
||||||
|
|||||||
Reference in New Issue
Block a user