Implement Increment and Decrement Instructions
This commit is contained in:
326
src/cpu.cpp
326
src/cpu.cpp
@@ -56,7 +56,30 @@ void CPU::WriteWord(const uint32_t address, const uint16_t value) const {
|
||||
void CPU::ExecuteInstruction() {
|
||||
// TODO: Actual Opcode decoding
|
||||
switch (const uint8_t opcode = bus->Read(PC++)) {
|
||||
case 0xEA: NOP(); break;
|
||||
// DEC - Decrement Memory
|
||||
case 0x3A: DEC_Accumulator(); break; // DEC A
|
||||
case 0xCE: DEC_Absolute(); break; // DEC $nnnn
|
||||
case 0xDE: DEC_AbsoluteX(); break; // DEC $nnnn,X
|
||||
case 0xC6: DEC_DirectPage(); break; // DEC $nn
|
||||
case 0xD6: DEC_DirectPageX(); break; // DEC $nn,X
|
||||
|
||||
// Single Register Decrement
|
||||
case 0xCA: DEX(); break; // DEX - Decrement X Register
|
||||
case 0x88: DEY(); break; // DEY - Decrement Y Register
|
||||
|
||||
// INC - Increment Memory
|
||||
case 0x1A: INC_Accumulator(); break; // INC A
|
||||
case 0xEE: INC_Absolute(); break; // INC $nnnn
|
||||
case 0xFE: INC_AbsoluteX(); break; // INC $nnnn,X
|
||||
case 0xE6: INC_DirectPage(); break; // INC $nn
|
||||
case 0xF6: INC_DirectPageX(); break; // INC $nn,X
|
||||
|
||||
// Single Register Increment
|
||||
case 0xE8: INX(); break; // INX - Increment X Register
|
||||
case 0xC8: INY(); break; // INY - Increment Y Register
|
||||
|
||||
// No Operation
|
||||
case 0xEA: NOP(); break; //NOP
|
||||
|
||||
// LDA - Load Accumulator
|
||||
case 0xA9: LDA_Immediate(); break; // LDA #$nn or #$nnnn
|
||||
@@ -71,7 +94,7 @@ void CPU::ExecuteInstruction() {
|
||||
case 0xAF: LDA_Long(); break; // LDA $nnnnnn
|
||||
case 0xBF: LDA_LongX(); break; // LDA $nnnnnn,X
|
||||
|
||||
// LDX - Load X Register
|
||||
// LDX - Load X Register
|
||||
case 0xA2: LDX_Immediate(); break; // LDX #$nn or LDX #$nnnn
|
||||
case 0xAE: LDX_Absolute(); break; // LDX $nnnn
|
||||
case 0xBE: LDX_AbsoluteY(); break; // LDX $nnnn,Y
|
||||
@@ -543,7 +566,7 @@ void CPU::LDY_DirectPageX() {
|
||||
|
||||
//Store operations implementation
|
||||
void CPU::STA_Absolute() {
|
||||
uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -556,8 +579,8 @@ void CPU::STA_Absolute() {
|
||||
}
|
||||
|
||||
void CPU::STA_AbsoluteX() {
|
||||
uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
uint32_t address = base + X;
|
||||
const uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = base + X;
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -570,8 +593,8 @@ void CPU::STA_AbsoluteX() {
|
||||
}
|
||||
|
||||
void CPU::STA_AbsoluteY() {
|
||||
uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
uint32_t address = base + Y;
|
||||
const uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = base + Y;
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -584,8 +607,8 @@ void CPU::STA_AbsoluteY() {
|
||||
}
|
||||
|
||||
void CPU::STA_DirectPage() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t address = (D + offset) & 0xFFFF;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -600,8 +623,8 @@ void CPU::STA_DirectPage() {
|
||||
}
|
||||
|
||||
void CPU::STA_DirectPageX() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -616,9 +639,9 @@ void CPU::STA_DirectPageX() {
|
||||
}
|
||||
|
||||
void CPU::STA_IndirectDirectPage() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t pointer = (D + offset) & 0xFFFF;
|
||||
uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t pointer = (D + offset) & 0xFFFF;
|
||||
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -633,10 +656,10 @@ void CPU::STA_IndirectDirectPage() {
|
||||
}
|
||||
|
||||
void CPU::STA_IndirectDirectPageY() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t pointer = (D + offset) & 0xFFFF;
|
||||
uint32_t base = ReadWord(pointer) | (DB << 16);
|
||||
uint32_t address = base + Y;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t pointer = (D + offset) & 0xFFFF;
|
||||
const uint32_t base = ReadWord(pointer) | (DB << 16);
|
||||
const uint32_t address = base + Y;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -651,9 +674,9 @@ void CPU::STA_IndirectDirectPageY() {
|
||||
}
|
||||
|
||||
void CPU::STA_DirectPageIndirectX() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t pointer = (D + offset + X) & 0xFFFF;
|
||||
uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t pointer = (D + offset + X) & 0xFFFF;
|
||||
const uint32_t address = ReadWord(pointer) | (DB << 16);
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -668,7 +691,7 @@ void CPU::STA_DirectPageIndirectX() {
|
||||
}
|
||||
|
||||
void CPU::STA_Long() {
|
||||
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;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -681,8 +704,8 @@ void CPU::STA_Long() {
|
||||
}
|
||||
|
||||
void CPU::STA_LongX() {
|
||||
uint32_t base = ReadByte(PC + 1) | (ReadByte(PC + 2) << 8) | (ReadByte(PC + 3) << 16);
|
||||
uint32_t address = base + X;
|
||||
const uint32_t base = ReadByte(PC + 1) | (ReadByte(PC + 2) << 8) | (ReadByte(PC + 3) << 16);
|
||||
const uint32_t address = base + X;
|
||||
PC += 4;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
@@ -696,7 +719,7 @@ void CPU::STA_LongX() {
|
||||
|
||||
// STX - Store X Register
|
||||
void CPU::STX_Absolute() {
|
||||
uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
@@ -709,8 +732,8 @@ void CPU::STX_Absolute() {
|
||||
}
|
||||
|
||||
void CPU::STX_DirectPage() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t address = (D + offset) & 0xFFFF;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
@@ -755,8 +778,8 @@ void CPU::STY_Absolute() {
|
||||
}
|
||||
|
||||
void CPU::STY_DirectPage() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t address = (D + offset) & 0xFFFF;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
@@ -771,8 +794,8 @@ void CPU::STY_DirectPage() {
|
||||
}
|
||||
|
||||
void CPU::STY_DirectPageX() {
|
||||
uint8_t offset = ReadByte(PC + 1);
|
||||
uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
@@ -784,4 +807,245 @@ void CPU::STY_DirectPageX() {
|
||||
cycles += 5;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
}
|
||||
}
|
||||
|
||||
// INC - Increment Memory
|
||||
// Important to note: PC doesn't increment in accumulator mode I think
|
||||
void CPU::INC_Accumulator() {
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
A = (A & 0xFF00) | ((A + 1) & 0xFF);
|
||||
UpdateNZ8(A & 0xFF);
|
||||
cycles += 2;
|
||||
} else { // 16-bit mode
|
||||
A = (A + 1) & 0xFFFF;
|
||||
UpdateNZ16(A);
|
||||
cycles += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::INC_Absolute() {
|
||||
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value + 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value + 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::INC_AbsoluteX() {
|
||||
const uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = base + X;
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value + 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 7;
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value + 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 9;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::INC_DirectPage() {
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value + 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 5;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value + 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 7;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::INC_DirectPageX() {
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value + 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value + 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 8;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
}
|
||||
}
|
||||
|
||||
// DEC - Decrement Memory
|
||||
void CPU::DEC_Accumulator() {
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
A = (A & 0xFF00) | ((A - 1) & 0xFF);
|
||||
UpdateNZ8(A & 0xFF);
|
||||
cycles += 2;
|
||||
} else { // 16-bit mode
|
||||
A = (A - 1) & 0xFFFF;
|
||||
UpdateNZ16(A);
|
||||
cycles += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::DEC_Absolute() {
|
||||
const uint32_t address = ReadWord(PC + 1) | (DB << 16);
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value - 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value - 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::DEC_AbsoluteX() {
|
||||
const uint32_t base = ReadWord(PC + 1) | (DB << 16);
|
||||
const uint32_t address = base + X;
|
||||
PC += 3;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value - 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 7;
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value - 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 9;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::DEC_DirectPage() {
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value - 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 5;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value - 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 7;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::DEC_DirectPageX() {
|
||||
const uint8_t offset = ReadByte(PC + 1);
|
||||
const uint32_t address = (D + offset + X) & 0xFFFF;
|
||||
PC += 2;
|
||||
|
||||
if (P & FLAG_M) { // 8-bit mode
|
||||
uint8_t value = ReadByte(address);
|
||||
value = (value - 1) & 0xFF;
|
||||
WriteByte(address, value);
|
||||
UpdateNZ8(value);
|
||||
cycles += 6;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
} else { // 16-bit mode
|
||||
uint16_t value = ReadWord(address);
|
||||
value = (value - 1) & 0xFFFF;
|
||||
WriteWord(address, value);
|
||||
UpdateNZ16(value);
|
||||
cycles += 8;
|
||||
if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0
|
||||
}
|
||||
}
|
||||
|
||||
// INX - Increment X Register
|
||||
void CPU::INX() {
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
X = (X & 0xFF00) | ((X + 1) & 0xFF);
|
||||
UpdateNZ8(X & 0xFF);
|
||||
} else { // 16-bit mode
|
||||
X = (X + 1) & 0xFFFF;
|
||||
UpdateNZ16(X);
|
||||
}
|
||||
cycles += 2;
|
||||
}
|
||||
|
||||
// INY - Increment Y Register
|
||||
void CPU::INY() {
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
Y = (Y & 0xFF00) | ((Y + 1) & 0xFF);
|
||||
UpdateNZ8(Y & 0xFF);
|
||||
} else { // 16-bit mode
|
||||
Y = (Y + 1) & 0xFFFF;
|
||||
UpdateNZ16(Y);
|
||||
}
|
||||
cycles += 2;
|
||||
}
|
||||
|
||||
// DEX - Decrement X Register
|
||||
void CPU::DEX() {
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
X = (X & 0xFF00) | ((X - 1) & 0xFF);
|
||||
UpdateNZ8(X & 0xFF);
|
||||
} else { // 16-bit mode
|
||||
X = (X - 1) & 0xFFFF;
|
||||
UpdateNZ16(X);
|
||||
}
|
||||
cycles += 2;
|
||||
}
|
||||
|
||||
// DEY - Decrement Y Register
|
||||
void CPU::DEY() {
|
||||
if (P & FLAG_X) { // 8-bit mode
|
||||
Y = (Y & 0xFF00) | ((Y - 1) & 0xFF);
|
||||
UpdateNZ8(Y & 0xFF);
|
||||
} else { // 16-bit mode
|
||||
Y = (Y - 1) & 0xFFFF;
|
||||
UpdateNZ16(Y);
|
||||
}
|
||||
cycles += 2;
|
||||
}
|
||||
Reference in New Issue
Block a user