1 // license:BSD-3-Clause
2 // copyright-holders:Manuel Abadia, Peter Ferrie, David Haywood
3 /***************************************************************************
4
5 Thunder Hoop II: Strikes Back (c) 1994 Gaelco
6
7 Driver by Manuel Abadia <emumanu+mame@gmail.com>
8
9 updated by Peter Ferrie <peter.ferrie@gmail.com>
10
11 There is a priority bug on the title screen (Gaelco logo is hidden by black
12 borders) It seems sprite priority is hacked around on most of the older
13 Gaelco drivers.
14
15
16 REF.940411
17 +-------------------------------------------------+
18 | C1 6116 |
19 | VOL C2* 6116 |
20 | 30MHz 6116 |
21 | M6295 +----------+ 6116 |
22 | 1MHz |TMS | |
23 | 6116 |TPC1020AFN| |
24 |J 6116 | -084C | H8 |
25 |A +------------+ +----------+ |
26 |M |DS5002FP Box| +----------+ |
27 |M +------------+ |TMS | H12 |
28 |A 65756 |TPC1020AFN| |
29 | 65756 | -084C | |
30 | +----------+ |
31 |SW1 PAL 65764|
32 | 24MHz MC68000P12 65764|
33 |SW2 C22 6116 |
34 | PAL C23 6116 |
35 +-------------------------------------------------+
36
37 CPU: MC68000P12 & DS5002FP (used for protection)
38 Sound: OKI M6295
39 OSC: 30MHz, 24MHz & 1MHz resonator
40 RAM: MHS HM3-65756K-5 32K x 8 SRAM (x2)
41 MHS HM3-65764E-5 8K x 8 SRAM (x2)
42 UM6116BK-35 2K x 8 SRAM (x8)
43 PAL: TI F20L8-25CNT DIP24 (x2)
44 VOL: Volume pot
45 SW: Two 8 switch dipswitches
46
47 DS5002FP Box contains:
48 Dallas DS5002SP @ 12MHz
49 KM62256BLG-7L - 32Kx8 Low Power CMOS SRAM
50 3.6v Battery
51 JP1 - 5 pin port to program SRAM
52
53 Measurements from actual PCB:
54 DS5002FP - 12MHz
55 OKI MSM6295 - 1MHz, pin 7 is disconnected (neither pulled LOW or HIGH)
56 H-SYNC - 15.151KHz
57 V-SYNC - 59.24Hz
58
59 ***************************************************************************/
60
61 #include "emu.h"
62 #include "includes/thoop2.h"
63
64 #include "machine/gaelco_ds5002fp.h"
65
66 #include "cpu/m68000/m68000.h"
67 #include "cpu/mcs51/mcs51.h"
68 #include "machine/74259.h"
69 #include "machine/watchdog.h"
70 #include "sound/okim6295.h"
71
72 #include "screen.h"
73 #include "speaker.h"
74
75
machine_start()76 void thoop2_state::machine_start()
77 {
78 m_okibank->configure_entries(0, 16, memregion("oki")->base(), 0x10000);
79 }
80
oki_bankswitch_w(uint8_t data)81 void thoop2_state::oki_bankswitch_w(uint8_t data)
82 {
83 m_okibank->set_entry(data & 0x0f);
84 }
85
WRITE_LINE_MEMBER(thoop2_state::coin1_lockout_w)86 WRITE_LINE_MEMBER(thoop2_state::coin1_lockout_w)
87 {
88 machine().bookkeeping().coin_lockout_w(0, !state);
89 }
90
WRITE_LINE_MEMBER(thoop2_state::coin2_lockout_w)91 WRITE_LINE_MEMBER(thoop2_state::coin2_lockout_w)
92 {
93 machine().bookkeeping().coin_lockout_w(1, !state);
94 }
95
WRITE_LINE_MEMBER(thoop2_state::coin1_counter_w)96 WRITE_LINE_MEMBER(thoop2_state::coin1_counter_w)
97 {
98 machine().bookkeeping().coin_counter_w(0, state);
99 }
100
WRITE_LINE_MEMBER(thoop2_state::coin2_counter_w)101 WRITE_LINE_MEMBER(thoop2_state::coin2_counter_w)
102 {
103 machine().bookkeeping().coin_counter_w(1, state);
104 }
105
shareram_w(offs_t offset,uint8_t data)106 void thoop2_state::shareram_w(offs_t offset, uint8_t data)
107 {
108 // why isn't there address map functionality for this?
109 reinterpret_cast<u8 *>(m_shareram.target())[BYTE_XOR_BE(offset)] = data;
110 }
111
shareram_r(offs_t offset)112 uint8_t thoop2_state::shareram_r(offs_t offset)
113 {
114 // why isn't there address map functionality for this?
115 return reinterpret_cast<u8 const *>(m_shareram.target())[BYTE_XOR_BE(offset)];
116 }
117
118
mcu_hostmem_map(address_map & map)119 void thoop2_state::mcu_hostmem_map(address_map &map)
120 {
121 map(0x8000, 0xffff).rw(FUNC(thoop2_state::shareram_r), FUNC(thoop2_state::shareram_w)); // confirmed that 0x8000 - 0xffff is a window into 68k shared RAM
122 }
123
124
thoop2_map(address_map & map)125 void thoop2_state::thoop2_map(address_map &map)
126 {
127 map(0x000000, 0x0fffff).rom(); /* ROM */
128 map(0x100000, 0x101fff).ram().w(FUNC(thoop2_state::vram_w)).share("videoram"); /* Video RAM */
129 map(0x108000, 0x108007).writeonly().share("vregs"); /* Video Registers */
130 map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); /* INT 6 ACK/Watchdog timer */
131 map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");/* Palette */
132 map(0x440000, 0x440fff).ram().share("spriteram"); /* Sprite RAM */
133 map(0x700000, 0x700001).portr("DSW2");
134 map(0x700002, 0x700003).portr("DSW1");
135 map(0x700004, 0x700005).portr("P1");
136 map(0x700006, 0x700007).portr("P2");
137 map(0x700008, 0x700009).portr("SYSTEM");
138 map(0x70000b, 0x70000b).select(0x000070).lw8(NAME([this] (offs_t offset, u8 data) { m_outlatch->write_d0(offset >> 4, data); }));
139 map(0x70000d, 0x70000d).w(FUNC(thoop2_state::oki_bankswitch_w)); /* OKI6295 bankswitch */
140 map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); /* OKI6295 data register */
141 map(0xfe0000, 0xfe7fff).ram(); /* Work RAM */
142 map(0xfe8000, 0xfeffff).ram().share("shareram"); /* Work RAM (shared with D5002FP) */
143 }
144
145
oki_map(address_map & map)146 void thoop2_state::oki_map(address_map &map)
147 {
148 map(0x00000, 0x2ffff).rom();
149 map(0x30000, 0x3ffff).bankr("okibank");
150 }
151
152
153 static INPUT_PORTS_START( thoop2 )
154 PORT_START("DSW1")
155 PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_B ) )
156 PORT_DIPSETTING( 0x02, DEF_STR( 6C_1C ) )
157 PORT_DIPSETTING( 0x03, DEF_STR( 5C_1C ) )
158 PORT_DIPSETTING( 0x04, DEF_STR( 4C_1C ) )
159 PORT_DIPSETTING( 0x05, DEF_STR( 3C_1C ) )
160 PORT_DIPSETTING( 0x06, DEF_STR( 2C_1C ) )
161 PORT_DIPSETTING( 0x01, DEF_STR( 3C_2C ) )
162 PORT_DIPSETTING( 0x00, DEF_STR( 4C_3C ) )
163 PORT_DIPSETTING( 0x07, DEF_STR( 1C_1C ) )
164 PORT_DIPNAME( 0x38, 0x38, DEF_STR( Coin_A ) )
165 PORT_DIPSETTING( 0x38, DEF_STR( 1C_1C ) )
166 PORT_DIPSETTING( 0x00, DEF_STR( 3C_4C ) )
167 PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) )
168 PORT_DIPSETTING( 0x30, DEF_STR( 1C_2C ) )
169 PORT_DIPSETTING( 0x28, DEF_STR( 1C_3C ) )
170 PORT_DIPSETTING( 0x20, DEF_STR( 1C_4C ) )
171 PORT_DIPSETTING( 0x18, DEF_STR( 1C_5C ) )
172 PORT_DIPSETTING( 0x10, DEF_STR( 1C_6C ) )
173 PORT_DIPNAME( 0x40, 0x40, "Credit configuration" )
174 PORT_DIPSETTING( 0x40, "Start 1C/Continue 1C" )
175 PORT_DIPSETTING( 0x00, "Start 2C/Continue 1C" )
176 PORT_DIPNAME( 0x80, 0x80, DEF_STR( Free_Play ) )
177 PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
178 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
179
180 PORT_START("DSW2")
181 PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) )
182 PORT_DIPSETTING( 0x03, DEF_STR( Normal ) )
183 PORT_DIPSETTING( 0x02, DEF_STR( Easy ) )
184 PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
185 PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
186 PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
187 PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
188 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
189 PORT_DIPNAME( 0x18, 0x18, DEF_STR( Lives ) )
190 PORT_DIPSETTING( 0x18, "2" )
191 PORT_DIPSETTING( 0x10, "3" )
192 PORT_DIPSETTING( 0x08, "4" )
193 PORT_DIPSETTING( 0x00, "1" )
194 PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
195 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
196 PORT_DIPSETTING( 0x20, DEF_STR( On ) )
197 PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
198 PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
199 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
200 PORT_SERVICE( 0x80, IP_ACTIVE_LOW )
201
202 PORT_START("P1")
203 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
204 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
205 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
206 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
207 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
208 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
209 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
210 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
211
212 PORT_START("P2")
213 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
214 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
215 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
216 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
217 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
218 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
219 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
220 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
221
222 PORT_START("SYSTEM")
223 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 )
224 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* test button */
225 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
226 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
227 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
228 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
229 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
230 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
231 INPUT_PORTS_END
232
233
234 static const gfx_layout thoop2_tilelayout =
235 {
236 8,8, /* 8x8 tiles */
237 RGN_FRAC(1,2), /* number of tiles */
238 4, /* 4 bpp */
239 { 8, 0, RGN_FRAC(1,2)+8, RGN_FRAC(1,2)+0 },
240 { STEP8(0,1) },
241 { STEP8(0,8*2) },
242 16*8
243 };
244
245 static const gfx_layout thoop2_tilelayout_16 =
246 {
247 16,16, /* 16x16 tiles */
248 RGN_FRAC(1,2), /* number of tiles */
249 4, /* 4 bpp */
250 { 8, 0, RGN_FRAC(1,2)+8, RGN_FRAC(1,2)+0 },
251 { STEP8(0,1), STEP8(8*2*16,1) },
252 { STEP16(0,8*2) },
253 64*8
254 };
255
256
257 static GFXDECODE_START( gfx_thoop2 )
258 GFXDECODE_ENTRY( "gfx1", 0x000000, thoop2_tilelayout, 0, 64 )
259 GFXDECODE_ENTRY( "gfx1", 0x000000, thoop2_tilelayout_16, 0, 64 )
260 GFXDECODE_END
261
262
thoop2(machine_config & config)263 void thoop2_state::thoop2(machine_config &config)
264 {
265 /* basic machine hardware */
266 M68000(config, m_maincpu, XTAL(24'000'000) / 2); // 12MHz verified
267 m_maincpu->set_addrmap(AS_PROGRAM, &thoop2_state::thoop2_map);
268 m_maincpu->set_vblank_int("screen", FUNC(thoop2_state::irq6_line_hold));
269
270 gaelco_ds5002fp_device &ds5002fp(GAELCO_DS5002FP(config, "gaelco_ds5002fp", XTAL(24'000'000) / 2)); // 12MHz verified
271 ds5002fp.set_addrmap(0, &thoop2_state::mcu_hostmem_map);
272 config.set_perfect_quantum("gaelco_ds5002fp:mcu");
273
274 LS259(config, m_outlatch);
275 m_outlatch->q_out_cb<0>().set(FUNC(thoop2_state::coin1_lockout_w));
276 m_outlatch->q_out_cb<1>().set(FUNC(thoop2_state::coin2_lockout_w));
277 m_outlatch->q_out_cb<2>().set(FUNC(thoop2_state::coin1_counter_w));
278 m_outlatch->q_out_cb<3>().set(FUNC(thoop2_state::coin2_counter_w));
279 m_outlatch->q_out_cb<4>().set_nop(); // unknown. Sound related?
280 m_outlatch->q_out_cb<5>().set_nop(); // unknown
281
282 WATCHDOG_TIMER(config, "watchdog");
283
284 /* video hardware */
285 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
286 screen.set_refresh_hz(59.24);
287 screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
288 screen.set_size(32*16, 32*16);
289 screen.set_visarea(0, 320-1, 16, 256-1);
290 screen.set_screen_update(FUNC(thoop2_state::screen_update));
291 screen.set_palette(m_palette);
292
293 GFXDECODE(config, m_gfxdecode, m_palette, gfx_thoop2);
294 PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
295
296 /* sound hardware */
297 SPEAKER(config, "mono").front_center();
298
299 okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); // 1MHz resonator - pin 7 not connected
300 oki.set_addrmap(0, &thoop2_state::oki_map);
301 oki.add_route(ALL_OUTPUTS, "mono", 1.0);
302 }
303
304
305
306 ROM_START( thoop2 ) /* REF.940411 PCB */
307 ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
308 ROM_LOAD16_BYTE( "th2c23.c23", 0x000000, 0x080000, CRC(3e465753) SHA1(1ea1173b9fe5d652e7b5fafb822e2535cecbc198) )
309 ROM_LOAD16_BYTE( "th2c22.c22", 0x000001, 0x080000, CRC(837205b7) SHA1(f78b90c2be0b4dddaba26f074ea00eff863cfdb2) )
310
311 ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
312 ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) /* dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct */
313
314 ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
315 /* these are the default states stored in NVRAM */
316 DS5002FP_SET_MON( 0x79 )
317 DS5002FP_SET_RPCTL( 0x00 )
318 DS5002FP_SET_CRCR( 0x80 )
319
320 ROM_REGION( 0x800000, "gfx1", 0 )
321 ROM_LOAD( "th2-h8.h8", 0x000000, 0x400000, CRC(60328a11) SHA1(fcdb374d2fc7ef5351a4181c471d192199dc2081) )
322 ROM_LOAD( "th2-h12.h12", 0x400000, 0x400000, CRC(b25c2d3e) SHA1(d70f3e4e2432d80c2ac87cd81208ada303bac04a) )
323
324 ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
325 ROM_LOAD( "th2-c1.c1", 0x000000, 0x100000, CRC(8fac8c30) SHA1(8e49bb596144761eae95f3e1266e57fb386664f2) )
326 /* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched */
327 ROM_END
328
329 ROM_START( thoop2a ) /* REF.940411 PCB */
330 ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
331 ROM_LOAD16_BYTE( "3.c23", 0x000000, 0x080000, CRC(6cd4a8dc) SHA1(7d0cdce64b390c3f9769b07d57cf1eee1e6a7bf5) )
332 ROM_LOAD16_BYTE( "2.c22", 0x000001, 0x080000, CRC(59ba9b43) SHA1(6c6690a2e389fc9f1e166c87748da1175e3b58f8) )
333
334 ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
335 ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) /* dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct */
336
337 ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
338 /* these are the default states stored in NVRAM */
339 DS5002FP_SET_MON( 0x79 )
340 DS5002FP_SET_RPCTL( 0x00 )
341 DS5002FP_SET_CRCR( 0x80 )
342
343 ROM_REGION( 0x800000, "gfx1", 0 )
344 ROM_LOAD( "th2-h8.h8", 0x000000, 0x400000, CRC(60328a11) SHA1(fcdb374d2fc7ef5351a4181c471d192199dc2081) )
345 ROM_LOAD( "th2-h12.h12", 0x400000, 0x400000, CRC(b25c2d3e) SHA1(d70f3e4e2432d80c2ac87cd81208ada303bac04a) )
346
347 ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
348 ROM_LOAD( "th2-c1.c1", 0x000000, 0x100000, CRC(8fac8c30) SHA1(8e49bb596144761eae95f3e1266e57fb386664f2) )
349 /* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched */
350 ROM_END
351
352 GAME( 1994, thoop2, 0, thoop2, thoop2, thoop2_state, empty_init, ROT0, "Gaelco", "TH Strikes Back (Non North America, Version 1.0, Checksum 020E0867)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
353 GAME( 1994, thoop2a, thoop2, thoop2, thoop2, thoop2_state, empty_init, ROT0, "Gaelco", "TH Strikes Back (Non North America, Version 1.0, Checksum 020EB356)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
354