📄 mcr.c
字号:
/***************************************************************************
machine.c
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
I/O ports)
Tapper machine started by Chris Kirmse
***************************************************************************/
#include <stdio.h>
#include "driver.h"
#include "z80/z80.h"
#include "machine/z80fmly.h"
#include "m6808/m6808.h"
#include "m6809/m6809.h"
#include "machine/6821pia.h"
#include "timer.h"
int pedal_sensitivity = 4; /* Amount of change to read each time the pedal keys are pulsed */
int weighting_factor = 0; /* Progressive weighting factor */
int mcr_loadnvram;
int spyhunt_lamp[8];
extern int spyhunt_scrollx,spyhunt_scrolly;
static int spyhunt_mux;
static int maxrpm_mux;
static int maxrpm_last_shift;
static int maxrpm_p1_shift;
static int maxrpm_p2_shift;
static unsigned char soundlatch[4];
static unsigned char soundstatus;
extern void dotron_change_light (int light);
/* z80 ctc */
static void ctc_interrupt (int state)
{
cpu_cause_interrupt (0, Z80_VECTOR(0,state) );
}
static z80ctc_interface ctc_intf =
{
1, /* 1 chip */
{ 0 }, /* clock (filled in from the CPU 0 clock */
{ 0 }, /* timer disables */
{ ctc_interrupt }, /* interrupt handler */
{ 0 }, /* ZC/TO0 callback */
{ 0 }, /* ZC/TO1 callback */
{ 0 } /* ZC/TO2 callback */
};
/* used for the sound boards */
static int dacval;
static int suspended;
/* Chip Squeak Deluxe (CSD) interface */
static void csd_porta_w (int offset, int data);
static void csd_portb_w (int offset, int data);
static void csd_irq (void);
static pia6821_interface csd_pia_intf =
{
1, /* 1 chip */
{ PIA_DDRA, PIA_NOP, PIA_DDRB, PIA_NOP, PIA_CTLA, PIA_NOP, PIA_CTLB, PIA_NOP }, /* offsets */
{ 0 }, /* input port A */
{ 0 }, /* input bit CA1 */
{ 0 }, /* input bit CA2 */
{ 0 }, /* input port B */
{ 0 }, /* input bit CB1 */
{ 0 }, /* input bit CB2 */
{ csd_porta_w }, /* output port A */
{ csd_portb_w }, /* output port B */
{ 0 }, /* output CA2 */
{ 0 }, /* output CB2 */
{ csd_irq }, /* IRQ A */
{ csd_irq }, /* IRQ B */
};
/* Sounds Good (SG) PIA interface */
static void sg_porta_w (int offset, int data);
static void sg_portb_w (int offset, int data);
static void sg_irq (void);
static pia6821_interface sg_pia_intf =
{
1, /* 1 chip */
{ PIA_DDRA, PIA_NOP, PIA_DDRB, PIA_NOP, PIA_CTLA, PIA_NOP, PIA_CTLB, PIA_NOP }, /* offsets */
{ 0 }, /* input port A */
{ 0 }, /* input bit CA1 */
{ 0 }, /* input bit CA2 */
{ 0 }, /* input port B */
{ 0 }, /* input bit CB1 */
{ 0 }, /* input bit CB2 */
{ sg_porta_w }, /* output port A */
{ sg_portb_w }, /* output port B */
{ 0 }, /* output CA2 */
{ 0 }, /* output CB2 */
{ sg_irq }, /* IRQ A */
{ sg_irq }, /* IRQ B */
};
/* Turbo Chip Squeak (TCS) PIA interface */
static void tcs_irq (void);
static pia6821_interface tcs_pia_intf =
{
1, /* 1 chip */
{ PIA_DDRA, PIA_DDRB, PIA_CTLA, PIA_CTLB }, /* offsets */
{ 0 }, /* input port A */
{ 0 }, /* input bit CA1 */
{ 0 }, /* input bit CA2 */
{ 0 }, /* input port B */
{ 0 }, /* input bit CB1 */
{ 0 }, /* input bit CB2 */
{ DAC_data_w }, /* output port A */
{ 0 }, /* output port B */
{ 0 }, /* output CA2 */
{ 0 }, /* output CB2 */
{ tcs_irq }, /* IRQ A */
{ tcs_irq }, /* IRQ B */
};
/* Squawk & Talk (SNT) PIA interface */
static void snt_porta1_w (int offset, int data);
static void snt_porta2_w (int offset, int data);
static void snt_portb2_w (int offset, int data);
static void snt_irq (void);
static pia6821_interface snt_pia_intf =
{
2, /* 2 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ 0, 0 }, /* input port A */
{ 0, 0 }, /* input bit CA1 */
{ 0, 0 }, /* input bit CA2 */
{ 0, 0 }, /* input port B */
{ 0, 0 }, /* input bit CB1 */
{ 0, 0 }, /* input bit CB2 */
{ snt_porta1_w, snt_porta2_w }, /* output port A */
{ 0, snt_portb2_w }, /* output port B */
{ 0, 0 }, /* output CA2 */
{ 0, 0 }, /* output CB2 */
{ snt_irq, snt_irq }, /* IRQ A */
{ snt_irq, snt_irq }, /* IRQ B */
};
/***************************************************************************
Generic MCR handlers
***************************************************************************/
void mcr_init_machine(void)
{
int i;
/* reset the sound */
for (i = 0; i < 4; i++)
soundlatch[i] = 0;
soundstatus = 0;
suspended = 0;
/* initialize the CTC */
ctc_intf.baseclock[0] = Machine->drv->cpu[0].cpu_clock;
z80ctc_init (&ctc_intf);
/* daisy chain set */
{
static Z80_DaisyChain daisy_chain[] =
{
{ z80ctc_reset, z80ctc_interrupt, z80ctc_reti, 0 }, /* CTC number 0 */
{ 0,0,0,-1} /* end mark */
};
cpu_setdaisychain (0,daisy_chain );
}
/* can't load NVRAM right away */
mcr_loadnvram = 0;
}
void spyhunt_init_machine (void)
{
mcr_init_machine ();
/* reset the PIAs */
pia_startup (&csd_pia_intf);
}
void rampage_init_machine (void)
{
mcr_init_machine ();
mcr_loadnvram = 1;
/* reset the PIAs */
pia_startup (&sg_pia_intf);
}
void sarge_init_machine (void)
{
mcr_init_machine ();
mcr_loadnvram = 1;
/* reset the PIAs */
pia_startup (&tcs_pia_intf);
}
void dotron_init_machine (void)
{
mcr_init_machine ();
/* reset the PIAs */
pia_startup (&snt_pia_intf);
}
int mcr_interrupt (void)
{
/* once per frame, pulse the CTC line 3 */
z80ctc_0_trg3_w (0, 1);
z80ctc_0_trg3_w (0, 0);
return ignore_interrupt ();
}
int dotron_interrupt (void)
{
/* pulse the CTC line 2 to enable Platform Poles */
z80ctc_0_trg2_w (0, 1);
z80ctc_0_trg2_w (0, 0);
/* once per frame, pulse the CTC line 3 */
z80ctc_0_trg3_w (0, 1);
z80ctc_0_trg3_w (0, 0);
return ignore_interrupt ();
}
void mcr_delayed_write (int param)
{
soundlatch[param >> 8] = param & 0xff;
}
void mcr_writeport(int port,int value)
{
switch (port)
{
case 0: /* OP0 Write latch OP0 (coin meters, 2 led's and cocktail 'flip') */
return;
case 4: /* Write latch OP4 */
return;
case 0x1c: /* WIRAM0 - write audio latch 0 */
case 0x1d: /* WIRAM0 - write audio latch 1 */
case 0x1e: /* WIRAM0 - write audio latch 2 */
case 0x1f: /* WIRAM0 - write audio latch 3 */
timer_set (TIME_NOW, ((port - 0x1c) << 8) | (value & 0xff), mcr_delayed_write);
/* mcr_delayed_write (((port - 0x1c) << 8) | (value & 0xff));*/
/* soundlatch[port - 0x1c] = value;*/
return;
case 0xe0: /* clear watchdog timer */
watchdog_reset_w (0, 0);
return;
case 0xe8:
/* A sequence of values gets written here at startup; we don't know why;
However, it does give us the opportunity to tweak the IX register before
it's checked in Tapper and Timber, thus eliminating the need for patches
The value 5 is written last; we key on that, and only modify IX if it is
currently 0; hopefully this is 99.9999% safe :-) */
if (value == 5)
{
Z80_Regs temp;
Z80_GetRegs (&temp);
#ifndef USE_DRZ80
if (temp.IX.D == 0)
temp.IX.D += 1;
#else
if (temp.regs.Z80IX == 0)
temp.regs.Z80IX+= 1;
#endif
Z80_SetRegs (&temp);
}
return;
case 0xf0: /* These are the ports of a Z80-CTC; it generates interrupts in mode 2 */
case 0xf1:
case 0xf2:
case 0xf3:
z80ctc_0_w (port - 0xf0, value);
return;
}
}
int mcr_readport(int port)
{
/* ports 0-4 are read directly via the input ports structure */
port += 5;
/* only a few ports here */
switch (port)
{
case 0x07: /* Read audio status register */
/* once the system starts checking the sound, memory tests are done; load the NVRAM */
mcr_loadnvram = 1;
return soundstatus;
case 0x10: /* Tron reads this as an alias to port 0 -- does this apply to all ports 10-14? */
return cpu_readport (port & 0x0f);
}
return 0;
}
void mcr_soundstatus_w (int offset,int data)
{
soundstatus = data;
}
int mcr_soundlatch_r (int offset)
{
return soundlatch[offset];
}
/***************************************************************************
Game-specific port handlers
***************************************************************************/
/* Translation table for one-joystick emulation */
static int one_joy_trans[32]={
0x00,0x05,0x0A,0x00,0x06,0x04,0x08,0x00,
0x09,0x01,0x02,0x00,0x00,0x00,0x00,0x00 };
int sarge_IN1_r(int offset)
{
int res,res1;
res=readinputport(1);
res1=readinputport(6);
res&=~one_joy_trans[res1&0xf];
return (res);
}
int sarge_IN2_r(int offset)
{
int res,res1;
res=readinputport(2);
res1=readinputport(6)>>4;
res&=~one_joy_trans[res1&0xf];
return (res);
}
void spyhunt_delayed_write (int param)
{
pia_1_portb_w (0, param & 0x0f);
pia_1_ca1_w (0, param & 0x10);
}
void spyhunt_writeport(int port,int value)
{
static int lastport4;
switch (port)
{
case 0x04:
case 0x05:
case 0x06:
case 0x07:
/* mux select is in bit 7 */
spyhunt_mux = value & 0x80;
/* lamp driver command triggered by bit 5, data is in low four bits */
if (((lastport4 ^ value) & 0x20) && !(value & 0x20))
{
if (value & 8)
spyhunt_lamp[value & 7] = 1;
else
spyhunt_lamp[value & 7] = 0;
}
/* CSD command triggered by bit 4, data is in low four bits */
timer_set (TIME_NOW, value, spyhunt_delayed_write);
/* remember the last value */
lastport4 = value;
break;
case 0x84:
spyhunt_scrollx = (spyhunt_scrollx & ~0xff) | value;
break;
case 0x85:
spyhunt_scrollx = (spyhunt_scrollx & 0xff) | ((value & 0x07) << 8);
spyhunt_scrolly = (spyhunt_scrolly & 0xff) | ((value & 0x80) << 1);
break;
case 0x86:
spyhunt_scrolly = (spyhunt_scrolly & ~0xff) | value;
break;
default:
mcr_writeport(port,value);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -