#ifndef _MDEP_H_

#define	_MDEP_H_



FILE *debugf;

#define CARRYBIT (1<<12)

#define A0BIT 1


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


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

#define GETA0()       ( RCacc_a0 )


/* for setting/checking the Carry flag */
#define SETFC(val)    ( RCflag_C = val )

#define GETFC()       ( ( RCflag_C >> 8 ) & 0xFF )


/* Contorted sign-extend macro only evaluates its parameter once, and
   executes in two shifts.  This is far more efficient that any other
   sign extend procedure I can think of, and relatively safe */

#define SEX(twelvebit) ((((int)twelvebit) << (int)((sizeof(int)*8)-12)) \

                          >> (int)((sizeof(int)*8)-12))


/* Mouse values currently sampled once per frame and set in WAI code.
   This is not ideal. */
/* Define new types for the c-cpu emulator
 */

#define SW_ABORT           0x100          /* for ioSwitches */


#define UINT32 unsigned int

#define UINT16 unsigned short int

#define UINT8  unsigned char


#define INT32  signed int

#define INT16  signed short int

#define INT8   signed char


static UINT8 bBailOut = FALSE;

static UINT8 rom[0x2000] =
#include "tailgunner-data.c"    /* Preload whole eprom here */


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

typedef short unsigned int RCCINEWORD;      /* 12bits on the C-CPU */
typedef unsigned char      RCCINEBYTE;      /* 8 (or less) bits on the C-CPU */
typedef short signed int   RCCINESWORD;     /* 12bits on the C-CPU */
typedef signed char        RCCINESBYTE;     /* 8 (or less) bits on the C-CPU */

typedef enum {
  RCstate_A = 0, RCstate_AA, RCstate_B, RCstate_BB
} RCCINESTATE;                              /* current RCstate */
/* C-CPU context information begins --
 */
RCCINEWORD RCregister_PC = 0; /* C-CPU registers; program counter */
RCCINEWORD RCregister_A = 0;  /* ; A-Register (accumulator) */
RCCINEWORD RCregister_B = 0;  /* ; B-Register (accumulator) */
RCCINEBYTE RCregister_I = 0;  /* ; I-Register (last access RAM location) */
RCCINEWORD RCregister_J = 0;  /* ; J-Register (target address for JMP opcodes) */
RCCINEBYTE RCregister_P = 0;  /* ; Page-Register (4 bits) */
RCCINEWORD RCFromX = 0;       /* ; X-Register (start of a vector) */
RCCINEWORD RCFromY = 0;       /* ; Y-Register (start of a vector) */
RCCINEWORD RCregister_T = 0;  /* ; T-Register (vector draw length timer) */
RCCINEWORD RCflag_C = 0;      /* C-CPU flags; carry. Is word sized, instead
                           * of RCCINEBYTE, so we can do direct assignment
                           * and then change to BYTE during inspection.
                           */

RCCINEWORD RCcmp_old = 0;     /* last accumulator value */
RCCINEWORD RCcmp_new = 0;     /* new accumulator value */
RCCINEBYTE RCacc_a0 = 0;      /* bit0 of A-reg at last accumulator access */

RCCINESTATE RCstate = RCstate_A; /* C-CPU RCstate machine current RCstate */
RCCINEWORD RCram [ 256 ];     /* C-CPU RCram (for all pages) */
RCCINEBYTE RCvgShiftLength = 0; /* number of shifts loaded into length reg */

/* -- Context information ends.
 */

UINT8 bFlipX;
UINT8 bFlipY;
UINT8 bSwapXY;
/*UINT8 bOverlay;*/
volatile static UINT32 dwElapsedTicks = 0;

UINT16 ioSwitches;
UINT16 ioInputs;
UINT8 ioOutputs = 0; /* Where are these used??? */

UINT16 RCvgColour = 0;

INT16 JoyX;
INT16 JoyY;
UINT8 bNewFrame;

INT32 sdwGameXSize;
INT32 sdwGameYSize;
INT32 sdwXOffset = 0;
INT32 sdwYOffset = 0;

/* Now the same information for Graham's machine */


/* Define new types for the c-cpu emulator */
typedef short unsigned int CINEWORD;      /* 12bits on the C-CPU */
typedef unsigned char      CINEBYTE;      /* 8 (or less) bits on the C-CPU */
typedef short signed int   CINESWORD;     /* 12bits on the C-CPU */
typedef signed char        CINESBYTE;     /* 8 (or less) bits on the C-CPU */

typedef unsigned long int  CINELONG;

typedef enum
{
	state_A = 0,
	state_AA,
	state_B,
	state_BB
} CINESTATE;

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

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

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

#ifdef NEVER


           int       ccpu_jmi_dip = 0; /* as set by cineSetJMI  Use EI, not MI */
           int       ccpu_msize = 0;   /* as set by cineSetMSize */
           int       ccpu_monitor = 0; /* as set by cineSetMonitor */

           int bNewFrame = 0;
           int bFlipX = 0;
           int bFlipY = 0;
           int bSwapXY = 0;
           int sdwGameXSize = 0;
           int sdwGameYSize = 0;
           int sdwXOffset = 0;
           int sdwYOffset = 0;
#endif

           CINEWORD  vgColour = 0;
           CINEBYTE  vgShiftLength = 0;   /* number of shifts loaded into length reg */
           int bailOut = 0;
           int       ccpu_ICount = 0;  /* */

  /* -- Context information ends. */


/* debug junk
 */

#ifdef DUALCPU

int ccpudebug = 1; /* default is on */
#else

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


/***
const int xmousethresh = 2;
const int ymousethresh = 2;
static int mickeyx = 0;
static int mickeyy = 0;
static int mousecode = 0;
***/
static int Frames = 0;

/* INP $8 ? */
#define IO_START   0x80


/* INP $7 ? */
#define IO_SHIELDS 0x40


#define IO_FIRE    0x20

#define IO_DOWN    0x10

#define IO_UP      0x08

#define IO_LEFT    0x04

#define IO_RIGHT   0x02

#define SW_QUARTERS_PER_GAME 0x01


#define IO_COIN   0x80


#define IO_KNOWNBITS (IO_START | IO_SHIELDS | IO_FIRE | IO_DOWN | IO_LEFT | IO_RIGHT)


/* initial value of shields (on a DIP) */
#define SW_SHIELDS80 ((1<<1) | (1<<4) | (1<<5))  /* 000 */

#define SW_SHIELDS70 ((1<<1) | (0<<4) | (1<<5))  /* 010 */

#define SW_SHIELDS60 ((1<<1) | (1<<4) | (0<<5))  /* 001 */

#define SW_SHIELDS50 ((1<<1) | (0<<4) | (0<<5))  /* 011 */

#define SW_SHIELDS40 ((0<<1) | (1<<4) | (1<<5))  /* 100 */

#define SW_SHIELDS30 ((0<<1) | (0<<4) | (1<<5))  /* 110 */

#define SW_SHIELDS20 ((0<<1) | (1<<4) | (0<<5))  /* 101 */

#define SW_SHIELDS15 ((0<<1) | (0<<4) | (0<<5))  /* 111 */

#define SW_SHIELDS15 ((0<<1) | (0<<4) | (0<<5))  /* 111 */

#define SW_SHIELDS SW_SHIELDS80


#define SW_SHIELDMASK ((1<<1) | (1<<4) | (1<<5))  /* 000 */


static int startflag = IO_START;
static int coinflag  = 0;
static int shieldsflag = IO_SHIELDS;   /* Whether shields are up (mouse or key) */
static int fireflag = IO_FIRE;
static int quarterflag = SW_QUARTERS_PER_GAME; /* 1 quarter per game */

/* RCstate setting macros to exit opcode handler */
#define jumpCineRet_A RCstate = RCstate_A; \

                      goto cineExecBottom;

#define jumpCineRet_B RCstate = RCstate_B; \

                      goto cineExecBottom;

#define jumpCineRet_AA RCstate = RCstate_AA; \

                       goto cineExecBottom;

#define jumpCineRet_BB RCstate = RCstate_BB; \

                       goto cineExecBottom;

#define jumpCineRet_WEIRD if (debugf) fprintf(debugf, "Didn't bother yet.\n" ); \

                          exit ( 0 );


#endif