diff options
Diffstat (limited to 'src/mame/drivers/thayers.c')
-rw-r--r-- | src/mame/drivers/thayers.c | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/src/mame/drivers/thayers.c b/src/mame/drivers/thayers.c new file mode 100644 index 00000000000..f2535488b0d --- /dev/null +++ b/src/mame/drivers/thayers.c @@ -0,0 +1,514 @@ +/* +RDI Video Systems Thayer's Quest laserdisc hardware +Driver by Andrew Gardner from schematics with help from Daphne Source + +Notes: + How odd. The schematics say there's a COP421L hooked up, but they also make mention of + a COP404L - A ROMless COP420 with 1k of RAM. I wonder which one is correct? + +Todo: + Add SIO to the cop420 core. + Fix up my poor interpretation of the hard-to-read schematics. + Write a real SC-01 (SSI-263) emulator for MAME. + Convert to tilemaps. +*/ + +#include "driver.h" +#include "render.h" +#include "machine/laserdsc.h" +#include "cpu/cop400/cop400.h" + +#define SCHEMATIC_CLOCK (4000000) + +/* + * Z80 IRQ Status bit + * ------------------ + * + * Bit | Use + * 76543210-+---------------- + * -------x | Unused + * ------x- | Unused + * -----x-- | SSI-263 Request Data. + * ----x--- | always high. (? but it's checked at 0x1bb ?) + * ---x---- | /TIMER INT. + * --x----- | /DATA RDY INT. + * -x------ | /CART PRES. + * x------- | Unused + */ +static UINT8 z80_irq_status; + +#define Z80_IRQ_STATUS_SET() (z80_irq_status = 0x00) +#define Z80_IRQ_STATUS_CLEAR() (z80_irq_status = 0xff) + +#define Z80_SSI_REQUEST() ((z80_irq_status & 0x04) >> 2) +#define Z80_TIMER_INT() ((z80_irq_status & 0x10) >> 4) +#define Z80_DATA_RDY_INT() ((z80_irq_status & 0x20) >> 5) +#define Z80_CART_PRES() ((z80_irq_status & 0x40) >> 6) + +#define SET_Z80_SSI_REQUEST() (z80_irq_status &= ~0x04) +#define SET_Z80_TIMER_INT() (z80_irq_status &= ~0x10) +#define SET_Z80_DATA_RDY_INT() (z80_irq_status &= ~0x20) +#define SET_Z80_CART_PRES() (z80_irq_status &= ~0x40) + +#define CLEAR_Z80_SSI_REQUEST() (z80_irq_status |= 0x04) +#define CLEAR_Z80_TIMER_INT() (z80_irq_status |= 0x10) +#define CLEAR_Z80_DATA_RDY_INT() (z80_irq_status |= 0x20) +#define CLEAR_Z80_CART_PRES() (z80_irq_status |= 0x40) + + +/* Misc variables */ +static UINT8* ram_ic; +static laserdisc_info *discinfo; + +static UINT8 m_ssi_control; +static UINT8 cop_g_latch; +static UINT8 cop_l_latch; + + + +/* VIDEO GOODS */ +static VIDEO_UPDATE( thayers ) +{ + /* display disc information */ + if (discinfo != NULL) + popmessage("%s", laserdisc_describe_state(discinfo)); + + return 0; +} + + + +/* MEMORY HANDLERS */ +/* Z80 R/W */ +static READ8_HANDLER(z80_irq_status_r) +{ + return z80_irq_status; +} + +static READ8_HANDLER(ram_ic_read) +{ + /* Daphne patches. + if (offset == 0xbe07-0x8000) + return 0x02; + + if (offset == 0xbe17-0x8000) + return 0x01; + */ + + return ram_ic[offset]; +} + +static UINT32 laserdisc_status_r(void *param) +{ + if (discinfo == NULL) + return 0; + + /* Someday handle multiple LD players */ + return (laserdisc_line_r(discinfo, LASERDISC_LINE_STATUS) == ASSERT_LINE) ? 0 : 1; +} + +static UINT32 laserdisc_command_r(void *param) +{ + if (discinfo == NULL) + return 0; + + /* Someday handle multiple LD players */ + return (laserdisc_line_r(discinfo, LASERDISC_LINE_COMMAND) == ASSERT_LINE) ? 0 : 1; +} + +static WRITE8_HANDLER(ram_ic_write) +{ + ram_ic[offset] = data; +} + +static WRITE8_HANDLER(data_ready_int_w) +{ + CLEAR_Z80_DATA_RDY_INT(); + /* Hackaroo? */ + /* cop_l_latch = 0x00; */ +} + +static WRITE8_HANDLER(timer_int_w) +{ + CLEAR_Z80_TIMER_INT(); +} + +static WRITE8_HANDLER(write_cop) +{ + logerror("Writing 0x%x to COP port G\n", data); + + /* Bits 5-7 write to COP421 ports G0-G2 */ + cop_g_latch = (data >> 5) & 0x07; + + /* Bit 2 goes to BANKSELT */ + /* bankselect = (data & 0x04) >> 2; */ + + /* Bit 1 goes to CS128x? (illegible schems) */ +} + +#ifdef UNUSED_FUNCTION +static WRITE8_HANDLER(data_write_cop) +{ + cop_l_latch = data; +} +#endif + +static WRITE8_HANDLER(intrq_w) +{ + cpunum_set_input_line(0, 0, ASSERT_LINE); +} + +static WRITE8_HANDLER(sc01_register_w) +{ + /* (Thank you Daphne) */ + switch (offset) + { + case 0x00: + if (m_ssi_control) + { + logerror("SC-01 control mode : 0x%x\n", data); + + switch(data) + { + /* Stop requesting phonemes */ + case 0x00: + CLEAR_Z80_SSI_REQUEST(); + break; + + /* Start adding phonemes */ + case 0xc0: + SET_Z80_SSI_REQUEST(); + if (!(Z80_SSI_REQUEST())) + logerror("SETTING IRQ LINE sc01\n"); + cpunum_set_input_line(0, 0, ASSERT_LINE); + break; + + default: + logerror("SC-01 control mode invalid code 0x%x\n", data); + break; + } + } + else + { + logerror("SC-01 receiving phonemes 0x%x\n", data & 0x3f); + } + break; + + case 0x01: + logerror("SC-01 inflection changed to 0x%x\n", data); + break; + + case 0x02: + logerror("SC-01 speech rate changed to 0x%x\n", data); + break; + + case 0x03: + if (data & 0x80) + { + m_ssi_control = 1; + logerror("SC-01 now in control mode.\n"); + } + else if (data & 0x70) + { + m_ssi_control = 0; + logerror("SC-01 control mode cleared.\n"); + } + else + { + logerror("SC-01 amplitude manipulated 0x%x.\n", data); + } + break; + + case 0x04: + logerror("SC-01 filter frequency changed to 0x%x.\n", data); + break; + } +} + + +/* COP R/W */ +/* All 8 l pins are hooked up here */ +static READ8_HANDLER(cop_l_read) +{ + logerror("COP - Reading from L @ (0x%x)\n", activecpu_get_pc()); + return cop_l_latch; +} + +/* Pins g0, g1, g2, and g3 are all hooked up */ +static READ8_HANDLER(cop_g_read) +{ + logerror("COP - Reading from G @ (0x%x)\n", activecpu_get_pc()); + return cop_g_latch; +} + +static WRITE8_HANDLER(cop_l_write) +{ + logerror("COP - WRITING TO L 0x%x @ (0x%x)\n", data, activecpu_get_pc()); + cop_l_latch = data; +} + +static WRITE8_HANDLER(cop_g_write) +{ + logerror("COP - WRITING TO G 0x%x @ (0x%x)\n", data, activecpu_get_pc()); + + /* Bit 3 goes to an enable pin on the data latch? */ + /* Bits 0-2 seem to go into the wrong side of a logic IC? */ +} + +/* Schematics say pins d0 and d1 are the only two that are hooked up */ +static WRITE8_HANDLER(cop_d_write) +{ + int irq_flag = 0; + + logerror("COP - WRITING TO D 0x%x @ (0x%x)\n", data, activecpu_get_pc()); + + /* Pin d0 - TIMER INT */ + if (!(data & 0x01)) + { + SET_Z80_TIMER_INT(); + irq_flag = 1; + logerror("THE COP IS TRIPPING THE TIMER INTERRUPT\n"); + } + else + { + CLEAR_Z80_TIMER_INT(); + } + + /* Pin d1 - DATA READY INT */ + if (!(data & 0x02)) + { + SET_Z80_DATA_RDY_INT(); + irq_flag = 1; + logerror("THE COP IS TRIPPING THE DATA READY INTERRUPT\n"); + } + else + { + CLEAR_Z80_DATA_RDY_INT(); + } + + /* Assert the Z80's interrupt line if necessary */ + if (irq_flag) + { + cpunum_set_input_line(0, 0, ASSERT_LINE); + } +} + +static WRITE8_HANDLER(cop_sk_write) +{ + /* I think this data falls off into a black hole - the pins aren't hooked up. + The COP400 XAS instruction writes to both SK and SIO, that's why the CPU writes data here at all. */ +} + +static WRITE8_HANDLER(cop_sio_write) +{ + /* This data is sent to the CLK pin of the keyboard handling logic. We don't need to emulate it here. */ +} + + + +/* PROGRAM MAPS */ +static ADDRESS_MAP_START( mainmem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x7fff) AM_ROM + AM_RANGE(0x8000, 0xbfff) AM_READWRITE(ram_ic_read,ram_ic_write) AM_BASE(&ram_ic) /* Not quite sure how big the RAM IC is. */ + AM_RANGE(0xc000, 0xdfff) AM_ROM /* This is what Daphne says - we'll soon see. */ +ADDRESS_MAP_END + +static ADDRESS_MAP_START( copmem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x000, 0x3ff) AM_ROM /* The schematics seem to claim this is a 2716 (0x800 bytes) - is the dump too small? */ +ADDRESS_MAP_END + + +/* IO MAPS */ +static ADDRESS_MAP_START( mainio, ADDRESS_SPACE_IO, 8 ) + ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) + AM_RANGE(0x00,0x04) AM_WRITE(sc01_register_w) + AM_RANGE(0x20,0x20) AM_WRITE(write_cop) + AM_RANGE(0x40,0x40) AM_READ(z80_irq_status_r) +/* AM_RANGE(0x80,0x80) AM_WRITE(data_write_cop) */ + AM_RANGE(0xa0,0xa0) AM_WRITE(timer_int_w) + AM_RANGE(0xc0,0xc0) AM_WRITE(data_ready_int_w) + +/* AM_RANGE(0xf0,0xf0) */ /* Laserdisc data read */ + AM_RANGE(0xf1,0xf1) AM_READ_PORT("DSWB") /* 4 dips, 2 coins, Laserdisc 'ready' and 'enter' pins */ + AM_RANGE(0xf2,0xf2) AM_READ_PORT("DSWA") /* 8 dips */ + AM_RANGE(0xf3,0xf3) AM_WRITE(intrq_w) /* goes to /INTRQ */ +/* AM_RANGE(0xf4,0xf4) */ /* Laserdisc data write */ +/* AM_RANGE(0xf5,0xf5) */ /* Coin counter, 0xf4 write enable, DIP-controlled (SWB-6) LDV1000 'enter' line, and LDV1000 INT/!EXT line */ +/* AM_RANGE(0xf6,0xf6) */ /* Scoreboard DEN1 */ +/* AM_RANGE(0xf7,0xf7) */ /* Scoreboard DEN2 */ +ADDRESS_MAP_END + +static ADDRESS_MAP_START( copio, ADDRESS_SPACE_IO, 8 ) + AM_RANGE(COP400_PORT_L, COP400_PORT_L) AM_READWRITE(cop_l_read,cop_l_write) + AM_RANGE(COP400_PORT_G, COP400_PORT_G) AM_READWRITE(cop_g_read,cop_g_write) + AM_RANGE(COP400_PORT_D, COP400_PORT_D) AM_WRITE(cop_d_write) + AM_RANGE(COP400_PORT_SK, COP400_PORT_SK) AM_WRITE(cop_sk_write) + AM_RANGE(COP400_PORT_SIO,COP400_PORT_SIO) AM_READ_PORT("THAYERS_LETTERS") AM_WRITE(cop_sio_write) /* Unemulated in COP40x core, so nothing happens ATM */ +ADDRESS_MAP_END /* This is also very wrong. The keyboard interface needs to + be understood much better than what I have here */ + +/* PORTS */ +static INPUT_PORTS_START( thayers ) + PORT_START_TAG("DSWA") + PORT_DIPNAME( 0x07, 0x07, "Time Per Coin" ) PORT_DIPLOCATION( "A:3,2,1" ) + PORT_DIPSETTING( 0x07, "110 Seconds" ) + PORT_DIPSETTING( 0x06, "95 Seconds" ) + PORT_DIPSETTING( 0x05, "80 Seconds" ) + PORT_DIPSETTING( 0x04, "70 Seconds" ) + PORT_DIPSETTING( 0x03, "60 Seconds" ) + PORT_DIPSETTING( 0x02, "45 Seconds" ) + PORT_DIPSETTING( 0x01, "30 Seconds" ) + PORT_DIPSETTING( 0x00, DEF_STR ( Free_Play ) ) + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Coinage ) ) PORT_DIPLOCATION( "A:4" ) + PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x08, DEF_STR( 1C_1C ) ) + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Lives ) ) PORT_DIPLOCATION( "A:5" ) + PORT_DIPSETTING( 0x10, "3" ) + PORT_DIPSETTING( 0x00, "5" ) + PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION( "A:6" ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x20, DEF_STR( On ) ) + PORT_DIPNAME( 0x40, 0x40, "Attract Mode Audio" ) PORT_DIPLOCATION( "A:7" ) + PORT_DIPSETTING( 0x40, "Always Playing" ) + PORT_DIPSETTING( 0x00, "One Out of 8 Times" ) + PORT_DIPUNUSED_DIPLOC( 0x80, IP_ACTIVE_LOW, "A:8" ) + + PORT_START_TAG("DSWB") + PORT_DIPNAME( 0x01, 0x01, "Gameplay Mode" ) PORT_DIPLOCATION( "B:1" ) + PORT_DIPSETTING( 0x01, "Normal Play" ) + PORT_DIPSETTING( 0x00, "Self-Diagnostics Mode" ) + PORT_DIPUNUSED_DIPLOC( 0x02, IP_ACTIVE_LOW, "B:2" ) + PORT_DIPUNUSED_DIPLOC( 0x04, IP_ACTIVE_LOW, "B:3" ) + PORT_DIPNAME( 0x08, 0x08, "LD Player" ) PORT_DIPLOCATION( "B:4" ) + PORT_DIPSETTING( 0x08, "LDV-1000" ) + PORT_DIPSETTING( 0x00, "PR-7820" ) + /* DIP SWITCH 5 isn't read here, but it also controls LD player selection - I wonder how to add it properly? */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(laserdisc_command_r, 0 ) /* Enter pin on LD player */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(laserdisc_status_r, 0 ) /* Ready pin on LD player */ + + /* The following 3 port definitions can be combined into one (thus making this scheme work) if the port bit limit is raised from 32 to 64 */ + /* But maybe there's a better way to do it than what I have here? */ + /* Or maybe this doesn't even work at all :) */ + /* "Scan codes" heisted from Daphne - need to be tested! */ + PORT_START_TAG("THAYERS_ACTIONS") + PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( No ) ) PORT_CODE( KEYCODE_DEL_PAD ) + PORT_BIT( 0x31, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( Yes ) ) PORT_CODE( KEYCODE_0_PAD ) + PORT_BIT( 0x32, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Items" ) PORT_CODE( KEYCODE_1_PAD ) + PORT_BIT( 0x33, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Drop Item" ) PORT_CODE( KEYCODE_2_PAD ) + PORT_BIT( 0x34, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Give Score" ) PORT_CODE( KEYCODE_3_PAD ) + PORT_BIT( 0x35, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Replay" ) PORT_CODE( KEYCODE_4_PAD ) + PORT_BIT( 0x36, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Combine Action" ) PORT_CODE( KEYCODE_6_PAD ) + PORT_BIT( 0x37, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Save Game" ) PORT_CODE( KEYCODE_7_PAD ) + PORT_BIT( 0x38, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Update" ) PORT_CODE( KEYCODE_8_PAD ) + PORT_BIT( 0x39, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Hint" ) PORT_CODE( KEYCODE_9_PAD ) + + PORT_START_TAG("THAYERS_LETTERS") + PORT_BIT( 0x41, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "A" ) PORT_CODE( KEYCODE_A ) + PORT_BIT( 0x42, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "B - Silver Wheat" ) PORT_CODE( KEYCODE_B ) + PORT_BIT( 0x43, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "C - Spell of Seeing" ) PORT_CODE( KEYCODE_C ) + PORT_BIT( 0x44, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "D - Great Circlet" ) PORT_CODE( KEYCODE_D ) + PORT_BIT( 0x45, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "E - Black Mace" ) PORT_CODE( KEYCODE_E ) + PORT_BIT( 0x46, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F - Hunting Horn" ) PORT_CODE( KEYCODE_F ) + PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "G - Long Bow" ) PORT_CODE( KEYCODE_G ) + PORT_BIT( 0x48, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "H - Medallion" ) PORT_CODE( KEYCODE_H ) + PORT_BIT( 0x49, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "I - Crown" ) PORT_CODE( KEYCODE_I ) + PORT_BIT( 0x4a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "J - Onyx Seal" ) PORT_CODE( KEYCODE_J ) + PORT_BIT( 0x4b, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "K - Orb of Quoid" ) PORT_CODE( KEYCODE_K ) + PORT_BIT( 0x4c, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "L" ) PORT_CODE( KEYCODE_L ) + PORT_BIT( 0x4d, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "M - Spell of Understanding" ) PORT_CODE( KEYCODE_M ) + PORT_BIT( 0x4e, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "N - Staff" ) PORT_CODE( KEYCODE_N ) + PORT_BIT( 0x4f, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "O - Crystal" ) PORT_CODE( KEYCODE_O ) + PORT_BIT( 0x50, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "P" ) PORT_CODE( KEYCODE_P ) + PORT_BIT( 0x51, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Q" ) PORT_CODE( KEYCODE_Q ) + PORT_BIT( 0x52, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "R - Blood Sword" ) PORT_CODE( KEYCODE_R ) + PORT_BIT( 0x53, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "S - Dagger" ) PORT_CODE( KEYCODE_S ) + PORT_BIT( 0x54, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "T - Chalice" ) PORT_CODE( KEYCODE_T ) + PORT_BIT( 0x55, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "U - Cold Fire" ) PORT_CODE( KEYCODE_U ) + PORT_BIT( 0x56, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "V - Shield" ) PORT_CODE( KEYCODE_V ) + PORT_BIT( 0x57, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "W - Amulet" ) PORT_CODE( KEYCODE_W ) + PORT_BIT( 0x58, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "X - Scepter" ) PORT_CODE( KEYCODE_X ) + PORT_BIT( 0x59, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Y - Coins" ) PORT_CODE( KEYCODE_Y ) + PORT_BIT( 0x5a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Z - Spell of Release" ) PORT_CODE( KEYCODE_Z ) + + PORT_START_TAG("THAYERS_NUMBERS") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "1 - Clear" ) PORT_CODE( KEYCODE_LCONTROL ) + PORT_BIT( 0x81, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "2" ) PORT_CODE( KEYCODE_RCONTROL ) + PORT_BIT( 0x82, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "3 - Enter" ) PORT_CODE( KEYCODE_ENTER ) + PORT_BIT( 0x83, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "4 - Space" ) PORT_CODE( KEYCODE_SPACE ) +INPUT_PORTS_END + + +static MACHINE_START( thayers ) +{ + discinfo = laserdisc_init(LASERDISC_TYPE_LDV1000, get_disk_handle(0), 0); + return; +} + +static INTERRUPT_GEN( vblank_callback_thayers ) +{ + laserdisc_vsync(discinfo); +} + + +/* DRIVER */ +static MACHINE_DRIVER_START( thayers ) +/* main cpu */ + MDRV_CPU_ADD(Z80, SCHEMATIC_CLOCK) + MDRV_CPU_PROGRAM_MAP(mainmem,0) + MDRV_CPU_IO_MAP(mainio,0) + MDRV_CPU_VBLANK_INT(vblank_callback_thayers, 1) + + MDRV_MACHINE_START(thayers) + +/* io device cpu */ + MDRV_CPU_ADD(COP420, SCHEMATIC_CLOCK/2/8) /* Can't read the schematics, but this is what daphne says */ + MDRV_CPU_PROGRAM_MAP(copmem,0) + MDRV_CPU_IO_MAP(copio,0) + +/* video */ + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + MDRV_SCREEN_REFRESH_RATE(60) + MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) + MDRV_SCREEN_SIZE(32*10, 32*8) + MDRV_SCREEN_VISIBLE_AREA(0*10, 32*10-1, 0*8, 32*8-1) + + MDRV_PALETTE_LENGTH(256) + MDRV_VIDEO_UPDATE(thayers) + +/* sound */ +MACHINE_DRIVER_END + + +ROM_START( thayers ) + ROM_REGION( 0xe000, REGION_CPU1, 0 ) + ROM_LOAD( "tq_u33.bin", 0x0000, 0x8000, CRC(82df5d89) SHA1(58dfd62bf8c5a55d1eba397d2c284e99a4685a3f) ) + ROM_LOAD( "tq_u1.bin", 0xc000, 0x2000, CRC(e8e7f566) SHA1(df7b83ef465c65446c8418bc6007447693b75021) ) + + ROM_REGION( 0x400, REGION_CPU2, 0 ) + ROM_LOAD( "tq_cop.bin", 0x000, 0x400, CRC(6748e6b3) SHA1(5d7d1ecb57c1501ef6a2d9691eecc9970586606b) ) +ROM_END + +ROM_START( thayersa ) + ROM_REGION( 0xe000, REGION_CPU1, 0 ) + ROM_LOAD( "tq_u33.bin", 0x0000, 0x8000, CRC(82df5d89) SHA1(58dfd62bf8c5a55d1eba397d2c284e99a4685a3f) ) + ROM_LOAD( "tq_u1.bin", 0xc000, 0x2000, CRC(33817e25) SHA1(f9750da863dd57fe2f5b6e8fce9c6695dc5c9adc) ) + + ROM_REGION( 0x400, REGION_CPU2, 0 ) + ROM_LOAD( "tq_cop.bin", 0x000, 0x400, CRC(6748e6b3) SHA1(5d7d1ecb57c1501ef6a2d9691eecc9970586606b) ) +ROM_END + +static DRIVER_INIT( thayers ) +{ + Z80_IRQ_STATUS_CLEAR(); + m_ssi_control = 0; + + cop_g_latch = 0xff; +} + +/* YEAR NAME PARENT MACHINE INPUT INIT MONITOR COMPANY FULLNAME FLAGS) */ +GAME( 1983, thayers, 0, thayers, thayers, thayers, ROT0, "RDI Video Systems", "Thayer's Quest", GAME_NOT_WORKING|GAME_NO_SOUND) +GAME( 1983, thayersa, thayers, thayers, thayers, thayers, ROT0, "RDI Video Systems", "Thayer's Quest (Alternate Set)", GAME_NOT_WORKING|GAME_NO_SOUND) |