+static void OpA4(void) // ANDA IDX
+{
+ uint16 m = READ_IDX;
+ OP_AND_HANDLER(m, regs.a);
+}
+
+static void OpB4(void) // ANDA ABS
+{
+ uint16 m = READ_ABS;
+ OP_AND_HANDLER(m, regs.a);
+}
+
+static void OpC4(void) // ANDB #
+{
+ uint16 m = READ_IMM;
+ OP_AND_HANDLER(m, regs.b);
+}
+
+static void OpD4(void) // ANDB DP
+{
+ uint16 m = READ_DP;
+ OP_AND_HANDLER(m, regs.b);
+}
+
+static void OpE4(void) // ANDB IDX
+{
+ uint16 m = READ_IDX;
+ OP_AND_HANDLER(m, regs.b);
+}
+
+static void OpF4(void) // ANDB ABS
+{
+ uint16 m = READ_ABS;
+ OP_AND_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
+ | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
+ | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
+ | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
+ | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
+*/
+
+// ASL opcodes
+
+#define OP_ASL_HANDLER(m) \
+ uint16 res = m << 1; \
+ SET_V(m, m, res); \
+ flagC = (res >> 8) & 0x01; \
+ m = res & 0xFF; \
+ SET_ZN(m)
+
+static void Op08(void) // ASL DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_ASL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op48(void) // ASLA
+{
+ OP_ASL_HANDLER(regs.a);
+}
+
+static void Op58(void) // ASLB
+{
+ OP_ASL_HANDLER(regs.b);
+}
+
+static void Op68(void) // ASL IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_ASL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op78(void) // ASL ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_ASL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
+ | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
+ | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
+ | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
+ | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
+*/
+
+// ASR opcodes (arithmetic, so preserves the sign)
+
+#define OP_ASR_HANDLER(m) \
+ uint8 res = (m & 0x80) | (m >> 1); \
+ SET_ZN(res); \
+ flagC = m & 0x01; \
+ m = res
+
+static void Op07(void) // ASR DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_ASR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op47(void) // ASRA
+{
+ OP_ASR_HANDLER(regs.a);
+}
+
+static void Op57(void) // ASRB
+{
+ OP_ASR_HANDLER(regs.b);
+}
+
+static void Op67(void) // ASR IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_ASR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op77(void) // ASR ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_ASR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
+ | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
+ | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
+ | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
+ | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
+ | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
+ | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
+ | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
+ | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
+ | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
+ | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
+ | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
+ | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
+ | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
+ | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
+ | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
+ | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
+ | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
+ | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
+ | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
+ | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
+ | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
+ | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
+ | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
+ | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
+ | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
+ | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
+ | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
+ | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
+ | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
+ | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
+ | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
+*/
+
+// Branch opcodes
+
+static void Op16(void) // LBRA
+{
+ uint16 offset = READ_IMM16;
+ regs.pc += offset;
+}
+
+static void Op20(void) // BRA
+{
+ int16 offset = (int16)(int8)READ_IMM;
+ regs.pc += offset;
+}
+
+static void Op21(void) // BRN
+{
+ // This is basically a 2 byte NOP
+ int16 offset = (int16)(int8)READ_IMM;
+}
+
+static void Op22(void) // BHI
+{
+ // !C && !Z
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
+ regs.pc += offset * ((flagZ | flagC) ^ 0x01);
+#else
+ if (!(flagZ || flagC))
+ regs.pc += offset;
+#endif
+}
+
+static void Op23(void) // BLS
+{
+ // C || Z
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ | flagC);
+#else
+ if (flagZ || flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op24(void) // BHS/CC
+{
+ // !C
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagC ^ 0x01);
+#else
+ if (!flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op25(void) // BLO/CS
+{
+ // C
+ int16 offset = (int16)(int8)READ_IMM;
+//if (disasm)
+// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagC;
+#else
+ if (flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op26(void) // BNE
+{
+ // !Z
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ ^ 0x01);
+#else
+ if (!flagZ)
+ regs.pc += offset;
+#endif
+}
+
+static void Op27(void) // BEQ
+{
+ // Z
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagZ;
+#else
+ if (flagZ)
+ regs.pc += offset;
+#endif
+}
+
+static void Op28(void) // BVC
+{
+ // !V
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagV ^ 0x01);
+#else
+ if (!flagV)
+ regs.pc += offset;
+#endif
+}
+
+static void Op29(void) // BVS
+{
+ // V
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagV;
+#else
+ if (flagV)
+ regs.pc += offset;
+#endif
+}
+
+static void Op2A(void) // BPL
+{
+ // !N
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagN ^ 0x01);
+#else
+ if (!flagN)
+ regs.pc += offset;
+#endif
+}
+
+static void Op2B(void) // BMI
+{
+ // N
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagN;
+#else
+ if (flagN)
+ regs.pc += offset;
+#endif
+}
+
+static void Op2C(void) // BGE
+{
+ // (N && V) || (!N && !V)
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
+#else
+ if ((flagN && flagV) || (!flagN && !flagV))
+ regs.pc += offset;
+#endif
+}
+
+static void Op2D(void) // BLT
+{
+ // (N && !V) || (!N && V)
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+ if ((flagN && !flagV) || (!flagN && flagV))
+ regs.pc += offset;
+#endif
+}
+
+static void Op2E(void) // BGT
+{
+ // (N && V && !Z) || (!N && !V && !Z)
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
+#else
+ if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
+ regs.pc += offset;
+#endif
+}
+
+static void Op2F(void) // BLE
+{
+ // Z || (N && !V) || (!N && V)
+ int16 offset = (int16)(int8)READ_IMM;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+ if (flagZ || (flagN && !flagV) || (!flagN && flagV))
+ regs.pc += offset;
+#endif
+}
+
+static void Op1021(void) // LBRN
+{
+ // This is basically a 4 byte NOP
+ uint16 offset = READ_IMM16;
+}
+
+static void Op1022(void) // LBHI
+{
+ // !C && !Z
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
+ regs.pc += offset * ((flagZ | flagC) ^ 0x01);
+#else
+ if (!(flagZ || flagC))
+ regs.pc += offset;
+#endif
+}
+
+static void Op1023(void) // LBLS
+{
+ // C || Z
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ | flagC);
+#else
+ if (flagZ || flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1024(void) // LBHS/CC
+{
+ // !C
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagC ^ 0x01);
+#else
+ if (!flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1025(void) // LBLO/CS
+{
+ // C
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagC;
+#else
+ if (flagC)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1026(void) // LBNE
+{
+ // !Z
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ ^ 0x01);
+#else
+ if (!flagZ)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1027(void) // LBEQ
+{
+ // Z
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagZ;
+#else
+ if (flagZ)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1028(void) // LBVC
+{
+ // !V
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagV ^ 0x01);
+#else
+ if (!flagV)
+ regs.pc += offset;
+#endif
+}
+
+static void Op1029(void) // LBVS
+{
+ // V
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagV;
+#else
+ if (flagV)
+ regs.pc += offset;
+#endif
+}
+
+static void Op102A(void) // LBPL
+{
+ // !N
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagN ^ 0x01);
+#else
+ if (!flagN)
+ regs.pc += offset;
+#endif
+}
+
+static void Op102B(void) // LBMI
+{
+ // N
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * flagN;
+#else
+ if (flagN)
+ regs.pc += offset;
+#endif
+}
+
+static void Op102C(void) // LBGE
+{
+ // (N && V) || (!N && !V)
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
+#else
+ if ((flagN && flagV) || (!flagN && !flagV))
+ regs.pc += offset;
+#endif
+}
+
+static void Op102D(void) // LBLT
+{
+ // (N && !V) || (!N && V)
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+ if ((flagN && !flagV) || (!flagN && flagV))
+ regs.pc += offset;
+#endif
+}
+
+static void Op102E(void) // LBGT
+{
+ // (N && V && !Z) || (!N && !V && !Z)
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
+#else
+ if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
+ regs.pc += offset;
+#endif
+}
+
+static void Op102F(void) // LBLE
+{
+ // Z || (N && !V) || (!N && V)
+ uint16 offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+ if (flagZ || (flagN && !flagV) || (!flagN && flagV))
+ regs.pc += offset;
+#endif
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
+ | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
+ | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
+ | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
+ | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
+ | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
+ | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
+ | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
+*/
+
+// BIT opcodes
+
+#define OP_BIT_HANDLER(m, acc) \
+ uint8 result = acc & (m); \
+ SET_ZN(result); \
+ CLR_V
+
+static void Op85(void) // BITA #
+{
+ uint8 m = READ_IMM;
+ OP_BIT_HANDLER(m, regs.a);
+}
+
+static void Op95(void) // BITA DP
+{
+ uint8 m = READ_DP;
+ OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpA5(void) // BITA IDX
+{
+ uint8 m = READ_IDX;
+ OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpB5(void) // BITA ABS
+{
+ uint8 m = READ_ABS;
+ OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpC5(void) // BITB #
+{
+ uint8 m = READ_IMM;
+ OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpD5(void) // BITB DP
+{
+ uint8 m = READ_DP;
+ OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpE5(void) // BITB IDX
+{
+ uint8 m = READ_IDX;
+ OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpF5(void) // BITB ABS
+{
+ uint8 m = READ_ABS;
+ OP_BIT_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
+ | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
+ | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
+ | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
+ | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
+*/
+
+// CLR opcodes
+
+#define OP_CLR_HANDLER(m) \
+ flagN = flagV = flagC = 0; \
+ flagZ = 1; \
+ m = 0
+
+static void Op0F(void) // CLR DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_CLR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op4F(void) // CLRA
+{
+ OP_CLR_HANDLER(regs.a);
+}
+
+static void Op5F(void) // CLRB
+{
+ OP_CLR_HANDLER(regs.b);
+}
+
+static void Op6F(void) // CLR IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_CLR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op7F(void) // CLR ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_CLR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
+ | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
+ | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
+ | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
+ | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
+ | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
+ | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
+ | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
+ | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
+ | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
+ | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
+ | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
+ | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
+ | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
+ | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
+ | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
+ | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
+ | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
+ | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
+ | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
+ | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
+ | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
+ | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
+ | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
+ | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
+ | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
+ | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
+ | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
+*/
+
+// CMP opcodes
+
+#define OP_CMP_HANDLER(m, acc) \
+ uint16 sum = (uint16)(acc) - (m); \
+ flagC = (sum >> 8) & 0x01; \
+ SET_V(m, acc, sum); \
+ SET_ZN(sum)
+
+#define OP_CMP_HANDLER16(m, acc) \
+ uint32 sum = (uint32)(acc) - (m); \
+ flagC = (sum >> 16) & 0x01; \
+ SET_V16(m, acc, sum); \
+ SET_ZN16(sum)
+
+static void Op81(void) // CMPA #
+{
+ uint8 m = READ_IMM;
+ OP_CMP_HANDLER(m, regs.a);
+}
+
+static void Op8C(void) // CMPX #
+{
+ uint16 m = READ_IMM16;
+ OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void Op91(void) // CMPA DP
+{
+ uint8 m = READ_DP;
+ OP_CMP_HANDLER(m, regs.a);
+}
+
+static void Op9C(void) // CMPX DP
+{
+ uint16 m = READ_DP16;
+ OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpA1(void) // CMPA IDX
+{
+ uint8 m = READ_IDX;
+ OP_CMP_HANDLER(m, regs.a);
+}
+
+static void OpAC(void) // CMPX IDX
+{
+ uint16 m = READ_IDX16;
+ OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpB1(void) // CMPA ABS
+{
+ uint8 m = READ_ABS;
+ OP_CMP_HANDLER(m, regs.a);
+}
+
+static void OpBC(void) // CMPX ABS
+{
+ uint16 m = READ_ABS16;
+ OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpC1(void) // CMPB #
+{
+ uint8 m = READ_IMM;
+ OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpD1(void) // CMPB DP
+{
+ uint8 m = READ_DP;
+ OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpE1(void) // CMPB IDX
+{
+ uint8 m = READ_IDX;
+ OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpF1(void) // CMPB ABS
+{
+ uint8 m = READ_ABS;
+ OP_CMP_HANDLER(m, regs.b);
+}
+
+static void Op1083(void) // CMPD #
+{
+ uint16 m = READ_IMM16;
+ OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op108C(void) // CMPY #
+{
+ uint16 m = READ_IMM16;
+ OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op1093(void) // CMPD DP
+{
+ uint16 m = READ_DP16;
+ OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op109C(void) // CMPY DP
+{
+ uint16 m = READ_DP16;
+ OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op10A3(void) // CMPD IDX
+{
+ uint16 m = READ_IDX16;
+ OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op10AC(void) // CMPY IDX
+{
+ uint16 m = READ_IDX16;
+ OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op10B3(void) // CMPD ABS
+{
+ uint16 m = READ_ABS16;
+ OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op10BC(void) // CMPY ABS
+{
+ uint16 m = READ_ABS16;
+ OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op1183(void) // CMPU #
+{
+ uint16 m = READ_IMM16;
+ OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op118C(void) // CMPS #
+{
+ uint16 m = READ_IMM16;
+ OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op1193(void) // CMPU DP
+{
+ uint16 m = READ_DP16;
+ OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op119C(void) // CMPS DP
+{
+ uint16 m = READ_DP16;
+ OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op11A3(void) // CMPU IDX
+{
+ uint16 m = READ_IDX16;
+ OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op11AC(void) // CMPS IDX
+{
+ uint16 m = READ_IDX16;
+ OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op11B3(void) // CMPU ABS
+{
+ uint16 m = READ_ABS16;
+ OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op11BC(void) // CMPS ABS
+{
+ uint16 m = READ_ABS16;
+ OP_CMP_HANDLER16(m, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
+ | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
+ | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
+ | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
+ | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
+*/
+
+// COM opcodes
+
+#define OP_COM_HANDLER(m) \
+ m = ~m; \
+ SET_ZN(m); \
+ flagC = 1; \
+ flagV = 0
+
+static void Op03(void) // COM DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_COM_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op43(void) // COMA
+{
+ OP_COM_HANDLER(regs.a);
+}
+
+static void Op53(void) // COMB
+{
+ OP_COM_HANDLER(regs.b);
+}
+
+static void Op63(void) // COM IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_COM_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op73(void) // COM ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_COM_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
+ | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
+ | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
+ | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
+ | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
+ | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
+*/
+
+static void Op13(void) // SYNC
+{
+#warning "!!! SYNC not implemented !!!"
+#if 0
+ /* SYNC stops processing instructions until an interrupt request happens. */
+ /* This doesn't require the corresponding interrupt to be enabled: if it */
+ /* is disabled, execution continues with the next instruction. */
+ m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
+ check_irq_lines(m68_state);
+ /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
+ * stop execution until the interrupt lines change. */
+ if( m68_state->int_state & M6809_SYNC )
+ if (m68_state->icount > 0) m68_state->icount = 0;
+#endif
+}
+
+static void Op3C(void) // CWAI
+{
+#warning "!!! CWAI not implemented !!!"
+#if 0
+ UINT8 t;
+ IMMBYTE(t);
+ CC &= t;
+ /*
+ * CWAI stacks the entire machine state on the hardware stack,
+ * then waits for an interrupt; when the interrupt is taken
+ * later, the state is *not* saved again after CWAI.
+ */
+ CC |= CC_E; /* HJB 990225: save entire state */
+ PUSHWORD(pPC);
+ PUSHWORD(pU);
+ PUSHWORD(pY);
+ PUSHWORD(pX);
+ PUSHBYTE(DP);
+ PUSHBYTE(B);
+ PUSHBYTE(A);
+ PUSHBYTE(CC);
+ m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
+ check_irq_lines(m68_state); /* HJB 990116 */
+ if( m68_state->int_state & M6809_CWAI )
+ if( m68_state->icount > 0 )
+ m68_state->icount = 0;
+#endif
+}
+
+static void Op3E(void) // RESET
+{
+ regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
+}
+
+static void Op3F(void) // SWI
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ flagF = flagI = 1;
+ regs.pc = RdMemW(0xFFFA);
+}
+
+static void Op103F(void) // SWI2
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ regs.pc = RdMemW(0xFFF4);
+}
+
+static void Op113F(void) // SWI3
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ regs.pc = RdMemW(0xFFF2);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
+ | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
+ | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
+ | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
+ | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
+*/
+
+static void Op12() // NOP
+{
+}
+
+static void Op19() // DAA
+{
+ uint16 result = (uint16)regs.a;
+
+ if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
+ result += 0x06;
+
+ if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
+ result += 0x60;
+
+ regs.a = (uint8)result;
+ SET_ZN(result);
+ CLR_V;
+ flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
+}
+
+static void Op1A() // ORCC
+{
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ regs.cc |= READ_IMM;
+ UNPACK_FLAGS; // & unmash 'em
+}
+
+static void Op1C() // ANDCC
+{
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ regs.cc &= READ_IMM;
+ UNPACK_FLAGS; // & unmash 'em
+}
+
+static void Op1D() // SEX
+{
+ regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
+ SET_ZN16((regs.a << 8) | regs.b);
+ CLR_V;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
+ | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
+ | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
+ | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
+ | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
+*/
+
+// DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
+
+#define OP_DEC_HANDLER(m) \
+ m--; \
+ SET_ZN(m); \
+ flagV = (m == 0x7F ? 1 : 0)
+
+static void Op0A(void) // DEC DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_DEC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op4A(void) // DECA
+{
+ OP_DEC_HANDLER(regs.a);
+}
+
+static void Op5A(void) // DECB
+{
+ OP_DEC_HANDLER(regs.b);
+}
+
+static void Op6A(void) // DEC IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_DEC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op7A(void) // DEC ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_DEC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
+ | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
+ | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
+ | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
+ | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
+ | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
+ | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
+ | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
+*/
+
+// EOR opcodes
+
+#define OP_EOR_HANDLER(m, acc) \
+ acc ^= (m); \
+ SET_ZN(acc); \
+ CLR_V
+
+static void Op88(void) // EORA #
+{
+ uint8 m = READ_IMM;
+ OP_EOR_HANDLER(m, regs.a);
+}
+
+static void Op98(void) // EORA DP
+{
+ uint8 m = READ_DP;
+ OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpA8(void) // EORA IDX
+{
+ uint8 m = READ_IDX;
+ OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpB8(void) // EORA ABS
+{
+ uint8 m = READ_ABS;
+ OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpC8(void) // EORB #
+{
+ uint8 m = READ_IMM;
+ OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpD8(void) // EORB DP
+{
+ uint8 m = READ_DP;
+ OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpE8(void) // EORB IDX
+{
+ uint8 m = READ_IDX;
+ OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpF8(void) // EORB ABS
+{
+ uint8 m = READ_ABS;
+ OP_EOR_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
+ | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
+ | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
+ | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
+ | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
+*/
+
+// INC opcodes (If we went from $7F -> $80, sign overflowed.)
+
+#define OP_INC_HANDLER(m) \
+ m++; \
+ SET_ZN(m); \
+ flagV = (m == 0x80 ? 1 : 0)
+
+static void Op0C(void) // INC DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_INC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op4C(void) // INCA
+{
+ OP_INC_HANDLER(regs.a);
+}
+
+static void Op5C(void) // INCB
+{
+ OP_INC_HANDLER(regs.b);
+}
+
+static void Op6C(void) // INC IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_INC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op7C(void) // INC ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_INC_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
+ | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
+ | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
+ | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
+ | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
+ | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
+ | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
+ | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
+ | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
+ | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
+*/
+
+static void Op0E(void) // JMP DP
+{
+ regs.pc = EA_DP;
+}
+
+static void Op17(void) // LBSR
+{
+ uint16 word = FetchMemW(regs.pc);
+ PUSHS16(regs.pc);
+ regs.pc += word;
+}
+
+static void Op39(void) // RTS
+{
+ PULLS16(regs.pc);
+}
+
+static void Op3B(void) // RTI
+{
+ PULLS(regs.cc);
+ UNPACK_FLAGS;
+
+ // If E flag set, pull all regs
+ if (flagE)
+ {
+ PULLS(regs.a);
+ PULLS(regs.b);
+ PULLS(regs.dp);
+ PULLS16(regs.x);
+ PULLS16(regs.y);
+ PULLS16(regs.u);
+ regs.clock += 9;
+ }
+
+ PULLS16(regs.pc);
+}
+
+static void Op6E(void) // JMP IDX
+{
+ regs.pc = EA_IDX;
+}
+
+static void Op7E(void) // JMP ABS
+{
+ regs.pc = EA_ABS;
+}
+
+static void Op8D(void) // BSR
+{
+ uint16 word = (int16)(int8)READ_IMM;
+ PUSHS16(regs.pc);
+ regs.pc += word;
+}
+
+static void Op9D(void) // JSR DP
+{
+ uint16 word = EA_DP;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+static void OpAD(void) // JSR IDX
+{
+ uint16 word = EA_IDX;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+static void OpBD(void) // JSR ABS
+{
+ uint16 word = EA_ABS;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
+ | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
+*/
+
+static void Op1E(void) // EXG
+{
+ uint8 m = READ_IMM;
+ uint8 reg1 = m >> 4, reg2 = m & 0x0F;
+ uint16 acc = ReadEXG(reg1);
+ WriteEXG(reg1, ReadEXG(reg2));
+ WriteEXG(reg2, acc);
+}
+
+static void Op1F(void) // TFR
+{
+ uint8 m = READ_IMM;
+ WriteEXG(m & 0x0F, ReadEXG(m >> 4));
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
+ | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
+ | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
+ | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
+ | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
+ | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
+ | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
+ | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
+ | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
+ | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
+ | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
+ | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
+ | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
+ | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
+ | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
+ | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
+ | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
+ | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
+ | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
+ | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
+ | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
+ | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
+ | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
+ | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
+ | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
+ | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
+ | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
+ | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
+*/
+
+// LDA opcodes
+
+#define OP_LDA_HANDLER(m, acc) \
+ acc = m; \
+ CLR_V; \
+ SET_ZN(acc)
+
+#define OP_LDA_HANDLER16(m, acc) \
+ acc = m; \
+ CLR_V; \
+ SET_ZN16(acc)
+
+#define OP_LDA_HANDLER16D(m) \
+ regs.a = (m >> 8); \
+ regs.b = m & 0xFF; \
+ CLR_V; \
+ SET_ZN16(m)
+
+static void Op86(void) // LDA #
+{
+ uint8 m = READ_IMM;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void Op8E(void) // LDX #
+{
+ uint16 m = READ_IMM16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void Op96(void) // LDA DP
+{
+ uint8 m = READ_DP;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void Op9E(void) // LDX DP
+{
+ uint16 m = READ_DP16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpA6(void) // LDA IDX
+{
+ uint8 m = READ_IDX;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void OpAE(void) // LDX IDX
+{
+ uint16 m = READ_IDX16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpB6(void) // LDA ABS
+{
+ uint8 m = READ_ABS;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void OpBE(void) // LDX ABS
+{
+ uint16 m = READ_ABS16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpC6(void) // LDB #
+{
+ uint8 m = READ_IMM;
+ OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpCC(void) // LDD #
+{
+ uint16 m = READ_IMM16;
+ OP_LDA_HANDLER16D(m);
+}
+
+static void OpCE(void) // LDU #
+{
+ uint16 m = READ_IMM16;
+ OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpD6(void) // LDB DP
+{
+ uint8 m = READ_DP;
+ OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpDC(void) // LDD DP
+{
+ uint16 m = READ_DP16;
+ OP_LDA_HANDLER16D(m);
+}
+
+static void OpDE(void) // LDU DP
+{
+ uint16 m = READ_DP16;
+ OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpE6(void) // LDB IDX
+{
+ uint8 m = READ_IDX;
+ OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpEC(void) // LDD IDX
+{
+ uint16 m = READ_IDX16;
+ OP_LDA_HANDLER16D(m);
+}
+
+static void OpEE(void) // LDU IDX
+{
+ uint16 m = READ_IDX16;
+ OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpF6(void) // LDB ABS
+{
+ uint8 m = READ_ABS;
+ OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpFC(void) // LDD ABS
+{
+ uint16 m = READ_ABS16;
+ OP_LDA_HANDLER16D(m);
+}
+
+static void OpFE(void) // LDU ABS
+{
+ uint16 m = READ_ABS16;
+ OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void Op108E(void) // LDY #
+{
+ uint16 m = READ_IMM16;
+ OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op109E(void) // LDY DP
+{
+ uint16 m = READ_DP16;
+ OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10AE(void) // LDY IDX
+{
+ uint16 m = READ_IDX16;
+ OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10BE(void) // LDY ABS
+{
+ uint16 m = READ_ABS16;
+ OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10CE(void) // LDS #
+{
+ uint16 m = READ_IMM16;
+ OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10DE(void) // LDS DP
+{
+ uint16 m = READ_DP16;
+ OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10EE(void) // LDS IDX
+{
+ uint16 m = READ_IDX16;
+ OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10FE(void) // LDS ABS
+{
+ uint16 m = READ_ABS16;
+ OP_LDA_HANDLER16(m, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
+ | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
+ | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
+ | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
+*/
+
+static void Op30(void) // LEAX
+{
+ regs.x = EA_IDX;
+ SET_Z(regs.x);
+}
+
+static void Op31(void) // LEAY
+{
+ regs.y = EA_IDX;
+ SET_Z(regs.y);
+}
+
+static void Op32(void) // LEAS
+{
+ regs.s = EA_IDX;
+}
+
+static void Op33(void) // LEAU
+{
+ regs.u = EA_IDX;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
+ | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
+ | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
+ | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
+ | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
+*/
+
+// LSR opcodes
+
+#define OP_LSR_HANDLER(m) \
+ flagC = m & 0x01; \
+ m >>= 1; \
+ SET_ZN(m)
+
+static void Op04(void) // LSR DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_LSR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op44(void) // LSRA
+{
+ OP_LSR_HANDLER(regs.a);
+}
+
+static void Op54(void) // LSRB
+{
+ OP_LSR_HANDLER(regs.b);
+}
+
+static void Op64(void) // LSR IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_LSR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op74(void) // LSR ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_LSR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
+*/
+
+static void Op3D(void) // MUL
+{
+ uint16 prod = regs.a * regs.b;
+ regs.a = prod >> 8;
+ regs.b = prod & 0xFF;
+ SET_Z(prod);
+// flagC = (prod & 0x0080 ? 1 : 0);
+ flagC = (prod >> 7) & 0x01;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
+ | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
+ | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
+ | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
+ | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
+*/
+
+// NEG opcodes
+
+#define OP_NEG_HANDLER(m) \
+ uint8 res = -m; \
+ SET_ZN(res); \
+ SET_V(0, m, res); \
+ flagC = (res >= 0x80 ? 1 : 0); \
+ m = res
+
+/*
+ UINT16 r,t;
+ DIRBYTE(t);
+ r = -t;
+ CLR_NZVC;
+ SET_FLAGS8(0,t,r);
+ WM(EAD,r);
+#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
+#define SET_C8(a) CC|=((a&0x100)>>8)
+*/
+static void Op00(void) // NEG DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_NEG_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op40(void) // NEGA
+{
+ OP_NEG_HANDLER(regs.a);
+}
+
+static void Op50(void) // NEGB
+{
+ OP_NEG_HANDLER(regs.b);
+}
+
+static void Op60(void) // NEG IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_NEG_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op70(void) // NEG ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_NEG_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
+ | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
+ | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
+ | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
+ | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
+ | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
+ | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
+ | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
+*/
+
+// ORA opcodes
+
+#define OP_OR_HANDLER(m, acc) \
+ acc |= (m); \
+ SET_ZN(acc); \
+ CLR_V
+
+static void Op8A(void) // ORA #
+{
+ uint8 m = READ_IMM;
+ OP_OR_HANDLER(m, regs.a);
+}
+
+static void Op9A(void) // ORA DP
+{
+ uint8 m = READ_DP;
+ OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpAA(void) // ORA IDX
+{
+ uint8 m = READ_IDX;
+ OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpBA(void) // ORA ABS
+{
+ uint8 m = READ_ABS;
+ OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpCA(void) // ORB #
+{
+ uint8 m = READ_IMM;
+ OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpDA(void) // ORB DP
+{
+ uint8 m = READ_DP;
+ OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpEA(void) // ORB IDX
+{
+ uint8 m = READ_IDX;
+ OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpFA(void) // ORB ABS
+{
+ uint8 m = READ_ABS;
+ OP_OR_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
+ | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
+ | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
+ | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
+*/
+
+static void Op34(void) // PSHS
+{
+ uint8 m = READ_IMM;
+
+ if (m & 0x80)
+ PUSHS16(regs.pc);
+ if (m & 0x40)
+ PUSHS16(regs.u);
+ if (m & 0x20)
+ PUSHS16(regs.y);
+ if (m & 0x10)
+ PUSHS16(regs.x);
+ if (m & 0x08)
+ PUSHS(regs.dp);
+ if (m & 0x04)
+ PUSHS(regs.b);
+ if (m & 0x02)
+ PUSHS(regs.a);
+ if (m & 0x01)
+ {
+ regs.cc = PACK_FLAGS;
+ PUSHS(regs.cc);
+ }
+}
+
+static void Op35(void) // PULS
+{
+ uint8 m = READ_IMM;
+
+ if (m & 0x01)
+ {
+ PULLS(regs.cc);
+ UNPACK_FLAGS;
+ }
+ if (m & 0x02)
+ PULLS(regs.a);
+ if (m & 0x04)
+ PULLS(regs.b);
+ if (m & 0x08)
+ PULLS(regs.dp);
+ if (m & 0x10)
+ PULLS16(regs.x);
+ if (m & 0x20)
+ PULLS16(regs.y);
+ if (m & 0x40)
+ PULLS16(regs.u);
+ if (m & 0x80)
+ PULLS16(regs.pc);
+}
+
+static void Op36(void) // PHSU
+{
+ uint8 m = READ_IMM;
+
+ if (m & 0x80)
+ PUSHU16(regs.pc);
+ if (m & 0x40)
+ PUSHU16(regs.s);
+ if (m & 0x20)
+ PUSHU16(regs.y);
+ if (m & 0x10)
+ PUSHU16(regs.x);
+ if (m & 0x08)
+ PUSHU(regs.dp);
+ if (m & 0x04)
+ PUSHU(regs.b);
+ if (m & 0x02)
+ PUSHU(regs.a);
+ if (m & 0x01)
+ {
+ regs.cc = PACK_FLAGS;
+ PUSHU(regs.cc);
+ }
+}
+
+static void Op37(void) // PULU
+{
+ uint8 m = READ_IMM;
+
+ if (m & 0x01)
+ {
+ PULLU(regs.cc);
+ UNPACK_FLAGS;
+ }
+ if (m & 0x02)
+ PULLU(regs.a);
+ if (m & 0x04)
+ PULLU(regs.b);
+ if (m & 0x08)
+ PULLU(regs.dp);
+ if (m & 0x10)
+ PULLU16(regs.x);
+ if (m & 0x20)
+ PULLU16(regs.y);
+ if (m & 0x40)
+ PULLU16(regs.s);
+ if (m & 0x80)
+ PULLU16(regs.pc);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
+ | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
+ | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
+ | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
+ | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
+*/
+
+// ROL opcodes
+
+#define OP_ROL_HANDLER(m) \
+ uint8 res = (m << 1) | flagC; \
+ SET_ZN(res); \
+ SET_V(m, m, res); \
+ flagC = (m >> 7) & 0x01; \
+ m = res
+
+/*
+ UINT16 t,r;
+ DIRBYTE(t);
+ r = (CC & CC_C) | (t << 1);
+ CLR_NZVC;
+ SET_FLAGS8(t,t,r);
+ WM(EAD,r);
+*/
+static void Op09(void) // ROL DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op49(void) // ROLA
+{
+ OP_ROL_HANDLER(regs.a);
+}
+
+static void Op59(void) // ROLB
+{
+ OP_ROL_HANDLER(regs.b);
+}
+
+static void Op69(void) // ROL IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op79(void) // ROL ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
+ | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
+ | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
+ | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
+ | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
+*/
+
+// ROR opcodes
+
+#define OP_ROR_HANDLER(m) \
+ uint8 res = (flagC << 7) | (m >> 1); \
+ SET_ZN(res); \
+ SET_V(m, m, res); \
+ flagC = m & 0x01; \
+ m = res
+
+static void Op06(void) // ROR DP
+{
+ uint8 m;
+ READ_DP_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op46(void) // RORA
+{
+ OP_ROR_HANDLER(regs.a);
+}
+
+static void Op56(void) // RORB
+{
+ OP_ROR_HANDLER(regs.b);
+}
+
+static void Op66(void) // ROR IDX
+{
+ uint8 m;
+ READ_IDX_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op76(void) // ROR ABS
+{
+ uint8 m;
+ READ_ABS_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
+ | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
+ | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
+ | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
+ | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
+ | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
+ | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
+ | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
+*/
+
+// SBC opcodes
+
+#define OP_SBC_HANDLER(m, acc) \
+ uint16 sum = (uint16)acc - (m) - (uint16)flagC; \
+ flagC = (sum >> 8) & 0x01; \
+ SET_V(m, acc, sum); \
+ acc = (uint8)sum; \
+ SET_ZN(acc)
+
+static void Op82(void) // SBCA #
+{
+ uint8 m = READ_IMM;
+ OP_SBC_HANDLER(m, regs.a);
+}
+
+static void Op92(void) // SBCA DP
+{
+ uint8 m = READ_DP;
+ OP_SBC_HANDLER(m, regs.a);
+}
+
+static void OpA2(void) // SBCA IDX
+{
+ uint8 m = READ_IDX;
+ OP_SBC_HANDLER(m, regs.a);
+}
+
+static void OpB2(void) // SBCA ABS
+{
+ uint8 m = READ_ABS;
+ OP_SBC_HANDLER(m, regs.a);
+}
+
+static void OpC2(void) // SBCB #
+{
+ uint8 m = READ_IMM;
+ OP_SBC_HANDLER(m, regs.b);
+}
+
+static void OpD2(void) // SBCB DP
+{
+ uint8 m = READ_DP;
+ OP_SBC_HANDLER(m, regs.b);
+}
+
+static void OpE2(void) // SBCB IDX
+{
+ uint8 m = READ_IDX;
+ OP_SBC_HANDLER(m, regs.b);
+}
+
+static void OpF2(void) // SBCB ABS
+{
+ uint8 m = READ_ABS;
+ OP_SBC_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
+ | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
+ | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
+ | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
+ | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
+ | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
+ | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
+ | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
+ | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
+ | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
+ | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
+ | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
+ | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
+ | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
+ | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
+ | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
+ | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
+ | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
+ | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
+ | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
+ | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
+*/
+
+// STA opcodes
+
+#define OP_STA_HANDLER(m, acc) \
+ regs.WrMem(m, acc); \
+ CLR_V; \
+ SET_ZN(acc)
+
+#define OP_STA_HANDLER16(m, acc) \
+ WrMemW(m, acc); \
+ CLR_V; \
+ SET_ZN16(acc)
+
+static void Op97(void) // STA DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER(addr, regs.a);
+}
+
+static void Op9F(void) // STX DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.x);
+}
+
+static void OpA7(void) // STA IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER(addr, regs.a);
+}
+
+static void OpAF(void) // STX IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.x);
+}
+
+static void OpB7(void) // STA ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER(addr, regs.a);
+}
+
+static void OpBF(void) // STX ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.x);
+}
+
+static void OpD7(void) // STB DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER(addr, regs.b);
+}
+
+static void OpDD(void) // STD DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
+}
+
+static void OpDF(void) // STU DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.u);
+}
+
+static void OpE7(void) // STB IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER(addr, regs.b);
+}
+
+static void OpED(void) // STD IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
+}
+
+static void OpEF(void) // STU IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.u);
+}
+
+static void OpF7(void) // STB ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER(addr, regs.b);
+}
+
+static void OpFD(void) // STD ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
+}
+
+static void OpFF(void) // STU ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.u);
+}
+
+static void Op109F(void) // STY DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.y);
+}
+
+static void Op10AF(void) // STY IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.y);
+}
+
+static void Op10BF(void) // STY ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.y);
+}
+
+static void Op10DF(void) // STS DP
+{
+ uint16 addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.s);
+}
+
+static void Op10EF(void) // STS IDX
+{
+ uint16 addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.s);
+}
+
+static void Op10FF(void) // STS ABS
+{
+ uint16 addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
+ | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
+ | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
+ | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
+ | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
+ | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
+ | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
+ | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
+ | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
+ | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
+ | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
+ | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
+*/
+
+// SUB opcodes
+
+#define OP_SUB_HANDLER(m, acc) \
+ uint16 sum = (uint16)acc - (m); \
+ flagC = (sum >> 8) & 0x01; \
+ SET_V(m, acc, sum); \
+ acc = (uint8)sum; \
+ SET_ZN(acc)
+
+#define OP_SUB_HANDLER16D(m) \
+ uint32 acc = (uint32)((regs.a << 8) | regs.b); \
+ uint32 sum = acc - (m); \
+ flagC = (sum >> 16) & 0x01; \
+ SET_V16(m, acc, sum); \
+ acc = sum & 0xFFFF; \
+ regs.a = (acc >> 8) & 0xFF; \
+ regs.b = acc & 0xFF; \
+ SET_ZN16(acc)
+
+static void Op80(void) // SUBA #
+{
+ uint8 m = READ_IMM;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void Op83(void) // SUBD #
+{
+ uint16 m = READ_IMM16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void Op90(void) // SUBA DP
+{
+ uint8 m = READ_DP;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void Op93(void) // SUBD DP
+{
+ uint16 m = READ_DP16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpA0(void) // SUBA IDX
+{
+ uint8 m = READ_IDX;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void OpA3(void) // SUBD IDX
+{
+ uint16 m = READ_IDX16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpB0(void) // SUBA ABS
+{
+ uint8 m = READ_ABS;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void OpB3(void) // SUBD ABS
+{
+ uint16 m = READ_ABS16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpC0(void) // SUBB #
+{
+ uint8 m = READ_IMM;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpD0(void) // SUBB DP
+{
+ uint8 m = READ_DP;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpE0(void) // SUBB IDX
+{
+ uint8 m = READ_IDX;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpF0(void) // SUBB ABS
+{
+ uint8 m = READ_ABS;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
+ | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
+ | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
+ | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
+ | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
+*/
+
+// TST opcodes
+
+#define OP_TST_HANDLER(m) \
+ SET_ZN(m); \
+ CLR_V
+
+static void Op0D(void) // TST DP
+{
+ uint8 m = READ_DP;
+ OP_TST_HANDLER(m);
+}
+
+static void Op4D(void) // TSTA
+{
+ OP_TST_HANDLER(regs.a);
+}
+
+static void Op5D(void) // TSTB
+{
+ OP_TST_HANDLER(regs.b);
+}
+
+static void Op6D(void) // TST IDX
+{
+ uint8 m = READ_IDX;
+ OP_TST_HANDLER(m);
+}
+
+static void Op7D(void) // TST ABS
+{
+ uint8 m = READ_ABS;
+ OP_TST_HANDLER(m);
+}
+
+// Undocumented Opcodes
+
+static void Op01(void)
+{
+ Op00(); // NEG DP
+}
+
+#else
+
+//
+// Page zero instructions...
+//
+
+static void Op00(void) // NEG DP
+{
+ addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
+ tmp = 256 - regs.RdMem(addr);
+ regs.WrMem(addr, tmp);
+
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+
+ regs.clock += 6;
+}
+
+static void Op01(void) // NEG DP (Undocumented)
+{
+ Op00();
+}
+
+static void Op03(void) // COM DP
+{
+ addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
+ tmp = 0xFF ^ regs.RdMem(addr);
+ regs.WrMem(addr, tmp);
+
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 6;
+}
+
+static void Op04(void) // LSR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ tmp >>= 1; regs.WrMem(addr, tmp);
+ regs.cc &= 0xF7; // CLN
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 6;
+}
+static void Op06(void) // ROR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
+ tmp = (tmp2>>1) + (regs.cc&0x01)*128;
+ regs.WrMem(addr, tmp);
+ (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op07(void) // ASR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ tmp >>= 1;
+ if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op08(void) // LSL DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
+ tmp = regs.RdMem(addr);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ tmp <<= 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op09(void) // ROL DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0A(void) // DEC DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr) - 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0C(void) // INC DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr) + 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0D(void) // TST DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0E(void) // JMP DP
+{
+ regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ regs.clock += 3;
+}
+static void Op0F(void) // CLR DP