1 // FB Alpha Chelnov / Karnov / Wonder Planet driver module
2 // Based on MAME driver by Bryan McPhail
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "m6502_intf.h"
7 #include "burn_ym2203.h"
8 #include "burn_ym3526.h"
9 
10 static UINT8 *AllMem;
11 static UINT8 *AllRam;
12 static UINT8 *RamEnd;
13 static UINT8 *MemEnd;
14 static UINT8 *Drv68KROM;
15 static UINT8 *Drv6502ROM;
16 static UINT8 *DrvGfxROM0;
17 static UINT8 *DrvGfxROM1;
18 static UINT8 *DrvGfxROM2;
19 static UINT8 *DrvColPROM;
20 static UINT8 *Drv68KRAM;
21 static UINT8 *DrvPfRAM;
22 static UINT8 *Drv6502RAM;
23 static UINT8 *DrvVidRAM;
24 static UINT8 *DrvSprRAM;
25 static UINT8 *DrvSprBuf;
26 
27 static UINT32 *Palette;
28 static UINT32 *DrvPalette;
29 static UINT8  DrvRecalc;
30 
31 static UINT16 *DrvScroll;
32 
33 static UINT8 *soundlatch;
34 static UINT8 *flipscreen;
35 
36 static UINT16 i8751_return;
37 static UINT16 i8751_needs_ack;
38 static UINT16 i8751_coin_pending;
39 static UINT16 i8751_command_queue;
40 static INT32 i8751_level;
41 static INT32 i8751_reset;
42 
43 static UINT8 DrvJoy1[16];
44 static UINT8 DrvJoy2[16];
45 static UINT8 DrvJoy3[16];
46 static UINT16 DrvInput[3];
47 static UINT8 DrvDip[2];
48 static UINT8 DrvReset;
49 
50 #ifdef BUILD_A68K
51 static bool bUseAsm68KCoreOldValue = false;
52 #endif
53 
54 enum { KARNOV=0, KARNOVJ, CHELNOV, CHELNOVJ, CHELNOVW, WNDRPLNT };
55 static INT32 microcontroller_id;
56 static INT32 coin_mask;
57 static INT32 vblank;
58 
59 static struct BurnInputInfo KarnovInputList[] = {
60 	{"P1 Coin",		BIT_DIGITAL,	DrvJoy3 + 2,	"p1 coin"	},
61 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 2,	"p1 start"	},
62 	{"P1 Up",		BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
63 	{"P1 Down",		BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
64 	{"P1 Left",		BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
65 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
66 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
67 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
68 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy1 + 6,	"p1 fire 3"	},
69 
70 	{"P2 Coin",		BIT_DIGITAL,	DrvJoy3 + 1,	"p2 coin"	},
71 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 start"	},
72 	{"P2 Up",		BIT_DIGITAL,	DrvJoy1 + 8,	"p2 up"		},
73 	{"P2 Down",		BIT_DIGITAL,	DrvJoy1 + 9,	"p2 down"	},
74 	{"P2 Left",		BIT_DIGITAL,	DrvJoy1 + 10,	"p2 left"	},
75 	{"P2 Right",		BIT_DIGITAL,	DrvJoy1 + 11,	"p2 right"	},
76 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy1 + 12,	"p2 fire 1"	},
77 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy1 + 13,	"p2 fire 2"	},
78 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy1 + 14,	"p2 fire 3"	},
79 
80 	{"Reset",		BIT_DIGITAL,	&DrvReset,	"reset"		},
81 	{"Service",		BIT_DIGITAL,	DrvJoy3 + 0,	"service"	},
82 	{"Dip A",		BIT_DIPSWITCH,	DrvDip + 0,	"dip"		},
83 	{"Dip B",		BIT_DIPSWITCH,	DrvDip + 1,	"dip"		},
84 };
85 
86 STDINPUTINFO(Karnov)
87 
88 static struct BurnInputInfo ChelnovInputList[] = {
89 	{"P1 Coin",		BIT_DIGITAL,	DrvJoy3 + 6,	"p1 coin"	},
90 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 2,	"p1 start"	},
91 	{"P1 Up",		BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
92 	{"P1 Down",		BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
93 	{"P1 Left",		BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
94 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
95 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
96 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
97 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy1 + 6,	"p1 fire 3"	},
98 
99 	{"P2 Coin",		BIT_DIGITAL,	DrvJoy3 + 5,	"p2 coin"	},
100 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 start"	},
101 	{"P2 Up",		BIT_DIGITAL,	DrvJoy1 + 8,	"p2 up"		},
102 	{"P2 Down",		BIT_DIGITAL,	DrvJoy1 + 9,	"p2 down"	},
103 	{"P2 Left",		BIT_DIGITAL,	DrvJoy1 + 10,	"p2 left"	},
104 	{"P2 Right",		BIT_DIGITAL,	DrvJoy1 + 11,	"p2 right"	},
105 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy1 + 12,	"p2 fire 1"	},
106 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy1 + 13,	"p2 fire 2"	},
107 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy1 + 14,	"p2 fire 3"	},
108 
109 	{"Reset",		BIT_DIGITAL,	&DrvReset,	"reset"		},
110 	{"Service",		BIT_DIGITAL,	DrvJoy3 + 7,	"service"	},
111 	{"Dip A",		BIT_DIPSWITCH,	DrvDip + 0,	"dip"		},
112 	{"Dip B",		BIT_DIPSWITCH,	DrvDip + 1,	"dip"		},
113 };
114 
115 STDINPUTINFO(Chelnov)
116 
117 static struct BurnDIPInfo KarnovDIPList[]=
118 {
119 	{0x14, 0xff, 0xff, 0xaf, NULL			},
120 	{0x15, 0xff, 0xff, 0xff, NULL			},
121 
122 	{0   , 0xfe, 0   ,    4, "Coin B"		},
123 	{0x14, 0x01, 0x03, 0x00, "2 Coins 1 Credits"	},
124 	{0x14, 0x01, 0x03, 0x03, "1 Coin  1 Credits"	},
125 	{0x14, 0x01, 0x03, 0x02, "1 Coin  2 Credits"	},
126 	{0x14, 0x01, 0x03, 0x01, "1 Coin  3 Credits"	},
127 
128 	{0   , 0xfe, 0   ,    4, "Coin A"		},
129 	{0x14, 0x01, 0x0c, 0x00, "2 Coins 1 Credits"	},
130 	{0x14, 0x01, 0x0c, 0x0c, "1 Coin  1 Credits"	},
131 	{0x14, 0x01, 0x0c, 0x08, "1 Coin  2 Credits"	},
132 	{0x14, 0x01, 0x0c, 0x04, "1 Coin  3 Credits"	},
133 
134 	{0   , 0xfe, 0   ,    2, "Flip Screen"		},
135 	{0x14, 0x01, 0x20, 0x20, "Off"			},
136 	{0x14, 0x01, 0x20, 0x00, "On"			},
137 
138 	{0   , 0xfe, 0   ,    2, "Cabinet"		},
139 	{0x14, 0x01, 0x40, 0x00, "Upright"		},
140 	{0x14, 0x01, 0x40, 0x40, "Cocktail"		},
141 
142 	{0   , 0xfe, 0   ,    4, "Lives"		},
143 	{0x15, 0x01, 0x03, 0x01, "1"			},
144 	{0x15, 0x01, 0x03, 0x03, "3"			},
145 	{0x15, 0x01, 0x03, 0x02, "5"			},
146 	{0x15, 0x01, 0x03, 0x00, "Infinite (Cheat)"	},
147 
148 	{0   , 0xfe, 0   ,    4, "Bonus Life"		},
149 	{0x15, 0x01, 0x0c, 0x0c, "50 K"			},
150 	{0x15, 0x01, 0x0c, 0x08, "70 K"			},
151 	{0x15, 0x01, 0x0c, 0x04, "90 K"			},
152 	{0x15, 0x01, 0x0c, 0x00, "100 K"		},
153 
154 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
155 	{0x15, 0x01, 0x30, 0x30, "Easy"			},
156 	{0x15, 0x01, 0x30, 0x10, "Normal"		},
157 	{0x15, 0x01, 0x30, 0x20, "Hard"			},
158 	{0x15, 0x01, 0x30, 0x00, "Very Hard"		},
159 
160 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
161 	{0x15, 0x01, 0x40, 0x00, "Off"			},
162 	{0x15, 0x01, 0x40, 0x40, "On"			},
163 
164 	{0   , 0xfe, 0   ,    2, "Timer Speed"		},
165 	{0x15, 0x01, 0x80, 0x80, "Normal"		},
166 	{0x15, 0x01, 0x80, 0x00, "Fast"			},
167 };
168 
169 STDDIPINFO(Karnov)
170 
171 static struct BurnDIPInfo WndrplntDIPList[]=
172 {
173 	{0x14, 0xff, 0xff, 0x6f, NULL			},
174 	{0x15, 0xff, 0xff, 0xd3, NULL			},
175 
176 	{0   , 0xfe, 0   ,    4, "Coin B"		},
177 	{0x14, 0x01, 0x03, 0x00, "2 Coins 1 Credits"	},
178 	{0x14, 0x01, 0x03, 0x03, "1 Coin  1 Credits"	},
179 	{0x14, 0x01, 0x03, 0x02, "1 Coin  2 Credits"	},
180 	{0x14, 0x01, 0x03, 0x01, "1 Coin  3 Credits"	},
181 
182 	{0   , 0xfe, 0   ,    4, "Coin A"		},
183 	{0x14, 0x01, 0x0c, 0x00, "2 Coins 1 Credits"	},
184 	{0x14, 0x01, 0x0c, 0x0c, "1 Coin  1 Credits"	},
185 	{0x14, 0x01, 0x0c, 0x08, "1 Coin  2 Credits"	},
186 	{0x14, 0x01, 0x0c, 0x04, "1 Coin  3 Credits"	},
187 
188 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
189 	{0x14, 0x01, 0x20, 0x00, "Off"			},
190 	{0x14, 0x01, 0x20, 0x20, "On"			},
191 
192 	{0   , 0xfe, 0   ,    2, "Flip Screen"		},
193 	{0x14, 0x01, 0x40, 0x40, "Off"			},
194 	{0x14, 0x01, 0x40, 0x00, "On"			},
195 
196 	{0   , 0xfe, 0   ,    2, "Cabinet"		},
197 	{0x14, 0x01, 0x80, 0x00, "Upright"		},
198 	{0x14, 0x01, 0x80, 0x80, "Cocktail"		},
199 
200 	{0   , 0xfe, 0   ,    4, "Lives"		},
201 	{0x15, 0x01, 0x03, 0x01, "1"			},
202 	{0x15, 0x01, 0x03, 0x03, "3"			},
203 	{0x15, 0x01, 0x03, 0x02, "5"			},
204 	{0x15, 0x01, 0x03, 0x00, "Infinite (Cheat)"	},
205 
206 	{0   , 0xfe, 0   ,    2, "Allow Continue"	},
207 	{0x15, 0x01, 0x10, 0x00, "No"			},
208 	{0x15, 0x01, 0x10, 0x10, "Yes"			},
209 
210 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
211 	{0x15, 0x01, 0xc0, 0x80, "Easy"			},
212 	{0x15, 0x01, 0xc0, 0xc0, "Normal"		},
213 	{0x15, 0x01, 0xc0, 0x40, "Hard"			},
214 	{0x15, 0x01, 0xc0, 0x00, "Hardest"		},
215 };
216 
217 STDDIPINFO(Wndrplnt)
218 
219 static struct BurnDIPInfo ChelnovDIPList[]=
220 {
221 	{0x14, 0xff, 0xff, 0x6f, NULL			},
222 	{0x15, 0xff, 0xff, 0xdf, NULL			},
223 
224 	{0   , 0xfe, 0   ,    4, "Coin A"		},
225 	{0x14, 0x01, 0x03, 0x03, "1 Coin 2 Credits"	},
226 	{0x14, 0x01, 0x03, 0x02, "1 Coin 3 Credits"	},
227 	{0x14, 0x01, 0x03, 0x01, "1 Coin 4 Credits"	},
228 	{0x14, 0x01, 0x03, 0x00, "1 Coin 6 Credits"	},
229 
230 	{0   , 0xfe, 0   ,    4, "Coin B"		},
231 	{0x14, 0x01, 0x0c, 0x00, "4 Coins 1 Credits"	},
232 	{0x14, 0x01, 0x0c, 0x04, "3 Coins 1 Credits"	},
233 	{0x14, 0x01, 0x0c, 0x08, "2 Coins 1 Credits"	},
234 	{0x14, 0x01, 0x0c, 0x0c, "1 Coin  1 Credits"	},
235 
236 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
237 	{0x14, 0x01, 0x20, 0x00, "Off"			},
238 	{0x14, 0x01, 0x20, 0x20, "On"			},
239 
240 	{0   , 0xfe, 0   ,    2, "Flip Screen"		},
241 	{0x14, 0x01, 0x40, 0x40, "Off"			},
242 	{0x14, 0x01, 0x40, 0x00, "On"			},
243 
244 	{0   , 0xfe, 0   ,    2, "Cabinet"		},
245 	{0x14, 0x01, 0x80, 0x00, "Upright"		},
246 	{0x14, 0x01, 0x80, 0x80, "Cocktail"		},
247 
248 	{0   , 0xfe, 0   ,    4, "Lives"		},
249 	{0x15, 0x01, 0x03, 0x01, "1"			},
250 	{0x15, 0x01, 0x03, 0x03, "3"			},
251 	{0x15, 0x01, 0x03, 0x02, "5"			},
252 	{0x15, 0x01, 0x03, 0x00, "Infinite (Cheat)"	},
253 
254 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
255 	{0x15, 0x01, 0x0c, 0x04, "Easy"			},
256 	{0x15, 0x01, 0x0c, 0x0c, "Normal"		},
257 	{0x15, 0x01, 0x0c, 0x08, "Hard"			},
258 	{0x15, 0x01, 0x0c, 0x00, "Hardest"		},
259 
260 	{0   , 0xfe, 0   ,    2, "Allow Continue"	},
261 	{0x15, 0x01, 0x10, 0x00, "No"			},
262 	{0x15, 0x01, 0x10, 0x10, "Yes"			},
263 
264 	{0   , 0xfe, 0   ,    2, "Freeze"		},
265 	{0x15, 0x01, 0x40, 0x40, "Off"			},
266 	{0x15, 0x01, 0x40, 0x00, "On"			},
267 };
268 
269 STDDIPINFO(Chelnov)
270 
271 static struct BurnDIPInfo ChelnovuDIPList[]=
272 {
273 	{0x14, 0xff, 0xff, 0x6f, NULL			},
274 	{0x15, 0xff, 0xff, 0xdf, NULL			},
275 
276 	{0   , 0xfe, 0   ,    4, "Coin B"		},
277 	{0x14, 0x01, 0x03, 0x00, "2 Coins 1 Credits"	},
278 	{0x14, 0x01, 0x03, 0x03, "1 Coin  1 Credits"	},
279 	{0x14, 0x01, 0x03, 0x02, "1 Coin  2 Credits"	},
280 	{0x14, 0x01, 0x03, 0x01, "1 Coin  3 Credits"	},
281 
282 	{0   , 0xfe, 0   ,    4, "Coin A"		},
283 	{0x14, 0x01, 0x0c, 0x00, "2 Coins 1 Credits"	},
284 	{0x14, 0x01, 0x0c, 0x0c, "1 Coin  1 Credits"	},
285 	{0x14, 0x01, 0x0c, 0x08, "1 Coin  2 Credits"	},
286 	{0x14, 0x01, 0x0c, 0x04, "1 Coin  3 Credits"	},
287 
288 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
289 	{0x14, 0x01, 0x20, 0x00, "Off"			},
290 	{0x14, 0x01, 0x20, 0x20, "On"			},
291 
292 	{0   , 0xfe, 0   ,    2, "Flip Screen"		},
293 	{0x14, 0x01, 0x40, 0x40, "Off"			},
294 	{0x14, 0x01, 0x40, 0x00, "On"			},
295 
296 	{0   , 0xfe, 0   ,    2, "Cabinet"		},
297 	{0x14, 0x01, 0x80, 0x00, "Upright"		},
298 	{0x14, 0x01, 0x80, 0x80, "Cocktail"		},
299 
300 	{0   , 0xfe, 0   ,    4, "Lives"		},
301 	{0x15, 0x01, 0x03, 0x01, "1"			},
302 	{0x15, 0x01, 0x03, 0x03, "3"			},
303 	{0x15, 0x01, 0x03, 0x02, "5"			},
304 	{0x15, 0x01, 0x03, 0x00, "Infinite (Cheat)"	},
305 
306 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
307 	{0x15, 0x01, 0x0c, 0x04, "Easy"			},
308 	{0x15, 0x01, 0x0c, 0x0c, "Normal"		},
309 	{0x15, 0x01, 0x0c, 0x08, "Hard"			},
310 	{0x15, 0x01, 0x0c, 0x00, "Hardest"		},
311 
312 	{0   , 0xfe, 0   ,    2, "Allow Continue"	},
313 	{0x15, 0x01, 0x10, 0x00, "No"			},
314 	{0x15, 0x01, 0x10, 0x10, "Yes"			},
315 
316 	{0   , 0xfe, 0   ,    2, "Freeze"		},
317 	{0x15, 0x01, 0x40, 0x40, "Off"			},
318 	{0x15, 0x01, 0x40, 0x00, "On"			},
319 };
320 
STDDIPINFO(Chelnovu)321 STDDIPINFO(Chelnovu)
322 
323 //------------------------------------------------------------------------------------------------
324 // These are pretty much ripped straight from MAME
325 
326 static void karnov_i8751_w(INT32 data)
327 {
328 	if (i8751_needs_ack)
329 	{
330 		i8751_command_queue=data;
331 		return;
332 	}
333 
334 	i8751_return=0;
335 	if (data==0x100 && microcontroller_id==KARNOVJ) i8751_return=0x56a; /* Japan version */
336 	if (data==0x100 && microcontroller_id==KARNOV) i8751_return=0x56b; /* USA version */
337 	if ((data&0xf00)==0x300) i8751_return=(data&0xff)*0x12; /* Player sprite mapping */
338 
339 	if (data==0x400) i8751_return=0x4000; /* Get The Map... */
340 	if (data==0x402) i8751_return=0x40a6; /* Ancient Ruins */
341 	if (data==0x403) i8751_return=0x4054; /* Forest... */
342 	if (data==0x404) i8751_return=0x40de; /* ^Rocky hills */
343 	if (data==0x405) i8751_return=0x4182; /* Sea */
344 	if (data==0x406) i8751_return=0x41ca; /* Town */
345 	if (data==0x407) i8751_return=0x421e; /* Desert */
346 	if (data==0x401) i8751_return=0x4138; /* ^Whistling wind */
347 	if (data==0x408) i8751_return=0x4276; /* ^Heavy Gates */
348 
349 	SekSetIRQLine(6, CPU_IRQSTATUS_AUTO); /* Signal main cpu task is complete */
350 	i8751_needs_ack=1;
351 }
352 
wndrplnt_i8751_w(INT32 data)353 static void wndrplnt_i8751_w(INT32 data)
354 {
355 	if (i8751_needs_ack)
356 	{
357 		i8751_command_queue=data;
358 		return;
359 	}
360 
361 	i8751_return=0;
362 	if (data==0x100) i8751_return=0x67a;
363 	if (data==0x200) i8751_return=0x214;
364 	if (data==0x300) i8751_return=0x17; /* Copyright text on title screen */
365 // 	if (data==0x300) i8751_return=0x1; /* (USA) Copyright text on title screen */
366 
367 	if ((data&0x600)==0x600)
368 	{
369 		switch (data&0x18)
370 		{
371 			case 0x00: 	i8751_return=0x4d53; break;
372 			case 0x08:	i8751_return=0x4b54; break;
373 			case 0x10: 	i8751_return=0x5453; break;
374 			case 0x18:	i8751_return=0x5341; break;
375 		}
376 	}
377 
378 	if (data==0x400) i8751_return=0x594;
379 	if (data==0x401) i8751_return=0x5ea;
380 	if (data==0x402) i8751_return=0x628;
381 	if (data==0x403) i8751_return=0x66c;
382 	if (data==0x404) i8751_return=0x6a4;
383 	if (data==0x405) i8751_return=0x6a4;
384 	if (data==0x406) i8751_return=0x6a4;
385 
386 	if (data==0x50c) i8751_return=0x13fc;
387 	if (data==0x50b) i8751_return=0x00ff;
388 	if (data==0x50a) i8751_return=0x0006;
389 	if (data==0x509) i8751_return=0x0000;
390 	if (data==0x508) i8751_return=0x4a39;
391 	if (data==0x507) i8751_return=0x0006;
392 	if (data==0x506) i8751_return=0x0000;
393 	if (data==0x505) i8751_return=0x66f8;
394 	if (data==0x504) i8751_return=0x4a39;
395 	if (data==0x503) i8751_return=0x000c;
396 	if (data==0x502) i8751_return=0x0003;
397 	if (data==0x501) i8751_return=0x6bf8;
398 	if (data==0x500) i8751_return=0x4e75;
399 
400 	SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
401 	i8751_needs_ack=1;
402 }
403 
chelnov_i8751_w(INT32 data)404 static void chelnov_i8751_w(INT32 data)
405 {
406 	if (i8751_needs_ack)
407 	{
408 		i8751_command_queue=data;
409 		return;
410 	}
411 
412 	i8751_return=0;
413 	if (data==0x200 && microcontroller_id==CHELNOVJ) i8751_return=0x7734; /* Japan version */
414 	if (data==0x200 && microcontroller_id==CHELNOV)  i8751_return=0x783e; /* USA version */
415 	if (data==0x200 && microcontroller_id==CHELNOVW)  i8751_return=0x7736; /* World version */
416 	if (data==0x100 && microcontroller_id==CHELNOVJ) i8751_return=0x71a; /* Japan version */
417 	if (data==0x100 && microcontroller_id==CHELNOV)  i8751_return=0x71b; /* USA version */
418 	if (data==0x100 && microcontroller_id==CHELNOVW)  i8751_return=0x71c; /* World version */
419 
420 	if ((data & 0xe000) == 0x6000) {
421 		if (data & 0x1000) {
422 			i8751_return = ((data & 0x0f) + ((data >> 4) & 0x0f)) * ((data >> 8) & 0x0f);
423 		} else {
424 			i8751_return = (data & 0x0f) * (((data >> 8) & 0x0f) + ((data >> 4) & 0x0f));
425 		}
426 	}
427 
428 	if ((data&0xf000)==0x1000) i8751_level=1; /* Level 1 */
429 	if ((data&0xf000)==0x2000) i8751_level++; /* Level Increment */
430 
431 	if ((data&0xf000)==0x3000)
432 	{        /* Sprite table mapping */
433 		INT32 b=data&0xff;
434 		switch (i8751_level)
435 		{
436 			case 1: /* Level 1, Sprite mapping tables */
437 				if (microcontroller_id==CHELNOV)
438 				{ /* USA */
439 					if (b<2) i8751_return=0;
440 					else if (b<6) i8751_return=1;
441 					else if (b<0xb) i8751_return=2;
442 					else if (b<0xf) i8751_return=3;
443 					else if (b<0x13) i8751_return=4;
444 					else i8751_return=5;
445 				}
446 				else
447 				{ /* Japan, World */
448 					if (b<3) i8751_return=0;
449 					else if (b<8) i8751_return=1;
450 					else if (b<0x0c) i8751_return=2;
451 					else if (b<0x10) i8751_return=3;
452 					else if (b<0x19) i8751_return=4;
453 					else if (b<0x1b) i8751_return=5;
454 					else if (b<0x22) i8751_return=6;
455 					else if (b<0x28) i8751_return=7;
456 					else i8751_return=8;
457 				}
458 				break;
459 			case 2: /* Level 2, Sprite mapping tables, USA & Japan are the same */
460 				if (b<3) i8751_return=0;
461 				else if (b<9) i8751_return=1;
462 				else if (b<0x11) i8751_return=2;
463 				else if (b<0x1b) i8751_return=3;
464 				else if (b<0x21) i8751_return=4;
465 				else if (b<0x28) i8751_return=5;
466 				else i8751_return=6;
467 				break;
468 			case 3: /* Level 3, Sprite mapping tables, USA & Japan are the same */
469 				if (b<5) i8751_return=0;
470 				else if (b<9) i8751_return=1;
471 				else if (b<0x0d) i8751_return=2;
472 				else if (b<0x11) i8751_return=3;
473 				else if (b<0x1b) i8751_return=4;
474 				else if (b<0x1c) i8751_return=5;
475 				else if (b<0x22) i8751_return=6;
476 				else if (b<0x27) i8751_return=7;
477 				else i8751_return=8;
478 				break;
479 			case 4: /* Level 4, Sprite mapping tables, USA & Japan are the same */
480 				if (b<4) i8751_return=0;
481 				else if (b<0x0c) i8751_return=1;
482 				else if (b<0x0f) i8751_return=2;
483 				else if (b<0x19) i8751_return=3;
484 				else if (b<0x1c) i8751_return=4;
485 				else if (b<0x22) i8751_return=5;
486 				else if (b<0x29) i8751_return=6;
487 				else i8751_return=7;
488 				break;
489 			case 5: /* Level 5, Sprite mapping tables */
490 				if (b<7) i8751_return=0;
491 				else if (b<0x0e) i8751_return=1;
492 				else if (b<0x14) i8751_return=2;
493 				else if (b<0x1a) i8751_return=3;
494 				else if (b<0x23) i8751_return=4;
495 				else if (b<0x27) i8751_return=5;
496 				else i8751_return=6;
497 				break;
498 			case 6: /* Level 6, Sprite mapping tables */
499 				if (b<3) i8751_return=0;
500 				else if (b<0x0b) i8751_return=1;
501 				else if (b<0x11) i8751_return=2;
502 				else if (b<0x17) i8751_return=3;
503 				else if (b<0x1d) i8751_return=4;
504 				else if (b<0x24) i8751_return=5;
505 				else i8751_return=6;
506 				break;
507 			case 7: /* Level 7, Sprite mapping tables */
508 				if (b<5) i8751_return=0;
509 				else if (b<0x0b) i8751_return=1;
510 				else if (b<0x11) i8751_return=2;
511 				else if (b<0x1a) i8751_return=3;
512 				else if (b<0x21) i8751_return=4;
513 				else if (b<0x27) i8751_return=5;
514 				else i8751_return=6;
515 				break;
516 		}
517 	}
518 
519 	SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
520 	i8751_needs_ack=1;
521 }
522 
karnov_control_w(INT32 offset,INT32 data)523 static void karnov_control_w(INT32 offset, INT32 data)
524 {
525 	switch (offset<<1)
526 	{
527 		case 0:
528 			SekSetIRQLine(6, CPU_IRQSTATUS_NONE);
529 
530 			if (i8751_needs_ack)
531 			{
532 				if (i8751_coin_pending)
533 				{
534 					i8751_return=i8751_coin_pending;
535 					SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
536 					i8751_coin_pending=0;
537 				}
538 				else if (i8751_command_queue)
539 				{
540 					i8751_needs_ack=0;
541 					karnov_control_w(3,i8751_command_queue);
542 					i8751_command_queue=0;
543 				}
544 				else
545 				{
546 					i8751_needs_ack=0;
547 				}
548 			}
549 			return;
550 
551 		case 2:
552 			*soundlatch = data;
553 			M6502SetIRQLine(M6502_INPUT_LINE_NMI, CPU_IRQSTATUS_AUTO);
554 			break;
555 
556 		case 4:
557 			memcpy (DrvSprBuf, DrvSprRAM, 0x1000);
558 			break;
559 
560 		case 6:
561 			if (microcontroller_id==KARNOV  || microcontroller_id==KARNOVJ) karnov_i8751_w(data);
562 			if (microcontroller_id==CHELNOV || microcontroller_id==CHELNOVJ || microcontroller_id==CHELNOVW) chelnov_i8751_w(data);
563 			if (microcontroller_id==WNDRPLNT) wndrplnt_i8751_w(data);
564 			break;
565 
566 		case 8:
567 			DrvScroll[0] = data;
568 			*flipscreen = data >> 15;
569 			break;
570 
571 		case 0xa:
572 			DrvScroll[1] = data;
573 			break;
574 
575 		case 0xc:
576 			i8751_needs_ack=0;
577 			i8751_coin_pending=0;
578 			i8751_command_queue=0;
579 			i8751_return=0;
580 			break;
581 
582 		case 0xe:
583 			SekSetIRQLine(7, CPU_IRQSTATUS_NONE);
584 			break;
585 	}
586 }
587 
karnov_control_r(INT32 offset)588 static UINT16 karnov_control_r(INT32 offset)
589 {
590 	switch (offset<<1)
591 	{
592 		case 0:
593 			return DrvInput[0];
594 		case 2:
595 			return DrvInput[1] ^ vblank;
596 		case 4:
597 			return (DrvDip[1] << 8) | DrvDip[0];
598 		case 6:
599 			return i8751_return;
600 	}
601 
602 	return ~0;
603 }
604 
605 //------------------------------------------------------------------------------------------
606 
karnov_main_write_word(UINT32 address,UINT16 data)607 static void __fastcall karnov_main_write_word(UINT32 address, UINT16 data)
608 {
609 	if ((address & 0xfff800) == 0x0a1800) {
610 		UINT16 *ptr = (UINT16*)DrvPfRAM;
611 
612 		INT32 offset = (address >> 1) & 0x3ff;
613 		offset = ((offset & 0x1f) << 5) | ((offset & 0x3e0) >> 5);
614 
615 		ptr[offset] = BURN_ENDIAN_SWAP_INT16(data);
616 		return;
617 	}
618 
619 	if ((address & 0xfffff0) == 0x0c0000) {
620 		karnov_control_w((address >> 1) & 0x07, data);
621 		return;
622 	}
623 }
624 
karnov_main_write_byte(UINT32 address,UINT8 data)625 static void __fastcall karnov_main_write_byte(UINT32 address, UINT8 data)
626 {
627 	if ((address & 0xfff800) == 0x0a1800) {
628 		INT32 offset = (address >> 1) & 0x3ff;
629 		offset = ((offset & 0x1f) << 5) | ((offset & 0x3e0) >> 5);
630 
631 		DrvPfRAM[(offset << 1) | (~address & 1)] = data;
632 		return;
633 	}
634 
635 	if ((address & 0xfffff0) == 0x0c0000) {
636 		karnov_control_w((address >> 1) & 0x07, data);
637 
638 	}
639 }
640 
karnov_main_read_word(UINT32 address)641 static UINT16 __fastcall karnov_main_read_word(UINT32 address)
642 {
643 	if ((address & 0xfffff0) == 0x0c0000) {
644 		return karnov_control_r((address >> 1) & 7);
645 	}
646 
647 	return 0;
648 }
649 
karnov_main_read_byte(UINT32 address)650 static UINT8 __fastcall karnov_main_read_byte(UINT32 address)
651 {
652 	if ((address & 0xfffff0) == 0x0c0000) {
653 		return karnov_control_r((address >> 1) & 7) >> ((~address & 1) << 3);
654 	}
655 
656 	return 0;
657 }
658 
karnov_sound_write(UINT16 address,UINT8 data)659 static void karnov_sound_write(UINT16 address, UINT8 data)
660 {
661 	switch (address)
662 	{
663 		case 0x1000:
664 		case 0x1001:
665 			BurnYM2203Write(0, address & 1, data);
666 		return;
667 
668 		case 0x1800:
669 		case 0x1801:
670 			BurnYM3526Write(address & 1, data);
671 		return;
672 	}
673 }
674 
karnov_sound_read(UINT16 address)675 UINT8 karnov_sound_read(UINT16 address)
676 {
677 	switch (address)
678 	{
679 		case 0x0800:
680 //			m6502SetIRQ(M6502_CLEAR);
681 			return *soundlatch;
682 	}
683 
684 	return 0;
685 }
686 
DrvYM3526FMIRQHandler(INT32,INT32 nStatus)687 static void DrvYM3526FMIRQHandler(INT32, INT32 nStatus)
688 {
689 	if (nStatus) {
690 		M6502SetIRQLine(M6502_IRQ_LINE, CPU_IRQSTATUS_ACK);
691 	} else {
692 		M6502SetIRQLine(M6502_IRQ_LINE, CPU_IRQSTATUS_NONE);
693 	}
694 }
695 
DrvDoReset()696 static INT32 DrvDoReset()
697 {
698 	DrvReset = 0;
699 
700 	memset (AllRam, 0, RamEnd - AllRam);
701 
702 	SekOpen(0);
703 	M6502Open(0);
704 
705 	SekReset();
706 	M6502Reset();
707 
708 	BurnYM3526Reset();
709 	BurnYM2203Reset();
710 
711 	M6502Close();
712 	SekClose();
713 
714 	HiscoreReset();
715 
716 	i8751_return = 0;
717 	i8751_needs_ack = 0;
718 	i8751_coin_pending = 0;
719 	i8751_command_queue = 0;
720 	i8751_level = 0;
721 	i8751_reset = 0;
722 
723 	return 0;
724 }
725 
MemIndex()726 static INT32 MemIndex()
727 {
728 	UINT8 *Next; Next = AllMem;
729 
730 	Drv68KROM		= Next; Next += 0x060000;
731 	Drv6502ROM		= Next; Next += 0x010000;
732 
733 	DrvGfxROM0		= Next; Next += 0x020000;
734 	DrvGfxROM1		= Next; Next += 0x080000;
735 	DrvGfxROM2		= Next; Next += 0x100000;
736 
737 	DrvColPROM		= Next; Next += 0x000800;
738 
739 	Palette			= (UINT32*)Next; Next += 0x0300 * sizeof(UINT32);
740 	DrvPalette		= (UINT32*)Next; Next += 0x0300 * sizeof(UINT32);
741 
742 	AllRam			= Next;
743 
744 	Drv68KRAM		= Next; Next += 0x004000;
745 	DrvPfRAM		= Next; Next += 0x000800;
746 	Drv6502RAM		= Next; Next += 0x000800;
747 	DrvVidRAM		= Next; Next += 0x000800;
748 	DrvSprRAM		= Next; Next += 0x001000;
749 	DrvSprBuf		= Next; Next += 0x001000;
750 
751 	soundlatch		= Next; Next += 0x000001;
752 	flipscreen		= Next; Next += 0x000001;
753 
754 	DrvScroll		= (UINT16*)Next; Next += 0x0002 * sizeof(UINT16);
755 
756 	RamEnd			= Next;
757 	MemEnd			= Next;
758 
759 	return 0;
760 }
761 
DrvPaletteInit()762 static void DrvPaletteInit()
763 {
764 	for (INT32 i = 0; i < 0x300; i++)
765 	{
766 		INT32 bit0,bit1,bit2,bit3,r,g,b;
767 
768 		bit0 = (DrvColPROM[0x000 + i] >> 0) & 0x01;
769 		bit1 = (DrvColPROM[0x000 + i] >> 1) & 0x01;
770 		bit2 = (DrvColPROM[0x000 + i] >> 2) & 0x01;
771 		bit3 = (DrvColPROM[0x000 + i] >> 3) & 0x01;
772 		r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
773 
774 		bit0 = (DrvColPROM[0x000 + i] >> 4) & 0x01;
775 		bit1 = (DrvColPROM[0x000 + i] >> 5) & 0x01;
776 		bit2 = (DrvColPROM[0x000 + i] >> 6) & 0x01;
777 		bit3 = (DrvColPROM[0x000 + i] >> 7) & 0x01;
778 		g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
779 
780 		bit0 = (DrvColPROM[0x400 + i] >> 0) & 0x01;
781 		bit1 = (DrvColPROM[0x400 + i] >> 1) & 0x01;
782 		bit2 = (DrvColPROM[0x400 + i] >> 2) & 0x01;
783 		bit3 = (DrvColPROM[0x400 + i] >> 3) & 0x01;
784 		b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
785 
786 		Palette[i] = (r << 16) | (g << 8) | b;
787 		DrvPalette[i] = BurnHighCol(r, g, b, 0);
788 	}
789 }
790 
DrvGfxDecode()791 static INT32 DrvGfxDecode()
792 {
793 	INT32 Plane0[3] = { 0x6000*8,0x4000*8,0x2000*8 };
794 	INT32 Plane1[4] = { 0x60000*8,0x00000*8,0x20000*8,0x40000*8 };
795 	INT32 XOffs[16] = { 16*8, 1+(16*8), 2+(16*8), 3+(16*8), 4+(16*8), 5+(16*8), 6+(16*8), 7+(16*8), 0,1,2,3,4,5,6,7 };
796 	INT32 YOffs[16] = { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 ,8*8,9*8,10*8,11*8,12*8,13*8,14*8,15*8 };
797 
798 	UINT8 *tmp = (UINT8*)BurnMalloc(0x80000);
799 	if (tmp == NULL) {
800 		return 1;
801 	}
802 
803 	memcpy (tmp, DrvGfxROM0, 0x08000);
804 
805 	GfxDecode(0x0400, 3,  8,  8, Plane0, XOffs + 8, YOffs, 0x040, tmp, DrvGfxROM0);
806 
807 	memcpy (tmp, DrvGfxROM1, 0x80000);
808 
809 	GfxDecode(0x0800, 4, 16, 16, Plane1, XOffs + 0, YOffs, 0x100, tmp, DrvGfxROM1);
810 
811 	memcpy (tmp, DrvGfxROM2, 0x80000);
812 
813 	GfxDecode(0x1000, 4, 16, 16, Plane1, XOffs + 0, YOffs, 0x100, tmp, DrvGfxROM2);
814 
815 	BurnFree (tmp);
816 
817 	return 0;
818 }
819 
DrvInit()820 static INT32 DrvInit()
821 {
822 	AllMem = NULL;
823 	MemIndex();
824 	INT32 nLen = MemEnd - (UINT8 *)0;
825 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
826 	memset(AllMem, 0, nLen);
827 	MemIndex();
828 
829 	{
830 		if (BurnLoadRom(Drv68KROM + 0x000001,  0, 2)) return 1;
831 		if (BurnLoadRom(Drv68KROM + 0x000000,  1, 2)) return 1;
832 		if (BurnLoadRom(Drv68KROM + 0x020001,  2, 2)) return 1;
833 		if (BurnLoadRom(Drv68KROM + 0x020000,  3, 2)) return 1;
834 		if (BurnLoadRom(Drv68KROM + 0x040001,  4, 2)) return 1;
835 		if (BurnLoadRom(Drv68KROM + 0x040000,  5, 2)) return 1;
836 
837 		if (BurnLoadRom(Drv6502ROM + 0x08000,  6, 1)) return 1;
838 
839 		if (BurnLoadRom(DrvGfxROM0 + 0x00000,  7, 1)) return 1;
840 
841 		if (BurnLoadRom(DrvGfxROM1 + 0x00000,  8, 1)) return 1;
842 		if (BurnLoadRom(DrvGfxROM1 + 0x20000,  9, 1)) return 1;
843 		if (BurnLoadRom(DrvGfxROM1 + 0x40000, 10, 1)) return 1;
844 		if (BurnLoadRom(DrvGfxROM1 + 0x60000, 11, 1)) return 1;
845 
846 		if (microcontroller_id == CHELNOVJ || microcontroller_id == CHELNOVW || microcontroller_id == CHELNOV) {
847 			if (BurnLoadRom(DrvGfxROM2 + 0x00000, 12, 1)) return 1;
848 			if (BurnLoadRom(DrvGfxROM2 + 0x20000, 13, 1)) return 1;
849 			if (BurnLoadRom(DrvGfxROM2 + 0x40000, 14, 1)) return 1;
850 			if (BurnLoadRom(DrvGfxROM2 + 0x60000, 15, 1)) return 1;
851 
852 			if (BurnLoadRom(DrvColPROM + 0x00000, 16, 1)) return 1;
853 			if (BurnLoadRom(DrvColPROM + 0x00400, 17, 1)) return 1;
854 
855 			// hack to bypass infinite loop waiting for mcu response
856 		//	*((UINT16*)(Drv68KROM + 0x062a)) = BURN_ENDIAN_SWAP_INT16(0x4E71);
857 		} else {
858 			if (BurnLoadRom(DrvGfxROM2 + 0x00000, 12, 1)) return 1;
859 			if (BurnLoadRom(DrvGfxROM2 + 0x10000, 13, 1)) return 1;
860 			if (BurnLoadRom(DrvGfxROM2 + 0x20000, 14, 1)) return 1;
861 			if (BurnLoadRom(DrvGfxROM2 + 0x30000, 15, 1)) return 1;
862 			if (BurnLoadRom(DrvGfxROM2 + 0x40000, 16, 1)) return 1;
863 			if (BurnLoadRom(DrvGfxROM2 + 0x50000, 17, 1)) return 1;
864 			if (BurnLoadRom(DrvGfxROM2 + 0x60000, 18, 1)) return 1;
865 			if (BurnLoadRom(DrvGfxROM2 + 0x70000, 19, 1)) return 1;
866 
867 			if (BurnLoadRom(DrvColPROM + 0x00000, 20, 1)) return 1;
868 			if (BurnLoadRom(DrvColPROM + 0x00400, 21, 1)) return 1;
869 		}
870 
871 		DrvPaletteInit();
872 		DrvGfxDecode();
873 	}
874 
875 #ifdef BUILD_A68K
876 	// These games really don't like the ASM core, so disable it for now
877 	// and restore it on exit.
878 	if (bBurnUseASMCPUEmulation) {
879 		bUseAsm68KCoreOldValue = bBurnUseASMCPUEmulation;
880 		bBurnUseASMCPUEmulation = false;
881 	}
882 #endif
883 
884 	SekInit(0, 0x68000);
885 	SekOpen(0);
886 	SekMapMemory(Drv68KROM,		0x000000, 0x05ffff, MAP_ROM);
887 	SekMapMemory(Drv68KRAM,		0x060000, 0x063fff, MAP_RAM);
888 	SekMapMemory(DrvSprRAM,		0x080000, 0x080fff, MAP_RAM);
889 	SekMapMemory(DrvVidRAM,		0x0a0000, 0x0a07ff, MAP_RAM);
890 	SekMapMemory(DrvVidRAM,		0x0a0800, 0x0a0fff, MAP_RAM);
891 	SekMapMemory(DrvPfRAM,		0x0a1000, 0x0a17ff, MAP_WRITE);
892 	SekSetWriteWordHandler(0,	karnov_main_write_word);
893 	SekSetWriteByteHandler(0,	karnov_main_write_byte);
894 	SekSetReadWordHandler(0,	karnov_main_read_word);
895 	SekSetReadByteHandler(0,	karnov_main_read_byte);
896 	SekClose();
897 
898 	M6502Init(0, TYPE_M6502);
899 	M6502Open(0);
900 	M6502MapMemory(Drv6502RAM,		0x0000, 0x05ff, MAP_RAM);
901 	M6502MapMemory(Drv6502ROM + 0x8000,	0x8000, 0xffff, MAP_ROM);
902 	M6502SetReadHandler(karnov_sound_read);
903 	M6502SetWriteHandler(karnov_sound_write);
904 	M6502Close();
905 
906 	BurnYM3526Init(3000000, &DrvYM3526FMIRQHandler, 0);
907 	BurnTimerAttachYM3526(&M6502Config, 1500000);
908 	BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
909 
910 	BurnYM2203Init(1, 1500000, NULL, 1);
911 	BurnTimerAttachSek(10000000);
912 	BurnYM2203SetAllRoutes(0, 0.25, BURN_SND_ROUTE_BOTH);
913 
914 	GenericTilesInit();
915 
916 	DrvDoReset();
917 
918 	return 0;
919 }
920 
DrvExit()921 static INT32 DrvExit()
922 {
923 	GenericTilesExit();
924 
925 	SekExit();
926 	M6502Exit();
927 
928 	BurnYM3526Exit();
929 	BurnYM2203Exit();
930 
931 	BurnFree (AllMem);
932 
933 #ifdef BUILD_A68K
934 	if (bUseAsm68KCoreOldValue) {
935 		bBurnUseASMCPUEmulation = true;
936 	}
937 #endif
938 
939 	return 0;
940 }
941 
draw_txt_layer(INT32 swap)942 static void draw_txt_layer(INT32 swap)
943 {
944 	UINT16 *vram = (UINT16*)DrvVidRAM;
945 	for (INT32 offs = 0x20; offs < 0x3e0; offs++)
946 	{
947 		INT32 sx = (offs & 0x1f) << 3;
948 		INT32 sy = (offs >> 5) << 3;
949 
950 		if (swap) {
951 			INT32 t = sx;
952 			sx = sy;
953 			sy = t;
954 		}
955 
956 		if (*flipscreen) {
957 			sy ^= 0xf8;
958 			sx ^= 0xf8;
959 		}
960 
961 		if (microcontroller_id == WNDRPLNT) {
962 			sy -= 8;
963 		}
964 
965 		INT32 code  = BURN_ENDIAN_SWAP_INT16(vram[offs]) & 0x0fff;
966 		INT32 color = BURN_ENDIAN_SWAP_INT16(vram[offs]) >> 14;
967 
968 		if (code == 0) continue;
969 
970 		if (*flipscreen) {
971 			Render8x8Tile_Mask_FlipXY(pTransDraw, code, sx, sy, color, 3, 0, 0, DrvGfxROM0);
972 		} else {
973 			Render8x8Tile_Mask(pTransDraw, code, sx, sy, color, 3, 0, 0, DrvGfxROM0);
974 		}
975 	}
976 }
977 
draw_bg_layer()978 static void draw_bg_layer()
979 {
980 	INT32 scrollx = DrvScroll[0] & 0x1ff;
981 	INT32 scrolly = DrvScroll[1] & 0x1ff;
982 
983 	UINT16 *vram = (UINT16*)DrvPfRAM;
984 
985 	for (INT32 offs = 0; offs < 0x400; offs++)
986 	{
987 		INT32 sx = (offs & 0x1f) << 4;
988 		INT32 sy = (offs >> 5) << 4;
989 
990 		sy -= scrolly;
991 		if (sy < -15) sy+=512;
992 		sx -= scrollx;
993 		if (sx < -15) sx+=512;
994 
995 		if (sx >= nScreenWidth || sy >= nScreenHeight) continue;
996 
997 		INT32 attr = BURN_ENDIAN_SWAP_INT16(vram[offs]);
998 		INT32 code = attr & 0x7ff;
999 		INT32 color= attr >> 12;
1000 
1001 		if (*flipscreen) {
1002 			Render16x16Tile_FlipXY_Clip(pTransDraw, code, 240 - sx, (240 - sy) - 8, color, 4, 0x200, DrvGfxROM1);
1003 		} else {
1004 			Render16x16Tile_Clip(pTransDraw, code, sx, sy, color, 4, 0x200, DrvGfxROM1);
1005 		}
1006 	}
1007 }
1008 
sprite_routine(INT32 code,INT32 sx,INT32 sy,INT32 color,INT32 fy,INT32 fx)1009 static inline void sprite_routine(INT32 code, INT32 sx, INT32 sy, INT32 color, INT32 fy, INT32 fx)
1010 {
1011 	if (fy) {
1012 		if (fx) {
1013 			Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x100, DrvGfxROM2);
1014 		} else {
1015 			Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x100, DrvGfxROM2);
1016 		}
1017 	} else {
1018 		if (fx) {
1019 			Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x100, DrvGfxROM2);
1020 		} else {
1021 			Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x100, DrvGfxROM2);
1022 		}
1023 	}
1024 }
1025 
draw_sprites()1026 static void draw_sprites()
1027 {
1028 	UINT16 *ram = (UINT16*)DrvSprBuf;
1029 
1030 	for (INT32 offs = 0; offs < 0x800; offs+=4)
1031 	{
1032 		INT32 y = BURN_ENDIAN_SWAP_INT16(ram[offs]);
1033 		INT32 x = BURN_ENDIAN_SWAP_INT16(ram[offs + 2]) & 0x1ff;
1034 		if (~y & 0x8000) continue;
1035 		y &= 0x1ff;
1036 
1037 		INT32 sprite = BURN_ENDIAN_SWAP_INT16(ram[offs + 3]);
1038 		INT32 color = sprite >> 12;
1039 		sprite &= 0xfff;
1040 
1041 		INT32 flipx = BURN_ENDIAN_SWAP_INT16(ram[offs + 1]);
1042 		INT32 flipy = flipx & 0x02;
1043 		INT32 extra = flipx & 0x10;
1044 		flipx &= 0x04;
1045 
1046 		x = (x + 16) & 0x1ff;
1047 		y = (y + 16 + extra) & 0x1ff;
1048 		x = 256 - x;
1049 		y = 256 - y;
1050 
1051 		if (*flipscreen) {
1052 			y = 240 - y;
1053 			x = 240 - x;
1054 			flipx ^= 0x04;
1055 			flipy ^= 0x02;
1056 			if (extra) y -= 16;
1057 			y -= 8;
1058 		}
1059 
1060 		INT32 sprite2 = sprite + 1;
1061 		if (extra && flipy) {
1062 			sprite2--;
1063 			sprite++;
1064 		}
1065 
1066 		sprite_routine(sprite, x, y, color, flipy, flipx);
1067 
1068 		if (extra) sprite_routine(sprite2, x, y + 16, color, flipy, flipx);
1069 	}
1070 }
1071 
DrvDraw()1072 static INT32 DrvDraw()
1073 {
1074 	if (DrvRecalc) {
1075 		UINT8 r,g,b;
1076 		for (INT32 i = 0; i < 0x300; i++) {
1077 			INT32 d = Palette[i];
1078 
1079 			r = d >> 16;
1080 			g = d >> 8;
1081 			b = d >> 0;
1082 
1083 			DrvPalette[i] = BurnHighCol(r, g, b, 0);
1084 		}
1085 		DrvRecalc = 0;
1086 	}
1087 
1088 	draw_bg_layer();
1089 	draw_sprites();
1090 	draw_txt_layer(microcontroller_id == WNDRPLNT);
1091 
1092 	BurnTransferCopy(DrvPalette);
1093 
1094 	return 0;
1095 }
1096 
DrvInterrupt()1097 static void DrvInterrupt()
1098 {
1099 	static INT32 latch = 0;
1100 
1101 	if (DrvInput[2] == coin_mask) latch=1;
1102 	if (DrvInput[2] != coin_mask && latch)
1103 	{
1104 		if (i8751_needs_ack)
1105 		{
1106 			i8751_coin_pending = DrvInput[2] | 0x8000;
1107 		}
1108 		else
1109 		{
1110 			i8751_return = DrvInput[2] | 0x8000;
1111 			SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
1112 			SekRun(100);
1113 			i8751_needs_ack=1;
1114 		}
1115 		latch=0;
1116 	}
1117 
1118 	SekSetIRQLine(7, CPU_IRQSTATUS_AUTO);
1119 }
1120 
DrvFrame()1121 static INT32 DrvFrame()
1122 {
1123 	if (DrvReset) {
1124 		DrvDoReset();
1125 	}
1126 
1127 	SekNewFrame();
1128 	M6502NewFrame();
1129 
1130 	{
1131 		memset (DrvInput, 0xff, 2 * sizeof(INT16));
1132 		DrvInput[2] = coin_mask;
1133 		for (INT32 i = 0; i < 16; i++) {
1134 			DrvInput[0] ^= (DrvJoy1[i] & 1) << i;
1135 			DrvInput[1] ^= (DrvJoy2[i] & 1) << i;
1136 			DrvInput[2] ^= (DrvJoy3[i] & 1) << i;
1137 		}
1138 	}
1139 
1140 	INT32 nInterleave = 256;
1141 	INT32 nCyclesTotal[2] = { 10000000 / 60, 1500000 / 60 };
1142 
1143 	M6502Open(0);
1144 	SekOpen(0);
1145 
1146 	vblank = 0x80;
1147 
1148 	for (INT32 i = 0; i < nInterleave; i++)
1149 	{
1150 		if (i == 240) {
1151 			vblank = 0x00;
1152 			DrvInterrupt();
1153 		}
1154 
1155 		BurnTimerUpdate((i + 1) * (nCyclesTotal[0] / nInterleave));
1156 
1157 		BurnTimerUpdateYM3526((i + 1) * (nCyclesTotal[1] / nInterleave));
1158 	}
1159 
1160 	BurnTimerEndFrame(nCyclesTotal[0]);
1161 	BurnTimerEndFrameYM3526(nCyclesTotal[1]);
1162 
1163 	if (pBurnSoundOut) {
1164 		BurnYM3526Update(pBurnSoundOut, nBurnSoundLen);
1165 		BurnYM2203Update(pBurnSoundOut, nBurnSoundLen);
1166 	}
1167 
1168 	if (i8751_reset == 0) {
1169 		chelnov_i8751_w(0);
1170 		i8751_reset = 1;
1171 	}
1172 
1173 	SekClose();
1174 	M6502Close();
1175 
1176 	if (pBurnDraw) {
1177 		DrvDraw();
1178 	}
1179 
1180 	return 0;
1181 }
1182 
DrvScan(INT32 nAction,INT32 * pnMin)1183 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
1184 {
1185 	struct BurnArea ba;
1186 
1187 	if (pnMin != NULL) {
1188 		*pnMin = 0x029707;
1189 	}
1190 
1191 	if (nAction & ACB_MEMORY_RAM) {
1192 		memset(&ba, 0, sizeof(ba));
1193 		ba.Data	  = AllRam;
1194 		ba.nLen	  = RamEnd-AllRam;
1195 		ba.szName = "All Ram";
1196 		BurnAcb(&ba);
1197 	}
1198 
1199 	if (nAction & ACB_DRIVER_DATA) {
1200 		SekScan(nAction);
1201 		M6502Scan(nAction);
1202 
1203 		SekOpen(0);
1204 		M6502Open(0);
1205 		BurnYM3526Scan(nAction, pnMin);
1206 		BurnYM2203Scan(nAction, pnMin);
1207 		M6502Close();
1208 		SekClose();
1209 
1210 		if (nAction & ACB_WRITE) {
1211 			BurnYM2203Reset(); // Prevent hung sounds on savestate load (weird!) - dink
1212 		}
1213 
1214 		SCAN_VAR(i8751_return);
1215 		SCAN_VAR(i8751_needs_ack);
1216 		SCAN_VAR(i8751_coin_pending);
1217 		SCAN_VAR(i8751_command_queue);
1218 		SCAN_VAR(i8751_level);
1219 		SCAN_VAR(i8751_reset);
1220 	}
1221 
1222 	return 0;
1223 }
1224 
1225 
1226 // Karnov (US, rev 6)
1227 
1228 static struct BurnRomInfo karnovRomDesc[] = {
1229 	{ "dn08-6",		0x10000, 0x4c60837f, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1230 	{ "dn11-6",		0x10000, 0xcd4abb99, 1 | BRF_PRG | BRF_ESS }, //  1
1231 	{ "dn07-",		0x10000, 0xfc14291b, 1 | BRF_PRG | BRF_ESS }, //  2
1232 	{ "dn10-",		0x10000, 0xa4a34e37, 1 | BRF_PRG | BRF_ESS }, //  3
1233 	{ "dn06-5",		0x10000, 0x29d64e42, 1 | BRF_PRG | BRF_ESS }, //  4
1234 	{ "dn09-5",		0x10000, 0x072d7c49, 1 | BRF_PRG | BRF_ESS }, //  5
1235 
1236 	{ "dn05-5",		0x08000, 0xfa1a31a8, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1237 
1238 	{ "dn00-",		0x08000, 0x0ed77c6d, 3 | BRF_GRA},            //  7 Characters
1239 
1240 	{ "dn04-",		0x10000, 0xa9121653, 4 | BRF_GRA},            //  8 Tiles
1241 	{ "dn01-",		0x10000, 0x18697c9e, 4 | BRF_GRA},            //  9
1242 	{ "dn03-",		0x10000, 0x90d9dd9c, 4 | BRF_GRA},            // 10
1243 	{ "dn02-",		0x10000, 0x1e04d7b9, 4 | BRF_GRA},            // 11
1244 
1245 	{ "dn12-",		0x10000, 0x9806772c, 5 | BRF_GRA},            // 12 Sprites
1246 	{ "dn14-5",		0x08000, 0xac9e6732, 5 | BRF_GRA},            // 13
1247 	{ "dn13-",		0x10000, 0xa03308f9, 5 | BRF_GRA},            // 14
1248 	{ "dn15-5",		0x08000, 0x8933fcb8, 5 | BRF_GRA},            // 15
1249 	{ "dn16-",		0x10000, 0x55e63a11, 5 | BRF_GRA},            // 16
1250 	{ "dn17-5",		0x08000, 0xb70ae950, 5 | BRF_GRA},            // 17
1251 	{ "dn18-",		0x10000, 0x2ad53213, 5 | BRF_GRA},            // 18
1252 	{ "dn19-5",		0x08000, 0x8fd4fa40, 5 | BRF_GRA},            // 19
1253 
1254 	{ "karnprom.21",	0x00400, 0xaab0bb93, 6 | BRF_GRA},            // 20 Color Color Proms
1255 	{ "karnprom.20",	0x00400, 0x02f78ffb, 6 | BRF_GRA},            // 21
1256 
1257 	{ "karnov_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1258 };
1259 
1260 STD_ROM_PICK(karnov)
STD_ROM_FN(karnov)1261 STD_ROM_FN(karnov)
1262 
1263 static INT32 KarnovInit()
1264 {
1265 	microcontroller_id = KARNOV;
1266 	coin_mask = 0;
1267 
1268 	return DrvInit();
1269 }
1270 
1271 struct BurnDriver BurnDrvKarnov = {
1272 	"karnov", NULL, NULL, NULL, "1987",
1273 	"Karnov (US, rev 6)\0", NULL, "Data East USA", "Miscellaneous",
1274 	NULL, NULL, NULL, NULL,
1275 	BDF_GAME_WORKING | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1276 	NULL, karnovRomInfo, karnovRomName, NULL, NULL, NULL, NULL, KarnovInputInfo, KarnovDIPInfo,
1277 	KarnovInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1278 	&DrvRecalc, 0x300, 256, 248, 4, 3
1279 };
1280 
1281 
1282 // Karnov (US, rev 5)
1283 
1284 static struct BurnRomInfo karnovaRomDesc[] = {
1285 	{ "dn08-5",		0x10000, 0xdb92c264, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1286 	{ "dn11-5",		0x10000, 0x05669b4b, 1 | BRF_PRG | BRF_ESS }, //  1
1287 	{ "dn07-",		0x10000, 0xfc14291b, 1 | BRF_PRG | BRF_ESS }, //  2
1288 	{ "dn10-",		0x10000, 0xa4a34e37, 1 | BRF_PRG | BRF_ESS }, //  3
1289 	{ "dn06-5",		0x10000, 0x29d64e42, 1 | BRF_PRG | BRF_ESS }, //  4
1290 	{ "dn09-5",		0x10000, 0x072d7c49, 1 | BRF_PRG | BRF_ESS }, //  5
1291 
1292 	{ "dn05-5",		0x08000, 0xfa1a31a8, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1293 
1294 	{ "dn00-",		0x08000, 0x0ed77c6d, 3 | BRF_GRA},            //  7 Characters
1295 
1296 	{ "dn04-",		0x10000, 0xa9121653, 4 | BRF_GRA},            //  8 Tiles
1297 	{ "dn01-",		0x10000, 0x18697c9e, 4 | BRF_GRA},            //  9
1298 	{ "dn03-",		0x10000, 0x90d9dd9c, 4 | BRF_GRA},            // 10
1299 	{ "dn02-",		0x10000, 0x1e04d7b9, 4 | BRF_GRA},            // 11
1300 
1301 	{ "dn12-",		0x10000, 0x9806772c, 5 | BRF_GRA},            // 12 Sprites
1302 	{ "dn14-5",		0x08000, 0xac9e6732, 5 | BRF_GRA},            // 13
1303 	{ "dn13-",		0x10000, 0xa03308f9, 5 | BRF_GRA},            // 14
1304 	{ "dn15-5",		0x08000, 0x8933fcb8, 5 | BRF_GRA},            // 15
1305 	{ "dn16-",		0x10000, 0x55e63a11, 5 | BRF_GRA},            // 16
1306 	{ "dn17-5",		0x08000, 0xb70ae950, 5 | BRF_GRA},            // 17
1307 	{ "dn18-",		0x10000, 0x2ad53213, 5 | BRF_GRA},            // 18
1308 	{ "dn19-5",		0x08000, 0x8fd4fa40, 5 | BRF_GRA},            // 19
1309 
1310 	{ "karnprom.21",	0x00400, 0xaab0bb93, 6 | BRF_GRA},            // 20 Color Color Proms
1311 	{ "karnprom.20",	0x00400, 0x02f78ffb, 6 | BRF_GRA},            // 21
1312 
1313 	{ "karnov_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1314 };
1315 
1316 STD_ROM_PICK(karnova)
1317 STD_ROM_FN(karnova)
1318 
1319 struct BurnDriver BurnDrvKarnova = {
1320 	"karnova", "karnov", NULL, NULL, "1987",
1321 	"Karnov (US, rev 5)\0", NULL, "Data East USA", "Miscellaneous",
1322 	NULL, NULL, NULL, NULL,
1323 	BDF_GAME_WORKING | BDF_CLONE | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1324 	NULL, karnovaRomInfo, karnovaRomName, NULL, NULL, NULL, NULL, KarnovInputInfo, KarnovDIPInfo,
1325 	KarnovInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1326 	&DrvRecalc, 0x300, 256, 248, 4, 3
1327 };
1328 
1329 
1330 // Karnov (Japan)
1331 
1332 static struct BurnRomInfo karnovjRomDesc[] = {
1333 	{ "kar8",		0x10000, 0x3e17e268, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1334 	{ "kar11",		0x10000, 0x417c936d, 1 | BRF_PRG | BRF_ESS }, //  1
1335 	{ "dn07-",		0x10000, 0xfc14291b, 1 | BRF_PRG | BRF_ESS }, //  2
1336 	{ "dn10-",		0x10000, 0xa4a34e37, 1 | BRF_PRG | BRF_ESS }, //  3
1337 	{ "kar6",		0x10000, 0xc641e195, 1 | BRF_PRG | BRF_ESS }, //  4
1338 	{ "kar9",		0x10000, 0xd420658d, 1 | BRF_PRG | BRF_ESS }, //  5
1339 
1340 	{ "kar5",		0x08000, 0x7c9158f1, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1341 
1342 	{ "dn00-",		0x08000, 0x0ed77c6d, 3 | BRF_GRA},            //  7 Characters
1343 
1344 	{ "dn04-",		0x10000, 0xa9121653, 4 | BRF_GRA},            //  8 Tiles
1345 	{ "dn01-",		0x10000, 0x18697c9e, 4 | BRF_GRA},            //  9
1346 	{ "dn03-",		0x10000, 0x90d9dd9c, 4 | BRF_GRA},            // 10
1347 	{ "dn02-",		0x10000, 0x1e04d7b9, 4 | BRF_GRA},            // 11
1348 
1349 	{ "dn12-",		0x10000, 0x9806772c, 5 | BRF_GRA},            // 12 Sprites
1350 	{ "kar14",		0x08000, 0xc6b39595, 5 | BRF_GRA},            // 13
1351 	{ "dn13-",		0x10000, 0xa03308f9, 5 | BRF_GRA},            // 14
1352 	{ "kar15",		0x08000, 0x2f72cac0, 5 | BRF_GRA},            // 15
1353 	{ "dn16-",		0x10000, 0x55e63a11, 5 | BRF_GRA},            // 16
1354 	{ "kar17",		0x08000, 0x7851c70f, 5 | BRF_GRA},            // 17
1355 	{ "dn18-",		0x10000, 0x2ad53213, 5 | BRF_GRA},            // 18
1356 	{ "kar19",		0x08000, 0x7bc174bb, 5 | BRF_GRA},            // 19
1357 
1358 	{ "karnprom.21",	0x00400, 0xaab0bb93, 6 | BRF_GRA},            // 20 Color Proms
1359 	{ "karnprom.20",	0x00400, 0x02f78ffb, 6 | BRF_GRA},            // 21
1360 
1361 	{ "karnovj_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1362 };
1363 
1364 STD_ROM_PICK(karnovj)
STD_ROM_FN(karnovj)1365 STD_ROM_FN(karnovj)
1366 
1367 static INT32 KarnovjInit()
1368 {
1369 	microcontroller_id = KARNOVJ;
1370 	coin_mask = 0;
1371 
1372 	return DrvInit();
1373 }
1374 
1375 struct BurnDriver BurnDrvKarnovj = {
1376 	"karnovj", "karnov", NULL, NULL, "1987",
1377 	"Karnov (Japan)\0", NULL, "Data East Corporation", "Miscellaneous",
1378 	NULL, NULL, NULL, NULL,
1379 	BDF_GAME_WORKING | BDF_CLONE | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1380 	NULL, karnovjRomInfo, karnovjRomName, NULL, NULL, NULL, NULL, KarnovInputInfo, KarnovDIPInfo,
1381 	KarnovjInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1382 	&DrvRecalc, 0x300, 256, 248, 4, 3
1383 };
1384 
1385 
1386 // Wonder Planet (Japan)
1387 
1388 static struct BurnRomInfo wndrplntRomDesc[] = {
1389 	{ "ea08.bin",		0x10000, 0xb0578a14, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1390 	{ "ea11.bin",		0x10000, 0x271edc6c, 1 | BRF_PRG | BRF_ESS }, //  1
1391 	{ "ea07.bin",		0x10000, 0x7095a7d5, 1 | BRF_PRG | BRF_ESS }, //  2
1392 	{ "ea10.bin",		0x10000, 0x81a96475, 1 | BRF_PRG | BRF_ESS }, //  3
1393 	{ "ea06.bin",		0x10000, 0x5951add3, 1 | BRF_PRG | BRF_ESS }, //  4
1394 	{ "ea09.bin",		0x10000, 0xc4b3cb1e, 1 | BRF_PRG | BRF_ESS }, //  5
1395 
1396 	{ "ea05.bin",		0x08000, 0x8dbb6231, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1397 
1398 	{ "ea00.bin",		0x08000, 0x9f3cac4c, 3 | BRF_GRA},            //  7 Characters
1399 
1400 	{ "ea04.bin",		0x10000, 0x7d701344, 4 | BRF_GRA},            //  8 Tiles
1401 	{ "ea01.bin",		0x10000, 0x18df55fb, 4 | BRF_GRA},            //  9
1402 	{ "ea03.bin",		0x10000, 0x922ef050, 4 | BRF_GRA},            // 10
1403 	{ "ea02.bin",		0x10000, 0x700fde70, 4 | BRF_GRA},            // 11
1404 
1405 	{ "ea12.bin",		0x10000, 0xa6d4e99d, 5 | BRF_GRA},            // 12 Sprites
1406 	{ "ea14.bin",		0x10000, 0x915ffdc9, 5 | BRF_GRA},            // 13
1407 	{ "ea13.bin",		0x10000, 0xcd839f3a, 5 | BRF_GRA},            // 14
1408 	{ "ea15.bin",		0x10000, 0xa1f14f16, 5 | BRF_GRA},            // 15
1409 	{ "ea16.bin",		0x10000, 0x7a1d8a9c, 5 | BRF_GRA},            // 16
1410 	{ "ea17.bin",		0x10000, 0x21a3223d, 5 | BRF_GRA},            // 17
1411 	{ "ea18.bin",		0x10000, 0x3fb2cec7, 5 | BRF_GRA},            // 18
1412 	{ "ea19.bin",		0x10000, 0x87cf03b5, 5 | BRF_GRA},            // 19
1413 
1414 	{ "ea21.prm",		0x00400, 0xc8beab49, 6 | BRF_GRA},            // 20 Color Proms
1415 	{ "ea20.prm",		0x00400, 0x619f9d1e, 6 | BRF_GRA},            // 21
1416 
1417 	{ "wndrplnt_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1418 };
1419 
1420 STD_ROM_PICK(wndrplnt)
STD_ROM_FN(wndrplnt)1421 STD_ROM_FN(wndrplnt)
1422 
1423 static INT32 WndrplntInit()
1424 {
1425 	microcontroller_id = WNDRPLNT;
1426 	coin_mask = 0;
1427 
1428 	return DrvInit();
1429 }
1430 
1431 struct BurnDriver BurnDrvWndrplnt = {
1432 	"wndrplnt", NULL, NULL, NULL, "1987",
1433 	"Wonder Planet (Japan)\0", NULL, "Data East Corporation", "Miscellaneous",
1434 	NULL, NULL, NULL, NULL,
1435 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_VERSHOOT, 0,
1436 	NULL, wndrplntRomInfo, wndrplntRomName, NULL, NULL, NULL, NULL, KarnovInputInfo, WndrplntDIPInfo,
1437 	WndrplntInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1438 	&DrvRecalc, 0x300, 248, 256, 3, 4
1439 };
1440 
1441 
1442 // Chelnov - Atomic Runner (World)
1443 
1444 static struct BurnRomInfo chelnovRomDesc[] = {
1445 	{ "ee08-e.j16",		0x10000, 0x8275cc3a, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1446 	{ "ee11-e.j19",		0x10000, 0x889e40a0, 1 | BRF_PRG | BRF_ESS }, //  1
1447 	{ "a-j14.bin",		0x10000, 0x51465486, 1 | BRF_PRG | BRF_ESS }, //  2
1448 	{ "a-j18.bin",		0x10000, 0xd09dda33, 1 | BRF_PRG | BRF_ESS }, //  3
1449 	{ "ee06-e.j13",		0x10000, 0x55acafdb, 1 | BRF_PRG | BRF_ESS }, //  4
1450 	{ "ee09-e.j17",		0x10000, 0x303e252c, 1 | BRF_PRG | BRF_ESS }, //  5
1451 
1452 	{ "ee05-.f3",		0x08000, 0x6a8936b4, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1453 
1454 	{ "ee00-e.c5",		0x08000, 0xe06e5c6b, 3 | BRF_GRA},            //  7 Characters
1455 
1456 	{ "ee04-.d18",		0x10000, 0x96884f95, 4 | BRF_GRA},            //  8 Tiles
1457 	{ "ee01-.c15",		0x10000, 0xf4b54057, 4 | BRF_GRA},            //  9
1458 	{ "ee03-.d15",		0x10000, 0x7178e182, 4 | BRF_GRA},            // 10
1459 	{ "ee02-.c18",		0x10000, 0x9d7c45ae, 4 | BRF_GRA},            // 11
1460 
1461 	{ "ee12-.f8",		0x10000, 0x9b1c53a5, 5 | BRF_GRA},            // 12 Sprites
1462 	{ "ee13-.f9",		0x10000, 0x72b8ae3e, 5 | BRF_GRA},            // 13
1463 	{ "ee14-.f13",		0x10000, 0xd8f4bbde, 5 | BRF_GRA},            // 14
1464 	{ "ee15-.f15",		0x10000, 0x81e3e68b, 5 | BRF_GRA},            // 15
1465 
1466 	{ "ee21.k8",		0x00400, 0xb1db6586, 6 | BRF_GRA},            // 16 Color Proms
1467 	{ "ee20.l6",		0x00400, 0x41816132, 6 | BRF_GRA},            // 17
1468 
1469 	{ "chelnov_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1470 };
1471 
1472 STD_ROM_PICK(chelnov)
STD_ROM_FN(chelnov)1473 STD_ROM_FN(chelnov)
1474 
1475 static INT32 ChelnovInit()
1476 {
1477 	microcontroller_id = CHELNOVW;
1478 	coin_mask = 0xe0;
1479 
1480 	return DrvInit();
1481 }
1482 
1483 struct BurnDriver BurnDrvChelnov = {
1484 	"chelnov", NULL, NULL, NULL, "1988",
1485 	"Chelnov - Atomic Runner (World)\0", NULL, "Data East Corporation", "Miscellaneous",
1486 	NULL, NULL, NULL, NULL,
1487 	BDF_GAME_WORKING | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1488 	NULL, chelnovRomInfo, chelnovRomName, NULL, NULL, NULL, NULL, ChelnovInputInfo, ChelnovDIPInfo,
1489 	ChelnovInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1490 	&DrvRecalc, 0x300, 256, 248, 4, 3
1491 };
1492 
1493 
1494 // Chelnov - Atomic Runner (US)
1495 
1496 static struct BurnRomInfo chelnovuRomDesc[] = {
1497 	{ "ee08-a.j15",		0x10000, 0x2f2fb37b, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1498 	{ "ee11-a.j20",		0x10000, 0xf306d05f, 1 | BRF_PRG | BRF_ESS }, //  1
1499 	{ "ee07-a.j14",		0x10000, 0x9c69ed56, 1 | BRF_PRG | BRF_ESS }, //  2
1500 	{ "ee10-a.j18",		0x10000, 0xd5c5fe4b, 1 | BRF_PRG | BRF_ESS }, //  3
1501 	{ "ee06-e.j13",		0x10000, 0x55acafdb, 1 | BRF_PRG | BRF_ESS }, //  4
1502 	{ "ee09-e.j17",		0x10000, 0x303e252c, 1 | BRF_PRG | BRF_ESS }, //  5
1503 
1504 	{ "ee05-.f3",		0x08000, 0x6a8936b4, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1505 
1506 	{ "ee00-e.c5",		0x08000, 0xe06e5c6b, 3 | BRF_GRA},            //  7 Characters
1507 
1508 	{ "ee04-.d18",		0x10000, 0x96884f95, 4 | BRF_GRA},            //  8 Tiles
1509 	{ "ee01-.c15",		0x10000, 0xf4b54057, 4 | BRF_GRA},            //  9
1510 	{ "ee03-.d15",		0x10000, 0x7178e182, 4 | BRF_GRA},            // 10
1511 	{ "ee02-.c18",		0x10000, 0x9d7c45ae, 4 | BRF_GRA},            // 11
1512 
1513 	{ "ee12-.f8",		0x10000, 0x9b1c53a5, 5 | BRF_GRA},            // 12 Sprites
1514 	{ "ee13-.f9",		0x10000, 0x72b8ae3e, 5 | BRF_GRA},            // 13
1515 	{ "ee14-.f13",		0x10000, 0xd8f4bbde, 5 | BRF_GRA},            // 14
1516 	{ "ee15-.f15",		0x10000, 0x81e3e68b, 5 | BRF_GRA},            // 15
1517 
1518 	{ "ee21.k8",		0x00400, 0xb1db6586, 6 | BRF_GRA},            // 16 Color Proms
1519 	{ "ee20.l6",		0x00400, 0x41816132, 6 | BRF_GRA},            // 17
1520 
1521 	{ "chelnovu_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1522 };
1523 
1524 STD_ROM_PICK(chelnovu)
STD_ROM_FN(chelnovu)1525 STD_ROM_FN(chelnovu)
1526 
1527 static INT32 ChelnovuInit()
1528 {
1529 	microcontroller_id = CHELNOV;
1530 	coin_mask = 0xe0;
1531 
1532 	return DrvInit();
1533 }
1534 
1535 struct BurnDriver BurnDrvChelnovu = {
1536 	"chelnovu", "chelnov", NULL, NULL, "1988",
1537 	"Chelnov - Atomic Runner (US)\0", NULL, "Data East USA", "Miscellaneous",
1538 	NULL, NULL, NULL, NULL,
1539 	BDF_GAME_WORKING | BDF_CLONE | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1540 	NULL, chelnovuRomInfo, chelnovuRomName, NULL, NULL, NULL, NULL, ChelnovInputInfo, ChelnovuDIPInfo,
1541 	ChelnovuInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1542 	&DrvRecalc, 0x300, 256, 248, 4, 3
1543 };
1544 
1545 
1546 // Chelnov - Atomic Runner (Japan)
1547 
1548 static struct BurnRomInfo chelnovjRomDesc[] = {
1549 	{ "a-j15.bin",		0x10000, 0x1978cb52, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
1550 	{ "a-j20.bin",		0x10000, 0xe0ed3d99, 1 | BRF_PRG | BRF_ESS }, //  1
1551 	{ "a-j14.bin",		0x10000, 0x51465486, 1 | BRF_PRG | BRF_ESS }, //  2
1552 	{ "a-j18.bin",		0x10000, 0xd09dda33, 1 | BRF_PRG | BRF_ESS }, //  3
1553 	{ "a-j13.bin",		0x10000, 0xcd991507, 1 | BRF_PRG | BRF_ESS }, //  4
1554 	{ "a-j17.bin",		0x10000, 0x977f601c, 1 | BRF_PRG | BRF_ESS }, //  5
1555 
1556 	{ "ee05-.f3",		0x08000, 0x6a8936b4, 2 | BRF_PRG | BRF_ESS }, //  6 m6502 Code
1557 
1558 	{ "a-c5.bin",		0x08000, 0x1abf2c6d, 3 | BRF_GRA},            //  7 Characters
1559 
1560 	{ "ee04-.d18",		0x10000, 0x96884f95, 4 | BRF_GRA},            //  8 Tiles
1561 	{ "ee01-.c15",		0x10000, 0xf4b54057, 4 | BRF_GRA},            //  9
1562 	{ "ee03-.d15",		0x10000, 0x7178e182, 4 | BRF_GRA},            // 10
1563 	{ "ee02-.c18",		0x10000, 0x9d7c45ae, 4 | BRF_GRA},            // 11
1564 
1565 	{ "ee12-.f8",		0x10000, 0x9b1c53a5, 5 | BRF_GRA},            // 12 Sprites
1566 	{ "ee13-.f9",		0x10000, 0x72b8ae3e, 5 | BRF_GRA},            // 13
1567 	{ "ee14-.f13",		0x10000, 0xd8f4bbde, 5 | BRF_GRA},            // 14
1568 	{ "ee15-.f15",		0x10000, 0x81e3e68b, 5 | BRF_GRA},            // 15
1569 
1570 	{ "a-k7.bin",		0x00400, 0x309c49d8, 6 | BRF_GRA},            // 16 Color Proms
1571 	{ "ee20.l6",		0x00400, 0x41816132, 6 | BRF_GRA},            // 17
1572 
1573 	{ "chelnovj_i8751",  0x01000, 0x00000000, BRF_OPT | BRF_NODUMP},
1574 };
1575 
1576 STD_ROM_PICK(chelnovj)
STD_ROM_FN(chelnovj)1577 STD_ROM_FN(chelnovj)
1578 
1579 static INT32 ChelnovjInit()
1580 {
1581 	microcontroller_id = CHELNOVJ;
1582 	coin_mask = 0xe0;
1583 
1584 	return DrvInit();
1585 }
1586 
1587 struct BurnDriver BurnDrvChelnovj = {
1588 	"chelnovj", "chelnov", NULL, NULL, "1988",
1589 	"Chelnov - Atomic Runner (Japan)\0", NULL, "Data East Corporation", "Miscellaneous",
1590 	NULL, NULL, NULL, NULL,
1591 	BDF_GAME_WORKING | BDF_CLONE | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_DATAEAST, GBF_RUNGUN, 0,
1592 	NULL, chelnovjRomInfo, chelnovjRomName, NULL, NULL, NULL, NULL, ChelnovInputInfo, ChelnovuDIPInfo,
1593 	ChelnovjInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1594 	&DrvRecalc, 0x300, 256, 248, 4, 3
1595 };
1596