/*****************************************************************************
* CINEDISM.C																					  *
*																									  *
* Cinematronics Disassembler.																  *
*																									  *
* This program is used to generate a disassembled listing of a program		  *
* written for the Cinematronics CPU cards.											  *
*																									  *
* Author:  Zonn Moore																		  *
* Version: 1.1																					  *
* Date:    01/31/97																			  *
*																									  *
* Revision History:																			  *
* -----------------																			  *
*																									  *
* Version 1.0, 01/31/97																		  *
*    Initial release.																		  *
*																									  *
* Version 1.1, 07/31/97																		  *
*    Removed '[j]' from JMP instructructions.										  *
*																									  *
* Released to public domain by the author, distribute freely.					  *
*****************************************************************************/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<fcntl.h>
#include	<sys/types.h>
#include	<sys/stat.h>

#include "ccpu.h"

#include "opcodes.h"

void strlwr(char *s)
{
  int c;
  if (s == NULL) return;
  for (;;) {
    c = *s++;
    if (c == NULL) break;
    if (isalpha(c) && isupper(c)) {
      c = tolower(c);
    }
  }
}

off_t filelength(int fd)
{
  off_t curpos = lseek(fd, 0, SEEK_CUR);
  off_t l = lseek(fd, 0, SEEK_END);
  lseek(fd, curpos, SEEK_SET);
  return(l);
}

#define JMP() register_PC = ((register_PC - 1) & 0xF000) + register_J; ccpu_ICount -= 2

void SAR(char *var, char *arg) {
  fprintf(stdout, "(((signed short int) %s) >> %s)", var, arg);
}

void SETA0(char *var)
{
  fprintf(stdout, "(acc_a0 = %s)", var);
}

void GETA0(void)
{
  fprintf(stdout, "(acc_a0)");
}

void SETFC(char *val)
{
  fprintf(stdout, "(flag_C = %s)", val);
}

void GETFC(void)
{
  fprintf(stdout, "((flag_C >> 8) & 0xFF)");
}


/* Define some common data types */

typedef unsigned char	uchar;

#define	TAB_OPCODE	23						/* Column to place opcode */
#define	TAB_PARAM	(TAB_OPCODE+8)		/* Column to place parameters */

/* Default filname extensions */

#define	EXT1		".t7"
#define	EXT2		".p7"
#define	EXT3		".u7"
#define	EXT4		".r7"

/*****************************************************************************
* Setup a table of opcode indexes.  These are used to index						  *
* the 'OpCodeName[]' array.																  *
*****************************************************************************/
enum OPCODE
{	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, JA0B, NOPB,
	JMPA, JMIA, JDRA, JLTA, JEQA, JNCA, JA0A, NOPA,
	JEIA, JEIB
};

/*****************************************************************************
* A table of opcode names.																	  *
*****************************************************************************/
char *OpcodeName[] =
{
	"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", "JA0B", "USB",
	"JMP",  "JMI",  "JDR",  "JLT",  "JEQ",  "JNC",  "JA0",  "NOP",
	"JEI",  "JEIB"
};

/*****************************************************************************
* Addressing types.  One address type exist for every possible way a			  *
* parameter needs to be displayed.  Along with a couple of extended			  *
* types used to make a disassembly more readable.									  *
*****************************************************************************/
enum ADTYPE
{	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 */
};

/*****************************************************************************
* Define one member of the opcode lookup table.										  *
*****************************************************************************/
struct DECODE_S
{	enum OPCODE	name;		/* name of opcode */
	enum ADTYPE	mode;		/* addressing mode of opcode */
};

/*****************************************************************************
* Table of opcodes and their addressing modes.										  *
*****************************************************************************/
struct DECODE_S DecodeTbl[] =
{
	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 */
	JA0B, JUMP,			/* 56 */
	NOPB, IMP,			/* 57 */

	JMPA, JUMP,			/* 58 */
	JMIA, JUMP,			/* 59 */
	JDRA, JUMP,			/* 5A */
	JLTA, JUMP,			/* 5B */
	JEQA, JUMP,			/* 5C */
	JNCA, JUMP,			/* 5D */
	JA0A, 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 */
};

uchar		*ObjCode;	/* Object code buffer for full object code */
char		OpcBfr[81];	/* Temp buffer used to build opcodes */
char		DspBfr[81];	/* Line display buffer */
uchar		Extd_f;		/* Extended diss flag, if set display extended insts. */
uchar		Pause_f;		/* Pause after each instruction flag */

/*****************************************************************************
* Print the opcode name to the 'dest' buffer.										  *
*																									  *
* Called with:																					  *
*    dest    = Pointer to buffer to receive opcode's name.						  *
*    opc     = Opcode's binary value.													  *
*    mode    = Addressing mode used by opcode.										  *
*    useBreg = Flag indicating Acc instruction should use B-reg				  *
*****************************************************************************/
void printOpc( char *dest, uint opc, uint mode, uint useBreg)
{
	int	ii;

	strcpy( OpcBfr, OpcodeName[opc]);

	/* If extended instructions being printed, use the 'useBreg' */
	/* to determine Acc used by any Acc instruction. */

	if (Extd_f)
	{
			/* if Accumulator accessed, print it */

			if (mode <= AIRG)
			{
						if (useBreg)
							OpcBfr[3] = 'B';		/* B register accessed */

						else
							OpcBfr[3] = 'A';		/* A register accessed */

						OpcBfr[4] = '\0';			/* terminate string */
			}
	}

	strlwr( OpcBfr);		/* lower case string (just my preference) */

	/* move into destination buffer without trailing '\0' */

	for (ii = 0; OpcBfr[ii] != '\0'; ii++)
		dest[ii] = OpcBfr[ii];
}

/*****************************************************************************
* Print parameters, based on the addressing mode of the instruction			  *
* to the 'dest' buffer.																		  *
*																									  *
* Called with:																					  *
*    dest    = Destination buffer of parameters.									  *
*    mode    = Addressing mode of opcode.												  *
*    adr     = Address of opcode (index into 'ObjCode[]').						  *
*    useBreg = Flag indicating Acc instruction should use B-reg				  *
*																									  *
* Returns:																						  *
*    Length of object code associated with opcode.									  *
*****************************************************************************/
uint printMode( char *dest, uint mode, uint adr, uint useBreg)
{
	uint	ii, jj, size;

	size = useBreg + 1;		/* initial size of object code */
	adr += useBreg;			/* if using B-reg skip 'USB' instruction */

	switch (mode)
	{
			/* display 4 bit immediate value */

		case AIM4:
		case IM4:
			sprintf( OpcBfr, "#$%X", ObjCode[adr] & 0x0F);
			break;

			/* display 4 bit extended immediate value */

		case AIM4X:	
			sprintf( OpcBfr, "#$%X", (ObjCode[adr] & 0x0F) << 8);
			break;

			/* display 8 bit immediate value */

		case AIM8:
			sprintf( OpcBfr, "#$%02X", ObjCode[adr+1]);
			size++;		/* add 8 bit immediate value to object code size */
			break;

			/* display the '[i]', indicating a indirect through 'I' instruction */

		case AIRG:
		case IRG:
			strcpy( OpcBfr, "[i]");
			break;

			/* *** display special 'extended' 12 bit immediate value */

			/* This is done by reading two consective acc load / add / sub */
			/* instructions and calculating what ends up in the Acc */

		case AIMX:
			ii = (ObjCode[adr] & 0x0F) << 8;	/* get 4 bit extended immediate */
			adr += useBreg + 1;					/* if point to next opcode, skip 'USB's */
			size += useBreg + 1;					/* add to object code size, include 'USB's */
			jj = ObjCode[adr] & 0x0F;			/* get 4 bit immediate value */

			/* check if the next opcode is an 'ADD' instruction (0x20-0x2F) */

			if ((ObjCode[adr] & 0xF0) == 0x20)
			{
						/* if 4 bit immediate value is 0, use 8 bit immediate value	 */

						if (jj == 0)
						{	ii += ObjCode[adr+1];	/* add 8 bit immediate value */
										size++;						/* add to oject code size */
						}
						else
							ii += jj;					/* else, just add 4 bit immediate value */
			}

			/* if not followed by an 'ADD' instruction, then must be a 'SUB' */

			else
			{
						/* if 4 bit immediate value is 0, use 8 bit immediate value	 */

						if (jj == 0)
						{	ii -= ObjCode[adr+1];	/* sub 8 bit immediate value */
										size++;						/* sub to oject code size */
						}
						else
							ii -= jj;					/* else, just sub 4 bit immediate value */
			}
			ii &= 0xFFF;							/* remove any overflow */
			sprintf( OpcBfr, "#$%03X", ii);	/* print to temperary buffer */
			break;

			/* display no parameters */

		case ACC:
		case AXLT:
		case IMP:
			OpcBfr[0] = '\0';					/* no parameters */
			break;

			/* display 12 bit immediate value */

		case IM12:
			sprintf( OpcBfr, "#$%03X",
						(ObjCode[adr] & 0x0F) +
						(ObjCode[adr+1] & 0xF0) +
						((ObjCode[adr+1] & 0x0F) << 8)
					);
			size++;
			break;

			/* display address of direct addressing mode */

		case ADIR:
		case DIR:
			sprintf( OpcBfr, "$%X", ObjCode[adr] & 0x0F);
			break;

			/* indicate a jump through the 'J' register */

		case JUMP:
/*		strcpy( OpcBfr, "[j]"); */
			OpcBfr[0] = '\0';					/* no parameters */
			break;

			/* *** special extended jump */
			/* This address mode can be used to display a 'LDJ #nnn' instruction */
			/* followed immediatly be a 'JMP' instruction. */

		case JUMPX:
			size += 2;		/* add immediate value and 'JMP' inst to object size */

			/* use 12 bit value of 'LDJ' instruction as parameter */

			sprintf( OpcBfr, "$%03X",
						(ObjCode[adr] & 0x0F) +
						(ObjCode[adr+1] & 0xF0) +
						((ObjCode[adr+1] & 0x0F) << 8)
					);
			break;
	}

	/* move into destination buffer without trailing '\0' */

	for (ii = 0; OpcBfr[ii] != '\0'; ii++)
		dest[ii] = OpcBfr[ii];

	return (size);			/* return size of opcode */
}

/*****************************************************************************
* Print the object code in hexidecimal.												  *
*																									  *
* Called with:																					  *
*    dest = Destination buffer used to receive data.								  *
*    adr  = Address of object code (index into 'ObjCode[]').					  *
*    size = Size of object code.															  *
*****************************************************************************/
void printObj( char *dest, uint adr, uint size)
{
	uint	ii;

	sprintf( OpcBfr, "%04X:", adr);		/* print address */

	/* print however many bytes contained in oject code */

	for (ii = 0; ii < size; ii++)
		sprintf( OpcBfr+((ii * 3) + 5), " %02X", ObjCode[adr+ii]);

	/* move into destination buffer without trailing '\0' */

	for (ii = 0; OpcBfr[ii] != '\0'; ii++)
		dest[ii] = OpcBfr[ii];
}

/*****************************************************************************
* Fully disassemble one opcode.															  *
*																									  *
* Called with:																					  *
*    dest    = Destination buffer to receive ASCII data.							  *
*    adr     = Address of opcode (index into ObjCode[]).							  *
*    objSize = Pointer to (uint) to receive object code size.					  *
*    brkFlg  = Pointer to a flag indicating a break in instruction flow.	  *
*****************************************************************************/

uchar	opCode;

void dissOpcode( char *dest, uint adr, uint *objSize, uint *brkFlg)
{
	uchar	/*opCode,*/ nextOpc;
	uint	useBreg;

	opCode = ObjCode[adr];					/* get opcode */

	/* check for break in code flow */

	if (DecodeTbl[opCode].name == JMPA || DecodeTbl[opCode].name == JPPB)
		*brkFlg = 1;							/* indicate code break */

	else
		*brkFlg = 0;							/* indicate no code break */

	/* Check to see if extended instructions are being disassembled. */

	if (Extd_f)
	{

			/* start by check for special prefixes */

			/* *** Use B-reg? */

			if (DecodeTbl[opCode].name == NOPB)
			{
						nextOpc = ObjCode[adr+1];

						/* does next opcode use Acc addressing? */

						if (DecodeTbl[nextOpc].mode > AIRG)
						{
										/* No, disassemble opcode NOPB */

										printOpc( dest+TAB_OPCODE, DecodeTbl[opCode].name, DecodeTbl[opCode].mode, 0);
										*objSize = printMode( dest+TAB_PARAM, DecodeTbl[opCode].mode, adr, 0);
										printObj( dest, adr, *objSize);
										return;
						}
						else
						{	useBreg = 1;				/* set to B-reg */
										opCode = nextOpc;			/* get next opcode */
						}
			}
			else
				useBreg = 0;

			/* check for extended LDA instructions */

			if ((opCode & 0xF0) == 0x00)
			{
						if (useBreg == 0 || (useBreg == 1 && ObjCode[adr+2] == 0x57))
						{
										nextOpc = ObjCode[adr+useBreg+useBreg+1];

										if ((nextOpc & 0xE0) == 0x20)
										{
															/* disasemble extended LDA instruction */

															printOpc( dest+TAB_OPCODE, LDA, AIMX, useBreg);
															*objSize = printMode( dest+TAB_PARAM, AIMX, adr, useBreg);
															printObj( dest, adr, *objSize);
															return;
										}
						}
			}

			/* check for extended JUMP instructions */

			if (DecodeTbl[opCode].name == LDJ && opCode != 0xE1)
			{
						nextOpc = ObjCode[adr+2];

						if (DecodeTbl[nextOpc].mode == JUMP)
						{
										/* Disassemble extended JUMP */

										if (DecodeTbl[nextOpc].name == JMPA ||
															DecodeTbl[nextOpc].name == JPPB)
											*brkFlg = 1;		/* set break in instruction flow flag */

										printOpc( dest+TAB_OPCODE, DecodeTbl[nextOpc].name, DecodeTbl[nextOpc].mode, useBreg);
										*objSize = printMode( dest+TAB_PARAM, JUMPX, adr, useBreg);
										printObj( dest, adr, *objSize);
										return;
						}
			}
	}
	else
		useBreg = 0;		/* no extended instructions allowed */

	/* Disassemble the opcode */

	printOpc( dest+TAB_OPCODE, DecodeTbl[opCode].name, DecodeTbl[opCode].mode, useBreg);
	*objSize = printMode( dest+TAB_PARAM, DecodeTbl[opCode].mode, adr, useBreg);
	printObj( dest, adr, *objSize);
	return;
}

CINESTATE opINP_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opINP_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * bottom 4 bits of opcode are the position of the bit we want;\n");
fprintf(stdout, "%s", "	 * obtain input value, shift over that no, and truncate to last bit.\n");
fprintf(stdout, "%s", "	 * NOTE: Masking 0x07 does interesting things on Sundance and\n");
fprintf(stdout, "%s", "	 * others, but masking 0x0F makes RipOff and others actually work :)\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = (CCPU_READPORT (CCPU_PORT_IOINPUTS) >> (opcode & 0x0F)) & 0x01;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	"); SETA0 ("register_A"); fprintf(stdout, ";               /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	"); SETFC ("register_A"); fprintf(stdout, ";\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_A;               /* save old accB */\n");
fprintf(stdout, "%s", "	register_A = cmp_new;               /* load new accB; zero other bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opINP_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opINP_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * bottom 3 bits of opcode are the position of the bit we want;\n");
fprintf(stdout, "%s", "	 * obtain Switches value, shift over that no, and truncate to last bit.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = (CCPU_READPORT (CCPU_PORT_IOSWITCHES) >> (opcode & 0x07)) & 0x01;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);               /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_B;               /* save old accB */\n");
fprintf(stdout, "%s", "	register_B = cmp_new;               /* load new accB; zero other bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opOUTsnd_A (int opcode)
{
	fprintf(stdout, "/*                        opOUTsnd_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (!(register_A & 0x01))\n");
fprintf(stdout, "%s", "		CCPU_WRITEPORT (CCPU_PORT_IOOUTPUTS, CCPU_READPORT (CCPU_PORT_IOOUTPUTS) | (0x01 << (opcode & 0x07)));\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "		CCPU_WRITEPORT (CCPU_PORT_IOOUTPUTS, CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & ~(0x01 << (opcode & 0x07)));\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if ((opcode & 0x07) == 0x05)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			/* reset coin counter */\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opOUTbi_A_A (int opcode)
{
	fprintf(stdout, "/*                        opOUTbi_A_A (%02x) */\n", opcode);
fprintf(stdout, "/* NEW CODE - CHECK IT */\n");
fprintf(stdout, "%s", "	if ((0x%2x & 0x07) != 6)\n", opcode);
fprintf(stdout, "%s", "	{\n");
                          opOUTsnd_A (opcode); /* Macro expand */
fprintf(stdout, "%s", "	}\n");

fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	vgColour = register_A & 0x01 ? 0x0f: 0x07;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opOUT16_A_A (int opcode)
{
	fprintf(stdout, "/*                        opOUT16_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if ((opcode & 0x07) != 6)\n");
fprintf(stdout, "%s", "		return opOUTsnd_A (opcode);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if ((register_A & 0x1) != 1)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			vgColour = FromX & 0x0F;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			if (!vgColour)\n");
fprintf(stdout, "%s", "				vgColour = 1;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opOUT64_A_A (int opcode)
{
	fprintf(stdout, "/*                        opOUT64_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opOUTWW_A_A (int opcode)
{
	fprintf(stdout, "/*                        opOUTWW_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if ((opcode & 0x07) != 6)\n");
fprintf(stdout, "%s", "		return opOUTsnd_A (opcode);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if ((register_A & 0x1) == 1)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			CINEWORD temp_word = ~FromX & 0x0FFF;\n");
fprintf(stdout, "%s", "			if (!temp_word)   /* black */\n");
fprintf(stdout, "%s", "				vgColour = 0;\n");
fprintf(stdout, "%s", "			else\n");
fprintf(stdout, "%s", "			{   /* non-black */\n");
fprintf(stdout, "%s", "						if (temp_word & 0x0888)\n");
fprintf(stdout, "%s", "							/* bright */\n");
fprintf(stdout, "%s", "							vgColour = ((temp_word >> 1) & 0x04) | ((temp_word >> 6) & 0x02) | ((temp_word >> 11) & 0x01) | 0x08;\n");
fprintf(stdout, "%s", "						else if (temp_word & 0x0444)\n");
fprintf(stdout, "%s", "							/* dim bits */\n");
fprintf(stdout, "%s", "							vgColour = (temp_word & 0x04) | ((temp_word >> 5) & 0x02) | ((temp_word >> 10) & 0x01);\n");
fprintf(stdout, "%s", "			}\n");
fprintf(stdout, "%s", "	} /* colour change? == 1 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opOUTsnd_B (int opcode)
{
	fprintf(stdout, "/*                        opOUTsnd_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opOUTbi_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opOUTbi_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x07;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (temp_byte - 0x06)\n");
fprintf(stdout, "%s", "		return opOUTsnd_B (opcode);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	vgColour = ((register_B & 0x01) << 3) | 0x07;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opOUT16_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opOUT16_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x07;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (temp_byte - 0x06)\n");
fprintf(stdout, "%s", "		return opOUTsnd_B (opcode);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if ((register_B & 0xFF) != 1)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			vgColour = FromX & 0x0F;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			if (!vgColour)\n");
fprintf(stdout, "%s", "				vgColour = 1;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opOUT64_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opOUT64_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opOUTWW_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opOUTWW_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opLDAimm_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAimm_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;   /* pick up immediate value */\n");
fprintf(stdout, "%s", "	temp_word <<= 8;                          /* LDAimm is the HIGH nibble!*/\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                      /* set new comparison flag */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                     /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                     /* ??? clear carry? */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                     /* step back cmp flag */\n");
fprintf(stdout, "%s", "	register_A = temp_word;                   /* set the register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;                           /* swap state and end opcode */\n");
}

CINESTATE opLDAimm_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAimm_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;   /* pick up immediate value */\n");
fprintf(stdout, "%s", "	temp_word <<= 8;                          /* LDAimm is the HIGH nibble!*/\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                      /* set new comparison flag */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                     /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                     /* step back cmp flag */\n");
fprintf(stdout, "%s", "	register_B = temp_word;                   /* set the register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLDAdir_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAdir_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;        /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;  /* set I register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                  /* new acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                          /* back up bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                          /* store old acc */\n");
fprintf(stdout, "%s", "	register_A = cmp_new;                          /* store new acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLDAdir_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAdir_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;        /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;  /* set I register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                  /* new acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                          /* back up bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                          /* store old acc */\n");
fprintf(stdout, "%s", "	register_B = cmp_new;                          /* store new acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLDAirg_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAirg_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "	register_A = cmp_new;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLDAirg_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLDAirg_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "	register_B = cmp_new;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opADDimm_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDimm_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;     /* get imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                        /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                       /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                       /* store old acc for later */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A += temp_word;                    /* add values */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                       /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_A &= 0xFFF;                        /* toss out >12bit carry */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opADDimm_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDimm_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;     /* get imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                        /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                       /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                       /* store old acc for later */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B += temp_word;                    /* add values */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                       /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_B &= 0xFFF;                        /* toss out >12bit carry */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opADDimmX_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDimmX_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = CCPU_FETCH (register_PC++);       /* get extended value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                       /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                       /* store old acc for later */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A += cmp_new;                      /* add values */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                       /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_A &= 0xFFF;                        /* toss out >12bit carry */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opADDimmX_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDimmX_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = CCPU_FETCH (register_PC++);       /* get extended value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                       /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                       /* store old acc for later */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B += cmp_new;                      /* add values */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                       /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_B &= 0xFFF;                        /* toss out >12bit carry */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opADDdir_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDdir_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;         /* fetch imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;   /* set regI addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                   /* fetch imm real value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                           /* store bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                           /* store old acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A += cmp_new;                          /* do acc operation */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                           /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opADDdir_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opADDdir_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;         /* fetch imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;   /* set regI addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                   /* fetch imm real value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                           /* store bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                           /* store old acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B += cmp_new;                          /* do acc operation */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                           /* store carry and extra */\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opAWDirg_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opAWDirg_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A += cmp_new;\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opAWDirg_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opAWDirg_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B += cmp_new;\n");
fprintf(stdout, "%s", "	SETFC (register_B);\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBimm_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBimm_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 *	SUBtractions are negate-and-add instructions of the CCPU; what\n");
fprintf(stdout, "%s", "	 *	a pain in the ass.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;         /* ones compliment */\n");
fprintf(stdout, "%s", "	register_A += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBimm_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBimm_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * SUBtractions are negate-and-add instructions of the CCPU; what\n");
fprintf(stdout, "%s", "	 * a pain in the ass.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;         /* ones compliment */\n");
fprintf(stdout, "%s", "	register_B += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBimmX_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBimmX_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = CCPU_FETCH (register_PC++);       /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                          /* save cmp value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                         /* store bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                         /* back up regA */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;        /* ones compliment */\n");
fprintf(stdout, "%s", "	register_A += temp_word;                      /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                         /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;                         /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBimmX_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBimmX_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = CCPU_FETCH (register_PC++);       /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                          /* save cmp value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                         /* store bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                         /* back up regA */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;        /* ones compliment */\n");
fprintf(stdout, "%s", "	register_B += temp_word;                      /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                         /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;                         /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBdir_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBdir_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = opcode & 0x0F;         /* fetch imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_word;   /* set regI addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (cmp_new ^ 0xFFF) + 1;           /* ones compliment */\n");
fprintf(stdout, "%s", "	register_A += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBdir_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBdir_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word;\n");
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;         /* fetch imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;   /* set regI addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (cmp_new ^ 0xFFF) + 1;           /* ones compliment */\n");
fprintf(stdout, "%s", "	register_B += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBirg_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBirg_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* sub [i] */\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (cmp_new ^ 0xFFF) + 1;           /* ones compliment */\n");
fprintf(stdout, "%s", "	register_A += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_A);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opSUBirg_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opSUBirg_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* sub [i] */\n");
fprintf(stdout, "%s", "	cmp_new = ram[register_I];\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (cmp_new ^ 0xFFF) + 1;           /* ones compliment */\n");
fprintf(stdout, "%s", "	register_B += temp_word;                       /* add */\n");
fprintf(stdout, "%s", "	SETFC (register_B);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;                          /* mask final regA value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opCMPdir_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opCMPdir_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * compare direct mode; don't modify regs, just set carry flag or not.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word;\n");
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;       /* obtain relative addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte; /* build real addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = ram[register_I];\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                          /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                         /* backup bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;                         /* backup old acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;        /* ones compliment */\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opCMPdir_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opCMPdir_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word;\n");
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;       /* obtain relative addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte; /* build real addr */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = ram[register_I];\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                          /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                         /* backup bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                         /* backup old acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word = (temp_word ^ 0xFFF) + 1;        /* ones compliment */\n");
fprintf(stdout, "%s", "	temp_word += register_B;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);                          /* pick up top bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opANDirg_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opANDirg_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A &= cmp_new;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opANDirg_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opANDirg_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = ram[register_I];                /* new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B &= cmp_new;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opLDJimm_A_A (int opcode)
{
	fprintf(stdout, "/*                        opLDJimm_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = CCPU_FETCH (register_PC++);      /* upper part of address */\n");
fprintf(stdout, "%s", "	temp_byte = (temp_byte << 4) |             /* Silly CCPU; Swap */\n");
fprintf(stdout, "%s", "	            (temp_byte >> 4);              /* nibbles */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* put the upper 8 bits above the existing 4 bits */\n");
fprintf(stdout, "%s", "	register_J = (opcode & 0x0F) | (temp_byte << 4);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opLDJimm_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opLDJimm_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = CCPU_FETCH (register_PC++);      /* upper part of address */\n");
fprintf(stdout, "%s", "	temp_byte = (temp_byte << 4) |             /* Silly CCPU; Swap */\n");
fprintf(stdout, "%s", "	            (temp_byte >> 4);              /* nibbles */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* put the upper 8 bits above the existing 4 bits */\n");
fprintf(stdout, "%s", "	register_J = (opcode & 0x0F) | (temp_byte << 4);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opLDJirg_A_A (int opcode)
{
	fprintf(stdout, "/*                        opLDJirg_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* load J reg from value at last dir addr */\n");
fprintf(stdout, "%s", "	register_J = ram[register_I];\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opLDJirg_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opLDJirg_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	register_J = ram[register_I];\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opLDPimm_A_A (int opcode)
{
	fprintf(stdout, "/*                        opLDPimm_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* load page register from immediate */\n");
fprintf(stdout, "%s", "	register_P = opcode & 0x0F;  /* set page register */\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opLDPimm_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opLDPimm_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* load page register from immediate */\n");
fprintf(stdout, "%s", "	register_P = opcode & 0x0F;  /* set page register */\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opLDIdir_A_A (int opcode)
{
	fprintf(stdout, "/*                        opLDIdir_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* load regI directly .. */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEBYTE temp_byte = (register_P << 4) +           /* get ram page ... */\n");
fprintf(stdout, "%s", "	         (opcode & 0x0F); /* and imm half of ram addr.. */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = ram[temp_byte] & 0xFF;      /* set/mask new register_I */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opLDIdir_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opLDIdir_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = (register_P << 4) +           /* get ram page ... */\n");
fprintf(stdout, "%s", "	         (opcode & 0x0F); /* and imm half of ram addr.. */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = ram[temp_byte] & 0xFF;      /* set/mask new register_I */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opSTAdir_A_A (int opcode)
{
	fprintf(stdout, "/*                        opSTAdir_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;        /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;  /* set I register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	ram[register_I] = register_A;               /* store acc to RAM */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opSTAdir_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opSTAdir_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0x0F;        /* snag imm value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_I = (register_P << 4) + temp_byte;  /* set I register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	ram[register_I] = register_B;               /* store acc to RAM */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opSTAirg_A_A (int opcode)
{
	fprintf(stdout, "/*                        opSTAirg_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * STA into address specified in regI. Nice and easy :)\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	ram[register_I] = register_A;               /* store acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opSTAirg_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opSTAirg_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	ram[register_I] = register_B;               /* store acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}


CINESTATE opXLT_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opXLT_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * XLT is weird; it loads the current accumulator with the bytevalue\n");
fprintf(stdout, "%s", "	 * at ROM location pointed to by the accumulator; this allows the\n");
fprintf(stdout, "%s", "	 * program to read the program itself..\n");
fprintf(stdout, "%s", "	 *		NOTE! Next opcode is *IGNORED!* because of a twisted side-effect\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = CCPU_FETCH (((register_PC - 1) & 0xF000) + register_A);   /* store new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);           /* store bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;           /* back up acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A = cmp_new;           /* new acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_PC++;               /* bump PC twice because XLT is fucked up */\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opXLT_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opXLT_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = CCPU_FETCH (((register_PC - 1) & 0xF000) + register_B);   /* store new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);           /* store bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;           /* back up acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B = cmp_new;           /* new acc value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_PC++;               /* bump PC twice because XLT is fucked up */\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opMULirg_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opMULirg_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = opcode & 0xFF;    /* (for ease and speed) */\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = ram[register_I];               /* pick up ram value */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word <<= 4;                              /* shift into ADD position */\n");
fprintf(stdout, "%s", "	register_B <<= 4;                             /* get sign bit 15 */\n");
fprintf(stdout, "%s", "	register_B |= (register_A >> 8);            /* bring in A high nibble */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A = ((register_A & 0xFF) << 8) | /* shift over 8 bits */\n");
fprintf(stdout, "%s", "	          temp_byte;  /* pick up opcode */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (register_A & 0x100)\n");
fprintf(stdout, "%s", "	{					   /* 1bit shifted out? */\n");
fprintf(stdout, "%s", "			register_A = (register_A >> 8) |\n");
fprintf(stdout, "%s", "			             ((register_B & 0xFF) << 8);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			SETA0 (register_A & 0xFF);                  /* store bit0 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_A >>= 1;\n");
fprintf(stdout, "%s", "			register_A &= 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout,       "			register_B = "); SAR("register_B","4"); fprintf(stdout, "\n");
fprintf(stdout, "%s", "			cmp_old = register_B & 0x0F;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_B = SAR(register_B,1);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_B &= 0xFFF;\n");
fprintf(stdout, "%s", "			register_B += cmp_new;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			SETFC (register_B);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_B &= 0xFFF;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			register_A = (register_A >> 8) |    /* Bhigh | Alow */\n");
fprintf(stdout, "%s", "			             ((register_B & 0xFF) << 8);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_word = register_A & 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			SETA0 (temp_word & 0xFF);                   /* store bit0 */\n");
fprintf(stdout, "%s", "			cmp_old = temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_word += cmp_new;\n");
fprintf(stdout, "%s", "			SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_A >>= 1;\n");
fprintf(stdout, "%s", "			register_A &= 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_B = SAR(register_B,5);\n");
fprintf(stdout, "%s", "			register_B &= 0xFFF;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opMULirg_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opMULirg_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = ram[register_I];\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "	SETA0 (register_A & 0xFF);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B <<= 4;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B = SAR(register_B,5);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (register_A & 0x01)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			register_B += temp_word;\n");
fprintf(stdout, "%s", "			SETFC (register_B);\n");
fprintf(stdout, "%s", "			register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			temp_word += register_B;\n");
fprintf(stdout, "%s", "			SETFC (temp_word);\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}


CINESTATE opLSRe_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSRe_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * EB; right shift pure; fill new bit with zero.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0BEB;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A >>= 1;\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSRe_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSRe_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0BEB;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_B;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B >>= 1;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSRf_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSRf_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLSRf 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSRf_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSRf_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLSRf 2\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLe_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLe_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * EC; left shift pure; fill new bit with zero *\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0CEC;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A <<= 1;\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLe_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLe_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0CEC;                          /* data register */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;                         /* magic value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A);                        /* back up bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_B;                        /* store old acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_B;                     /* add to acc */\n");
fprintf(stdout, "%s", "	SETFC (temp_word);                         /* store carry flag */\n");
fprintf(stdout, "%s", "	register_B <<= 1;                            /* add regA to itself */\n");
fprintf(stdout, "%s", "	register_B &= 0xFFF;                         /* toss excess bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLf_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLf_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLSLf 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLf_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLf_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLSLf 2\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRe_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRe_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* agh! I dislike these silly 12bit processors :P */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = 0x0DED;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);           /* store bit0 */\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A <<= 4; /* get sign bit */\n");
fprintf(stdout, "%s", "	register_A = SAR(register_A,5);\n");
fprintf(stdout, "%s", "	register_A &= 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRe_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRe_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	cmp_new = 0x0DED;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	SETFC (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B <<= 4;\n");
fprintf(stdout, "%s", "	register_B = SAR(register_B,5);\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRf_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRf_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opASRf 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRf_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRf_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opASRf 2\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRDe_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRDe_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * Arithmetic shift right of D (A+B) .. B is high (sign bits).\n");
fprintf(stdout, "%s", "	 * divide by 2, but leave the sign bit the same. (ie: 1010 -> 1001)\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0EEE;\n");
fprintf(stdout, "%s", "	CINEWORD temp_word_2;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;          /* save new acc value */\n");
fprintf(stdout, "%s", "	SETA0 (register_A & 0xFF);  /* save old accA bit0 */\n");
fprintf(stdout, "%s", "	cmp_old = register_A;         /* save old acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A <<= 4;\n");
fprintf(stdout, "%s", "	register_B <<= 4;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word_2 = (register_B >> 4) << 15;\n");
fprintf(stdout, "%s", "	register_B = SAR(register_B,5);\n");
fprintf(stdout, "%s", "	register_A = (register_A >> 1) | temp_word_2;\n");
fprintf(stdout, "%s", "	register_A >>= 4;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRDe_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRDe_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0EEE;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A & 0xFF);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_B;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "	register_B <<= 4;\n");
fprintf(stdout, "%s", "	register_B = SAR(register_B,5);\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRDf_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRDf_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opASRDf 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opASRDf_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opASRDf_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opASRDf 2\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLDe_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLDe_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* LSLDe -- Left shift through both accumulators; lossy in middle. */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0FEF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "	register_A <<= 1;                             /* logical shift left */\n");
fprintf(stdout, "%s", "	register_A &= 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B <<= 1;\n");
fprintf(stdout, "%s", "	register_B &= 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLDe_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLDe_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLSLD 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLDf_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLDf_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* LSLDf */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_A;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_A;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_A <<= 1;\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B <<= 1;\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLSLDf_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLSLDf_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* not 'the same' as the A->AA version above */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	cmp_new = temp_word;\n");
fprintf(stdout, "%s", "	SETA0 (register_A);\n");
fprintf(stdout, "%s", "	cmp_old = register_B;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	temp_word += register_B;\n");
fprintf(stdout, "%s", "	SETFC (temp_word);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	register_B <<= 1;\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opJMP_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJMP_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * simple jump; change PC and continue..\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	JMP();\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJMP_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJMP_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	JMP();\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJEI_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJEI_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (FromX & 0x800)\n");
fprintf(stdout, "%s", "		FromX |= 0xF000;\n");
fprintf(stdout, "%s", "	if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80))\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJEI_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJEI_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (FromX & 0x800)\n");
fprintf(stdout, "%s", "		FromX |= 0xF000;\n");
fprintf(stdout, "%s", "	if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80))\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJEI_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJEI_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (FromX & 0x800)\n");
fprintf(stdout, "%s", "		FromX |= 0xF000;\n");
fprintf(stdout, "%s", "	if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80))\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	else\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800)\n");
fprintf(stdout, "%s", "				JMP();\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJMI_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJMI_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * previous instruction was not an ACC instruction, nor was the\n");
fprintf(stdout, "%s", "	 * instruction twice back a USB, therefore minus flag test the\n");
fprintf(stdout, "%s", "	 * current A-reg\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* negative acc? */\n");
fprintf(stdout, "%s", "	if (register_A & 0x800)\n");
fprintf(stdout, "%s", "		JMP();	  /* yes -- do jump */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJMI_AA_A (int opcode)
{
	fprintf(stdout, "/*                        opJMI_AA_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* previous acc negative? Jump if so... */\n");
fprintf(stdout, "%s", "	if (cmp_old & 0x800)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJMI_BB_A (int opcode)
{
	fprintf(stdout, "/*                        opJMI_BB_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (register_B & 0x800)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJMI_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJMI_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (register_A & 0x800)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJLT_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJLT_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* jump if old acc equals new acc */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (cmp_new < cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJLT_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJLT_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (cmp_new < cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJEQ_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJEQ_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* jump if equal */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (cmp_new == cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJEQ_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJEQ_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (cmp_new == cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJA0_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJA0_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (acc_a0 & 0x01)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJA0_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJA0_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (acc_a0 & 0x01)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJNC_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJNC_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (!(GETFC() & 0xF0))\n");
fprintf(stdout, "%s", "		JMP(); /* no carry, so jump */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJNC_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJNC_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (!(GETFC() & 0xF0))\n");
fprintf(stdout, "%s", "		JMP(); /* no carry, so jump */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJDR_A_A (int opcode)
{
	fprintf(stdout, "/*                        opJDR_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * Calculate number of cycles executed since\n");
fprintf(stdout, "%s", "	 * last 'VDR' instruction, add two and use as\n");
fprintf(stdout, "%s", "	 * cycle count, never branch\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opJDR_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJDR_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * Calculate number of cycles executed since\n");
fprintf(stdout, "%s", "	 * last 'VDR' instruction, add two and use as\n");
fprintf(stdout, "%s", "	 * cycle count, never branch\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opNOP_A_A (int opcode)
{
	fprintf(stdout, "/*                        opNOP_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opNOP_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opNOP_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJPP32_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJPP32_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * 00 = Offset 0000h\n");
fprintf(stdout, "%s", "	 * 01 = Offset 1000h\n");
fprintf(stdout, "%s", "	 * 02 = Offset 2000h\n");
fprintf(stdout, "%s", "	 * 03 = Offset 3000h\n");
fprintf(stdout, "%s", "	 * 04 = Offset 4000h\n");
fprintf(stdout, "%s", "	 * 05 = Offset 5000h\n");
fprintf(stdout, "%s", "	 * 06 = Offset 6000h\n");
fprintf(stdout, "%s", "	 * 07 = Offset 7000h\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = (register_P & 0x07) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJPP32_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJPP32_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = (register_P & 0x07) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJPP16_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJPP16_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * 00 = Offset 0000h\n");
fprintf(stdout, "%s", "	 * 01 = Offset 1000h\n");
fprintf(stdout, "%s", "	 * 02 = Offset 2000h\n");
fprintf(stdout, "%s", "	 * 03 = Offset 3000h\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = (register_P & 0x03) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJPP16_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJPP16_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = (register_P & 0x03) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJMP_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJMP_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	JMP();\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJPP8_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJPP8_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * \"long jump\"; combine P and J to jump to a new far location (that can\n");
fprintf(stdout, "%s", "								        *	be more than 12 bits in address). After this jump, further jumps\n");
fprintf(stdout, "%s", "	 * are local to this new page.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	CINEWORD temp_word = ((register_P & 0x03) - 1) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJPP8_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opJPP8_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEWORD temp_word = ((register_P & 0x03) - 1) << 12;  /* rom offset */\n");
fprintf(stdout, "%s", "	register_PC = register_J + temp_word;\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opJMI_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJMI_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (register_A & 0x800)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJMI_AA_B (int opcode)
{
	fprintf(stdout, "/*                        opJMI_AA_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opJMI 3\n\");\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJMI_BB_B (int opcode)
{
	fprintf(stdout, "/*                        opJMI_BB_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opJMI 4\n\");\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJLT_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJLT_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (cmp_new < cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJEQ_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJEQ_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (cmp_new == cmp_old)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJA0_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJA0_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (GETA0() & 0x01)\n");
fprintf(stdout, "%s", "		JMP();\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJNC_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJNC_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	if (!(GETFC() & 0x0F0))\n");
fprintf(stdout, "%s", "		JMP(); /* if no carry, jump */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opJDR_A_B (int opcode)
{
	fprintf(stdout, "/*                        opJDR_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* register_PC++; */\n");
fprintf(stdout, "%s", "	fprintf (stderr, \"The hell? No PC incrementing?\n\");\n");
fprintf(stdout, "%s", "	state = state_B;\n");
}


CINESTATE opNOP_A_B (int opcode)
{
	fprintf(stdout, "/*                        opNOP_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	state = state_B;\n");
}

CINESTATE opLLT_A_AA (int opcode)
{
	fprintf(stdout, "/*                        opLLT_A_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	CINEBYTE temp_byte = 0;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	while (1)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			CINEWORD temp_word = register_A >> 8;  /* register_A's high bits */\n");
fprintf(stdout, "%s", "			temp_word &= 0x0A;                   /* only want PA11 and PA9 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			if (temp_word)\n");
fprintf(stdout, "%s", "			{\n");
fprintf(stdout, "%s", "						temp_word ^= 0x0A;                   /* flip the bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "						if (temp_word)\n");
fprintf(stdout, "%s", "							break;			        /* if not zero, mismatch found */\n");
fprintf(stdout, "%s", "			}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_word = register_B >> 8;         /* regB's top bits */\n");
fprintf(stdout, "%s", "			temp_word &= 0x0A;                   /* only want SA11 and SA9 */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			if (temp_word)\n");
fprintf(stdout, "%s", "			{\n");
fprintf(stdout, "%s", "						temp_word ^= 0x0A;                   /* flip bits */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "						if (temp_word)\n");
fprintf(stdout, "%s", "							break;                          /* if not zero, mismatch found */\n");
fprintf(stdout, "%s", "			}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			register_A <<= 1;                    /* shift regA */\n");
fprintf(stdout, "%s", "			register_B <<= 1;                    /* shift regB */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_byte ++;\n");
fprintf(stdout, "%s", "			if (!temp_byte)\n");
fprintf(stdout, "%s", "				state = state_AA;\n");
fprintf(stdout, "%s", "        /* try again */\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	vgShiftLength = temp_byte;\n");
fprintf(stdout, "%s", "	register_A &= 0x0FFF;\n");
fprintf(stdout, "%s", "	register_B &= 0x0FFF;\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opLLT_B_AA (int opcode)
{
	fprintf(stdout, "/*                        opLLT_B_AA (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opLLT 1\n\");\n");
fprintf(stdout, "%s", "	state = state_AA;\n");
}

CINESTATE opVIN_A_A (int opcode)
{
	fprintf(stdout, "/*                        opVIN_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* set the starting address of a vector */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	FromX = register_A & 0xFFF;            /* regA goes to x-coord */\n");
fprintf(stdout, "%s", "	FromY = register_B & 0xFFF;            /* regB goes to y-coord */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opVIN_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opVIN_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	FromX = register_A & 0xFFF;            /* regA goes to x-coord */\n");
fprintf(stdout, "%s", "	FromY = register_B & 0xFFF;            /* regB goes to y-coord */\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}

CINESTATE opWAI_A_A (int opcode)
{
	fprintf(stdout, "/*                        opWAI_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* wait for a tick on the watchdog */\n");
fprintf(stdout, "%s", "	bNewFrame = 1;\n");
fprintf(stdout, "%s", "	bailOut = TRUE;\n");
fprintf(stdout, "%s", "	state = state;\n");
}

CINESTATE opWAI_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opWAI_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	bNewFrame = 1;\n");
fprintf(stdout, "%s", "	bailOut = TRUE;\n");
fprintf(stdout, "%s", "	state = state;\n");
}

CINESTATE opVDR_A_A (int opcode)
{
	fprintf(stdout, "/*                        opVDR_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* set ending points and draw the vector, or buffer for a later draw. */\n");
fprintf(stdout, "%s", "	int ToX = register_A & 0xFFF;\n");
fprintf(stdout, "%s", "	int ToY = register_B & 0xFFF;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/*\n");
fprintf(stdout, "%s", "	 * shl 20, sar 20; this means that if the CCPU reg should be -ve,\n");
fprintf(stdout, "%s", "	 * we should be negative as well.. sign extended.\n");
fprintf(stdout, "%s", "	 */\n");
fprintf(stdout, "%s", "	if (FromX & 0x800)\n");
fprintf(stdout, "%s", "		FromX |= 0xFFFFF000;\n");
fprintf(stdout, "%s", "	if (ToX & 0x800)\n");
fprintf(stdout, "%s", "		ToX |= 0xFFFFF000;\n");
fprintf(stdout, "%s", "	if (FromY & 0x800)\n");
fprintf(stdout, "%s", "		FromY |= 0xFFFFF000;\n");
fprintf(stdout, "%s", "	if (ToY & 0x800)\n");
fprintf(stdout, "%s", "		ToY |= 0xFFFFF000;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* figure out the vector */\n");
fprintf(stdout, "%s", "	ToX -= FromX;\n");
fprintf(stdout, "%s", "	ToX = SAR(ToX,vgShiftLength);\n");
fprintf(stdout, "%s", "	ToX += FromX;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	ToY -= FromY;\n");
fprintf(stdout, "%s", "	ToY = SAR(ToY,vgShiftLength);\n");
fprintf(stdout, "%s", "	ToY += FromY;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* do orientation flipping, etc. */\n");
fprintf(stdout, "%s", "	/* NOTE: this has been removed on the assumption that the vector draw routine can do it all */\n");
fprintf(stdout, "%s", "#if !RAW_VECTORS\n");
fprintf(stdout, "%s", "	if (bFlipX)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			ToX = sdwGameXSize - ToX;\n");
fprintf(stdout, "%s", "			FromX = sdwGameXSize - FromX;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	if (bFlipY)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			ToY = sdwGameYSize - ToY;\n");
fprintf(stdout, "%s", "			FromY = sdwGameYSize - FromY;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	FromX += sdwXOffset;\n");
fprintf(stdout, "%s", "	ToX += sdwXOffset;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	FromY += sdwYOffset;\n");
fprintf(stdout, "%s", "	ToY += sdwYOffset;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* check real coords */\n");
fprintf(stdout, "%s", "	if (bSwapXY)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			CINEWORD temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_word = ToY;\n");
fprintf(stdout, "%s", "			ToY = ToX;\n");
fprintf(stdout, "%s", "			ToX = temp_word;\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "			temp_word = FromY;\n");
fprintf(stdout, "%s", "			FromY = FromX;\n");
fprintf(stdout, "%s", "			FromX = temp_word;\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "#endif\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	/* render the line */\n");
fprintf(stdout, "%s", "	CinemaVectorData (FromX, FromY, ToX, ToY, vgColour);\n");
fprintf(stdout, "%s", "\n");
fprintf(stdout, "%s", "	state = state_A;\n");
}

CINESTATE opVDR_B_BB (int opcode)
{
	fprintf(stdout, "/*                        opVDR_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	UNFINISHED (\"opVDR B 1\n\");\n");
fprintf(stdout, "%s", "	state = state_BB;\n");
}









CINESTATE tJPP_A_B (int opcode)
{
	fprintf(stdout, "/*                        tJPP_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */\n");
fprintf(stdout, "%s", "	switch (ccpu_msize)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_4K:\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_8K:\n");
fprintf(stdout, "%s", "				return opJPP8_A_B (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_16K:\n");
fprintf(stdout, "%s", "				return opJPP16_A_B (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_32K:\n");
fprintf(stdout, "%s", "				return opJPP32_A_B (opcode);\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	fprintf (stderr, \"Out of range JPP!\n\");\n");
fprintf(stdout, "%s", "	return opJPP32_A_B (opcode);\n");
}

CINESTATE tJPP_B_BB (int opcode)
{
	fprintf(stdout, "/*                        tJPP_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	/* MSIZE -- 0 = 4k, 1 = 8k, 2 = 16k, 3 = 32k */\n");
fprintf(stdout, "%s", "	switch (ccpu_msize)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_4K:\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_8K:\n");
fprintf(stdout, "%s", "				return opJPP8_B_BB (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_16K:\n");
fprintf(stdout, "%s", "				return opJPP16_B_BB (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MEMSIZE_32K:\n");
fprintf(stdout, "%s", "				return opJPP32_B_BB (opcode);\n");
fprintf(stdout, "%s", "	}\n");
fprintf(stdout, "%s", "	fprintf (stderr, \"Out of range JPP!\n\");\n");
fprintf(stdout, "%s", "	/* state = state; */\n");
}



CINESTATE tJMI_A_B (int opcode)
{
	fprintf(stdout, "/*                        tJMI_A_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_A_B (opcode) : opJEI_A_B (opcode);\n");
}

CINESTATE tJMI_A_A (int opcode)
{
	fprintf(stdout, "/*                        tJMI_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_A_A (opcode) : opJEI_A_A (opcode);\n");
}

CINESTATE tJMI_AA_B (int opcode)
{
	fprintf(stdout, "/*                        tJMI_AA_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_AA_B (opcode) : opJEI_AA_B (opcode);\n");
}

CINESTATE tJMI_AA_A (int opcode)
{
	fprintf(stdout, "/*                        tJMI_AA_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_AA_A (opcode) : opJEI_A_A (opcode);\n");
}

CINESTATE tJMI_B_BB1 (int opcode)
{
	fprintf(stdout, "/*                        tJMI_B_BB1 (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_B_BB (opcode) : opJEI_B_BB (opcode);\n");
}

CINESTATE tJMI_BB_B (int opcode)
{
	fprintf(stdout, "/*                        tJMI_BB_B (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_BB_B (opcode) : opJEI_A_B (opcode);\n");
}

CINESTATE tJMI_BB_A (int opcode)
{
	fprintf(stdout, "/*                        tJMI_BB_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	return (ccpu_jmi_dip) ? opJMI_BB_A (opcode) : opJEI_A_A (opcode);\n");
}









CINESTATE tOUT_A_A (int opcode)
{
	fprintf(stdout, "/*                        tOUT_A_A (%02x) */\n", opcode);
fprintf(stdout, "%s", "	switch (ccpu_monitor)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_16LEV:\n");
fprintf(stdout, "%s", "				return opOUT16_A_A (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_64LEV:\n");
fprintf(stdout, "%s", "				return opOUT64_A_A (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_WOWCOL:\n");
fprintf(stdout, "%s", "				return opOUTWW_A_A (opcode);\n");
fprintf(stdout, "%s", "			default:\n");
fprintf(stdout, "%s", "				return opOUTbi_A_A (opcode);\n");
fprintf(stdout, "%s", "	}\n");
}

CINESTATE tOUT_B_BB (int opcode)
{
	fprintf(stdout, "/*                        tOUT_B_BB (%02x) */\n", opcode);
fprintf(stdout, "%s", "	switch (ccpu_monitor)\n");
fprintf(stdout, "%s", "	{\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_16LEV:\n");
fprintf(stdout, "%s", "				return opOUT16_B_BB (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_64LEV:\n");
fprintf(stdout, "%s", "				return opOUT64_B_BB (opcode);\n");
fprintf(stdout, "%s", "			case CCPU_MONITOR_WOWCOL:\n");
fprintf(stdout, "%s", "				return opOUTWW_B_BB (opcode);\n");
fprintf(stdout, "%s", "			default:\n");
fprintf(stdout, "%s", "				return opOUTbi_B_BB (opcode);\n");
fprintf(stdout, "%s", "	}\n");
}

void main( int argc, char *argv[])
{
	int			inFile, err, ii;
	static char	fileName[131];
	int			nameLen, romSize, startAdr, endAdr, romidx, objidx;
	long			tempSize;
	uint			objSize, brk_f;
	uchar			*romBfr;
	char			*gamename;

	fputs( "/* CINEDISM - Cinematronics Game ROM Disassembler. */\n", stdout);
	fputs( "/* Version 1.1   Written by Zonn Moore. */\n", stdout);
	fputs( "/* Released to the public domain by the author, distribute freely. */\n", stdout);

        if (argc == 1) {
                /* hacked defaults for tailgunr */
		gamename = "tailgunr";
		startAdr = 0;
		endAdr = 0x1fff;
		Extd_f = 0;					/* reset flags */
		Pause_f = 0;
	} else if (argc < 4) {
			fputs( "\nUse: CINEDISM game start end [/x] [/p]\n", stderr);
			fputs( "\nWhere:", stderr);
			fputs( "\n   game  = Base name of game ROMs to disassemble.", stderr);
			fputs( "\n   start = Hexidecimal start address of disassembly.", stderr);
			fputs( "\n   end   = Hexidecimal end address of disassembly.", stderr);
			fputs( "\n   [/x]  = Use an intellegent 'extended' instruction set.", stderr);
			fputs( "\n   [/p]  = Pause after each instruction.\n", stderr);

			fputs( "\nThe base filename of the ROMs is given as 'game'.", stderr);

			fprintf( stderr, "\nThe assumed extensions are \"%s\", \"%s\", \"%s\", and \"%s\".\n",
							EXT1, EXT2, EXT3, EXT4);

			exit( 0);
	} else {

	/* read in start and end addresses */

        gamename = argv[1];
	sscanf( argv[2], "%x", &startAdr);
	sscanf( argv[3], "%x", &endAdr);

	if (startAdr > endAdr)
	{	fputs( "\nStart address must be greater than or equal to end address.\n", stderr);
			exit( 0);
	}

	Extd_f = 0;					/* reset flags */
	Pause_f = 0;

	/* scan for flags */

	for (ii = 4; ii < argc; ii++)
	{
			if (strcasecmp( argv[ii], "/x") == 0)
				Extd_f = 1;		/* set flag true */

			else if (strcasecmp( argv[ii], "/p") == 0)
				Pause_f = 1;	/* set flag true */

			/* else, what the heck is it? */

			else
			{	fprintf( stderr, "\nInvalid parameter: %s\n", argv[ii]);
						exit( 0);
			}
	}
	}

	/* Read ROMs.  Start by allocating storage for ROMs and Object code */

	romBfr = (uchar *)malloc( 4096);		/* Rom storage */
	ObjCode = (uchar *)malloc( 32768U);	/* Object code */

	if (romBfr == 0 || ObjCode == 0)
	{	fputs( "\nNot enough memory!\n", stderr);
			exit( 0);
	}

	/* get file name and read in ROMs */

	nameLen = strlen( gamename);				/* get length of filename */

	memcpy( fileName, gamename, nameLen);	/* get games name */

	/* open EXT1 (lower, even, ROM) */

	strcpy( fileName+nameLen, EXT1);

	inFile = open( fileName, O_RDONLY);

	if (inFile == -1)
	{	perror( fileName);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	tempSize = filelength( inFile);		/* get length of file */

	if (tempSize != 2048 && tempSize != 4096)
	{	fprintf( stderr, "\nFile %s wrong size (%d). (Must be 2048 or 4096 bytes.)\n", fileName, tempSize);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	romSize = (int)tempSize;

	err = read( inFile, romBfr, romSize);

	if (err == -1)
	{	perror( fileName);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	close( inFile);

	/* move the ROM data into the Object code buffer */

	for (objidx = 0, romidx = 0; romidx < romSize; objidx += 2, romidx++)
		ObjCode[objidx] = romBfr[romidx];

	/* open EXT2 (lower, odd, ROM) */

	strcpy( fileName+nameLen, EXT2);

	inFile = open( fileName, O_RDONLY);

	if (inFile == -1)
	{	perror( fileName);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	tempSize = filelength( inFile);		/* get length of file */

	if (tempSize != romSize)
	{	fprintf( stderr, "\nFile %s does not match previous ROM's size. (Must be %u)\n", fileName, romSize);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	err = read( inFile, romBfr, romSize);

	if (err == -1)
	{	perror( fileName);
			free( romBfr);
			free( ObjCode);
			exit( 0);
	}

	close( inFile);

	/* move the ROM data into the Object code buffer */

	for (objidx = 1, romidx = 0; romidx < romSize; objidx += 2, romidx++)
		ObjCode[objidx] = romBfr[romidx];

	/* open EXT3 (upper, even, ROM) */

	strcpy( fileName+nameLen, EXT3);

	inFile = open( fileName, O_RDONLY);

	/* if file exists, read them in */

	if (inFile != -1)
	{
			tempSize = filelength( inFile);		/* get length of file */

			if (tempSize != romSize)
			{	fprintf( stderr, "\nFile %s does not match previous ROM's size. (Must be %u)\n", fileName, romSize);
						free( romBfr);
						free( ObjCode);
						exit( 0);
			}

			romSize = (int)tempSize;

			err = read( inFile, romBfr, romSize);

			if (err == -1)
			{	perror( fileName);
						free( romBfr);
						free( ObjCode);
						exit( 0);
			}

			close( inFile);

			/* move the ROM data into the Object code buffer */

			for (objidx = romSize * 2, romidx = 0; romidx < romSize; objidx += 2, romidx++)
				ObjCode[objidx] = romBfr[romidx];

			/* open EXT4 (upper, odd, ROM) */

			strcpy( fileName+nameLen, EXT4);

			inFile = open( fileName, O_RDONLY);

			if (inFile == -1)
			{	perror( fileName);
						free( romBfr);
						free( ObjCode);
						exit( 0);
			}

			tempSize = filelength( inFile);		/* get length of file */

			if (tempSize != romSize)
			{	fprintf( stderr, "\nFile %s does not match previous ROM's size. (Must be %u)\n", fileName, romSize);
						free( romBfr);
						free( ObjCode);
						exit( 0);
			}

			err = read( inFile, romBfr, romSize);

			if (err == -1)
			{	perror( fileName);
						free( romBfr);
						free( ObjCode);
						exit( 0);
			}

			close( inFile);

			/* move the ROM data into the Object code buffer */

			for (objidx = (romSize * 2) + 1, romidx = 0; romidx < romSize; objidx += 2, romidx++)
				ObjCode[objidx] = romBfr[romidx];
	}
	free( romBfr);

	while (startAdr <= endAdr)
	{	memset( DspBfr, ' ', 80);					/* set to blanks */
			DspBfr[80] = '\0';
			dissOpcode( DspBfr, startAdr, &objSize, &brk_f);	/* setup buffer */
			startAdr += objSize;

			for (ii = 79; DspBfr[ii] == ' '; ii--)
				;

			DspBfr[ii+1] = '\0';											/* terminate line */
			printf( "/* %s */\n", DspBfr);									/* print line */


			printf( "\tif (state == state_A) {\n");
				cineops[state_A][opCode](opCode);
			printf( "\t} else if (state == state_AA) {\n");
				cineops[state_AA][opCode](opCode);
			printf( "\t} else if (state == state_B) {\n");
				cineops[state_B][opCode](opCode);
			printf( "\t} else if (state == state_BB) {\n");
				cineops[state_BB][opCode](opCode);
			printf( "\t} else {\n");
			printf( "\t  /* error */\n");
			printf( "\t}\n");

			if (Pause_f)
			{
						ii = fgetc(stdin);												/* just wait */

						if (ii == '\x1B')
							exit( 0);
			}
			if (brk_f)
				putchar( '\n');											/* print break */
	}
	fputc( '\n', stderr);		/* make look nice on screen */
	free( ObjCode);
}

