1 // FB Alpha Midway MCR-3 system driver module
2 // Based on MAME driver by Christopher Kirmse, Aaron Giles
3
4 // demoderm - good
5 // sarge - good
6 // maxrpm - good
7 // rampage - good
8 // rampage2 - good
9 // powerdrv - good
10 // stargrds - good
11 // spyhunt - good
12 // spyhuntp - good
13 // crater - graphics issues (unfixable offset? weird.)
14 // turbotag - should we bother? looks like a buggy mess
15
16 #include "tiles_generic.h"
17 #include "z80_intf.h"
18 #include "m68000_intf.h"
19 #include "m6809_intf.h"
20 #include "midsg.h"
21 #include "midtcs.h"
22 #include "midcsd.h"
23 #include "midssio.h"
24 #include "dac.h"
25 #include "ay8910.h"
26 #include "watchdog.h"
27 #include "burn_pal.h"
28 #include "burn_gun.h" // for dial (crater) etc.
29 #include "burn_shift.h"
30 #include "flt_rc.h" // spyhunt mixing
31 #include "lowpass2.h" // fur spyhunt beefy-engine v1.0 -dink
32
33 static UINT8 *AllMem;
34 static UINT8 *MemEnd;
35 static UINT8 *AllRam;
36 static UINT8 *RamEnd;
37 static UINT8 *DrvZ80ROM0;
38 static UINT8 *DrvZ80ROM1;
39 static UINT8 *Drv68KROM;
40 static UINT8 *DrvSndROM;
41 static UINT8 *DrvGfxROM0;
42 static UINT8 *DrvGfxROM1;
43 static UINT8 *DrvGfxROM2;
44 static UINT8 *DrvSndPROM;
45 static UINT8 *DrvNVRAM;
46 static UINT8 *DrvSprRAM;
47 static UINT8 *DrvVidRAM;
48 static UINT8 *DrvSndRAM;
49 static UINT8 *Drv68KRAM;
50 static UINT8 *DrvTxtRAM;
51 static UINT8 *DrvZ80RAM1;
52 static UINT16 *DrvPalRAM16;
53 static UINT8 *DrvTransTab[2];
54
55 static UINT32 *DrvPalette;
56 static UINT8 DrvRecalc;
57
58 static INT32 flipscreen;
59 static INT32 scrollx;
60 static INT32 scrolly;
61 static INT32 input_mux;
62 static INT32 latched_input;
63 static UINT8 maxrpm_adc_control;
64 static UINT8 maxrpm_adc_select;
65 static UINT8 maxrpm_p1_shift;
66 static UINT8 maxrpm_p2_shift;
67 static UINT8 maxrpm_last_shift;
68 static UINT8 lamp;
69 static UINT8 last_op4;
70
71 static INT32 sound_status_bit = 8; // default to disabled
72 static INT32 sound_input_bank = 0;
73 static INT32 (*port_write_handler)(UINT8 address, UINT8 data) = NULL;
74 static INT32 (*port_read_handler)(UINT8 address) = NULL;
75 static INT32 sprite_color_mask = 0;
76 static INT32 flip_screen_x = 0;
77 static INT32 nGraphicsLen[3];
78
79 static INT32 nExtraCycles[3];
80
81 static UINT8 DrvJoy1[8];
82 static UINT8 DrvJoy2[8];
83 static UINT8 DrvJoy3[8];
84 static UINT8 DrvJoy4[8];
85 static UINT8 DrvJoy5[8];
86 static UINT8 DrvJoy6[8];
87 static UINT8 DrvDips[6];
88 static UINT8 DrvInputs[6];
89 static UINT8 DrvReset;
90 static UINT8 dip_service = 0x20;
91
92 static UINT8 pd_shift[3];
93 static UINT8 pd_shift_prev[3];
94
95 static INT32 is_demoderm = 0;
96 static INT32 is_spyhunt = 0;
97 static INT32 is_powerdrv = 0;
98 static INT32 is_maxrpm = 0;
99
100 static INT32 has_shift = 0;
101 static INT32 has_dial = 0;
102 static UINT8 DrvJoy4f[8]; // fake, for digital-dial
103 static UINT8 DrvInputs4f;
104 static INT16 DrvAnalogPort0 = 0;
105 static INT16 DrvAnalogPort1 = 0;
106 static INT16 DrvAnalogPort2 = 0;
107 static INT16 DrvAnalogPort3 = 0;
108
109 // For spyhunt's engine effect
110 static class LowPass2 *LP1 = NULL;
111 #define SampleFreq 44100.0
112 #define CutFreq 1000.0
113 #define Q 0.4
114 #define Gain 1.3
115 #define CutFreq2 1000.0
116 #define Q2 0.3
117 #define Gain2 1.475
118
119 #define A(a, b, c, d) {a, b, (UINT8*)(c), d}
120 static struct BurnInputInfo RampageInputList[] = {
121 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
122 {"P1 Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" },
123 {"P1 Down", BIT_DIGITAL, DrvJoy2 + 2, "p1 down" },
124 {"P1 Left", BIT_DIGITAL, DrvJoy2 + 3, "p1 left" },
125 {"P1 Right", BIT_DIGITAL, DrvJoy2 + 1, "p1 right" },
126 {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 1" },
127 {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 2" },
128
129 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
130 {"P2 Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up" },
131 {"P2 Down", BIT_DIGITAL, DrvJoy3 + 2, "p2 down" },
132 {"P2 Left", BIT_DIGITAL, DrvJoy3 + 3, "p2 left" },
133 {"P2 Right", BIT_DIGITAL, DrvJoy3 + 1, "p2 right" },
134 {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 4, "p2 fire 1" },
135 {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 5, "p2 fire 2" },
136
137 {"P3 Up", BIT_DIGITAL, DrvJoy5 + 0, "p3 up" },
138 {"P3 Down", BIT_DIGITAL, DrvJoy5 + 2, "p3 down" },
139 {"P3 Left", BIT_DIGITAL, DrvJoy5 + 3, "p3 left" },
140 {"P3 Right", BIT_DIGITAL, DrvJoy5 + 1, "p3 right" },
141 {"P3 Button 1", BIT_DIGITAL, DrvJoy5 + 4, "p3 fire 1" },
142 {"P3 Button 2", BIT_DIGITAL, DrvJoy5 + 5, "p3 fire 2" },
143
144 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
145 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
146 {"Tilt", BIT_DIGITAL, DrvJoy1 + 4, "tilt" },
147 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
148 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
149 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
150 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
151 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
152 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
153 };
154
155 STDINPUTINFO(Rampage)
156
157 static struct BurnInputInfo PowerdrvInputList[] = {
158 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
159 {"P1 Wheel Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 fire 1" },
160 {"P1 Wheel Right", BIT_DIGITAL, DrvJoy2 + 3, "p1 fire 2" },
161 {"P1 Wheelie", BIT_DIGITAL, DrvJoy2 + 0, "p1 fire 3" },
162 {"P1 Shift", BIT_DIGITAL, DrvJoy2 + 1, "p1 fire 4" },
163
164 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
165 {"P2 Wheel Left", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire 1" },
166 {"P2 Wheel Right", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire 2" },
167 {"P2 Wheelie", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 3" },
168 {"P2 Shift", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 4" },
169
170 {"P3 Coin", BIT_DIGITAL, DrvJoy1 + 2, "p3 coin" },
171 {"P3 Wheel Left", BIT_DIGITAL, DrvJoy3 + 2, "p3 fire 1" },
172 {"P3 Wheel Right", BIT_DIGITAL, DrvJoy3 + 3, "p3 fire 2" },
173 {"P3 Wheelie", BIT_DIGITAL, DrvJoy3 + 0, "p3 fire 3" },
174 {"P3 Shift", BIT_DIGITAL, DrvJoy3 + 1, "p3 fire 4" },
175
176 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
177 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
178 {"Service Mode", BIT_DIGITAL, DrvJoy1 + 5, "diag" },
179 {"Tilt", BIT_DIGITAL, DrvJoy1 + 4, "tilt" },
180 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
181 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
182 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
183 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
184 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
185 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
186 };
187
188 STDINPUTINFO(Powerdrv)
189
190 static struct BurnInputInfo DemodermInputList[] = {
191 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
192 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 2, "p1 start" },
193 A("P1 Dial", BIT_ANALOG_REL, &DrvAnalogPort0,"p1 x-axis"),
194 {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 0, "p1 fire 1" },
195 {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 1, "p1 fire 2" },
196
197 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
198 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 3, "p2 start" },
199 A("P2 Dial", BIT_ANALOG_REL, &DrvAnalogPort1,"p2 x-axis"),
200 {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 0, "p2 fire 1" },
201 {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 1, "p2 fire 2" },
202
203 {"P3 Coin", BIT_DIGITAL, DrvJoy5 + 0, "p3 coin" },
204 {"P3 Start", BIT_DIGITAL, DrvJoy5 + 2, "p3 start" },
205 A("P3 Dial", BIT_ANALOG_REL, &DrvAnalogPort2,"p3 x-axis"),
206 {"P3 Button 1", BIT_DIGITAL, DrvJoy5 + 4, "p3 fire 1" },
207 {"P3 Button 2", BIT_DIGITAL, DrvJoy5 + 5, "p3 fire 2" },
208
209 {"P4 Coin", BIT_DIGITAL, DrvJoy5 + 1, "p4 coin" },
210 {"P4 Start", BIT_DIGITAL, DrvJoy5 + 3, "p4 start" },
211 A("P4 Dial", BIT_ANALOG_REL, &DrvAnalogPort3,"p4 x-axis"),
212 {"P4 Button 1", BIT_DIGITAL, DrvJoy5 + 6, "p4 fire 1" },
213 {"P4 Button 2", BIT_DIGITAL, DrvJoy5 + 7, "p4 fire 2" },
214
215 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
216 {"Tilt", BIT_DIGITAL, DrvJoy1 + 6, "tilt" },
217 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
218 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
219 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
220 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
221 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
222 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
223 };
224
225 STDINPUTINFO(Demoderm)
226
227 static struct BurnInputInfo SargeInputList[] = {
228 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
229 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 2, "p1 start" },
230 {"P1 Left Stick Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" },
231 {"P1 Left Stick Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down" },
232 {"P1 Right Stick Up", BIT_DIGITAL, DrvJoy2 + 2, "p1 up 2" },
233 {"P1 Right Stick Down", BIT_DIGITAL, DrvJoy2 + 3, "p1 down 2" },
234 {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 1" },
235 {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 6, "p1 fire 2" },
236
237 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
238 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 3, "p2 start" },
239 {"P2 Left Stick Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up" },
240 {"P2 Left Stick Down", BIT_DIGITAL, DrvJoy3 + 1, "p2 down" },
241 {"P2 Right Stick Up", BIT_DIGITAL, DrvJoy3 + 2, "p2 up 2" },
242 {"P2 Right Stick Down", BIT_DIGITAL, DrvJoy3 + 3, "p2 down 2" },
243 {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 4, "p2 fire 1" },
244 {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 6, "p2 fire 2" },
245
246 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
247 {"Service", BIT_DIGITAL, DrvJoy1 + 5, "service" },
248 {"Tilt", BIT_DIGITAL, DrvJoy1 + 4, "tilt" },
249 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
250 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
251 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
252 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
253 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
254 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
255 };
256
257 STDINPUTINFO(Sarge)
258
259 static struct BurnInputInfo SpyhuntInputList[] = {
260 {"Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
261 {"Weapons Van", BIT_DIGITAL, DrvJoy2 + 2, "p1 start" },
262 {"Gear Shift", BIT_DIGITAL, DrvJoy4f + 4, "p1 fire 2" },
263 {"Missiles", BIT_DIGITAL, DrvJoy2 + 1, "p1 fire 3" },
264 {"Oil Slick", BIT_DIGITAL, DrvJoy2 + 0, "p1 fire 4" },
265 {"Smoke Screen", BIT_DIGITAL, DrvJoy2 + 3, "p1 fire 5" },
266 {"Machine Gun", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 6" },
267
268 A("P1 Wheel", BIT_ANALOG_REL, &DrvAnalogPort0, "p1 x-axis"),
269 A("P1 Accelerator", BIT_ANALOG_REL, &DrvAnalogPort1, "p1 fire 1"),
270
271 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
272 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
273 {"Tilt", BIT_DIGITAL, DrvJoy1 + 5, "tilt" },
274 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
275 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
276 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
277 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
278 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
279 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
280 };
281
282 STDINPUTINFO(Spyhunt)
283
284 static struct BurnInputInfo MaxrpmInputList[] = {
285 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
286 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 3, "p1 start" },
287 A("P1 Wheel", BIT_ANALOG_REL, &DrvAnalogPort0, "p1 x-axis"),
288 A("P1 Accelerator", BIT_ANALOG_REL, &DrvAnalogPort1, "p1 fire 1"),
289 {"P1 Shift Up", BIT_DIGITAL, DrvJoy4f + 0, "p1 up" },
290 {"P1 Shift Down", BIT_DIGITAL, DrvJoy4f + 1, "p1 down" },
291
292 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
293 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 2, "p2 start" },
294 A("P2 Wheel", BIT_ANALOG_REL, &DrvAnalogPort2, "p2 x-axis"),
295 A("P2 Accelerator", BIT_ANALOG_REL, &DrvAnalogPort3, "p2 fire 1"),
296 {"P2 Shift Up", BIT_DIGITAL, DrvJoy4f + 2, "p2 up" },
297 {"P2 Shift Down", BIT_DIGITAL, DrvJoy4f + 3, "p2 down" },
298
299 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
300 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
301 {"Tilt", BIT_DIGITAL, DrvJoy1 + 4, "tilt" },
302 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
303 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
304 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
305 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
306 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
307 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
308 };
309
310 STDINPUTINFO(Maxrpm)
311
312 static struct BurnInputInfo CraterInputList[] = {
313 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
314 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 2, "p1 start" },
315 {"P1 Up", BIT_DIGITAL, DrvJoy3 + 2, "p1 up" },
316 {"P1 Down", BIT_DIGITAL, DrvJoy3 + 3, "p1 down" },
317 {"P1 Left", BIT_DIGITAL, DrvJoy4f + 0, "p1 left" },
318 {"P1 Right", BIT_DIGITAL, DrvJoy4f + 1, "p1 right" },
319 A("P1 Dial", BIT_ANALOG_REL, &DrvAnalogPort0,"p1 x-axis"),
320 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
321 {"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 6, "p1 fire 2" },
322 {"P1 Button 3", BIT_DIGITAL, DrvJoy3 + 4, "p1 fire 3" },
323
324 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
325 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
326 {"Tilt", BIT_DIGITAL, DrvJoy1 + 5, "tilt" },
327 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
328 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
329 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
330 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
331 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
332 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
333 };
334
335 STDINPUTINFO(Crater)
336 #undef A
337
338 static struct BurnInputInfo StargrdsInputList[] = {
339 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
340 {"P1 Start / Weapon", BIT_DIGITAL, DrvJoy1 + 2, "p1 start" },
341 {"P1 Left Stick Up", BIT_DIGITAL, DrvJoy2 + 4, "p1 up" },
342 {"P1 Left Stick Down", BIT_DIGITAL, DrvJoy2 + 5, "p1 down" },
343 {"P1 Left Stick Left", BIT_DIGITAL, DrvJoy2 + 6, "p1 left" },
344 {"P1 Left Stick Right", BIT_DIGITAL, DrvJoy2 + 7, "p1 right" },
345 {"P1 Right Stick Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up 2" },
346 {"P1 Right Stick Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down 2" },
347 {"P1 Right Stick Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 left 2" },
348 {"P1 Right Stick Right",BIT_DIGITAL, DrvJoy2 + 3, "p1 right 2"},
349
350 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" },
351 {"P2 Start / Weapon", BIT_DIGITAL, DrvJoy1 + 3, "p2 start" },
352 {"P2 Left Stick Up", BIT_DIGITAL, DrvJoy3 + 4, "p2 up" },
353 {"P2 Left Stick Down", BIT_DIGITAL, DrvJoy3 + 5, "p2 down" },
354 {"P2 Left Stick Left", BIT_DIGITAL, DrvJoy3 + 6, "p2 left" },
355 {"P2 Left Stick Right", BIT_DIGITAL, DrvJoy3 + 7, "p2 right" },
356 {"P2 Right Stick Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up 2" },
357 {"P2 Right Stick Down", BIT_DIGITAL, DrvJoy3 + 1, "p2 down 2" },
358 {"P2 Right Stick Left", BIT_DIGITAL, DrvJoy3 + 2, "p2 left 2" },
359 {"P2 Right Stick Right",BIT_DIGITAL, DrvJoy3 + 3, "p2 right 2"},
360
361 {"P3 Coin", BIT_DIGITAL, DrvJoy6 + 1, "p3 coin" },
362 {"P3 Start / Weapon", BIT_DIGITAL, DrvJoy6 + 3, "p3 start" },
363 {"P3 Left Stick Up", BIT_DIGITAL, DrvJoy5 + 4, "p3 up" },
364 {"P3 Left Stick Down", BIT_DIGITAL, DrvJoy5 + 5, "p3 down" },
365 {"P3 Left Stick Left", BIT_DIGITAL, DrvJoy5 + 6, "p3 left" },
366 {"P3 Left Stick Right", BIT_DIGITAL, DrvJoy5 + 7, "p3 right" },
367 {"P3 Right Stick Up", BIT_DIGITAL, DrvJoy5 + 0, "p3 up 2" },
368 {"P3 Right Stick Down", BIT_DIGITAL, DrvJoy5 + 1, "p3 down 2" },
369 {"P3 Right Stick Left", BIT_DIGITAL, DrvJoy5 + 2, "p3 left 2" },
370 {"P3 Right Stick Right",BIT_DIGITAL, DrvJoy5 + 3, "p3 right 2"},
371
372 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
373 {"Service", BIT_DIGITAL, DrvJoy1 + 6, "service" },
374 {"Tilt", BIT_DIGITAL, DrvJoy1 + 5, "tilt" },
375 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
376 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
377 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
378 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
379 {"Dip E", BIT_DIPSWITCH, DrvDips + 4, "dip" },
380 {"Dip F", BIT_DIPSWITCH, DrvDips + 5, "dip" },
381 };
382
383 STDINPUTINFO(Stargrds)
384
385 static struct BurnDIPInfo StargrdsDIPList[]=
386 {
387 {0x21, 0xff, 0xff, 0xff, NULL },
388 {0x22, 0xff, 0xff, 0xff, NULL },
389 {0x23, 0xff, 0xff, 0xff, NULL },
390 {0x24, 0xff, 0xff, 0xff, NULL },
391 {0x25, 0xff, 0xff, 0xff, NULL },
392 {0x26, 0xff, 0xff, 0x80, NULL },
393
394 {0 , 0xfe, 0 , 4, "Energy Units" },
395 {0x24, 0x01, 0x0c, 0x08, "8" },
396 {0x24, 0x01, 0x0c, 0x0c, "10" },
397 {0x24, 0x01, 0x0c, 0x04, "12" },
398 {0x24, 0x01, 0x0c, 0x00, "14" },
399
400 {0 , 0xfe, 0 , 2, "Demo Sounds" },
401 {0x24, 0x01, 0x20, 0x00, "Off" },
402 {0x24, 0x01, 0x20, 0x20, "On" },
403
404 {0 , 0xfe, 0 , 4, "Difficulty" },
405 {0x24, 0x01, 0xc0, 0x80, "Easy" },
406 {0x24, 0x01, 0xc0, 0xc0, "Medium" },
407 {0x24, 0x01, 0xc0, 0x40, "Hard" },
408 {0x24, 0x01, 0xc0, 0x00, "Hardest" },
409
410 {0 , 0xfe, 0 , 2, "Service Mode" },
411 {0x26, 0x01, 0x80, 0x80, "Off" },
412 {0x26, 0x01, 0x80, 0x00, "On" },
413 };
414
415 STDDIPINFO(Stargrds)
416
417 static struct BurnDIPInfo PowerdrvDIPList[]=
418 {
419 {0x13, 0xff, 0xff, 0xff, NULL },
420 {0x14, 0xff, 0xff, 0xff, NULL },
421 {0x15, 0xff, 0xff, 0xff, NULL },
422 {0x16, 0xff, 0xff, 0xff, NULL },
423 {0x17, 0xff, 0xff, 0xff, NULL },
424 {0x18, 0xff, 0xff, 0x20, NULL },
425
426 {0 , 0xfe, 0 , 3, "Coinage" },
427 {0x16, 0x01, 0x03, 0x02, "2 Coins 1 Credits" },
428 {0x16, 0x01, 0x03, 0x03, "1 Coin 1 Credits" },
429 {0x16, 0x01, 0x03, 0x01, "1 Coin 2 Credits" },
430
431 {0 , 0xfe, 0 , 4, "Difficulty" },
432 {0x16, 0x01, 0x30, 0x20, "Easy" },
433 {0x16, 0x01, 0x30, 0x30, "Factory" },
434 {0x16, 0x01, 0x30, 0x10, "Hard" },
435 {0x16, 0x01, 0x30, 0x00, "Hardest" },
436
437 {0 , 0xfe, 0 , 2, "Demo Sounds" },
438 {0x16, 0x01, 0x40, 0x00, "Off" },
439 {0x16, 0x01, 0x40, 0x40, "On" },
440
441 {0 , 0xfe, 0 , 2, "Rack Advance (Cheat)" },
442 {0x16, 0x01, 0x80, 0x80, "Off" },
443 {0x16, 0x01, 0x80, 0x00, "On" },
444
445 {0 , 0xfe, 0 , 2, "Service Mode" },
446 {0x18, 0x01, 0x20, 0x20, "Off" },
447 {0x18, 0x01, 0x20, 0x00, "On" },
448 };
449
450 STDDIPINFO(Powerdrv)
451
452 static struct BurnDIPInfo RampageDIPList[]=
453 {
454 {0x17, 0xff, 0xff, 0xff, NULL },
455 {0x18, 0xff, 0xff, 0xff, NULL },
456 {0x19, 0xff, 0xff, 0xff, NULL },
457 {0x1a, 0xff, 0xff, 0xff, NULL },
458 {0x1b, 0xff, 0xff, 0xff, NULL },
459 {0x1c, 0xff, 0xff, 0x20, NULL },
460
461 {0 , 0xfe, 0 , 4, "Difficulty" },
462 {0x1a, 0x01, 0x03, 0x02, "Easy" },
463 {0x1a, 0x01, 0x03, 0x03, "Normal" },
464 {0x1a, 0x01, 0x03, 0x01, "Hard" },
465 {0x1a, 0x01, 0x03, 0x00, "Free Play" },
466
467 {0 , 0xfe, 0 , 2, "Score Option" },
468 {0x1a, 0x01, 0x04, 0x04, "Keep score when continuing" },
469 {0x1a, 0x01, 0x04, 0x00, "Lose score when continuing" },
470
471 {0 , 0xfe, 0 , 2, "Coin A" },
472 {0x1a, 0x01, 0x08, 0x00, "2 Coins 1 Credits" },
473 {0x1a, 0x01, 0x08, 0x08, "1 Coin 1 Credits" },
474
475 {0 , 0xfe, 0 , 8, "Coin B" },
476 {0x1a, 0x01, 0x70, 0x00, "3 Coins 1 Credits" },
477 {0x1a, 0x01, 0x70, 0x10, "2 Coins 1 Credits" },
478 {0x1a, 0x01, 0x70, 0x70, "1 Coin 1 Credits" },
479 {0x1a, 0x01, 0x70, 0x60, "1 Coin 2 Credits" },
480 {0x1a, 0x01, 0x70, 0x50, "1 Coin 3 Credits" },
481 {0x1a, 0x01, 0x70, 0x40, "1 Coin 4 Credits" },
482 {0x1a, 0x01, 0x70, 0x30, "1 Coin 5 Credits" },
483 {0x1a, 0x01, 0x70, 0x20, "1 Coin 6 Credits" },
484
485 {0 , 0xfe, 0 , 2, "Rack Advance (Cheat)" },
486 {0x1a, 0x01, 0x80, 0x80, "Off" },
487 {0x1a, 0x01, 0x80, 0x00, "On" },
488
489 {0 , 0xfe, 0 , 2, "Service Mode" },
490 {0x1c, 0x01, 0x20, 0x20, "Off" },
491 {0x1c, 0x01, 0x20, 0x00, "On" },
492 };
493
494 STDDIPINFO(Rampage)
495
496 static struct BurnDIPInfo DemodermDIPList[]=
497 {
498 {0x16, 0xff, 0xff, 0xff, NULL },
499 {0x17, 0xff, 0xff, 0xff, NULL },
500 {0x18, 0xff, 0xff, 0xff, NULL },
501 {0x19, 0xff, 0xff, 0xff, NULL },
502 {0x1a, 0xff, 0xff, 0xff, NULL },
503 {0x1b, 0xff, 0xff, 0x20, NULL },
504
505 {0 , 0xfe, 0 , 2, "Cabinet" },
506 {0x19, 0x01, 0x01, 0x01, "2P Upright" },
507 {0x19, 0x01, 0x01, 0x00, "4P Cocktail" },
508
509 {0 , 0xfe, 0 , 2, "Difficulty" },
510 {0x19, 0x01, 0x02, 0x02, "Normal" },
511 {0x19, 0x01, 0x02, 0x00, "Harder" },
512
513 {0 , 0xfe, 0 , 2, "Free Play" },
514 {0x19, 0x01, 0x04, 0x04, "Off" },
515 {0x19, 0x01, 0x04, 0x00, "On" },
516
517 {0 , 0xfe, 0 , 2, "Reward Screen" },
518 {0x19, 0x01, 0x08, 0x08, "Expanded" },
519 {0x19, 0x01, 0x08, 0x00, "Limited" },
520
521 {0 , 0xfe, 0 , 4, "Coinage" },
522 {0x19, 0x01, 0x30, 0x20, "2 Coins 1 Credits" },
523 {0x19, 0x01, 0x30, 0x00, "2 Coins 2 Credits" },
524 {0x19, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
525 {0x19, 0x01, 0x30, 0x10, "1 Coin 2 Credits" },
526
527 {0 , 0xfe, 0 , 2, "Service Mode" },
528 {0x1b, 0x01, 0x20, 0x20, "Off" },
529 {0x1b, 0x01, 0x20, 0x00, "On" },
530 };
531
532 STDDIPINFO(Demoderm)
533
534 static struct BurnDIPInfo SargeDIPList[]=
535 {
536 {0x13, 0xff, 0xff, 0xff, NULL },
537 {0x14, 0xff, 0xff, 0xff, NULL },
538 {0x15, 0xff, 0xff, 0xff, NULL },
539 {0x16, 0xff, 0xff, 0xff, NULL },
540 {0x17, 0xff, 0xff, 0xff, NULL },
541 {0x18, 0xff, 0xff, 0x20, NULL },
542
543 {0 , 0xfe, 0 , 2, "Free Play" },
544 {0x16, 0x01, 0x08, 0x08, "Off" },
545 {0x16, 0x01, 0x08, 0x00, "On" },
546
547 {0 , 0xfe, 0 , 3, "Coinage" },
548 {0x16, 0x01, 0x30, 0x20, "2 Coins 1 Credits" },
549 {0x16, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
550 {0x16, 0x01, 0x30, 0x10, "1 Coin 2 Credits" },
551
552 {0 , 0xfe, 0 , 2, "Service Mode" },
553 {0x18, 0x01, 0x20, 0x20, "Off" },
554 {0x18, 0x01, 0x20, 0x00, "On" },
555 };
556
557 STDDIPINFO(Sarge)
558
559 static struct BurnDIPInfo SpyhuntDIPList[]=
560 {
561 {0x0c, 0xff, 0xff, 0xff, NULL },
562 {0x0d, 0xff, 0xff, 0xff, NULL },
563 {0x0e, 0xff, 0xff, 0xff, NULL },
564 {0x0f, 0xff, 0xff, 0xff, NULL },
565 {0x10, 0xff, 0xff, 0xff, NULL },
566 {0x11, 0xff, 0xff, 0x80, NULL },
567
568 {0 , 0xfe, 0 , 2, "Game Timer" },
569 {0x0f, 0x01, 0x01, 0x00, "1:00" },
570 {0x0f, 0x01, 0x01, 0x01, "1:30" },
571
572 {0 , 0xfe, 0 , 2, "Demo Sounds" },
573 {0x0f, 0x01, 0x02, 0x02, "Off" },
574 {0x0f, 0x01, 0x02, 0x00, "On" },
575
576 {0 , 0xfe, 0 , 2, "Service Mode" },
577 {0x11, 0x01, 0x80, 0x80, "Off" },
578 {0x11, 0x01, 0x80, 0x00, "On" },
579 };
580
581 STDDIPINFO(Spyhunt)
582
583 static struct BurnDIPInfo MaxrpmDIPList[]=
584 {
585 {0x0f, 0xff, 0xff, 0xff, NULL },
586 {0x10, 0xff, 0xff, 0xff, NULL },
587 {0x11, 0xff, 0xff, 0xff, NULL },
588 {0x12, 0xff, 0xff, 0xff, NULL },
589 {0x13, 0xff, 0xff, 0xff, NULL },
590 {0x14, 0xff, 0xff, 0x80, NULL },
591
592 {0 , 0xfe, 0 , 2, "Free Play" },
593 {0x12, 0x01, 0x08, 0x08, "Off" },
594 {0x12, 0x01, 0x08, 0x00, "On" },
595
596 {0 , 0xfe, 0 , 3, "Coinage" },
597 {0x12, 0x01, 0x30, 0x20, "2 Coins 1 Credits" },
598 {0x12, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
599 {0x12, 0x01, 0x30, 0x10, "1 Coin 2 Credits" },
600
601 {0 , 0xfe, 0 , 2, "Service Mode" },
602 {0x14, 0x01, 0x80, 0x80, "Off" },
603 {0x14, 0x01, 0x80, 0x00, "On" },
604 };
605
606 STDDIPINFO(Maxrpm)
607
608 static struct BurnDIPInfo CraterDIPList[]=
609 {
610 {0x0d, 0xff, 0xff, 0xff, NULL },
611 {0x0e, 0xff, 0xff, 0xff, NULL },
612 {0x0f, 0xff, 0xff, 0xff, NULL },
613 {0x10, 0xff, 0xff, 0xff, NULL },
614 {0x11, 0xff, 0xff, 0xff, NULL },
615 {0x12, 0xff, 0xff, 0x80, NULL },
616
617 {0 , 0xfe, 0 , 2, "Service Mode" },
618 {0x12, 0x01, 0x80, 0x80, "Off" },
619 {0x12, 0x01, 0x80, 0x00, "On" },
620 };
621
STDDIPINFO(Crater)622 STDDIPINFO(Crater)
623
624 static UINT8 soundsgood_input_read(UINT8 address)
625 {
626 address &= 7;
627 UINT8 ret = DrvInputs[address];
628
629 if (sound_input_bank == address)
630 {
631 ret &= ~(1 << sound_status_bit);
632 if (soundsgood_status_read()) ret |= 1 << sound_status_bit;
633 }
634
635 // bprintf (0, _T("Input: %d, %2.2x\n"), address, ret);
636
637 return ret;
638 }
639
mcrmono_write(UINT16 address,UINT8 data)640 static void __fastcall mcrmono_write(UINT16 address, UINT8 data)
641 {
642 if ((address & 0xfc00) == 0xec00) {
643 DrvPalRAM16[(address >> 1) & 0x3f] = data | ((address & 1) << 8);
644 return;
645 }
646
647 if ((address & 0xf000) != 0xf000)
648 bprintf (0, _T("MW: %4.4x, %2.2x\n"), address, data);
649 }
650
mcrmono_read(UINT16 address)651 static UINT8 __fastcall mcrmono_read(UINT16 address)
652 {
653 bprintf (0, _T("MR: %4.4x\n"), address);
654
655 return 0;
656 }
657
mcrmono_write_port(UINT16 address,UINT8 data)658 static void __fastcall mcrmono_write_port(UINT16 address, UINT8 data)
659 {
660 address &= 0xff;
661
662 // bprintf (0, _T("WP: %2.2x, %2.2x\n"), address & 0xff, data);
663
664 if (port_write_handler) {
665 if (port_write_handler(address, data) != -1) return;
666 }
667
668 switch (address)
669 {
670 case 0x05:
671 // coin counter = data & 0x01
672 flipscreen = (data & 0x40) >> 6;
673 return;
674
675 //case 0x06:
676 //return;
677
678 case 0x07:
679 BurnWatchdogWrite();
680 return;
681
682 case 0xf0:
683 case 0xf1:
684 case 0xf2:
685 case 0xf3:
686 z80ctc_write(address & 3, data);
687 return;
688 }
689 }
690
mcrmono_read_port(UINT16 address)691 static UINT8 __fastcall mcrmono_read_port(UINT16 address)
692 {
693 address &= 0xff;
694
695 // bprintf (0, _T("RP: %2.2x\n"), address & 0xff);
696
697 if (port_read_handler) {
698 INT32 ret = port_read_handler(address);
699 if (ret != -1) return ret;
700 }
701
702 switch (address & ~3)
703 {
704 case 0x00:
705 case 0x04:
706 return soundsgood_input_read(address);
707
708 case 0xf0:
709 return z80ctc_read(address & 3);
710 }
711
712 return 0;
713 }
spyhunt_write(UINT16 address,UINT8 data)714 static void __fastcall spyhunt_write(UINT16 address, UINT8 data)
715 {
716 if ((address & 0xfe00) == 0xfa00) {
717 DrvPalRAM16[(address >> 1) & 0x3f] = data | ((address & 1) << 8);
718 return;
719 }
720 }
721
spyhunt_write_port(UINT16 address,UINT8 data)722 static void __fastcall spyhunt_write_port(UINT16 address, UINT8 data)
723 {
724 switch (address & 0xff)
725 {
726 case 0x00:
727 case 0x01:
728 case 0x02:
729 case 0x03:
730 // coin counter = data & 0x01
731 flipscreen = (data & 0x40) >> 6;
732 break; // yes!
733
734 case 0x84:
735 scrollx = (scrollx & 0x700) | data;
736 return;
737
738 case 0x85:
739 scrollx = (scrollx & 0x0ff) | ((data & 7) << 8);
740 scrolly = (scrolly & 0x0ff) | ((data >> 7) << 8);
741 return;
742
743 case 0x86:
744 scrolly = (scrolly & 0x100) | data;
745 return;
746
747 case 0xe0:
748 BurnWatchdogWrite();
749 return;
750
751 case 0xe8:
752 return; // nop
753
754 case 0xf0:
755 case 0xf1:
756 case 0xf2:
757 case 0xf3:
758 z80ctc_write(address & 3, data);
759 return;
760 }
761
762 ssio_write_ports(address, data);
763 }
764
spyhunt_read_port(UINT16 address)765 static UINT8 __fastcall spyhunt_read_port(UINT16 address)
766 {
767 switch (address & ~3)
768 {
769 case 0xf0:
770 return z80ctc_read(address & 3);
771 }
772
773 return ssio_read_ports(address);
774 }
775
ctc_interrupt(INT32 state)776 static void ctc_interrupt(INT32 state)
777 {
778 if (state) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
779 //ZetSetIRQLine(0, state ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
780 }
781
tilemap_callback(bg)782 static tilemap_callback( bg )
783 {
784 INT32 attr = DrvVidRAM[offs * 2 + 1];
785 INT32 code = DrvVidRAM[offs * 2 + 0] | ((attr & 0x03) << 8) | ((attr & 0x40) << 4);
786
787 TILE_SET_INFO(0, code, (attr >> 4) ^ 3, TILE_FLIPYX(attr >> 2));
788 }
789
tilemap_scan(spybg)790 static tilemap_scan( spybg )
791 {
792 return (row & 0x0f) | ((col & 0x3f) << 4) | ((row & 0x10) << 6);
793 }
794
tilemap_callback(spybg)795 static tilemap_callback( spybg )
796 {
797 INT32 attr = DrvVidRAM[offs];
798
799 TILE_SET_INFO(0, (attr & 0x3f) | ((attr >> 7) << 6), 0, (attr & 0x40) ? TILE_FLIPY : 0);
800 }
801
tilemap_callback(txt)802 static tilemap_callback( txt )
803 {
804 TILE_SET_INFO(1, DrvTxtRAM[offs], 0, 0);
805 }
806
DrvDoReset(INT32 clear_mem)807 static INT32 DrvDoReset(INT32 clear_mem)
808 {
809 if (clear_mem) {
810 memset (AllRam, 0, RamEnd - AllRam);
811 }
812
813 ZetOpen(0);
814 ZetReset();
815 ZetClose();
816
817 csd_reset();
818 tcs_reset();
819 soundsgood_reset();
820 ssio_reset();
821
822 BurnWatchdogReset();
823
824 if (has_shift) BurnShiftReset();
825
826 input_mux = 0;
827 flipscreen = 0;
828 scrollx = 0;
829 scrolly = 0;
830 latched_input = 0;
831
832 lamp = 0;
833 last_op4 = 0;
834
835 // powerdrv shifters
836 memset(pd_shift, 0, sizeof(pd_shift));
837 memset(pd_shift_prev, 0, sizeof(pd_shift_prev));
838
839 nExtraCycles[0] = nExtraCycles[1] = nExtraCycles[2] = 0;
840
841 return 0;
842 }
843
MemIndex()844 static INT32 MemIndex()
845 {
846 UINT8 *Next; Next = AllMem;
847
848 DrvZ80ROM0 = Next; Next += 0x010000;
849 DrvZ80ROM1 = Next; Next += 0x010000;
850 DrvSndROM = Next;
851 Drv68KROM = Next; Next += 0x040000;
852
853 DrvGfxROM0 = Next; Next += 0x080000;
854 DrvGfxROM1 = Next; Next += 0x080000 + (32 * 32 * 8);
855 DrvGfxROM2 = Next; Next += 0x010000;
856
857 DrvSndPROM = Next; Next += 0x000020;
858
859 DrvTransTab[0] = Next; Next += 0x000040;
860 DrvTransTab[1] = Next; Next += 0x000040;
861
862 DrvPalette = (UINT32*)Next; Next += 0x044 * sizeof(UINT32);
863
864 DrvNVRAM = Next; Next += 0x000800;
865
866 AllRam = Next;
867
868 DrvSprRAM = Next; Next += 0x000400;
869 DrvVidRAM = Next; Next += 0x000800;
870 DrvPalRAM16 = (UINT16*)Next; Next += 0x000040 * sizeof(UINT16);
871 DrvSndRAM = Next; Next += 0x001000;
872 Drv68KRAM = Next; Next += 0x001000;
873 DrvTxtRAM = Next; Next += 0x000400;
874 DrvZ80RAM1 = Next; Next += 0x000400;
875
876 RamEnd = Next;
877
878 MemEnd = Next;
879
880 return 0;
881 }
882
DrvBuildTransTab()883 static void DrvBuildTransTab()
884 {
885 for (INT32 i = 0; i < 16*4; i++) { // 4bpp pixels * 4 color banks
886 DrvTransTab[0][i] = (0x0101 & (1 << (i & 0xf))) ? 0xff : 0;
887 DrvTransTab[1][i] = (0xfeff & (1 << (i & 0xf))) ? 0xff : 0;
888 }
889 }
890
copy_and_rotate(UINT8 * src,UINT8 * dst)891 static void copy_and_rotate(UINT8 *src, UINT8 *dst)
892 {
893 for (INT32 y = 0; y < 32; y++)
894 {
895 for (INT32 x = 0; x < 32; x++)
896 {
897 dst[(y * 32) + x] = src[(31-x)*32+y];
898 }
899 }
900 }
901
DrvGfxDecode()902 static INT32 DrvGfxDecode()
903 {
904 INT32 Plane0[4] = { (nGraphicsLen[0]/2)*8+0, (nGraphicsLen[0]/2)*8+1, 0, 1 };
905 INT32 XOffs0[16] = { STEP8(0,2) };
906 INT32 YOffs0[16] = { STEP8(0,16) };
907
908 INT32 L = (nGraphicsLen[1]/4)*8;
909 INT32 Plane1[4] = { STEP4(0,1) };
910 INT32 XOffs1[32] = {
911 L*0+0, L*0+4, L*1+0, L*1+4, L*2+0, L*2+4, L*3+0, L*3+4,
912 L*0+0+8, L*0+4+8, L*1+0+8, L*1+4+8, L*2+0+8, L*2+4+8, L*3+0+8, L*3+4+8,
913 L*0+0+16, L*0+4+16, L*1+0+16, L*1+4+16, L*2+0+16, L*2+4+16, L*3+0+16, L*3+4+16,
914 L*0+0+24, L*0+4+24, L*1+0+24, L*1+4+24, L*2+0+24, L*2+4+24, L*3+0+24, L*3+4+24
915 };
916 INT32 YOffs1[32] = { STEP32(0,32) };
917
918 UINT8 *tmp = (UINT8*)BurnMalloc(0x40000);
919 if (tmp == NULL) {
920 return 1;
921 }
922
923 GfxDecode((nGraphicsLen[0] * 2) / (8 * 8), 4, 8, 8, Plane0, XOffs0, YOffs0, 0x080, DrvGfxROM0, tmp);
924
925 for (INT32 i = 0; i < nGraphicsLen[0] * 2; i+=0x40) { // 2x size and invert pixel
926 for (INT32 y = 0; y < 16; y++) {
927 for (INT32 x = 0; x < 16; x++) {
928 DrvGfxROM0[(i * 4) + (y * 16) + x] = tmp[i + ((y / 2) * 8) + (x / 2)] ^ 0xf;
929 }
930 }
931 }
932
933 memcpy (tmp, DrvGfxROM1, nGraphicsLen[1]);
934
935 GfxDecode((nGraphicsLen[1] * 2) / (32 * 32), 4, 32, 32, Plane1, XOffs1, YOffs1, 0x400, tmp, DrvGfxROM1);
936
937 BurnFree(tmp);
938
939 return 0;
940 }
941
SpyhuntGfxDecode()942 static INT32 SpyhuntGfxDecode()
943 {
944 INT32 Plane0[2] = { 0, 1 };
945 INT32 XOffs0[16] = { 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14 };
946 INT32 YOffs0[16] = { 0, 0, 16, 16, 32, 32, 48, 48, 64, 64, 80, 80, 96, 96, 112, 112 };
947
948 INT32 L = (nGraphicsLen[1]/4)*8;
949 INT32 Plane1[4] = { STEP4(0,1) };
950 INT32 XOffs1[32] = {
951 L*0+0, L*0+4, L*1+0, L*1+4, L*2+0, L*2+4, L*3+0, L*3+4,
952 L*0+0+8, L*0+4+8, L*1+0+8, L*1+4+8, L*2+0+8, L*2+4+8, L*3+0+8, L*3+4+8,
953 L*0+0+16, L*0+4+16, L*1+0+16, L*1+4+16, L*2+0+16, L*2+4+16, L*3+0+16, L*3+4+16,
954 L*0+0+24, L*0+4+24, L*1+0+24, L*1+4+24, L*2+0+24, L*2+4+24, L*3+0+24, L*3+4+24
955 };
956 INT32 YOffs1[32] = { STEP32(0,32) };
957
958 INT32 Plane2[4] = { (nGraphicsLen[0]/2)*8+0, (nGraphicsLen[0]/2)*8+1, 0, 1 };
959 INT32 XOffs2[64] = {
960 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
961 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30,
962 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46,
963 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62
964 };
965 INT32 YOffs2[32] = {
966 0*32, 0*32, 2*32, 2*32, 4*32, 4*32, 6*32, 6*32,
967 8*32, 8*32, 10*32, 10*32, 12*32, 12*32, 14*32, 14*32,
968 16*32, 16*32, 18*32, 18*32, 20*32, 20*32, 22*32, 22*32,
969 24*32, 24*32, 26*32, 26*32, 28*32, 28*32, 30*32, 30*32
970 };
971
972 UINT8 *tmp = (UINT8*)BurnMalloc(0x40000);
973 if (tmp == NULL) {
974 return 1;
975 }
976
977 memcpy (tmp, DrvGfxROM0, nGraphicsLen[0]);
978
979 GfxDecode((nGraphicsLen[0] * 8) / (64 * 32), 4, 64, 32, Plane2, XOffs2, YOffs2, 0x400, tmp, DrvGfxROM0);
980
981 memcpy (tmp, DrvGfxROM1, nGraphicsLen[1]);
982
983 GfxDecode((nGraphicsLen[1] * 2) / (32 * 32), 4, 32, 32, Plane1, XOffs1, YOffs1, 0x400, tmp, DrvGfxROM1);
984
985 memcpy (tmp, DrvGfxROM2, nGraphicsLen[2]);
986
987 GfxDecode((nGraphicsLen[2] * 8 * 2) / (16 * 16), 2, 16, 16, Plane0, XOffs0, YOffs0, 0x080, tmp, DrvGfxROM2);
988
989 BurnFree(tmp);
990
991 return 0;
992 }
993
ctc_trigger(INT32,UINT8 data)994 static void ctc_trigger(INT32 , UINT8 data)
995 {
996 z80ctc_trg_write(1, data);
997 }
998
sound_system_init(INT32 sound_system)999 static void sound_system_init(INT32 sound_system)
1000 {
1001 BurnLoadRom(DrvSndPROM + 0x00000, 0x80, 1);
1002
1003 switch (sound_system)
1004 {
1005 case 0: soundsgood_init(0, 0, Drv68KROM, Drv68KRAM); break;
1006 case 1: tcs_init(0, 0, 0, DrvSndROM, DrvSndRAM); break;
1007
1008 case 2:
1009 {
1010 csd_init(Drv68KROM, Drv68KRAM);
1011 ssio_init(DrvZ80ROM1, DrvZ80RAM1, DrvSndPROM);
1012 }
1013 break;
1014
1015 case 3:
1016 {
1017 ssio_init(DrvZ80ROM1, DrvZ80RAM1, DrvSndPROM);
1018 }
1019 break;
1020
1021 case 4: csd_init(Drv68KROM, Drv68KRAM); break;
1022 }
1023
1024 ssio_inputs = DrvInputs;
1025 ssio_dips = 0xff; // unused in mcr3
1026 }
1027
DrvLoadRoms(bool bLoad)1028 static INT32 DrvLoadRoms(bool bLoad)
1029 {
1030 char* pRomName;
1031 struct BurnRomInfo ri;
1032 UINT8 *pLoad[4] = { DrvZ80ROM0, DrvZ80ROM1, DrvSndROM, Drv68KROM };
1033 UINT8 *gLoad[3] = { DrvGfxROM0, DrvGfxROM1, DrvGfxROM2 };
1034
1035 for (INT32 i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++)
1036 {
1037 BurnDrvGetRomInfo(&ri, i);
1038
1039 if ((ri.nType & BRF_PRG) && ((ri.nType & 7) <= 2)) {
1040 INT32 type = (ri.nType - 1) & 1;
1041 if (bLoad) if (BurnLoadRom(pLoad[type], i, 1)) return 1;
1042 pLoad[type] += ri.nLen;
1043 continue;
1044 }
1045
1046 if ((ri.nType & BRF_PRG) && ((ri.nType & 7) == 3)) {
1047 INT32 type = 2;
1048 if (bLoad) {
1049 memmove (pLoad[type], pLoad[type] + ri.nLen, 0x10000 - ri.nLen); // m6809 loaded at end of mem space
1050 if (BurnLoadRom(pLoad[type] + 0x10000 - ri.nLen, i, 1)) return 1;
1051 }
1052 continue;
1053 }
1054
1055 if ((ri.nType & BRF_PRG) && ((ri.nType & 7) == 4)) {
1056 INT32 type = 3;
1057 if (bLoad) {
1058 if (BurnLoadRom(pLoad[type] + 1, i, 2)) return 1;
1059 if (BurnLoadRom(pLoad[type] + 0, i+1, 2)) return 1;
1060 }
1061 i++;
1062 pLoad[type] += ri.nLen * 2;
1063 continue;
1064 }
1065
1066 if ((ri.nType & BRF_GRA) && ((ri.nType & 7) <= 3)) {
1067 INT32 type = (ri.nType - 1) & 3;
1068 if (bLoad) if (BurnLoadRom(gLoad[type], i, 1)) return 1;
1069 gLoad[type] += ri.nLen;
1070 continue;
1071 }
1072 }
1073
1074 nGraphicsLen[0] = gLoad[0] - DrvGfxROM0;
1075 nGraphicsLen[1] = gLoad[1] - DrvGfxROM1;
1076 nGraphicsLen[2] = gLoad[2] - DrvGfxROM2;
1077
1078 return 0;
1079 }
1080
DrvInit(INT32 sound_system)1081 static INT32 DrvInit(INT32 sound_system)
1082 {
1083 BurnSetRefreshRate(30.00);
1084
1085 AllMem = NULL;
1086 MemIndex();
1087 INT32 nLen = MemEnd - (UINT8 *)0;
1088 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1089 memset(AllMem, 0, nLen);
1090 MemIndex();
1091
1092 if (DrvLoadRoms(true)) return 1;
1093
1094 DrvGfxDecode();
1095 DrvBuildTransTab();
1096
1097 memset (DrvZ80ROM0 + 0xf800, 0xff, 0x800); // unmapped
1098
1099 ZetInit(0);
1100 ZetOpen(0);
1101 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xdfff, MAP_ROM);
1102 ZetMapMemory(DrvNVRAM, 0xe000, 0xe7ff, MAP_RAM);
1103 ZetMapMemory(DrvSprRAM, 0xe800, 0xebff, MAP_RAM);
1104 ZetMapMemory(DrvVidRAM, 0xf000, 0xf7ff, MAP_RAM);
1105 ZetMapMemory(DrvZ80ROM0 + 0xf800, 0xf800, 0xffff, MAP_ROM);
1106 ZetSetWriteHandler(mcrmono_write);
1107 ZetSetReadHandler(mcrmono_read);
1108 ZetSetInHandler(mcrmono_read_port);
1109 ZetSetOutHandler(mcrmono_write_port);
1110
1111 ZetDaisyInit(Z80_CTC, 0);
1112 z80ctc_init(5000000, 0, ctc_interrupt, ctc_trigger, NULL, NULL);
1113 ZetClose();
1114
1115 sound_system_init(sound_system);
1116
1117 BurnWatchdogInit(DrvDoReset, -1); // power drive doesn't like 16
1118
1119 GenericTilesInit();
1120 GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 16, 16, 32, 30);
1121 GenericTilemapSetGfx(0, DrvGfxROM0, 4, 16, 16, (nGraphicsLen[0] * 2 * 2 * 2), 0, 3);
1122
1123 BurnTrackballInit(2);
1124
1125 DrvDoReset(1);
1126
1127 return 0;
1128 }
1129
SpyhuntCommonInit(INT32 sound_system)1130 static INT32 SpyhuntCommonInit(INT32 sound_system)
1131 {
1132 BurnSetRefreshRate(30.00);
1133
1134 AllMem = NULL;
1135 MemIndex();
1136 INT32 nLen = MemEnd - (UINT8 *)0;
1137 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1138 memset(AllMem, 0, nLen);
1139 MemIndex();
1140
1141 if (DrvLoadRoms(true)) return 1;
1142
1143 SpyhuntGfxDecode();
1144 DrvBuildTransTab();
1145
1146 ZetInit(0);
1147 ZetOpen(0);
1148 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xdfff, MAP_ROM);
1149 ZetMapMemory(DrvVidRAM, 0xe000, 0xe7ff, MAP_RAM);
1150 ZetMapMemory(DrvTxtRAM, 0xe800, 0xebff, MAP_RAM);
1151 ZetMapMemory(DrvTxtRAM, 0xec00, 0xefff, MAP_RAM);
1152 ZetMapMemory(DrvNVRAM, 0xf000, 0xf7ff, MAP_RAM);
1153 ZetMapMemory(DrvSprRAM, 0xf800, 0xf9ff, MAP_RAM);
1154 ZetSetWriteHandler(spyhunt_write);
1155 ZetSetOutHandler(spyhunt_write_port);
1156 ZetSetInHandler(spyhunt_read_port);
1157
1158 ZetDaisyInit(Z80_CTC, 0);
1159 z80ctc_init(5000000, 0, ctc_interrupt, ctc_trigger, NULL, NULL);
1160 ZetClose();
1161
1162 if (is_spyhunt) {
1163 ssio_spyhunter = 1;
1164 filter_rc_init(0, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 0);
1165 filter_rc_init(1, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
1166 filter_rc_init(2, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
1167 filter_rc_init(3, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
1168 filter_rc_init(4, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
1169 filter_rc_init(5, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
1170
1171 filter_rc_set_route(0, 1.00, FLT_RC_PANNEDLEFT);
1172 filter_rc_set_route(1, 1.00, FLT_RC_PANNEDLEFT);
1173 filter_rc_set_route(2, 1.00, FLT_RC_PANNEDLEFT);
1174 filter_rc_set_route(3, 1.00, FLT_RC_PANNEDRIGHT);
1175 filter_rc_set_route(4, 1.00, FLT_RC_PANNEDRIGHT);
1176 filter_rc_set_route(5, 1.00, FLT_RC_PANNEDRIGHT);
1177
1178 LP1 = new LowPass2(CutFreq, SampleFreq, Q, Gain, CutFreq2, Q2, Gain2);
1179 }
1180
1181 sound_system_init(sound_system);
1182
1183 BurnWatchdogInit(DrvDoReset, -1);
1184
1185 GenericTilesInit();
1186 GenericTilemapInit(0, spybg_map_scan , spybg_map_callback, 64, 32, 64, 32);
1187 GenericTilemapInit(1, TILEMAP_SCAN_COLS, txt_map_callback, 16, 16, 32, 32);
1188 GenericTilemapSetGfx(0, DrvGfxROM0, 4, 64, 32, 0x40000, 0x30, 0);
1189 GenericTilemapSetGfx(1, DrvGfxROM2, 2, 16, 16, 0x10000, 0x40, 0);
1190 GenericTilemapSetTransparent(1, 0);
1191 GenericTilemapSetOffsets(0, (sound_system == 3) ? 96-16 : -16, 0);
1192 GenericTilemapSetOffsets(1, (sound_system == 3) ? 16 : -16, 0);
1193
1194 if (is_spyhunt) {
1195 copy_and_rotate(DrvGfxROM1 + 0x29*0x20*0x20, DrvGfxROM1 + (0x200*0x20*0x20)+(0x20*0x20*0));
1196 copy_and_rotate(DrvGfxROM1 + 0x2a*0x20*0x20, DrvGfxROM1 + (0x200*0x20*0x20)+(0x20*0x20*1));
1197 copy_and_rotate(DrvGfxROM1 + 0x45*0x20*0x20, DrvGfxROM1 + (0x200*0x20*0x20)+(0x20*0x20*2));
1198 copy_and_rotate(DrvGfxROM1 + 0x7b*0x20*0x20, DrvGfxROM1 + (0x200*0x20*0x20)+(0x20*0x20*3));
1199 copy_and_rotate(DrvGfxROM1 + 0x0f*0x20*0x20, DrvGfxROM1 + (0x200*0x20*0x20)+(0x20*0x20*4));
1200 }
1201
1202 BurnTrackballInit(2);
1203
1204 if (has_shift)
1205 BurnShiftInit(SHIFT_POSITION_BOTTOM_RIGHT, SHIFT_COLOR_RED, 80);
1206
1207 DrvDoReset(1);
1208
1209 return 0;
1210 }
1211
DrvExit()1212 static INT32 DrvExit()
1213 {
1214 GenericTilesExit();
1215 ZetExit();
1216
1217 csd_exit();
1218 tcs_exit();
1219 soundsgood_exit();
1220 ssio_exit();
1221
1222 if (is_spyhunt) {
1223 filter_rc_exit();
1224 delete LP1;
1225 LP1 = NULL;
1226 }
1227
1228 BurnWatchdogExit();
1229
1230 BurnTrackballExit();
1231 if (has_shift) BurnShiftExit();
1232
1233 sound_status_bit = 8; // default to disabled
1234 sound_input_bank = 0;
1235 port_write_handler = NULL;
1236 port_read_handler = NULL;
1237 sprite_color_mask = 0;
1238 flip_screen_x = 0;
1239
1240 is_demoderm = 0;
1241 is_spyhunt = 0;
1242 is_powerdrv = 0;
1243 is_maxrpm = 0;
1244
1245 has_dial = 0;
1246 has_shift = 0;
1247
1248 dip_service = 0x20;
1249
1250 BurnFree(AllMem);
1251
1252 return 0;
1253 }
1254
DrvPaletteUpdate()1255 static void DrvPaletteUpdate()
1256 {
1257 for (INT32 i = 0; i < 0x40; i++)
1258 {
1259 UINT8 r = pal3bit(DrvPalRAM16[i] >> 6);
1260 UINT8 g = pal3bit(DrvPalRAM16[i] & 7);
1261 UINT8 b = pal3bit((DrvPalRAM16[i] >> 3) & 7);
1262
1263 DrvPalette[i] = BurnHighCol(r,g,b,0);
1264 }
1265
1266 // spyhunt hardware
1267 DrvPalette[0x40] = 0;
1268 DrvPalette[0x41] = BurnHighCol(0x00, 0xff, 0x00, 0);
1269 DrvPalette[0x42] = BurnHighCol(0x00, 0x00, 0xff, 0);
1270 DrvPalette[0x43] = BurnHighCol(0xff, 0xff, 0xff, 0);
1271 }
1272
draw_sprites(INT32 color_mask,INT32 dx,INT32 dy)1273 static void draw_sprites(INT32 color_mask, INT32 dx, INT32 dy)
1274 {
1275 INT32 codemask = (nGraphicsLen[1] * 2) / (32 * 32);
1276
1277 for (INT32 offs = 0x200 - 4; offs >= 0; offs -= 4)
1278 {
1279 if (DrvSprRAM[offs] == 0) continue;
1280
1281 INT32 flags = DrvSprRAM[offs + 1];
1282 INT32 code = DrvSprRAM[offs + 2] + 256 * ((flags >> 3) & 0x01);
1283 INT32 color = ~flags & color_mask;
1284 INT32 flipx = flags & 0x10;
1285 INT32 flipy = flags & 0x20;
1286 INT32 sx = (DrvSprRAM[offs + 3] - 3) * 2;
1287 INT32 sy = (241 - DrvSprRAM[offs]) * 2;
1288
1289 sx += dx;
1290 sy += dy;
1291
1292 if (flip_screen_x) {
1293 sx = (nScreenWidth - 32) - sx;
1294 flipx ^= 0x10;
1295 }
1296
1297 if (!flipscreen)
1298 {
1299 if (nSpriteEnable & 2) RenderPrioMaskTranstabSprite(pTransDraw, DrvGfxROM1, code % codemask, (color * 16), 0xff, sx, sy, flipx, flipy, 32, 32, DrvTransTab[0], 0);
1300 if (nSpriteEnable & 4) RenderPrioMaskTranstabSprite(pTransDraw, DrvGfxROM1, code % codemask, (color * 16), 0xff, sx, sy, flipx, flipy, 32, 32, DrvTransTab[1], 2);
1301 }
1302 else
1303 {
1304 RenderPrioMaskTranstabSprite(pTransDraw, DrvGfxROM1, code % codemask, (color * 16), 0xff, 480 - sx, 452 - sy, !flipx, !flipy, 32, 32, DrvTransTab[0], 0);
1305 RenderPrioMaskTranstabSprite(pTransDraw, DrvGfxROM1, code % codemask, (color * 16), 0xff, 480 - sx, 452 - sy, !flipx, !flipy, 32, 32, DrvTransTab[1], 2);
1306 }
1307 }
1308 }
1309
DrvDraw()1310 static INT32 DrvDraw()
1311 {
1312 if (DrvRecalc) {
1313 DrvPaletteUpdate();
1314 DrvRecalc = 1;
1315 }
1316
1317 BurnTransferClear();
1318
1319 GenericTilemapSetFlip(0, flipscreen ? (TMAP_FLIPX | TMAP_FLIPY) : 0);
1320
1321 if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 1/*must be this!*/);
1322
1323 if (nSpriteEnable & 1) draw_sprites(0x03, 0, 0);
1324
1325 BurnTransferCopy(DrvPalette);
1326
1327 return 0;
1328 }
1329
SpyhuntDraw()1330 static INT32 SpyhuntDraw()
1331 {
1332 if (DrvRecalc) {
1333 DrvPaletteUpdate();
1334 DrvRecalc = 1;
1335 }
1336
1337 BurnTransferClear();
1338
1339 GenericTilemapSetFlip(TMAP_GLOBAL, (flipscreen ? (TMAP_FLIPX | TMAP_FLIPY) : 0) ^ flip_screen_x);
1340 GenericTilemapSetScrollX(0, scrollx * 2);
1341 GenericTilemapSetScrollY(0, scrolly * 2);
1342
1343 if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 0);
1344
1345 if (nSpriteEnable & 1) draw_sprites(sprite_color_mask, -12, 0);
1346
1347 if (nBurnLayer & 2) GenericTilemapDraw(1, pTransDraw, 0);
1348
1349 if (is_spyhunt) {
1350 if (lamp&0x04) {
1351 // 29+2a, weapons van (pre-rotated)
1352 RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x200, 0, 0, nScreenWidth-16, 32, 0, 0, 32, 32, 0x10000/2, 0x10000/2);
1353 RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x201, 0, 0, nScreenWidth-16, 48, 0, 0, 32, 32, 0x10000/2, 0x10000/2);
1354 }
1355 if (lamp&0x01) {
1356 // oil
1357 RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x016, 0, 0, nScreenWidth-16, 64, 0, 0, 32, 32, 0x10000/2, 0x10000/2);
1358 }
1359 if (lamp&0x08) {
1360 // smoke
1361 RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x019, 0, 0, nScreenWidth-16, 80, 0, 0, 32, 32, 0x10000/2, 0x10000/2);
1362 }
1363 if (lamp&0x02) {
1364 // missile (pre-rotated)
1365 RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x202, 0, 0, nScreenWidth-24, 96, 0, 0, 32, 32, 0x10000, 0x10000);
1366 }
1367 if (lamp&0x10) {
1368 // machine guns (pre-rotated)
1369 //RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x204, 0, 0, nScreenWidth-16, 128, 1, 0, 32, 32, 0x10000/2, 0x10000/2);
1370 //RenderZoomedTile(pTransDraw, DrvGfxROM1, 0x203, 0, 0, nScreenWidth-16, 144, 1, 0, 32, 32, 0x10000/2, 0x10000/2);
1371 }
1372 }
1373 BurnTransferCopy(DrvPalette);
1374
1375 if (has_shift) BurnShiftRenderDoubleSize();
1376
1377 return 0;
1378 }
1379
mcr_interrupt(INT32 scanline)1380 static void mcr_interrupt(INT32 scanline)
1381 {
1382 if (scanline == 0 || scanline == 240)
1383 {
1384 z80ctc_trg_write(2, 1);
1385 z80ctc_trg_write(2, 0);
1386 }
1387
1388 if (scanline == 0)
1389 {
1390 z80ctc_trg_write(3, 1);
1391 z80ctc_trg_write(3, 0);
1392 }
1393 }
1394
build_inputs()1395 static void build_inputs()
1396 {
1397 if (is_powerdrv) {
1398 if (DrvJoy2[1] && !pd_shift_prev[0]) { // P1
1399 pd_shift[0] = !pd_shift[0];
1400 }
1401 pd_shift_prev[0] = DrvJoy2[1];
1402 DrvJoy2[1] = pd_shift[0];
1403
1404 if (DrvJoy2[5] && !pd_shift_prev[1]) { // P2
1405 pd_shift[1] = !pd_shift[1];
1406 }
1407 pd_shift_prev[1] = DrvJoy2[5];
1408 DrvJoy2[5] = pd_shift[1];
1409
1410 if (DrvJoy3[1] && !pd_shift_prev[2]) { // P3
1411 pd_shift[2] = !pd_shift[2];
1412 }
1413 pd_shift_prev[2] = DrvJoy3[1];
1414 DrvJoy3[1] = pd_shift[2];
1415 }
1416
1417 memcpy (DrvInputs, DrvDips, 5); // 0xff-filled?
1418 DrvInputs[5] = 0xff;
1419 DrvInputs4f = 0xff;
1420
1421 for (INT32 i = 0; i < 8; i++) {
1422 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
1423 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
1424 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
1425 DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
1426 DrvInputs[4] ^= (DrvJoy5[i] & 1) << i;
1427 DrvInputs[5] ^= (DrvJoy6[i] & 1) << i;
1428 DrvInputs4f ^= (DrvJoy4f[i] & 1) << i; // for maxrpm
1429 }
1430
1431 DrvInputs[0] = (DrvInputs[0] & ~dip_service) | (DrvDips[5] & dip_service);
1432
1433 { // analog stuff
1434 if (has_dial) { // etc
1435 BurnTrackballConfig(0, AXIS_REVERSED, AXIS_REVERSED);
1436 BurnTrackballFrame(0, DrvAnalogPort0, DrvAnalogPort1, 7, 10);
1437 BurnTrackballUDLR(0, 0, 0, DrvJoy4f[0], DrvJoy4f[1]);
1438 BurnTrackballUpdate(0);
1439 }
1440
1441 if (is_demoderm) {
1442 BurnTrackballConfig(0, AXIS_NORMAL, AXIS_NORMAL);
1443 BurnTrackballFrame(0, DrvAnalogPort0, DrvAnalogPort1, 2, 5);
1444 BurnTrackballUpdate(0);
1445
1446 BurnTrackballConfig(1, AXIS_NORMAL, AXIS_NORMAL);
1447 BurnTrackballFrame(1, DrvAnalogPort2, DrvAnalogPort3, 2, 5);
1448 BurnTrackballUpdate(1);
1449 }
1450
1451 if (has_shift) { // gear shifter stuff
1452 BurnShiftInputCheckToggle(DrvJoy4f[4]);
1453
1454 DrvInputs[0] &= ~0x10;
1455 DrvInputs[0] |= (bBurnShiftStatus) ? 0x00 : 0x10;
1456 }
1457 }
1458 }
1459
DrvFrame()1460 static INT32 DrvFrame()
1461 {
1462 BurnWatchdogUpdate();
1463
1464 if (DrvReset) {
1465 DrvDoReset(1);
1466 }
1467
1468 ZetNewFrame();
1469 SekNewFrame();
1470
1471 build_inputs();
1472
1473 INT32 nInterleave = 480;
1474 INT32 nCyclesTotal[2] = { 5000000 / 30, 8000000 / 30 };
1475 INT32 nCyclesDone[2] = { nExtraCycles[0], 0 };
1476
1477 ZetOpen(0);
1478 SekOpen(0);
1479
1480 for (INT32 i = 0; i < nInterleave; i++)
1481 {
1482 CPU_RUN(0, Zet);
1483 mcr_interrupt(i);
1484
1485 if (soundsgood_reset_status())
1486 {
1487 CPU_IDLE_SYNCINT(1, Sek);
1488 }
1489 else
1490 {
1491 CPU_RUN_SYNCINT(1, Sek);
1492 }
1493 }
1494
1495 if (pBurnSoundOut) {
1496 BurnSoundClear();
1497 DACUpdate(pBurnSoundOut, nBurnSoundLen);
1498 }
1499
1500 SekClose();
1501 ZetClose();
1502
1503 nExtraCycles[0] = nCyclesDone[0] - nCyclesTotal[0];
1504
1505 if (pBurnDraw) {
1506 BurnDrvRedraw();
1507 }
1508
1509 return 0;
1510 }
1511
TcsFrame()1512 static INT32 TcsFrame()
1513 {
1514 BurnWatchdogUpdate();
1515
1516 if (DrvReset) {
1517 DrvDoReset(1);
1518 }
1519
1520 ZetNewFrame();
1521 M6809NewFrame();
1522
1523 build_inputs();
1524
1525 INT32 nInterleave = 480;
1526 INT32 nCyclesTotal[2] = { 5000000 / 30, 2000000 / 30 };
1527 INT32 nCyclesDone[2] = { nExtraCycles[0], 0 };
1528
1529 ZetOpen(0);
1530 M6809Open(0);
1531
1532 for (INT32 i = 0; i < nInterleave; i++)
1533 {
1534 CPU_RUN(0, Zet);
1535 mcr_interrupt(i);
1536
1537 if (tcs_reset_status())
1538 {
1539 CPU_IDLE_SYNCINT(1, M6809);
1540 }
1541 else
1542 {
1543 CPU_RUN_SYNCINT(1, M6809);
1544 }
1545 }
1546
1547 if (pBurnSoundOut) {
1548 BurnSoundClear();
1549 DACUpdate(pBurnSoundOut, nBurnSoundLen);
1550 }
1551
1552 M6809Close();
1553 ZetClose();
1554 nExtraCycles[0] = nCyclesDone[0] - nCyclesTotal[0];
1555
1556 if (pBurnDraw) {
1557 BurnDrvRedraw();
1558 }
1559
1560 return 0;
1561 }
1562
CSDSSIOFrame()1563 static INT32 CSDSSIOFrame()
1564 {
1565 BurnWatchdogUpdate();
1566
1567 if (DrvReset) {
1568 DrvDoReset(1);
1569 }
1570
1571 INT32 has_ssio = ssio_initialized();
1572 INT32 has_csd = csd_initialized();
1573
1574 ZetNewFrame();
1575 if (has_csd) SekNewFrame();
1576
1577 build_inputs();
1578
1579 INT32 nInterleave = 480;
1580 INT32 nCyclesTotal[3] = { 5000000 / 30, 8000000 / 30, 2000000 / 30 };
1581 INT32 nCyclesDone[3] = { nExtraCycles[0], nExtraCycles[1], nExtraCycles[2] };
1582
1583 if (has_csd) {
1584 SekOpen(0);
1585 SekIdle(nExtraCycles[1]);
1586 nExtraCycles[1] = 0;
1587 }
1588
1589 for (INT32 i = 0; i < nInterleave; i++)
1590 {
1591 ZetOpen(0);
1592 CPU_RUN(0, Zet);
1593 mcr_interrupt(i);
1594
1595 if (has_csd)
1596 {
1597 if (csd_reset_status())
1598 {
1599 CPU_IDLE_SYNCINT(1, Sek);
1600 }
1601 else
1602 {
1603 CPU_RUN_SYNCINT(1, Sek);
1604 }
1605 }
1606 ZetClose();
1607
1608 if (has_ssio)
1609 {
1610 ZetOpen(1);
1611 CPU_RUN(2, Zet);
1612 ssio_14024_clock(nInterleave);
1613 ZetClose();
1614 }
1615 }
1616
1617 if (pBurnSoundOut) {
1618 if (is_spyhunt) {
1619 AY8910RenderInternal(nBurnSoundLen);
1620 filter_rc_update(0, pAY8910Buffer[0], pBurnSoundOut, nBurnSoundLen); // filter just used as a mixer
1621 filter_rc_update(1, pAY8910Buffer[1], pBurnSoundOut, nBurnSoundLen);
1622 filter_rc_update(2, pAY8910Buffer[2], pBurnSoundOut, nBurnSoundLen);
1623 filter_rc_update(3, pAY8910Buffer[3], pBurnSoundOut, nBurnSoundLen);
1624 filter_rc_update(4, pAY8910Buffer[4], pBurnSoundOut, nBurnSoundLen);
1625 if (LP1) { // this filter actually does the filtering
1626 LP1->FilterMono(pAY8910Buffer[5], nBurnSoundLen); // Engine
1627 }
1628 filter_rc_update(5, pAY8910Buffer[5], pBurnSoundOut, nBurnSoundLen);
1629
1630 DACUpdate(pBurnSoundOut, nBurnSoundLen);
1631 } else {
1632 BurnSoundClear();
1633 if (has_ssio) AY8910Render(pBurnSoundOut, nBurnSoundLen);
1634 if (has_csd) DACUpdate(pBurnSoundOut, nBurnSoundLen);
1635 }
1636 }
1637
1638 if (has_csd) {
1639 nExtraCycles[1] = nCyclesDone[1] - SekTotalCycles();
1640 SekClose();
1641 }
1642
1643 nExtraCycles[0] = nCyclesDone[0] - nCyclesTotal[0];
1644 nExtraCycles[2] = nCyclesDone[2] - nCyclesTotal[2];
1645
1646 if (pBurnDraw) {
1647 BurnDrvRedraw();
1648 }
1649
1650 return 0;
1651 }
1652
DrvScan(INT32 nAction,INT32 * pnMin)1653 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
1654 {
1655 struct BurnArea ba;
1656
1657 if (pnMin) {
1658 *pnMin = 0x029702;
1659 }
1660
1661 if (nAction & ACB_VOLATILE) {
1662 memset(&ba, 0, sizeof(ba));
1663
1664 ba.Data = AllRam;
1665 ba.nLen = RamEnd - AllRam;
1666 ba.szName = "All Ram";
1667 BurnAcb(&ba);
1668
1669 ScanVar(DrvNVRAM, 0x800, "WORK RAM"); // also nv...
1670
1671 ZetScan(nAction);
1672
1673 tcs_scan(nAction, pnMin);
1674 csd_scan(nAction, pnMin);
1675 soundsgood_scan(nAction, pnMin);
1676 ssio_scan(nAction, pnMin);
1677
1678 BurnWatchdogScan(nAction);
1679
1680 BurnTrackballScan();
1681
1682 if (has_shift) BurnShiftScan(nAction);
1683
1684 SCAN_VAR(flipscreen);
1685 SCAN_VAR(latched_input);
1686 SCAN_VAR(maxrpm_adc_control);
1687 SCAN_VAR(maxrpm_adc_select);
1688 SCAN_VAR(maxrpm_p1_shift);
1689 SCAN_VAR(maxrpm_p2_shift);
1690 SCAN_VAR(maxrpm_last_shift);
1691 SCAN_VAR(pd_shift);
1692 SCAN_VAR(pd_shift_prev);
1693 SCAN_VAR(scrollx);
1694 SCAN_VAR(scrolly);
1695 SCAN_VAR(input_mux);
1696
1697 SCAN_VAR(lamp);
1698 SCAN_VAR(last_op4);
1699
1700 SCAN_VAR(nExtraCycles);
1701 }
1702
1703 if (nAction & ACB_NVRAM) {
1704 ScanVar(DrvNVRAM, 0x800, "NV RAM");
1705 }
1706
1707 return 0;
1708 }
1709
1710
1711 static struct BurnRomInfo emptyRomDesc[] = {
1712 { "", 0, 0, 0 },
1713 };
1714
1715 static struct BurnRomInfo SsiopromRomDesc[] = {
1716 #if !defined (ROM_VERIFY)
1717 { "82s123.12d", 0x0020, 0xe1281ee9, 0 | BRF_SND },
1718 #else
1719 { "", 0x000000, 0x00000000, BRF_ESS | BRF_PRG | BRF_BIOS },
1720 #endif
1721 };
1722
1723
1724 // Demolition Derby (MCR-3 Mono Board Version)
1725
1726 static struct BurnRomInfo demodermRomDesc[] = {
1727 { "pro0.3b", 0x8000, 0x2e24527b, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
1728 { "pro1.5b", 0x8000, 0x034c00fc, 1 | BRF_PRG | BRF_ESS }, // 1
1729
1730 { "tcs_u5.bin", 0x2000, 0xeca33b2c, 3 | BRF_PRG | BRF_ESS }, // 2 M6809 Code
1731 { "tcs_u4.bin", 0x2000, 0x3490289a, 3 | BRF_PRG | BRF_ESS }, // 3
1732
1733 { "bg0.15a", 0x2000, 0xa35d13b8, 1 | BRF_GRA }, // 4 Background Tiles
1734 { "bg1.14b", 0x2000, 0x22ca93f3, 1 | BRF_GRA }, // 5
1735
1736 { "dd_fg-0.a4", 0x4000, 0xe57a4de6, 2 | BRF_GRA }, // 6 Sprites
1737 { "dd_fg-4.a3", 0x4000, 0x55aa667f, 2 | BRF_GRA }, // 7
1738 { "dd_fg-1.a6", 0x4000, 0x70259651, 2 | BRF_GRA }, // 8
1739 { "dd_fg-5.a5", 0x4000, 0x5fe99007, 2 | BRF_GRA }, // 9
1740 { "dd_fg-2.a8", 0x4000, 0x6cab7b95, 2 | BRF_GRA }, // 10
1741 { "dd_fg-6.a7", 0x4000, 0xabfb9a8b, 2 | BRF_GRA }, // 11
1742 { "dd_fg-3.a10", 0x4000, 0x801d9b86, 2 | BRF_GRA }, // 12
1743 { "dd_fg-7.a9", 0x4000, 0x0ec3f60a, 2 | BRF_GRA }, // 13
1744 };
1745
1746 STD_ROM_PICK(demoderm)
STD_ROM_FN(demoderm)1747 STD_ROM_FN(demoderm)
1748
1749 static INT32 demoderm_read_callback(UINT8 address)
1750 {
1751 switch (address)
1752 {
1753 case 0x01:
1754 {
1755 UINT8 ipt = DrvInputs[1] & 0x03;
1756 ipt |= (((input_mux) ? ~BurnTrackballRead(1, 0) : ~BurnTrackballRead(0, 0)) << 2) & 0x3f;
1757
1758 BurnTrackballUpdate(input_mux);
1759
1760 return ipt;
1761 }
1762
1763 case 0x02:
1764 {
1765 UINT8 ipt = DrvInputs[2] & 0x03;
1766 ipt |= (((input_mux) ? ~BurnTrackballRead(1, 1) : ~BurnTrackballRead(0, 1)) << 2) & 0x3f;
1767
1768 BurnTrackballUpdate(input_mux);
1769
1770 return ipt;
1771 }
1772 }
1773
1774 return -1;
1775 }
1776
demoderm_write_callback(UINT8 address,UINT8 data)1777 static INT32 demoderm_write_callback(UINT8 address, UINT8 data)
1778 {
1779 switch (address)
1780 {
1781 case 0x06:
1782 {
1783 if (data & 0x80) input_mux = 0;
1784 if (data & 0x40) input_mux = 1;
1785
1786 INT32 cycles = ((ZetTotalCycles() * 2) / 5) - M6809TotalCycles();
1787 if (cycles > 0) M6809Run(cycles);
1788 tcs_data_write(data);
1789 }
1790 return 0;
1791 }
1792
1793 return -1;
1794 }
1795
DemodermInit()1796 static INT32 DemodermInit()
1797 {
1798 port_write_handler = demoderm_write_callback;
1799 port_read_handler = demoderm_read_callback;
1800 is_demoderm = 1;
1801
1802 return DrvInit(1);
1803 }
1804
1805 struct BurnDriver BurnDrvDemoderm = {
1806 "demoderm", "demoderb", NULL, NULL, "1984",
1807 "Demolition Derby (MCR-3 Mono Board Version)\0", NULL, "Bally Midway", "MCR3",
1808 NULL, NULL, NULL, NULL,
1809 BDF_GAME_WORKING | BDF_CLONE, 4, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
1810 NULL, demodermRomInfo, demodermRomName, NULL, NULL, NULL, NULL, DemodermInputInfo, DemodermDIPInfo,
1811 DemodermInit, DrvExit, TcsFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
1812 512, 480, 4, 3
1813 };
1814
1815
1816 // Sarge
1817
1818 static struct BurnRomInfo sargeRomDesc[] = {
1819 { "cpu_3b.bin", 0x8000, 0xda31a58f, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
1820 { "cpu_5b.bin", 0x8000, 0x6800e746, 1 | BRF_PRG | BRF_ESS }, // 1
1821
1822 { "tcs_u5.bin", 0x2000, 0xa894ef8a, 3 | BRF_PRG | BRF_ESS }, // 2 M6809 Code
1823 { "tcs_u4.bin", 0x2000, 0x6ca6faf3, 3 | BRF_PRG | BRF_ESS }, // 3
1824
1825 { "til_15a.bin", 0x2000, 0x685001b8, 1 | BRF_GRA }, // 4 Background Tiles
1826 { "til_14b.bin", 0x2000, 0x8449eb45, 1 | BRF_GRA }, // 5
1827
1828 { "spr_8e.bin", 0x8000, 0x93fac29d, 2 | BRF_GRA }, // 6 Sprites
1829 { "spr_6e.bin", 0x8000, 0x7cc6fb28, 2 | BRF_GRA }, // 7
1830 { "spr_5e.bin", 0x8000, 0xc832375c, 2 | BRF_GRA }, // 8
1831 { "spr_4e.bin", 0x8000, 0xc382267d, 2 | BRF_GRA }, // 9
1832
1833 { "a59a26axlcxhd.13j.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 10 PALs
1834 { "a59a26axlbxhd.2j.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 11
1835 { "a59a26axlaxhd.3j.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 12
1836 { "0066-314bx-xxqx.6h.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 13
1837 { "0066-316bx-xxqx.5h.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 14
1838 { "0066-315bx-xxqx.5g.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 15
1839 { "0066-313bx-xxqx.4g.bin", 0x0001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 16
1840 };
1841
1842 STD_ROM_PICK(sarge)
STD_ROM_FN(sarge)1843 STD_ROM_FN(sarge)
1844
1845 static INT32 SargeInit()
1846 {
1847 port_write_handler = demoderm_write_callback;
1848
1849 return DrvInit(1);
1850 }
1851
1852 struct BurnDriver BurnDrvSarge = {
1853 "sarge", NULL, NULL, NULL, "1985",
1854 "Sarge\0", NULL, "Bally Midway", "MCR3",
1855 NULL, NULL, NULL, NULL,
1856 BDF_GAME_WORKING, 4, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
1857 NULL, sargeRomInfo, sargeRomName, NULL, NULL, NULL, NULL, SargeInputInfo, SargeDIPInfo,
1858 SargeInit, DrvExit, TcsFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
1859 512, 480, 4, 3
1860 };
1861
1862
1863 // Max RPM (ver 2)
1864
1865 static struct BurnRomInfo maxrpmRomDesc[] = {
1866 { "pro.0", 0x8000, 0x3f9ec35f, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
1867 { "pro.1", 0x8000, 0xf628bb30, 1 | BRF_PRG | BRF_ESS }, // 1
1868
1869 { "turbskwk.u5", 0x4000, 0x55c3b759, 3 | BRF_PRG | BRF_ESS }, // 2 M6809 Code
1870 { "turbskwk.u4", 0x4000, 0x31a2da2e, 3 | BRF_PRG | BRF_ESS }, // 3
1871
1872 { "bg-0", 0x4000, 0xe3fb693a, 1 | BRF_GRA }, // 4 Background Tiles
1873 { "bg-1", 0x4000, 0x50d1db6c, 1 | BRF_GRA }, // 5
1874
1875 { "fg-0", 0x8000, 0x1d1435c1, 2 | BRF_GRA }, // 6 Sprites
1876 { "fg-1", 0x8000, 0xe54b7f2a, 2 | BRF_GRA }, // 7
1877 { "fg-2", 0x8000, 0x38be8505, 2 | BRF_GRA }, // 8
1878 { "fg-3", 0x8000, 0x9ae3eb52, 2 | BRF_GRA }, // 9
1879 };
1880
1881 STD_ROM_PICK(maxrpm)
STD_ROM_FN(maxrpm)1882 STD_ROM_FN(maxrpm)
1883
1884
1885 static UINT8 maxrpm_ipt2_read()
1886 {
1887 const UINT8 shift_bits[5] = { 0x00, 0x05, 0x06, 0x01, 0x02 };
1888 UINT8 start = DrvInputs[0];
1889 UINT8 shift = DrvInputs4f;
1890
1891 if (~start & 0x08) maxrpm_p1_shift = 0;
1892 if (~start & 0x04) maxrpm_p2_shift = 0;
1893
1894 if (~shift & 0x01 && maxrpm_last_shift & 0x01) {
1895 if (maxrpm_p1_shift < 4) maxrpm_p1_shift++;
1896 }
1897 if (~shift & 0x02 && maxrpm_last_shift & 0x02) {
1898 if (maxrpm_p1_shift > 0) maxrpm_p1_shift--;
1899 }
1900 if (~shift & 0x04 && maxrpm_last_shift & 0x04) {
1901 if (maxrpm_p2_shift < 4) maxrpm_p2_shift++;
1902 }
1903 if (~shift & 0x08 && maxrpm_last_shift & 0x08) {
1904 if (maxrpm_p2_shift > 0) maxrpm_p2_shift--;
1905 }
1906
1907 maxrpm_last_shift = shift;
1908
1909 return ~((shift_bits[maxrpm_p1_shift] << 4) + shift_bits[maxrpm_p2_shift]);
1910 }
1911
maxrpm_read_callback(UINT8 address)1912 static INT32 maxrpm_read_callback(UINT8 address)
1913 {
1914 switch (address)
1915 {
1916 case 1:
1917 return latched_input;
1918
1919 case 2:
1920 return maxrpm_ipt2_read();
1921 }
1922
1923 return -1;
1924 }
1925
maxrpm_write_callback(UINT8 address,UINT8 data)1926 static INT32 maxrpm_write_callback(UINT8 address, UINT8 data)
1927 {
1928 switch (address)
1929 {
1930 case 0x05:
1931 {
1932 maxrpm_adc_control = data & 0x0f;
1933 }
1934 return -1; // fall through
1935
1936 case 0x06:
1937 {
1938 INT16 analogs[4] = { DrvAnalogPort3, DrvAnalogPort1, DrvAnalogPort2, DrvAnalogPort0 };
1939
1940 if (~data & 0x80) {
1941 if (maxrpm_adc_select < 2) { // p2 gas, p1 gas
1942 latched_input = ProcessAnalog(analogs[maxrpm_adc_select], 1, INPUT_DEADZONE | INPUT_LINEAR | INPUT_MIGHTBEDIGITAL, 0x30, 0xff);
1943 if (latched_input < 0x34) latched_input = 0x30; // some inputs don't go all the way
1944 //bprintf(0, _T("inp %x: latched input: %x (%d dec.)\n"), maxrpm_adc_select, latched_input, latched_input);
1945 } else { // p2 wheel, p1 wheel
1946 latched_input = ProcessAnalog(analogs[maxrpm_adc_select], (maxrpm_adc_select == 2) ? 0 : 1, INPUT_DEADZONE, 0x40, 0xb4);
1947 }
1948 }
1949
1950 if (~data & 0x40 && ~data & 0x20) {
1951 maxrpm_adc_select = (maxrpm_adc_control >> 1) & 0x03;
1952 }
1953
1954 // do sound
1955 INT32 cycles = ((ZetTotalCycles() * 2) / 5) - M6809TotalCycles();
1956 if (cycles > 0) M6809Run(cycles);
1957 tcs_data_write(data);
1958 }
1959 return 0;
1960 }
1961
1962 return -1;
1963 }
1964
MaxrpmInit()1965 static INT32 MaxrpmInit()
1966 {
1967 dip_service = 0x80;
1968 is_maxrpm = 1;
1969 port_write_handler = maxrpm_write_callback;
1970 port_read_handler = maxrpm_read_callback;
1971
1972 return DrvInit(1);
1973 }
1974
1975 struct BurnDriver BurnDrvMaxrpm = {
1976 "maxrpm", NULL, NULL, NULL, "1986",
1977 "Max RPM (ver 2)\0", NULL, "Bally Midway", "MCR3",
1978 NULL, NULL, NULL, NULL,
1979 BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_RACING, 0,
1980 NULL, maxrpmRomInfo, maxrpmRomName, NULL, NULL, NULL, NULL, MaxrpmInputInfo, MaxrpmDIPInfo,
1981 MaxrpmInit, DrvExit, TcsFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
1982 512, 480, 4, 3
1983 };
1984
1985
1986 // Rampage (Rev 3, 8/27/86)
1987
1988 static struct BurnRomInfo rampageRomDesc[] = {
1989 { "pro-0_3b_rev_3_8-27-86.3b", 0x08000, 0x2f7ca03c, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
1990 { "pro-1_5b_rev_3_8-27-86.5b", 0x08000, 0xd89bd9a4, 1 | BRF_PRG | BRF_ESS }, // 1
1991
1992 { "u-7_rev.2_8-14-86.u7", 0x08000, 0xcffd7fa5, 4 | BRF_PRG | BRF_ESS }, // 2 68K Code
1993 { "u-17_rev.2_8-14-86.u17", 0x08000, 0xe92c596b, 4 | BRF_PRG | BRF_ESS }, // 3
1994 { "u-8_rev.2_8-14-86.u8", 0x08000, 0x11f787e4, 4 | BRF_PRG | BRF_ESS }, // 4
1995 { "u-18_rev.2_8-14-86.u18", 0x08000, 0x6b8bf5e1, 4 | BRF_PRG | BRF_ESS }, // 5
1996
1997 { "bg-0_u15_7-23-86.15a", 0x04000, 0xc0d8b7a5, 1 | BRF_GRA }, // 6 Background Tiles
1998 { "bg-1_u14_7-23-86.14b", 0x04000, 0x2f6e3aa1, 1 | BRF_GRA }, // 7
1999
2000 { "fg-0_8e_6-30-86.8e", 0x10000, 0x0974be5d, 2 | BRF_GRA }, // 8 Sprites
2001 { "fg-1_6e_6-30-86.6e", 0x10000, 0x8728532b, 2 | BRF_GRA }, // 9
2002 { "fg-2_5e_6-30-86.5e", 0x10000, 0x9489f714, 2 | BRF_GRA }, // 10
2003 { "fg-3_4e_6-30-86.4e", 0x10000, 0x81e1de40, 2 | BRF_GRA }, // 11
2004
2005 { "e36a31axnaxqd.u15.bin", 0x00001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 12 Sounds Good PAL
2006 };
2007
2008 STD_ROM_PICK(rampage)
STD_ROM_FN(rampage)2009 STD_ROM_FN(rampage)
2010
2011 static INT32 rampage_write_callback(UINT8 address, UINT8 data)
2012 {
2013 switch (address)
2014 {
2015 case 0x06:
2016 {
2017 INT32 cycles = ((ZetTotalCycles() * 8) / 5) - SekTotalCycles();
2018 if (cycles > 0) SekRun(cycles);
2019 soundsgood_reset_write((~data & 0x20) >> 5);
2020 soundsgood_data_write(data);
2021 }
2022 return 0;
2023 }
2024
2025 return -1;
2026 }
2027
RampageInit()2028 static INT32 RampageInit()
2029 {
2030 sound_status_bit = 7;
2031 sound_input_bank = 4;
2032 port_write_handler = rampage_write_callback;
2033
2034 soundsgood_rampage = 1; // for sound-cleanup in soundsgood
2035
2036 return DrvInit(0);
2037 }
2038
2039 struct BurnDriver BurnDrvRampage = {
2040 "rampage", NULL, NULL, NULL, "1986",
2041 "Rampage (Rev 3, 8/27/86)\0", NULL, "Bally Midway", "MCR3",
2042 NULL, NULL, NULL, NULL,
2043 BDF_GAME_WORKING, 3, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
2044 NULL, rampageRomInfo, rampageRomName, NULL, NULL, NULL, NULL, RampageInputInfo, RampageDIPInfo,
2045 RampageInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
2046 512, 480, 4, 3
2047 };
2048
2049
2050 // Rampage (Rev 2, 8/4/86)
2051
2052 static struct BurnRomInfo rampage2RomDesc[] = {
2053 { "pro-0_3b_rev_2_8-4-86.3b", 0x08000, 0x3f1d0293, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
2054 { "pro-1_5b_rev_2_8-4-86.5b", 0x08000, 0x58523d75, 1 | BRF_PRG | BRF_ESS }, // 1
2055
2056 { "u-7_rev.2_8-14-86.u7", 0x08000, 0xcffd7fa5, 4 | BRF_PRG | BRF_ESS }, // 2 68K Code
2057 { "u-17_rev.2_8-14-86.u17", 0x08000, 0xe92c596b, 4 | BRF_PRG | BRF_ESS }, // 3
2058 { "u-8_rev.2_8-14-86.u8", 0x08000, 0x11f787e4, 4 | BRF_PRG | BRF_ESS }, // 4
2059 { "u-18_rev.2_8-14-86.u18", 0x08000, 0x6b8bf5e1, 4 | BRF_PRG | BRF_ESS }, // 5
2060
2061 { "bg-0_u15_7-23-86.15a", 0x04000, 0xc0d8b7a5, 1 | BRF_GRA }, // 6 Background Tiles
2062 { "bg-1_u14_7-23-86.14b", 0x04000, 0x2f6e3aa1, 1 | BRF_GRA }, // 7
2063
2064 { "fg-0_8e_6-30-86.8e", 0x10000, 0x0974be5d, 2 | BRF_GRA }, // 8 Sprites
2065 { "fg-1_6e_6-30-86.6e", 0x10000, 0x8728532b, 2 | BRF_GRA }, // 9
2066 { "fg-2_5e_6-30-86.5e", 0x10000, 0x9489f714, 2 | BRF_GRA }, // 10
2067 { "fg-3_4e_6-30-86.4e", 0x10000, 0x81e1de40, 2 | BRF_GRA }, // 11
2068
2069 { "e36a31axnaxqd.u15.bin", 0x00001, 0x00000000, 5 | BRF_NODUMP | BRF_OPT }, // 12 Sounds Good PAL
2070 };
2071
2072 STD_ROM_PICK(rampage2)
2073 STD_ROM_FN(rampage2)
2074
2075 struct BurnDriver BurnDrvRampage2 = {
2076 "rampage2", "rampage", NULL, NULL, "1986",
2077 "Rampage (Rev 2, 8/4/86)\0", NULL, "Bally Midway", "MCR3",
2078 NULL, NULL, NULL, NULL,
2079 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
2080 NULL, rampage2RomInfo, rampage2RomName, NULL, NULL, NULL, NULL, RampageInputInfo, RampageDIPInfo,
2081 RampageInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
2082 512, 480, 4, 3
2083 };
2084
2085
2086 // Power Drive
2087
2088 static struct BurnRomInfo powerdrvRomDesc[] = {
2089 { "pdrv3b.bin", 0x08000, 0xd870b704, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
2090 { "pdrv5b.bin", 0x08000, 0xfa0544ad, 1 | BRF_PRG | BRF_ESS }, // 1
2091
2092 { "power_drive_snd_u7.u7", 0x08000, 0x78713e78, 4 | BRF_PRG | BRF_ESS }, // 2 68K Code
2093 { "power_drive_snd_u17.u17", 0x08000, 0xc41de6e4, 4 | BRF_PRG | BRF_ESS }, // 3
2094 { "power_drive_snd_u8.u8", 0x08000, 0x15714036, 4 | BRF_PRG | BRF_ESS }, // 4
2095 { "power_drive_snd_u18.u18", 0x08000, 0xcae14c70, 4 | BRF_PRG | BRF_ESS }, // 5
2096
2097 { "pdrv15a.bin", 0x04000, 0xb858b5a8, 1 | BRF_GRA }, // 6 Background Tiles
2098 { "pdrv14b.bin", 0x04000, 0x12ee7fc2, 1 | BRF_GRA }, // 7
2099
2100 { "pdrv8e.bin", 0x10000, 0xdd3a2adc, 2 | BRF_GRA }, // 8 Sprites
2101 { "pdrv6e.bin", 0x10000, 0x1a1f7f81, 2 | BRF_GRA }, // 9
2102 { "pdrv5e.bin", 0x10000, 0x4cb4780e, 2 | BRF_GRA }, // 10
2103 { "pdrv4e.bin", 0x10000, 0xde400335, 2 | BRF_GRA }, // 11
2104 };
2105
2106 STD_ROM_PICK(powerdrv)
STD_ROM_FN(powerdrv)2107 STD_ROM_FN(powerdrv)
2108
2109 static INT32 PowerdrvInit()
2110 {
2111 is_powerdrv = 1;
2112 sound_status_bit = 7;
2113 sound_input_bank = 2;
2114 port_write_handler = rampage_write_callback;
2115
2116 return DrvInit(0);
2117 }
2118
2119 struct BurnDriver BurnDrvPowerdrv = {
2120 "powerdrv", NULL, NULL, NULL, "1986",
2121 "Power Drive\0", NULL, "Bally Midway", "MCR3",
2122 NULL, NULL, NULL, NULL,
2123 BDF_GAME_WORKING, 3, HARDWARE_MISC_PRE90S, GBF_RACING, 0,
2124 NULL, powerdrvRomInfo, powerdrvRomName, NULL, NULL, NULL, NULL, PowerdrvInputInfo, PowerdrvDIPInfo,
2125 PowerdrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
2126 512, 480, 4, 3
2127 };
2128
2129
2130 // Star Guards
2131
2132 static struct BurnRomInfo stargrdsRomDesc[] = {
2133 { "pro-0.3b", 0x08000, 0x3ad94aa2, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
2134 { "pro-1.5b", 0x08000, 0xdba428b0, 1 | BRF_PRG | BRF_ESS }, // 1
2135
2136 { "snd0.u7", 0x08000, 0x7755a493, 4 | BRF_PRG | BRF_ESS }, // 2 68K Code
2137 { "snd1.u17", 0x08000, 0xd98d14ae, 4 | BRF_PRG | BRF_ESS }, // 3
2138
2139 { "bg-0.15a", 0x08000, 0xecfaef3e, 1 | BRF_GRA }, // 4 Background Tiles
2140 { "bg-1.14b", 0x08000, 0x2c75569d, 1 | BRF_GRA }, // 5
2141
2142 { "fg-0.8e", 0x10000, 0x22797aaa, 2 | BRF_GRA }, // 6 Sprites
2143 { "fg-1.6e", 0x10000, 0x413fa119, 2 | BRF_GRA }, // 7
2144 { "fg-2.5e", 0x10000, 0x7036cfe6, 2 | BRF_GRA }, // 8
2145 { "fg-3.4e", 0x10000, 0xcc5cc003, 2 | BRF_GRA }, // 9
2146 };
2147
2148 STD_ROM_PICK(stargrds)
STD_ROM_FN(stargrds)2149 STD_ROM_FN(stargrds)
2150
2151 static INT32 stargrds_write_callback(UINT8 address, UINT8 data)
2152 {
2153 switch (address)
2154 {
2155 case 0x05:
2156 // coin counter = data & 0x01;
2157 input_mux = (data & 0x02) >> 1;
2158 // leds 0x1c
2159 flipscreen = (data & 0x40) >> 6;
2160 return 0;
2161
2162 case 0x06:
2163 {
2164 INT32 cycles = ((ZetTotalCycles() * 8) / 5) - SekTotalCycles();
2165 if (cycles > 0) SekRun(cycles);
2166 soundsgood_reset_write((~data & 0x40) >> 6);
2167 soundsgood_data_write((data << 1) | (data >> 7));
2168 }
2169 return 0;
2170 }
2171
2172 return -1;
2173 }
2174
stargrds_read_callback(UINT8 address)2175 static INT32 stargrds_read_callback(UINT8 address)
2176 {
2177 switch (address)
2178 {
2179 case 0x00:
2180 {
2181 UINT8 ret = soundsgood_input_read(0) & 0xff;
2182 if (input_mux) ret = (ret & 0xf5) | (soundsgood_input_read(5) & 0x0a);
2183 return ret;
2184 }
2185 }
2186
2187 return -1;
2188 }
2189
StargrdsInit()2190 static INT32 StargrdsInit()
2191 {
2192 dip_service = 0x80;
2193
2194 sound_status_bit = 4;
2195 sound_input_bank = 0;
2196 port_write_handler = stargrds_write_callback;
2197 port_read_handler = stargrds_read_callback;
2198
2199 return DrvInit(0);
2200 }
2201
2202 struct BurnDriver BurnDrvStargrds = {
2203 "stargrds", NULL, NULL, NULL, "1987",
2204 "Star Guards\0", NULL, "Bally Midway", "MCR3",
2205 NULL, NULL, NULL, NULL,
2206 BDF_GAME_WORKING, 4, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
2207 NULL, stargrdsRomInfo, stargrdsRomName, NULL, NULL, NULL, NULL, StargrdsInputInfo, StargrdsDIPInfo,
2208 StargrdsInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40,
2209 512, 480, 4, 3
2210 };
2211
2212
2213
2214 // Spy Hunter
2215
2216 static struct BurnRomInfo spyhuntRomDesc[] = {
2217 { "spy-hunter_cpu_pg0_2-9-84.6d", 0x2000, 0x1721b88f, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
2218 { "spy-hunter_cpu_pg1_2-9-84.7d", 0x2000, 0x909d044f, 1 | BRF_PRG | BRF_ESS }, // 1
2219 { "spy-hunter_cpu_pg2_2-9-84.8d", 0x2000, 0xafeeb8bd, 1 | BRF_PRG | BRF_ESS }, // 2
2220 { "spy-hunter_cpu_pg3_2-9-84.9d", 0x2000, 0x5e744381, 1 | BRF_PRG | BRF_ESS }, // 3
2221 { "spy-hunter_cpu_pg4_2-9-84.10d", 0x2000, 0xa3033c15, 1 | BRF_PRG | BRF_ESS }, // 4
2222 { "spy-hunter_cpu_pg5_2-9-84.11d", 0x4000, 0x88aa1e99, 1 | BRF_PRG | BRF_ESS }, // 5
2223
2224 { "spy-hunter_snd_0_sd_11-18-83.a7", 0x1000, 0xc95cf31e, 2 | BRF_PRG | BRF_ESS }, // 6 Z80 #1 Code (SSIO)
2225 { "spy-hunter_snd_1_sd_11-18-83.a8", 0x1000, 0x12aaa48e, 2 | BRF_PRG | BRF_ESS }, // 7
2226
2227 { "spy-hunter_cs_deluxe_u7_a_11-18-83.u7", 0x2000, 0x6e689fe7, 4 | BRF_PRG | BRF_ESS }, // 8 68K Code
2228 { "spy-hunter_cs_deluxe_u17_b_11-18-83.u17", 0x2000, 0x0d9ddce6, 4 | BRF_PRG | BRF_ESS }, // 9
2229 { "spy-hunter_cs_deluxe_u8_c_11-18-83.u8", 0x2000, 0x35563cd0, 4 | BRF_PRG | BRF_ESS }, // 10
2230 { "spy-hunter_cs_deluxe_u18_d_11-18-83.u18", 0x2000, 0x63d3f5b1, 4 | BRF_PRG | BRF_ESS }, // 11
2231
2232 { "spy-hunter_cpu_bg0_11-18-83.3a", 0x2000, 0xdea34fed, 1 | BRF_GRA }, // 12 Background Tiles
2233 { "spy-hunter_cpu_bg1_11-18-83.4a", 0x2000, 0x8f64525f, 1 | BRF_GRA }, // 13
2234 { "spy-hunter_cpu_bg2_11-18-83.5a", 0x2000, 0xba0fd626, 1 | BRF_GRA }, // 14
2235 { "spy-hunter_cpu_bg3_11-18-83.6a", 0x2000, 0x7b482d61, 1 | BRF_GRA }, // 15
2236
2237 { "spy-hunter_video_1fg_11-18-83.a7", 0x4000, 0x9fe286ec, 2 | BRF_GRA }, // 16 Sprites
2238 { "spy-hunter_video_0fg_11-18-83.a8", 0x4000, 0x292c5466, 2 | BRF_GRA }, // 17
2239 { "spy-hunter_video_3fg_11-18-83.a5", 0x4000, 0xb894934d, 2 | BRF_GRA }, // 18
2240 { "spy-hunter_video_2fg_11-18-83.a6", 0x4000, 0x62c8bfa5, 2 | BRF_GRA }, // 19
2241 { "spy-hunter_video_5fg_11-18-83.a3", 0x4000, 0x2d9fbcec, 2 | BRF_GRA }, // 20
2242 { "spy-hunter_video_4fg_11-18-83.a4", 0x4000, 0x7ca4941b, 2 | BRF_GRA }, // 21
2243 { "spy-hunter_video_7fg_11-18-83.a1", 0x4000, 0x940fe17e, 2 | BRF_GRA }, // 22
2244 { "spy-hunter_video_6fg_11-18-83.a2", 0x4000, 0x8cb8a066, 2 | BRF_GRA }, // 23
2245
2246 { "spy-hunter_cpu_alpha-n_11-18-83", 0x1000, 0x936dc87f, 3 | BRF_GRA }, // 24 Characters
2247 };
2248
STDROMPICKEXT(spyhunt,spyhunt,Ssioprom)2249 STDROMPICKEXT(spyhunt, spyhunt, Ssioprom)
2250 STD_ROM_FN(spyhunt)
2251
2252 static UINT8 spyhunt_ip1_read(UINT8)
2253 {
2254 return (DrvInputs[1] & ~0x60) | (csd_status_read() << 5);
2255 }
2256
spyhunt_ip2_read(UINT8)2257 static UINT8 spyhunt_ip2_read(UINT8)
2258 {
2259 UINT8 temp = 0;
2260
2261 switch (input_mux) {
2262 case 1: {
2263 temp = ProcessAnalog(DrvAnalogPort0, 0, INPUT_DEADZONE, 0x34, 0xb4);
2264 break;
2265 }
2266 case 0: {
2267 temp = ProcessAnalog(DrvAnalogPort1, 0, INPUT_LINEAR | INPUT_MIGHTBEDIGITAL | INPUT_DEADZONE, 0x30, 0xff);
2268 break;
2269 }
2270 }
2271 return temp;
2272 }
2273
spyhunt_op4_write(UINT8,UINT8 data)2274 static void spyhunt_op4_write(UINT8 , UINT8 data)
2275 {
2276 if (last_op4 & 0x20 && ~data & 0x20) {
2277 if (data&8) lamp |= 1<<(data&7);
2278 if (~data&8) lamp &= ~(1<<(data&7));
2279 }
2280 last_op4 = data;
2281
2282 input_mux = data >> 7;
2283
2284 csd_data_write(data);
2285 }
2286
spyhunt_rom_swap()2287 static void spyhunt_rom_swap()
2288 {
2289 for (INT32 i = 0; i < 0x2000; i++) { // swap halves of last program rom
2290 INT32 t = DrvZ80ROM0[0xa000 + i];
2291 DrvZ80ROM0[0xa000 + i] = DrvZ80ROM0[0xc000 + i];
2292 DrvZ80ROM0[0xc000 + i] = t;
2293 }
2294 }
2295
SpyhuntInit()2296 static INT32 SpyhuntInit()
2297 {
2298 dip_service = 0x80;
2299
2300 sprite_color_mask = 0;
2301 has_shift = 1; // must be before init!
2302 is_spyhunt = 1;
2303 INT32 nRet = SpyhuntCommonInit(2);
2304
2305 if (nRet == 0)
2306 {
2307 ssio_set_custom_input(1, 0x60, spyhunt_ip1_read);
2308 ssio_set_custom_input(2, 0xff, spyhunt_ip2_read);
2309 ssio_set_custom_output(4, 0xff, spyhunt_op4_write);
2310
2311 spyhunt_rom_swap();
2312 }
2313
2314 return nRet;
2315 }
2316
2317 struct BurnDriver BurnDrvSpyhunt = {
2318 "spyhunt", NULL, "midssio", NULL, "1983",
2319 "Spy Hunter\0", NULL, "Bally Midway", "MCR3",
2320 NULL, NULL, NULL, NULL,
2321 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_ACTION | GBF_SHOOT, 0,
2322 NULL, spyhuntRomInfo, spyhuntRomName, NULL, NULL, NULL, NULL, SpyhuntInputInfo, SpyhuntDIPInfo,
2323 SpyhuntInit, DrvExit, CSDSSIOFrame, SpyhuntDraw, DrvScan, &DrvRecalc, 0x40,
2324 480, 480, 3, 4
2325 };
2326
2327
2328 // Spy Hunter (Playtronic license)
2329
2330 static struct BurnRomInfo spyhuntpRomDesc[] = {
2331 { "sh_mb_2.bin", 0x2000, 0xdf6cd642, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
2332 { "spy-hunter_cpu_pg1_2-9-84.7d", 0x2000, 0x909d044f, 1 | BRF_PRG | BRF_ESS }, // 1
2333 { "spy-hunter_cpu_pg2_2-9-84.8d", 0x2000, 0xafeeb8bd, 1 | BRF_PRG | BRF_ESS }, // 2
2334 { "spy-hunter_cpu_pg3_2-9-84.9d", 0x2000, 0x5e744381, 1 | BRF_PRG | BRF_ESS }, // 3
2335 { "sh_mb_6.bin", 0x2000, 0x8cbf04d8, 1 | BRF_PRG | BRF_ESS }, // 4
2336 { "spy-hunter_cpu_pg5_2-9-84.11d", 0x4000, 0x88aa1e99, 1 | BRF_PRG | BRF_ESS }, // 5
2337
2338 { "spy-hunter_snd_0_sd_11-18-83.a7", 0x1000, 0xc95cf31e, 2 | BRF_PRG | BRF_ESS }, // 6 Z80 #1 Code (SSIO)
2339 { "spy-hunter_snd_1_sd_11-18-83.a8", 0x1000, 0x12aaa48e, 2 | BRF_PRG | BRF_ESS }, // 7
2340
2341 { "spy-hunter_cs_deluxe_u7_a_11-18-83.u7", 0x2000, 0x6e689fe7, 4 | BRF_PRG | BRF_ESS }, // 8 68K Code
2342 { "spy-hunter_cs_deluxe_u17_b_11-18-83.u17", 0x2000, 0x0d9ddce6, 4 | BRF_PRG | BRF_ESS }, // 9
2343 { "spy-hunter_cs_deluxe_u8_c_11-18-83.u8", 0x2000, 0x35563cd0, 4 | BRF_PRG | BRF_ESS }, // 10
2344 { "spy-hunter_cs_deluxe_u18_d_11-18-83.u18", 0x2000, 0x63d3f5b1, 4 | BRF_PRG | BRF_ESS }, // 11
2345
2346 { "spy-hunter_cpu_bg0_11-18-83.3a", 0x2000, 0xdea34fed, 1 | BRF_GRA }, // 12 Background Tiles
2347 { "spy-hunter_cpu_bg1_11-18-83.4a", 0x2000, 0x8f64525f, 1 | BRF_GRA }, // 13
2348 { "spy-hunter_cpu_bg2_11-18-83.5a", 0x2000, 0xba0fd626, 1 | BRF_GRA }, // 14
2349 { "spy-hunter_cpu_bg3_11-18-83.6a", 0x2000, 0x7b482d61, 1 | BRF_GRA }, // 15
2350
2351 { "spy-hunter_video_1fg_11-18-83.a7", 0x4000, 0x9fe286ec, 2 | BRF_GRA }, // 16 Sprites
2352 { "spy-hunter_video_0fg_11-18-83.a8", 0x4000, 0x292c5466, 2 | BRF_GRA }, // 17
2353 { "spy-hunter_video_3fg_11-18-83.a5", 0x4000, 0xb894934d, 2 | BRF_GRA }, // 18
2354 { "spy-hunter_video_2fg_11-18-83.a6", 0x4000, 0x62c8bfa5, 2 | BRF_GRA }, // 19
2355 { "spy-hunter_video_5fg_11-18-83.a3", 0x4000, 0x2d9fbcec, 2 | BRF_GRA }, // 20
2356 { "spy-hunter_video_4fg_11-18-83.a4", 0x4000, 0x7ca4941b, 2 | BRF_GRA }, // 21
2357 { "spy-hunter_video_7fg_11-18-83.a1", 0x4000, 0x940fe17e, 2 | BRF_GRA }, // 22
2358 { "spy-hunter_video_6fg_11-18-83.a2", 0x4000, 0x8cb8a066, 2 | BRF_GRA }, // 23
2359
2360 { "sh_mb_1.bin", 0x0800, 0x5c74c9f0, 3 | BRF_GRA }, // 24 Characters
2361 };
2362
2363 STDROMPICKEXT(spyhuntp, spyhuntp, Ssioprom)
2364 STD_ROM_FN(spyhuntp)
2365
2366 struct BurnDriver BurnDrvSpyhuntp = {
2367 "spyhuntp", "spyhunt", "midssio", NULL, "1983",
2368 "Spy Hunter (Playtronic license)\0", NULL, "Bally Midway (Playtronic license)", "MCR3",
2369 NULL, NULL, NULL, NULL,
2370 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_ACTION | GBF_SHOOT, 0,
2371 NULL, spyhuntpRomInfo, spyhuntpRomName, NULL, NULL, NULL, NULL, SpyhuntInputInfo, SpyhuntDIPInfo,
2372 SpyhuntInit, DrvExit, CSDSSIOFrame, SpyhuntDraw, DrvScan, &DrvRecalc, 0x40,
2373 480, 480, 3, 4
2374 };
2375
2376
2377 // Crater Raider
2378
2379 static struct BurnRomInfo craterRomDesc[] = {
2380 { "crcpu.6d", 0x2000, 0xad31f127, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
2381 { "crcpu.7d", 0x2000, 0x3743c78f, 1 | BRF_PRG | BRF_ESS }, // 1
2382 { "crcpu.8d", 0x2000, 0xc95f9088, 1 | BRF_PRG | BRF_ESS }, // 2
2383 { "crcpu.9d", 0x2000, 0xa03c4b11, 1 | BRF_PRG | BRF_ESS }, // 3
2384 { "crcpu.10d", 0x2000, 0x44ae4cbd, 1 | BRF_PRG | BRF_ESS }, // 4
2385
2386 { "crsnd4.a7", 0x1000, 0xfd666cb5, 2 | BRF_PRG | BRF_ESS }, // 5 Z80 #1 Code (SSIO)
2387 { "crsnd1.a8", 0x1000, 0x90bf2c4c, 2 | BRF_PRG | BRF_ESS }, // 6
2388 { "crsnd2.a9", 0x1000, 0x3b8deef1, 2 | BRF_PRG | BRF_ESS }, // 7
2389 { "crsnd3.a10", 0x1000, 0x05803453, 2 | BRF_PRG | BRF_ESS }, // 8
2390
2391 { "crcpu.3a", 0x2000, 0x9d73504a, 1 | BRF_GRA }, // 9 Background Tiles
2392 { "crcpu.4a", 0x2000, 0x42a47dff, 1 | BRF_GRA }, // 10
2393 { "crcpu.5a", 0x2000, 0x2fe4a6e1, 1 | BRF_GRA }, // 11
2394 { "crcpu.6a", 0x2000, 0xd0659042, 1 | BRF_GRA }, // 12
2395
2396 { "crvid.a4", 0x4000, 0x579a8e36, 2 | BRF_GRA }, // 13 Sprites
2397 { "crvid.a3", 0x4000, 0x2c2f5b29, 2 | BRF_GRA }, // 14
2398 { "crvid.a6", 0x4000, 0x5bf954e0, 2 | BRF_GRA }, // 15
2399 { "crvid.a5", 0x4000, 0x9bdec312, 2 | BRF_GRA }, // 16
2400 { "crvid.a8", 0x4000, 0x4b913498, 2 | BRF_GRA }, // 17
2401 { "crvid.a7", 0x4000, 0x9fa307d5, 2 | BRF_GRA }, // 18
2402 { "crvid.a10", 0x4000, 0x7a22d6bc, 2 | BRF_GRA }, // 19
2403 { "crvid.a9", 0x4000, 0x811f152d, 2 | BRF_GRA }, // 20
2404
2405 { "crcpu.10g", 0x1000, 0x6fe53c8d, 3 | BRF_GRA }, // 21 Characters
2406 };
2407
STDROMPICKEXT(crater,crater,Ssioprom)2408 STDROMPICKEXT(crater, crater, Ssioprom)
2409 STD_ROM_FN(crater)
2410
2411 static UINT8 crater_ip1_read(UINT8)
2412 {
2413 return BurnTrackballRead(0, 0);
2414 }
2415
CraterInit()2416 static INT32 CraterInit()
2417 {
2418 dip_service = 0x80;
2419
2420 INT32 nRet = SpyhuntCommonInit(3);
2421
2422 if (nRet == 0)
2423 {
2424 flip_screen_x = TMAP_FLIPX;
2425 sprite_color_mask = 3;
2426 has_dial = 1;
2427
2428 ssio_set_custom_input(1, 0xff, crater_ip1_read);
2429 }
2430
2431 return nRet;
2432 }
2433
2434 struct BurnDriverD BurnDrvCrater = {
2435 "crater", NULL, "midssio", NULL, "1984",
2436 "Crater Raider\0", "Graphics Issues", "Bally Midway", "MCR3",
2437 NULL, NULL, NULL, NULL,
2438 BDF_GAME_NOT_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
2439 NULL, craterRomInfo, craterRomName, NULL, NULL, NULL, NULL, CraterInputInfo, CraterDIPInfo,
2440 CraterInit, DrvExit, CSDSSIOFrame, SpyhuntDraw, DrvScan, &DrvRecalc, 0x40,
2441 480, 480, 4, 3
2442 };
2443