/* ----------------------------------------------------------------- core.c */
/*
 * cinecore.c, cinedbg.c, cineops.c -- Cinematronics game emulator
 * copyright 1997/1998 Jeff Mitchell and the Retrocade Alliance
 * copyright 1997 Zonn Moore
 *
 * This Cinematronics emulator may be freely used in any non-commercial
 * venture, and is to be considered as under the Gnu Public Licence
 * (GPL, copyleft). To avoid a huge deluge of email, I also allow the
 * MAME team usage under the so-called MAME licence for non-commercial
 * use.
 *
 * There are some restrictions, however, mostly to help further development
 * of the emulator and continue the enjoyment these fine games have
 * provided.
 *
 * 1) Jeff Mitchell (skeezix@skeleton.org) is the authoritative maintainer for
 *    the C implementation of the "CCPU" written by Zonn Moore. Modifications
 *    or changes to this code may not be distributed in source form, in whole
 *    or in part, without the written permission of the maintainer. (ie: At
 *    some point after changes have been made, submit them to the maintainer
 *    for inclusion into the authoritative source tree, for all to use.)
 * 2) Credit must be given where appropriate: Jeff Mitchell, author of the
 *    C version. Zonn Moore for the ASM version and all original research,
 *    original documentation, etc. (The C version is a rewrite of Zonn's
 *    brilliant work.) Neil Bradley, for the 32bit conversion of the ASM
 *    core, and technical assistance. Without him, the C version wouldn't
 *    have been written. Where possible, please include references to the
 *    official website for the software (see below), so that others may
 *    easily find the sources.
 * 3) Users of this software are encouraged to periodically check the
 *    official website for new revisions, bugfixes, etc. This is an
 *    ongoing project, with many optimizations yet to be done.
 *
 * Games known to work 100% or nearly so, at some point or another of
 * the emulators development (but not necessarily right now :):
 * RipOff, Solar Quest, Spacewar, Speed Freak, Star Castle, Star Hawk,
 * Tail Gunner, War of the Worlds, Warrior
 *
 * For reference, all of the cinematronics games are:
 * Armor Attack, Barrier, Boxing Bugs, Demon, Ripoff, Solar Quest,
 * Spacewar, Speed Freak, Star Castle, Star Hawk, Sundance, Tail Gunner
 * War of the worlds, Warrior
 * (There is another, but it has not been made available yet)
 *
 * USAGE:
 * 1) The emulator works like any other "processor" emulator
 * 2) It does expect a few variables to be set, however, indicating
 *    which switches were connected on the original boards. (Most
 *    important is the variable to chose whethor or not to use the MI
 *    or EI flag...). See below.
 * 3) The emulator expects the memory to ALREADY be interleaved into
 *    "normalacy". The cinem ROMs are slow to read otherwise...
 * 4) Endianness doesn't matter; its code nice and slowly :)
 * 5) Compile time options may be set to obtain debugging tool, runtime
 *    traces, etc etc.
 * 6) The emulator does the vector handling; you need provide a routine
 *    to receive the vector draw requests, so that it may queue them up
 * 7) Zonn will be documenting the method by which the game palettes
 *    may be derived, where applicable.
 *
 * INITIALIZATION:
 * Take, for example, the game RipOff (the reaosn I got into this mess :).
 * The following variables need to be set, and the functions called, in
 * order to have the "cpu" run properly (courtesy Neil Bradley, Zonn Moore):
 * bFlipX = 0;  bFlipY = 1;     bSwapXY = 0;     (for vector generation)
 * ioInputs = 0xffff; ioSwitches = 0xfff0;  (cleared values)
 * bOverlay = 0xff;                                 (No overlay)
 * cineSetJMI(1);                                      (JMI Allowed)
 * cineSetMSize(0);                            (8K)
 * cineSetMonitor(0);                       (Bi-level display)
 *
 * If masking values are needed by anyone for the various game
 * controllers and whatnot, let me know, and I'll put up a document.
 *
 * SUPPORT:
 * FTP and WEB:
 *   Official support archive is at ftp.retrocade.com and www.retrocade.com.
 *   Various mirrors will be kept (ie: skeleton.org, the Emulation Repository,
 *   erc.), and are yet to be announced.
 * EMAIL:
 *   The C version: Jeff Mitchell is skeezix@skeleton.org
 *   The ASM version: Neil Bradley (neil@synthcom.com) and
 *                    Zonn Moore (zonn@zonn.com)
 *
 * An emulator for the Cinematronics vector game hardware, originally
 * for use in the Retrocade emulator project. All work is based on
 * documentation and sources and testbeds created by Zonn. He's a freak.
 *
 * Last modified: 02/17/98
 *
 * 12/04/97:      Created a "SETFC" macro for storing the flag_C var
 *                (shift and mask it at inspection time)
 * 12/??/97:      Fixed subtraction bugs (using register_B for A0 instead
 *                of register_A). Fixed input mask value in opINP.
 * 12/24/97:      Added #define for CCPUSSTEP for single stepping
 * 12/25/97:      Added ioSwitches &= ( ! SW_ABORT ) into the top
 *                of the cineExec call. This fixed Star Castle, but
 *                broke others :/
 *                  Made opLSLe_A_.. handle multiple consecutive occurances
 *                so things would be a little faster, and so DOS versus
 *                Unix traces would be easier.
 *                  Changed above ioSwitches fix to ~SW_ABORT instead. This
 *                rebroke StarCastle and Sundance, but fixed Barrier. *sigh*
 */

/* Optional #defines for debugging:
 * CCPUBREAK -- causes stopage on unknown upcodes
 * CCPUDEBUG -- causes live trace to be dumped
 * For these to operate, the debugging variables must be set as well.
 * This allows runtime selection of traces, etc.
 * CCPUSSTEP -- force single stepping
 *
 * Debug Variables:
 * ccpubreak -- set to non-zero to enable "break"ing
 * ccpudebug -- set to non-zero to enable disassembly tracing
 */

/* 1) Need to macro-ize everything, so that I can have this whole
 *    source file written by a perl script generator easier.
 * 4) Any of the jumps weird? JNC?
 * 5) JEI's all fucked? Are the tredirector's set right in the first place?
 *    What about all those damned JPP8, 16 and 32s? They work right?
 * 6) Store ccpu_jmi_dip and other new state vars in struct?
 * 7) Various OUT functions correct?
 */


#include "rccore/global.h"
#include <string.h>
#ifdef UNIX
#include <strings.h>
#endif

#include "osdep/osdep.h"
#include "cpucores/ccpu.h"
#include "rccore/cpu.h"
#include "graphics/vector.h"
#include "graphics/display.h"

/* Declare needed macros
 */
#ifndef _WINCE
#define UNFINISHED(x) HostFprintf ( (FILE *) stderr, "UNFINISHED: %s\n", x );
#else
#define UNFINISHED(x)
#endif

/* state setting macros to exit opcode handler */
#define jumpCineRet_A state = state_A; \
                      goto cineExecBottom;

#define jumpCineRet_B state = state_B; \
                      goto cineExecBottom;

#define jumpCineRet_AA state = state_AA; \
                       goto cineExecBottom;

#define jumpCineRet_BB state = state_BB; \
                       goto cineExecBottom;

#define jumpCineRet_WEIRD fprintf ( stderr, "Didn't bother yet.\n" ); \
                          exit ( 0 );

/* Handy new operators ...
 */

/* for Zonn translation :) */
#define SAR(var,arg)    ( ( (signed short int) var ) >> arg )

/* for setting/checking the A0 flag */
#define SETA0(var)    ( acc_a0 = var )
#define GETA0()       ( acc_a0 )

/* for setting/checking the Carry flag */
#define SETFC(val)    ( flag_C = val )
#define GETFC()       ( ( flag_C >> 8 ) & 0xFF )

/* Define new types for the c-cpu emulator
 */

#define SW_ABORT           0x100          /* for ioSwitches */
#define SW_COIN            0x080          /* for ioSwitches */

typedef short unsigned int CINEWORD;      /* 12bits on the C-CPU */
typedef unsigned char      CINEBYTE;      /* 8 (or less) bits on the C-CPU */
typedef short signed int   CINESWORD;     /* 12bits on the C-CPU */
typedef signed char        CINESBYTE;     /* 8 (or less) bits on the C-CPU */

typedef enum {
  state_A = 0, state_AA, state_B, state_BB
} CINESTATE;                              /* current state */

volatile static UINT32 dwElapsedTicks = 0;
static UINT8 bBailOut = FALSE;

/* C-CPU context information begins --
 */
CINEWORD register_PC = 0; /* C-CPU registers; program counter */
CINEWORD register_A = 0;  /* ; A-Register (accumulator) */
CINEWORD register_B = 0;  /* ; B-Register (accumulator) */
CINEBYTE register_I = 0;  /* ; I-Register (last access RAM location) */
CINEWORD register_J = 0;  /* ; J-Register (target address for JMP opcodes) */
CINEBYTE register_P = 0;  /* ; Page-Register (4 bits) */
CINEWORD FromX = 0;       /* ; X-Register (start of a vector) */
CINEWORD FromY = 0;       /* ; Y-Register (start of a vector) */
CINEWORD register_T = 0;  /* ; T-Register (vector draw length timer) */
CINEWORD flag_C = 0;      /* C-CPU flags; carry. Is word sized, instead
                           * of CINEBYTE, so we can do direct assignment
                           * and then change to BYTE during inspection.
                           */

CINEWORD cmp_old = 0;     /* last accumulator value */
CINEWORD cmp_new = 0;     /* new accumulator value */
CINEBYTE acc_a0 = 0;      /* bit0 of A-reg at last accumulator access */

CINESTATE state = state_A; /* C-CPU state machine current state */
CINEWORD ram [ 256 ];     /* C-CPU ram (for all pages) */
static UINT8 *rom = NULL; /* C-CPU rom code */

static UINT8 ccpu_jmi_dip = 0;  /* as set by cineSetJMI */
static UINT8 ccpu_msize = 0;    /* as set by cineSetMSize */
static UINT8 ccpu_monitor = 0;  /* as set by cineSetMonitor */

/* cinem graphics junk */
CINEBYTE vgShiftLength = 0; /* number of shifts loaded into length reg */

/* -- Context information ends.
 */

UINT8 bFlipX;
UINT8 bFlipY;
UINT8 bSwapXY;
UINT8 bOverlay;

UINT16 ioSwitches = 0xFF;  /* high values for non-triggered switches */
UINT16 ioInputs = 0;
UINT8 ioOutputs = 0;

UINT16 vgColour = 0;

INT16 JoyX;
INT16 JoyY;
UINT8 bNewFrame;

extern INT32 sdwGameXSize;
extern INT32 sdwGameYSize;
extern INT32 sdwXOffset;
extern INT32 sdwYOffset;

/* debug junk
 */
//#include "cinedbg.c"

#ifdef CCPUBREAK
int ccpubreak = 1; /* default is on */
#endif

#ifdef CCPUDEBUG
int ccpudebug = 0; /* default is off */
#endif

/* functions
 */

#ifdef HAVE_CCPU

void DrawOverlay(void) {
}

/* cineExec() is what performs all the "processors" work; it will
 * continue to execute until something horrible happens, a watchpoint
 * is hit, cycle count exceeded, or other happy things.
 */
UINT32 cineExec ( UINT32 a ) {
#ifdef CCPUDEBUG
  char disassembly [ 256 ]; /* debugger buffer */
#endif
#ifdef CCPUBREAK
  CINEWORD original_PC;     /* before opcode begins executing */
  int original_state = 0;   /* before opcode executes */
  int repeat_count = 0;     /* each time PC repeats itself.. */
#endif

  CINEBYTE temp_byte = 0;   /* cause it'll be handy */
  CINEBYTE temp_byte_2 = 0; /* cause it'll be handy */
  CINEWORD temp_word = 0;   /* cause it'll be handy */
  CINEWORD temp_word_2 = 0; /* cause it'll be handy */

  CINESWORD temp_sword = 0; /* in case its handy... */
  CINESBYTE temp_sbyte = 0; /* in case its handy... */

  /* before opcode handlers ...
   */
  ioSwitches &= ( ~SW_ABORT ); /* ( ! SW_ABORT ) ? */

  /* label; after each opcode is finished running, execution returns
   * to this point, where the state is examined and the proper
   * jump table used.
   */
cineExecTop:

  /* back up the PC, for debugger sake
   */
#ifdef CCPUBREAK
  original_PC = register_PC;
#endif
#ifdef CCPUDEBUG
  original_state = state;
#endif

  bBailOut = FALSE;

#if 0
  /****/ /* for debugging only! */
  if ( register_PC == 0xabf ) {
    printf ( "got it: register_A = %x register_B = %x register_PC = %x\n",
             register_A, register_B, register_PC );
  }
  /****/
#endif

  /* examine the current state, and jump down to the correct
   * opcode jump table.
   */
  switch ( state ) {
  case state_A:  goto opCodeTblA;
  case state_AA: goto opCodeTblAA;
  case state_B:  goto opCodeTblB;
  case state_BB: goto opCodeTblBB;
  } /* switch on current state */

  /* include the opcode jump tables; goto the correct piece of code
   * for the current opcode. That piece of code will set the state
   * for the next run, as well. The opcode jumptables were generated
   * with a perl script and are kept separate for make and ugly sake.
   */
#include "cineops.c"

  /* the actual opcode code; each piece should be careful to
   * (1) set the correct state
   * (2) increment the program counter as necessary
   * (3) piss with the flags as needed
   * otherwise the next opcode will be completely buggered.
   */

opINP_A_AA:
opINP_AA_AA:
opINP_BB_AA:
  /* bottom 4 bits of opcode are the position of the bit we want;
   * obtain input value, shift over that no, and truncate to last bit.
   * NOTE: Masking 0x07 does interesting things on Sundance and
   * others, but masking 0x0F makes RipOff and others actually work :)
   */
  cmp_new = ( ioInputs >> ( rom [ register_PC ] & 0x0F ) ) & 0x01;

  SETA0 ( register_A );               /* save old accA bit0 */
  SETFC ( register_A );

  cmp_old = register_A;               /* save old accB */
  register_A = cmp_new;               /* load new accB; zero other bits */

  register_PC ++;
  jumpCineRet_AA;

opINP_B_AA:
  /* bottom 3 bits of opcode are the position of the bit we want;
   * obtain Switches value, shift over that no, and truncate to last bit.
   */
  cmp_new = ( ioSwitches >> ( rom [ register_PC ] & 0x07 ) ) & 0x01;

  SETA0 ( register_A );               /* save old accA bit0 */
  SETFC ( register_A );

  cmp_old = register_B;               /* save old accB */
  register_B = cmp_new;               /* load new accB; zero other bits */

  register_PC ++;
  jumpCineRet_AA;

opOUTbi_A_A:
opOUTbi_AA_A:
opOUTbi_BB_A:

  temp_byte = rom [ register_PC ] & 0x07;
  register_PC++;

  if ( temp_byte - 0x06 ) {
    goto opOUTsnd_A;
  }

  vgColour = ( ( register_A & 0x01 ) << 3 ) | 0x07;

  jumpCineRet_A;

opOUT16_A_A:
opOUT16_AA_A:
opOUT16_BB_A:

  temp_byte = rom [ register_PC ] & 0x07;
  register_PC++;

  if ( temp_byte - 0x06 ) {
    goto opOUTsnd_A;
  }

  if ( ( register_A & 0xFF ) != 1 ) {
    vgColour = FromX & 0x0F;

    if ( ! vgColour ) {
      vgColour = 1;
    }

  }

  jumpCineRet_A;

opOUTsnd_A:
  temp_byte = 0x01 << ( rom [ register_PC ] & 0x07 );

  if ( ! ( register_A & 0x01 ) ) {
    goto opOUT_Aset;
  }

  temp_byte = ( ! temp_byte );
  ioOutputs &= temp_byte;

  if ( ( rom [ register_PC ] & 0x07 ) == 0x05 ) {
    goto opOUT_Aq;
  }

  jumpCineRet_A;

opOUT_Aq:
  /* reset coin counter */
  jumpCineRet_A;

opOUT_Aset:
  ioOutputs |= temp_byte;
  jumpCineRet_A;

opOUT64_A_A:
opOUT64_AA_A:
opOUT64_BB_A:
  jumpCineRet_A;

opOUTWW_A_A:
opOUTWW_AA_A:
opOUTWW_BB_A:
  temp_byte = rom [ register_PC ] & 0x07;
  register_PC++;

  if ( temp_byte - 0x06 ) {
    goto opOUTsnd_A;
  }

  if ( ( register_A & 0xFF ) == 1 ) {
    temp_word = ( ! FromX ) & 0x0FFF;

    if ( ! temp_word ) {   /* black */

      vgColour = 0;

    } else {              /* non-black */

      if ( temp_word & 0x0888 ) {
        /* bright */

        temp_word_2 = ( ( temp_word << 4 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        temp_word_2 = ( ( temp_word << 3 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        temp_word_2 = ( ( temp_word << 3 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        vgColour = ( temp_byte & 0x07 ) + 7;

      } else if ( temp_word & 0x0444 ) {
        /* dim bits */

        temp_word_2 = ( ( temp_word << 5 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        temp_word_2 = ( ( temp_word << 3 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        temp_word_2 = ( ( temp_word << 3 ) & 0x8000 ) >> 15;
        temp_byte = ( temp_byte << 1 ) + temp_word_2;

        vgColour = ( temp_byte & 0x07 );

      } else {
        /* dim white */
        vgColour = 0x0F;

      }

    }

  } /* colour change? == 1 */

  jumpCineRet_A;

opOUTbi_B_BB:
  temp_byte = rom [ register_PC ] & 0x07;
  register_PC++;

  if ( temp_byte - 0x06 ) {
    goto opOUTsnd_B;
  }

  vgColour = ( ( register_B & 0x01 ) << 3 ) | 0x07;

  jumpCineRet_BB;

opOUT16_B_BB:
  temp_byte = rom [ register_PC ] & 0x07;
  register_PC++;

  if ( temp_byte - 0x06 ) {
    goto opOUTsnd_B;
  }

  if ( ( register_B & 0xFF ) != 1 ) {
    vgColour = FromX & 0x0F;

    if ( ! vgColour ) {
      vgColour = 1;
    }

  }

  jumpCineRet_BB;

opOUTsnd_B:
  jumpCineRet_BB;

opOUT64_B_BB:
  jumpCineRet_BB;

opOUTWW_B_BB:
  jumpCineRet_BB;

  /* LDA imm (0x) */
opLDAimm_A_AA:
opLDAimm_AA_AA:
opLDAimm_BB_AA:
  temp_word = rom [ register_PC ] & 0x0F;   /* pick up immediate value */
  temp_word <<= 8;                          /* LDAimm is the HIGH nibble! */

  cmp_new = temp_word;                      /* set new comparison flag */

  SETA0 ( register_A );                     /* save old accA bit0 */
  SETFC ( register_A );                     /* ??? clear carry? */

  cmp_old = register_A;                     /* step back cmp flag */
  register_A = temp_word;                   /* set the register */

  register_PC++;                            /* increment PC */
  jumpCineRet_AA;                           /* swap state and end opcode */

opLDAimm_B_AA:
  temp_word = rom [ register_PC ] & 0x0F;   /* pick up immediate value */
  temp_word <<= 8;                          /* LDAimm is the HIGH nibble! */

  cmp_new = temp_word;                      /* set new comparison flag */

  SETA0 ( register_A );                     /* save old accA bit0 */
  SETFC ( register_A );

  cmp_old = register_B;                     /* step back cmp flag */
  register_B = temp_word;                   /* set the register */

  register_PC++;                            /* increment PC */
  jumpCineRet_AA;

opLDAdir_A_AA:
opLDAdir_AA_AA:
opLDAdir_BB_AA:

  temp_byte = rom [ register_PC ] & 0x0F;        /* snag imm value */
  register_I = ( register_P << 4 ) + temp_byte;  /* set I register */

  cmp_new = ram[ register_I ];                  /* new acc value */

  SETA0 ( register_A );                          /* back up bit0 */
  SETFC ( register_A );

  cmp_old = register_A;                          /* store old acc */
  register_A = cmp_new;                          /* store new acc */

  register_PC ++;                                /* bump PC */
  jumpCineRet_AA;

opLDAdir_B_AA:

  temp_byte = rom [ register_PC ] & 0x0F;        /* snag imm value */
  register_I = ( register_P << 4 ) + temp_byte;  /* set I register */

  cmp_new = ram[ register_I ];                  /* new acc value */

  SETA0 ( register_A );                          /* back up bit0 */
  SETFC ( register_A );

  cmp_old = register_B;                          /* store old acc */
  register_B = cmp_new;                          /* store new acc */

  register_PC ++;                                /* bump PC */
  jumpCineRet_AA;

opLDAirg_A_AA:
opLDAirg_AA_AA:
opLDAirg_BB_AA:

  cmp_new = ram[ register_I ];

  SETA0 ( register_A );
  SETFC ( register_A );

  cmp_old = register_A;
  register_A = cmp_new;

  register_PC++;
  jumpCineRet_AA;

opLDAirg_B_AA:
  cmp_new = ram[ register_I ];

  SETA0 ( register_A );
  SETFC ( register_A );

  cmp_old = register_B;
  register_B = cmp_new;

  register_PC++;
  jumpCineRet_AA;

  /* ADD imm */
opADDimm_A_AA:
opADDimm_AA_AA:
opADDimm_BB_AA:
  temp_word = rom [ register_PC ] & 0x0F;     /* get imm value */

  cmp_new = temp_word;                        /* new acc value */
  SETA0 ( register_A );                       /* save old accA bit0 */
  cmp_old = register_A;                       /* store old acc for later */

  register_A += temp_word;                    /* add values */
  SETFC ( register_A );                       /* store carry and extra */
  register_A &= 0xFFF;                        /* toss out >12bit carry */

  register_PC ++;
  jumpCineRet_AA;

opADDimm_B_AA:
  temp_word = rom [ register_PC ] & 0x0F;     /* get imm value */

  cmp_new = temp_word;                        /* new acc value */
  SETA0 ( register_A );                       /* save old accA bit0 */
  cmp_old = register_B;                       /* store old acc for later */

  register_B += temp_word;                    /* add values */
  SETFC ( register_B );                       /* store carry and extra */
  register_B &= 0xFFF;                        /* toss out >12bit carry */

  register_PC ++;
  jumpCineRet_AA;

  /* ADD imm extended */
opADDimmX_A_AA:
opADDimmX_AA_AA:
opADDimmX_BB_AA:
  cmp_new = rom [ register_PC + 1 ];          /* get extended value */
  SETA0 ( register_A );                       /* save old accA bit0 */
  cmp_old = register_A;                       /* store old acc for later */

  register_A += cmp_new;                      /* add values */
  SETFC ( register_A );                       /* store carry and extra */
  register_A &= 0xFFF;                        /* toss out >12bit carry */

  register_PC += 2;                           /* bump PC */
  jumpCineRet_AA;

opADDimmX_B_AA:
  cmp_new = rom [ register_PC + 1 ];          /* get extended value */
  SETA0 ( register_A );                       /* save old accA bit0 */
  cmp_old = register_B;                       /* store old acc for later */

  register_B += cmp_new;                      /* add values */
  SETFC ( register_B );                       /* store carry and extra */
  register_B &= 0xFFF;                        /* toss out >12bit carry */

  register_PC += 2;                           /* bump PC */
  jumpCineRet_AA;

opADDdir_A_AA:
opADDdir_AA_AA:
opADDdir_BB_AA:

  temp_byte = rom [ register_PC ] & 0x0F;         /* fetch imm value */
  register_I = ( register_P << 4 ) + temp_byte;   /* set regI addr */

  cmp_new = ram[ register_I ];                   /* fetch imm real value */
  SETA0 ( register_A );                           /* store bit0 */
  cmp_old = register_A;                           /* store old acc value */

  register_A += cmp_new;                          /* do acc operation */
  SETFC ( register_A );                           /* store carry and extra */
  register_A &= 0x0FFF;

  register_PC ++;                                 /* bump PC */
  jumpCineRet_AA;

opADDdir_B_AA:
  temp_byte = rom [ register_PC ] & 0x0F;         /* fetch imm value */
  register_I = ( register_P << 4 ) + temp_byte;   /* set regI addr */

  cmp_new = ram[ register_I ];                   /* fetch imm real value */
  SETA0 ( register_A );                           /* store bit0 */
  cmp_old = register_B;                           /* store old acc value */

  register_B += cmp_new;                          /* do acc operation */
  SETFC ( register_B );                           /* store carry and extra */
  register_B &= 0x0FFF;

  register_PC ++;                                 /* bump PC */
  jumpCineRet_AA;

opAWDirg_A_AA:
opAWDirg_AA_AA:
opAWDirg_BB_AA:
opADDirg_A_AA:
opADDirg_AA_AA:
opADDirg_BB_AA:

  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_A;

  register_A += cmp_new;
  SETFC ( register_A );
  register_A &= 0x0FFF;

  register_PC++;
  jumpCineRet_AA;

opAWDirg_B_AA:
opADDirg_B_AA:
  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_B;

  register_B += cmp_new;
  SETFC ( register_B );
  register_B &= 0x0FFF;

  register_PC++;
  jumpCineRet_AA;

opSUBimm_A_AA:
opSUBimm_AA_AA:
opSUBimm_BB_AA:
  /* SUBtractions are negate-and-add instructions of the CCPU; what
   * a pain in the ass.
   */
  temp_word = rom [ register_PC ] & 0x0F;

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word = ( temp_word ^ 0xFFF ) + 1;         /* ones compliment */
  register_A += temp_word;                       /* add */
  SETFC ( register_A );                          /* pick up top bits */
  register_A &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;                                /* bump PC */
  jumpCineRet_AA;

opSUBimm_B_AA:
  /* SUBtractions are negate-and-add instructions of the CCPU; what
   * a pain in the ass.
   */
  temp_word = rom [ register_PC ] & 0x0F;

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_B;

  temp_word = ( temp_word ^ 0xFFF ) + 1;         /* ones compliment */
  register_B += temp_word;                       /* add */
  SETFC ( register_B );                          /* pick up top bits */
  register_B &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;                                /* bump PC */
  jumpCineRet_AA;

opSUBimmX_A_AA:
opSUBimmX_AA_AA:
opSUBimmX_BB_AA:

  temp_word = rom [ register_PC + 1 ];          /* snag imm value */

  cmp_new = temp_word;                          /* save cmp value */
  SETA0 ( register_A );                         /* store bit0 */
  cmp_old = register_A;                         /* back up regA */

  temp_word = ( temp_word ^ 0xFFF ) + 1;        /* ones compliment */
  register_A += temp_word;                      /* add */
  SETFC ( register_A );                         /* pick up top bits */
  register_A &= 0x0FFF;                         /* mask final regA value */

  register_PC += 2;                             /* bump PC */
  jumpCineRet_AA;

opSUBimmX_B_AA:

  temp_word = rom [ register_PC + 1 ];          /* snag imm value */

  cmp_new = temp_word;                          /* save cmp value */
  SETA0 ( register_A );                         /* store bit0 */
  cmp_old = register_B;                         /* back up regA */

  temp_word = ( temp_word ^ 0xFFF ) + 1;        /* ones compliment */
  register_B += temp_word;                      /* add */
  SETFC ( register_B );                         /* pick up top bits */
  register_B &= 0x0FFF;                         /* mask final regA value */

  register_PC += 2;                             /* bump PC */
  jumpCineRet_AA;

opSUBdir_A_AA:
opSUBdir_AA_AA:
opSUBdir_BB_AA:
  temp_word = rom [ register_PC ] & 0x0F;         /* fetch imm value */
  register_I = ( register_P << 4 ) + temp_word;   /* set regI addr */

  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word = ( cmp_new ^ 0xFFF ) + 1;           /* ones compliment */
  register_A += temp_word;                       /* add */
  SETFC ( register_A );                          /* pick up top bits */
  register_A &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;
  jumpCineRet_AA;

opSUBdir_B_AA:

  temp_byte = rom [ register_PC ] & 0x0F;         /* fetch imm value */
  register_I = ( register_P << 4 ) + temp_byte;   /* set regI addr */

  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_B;

  temp_word = ( cmp_new ^ 0xFFF ) + 1;           /* ones compliment */
  register_B += temp_word;                       /* add */
  SETFC ( register_B );                          /* pick up top bits */
  register_B &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;
  jumpCineRet_AA;

opSUBirg_A_AA:
opSUBirg_AA_AA:
opSUBirg_BB_AA:
  /* sub [i] */
  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word = ( cmp_new ^ 0xFFF ) + 1;           /* ones compliment */
  register_A += temp_word;                       /* add */
  SETFC ( register_A );                          /* pick up top bits */
  register_A &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;
  jumpCineRet_AA;

opSUBirg_B_AA:
  /* sub [i] */
  cmp_new = ram[ register_I ];
  SETA0 ( register_A );
  cmp_old = register_B;

  temp_word = ( cmp_new ^ 0xFFF ) + 1;           /* ones compliment */
  register_B += temp_word;                       /* add */
  SETFC ( register_B );                          /* pick up top bits */
  register_B &= 0x0FFF;                          /* mask final regA value */

  register_PC ++;
  jumpCineRet_AA;

  /* CMP dir */
opCMPdir_A_AA:
opCMPdir_AA_AA:
opCMPdir_BB_AA:
  /* compare direct mode; don't modify regs, just set carry flag or not.
   */

  temp_byte = rom [ register_PC ] & 0x0F;       /* obtain relative addr */
  register_I = ( register_P << 4 ) + temp_byte; /* build real addr */

  temp_word = ram[ register_I ];
  cmp_new = temp_word;                          /* new acc value */
  SETA0 ( register_A );                         /* backup bit0 */
  cmp_old = register_A;                         /* backup old acc */

  temp_word = ( temp_word ^ 0xFFF ) + 1;        /* ones compliment */
  temp_word += register_A;
  SETFC ( temp_word );                          /* pick up top bits */

  register_PC ++;                               /* bump PC */
  jumpCineRet_AA;

opCMPdir_B_AA:
  temp_byte = rom [ register_PC ] & 0x0F;       /* obtain relative addr */
  register_I = ( register_P << 4 ) + temp_byte; /* build real addr */

  temp_word = ram[ register_I ];
  cmp_new = temp_word;                          /* new acc value */
  SETA0 ( register_A );                         /* backup bit0 */
  cmp_old = register_B;                         /* backup old acc */

  temp_word = ( temp_word ^ 0xFFF ) + 1;        /* ones compliment */
  temp_word += register_B;
  SETFC ( temp_word );                          /* pick up top bits */

  register_PC ++;                               /* bump PC */
  jumpCineRet_AA;

  /* AND [i] */
opANDirg_A_AA:
opANDirg_AA_AA:
opANDirg_BB_AA:
  cmp_new = ram[ register_I ];                /* new acc value */
  SETA0 ( register_A );
  SETFC ( register_A );
  cmp_old = register_A;

  register_A &= cmp_new;

  register_PC ++;                              /* bump PC */
  jumpCineRet_AA;

opANDirg_B_AA:
  cmp_new = ram[ register_I ];                /* new acc value */
  SETA0 ( register_A );
  SETFC ( register_A );
  cmp_old = register_B;

  register_B &= cmp_new;

  register_PC ++;                              /* bump PC */
  jumpCineRet_AA;

  /* LDJ imm */
opLDJimm_A_A:
opLDJimm_AA_A:
opLDJimm_BB_A:
  temp_byte = rom [ register_PC + 1 ];         /* upper part of address */
  temp_byte = ( temp_byte << 4 ) |             /* Silly CCPU; Swap */
              ( temp_byte >> 4 );              /* nibbles */

  /* put the upper 8 bits above the existing 4 bits */
  register_J = ( rom [ register_PC ] & 0x0F ) | ( temp_byte << 4 );

  register_PC += 2;
  jumpCineRet_A;

opLDJimm_B_BB:
  temp_byte = rom [ register_PC + 1 ];         /* upper part of address */
  temp_byte = ( temp_byte << 4 ) |             /* Silly CCPU; Swap */
              ( temp_byte >> 4 );              /* nibbles */

  /* put the upper 8 bits above the existing 4 bits */
  register_J = ( rom [ register_PC ] & 0x0F ) | ( temp_byte << 4 );

  register_PC += 2;
  jumpCineRet_BB;

  /* LDJ irg */
opLDJirg_A_A:
opLDJirg_AA_A:
opLDJirg_BB_A:
  /* load J reg from value at last dir addr */
  register_J = ram[ register_I ];
  register_PC++;                             /* bump PC */
  jumpCineRet_A;

opLDJirg_B_BB:
  register_J = ram[ register_I ];
  register_PC++;                             /* bump PC */
  jumpCineRet_BB;

  /* LDP imm */
opLDPimm_A_A:
opLDPimm_AA_A:
opLDPimm_BB_A:
  /* load page register from immediate */
  register_P = rom [ register_PC ] & 0x0F;  /* set page register */
  register_PC ++;  /* inc PC */
  jumpCineRet_A;

opLDPimm_B_BB:
  /* load page register from immediate */
  register_P = rom [ register_PC ] & 0x0F;  /* set page register */
  register_PC ++;  /* inc PC */
  jumpCineRet_BB;

  /* LDI dir */
opLDIdir_A_A:
opLDIdir_AA_A:
opLDIdir_BB_A:
  /* load regI directly .. */

  temp_byte = ( register_P << 4 ) +           /* get rampage ... */
              ( rom [ register_PC ] & 0x0F ); /* and imm half of ramaddr.. */

  register_I = ram[ temp_byte ] & 0xFF;      /* set/mask new register_I */

  register_PC ++;
  jumpCineRet_A;

opLDIdir_B_BB:
  temp_byte = ( register_P << 4 ) +           /* get rampage ... */
              ( rom [ register_PC ] & 0x0F ); /* and imm half of ramaddr.. */

  register_I = ram[ temp_byte ] & 0xFF;      /* set/mask new register_I */

  register_PC ++;
  jumpCineRet_BB;

  /* STA dir */
opSTAdir_A_A:
opSTAdir_AA_A:
opSTAdir_BB_A:
  temp_byte = rom [ register_PC ] & 0x0F;        /* snag imm value */
  register_I = ( register_P << 4 ) + temp_byte;  /* set I register */

  ram[ register_I ] = register_A;               /* store acc to */ram

  register_PC ++;                                /* inc PC */
  jumpCineRet_A;

opSTAdir_B_BB:
  temp_byte = rom [ register_PC ] & 0x0F;        /* snag imm value */
  register_I = ( register_P << 4 ) + temp_byte;  /* set I register */

  ram[ register_I ] = register_B;               /* store acc to */ram

  register_PC ++;                                /* inc PC */
  jumpCineRet_BB;

  /* STA irg */
opSTAirg_A_A:
opSTAirg_AA_A:
opSTAirg_BB_A:
  /* STA into address specified in regI. Nice and easy :)
   */

  ram[ register_I ] = register_A;               /* store acc */

  register_PC ++;                                /* bump PC */
  jumpCineRet_A;

opSTAirg_B_BB:

  ram[ register_I ] = register_B;               /* store acc */

  register_PC ++;                                /* bump PC */
  jumpCineRet_BB;

  /* XLT */
opXLT_A_AA:
opXLT_AA_AA:
opXLT_BB_AA:
  /* XLT is weird; it loads the current accumulator with the bytevalue
   * at ROM location pointed to by the accumulator; this allows the
   * programto read the programitself..
   *   NOTE! Next opcode is *IGNORED!* because of a twisted side-effect
   */

  cmp_new = rom [ ( register_PC & 0xF000 ) + register_A ];   /* store new acc value */
  SETA0 ( register_A );           /* store bit0 */
  SETFC ( register_A );
  cmp_old = register_A;           /* back up acc */

  register_A = cmp_new;           /* new acc value */

  register_PC += 2;               /* bump PC twice because XLT is fucked up */
  jumpCineRet_AA;

opXLT_B_AA:

  cmp_new = rom [ ( register_PC & 0xF000 ) + register_B ];   /* store new acc value */
  SETA0 ( register_A );           /* store bit0 */
  SETFC ( register_A );
  cmp_old = register_B;           /* back up acc */

  register_B = cmp_new;           /* new acc value */

  register_PC += 2;               /* bump PC twice because XLT is fucked up */
  jumpCineRet_AA;

  /* MUL [i] */
opMULirg_A_AA:
opMULirg_AA_AA:
opMULirg_BB_AA:
  /* MUL's usually happen in batches, so a slight speed bump can be
   * gained by checking for multiple instances and handling in here,
   * without going through the main loop for each.
   */
  temp_word = ram[ register_I ];               /* pick up ramvalue */
  cmp_new = temp_word;

  temp_word <<= 4;                              /* shift into ADD position */
  register_B <<= 4;                             /* get sign bit 15 */
  register_B |= ( register_A >> 8 );            /* bring in A high nibble */

  register_A = ( ( register_A & 0xFF ) << 8 ) | /* shift over 8 bits */
               ( rom [ register_PC ] & 0xFF );  /* pick up opcode */

  temp_byte = rom [ register_PC ] & 0xFF;       /* (for ease and speed) */

  /* handle multiple consecutive MUL's
   */

  register_PC++;                               /* inc PC */
  if ( rom [ register_PC ] != temp_byte ) {    /* next opcode is a MUL? */
    goto opMUL1;                               /* no? skip multiples... */
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL2;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL3;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL4;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL5;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL6;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL7;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL8;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL9;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL10;
  }

  register_PC++;                               /* repeat above */
  if ( rom [ register_PC ] != temp_byte ) {
    goto opMUL11;
  }

opMUL12:
  register_PC++;                               /* we don't bother to check
                                                * for multiple occurances more
                                                * than 12, so just inc the PC
                                                * and not worry about it.
                                                */

  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL11;
  }
  register_B += temp_word;

opMUL11:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL10;
  }
  register_B += temp_word;

opMUL10:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL9;
  }
  register_B += temp_word;

opMUL9:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL8;
  }
  register_B += temp_word;

opMUL8:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL7;
  }
  register_B += temp_word;

opMUL7:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL6;
  }
  register_B += temp_word;

opMUL6:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL5;
  }
  register_B += temp_word;

opMUL5:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL4;
  }
  register_B += temp_word;

opMUL4:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL3;
  }
  register_B += temp_word;

opMUL3:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL2;
  }
  register_B += temp_word;

opMUL2:
  temp_word_2 = ( register_B & 0x01 ) << 15;   /* get low bit for rotation */
  register_B = SAR(register_B,1);              /* signed arith right 1 */
  register_A = ( register_A >> 1 ) |           /* rotate right ... */
               temp_word_2;                    /*   ... via carry flag */
  if ( ! ( register_A & 0x80 ) ) {
    goto opMUL1;
  }
  register_B += temp_word;

opMUL1:

  if ( register_A & 0x100 ) {           /* 1bit shifted out? */
    goto opMULshf;
  }

  register_A = ( register_A >> 8 ) |    /* Bhigh | Alow */
               ( ( register_B & 0xFF ) << 8 );

  temp_word = register_A & 0xFFF;

  SETA0 ( temp_word & 0xFF );                   /* store bit0 */
  cmp_old = temp_word;

  temp_word += cmp_new;
  SETFC ( temp_word );

  register_A >>= 1;
  register_A &= 0xFFF;

  register_B = SAR(register_B,5);
  register_B &= 0xFFF;

  jumpCineRet_AA;

opMULshf: /* part of opMULirg */

  register_A = ( register_A >> 8 ) |
               ( ( register_B & 0xFF ) << 8 );

  SETA0 ( register_A & 0xFF );                  /* store bit0 */

  register_A >>= 1;
  register_A &= 0xFFF;

  register_B = SAR(register_B,4);
  cmp_old = register_B & 0x0F;

  register_B = SAR(register_B,1);

  register_B &= 0xFFF;
  register_B += cmp_new;

  SETFC ( register_B );

  register_B &= 0xFFF;

  jumpCineRet_AA;

opMULirg_B_AA:
  register_PC++;

  temp_word = ram[ register_I ];
  cmp_new = temp_word;
  cmp_old = register_B;
  SETA0 ( register_A & 0xFF );

  register_B <<= 4;

  register_B = SAR(register_B,5);

  if ( register_A & 0x01 ) {
    goto opMULirgB1;
  }

  temp_word += register_B;
  SETFC ( temp_word );

  jumpCineRet_AA;

opMULirgB1:
  register_B += temp_word;
  SETFC ( register_B );
  register_B &= 0x0FFF;
  jumpCineRet_AA;

  /* LSRe */
opLSRe_A_AA:
opLSRe_AA_AA:
opLSRe_BB_AA:
  /* EB; right shift pure; fill new bit with zero.
   */
  temp_word = 0x0BEB;

  register_PC++;

  if ( rom [ register_PC ] == 0xEB ) {
    goto opLSRe_A0; /* multiples */
  }

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A >>= 1;
  jumpCineRet_AA;

opLSRe_A0:
  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;
  if ( rom [ register_PC ] != 0xEB ) {
    goto opLSRe_A1;
  }

  register_A >>= 1;
  register_PC ++;

opLSRe_A1:
  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A >>= 1;
  jumpCineRet_AA;

opLSRe_B_AA:
  UNFINISHED ( "opLSRe B 1\n" );
  jumpCineRet_AA;

opLSRf_A_AA:
opLSRf_AA_AA:
opLSRf_BB_AA:
  UNFINISHED ( "opLSRf 1\n" );
  jumpCineRet_AA;

opLSRf_B_AA:
  UNFINISHED ( "opLSRf 2\n" );
  jumpCineRet_AA;

opLSLe_A_AA:
opLSLe_AA_AA:
opLSLe_BB_AA:
  /* EC; left shift pure; fill new bit with zero */
  /* This version supports multiple consecutive LSLe's; the older
   * version only did one at a time. I'm changing it to make tracing
   * easier (as its comperable to Zonn's)
   */

  register_PC++;
  temp_word = 0x0CEC;

  if ( rom [ register_PC ] == 0xEC ) {
    goto opLSLe_A0; /* do multiples */
  }

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 1;
  register_A &= 0x0FFF;

  jumpCineRet_AA;

opLSLe_A0:
  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1; /* unit begin */
  register_PC++;
  if ( rom [ register_PC ] != 0xEC ) {
    goto opLSLe_A1; /* no more, do last one */
  }

  register_A <<= 1;
  register_PC++;

opLSLe_A1:
  register_A &= 0x0FFF;

opLSLe_A2:
  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 1;
  register_A &= 0x0FFF;

  jumpCineRet_AA;

#if 0 /* non-multiple-consecutive-LSLe's version */
  temp_word = 0x0CEC;                          /* data register */

  cmp_new = temp_word;                         /* magic value */
  SETA0 ( register_A );                        /* back up bit0 */
  cmp_old = register_A;                        /* store old acc */

  temp_word += register_A;                     /* add to acc */
  SETFC ( temp_word );                         /* store carry flag */
  register_A <<= 1;                            /* add regA to itself */
  register_A &= 0xFFF;                         /* toss excess bits */

  register_PC ++;                              /* bump PC */
  jumpCineRet_AA;
#endif

opLSLe_B_AA:
  temp_word = 0x0CEC;                          /* data register */

  cmp_new = temp_word;                         /* magic value */
  SETA0 ( register_A );                        /* back up bit0 */
  cmp_old = register_B;                        /* store old acc */

  temp_word += register_B;                     /* add to acc */
  SETFC ( temp_word );                         /* store carry flag */
  register_B <<= 1;                            /* add regA to itself */
  register_B &= 0xFFF;                         /* toss excess bits */

  register_PC ++;                              /* bump PC */
  jumpCineRet_AA;

opLSLf_A_AA:
opLSLf_AA_AA:
opLSLf_BB_AA:
  UNFINISHED ( "opLSLf 1\n" );
  jumpCineRet_AA;

opLSLf_B_AA:
  UNFINISHED ( "opLSLf 2\n" );
  jumpCineRet_AA;

opASRe_A_AA:
opASRe_AA_AA:
opASRe_BB_AA:
  /* agh! I dislike these silly 12bit processors :P */

  temp_word = 0xDED;

  register_PC ++;

  if ( rom [ register_PC ] == ( temp_word & 0xFF ) ) {
    goto opASRe_A0;
  }

  cmp_new = temp_word;

  SETA0 ( register_A );           /* store bit0 */
  SETFC ( register_A );

  cmp_old = register_A;

  register_A <<= 4; /* get sign bit */
  register_A = SAR(register_A,5);
  register_A &= 0xFFF;

  jumpCineRet_AA;

opASRe_A0:
  /* multiple ASRe's ... handle 'em in a batch, for efficiency
   */

  register_A <<= 4;
  register_A = SAR(register_A,1);

  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opASRe_A1;
  }                               /* end of unit */

  register_A = SAR(register_A,1);
  register_PC++;
  
opASRe_A1:
  /* no more multiples left; finish off.
   */
  register_A >>= 4;

opASRe_A2:
  /* shift once with flags */
  cmp_new = temp_word;

  SETA0 ( register_A );           /* store bit0 */
  SETFC ( register_A );

  cmp_old = register_A;

  register_A <<= 4; /* get sign bit */
  register_A = SAR(register_A,5);
  register_A &= 0xFFF;

  jumpCineRet_AA;

opASRe_B_AA:
  register_PC++;

  if ( ( rom [ register_PC ] == 0xED ) &&
       ( rom [ register_PC + 1 ] == 0x57 ) )
  {
    goto opASRe_B0; /* another one follows, do multiples */
  }

  cmp_new = 0x0DED;
  SETA0 ( register_A );
  SETFC ( register_A );
  cmp_old = register_B;

  register_B <<= 4;
  register_B = SAR(register_B,5);
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opASRe_B0:
  register_B <<= 4;  /* get sign bit */

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;
  if ( ! ( ( rom [ register_PC ] == 0xED ) &&
           ( rom [ register_PC + 1 ] == 0x57 ) ) )
  {
    goto opASRe_B1;
  }

  register_B = SAR(register_B,1);
  register_PC += 2;

opASRe_B1:
  register_B >>= 4; /* fix register */

opASRe_B2:
  cmp_new = 0x0DED;
  SETA0 ( register_A );
  SETFC ( register_A );
  cmp_old = register_B;

  register_B <<= 4;
  register_B = SAR(register_B,5);
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opASRf_A_AA:
opASRf_AA_AA:
opASRf_BB_AA:
  UNFINISHED ( "opASRf 1\n" );
  jumpCineRet_AA;

opASRf_B_AA:
  UNFINISHED ( "opASRf 2\n" );
  jumpCineRet_AA;

opASRDe_A_AA:
opASRDe_AA_AA:
opASRDe_BB_AA:
  /* Arithmetic shift right of D (A+B) .. B is high (sign bits).
   * divide by 2, but leave the sign bit the same. (ie: 1010 -> 1001)
   */
  temp_word = 0x0EEE;
  register_PC++;

  if ( rom [ register_PC ] == ( temp_word & 0xFF ) ) {
    goto opASRDe_A0; /* multiples, do the batch */
  }

  cmp_new = temp_word;          /* save new acc value */
  SETA0 ( register_A & 0xFF );  /* save old accA bit0 */
  cmp_old = register_A;         /* save old acc */

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 4;
  register_B <<= 4;

  temp_word_2 = ( register_B >> 4 ) << 15;
  register_B = SAR(register_B,5);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_A >>= 4;

  register_B &= 0x0FFF;
  jumpCineRet_AA;

opASRDe_A0:
  register_A <<= 4;
  register_B <<= 4;

  temp_word_2 = ( register_B >> 4 ) << 15;
  register_B = SAR(register_B,5);
  register_A = ( register_A >> 1 ) | temp_word_2;

  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more, do last one */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opASRDe_A1; /* no more */
  }

  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;

  register_PC++;

opASRDe_A1:  /* do last shift with flags */
  register_A >>= 4;

  cmp_new = temp_word;
  SETA0 ( register_A & 0xFF );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 4;
  temp_word_2 = ( register_B & 0x01 ) << 15;
  register_B = SAR(register_B,1);
  register_A = ( register_A >> 1 ) | temp_word_2;
  register_A >>= 4;

  register_B &= 0x0FFF;
  jumpCineRet_AA;

opASRDe_B_AA:
  register_PC++;
  temp_word = 0x0EEE;
  cmp_new = temp_word;
  SETA0 ( register_A & 0xFF );
  cmp_old = register_B;

  temp_word += register_B;
  SETFC ( temp_word );
  register_B <<= 4;
  register_B = SAR(register_B,5);
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opASRDf_A_AA:
opASRDf_AA_AA:
opASRDf_BB_AA:
  UNFINISHED ( "opASRDf 1\n" );
  jumpCineRet_AA;

opASRDf_B_AA:
  UNFINISHED ( "opASRDf 2\n" );
  jumpCineRet_AA;

opLSLDe_A_AA:
opLSLDe_AA_AA:
opLSLDe_BB_AA:
  /* LSLDe -- Left shift through both accumulators; lossy in middle. */

  temp_word = 0x0FEF;

  register_PC++;
  if ( rom [ register_PC ] == ( temp_word & 0xFF ) ) {
    goto opLSLDe_A0; /* multiples.. go to it. */
  }

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );
  register_A <<= 1;                             /* logical shift left */
  register_A &= 0xFFF;

  register_B <<= 1;
  register_B &= 0xFFF;

  jumpCineRet_AA;

opLSLDe_A0:
  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC ++;
  if ( ! ( rom [ register_PC ] == ( temp_word & 0xFF ) ) ) {
    goto opLSLDe_A1; /* nope, go do last one */
  }

  register_A <<= 1;
  register_B <<= 1;

  register_PC++;

opLSLDe_A1:
  register_A &= 0xFFF;
  register_B &= 0xFFF;

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );
  register_A <<= 1;                             /* logical shift left */
  register_A &= 0xFFF;

  register_B <<= 1;
  register_B &= 0xFFF;

  jumpCineRet_AA;

opLSLDe_B_AA:
  UNFINISHED ( "opLSLD 1\n" );
  jumpCineRet_AA;

opLSLDf_A_AA:
opLSLDf_AA_AA:
opLSLDf_BB_AA:
  /* LSLDf */

  temp_word = 0x0FFF;

  register_PC++;
  if ( rom [ register_PC ] == ( temp_word & 0xFF ) ) {
    goto opLSLDf_A0; /* do multiple batches */
  }

  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 1;
  register_A &= 0x0FFF;

  register_B <<= 1;
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opLSLDf_A0:

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;  /* unit begin */
  register_B <<= 1;
  register_PC++;
  if ( rom [ register_PC ] != ( temp_word & 0xFF ) ) {
    goto opLSLDf_A1;
  }                  /* unit end */

  register_A <<= 1;
  register_B <<= 1;

  register_PC++;

opLSLDf_A1:
  register_A &= 0x0FFF;
  register_B &= 0x0FFF;

  cmp_new = temp_word;
  SETA0 ( register_A );
  SETFC ( register_A );
  cmp_old = register_A;

  temp_word += register_A;
  SETFC ( temp_word );

  register_A <<= 1;
  register_A &= 0x0FFF;

  register_B <<= 1;
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opLSLDf_B_AA: /* not 'the same' as the A->AA version above */

  register_PC++;

  temp_word = 0x0FFF;
  cmp_new = temp_word;
  SETA0 ( register_A );
  cmp_old = register_B;

  temp_word += register_B;
  SETFC ( temp_word );

  register_B <<= 1;
  register_B &= 0x0FFF;

  jumpCineRet_AA;

opJMP_A_A:
opJMP_AA_A:
opJMP_BB_A:
  /* simple jump; change PC and continue..
   */

  /* Use 0xF000 so as to keep the current page, since it may well
   * have been changed with JPP.
   */
  register_PC = ( register_PC & 0xF000 ) + register_J;  /* pick up new PC */
  jumpCineRet_A;

opJMP_B_BB:
  register_PC = ( register_PC & 0xF000 ) + register_J;  /* pick up new PC */
  jumpCineRet_BB;

opJEI_A_A:
opJEI_AA_A:
opJEI_BB_A:

  if ( ! ( ioOutputs & 0x80 ) ) {
    goto opja1;
  }

  if ( ( FromX - JoyX ) > 0 ) {
    goto opJMP_A_A;
  }

  register_PC ++;   /* increment PC */
  jumpCineRet_A;

opja1:

  if ( ( FromX - JoyY ) > 0 ) {
    goto opJMP_A_A;
  }

  register_PC++;
  jumpCineRet_A;

opJEI_B_BB:

  if ( ! ( ioOutputs & 0x80 ) ) {
    goto opjbb1;
  }

  if ( ( FromX - JoyX ) > 0 ) {
    goto opJMP_B_BB;
  }

  register_PC ++;   /* increment PC */
  jumpCineRet_BB;

opjbb1:

  if ( ( FromX - JoyY ) > 0 ) {
    goto opJMP_B_BB;
  }

  register_PC++;
  jumpCineRet_BB;

opJEI_A_B:
opJEI_AA_B:
opJEI_BB_B:

  if ( ! ( ioOutputs & 0x80 ) ) {
    goto opjb1;
  }

  if ( ( FromX - JoyX ) > 0 ) {
    goto opJMP_A_B;
  }

  register_PC ++;   /* increment PC */
  jumpCineRet_B;

opjb1:

  if ( ( FromX - JoyY ) > 0 ) {
    goto opJMP_A_B;
  }

  register_PC++;
  jumpCineRet_B;

opJMI_A_A:
  /* previous instruction was not an ACC instruction, nor was the
   * instruction twice back a USB, therefore minus flag test the
   * current A-reg
   */

  /* negative acc? */
  if ( register_A & 0x800 ) {
    goto opJMP_A_A;  /* yes -- do jump */
  }

  register_PC ++;   /* increment PC */
  jumpCineRet_A;

opJMI_AA_A:
  /* previous acc negative? Jump if so... */
  if ( cmp_old & 0x800 ) {
    goto opJMP_AA_A;
  }
  register_PC++;
  jumpCineRet_A;

opJMI_BB_A:
  if ( register_B & 0x800 ) {
    goto opJMP_BB_A;
  }
  register_PC++;
  jumpCineRet_A;

opJMI_B_BB:
  if ( register_A & 0x800 ) {
    goto opJMP_B_BB;
  }
  register_PC++;
  jumpCineRet_BB;

opJLT_A_A:
opJLT_AA_A:
opJLT_BB_A:
  /* jump if old acc equals new acc */

  if ( cmp_new < cmp_old ) {
    goto opJMP_A_A;
  }

  register_PC ++;
  jumpCineRet_A;

opJLT_B_BB:
  if ( cmp_new < cmp_old ) {
    goto opJMP_B_BB;
  }
  register_PC ++;
  jumpCineRet_BB;

opJEQ_A_A:
opJEQ_AA_A:
opJEQ_BB_A:
  /* jump if equal */

  if ( cmp_new == cmp_old ) {
    goto opJMP_A_A;
  }
  register_PC++;                            /* bump PC */
  jumpCineRet_A;

opJEQ_B_BB:

  if ( cmp_new == cmp_old ) {
    goto opJMP_B_BB;
  }
  register_PC++;                            /* bump PC */
  jumpCineRet_BB;

opJA0_A_A:
opJA0_AA_A:
opJA0_BB_A:

  if ( acc_a0 & 0x01 ) {
    goto opJMP_A_A;
  }

  register_PC ++;                               /* bump PC */
  jumpCineRet_A;

opJA0_B_BB:
  if ( acc_a0 & 0x01 ) {
    goto opJMP_B_BB;
  }

  register_PC ++;                               /* bump PC */
  jumpCineRet_BB;

opJNC_A_A:
opJNC_AA_A:
opJNC_BB_A:

  if ( ! ( GETFC() & 0xF0 ) ) {
    goto opJMP_A_A; /* no carry, so jump */
  }
  register_PC ++;

  jumpCineRet_A;

opJNC_B_BB:
  if ( ! ( GETFC() & 0xF0 ) ) {
    goto opJMP_B_BB; /* no carry, so jump */
  }
  register_PC ++;

  jumpCineRet_BB;

opJDR_A_A:
opJDR_AA_A:
opJDR_BB_A:
  /*
   * ; Calculate number of cycles executed since
   * ; last 'VDR' instruction, add two and use as
   * ; cycle count, never branch
   */
  register_PC ++;
  jumpCineRet_A;

opJDR_B_BB:
  /*
   * ; Calculate number of cycles executed since
   * ; last 'VDR' instruction, add two and use as
   * ; cycle count, never branch
   */
  register_PC ++;
  jumpCineRet_BB;

opNOP_A_A:
opNOP_AA_A:
opNOP_BB_A:
  register_PC++;
  jumpCineRet_A;

opNOP_B_BB:
  register_PC++;
  jumpCineRet_BB;

opJPP32_A_B:
opJPP32_AA_B:
opJPP32_BB_B:
  /* ; 00 = Offset 0000h
   * ; 01 = Offset 1000h
   * ; 02 = Offset 2000h
   * ; 03 = Offset 3000h
   * ; 04 = Offset 4000h
   * ; 05 = Offset 5000h
   * ; 06 = Offset 6000h
   * ; 07 = Offset 7000h
   */
  temp_word = ( register_P & 0x07 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_B;

opJPP32_B_BB:
  temp_word = ( register_P & 0x07 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_BB;

opJPP16_A_B:
opJPP16_AA_B:
opJPP16_BB_B:
  /* ; 00 = Offset 0000h
   * ; 01 = Offset 1000h
   * ; 02 = Offset 2000h
   * ; 03 = Offset 3000h
   */
  temp_word = ( register_P & 0x03 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_B;

opJPP16_B_BB:
  temp_word = ( register_P & 0x03 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_BB;

opJMP_A_B:
  register_PC = ( register_PC & 0xF000 ) + register_J;  /* pick up new PC */
  jumpCineRet_B;

opJPP8_A_B:
opJPP8_AA_B:
opJPP8_BB_B:
  /* "long jump"; combine P and J to jump to a new far location (that can
   * be more than 12 bits in address). After this jump, further jumps
   * are local to this new page.
   */
  temp_word = ( ( register_P & 0x03 ) - 1 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_B;

opJPP8_B_BB:
  temp_word = ( ( register_P & 0x03 ) - 1 ) << 12;  /* rom offset */
  register_PC = register_J + temp_word;
  jumpCineRet_BB;

opJMI_A_B:
  if ( register_A & 0x800 ) {
    goto opJMP_A_B;
  }
  register_PC++;
  jumpCineRet_B;

opJMI_AA_B:
  UNFINISHED ( "opJMI 3\n" );
  jumpCineRet_B;

opJMI_BB_B:
  UNFINISHED ( "opJMI 4\n" );
  jumpCineRet_B;

opJLT_A_B:
opJLT_AA_B:
opJLT_BB_B:
  if ( cmp_new < cmp_old ) {
    goto opJMP_A_B;
  }
  register_PC ++;
  jumpCineRet_B;

opJEQ_A_B:
opJEQ_AA_B:
opJEQ_BB_B:
  if ( cmp_new == cmp_old ) {
    goto opJMP_A_B;
  }
  register_PC++;                            /* bump PC */
  jumpCineRet_B;

opJA0_A_B:
opJA0_AA_B:
opJA0_BB_B:

  if ( GETA0() & 0x01 ) {
    goto opJMP_A_B;
  }
  register_PC++;

  jumpCineRet_B;

opJNC_A_B:
opJNC_AA_B:
opJNC_BB_B:

  if ( ! ( GETFC() & 0x0F0 ) ) {
    goto opJMP_A_B; /* if no carry, jump */
  }
  register_PC++;

  jumpCineRet_B;

opJDR_A_B:
opJDR_AA_B:
opJDR_BB_B:
  /* register_PC++; */

  jumpCineRet_B;

  /* NOP */
opNOP_A_B:
opNOP_AA_B:
opNOP_BB_B:
  register_PC++;                          /* NOP; bump PC only */
  jumpCineRet_B;

opLLT_A_AA:
opLLT_AA_AA:
opLLT_BB_AA:

  register_PC++;
  temp_byte = 0;

opLLTa1:
  temp_word = register_A >> 8;         /* register_A's high bits */
  temp_word &= 0x0A;                   /* only want PA11 and PA9 */

  if ( ! temp_word ) {
    goto opLLTa2;                      /* zero, no mismatch */
  }

  temp_word ^= 0x0A;                   /* flip the bits */

  if ( temp_word ) {
    goto opLLTa4;                      /* if not zero, mismatch found */
  }

opLLTa2:
  temp_word = register_B >> 8;         /* regB's top bits */
  temp_word &= 0x0A;                   /* only want SA11 and SA9 */

  if ( ! temp_word ) {
    goto opLLTa3;                      /* if zero, no mismatch */
  }

  temp_word ^= 0x0A;                   /* flip bits */

  if ( temp_word ) {
    goto opLLTa4;                      /* if not zero, mismatch found */
  }

opLLTa3:
  register_A <<= 1;                    /* shift regA */
  register_B <<= 1;                    /* shift regB */

  temp_byte ++;
  if ( temp_byte ) {
    goto opLLTa1;                      /* try again */
  }
  jumpCineRet_AA;

opLLTa4:
  vgShiftLength = temp_byte;
  register_A &= 0x0FFF;
  register_B &= 0x0FFF;

opLLTaErr:
  jumpCineRet_AA;

opLLT_B_AA:
  UNFINISHED ( "opLLT 1\n" );
  jumpCineRet_AA;

opVIN_A_A:
opVIN_AA_A:
opVIN_BB_A:
  /* set the starting address of a vector */

  FromX = register_A & 0xFFF;            /* regA goes to x-coord */
  FromY = register_B & 0xFFF;            /* regB goes to y-coord */

  register_PC ++;                             /* bump PC */
  jumpCineRet_A;

opVIN_B_BB:

  FromX = register_A & 0xFFF;            /* regA goes to x-coord */
  FromY = register_B & 0xFFF;            /* regB goes to y-coord */

  register_PC ++;                             /* bump PC */
  jumpCineRet_BB;

opWAI_A_A:
opWAI_AA_A:
opWAI_BB_A:
  /* wait for a tick on the watchdog
   */
  bNewFrame = 1;
  register_PC ++;
  goto cineExit;

opWAI_B_BB:
  bNewFrame = 1;
  register_PC ++;
  goto cineExit;

opVDR_A_A:
opVDR_AA_A:
opVDR_BB_A:
  /* set ending points and draw the vector, or buffer for a later draw.
   */
  {
    int ToX = register_A & 0xFFF;
    int ToY = register_B & 0xFFF;

    /* shl 20, sar 20; this means that if the CCPU reg should be -ve,
     * we should be negative as well.. sign extended.
     */
    if ( FromX & 0x800 ) {
      FromX |= 0xFFFFF000;
    }
    if ( ToX & 0x800 ) {
      ToX |= 0xFFFFF000;
    }
    if ( FromY & 0x800 ) {
      FromY |= 0xFFFFF000;
    }
    if ( ToY & 0x800 ) {
      ToY |= 0xFFFFF000;
    }

    /* figure out the vector
     */

    ToX -= FromX;
    ToX = SAR(ToX,vgShiftLength);
    ToX += FromX;

    ToY -= FromY;
    ToY = SAR(ToY,vgShiftLength);
    ToY += FromY;

    /* do orientation flipping, etc.
     */
    if ( ! bFlipX ) {
      goto noFlipX1;
    }

    ToX = sdwGameXSize - ToX;
    FromX = sdwGameXSize - FromX;

  noFlipX1:
    if ( ! bFlipY ) {
      goto noFlipY1;
    }
    
    ToY = sdwGameYSize - ToY;
    FromY = sdwGameYSize - FromY;

  noFlipY1:
    FromX += sdwXOffset;
    ToX += sdwXOffset;

    FromY += sdwYOffset;
    ToY += sdwYOffset;

    /* check real coords */
    if ( ! bSwapXY ) {
      goto noSwapXY2;
    }

    temp_word = ToY;
    ToY = ToX;
    ToX = temp_word;

    temp_word = FromY;
    FromY = FromX;
    FromX = temp_word;

  noSwapXY2:
    /* render the line
     */

    CinemaVectorData ( FromX, FromY,
                       ToX, ToY, 
                       vgColour + 0x0F );

  }

  register_PC++;
  jumpCineRet_A;

opVDR_B_BB:
  UNFINISHED ( "opVDR B 1\n" );
  jumpCineRet_BB;

/* some code needs to be changed based on the machine or switches set.
 * Instead of getting disorganized, I'll put the extra dispatchers
 * here. The main dispatch loop jumps here, checks options, and
 * redispatches to the actual opcode handlers.
 */

/* JPP series of opcodes
 */
tJPP_A_B:
  /* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */
  switch ( ccpu_msize ) {
  case 0:
  case 1:
    goto opJPP8_A_B;
    break;
  case 2:
    goto opJPP16_A_B;
    break;
  case 3:
    goto opJPP32_A_B;
    break;
  }


tJPP_AA_B:
  /* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */
  switch ( ccpu_msize ) {
  case 0:
  case 1:
    goto opJPP8_AA_B;
    break;
  case 2:
    goto opJPP16_AA_B;
    break;
  case 3:
    goto opJPP32_AA_B;
    break;
  }


tJPP_B_BB:
  /* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */
  switch ( ccpu_msize ) {
  case 0:
  case 1:
    goto opJPP8_B_BB;
    break;
  case 2:
    goto opJPP16_B_BB;
    break;
  case 3:
    goto opJPP32_B_BB;
    break;
  }


tJPP_BB_B:
  /* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */
  switch ( ccpu_msize ) {
  case 0:
  case 1:
    goto opJPP8_BB_B;
    break;
  case 2:
    goto opJPP16_BB_B;
    break;
  case 3:
    goto opJPP32_BB_B;
    break;
  }


/* JMI series of opcodes
 */

tJMI_A_B:
  if ( ccpu_jmi_dip ) {
    goto opJMI_A_B;
  } else {
    goto opJEI_A_B;
  }

tJMI_A_A:
  if ( ccpu_jmi_dip ) {
    goto opJMI_A_A;
  } else {
    goto opJEI_AA_B;
  }

tJMI_AA_B:
  if ( ccpu_jmi_dip ) {
    goto opJMI_AA_B;
  } else {
    goto opJEI_AA_B;
  }

tJMI_AA_A:
  if ( ccpu_jmi_dip ) {
    goto opJMI_AA_A;
  } else {
    goto opJEI_AA_A;
  }

tJMI_B_BB1:
  if ( ccpu_jmi_dip ) {
    goto opJMI_B_BB;
  } else {
    goto opJEI_B_BB;
  }

tJMI_B_BB2:
  if ( ccpu_jmi_dip ) {
    goto opJMI_B_BB;
  } else {
    goto opJEI_B_BB;
  }

tJMI_BB_B:
  if ( ccpu_jmi_dip ) {
    goto opJMI_BB_B;
  } else {
    goto opJEI_BB_B;
  }

tJMI_BB_A:
  if ( ccpu_jmi_dip ) {
    goto opJMI_BB_A;
  } else {
    goto opJEI_BB_A;
  }

/* OUT series of opcodes:
 * ccpu_monitor can be one of:
 * 1 -- 16-level colour
 * 2 -- 64-level colour
 * 3 -- War of the Worlds colour
 * other -- bi-level
 */
tOUT_A_A:
  switch ( ccpu_monitor ) {
  case 1:
    goto opOUT16_A_A;
    break;
  case 2:
    goto opOUT64_A_A;
    break;
  case 3:
    goto opOUTWW_A_A;
    break;
  default:
    goto opOUTbi_A_A;
  }

  goto opOUTbi_A_A;

tOUT_AA_A:
  switch ( ccpu_monitor ) {
  case 1:
    goto opOUT16_AA_A;
    break;
  case 2:
    goto opOUT64_AA_A;
    break;
  case 3:
    goto opOUTWW_AA_A;
    break;
  default:
    goto opOUTbi_AA_A;
  }

  goto opOUTbi_A_A;

tOUT_B_BB:
  switch ( ccpu_monitor ) {
  case 1:
    goto opOUT16_B_BB;
    break;
  case 2:
    goto opOUT64_B_BB;
    break;
  case 3:
    goto opOUTWW_B_BB;
    break;
  default:
    goto opOUTbi_B_BB;
  }

  goto opOUTbi_A_A;

tOUT_BB_A:
  switch ( ccpu_monitor ) {
  case 1:
    goto opOUT16_BB_A;
    break;
  case 2:
    goto opOUT64_BB_A;
    break;
  case 3:
    goto opOUTWW_BB_A;
    break;
  default:
    goto opOUTbi_BB_A;
  }

  goto opOUTbi_A_A;

  /* opcode exit point (so we can catch and do debugging, etc.
   */
cineExecBottom:

#ifdef CCPUDEBUG
  /* handle debugger */
  if ( ccpudebug ) {
    disassemble ( disassembly, sizeof ( disassembly ), original_PC );
  }
#endif

#ifdef CCPUBREAK
  /* make adding opcodes easier..
   */
  if ( ccpubreak ) {
    if ( original_PC == register_PC ) {
      repeat_count++;

      if ( repeat_count == 1 ) {
        repeat_count = 0;    /* in case we don't want it to exit.. */
        exit ( 0 );
      }

    }

  }
#endif

  /* the opcode code has set a state and done mischief with flags and
   * the programcounter; now jump back to the top and run through another
   * opcode.
   */
#ifndef CCPUSSTEP
  if ( bBailOut == FALSE ) {
         goto cineExecTop;
  }
#endif

cineExit:
  /* return control to main system
   */
  dwElapsedTicks = 100000; /* some magic number */

  return ( 0x80000000 );
}

/* Reset C-CPU registers, flags, etc to default starting values
 */
void cineReset(void) {

  /* ensure the context has been set at least once */
  RASSERT ( rom );

  /* zero registers */
  register_PC = 0;
  register_A = 0;
  register_B = 0;
  register_I = 0;
  register_J = 0;
  register_P = 0;
  FromX = 0;
  FromY = 0;
  register_T = 0;

  /* zero flags */
  flag_C = 0;

  /* reset state */
  state = 0;

  /* reset */ram
        memset(ram, 0, sizeof(ram));

  /* reset internal state */
  cmp_old = 0;
  cmp_new = 0;
  SETA0 ( 0 );

}

void cineSetJMI(UINT8 j) {
  ccpu_jmi_dip = j;


}

void cineSetMSize(UINT8 m) {
  ccpu_msize = m;

}

void cineSetMonitor(UINT8 m) {
  ccpu_monitor = m;
}

void cSetContext(void *p) {
        CONTEXTCCPU *c = p;
  cmp_old = c -> accVal;
  cmp_new = c -> cmpVal;
  rom = c -> cineBase;
  SETA0 ( c -> pa0 );
  flag_C = c -> cFlag;
  register_PC = c -> eRegPC;
  register_A = c -> eRegA;
  register_B = c -> eRegB;
  register_I = c -> eRegI;
  register_J = c -> eRegJ;
  register_P = c -> eRegP;
  state = c -> eCState;

}

void cGetContext(void *p) {

        CONTEXTCCPU *c = p;

  c -> accVal = cmp_old;
  c -> cmpVal = cmp_new;
  c -> cineBase = rom;
  c -> pa0 = GETA0();
  c -> cFlag = GETFC();
  c -> eRegPC = register_PC;
  c -> eRegA = register_A;
  c -> eRegB = register_B;
  c -> eRegI = register_I;
  c -> eRegJ = register_J;
  c -> eRegP = register_P;
  c -> eCState = state;
}

UINT32 cineGetElapsedTicks ( UINT32 dwClearIt ) {
  UINT32 dwTemp;

  dwTemp = dwElapsedTicks;
  if ( dwClearIt ) {
         dwElapsedTicks = 0;
  }

  return ( dwTemp );
}

void cineReleaseTimeslice ( void ) {
  bBailOut = TRUE;
}

UINT32 cGetContextSize(void) {
  return ( sizeof ( CONTEXTCCPU ) );
}

/* extra functions
 */

/* disassemble() appends a disassembly of the specified address to
 * the end of the specified text buffer.
 */
void disassemble ( char *buffer, unsigned int maxlen, unsigned int address ) {
#ifdef CCPUDEBUG
  char ambuffer [ 40 ];   /* text buffer for addressing mode values */
  char opbuffer [ 40 ];   /* text buffer for opcodes etc. */
  char flbuffer [ 80 ];   /* text buffer for flag dump */
  CINEBYTE opcode;
  CINEBYTE opsize = 1;
  int iter = 0;

  /* which opcode in opcode table? (includes immediate data) */
  opcode = rom [ address ];

  /* build addressing mode (value to opcode) */

        memset(ambuffer, 0, sizeof(ambuffer));
  switch ( amodes [ opcode_table [ opcode ].ot_amode ].ad_amode ) {

  /* 4-bit immediate value */
  case AIM4:
  case IM4:
    sprintf ( ambuffer, "#$%X", opcode & 0x0F );
    break;

  /* 4-bit extended immediate value */
  case AIM4X:
    sprintf ( ambuffer, "#$%X", ( opcode & 0x0F ) << 8 );
    break;

  /* 8-bit immediate value */
  case AIM8:
    sprintf ( ambuffer, "#$%02X", rom [ address + 1 ] );
    opsize ++; /* required second byte for value */
    break;

  /* [m] -- indirect through memory */
  case AINDM:
    sprintf ( ambuffer, "AINDM/Error" );
    break;

  /* [i] -- indirect through 'I' */
  case AIRG:
  case IRG:
    sprintf ( ambuffer, "[i]" );
    break;

  /* extended 12-bit immediate value */
  case AIMX:
    sprintf ( ambuffer, "AIMX/Error" );
    break;

  /* no special params */
  case ACC:
  case AXLT:
  case IMP:
    ambuffer [ 0 ] = '\0';
    break;

  /* 12-bit immediate value */
  case IM12:
    sprintf ( ambuffer, "#$%03X",
              ( rom [ address ] & 0x0F ) +
              ( rom [ address + 1 ] & 0xF0 ) +
              ( ( rom [ address + 1 ] & 0x0F ) << 8 ) );
    opsize ++;
    break;

  /* display address of direct addressing modes */
  case ADIR:
  case DIR:
    sprintf ( ambuffer, "$%X", opcode & 0x0F );
    break;

  /* jump through J register */
  case JUMP:
    sprintf ( ambuffer, "<jump>" );
    break;

  /* extended jump */
  case JUMPX:
    sprintf ( ambuffer, "JUMPX/Error" );
    break;

  } /* switch on addressing mode */

  /* build flags dump */
  sprintf ( flbuffer,
            "A=%03X B=%03X I=%03XZ J=%03X P=%X " \
            "A0=%02X %02X N%X O%X %c%c%c%c",
            register_A, register_B,
            register_I << 1,               /* use the <<1 for Zonn style */
            register_J, register_P, GETA0(),
            GETFC() /* ? 'C' : 'c' */,
            cmp_new, cmp_old,
            ( ( state == state_A ) || ( state == state_AA ) ) ? 'A' : ' ',
            ( state == state_AA ) ? 'A' : ' ',
            ( ( state == state_B ) || ( state == state_BB ) ) ? 'B' : ' ',
            ( state == state_BB ) ? 'B' : ' ' );

  /* build the final output string. Format is as follows:
   * ADDRESS: OPCODE-ROM-DUMP\tOPCODE VALUE\tFLAGS
   */

  /* append complete opcode ROM dump */
        memset(opbuffer, 0, sizeof(opbuffer));
  for ( iter = 0; iter < opsize; iter++ ) {
    sprintf ( opbuffer + ( iter * 3 ), " %02X", rom [ address + iter ] );
  }
 
  /* create final output */
  sprintf ( buffer, "%04X:%-6s : %-4s %-6s : %s",
            address, opbuffer,
            opcodes [ opcode_table [ opcode ].ot_opcode ].od_name,
            ambuffer,
            flbuffer );

#endif

  return;
}

#endif

/* ----------------------------------------------- Trace debugger cinedbg.c */

/* handy macros
 */

void disassemble ( char *buffer, unsigned int maxlen, unsigned int address );

#define START(x) { \
  fprintf ( stderr, "Entered C-CPU function: %s\n", x ); \
}

#define STOP(x) { \
  fprintf ( stderr, "Left C-CPU function: %s\n", x ); \
}

/* opcode tables for debugging
 */
typedef enum {
  CLR,  LDA,  INP,  ADD,  SUB,  LDJ,  LDP,  OUT,
  CMP,  LDI,  STA,  VIN,  VDR,  XLT,  MUL,  LLT,
  WAI,  AWD,  AND,  LSR,  LSL,  ASR,  ASRD, LSLD,
  JPPB, JMIB, JDRB, JLTB, JEQB, JNCB, JAOB, NOPB,
  JMPA, JMIA, JDRA, JLTA, JEQA, JNCA, JAOA, NOPA,
  JEIA, JEIB
} opcode_mnemonics;

typedef struct {
  opcode_mnemonics od_opcode;
  char *od_name;
} opcode_detail;

opcode_detail opcodes[] = {
  { CLR, "clr" },
  { LDA, "lda" },
  { INP, "inp" },
  { ADD, "add" },
  { SUB, "sub" },
  { LDJ, "ldj" },
  { LDP, "ldp" },
  { OUT, "out" },
  { CMP, "cmp" },
  { LDI, "ldi" },
  { STA, "sta" },
  { VIN, "vin" },
  { VDR, "vdr" },
  { XLT, "xlt" },
  { MUL, "mul" },
  { LLT, "llt" },
  { WAI, "wai" },
  { AWD, "awd" },
  { AND, "and" },
  { LSR, "lsr" },
  { LSL, "lsl" },
  { ASR, "asr" },
  { ASRD, "asrd" },
  { LSLD, "lsld" },
  { JPPB, "jppb" },
  { JMIB, "jmib" },
  { JDRB, "jdrb" },
  { JLTB, "jltb" },
  { JEQB, "jeqb" },
  { JNCB, "jncb" },
  { JAOB, "jaob" },
  { NOPB, "nopb" },
  { JMPA, "jmpa" },
  { JMIA, "jmia" },
  { JDRA, "jdra" },
  { JLTA, "jlta" },
  { JEQA, "jeqa" },
  { JNCA, "jnca" },
  { JAOA, "jaoa" },
  { NOPA, "nopa" },
  { JEIA, "jeia" },
  { JEIB, "jeib" }
};

typedef enum {
  ACC,          // Accumulator
  ADIR,         // Acc Direct memory access
  AIM4,         // Acc 4 bit immediate
  AIM4X,        // Acc 4 bit immediate extended size
  AIM8,         // Acc 8 bit immediate
  AINDM,        // Acc indirect through memory
  AIMX,         // Acc immediate extended A-reg
  AXLT,         // Acc lookup ROM using Acc as pointer
  AIRG,         // Acc Through the I-reg
  IRG,          // Through the I-reg
  IM4,          // 4 bit immediate
  IM12,         // 12 bit immediate
  DIR,          // Direct memory access
  IMP,          // Implied
  JUMP,         // Acc selection/Jump instruction
  JUMPX         // Acc selection/Extended jump instruction
} amode_mnemonics;

typedef struct {
  amode_mnemonics ad_amode;
  char *ad_name;
} amode_detail;

amode_detail amodes[] = {
  { ACC,   "acc" },
  { ADIR,  "adir" },
  { AIM4,  "aim4" },
  { AIM4X, "aim4x" },
  { AIM8,  "aim8" },
  { AINDM, "aindm" },
  { AIMX,  "aimx" },
  { AXLT,  "axlt" },
  { AIRG,  "airg" },
  { IRG,   "irg" },
  { IM4,   "im4" },
  { IM12,  "im12" },
  { DIR,   "dir" },
  { IMP,   "imp" },
  { JUMP,  "jump" },
  { JUMPX, "jumpx" }
};

typedef struct {
  opcode_mnemonics ot_opcode;
  amode_mnemonics  ot_amode;
} opcode_table_entry;

opcode_table_entry opcode_table[] = {
  { CLR, ACC   },                       // 00
  { LDA, AIM4X },                       // 01
  { LDA, AIM4X },                       // 02
  { LDA, AIM4X },                       // 03
  { LDA, AIM4X },                       // 04
  { LDA, AIM4X },                       // 05
  { LDA, AIM4X },                       // 06
  { LDA, AIM4X },                       // 07
  { LDA, AIM4X },                       // 08
  { LDA, AIM4X },                       // 09
  { LDA, AIM4X },                       // 0A
  { LDA, AIM4X },                       // 0B
  { LDA, AIM4X },                       // 0C
  { LDA, AIM4X },                       // 0D
  { LDA, AIM4X },                       // 0E
  { LDA, AIM4X },                       // 0F

  { INP, ADIR },                        // 10
  { INP, ADIR },                        // 11
  { INP, ADIR },                        // 12
  { INP, ADIR },                        // 13
  { INP, ADIR },                        // 14
  { INP, ADIR },                        // 15
  { INP, ADIR },                        // 16
  { INP, ADIR },                        // 17
  { INP, ADIR },                        // 18
  { INP, ADIR },                        // 19
  { INP, ADIR },                        // 1A
  { INP, ADIR },                        // 1B
  { INP, ADIR },                        // 1C
  { INP, ADIR },                        // 1D
  { INP, ADIR },                        // 1E
  { INP, ADIR },                        // 1F

  { ADD, AIM8 },                        // 20
  { ADD, AIM4 },                        // 21
  { ADD, AIM4 },                        // 22
  { ADD, AIM4 },                        // 23
  { ADD, AIM4 },                        // 24
  { ADD, AIM4 },                        // 25
  { ADD, AIM4 },                        // 26
  { ADD, AIM4 },                        // 27
  { ADD, AIM4 },                        // 28
  { ADD, AIM4 },                        // 29
  { ADD, AIM4 },                        // 2A
  { ADD, AIM4 },                        // 2B
  { ADD, AIM4 },                        // 2C
  { ADD, AIM4 },                        // 2D
  { ADD, AIM4 },                        // 2E
  { ADD, AIM4 },                        // 2F

  { SUB, AIM8 },                        // 30
  { SUB, AIM4 },                        // 31
  { SUB, AIM4 },                        // 32
  { SUB, AIM4 },                        // 33
  { SUB, AIM4 },                        // 34
  { SUB, AIM4 },                        // 35
  { SUB, AIM4 },                        // 36
  { SUB, AIM4 },                        // 37
  { SUB, AIM4 },                        // 38
  { SUB, AIM4 },                        // 39
  { SUB, AIM4 },                        // 3A
  { SUB, AIM4 },                        // 3B
  { SUB, AIM4 },                        // 3C
  { SUB, AIM4 },                        // 3D
  { SUB, AIM4 },                        // 3E
  { SUB, AIM4 },                        // 3F

  { LDJ, IM12 },                        // 40
  { LDJ, IM12 },                        // 41
  { LDJ, IM12 },                        // 42
  { LDJ, IM12 },                        // 43
  { LDJ, IM12 },                        // 44
  { LDJ, IM12 },                        // 45
  { LDJ, IM12 },                        // 46
  { LDJ, IM12 },                        // 47
  { LDJ, IM12 },                        // 48
  { LDJ, IM12 },                        // 49
  { LDJ, IM12 },                        // 4A
  { LDJ, IM12 },                        // 4B
  { LDJ, IM12 },                        // 4C
  { LDJ, IM12 },                        // 4D
  { LDJ, IM12 },                        // 4E
  { LDJ, IM12 },                        // 4F

  { JPPB, JUMP },                       // 50
  { JMIB, JUMP },                       // 51
  { JDRB, JUMP },                       // 52
  { JLTB, JUMP },                       // 53
  { JEQB, JUMP },                       // 54
  { JNCB, JUMP },                       // 55
  { JAOB, JUMP },                       // 56
  { NOPB, IMP },                        // 57

  { JMPA, JUMP },                       // 58
  { JMIA, JUMP },                       // 59
  { JDRA, JUMP },                       // 5A
  { JLTA, JUMP },                       // 5B
  { JEQA, JUMP },                       // 5C
  { JNCA, JUMP },                       // 5D
  { JAOA, JUMP },                       // 5E
  { NOPA, IMP },                        // 5F

  { ADD, ADIR },                        // 60
  { ADD, ADIR },                        // 61
  { ADD, ADIR },                        // 62
  { ADD, ADIR },                        // 63
  { ADD, ADIR },                        // 64
  { ADD, ADIR },                        // 65
  { ADD, ADIR },                        // 66
  { ADD, ADIR },                        // 67
  { ADD, ADIR },                        // 68
  { ADD, ADIR },                        // 69
  { ADD, ADIR },                        // 6A
  { ADD, ADIR },                        // 6B
  { ADD, ADIR },                        // 6C
  { ADD, ADIR },                        // 6D
  { ADD, ADIR },                        // 6E
  { ADD, ADIR },                        // 6F

  { SUB, ADIR },                        // 70
  { SUB, ADIR },                        // 71
  { SUB, ADIR },                        // 72
  { SUB, ADIR },                        // 73
  { SUB, ADIR },                        // 74
  { SUB, ADIR },                        // 75
  { SUB, ADIR },                        // 76
  { SUB, ADIR },                        // 77
  { SUB, ADIR },                        // 78
  { SUB, ADIR },                        // 79
  { SUB, ADIR },                        // 7A
  { SUB, ADIR },                        // 7B
  { SUB, ADIR },                        // 7C
  { SUB, ADIR },                        // 7D
  { SUB, ADIR },                        // 7E
  { SUB, ADIR },                        // 7F

  { LDP, IM4  },                        // 80
  { LDP, IM4  },                        // 81
  { LDP, IM4  },                        // 82
  { LDP, IM4  },                        // 83
  { LDP, IM4  },                        // 84
  { LDP, IM4  },                        // 85
  { LDP, IM4  },                        // 86
  { LDP, IM4  },                        // 87
  { LDP, IM4  },                        // 88
  { LDP, IM4  },                        // 89
  { LDP, IM4  },                        // 8A
  { LDP, IM4  },                        // 8B
  { LDP, IM4  },                        // 8C
  { LDP, IM4  },                        // 8D
  { LDP, IM4  },                        // 8E
  { LDP, IM4  },                        // 8F

  { OUT, ADIR },                        // 90
  { OUT, ADIR },                        // 91
  { OUT, ADIR },                        // 92
  { OUT, ADIR },                        // 93
  { OUT, ADIR },                        // 94
  { OUT, ADIR },                        // 95
  { OUT, ADIR },                        // 96
  { OUT, ADIR },                        // 97
  { OUT, ADIR },                        // 98
  { OUT, ADIR },                        // 99
  { OUT, ADIR },                        // 9A
  { OUT, ADIR },                        // 9B
  { OUT, ADIR },                        // 9C
  { OUT, ADIR },                        // 9D
  { OUT, ADIR },                        // 9E
  { OUT, ADIR },                        // 9F

  { LDA, ADIR },                        // A0
  { LDA, ADIR },                        // A1
  { LDA, ADIR },                        // A2
  { LDA, ADIR },                        // A3
  { LDA, ADIR },                        // A4
  { LDA, ADIR },                        // A5
  { LDA, ADIR },                        // A6
  { LDA, ADIR },                        // A7
  { LDA, ADIR },                        // A8
  { LDA, ADIR },                        // A9
  { LDA, ADIR },                        // AA
  { LDA, ADIR },                        // AB
  { LDA, ADIR },                        // AC
  { LDA, ADIR },                        // AD
  { LDA, ADIR },                        // AE
  { LDA, ADIR },                        // AF

  { CMP, ADIR },                        // B0
  { CMP, ADIR },                        // B1
  { CMP, ADIR },                        // B2
  { CMP, ADIR },                        // B3
  { CMP, ADIR },                        // B4
  { CMP, ADIR },                        // B5
  { CMP, ADIR },                        // B6
  { CMP, ADIR },                        // B7
  { CMP, ADIR },                        // B8
  { CMP, ADIR },                        // B9
  { CMP, ADIR },                        // BA
  { CMP, ADIR },                        // BB
  { CMP, ADIR },                        // BC
  { CMP, ADIR },                        // BD
  { CMP, ADIR },                        // BE
  { CMP, ADIR },                        // BF

  { LDI, DIR  },                        // C0
  { LDI, DIR  },                        // C1
  { LDI, DIR  },                        // C2
  { LDI, DIR  },                        // C3
  { LDI, DIR  },                        // C4
  { LDI, DIR  },                        // C5
  { LDI, DIR  },                        // C6
  { LDI, DIR  },                        // C7
  { LDI, DIR  },                        // C8
  { LDI, DIR  },                        // C9
  { LDI, DIR  },                        // CA
  { LDI, DIR  },                        // CB
  { LDI, DIR  },                        // CC
  { LDI, DIR  },                        // CD
  { LDI, DIR  },                        // CE
  { LDI, DIR  },                        // CF

  { STA, ADIR },                        // D0
  { STA, ADIR },                        // D1
  { STA, ADIR },                        // D2
  { STA, ADIR },                        // D3
  { STA, ADIR },                        // D4
  { STA, ADIR },                        // D5
  { STA, ADIR },                        // D6
  { STA, ADIR },                        // D7
  { STA, ADIR },                        // D8
  { STA, ADIR },                        // D9
  { STA, ADIR },                        // DA
  { STA, ADIR },                        // DB
  { STA, ADIR },                        // DC
  { STA, ADIR },                        // DD
  { STA, ADIR },                        // DE
  { STA, ADIR },                        // DF

  { VDR, IMP  },                        // E0
  { LDJ, IRG  },                        // E1
  { XLT, AXLT },                        // E2
  { MUL, IRG  },                        // E3
  { LLT, IMP  },                        // E4
  { WAI, IMP  },                        // E5
  { STA, AIRG },                        // E6
  { ADD, AIRG },                        // E7
  { SUB, AIRG },                        // E8
  { AND, AIRG },                        // E9
  { LDA, AIRG },                        // EA
  { LSR, ACC  },                        // EB
  { LSL, ACC  },                        // EC
  { ASR, ACC  },                        // ED
  { ASRD, IMP },                        // EE
  { LSLD, IMP },                        // EF

  { VIN, IMP  },                        // F0
  { LDJ, IRG  },                        // F1
  { XLT, AXLT },                        // F2
  { MUL, IRG  },                        // F3
  { LLT, IMP  },                        // F4
  { WAI, IMP  },                        // F5
  { STA, AIRG },                        // F6
  { AWD, AIRG },                        // F7
  { SUB, AIRG },                        // F8
  { AND, AIRG },                        // F9
  { LDA, AIRG },                        // FA
  { LSR, ACC  },                        // FB
  { LSL, ACC  },                        // FC
  { ASR, ACC  },                        // FD
  { ASRD, IMP },                        // FE
  { LSLD, IMP }                         // FF
};


/* ---------------------------------------------- Main jump table cineops.c */


/* cineops.c is meant to be included directly into cinecpu.c, or turned
 * into a master dispatcher macro, or some other horrible thing. cineops.c
 * is the state dispatcher, which also causes tate changes. This design
 * keeps things running very fast, since no costly flag calculations
 * need to be performed. Thank Zonn for this twisted but effective
 * idea.
 */

/* extern CINEBYTE opcode */

/* table for state "A" -- Use this table if the last opcode was not
 * an ACC related opcode, and was not a B flip/flop operation.
 * Translation:
 *   Any ACC related routine will use A-reg and go on to opCodeTblAA
 *   Any B flip/flop instructions will jump to opCodeTblB
 *   All other instructions remain in opCodeTblA
 *   JMI will use the current sign of the A-reg
 */
opCodeTblA:

switch ( rom [ register_PC ] ) {
case 0: goto opLDAimm_A_AA;
case 1: goto opLDAimm_A_AA;
case 2: goto opLDAimm_A_AA;
case 3: goto opLDAimm_A_AA;
case 4: goto opLDAimm_A_AA;
case 5: goto opLDAimm_A_AA;
case 6: goto opLDAimm_A_AA;
case 7: goto opLDAimm_A_AA;
case 8: goto opLDAimm_A_AA;
case 9: goto opLDAimm_A_AA;
case 10: goto opLDAimm_A_AA;
case 11: goto opLDAimm_A_AA;
case 12: goto opLDAimm_A_AA;
case 13: goto opLDAimm_A_AA;
case 14: goto opLDAimm_A_AA;
case 15: goto opLDAimm_A_AA;
case 16: goto opINP_A_AA;
case 17: goto opINP_A_AA;
case 18: goto opINP_A_AA;
case 19: goto opINP_A_AA;
case 20: goto opINP_A_AA;
case 21: goto opINP_A_AA;
case 22: goto opINP_A_AA;
case 23: goto opINP_A_AA;
case 24: goto opINP_A_AA;
case 25: goto opINP_A_AA;
case 26: goto opINP_A_AA;
case 27: goto opINP_A_AA;
case 28: goto opINP_A_AA;
case 29: goto opINP_A_AA;
case 30: goto opINP_A_AA;
case 31: goto opINP_A_AA;
case 32: goto opADDimmX_A_AA;
case 33: goto opADDimm_A_AA;
case 34: goto opADDimm_A_AA;
case 35: goto opADDimm_A_AA;
case 36: goto opADDimm_A_AA;
case 37: goto opADDimm_A_AA;
case 38: goto opADDimm_A_AA;
case 39: goto opADDimm_A_AA;
case 40: goto opADDimm_A_AA;
case 41: goto opADDimm_A_AA;
case 42: goto opADDimm_A_AA;
case 43: goto opADDimm_A_AA;
case 44: goto opADDimm_A_AA;
case 45: goto opADDimm_A_AA;
case 46: goto opADDimm_A_AA;
case 47: goto opADDimm_A_AA;
case 48: goto opSUBimmX_A_AA;
case 49: goto opSUBimm_A_AA;
case 50: goto opSUBimm_A_AA;
case 51: goto opSUBimm_A_AA;
case 52: goto opSUBimm_A_AA;
case 53: goto opSUBimm_A_AA;
case 54: goto opSUBimm_A_AA;
case 55: goto opSUBimm_A_AA;
case 56: goto opSUBimm_A_AA;
case 57: goto opSUBimm_A_AA;
case 58: goto opSUBimm_A_AA;
case 59: goto opSUBimm_A_AA;
case 60: goto opSUBimm_A_AA;
case 61: goto opSUBimm_A_AA;
case 62: goto opSUBimm_A_AA;
case 63: goto opSUBimm_A_AA;
case 64: goto opLDJimm_A_A;
case 65: goto opLDJimm_A_A;
case 66: goto opLDJimm_A_A;
case 67: goto opLDJimm_A_A;
case 68: goto opLDJimm_A_A;
case 69: goto opLDJimm_A_A;
case 70: goto opLDJimm_A_A;
case 71: goto opLDJimm_A_A;
case 72: goto opLDJimm_A_A;
case 73: goto opLDJimm_A_A;
case 74: goto opLDJimm_A_A;
case 75: goto opLDJimm_A_A;
case 76: goto opLDJimm_A_A;
case 77: goto opLDJimm_A_A;
case 78: goto opLDJimm_A_A;
case 79: goto opLDJimm_A_A;
case 80: goto tJPP_A_B;      /* redirector */
case 81: goto tJMI_A_B;      /* redirector */
case 82: goto opJDR_A_B;
case 83: goto opJLT_A_B;
case 84: goto opJEQ_A_B;
case 85: goto opJNC_A_B;
case 86: goto opJA0_A_B;
case 87: goto opNOP_A_B;
case 88: goto opJMP_A_A;
case 89: goto tJMI_A_A;      /* redirector */
case 90: goto opJDR_A_A;
case 91: goto opJLT_A_A;
case 92: goto opJEQ_A_A;
case 93: goto opJNC_A_A;
case 94: goto opJA0_A_A;
case 95: goto opNOP_A_A;
case 96: goto opADDdir_A_AA;
case 97: goto opADDdir_A_AA;
case 98: goto opADDdir_A_AA;
case 99: goto opADDdir_A_AA;
case 100: goto opADDdir_A_AA;
case 101: goto opADDdir_A_AA;
case 102: goto opADDdir_A_AA;
case 103: goto opADDdir_A_AA;
case 104: goto opADDdir_A_AA;
case 105: goto opADDdir_A_AA;
case 106: goto opADDdir_A_AA;
case 107: goto opADDdir_A_AA;
case 108: goto opADDdir_A_AA;
case 109: goto opADDdir_A_AA;
case 110: goto opADDdir_A_AA;
case 111: goto opADDdir_A_AA;
case 112: goto opSUBdir_A_AA;
case 113: goto opSUBdir_A_AA;
case 114: goto opSUBdir_A_AA;
case 115: goto opSUBdir_A_AA;
case 116: goto opSUBdir_A_AA;
case 117: goto opSUBdir_A_AA;
case 118: goto opSUBdir_A_AA;
case 119: goto opSUBdir_A_AA;
case 120: goto opSUBdir_A_AA;
case 121: goto opSUBdir_A_AA;
case 122: goto opSUBdir_A_AA;
case 123: goto opSUBdir_A_AA;
case 124: goto opSUBdir_A_AA;
case 125: goto opSUBdir_A_AA;
case 126: goto opSUBdir_A_AA;
case 127: goto opSUBdir_A_AA;
case 128: goto opLDPimm_A_A;
case 129: goto opLDPimm_A_A;
case 130: goto opLDPimm_A_A;
case 131: goto opLDPimm_A_A;
case 132: goto opLDPimm_A_A;
case 133: goto opLDPimm_A_A;
case 134: goto opLDPimm_A_A;
case 135: goto opLDPimm_A_A;
case 136: goto opLDPimm_A_A;
case 137: goto opLDPimm_A_A;
case 138: goto opLDPimm_A_A;
case 139: goto opLDPimm_A_A;
case 140: goto opLDPimm_A_A;
case 141: goto opLDPimm_A_A;
case 142: goto opLDPimm_A_A;
case 143: goto opLDPimm_A_A;
case 144: goto tOUT_A_A;         /* redirector */
case 145: goto tOUT_A_A;         /* redirector */
case 146: goto tOUT_A_A;         /* redirector */
case 147: goto tOUT_A_A;         /* redirector */
case 148: goto tOUT_A_A;         /* redirector */
case 149: goto tOUT_A_A;         /* redirector */
case 150: goto tOUT_A_A;         /* redirector */
case 151: goto tOUT_A_A;         /* redirector */
case 152: goto tOUT_A_A;         /* redirector */
case 153: goto tOUT_A_A;         /* redirector */
case 154: goto tOUT_A_A;         /* redirector */
case 155: goto tOUT_A_A;         /* redirector */
case 156: goto tOUT_A_A;         /* redirector */
case 157: goto tOUT_A_A;         /* redirector */
case 158: goto tOUT_A_A;         /* redirector */
case 159: goto tOUT_A_A;         /* redirector */
case 160: goto opLDAdir_A_AA;
case 161: goto opLDAdir_A_AA;
case 162: goto opLDAdir_A_AA;
case 163: goto opLDAdir_A_AA;
case 164: goto opLDAdir_A_AA;
case 165: goto opLDAdir_A_AA;
case 166: goto opLDAdir_A_AA;
case 167: goto opLDAdir_A_AA;
case 168: goto opLDAdir_A_AA;
case 169: goto opLDAdir_A_AA;
case 170: goto opLDAdir_A_AA;
case 171: goto opLDAdir_A_AA;
case 172: goto opLDAdir_A_AA;
case 173: goto opLDAdir_A_AA;
case 174: goto opLDAdir_A_AA;
case 175: goto opLDAdir_A_AA;
case 176: goto opCMPdir_A_AA;
case 177: goto opCMPdir_A_AA;
case 178: goto opCMPdir_A_AA;
case 179: goto opCMPdir_A_AA;
case 180: goto opCMPdir_A_AA;
case 181: goto opCMPdir_A_AA;
case 182: goto opCMPdir_A_AA;
case 183: goto opCMPdir_A_AA;
case 184: goto opCMPdir_A_AA;
case 185: goto opCMPdir_A_AA;
case 186: goto opCMPdir_A_AA;
case 187: goto opCMPdir_A_AA;
case 188: goto opCMPdir_A_AA;
case 189: goto opCMPdir_A_AA;
case 190: goto opCMPdir_A_AA;
case 191: goto opCMPdir_A_AA;
case 192: goto opLDIdir_A_A;
case 193: goto opLDIdir_A_A;
case 194: goto opLDIdir_A_A;
case 195: goto opLDIdir_A_A;
case 196: goto opLDIdir_A_A;
case 197: goto opLDIdir_A_A;
case 198: goto opLDIdir_A_A;
case 199: goto opLDIdir_A_A;
case 200: goto opLDIdir_A_A;
case 201: goto opLDIdir_A_A;
case 202: goto opLDIdir_A_A;
case 203: goto opLDIdir_A_A;
case 204: goto opLDIdir_A_A;
case 205: goto opLDIdir_A_A;
case 206: goto opLDIdir_A_A;
case 207: goto opLDIdir_A_A;
case 208: goto opSTAdir_A_A;
case 209: goto opSTAdir_A_A;
case 210: goto opSTAdir_A_A;
case 211: goto opSTAdir_A_A;
case 212: goto opSTAdir_A_A;
case 213: goto opSTAdir_A_A;
case 214: goto opSTAdir_A_A;
case 215: goto opSTAdir_A_A;
case 216: goto opSTAdir_A_A;
case 217: goto opSTAdir_A_A;
case 218: goto opSTAdir_A_A;
case 219: goto opSTAdir_A_A;
case 220: goto opSTAdir_A_A;
case 221: goto opSTAdir_A_A;
case 222: goto opSTAdir_A_A;
case 223: goto opSTAdir_A_A;
case 224: goto opVDR_A_A;
case 225: goto opLDJirg_A_A;
case 226: goto opXLT_A_AA;
case 227: goto opMULirg_A_AA;
case 228: goto opLLT_A_AA;
case 229: goto opWAI_A_A;
case 230: goto opSTAirg_A_A;
case 231: goto opADDirg_A_AA;
case 232: goto opSUBirg_A_AA;
case 233: goto opANDirg_A_AA;
case 234: goto opLDAirg_A_AA;
case 235: goto opLSRe_A_AA;
case 236: goto opLSLe_A_AA;
case 237: goto opASRe_A_AA;
case 238: goto opASRDe_A_AA;
case 239: goto opLSLDe_A_AA;
case 240: goto opVIN_A_A;
case 241: goto opLDJirg_A_A;
case 242: goto opXLT_A_AA;
case 243: goto opMULirg_A_AA;
case 244: goto opLLT_A_AA;
case 245: goto opWAI_A_A;
case 246: goto opSTAirg_A_A;
case 247: goto opAWDirg_A_AA;
case 248: goto opSUBirg_A_AA;
case 249: goto opANDirg_A_AA;
case 250: goto opLDAirg_A_AA;
case 251: goto opLSRf_A_AA;
case 252: goto opLSLf_A_AA;
case 253: goto opASRf_A_AA;
case 254: goto opASRDf_A_AA;
case 255: goto opLSLDf_A_AA;
} /* switch on opcode */

/* opcode table AA -- Use this table if the last opcode was an ACC
 * related opcode. Translation:
 *   Any ACC related routine will use A-reg and remain in OpCodeTblAA
 *   Any B flip/flop instructions will jump to opCodeTblB
 *   All other instructions will jump to opCodeTblA
 *   JMI will use the sign of acc_old
 */

opCodeTblAA:

switch ( rom [ register_PC ] ) {
case 0: goto opLDAimm_AA_AA;
case 1: goto opLDAimm_AA_AA;
case 2: goto opLDAimm_AA_AA;
case 3: goto opLDAimm_AA_AA;
case 4: goto opLDAimm_AA_AA;
case 5: goto opLDAimm_AA_AA;
case 6: goto opLDAimm_AA_AA;
case 7: goto opLDAimm_AA_AA;
case 8: goto opLDAimm_AA_AA;
case 9: goto opLDAimm_AA_AA;
case 10: goto opLDAimm_AA_AA;
case 11: goto opLDAimm_AA_AA;
case 12: goto opLDAimm_AA_AA;
case 13: goto opLDAimm_AA_AA;
case 14: goto opLDAimm_AA_AA;
case 15: goto opLDAimm_AA_AA;
case 16: goto opINP_AA_AA;
case 17: goto opINP_AA_AA;
case 18: goto opINP_AA_AA;
case 19: goto opINP_AA_AA;
case 20: goto opINP_AA_AA;
case 21: goto opINP_AA_AA;
case 22: goto opINP_AA_AA;
case 23: goto opINP_AA_AA;
case 24: goto opINP_AA_AA;
case 25: goto opINP_AA_AA;
case 26: goto opINP_AA_AA;
case 27: goto opINP_AA_AA;
case 28: goto opINP_AA_AA;
case 29: goto opINP_AA_AA;
case 30: goto opINP_AA_AA;
case 31: goto opINP_AA_AA;
case 32: goto opADDimmX_AA_AA;
case 33: goto opADDimm_AA_AA;
case 34: goto opADDimm_AA_AA;
case 35: goto opADDimm_AA_AA;
case 36: goto opADDimm_AA_AA;
case 37: goto opADDimm_AA_AA;
case 38: goto opADDimm_AA_AA;
case 39: goto opADDimm_AA_AA;
case 40: goto opADDimm_AA_AA;
case 41: goto opADDimm_AA_AA;
case 42: goto opADDimm_AA_AA;
case 43: goto opADDimm_AA_AA;
case 44: goto opADDimm_AA_AA;
case 45: goto opADDimm_AA_AA;
case 46: goto opADDimm_AA_AA;
case 47: goto opADDimm_AA_AA;
case 48: goto opSUBimmX_AA_AA;
case 49: goto opSUBimm_AA_AA;
case 50: goto opSUBimm_AA_AA;
case 51: goto opSUBimm_AA_AA;
case 52: goto opSUBimm_AA_AA;
case 53: goto opSUBimm_AA_AA;
case 54: goto opSUBimm_AA_AA;
case 55: goto opSUBimm_AA_AA;
case 56: goto opSUBimm_AA_AA;
case 57: goto opSUBimm_AA_AA;
case 58: goto opSUBimm_AA_AA;
case 59: goto opSUBimm_AA_AA;
case 60: goto opSUBimm_AA_AA;
case 61: goto opSUBimm_AA_AA;
case 62: goto opSUBimm_AA_AA;
case 63: goto opSUBimm_AA_AA;
case 64: goto opLDJimm_AA_A;
case 65: goto opLDJimm_AA_A;
case 66: goto opLDJimm_AA_A;
case 67: goto opLDJimm_AA_A;
case 68: goto opLDJimm_AA_A;
case 69: goto opLDJimm_AA_A;
case 70: goto opLDJimm_AA_A;
case 71: goto opLDJimm_AA_A;
case 72: goto opLDJimm_AA_A;
case 73: goto opLDJimm_AA_A;
case 74: goto opLDJimm_AA_A;
case 75: goto opLDJimm_AA_A;
case 76: goto opLDJimm_AA_A;
case 77: goto opLDJimm_AA_A;
case 78: goto opLDJimm_AA_A;
case 79: goto opLDJimm_AA_A;
case 80: goto tJPP_AA_B;         /* redirector */
case 81: goto tJMI_AA_B;         /* redirector */
case 82: goto opJDR_AA_B;
case 83: goto opJLT_AA_B;
case 84: goto opJEQ_AA_B;
case 85: goto opJNC_AA_B;
case 86: goto opJA0_AA_B;
case 87: goto opNOP_AA_B;
case 88: goto opJMP_AA_A;
case 89: goto tJMI_AA_A;         /* redirector */
case 90: goto opJDR_AA_A;
case 91: goto opJLT_AA_A;
case 92: goto opJEQ_AA_A;
case 93: goto opJNC_AA_A;
case 94: goto opJA0_AA_A;
case 95: goto opNOP_AA_A;
case 96: goto opADDdir_AA_AA;
case 97: goto opADDdir_AA_AA;
case 98: goto opADDdir_AA_AA;
case 99: goto opADDdir_AA_AA;
case 100: goto opADDdir_AA_AA;
case 101: goto opADDdir_AA_AA;
case 102: goto opADDdir_AA_AA;
case 103: goto opADDdir_AA_AA;
case 104: goto opADDdir_AA_AA;
case 105: goto opADDdir_AA_AA;
case 106: goto opADDdir_AA_AA;
case 107: goto opADDdir_AA_AA;
case 108: goto opADDdir_AA_AA;
case 109: goto opADDdir_AA_AA;
case 110: goto opADDdir_AA_AA;
case 111: goto opADDdir_AA_AA;
case 112: goto opSUBdir_AA_AA;
case 113: goto opSUBdir_AA_AA;
case 114: goto opSUBdir_AA_AA;
case 115: goto opSUBdir_AA_AA;
case 116: goto opSUBdir_AA_AA;
case 117: goto opSUBdir_AA_AA;
case 118: goto opSUBdir_AA_AA;
case 119: goto opSUBdir_AA_AA;
case 120: goto opSUBdir_AA_AA;
case 121: goto opSUBdir_AA_AA;
case 122: goto opSUBdir_AA_AA;
case 123: goto opSUBdir_AA_AA;
case 124: goto opSUBdir_AA_AA;
case 125: goto opSUBdir_AA_AA;
case 126: goto opSUBdir_AA_AA;
case 127: goto opSUBdir_AA_AA;
case 128: goto opLDPimm_AA_A;
case 129: goto opLDPimm_AA_A;
case 130: goto opLDPimm_AA_A;
case 131: goto opLDPimm_AA_A;
case 132: goto opLDPimm_AA_A;
case 133: goto opLDPimm_AA_A;
case 134: goto opLDPimm_AA_A;
case 135: goto opLDPimm_AA_A;
case 136: goto opLDPimm_AA_A;
case 137: goto opLDPimm_AA_A;
case 138: goto opLDPimm_AA_A;
case 139: goto opLDPimm_AA_A;
case 140: goto opLDPimm_AA_A;
case 141: goto opLDPimm_AA_A;
case 142: goto opLDPimm_AA_A;
case 143: goto opLDPimm_AA_A;
case 144: goto tOUT_AA_A;          /* redirector */
case 145: goto tOUT_AA_A;          /* redirector */
case 146: goto tOUT_AA_A;          /* redirector */
case 147: goto tOUT_AA_A;          /* redirector */
case 148: goto tOUT_AA_A;          /* redirector */
case 149: goto tOUT_AA_A;          /* redirector */
case 150: goto tOUT_AA_A;          /* redirector */
case 151: goto tOUT_AA_A;          /* redirector */
case 152: goto tOUT_AA_A;          /* redirector */
case 153: goto tOUT_AA_A;          /* redirector */
case 154: goto tOUT_AA_A;          /* redirector */
case 155: goto tOUT_AA_A;          /* redirector */
case 156: goto tOUT_AA_A;          /* redirector */
case 157: goto tOUT_AA_A;          /* redirector */
case 158: goto tOUT_AA_A;          /* redirector */
case 159: goto tOUT_AA_A;          /* redirector */
case 160: goto opLDAdir_AA_AA;
case 161: goto opLDAdir_AA_AA;
case 162: goto opLDAdir_AA_AA;
case 163: goto opLDAdir_AA_AA;
case 164: goto opLDAdir_AA_AA;
case 165: goto opLDAdir_AA_AA;
case 166: goto opLDAdir_AA_AA;
case 167: goto opLDAdir_AA_AA;
case 168: goto opLDAdir_AA_AA;
case 169: goto opLDAdir_AA_AA;
case 170: goto opLDAdir_AA_AA;
case 171: goto opLDAdir_AA_AA;
case 172: goto opLDAdir_AA_AA;
case 173: goto opLDAdir_AA_AA;
case 174: goto opLDAdir_AA_AA;
case 175: goto opLDAdir_AA_AA;
case 176: goto opCMPdir_AA_AA;
case 177: goto opCMPdir_AA_AA;
case 178: goto opCMPdir_AA_AA;
case 179: goto opCMPdir_AA_AA;
case 180: goto opCMPdir_AA_AA;
case 181: goto opCMPdir_AA_AA;
case 182: goto opCMPdir_AA_AA;
case 183: goto opCMPdir_AA_AA;
case 184: goto opCMPdir_AA_AA;
case 185: goto opCMPdir_AA_AA;
case 186: goto opCMPdir_AA_AA;
case 187: goto opCMPdir_AA_AA;
case 188: goto opCMPdir_AA_AA;
case 189: goto opCMPdir_AA_AA;
case 190: goto opCMPdir_AA_AA;
case 191: goto opCMPdir_AA_AA;
case 192: goto opLDIdir_AA_A;
case 193: goto opLDIdir_AA_A;
case 194: goto opLDIdir_AA_A;
case 195: goto opLDIdir_AA_A;
case 196: goto opLDIdir_AA_A;
case 197: goto opLDIdir_AA_A;
case 198: goto opLDIdir_AA_A;
case 199: goto opLDIdir_AA_A;
case 200: goto opLDIdir_AA_A;
case 201: goto opLDIdir_AA_A;
case 202: goto opLDIdir_AA_A;
case 203: goto opLDIdir_AA_A;
case 204: goto opLDIdir_AA_A;
case 205: goto opLDIdir_AA_A;
case 206: goto opLDIdir_AA_A;
case 207: goto opLDIdir_AA_A;
case 208: goto opSTAdir_AA_A;
case 209: goto opSTAdir_AA_A;
case 210: goto opSTAdir_AA_A;
case 211: goto opSTAdir_AA_A;
case 212: goto opSTAdir_AA_A;
case 213: goto opSTAdir_AA_A;
case 214: goto opSTAdir_AA_A;
case 215: goto opSTAdir_AA_A;
case 216: goto opSTAdir_AA_A;
case 217: goto opSTAdir_AA_A;
case 218: goto opSTAdir_AA_A;
case 219: goto opSTAdir_AA_A;
case 220: goto opSTAdir_AA_A;
case 221: goto opSTAdir_AA_A;
case 222: goto opSTAdir_AA_A;
case 223: goto opSTAdir_AA_A;
case 224: goto opVDR_AA_A;
case 225: goto opLDJirg_AA_A;
case 226: goto opXLT_AA_AA;
case 227: goto opMULirg_AA_AA;
case 228: goto opLLT_AA_AA;
case 229: goto opWAI_AA_A;
case 230: goto opSTAirg_AA_A;
case 231: goto opADDirg_AA_AA;
case 232: goto opSUBirg_AA_AA;
case 233: goto opANDirg_AA_AA;
case 234: goto opLDAirg_AA_AA;
case 235: goto opLSRe_AA_AA;
case 236: goto opLSLe_AA_AA;
case 237: goto opASRe_AA_AA;
case 238: goto opASRDe_AA_AA;
case 239: goto opLSLDe_AA_AA;
case 240: goto opVIN_AA_A;
case 241: goto opLDJirg_AA_A;
case 242: goto opXLT_AA_AA;
case 243: goto opMULirg_AA_AA;
case 244: goto opLLT_AA_AA;
case 245: goto opWAI_AA_A;
case 246: goto opSTAirg_AA_A;
case 247: goto opAWDirg_AA_AA;
case 248: goto opSUBirg_AA_AA;
case 249: goto opANDirg_AA_AA;
case 250: goto opLDAirg_AA_AA;
case 251: goto opLSRf_AA_AA;
case 252: goto opLSLf_AA_AA;
case 253: goto opASRf_AA_AA;
case 254: goto opASRDf_AA_AA;
case 255: goto opLSLDf_AA_AA;
} /* switch on opcode */

/* opcode table B -- use this table if the last opcode was a B-reg flip/flop
 * Translation:
 *   Any ACC related routine uses B-reg, and goes to opCodeTblAA
 *   All other instructions will jump to table opCodeTblBB (including
 *     B flip/flop related instructions)
 *   JMI will use current sign of the A-reg
 */

opCodeTblB:

switch ( rom [ register_PC ] ) {
case 0: goto opLDAimm_B_AA;
case 1: goto opLDAimm_B_AA;
case 2: goto opLDAimm_B_AA;
case 3: goto opLDAimm_B_AA;
case 4: goto opLDAimm_B_AA;
case 5: goto opLDAimm_B_AA;
case 6: goto opLDAimm_B_AA;
case 7: goto opLDAimm_B_AA;
case 8: goto opLDAimm_B_AA;
case 9: goto opLDAimm_B_AA;
case 10: goto opLDAimm_B_AA;
case 11: goto opLDAimm_B_AA;
case 12: goto opLDAimm_B_AA;
case 13: goto opLDAimm_B_AA;
case 14: goto opLDAimm_B_AA;
case 15: goto opLDAimm_B_AA;
case 16: goto opINP_B_AA;
case 17: goto opINP_B_AA;
case 18: goto opINP_B_AA;
case 19: goto opINP_B_AA;
case 20: goto opINP_B_AA;
case 21: goto opINP_B_AA;
case 22: goto opINP_B_AA;
case 23: goto opINP_B_AA;
case 24: goto opINP_B_AA;
case 25: goto opINP_B_AA;
case 26: goto opINP_B_AA;
case 27: goto opINP_B_AA;
case 28: goto opINP_B_AA;
case 29: goto opINP_B_AA;
case 30: goto opINP_B_AA;
case 31: goto opINP_B_AA;
case 32: goto opADDimmX_B_AA;
case 33: goto opADDimm_B_AA;
case 34: goto opADDimm_B_AA;
case 35: goto opADDimm_B_AA;
case 36: goto opADDimm_B_AA;
case 37: goto opADDimm_B_AA;
case 38: goto opADDimm_B_AA;
case 39: goto opADDimm_B_AA;
case 40: goto opADDimm_B_AA;
case 41: goto opADDimm_B_AA;
case 42: goto opADDimm_B_AA;
case 43: goto opADDimm_B_AA;
case 44: goto opADDimm_B_AA;
case 45: goto opADDimm_B_AA;
case 46: goto opADDimm_B_AA;
case 47: goto opADDimm_B_AA;
case 48: goto opSUBimmX_B_AA;
case 49: goto opSUBimm_B_AA;
case 50: goto opSUBimm_B_AA;
case 51: goto opSUBimm_B_AA;
case 52: goto opSUBimm_B_AA;
case 53: goto opSUBimm_B_AA;
case 54: goto opSUBimm_B_AA;
case 55: goto opSUBimm_B_AA;
case 56: goto opSUBimm_B_AA;
case 57: goto opSUBimm_B_AA;
case 58: goto opSUBimm_B_AA;
case 59: goto opSUBimm_B_AA;
case 60: goto opSUBimm_B_AA;
case 61: goto opSUBimm_B_AA;
case 62: goto opSUBimm_B_AA;
case 63: goto opSUBimm_B_AA;
case 64: goto opLDJimm_B_BB;
case 65: goto opLDJimm_B_BB;
case 66: goto opLDJimm_B_BB;
case 67: goto opLDJimm_B_BB;
case 68: goto opLDJimm_B_BB;
case 69: goto opLDJimm_B_BB;
case 70: goto opLDJimm_B_BB;
case 71: goto opLDJimm_B_BB;
case 72: goto opLDJimm_B_BB;
case 73: goto opLDJimm_B_BB;
case 74: goto opLDJimm_B_BB;
case 75: goto opLDJimm_B_BB;
case 76: goto opLDJimm_B_BB;
case 77: goto opLDJimm_B_BB;
case 78: goto opLDJimm_B_BB;
case 79: goto opLDJimm_B_BB;
case 80: goto tJPP_B_BB;          /* redirector */
case 81: goto tJMI_B_BB1;         /* redirector */
case 82: goto opJDR_B_BB;
case 83: goto opJLT_B_BB;
case 84: goto opJEQ_B_BB;
case 85: goto opJNC_B_BB;
case 86: goto opJA0_B_BB;
case 87: goto opNOP_B_BB;
case 88: goto opJMP_B_BB;
case 89: goto tJMI_B_BB2;         /* redirector */
case 90: goto opJDR_B_BB;
case 91: goto opJLT_B_BB;
case 92: goto opJEQ_B_BB;
case 93: goto opJNC_B_BB;
case 94: goto opJA0_B_BB;
case 95: goto opNOP_B_BB;
case 96: goto opADDdir_B_AA;
case 97: goto opADDdir_B_AA;
case 98: goto opADDdir_B_AA;
case 99: goto opADDdir_B_AA;
case 100: goto opADDdir_B_AA;
case 101: goto opADDdir_B_AA;
case 102: goto opADDdir_B_AA;
case 103: goto opADDdir_B_AA;
case 104: goto opADDdir_B_AA;
case 105: goto opADDdir_B_AA;
case 106: goto opADDdir_B_AA;
case 107: goto opADDdir_B_AA;
case 108: goto opADDdir_B_AA;
case 109: goto opADDdir_B_AA;
case 110: goto opADDdir_B_AA;
case 111: goto opADDdir_B_AA;
case 112: goto opSUBdir_B_AA;
case 113: goto opSUBdir_B_AA;
case 114: goto opSUBdir_B_AA;
case 115: goto opSUBdir_B_AA;
case 116: goto opSUBdir_B_AA;
case 117: goto opSUBdir_B_AA;
case 118: goto opSUBdir_B_AA;
case 119: goto opSUBdir_B_AA;
case 120: goto opSUBdir_B_AA;
case 121: goto opSUBdir_B_AA;
case 122: goto opSUBdir_B_AA;
case 123: goto opSUBdir_B_AA;
case 124: goto opSUBdir_B_AA;
case 125: goto opSUBdir_B_AA;
case 126: goto opSUBdir_B_AA;
case 127: goto opSUBdir_B_AA;
case 128: goto opLDPimm_B_BB;
case 129: goto opLDPimm_B_BB;
case 130: goto opLDPimm_B_BB;
case 131: goto opLDPimm_B_BB;
case 132: goto opLDPimm_B_BB;
case 133: goto opLDPimm_B_BB;
case 134: goto opLDPimm_B_BB;
case 135: goto opLDPimm_B_BB;
case 136: goto opLDPimm_B_BB;
case 137: goto opLDPimm_B_BB;
case 138: goto opLDPimm_B_BB;
case 139: goto opLDPimm_B_BB;
case 140: goto opLDPimm_B_BB;
case 141: goto opLDPimm_B_BB;
case 142: goto opLDPimm_B_BB;
case 143: goto opLDPimm_B_BB;
case 144: goto tOUT_B_BB;         /* redirector */
case 145: goto tOUT_B_BB;         /* redirector */
case 146: goto tOUT_B_BB;         /* redirector */
case 147: goto tOUT_B_BB;         /* redirector */
case 148: goto tOUT_B_BB;         /* redirector */
case 149: goto tOUT_B_BB;         /* redirector */
case 150: goto tOUT_B_BB;         /* redirector */
case 151: goto tOUT_B_BB;         /* redirector */
case 152: goto tOUT_B_BB;         /* redirector */
case 153: goto tOUT_B_BB;         /* redirector */
case 154: goto tOUT_B_BB;         /* redirector */
case 155: goto tOUT_B_BB;         /* redirector */
case 156: goto tOUT_B_BB;         /* redirector */
case 157: goto tOUT_B_BB;         /* redirector */
case 158: goto tOUT_B_BB;         /* redirector */
case 159: goto tOUT_B_BB;         /* redirector */
case 160: goto opLDAdir_B_AA;
case 161: goto opLDAdir_B_AA;
case 162: goto opLDAdir_B_AA;
case 163: goto opLDAdir_B_AA;
case 164: goto opLDAdir_B_AA;
case 165: goto opLDAdir_B_AA;
case 166: goto opLDAdir_B_AA;
case 167: goto opLDAdir_B_AA;
case 168: goto opLDAdir_B_AA;
case 169: goto opLDAdir_B_AA;
case 170: goto opLDAdir_B_AA;
case 171: goto opLDAdir_B_AA;
case 172: goto opLDAdir_B_AA;
case 173: goto opLDAdir_B_AA;
case 174: goto opLDAdir_B_AA;
case 175: goto opLDAdir_B_AA;
case 176: goto opCMPdir_B_AA;
case 177: goto opCMPdir_B_AA;
case 178: goto opCMPdir_B_AA;
case 179: goto opCMPdir_B_AA;
case 180: goto opCMPdir_B_AA;
case 181: goto opCMPdir_B_AA;
case 182: goto opCMPdir_B_AA;
case 183: goto opCMPdir_B_AA;
case 184: goto opCMPdir_B_AA;
case 185: goto opCMPdir_B_AA;
case 186: goto opCMPdir_B_AA;
case 187: goto opCMPdir_B_AA;
case 188: goto opCMPdir_B_AA;
case 189: goto opCMPdir_B_AA;
case 190: goto opCMPdir_B_AA;
case 191: goto opCMPdir_B_AA;
case 192: goto opLDIdir_B_BB;
case 193: goto opLDIdir_B_BB;
case 194: goto opLDIdir_B_BB;
case 195: goto opLDIdir_B_BB;
case 196: goto opLDIdir_B_BB;
case 197: goto opLDIdir_B_BB;
case 198: goto opLDIdir_B_BB;
case 199: goto opLDIdir_B_BB;
case 200: goto opLDIdir_B_BB;
case 201: goto opLDIdir_B_BB;
case 202: goto opLDIdir_B_BB;
case 203: goto opLDIdir_B_BB;
case 204: goto opLDIdir_B_BB;
case 205: goto opLDIdir_B_BB;
case 206: goto opLDIdir_B_BB;
case 207: goto opLDIdir_B_BB;
case 208: goto opSTAdir_B_BB;
case 209: goto opSTAdir_B_BB;
case 210: goto opSTAdir_B_BB;
case 211: goto opSTAdir_B_BB;
case 212: goto opSTAdir_B_BB;
case 213: goto opSTAdir_B_BB;
case 214: goto opSTAdir_B_BB;
case 215: goto opSTAdir_B_BB;
case 216: goto opSTAdir_B_BB;
case 217: goto opSTAdir_B_BB;
case 218: goto opSTAdir_B_BB;
case 219: goto opSTAdir_B_BB;
case 220: goto opSTAdir_B_BB;
case 221: goto opSTAdir_B_BB;
case 222: goto opSTAdir_B_BB;
case 223: goto opSTAdir_B_BB;
case 224: goto opVDR_B_BB;
case 225: goto opLDJirg_B_BB;
case 226: goto opXLT_B_AA;
case 227: goto opMULirg_B_AA;
case 228: goto opLLT_B_AA;
case 229: goto opWAI_B_BB;
case 230: goto opSTAirg_B_BB;
case 231: goto opADDirg_B_AA;
case 232: goto opSUBirg_B_AA;
case 233: goto opANDirg_B_AA;
case 234: goto opLDAirg_B_AA;
case 235: goto opLSRe_B_AA;
case 236: goto opLSLe_B_AA;
case 237: goto opASRe_B_AA;
case 238: goto opASRDe_B_AA;
case 239: goto opLSLDe_B_AA;
case 240: goto opVIN_B_BB;
case 241: goto opLDJirg_B_BB;
case 242: goto opXLT_B_AA;
case 243: goto opMULirg_B_AA;
case 244: goto opLLT_B_AA;
case 245: goto opWAI_B_BB;
case 246: goto opSTAirg_B_BB;
case 247: goto opAWDirg_B_AA;
case 248: goto opSUBirg_B_AA;
case 249: goto opANDirg_B_AA;
case 250: goto opLDAirg_B_AA;
case 251: goto opLSRf_B_AA;
case 252: goto opLSLf_B_AA;
case 253: goto opASRf_B_AA;
case 254: goto opASRDf_B_AA;
case 255: goto opLSLDf_B_AA;
} /* switch on opcode */

/* opcode table BB -- use this table if the last opcode was not an ACC
 * related opcode, but instruction before that was a B-flip/flop instruction.
 * Translation:
 *   Any ACC related routine will use A-reg and go to opCodeTblAA
 *   Any B flip/flop instructions will jump to opCodeTblB
 *   All other instructions will jump to table opCodeTblA
 *   JMI will use the current state of the B-reg
 */

opCodeTblBB:

switch ( rom [ register_PC ] ) {
case 0: goto opLDAimm_BB_AA;
case 1: goto opLDAimm_BB_AA;
case 2: goto opLDAimm_BB_AA;
case 3: goto opLDAimm_BB_AA;
case 4: goto opLDAimm_BB_AA;
case 5: goto opLDAimm_BB_AA;
case 6: goto opLDAimm_BB_AA;
case 7: goto opLDAimm_BB_AA;
case 8: goto opLDAimm_BB_AA;
case 9: goto opLDAimm_BB_AA;
case 10: goto opLDAimm_BB_AA;
case 11: goto opLDAimm_BB_AA;
case 12: goto opLDAimm_BB_AA;
case 13: goto opLDAimm_BB_AA;
case 14: goto opLDAimm_BB_AA;
case 15: goto opLDAimm_BB_AA;
case 16: goto opINP_BB_AA;
case 17: goto opINP_BB_AA;
case 18: goto opINP_BB_AA;
case 19: goto opINP_BB_AA;
case 20: goto opINP_BB_AA;
case 21: goto opINP_BB_AA;
case 22: goto opINP_BB_AA;
case 23: goto opINP_BB_AA;
case 24: goto opINP_BB_AA;
case 25: goto opINP_BB_AA;
case 26: goto opINP_BB_AA;
case 27: goto opINP_BB_AA;
case 28: goto opINP_BB_AA;
case 29: goto opINP_BB_AA;
case 30: goto opINP_BB_AA;
case 31: goto opINP_BB_AA;
case 32: goto opADDimmX_BB_AA;
case 33: goto opADDimm_BB_AA;
case 34: goto opADDimm_BB_AA;
case 35: goto opADDimm_BB_AA;
case 36: goto opADDimm_BB_AA;
case 37: goto opADDimm_BB_AA;
case 38: goto opADDimm_BB_AA;
case 39: goto opADDimm_BB_AA;
case 40: goto opADDimm_BB_AA;
case 41: goto opADDimm_BB_AA;
case 42: goto opADDimm_BB_AA;
case 43: goto opADDimm_BB_AA;
case 44: goto opADDimm_BB_AA;
case 45: goto opADDimm_BB_AA;
case 46: goto opADDimm_BB_AA;
case 47: goto opADDimm_BB_AA;
case 48: goto opSUBimmX_BB_AA;
case 49: goto opSUBimm_BB_AA;
case 50: goto opSUBimm_BB_AA;
case 51: goto opSUBimm_BB_AA;
case 52: goto opSUBimm_BB_AA;
case 53: goto opSUBimm_BB_AA;
case 54: goto opSUBimm_BB_AA;
case 55: goto opSUBimm_BB_AA;
case 56: goto opSUBimm_BB_AA;
case 57: goto opSUBimm_BB_AA;
case 58: goto opSUBimm_BB_AA;
case 59: goto opSUBimm_BB_AA;
case 60: goto opSUBimm_BB_AA;
case 61: goto opSUBimm_BB_AA;
case 62: goto opSUBimm_BB_AA;
case 63: goto opSUBimm_BB_AA;
case 64: goto opLDJimm_BB_A;
case 65: goto opLDJimm_BB_A;
case 66: goto opLDJimm_BB_A;
case 67: goto opLDJimm_BB_A;
case 68: goto opLDJimm_BB_A;
case 69: goto opLDJimm_BB_A;
case 70: goto opLDJimm_BB_A;
case 71: goto opLDJimm_BB_A;
case 72: goto opLDJimm_BB_A;
case 73: goto opLDJimm_BB_A;
case 74: goto opLDJimm_BB_A;
case 75: goto opLDJimm_BB_A;
case 76: goto opLDJimm_BB_A;
case 77: goto opLDJimm_BB_A;
case 78: goto opLDJimm_BB_A;
case 79: goto opLDJimm_BB_A;
case 80: goto tJPP_BB_B;         /* redirector */
case 81: goto tJMI_BB_B;         /* redirector */
case 82: goto opJDR_BB_B;
case 83: goto opJLT_BB_B;
case 84: goto opJEQ_BB_B;
case 85: goto opJNC_BB_B;
case 86: goto opJA0_BB_B;
case 87: goto opNOP_BB_B;
case 88: goto opJMP_BB_A;
case 89: goto tJMI_BB_A;         /* redirector */
case 90: goto opJDR_BB_A;
case 91: goto opJLT_BB_A;
case 92: goto opJEQ_BB_A;
case 93: goto opJNC_BB_A;
case 94: goto opJA0_BB_A;
case 95: goto opNOP_BB_A;
case 96: goto opADDdir_BB_AA;
case 97: goto opADDdir_BB_AA;
case 98: goto opADDdir_BB_AA;
case 99: goto opADDdir_BB_AA;
case 100: goto opADDdir_BB_AA;
case 101: goto opADDdir_BB_AA;
case 102: goto opADDdir_BB_AA;
case 103: goto opADDdir_BB_AA;
case 104: goto opADDdir_BB_AA;
case 105: goto opADDdir_BB_AA;
case 106: goto opADDdir_BB_AA;
case 107: goto opADDdir_BB_AA;
case 108: goto opADDdir_BB_AA;
case 109: goto opADDdir_BB_AA;
case 110: goto opADDdir_BB_AA;
case 111: goto opADDdir_BB_AA;
case 112: goto opSUBdir_BB_AA;
case 113: goto opSUBdir_BB_AA;
case 114: goto opSUBdir_BB_AA;
case 115: goto opSUBdir_BB_AA;
case 116: goto opSUBdir_BB_AA;
case 117: goto opSUBdir_BB_AA;
case 118: goto opSUBdir_BB_AA;
case 119: goto opSUBdir_BB_AA;
case 120: goto opSUBdir_BB_AA;
case 121: goto opSUBdir_BB_AA;
case 122: goto opSUBdir_BB_AA;
case 123: goto opSUBdir_BB_AA;
case 124: goto opSUBdir_BB_AA;
case 125: goto opSUBdir_BB_AA;
case 126: goto opSUBdir_BB_AA;
case 127: goto opSUBdir_BB_AA;
case 128: goto opLDPimm_BB_A;
case 129: goto opLDPimm_BB_A;
case 130: goto opLDPimm_BB_A;
case 131: goto opLDPimm_BB_A;
case 132: goto opLDPimm_BB_A;
case 133: goto opLDPimm_BB_A;
case 134: goto opLDPimm_BB_A;
case 135: goto opLDPimm_BB_A;
case 136: goto opLDPimm_BB_A;
case 137: goto opLDPimm_BB_A;
case 138: goto opLDPimm_BB_A;
case 139: goto opLDPimm_BB_A;
case 140: goto opLDPimm_BB_A;
case 141: goto opLDPimm_BB_A;
case 142: goto opLDPimm_BB_A;
case 143: goto opLDPimm_BB_A;
case 144: goto tOUT_BB_A;         /* redirector */
case 145: goto tOUT_BB_A;         /* redirector */
case 146: goto tOUT_BB_A;         /* redirector */
case 147: goto tOUT_BB_A;         /* redirector */
case 148: goto tOUT_BB_A;         /* redirector */
case 149: goto tOUT_BB_A;         /* redirector */
case 150: goto tOUT_BB_A;         /* redirector */
case 151: goto tOUT_BB_A;         /* redirector */
case 152: goto tOUT_BB_A;         /* redirector */
case 153: goto tOUT_BB_A;         /* redirector */
case 154: goto tOUT_BB_A;         /* redirector */
case 155: goto tOUT_BB_A;         /* redirector */
case 156: goto tOUT_BB_A;         /* redirector */
case 157: goto tOUT_BB_A;         /* redirector */
case 158: goto tOUT_BB_A;         /* redirector */
case 159: goto tOUT_BB_A;         /* redirector */
case 160: goto opLDAdir_BB_AA;
case 161: goto opLDAdir_BB_AA;
case 162: goto opLDAdir_BB_AA;
case 163: goto opLDAdir_BB_AA;
case 164: goto opLDAdir_BB_AA;
case 165: goto opLDAdir_BB_AA;
case 166: goto opLDAdir_BB_AA;
case 167: goto opLDAdir_BB_AA;
case 168: goto opLDAdir_BB_AA;
case 169: goto opLDAdir_BB_AA;
case 170: goto opLDAdir_BB_AA;
case 171: goto opLDAdir_BB_AA;
case 172: goto opLDAdir_BB_AA;
case 173: goto opLDAdir_BB_AA;
case 174: goto opLDAdir_BB_AA;
case 175: goto opLDAdir_BB_AA;
case 176: goto opCMPdir_BB_AA;
case 177: goto opCMPdir_BB_AA;
case 178: goto opCMPdir_BB_AA;
case 179: goto opCMPdir_BB_AA;
case 180: goto opCMPdir_BB_AA;
case 181: goto opCMPdir_BB_AA;
case 182: goto opCMPdir_BB_AA;
case 183: goto opCMPdir_BB_AA;
case 184: goto opCMPdir_BB_AA;
case 185: goto opCMPdir_BB_AA;
case 186: goto opCMPdir_BB_AA;
case 187: goto opCMPdir_BB_AA;
case 188: goto opCMPdir_BB_AA;
case 189: goto opCMPdir_BB_AA;
case 190: goto opCMPdir_BB_AA;
case 191: goto opCMPdir_BB_AA;
case 192: goto opLDIdir_BB_A;
case 193: goto opLDIdir_BB_A;
case 194: goto opLDIdir_BB_A;
case 195: goto opLDIdir_BB_A;
case 196: goto opLDIdir_BB_A;
case 197: goto opLDIdir_BB_A;
case 198: goto opLDIdir_BB_A;
case 199: goto opLDIdir_BB_A;
case 200: goto opLDIdir_BB_A;
case 201: goto opLDIdir_BB_A;
case 202: goto opLDIdir_BB_A;
case 203: goto opLDIdir_BB_A;
case 204: goto opLDIdir_BB_A;
case 205: goto opLDIdir_BB_A;
case 206: goto opLDIdir_BB_A;
case 207: goto opLDIdir_BB_A;
case 208: goto opSTAdir_BB_A;
case 209: goto opSTAdir_BB_A;
case 210: goto opSTAdir_BB_A;
case 211: goto opSTAdir_BB_A;
case 212: goto opSTAdir_BB_A;
case 213: goto opSTAdir_BB_A;
case 214: goto opSTAdir_BB_A;
case 215: goto opSTAdir_BB_A;
case 216: goto opSTAdir_BB_A;
case 217: goto opSTAdir_BB_A;
case 218: goto opSTAdir_BB_A;
case 219: goto opSTAdir_BB_A;
case 220: goto opSTAdir_BB_A;
case 221: goto opSTAdir_BB_A;
case 222: goto opSTAdir_BB_A;
case 223: goto opSTAdir_BB_A;
case 224: goto opVDR_BB_A;
case 225: goto opLDJirg_BB_A;
case 226: goto opXLT_BB_AA;
case 227: goto opMULirg_BB_AA;
case 228: goto opLLT_BB_AA;
case 229: goto opWAI_BB_A;
case 230: goto opSTAirg_BB_A;
case 231: goto opADDirg_BB_AA;
case 232: goto opSUBirg_BB_AA;
case 233: goto opANDirg_BB_AA;
case 234: goto opLDAirg_BB_AA;
case 235: goto opLSRe_BB_AA;
case 236: goto opLSLe_BB_AA;
case 237: goto opASRe_BB_AA;
case 238: goto opASRDe_BB_AA;
case 239: goto opLSLDe_BB_AA;
case 240: goto opVIN_BB_A;
case 241: goto opLDJirg_BB_A;
case 242: goto opXLT_BB_AA;
case 243: goto opMULirg_BB_AA;
case 244: goto opLLT_BB_AA;
case 245: goto opWAI_BB_A;
case 246: goto opSTAirg_BB_A;
case 247: goto opAWDirg_BB_AA;
case 248: goto opSUBirg_BB_AA;
case 249: goto opANDirg_BB_AA;
case 250: goto opLDAirg_BB_AA;
case 251: goto opLSRf_BB_AA;
case 252: goto opLSLf_BB_AA;
case 253: goto opASRf_BB_AA;
case 254: goto opASRDf_BB_AA;
case 255: goto opLSLDf_BB_AA;
} /* switch on opcode */