Implement Missing STA Instructions and Add SE* Instructions
This commit is contained in:
148
src/cpu.cpp
148
src/cpu.cpp
@@ -18,7 +18,7 @@ void CPU::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU::Step() {
|
void CPU::Step() {
|
||||||
ExecuteInstruction();
|
if (!stopped) ExecuteInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPU Helper Methods
|
// CPU Helper Methods
|
||||||
@@ -751,17 +751,30 @@ void CPU::ExecuteInstruction() {
|
|||||||
case 0xE3: SBC_StackRelative(); break; // SBC $nn,S
|
case 0xE3: SBC_StackRelative(); break; // SBC $nn,S
|
||||||
case 0xF3: SBC_StackRelativeIndirectY(); break; // SBC ($nn,S),Y
|
case 0xF3: SBC_StackRelativeIndirectY(); break; // SBC ($nn,S),Y
|
||||||
|
|
||||||
//SDA - Store Accumulator
|
// SE* - Set Certain Flags
|
||||||
case 0x8D: STA_Absolute(); break; // STA $nnnn
|
case 0x38: SEC(); break;
|
||||||
case 0x9D: STA_AbsoluteX(); break; // STA $nnnn,X
|
case 0xF8: SED(); break;
|
||||||
case 0x99: STA_AbsoluteY(); break; // STA $nnnn,Y
|
case 0x78: SEI(); break;
|
||||||
case 0x85: STA_DirectPage(); break; // STA $nn
|
case 0xE2: SEP(); break;
|
||||||
case 0x95: STA_DirectPageX(); break; // STA $nn,X
|
|
||||||
case 0x92: STA_IndirectDirectPage(); break; // STA ($nn)
|
//STA - Store Accumulator
|
||||||
case 0x91: STA_IndirectDirectPageY(); break; // STA ($nn),Y
|
case 0x8D: STA_Absolute(); break; // STA $nnnn
|
||||||
case 0x81: STA_DirectPageIndirectX(); break; // STA ($nn,X)
|
case 0x9D: STA_AbsoluteX(); break; // STA $nnnn,X
|
||||||
case 0x8F: STA_Long(); break; // STA $nnnnnn
|
case 0x99: STA_AbsoluteY(); break; // STA $nnnn,Y
|
||||||
case 0x9F: STA_LongX(); break; // STA $nnnnnn,X
|
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
|
//SDX - Store X Register
|
||||||
case 0x8E: STX_Absolute(); break; // STX $nnnn
|
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
|
// STX - Store X Register
|
||||||
void CPU::STX_Absolute() {
|
void CPU::STX_Absolute() {
|
||||||
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||||
@@ -4600,3 +4693,34 @@ void CPU::SBC_StackRelativeIndirectY() {
|
|||||||
cycles += 8;
|
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?
|
||||||
|
}
|
||||||
12
src/cpu.h
12
src/cpu.h
@@ -21,6 +21,7 @@ class CPU {
|
|||||||
Bus* bus;
|
Bus* bus;
|
||||||
uint64_t cycles;
|
uint64_t cycles;
|
||||||
bool emulation_mode = false;
|
bool emulation_mode = false;
|
||||||
|
bool stopped = false;
|
||||||
|
|
||||||
// Status flags
|
// Status flags
|
||||||
enum Flags {
|
enum Flags {
|
||||||
@@ -162,6 +163,10 @@ public:
|
|||||||
void STA_DirectPageIndirectX();
|
void STA_DirectPageIndirectX();
|
||||||
void STA_Long();
|
void STA_Long();
|
||||||
void STA_LongX();
|
void STA_LongX();
|
||||||
|
void STA_StackRelative();
|
||||||
|
void STA_DirectPageIndirectLong();
|
||||||
|
void STA_StackRelativeIndirectY();
|
||||||
|
void STA_DirectPageIndirectLongY();
|
||||||
|
|
||||||
void STX_Absolute();
|
void STX_Absolute();
|
||||||
void STX_DirectPage();
|
void STX_DirectPage();
|
||||||
@@ -355,6 +360,13 @@ public:
|
|||||||
void SBC_DirectPageIndirectX();
|
void SBC_DirectPageIndirectX();
|
||||||
void SBC_StackRelative();
|
void SBC_StackRelative();
|
||||||
void SBC_StackRelativeIndirectY();
|
void SBC_StackRelativeIndirectY();
|
||||||
|
|
||||||
|
void SEC();
|
||||||
|
void SED();
|
||||||
|
void SEI();
|
||||||
|
void SEP();
|
||||||
|
|
||||||
|
void STP();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CPU_H
|
#endif //CPU_H
|
||||||
|
|||||||
Reference in New Issue
Block a user