📄 qix.c
字号:
/***************************************************************************
Qix/ZooKeeper/Space Dungeon Memory Map
------------- ------ ---
Qix uses two 6809 CPUs: one for data and sound and the other for video.
Communication between the two CPUs is done using a 4K RAM space at $8000
(for ZooKeeper the data cpu maps it at $0000 and the video cpu at $8000)
which both CPUs have direct access. FIRQs (fast interrupts) are generated
by each CPU to interrupt the other at specific times.
A third CPU, a 6802, is used for sample playback. It drives an 8-bit
DAC and according to the schematics a TMS5220 speech chip, which is never
accessed. ROM u27 is the only code needed. A sound command from the
data CPU causes an IRQ to fire on the 6802 and the sound playback is
started.
The coin door switches and player controls are connected to the CPUs by
Mototola 6821 PIAs. These devices are memory mapped as shown below.
The screen is 256x256 with eight bit pixels (64K). The screen is divided
into two halves each half mapped by the video CPU at $0000-$7FFF. The
high order bit of the address latch at $9402 specifies which half of the
screen is being accessed.
Timing is critical in the hardware. The data CPU must have an interrupt
signal generated externally at the right frequency to make the game play
correctly.
The address latch works as follows. When the video CPU accesses $9400,
the screen address is computed by using the values at $9402 (high byte)
and $9403 (low byte) to get a value between $0000-$FFFF. The value at
that location is either returned or written.
The scan line at $9800 on the video CPU records where the scan line is
on the display (0-255). Several places in the ROM code wait until the
scan line reaches zero before continuing.
QIX CPU #1 (Data/Sound):
$8000 - $83FF: Dual port RAM accessible by both processors
$8400 - $87FF: Local Memory
$8800 : ACIA base address
$8C00 : Video FIRQ activation
$8C01 : Data FIRQ deactivation
$9000 : Sound PIA
$9400 : [76543210] Game PIA 1 (Port A)
o Fast draw
o 1P button
o 2P button
o Slow draw
o Joystick Left
o Joystick Down
o Joystick Right
o Joystick Up
$9402 : [76543210] Game PIA 1 (Port B)
o Tilt
o Coin sw Unknown
o Right coin
o Left coin
o Slew down
o Slew up
o Sub. test
o Adv. test
$9900 : Game PIA 2
$9C00 : Game PIA 3
ZOOKEEPER CPU #1 (Data/Sound):
$0000 - $03FF: Dual Port RAM accessible by both processors
$0400 - $07FF: Local Memory
$0800 : ACIA base address
$0C00 : Video FIRQ activation
$0C01 : Data FIRQ deactivation
$1000 : Sound PIA
$1400 : [76543210] Game PIA 1 (Port A)
o Fast draw
o 1P button
o 2P button
o Slow draw
o Joystick Left
o Joystick Down
o Joystick Right
o Joystick Up
$1402 : [76543210] Game PIA 1 (Port B)
o Tilt
o Coin sw Unknown
o Right coin
o Left coin
o Slew down
o Slew up
o Sub. test
o Adv. test
$1900 : Game PIA 2
$1C00 : Game PIA 3
CPU #2 (Video):
$0000 - $7FFF: Video/Screen RAM
$8000 - $83FF: Dual port RAM accessible by both processors
$8400 - $87FF: CMOS backup and local memory
$8800 : LED output and color RAM page select
$8801 : EPROM page select (ZooKeeper only)
$8C00 : Data FIRQ activation
$8C01 : Video FIRQ deactivation
$9000 : Color RAM
$9400 : Address latch screen location
$9402 : Address latch Hi-byte
$9403 : Address latch Lo-byte
$9800 : Scan line location
$9C00 : CRT controller base address
QIX NONVOLATILE CMOS MEMORY MAP (CPU #2 -- Video) $8400-$87ff
$86A9 - $86AA: When CMOS is valid, these bytes are $55AA
$86AC - $86C3: AUDIT TOTALS -- 4 4-bit BCD digits per setting
(All totals default to: 0000)
$86AC: TOTAL PAID CREDITS
$86AE: LEFT COINS
$86B0: CENTER COINS
$86B2: RIGHT COINS
$86B4: PAID CREDITS
$86B6: AWARDED CREDITS
$86B8: % FREE PLAYS
$86BA: MINUTES PLAYED
$86BC: MINUTES AWARDED
$86BE: % FREE TIME
$86C0: AVG. GAME [SEC]
$86C2: HIGH SCORES
$86C4 - $86FF: High scores -- 10 scores/names, consecutive in memory
Six 4-bit BCD digits followed by 3 ascii bytes
(Default: 030000 QIX)
$8700 : LANGUAGE SELECT (Default: $32)
ENGLISH = $32 FRANCAIS = $33 ESPANOL = $34 DEUTSCH = $35
$87D9 - $87DF: COIN SLOT PROGRAMMING -- 2 4-bit BCD digits per setting
$87D9: STANDARD COINAGE SETTING (Default: 01)
$87DA: COIN MULTIPLIERS LEFT (Default: 01)
$87DB: COIN MULTIPLIERS CENTER (Default: 04)
$87DC: COIN MULTIPLIERS RIGHT (Default: 01)
$87DD: COIN UNITS FOR CREDIT (Default: 01)
$87DE: COIN UNITS FOR BONUS (Default: 00)
$87DF: MINIMUM COINS (Default: 00)
$87E0 - $87EA: LOCATION PROGRAMMING -- 2 4-bit BCD digits per setting
$87E0: BACKUP HSTD [0000] (Default: 03)
$87E1: MAXIMUM CREDITS (Default: 10)
$87E2: NUMBER OF TURNS (Default: 03)
$87E3: THRESHOLD (Default: 75)
$87E4: TIME LINE (Default: 37)
$87E5: DIFFICULTY 1 (Default: 01)
$87E6: DIFFICULTY 2 (Default: 01)
$87E7: DIFFICULTY 3 (Default: 01)
$87E8: DIFFICULTY 4 (Default: 01)
$87E9: ATTRACT SOUND (Default: 01)
$87EA: TABLE MODE (Default: 00)
COIN PROCESSOR
$0000 (PORTA) : Bi directional communication to the data CPU
$0001 (PORTB) : [76543210] Game PIA 1 (Port B)
o SPARE output
o Coin lockout output
o Coin lockout output
o Tilt input
o Slew down input
o Slew up input
o Sub. test input
o Adv. test input
$0002 (PORTC) : [76543210] Game PIA 1 (Port B)
o From DATA cpu input
o Aux coin switch input
o Right coin switch input
o Left coin switch input
INT input : From data cpu
Timer input : From data cpu
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "machine/6821pia.h"
/* #define TRYGAMEPIA 1 */
extern void sdungeon_68705_mcu_w(int offest, int value);
extern int sdungeon_68705_mcu_r(int offset);
extern int sdungeon_68705_portc_r(int offset);
extern int sdungeon_68705_portb_r(int offset);
extern unsigned char *qix_sharedram;
int qix_scanline_r(int offset);
void qix_data_firq_w(int offset, int data);
void qix_video_firq_w(int offset, int data);
extern unsigned char *qix_palettebank;
extern unsigned char *qix_videoaddress;
int qix_videoram_r(int offset);
void qix_videoram_w(int offset, int data);
int qix_addresslatch_r(int offset);
void qix_addresslatch_w(int offset, int data);
void qix_paletteram_w(int offset,int data);
void qix_palettebank_w(int offset,int data);
int qix_sharedram_r(int offset);
void qix_sharedram_w(int offset, int data);
int qix_interrupt_video(void);
void qix_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
int qix_vh_start(void);
void qix_vh_stop(void);
void qix_init_machine(void);
void withmcu_init_machine(void);
int qix_data_io_r (int offset);
int qix_sound_io_r (int offset);
void qix_data_io_w (int offset, int data);
void qix_sound_io_w (int offset, int data);
extern void zoo_bankswitch_w(int offset, int data);
extern void zoo_init_machine(void);
static struct MemoryReadAddress readmem[] =
{
{ 0x8000, 0x83ff, qix_sharedram_r, &qix_sharedram },
{ 0x8400, 0x87ff, MRA_RAM },
{ 0x8800, 0x8800, MRA_RAM }, /* ACIA */
{ 0x9000, 0x9003, pia_4_r },
{ 0x9400, 0x9403, pia_1_r },
{ 0x9900, 0x9903, pia_2_r },
{ 0x9c00, 0x9FFF, pia_3_r },
{ 0xa000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress zoo_readmem[] =
{
{ 0x0000, 0x03ff, qix_sharedram_r, &qix_sharedram },
{ 0x0400, 0x07ff, MRA_RAM },
{ 0x1000, 0x1003, pia_4_r }, /* Sound PIA */
#ifdef TRYGAMEPIA
{ 0x1400, 0x1403, pia_1_r }, /* Game PIA 1 - Player inputs, coin door switches */
{ 0x1c00, 0x1fff, pia_3_r }, /* Game PIA 3 - Player 2 */
#else
{ 0x1400, 0x1400, input_port_0_r }, /* PIA 1 PORT A -- Player controls */
{ 0x1402, 0x1402, input_port_1_r }, /* PIA 1 PORT B -- Coin door switches */
{ 0x1c00, 0x1c00, input_port_2_r }, /* PIA 3 PORT A -- Player 2 controls */
#endif
{ 0x1900, 0x1903, pia_2_r }, /* Game PIA 2 */
{ 0x1ffe, 0x1ffe, MRA_RAM }, /* ????? Some kind of I/O */
{ 0x8000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress readmem_video[] =
{
{ 0x0000, 0x7fff, qix_videoram_r },
{ 0x8000, 0x83ff, qix_sharedram_r },
{ 0x8400, 0x87ff, MRA_RAM },
{ 0x9400, 0x9400, qix_addresslatch_r },
{ 0x9800, 0x9800, qix_scanline_r },
{ 0xa000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress zoo_readmem_video[] =
{
{ 0x0000, 0x7fff, qix_videoram_r },
{ 0x8000, 0x83ff, qix_sharedram_r },
{ 0x8400, 0x87ff, MRA_RAM },
{ 0x9400, 0x9400, qix_addresslatch_r },
{ 0x9800, 0x9800, qix_scanline_r },
{ 0xa000, 0xbfff, MRA_BANK1 },
{ 0xc000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress readmem_sound[] =
{
{ 0x0000, 0x007f, MRA_RAM },
{ 0x2000, 0x2003, pia_6_r },
{ 0x4000, 0x4003, pia_5_r },
{ 0xf000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress zoo_readmem_sound[] =
{
{ 0x0000, 0x007f, MRA_RAM },
{ 0x2000, 0x2003, pia_6_r },
{ 0x4000, 0x4003, pia_5_r },
{ 0xd000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x8000, 0x83ff, qix_sharedram_w },
{ 0x8400, 0x87ff, MWA_RAM },
{ 0x8c00, 0x8c00, qix_video_firq_w },
{ 0x9000, 0x9003, pia_4_w },
{ 0x9400, 0x9403, pia_1_w },
{ 0x9900, 0x9903, pia_2_w },
{ 0x9c00, 0x9fff, pia_3_w },
{ 0xa000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress zoo_writemem[] =
{
{ 0x0000, 0x03ff, qix_sharedram_w },
{ 0x0400, 0x07ff, MWA_RAM },
{ 0x0c00, 0x0c00, qix_video_firq_w },
{ 0x0c01, 0x0c01, MWA_NOP }, /* interrupt acknowledge */
{ 0x1000, 0x1003, pia_4_w }, /* Sound PIA */
{ 0x1400, 0x1403, pia_1_w }, /* Game PIA 1 */
{ 0x1900, 0x1903, pia_2_w }, /* Game PIA 2 */
{ 0x1c00, 0x1fff, pia_3_w }, /* Game PIA 3 */
{ 0x8000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem_video[] =
{
{ 0x0000, 0x7fff, qix_videoram_w },
{ 0x8000, 0x83ff, qix_sharedram_w },
{ 0x8400, 0x87ff, MWA_RAM },
{ 0x8800, 0x8800, qix_palettebank_w, &qix_palettebank },
{ 0x8c00, 0x8c00, qix_data_firq_w },
{ 0x9000, 0x93ff, qix_paletteram_w, &paletteram },
{ 0x9400, 0x9400, qix_addresslatch_w },
{ 0x9402, 0x9403, MWA_RAM, &qix_videoaddress },
{ 0x9c00, 0x9FFF, MWA_RAM }, /* Video controller */
{ 0xa000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress zoo_writemem_video[] =
{
{ 0x0000, 0x7fff, qix_videoram_w },
{ 0x8000, 0x83ff, qix_sharedram_w },
{ 0x8400, 0x86ff, MWA_RAM },
{ 0x8700, 0x87ff, MWA_RAM },
{ 0x8800, 0x8800, qix_palettebank_w, &qix_palettebank }, /* LEDs are upper 6 bits */
{ 0x8801, 0x8801, zoo_bankswitch_w },
{ 0x8c00, 0x8c00, qix_data_firq_w },
{ 0x8c01, 0x8c01, MWA_NOP }, /* interrupt acknowledge */
{ 0x9000, 0x93ff, qix_paletteram_w, &paletteram },
{ 0x9400, 0x9400, qix_addresslatch_w },
{ 0x9402, 0x9403, MWA_RAM, &qix_videoaddress },
{ 0xa000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem_sound[] =
{
{ 0x0000, 0x007f, MWA_RAM },
{ 0x2000, 0x2003, pia_6_w },
{ 0x4000, 0x4003, pia_5_w },
{ 0xf000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress zoo_writemem_sound[] =
{
{ 0x0000, 0x007f, MWA_RAM },
{ 0x2000, 0x2003, pia_6_w },
{ 0x4000, 0x4003, pia_5_w },
{ 0xd000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress mcu_readmem[] =
{
{ 0x0000, 0x0000, sdungeon_68705_mcu_r },
{ 0x0001, 0x0001, sdungeon_68705_portb_r },
{ 0x0002, 0x0002, sdungeon_68705_portc_r },
{ 0x0007, 0x000f, MRA_RAM },
{ 0x0010, 0x007f, MRA_RAM },
{ 0x0080, 0x07ff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress mcu_writemem[] =
{
{ 0x0000, 0x0000, sdungeon_68705_mcu_w },
{ 0x0001, 0x000f, MWA_RAM },
{ 0x0010, 0x007f, MWA_RAM },
{ 0x0080, 0x07ff, MWA_ROM },
{ -1 } /* end of table */
};
INPUT_PORTS_START( input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -