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