summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/xtheball.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/xtheball.c')
-rw-r--r--src/mame/drivers/xtheball.c415
1 files changed, 415 insertions, 0 deletions
diff --git a/src/mame/drivers/xtheball.c b/src/mame/drivers/xtheball.c
new file mode 100644
index 00000000000..2dce3ff2191
--- /dev/null
+++ b/src/mame/drivers/xtheball.c
@@ -0,0 +1,415 @@
+/*************************************************************************
+
+ X the Ball
+
+ driver by Aaron Giles
+
+**************************************************************************/
+
+#include "driver.h"
+#include "cpu/tms34010/tms34010.h"
+#include "video/tlc34076.h"
+#include "machine/ticket.h"
+#include "sound/dac.h"
+
+
+
+/*************************************
+ *
+ * Global variables
+ *
+ *************************************/
+
+static UINT16 *vram_bg, *vram_fg;
+static UINT8 bitvals[32];
+
+
+
+/*************************************
+ *
+ * Machine init
+ *
+ *************************************/
+
+static MACHINE_RESET( xtheball )
+{
+ tlc34076_reset(6);
+ ticket_dispenser_init(100, 1, 1);
+}
+
+
+
+/*************************************
+ *
+ * Video update
+ *
+ *************************************/
+
+static void xtheball_scanline_update(running_machine *machine, int screen, mame_bitmap *bitmap, int scanline, const tms34010_display_params *params)
+{
+ UINT16 *srcbg = &vram_bg[(params->rowaddr << 8) & 0xff00];
+ UINT16 *dest = BITMAP_ADDR16(bitmap, scanline, 0);
+ int coladdr = params->coladdr;
+ int x;
+
+ /* bit value 0x13 controls which foreground mode to use */
+ if (!bitvals[0x13])
+ {
+ /* mode 0: foreground is the same as background */
+ UINT16 *srcfg = &vram_fg[(params->rowaddr << 8) & 0xff00];
+
+ for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
+ {
+ UINT16 fgpix = srcfg[coladdr & 0xff];
+ UINT16 bgpix = srcbg[coladdr & 0xff];
+
+ dest[x + 0] = ((fgpix & 0x00ff) != 0) ? (fgpix & 0xff) : (bgpix & 0xff);
+ dest[x + 1] = ((fgpix & 0xff00) != 0) ? (fgpix >> 8) : (bgpix >> 8);
+ }
+ }
+ else
+ {
+ /* mode 1: foreground is half background resolution in */
+ /* X and supports two pages */
+ UINT16 *srcfg = &vram_fg[(params->rowaddr << 7) & 0xff00];
+
+ for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
+ {
+ UINT16 fgpix = srcfg[(coladdr >> 1) & 0xff] >> (8 * (coladdr & 1));
+ UINT16 bgpix = srcbg[coladdr & 0xff];
+
+ dest[x + 0] = ((fgpix & 0x00ff) != 0) ? (fgpix & 0xff) : (bgpix & 0xff);
+ dest[x + 1] = ((fgpix & 0x00ff) != 0) ? (fgpix & 0xff) : (bgpix >> 8);
+ }
+ }
+
+}
+
+
+
+/*************************************
+ *
+ * Shift register transfers
+ *
+ *************************************/
+
+static void xtheball_to_shiftreg(UINT32 address, UINT16 *shiftreg)
+{
+ if (address >= 0x01000000 && address <= 0x010fffff)
+ memcpy(shiftreg, &vram_bg[TOWORD(address & 0xff000)], TOBYTE(0x1000));
+ else if (address >= 0x02000000 && address <= 0x020fffff)
+ memcpy(shiftreg, &vram_fg[TOWORD(address & 0xff000)], TOBYTE(0x1000));
+ else
+ logerror("%08X:xtheball_to_shiftreg(%08X)\n", activecpu_get_pc(), address);
+}
+
+
+static void xtheball_from_shiftreg(UINT32 address, UINT16 *shiftreg)
+{
+ if (address >= 0x01000000 && address <= 0x010fffff)
+ memcpy(&vram_bg[TOWORD(address & 0xff000)], shiftreg, TOBYTE(0x1000));
+ else if (address >= 0x02000000 && address <= 0x020fffff)
+ memcpy(&vram_fg[TOWORD(address & 0xff000)], shiftreg, TOBYTE(0x1000));
+ else
+ logerror("%08X:xtheball_from_shiftreg(%08X)\n", activecpu_get_pc(), address);
+}
+
+
+
+/*************************************
+ *
+ * Sound data access
+ *
+ *************************************/
+
+static WRITE16_HANDLER( dac_w )
+{
+ if (ACCESSING_MSB)
+ DAC_data_w(0, data >> 8);
+}
+
+
+
+/*************************************
+ *
+ * Output ports
+ *
+ *************************************/
+
+static WRITE16_HANDLER( bit_controls_w )
+{
+ if (ACCESSING_LSB)
+ {
+ if (bitvals[offset] != (data & 1))
+ {
+ logerror("%08x:bit_controls_w(%x,%d)\n", activecpu_get_pc(), offset, data & 1);
+
+ switch (offset)
+ {
+ case 7:
+ ticket_dispenser_w(0, data << 7);
+ break;
+
+ case 8:
+ set_led_status(0, data & 1);
+ break;
+ }
+ }
+ bitvals[offset] = data & 1;
+ }
+// popmessage("%d%d%d%d-%d%d%d%d--%d%d%d%d-%d%d%d%d",
+/*
+ bitvals[0],
+ bitvals[1],
+ bitvals[2],
+ bitvals[3],
+ bitvals[4], // meter
+ bitvals[5],
+ bitvals[6], // tickets
+ bitvals[7], // tickets
+ bitvals[8], // start lamp
+ bitvals[9], // lamp
+ bitvals[10], // lamp
+ bitvals[11], // lamp
+ bitvals[12], // lamp
+ bitvals[13], // lamp
+ bitvals[14], // lamp
+ bitvals[15] // lamp
+*/
+/* bitvals[16],
+ bitvals[17],
+ bitvals[18],
+ bitvals[19], // video foreground control
+ bitvals[20],
+ bitvals[21],
+ bitvals[22],
+ bitvals[23],
+ bitvals[24],
+ bitvals[25],
+ bitvals[26],
+ bitvals[27],
+ bitvals[28],
+ bitvals[29],
+ bitvals[30],
+ bitvals[31]
+*/
+// );
+}
+
+
+
+/*************************************
+ *
+ * Input ports
+ *
+ *************************************/
+
+static READ16_HANDLER( port0_r )
+{
+ int result = readinputport(0);
+ result ^= ticket_dispenser_r(0) >> 3;
+ return result;
+}
+
+
+static READ16_HANDLER( analogx_r )
+{
+ return (readinputportbytag("ANALOGX") << 8) | 0x00ff;
+}
+
+
+static READ16_HANDLER( analogy_watchdog_r )
+{
+ /* doubles as a watchdog address */
+ watchdog_reset_w(0,0);
+ return (readinputportbytag("ANALOGY") << 8) | 0x00ff;
+}
+
+
+
+/*************************************
+ *
+ * Main CPU memory map
+ *
+ *************************************/
+
+static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 )
+ AM_RANGE(0x00000000, 0x0001ffff) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size)
+ AM_RANGE(0x01000000, 0x010fffff) AM_RAM AM_BASE(&vram_bg)
+ AM_RANGE(0x02000000, 0x020fffff) AM_RAM AM_BASE(&vram_fg)
+ AM_RANGE(0x03000000, 0x030000ff) AM_READWRITE(tlc34076_lsb_r, tlc34076_lsb_w)
+ AM_RANGE(0x03040000, 0x030401ff) AM_WRITE(bit_controls_w)
+ AM_RANGE(0x03040080, 0x0304008f) AM_READ(port0_r)
+ AM_RANGE(0x03040100, 0x0304010f) AM_READ(analogx_r)
+ AM_RANGE(0x03040110, 0x0304011f) AM_READ(input_port_1_word_r)
+ AM_RANGE(0x03040130, 0x0304013f) AM_READ(input_port_2_word_r)
+ AM_RANGE(0x03040140, 0x0304014f) AM_READ(input_port_3_word_r)
+ AM_RANGE(0x03040150, 0x0304015f) AM_READ(input_port_4_word_r)
+ AM_RANGE(0x03040160, 0x0304016f) AM_READ(input_port_5_word_r)
+ AM_RANGE(0x03040170, 0x0304017f) AM_READ(input_port_6_word_r)
+ AM_RANGE(0x03040180, 0x0304018f) AM_READ(analogy_watchdog_r)
+ AM_RANGE(0x03060000, 0x0306000f) AM_WRITE(dac_w)
+ AM_RANGE(0x04000000, 0x057fffff) AM_ROM AM_REGION(REGION_USER2, 0)
+ AM_RANGE(0xc0000000, 0xc00001ff) AM_READWRITE(tms34010_io_register_r, tms34010_io_register_w)
+ AM_RANGE(0xfff80000, 0xffffffff) AM_ROM AM_REGION(REGION_USER1, 0)
+ADDRESS_MAP_END
+
+
+
+/*************************************
+ *
+ * Input ports
+ *
+ *************************************/
+
+static INPUT_PORTS_START( xtheball )
+ PORT_START
+ PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_DIPNAME( 0x0700, 0x0000, "Target Tickets")
+ PORT_DIPSETTING( 0x0000, "3" )
+ PORT_DIPSETTING( 0x0100, "4" )
+ PORT_DIPSETTING( 0x0200, "5" )
+ PORT_DIPSETTING( 0x0300, "6" )
+ PORT_DIPSETTING( 0x0400, "7" )
+ PORT_DIPSETTING( 0x0500, "8" )
+ PORT_DIPSETTING( 0x0600, "9" )
+ PORT_DIPSETTING( 0x0700, "10" )
+ PORT_DIPNAME( 0x0800, 0x0000, DEF_STR( Coinage ))
+ PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ))
+ PORT_DIPSETTING( 0x0800, DEF_STR( 1C_2C ))
+ PORT_DIPNAME( 0x1000, 0x1000, "Automatic 1 Ticket" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x1000, DEF_STR( On ))
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ))
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x2000, DEF_STR( On ))
+ PORT_DIPNAME( 0x4000, 0x4000, "Game Tune" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x4000, DEF_STR( On ))
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Demo_Sounds ))
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x8000, DEF_STR( On ))
+
+ /* service mode is funky:
+ hit F2 to enter bookkeeping mode; hit service1 (9) to exit
+ hold service 1 (9) and hit F2 to enter test mode; hit service2 (0) to exit
+ */
+ PORT_START
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(5)
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE2 )
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN3 )
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START
+ PORT_SERVICE_NO_TOGGLE( 0x0001, IP_ACTIVE_HIGH )
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
+ PORT_BIT( 0xfffe, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START_TAG("ANALOGX")
+ PORT_BIT( 0x00ff, 0x0000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1)
+
+ PORT_START_TAG("ANALOGY")
+ PORT_BIT( 0x00ff, 0x0000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1)
+INPUT_PORTS_END
+
+
+
+/*************************************
+ *
+ * 34010 configuration
+ *
+ *************************************/
+
+static tms34010_config tms_config =
+{
+ FALSE, /* halt on reset */
+ 0, /* the screen operated on */
+ 5000000, /* pixel clock */
+ 2, /* pixels per clock */
+ xtheball_scanline_update, /* scanline callback */
+ NULL, /* generate interrupt */
+ xtheball_to_shiftreg, /* write to shiftreg function */
+ xtheball_from_shiftreg /* read from shiftreg function */
+};
+
+
+
+/*************************************
+ *
+ * Machine drivers
+ *
+ *************************************/
+
+static MACHINE_DRIVER_START( xtheball )
+
+ MDRV_CPU_ADD(TMS34010, 40000000/TMS34010_CLOCK_DIVIDER)
+ MDRV_CPU_CONFIG(tms_config)
+ MDRV_CPU_PROGRAM_MAP(main_map,0)
+ MDRV_CPU_PERIODIC_INT(irq1_line_pulse,15000)
+
+ MDRV_MACHINE_RESET(xtheball)
+ MDRV_NVRAM_HANDLER(generic_1fill)
+
+ /* video hardware */
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
+ MDRV_PALETTE_LENGTH(256)
+
+ MDRV_SCREEN_ADD("main", 0)
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+ MDRV_SCREEN_SIZE(512,256)
+ MDRV_SCREEN_VISIBLE_AREA(0,511, 24,247)
+ MDRV_SCREEN_REFRESH_RATE(60)
+
+ MDRV_VIDEO_UPDATE(tms340x0)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_MONO("mono")
+
+ MDRV_SOUND_ADD(DAC, 0)
+ MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+MACHINE_DRIVER_END
+
+
+
+/*************************************
+ *
+ * ROM definitions
+ *
+ *************************************/
+
+ROM_START( xtheball )
+ ROM_REGION16_LE( 0x10000, REGION_USER1, 0 ) /* 34010 code */
+ ROM_LOAD16_BYTE( "aces18-lo.ic13", 0x000000, 0x8000, CRC(c0e80004) SHA1(d79c2e7301857148674fffad349c7a2a98fa1ee2) )
+ ROM_LOAD16_BYTE( "aces18-hi.ic19", 0x000001, 0x8000, CRC(5a682f92) SHA1(ed77c02cbdcff9eac32760cee67e3a784efacac7) )
+
+ ROM_REGION16_LE( 0x300000, REGION_USER2, 0 ) /* 34010 code */
+ ROM_LOAD16_BYTE( "xtb-ic6.bin", 0x000000, 0x40000, CRC(a3cc01b8) SHA1(49d42bb17c314609f371df7d7ace57e54fdf6335) )
+ ROM_LOAD16_BYTE( "xtb-ic7.bin", 0x000001, 0x40000, CRC(8dfa6c1b) SHA1(a32940b3f9501a44e1d1ef1628f8a64b32aa2183) )
+ ROM_LOAD16_BYTE( "xtb-1l.ic8", 0x100000, 0x80000, CRC(df52c00f) SHA1(9a89d780ad394b55ce9540a5743bbe571543288f) )
+ ROM_LOAD16_BYTE( "xtb-1h.ic9", 0x100001, 0x80000, CRC(9ce7785b) SHA1(9a002ba492cdc35391df2b55dfe90c55b7d48ad1) )
+ ROM_LOAD16_BYTE( "xtb-2l.ic10", 0x200000, 0x80000, CRC(e2545a19) SHA1(c2fe5adf7a174cec6aad63baa1b92761ef21d5a4) )
+ ROM_LOAD16_BYTE( "xtb-2h.ic11", 0x200001, 0x80000, CRC(50c27558) SHA1(ecfb7d918868d35a8cde45f7d04fdfc3ffc06328) )
+ROM_END
+
+
+
+/*************************************
+ *
+ * Game drivers
+ *
+ *************************************/
+
+GAME( 1991, xtheball, 0, xtheball, xtheball, 0, ROT0, "Rare", "X the Ball", 0 )