summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-07-03 18:52:15 -0400
committervin <git@vineetk.net>2024-07-03 19:22:00 -0400
commitd8bb5a5ccf96fed7e8084cf691c987ce56a8c995 (patch)
tree5cfc546f2ae063d1261ef34ee054bd857033231d
parenta4b39966aed8d41ad4ddc6700683c4779e8d1cb2 (diff)
call opcode function pointer instead of using switch case
Also improve logging.
-rw-r--r--cpu.c1445
-rw-r--r--opcodes.h304
2 files changed, 325 insertions, 1424 deletions
diff --git a/cpu.c b/cpu.c
index edfe172..6e44c7f 100644
--- a/cpu.c
+++ b/cpu.c
@@ -106,10 +106,8 @@ opcode_arg(enum addressing_mode mode)
if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) {
arg = peek(regs.pc++);
- printf(" %02X\t", arg);
} else {
arg = peek16(regs.pc);
- printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
regs.pc += 2;
}
@@ -155,12 +153,12 @@ opcode_mem(enum addressing_mode mode)
{
uint16_t arg, val;
- if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y && mode != AM_IND && mode) {
+ if (mode == AM_ACC || mode == AM_NONE) {
+ return 0;
+ } else if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y && mode != AM_IND && mode) {
arg = peek(regs.pc++);
- printf(" %02X\t", arg);
} else {
arg = peek16(regs.pc);
- printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
regs.pc += 2;
}
@@ -175,6 +173,7 @@ opcode_mem(enum addressing_mode mode)
val = (arg + regs.y) % 256;
break;
case AM_IMM:
+ case AM_REL:
case AM_ABS:
val = arg;
break;
@@ -194,15 +193,15 @@ opcode_mem(enum addressing_mode mode)
val = peek(arg) + peek((arg + 1) % 256) * 256 + regs.y;
break;
default:
- fprintf(stderr, "INVALID ADDRESSING MODE\n");
+ fprintf(stderr, "opcode_mem INVALID ADDRESSING MODE %i\n", mode);
abort();
}
return val;
}
-static void
-adc(uint8_t arg)
+void
+ADC(uint16_t arg)
{
uint16_t sum; // 16-bit sum makes it easier to determine carry flag
@@ -216,16 +215,16 @@ adc(uint8_t arg)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-and(uint8_t arg)
+void
+AND(uint16_t arg)
{
regs.a &= arg;
STATUS_UPDATE_NZ(regs.a);
}
-static void
-asl_acc(void)
+void
+ASL_acc(uint16_t arg)
{
uint16_t tmp;
@@ -236,8 +235,8 @@ asl_acc(void)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-asl(uint16_t mem)
+void
+ASL(uint16_t mem)
{
uint16_t tmp;
@@ -248,109 +247,108 @@ asl(uint16_t mem)
STATUS_UPDATE_NZ(tmp);
}
-static void
-bcc(uint8_t arg)
+void
+BCC(uint16_t arg)
{
if (regs.status.carry == 0)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-bcs(uint8_t arg)
+void
+BCS(uint16_t arg)
{
if (regs.status.carry == 1)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-beq(uint8_t arg)
+void
+BEQ(uint16_t arg)
{
if (regs.status.zero == 1)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static uint8_t
-bit(uint8_t arg)
+void
+BIT(uint16_t arg)
{
- regs.status.zero = (regs.a & arg) == 0;
- regs.status.overflow = (arg & (1 << 6)) != 0;
- STATUS_UPDATE_NEGATIVE(arg);
-
- return regs.a & arg;
+ uint8_t tmp = peek(arg);
+ regs.status.zero = (regs.a & tmp) == 0;
+ regs.status.overflow = (tmp & (1 << 6)) != 0;
+ STATUS_UPDATE_NEGATIVE(tmp);
}
-static void
-bmi(uint8_t arg)
+void
+BMI(uint16_t arg)
{
if (regs.status.negative == 1)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-bne(uint8_t arg)
+void
+BNE(uint16_t arg)
{
if (regs.status.zero == 0)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-bpl(uint8_t arg)
+void
+BPL(uint16_t arg)
{
if (regs.status.negative == 0)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-brk(void)
+void
+BRK(uint16_t arg)
{
/* TODO: push regs.pc and regs.status to stack and load IRQ vector */
regs.status.brk = 1;
// exit(0);
}
-static void
-bvc(uint8_t arg)
+void
+BVC(uint16_t arg)
{
//regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) == 0;
//if (regs.status.overflow == 0)
if ((STATUS_TO_INT() & (1 << 6)) == 0)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-bvs(uint8_t arg)
+void
+BVS(uint16_t arg)
{
regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) != 0;
if (regs.status.overflow == 1)
- regs.pc += arg;
+ regs.pc += arg, cycles++;
}
-static void
-clc(void)
+void
+CLC(uint16_t arg)
{
regs.status.carry = 0;
}
-static void
-cld(void)
+void
+CLD(uint16_t arg)
{
regs.status.decimal_mode = 0;
}
-static void
-cli(void)
+void
+CLI(uint16_t arg)
{
regs.status.interrupt_disable = 0;
}
-static void
-clv(void)
+void
+CLV(uint16_t arg)
{
regs.status.overflow = 0;
}
-static void
-cmp(uint8_t arg)
+void
+CMP(uint16_t arg)
{
uint8_t tmp;
@@ -361,8 +359,8 @@ cmp(uint8_t arg)
STATUS_UPDATE_NEGATIVE(tmp);
}
-static void
-cpx(uint8_t arg)
+void
+CPX(uint16_t arg)
{
uint8_t tmp;
@@ -373,8 +371,8 @@ cpx(uint8_t arg)
STATUS_UPDATE_NEGATIVE(tmp);
}
-static void
-cpy(uint8_t arg)
+void
+CPY(uint16_t arg)
{
uint8_t tmp;
@@ -385,70 +383,70 @@ cpy(uint8_t arg)
STATUS_UPDATE_NEGATIVE(tmp);
}
-static void
-dec(uint16_t mem)
+void
+DEC(uint16_t mem)
{
memwrite(mem, peek(mem) - 1);
STATUS_UPDATE_NZ(peek(mem));
}
-static void
-dex(void)
+void
+DEX(uint16_t arg)
{
regs.x--;
STATUS_UPDATE_NZ(regs.x);
}
-static void
-dey(void)
+void
+DEY(uint16_t arg)
{
regs.y--;
STATUS_UPDATE_NZ(regs.y);
}
-static void
-eor(uint8_t arg)
+void
+EOR(uint16_t arg)
{
regs.a ^= arg;
STATUS_UPDATE_NZ(regs.a);
}
-static void
-inc(uint16_t mem)
+void
+INC(uint16_t mem)
{
memwrite(mem, peek(mem) + 1);
STATUS_UPDATE_NZ(peek(mem));
}
-static void
-inx(void)
+void
+INX(uint16_t arg)
{
regs.x++;
STATUS_UPDATE_NZ(regs.x);
}
-static void
-iny(void)
+void
+INY(uint16_t arg)
{
regs.y++;
STATUS_UPDATE_NZ(regs.y);
}
-static void
-jmp(uint16_t arg)
+void
+JMP(uint16_t arg)
{
regs.pc = arg;
}
-static void
-jsr(uint16_t arg)
+void
+JSR(uint16_t arg)
{
uint16_t tmp = regs.pc - 1;
@@ -461,32 +459,32 @@ jsr(uint16_t arg)
regs.pc = arg;
}
-static void
-lda(uint8_t arg)
+void
+LDA(uint16_t arg)
{
regs.a = arg;
STATUS_UPDATE_NZ(regs.a);
}
-static void
-ldx(uint8_t arg)
+void
+LDX(uint16_t arg)
{
regs.x = arg;
STATUS_UPDATE_NZ(regs.x);
}
-static void
-ldy(uint8_t arg)
+void
+LDY(uint16_t arg)
{
regs.y = arg;
STATUS_UPDATE_NZ(regs.y);
}
-static void
-lsr_acc(void)
+void
+LSR_acc(uint16_t arg)
{
regs.status.carry = regs.a & 1; // bit 0 in carry
regs.a >>= 1;
@@ -495,8 +493,8 @@ lsr_acc(void)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-lsr(uint16_t mem)
+void
+LSR(uint16_t mem)
{
uint8_t tmp;
@@ -511,42 +509,42 @@ lsr(uint16_t mem)
STATUS_UPDATE_NZ(tmp);
}
-static void
-nop(void)
+void
+NOP(uint16_t arg)
{
return;
}
-static void
-ora(uint8_t arg)
+void
+ORA(uint16_t arg)
{
regs.a |= arg;
STATUS_UPDATE_NZ(regs.a);
}
-static void
-pha(void)
+void
+PHA(uint16_t arg)
{
PUSH(regs.a);
}
-static void
-php(void)
+void
+PHP(uint16_t arg)
{
PUSH(STATUS_TO_INT() | (1 << 4));
}
-static void
-pla(void)
+void
+PLA(uint16_t arg)
{
regs.a = PULL();
STATUS_UPDATE_NZ(regs.a);
}
-static void
-plp(void)
+void
+PLP(uint16_t arg)
{
uint8_t status;
@@ -562,8 +560,8 @@ plp(void)
regs.status.negative = (status & (1 << 7)) != 0;
}
-static void
-rol_acc(void)
+void
+ROL_acc(uint16_t arg)
{
uint8_t carry;
carry = (regs.a & (1 << 7)) != 0;
@@ -575,8 +573,8 @@ rol_acc(void)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-rol(uint16_t mem)
+void
+ROL(uint16_t mem)
{
uint8_t carry, tmp;
carry = (peek(mem) & (1 << 7)) != 0;
@@ -588,8 +586,8 @@ rol(uint16_t mem)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-ror_acc(void)
+void
+ROR_acc(uint16_t arg)
{
uint8_t carry;
carry = regs.a & 1;
@@ -601,8 +599,8 @@ ror_acc(void)
STATUS_UPDATE_NZ(regs.a);
}
-static void
-ror(uint16_t mem)
+void
+ROR(uint16_t mem)
{
uint8_t carry, tmp;
carry = peek(mem) & 1;
@@ -614,89 +612,83 @@ ror(uint16_t mem)
STATUS_UPDATE_NZ(tmp);
}
-static void
-rti(void)
+void
+RTI(uint16_t arg)
{
- plp();
+ PLP(0);
regs.pc = PULL() | (PULL() << 8);
}
-static void
-rts(void)
+void
+RTS(uint16_t arg)
{
regs.pc = (PULL() | (PULL() << 8)) + 1;
}
-static void
-sbc(uint8_t arg)
+void
+SBC(uint16_t arg)
{
/* SBC is described online as ADC with argument as two's complement */
- adc(~arg);
+ ADC(~(uint8_t)arg);
}
-static void
-sec(void)
+void
+SEC(uint16_t arg)
{
regs.status.carry = 1;
}
-static void
-sed(void)
+void
+SED(uint16_t arg)
{
regs.status.decimal_mode = 1;
}
-static void
-sei(void)
+void
+SEI(uint16_t arg)
{
regs.status.interrupt_disable = 1;
}
-static uint8_t
-sta(uint16_t mem)
+void
+STA(uint16_t mem)
{
uint8_t tmp = peek(mem);
memwrite(mem, regs.a);
-
- return tmp;
}
-static uint8_t
-stx(uint16_t mem)
+void
+STX(uint16_t mem)
{
uint8_t tmp = peek(mem);
memwrite(mem, regs.x);
-
- return tmp;
}
-static uint8_t
-sty(uint16_t mem)
+void
+STY(uint16_t mem)
{
uint8_t tmp = peek(mem);
memwrite(mem, regs.y);
-
- return tmp;
}
-static void
-tax(void)
+void
+TAX(uint16_t arg)
{
regs.x = regs.a;
STATUS_UPDATE_NZ(regs.x);
}
-static void
-tay(void)
+void
+TAY(uint16_t arg)
{
regs.y = regs.a;
STATUS_UPDATE_NZ(regs.y);
}
-static void
-tsx(void)
+void
+TSX(uint16_t arg)
{
// regs.x = PULL();
regs.x = regs.sp;
@@ -704,23 +696,23 @@ tsx(void)
STATUS_UPDATE_NZ(regs.x);
}
-static void
-txa(void)
+void
+TXA(uint16_t arg)
{
regs.a = regs.x;
STATUS_UPDATE_NZ(regs.a);
}
-static void
-txs(void)
+void
+TXS(uint16_t arg)
{
// PUSH(regs.x);
regs.sp = regs.x;
}
-static void
-tya(void)
+void
+TYA(uint16_t arg)
{
regs.a = regs.y;
@@ -730,1161 +722,68 @@ tya(void)
static void
interpret(void)
{
- uint8_t opcode, did_memwrite, ret, status;
+ uint8_t op;
uint16_t arg, mem, deref;
- uint32_t cycles_;
enum addressing_mode mode;
- struct registers regs_;
for (;;) {
- opcode = peek(regs.pc++);
- cycles_ = cycles;
- did_memwrite = 0;
- status = STATUS_TO_INT();
- regs_ = regs;
-
- printf("%04X %02X", regs.pc - 1, opcode);
-
- switch (opcode) {
- case 0x69:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 2;
- printf("ADC");
- break;
- case 0x65:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 3;
- printf("ADC");
- break;
- case 0x75:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 4;
- printf("ADC");
- break;
- case 0x6d:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 4;
- printf("ADC");
- break;
- case 0x7d:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 4;
- printf("ADC");
- break;
- case 0x79:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 4;
- printf("ADC");
- break;
- case 0x61:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 6;
- printf("ADC");
- break;
- case 0x71:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- adc(arg);
- cycles += 5;
- printf("ADC");
- break;
- case 0x29:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 2;
- printf("AND");
- break;
- case 0x25:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 3;
- printf("AND");
- break;
- case 0x35:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 4;
- printf("AND");
- break;
- case 0x2d:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 4;
- printf("AND");
- break;
- case 0x3d:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 4;
- printf("AND");
- break;
- case 0x39:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 4;
- printf("AND");
- break;
- case 0x21:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 6;
- printf("AND");
- break;
- case 0x31:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- and(arg);
- cycles += 5;
- printf("AND");
- break;
- case 0x0a:
- mode = AM_ACC;
- asl_acc();
- cycles += 2;
- printf("\tASL");
- break;
- case 0x06:
- mode = AM_ZP;
- arg = opcode_mem(mode);
- asl(arg);
- cycles += 5;
- printf("ASL");
- break;
- case 0x16:
- mode = AM_ZP_X;
- arg = opcode_mem(mode);
- asl(arg);
- cycles += 6;
- printf("ASL");
- break;
- case 0x0e:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- asl(arg);
- cycles += 6;
- printf("ASL");
- break;
- case 0x1e:
- mode = AM_ABS_X;
- arg = opcode_mem(mode);
- asl(arg);
- cycles += 6;
- printf("ASL");
- break;
- case 0x90:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bcc(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BCC");
- break;
- case 0xb0:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bcs(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BCS");
- break;
- case 0xf0:
- mode = AM_REL;
- arg = opcode_arg(mode);
- beq(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BEQ");
- break;
- case 0x89:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- did_memwrite = 1;
- ret = bit(arg);
- cycles += 2;
- printf("BIT");
- break;
- case 0x24:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- did_memwrite = 1;
- ret = bit(arg);
- cycles += 3;
- printf("BIT");
- break;
- case 0x34:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- did_memwrite = 1;
- ret = bit(arg);
- cycles += 4;
- printf("BIT");
- break;
- case 0x2c:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- did_memwrite = 1;
- ret = bit(arg);
- cycles += 4;
- printf("BIT");
- break;
- case 0x3c:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- did_memwrite = 1;
- ret = bit(arg);
- cycles += 4;
- printf("BIT");
- break;
- case 0x30:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bmi(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BMI");
- break;
- case 0xd0:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bne(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BNE");
- break;
- case 0x10:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bpl(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BPL");
- break;
- case 0x00:
- mode = AM_IMPLICIT;
- brk();
- cycles += 7;
- printf("\tBRK");
- goto loop_exit;
- case 0x50:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bvc(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BVC");
- break;
- case 0x70:
- mode = AM_REL;
- arg = opcode_arg(mode);
- bvs(arg);
- arg += regs_.pc + 1;
- cycles += 2;
- printf("BVS");
- break;
- case 0x18:
- mode = AM_IMPLICIT;
- clc();
- cycles += 2;
- printf("\tCLC");
- break;
- case 0xd8:
- mode = AM_IMPLICIT;
- cld();
- cycles += 2;
- printf("\tCLD");
- break;
- case 0x58:
- mode = AM_IMPLICIT;
- cli();
- cycles += 2;
- printf("\tCLI");
- break;
- case 0xb8:
- mode = AM_IMPLICIT;
- clv();
- cycles += 2;
- printf("\tCLV");
- break;
- case 0xc9:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 2;
- printf("CMP");
- break;
- case 0xc5:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 3;
- printf("CMP");
- break;
- case 0xd5:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 4;
- printf("CMP");
- break;
- case 0xcd:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 4;
- printf("CMP");
- break;
- case 0xdd:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 4;
- printf("CMP");
- break;
- case 0xd9:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 4;
- printf("CMP");
- break;
- case 0xc1:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 6;
- printf("CMP");
- break;
- case 0xd1:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- cmp(arg);
- cycles += 5;
- printf("CMP");
- break;
- case 0xe0:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- cpx(arg);
- cycles += 2;
- printf("CPX");
- break;
- case 0xe4:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- cpx(arg);
- cycles += 3;
- printf("CPX");
- break;
- case 0xec:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- cpx(arg);
- cycles += 4;
- printf("CPX");
- break;
- case 0xc0:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- cpy(arg);
- cycles += 2;
- printf("CPY");
- break;
- case 0xc4:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- cpy(arg);
- cycles += 3;
- printf("CPY");
- break;
- case 0xcc:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- cpy(arg);
- cycles += 4;
- printf("CPY");
- break;
- case 0xc6:
- mode = AM_ZP;
- arg = opcode_mem(mode);
- dec(arg);
- cycles += 5;
- printf("DEC");
- break;
- case 0xd6:
- mode = AM_ZP_X;
- arg = opcode_mem(mode);
- dec(arg);
- cycles += 6;
- printf("DEC");
- break;
- case 0xce:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- dec(arg);
- cycles += 6;
- printf("DEC");
- break;
- case 0xde:
- mode = AM_ABS_X;
- arg = opcode_mem(mode);
- dec(arg);
- cycles += 7;
- printf("DEC");
- break;
- case 0xca:
- mode = AM_IMPLICIT;
- dex();
- cycles += 2;
- printf("\tDEX");
- break;
- case 0x88:
- mode = AM_IMPLICIT;
- dey();
- cycles += 2;
- printf("\tDEY");
- break;
- case 0x49:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 2;
- printf("EOR");
- break;
- case 0x45:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 3;
- printf("EOR");
- break;
- case 0x55:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 4;
- printf("EOR");
- break;
- case 0x4d:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 4;
- printf("EOR");
- break;
- case 0x5d:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 4;
- printf("EOR");
- break;
- case 0x59:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 4;
- printf("EOR");
- break;
- case 0x41:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 6;
- printf("EOR");
- break;
- case 0x51:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- eor(arg);
- cycles += 5;
- printf("EOR");
- break;
- case 0xe6:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- inc(arg);
- cycles += 5;
- printf("INC");
- break;
- case 0xf6:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- inc(arg);
- cycles += 6;
- printf("INC");
- break;
- case 0xee:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- inc(arg);
- cycles += 6;
- printf("INC");
- break;
- case 0xfe:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- inc(arg);
- cycles += 7;
- printf("INC");
- break;
- case 0xe8:
- mode = AM_IMPLICIT;
- inx();
- cycles += 2;
- printf("\tINX");
- break;
- case 0xc8:
- mode = AM_IMPLICIT;
- iny();
- cycles += 2;
- printf("\tINY");
- break;
- case 0x4c:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- jmp(arg);
- cycles += 3;
- printf("JMP");
- break;
- case 0x6c:
- mode = AM_IND;
- mem = peek16(regs.pc);
- deref = peek16(mem);
- arg = opcode_mem(mode);
- deref = arg;
- jmp(arg);
- cycles += 6;
- printf("JMP");
- break;
- case 0x7c:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- jmp(arg);
- cycles += 6;
- printf("JMP");
- break;
- case 0x20:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- jsr(arg);
- cycles += 6;
- printf("JSR");
- break;
- case 0xa9:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 2;
- printf("LDA");
- break;
- case 0xa5:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 3;
- printf("LDA");
- break;
- case 0xb5:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 4;
- printf("LDA");
- break;
- case 0xad:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 4;
- printf("LDA");
- break;
- case 0xbd:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 4;
- printf("LDA");
- break;
- case 0xb9:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 4;
- printf("LDA");
- break;
- case 0xa1:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 6;
- printf("LDA");
- break;
- case 0xb1:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- lda(arg);
- cycles += 5;
- printf("LDA");
- break;
- case 0xa2:
- mode = AM_IMM;
- arg = opcode_mem(mode);
- ldx(arg);
- cycles += 2;
- printf("LDX");
- break;
- case 0xa6:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- ldx(arg);
- cycles += 3;
- printf("LDX");
- break;
- case 0xb6:
- mode = AM_ZP_Y;
- arg = opcode_arg(mode);
- ldx(arg);
- cycles += 4;
- printf("LDX");
- break;
- case 0xae:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- ldx(arg);
- cycles += 4;
- printf("LDX");
- break;
- case 0xbe:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- ldx(arg);
- cycles += 4;
- printf("LDX");
- break;
- case 0xa0:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- ldy(arg);
- cycles += 2;
- printf("LDY");
- break;
- case 0xa4:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- ldy(arg);
- cycles += 3;
- printf("LDY");
- break;
- case 0xb4:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- ldy(arg);
- cycles += 4;
- printf("LDY");
- break;
- case 0xac:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- ldy(arg);
- cycles += 4;
- printf("LDY");
- break;
- case 0xbc:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- ldy(arg);
- cycles += 4;
- printf("LDY");
- break;
- case 0x4a:
- mode = AM_ACC;
- lsr_acc();
- cycles += 2;
- printf("\tLSR");
- break;
- case 0x46:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- lsr(arg);
- cycles += 5;
- printf("LSR");
- break;
- case 0x56:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- lsr(arg);
- cycles += 6;
- printf("LSR");
- break;
- case 0x4e:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- lsr(arg);
- cycles += 6;
- printf("LSR");
- break;
- case 0x5e:
- mode = AM_ABS_X;
- arg = opcode_mem(mode);
- lsr(arg);
- cycles += 6;
- printf("LSR");
- break;
- case 0xea:
- mode = AM_IMPLICIT;
- nop();
- cycles += 2;
- printf("\tNOP");
- break;
- case 0x09:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 2;
- printf("ORA");
- break;
- case 0x05:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 3;
- printf("ORA");
- break;
- case 0x15:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 4;
- printf("ORA");
- break;
- case 0x0d:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 4;
- printf("ORA");
- break;
- case 0x1d:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 4;
- printf("ORA");
- break;
- case 0x19:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 4;
- printf("ORA");
- break;
- case 0x01:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 6;
- printf("ORA");
- break;
- case 0x11:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- ora(arg);
- cycles += 5;
- printf("ORA");
- break;
- case 0x48:
- mode = AM_IMPLICIT;
- pha();
- cycles += 3;
- printf("\tPHA");
- break;
- case 0x08:
- mode = AM_IMPLICIT;
- php();
- cycles += 3;
- printf("\tPHP");
- break;
- case 0x68:
- mode = AM_IMPLICIT;
- pla();
- cycles += 4;
- printf("\tPLA");
- break;
- case 0x28:
- mode = AM_IMPLICIT;
- plp();
- cycles += 4;
- printf("\tPLP");
- break;
- case 0x2a:
- mode = AM_ACC;
- rol_acc();
- cycles += 2;
- printf("\tROL");
- break;
- case 0x26:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- rol(arg);
- cycles += 5;
- printf("ROL");
- break;
- case 0x36:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- rol(arg);
- cycles += 6;
- printf("ROL");
- break;
- case 0x2e:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- rol(arg);
- cycles += 6;
- printf("ROL");
- break;
- case 0x3e:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- rol(arg);
- cycles += 6;
- printf("ROL");
- break;
- case 0x6a:
- mode = AM_ACC;
- ror_acc();
- cycles += 2;
- printf("\tROR");
- break;
- case 0x66:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- ror(arg);
- cycles += 5;
- printf("ROR");
- break;
- case 0x76:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- ror(arg);
- cycles += 6;
- printf("ROR");
- break;
- case 0x6e:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- ror(arg);
- cycles += 6;
- printf("ROR");
- break;
- case 0x7e:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- ror(arg);
- cycles += 6;
- printf("ROR");
- break;
- case 0x40:
- mode = AM_IMPLICIT;
- rti();
- cycles += 6;
- printf("\tRTI");
- break;
- case 0x60:
- mode = AM_IMPLICIT;
- rts();
- cycles += 6;
- printf("\tRTS");
- break;
- case 0xe9:
- mode = AM_IMM;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 2;
- printf("SBC");
- break;
- case 0xe5:
- mode = AM_ZP;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 3;
- printf("SBC");
- break;
- case 0xf5:
- mode = AM_ZP_X;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 4;
- printf("SBC");
- break;
- case 0xed:
- mode = AM_ABS;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 4;
- printf("SBC");
- break;
- case 0xfd:
- mode = AM_ABS_X;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 4;
- printf("SBC");
- break;
- case 0xf9:
- mode = AM_ABS_Y;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 4;
- printf("SBC");
- break;
- case 0xe1:
- mode = AM_IND_X;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 6;
- printf("SBC");
- break;
- case 0xf1:
- mode = AM_IND_Y;
- arg = opcode_arg(mode);
- sbc(arg);
- cycles += 5;
- printf("SBC");
- break;
- case 0x38:
- mode = AM_IMPLICIT;
- sec();
- cycles += 2;
- printf("\tSEC");
- break;
- case 0xf8:
- mode = AM_IMPLICIT;
- sed();
- cycles += 2;
- printf("\tSED");
- break;
- case 0x78:
- mode = AM_IMPLICIT;
- sei();
- cycles += 2;
- printf("\tSEI");
- break;
- case 0x85:
- mode = AM_ZP;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 4;
- printf("STA");
- break;
- case 0x95:
- mode = AM_ZP_X;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 5;
- printf("STA");
- break;
- case 0x8d:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 5;
- printf("STA");
- break;
- case 0x9d:
- mode = AM_ABS_X;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 6;
- printf("STA");
- break;
- case 0x99:
- mode = AM_ABS_Y;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 6;
- printf("STA");
- break;
- case 0x81:
- mode = AM_IND_X;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 7;
- printf("STA");
- break;
- case 0x91:
- mode = AM_IND_Y;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sta(arg);
- cycles += 7;
- printf("STA");
- break;
- case 0x86:
- mode = AM_ZP;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = stx(arg);
- cycles += 4;
- printf("STX");
- break;
- case 0x96:
- mode = AM_ZP_Y;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = stx(arg);
- cycles += 5;
- printf("STX");
- break;
- case 0x8e:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = stx(arg);
- cycles += 5;
- printf("STX");
- break;
- case 0x84:
- mode = AM_ZP;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sty(arg);
- cycles += 4;
- printf("STY");
- break;
- case 0x94:
- mode = AM_ZP_X;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sty(arg);
- cycles += 5;
- printf("STY");
- break;
- case 0x8c:
- mode = AM_ABS;
- arg = opcode_mem(mode);
- did_memwrite = 1;
- ret = sty(arg);
- cycles += 5;
- printf("STY");
- break;
- case 0xaa:
- mode = AM_IMPLICIT;
- tax();
- cycles += 2;
- printf("\tTAX");
- break;
- case 0xa8:
- mode = AM_IMPLICIT;
- tay();
- cycles += 2;
- printf("\tTAY");
- break;
- case 0xba:
- mode = AM_IMPLICIT;
- tsx();
- cycles += 2;
- printf("\tTSX");
- break;
- case 0x8a:
- mode = AM_IMPLICIT;
- txa();
- cycles += 2;
- printf("\tTXA");
- break;
- case 0x9a:
- mode = AM_IMPLICIT;
- txs();
- cycles += 2;
- printf("\tTXS");
- break;
- case 0x98:
- mode = AM_IMPLICIT;
- tya();
- cycles += 2;
- printf("\tTYA");
- break;
- default:
- printf("opcode $%02X not implemented\n", opcode);
- break;
- }
+ printf("%04X ", regs.pc);
+
+ op = peek(regs.pc++);
+
+ printf("%02X", op);
+ for (uint8_t i = 0; i < opcodes[op].bytes - 1; i++)
+ printf(" %02X", peek(regs.pc + i));
+ printf("\t%s ", opcodes[op].name);
+
+ mode = opcodes[op].mode;
+ arg = opcode_mem(mode);
switch (mode) {
case AM_IMM:
- printf(" #$%02X", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t");
+ printf("#$%02X", arg);
break;
case AM_ZP:
- printf(" $%02X", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t\t");
+ printf("$%02X", arg);
break;
case AM_ZP_X:
- printf(" $%02X,X", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t");
+ printf("$%02X,X", arg);
break;
case AM_ZP_Y:
- printf(" $%02X,Y", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t\t");
+ printf("$%02X,Y", arg);
break;
case AM_REL:
+ printf("$%04X", regs.pc + arg);
+ break;
case AM_ABS:
- printf(" $%04X", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t");
+ printf("$%04X", arg);
break;
case AM_ABS_X:
- printf(" $%04X,X", arg);
- if (did_memwrite) printf(" = %02X\t\t", ret);
- else printf("\t\t\t");
+ printf("$%04X,X", arg);
break;
case AM_ABS_Y:
- printf(" $%04X,Y", arg);
- if (did_memwrite) printf(" = %02X\t\t\t", ret);
- else printf("\t\t\t");
+ printf("$%04X,Y", arg);
break;
case AM_IND:
- printf(" ($%04X) = %04X\t\t", mem, deref);
+ printf("($%04X) = %04X\t\t", arg, peek16(arg));
break;
case AM_ACC:
- case AM_IMPLICIT:
+ case AM_NONE:
+ putchar('\t');
+ break;
default:
printf("\t\t\t\t");
break;
}
- printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n",
- regs_.a, regs_.x, regs_.y, status, regs_.sp, cycles_);
+ if (opcodes[op].didmemory) printf(" = %02X", peek(arg));
+ printf("\t\t\t");
+
+ printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d %08b\n",
+ regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp, cycles, STATUS_TO_INT());
+
+ opcodes[op].instr(arg);
+ cycles += opcodes[op].cycles;
}
loop_exit:
}
diff --git a/opcodes.h b/opcodes.h
index defc427..ef57ab0 100644
--- a/opcodes.h
+++ b/opcodes.h
@@ -1,3 +1,4 @@
+#include <stdbool.h>
#include <stdint.h>
#include "cpu.h"
@@ -25,160 +26,161 @@ struct opcode {
void (*instr)(uint16_t arg);
uint8_t bytes;
uint8_t cycles;
+ bool didmemory;
enum addressing_mode mode;
};
struct opcode opcodes[0x100] = {
/* official opcodes */
- [0x69] = { "ADC", ADC, 2, 2, AM_IMM },
- [0x65] = { "ADC", ADC, 2, 3, AM_ZP },
- [0x75] = { "ADC", ADC, 2, 4, AM_ZP_X },
- [0x6D] = { "ADC", ADC, 3, 4, AM_ABS },
- [0x7D] = { "ADC", ADC, 3, 4, AM_ABS_X },
- [0x79] = { "ADC", ADC, 3, 4, AM_ABS_Y },
- [0x61] = { "ADC", ADC, 2, 6, AM_IND_X },
- [0x71] = { "ADC", ADC, 2, 5, AM_IND_Y },
- [0x29] = { "AND", AND, 2, 2, AM_IMM },
- [0x25] = { "AND", AND, 2, 3, AM_ZP },
- [0x35] = { "AND", AND, 2, 4, AM_ZP_X },
- [0x2D] = { "AND", AND, 3, 4, AM_ABS },
- [0x3D] = { "AND", AND, 3, 4, AM_ABS_X },
- [0x39] = { "AND", AND, 3, 4, AM_ABS_Y },
- [0x21] = { "AND", AND, 2, 6, AM_IND_X },
- [0x31] = { "AND", AND, 2, 5, AM_IND_Y },
- [0x0A] = { "ASL", ASL_acc, 1, 2, AM_ACC },
- [0x06] = { "ASL", ASL, 2, 5, AM_ZP },
- [0x16] = { "ASL", ASL, 2, 6, AM_ZP_X },
- [0x0E] = { "ASL", ASL, 3, 6, AM_ABS },
- [0x1E] = { "ASL", ASL, 3, 7, AM_ABS_X },
- [0x90] = { "BCC", BCC, 2, 2, AM_REL },
- [0xB0] = { "BCS", BCS, 2, 2, AM_REL },
- [0xF0] = { "BEQ", BEQ, 2, 2, AM_REL },
- [0x24] = { "BIT", BIT, 2, 3, AM_ZP },
- [0x2C] = { "BIT", BIT, 3, 4, AM_ABS },
- [0x30] = { "BMI", BMI, 2, 2, AM_REL },
- [0xD0] = { "BNE", BNE, 2, 2, AM_REL },
- [0x10] = { "BPL", BPL, 2, 2, AM_REL },
- [0x00] = { "BRK", BRK, 1, 7, AM_NONE },
- [0x50] = { "BVC", BVC, 2, 2, AM_REL },
- [0x70] = { "BVS", BVS, 2, 2, AM_REL },
- [0x18] = { "CLC", CLC, 1, 2, AM_NONE },
- [0xD8] = { "CLD", CLD, 1, 2, AM_NONE },
- [0x58] = { "CLI", CLI, 1, 2, AM_NONE },
- [0xB8] = { "CLV", CLV, 1, 2, AM_NONE },
- [0xC9] = { "CMP", CMP, 2, 2, AM_IMM },
- [0xC5] = { "CMP", CMP, 2, 3, AM_ZP },
- [0xD5] = { "CMP", CMP, 2, 4, AM_ZP_X },
- [0xCD] = { "CMP", CMP, 3, 4, AM_ABS },
- [0xDD] = { "CMP", CMP, 3, 4, AM_ABS_X },
- [0xD9] = { "CMP", CMP, 3, 4, AM_ABS_Y },
- [0xC1] = { "CMP", CMP, 2, 6, AM_IND_X },
- [0xD1] = { "CMP", CMP, 2, 5, AM_IND_Y },
- [0xE0] = { "CPX", CPX, 2, 2, AM_IMM },
- [0xE4] = { "CPX", CPX, 2, 3, AM_ZP },
- [0xEC] = { "CPX", CPX, 3, 4, AM_ABS },
- [0xC0] = { "CPY", CPY, 2, 2, AM_IMM },
- [0xC4] = { "CPY", CPY, 2, 3, AM_ZP },
- [0xCC] = { "CPY", CPY, 3, 4, AM_ABS },
- [0xC6] = { "DEC", DEC, 2, 5, AM_ZP },
- [0xD6] = { "DEC", DEC, 2, 6, AM_ZP_X },
- [0xCE] = { "DEC", DEC, 3, 6, AM_ABS },
- [0xDE] = { "DEC", DEC, 3, 7, AM_ABS_X },
- [0xCA] = { "DEX", DEX, 1, 2, AM_NONE },
- [0x88] = { "DEY", DEY, 1, 2, AM_NONE },
- [0x49] = { "EOR", EOR, 2, 2, AM_IMM },
- [0x45] = { "EOR", EOR, 2, 3, AM_ZP },
- [0x55] = { "EOR", EOR, 2, 4, AM_ZP_X },
- [0x4D] = { "EOR", EOR, 3, 4, AM_ABS },
- [0x5D] = { "EOR", EOR, 3, 4, AM_ABS_X },
- [0x59] = { "EOR", EOR, 3, 4, AM_ABS_Y },
- [0x41] = { "EOR", EOR, 2, 6, AM_IND_X },
- [0x51] = { "EOR", EOR, 2, 5, AM_IND_Y },
- [0xE6] = { "INC", INC, 2, 5, AM_ZP },
- [0xF6] = { "INC", INC, 2, 6, AM_ZP_X },
- [0xEE] = { "INC", INC, 3, 6, AM_ABS },
- [0xFE] = { "INC", INC, 3, 7, AM_ABS_X },
- [0xE8] = { "INX", INX, 1, 2, AM_NONE },
- [0xC8] = { "INY", INY, 1, 2, AM_NONE },
- [0x4C] = { "JMP", JMP, 3, 3, AM_ABS },
- [0x6C] = { "JMP", JMP, 3, 5, AM_IND },
- [0x20] = { "JSR", JSR, 3, 6, AM_ABS },
- [0xA9] = { "LDA", LDA, 2, 2, AM_IMM },
- [0xA5] = { "LDA", LDA, 2, 3, AM_ZP },
- [0xB5] = { "LDA", LDA, 2, 4, AM_ZP_X },
- [0xAD] = { "LDA", LDA, 3, 4, AM_ABS },
- [0xBD] = { "LDA", LDA, 3, 4, AM_ABS_X },
- [0xB9] = { "LDA", LDA, 3, 4, AM_ABS_Y },
- [0xA1] = { "LDA", LDA, 2, 6, AM_IND_X },
- [0xB1] = { "LDA", LDA, 2, 5, AM_IND_Y },
- [0xA2] = { "LDX", LDX, 2, 2, AM_IMM },
- [0xA6] = { "LDX", LDX, 2, 3, AM_ZP },
- [0xB6] = { "LDX", LDX, 2, 4, AM_ZP_Y },
- [0xAE] = { "LDX", LDX, 3, 4, AM_ABS },
- [0xBE] = { "LDX", LDX, 3, 4, AM_ABS_Y },
- [0xA0] = { "LDY", LDY, 2, 2, AM_IMM },
- [0xA4] = { "LDY", LDY, 2, 3, AM_ZP },
- [0xB4] = { "LDY", LDY, 2, 4, AM_ZP_X },
- [0xAC] = { "LDY", LDY, 3, 4, AM_ABS },
- [0xBC] = { "LDY", LDY, 3, 4, AM_ABS_X },
- [0x4A] = { "LSR", LSR_acc, 1, 2, AM_ACC },
- [0x46] = { "LSR", LSR, 2, 5, AM_ZP },
- [0x56] = { "LSR", LSR, 2, 6, AM_ZP_X },
- [0x4E] = { "LSR", LSR, 3, 6, AM_ABS },
- [0x5E] = { "LSR", LSR, 3, 7, AM_ABS_X },
- [0xEA] = { "NOP", NOP, 1, 2, AM_NONE },
- [0x09] = { "ORA", ORA, 2, 2, AM_IMM },
- [0x05] = { "ORA", ORA, 2, 3, AM_ZP },
- [0x15] = { "ORA", ORA, 2, 4, AM_ZP_X },
- [0x0D] = { "ORA", ORA, 3, 4, AM_ABS },
- [0x1D] = { "ORA", ORA, 3, 4, AM_ABS_X },
- [0x19] = { "ORA", ORA, 3, 4, AM_ABS_Y },
- [0x01] = { "ORA", ORA, 2, 6, AM_IND_X },
- [0x11] = { "ORA", ORA, 2, 5, AM_IND_Y },
- [0x48] = { "PHA", PHA, 1, 3, AM_NONE },
- [0x08] = { "PHP", PHP, 1, 3, AM_NONE },
- [0x68] = { "PLA", PLA, 1, 4, AM_NONE },
- [0x28] = { "PLP", PLP, 1, 4, AM_NONE },
- [0x2A] = { "ROL", ROL_acc, 1, 2, AM_ACC },
- [0x26] = { "ROL", ROL, 2, 5, AM_ZP },
- [0x36] = { "ROL", ROL, 2, 6, AM_ZP_X },
- [0x2E] = { "ROL", ROL, 3, 6, AM_ABS },
- [0x3E] = { "ROL", ROL, 3, 7, AM_ABS_X },
- [0x6A] = { "ROR", ROR_acc, 1, 2, AM_ACC },
- [0x66] = { "ROR", ROR, 2, 5, AM_ZP },
- [0x76] = { "ROR", ROR, 2, 6, AM_ZP_X },
- [0x6E] = { "ROR", ROR, 3, 6, AM_ABS },
- [0x7E] = { "ROR", ROR, 3, 7, AM_ABS_X },
- [0x40] = { "RTI", RTI, 1, 6, AM_NONE },
- [0x60] = { "RTS", RTS, 1, 6, AM_NONE },
- [0xE9] = { "SBC", SBC, 2, 2, AM_IMM },
- [0xE5] = { "SBC", SBC, 2, 3, AM_ZP },
- [0xF5] = { "SBC", SBC, 2, 4, AM_ZP_X },
- [0xED] = { "SBC", SBC, 3, 4, AM_ABS },
- [0xFD] = { "SBC", SBC, 3, 4, AM_ABS_X },
- [0xF9] = { "SBC", SBC, 3, 4, AM_ABS_Y },
- [0xE1] = { "SBC", SBC, 2, 6, AM_IND_X },
- [0xF1] = { "SBC", SBC, 2, 5, AM_IND_Y },
- [0x38] = { "SEC", SEC, 1, 2, AM_NONE },
- [0xF8] = { "SED", SED, 1, 2, AM_NONE },
- [0x78] = { "SEI", SEI, 1, 2, AM_NONE },
- [0x85] = { "STA", STA, 2, 3, AM_ZP },
- [0x95] = { "STA", STA, 2, 4, AM_ZP_X },
- [0x8D] = { "STA", STA, 3, 4, AM_ABS },
- [0x9D] = { "STA", STA, 3, 5, AM_ABS_X },
- [0x99] = { "STA", STA, 3, 5, AM_ABS_Y },
- [0x81] = { "STA", STA, 2, 6, AM_IND_X },
- [0x91] = { "STA", STA, 2, 6, AM_IND_Y },
- [0x86] = { "STX", STX, 2, 3, AM_ZP },
- [0x96] = { "STX", STX, 2, 4, AM_ZP_Y },
- [0x8E] = { "STX", STX, 3, 4, AM_ABS },
- [0x84] = { "STY", STY, 2, 3, AM_ZP },
- [0x94] = { "STY", STY, 2, 4, AM_ZP_X },
- [0x8C] = { "STY", STY, 3, 4, AM_ABS },
- [0xAA] = { "TAX", TAX, 1, 2, AM_NONE },
- [0xA8] = { "TAY", TAY, 1, 2, AM_NONE },
- [0xBA] = { "TSX", TSX, 1, 2, AM_NONE },
- [0x8A] = { "TXA", TXA, 1, 2, AM_NONE },
- [0x9A] = { "TXS", TXS, 1, 2, AM_NONE },
- [0x98] = { "TYA", TYA, 1, 2, AM_NONE },
+ [0x69] = { "ADC", ADC, 2, 2, false, AM_IMM },
+ [0x65] = { "ADC", ADC, 2, 3, false, AM_ZP },
+ [0x75] = { "ADC", ADC, 2, 4, false, AM_ZP_X },
+ [0x6D] = { "ADC", ADC, 3, 4, false, AM_ABS },
+ [0x7D] = { "ADC", ADC, 3, 4, false, AM_ABS_X },
+ [0x79] = { "ADC", ADC, 3, 4, false, AM_ABS_Y },
+ [0x61] = { "ADC", ADC, 2, 6, false, AM_IND_X },
+ [0x71] = { "ADC", ADC, 2, 5, false, AM_IND_Y },
+ [0x29] = { "AND", AND, 2, 2, false, AM_IMM },
+ [0x25] = { "AND", AND, 2, 3, false, AM_ZP },
+ [0x35] = { "AND", AND, 2, 4, false, AM_ZP_X },
+ [0x2D] = { "AND", AND, 3, 4, false, AM_ABS },
+ [0x3D] = { "AND", AND, 3, 4, false, AM_ABS_X },
+ [0x39] = { "AND", AND, 3, 4, false, AM_ABS_Y },
+ [0x21] = { "AND", AND, 2, 6, false, AM_IND_X },
+ [0x31] = { "AND", AND, 2, 5, false, AM_IND_Y },
+ [0x0A] = { "ASL", ASL_acc, 1, 2, false, AM_ACC },
+ [0x06] = { "ASL", ASL, 2, 5, true, AM_ZP },
+ [0x16] = { "ASL", ASL, 2, 6, true, AM_ZP_X },
+ [0x0E] = { "ASL", ASL, 3, 6, true, AM_ABS },
+ [0x1E] = { "ASL", ASL, 3, 7, true, AM_ABS_X },
+ [0x90] = { "BCC", BCC, 2, 2, false, AM_REL },
+ [0xB0] = { "BCS", BCS, 2, 2, false, AM_REL },
+ [0xF0] = { "BEQ", BEQ, 2, 2, false, AM_REL },
+ [0x24] = { "BIT", BIT, 2, 3, true, AM_ZP },
+ [0x2C] = { "BIT", BIT, 3, 4, true, AM_ABS },
+ [0x30] = { "BMI", BMI, 2, 2, false, AM_REL },
+ [0xD0] = { "BNE", BNE, 2, 2, false, AM_REL },
+ [0x10] = { "BPL", BPL, 2, 2, false, AM_REL },
+ [0x00] = { "BRK", BRK, 1, 7, false, AM_NONE },
+ [0x50] = { "BVC", BVC, 2, 2, false, AM_REL },
+ [0x70] = { "BVS", BVS, 2, 2, false, AM_REL },
+ [0x18] = { "CLC", CLC, 1, 2, false, AM_NONE },
+ [0xD8] = { "CLD", CLD, 1, 2, false, AM_NONE },
+ [0x58] = { "CLI", CLI, 1, 2, false, AM_NONE },
+ [0xB8] = { "CLV", CLV, 1, 2, false, AM_NONE },
+ [0xC9] = { "CMP", CMP, 2, 2, false, AM_IMM },
+ [0xC5] = { "CMP", CMP, 2, 3, false, AM_ZP },
+ [0xD5] = { "CMP", CMP, 2, 4, false, AM_ZP_X },
+ [0xCD] = { "CMP", CMP, 3, 4, false, AM_ABS },
+ [0xDD] = { "CMP", CMP, 3, 4, false, AM_ABS_X },
+ [0xD9] = { "CMP", CMP, 3, 4, false, AM_ABS_Y },
+ [0xC1] = { "CMP", CMP, 2, 6, false, AM_IND_X },
+ [0xD1] = { "CMP", CMP, 2, 5, false, AM_IND_Y },
+ [0xE0] = { "CPX", CPX, 2, 2, false, AM_IMM },
+ [0xE4] = { "CPX", CPX, 2, 3, false, AM_ZP },
+ [0xEC] = { "CPX", CPX, 3, 4, false, AM_ABS },
+ [0xC0] = { "CPY", CPY, 2, 2, false, AM_IMM },
+ [0xC4] = { "CPY", CPY, 2, 3, false, AM_ZP },
+ [0xCC] = { "CPY", CPY, 3, 4, false, AM_ABS },
+ [0xC6] = { "DEC", DEC, 2, 5, true, AM_ZP },
+ [0xD6] = { "DEC", DEC, 2, 6, true, AM_ZP_X },
+ [0xCE] = { "DEC", DEC, 3, 6, true, AM_ABS },
+ [0xDE] = { "DEC", DEC, 3, 7, true, AM_ABS_X },
+ [0xCA] = { "DEX", DEX, 1, 2, false, AM_NONE },
+ [0x88] = { "DEY", DEY, 1, 2, false, AM_NONE },
+ [0x49] = { "EOR", EOR, 2, 2, false, AM_IMM },
+ [0x45] = { "EOR", EOR, 2, 3, false, AM_ZP },
+ [0x55] = { "EOR", EOR, 2, 4, false, AM_ZP_X },
+ [0x4D] = { "EOR", EOR, 3, 4, false, AM_ABS },
+ [0x5D] = { "EOR", EOR, 3, 4, false, AM_ABS_X },
+ [0x59] = { "EOR", EOR, 3, 4, false, AM_ABS_Y },
+ [0x41] = { "EOR", EOR, 2, 6, false, AM_IND_X },
+ [0x51] = { "EOR", EOR, 2, 5, false, AM_IND_Y },
+ [0xE6] = { "INC", INC, 2, 5, true, AM_ZP },
+ [0xF6] = { "INC", INC, 2, 6, true, AM_ZP_X },
+ [0xEE] = { "INC", INC, 3, 6, true, AM_ABS },
+ [0xFE] = { "INC", INC, 3, 7, true, AM_ABS_X },
+ [0xE8] = { "INX", INX, 1, 2, false, AM_NONE },
+ [0xC8] = { "INY", INY, 1, 2, false, AM_NONE },
+ [0x4C] = { "JMP", JMP, 3, 3, false, AM_ABS },
+ [0x6C] = { "JMP", JMP, 3, 5, false, AM_IND },
+ [0x20] = { "JSR", JSR, 3, 6, false, AM_ABS },
+ [0xA9] = { "LDA", LDA, 2, 2, false, AM_IMM },
+ [0xA5] = { "LDA", LDA, 2, 3, false, AM_ZP },
+ [0xB5] = { "LDA", LDA, 2, 4, false, AM_ZP_X },
+ [0xAD] = { "LDA", LDA, 3, 4, false, AM_ABS },
+ [0xBD] = { "LDA", LDA, 3, 4, false, AM_ABS_X },
+ [0xB9] = { "LDA", LDA, 3, 4, false, AM_ABS_Y },
+ [0xA1] = { "LDA", LDA, 2, 6, false, AM_IND_X },
+ [0xB1] = { "LDA", LDA, 2, 5, false, AM_IND_Y },
+ [0xA2] = { "LDX", LDX, 2, 2, false, AM_IMM },
+ [0xA6] = { "LDX", LDX, 2, 3, true, AM_ZP },
+ [0xB6] = { "LDX", LDX, 2, 4, false, AM_ZP_Y },
+ [0xAE] = { "LDX", LDX, 3, 4, true, AM_ABS },
+ [0xBE] = { "LDX", LDX, 3, 4, false, AM_ABS_Y },
+ [0xA0] = { "LDY", LDY, 2, 2, false, AM_IMM },
+ [0xA4] = { "LDY", LDY, 2, 3, false, AM_ZP },
+ [0xB4] = { "LDY", LDY, 2, 4, false, AM_ZP_X },
+ [0xAC] = { "LDY", LDY, 3, 4, false, AM_ABS },
+ [0xBC] = { "LDY", LDY, 3, 4, false, AM_ABS_X },
+ [0x4A] = { "LSR", LSR_acc, 1, 2, false, AM_ACC },
+ [0x46] = { "LSR", LSR, 2, 5, true, AM_ZP },
+ [0x56] = { "LSR", LSR, 2, 6, true, AM_ZP_X },
+ [0x4E] = { "LSR", LSR, 3, 6, true, AM_ABS },
+ [0x5E] = { "LSR", LSR, 3, 7, true, AM_ABS_X },
+ [0xEA] = { "NOP", NOP, 1, 2, false, AM_NONE },
+ [0x09] = { "ORA", ORA, 2, 2, false, AM_IMM },
+ [0x05] = { "ORA", ORA, 2, 3, false, AM_ZP },
+ [0x15] = { "ORA", ORA, 2, 4, false, AM_ZP_X },
+ [0x0D] = { "ORA", ORA, 3, 4, false, AM_ABS },
+ [0x1D] = { "ORA", ORA, 3, 4, false, AM_ABS_X },
+ [0x19] = { "ORA", ORA, 3, 4, false, AM_ABS_Y },
+ [0x01] = { "ORA", ORA, 2, 6, false, AM_IND_X },
+ [0x11] = { "ORA", ORA, 2, 5, false, AM_IND_Y },
+ [0x48] = { "PHA", PHA, 1, 3, false, AM_NONE },
+ [0x08] = { "PHP", PHP, 1, 3, false, AM_NONE },
+ [0x68] = { "PLA", PLA, 1, 4, false, AM_NONE },
+ [0x28] = { "PLP", PLP, 1, 4, false, AM_NONE },
+ [0x2A] = { "ROL", ROL_acc, 1, 2, false, AM_ACC },
+ [0x26] = { "ROL", ROL, 2, 5, true, AM_ZP },
+ [0x36] = { "ROL", ROL, 2, 6, true, AM_ZP_X },
+ [0x2E] = { "ROL", ROL, 3, 6, true, AM_ABS },
+ [0x3E] = { "ROL", ROL, 3, 7, true, AM_ABS_X },
+ [0x6A] = { "ROR", ROR_acc, 1, 2, false, AM_ACC },
+ [0x66] = { "ROR", ROR, 2, 5, true, AM_ZP },
+ [0x76] = { "ROR", ROR, 2, 6, true, AM_ZP_X },
+ [0x6E] = { "ROR", ROR, 3, 6, true, AM_ABS },
+ [0x7E] = { "ROR", ROR, 3, 7, true, AM_ABS_X },
+ [0x40] = { "RTI", RTI, 1, 6, false, AM_NONE },
+ [0x60] = { "RTS", RTS, 1, 6, false, AM_NONE },
+ [0xE9] = { "SBC", SBC, 2, 2, false, AM_IMM },
+ [0xE5] = { "SBC", SBC, 2, 3, false, AM_ZP },
+ [0xF5] = { "SBC", SBC, 2, 4, false, AM_ZP_X },
+ [0xED] = { "SBC", SBC, 3, 4, false, AM_ABS },
+ [0xFD] = { "SBC", SBC, 3, 4, false, AM_ABS_X },
+ [0xF9] = { "SBC", SBC, 3, 4, false, AM_ABS_Y },
+ [0xE1] = { "SBC", SBC, 2, 6, false, AM_IND_X },
+ [0xF1] = { "SBC", SBC, 2, 5, false, AM_IND_Y },
+ [0x38] = { "SEC", SEC, 1, 2, false, AM_NONE },
+ [0xF8] = { "SED", SED, 1, 2, false, AM_NONE },
+ [0x78] = { "SEI", SEI, 1, 2, false, AM_NONE },
+ [0x85] = { "STA", STA, 2, 3, true, AM_ZP },
+ [0x95] = { "STA", STA, 2, 4, true, AM_ZP_X },
+ [0x8D] = { "STA", STA, 3, 4, true, AM_ABS },
+ [0x9D] = { "STA", STA, 3, 5, true, AM_ABS_X },
+ [0x99] = { "STA", STA, 3, 5, true, AM_ABS_Y },
+ [0x81] = { "STA", STA, 2, 6, true, AM_IND_X },
+ [0x91] = { "STA", STA, 2, 6, true, AM_IND_Y },
+ [0x86] = { "STX", STX, 2, 3, true, AM_ZP },
+ [0x96] = { "STX", STX, 2, 4, true, AM_ZP_Y },
+ [0x8E] = { "STX", STX, 3, 4, true, AM_ABS },
+ [0x84] = { "STY", STY, 2, 3, true, AM_ZP },
+ [0x94] = { "STY", STY, 2, 4, true, AM_ZP_X },
+ [0x8C] = { "STY", STY, 3, 4, true, AM_ABS },
+ [0xAA] = { "TAX", TAX, 1, 2, false, AM_NONE },
+ [0xA8] = { "TAY", TAY, 1, 2, false, AM_NONE },
+ [0xBA] = { "TSX", TSX, 1, 2, false, AM_NONE },
+ [0x8A] = { "TXA", TXA, 1, 2, false, AM_NONE },
+ [0x9A] = { "TXS", TXS, 1, 2, false, AM_NONE },
+ [0x98] = { "TYA", TYA, 1, 2, false, AM_NONE },
};