Implement Missing JMP and LDA Instructions
This commit is contained in:
105
src/cpu.cpp
105
src/cpu.cpp
@@ -411,6 +411,7 @@ void CPU::ExecuteInstruction() {
|
||||
case 0x6C: JMP_AbsoluteIndirect(); break; // JMP ($nnnn)
|
||||
case 0x5C: JMP_AbsoluteLong(); break; // JMP $nnnnnn
|
||||
case 0x7C: JMP_AbsoluteIndirectX(); break; // JMP ($nnnn,X)
|
||||
case 0xDC: JMP_AbsoluteIndirectLong(); break; // JMP [addr]
|
||||
|
||||
// Subroutine instructions
|
||||
case 0x20: JSR_Absolute(); break; // JSR $nnnn
|
||||
@@ -447,6 +448,10 @@ void CPU::ExecuteInstruction() {
|
||||
case 0xA1: LDA_DirectPageIndirectX(); break; // LDA ($nn,X)
|
||||
case 0xAF: LDA_Long(); break; // LDA $nnnnnn
|
||||
case 0xBF: LDA_LongX(); break; // LDA $nnnnnn,X
|
||||
case 0xA3: LDA_StackRelative(); break; // LDA sr,S
|
||||
case 0xA7: LDA_IndirectDirectPageLong(); break; // LDA [dp]
|
||||
case 0xB3: LDA_StackRelativeIndirectY(); break; // LDA (sr,S),Y
|
||||
case 0xB7: LDA_IndirectDirectPageLongY(); break; // LDA [dp],Y
|
||||
|
||||
// LDX - Load X Register
|
||||
case 0xA2: LDX_Immediate(); break; // LDX #$nn or LDX #$nnnn
|
||||
@@ -3224,3 +3229,103 @@ void CPU::EOR_StackRelativeIndirectY() {
|
||||
cycles += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::JMP_AbsoluteIndirectLong() {
|
||||
const uint16_t pointer_address = ReadWord(PC);
|
||||
PC += 2;
|
||||
|
||||
const uint32_t target_address = ReadByte(pointer_address) |
|
||||
(ReadByte(pointer_address + 1) << 8) |
|
||||
(ReadByte(pointer_address + 2) << 16);
|
||||
|
||||
PC = target_address & 0xFFFF;
|
||||
PB = (target_address >> 16) & 0xFF;
|
||||
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void CPU::LDA_StackRelative() {
|
||||
const uint8_t offset = ReadByte(PC++);
|
||||
const uint32_t address = SP + offset;
|
||||
|
||||
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
|
||||
const uint16_t value = ReadWord(address);
|
||||
A = value;
|
||||
UpdateNZ16(value);
|
||||
cycles += 5;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::LDA_IndirectDirectPageLong() {
|
||||
const uint8_t offset = ReadByte(PC++);
|
||||
const uint32_t pointer_address = D + offset;
|
||||
|
||||
const uint32_t full_address = ReadByte(pointer_address) |
|
||||
(ReadByte(pointer_address + 1) << 8) |
|
||||
(ReadByte(pointer_address + 2) << 16);
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
const uint8_t value = ReadByte(full_address);
|
||||
A = (A & 0xFF00) | value;
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
if (D & 0xFF) cycles++;
|
||||
} else { // 16-bit mode
|
||||
const uint16_t value = ReadWord(full_address);
|
||||
A = value;
|
||||
UpdateNZ16(value);
|
||||
cycles += 7;
|
||||
if (D & 0xFF) cycles++;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::LDA_StackRelativeIndirectY() {
|
||||
const uint8_t offset = ReadByte(PC++);
|
||||
const uint32_t pointer_address = SP + offset;
|
||||
|
||||
const uint16_t base_address = ReadWord(pointer_address);
|
||||
|
||||
const uint32_t full_address = (DB << 16) | (base_address + Y);
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
const uint8_t value = ReadByte(full_address);
|
||||
A = (A & 0xFF00) | value;
|
||||
UpdateNZ8(value);
|
||||
cycles += 7;
|
||||
} else { // 16-bit mode
|
||||
const uint16_t value = ReadWord(full_address);
|
||||
A = value;
|
||||
UpdateNZ16(value);
|
||||
cycles += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::LDA_IndirectDirectPageLongY() {
|
||||
const uint8_t offset = ReadByte(PC++);
|
||||
const uint32_t pointer_address = D + offset;
|
||||
|
||||
const uint32_t base_address = ReadByte(pointer_address) |
|
||||
(ReadByte(pointer_address + 1) << 8) |
|
||||
(ReadByte(pointer_address + 2) << 16);
|
||||
|
||||
const uint32_t full_address = base_address + Y;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
const uint8_t value = ReadByte(full_address);
|
||||
A = (A & 0xFF00) | value;
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
if (D & 0xFF) cycles++;
|
||||
} else { // 16-bit mode
|
||||
const uint16_t value = ReadWord(full_address);
|
||||
A = value;
|
||||
UpdateNZ16(value);
|
||||
cycles += 7;
|
||||
if (D & 0xFF) cycles++;
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,10 @@ public:
|
||||
void LDA_DirectPageIndirectX();
|
||||
void LDA_Long();
|
||||
void LDA_LongX();
|
||||
void LDA_StackRelative();
|
||||
void LDA_IndirectDirectPageLong();
|
||||
void LDA_StackRelativeIndirectY();
|
||||
void LDA_IndirectDirectPageLongY();
|
||||
|
||||
void LDX_Immediate();
|
||||
void LDX_Absolute();
|
||||
@@ -173,6 +177,7 @@ public:
|
||||
void JMP_AbsoluteIndirect();
|
||||
void JMP_AbsoluteLong();
|
||||
void JMP_AbsoluteIndirectX();
|
||||
void JMP_AbsoluteIndirectLong();
|
||||
|
||||
void BEQ_Relative();
|
||||
void BNE_Relative();
|
||||
|
||||
Reference in New Issue
Block a user