1 // FB Alpha Tecmo Bowl driver module
2 // Based on MAME driver by David Haywood
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "burn_ym3812.h"
7 #include "msm5205.h"
8 
9 static UINT8 *AllMem;
10 static UINT8 *AllRam;
11 static UINT8 *RamEnd;
12 static UINT8 *MemEnd;
13 static UINT8 *DrvZ80ROM0;
14 static UINT8 *DrvZ80ROM1;
15 static UINT8 *DrvZ80ROM2;
16 static UINT8 *DrvGfxROM0;
17 static UINT8 *DrvGfxROM1;
18 static UINT8 *DrvGfxROM2;
19 static UINT8 *DrvGfxROM3;
20 static UINT8 *DrvSndROM;
21 static UINT8 *DrvZ80RAM0;
22 static UINT8 *DrvZ80RAM1;
23 static UINT8 *DrvZ80RAM2;
24 static UINT8 *DrvBgRAM2;
25 static UINT8 *DrvBgRAM;
26 static UINT8 *DrvTxRAM;
27 static UINT8 *DrvShareRAM;
28 static UINT8 *DrvPalRAM;
29 static UINT8 *DrvSprRAM;
30 
31 static UINT32 *DrvPalette;
32 static UINT8 DrvRecalc;
33 
34 static UINT8 *DrvBank;
35 static UINT8 *DrvScroll;
36 
37 static INT32 adpcm_data[2];
38 static INT32 adpcm_pos[2];
39 static INT32 adpcm_end[2];
40 
41 static UINT8 *soundlatch;
42 
43 static UINT8 DrvJoy1[8];
44 static UINT8 DrvJoy2[8];
45 static UINT8 DrvJoy3[8];
46 static UINT8 DrvJoy4[8];
47 static UINT8 DrvJoy5[8];
48 static UINT8 DrvDips[3];
49 static UINT8 DrvReset;
50 static UINT8 DrvInputs[5];
51 
52 static struct BurnInputInfo TbowlInputList[] = {
53 	{"P1 Coin",		BIT_DIGITAL,	DrvJoy5 + 0,	"p1 coin"	},
54 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 7,	"p1 start"	},
55 	{"P1 Up",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 up"		},
56 	{"P1 Down",		BIT_DIGITAL,	DrvJoy1 + 2,	"p1 down"	},
57 	{"P1 Left",		BIT_DIGITAL,	DrvJoy1 + 1,	"p1 left"	},
58 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 0,	"p1 right"	},
59 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
60 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
61 
62 	{"P2 Coin",		BIT_DIGITAL,	DrvJoy5 + 1,	"p2 coin"	},
63 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 7,	"p2 start"	},
64 	{"P2 Up",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 up"		},
65 	{"P2 Down",		BIT_DIGITAL,	DrvJoy2 + 2,	"p2 down"	},
66 	{"P2 Left",		BIT_DIGITAL,	DrvJoy2 + 1,	"p2 left"	},
67 	{"P2 Right",		BIT_DIGITAL,	DrvJoy2 + 0,	"p2 right"	},
68 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p2 fire 1"	},
69 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p2 fire 2"	},
70 
71 	{"P3 Coin",		BIT_DIGITAL,	DrvJoy5 + 2,	"p3 coin"	},
72 	{"P3 Start",		BIT_DIGITAL,	DrvJoy3 + 7,	"p3 start"	},
73 	{"P3 Up",		BIT_DIGITAL,	DrvJoy3 + 3,	"p3 up"		},
74 	{"P3 Down",		BIT_DIGITAL,	DrvJoy3 + 2,	"p3 down"	},
75 	{"P3 Left",		BIT_DIGITAL,	DrvJoy3 + 1,	"p3 left"	},
76 	{"P3 Right",		BIT_DIGITAL,	DrvJoy3 + 0,	"p3 right"	},
77 	{"P3 Button 1",		BIT_DIGITAL,	DrvJoy3 + 4,	"p3 fire 1"	},
78 	{"P3 Button 2",		BIT_DIGITAL,	DrvJoy3 + 5,	"p3 fire 2"	},
79 
80 	{"P4 Coin",		BIT_DIGITAL,	DrvJoy5 + 3,	"p4 coin"	},
81 	{"P4 Start",		BIT_DIGITAL,	DrvJoy4 + 7,	"p4 start"	},
82 	{"P4 Up",		BIT_DIGITAL,	DrvJoy4 + 3,	"p4 up"		},
83 	{"P4 Down",		BIT_DIGITAL,	DrvJoy4 + 2,	"p4 down"	},
84 	{"P4 Left",		BIT_DIGITAL,	DrvJoy4 + 1,	"p4 left"	},
85 	{"P4 Right",		BIT_DIGITAL,	DrvJoy4 + 0,	"p4 right"	},
86 	{"P4 Button 1",		BIT_DIGITAL,	DrvJoy4 + 4,	"p4 fire 1"	},
87 	{"P4 Button 2",		BIT_DIGITAL,	DrvJoy4 + 5,	"p4 fire 2"	},
88 
89 	{"Reset",		BIT_DIGITAL,	&DrvReset,	"reset"		},
90 	{"Service (General)",	BIT_DIGITAL,	DrvJoy5 + 4,	"service"	},
91 	{"Service 1",		BIT_DIGITAL,	DrvJoy1 + 6,	"service"	},
92 	{"Service 2",		BIT_DIGITAL,	DrvJoy2 + 6,	"service"	},
93 	{"Service 3",		BIT_DIGITAL,	DrvJoy3 + 6,	"service"	},
94 	{"Service 4",		BIT_DIGITAL,	DrvJoy4 + 6,	"service"	},
95 	{"Dip A",		BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
96 	{"Dip B",		BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
97 	{"Dip C",		BIT_DIPSWITCH,	DrvDips + 2,	"dip"		},
98 };
99 
100 STDINPUTINFO(Tbowl)
101 
102 static struct BurnDIPInfo TbowlDIPList[]=
103 {
104 	{0x26, 0xff, 0xff, 0xbf, NULL			},
105 	{0x27, 0xff, 0xff, 0xff, NULL			},
106 	{0x28, 0xff, 0xff, 0xff, NULL			},
107 
108 	{0   , 0xfe, 0   ,    8, "Coinage"		},
109 	{0x26, 0x01, 0x07, 0x00, "8 Coins 1 Credits"	},
110 	{0x26, 0x01, 0x07, 0x01, "7 Coins 1 Credits"	},
111 	{0x26, 0x01, 0x07, 0x02, "6 Coins 1 Credits"	},
112 	{0x26, 0x01, 0x07, 0x03, "5 Coins 1 Credits"	},
113 	{0x26, 0x01, 0x07, 0x04, "4 Coins 1 Credits"	},
114 	{0x26, 0x01, 0x07, 0x05, "3 Coins 1 Credits"	},
115 	{0x26, 0x01, 0x07, 0x06, "2 Coins 1 Credits"	},
116 	{0x26, 0x01, 0x07, 0x07, "1 Coin  1 Credits"	},
117 
118 	{0   , 0xfe, 0   ,   31, "Time (Players)"	},
119 	{0x26, 0x01, 0xf8, 0x00, "7:00"			},
120 	{0x26, 0x01, 0xf8, 0x08, "6:00"			},
121 	{0x26, 0x01, 0xf8, 0x10, "5:00"			},
122 	{0x26, 0x01, 0xf8, 0x18, "4:30"			},
123 	{0x26, 0x01, 0xf8, 0x20, "3:40"			},
124 	{0x26, 0x01, 0xf8, 0x28, "3:20"			},
125 	{0x26, 0x01, 0xf8, 0x30, "3:00"			},
126 	{0x26, 0x01, 0xf8, 0x38, "2:50"			},
127 	{0x26, 0x01, 0xf8, 0x40, "2:40"			},
128 	{0x26, 0x01, 0xf8, 0x48, "2:30"			},
129 	{0x26, 0x01, 0xf8, 0x50, "2:20"			},
130 	{0x26, 0x01, 0xf8, 0x58, "2:10"			},
131 	{0x26, 0x01, 0xf8, 0x60, "2:00"			},
132 	{0x26, 0x01, 0xf8, 0x68, "1:55"			},
133 	{0x26, 0x01, 0xf8, 0x70, "1:50"			},
134 	{0x26, 0x01, 0xf8, 0x78, "1:45"			},
135 	{0x26, 0x01, 0xf8, 0x80, "1:40"			},
136 	{0x26, 0x01, 0xf8, 0x88, "1:35"			},
137 	{0x26, 0x01, 0xf8, 0x90, "1:25"			},
138 	{0x26, 0x01, 0xf8, 0x98, "1:20"			},
139 	{0x26, 0x01, 0xf8, 0xa0, "1:15"			},
140 	{0x26, 0x01, 0xf8, 0xa8, "1:10"			},
141 	{0x26, 0x01, 0xf8, 0xb0, "1:05"			},
142 	{0x26, 0x01, 0xf8, 0xb8, "1:00"			},
143 	{0x26, 0x01, 0xf8, 0xc0, "0:55"			},
144 	{0x26, 0x01, 0xf8, 0xc8, "0:50"			},
145 	{0x26, 0x01, 0xf8, 0xd0, "0:45"			},
146 	{0x26, 0x01, 0xf8, 0xd8, "0:40"			},
147 	{0x26, 0x01, 0xf8, 0xe0, "0:35"			},
148 	{0x26, 0x01, 0xf8, 0xe8, "0:30"			},
149 	{0x26, 0x01, 0xf8, 0xf0, "0:25"			},
150 
151 	{0   , 0xfe, 0   ,    4, "Difficulty (unused ?)"},
152 	{0x27, 0x01, 0x03, 0x00, "0x00"			},
153 	{0x27, 0x01, 0x03, 0x01, "0x01"			},
154 	{0x27, 0x01, 0x03, 0x02, "0x02"			},
155 	{0x27, 0x01, 0x03, 0x03, "0x03"			},
156 
157 	{0   , 0xfe, 0   ,    4, "Extra Time (Players)"	},
158 	{0x27, 0x01, 0x0c, 0x00, "0:30"			},
159 	{0x27, 0x01, 0x0c, 0x04, "0:20"			},
160 	{0x27, 0x01, 0x0c, 0x08, "0:10"			},
161 	{0x27, 0x01, 0x0c, 0x0c, "None"			},
162 
163 	{0   , 0xfe, 0   ,    4, "Timer Speed"		},
164 	{0x27, 0x01, 0x30, 0x00, "56/60"		},
165 	{0x27, 0x01, 0x30, 0x10, "51/60"		},
166 	{0x27, 0x01, 0x30, 0x30, "47/60"		},
167 	{0x27, 0x01, 0x30, 0x20, "42/60"		},
168 
169 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
170 	{0x27, 0x01, 0x40, 0x00, "Off"			},
171 	{0x27, 0x01, 0x40, 0x40, "On"			},
172 
173 	{0   , 0xfe, 0   ,    2, "Hi-Score Reset"	},
174 	{0x27, 0x01, 0x80, 0x00, "Off"			},
175 	{0x27, 0x01, 0x80, 0x80, "On"			},
176 
177 	{0   , 0xfe, 0   ,    4, "Time (Quarter)"	},
178 	{0x28, 0x01, 0x03, 0x00, "8:00"			},
179 	{0x28, 0x01, 0x03, 0x01, "5:00"			},
180 	{0x28, 0x01, 0x03, 0x03, "4:00"			},
181 	{0x28, 0x01, 0x03, 0x02, "3:00"			},
182 };
183 
STDDIPINFO(Tbowl)184 STDDIPINFO(Tbowl)
185 
186 static void bankswitch(INT32 n, INT32 data)
187 {
188 	DrvBank[n] = data;
189 
190 	INT32 bank = 0x10000 + (data & 0xf8) * 256;
191 
192 	ZetMapMemory((n ? DrvZ80ROM1 : DrvZ80ROM0) + bank, 0xf000, 0xf7ff, MAP_ROM);
193 }
194 
tbowl_main_write(UINT16 address,UINT8 data)195 static void __fastcall tbowl_main_write(UINT16 address, UINT8 data)
196 {
197 	switch (address)
198 	{
199 		case 0xfc00:
200 			bankswitch(0, data);
201 		return;
202 
203 		case 0xfc03: // coin counter
204 		return;
205 
206 		case 0xfc0d:
207 			*soundlatch = data;
208 			ZetNmi(2);
209 		return;
210 	}
211 
212 	if ((address & 0xfff8) == 0xfc10) {
213 		DrvScroll[address & 0x07] = data;
214 		return;
215 	}
216 }
217 
tbowl_main_read(UINT16 address)218 static UINT8 __fastcall tbowl_main_read(UINT16 address)
219 {
220 	switch (address)
221 	{
222 		case 0xfc00:
223 			return DrvInputs[0];
224 
225 		case 0xfc01:
226 			return DrvInputs[1];
227 
228 		case 0xfc02:
229 			return DrvInputs[2];
230 
231 		case 0xfc03:
232 			return DrvInputs[3];
233 
234 		case 0xfc07:
235 			return DrvInputs[4];
236 
237 		case 0xfc08:
238 			return DrvDips[0];
239 
240 		case 0xfc09:
241 			return DrvDips[1];
242 
243 		case 0xfc0a:
244 			return DrvDips[2];
245 	}
246 
247 	return 0;
248 }
249 
tbowl_sub_write(UINT16 address,UINT8 data)250 static void __fastcall tbowl_sub_write(UINT16 address, UINT8 data)
251 {
252 	switch (address)
253 	{
254 		case 0xfc00:
255 			bankswitch(1, data);
256 		return;
257 
258 		case 0xfc02:
259 			ZetNmi(0);
260 		return;
261 	}
262 }
263 
tbowl_sound_write(UINT16 address,UINT8 data)264 static void __fastcall tbowl_sound_write(UINT16 address, UINT8 data)
265 {
266 	switch (address)
267 	{
268 		case 0xd000:
269 		case 0xd001:
270 			BurnYM3812Write(0, address & 1, data);
271 		return;
272 
273 		case 0xd800:
274 		case 0xd801:
275 			BurnYM3812Write(1, address & 1, data);
276 		return;
277 
278 		case 0xe000:
279 		case 0xe001:
280 			adpcm_end[address & 1] = (data + 1) << 8;
281 		return;
282 
283 		case 0xe002:
284 		case 0xe003:
285 			adpcm_pos[address & 1] = data << 8;
286 			MSM5205ResetWrite(address & 1, 0);
287 		return;
288 
289 		case 0xe004:
290 		case 0xe005:
291 			data &= 0x7f;
292 			MSM5205SetRoute(address & 1, (double)data / 0x7f, BURN_SND_ROUTE_BOTH);
293 		return;
294 	}
295 }
296 
tbowl_sound_read(UINT16 address)297 static UINT8 __fastcall tbowl_sound_read(UINT16 address)
298 {
299 	if (address == 0xe010) return *soundlatch;
300 
301 	return 0;
302 }
303 
tbowl_adpcm_int(INT32 num)304 static void tbowl_adpcm_int(INT32 num)
305 {
306 	if (adpcm_pos[num] >= adpcm_end[num] || adpcm_pos[num] >= 0x10000)
307 	{
308 		MSM5205ResetWrite(num, 1);
309 	}
310 	else if (adpcm_data[num] != -1)
311 	{
312 		MSM5205DataWrite(num, adpcm_data[num] & 0x0f);
313 		adpcm_data[num] = -1;
314 	}
315 	else
316 	{
317 		UINT8 *ROM = DrvSndROM + 0x10000 * num;
318 
319 		adpcm_data[num] = ROM[adpcm_pos[num]++ & 0xffff];
320 		MSM5205DataWrite(num, adpcm_data[num] >> 4);
321 	}
322 }
323 
tbowl_vclk_0()324 static void tbowl_vclk_0()
325 {
326 	tbowl_adpcm_int(0);
327 }
328 
tbowl_vclk_1()329 static void tbowl_vclk_1()
330 {
331 	tbowl_adpcm_int(1);
332 }
333 
DrvFMIRQHandler(int,INT32 nStatus)334 static void DrvFMIRQHandler(int, INT32 nStatus)
335 {
336 	ZetSetIRQLine(0, ((nStatus) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE));
337 }
338 
DrvSynchroniseStream(INT32 nSoundRate)339 static INT32 DrvSynchroniseStream(INT32 nSoundRate)
340 {
341 	return (INT64)ZetTotalCycles() * nSoundRate / 4000000;
342 }
343 
DrvDoReset()344 static INT32 DrvDoReset()
345 {
346 	memset (AllRam, 0, RamEnd - AllRam);
347 
348 	ZetOpen(0);
349 	ZetReset();
350 	bankswitch(0, 0);
351 	ZetClose();
352 
353 	ZetOpen(1);
354 	ZetReset();
355 	bankswitch(1, 0);
356 	ZetClose();
357 
358 	ZetOpen(2);
359 	ZetReset();
360 	BurnYM3812Reset();
361 	MSM5205Reset();
362 	ZetClose();
363 
364 	adpcm_pos[0] = adpcm_pos[1] = 0;
365 	adpcm_end[0] = adpcm_end[1] = 0;
366 	adpcm_data[0] = adpcm_data[1] = -1;
367 
368 	return 0;
369 }
370 
MemIndex()371 static INT32 MemIndex()
372 {
373 	UINT8 *Next; Next = AllMem;
374 
375 	DrvZ80ROM0	= Next; Next += 0x020000;
376 	DrvZ80ROM1	= Next; Next += 0x020000;
377 	DrvZ80ROM2	= Next; Next += 0x008000;
378 
379 	DrvGfxROM0	= Next; Next += 0x020000;
380 	DrvGfxROM1	= Next; Next += 0x100000;
381 	DrvGfxROM2	= Next; Next += 0x100000;
382 	DrvGfxROM3	= Next; Next += 0x100000;
383 
384 	DrvSndROM	= Next; Next += 0x020000;
385 
386 	DrvPalette	= (UINT32*)Next; Next += 0x00800 * sizeof(UINT32);
387 
388 	AllRam		= Next;
389 
390 	DrvZ80RAM0	= Next; Next += 0x02000;
391 	DrvZ80RAM1	= Next; Next += 0x01800;
392 	DrvZ80RAM2	= Next; Next += 0x00800;
393 
394 	DrvBgRAM2	= Next; Next += 0x02000;
395 	DrvBgRAM	= Next; Next += 0x02000;
396 	DrvTxRAM	= Next; Next += 0x01000;
397 	DrvShareRAM	= Next; Next += 0x00400;
398 
399 	DrvPalRAM	= Next; Next += 0x01000;
400 	DrvSprRAM	= Next; Next += 0x00800;
401 
402 	DrvBank		= Next; Next += 0x00002;
403 	DrvScroll	= Next; Next += 0x00008;
404 
405 	soundlatch	= Next; Next += 0x00001;
406 
407 	RamEnd		= Next;
408 	MemEnd		= Next;
409 
410 	return 0;
411 }
412 
DrvGfxDecode()413 static INT32 DrvGfxDecode()
414 {
415 	UINT8 *tmp = (UINT8*)BurnMalloc(0x80000);
416 	if (tmp == NULL) {
417 		return 1;
418 	}
419 
420 	static INT32 Planes[4] = { STEP4(0,1) };
421 	static INT32 XOffs[16] = { STEP8(0,4), STEP8(256,4) };
422 	static INT32 YOffs[16] = { STEP8(0,32), STEP8(512,32) };
423 
424 	memcpy (tmp, DrvGfxROM0, 0x10000);
425 
426 	GfxDecode(0x0800, 4,  8,  8, Planes, XOffs, YOffs, 0x100, tmp, DrvGfxROM0);
427 
428 	memcpy (tmp, DrvGfxROM1, 0x80000);
429 
430 	GfxDecode(0x1000, 4, 16, 16, Planes, XOffs, YOffs, 0x400, tmp, DrvGfxROM1);
431 
432 	memcpy (tmp, DrvGfxROM2, 0x80000);
433 
434 	GfxDecode(0x4000, 4,  8,  8, Planes, XOffs, YOffs, 0x100, tmp, DrvGfxROM2);
435 
436 	BurnFree (tmp);
437 
438 	return 0;
439 }
440 
DrvInit()441 static INT32 DrvInit()
442 {
443 	AllMem = NULL;
444 	MemIndex();
445 	INT32 nLen = MemEnd - (UINT8 *)0;
446 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
447 	memset(AllMem, 0, nLen);
448 	MemIndex();
449 
450 	{
451 		if (BurnLoadRom(DrvZ80ROM0 + 0x00000,  0, 1)) return 1;
452 		if (BurnLoadRom(DrvZ80ROM0 + 0x10000,  1, 1)) return 1;
453 
454 		if (BurnLoadRom(DrvZ80ROM1 + 0x00000,  2, 1)) return 1;
455 		if (BurnLoadRom(DrvZ80ROM1 + 0x10000,  3, 1)) return 1;
456 
457 		if (BurnLoadRom(DrvZ80ROM2 + 0x00000,  4, 1)) return 1;
458 
459 		if (BurnLoadRom(DrvGfxROM0 + 0x00000,  5, 2)) return 1;
460 		if (BurnLoadRom(DrvGfxROM0 + 0x00001,  6, 2)) return 1;
461 
462 		if (BurnLoadRom(DrvGfxROM1 + 0x40001,  7, 2)) return 1;
463 		if (BurnLoadRom(DrvGfxROM1 + 0x40000,  8, 2)) return 1;
464 		if (BurnLoadRom(DrvGfxROM1 + 0x00001,  9, 2)) return 1;
465 		if (BurnLoadRom(DrvGfxROM1 + 0x00000, 10, 2)) return 1;
466 		if (BurnLoadRom(DrvGfxROM1 + 0x60001, 11, 2)) return 1;
467 		if (BurnLoadRom(DrvGfxROM1 + 0x60000, 12, 2)) return 1;
468 		if (BurnLoadRom(DrvGfxROM1 + 0x20001, 13, 2)) return 1;
469 		if (BurnLoadRom(DrvGfxROM1 + 0x20000, 14, 2)) return 1;
470 
471 		if (BurnLoadRom(DrvGfxROM2 + 0x60001, 15, 2)) return 1;
472 		if (BurnLoadRom(DrvGfxROM2 + 0x60000, 16, 2)) return 1;
473 		if (BurnLoadRom(DrvGfxROM2 + 0x40001, 17, 2)) return 1;
474 		if (BurnLoadRom(DrvGfxROM2 + 0x40000, 18, 2)) return 1;
475 		if (BurnLoadRom(DrvGfxROM2 + 0x20001, 19, 2)) return 1;
476 		if (BurnLoadRom(DrvGfxROM2 + 0x20000, 20, 2)) return 1;
477 		if (BurnLoadRom(DrvGfxROM2 + 0x00001, 21, 2)) return 1;
478 		if (BurnLoadRom(DrvGfxROM2 + 0x00000, 22, 2)) return 1;
479 
480 		if (BurnLoadRom(DrvSndROM  + 0x00000, 23, 1)) return 1;
481 		if (BurnLoadRom(DrvSndROM  + 0x10000, 24, 1)) return 1;
482 
483 		DrvGfxDecode();
484 	}
485 
486 	ZetInit(0);
487 	ZetOpen(0);
488 	ZetMapMemory(DrvZ80ROM0,	0x0000, 0x7fff, MAP_ROM);
489 	ZetMapMemory(DrvZ80RAM0,	0x8000, 0x9fff, MAP_RAM);
490 	ZetMapMemory(DrvBgRAM2,		0xa000, 0xbfff, MAP_RAM);
491 	ZetMapMemory(DrvBgRAM,		0xc000, 0xdfff, MAP_RAM);
492 	ZetMapMemory(DrvTxRAM,		0xe000, 0xefff, MAP_RAM);
493 	ZetMapMemory(DrvShareRAM,	0xf800, 0xfbff, MAP_RAM);
494 	ZetSetWriteHandler(tbowl_main_write);
495 	ZetSetReadHandler(tbowl_main_read);
496 	ZetClose();
497 
498 	ZetInit(1);
499 	ZetOpen(1);
500 	ZetMapMemory(DrvZ80ROM1,	0x0000, 0xbfff, MAP_ROM);
501 	ZetMapMemory(DrvZ80RAM1,	0xc000, 0xd7ff, MAP_RAM);
502 	ZetMapMemory(DrvSprRAM,		0xd800, 0xdfff, MAP_RAM);
503 	ZetMapMemory(DrvPalRAM,		0xe000, 0xefff, MAP_RAM);
504 	ZetMapMemory(DrvShareRAM,	0xf800, 0xfbff, MAP_RAM);
505 	ZetSetWriteHandler(tbowl_sub_write);
506 	ZetClose();
507 
508 	ZetInit(2);
509 	ZetOpen(2);
510 	ZetMapMemory(DrvZ80ROM2,	0x0000, 0x7fff, MAP_ROM);
511 	ZetMapMemory(DrvZ80RAM2,	0xc000, 0xc7ff, MAP_RAM);
512 	ZetSetWriteHandler(tbowl_sound_write);
513 	ZetSetReadHandler(tbowl_sound_read);
514 	ZetClose();
515 
516 	BurnYM3812Init(2, 4000000, &DrvFMIRQHandler, &DrvSynchroniseStream, 0);
517 	BurnTimerAttachYM3812(&ZetConfig, 4000000);
518 	BurnYM3812SetRoute(0, BURN_SND_YM3812_ROUTE, 0.80, BURN_SND_ROUTE_BOTH);
519 	BurnYM3812SetRoute(1, BURN_SND_YM3812_ROUTE, 0.80, BURN_SND_ROUTE_BOTH);
520 
521 	MSM5205Init(0, DrvSynchroniseStream, 384000, tbowl_vclk_0, MSM5205_S48_4B, 1);
522 	MSM5205SetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
523 
524 	MSM5205Init(1, DrvSynchroniseStream, 384000, tbowl_vclk_1, MSM5205_S48_4B, 1);
525 	MSM5205SetRoute(1, 0.50, BURN_SND_ROUTE_BOTH);
526 
527 	GenericTilesInit();
528 
529 	DrvDoReset();
530 
531 	return 0;
532 }
533 
DrvExit()534 static INT32 DrvExit()
535 {
536 	GenericTilesExit();
537 
538 	MSM5205Exit();
539 	BurnYM3812Exit();
540 
541 	ZetExit();
542 
543 	BurnFree (AllMem);
544 
545 	return 0;
546 }
547 
DrvRecalcPalette()548 static inline void DrvRecalcPalette()
549 {
550 	UINT8 r,g,b;
551 	UINT16 *p = (UINT16*)DrvPalRAM;
552 	for (INT32 i = 0; i < 0x1000 / 2; i++) {
553 		UINT16 d = (p[i] << 8) | (p[i] >> 8);
554 
555 		g = (d >> 0) & 0x0f;
556 		r = (d >> 4) & 0x0f;
557 		b = (d >> 8) & 0x0f;
558 
559 		DrvPalette[i] = BurnHighCol((r << 4) | r, (g << 4) | g, (b << 4) | b, 0);
560 	}
561 }
562 
draw_background_layer(UINT8 * src,INT32 xr,INT32 coloff,UINT8 * scroll)563 static void draw_background_layer(UINT8 *src, INT32 xr, INT32 coloff, UINT8 *scroll)
564 {
565 	INT32 scrollx = ((scroll[1] << 8) | scroll[0]) & 0x7ff;
566 	INT32 scrolly = ((scroll[3] << 8) | scroll[2]) & 0x1ff;
567 
568 	for (INT32 offs = 0; offs < 128 * 32; offs++) {
569 		INT32 sx = (offs & 0x7f) << 4;
570 		INT32 sy = (offs >> 7) << 4;
571 
572 		sx -= scrollx;
573 		if (sx < -15) sx += 0x800;
574 		sy -= scrolly + 16;
575 		if (sy < -15) sy += 0x200;
576 
577 		if (sx >= nScreenWidth || sy >= nScreenHeight) continue;
578 
579 		INT32 attr = src[offs + 0x1000];
580 		INT32 code = src[offs] + ((attr & 0x0f) << 8);
581 		INT32 color= attr >> 4;
582 
583 		if (!code) continue;
584 
585 		Render16x16Tile_Mask_Clip(pTransDraw, code ^ xr, sx, sy, color, 4, 0, coloff, DrvGfxROM1);
586 	}
587 }
588 
draw_text_layer()589 static void draw_text_layer()
590 {
591 	for (INT32 offs = 0x80; offs < 0x780; offs++) {
592 		INT32 sx = (offs & 0x3f) << 3;
593 		INT32 sy = (offs >> 6) << 3;
594 
595 		INT32 attr = DrvTxRAM[offs + 0x800];
596 		INT32 code = DrvTxRAM[offs] | ((attr & 0x07) << 8);
597 		INT32 color= attr >> 4;
598 
599 		if (!code) continue;
600 
601 		Render8x8Tile_Mask_Clip(pTransDraw, code, sx, sy - 16, color, 4, 0, 0x100, DrvGfxROM0);
602 	}
603 }
604 
calc_sprite_offset(INT32 code,INT32 x,INT32 y)605 static inline INT32 calc_sprite_offset(INT32 code, INT32 x, INT32 y)
606 {
607 	INT32 ofst = ((y & 4) << 3) | ((x & 4) << 2) | ((y & 2) << 2) | ((x & 2) << 1) | ((y & 1) << 1) | (x & 1);
608 	return (ofst + code) & 0x3fff;
609 }
610 
draw_sprites()611 static void draw_sprites()
612 {
613 	for (INT32 offs = 0; offs < 0x800; offs+=8)
614 	{
615 		if (DrvSprRAM[offs+0] & 0x80)
616 		{
617 			INT32 code  = DrvSprRAM[offs + 2] | (DrvSprRAM[offs + 1] << 8);
618 			INT32 color = DrvSprRAM[offs + 3] & 0x1f;
619 			INT32 sizex = 1 << ((DrvSprRAM[offs] & 0x03));
620 			INT32 sizey = 1 << ((DrvSprRAM[offs] & 0x0c) >> 2);
621 
622 			INT32 flipx = DrvSprRAM[offs] & 0x20;
623 			INT32 xpos  = DrvSprRAM[offs + 6] | ((DrvSprRAM[offs + 4] & 0x03) << 8);
624 			INT32 ypos  = DrvSprRAM[offs + 5] | ((DrvSprRAM[offs + 4] & 0x10) << 4);
625 
626 			for (INT32 y = 0; y < sizey; y++)
627 			{
628 				for (INT32 x = 0; x < sizex; x++)
629 				{
630 					INT32 sx = xpos + 8 * (flipx ? (sizex - 1 - x) : x);
631 					INT32 sy = (ypos + 8 * y) - 16;
632 
633 					INT32 tile = calc_sprite_offset(code, x, y);
634 
635 					if (flipx) {
636 						Render8x8Tile_Mask_FlipX_Clip(pTransDraw, tile, sx,         sy,         color, 4, 0, 0, DrvGfxROM2);
637 						Render8x8Tile_Mask_FlipX_Clip(pTransDraw, tile, sx,         sy - 0x200, color, 4, 0, 0, DrvGfxROM2);
638 						Render8x8Tile_Mask_FlipX_Clip(pTransDraw, tile, sx - 0x400, sy,         color, 4, 0, 0, DrvGfxROM2);
639 						Render8x8Tile_Mask_FlipX_Clip(pTransDraw, tile, sx - 0x400, sy - 0x200, color, 4, 0, 0, DrvGfxROM2);
640 					}
641 					else
642 					{
643 						Render8x8Tile_Mask_Clip(pTransDraw, tile, sx,         sy,         color, 4, 0, 0, DrvGfxROM2);
644 						Render8x8Tile_Mask_Clip(pTransDraw, tile, sx,         sy - 0x200, color, 4, 0, 0, DrvGfxROM2);
645 						Render8x8Tile_Mask_Clip(pTransDraw, tile, sx - 0x400, sy,         color, 4, 0, 0, DrvGfxROM2);
646 						Render8x8Tile_Mask_Clip(pTransDraw, tile, sx - 0x400, sy - 0x200, color, 4, 0, 0, DrvGfxROM2);
647 					}
648 				}
649 			}
650 		}
651 	}
652 }
653 
DrvDraw()654 static INT32 DrvDraw()
655 {
656 	if (DrvRecalc) {
657 		DrvRecalcPalette();
658 	}
659 
660 	for (INT32 i = 0; i < nScreenWidth * nScreenHeight; i++) {
661 		pTransDraw[i] = 0x0100;
662 	}
663 
664 	draw_background_layer(DrvBgRAM,  0x000, 0x300, DrvScroll + 4);
665 	draw_sprites();
666 	draw_background_layer(DrvBgRAM2, 0x400, 0x200, DrvScroll + 0);
667 	draw_text_layer();
668 
669 	BurnTransferCopy(DrvPalette);
670 
671 	return 0;
672 }
673 
DrvClearOpposites(UINT8 * nJoystickInputs)674 static void DrvClearOpposites(UINT8* nJoystickInputs)
675 {
676 	if ((*nJoystickInputs & 0x03) == 0x00) {
677 		*nJoystickInputs |= 0x03;
678 	}
679 	if ((*nJoystickInputs & 0x0c) == 0x00) {
680 		*nJoystickInputs |= 0x0c;
681 	}
682 }
683 
DrvFrame()684 static INT32 DrvFrame()
685 {
686 	if (DrvReset) {
687 		DrvDoReset();
688 	}
689 
690 	{
691 		memset (DrvInputs, 0xff, 5);
692 		for (INT32 i = 0; i < 8; i++) {
693 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
694 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
695 			DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
696 			DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
697 			DrvInputs[4] ^= (DrvJoy5[i] & 1) << i;
698 		}
699 		DrvClearOpposites(&DrvInputs[0]);
700 		DrvClearOpposites(&DrvInputs[1]);
701 		DrvClearOpposites(&DrvInputs[2]);
702 		DrvClearOpposites(&DrvInputs[3]);
703 	}
704 
705 	ZetNewFrame();
706 
707 	INT32 nInterleave = 256;
708 	INT32 nCyclesTotal[3] = { 8000000 / 60, 8000000 / 60, 4000000 / 60 };
709 	INT32 nCyclesDone[3] = { 0, 0, 0 };
710 
711 	MSM5205NewFrame(0, 4000000, nInterleave);
712 
713 	for (INT32 i = 0; i < nInterleave; i++)
714 	{
715 		ZetOpen(0);
716 		nCyclesDone[0] += ZetRun((nCyclesTotal[0] * (i + 1) / nInterleave) - nCyclesDone[0]);
717 		if (i == (nInterleave-1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
718 		ZetClose();
719 
720 		ZetOpen(1);
721 		nCyclesDone[1] += ZetRun((nCyclesTotal[1] * (i + 1) / nInterleave) - nCyclesDone[1]);
722 		if (i == (nInterleave-1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
723 		ZetClose();
724 
725 		ZetOpen(2);
726 		BurnTimerUpdateYM3812((i + 1) * (nCyclesTotal[2] / nInterleave));
727 		MSM5205UpdateScanline(i);
728 		ZetClose();
729 	}
730 
731 	ZetOpen(2);
732 
733 	BurnTimerEndFrameYM3812(nCyclesTotal[2]);
734 
735 	if (pBurnSoundOut) {
736 		BurnYM3812Update(pBurnSoundOut, nBurnSoundLen);
737 		MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
738 		MSM5205Render(1, pBurnSoundOut, nBurnSoundLen);
739 	}
740 
741 	ZetClose();
742 
743 	if (pBurnDraw) {
744 		DrvDraw();
745 	}
746 
747 	return 0;
748 }
749 
DrvScan(INT32 nAction,INT32 * pnMin)750 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
751 {
752 	struct BurnArea ba;
753 
754 	if (pnMin) {
755 		*pnMin = 0x029702;
756 	}
757 
758 	if (nAction & ACB_VOLATILE) {
759 		memset(&ba, 0, sizeof(ba));
760 		ba.Data	  = AllRam;
761 		ba.nLen	  = RamEnd - AllRam;
762 		ba.szName = "All Ram";
763 		BurnAcb(&ba);
764 
765 		ZetScan(nAction);
766 		BurnYM3812Scan(nAction, pnMin);
767 		MSM5205Scan(nAction, pnMin);
768 
769 		SCAN_VAR(adpcm_data);
770 		SCAN_VAR(adpcm_pos);
771 		SCAN_VAR(adpcm_end);
772 	}
773 
774 	if (nAction & ACB_WRITE) {
775 		ZetOpen(0);
776 		bankswitch(0, DrvBank[0]);
777 		ZetClose();
778 
779 		ZetOpen(1);
780 		bankswitch(1, DrvBank[1]);
781 		ZetClose();
782 	}
783 
784 	return 0;
785 }
786 
787 
788 // Tecmo Bowl (World, set 1)
789 
790 static struct BurnRomInfo tbowlRomDesc[] = {
791 	{ "4.b11",			0x08000, 0xdb8a4f5d, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
792 	{ "6206b-5.b13",	0x10000, 0x133c5c11, 1 | BRF_PRG | BRF_ESS }, //  1
793 
794 	{ "6206c-24.h5",	0x10000, 0x040c8138, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
795 	{ "6206c-25.h7",	0x10000, 0x92c3cef5, 2 | BRF_PRG | BRF_ESS }, //  3
796 
797 	{ "6206a-1.f11",	0x08000, 0x4370207b, 3 | BRF_PRG | BRF_ESS }, //  4 Z80 #2 Code
798 
799 	{ "14.13l",			0x08000, 0xf9cf60b9, 4 | BRF_GRA },           //  5 Characters
800 	{ "15.15l",			0x08000, 0xa23f6c53, 4 | BRF_GRA },           //  6
801 
802 	{ "6206b-8.e1",		0x10000, 0xb9615ffa, 5 | BRF_GRA },           //  7 Tiles
803 	{ "6206b-8.e4",		0x10000, 0x6389c719, 5 | BRF_GRA },           //  8
804 	{ "6206b-7.e2",		0x10000, 0xd139c397, 5 | BRF_GRA },           //  9
805 	{ "6206b-9.e6",		0x10000, 0x975ded4c, 5 | BRF_GRA },           // 10
806 	{ "6206b-10.l1",	0x10000, 0x9b4fa82e, 5 | BRF_GRA },           // 11
807 	{ "6206b-12.l4",	0x10000, 0x7d0030f6, 5 | BRF_GRA },           // 12
808 	{ "6206b-11.l2",	0x10000, 0x06bf07bb, 5 | BRF_GRA },           // 13
809 	{ "6206b-13.l6",	0x10000, 0x4ad72c16, 5 | BRF_GRA },           // 14
810 
811 	{ "6206c-16.b11",	0x10000, 0x1a2fb925, 6 | BRF_GRA },           // 15 Sprites
812 	{ "6206c-20.d11",	0x10000, 0x70bb38a3, 6 | BRF_GRA },           // 16
813 	{ "6206c-17.b13",	0x10000, 0xde16bc10, 6 | BRF_GRA },           // 17
814 	{ "6206c-21.d13",	0x10000, 0x41b2a910, 6 | BRF_GRA },           // 18
815 	{ "6206c-18.b14",	0x10000, 0x0684e188, 6 | BRF_GRA },           // 19
816 	{ "6206c-22.d14",	0x10000, 0xcf660ebc, 6 | BRF_GRA },           // 20
817 	{ "6206c-19.b16",	0x10000, 0x71795604, 6 | BRF_GRA },           // 21
818 	{ "6206c-23.d16",	0x10000, 0x97fba168, 6 | BRF_GRA },           // 22
819 
820 	{ "6206a-3.l18",	0x10000, 0x3aa24744, 7 | BRF_SND },           // 23 Samples
821 	{ "6206a-2.l16",	0x10000, 0x1e9e5936, 7 | BRF_SND },           // 24
822 };
823 
824 STD_ROM_PICK(tbowl)
825 STD_ROM_FN(tbowl)
826 
827 struct BurnDriver BurnDrvTbowl = {
828 	"tbowl", NULL, NULL, NULL, "1987",
829 	"Tecmo Bowl (World, set 1)\0", NULL, "Tecmo", "hardware",
830 	NULL, NULL, NULL, NULL,
831 	BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
832 	NULL, tbowlRomInfo, tbowlRomName, NULL, NULL, NULL, NULL, TbowlInputInfo, TbowlDIPInfo,
833 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
834 	512, 224, 8, 3
835 };
836 
837 
838 // Tecmo Bowl (World, set 2)
839 
840 static struct BurnRomInfo tbowlaRomDesc[] = {
841 	{ "6206b-4.b11",	0x08000, 0x8c4260b1, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
842 	{ "6206b-5.b13",	0x10000, 0x133c5c11, 1 | BRF_PRG | BRF_ESS }, //  1
843 
844 	{ "6206c-24.h5",	0x10000, 0x040c8138, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
845 	{ "6206c-25.h7",	0x10000, 0x92c3cef5, 2 | BRF_PRG | BRF_ESS }, //  3
846 
847 	{ "6206a-1.f11",	0x08000, 0x4370207b, 3 | BRF_PRG | BRF_ESS }, //  4 Z80 #2 Code
848 
849 	{ "6206b-14.l13",	0x08000, 0xcf99d0bf, 4 | BRF_GRA },           //  5 Characters
850 	{ "6206b-15.l14",	0x08000, 0xd69248cf, 4 | BRF_GRA },           //  6
851 
852 	{ "6206b-8.e1",		0x10000, 0xb9615ffa, 5 | BRF_GRA },           //  7 Tiles
853 	{ "6206b-8.e4",		0x10000, 0x6389c719, 5 | BRF_GRA },           //  8
854 	{ "6206b-7.e2",		0x10000, 0xd139c397, 5 | BRF_GRA },           //  9
855 	{ "6206b-9.e6",		0x10000, 0x975ded4c, 5 | BRF_GRA },           // 10
856 	{ "6206b-10.l1",	0x10000, 0x9b4fa82e, 5 | BRF_GRA },           // 11
857 	{ "6206b-12.l4",	0x10000, 0x7d0030f6, 5 | BRF_GRA },           // 12
858 	{ "6206b-11.l2",	0x10000, 0x06bf07bb, 5 | BRF_GRA },           // 13
859 	{ "6206b-13.l6",	0x10000, 0x4ad72c16, 5 | BRF_GRA },           // 14
860 
861 	{ "6206c-16.b11",	0x10000, 0x1a2fb925, 6 | BRF_GRA },           // 15 Sprites
862 	{ "6206c-20.d11",	0x10000, 0x70bb38a3, 6 | BRF_GRA },           // 16
863 	{ "6206c-17.b13",	0x10000, 0xde16bc10, 6 | BRF_GRA },           // 17
864 	{ "6206c-21.d13",	0x10000, 0x41b2a910, 6 | BRF_GRA },           // 18
865 	{ "6206c-18.b14",	0x10000, 0x0684e188, 6 | BRF_GRA },           // 19
866 	{ "6206c-22.d14",	0x10000, 0xcf660ebc, 6 | BRF_GRA },           // 20
867 	{ "6206c-19.b16",	0x10000, 0x71795604, 6 | BRF_GRA },           // 21
868 	{ "6206c-23.d16",	0x10000, 0x97fba168, 6 | BRF_GRA },           // 22
869 
870 	{ "6206a-3.l18",	0x10000, 0x3aa24744, 7 | BRF_SND },           // 23 Samples
871 	{ "6206a-2.l16",	0x10000, 0x1e9e5936, 7 | BRF_SND },           // 24
872 };
873 
874 STD_ROM_PICK(tbowla)
875 STD_ROM_FN(tbowla)
876 
877 struct BurnDriver BurnDrvTbowla = {
878 	"tbowla", "tbowl", NULL, NULL, "1987",
879 	"Tecmo Bowl (World, set 2)\0", NULL, "Tecmo", "hardware",
880 	NULL, NULL, NULL, NULL,
881 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
882 	NULL, tbowlaRomInfo, tbowlaRomName, NULL, NULL, NULL, NULL, TbowlInputInfo, TbowlDIPInfo,
883 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
884 	512, 224, 8, 3
885 };
886 
887 
888 // Tecmo Bowl (World, prototype?)
889 // same as 'tbowl'
890 
891 static struct BurnRomInfo tbowlpRomDesc[] = {
892 	{ "4.b11",					0x08000, 0xdb8a4f5d, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
893 	{ "main_data_10-25.b13",	0x10000, 0x133c5c11, 1 | BRF_PRG | BRF_ESS }, //  1
894 
895 	// different to other sets
896 	{ "sub_pro_10-29.h5",		0x10000, 0x1933a3f0, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
897 	{ "sub_data_10-25.h7",		0x10000, 0x7277c852, 2 | BRF_PRG | BRF_ESS }, //  3
898 
899 	// this rom is quite strange, maybe damaged / badly programmed? areas which should be a 0x00 0x00 end up being
900 	// a 0x00 / 0xff alternating pattern, and there are some odd sounds at times.  It does however read consistently
901 	// and is a different revision of the code to the other sets, so it might be correct and we can't just replace it
902 	// with a rom from another set.
903 	{ "6206_sound_10-25.f11",	0x08000, 0x2158472d, 3 | BRF_PRG | BRF_ESS }, //  4 Z80 #2 Code
904 
905 	{ "14.13l",					0x08000, 0xf9cf60b9, 4 | BRF_GRA },           //  5 Characters
906 	{ "15.15l",					0x08000, 0xa23f6c53, 4 | BRF_GRA },           //  6
907 
908 	{ "6206b-8.e1",		0x10000, 0xb9615ffa, 5 | BRF_GRA },           //  7 Tiles
909 	{ "6206b-8.e4",		0x10000, 0x6389c719, 5 | BRF_GRA },           //  8
910 	{ "6206b-7.e2",		0x10000, 0xd139c397, 5 | BRF_GRA },           //  9
911 	{ "6206b-9.e6",		0x10000, 0x975ded4c, 5 | BRF_GRA },           // 10
912 	{ "6206b-10.l1",	0x10000, 0x9b4fa82e, 5 | BRF_GRA },           // 11
913 	{ "6206b-12.l4",	0x10000, 0x7d0030f6, 5 | BRF_GRA },           // 12
914 	{ "6206b-11.l2",	0x10000, 0x06bf07bb, 5 | BRF_GRA },           // 13
915 	{ "6206b-13.l6",	0x10000, 0x4ad72c16, 5 | BRF_GRA },           // 14
916 
917 	{ "sp_7_10-16.b11",			0x10000, 0x807af46a, 6 | BRF_GRA },           // 15 Sprites
918 	{ "sp_6_10-16.d11",			0x10000, 0x3c5654a9, 6 | BRF_GRA },           // 16
919 	{ "6206c-17.b13",			0x10000, 0xde16bc10, 6 | BRF_GRA },           // 17
920 	{ "6206c-21.d13",			0x10000, 0x41b2a910, 6 | BRF_GRA },           // 18
921 	{ "6206c-18.b14",			0x10000, 0x0684e188, 6 | BRF_GRA },           // 19
922 	{ "6206c-22.d14",			0x10000, 0xcf660ebc, 6 | BRF_GRA },           // 20
923 	{ "6206c-19.b16",			0x10000, 0x71795604, 6 | BRF_GRA },           // 21
924 	{ "6206c-23.d16",			0x10000, 0x97fba168, 6 | BRF_GRA },           // 22
925 
926 	{ "6206a-3.l18",			0x10000, 0x3aa24744, 7 | BRF_SND },           // 23 Samples
927 	{ "6206a-2.l16",			0x10000, 0x1e9e5936, 7 | BRF_SND },           // 24
928 };
929 
930 STD_ROM_PICK(tbowlp)
931 STD_ROM_FN(tbowlp)
932 
933 struct BurnDriver BurnDrvTbowlp = {
934 	"tbowlp", "tbowl", NULL, NULL, "1987",
935 	"Tecmo Bowl (World, prototype?)\0", NULL, "Tecmo", "hardware",
936 	NULL, NULL, NULL, NULL,
937 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
938 	NULL, tbowlpRomInfo, tbowlpRomName, NULL, NULL, NULL, NULL, TbowlInputInfo, TbowlDIPInfo,
939 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
940 	512, 224, 8, 3
941 };
942 
943 
944 // Tecmo Bowl (Japan)
945 
946 static struct BurnRomInfo tbowljRomDesc[] = {
947 	{ "6206b.4",		0x08000, 0x7ed3eff7, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
948 	{ "6206b.5",		0x10000, 0x133c5c11, 1 | BRF_PRG | BRF_ESS }, //  1
949 
950 	{ "6206c-24.h5",	0x10000, 0x040c8138, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
951 	{ "6206c-25.h7",	0x10000, 0x92c3cef5, 2 | BRF_PRG | BRF_ESS }, //  3
952 
953 	{ "6206a-1.f11",	0x08000, 0x4370207b, 3 | BRF_PRG | BRF_ESS }, //  4 Z80 #2 Code
954 
955 	{ "6206b-14.l13",	0x08000, 0xcf99d0bf, 4 | BRF_GRA },           //  5 Characters
956 	{ "6206b-15.l14",	0x08000, 0xd69248cf, 4 | BRF_GRA },           //  6
957 
958 	{ "6206b-8.e1",		0x10000, 0xb9615ffa, 5 | BRF_GRA },           //  7 Tiles
959 	{ "6206b-8.e4",		0x10000, 0x6389c719, 5 | BRF_GRA },           //  8
960 	{ "6206b-7.e2",		0x10000, 0xd139c397, 5 | BRF_GRA },           //  9
961 	{ "6206b-9.e6",		0x10000, 0x975ded4c, 5 | BRF_GRA },           // 10
962 	{ "6206b-10.l1",	0x10000, 0x9b4fa82e, 5 | BRF_GRA },           // 11
963 	{ "6206b-12.l4",	0x10000, 0x7d0030f6, 5 | BRF_GRA },           // 12
964 	{ "6206b-11.l2",	0x10000, 0x06bf07bb, 5 | BRF_GRA },           // 13
965 	{ "6206b-13.l6",	0x10000, 0x4ad72c16, 5 | BRF_GRA },           // 14
966 
967 	{ "6206c-16.b11",	0x10000, 0x1a2fb925, 6 | BRF_GRA },           // 15 Sprites
968 	{ "6206c-20.d11",	0x10000, 0x70bb38a3, 6 | BRF_GRA },           // 16
969 	{ "6206c-17.b13",	0x10000, 0xde16bc10, 6 | BRF_GRA },           // 17
970 	{ "6206c-21.d13",	0x10000, 0x41b2a910, 6 | BRF_GRA },           // 18
971 	{ "6206c-18.b14",	0x10000, 0x0684e188, 6 | BRF_GRA },           // 19
972 	{ "6206c-22.d14",	0x10000, 0xcf660ebc, 6 | BRF_GRA },           // 20
973 	{ "6206c-19.b16",	0x10000, 0x71795604, 6 | BRF_GRA },           // 21
974 	{ "6206c-23.d16",	0x10000, 0x97fba168, 6 | BRF_GRA },           // 22
975 
976 	{ "6206a-3.l18",	0x10000, 0x3aa24744, 7 | BRF_SND },           // 23 Samples
977 	{ "6206a-2.l16",	0x10000, 0x1e9e5936, 7 | BRF_SND },           // 24
978 };
979 
980 STD_ROM_PICK(tbowlj)
981 STD_ROM_FN(tbowlj)
982 
983 struct BurnDriver BurnDrvTbowlj = {
984 	"tbowlj", "tbowl", NULL, NULL, "1987",
985 	"Tecmo Bowl (Japan)\0", NULL, "Tecmo", "hardware",
986 	NULL, NULL, NULL, NULL,
987 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
988 	NULL, tbowljRomInfo, tbowljRomName, NULL, NULL, NULL, NULL, TbowlInputInfo, TbowlDIPInfo,
989 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
990 	512, 224, 8, 3
991 };
992