]> Shamusworld >> Repos - thunder/commitdiff
Removed useless cruft, fixed off-by-one bug in screen render.
authorShamus Hammons <jlhamm@acm.org>
Thu, 17 Apr 2014 16:27:02 +0000 (11:27 -0500)
committerShamus Hammons <jlhamm@acm.org>
Thu, 17 Apr 2014 16:27:02 +0000 (11:27 -0500)
13 files changed:
makefile
src/dis6808.cpp [deleted file]
src/dis6808.h [deleted file]
src/gui.h
src/screen.cpp
src/thunder.cpp
src/v63701.cpp
src/v6808.cpp [deleted file]
src/v6808.h [deleted file]
src/v6809.cpp [changed mode: 0644->0755]
src/v6809.h [changed mode: 0644->0755]
src/ym2151.c
test/mcu-sound.cpp

index 9004c5855cd27fd9e63924b844ed8b8c1d2df971..e19b93ab4cb994aad4f93fb354e5e4137f014f9d 100644 (file)
--- a/makefile
+++ b/makefile
@@ -51,21 +51,22 @@ CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -Wno-uninitialized -Wno-
 LDFLAGS =
 
 # Ugh, let's get rid of the ref to -lcurses
-LIBS = `sdl2-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB) -lcurses
+LIBS = `sdl2-config $(SDLLIBTYPE)` -lstdc++ -lz -lm $(GLLIB)
 
 INCS = -I. -Isrc
 
 OBJS = \
-       obj/dis6808.o    \
+       obj/dis63701.o   \
        obj/dis6809.o    \
        obj/gui.o        \
        obj/icon-64x64.o \
        obj/log.o        \
        obj/resource.o   \
        obj/screen.o     \
-       obj/v6808.o      \
+       obj/v63701.o     \
        obj/v6809.o      \
        obj/video.o      \
+       obj/ym2151.o     \
        obj/thunder.o    \
        $(ICON)
 
diff --git a/src/dis6808.cpp b/src/dis6808.cpp
deleted file mode 100644 (file)
index 97f20c4..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-//
-// 6808 disassembler
-//
-// by James Hammons
-//
-// (c) 2004, 2014 Underground Software
-//
-
-#include "dis6808.h"
-
-#include <stdio.h>
-#include <string>
-#include "v6808.h"
-#include "log.h"
-
-using namespace std;
-
-// External shit
-
-#warning "THIS ISN'T GENERIC ENOUGH... !!! FIX !!!"
-/*extern*/ V6808REGS soundCPU;//Hm.
-
-// Private globals variables
-
-static char op_mat[256] = {
-  0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-  5, 5, 0, 0, 0, 0, 5, 5, 0, 5, 0, 5, 0, 0, 0, 0,
-  3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-  5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 0, 0, 5, 5,
-  5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
-  5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
-  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
-  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
-  8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
-  1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
-  7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-  2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0, 9, 0,
-  1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
-  7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7,
-  2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2
-};
-
-static char mnemonics[256][6] = {
-  "???  ","NOP  ","???  ","???  ","???  ","???  ","TAP  ","TPA  ",
-  "INX  ","DEX  ","CLV  ","SEV  ","CLC  ","SEC  ","CLI  ","SEI  ",
-  "SBA  ","CBA  ","???  ","???  ","???  ","???  ","TAB  ","TBA  ",
-  "???  ","DAA  ","???  ","ABA  ","???  ","???  ","???  ","???  ",
-  "BRA  ","???  ","BHI  ","BLS  ","BCC  ","BCS  ","BNE  ","BEQ  ",
-  "BVC  ","BVS  ","BPL  ","BMI  ","BGE  ","BLT  ","BGT  ","BLE  ",
-  "TSX  ","INS  ","PULA ","PULB ","DES  ","TXS  ","PSHA ","PSHB ",
-  "???  ","RTS  ","???  ","RTI  ","???  ","???  ","WAI  ","SWI  ",
-  "NEGA ","???  ","???  ","COMA ","LSRA ","???  ","RORA ","ASRA ",
-  "ASLA ","ROLA ","DECA ","???  ","INCA ","TSTA ","???  ","CLRA ",
-  "NEGB ","???  ","???  ","COMB ","LSRB ","???  ","RORB ","ASRB ",
-  "ASLB ","ROLB ","DECB ","???  ","INCB ","TSTB ","???  ","CLRB ",
-  "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
-  "ASL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
-  "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
-  "ASL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
-  "SUBA ","CMPA ","SBCA ","???  ","ANDA ","BITA ","LDAA ","???  ",
-  "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","BSR  ","LDS  ","???  ",
-  "SUBA ","CMPA ","SBCA ","???  ","ANDA ","BITA ","LDAA ","STAA ",
-  "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","???  ","LDS  ","STS  ",
-  "SUBA ","CMPA ","SBCA ","???  ","ANDA ","BITA ","LDAA ","STAA ",
-  "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","JSR  ","LDS  ","STS  ",
-  "SUBA ","CMPA ","SBCA ","???  ","ANDA ","BITA ","LDAA ","STAA ",
-  "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","JSR  ","LDS  ","STS  ",
-  "SUBB ","CMPB ","SBCB ","???  ","ANDB ","BITB ","LDAB ","???  ",
-  "EORB ","ADCB ","ORAB ","ADDB ","???  ","???  ","LDX  ","???  ",
-  "SUBB ","CMPB ","SBCB ","???  ","ANDB ","BITB ","LDAB ","STAB ",
-  "EORB ","ADCB ","ORAB ","ADDB ","???  ","???  ","LDX  ","STX  ",
-  "SUBB ","CMPB ","SBCB ","???  ","ANDB ","BITB ","LDAB ","STAB ",
-  "EORB ","ADCB ","ORAB ","ADDB ","???  ","???  ","LDX  ","STX  ",
-  "SUBB ","CMPB ","SBCB ","???  ","ANDB ","BITB ","LDAB ","STAB ",
-  "EORB ","ADCB ","ORAB ","ADDB ","???  ","???  ","LDX  ","STX  "
-};
-
-//
-// Display bytes in mem in hex
-//
-static void DisplayBytes(uint16_t src, uint32_t dst)
-{
-       WriteLog("%04X: ", src);
-       uint8_t cnt = 0;                                                                                // Init counter...
-
-       if (src > dst)
-               dst += 0x10000;                                                                 // That should fix the FFFF bug...
-
-       for(uint32_t i=src; i<dst; i++)
-       {
-               WriteLog("%02X ", soundCPU.RdMem(i));
-               cnt++;                                                                                  // Bump counter...
-       }
-
-       for(int i=cnt; i<5; i++)                                                        // Pad the leftover spaces...
-               WriteLog("   ");
-}
-
-//
-// Decode a 6808 instruction
-//
-int Decode6808(uint16_t pc)
-{
-       char outbuf[80];
-
-       uint16_t addr = pc, offset;
-       uint8_t opcode = soundCPU.RdMem(addr++);                                // Get the opcode
-
-       switch (op_mat[opcode])                                                         // Decode the addressing mode...
-       {
-       case 0:                                                                                         // Illegal
-               sprintf(outbuf, "???          ");
-               break;
-       case 1:                                                                                         // Zero page
-               sprintf(outbuf, "%s $%02X    ", mnemonics[opcode], soundCPU.RdMem(addr++));
-               break;
-       case 2:                                                                                         // Absolute
-//             sprintf(outbuf, "%s $%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++));
-               offset = (soundCPU.RdMem(addr + 0) << 8) | soundCPU.RdMem(addr + 1);
-               addr += 2;
-               sprintf(outbuf, "%s $%04X  ", mnemonics[opcode], offset);
-               break;
-       case 3:                                                                                         // Relative
-//             sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16_t)(int8_t)soundCPU.RdMem(addr));
-               offset = addr + 1 + (int16_t)(int8_t)soundCPU.RdMem(addr);
-               addr++;
-               sprintf(outbuf, "%s $%04X  ", mnemonics[opcode], offset);
-               break;
-       case 5:                                                                                         // Inherent
-               sprintf(outbuf, "%s        ", mnemonics[opcode]);
-               break;
-       case 7:                                                                                         // Indexed
-               sprintf(outbuf, "%s $%02X,X  ", mnemonics[opcode], soundCPU.RdMem(addr++));
-               break;
-       case 8:                                                                                         // Immediate
-               sprintf(outbuf, "%s #$%02X   ", mnemonics[opcode], soundCPU.RdMem(addr++));
-               break;
-       case 9:                                                                                         // Long Immediate
-//             sprintf(outbuf, "%s #$%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++));
-               offset = (soundCPU.RdMem(addr + 0) << 8) | soundCPU.RdMem(addr + 1);
-               addr += 2;
-               sprintf(outbuf, "%s #$%04X ", mnemonics[opcode], offset);
-               break;
-       }
-
-       DisplayBytes(pc, addr);                                                         // Show bytes
-       WriteLog("%s", outbuf);                                                         // Display opcode & addressing, etc.
-
-       return addr - pc;
-}
diff --git a/src/dis6808.h b/src/dis6808.h
deleted file mode 100644 (file)
index 0e3934a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// DIS6808.H
-//
-// by James Hammons
-// (C) 2004, 2014 Underground Software
-//
-
-#ifndef __DIS6808_H__
-#define __DIS6808_H__
-
-#include <stdint.h>
-
-int Decode6808(uint16_t pc);
-
-#endif // __DIS6808_H__
index 663dd527dfe9c3429b940ce497c1bbcb17101010..9a17174c5cdc7cadbe5f92a248c1bc336bdef658 100644 (file)
--- a/src/gui.h
+++ b/src/gui.h
@@ -9,7 +9,7 @@
 #define __GUI_H__
 
 #include <stdint.h>
-#include "SDL.h"
+#include <SDL2/SDL.h>
 
 // Message macros
 
index f72b2bf026a57a9fb9f3a0d219dc945fb6928d60..660281feef003db641bf26187eb748cccbcbe4c9 100644 (file)
@@ -161,9 +161,13 @@ void BlitChar(SDL_Surface * scr, uint8_t * chr, uint8_t * ram)
        uint32_t src = 0;
 
        for(int i=0; i<VIRTUAL_SCREEN_HEIGHT; i++)
+       {
                for (int j=0; j<VIRTUAL_SCREEN_WIDTH; j++)
-//                     scrBuffer[(i * VIRTUAL_SCREEN_WIDTH) + j] = palette[my_scr[src++]];
-                       scrBuffer[src] = palette[my_scr[src++]];
+               {
+                       scrBuffer[src] = palette[my_scr[src]];
+                       src++;
+               }
+       }
 
        RenderScreenBuffer();
 }
index 9439026682dab5eb03a272f204baabbe473c0a4d..09cc40f147fc6d3446369075fa5e7c58356fa512 100644 (file)
 // JLH  07/23/2009  Added changelog ;-)
 // JLH  08/12/2009  Stabilized emulation so that it works
 // JLH  04/04/2014  Converted to SDL 2
+// JLH  04/17/2014  Removed a metric fuck-tonne of cruft, added YM2151 & MCU
 //
 
-#define THUNDER_VERSION                "1.0.0"
+#define THUNDER_VERSION                "1.1.0"
 
 #include <iostream>
 #include <iomanip>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
-//#include <conio.h>                   // For getch()
-#include <curses.h>                    // For getch()
+//#include <curses.h>                  // For getch()
 #include <time.h>
-#include <SDL2/SDL.h>          // Get yer SDL out...!
+#include <SDL2/SDL.h>
 #include "v6809.h"
 #include "screen.h"
 #include "gui.h"
@@ -77,17 +77,17 @@ uint8_t chr_rom[0x60000];                   // Character ROM pointer
 
 V6809REGS cpu1, cpu2;
 
-bool trace1 = false;                           // ditto...
-bool looking_at_rom = true;                    // true = R1, false = R2
-uint32_t banksw1, banksw2;                     // Bank switch addresses
-uint16_t game_over_switch;                     // Game over delay
-uint16_t dpc;                                          // Debug pc reg...
-bool show_scr = true;                          // Whether or not to show background
-bool enable_cpu = true;                                // Whether or not to enable CPUs
-bool irqGoA = true;                                    // IRQ switch for CPU #1
-bool irqGoB = true;                                    // IRQ switch for CPU #2
-
-uint16_t refresh_ = 0;                         // Crappy global screen stuff...
+bool trace1 = false;                   // ditto...
+bool looking_at_rom = true;            // true = R1, false = R2
+uint32_t banksw1, banksw2;             // Bank switch addresses
+uint16_t game_over_switch;             // Game over delay
+uint16_t dpc;                                  // Debug pc reg...
+bool show_scr = true;                  // Whether or not to show background
+bool enable_cpu = true;                        // Whether or not to enable CPUs
+bool irqGoA = true;                            // IRQ switch for CPU #1
+bool irqGoB = true;                            // IRQ switch for CPU #2
+
+uint16_t refresh_ = 0;                 // Crappy global screen stuff...
 bool refresh2 = true;
 
 uint32_t psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -101,164 +101,6 @@ uint8_t * fm_adrs[14];
 fstream tr;                                                    // Tracelog hook
 uint16_t pcx;                                          // Where we at?
 
-//kludge, for now
-//static uint8_t keys[0x1000];                         // SDL raw keyboard matrix
-
-static char op_mat1[256] = {
-  1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
-  0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6,
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-  7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5,
-  5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
-  5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
-  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
-  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
-  8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
-op_mat2[256] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0,
-  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
-  0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7,
-  0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 },
-op_mat3[256] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
-  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-  0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
-  0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static char mnemonics[256][6] = {
-  "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
-  "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
-  "PAGE1","PAGE2","NOP  ","SYNC ","???  ","???  ","LBRA ","LBSR ",
-  "???  ","DAA  ","ORCC ","???  ","ANDCC","SEX  ","EXG  ","TFR  ",
-  "BRA  ","BRN  ","BHI  ","BLS  ","BHS  ","BLO  ","BNE  ","BEQ  ",
-  "BVC  ","BVS  ","BPL  ","BMI  ","BGE  ","BLT  ","BGT  ","BLE  ",
-  "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ",
-  "???  ","RTS  ","ABX  ","RTI  ","CWAI ","MUL  ","RESET","SWI  ",
-  "NEGA ","???  ","???  ","COMA ","LSRA ","???  ","RORA ","ASRA ",
-  "LSLA ","ROLA ","DECA ","???  ","INCA ","TSTA ","???  ","CLRA ",
-  "NEGB ","???  ","???  ","COMB ","LSRB ","???  ","RORB ","ASRB ",
-  "LSLB ","ROLB ","DECB ","???  ","INCB ","TSTB ","???  ","CLRB ",
-  "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
-  "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
-  "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
-  "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
-  "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA  ","???  ",
-  "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","BSR  ","LDX  ","???  ",
-  "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
-  "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
-  "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
-  "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
-  "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
-  "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
-  "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB  ","???  ",
-  "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","???  ","LDU  ","???  ",
-  "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
-  "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  ",
-  "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
-  "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  ",
-  "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
-  "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  " },
-mnemonics2[256][6] = {
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ",
-  "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","SWI2 ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","???  ",
-  "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
-  "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
-  "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  " },
-mnemonics3[256][6] = {
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","SWI3 ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
-  "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  " },
-tregs[16][3] = {
-  "D",  "X", "Y",  "U",  "S",  "PC", "??", "??",
-  "A",  "B", "CC", "DP", "??", "??", "??", "??" },
-iregs[4][2] = {"X", "Y", "U", "S" };
-
 
 //
 // Read a byte from memory (without touching PC. Not a Fetch!)
@@ -289,26 +131,14 @@ uint8_t RdMem(uint16_t addr)
 void WrMem(uint16_t addr, uint8_t b)
 {
        extern bool disasm;
-       extern bool charbase;                                                           // Needed for screen. Extern it in it??
-  //extern uint16_t sr, ur, xr, yr;            // Needed for tracelog
-  //extern uint16_t pcr;
-/*  if ((addr>0x40FF) && (addr<0x4390))
-  {
-    tr << hex << addr << ":" << (int)b;
-    //for(int i=0; i<32; i++)
-    //{
-    //  if (gram1[0x4400+i]<0x10)  tr << "0";
-    //  tr << hex << (uint16_t)gram1[0x4400+i] << " ";
-    //}
-    tr << endl;
-  }//*/
+       extern bool charbase;   // Needed for screen. Extern it in it??
 #if 0
        if (addr == 0x4182)
        {
                WriteLog("\nWriteMem: CPU #1 writing $%02X to $4182!\n\n", b);
        }
 #endif
-#if 1
+#if 0
 if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380))
        printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, addr);
 #endif
@@ -356,7 +186,6 @@ if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380))
 //
 uint8_t RdMemB(uint16_t addr)
 {
-//  extern uint16_t cpu2.s, cpu2.u, cpu2.x, cpu2.y;            // Needed for tracelog
        uint8_t b;
 
        if (addr < 0x8000)
@@ -371,13 +200,6 @@ uint8_t RdMemB(uint16_t addr)
        else
                b = grom2[addr];
 
-/*  if ((addr>0x3FFF) && (addr<0x4400))  tr << "R-" << hex << pcx << ": "
-                                        << addr << "-"
-                                        << (int)looking_at_rom
-                                        << " [" << (int)b
-                                        << "] XR:" << xr << " YR:" << yr
-                                        << " SR:" << sr << " UR:" << ur
-                                        << endl; //*/
        return b;
 }
 
@@ -389,25 +211,14 @@ void WrMemB(uint16_t addr, uint8_t b)
 {
        extern bool disasm;
        extern bool charbase;
-  //extern uint16_t sr, ur, xr, yr;            // Needed for tracelog
-  //extern uint16_t pcr;
-/*  if ((addr>0x00FF) && (addr<0x0390))
-  {
-    tr << hex << addr << ":" << (int)b;
-    //for(int i=0; i<32; i++)
-    //{
-    //  if (gram1[0x4400+i]<0x10)  tr << "0";
-    //  tr << hex << (uint16_t)gram1[0x4400+i] << " ";
-    //}
-    tr << endl;
-  }//*/
+
 #if 0
        if (addr == 0x0182)
        {
                WriteLog("\nWriteMem: CPU #2 writing $%02X to $0182 ($4182)!\n\n", b);
        }
 #endif
-#if 1
+#if 0
 if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
        printf("WriteMem: CPU #2 writing $%02X to $%04X...\n", b, addr);
 #endif
@@ -447,302 +258,25 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
 }
 
 
-//
-// Display bytes in mem in hex
-//
-void DisplayBytes(uint16_t src, unsigned long dst)
-{
-       uint8_t cnt = 0;
-       WriteLog("%04X: ", src);
-
-       if (src > dst)
-               dst += 0x10000;        // That should fix the FFFF bug...
-
-       for(unsigned long i=src; i<dst; i++)
-       {
-               WriteLog("%02X ", (uint8_t)(looking_at_rom ? RdMem(i) : RdMemB(i)));
-               cnt++;
-       }
-
-       // Pad the leftover spaces...
-       for(unsigned long i=cnt; i<5; i++)
-               WriteLog("   ");
-}
-
-
-// temp crap...
-uint8_t Fetch(void) { return RdMem(dpc); }
-uint16_t FetchW(void) { return (uint16_t)((RdMem(dpc) << 8) | RdMem(dpc+1)); }
-uint8_t FetchB(void) { return RdMemB(dpc); }
-uint16_t FetchWB(void) { return (uint16_t)((RdMemB(dpc) << 8) | RdMemB(dpc+1)); }
-
-
-//
-// Decode a 6809 instruction at 'addr'
-//
-void Decode_6809()
-{
-       uint8_t (* DFetch)();           // Decode Fetch() pointer...
-       uint16_t (* DFetchW)();          // Decode FetchW() pointer...
-       DFetch  = (looking_at_rom ? Fetch : FetchB);
-       DFetchW = (looking_at_rom ? FetchW : FetchWB);
-
-       /*  extern*/ uint16_t pcr, pcrB;              // Pull in 'pcr' from '6809.cpp'
-       uint16_t pc_save = pcr, pcB_save = pcrB;
-       pcr  = dpc;  pcrB = dpc;
-       uint8_t opcode = DFetch();             // Get the opcode ('fetch' cycle)
-       uint8_t opcode2, operand;
-       uint16_t loperand;
-       uint8_t admode = op_mat1[opcode];     // addressing mode
-       char outbuf[80], mnem[6], tmp[30];
-
-       strcpy(mnem, mnemonics[opcode]);  // Copy page 1 opcode
-
-       if (opcode == 0x10)             // Extended opcode?
-       {
-               opcode2 = DFetch();     // Then get next byte
-               admode = op_mat2[opcode2];    // And use it as index into 'op_mat2'
-               strcpy(mnem, mnemonics2[opcode2]);  // Overwrite mnemonic
-       }
-
-       if (opcode == 0x11)             // Same as above...
-       {
-               opcode2 = DFetch();
-               admode = op_mat3[opcode2];
-               strcpy(mnem, mnemonics3[opcode2]);  // Overwrite mnemonic
-       }
-
-       // Decode it...
-       switch (admode)
-       {
-       case 0:  // Illegal
-               sprintf(outbuf, "???");
-               break;
-       case 1:  // Zero page
-               operand = DFetch();   // Get ZP address
-               sprintf(outbuf, "%s $%02X", mnem, operand);
-               break;
-       case 2:  // Absolute
-               loperand = DFetchW(); // Get ABS address
-               sprintf(outbuf, "%s $%04X", mnem, loperand);
-               break;
-       case 3:  // Relative
-       {
-               operand = DFetch();   // Get offset
-               uint16_t tmpc = (looking_at_rom ? pcr : pcrB);
-               sprintf(outbuf, "%s $%04X", mnem, tmpc+(int16_t)(int8_t)operand);
-               break;
-       }
-       case 4:  // Long Relative
-       {
-               loperand = DFetchW(); // Get long offset
-               uint16_t tmpc = (looking_at_rom ? pcr : pcrB);
-               sprintf(outbuf, "%s $%04X", mnem, tmpc+(int16_t)loperand);
-               break;
-       }
-       case 5:  // Inherent
-               sprintf(outbuf, "%s ", mnem);
-               break;
-       case 6:  // Txfr/exchg/push/pull
-       {
-               operand = DFetch();   // Get txfr/exg/push/pull byte
-
-               if ((opcode == 0x1E) || (opcode == 0x1F))  // Is it TXF/EXG?
-               {
-                       sprintf(tmp, "%s,%s", tregs[operand>>4], tregs[operand&0x0F]);
-               }
-               else
-               {
-                       tmp[0] = 0;
-                       if (operand&0x01)  strcat(tmp, "CC ");
-                       if (operand&0x02)  strcat(tmp, "A ");
-                       if (operand&0x04)  strcat(tmp, "B ");
-                       if (operand&0x08)  strcat(tmp, "DP ");
-                       if (operand&0x10)  strcat(tmp, "X ");
-                       if (operand&0x20)  strcat(tmp, "Y ");
-                       if (operand&0x40)  (((opcode==0x34)||(opcode==0x35))
-                                               ? strcat(tmp, "U ") : strcat(tmp, "S "));
-                       if (operand&0x80)  strcat(tmp, "PC");
-               }
-               sprintf(outbuf, "%s %s", mnem, tmp);
-               break;
-       }
-       case 7:  // Indexed (the tough one!)
-       {
-               operand = DFetch();   // Get IDX byte
-               uint8_t reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4),
-                       lo_nyb = (operand & 0x0F),  boff;
-               uint16_t woff;
-
-               strcpy(tmp, "??");
-
-               if (!(operand & 0x80))      // Hi bit set? Then decode 4 bit offset
-               {
-                       sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb),
-                                       iregs[reg]);
-               }
-               else   // Add the ($nnnn,R) code dude...
-               {
-                       if (idxind)
-                       {
-                               switch (lo_nyb)
-                               {
-                               case 1:   sprintf(tmp, "(,%s++)", iregs[reg]);  break;
-                               case 3:   sprintf(tmp, "(,--%s)", iregs[reg]);  break;
-                               case 4:   sprintf(tmp, "(,%s)", iregs[reg]);  break;
-                               case 5:   sprintf(tmp, "(B,%s)", iregs[reg]);  break;
-                               case 6:   sprintf(tmp, "(A,%s)", iregs[reg]);  break;
-                               case 8:
-                               { boff = DFetch();  sprintf(tmp, "($%02X,%s)", boff,
-                                                                               iregs[reg]);  break; }
-                               case 9:
-                               { woff = DFetchW();  sprintf(tmp, "($%04X,%s)", woff,
-                                                                                       iregs[reg]);  break; }
-                               case 11:  sprintf(tmp, "(D,%s)", iregs[reg]);  break;
-                               case 12:
-                               { boff = DFetch();  sprintf(tmp, "($%02X,PC)", boff);  break; }
-                               case 13:
-                               { woff = DFetchW();  sprintf(tmp, "($%04X,PC)", woff);  break; }
-                               case 15:
-                               { woff = DFetchW();  sprintf(tmp, "[$%04X]", woff);  break; }
-                               default:  strcpy(tmp, "??");
-                               }
-                       }
-                       else
-                       {
-                               switch (lo_nyb)
-                               {
-                               case 0:   sprintf(tmp, ",%s+", iregs[reg]);  break;
-                               case 1:   sprintf(tmp, ",%s++", iregs[reg]);  break;
-                               case 2:   sprintf(tmp, ",-%s", iregs[reg]);  break;
-                               case 3:   sprintf(tmp, ",--%s", iregs[reg]);  break;
-                               case 4:   sprintf(tmp, ",%s", iregs[reg]);  break;
-                               case 5:   sprintf(tmp, "(B),%s", iregs[reg]);  break;
-                               case 6:   sprintf(tmp, "(A),%s", iregs[reg]);  break;
-                               case 8:
-                               { boff = DFetch();  sprintf(tmp, "($%02X),%s", boff,
-                                                                               iregs[reg]);  break; }
-                               case 9:
-                               { woff = DFetchW();  sprintf(tmp, "($%04X),%s", woff,
-                                                                               iregs[reg]);  break; }
-                               case 11:  sprintf(tmp, "(D),%s", iregs[reg]);  break;
-                               case 12:
-                               { boff = DFetch();  sprintf(tmp, "($%02X),PC", boff);  break; }
-                               case 13:
-                               { woff = DFetchW();  sprintf(tmp, "($%04X),PC", woff);  break; }
-                               default:  strcpy(tmp, "??");
-                               }
-                       }
-               }
-
-               sprintf(outbuf, "%s %s", mnem, tmp);
-               break;
-       }
-       case 8:  // Immediate
-               operand = DFetch();   // Get IMM byte
-               sprintf(outbuf, "%s #$%02X", mnem, operand);
-               break;
-       case 9:  // Long Immediate
-               loperand = DFetchW(); // Get IMM word
-               sprintf(outbuf, "%s #$%04X", mnem, loperand);
-               break;
-       }
-
-       DisplayBytes(dpc, (looking_at_rom ? pcr : pcrB));  // Show bytes
-       WriteLog(outbuf);
-       WriteLog("\n");     // display opcode & addressing, etc
-       dpc = (looking_at_rom ? pcr : pcrB);  // Advance debug PC
-       pcr = pc_save;
-       pcrB = pcB_save;  // Restore PCs
-}
-
-
-//
-// Convert hex to dec
-//
-uint16_t htod(char * str)
-{
-       uint16_t value = 0;
-       int len = strlen(str);
-
-       for(int i=0; i<len; i++)
-       {
-               if (str[i] >= '0' && str[i] <= '9')
-                       value = (value << 4) | (unsigned)(str[i] - '0');
-               else if (str[i] >= 'a' && str[i] <= 'f')
-                       value = (value << 4) | (unsigned)((str[i] - 'a') + 10);
-               else if (str[i] >= 'A' && str[i] <= 'F')
-                       value = (value << 4) | (unsigned)((str[i] - 'A') + 10);
-       }
-
-       return value;
-}
-
-
-//
-// Load 32K file into ROM image space
-//
-bool Load32KImg(char * filename, uint16_t address)
-{
-#if 0
-       ifstream ff;
-       char ch;
-
-       ff.open(filename, ios::binary | ios::in);
-
-       if (ff)
-       {
-               // Read it in...
-               for(long i=0; i<32768; i++)
-               {
-                       ff.get(ch);
-                       grom[address+i] = ch;
-               }
-
-               ff.close();
-       }
-
-       return ff;
-#else
-       FILE * file = fopen(filename, "rb");
-
-       if (!file)
-               return false;
-
-       fread(&grom[address], 1, 0x8000, file);
-
-       return true;
-#endif
-}
-
-
 //
 // Generic Load file into image space
 // (No error checking performed!  Responsibility of caller!)
 //
 bool LoadImg(const char * filename, uint8_t * mem, uint32_t address, uint32_t length)
 {
-       ifstream ff;
-       char path[80];
-       char ch;
+       char path[128];
 
        strcpy(path, "./ROMs/");
        strcat(path, filename);
-//  ff.open(filename, ios::binary | ios::in);  // Open 'da file...
-       ff.open(path, ios::binary | ios::in);       // Open 'da file...
+       FILE * file = fopen(path, "rb");
 
-       if (ff)
-       {
-               for(uint32_t i=0; i<length; i++)             // Read it in...
-               {
-                       ff.get(ch);
-                       mem[address+i] = ch;
-               }
+       if (!file)
+               return false;
 
-               ff.close();                               // Close 'da file...
-       }
+       fread(&mem[address], 1, length, file);
+       fclose(file);
 
-       return ff;
+       return true;
 }
 
 
@@ -754,7 +288,6 @@ bool ReadColorPROMs(void)
        fstream ff1, ff2;
        //  uint8_t ch;
        char ch;
-//     extern uint8_t palette[768];     // Screen physical palette
        extern uint32_t palette[256];     // Screen physical palette
        extern uint8_t ccolor[256][8];   // Character color PROM values
        extern uint8_t scolor[128][16];  // Sprite color PROM values
@@ -795,7 +328,7 @@ bool ReadColorPROMs(void)
        ff2.open("./ROMs/"PROM2, ios::binary | ios::in);
 
        // If open was successful...
-       if (ff1)
+       if (ff1 && ff2)
        {
                // Palette is 12-bit RGB, we stretch it to 24-bit
                for(int i=0; i<256; i++)
@@ -945,7 +478,6 @@ void LoadPSGs(void)
                                }
 
                                psg_lens[i] = len;
-//                             cout << "Found sample file: " << file << "\t[Length: " << dec << len << "]" << endl;
                                printf("Found sample file: %s\t[Length: %u]\n", file, len);
                        }
 
@@ -968,31 +500,29 @@ void LoadFMs(void)
        {
                fstream fp;
 
-               fm_adrs[i] = NULL;                                                              // Zero out pointer
-               sprintf(file, "./sounds/fm%i.wav", i);                  // Create filename
+               fm_adrs[i] = NULL;                                              // Zero out pointer
+               sprintf(file, "./sounds/fm%i.wav", i);  // Create filename
+               fp.open(file, ios::binary | ios::in);   // Attempt to open it...
 
-               fp.open(file, ios::binary | ios::in);                   // Attempt to open it...
+               if (!fp)
+                       continue;
 
-               if (fp)
-               {
-                       len = GetWAVLength(fp);                                         // Get WAV length...
-                       fm_adrs[i] = new uint8_t[len];                                  // Attempt to allocate space...
+               len = GetWAVLength(fp);                                 // Get WAV length...
+               fm_adrs[i] = new uint8_t[len];                  // Attempt to allocate space...
 
-                       if (fm_adrs[i] != NULL)
+               if (fm_adrs[i] != NULL)
+               {
+                       for(int j=0; j<(signed)len; j++)
                        {
-                               for(int j=0; j<(signed)len; j++)
-                               {
-                                       fp.get(ch);
-                                       fm_adrs[i][j] = ch;                                     // & load it in...
-                               }
-
-                               fm_lens[i] = len;
-//                             cout << "Found sample file: " << file << " [Length: " << dec << len << "]" << endl;
-                               printf("Found sample file: %s\t[Length: %u]\n", file, len);
+                               fp.get(ch);
+                               fm_adrs[i][j] = ch;                                     // & load it in...
                        }
 
-                       fp.close();
+                       fm_lens[i] = len;
+                       printf("Found sample file: %s\t[Length: %u]\n", file, len);
                }
+
+               fp.close();
        }
 }
 
@@ -1017,7 +547,6 @@ extern bool disasm;        // From 'V6809.CPP'
        bool scr_type = false;            // false=chars, true=pixels
        uint16_t debounce = 0;                // Key de-bounce counter
        uint16_t fire_debounce = 0;           // Fire button debounce counter
-//  bool refresh2 = true;             // Default to 60 Hz...
        uint8_t x;                           // General placeholder...
        bool active = true;                                             // Program running flag
 
@@ -1027,46 +556,24 @@ extern bool disasm;      // From 'V6809.CPP'
 
        cout << endl << "THUNDER v"THUNDER_VERSION" ";
        cout << "by James Hammons" << endl;
-       cout << "Serial #20149404 / Prerelease" << endl;
+       cout << "Serial #20149417 / Prerelease" << endl;
        cout << "© 2003, 2014 Underground Software" << endl << endl;
 
        cout << "This emulator is free software. If you paid for it you were RIPPED OFF"
                << endl << endl;
 
-#if 0
-       cout << "Initializing SDL..." << endl;
-
-       if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
-       {
-               cout << "Couldn't initialize SDL: " << SDL_GetError() << endl;
-               return -1;
-       }
-#endif
-
 //     SDL_WM_SetCaption("Thunder v"THUNDER_VERSION" ", "Thunder");
 
-//     keys = SDL_GetKeyState(NULL);                           // Get the SDL keyboard matrix
-
        gram = gram1;  grom = grom1;           // Needed only for debugger
 
-#if 0
-       for(long i=0; i<0x10000; i++)
-       {
-               gram[i] = 0;  grom[i] = 0;           // Zero out memory
-               gram2[i] = 0;  grom2[i] = 0;
-       }
-#else
        memset(gram, 0, 0x10000);
        memset(grom, 0, 0x10000);
        memset(gram2, 0, 0x10000);
        memset(grom2, 0, 0x10000);
-#endif
 
        game_over_switch = 0;   // Init game over delay
-//  cpu1.a = 0; cpu1.b = 0; cpu1.cc = 0; cpu1.dp = 0; cpu1.x = 0; cpu1.y = 0; cpu1.s = 0; ur = 0; cpu1.pc = 0;
 
        cout << "Loading ROMs..." << endl;
-//  LoadCMOS();                            // Load CMOS at $CC00-$CFFF
        if (!ReadColorPROMs())                   // Load virtual PROMs
        { cout << "Could not open PROM files!" << endl;  return -1; }
 
@@ -1134,20 +641,6 @@ extern bool disasm;       // From 'V6809.CPP'
        LoadPSGs();
        LoadFMs();
 
-  // Quick 'n' Dirty voice dump (sound 0x0E)
-/*  uint32_t adc = (voice_rom[26]<<8) | voice_rom[27];
-  bool doneWitIt = false;
-  int crh = 0;
-  while (!doneWitIt)
-  {
-    if (voice_rom[adc] < 0x10)  tr << "0";
-    tr << hex << (int)voice_rom[adc] << " ";
-    if (crh++ > 24)  { crh = 0;  tr << endl; }
-    if ((voice_rom[adc] == 0xFF) && (voice_rom[adc-1] != 0x00))
-      doneWitIt = true;
-    adc++;
-  }//*/
-
        // Set up V6809 execution contexts
 
        memset(&cpu1, 0, sizeof(V6809REGS));
@@ -1160,243 +653,141 @@ extern bool disasm;    // From 'V6809.CPP'
        cpu2.WrMem = WrMemB;
        cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET;
 
-       bool firstTime = true;                                                          // kludge...
+       uint32_t my_clock = 0;
+       running = true;                                                         // Set running status...
+       trace1 = false;
+       SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
 
-WriteLog("About to go to the main loop...\n");
-       while (active)
-       {
-               cout << ">";
-               if (firstTime)
-               {
-                       firstTime = false;                                                      // crappy kludge...
-                       lbuff[0] = 'r';
-                       lbuff[1] = 0;
-               }
-               else
-                       cin >> lbuff;
-
-               if (lbuff[0] == 'd')
-               {
-                       if (lbuff[1] != 0)
-                       {
-                               lbuff[0] = 32;
-                               dpc = htod(lbuff);
-                       }
-                       printf("%04X: ", dpc);
-                       uint16_t pc_save = cpu1.pc, pcB_save = cpu2.pc;
-                       cpu1.pc = dpc;  cpu2.pc = dpc;
-                       for(int i=0; i<16; i++)
-                               printf("%02X ", (looking_at_rom ? Fetch() : FetchB()));
-                       cout << " ";
-                       cpu1.pc = dpc;  cpu2.pc = dpc;
-                       for(int i=0; i<16; i++)
-                       {
-                               uint8_t a = (looking_at_rom ? Fetch() : FetchB());
-                               if (a<10)             cout << (char)(a+48);
-                               if ((a>9) && (a<37))  cout << (char)(a+55);
-                               if (a>36)             cout << ".";
-                       }
-                       cout << endl;
-                       dpc = (looking_at_rom ? cpu1.pc : cpu2.pc);
-                       cpu1.pc = pc_save;  cpu2.pc = pcB_save;
-               }
-               else if (lbuff[0] == 'e')
-               {
-                       if (lbuff[1] != 0)
-                       {
-                               lbuff[0] = 32;
-                               dpc = htod(lbuff);
-                       }
-                       printf("%04X: ", dpc);
-                       for(int i=0; i<16; i++)  printf("%02X ", (uint8_t)gram[dpc++]);
-                       cout << endl;
-               }
-               else if (lbuff[0] == 'l')
-               {
-                       if (lbuff[1] != 0)
-                       {
-                               lbuff[0] = 32;
-                               dpc = htod(lbuff);
-                       }
-                       for(int i=0; i<23; i++)
-                               Decode_6809();
-               }
-               else if (lbuff[0] == 't')
-               {
-                       if (lbuff[1] != 0)
-                       {
-                               lbuff[0] = 32;
-                               dpc = htod(lbuff);
-                       }
-                       if (looking_at_rom)
-                       {
-                               cpu1.pc = dpc;
-                               Decode_6809();
-                               Execute6809(&cpu1, 1);
-                               dpc = cpu1.pc;
-                               printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
-                                       cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
-                               cout << " iclock=" << cpu1.clock << endl;
-                       }
-                       else
-                       {
-                               cpu2.pc = dpc;
-                               Decode_6809();
-                               Execute6809(&cpu2, 1);
-                               dpc = cpu2.pc;
-                               printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
-                                       cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
-                               cout << " iclock=" << cpu2.clock << endl;
-                       }
-               }
-               else if ((lbuff[0] == 'r') || (lbuff[0] == 'c')) // Run/continue...
-               {
-WriteLog("Executing 'run' command...\n");
-                       uint32_t my_clock = 0;
-                       running = true;                                                         // Set running status...
-                       trace1 = false;
-                       SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
-      //for(uint16_t i=0; i<0x8000; i++)  gram2[i] = grom3[i]; //Temp
-
-                       if (lbuff[0] == 'r')                                            // If run, then reset CPUs
-                       {
-WriteLog("Executing secondary 'run' command...\n");
 #if 1
-                               // This is data that is supposed to come from the MCU... So that's why it hangs
-                               gram1[0x4182] = 0xA6;          // Temp kludge
-                               gram1[0x4184] = 0xA6;
-                               gram1[0x4183] = 0x00;          // More of the same
-                               gram1[0x4185] = 0x00;
+       // This is data that is supposed to come from the MCU... So that's why it hangs
+       gram1[0x4182] = 0xA6;          // Temp kludge
+       gram1[0x4184] = 0xA6;
+       gram1[0x4183] = 0x00;          // More of the same
+       gram1[0x4185] = 0x00;
 #endif
-                               banksw1 = 0;                   // Will this work?
-                               banksw2 = 0;
+       banksw1 = 0;                   // Will this work?
+       banksw2 = 0;
 //        iclock = 0;                // Reset instr clock #1...
-                               InitGUI();                 // Reset # of coins
-
-#if 0
-                               cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1
-                               if (lbuff[1] != 0)
-                               {
-                               lbuff[0] = 32;  cpu1.pc = htod(lbuff);
-                               }
-                               else  cpu1.cc = 0xFF;                         // Set CC register
-
-                               cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2
-                               cpu2.cc = 0xFF;                              // Set CC register
-                               while(iclock < 8000)  // was 17000, 20000, 5000
-                               {
-                               Execute6809(&cpu1, 1);  Execute6809(&cpu2, 1);
-                               }
-#endif
-#if 0
-WriteLog("--> CPU clock #1: %u\n", cpu1.clock);
-                               // Will *this* help video sync? NO
-                               while (cpu1.clock < 8000)                               // was 17000, 20000, 5000
-                               {
-                                       Execute6809(&cpu1, 1);
-                                       Execute6809(&cpu2, 1);
-                               }
-#endif
-                       }
+       InitGUI();                 // Reset # of coins
 
 WriteLog("About to set up screen...\n");
-#if 0
-                       screen = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 8, SDL_SWSURFACE  | SDL_DOUBLEBUF);
-                       if (screen == NULL)
-                       {
-                               cout << "Failed to initialize screen!" << endl;
-                               running = false;
-                       }
-#else
-                       InitVideo();
-#endif
-
-#if 0
-                       SDL_Color colors[256];
-
-                       for(int i=0; i<256; i++)
-                       {
-                               colors[i].r = palette[i*3+0];
-                               colors[i].g = palette[i*3+1];
-                               colors[i].b = palette[i*3+2];
-                       }
-
-                       SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256);
-#endif
-
-#if 0
-                       for(int i=0; i<256; i++)
-                               keys[i] = 0;                            // Clear keyboard buffer...
-#endif
+       InitVideo();
 
-                       oldTicks = SDL_GetTicks();
+       oldTicks = SDL_GetTicks();
 
 WriteLog("About to set up audio...\n");
 #if 1
-                       // This crap SHOULD be in sound.cpp (not yet created)...
-                       SDL_AudioSpec desired, obtained;
-                       desired.freq = 22050;
-                       desired.format = AUDIO_U8;
-                       desired.channels = 1;
-                       desired.samples = 600;
-                       desired.callback = SoundFunc;
-                       desired.userdata = NULL;
-                       // Also, should check to see if it got the hardware it needed, correct sample size, etc.
-                       if (SDL_OpenAudio(&desired, &obtained) < 0)
-                       {
-                               cout << "Couldn't open audio: " << SDL_GetError() << endl;
-                               return -1;
-                       }
+       // This crap SHOULD be in sound.cpp (not yet created)...
+       SDL_AudioSpec desired, obtained;
+       desired.freq = 22050;
+       desired.format = AUDIO_U8;
+       desired.channels = 1;
+       desired.samples = 600;
+       desired.callback = SoundFunc;
+       desired.userdata = NULL;
+       // Also, should check to see if it got the hardware it needed, correct sample size, etc.
+       if (SDL_OpenAudio(&desired, &obtained) < 0)
+       {
+               cout << "Couldn't open audio: " << SDL_GetError() << endl;
+               return -1;
+       }
 
-                       SDL_PauseAudio(0);                                                      // Get that audio going!
+       SDL_PauseAudio(0);                                                      // Get that audio going!
 #endif
 
 memset(scrBuffer, 0xFF, VIRTUAL_SCREEN_WIDTH*VIRTUAL_SCREEN_HEIGHT*sizeof(uint32_t));
 RenderScreenBuffer();
+
 WriteLog("About to enter main loop...\n");
-                       while (running)
-                       {
-                               HandleGUIDebounce();                                    // Debounce GUI keys
+       while (running)
+       {
+               HandleGUIDebounce();                                    // Debounce GUI keys
 
-                               if (game_over_switch)
-                               {
-                                       game_over_switch--;  // Countdown...
+               if (game_over_switch)
+               {
+                       game_over_switch--;  // Countdown...
 
-                                       if (game_over_switch == 0)
-                                               gram1[0x4380] = 0; // Kill music!
-                               }
+                       if (game_over_switch == 0)
+                               gram1[0x4380] = 0; // Kill music!
+               }
 
 //testing... (works)
 //gram1[0x423D] = 1;
-                               //gram1[0x423D] = self_test;                    // Reset DSW1-1
-                               gram1[0x4268] = 0;                                              // Reset Video test
-                               gram1[0x427A] = 0;  gram1[0x427C] = 0;
-                               gram1[0x427B] = 0;  gram1[0x427D] = 0;
-                               gram1[0x427E] = 0;  gram1[0x427F] = 0;
-                               gram1[0x4280] = 0;  gram1[0x4281] = 0;
-                               gram1[0x4276] = 0;  gram1[0x426A] = 0;
-                               gram1[0x4278] = 0;  gram1[0x426C] = 0;
-                               gram1[0x4262] = 0;  gram1[0x4260] = 0;
-                               //gram1[0x4247] = 0;
-
-                               // SDL key handling...
-
-//                             SDL_PumpEvents();                               // Force key events into the buffer.
-                               SDL_Event event;
-
-                               while (SDL_PollEvent(&event))
+               //gram1[0x423D] = self_test;                    // Reset DSW1-1
+               gram1[0x4268] = 0;                                              // Reset Video test
+               gram1[0x427A] = 0;  gram1[0x427C] = 0;
+               //gram1[0x427B] = 0;  gram1[0x427D] = 0;
+               gram1[0x427E] = 0;//  gram1[0x427F] = 0;
+               gram1[0x4280] = 0;//  gram1[0x4281] = 0;
+               //gram1[0x4276] = 0;
+               gram1[0x426A] = 0;
+               //gram1[0x4278] = 0;
+               gram1[0x426C] = 0;
+               gram1[0x4262] = 0;  gram1[0x4260] = 0;
+               //gram1[0x4247] = 0;
+
+               // SDL key handling...
+
+               SDL_Event event;
+
+               while (SDL_PollEvent(&event))
+               {
+                       switch (event.type)
+                       {
+                       case SDL_KEYDOWN:
+                               if (event.key.keysym.sym == SDLK_ESCAPE)
+                                       running = false;
+                               else if (event.key.keysym.sym == SDLK_F10)
+                                       gram1[0x41A5]++;                        // Coin? (F10)
+                               else if (event.key.keysym.sym == SDLK_c)
+                                       gram1[0x418C]++;                        // ? (C) Start
+                               else if (event.key.keysym.sym == SDLK_RIGHT)
                                {
-                                       switch (event.type)
-                                       {
-                                       case SDL_KEYDOWN:
-                                               if (event.key.keysym.sym == SDLK_ESCAPE)
-                                                       running = false;
-                                               else if (event.key.keysym.sym == SDLK_F10)
-                                                       gram1[0x41A5]++;                        // Coin? (F10)
-                                               else if (event.key.keysym.sym == SDLK_c)
-                                                       gram1[0x418C]++;                        // ? (C) Start
-                                       }
+                                       // Disallow opposite directions @ same time
+                                       if (gram1[0x4281] == 0)
+                                               gram1[0x427F] = 1;              // Stick right
                                }
+                               else if (event.key.keysym.sym == SDLK_LEFT)
+                               {
+                                       // Disallow opposite directions@same time
+                                       if (gram1[0x427F] == 0)
+                                               gram1[0x4281] = 1;              // Stick left
+                               }
+                               else if (event.key.keysym.sym == SDLK_UP)
+                               {
+                                       // Disallow opposite directions@same time
+                                       if (gram1[0x427D] == 0)
+                                               gram1[0x427B] = 1;              // Stick up
+                               }
+                               else if (event.key.keysym.sym == SDLK_DOWN)
+                               {
+                                       // Disallow opposite directions@same time
+                                       if (gram1[0x427B] == 0)
+                                               gram1[0x427D] = 1;              // Stick down
+                               }
+                               else if (event.key.keysym.sym == SDLK_q)
+                                       gram1[0x4276] = 1;                      // (Q)  Jump
+                               else if (event.key.keysym.sym == SDLK_e)        // (E) Fire
+                                       gram1[0x4278] = 1;
+
+                               break;
+                       case SDL_KEYUP:
+                               if (event.key.keysym.sym == SDLK_RIGHT)
+                                       gram1[0x427F] = 0;
+                               else if (event.key.keysym.sym == SDLK_LEFT)
+                                       gram1[0x4281] = 0;
+                               else if (event.key.keysym.sym == SDLK_UP)
+                                       gram1[0x427B] = 0;
+                               else if (event.key.keysym.sym == SDLK_DOWN)
+                                       gram1[0x427D] = 0;
+                               else if (event.key.keysym.sym == SDLK_q)
+                                       gram1[0x4276] = 0;                      // (Q)  Jump
+                               else if (event.key.keysym.sym == SDLK_e)        // (E) Fire
+                                       gram1[0x4278] = 0;
+
+                               break;
+                       }
+               }
 
 #if 0
                                if (keys[SDLK_ESCAPE])
@@ -1611,12 +1002,12 @@ WriteLog("About to enter main loop...\n");
 #endif
 #endif
 
-                               if (enable_cpu)
+               if (enable_cpu)
 //                             if (true)
-                               {
-                                       // We can do this here because we're not executing the cores yet.
-                                       cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-                                       cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+               {
+                       // We can do this here because we're not executing the cores yet.
+                       cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+                       cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
 //                                     while (cpu1.clock < 25000)
 // 1.538 MHz = 25633.333... cycles per frame (1/60 s)
 // 25600 cycles/frame
@@ -1626,158 +1017,35 @@ WriteLog("About to enter main loop...\n");
 // 640 * 40
 // 800 * 32
 // Interesting, putting IRQs at 30 Hz makes it run at the correct speed. Still hangs in the demo, though.
-                                       for(uint32_t i=0; i<640; i++)
+                       for(uint32_t i=0; i<640; i++)
 //                                     for(uint32_t i=0; i<1280; i++)
-                                       {
-                                               // Gay, but what are ya gonna do?
-                                               // There's better ways, such as keeping track of when slave writes to master, etc...
-                                               Execute6809(&cpu1, 40);
-                                               Execute6809(&cpu2, 40);
-                                       }
-                               } // END: enable_cpu
-
-//        if (refresh_++ == 1)                // 30 Hz...
-//        {
-//          if (scr_type)
-//            BlitWilliamsScreen(gram1);     // Display the screen...
-//          else
-//            BlitChar(screen, chr_rom, gram1);
-//          refresh_ = (refresh2 ? 1 : 0);    // 60/30 Hz...
-//        }
-
-#if 0
-//temp, for testing...
-BlitChar(screen, chr_rom, gram1);
-#endif
-                               // Speed throttling happens here...
-                               while (SDL_GetTicks() - oldTicks < 16)  // Actually, it's 16.66... Need to account for that somehow
-//                             while (SDL_GetTicks() - oldTicks < 32)  // Actually, it's 16.66... Need to account for that somehow
-                                       SDL_Delay(1);                           // Release our timeslice...
-
-                               oldTicks = SDL_GetTicks();
-//cout << "Finished frame..." << endl;
-                       }
-
-//      Stop_audio_output();
-//      ReleaseTimer();
-//      ReleaseKeyboard();               // Release the interrupt...
-//      RestoreOldMode();                // Restore screen
-                       if (brk && (cpu1.pc == brkpnt))
-                               cout << "CPU 1: Break at " << hex << cpu1.pc << endl;
-                       if (brk2 && (cpu2.pc == brkpnt2))
-                               cout << "CPU 2: Break at " << hex << cpu2.pc << endl;
-
-                       lbuff[0] = 'q';                         // Temp kludge...
-               }
-               else if (lbuff[0] == 'b')  // Set/clear breakpoint
-               {
-                       if (lbuff[1] != 0)
                        {
-                               lbuff[0] = 32;
-                               brkpnt = htod(lbuff);
-                               brk = true;
-                               cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
-                       }
-                       else
-                       {
-                               brk = false;
-                               cout << "Breakpoint cleared" << endl;
-                       }
-               }
-               else if (lbuff[0] == 'a')  // Set/clear breakpoint #2
-               {
-                       if (lbuff[1] != 0)
-                       {
-                               lbuff[0] = 32;
-                               brkpnt2 = htod(lbuff);
-                               brk2 = true;
-                               cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
-                       }
-                       else
-                       {
-                               brk2 = false;
-                               cout << "Breakpoint cleared" << endl;
-                       }
-               }
-               else if (lbuff[0] == 'i')  // Inspect registers
-               {
-                       printf("CPU1: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
-                                       cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
-                       cout << " iclk=" << dec << cpu1.clock << endl;
-                       printf("CPU2: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
-                                       cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
-                       cout << " iclk=" << dec << cpu2.clock << endl;
-
-                       if (brk)
-                               cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
-
-                       if (brk2)
-                               cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
-               }
-               else if (strncmp(lbuff, "swap", 4) == 0)  // Swap ROMs
-               {
-                       looking_at_rom = !looking_at_rom;
-                       cout << "Swapped:  Looking at ";
-                       (looking_at_rom ? cout << "ROM #1" : cout << "ROM #2");
-                       cout << endl;
-               }
-               else if (strncmp(lbuff, "seek", 4) == 0)  // Seek non-zero bytes in RAM
-               {
-
-                       if (lbuff[4] != 0)
-                       {
-                               for(int i=0; i<4; i++)
-                               lbuff[i] = 32;
-                               dpc = htod(lbuff);
-                       }
-
-                       do
-                       {
-                               x = gram1[dpc++];
-                       }
-                       while ((x == 0) && (dpc != 0xFFFF)); // Keep going until something found
-                       dpc--;
-
-                       printf("%04X: ", dpc);       // Show data found...
-
-                       for(int i=0; i<16; i++)
-                               printf("%02X ", gram1[(uint16_t)(dpc+i)]);
-
-                       cout << " ";
-
-                       for(int i=0; i<16; i++)
-                       {
-                               uint8_t a = gram1[dpc++];
-
-                               if (a<10)
-                                       cout << (char)(a+48);
-                               if ((a>9) && (a<37))
-                                       cout << (char)(a+55);
-                               if (a>36)
-                                       cout << ".";
+                               // Gay, but what are ya gonna do?
+                               // There's better ways, such as keeping track of when slave writes to master, etc...
+                               Execute6809(&cpu1, 40);
+                               Execute6809(&cpu2, 40);
                        }
+               } // END: enable_cpu
 
-                       cout << endl;
-               }
-               else if (lbuff[0] == 'v')    // View screen
-               {
-                       BlitChar(screen, chr_rom, gram1);
-                       getch();
-               }
+               // Speed throttling happens here...
+               while (SDL_GetTicks() - oldTicks < 16)  // Actually, it's 16.66... Need to account for that somehow
+//                             while (SDL_GetTicks() - oldTicks < 32)  // Actually, it's 16.66... Need to account for that somehow
+                       SDL_Delay(1);                           // Release our timeslice...
 
-               if (lbuff[0] == 'q')
-                       active = false; //break;  // Quit
+               oldTicks = SDL_GetTicks();
+//cout << "Finished frame..." << endl;
        }
 
-       SDL_Quit();                                                                     // Shut down SDL
+       SDL_Quit();
 
+       // Deallocate sounds if they were loaded
        for(int i=0; i<16; i++)
                if (psg_adrs[i])
-                       delete[] psg_adrs[i];                           // Deallocate if loaded
+                       delete[] psg_adrs[i];
 
        for(int i=0; i<14; i++)
                if (fm_adrs[i])
-                       delete[] fm_adrs[i];                            // Deallocate if loaded
+                       delete[] fm_adrs[i];
 
        LogDone();
 
index 3f01921f74819789e9da73063c702c220ef9ccc1..b76063fccc168a931ee92d83e1d8c63b620a0cf9 100644 (file)
@@ -2285,7 +2285,8 @@ static void Op8D(void)            // BSR
 
 static void Op6E(void)         // JMP ZP, X
 {
-       regs.pc = EA_ZP_X;
+       uint16_t m = EA_ZP_X;
+       regs.pc = m;
 }
 
 
@@ -2556,7 +2557,7 @@ static void Op__(void)
 // Ok, the exec_op[] array is globally defined here basically to save
 // a LOT of unnecessary typing.  Sure it's ugly, but hey, it works!
 //
-void (* exec_op[256])() = {
+static void (* exec_op[256])() = {
        Op__, Op01, Op__, Op__, Op04, Op05, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F,
        Op10, Op11, OpUN, OpUN, Op__, Op__, Op16, Op17, Op18, Op19, Op1A, Op1B, Op__, Op__, Op__, Op__,
        Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
diff --git a/src/v6808.cpp b/src/v6808.cpp
deleted file mode 100644 (file)
index 0f9860d..0000000
+++ /dev/null
@@ -1,2119 +0,0 @@
-//
-// Virtual 6808 Emulator v2.0
-//
-// by James Hammons
-// (C) 2006 Underground Software
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  -----------------------------------------------------------
-// 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
-// JLH  07/21/2009  Converted clock from 32-bit to 64-bit value, added possible
-//                  "don't branch" optimization
-//
-
-// 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_t 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__
-#define TEST_DONT_BRANCH_OPTIMIZATION
-
-#include "v6808.h"
-
-#ifdef __DEBUG__
-#include "dis6808.h"
-#include "log.h"
-#endif
-
-// Various macros
-
-#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_t)(b) < (uint8_t)(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_t)(b) < (uint16_t)(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)
-
-//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! [DONE, kinda]
-//Can't fix for reading...
-#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_t addr = EA_IMM;         v = regs.RdMem(addr)
-#define READ_ZP_WB(v)          uint16_t addr = EA_ZP;          v = regs.RdMem(addr)
-#define READ_ZP_X_WB(v)                uint16_t addr = EA_ZP_X;                v = regs.RdMem(addr)
-#define READ_ABS_WB(v)         uint16_t 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 uint8_t flagH, flagI, flagN, flagZ, flagV, flagC;
-
-static uint8_t CPUCycles[256] = {
-       1,  2,  1,  1,  1,  1,  2,  2,  4,  4,  2,  2,  2,  2,  2,  2,
-       2,  2,  1,  1,  1,  1,  2,  2,  1,  2,  1,  2,  1,  1,  1,  1,
-       4,  1,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-       4,  4,  4,  4,  4,  4,  4,  4,  1,  5,  1, 10,  1,  1,  9, 12,
-       2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,
-       2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,
-       7,  1,  1,  8,  7,  1,  7,  7,  7,  7,  7,  1,  7,  7,  4,  7,
-       6,  1,  1,  7,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,
-       2,  2,  2,  1,  2,  2,  2,  1,  2,  2,  2,  2,  3,  8,  3,  1,
-       3,  3,  3,  1,  3,  3,  3,  4,  3,  3,  3,  3,  4,  1,  4,  5,
-       5,  5,  5,  1,  5,  5,  5,  6,  5,  5,  5,  5,  6,  8,  6,  7,
-       4,  4,  4,  1,  4,  4,  4,  5,  4,  4,  4,  4,  5,  9,  5,  6,
-       2,  2,  2,  1,  2,  2,  2,  1,  2,  2,  2,  2,  1,  1,  3,  1,
-       3,  3,  3,  1,  3,  3,  3,  4,  3,  3,  3,  3,  1,  1,  4,  5,
-       5,  5,  5,  1,  5,  5,  5,  6,  5,  5,  5,  5,  1,  1,  6,  7,
-       4,  4,  4,  1,  4,  4,  4,  5,  4,  4,  4,  4,  1,  1,  5,  6
-};
-
-// Private function prototypes
-
-static uint16_t RdMemW(uint16_t);
-
-//
-// Read a word out of 6808 memory (little endian format)
-//
-static inline uint16_t RdMemW(uint16_t address)
-{
-       return (uint16_t)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
-}
-
-//
-// 6808 OPCODE IMPLEMENTATION
-//
-// 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! ;-)
-//
-
-/*
-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|
-*/
-
-// ADD opcodes
-
-#define OP_ADD_HANDLER(m, acc) \
-       uint16_t sum = (uint16_t)(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_t m = READ_IMM;
-       OP_ADD_HANDLER(m, regs.a);
-}
-
-static void Op9B(void)                                                 // ADDA ZP
-{
-       uint16_t m = READ_ZP;
-       OP_ADD_HANDLER(m, regs.a);
-}
-
-static void OpAB(void)                                                 // ADDA ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_ADD_HANDLER(m, regs.a);
-}
-
-static void OpBB(void)                                                 // ADDA ABS
-{
-       uint16_t m = READ_ABS;
-       OP_ADD_HANDLER(m, regs.a);
-}
-
-static void OpCB(void)                                                 // ADDB #
-{
-       uint16_t m = READ_IMM;
-       OP_ADD_HANDLER(m, regs.b);
-}
-
-static void OpDB(void)                                                 // ADDB ZP
-{
-       uint16_t m = READ_ZP;
-       OP_ADD_HANDLER(m, regs.b);
-}
-
-static void OpEB(void)                                                 // ADDB ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_ADD_HANDLER(m, regs.b);
-}
-
-static void OpFB(void)                                                 // ADDB ABS
-{
-       uint16_t m = READ_ABS;
-       OP_ADD_HANDLER(m, regs.b);
-}
-
-static void Op1B(void)                                                 // ABA
-{
-       OP_ADD_HANDLER(regs.b, regs.a);
-}
-
-/*
-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_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
-       flagC = sum >> 8; \
-       flagH = (sum >> 4) & 0x01; \
-       SET_V(m, acc, sum); \
-       acc = sum & 0xFF; \
-       SET_ZN(acc)
-
-static void Op89(void)                                                 // ADCA #
-{
-       uint16_t m = READ_IMM;
-       OP_ADC_HANDLER(m, regs.a);
-}
-
-static void Op99(void)                                                 // ADCA ZP
-{
-       uint16_t m = READ_ZP;
-       OP_ADC_HANDLER(m, regs.a);
-}
-
-static void OpA9(void)                                                 // ADCA ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_ADC_HANDLER(m, regs.a);
-}
-
-static void OpB9(void)                                                 // ADCA ABS
-{
-       uint16_t m = READ_ABS;
-       OP_ADC_HANDLER(m, regs.a);
-}
-
-static void OpC9(void)                                                 // ADCB #
-{
-       uint16_t m = READ_IMM;
-       OP_ADC_HANDLER(m, regs.b);
-}
-
-static void OpD9(void)                                                 // ADCB ZP
-{
-       uint16_t m = READ_ZP;
-       OP_ADC_HANDLER(m, regs.b);
-}
-
-static void OpE9(void)                                                 // ADCB ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_ADC_HANDLER(m, regs.b);
-}
-
-static void OpF9(void)                                                 // ADCB ABS
-{
-       uint16_t m = READ_ABS;
-       OP_ADC_HANDLER(m, regs.b);
-}
-
-/*
-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 |
-*/
-
-// AND opcodes
-
-#define OP_AND_HANDLER(m, acc) \
-       acc &= m; \
-       SET_ZN(acc); \
-       CLR_V
-
-static void Op84(void)                                                 // ANDA #
-{
-       uint8_t m = READ_IMM;
-       OP_AND_HANDLER(m, regs.a);
-}
-
-static void Op94(void)                                                 // ANDA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_AND_HANDLER(m, regs.a);
-}
-
-static void OpA4(void)                                                 // ANDA ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_AND_HANDLER(m, regs.a);
-}
-
-static void OpB4(void)                                                 // ANDA ABS
-{
-       uint16_t m = READ_ABS;
-       OP_AND_HANDLER(m, regs.a);
-}
-
-static void OpC4(void)                                                 // ANDB #
-{
-       uint8_t m = READ_IMM;
-       OP_AND_HANDLER(m, regs.b);
-}
-
-static void OpD4(void)                                                 // ANDB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_AND_HANDLER(m, regs.b);
-}
-
-static void OpE4(void)                                                 // ANDB ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_AND_HANDLER(m, regs.b);
-}
-
-static void OpF4(void)                                                 // ANDB ABS
-{
-       uint16_t m = READ_ABS;
-       OP_AND_HANDLER(m, regs.b);
-}
-
-/*
-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_t result = acc & (m); \
-       SET_ZN(result)
-
-static void Op85(void)                                                 // BITA #
-{
-       uint8_t m = READ_IMM;
-       OP_BIT_HANDLER(m, regs.a);
-}
-
-static void Op95(void)                                                 // BITA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_BIT_HANDLER(m, regs.a);
-}
-
-static void OpA5(void)                                                 // BITA ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_BIT_HANDLER(m, regs.a);
-}
-
-static void OpB5(void)                                                 // BITA ABS
-{
-       uint8_t m = READ_ABS;
-       OP_BIT_HANDLER(m, regs.a);
-}
-
-static void OpC5(void)                                                 // BITB #
-{
-       uint8_t m = READ_IMM;
-       OP_BIT_HANDLER(m, regs.b);
-}
-
-static void OpD5(void)                                                 // BITB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_BIT_HANDLER(m, regs.b);
-}
-
-static void OpE5(void)                                                 // BITB ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_BIT_HANDLER(m, regs.b);
-}
-
-static void OpF5(void)                                                 // BITB ABS
-{
-       uint8_t m = READ_ABS;
-       OP_BIT_HANDLER(m, regs.b);
-}
-
-/*
-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
-{
-       regs.WrMem(EA_ZP_X, 0);
-       CLR_NVC;
-       SET_Z(0);
-}
-
-static void Op7F(void)                                                 // CLR ABS
-{
-       regs.WrMem(EA_ABS, 0);
-       regs.pc += 2;
-       CLR_NVC;
-       SET_Z(0);
-}
-
-static void Op4F(void)                                                 // CLRA
-{
-       regs.a = 0;
-       CLR_NVC;
-       SET_Z(0);
-}
-
-static void Op5F(void)                                                 // CLRB
-{
-       regs.b = 0;
-       CLR_NVC;
-       SET_Z(0);
-}
-
-/*
-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_t result = acc - (m); \
-       SET_ZNVC_CMP(m, acc, result)
-
-static void Op81(void)                                                 // CMPA #
-{
-       uint8_t m = READ_IMM;
-       OP_CMP_HANDLER(m, regs.a);
-}
-
-static void Op91(void)                                                 // CMPA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_CMP_HANDLER(m, regs.a);
-}
-
-static void OpA1(void)                                                 // CMPA ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_CMP_HANDLER(m, regs.a);
-}
-
-static void OpB1(void)                                                 // CMPA ABS
-{
-       uint8_t m = READ_ABS;
-       OP_CMP_HANDLER(m, regs.a);
-}
-
-static void OpC1(void)                                                 // CMPB #
-{
-       uint8_t m = READ_IMM;
-       OP_CMP_HANDLER(m, regs.b);
-}
-
-static void OpD1(void)                                                 // CMPB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_CMP_HANDLER(m, regs.b);
-}
-
-static void OpE1(void)                                                 // CMPB ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_CMP_HANDLER(m, regs.b);
-}
-
-static void OpF1(void)                                                 // CMPB ABS
-{
-       uint8_t m = READ_ABS;
-       OP_CMP_HANDLER(m, regs.b);
-}
-
-static void Op11(void)                                                 // CBA
-{
-       OP_CMP_HANDLER(regs.b, regs.a);
-}
-
-/*
-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|
-*/
-
-// COM opcodes
-
-#define OP_COM_HANDLER(m) \
-       m = m ^ 0xFF; \
-       SET_ZN(m); \
-       CLR_V; \
-       flagC = 1
-
-static void Op63(void)                                                 // COM ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_COM_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op73(void)                                                 // COM ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_COM_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op43(void)                                                 // COMA
-{
-       OP_COM_HANDLER(regs.a);
-}
-
-static void Op53(void)                                                 // COMB
-{
-       OP_COM_HANDLER(regs.b);
-}
-
-/*
-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); \
-       flagV = (m == 0x80 ? 1 : 0); \
-       flagC = (m == 0x00 ? 1 : 0)
-
-static void Op60(void)                                                 // NEG ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_NEG_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op70(void)                                                 // NEG ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_NEG_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op40(void)                                                 // NEGA
-{
-       OP_NEG_HANDLER(regs.a);
-}
-
-static void Op50(void)                                                 // NEGB
-{
-       OP_NEG_HANDLER(regs.b);
-}
-
-/*
-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
-{
-       uint16_t result = (uint16_t)regs.a;
-
-       if ((regs.a & 0x0F) > 0x09 || flagH)
-               result += 0x06;
-
-       if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
-               result += 0x60;
-
-       regs.a = (uint8_t)result;
-       SET_ZN(result);
-       CLR_V;                                                                          // Not sure this is correct...
-       flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
-}
-
-/*
-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); \
-       flagV = (m == 0x7F ? 1 : 0)
-
-static void Op6A(void)                                                 // DEC ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_DEC_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op7A(void)                                                 // DEC ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_DEC_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op4A(void)                                                 // DECA
-{
-       OP_DEC_HANDLER(regs.a);
-}
-
-static void Op5A(void)                                                 // DECB
-{
-       OP_DEC_HANDLER(regs.b);
-}
-
-/*
-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 #
-{
-       uint8_t m = READ_IMM;
-       OP_EOR_HANDLER(m, regs.a);
-}
-
-static void Op98(void)                                                 // EORA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_EOR_HANDLER(m, regs.a);
-}
-
-static void OpA8(void)                                                 // EORA ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_EOR_HANDLER(m, regs.a);
-}
-
-static void OpB8(void)                                                 // EORA ABS
-{
-       uint8_t m = READ_ABS;
-       OP_EOR_HANDLER(m, regs.a);
-}
-
-static void OpC8(void)                                                 // EORB #
-{
-       uint8_t m = READ_IMM;
-       OP_EOR_HANDLER(m, regs.b);
-}
-
-static void OpD8(void)                                                 // EORB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_EOR_HANDLER(m, regs.b);
-}
-
-static void OpE8(void)                                                 // EORB ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_EOR_HANDLER(m, regs.b);
-}
-
-static void OpF8(void)                                                 // EORB ABS
-{
-       uint8_t m = READ_ABS;
-       OP_EOR_HANDLER(m, regs.b);
-}
-
-/*
-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); \
-       flagV = (m == 0x80 ? 1 : 0)
-
-static void Op6C(void)                                                 // INC ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_INC_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op7C(void)                                                 // INC ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_INC_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op4C(void)                                                 // INCA
-{
-       OP_INC_HANDLER(regs.a);
-}
-
-static void Op5C(void)                                                 // INCB
-{
-       OP_INC_HANDLER(regs.b);
-}
-
-/*
-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 #
-{
-       uint8_t m = READ_IMM;
-       OP_LDA_HANDLER(m, regs.a);
-}
-
-static void Op96(void)                                                 // LDAA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_LDA_HANDLER(m, regs.a);
-}
-
-static void OpA6(void)                                                 // LDAA ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_LDA_HANDLER(m, regs.a);
-}
-
-static void OpB6(void)                                                 // LDAA ABS
-{
-       uint8_t m = READ_ABS;
-       OP_LDA_HANDLER(m, regs.a);
-}
-
-static void OpC6(void)                                                 // LDAB #
-{
-       uint8_t m = READ_IMM;
-       OP_LDA_HANDLER(m, regs.b);
-}
-
-static void OpD6(void)                                                 // LDAB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_LDA_HANDLER(m, regs.b);
-}
-
-static void OpE6(void)                                                 // LDAB ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_LDA_HANDLER(m, regs.b);
-}
-
-static void OpF6(void)                                                 // LDAB ABS
-{
-       uint8_t m = READ_ABS;
-       OP_LDA_HANDLER(m, regs.b);
-}
-
-/*
-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_t m = READ_IMM;
-       OP_ORA_HANDLER(m, regs.a);
-}
-
-static void Op9A(void)                                                 // ORAA ZP
-{
-       uint8_t m = READ_ZP;
-       OP_ORA_HANDLER(m, regs.a);
-}
-
-static void OpAA(void)                                                 // ORAA ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_ORA_HANDLER(m, regs.a);
-}
-
-static void OpBA(void)                                                 // ORAA ABS
-{
-       uint8_t m = READ_ABS;
-       OP_ORA_HANDLER(m, regs.a);
-}
-
-static void OpCA(void)                                                 // ORAB #
-{
-       uint8_t m = READ_IMM;
-       OP_ORA_HANDLER(m, regs.b);
-}
-
-static void OpDA(void)                                                 // ORAB ZP
-{
-       uint8_t m = READ_ZP;
-       OP_ORA_HANDLER(m, regs.b);
-}
-
-static void OpEA(void)                                                 // ORAB ZP, X
-{
-       uint8_t m = READ_ZP_X;
-       OP_ORA_HANDLER(m, regs.b);
-}
-
-static void OpFA(void)                                                 // ORAB ABS
-{
-       uint8_t m = READ_ABS;
-       OP_ORA_HANDLER(m, regs.b);
-}
-
-/*
-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, *+ |      |
-*/
-
-static void Op36(void)                                                 // PSHA
-{
-       PUSH(regs.a);
-}
-
-static void Op37(void)                                                 // PSHB
-{
-       PUSH(regs.b);
-}
-
-static void Op32(void)                                                 // PULA
-{
-       regs.a = PULL;
-}
-
-static void Op33(void)                                                 // PULB
-{
-       regs.b = PULL;
-}
-
-/*
-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_t newCarry = (m & 0x80) >> 7; \
-       m = (m << 1) | flagC; \
-       SET_ZN(m); \
-       flagC = newCarry; \
-       flagV = flagN ^ flagC
-
-static void Op69(void)                                                 // ROL ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_ROL_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op79(void)                                                 // ROL ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_ROL_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op49(void)                                                 // ROLA
-{
-       OP_ROL_HANDLER(regs.a);
-}
-
-static void Op59(void)                                                 // ROLB
-{
-       OP_ROL_HANDLER(regs.b);
-}
-
-/*
-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_t newCarry = m & 0x01; \
-       m = (m >> 1) | (flagC << 7); \
-       SET_ZN(m); \
-       flagC = newCarry; \
-       flagV = flagN ^ flagC
-
-static void Op66(void)                                                 // ROR ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_ROR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op76(void)                                                 // ROR ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_ROR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op46(void)                                                 // RORA
-{
-       OP_ROR_HANDLER(regs.a);
-}
-
-static void Op56(void)                                                 // RORB
-{
-       OP_ROR_HANDLER(regs.b);
-}
-
-/*
-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_t newCarry = (m & 0x80) >> 7; \
-       m <<= 1; \
-       SET_ZN(m); \
-       flagC = newCarry; \
-       flagV = flagN ^ flagC
-
-static void Op68(void)                                                 // ASL ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_ASL_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op78(void)                                                 // ASL ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_ASL_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op48(void)                                                 // ASLA
-{
-       OP_ASL_HANDLER(regs.a);
-}
-
-static void Op58(void)                                                 // ASLB
-{
-       OP_ASL_HANDLER(regs.b);
-}
-
-/*
-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
-
-#define OP_ASR_HANDLER(m) \
-       uint8_t newCarry = m & 0x01; \
-       m = (m >> 1) | (m & 0x80); \
-       SET_ZN(m); \
-       flagC = newCarry; \
-       flagV = flagN ^ flagC
-
-static void Op67(void)                                                 // ASR ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_ASR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op77(void)                                                 // ASR ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_ASR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op47(void)                                                 // ASRA
-{
-       OP_ASR_HANDLER(regs.a);
-}
-
-static void Op57(void)                                                 // ASRB
-{
-       OP_ASR_HANDLER(regs.b);
-}
-
-/*
-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_t newCarry = m & 0x01; \
-       m >>= 1; \
-       SET_ZN(m); \
-       flagC = newCarry; \
-       flagV = flagN ^ flagC
-
-static void Op64(void)                                                 // LSR ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_LSR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op74(void)                                                 // LSR ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_LSR_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op44(void)                                                 // LSRA
-{
-       OP_LSR_HANDLER(regs.a);
-}
-
-static void Op54(void)                                                 // LSRB
-{
-       OP_LSR_HANDLER(regs.b);
-}
-
-/*
-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(EA_ZP, regs.a);
-}
-
-static void OpA7(void)                                                 // STAA ZP, X
-{
-       regs.WrMem(EA_ZP_X, regs.a);
-}
-
-static void OpB7(void)                                                 // STAA ABS
-{
-       regs.WrMem(EA_ABS, regs.a);
-       regs.pc += 2;
-}
-
-static void OpD7(void)                                                 // STAB ZP
-{
-       regs.WrMem(EA_ZP, regs.b);
-}
-
-static void OpE7(void)                                                 // STAB ZP, X
-{
-       regs.WrMem(EA_ZP_X, regs.b);
-}
-
-static void OpF7(void)                                                 // STAB ABS
-{
-       regs.WrMem(EA_ABS, regs.b);
-       regs.pc += 2;
-}
-
-/*
-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_t sum = (uint16_t)acc - (m); \
-       flagC = sum >> 15; \
-       SET_V(m, acc, sum); \
-       acc = (uint8_t)sum; \
-       SET_ZN(acc)
-
-static void Op80(void)                                                 // SUBA #
-{
-       uint16_t m = READ_IMM;
-       OP_SUB_HANDLER(m, regs.a);
-}
-
-static void Op90(void)                                                 // SUBA ZP
-{
-       uint16_t m = READ_ZP;
-       OP_SUB_HANDLER(m, regs.a);
-}
-
-static void OpA0(void)                                                 // SUBA ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_SUB_HANDLER(m, regs.a);
-}
-
-static void OpB0(void)                                                 // SUBA ABS
-{
-       uint16_t m = READ_ABS;
-       OP_SUB_HANDLER(m, regs.a);
-}
-
-static void OpC0(void)                                                 // SUBB #
-{
-       uint16_t m = READ_IMM;
-       OP_SUB_HANDLER(m, regs.b);
-}
-
-static void OpD0(void)                                                 // SUBB ZP
-{
-       uint16_t m = READ_ZP;
-       OP_SUB_HANDLER(m, regs.b);
-}
-
-static void OpE0(void)                                                 // SUBB ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_SUB_HANDLER(m, regs.b);
-}
-
-static void OpF0(void)                                                 // SUBB ABS
-{
-       uint16_t m = READ_ABS;
-       OP_SUB_HANDLER(m, regs.b);
-}
-
-static void Op10(void)                                                 // SBA
-{
-       OP_SUB_HANDLER(regs.b, regs.a);
-}
-
-/*
-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_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
-       flagC = sum >> 15; \
-       SET_V(m, acc, sum); \
-       acc = (uint8_t)sum; \
-       SET_ZN(acc)
-
-static void Op82(void)                                                 // SBCA #
-{
-       uint16_t m = READ_IMM;
-       OP_SBC_HANDLER(m, regs.a);
-}
-
-static void Op92(void)                                                 // SBCA ZP
-{
-       uint16_t m = READ_ZP;
-       OP_SBC_HANDLER(m, regs.a);
-}
-
-static void OpA2(void)                                                 // SBCA ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_SBC_HANDLER(m, regs.a);
-}
-
-static void OpB2(void)                                                 // SBCA ABS
-{
-       uint16_t m = READ_ABS;
-       OP_SBC_HANDLER(m, regs.a);
-}
-
-static void OpC2(void)                                                 // SBCB #
-{
-       uint16_t m = READ_IMM;
-       OP_SBC_HANDLER(m, regs.b);
-}
-
-static void OpD2(void)                                                 // SBCB ZP
-{
-       uint16_t m = READ_ZP;
-       OP_SBC_HANDLER(m, regs.b);
-}
-
-static void OpE2(void)                                                 // SBCB ZP, X
-{
-       uint16_t m = READ_ZP_X;
-       OP_SBC_HANDLER(m, regs.b);
-}
-
-static void OpF2(void)                                                 // SBCB ABS
-{
-       uint16_t m = READ_ABS;
-       OP_SBC_HANDLER(m, regs.b);
-}
-
-/*
-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 |
-*/
-
-static void Op16(void)                                                 // TAB
-{
-       regs.b = regs.a;
-       SET_ZN(regs.b);
-       CLR_V;
-}
-
-static void Op17(void)                                                 // TBA
-{
-       regs.a = regs.b;
-       SET_ZN(regs.a);
-       CLR_V;
-}
-
-/*
-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|
-*/
-
-// TST opcodes
-
-#define OP_TST_HANDLER(m) \
-       SET_ZN(m); \
-       CLR_VC
-
-static void Op6D(void)                                                 // TST ZP, X
-{
-       uint8_t m;
-       READ_ZP_X_WB(m);
-       OP_TST_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op7D(void)                                                 // TST ABS
-{
-       uint8_t m;
-       READ_ABS_WB(m);
-       OP_TST_HANDLER(m);
-       WRITE_BACK(m);
-}
-
-static void Op4D(void)                                                 // TSTA
-{
-       OP_TST_HANDLER(regs.a);
-}
-
-static void Op5D(void)                                                 // TSTB
-{
-       OP_TST_HANDLER(regs.b);
-}
-
-/*
-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_t result = regs.x - (m); \
-       SET_ZNVC_CMP16(m, regs.x, result)
-
-static void Op8C(void)                                                 // CPX #
-{
-       uint16_t m = READ_IMM16;
-       OP_CPX_HANDLER(m);
-}
-
-static void Op9C(void)                                                 // CPX ZP
-{
-       uint16_t m = READ_ZP16;
-       OP_CPX_HANDLER(m);
-}
-
-static void OpAC(void)                                                 // CPX ZP, X
-{
-       uint16_t m = READ_ZP_X16;
-       OP_CPX_HANDLER(m);
-}
-
-static void OpBC(void)                                                 // CPX ABS
-{
-       uint16_t m = READ_ABS16;
-       OP_CPX_HANDLER(m);
-}
-
-/*
-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.x--;
-       SET_Z(regs.x);
-}
-
-static void Op34(void)                                                 // DES
-{
-       regs.s--;
-}
-
-static void Op08(void)                                                 // INX
-{
-       regs.x++;
-       SET_Z(regs.x);
-}
-
-static void Op31(void)                                                 // INS
-{
-       regs.s++;
-}
-
-/*
-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 |
-*/
-
-// LD* opcode handler
-
-#define OP_LD_HANDLER(acc) \
-       SET_N16(acc); \
-       SET_Z(acc); \
-       CLR_V
-
-static void OpCE(void)                                                 // LDX #
-{
-       regs.x = READ_IMM16;
-       OP_LD_HANDLER(regs.x);
-}
-
-static void OpDE(void)                                                 // LDX ZP
-{
-       regs.x = READ_ZP16;
-       OP_LD_HANDLER(regs.x);
-}
-
-static void OpEE(void)                                                 // LDX ZP, X
-{
-       regs.x = READ_ZP_X16;
-       OP_LD_HANDLER(regs.x);
-}
-
-static void OpFE(void)                                                 // LDX ABS
-{
-       regs.x = READ_ABS16;
-       OP_LD_HANDLER(regs.x);
-}
-
-static void Op8E(void)                                                 // LDS #
-{
-       regs.s = READ_IMM16;
-       OP_LD_HANDLER(regs.s);
-}
-
-static void Op9E(void)                                                 // LDS ZP
-{
-       regs.s = READ_ZP16;
-       OP_LD_HANDLER(regs.s);
-}
-
-static void OpAE(void)                                                 // LDS ZP, X
-{
-       regs.s = READ_ZP_X16;
-       OP_LD_HANDLER(regs.s);
-}
-
-static void OpBE(void)                                                 // LDS ABS
-{
-       regs.s = READ_ABS16;
-       OP_LD_HANDLER(regs.s);
-}
-
-/*
-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
-{
-       uint16_t m = EA_ZP;
-       OP_ST_HANDLER(m, regs.x);
-}
-
-static void OpEF(void)                                                 // STX ZP, X
-{
-       uint16_t m = EA_ZP_X;
-       OP_ST_HANDLER(m, regs.x);
-}
-
-static void OpFF(void)                                                 // STX ABS
-{
-       uint16_t m = EA_ABS;
-       regs.pc += 2;
-       OP_ST_HANDLER(m, regs.x);
-}
-
-static void Op9F(void)                                                 // STS ZP
-{
-       uint16_t m = EA_ZP;
-       OP_ST_HANDLER(m, regs.s);
-}
-
-static void OpAF(void)                                                 // STS ZP, X
-{
-       uint16_t m = EA_ZP_X;
-       OP_ST_HANDLER(m, regs.s);
-}
-
-static void OpBF(void)                                                 // STS ABS
-{
-       uint16_t m = EA_ABS;
-       regs.pc += 2;
-       OP_ST_HANDLER(m, regs.s);
-}
-
-/*
-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
-{
-       regs.s = regs.x - 1;
-}
-
-static void Op30(void)                                                 // TSX
-{
-       regs.x = regs.s + 1;
-}
-
-/*
-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
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-       regs.pc += m;
-}
-
-static void Op24(void)                                                 // BCC
-{
-// NOTE: We can optimize this by following the maxim: "Don't branch!" by converting the boolean
-//       result into a multiplication. The only way to know if this is a win is to do some profiling
-//       both with and without the optimization.
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-//Note sure if the ! operator will do what we want, so we use ^ 1
-       regs.pc += m * (flagC ^ 0x01);
-#else
-       if (!flagC)
-               regs.pc += m;
-#endif
-}
-
-static void Op25(void)                                                 // BCS
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagC);
-#else
-       if (flagC)
-               regs.pc += m;
-#endif
-}
-
-static void Op27(void)                                                 // BEQ
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagZ);
-#else
-       if (flagZ)
-               regs.pc += m;
-#endif
-}
-
-static void Op2C(void)                                                 // BGE
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * ((flagN ^ flagV) ^ 0x01);
-#else
-       if (!(flagN ^ flagV))
-               regs.pc += m;
-#endif
-}
-
-static void Op2E(void)                                                 // BGT
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * ((flagZ | (flagN ^ flagV)) ^ 0x01);
-#else
-       if (!(flagZ | (flagN ^ flagV)))
-               regs.pc += m;
-#endif
-}
-
-static void Op22(void)                                                 // BHI
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * ((flagZ | flagC) ^ 0x01);
-#else
-       if (!(flagZ | flagC))
-               regs.pc += m;
-#endif
-}
-
-static void Op2F(void)                                                 // BLE
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagZ | (flagN ^ flagV));
-#else
-       if (flagZ | (flagN ^ flagV))
-               regs.pc += m;
-#endif
-}
-
-static void Op23(void)                                                 // BLS
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagZ | flagC);
-#else
-       if (flagZ | flagC)
-               regs.pc += m;
-#endif
-}
-
-static void Op2D(void)                                                 // BLT
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagN ^ flagV);
-#else
-       if (flagN ^ flagV)
-               regs.pc += m;
-#endif
-}
-
-static void Op2B(void)                                                 // BMI
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagN);
-#else
-       if (flagN)
-               regs.pc += m;
-#endif
-}
-
-static void Op26(void)                                                 // BNE
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagZ ^ 0x01);
-#else
-       if (!flagZ)
-               regs.pc += m;
-#endif
-}
-
-static void Op28(void)                                                 // BVC
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagV ^ 0x01);
-#else
-       if (!flagV)
-               regs.pc += m;
-#endif
-}
-
-static void Op29(void)                                                 // BVS
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagV);
-#else
-       if (flagV)
-               regs.pc += m;
-#endif
-}
-
-static void Op2A(void)                                                 // BPL
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-
-#ifdef TEST_DONT_BRANCH_OPTIMIZATION
-       regs.pc += m * (flagN ^ 0x01);
-#else
-       if (!flagN)
-               regs.pc += m;
-#endif
-}
-
-/*
-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
-{
-       int16_t m = (int16_t)(int8_t)READ_IMM;
-       PUSH16(regs.pc);
-       regs.pc += m;
-}
-
-static void Op6E(void)                                                 // JMP ZP, X
-{
-       regs.pc = EA_ZP_X;
-}
-
-static void Op7E(void)                                                 // JMP ABS
-{
-       regs.pc = EA_ABS;
-}
-
-static void OpAD(void)                                                 // JSR ZP, X
-{
-       uint16_t m = EA_ZP_X;
-       PUSH16(regs.pc);
-       regs.pc = m;
-}
-
-static void OpBD(void)                                                 // JSR ABS
-{
-       uint16_t m = EA_ABS;
-       regs.pc += 2;
-       PUSH16(regs.pc);
-       regs.pc = m;
-}
-
-/*
-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
-{
-}
-
-static void Op3B(void)                                                 // RTI
-{
-       regs.cc = PULL;
-       regs.a  = PULL;
-       regs.b  = PULL;
-       regs.x  = PULL16;
-       regs.pc = PULL16;
-       UNPACK_FLAGS;
-}
-
-static void Op39(void)                                                 // RTS
-{
-       regs.pc = PULL16;
-}
-
-static void Op3F(void)                                                 // SWI
-{
-       // 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!
-       flagI = 1;                                                                      // Also, set IRQ inhibit
-}
-
-static void Op3E(void)                                                 // WAI
-{
-#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 Op0C(void)                                                 // CLC
-{
-       flagC = 0;
-}
-
-static void Op0E(void)                                                 // CLI
-{
-       flagI = 0;
-}
-
-static void Op0A(void)                                                 // CLV
-{
-       flagV = 0;
-}
-
-static void Op0D(void)                                                 // SEC
-{
-       flagC = 1;
-}
-
-static void Op0F(void)                                                 // SEI
-{
-       flagI = 1;
-}
-
-static void Op0B(void)                                                 // SEV
-{
-       flagV = 1;
-}
-
-static void Op06(void)                                                 // TAP
-{
-       regs.cc = regs.a;
-       UNPACK_FLAGS;
-}
-
-static void Op07(void)                                                 // TPA
-{
-       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)
-{
-       regs.cpuFlags |= V6808_STATE_ILLEGAL_INST;
-}
-
-
-//
-// Ok, the exec_op[] array is globally defined here basically to save
-// a LOT of unnecessary typing.  Sure it's ugly, but hey, it works!
-//
-void (* exec_op[256])() = {
-       Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F,
-       Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__,
-       Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
-       Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, Op3E, Op3F,
-       Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
-       Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
-       Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
-       Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
-       Op80, Op81, Op82, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
-       Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F,
-       OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
-       OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
-       OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__,
-       OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF,
-       OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF,
-       OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF
-};
-
-
-//
-// Internal "memcpy" (so we don't have to link with any external libraries!)
-//
-static void myMemcpy(void * dst, void * src, uint32_t size)
-{
-       uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
-
-       for(uint32_t i=0; i<size; i++)
-               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_t cycles)
-{
-#warning "V6808_STATE_WAI is not properly handled yet! !!! FIX !!!"
-#warning "Need to convert from destructive clock to non-destructive. !!! FIX !!!"
-
-       myMemcpy(&regs, context, sizeof(V6808REGS));
-       UNPACK_FLAGS;                                                           // Explode flags register into individual uint8_ts
-
-       // Execute here...
-       while (regs.clock < cycles)
-       {
-#ifdef __DEBUG__
-if (logGo)
-       Decode6808(regs.pc);
-#endif
-               uint8_t opcode = regs.RdMem(regs.pc++);
-
-#ifdef __DEBUG__
-//if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
-//instCount[opcode]++;
-#endif
-
-               exec_op[opcode]();                                              // Execute that opcode...
-               regs.clock += CPUCycles[opcode];
-#ifdef __DEBUG__
-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)
-               {
-#ifdef __DEBUG__
-WriteLog("*** RESET LINE ASSERTED ***\n");
-#endif
-                       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)
-               {
-#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!
-
-#warning "# of clock cycles for NMI unknown. !!! FIX !!!"
-                       regs.clock += 0;                                                        // How many???
-                       context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
-                       regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI;        // Reset the asserted line (NMI)...
-               }
-               else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
-               {
-#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)?
-                       {
-#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!
-
-#warning "# of clock cycles for IRQ unknown. !!! FIX !!!"
-                               regs.clock += 0;                                // How many???
-#warning "IRQ/NMI lines should not be cleared here... !!! FIX !!!"
-                               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));
-}
-
-//
-// Get the clock of the currently executing CPU
-//
-uint64_t GetCurrentV6808Clock(void)
-{
-       return regs.clock;
-}
diff --git a/src/v6808.h b/src/v6808.h
deleted file mode 100644 (file)
index 196ce3e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Virtual 6808 Header file
-//
-// by James Hammons
-//
-// (C) 2006 Underground Software
-//
-
-#ifndef __V6808_H__
-#define __V6808_H__
-
-#include <stdint.h>
-
-// Useful defines
-
-#define FLAG_E         0x80            // ??? Entire ??? [No.]
-#define FLAG_F         0x40            // ??? Fast IRQ ??? [No.]
-#define FLAG_H         0x20            // Half carry
-#define FLAG_I         0x10            // IRQ
-#define FLAG_N         0x08            // Negative
-#define FLAG_Z         0x04            // Zero
-#define FLAG_V         0x02            // oVerflow
-#define FLAG_C         0x01            // Carry
-
-#define V6808_ASSERT_LINE_RESET                0x0001          // v6808 RESET line
-#define V6808_ASSERT_LINE_IRQ          0x0002          // v6808 IRQ line
-#define V6808_ASSERT_LINE_NMI          0x0004          // v6808 NMI line
-#define V6808_STATE_WAI                                0x0008          // v6808 wait for IRQ line
-#define V6808_STATE_ILLEGAL_INST       0x0010          // Illegal instruction executed flag
-//#define V6809_START_DEBUG_LOG                0x0020          // Debug log go (temporary!)
-
-// Useful structs
-
-struct V6808REGS
-{
-       uint16_t pc;                                    // 6808 PC register
-       uint16_t x;                                             // 6808 X index register
-       uint16_t s;                                             // 6808 System stack pointer
-       uint8_t cc;                                             // 6808 Condition Code register
-       uint8_t a;                                              // 6808 A register
-       uint8_t b;                                              // 6808 B register
-       uint64_t clock;                                 // 6808 clock
-       uint8_t (* RdMem)(uint16_t);    // Address of uint8_t read routine
-       void (* WrMem)(uint16_t, uint8_t);      // Address of uint8_t write routine
-       uint32_t cpuFlags;                              // v6808 IRQ/RESET flags
-       uint32_t clockOverrun;                  // Amount of overflow between runs
-};
-
-// Function prototypes
-
-void Execute6808(V6808REGS *, uint32_t);       // Function to execute 6808 instructions
-uint64_t GetCurrentV6808Clock(void);           // Get the clock of the currently executing CPU
-//uint8_t GetCCRegister(void);                         // Hmm.
-
-#endif // __V6808_H__
-
old mode 100644 (file)
new mode 100755 (executable)
index 862f1a8..a6c07fc
 //
-// Virtual 6809 v1.3
+// Virtual 6809 v1.4.1
 //
-// by James Hammons
-// (c) 1997, 2014 Underground Software
+// by James L. Hammons
+// (C) 1997, 2009, 2014 Underground Software
 //
-// JLH = James Hammons <jlhamm@acm.org>
+// JLH = James L. Hammons <jlhamm@acm.org>
 //
 // WHO  WHEN        WHAT
 // ---  ----------  -----------------------------------------------------------
 // JLH  06/15/2006  Added changelog ;-)
 // JLH  06/15/2006  Scrubbed all BYTE, WORD & DWORD references from the code
 // JLH  11/11/2006  Removed all SignedX() references
+// JLH  09/29/2009  Converted V6809 to macro implementation!
+// JLH  04/17/2014  Misc. cleanups, fixes to missing instructions
 //
 
-// Mebbe someday I'll get around to fixing the core to be more like V65C02...
-// We have a start... ;-)
-//
+#define __DEBUG__
 
 #include "v6809.h"
 
-#define __DEBUG__
 #ifdef __DEBUG__
 #include "dis6809.h"   // Temporary...
 #include "log.h"               // Temporary...
+bool disasm = false;//so we can extern this shit
 #endif
 
+#define TEST_DONT_BRANCH_OPTIMIZATION
+
 // Various macros
 
-#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_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 CLR_Z                          (flagZ = 0)
+#define CLR_ZN                         (flagZ = flagN = 0)
+#define CLR_ZNC                                (flagZ = flagN = 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_N16(r)                     (flagN = ((r) & 0x8000) >> 15)
+#define SET_V(a,b,r)           (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
+#define SET_V16(a,b,r)         (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
+#define SET_H(a,b,r)           (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
 
 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
-#define SET_C_ADD(a,b)         (regs.cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+//#define SET_C_ADD(a,b)               (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0))
 //#define SET_C_SUB(a,b)               (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
-#define SET_C_CMP(a,b)         (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+//#define SET_C_CMP(a,b)               (flagC = ((uint8_t)(b) >= (uint8_t)(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_ZN16(r)                    SET_N16(r); SET_Z(r)
+//#define SET_ZNC_ADD(a,b,r)   SET_N(r); SET_Z(r); SET_C_ADD(a,b)
 //#define SET_ZNC_SUB(a,b,r)   SET_N(r); SET_Z(r); SET_C_SUB(a,b)
-#define SET_ZNC_CMP(a,b,r)     SET_N(r); SET_Z(r); SET_C_CMP(a,b)
+//#define SET_ZNC_CMP(a,b,r)   SET_N(r); SET_Z(r); SET_C_CMP(a,b)
 
-//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
-//Hmm, why not do like we did for READ_ABS*???
-//Because the EA_* macros are usually used as an argument to a function call, that's why.
 #define EA_IMM                         regs.pc++
-#define EA_ZP                          regs.RdMem(regs.pc++)
-#define EA_ZP_X                                (regs.RdMem(regs.pc++) + regs.x) & 0xFF
-#define EA_ZP_Y                                (regs.RdMem(regs.pc++) + regs.y) & 0xFF
-#define EA_ABS                         RdMemW(regs.pc)
-#define EA_ABS_X                       RdMemW(regs.pc) + regs.x
-#define EA_ABS_Y                       RdMemW(regs.pc) + regs.y
-#define EA_IND_ZP_X                    RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
-#define EA_IND_ZP_Y                    RdMemW(regs.RdMem(regs.pc++)) + regs.y
-#define EA_IND_ZP                      RdMemW(regs.RdMem(regs.pc++))
+#define EA_DP                          (regs.dp << 8) | regs.RdMem(regs.pc++)
+#define EA_IDX                         DecodeIDX(regs.RdMem(regs.pc++))
+#define EA_ABS                         FetchMemW(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_ZP_Y                      regs.RdMem(EA_ZP_Y)
-#define READ_ABS                       regs.RdMem(EA_ABS);     regs.pc += 2
-#define READ_ABS_X                     regs.RdMem(EA_ABS_X);   regs.pc += 2
-#define READ_ABS_Y                     regs.RdMem(EA_ABS_Y);   regs.pc += 2
-#define READ_IND_ZP_X          regs.RdMem(EA_IND_ZP_X)
-#define READ_IND_ZP_Y          regs.RdMem(EA_IND_ZP_Y)
-#define READ_IND_ZP                    regs.RdMem(EA_IND_ZP)
+#define READ_IMM16                     FetchMemW(regs.pc)
+#define READ_DP                                regs.RdMem(EA_DP)
+#define READ_DP16                      RdMemW(EA_DP)
+#define READ_IDX                       regs.RdMem(EA_IDX)
+#define READ_IDX16                     RdMemW(EA_IDX)
+#define READ_ABS                       regs.RdMem(EA_ABS)
+#define READ_ABS16                     RdMemW(EA_ABS)
 
 #define READ_IMM_WB(v)         uint16_t addr = EA_IMM;      v = regs.RdMem(addr)
-#define READ_ZP_WB(v)          uint16_t addr = EA_ZP;       v = regs.RdMem(addr)
-#define READ_ZP_X_WB(v)                uint16_t addr = EA_ZP_X;     v = regs.RdMem(addr)
-#define READ_ABS_WB(v)         uint16_t addr = EA_ABS;      v = regs.RdMem(addr); regs.pc += 2
-#define READ_ABS_X_WB(v)       uint16_t addr = EA_ABS_X;    v = regs.RdMem(addr); regs.pc += 2
-#define READ_ABS_Y_WB(v)       uint16_t addr = EA_ABS_Y;    v = regs.RdMem(addr); regs.pc += 2
-#define READ_IND_ZP_X_WB(v)    uint16_t addr = EA_IND_ZP_X; v = regs.RdMem(addr)
-#define READ_IND_ZP_Y_WB(v)    uint16_t addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
-#define READ_IND_ZP_WB(v)      uint16_t addr = EA_IND_ZP;   v = regs.RdMem(addr)
+#define READ_DP_WB(v)          uint16_t addr = EA_DP;       v = regs.RdMem(addr)
+#define READ_IDX_WB(v)         uint16_t addr = EA_IDX;      v = regs.RdMem(addr)
+#define READ_ABS_WB(v)         uint16_t addr = EA_ABS;      v = regs.RdMem(addr)
 
 #define WRITE_BACK(d)          regs.WrMem(addr, (d))
 
+#define PULLS(r)                       r = regs.RdMem(regs.s++)
+#define PUSHS(r)                       regs.WrMem(--regs.s, (r))
+#define PULLS16(r)                     { r = RdMemW(regs.s); regs.s += 2; }
+#define PUSHS16(r)                     { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
+#define PULLU(r)                       r = regs.RdMem(regs.u++)
+#define PUSHU(r)                       regs.WrMem(--regs.u, (r))
+#define PULLU16(r)                     { r = RdMemW(regs.u); regs.u += 2; }
+#define PUSHU16(r)                     { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
+
+#define PACK_FLAGS                     ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
+#define UNPACK_FLAGS           flagE = (regs.cc & FLAG_E) >> 7; \
+       flagF = (regs.cc & FLAG_F) >> 6; \
+       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 V6809REGS regs;
-//Let's see if we can nuke this shit.
-static uint16_t addr;                                                          // Temporary variables common to all funcs...
-static uint8_t tmp;
+static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
+
+static const uint8_t page0Cycles[256] = {
+       6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $0x
+       1,  1,  2,  2,  1,  1,  5,  9,  1,  2,  3,  1,  3,  2,  8,  7,          // $1x
+       3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,          // $2x
+       4,  4,  4,  4,  5,  5,  5,  5,  1,  5,  3,  6, 21, 11,  0, 19,          // $3x
+       2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,          // $4x
+       2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  1,          // $5x
+       6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $6x
+       7,  1,  1,  7,  7,  1,  7,  7,  7,  7,  7,  1,  7,  7,  3,  7,          // $7x
+       2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  4,  7,  3,  1,          // $8x
+       4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $9x
+       4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $Ax
+       5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  7,  8,  6,  6,          // $Bx
+       2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  3,  1,  3,  1,          // $Cx
+       4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Dx
+       4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Ex
+       5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6           // $Fx
+};
+
+static const uint8_t page1Cycles[256] = {
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
+       1,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,          // $2x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
+       1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  4,  1,          // $8x
+       1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $9x
+       1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $Ax
+       1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  7,  7,          // $Bx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  4,  1,          // $Cx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Dx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Ex
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  7,  7           // $Fx
+};
+
+static const uint8_t page2Cycles[256] = {
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $2x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
+       1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  1,  1,          // $8x
+       1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $9x
+       1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $Ax
+       1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  1,  1,          // $Bx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Cx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Dx
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Ex
+       1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1           // $Fx
+};
 
 // Private function prototypes
 
-static uint16_t FetchW(void);
 static uint16_t RdMemW(uint16_t addr);
+static uint16_t FetchMemW(uint16_t addr);
 static void WrMemW(uint16_t addr, uint16_t w);
 static uint16_t ReadEXG(uint8_t);                                      // Read TFR/EXG post byte
 static void WriteEXG(uint8_t, uint16_t);                       // Set TFR/EXG data
 static uint16_t DecodeReg(uint8_t);                                    // Decode register data
 static uint16_t DecodeIDX(uint8_t);                                    // Decode IDX data
 
-//static void (* exec_op1[256])();
-//static void (* exec_op2[256])();
-#if 1
-
-// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
-// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
-// even *try* to see if they're there).
-
-#define FD(x)          static void Op##x();            // FD -> "Forward Declaration"
-#define FE(x)          static void Op10##x();
-#define FF(x)          static void Op11##x();
-
-FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11)
-FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23)
-FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31)
-FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40)
-FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56)
-FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69)
-FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C)
-FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B)
-FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A)
-FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8)
-FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6)
-FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4)
-FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5)
-FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3)
-FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1)
-FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF)
-FD(__) FD(01)
-
-FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E)
-FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3)
-FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
-
-FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
-
-#undef FD
-#undef FE
-#undef FF
-
-#endif
-
-// We can move these down and do away with the forward declarations... !!! FIX !!!
-// Actually, we can't because these are used in a couple of the opcode functions.
-// Have to think about how to fix that...
-
-//
-// Function arrays
-//
-
-// Array of page zero opcode functions...
-static void (* exec_op0[256])() = {
-       Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
-       Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
-       Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
-       Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
-       Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
-       Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
-       Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
-       Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
-       Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
-       Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
-       OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
-       OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
-       OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
-       OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
-       OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
-       OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
-};
-
-// Array of page one opcode functions...
-static void (* exec_op1[256])() = {
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op103F,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op1083, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op108C, Op__,   Op108E, Op__,
-       Op__,   Op__,   Op__,   Op1093, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op109C, Op__,   Op109E, Op109F,
-       Op__,   Op__,   Op__,   Op10A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10AC, Op__,   Op10AE, Op10AF,
-       Op__,   Op__,   Op__,   Op10B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10BC, Op__,   Op10BE, Op10BF,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10CE, Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10DE, Op10DF,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10EE, Op10EF,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10FE, Op10FF
-};
-
-// Array of page two opcode functions...
-static void (* exec_op2[256])() = {
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op113F,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op1183, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op118C, Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op1193, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op119C, Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op11A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11AC, Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op11B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11BC, Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
-       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__
-};
-
 
 //
-// Fetch a word out of 6809 memory (little endian format)
-// This is a leftover from when fetches were separated from garden variety reads...
+// Read word from memory function
 //
-static uint16_t FetchW()
+static inline uint16_t RdMemW(uint16_t addr)
 {
-       uint16_t w = RdMemW(regs.pc);
-       regs.pc += 2;
-       return w;
+       return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
 }
 
+
 //
-// Read word from memory function
+// Fetch a word from memory function. Increments PC
 //
-uint16_t RdMemW(uint16_t addr)
+static inline uint16_t FetchMemW(uint16_t addr)
 {
+       regs.pc += 2;
        return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
 }
 
+
 //
 // Write word to memory function
 //
-void WrMemW(uint16_t addr, uint16_t w)
+static inline void WrMemW(uint16_t addr, uint16_t w)
 {
        regs.WrMem(addr + 0, w >> 8);
        regs.WrMem(addr + 1, w & 0xFF);
 }
 
+
 //
 // Function to read TFR/EXG post byte
 //
-uint16_t ReadEXG(uint8_t code)
+static uint16_t ReadEXG(uint8_t code)
 {
        uint16_t retval;
 
@@ -271,6 +227,7 @@ uint16_t ReadEXG(uint8_t code)
                retval = regs.b;
                break;
        case 10:
+               PACK_FLAGS;
                retval = regs.cc;
                break;
        case 11:
@@ -283,10 +240,11 @@ uint16_t ReadEXG(uint8_t code)
        return retval;
 }
 
+
 //
 // Function to set TFR/EXG data
 //
-void WriteEXG(uint8_t code, uint16_t data)
+static void WriteEXG(uint8_t code, uint16_t data)
 {
        switch (code)
        {
@@ -307,16 +265,17 @@ void WriteEXG(uint8_t code, uint16_t data)
        case 9:
                regs.b = data & 0xFF;  break;
        case 10:
-               regs.cc = data & 0xFF;  break;
+               regs.cc = data & 0xFF;  UNPACK_FLAGS;  break;
        case 11:
                regs.dp = data & 0xFF;  break;
        }
 }
 
+
 //
 // Function to decode register data
 //
-uint16_t DecodeReg(uint8_t reg)
+static uint16_t DecodeReg(uint8_t reg)
 {
        uint16_t retval;
 
@@ -335,10 +294,11 @@ uint16_t DecodeReg(uint8_t reg)
        return retval;
 }
 
+
 //
 // Function to decode IDX data
 //
-uint16_t DecodeIDX(uint8_t code)
+static uint16_t DecodeIDX(uint8_t code)
 {
        uint16_t addr, woff;
        uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
@@ -390,7 +350,7 @@ uint16_t DecodeIDX(uint8_t code)
                                addr = RdMemW(woff);
                                break;
                        case 9:
-                               woff = DecodeReg(reg) + FetchW();
+                               woff = DecodeReg(reg) + FetchMemW(regs.pc);
                                addr = RdMemW(woff);
                                break;
                        case 11:
@@ -398,15 +358,17 @@ uint16_t DecodeIDX(uint8_t code)
                                addr = RdMemW(woff);
                                break;
                        case 12:
-                               woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+//                             woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+                               woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
+                               regs.pc++;
                                addr = RdMemW(woff);
                                break;
                        case 13:
-                               woff = regs.pc + FetchW();
+                               woff = regs.pc + FetchMemW(regs.pc);
                                addr = RdMemW(woff);
                                break;
                        case 15:
-                               woff = FetchW();
+                               woff = FetchMemW(regs.pc);
                                addr = RdMemW(woff);
                                break;
                        }
@@ -455,10 +417,11 @@ uint16_t DecodeIDX(uint8_t code)
         case 5:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;  break; }
         case 6:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;  break; }
         case 8:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
-        case 9:  { addr = DecodeReg(reg) + FetchW();  break; }
+        case 9:  { addr = DecodeReg(reg) + FetchMemW(regs.pc);  break; }
         case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);  break; }
-        case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
-        case 13: { addr = regs.pc + FetchW();  break; }
+//        case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
+        case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++;  break; }
+        case 13: { addr = regs.pc + FetchMemW(regs.pc);  break; }
                        }
                }
        }
@@ -466,2589 +429,2875 @@ uint16_t DecodeIDX(uint8_t code)
        return addr;
 }
 
+
 //
-// Page zero instructions...
+// 6809 OPCODE IMPLEMENTATION
 //
+// 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! ;-)
+//
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 89    0137 | ADCA        | IMMEDIATE    |   2   |   2   | aaaaa |
+ | 99    0153 | ADCA        | DIRECT       |   4   |   2   | aaaaa |
+ | A9    0169 | ADCA        | INDEXED      |   4   |   2   | aaaaa |
+ | B9    0185 | ADCA        | EXTENDED     |   5   |   3   | aaaaa |
+ | C9    0201 | ADCB        | IMMEDIATE    |   2   |   2   | aaaaa |
+ | D9    0217 | ADCB        | DIRECT       |   4   |   2   | aaaaa |
+ | E9    0233 | ADCB        | INDEXED      |   4   |   2   | aaaaa |
+ | F9    0249 | ADCB        | EXTENDED     |   5   |   3   | aaaaa |
+*/
+
+// ADC opcodes
+
+#define OP_ADC_HANDLER(m, acc) \
+       uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
+       flagC = (sum >> 8) & 0x01; \
+       SET_H(m, acc, sum); \
+       SET_V(m, acc, sum); \
+       acc = sum & 0xFF; \
+       SET_ZN(acc)
+
+/*
+Old flag handling code:
+  (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
+*/
+
+static void Op89(void)         // ADCA #
+{
+       uint16_t m = READ_IMM;
+       OP_ADC_HANDLER(m, regs.a);
+}
+
+
+static void Op99(void)         // ADCA DP
+{
+       uint16_t m = READ_DP;
+       OP_ADC_HANDLER(m, regs.a);
+}
+
 
-static void Op00(void)                                                                 // NEG DP
+static void OpA9(void)         // ADCA IDX
 {
-       addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
-       tmp = 256 - regs.RdMem(addr);
-       regs.WrMem(addr, tmp);
+       uint16_t m = READ_IDX;
+       OP_ADC_HANDLER(m, regs.a);
+}
 
-       (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD);      // oVerflow
-       (tmp == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);      // Adjust Zero flag
-       (tmp & 0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);      // Adjust Negative flag
-       (tmp > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE);      // Adjust carry
 
-       regs.clock += 6;
+static void OpB9(void)         // ADCA ABS
+{
+       uint16_t m = READ_ABS;
+       OP_ADC_HANDLER(m, regs.a);
 }
 
-static void Op01(void)                                                                 // NEG DP (Undocumented)
+
+static void OpC9(void)         // ADCB #
 {
-       Op00();
+       uint16_t m = READ_IMM;
+       OP_ADC_HANDLER(m, regs.b);
 }
 
-static void Op03(void)                                                                 // COM DP
+
+static void OpD9(void)         // ADCB DP
 {
-       addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
-       tmp = 0xFF ^ regs.RdMem(addr);
-       regs.WrMem(addr, tmp);
+       uint16_t m = READ_DP;
+       OP_ADC_HANDLER(m, regs.b);
+}
 
-       regs.cc &= 0xFD;  regs.cc |= 0x01;                                      // CLV SEC
-       (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);         // Adjust Zero flag
-       (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);         // Adjust Negative flag
 
-       regs.clock += 6;
+static void OpE9(void)         // ADCB IDX
+{
+       uint16_t m = READ_IDX;
+       OP_ADC_HANDLER(m, regs.b);
 }
 
-static void Op04(void)  // LSR DP
+
+static void OpF9(void)         // ADCB ABS
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
-  tmp = regs.RdMem(addr);
-  (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
-  tmp >>= 1;  regs.WrMem(addr, tmp);
-  regs.cc &= 0xF7;                             // CLN
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  regs.clock += 6;
+       uint16_t m = READ_ABS;
+       OP_ADC_HANDLER(m, regs.b);
 }
-static void Op06(void)  // ROR DP
+
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 3A    0058 | ABX         | INHERENT     |   3   |   1   | ----- |
+ | 8B    0139 | ADDA        | IMMEDIATE    |   2   |   2   | aaaaa |
+ | 9B    0155 | ADDA        | DIRECT       |   4   |   2   | aaaaa |
+ | AB    0171 | ADDA        | INDEXED      |   4   |   2   | aaaaa |
+ | BB    0187 | ADDA        | EXTENDED     |   5   |   3   | aaaaa |
+ | C3    0195 | ADDD        | IMMEDIATE    |   4   |   3   | -aaaa |
+ | CB    0203 | ADDB        | IMMEDIATE    |   2   |   2   | aaaaa |
+ | D3    0211 | ADDD        | DIRECT       |   6   |   2   | -aaaa |
+ | DB    0219 | ADDB        | DIRECT       |   4   |   2   | aaaaa |
+ | E3    0227 | ADDD        | INDEXED      |   6   |   2   | -aaaa |
+ | EB    0235 | ADDB        | INDEXED      |   4   |   2   | aaaaa |
+ | F3    0243 | ADDD        | EXTENDED     |   7   |   3   | -aaaa |
+ | FB    0251 | ADDB        | EXTENDED     |   5   |   3   | aaaaa |
+*/
+
+// ADD opcodes
+
+#define OP_ADD_HANDLER(m, acc) \
+       uint16_t sum = (uint16_t)(acc) + (m); \
+       flagC = (sum >> 8) & 0x01; \
+       SET_H(m, acc, sum); \
+       SET_V(m, acc, sum); \
+       (acc) = sum & 0xFF; \
+       SET_ZN(acc)
+
+#define OP_ADD_HANDLER16(m, hireg, loreg) \
+       uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
+       uint32_t sum = acc + (m); \
+       flagC = (sum >> 16) & 0x01; \
+       SET_V16(m, acc, sum); \
+       acc = sum & 0xFFFF; \
+       hireg = (acc >> 8) & 0xFF; \
+       loreg = acc & 0xFF; \
+       SET_ZN16(acc)
+
+/*
+Old flags:
+  (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+  ((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);  // Set Zero flag
+  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
+
+  dr += addr;
+  (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
+  dr &= 0xFFFF;
+  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
+  ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+  regs.a = dr>>8;  regs.b = dr&0xFF;
+  regs.clock += 4;
+*/
+
+static void Op3A(void)         // ABX
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8_t tmp2 = regs.RdMem(addr);
-  tmp = (tmp2>>1) + (regs.cc&0x01)*128;
-  regs.WrMem(addr, tmp);
-  (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
-  (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
-  (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
-  regs.clock += 6;
+       regs.x += (uint16_t)regs.b;
 }
-static void Op07(void)  // ASR DP
+
+
+static void Op8B(void)         // ADDA #
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  tmp = regs.RdMem(addr);
-  (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
-  tmp >>= 1;
-  if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
-  regs.WrMem(addr, tmp);
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 6;
+       uint16_t m = READ_IMM;
+       OP_ADD_HANDLER(m, regs.a);
 }
-static void Op08(void)  // LSL DP
+
+
+static void Op9B(void)         // ADDA DP
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
-  tmp = regs.RdMem(addr);
-  (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
-  tmp <<= 1;
-  regs.WrMem(addr, tmp);
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 6;
+       uint16_t m = READ_DP;
+       OP_ADD_HANDLER(m, regs.a);
 }
-static void Op09(void)  // ROL DP
+
+
+static void OpAB(void)         // ADDA IDX
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8_t tmp2 = regs.RdMem(addr);
-  tmp = (tmp2<<1) + (regs.cc&0x01);
-  regs.WrMem(addr, tmp);
-  (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
-  ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
-  (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
-  regs.clock += 6;
+       uint16_t m = READ_IDX;
+       OP_ADD_HANDLER(m, regs.a);
 }
-static void Op0A(void)  // DEC DP
+
+
+static void OpBB(void)         // ADDA ABS
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
-  tmp = regs.RdMem(addr) - 1;
-  regs.WrMem(addr, tmp);
-  (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
-  regs.clock += 6;
+       uint16_t m = READ_ABS;
+       OP_ADD_HANDLER(m, regs.a);
 }
-static void Op0C(void)  // INC DP
+
+
+static void OpC3(void)         // ADDD #
 {
-  addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
-  tmp = regs.RdMem(addr) + 1;
-  regs.WrMem(addr, tmp);
-  (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
-  regs.clock += 6;
+       uint32_t m = READ_IMM16;
+       OP_ADD_HANDLER16(m, regs.a, regs.b);
 }
-static void Op0D(void)  // TST DP
+
+
+static void OpCB(void)         // ADDB #
 {
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  regs.cc &= 0xFD;                              // CLV
-  (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
-  (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
-  regs.clock += 6;
+       uint16_t m = READ_IMM;
+       OP_ADD_HANDLER(m, regs.b);
 }
-static void Op0E(void)  // JMP DP
+
+
+static void OpD3(void)         // ADDD DP
 {
-  regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
-  regs.clock += 3;
+       uint32_t m = READ_DP16;
+       OP_ADD_HANDLER16(m, regs.a, regs.b);
 }
-static void Op0F(void)  // CLR DP
+
+
+static void OpDB(void)         // ADDB DP
 {
-  regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
-  regs.cc &= 0xF0;  regs.cc |= 0x04;                // CLN, SEZ, CLV, CLC
-  regs.clock += 6;
+       uint16_t m = READ_DP;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op10(void)                                                                                 // Page 1 opcode
+
+static void OpE3(void)         // ADDD IDX
 {
-       exec_op1[regs.RdMem(regs.pc++)]();
+       uint32_t m = READ_IDX16;
+       OP_ADD_HANDLER16(m, regs.a, regs.b);
 }
 
-static void Op11(void)                                                 // Page 2 opcode
+
+static void OpEB(void)         // ADDB IDX
 {
-       exec_op2[regs.RdMem(regs.pc++)]();
+       uint16_t m = READ_IDX;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op12(void)                                                 // NOP
+
+static void OpF3(void)         // ADDD ABS
 {
-       regs.clock += 2;
+       uint32_t m = READ_ABS16;
+       OP_ADD_HANDLER16(m, regs.a, regs.b);
 }
 
-static void Op13(void)                                                 // SYNC
+
+static void OpFB(void)         // ADDB ABS
 {
-       // Fix this so it does the right thing (software interrupt!)
-       regs.clock += 2;
+       uint16_t m = READ_ABS;
+       OP_ADD_HANDLER(m, regs.b);
 }
 
-static void Op16(void)                                                 // LBRA
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 84    0132 | ANDA        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | 94    0148 | ANDA        | DIRECT       |   4   |   2   | -aa0- |
+ | A4    0164 | ANDA        | INDEXED      |   4   |   2   | -aa0- |
+ | B4    0180 | ANDA        | EXTENDED     |   5   |   3   | -aa0- |
+ | C4    0196 | ANDB        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | D4    0212 | ANDB        | DIRECT       |   4   |   2   | -aa0- |
+ | E4    0228 | ANDB        | INDEXED      |   4   |   2   | -aa0- |
+ | F4    0244 | ANDB        | EXTENDED     |   5   |   3   | -aa0- |
+*/
+
+// AND opcodes
+
+#define OP_AND_HANDLER(m, acc) \
+       acc &= m; \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op84(void)                                                 // ANDA #
 {
-//     regs.pc += SignedW(FetchW());
-       regs.pc += FetchW();                                            // No need to make signed, both are 16 bit quantities
+       uint16_t m = READ_IMM;
+       OP_AND_HANDLER(m, regs.a);
+}
 
-       regs.clock += 5;
+static void Op94(void)                                                 // ANDA DP
+{
+       uint16_t m = READ_DP;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op17(void)                                                 // LBSR
+static void OpA4(void)                                                 // ANDA IDX
 {
-       uint16_t word = FetchW();
-       regs.WrMem(--regs.s, regs.pc & 0xFF);
-       regs.WrMem(--regs.s, regs.pc >> 8);
-//     regs.pc += SignedW(addr);
-       regs.pc += word;                                                        // No need to make signed, both are 16 bit
+       uint16_t m = READ_IDX;
+       OP_AND_HANDLER(m, regs.a);
+}
 
-       regs.clock += 9;
+static void OpB4(void)                                                 // ANDA ABS
+{
+       uint16_t m = READ_ABS;
+       OP_AND_HANDLER(m, regs.a);
 }
 
-static void Op19(void)  // DAA
+static void OpC4(void)                                                 // ANDB #
 {
-#if 0
-       uint8_t result = regs.a;
+       uint16_t m = READ_IMM;
+       OP_AND_HANDLER(m, regs.b);
+}
 
-       if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
-       {
-//             regs.a += 0x06;
-               result += 0x06;
-               regs.cc |= 0x20;              // Then adjust & set half carry
-       }
+static void OpD4(void)                                                 // ANDB DP
+{
+       uint16_t m = READ_DP;
+       OP_AND_HANDLER(m, regs.b);
+}
 
-       if ((regs.cc&0x01) || (regs.a > 0x9F))           // C set or hi nyb too big?
-       {
-//             regs.a += 0x60;
-               result += 0x60;
-               regs.cc |= 0x01;              // Then adjust & set carry
-       }
+static void OpE4(void)                                                 // ANDB IDX
+{
+       uint16_t m = READ_IDX;
+       OP_AND_HANDLER(m, regs.b);
+}
 
-       regs.a = result;
+static void OpF4(void)                                                 // ANDB ABS
+{
+       uint16_t m = READ_ABS;
+       OP_AND_HANDLER(m, regs.b);
+}
 
-       regs.cc &= 0xF1;                             // CL NZV
-       if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
-       if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
-#else
-       uint16_t result = (uint16_t)regs.a;
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 08    0008 | LSL/ASL     | DIRECT       |   6   |   2   | naaas |
+ | 48    0072 | LSLA/ASLA   | INHERENT     |   2   |   1   | naaas |
+ | 58    0088 | LSLB/ASLB   | INHERENT     |   2   |   1   | naaas |
+ | 68    0104 | LSL/ASL     | INDEXED      |   6   |   2   | naaas |
+ | 78    0120 | LSL/ASL     | EXTENDED     |   7   |   3   | naaas |
+*/
 
-       if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
-               result += 0x06;
+// ASL opcodes
 
-       if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
-               result += 0x60;
+#define OP_ASL_HANDLER(m) \
+       uint16_t res = m << 1; \
+       SET_V(m, m, res); \
+       flagC = (res >> 8) & 0x01; \
+       m = res & 0xFF; \
+       SET_ZN(m)
 
-       regs.a = (uint8_t)result;
-//     SET_ZN(result);
-//     CLR_V;                                                                          // Not sure this is correct...
-       regs.cc &= 0xF1;                             // CL NZV
-       if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
-       if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
-//     flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
-       regs.cc |= (result & 0x100) > 8;
-#endif
-       regs.clock += 2;
+static void Op08(void)                                                 // ASL DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_ASL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op1A(void)                                                                 // ORCC #
+static void Op48(void)                                                 // ASLA
 {
-       regs.cc |= regs.RdMem(regs.pc++);
+       OP_ASL_HANDLER(regs.a);
+}
 
-       regs.clock += 3;
+static void Op58(void)                                                 // ASLB
+{
+       OP_ASL_HANDLER(regs.b);
 }
 
-static void Op1C(void)                                                                 // ANDCC #
+static void Op68(void)                                                 // ASL IDX
 {
-       regs.cc &= regs.RdMem(regs.pc++);
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_ASL_HANDLER(m);
+       WRITE_BACK(m);
+}
 
-       regs.clock += 3;
+static void Op78(void)                                                 // ASL ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_ASL_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op1D(void)                                                 // SEX
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 07    0007 | ASR         | DIRECT       |   6   |   2   | uaa-s |
+ | 47    0071 | ASRA        | INHERENT     |   2   |   1   | uaa-s |
+ | 57    0087 | ASRB        | INHERENT     |   2   |   1   | uaa-s |
+ | 67    0103 | ASR         | INDEXED      |   6   |   2   | uaa-s |
+ | 77    0119 | ASR         | EXTENDED     |   7   |   3   | uaa-s |
+*/
+
+// ASR opcodes (arithmetic, so preserves the sign)
+
+#define OP_ASR_HANDLER(m) \
+       uint8_t res = (m & 0x80) | (m >> 1); \
+       SET_ZN(res); \
+       flagC = m & 0x01; \
+       m = res
+
+static void Op07(void)                                                 // ASR DP
 {
-       (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_ASR_HANDLER(m);
+       WRITE_BACK(m);
+}
 
-       ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
-       (regs.a & 0x80          ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
+static void Op47(void)                                                 // ASRA
+{
+       OP_ASR_HANDLER(regs.a);
+}
 
-       regs.clock += 2;
+static void Op57(void)                                                 // ASRB
+{
+       OP_ASR_HANDLER(regs.b);
 }
 
-static void Op1E(void)                                                 // EXG
+static void Op67(void)                                                 // ASR IDX
 {
-       tmp = regs.RdMem(regs.pc++);
-       addr = ReadEXG(tmp >> 4);
-       WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
-       WriteEXG(tmp & 0xF, addr);
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_ASR_HANDLER(m);
+       WRITE_BACK(m);
+}
 
-       regs.clock += 8;
+static void Op77(void)                                                 // ASR ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_ASR_HANDLER(m);
+       WRITE_BACK(m);
 }
 
-static void Op1F(void)  // TFR
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 16    0022 | LBRA        | RELATIVE     |   5   |   3   | ----- |
+ | 20    0032 | BRA         | RELATIVE     |   3   |   2   | ----- |
+ | 21    0033 | BRN         | RELATIVE     |   3   |   2   | ----- |
+ | 22    0034 | BHI         | RELATIVE     |   3   |   2   | ----- |
+ | 23    0035 | BLS         | RELATIVE     |   3   |   2   | ----- |
+ | 24    0036 | BHS/BCC     | RELATIVE     |   3   |   2   | ----- |
+ | 25    0037 | BLO/BCS     | RELATIVE     |   3   |   2   | ----- |
+ | 26    0038 | BNE         | RELATIVE     |   3   |   2   | ----- |
+ | 27    0039 | BEQ         | RELATIVE     |   3   |   2   | ----- |
+ | 28    0040 | BVC         | RELATIVE     |   3   |   2   | ----- |
+ | 29    0041 | BVS         | RELATIVE     |   3   |   2   | ----- |
+ | 2A    0042 | BPL         | RELATIVE     |   3   |   2   | ----- |
+ | 2B    0043 | BMI         | RELATIVE     |   3   |   2   | ----- |
+ | 2C    0044 | BGE         | RELATIVE     |   3   |   2   | ----- |
+ | 2D    0045 | BLT         | RELATIVE     |   3   |   2   | ----- |
+ | 2E    0046 | BGT         | RELATIVE     |   3   |   2   | ----- |
+ | 2F    0047 | BLE         | RELATIVE     |   3   |   2   | ----- |
+ | 1021  4129 | LBRN        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1022  4130 | LBHI        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1023  4131 | LBLS        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1024  4132 | LBHS/LBCC   | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1025  4133 | LBLO/LBCS   | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1026  4134 | LBNE        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1027  4135 | LBEQ        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1028  4136 | LBVC        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 1029  4137 | LBVS        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102A  4138 | LBPL        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102B  4139 | LBMI        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102C  4140 | LBGE        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102D  4141 | LBLT        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102E  4142 | LBGT        | RELATIVE     | 5(6)  |   4   | ----- |
+ | 102F  4143 | LBLE        | RELATIVE     | 5(6)  |   4   | ----- |
+*/
+
+// Branch opcodes
+
+static void Op16(void)                                                 // LBRA
 {
-  tmp = regs.RdMem(regs.pc++);
-  WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
-  regs.clock += 7;
+       uint16_t offset = READ_IMM16;
+       regs.pc += offset;
 }
 
 static void Op20(void)                                                 // BRA
 {
-//     regs.pc += SignedB(regs.RdMem(regs.pc++));  // Branch always
-       regs.pc += (int16_t)(int8_t)regs.RdMem(regs.pc) + 1;    // Branch always
-
-       regs.clock += 3;
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
+       regs.pc += offset;
 }
 
 static void Op21(void)                                                 // BRN
 {
-       regs.RdMem(regs.pc++);
-
-       regs.clock += 3;
+       // This is basically a 2 byte NOP
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 }
 
 static void Op22(void)                                                 // BHI
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // !C && !Z
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs.cc & 0x05))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
+       regs.pc += offset * ((flagZ | flagC) ^ 0x01);
+#else
+       if (!(flagZ || flagC))
+               regs.pc += offset;
+#endif
 }
 
 static void Op23(void)                                                 // BLS
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (regs.cc & 0x05)
-               regs.pc += word;
+       // C || Z
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ | flagC);
+#else
+       if (flagZ || flagC)
+               regs.pc += offset;
+#endif
 }
 
-static void Op24(void)                                                 // BCC (BHS)
+static void Op24(void)                                                 // BHS/CC
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // !C
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs.cc & 0x01))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagC ^ 0x01);
+#else
+       if (!flagC)
+               regs.pc += offset;
+#endif
 }
 
-static void Op25(void)                                                 // BCS (BLO)
+static void Op25(void)                                                 // BLO/CS
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (regs.cc & 0x01)
-               regs.pc += word;
+       // C
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
+//if (disasm)
+//     WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagC;
+#else
+       if (flagC)
+               regs.pc += offset;
+#endif
 }
 
 static void Op26(void)                                                 // BNE
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // !Z
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs.cc & 0x04))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ ^ 0x01);
+#else
+       if (!flagZ)
+               regs.pc += offset;
+#endif
 }
 
 static void Op27(void)                                                 // BEQ
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (regs.cc & 0x04)
-               regs.pc += word;
+       // Z
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagZ;
+#else
+       if (flagZ)
+               regs.pc += offset;
+#endif
 }
 
 static void Op28(void)                                                 // BVC
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // !V
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs.cc & 0x02))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagV ^ 0x01);
+#else
+       if (!flagV)
+               regs.pc += offset;
+#endif
 }
 
 static void Op29(void)                                                 // BVS
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (regs.cc & 0x02)
-               regs.pc += word;
+       // V
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagV;
+#else
+       if (flagV)
+               regs.pc += offset;
+#endif
 }
 
 static void Op2A(void)                                                 // BPL
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // !N
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs.cc & 0x08))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagN ^ 0x01);
+#else
+       if (!flagN)
+               regs.pc += offset;
+#endif
 }
 
 static void Op2B(void)                                                 // BMI
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (regs.cc & 0x08)
-               regs.pc += word;
+       // N
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagN;
+#else
+       if (flagN)
+               regs.pc += offset;
+#endif
 }
 
 static void Op2C(void)                                                 // BGE
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // (N && V) || (!N && !V)
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
+#else
+       if ((flagN && flagV) || (!flagN && !flagV))
+               regs.pc += offset;
+#endif
 }
 
 static void Op2D(void)                                                 // BLT
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
-               regs.pc += word;
+       // (N && !V) || (!N && V)
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+       if ((flagN && !flagV) || (!flagN && flagV))
+               regs.pc += offset;
+#endif
 }
 
 static void Op2E(void)                                                 // BGT
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+       // (N && V && !Z) || (!N && !V && !Z)
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
-               regs.pc += word;
-
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
+#else
+       if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
+               regs.pc += offset;
+#endif
 }
 
 static void Op2F(void)                                                 // BLE
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-
-       if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
-               regs.pc += word;
+       // Z || (N && !V) || (!N && V)
+       int16_t offset = (int16_t)(int8_t)READ_IMM;
 
-       regs.clock += 3;
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+       if (flagZ || (flagN && !flagV) || (!flagN && flagV))
+               regs.pc += offset;
+#endif
 }
 
-static void Op30(void)  // LEAX
+static void Op1021(void)                                               // LBRN
 {
-  regs.x = DecodeIDX(regs.RdMem(regs.pc++));
-  (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  regs.clock += 4;
+       // This is basically a 4 byte NOP
+       uint16_t offset = READ_IMM16;
 }
-static void Op31(void)  // LEAY
+
+static void Op1022(void)                                               // LBHI
 {
-  regs.y = DecodeIDX(regs.RdMem(regs.pc++));
-  (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  regs.clock += 4;
+       // !C && !Z
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
+       regs.pc += offset * ((flagZ | flagC) ^ 0x01);
+#else
+       if (!(flagZ || flagC))
+               regs.pc += offset;
+#endif
 }
-static void Op32(void)  // LEAS
+
+static void Op1023(void)                                               // LBLS
 {
-  regs.s = DecodeIDX(regs.RdMem(regs.pc++));
-  (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  regs.clock += 4;
+       // C || Z
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ | flagC);
+#else
+       if (flagZ || flagC)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1024(void)                                               // LBHS/CC
+{
+       // !C
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagC ^ 0x01);
+#else
+       if (!flagC)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1025(void)                                               // LBLO/CS
+{
+       // C
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagC;
+#else
+       if (flagC)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1026(void)                                               // LBNE
+{
+       // !Z
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ ^ 0x01);
+#else
+       if (!flagZ)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1027(void)                                               // LBEQ
+{
+       // Z
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagZ;
+#else
+       if (flagZ)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1028(void)                                               // LBVC
+{
+       // !V
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagV ^ 0x01);
+#else
+       if (!flagV)
+               regs.pc += offset;
+#endif
+}
+
+static void Op1029(void)                                               // LBVS
+{
+       // V
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagV;
+#else
+       if (flagV)
+               regs.pc += offset;
+#endif
+}
+
+static void Op102A(void)                                               // LBPL
+{
+       // !N
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagN ^ 0x01);
+#else
+       if (!flagN)
+               regs.pc += offset;
+#endif
+}
+
+static void Op102B(void)                                               // LBMI
+{
+       // N
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * flagN;
+#else
+       if (flagN)
+               regs.pc += offset;
+#endif
+}
+
+static void Op102C(void)                                               // LBGE
+{
+       // (N && V) || (!N && !V)
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
+#else
+       if ((flagN && flagV) || (!flagN && !flagV))
+               regs.pc += offset;
+#endif
+}
+
+static void Op102D(void)                                               // LBLT
+{
+       // (N && !V) || (!N && V)
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+       if ((flagN && !flagV) || (!flagN && flagV))
+               regs.pc += offset;
+#endif
+}
+
+static void Op102E(void)                                               // LBGT
+{
+       // (N && V && !Z) || (!N && !V && !Z)
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
+#else
+       if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
+               regs.pc += offset;
+#endif
+}
+
+static void Op102F(void)                                               // LBLE
+{
+       // Z || (N && !V) || (!N && V)
+       uint16_t offset = READ_IMM16;
+
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+       regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+       if (flagZ || (flagN && !flagV) || (!flagN && flagV))
+               regs.pc += offset;
+#endif
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 85    0133 | BITA        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | 95    0149 | BITA        | DIRECT       |   4   |   2   | -aa0- |
+ | A5    0165 | BITA        | INDEXED      |   4   |   2   | -aa0- |
+ | B5    0181 | BITA        | EXTENDED     |   5   |   3   | -aa0- |
+ | C5    0197 | BITB        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | D5    0213 | BITB        | DIRECT       |   4   |   2   | -aa0- |
+ | E5    0229 | BITB        | INDEXED      |   4   |   2   | -aa0- |
+ | F5    0245 | BITB        | EXTENDED     |   5   |   3   | -aa0- |
+*/
+
+// BIT opcodes
+
+#define OP_BIT_HANDLER(m, acc) \
+       uint8_t result = acc & (m); \
+       SET_ZN(result); \
+       CLR_V
+
+static void Op85(void)                                                 // BITA #
+{
+       uint8_t m = READ_IMM;
+       OP_BIT_HANDLER(m, regs.a);
+}
+
+static void Op95(void)                                                 // BITA DP
+{
+       uint8_t m = READ_DP;
+       OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpA5(void)                                                 // BITA IDX
+{
+       uint8_t m = READ_IDX;
+       OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpB5(void)                                                 // BITA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_BIT_HANDLER(m, regs.a);
+}
+
+static void OpC5(void)                                                 // BITB #
+{
+       uint8_t m = READ_IMM;
+       OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpD5(void)                                                 // BITB DP
+{
+       uint8_t m = READ_DP;
+       OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpE5(void)                                                 // BITB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_BIT_HANDLER(m, regs.b);
+}
+
+static void OpF5(void)                                                 // BITB ABS
+{
+       uint8_t m = READ_ABS;
+       OP_BIT_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0F    0015 | CLR         | DIRECT       |   6   |   2   | -0100 |
+ | 4F    0079 | CLRA        | INHERENT     |   2   |   1   | -0100 |
+ | 5F    0095 | CLRB        | INHERENT     |   2   |   1   | -0100 |
+ | 6F    0111 | CLR         | INDEXED      |   6   |   2   | -0100 |
+ | 7F    0127 | CLR         | EXTENDED     |   7   |   3   | -0100 |
+*/
+
+// CLR opcodes
+
+#define OP_CLR_HANDLER(m) \
+       flagN = flagV = flagC = 0; \
+       flagZ = 1; \
+       m = 0
+
+static void Op0F(void)                                                 // CLR DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_CLR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op4F(void)                                                 // CLRA
+{
+       OP_CLR_HANDLER(regs.a);
+}
+
+static void Op5F(void)                                                 // CLRB
+{
+       OP_CLR_HANDLER(regs.b);
+}
+
+static void Op6F(void)                                                 // CLR IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_CLR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op7F(void)                                                 // CLR ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_CLR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 81    0129 | CMPA        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | 8C    0140 | CMPX        | IMMEDIATE    |   4   |   3   | -aaaa |
+ | 91    0145 | CMPA        | DIRECT       |   4   |   2   | uaaaa |
+ | 9C    0156 | CMPX        | DIRECT       |   6   |   2   | -aaaa |
+ | A1    0161 | CMPA        | INDEXED      |   4   |   2   | uaaaa |
+ | AC    0172 | CMPX        | INDEXED      |   6   |   2   | -aaaa |
+ | B1    0177 | CMPA        | EXTENDED     |   5   |   3   | uaaaa |
+ | BC    0188 | CMPX        | EXTENDED     |   7   |   3   | -aaaa |
+ | C1    0193 | CMPB        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | D1    0209 | CMPB        | DIRECT       |   4   |   2   | uaaaa |
+ | E1    0225 | CMPB        | INDEXED      |   4   |   2   | uaaaa |
+ | F1    0241 | CMPB        | EXTENDED     |   5   |   3   | uaaaa |
+ | 1083  4227 | CMPD        | IMMEDIATE    |   5   |   4   | -aaaa |
+ | 108C  4236 | CMPY        | IMMEDIATE    |   5   |   4   | -aaaa |
+ | 1093  4243 | CMPD        | DIRECT       |   7   |   3   | -aaaa |
+ | 109C  4252 | CMPY        | DIRECT       |   7   |   3   | -aaaa |
+ | 10A3  4259 | CMPD        | INDEXED      |   7   |   3   | -aaaa |
+ | 10AC  4268 | CMPY        | INDEXED      |   7   |   3   | -aaaa |
+ | 10B3  4275 | CMPD        | EXTENDED     |   8   |   4   | -aaaa |
+ | 10BC  4284 | CMPY        | EXTENDED     |   8   |   4   | -aaaa |
+ | 1183  4438 | CMPU        | IMMEDIATE    |   5   |   4   | -aaaa |
+ | 118C  4492 | CMPS        | IMMEDIATE    |   5   |   4   | -aaaa |
+ | 1193  4499 | CMPU        | DIRECT       |   7   |   3   | -aaaa |
+ | 119C  4508 | CMPS        | DIRECT       |   7   |   3   | -aaaa |
+ | 11A3  4515 | CMPU        | INDEXED      |   7   |   3   | -aaaa |
+ | 11AC  4524 | CMPS        | INDEXED      |   7   |   3   | -aaaa |
+ | 11B3  4531 | CMPU        | EXTENDED     |   8   |   4   | -aaaa |
+ | 11BC  4540 | CMPS        | EXTENDED     |   8   |   4   | -aaaa |
+*/
+
+// CMP opcodes
+
+#define OP_CMP_HANDLER(m, acc) \
+       uint16_t sum = (uint16_t)(acc) - (m); \
+       flagC = (sum >> 8) & 0x01; \
+       SET_V(m, acc, sum); \
+       SET_ZN(sum)
+
+#define OP_CMP_HANDLER16(m, acc) \
+       uint32_t sum = (uint32_t)(acc) - (m); \
+       flagC = (sum >> 16) & 0x01; \
+       SET_V16(m, acc, sum); \
+       SET_ZN16(sum)
+
+static void Op81(void)                                                 // CMPA #
+{
+       uint8_t m = READ_IMM;
+       OP_CMP_HANDLER(m, regs.a);
+}
+
+static void Op8C(void)                                                 // CMPX #
+{
+       uint16_t m = READ_IMM16;
+       OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void Op91(void)                                                 // CMPA DP
+{
+       uint8_t m = READ_DP;
+       OP_CMP_HANDLER(m, regs.a);
+}
+
+static void Op9C(void)                                                 // CMPX DP
+{
+       uint16_t m = READ_DP16;
+       OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpA1(void)                                                 // CMPA IDX
+{
+       uint8_t m = READ_IDX;
+       OP_CMP_HANDLER(m, regs.a);
+}
+
+static void OpAC(void)                                                 // CMPX IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpB1(void)                                                 // CMPA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_CMP_HANDLER(m, regs.a);
+}
+
+static void OpBC(void)                                                 // CMPX ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_CMP_HANDLER16(m, regs.x);
+}
+
+static void OpC1(void)                                                 // CMPB #
+{
+       uint8_t m = READ_IMM;
+       OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpD1(void)                                                 // CMPB DP
+{
+       uint8_t m = READ_DP;
+       OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpE1(void)                                                 // CMPB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_CMP_HANDLER(m, regs.b);
+}
+
+static void OpF1(void)                                                 // CMPB ABS
+{
+       uint8_t m = READ_ABS;
+       OP_CMP_HANDLER(m, regs.b);
+}
+
+static void Op1083(void)                                               // CMPD #
+{
+       uint16_t m = READ_IMM16;
+       OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op108C(void)                                               // CMPY #
+{
+       uint16_t m = READ_IMM16;
+       OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op1093(void)                                               // CMPD DP
+{
+       uint16_t m = READ_DP16;
+       OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op109C(void)                                               // CMPY DP
+{
+       uint16_t m = READ_DP16;
+       OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op10A3(void)                                               // CMPD IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op10AC(void)                                               // CMPY IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op10B3(void)                                               // CMPD ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
+}
+
+static void Op10BC(void)                                               // CMPY ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_CMP_HANDLER16(m, regs.y);
+}
+
+static void Op1183(void)                                               // CMPU #
+{
+       uint16_t m = READ_IMM16;
+       OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op118C(void)                                               // CMPS #
+{
+       uint16_t m = READ_IMM16;
+       OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op1193(void)                                               // CMPU DP
+{
+       uint16_t m = READ_DP16;
+       OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op119C(void)                                               // CMPS DP
+{
+       uint16_t m = READ_DP16;
+       OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op11A3(void)                                               // CMPU IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op11AC(void)                                               // CMPS IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_CMP_HANDLER16(m, regs.s);
+}
+
+static void Op11B3(void)                                               // CMPU ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_CMP_HANDLER16(m, regs.u);
+}
+
+static void Op11BC(void)                                               // CMPS ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_CMP_HANDLER16(m, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 03    0003 | COM         | DIRECT       |   6   |   2   | -aa01 |
+ | 43    0067 | COMA        | INHERENT     |   2   |   1   | -aa01 |
+ | 53    0083 | COMB        | INHERENT     |   2   |   1   | -aa01 |
+ | 63    0099 | COM         | INDEXED      |   6   |   2   | -aa01 |
+ | 73    0115 | COM         | EXTENDED     |   7   |   3   | -aa01 |
+*/
+
+// COM opcodes
+
+#define OP_COM_HANDLER(m) \
+       m = ~m; \
+       SET_ZN(m); \
+       flagC = 1; \
+       flagV = 0
+
+static void Op03(void)                                                 // COM DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_COM_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op43(void)                                                 // COMA
+{
+       OP_COM_HANDLER(regs.a);
+}
+
+static void Op53(void)                                                 // COMB
+{
+       OP_COM_HANDLER(regs.b);
+}
+
+static void Op63(void)                                                 // COM IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_COM_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op73(void)                                                 // COM ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_COM_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 13    0019 | SYNC        | INHERENT     |   2   |   1   | ----- |
+ | 3C    0060 | CWAI        | INHERENT     |  21   |   2   | ddddd |
+ | 3E    0062 | RESET*      | INHERENT     |   *   |   1   | ***** |
+ | 3F    0063 | SWI         | INHERENT     |  19   |   1   | ----- |
+ | 103F  4159 | SWI2        | INHERENT     |  20   |   2   | ----- |
+ | 113F  4415 | SWI3        | INHERENT     |  20   |   2   | ----- |
+*/
+
+static void Op13(void)                                                 // SYNC
+{
+#warning "!!! SYNC not implemented !!!"
+#if 0
+       /* SYNC stops processing instructions until an interrupt request happens. */
+       /* This doesn't require the corresponding interrupt to be enabled: if it */
+       /* is disabled, execution continues with the next instruction. */
+       m68_state->int_state |= M6809_SYNC;      /* HJB 990227 */
+       check_irq_lines(m68_state);
+       /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
+     * stop execution until the interrupt lines change. */
+       if( m68_state->int_state & M6809_SYNC )
+               if (m68_state->icount > 0) m68_state->icount = 0;
+#endif
+}
+
+static void Op3C(void)                                                 // CWAI
+{
+#warning "!!! CWAI not implemented !!!"
+#if 0
+       UINT8 t;
+       IMMBYTE(t);
+       CC &= t;
+       /*
+     * CWAI stacks the entire machine state on the hardware stack,
+     * then waits for an interrupt; when the interrupt is taken
+     * later, the state is *not* saved again after CWAI.
+     */
+       CC |= CC_E;             /* HJB 990225: save entire state */
+       PUSHWORD(pPC);
+       PUSHWORD(pU);
+       PUSHWORD(pY);
+       PUSHWORD(pX);
+       PUSHBYTE(DP);
+       PUSHBYTE(B);
+       PUSHBYTE(A);
+       PUSHBYTE(CC);
+       m68_state->int_state |= M6809_CWAI;      /* HJB 990228 */
+       check_irq_lines(m68_state);    /* HJB 990116 */
+       if( m68_state->int_state & M6809_CWAI )
+               if( m68_state->icount > 0 )
+                       m68_state->icount = 0;
+#endif
+}
+
+static void Op3E(void)                                                 // RESET
+{
+       regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
+}
+
+static void Op3F(void)                                                 // SWI
+{
+       flagE = 1;
+       regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
+       PUSHS16(regs.pc);
+       PUSHS16(regs.u);
+       PUSHS16(regs.y);
+       PUSHS16(regs.x);
+       PUSHS(regs.dp);
+       PUSHS(regs.b);
+       PUSHS(regs.a);
+       PUSHS(regs.cc);
+       flagF = flagI = 1;
+       regs.pc = RdMemW(0xFFFA);
+}
+
+static void Op103F(void)                                               // SWI2
+{
+       flagE = 1;
+       regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
+       PUSHS16(regs.pc);
+       PUSHS16(regs.u);
+       PUSHS16(regs.y);
+       PUSHS16(regs.x);
+       PUSHS(regs.dp);
+       PUSHS(regs.b);
+       PUSHS(regs.a);
+       PUSHS(regs.cc);
+       regs.pc = RdMemW(0xFFF4);
+}
+
+static void Op113F(void)                                               // SWI3
+{
+       flagE = 1;
+       regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
+       PUSHS16(regs.pc);
+       PUSHS16(regs.u);
+       PUSHS16(regs.y);
+       PUSHS16(regs.x);
+       PUSHS(regs.dp);
+       PUSHS(regs.b);
+       PUSHS(regs.a);
+       PUSHS(regs.cc);
+       regs.pc = RdMemW(0xFFF2);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 12    0018 | NOP         | INHERENT     |   2   |   1   | ----- |
+ | 19    0025 | DAA         | INHERENT     |   2   |   1   | -aa0a |
+ | 1A    0026 | ORCC        | IMMEDIATE    |   3   |   2   | ddddd |
+ | 1C    0028 | ANDCC       | IMMEDIATE    |   3   |   2   | ddddd |
+ | 1D    0029 | SEX         | INHERENT     |   2   |   1   | -aa0- |
+*/
+
+static void Op12()                                                             // NOP
+{
+}
+
+/*
+D3F8: A6 47       LDA   (7),U      CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA
+D3FA: 8B 01       ADDA  #$01       CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC
+D3FC: 19          DAA              CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD
+*/
+
+static void Op19()                                                             // DAA
+{
+       uint16_t result = (uint16_t)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_t)result;
+       SET_ZN(result);
+       CLR_V;
+       flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
+}
+
+static void Op1A()                                                             // ORCC
+{
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
+       regs.cc |= READ_IMM;
+       UNPACK_FLAGS;                                                           // & unmash 'em
+}
+
+static void Op1C()                                                             // ANDCC
+{
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
+       regs.cc &= READ_IMM;
+       UNPACK_FLAGS;                                                           // & unmash 'em
+}
+
+static void Op1D()                                                             // SEX
+{
+       regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
+       SET_ZN16((regs.a << 8) | regs.b);
+       CLR_V;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0A    0010 | DEC         | DIRECT       |   6   |   2   | -aaa- |
+ | 4A    0074 | DECA        | INHERENT     |   2   |   1   | -aaa- |
+ | 5A    0090 | DECB        | INHERENT     |   2   |   1   | -aaa- |
+ | 6A    0106 | DEC         | INDEXED      |   6   |   2   | -aaa- |
+ | 7A    0122 | DEC         | EXTENDED     |   7   |   3   | -aaa- |
+*/
+
+// DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
+
+#define OP_DEC_HANDLER(m) \
+       m--; \
+       SET_ZN(m); \
+       flagV = (m == 0x7F ? 1 : 0)
+
+static void Op0A(void)                                                 // DEC DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_DEC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op4A(void)                                                 // DECA
+{
+       OP_DEC_HANDLER(regs.a);
+}
+
+static void Op5A(void)                                                 // DECB
+{
+       OP_DEC_HANDLER(regs.b);
+}
+
+static void Op6A(void)                                                 // DEC IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_DEC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op7A(void)                                                 // DEC ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_DEC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 88    0136 | EORA        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | 98    0152 | EORA        | DIRECT       |   4   |   2   | -aa0- |
+ | A8    0168 | EORA        | INDEXED      |   4   |   2   | -aa0- |
+ | B8    0184 | EORA        | EXTENDED     |   5   |   3   | -aa0- |
+ | C8    0200 | EORB        | IMMEDIATE    |   2   |   2   | -aa0- |
+ | D8    0216 | EORB        | DIRECT       |   4   |   2   | -aa0- |
+ | E8    0232 | EORB        | INDEXED      |   4   |   2   | -aa0- |
+ | F8    0248 | EORB        | EXTENDED     |   5   |   3   | -aa0- |
+*/
+
+// EOR opcodes
+
+#define OP_EOR_HANDLER(m, acc) \
+       acc ^= (m); \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op88(void)                                                 // EORA #
+{
+       uint8_t m = READ_IMM;
+       OP_EOR_HANDLER(m, regs.a);
+}
+
+static void Op98(void)                                                 // EORA DP
+{
+       uint8_t m = READ_DP;
+       OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpA8(void)                                                 // EORA IDX
+{
+       uint8_t m = READ_IDX;
+       OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpB8(void)                                                 // EORA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_EOR_HANDLER(m, regs.a);
+}
+
+static void OpC8(void)                                                 // EORB #
+{
+       uint8_t m = READ_IMM;
+       OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpD8(void)                                                 // EORB DP
+{
+       uint8_t m = READ_DP;
+       OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpE8(void)                                                 // EORB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_EOR_HANDLER(m, regs.b);
+}
+
+static void OpF8(void)                                                 // EORB ABS
+{
+       uint8_t m = READ_ABS;
+       OP_EOR_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0C    0012 | INC         | DIRECT       |   6   |   2   | -aaa- |
+ | 4C    0076 | INCA        | INHERENT     |   2   |   1   | -aaa- |
+ | 5C    0092 | INCB        | INHERENT     |   2   |   1   | -aaa- |
+ | 6C    0108 | INC         | INDEXED      |   6   |   2   | -aaa- |
+ | 7C    0124 | INC         | EXTENDED     |   7   |   3   | -aaa- |
+*/
+
+// INC opcodes (If we went from $7F -> $80, sign overflowed.)
+
+#define OP_INC_HANDLER(m) \
+       m++; \
+       SET_ZN(m); \
+       flagV = (m == 0x80 ? 1 : 0)
+
+static void Op0C(void)         // INC DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_INC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+
+static void Op4C(void)         // INCA
+{
+       OP_INC_HANDLER(regs.a);
+}
+
+
+static void Op5C(void)         // INCB
+{
+       OP_INC_HANDLER(regs.b);
+}
+
+
+static void Op6C(void)         // INC IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_INC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+
+static void Op7C(void)         // INC ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_INC_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0E    0014 | JMP         | DIRECT       |   3   |   2   | ----- |
+ | 17    0023 | LBSR        | RELATIVE     |   9   |   3   | ----- |
+ | 39    0057 | RTS         | INHERENT     |   5   |   1   | ----- |
+ | 3B    0059 | RTI         | INHERENT     | 6/15  |   1   | ----- |
+ | 6E    0110 | JMP         | INDEXED      |   3   |   2   | ----- |
+ | 7E    0126 | JMP         | EXTENDED     |   3   |   3   | ----- |
+ | 8D    0141 | BSR         | RELATIVE     |   7   |   2   | ----- |
+ | 9D    0157 | JSR         | DIRECT       |   7   |   2   | ----- |
+ | AD    0173 | JSR         | INDEXED      |   7   |   2   | ----- |
+ | BD    0189 | JSR         | EXTENDED     |   8   |   3   | ----- |
+*/
+
+static void Op0E(void)         // JMP DP
+{
+       // This needs to be separate because of the EA_DP adding to regs.pc.
+       uint16_t m = EA_DP;
+       regs.pc = m;
+}
+
+
+static void Op17(void)         // LBSR
+{
+       uint16_t word = FetchMemW(regs.pc);
+       PUSHS16(regs.pc);
+       regs.pc += word;
 }
-static void Op33(void)  // LEAU
+
+
+static void Op39(void)         // RTS
 {
-  regs.u = DecodeIDX(regs.RdMem(regs.pc++));
-  (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  regs.clock += 4;
+       PULLS16(regs.pc);
 }
-static void Op34(void)  // PSHS
+
+
+static void Op3B(void)         // RTI
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (tmp&0x80)  { regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8); }
-  if (tmp&0x40)  { regs.WrMem(--regs.s, regs.u&0xFF);  regs.WrMem(--regs.s, regs.u>>8); }
-  if (tmp&0x20)  { regs.WrMem(--regs.s, regs.y&0xFF);  regs.WrMem(--regs.s, regs.y>>8); }
-  if (tmp&0x10)  { regs.WrMem(--regs.s, regs.x&0xFF);  regs.WrMem(--regs.s, regs.x>>8); }
-  if (tmp&0x08)  regs.WrMem(--regs.s, regs.dp);
-  if (tmp&0x04)  regs.WrMem(--regs.s, regs.b);
-  if (tmp&0x02)  regs.WrMem(--regs.s, regs.a);
-  if (tmp&0x01)  regs.WrMem(--regs.s, regs.cc);
-  regs.clock += 5;
+       PULLS(regs.cc);
+       UNPACK_FLAGS;
+
+       // If E flag set, pull all regs
+       if (flagE)
+       {
+               PULLS(regs.a);
+               PULLS(regs.b);
+               PULLS(regs.dp);
+               PULLS16(regs.x);
+               PULLS16(regs.y);
+               PULLS16(regs.u);
+               regs.clock += 9;
+       }
+
+       PULLS16(regs.pc);
 }
-static void Op35(void)  // PULS
+
+
+static void Op6E(void)         // JMP IDX
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (tmp&0x01)  regs.cc = regs.RdMem(regs.s++);
-  if (tmp&0x02)  regs.a  = regs.RdMem(regs.s++);
-  if (tmp&0x04)  regs.b  = regs.RdMem(regs.s++);
-  if (tmp&0x08)  regs.dp = regs.RdMem(regs.s++);
-  if (tmp&0x10)  regs.x  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-  if (tmp&0x20)  regs.y  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-  if (tmp&0x40)  regs.u  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-  if (tmp&0x80)  regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-  regs.clock += 5;
+       regs.pc = EA_IDX;
 }
 
-static void Op36(void)  // PSHU
+
+static void Op7E(void)         // JMP ABS
 {
-       tmp = regs.RdMem(regs.pc++);
+       regs.pc = EA_ABS;
+}
 
-       if (tmp & 0x80)  { regs.WrMem(--regs.u, regs.pc & 0xFF);  regs.WrMem(--regs.u, regs.pc >> 8); }
-       if (tmp & 0x40)  { regs.WrMem(--regs.u, regs.s & 0xFF);  regs.WrMem(--regs.u, regs.s >> 8); }
-       if (tmp & 0x20)  { regs.WrMem(--regs.u, regs.y & 0xFF);  regs.WrMem(--regs.u, regs.y >> 8); }
-       if (tmp & 0x10)  { regs.WrMem(--regs.u, regs.x & 0xFF);  regs.WrMem(--regs.u, regs.x >> 8); }
-       if (tmp & 0x08)  regs.WrMem(--regs.u, regs.dp);
-       if (tmp & 0x04)  regs.WrMem(--regs.u, regs.b);
-       if (tmp & 0x02)  regs.WrMem(--regs.u, regs.a);
-       if (tmp & 0x01)  regs.WrMem(--regs.u, regs.cc);
 
-  regs.clock += 5;
+static void Op8D(void)         // BSR
+{
+       uint16_t word = (int16_t)(int8_t)READ_IMM;
+       PUSHS16(regs.pc);
+       regs.pc += word;
 }
 
-static void Op37(void)  // PULU
+
+static void Op9D(void)         // JSR DP
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (tmp&0x01)  regs.cc = regs.RdMem(regs.u++);
-  if (tmp&0x02)  regs.a  = regs.RdMem(regs.u++);
-  if (tmp&0x04)  regs.b  = regs.RdMem(regs.u++);
-  if (tmp&0x08)  regs.dp = regs.RdMem(regs.u++);
-  if (tmp&0x10)  regs.x  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
-  if (tmp&0x20)  regs.y  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
-  if (tmp&0x40)  regs.s  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
-  if (tmp&0x80)  regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
-  regs.clock += 5;
+       uint16_t word = EA_DP;
+       PUSHS16(regs.pc);
+       regs.pc = word;
 }
-static void Op39(void)  // RTS
+
+
+static void OpAD(void)         // JSR IDX
 {
-  regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-  regs.clock += 5;
+       uint16_t word = EA_IDX;
+       PUSHS16(regs.pc);
+       regs.pc = word;
 }
-static void Op3A(void)  // ABX
+
+
+static void OpBD(void)         // JSR ABS
 {
-  regs.x += regs.b;
-  regs.clock += 3;
+       uint16_t word = EA_ABS;
+       PUSHS16(regs.pc);
+       regs.pc = word;
 }
-static void Op3B(void)  // RTI
+
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 1E    0030 | EXG         | INHERENT     |   8   |   2   | ccccc |
+ | 1F    0031 | TFR         | INHERENT     |   7   |   2   | ccccc |
+*/
+
+static void Op1E(void)                                                 // EXG
 {
-  regs.cc = regs.RdMem(regs.s++);
-  if (regs.cc&0x80)      // If E flag set, pull all regs
-  {
-    regs.a = regs.RdMem(regs.s++);  regs.b = regs.RdMem(regs.s++);  regs.dp = regs.RdMem(regs.s++);
-    regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-    regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-    regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-    regs.clock += 15;
-  }
-  else
-  {
-    regs.clock += 6;
-  }
-  regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
-}
-static void Op3C(void)  // CWAI
-{
-  regs.cc &= regs.RdMem(regs.pc++);  regs.cc |= 0x80;
-  regs.clock += 1000000;             // Force interrupt
-}
-static void Op3D(void)  // MUL
-{
-  addr = regs.a * regs.b;  regs.a = addr>>8;  regs.b = addr&0xFF;
-  (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
-  (regs.b&0x80   ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
-  regs.clock += 11;
-}
-static void Op3E(void)  // RESET
-{
-}
-static void Op3F(void)  // SWI
-{
-}
-static void Op40(void)  // NEGA
-{
-  regs.a = 256 - regs.a;
-  (regs.a > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
-  (regs.a == 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
-  regs.clock += 2;
-}
-static void Op43(void)  // COMA
-{
-  regs.a ^= 0xFF;
-  regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
-  (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.clock += 2;
-}
-static void Op44(void)  // LSRA
-{
-  (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
-  regs.clock += 2;
-}
-static void Op46(void)  // RORA
-{
-  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
-  regs.clock += 2;
-}
-static void Op47(void)  // ASRA
-{
-  (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
-  regs.clock += 2;
-}
-static void Op48(void)  // LSLA  [Keep checking from here...]
-{
-  (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
-  regs.clock += 2;
-}
-static void Op49(void)  // ROLA
-{
-  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
-  regs.clock += 2;
-}
-static void Op4A(void)  // DECA
-{
-  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
-  regs.clock += 2;
-}
-static void Op4C(void)  // INCA
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op4D(void)  // TSTA
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op4F(void)  // CLRA
-{
-  regs.a = 0;
-  regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
-  regs.clock += 2;
-}
-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
-        regs.clock += 2;
-      }
-static void Op53(void)  // COMB
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op54(void)  // LSRB
-      {
-        (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
-        regs.clock += 2;
-      }
-static void Op56(void)  // RORB
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op57(void)  // ASRB
-      {
-        (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
-        regs.clock += 2;
-      }
-static void Op58(void)  // LSLB
-      {
-        (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
-        regs.clock += 2;
-      }
-static void Op59(void)  // ROLB
-{
-  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
-  regs.clock += 2;
-}
-static void Op5A(void)  // DECB
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op5C(void)  // INCB
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op5D(void)  // TSTB
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op5F(void)  // CLRB
-      {
-        regs.b = 0;
-        regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
-        regs.clock += 2;
-      }
-static void Op60(void)  // NEG IDX
-      {
-        addr = DecodeIDX(regs.RdMem(regs.pc++));
-        tmp = regs.RdMem(addr);  uint8_t 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
-        regs.clock += 6;
-      }
-static void Op63(void)  // COM IDX
-      {
-        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
-        regs.clock += 6;
-      }
-static void Op64(void)  // LSR IDX
-      {
-        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
-        regs.clock += 6;
-      }
-static void Op66(void)  // ROR IDX
-      {
-        addr = DecodeIDX(regs.RdMem(regs.pc++));
-        tmp = regs.RdMem(addr);  uint8_t 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
-        regs.clock += 6;
-      }
-static void Op67(void)  // ASR IDX
-      {
-        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
-        regs.clock += 6;
-      }
-static void Op68(void)  // LSL IDX
-      {
-        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
-        regs.clock += 6;
-      }
-static void Op69(void)  // ROL IDX
-{
-  uint8_t 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
-  regs.clock += 6;
-}
-static void Op6A(void)  // DEC IDX
-      {
-  uint8_t tmp;  uint16_t 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
-        regs.clock += 6;
-      }
-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
-        regs.clock += 6;
-      }
-static void Op6D(void)  // TST IDX
-      {
-        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
-        regs.clock += 6;
-      }
-static void Op6E(void)  // JMP IDX
-{
-  regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.clock += 3;
-}
-static void Op6F(void)  // CLR IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(addr, 0);
-  regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
-  regs.clock += 6;
-}
-static void Op70(void)  // NEG ABS
-      {
-        addr = FetchW();
-        tmp = regs.RdMem(addr);  uint8_t 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
-        regs.clock += 7;
-      }
-static void Op73(void)  // COM ABS
-      {
-        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
-        regs.clock += 7;
-      }
-static void Op74(void)  // LSR ABS
-      {
-        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
-        regs.clock += 7;
-      }
-static void Op76(void)  // ROR ABS
-      {
-  uint8_t tmp;  uint16_t addr;
-        addr = FetchW();
-        tmp = regs.RdMem(addr);  uint8_t 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
-        regs.clock += 7;
-      }
-static void Op77(void)  // ASR ABS
-      {
-  uint8_t tmp;  uint16_t 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
-        regs.clock += 7;
-      }
-static void Op78(void)  // LSL ABS
-      {
-  uint8_t tmp;  uint16_t 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
-        regs.clock += 7;
-      }
-static void Op79(void)  // ROL ABS
-{
-  uint8_t 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
-  regs.clock += 7;
-}
-static void Op7A(void)  // DEC ABS
-      {
-  uint8_t tmp;  uint16_t 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
-        regs.clock += 7;
-      }
-static void Op7C(void)  // INC ABS
-      {
-  uint8_t tmp;  uint16_t addr;
-        addr = FetchW();
-        tmp = regs.RdMem(addr) + 1;
-        regs.WrMem(addr, tmp);
-        (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
-        (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
-        (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
-        regs.clock += 7;
-      }
-
-static void Op7D(void)  // TST ABS
-{
-       uint8_t 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.clock += 7;
-}
-
-static void Op7E(void)  // JMP ABS
-{
-  regs.pc = FetchW();
-  regs.clock += 3;
-}
-static void Op7F(void)  // CLR ABS
-      {
-        regs.WrMem(FetchW(), 0);
-        regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
-        regs.clock += 7;
-      }
-static void Op80(void)  // SUBA #
-{
-  uint8_t tmp = regs.RdMem(regs.pc++);  uint8_t 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
-  regs.clock += 2;
-}
-static void Op81(void)  // CMPA #
-{
-  tmp = regs.RdMem(regs.pc++);
-  uint8_t 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
-  regs.clock += 2;
-}
-static void Op82(void)  // SBCA #
-{
-  tmp = regs.RdMem(regs.pc++);  uint8_t 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
-  regs.clock += 2;
-}
-static void Op83(void)  // SUBD #
-{
-  addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
-  dr -= addr;
-  (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 4;
+       // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
+
+       uint8_t m = READ_IMM;
+       uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
+       uint16_t acc1 = ReadEXG(reg1);
+       uint16_t acc2 = ReadEXG(reg2);
+
+       // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
+       if (((m >> 4) ^ m) & 0x08)
+               acc1 = acc2 = 0xFF;
+
+       WriteEXG(reg1, acc2);
+       WriteEXG(reg2, acc1);
 }
-static void Op84(void)  // ANDA #
-      {
-        regs.a &= regs.RdMem(regs.pc++);
-        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
-        regs.clock += 2;
-      }
-static void Op85(void)  // BITA #
-      {
-        tmp = regs.a & 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
-        regs.clock += 2;
-      }
-static void Op86(void)  // LDA #
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op88(void)  // EORA #
-      {
-        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
-        regs.clock += 2;
-      }
-static void Op89(void)  // ADCA #
-{
-  tmp = regs.RdMem(regs.pc++);
-  addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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
-  regs.clock += 2;
-}
-static void Op8A(void)  // ORA #
-      {
-        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
-        regs.clock += 2;
-      }
-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)&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);  // Set Zero flag
-  (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
-  regs.clock += 2;
+
+static void Op1F(void)                                                 // TFR
+{
+       uint8_t m = READ_IMM;
+       uint16_t acc = ReadEXG(m >> 4);
+
+       // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
+       if (((m >> 4) ^ m) & 0x08)
+               acc = 0xFF;
+
+       WriteEXG(m & 0x0F, acc);
 }
-static void Op8C(void)  // CMPX #
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 86    0134 | LDA         | IMMEDIATE    |   2   |   2   | -aa0- |
+ | 8E    0142 | LDX         | IMMEDIATE    |   3   |   3   | -aa0- |
+ | 96    0150 | LDA         | DIRECT       |   4   |   2   | -aa0- |
+ | 9E    0158 | LDX         | DIRECT       |   5   |   2   | -aa0- |
+ | A6    0166 | LDA         | INDEXED      |   4   |   2   | -aa0- |
+ | AE    0174 | LDX         | INDEXED      |   5   |   2   | -aa0- |
+ | B6    0182 | LDA         | EXTENDED     |   5   |   3   | -aa0- |
+ | BE    0190 | LDX         | EXTENDED     |   6   |   3   | -aa0- |
+ | C6    0198 | LDB         | IMMEDIATE    |   2   |   2   | -aa0- |
+ | CC    0204 | LDD         | IMMEDIATE    |   3   |   3   | -aa0- |
+ | CE    0206 | LDU         | IMMEDIATE    |   3   |   3   | -aa0- |
+ | D6    0214 | LDB         | DIRECT       |   4   |   2   | -aa0- |
+ | DC    0220 | LDD         | DIRECT       |   5   |   2   | -aa0- |
+ | DE    0222 | LDU         | DIRECT       |   5   |   2   | -aa0- |
+ | E6    0230 | LDB         | INDEXED      |   4   |   2   | -aa0- |
+ | EC    0236 | LDD         | INDEXED      |   5   |   2   | -aa0- |
+ | EE    0238 | LDU         | INDEXED      |   5   |   2   | -aa0- |
+ | F6    0246 | LDB         | EXTENDED     |   5   |   3   | -aa0- |
+ | FC    0252 | LDD         | EXTENDED     |   6   |   3   | -aa0- |
+ | FE    0254 | LDU         | EXTENDED     |   6   |   3   | -aa0- |
+ | 108E  4238 | LDY         | IMMEDIATE    |   4   |   4   | -aa0- |
+ | 109E  4254 | LDY         | DIRECT       |   6   |   3   | -aa0- |
+ | 10AE  4270 | LDY         | INDEXED      |   6   |   3   | -aa0- |
+ | 10BE  4286 | LDY         | EXTENDED     |   7   |   4   | -aa0- |
+ | 10CE  4302 | LDS         | IMMEDIATE    |   4   |   4   | -aa0- |
+ | 10DE  4318 | LDS         | DIRECT       |   6   |   3   | -aa0- |
+ | 10EE  4334 | LDS         | INDEXED      |   6   |   3   | -aa0- |
+ | 10FE  4350 | LDS         | EXTENDED     |   7   |   4   | -aa0- |
+*/
+
+// LDA opcodes
+
+#define OP_LDA_HANDLER(m, acc) \
+       acc = m; \
+       CLR_V; \
+       SET_ZN(acc)
+
+#define OP_LDA_HANDLER16(m, acc) \
+       acc = m; \
+       CLR_V; \
+       SET_ZN16(acc)
+
+#define OP_LDA_HANDLER16D(m) \
+       regs.a = (m >> 8); \
+       regs.b = m & 0xFF; \
+       CLR_V; \
+       SET_ZN16(m)
+
+static void Op86(void)                                                 // LDA #
 {
-        addr = FetchW();
-        uint16_t 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
-        regs.clock += 4;
+       uint8_t m = READ_IMM;
+       OP_LDA_HANDLER(m, regs.a);
 }
 
-static void Op8D(void)                                                 // Bregs.s
+static void Op8E(void)                                                 // LDX #
 {
-       uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
-       regs.WrMem(--regs.s, regs.pc & 0xFF);
-       regs.WrMem(--regs.s, regs.pc >> 8);
-       regs.pc += word;
+       uint16_t m = READ_IMM16;
+       OP_LDA_HANDLER16(m, regs.x);
+}
 
-       regs.clock += 7;
-}
-
-static void Op8E(void)  // LDX #
-      {
-        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
-        regs.clock += 3;
-      }
-static void Op90(void)  // SUBA DP
-      {
-        tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t 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
-        regs.clock += 4;
-      }
-static void Op91(void)  // CMPA DP
-      {
-        tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-        uint8_t 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
-        regs.clock += 4;
-      }
-static void Op92(void)  // SBCA DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t 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
-  regs.clock += 4;
+static void Op96(void)                                                 // LDA DP
+{
+       uint8_t m = READ_DP;
+       OP_LDA_HANDLER(m, regs.a);
 }
-static void Op93(void)  // SUBD DP
+
+static void Op9E(void)                                                 // LDX DP
 {
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  dr -= adr2;
-  (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 6;
+       uint16_t m = READ_DP16;
+       OP_LDA_HANDLER16(m, regs.x);
 }
-static void Op94(void)  // ANDA DP
+
+static void OpA6(void)                                                 // LDA IDX
 {
-  regs.a &= regs.RdMem((regs.dp<<8)|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
-  regs.clock += 4;
+       uint8_t m = READ_IDX;
+       OP_LDA_HANDLER(m, regs.a);
 }
-static void Op95(void)  // BITA DP
-      {
-        tmp = regs.a & regs.RdMem((regs.dp<<8)|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
-        regs.clock += 4;
-      }
-static void Op96(void)  // LDA DP
-{
-  regs.a = regs.RdMem((regs.dp<<8)|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
-  regs.clock += 4;
+
+static void OpAE(void)                                                 // LDX IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_LDA_HANDLER16(m, regs.x);
 }
-static void Op97(void)  // STA DP
-      {
-        regs.WrMem((regs.dp<<8)|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.clock += 4;
-      }
-static void Op98(void)  // EORA DP
-      {
-        regs.a ^= regs.RdMem((regs.dp<<8)|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.clock += 4;
-      }
-static void Op99(void)  // ADCA DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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
-  regs.clock += 4;
+
+static void OpB6(void)                                                 // LDA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_LDA_HANDLER(m, regs.a);
 }
-static void Op9A(void)  // ORA DP
-      {
-        regs.a |= regs.RdMem((regs.dp<<8)|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.clock += 4;
-      }
-static void Op9B(void)  // ADDA DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  addr = (uint16_t)regs.a + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((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); // 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
-  regs.clock += 4;
+
+static void OpBE(void)                                                 // LDX ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_LDA_HANDLER16(m, regs.x);
 }
-static void Op9C(void)  // CMPX DP
-      {
-        addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-        uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-        uint16_t 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.clock += 6;
-      }
-static void Op9D(void)  // JSR DP
-      {
-        addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
-        regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
-        regs.pc = addr;      // JSR to DP location...
-        regs.clock += 7;
-      }
-static void Op9E(void)  // LDX DP
-      {
-        addr = (regs.dp<<8) | 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
-        regs.clock += 5;
-      }
-static void Op9F(void)  // STX DP
-      {
-        addr = (regs.dp<<8) | 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
-        regs.clock += 5;
-      }
-static void OpA0(void)  // SUBA IDX
-      {
-        tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t 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
-        regs.clock += 4;
-      }
-static void OpA1(void)  // CMPA IDX
-      {
-        tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-        uint8_t 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
-        regs.clock += 4;
-      }
-static void OpA2(void)  // SBCA IDX
-{
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t 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
-  regs.clock += 4;
+
+static void OpC6(void)                                                 // LDB #
+{
+       uint8_t m = READ_IMM;
+       OP_LDA_HANDLER(m, regs.b);
 }
-static void OpA3(void)  // SUBD IDX
+
+static void OpCC(void)                                                 // LDD #
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  dr -= adr2;
-  (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 6;
-}
-static void OpA4(void)  // ANDA IDX
-      {
-        regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-        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
-        regs.clock += 4;
-      }
-static void OpA5(void)  // BITA IDX
-      {
-        tmp = regs.a & 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
-        regs.clock += 4;
-      }
-static void OpA6(void)  // LDA IDX
-{
-  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
-  regs.clock += 4;
+       uint16_t m = READ_IMM16;
+       OP_LDA_HANDLER16D(m);
+}
+
+static void OpCE(void)                                                 // LDU #
+{
+       uint16_t m = READ_IMM16;
+       OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpD6(void)                                                 // LDB DP
+{
+       uint8_t m = READ_DP;
+       OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpDC(void)                                                 // LDD DP
+{
+       uint16_t m = READ_DP16;
+       OP_LDA_HANDLER16D(m);
+}
+
+static void OpDE(void)                                                 // LDU DP
+{
+       uint16_t m = READ_DP16;
+       OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpE6(void)                                                 // LDB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpEC(void)                                                 // LDD IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_LDA_HANDLER16D(m);
+}
+
+static void OpEE(void)                                                 // LDU IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void OpF6(void)                                                 // LDB ABS
+{
+       uint8_t m = READ_ABS;
+       OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpFC(void)                                                 // LDD ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_LDA_HANDLER16D(m);
+}
+
+static void OpFE(void)                                                 // LDU ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_LDA_HANDLER16(m, regs.u);
+}
+
+static void Op108E(void)                                               // LDY #
+{
+       uint16_t m = READ_IMM16;
+       OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op109E(void)                                               // LDY DP
+{
+       uint16_t m = READ_DP16;
+       OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10AE(void)                                               // LDY IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10BE(void)                                               // LDY ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_LDA_HANDLER16(m, regs.y);
+}
+
+static void Op10CE(void)                                               // LDS #
+{
+       uint16_t m = READ_IMM16;
+       OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10DE(void)                                               // LDS DP
+{
+       uint16_t m = READ_DP16;
+       OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10EE(void)                                               // LDS IDX
+{
+       uint16_t m = READ_IDX16;
+       OP_LDA_HANDLER16(m, regs.s);
+}
+
+static void Op10FE(void)                                               // LDS ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_LDA_HANDLER16(m, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 30    0048 | LEAX        | INDEXED      |   4   |   2   | --a-- |
+ | 31    0049 | LEAY        | INDEXED      |   4   |   2   | --a-- |
+ | 32    0050 | LEAS        | INDEXED      |   4   |   2   | ----- |
+ | 33    0051 | LEAU        | INDEXED      |   4   |   2   | ----- |
+*/
+
+static void Op30(void)                                                 // LEAX
+{
+       regs.x = EA_IDX;
+       SET_Z(regs.x);
+}
+
+static void Op31(void)                                                 // LEAY
+{
+       regs.y = EA_IDX;
+       SET_Z(regs.y);
+}
+
+static void Op32(void)                                                 // LEAS
+{
+       regs.s = EA_IDX;
+}
+
+static void Op33(void)                                                 // LEAU
+{
+       regs.u = EA_IDX;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 04    0004 | LSR         | DIRECT       |   6   |   2   | -0a-s |
+ | 44    0068 | LSRA        | INHERENT     |   2   |   1   | -0a-s |
+ | 54    0084 | LSRB        | INHERENT     |   2   |   1   | -0a-s |
+ | 64    0100 | LSR         | INDEXED      |   6   |   2   | -0a-s |
+ | 74    0116 | LSR         | EXTENDED     |   7   |   3   | -0a-s |
+*/
+
+// LSR opcodes
+
+#define OP_LSR_HANDLER(m) \
+       flagC = m & 0x01; \
+       m >>= 1; \
+       SET_ZN(m)
+
+static void Op04(void)                                                 // LSR DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_LSR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op44(void)                                                 // LSRA
+{
+       OP_LSR_HANDLER(regs.a);
+}
+
+static void Op54(void)                                                 // LSRB
+{
+       OP_LSR_HANDLER(regs.b);
+}
+
+static void Op64(void)                                                 // LSR IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_LSR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op74(void)                                                 // LSR ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_LSR_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 3D    0061 | MUL         | INHERENT     |  11   |   1   | --a-a |
+*/
+
+static void Op3D(void)                                                 // MUL
+{
+       uint16_t prod = regs.a * regs.b;
+       regs.a = prod >> 8;
+       regs.b = prod & 0xFF;
+       SET_Z(prod);
+//     flagC = (prod & 0x0080 ? 1 : 0);
+       flagC = (prod >> 7) & 0x01;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 00    0000 | NEG         | DIRECT       |   6   |   2   | uaaaa |
+ | 40    0064 | NEGA        | INHERENT     |   2   |   1   | uaaaa |
+ | 50    0080 | NEGB        | INHERENT     |   2   |   1   | uaaaa |
+ | 60    0096 | NEG         | INDEXED      |   6   |   2   | uaaaa |
+ | 70    0112 | NEG         | EXTENDED     |   7   |   3   | uaaaa |
+*/
+
+// NEG opcodes
+
+#define OP_NEG_HANDLER(m) \
+       uint8_t res = -m; \
+       SET_ZN(res); \
+       SET_V(0, m, res); \
+       flagC = (res >= 0x80 ? 1 : 0); \
+       m = res
+
+/*
+       UINT16 r,t;
+       DIRBYTE(t);
+       r = -t;
+       CLR_NZVC;
+       SET_FLAGS8(0,t,r);
+       WM(EAD,r);
+#define SET_FLAGS8(a,b,r)      {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
+#define SET_C8(a)              CC|=((a&0x100)>>8)
+*/
+static void Op00(void)                                                 // NEG DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_NEG_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op40(void)                                                 // NEGA
+{
+       OP_NEG_HANDLER(regs.a);
+}
+
+static void Op50(void)                                                 // NEGB
+{
+       OP_NEG_HANDLER(regs.b);
+}
+
+static void Op60(void)                                                 // NEG IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_NEG_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op70(void)                                                 // NEG ABS
+{
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_NEG_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 8A    0138 | ORA         | IMMEDIATE    |   2   |   2   | -aa0- |
+ | 9A    0154 | ORA         | DIRECT       |   4   |   2   | -aa0- |
+ | AA    0170 | ORA         | INDEXED      |   4   |   2   | -aa0- |
+ | BA    0186 | ORA         | EXTENDED     |   5   |   3   | -aa0- |
+ | CA    0202 | ORB         | IMMEDIATE    |   2   |   2   | -aa0- |
+ | DA    0218 | ORB         | DIRECT       |   4   |   2   | -aa0- |
+ | EA    0234 | ORB         | INDEXED      |   4   |   2   | -aa0- |
+ | FA    0250 | ORB         | EXTENDED     |   5   |   3   | -aa0- |
+*/
+
+// ORA opcodes
+
+#define OP_OR_HANDLER(m, acc) \
+       acc |= (m); \
+       SET_ZN(acc); \
+       CLR_V
+
+static void Op8A(void)                                                 // ORA #
+{
+       uint8_t m = READ_IMM;
+       OP_OR_HANDLER(m, regs.a);
+}
+
+static void Op9A(void)                                                 // ORA DP
+{
+       uint8_t m = READ_DP;
+       OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpAA(void)                                                 // ORA IDX
+{
+       uint8_t m = READ_IDX;
+       OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpBA(void)                                                 // ORA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_OR_HANDLER(m, regs.a);
+}
+
+static void OpCA(void)                                                 // ORB #
+{
+       uint8_t m = READ_IMM;
+       OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpDA(void)                                                 // ORB DP
+{
+       uint8_t m = READ_DP;
+       OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpEA(void)                                                 // ORB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_OR_HANDLER(m, regs.b);
+}
+
+static void OpFA(void)                                                 // ORB ABS
+{
+       uint8_t m = READ_ABS;
+       OP_OR_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 34    0052 | PSHS        | INHERENT     |   5   |   2   | ----- |
+ | 35    0053 | PULS        | INHERENT     |   5   |   2   | ccccc |
+ | 36    0054 | PSHU        | INHERENT     |   5   |   2   | ----- |
+ | 37    0055 | PULU        | INHERENT     |   5   |   2   | ccccc |
+*/
+
+static void Op34(void)                                                 // PSHS
+{
+       uint8_t m = READ_IMM;
+
+       if (m & 0x80)
+               PUSHS16(regs.pc);
+       if (m & 0x40)
+               PUSHS16(regs.u);
+       if (m & 0x20)
+               PUSHS16(regs.y);
+       if (m & 0x10)
+               PUSHS16(regs.x);
+       if (m & 0x08)
+               PUSHS(regs.dp);
+       if (m & 0x04)
+               PUSHS(regs.b);
+       if (m & 0x02)
+               PUSHS(regs.a);
+       if (m & 0x01)
+       {
+               regs.cc = PACK_FLAGS;
+               PUSHS(regs.cc);
+       }
+
+       // Count bits in each nybble to come up with correct cycle counts...
+       uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+       regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
+}
+
+static void Op35(void)                                                 // PULS
+{
+       uint8_t m = READ_IMM;
+
+       if (m & 0x01)
+       {
+               PULLS(regs.cc);
+               UNPACK_FLAGS;
+       }
+       if (m & 0x02)
+               PULLS(regs.a);
+       if (m & 0x04)
+               PULLS(regs.b);
+       if (m & 0x08)
+               PULLS(regs.dp);
+       if (m & 0x10)
+               PULLS16(regs.x);
+       if (m & 0x20)
+               PULLS16(regs.y);
+       if (m & 0x40)
+               PULLS16(regs.u);
+       if (m & 0x80)
+               PULLS16(regs.pc);
+
+       // Count bits in each nybble to come up with correct cycle counts...
+       uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+       regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
+}
+
+static void Op36(void)                                                 // PHSU
+{
+       uint8_t m = READ_IMM;
+
+       if (m & 0x80)
+               PUSHU16(regs.pc);
+       if (m & 0x40)
+               PUSHU16(regs.s);
+       if (m & 0x20)
+               PUSHU16(regs.y);
+       if (m & 0x10)
+               PUSHU16(regs.x);
+       if (m & 0x08)
+               PUSHU(regs.dp);
+       if (m & 0x04)
+               PUSHU(regs.b);
+       if (m & 0x02)
+               PUSHU(regs.a);
+       if (m & 0x01)
+       {
+               regs.cc = PACK_FLAGS;
+               PUSHU(regs.cc);
+       }
+
+       // Count bits in each nybble to come up with correct cycle counts...
+       uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+       regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
+}
+
+static void Op37(void)                                                 // PULU
+{
+       uint8_t m = READ_IMM;
+
+       if (m & 0x01)
+       {
+               PULLU(regs.cc);
+               UNPACK_FLAGS;
+       }
+       if (m & 0x02)
+               PULLU(regs.a);
+       if (m & 0x04)
+               PULLU(regs.b);
+       if (m & 0x08)
+               PULLU(regs.dp);
+       if (m & 0x10)
+               PULLU16(regs.x);
+       if (m & 0x20)
+               PULLU16(regs.y);
+       if (m & 0x40)
+               PULLU16(regs.s);
+       if (m & 0x80)
+               PULLU16(regs.pc);
+
+       // Count bits in each nybble to come up with correct cycle counts...
+       uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+       regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 09    0009 | ROL         | DIRECT       |   6   |   2   | -aaas |
+ | 49    0073 | ROLA        | INHERENT     |   2   |   1   | -aaas |
+ | 59    0089 | ROLB        | INHERENT     |   2   |   1   | -aaas |
+ | 69    0105 | ROL         | INDEXED      |   6   |   2   | -aaas |
+ | 79    0121 | ROL         | EXTENDED     |   7   |   3   | -aaas |
+*/
+
+// ROL opcodes
+
+#define OP_ROL_HANDLER(m) \
+       uint8_t res = (m << 1) | flagC; \
+       SET_ZN(res); \
+       SET_V(m, m, res); \
+       flagC = (m >> 7) & 0x01; \
+       m = res
+
+/*
+       UINT16 t,r;
+       DIRBYTE(t);
+       r = (CC & CC_C) | (t << 1);
+       CLR_NZVC;
+       SET_FLAGS8(t,t,r);
+       WM(EAD,r);
+*/
+static void Op09(void)                                                 // ROL DP
+{
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_ROL_HANDLER(m);
+       WRITE_BACK(m);
+}
+
+static void Op49(void)                                                 // ROLA
+{
+       OP_ROL_HANDLER(regs.a);
 }
-static void OpA7(void)  // STA IDX
+
+static void Op59(void)                                                 // ROLB
 {
-  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
-  regs.clock += 4;
+       OP_ROL_HANDLER(regs.b);
 }
-static void OpA8(void)  // EORA IDX
-      {
-        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
-        regs.clock += 4;
-      }
-static void OpA9(void)  // ADCA IDX
-{
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((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); // 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
-  regs.clock += 4;
+
+static void Op69(void)                                                 // ROL IDX
+{
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_ROL_HANDLER(m);
+       WRITE_BACK(m);
 }
-static void OpAA(void)  // ORA IDX
+
+static void Op79(void)                                                 // ROL ABS
 {
-  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
-  regs.clock += 4;
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_ROL_HANDLER(m);
+       WRITE_BACK(m);
 }
-static void OpAB(void)  // ADDA IDX
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 06    0006 | ROR         | DIRECT       |   6   |   2   | -aa-s |
+ | 46    0070 | RORA        | INHERENT     |   2   |   1   | -aa-s |
+ | 56    0086 | RORB        | INHERENT     |   2   |   1   | -aa-s |
+ | 66    0102 | ROR         | INDEXED      |   6   |   2   | -aa-s |
+ | 76    0118 | ROR         | EXTENDED     |   7   |   3   | -aa-s |
+*/
+
+// ROR opcodes
+
+#define OP_ROR_HANDLER(m) \
+       uint8_t res = (flagC << 7) | (m >> 1); \
+       SET_ZN(res); \
+       SET_V(m, m, res); \
+       flagC = m & 0x01; \
+       m = res
+
+static void Op06(void)                                                 // ROR DP
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16_t)regs.a + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((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); // 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
-  regs.clock += 4;
+       uint8_t m;
+       READ_DP_WB(m);
+       OP_ROR_HANDLER(m);
+       WRITE_BACK(m);
 }
-static void OpAC(void)  // CMPX IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  uint16_t 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.clock += 6;
-}
-static void OpAD(void)  // JSR IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
-  regs.pc = addr;                               // Jregs.s directly to IDX ptr
-  regs.clock += 7;
-}
-static void OpAE(void)  // LDX IDX
-{
-  addr = DecodeIDX(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
-  regs.clock += 5;
-}
-static void OpAF(void)  // STX IDX
-{
-  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
-  regs.clock += 5;
-}
-static void OpB0(void)  // SUBA ABS
-      {
-        tmp = regs.RdMem(FetchW());  uint8_t 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
-        regs.clock += 5;
-      }
-static void OpB1(void)  // CMPA ABS
-      {
-        tmp = regs.RdMem(FetchW());
-        uint8_t 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
-        regs.clock += 5;
-      }
-static void OpB2(void)  // SBCA ABS
-{
-  tmp = regs.RdMem(FetchW());  uint8_t 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
-  regs.clock += 5;
-}
-static void OpB3(void)  // SUBD ABS
-{
-  addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  dr -= adr2;
-  (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 7;
+
+static void Op46(void)                                                 // RORA
+{
+       OP_ROR_HANDLER(regs.a);
 }
-static void OpB4(void)  // ANDA ABS
+
+static void Op56(void)                                                 // RORB
 {
-  regs.a &= regs.RdMem(FetchW());
-  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
-  regs.clock += 5;
+       OP_ROR_HANDLER(regs.b);
 }
-static void OpB5(void)  // BITA ABS
+
+static void Op66(void)                                                 // ROR IDX
 {
-  tmp = regs.a & 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.clock += 5;
+       uint8_t m;
+       READ_IDX_WB(m);
+       OP_ROR_HANDLER(m);
+       WRITE_BACK(m);
 }
-static void OpB6(void)  // LDA ABS
+
+static void Op76(void)                                                 // ROR ABS
 {
-  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.clock += 5;
+       uint8_t m;
+       READ_ABS_WB(m);
+       OP_ROR_HANDLER(m);
+       WRITE_BACK(m);
 }
-static void OpB7(void)  // STA ABS
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 82    0130 | SBCA        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | 92    0146 | SBCA        | DIRECT       |   4   |   2   | uaaaa |
+ | A2    0162 | SBCA        | INDEXED      |   4   |   2   | uaaaa |
+ | B2    0178 | SBCA        | EXTENDED     |   5   |   3   | uaaaa |
+ | C2    0194 | SBCB        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | D2    0210 | SBCB        | DIRECT       |   4   |   2   | uaaaa |
+ | E2    0226 | SBCB        | INDEXED      |   4   |   2   | uaaaa |
+ | F2    0242 | SBCB        | EXTENDED     |   5   |   3   | uaaaa |
+*/
+
+// SBC opcodes
+
+#define OP_SBC_HANDLER(m, acc) \
+       uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
+       flagC = (sum >> 8) & 0x01; \
+       SET_V(m, acc, sum); \
+       acc = (uint8_t)sum; \
+       SET_ZN(acc)
+
+static void Op82(void)                                                 // SBCA #
 {
-  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
-  regs.clock += 5;
+       uint8_t m = READ_IMM;
+       OP_SBC_HANDLER(m, regs.a);
 }
-static void OpB8(void)  // EORA ABS
+
+static void Op92(void)                                                 // SBCA DP
 {
-  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.clock += 5;
+       uint8_t m = READ_DP;
+       OP_SBC_HANDLER(m, regs.a);
 }
-static void OpB9(void)  // ADCA ABS
+
+static void OpA2(void)                                                 // SBCA IDX
 {
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((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;                              // 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
-  regs.clock += 5;
+       uint8_t m = READ_IDX;
+       OP_SBC_HANDLER(m, regs.a);
 }
-static void OpBA(void)  // ORA ABS
+
+static void OpB2(void)                                                 // SBCA ABS
 {
-  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.clock += 5;
+       uint8_t m = READ_ABS;
+       OP_SBC_HANDLER(m, regs.a);
 }
-static void OpBB(void)  // ADDA ABS
+
+static void OpC2(void)                                                 // SBCB #
 {
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16_t)regs.a + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((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); // 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
-  regs.clock += 5;
+       uint8_t m = READ_IMM;
+       OP_SBC_HANDLER(m, regs.b);
 }
-static void OpBC(void)  // CMPX ABS
+
+static void OpD2(void)                                                 // SBCB DP
 {
-  addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  uint16_t 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.clock += 7;
+       uint8_t m = READ_DP;
+       OP_SBC_HANDLER(m, regs.b);
 }
-static void OpBD(void)  // JSR ABS
+
+static void OpE2(void)                                                 // SBCB IDX
 {
-  addr = FetchW();
-  regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
-  regs.pc = addr;                          // Go to absolute address (Not indir)
-  regs.clock += 8;
+       uint8_t m = READ_IDX;
+       OP_SBC_HANDLER(m, regs.b);
 }
 
-static void OpBE(void)                                                                 // LDX ABS
+static void OpF2(void)                                                 // SBCB ABS
 {
-//     addr = FetchW();
-//     regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-       regs.x = RdMemW(FetchW());
+       uint8_t m = READ_ABS;
+       OP_SBC_HANDLER(m, regs.b);
+}
 
-       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
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 97    0151 | STA         | DIRECT       |   4   |   2   | -aa0- |
+ | 9F    0159 | STX         | DIRECT       |   5   |   2   | -aa0- |
+ | A7    0167 | STA         | INDEXED      |   4   |   2   | -aa0- |
+ | AF    0175 | STX         | INDEXED      |   5   |   2   | -aa0- |
+ | B7    0183 | STA         | EXTENDED     |   5   |   3   | -aa0- |
+ | BF    0191 | STX         | EXTENDED     |   6   |   3   | -aa0- |
+ | D7    0215 | STB         | DIRECT       |   4   |   2   | -aa0- |
+ | DD    0221 | STD         | DIRECT       |   5   |   2   | -aa0- |
+ | DF    0223 | STU         | DIRECT       |   5   |   2   | -aa0- |
+ | E7    0231 | STB         | INDEXED      |   4   |   2   | -aa0- |
+ | ED    0237 | STD         | INDEXED      |   5   |   2   | -aa0- |
+ | EF    0239 | STU         | INDEXED      |   5   |   2   | -aa0- |
+ | F7    0247 | STB         | EXTENDED     |   5   |   3   | -aa0- |
+ | FD    0253 | STD         | EXTENDED     |   6   |   3   | -aa0- |
+ | FF    0255 | STU         | EXTENDED     |   6   |   3   | -aa0- |
+ | 109F  4255 | STY         | DIRECT       |   6   |   3   | -aa0- |
+ | 10AF  4271 | STY         | INDEXED      |   6   |   3   | -aa0- |
+ | 10BF  4287 | STY         | EXTENDED     |   7   |   4   | -aa0- |
+ | 10DF  4319 | STS         | DIRECT       |   6   |   3   | -aa0- |
+ | 10EF  4335 | STS         | INDEXED      |   6   |   3   | -aa0- |
+ | 10FF  4351 | STS         | EXTENDED     |   7   |   4   | -aa0- |
+*/
 
-       regs.clock += 6;
-}
+// STA opcodes
 
-static void OpBF(void)                                                                 // STX ABS
-{
-//     addr = FetchW();
-//     regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
-       WrMemW(FetchW(), regs.x);
+#define OP_STA_HANDLER(m, acc) \
+       regs.WrMem(m, acc); \
+       CLR_V; \
+       SET_ZN(acc)
 
-       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
+#define OP_STA_HANDLER16(m, acc) \
+       WrMemW(m, acc); \
+       CLR_V; \
+       SET_ZN16(acc)
 
-       regs.clock += 6;
+static void Op97(void)                                                 // STA DP
+{
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER(addr, regs.a);
 }
 
-static void OpC0(void)  // SUBB #
-      {
-        tmp = regs.RdMem(regs.pc++);  uint8_t 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
-        regs.clock += 2;
-      }
-static void OpC1(void)  // CMPB #
-      {
-        tmp = regs.RdMem(regs.pc++);
-        uint8_t 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.clock += 2;
-      }
-static void OpC2(void)  // SBCB #
+static void Op9F(void)                                                 // STX DP
 {
-  tmp = regs.RdMem(regs.pc++);  uint8_t 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.clock += 2;
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER16(addr, regs.x);
 }
-static void OpC3(void)  // ADDD #
+
+static void OpA7(void)                                                 // STA IDX
 {
-  addr = FetchW();  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
-  dr += addr;
-  (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  dr &= 0xFFFF;
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 4;
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER(addr, regs.a);
 }
-static void OpC4(void)  // ANDB #
-      {
-        regs.b &= 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
-        regs.clock += 2;
-      }
-static void OpC5(void)  // BITB #
-{
-  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.clock += 2;
-}
-static void OpC6(void)  // LDB #
-{
-  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.clock += 2;
-}
-static void OpC8(void)  // EORB #
-      {
-        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
-        regs.clock += 2;
-      }
-static void OpC9(void)  // ADCB #
-{
-  tmp = regs.RdMem(regs.pc++);
-  addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 2;
-}
-static void OpCA(void)  // ORB #
-      {
-        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
-        regs.clock += 2;
-      }
-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)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 2;
-}
-static void OpCC(void)  // LDD #
-{
-  regs.a = regs.RdMem(regs.pc++);  regs.b = regs.RdMem(regs.pc++);
-  regs.cc &= 0xFD;                                 // CLV
-  ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 3;
-}
-static void OpCE(void)  // LDU #
-{
-  regs.u = FetchW();
-  regs.cc &= 0xFD;                              // CLV
-  (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 3;
-}
-static void OpD0(void)  // SUBB DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t 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
-  regs.clock += 4;
-}
-static void OpD1(void)  // CMPB DP
+
+static void OpAF(void)                                                 // STX IDX
 {
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  uint8_t 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.clock += 4;
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER16(addr, regs.x);
 }
-static void OpD2(void)  // SBCB DP
+
+static void OpB7(void)                                                 // STA ABS
 {
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t 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.clock += 4;
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER(addr, regs.a);
 }
-static void OpD3(void)  // ADDD DP
+
+static void OpBF(void)                                                 // STX ABS
 {
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
-  dr += adr2;
-  (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  dr &= 0xFFFF;
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 6;
-}
-static void OpD4(void)  // ANDB DP
-      {
-        regs.b &= regs.RdMem((regs.dp<<8)|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
-        regs.clock += 4;
-      }
-static void OpD5(void)  // BITB DP
-      {
-        tmp = regs.b & regs.RdMem((regs.dp<<8)|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
-        regs.clock += 4;
-      }
-static void OpD6(void)  // LDB DP
-{
-  regs.b = regs.RdMem((regs.dp<<8)|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.clock += 4;
-}
-static void OpD7(void)  // STB DP
-      {
-        regs.WrMem((regs.dp<<8)|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
-        regs.clock += 4;
-      }
-static void OpD8(void)  // EORB DP
-      {
-        regs.b ^= regs.RdMem((regs.dp<<8)|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.clock += 4;
-      }
-static void OpD9(void)  // ADCB DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 4;
-}
-static void OpDA(void)  // ORB DP
-      {
-        regs.b |= regs.RdMem((regs.dp<<8)|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.clock += 4;
-      }
-static void OpDB(void)  // ADDB DP
-{
-  tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
-  addr = (uint16_t)regs.b + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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
-  regs.clock += 4;
-}
-static void OpDC(void)  // LDD DP
-{
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-  regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
-  regs.cc &= 0xFD;                                 // CLV
-  ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpDD(void)  // STD DP
-{
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-  regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
-  regs.cc &= 0xFD;                                 // CLV
-  ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpDE(void)  // LDU DP
-{
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-  regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-  regs.cc &= 0xFD;                              // CLV
-  (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpDF(void)  // STU DP
-{
-  addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-  regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
-  regs.cc &= 0xFD;                              // CLV
-  (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpE0(void)  // SUBB IDX
-{
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t 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
-  regs.clock += 4;
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER16(addr, regs.x);
 }
-static void OpE1(void)  // CMPB IDX
+
+static void OpD7(void)                                                 // STB DP
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  uint8_t 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.clock += 4;
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER(addr, regs.b);
 }
-static void OpE2(void)  // SBCB IDX
+
+static void OpDD(void)                                                 // STD DP
 {
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t 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.clock += 4;
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
 }
-static void OpE3(void)  // ADDD IDX
+
+static void OpDF(void)                                                 // STU DP
 {
-  addr = DecodeIDX(regs.RdMem(regs.pc++));  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
-  dr += adr2;
-  (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  dr &= 0xFFFF;
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 6;
-}
-static void OpE4(void)  // ANDB IDX
-      {
-        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
-        regs.clock += 4;
-      }
-static void OpE5(void)  // BITB IDX
-      {
-        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
-        regs.clock += 4;
-      }
-static void OpE6(void)  // LDB IDX
-      {
-        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.clock += 4;
-      }
-static void OpE7(void)  // STB IDX
-{
-  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
-  regs.clock += 4;
-}
-static void OpE8(void)  // EORB IDX
-      {
-        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.clock += 4;
-      }
-static void OpE9(void)  // ADCB IDX
-{
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 4;
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER16(addr, regs.u);
 }
-static void OpEA(void)  // ORB IDX
-      {
-        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.clock += 4;
-      }
-static void OpEB(void)  // ADDB IDX
-{
-  tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
-  addr = (uint16_t)regs.b + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 4;
-}
-static void OpEC(void)  // LDD IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
-  regs.cc &= 0xF1;                             // CLV CLZ CLN
-  if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
-  if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpED(void)  // STD IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
-  regs.cc &= 0xF1;                             // CLV CLZ CLZ
-  if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
-  if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
-  regs.clock += 5;
-}
-static void OpEE(void)  // LDU IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-  regs.cc &= 0xF1;                              // CLV CLZ CLN
-  if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
-  if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
-  regs.clock += 5;
-}
-static void OpEF(void)  // STU IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
-  regs.cc &= 0xF1;                              // CLV CLZ CLN
-  if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
-  if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
-  regs.clock += 5;
-}
-static void OpF0(void)  // SUBB ABS
-      {
-        tmp = regs.RdMem(FetchW());  uint8_t 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 OpF1(void)  // CMPB ABS
-      {
-        tmp = regs.RdMem(FetchW());
-        uint8_t 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.clock += 5;
-      }
-static void OpF2(void)  // SBCB ABS
-{
-  tmp = regs.RdMem(FetchW());  uint8_t 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
-  regs.clock += 5;
-}
-static void OpF3(void)  // ADDD ABS
-{
-  addr = FetchW();  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
-  uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
-  dr += adr2;
-  (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-  dr &= 0xFFFF;
-  (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-  (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-  ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-  regs.a = dr>>8;  regs.b = dr&0xFF;
-  regs.clock += 7;
-}
-static void OpF4(void)  // ANDB ABS
-      {
-        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
-        regs.clock += 5;
-      }
-static void OpF5(void)  // BITB ABS
-      {
-        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.clock += 5;
-      }
-static void OpF6(void)  // LDB ABS
-      {
-        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.clock += 5;
-      }
-static void OpF7(void)  // STB ABS
-      {
-        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.clock += 5;
-      }
-static void OpF8(void)  // EORB ABS
-      {
-        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.clock += 5;
-      }
-static void OpF9(void)  // ADCB ABS
-{
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 5;
-}
-static void OpFA(void)  // ORB ABS
-      {
-        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.clock += 5;
-      }
-static void OpFB(void)  // ADDB ABS
-{
-  tmp = regs.RdMem(FetchW());
-  addr = (uint16_t)regs.b + (uint16_t)tmp;
-  (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
-  ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
-  ((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.clock += 5;
-}
-static void OpFC(void)  // LDD ABS
-      {
-        addr = FetchW();
-        regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
-        regs.cc &= 0xFD;                                 // CLV
-        ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-        (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-        regs.clock += 6;
-      }
-static void OpFD(void)  // STD ABS
-      {
-        addr = FetchW();
-        regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
-        regs.cc &= 0xFD;                                 // CLV
-        ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-        (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-        regs.clock += 6;
-      }
-static void OpFE(void)  // LDU ABS
-      {
-        addr = FetchW();
-        regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
-        regs.cc &= 0xFD;                              // CLV
-        (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-        (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-        regs.clock += 6;
-      }
-static void OpFF(void)  // STU ABS
-      {
-        addr = FetchW();
-        regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
-        regs.cc &= 0xFD;                              // CLV
-        (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-        (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-        regs.clock += 6;
-      }
-
-//
-// Page one opcodes' execute code
-//
 
-static void Op1021(void)                                               // LBRN
+static void OpE7(void)                                                 // STB IDX
 {
-       addr = FetchW();
-
-       regs.clock += 5;
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER(addr, regs.b);
 }
 
-static void Op1022(void)                                               // LBHI
+static void OpED(void)                                                 // STD IDX
 {
-       uint16_t word = FetchW();
-
-       if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
-               regs.pc += word;
-
-       regs.clock += 5;
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
 }
 
-static void Op1023(void)                                               // LBLS
+static void OpEF(void)                                                 // STU IDX
 {
-       uint16_t word = FetchW();
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER16(addr, regs.u);
+}
 
-       if ((regs.cc & 0x01) | (regs.cc & 0x04))
-               regs.pc += word;
+static void OpF7(void)                                                 // STB ABS
+{
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER(addr, regs.b);
+}
 
-       regs.clock += 5;
+static void OpFD(void)                                                 // STD ABS
+{
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
 }
 
-static void Op1024(void)                                               // LBCC (LBHS)
+static void OpFF(void)                                                 // STU ABS
 {
-       uint16_t word = FetchW();
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER16(addr, regs.u);
+}
 
-       if (!(regs.cc & 0x01))
-               regs.pc += word;
+static void Op109F(void)                                               // STY DP
+{
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER16(addr, regs.y);
+}
 
-       regs.clock += 5;
+static void Op10AF(void)                                               // STY IDX
+{
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER16(addr, regs.y);
 }
 
-static void Op1025(void)                                               // LBCS (LBLO)
+static void Op10BF(void)                                               // STY ABS
 {
-       uint16_t word = FetchW();
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER16(addr, regs.y);
+}
 
-       if (regs.cc & 0x01)
-               regs.pc += word;
+static void Op10DF(void)                                               // STS DP
+{
+       uint16_t addr = EA_DP;
+       OP_STA_HANDLER16(addr, regs.s);
+}
 
-       regs.clock += 5;
+static void Op10EF(void)                                               // STS IDX
+{
+       uint16_t addr = EA_IDX;
+       OP_STA_HANDLER16(addr, regs.s);
 }
 
-static void Op1026(void)                                               // LBNE
+static void Op10FF(void)                                               // STS ABS
 {
-       uint16_t word = FetchW();
+       uint16_t addr = EA_ABS;
+       OP_STA_HANDLER16(addr, regs.s);
+}
 
-       if (!(regs.cc & 0x04))
-               regs.pc += word;
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 80    0128 | SUBA        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | 83    0131 | SUBD        | IMMEDIATE    |   4   |   3   | -aaaa |
+ | 90    0144 | SUBA        | DIRECT       |   4   |   2   | uaaaa |
+ | 93    0147 | SUBD        | DIRECT       |   6   |   2   | -aaaa |
+ | A0    0160 | SUBA        | INDEXED      |   4   |   2   | uaaaa |
+ | A3    0163 | SUBD        | INDEXED      |   6   |   2   | -aaaa |
+ | B0    0176 | SUBA        | EXTENDED     |   5   |   3   | uaaaa |
+ | B3    0179 | SUBD        | EXTENDED     |   7   |   3   | -aaaa |
+ | C0    0192 | SUBB        | IMMEDIATE    |   2   |   2   | uaaaa |
+ | D0    0208 | SUBB        | DIRECT       |   4   |   2   | uaaaa |
+ | E0    0224 | SUBB        | INDEXED      |   4   |   2   | uaaaa |
+ | F0    0240 | SUBB        | EXTENDED     |   5   |   3   | uaaaa |
+*/
 
-       regs.clock += 5;
-}
+// SUB opcodes
 
-static void Op1027(void)                                               // LBEQ
-{
-       uint16_t word = FetchW();
+#define OP_SUB_HANDLER(m, acc) \
+       uint16_t sum = (uint16_t)acc - (m); \
+       flagC = (sum >> 8) & 0x01; \
+       SET_V(m, acc, sum); \
+       acc = (uint8_t)sum; \
+       SET_ZN(acc)
 
-       if (regs.cc & 0x04)
-               regs.pc += word;
+#define OP_SUB_HANDLER16D(m) \
+       uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
+       uint32_t sum = acc - (m); \
+       flagC = (sum >> 16) & 0x01; \
+       SET_V16(m, acc, sum); \
+       acc = sum & 0xFFFF; \
+       regs.a = (acc >> 8) & 0xFF; \
+       regs.b = acc & 0xFF; \
+       SET_ZN16(acc)
 
-       regs.clock += 5;
+static void Op80(void)                                                 // SUBA #
+{
+       uint8_t m = READ_IMM;
+       OP_SUB_HANDLER(m, regs.a);
 }
 
-static void Op1028(void)                                               // LBVC
+static void Op83(void)                                                 // SUBD #
 {
-       uint16_t word = FetchW();
-
-       if (!(regs.cc & 0x02))
-               regs.pc += word;
-
-       regs.clock += 5;
+       uint16_t m = READ_IMM16;
+       OP_SUB_HANDLER16D(m);
 }
 
-static void Op1029(void)                                               // LBVS
+static void Op90(void)                                                 // SUBA DP
 {
-       uint16_t word = FetchW();
+       uint8_t m = READ_DP;
+       OP_SUB_HANDLER(m, regs.a);
+}
 
-       if (regs.cc & 0x02)
-               regs.pc += word;
+static void Op93(void)                                                 // SUBD DP
+{
+       uint16_t m = READ_DP16;
+       OP_SUB_HANDLER16D(m);
+}
 
-       regs.clock += 5;
+static void OpA0(void)                                                 // SUBA IDX
+{
+       uint8_t m = READ_IDX;
+       OP_SUB_HANDLER(m, regs.a);
 }
 
-static void Op102A(void)                                               // LBPL
+static void OpA3(void)                                                 // SUBD IDX
 {
-       uint16_t word = FetchW();
+       uint16_t m = READ_IDX16;
+       OP_SUB_HANDLER16D(m);
+}
 
-       if (!(regs.cc & 0x08))
-               regs.pc += word;
+static void OpB0(void)                                                 // SUBA ABS
+{
+       uint8_t m = READ_ABS;
+       OP_SUB_HANDLER(m, regs.a);
+}
 
-       regs.clock += 5;
+static void OpB3(void)                                                 // SUBD ABS
+{
+       uint16_t m = READ_ABS16;
+       OP_SUB_HANDLER16D(m);
 }
 
-static void Op102B(void)                                               // LBMI
+static void OpC0(void)                                                 // SUBB #
 {
-       uint16_t word = FetchW();
+       uint8_t m = READ_IMM;
+       OP_SUB_HANDLER(m, regs.b);
+}
 
-       if (regs.cc & 0x08)
-               regs.pc += word;
+static void OpD0(void)                                                 // SUBB DP
+{
+       uint8_t m = READ_DP;
+       OP_SUB_HANDLER(m, regs.b);
+}
 
-       regs.clock += 5;
+static void OpE0(void)                                                 // SUBB IDX
+{
+       uint8_t m = READ_IDX;
+       OP_SUB_HANDLER(m, regs.b);
 }
 
-static void Op102C(void)                                               // LBGE
+static void OpF0(void)                                                 // SUBB ABS
 {
-       uint16_t word = FetchW();
+       uint8_t m = READ_ABS;
+       OP_SUB_HANDLER(m, regs.b);
+}
 
-       if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
-               regs.pc += word;
+/*
+ +-----------------------------------------------------------------+
+ | Opcode     |             | Addressing   |               |       |
+ | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0D    0013 | TST         | DIRECT       |   6   |   2   | -aa0- |
+ | 4D    0077 | TSTA        | INHERENT     |   2   |   1   | -aa0- |
+ | 5D    0093 | TSTB        | INHERENT     |   2   |   1   | -aa0- |
+ | 6D    0109 | TST         | INDEXED      |   6   |   2   | -aa0- |
+ | 7D    0125 | TST         | EXTENDED     |   7   |   3   | -aa0- |
+*/
 
-       regs.clock += 5;
-}
+// TST opcodes
 
-static void Op102D(void)                                               // LBLT
+#define OP_TST_HANDLER(m) \
+       SET_ZN(m); \
+       CLR_V
+
+static void Op0D(void)         // TST DP
 {
-       uint16_t word = FetchW();
+       uint8_t m = READ_DP;
+       OP_TST_HANDLER(m);
+}
 
-       if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
-               regs.pc += word;
 
-       regs.clock += 5;
+static void Op4D(void)         // TSTA
+{
+       OP_TST_HANDLER(regs.a);
 }
 
-static void Op102E(void)                                               // LBGT
+
+static void Op5D(void)         // TSTB
 {
-       uint16_t word = FetchW();
+       OP_TST_HANDLER(regs.b);
+}
 
-       if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
-               regs.pc += word;
 
-       regs.clock += 5;
+static void Op6D(void)         // TST IDX
+{
+       uint8_t m = READ_IDX;
+       OP_TST_HANDLER(m);
 }
 
-static void Op102F(void)                                               // LBLE
+
+static void Op7D(void)         // TST ABS
 {
-       uint16_t word = FetchW();
-
-       if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
-               regs.pc += word;
-
-       regs.clock += 5;
-}
-
-static void Op103F(void)  // SWI2 (Not yet implemented)
-{
-  regs.clock += 20;
-}
-static void Op1083(void)  // CMPD #
-    {
-      addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b;
-      uint16_t dw = dr - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      ((dr^addr^dw^((uint16_t)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 5;
-    }
-static void Op108C(void)  // CMPY #
-    {
-      addr = FetchW();
-      uint16_t dw = regs.y - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 5;
-    }
-static void Op108E(void)  // LDY #
-    {
-      regs.y = FetchW();
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 4;
-    }
-static void Op1093(void)  // CMPD DP
-    {
-      uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
-      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-      uint16_t dw = dr - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op109C(void)  // CMPY DP
-    {
-      uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-      uint16_t dw = regs.y - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-
-static void Op109E(void)  // LDY DP
-    {
-      addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 6;
-    }
-
-static void Op109F(void)  // STY DP
-    {
-      addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 6;
-    }
-static void Op10A3(void)  // CMPD IDX
-{
-  uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
-  addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-  uint16_t dw = dr - addr;
-  regs.cc &= 0xF0;                              // CLC CLV CLZ CLN
-  if (dr < addr)  regs.cc |= 0x01;              // Set Carry flag
-  if ((dr^addr^dw^(regs.cc<<15))&0x8000)  regs.cc |= 0x02; // Set oVerflow
-  if (dw == 0)    regs.cc |= 0x04;              // Set Zero flag
-  if (dw&0x8000)  regs.cc |= 0x08;              // Set Negative flag
-  regs.clock += 7;
-}
-static void Op10AC(void)  // CMPY IDX
-    {
-      uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++));
-      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-      uint16_t dw = regs.y - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op10AE(void)  // LDY IDX
-{
-  addr = DecodeIDX(regs.RdMem(regs.pc++));
-  regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-  regs.cc &= 0xF1;                              // CLV CLZ CLN
-  if (regs.y == 0)    regs.cc |= 0x04;              // Adjust Zero flag
-  if (regs.y&0x8000)  regs.cc |= 0x08;              // Adjust Negative flag
-  regs.clock += 6;
-}
-static void Op10AF(void)  // STY IDX
-    {
-      addr = DecodeIDX(regs.RdMem(regs.pc++));
-      regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 6;
-    }
-static void Op10B3(void)  // CMPD ABS
-    {
-      addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b;
-      uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-      uint16_t dw = dr - addr2;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 8;
-    }
-static void Op10BC(void)  // CMPY ABS
-    {
-      addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-      uint16_t dw = regs.y - addr2;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 8;
-    }
-static void Op10BE(void)  // LDY ABS
-    {
-      addr = FetchW();
-      regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 7;
-    }
-static void Op10BF(void)  // STY ABS
-    {
-      addr = FetchW();
-      regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
-      regs.cc &= 0xFD;                              // CLV
-      (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      regs.clock += 7;
-    }
-static void Op10CE(void)  // LDS #
-    {
-      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
-      regs.clock += 4;
-    }
-static void Op10DE(void)  // LDS DP
-    {
-      addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      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.clock += 6;
-    }
-static void Op10DF(void)  // STS DP
-    {
-      addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      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.clock += 6;
-    }
-static void Op10EE(void)  // LDS IDX
-    {
-      addr = DecodeIDX(regs.RdMem(regs.pc++));
-      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.clock += 6;
-    }
-static void Op10EF(void)  // STS IDX
-    {
-      addr = DecodeIDX(regs.RdMem(regs.pc++));
-      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.clock += 6;
-    }
-static void Op10FE(void)  // LDS ABS
-    {
-      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.clock += 7;
-    }
-static void Op10FF(void)  // STS ABS
-{
-  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.clock += 7;
+       uint8_t m = READ_ABS;
+       OP_TST_HANDLER(m);
 }
 
+
 //
-// Page two opcodes' execute code
+// Undocumented Opcodes
 //
-
-static void Op113F(void)  // SWI3
-    {
-      regs.clock += 20;
-    }
-static void Op1183(void)  // CMPU #
-    {
-      addr = FetchW();
-      uint16_t dw = regs.u - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 5;
-    }
-static void Op118C(void)  // CMPS #
-    {
-      addr = FetchW();
-      uint16_t dw = regs.s - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 5;
-    }
-static void Op1193(void)  // CMPU DP
-    {
-      uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-      uint16_t dw = regs.u - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op119C(void)  // CMPS DP
-    {
-      uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
-      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
-      uint16_t dw = regs.s - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op11A3(void)  // CMPU IDX
-    {
-      uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
-      addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
-      uint16_t dw = regs.u - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op11AC(void)  // CMPS IDX
-    {
-      uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
-      addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
-      uint16_t dw = regs.s - addr;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 7;
-    }
-static void Op11B3(void)  // CMPU ABS
-    {
-      addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-      uint16_t dw = regs.u - addr2;
-      (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-      (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-      (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-      (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-      regs.clock += 8;
-    }
-
-static void Op11BC(void)  // CMPS ABS
-{
-       addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
-       uint16_t dw = regs.s - addr2;
-       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
-       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
-       (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
-       (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
-       regs.clock += 8;
+static void Op01(void)
+{
+       Op00();                                 // NEG DP
 }
 
+
 //temp, for testing...
 #ifdef __DEBUG__
 static uint8_t backTrace[256];
 static uint16_t btPC[256];
 static int btPtr = 0;//*/
 #endif
-static void Op__(void)                                                                 // Illegal opcode
+static void Op__(void)         // Illegal opcode
 {
        regs.clock++;
 //     illegal = true;
@@ -3063,6 +3312,98 @@ for(int i=0; i<256; i++)
 #endif
 }
 
+//
+// Function arrays
+//
+
+// These are defined below, so we just use forward declarations here to prevent the compiler barfing...
+static void Op10(void);
+static void Op11(void);
+
+// Array of page zero opcode functions...
+
+static void (* exec_op0[256])() = {
+       Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
+       Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
+       Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
+       Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
+       Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
+       Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
+       Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
+       Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
+       Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
+       Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
+       OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
+       OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
+       OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
+       OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
+       OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
+       OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
+};
+
+// Array of page one opcode functions...
+static void (* exec_op1[256])() = {
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op103F,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op1083, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op108C, Op__,   Op108E, Op__,
+       Op__,   Op__,   Op__,   Op1093, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op109C, Op__,   Op109E, Op109F,
+       Op__,   Op__,   Op__,   Op10A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10AC, Op__,   Op10AE, Op10AF,
+       Op__,   Op__,   Op__,   Op10B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10BC, Op__,   Op10BE, Op10BF,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10CE, Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10DE, Op10DF,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10EE, Op10EF,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10FE, Op10FF
+};
+
+// Array of page two opcode functions...
+static void (* exec_op2[256])() = {
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op113F,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op1183, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op118C, Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op1193, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op119C, Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op11A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11AC, Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op11B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11BC, Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
+       Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__
+};
+
+
+// These are here to save typing a ton of forward declarations...
+
+
+// Page 1 opcode
+static void Op10(void)
+{
+//     exec_op1[regs.RdMem(regs.pc++)]();
+       uint8_t opcode = regs.RdMem(regs.pc++);
+       exec_op1[opcode]();
+       regs.clock += page1Cycles[opcode];
+}
+
+
+// Page 2 opcode
+static void Op11(void)
+{
+//     exec_op2[regs.RdMem(regs.pc++)]();
+       uint8_t opcode = regs.RdMem(regs.pc++);
+       exec_op2[opcode]();
+       regs.clock += page2Cycles[opcode];
+}
+
 
 //
 // Internal "memcpy" (so we don't have to link with any external libraries!)
@@ -3075,6 +3416,7 @@ static void myMemcpy(void * dst, void * src, uint32_t size)
                d[i] = s[i];
 }
 
+
 //
 // Function to execute 6809 instructions
 //
@@ -3087,28 +3429,25 @@ uint8_t backTrace[256];
 V6809REGS btRegs[256];
 bool tripped = false;
 #endif
-#ifdef __DEBUG__
-//Here so this can be externally linked
-bool disasm = false;
-//bool disasm = true;
-#endif
 void Execute6809(V6809REGS * context, uint32_t cycles)
 {
-       // If this is not in place, the clockOverrun calculations can cause the V6809 to get
-       // stuck in an infinite loop.
-       if (cycles == 0)                                                        // Nothing to do, so bail!
+       // If this is not in place, the clockOverrun calculations can cause the
+       // V6809 to get stuck in an infinite loop.
+       if (cycles == 0)
                return;
 
        myMemcpy(&regs, context, sizeof(V6809REGS));
+       // Explode flags register into individual uint8_ts
+       UNPACK_FLAGS;
 
        // Execute here...
 
-       // Since we can't guarantee that we'll execute the number of cycles passed in
-       // exactly, we have to keep track of how much we overran the number of cycles
-       // the last time we executed. Since we already executed those cycles, this time
-       // through we remove them from the cycles passed in in order to come out
-       // approximately even. Over the long run, this unevenness in execution times
-       // evens out.
+       // Since we can't guarantee that we'll execute the number of cycles passed
+       // in exactly, we have to keep track of how much we overran the number of
+       // cycles the last time we executed. Since we already executed those
+       // cycles, this time through we remove them from the cycles passed in in
+       // order to come out approximately even. Over the long run, this unevenness
+       // in execution times evens out. :-)
        uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
 
        while (regs.clock < endCycles)
@@ -3138,8 +3477,16 @@ if (!tripped)
 }
 #endif
 #ifdef __DEBUG__
-//Decode6809(regs.pc);
-if (disasm) Decode6809(regs);
+if (disasm)
+{
+       Decode6809(regs);
+//     WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
+}
+#if 0 //we solved this...
+if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
+       WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
+#endif
+//static bool disasm = false;
 /*//if (regs.pc == 0x15BA)     disasm = true;
 //if (regs.pc == 0xFE76)       disasm = true;
 if (regs.x == 0xFED4)  disasm = true;
@@ -3151,7 +3498,10 @@ if (disasm) Decode6809(regs.pc);
 btPC[btPtr] = regs.pc;
 btPtr = (btPtr + 1) & 0xFF;//*/
 #endif
-               exec_op0[regs.RdMem(regs.pc++)]();
+//             exec_op0[regs.RdMem(regs.pc++)]();
+               uint8_t opcode = regs.RdMem(regs.pc++);
+               exec_op0[opcode]();
+               regs.clock += page0Cycles[opcode];
 
                // Handle any pending interrupts
 
@@ -3164,7 +3514,7 @@ btPtr = (btPtr + 1) & 0xFF;//*/
 #ifdef __DEBUG__
 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
 #endif
-                       regs.cc |= (FLAG_F | FLAG_I);                           // Set F, I
+                       flagF = flagI = 1;                                                      // Set F, I
                        regs.dp = 0;                                                            // Reset direct page register
                        regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
                        context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
@@ -3175,22 +3525,19 @@ if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
 #ifdef __DEBUG__
 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
 #endif
-                       regs.cc |= FLAG_E;                                                      // Set the Entire flag
-
-                       regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
-                       regs.WrMem(--regs.s, regs.pc >> 8);
-                       regs.WrMem(--regs.s, regs.u & 0xFF);
-                       regs.WrMem(--regs.s, regs.u >> 8);
-                       regs.WrMem(--regs.s, regs.y & 0xFF);
-                       regs.WrMem(--regs.s, regs.y >> 8);
-                       regs.WrMem(--regs.s, regs.x & 0xFF);
-                       regs.WrMem(--regs.s, regs.x >> 8);
-                       regs.WrMem(--regs.s, regs.dp);
-                       regs.WrMem(--regs.s, regs.b);
-                       regs.WrMem(--regs.s, regs.a);
-                       regs.WrMem(--regs.s, regs.cc);
-
-                       regs.cc |= (FLAG_I | FLAG_F);                           // Set IRQ/FIRQ suppress flags
+                       flagE = 1;                                                                      // Set Entire flag
+                       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
+
+                       PUSHS16(regs.pc);                                                       // Save all regs...
+                       PUSHS16(regs.u);
+                       PUSHS16(regs.y);
+                       PUSHS16(regs.x);
+                       PUSHS(regs.dp);
+                       PUSHS(regs.b);
+                       PUSHS(regs.a);
+                       PUSHS(regs.cc);
+
+                       flagI = flagF = 1;                                                      // Set IRQ/FIRQ suppress flags
                        regs.pc = RdMemW(0xFFFC);                                       // And load PC with the NMI vector
                        regs.clock += 19;
 //                     context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
@@ -3201,18 +3548,18 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
 #ifdef __DEBUG__
 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
 #endif
-                       if (!(regs.cc & FLAG_F))                                        // Is the FIRQ masked (F == 1)?
+                       if (!flagF)                                                                     // Is the FIRQ masked (F == 1)?
                        {
 #ifdef __DEBUG__
 if (disasm) WriteLog("       FIRQ taken...\n");
 #endif
-                               regs.cc &= ~FLAG_E;                                             // Clear the Entire flag
+                               flagE = 0;                                                              // Clear Entire flag
+                               regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
 
-                               regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save PC, CC regs...
-                               regs.WrMem(--regs.s, regs.pc >> 8);
-                               regs.WrMem(--regs.s, regs.cc);
+                               PUSHS16(regs.pc);
+                               PUSHS(regs.cc);
 
-                               regs.cc |= (FLAG_I | FLAG_F);                   // Set IRQ/FIRQ suppress flags
+                               flagI = flagF = 1;                                              // Set IRQ/FIRQ suppress flags
                                regs.pc = RdMemW(0xFFF6);                               // And load PC with the IRQ vector
                                regs.clock += 10;
 //                             context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;   // Reset the asserted line (FIRQ)...
@@ -3224,56 +3571,49 @@ if (disasm) WriteLog("       FIRQ taken...\n");
 #ifdef __DEBUG__
 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
 #endif
-                       if (!(regs.cc & FLAG_I))                                        // Is the IRQ masked (I == 1)?
+                       if (!flagI)                                                                     // Is the IRQ masked (I == 1)?
                        {
 #ifdef __DEBUG__
 if (disasm) WriteLog("       IRQ taken...\n");
 #endif
-                               regs.cc |= FLAG_E;                                              // Set the Entire flag
-
-                               regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save all regs...
-                               regs.WrMem(--regs.s, regs.pc >> 8);
-                               regs.WrMem(--regs.s, regs.u & 0xFF);
-                               regs.WrMem(--regs.s, regs.u >> 8);
-                               regs.WrMem(--regs.s, regs.y & 0xFF);
-                               regs.WrMem(--regs.s, regs.y >> 8);
-                               regs.WrMem(--regs.s, regs.x & 0xFF);
-                               regs.WrMem(--regs.s, regs.x >> 8);
-                               regs.WrMem(--regs.s, regs.dp);
-                               regs.WrMem(--regs.s, regs.b);
-                               regs.WrMem(--regs.s, regs.a);
-                               regs.WrMem(--regs.s, regs.cc);
-
-                               regs.cc |= FLAG_I;                                              // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
+                               flagE = 1;                                                              // Set the Entire flag
+                               regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
+
+                               PUSHS16(regs.pc);
+                               PUSHS16(regs.u);
+                               PUSHS16(regs.y);
+                               PUSHS16(regs.x);
+                               PUSHS(regs.dp);
+                               PUSHS(regs.b);
+                               PUSHS(regs.a);
+                               PUSHS(regs.cc);
+
+                               flagI = 1;                                                              // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
                                regs.pc = RdMemW(0xFFF8);                               // And load PC with the IRQ vector
                                regs.clock += 19;
 // Apparently, not done here!
-// Need to put IRQ handling in somewhere... It shouldn't be cleared here!
 //                             context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
 //                             regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
                        }
                }
 #ifdef __DEBUG__
-if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
-       (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" : "-"),
+if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
+       (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
+       (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
        regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
        regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
 #endif
        }
+
        // Keep track of how much we overran so we can adjust on the next run...
        regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
 
+       regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
        myMemcpy(context, &regs, sizeof(V6809REGS));
-
-#ifdef __DEBUG__
-       if (disasm)
-               WriteLog("\n*** CONTEXT SWITCH ***\n\n");
-#endif
 }
 
+
 //
 // Get the clock of the currently executing CPU
 //
@@ -3282,6 +3622,7 @@ uint64_t GetCurrentV6809Clock(void)
        return regs.clock;
 }
 
+
 //
 // Get the PC of the currently executing CPU
 //
@@ -3290,12 +3631,14 @@ uint16_t GetCurrentV6809PC(void)
        return regs.pc;
 }
 
+
 // Set a line of the currently executing CPU
 void SetLineOfCurrentV6809(uint32_t line)
 {
        regs.cpuFlags |= line;
 }
 
+
 // Clear a line of the currently executing CPU
 void ClearLineOfCurrentV6809(uint32_t line)
 {
@@ -3305,3 +3648,32 @@ if (disasm)
 #endif
        regs.cpuFlags &= ~line;
 }
+
+
+#if 0
+FE54: 27 6A          BEQ   $FEC0        CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
+E S=BFFF U=0000 PC=FEC0
+FEC0: 6E A4          JMP   ,Y   CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
+ U=0000 PC=F51E
+F51E: 86 34          LDA   #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
+ U=0000 PC=F520
+F520: B7 C8 0D       STA   $C80D        CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
+F523: B7 C8 0F       STA   $C80F        CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
+F526: 7F C8 0E       CLR   $C80EV6809: Clearing line IRQ...     CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
+F529: 86 9C          LDA   #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
+F52B: 1F 8B          TFR   A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
+F52D: 10 CE BF FF    LDS   #$BFFF       CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
+F531: BD 13 BD       JSR   $13BD        CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
+13BD: 34 76          PSHS  A B X Y U    CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
+13BF: CE 9C 00       LDU   #$9C00       CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
+13C2: 8E 00 00       LDX   #$0000       CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
+13C5: 1F 12          TFR   X,Y  CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
+13C7: 1F 10          TFR   X,D  CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
+13C9: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
+13CB: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
+13CD: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
+13CF: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
+13D1: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
+13D3: 36 10          PSHU  X    CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
+13D5: 11 83 00 00    CMPU  #$0000       CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 380318c..ae8a337
@@ -1,9 +1,9 @@
 //
 // Virtual 6809 Header file
 //
-// by James Hammons
+// by James L. Hammons
 //
-// (C) 1997, 2014 Underground Software
+// (C) 1997, 2004 Underground Software
 //
 
 #ifndef __V6809_H__
 
 // Useful defines
 
-#define FLAG_E 0x80            // Entire
-#define FLAG_F 0x40            // Fast IRQ
-#define FLAG_H 0x20            // Half carry
-#define FLAG_I 0x10            // IRQ
-#define FLAG_N 0x08            // Negative
-#define FLAG_Z 0x04            // Zero
-#define FLAG_V 0x02            // oVerflow
-#define FLAG_C 0x01            // Carry
+#define FLAG_E         0x80            // Entire
+#define FLAG_F         0x40            // Fast IRQ
+#define FLAG_H         0x20            // Half carry
+#define FLAG_I         0x10            // IRQ
+#define FLAG_N         0x08            // Negative
+#define FLAG_Z         0x04            // Zero
+#define FLAG_V         0x02            // oVerflow
+#define FLAG_C         0x01            // Carry
 
 #define V6809_ASSERT_LINE_RESET                0x0001          // v6809 RESET line
 #define V6809_ASSERT_LINE_IRQ          0x0002          // v6809 IRQ line
@@ -28,6 +28,7 @@
 #define V6809_ASSERT_LINE_NMI          0x0008          // v6809 NMI line
 #define V6809_STATE_SYNC                       0x0010          // v6809 SYNC line
 #define V6809_STATE_ILLEGAL_INST       0x0020          // Illegal instruction executed flag
+
 //#define V6809_START_DEBUG_LOG        EQU     0020h           // Debug log go (temporary!)
 
 // Useful structs
@@ -43,10 +44,9 @@ struct V6809REGS
        uint8_t a;                                              // 6809 A register
        uint8_t b;                                              // 6809 B register
        uint8_t dp;                                             // 6809 Direct Page register
-//     uint32_t clock;                                 // 6809 clock (@ 1 MHz, wraps at 71.5 minutes)
        uint64_t clock;                                 // 6809 clock (@ 1 MHz, wraps at 570842 years)
-       uint8_t (* RdMem)(uint16_t);            // Address of uint8_t read routine
-       void (* WrMem)(uint16_t, uint8_t);      // Address of uint8_t write routine
+       uint8_t (* RdMem)(uint16_t);    // Address of uint8 read routine
+       void (* WrMem)(uint16_t, uint8_t);      // Address of uint8 write routine
        uint32_t cpuFlags;                              // v6809 IRQ/RESET flags
        uint32_t clockOverrun;
 };
index 46776eedba4887412417a013de2354836f722d58..2074a4c3cfae96cbd183f622a715edca98644697 100644 (file)
@@ -1,10 +1,17 @@
+//
+// Jarek Burczynski's YM2151 emulator
+//
+// Cleaned of most MAMEisms & cleaned up in general by James Hammons
+// (this is mostly a placeholder until I write my own)
+//
+
+#include "ym2151.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
 #include <stdint.h>
-//#include "driver.h"
-#include "ym2151.h"
 
 
 // Missing shit (from M.A.M.E.)
 #if 1
 #define PI 3.1415629535897932338
 static FILE * errorlog = 0;
-int cpu_scalebyfcount(int);
-void timer_remove(void *);
-void * timer_set(int, int, void (*)(int));
+//int cpu_scalebyfcount(int);
+//void timer_remove(void *);
+//void * timer_set(int, int, void (*)(int));
+
+// Bogus M.A.M.E. shite
+int cpu_scalebyfcount(int f) { return f; }
+void timer_remove(void * foo) { printf("STUB: timer_remove()\n"); }
+void * timer_set(int foo, int bar, void (* baz)(int)) { printf("STUB: timer_set()\n"); return 0; }
+
 #endif
 
 
index 6c8f23043f845e01e182511a59eebe09af5580f0..9430ac284e0a649414d5d131b339838425d7312d 100644 (file)
@@ -60,13 +60,6 @@ uint8_t ReadMemory(uint16_t address)
 //     else if (address == 0x2021)
 //             return input_port_1_r(0);
 
-#if 0
-       // This is a cheap hack to fool the MCU into thinking something's
-       // attached to it...
-       if (address == 0x1181)
-               return 0xA6;
-#endif
-
        return memory[address];
 }