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