From 366460bd8f789e7e3bb53820aa67354ed785177f Mon Sep 17 00:00:00 2001 From: Phil Bennett Date: Thu, 20 Dec 2007 23:58:28 +0000 Subject: [PATCH] Renamed 'buggyb1' set to 'buggybjr' Also made it work properly. --- .gitattributes | 2 + src/mame/audio/tx1.c | 333 +++++++ src/mame/drivers/tx1.c | 1762 +++++++++++++++------------------ src/mame/includes/tx1.h | 106 ++ src/mame/machine/tx1.c | 2074 +++++++++++++++++++++++++++------------ src/mame/mame.mak | 2 +- src/mame/mamedriv.c | 2 +- src/mame/video/tx1.c | 1952 ++++++++++++++++++++++++++++++------ 8 files changed, 4296 insertions(+), 1937 deletions(-) create mode 100644 src/mame/audio/tx1.c create mode 100644 src/mame/includes/tx1.h diff --git a/.gitattributes b/.gitattributes index ad6f63d0662..2cdc389cad0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1127,6 +1127,7 @@ src/mame/audio/toaplan2.c svneol=native#text/plain src/mame/audio/trackfld.c svneol=native#text/plain src/mame/audio/triplhnt.c svneol=native#text/plain src/mame/audio/turbo.c svneol=native#text/plain +src/mame/audio/tx1.c svneol=native#text/plain src/mame/audio/vicdual.c svneol=native#text/plain src/mame/audio/videopin.c svneol=native#text/plain src/mame/audio/warpwarp.c svneol=native#text/plain @@ -2285,6 +2286,7 @@ src/mame/includes/triplhnt.h svneol=native#text/plain src/mame/includes/tubep.h svneol=native#text/plain src/mame/includes/turbo.h svneol=native#text/plain src/mame/includes/twincobr.h svneol=native#text/plain +src/mame/includes/tx1.h svneol=native#text/plain src/mame/includes/ultratnk.h svneol=native#text/plain src/mame/includes/unico.h svneol=native#text/plain src/mame/includes/vertigo.h svneol=native#text/plain diff --git a/src/mame/audio/tx1.c b/src/mame/audio/tx1.c new file mode 100644 index 00000000000..56305e1786d --- /dev/null +++ b/src/mame/audio/tx1.c @@ -0,0 +1,333 @@ +/*************************************************************************** + + Tatsumi TX-1/Buggy Boy sound hardware + +***************************************************************************/ +#include "driver.h" +#include "includes/tx1.h" +#include "video/resnet.h" +#include "sound/custom.h" +#include "streams.h" + +static sound_stream *stream; +static int freq_to_step; + +/************************************* + * + * TX-1 + * + *************************************/ + + +/************************************* + * + * Buggy Boy + * + *************************************/ + +#define BUGGYBOY_PIT_CLOCK (BUGGYBOY_ZCLK / 8) +#define BUGGYBOY_NOISE_CLOCK (BUGGYBOY_PIT_CLOCK / 4) + +#define BUGGYBOY_R1 47000.0 +#define BUGGYBOY_R2 22000.0 +#define BUGGYBOY_R3 10000.0 +#define BUGGYBOY_R4 5600.0 +#define BUGGYBOY_SHUNT 250.0 + +#define BUGGYBOY_R1S (1.0/(1.0/BUGGYBOY_R1 + 1.0/BUGGYBOY_SHUNT)) +#define BUGGYBOY_R2S (1.0/(1.0/BUGGYBOY_R2 + 1.0/BUGGYBOY_SHUNT)) +#define BUGGYBOY_R3S (1.0/(1.0/BUGGYBOY_R3 + 1.0/BUGGYBOY_SHUNT)) +#define BUGGYBOY_R4S (1.0/(1.0/BUGGYBOY_R4 + 1.0/BUGGYBOY_SHUNT)) + +static int noise_lfsra; +static int noise_lfsrb; +static int noise_lfsrc; +static int noise_lfsrd; +static int noise_counter; +static int step0; +static int step1; +static UINT8 ym_outputa; +static UINT8 ym_outputb; +static UINT16 buggyboy_eng_voltages[16]; + +static const double bb_engine_gains[16] = +{ + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2 + BUGGYBOY_R3 + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2 + BUGGYBOY_R3 + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2 + BUGGYBOY_R3S + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2 + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2S + BUGGYBOY_R3 + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2S + BUGGYBOY_R3 + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1 + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2 + BUGGYBOY_R3 + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2 + BUGGYBOY_R3 + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2 + BUGGYBOY_R3S + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2 + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3 + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3 + BUGGYBOY_R4S) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4 ) + 1.0/100E3)/100E3, + -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100E3)/100E3, +}; + + +/* + 8253 Programmable Interval Timer +*/ +static struct +{ + union + { +#ifdef LSB_FIRST + struct { UINT8 LSB; UINT8 MSB; }; +#else + struct { UINT8 MSB; UINT8 LSB; }; +#endif + UINT16 val; + } counts[3]; + + int idx[3]; +} pit8253; + +/* + Port A Port B + ====== ====== + + 0: Engine 1 gain (FR) #0 0: Coin Counter 1 + 1: Engine 1 gain (FR) #1 1: Coin Counter 2 + 2: Engine 1 gain (FR) #2 2: Coin Counter 3 (Unused) + 3: Engine 1 gain (FR) #3 3: Engine 0 gain + 4: Engine 1 gain (FL) #0 4: Noise EN1 + 5: Engine 1 gain (FL) #1 5: Noise EN2 + 6: Engine 1 gain (FL) #2 6: Enable YM IC24 output on RR + 7: Engine 1 gain (FL) #3 7: Enable YM IC19 output on RL + + + The engine sounds are generated by an 8253. There are two channels. + + #0 is the player's buggy + #1 is the opponents' buggies + + +------------> GAIN[1] +--> FL + | +--> FR + 8255 #0 --+--> BL + +--> BR + + 8255 #1 --+--> GAIN[2] ---> FL + +--> GAIN[3] ---> FR + + + [1] is used to amplify sound during tunnel. + [2] and [3] are stereo fades + +*/ + +WRITE8_HANDLER( bb_ym1_a_w ) +{ + stream_update(stream); + + ym_outputa = data ^ 0xff; +} + +WRITE8_HANDLER( bb_ym1_b_w ) +{ + double gain; + + stream_update(stream); + + ym_outputb = data ^ 0xff; + + coin_counter_w(0, data & 0x01); + coin_counter_w(1, data & 0x02); + + /* Until we support > 2 speakers, double the gain of the front speakers */ + + /* Rear left speaker */ + gain = data & 0x80 ? 1.0 : 2.0; + sndti_set_output_gain(SOUND_AY8910, 0, 0, gain); + sndti_set_output_gain(SOUND_AY8910, 0, 1, gain); + sndti_set_output_gain(SOUND_AY8910, 0, 2, gain); + + /* Rear right speaker */ + gain = data & 0x40 ? 1.0 : 2.0; + sndti_set_output_gain(SOUND_AY8910, 1, 0, gain); + sndti_set_output_gain(SOUND_AY8910, 1, 1, gain); + sndti_set_output_gain(SOUND_AY8910, 1, 2, gain); +} + + +WRITE8_HANDLER( pit8253_w ) +{ + stream_update(stream); + + if (offset < 3) + { + if (pit8253.idx[offset] == 0) + { + pit8253.counts[offset].LSB = data; + pit8253.idx[offset] = 1; + } + else + { + pit8253.counts[offset].MSB = data; + pit8253.idx[offset] = 0; + } + } + else + { + int mode = (data >> 1) & 7; + + if (mode == 3) + { + int cntsel = (data >> 6) & 3; + pit8253.idx[cntsel] = 0; + pit8253.counts[cntsel].val = 0; + } + else + mame_printf_debug("PIT8253: Unsupported mode %d.\n", mode); + + } +} + +READ8_HANDLER( pit8253_r ) +{ + mame_printf_debug("PIT R: %x", offset); + return 0; +} + +static void tx1_stream_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length) +{ + +} + +/* + This is admittedly a bit of a hack job... +*/ +static void buggyboy_stream_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length) +{ + int step_0, step_1; + int n1_en, n2_en; + double gain0, gain1_l, gain1_r; + + stream_sample_t *fl = &buffer[0][0]; + stream_sample_t *fr = &buffer[1][0]; + + /* Clear the buffers */ + memset(buffer[0], 0, length * sizeof(*buffer[0])); + memset(buffer[1], 0, length * sizeof(*buffer[1])); + + /* 8253 outputs for the player/opponent buggy engine sounds. */ + step_0 = pit8253.counts[0].val ? (BUGGYBOY_PIT_CLOCK / pit8253.counts[0].val) * freq_to_step : 0; + step_1 = pit8253.counts[1].val ? (BUGGYBOY_PIT_CLOCK / pit8253.counts[1].val) * freq_to_step : 0; + + gain0 = BIT(ym_outputb, 3) ? 1.0 : 2.0; + n1_en = BIT(ym_outputb, 4); + n2_en = BIT(ym_outputb, 5); + + gain1_l = bb_engine_gains[ym_outputa >> 4] * 5; + gain1_r = bb_engine_gains[ym_outputa & 0xf] * 5; + + while (length--) + { + int i; + stream_sample_t pit0, pit1, n1, n2; + pit0 = buggyboy_eng_voltages[(step0 >> 24) & 0xf]; + pit1 = buggyboy_eng_voltages[(step1 >> 24) & 0xf]; + + /* Calculate the tyre screech noise source */ + for (i = 0; i < BUGGYBOY_NOISE_CLOCK / Machine->sample_rate; ++i) + { + /* CD4006 is a 4-4-1-4-4-1 shift register */ + int p13 = BIT(noise_lfsra, 3); + int p12 = BIT(noise_lfsrb, 4); + int p10 = BIT(noise_lfsrc, 3); + int p8 = BIT(noise_lfsrd, 3); + + /* Update the register */ + noise_lfsra = p12 | ((noise_lfsra << 1) & 0xf); + noise_lfsrb = (p8 ^ p12) | ((noise_lfsrb << 1) & 0x1f); + noise_lfsrc = p13 | ((noise_lfsrc << 1) & 0xf); + noise_lfsrd = p10 | ((noise_lfsrd << 1) & 0x1f); + + /* 4040 12-bit counter is clocked on the falling edge of Q13 */ + if ( !BIT(noise_lfsrc, 3) && p10 ) + noise_counter = (noise_counter + 1) & 0x0fff; + } + + if (n1_en) + { + n1 = !BIT(noise_counter, 7-1) * 16000; + if ( BIT(noise_counter, 11-1) ) n1 /=2; + } + else + n1 = 8192; + + if (n2_en) + { + n2 = !BIT(noise_counter, 6-1) * 16000; + if ( BIT(noise_counter, 11-1) ) n2 /=2; + } + else + n2 = 8192; + + *fl++ = n1 + n2 + (pit0 * gain0) + (pit1 * gain1_l); + *fr++ = n1 + n2 + (pit0 * gain0) + (pit1 * gain1_r); + + step0 += step_0; + step1 += step_1; + } +} + +void *buggyboy_sh_start(int clock, const struct CustomSound_interface *config) +{ + static const int resistors[4] = { 330000, 220000, 330000, 220000 }; + double aweights[4]; + int i; + static const int tmp[16] = + { + 0x0, 0x1, 0xe, 0xf, 0x8, 0x9, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0x4, 0x5, 0x6, 0x7 + }; + + compute_resistor_weights(0, 16384, -1.0, + 4, &resistors[0], aweights, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ); + + for (i = 0; i < 16; i++) + buggyboy_eng_voltages[i] = combine_4_weights(aweights, BIT(tmp[i], 0), BIT(tmp[i], 1), BIT(tmp[i], 2), BIT(tmp[i], 3)); + + /* Allocate the stream */ + stream = stream_create(0, 2, Machine->sample_rate, NULL, buggyboy_stream_update); + + freq_to_step = (double)(1 << 24) / (double)Machine->sample_rate; + step0 = step1 = 0; + + return auto_malloc(1); +} + +void buggyboy_sh_reset(void *token) +{ + step0 = step1 = 0; + + /* Reset noise LFSR */ + noise_lfsra = 0; + noise_lfsrb = 1; + noise_lfsrc = 0; + noise_lfsrd = 0; +} + +void *tx1_sh_start(int clock, const struct CustomSound_interface *config) +{ + /* Allocate the stream */ + stream = stream_create(0, 2, Machine->sample_rate, NULL, tx1_stream_update); + + freq_to_step = (double)(1 << 24) / (double)Machine->sample_rate; + step0 = 0; + step1 = 0; + + return auto_malloc(1); +} + +void tx1_sh_reset(void *token) +{ +} diff --git a/src/mame/drivers/tx1.c b/src/mame/drivers/tx1.c index 73c8e16042c..729ab9ca813 100644 --- a/src/mame/drivers/tx1.c +++ b/src/mame/drivers/tx1.c @@ -1,269 +1,116 @@ -/*====================================================================*/ -/* TX-1/Buggy Boy (Tatsumi) Hardware */ -/* Philip J Bennett 2005 */ -/*====================================================================*/ +/*************************************************************************** -/* -Notes: -====== -TX-1 -==== -* ROM dumps incomplete. -* Arithmetic unit/interface not implemented. -* Several sound related things are guessed (I don't have the relevent schematic sheet or an actual PCB to verify). + Tatsumi TX-1/Buggy Boy hardware -Buggy Boy -========= -* Buggy Boy/Speed Buggy and the copyrights are changed via wire jumper on the sound PCB. -* Fiddle with dipswitch 'Do Not Change 2' to skip errors if necessary. -* The 3-monitor version of Buggy Boy is not fully dumped (will be taken care of). + driver by Phil Bennett -* Arithmetic unit/interface not fully implemented/understood. -* Road hardware emulation is lacking. -* Object drawing is not fully understood (scale parameters and end of line/sprite flags especially). -* Discrete sound emulation is not implemented. -* Character layer scrolling is not implemented. -* Layer mixing is incorrect. + Games supported: + * TX-1 (1983) [2 sets] + * Buggy Boy (1985) + * Buggy Boy Junior (1986) -* Buggy Boy controls don't work correctly. -* At some point the slave CPU writes F0 to EVERY 15th memory location. Hmmm. (see PC=fc630) -* Without ROM patches, the game hangs on bootup (sometimes giving error 22): Z80->8086 communication timeout. - The Z80<->Main CPU comms needs work (although they work fine during the game). + Notes: + * 'buggyboy' and 'tx1' are preliminary + * 'buggyboy' set is using ROMs from 'buggybjr' for testing purposes + until the original set can be dumped. + +**************************************************************************** -Useful memory locations: -* Score = 0x544 -* Timer = 0x54A + Buggy Boy Error Codes TX-1 Error Codes + ===================== ================ -Buggy Boy Error Codes TX-1 Error Codes -===================== ================ + 1 Main CPU RAM 1 Main microprocessor RAM + 2 Video (character) RAM 2 Video RAM + 3 Road/common RAM 3 Common RAM + 4 Sound RAM 4 Sound RAM + 5 Main CPU ROM 5 Main microprocessor ROM + 6 Sound ROM 6 Sound ROM + 8 Auxillary ROM 10 Interface ROM (time-out error) + 12 Arithmetic unit 11 Common RAM (access for arithmetic CPU) + 22 Main 8086-Z80 timeout 12 Common RAM (access for arithmetic CPU) + 13 Arithmetic RAM + 14 Common RAM (access for arithmetic CPU) + 15 Object RAM + 16 Arithmetic ROM + 17 Data ROM (checksum) + 18 Arithmetic unit -1. Main CPU RAM 1. Main microprocessor RAM -2. Video (character) RAM 2. Video RAM -3. Road/common RAM 3. Common RAM -4. Sound RAM 4. Sound RAM -5. Main CPU ROM 5. Main microprocessor ROM -6. Sound ROM 6. Sound ROM -8. Auxillary ROM 10. Interface ROM (time-out error) -12. Arithmetic unit 11. Common RAM (access for arithmetic CPU) -22. Main 8086-Z80 timeout 12. Common RAM (access for arithmetic CPU) - 13. Arithmetic RAM - 14. Common RAM (access for arithmetic CPU) - 15. Object RAM - 16. Arithmetic ROM - 17. Data ROM (Checksum) - 18. Arithmetic unit -*/ +***************************************************************************/ #include "driver.h" -#include "machine/8255ppi.h" #include "sound/ay8910.h" +#include "sound/custom.h" #include "cpu/i86/i86.h" #include "rendlay.h" +#include "tx1.h" -#define PRINT_CRT 0 -#define ROM_PATCHES 1 - -static int TS, z80_int = 0; - -UINT16 *tx1_vram; -static UINT16 *tx1_object_ram; - -UINT16 *buggyboy_vram; /* Tile RAM (three monitor) */ -UINT16 *buggyb1_vram; /* Tile RAM (single monitor) */ -static UINT8 *z80_ram; /* Main 8086/Z80 shared RAM */ -UINT16 *bb_objram; -UINT16 *bb_sky; /* Sky register */ -static UINT16 *bb_rcram; - -static size_t tx1_objectram_size; -size_t bb_objectram_size; -static size_t bb_rcram_size; - -tilemap *tx1_tilemap; -tilemap *buggyboy_tilemap; -tilemap *buggyb1_tilemap; - -/* machine/tx1.c */ -void MMI_74S516(int ins, UINT16 *data); -READ16_HANDLER( BB_AU_R ); -WRITE16_HANDLER( BB_AU_W ); - -/* video/tx1.c */ -WRITE16_HANDLER( tx1_vram_w ); -VIDEO_START( tx1 ); -VIDEO_UPDATE( tx1 ); - -PALETTE_INIT( buggyboy ); -WRITE16_HANDLER( buggyboy_vram_w ); -WRITE16_HANDLER( buggyb1_vram_w ); -VIDEO_START( buggyboy ); -VIDEO_UPDATE( buggyboy ); -VIDEO_START( buggyb1 ); -VIDEO_UPDATE( buggyb1 ); +/************************************* + * + * Globals + * + *************************************/ +UINT16 *tx1_math_ram; +static UINT8 *z80_ram; +static UINT8 tx1_ppi_latch_a; +static UINT8 tx1_ppi_latch_b; +static UINT32 ts; -static INTERRUPT_GEN( main_irq ) +/* Main CPU and Z80 synchronisation */ +static WRITE16_HANDLER( z80_busreq_w ) { - cpunum_set_input_line_and_vector(0, 0, HOLD_LINE, 0x80/4); + cpunum_set_input_line(2, INPUT_LINE_HALT, (data & 1) ? CLEAR_LINE : ASSERT_LINE); +} + +static WRITE16_HANDLER( resume_math_w ) +{ + cpunum_set_input_line(1, INPUT_LINE_TEST, ASSERT_LINE); +} + +static WRITE16_HANDLER( halt_math_w ) +{ + cpunum_set_input_line(1, INPUT_LINE_TEST, CLEAR_LINE); +} + +/* Z80 can trigger an interrupt itself */ +static WRITE8_HANDLER( z80_intreq_w ) +{ + cpunum_set_input_line(2, 0, HOLD_LINE); } /* Periodic Z80 interrupt */ static INTERRUPT_GEN( z80_irq ) { - if(!z80_int){ - cpunum_set_input_line(2, 0, HOLD_LINE); - z80_int = 1; - } + cpunum_set_input_line(2, 0, HOLD_LINE); } - -/* HD46505S-2 CRT Controller */ -/* Buggy Boy: The main 8086 at F003C expects non-zero value or else jump to 4000:0000 and execute crap */ -static READ16_HANDLER(crt_read) +static READ16_HANDLER( z80_shared_r ) { - return 1; + UINT16 result = 0xffff; + + cpuintrf_push_context(2); + result = program_read_byte(offset); + cpuintrf_pop_context(); + + return result; } -/* Remove this eventually */ -static WRITE16_HANDLER(crt_write) +static WRITE16_HANDLER( z80_shared_w ) { -#if PRINT_CRT - if (ACCESSING_LSB) - { - data &= 0xff; - if(offset==0) - { - switch (data) - { - case 0:mame_printf_debug("Horizontal Total"); - break; - case 1:mame_printf_debug("Horizontal displayed"); - break; - case 2:mame_printf_debug("Horizontal sync position"); - break; - case 3:mame_printf_debug("Horizontal sync width"); - break; - case 4:mame_printf_debug("Vertical total"); - break; - case 5:mame_printf_debug("Vertical total adj"); - break; - case 6:mame_printf_debug("Vertical displayed"); - break; - case 7:mame_printf_debug("Vertical sync position"); - break; - case 8:mame_printf_debug("Interlace mode"); - break; - case 9:mame_printf_debug("Max. scan line address"); - break; - case 0xa:mame_printf_debug("Cursror start"); - break; - case 0xb:mame_printf_debug("Cursor end"); - break; - case 0xc:mame_printf_debug("Start address (h)"); - break; - case 0xd:mame_printf_debug("Start address (l)"); - break; - case 0xe:mame_printf_debug("Cursor (h)"); - break; - case 0xf:mame_printf_debug("Cursor (l)"); - break; - case 0x10:mame_printf_debug("Light pen (h))"); - break; - case 0x11:mame_printf_debug("Light pen (l)"); - break; - } - } - if(offset==1) mame_printf_debug("= 0x%x, %d\n",data,data); - } -#endif + cpuintrf_push_context(2); + program_write_byte(offset, data & 0xff); + cpuintrf_pop_context(); } -/* Main CPU and Z80 synchronisation*/ -static WRITE16_HANDLER(z80_busreq) -{ - if (ACCESSING_LSB) - { - if (data & 0xff) - cpunum_set_input_line(2, INPUT_LINE_HALT, CLEAR_LINE); - else - cpunum_set_input_line(2, INPUT_LINE_HALT, ASSERT_LINE); - } -} +/************************************* + * + * Port definitions + * + *************************************/ - -/* Called by main 8086 to wake up slave */ -static WRITE16_HANDLER(resume_slave) -{ - cpunum_set_input_line(1, INPUT_LINE_TEST, ASSERT_LINE); -} - -static READ16_HANDLER(halt_slave_r) -{ - cpunum_set_input_line(1, INPUT_LINE_TEST, CLEAR_LINE); - return 0; -} - -/* Called by slave 8086 to halt on WAIT instruction */ -static void halt_slave(void) -{ - cpunum_set_input_line(1, INPUT_LINE_TEST, CLEAR_LINE); -} - - -static WRITE8_HANDLER(z80_intreq_w) -{ - z80_int=0; -} - -static READ8_HANDLER(z80_intreq_r) -{ - z80_int=0; - return 0; -} - - -/* Handlers for main CPU<->Z80 RAM */ -static READ16_HANDLER(z80_shared_r) -{ - return z80_ram[offset]; -} - -static WRITE16_HANDLER(z80_shared_w) -{ - if (ACCESSING_LSB) - z80_ram[offset] = data; -} - -static INPUT_PORTS_START( tx1 ) - PORT_START_TAG("DSW1") - PORT_DIPNAME( 0x0700, 0x0300, DEF_STR( Difficulty ) ) - PORT_DIPSETTING( 0x0000, "A" ) - PORT_DIPSETTING( 0x0100, "B" ) - PORT_DIPSETTING( 0x0200, "C" ) - PORT_DIPSETTING( 0x0300, "D" ) - PORT_DIPSETTING( 0x0400, "E" ) - PORT_DIPSETTING( 0x0500, "F" ) - PORT_DIPSETTING( 0x0600, "G" ) - PORT_DIPSETTING( 0x0700, "H" ) - - PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Game_Time ) ) - PORT_DIPSETTING( 0x0000, "A" ) - PORT_DIPSETTING( 0x0800, "B" ) - PORT_DIPSETTING( 0x1000, "C" ) - PORT_DIPSETTING( 0x1800, "D" ) - - PORT_DIPNAME( 0xe000, 0xe000, "Bonus Adder" ) - PORT_DIPSETTING( 0x0000, "No Bonus" ) - PORT_DIPSETTING( 0x2000, "2 Coin Units for 1 Credit" ) - PORT_DIPSETTING( 0x4000, "3 Coin Units for 1 Credit" ) - PORT_DIPSETTING( 0x6000, "4 Coin Units for 1 Credit" ) - PORT_DIPSETTING( 0x8000, "5 Coin Units for 1 Credit" ) - PORT_DIPSETTING( 0xa000, "4 Coin Units for 2 Credit" ) - PORT_DIPSETTING( 0xc000, DEF_STR( Free_Play ) ) - PORT_DIPSETTING( 0xe000, "No Bonus" ) - - /* These don't correspond to the Atari manual :( */ +INPUT_PORTS_START( tx1 ) +PORT_START_TAG("DSW") PORT_DIPNAME( 0x0003, 0x0003, "Game Cost" ) PORT_DIPSETTING( 0x0000, "1 Coin Unit for 1 Credit" ) PORT_DIPSETTING( 0x0001, "2 Coin Units for 1 Credit" ) @@ -271,246 +118,318 @@ static INPUT_PORTS_START( tx1 ) PORT_DIPSETTING( 0x0003, "4 Coin Units for 1 Credit" ) PORT_DIPNAME( 0x0004, 0x0004, "Left Coin Mechanism" ) - PORT_DIPSETTING( 0x0000, "1 Coin for 1 Coin Unit" ) - PORT_DIPSETTING( 0x0004, "1 Coin for 2 Coin Units" ) + PORT_DIPSETTING( 0x0000, "1 Coin for 1 Coin Unit" ) + PORT_DIPSETTING( 0x0004, "1 Coin for 2 Coin Units" ) PORT_DIPNAME( 0x0018, 0x0000, "Right Coin Mechanism" ) - PORT_DIPSETTING( 0x0000, "1 Coin Units 1 Credit" ) - PORT_DIPSETTING( 0x0008, "1 Coin Units 4 Credit" ) - PORT_DIPSETTING( 0x0010, "1 Coin Units 5 Credit" ) - PORT_DIPSETTING( 0x0018, "1 Coin Unit 6 Credit" ) + PORT_DIPSETTING( 0x0000, "1 Coin Units 1 Credit" ) + PORT_DIPSETTING( 0x0008, "1 Coin Units 4 Credit" ) + PORT_DIPSETTING( 0x0010, "1 Coin Units 5 Credit" ) + PORT_DIPSETTING( 0x0018, "1 Coin Unit 6 Credit" ) - PORT_START_TAG("ANALOG_A") - PORT_BIT( 0x000f, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Accelerator */ - PORT_BIT( 0xf0, 0x10, IPT_PEDAL ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(2) /* Brake */ - PORT_START_TAG("ANALOG_B") - PORT_BIT( 0x0f, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Steering */ - /* Wire jumper setting on sound PCB */ - PORT_DIPNAME( 0xf0, 0x80, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x10, "1" ) - PORT_DIPSETTING( 0x20, "2" ) - PORT_DIPSETTING( 0x40, "3" ) - PORT_DIPSETTING( 0x80, "4" ) + PORT_DIPNAME( 0x0700, 0x0300, DEF_STR( Difficulty ) ) + PORT_DIPSETTING( 0x0000, "A (Easiest)" ) + PORT_DIPSETTING( 0x0100, "B" ) + PORT_DIPSETTING( 0x0200, "C" ) + PORT_DIPSETTING( 0x0300, "D" ) + PORT_DIPSETTING( 0x0400, "E" ) + PORT_DIPSETTING( 0x0500, "F" ) + PORT_DIPSETTING( 0x0600, "G" ) + PORT_DIPSETTING( 0x0700, "H (Hardest)" ) - PORT_START_TAG("INPUTS") + PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Game_Time ) ) + PORT_DIPSETTING( 0x0000, "A (Longest)" ) + PORT_DIPSETTING( 0x0800, "B" ) + PORT_DIPSETTING( 0x1000, "C" ) + PORT_DIPSETTING( 0x1800, "D (Shortest)" ) + + PORT_DIPNAME( 0xe000, 0xe000, "Bonus Adder" ) + PORT_DIPSETTING( 0x0000, "No Bonus" ) + PORT_DIPSETTING( 0x2000, "2 Coin Units for 1 Credit" ) + PORT_DIPSETTING( 0x4000, "3 Coin Units for 1 Credit" ) + PORT_DIPSETTING( 0x6000, "4 Coin Units for 1 Credit" ) + PORT_DIPSETTING( 0x8000, "5 Coin Units for 1 Credit" ) + PORT_DIPSETTING( 0xa000, "4 Coin Units for 2 Credit" ) + PORT_DIPSETTING( 0xc000, DEF_STR( Free_Play ) ) + PORT_DIPSETTING( 0xe000, "No Bonus" ) + +PORT_START_TAG("AN_STEERING") + PORT_BIT( 0x0f, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) + +PORT_START_TAG("AN_ACCELERATOR") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) + +PORT_START_TAG("AN_BRAKE") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) + +PORT_START_TAG("PPI_PORTC") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE -INPUT_PORTS_END - - -static INPUT_PORTS_START( buggyboy ) - PORT_START_TAG("DSW1") - PORT_DIPNAME( 0xe000, 0x0000, DEF_STR( Coin_A ) ) - PORT_DIPSETTING( 0x4000, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x2000, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0xc000, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x6000, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x8000, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0xa000, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0xe000, "Free-Play" ) - - PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Coin_B ) ) - PORT_DIPSETTING( 0x0800, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x1800, DEF_STR( 1C_5C ) ) - - PORT_DIPNAME( 0x0700, 0x0700, "Do not change 1" ) - PORT_DIPSETTING( 0x0000, "0" ) - PORT_DIPSETTING( 0x0100, "1" ) - PORT_DIPSETTING( 0x0200, "2" ) - PORT_DIPSETTING( 0x0300, "3" ) - PORT_DIPSETTING( 0x0400, "4" ) - PORT_DIPSETTING( 0x0500, "5" ) - PORT_DIPSETTING( 0x0600, "6" ) - PORT_DIPSETTING( 0x0700, "7" ) - - PORT_DIPNAME( 0x0003, 0x0003, "Do not change 2" ) /* Dipswitch 0 is unconnected */ - PORT_DIPSETTING( 0x0000, "0" ) - PORT_DIPSETTING( 0x0001, "1" ) - PORT_DIPSETTING( 0x0002, "2" ) - PORT_DIPSETTING( 0x0003, "3" ) - - PORT_DIPNAME( 0x0004, 0x0004, "Message" ) - PORT_DIPSETTING( 0x0004, DEF_STR( English ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Japanese ) ) - - PORT_DIPNAME( 0x0008, 0x0008, "Do not Change 3" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0008, DEF_STR( On ) ) - - PORT_DIPNAME( 0x0030, 0x0030, "Time Rank" ) - PORT_DIPSETTING( 0x0000, "A" ) - PORT_DIPSETTING( 0x0010, "B" ) - PORT_DIPSETTING( 0x0020, "C" ) - PORT_DIPSETTING( 0x0030, "D" ) - - PORT_DIPNAME( 0x00c0, 0x0040, "Game Rank" ) - PORT_DIPSETTING( 0x0000, "A") - PORT_DIPSETTING( 0x0040, "B" ) - PORT_DIPSETTING( 0x0080, "C" ) - PORT_DIPSETTING( 0x00c0, "D" ) - - PORT_START_TAG("YM2149_IC19_A") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE /* Gear shift */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE - - - /* Read by 8255 I think */ - PORT_START_TAG("YM2149_IC19_B") - PORT_DIPNAME( 0xff, 0x80, "Sound PCB Jumper:" ) - PORT_DIPSETTING( 0x00, "0" ) - PORT_DIPSETTING( 0x01, "1" ) - PORT_DIPSETTING( 0x02, "2" ) - PORT_DIPSETTING( 0x04, "3" ) - PORT_DIPSETTING( 0x08, "4" ) - PORT_DIPSETTING( 0x10, "5" ) - PORT_DIPSETTING( 0x20, "Speed Buggy/Data East" ) - PORT_DIPSETTING( 0x40, "Buggy Boy/Taito" ) - PORT_DIPSETTING( 0x80, "Buggy Boy/Tatsumi" ) - - /* Fix me */ - PORT_START_TAG("ANALOG_A") - PORT_BIT( 0x0f, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Accelerator */ - PORT_BIT( 0xf0, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Steering */ - PORT_START_TAG("ANALOG_B") - PORT_BIT( 0xf0, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(2) /* Brake */ - -INPUT_PORTS_END - -static INPUT_PORTS_START( buggyb1 ) - PORT_START_TAG("DSW1") - PORT_DIPNAME( 0xe000, 0x0000, DEF_STR( Coin_A ) ) - PORT_DIPSETTING( 0x4000, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x2000, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0xc000, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x6000, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x8000, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0xa000, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0xe000, "Free-Play" ) - - PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Coin_B ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x0800, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x1800, DEF_STR( 1C_6C ) ) - - PORT_DIPNAME( 0x0700, 0x0700, "Do not change 1" ) - PORT_DIPSETTING( 0x0000, "0" ) - PORT_DIPSETTING( 0x0100, "1" ) - PORT_DIPSETTING( 0x0200, "2" ) - PORT_DIPSETTING( 0x0300, "3" ) - PORT_DIPSETTING( 0x0400, "4" ) - PORT_DIPSETTING( 0x0500, "5" ) - PORT_DIPSETTING( 0x0600, "6" ) - PORT_DIPSETTING( 0x0700, "7" ) - - PORT_DIPNAME( 0x0003, 0x0003, "Do not change 2" ) /* Dipswitch 0 is unconnected */ - PORT_DIPSETTING( 0x0000, "0" ) - PORT_DIPSETTING( 0x0001, "1" ) - PORT_DIPSETTING( 0x0002, "2" ) - PORT_DIPSETTING( 0x0003, "3" ) - - PORT_DIPNAME( 0x0004, 0x0004, "Message" ) - PORT_DIPSETTING( 0x0004, DEF_STR( English ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Japanese ) ) - - PORT_DIPNAME( 0x0008, 0x0008, "Do not Change 3" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0008, DEF_STR( On ) ) - - PORT_DIPNAME( 0x0030, 0x0030, "Time Rank" ) - PORT_DIPSETTING( 0x0000, "A" ) - PORT_DIPSETTING( 0x0010, "B" ) - PORT_DIPSETTING( 0x0020, "C" ) - PORT_DIPSETTING( 0x0030, "D" ) - - PORT_DIPNAME( 0x00c0, 0x0040, "Game Rank" ) - PORT_DIPSETTING( 0x0000, "A") - PORT_DIPSETTING( 0x0040, "B" ) - PORT_DIPSETTING( 0x0080, "C" ) - PORT_DIPSETTING( 0x00c0, "D" ) - - PORT_START_TAG("YM2149_IC19_A") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE /* Gear shift */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE +PORT_START_TAG("PPI_PORTD") /* Wire jumper setting on sound PCB */ - PORT_START_TAG("YM2149_IC19_B") - PORT_DIPNAME( 0xff, 0x80, "Sound PCB Jumper:" ) - PORT_DIPSETTING( 0x00, "0" ) - PORT_DIPSETTING( 0x01, "1" ) - PORT_DIPSETTING( 0x02, "2" ) - PORT_DIPSETTING( 0x04, "3" ) - PORT_DIPSETTING( 0x08, "4" ) - PORT_DIPSETTING( 0x10, "5" ) - PORT_DIPSETTING( 0x20, "Speed Buggy/Data East" ) - PORT_DIPSETTING( 0x40, "Buggy Boy/Taito" ) - PORT_DIPSETTING( 0x80, "Buggy Boy/Tatsumi" ) - - PORT_START_TAG("ANALOG_A") - PORT_BIT( 0x0f, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Steering */ - PORT_BIT( 0xf0, 0x10, IPT_PEDAL ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) /* Accelerator */ - PORT_START_TAG("ANALOG_B") - PORT_BIT( 0xf0, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(2) /* Brake */ + PORT_DIPNAME( 0xf0, 0x80, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x10, "1" ) + PORT_DIPSETTING( 0x20, "2" ) + PORT_DIPSETTING( 0x40, "3" ) + PORT_DIPSETTING( 0x80, "4" ) INPUT_PORTS_END -/********************/ -/* TX-1 Memory Maps */ -/********************/ -static ADDRESS_MAP_START( tx1_master, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x00fff) AM_MIRROR(0x1000) AM_RAM /* RAM */ - AM_RANGE(0x02000, 0x02fff) AM_MIRROR(0x1000) AM_RAM /* RAM */ - AM_RANGE(0x04000, 0x04fff) AM_MIRROR(0x1000) AM_RAM /* Backup RAM */ - AM_RANGE(0x06000, 0x06009) AM_READWRITE(crt_read, crt_write) - AM_RANGE(0x08000, 0x09fff) AM_READWRITE(MRA16_RAM,tx1_vram_w) AM_BASE(&tx1_vram) - AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) /* Road/common RAM */ - AM_RANGE(0x0b000, 0x0b001) AM_READWRITE (input_port_0_word_r, z80_busreq) - AM_RANGE(0x0c000, 0x0c001) AM_RAM /* /SCOLST */ - AM_RANGE(0x0d000, 0x0d001) AM_RAM /* /SLINCS */ - AM_RANGE(0x0e000, 0x0e001) AM_RAM /* /SLOCK */ - AM_RANGE(0x0f000, 0x0f003) AM_READWRITE (MRA16_NOP, resume_slave) /* Watchdog and slave resume */ - AM_RANGE(0x10000, 0x13fff) AM_ROM /* Z80 ROM */ - AM_RANGE(0x16000, 0x16fff) AM_READWRITE (z80_shared_r, z80_shared_w) +INPUT_PORTS_START( buggyboy ) +PORT_START_TAG("DSW") + /* Dipswitch 0 is unconnected */ + PORT_DIPNAME( 0x0003, 0x0003, "Do not change 2" ) + PORT_DIPSETTING( 0x0000, "0" ) + PORT_DIPSETTING( 0x0001, "1" ) + PORT_DIPSETTING( 0x0002, "2" ) + PORT_DIPSETTING( 0x0003, "3" ) + + PORT_DIPNAME( 0x0004, 0x0004, "Message" ) + PORT_DIPSETTING( 0x0004, DEF_STR( English ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Japanese ) ) + + PORT_DIPNAME( 0x0008, 0x0008, "Do not Change 3" ) + PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( On ) ) + + PORT_DIPNAME( 0x0030, 0x0030, "Time Rank" ) + PORT_DIPSETTING( 0x0000, "A (Short)" ) + PORT_DIPSETTING( 0x0010, "B" ) + PORT_DIPSETTING( 0x0020, "C" ) + PORT_DIPSETTING( 0x0030, "D (Long)" ) + + PORT_DIPNAME( 0x00c0, 0x0040, "Game Rank" ) + PORT_DIPSETTING( 0x0000, "A (Easy)") + PORT_DIPSETTING( 0x0040, "B" ) + PORT_DIPSETTING( 0x0080, "C" ) + PORT_DIPSETTING( 0x00c0, "D (Difficult)" ) + + PORT_DIPNAME( 0xe000, 0x0000, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0xc000, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x6000, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0xa000, DEF_STR( 1C_6C ) ) + PORT_DIPSETTING( 0xe000, "Free-Play" ) + + PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Coin_B ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x1800, DEF_STR( 1C_5C ) ) + + PORT_DIPNAME( 0x0700, 0x0700, "Do not change 1" ) + PORT_DIPSETTING( 0x0000, "0" ) + PORT_DIPSETTING( 0x0100, "1" ) + PORT_DIPSETTING( 0x0200, "2" ) + PORT_DIPSETTING( 0x0300, "3" ) + PORT_DIPSETTING( 0x0400, "4" ) + PORT_DIPSETTING( 0x0500, "5" ) + PORT_DIPSETTING( 0x0600, "6" ) + PORT_DIPSETTING( 0x0700, "7" ) + +PORT_START_TAG("PPI_PORTA") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE + +PORT_START_TAG("PPI_PORTC") + PORT_DIPNAME( 0xff, 0x80, "Sound PCB Jumper:" ) + PORT_DIPSETTING( 0x00, "0" ) + PORT_DIPSETTING( 0x01, "1" ) + PORT_DIPSETTING( 0x02, "2" ) + PORT_DIPSETTING( 0x04, "3" ) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x10, "5" ) + PORT_DIPSETTING( 0x20, "Speed Buggy/Data East" ) + PORT_DIPSETTING( 0x40, "Buggy Boy/Taito" ) + PORT_DIPSETTING( 0x80, "Buggy Boy/Tatsumi" ) + +PORT_START_TAG("AN_STEERING") + PORT_BIT( 0x0f, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) + +PORT_START_TAG("AN_ACCELERATOR") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) + +PORT_START_TAG("AN_BRAKE") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) +INPUT_PORTS_END + +INPUT_PORTS_START( buggybjr ) +PORT_START_TAG("DSW") + /* Dipswitch 0 is unconnected */ + PORT_DIPNAME( 0x0003, 0x0003, "Do not change 2" ) + PORT_DIPSETTING( 0x0000, "0" ) + PORT_DIPSETTING( 0x0001, "1" ) + PORT_DIPSETTING( 0x0002, "2" ) + PORT_DIPSETTING( 0x0003, "3" ) + + PORT_DIPNAME( 0x0004, 0x0004, "Message" ) + PORT_DIPSETTING( 0x0004, DEF_STR( English ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Japanese ) ) + + PORT_DIPNAME( 0x0008, 0x0008, "Do not Change 3" ) + PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( On ) ) + + PORT_DIPNAME( 0x0030, 0x0030, "Time Rank" ) + PORT_DIPSETTING( 0x0000, "A (Short)" ) + PORT_DIPSETTING( 0x0010, "B" ) + PORT_DIPSETTING( 0x0020, "C" ) + PORT_DIPSETTING( 0x0030, "D (Long)" ) + + PORT_DIPNAME( 0x00c0, 0x0040, "Game Rank" ) + PORT_DIPSETTING( 0x0000, "A (Easy)") + PORT_DIPSETTING( 0x0040, "B" ) + PORT_DIPSETTING( 0x0080, "C" ) + PORT_DIPSETTING( 0x00c0, "D (Difficult)" ) + + PORT_DIPNAME( 0xe000, 0x0000, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0xc000, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x6000, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0xa000, DEF_STR( 1C_6C ) ) + PORT_DIPSETTING( 0xe000, "Free-Play" ) + + PORT_DIPNAME( 0x1800, 0x0800, DEF_STR( Coin_B ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0x1800, DEF_STR( 1C_6C ) ) + + PORT_DIPNAME( 0x0700, 0x0700, "Do not change 1" ) + PORT_DIPSETTING( 0x0000, "0" ) + PORT_DIPSETTING( 0x0100, "1" ) + PORT_DIPSETTING( 0x0200, "2" ) + PORT_DIPSETTING( 0x0300, "3" ) + PORT_DIPSETTING( 0x0400, "4" ) + PORT_DIPSETTING( 0x0500, "5" ) + PORT_DIPSETTING( 0x0600, "6" ) + PORT_DIPSETTING( 0x0700, "7" ) + +PORT_START_TAG("YM2149_IC19_A") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE + +/* Wire jumper setting on sound PCB */ +PORT_START_TAG("YM2149_IC19_B") + PORT_DIPNAME( 0xff, 0x80, "Sound PCB Jumper:" ) + PORT_DIPSETTING( 0x00, "0" ) + PORT_DIPSETTING( 0x01, "1" ) + PORT_DIPSETTING( 0x02, "2" ) + PORT_DIPSETTING( 0x04, "3" ) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x10, "5" ) + PORT_DIPSETTING( 0x20, "Speed Buggy/Data East" ) + PORT_DIPSETTING( 0x40, "Buggy Boy/Taito" ) + PORT_DIPSETTING( 0x80, "Buggy Boy/Tatsumi" ) + +PORT_START_TAG("AN_STEERING") + PORT_BIT( 0x0f, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) + +PORT_START_TAG("AN_ACCELERATOR") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) + +PORT_START_TAG("AN_BRAKE") + PORT_BIT( 0x1f, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0x1f) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) +INPUT_PORTS_END + +static READ16_HANDLER( dipswitches_r ) +{ + return (readinputport(0) & 0xfffe) | ts; +} + +/* + (TODO) TS: Connected in place of dipswitch A bit 0 + Accessed on startup as some sort of acknowledgement +*/ +static WRITE8_HANDLER( ts_w ) +{ +// TS = 1; + z80_ram[offset] = data; +} + +static READ8_HANDLER( ts_r ) +{ +// TS = 1; + return z80_ram[offset]; +} + +/************************************* + * + * TX-1 Memory Maps + * + *************************************/ + +static ADDRESS_MAP_START( tx1_main, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x00000, 0x00fff) AM_MIRROR(0x1000) AM_RAM + AM_RANGE(0x02000, 0x02fff) AM_MIRROR(0x1000) AM_RAM + AM_RANGE(0x04000, 0x04fff) AM_MIRROR(0x1000) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size) + AM_RANGE(0x06000, 0x06fff) AM_READWRITE(tx1_crtc_r, tx1_crtc_w) + AM_RANGE(0x08000, 0x09fff) AM_READWRITE(MRA16_RAM, tx1_vram_w) AM_BASE(&tx1_vram) + AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) AM_BASE(&tx1_rcram) + AM_RANGE(0x0b000, 0x0b001) AM_READWRITE(dipswitches_r, z80_busreq_w) + AM_RANGE(0x0c000, 0x0c001) AM_WRITE(tx1_scolst_w) + AM_RANGE(0x0d000, 0x0d003) AM_WRITE(tx1_slincs_w) + AM_RANGE(0x0e000, 0x0e001) AM_WRITE(tx1_slock_w) + AM_RANGE(0x0f000, 0x0f001) AM_READWRITE(watchdog_reset16_r, resume_math_w) + AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(z80_shared_r, z80_shared_w) AM_RANGE(0xf0000, 0xfffff) AM_ROM ADDRESS_MAP_END -/* Lot of unknown writes - I haven't investigated further */ -static ADDRESS_MAP_START( tx1_slave, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x007ff) AM_MIRROR(0x800) AM_RAM /* Arithmetic RAM (IC169, IC158) A10 is grounded */ - AM_RANGE(0x01000, 0x01fff) AM_RAM AM_SHARE(1) /* Common RAM (IC195, IC210) */ - AM_RANGE(0x02000, 0x022ff) AM_RAM AM_BASE(&tx1_object_ram) AM_SIZE(&tx1_objectram_size) /* Object RAM (IC43, IC68) A10-A8 are grounded*/ - AM_RANGE(0x02400, 0x027ff) AM_RAM /* /BANKCS */ - AM_RANGE(0x02800, 0x02bff) AM_READWRITE(halt_slave_r, MWA16_NOP) /* /DRAK */ - AM_RANGE(0x02C00, 0x02fff) AM_RAM /* /FLGCS */ - AM_RANGE(0x03000, 0x03fff) AM_RAM /* SN74S516 arithmetic unit */ - AM_RANGE(0x04000, 0x07fff) AM_ROM /* ROM mirror? */ - AM_RANGE(0x08000, 0x0bfff) AM_ROM /* ROM mirror? */ - AM_RANGE(0x0c000, 0x0ffff) AM_ROM /* ROM mirror? */ +static ADDRESS_MAP_START( tx1_math, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x00000, 0x007ff) AM_RAM AM_BASE(&tx1_math_ram) + AM_RANGE(0x00800, 0x00fff) AM_READWRITE(tx1_spcs_ram_r, tx1_spcs_ram_w) + AM_RANGE(0x01000, 0x01fff) AM_RAM AM_SHARE(1) + AM_RANGE(0x02000, 0x022ff) AM_RAM AM_BASE(&tx1_objram) AM_SIZE(&tx1_objram_size) + AM_RANGE(0x02400, 0x027ff) AM_WRITE(tx1_bankcs_w) + AM_RANGE(0x02800, 0x02bff) AM_WRITE(halt_math_w) + AM_RANGE(0x02C00, 0x02fff) AM_WRITE(tx1_flgcs_w) + AM_RANGE(0x03000, 0x03fff) AM_READWRITE(tx1_math_r, tx1_math_w) + AM_RANGE(0x05000, 0x07fff) AM_READ(tx1_spcs_rom_r) + AM_RANGE(0x08000, 0x0bfff) AM_ROM + AM_RANGE(0x0c000, 0x0ffff) AM_ROM AM_RANGE(0xfc000, 0xfffff) AM_ROM ADDRESS_MAP_END -/* Sound */ +static WRITE8_HANDLER( tx1_ppi_latch_w ) +{ + tx1_ppi_latch_a = ((readinputportbytag("AN_ACCELERATOR") & 0xf) << 4) | (readinputportbytag("AN_BRAKE") & 0xf); + tx1_ppi_latch_b = readinputportbytag("AN_STEERING"); +} + +static READ8_HANDLER( tx1_ppi_porta_r ) +{ + return tx1_ppi_latch_a; +} + +static READ8_HANDLER( tx1_ppi_portb_r ) +{ + return readinputportbytag("PPI_PORTD") | tx1_ppi_latch_b; +} + static ADDRESS_MAP_START( tx1_sound_prg, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x3000, 0x37ff) AM_RAM AM_MIRROR(0x800) AM_BASE (&z80_ram) - AM_RANGE(0x4000, 0x4000) AM_READ (z80_intreq_r) /* Unconfirmed */ + AM_RANGE(0x3000, 0x37ff) AM_RAM AM_MIRROR(0x800) AM_BASE(&z80_ram) + AM_RANGE(0x4000, 0x4000) AM_WRITE(z80_intreq_w) AM_RANGE(0x5000, 0x5003) AM_READWRITE(ppi8255_0_r, ppi8255_0_w) - AM_RANGE(0x6000, 0x6003) AM_RAM /* 8253A PIT */ - AM_RANGE(0x7000, 0x70DF) AM_RAM /* Propigate input signals into 8255 */ - AM_RANGE(0xb00b, 0xb00b) AM_RAM /* Read once - TS?*/ + AM_RANGE(0x6000, 0x6003) AM_READWRITE(pit8253_r, pit8253_w) + AM_RANGE(0x7000, 0x7fff) AM_WRITE(tx1_ppi_latch_w) + AM_RANGE(0xb000, 0xbfff) AM_READWRITE(ts_r, ts_w) ADDRESS_MAP_END @@ -521,159 +440,119 @@ static ADDRESS_MAP_START( tx1_sound_io, ADDRESS_SPACE_IO, 8 ) ADDRESS_MAP_END -/*************************/ -/* Buggy Boy Memory Maps */ -/*************************/ +/************************************* + * + * Buggy Boy Memory Maps + * + *************************************/ -static READ16_HANDLER(input_port_0A_r) -{ - return (readinputport(0) & 0xfffe) | TS; -} - -static ADDRESS_MAP_START( buggyb1_master, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x03fff) AM_RAM /* 1kB RAM - battery backed */ - AM_RANGE(0x04000, 0x04fff) AM_READWRITE(crt_read, crt_write) /* HD46505S-2 or equivalent CRT controller */ - AM_RANGE(0x08000, 0x08fff) AM_READWRITE(MRA16_RAM,buggyb1_vram_w) AM_BASE(&buggyb1_vram) /* Character mapped RAM */ - AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) AM_BASE(&bb_rcram) AM_SIZE(&bb_rcram_size) /* Road/common RAM - 1800-18ff & 1c00-1cff are read by road H/W */ - AM_RANGE(0x0b000, 0x0b001) AM_READWRITE (input_port_0A_r, z80_busreq) /* Dipswitches and Z80 busreq */ - AM_RANGE(0x0c000, 0x0c001) AM_RAM /* /SCOLW */ - AM_RANGE(0x0d000, 0x0d003) AM_RAM /* /SLINCS */ - AM_RANGE(0x0e000, 0x0e001) AM_RAM AM_BASE(&bb_sky) /* /SKYCS */ - AM_RANGE(0x0f000, 0x0f003) AM_READWRITE (MRA16_NOP, resume_slave) /* Watchdog and slave resume */ - AM_RANGE(0x10000, 0x17fff) AM_ROM /* Z80 ROM */ - AM_RANGE(0x18000, 0x18fff) AM_READWRITE (z80_shared_r, z80_shared_w) +static ADDRESS_MAP_START( buggyboy_main, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x00000, 0x03fff) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size) + AM_RANGE(0x04000, 0x04fff) AM_READWRITE(tx1_crtc_r, tx1_crtc_w) + AM_RANGE(0x08000, 0x09fff) AM_READWRITE(MRA16_RAM, buggyboy_vram_w) AM_BASE(&buggyboy_vram) + AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) AM_BASE(&buggyboy_rcram) AM_SIZE(&buggyboy_rcram_size) + AM_RANGE(0x0b000, 0x0b001) AM_READWRITE(dipswitches_r, z80_busreq_w) + AM_RANGE(0x0c000, 0x0c001) AM_WRITE(buggyboy_scolst_w) + AM_RANGE(0x0d000, 0x0d003) AM_WRITE(buggyboy_slincs_w) + AM_RANGE(0x0e000, 0x0e001) AM_WRITE(buggyboy_sky_w) + AM_RANGE(0x0f000, 0x0f003) AM_READWRITE(watchdog_reset16_r, resume_math_w) + AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(z80_shared_r, z80_shared_w) AM_RANGE(0x20000, 0x2ffff) AM_ROM AM_RANGE(0xf0000, 0xfffff) AM_ROM ADDRESS_MAP_END - -static ADDRESS_MAP_START( buggyboy_master, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x03fff) AM_RAM /* 1kB RAM - battery backed */ - AM_RANGE(0x04000, 0x04fff) AM_READWRITE(crt_read, crt_write) /* HD46505S-2 or equivalent CRT controller */ - AM_RANGE(0x08000, 0x09fff) AM_READWRITE(MRA16_RAM,buggyboy_vram_w) AM_BASE(&buggyboy_vram) /* Character mapped RAM */ - AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) AM_BASE(&bb_rcram) AM_SIZE(&bb_rcram_size) /* Road/common RAM */ - AM_RANGE(0x0b000, 0x0b001) AM_READWRITE (input_port_0A_r, z80_busreq) /* Dipswitches and Z80 busreq */ - AM_RANGE(0x0c000, 0x0c001) AM_RAM /* /SCOLW */ - AM_RANGE(0x0d000, 0x0d003) AM_RAM /* /SLINCS */ - AM_RANGE(0x0e000, 0x0e001) AM_RAM AM_BASE(&bb_sky) /* /SKYCS */ - AM_RANGE(0x0f000, 0x0f003) AM_READWRITE (MRA16_NOP, resume_slave) /* Watchdog and slave resume */ - AM_RANGE(0x10000, 0x17fff) AM_ROM /* Z80 ROM */ - AM_RANGE(0x18000, 0x18fff) AM_READWRITE (z80_shared_r, z80_shared_w) +static ADDRESS_MAP_START( buggybjr_main, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x00000, 0x03fff) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size) + AM_RANGE(0x04000, 0x04fff) AM_READWRITE(tx1_crtc_r, tx1_crtc_w) + AM_RANGE(0x08000, 0x08fff) AM_RAM AM_BASE(&buggybjr_vram) + AM_RANGE(0x0a000, 0x0afff) AM_RAM AM_SHARE(1) AM_BASE(&buggyboy_rcram) AM_SIZE(&buggyboy_rcram_size) + AM_RANGE(0x0b000, 0x0b001) AM_READWRITE(dipswitches_r, z80_busreq_w) + AM_RANGE(0x0c000, 0x0c001) AM_WRITE(buggyboy_scolst_w) + AM_RANGE(0x0d000, 0x0d003) AM_WRITE(buggyboy_slincs_w) + AM_RANGE(0x0e000, 0x0e001) AM_WRITE(buggyboy_sky_w) + AM_RANGE(0x0f000, 0x0f003) AM_READWRITE(watchdog_reset16_r, resume_math_w) + AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(z80_shared_r, z80_shared_w) AM_RANGE(0x20000, 0x2ffff) AM_ROM AM_RANGE(0xf0000, 0xfffff) AM_ROM ADDRESS_MAP_END - -/* -2400-24FF appear to be road control (R/W) - -From the single monitor schematics: - --GAS = 24XX: --BASET0 = 2400-F, 2410-F --BASET1 = 2420-F, 2430-F --BSET = 2440-F, 2450-F --HASET = 2460-F, 2470-F --HSET = 2480-F, 2490-F --WASET = 24A0-F, 24B0-F --FLAGS = 24E0-F, 24F0-F -*/ - -static READ16_HANDLER(GAS_r) -{ - if(offset >= 0xe0/2) halt_slave(); - return 0; -} - -static WRITE16_HANDLER(GAS_w) -{ - if(offset >= 0xe0/2) halt_slave(); -} - - -/* -From single monitor PCB TC-041: - -TZ0310 IC87 (PAL12L6) -============================ -/SPCS = !A15.!A14.!A13.A12 + A14.!A13.!A12 + !A14.A12.A9 + !A14.A13./A12 + !A14.!A11 + A15 -/PRCS (Program ROM) = !A15.!A14.A13.A12 + !A15.!A14.!A13.A12 + !A15.!A14.!A12 -/ARCRCS (Road/Common RAM) = A15.!A14.A13.A12 + !A15.!A14.!A12 + A14 + A15 -/INSALD = /AT3RD.!AT3WDRART + !AT3WDRART.A15 + !AT3WDRART.!A13 + !AT3WDRART.A14 + !AT3WDRART.!A12 + !A7 -/CNTST = /AT3RD.!AT3WDRART + !AT3WDRART.A15 + !AT3WDRART.!A13 + !AT3WDRART.A14 + !AT3WDRART.!A12 + !A8 -LS245 IC24/55 /G (Program ROM and RAM data bus) = !A15.!A14.A13.!A11 + !A15.!A14.A13.A12 + !A15.!A14.!A13.A12 + /ADEN - - -TZ0311 IC88 (PAL10L8) (protection fuse was set, yet it read) -============================ - -/ARTCS (Arithmetic unit and interface) = !(A12.A13.!A14.!A15) -/GAS (Road registers) = !(Q.ADT/#R + Q.!Q.ADT/#R.!ADT/#R) <-- ??? -/EXPCS (Expansion RAM) = !(A11.!A12.A13.!A14.!A15) -/PRMHCS (Program RAM high-byte) = !(!A12.!A13.!A14.!A15.!/ADHE) -/PRMLCS (Program RAM low-byte) = !(!A0.!A12.!A13.!A14.!A15) -/OCRCS (Object RAM) = !(!A10.!A11.!A12.A13.!A14.!A15) -/MLPCS (Arithmetic Unit Instruction = A1-A3) = !(!A10.!A11.A12.A13.!A14.!A15) -/DPRCS (Function Data ROM) = !(A10.A11.A12.A13.!A14.!A15) -*/ - -/* Memory map and ROM contents are the same for both versions */ -static ADDRESS_MAP_START( buggyboy_slave, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x00fff) AM_RAM /* 4kB RAM */ - AM_RANGE(0x01000, 0x01fff) AM_RAM AM_SHARE(1) /* Road/Common RAM */ - AM_RANGE(0x02000, 0x022ff) AM_RAM AM_BASE(&bb_objram) AM_SIZE(&bb_objectram_size) /* RAM A10-A8 are grounded */ - AM_RANGE(0x02400, 0x024ff) AM_READWRITE (GAS_r, GAS_w) /* Road control registers */ - AM_RANGE(0x03000, 0x03fff) AM_READWRITE (BB_AU_R, BB_AU_W) /* SN74S516 arithmetic unit */ - AM_RANGE(0x04000, 0x07fff) AM_ROM /* ROM mirror */ - AM_RANGE(0x08000, 0x0bfff) AM_ROM /* ROM mirror */ - AM_RANGE(0x0c000, 0x0ffff) AM_ROM /* ROM mirror */ - AM_RANGE(0xfc000, 0xfffff) AM_ROM /* ROM */ +static ADDRESS_MAP_START( buggyboy_math, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x00000, 0x007ff) AM_RAM AM_BASE(&tx1_math_ram) + AM_RANGE(0x00800, 0x00fff) AM_READWRITE(buggyboy_spcs_ram_r, buggyboy_spcs_ram_w) + AM_RANGE(0x01000, 0x01fff) AM_RAM AM_SHARE(1) + AM_RANGE(0x02000, 0x022ff) AM_RAM AM_BASE(&buggyboy_objram) AM_SIZE(&buggyboy_objram_size) + AM_RANGE(0x02400, 0x024ff) AM_WRITE(buggyboy_gas_w) + AM_RANGE(0x03000, 0x03fff) AM_READWRITE(buggyboy_math_r, buggyboy_math_w) + AM_RANGE(0x04000, 0x04fff) AM_ROM + AM_RANGE(0x05000, 0x07fff) AM_READ(buggyboy_spcs_rom_r) + AM_RANGE(0x08000, 0x0bfff) AM_ROM + AM_RANGE(0x0c000, 0x0ffff) AM_ROM + AM_RANGE(0xfc000, 0xfffff) AM_ROM ADDRESS_MAP_END -/* Connected in place of dipswitch A bit 0 */ -/* Accessed on startup as some sort of acknowledgement */ -static WRITE8_HANDLER(_TS_) +/* TODO */ +static READ8_HANDLER( bb_analog_r ) { -// TS = 1; + if ( offset == 1 ) + { + return ((readinputportbytag("AN_ACCELERATOR") & 0xf) << 4) | readinputportbytag("AN_STEERING"); + } + else + { + return (readinputportbytag("AN_BRAKE") & 0xf) << 4; + } } -/* Buggy Boy Sound PCB TC033A. */ +static READ8_HANDLER( bbjr_analog_r ) +{ + if ( offset == 0 ) + { + return ((readinputportbytag("AN_ACCELERATOR") & 0xf) << 4) | readinputportbytag("AN_STEERING"); + } + else + { + return (readinputportbytag("AN_BRAKE") & 0xf) << 4; + } +} + +/* Buggy Boy Sound PCB TC033A */ static ADDRESS_MAP_START( buggyboy_sound_prg, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x3fff) AM_ROM - AM_RANGE(0x4000, 0x47ff) AM_RAM AM_BASE(&z80_ram) /* 2kB RAM - shared with Main CPU */ - AM_RANGE(0x6000, 0x6000) AM_READ(input_port_4_r) /* Steering and accelerator */ - AM_RANGE(0x6001, 0x6001) AM_READ(input_port_5_r) /* Brake (NOT USED) */ - AM_RANGE(0x6800, 0x6803) AM_READWRITE(ppi8255_0_r, ppi8255_0_w) /* Digital inputs (coins etc.) - check me */ - AM_RANGE(0x7000, 0x7003) AM_RAM /* 8253 Programmable Interval Timer (Engine Sound) */ - AM_RANGE(0xc024, 0xc024) AM_WRITE(_TS_) /* /TS? */ - AM_RANGE(0x7800, 0x7800) AM_WRITE(z80_intreq_w) /* /INTREQ? */ + AM_RANGE(0x4000, 0x47ff) AM_RAM AM_BASE(&z80_ram) + AM_RANGE(0x6000, 0x6001) AM_READ(bb_analog_r) + AM_RANGE(0x6800, 0x6803) AM_READWRITE(ppi8255_0_r, ppi8255_0_w) + AM_RANGE(0x7000, 0x7003) AM_RAM + AM_RANGE(0x7800, 0x7800) AM_WRITE(z80_intreq_w) + AM_RANGE(0xc000, 0xc7ff) AM_READWRITE(ts_r, ts_w) ADDRESS_MAP_END -/* Buggy Boy (single monitor) Sound PCB TC-043 (no 8255). */ -static ADDRESS_MAP_START( buggyb1_sound_prg, ADDRESS_SPACE_PROGRAM, 8 ) +/* Buggy Boy Jr Sound PCB TC043 */ +static ADDRESS_MAP_START( buggybjr_sound_prg, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x3fff) AM_ROM - AM_RANGE(0x4000, 0x47ff) AM_RAM AM_BASE(&z80_ram) /* 2kB RAM - shared with Main 8086 */ - AM_RANGE(0x5000, 0x5003) AM_RAM /* 8253 Programmable Interval Timer (Engine Sound) */ - AM_RANGE(0x6000, 0x6000) AM_READ(input_port_4_r) /* Steering and accelerator */ - AM_RANGE(0x6001, 0x6001) AM_READ(input_port_5_r) /* Brake (NOT USED) */ - AM_RANGE(0xc024, 0xc024) AM_WRITE(_TS_) /* /TS? */ - AM_RANGE(0x7000, 0x7001) AM_WRITE(z80_intreq_w) /* /INTREQ */ + AM_RANGE(0x4000, 0x47ff) AM_RAM AM_BASE(&z80_ram) + AM_RANGE(0x5000, 0x5003) AM_READWRITE(pit8253_r, pit8253_w) + AM_RANGE(0x6000, 0x6001) AM_READ(bbjr_analog_r) + AM_RANGE(0x7000, 0x7000) AM_WRITE(z80_intreq_w) + AM_RANGE(0xc000, 0xc7ff) AM_READWRITE(ts_r, ts_w) ADDRESS_MAP_END - -/* Common to both versions*/ +/* Common */ static ADDRESS_MAP_START( buggyboy_sound_io, ADDRESS_SPACE_IO, 8 ) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) AM_RANGE(0x40, 0x40) AM_READWRITE(AY8910_read_port_0_r, AY8910_write_port_0_w) AM_RANGE(0x41, 0x41) AM_WRITE(AY8910_control_port_0_w) - AM_RANGE(0x80, 0x80) AM_READWRITE(AY8910_read_port_1_r, AY8910_write_port_1_w) AM_RANGE(0x81, 0x81) AM_WRITE(AY8910_control_port_1_w) ADDRESS_MAP_END -/* Common to TX-1 and Buggy Boy */ +/************************************* + * + * Graphics definitions + * + *************************************/ + static const gfx_layout char_layout = { 8,8, @@ -685,315 +564,187 @@ static const gfx_layout char_layout = 8*8 }; -static const gfx_layout bb_object_layout = -{ - 8,8, - 4096, - 2, - { 0, 8*8*4096 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - -static const gfx_layout tx1_object_layout = -{ - 8,8, - 2048, - 2, - { 0, 8*8*2048 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - -static GFXDECODE_START( bb ) +static GFXDECODE_START( buggyboy ) GFXDECODE_ENTRY( REGION_GFX1, 0, char_layout, 0, 256 ) - GFXDECODE_ENTRY( REGION_GFX2, 0, bb_object_layout, 256, 2048 ) - GFXDECODE_ENTRY( REGION_GFX3, 0, bb_object_layout, 256, 2048 ) - GFXDECODE_ENTRY( REGION_GFX4, 0, bb_object_layout, 256, 2048 ) GFXDECODE_END static GFXDECODE_START( tx1 ) GFXDECODE_ENTRY( REGION_GFX1, 0, char_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX2, 0, tx1_object_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX3, 0, tx1_object_layout, 0, 16 ) GFXDECODE_END -/****************************/ -/* TX-1 Sound Hardware */ -/****************************/ +/************************************* + * + * Sound Hardware + * + *************************************/ -static const struct AY8910interface tx1_ay8910_interface = +static struct AY8910interface tx1_ay8910_interface = { - 0, /* Probably hooked up to discrete sound filters */ + /* TODO */ + 0, + 0, + 0, 0, - 0, - 0, }; -/****************************/ -/* Buggy Boy Sound Hardware */ -/****************************/ -/* -According to the single monitor schematics: - - YM-2149 IC 24 - ============= - - Port A Port B - ====== ====== - -0: Engine sound control 0: Coin Counter 1 -1: Engine sound control 1: Coin Counter 2 -2: Engine sound control 2: Coin Counter 3 (Unused) -3: Engine sound control 3: Engine sound 4066B -4: Engine sound control 4: Noise EN1 -5: Engine sound control 5: Noise EN2 -6: Engine sound control 6: Enable YM IC24 on rear right speaker -7: Engine Noise control 7: Enable YM IC19 on rear left speaker - - YM-2149 IC 19 - ============= - - Port A Port B - ====== ====== - -0: Engine sound control 0: Coin Counter 1 -1: Engine sound control 1: Coin Counter 2 -2: Engine sound control 2: Coin Counter 3 (Unused) -3: Engine sound control 3: Engine sound 4066B -4: Engine sound control 4: Noise EN1 -5: Engine sound control 5: Noise EN2 -6: Engine sound control 6: Enable YM IC24 on rear right speaker -7: Engine Noise control 7: Enable YM IC19 on rear left speaker -*/ - - -static WRITE8_HANDLER(BB_YM2149_1_A_w) -{ - -} - -static WRITE8_HANDLER(BB_YM2149_1_B_w) -{ - coin_counter_w(0,data & 0x01); - coin_counter_w(1,data & 0x02); -} - - -/* YM2149 IC19 - front left */ -static const struct AY8910interface buggyboy_ay8910_interface_1 = +/* YM2149 IC19 */ +static struct AY8910interface buggyboy_ym2149_interface_1 = { + input_port_1_r, input_port_2_r, - input_port_3_r, 0, 0, }; - -/* YM2149 IC24 - front right */ -static const struct AY8910interface buggyboy_ay8910_interface_2 = +/* YM2149 IC24 */ +static struct AY8910interface buggyboy_ym2149_interface_2 = { 0, 0, - BB_YM2149_1_A_w, - BB_YM2149_1_B_w, + bb_ym1_a_w, + bb_ym1_b_w, }; -static WRITE8_HANDLER(TX1_COIN_COUNTER) +static WRITE8_HANDLER( tx1_coin_cnt ) { - coin_counter_w(0,data & 0x80); - coin_counter_w(1,data & 0x40); + coin_counter_w(0, data & 0x80); + coin_counter_w(1, data & 0x40); } -static const ppi8255_interface tx1_ppi8255_intf = + +ppi8255_interface tx1_ppi8255_intf = { 1, - { input_port_2_r }, /* Accelerator and brake */ - { input_port_3_r }, /* Steering and sound wire jumpers */ - { input_port_4_r }, /* Coin and shift inputs */ - { NULL }, - { NULL }, - { TX1_COIN_COUNTER }, + { tx1_ppi_porta_r }, /* Accelerator and brake */ + { tx1_ppi_portb_r }, /* Steering and sound wire jumpers */ + { input_port_4_r }, + { 0 }, + { 0 }, + { tx1_coin_cnt }, }; +static struct CustomSound_interface tx1_custom_interface = +{ + tx1_sh_start, + NULL, + tx1_sh_reset +}; -/* Buggy Boy (3-monitor) uses a 8255 instead of the YM2149 ports for inputs */ -static const ppi8255_interface buggyboy_ppi8255_intf = +/* Buggy Boy uses an 8255 PPI instead of YM2149 ports for inputs! */ +ppi8255_interface buggyboy_ppi8255_intf = { 1, + { input_port_1_r }, + { 0 }, { input_port_2_r }, - { NULL }, - { input_port_3_r }, - { NULL }, - { NULL }, - { NULL }, + { 0 }, + { 0 }, + { 0 }, }; -static MACHINE_RESET( buggyb1 ) +static struct CustomSound_interface bb_custom_interface = { - UINT8 *rom = (UINT8 *)memory_region(REGION_CPU1); + buggyboy_sh_start, + NULL, + buggyboy_sh_reset +}; -/* - The main CPU /TEST line is connected to the /BUSAK output of the Z80. - - TODO: Improve communications. -*/ -#if ROM_PATCHES - rom[0xf00d0]=0x3b; /* Patch out cmp Al,05 - z80 comms */ - rom[0xf00d1]=0xc0; -#endif -} - - -static MACHINE_RESET( buggyboy ) -{ - UINT8 *rom = (UINT8 *)memory_region(REGION_CPU1); - - ppi8255_init(&buggyboy_ppi8255_intf); - -#ifdef ROM_PATCHES - rom[0xf00d0]=0x3b; /* Patch out cmp Al,05 - z80 comms */ - rom[0xf00d1]=0xc0; -#endif -} - -static MACHINE_RESET( tx1 ) -{ - UINT8 *rom = (UINT8 *)memory_region(REGION_CPU1); - UINT8 *rom_b = (UINT8 *)memory_region(REGION_CPU2); - - ppi8255_init(&tx1_ppi8255_intf); - - rom = rom; - rom_b = rom_b; - - /* For tx1a: Needed to skip the startup tests */ -#if 0 - rom_b[0xfcf38]=0x3B; /* Patch out AU check */ - rom_b[0xfcf39]=0xc0; - rom_b[0xfcf3a]=0x90; - rom_b[0xfcf3b]=0x90; - rom_b[0xfcf3c]=0x90; - - rom_b[0xfce68]=0x3b; - rom_b[0xfce69]=0xc0; - rom_b[0xfce6a]=0x90; - - rom_b[0xfcf43]=0x3B; /* Patch out AU check */ - rom_b[0xfcf44]=0xc0; - rom_b[0xfcf45]=0x90; - rom_b[0xfcf46]=0x90; - rom_b[0xfcf47]=0x90; - - rom[0xf3c38]=0x3b; /* Main ROM Checksum */ - rom[0xf3c39]=0xc0; - rom[0xf0251]=0x3b; /* Patch out cmp Al,?? */ - rom[0xf0252]=0xc0; - rom[0xf0265]=0x3b; /* Patch out cmp Al,?? */ - rom[0xf0266]=0xc0; - rom[0xf0271]=0x90; /* NOP */ - rom[0xf0280]=0x3b; /* Patch out cmp Al,?? */ - rom[0xf0281]=0xc0; -#endif -} +/************************************* + * + * Machine driver + * + *************************************/ static MACHINE_DRIVER_START( tx1 ) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(tx1_master,0) - MDRV_CPU_PERIODIC_INT(main_irq, 46 ) /* To do: measure HD46505 CUDISP output rate */ - //MDRV_WATCHDOG_TIME_INIT(ATTOTIME_IN_SEC(5)) /* To do: measure watchdog time interval */ + MDRV_CPU_ADD(I8086, 5000000) + MDRV_CPU_PROGRAM_MAP(tx1_main, 0) +// MDRV_WATCHDOG_TIME_INIT(5) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(tx1_slave,0) + MDRV_CPU_ADD(I8086,5000000) + MDRV_CPU_PROGRAM_MAP(tx1_math, 0) - MDRV_CPU_ADD(Z80,3750000 ) /* Guess */ - MDRV_CPU_PROGRAM_MAP(tx1_sound_prg,0) - MDRV_CPU_IO_MAP(tx1_sound_io,0) - MDRV_CPU_PERIODIC_INT(irq0_line_hold, 915.52734375/2 ) /* Guess */ + MDRV_CPU_ADD(Z80, TX1_PIXEL_CLOCK / 2) + MDRV_CPU_PROGRAM_MAP(tx1_sound_prg, 0) + MDRV_CPU_IO_MAP(tx1_sound_io, 0) + MDRV_CPU_PERIODIC_INT(irq0_line_hold, TX1_PIXEL_CLOCK / 4 / 2048 / 2) MDRV_MACHINE_RESET(tx1) - MDRV_INTERLEAVE(100) + MDRV_MACHINE_START(tx1) + MDRV_NVRAM_HANDLER(generic_0fill) MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_GFXDECODE(tx1) - MDRV_PALETTE_LENGTH(32768) + MDRV_PALETTE_LENGTH(256) + MDRV_COLORTABLE_LENGTH(256+(256*4)+(2048*4)) + MDRV_PALETTE_INIT(tx1) + MDRV_VIDEO_EOF(tx1) + MDRV_DEFAULT_LAYOUT(layout_triphsxs) MDRV_SCREEN_ADD("left", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(TX1_PIXEL_CLOCK, TX1_HTOTAL, TX1_HBEND, TX1_HBSTART, TX1_VTOTAL, TX1_VBEND, TX1_VBSTART) - MDRV_SCREEN_ADD("middle", 0x000) + MDRV_SCREEN_ADD("center", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(TX1_PIXEL_CLOCK, TX1_HTOTAL, TX1_HBEND, TX1_HBSTART, TX1_VTOTAL, TX1_VBEND, TX1_VBSTART) MDRV_SCREEN_ADD("right", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(TX1_PIXEL_CLOCK, TX1_HTOTAL, TX1_HBEND, TX1_HBSTART, TX1_VTOTAL, TX1_VBEND, TX1_VBSTART) MDRV_VIDEO_START(tx1) MDRV_VIDEO_UPDATE(tx1) - MDRV_SPEAKER_STANDARD_MONO("Mono") /* Mono for the time being */ + MDRV_SPEAKER_STANDARD_STEREO("Front Left", "Front Right") +// MDRV_SPEAKER_STANDARD_STEREO("Rear Left", "Rear Right") - MDRV_SOUND_ADD(AY8910, 1875000) /* Guess */ + MDRV_SOUND_ADD(AY8910, TX1_PIXEL_CLOCK / 8) MDRV_SOUND_CONFIG(tx1_ay8910_interface) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Mono", 0.5) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Left", 0.5) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Right", 0.5) + + MDRV_SOUND_ADD(CUSTOM, 0) + MDRV_SOUND_CONFIG(tx1_custom_interface) + MDRV_SOUND_ROUTE(0, "Front Left", 0.2) + MDRV_SOUND_ROUTE(1, "Front Right", 0.2) MACHINE_DRIVER_END + static MACHINE_DRIVER_START( buggyboy ) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(buggyboy_master,0) - MDRV_CPU_PERIODIC_INT(main_irq, 46 ) /* To do: measure HD46505 CUDISP output rate */ - //MDRV_WATCHDOG_TIME_INIT(ATTOTIME_IN_SEC(5)) /* To do: measure watchdog time interval */ + MDRV_CPU_ADD(BUGGYBOY_CPU_TYPE, 5000000) + MDRV_CPU_PROGRAM_MAP(buggyboy_main, 0) +// MDRV_WATCHDOG_TIME_INIT(5) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(buggyboy_slave,0) + MDRV_CPU_ADD(BUGGYBOY_CPU_TYPE, 5000000) + MDRV_CPU_PROGRAM_MAP(buggyboy_math, 0) - MDRV_CPU_ADD(Z80,3750000 ) /* audio CPU */ - MDRV_CPU_PROGRAM_MAP(buggyboy_sound_prg,0) - MDRV_CPU_PERIODIC_INT(z80_irq, 915.52734375/2 ) /* To do: verify against real PCB */ - MDRV_CPU_IO_MAP(buggyboy_sound_io,0) + MDRV_CPU_ADD(Z80, BUGGYBOY_ZCLK / 2) + MDRV_CPU_PROGRAM_MAP(buggyboy_sound_prg, 0) + MDRV_CPU_PERIODIC_INT(z80_irq, BUGGYBOY_ZCLK / 2 / 4 / 2048) + MDRV_CPU_IO_MAP(buggyboy_sound_io, 0) MDRV_MACHINE_RESET(buggyboy) - MDRV_INTERLEAVE(100) + MDRV_MACHINE_START(buggyboy) + MDRV_NVRAM_HANDLER(generic_0fill) MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) - MDRV_GFXDECODE(bb) + MDRV_GFXDECODE(buggyboy) MDRV_DEFAULT_LAYOUT(layout_triphsxs) MDRV_SCREEN_ADD("left", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(BB_PIXEL_CLOCK, BB_HTOTAL, BB_HBEND, BB_HBSTART, BB_VTOTAL, BB_VBEND, BB_VBSTART) - MDRV_SCREEN_ADD("middle", 0x000) + MDRV_SCREEN_ADD("center", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(BB_PIXEL_CLOCK, BB_HTOTAL, BB_HBEND, BB_HBSTART, BB_VTOTAL, BB_VBEND, BB_VBSTART) MDRV_SCREEN_ADD("right", 0x000) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_SCREEN_SIZE(256, 256) - MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) + MDRV_SCREEN_RAW_PARAMS(BB_PIXEL_CLOCK, BB_HTOTAL, BB_HBEND, BB_HBSTART, BB_VTOTAL, BB_VBEND, BB_VBSTART) MDRV_PALETTE_LENGTH(256) MDRV_COLORTABLE_LENGTH(256+(256*4)+(2048*4)) @@ -1001,73 +752,88 @@ static MACHINE_DRIVER_START( buggyboy ) MDRV_VIDEO_START(buggyboy) MDRV_VIDEO_UPDATE(buggyboy) - /* Sound hardware */ MDRV_SPEAKER_STANDARD_STEREO("Front Left", "Front Right") - /* MDRV_SPEAKER_STANDARD_STEREO("Rear Left", "Rear Right") */ +// MDRV_SPEAKER_STANDARD_STEREO("Rear Left", "Rear Right") - MDRV_SOUND_ADD(AY8910, 1875000) - MDRV_SOUND_CONFIG(buggyboy_ay8910_interface_1) + MDRV_SOUND_ADD(YM2149, BUGGYBOY_ZCLK / 4) + MDRV_SOUND_CONFIG(buggyboy_ym2149_interface_1) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Left", 0.15) - MDRV_SOUND_ADD(AY8910, 1875000) - MDRV_SOUND_CONFIG(buggyboy_ay8910_interface_2) + MDRV_SOUND_ADD(YM2149, BUGGYBOY_ZCLK / 4) + MDRV_SOUND_CONFIG(buggyboy_ym2149_interface_2) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Right", 0.15) + + MDRV_SOUND_ADD(CUSTOM, 0) + MDRV_SOUND_CONFIG(bb_custom_interface) + MDRV_SOUND_ROUTE(0, "Front Left", 0.2) + MDRV_SOUND_ROUTE(1, "Front Right", 0.2) MACHINE_DRIVER_END -/* Need to verify clocks on real PCB */ -static MACHINE_DRIVER_START( buggyb1 ) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(buggyb1_master,0) - MDRV_CPU_PERIODIC_INT(main_irq, 46 ) /* To do: measure HD46505 CUDISP output rate */ - //MDRV_WATCHDOG_TIME_INIT(ATTOTIME_IN_SEC(5)) /* To do: measure watchdog time interval */ +static MACHINE_DRIVER_START( buggybjr ) + MDRV_CPU_ADD(BUGGYBOY_CPU_TYPE, 5000000) + MDRV_CPU_PROGRAM_MAP(buggybjr_main, 0) +// MDRV_WATCHDOG_TIME_INIT(5) - MDRV_CPU_ADD(I8086,5000000 ) - MDRV_CPU_PROGRAM_MAP(buggyboy_slave,0) + MDRV_CPU_ADD(BUGGYBOY_CPU_TYPE, 5000000) + MDRV_CPU_PROGRAM_MAP(buggyboy_math, 0) - MDRV_CPU_ADD(Z80,3750000 ) /* audio CPU */ - MDRV_CPU_PROGRAM_MAP(buggyb1_sound_prg,0) - MDRV_CPU_PERIODIC_INT(z80_irq, 915.52734375/2 ) /* To do: verify against real PCB*/ - MDRV_CPU_IO_MAP(buggyboy_sound_io,0) + MDRV_CPU_ADD(Z80, BUGGYBOY_ZCLK / 2) + MDRV_CPU_PROGRAM_MAP(buggybjr_sound_prg, 0) + MDRV_CPU_IO_MAP(buggyboy_sound_io, 0) + MDRV_CPU_PERIODIC_INT(z80_irq, BUGGYBOY_ZCLK / 2 / 4 / 2048) - /* Confirm this stuff */ - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_MACHINE_RESET( buggyb1 ) - MDRV_INTERLEAVE(100) /* ? */ + MDRV_MACHINE_RESET(buggybjr) + MDRV_MACHINE_START(buggybjr) + MDRV_NVRAM_HANDLER(generic_0fill) MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + +#if 0 + MDRV_SCREEN_RAW_PARAMS(BB_PIXEL_CLOCK, BB_HTOTAL, BB_HBEND, BB_HBSTART, BB_VTOTAL, BB_VBEND, BB_VBSTART) +#else + MDRV_SCREEN_REFRESH_RATE(54.10) + MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(3072)) MDRV_SCREEN_SIZE(256, 256) MDRV_SCREEN_VISIBLE_AREA(0, 255, 0, 239) - MDRV_GFXDECODE(bb) - +#endif + MDRV_GFXDECODE(buggyboy) MDRV_PALETTE_LENGTH(256) - MDRV_COLORTABLE_LENGTH(256+(256*4)+(2048*4)) /* 256 for chars, 2048 for objects */ + MDRV_COLORTABLE_LENGTH(256) MDRV_PALETTE_INIT(buggyboy) - MDRV_VIDEO_START(buggyb1) - MDRV_VIDEO_UPDATE(buggyb1) + MDRV_VIDEO_START(buggybjr) + MDRV_VIDEO_UPDATE(buggybjr) + MDRV_VIDEO_EOF(buggyboy) - /* Sound hardware */ MDRV_SPEAKER_STANDARD_STEREO("Front Left", "Front Right") - /* MDRV_SPEAKER_STANDARD_STEREO("Rear Left", "Rear Right") */ +// MDRV_SPEAKER_STANDARD_STEREO("Rear Left", "Rear Right") - MDRV_SOUND_ADD(AY8910, 1875000) - MDRV_SOUND_CONFIG(buggyboy_ay8910_interface_1) + MDRV_SOUND_ADD(YM2149, BUGGYBOY_ZCLK / 4) + MDRV_SOUND_CONFIG(buggyboy_ym2149_interface_1) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Left", 0.15) - MDRV_SOUND_ADD(AY8910, 1875000) - MDRV_SOUND_CONFIG(buggyboy_ay8910_interface_2) + MDRV_SOUND_ADD(YM2149, BUGGYBOY_ZCLK / 4) + MDRV_SOUND_CONFIG(buggyboy_ym2149_interface_2) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "Front Right", 0.15) + + MDRV_SOUND_ADD(CUSTOM, 0) + MDRV_SOUND_CONFIG(bb_custom_interface) + MDRV_SOUND_ROUTE(0, "Front Left", 0.2) + MDRV_SOUND_ROUTE(1, "Front Right", 0.2) MACHINE_DRIVER_END +/************************************* + * + * ROM definition(s) + * + *************************************/ ROM_START( tx1 ) ROM_REGION( 0x100000, REGION_CPU1, 0 ) - ROM_LOAD16_BYTE( "8411-136027-157.11", 0x10000, 0x2000, CRC(10ae3075) SHA1(69c5f62f2473aba848383eed3cecf15e273d86ca) ) /* Z80 ROM - checksummed by main CPU */ - ROM_LOAD16_BYTE( "tx1_1c.ic22", 0xf0000, 0x4000, CRC(eedcee83) SHA1(7fa0590b142fb13c6562126a9bdd5a1e032880c7) ) ROM_LOAD16_BYTE( "tx1_2c.ic29", 0xf0001, 0x4000, CRC(294bf5bf) SHA1(02b425caba8a187c58211bab27988205eb044558) ) + ROM_LOAD16_BYTE( "tx1_4c.ic54", 0xf8001, 0x4000, CRC(15bb8ef2) SHA1(83968f010ec555fcd0548a80562fb23a892b5afb) ) ROM_LOAD16_BYTE( "tx1_3c.ic45", 0xf8000, 0x4000, CRC(21a8aa55) SHA1(21bc4adefb22a95fcd7a4e305bf0b05e2cb34129) ) @@ -1080,72 +846,93 @@ ROM_START( tx1 ) ROM_RELOAD( 0x4001, 0x2000 ) ROM_RELOAD( 0x8001, 0x2000 ) ROM_RELOAD( 0xc001, 0x2000 ) + /* Sound */ ROM_REGION( 0x10000, REGION_CPU3, 0 ) ROM_LOAD( "8411-136027-157.11", 0x00000, 0x2000, CRC(10ae3075) SHA1(69c5f62f2473aba848383eed3cecf15e273d86ca) ) /* 8x8 characters */ ROM_REGION( 0x20000, REGION_GFX1, ROMREGION_DISPOSE ) - ROM_LOAD( "tx1_20a.ic174", 0x0000, 0x4000, CRC(dbe595fc) SHA1(1ed2f775f0a1b46a2ffbc056eb4ef732ed546d3c) ) - ROM_LOAD( "tx1_21a.ic204", 0x4000, 0x4000, CRC(cd3441ad) SHA1(8e6597b3177b8aaa34ed3373d85fc4b6231e1333) ) + ROM_LOAD( "tx1_21a.ic204", 0x0000, 0x4000, CRC(cd3441ad) SHA1(8e6597b3177b8aaa34ed3373d85fc4b6231e1333) ) + ROM_LOAD( "tx1_20a.ic174", 0x4000, 0x4000, CRC(dbe595fc) SHA1(1ed2f775f0a1b46a2ffbc056eb4ef732ed546d3c) ) /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX2, ROMREGION_DISPOSE ) + ROM_REGION( 0x40000, REGION_GFX2, 0 ) ROM_LOAD( "tx1_16b.ic203", 0x0000, 0x4000, CRC(1141c965) SHA1(4b90c1428bcbd72d0449c064856a5596269b3fc6) ) ROM_LOAD( "tx1_18b.ic258", 0x4000, 0x4000, NO_DUMP ) /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX3, ROMREGION_DISPOSE ) + ROM_REGION( 0x40000, REGION_GFX3, 0 ) ROM_LOAD( "tx1_15b.ic173", 0x0000, 0x4000, CRC(30d1a8d5) SHA1(b4c585b7b8a8920bb3949d643e9e10c17d4009a0) ) ROM_LOAD( "tx1_17b.ic232", 0x4000, 0x4000, CRC(364bb354) SHA1(a26581ca1088b979285471e2c6595048df84d75e) ) /* Road LUTs */ - ROM_REGION( 0x40000, REGION_GFX4, ROMREGION_DISPOSE ) + ROM_REGION( 0x40000, REGION_GFX4, 0 ) ROM_LOAD( "tx1_5a.ic56", 0x0000, 0x2000, CRC(5635b8c1) SHA1(5cc9437a2ff0843f1917f2451852d4561c240b24) ) ROM_LOAD( "tx1_6a.ic66", 0x2000, 0x2000, CRC(03d83cf8) SHA1(5c0cfc6bf02ad2b3f37e1ceb493f69eb9829ab1e) ) ROM_LOAD( "tx1_7a.ic76", 0x4000, 0x2000, CRC(ad56013a) SHA1(ae3a91f58f30daff334754476db33ad1d12569fc) ) /* Arithmetic Unit Function Data ROMs */ - ROM_REGION( 0x10000, REGION_USER1, 0 ) + ROM_REGION( 0x10000, REGION_USER1, ROMREGION_LE ) ROM_LOAD16_BYTE( "tx1_10b.ic184", 0x0000, 0x4000, CRC(acf754e8) SHA1(06779e18636f0799efdaa09396e9ccd59f426257) ) ROM_LOAD16_BYTE( "tx1_11b.ic185", 0x0001, 0x4000, CRC(f89d3e20) SHA1(4b4cf679b7e3d63cded9989d2b667941f718ff57) ) + ROM_LOAD16_BYTE( "xb02b.ic223", 0x8000, 0x200, CRC(22c77af6) SHA1(1be8585b95316b4fc5712cdaef699e676320cd4d) ) + ROM_LOAD16_BYTE( "xb01b.ic213", 0x8001, 0x200, CRC(f6b8b70b) SHA1(b79374acf11d71db1e4ad3c494ac5f500a52677b) ) + /* Object chunk sequence LUT */ ROM_REGION( 0x50000, REGION_USER2, 0 ) - ROM_LOAD( "tx1_14b.ic106", 0x0000, 0x4000, CRC(68c63d6e) SHA1(110e02b99c44d31041be588bd14642e26890ecbd) ) /* Object chunk sequence LUT */ - ROM_LOAD( "tx1_13b.ic73", 0x4000, 0x4000, CRC(b0c581b2) SHA1(20926bc15e7c97045b219b828acfcdd99b8712a6) ) /* Object chunk sequence LUT */ + ROM_LOAD( "tx1_14b.ic106", 0x0000, 0x4000, CRC(68c63d6e) SHA1(110e02b99c44d31041be588bd14642e26890ecbd) ) + ROM_LOAD( "tx1_13b.ic73", 0x4000, 0x4000, CRC(b0c581b2) SHA1(20926bc15e7c97045b219b828acfcdd99b8712a6) ) + /* Object LUT */ + /* Object palette LUT */ ROM_REGION( 0x50000, REGION_USER3, 0 ) - ROM_LOAD( "tx1_12b.ic48", 0x0000, 0x2000, CRC(4b3d7956) SHA1(fc2432dd69f3be7007d4fd6f7c86c7c19453b1ba) ) /* Object LUT */ - ROM_LOAD( "tx1_19b.ic281", 0x2000, 0x4000, NO_DUMP ) /* Object palette LUT */ + ROM_LOAD( "tx1_12b.ic48", 0x0000, 0x2000, CRC(4b3d7956) SHA1(fc2432dd69f3be7007d4fd6f7c86c7c19453b1ba) ) + ROM_LOAD( "tx1_19b.ic281", 0x2000, 0x4000, NO_DUMP ) ROM_REGION( 0x10000, REGION_PROMS, 0 ) - ROM_LOAD( "xb01b.ic213",0x0000, 0x200, CRC(f6b8b70b) SHA1(b79374acf11d71db1e4ad3c494ac5f500a52677b) ) - ROM_LOAD( "xb02b.ic223",0x0200, 0x200, CRC(22c77af6) SHA1(1be8585b95316b4fc5712cdaef699e676320cd4d) ) - ROM_LOAD( "xb03a.ic25", 0x0300, 0x100, CRC(616a7a85) SHA1(b7c1060ecb128154092441212de64dc304aa3fcd) ) - ROM_LOAD( "xb04a.ic276",0x0500, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) - ROM_LOAD( "xb04a.ic277",0x0700, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) - ROM_LOAD( "xb05a.ic36", 0x0800, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) - ROM_LOAD( "xb05a.ic57", 0x0900, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) - ROM_LOAD( "xb05a.ic8", 0x0a00, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) - ROM_LOAD( "xb06a.ic37", 0x0b00, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) - ROM_LOAD( "xb06a.ic58", 0x0c00, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) - ROM_LOAD( "xb06a.ic9", 0x0d00, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) - ROM_LOAD( "xb07a.ic10", 0x0e00, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) - ROM_LOAD( "xb07a.ic38", 0x0f00, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) - ROM_LOAD( "xb07a.ic59", 0x1000, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) - ROM_LOAD( "xb08.ic116", 0x1100, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) - ROM_LOAD( "xb08.ic148", 0x1200, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) - ROM_LOAD( "xb08.ic85", 0x1300, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) - ROM_LOAD( "xb09.ic33", 0x1500, 0x200, CRC(fafb6917) SHA1(30eb182c7623026dce7dba9e249bc8a9eb7a7f3e) ) - ROM_LOAD( "xb10.ic40", 0x1700, 0x200, CRC(93deb894) SHA1(5ae9a21298c836fe649a52f3df2b4067f9012b91) ) - ROM_LOAD( "xb11.ic49", 0x1900, 0x200, CRC(aa5ed232) SHA1(f33e7bc2dd33ac6d75fb06b93c4dd58e5d10010d) ) - ROM_LOAD( "xb12.ic50", 0x1b00, 0x200, CRC(6b424cea) SHA1(83127326c20116b0a4be1126e163f9c6755e19dc) ) + /* RGB palette (left) */ + ROM_LOAD( "xb05a.ic57", 0x0000, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic58", 0x0100, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic59", 0x0200, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* RGB palette (center) */ + ROM_LOAD( "xb05a.ic36", 0x0300, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic37", 0x0400, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic38", 0x0500, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* RGB palette (right) */ + ROM_LOAD( "xb05a.ic8", 0x0600, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic9", 0x0700, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic10", 0x0800, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* Character colour tables (L, C, R) */ + ROM_LOAD( "xb08.ic85", 0x0900, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + ROM_LOAD( "xb08.ic116", 0x0a00, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + ROM_LOAD( "xb08.ic148", 0x0b00, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + + /* Object colour table */ + ROM_LOAD( "xb04a.ic276",0x0c00, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) + ROM_LOAD( "xb04a.ic277",0x0e00, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) + + /* Object tile lookup */ + ROM_LOAD( "xb03a.ic25", 0x1000, 0x100, CRC(616a7a85) SHA1(b7c1060ecb128154092441212de64dc304aa3fcd) ) + + /* Road graphics */ + ROM_LOAD( "xb09.ic33", 0x1100, 0x200, CRC(fafb6917) SHA1(30eb182c7623026dce7dba9e249bc8a9eb7a7f3e) ) + ROM_LOAD( "xb10.ic40", 0x1300, 0x200, CRC(93deb894) SHA1(5ae9a21298c836fe649a52f3df2b4067f9012b91) ) + ROM_LOAD( "xb11.ic49", 0x1500, 0x200, CRC(aa5ed232) SHA1(f33e7bc2dd33ac6d75fb06b93c4dd58e5d10010d) ) + + /* Road related */ + ROM_LOAD( "xb12.ic50", 0x1700, 0x200, CRC(6b424cea) SHA1(83127326c20116b0a4be1126e163f9c6755e19dc) ) + + /* Arithmetic unit instructions */ + ROM_LOAD16_BYTE( "xb02b.ic223", 0x1800, 0x200, CRC(22c77af6) SHA1(1be8585b95316b4fc5712cdaef699e676320cd4d) ) + ROM_LOAD16_BYTE( "xb01b.ic213", 0x1801, 0x200, CRC(f6b8b70b) SHA1(b79374acf11d71db1e4ad3c494ac5f500a52677b) ) ROM_END ROM_START( tx1a ) ROM_REGION( 0x100000, REGION_CPU1, 0 ) - ROM_LOAD16_BYTE( "8411-136027-157.11", 0x10000, 0x2000, CRC(10ae3075) SHA1(69c5f62f2473aba848383eed3cecf15e273d86ca) ) /* Z80 ROM - checksummed by main CPU */ - ROM_LOAD16_BYTE( "8412-136027-244.22", 0xf0000, 0x4000, CRC(2e9cefa2) SHA1(4ca04eae446e8df08ab793488a79217ed1a27875) ) ROM_LOAD16_BYTE( "8412-136027-245.29", 0xf0001, 0x4000, CRC(ade7895c) SHA1(1c33a574cae46fddb4cadb85f5de17f02ae7a596) ) ROM_LOAD16_BYTE( "8412-136027-250.54", 0xf8001, 0x4000, CRC(c8c9368f) SHA1(0972d54d506216eb2b204cf22ccdff9210fb7b10) ) @@ -1167,48 +954,78 @@ ROM_START( tx1a ) /* 8x8 characters */ ROM_REGION( 0x20000, REGION_GFX1, ROMREGION_DISPOSE ) - ROM_LOAD( "8411-136027-155.174", 0x0000, 0x4000, CRC(e59a6b72) SHA1(c10efa77ab421ac60b97227a8d547f50f8415670) ) - ROM_LOAD( "8411-136027-156.204", 0x4000, 0x4000, CRC(60f3c616) SHA1(59c4361891e4274e27e6279c919e8fd6803af7cf) ) + ROM_LOAD( "8411-136027-156.204", 0x0000, 0x4000, CRC(60f3c616) SHA1(59c4361891e4274e27e6279c919e8fd6803af7cf) ) + ROM_LOAD( "8411-136027-155.174", 0x4000, 0x4000, CRC(e59a6b72) SHA1(c10efa77ab421ac60b97227a8d547f50f8415670) ) /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX2, ROMREGION_DISPOSE ) + ROM_REGION( 0x40000, REGION_GFX2, 0 ) ROM_LOAD( "8411-136027-114.203", 0x0000, 0x4000, CRC(fc91328b) SHA1(e57fd2056b65d37cf2e1f0af56616c6555df3006) ) ROM_LOAD( "8411-136027-116.258", 0x4000, 0x4000, CRC(5745f671) SHA1(6e471633cd6de9926b3361a84430c088e1f6a097) ) - - /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX3, ROMREGION_DISPOSE ) - ROM_LOAD( "8411-136027-115.173", 0x0000, 0x4000, CRC(720e5873) SHA1(151d9063c35b26f5876cf94bdf0c2665ec701bbd) ) - ROM_LOAD( "8411-136027-117.232", 0x4000, 0x4000, CRC(3c68d0bc) SHA1(2dbaf2a268b90214fd61c016ac945d4371057826) ) + ROM_LOAD( "8411-136027-115.173", 0x8000, 0x4000, CRC(720e5873) SHA1(151d9063c35b26f5876cf94bdf0c2665ec701bbd) ) + ROM_LOAD( "8411-136027-117.232", 0xc000, 0x4000, CRC(3c68d0bc) SHA1(2dbaf2a268b90214fd61c016ac945d4371057826) ) /* Road LUTs */ - ROM_REGION( 0x40000, REGION_GFX4, ROMREGION_DISPOSE ) + ROM_REGION( 0x40000, REGION_GFX3, 0 ) ROM_LOAD( "8411-136027-146.56", 0x0000, 0x2000, CRC(5635b8c1) SHA1(5cc9437a2ff0843f1917f2451852d4561c240b24) ) ROM_LOAD( "8411-136027-147.66", 0x2000, 0x2000, CRC(03d83cf8) SHA1(5c0cfc6bf02ad2b3f37e1ceb493f69eb9829ab1e) ) ROM_LOAD( "8411-136027-148.76", 0x4000, 0x2000, CRC(ad56013a) SHA1(ae3a91f58f30daff334754476db33ad1d12569fc) ) /* Arithmetic Unit Function Data ROMs */ - ROM_REGION( 0x10000, REGION_USER1, 0 ) + ROM_REGION( 0x10000, REGION_USER1, ROMREGION_LE ) ROM_LOAD16_BYTE( "8411-136027-153.184", 0x0000, 0x4000, CRC(acf754e8) SHA1(06779e18636f0799efdaa09396e9ccd59f426257) ) ROM_LOAD16_BYTE( "8411-136027-154.185", 0x0001, 0x4000, CRC(f89d3e20) SHA1(4b4cf679b7e3d63cded9989d2b667941f718ff57) ) + ROM_LOAD16_BYTE( "xb02b.ic223", 0x8000, 0x200, CRC(22c77af6) SHA1(1be8585b95316b4fc5712cdaef699e676320cd4d) ) + ROM_LOAD16_BYTE( "xb01b.ic213", 0x8001, 0x200, CRC(f6b8b70b) SHA1(b79374acf11d71db1e4ad3c494ac5f500a52677b) ) ROM_REGION( 0x50000, REGION_USER2, 0 ) ROM_LOAD( "8411-136027-119.106", 0x0000, 0x4000, CRC(88eec0fb) SHA1(81d7a69dc1a4b3b81d7f28d97a3f80697cdcc6eb) ) /* Object chunk sequence LUT */ - ROM_LOAD( "8411-136027-120.73", 0x4000, 0x4000, CRC(407cbe65) SHA1(e1c11b65f3c6abde6d55afeaffdb39cdd6d66377) ) /* Object chunk sequence LUT */ + ROM_LOAD( "8411-136027-120.73", 0x4000, 0x4000, CRC(407cbe65) SHA1(e1c11b65f3c6abde6d55afeaffdb39cdd6d66377) ) /* Object chunk sequence LUT */ ROM_REGION( 0x50000, REGION_USER3, 0 ) ROM_LOAD( "8411-136027-113.48", 0x0000, 0x2000, CRC(4b3d7956) SHA1(fc2432dd69f3be7007d4fd6f7c86c7c19453b1ba) ) /* Object LUT */ ROM_LOAD( "8411-136027-118.281", 0x2000, 0x4000, CRC(de418dc7) SHA1(1233e2f7499ec5a73a40ee336d3fe26c06187784) ) /* Object palette LUT */ /* PROMs not dumped. May well be the same as the Tazmi set. */ + ROM_REGION( 0x10000, REGION_PROMS, 0 ) + /* RGB palette (left) */ + ROM_LOAD( "xb05a.ic57", 0x0000, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic58", 0x0100, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic59", 0x0200, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* RGB palette (center) */ + ROM_LOAD( "xb05a.ic36", 0x0300, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic37", 0x0400, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic38", 0x0500, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* RGB palette (right) */ + ROM_LOAD( "xb05a.ic8", 0x0600, 0x100, CRC(3b387d01) SHA1(1229548e3052ad34eeee9598743091d19f6b8f88) ) + ROM_LOAD( "xb06a.ic9", 0x0700, 0x100, CRC(f6f4d7d9) SHA1(866024b76b26d6942bd4e1d2494686299414f6be) ) + ROM_LOAD( "xb07a.ic10", 0x0800, 0x100, CRC(824e7532) SHA1(917ce74d2bae6af90f2c4e41d12a69f884320915) ) + + /* Character colour tables (L, C, R) */ + ROM_LOAD( "xb08.ic85", 0x0900, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + ROM_LOAD( "xb08.ic116", 0x0a00, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + ROM_LOAD( "xb08.ic148", 0x0b00, 0x100, CRC(5aeef5cc) SHA1(e123bf01d556178b0cf9d495bcce445f3f8421cd) ) + + /* Object colour table */ + ROM_LOAD( "xb04a.ic276",0x0c00, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) + ROM_LOAD( "xb04a.ic277",0x0e00, 0x200, CRC(92bf5533) SHA1(4d9127417325af66099234178ab2641d23ee9d22) ) + + /* Object tile lookup */ + ROM_LOAD( "xb03a.ic25", 0x1000, 0x100, CRC(616a7a85) SHA1(b7c1060ecb128154092441212de64dc304aa3fcd) ) + + /* Road graphics */ + ROM_LOAD( "xb09.ic33", 0x1100, 0x200, CRC(fafb6917) SHA1(30eb182c7623026dce7dba9e249bc8a9eb7a7f3e) ) + ROM_LOAD( "xb10.ic40", 0x1300, 0x200, CRC(93deb894) SHA1(5ae9a21298c836fe649a52f3df2b4067f9012b91) ) + ROM_LOAD( "xb11.ic49", 0x1500, 0x200, CRC(aa5ed232) SHA1(f33e7bc2dd33ac6d75fb06b93c4dd58e5d10010d) ) + + /* Road related */ + ROM_LOAD( "xb12.ic50", 0x1700, 0x200, CRC(6b424cea) SHA1(83127326c20116b0a4be1126e163f9c6755e19dc) ) ROM_END /* The single monitor is the parent set at the moment, as the 3-monitor dump is incomplete */ - -/* Single Monitor Version */ -ROM_START( buggyb1 ) +ROM_START( buggybjr ) ROM_REGION( 0x100000, REGION_CPU1, 0 ) - ROM_LOAD16_BYTE( "bug35s.21", 0x10000, 0x4000, CRC(65d9af57) SHA1(17b09404942d17e7254550c43b56ae96a8c55680) ) /* Z80 ROM - checksummed by main CPU */ - ROM_LOAD16_BYTE( "bug1a.214", 0x20000, 0x8000, CRC(92797c25) SHA1(8f7434abbd7f557d3202abb01b1e4899c82c67a5) ) ROM_LOAD16_BYTE( "bug4a.175", 0x20001, 0x8000, CRC(40ce3930) SHA1(4bf62ebeea1549a13a21a32cb860717f064b186a) ) @@ -1230,78 +1047,66 @@ ROM_START( buggyb1 ) ROM_LOAD( "bug35s.21", 0x00000, 0x4000, CRC(65d9af57) SHA1(17b09404942d17e7254550c43b56ae96a8c55680) ) /* 8x8 characters */ - ROM_REGION( 0x20000, REGION_GFX1, ROMREGION_DISPOSE ) + ROM_REGION( 0x8000, REGION_GFX1, 0 ) ROM_LOAD( "bug34s.46", 0x00000, 0x4000, CRC(8ea8fec4) SHA1(75e67c9a59a86fcdedf2a70fafd303baa552aa18) ) ROM_LOAD( "bug33s.47", 0x04000, 0x4000, CRC(459c2b03) SHA1(ff62a86195042a349fbe799c638cf590fe9572bb) ) /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX2, ROMREGION_DISPOSE ) - ROM_LOAD( "bug26s.147", 0x0000, 0x8000, CRC(14033710) SHA1(e05afeb557ce14055fa8b4f6d8805307feaa1660) ) - ROM_LOAD( "bug19s.144", 0x8000, 0x8000, CRC(838e0697) SHA1(0e9aff2c4065d79350ddb55edff57a899c33ef1c) ) - - /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX3, ROMREGION_DISPOSE ) - ROM_LOAD( "bug28s.146", 0x0000, 0x8000, CRC(8b47d227) SHA1(a3e57594ad0085e8b1bd327c580eb36237f3e3d2) ) - ROM_LOAD( "bug21s.143", 0x8000, 0x8000, CRC(876a5666) SHA1(db485cdf35f63c080c919ee86374f63e577092c3) ) - - /* 8x8 object chunks */ - ROM_REGION( 0x40000, REGION_GFX4, ROMREGION_DISPOSE ) - ROM_LOAD( "bug30s.145", 0x0000, 0x8000, CRC(11d8e2a8) SHA1(9bf198229a12d331e8e7352b7ee3f39f6891f517) ) - ROM_LOAD( "bug23s.142", 0x8000, 0x8000, CRC(015db5d8) SHA1(39ef8b44f2eb9399fb1555cffa6763e06d59c181) ) + ROM_REGION( 0x40000, REGION_GFX2, 0 ) + ROM_LOAD( "bug26s.147", 0x00000, 0x8000, CRC(14033710) SHA1(e05afeb557ce14055fa8b4f6d8805307feaa1660) ) + ROM_LOAD( "bug19s.144", 0x08000, 0x8000, CRC(838e0697) SHA1(0e9aff2c4065d79350ddb55edff57a899c33ef1c) ) + ROM_LOAD( "bug28s.146", 0x10000, 0x8000, CRC(8b47d227) SHA1(a3e57594ad0085e8b1bd327c580eb36237f3e3d2) ) + ROM_LOAD( "bug21s.143", 0x18000, 0x8000, CRC(876a5666) SHA1(db485cdf35f63c080c919ee86374f63e577092c3) ) + ROM_LOAD( "bug30s.145", 0x20000, 0x8000, CRC(11d8e2a8) SHA1(9bf198229a12d331e8e7352b7ee3f39f6891f517) ) + ROM_LOAD( "bug23s.142", 0x28000, 0x8000, CRC(015db5d8) SHA1(39ef8b44f2eb9399fb1555cffa6763e06d59c181) ) /* Road */ - ROM_REGION( 0x40000, REGION_GFX6, 0) - ROM_LOAD( "bb3s", 0x000, 0x200, CRC(2ab3d5ff) SHA1(9f8359cb4ba2e7d15dbb9dc21cd71c0902cd2153) ) - ROM_LOAD( "bb4s", 0x200, 0x200, CRC(630f68a4) SHA1(d730f050353c688f81d090e33e00cd35e7b7b6fa) ) - ROM_LOAD( "bb5s", 0x400, 0x200, CRC(65925c9e) SHA1(d1ff1cb9f83c09e52a96632945e4edfedc335fd4) ) - ROM_LOAD( "bug11s.225", 0x1000, 0x4000, CRC(771af4e1) SHA1(a42b164dd0567c78c0d308ee48d63e5a284897bb) ) /* Road Lookup */ + ROM_REGION( 0x40000, REGION_GFX6, 0 ) + ROM_LOAD( "bug11s.225", 0x0000, 0x4000, CRC(771af4e1) SHA1(a42b164dd0567c78c0d308ee48d63e5a284897bb) ) + ROM_LOAD( "bb3s", 0x4000, 0x200, CRC(2ab3d5ff) SHA1(9f8359cb4ba2e7d15dbb9dc21cd71c0902cd2153) ) + ROM_LOAD( "bb4s", 0x4200, 0x200, CRC(630f68a4) SHA1(d730f050353c688f81d090e33e00cd35e7b7b6fa) ) + ROM_LOAD( "bb5s", 0x4400, 0x200, CRC(65925c9e) SHA1(d1ff1cb9f83c09e52a96632945e4edfedc335fd4) ) + ROM_LOAD( "bb6.224", 0x4600, 0x200, CRC(ad43e02a) SHA1(c50a398020508f52ddf8d45881f211d17d096fa1) ) /* Arithmetic Unit Function Data ROMs */ - ROM_REGION( 0x10000, REGION_USER1, 0 ) - ROM_LOAD( "bug9.138", 0x0800, 0x800, CRC(7d84135b) SHA1(3c669c4e796e83672aceeb6de1aeea28f9f2fef0) ) - ROM_CONTINUE( 0x1800, 0x800 ) - ROM_CONTINUE( 0x2800, 0x800 ) - ROM_CONTINUE( 0x3800, 0x800 ) - ROM_CONTINUE( 0x4800, 0x800 ) - ROM_CONTINUE( 0x5800, 0x800 ) - ROM_CONTINUE( 0x6800, 0x800 ) - ROM_CONTINUE( 0x7800, 0x800 ) + ROM_REGION( 0x10000, REGION_USER1, ROMREGION_LE ) + ROM_LOAD16_BYTE( "bug9.138", 0x0000, 0x4000, CRC(7d84135b) SHA1(3c669c4e796e83672aceeb6de1aeea28f9f2fef0) ) + ROM_LOAD16_BYTE( "bug10.95", 0x0001, 0x4000, CRC(b518dd6f) SHA1(7cefa2f9438306c81dc83cd260928c835eb9b712) ) + ROM_LOAD16_BYTE( "bb1.163", 0x8000, 0x0200, CRC(0ddbd36d) SHA1(7a08901a350c315d46ab8d0aa881db384b9f37d2) ) + ROM_LOAD16_BYTE( "bb2.162", 0x8001, 0x0200, CRC(71d47de1) SHA1(2da9aeb3f2ebb1114631c8042a37c4f4c18e741b) ) - ROM_LOAD( "bug10.95", 0x0000, 0x800, CRC(b518dd6f) SHA1(7cefa2f9438306c81dc83cd260928c835eb9b712) ) - ROM_CONTINUE( 0x1000, 0x800 ) - ROM_CONTINUE( 0x2000, 0x800 ) - ROM_CONTINUE( 0x3000, 0x800 ) - ROM_CONTINUE( 0x4000, 0x800 ) - ROM_CONTINUE( 0x5000, 0x800 ) - ROM_CONTINUE( 0x6000, 0x800 ) - ROM_CONTINUE( 0x7000, 0x800 ) - - ROM_REGION( 0x100000, REGION_USER2, 0 ) - ROM_LOAD( "bug16s.139", 0x0000, 0x8000, CRC(1903a9ad) SHA1(526c404c15e3f04b4afb27dee66e9deb0a6b9704) ) /* Object chunk sequence LUT */ - ROM_LOAD( "bug17s.140", 0x8000, 0x8000, CRC(82cabdd4) SHA1(94324fcf83c373621fc40553473ae3cb552ab704) ) /* Object chunk sequence LUT */ + /* Object chunk sequence LUT */ + ROM_REGION( 0x100000, REGION_USER2, 0 ) + ROM_LOAD( "bug16s.139", 0x0000, 0x8000, CRC(1903a9ad) SHA1(526c404c15e3f04b4afb27dee66e9deb0a6b9704) ) + ROM_LOAD( "bug17s.140", 0x8000, 0x8000, CRC(82cabdd4) SHA1(94324fcf83c373621fc40553473ae3cb552ab704) ) + /* Object LUT and palette LUT*/ ROM_REGION( 0x10000, REGION_USER3, 0 ) - ROM_LOAD( "bug13.32", 0x0000, 0x2000, CRC(53604d7a) SHA1(bfa304cd885162ece7a5f54988d9880fc541eb3a) ) /* Object LUT */ - ROM_LOAD( "bug18s.141", 0x2000, 0x4000, CRC(67786327) SHA1(32cc1f5bc654497c968ddcd4af29720c6d659482) ) /* Object palette LUT */ + ROM_LOAD( "bug13.32", 0x0000, 0x2000, CRC(53604d7a) SHA1(bfa304cd885162ece7a5f54988d9880fc541eb3a) ) + ROM_LOAD( "bug18s.141", 0x2000, 0x4000, CRC(67786327) SHA1(32cc1f5bc654497c968ddcd4af29720c6d659482) ) ROM_REGION( 0x10000, REGION_PROMS, 0 ) - ROM_LOAD( "bb10.41", 0x000, 0x100, CRC(f2368398) SHA1(53f28dba11bb494d033bb279abf138975c84b20d) ) /* RED */ - ROM_LOAD( "bb11.40", 0x100, 0x100, CRC(bf77f624) SHA1(b042d293d2094dbabb32d628fd9addd832f084ef) ) /* GREEN */ - ROM_LOAD( "bb12.39", 0x200, 0x100, CRC(10a2e8d1) SHA1(51a8c51ecbbb7bd04ae46fb5598d2c8de8097581) ) /* BLUE */ + /* RGBI */ + ROM_LOAD( "bb10.41", 0x000, 0x100, CRC(f2368398) SHA1(53f28dba11bb494d033bb279abf138975c84b20d) ) + ROM_LOAD( "bb11.40", 0x100, 0x100, CRC(bf77f624) SHA1(b042d293d2094dbabb32d628fd9addd832f084ef) ) + ROM_LOAD( "bb12.39", 0x200, 0x100, CRC(10a2e8d1) SHA1(51a8c51ecbbb7bd04ae46fb5598d2c8de8097581) ) ROM_LOAD( "bb13.42", 0x300, 0x100, CRC(40d10dfa) SHA1(e40b4c424827937fec6df1a27b19b8dc09d3274a) ) - ROM_LOAD( "bb14.19", 0x400, 0x100, CRC(0b821e0b) SHA1(b9401b9364fb99e15f562df91dcfdec1b989af2d) ) /* Character colour LUT */ - ROM_LOAD( "bb9.190", 0x500, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) /* Object colour LUT (odd) */ - ROM_LOAD( "bb9.162", 0xd00, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) /* Object colour LUT (even)*/ - ROM_LOAD( "bb7.188", 0x1500, 0x100, CRC(b57b609f) SHA1(2dea375437c62cb4c64b21d5e6ddc09397b6ab35) ) /* Road colour LUT */ + /* Character colour LUT */ + ROM_LOAD( "bb14.19", 0x400, 0x100, CRC(0b821e0b) SHA1(b9401b9364fb99e15f562df91dcfdec1b989af2d) ) - ROM_LOAD( "bb8.31", 0x1600, 0x100, CRC(2330ff4f) SHA1(e86eb63ce47572bcbbf325f9bb749d10d96bf2e7) ) /* Object tile LUT */ - ROM_LOAD( "bb1.163", 0x1700, 0x200, CRC(0ddbd36d) SHA1(7a08901a350c315d46ab8d0aa881db384b9f37d2) ) /* Arithmetic instruction PROM */ - ROM_LOAD( "bb2.162", 0x1900, 0x200, CRC(71d47de1) SHA1(2da9aeb3f2ebb1114631c8042a37c4f4c18e741b) ) /* Arithmetic instruction PROM */ - ROM_LOAD( "bb6.224", 0x1b00, 0x200, CRC(ad43e02a) SHA1(c50a398020508f52ddf8d45881f211d17d096fa1) ) /* Road video timing? */ + /* Object colour LUTs (odd and even pixels) */ + ROM_LOAD( "bb9.190", 0x500, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) + ROM_LOAD( "bb9.162", 0xd00, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) + + /* Object tile LUT */ + ROM_LOAD( "bb8.31", 0x1600, 0x100, CRC(2330ff4f) SHA1(e86eb63ce47572bcbbf325f9bb749d10d96bf2e7) ) + + /* Road */ + ROM_LOAD( "bb7.188", 0x1500, 0x100, CRC(b57b609f) SHA1(2dea375437c62cb4c64b21d5e6ddc09397b6ab35) ) ROM_END -/* 3 Monitor Version */ + ROM_START( buggyboy ) ROM_REGION( 0x100000, REGION_CPU1, 0 ) ROM_LOAD16_BYTE( "bug1a.230", 0x20000, 0x8000, CRC(92797c25) SHA1(8f7434abbd7f557d3202abb01b1e4899c82c67a5) ) @@ -1313,8 +1118,6 @@ ROM_START( buggyboy ) ROM_LOAD16_BYTE( "bug3b.232", 0xf8000, 0x4000, CRC(43cce3f0) SHA1(17de3728d809d386f6a7a330c8c8701975d4ebed) ) ROM_LOAD16_BYTE( "bug6b.175", 0xf8001, 0x4000, CRC(8f000dfa) SHA1(5fd78a03a00f547bbb431839f78a8d10a4ba8e3e) ) - ROM_LOAD16_BYTE( "bug35.11", 0x10000, 0x4000, CRC(7aa16e9e) SHA1(ea54e56270f70351a62a78fa32027bb41ef9861e) ) /* Z80 ROM - tested by main CPU */ - ROM_REGION( 0x100000, REGION_CPU2, 0 ) ROM_LOAD16_BYTE( "bug8a.061", 0x4000, 0x2000, CRC(512291cd) SHA1(60f87133c86b88b982ba4680f96d0ac55970cb8d) ) ROM_RELOAD( 0x8000, 0x2000 ) @@ -1326,87 +1129,70 @@ ROM_START( buggyboy ) ROM_RELOAD( 0xc001, 0x2000 ) ROM_RELOAD( 0xfc001, 0x2000 ) - ROM_REGION( 0x10000, REGION_CPU3, 0 ) /* Sound */ + ROM_REGION( 0x10000, REGION_CPU3, 0 ) ROM_LOAD( "bug35.11", 0x00000, 0x4000, CRC(7aa16e9e) SHA1(ea54e56270f70351a62a78fa32027bb41ef9861e) ) - /* 8x8 Characters */ ROM_REGION( 0x20000, REGION_GFX1, ROMREGION_DISPOSE ) ROM_LOAD( "bug34s.46", 0x00000, 0x4000, CRC(8ea8fec4) SHA1(75e67c9a59a86fcdedf2a70fafd303baa552aa18) ) ROM_LOAD( "bug33s.47", 0x04000, 0x4000, CRC(459c2b03) SHA1(ff62a86195042a349fbe799c638cf590fe9572bb) ) - /* 8x8 object chunks */ ROM_REGION( 0x40000, REGION_GFX2, ROMREGION_DISPOSE ) ROM_LOAD( "bug26s.147", 0x0000, 0x8000, CRC(14033710) SHA1(e05afeb557ce14055fa8b4f6d8805307feaa1660) ) ROM_LOAD( "bug19s.144", 0x8000, 0x8000, CRC(838e0697) SHA1(0e9aff2c4065d79350ddb55edff57a899c33ef1c) ) - /* 8x8 object chunks */ ROM_REGION( 0x40000, REGION_GFX3, ROMREGION_DISPOSE ) ROM_LOAD( "bug28s.146", 0x0000, 0x8000, CRC(8b47d227) SHA1(a3e57594ad0085e8b1bd327c580eb36237f3e3d2) ) ROM_LOAD( "bug21s.143", 0x8000, 0x8000, CRC(876a5666) SHA1(db485cdf35f63c080c919ee86374f63e577092c3) ) - /* 8x8 object chunks */ ROM_REGION( 0x40000, REGION_GFX4, ROMREGION_DISPOSE ) ROM_LOAD( "bug30s.145", 0x0000, 0x8000, CRC(11d8e2a8) SHA1(9bf198229a12d331e8e7352b7ee3f39f6891f517) ) ROM_LOAD( "bug23s.142", 0x8000, 0x8000, CRC(015db5d8) SHA1(39ef8b44f2eb9399fb1555cffa6763e06d59c181) ) - /* Object Lookups */ ROM_REGION( 0x40000, REGION_GFX5, ROMREGION_DISPOSE ) ROM_LOAD( "bug16s.139", 0x0000, 0x8000, CRC(1903a9ad) SHA1(526c404c15e3f04b4afb27dee66e9deb0a6b9704) ) ROM_LOAD( "bug17s.140", 0x8000, 0x8000, CRC(82cabdd4) SHA1(94324fcf83c373621fc40553473ae3cb552ab704) ) ROM_LOAD( "bug18s.141", 0x10000, 0x4000, CRC(67786327) SHA1(32cc1f5bc654497c968ddcd4af29720c6d659482) ) - /* Road */ ROM_REGION( 0x40000, REGION_GFX6, 0) ROM_LOAD( "bb3s", 0x000, 0x200, CRC(2ab3d5ff) SHA1(9f8359cb4ba2e7d15dbb9dc21cd71c0902cd2153) ) ROM_LOAD( "bb4s", 0x200, 0x200, CRC(630f68a4) SHA1(d730f050353c688f81d090e33e00cd35e7b7b6fa) ) ROM_LOAD( "bb5s", 0x400, 0x200, CRC(65925c9e) SHA1(d1ff1cb9f83c09e52a96632945e4edfedc335fd4) ) - ROM_LOAD( "bug11s.225", 0x1000, 0x4000, CRC(771af4e1) SHA1(a42b164dd0567c78c0d308ee48d63e5a284897bb) ) /* Road Lookup */ + ROM_LOAD( "bug11s.225", 0x1000, 0x4000, CRC(771af4e1) SHA1(a42b164dd0567c78c0d308ee48d63e5a284897bb) ) - /* Arithmetic Unit Function Data ROMs */ - ROM_REGION( 0x10000, REGION_USER1, 0 ) - ROM_LOAD( "bug9.138", 0x0800, 0x800, CRC(7d84135b) SHA1(3c669c4e796e83672aceeb6de1aeea28f9f2fef0) ) - ROM_CONTINUE( 0x1800, 0x800 ) - ROM_CONTINUE( 0x2800, 0x800 ) - ROM_CONTINUE( 0x3800, 0x800 ) - ROM_CONTINUE( 0x4800, 0x800 ) - ROM_CONTINUE( 0x5800, 0x800 ) - ROM_CONTINUE( 0x6800, 0x800 ) - ROM_CONTINUE( 0x7800, 0x800 ) - - ROM_LOAD( "bug10.95", 0x0000, 0x800, CRC(b518dd6f) SHA1(7cefa2f9438306c81dc83cd260928c835eb9b712) ) - ROM_CONTINUE( 0x1000, 0x800 ) - ROM_CONTINUE( 0x2000, 0x800 ) - ROM_CONTINUE( 0x3000, 0x800 ) - ROM_CONTINUE( 0x4000, 0x800 ) - ROM_CONTINUE( 0x5000, 0x800 ) - ROM_CONTINUE( 0x6000, 0x800 ) - ROM_CONTINUE( 0x7000, 0x800 ) + ROM_REGION( 0x10000, REGION_USER1, ROMREGION_LE ) + ROM_LOAD16_BYTE( "bug9.138", 0x0000, 0x4000, CRC(7d84135b) SHA1(3c669c4e796e83672aceeb6de1aeea28f9f2fef0) ) + ROM_LOAD16_BYTE( "bug10.95", 0x0001, 0x4000, CRC(b518dd6f) SHA1(7cefa2f9438306c81dc83cd260928c835eb9b712) ) + ROM_LOAD16_BYTE( "bb1.163", 0x8000, 0x0200, CRC(0ddbd36d) SHA1(7a08901a350c315d46ab8d0aa881db384b9f37d2) ) + ROM_LOAD16_BYTE( "bb2.162", 0x8001, 0x0200, CRC(71d47de1) SHA1(2da9aeb3f2ebb1114631c8042a37c4f4c18e741b) ) ROM_REGION( 0x100000, REGION_USER2, 0 ) - ROM_LOAD( "bug16s.139", 0x0000, 0x8000, CRC(1903a9ad) SHA1(526c404c15e3f04b4afb27dee66e9deb0a6b9704) ) /* Object chunk sequence LUT */ - ROM_LOAD( "bug17s.140", 0x8000, 0x8000, CRC(82cabdd4) SHA1(94324fcf83c373621fc40553473ae3cb552ab704) ) /* Object chunk sequence LUT */ + ROM_LOAD( "bug16s.139", 0x0000, 0x8000, CRC(1903a9ad) SHA1(526c404c15e3f04b4afb27dee66e9deb0a6b9704) ) + ROM_LOAD( "bug17s.140", 0x8000, 0x8000, CRC(82cabdd4) SHA1(94324fcf83c373621fc40553473ae3cb552ab704) ) ROM_REGION( 0x10000, REGION_USER3, 0 ) - ROM_LOAD( "bug13.32", 0x0000, 0x2000, CRC(53604d7a) SHA1(bfa304cd885162ece7a5f54988d9880fc541eb3a) ) /* Object LUT */ - ROM_LOAD( "bug18s.141", 0x2000, 0x4000, CRC(67786327) SHA1(32cc1f5bc654497c968ddcd4af29720c6d659482) ) /* Object palette LUT */ + ROM_LOAD( "bug13.32", 0x0000, 0x2000, CRC(53604d7a) SHA1(bfa304cd885162ece7a5f54988d9880fc541eb3a) ) + ROM_LOAD( "bug18s.141", 0x2000, 0x4000, CRC(67786327) SHA1(32cc1f5bc654497c968ddcd4af29720c6d659482) ) ROM_REGION( 0x10000, REGION_PROMS, 0 ) - ROM_LOAD( "bb10.41", 0x000, 0x100, CRC(f2368398) SHA1(53f28dba11bb494d033bb279abf138975c84b20d) ) /* RED */ - ROM_LOAD( "bb11.40", 0x100, 0x100, CRC(bf77f624) SHA1(b042d293d2094dbabb32d628fd9addd832f084ef) ) /* GREEN */ - ROM_LOAD( "bb12.39", 0x200, 0x100, CRC(10a2e8d1) SHA1(51a8c51ecbbb7bd04ae46fb5598d2c8de8097581) ) /* BLUE */ + ROM_LOAD( "bb10.41", 0x000, 0x100, CRC(f2368398) SHA1(53f28dba11bb494d033bb279abf138975c84b20d) ) + ROM_LOAD( "bb11.40", 0x100, 0x100, CRC(bf77f624) SHA1(b042d293d2094dbabb32d628fd9addd832f084ef) ) + ROM_LOAD( "bb12.39", 0x200, 0x100, CRC(10a2e8d1) SHA1(51a8c51ecbbb7bd04ae46fb5598d2c8de8097581) ) ROM_LOAD( "bb13.42", 0x300, 0x100, CRC(40d10dfa) SHA1(e40b4c424827937fec6df1a27b19b8dc09d3274a) ) - ROM_LOAD( "bb14.19", 0x400, 0x100, CRC(0b821e0b) SHA1(b9401b9364fb99e15f562df91dcfdec1b989af2d) ) /* Character colour LUT */ + ROM_LOAD( "bb14.19", 0x400, 0x100, CRC(0b821e0b) SHA1(b9401b9364fb99e15f562df91dcfdec1b989af2d) ) - ROM_LOAD( "bb9.190", 0x500, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) /* Object colour LUT (odd) */ - ROM_LOAD( "bb9.162", 0xd00, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) /* Object colour LUT (even)*/ - ROM_LOAD( "bb7.188", 0x1500,0x100, CRC(b57b609f) SHA1(2dea375437c62cb4c64b21d5e6ddc09397b6ab35) ) /* Road colour LUT */ - - ROM_LOAD( "bb8.31", 0x1600, 0x100, CRC(2330ff4f) SHA1(e86eb63ce47572bcbbf325f9bb749d10d96bf2e7) ) /* Object tile LUT */ - ROM_LOAD( "bb1.163", 0x1700, 0x200, CRC(0ddbd36d) SHA1(7a08901a350c315d46ab8d0aa881db384b9f37d2) ) /* Arithmetic instruction PROM */ - ROM_LOAD( "bb2.162", 0x1900, 0x200, CRC(71d47de1) SHA1(2da9aeb3f2ebb1114631c8042a37c4f4c18e741b) ) /* Arithmetic instruction PROM */ + ROM_LOAD( "bb9.190", 0x500, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) + ROM_LOAD( "bb9.162", 0xd00, 0x800, CRC(6fc807d1) SHA1(3442cbb21bbedf6291a3fe1747d479445f613d26) ) + ROM_LOAD( "bb7.188", 0x1500,0x100, CRC(b57b609f) SHA1(2dea375437c62cb4c64b21d5e6ddc09397b6ab35) ) + ROM_LOAD( "bb8.31", 0x1600, 0x100, CRC(2330ff4f) SHA1(e86eb63ce47572bcbbf325f9bb749d10d96bf2e7) ) ROM_END -GAME( 1983, tx1, 0, tx1, tx1, 0, ROT0, "Tazmi", "TX-1", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) -GAME( 1983, tx1a, 0, tx1, tx1, 0, ROT0, "Tazmi", "TX-1 (Atari/Namco/Taito License)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) -GAME( 1985, buggyboy, buggyb1, buggyboy, buggyboy, 0, ROT0, "Tatsumi", "Buggy Boy", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) -GAME( 1986, buggyb1, 0, buggyb1, buggyb1, 0, ROT0, "Tatsumi", "Buggy Boy (Single Monitor)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) +/************************************* + * + * Game driver(s) + * + *************************************/ + +GAME( 1983, tx1, 0, tx1, tx1, 0, ROT0, "Tatsumi", "TX-1", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) +GAME( 1983, tx1a, tx1, tx1, tx1, 0, ROT0, "Tatsumi", "TX-1 (Atari/Namco/Taito License)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) +GAME( 1985, buggyboy, buggybjr, buggyboy, buggyboy, 0, ROT0, "Tatsumi", "Buggy Boy", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) +GAME( 1986, buggybjr, 0, buggybjr, buggybjr, 0, ROT0, "Tatsumi", "Buggy Boy Junior", 0 ) diff --git a/src/mame/includes/tx1.h b/src/mame/includes/tx1.h new file mode 100644 index 00000000000..b027bdf724f --- /dev/null +++ b/src/mame/includes/tx1.h @@ -0,0 +1,106 @@ +/************************************************************************* + + TX-1/Buggy Boy hardware + +*************************************************************************/ +#include "machine/8255ppi.h" +#include "sound/custom.h" + +#define TX1_PIXEL_CLOCK 6000000 +#define TX1_HBSTART 256 +#define TX1_HBEND 0 +#define TX1_HTOTAL 384 +#define TX1_VBSTART 240 +#define TX1_VBEND 0 +#define TX1_VTOTAL 264 + +#define BB_PIXEL_CLOCK 6000000 +#define BB_HBSTART 256 +#define BB_HBEND 0 +#define BB_HTOTAL 384 +#define BB_VBSTART 240 +#define BB_VBEND 0 +#define BB_VTOTAL 288 + +/* Buggy Boy PCBs could use 8086s or V30s */ +#define BUGGYBOY_CPU_TYPE I8086 +#define BUGGYBOY_ZCLK 7500000 + + +/*----------- defined in drivers/tx1.c -----------*/ +extern UINT16 *tx1_math_ram; +extern ppi8255_interface tx1_ppi8255_intf; +extern ppi8255_interface buggyboy_ppi8255_intf; + +/*----------- defined in machine/tx1.c -----------*/ +READ16_HANDLER( tx1_spcs_rom_r ); +READ16_HANDLER( tx1_spcs_ram_r ); +WRITE16_HANDLER( tx1_spcs_ram_w ); +READ16_HANDLER( tx1_math_r ); +WRITE16_HANDLER( tx1_math_w ); +MACHINE_START( tx1 ); +MACHINE_RESET( tx1 ); + + +READ16_HANDLER( buggyboy_spcs_rom_r ); +READ16_HANDLER( buggyboy_spcs_ram_r ); +WRITE16_HANDLER( buggyboy_spcs_ram_w ); +READ16_HANDLER( buggyboy_math_r ); +WRITE16_HANDLER( buggyboy_math_w ); +MACHINE_RESET( buggybjr ); +MACHINE_RESET( buggyboy ); +MACHINE_START( buggybjr ); +MACHINE_START( buggyboy ); + +/*----------- defined in audio/tx1.c -----------*/ +READ8_HANDLER( pit8253_r ); +WRITE8_HANDLER( pit8253_w ); + +WRITE8_HANDLER( bb_ym1_a_w ); +WRITE8_HANDLER( bb_ym1_b_w ); +void *buggyboy_sh_start(int clock, const struct CustomSound_interface *config); +void buggyboy_sh_reset(void *token); + +void *tx1_sh_start(int clock, const struct CustomSound_interface *config); +void tx1_sh_reset(void *token); + + +/*----------- defined in video/tx1.c -----------*/ +READ16_HANDLER( tx1_crtc_r ); +WRITE16_HANDLER( tx1_crtc_w ); + +extern UINT16 *tx1_vram; +extern UINT16 *tx1_objram; +extern UINT16 *tx1_rcram; +extern size_t tx1_objram_size; +PALETTE_INIT( tx1 ); +WRITE16_HANDLER( tx1_vram_w ); +VIDEO_START( tx1 ); +VIDEO_UPDATE( tx1 ); +VIDEO_EOF( tx1 ); +WRITE16_HANDLER( tx1_slincs_w ); +WRITE16_HANDLER( tx1_slock_w ); +WRITE16_HANDLER( tx1_scolst_w ); +WRITE16_HANDLER( tx1_bankcs_w ); +WRITE16_HANDLER( tx1_flgcs_w ); + +extern UINT16 *buggyboy_objram; +extern UINT16 *buggyboy_rcram; +extern UINT16 *buggyboy_vram; +extern size_t buggyboy_objram_size; +extern size_t buggyboy_rcram_size; +PALETTE_INIT( buggyboy ); +WRITE16_HANDLER( buggyboy_vram_w ); +VIDEO_START( buggyboy ); +VIDEO_UPDATE( buggyboy ); +VIDEO_EOF( buggyboy ); + +extern UINT16 *buggybjr_vram; +PALETTE_INIT( buggybjr ); +WRITE16_HANDLER( buggybjr_vram_w ); +VIDEO_START( buggybjr ); +VIDEO_UPDATE( buggybjr ); +WRITE16_HANDLER( buggyboy_slincs_w ); +WRITE16_HANDLER( buggyboy_scolst_w ); +WRITE16_HANDLER( buggyboy_gas_w ); +WRITE16_HANDLER( buggyboy_sky_w ); diff --git a/src/mame/machine/tx1.c b/src/mame/machine/tx1.c index 0b1930d7014..e71fffedab7 100644 --- a/src/mame/machine/tx1.c +++ b/src/mame/machine/tx1.c @@ -1,679 +1,1453 @@ -/*===================================================================*/ -/* TX-1/Buggy Boy (Tatsumi) Hardware */ -/* SN74S516 Arithmetic Unit and Interface Emulation */ -/* VERY PRELIMINARY! */ -/*===================================================================*/ +/*************************************************************************** + Tatsumi TX-1/Buggy Boy machine hardware + +***************************************************************************/ #include "driver.h" - -static INT16 AU_DATA; -static INT16 *const AU_PTR = &AU_DATA; -static UINT16 inst_index; - -/* Internal registers and so forth */ -static struct Regs -{ - INT16 X; /* Multiplicand and divisor */ - INT16 X1; /* Previous X */ - INT16 Y; /* Multiplier */ - - INT16 Operand2; - - union /* 32-bit accumulator */ - { - #ifdef LSB_FIRST - struct { UINT16 W; INT16 Z;} ZW_16; - #else - struct { INT16 Z; UINT16 W;} ZW_16; - #endif - INT32 ZW_32; - } acc; - - INT16 ins_seq; /* Instruciton sequence */ -} AU_Regs; - - -/* Main portion of the arithmetic unit emulation. Accessed by AU_R and AU_W */ -/* Only a few instructions implemented currently */ - -static void MMI_74S516(int ins, UINT16 *data) -{ - - if ((ins!=7) && ((AU_Regs.ins_seq & 0xf)==7)) /* If last instruction was a reading operation, clear sequence. */ - AU_Regs.ins_seq = 0; - - /* Take INS and append to instruction */ - AU_Regs.ins_seq <<=4; - AU_Regs.ins_seq = AU_Regs.ins_seq | (ins & 0xf); - - switch ( AU_Regs.ins_seq ) - { - /* X1 . Y */ - case 0x0: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* -X1 . Y */ - case 0x1: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* X1 . Y + Kz.Kw */ - case 0x2: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* -X1 . Y + Kz.Kw */ - case 0x3: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* Partial: Load X */ - case 0x5: AU_Regs.X = *data; - break; - case 0x6: AU_Regs.X = *data; - break; - - - /* X * Y (Fractional) */ - case 0x50: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* X * Y (Integer) */ // Ok - case 0x60: AU_Regs.Y = *data; - AU_Regs.acc.ZW_32 = ((INT16)AU_Regs.X * (INT16)AU_Regs.Y); - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - /* -X * Y (Fractional) */ - case 0x51: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* -X * Y (Integer) */ // Ok - case 0x61: AU_Regs.Y = *data; - AU_Regs.acc.ZW_32 = (-(INT16)AU_Regs.X * (INT16)AU_Regs.Y); - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - - /* X * Y + Kz.Kw (Fractional) */ - case 0x52: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* X * Y + Kz.Kw (Integer) */ // Ok - case 0x62: AU_Regs.Y = *data; - AU_Regs.acc.ZW_32 += ((INT16)AU_Regs.X * (INT16)AU_Regs.Y); - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - - /* -X * Y + Kz.Kw (Fractional) */ - case 0x53: AU_Regs.Y = *data; - AU_Regs.ins_seq = 0; - break; - - /* -X * Y + Kz.Kw (Integer) */ // Ok - case 0x63: AU_Regs.Y = *data; - AU_Regs.acc.ZW_32 += (-(INT16)AU_Regs.X * (INT16)AU_Regs.Y); - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - - - /* Kw / X (Fractional) Nothing Loaded */ - case 0x54: AU_Regs.ins_seq = 0; - break; - - /* Kw / X (Integer) Nothing Loaded */ - case 0x64: AU_Regs.acc.ZW_32 /= (INT16)AU_Regs.X; - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - /* Kz / X (Fractional) Nothing Loaded */ - case 0x55: AU_Regs.ins_seq = 0; - break; - - - /* Kz / X (Integer) Nothing Loaded */ - case 0x65: AU_Regs.acc.ZW_32=AU_Regs.ins_seq; - AU_Regs.ins_seq=0; - break; - - - /* This can either load Z,Nothing or 0? */ - case 0x56: AU_Regs.Operand2 = *data; - break; - - - case 0x560: AU_Regs.ins_seq = 0; - break; - - case 0x561: AU_Regs.ins_seq = 0; - break; - - case 0x562: AU_Regs.ins_seq = 0; - break; - - case 0x563: AU_Regs.ins_seq = 0; - break; - - case 0x564: AU_Regs.ins_seq = 0; - break; - - case 0x565: AU_Regs.ins_seq = 0; - break; - - // Not complete instruction - case 0x566: - AU_Regs.ins_seq = 0; - break; - - - case 0x660: AU_Regs.ins_seq = 0; - break; - - case 0x661: AU_Regs.ins_seq = 0; - break; - - case 0x662: AU_Regs.ins_seq = 0; - break; - - case 0x663: AU_Regs.ins_seq = 0; - break; - - /* Z,W /X */ - // result in Z, remainder in W - case 0x664: AU_Regs.acc.ZW_16.W = *data; - AU_Regs.acc.ZW_16.Z = AU_Regs.Operand2; - AU_Regs.acc.ZW_16.Z = (INT16)((INT32)AU_Regs.acc.ZW_32 / (INT16)AU_Regs.X); // wrong :( - AU_Regs.acc.ZW_16.W = (INT16)((INT32)AU_Regs.acc.ZW_32 % (INT16)AU_Regs.X); //correct! - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - case 0x665: AU_Regs.ins_seq = 0; - break; - - case 0x5660:AU_Regs.ins_seq = 0; - break; - - case 0x5661:AU_Regs.ins_seq = 0; - break; - - case 0x5662:AU_Regs.ins_seq = 0; - break; - - case 0x5663:AU_Regs.ins_seq = 0; - break; - - case 0x5664:AU_Regs.ins_seq = 0; - break; - - case 0x5665:AU_Regs.ins_seq = 0; - break; - - case 0x5666:AU_Regs.ins_seq = 0; - break; - - case 0x5667:AU_Regs.ins_seq = 0; - break; - - case 0x6660:AU_Regs.ins_seq = 0; - break; - - case 0x6661:AU_Regs.ins_seq = 0; - break; - - case 0x6662:AU_Regs.ins_seq = 0; - break; - - case 0x6663:AU_Regs.ins_seq = 0; - break; - - /* W/X */ - case 0x6664:AU_Regs.acc.ZW_32 = (INT16)AU_Regs.acc.ZW_16.W / (INT16)AU_Regs.X; - AU_Regs.X1 = AU_Regs.X; - AU_Regs.ins_seq = 0; - break; - - case 0x6665: - AU_Regs.ins_seq = 0; - break; - - case 0x6666: - AU_Regs.ins_seq = 0; - break; - - case 0x6667: - AU_Regs.ins_seq = 0; - break; - - case 0x66: AU_Regs.Operand2 = *data; - break; - - case 0x4: AU_Regs.ins_seq = 0; - break; - - /* Reading Operations */ - - case 0x7: *data = AU_Regs.acc.ZW_16.Z; - break; - - case 0x77: *data = AU_Regs.acc.ZW_16.W; - break; - - case 0x777: *data = AU_Regs.acc.ZW_16.Z; - break; - - case 0x7777: *data = AU_Regs.acc.ZW_16.W; - break; - - default: break; - } - -} - - - -/******************************************************/ -/* */ -/* MMI SN74S516T Arithmetic Unit and Interface */ -/* */ -/******************************************************/ +#include "debugger.h" +#include "machine/8255ppi.h" +#include "tx1.h" /* -The arithmetic unit is used extensively to calculate both object and road attributes in both games. -It can take instructions directly from slave address bus A1-A3 or from a pair of PROMS (BB1.163 and BB2.162). -Two 16KB function data ROMs are accessible by the chip and the slave CPU (via a hardware index and pointer). - -The interface between the arithmetic unit and the slave CPU is different between Buggy Boy and TX-1. - -In the case of an Buggy Boy PCB: -Without AU: No objects visible, road is unchanging in direction. -Without instruction PROMS: Hand/Go is displayed correctly as well as the end of race animation sequence (buggy spins and goes up in smoke). - -Therfore, once enough simple instructions are implemented, it should be possible do display some objects correctly. - -/MLPCS = !A10.!A11.A12.A13.!A14.!A15 -/DPRCS = A10.A11.A12.A13.!A14.!A15 -/INSALD = /AT3RD.!AT3WDRART + !AT3WDRART.A15 + !AT3WDRART.!A13 + !AT3WDRART.A14 + !AT3WDRART.!A12 + !A8 -/CNTST = /AT3RD.!AT3WDRART + !AT3WDRART.A15 + !AT3WDRART.!A13 + !AT3WDRART.A14 + !AT3WDRART.!A12 + !A7 -/SPCS = !A15.!A14.!A13.A12 + A14.!A13.!A12 + !A14.A12.A9 + !A14.A13.!A12 + !A14.!A11 + A15 - -3000-31ff = Direct instruction input (AAB1-AAB3 connect to I0-2 of AU). - -3c00-3cff -3d00-3dff -3e00-3eff -3f00-3fff = DATA ROM output enable. - -/SPCS = 0800-0fff - 3800-39ff - 3c00-3dff - 5000-7fff - - -When CPU A8=1, the counters are loaded with an address (e.g. [3754] and [3120]). - -The counters are enabled on: - -* A7=1 (e.g. [3680] and [3A80]). -* Read access to locations asserting /SPCS (e.g. [7a72] - those ROM mirror accesses have some significance afterall!) -* BB2.162 bit 7 = 0 (/CUDEN). - -Writes to [36XX] and [37XX] load a value into the AU ROM address shift-registers . -Reads from [36XX] (and [37xx] presumably) returns this value. -Writes to [3A00] loads a shift value/direction. - -The AU ROM address shifting is governed by DSEL0-1 (BB2.162): - -00 = Invalid -01 = >> 4 -10 = << 4 -11 = Shift direction and magnitude specified by 4-bit data value written to [3A00]: - A13-11 = 000 -> << by A10-7 - A13-11 != 000 -> >> by A13-11 (LSB=0) - - The shift magnitude is specified by the number of number of 0s between the LSB (inclusive) and the '1'. Shifting is circular. - -Examples: - -13 [3754] <- 2DB5 - [3A00] <- 0100 - [3600] == B6D4 ? // 0x2DB5 << 2 == 0xB6D4 - -14 [3600] <- 2DB5 - [3A00] <- 0200 - [3600] == 5B6A ? // 0x2DB5 << 1 == 0x5B6A - -15 [3600] <- 2DB5 - [3A00] <- 0400 - [3600] == 2DB5 // No shift. - -16 [3600] <- 2DB5 - [3A00] <- 0800 - [3600] == 96DA ? // 0x2DB5 >> 1 == 0x96DA - -17 [3600] <- 2DB5 - [3A00] <- 1000 - [3600] = 4B6D ? // 0x2DB5 >> 2 == 0x4B6D - -18 [3600] <- 2DB5 - [3A00] <- 2000 - [3600] = A5B6 ? // 0x2DB5 >> 3 == 0xA5B6 - -19 [3600] <- 1568 - [3A00] <- 2000 - [3E00] = 1BF2 ? // 0x1568 >> 3 == 0x02AD -> AU_ROM[0x02AD] == 0x1BF2 - - -The 14-bit AU ROM address is formed from: - -A13-11 = TFAD13-11 (BB2.162 D4-2) -A10-8 = If RADCHG = 1: AU PROM address bits 7-5 - If RADCHG = 0: Bits 10-8 of shift registers -A7-0 = Bits 7-0 of shift registers. - -The current implementation of accessing the AU ROM is wrong (it's based on software behaviour rather than the actual hardware ) - -Here's the full list of AU tests performed during test mode: - -ST - [300C] <- AA55 - [3000] <- 55AA -04 [300E] = E355 ? -04 [300E] = 5572 ? - - [300C] <- AA55 - [3002] <- 55AA -05 [300E] = 1CAA ? -05 [300E] = AA8E ? - - [300C] <- 5A5A - [3004] <- A5A5 -06 [300E] = FCC6 ? -06 [300E] = E890 ? - - [300C] <- AA55 - [3006] <- 55AA -07 [300E] = 1971 ? -07 [300E] = 931E ? - - [300C] <- 1000 - [300C] <- 5678 - [3008] <- 8765 -08 [300E] = ff88 ? -08 [300E] = 0765 ? - - [300C] <- 0200 - [300C] <- FFFF - [300C] <- 55AA - [3008] <- FFFF -09 [300E] = 002a ? -09 [300E] = 01aa ? - - [3752] <- AA55 -10 [3600] = AA55 ? - - [3600] <- 55AA -10 [3680] = 55AA ? - -11 [3680] = A55A ? -12 [3600] = 55AA ? - - [3754] <- 2DB5 - [3A00] <- 0100 -13 [3600] = B6D4 ? - - [3600] <- 2DB5 - [3A00] <- 0200 -14 [3600] = 5B6A ? - -15 [3600] <- 2DB5 - [3A00] <- 0400 - [3600] = 2DB5 ? - -16 [3600] <- 2DB5 - [3A00] <- 0800 - [3600] = 96DA ? - -17 [3600] <- 2DB5 - [3A00] <- 1000 - [3600] = 4B6D ? - -18 [3600] <- 2DB5 - [3A00] <- 2000 - [3600] = A5B6 ? - -19 [3600] <- 1568 - [3A00] <- 2000 - [3E00] = 1BF2 ? - -1A [7A68] = 0000 ? - -1B [3680] <- AA55 - [7A6A] = 55AA ? - -1C [3200] <- AA55 - [300E] = E355 ? - -1D [3754] <- AA55 - [7A6A] = 55AA ? - -1E [3680] <- AA55 - [7A6A] = 55AA ? - -1F [7A6C] = AA55 ? - -20 [300E] = 1CAA ? - -21 [300C] <- 55AA - [3200] <- AA55 - [300E] = E355 ? - -22 [3E00] = 14D5 ? -23 [308C] <- 55AA - [7A70] = 15AA ? - -24 [7A6E] = 2000 ? -25 [3600] = 42B5 ? -26 [3E80] = 1CC2 ? -27 [308E] = 099F ? -28 [3680] = 4099 ? -29 [3680] = 2D40 ? -2A [3C00] = 5Cf4 ? -2B [3600] = 5Cf4 ? -2C [300C] <- 55AA - [3A80] = FFFF ? -2D [300E] = FFFF ? -2E [300E] = AA56 ? - [3600] <- 0000 -2F [4000] = 00BC ? -30 [3600] = 0000 ? - - [310C] <- 0078 - [308C] <- 3F70 -40 [3680] = 0087 ? - - [3600] <- 0020 -41 [3680] = 0100 ? - - [3680] <- 533f -42 [300e] = 0058 ? - - [315c] <- 0020 -43 [7a72] = 0087 ? - -44 [3700] = 0080 ? - - [300c] <- 00cc - [3000] <- 0074 -45 [308e] = 0000 ? - -46 [7a74] = 0078 ? - [308c] <- 0000 -47 [300e] = 00c5 ? - - [300c] <- 0074 - [3000] <- 008c -48 [311e] = 0000 ? - - [300c] <- 0224 - [308c] <- 0000 -49 [300e] = 001c ? - - [3724] <- 000c - [3000] <- 0078 -4a [300e] = 007c - - [3728] <- 0023 -4b [3e80] = 0055 ? -4c [3e00] = 0045 ? - - [3600] <- fca2 - [313c] <- 0118 - [308c] <- ff42 -4d [300e] = 007e ? - - [312c] <- 0040 - [308c] <- 00f8 -4e [300e] = 0080 ? - - [300c] <- 0261 - [3130] <- 2000 -4f [3680] = 004c ? - - [300c] <- 000f - [3008] <- e440 -50 [300e] = 0111 ? - -51 [7a7a] = 41fd ? - [3740] <- 010e - -52 [7a76] = 4000 ? -53 [7a78] = 03a9 ? - - [3280] <- 0800 -54 [3e00] = ff52 ? - - [3680] <- 001e -55 [3680] = ffcd ? - -56 [3600] = fff0 ? - - [314c] <- 0091 - [3680] <- 0300 - -57 [3680] = 015e ? - - [3680] <- 00d5 - [3704] <- 0002 -58 [3600] = 0015 ? - - [3600] <- 0086 - [317c] <- 0013 -59 [300e] = 09f2 ? - - [300c] <- 0010 - [3120] <- 011c -5a [300e] = 11c0 ? + 6845 cursor output is connected to the main CPU interrupt pin. + The CRTC is programmed to provide a rudimentary VBLANK interrupt. + TODO: Calc TX-1 values... */ +#define CURSOR_YPOS 239 +#define CURSOR_XPOS 168 -READ16_HANDLER(BB_AU_R) + +/* + Globals +*/ +static UINT16 *prom; + +static struct { -UINT8 *AU_instr = (UINT8 *)memory_region(REGION_USER1); -//UINT8 *AU_PROM1 = (UINT8 *)memory_region(REGION_PROMS) + 0x1700; -//UINT8 *AU_PROM2 = (UINT8 *)memory_region(REGION_PROMS) + 0x1900; + UINT16 cpulatch; + UINT16 promaddr; + UINT16 inslatch; + UINT32 mux; + UINT16 ppshift; + UINT32 i0ff; -INT16 value = 0; + UINT16 retval; - switch (offset) - { - case 0x0: - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: MMI_74S516(offset, (UINT16*)AU_PTR); /* Typically Instruction 7 - read result(s) */ - value = *AU_PTR; - break; + UINT16 muxlatch; // TX-1 - case 0x0e00/2: value = AU_instr[inst_index] | (AU_instr[inst_index] << 8); - break; + int dbgaddr; + int dbgpc; +} math; - case 0x0680/2: - break; /* Use to change upper ROM address portion? */ +/* + Helper functions +*/ +#define INC_PROM_ADDR ( math.promaddr = (math.promaddr + 1) & 0x1ff ) +#define ROR16(val, shift) ( ((UINT16)val >> shift) | ((UINT16)val << (16 - shift)) ) +#define ROL16(val, shift) ( ((UINT16)val << shift) | ((UINT16)val >> (16 - shift)) ) +#define SWAP16(val) ( (((UINT16)val << 8) & 0xff00) | ((UINT16)val >> 8) ) - case 0x0726/2: - break; +INLINE UINT8 reverse_nibble(UINT8 nibble) +{ + return (nibble & 1) << 3 | + (nibble & 2) << 1 | + (nibble & 4) >> 1 | + (nibble & 8) >> 3; +} - default: value = 0; - break; - } - return value; + +/* + TODO: Check interrupt timing from CRT config. Probably different between games. +*/ +static TIMER_CALLBACK( interrupt_callback ) +{ + cpunum_set_input_line_and_vector(0, 0, HOLD_LINE, 0xff); + timer_set(video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), NULL, 0, interrupt_callback); +} + +/* + SN74S516 16x16 Multiplier/Divider +*/ +static struct +{ + INT16 X; + INT16 Y; + + union + { + #ifdef LSB_FIRST + struct { UINT16 W; INT16 Z; }; + #else + struct { INT16 Z; UINT16 W; }; + #endif + INT32 ZW32; + } ZW; + + int code; + int state; + int ZWfl; +} SN74S516; + +/* + State transition table + + A little different to the real thing in that + there are no states between final input and + multiplication/division. +*/ +static const UINT8 state_table[16][8] = +{ + { 4, 4, 4, 4, 5, 1, 1, 0 }, + { 4, 4, 4, 4, 5, 5, 3, 0 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { 4, 4, 4, 4, 5, 5, 11, 0 }, + { 8, 8, 8, 8, 8, 8, 8, 8 }, + { 10, 10, 10, 10, 10, 10, 10, 10 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { 4, 4, 4, 4, 5, 0, 1, 0 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { 4, 4, 4, 4, 4, 5, 1, 0 }, + { 4, 4, 4, 4, 5, 5, 1, 0 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1 }, +}; + +static void sn_multiply(void) +{ + switch (SN74S516.code) + { + case 0: + { + SN74S516.ZW.ZW32 = SN74S516.X * SN74S516.Y; + break; + } + case 2: + { + SN74S516.ZW.ZW32 += SN74S516.X * SN74S516.Y; + break; + } + case 3: + { + SN74S516.ZW.ZW32 += -SN74S516.X * SN74S516.Y; + break; + } + case 0x60: + { + SN74S516.ZW.ZW32 = SN74S516.X * SN74S516.Y; + break; + } + case 0x61: + { + SN74S516.ZW.ZW32 = -SN74S516.X * SN74S516.Y; + break; + } + case 0x62: + { + SN74S516.ZW.ZW32 += SN74S516.X * SN74S516.Y; + break; + } + case 0x63: + { + SN74S516.ZW.ZW32 += -SN74S516.X * SN74S516.Y; + break; + } + case 0x660: + { + SN74S516.ZW.ZW32 = (SN74S516.X * SN74S516.Y) + (SN74S516.ZW.ZW32 & 0xffff0000); + break; + } + case 0x661: + { + SN74S516.ZW.ZW32 = (-SN74S516.X * SN74S516.Y) + (SN74S516.ZW.ZW32 & 0xffff0000); + break; + } + case 0x662: + { + SN74S516.ZW.ZW32 = (-SN74S516.X * SN74S516.Y) + (SN74S516.ZW.ZW32 & 0xffff0000); + break; + } + case 0x6660: + { + SN74S516.ZW.ZW32 += (SN74S516.X * SN74S516.Y); + break; + } + default: + { + mame_printf_debug("sn74s516 ??? multiply: %x\n", SN74S516.code); + } + } + + /* Seems a good enough place to clear it. */ + SN74S516.ZWfl = 0; +} + +static void sn_divide(void) +{ + INT32 Z = 0; + INT32 W = 0; + + if ( SN74S516.X == 0 ) + fatalerror("SN74S516 tried to divide by zero (PC=%x)\n", activecpu_get_pc()); + + switch ( SN74S516.code ) + { + case 4: + { + Z = SN74S516.ZW.ZW32 / SN74S516.X; + W = SN74S516.ZW.ZW32 % SN74S516.X; + break; + } + case 0x664: + { + Z = SN74S516.ZW.ZW32 / SN74S516.X; + W = SN74S516.ZW.ZW32 % SN74S516.X; + break; + } + case 0x6664: + { + Z = SN74S516.ZW.W / SN74S516.X; + W = SN74S516.ZW.W % SN74S516.X; + break; + } + default: + { + mame_printf_debug("SN74S516 unhandled divide type: %x\n", SN74S516.code); + } + } + + /* Divide overflow Only happens during chip test anyway */ + if ( Z > 0xffff ) + Z |= 0xff00; + + SN74S516.ZW.Z = Z; + SN74S516.ZW.W = W; + SN74S516.ZWfl = 0; +} + +void sn74s516_update(const int ins) +{ + SN74S516.state = state_table[SN74S516.state][ins]; + + if ( SN74S516.state == 4 ) + { + sn_multiply(); + SN74S516.state = 8; + } + else if ( SN74S516.state == 5 ) + { + sn_divide(); + SN74S516.state = 10; + } +} + +static void kick_sn74s516(UINT16 *data, const int ins) +{ + +#define LOAD_X (SN74S516.X = *data) +#define LOAD_Y (SN74S516.Y = *data) +#define LOAD_Z (SN74S516.ZW.Z = *data) +#define LOAD_W (SN74S516.ZW.W = *data) +#define READ_ZW *data = SN74S516.ZWfl ? SN74S516.ZW.W : SN74S516.ZW.Z; \ + SN74S516.ZWfl ^= 1; + +#define UPDATE_SEQUENCE (SN74S516.code = (SN74S516.code << 4) | ins) +#define CLEAR_SEQUENCE (SN74S516.code = 0) + + /* + Remember to change the Z/W flag. + */ + switch (SN74S516.state) + { + case 0: + { + CLEAR_SEQUENCE; + UPDATE_SEQUENCE; + + if (ins < 4) + { + LOAD_Y; + sn74s516_update(ins); + } + else if (ins == 4) + { + sn74s516_update(ins); + } + else if (ins < 7) + { + LOAD_X; + sn74s516_update(ins); + } + else if (ins == 7) + { + READ_ZW; + break; + } + + break; + } + case 8: + case 10: + { + CLEAR_SEQUENCE; + UPDATE_SEQUENCE; + + if (ins < 4) + { + LOAD_Y; + sn74s516_update(ins); + } + else if (ins == 4) + { + sn74s516_update(ins); + } + else if (ins == 5) + { + // Rounding + // Operation + sn74s516_update(ins); + } + else if (ins == 6) + { + LOAD_X; + sn74s516_update(ins); + } + else if (ins == 7) + { + READ_ZW; + sn74s516_update(ins); + } + break; + } + case 1: + { + // TODO: 6666 represents an incomplete state - clear it. + if (SN74S516.code == 0x6666) + { + CLEAR_SEQUENCE; + mame_printf_debug("Code 6666: PROMADDR:%x PC:%x\n", math.promaddr, activecpu_get_pc()); + } + + UPDATE_SEQUENCE; + if (ins < 4) + { + LOAD_Y; + sn74s516_update(ins); + } + else if (ins < 6) + { + sn74s516_update(ins); + } + else if (ins == 6) + { + LOAD_Z; + sn74s516_update(ins); + } + else if (ins == 7) + { + // Pointless operation. + sn74s516_update(ins); + } + + break; + } + case 3: + { + UPDATE_SEQUENCE; + if (ins < 4) + { + LOAD_Y; + sn74s516_update(ins); + } + else if (ins == 4) + { + LOAD_W; + sn74s516_update(ins); + } + else if (ins == 5) + { + sn74s516_update(ins); + } + else if (ins == 6) + { + LOAD_W; + sn74s516_update(ins); + } + else if (ins == 7) + { + READ_ZW; + sn74s516_update(ins); + } + break; + } + case 11: + { + UPDATE_SEQUENCE; + if (ins < 4) + { + LOAD_Y; + sn74s516_update(ins); + } + else if (ins < 6) + { + sn74s516_update(ins); + } + else if (ins == 6) + { + // CHECK: Incomplete state + sn74s516_update(ins); + } + else if (ins == 7) + { + /* 6667 = Load X, Load Z, Load W, Clear Z */ + SN74S516.ZW.Z = 0; + sn74s516_update(ins); + } + break; + } + default: + { + mame_printf_debug("Unknown SN74S516 state. %x\n", SN74S516.code); + } + } + + math.dbgaddr = math.promaddr; + math.dbgpc = activecpu_get_previouspc(); +} + + +/*************************************************************************** + + TX-1 + + Preliminary + +***************************************************************************/ + +/* Same mapping as Buggy Boy actually */ +#define TX1_INSLD 0x100 +#define TX1_CNTST 0x80 +#define TX1_RADCHG 0x20 +#define TX1_DSEL 0x03 + +#define TX1_SEL_MULEN 0x00 +#define TX1_SEL_PPSEN 0x01 +#define TX1_SEL_PSSEN 0x02 +#define TX1_SEL_LMSEL 0x03 +#define TX1_SEL_DSELOE 0x04 +#define TX1_SEL_INSCL 0x06 +#define TX1_SEL_ILDEN 0x07 + +#define TX1_SET_INS0_BIT do { if (!(ins & 0x4) && math.i0ff) ins |= math.i0ff; } while(0) + +INLINE UINT16 get_tx1_datarom_addr(void) +{ + UINT16 addr; + + addr = ((math.inslatch & 0x1c00) << 1) | (math.ppshift & 0xff); + + if ( (math.inslatch >> 8) & TX1_RADCHG ) + { + addr |= (math.ppshift & 0x0700); + } + else + { + addr |= (math.promaddr << 3) & 0x0700; + } + + return addr & 0x3fff; +} + +static void tx1_update_state(void) +{ +#define LHIEN(a) !(a & 0x80) +#define LLOEN(a) !(a & 0x40) +#define GO_EN(a) !(a & 0x4000) + + for (;;) + { + int go = 0; + + if ( !GO_EN(math.inslatch) && GO_EN(prom[math.promaddr]) ) + { + go = 1; + } + /* + Example: + 120 /GO /LHIEN + 121 /GO /LLOEN + Both 120 and 121 are used. + */ + else if ( (GO_EN(math.inslatch) && GO_EN(prom[math.promaddr])) && (LHIEN(math.inslatch) && LLOEN(prom[math.promaddr])) ) + { + go = 1; + } + + /* Now update the latch */ + math.inslatch = prom[math.promaddr] & 0x7fff; + math.mux = (math.inslatch >> 3) & 7; + + if ( math.mux == TX1_SEL_INSCL ) + { + math.i0ff = 0; + } + else if ( math.mux == TX1_SEL_PPSEN ) + { + // NOTE: Doesn't do anything without SPCS. + } + + /* TODO */ + if ( go ) + { + int ins = math.inslatch & 7; + + TX1_SET_INS0_BIT; + + if ( math.mux == TX1_SEL_DSELOE ) + { + UINT16 data; + int dsel = (math.inslatch >> 8) & TX1_DSEL; + +// int tfad = (math.inslatch & 0x1c00); +// int ps = math.ppshift & 0x78; + + + if ( (dsel & 1) == 0 ) + dsel |= 1; + else + { + dsel &= ~1; + } + + if ( dsel == 0 ) + data = math.muxlatch; + else if ( dsel == 1 ) + { + UINT16 *romdata = (UINT16*)memory_region(REGION_USER1); + UINT16 addr = get_tx1_datarom_addr(); + data = romdata[addr]; + } + else if ( dsel == 2 ) + data = ROL16(math.muxlatch, 4); + else if ( dsel == 3 ) + data = ROL16(SWAP16(math.muxlatch), 3); + + kick_sn74s516(&data, ins); + } + /* + TODO: Changed ppshift to muxlatch for TX-1 + Changed masks. + */ + else if ( LHIEN(math.inslatch) || LLOEN(math.inslatch) ) + { + UINT16 data; + + kick_sn74s516(&data, ins); + + if ( LHIEN(math.inslatch) && LLOEN(math.inslatch) ) + { + math.muxlatch = data; + } + else if ( math.mux == TX1_SEL_LMSEL ) + { + if ( LLOEN(math.inslatch) ) + { + math.muxlatch &= 0x001f; + math.muxlatch |= data & 0xffe0; + } + else if ( LHIEN(math.inslatch) ) + { + math.muxlatch &= 0xffe0; + math.muxlatch |= data & 0x001f; + } + } + else + { + if ( LLOEN(math.inslatch) ) + { + math.muxlatch &= 0x0fff; + math.muxlatch |= data & 0xf000; + } + else if ( LHIEN(math.inslatch) ) + { + math.muxlatch &= 0xf000; + math.muxlatch |= data & 0x0fff; + } + } + } + else + { + if ( math.mux == TX1_SEL_PPSEN ) + { + kick_sn74s516(&math.ppshift, ins); + } + else + { + /* Bus pullups give 0xffff */ + UINT16 data = 0xffff; + kick_sn74s516(&data, ins); + } + } + } + + /* Is there another instruction in the sequence? */ + if ( prom[math.promaddr] & 0x8000 ) + break; + else + INC_PROM_ADDR; + } +} + +READ16_HANDLER( tx1_math_r ) +{ + offset = offset << 1; + + /* /MLPCS */ + if ( offset < 0x400 ) + { + int ins; + + if ( offset & 0x200 ) + { + ins = math.inslatch & 7; + TX1_SET_INS0_BIT; + } + else + { + ins = (offset >> 1) & 7; + } + + /* TODO What do we return? */ + kick_sn74s516(&math.retval, ins); + } + /* /PPSEN */ + else if ( offset < 0x800 ) + { + // Unused - just pullups? + math.retval = 0xffff; + } + /* /MUXCS */ + else if ( (offset & 0xc00) == 0xc00 ) + { + + /* TODO + SEL0 = 1 (DSEL = 0 or ???????) + DSEL1 = 0 + */ + int dsel = (math.inslatch >> 8) & TX1_DSEL; +// int tfad = (math.inslatch & 0x1c00); +// int ps = math.ppshift & 0x78; + + /* + Actual MUX selects + 00 Straight from DLATCH + 01 Straight from ROM + 10 << 4 + 11 Halves swapped, << 3 + + If DSEL = x0, MUX = x1 + + 00 -> 01 + + 10 -> 11 + + 10 = 11 + 00 = 01 + */ + + // TEST! + if ( (dsel & 1) == 0 ) + dsel |= 1; + else + { + dsel &= ~1; + } + + if ( dsel == 0 ) + math.retval = math.muxlatch; + else if ( dsel == 1 ) + { + /* + TODO make this constant somewhere + e.g. math.retval = math.romptr[ get_tx1_datarom_addr() ]; + */ + UINT16 *romdata = (UINT16*)memory_region(REGION_USER1); + UINT16 addr = get_tx1_datarom_addr(); + math.retval = romdata[addr]; + } + else if ( dsel == 2 ) + math.retval = ROL16(math.muxlatch, 4); + else if ( dsel == 3 ) + math.retval = ROL16(SWAP16(math.muxlatch), 3); + + /* TODO for TX-1: This is /SPCS region? */ + if ( offset < 0xe00 ) + { + // Load the PP with retval?????? + if ( math.mux == TX1_SEL_PPSEN ) + { + math.ppshift = math.retval & 0x3fff; + } + else if ( math.mux == TX1_SEL_PSSEN ) + { + // ???????? + math.ppshift = math.retval; + } + + if ( math.mux != TX1_SEL_ILDEN ) + { + INC_PROM_ADDR; + tx1_update_state(); + + // MUST RETURN HERE? + return math.retval; + } + } + } + else + { + if ( math.mux == TX1_SEL_PPSEN ) + math.retval = math.ppshift; + else + /* Nothing is mapped - read from pull up resistors! */ + math.retval = 0xffff; + } + + if ( offset & TX1_INSLD ) + { + math.promaddr = (offset << 2) & 0x1ff; + tx1_update_state(); + } + else if ( offset & TX1_CNTST ) + { + INC_PROM_ADDR; + tx1_update_state(); + } + + return math.retval; +} + +WRITE16_HANDLER( tx1_math_w ) +{ + math.cpulatch = data; + offset <<= 1; + +// printf("W %x: %x\n", 0x3000 + offset, data); + + /* /MLPCS */ + if ( offset < 0x400 ) + { + int ins; + + if ( offset & 0x200 ) + { + ins = math.inslatch & 7; + TX1_SET_INS0_BIT; + } + else + { + ins = (offset >> 1) & 7; + } + + kick_sn74s516(&math.cpulatch, ins); + } + /* /PPSEN */ + else if ( (offset & 0xc00) == 0x400 ) + { + /* Input is 14 bits */ + math.ppshift = math.cpulatch & 0x3fff; + } + /* /PSSEN */ + else if ( (offset & 0xc00) == 0x800 ) + { + //if ( ((math.inslatch >> 8) & TX1_DSEL) == 3 ) + { + int shift; + UINT16 val = math.ppshift; + + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; + + while (shift) + { + val >>= 1; + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; + + while (shift) + { + val <<= 1; + shift >>= 1; + } + } + math.ppshift = val & 0x7ff; + } + } + /* /MUXCS */ + else if ( (offset & 0xc00) == 0xc00 ) + { + /* TODO */ + math.muxlatch = math.cpulatch; + } + + if ( offset & TX1_INSLD ) + { + math.promaddr = (offset << 2) & 0x1ff; + tx1_update_state(); + } + else if ( offset & TX1_CNTST ) + { + INC_PROM_ADDR; + tx1_update_state(); + } +} + +READ16_HANDLER( tx1_spcs_rom_r ) +{ + math.cpulatch = *(UINT16*)((UINT8*)memory_region(REGION_CPU2) + 0xfc000 + 0x1000 + offset*2); + + if ( math.mux == TX1_SEL_ILDEN ) + { + math.i0ff = math.cpulatch & (1 << 14) ? 1 : 0; + } + else if ( math.mux == TX1_SEL_MULEN ) + { + int ins = math.inslatch & 7; + + TX1_SET_INS0_BIT; + kick_sn74s516(&math.cpulatch, ins); + } + else if ( math.mux == TX1_SEL_PPSEN ) + { + math.ppshift = math.cpulatch; + } + else if ( math.mux == TX1_SEL_PSSEN ) + { + //if ( ((math.inslatch >> 8) & TX1_DSEL) == 3 ) + { + int shift; + UINT16 val = math.ppshift; + + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; + + while (shift) + { + val >>= 1; + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; + + while (shift) + { + val <<= 1; + shift >>= 1; + } + } + math.ppshift = val & 0x7ff; + } + } + + if ( math.mux != TX1_SEL_ILDEN ) + { + INC_PROM_ADDR; + tx1_update_state(); + } + + return math.cpulatch; } -WRITE16_HANDLER(BB_AU_W) +READ16_HANDLER( tx1_spcs_ram_r ) { -//UINT8 *AU_PROM1 = (UINT8 *)memory_region(REGION_PROMS) + 0x1700; -//UINT8 *AU_PROM2 = (UINT8 *)memory_region(REGION_PROMS) + 0x1900; + math.cpulatch = tx1_math_ram[offset]; - switch (offset) - { + offset <<= 1; - case 0x0: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); /* Load values */ - break; + if ( math.mux == TX1_SEL_ILDEN ) + { + math.i0ff = math.cpulatch & (1 << 14) ? 1 : 0; + } + else if ( math.mux == TX1_SEL_MULEN ) + { + int ins = math.inslatch & 7; - case 0x1: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; + TX1_SET_INS0_BIT; + kick_sn74s516(&math.cpulatch, ins); + } + else if ( math.mux == TX1_SEL_PPSEN ) + { + math.ppshift = math.retval & 0x3fff; + } + else if ( math.mux == TX1_SEL_PSSEN ) + { + int shift; + UINT16 val = math.ppshift; - case 0x2: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; - case 0x3: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; + while (shift) + { + val >>= 1; + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; - case 0x4: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; + while (shift) + { + val <<= 1; + shift >>= 1; + } + } + math.ppshift = val & 0x7ff; + } - case 0x5: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; + if ( math.mux != TX1_SEL_ILDEN ) + { + INC_PROM_ADDR; + tx1_update_state(); + } - case 0x6: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; - - case 0x7: COMBINE_DATA(AU_PTR); - MMI_74S516(offset, (UINT16*)AU_PTR); - break; - - /* Accessing FN ROMs */ - case 0x0600/2: - COMBINE_DATA(&inst_index); - break; - - - case 0x0680/2: break; /* Increment instruction PROM address */ - case 0x0726/2: break; - } + return math.cpulatch; } +/* Should never occur */ +WRITE16_HANDLER( tx1_spcs_ram_w ) +{ + mame_printf_debug("Write to /SPCS RAM?"); + COMBINE_DATA(&tx1_math_ram[offset]); +} + + +/*************************************************************************** + + Buggy Boy + +***************************************************************************/ +#define BB_INSLD 0x100 +#define BB_CNTST 0x80 +#define BB_RADCHG 0x20 +#define BB_DSEL 0x03 + +#define BB_MUX_MULEN 0x00 +#define BB_MUX_PPSEN 0x01 +#define BB_MUX_PSSEN 0x02 +#define BB_MUX_LMSEL 0x03 +#define BB_MUX_DPROE 0x04 +#define BB_MUX_PPOE 0x05 +#define BB_MUX_INSCL 0x06 +#define BB_MUX_ILDEN 0x07 + +#define BB_SET_INS0_BIT do { if (!(ins & 0x4) && math.i0ff) ins |= math.i0ff;} while(0) + +INLINE UINT16 get_bb_datarom_addr(void) +{ + UINT16 addr; + + addr = ((math.inslatch & 0x1c00) << 1) | (math.ppshift & 0xff); + + if ( (math.inslatch >> 8) & BB_RADCHG ) + { + addr |= (math.ppshift & 0x0700); + } + else + { + addr |= (math.promaddr << 3) & 0x0700; + } + + return addr & 0x3fff; +} + +static void buggyboy_update_state(void) +{ +#define LHIEN(a) !(a & 0x80) +#define LLOEN(a) !(a & 0x40) +#define GO_EN(a) !(a & 0x4000) + + for (;;) + { + int go = 0; + + if ( !GO_EN(math.inslatch) && GO_EN(prom[math.promaddr]) ) + go = 1; + else if ( (GO_EN(math.inslatch) && GO_EN(prom[math.promaddr])) && (LHIEN(math.inslatch) && LLOEN(prom[math.promaddr])) ) + go = 1; + + /* Now update the latch */ + math.inslatch = prom[math.promaddr] & 0x7fff; + math.mux = (math.inslatch >> 3) & 7; + + if ( math.mux == BB_MUX_INSCL ) + math.i0ff = 0; + else if ( math.mux == BB_MUX_PPSEN ) + { + // TODO: Needed? + //mame_printf_debug("/PPSEN with INS: %x\n", math.promaddr); + //math.ppshift = lastval;//math.cpulatch; + } + + /* TODO */ + if (go) + { + int ins = math.inslatch & 7; + + BB_SET_INS0_BIT; + + if ( math.mux == BB_MUX_DPROE ) + { + UINT16 *romdata = (UINT16*)memory_region(REGION_USER1); + UINT16 addr = get_bb_datarom_addr(); + kick_sn74s516(&romdata[addr], ins); + } + else if ( math.mux == BB_MUX_PPOE ) + { + kick_sn74s516(&math.ppshift, ins); + } + /* This is quite tricky. */ + /* It can either be a read operation or */ + /* What if /LHIEN and /LLOEN? */ + else if ( LHIEN(math.inslatch) || LLOEN(math.inslatch) ) + { + UINT16 data; + + kick_sn74s516(&data, ins); + + if ( LHIEN(math.inslatch) && LLOEN(math.inslatch) ) + { + math.ppshift = data; + } + else if ( math.mux == BB_MUX_LMSEL ) + { + if ( LLOEN(math.inslatch) ) + { + math.ppshift &= 0x000f; + math.ppshift |= data & 0xfff0; + } + else if ( LHIEN(math.inslatch) ) + { + math.ppshift &= 0xfff0; + math.ppshift |= data & 0x000f; + } + } + else + { + if ( LLOEN(math.inslatch) ) + { + math.ppshift &= 0x0fff; + math.ppshift |= data & 0xf000; + } + else if ( LHIEN(math.inslatch) ) + { + math.ppshift &= 0xf000; + math.ppshift |= data & 0x0fff; + } + } + } + else + { + if ( math.mux == BB_MUX_PPSEN ) + { + kick_sn74s516(&math.ppshift, ins); + } + else + { + /* Bus pullups give 0xffff */ + UINT16 data = 0xffff; + kick_sn74s516(&data, ins); + } + } + } + + /* Handle rotation */ + if ( ((math.inslatch >> 8) & BB_DSEL) == 1 ) + { + math.ppshift = ROR16(math.ppshift, 4); + } + else if ( ((math.inslatch >> 8) & BB_DSEL) == 2 ) + { + math.ppshift = ROL16(math.ppshift, 4); + } + + /* Is there another instruction in the sequence? */ + if ( prom[math.promaddr] & 0x8000 ) + break; + else + INC_PROM_ADDR; + } +} + +READ16_HANDLER( buggyboy_math_r ) +{ + offset = offset << 1; + + /* /MLPCS */ + if ( offset < 0x400 ) + { + int ins; + + if ( offset & 0x200 ) + { + ins = math.inslatch & 7; + BB_SET_INS0_BIT; + } + else + { + ins = (offset >> 1) & 7; + } + + /* TODO What do we return? */ + kick_sn74s516(&math.retval, ins); + + /* TODO */ + //if (math.mux == BB_MUX_PPSEN) + // math.ppshift = math.retval; + } + /* /PPSEN */ + else if ( offset < 0x800 ) + { + math.retval = math.ppshift; + } + /* /DPROE */ + else if ( (offset & 0xc00) == 0xc00 ) + { + UINT16 *romdata = (UINT16*)memory_region(REGION_USER1); + UINT16 addr = get_bb_datarom_addr(); + + math.retval = romdata[addr]; + + /* This is necessary */ + if ( math.mux == BB_MUX_PPSEN ) + math.ppshift = romdata[addr]; + + /* This is /SPCS region? Necessary anyway */ + if ( offset < 0xe00 ) + { + if ( math.mux != BB_MUX_ILDEN ) + { + INC_PROM_ADDR; + buggyboy_update_state(); + } + } + } + else + { + if ( math.mux == BB_MUX_PPSEN ) + math.retval = math.ppshift; + else + /* Nothing is mapped - read from pull up resistors! */ + math.retval = 0xffff; + } + + if ( offset & BB_INSLD ) + { + math.promaddr = (offset << 2) & 0x1ff; + buggyboy_update_state(); + } + else if ( offset & BB_CNTST ) + { + INC_PROM_ADDR; + buggyboy_update_state(); + } + + return math.retval; +} + +WRITE16_HANDLER( buggyboy_math_w ) +{ + math.cpulatch = data; + + offset <<= 1; + + /* /MLPCS */ + if ( offset < 0x400 ) + { + int ins; + + if ( offset & 0x200 ) + { + ins = math.inslatch & 7; + BB_SET_INS0_BIT; + } + else + { + ins = (offset >> 1) & 7; + } + + kick_sn74s516(&math.cpulatch, ins); + } + /* /PPSEN */ + else if ( (offset & 0xc00) == 0x400 ) + { + math.ppshift = math.cpulatch; + } + /* /PSSEN */ + else if ( (offset & 0xc00) == 0x800 ) + { + if ( ((math.inslatch >> 8) & BB_DSEL) == 3 ) + { + int shift; + UINT16 val = math.ppshift; + + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; + + while (shift) + { + val = ROR16(val, 1); + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; + + while (shift) + { + val = ROL16(val, 1); + shift >>= 1; + } + } + math.ppshift = val; + } + else + { + mame_printf_debug("BB_DSEL was not 3 for P->S load!\n"); + DEBUGGER_BREAK; + } + } + else + { + mame_printf_debug("Buggy Boy unknown math state!\n"); + DEBUGGER_BREAK; + } + + if ( offset & BB_INSLD ) + { + math.promaddr = (offset << 2) & 0x1ff; + buggyboy_update_state(); + } + else if ( offset & BB_CNTST ) + { + INC_PROM_ADDR; + buggyboy_update_state(); + } +} + +/* + This is for ROM range 0x5000-0x7fff +*/ +READ16_HANDLER( buggyboy_spcs_rom_r ) +{ + math.cpulatch = *(UINT16*)((UINT8*)memory_region(REGION_CPU2) + 0xfc000 + 0x1000 + offset*2); + + if ( math.mux == BB_MUX_ILDEN ) + { + math.i0ff = math.cpulatch & (1 << 14) ? 1 : 0; + } + else if ( math.mux == BB_MUX_MULEN ) + { + int ins = math.inslatch & 7; + + BB_SET_INS0_BIT; + kick_sn74s516(&math.cpulatch, ins); + } + else if ( math.mux == BB_MUX_PPSEN ) + { + math.ppshift = math.cpulatch; + } + else if ( math.mux == BB_MUX_PSSEN ) + { + if ( ((math.inslatch >> 8) & BB_DSEL) == 3 ) + { + int shift; + UINT16 val = math.ppshift; + + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; + + while (shift) + { + val = ROR16(val, 1); + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; + + while (shift) + { + val = ROL16(val, 1); + shift >>= 1; + } + } + math.ppshift = val; + } + } + + if ( math.mux != BB_MUX_ILDEN ) + { + INC_PROM_ADDR; + buggyboy_update_state(); + } + + return math.cpulatch; +} + +WRITE16_HANDLER( buggyboy_spcs_ram_w ) +{ + COMBINE_DATA(&tx1_math_ram[offset]); +} + +READ16_HANDLER( buggyboy_spcs_ram_r ) +{ + math.cpulatch = tx1_math_ram[offset]; + + offset <<= 1; + + if ( math.mux == BB_MUX_ILDEN ) + { + math.i0ff = math.cpulatch & (1 << 14) ? 1 : 0; + } + else if ( math.mux == BB_MUX_MULEN ) + { + int ins = math.inslatch & 7; + + BB_SET_INS0_BIT; + kick_sn74s516(&math.cpulatch, ins); + } + else if ( math.mux == BB_MUX_PPSEN ) + { + math.ppshift = math.cpulatch; + } + else if ( math.mux == BB_MUX_PSSEN ) + { + if ( ((math.inslatch >> 8) & BB_DSEL) == 3 ) + { + int shift; + UINT16 val = math.ppshift; + + if ( math.cpulatch & 0x3800 ) + { + shift = (math.cpulatch >> 11) & 0x7; + + while (shift) + { + val = ROR16(val, 1); + shift >>= 1; + } + } + else + { + shift = (math.cpulatch >> 7) & 0xf; + shift = reverse_nibble(shift); + shift >>= 1; + + while (shift) + { + val = ROL16(val, 1); + shift >>= 1; + } + } + math.ppshift = val; + } + } + + if ( math.mux != BB_MUX_ILDEN ) + { + INC_PROM_ADDR; + buggyboy_update_state(); + } + + return math.cpulatch; +} + + + +/************************************* + * + * Machine Reset + * + *************************************/ +MACHINE_RESET( buggybjr ) +{ + /* TODO */ + memset(&math, 0, sizeof(math)); +} + +MACHINE_RESET( buggyboy ) +{ + memset(&math, 0, sizeof(math)); +} + +MACHINE_RESET( tx1 ) +{ + memset(&math, 0, sizeof(math)); +} + + +/************************************* + * + * Machine Reset + * + *************************************/ +MACHINE_START( tx1 ) +{ + ppi8255_init(&tx1_ppi8255_intf); + + /* Initialise for each game */ + prom = (UINT16*)memory_region(REGION_USER1) + (0x8000 >> 1); + + /* /CUDISP CRTC interrupt */ + timer_set(video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), NULL, 0, interrupt_callback); +} + +MACHINE_START( buggyboy ) +{ + ppi8255_init(&buggyboy_ppi8255_intf); + + /* Initialise for each game */ + prom = (UINT16*)memory_region(REGION_USER1) + (0x8000 >> 1); + + /* /CUDISP CRTC interrupt */ + timer_set(video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), NULL, 0, interrupt_callback); +} + +MACHINE_START( buggybjr ) +{ + /* Initialise for each game */ + prom = (UINT16*)memory_region(REGION_USER1) + (0x8000 >> 1); + + /* /CUDISP CRTC interrupt */ + timer_set(video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), NULL, 0, interrupt_callback); +} diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 54a091cc0d6..c0591f2e011 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1343,7 +1343,7 @@ $(MAMEOBJ)/taito.a: \ $(MAMEOBJ)/tatsumi.a: \ $(DRIVERS)/lockon.o \ $(DRIVERS)/tatsumi.o $(MACHINE)/tatsumi.o $(VIDEO)/tatsumi.o \ - $(DRIVERS)/tx1.o $(MACHINE)/tx1.o $(VIDEO)/tx1.o \ + $(DRIVERS)/tx1.o $(MACHINE)/tx1.o $(AUDIO)/tx1.o $(VIDEO)/tx1.o \ $(MAMEOBJ)/tch.a: \ $(DRIVERS)/kickgoal.o $(VIDEO)/kickgoal.o \ diff --git a/src/mame/mamedriv.c b/src/mame/mamedriv.c index 64db2e81fbb..65667774609 100644 --- a/src/mame/mamedriv.c +++ b/src/mame/mamedriv.c @@ -7500,7 +7500,7 @@ Other Sun games DRIVER( tx1 ) /* (c) 1983 Tatsumi */ DRIVER( tx1a ) /* (c) 1983 Tatsumi */ DRIVER( buggyboy ) /* (c) 1985 Tatsumi */ - DRIVER( buggyb1 ) /* (c) 1985 Tatsumi */ + DRIVER( buggybjr ) /* (c) 1986 Tatsumi */ DRIVER( sprcros2 ) /* (c) 1986 GM Shoji */ DRIVER( sprcrs2a ) /* (c) 1986 GM Shoji */ DRIVER( gcpinbal ) /* (c) 1994 Excellent System */ diff --git a/src/mame/video/tx1.c b/src/mame/video/tx1.c index 60892a2c532..60252955244 100644 --- a/src/mame/video/tx1.c +++ b/src/mame/video/tx1.c @@ -1,65 +1,593 @@ -/*====================================================================*/ -/* TX-1/Buggy Boy (Tatsumi) Hardware */ -/* Philip J Bennett 2005 */ -/* */ -/* Video Emulation */ -/*====================================================================*/ +/*************************************************************************** + Tatsumi TX-1/Buggy Boy video hardware + +****************************************************************************/ #include "driver.h" +#include "profiler.h" +#include "render.h" +#include "cpu/i86/i86.h" +#include "tx1.h" -extern UINT16 *buggyb1_vram; -extern UINT16 *buggyboy_vram; -extern UINT16 *bb_objram; -extern UINT16 *bb_sky; +#define PRINT_CRTC_DATA 1 -extern tilemap *buggyb1_tilemap; -extern tilemap *buggyboy_tilemap; -extern size_t bb_objectram_size; +/* + HD46505S-2 CRT Controller +*/ +READ16_HANDLER( tx1_crtc_r ) +{ + return 0xffff; +} + +WRITE16_HANDLER( tx1_crtc_w ) +{ +#if PRINT_CRTC_DATA + data &= 0xff; + if (offset == 0) + { + switch (data) + { + case 0x00: mame_printf_debug("Horizontal Total "); break; + case 0x01: mame_printf_debug("Horizontal displayed "); break; + case 0x02: mame_printf_debug("Horizontal sync position "); break; + case 0x03: mame_printf_debug("Horizontal sync width "); break; + case 0x04: mame_printf_debug("Vertical total "); break; + case 0x05: mame_printf_debug("Vertical total adjust "); break; + case 0x06: mame_printf_debug("Vertical displayed "); break; + case 0x07: mame_printf_debug("Vertical sync position "); break; + case 0x08: mame_printf_debug("Interlace mode "); break; + case 0x09: mame_printf_debug("Max. scan line address "); break; + case 0x0a: mame_printf_debug("Cursror start "); break; + case 0x0b: mame_printf_debug("Cursor end "); break; + case 0x0c: mame_printf_debug("Start address (h) "); break; + case 0x0d: mame_printf_debug("Start address (l) "); break; + case 0x0e: mame_printf_debug("Cursor (h) "); break; + case 0x0f: mame_printf_debug("Cursor (l) "); break; + case 0x10: mame_printf_debug("Light pen (h)) "); break; + case 0x11: mame_printf_debug("Light pen (l) "); break; + } + } + else if (offset == 1) + { + mame_printf_debug("0x%.2x, (%d)\n",data, data); + } +#endif +} -extern UINT16 *tx1_vram; -extern UINT16 *tx1_object_ram; +/*************************************************************************** -extern tilemap *tx1_tilemap; -extern size_t tx1_objectram_size; + TX-1 -/*********/ -/* TX-1 */ -/********/ +***************************************************************************/ +static struct +{ + UINT16 scol; /* Road colours */ + UINT32 slock; /* Scroll lock */ + UINT8 flags; /* Road flags */ + + UINT32 ba_val; /* Accumulator */ + UINT32 ba_inc; + + UINT16 h_val; /* Accumulator */ + UINT16 h_inc; + + UINT8 slin_val; /* Accumulator */ + UINT8 slin_inc; +} tx1_vregs; + +/* Offsets into the palette PROMs */ +#define TX1_COLORS_CHAR 0x00 +#define TX1_COLORS_OBJ 0x80 +#define TX1_COLORS_ROAD 0xC0 + +UINT16 *tx1_vram; +UINT16 *tx1_objram; +UINT16 *tx1_rcram; +size_t tx1_objram_size; + +static tilemap *tx1_tilemap; +static mame_bitmap *tx1_bitmap; +static render_texture *tx1_texture; WRITE16_HANDLER( tx1_vram_w ) { COMBINE_DATA(&tx1_vram[offset]); - tilemap_mark_tile_dirty(tx1_tilemap,offset); + tilemap_mark_tile_dirty(tx1_tilemap, offset); } static TILE_GET_INFO( get_tx1_tile_info ) { - int tileno = (tx1_vram[tile_index]&0x03ff) | ((tx1_vram[tile_index] & 0x8000) >> 5); + int tilenum, color; - SET_TILE_INFO(0,tileno,0,0); + color = (tx1_vram[tile_index] >> 10) & 0x3f; + tilenum = (tx1_vram[tile_index]&0x03ff) | ((tx1_vram[tile_index] & 0x8000) >> 5); + + SET_TILE_INFO(0, tilenum, color, 0); } +/*************************************************************************** + + Palette initialisation + + TODO: Add some notes + + bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE + -- 470 ohm resistor -- RED/GREEN/BLUE + -- 1.0kohm resistor -- RED/GREEN/BLUE + bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE + +***************************************************************************/ +PALETTE_INIT( tx1 ) +{ + int i; + + for (i = 0; i < 256; ++i) + { + int bit0, bit1, bit2, bit3; + int r, g, b; + + bit0 = BIT(color_prom[i], 0); + bit1 = BIT(color_prom[i], 1); + bit2 = BIT(color_prom[i], 2); + bit3 = BIT(color_prom[i], 3); + r = 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + + bit0 = BIT(color_prom[i + 0x100], 0); + bit1 = BIT(color_prom[i + 0x100], 1); + bit2 = BIT(color_prom[i + 0x100], 2); + bit3 = BIT(color_prom[i + 0x100], 3); + g = 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + + bit0 = BIT(color_prom[i + 0x200], 0); + bit1 = BIT(color_prom[i + 0x200], 1); + bit2 = BIT(color_prom[i + 0x200], 2); + bit3 = BIT(color_prom[i + 0x200], 3); + b = 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + + palette_set_color(machine, i, MAKE_RGB(r, g, b)); + } + + /* TODO */ + for (i = 0; i < 256; ++i) + { + colortable[i] = (color_prom[i + 0x900] & 0xf) + 0x00; + } +} + +WRITE16_HANDLER( tx1_bankcs_w ) +{ + // AAB2 = /BASET0 + // AAB3 = /BASET + // AAB4 = /BSET + // AAB5 = /HASET + // AAB6 = /HSET + + offset <<= 1; + + if ( offset & 0x04 ) + { + tx1_vregs.ba_inc &= ~0x0000ffff; + tx1_vregs.ba_inc |= data; + + if ( !(offset & 2) ) + tx1_vregs.ba_val &= ~0x000ffff; + } + if ( offset & 0x08 ) + { + data &= 0xff; + tx1_vregs.ba_inc &= ~0xffff0000; + tx1_vregs.ba_inc |= data << 16; + + if ( !(offset & 2) ) + tx1_vregs.ba_val &= ~0xffff0000; + } + if ( offset & 0x10 ) + { + /* Ignore data */ + if ( offset & 2 ) + { + tx1_vregs.ba_val = (tx1_vregs.ba_inc + tx1_vregs.ba_val) & 0x00ffffff; + } + } + if ( offset & 0x20 ) + { + tx1_vregs.h_inc = data; + + if ( !(offset & 2) ) + tx1_vregs.h_val = 0; + } + if ( !(offset & 0x40) ) + { + /* Ignore data? */ + if ( offset & 2 ) + tx1_vregs.h_val += tx1_vregs.h_inc; + } +} + +WRITE16_HANDLER( tx1_slincs_w ) +{ + if ( offset == 1 ) + tx1_vregs.slin_inc = data; + else + tx1_vregs.slin_inc = tx1_vregs.slin_val = 0; +} + +WRITE16_HANDLER( tx1_slock_w ) +{ + tx1_vregs.slock = data & 1; +} + +WRITE16_HANDLER( tx1_scolst_w ) +{ + tx1_vregs.scol = data & 0x0707; +} + +WRITE16_HANDLER( tx1_flgcs_w ) +{ + tx1_vregs.flags = data & 0xff; +} + + +/* Preliminary */ +static void tx1_draw_objects(mame_bitmap *bitmap, const rectangle *cliprect) +{ +#define FRAC 16 + + UINT32 offs; + + /* The many lookup table ROMs */ + const UINT8 *const ic48 = (UINT8*)memory_region(REGION_USER3); + const UINT8 *const ic281 = (UINT8*)memory_region(REGION_USER3) + 0x2000; + const UINT8 *const ic25 = (UINT8*)memory_region(REGION_PROMS) + 0x1000; + + const UINT8 *const ic106 = (UINT8*)memory_region(REGION_USER2); + const UINT8 *const ic73 = (UINT8*)memory_region(REGION_USER2) + 0x4000; + + const UINT8 *const ic190 = (UINT8*)memory_region(REGION_PROMS) + 0xc00; + const UINT8 *const ic162 = (UINT8*)memory_region(REGION_PROMS) + 0xe00; + + const UINT8 *const pixdata_rgn = (UINT8*)memory_region(REGION_GFX2); + + for (offs = 0x0; offs <= tx1_objram_size; offs += 8) + { + UINT32 x; + UINT32 y; + UINT32 gxflip; + + UINT32 x_scale; + UINT32 x_step; + UINT16 y_scale; + UINT16 y_step; + + UINT8 pctmp0_7; + UINT8 code; + + /* Check for end of object list */ + if ( (tx1_objram[offs] & 0xff00) == 0xff00 ) + break; + + /* X scale */ + x_scale = tx1_objram[offs + 2] & 0xff; + + /* TODO: Confirm against hardware? */ + if ( x_scale == 0 ) + continue; + + /* 16-bit y-scale accumulator */ + y_scale = tx1_objram[offs + 1]; + y_step = tx1_objram[offs + 3]; + + /* Object number */ + code = tx1_objram[offs] & 0xff; + + /* Attributes */ + pctmp0_7 = tx1_objram[offs + 2] >> 8; + + /* Global x-flip */ + gxflip = (pctmp0_7 & 0x80) >> 7; + + /* Add 1 to account for line buffering */ + y = (tx1_objram[offs] >> 8) + 1; + + for (; y <= cliprect->max_y; ++y) + { + UINT32 rom_addr2 = 0; + UINT8 ic106_data = 0; + UINT8 ic73_data; + + /* Are we drawing on this line? */ + + /* TODO: See big lampposts. */ + if ( y_scale & 0x8000 ) + break; + + { + UINT32 psa0_11; + UINT32 ic48_addr; + UINT32 ic48_data; + UINT32 rom_addr; + UINT32 x_acc; + UINT32 newtile = 1; + UINT32 dataend = 0; + UINT8 data1 = 0; + UINT8 data2 = 0; + UINT32 xflip = 0; + UINT32 opcd0_7 = 0; + UINT32 lasttile = 0; + + /* Use the object code to lookup the tile sequence data in ROM */ + ic48_addr = code << 4; + ic48_addr |= ((y_scale >> 11) & 0xf); + ic48_data = ic48[ic48_addr]; + + /* Reached the bottom of the object? (/PASS2E) */ + if ( ic48_data == 0xff ) + break; + + /* Combine ROM and PROM data */ + psa0_11 = ((ic25[code] << 8) | ic48_data) & 0xfff; + + /* psa8_11 */ + rom_addr = (psa0_11 & ~0xff) << 2; + + /* Prepare the x-scaling */ + x_step = (128 << FRAC) / x_scale; + x_acc = (psa0_11 & 0xff) << (FRAC + 5); + + /* TODO */ + //x = tx1_objram[offs + 4] & 0x7ff; + x = tx1_objram[offs + 4]; + + for (;;) + { + #define MASK 0x3ff + + if (newtile) + { + UINT32 low_addr = ((x_acc >> (FRAC + 3)) & MASK); + + if (gxflip) + { + UINT32 xor_mask; + + if ( BIT(psa0_11, 11) && BIT(psa0_11, 10) ) + xor_mask = 0xf; + else if ( BIT(psa0_11, 9) ) + xor_mask = 0x7; + else + xor_mask = 0x3; + + rom_addr2 = rom_addr + (xor_mask ^ low_addr); + } + else + rom_addr2 = rom_addr + low_addr; + + ic106_data = ic106[rom_addr2 & 0x3fff]; + + if ( (ic106_data & 0x40) && dataend ) + lasttile = 1; + + dataend |= ic106_data & 0x40; + } + + { + if ( newtile ) + { + UINT32 psbb0_12; + UINT32 pscb0_14; + UINT32 pscb11; + UINT8 *romptr; + UINT32 ic281_addr; + UINT32 grom_addr; + UINT32 lut_data; + + /* Retrieve data for an 8x8 tile */ + ic73_data = ic73[rom_addr2]; + + // This is the data from the LUT pair + lut_data = (ic106_data << 8) | ic73_data; + psbb0_12 = lut_data & 0x1fff; + + // 0000 1100 0011 1111 + pscb0_14 = (psbb0_12 & 0xc3f); + + + /* Bits 9_6 are from PCTMP11-8 or PSBB9-6 */ + + /* 0000 0011 1100 0000 */ + if ( BIT(psbb0_12, 12) ) + pscb0_14 |= psbb0_12 & 0x3c0; + else + pscb0_14 |= (pctmp0_7 & 0xf) << 6; + + // This is the important one! + if ( BIT(lut_data, 13) ) // PSBB13 + pscb0_14 |= BIT(psbb0_12, 10) << 12; + else + pscb0_14 |= ((pctmp0_7 & 0x70) << 8); + + + + // 1 = Bit 12 is Bit 10 duplicated. + // Schematics indicate otherwise... + #if 1 + pscb0_14 &= ~(1 << 12); + pscb0_14 |= BIT(psbb0_12, 10) << 12; + #endif + + pscb11 = BIT(pscb0_14, 11); + + /* TODO: Remove this - it's constant. */ + romptr = (UINT8*)(pixdata_rgn + pscb11 * (0x4000 * 2)); + + grom_addr = ((pscb0_14 << 3) | ((y_scale >> 8) & 7)) & 0x3fff; + + /* Get raw 8x8 2bpp pixel row data */ + data1 = *(grom_addr + romptr); + data2 = *(grom_addr + romptr + 0x4000); + + /* Determine flip state (global XOR local) */ + xflip = gxflip ^ !BIT(lut_data, 15); + + /* WRONG */ + ic281_addr = pscb0_14 & 0x3ff; // Bits 9_0 + ic281_addr |= ((pscb0_14 & 0x7000) >> 2); //Bits 14 13 12 + ic281_addr |= pscb11 << 13; // Bit 11 + + opcd0_7 = ic281[ic281_addr]; + } + + /* Draw a pixel? */ + if ( x <= cliprect->max_x ) + { + UINT8 pix; + UINT8 bit; + + bit = (x_acc >> FRAC) & 7; + + if ( xflip ) + bit ^= 7; + + pix = (((data1 >> bit) & 1) << 1) | ((data2 >> bit) & 1); + + /* Draw pixel, if not transparent */ + if ( !(!(opcd0_7 & 0x80) && !pix) ) + { + UINT8 color; + UINT32 prom_addr; + + prom_addr = ((opcd0_7 << 2) | pix) & 0x1ff; + + /* Inverted on schematic */ + if (x & 1) + color = ~ic190[prom_addr] & 0x3f; + else + color = ~ic162[prom_addr] & 0x3f; + + *BITMAP_ADDR16(bitmap, y, x) = Machine->pens[TX1_COLORS_OBJ + color]; + } + } + } + newtile = 0; + + /* Check if we've stepped into a new 8x8 tile */ + /* TODO */ + if ( (((x_acc + x_step) >> (FRAC + 3)) & MASK) != ((x_acc >> (FRAC + 3)) & MASK) ) + { + newtile = 1; + + if ( lasttile ) + break; + } + + // TODO! + //x = (x + 1) & 0x7ff; + x = (x + 1); + x_acc += x_step; + } + }// if (yscale) + y_scale += y_step; + } /* for (y) */ + }/* for (offs) */ +} + + VIDEO_START( tx1 ) { - tx1_tilemap = tilemap_create(get_tx1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,128,64); - tilemap_set_transparent_pen(tx1_tilemap,0xff); + tx1_tilemap = tilemap_create(get_tx1_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8, 8, 128, 64); + tilemap_set_transparent_pen(tx1_tilemap, 0xff); + + /* Allocate a large bitmap that covers the three screens */ + tx1_bitmap = auto_bitmap_alloc(768, 256, BITMAP_FORMAT_INDEXED16); + tx1_texture = render_texture_alloc(NULL, NULL); } +VIDEO_EOF( tx1 ) +{ + /* /VSYNC: Update TZ113 */ + tx1_vregs.slin_val += tx1_vregs.slin_inc; +} + + +/* Experimental :) */ VIDEO_UPDATE( tx1 ) { - /* the video hardware seems to use one large tilemap, scroll it to the right position for each screen */ - int xscrollamount = screen*256; - tilemap_set_scrollx(tx1_tilemap,0,xscrollamount); + int y; + if ( screen == 0 ) + { + rectangle rect = { 0, 768 - 1, 0, 240 - 1 }; + +// tilemap_set_scrollx(tx1_tilemap, 0, scroll); + tilemap_draw(tx1_bitmap, &rect, tx1_tilemap, 0, 0); +// tx1_draw_road(tx1_bitmap, &rect); + tx1_draw_objects(tx1_bitmap, &rect); + } + + for (y = 0; y < 240; ++y) + memcpy(BITMAP_ADDR16(bitmap, y, 0), BITMAP_ADDR16(tx1_bitmap, y, screen * 256), sizeof(UINT16) * 256); - tilemap_draw(bitmap,cliprect,tx1_tilemap,0,0); return 0; } -/*************/ -/* Buggy Boy */ -/*************/ + +/*************************************************************************** + + Buggy Boy + +***************************************************************************/ + +/* Road register bits */ +#define BB_RDFLAG_WAVE1 7 +#define BB_RDFLAG_WAVE0 6 +#define BB_RDFLAG_TNLMD1 5 +#define BB_RDFLAG_TNLMD0 4 +#define BB_RDFLAG_TNLF 3 +#define BB_RDFLAG_LINF 2 +#define BB_RDFLAG_RVA7 1 +#define BB_RDFLAG_WANGL 0 + +/* Video registers */ +static struct +{ + UINT32 ba_val; + UINT32 ba_inc; + + UINT32 bank_mode; + + UINT16 h_val; + UINT16 h_inc; + UINT16 h_init; + + UINT8 wa8; + UINT8 wa4; + + UINT8 slin; + UINT8 slin_inc; + + UINT16 wave_lfsr; + UINT16 scol; + UINT8 sky; + UINT16 gas; + UINT8 flags; + UINT8 shift; +} vregs; + + +UINT16 *buggyboy_objram; +UINT16 *buggyboy_rcram; +UINT16 *buggyboy_vram; +UINT16 *buggybjr_vram; +size_t buggyboy_objram_size; +size_t buggyboy_rcram_size; + +tilemap *buggybjr_tilemap; +tilemap *buggyboy_tilemap; + +UINT8 *chr_bmp; +UINT8 *obj_bmp; +UINT8 *rod_bmp; /*************************************************************************** @@ -83,324 +611,1154 @@ VIDEO_UPDATE( tx1 ) ***************************************************************************/ PALETTE_INIT( buggyboy ) { - int i; + int i; - for (i = 0; i < 256;i++) + for (i = 0; i < 256; ++i) { - int bit0,bit1,bit2,bit3,bit4,r,g,b; + int bit0, bit1, bit2, bit3, bit4; + int r, g, b; - bit0 = color_prom[i] & 1; - bit1 = (color_prom[i] >> 1) & 1; - bit2 = (color_prom[i] >> 2) & 1; - bit3 = (color_prom[i] >> 3) & 1; - bit4 = (color_prom[i+0x300] >> 2) & 1; - r = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + bit0 = BIT(color_prom[i], 0); + bit1 = BIT(color_prom[i], 1); + bit2 = BIT(color_prom[i], 2); + bit3 = BIT(color_prom[i], 3); + bit4 = BIT(color_prom[i + 0x300], 2); + r = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; - bit0 = color_prom[i+0x100] & 1; - bit1 = (color_prom[i+0x100] >> 1) & 1; - bit2 = (color_prom[i+0x100] >> 2) & 1; - bit3 = (color_prom[i+0x100] >> 3) & 1; - bit4 = (color_prom[i+0x300] >> 1) & 1; - g = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + bit0 = BIT(color_prom[i + 0x100], 0); + bit1 = BIT(color_prom[i + 0x100], 1); + bit2 = BIT(color_prom[i + 0x100], 2); + bit3 = BIT(color_prom[i + 0x100], 3); + bit4 = BIT(color_prom[i + 0x300], 1); + g = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; - bit0 = color_prom[i+0x200] & 1; - bit1 = (color_prom[i+0x200] >> 1) & 1; - bit2 = (color_prom[i+0x200] >> 2) & 1; - bit3 = (color_prom[i+0x200] >> 3) & 1; - bit4 = (color_prom[i+0x300]) & 1; - b = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; + bit0 = BIT(color_prom[i + 0x200], 0); + bit1 = BIT(color_prom[i + 0x200], 1); + bit2 = BIT(color_prom[i + 0x200], 2); + bit3 = BIT(color_prom[i + 0x200], 3); + bit4 = BIT(color_prom[i + 0x300], 0); + b = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3; - palette_set_color(machine,i,MAKE_RGB(r,g,b)); + palette_set_color(machine, i, MAKE_RGB(r,g,b)); } - - /** Set up the colour lookups **/ - - /* Objects use colours 0-63 */ - /* There are 2048 palette, however, this is expanded to 8192 */ - - for (i = 0; i < 2048; i++) - colortable[256+i] = ((0xf-color_prom[i + 0x500]) & 0xf) + 48; - - for (i = 0; i < 2048; i++) - colortable[256+2048+i] = ((0xf-color_prom[i + 0x500]) & 0xf) + 32; - - for (i = 0; i < 2048; i++) - colortable[256+2048+2048+i] = ((0xf-color_prom[i + 0x500]) & 0xf) + 16; - - /* Only this is used? */ - for (i = 0; i < 2048; i++) - colortable[256+2048+2048+2048+i] = ((0xf-color_prom[i + 0x500]) & 0xf); - - /* Road uses 64-127 */ - /* Colour PROM only constitutes bits 0-3 - so expand 4-6*/ - for (i = 0; i < 256; i++) - colortable[256+8192+i] = (color_prom[i + 0x1500] & 0xf) + 64; - - for (i = 0; i < 256; i++) - colortable[256+8192+256+i] = (color_prom[i + 0x1500] & 0xf) + 64 + 16; - - for (i = 0; i < 256; i++) - colortable[256+8192+256*2+i] = (color_prom[i + 0x1500] & 0xf) + 64 + 32; - - for (i = 0; i < 256; i++) - colortable[256+8192+256*3+i] = (color_prom[i + 0x1500] & 0xf) + 64 + 48; - - /* Sky uses colours 128-191 directly - no lookup */ - - /* Characters use colours 192-255 */ - for (i = 0; i < 256; i++) - colortable[i] = (color_prom[i + 0x400] & 0xf) + 192; - -} - - -WRITE16_HANDLER( buggyb1_vram_w ) -{ - COMBINE_DATA(&buggyb1_vram[offset]); - tilemap_mark_tile_dirty(buggyb1_tilemap,offset); + /* Characters use colours 192-255 */ + for (i = 0; i < 256; ++i) + { + colortable[i] = 192 + color_prom[i + 0x400] + ((i & 0xc0) >> 2); + } } WRITE16_HANDLER( buggyboy_vram_w ) { COMBINE_DATA(&buggyboy_vram[offset]); - tilemap_mark_tile_dirty(buggyboy_tilemap,offset); + tilemap_mark_tile_dirty(buggyboy_tilemap, offset); } - -static TILE_GET_INFO( get_buggyb1_tile_info ) +WRITE16_HANDLER( buggybjr_vram_w ) { - int color, tileno; - - color = ((buggyb1_vram[tile_index] >>10) & 0x3f); - tileno = (buggyb1_vram[tile_index]&0x03ff) | ((buggyb1_vram[tile_index] & 0x8000) >> 5); - - SET_TILE_INFO(0,tileno,color,0); + COMBINE_DATA(&buggybjr_vram[offset]); } static TILE_GET_INFO( get_buggyboy_tile_info ) { - int color, tileno; + int color, tilenum; - color = ((buggyboy_vram[tile_index] >>10) & 0x3f); - tileno = (buggyboy_vram[tile_index]&0x03ff) | ((buggyboy_vram[tile_index] & 0x8000) >> 5); + color = (buggyboy_vram[tile_index] >> 10) & 0x3f; + tilenum = (buggyboy_vram[tile_index]&0x03ff) | ((buggyboy_vram[tile_index] & 0x8000) >> 5); - SET_TILE_INFO(0,tileno,color,0); + SET_TILE_INFO(0, tilenum, color, 0); +} + +/*************************************************************************** + + Buggy Boy Road Hardware + + A mega-hack of TX-1 but without the second road. + + There are two lists in road/common RAM (double buffered) starting at 0x800 + and 0xa00: + + 0x1800 - 0x18ff: Road line horizontal position word (128 entries). + 0x19e0 - 0x19ef: Vertical positions (starting line, water, tunnels etc) + 0x19f0 - 0x19ff: Horizontal positions (walls and tunnels) + + Three TZ1113 accumulators are used to vary: + * Road camber (update per pixel) + * Road vertical scale/position (update per scanline) + * Road 'speed' (update per frame) + + Road flags register (0x24E0): + 7 : Water sparkle control 1 + 6 : Water sparkle control 0 ('WAVE0,1') + 5 : Tunnel mode 1 + 4 : Tunnel mode 0 ('TNLMD0,1') + 3 : Tunnel flag ('TNLF') + 2 : Starting Line flag ('LINF') + 1 : Road list select + 0 : Wall angle enable ('WANGL') + + Road PAL equations: + + http://philwip.mameworld.info/buggyboy/PAL14H4.149.htm + http://philwip.mameworld.info/buggyboy/PAL14L4.151.htm + http://philwip.mameworld.info/buggyboy/PAL16H2.3.htm + http://philwip.mameworld.info/buggyboy/PAL16L8.4.htm + http://philwip.mameworld.info/buggyboy/PAL16L8.150.htm + +***************************************************************************/ +static void buggybjr_draw_road(UINT8 *bitmap) +{ +#define X_ADJUST 384 +#define LOAD_HPOS_COUNTER( NUM ) \ + ram_val = buggyboy_rcram[(rva_offs + 0x1f8 + (2*NUM)) >> 1]; \ + rcrs10 = ram_val & 0xfc00 ? 0x0400 : 0x0000; \ + hp = vregs.wa8 + ((BIT(ram_val, 15) << 11) | rcrs10 | (ram_val & 0x03ff)); \ + hp##NUM = hp & 0xff; \ + hp >>= 8; \ + hps##NUM##0 = (BIT(hp, 0) || BIT(hp, 2)) && !BIT(hp, 3); \ + hps##NUM##1 = (BIT(hp, 1) || BIT(hp, 2)) && !BIT(hp, 3); \ + hps##NUM##2 = BIT(hp, 2); \ + +/* Check carry out calc */ +#define UPDATE_HPOS( NUM ) \ + if (hp##NUM##_en) \ + { \ + if ((hp##NUM & 0xff) == 0xff) \ + hp##NUM##_cy = 1; \ + else \ + hp##NUM = hp##NUM + 1; \ + } \ + + INT32 x; + UINT32 y; + UINT16 rva_offs; + UINT32 tnlmd0; + UINT32 tnlmd1; + UINT32 linf; + UINT32 tnlf; + UINT32 wangl; + UINT32 tcmd; + UINT32 wave0; + UINT32 wave1; + UINT32 rva20_6; + + /* ROM/PROM lookup tables */ + const UINT8 *rcols = (UINT8*)(memory_region(REGION_PROMS) + 0x1500); + const UINT8 *rom = memory_region(REGION_GFX6); + const UINT8 *prom0 = rom + 0x4000; + const UINT8 *prom1 = rom + 0x4200; + const UINT8 *prom2 = rom + 0x4400; + const UINT8 *vprom = rom + 0x4600; + + /* Extract constant values */ + tcmd = ((vregs.scol & 0xc000) >> 12) | ((vregs.scol & 0x00c0) >> 6); + tnlmd0 = BIT(vregs.flags, BB_RDFLAG_TNLMD0); + tnlmd1 = BIT(vregs.flags, BB_RDFLAG_TNLMD1); + linf = BIT(vregs.flags, BB_RDFLAG_LINF); + tnlf = BIT(vregs.flags, BB_RDFLAG_TNLF); + wangl = BIT(vregs.flags, BB_RDFLAG_WANGL); + wave0 = BIT(vregs.flags, BB_RDFLAG_WAVE0); + wave1 = BIT(vregs.flags, BB_RDFLAG_WAVE1); + rva_offs = BIT(vregs.flags, BB_RDFLAG_RVA7) ? 0x800 : 0xc00; + + profiler_mark(PROFILER_USER1); + + for (y = 0; y < 240; ++y) + { + UINT8 rva0_6; + UINT8 ram_addr; + UINT16 rcrdb0_15; + UINT16 rcrs10; + UINT16 ls161_156_a; + UINT16 ls161; + UINT8 sld; + UINT32 rva8; + UINT32 rm0, rm1; + UINT32 rcmd; + UINT32 bnkcs = 1; + + UINT32 x_offs; + + /* Vertical positions shift register */ + UINT32 ram_val; + UINT32 hp; + UINT32 vp1, vp2, vp3, vp4, vp5, vp6, vp7; + + /* PAL outputs */ + UINT32 ic4_o12; + UINT32 ic4_o13; + UINT32 ic149_o15; + UINT32 ic151_o14; + + /* Horizontal positions */ + UINT32 hp0, hp1, hp2, hp3; + UINT8 hps00, hps01, hps02; + UINT8 hps10, hps11, hps12; + UINT8 hps20, hps21, hps22; + UINT8 hps30, hps31, hps32; + + /* Road pixel data planes */ + UINT8 rc0 = 0, rc1 = 0, rc2 = 0, rc3 = 0; + + /* Horizontal position counter carry out */ + UINT8 hp0_cy = 0, hp1_cy = 0, hp2_cy = 0, hp3_cy = 0; + + UINT8 *bmpaddr = bitmap + (y * 256); + + UINT32 bank_cnt; + UINT8 roadpix; + + rva8 = (vregs.h_val & 0x8000) || !(vregs.shift & 0x80); + + /* Get RVA0_6 from TZ113 accumulator chain @ 122/123 */ + rva0_6 = (vregs.h_val >> 7) & 0x7f; + + /* For /WAVE bit logic later */ + rva20_6 = ((rva0_6 >> 3) & 0xe) | ((rva0_6 & 2) >> 1); + + /* RVA is inverted! */ + ram_addr = (~rva0_6 & 0x7f) << 1; + + /* Get the road RAM data for this line */ + rcrdb0_15 = buggyboy_rcram[(rva_offs + ram_addr) >> 1]; + + /* If 15-10 == 000000, then 0 */ + rcrs10 = rcrdb0_15 & 0xfc00 ? 0x0400 : 0x0000; + + /* If 15-10 == 111111, then 1 */ + ls161_156_a = (rcrdb0_15 & 0xfc00) == 0xfc00 ? 0x800 : 0x0000; + + /* LS161 15-bit counter chain - loaded with RAM data (bar bits 10-13) */ + ls161 = ((rcrdb0_15 & 0x8000) >> 1) | ls161_156_a | rcrs10 | (rcrdb0_15 & 0x03ff); + + /* SLD */ + sld = (vprom[rva0_6] + vregs.slin) & 0x38; + + /* Determine the x-offset */ + x_offs = ls161 & 7; + ls161 &= ~7; + + /* Fill vertical position shift register with bits for this line */ + /* TODO; cheated slightly to shift stuff up one pixel*/ + vp1 = buggyboy_rcram[(rva_offs + 0x1e2) >> 1] >= y ? 0 : 1; + vp2 = buggyboy_rcram[(rva_offs + 0x1e4) >> 1] >= y ? 0 : 1; + vp3 = buggyboy_rcram[(rva_offs + 0x1e6) >> 1] >= y ? 0 : 1; + vp4 = buggyboy_rcram[(rva_offs + 0x1e8) >> 1] >= y ? 0 : 1; + vp5 = buggyboy_rcram[(rva_offs + 0x1ea) >> 1] >= y ? 0 : 1; + vp6 = buggyboy_rcram[(rva_offs + 0x1ec) >> 1] >= y ? 0 : 1; + vp7 = buggyboy_rcram[(rva_offs + 0x1ee) >> 1] >= y ? 0 : 1; + + /* Stuff */ + rm0 = vp7 ? BIT(vregs.scol, 4) : BIT(vregs.scol, 12); + rm1 = vp7 ? BIT(vregs.scol, 5) : BIT(vregs.scol, 13); + + /* Wall/tunnel control */ + rcmd = (vp7 ? vregs.scol : vregs.scol >> 8) & 0xf; + + /* Load 'em up */ + LOAD_HPOS_COUNTER(0); + LOAD_HPOS_COUNTER(1); + LOAD_HPOS_COUNTER(2); + LOAD_HPOS_COUNTER(3); + + /* Some PAL equations that we can evaluate outside of the x-loop */ + ic4_o12 = (!vp1 && !vp2 && !vp6) || (!vp1 && !vp2 && vp7) || (vp4 && !vp6) || (vp4 && vp7); + ic4_o13 = (!vp1 && !vp2 && !vp5) || (!vp1 && !vp2 && vp7) || (vp3 && !vp5) || (vp3 && vp7); + ic149_o15 = (!vp5 && !vp6) || vp7 || !linf; + ic151_o14 = !BIT(sld, 3) || tnlmd0 || tnlmd1 || ic149_o15; + + /* Load the bank counter with accumulator bits 14-5 */ + bank_cnt = (vregs.ba_val >> 5) & 0x3ff; + + bnkcs = 1; + + for (x = -x_offs; x < 256; ++x) + { + UINT16 ls283_159; + UINT32 ls283_159_co; + UINT16 rha; + UINT32 rom_flip; + UINT32 rom_en; + UINT32 pix; + UINT32 hp0_en, hp1_en, hp2_en, hp3_en; + UINT32 _rorevcs = 0; + + /* The many PALs */ + + UINT32 ic149_o16; + + UINT32 ic4_o18; + UINT32 ic3_o15; + UINT32 ic150_o12 = 0; + UINT32 ic150_o16; + UINT32 ic150_o17; + UINT32 ic150_o18; + UINT32 ic150_o19; + UINT32 ic151_o15; + UINT32 ic151_o16; + UINT32 ic151_o17; + + UINT32 rcsd0_3 = 0; + + UINT32 sld5 = BIT(sld, 5); + UINT32 sld4 = BIT(sld, 4); + UINT32 mux; + + UINT32 cprom_addr; + + UINT8 px0, px1, px2, px3; + + /* Counter Q10-7 are added to 384 */ + ls283_159_co = (ls283_159 = (ls161 & 0x780) + X_ADJUST) & 0x800; + rom_flip = ls283_159 & 0x200 ? 0 : 1; + rom_en = !(ls283_159 & 0x400) && !(ls283_159_co ^ (ls161 & 0x800)); + + /* Strip pixel number */ + pix = (ls161 & 7) ^ 7; + + /* Horizotnal position counter enables - also used as PAL inputs */ + hp0_en = !(hp0_cy || hps02); + hp1_en = !(hp1_cy || hps12); + hp2_en = !(hp2_cy || hps22); + hp3_en = !(hp3_cy || hps32); + + _rorevcs = !( (rom_en && rom_flip) || (!rom_en && (ls161 & 0x4000)) ); + + /* Load in a new road gfx strip */ + if ( (ls161 & 7) == 0 ) + { + UINT8 d0 = 0; + UINT8 d1 = 0; + + /* TODO: ROM data is 0xff if not enabled. */ + if (rom_en) + { + UINT8 rom_data; + UINT16 prom_addr; + + /* 6 bit road horizontal address */ + rha = (ls283_159 & 0x180) | (ls161 & 0x78); + + if (rom_flip) + rha ^= 0x1f8; + + /* Get road chunk first */ + rom_data = rom[(1 << 13) | (rha << 4) | rva0_6]; + prom_addr = (rom_flip ? 0x80 : 0) | (rom_data & 0x7f); + + rc0 = prom0[prom_addr]; + rc1 = prom1[prom_addr]; + rc2 = prom2[prom_addr]; + + /* Now get the dirt chunk */ + rom_data = rom[(rha << 4) | rva0_6]; + prom_addr = 0x100 | rom_data; + + d0 = prom0[prom_addr]; + d1 = prom1[prom_addr]; + } + else + { + /* + TODO: When ROM is not enabled, data = 0xff + But does anybody care? + */ + rc0 = rc1 = rc2 = rc3 = 0; + } + + /* The data is mixed by two TZ0314 PALs */ + if (BIT(sld, 4)) + { + if (BIT(sld, 5)) + d1 = ~d1; + + rc3 = d0 & d1; + + if (rom_flip) + rc3 = BITSWAP8(rc3, 0, 1, 2, 3, 4, 5, 6, 7); + } + else + rc3 = 0; + } + + /* NEW!!!! Road camber */ + if (vregs.bank_mode == 0) + { + if ( BIT(vregs.ba_val, 23) ) + bnkcs = 1; + else if (vregs.ba_val & 0x007f8000) + bnkcs = 0; + else + bnkcs = bank_cnt < 0x300; + } + else + { + if ( BIT(vregs.ba_val, 23) ) + bnkcs = 0; + else if (vregs.ba_val & 0x007f8000) + bnkcs = 1; + else + bnkcs = bank_cnt >= 0x300; + } + + px0 = BIT(rc0, pix); + px1 = BIT(rc1, pix); + px2 = BIT(rc2, pix); + px3 = BIT(rc3, pix); + + /* + Uh oh... + */ + if (vp2) + ic4_o18 = (hps00 && hps01 && hp3_en && !hps30) || + (!hp0_en && hps01 && hp3_en && !hps30) || + (hps00 && hps01 && !hps31) || + (!hp0_en && hps01 && !hps31) || + vp7; + else + ic4_o18 = !vp1; + + + if (tnlf) + ic3_o15 = (vp4 && !vp6 && !hp2_en && hps21) || + (vp4 && !vp6 && hps20 && hps21) || + (vp1 && !vp4 && !tnlmd1 && !tnlmd0) || + (vp1 && !vp3 && !tnlmd1 && !tnlmd0) || + (hp1_en && !hps10 && vp3 && !vp5) || + (!hps11 && vp3 && !vp5); + else + ic3_o15 = !ic4_o18; + + ic151_o17 = (_rorevcs && !tnlmd1 && tnlmd0) || + (!_rorevcs && tnlmd1 && !tnlmd0) || + (_rorevcs && ic4_o12) || + (!_rorevcs && ic4_o13); + + if (!ic3_o15) + ic151_o15 = (px0 && (bnkcs && wangl)) || + (px1 && (bnkcs && wangl)) || + ic151_o17 || + px2 || + !tnlf; + else + ic151_o15 = !tnlf; + + ic151_o16 = (px1 && !px0 && tnlmd1 && !tnlmd0) || + (px2 && tnlmd1 && tnlmd0) || + ic149_o15; + + mux = BIT(tcmd, 3) ? ic149_o15 : ic151_o16; + + ic150_o19 = (px2 && !rva8) || + !bnkcs || + !mux || + !ic151_o15; + + /* Don't calculate the pixel colour if not visible */ + if (ic150_o19) + { + ic149_o16 = (_rorevcs && !px2 && ic151_o15) || + (tnlf && vp5 && !vp7 && px2 && !tnlmd0 && !tnlmd1 && ic151_o15) || + (tnlf && vp6 && !vp7 && px2 && !tnlmd0 && !tnlmd1 && ic151_o15) || + (tnlf && !ic4_o18); + + ic150_o16 = (px2 && mux && rm1) || + (mux && rva8 && ic151_o15) || + (!px0 && mux) || + !ic151_o15; + + { + UINT32 a = mux && ic151_o15; + + ic150_o17 = (a && !rm0 && px0) || + (a && !px1) || + (rva8 && a); + + ic150_o18 = (a && !px2) || + (rva8 && a); + } + + if (ic151_o14) + ic150_o12 = rva8 || !mux || !ic151_o15 || + (px2 && px1 && px0 && rm1 && !rm0) || + (!px2 && px1 && px0 && !sld4 && rm0) || + (px2 && px0 && !sld5 && !rm1 && !rm0) || + (px2 && !px1 && px0 && !sld5 && !rm1) || + (px2 && px1 && px0 && !sld5 && !sld4) || + (px2 && px1 && px0 && !sld4 && rm1) || + (!px2 && !px3 && !rm0) || + (!px1 && !px3 && rm1) || + (!px2 && !px1 && !px3) || + (!px0 && !px3); + else + ic150_o12 = 0; + + if (vp6 || ic151_o16) + { + UINT32 ic150_i5 = BIT(tcmd, 3) ? ic149_o15 : ic151_o16; + + if ( !(ic151_o15 && ic150_i5) ) + cprom_addr = (tcmd & 0x7) | (ic151_o16 ? 0x08 : 0); + else + cprom_addr = rcmd; + + /* Inverted! */ + cprom_addr = ((~cprom_addr) & 0xf) << 4; + } + else + cprom_addr = 0xf0; + + cprom_addr |= (ic149_o16 ? 0x8 : 0) | + (ic150_o18 ? 0x4 : 0) | + (ic150_o17 ? 0x2 : 0) | + (ic150_o16 ? 0x1 : 0); + + /* Lower four bits of colour output come from PROM BB7 @ 188 */ + rcsd0_3 = rcols[cprom_addr] & 0xf; + + { + UINT32 lfsr = vregs.wave_lfsr; + UINT32 wave = + (wave0 ^ BIT(lfsr, 0)) && + (wave1 ^ BIT(lfsr, 3)) && + BIT(lfsr, 5) && + !BIT(lfsr, 15) && + BIT(lfsr, 11) && + BIT(lfsr, 13) && + (rva20_6 < ((lfsr >> 8) & 0xf)); + + roadpix = 0x40 | (wave ? 0 : 0x20) | (ic150_o12 ? 0x10 : 0) | rcsd0_3; + } + } + else + roadpix = 0; + + + /* Horizontal position counters */ + if (x >= 0) + { + *bmpaddr++ = roadpix; + + UPDATE_HPOS(0); + UPDATE_HPOS(1); + UPDATE_HPOS(2); + UPDATE_HPOS(3); + + /* Update the LFSR */ + vregs.wave_lfsr = (vregs.wave_lfsr << 1) | (BIT(vregs.wave_lfsr, 6) ^ !BIT(vregs.wave_lfsr, 15)); + + /* Increment the bank counter */ + bank_cnt = (bank_cnt + 1) & 0x7ff; + } + + /* X pos */ + ls161 = (ls161 + 1) & 0x7fff; + } + + /* WANGL active? Update the 8-bit counter */ + if ( wangl ) + { + if ( BIT(vregs.flags, BB_RDFLAG_TNLMD0) ) + vregs.wa8 -= 1; + else + vregs.wa8 += 1; + } + + /* No carry out - just increment */ + if ( vregs.wa4 != 0xf ) + vregs.wa4 += 1; + else + { + /* Carry out; increment again on /TMG2S rise */ + if ( wangl ) + { + if ( BIT(vregs.flags, BB_RDFLAG_TNLMD0) ) + vregs.wa8 -= 1; + else + vregs.wa8 += 1; + } + vregs.wa4 = 1; + } + + /* Update accumulator */ + vregs.h_val += vregs.h_inc; + + /* Seems correct */ + { + UINT8 sf = vregs.shift; + + if ((vregs.shift & 0x80) == 0) + { + vregs.shift <<= 1; + + if ((sf & 0x08) == 0) + vregs.shift |= BIT(vregs.h_val, 15); + } + + if ((sf & 0x08) && !(vregs.shift & 0x08)) + vregs.h_inc = vregs.gas; + } + + /* Finally, increment the banking accumulator */ + vregs.ba_val = (vregs.ba_val + vregs.ba_inc) & 0x00ffffff; + } + + profiler_mark(PROFILER_END); +} + + +/*************************************************************************** + + Buggy Boy Object Drawing + + X-scaling isn't quite right but you wouldn't notice... + + -------- xxxxxxxx Object number + xxxxxxxx -------- Y position + + xxxxxxxx xxxxxxxx Y scale value + + -------- xxxxxxxx X scale + 00 = Invisible? + 80 = 1:1 + FF = Double size + xxxxxxxx -------- Attributes + + xxxxxxxx xxxxxxxx Y scale delta + + ------xx xxxxxxxx X position + +**************************************************************************/ +static void buggyboy_draw_objs(UINT8 *bitmap) +{ +#define FRAC 16 + + UINT32 offs; + + /* The many lookup table ROMs */ + const UINT8 *const bug13 = (UINT8*)memory_region(REGION_USER3); + const UINT8 *const bug18s = (UINT8*)memory_region(REGION_USER3) + 0x2000; + const UINT8 *const bb8 = (UINT8*)memory_region(REGION_PROMS) + 0x1600; + + const UINT8 *const bug16s = (UINT8*)memory_region(REGION_USER2); + const UINT8 *const bug17s = (UINT8*)memory_region(REGION_USER2) + 0x8000; + + const UINT8 *const bb9o = (UINT8*)memory_region(REGION_PROMS) + 0x500; + const UINT8 *const bb9e = (UINT8*)memory_region(REGION_PROMS) + 0xd00; + + const UINT8 *const pixdata_rgn = (UINT8*)memory_region(REGION_GFX2); + + profiler_mark(PROFILER_USER1); + + for (offs = 0; offs <= buggyboy_objram_size; offs += 8) + { + UINT32 x; + UINT32 y; + UINT32 gxflip; + + UINT32 x_scale; + UINT32 x_step; + UINT16 y_scale; + UINT16 y_step; + + UINT8 pctmp0_7; + UINT8 code; + + /* Check for end of object list */ + if ( (buggyboy_objram[offs] & 0xff00) == 0xff00 ) + break; + + /* X scale */ + x_scale = buggyboy_objram[offs + 2] & 0xff; + + /* TODO: Confirm against hardware? */ + if ( x_scale == 0 ) + continue; + + /* 16-bit y-scale accumulator */ + y_scale = buggyboy_objram[offs + 1]; + y_step = buggyboy_objram[offs + 3]; + + /* Object number */ + code = buggyboy_objram[offs] & 0xff; + + /* Attributes */ + pctmp0_7 = buggyboy_objram[offs + 2] >> 8; + + /* Global x-flip */ + gxflip = (pctmp0_7 & 0x80) >> 7; + + /* Add 1 to account for line buffering */ + y = (buggyboy_objram[offs] >> 8) + 1; + + if (code == 0xa8) + code = 0xa8; + + for (; y < 240; ++y) + { + UINT32 rom_addr2 = 0; + UINT8 bug17s_data = 0; + UINT8 bug16s_data; + + /* Are we drawing on this line? */ + + // TODO: See big lampposts. + if ( y_scale & 0x8000 ) + break; + + { + UINT32 psa0_12; + UINT32 bug13_addr; + UINT32 bug13_data; + UINT32 rom_addr; + UINT32 x_acc; + UINT32 newtile = 1; + UINT32 dataend = 0; + UINT8 data1 = 0; + UINT8 data2 = 0; + UINT32 xflip = 0; + UINT32 opcd10_11; + UINT32 opcd8_9; + UINT32 opcd0_11 = 0; + UINT32 lasttile = 0; + + /* Use the object code to lookup the tile sequence data */ + bug13_addr = code << 4; + bug13_addr |= ((y_scale >> 11) & 0xf); + bug13_data = bug13[bug13_addr]; + + /* Reached the bottom of the object */ + if (bug13_data == 0xff) + break; + + psa0_12 = (((code & 0x80) << 5) | ((code & 0x40) << 6)) & 0x1000; + psa0_12 |= ((bb8[code] << 8) | bug13_data) & 0x1fff; + + /* Static part of the BUG17S/BUG16S ROM address */ + rom_addr = (psa0_12 & ~0xff) << 2; + + /* Prepare the x-scaling */ + x_step = (128 << FRAC) / x_scale; + x_acc = (psa0_12 & 0xff) << (FRAC + 5); + + /* TODO Add note */ + x = buggyboy_objram[offs + 4] & 0x3ff; + + for (;;) + { + #define MASK 0x3ff + + /* Get data and attributes for an 8x8 tile */ + if (newtile) + { + UINT32 pscb0_11; + UINT32 psbb0_15; + UINT32 psbb6_7; + UINT32 rombank; + UINT8 *romptr; + UINT32 bug18s_data; + UINT32 low_addr = ((x_acc >> (FRAC + 3)) & MASK); + + /* + Objects are grouped by width (either 16, 8 or 4 tiles) in + the LUT ROMs. The ROM address lines therefore indicate + width and are used to determine the correct scan order + when x-flip is set. + */ + if (gxflip) + { + UINT32 xor_mask; + + if ( BIT(psa0_12, 11) || !BIT(psa0_12, 12) ) + xor_mask = 0xf; + else if ( !BIT(psa0_12, 9) ) + xor_mask = 0x7; + else + xor_mask = 0x3; + + rom_addr2 = rom_addr + (low_addr ^ xor_mask); + } + else + rom_addr2 = rom_addr + low_addr; + + bug17s_data = bug17s[rom_addr2 & 0x7fff]; + + if ((bug17s_data & 0x40) && dataend) + lasttile = 1; + + dataend |= (bug17s_data & 0x40); + + /* Retrieve data for an 8x8 tile */ + bug16s_data = bug16s[rom_addr2]; + psbb0_15 = (bug17s_data << 8) | bug16s_data; + psbb6_7 = (BIT(psbb0_15, 12) ? psbb0_15 : (pctmp0_7 << 6)) & 0xc0; + + /* Form the tile ROM address */ + pscb0_11 = ((((psbb0_15 & ~0xc0) | psbb6_7) << 3) | ((y_scale >> 8) & 7)) & 0x7fff; + + /* Choose from one of three banks */ + rombank = ((BIT(pctmp0_7, 4) << 1) | BIT(psbb0_15, 13)) & 3; + + /* TODO: Remember to put all the data into one GFX region */ + romptr = (UINT8*)(pixdata_rgn + rombank * (0x8000 * 2)); + + /* Get raw 8x8 pixel row data */ + data1 = *(pscb0_11 + romptr); + data2 = *(pscb0_11 + romptr + 0x8000); + + /* Determine flip state (global XOR local) */ + xflip = gxflip ^ !BIT(psbb0_15, 15); + + bug18s_data = bug18s[ (BIT(pctmp0_7, 4) << 13) | + (BIT(psbb0_15, 13) << 12) | + (psbb0_15 & ~0xf0c0) | + psbb6_7 ]; + + /* Get the colour data. Note that bits 11 and 10 are inverted */ + opcd10_11 = ((pctmp0_7 << 8) & 0xc00) ^ 0xc00; + opcd8_9 = ((pctmp0_7 & 0x60) << 3); + opcd0_11 = (opcd10_11 | opcd8_9 | bug18s_data) & 0xfff; + + newtile = 0; + } + + /* Draw a pixel? */ + if (x < 256) + { + UINT8 pix; + UINT8 bit; + + bit = (x_acc >> FRAC) & 7; + + if (xflip) + bit ^= 7; + + pix = (((data1 >> bit) & 1) << 1) | ((data2 >> bit) & 1); + + /* Write the pixel if not transparent */ + if ( !(!(opcd0_11 & 0x80) && !pix) ) + { + UINT8 color; + UINT32 bb9_addr; + + bb9_addr = ((opcd0_11 << 1) & 0x600) | ((opcd0_11 & 0x7f) << 2) | pix; + color = ((opcd0_11 >> 6) & 0x30); + + /* Inverted on schematic */ + if (x & 1) + color = ~(color | bb9o[bb9_addr]) & 0x3f; + else + color = ~(color | bb9e[bb9_addr]) & 0x3f; + + *(bitmap + 256*y + x) = 0x40 | color; + } + } + + /* Check if we've stepped into a new 8x8 tile */ + if ( (((x_acc + x_step) >> (FRAC + 3)) & MASK) != ((x_acc >> (FRAC + 3)) & MASK) ) + { + if (lasttile) + break; + + newtile = 1; + } + + x = (x + 1) & 0x3ff; + x_acc += x_step; + } + }// if (yscale) + y_scale += y_step; + } /* for (y) */ + }/* for (offs) */ + + profiler_mark(PROFILER_END); } /* + 2400-24FF is road control (R/W) - Applies to both versions of Buggy Boy - - Each object entry occupies 16 bytes: - - Byte 0: Sprite code - Byte 1: Y-Position (bit 15 has some significance) - - Byte 2: Scale - Byte 3: Scale - - Byte 4: Scale 0=Tiny 0x7f=Normal 0xff=Huge ? - Byte 5: Bit 7 = X-Flip, Bit 4 = chunk bank, Bit 5-6 = palette select, Bit 0-1 = palette related (PC_TMP) - - Byte 6: Scale - Byte 7: Scale - - Byte 8: X position bits 0-7 - Byte 9: X position bits 8-9 - - Remaining bytes are unusued. - + /GAS = 24XX: + /BASET0 = 2400-F, 2410-F + /BASET1 = 2420-F, 2430-F + /BSET = 2440-F, 2450-F + /HASET = 2460-F, 2470-F + /HSET = 2480-F, 2490-F + /WASET = 24A0-F, 24B0-F + /FLAGS = 24E0-F, 24F0-F */ - -/* Rewrite once scale parameters etc. are discovered */ -static void draw_objects(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect,int xdrawoffset) +WRITE16_HANDLER( buggyboy_gas_w ) { - int offs; + offset <<= 1; - UINT8 PROM_lookup; - UINT16 ROM_lookup; - - UINT8 *rom_lut = (UINT8 *)memory_region(REGION_USER3); /* Object index ROM */ - UINT8 *prom_lut = (UINT8 *)memory_region(REGION_PROMS)+0x1600; /* Object index PROM */ - - UINT8 *ROM_LUTA = (UINT8 *)memory_region(REGION_USER2); /* Object LUT (lower byte) */ - UINT8 *ROM_LUTB = (UINT8 *)memory_region(REGION_USER2)+0x8000; /* Object LUT (lower byte) */ - UINT8 *ROM_CLUT = (UINT8 *)memory_region(REGION_USER3)+0x2000; /* Object palette LUT */ - - for (offs = 0x0; offs <= (bb_objectram_size)/2; offs += 8) + switch (offset & 0xe0) { - int inc,last; - int bit_12, PSA0_12, PSA, object_flip_x; - int index_y,index_x,index=0; - - - if((bb_objram[offs+0] >> 8) == 0xff) /* End of object list marker? */ - return; - - /* The object code is fed into ROM and PROM to generate a lookup into a pair of ROMs */ - PROM_lookup = bb_objram[offs] & 0xff; - ROM_lookup = ((bb_objram[offs] & 0xff) << 4) | ((bb_objram[offs+1]>>11) & 0xf); - - if(rom_lut[ROM_lookup] == 0xff) /* Do not draw object */ - continue; - - - /* Calculate 13-bit index into object lookup ROMs that holds 8x8 chunk sequence */ - bit_12 = (((bb_objram[offs]>>7)&0x1) | ((bb_objram[offs]>>6)&0x1)) <<12; - PSA0_12 = ( ( (prom_lut[PROM_lookup]&0xf)<<8) | rom_lut[ROM_lookup] | bit_12) & 0x1fff; - - PSA = (PSA0_12 << 2); - - object_flip_x = (bb_objram[offs+2]>>15)&0x1; - - for (index_y=0; index_y<16; index_y++) + case 0x00: { - if (object_flip_x) + vregs.ba_inc &= ~0x0000ffff; + vregs.ba_inc |= data; + + if ( !(offset & 2) ) + vregs.ba_val &= ~0x0000ffff; + + break; + } + case 0x20: + { + data &= 0xff; + vregs.ba_inc &= ~0xffff0000; + vregs.ba_inc |= data << 16; + + vregs.bank_mode = data & 1; + + if ( !(offset & 2) ) + vregs.ba_val &= ~0xffff0000; + + break; + } + case 0x40: + { + /* Ignore data? */ + if ( offset & 2 ) { - index_x=16; - inc=-1; - last=0; - } - else - { - index_x=0; - inc=1; - last=16; + vregs.ba_val = (vregs.ba_inc + vregs.ba_val) & 0x00ffffff; } - while(index_x!=last) - { - /* Bit 14 of chunk_number = data_end, related to end of line */ - int chunk_number = (ROM_LUTB[PSA+index]<<8) | ROM_LUTA[PSA+index]; // PSBB0-15 + break; + } + case 0x60: + { + vregs.h_inc = data; + vregs.shift = 0; - int sx = (bb_objram[offs+4])+(index_x*8); - int sy = (bb_objram[offs+0] >> 8)+(index_y*7); + if ( !(offset & 2) ) + vregs.h_val = 0; - /* Calculate the 14-bit CLUT ROM address */ - int bit13 = (bb_objram[offs+2] & 0x1000) << 1; - int bit12 = (chunk_number & 0x2000) >> 1; + break; + } + case 0x80: + { + /* Ignore data? */ + if ( offset & 2 ) + vregs.h_val += vregs.h_inc; + break; + } + case 0xa0: + { + vregs.wa8 = data >> 8; + vregs.wa4 = 0; + break; + } + case 0xe0: + { + cpunum_set_input_line(1, INPUT_LINE_TEST, CLEAR_LINE); + vregs.flags = data; + break; + } + } - /* Tile Number bit 12 -> 1 = Bits 6-7 of BUG16s or bits 8-9 of PC_TMP */ - int bits6_and_7 = (chunk_number & 0x1000 ? chunk_number : bb_objram[offs+2] >> 2) & 0xc0; - int CLUT_ROM_ADDR = (chunk_number & 0xf3f) + bits6_and_7 + bit12 + bit13; - - /* Now form the 12 bit OPCD */ - int bits10_and_11 = 0xc00 - (bb_objram[offs+2] & 0xc00); - int OPCS = (bb_objram[offs+2] & 0x6000) >> 5; // bits 8 and 9 - int OPCD = (ROM_CLUT[CLUT_ROM_ADDR] + OPCS + bits10_and_11) & 0xfff; - - int tmp = (OPCD&0x7f); // bits 0-6 - int tmp2= (OPCD&0x300)>>1; // bits 9,8 (bit 7 is not there) - int tmp3 = bits10_and_11 >> 1; - - int color = (tmp + tmp2 + tmp3); - int trans; - - /* 8x8 chunk ROM bank (0-2) */ - int bank = (((bb_objram[offs+2]>>11)&0x2) | ((chunk_number>>13)&0x1))+1; - int zoomx = 0xffff; //object_ram[offs+6]<<8; - int zoomy = 0xffff; //object_ram[offs+4]<<8; - int flipx = ((chunk_number>>15) & 0x1) ^ object_flip_x; - int flipy = 0; - - const gfx_element *gfx = machine->gfx[bank]; - - if(!(OPCD & 0x80)) /* Seems to work! */ - trans = TRANSPARENCY_PEN; - else - trans = TRANSPARENCY_NONE; - - index_x+=inc; - index++; - - drawgfxzoom(bitmap, gfx, - chunk_number, - color, - flipx,flipy, - sx-xdrawoffset,sy, - cliprect,trans,0, - zoomx,zoomy); - } - } - } + /* Value is latched by LS373 76/77 */ + vregs.gas = data; } -VIDEO_START( buggyb1 ) +WRITE16_HANDLER( buggyboy_sky_w ) { - buggyb1_tilemap = tilemap_create(get_buggyb1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,64,64); - tilemap_set_transparent_pen(buggyb1_tilemap, 0); + vregs.sky = data; } +WRITE16_HANDLER( buggyboy_slincs_w ) +{ + if ( offset == 1 ) + vregs.slin_inc = data; + else + vregs.slin_inc = vregs.slin = 0; +} + +WRITE16_HANDLER( buggyboy_scolst_w ) +{ + vregs.scol = data; +} + + VIDEO_START( buggyboy ) { - buggyboy_tilemap = tilemap_create(get_buggyboy_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,128,64); - tilemap_set_transparent_pen(buggyboy_tilemap, 0); + buggyboy_tilemap = tilemap_create(get_buggyboy_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8, 8, 128, 64); + tilemap_set_transparent_pen(buggyboy_tilemap, 0); } -/* Gradient sky - 'scrolls' up and down */ -static void draw_sky(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) -{ - int x,y,colour; - for (y = cliprect->min_y; y <= cliprect->max_y; y++) - { - for (x = cliprect->min_x; x <= cliprect->max_x; x++) - { - colour = (((*bb_sky & 0x7f) + y)>>2)&0x3f; - *BITMAP_ADDR16(bitmap, y, x) = machine->pens[0x80 + colour]; - } - } -} - - -/* -The current layer mixing implementation is incorrect. - -On the actual PCB, the GAME OVER sign chains should be behind the text but the -objects are often in front of the characters. - -See schematic page 11 for mixing logic. - -*/ - - -VIDEO_UPDATE( buggyb1 ) -{ - if(*bb_sky & 0x80) - { - draw_sky(machine, bitmap, cliprect); - tilemap_draw(bitmap,cliprect,buggyb1_tilemap,0,0); - draw_objects(machine, bitmap,cliprect,0); - } - else - { - tilemap_draw(bitmap,cliprect,buggyb1_tilemap,TILEMAP_DRAW_OPAQUE,0); - draw_objects(machine, bitmap,cliprect,0); - } - return 0; -} - VIDEO_UPDATE( buggyboy ) { - /* the video hardware seems to use one large tilemap, scroll it to the right position for each screen */ - int xscrollamount = screen*256; - tilemap_set_scrollx(buggyboy_tilemap,0,xscrollamount); + /* The video hardware seems to use one large tilemap, scroll it to the right position for each screen */ + int xscrollamount = screen * 256; + tilemap_set_scrollx(buggyboy_tilemap, 0, xscrollamount); + + tilemap_draw(bitmap, cliprect, buggyboy_tilemap, TILEMAP_DRAW_OPAQUE, 0); + return 0; +} + + +VIDEO_EOF( buggyboy ) +{ + /* /VSYNC: Update TZ113 @ 219 */ + vregs.slin += vregs.slin_inc; + + /* /VSYNC: Clear wave LFSR */ + vregs.wave_lfsr = 0; +} + + +VIDEO_START( buggybjr ) +{ + /* Allocate some bitmaps */ + chr_bmp = auto_malloc(sizeof(UINT8) * 256 * 240); + obj_bmp = auto_malloc(sizeof(UINT8) * 256 * 240); + rod_bmp = auto_malloc(sizeof(UINT8) * 256 * 240); +} + +/* + Draw the tilemap with scrolling +*/ +static void buggyboy_draw_char(UINT8 *bitmap) +{ + INT32 x, y; + UINT32 scroll_x, scroll_y; + UINT8 *gfx1, *gfx2; + + profiler_mark(PROFILER_USER3); + + /* 2bpp characters */ + gfx1 = memory_region(REGION_GFX1); + gfx2 = memory_region(REGION_GFX1) + 0x4000; + + /* X/Y scroll values are the last word in char RAM */ + scroll_y = (buggybjr_vram[0x7ff] >> 10) & 0x3f; + scroll_x = buggybjr_vram[0x7ff] & 0x1ff; + + for (y = 0; y < 240; ++y) + { + UINT32 d0 = 0, d1 = 0; + UINT32 colour = 0; + UINT32 y_offs; + UINT32 x_offs; + UINT32 y_gran; + + /* There's no y-scrolling between scanlines 0 and 1 */ + if (y < 64) + y_offs = y; + else + { + y_offs = (y + (scroll_y | 0xc0) + 1) & 0xff; + + /* Clamp */ + if (y_offs < 64) + y_offs |= 0xc0; + } + + if ( (y_offs >= 64) && (y_offs < 128) ) + x_offs = scroll_x; + else + x_offs = 0; + + + y_gran = y_offs & 7; + + if (x_offs & 7) + { + UINT32 tilenum; + UINT16 ram_val = buggybjr_vram[((y_offs << 3) & 0x7c0) + ((x_offs >> 3) & 0x3f)]; + + tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5); + colour = (ram_val & 0xfc00) >> 8; + d0 = *(gfx2 + (tilenum << 3) + y_gran); + d1 = *(gfx1 + (tilenum << 3) + y_gran); + } + + for (x = 0; x < 256; ++x) + { + UINT32 x_gran = x_offs & 7; + + if (!x_gran) + { + UINT32 tilenum; + UINT16 ram_val = buggybjr_vram[((y_offs << 3) & 0x7c0) + ((x_offs >> 3) & 0x3f)]; + + tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5); + colour = (ram_val & 0xfc00) >> 8; + d0 = *(gfx2 + (tilenum << 3) + y_gran); + d1 = *(gfx1 + (tilenum << 3) + y_gran); + } + + *bitmap++ = colour | + (((d1 >> (7 ^ x_gran)) & 1) << 1) | + ((d0 >> (7 ^ x_gran)) & 1); + + x_offs = (x_offs + 1) & 0x1ff; + } + + } + + profiler_mark(PROFILER_END); +} + +VIDEO_UPDATE( buggybjr ) +{ + int x, y; + UINT8 *chr_pal = (memory_region(REGION_PROMS) + 0x400); + + memset(obj_bmp, 0, 256*240); + + buggyboy_draw_char(chr_bmp); + buggybjr_draw_road(rod_bmp); + buggyboy_draw_objs(obj_bmp); + + for (y = 0; y < 240; ++y) + { + UINT16 *bmp_addr = BITMAP_ADDR16(bitmap, y, 0); + + UINT8 *chr_addr = chr_bmp + (y * 256); + UINT8 *rod_addr = rod_bmp + (y * 256); + UINT8 *obj_addr = obj_bmp + (y * 256); + + UINT32 sky_en = BIT(vregs.sky, 7); + UINT32 sky_val = (((vregs.sky & 0x7f) + y) >> 2) & 0x3f; + + for (x = 0; x < 256; ++x) + { + UINT32 out_val; + + UINT32 char_val = *chr_addr++; + UINT32 char_6_7 = (char_val & 0xc0) >> 2; + + UINT32 obj_val = *obj_addr++; + UINT32 obj6 = BIT(obj_val, 6); + + UINT32 rod_val = *rod_addr++; + UINT32 rod6 = BIT(rod_val, 6); + + UINT32 chr = !(BIT(char_val, 7) && (char_val & 3) ); + + UINT32 sel = + ( + ( BIT(obj_val, 6) && chr) || + ( sky_en && !(char_val & 3) && (!obj6 && !rod6) ) + ) ? 0 : 1; + + sel |= (!(obj6 || rod6) || !chr) ? 2 : 0; + + /* Select the layer */ + if (sel == 0) out_val = obj_val & 0x3f; + else if (sel == 1) out_val = rod_val & 0x3f; + else if (sel == 2) out_val = sky_val; + else out_val = char_6_7 + chr_pal[char_val]; + + *bmp_addr++ = (sel << 6) + out_val; + } + } - if(*bb_sky & 0x80) - { - draw_sky(machine, bitmap, cliprect); - tilemap_draw(bitmap,cliprect,buggyboy_tilemap,0,0); - draw_objects(machine, bitmap,cliprect,xscrollamount); - } - else - { - tilemap_draw(bitmap,cliprect,buggyboy_tilemap,TILEMAP_DRAW_OPAQUE,0); - draw_objects(machine, bitmap,cliprect,xscrollamount); - } return 0; }