1 // FB Alpha Shanghai Kid / Chinese Hero / Dynamic Ski driver module
2 // Based on MAME driver by Phil Stroffolino
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "ay8910.h"
7 #include "dac.h"
8 
9 static UINT8 *AllMem;
10 static UINT8 *AllRam;
11 static UINT8 *RamEnd;
12 static UINT8 *MemEnd;
13 static UINT8 *DrvZ80ROM[3];
14 static UINT8 *DrvGfxROM0;
15 static UINT8 *DrvGfxROM1;
16 static UINT8 *DrvGfxROM2;
17 static UINT8 *DrvColPROM;
18 static UINT8 *DrvShareRAM;
19 static UINT8 *DrvVidRAM;
20 static UINT8 *DrvSprRAM;
21 static UINT8 *DrvZ80RAM;
22 
23 static UINT32 *DrvPalette;
24 static UINT8 DrvRecalc;
25 
26 static UINT8 *video_regs;
27 
28 static INT32 soundlatch;
29 static INT32 bankdata;
30 static INT32 soundbank;
31 
32 static INT32 irq[2];
33 static INT32 nmi[2];
34 
35 static UINT8 DrvJoy1[8];
36 static UINT8 DrvJoy2[8];
37 static UINT8 DrvJoy3[8];
38 static UINT8 DrvDips[1];
39 static UINT8 DrvInputs[3];
40 static UINT8 DrvReset;
41 
42 static INT32 is_game; // 0 chinhero, 1 shangkid
43 
44 static struct BurnInputInfo DynamskiInputList[] = {
45 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 coin"	},
46 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 start"	},
47 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 left"	},
48 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 1,	"p1 right"	},
49 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p1 fire 1"	},
50 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p1 fire 2"	},
51 
52 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p2 coin"	},
53 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 4,	"p2 start"	},
54 	{"P2 Left",			BIT_DIGITAL,	DrvJoy3 + 0,	"p2 left"	},
55 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 1,	"p2 right"	},
56 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 4,	"p2 fire 1"	},
57 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy3 + 5,	"p2 fire 2"	},
58 
59 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
60 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 2,	"service"	},
61 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
62 };
63 
64 STDINPUTINFO(Dynamski)
65 
66 static struct BurnInputInfo ShangkidInputList[] = {
67 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 coin"	},
68 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 start"	},
69 	{"P1 Up",			BIT_DIGITAL,	DrvJoy2 + 6,	"p1 up"		},
70 	{"P1 Down",			BIT_DIGITAL,	DrvJoy2 + 7,	"p1 down"	},
71 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 4,	"p1 left"	},
72 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 5,	"p1 right"	},
73 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 1,	"p1 fire 1"	},
74 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy2 + 0,	"p1 fire 2"	},
75 
76 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p2 coin"	},
77 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 4,	"p2 start"	},
78 	{"P2 Up",			BIT_DIGITAL,	DrvJoy3 + 6,	"p2 up"		},
79 	{"P2 Down",			BIT_DIGITAL,	DrvJoy3 + 7,	"p2 down"	},
80 	{"P2 Left",			BIT_DIGITAL,	DrvJoy3 + 4,	"p2 left"	},
81 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 5,	"p2 right"	},
82 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 1,	"p2 fire 1"	},
83 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy3 + 0,	"p2 fire 2"	},
84 
85 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
86 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 2,	"service"	},
87 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
88 };
89 
90 STDINPUTINFO(Shangkid)
91 
92 static struct BurnInputInfo ChinheroInputList[] = {
93 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 coin"	},
94 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 start"	},
95 	{"P1 Up",			BIT_DIGITAL,	DrvJoy2 + 2,	"p1 up"		},
96 	{"P1 Down",			BIT_DIGITAL,	DrvJoy2 + 3,	"p1 down"	},
97 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 left"	},
98 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 1,	"p1 right"	},
99 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p1 fire 1"	},
100 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p1 fire 2"	},
101 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy2 + 6,	"p1 fire 3"	},
102 	{"P1 Button 4",		BIT_DIGITAL,	DrvJoy2 + 7,	"p1 fire 4"	},
103 
104 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p2 coin"	},
105 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 4,	"p2 start"	},
106 	{"P2 Up",			BIT_DIGITAL,	DrvJoy3 + 2,	"p2 up"		},
107 	{"P2 Down",			BIT_DIGITAL,	DrvJoy3 + 3,	"p2 down"	},
108 	{"P2 Left",			BIT_DIGITAL,	DrvJoy3 + 0,	"p2 left"	},
109 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 1,	"p2 right"	},
110 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 4,	"p2 fire 1"	},
111 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy3 + 5,	"p2 fire 2"	},
112 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy3 + 6,	"p2 fire 3"	},
113 	{"P2 Button 4",		BIT_DIGITAL,	DrvJoy3 + 7,	"p2 fire 4"	},
114 
115 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
116 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 2,	"service"	},
117 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
118 };
119 
120 STDINPUTINFO(Chinhero)
121 
122 static struct BurnDIPInfo DynamskiDIPList[]=
123 {
124 	DIP_OFFSET(0x0e)
125 	{0x00, 0xff, 0xff, 0x05, NULL					},
126 
127 	{0   , 0xfe, 0   ,    3, "Unknown"				},
128 	{0x00, 0x01, 0x03, 0x01, "A"					},
129 	{0x00, 0x01, 0x03, 0x02, "B"					},
130 	{0x00, 0x01, 0x03, 0x03, "C"					},
131 
132 	{0   , 0xfe, 0   ,    2, "Cabinet"				},
133 	{0x00, 0x01, 0x04, 0x04, "Upright"				},
134 	{0x00, 0x01, 0x04, 0x00, "Cocktail"				},
135 
136 	{0   , 0xfe, 0   ,    4, "Coinage"				},
137 	{0x00, 0x01, 0x18, 0x18, "3 Coins 1 Credits"	},
138 	{0x00, 0x01, 0x18, 0x10, "2 Coins 1 Credits"	},
139 	{0x00, 0x01, 0x18, 0x00, "1 Coin  1 Credits"	},
140 	{0x00, 0x01, 0x18, 0x08, "1 Coin  2 Credits"	},
141 };
142 
143 STDDIPINFO(Dynamski)
144 
145 static struct BurnDIPInfo ChinheroDIPList[]=
146 {
147 	DIP_OFFSET(0x16)
148 	{0x00, 0xff, 0xff, 0x01, NULL					},
149 
150 	{0   , 0xfe, 0   ,    4, "Lives"				},
151 	{0x00, 0x01, 0x03, 0x01, "3"					},
152 	{0x00, 0x01, 0x03, 0x02, "4"					},
153 	{0x00, 0x01, 0x03, 0x03, "5"					},
154 	{0x00, 0x01, 0x03, 0x00, "Infinite (Cheat)"		},
155 
156 	{0   , 0xfe, 0   ,    2, "Unknown"				},
157 	{0x00, 0x01, 0x04, 0x00, "Off"					},
158 	{0x00, 0x01, 0x04, 0x04, "On"					},
159 
160 	{0   , 0xfe, 0   ,    4, "Coinage"				},
161 	{0x00, 0x01, 0x18, 0x18, "3 Coins 1 Credits"	},
162 	{0x00, 0x01, 0x18, 0x10, "2 Coins 1 Credits"	},
163 	{0x00, 0x01, 0x18, 0x00, "1 Coin  1 Credits"	},
164 	{0x00, 0x01, 0x18, 0x08, "1 Coin  2 Credits"	},
165 
166 	{0   , 0xfe, 0   ,    2, "Demo Sounds"			},
167 	{0x00, 0x01, 0x20, 0x20, "Off"					},
168 	{0x00, 0x01, 0x20, 0x00, "On"					},
169 
170 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
171 	{0x00, 0x01, 0xc0, 0x00, "Easy"					},
172 	{0x00, 0x01, 0xc0, 0x40, "Medium"				},
173 	{0x00, 0x01, 0xc0, 0x80, "Hard"					},
174 	{0x00, 0x01, 0xc0, 0xc0, "Hardest"				},
175 };
176 
177 STDDIPINFO(Chinhero)
178 
179 static struct BurnDIPInfo ShangkidDIPList[]=
180 {
181 	DIP_OFFSET(0x12)
182 	{0x00, 0xff, 0xff, 0x06, NULL					},
183 
184 	{0   , 0xfe, 0   ,    2, "Unknown"				},
185 	{0x00, 0x01, 0x01, 0x01, "Off"					},
186 	{0x00, 0x01, 0x01, 0x00, "On"					},
187 
188 	{0   , 0xfe, 0   ,    2, "Cabinet"				},
189 	{0x00, 0x01, 0x02, 0x02, "Upright"				},
190 	{0x00, 0x01, 0x02, 0x00, "Cocktail"				},
191 
192 	{0   , 0xfe, 0   ,    8, "Coinage"				},
193 	{0x00, 0x01, 0x1c, 0x10, "4 Coins 1 Credits"	},
194 	{0x00, 0x01, 0x1c, 0x0c, "3 Coins 1 Credits"	},
195 	{0x00, 0x01, 0x1c, 0x08, "2 Coins 1 Credits"	},
196 	{0x00, 0x01, 0x1c, 0x00, "1 Coin/1 Credit without coin counter"	},
197 	{0x00, 0x01, 0x1c, 0x04, "1 Coin  1 Credits"	},
198 	{0x00, 0x01, 0x1c, 0x14, "1 Coin  2 Credits"	},
199 	{0x00, 0x01, 0x1c, 0x18, "1 Coin  3 Credits"	},
200 	{0x00, 0x01, 0x1c, 0x1c, "1 Coin  5 Credits"	},
201 
202 	{0   , 0xfe, 0   ,    2, "Demo Sounds"			},
203 	{0x00, 0x01, 0x20, 0x20, "Off"					},
204 	{0x00, 0x01, 0x20, 0x00, "On"					},
205 
206 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
207 	{0x00, 0x01, 0xc0, 0x00, "Easy"					},
208 	{0x00, 0x01, 0xc0, 0x40, "Medium"				},
209 	{0x00, 0x01, 0xc0, 0x80, "Hard"					},
210 	{0x00, 0x01, 0xc0, 0xc0, "Hardest"				},
211 };
212 
STDDIPINFO(Shangkid)213 STDDIPINFO(Shangkid)
214 
215 static void bankswitch(INT32 data)
216 {
217 	bankdata = data;
218 
219 	ZetMapMemory(DrvZ80ROM[0] + 0x8000 + (data & 1) * 0x2000, 0x8000, 0x9fff, MAP_ROM);
220 }
221 
chinhero_main_write(UINT16 address,UINT8 data)222 static void __fastcall chinhero_main_write(UINT16 address, UINT8 data)
223 {
224 	switch (address)
225 	{
226 		case 0xa000:
227 			if (nmi[0]) {
228 				ZetSetIRQLine(0, 0x20, CPU_IRQSTATUS_ACK);
229 			}
230 		return;
231 
232 		case 0xa800:
233 			if (nmi[1]) {
234 				ZetSetIRQLine(1, 0x20, CPU_IRQSTATUS_ACK);
235 			}
236 		return;
237 
238 		case 0xb000:
239 			ZetSetRESETLine(1, (data ? 0 : 1));
240 		return;
241 
242 		case 0xb001:
243 			ZetSetRESETLine(2, (data ? 0 : 1));
244 		return;
245 
246 		case 0xb002:
247 			irq[0] = data;
248 			if (!data) {
249 				ZetSetIRQLine(0, 0, CPU_IRQSTATUS_NONE);
250 			}
251 		return;
252 
253 		case 0xb003:
254 			irq[1] = data;
255 			if (!data) {
256 				ZetSetIRQLine(1, 0, CPU_IRQSTATUS_NONE);
257 			}
258 		return;
259 
260 		case 0xb004:
261 			nmi[0] = data;
262 			if (!data) {
263 				ZetSetIRQLine(0, 0x20, CPU_IRQSTATUS_NONE);
264 			}
265 		return;
266 
267 		case 0xb005:
268 			nmi[1] = data;
269 			if (!data) {
270 				ZetSetIRQLine(1, 0x20, CPU_IRQSTATUS_NONE);
271 			}
272 		return;
273 
274 		case 0xb006:
275 			// nop
276 		return;
277 
278 		case 0xb007: // shangkid (cpu#0 only)
279 			if (is_game == 1) {
280 				bankswitch(data & 1);
281 			}
282 		return;
283 
284 		case 0xc000:
285 		case 0xc001:
286 		case 0xc002:
287 			video_regs[address & 3] = data;
288 		return;
289 	}
290 }
291 
chinhero_main_read(UINT16 address)292 static UINT8 __fastcall chinhero_main_read(UINT16 address)
293 {
294 	switch (address)
295 	{
296 		case 0xb800:
297 			return DrvDips[0];
298 
299 		case 0xb801:
300 			return DrvInputs[0] | ((is_game == 1) ? 0x80 : 0x00); // sys -shangkid needs this bit set
301 
302 		case 0xb802:
303 			return DrvInputs[2]; // p2
304 
305 		case 0xb803:
306 			return DrvInputs[1]; // p1
307 	}
308 
309 	return 0;
310 }
311 
chinhero_main_write_port(UINT16 port,UINT8 data)312 static void __fastcall chinhero_main_write_port(UINT16 port, UINT8 data)
313 {
314 	switch (port & 0xff)
315 	{
316 		case 0x00:
317 		case 0x01:
318 			AY8910Write(0, port & 1, data);
319 		return;
320 	}
321 }
322 
dynamski_write(UINT16 address,UINT8 data)323 static void __fastcall dynamski_write(UINT16 address, UINT8 data)
324 {
325 	switch (address)
326 	{
327 		case 0xe000:
328 			irq[0] = data;
329 			if (!data) {
330 				ZetSetIRQLine(0, 0, CPU_IRQSTATUS_NONE);
331 			}
332 		return;
333 
334 		case 0xe001:
335 		case 0xe002: // flipsc?
336 			video_regs[address - 0xe001] = data;
337 			return;
338 	}
339 }
340 
dynamski_read(UINT16 address)341 static UINT8 __fastcall dynamski_read(UINT16 address)
342 {
343 	switch (address)
344 	{
345 		case 0xe800:
346 			return DrvInputs[0]; // sys
347 
348 		case 0xe801:
349 			return DrvInputs[1]; // p1
350 
351 		case 0xe802:
352 			return DrvInputs[2]; // p2
353 
354 		case 0xe803:
355 			return DrvDips[0];
356 	}
357 
358 	return 0;
359 }
360 
dynamski_main_write_port(UINT16 port,UINT8 data)361 static void __fastcall dynamski_main_write_port(UINT16 port, UINT8 data)
362 {
363 	switch (port & 0xff)
364 	{
365 		case 0x00:
366 		case 0x01:
367 			AY8910Write(0, ~port & 1, data);
368 		return;
369 	}
370 }
371 
chinhero_sound_write_port(UINT16 port,UINT8 data)372 static void __fastcall chinhero_sound_write_port(UINT16 port, UINT8 data)
373 {
374 	switch (port & 0xff)
375 	{
376 		case 0:
377 			DACSignedWrite(0, data);
378 		return;
379 	}
380 }
381 
chinhero_sound_read_port(UINT16 port)382 static UINT8 __fastcall chinhero_sound_read_port(UINT16 port)
383 {
384 	switch (port & 0xff)
385 	{
386 		case 0:
387 			ZetSetIRQLine(2, 0, CPU_IRQSTATUS_NONE);
388 			return soundlatch;
389 	}
390 
391 	return 0;
392 }
393 
sound_bankswitch(INT32 data)394 static void sound_bankswitch(INT32 data)
395 {
396 	soundbank = data;
397 
398 	ZetMapMemory(DrvZ80ROM[2] + (soundbank * 0x10000), 0x0000, 0xdfff, MAP_ROM);
399 }
400 
ay8910_portA_write(UINT32,UINT32 data)401 static void ay8910_portA_write(UINT32 /*addr*/, UINT32 data)
402 {
403 	if (data & 1) ZetSetIRQLine(2, 0, CPU_IRQSTATUS_HOLD);
404 
405 	if (is_game == 1) { // shangkid
406 		ZetCPUPush(2);
407 		sound_bankswitch((data & ~1) ? 0 : 1);
408 		ZetCPUPop();
409 	}
410 }
411 
ay8910_portB_write(UINT32,UINT32 data)412 static void ay8910_portB_write(UINT32 /*addr*/, UINT32 data)
413 {
414 	soundlatch = data;
415 }
416 
tilemap_callback(skbg)417 static tilemap_callback( skbg )
418 {
419 	INT32 attr  = DrvVidRAM[offs + 0x800];
420 	INT32 code  = DrvVidRAM[offs] + attr * 256;
421 	INT32 color = ((attr >> 3) & 3) | ((attr >> 2) & 0x38);
422 	INT32 group = TILE_GROUP((DrvColPROM[0x800 + color * 4] == 2) ? 1 : 0);
423 
424 	TILE_SET_INFO(0, code, color, ((attr & 0x04) ? TILE_FLIPX : 0) | group);
425 }
426 
tilemap_callback(chbg)427 static tilemap_callback( chbg )
428 {
429 	INT32 attr  = DrvVidRAM[offs + 0x800];
430 	INT32 code  = DrvVidRAM[offs] + attr * 256;
431 	INT32 color = (attr >> 2) & 0x1f;
432 	INT32 group = TILE_GROUP((DrvColPROM[0x800 + color * 4] == 2) ? 1 : 0);
433 
434 	TILE_SET_INFO(0, code, color, ((attr & 0x80) ? TILE_FLIPX : 0) | group);
435 }
436 
DrvDoReset()437 static INT32 DrvDoReset()
438 {
439 	memset (AllRam, 0, RamEnd - AllRam);
440 
441 	ZetReset(0);
442 	ZetSetRESETLine(1, 1);
443 	ZetSetRESETLine(2, 1);
444 
445 	AY8910Reset(0);
446 	DACReset();
447 
448 	soundlatch = 0;
449 
450 	irq[0] = irq[1] = 0;
451 	nmi[0] = nmi[1] = 0;
452 
453 	return 0;
454 }
455 
MemIndex()456 static INT32 MemIndex()
457 {
458 	UINT8 *Next; Next = AllMem;
459 
460 	DrvZ80ROM[0]		= Next; Next += 0x010000;
461 	DrvZ80ROM[1]		= Next; Next += 0x010000;
462 	DrvZ80ROM[2]		= Next; Next += 0x020000;
463 
464 	DrvGfxROM0			= Next; Next += 0x010000;
465 	DrvGfxROM1			= Next; Next += 0x060000;
466 	DrvGfxROM2			= Next; Next += 0x040000; // temp
467 
468 	DrvColPROM			= Next; Next += 0x000b00;
469 
470 	DrvPalette			= (UINT32*)Next; Next += 0x100 * sizeof(UINT32);
471 
472 	AllRam				= Next;
473 
474 	DrvShareRAM			= Next; Next += 0x002e00;
475 	DrvVidRAM			= Next; Next += 0x001000;
476 	DrvSprRAM			= Next; Next += 0x001000; // 0x200 shangkid,chinhero, 0xc00 dynamski
477 	DrvZ80RAM			= Next; Next += 0x001000;
478 
479 	video_regs			= Next; Next += 0x000004;
480 
481 	RamEnd				= Next;
482 
483 	MemEnd				= Next;
484 
485 	return 0;
486 }
487 
DrvGfxDecode(UINT8 * src,UINT8 * dst,INT32 len,INT32 num,INT32 type)488 static INT32 DrvGfxDecode(UINT8 *src, UINT8 *dst, INT32 len, INT32 num, INT32 type)
489 {
490 	INT32 Plane[4][3] = { { 0, 4 }, { 0, 4 }, { 0x8000*8+4, 0, 4 }, { 0x8000*8, 0x4000*8+0, 0x4000*8+4 } };
491 	INT32 XOffs[16] = { STEP4(0,1), STEP4(8,1), STEP4(128,1), STEP4(128+8,1) };
492 	INT32 YOffs[16] = { STEP8(0,16), STEP8(256,16) };
493 
494 	UINT8 *tmp = (UINT8*)BurnMalloc(len);
495 	if (tmp == NULL) {
496 		return 1;
497 	}
498 
499 	for (INT32 i = 0; i < len; i++) tmp[i] = src[i] ^ 0xff;
500 
501 	GfxDecode(num, (type < 2) ? 2 : 3, (type > 0) ? 16 : 8, (type > 0) ? 16 : 8, Plane[type], XOffs, YOffs, (type > 0) ? 0x200 : 0x80, tmp, dst);
502 
503 	BurnFree(tmp);
504 
505 	return 0;
506 }
507 
DrvGfxDecodeCH(UINT8 * src,UINT8 * dst,INT32 num)508 static INT32 DrvGfxDecodeCH(UINT8 *src, UINT8 *dst, INT32 num)
509 {
510 	INT32 Plane[2][3] = { { 0x4000*8+4, 0, 4 }, { 0x4000*8, 0x2000*8+0, 0x2000*8+4 } };
511 	INT32 XOffs[16] = { STEP4(0,1), STEP4(8,1), STEP4(128,1), STEP4(128+8,1) };
512 	INT32 YOffs[16] = { STEP8(0,16), STEP8(256,16) };
513 
514 	UINT8 *tmp = (UINT8*)BurnMalloc(0x20000);
515 	if (tmp == NULL) {
516 		return 1;
517 	}
518 
519 	for (INT32 i = 0; i < 0x20000; i++) tmp[i] = src[i] ^ 0xff;
520 
521 	GfxDecode(num, 3, 16, 16, Plane[0], XOffs, YOffs, 0x200, tmp + 0x00000, dst + (16*16*num*0));
522 	GfxDecode(num, 3, 16, 16, Plane[1], XOffs, YOffs, 0x200, tmp + 0x00000, dst + (16*16*num*2));
523 
524 	GfxDecode(num, 3, 16, 16, Plane[0], XOffs, YOffs, 0x200, tmp + 0x10000, dst + (16*16*num*1));
525 	GfxDecode(num, 3, 16, 16, Plane[1], XOffs, YOffs, 0x200, tmp + 0x10000, dst + (16*16*num*3));
526 
527 	BurnFree(tmp);
528 
529 	return 0;
530 }
531 
maincpu_init(INT32 cpu)532 static void maincpu_init(INT32 cpu)
533 {
534 	ZetInit(cpu);
535 	ZetOpen(cpu);
536 	ZetMapMemory(DrvZ80ROM[cpu],	0x0000, 0x9fff, MAP_ROM);
537 	// 8000-9fff banked in shangkid (main cpu)
538 	ZetMapMemory(DrvVidRAM,		0xd000, 0xdfff, MAP_RAM);
539 	ZetMapMemory(DrvShareRAM,	0xe000, 0xfdff, MAP_RAM);
540 	ZetMapMemory(DrvSprRAM,		0xfe00, 0xffff, MAP_RAM);
541 	ZetSetWriteHandler(chinhero_main_write);
542 	ZetSetReadHandler(chinhero_main_read);
543 	if (cpu == 1) {
544 		ZetSetOutHandler(chinhero_main_write_port);
545 	}
546 	ZetClose();
547 }
548 
DrvInit(INT32 game,INT32 load_type)549 static INT32 DrvInit(INT32 game, INT32 load_type)
550 {
551 	BurnAllocMemIndex();
552 
553 	GenericTilesInit();
554 
555 	is_game = game;
556 
557 	INT32 k = 0;
558 	if (game == 0 && load_type == 0) // chinhero
559 	{
560 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
561 		if (BurnLoadRom(DrvZ80ROM[0] + 0x02000, k++, 1)) return 1;
562 		if (BurnLoadRom(DrvZ80ROM[0] + 0x04000, k++, 1)) return 1;
563 		if (BurnLoadRom(DrvZ80ROM[0] + 0x06000, k++, 1)) return 1;
564 		if (BurnLoadRom(DrvZ80ROM[0] + 0x08000, k++, 1)) return 1;
565 
566 		if (BurnLoadRom(DrvZ80ROM[1] + 0x00000, k++, 1)) return 1;
567 		if (BurnLoadRom(DrvZ80ROM[1] + 0x02000, k++, 1)) return 1;
568 
569 		if (BurnLoadRom(DrvZ80ROM[2] + 0x00000, k++, 1)) return 1;
570 		if (BurnLoadRom(DrvZ80ROM[2] + 0x02000, k++, 1)) return 1;
571 		if (BurnLoadRom(DrvZ80ROM[2] + 0x04000, k++, 1)) return 1;
572 
573 		if (BurnLoadRom(DrvGfxROM0 + 0x00000, k++, 1)) return 1;
574 		if (BurnLoadRom(DrvGfxROM0 + 0x02000, k++, 1)) return 1;
575 
576 		if (BurnLoadRom(DrvGfxROM2 + 0x00000, k++, 1)) return 1; // load temp
577 		if (BurnLoadRom(DrvGfxROM2 + 0x02000, k++, 1)) return 1;
578 		if (BurnLoadRom(DrvGfxROM2 + 0x04000, k++, 1)) return 1;
579 		if (BurnLoadRom(DrvGfxROM2 + 0x10000, k++, 1)) return 1;
580 		if (BurnLoadRom(DrvGfxROM2 + 0x12000, k++, 1)) return 1;
581 		if (BurnLoadRom(DrvGfxROM2 + 0x14000, k++, 1)) return 1;
582 
583 		if (BurnLoadRom(DrvColPROM   + 0x00000, k++, 1)) return 1;
584 		if (BurnLoadRom(DrvColPROM   + 0x00100, k++, 1)) return 1;
585 		if (BurnLoadRom(DrvColPROM   + 0x00200, k++, 1)) return 1;
586 		if (BurnLoadRom(DrvColPROM   + 0x00300, k++, 1)) return 1;
587 		if (BurnLoadRom(DrvColPROM   + 0x00400, k++, 1)) return 1;
588 		if (BurnLoadRom(DrvColPROM   + 0x00600, k++, 1)) return 1;
589 		if (BurnLoadRom(DrvColPROM   + 0x00800, k++, 1)) return 1;
590 		if (BurnLoadRom(DrvColPROM   + 0x00900, k++, 1)) return 1;
591 		if (BurnLoadRom(DrvColPROM   + 0x00a00, k++, 1)) return 1;
592 		if (BurnLoadRom(DrvColPROM   + 0x00a20, k++, 1)) return 1;
593 		if (BurnLoadRom(DrvColPROM   + 0x00a40, k++, 1)) return 1;
594 		if (BurnLoadRom(DrvColPROM   + 0x00a60, k++, 1)) return 1;
595 	}
596 	else if (game == 0 && load_type == 1) // chinhero
597 	{
598 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
599 		if (BurnLoadRom(DrvZ80ROM[0] + 0x04000, k++, 1)) return 1;
600 		if (BurnLoadRom(DrvZ80ROM[0] + 0x08000, k++, 1)) return 1;
601 
602 		if (BurnLoadRom(DrvZ80ROM[1] + 0x00000, k++, 1)) return 1;
603 
604 		if (BurnLoadRom(DrvZ80ROM[2] + 0x00000, k++, 1)) return 1;
605 		if (BurnLoadRom(DrvZ80ROM[2] + 0x04000, k++, 1)) return 1;
606 
607 		if (BurnLoadRom(DrvGfxROM0 + 0x00000, k++, 1)) return 1;
608 		if (BurnLoadRom(DrvGfxROM0 + 0x02000, k++, 1)) return 1;
609 
610 		if (BurnLoadRom(DrvGfxROM2 + 0x00000, k++, 1)) return 1; // load temp
611 		if (BurnLoadRom(DrvGfxROM2 + 0x02000, k++, 1)) return 1;
612 		if (BurnLoadRom(DrvGfxROM2 + 0x04000, k++, 1)) return 1;
613 		if (BurnLoadRom(DrvGfxROM2 + 0x10000, k++, 1)) return 1;
614 		if (BurnLoadRom(DrvGfxROM2 + 0x12000, k++, 1)) return 1;
615 		if (BurnLoadRom(DrvGfxROM2 + 0x14000, k++, 1)) return 1;
616 
617 		if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1;
618 		if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1;
619 		if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1;
620 		if (BurnLoadRom(DrvColPROM + 0x00300, k++, 1)) return 1;
621 		if (BurnLoadRom(DrvColPROM + 0x00400, k++, 1)) return 1;
622 		if (BurnLoadRom(DrvColPROM + 0x00600, k++, 1)) return 1;
623 		if (BurnLoadRom(DrvColPROM + 0x00800, k++, 1)) return 1;
624 		if (BurnLoadRom(DrvColPROM + 0x00900, k++, 1)) return 1;
625 		if (BurnLoadRom(DrvColPROM + 0x00a00, k++, 1)) return 1;
626 		if (BurnLoadRom(DrvColPROM + 0x00a20, k++, 1)) return 1;
627 		if (BurnLoadRom(DrvColPROM + 0x00a40, k++, 1)) return 1;
628 		if (BurnLoadRom(DrvColPROM + 0x00a60, k++, 1)) return 1;
629 	}
630 	else if (game == 1 && load_type == 0) // shangkid
631 	{
632 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
633 		if (BurnLoadRom(DrvZ80ROM[0] + 0x04000, k++, 1)) return 1;
634 		if (BurnLoadRom(DrvZ80ROM[0] + 0x08000, k++, 1)) return 1;
635 		if (BurnLoadRom(DrvZ80ROM[0] + 0x0a000, k++, 1)) return 1;
636 
637 		if (BurnLoadRom(DrvZ80ROM[1] + 0x00000, k++, 1)) return 1;
638 		if (BurnLoadRom(DrvZ80ROM[1] + 0x02000, k++, 1)) return 1;
639 		if (BurnLoadRom(DrvZ80ROM[1] + 0x04000, k++, 1)) return 1;
640 		if (BurnLoadRom(DrvZ80ROM[1] + 0x08000, k++, 1)) return 1;
641 
642 		if (BurnLoadRom(DrvZ80ROM[2] + 0x00000, k++, 1)) return 1;
643 		if (BurnLoadRom(DrvZ80ROM[2] + 0x04000, k++, 1)) return 1;
644 		if (BurnLoadRom(DrvZ80ROM[2] + 0x08000, k++, 1)) return 1;
645 		if (BurnLoadRom(DrvZ80ROM[2] + 0x10000, k++, 1)) return 1;
646 		if (BurnLoadRom(DrvZ80ROM[2] + 0x14000, k++, 1)) return 1;
647 		if (BurnLoadRom(DrvZ80ROM[2] + 0x18000, k++, 1)) return 1;
648 		if (BurnLoadRom(DrvZ80ROM[2] + 0x1c000, k++, 1)) return 1;
649 
650 		if (BurnLoadRom(DrvGfxROM0 + 0x00000, k++, 1)) return 1;
651 		if (BurnLoadRom(DrvGfxROM0 + 0x02000, k++, 1)) return 1;
652 
653 		if (BurnLoadRom(DrvGfxROM1 + 0x00000, k++, 1)) return 1;
654 		if (BurnLoadRom(DrvGfxROM1 + 0x04000, k++, 1)) return 1;
655 		if (BurnLoadRom(DrvGfxROM1 + 0x08000, k++, 1)) return 1;
656 		if (BurnLoadRom(DrvGfxROM1 + 0x0c000, k++, 1)) return 1;
657 		if (BurnLoadRom(DrvGfxROM1 + 0x10000, k++, 1)) return 1;
658 		if (BurnLoadRom(DrvGfxROM1 + 0x14000, k++, 1)) return 1;
659 
660 		if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1;
661 		if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1;
662 		if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1;
663 		if (BurnLoadRom(DrvColPROM + 0x00300, k++, 1)) return 1;
664 		if (BurnLoadRom(DrvColPROM + 0x00400, k++, 1)) return 1;
665 		if (BurnLoadRom(DrvColPROM + 0x00600, k++, 1)) return 1;
666 		if (BurnLoadRom(DrvColPROM + 0x00800, k++, 1)) return 1;
667 		if (BurnLoadRom(DrvColPROM + 0x00900, k++, 1)) return 1;
668 		if (BurnLoadRom(DrvColPROM + 0x00a00, k++, 1)) return 1;
669 		if (BurnLoadRom(DrvColPROM + 0x00a20, k++, 1)) return 1;
670 		if (BurnLoadRom(DrvColPROM + 0x00a40, k++, 1)) return 1;
671 		if (BurnLoadRom(DrvColPROM + 0x00a60, k++, 1)) return 1;
672 	}
673 	else if (game == 1 && load_type == 1)
674 	{
675 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
676 		if (BurnLoadRom(DrvZ80ROM[0] + 0x04000, k++, 1)) return 1;
677 		if (BurnLoadRom(DrvZ80ROM[0] + 0x08000, k++, 1)) return 1;
678 		if (BurnLoadRom(DrvZ80ROM[0] + 0x0a000, k++, 1)) return 1;
679 
680 		if (BurnLoadRom(DrvZ80ROM[1] + 0x00000, k++, 1)) return 1;
681 		if (BurnLoadRom(DrvZ80ROM[1] + 0x02000, k++, 1)) return 1;
682 		if (BurnLoadRom(DrvZ80ROM[1] + 0x04000, k++, 1)) return 1;
683 		if (BurnLoadRom(DrvZ80ROM[1] + 0x08000, k++, 1)) return 1;
684 
685 		if (BurnLoadRom(DrvZ80ROM[2] + 0x00000, k++, 1)) return 1;
686 		if (BurnLoadRom(DrvZ80ROM[2] + 0x10000, k++, 1)) return 1;
687 		if (BurnLoadRom(DrvZ80ROM[2] + 0x14000, k++, 1)) return 1;
688 		if (BurnLoadRom(DrvZ80ROM[2] + 0x18000, k++, 1)) return 1;
689 		if (BurnLoadRom(DrvZ80ROM[2] + 0x1c000, k++, 1)) return 1;
690 
691 		if (BurnLoadRom(DrvGfxROM0 + 0x00000, k++, 1)) return 1;
692 		if (BurnLoadRom(DrvGfxROM0 + 0x02000, k++, 1)) return 1;
693 
694 		if (BurnLoadRom(DrvGfxROM1 + 0x00000, k++, 1)) return 1;
695 		if (BurnLoadRom(DrvGfxROM1 + 0x04000, k++, 1)) return 1;
696 		if (BurnLoadRom(DrvGfxROM1 + 0x08000, k++, 1)) return 1;
697 		if (BurnLoadRom(DrvGfxROM1 + 0x0c000, k++, 1)) return 1;
698 		if (BurnLoadRom(DrvGfxROM1 + 0x10000, k++, 1)) return 1;
699 		if (BurnLoadRom(DrvGfxROM1 + 0x14000, k++, 1)) return 1;
700 
701 		if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1;
702 		if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1;
703 		if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1;
704 		if (BurnLoadRom(DrvColPROM + 0x00300, k++, 1)) return 1;
705 		if (BurnLoadRom(DrvColPROM + 0x00400, k++, 1)) return 1;
706 		if (BurnLoadRom(DrvColPROM + 0x00600, k++, 1)) return 1;
707 		if (BurnLoadRom(DrvColPROM + 0x00800, k++, 1)) return 1;
708 		if (BurnLoadRom(DrvColPROM + 0x00900, k++, 1)) return 1;
709 		if (BurnLoadRom(DrvColPROM + 0x00a00, k++, 1)) return 1;
710 		if (BurnLoadRom(DrvColPROM + 0x00a20, k++, 1)) return 1;
711 		if (BurnLoadRom(DrvColPROM + 0x00a40, k++, 1)) return 1;
712 		if (BurnLoadRom(DrvColPROM + 0x00a60, k++, 1)) return 1;
713 	}
714 
715 	if (game == 0) { // chinhero
716 		DrvGfxDecode(DrvGfxROM0 + 0x000000, DrvGfxROM0, 0x4000, 0x400, 0);
717 		DrvGfxDecodeCH(DrvGfxROM2 + 0x00000, DrvGfxROM1, 0x80);
718 
719 		GenericTilemapInit(0, TILEMAP_SCAN_ROWS, chbg_map_callback, 8, 8, 64, 32);
720 		GenericTilemapSetGfx(0, DrvGfxROM0, 2,  8,  8, 0x10000, 0, 0x3f);
721 		GenericTilemapSetGfx(1, DrvGfxROM1, 3, 16, 16, 0x8000*4, 0, 0x1f);
722 		GenericTilemapSetOffsets(TMAP_GLOBAL, 0, -16);
723 
724 	} else if (game == 1) { // shangkid
725 		DrvGfxDecode(DrvGfxROM0 + 0x000000, DrvGfxROM0, 0x04000, 0x400, 0);
726 		DrvGfxDecode(DrvGfxROM1 + 0x000000, DrvGfxROM1, 0x18000, 0x600, 1);
727 
728 		GenericTilemapInit(0, TILEMAP_SCAN_ROWS, skbg_map_callback, 8, 8, 64, 32);
729 		GenericTilemapSetGfx(0, DrvGfxROM0, 2,  8,  8, 0x10000, 0, 0x3f);
730 		GenericTilemapSetGfx(1, DrvGfxROM1, 2, 16, 16, 0x60000, 0, 0x3f);
731 		GenericTilemapSetOffsets(TMAP_GLOBAL, 0, -16);
732 
733 	}
734 
735 	maincpu_init(0);
736 	maincpu_init(1);
737 
738 	ZetInit(2);
739 	ZetOpen(2);
740 	ZetMapMemory(DrvZ80ROM[2],	0x0000, 0xdfff, MAP_ROM); // banked on shangkid
741 	ZetMapMemory(DrvZ80RAM,		0xe000, 0xe7ff, MAP_RAM);
742 	ZetMapMemory(DrvZ80RAM,		0xe800, 0xefff, MAP_RAM); // mirror
743 	ZetSetOutHandler(chinhero_sound_write_port);
744 	ZetSetInHandler(chinhero_sound_read_port);
745 	ZetClose();
746 
747 	AY8910Init(0, 1536000, 0);
748 	AY8910SetAllRoutes(0, 0.25, BURN_SND_ROUTE_BOTH);
749 	AY8910SetPorts(0, NULL, NULL, ay8910_portA_write, ay8910_portB_write);
750 	AY8910SetBuffered(ZetTotalCycles, 3072000);
751 
752 	DACInit(0, 0, 1, ZetTotalCycles, 3072000);
753 	DACSetRoute(0, 0.75, BURN_SND_ROUTE_BOTH);
754 
755 	DrvDoReset();
756 
757 	return 0;
758 }
759 
DynamskiInit()760 static INT32 DynamskiInit()
761 {
762 	BurnAllocMemIndex();
763 
764 	{
765 		INT32 k = 0;
766 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
767 		if (BurnLoadRom(DrvZ80ROM[0] + 0x01000, k++, 1)) return 1;
768 		if (BurnLoadRom(DrvZ80ROM[0] + 0x02000, k++, 1)) return 1;
769 		if (BurnLoadRom(DrvZ80ROM[0] + 0x03000, k++, 1)) return 1;
770 		if (BurnLoadRom(DrvZ80ROM[0] + 0x04000, k++, 1)) return 1;
771 		if (BurnLoadRom(DrvZ80ROM[0] + 0x05000, k++, 1)) return 1;
772 		if (BurnLoadRom(DrvZ80ROM[0] + 0x06000, k++, 1)) return 1;
773 		if (BurnLoadRom(DrvZ80ROM[0] + 0x07000, k++, 1)) return 1;
774 
775 		if (BurnLoadRom(DrvGfxROM0 + 0x00000, k++, 1)) return 1;
776 		if (BurnLoadRom(DrvGfxROM0 + 0x02000, k++, 1)) return 1;
777 
778 		if (BurnLoadRom(DrvGfxROM1 + 0x00000, k++, 1)) return 1;
779 		if (BurnLoadRom(DrvGfxROM1 + 0x02000, k++, 1)) return 1;
780 		if (BurnLoadRom(DrvGfxROM1 + 0x04000, k++, 1)) return 1;
781 
782 		if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1;
783 		if (BurnLoadRom(DrvColPROM + 0x00020, k++, 1)) return 1;
784 		if (BurnLoadRom(DrvColPROM + 0x00040, k++, 1)) return 1;
785 		if (BurnLoadRom(DrvColPROM + 0x00140, k++, 1)) return 1;
786 
787 		DrvGfxDecode(DrvGfxROM0 + 0x000000, DrvGfxROM0, 0x04000, 0x400, 0);
788 		DrvGfxDecode(DrvGfxROM1 + 0x000000, DrvGfxROM1, 0x06000, 0x180, 1);
789 	}
790 
791 	ZetInit(0);
792 	ZetOpen(0);
793 	ZetMapMemory(DrvZ80ROM[0],		0x0000, 0x7fff, MAP_ROM);
794 	ZetMapMemory(DrvVidRAM,			0xc000, 0xcbff, MAP_RAM);
795 	ZetMapMemory(DrvSprRAM,			0xd000, 0xdbff, MAP_RAM);
796 	ZetMapMemory(DrvZ80RAM,			0xf000, 0xf7ff, MAP_RAM);
797 	ZetSetWriteHandler(dynamski_write);
798 	ZetSetReadHandler(dynamski_read);
799 	ZetSetOutHandler(dynamski_main_write_port);
800 	ZetClose();
801 
802 	ZetInit(1); // not on this hardware
803 	ZetInit(2); // not on this hardware
804 
805 	AY8910Init(0, 2000000, 0);
806 	AY8910SetAllRoutes(0, 0.25, BURN_SND_ROUTE_BOTH);
807 	AY8910SetBuffered(ZetTotalCycles, 3000000);
808 
809 	DACInit(0, 0, 1, ZetTotalCycles, 3000000); // not on this hardware
810 	DACSetRoute(0, 0.00, BURN_SND_ROUTE_BOTH);
811 
812 	GenericTilesInit();
813 
814 	DrvDoReset();
815 
816 	return 0;
817 }
818 
DrvExit()819 static INT32 DrvExit()
820 {
821 	GenericTilesExit();
822 
823 	ZetExit();
824 	AY8910Exit(0);
825 	DACExit();
826 
827 	BurnFreeMemIndex();
828 
829 	is_game = 0;
830 
831 	return 0;
832 }
833 
DrvPaletteInit()834 static void DrvPaletteInit()
835 {
836 	for (INT32 i = 0; i < 0x100; i++)
837 	{
838 		INT32 bit0 = (DrvColPROM[i] >> 0) & 0x01;
839 		INT32 bit1 = (DrvColPROM[i] >> 1) & 0x01;
840 		INT32 bit2 = (DrvColPROM[i] >> 2) & 0x01;
841 		INT32 bit3 = (DrvColPROM[i] >> 3) & 0x01;
842 		INT32 r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
843 
844 		bit0 = (DrvColPROM[i + 0x100] >> 0) & 0x01;
845 		bit1 = (DrvColPROM[i + 0x100] >> 1) & 0x01;
846 		bit2 = (DrvColPROM[i + 0x100] >> 2) & 0x01;
847 		bit3 = (DrvColPROM[i + 0x100] >> 3) & 0x01;
848 		INT32 g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
849 
850 		bit0 = (DrvColPROM[i + 2*0x100] >> 0) & 0x01;
851 		bit1 = (DrvColPROM[i + 2*0x100] >> 1) & 0x01;
852 		bit2 = (DrvColPROM[i + 2*0x100] >> 2) & 0x01;
853 		bit3 = (DrvColPROM[i + 2*0x100] >> 3) & 0x01;
854 		INT32 b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
855 
856 		DrvPalette[i] = BurnHighCol(r,g,b,0);
857 	}
858 }
859 
draw_sprite(INT32 sprite_type)860 static void draw_sprite(INT32 sprite_type)
861 {
862 	GenericTilesGfx *gfx = &GenericGfxData[1];
863 
864 	INT32 transparent_pen = (1 << gfx->depth) - 1;
865 	INT32 color_shift = gfx->depth - 2;
866 
867 	UINT8 *finish = DrvSprRAM;
868 	UINT8 *source = DrvSprRAM + 0x200;
869 
870 	while (source > finish) {
871 		source -= 8;
872 
873 		INT32 ypos        = 209 - source[0];
874 		INT32 tile        = source[1]&0x3f;
875 		INT32 xflip       = (source[1]&0x40) >> 6;
876 		INT32 yflip       = (source[1]&0x80) >> 7;
877 		INT32 bank        = source[2]&0x3f;
878 		INT32 xsize       = (source[2]&0x40) >> 6;
879 		INT32 ysize       = (source[2]&0x80) >> 7;
880 		INT32 height      = ((source[3]&0x07) + 1) << 1;
881 		INT32 xpos        = ((source[4]+source[5]*0x100)&0x1ff)-23;
882 		INT32 color       = (source[6]&0x3f) >> color_shift;
883 		INT32 width       = ((source[7]&0x07) + 1) << 1;
884 
885 		if (sprite_type == 1) {
886 			INT32 t[4] = { bank & 0xf, bank & 0xf, 0x10 | (bank & 0x3), 0x14 | (bank & 0x3) };
887 
888 			tile += t[bank >> 4 & 0x3] * 0x40;
889 		} else {
890 			if (color == 0) continue;
891 			tile += (bank >> 4) * 0x80 + (bank & 0x01) * 0x40;
892 		}
893 
894 		color = ((color & gfx->color_mask) << gfx->depth) + gfx->color_offset;
895 
896 		if (xsize == 0 && xflip) xpos -= 16;
897 		if (ysize == 0 && yflip == 0) ypos += 16;
898 
899 		xpos += (16-width)*(xsize+1)/2;
900 		ypos += (16-height)*(ysize+1)/2;
901 
902 		for (INT32 r = 0; r <= ysize; r++) {
903 			for (INT32 c = 0; c <= xsize; c++) {
904 				INT32 sx = xpos+(c^xflip)*width;
905 				INT32 sy = ypos+(r^yflip)*height;
906 
907 				RenderZoomedTile(pTransDraw, gfx->gfxbase, (tile+c*8+r) % gfx->code_mask, color, transparent_pen, sx - 16, sy, xflip, yflip, gfx->width, gfx->height, (width<<16)/16, (height<<16)/16);
908 				RenderZoomedTile(pTransDraw, gfx->gfxbase, (tile+c*8+r) % gfx->code_mask, color, transparent_pen, sx - 16, sy + 256, xflip, yflip, gfx->width, gfx->height, (width<<16)/16, (height<<16)/16);
909 			}
910 		}
911 	}
912 }
913 
DrvDraw()914 static INT32 DrvDraw()
915 {
916 	if (DrvRecalc) {
917 		DrvPaletteInit();
918 		DrvRecalc = 0;
919 	}
920 
921 	BurnTransferClear(0);
922 
923 	INT32 flipscreen = video_regs[1] & 0x80;
924 
925 	GenericTilemapSetFlip(TMAP_GLOBAL, flipscreen ? (TMAP_FLIPX | TMAP_FLIPY) : 0);
926 	GenericTilemapSetScrollX(0, video_regs[0] - 24);
927 	GenericTilemapSetScrollY(0, video_regs[2]);
928 
929 	if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 0);
930 
931 	if (nSpriteEnable & 1) draw_sprite(is_game);
932 
933 	if (nBurnLayer & 2) GenericTilemapDraw(0, pTransDraw, TMAP_SET_GROUP(1));
934 
935 	BurnTransferCopy(DrvPalette);
936 
937 	return 0;
938 }
939 
DrvFrame()940 static INT32 DrvFrame()
941 {
942 	if (DrvReset) {
943 		DrvDoReset();
944 	}
945 
946 	ZetNewFrame();
947 
948 	{
949 		DrvInputs[0] = 0;
950 		DrvInputs[1] = 0;
951 		DrvInputs[2] = 0;
952 
953 		for (INT32 i = 0; i < 8; i++) {
954 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
955 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
956 			DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
957 		}
958 	}
959 
960 	INT32 nInterleave = 256;
961 	INT32 nCyclesTotal[3] =  { 3072000 / 60, 3072000 / 60, 3072000 / 60 };
962 	INT32 nCyclesDone[3] = { 0, 0, 0 };
963 
964 	for (INT32 i = 0; i < nInterleave; i++)
965 	{
966 		ZetOpen(0);
967 		CPU_RUN(0, Zet);
968 		if (i == 223 && irq[0]) ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
969 		ZetClose();
970 
971 		ZetOpen(1);
972 		CPU_RUN(1, Zet);
973 		if (i == 223 && irq[1]) ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
974 		ZetClose();
975 
976 		ZetOpen(2);
977 		CPU_RUN(2, Zet);
978 		ZetClose();
979 
980 		if (i == 223 && pBurnDraw) {
981 			BurnDrvRedraw();
982 		}
983 	}
984 
985 	if (pBurnSoundOut) {
986 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
987 		DACUpdate(pBurnSoundOut, nBurnSoundLen);
988 	}
989 
990 	return 0;
991 }
992 
DynamskiPaletteInit()993 static void DynamskiPaletteInit()
994 {
995 	UINT32 pal[32];
996 
997 	for (int i = 0; i < 32; i++)
998 	{
999 		UINT32 data = (DrvColPROM[i | 0x20] << 8) | DrvColPROM[i];
1000 
1001 		UINT8 r = (data >> 1) & 0x1f;
1002 		UINT8 g = (data >> 6) & 0x1f;
1003 		UINT8 b = (data >> 11) & 0x1f;
1004 
1005 		r = (r << 3) | (r >> 2);
1006 		g = (g << 3) | (g >> 2);
1007 		b = (b << 3) | (b >> 2);
1008 
1009 		pal[i] = BurnHighCol(r,g,b,0);
1010 	}
1011 
1012 	for (INT32 i = 0; i < 0x40; i++)
1013 	{
1014 		DrvPalette[0x00 + i] = pal[(DrvColPROM[i + 0x040] & 0x0f)];
1015 		DrvPalette[0x40 + i] = pal[(DrvColPROM[i + 0x140] & 0x0f) | 0x10];
1016 	}
1017 }
1018 
dynamski_draw_background(INT32 pri)1019 static void dynamski_draw_background(INT32 pri)
1020 {
1021 	for (INT32 i = 0; i < 0x400; i++)
1022 	{
1023 		INT32 sx = (i & 0x1f) * 8;
1024 		INT32 sy = (i / 0x20) * 8;
1025 		INT32 code  = DrvVidRAM[i];
1026 		INT32 color = DrvVidRAM[i + 0x400];
1027 
1028 		if (sy < 16)
1029 		{
1030 			INT32 temp = sx;
1031 			sx = sy+256+16;
1032 			sy = temp;
1033 		}
1034 		else if (sy >= (256-16))
1035 		{
1036 			INT32 temp = sx;
1037 			sx = sy-256+16;
1038 			sy = temp;
1039 		}
1040 		else
1041 		{
1042 			sx+=16;
1043 		}
1044 
1045 		if (pri == 0 || (color >> 7) == pri)
1046 		{
1047 			code += (color & 0x60) << 3;
1048 
1049 			Draw8x8MaskTile(pTransDraw, code, sx, sy - 16, 0, 0, color & 0xf, 2, pri ? 3 : -1, 0, DrvGfxROM0);
1050 		}
1051 	}
1052 }
1053 
dynamski_draw_sprites()1054 static void dynamski_draw_sprites()
1055 {
1056 	for (INT32 i = 0x7e; i >= 0x00; i -= 2)	{
1057 		INT32 bank = DrvSprRAM[0xb80 + i];
1058 		INT32 attr = DrvSprRAM[0xb81 + i];
1059 
1060 		INT32 code = (DrvVidRAM[0xb80 + i] & 0x3f) + (bank * 0x40);
1061 		INT32 color = DrvVidRAM[0xb81 + i] & 0xf;
1062 		INT32 flipx = DrvVidRAM[0xb80 + i] & 0x80;
1063 		INT32 flipy = DrvVidRAM[0xb80 + i] & 0x40;
1064 		INT32 sy = 240-DrvSprRAM[0x380 + i];
1065 		INT32 sx = (DrvSprRAM[0x381 + i] - 64 + 8 + 16) + ((attr & 1) * 0x100);
1066 
1067 		Draw16x16MaskTile(pTransDraw, code % 0x180, sx, sy - 16, flipx, flipy, color, 2, 3, 0x40, DrvGfxROM1);
1068 	}
1069 }
DynamskiDraw()1070 static INT32 DynamskiDraw()
1071 {
1072 	if (DrvRecalc) {
1073 		DynamskiPaletteInit();
1074 		DrvRecalc = 1;
1075 	}
1076 
1077 	BurnTransferClear(0);
1078 
1079 	if (nBurnLayer & 1) dynamski_draw_background(0);
1080 	if (nSpriteEnable & 1) dynamski_draw_sprites();
1081 	if (nBurnLayer & 2) dynamski_draw_background(1);
1082 
1083 	BurnTransferCopy(DrvPalette);
1084 
1085 	return 0;
1086 }
1087 
DynamskiFrame()1088 static INT32 DynamskiFrame()
1089 {
1090 	if (DrvReset) {
1091 		DrvDoReset();
1092 	}
1093 
1094 	ZetNewFrame();
1095 
1096 	{
1097 		DrvInputs[0] = 0;
1098 		DrvInputs[1] = 0;
1099 		DrvInputs[2] = 0;
1100 
1101 		for (INT32 i = 0; i < 8; i++) {
1102 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
1103 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
1104 			DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
1105 		}
1106 	}
1107 
1108 	INT32 nInterleave = 256;
1109 	INT32 nCyclesTotal[1] =  { 3000000 / 60 };
1110 	INT32 nCyclesDone[1] = { 0 };
1111 
1112 	for (INT32 i = 0; i < nInterleave; i++)
1113 	{
1114 		ZetOpen(0);
1115 		CPU_RUN(0, Zet);
1116 		if (i == 223 && irq[0]) ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
1117 		ZetClose();
1118 
1119 		if (i == 223 && pBurnDraw) {
1120 			BurnDrvRedraw();
1121 		}
1122 	}
1123 
1124 	if (pBurnSoundOut) {
1125 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
1126 		DACUpdate(pBurnSoundOut, nBurnSoundLen);
1127 	}
1128 
1129 	return 0;
1130 }
1131 
DrvScan(INT32 nAction,INT32 * pnMin)1132 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
1133 {
1134 	struct BurnArea ba;
1135 
1136 	if (pnMin) {
1137 		*pnMin = 0x029702;
1138 	}
1139 
1140 	if (nAction & ACB_VOLATILE) {
1141 		memset(&ba, 0, sizeof(ba));
1142 
1143 		ba.Data	  = AllRam;
1144 		ba.nLen	  = RamEnd - AllRam;
1145 		ba.szName = "All Ram";
1146 		BurnAcb(&ba);
1147 
1148 		ZetScan(nAction);
1149 
1150 		AY8910Scan(nAction, pnMin);
1151 		DACScan(nAction, pnMin);
1152 
1153 		SCAN_VAR(irq);
1154 		SCAN_VAR(nmi);
1155 		SCAN_VAR(soundlatch);
1156 
1157 		if (is_game == 1) { // shangkid
1158 			SCAN_VAR(bankdata);
1159 			SCAN_VAR(soundbank);
1160 		}
1161 	}
1162 
1163 	if (nAction & ACB_WRITE)
1164 	{
1165 		if (is_game == 1) { // shangkid
1166 			ZetOpen(0);
1167 			bankswitch(bankdata);
1168 			ZetClose();
1169 
1170 			ZetOpen(2);
1171 			sound_bankswitch(soundbank);
1172 			ZetClose();
1173 		}
1174 	}
1175 
1176 	return 0;
1177 }
1178 
1179 // Chinese Hero
1180 
1181 static struct BurnRomInfo chinheroRomDesc[] = {
1182 	{ "ic2.1",				0x2000, 0x8974bac4, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1183 	{ "ic3.2",				0x2000, 0x9b7a02fe, 1 | BRF_PRG | BRF_ESS }, //  1
1184 	{ "ic4.3",				0x2000, 0xe86d4195, 1 | BRF_PRG | BRF_ESS }, //  2
1185 	{ "ic5.4",				0x2000, 0x2b629d2c, 1 | BRF_PRG | BRF_ESS }, //  3
1186 	{ "ic6.5",				0x2000, 0x35bf4a4f, 1 | BRF_PRG | BRF_ESS }, //  4
1187 
1188 	{ "ic31.6",				0x2000, 0x7c56927b, 2 | BRF_PRG | BRF_ESS }, //  5 Sub Z80 COde
1189 	{ "ic32.7",				0x2000, 0xd67b8045, 2 | BRF_PRG | BRF_ESS }, //  6
1190 
1191 	{ "ic47.8",				0x2000, 0x3c396062, 3 | BRF_PRG | BRF_ESS }, //  7 Sound Z80 Code
1192 	{ "ic48.9",				0x2000, 0xb14f2bab, 3 | BRF_PRG | BRF_ESS }, //  8
1193 	{ "ic49.10",			0x2000, 0x8c0e43d1, 3 | BRF_PRG | BRF_ESS }, //  9
1194 
1195 	{ "ic21.11",			0x2000, 0x3a37fb45, 4 | BRF_GRA },           // 10 Background Tiles
1196 	{ "ic22.12",			0x2000, 0xbc21c002, 4 | BRF_GRA },           // 11
1197 
1198 	{ "ic114.18",			0x2000, 0xfc4183a8, 5 | BRF_GRA },           // 12 Sprites
1199 	{ "ic113.17",			0x2000, 0xd713d7fe, 5 | BRF_GRA },           // 13
1200 	{ "ic99.13",			0x2000, 0xa8e2a3f4, 5 | BRF_GRA },           // 14
1201 	{ "ic112.16",			0x2000, 0xdd5170ca, 6 | BRF_GRA },           // 15
1202 	{ "ic111.15",			0x2000, 0x20f6052e, 6 | BRF_GRA },           // 16
1203 	{ "ic110.14",			0x2000, 0x9bc2d568, 6 | BRF_GRA },           // 17
1204 
1205 	{ "v_ic36_r",			0x0100, 0x16ae1692, 7 | BRF_GRA },           // 18 PROMs
1206 	{ "v_ic35_g",			0x0100, 0xb3d0a074, 7 | BRF_GRA },           // 19
1207 	{ "v_ic27_b",			0x0100, 0x353a2d11, 7 | BRF_GRA },           // 20
1208 	{ "v_ic28_m",			0x0100, 0x7ca273c1, 7 | BRF_GRA },           // 21
1209 	{ "v_ic69",				0x0200, 0x410d6f86, 7 | BRF_GRA },           // 22
1210 	{ "v_ic108",			0x0200, 0xd33c02ae, 7 | BRF_GRA },           // 23
1211 	{ "v_ic12",				0x0100, 0x0de07e89, 7 | BRF_GRA },           // 24
1212 	{ "v_ic15_p",			0x0100, 0x7e0a0581, 7 | BRF_GRA },           // 25
1213 	{ "v_ic8",				0x0020, 0x4c62974d, 7 | BRF_GRA },           // 26
1214 	{ "ic8",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 27
1215 	{ "ic22",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 28
1216 	{ "ic42",				0x0020, 0x2ccfe10a, 7 | BRF_GRA },           // 29
1217 };
1218 
1219 STD_ROM_PICK(chinhero)
STD_ROM_FN(chinhero)1220 STD_ROM_FN(chinhero)
1221 
1222 static INT32 ChinheroInit()
1223 {
1224 	return DrvInit(0, 0);
1225 }
1226 
1227 struct BurnDriver BurnDrvChinhero = {
1228 	"chinhero", NULL, NULL, NULL, "1984",
1229 	"Chinese Hero\0", NULL, "Taiyo", "Miscellaneous",
1230 	NULL, NULL, NULL, NULL,
1231 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_SCRFIGHT, 0,
1232 	NULL, chinheroRomInfo, chinheroRomName, NULL, NULL, NULL, NULL, ChinheroInputInfo, ChinheroDIPInfo,
1233 	ChinheroInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1234 	224, 288, 3, 4
1235 };
1236 
1237 
1238 // Chinese Hero (older, set 1)
1239 
1240 static struct BurnRomInfo chinhero2RomDesc[] = {
1241 	{ "1.128",				0x4000, 0x68e247aa, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1242 	{ "2.128",				0x4000, 0x0346d8c9, 1 | BRF_PRG | BRF_ESS }, //  1
1243 	{ "3.128",				0x4000, 0xa78b8d78, 1 | BRF_PRG | BRF_ESS }, //  2
1244 
1245 	{ "4.128",				0x4000, 0x6ab2e836, 2 | BRF_PRG | BRF_ESS }, //  3 Sub Z80 Code
1246 
1247 	{ "5.128",				0x4000, 0x4e4f3f92, 3 | BRF_PRG | BRF_ESS }, //  4 Sound Z80 Code
1248 	{ "ic49.10",			0x2000, 0x8c0e43d1, 3 | BRF_PRG | BRF_ESS }, //  5
1249 
1250 	{ "ic21.11",			0x2000, 0x3a37fb45, 4 | BRF_GRA },           //  6 Background Tiles
1251 	{ "ic22.12",			0x2000, 0xbc21c002, 4 | BRF_GRA },           //  7
1252 
1253 	{ "ic114.18",			0x2000, 0xfc4183a8, 5 | BRF_GRA },           //  8 Sprites
1254 	{ "ic113.17",			0x2000, 0xd713d7fe, 5 | BRF_GRA },           //  9
1255 	{ "ic99.13",			0x2000, 0xa8e2a3f4, 5 | BRF_GRA },           // 10
1256 	{ "ic112.16",			0x2000, 0xdd5170ca, 6 | BRF_GRA },           // 11
1257 	{ "ic111.15",			0x2000, 0x20f6052e, 6 | BRF_GRA },           // 12
1258 	{ "ic110.14",			0x2000, 0x9bc2d568, 6 | BRF_GRA },           // 13
1259 
1260 	{ "v_ic36_r",			0x0100, 0x16ae1692, 7 | BRF_GRA },           // 14 PROMs
1261 	{ "v_ic35_g",			0x0100, 0xb3d0a074, 7 | BRF_GRA },           // 15
1262 	{ "v_ic27_b",			0x0100, 0x353a2d11, 7 | BRF_GRA },           // 16
1263 	{ "v_ic28_m",			0x0100, 0x7ca273c1, 7 | BRF_GRA },           // 17
1264 	{ "v_ic69",				0x0200, 0x410d6f86, 7 | BRF_GRA },           // 18
1265 	{ "v_ic108",			0x0200, 0xd33c02ae, 7 | BRF_GRA },           // 19
1266 	{ "v_ic12",				0x0100, 0x0de07e89, 7 | BRF_GRA },           // 20
1267 	{ "v_ic15_p",			0x0100, 0x7e0a0581, 7 | BRF_GRA },           // 21
1268 	{ "v_ic8",				0x0020, 0x4c62974d, 7 | BRF_GRA },           // 22
1269 	{ "ic8",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 23
1270 	{ "ic22",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 24
1271 	{ "ic42",				0x0020, 0x2ccfe10a, 7 | BRF_GRA },           // 25
1272 };
1273 
1274 STD_ROM_PICK(chinhero2)
STD_ROM_FN(chinhero2)1275 STD_ROM_FN(chinhero2)
1276 
1277 static INT32 Chinhero2Init()
1278 {
1279 	return DrvInit(0, 1);
1280 }
1281 
1282 struct BurnDriver BurnDrvChinhero2 = {
1283 	"chinhero2", "chinhero", NULL, NULL, "1984",
1284 	"Chinese Hero (older, set 1)\0", NULL, "Taiyo", "Miscellaneous",
1285 	NULL, NULL, NULL, NULL,
1286 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_SCRFIGHT, 0,
1287 	NULL, chinhero2RomInfo, chinhero2RomName, NULL, NULL, NULL, NULL, ChinheroInputInfo, ChinheroDIPInfo,
1288 	Chinhero2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1289 	224, 288, 3, 4
1290 };
1291 
1292 
1293 // Chinese Hero (older, set 2)
1294 
1295 static struct BurnRomInfo chinhero3RomDesc[] = {
1296 	{ "1-11-22.ic2",		0x4000, 0x9b24f886, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1297 	{ "2-11-22.ic3",		0x4000, 0x39c66686, 1 | BRF_PRG | BRF_ESS }, //  1
1298 	{ "3-11-22.ic4",		0x2000, 0x2d51135e, 1 | BRF_PRG | BRF_ESS }, //  2
1299 
1300 	{ "4-11-22.ic31",		0x4000, 0x6ab2e836, 2 | BRF_PRG | BRF_ESS }, //  3 Sub Z80 Code
1301 
1302 	{ "5.128",				0x4000, 0x4e4f3f92, 3 | BRF_PRG | BRF_ESS }, //  4 Sound Z80 Code
1303 	{ "ic49.10",			0x2000, 0x8c0e43d1, 3 | BRF_PRG | BRF_ESS }, //  5
1304 
1305 	{ "ic21.11",			0x2000, 0x3a37fb45, 4 | BRF_GRA },           //  6 Background Tiles
1306 	{ "ic22.12",			0x2000, 0xbc21c002, 4 | BRF_GRA },           //  7
1307 
1308 	{ "ic114.18",			0x2000, 0xfc4183a8, 5 | BRF_GRA },           //  8 Sprites
1309 	{ "ic113.17",			0x2000, 0xd713d7fe, 5 | BRF_GRA },           //  9
1310 	{ "ic99.13",			0x2000, 0xa8e2a3f4, 5 | BRF_GRA },           // 10
1311 	{ "ic112.16",			0x2000, 0xdd5170ca, 6 | BRF_GRA },           // 11
1312 	{ "ic111.15",			0x2000, 0x20f6052e, 6 | BRF_GRA },           // 12
1313 	{ "ic110.14",			0x2000, 0x9bc2d568, 6 | BRF_GRA },           // 13
1314 
1315 	{ "v_ic36_r",			0x0100, 0x16ae1692, 7 | BRF_GRA },           // 14 PROMs
1316 	{ "v_ic35_g",			0x0100, 0xb3d0a074, 7 | BRF_GRA },           // 15
1317 	{ "v_ic27_b",			0x0100, 0x353a2d11, 7 | BRF_GRA },           // 16
1318 	{ "v_ic28_m",			0x0100, 0x7ca273c1, 7 | BRF_GRA },           // 17
1319 	{ "v_ic69",				0x0200, 0x410d6f86, 7 | BRF_GRA },           // 18
1320 	{ "v_ic108",			0x0200, 0xd33c02ae, 7 | BRF_GRA },           // 19
1321 	{ "v_ic12",				0x0100, 0x0de07e89, 7 | BRF_GRA },           // 20
1322 	{ "v_ic15_p",			0x0100, 0x7e0a0581, 7 | BRF_GRA },           // 21
1323 	{ "v_ic8",				0x0020, 0x4c62974d, 7 | BRF_GRA },           // 22
1324 	{ "ic8",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 23
1325 	{ "ic22",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 24
1326 	{ "ic42",				0x0020, 0x2ccfe10a, 7 | BRF_GRA },           // 25
1327 };
1328 
1329 STD_ROM_PICK(chinhero3)
1330 STD_ROM_FN(chinhero3)
1331 
1332 struct BurnDriver BurnDrvChinhero3 = {
1333 	"chinhero3", "chinhero", NULL, NULL, "1984",
1334 	"Chinese Hero (older, set 2)\0", NULL, "Taiyo", "Miscellaneous",
1335 	NULL, NULL, NULL, NULL,
1336 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_SCRFIGHT, 0,
1337 	NULL, chinhero3RomInfo, chinhero3RomName, NULL, NULL, NULL, NULL, ChinheroInputInfo, ChinheroDIPInfo,
1338 	Chinhero2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1339 	224, 288, 3, 4
1340 };
1341 
1342 
1343 // Chinese Heroe (Taito)
1344 
1345 static struct BurnRomInfo chinherotRomDesc[] = {
1346 	{ "chtaito1.bin",		0x4000, 0x2bd64de0, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1347 	{ "chtaito2.bin",		0x4000, 0x8fd04da9, 1 | BRF_PRG | BRF_ESS }, //  1
1348 	{ "chtaito3.bin",		0x2000, 0xcd6908e7, 1 | BRF_PRG | BRF_ESS }, //  2
1349 
1350 	{ "chtaito4.bin",		0x4000, 0x2a012614, 2 | BRF_PRG | BRF_ESS }, //  3 Sub Z80 Code
1351 
1352 	{ "chtaito5.bin",		0x4000, 0x4e4f3f92, 3 | BRF_PRG | BRF_ESS }, //  4 Sound Z80 Code
1353 	{ "chtaito6.bin",		0x2000, 0x8c0e43d1, 3 | BRF_PRG | BRF_ESS }, //  5
1354 
1355 	{ "chtaito11.bin",		0x2000, 0x3a37fb45, 4 | BRF_GRA },           //  6 Background Tiles
1356 	{ "chtaito12.bin",		0x2000, 0xbc21c002, 4 | BRF_GRA },           //  7
1357 
1358 	{ "chtaito18.bin",		0x2000, 0xfc4183a8, 5 | BRF_GRA },           //  8 Sprites
1359 	{ "chtaito17.bin",		0x2000, 0xd713d7fe, 5 | BRF_GRA },           //  9
1360 	{ "chtaito13.bin",		0x2000, 0xa8e2a3f4, 5 | BRF_GRA },           // 10
1361 	{ "chtaito16.bin",		0x2000, 0xdd5170ca, 6 | BRF_GRA },           // 11
1362 	{ "chtaito15.bin",		0x2000, 0x20f6052e, 6 | BRF_GRA },           // 12
1363 	{ "chtaito14.bin",		0x2000, 0x9bc2d568, 6 | BRF_GRA },           // 13
1364 
1365 	{ "v_ic36_r",			0x0100, 0x16ae1692, 7 | BRF_GRA },           // 14 PROMs
1366 	{ "v_ic35_g",			0x0100, 0xb3d0a074, 7 | BRF_GRA },           // 15
1367 	{ "v_ic27_b",			0x0100, 0x353a2d11, 7 | BRF_GRA },           // 16
1368 	{ "v_ic28_m",			0x0100, 0x7ca273c1, 7 | BRF_GRA },           // 17
1369 	{ "v_ic69",				0x0200, 0x410d6f86, 7 | BRF_GRA },           // 18
1370 	{ "v_ic108",			0x0200, 0xd33c02ae, 7 | BRF_GRA },           // 19
1371 	{ "v_ic12",				0x0100, 0x0de07e89, 7 | BRF_GRA },           // 20
1372 	{ "v_ic15_p",			0x0100, 0x7e0a0581, 7 | BRF_GRA },           // 21
1373 	{ "v_ic8",				0x0020, 0x4c62974d, 7 | BRF_GRA },           // 22
1374 	{ "ic8",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 23
1375 	{ "ic22",				0x0020, 0x84bcd9af, 7 | BRF_GRA },           // 24
1376 	{ "ic42",				0x0020, 0x2ccfe10a, 7 | BRF_GRA },           // 25
1377 };
1378 
1379 STD_ROM_PICK(chinherot)
1380 STD_ROM_FN(chinherot)
1381 
1382 struct BurnDriver BurnDrvChinherot = {
1383 	"chinherot", "chinhero", NULL, NULL, "1984",
1384 	"Chinese Heroe (Taito)\0", NULL, "Taiyo (Taito license)", "Miscellaneous",
1385 	NULL, NULL, NULL, NULL,
1386 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_SCRFIGHT, 0,
1387 	NULL, chinherotRomInfo, chinherotRomName, NULL, NULL, NULL, NULL, ChinheroInputInfo, ChinheroDIPInfo,
1388 	Chinhero2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1389 	224, 288, 3, 4
1390 };
1391 
1392 
1393 // Shanghai Kid
1394 
1395 static struct BurnRomInfo shangkidRomDesc[] = {
1396 	{ "cr00ic02.bin",		0x4000, 0x2e420377, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1397 	{ "cr01ic03.bin",		0x4000, 0x161cd358, 1 | BRF_PRG | BRF_ESS }, //  1
1398 	{ "cr02ic04.bin",		0x2000, 0x85b6e455, 1 | BRF_PRG | BRF_ESS }, //  2
1399 	{ "cr03ic05.bin",		0x2000, 0x3b383863, 1 | BRF_PRG | BRF_ESS }, //  3
1400 
1401 	{ "bbx.bin",			0x2000, 0x560c0abd, 2 | BRF_PRG | BRF_ESS }, //  4 Sub Z80 Code
1402 	{ "cr04ic31.bin",		0x2000, 0xcb207885, 2 | BRF_PRG | BRF_ESS }, //  5
1403 	{ "cr05ic32.bin",		0x4000, 0xcf3b8d55, 2 | BRF_PRG | BRF_ESS }, //  6
1404 	{ "cr06ic33.bin",		0x2000, 0x0f3bdbd8, 2 | BRF_PRG | BRF_ESS }, //  7
1405 
1406 	{ "cr11ic51.bin",		0x4000, 0x2e2d6afe, 3 | BRF_PRG | BRF_ESS }, //  8 Sound Z80 Code
1407 	{ "cr12ic43.bin",		0x4000, 0xdd29a0c8, 3 | BRF_PRG | BRF_ESS }, //  9
1408 	{ "cr13ic44.bin",		0x4000, 0x879d0de0, 3 | BRF_PRG | BRF_ESS }, // 10
1409 	{ "cr07ic47.bin",		0x4000, 0x20540f7c, 3 | BRF_PRG | BRF_ESS }, // 11
1410 	{ "cr08ic48.bin",		0x2000, 0x392f24db, 3 | BRF_PRG | BRF_ESS }, // 12
1411 	{ "cr09ic49.bin",		0x4000, 0xd50c96a8, 3 | BRF_PRG | BRF_ESS }, // 13
1412 	{ "cr10ic50.bin",		0x2000, 0x873a5f2d, 3 | BRF_PRG | BRF_ESS }, // 14
1413 
1414 	{ "cr20ic21.bin",		0x2000, 0xeb3cbb11, 4 | BRF_GRA },           // 15 Background Tiles
1415 	{ "cr21ic22.bin",		0x2000, 0x7c6e75f4, 4 | BRF_GRA },           // 16
1416 
1417 	{ "cr14i114.bin",		0x4000, 0xee1f348f, 5 | BRF_GRA },           // 17 Sprites
1418 	{ "cr15i113.bin",		0x4000, 0xa46398bd, 5 | BRF_GRA },           // 18
1419 	{ "cr16i112.bin",		0x4000, 0xcbed446c, 5 | BRF_GRA },           // 19
1420 	{ "cr17i111.bin",		0x4000, 0xb0a44330, 5 | BRF_GRA },           // 20
1421 	{ "cr18ic99.bin",		0x4000, 0xff7efd7c, 5 | BRF_GRA },           // 21
1422 	{ "cr19i100.bin",		0x4000, 0xf948f829, 5 | BRF_GRA },           // 22
1423 
1424 	{ "cr31ic36.bin",		0x0100, 0x9439590b, 6 | BRF_GRA },           // 23 PROMs
1425 	{ "cr30ic35.bin",		0x0100, 0x324e295e, 6 | BRF_GRA },           // 24
1426 	{ "cr28ic27.bin",		0x0100, 0x375cba96, 6 | BRF_GRA },           // 25
1427 	{ "cr29ic28.bin",		0x0100, 0x7ca273c1, 6 | BRF_GRA },           // 26
1428 	{ "cr32ic69.bin",		0x0200, 0x410d6f86, 6 | BRF_GRA },           // 27
1429 	{ "cr33-108.bin",		0x0200, 0xd33c02ae, 6 | BRF_GRA },           // 28
1430 	{ "cr26ic12.bin",		0x0100, 0x85b5e958, 6 | BRF_GRA },           // 29
1431 	{ "cr27ic15.bin",		0x0100, 0xf7a19fe2, 6 | BRF_GRA },           // 30
1432 	{ "cr25ic8.bin",		0x0020, 0xc85e09ad, 6 | BRF_GRA },           // 31
1433 	{ "cr22ic8.bin",		0x0020, 0x1a7e0b06, 6 | BRF_GRA },           // 32
1434 	{ "cr23ic22.bin",		0x0020, 0xefb5f265, 6 | BRF_GRA },           // 33
1435 	{ "cr24ic42.bin",		0x0020, 0x823878aa, 6 | BRF_GRA },           // 34
1436 };
1437 
1438 STD_ROM_PICK(shangkid)
STD_ROM_FN(shangkid)1439 STD_ROM_FN(shangkid)
1440 
1441 static INT32 ShangkidInit()
1442 {
1443 	return DrvInit(1, 0);
1444 }
1445 
1446 struct BurnDriver BurnDrvShangkid = {
1447 	"shangkid", NULL, NULL, NULL, "1985",
1448 	"Shanghai Kid\0", NULL, "Taiyo (Data East license)", "Miscellaneous",
1449 	NULL, NULL, NULL, NULL,
1450 	BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_VSFIGHT, 0,
1451 	NULL, shangkidRomInfo, shangkidRomName, NULL, NULL, NULL, NULL, ShangkidInputInfo, ShangkidDIPInfo,
1452 	ShangkidInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1453 	288, 224, 4, 3
1454 };
1455 
1456 
1457 // Hokuha Syourin Hiryu no Ken
1458 
1459 static struct BurnRomInfo hiryukenRomDesc[] = {
1460 	{ "1.2",				0x4000, 0xc7af7f2e, 1 | BRF_PRG | BRF_ESS }, //  0 Main Z80 Code
1461 	{ "2.3",				0x4000, 0x639afdb3, 1 | BRF_PRG | BRF_ESS }, //  1
1462 	{ "3.4",				0x2000, 0xad210482, 1 | BRF_PRG | BRF_ESS }, //  2
1463 	{ "4.5",				0x2000, 0x6518943a, 1 | BRF_PRG | BRF_ESS }, //  3
1464 
1465 	{ "bbxj.bin",			0x2000, 0x8def4aaf, 2 | BRF_GRA },           //  4 Sub Z80 Code
1466 	{ "5.31",				0x2000, 0x8ae37ce7, 2 | BRF_GRA },           //  5
1467 	{ "6.32",				0x4000, 0xe835bb7f, 2 | BRF_GRA },           //  6
1468 	{ "7.33",				0x2000, 0x3745ed36, 2 | BRF_GRA },           //  7
1469 
1470 	{ "cr11ic51.bin",		0x4000, 0x2e2d6afe, 3 | BRF_PRG | BRF_ESS }, //  8 Sound Z80 Code
1471 	{ "cr07ic47.bin",		0x4000, 0x20540f7c, 3 | BRF_PRG | BRF_ESS }, //  9
1472 	{ "9.48",				0x4000, 0x8da23cad, 3 | BRF_PRG | BRF_ESS }, // 10
1473 	{ "10.49",				0x4000, 0x52b82fee, 3 | BRF_PRG | BRF_ESS }, // 11
1474 	{ "cr10ic50.bin",		0x2000, 0x873a5f2d, 3 | BRF_PRG | BRF_ESS }, // 12
1475 
1476 	{ "21.21",				0x2000, 0xce20a1d4, 4 | BRF_GRA },           // 13 Background Tiles
1477 	{ "22.22",				0x2000, 0x26fc88bf, 4 | BRF_GRA },           // 14
1478 
1479 	{ "15.114",				0x4000, 0xed07854e, 5 | BRF_GRA },           // 15 Sprites
1480 	{ "16.113",				0x4000, 0x85cf1939, 5 | BRF_GRA },           // 16
1481 	{ "cr16i112.bin",		0x4000, 0xcbed446c, 5 | BRF_GRA },           // 17
1482 	{ "cr17i111.bin",		0x4000, 0xb0a44330, 5 | BRF_GRA },           // 18
1483 	{ "cr18ic99.bin",		0x4000, 0xff7efd7c, 5 | BRF_GRA },           // 19
1484 	{ "20.100",				0x4000, 0x4bc77ca0, 5 | BRF_GRA },           // 20
1485 
1486 	{ "r.36",				0x0100, 0x65dec63d, 6 | BRF_GRA },           // 21 PROMs
1487 	{ "g.35",				0x0100, 0xe79de8cf, 6 | BRF_GRA },           // 22
1488 	{ "b.27",				0x0100, 0xd6ab3448, 6 | BRF_GRA },           // 23
1489 	{ "cr29ic28.bin",		0x0100, 0x7ca273c1, 6 | BRF_GRA },           // 24
1490 	{ "cr32ic69.bin",		0x0200, 0x410d6f86, 6 | BRF_GRA },           // 25
1491 	{ "cr33-108.bin",		0x0200, 0xd33c02ae, 6 | BRF_GRA },           // 26
1492 	{ "cr26ic12.bin",		0x0100, 0x85b5e958, 6 | BRF_GRA },           // 27
1493 	{ "cr27ic15.bin",		0x0100, 0xf7a19fe2, 6 | BRF_GRA },           // 28
1494 	{ "cr25ic8.bin",		0x0020, 0xc85e09ad, 6 | BRF_GRA },           // 29
1495 	{ "cr22ic8.bin",		0x0020, 0x1a7e0b06, 6 | BRF_GRA },           // 30
1496 	{ "cr23ic22.bin",		0x0020, 0xefb5f265, 6 | BRF_GRA },           // 31
1497 	{ "cr24ic42.bin",		0x0020, 0x823878aa, 6 | BRF_GRA },           // 32
1498 };
1499 
1500 STD_ROM_PICK(hiryuken)
STD_ROM_FN(hiryuken)1501 STD_ROM_FN(hiryuken)
1502 
1503 static INT32 HiryukenInit()
1504 {
1505 	return DrvInit(1, 1);
1506 }
1507 
1508 struct BurnDriver BurnDrvHiryuken = {
1509 	"hiryuken", "shangkid", NULL, NULL, "1985",
1510 	"Hokuha Syourin Hiryu no Ken\0", NULL, "Taiyo (Taito license)", "Miscellaneous",
1511 	NULL, NULL, NULL, NULL,
1512 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_VSFIGHT, 0,
1513 	NULL, hiryukenRomInfo, hiryukenRomName, NULL, NULL, NULL, NULL, ShangkidInputInfo, ShangkidDIPInfo,
1514 	HiryukenInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x100,
1515 	288, 224, 4, 3
1516 };
1517 
1518 
1519 // Dynamic Ski
1520 
1521 static struct BurnRomInfo dynamskiRomDesc[] = {
1522 	{ "dynski.1",			0x1000, 0x30191160, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 Code
1523 	{ "dynski.2",			0x1000, 0x5e08a0b0, 1 | BRF_PRG | BRF_ESS }, //  1
1524 	{ "dynski.3",			0x1000, 0x29cfd740, 1 | BRF_PRG | BRF_ESS }, //  2
1525 	{ "dynski.4",			0x1000, 0xe1d47776, 1 | BRF_PRG | BRF_ESS }, //  3
1526 	{ "dynski.5",			0x1000, 0xe39aba1b, 1 | BRF_PRG | BRF_ESS }, //  4
1527 	{ "dynski.6",			0x1000, 0x95780608, 1 | BRF_PRG | BRF_ESS }, //  5
1528 	{ "dynski.7",			0x1000, 0xb88d328b, 1 | BRF_PRG | BRF_ESS }, //  6
1529 	{ "dynski.8",			0x1000, 0x8db5e691, 1 | BRF_PRG | BRF_ESS }, //  7
1530 
1531 	{ "dynski8.3e",			0x2000, 0x32c354dc, 2 | BRF_GRA },           //  8 Background Tiles
1532 	{ "dynski9.2e",			0x2000, 0x80a6290c, 2 | BRF_GRA },           //  9
1533 
1534 	{ "dynski5.14b",		0x2000, 0xaa4ac6e2, 3 | BRF_GRA },           // 10 Sprites
1535 	{ "dynski6.15b",		0x2000, 0x47e76886, 3 | BRF_GRA },           // 11
1536 	{ "dynski7.14d",		0x2000, 0xa153dfa9, 3 | BRF_GRA },           // 12
1537 
1538 	{ "dynskic.15g",		0x0020, 0x9333a5e4, 4 | BRF_GRA },           // 13 PROMs
1539 	{ "dynskic.15f",		0x0020, 0x3869514b, 4 | BRF_GRA },           // 14
1540 	{ "dynski.4g",			0x0100, 0x761fe465, 4 | BRF_GRA },           // 15
1541 	{ "dynski.11e",			0x0100, 0xe625aa09, 4 | BRF_GRA },           // 16
1542 };
1543 
1544 STD_ROM_PICK(dynamski)
1545 STD_ROM_FN(dynamski)
1546 
1547 struct BurnDriver BurnDrvDynamski = {
1548 	"dynamski", NULL, NULL, NULL, "1984",
1549 	"Dynamic Ski\0", NULL, "Taiyo", "Miscellaneous",
1550 	NULL, NULL, NULL, NULL,
1551 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
1552 	NULL, dynamskiRomInfo, dynamskiRomName, NULL, NULL, NULL, NULL, DynamskiInputInfo, DynamskiDIPInfo,
1553 	DynamskiInit, DrvExit, DynamskiFrame, DynamskiDraw, DrvScan, &DrvRecalc, 0x80,
1554 	224, 288, 3, 4
1555 };
1556