📄 williams.c
字号:
/***************************************************************************
machine.c
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
I/O ports)
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "M6808/M6808.h"
#include "M6809/M6809.h"
#include "6821pia.h"
#include "machine/ticket.h"
/* defined in vidhrdw/williams.c */
extern unsigned char *williams_videoram;
/* various banking controls */
unsigned char *williams_bank_base;
unsigned char *williams_video_counter;
unsigned char *defender_bank_base;
unsigned char *blaster_bank2_base;
/* pointers to memory locations for speedup optimizations */
unsigned char *robotron_catch;
unsigned char *stargate_catch;
unsigned char *defender_catch;
unsigned char *splat_catch;
unsigned char *blaster_catch;
unsigned char *mayday_catch;
/* internal bank switching tracks */
int blaster_bank;
int vram_bank;
/* switches controlled by $c900 */
int sinistar_clip;
int williams_cocktail;
/* video counter offset */
static int port_select;
static unsigned char defender_video_counter;
/* various input port maps */
int williams_input_port_0_3 (int offset);
int williams_input_port_1_4 (int offset);
int stargate_input_port_0_r (int offset);
int blaster_input_port_0_r (int offset);
int sinistar_input_port_0_r (int offset);
int defender_input_port_0_r (int offset);
int lottofun_input_port_0_r (int offset);
/* Defender-specific code */
int defender_io_r (int offset);
void defender_io_w (int offset,int data);
void defender_bank_select_w (int offset, int data);
/* Colony 7-specific code */
void colony7_bank_select_w (int offset, int data);
/* PIA interface functions */
static void williams_irq (void);
static void williams_snd_irq (void);
static void williams_snd_cmd_w (int offset, int cmd);
static void williams_port_select_w (int offset, int data);
static void sinistar_snd_cmd_w (int offset, int cmd);
/* external code to update part of the screen */
void williams_vh_update (int counter);
/***************************************************************************
PIA Interfaces for each game
***************************************************************************/
static pia6821_interface robotron_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface joust_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ williams_input_port_0_3, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ williams_port_select_w, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface stargate_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ stargate_input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface bubbles_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface splat_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ williams_input_port_0_3, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ williams_input_port_1_4, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ williams_port_select_w, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface sinistar_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ sinistar_input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, sinistar_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface blaster_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ blaster_input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface defender_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ defender_input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface colony7_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ 0, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
static pia6821_interface lottofun_pia_intf =
{
3, /* 3 chips */
{ PIA_DDRA, PIA_CTLA, PIA_DDRB, PIA_CTLB }, /* offsets */
{ lottofun_input_port_0_r, input_port_2_r, 0 }, /* input port A */
{ 0, 0, 0 }, /* input bit CA1 */
{ 0, 0, 0 }, /* input bit CA2 */
{ input_port_1_r, 0, 0 }, /* input port B */
{ 0, 0, 0 }, /* input bit CB1 */
{ 0, 0, 0 }, /* input bit CB2 */
{ 0, 0, DAC_data_w }, /* output port A */
{ ticket_dispenser_w, williams_snd_cmd_w, 0 }, /* output port B */
{ 0, 0, 0 }, /* output CA2 */
{ 0, 0, 0 }, /* output CB2 */
{ 0, williams_irq, williams_snd_irq }, /* IRQ A */
{ 0, williams_irq, williams_snd_irq } /* IRQ B */
};
/***************************************************************************
Common Williams routines
***************************************************************************/
/*
* Initialize the machine
*/
void robotron_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&robotron_pia_intf);
}
void joust_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&joust_pia_intf);
}
void stargate_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&stargate_pia_intf);
}
void bubbles_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&bubbles_pia_intf);
}
void splat_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&splat_pia_intf);
}
void sinistar_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&sinistar_pia_intf);
}
void blaster_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&blaster_pia_intf);
}
void defender_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&defender_pia_intf);
williams_video_counter = &defender_video_counter;
/* initialize the banks */
defender_bank_select_w (0, 0);
}
void colony7_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&colony7_pia_intf);
williams_video_counter = &defender_video_counter;
/* initialize the banks */
colony7_bank_select_w (0, 0);
}
void lottofun_init_machine (void)
{
m6809_Flags = M6809_FAST_NONE;
pia_startup (&lottofun_pia_intf);
/* Initialize the ticket dispenser to 70 milliseconds */
/* (I'm not sure what the correct value really is) */
ticket_dispenser_init(70, TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_HIGH);
}
/*
* Generic interrupt routine; interrupts are generated via the PIA, so we merely pulse the
* external inputs here; the PIA emulator will generate the interrupt if the proper conditions
* are met
*/
int williams_interrupt (void)
{
/* the video counter value is taken from the six bits of VA8-VA13 */
*williams_video_counter = ((64 - cpu_getiloops ()) << 2);
/* the IRQ signal comes into CB1, and is set to VA11 */
pia_2_cb1_w (0, *williams_video_counter & 0x20);
/* the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 */
pia_2_ca1_w (0, (*williams_video_counter & 0xf0) == 0xf0);
/* update the screen partially */
williams_vh_update (*williams_video_counter);
/* PIA generates interrupts, not us */
return ignore_interrupt ();
}
/*
* Read either port 0 or 3, depending on the value in CB2
*/
int williams_input_port_0_3 (int offset)
{
if (port_select)
return input_port_3_r (0);
else
return input_port_0_r (0);
}
/*
* Read either port 2 or 3, depending on the value in CB2
*/
int williams_input_port_1_4 (int offset)
{
if (port_select)
return input_port_4_r (0);
else
return input_port_1_r (0);
}
/*
* Switch between VRAM and ROM
*/
void williams_vram_select_w (int offset, int data)
{
vram_bank = data & 0x01;
williams_cocktail = data & 0x02;
sinistar_clip = data & 0x04;
if (vram_bank)
{
cpu_setbank (1, williams_bank_base);
}
else
{
cpu_setbank (1, williams_videoram);
}
}
/*
* PIA callback to generate the interrupt to the main CPU
*/
static void williams_irq (void)
{
cpu_cause_interrupt (0, M6809_INT_IRQ);
}
/*
* PIA callback to generate the interrupt to the sound CPU
*/
static void williams_snd_irq (void)
{
cpu_cause_interrupt (1, M6808_INT_IRQ);
}
/*
* Handle a write to the PIA which communicates to the sound CPU
*/
static void williams_snd_cmd_real_w (int param)
{
pia_3_portb_w (0, param);
pia_3_cb1_w (0, (param == 0xff) ? 0 : 1);
}
static void williams_snd_cmd_w (int offset, int cmd)
{
/* the high two bits are set externally, and should be 1 */
timer_set (TIME_NOW, cmd | 0xc0, williams_snd_cmd_real_w);
}
/*
* Detect a switch between input port sets
*/
static void williams_port_select_w (int offset, int data)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -