diff options
author | vin <git@vineetk.net> | 2024-07-04 14:17:40 -0400 |
---|---|---|
committer | vin <git@vineetk.net> | 2024-07-04 14:17:40 -0400 |
commit | 4ccf9f5cee97c8c2191660a5632ab2da60757f97 (patch) | |
tree | fd7c3668d904c3c9024401c396e9ca905d932971 /cpu.c | |
parent | c4fc40a036293a8f5899800ad3ecb1d24ba77bc4 (diff) |
add preliminary implementation of the unofficial opcodes
Diffstat (limited to 'cpu.c')
-rw-r--r-- | cpu.c | 91 |
1 files changed, 57 insertions, 34 deletions
@@ -128,8 +128,8 @@ opcode_mem(enum addressing_mode mode) break; case AM_REL: val = arg + regs.pc; - if ((regs.pc + 1) & 0xFF00 != val & 0xFF00) - page_crossed = true; + if (((regs.pc + 1) & 0xFF00) != (val & 0xFF00)) + val -= 0x0100; break; case AM_IMM: case AM_ABS: @@ -703,133 +703,158 @@ TYA(uint16_t arg) void AAC(uint16_t arg) { - NOP(0); + AND(arg); + + regs.status.carry = regs.status.negative; } void -AAX(uint16_t arg) +SAX(uint16_t arg) { - NOP(0); + uint8_t tmp = regs.x & regs.a; + memwrite(arg, tmp); } void ARR(uint16_t arg) { - NOP(0); + uint8_t tmp = arg & regs.a; + + AND(arg); + ROR_acc(0); + + if ((tmp & (1 << 5)) != 0 && (tmp & (1 << 6)) != 0) + SEC(0), CLV(0); + else if ((tmp & (1 << 5)) == 0 && (tmp & (1 << 6)) == 0) + CLC(0), CLV(0); + else if ((tmp & (1 << 5)) != 0) + CLC(0), regs.status.overflow = 1; + else if ((tmp & (1 << 6)) != 0) + SEC(0), regs.status.overflow = 1; } void ASR(uint16_t arg) { - NOP(0); + AND(arg); + LSR_acc(0); } void ATX(uint16_t arg) { - NOP(0); + AND(arg); + TAX(0); } void AXA(uint16_t arg) { - NOP(0); + uint8_t tmp = regs.x & regs.a & 7; + memwrite(arg, tmp); } void AXS(uint16_t arg) { - NOP(0); + regs.x &= regs.a; + regs.x -= arg; + + regs.status.carry = arg <= regs.x; + STATUS_UPDATE_NZ(regs.x); } void DCP(uint16_t arg) { - NOP(0); -} + uint8_t tmp = peek(arg) - 1; + memwrite(arg, tmp); -void -DOP(uint16_t arg) -{ - NOP(0); + regs.status.carry = tmp <= regs.a; + STATUS_UPDATE_NZ(tmp); } void ISC(uint16_t arg) { - NOP(0); + INC(arg); + SBC(peek(arg)); } void KIL(uint16_t arg) { + /* TODO: figure out how to stop interpret(), I guess with global bool */ NOP(0); } void LAR(uint16_t arg) { - NOP(0); + regs.a = regs.x = regs.sp = regs.a & regs.sp; + + STATUS_UPDATE_NZ(regs.a); } void LAX(uint16_t arg) { - NOP(0); + LDA(arg); + LDX(arg); } void RLA(uint16_t arg) { - NOP(0); + ROL(arg); + AND(arg); } void RRA(uint16_t arg) { - NOP(0); + ROR(arg); + ADC(peek(arg)); } void SLO(uint16_t arg) { - NOP(0); + ASL(arg); + ORA(arg); } void SRE(uint16_t arg) { - NOP(0); + LSR(arg); + EOR(arg); } void SXA(uint16_t arg) { - NOP(0); + memwrite(arg, regs.x & ((arg & 0xFF00) + 1)); } void SYA(uint16_t arg) { - NOP(0); -} - -void -TOP(uint16_t arg) -{ - NOP(0); + memwrite(arg, regs.x & ((arg & 0xFF00) + 1)); } void XAA(uint16_t arg) { + /* TODO: apparently the exact operation is unknown */ NOP(0); } void XAS(uint16_t arg) { - NOP(0); + regs.sp = regs.a & regs.x; + memwrite(arg, regs.sp & ((arg & 0xFF00) + 1)); } static void @@ -877,8 +902,6 @@ interpret(void) printf("$%02X,Y", arg); break; case AM_REL: - printf("$%04X", regs.pc + arg); - break; case AM_ABS: printf("$%04X", arg); break; |