#ifndef _MDEP_C
#define _MDEP_C 1

static UINT8 bBailOut = FALSE;

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 */

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

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

INT16 JoyX;
INT16 JoyY;
UINT8 bNewFrame;

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

  /* 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 */
CINEWORD /*CINEBYTE*/ acc_a0 = 0;	/* bit0 of A-reg at last accumulator access */

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

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

  /* -- Context information ends. */

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

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 */

const int xmousethresh = 2;
const int ymousethresh = 2;
static int mickeyx = 0;
static int mickeyy = 0;
static int mousecode = 0;
static int sound_addr = 0;
static int sound_addr_A = 0;
static int sound_addr_B = 0;
static int sound_addr_C = 0;
static int sound_data = 0;

void
ERROR (char *fmt, ...)
{
}

void
reset_coin_counter (int RCstate)
{
  coinflag = IO_COIN;
  ioSwitches |= IO_COIN;
}

int
get_coin_state (void)
{
  return ((coinflag >> 7) & 1);
}

int
get_quarters_per_game (void)
{
  return (quarterflag & 1);
}

void
set_watchdog (void)
{
}

int
get_shield_bit0 (void)
{
  return ((SW_SHIELDS >> 5) & 1);
}

int
get_shield_bit1 (void)
{
  return ((SW_SHIELDS >> 4) & 1);
}

int
get_shield_bit2 (void)
{
  return ((SW_SHIELDS >> 1) & 1);
}

int
get_switch_bit (int n)
{
  return (((int) ioSwitches >> n) & 1);
}

int
get_io_bit (int n)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   n) & 1);
}

int
get_io_moveright (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   1) & 1);
}

int
get_io_moveleft (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   2) & 1);
}

int
get_io_moveup (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   3) & 1);
}

int
get_io_movedown (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   4) & 1);
}

int
get_io_fire (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   5) & 1);
}

int
get_io_shields (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   6) & 1);
}

int
get_io_startbutton (void)
{
  return (((startflag | shieldsflag | fireflag | mousecode /* | inputs */ ) >>
	   7) & 1);
}

void
put_io_bit (int pos, int how)
{
  if (how == 1)
    {
      /* Set a bit */
      ioInputs = ioInputs | (1 << pos);
    }
  else
    {
      /* Clear a bit */
      ioInputs = ioInputs & (~(1 << pos));
    }
}

void
set_sound_data (int bit)
{
  sound_data = bit;
}

void
set_sound_addr_A (int bit)
{
  sound_addr_A = bit;
}

void
set_sound_addr_B (int bit)
{
  sound_addr_B = bit;
}

void
set_sound_addr_C (int bit)
{
  sound_addr_C = bit;
}

/* These don't yet do anything obvious or useful.  Debugging needed... */
void
strobe_sound_on (void)
{
  int sound_addr_tmp =
    (sound_addr_C << 2) | (sound_addr_B << 1) | sound_addr_A;
  sound_addr = sound_addr_tmp;
}

void
strobe_sound_off (void)
{
  int sound_addr_tmp =
    (sound_addr_C << 2) | (sound_addr_B << 1) | sound_addr_A;
  sound_addr = sound_addr_tmp;
}

void
init_graph (void)
{
}

void
end_graph (void)
{
}

void
save_config (void)
{
}

int
load_config (void)
{
  return (TRUE);
}

void
cineReset (void)
{
}

/* It's interesting to run "gprof" on this code.  It spends something
   like 20% of its time in MUL.  Really *must* tweak the code generator
   to use the C multiply operation. */

void
MUL (void)
{
  /* opMULirg_A_AA (e3) */
  cmp_new = ram[register_I];
  register_B <<= 4;		/* get sign bit 15 */
  register_B |= (register_A >> 8);	/* bring in A high nibble */
  register_A = ((register_A & 0xFF) << 8) | (0xe3);	/* pick up opcode */
  if (register_A & 0x100)	/* 1bit shifted out? */
    {
      acc_a0 = register_A = (register_A >> 8) | ((register_B & 0xFF) << 8);
      register_A >>= 1;
      register_A &= 0xFFF;
      register_B =
	((unsigned short int) (((signed short int) register_B) >>
			       (signed short int) 4)) /* SAR */ ;
      cmp_old = register_B & 0x0F;
      register_B =
	((unsigned short int) (((signed short int) register_B) >>
			       (signed short int) 1)) /* SAR */ ;
      register_B &= 0xFFF;
      flag_C = (register_B += cmp_new);
      register_B &= 0xFFF;
    }
  else
    {
      register_A =
	(register_A >> 8) | /* Bhigh | Alow */ ((register_B & 0xFF) << 8);
      cmp_old = acc_a0 = register_A & 0xFFF;
      flag_C = (cmp_old + cmp_new);
      register_A >>= 1;
      register_A &= 0xFFF;
      register_B =
	((unsigned short int) (((signed short int) register_B) >>
			       (signed short int) 5)) /* SAR */ ;
      register_B &= 0xFFF;
    }
}

#endif /* _MDEP_C */

