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