]> Shamusworld >> Repos - stargem2/blobdiff - src/v6808.cpp
Finalizing move to trunk...
[stargem2] / src / v6808.cpp
index e9c4253dce603a899047ad7a3d98b1729073590c..b26cb4af4e0a2551d2f1e86599a7d06101fdf8f2 100755 (executable)
@@ -1,8 +1,8 @@
 //
-// Virtual 6808 Emulator v1.2
+// Virtual 6808 Emulator v2.0
 //
 // by James L. Hammons
-// (c) 2006 Underground Software
+// (C) 2006 Underground Software
 //
 // JLH = James L. Hammons <jlhamm@acm.org>
 //
 // ---  ----------  ------------------------------------------------------------
 // JLH  06/15/2006  Added changelog ;-)
 // JLH  06/15/2006  Scrubbed all BYTE, WORD & DWORD references from the code
+// JLH  11/13/2006  Converted core to V65C02 macro style :-)
+// JLH  11/13/2006  Converted flags to unpacked and separate flags
 //
 
-// Mebbe someday I'll get around to fixing the core to be more like V65C02...
+// NOTE: V6808_STATE_WAI is not handled in the main loop correctly. !!! FIX !!!
+
+// Some random thoughts: Could there be a performance gain by breaking
+// out the flags in regs.cc into separate uint8 variables (or bools)?
+// You'd have to convert on entering and exiting the emulation loop, but I
+// think the perfomance hit would be negligible compared to the gain in not
+// having to mask and shift flags all the time. Investigate after the
+// conversion to macro style opcodes is completed. :-)
+// [DONE--remain to be seen if there is any performance increase]
 
 //#define __DEBUG__
 
 #include "log.h"
 #endif
 
+// Various macros
+
+#if 0
+#define CLR_Z                          (regs.cc &= ~FLAG_Z)
+#define CLR_ZN                         (regs.cc &= ~(FLAG_Z | FLAG_N))
+#define CLR_ZNC                                (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
+#define CLR_NVC                                (regs.cc &= ~(FLAG_N | FLAG_V | FLAG_C))
+#define CLR_VC                         (regs.cc &= ~(FLAG_V | FLAG_C))
+#define CLR_V                          (regs.cc &= ~FLAG_V)
+#define CLR_N                          (regs.cc &= ~FLAG_N)
+#define SET_Z(r)                       (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
+#define SET_N(r)                       (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
+#define SET_V(a,b,r)           (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
+
+//Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
+#define SET_C_ADD(a,b)         (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+#define SET_C_CMP(a,b)         (regs.cc = ((uint8)(b) < (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+#define SET_ZN(r)                      SET_N(r); SET_Z(r)
+#define SET_ZNC_ADD(a,b,r)     SET_N(r); SET_Z(r); SET_C_ADD(a,b)
+#define SET_ZNVC_CMP(a,b,r)    SET_N(r); SET_Z(r); SET_C_CMP(a,b); SET_V(a,b,r)
+
+#define SET_N16(r)                             (regs.cc = ((r) & 0x8000 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
+#define SET_V16(a,b,r)         (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
+#define SET_C_CMP16(a,b)               (regs.cc = ((uint16)(b) < (uint16)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+#define SET_ZNVC_CMP16(a,b,r)  SET_N16(r); SET_Z(r); SET_C_CMP16(a,b); SET_V16(a,b,r)
+#else
+#define CLR_Z                                  (flagZ = 0)
+#define CLR_ZN                                 (flagZ = flagN = 0)
+#define CLR_ZNC                                        (flagZ = flagN = flagC = 0)
+#define CLR_NVC                                        (flagN = flagV = flagC = 0)
+#define CLR_VC                                 (flagV = flagC = 0)
+#define CLR_V                                  (flagV = 0)
+#define CLR_N                                  (flagN = 0)
+#define SET_Z(r)                               (flagZ = ((r) == 0 ? 1 : 0))
+#define SET_N(r)                               (flagN = ((r) & 0x80) >> 7)
+#define SET_V(a,b,r)                   (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
+
+#define SET_C_CMP(a,b)                 (flagC = ((uint8)(b) < (uint8)(a) ? 1 : 0))
+#define SET_ZN(r)                              SET_N(r); SET_Z(r)
+#define SET_ZNC_ADD(a,b,r)             SET_N(r); SET_Z(r); SET_C_ADD(a,b)
+#define SET_ZNVC_CMP(a,b,r)            SET_N(r); SET_Z(r); SET_C_CMP(a,b); SET_V(a,b,r)
+
+#define SET_N16(r)                             (flagN = ((r) & 0x8000) >> 15)
+#define SET_V16(a,b,r)                 (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
+#define SET_C_CMP16(a,b)               (flagC = ((uint16)(b) < (uint16)(a) ? 1 : 0))
+#define SET_ZNVC_CMP16(a,b,r)  SET_N16(r); SET_Z(r); SET_C_CMP16(a,b); SET_V16(a,b,r)
+#endif
+
+//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! [DONE, kinda]
+#define EA_IMM                         regs.pc++
+#define EA_ZP                          regs.RdMem(regs.pc++)
+#define EA_ZP_X                                (regs.RdMem(regs.pc++) + regs.x)
+#define EA_ABS                         RdMemW(regs.pc)
+
+#define READ_IMM                       regs.RdMem(EA_IMM)
+#define READ_ZP                                regs.RdMem(EA_ZP)
+#define READ_ZP_X                      regs.RdMem(EA_ZP_X)
+#define READ_ABS                       regs.RdMem(EA_ABS);                     regs.pc += 2
+
+#define READ_IMM16                     RdMemW(regs.pc);                        regs.pc += 2
+#define READ_ZP16                      RdMemW(EA_ZP)
+#define READ_ZP_X16                    RdMemW(EA_ZP_X)
+#define READ_ABS16                     RdMemW(EA_ABS);                         regs.pc += 2
+
+#define READ_IMM_WB(v)         uint16 addr = EA_IMM;           v = regs.RdMem(addr)
+#define READ_ZP_WB(v)          uint16 addr = EA_ZP;            v = regs.RdMem(addr)
+#define READ_ZP_X_WB(v)                uint16 addr = EA_ZP_X;          v = regs.RdMem(addr)
+#define READ_ABS_WB(v)         uint16 addr = EA_ABS;           v = regs.RdMem(addr); regs.pc += 2
+
+#define WRITE_BACK(d)          regs.WrMem(addr, (d))
+
+#define PULL                           regs.RdMem(regs.s++)
+#define PUSH(r)                                regs.WrMem(--regs.s, (r))
+#define PULL16                         RdMemW(regs.s);                         regs.s += 2
+#define PUSH16(r)                      regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8)
+
+#define PACK_FLAGS                     ((regs.cc & 0xC0) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
+#define UNPACK_FLAGS           flagH = (regs.cc & FLAG_H) >> 5; \
+       flagI = (regs.cc & FLAG_I) >> 4; \
+       flagN = (regs.cc & FLAG_N) >> 3; \
+       flagZ = (regs.cc & FLAG_Z) >> 2; \
+       flagV = (regs.cc & FLAG_V) >> 1; \
+       flagC = (regs.cc & FLAG_C)
+
 // Private global variables
 
 static V6808REGS regs;
-static uint16 addr;
-static uint8 tmp;
+static uint8 flagH, flagI, flagN, flagZ, flagV, flagC;
 
 static uint8 CPUCycles[256] = {
        1,  2,  1,  1,  1,  1,  2,  2,  4,  4,  2,  2,  2,  2,  2,  2,
@@ -50,1756 +143,1912 @@ static uint8 CPUCycles[256] = {
 
 // Private function prototypes
 
-static uint16 FetchW(void);
 static uint16 RdMemW(uint16);
-static void WrMemW(uint16, uint16);
-
-//
-// Fetch a word out of 6808 memory (little endian format)
-// This is a leftover from when fetches were separated from garden variety reads...
-//
-static uint16 FetchW()
-{
-       uint16 w = RdMemW(regs.pc);
-       regs.pc += 2;
-       return w;
-}
 
 //
 // Read a word out of 6808 memory (little endian format)
 //
-static uint16 RdMemW(uint16 address)
+static inline uint16 RdMemW(uint16 address)
 {
        return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
 }
 
 //
-// Write a word into 6808 memory (little endian format)
-//
-static void WrMemW(uint16 address, uint16 w)
-{
-       regs.WrMem(address + 0, w >> 8);
-       regs.WrMem(address + 1, w & 0xFF);
-}
-
+// 6808 OPCODE IMPLEMENTATION
 //
-// Function to decode IDX data
+// NOTE: Lots of macros are used here to save a LOT of typing. Also
+//       helps speed the debugging process. :-) Because of this, combining
+//       certain lines may look like a good idea but would end in disaster.
+//       You have been warned! ;-)
 //
-inline uint16 DecodeIDX(uint8 code)
-{
-       return regs.x + code;
-}
 
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Add                     |ADDA |8B 2 2|9B 3 2|AB 5 2|BB 4 3|      |A=A+M     |T TTTT|
+                        |ADDB |CB 2 2|DB 3 2|EB 5 2|FB 4 3|      |B=B+M     |T TTTT|
+Add Accumulators        |ABA  |      |      |      |      |1B 2 1|A=A+B     |T TTTT|
+*/
 
-//
-// Opcode Functions (Mostly correct... Yikes!)
-//
+// ADD opcodes
 
-static void Op01(void)                                                 // NOP
+//#define OP_ADD_HANDLER(m, acc) \
+       uint16 sum = (uint16)(acc) + (m); \
+       regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \
+       regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \
+       SET_V(m, acc, sum); \
+       (acc) = sum & 0xFF; \
+       SET_ZN(acc)
+#define OP_ADD_HANDLER(m, acc) \
+       uint16 sum = (uint16)(acc) + (m); \
+       flagC = sum >> 8; \
+       flagH = (sum >> 4) & 0x01; \
+       SET_V(m, acc, sum); \
+       (acc) = sum & 0xFF; \
+       SET_ZN(acc)
+
+static void Op8B(void)                                                 // ADDA #
 {
+       uint16 m = READ_IMM;
+       OP_ADD_HANDLER(m, regs.a);
 }
 
-static void Op06(void)                                                 // TAP
+static void Op9B(void)                                                 // ADDA ZP
 {
-       regs.cc = regs.a;
+       uint16 m = READ_ZP;
+       OP_ADD_HANDLER(m, regs.a);
 }
 
-static void Op07(void)                                                 // TPA
+static void OpAB(void)                                                 // ADDA ZP, X
 {
-       regs.a = regs.cc;
+       uint16 m = READ_ZP_X;
+       OP_ADD_HANDLER(m, regs.a);
 }
 
-static void Op08(void)                                                 // INX
+static void OpBB(void)                                                 // ADDA ABS
 {
-       regs.x++;
-
-       (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
+       uint16 m = READ_ABS;
+       OP_ADD_HANDLER(m, regs.a);
 }
 
-static void Op09(void)                                                 // DEX
+static void OpCB(void)                                                 // ADDB #
 {
-       regs.x--;
-
-       (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
+       uint16 m = READ_IMM;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op0A(void)                                                 // CLV
+static void OpDB(void)                                                 // ADDB ZP
 {
-       regs.cc &= ~FLAG_V;
+       uint16 m = READ_ZP;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op0B(void)                                                 // SEV
+static void OpEB(void)                                                 // ADDB ZP, X
 {
-       regs.cc |= FLAG_V;
+       uint16 m = READ_ZP_X;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op0C(void)                                                 // CLC
+static void OpFB(void)                                                 // ADDB ABS
 {
-       regs.cc &= ~FLAG_C;
+       uint16 m = READ_ABS;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op0D(void)                                                 // SEC
+static void Op1B(void)                                                 // ABA
 {
-       regs.cc |= FLAG_C;
+       OP_ADD_HANDLER(regs.b, regs.a);
 }
 
-static void Op0E(void)                                                 // CLI
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Add with Carry          |ADCA |89 2 2|99 3 2|A9 5 2|B9 4 3|      |A=A+M+C   |T TTTT|
+                        |ADCB |C9 2 2|D9 3 2|E9 5 2|F9 4 3|      |B=B+M+C   |T TTTT|
+*/
+
+// ADC opcodes
+
+//#define OP_ADC_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc + (m) + (uint16)(regs.cc & FLAG_C); \
+       regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \
+       regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \
+       SET_V(m, acc, sum); \
+       acc = sum & 0xFF; \
+       SET_ZN(acc)
+#define OP_ADC_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc + (m) + (uint16)flagC; \
+       flagC = sum >> 8; \
+       flagH = (sum >> 4) & 0x01; \
+       SET_V(m, acc, sum); \
+       acc = sum & 0xFF; \
+       SET_ZN(acc)
+
+static void Op89(void)                                                 // ADCA #
 {
-       regs.cc &= ~FLAG_I;
+       uint16 m = READ_IMM;
+       OP_ADC_HANDLER(m, regs.a);
 }
 
-static void Op0F(void)                                                 // SEI
+static void Op99(void)                                                 // ADCA ZP
 {
-       regs.cc |= FLAG_I;
+       uint16 m = READ_ZP;
+       OP_ADC_HANDLER(m, regs.a);
 }
 
-static void Op10(void)                                                 // SBA
+static void OpA9(void)                                                 // ADCA ZP, X
 {
-       uint8 as = regs.a; 
-       regs.a -= regs.b;
-
-       regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C);        // Clear NZVC
-
-       if (as < regs.b)
-               regs.cc |= FLAG_C;
-
-       if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
-               regs.cc |= FLAG_V;
-
-       if (regs.a == 0)
-               regs.cc |= FLAG_Z;
-
-       if (regs.a & 0x80)
-               regs.cc |= FLAG_N;
+       uint16 m = READ_ZP_X;
+       OP_ADC_HANDLER(m, regs.a);
 }
 
-static void Op11(void)                                                 // CBA (Compare B to A)
+static void OpB9(void)                                                 // ADCA ABS
 {
-       tmp = regs.a - regs.b;
-
-       regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C);        // Clear NZVC
-
-       if (regs.a < regs.b)
-               regs.cc |= FLAG_C;
-
-       if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
-               regs.cc |= FLAG_V;
-
-       if (regs.a == 0)
-               regs.cc |= FLAG_Z;
-
-       if (regs.a & 0x80)
-               regs.cc |= FLAG_N;
+       uint16 m = READ_ABS;
+       OP_ADC_HANDLER(m, regs.a);
 }
 
-static void Op16(void)                                                 // TAB
+static void OpC9(void)                                                 // ADCB #
 {
-       regs.b = regs.a;
-
-       regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);         // Clear NZV
+       uint16 m = READ_IMM;
+       OP_ADC_HANDLER(m, regs.b);
+}
 
-       if (regs.b == 0)
-               regs.cc |= FLAG_Z;
+static void OpD9(void)                                                 // ADCB ZP
+{
+       uint16 m = READ_ZP;
+       OP_ADC_HANDLER(m, regs.b);
+}
 
-       if (regs.b & 0x80)
-               regs.cc |= FLAG_N;
+static void OpE9(void)                                                 // ADCB ZP, X
+{
+       uint16 m = READ_ZP_X;
+       OP_ADC_HANDLER(m, regs.b);
 }
 
-static void Op17(void)                                                 // TBA
+static void OpF9(void)                                                 // ADCB ABS
 {
-       regs.a = regs.b;
+       uint16 m = READ_ABS;
+       OP_ADC_HANDLER(m, regs.b);
+}
 
-       regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);         // Clear NZV
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+And                     |ANDA |84 2 2|94 3 2|A4 5 2|B4 4 3|      |A=A+M     |  TTR |
+                        |ANDB |C4 2 2|D4 3 2|E4 5 2|F4 4 3|      |B=B+M     |  TTR |
+*/
 
-       if (regs.a == 0)
-               regs.cc |= FLAG_Z;
+// AND opcodes
 
-       if (regs.a & 0x80)
-               regs.cc |= FLAG_N;
-}
+#define OP_AND_HANDLER(m, acc) \
+       acc &= m; \
+       SET_ZN(acc); \
+       CLR_V
 
-static void Op19(void)                                                 // DAA
+static void Op84(void)                                                 // ANDA #
 {
-  addr = regs.a;
-//  if (regs.cc&0x20)              addr += 6;    // H set? adjust
-  if ((addr&0x000F) > 9)     addr += 6;
-  if (regs.cc&0x01)              addr += 0x60; // C set? adjust
-  if ((addr&0x00F0) > 0x90)  addr += 0x60;
-  regs.cc &= 0xFD;                             // CLV
-  (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  regs.a = addr;
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag 
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag 
+       uint8 m = READ_IMM;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op1B(void)                                                 // ABA
+static void Op94(void)                                                 // ANDA ZP
 {
-  addr = regs.a + regs.b;
-  regs.cc &= 0xF0;
-  if (addr > 0xFF)  regs.cc |= 0x01;    // Set Carry flag
-  if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80)  regs.cc |= 0x02; // Set oVerflow 
-  regs.a = addr;                        // Set accumulator
-  if (regs.a == 0)      regs.cc |= 0x04;    // Set Zero flag
-  if (regs.a&0x80)      regs.cc |= 0x08;    // Set Negative flag
+       uint8 m = READ_ZP;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op20(void)                                                 // BRA (BRanch Always)
+static void OpA4(void)                                                 // ANDA ZP, X
 {
-       regs.pc += (int16)(int8)regs.RdMem(regs.pc++);
+       uint16 m = READ_ZP_X;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op22(void)                                                 // BHI
+static void OpB4(void)                                                 // ANDA ABS
 {
-       tmp = regs.RdMem(regs.pc++);
-
-       if (!(regs.cc & (FLAG_C | FLAG_Z)))
-               regs.pc += (signed short int)(signed char)tmp;
+       uint16 m = READ_ABS;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op23(void)                                                 // BLS
+static void OpC4(void)                                                 // ANDB #
 {
-       tmp = regs.RdMem(regs.pc++);
-
-       if (regs.cc & (FLAG_C | FLAG_Z))
-               regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_IMM;
+       OP_AND_HANDLER(m, regs.b);
 }
 
-static void Op24(void)                                                 // BCC (BHS)
+static void OpD4(void)                                                 // ANDB ZP
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x01))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ZP;
+       OP_AND_HANDLER(m, regs.b);
 }
 
-static void Op25(void)                                                 // BCS (BLO)
+static void OpE4(void)                                                 // ANDB ZP, X
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x01)  regs.pc += (signed short int)(signed char)tmp;
+       uint16 m = READ_ZP_X;
+       OP_AND_HANDLER(m, regs.b);
 }
 
-static void Op26(void)                                                 // BNE
+static void OpF4(void)                                                 // ANDB ABS
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x04))  regs.pc += (signed short int)(signed char)tmp;
+       uint16 m = READ_ABS;
+       OP_AND_HANDLER(m, regs.b);
 }
 
-static void Op27(void)                                                 // BEQ
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Bit Test                |BITA |85 2 2|95 3 2|A5 5 2|B5 4 3|      |A+M       |  TTR |
+                        |BITB |C5 2 2|D5 3 2|E5 5 2|F5 4 3|      |B+M       |  TTR |
+*/
+
+// BIT opcodes
+
+#define OP_BIT_HANDLER(m, acc) \
+       int8 result = acc & (m); \
+       SET_ZN(result)
+
+static void Op85(void)                                                 // BITA #
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x04)  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_IMM;
+       OP_BIT_HANDLER(m, regs.a);
 }
 
-static void Op28(void)                                                 // BVC
+static void Op95(void)                                                 // BITA ZP
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x02))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ZP;
+       OP_BIT_HANDLER(m, regs.a);
 }
 
-static void Op29(void)                                                 // BVS
+static void OpA5(void)                                                 // BITA ZP, X
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x02)  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ZP_X;
+       OP_BIT_HANDLER(m, regs.a);
 }
 
-static void Op2A(void)                                                 // BPL
+static void OpB5(void)                                                 // BITA ABS
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x08))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ABS;
+       OP_BIT_HANDLER(m, regs.a);
 }
 
-static void Op2B(void)                                                 // BMI
+static void OpC5(void)                                                 // BITB #
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x08)  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_IMM;
+       OP_BIT_HANDLER(m, regs.b);
 }
 
-static void Op2C(void)                                                 // BGE
+static void OpD5(void)                                                 // BITB ZP
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ZP;
+       OP_BIT_HANDLER(m, regs.b);
 }
 
-static void Op2D(void)                                                 // BLT
+static void OpE5(void)                                                 // BITB ZP, X
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ZP_X;
+       OP_BIT_HANDLER(m, regs.b);
 }
 
-static void Op2E(void)                                                 // BGT
+static void OpF5(void)                                                 // BITB ABS
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))))  regs.pc += (signed short int)(signed char)tmp;
+       uint8 m = READ_ABS;
+       OP_BIT_HANDLER(m, regs.b);
 }
 
-static void Op2F(void)                                                 // BLE
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Clear                   |CLR  |      |      |6F 7 2|7F 6 3|      |M=00      |  RSRR|
+                        |CLRA |      |      |      |      |4F 2 1|A=00      |  RSRR|
+                        |CLRB |      |      |      |      |5F 2 1|B=00      |  RSRR|
+*/
+
+// CLR opcodes
+
+static void Op6F(void)                                                 // CLR ZP, X
 {
-  tmp = regs.RdMem(regs.pc++);
-  if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += (signed short int)(signed char)tmp;
+       regs.WrMem(EA_ZP_X, 0);
+       CLR_NVC;
+       SET_Z(0);
 }
 
-static void Op30(void)                                                 // TSX
+static void Op7F(void)                                                 // CLR ABS
 {
-  regs.x = regs.s;
+       regs.WrMem(EA_ABS, 0);
+       regs.pc += 2;
+       CLR_NVC;
+       SET_Z(0);
 }
 
-static void Op31(void)                                                 // INS
+static void Op4F(void)                                                 // CLRA
 {
-  regs.s++;
+       regs.a = 0;
+       CLR_NVC;
+       SET_Z(0);
 }
 
-static void Op32(void)                                                 // PULA
+static void Op5F(void)                                                 // CLRB
 {
-  regs.a  = regs.RdMem(regs.s++);
+       regs.b = 0;
+       CLR_NVC;
+       SET_Z(0);
 }
 
-static void Op33(void)                                                 // PULB
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Compare                 |CMPA |81 2 2|91 3 2|A1 5 2|B1 4 3|      |A-M       |  TTTT|
+                        |CMPB |C1 2 2|D1 3 2|E1 5 2|F1 4 3|      |B-M       |  TTTT|
+Compare Accumulators    |CBA  |      |      |      |      |11 2 1|A-B       |  TTTT|
+*/
+
+// CMP opcodes
+
+/*
+Compare sets flags as if a subtraction had been carried out. If the value in the accumulator is equal or greater than the compared value, the Carry will be set. The equal (Z) and sign (S) flags will be set based on equality or lack thereof and the sign (i.e. A>=$80) of the accumulator.
+*/
+
+#define OP_CMP_HANDLER(m, acc) \
+       uint16 result = acc - (m); \
+       SET_ZNVC_CMP(m, acc, result)
+
+static void Op81(void)                                                 // CMPA #
 {
-  regs.b  = regs.RdMem(regs.s++);
+       uint8 m = READ_IMM;
+       OP_CMP_HANDLER(m, regs.a);
 }
 
-static void Op34(void)                                                 // DES
+static void Op91(void)                                                 // CMPA ZP
 {
-  regs.s--;
+       uint8 m = READ_ZP;
+       OP_CMP_HANDLER(m, regs.a);
 }
 
-static void Op35(void)                                                 // TXS
+static void OpA1(void)                                                 // CMPA ZP, X
 {
-  regs.s = regs.x;
+       uint8 m = READ_ZP_X;
+       OP_CMP_HANDLER(m, regs.a);
 }
 
-static void Op36(void)                                                 // PSHA
+static void OpB1(void)                                                 // CMPA ABS
 {
-       regs.WrMem(--regs.s, regs.a);
+       uint8 m = READ_ABS;
+       OP_CMP_HANDLER(m, regs.a);
 }
 
-static void Op37(void)                                                 // PSHB
+static void OpC1(void)                                                 // CMPB #
 {
-       regs.WrMem(--regs.s, regs.b);
+       uint8 m = READ_IMM;
+       OP_CMP_HANDLER(m, regs.b);
 }
 
-static void Op39(void)                                                 // RTS
+static void OpD1(void)                                                 // CMPB ZP
 {
-       regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
+       uint8 m = READ_ZP;
+       OP_CMP_HANDLER(m, regs.b);
 }
 
-static void Op3B(void)                                                 // RTI
+static void OpE1(void)                                                 // CMPB ZP, X
 {
-       regs.cc = regs.RdMem(regs.s++);
-       regs.a  = regs.RdMem(regs.s++);
-       regs.b  = regs.RdMem(regs.s++);
-       regs.x  = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
-       regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
+       uint8 m = READ_ZP_X;
+       OP_CMP_HANDLER(m, regs.b);
 }
 
-static void Op3E(void)                                                 // WAI (wait for interrupt)
+static void OpF1(void)                                                 // CMPB ABS
 {
-       regs.cc &= regs.RdMem(regs.pc++);
-       regs.cc |= 0x80;//???Is this right???
+       uint8 m = READ_ABS;
+       OP_CMP_HANDLER(m, regs.b);
 }
 
-static void Op3F(void)                                                 // SWI (software interrupt)
+static void Op11(void)                                                 // CBA
 {
-//Does this respect the I flag???
-       regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
-       regs.WrMem(--regs.s, regs.pc >> 8);
-       regs.WrMem(--regs.s, regs.x & 0xFF);
-       regs.WrMem(--regs.s, regs.x >> 8);
-       regs.WrMem(--regs.s, regs.b);
-       regs.WrMem(--regs.s, regs.a);
-       regs.WrMem(--regs.s, regs.cc);
-       regs.pc = RdMemW(0xFFFA);                                       // And do it!
-
-       regs.cc |= FLAG_I;                                                      // Also, set IRQ inhibit
+       OP_CMP_HANDLER(regs.b, regs.a);
 }
 
-static void Op40(void)                                                 // NEGA
-{ 
-  regs.a = 256 - regs.a;  regs.cc &= 0xF0;
-  if (regs.a > 0x7F)   regs.cc |= 0x01;   // Set Carry
-  if (regs.a == 0x80)  regs.cc |= 0x02;   // Set oVerflow
-  if (regs.a == 0)     regs.cc |= 0x04;   // Set Zero flag
-  if (regs.a&0x80)     regs.cc |= 0x08;   // Set Negative flag
-}
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Complement 1's          |COM  |      |      |63 7 2|73 6 3|      |M=-M      |  TTRS|
+                        |COMA |      |      |      |      |43 2 1|A=-A      |  TTRS|
+                        |COMB |      |      |      |      |53 2 1|B=-B      |  TTRS|
+*/
 
-static void Op43(void)                                                 // COMA
+// COM opcodes
+
+//#define OP_COM_HANDLER(m) \
+       m = m ^ 0xFF; \
+       SET_ZN(m); \
+       CLR_V; \
+       regs.cc |= FLAG_C
+#define OP_COM_HANDLER(m) \
+       m = m ^ 0xFF; \
+       SET_ZN(m); \
+       CLR_V; \
+       flagC = 1
+
+static void Op63(void)                                                 // COM ZP, X
 {
-  regs.a ^= 0xFF;
-  regs.cc &= 0xF0;  regs.cc |= 0x01;                   // CLV, SEC
-  if (regs.a == 0)  regs.cc |= 0x04;                   // Set Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;                   // Set Negative flag
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_COM_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op44(void)                                                 // LSRA
+static void Op73(void)                                                 // COM ABS
 {
-  (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
-  regs.a >>= 1;
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_COM_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op46(void)  // RORA
+static void Op43(void)                                                 // COMA
 {
-  tmp = regs.a;  regs.a = (tmp>>1) + (regs.cc&0x01)*128;
-  (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+       OP_COM_HANDLER(regs.a);
 }
 
-static void Op47(void)  // ASRA
+static void Op53(void)                                                 // COMB
 {
-  (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
-  regs.a >>= 1;                               // Do the shift
-  if (regs.a&0x40)  regs.a |= 0x80;               // Set neg if it was set
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_COM_HANDLER(regs.b);
 }
 
-static void Op48(void)  // LSLA (ASLA) [Keep checking from here...]
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Complement 2's          |NEG  |      |      |60 7 2|70 6 3|      |M=00-M    |  TT12|
+                        |NEGA |      |      |      |      |40 2 1|A=00-A    |  TT12|
+                        |NEGB |      |      |      |      |50 2 1|B=00-B    |  TT12|
+*/
+
+// NEG opcodes
+
+//#define OP_NEG_HANDLER(m) \
+       m = -m; \
+       SET_ZN(m); \
+       regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V); \
+       regs.cc = (m == 0x00 ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)
+#define OP_NEG_HANDLER(m) \
+       m = -m; \
+       SET_ZN(m); \
+       flagV = (m == 0x80 ? 1 : 0); \
+       flagC = (m == 0x00 ? 1 : 0)
+
+static void Op60(void)                                                 // NEG ZP, X
 {
-  (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
-  regs.a <<= 1;
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_NEG_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op49(void)  // ROLA  
+static void Op70(void)                                                 // NEG ABS
 {
-  tmp = regs.a;  regs.a = (tmp<<1) + (regs.cc&0x01);
-  (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_NEG_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op4A(void)  // DECA
+static void Op40(void)                                                 // NEGA
 {
-  regs.a--;
-  (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-  (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
-  (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+       OP_NEG_HANDLER(regs.a);
 }
 
-static void Op4C(void)  // INCA
+static void Op50(void)                                                 // NEGB
 {
-regs.a++;
-(regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
+       OP_NEG_HANDLER(regs.b);
 }
 
-static void Op4D(void)  // TSTA
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Decimal Adjust          |DAA  |      |      |      |      |19 2 1|*         |  TTT3|
+*/
+
+static void Op19(void)                                                 // DAA
 {
-regs.cc &= 0xFD;                            // Clear oVerflow flag
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+#if 0 // Just because we can optimize a little here, we will... ;-)
+       uint16 adjust = 0;
+
+       if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
+               adjust |= 0x06;
+
+       if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
+               adjust |= 0x60;
+
+       uint16 result = regs.a + adjust;
+       regs.a = (uint8)result;
+       SET_ZN(result);
+       CLR_V;                                                                          // Not sure this is correct...
+       regs.cc |= (result & 0x100) >> 8;                       // Overwrite carry if it was 0, otherwise, ignore
+#else
+       uint16 result = (uint16)regs.a;
+
+//     if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
+       if ((regs.a & 0x0F) > 0x09 || flagH)
+               result += 0x06;
+
+//     if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
+       if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
+               result += 0x60;
+
+       regs.a = (uint8)result;
+       SET_ZN(result);
+       CLR_V;                                                                          // Not sure this is correct...
+//     regs.cc |= (result & 0x100) >> 8;                       // Overwrite carry if it was 0, otherwise, ignore
+       flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
+#endif
 }
 
-static void Op4F(void)  // CLRA
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Decrement               |DEC  |      |      |6A 7 2|7A 6 3|      |M=M-1     |  TT4 |
+                        |DECA |      |      |      |      |4A 2 1|A=A-1     |  TT4 |
+                        |DECB |      |      |      |      |5A 2 1|B=B-1     |  TT4 |
+*/
+
+// DEC opcodes
+
+//#define OP_DEC_HANDLER(m) \
+       m--; \
+       SET_ZN(m); \
+       regs.cc = (m == 0x7F ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
+#define OP_DEC_HANDLER(m) \
+       m--; \
+       SET_ZN(m); \
+       flagV = (m == 0x7F ? 1 : 0)
+
+static void Op6A(void)                                                 // DEC ZP, X
 {
-  regs.a = 0;
-  regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_DEC_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op50(void)  // NEGB
-{ 
-regs.b = 256 - regs.b;
-//        ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
-(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
-(regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+static void Op7A(void)                                                 // DEC ABS
+{
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_DEC_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op53(void)  // COMB
+static void Op4A(void)                                                 // DECA
 {
-regs.b ^= 0xFF;
-regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_DEC_HANDLER(regs.a);
 }
 
-static void Op54(void)  // LSRB
+static void Op5A(void)                                                 // DECB
 {
-(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
-regs.b >>= 1;
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_DEC_HANDLER(regs.b);
 }
 
-static void Op56(void)  // RORB
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Exclusive OR            |EORA |88 2 2|98 3 2|A8 5 2|B8 4 3|      |A=A(+)M   |  TTR |
+                        |EORB |C8 2 2|D8 3 2|E8 5 2|F8 4 3|      |B=B(+)M   |  TTR |
+*/
+
+// EOR opcodes
+
+#define OP_EOR_HANDLER(m, acc) \
+       acc ^= m; \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op88(void)                                                 // EORA #
 {
-tmp = regs.b;  regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
-(tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m = READ_IMM;
+       OP_EOR_HANDLER(m, regs.a);
 }
 
-static void Op57(void)  // ASRB
+static void Op98(void)                                                 // EORA ZP
 {
-(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
-regs.b >>= 1;                               // Do the shift
-if (regs.b&0x40)  regs.b |= 0x80;               // Set neg if it was set
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m = READ_ZP;
+       OP_EOR_HANDLER(m, regs.a);
 }
 
-static void Op58(void)  // LSLB
+static void OpA8(void)                                                 // EORA ZP, X
 {
-(regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
-regs.b <<= 1;
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m = READ_ZP_X;
+       OP_EOR_HANDLER(m, regs.a);
 }
 
-static void Op59(void)  // ROLB
+static void OpB8(void)                                                 // EORA ABS
 {
-  tmp = regs.b;
-  regs.b = (tmp<<1) + (regs.cc&0x01);
-  (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m = READ_ABS;
+       OP_EOR_HANDLER(m, regs.a);
 }
 
-static void Op5A(void)  // DECB
+static void OpC8(void)                                                 // EORB #
 {
-regs.b--;
-(regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
+       uint8 m = READ_IMM;
+       OP_EOR_HANDLER(m, regs.b);
 }
 
-static void Op5C(void)  // INCB
+static void OpD8(void)                                                 // EORB ZP
 {
-regs.b++;
-(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag 
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
+       uint8 m = READ_ZP;
+       OP_EOR_HANDLER(m, regs.b);
 }
 
-static void Op5D(void)  // TSTB
+static void OpE8(void)                                                 // EORB ZP, X
 {
-regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m = READ_ZP_X;
+       OP_EOR_HANDLER(m, regs.b);
 }
 
-static void Op5F(void)  // CLRB
+static void OpF8(void)                                                 // EORB ABS
 {
-regs.b = 0;
-regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
+       uint8 m = READ_ABS;
+       OP_EOR_HANDLER(m, regs.b);
 }
 
-static void Op60(void)  // NEG IDX
-{ 
-addr = DecodeIDX(regs.RdMem(regs.pc++));
-tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
-regs.WrMem(addr, res);
-//        ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
-(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
-(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
-(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Increment               |INC  |      |      |6C 7 2|7C 6 3|      |M=M+1     |  TT5 |
+                        |INCA |      |      |      |      |4C 2 1|A=A+1     |  TT5 |
+                        |INCB |      |      |      |      |5C 2 1|B=B+1     |  TT5 |
+*/
+
+// INC opcodes
+
+//#define OP_INC_HANDLER(m) \
+       m++; \
+       SET_ZN(m); \
+       regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
+#define OP_INC_HANDLER(m) \
+       m++; \
+       SET_ZN(m); \
+       flagV = (m == 0x80 ? 1 : 0)
+
+static void Op6C(void)                                                 // INC ZP, X
+{
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_INC_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op63(void)  // COM IDX
+static void Op7C(void)                                                 // INC ABS
 {
-addr = DecodeIDX(regs.RdMem(regs.pc++));
-tmp = regs.RdMem(addr) ^ 0xFF;
-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
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_INC_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op64(void)  // LSR IDX
+static void Op4C(void)                                                 // INCA
 {
-addr = DecodeIDX(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
+       OP_INC_HANDLER(regs.a);
 }
 
-static void Op66(void)  // ROR IDX
+static void Op5C(void)                                                 // INCB
 {
-addr = DecodeIDX(regs.RdMem(regs.pc++));
-tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
-tmp = (tmp >> 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
+       OP_INC_HANDLER(regs.b);
 }
 
-static void Op67(void)  // ASR IDX
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Load Accumulator        |LDAA |86 2 2|96 3 2|A6 5 2|B6 4 3|      |A=M       |  TTR |
+                        |LDAB |C6 2 2|D6 3 2|E6 5 2|F6 4 3|      |B=M       |  TTR |
+*/
+
+// LDA opcodes
+
+#define OP_LDA_HANDLER(m, acc) \
+       acc = m; \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op86(void)                                                 // LDAA #
 {
-addr = DecodeIDX(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
+       uint8 m = READ_IMM;
+       OP_LDA_HANDLER(m, regs.a);
 }
 
-static void Op68(void)  // LSL IDX
+static void Op96(void)                                                 // LDAA ZP
 {
-addr = DecodeIDX(regs.RdMem(regs.pc++));
-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
+       uint8 m = READ_ZP;
+       OP_LDA_HANDLER(m, regs.a);
 }
 
-static void Op69(void)  // ROL IDX
+static void OpA6(void)                                                 // LDAA ZP, X
 {
-  uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  tmp = (tmp2<<1) + (regs.cc&0x01);
-  regs.WrMem(addr, tmp);
-  (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi 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
+       uint8 m = READ_ZP_X;
+       OP_LDA_HANDLER(m, regs.a);
 }
 
-static void Op6A(void)  // DEC IDX
+static void OpB6(void)                                                 // LDAA ABS
 {
-uint8 tmp;  uint16 addr;
-addr = DecodeIDX(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
+       uint8 m = READ_ABS;
+       OP_LDA_HANDLER(m, regs.a);
 }
 
-static void Op6C(void)  // INC IDX
-{       
-addr = DecodeIDX(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
+static void OpC6(void)                                                 // LDAB #
+{
+       uint8 m = READ_IMM;
+       OP_LDA_HANDLER(m, regs.b);
 }
 
-static void Op6D(void)  // TST IDX
+static void OpD6(void)                                                 // LDAB ZP
 {
-tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag 
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag 
+       uint8 m = READ_ZP;
+       OP_LDA_HANDLER(m, regs.b);
 }
 
-static void Op6E(void)  // JMP IDX
+static void OpE6(void)                                                 // LDAB ZP, X
 {
-  regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
+       uint8 m = READ_ZP_X;
+       OP_LDA_HANDLER(m, regs.b);
 }
 
-static void Op6F(void)  // CLR IDX
+static void OpF6(void)                                                 // LDAB ABS
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(addr, 0);
-  regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
+       uint8 m = READ_ABS;
+       OP_LDA_HANDLER(m, regs.b);
 }
 
-static void Op70(void)  // NEG ABS
-{ 
-addr = FetchW();
-tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
-regs.WrMem(addr, res);
-(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
-(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
-(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+OR, Inclusive           |ORAA |8A 2 2|9A 3 2|AA 5 2|BA 4 3|      |A=A+M     |  TTR |
+                        |ORAB |CA 2 2|DA 3 2|EA 5 2|FA 4 3|      |B=B+M     |  TTR |
+*/
+
+// ORA opcodes
+
+#define OP_ORA_HANDLER(m, acc) \
+       acc |= m; \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op8A(void)                                                 // ORAA #
+{
+       uint8 m = READ_IMM;
+       OP_ORA_HANDLER(m, regs.a);
 }
 
-static void Op73(void)  // COM ABS
+static void Op9A(void)                                                 // ORAA ZP
 {
-addr = FetchW();
-tmp = regs.RdMem(addr) ^ 0xFF;
-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
+       uint8 m = READ_ZP;
+       OP_ORA_HANDLER(m, regs.a);
 }
 
-static void Op74(void)  // LSR ABS
+static void OpAA(void)                                                 // ORAA ZP, X
 {
-addr = FetchW();
-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
+       uint8 m = READ_ZP_X;
+       OP_ORA_HANDLER(m, regs.a);
 }
 
-static void Op76(void)  // ROR ABS
+static void OpBA(void)                                                 // ORAA ABS
 {
-uint8 tmp;  uint16 addr;
-addr = FetchW();
-tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
-tmp = (tmp >> 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
+       uint8 m = READ_ABS;
+       OP_ORA_HANDLER(m, regs.a);
 }
 
-static void Op77(void)  // ASR ABS
+static void OpCA(void)                                                 // ORAB #
 {
-uint8 tmp;  uint16 addr;
-addr = FetchW();
-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
+       uint8 m = READ_IMM;
+       OP_ORA_HANDLER(m, regs.b);
 }
 
-static void Op78(void)  // LSL ABS
+static void OpDA(void)                                                 // ORAB ZP
 {
-uint8 tmp;  uint16 addr;
-addr = FetchW();
-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
+       uint8 m = READ_ZP;
+       OP_ORA_HANDLER(m, regs.b);
 }
 
-static void Op79(void)  // ROL ABS
+static void OpEA(void)                                                 // ORAB ZP, X
 {
-  uint8 tmp2 = regs.RdMem(FetchW());
-  tmp = (tmp2<<1) + (regs.cc&0x01);
-  regs.WrMem(addr, tmp);
-  (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi 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
+       uint8 m = READ_ZP_X;
+       OP_ORA_HANDLER(m, regs.b);
 }
 
-static void Op7A(void)  // DEC ABS
+static void OpFA(void)                                                 // ORAB ABS
 {
-uint8 tmp;  uint16 addr;
-addr = FetchW();
-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
+       uint8 m = READ_ABS;
+       OP_ORA_HANDLER(m, regs.b);
 }
 
-static void Op7C(void)                                                                 // INC ABS
-{       
-       addr = FetchW();
-       tmp = regs.RdMem(addr) + 1;
-       regs.WrMem(addr, tmp);
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Push Data               |PSHA |      |      |      |      |36 4 1|Msp=A, *- |      |
+                        |PSHB |      |      |      |      |37 4 1|Msp=B, *- |      |
+Pull Data               |PULA |      |      |      |      |32 4 1|A=Msp, *+ |      |
+                        |PULB |      |      |      |      |33 4 1|B=Msp, *+ |      |
+*/
 
-       (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
+static void Op36(void)                                                 // PSHA
+{
+//     regs.WrMem(--regs.s, regs.a);
+       PUSH(regs.a);
 }
 
-static void Op7D(void)                                                                 // TST ABS
+static void Op37(void)                                                 // PSHB
 {
-       uint8 tmp = regs.RdMem(FetchW());
-
-       (tmp == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);               // Adjust Zero flag 
-       (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);               // Adjust Negative flag 
+//     regs.WrMem(--regs.s, regs.b);
+       PUSH(regs.b);
 }
 
-static void Op7E(void)                                                                 // JMP ABS
+static void Op32(void)                                                 // PULA
 {
-       regs.pc = FetchW();
+//     regs.a = regs.RdMem(regs.s++);
+       regs.a = PULL;
 }
 
-static void Op7F(void)  // CLR ABS
+static void Op33(void)                                                 // PULB
 {
-regs.WrMem(FetchW(), 0);
-regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
+//     regs.b = regs.RdMem(regs.s++);
+       regs.b = PULL;
 }
 
-static void Op80(void)  // SUBA #
-{ 
-  uint8 tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a; 
-  regs.a -= tmp;
-  (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Rotate Left             |ROL  |      |      |69 7 2|79 6 3|      |Memory  *1|  TT6T|
+                        |ROLA |      |      |      |      |49 2 1|Accum A *1|  TT6T|
+                        |ROLB |      |      |      |      |59 2 1|Accum B *1|  TT6T|
+*/
+
+// ROL opcodes
+
+//#define OP_ROL_HANDLER(m) \
+       uint8 newCarry = (m & 0x80) >> 7; \
+       m = (m << 1) | (regs.cc & FLAG_C); \
+       SET_ZN(m); \
+       regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
+       regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
+#define OP_ROL_HANDLER(m) \
+       uint8 newCarry = (m & 0x80) >> 7; \
+       m = (m << 1) | flagC; \
+       SET_ZN(m); \
+       flagC = newCarry; \
+       flagV = flagN ^ flagC
+
+static void Op69(void)                                                 // ROL ZP, X
+{
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_ROL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op81(void)  // CMPA #
+static void Op79(void)                                                 // ROL ABS
 {
-  tmp = regs.RdMem(regs.pc++);
-  uint8 db = regs.a - tmp;
-  (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_ROL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op82(void)  // SBCA #
+static void Op49(void)                                                 // ROLA
 {
-  tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a; 
-  regs.a = regs.a - tmp - (regs.cc&0x01);
-  (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_ROL_HANDLER(regs.a);
 }
 
-static void Op84(void)  // ANDA #
+static void Op59(void)                                                 // ROLB
 {
-regs.a &= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_ROL_HANDLER(regs.b);
 }
 
-static void Op85(void)  // BITA #
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Rotate Right            |ROR  |      |      |66 7 2|76 6 3|      |Memory  *2|  TT6T|
+                        |RORA |      |      |      |      |46 2 1|Accum A *2|  TT6T|
+                        |RORB |      |      |      |      |56 2 1|Accum B *2|  TT6T|
+*/
+
+// ROR opcodes
+
+//#define OP_ROR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m = (m >> 1) | ((regs.cc & FLAG_C) << 7); \
+       SET_ZN(m); \
+       regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
+       regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
+#define OP_ROR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m = (m >> 1) | (flagC << 7); \
+       SET_ZN(m); \
+       flagC = newCarry; \
+       flagV = flagN ^ flagC
+
+static void Op66(void)                                                 // ROR ZP, X
 {
-tmp = regs.a & regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_ROR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op86(void)  // LDAA #
+static void Op76(void)                                                 // ROR ABS
 {
-regs.a = regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_ROR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op88(void)  // EORA #
+static void Op46(void)                                                 // RORA
 {
-regs.a ^= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_ROR_HANDLER(regs.a);
 }
 
-static void Op89(void)  // ADCA #
+static void Op56(void)                                                 // RORB
 {
-  tmp = regs.RdMem(regs.pc++);
-  addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
-//    ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half Carry
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
+       OP_ROR_HANDLER(regs.b);
 }
 
-static void Op8A(void)  // ORAA #
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Arithmetic Shift Left   |ASL  |      |      |68 7 2|78 6 3|      |Memory  *3|  TT6T|
+                        |ASLA |      |      |      |      |48 2 1|Accum A *3|  TT6T|
+                        |ASLB |      |      |      |      |58 2 1|Accum B *3|  TT6T|
+*/
+
+// ASL opcodes
+
+//#define OP_ASL_HANDLER(m) \
+       uint8 newCarry = (m & 0x80) >> 7; \
+       m <<= 1; \
+       SET_ZN(m); \
+       regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
+       regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
+#define OP_ASL_HANDLER(m) \
+       uint8 newCarry = (m & 0x80) >> 7; \
+       m <<= 1; \
+       SET_ZN(m); \
+       flagC = newCarry; \
+       flagV = flagN ^ flagC
+
+static void Op68(void)                                                 // ASL ZP, X
 {
-regs.a |= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_ASL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op8B(void)  // ADDA #
-{       
-  tmp = regs.RdMem(regs.pc++);  addr = regs.a + tmp;
-  (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void Op78(void)                                                 // ASL ABS
+{
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_ASL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op8C(void)  // CPX #
+static void Op48(void)                                                 // ASLA
 {
-       addr = FetchW();
-       uint16 dw = regs.x - addr;
-       (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-       ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_ASL_HANDLER(regs.a);
 }
 
-static void Op8D(void)                                                                 // BSR
+static void Op58(void)                                                 // ASLB
 {
-       tmp = regs.RdMem(regs.pc++);
+       OP_ASL_HANDLER(regs.b);
+}
+
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Arithmetic Shift Right  |ASR  |      |      |67 7 2|77 6 3|      |Memory  *4|  TT6T|
+                        |ASRA |      |      |      |      |47 2 1|Accum A *4|  TT6T|
+                        |ASRB |      |      |      |      |57 2 1|Accum B *4|  TT6T|
+*/
+
+// ASR opcodes
 
-       regs.s -= 2;
-       WrMemW(regs.s, regs.pc);
+//#define OP_ASR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m = (m >> 1) | (m & 0x80); \
+       SET_ZN(m); \
+       regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
+       regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
+#define OP_ASR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m = (m >> 1) | (m & 0x80); \
+       SET_ZN(m); \
+       flagC = newCarry; \
+       flagV = flagN ^ flagC
 
-       regs.pc += (signed short int)(signed char)tmp;
+static void Op67(void)                                                 // ASR ZP, X
+{
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_ASR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op8E(void)  // LDS #
+static void Op77(void)                                                 // ASR ABS
 {
-regs.s = FetchW();
-regs.cc &= 0xFD;                              // CLV
-(regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_ASR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op90(void)  // SUBA ZP
-{ 
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 as = regs.a; 
-  regs.a -= tmp;
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+static void Op47(void)                                                 // ASRA
+{
+       OP_ASR_HANDLER(regs.a);
 }
 
-static void Op91(void)  // CMPA ZP
+static void Op57(void)                                                 // ASRB
 {
-tmp = regs.RdMem(regs.RdMem(regs.pc++));
-uint8 db = regs.a - tmp;
-(db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       OP_ASR_HANDLER(regs.b);
 }
 
-static void Op92(void)  // SBCA ZP
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Logic Shift Right       |LSR  |      |      |64 7 2|74 6 3|      |Memory  *5|  TT6T|
+                        |LSRA |      |      |      |      |44 2 1|Accum A *5|  TT6T|
+                        |LSRB |      |      |      |      |54 2 1|Accum B *5|  TT6T|
+*/
+
+// LSR opcodes
+
+//#define OP_LSR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m >>= 1; \
+       SET_ZN(m); \
+       regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
+       regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
+#define OP_LSR_HANDLER(m) \
+       uint8 newCarry = m & 0x01; \
+       m >>= 1; \
+       SET_ZN(m); \
+       flagC = newCarry; \
+       flagV = flagN ^ flagC
+
+static void Op64(void)                                                 // LSR ZP, X
 {
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 as = regs.a; 
-  regs.a = regs.a - tmp - (regs.cc&0x01);
-  (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_LSR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op94(void)  // ANDA ZP
+static void Op74(void)                                                 // LSR ABS
 {
-  regs.a &= regs.RdMem(regs.RdMem(regs.pc++));
-  regs.cc &= 0xF1;                   // CLV CLZ CLN
-  if (regs.a == 0)  regs.cc |= 0x04;     // Adjust Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;     // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_LSR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op95(void)  // BITA ZP
+static void Op44(void)                                                 // LSRA
 {
-tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_LSR_HANDLER(regs.a);
 }
 
-static void Op96(void)  // LDAA ZP
+static void Op54(void)                                                 // LSRB
 {
-  regs.a = regs.RdMem(regs.RdMem(regs.pc++));
-  regs.cc &= 0xF1;                            // CLN CLZ CLV
-  if (regs.a == 0)  regs.cc |= 0x04;              // Set Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;              // Set Negative flag
+       OP_LSR_HANDLER(regs.b);
 }
 
-static void Op97(void)  // STAA ZP
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Store Accumulator       |STAA |      |97 4 2|A7 6 2|B7 5 3|      |M=A       |  TTR |
+                        |STAB |      |D7 4 2|E7 6 2|F7 5 3|      |M=B       |  TTR |
+*/
+
+static void Op97(void)                                                 // STAA ZP
 {
-regs.WrMem(regs.RdMem(regs.pc++), regs.a);
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.WrMem(EA_ZP, regs.a);
 }
 
-static void Op98(void)  // EORA ZP
+static void OpA7(void)                                                 // STAA ZP, X
 {
-regs.a ^= regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.WrMem(EA_ZP_X, regs.a);
 }
 
-static void Op99(void)  // ADCA ZP
+static void OpB7(void)                                                 // STAA ABS
 {
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));
-  addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
+       regs.WrMem(EA_ABS, regs.a);
+       regs.pc += 2;
 }
 
-static void Op9A(void)  // ORAA ZP
+static void OpD7(void)                                                 // STAB ZP
 {
-regs.a |= regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.WrMem(EA_ZP, regs.b);
 }
 
-static void Op9B(void)  // ADDA ZP
-{       
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));
-  addr = (uint16)regs.a + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void OpE7(void)                                                 // STAB ZP, X
+{
+       regs.WrMem(EA_ZP_X, regs.b);
 }
 
-static void Op9C(void)  // CPX ZP
+static void OpF7(void)                                                 // STAB ABS
 {
-addr = regs.RdMem(regs.pc++);
-uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-uint16 dw = regs.x - adr2;
-(dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+       regs.WrMem(EA_ABS, regs.b);
+       regs.pc += 2;
 }
 
-static void Op9E(void)                                                                 // LDS ZP
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Subtract                |SUBA |80 2 2|90 3 2|A0 5 2|B0 4 3|      |A=A-M     |  TTTT|
+                        |SUBB |C0 2 2|D0 3 2|E0 5 2|F0 4 3|      |B=B-M     |  TTTT|
+Subtract Accumulators   |SBA  |      |      |      |      |10 2 1|A=A-B     |  TTTT|
+*/
+
+// SUB opcodes
+
+//#define OP_SUB_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc - (m); \
+       regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \
+       SET_V(m, acc, sum); \
+       acc = (uint8)sum; \
+       SET_ZN(acc)
+#define OP_SUB_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc - (m); \
+       flagC = sum >> 15; \
+       SET_V(m, acc, sum); \
+       acc = (uint8)sum; \
+       SET_ZN(acc)
+
+static void Op80(void)                                                 // SUBA #
 {
-       regs.s = RdMemW(regs.RdMem(regs.pc++));
+       uint16 m = READ_IMM;
+       OP_SUB_HANDLER(m, regs.a);
+}
 
-       regs.cc &= 0xFD;                              // CLV
-       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+static void Op90(void)                                                 // SUBA ZP
+{
+       uint16 m = READ_ZP;
+       OP_SUB_HANDLER(m, regs.a);
 }
 
-static void Op9F(void)                                                                 // STS ZP
+static void OpA0(void)                                                 // SUBA ZP, X
 {
-       WrMemW(regs.RdMem(regs.pc++), regs.s);
+       uint16 m = READ_ZP_X;
+       OP_SUB_HANDLER(m, regs.a);
+}
 
-       regs.cc &= 0xFD;                              // CLV
-       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+static void OpB0(void)                                                 // SUBA ABS
+{
+       uint16 m = READ_ABS;
+       OP_SUB_HANDLER(m, regs.a);
 }
 
-static void OpA0(void)  // SUBA IDX
-{ 
-tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a; 
-regs.a -= tmp;
-(regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+static void OpC0(void)                                                 // SUBB #
+{
+       uint16 m = READ_IMM;
+       OP_SUB_HANDLER(m, regs.b);
 }
 
-static void OpA1(void)  // CMPA IDX
+static void OpD0(void)                                                 // SUBB ZP
 {
-tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-uint8 db = regs.a - tmp;
-(db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       uint16 m = READ_ZP;
+       OP_SUB_HANDLER(m, regs.b);
 }
 
-static void OpA2(void)  // SBCA IDX
+static void OpE0(void)                                                 // SUBB ZP, X
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a; 
-  regs.a = regs.a - tmp - (regs.cc&0x01);
-  (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_ZP_X;
+       OP_SUB_HANDLER(m, regs.b);
 }
 
-static void OpA4(void)  // ANDA IDX
+static void OpF0(void)                                                 // SUBB ABS
 {
-regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_ABS;
+       OP_SUB_HANDLER(m, regs.b);
 }
 
-static void OpA5(void)  // BITA IDX
+static void Op10(void)                                                 // SBA
 {
-tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_SUB_HANDLER(regs.b, regs.a);
 }
 
-static void OpA6(void)  // LDAA IDX
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Subtract with Carry     |SBCA |82 2 2|92 3 2|A2 5 2|B2 4 3|      |A=A-M-C   |  TTTT|
+                        |SBCB |C2 2 2|D2 3 2|E2 5 2|F2 4 3|      |B=B-M-C   |  TTTT|
+*/
+
+// SBC opcodes
+
+//#define OP_SBC_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc - (m) - (uint16)(regs.cc & FLAG_C); \
+       regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \
+       SET_V(m, acc, sum); \
+       acc = (uint8)sum; \
+       SET_ZN(acc)
+#define OP_SBC_HANDLER(m, acc) \
+       uint16 sum = (uint16)acc - (m) - (uint16)flagC; \
+       flagC = sum >> 15; \
+       SET_V(m, acc, sum); \
+       acc = (uint8)sum; \
+       SET_ZN(acc)
+
+static void Op82(void)                                                 // SBCA #
 {
-  regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  regs.cc &= 0xF1;                        // CLV CLZ CLN
-  if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
+       uint16 m = READ_IMM;
+       OP_SBC_HANDLER(m, regs.a);
 }
 
-static void OpA7(void)  // STAA IDX
+static void Op92(void)                                                 // SBCA ZP
 {
-  regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
-  regs.cc &= 0xF1;                        // CLV CLZ CLN
-  if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
+       uint16 m = READ_ZP;
+       OP_SBC_HANDLER(m, regs.a);
 }
 
-static void OpA8(void)  // EORA IDX
+static void OpA2(void)                                                 // SBCA ZP, X
 {
-regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // CLV
-(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_ZP_X;
+       OP_SBC_HANDLER(m, regs.a);
 }
 
-static void OpA9(void)  // ADCA IDX
+static void OpB2(void)                                                 // SBCA ABS
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+       uint16 m = READ_ABS;
+       OP_SBC_HANDLER(m, regs.a);
 }
 
-static void OpAA(void)  // ORAA IDX
+static void OpC2(void)                                                 // SBCB #
 {
-  regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  regs.cc &= 0xFD;                            // CLV
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_IMM;
+       OP_SBC_HANDLER(m, regs.b);
 }
 
-static void OpAB(void)  // ADDA IDX
-{       
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16)regs.a + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void OpD2(void)                                                 // SBCB ZP
+{
+       uint16 m = READ_ZP;
+       OP_SBC_HANDLER(m, regs.b);
 }
 
-static void OpAC(void)  // CPX IDX
+static void OpE2(void)                                                 // SBCB ZP, X
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  uint16 dw = regs.x - addr2;
-  (dw == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dw&0x8000  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       uint16 m = READ_ZP_X;
+       OP_SBC_HANDLER(m, regs.b);
 }
 
-static void OpAD(void)                                                                 // JSR IDX
+static void OpF2(void)                                                 // SBCB ABS
 {
-       addr = DecodeIDX(regs.RdMem(regs.pc++));
+       uint16 m = READ_ABS;
+       OP_SBC_HANDLER(m, regs.b);
+}
 
-       regs.s -= 2;
-       WrMemW(regs.s, regs.pc);
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Transfer Accumulators   |TAB  |      |      |      |      |16 2 1|B=A       |  TTR |
+                        |TBA  |      |      |      |      |17 2 1|A=B       |  TTR |
+*/
 
-       regs.pc = addr;                                                                         // JSR directly to IDX ptr
+static void Op16(void)                                                 // TAB
+{
+       regs.b = regs.a;
+       SET_ZN(regs.b);
+       CLR_V;
 }
 
-static void OpAE(void)                                                                 // LDS IDX
+static void Op17(void)                                                 // TBA
 {
-       regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++)));
-
-       regs.cc &= ~FLAG_V;
-       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.a = regs.b;
+       SET_ZN(regs.a);
+       CLR_V;
 }
 
-static void OpAF(void)                                                                 // STS IDX
-{
-       WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s);
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Test, Zero/Minus        |TST  |      |      |6D 7 2|7D 6 3|      |M-00      |  TTRR|
+                        |TSTA |      |      |      |      |4D 2 1|A-00      |  TTRR|
+                        |TSTB |      |      |      |      |5D 2 1|B-00      |  TTRR|
+*/
 
-       regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);                         // Clear NZV
-       if (regs.s & 0x8000)  regs.cc |= FLAG_N;                        // Set Negative flag
-       if (regs.s == 0)      regs.cc |= FLAG_Z;                        // Set Zero flag
-}
+// TST opcodes
 
-static void OpB0(void)  // SUBA ABS
-{ 
-tmp = regs.RdMem(FetchW());  uint8 as = regs.a; 
-regs.a -= tmp;
-(regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-}
+#define OP_TST_HANDLER(m) \
+       SET_ZN(m); \
+       CLR_VC
 
-static void OpB1(void)  // CMPA ABS
+static void Op6D(void)                                                 // TST ZP, X
 {
-tmp = regs.RdMem(FetchW());
-uint8 db = regs.a - tmp;
-(db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       uint8 m;
+       READ_ZP_X_WB(m);
+       OP_TST_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void OpB2(void)  // SBCA ABS
+static void Op7D(void)                                                 // TST ABS
 {
-  tmp = regs.RdMem(FetchW());  uint8 as = regs.a; 
-  regs.a = regs.a - tmp - (regs.cc&0x01);
-  (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint8 m;
+       READ_ABS_WB(m);
+       OP_TST_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void OpB4(void)  // ANDA ABS
+static void Op4D(void)                                                 // TSTA
 {
-  regs.a &= regs.RdMem(FetchW());
-  regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_TST_HANDLER(regs.a);
 }
 
-static void OpB5(void)  // BITA ABS
+static void Op5D(void)                                                 // TSTB
 {
-  tmp = regs.a & regs.RdMem(FetchW());
-  regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       OP_TST_HANDLER(regs.b);
 }
 
-static void OpB6(void)  // LDAA ABS
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Compare Index Register  |CPX  |8C 3 3|9C 4 2|AC 6 2|BC 5 3|      |Formula 1 |  7T8 |
+*/
+
+// CPX opcodes
+
+/*
+Compare sets flags as if a subtraction had been carried out. If the value in the X register is equal or greater than the compared value, the Carry will be set. The equal (Z) and sign (S) flags will be set based on equality or lack thereof and the sign (i.e. X>=$8000) of the X register.
+*/
+
+#define OP_CPX_HANDLER(m) \
+       uint32 result = regs.x - (m); \
+       SET_ZNVC_CMP16(m, regs.x, result)
+
+static void Op8C(void)                                                 // CPX #
 {
-  regs.a = regs.RdMem(FetchW());
-  regs.cc &= 0xFD;                            // CLV
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_IMM16;
+       OP_CPX_HANDLER(m);
 }
 
-static void OpB7(void)  // STAA ABS
+static void Op9C(void)                                                 // CPX ZP
 {
-  regs.WrMem(FetchW(), regs.a);
-  regs.cc &= 0xFD;                            // CLV
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_ZP16;
+       OP_CPX_HANDLER(m);
 }
 
-static void OpB8(void)  // EORA ABS
+static void OpAC(void)                                                 // CPX ZP, X
 {
-  regs.a ^= regs.RdMem(FetchW());
-  regs.cc &= 0xFD;                            // CLV
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = READ_ZP_X16;
+       OP_CPX_HANDLER(m);
 }
 
-static void OpB9(void)  // ADCA ABS
+static void OpBC(void)                                                 // CPX ABS
 {
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.a = addr;                              // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+       uint16 m = READ_ABS16;
+       OP_CPX_HANDLER(m);
 }
 
-static void OpBA(void)  // ORAA ABS
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Decrement Index Register|DEX  |      |      |      |      |09 4 1|X=X-1     |   T  |
+Dec Stack Pointer       |DES  |      |      |      |      |34 4 1|SP=SP-1   |      |
+Inc Index Regster       |INX  |      |      |      |      |08 4 1|X=X+1     |   T  |
+Inc Stack Pointer       |INS  |      |      |      |      |31 4 1|SP=SP+1   |      |
+*/
+
+static void Op09(void)                                                 // DEX
 {
-  regs.a |= regs.RdMem(FetchW());
-  regs.cc &= 0xFD;                            // CLV
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.x--;
+       SET_Z(regs.x);
 }
 
-static void OpBB(void)  // ADDA ABS
-{       
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16)regs.a + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
-  regs.a = addr & 0xFF;                       // Set accumulator
-  (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void Op34(void)                                                 // DES
+{
+       regs.s--;
 }
 
-static void OpBC(void)  // CPX ABS
+static void Op08(void)                                                 // INX
 {
-  addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  uint16 dw = regs.x - addr2;
-  (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       regs.x++;
+       SET_Z(regs.x);
 }
 
-static void OpBD(void)                                                                 // JSR ABS
+static void Op31(void)                                                 // INS
 {
-       addr = FetchW();
+       regs.s++;
+}
 
-       regs.s -= 2;
-       WrMemW(regs.s, regs.pc);
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Load Index Register     |LDX  |CE 3 3|DE 4 2|EE 6 2|FE 5 3|      |Formula 2 |  9TR |
+Load Stack Pointer      |LDS  |8E 3 3|9E 4 2|AE 6 2|BE 5 3|      |Formula 3 |  9TR |
+*/
 
-       regs.pc = addr;                                                                         // Go to absolute address (Not indir)
-}
+// LD* opcode handler
+
+#define OP_LD_HANDLER(acc) \
+       SET_N16(acc); \
+       SET_Z(acc); \
+       CLR_V
 
-static void OpBE(void)  // LDS ABS
+static void OpCE(void)                                                 // LDX #
 {
-  addr = FetchW();
-  regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-  regs.cc &= 0xFD;                              // CLV
-  (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.x = READ_IMM16;
+       OP_LD_HANDLER(regs.x);
 }
 
-static void OpBF(void)  // STS ABS
+static void OpDE(void)                                                 // LDX ZP
 {
-addr = FetchW();
-regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
-regs.cc &= 0xFD;                              // CLV
-(regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.x = READ_ZP16;
+       OP_LD_HANDLER(regs.x);
 }
 
-static void OpC0(void)  // SUBB #
-{ 
-tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b; 
-regs.b -= tmp;
-(regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+static void OpEE(void)                                                 // LDX ZP, X
+{
+       regs.x = READ_ZP_X16;
+       OP_LD_HANDLER(regs.x);
 }
 
-static void OpC1(void)  // CMPB #
+static void OpFE(void)                                                 // LDX ABS
 {
-tmp = regs.RdMem(regs.pc++);
-uint8 db = regs.b - tmp;
-(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-(db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.x = READ_ABS16;
+       OP_LD_HANDLER(regs.x);
 }
 
-static void OpC2(void)  // SBCB #
+static void Op8E(void)                                                 // LDS #
 {
-  tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b; 
-  regs.b = regs.b - tmp - (regs.cc&0x01);
-  (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.s = READ_IMM16;
+       OP_LD_HANDLER(regs.s);
 }
 
-static void OpC4(void)  // ANDB #
+static void Op9E(void)                                                 // LDS ZP
 {
-regs.b &= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.s = READ_ZP16;
+       OP_LD_HANDLER(regs.s);
 }
 
-static void OpC5(void)  // BITB #
+static void OpAE(void)                                                 // LDS ZP, X
 {
-  tmp = regs.b & regs.RdMem(regs.pc++);
-  regs.cc &= 0xF1;                             // CLV CLZ CLN
-  if (tmp == 0)  regs.cc |= 0x04;              // Set Zero flag
-  if (tmp&0x80)  regs.cc |= 0x08;              // Set Negative flag
+       regs.s = READ_ZP_X16;
+       OP_LD_HANDLER(regs.s);
 }
 
-static void OpC6(void)  // LDAB #
+static void OpBE(void)                                                 // LDS ABS
 {
-  regs.b = regs.RdMem(regs.pc++);
-  regs.cc &= 0xF1;                             // CLV CLZ CLN
-  if (regs.b == 0)  regs.cc |= 0x04;               // Set Zero flag
-  if (regs.b&0x80)  regs.cc |= 0x08;               // Set Negative flag
+       regs.s = READ_ABS16;
+       OP_LD_HANDLER(regs.s);
 }
 
-static void OpC8(void)  // EORB #
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Store Index Register    |STX  |      |DF 5 2|EF 7 2|FF 6 3|      |Formula 4 |  9TR |
+Store Stack Pointer     |STS  |      |9F 5 2|AF 7 2|BF 6 3|      |Formula 5 |  9TR |
+*/
+
+// ST* opcode handler
+
+#define OP_ST_HANDLER(m, acc) \
+       regs.WrMem(m + 0, acc >> 8); \
+       regs.WrMem(m + 1, acc & 0xFF); \
+       SET_N16(acc); \
+       SET_Z(acc); \
+       CLR_V
+
+static void OpDF(void)                                                 // STX ZP
 {
-regs.b ^= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = EA_ZP;
+       OP_ST_HANDLER(m, regs.x);
 }
 
-static void OpC9(void)  // ADCB #
+static void OpEF(void)                                                 // STX ZP, X
 {
-  tmp = regs.RdMem(regs.pc++);
-  addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.b = addr & 0xFF;                       // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+       uint16 m = EA_ZP_X;
+       OP_ST_HANDLER(m, regs.x);
 }
 
-static void OpCA(void)  // ORAB #
+static void OpFF(void)                                                 // STX ABS
 {
-regs.b |= regs.RdMem(regs.pc++);
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = EA_ABS;
+       regs.pc += 2;
+       OP_ST_HANDLER(m, regs.x);
 }
 
-static void OpCB(void)  // ADDB #
-{       
-  tmp = regs.RdMem(regs.pc++);  addr = regs.b + tmp;
-  (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.b = addr & 0xFF;                       // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void Op9F(void)                                                 // STS ZP
+{
+       uint16 m = EA_ZP;
+       OP_ST_HANDLER(m, regs.s);
 }
 
-static void OpCE(void)  // LDX #
+static void OpAF(void)                                                 // STS ZP, X
 {
-  regs.x = FetchW();
-  regs.cc &= 0xFD;                              // CLV
-  (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       uint16 m = EA_ZP_X;
+       OP_ST_HANDLER(m, regs.s);
 }
 
-static void OpD0(void)  // SUBB ZP
-{ 
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 bs = regs.b; 
-  regs.b -= tmp;
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+static void OpBF(void)                                                 // STS ABS
+{
+       uint16 m = EA_ABS;
+       regs.pc += 2;
+       OP_ST_HANDLER(m, regs.s);
 }
 
-static void OpD1(void)  // CMPB ZP
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Index Reg > Stack Pnter |TXS  |      |      |      |      |35 4 1|SP=X-1    |      |
+Stack Ptr > Index Regtr |TSX  |      |      |      |      |30 4 1|X=SP+1    |      |
+*/
+
+static void Op35(void)                                                 // TXS
 {
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));
-  uint8 db = regs.b - tmp;
-  (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       regs.s = regs.x - 1;
 }
 
-static void OpD2(void)  // SBCB ZP
+static void Op30(void)                                                 // TSX
 {
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 bs = regs.b; 
-  regs.b = regs.b - tmp - (regs.cc&0x01);
-  (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.x = regs.s + 1;
 }
 
-static void OpD4(void)  // ANDB ZP
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Always                  |BRA  |      |20 4 2|      |      |      |none      |      |
+Carry is Clear          |BCC  |      |24 4 2|      |      |      |C=0       |      |
+Carry is Set            |BCS  |      |25 4 2|      |      |      |C=1       |      |
+Equals Zero             |BEQ  |      |27 4 2|      |      |      |Z=1       |      |
+Greater or Equal to Zero|BGE  |      |2C 4 2|      |      |      |N(+)V=0   |      |
+Greater than Zero       |BGT  |      |2E 4 2|      |      |      |Z+N(+)V=0 |      |
+Higher                  |BHI  |      |22 4 2|      |      |      |C+Z=0     |      |
+Less or Equal than Zero |BLE  |      |2F 4 2|      |      |      |Z+N(+)V=1 |      |
+Lower or Same           |BLS  |      |23 4 2|      |      |      |C+Z=1     |      |
+Less Than Zero          |BLT  |      |2D 4 2|      |      |      |N(+)V=1   |      |
+Minus                   |BMI  |      |2B 4 2|      |      |      |N=1       |      |
+Not Zero                |BNE  |      |26 4 2|      |      |      |Z=0       |      |
+Overflow Clear          |BVC  |      |28 4 2|      |      |      |V=0       |      |
+Overflow Set            |BVS  |      |29 4 2|      |      |      |V=1       |      |
+Plus                    |BPL  |      |2A 4 2|      |      |      |N=0       |      |
+*/
+
+static void Op20(void)                                                 // BRA
 {
-regs.b &= regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                            // Clear oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+       regs.pc += m;
 }
 
-static void OpD5(void)  // BITB ZP
+static void Op24(void)                                                 // BCC
 {
-tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                             // Clear oVerflow flag
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(regs.cc & FLAG_C))
+       if (!flagC)
+               regs.pc += m;
 }
 
-static void OpD6(void)  // LDAB ZP
+static void Op25(void)                                                 // BCS
 {
-  regs.b = regs.RdMem(regs.RdMem(regs.pc++));
-  regs.cc &= 0xFD;                            // CLV
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (regs.cc & FLAG_C)
+       if (flagC)
+               regs.pc += m;
 }
 
-static void OpD7(void)  // STAB ZP
+static void Op27(void)                                                 // BEQ
 {
-regs.WrMem(regs.RdMem(regs.pc++), regs.b);
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (regs.cc & FLAG_Z)
+       if (flagZ)
+               regs.pc += m;
 }
 
-static void OpD8(void)  // EORB ZP
+static void Op2C(void)                                                 // BGE
 {
-regs.b ^= regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)))
+       if (!(flagN ^ flagV))
+               regs.pc += m;
 }
 
-static void OpD9(void)  // ADCB ZP
+static void Op2E(void)                                                 // BGT
 {
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));
-  addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.b = addr;                              // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))))
+       if (!(flagZ | (flagN ^ flagV)))
+               regs.pc += m;
 }
 
-static void OpDA(void)  // ORAB ZP
+static void Op22(void)                                                 // BHI
 {
-regs.b |= regs.RdMem(regs.RdMem(regs.pc++));
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-}
+       int16 m = (int16)(int8)READ_IMM;
 
-static void OpDB(void)  // ADDB ZP
-{       
-  tmp = regs.RdMem(regs.RdMem(regs.pc++));
-  addr = (uint16)regs.b + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.b = addr & 0xFF;                       // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+//     if (!(((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C)))
+       if (!(flagZ | flagC))
+               regs.pc += m;
 }
 
-static void OpDE(void)  // LDX ZP
+static void Op2F(void)                                                 // BLE
 {
-  addr = regs.RdMem(regs.pc++);
-  regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-  regs.cc &= 0xFD;                              // CLV
-  (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)))
+       if (flagZ | (flagN ^ flagV))
+               regs.pc += m;
 }
 
-static void OpDF(void)  // STX ZP
+static void Op23(void)                                                 // BLS
 {
-  addr = regs.RdMem(regs.pc++);
-  regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
-  regs.cc &= 0xFD;                              // CLV
-  (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-}
+       int16 m = (int16)(int8)READ_IMM;
 
-static void OpE0(void)  // SUBB IDX
-{ 
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b; 
-  regs.b -= tmp;
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+//     if (((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C))
+       if (flagZ | flagC)
+               regs.pc += m;
 }
 
-static void OpE1(void)  // CMPB IDX
+static void Op2D(void)                                                 // BLT
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  uint8 db = regs.b - tmp;
-  (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))
+       if (flagN ^ flagV)
+               regs.pc += m;
 }
 
-static void OpE2(void)  // SBCB IDX
+static void Op2B(void)                                                 // BMI
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b; 
-  regs.b = regs.b - tmp - (regs.cc&0x01);
-  (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (regs.cc & FLAG_N)
+       if (flagN)
+               regs.pc += m;
 }
 
-static void OpE4(void)  // ANDB IDX
+static void Op26(void)                                                 // BNE
 {
-regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // Clear oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(regs.cc & FLAG_Z))
+       if (!flagZ)
+               regs.pc += m;
 }
 
-static void OpE5(void)  // BITB IDX
+static void Op28(void)                                                 // BVC
 {
-tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                             // Clear oVerflow flag
-(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(regs.cc & FLAG_V))
+       if (!flagV)
+               regs.pc += m;
 }
 
-static void OpE6(void)  // LDB IDX
+static void Op29(void)                                                 // BVS
 {
-regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (regs.cc & FLAG_V)
+       if (flagV)
+               regs.pc += m;
 }
 
-static void OpE7(void)  // STB IDX
+static void Op2A(void)                                                 // BPL
 {
-  regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
-  regs.cc &= 0xF1;                            // CLV CLZ CLN
-  if (regs.b == 0)  regs.cc |= 0x04;              // Adjust Zero flag
-  if (regs.b&0x80)  regs.cc |= 0x08;              // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+
+//     if (!(regs.cc & FLAG_N))
+       if (!flagN)
+               regs.pc += m;
 }
 
-static void OpE8(void)  // EORB IDX
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Branch to Subroutine    |BSR  |      |8D 8 2|      |      |      |          |      |
+Jump                    |JMP  |      |      |6E 4 2|7E 3 3|      |          |      |
+Jump to Subroutine      |JSR  |      |      |AD 8 2|BD 9 3|      |          |      |
+*/
+
+static void Op8D(void)                                                 // BSR
 {
-regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       int16 m = (int16)(int8)READ_IMM;
+       PUSH16(regs.pc);
+       regs.pc += m;
 }
 
-static void OpE9(void)  // ADCB IDX
+static void Op6E(void)                                                 // JMP ZP, X
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.b = addr;                                  // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+       regs.pc = EA_ZP_X;
 }
 
-static void OpEA(void)  // ORB IDX
+static void Op7E(void)                                                 // JMP ABS
 {
-regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.pc = EA_ABS;
 }
 
-static void OpEB(void)  // ADDB IDX
-{       
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16)regs.b + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
-  regs.b = addr;                              // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+static void OpAD(void)                                                 // JSR ZP, X
+{
+       uint16 m = EA_ZP_X;
+       PUSH16(regs.pc);
+       regs.pc = m;
 }
 
-static void OpEE(void)  // LDX IDX
+static void OpBD(void)                                                 // JSR ABS
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-  regs.cc &= 0xF1;                              // CLV CLZ CLN
-  if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
-  if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
+       uint16 m = EA_ABS;
+       regs.pc += 2;
+       PUSH16(regs.pc);
+       regs.pc = m;
 }
 
-static void OpEF(void)  // STX IDX
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+No Operation            |NOP  |      |      |      |      |01 2 1|          |      |
+Return from Interrupt   |RTI  |      |      |      |      |3B A 1|          |AAAAAA|
+Return from Subroutine  |RTS  |      |      |      |      |39 5 1|          |      |
+Software Interrupt      |SWI  |      |      |      |      |3F C 1|          | S    |
+Wait For Interrupt      |WAI  |      |      |      |      |3E 9 1|          | B    |
+*/
+
+static void Op01(void)                                                 // NOP
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
-  regs.cc &= 0xF1;                              // CLV CLZ CLN
-  if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
-  if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
 }
 
-static void OpF0(void)  // SUBB ABS
-{ 
-tmp = regs.RdMem(FetchW());  uint8 bs = regs.b; 
-regs.b -= tmp;
-(regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+static void Op3B(void)                                                 // RTI
+{
+       regs.cc = PULL;
+       regs.a  = PULL;
+       regs.b  = PULL;
+       regs.x  = PULL16;
+       regs.pc = PULL16;
+       UNPACK_FLAGS;
 }
 
-static void OpF1(void)  // CMPB ABS
+static void Op39(void)                                                 // RTS
 {
-tmp = regs.RdMem(FetchW());
-uint8 db = regs.b - tmp;
-(db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       regs.pc = PULL16;
 }
 
-static void OpF2(void)  // SBCB ABS
+static void Op3F(void)                                                 // SWI
 {
-  tmp = regs.RdMem(FetchW());  uint8 bs = regs.b; 
-  regs.b = regs.b - tmp - (regs.cc&0x01);
-  (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+       // It seems that the SWI is non-maskable, unlike the IRQ...
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
+       PUSH16(regs.pc);                                                        // Save all regs...
+       PUSH16(regs.x);
+       PUSH(regs.b);
+       PUSH(regs.a);
+       PUSH(regs.cc);
+       regs.pc = RdMemW(0xFFFA);                                       // And do it!
+//     regs.cc |= FLAG_I;                                                      // Also, set IRQ inhibit
+       flagI = 1;                                                                      // Also, set IRQ inhibit
 }
 
-static void OpF4(void)  // ANDB ABS
+static void Op3E(void)                                                 // WAI
 {
-regs.b &= regs.RdMem(FetchW());
-regs.cc &= 0xFD;                            // Clear oVerflow flag
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-}
+#ifdef __DEBUG__
+WriteLog("*** WAI STATE ASSERTED ***\n");
+#endif
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
+       PUSH16(regs.pc);                                                        // Save all regs...
+       PUSH16(regs.x);
+       PUSH(regs.b);
+       PUSH(regs.a);
+       PUSH(regs.cc);
+       regs.cpuFlags |= V6808_STATE_WAI;                       // And signal that we're in WAI mode
+}
+
+/*
+Operation               |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+                        |     |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #|          |HINZVC|
+Clear Carry             |CLC  |      |      |      |      |0C 2 1|C=0       |     R|
+Clear Interrupt         |CLI  |      |      |      |      |0E 2 1|I=0       | R    |
+Clear Overflow          |CLV  |      |      |      |      |0A 2 1|V=0       |    R |
+Set Carry               |SEC  |      |      |      |      |0D 2 1|C=1       |     S|
+Set Interrupt           |SEI  |      |      |      |      |0F 2 1|I=1       | S    |
+Set Overflow            |SEV  |      |      |      |      |0B 2 1|V=1       |    S |
+CCR=Accumulator A       |TAP  |      |      |      |      |06 2 1|CCR=A     |CCCCCC|
+Accumlator A=CCR        |TPA  |      |      |      |      |07 2 1|A=CCR     |      |
+*/
 
-static void OpF5(void)  // BITB ABS
+static void Op0C(void)                                                 // CLC
 {
-tmp = regs.b & regs.RdMem(FetchW());
-regs.cc &= 0xFD;                             // Clear 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.cc &= ~FLAG_C;
+       flagC = 0;
 }
 
-static void OpF6(void)  // LDB ABS
+static void Op0E(void)                                                 // CLI
 {
-regs.b = regs.RdMem(FetchW());
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+//     regs.cc &= ~FLAG_I;
+       flagI = 0;
 }
 
-static void OpF7(void)  // STB ABS
+static void Op0A(void)                                                 // CLV
 {
-regs.WrMem(FetchW(), regs.b);
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+//     regs.cc &= ~FLAG_V;
+       flagV = 0;
 }
 
-static void OpF8(void)  // EORB ABS
+static void Op0D(void)                                                 // SEC
 {
-regs.b ^= regs.RdMem(FetchW());
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+//     regs.cc |= FLAG_C;
+       flagC = 1;
 }
 
-static void OpF9(void)  // ADCB ABS
+static void Op0F(void)                                                 // SEI
 {
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.b = addr & 0xFF;                       // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+//     regs.cc |= FLAG_I;
+       flagI = 1;
 }
 
-static void OpFA(void)  // ORB ABS
+static void Op0B(void)                                                 // SEV
 {
-regs.b |= regs.RdMem(FetchW());
-regs.cc &= 0xFD;                            // CLV
-(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-}       
-
-static void OpFB(void)  // ADDB ABS
-{       
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16)regs.b + (uint16)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
-  regs.b = addr & 0xFF;                       // Set accumulator
-  (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
-  (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+//     regs.cc |= FLAG_V;
+       flagV = 1;
 }
 
-static void OpFE(void)  // LDX ABS
+static void Op06(void)                                                 // TAP
 {
-addr = FetchW();
-regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-regs.cc &= 0xFD;                              // CLV
-(regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+       regs.cc = regs.a;
+       UNPACK_FLAGS;
 }
 
-static void OpFF(void)  // STX ABS
+static void Op07(void)                                                 // TPA
 {
-addr = FetchW();
-regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
-regs.cc &= 0xFD;                              // CLV
-(regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-}
+//     regs.a = regs.cc;
+       regs.a = PACK_FLAGS;
+}
+
+/*
+  OP  Operation Code, in Hexadecimal
+  ~   Number of MPU cycles required
+  #   Number of program bytes required
+  +   Arithmetic Plus
+  -   Arithmetic Minus
+  +   Boolean AND
+  Msp Contents of Memory pointed to be Stack Pointer
+  +   Boolean Inclusive OR
+  (+) Boolean Exclusive OR (XOR)
+  *   Converts Binary Addition of BCD Characters into BCD Format
+  *-  SP=SP-1
+  *+  SP=SP+1
+
+  Condition Code Register Legend
+     Not Affected
+   R Reset (0, Low)
+   S Set   (1, High)
+   T Tests and sets if True, cleared otherise
+   1 Test: Result=10000000?
+   2 Test: Result=00000000?
+   3 Test: Decimal value of most significant BCD character greater than nine?
+           (Not cleared if previously set)
+   4 Test: Operand=10000000 prior to execution?
+   5 Test: Operand=01111111 prior to execution?
+   6 Test: Set equal to result or N(+)C after shift has occurred.
+   7 Test: Sign bit of most significant byte or result=1?
+   8 Test: 2's compliment overflow from subtraction of least 
+           significant bytes?
+   9 Test: Result less than zero? (Bit 15=1)
+   A Load Condition Code Register from Stack.
+   B Set when interrupt occurs.  If previously set, a NMI is 
+        required to exit the wait state.
+   C Set according to the contents of Accumulator A.
+
+  *x SHIFT AND ROTATION DIAGRAMS
+   *1     +-----------------+       C to LSB
+          - C <- 76543210 <-+
+
+   *2    +-----------------+
+         +> C -> 76543210 -+
+
+   *3       C <- 76543210 <- 0(Data) 
+               +-+
+
+   *4          À>76543210 -> C
+
+   *5 (Data)0 -> 76543210 -> C
+
+  FORMULAS
+   1: (Xh/Xl)-(M/M+1)
+   2: Xh=M, Xl=M+1
+   3: SPh=M, SPl=M+1
+   4: M=Xh, M+1=Xl
+*/
 
 static void Op__(void)
 {
@@ -1842,49 +2091,66 @@ static void myMemcpy(void * dst, void * src, uint32 size)
                d[i] = s[i];
 }
 
+#ifdef __DEBUG__
 //int instCount[256];
+static bool logGo = false;
+#endif
 //
 // Function to execute 6808 for "cycles" cycles
 //
 void Execute6808(V6808REGS * context, uint32 cycles)
 {
+#warning V6808_STATE_WAI is not properly handled yet!
+
        myMemcpy(&regs, context, sizeof(V6808REGS));
+       UNPACK_FLAGS;                                                           // Explode flags register into individual uint8s
 
        // Execute here...
        while (regs.clock < cycles)
        {
 #ifdef __DEBUG__
-Decode6808(regs.pc);
+if (logGo)
+       Decode6808(regs.pc);
 #endif
                uint8 opcode = regs.RdMem(regs.pc++);
 
+#ifdef __DEBUG__
 //if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
 //instCount[opcode]++;
+#endif
 
-               exec_op[opcode]();                                                              // Execute that opcode...
+               exec_op[opcode]();                                              // Execute that opcode...
                regs.clock += CPUCycles[opcode];
 #ifdef __DEBUG__
-WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, regs.cc);
+if (logGo)
+//     WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " "));
+       WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (flagH ? "H" : " "), (flagI ? "I" : " "), (flagN ? "N" : " "), (flagZ ? "Z" : " "), (flagV ? "V" : " "), (flagC ? "C" : " "));
 #endif
 
                if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
                {
-                       regs.cc |= FLAG_I;                                                      // Set I
-                       regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
+#ifdef __DEBUG__
+WriteLog("*** RESET LINE ASSERTED ***\n");
+#endif
+//                     regs.cc |= FLAG_I;                                      // Set I
+                       flagI = 1;                                                      // Set I
+                       regs.pc = RdMemW(0xFFFE);                       // And load PC with the RESET vector
 
                        context->cpuFlags &= ~V6808_ASSERT_LINE_RESET;
                        regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET;
                }
                else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
                {
-                       regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
-                       regs.WrMem(--regs.s, regs.pc >> 8);
-                       regs.WrMem(--regs.s, regs.x & 0xFF);
-                       regs.WrMem(--regs.s, regs.x >> 8);
-                       regs.WrMem(--regs.s, regs.b);
-                       regs.WrMem(--regs.s, regs.a);
-                       regs.WrMem(--regs.s, regs.cc);
-                       regs.pc = RdMemW(0xFFFC);                                       // And do it!
+#ifdef __DEBUG__
+WriteLog("*** NMI LINE ASSERTED ***\n");
+#endif
+                       regs.cc = PACK_FLAGS;                           // Mash flags back into the CC register
+                       PUSH16(regs.pc);                                        // Save all regs...
+                       PUSH16(regs.x);
+                       PUSH(regs.b);
+                       PUSH(regs.a);
+                       PUSH(regs.cc);
+                       regs.pc = RdMemW(0xFFFC);                       // And do it!
 
                        regs.clock += 0;                                                        // How many???
                        context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
@@ -1892,24 +2158,32 @@ WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.
                }
                else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
                {
-                       if (!(regs.cc & FLAG_I))                                        // Process an interrupt (I=0)?
+#ifdef __DEBUG__
+WriteLog("*** IRQ LINE ASSERTED ***\n");
+#endif
+//                     if (!(regs.cc & FLAG_I))                        // Process an interrupt (I=0)?
+                       if (!flagI)                                                     // Process an interrupt (I=0)?
                        {
-                               regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save all regs...
-                               regs.WrMem(--regs.s, regs.pc >> 8);
-                               regs.WrMem(--regs.s, regs.x & 0xFF);
-                               regs.WrMem(--regs.s, regs.x >> 8);
-                               regs.WrMem(--regs.s, regs.b);
-                               regs.WrMem(--regs.s, regs.a);
-                               regs.WrMem(--regs.s, regs.cc);
-                               regs.pc = RdMemW(0xFFF8);                       // And do it!
-
-                               regs.clock += 0;                                                // How many???
+#ifdef __DEBUG__
+WriteLog("    IRQ TAKEN!\n");
+logGo = true;
+#endif
+                               regs.cc = PACK_FLAGS;                   // Mash flags back into the CC register
+                               PUSH16(regs.pc);                                // Save all regs...
+                               PUSH16(regs.x);
+                               PUSH(regs.b);
+                               PUSH(regs.a);
+                               PUSH(regs.cc);
+                               regs.pc = RdMemW(0xFFF8);               // And do it!
+
+                               regs.clock += 0;                                // How many???
                                context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
                                regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
                        }
                }
        }
 
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
        myMemcpy(context, &regs, sizeof(V6808REGS));
 }