1 // FB Alpha SunA 16-bit hardware driver module
2 // Based on MAME driver by Luca Elia
3
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "z80_intf.h"
7 #include "burn_ym2151.h"
8 #include "burn_ym3526.h"
9 #include "dac.h"
10 #include "ay8910.h"
11
12 static UINT8 *AllMem;
13 static UINT8 *MemEnd;
14 static UINT8 *AllRam;
15 static UINT8 *RamEnd;
16 static UINT8 *Drv68KROM;
17 static UINT8 *DrvZ80ROM0;
18 static UINT8 *DrvZ80ROM1;
19 static UINT8 *DrvZ80ROM2;
20 static UINT8 *DrvGfxROM0;
21 static UINT32 nGfxROM0Len;
22 static UINT8 *DrvGfxROM1;
23 static UINT8 *Drv68KRAM;
24 static UINT8 *DrvZ80RAM0;
25 static UINT8 *DrvSprRAM0;
26 static UINT8 *DrvSprRAM1;
27 static UINT8 *DrvPalRAM;
28 static UINT8 *DrvPalRAM2;
29 static UINT32 *Palette;
30 static UINT32 *DrvPalette;
31
32 static UINT8 DrvRecalc;
33
34 static UINT8 DrvJoy1[16];
35 static UINT8 DrvJoy2[16];
36 static UINT8 DrvJoy3[16];
37 static UINT8 DrvJoy4[16];
38 static UINT8 DrvJoy5[16];
39 static UINT8 DrvJoy6[16];
40
41 static UINT8 DrvDips[3];
42 static UINT8 DrvReset;
43
44 static UINT16 DrvInputs[6];
45
46 static INT32 game_select = 0;
47
48 static UINT8 soundlatch;
49 static UINT8 soundlatch2;
50 static UINT8 soundlatch3;
51 static UINT8 flipscreen;
52 static UINT8 color_bank;
53
54 static UINT8 bestofbest_prot = 0;
55
56 static UINT8 z80bankdata[2];
57
58 static struct BurnInputInfo BestbestInputList[] = {
59 {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 15, "p1 coin" },
60 {"Coin 2" , BIT_DIGITAL , DrvJoy2 + 15, "p2 coin" },
61
62 {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 14, "p1 start" },
63 {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 0, "p1 up" },
64 {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 1, "p1 down" },
65 {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 2, "p1 left" },
66 {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 3, "p1 right" },
67 {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"},
68 {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2"},
69 {"P1 Button 3" , BIT_DIGITAL , DrvJoy1 + 6, "p1 fire 3"},
70 {"P1 Button 4" , BIT_DIGITAL , DrvJoy1 + 9, "p1 fire 4"},
71 {"P1 Button 5" , BIT_DIGITAL , DrvJoy1 + 10, "p1 fire 5"},
72 {"P1 Button 6" , BIT_DIGITAL , DrvJoy1 + 11, "p1 fire 6"},
73
74 {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 14, "p2 start" },
75 {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 0, "p2 up" },
76 {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 1, "p2 down" },
77 {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 2, "p2 left" },
78 {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 3, "p2 right" },
79 {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"},
80 {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2"},
81 {"P2 Button 3" , BIT_DIGITAL , DrvJoy2 + 6, "p2 fire 3"},
82 {"P2 Button 4" , BIT_DIGITAL , DrvJoy2 + 9, "p2 fire 4"},
83 {"P2 Button 5" , BIT_DIGITAL , DrvJoy2 + 10, "p2 fire 5"},
84 {"P2 Button 6" , BIT_DIGITAL , DrvJoy2 + 11, "p2 fire 6"},
85
86 {"Service" , BIT_DIGITAL , DrvJoy3 + 6, "service" },
87
88 {"Reset", BIT_DIGITAL , &DrvReset, "reset" },
89 {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" },
90 {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" },
91 };
92
93 STDINPUTINFO(Bestbest)
94
95 static struct BurnInputInfo UballoonInputList[] = {
96 {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 15, "p1 coin" },
97 {"Coin 2" , BIT_DIGITAL , DrvJoy2 + 15, "p2 coin" },
98
99 {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 14, "p1 start" },
100 {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 0, "p1 up" },
101 {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 1, "p1 down" },
102 {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 2, "p1 left" },
103 {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 3, "p1 right" },
104 {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"},
105 {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2"},
106
107 {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 14, "p2 start" },
108 {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 0, "p2 up" },
109 {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 1, "p2 down" },
110 {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 2, "p2 left" },
111 {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 3, "p2 right" },
112 {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"},
113 {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2"},
114
115 {"Service" , BIT_DIGITAL , DrvJoy1 + 12, "service" },
116
117 {"Reset", BIT_DIGITAL , &DrvReset, "reset" },
118 {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" },
119 {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" },
120 {"Dip 3", BIT_DIPSWITCH, DrvDips + 2, "dip" },
121 };
122
123 STDINPUTINFO(Uballoon)
124
125 static struct BurnInputInfo BssoccerInputList[] = {
126 {"Coin 1" , BIT_DIGITAL , DrvJoy6 + 4, "p1 coin" },
127 {"Coin 2" , BIT_DIGITAL , DrvJoy6 + 5, "p2 coin" },
128 {"Coin 3" , BIT_DIGITAL , DrvJoy6 + 6, "p3 coin" },
129 {"Coin 4" , BIT_DIGITAL , DrvJoy6 + 7, "p4 coin" },
130
131 {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 7, "p1 start" },
132 {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 0, "p1 up" },
133 {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 1, "p1 down" },
134 {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 2, "p1 left" },
135 {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 3, "p1 right" },
136 {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"},
137 {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2"},
138 {"P1 Button 3" , BIT_DIGITAL , DrvJoy1 + 6, "p1 fire 3"},
139
140 {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 7, "p2 start" },
141 {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 0, "p2 up" },
142 {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 1, "p2 down" },
143 {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 2, "p2 left" },
144 {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 3, "p2 right" },
145 {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"},
146 {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2"},
147 {"P2 Button 3" , BIT_DIGITAL , DrvJoy2 + 6, "p2 fire 3"},
148
149 {"P3 Start" , BIT_DIGITAL , DrvJoy3 + 7, "p3 start" },
150 {"P3 Up" , BIT_DIGITAL , DrvJoy3 + 0, "p3 up" },
151 {"P3 Down" , BIT_DIGITAL , DrvJoy3 + 1, "p3 down" },
152 {"P3 Left" , BIT_DIGITAL , DrvJoy3 + 2, "p3 left" },
153 {"P3 Right" , BIT_DIGITAL , DrvJoy3 + 3, "p3 right" },
154 {"P3 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p3 fire 1"},
155 {"P3 Button 2" , BIT_DIGITAL , DrvJoy3 + 5, "p3 fire 2"},
156 {"P3 Button 3" , BIT_DIGITAL , DrvJoy3 + 6, "p3 fire 3"},
157
158 {"P4 Start" , BIT_DIGITAL , DrvJoy4 + 7, "p4 start" },
159 {"P4 Up" , BIT_DIGITAL , DrvJoy4 + 0, "p4 up" },
160 {"P4 Down" , BIT_DIGITAL , DrvJoy4 + 1, "p4 down" },
161 {"P4 Left" , BIT_DIGITAL , DrvJoy4 + 2, "p4 left" },
162 {"P4 Right" , BIT_DIGITAL , DrvJoy4 + 3, "p4 right" },
163 {"P4 Button 1" , BIT_DIGITAL , DrvJoy4 + 4, "p4 fire 1"},
164 {"P4 Button 2" , BIT_DIGITAL , DrvJoy4 + 5, "p4 fire 2"},
165 {"P4 Button 3" , BIT_DIGITAL , DrvJoy4 + 6, "p4 fire 3"},
166
167 {"Service" , BIT_DIGITAL , DrvJoy3 + 6, "service" },
168
169 {"Reset", BIT_DIGITAL , &DrvReset, "reset" },
170 {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" },
171 {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" },
172 {"Dip 3", BIT_DIPSWITCH, DrvDips + 2, "dip" },
173 };
174
175 STDINPUTINFO(Bssoccer)
176
177 static struct BurnInputInfo SunaqInputList[] = {
178 {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 7, "p1 coin" },
179 {"Coin 2" , BIT_DIGITAL , DrvJoy2 + 7, "p2 coin" },
180
181 {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 6, "p1 start" },
182 {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 0, "p1 fire 1"},
183 {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 1, "p1 fire 2"},
184 {"P1 Button 3" , BIT_DIGITAL , DrvJoy1 + 2, "p1 fire 3"},
185 {"P1 Button 4" , BIT_DIGITAL , DrvJoy1 + 3, "p1 fire 4"},
186
187 {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 6, "p2 start" },
188 {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 0, "p2 fire 1"},
189 {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 1, "p2 fire 2"},
190 {"P2 Button 3" , BIT_DIGITAL , DrvJoy2 + 2, "p2 fire 3"},
191 {"P2 Button 4" , BIT_DIGITAL , DrvJoy2 + 3, "p2 fire 4"},
192
193 {"Service" , BIT_DIGITAL , DrvJoy3 + 6, "service" },
194
195 {"Reset", BIT_DIGITAL , &DrvReset, "reset" },
196 {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" },
197 };
198
199 STDINPUTINFO(Sunaq)
200
201 static struct BurnDIPInfo bestbestDIPList[]=
202 {
203 {0x1a, 0xff, 0xff, 0xff, NULL },
204 {0x1b, 0xff, 0xff, 0xff, NULL },
205
206 {0x1a, 0xfe, 0, 8, "Coinage" },
207 {0x1a, 0x01, 0x07, 0x00, "5C 1C" },
208 {0x1a, 0x01, 0x07, 0x01, "4C 1C" },
209 {0x1a, 0x01, 0x07, 0x02, "3C 1C" },
210 {0x1a, 0x01, 0x07, 0x03, "2C 1C" },
211 {0x1a, 0x01, 0x07, 0x07, "1C 1C" },
212 {0x1a, 0x01, 0x07, 0x06, "1C 2C" },
213 {0x1a, 0x01, 0x07, 0x05, "1C 3C" },
214 {0x1a, 0x01, 0x07, 0x04, "1C 4C" },
215
216 {0x1a, 0xfe, 0, 4, "Difficulty" },
217 {0x1a, 0x01, 0x18, 0x18, "Easy" },
218 {0x1a, 0x01, 0x18, 0x10, "Normal" },
219 {0x1a, 0x01, 0x18, 0x08, "Hard" },
220 {0x1a, 0x01, 0x18, 0x00, "Hardest" },
221
222 {0x1a, 0xfe, 0, 2, "Display Combos" },
223 {0x1a, 0x01, 0x20, 0x00, "Off" },
224 {0x1a, 0x01, 0x20, 0x20, "On" },
225
226 {0x1a, 0xfe, 0, 2, "Demo Sounds" },
227 {0x1a, 0x01, 0x80, 0x80, "Off" },
228 {0x1a, 0x01, 0x80, 0x00, "On" },
229
230 {0x1b, 0xfe, 0, 2, "Flip Screen" },
231 {0x1b, 0x01, 0x01, 0x01, "Off" },
232 {0x1b, 0x01, 0x01, 0x00, "On" },
233
234 {0x1b, 0xfe, 0, 4, "Play Time" },
235 {0x1b, 0x01, 0x06, 0x06, "1:10" },
236 {0x1b, 0x01, 0x06, 0x04, "1:20" },
237 {0x1b, 0x01, 0x06, 0x02, "1:30" },
238 {0x1b, 0x01, 0x06, 0x00, "1:40" },
239 };
240
241 STDDIPINFO(bestbest)
242
243 static struct BurnDIPInfo bssoccerDIPList[]=
244 {
245 {0x26, 0xff, 0xff, 0xff, NULL },
246 {0x27, 0xff, 0xff, 0xff, NULL },
247 {0x28, 0xff, 0xff, 0xff, NULL },
248
249 {0x26, 0xfe, 0, 8, "Coinage" },
250 {0x26, 0x01, 0x07, 0x00, "4C 1C" },
251 {0x26, 0x01, 0x07, 0x01, "3C 1C" },
252 {0x26, 0x01, 0x07, 0x02, "2C 1C" },
253 {0x26, 0x01, 0x07, 0x07, "1C 1C" },
254 {0x26, 0x01, 0x07, 0x06, "1C 2C" },
255 {0x26, 0x01, 0x07, 0x05, "1C 3C" },
256 {0x26, 0x01, 0x07, 0x04, "1C 4C" },
257 {0x26, 0x01, 0x07, 0x03, "1C 5C" },
258
259 {0x26, 0xfe, 0, 4, "Difficulty" },
260 {0x26, 0x01, 0x18, 0x10, "Easy" },
261 {0x26, 0x01, 0x18, 0x18, "Normal" },
262 {0x26, 0x01, 0x18, 0x08, "Hard" },
263 {0x26, 0x01, 0x18, 0x00, "Hardest?" },
264
265 {0x26, 0xfe, 0, 2, "Demo Sounds" },
266 {0x26, 0x01, 0x20, 0x00, "Off" },
267 {0x26, 0x01, 0x20, 0x20, "On" },
268
269 {0x26, 0xfe, 0, 2, "Flip Screen" },
270 {0x26, 0x01, 0x40, 0x40, "Off" },
271 {0x26, 0x01, 0x40, 0x00, "On" },
272
273 {0x27, 0xfe, 0, 4, "Play Time P1" },
274 {0x27, 0x01, 0x03, 0x03, "1:30" },
275 {0x27, 0x01, 0x03, 0x02, "1:45" },
276 {0x27, 0x01, 0x03, 0x01, "2:00" },
277 {0x27, 0x01, 0x03, 0x00, "2:15" },
278
279 {0x27, 0xfe, 0, 4, "Play Time P2" },
280 {0x27, 0x01, 0x0c, 0x0c, "1:30" },
281 {0x27, 0x01, 0x0c, 0x08, "1:45" },
282 {0x27, 0x01, 0x0c, 0x04, "2:00" },
283 {0x27, 0x01, 0x0c, 0x00, "2:15" },
284
285 {0x27, 0xfe, 0, 4, "Play Time P3" },
286 {0x27, 0x01, 0x30, 0x30, "1:30" },
287 {0x27, 0x01, 0x30, 0x20, "1:45" },
288 {0x27, 0x01, 0x30, 0x10, "2:00" },
289 {0x27, 0x01, 0x30, 0x00, "2:15" },
290
291 {0x27, 0xfe, 0, 4, "Play Time P4" },
292 {0x27, 0x01, 0xc0, 0xc0, "1:30" },
293 {0x27, 0x01, 0xc0, 0x80, "1:45" },
294 {0x27, 0x01, 0xc0, 0x40, "2:00" },
295 {0x27, 0x01, 0xc0, 0x00, "2:15" },
296
297 {0x28, 0xfe, 0, 2, "Copyright" },
298 {0x28, 0x01, 0x01, 0x01, "Distributer Unico" },
299 {0x28, 0x01, 0x01, 0x00, "All Rights Reserved" },
300 };
301
302 STDDIPINFO(bssoccer)
303
304
305 static struct BurnDIPInfo sunaqDIPList[]=
306 {
307 {0x0e, 0xff, 0xff, 0xcf, NULL },
308
309 {0x0e, 0xfe, 0, 8, "Coinage" },
310 {0x0e, 0x01, 0x07, 0x00, "5C 1C" },
311 {0x0e, 0x01, 0x07, 0x01, "4C 1C" },
312 {0x0e, 0x01, 0x07, 0x02, "3C 1C" },
313 {0x0e, 0x01, 0x07, 0x03, "2C 1C" },
314 {0x0e, 0x01, 0x07, 0x07, "1C 1C" },
315 {0x0e, 0x01, 0x07, 0x06, "1C 2C" },
316 {0x0e, 0x01, 0x07, 0x05, "1C 3C" },
317 {0x0e, 0x01, 0x07, 0x04, "1C 4C" },
318
319 {0x0e, 0xfe, 0, 4, "Difficulty" },
320 {0x0e, 0x01, 0x18, 0x00, "Easy" },
321 {0x0e, 0x01, 0x18, 0x08, "Normal" },
322 {0x0e, 0x01, 0x18, 0x10, "Hard" },
323 {0x0e, 0x01, 0x18, 0x18, "Hardest" },
324
325 {0x0e, 0xfe, 0, 2, "Demo Sounds" },
326 {0x0e, 0x01, 0x20, 0x20, "Off" },
327 {0x0e, 0x01, 0x20, 0x00, "On" },
328
329 {0x0e, 0xfe, 0, 2, "Flip Screen" },
330 {0x0e, 0x01, 0x40, 0x40, "Off" },
331 {0x0e, 0x01, 0x40, 0x00, "On" },
332 };
333
334 STDDIPINFO(sunaq)
335
336
337 static struct BurnDIPInfo uballoonDIPList[]=
338 {
339 {0x12, 0xff, 0xff, 0xff, NULL },
340 {0x13, 0xff, 0xff, 0xff, NULL },
341 {0x14, 0xff, 0xff, 0xff, NULL },
342
343 {0x12, 0xfe, 0, 2, "Copyright" },
344 {0x12, 0x01, 0x30, 0x30, "Distributer Unico" },
345 {0x12, 0x01, 0x30, 0x20, "All Rights Reserved" },
346 // {0x12, 0x01, 0x30, 0x10, "Distributer Unico" },
347 // {0x12, 0x01, 0x30, 0x00, "All Rights Reserved" },
348
349 {0x13, 0xfe, 0, 8, "Coinage" },
350 {0x13, 0x01, 0x07, 0x00, "5C 1C" },
351 {0x13, 0x01, 0x07, 0x01, "4C 1C" },
352 {0x13, 0x01, 0x07, 0x02, "3C 1C" },
353 {0x13, 0x01, 0x07, 0x03, "2C 1C" },
354 {0x13, 0x01, 0x07, 0x07, "1C 1C" },
355 {0x13, 0x01, 0x07, 0x06, "1C 2C" },
356 {0x13, 0x01, 0x07, 0x05, "1C 3C" },
357 {0x13, 0x01, 0x07, 0x04, "1C 4C" },
358
359 {0x13, 0xfe, 0, 4, "Lives" },
360 {0x13, 0x01, 0x18, 0x10, "2" },
361 {0x13, 0x01, 0x18, 0x18, "3" },
362 {0x13, 0x01, 0x18, 0x08, "4" },
363 {0x13, 0x01, 0x18, 0x00, "5" },
364
365 {0x13, 0xfe, 0, 4, "Difficulty" },
366 {0x13, 0x01, 0x60, 0x40, "Easy" },
367 {0x13, 0x01, 0x60, 0x60, "Normal" },
368 {0x13, 0x01, 0x60, 0x20, "Hard" },
369 {0x13, 0x01, 0x60, 0x00, "Hardest" },
370
371 {0x14, 0xfe, 0, 2, "Flip Screen" },
372 {0x14, 0x01, 0x01, 0x01, "Off" },
373 {0x14, 0x01, 0x01, 0x00, "On" },
374
375 {0x14, 0xfe, 0, 2, "Cabinet" },
376 {0x14, 0x01, 0x02, 0x02, "Upright" },
377 {0x14, 0x01, 0x02, 0x00, "Cocktail" },
378
379 {0x14, 0xfe, 0, 8, "Bonus Life" },
380 {0x14, 0x01, 0x1c, 0x1c, "200K" },
381 {0x14, 0x01, 0x1c, 0x10, "300K, 1000K" },
382 {0x14, 0x01, 0x1c, 0x18, "400K" },
383 {0x14, 0x01, 0x1c, 0x0c, "500K, 1500K" },
384 {0x14, 0x01, 0x1c, 0x08, "500K, 2000K" },
385 {0x14, 0x01, 0x1c, 0x04, "500K, 3000K" },
386 {0x14, 0x01, 0x1c, 0x14, "600K" },
387 {0x14, 0x01, 0x1c, 0x00, "None" },
388
389 {0x14, 0xfe, 0, 2, "Demo Sounds" },
390 {0x14, 0x01, 0x80, 0x80, "Off" },
391 {0x14, 0x01, 0x80, 0x00, "On" },
392 };
393
STDDIPINFO(uballoon)394 STDDIPINFO(uballoon)
395
396
397 //-------------------------------------------------------------------------------------------------
398 // Generic functions
399
400 static void suna_palette_write(INT32 offset)
401 {
402 UINT8 r, b, g;
403 UINT16 data = BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM + offset)));
404
405 r = (data >> 0) & 0x1f;
406 r = (r << 3) | (r >> 2);
407
408 g = (data >> 5) & 0x1f;
409 g = (g << 3) | (g >> 2);
410
411 b = (data >> 10) & 0x1f;
412 b = (b << 3) | (b >> 2);
413
414 Palette[offset>>1] = (r << 16) | (g << 8) | b;
415 DrvPalette[offset>>1] = BurnHighCol(r, g, b, 0);
416
417 return;
418 }
419
420 //-------------------------------------------------------------------------------------------------
421 // Memory handlers
422
423
424 //----------------------------------------------------------------
425 // Best of Best
426
427
428 //------------------
429 // 68k
430
bestbest_read_word(UINT32 address)431 static UINT16 __fastcall bestbest_read_word(UINT32 address)
432 {
433 switch (address & ~1)
434 {
435 case 0x500000:
436 return DrvInputs[0];
437
438 case 0x500002:
439 return DrvInputs[1];
440
441 case 0x500004:
442 return DrvInputs[2];
443 }
444
445 return 0;
446 }
447
bestbest_read_byte(UINT32 address)448 static UINT8 __fastcall bestbest_read_byte(UINT32 address)
449 {
450 switch (address)
451 {
452 case 0x500000:
453 case 0x500001:
454 return DrvInputs[0] >> ((~address & 1) << 3);
455
456 case 0x500002:
457 case 0x500003:
458 return DrvInputs[1] >> ((~address & 1) << 3);
459
460 case 0x500004:
461 case 0x500005:
462 return DrvInputs[2] >> ((~address & 1) << 3);
463
464 case 0x500019:
465 return bestofbest_prot;
466 }
467
468 return 0;
469 }
470
bestbest_write_word(UINT32 address,UINT16 data)471 static void __fastcall bestbest_write_word(UINT32 address, UINT16 data)
472 {
473 if ((address & 0xfff000) == 0x540000) {
474 *((UINT16*)(DrvPalRAM + (address & 0x0fff))) = BURN_ENDIAN_SWAP_INT16(data);
475 suna_palette_write(address & 0xffe);
476 return;
477 }
478
479 switch (address & ~1)
480 {
481 case 0x500000:
482 soundlatch = data;
483 return;
484
485 case 0x500002:
486 flipscreen = data & 0x10;
487 return;
488 }
489
490 return;
491 }
492
bestbest_write_byte(UINT32 address,UINT8 data)493 static void __fastcall bestbest_write_byte(UINT32 address, UINT8 data)
494 {
495 if ((address & 0xfff000) == 0x540000) {
496 DrvPalRAM[address & 0xfff] = data;
497 suna_palette_write(address & 0xffe);
498 return;
499 }
500
501 switch (address)
502 {
503 case 0x500000:
504 case 0x500001:
505 soundlatch = data;
506 return;
507
508 case 0x500002:
509 case 0x500003:
510 flipscreen = data & 0x10;
511 return;
512
513 case 0x500008:
514 case 0x500009:
515 switch (data & 0xff) {
516 case 0x00: bestofbest_prot ^= 0x09; break;
517 case 0x08: bestofbest_prot ^= 0x02; break;
518 case 0x0c: bestofbest_prot ^= 0x03; break;
519 }
520 return;
521 }
522
523 return;
524 }
525
526 //------------------
527 // Z80 #0
528
bestbest_sound0_write(UINT16 address,UINT8 data)529 static void __fastcall bestbest_sound0_write(UINT16 address, UINT8 data)
530 {
531 switch (address)
532 {
533 case 0xc000:
534 case 0xc001:
535 BurnYM3526Write(address & 1, data);
536 return;
537
538 case 0xc002:
539 case 0xc003:
540 AY8910Write(0, address & 1, data);
541 return;
542
543 case 0xf000:
544 soundlatch2 = data;
545 return;
546 }
547
548 return;
549 }
550
bestbest_sound0_read(UINT16 address)551 static UINT8 __fastcall bestbest_sound0_read(UINT16 address)
552 {
553 switch (address)
554 {
555 case 0xf800:
556 return soundlatch;
557 }
558
559 return 0;
560 }
561
562 //------------------
563 // Z80 #1
564
bestbest_sound1_out(UINT16 port,UINT8 data)565 static void __fastcall bestbest_sound1_out(UINT16 port, UINT8 data)
566 {
567 switch (port & 0xff)
568 {
569 case 0x00: { DACSignedWrite(0, (data & 0xf) * 0x11); return; }
570 case 0x01: { DACSignedWrite(1, (data & 0xf) * 0x11); return; }
571
572 case 0x02: { DACSignedWrite(2, (data & 0xf) * 0x11); return; }
573 case 0x03: { DACSignedWrite(3, (data & 0xf) * 0x11); return; }
574 }
575
576 return;
577 }
578
bestbest_sound1_in(UINT16 port)579 static UINT8 __fastcall bestbest_sound1_in(UINT16 port)
580 {
581 switch (port & 0xff)
582 {
583 case 0x00:
584 return soundlatch2;
585 }
586
587 return 0;
588 }
589
590
591 //----------------------------------------------------------------
592 // SunA Quiz
593
594
595 //------------------
596 // 68k
597
sunaq_read_word(UINT32 address)598 static UINT16 __fastcall sunaq_read_word(UINT32 address)
599 {
600 if ((address & 0xfff000) == 0x540000) {
601 if (address & 0x200) {
602 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM2 + (address & 0xffe))));
603 } else {
604 address += color_bank << 9;
605 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM + (address & 0xffe))));
606 }
607 }
608
609 switch (address & ~1)
610 {
611 case 0x500000:
612 return DrvInputs[0];
613
614 case 0x500002:
615 return DrvInputs[1];
616
617 case 0x500004:
618 return DrvInputs[2];
619
620 case 0x500006:
621 return DrvInputs[3];
622 }
623
624 return 0;
625 }
626
sunaq_read_byte(UINT32 address)627 static UINT8 __fastcall sunaq_read_byte(UINT32 address)
628 {
629 if ((address & 0xfff000) == 0x540000) {
630 if (address & 0x200) {
631 return DrvPalRAM2[address & 0xffe];
632 } else {
633 address += color_bank << 9;
634 return DrvPalRAM[address & 0xffe];
635 }
636 }
637
638 switch (address)
639 {
640 case 0x500000:
641 case 0x500001:
642 return DrvInputs[0] >> ((~address & 1) << 3);
643
644 case 0x500002:
645 case 0x500003:
646 return DrvInputs[1] >> ((~address & 1) << 3);
647
648 case 0x500004:
649 case 0x500005:
650 return DrvInputs[2] >> ((~address & 1) << 3);
651
652 case 0x500006:
653 case 0x500007:
654 return DrvInputs[3] >> ((~address & 1) << 3);
655 }
656
657 return 0;
658 }
659
sunaq_write_word(UINT32 address,UINT16 data)660 static void __fastcall sunaq_write_word(UINT32 address, UINT16 data)
661 {
662 if ((address & 0xfff000) == 0x540000) {
663 if (address & 0x200) {
664 *((UINT16*)(DrvPalRAM2 + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
665 } else {
666 address += color_bank << 9;
667 *((UINT16*)(DrvPalRAM + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
668 suna_palette_write(address & 0xffff);
669 }
670 return;
671 }
672
673 switch (address & ~1)
674 {
675 case 0x500000:
676 soundlatch = data;
677 return;
678
679 case 0x500002:
680 flipscreen = data & 0x01;
681 color_bank = (data >> 2) & 1;
682 return;
683
684 case 0x500004:
685 // coin counter
686 return;
687 }
688 return;
689 }
690
sunaq_write_byte(UINT32 address,UINT8 data)691 static void __fastcall sunaq_write_byte(UINT32 address, UINT8 data)
692 {
693 if ((address & 0xfff000) == 0x540000) {
694 if (address & 0x200) {
695 DrvPalRAM2[address & 0xfff] = data;
696 } else {
697 address += color_bank << 9;
698 DrvPalRAM[address & 0xfff] = data;
699 suna_palette_write(address & 0xffe);
700 }
701
702 return;
703 }
704
705 switch (address)
706 {
707 case 0x500000:
708 case 0x500001:
709 soundlatch = data;
710 return;
711
712 case 0x500002:
713 case 0x500003:
714 flipscreen = data & 0x01;
715 color_bank = (data >> 2) & 1;
716 return;
717
718 case 0x500004:
719 case 0x500005:
720 // coin counter
721 return;
722 }
723 return;
724 }
725
726 //------------------
727 // Z80 #0
728
sunaq_sound0_write(UINT16 address,UINT8 data)729 static void __fastcall sunaq_sound0_write(UINT16 address, UINT8 data)
730 {
731 switch (address)
732 {
733 case 0xf800:
734 BurnYM2151SelectRegister(data);
735 return;
736
737 case 0xf801:
738 BurnYM2151WriteRegister(data);
739 return;
740
741 case 0xfc00:
742 soundlatch2 = data;
743 return;
744 }
745
746 return;
747 }
748
749
750 //----------------------------------------------------------------
751 // Ultra Balloon
752
753
754 //------------------
755 // 68k
756
uballoon_prot_read(UINT16 offset)757 static UINT8 uballoon_prot_read(UINT16 offset)
758 {
759 UINT8 ret = 0;
760
761 switch (offset)
762 {
763 case 0x0011:
764 ret = ((bestofbest_prot & 0x03) == 0x03) ? 2 : 0;
765 ret |= ((bestofbest_prot & 0x30) == 0x30) ? 1 : 0;
766 break;
767
768 case 0x0311:
769 ret = 0x03;
770 break;
771
772 default:
773 // bprintf (0, _T("uballoon_prot_read %04X\n"), offset);
774 break;
775 }
776
777 return ret;
778 }
779
uballoon_prot_write(UINT16 offset,UINT8 data)780 static void uballoon_prot_write(UINT16 offset, UINT8 data)
781 {
782 switch (offset)
783 {
784 case 0x0001:
785 bestofbest_prot = data;
786 break;
787
788 default:
789 // bprintf (0, _T("uballoon_prot_write %04X=%02X\n"), offset, data);
790 break;
791 }
792 }
793
uballoon_read_word(UINT32 address)794 static UINT16 __fastcall uballoon_read_word(UINT32 address)
795 {
796 if ((address & 0xfff000) == 0x200000) {
797 if (address & 0x200) {
798 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM2 + (address & 0xffe))));
799 } else {
800 address += color_bank << 9;
801 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM + (address & 0xffe))));
802 }
803 }
804
805 switch (address & ~1)
806 {
807 case 0x600000:
808 return DrvInputs[0];
809
810 case 0x600002:
811 return DrvInputs[1];
812
813 case 0x600004:
814 return DrvInputs[2];
815
816 case 0x600006:
817 return DrvInputs[3];
818 }
819
820 return 0;
821 }
822
uballoon_read_byte(UINT32 address)823 static UINT8 __fastcall uballoon_read_byte(UINT32 address)
824 {
825 if ((address & 0xff0000) == 0xa00000) {
826 return uballoon_prot_read(address);
827 }
828
829 if ((address & 0xfff000) == 0x200000) {
830 if (address & 0x200) {
831 return DrvPalRAM2[address & 0xffe];
832 } else {
833 address += color_bank << 9;
834 return DrvPalRAM[address & 0xffe];
835 }
836 }
837
838 switch (address)
839 {
840 case 0x600000:
841 case 0x600001:
842 return DrvInputs[0] >> ((~address & 1) << 3);
843
844 case 0x600002:
845 case 0x600003:
846 return DrvInputs[1] >> ((~address & 1) << 3);
847
848 case 0x600004:
849 case 0x600005:
850 return DrvInputs[2] >> ((~address & 1) << 3);
851
852 case 0x600006:
853 case 0x600007:
854 return DrvInputs[3] >> ((~address & 1) << 3);
855 }
856
857 return 0;
858 }
859
uballoon_write_word(UINT32 address,UINT16 data)860 static void __fastcall uballoon_write_word(UINT32 address, UINT16 data)
861 {
862 if ((address & 0xfff000) == 0x200000) {
863 if (address & 0x200) {
864 *((UINT16*)(DrvPalRAM2 + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
865 } else {
866 address += color_bank << 9;
867 *((UINT16*)(DrvPalRAM + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
868 suna_palette_write(address & 0xffff);
869 }
870 return;
871 }
872
873 switch (address & ~1)
874 {
875 case 0x600000:
876 soundlatch = data;
877 return;
878
879 case 0x600004:
880 flipscreen = data & 0x01;
881 color_bank = (data >> 2) & 1;
882 return;
883 }
884 return;
885 }
886
uballoon_write_byte(UINT32 address,UINT8 data)887 static void __fastcall uballoon_write_byte(UINT32 address, UINT8 data)
888 {
889 if ((address & 0xfff000) == 0x200000) {
890 if (address & 0x200) {
891 DrvPalRAM2[address & 0xfff] = data;
892 } else {
893 address += color_bank << 9;
894 DrvPalRAM[address & 0xfff] = data;
895 suna_palette_write(address & 0xffe);
896 }
897 return;
898 }
899
900 if ((address & 0xff0000) == 0xa00000) {
901 uballoon_prot_write(address, data);
902 return;
903 }
904
905 switch (address)
906 {
907 case 0x600000:
908 case 0x600001:
909 soundlatch = data;
910 return;
911
912 case 0x600004:
913 case 0x600005:
914 flipscreen = data & 0x01;
915 color_bank = (data >> 2) & 1;
916 return;
917 }
918 return;
919 }
920
921 //------------------
922 // Z80 #1
923
uballoon_bankswitch(INT32 data)924 static void uballoon_bankswitch(INT32 data)
925 {
926 z80bankdata[0] = data;
927
928 INT32 bank = ((data & 1) << 16) | 0x400;
929
930 ZetMapMemory(DrvZ80ROM1 + bank, 0x0400, 0xffff, MAP_ROM);
931 }
932
uballoon_sound1_out(UINT16 port,UINT8 data)933 static void __fastcall uballoon_sound1_out(UINT16 port, UINT8 data)
934 {
935 switch (port & 0xff)
936 {
937 case 0x00: { DACSignedWrite(0, (data & 0xf) * 0x11); return; }
938 case 0x01: { DACSignedWrite(1, (data & 0xf) * 0x11); return; }
939
940 case 0x03:
941 uballoon_bankswitch(data);
942 return;
943 }
944
945 return;
946 }
947
uballoon_sound1_in(UINT16 port)948 static UINT8 __fastcall uballoon_sound1_in(UINT16 port)
949 {
950 switch (port & 0xff)
951 {
952 case 0x00:
953 return soundlatch2;
954 }
955
956 return 0;
957 }
958
959
960 //----------------------------------------------------------------
961 // Back Street Soccer
962
963
964 //------------------
965 // 68k
966
bssoccer_read_word(UINT32 address)967 static UINT16 __fastcall bssoccer_read_word(UINT32 address)
968 {
969 if ((address & 0xfff000) == 0x400000) {
970 if (address & 0x200) {
971 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM2 + (address & 0xffe))));
972 } else {
973 address += color_bank << 9;
974 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM + (address & 0xffe))));
975 }
976 }
977
978 switch (address & ~1)
979 {
980 case 0xa00000:
981 return DrvInputs[0];
982
983 case 0xa00002:
984 return DrvInputs[1];
985
986 case 0xa00004:
987 return DrvInputs[2];
988
989 case 0xa00006:
990 return DrvInputs[3];
991
992 case 0xa00008:
993 return DrvInputs[4];
994
995 case 0xa0000a:
996 return DrvInputs[5];
997
998 }
999
1000 return 0;
1001 }
1002
bssoccer_read_byte(UINT32 address)1003 static UINT8 __fastcall bssoccer_read_byte(UINT32 address)
1004 {
1005 if ((address & 0xfff000) == 0x400000) {
1006 if (address & 0x200) {
1007 return DrvPalRAM2[address & 0xffe];
1008 } else {
1009 address += color_bank << 9;
1010 return DrvPalRAM[address & 0xffe];
1011 }
1012 }
1013
1014 switch (address)
1015 {
1016 case 0xa00000:
1017 case 0xa00001:
1018 return DrvInputs[0] >> ((~address & 1) << 3);
1019
1020 case 0xa00002:
1021 case 0xa00003:
1022 return DrvInputs[1] >> ((~address & 1) << 3);
1023
1024 case 0xa00004:
1025 case 0xa00005:
1026 return DrvInputs[2] >> ((~address & 1) << 3);
1027
1028 case 0xa00006:
1029 case 0xa00007:
1030 return DrvInputs[3] >> ((~address & 1) << 3);
1031
1032 case 0xa00008:
1033 case 0xa00009:
1034 return DrvInputs[4] >> ((~address & 1) << 3);
1035
1036 case 0xa0000a:
1037 case 0xa0000b:
1038 return DrvInputs[5] >> ((~address & 1) << 3);
1039 }
1040
1041 return 0;
1042 }
1043
bssoccer_write_word(UINT32 address,UINT16 data)1044 static void __fastcall bssoccer_write_word(UINT32 address, UINT16 data)
1045 {
1046 if ((address & 0xfff000) == 0x400000) {
1047 if (address & 0x200) {
1048 *((UINT16*)(DrvPalRAM2 + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
1049 } else {
1050 address += color_bank << 9;
1051 *((UINT16*)(DrvPalRAM + (address & 0xffff))) = BURN_ENDIAN_SWAP_INT16(data);
1052 suna_palette_write(address & 0xffff);
1053 }
1054 return;
1055 }
1056
1057 switch (address & ~1)
1058 {
1059 case 0xa00000:
1060 soundlatch = data;
1061 return;
1062
1063 case 0xa00002:
1064 flipscreen = data & 0x01;
1065 color_bank = (data >> 2) & 1;
1066 return;
1067 }
1068 return;
1069 }
1070
bssoccer_write_byte(UINT32 address,UINT8 data)1071 static void __fastcall bssoccer_write_byte(UINT32 address, UINT8 data)
1072 {
1073 if ((address & 0xfff000) == 0x400000) {
1074 if (address & 0x200) {
1075 DrvPalRAM[address & 0xfff] = data;
1076 } else {
1077 address += color_bank << 9;
1078 DrvPalRAM[address & 0xfff] = data;
1079 suna_palette_write(address & 0xffe);
1080 }
1081 return;
1082 }
1083
1084 switch (address)
1085 {
1086 case 0xa00000:
1087 case 0xa00001:
1088 soundlatch = data;
1089 return;
1090
1091 case 0xa00002:
1092 case 0xa00003:
1093 flipscreen = data & 0x01;
1094 color_bank = (data >> 2) & 1;
1095 return;
1096 }
1097 return;
1098 }
1099
1100 //------------------
1101 // Z80 #0
1102
bssoccer_bankswitch_w(UINT8 * z80data,INT32 p,INT32 data)1103 static void bssoccer_bankswitch_w(UINT8 *z80data, INT32 p, INT32 data)
1104 {
1105 z80bankdata[p] = data;
1106
1107 INT32 bank = ((data & 7) << 16) | 0x1000;
1108
1109 ZetMapMemory(z80data + bank, 0x1000, 0xffff, MAP_ROM);
1110 }
1111
bssoccer_sound0_write(UINT16 address,UINT8 data)1112 static void __fastcall bssoccer_sound0_write(UINT16 address, UINT8 data)
1113 {
1114 switch (address)
1115 {
1116 case 0xf800:
1117 BurnYM2151SelectRegister(data);
1118 return;
1119
1120 case 0xf801:
1121 BurnYM2151WriteRegister(data);
1122 return;
1123
1124 case 0xfd00:
1125 soundlatch2 = data;
1126 return;
1127
1128 case 0xfe00:
1129 soundlatch3 = data;
1130 return;
1131 }
1132
1133 return;
1134 }
1135
bssoccer_sound0_read(UINT16 address)1136 static UINT8 __fastcall bssoccer_sound0_read(UINT16 address)
1137 {
1138 switch (address)
1139 {
1140 case 0xf801:
1141 return BurnYM2151Read();
1142
1143 case 0xfc00:
1144 return soundlatch;
1145 }
1146
1147 return 0;
1148 }
1149
1150 //------------------
1151 // Z80 #1
1152
bssoccer_sound1_out(UINT16 port,UINT8 data)1153 static void __fastcall bssoccer_sound1_out(UINT16 port, UINT8 data)
1154 {
1155 switch (port & 0xff)
1156 {
1157 case 0x00: { DACSignedWrite(0, (data & 0xf) * 0x11); return; }
1158 case 0x01: { DACSignedWrite(1, (data & 0xf) * 0x11); return; }
1159
1160 case 0x03:
1161 bssoccer_bankswitch_w(DrvZ80ROM1, 0, data);
1162 return;
1163 }
1164
1165 return;
1166 }
1167
bssoccer_sound1_in(UINT16 port)1168 static UINT8 __fastcall bssoccer_sound1_in(UINT16 port)
1169 {
1170 switch (port & 0xff)
1171 {
1172 case 0x00:
1173 return soundlatch2;
1174 }
1175
1176 return 0;
1177 }
1178
1179 //------------------
1180 // Z80 #2
1181
bssoccer_sound2_out(UINT16 port,UINT8 data)1182 static void __fastcall bssoccer_sound2_out(UINT16 port, UINT8 data)
1183 {
1184 switch (port & 0xff)
1185 {
1186 case 0x00: { DACSignedWrite(2, (data & 0xf) * 0x11); return; }
1187 case 0x01: { DACSignedWrite(3, (data & 0xf) * 0x11); return; }
1188 return;
1189
1190 case 0x03:
1191 bssoccer_bankswitch_w(DrvZ80ROM2, 1, data);
1192 return;
1193 }
1194
1195 return;
1196 }
1197
bssoccer_sound2_in(UINT16 port)1198 static UINT8 __fastcall bssoccer_sound2_in(UINT16 port)
1199 {
1200 switch (port & 0xff)
1201 {
1202 case 0x00:
1203 return soundlatch3;
1204 }
1205
1206 return 0;
1207 }
1208
1209
1210 //-------------------------------------------------------------------------------------------------
1211 // Initialization routines
1212
DrvDoReset()1213 static INT32 DrvDoReset()
1214 {
1215 DrvReset = 0;
1216
1217 memset (AllRam, 0, RamEnd - AllRam);
1218
1219 SekOpen(0);
1220 SekReset();
1221 SekClose();
1222
1223 for (INT32 j = 0; j < 2; j++) {
1224 ZetOpen(j);
1225 ZetReset();
1226 ZetClose();
1227 }
1228
1229 if (game_select == 3) {
1230 ZetOpen(2);
1231 ZetReset();
1232 ZetClose();
1233 }
1234
1235 soundlatch = 0;
1236 soundlatch2 = 0;
1237 soundlatch3 = 0;
1238 color_bank = 0;
1239 bestofbest_prot = 0;
1240 flipscreen = 0;
1241
1242 z80bankdata[0] = z80bankdata[1] = 0;
1243
1244 if (game_select == 3) {
1245 ZetOpen(1);
1246 bssoccer_bankswitch_w(DrvZ80ROM1, 0, z80bankdata[0]);
1247 ZetClose();
1248 ZetOpen(2);
1249 bssoccer_bankswitch_w(DrvZ80ROM2, 1, z80bankdata[1]);
1250 ZetClose();
1251 }
1252
1253 if (game_select == 2) {
1254 ZetOpen(1);
1255 uballoon_bankswitch(z80bankdata[0]);
1256 ZetClose();
1257 }
1258
1259 if (game_select == 1) {
1260 ZetOpen(1);
1261 bssoccer_bankswitch_w(DrvZ80ROM1, 0, z80bankdata[0]);
1262 ZetClose();
1263 }
1264
1265 if (game_select) {
1266 BurnYM2151Reset();
1267 } else {
1268 BurnYM3526Reset();
1269 AY8910Reset(0);
1270 }
1271
1272 DACReset();
1273
1274 return 0;
1275 }
1276
1277
MemIndex()1278 static INT32 MemIndex()
1279 {
1280 UINT8 *Next; Next = AllMem;
1281
1282 Drv68KROM = Next; Next += 0x0200000;
1283 DrvZ80ROM0 = Next; Next += 0x0010000;
1284 DrvZ80ROM1 = Next; Next += 0x0080000;
1285 DrvZ80ROM2 = Next; Next += 0x0080000;
1286
1287 DrvGfxROM0 = Next; Next += 0x0600000;
1288 if (game_select == 0) {
1289 DrvGfxROM1 = Next; Next += 0x0800000;
1290 }
1291
1292 DrvPalette = (UINT32*)Next; Next += 0x01000 * sizeof(UINT32);
1293
1294 AllRam = Next;
1295
1296 Drv68KRAM = Next; Next += 0x0010000;
1297
1298 // DrvZ80RAM0 = Next; Next += 0x0000800;
1299 DrvZ80RAM0 = Next; Next += 0x0001000;
1300
1301 DrvSprRAM0 = Next; Next += 0x0020000;
1302 DrvSprRAM1 = Next; Next += 0x0020000;
1303
1304 DrvPalRAM = Next; Next += 0x0001000;
1305 DrvPalRAM2 = Next; Next += 0x0010000;
1306
1307 Palette = (UINT32*)Next; Next += 0x01000 * sizeof(UINT32);
1308
1309 RamEnd = Next;
1310
1311 MemEnd = Next;
1312
1313 return 0;
1314 }
1315
DrvGfxDecode(UINT8 * gfx_base,INT32 len)1316 static INT32 DrvGfxDecode(UINT8 *gfx_base, INT32 len)
1317 {
1318 INT32 Plane[4] = {(len << 2) + 0, (len << 2) + 4, 0, 4 };
1319 INT32 XOffs[8] = { 3, 2, 1, 0, 11, 10, 9, 8 };
1320 INT32 YOffs[8] = { 0, 16, 32, 48, 64, 80, 96, 112 };
1321
1322 UINT8 *tmp = (UINT8*)BurnMalloc(len);
1323 if (tmp == NULL) {
1324 return 1;
1325 }
1326
1327 for (INT32 i = 0; i < len; i++) tmp[i] = gfx_base[i] ^ 0xff; // copy & invert
1328
1329 GfxDecode(((len * 8) / 4) / 64, 4, 8, 8, Plane, XOffs, YOffs, 0x80, tmp, gfx_base);
1330
1331 BurnFree (tmp);
1332
1333 return 0;
1334 }
1335
DrvLoadRoms()1336 static INT32 DrvLoadRoms()
1337 {
1338 char* pRomName;
1339 struct BurnRomInfo ri;
1340
1341 UINT8 *Load68K = Drv68KROM;
1342 UINT8 *Loadz0 = DrvZ80ROM0;
1343 UINT8 *Loadz1 = DrvZ80ROM1;
1344 UINT8 *Loadz2 = DrvZ80ROM2;
1345 UINT8 *Loadg0 = DrvGfxROM0;
1346 UINT8 *Loadg1 = DrvGfxROM1;
1347
1348 INT32 gfx0_len = 0;
1349 INT32 gfx1_len = 0;
1350
1351 for (INT32 i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) {
1352
1353 BurnDrvGetRomInfo(&ri, i);
1354
1355 if ((ri.nType & 7) == 1) {
1356
1357 if (BurnLoadRom(Load68K + 1, i + 0, 2)) return 1;
1358 if (BurnLoadRom(Load68K + 0, i + 1, 2)) return 1;
1359
1360 Load68K += 0x100000;
1361
1362 i++;
1363
1364 continue;
1365 }
1366
1367 if ((ri.nType & 7) == 2) {
1368 if (BurnLoadRom(Loadz0, i, 1)) return 1;
1369 continue;
1370 }
1371
1372 if ((ri.nType & 7) == 3) {
1373 if (BurnLoadRom(Loadz1, i, 1)) return 1;
1374 continue;
1375 }
1376
1377 if ((ri.nType & 7) == 4) {
1378 if (BurnLoadRom(Loadz2, i, 1)) return 1;
1379 continue;
1380 }
1381
1382 if ((ri.nType & 7) == 5) {
1383 if (BurnLoadRom(Loadg0, i, 1)) return 1;
1384
1385 Loadg0 += ri.nLen;
1386 gfx0_len += ri.nLen;
1387
1388 continue;
1389 }
1390
1391 if ((ri.nType & 7) == 6) {
1392 if (BurnLoadRom(Loadg1, i, 1)) return 1;
1393
1394 Loadg1 += ri.nLen;
1395 gfx1_len += ri.nLen;
1396
1397 continue;
1398 }
1399 }
1400
1401 nGfxROM0Len = gfx0_len >> 5;
1402
1403 if (gfx0_len) DrvGfxDecode(DrvGfxROM0, gfx0_len);
1404 if (gfx1_len) DrvGfxDecode(DrvGfxROM1, gfx1_len);
1405
1406 return 0;
1407 }
1408
bestbest_ay8910_write_a(UINT32,UINT32)1409 static void bestbest_ay8910_write_a(UINT32,UINT32)
1410 {
1411 }
1412
bestbestFMIRQHandler(INT32,INT32 nStatus)1413 static void bestbestFMIRQHandler(INT32, INT32 nStatus)
1414 {
1415 if (nStatus) {
1416 ZetSetIRQLine(0xFF, CPU_IRQSTATUS_ACK);
1417 } else {
1418 ZetSetIRQLine(0, CPU_IRQSTATUS_NONE);
1419 }
1420 }
1421
bestbestSynchroniseStream(INT32 nSoundRate)1422 static INT32 bestbestSynchroniseStream(INT32 nSoundRate)
1423 {
1424 return (INT64)ZetTotalCycles() * nSoundRate / 6000000;
1425 }
1426
BestbestInit()1427 static INT32 BestbestInit()
1428 {
1429 INT32 nLen;
1430
1431 game_select = 0;
1432
1433 AllMem = NULL;
1434 MemIndex();
1435 nLen = MemEnd - (UINT8 *)0;
1436 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1437 memset(AllMem, 0, nLen);
1438 MemIndex();
1439
1440 if (DrvLoadRoms()) return 1;
1441
1442 SekInit(0, 0x68000);
1443 SekOpen(0);
1444 SekMapMemory(Drv68KROM, 0x000000, 0x03ffff, MAP_ROM);
1445 SekMapMemory(Drv68KROM, 0x040000, 0x07ffff, MAP_ROM);
1446 SekMapMemory(Drv68KROM, 0x080000, 0x0bffff, MAP_ROM);
1447 SekMapMemory(Drv68KROM, 0x0c0000, 0x0fffff, MAP_ROM);
1448 SekMapMemory(Drv68KROM + 0x100000, 0x200000, 0x2fffff, MAP_ROM);
1449 SekMapMemory(DrvPalRAM, 0x540000, 0x540fff, MAP_ROM);
1450 SekMapMemory(DrvPalRAM2, 0x541000, 0x54ffff, MAP_RAM);
1451 SekMapMemory(Drv68KRAM, 0x580000, 0x58ffff, MAP_RAM);
1452 SekMapMemory(DrvSprRAM0, 0x5c0000, 0x5dffff, MAP_RAM);
1453 SekMapMemory(DrvSprRAM1, 0x5e0000, 0x5fffff, MAP_RAM);
1454 SekSetWriteByteHandler(0, bestbest_write_byte);
1455 SekSetWriteWordHandler(0, bestbest_write_word);
1456 SekSetReadByteHandler(0, bestbest_read_byte);
1457 SekSetReadWordHandler(0, bestbest_read_word);
1458 SekClose();
1459
1460 ZetInit(0);
1461 ZetOpen(0);
1462 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xbfff, MAP_ROM);
1463 ZetMapMemory(DrvZ80RAM0, 0xe000, 0xe7ff, MAP_RAM);
1464 ZetSetReadHandler(bestbest_sound0_read);
1465 ZetSetWriteHandler(bestbest_sound0_write);
1466 ZetClose();
1467
1468 ZetInit(1);
1469 ZetOpen(1);
1470 ZetMapMemory(DrvZ80ROM1, 0x0000, 0xffff, MAP_ROM);
1471 ZetSetInHandler(bestbest_sound1_in);
1472 ZetSetOutHandler(bestbest_sound1_out);
1473 ZetClose();
1474
1475 BurnYM3526Init(3000000, &bestbestFMIRQHandler, &bestbestSynchroniseStream, 1);
1476 BurnTimerAttachYM3526(&ZetConfig, 6000000);
1477 BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
1478
1479 AY8910Init(0, 1500000, 0);
1480 AY8910SetPorts(0, NULL, NULL, bestbest_ay8910_write_a, NULL);
1481 AY8910SetRoute(0, BURN_SND_AY8910_ROUTE_1, 1.00, BURN_SND_ROUTE_LEFT);
1482 AY8910SetRoute(0, BURN_SND_AY8910_ROUTE_2, 1.00, BURN_SND_ROUTE_RIGHT);
1483 AY8910SetRoute(0, BURN_SND_AY8910_ROUTE_3, 0.00, BURN_SND_ROUTE_BOTH); // suppressed?
1484
1485 DACInit(0, 0, 1, ZetTotalCycles, 6000000);
1486 DACInit(1, 0, 1, ZetTotalCycles, 6000000);
1487 DACInit(2, 0, 1, ZetTotalCycles, 6000000);
1488 DACInit(3, 0, 1, ZetTotalCycles, 6000000);
1489 DACSetRoute(0, 0.40, BURN_SND_ROUTE_LEFT);
1490 DACSetRoute(1, 0.40, BURN_SND_ROUTE_RIGHT);
1491 DACSetRoute(2, 0.40, BURN_SND_ROUTE_LEFT);
1492 DACSetRoute(3, 0.40, BURN_SND_ROUTE_RIGHT);
1493
1494 DrvDoReset();
1495
1496 GenericTilesInit();
1497
1498 return 0;
1499 }
1500
SunaqInit()1501 static INT32 SunaqInit()
1502 {
1503 INT32 nLen;
1504
1505 game_select = 1;
1506
1507 AllMem = NULL;
1508 MemIndex();
1509 nLen = MemEnd - (UINT8 *)0;
1510 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1511 memset(AllMem, 0, nLen);
1512 MemIndex();
1513
1514 if (DrvLoadRoms()) return 1;
1515
1516 SekInit(0, 0x68000);
1517 SekOpen(0);
1518 SekMapMemory(Drv68KROM, 0x000000, 0x0fffff, MAP_ROM);
1519 SekMapMemory(DrvPalRAM2, 0x540400, 0x540fff, MAP_RAM);
1520 SekMapMemory(Drv68KRAM, 0x580000, 0x583fff, MAP_RAM);
1521 SekMapMemory(DrvSprRAM0, 0x5c0000, 0x5dffff, MAP_RAM);
1522 SekSetWriteByteHandler(0, sunaq_write_byte);
1523 SekSetWriteWordHandler(0, sunaq_write_word);
1524 SekSetReadByteHandler(0, sunaq_read_byte);
1525 SekSetReadWordHandler(0, sunaq_read_word);
1526 SekClose();
1527
1528 ZetInit(0);
1529 ZetOpen(0);
1530 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xefff, MAP_ROM);
1531 ZetMapMemory(DrvZ80RAM0, 0xf000, 0xf7ff, MAP_RAM);
1532 ZetSetWriteHandler(sunaq_sound0_write);
1533 ZetSetReadHandler(bssoccer_sound0_read);
1534 ZetClose();
1535
1536 ZetInit(1);
1537 ZetOpen(1);
1538 ZetMapMemory(DrvZ80ROM1, 0x0000, 0xffff, MAP_ROM);
1539 ZetSetInHandler(bssoccer_sound1_in);
1540 ZetSetOutHandler(bssoccer_sound1_out);
1541 ZetClose();
1542
1543 BurnYM2151Init(3579545);
1544 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.50, BURN_SND_ROUTE_LEFT);
1545 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.50, BURN_SND_ROUTE_RIGHT);
1546
1547 DACInit(0, 0, 2, ZetTotalCycles, 6000000);
1548 DACInit(1, 0, 2, ZetTotalCycles, 6000000);
1549 DACSetRoute(0, 0.50, BURN_SND_ROUTE_LEFT);
1550 DACSetRoute(1, 0.50, BURN_SND_ROUTE_RIGHT);
1551
1552 DrvDoReset();
1553
1554 GenericTilesInit();
1555
1556 return 0;
1557 }
1558
1559
UballoonInit()1560 static INT32 UballoonInit()
1561 {
1562 INT32 nLen;
1563
1564 game_select = 2;
1565
1566 AllMem = NULL;
1567 MemIndex();
1568 nLen = MemEnd - (UINT8 *)0;
1569 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1570 memset(AllMem, 0, nLen);
1571 MemIndex();
1572
1573 if (DrvLoadRoms()) return 1;
1574
1575 SekInit(0, 0x68000);
1576 SekOpen(0);
1577 SekMapMemory(Drv68KROM, 0x000000, 0x0fffff, MAP_ROM);
1578 SekMapMemory(DrvPalRAM2, 0x200400, 0x200fff, MAP_RAM);
1579 SekMapMemory(DrvSprRAM0, 0x400000, 0x41ffff, MAP_RAM);
1580 SekMapMemory(DrvSprRAM0, 0x5c0000, 0x5dffff, MAP_RAM);
1581 SekMapMemory(Drv68KRAM, 0x800000, 0x803fff, MAP_RAM);
1582 SekSetWriteByteHandler(0, uballoon_write_byte);
1583 SekSetWriteWordHandler(0, uballoon_write_word);
1584 SekSetReadByteHandler(0, uballoon_read_byte);
1585 SekSetReadWordHandler(0, uballoon_read_word);
1586 SekClose();
1587
1588 ZetInit(0);
1589 ZetOpen(0);
1590 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xefff, MAP_ROM);
1591 ZetMapMemory(DrvZ80RAM0, 0xf000, 0xf7ff, MAP_RAM);
1592 ZetSetWriteHandler(sunaq_sound0_write);
1593 ZetSetReadHandler(bssoccer_sound0_read);
1594 ZetClose();
1595
1596 ZetInit(1);
1597 ZetOpen(1);
1598 ZetMapMemory(DrvZ80ROM1, 0x0000, 0xffff, MAP_ROM);
1599 ZetSetInHandler(uballoon_sound1_in);
1600 ZetSetOutHandler(uballoon_sound1_out);
1601 ZetClose();
1602
1603 BurnYM2151Init(3579545);
1604 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.50, BURN_SND_ROUTE_LEFT);
1605 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.50, BURN_SND_ROUTE_RIGHT);
1606
1607 DACInit(0, 0, 1, ZetTotalCycles, 5333333);
1608 DACInit(1, 0, 1, ZetTotalCycles, 5333333);
1609 DACSetRoute(0, 0.50, BURN_SND_ROUTE_LEFT);
1610 DACSetRoute(1, 0.50, BURN_SND_ROUTE_RIGHT);
1611
1612 GenericTilesInit();
1613
1614 DrvDoReset();
1615
1616 return 0;
1617 }
1618
BssoccerInit()1619 static INT32 BssoccerInit()
1620 {
1621 INT32 nLen;
1622
1623 game_select = 3;
1624
1625 AllMem = NULL;
1626 MemIndex();
1627 nLen = MemEnd - (UINT8 *)0;
1628 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
1629 memset(AllMem, 0, nLen);
1630 MemIndex();
1631
1632 if (DrvLoadRoms()) return 1;
1633
1634 SekInit(0, 0x68000);
1635 SekOpen(0);
1636 SekMapMemory(Drv68KROM, 0x000000, 0x1fffff, MAP_ROM);
1637 SekMapMemory(Drv68KRAM, 0x200000, 0x203fff, MAP_RAM);
1638 SekMapMemory(DrvPalRAM2, 0x400400, 0x400fff, MAP_RAM);
1639 SekMapMemory(DrvSprRAM0, 0x600000, 0x61ffff, MAP_RAM);
1640 SekSetWriteByteHandler(0, bssoccer_write_byte);
1641 SekSetWriteWordHandler(0, bssoccer_write_word);
1642 SekSetReadByteHandler(0, bssoccer_read_byte);
1643 SekSetReadWordHandler(0, bssoccer_read_word);
1644 SekClose();
1645
1646 ZetInit(0);
1647 ZetOpen(0);
1648 ZetMapMemory(DrvZ80ROM0, 0x0000, 0x7fff, MAP_ROM);
1649 ZetMapMemory(DrvZ80RAM0, 0xf000, 0xf7ff, MAP_RAM);
1650 ZetSetWriteHandler(bssoccer_sound0_write);
1651 ZetSetReadHandler(bssoccer_sound0_read);
1652 ZetClose();
1653
1654 ZetInit(1);
1655 ZetOpen(1);
1656 ZetMapMemory(DrvZ80ROM1, 0x0000, 0xffff, MAP_ROM);
1657 ZetSetInHandler(bssoccer_sound1_in);
1658 ZetSetOutHandler(bssoccer_sound1_out);
1659 ZetClose();
1660
1661 ZetInit(2);
1662 ZetOpen(2);
1663 ZetMapMemory(DrvZ80ROM2, 0x0000, 0xffff, MAP_ROM);
1664 ZetSetInHandler(bssoccer_sound2_in);
1665 ZetSetOutHandler(bssoccer_sound2_out);
1666 ZetClose();
1667
1668 BurnYM2151Init(3579545);
1669 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.20, BURN_SND_ROUTE_LEFT);
1670 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.20, BURN_SND_ROUTE_RIGHT);
1671
1672 DACInit(0, 0, 1, ZetTotalCycles, 5333333);
1673 DACInit(1, 0, 1, ZetTotalCycles, 5333333);
1674 DACInit(2, 0, 1, ZetTotalCycles, 5333333);
1675 DACInit(3, 0, 1, ZetTotalCycles, 5333333);
1676 DACSetRoute(0, 0.40, BURN_SND_ROUTE_BOTH);
1677 DACSetRoute(1, 0.40, BURN_SND_ROUTE_BOTH);
1678 DACSetRoute(2, 0.40, BURN_SND_ROUTE_LEFT);
1679 DACSetRoute(3, 0.40, BURN_SND_ROUTE_RIGHT);
1680
1681 DrvDoReset();
1682
1683 GenericTilesInit();
1684
1685 return 0;
1686 }
1687
DrvExit()1688 static INT32 DrvExit()
1689 {
1690 BurnFree (AllMem);
1691
1692 if (game_select) {
1693 BurnYM2151Exit();
1694 } else {
1695 AY8910Exit(0);
1696 BurnYM3526Exit();
1697 }
1698
1699 DACExit();
1700
1701 SekExit();
1702 ZetExit();
1703
1704 GenericTilesExit();
1705
1706 return 0;
1707 }
1708
1709
1710 //-------------------------------------------------------------------------------------------------
1711 // Drawing & CPU/sound emulation routines
1712
1713
draw_sprites(UINT16 * sprites,UINT8 * gfx_base,INT32 max_tile)1714 static void draw_sprites(UINT16 *sprites, UINT8 *gfx_base, INT32 max_tile)
1715 {
1716 INT32 offs;
1717
1718 INT32 max_x = (256 - 0) - 8;
1719 INT32 max_y = (256 - 0) - 8;
1720
1721 for (offs = 0xfc00/2; offs < 0x10000/2 ; offs += 4/2)
1722 {
1723 INT32 srcpg, srcx,srcy, dimx,dimy;
1724 INT32 tile_x, tile_xinc, tile_xstart;
1725 INT32 tile_y, tile_yinc;
1726 INT32 dx, dy;
1727 INT32 flipx, y0;
1728
1729 INT32 y = BURN_ENDIAN_SWAP_INT16(sprites[ offs + 0 + 0x00000 / 2 ]);
1730 INT32 x = BURN_ENDIAN_SWAP_INT16(sprites[ offs + 1 + 0x00000 / 2 ]);
1731 INT32 dim = BURN_ENDIAN_SWAP_INT16(sprites[ offs + 0 + 0x10000 / 2 ]);
1732
1733 INT32 bank = (x >> 12) & 0xf;
1734
1735 srcpg = ((y & 0xf000) >> 12) + ((x & 0x0200) >> 5);
1736 srcx = ((y >> 8) & 0xf) * 2;
1737 srcy = ((dim >> 0) & 0xf) * 2;
1738
1739 switch ( (dim >> 4) & 0xc )
1740 {
1741 case 0x0: dimx = 2; dimy = 2; y0 = 0x100; break;
1742 case 0x4: dimx = 4; dimy = 4; y0 = 0x100; break;
1743 case 0x8: dimx = 2; dimy = 32; y0 = 0x130; break;
1744 default:
1745 case 0xc: dimx = 4; dimy = 32; y0 = 0x120; break;
1746 }
1747
1748 if (dimx==4) { flipx = srcx & 2; srcx &= ~2; }
1749 else { flipx = 0; }
1750
1751 x = (x & 0xff) - (x & 0x100);
1752 y = (y0 - (y & 0xff) - dimy*8 ) & 0xff;
1753
1754 if (flipx) { tile_xstart = dimx-1; tile_xinc = -1; }
1755 else { tile_xstart = 0; tile_xinc = +1; }
1756
1757 tile_y = 0; tile_yinc = +1;
1758
1759 for (dy = 0; dy < dimy * 8; dy += 8)
1760 {
1761 tile_x = tile_xstart;
1762
1763 for (dx = 0; dx < dimx * 8; dx += 8)
1764 {
1765 INT32 addr = (srcpg * 0x20 * 0x20) +
1766 ((srcx + tile_x) & 0x1f) * 0x20 +
1767 ((srcy + tile_y) & 0x1f);
1768
1769 INT32 tile = BURN_ENDIAN_SWAP_INT16(sprites[ addr + 0x00000 / 2 ]);
1770 INT32 color = BURN_ENDIAN_SWAP_INT16(sprites[ addr + 0x10000 / 2 ]);
1771
1772 INT32 sx = x + dx;
1773 INT32 sy = (y + dy) & 0xff;
1774
1775 INT32 tile_flipx = tile & 0x4000;
1776 INT32 tile_flipy = tile & 0x8000;
1777
1778 if (flipx) tile_flipx ^= 0x4000;
1779
1780 if (flipscreen)
1781 {
1782 sx = max_x - sx;
1783 sy = max_y - sy;
1784 tile_flipx ^= 0x4000;
1785 tile_flipy ^= 0x8000;
1786 }
1787
1788 tile = (tile & 0x3fff) | (bank << 14);
1789 color += (color_bank << 4);
1790 color &= 0x7f;
1791 tile %= max_tile;
1792
1793 sy -= 16;
1794
1795 tile_x += tile_xinc;
1796
1797 if (sy < -15 || sy > (nScreenHeight - 1) || sx < -15 || sx > (nScreenWidth - 1)) {
1798 continue;
1799 }
1800
1801 if (tile_flipy) {
1802 if (tile_flipx) {
1803 Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, tile, sx, sy, color, 4, 0x0f, 0, gfx_base);
1804 } else {
1805 Render8x8Tile_Mask_FlipY_Clip(pTransDraw, tile, sx, sy, color, 4, 0x0f, 0, gfx_base);
1806 }
1807 } else {
1808 if (tile_flipx) {
1809 Render8x8Tile_Mask_FlipX_Clip(pTransDraw, tile, sx, sy, color, 4, 0x0f, 0, gfx_base);
1810 } else {
1811 Render8x8Tile_Mask_Clip(pTransDraw, tile, sx, sy, color, 4, 0x0f, 0, gfx_base);
1812 }
1813 }
1814 }
1815
1816 tile_y += tile_yinc;
1817 }
1818
1819 }
1820
1821 }
1822
DrvDraw()1823 static INT32 DrvDraw()
1824 {
1825 if (DrvRecalc) {
1826 for (INT32 i = 0; i < 0x1000; i++) {
1827 INT32 rgb = Palette[i];
1828 DrvPalette[i] = BurnHighCol(rgb >> 16, rgb >> 8, rgb, 0);
1829 }
1830 }
1831
1832 BurnTransferClear(0xff);
1833
1834 draw_sprites((UINT16*)DrvSprRAM0, DrvGfxROM0, nGfxROM0Len);
1835 if (!game_select) {
1836 draw_sprites((UINT16*)DrvSprRAM1, DrvGfxROM1, 0x20000);
1837 }
1838
1839 BurnTransferCopy(DrvPalette);
1840
1841 return 0;
1842 }
1843
AssembleInputs()1844 static inline void AssembleInputs()
1845 {
1846 memset (DrvInputs, 0xff, 6 * sizeof(UINT16));
1847
1848 for (INT32 i = 0; i < 16; i++) {
1849 DrvInputs[0] ^= DrvJoy1[i] << i;
1850 DrvInputs[1] ^= DrvJoy2[i] << i;
1851 DrvInputs[2] ^= DrvJoy3[i] << i;
1852 DrvInputs[3] ^= DrvJoy4[i] << i;
1853 DrvInputs[4] ^= DrvJoy5[i] << i;
1854 DrvInputs[5] ^= DrvJoy6[i] << i;
1855 }
1856
1857 switch (game_select)
1858 {
1859 case 0: // bestbest
1860 {
1861 DrvInputs[2] = (DrvDips[1] << 8) | DrvDips[0];
1862 }
1863 return;
1864
1865 case 1: // sunaq
1866 {
1867 DrvInputs[2] = DrvDips[0];
1868 }
1869 return;
1870
1871 case 2: // uballoon
1872 {
1873 DrvInputs[1] = (DrvInputs[1] & ~0x3000) | ((DrvDips[0] << 8) & 0x3000);
1874 DrvInputs[2] = DrvDips[1];
1875 DrvInputs[3] = DrvDips[2];
1876 }
1877 return;
1878
1879 case 3: // bssoccer
1880 {
1881 DrvInputs[4] = (DrvDips[1] << 8) | DrvDips[0];
1882 DrvInputs[5] = ((DrvInputs[5] & 0xfe) | (DrvDips[2] & 0x01)) | 0xff00;
1883 }
1884 return;
1885 }
1886
1887 return;
1888 }
1889
BestbestFrame()1890 static INT32 BestbestFrame()
1891 {
1892 if (DrvReset) {
1893 DrvDoReset();
1894 }
1895
1896 AssembleInputs();
1897
1898 SekNewFrame();
1899 ZetNewFrame();
1900
1901 INT32 nInterleave = 50;
1902 INT32 nCyclesTotal[3] = { 6000000 / 60, 6000000 / 60, 6000000 / 60 };
1903 INT32 nCyclesDone[3] = { 0, 0, 0 };
1904
1905 SekOpen(0);
1906 for (INT32 i = 0; i < nInterleave; i++) {
1907
1908 CPU_RUN(0, Sek);
1909 if (i == (nInterleave / 2)-1) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
1910 if (i == (nInterleave )-1) SekSetIRQLine(2, CPU_IRQSTATUS_AUTO);
1911
1912 ZetOpen(0);
1913 BurnTimerUpdateYM3526((i + 1) * (nCyclesTotal[1] / nInterleave));
1914 ZetClose();
1915
1916 ZetOpen(1);
1917 CPU_RUN(1, Zet);
1918 ZetClose();
1919 }
1920 SekClose();
1921
1922 ZetOpen(0);
1923 BurnTimerEndFrameYM3526(nCyclesTotal[1]);
1924 if (pBurnSoundOut) {
1925 AY8910Render(pBurnSoundOut, nBurnSoundLen);
1926 BurnYM3526Update(pBurnSoundOut, nBurnSoundLen);
1927 DACUpdate(pBurnSoundOut, nBurnSoundLen);
1928 }
1929 ZetClose();
1930
1931 if (pBurnDraw) {
1932 DrvDraw();
1933 }
1934
1935 return 0;
1936 }
1937
SunaqFrame()1938 static INT32 SunaqFrame()
1939 {
1940 if (DrvReset) {
1941 DrvDoReset();
1942 }
1943
1944 AssembleInputs();
1945
1946 SekNewFrame();
1947 ZetNewFrame();
1948
1949 INT32 nInterleave = 50;
1950 INT32 nCyclesTotal[3] = { 6000000 / 60, 3579500 / 60, 6000000 / 60 };
1951 INT32 nCyclesDone[3] = { 0, 0, 0 };
1952 INT32 nSoundBufferPos = 0;
1953
1954 SekOpen(0);
1955
1956 for (INT32 i = 0; i < nInterleave; i++)
1957 {
1958 CPU_RUN(0, Sek);
1959 if (i == nInterleave-1) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
1960
1961 ZetOpen(0);
1962 CPU_RUN(1, Zet);
1963 ZetClose();
1964
1965 ZetOpen(1);
1966 CPU_RUN(2, Zet);
1967 ZetClose();
1968
1969 if (pBurnSoundOut) {
1970 INT32 nSegmentLength = nBurnSoundLen / nInterleave;
1971 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
1972 BurnYM2151Render(pSoundBuf, nSegmentLength);
1973
1974 nSoundBufferPos += nSegmentLength;
1975 }
1976 }
1977
1978 if (pBurnSoundOut) {
1979 INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
1980 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
1981
1982 if (nSegmentLength) {
1983 BurnYM2151Render(pSoundBuf, nSegmentLength);
1984 }
1985
1986 DACUpdate(pBurnSoundOut, nBurnSoundLen);
1987 }
1988
1989 SekClose();
1990
1991 if (pBurnDraw) {
1992 DrvDraw();
1993 }
1994
1995 return 0;
1996 }
1997
UballoonFrame()1998 static INT32 UballoonFrame()
1999 {
2000 if (DrvReset) {
2001 DrvDoReset();
2002 }
2003
2004 AssembleInputs();
2005
2006 SekNewFrame();
2007 ZetNewFrame();
2008
2009 INT32 nInterleave = 50;
2010 INT32 nCyclesTotal[3] = { 8000000 / 60, 3579500 / 60, 5333333 / 60 };
2011 INT32 nCyclesDone[3] = { 0, 0, 0 };
2012 INT32 nSoundBufferPos = 0;
2013
2014 SekOpen(0);
2015
2016 for (INT32 i = 0; i < nInterleave; i++)
2017 {
2018 CPU_RUN(0, Sek);
2019 if (i == nInterleave-1) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
2020
2021 ZetOpen(0);
2022 CPU_RUN(1, Zet);
2023 ZetClose();
2024
2025 ZetOpen(1);
2026 CPU_RUN(2, Zet);
2027 ZetClose();
2028
2029 if (pBurnSoundOut) {
2030 INT32 nSegmentLength = nBurnSoundLen / nInterleave;
2031 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
2032 BurnYM2151Render(pSoundBuf, nSegmentLength);
2033
2034 nSoundBufferPos += nSegmentLength;
2035 }
2036 }
2037
2038 // Make sure the buffer is entirely filled.
2039 if (pBurnSoundOut) {
2040 INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
2041 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
2042
2043 if (nSegmentLength) {
2044 BurnYM2151Render(pSoundBuf, nSegmentLength);
2045 }
2046
2047 ZetOpen(1);
2048 DACUpdate(pBurnSoundOut, nBurnSoundLen);
2049 ZetClose();
2050 }
2051
2052 SekClose();
2053
2054 if (pBurnDraw) {
2055 DrvDraw();
2056 }
2057
2058 return 0;
2059 }
2060
2061
BssoccerFrame()2062 static INT32 BssoccerFrame()
2063 {
2064 if (DrvReset) {
2065 DrvDoReset();
2066 }
2067
2068 AssembleInputs();
2069
2070 INT32 nInterleave = 50;
2071 INT32 nCyclesTotal[4] = { 8000000 / 60, 3579500 / 60, 5333333 / 60, 5333333 / 60 };
2072 INT32 nCyclesDone[4] = { 0, 0, 0, 0 };
2073 INT32 nSoundBufferPos = 0;
2074
2075 SekNewFrame();
2076 ZetNewFrame();
2077
2078 SekOpen(0);
2079
2080 for (INT32 i = 0; i < nInterleave; i++)
2081 {
2082 CPU_RUN(0, Sek);
2083 if (i == (nInterleave / 2)-1) SekSetIRQLine(2, CPU_IRQSTATUS_AUTO);
2084 if (i == (nInterleave )-1) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
2085
2086 ZetOpen(0);
2087 CPU_RUN(1, Zet);
2088 ZetClose();
2089
2090 ZetOpen(1);
2091 CPU_RUN(2, Zet);
2092 ZetClose();
2093
2094 ZetOpen(2);
2095 CPU_RUN(3, Zet);
2096 ZetClose();
2097
2098 if (pBurnSoundOut) {
2099 INT32 nSegmentLength = nBurnSoundLen / nInterleave;
2100 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
2101 BurnYM2151Render(pSoundBuf, nSegmentLength);
2102 nSoundBufferPos += nSegmentLength;
2103 }
2104 }
2105
2106 // Make sure the buffer is entirely filled.
2107 if (pBurnSoundOut) {
2108 INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
2109 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
2110
2111 if (nSegmentLength) {
2112 BurnYM2151Render(pSoundBuf, nSegmentLength);
2113 }
2114
2115 ZetOpen(1);
2116 DACUpdate(pBurnSoundOut, nBurnSoundLen);
2117 ZetClose();
2118 }
2119
2120 SekClose();
2121
2122 if (pBurnDraw) {
2123 DrvDraw();
2124 }
2125
2126 return 0;
2127 }
2128
2129
DrvScan(INT32 nAction,INT32 * pnMin)2130 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
2131 {
2132 struct BurnArea ba;
2133
2134 if (pnMin) {
2135 *pnMin = 0x029692;
2136 }
2137
2138 if (nAction & ACB_VOLATILE) {
2139 memset(&ba, 0, sizeof(ba));
2140
2141 ba.Data = AllRam;
2142 ba.nLen = RamEnd - AllRam;
2143 ba.szName = "All Ram";
2144 BurnAcb(&ba);
2145
2146 SekScan(nAction);
2147 ZetScan(nAction);
2148
2149 DACScan(nAction, pnMin);
2150
2151 if (game_select) {
2152 BurnYM2151Scan(nAction, pnMin);
2153 } else {
2154 AY8910Scan(nAction, pnMin);
2155 }
2156
2157 SCAN_VAR(soundlatch);
2158 SCAN_VAR(soundlatch2);
2159 SCAN_VAR(soundlatch3);
2160 SCAN_VAR(flipscreen);
2161 SCAN_VAR(color_bank);
2162 SCAN_VAR(bestofbest_prot);
2163
2164 SCAN_VAR(z80bankdata[0]);
2165 SCAN_VAR(z80bankdata[1]);
2166 }
2167
2168 if (game_select == 3) {
2169 ZetOpen(1);
2170 bssoccer_bankswitch_w(DrvZ80ROM1, 0, z80bankdata[0]);
2171 ZetClose();
2172 ZetOpen(2);
2173 bssoccer_bankswitch_w(DrvZ80ROM2, 1, z80bankdata[1]);
2174 ZetClose();
2175 }
2176
2177 if (game_select == 2) {
2178 ZetOpen(1);
2179 uballoon_bankswitch(z80bankdata[0]);
2180 ZetClose();
2181 }
2182
2183 return 0;
2184 }
2185
2186
2187
2188 //-------------------------------------------------------------------------------------------------
2189 // Drivers
2190
2191
2192 // Best Of Best
2193
2194 static struct BurnRomInfo bestbestRomDesc[] = {
2195 { "4.bin", 0x20000, 0x06741994, 1 | BRF_ESS | BRF_PRG }, // 0 - 68K Code
2196 { "2.bin", 0x20000, 0x42843dec, 1 | BRF_ESS | BRF_PRG }, // 1
2197 { "3.bin", 0x80000, 0xe2bb8f26, 1 | BRF_ESS | BRF_PRG }, // 2
2198 { "1.bin", 0x80000, 0xd365e20a, 1 | BRF_ESS | BRF_PRG }, // 3
2199
2200 { "5.bin", 0x10000, 0xbb9265e6, 2 | BRF_ESS | BRF_PRG }, // 4 - Z80 #0 Code
2201
2202 { "6.bin", 0x10000, 0xdd445f6b, 3 | BRF_ESS | BRF_PRG }, // 5 - Z80 #1 Code
2203
2204 { "9.bin", 0x80000, 0xb11994ea, 5 | BRF_GRA }, // 6 - Sprites (Chip 0)
2205 { "10.bin", 0x80000, 0x37b41ef5, 5 | BRF_GRA }, // 7
2206 { "7.bin", 0x80000, 0x16188b73, 5 | BRF_GRA }, // 8
2207 { "8.bin", 0x80000, 0x765ce06b, 5 | BRF_GRA }, // 9
2208
2209 { "16.bin", 0x80000, 0xdc46cdea, 6 | BRF_GRA }, // 10 - Sprites (Chip 1)
2210 { "17.bin", 0x80000, 0xc6fadd57, 6 | BRF_GRA }, // 11
2211 { "13.bin", 0x80000, 0x23283ac4, 6 | BRF_GRA }, // 12
2212 { "18.bin", 0x80000, 0x674c4609, 6 | BRF_GRA }, // 13
2213 { "14.bin", 0x80000, 0xc210fb53, 6 | BRF_GRA }, // 14
2214 { "15.bin", 0x80000, 0x3b1166c7, 6 | BRF_GRA }, // 15
2215 { "11.bin", 0x80000, 0x323eebc3, 6 | BRF_GRA }, // 16
2216 { "12.bin", 0x80000, 0xca7c8176, 6 | BRF_GRA }, // 17
2217
2218 { "82s129.5", 0x00100, 0x10bfcebb, 0 | BRF_OPT }, // 18 - PROMs (not used)
2219 { "82s129.6", 0x00100, 0x10bfcebb, 0 | BRF_OPT }, // 19
2220 };
2221
2222 STD_ROM_PICK(bestbest)
2223 STD_ROM_FN(bestbest)
2224
2225 struct BurnDriver BurnDrvBestbest = {
2226 "bestbest", NULL, NULL, NULL, "1994",
2227 "Best Of Best\0", NULL, "SunA", "Miscellaneous",
2228 NULL, NULL, NULL, NULL,
2229 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_VSFIGHT, 0,
2230 NULL, bestbestRomInfo, bestbestRomName, NULL, NULL, NULL, NULL, BestbestInputInfo, bestbestDIPInfo,
2231 BestbestInit, DrvExit, BestbestFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
2232 256, 224, 4, 3
2233 };
2234
2235
2236 // SunA Quiz 6000 Academy (940620-6)
2237
2238 static struct BurnRomInfo sunaqRomDesc[] = {
2239 { "prog2.bin", 0x80000, 0xa92bce45, 1 | BRF_ESS | BRF_PRG }, // 0 - 68K Code
2240 { "prog1.bin", 0x80000, 0xff690e7e, 1 | BRF_ESS | BRF_PRG }, // 1
2241
2242 { "audio1.bin", 0x10000, 0x3df42f82, 2 | BRF_ESS | BRF_PRG }, // 2 - Z80 #0 Code
2243
2244 { "audio2.bin", 0x80000, 0xcac85ba9, 3 | BRF_ESS | BRF_PRG }, // 3 - Z80 #1 Code
2245
2246 { "gfx1.bin", 0x80000, 0x0bde5acf, 5 | BRF_GRA }, // 4 - Sprites
2247 { "gfx2.bin", 0x80000, 0x24b74826, 5 | BRF_GRA }, // 5
2248 };
2249
2250 STD_ROM_PICK(sunaq)
2251 STD_ROM_FN(sunaq)
2252
2253 struct BurnDriver BurnDrvSunaq = {
2254 "sunaq", NULL, NULL, NULL, "1994",
2255 "SunA Quiz 6000 Academy (940620-6)\0", NULL, "SunA", "Miscellaneous",
2256 NULL, NULL, NULL, NULL,
2257 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_QUIZ, 0,
2258 NULL, sunaqRomInfo, sunaqRomName, NULL, NULL, NULL, NULL, SunaqInputInfo, sunaqDIPInfo,
2259 SunaqInit, DrvExit, SunaqFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
2260 256, 224, 4, 3
2261 };
2262
2263
2264 // Ultra Balloon
2265
2266 static struct BurnRomInfo uballoonRomDesc[] = {
2267 { "prg2.rom2", 0x80000, 0x72ab80ea, 1 | BRF_ESS | BRF_PRG }, // 0 - 68K Code
2268 { "prg1.rom1", 0x80000, 0x27a04f55, 1 | BRF_ESS | BRF_PRG }, // 1
2269
2270 { "audio1.rom7", 0x10000, 0xc771f2b4, 2 | BRF_ESS | BRF_PRG }, // 2 - Z80 #0 Code
2271
2272 { "audio2.rom8", 0x20000, 0xc7f75347, 3 | BRF_ESS | BRF_PRG }, // 3 - Z80 #1 Code
2273
2274 { "gfx3.rom3", 0x80000, 0xfd2ec297, 5 | BRF_GRA }, // 4 - Sprites
2275 { "gfx5.rom5", 0x80000, 0x6307aa60, 5 | BRF_GRA }, // 5
2276 { "gfx4.rom4", 0x80000, 0x718f3150, 5 | BRF_GRA }, // 6
2277 { "gfx6.rom6", 0x80000, 0xaf7e057e, 5 | BRF_GRA }, // 7
2278 };
2279
2280 STD_ROM_PICK(uballoon)
2281 STD_ROM_FN(uballoon)
2282
2283 struct BurnDriver BurnDrvUballoon = {
2284 "uballoon", NULL, NULL, NULL, "1996",
2285 "Ultra Balloon\0", NULL, "SunA", "Miscellaneous",
2286 NULL, NULL, NULL, NULL,
2287 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PLATFORM, 0,
2288 NULL, uballoonRomInfo, uballoonRomName, NULL, NULL, NULL, NULL, UballoonInputInfo, uballoonDIPInfo,
2289 UballoonInit, DrvExit, UballoonFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
2290 256, 224, 4, 3
2291 };
2292
2293
2294 // Back Street Soccer
2295
2296 static struct BurnRomInfo bssoccerRomDesc[] = {
2297 { "02", 0x080000, 0x32871005, 1 | BRF_ESS | BRF_PRG }, // 0 - 68K Code
2298 { "01", 0x080000, 0xace00db6, 1 | BRF_ESS | BRF_PRG }, // 1
2299 { "04", 0x080000, 0x25ee404d, 1 | BRF_ESS | BRF_PRG }, // 2
2300 { "03", 0x080000, 0x1a131014, 1 | BRF_ESS | BRF_PRG }, // 3
2301
2302 { "11", 0x010000, 0xdf7ae9bc, 2 | BRF_ESS | BRF_PRG }, // 4 - Z80 #0 Code
2303
2304 { "13", 0x080000, 0x2b273dca, 3 | BRF_ESS | BRF_PRG }, // 5 - Z80 #1 Code
2305
2306 { "12", 0x080000, 0x6b73b87b, 4 | BRF_ESS | BRF_PRG }, // 6 - Z80 #0 Code
2307
2308 { "05", 0x080000, 0xa5245bd4, 5 | BRF_GRA }, // 7 - Sprites
2309 { "07", 0x080000, 0xfdb765c2, 5 | BRF_GRA }, // 8
2310 { "09", 0x080000, 0x0e82277f, 5 | BRF_GRA }, // 9
2311 { "06", 0x080000, 0xd42ce84b, 5 | BRF_GRA }, // 10
2312 { "08", 0x080000, 0x96cd2136, 5 | BRF_GRA }, // 11
2313 { "10", 0x080000, 0x1ca94d21, 5 | BRF_GRA }, // 12
2314 };
2315
2316 STD_ROM_PICK(bssoccer)
2317 STD_ROM_FN(bssoccer)
2318
2319 struct BurnDriver BurnDrvBssoccer = {
2320 "bssoccer", NULL, NULL, NULL, "1996",
2321 "Back Street Soccer\0", NULL, "SunA", "Miscellaneous",
2322 NULL, NULL, NULL, NULL,
2323 BDF_GAME_WORKING, 4, HARDWARE_MISC_POST90S, GBF_SPORTSFOOTBALL, 0,
2324 NULL, bssoccerRomInfo, bssoccerRomName, NULL, NULL, NULL, NULL, BssoccerInputInfo, bssoccerDIPInfo,
2325 BssoccerInit, DrvExit, BssoccerFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
2326 256, 224, 4, 3
2327 };
2328