Implement Missing STA Instructions and Add SE* Instructions

This commit is contained in:
2025-07-24 09:31:26 -04:00
parent e6622191d3
commit 6be52bf145
2 changed files with 148 additions and 12 deletions

View File

@@ -18,7 +18,7 @@ void CPU::Reset() {
}
void CPU::Step() {
ExecuteInstruction();
if (!stopped) ExecuteInstruction();
}
// CPU Helper Methods
@@ -751,17 +751,30 @@ void CPU::ExecuteInstruction() {
case 0xE3: SBC_StackRelative(); break; // SBC $nn,S
case 0xF3: SBC_StackRelativeIndirectY(); break; // SBC ($nn,S),Y
//SDA - Store Accumulator
case 0x8D: STA_Absolute(); break; // STA $nnnn
case 0x9D: STA_AbsoluteX(); break; // STA $nnnn,X
case 0x99: STA_AbsoluteY(); break; // STA $nnnn,Y
case 0x85: STA_DirectPage(); break; // STA $nn
case 0x95: STA_DirectPageX(); break; // STA $nn,X
case 0x92: STA_IndirectDirectPage(); break; // STA ($nn)
case 0x91: STA_IndirectDirectPageY(); break; // STA ($nn),Y
case 0x81: STA_DirectPageIndirectX(); break; // STA ($nn,X)
case 0x8F: STA_Long(); break; // STA $nnnnnn
case 0x9F: STA_LongX(); break; // STA $nnnnnn,X
// SE* - Set Certain Flags
case 0x38: SEC(); break;
case 0xF8: SED(); break;
case 0x78: SEI(); break;
case 0xE2: SEP(); break;
//STA - Store Accumulator
case 0x8D: STA_Absolute(); break; // STA $nnnn
case 0x9D: STA_AbsoluteX(); break; // STA $nnnn,X
case 0x99: STA_AbsoluteY(); break; // STA $nnnn,Y
case 0x85: STA_DirectPage(); break; // STA $nn
case 0x95: STA_DirectPageX(); break; // STA $nn,X
case 0x92: STA_IndirectDirectPage(); break; // STA ($nn)
case 0x91: STA_IndirectDirectPageY(); break; // STA ($nn),Y
case 0x81: STA_DirectPageIndirectX(); break; // STA ($nn,X)
case 0x8F: STA_Long(); break; // STA $nnnnnn
case 0x9F: STA_LongX(); break; // STA $nnnnnn,X
case 0x83: STA_StackRelative(); break; // STA sr,S
case 0x87: STA_DirectPageIndirectLong(); break; // STA [dp]
case 0x93: STA_StackRelativeIndirectY(); break; // STA (sr,S),Y
case 0x97: STA_DirectPageIndirectLongY(); break; // STA [dp],Y
// STP - Stop Processor
case 0xDB: STP(); break; // STP
//SDX - Store X Register
case 0x8E: STX_Absolute(); break; // STX $nnnn
@@ -1360,6 +1373,86 @@ void CPU::STA_LongX() {
}
}
void CPU::STA_StackRelative() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = SP + offset;
if (P & FLAG_M) {
// 8-bit mode
WriteByte(address, A & 0xFF);
cycles += 4;
} else {
// 16-bit mode
WriteWord(address, A);
cycles += 5;
}
}
void CPU::STA_DirectPageIndirectLong() {
const uint8_t offset = ReadByte(PC++);
const uint32_t indirect_addr = D + offset;
const uint32_t target_address = ReadByte(indirect_addr) |
(ReadByte(indirect_addr + 1) << 8) |
(ReadByte(indirect_addr + 2) << 16);
if (P & FLAG_M) {
// 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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t indirect_addr = SP + offset;
const uint16_t base_address = ReadWord(indirect_addr);
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
const uint32_t target_address = (DB << 16) | (base_address + y_offset);
if (P & FLAG_M) {
// 8-bit mode
WriteByte(target_address, A & 0xFF);
cycles += 7;
} else {
// 16-bit mode
WriteWord(target_address, A);
cycles += 8;
}
}
void CPU::STA_DirectPageIndirectLongY() {
const uint8_t offset = ReadByte(PC++);
const uint32_t indirect_addr = D + offset;
const uint32_t base_address = ReadByte(indirect_addr) |
(ReadByte(indirect_addr + 1) << 8) |
(ReadByte(indirect_addr + 2) << 16);
const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
const uint32_t target_address = base_address + y_offset;
if (P & FLAG_M) {
// 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
void CPU::STX_Absolute() {
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
@@ -4600,3 +4693,34 @@ void CPU::SBC_StackRelativeIndirectY() {
cycles += 8;
}
}
void CPU::SEC() {
P |= FLAG_C;
cycles += 2;
}
void CPU::SED() {
P |= FLAG_D;
cycles += 2;
}
void CPU::SEI() {
// This prevents IRQ interrupts from being processed
P |= FLAG_I;
cycles += 2;
}
void CPU::SEP() {
const uint8_t mask = ReadByte(PC++);
P |= mask;
cycles += 3;
}
void CPU::STP() {
stopped = true;
cycles += 3;
// TODO: Implement way to resume processor?
}

View File

@@ -21,6 +21,7 @@ class CPU {
Bus* bus;
uint64_t cycles;
bool emulation_mode = false;
bool stopped = false;
// Status flags
enum Flags {
@@ -162,6 +163,10 @@ public:
void STA_DirectPageIndirectX();
void STA_Long();
void STA_LongX();
void STA_StackRelative();
void STA_DirectPageIndirectLong();
void STA_StackRelativeIndirectY();
void STA_DirectPageIndirectLongY();
void STX_Absolute();
void STX_DirectPage();
@@ -355,6 +360,13 @@ public:
void SBC_DirectPageIndirectX();
void SBC_StackRelative();
void SBC_StackRelativeIndirectY();
void SEC();
void SED();
void SEI();
void SEP();
void STP();
};
#endif //CPU_H