1 // FB Alpha Amazing Adventures of Mr. F. Lea driver module
2 // Based on MAME driver by Phil Stroffolino
3
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "bitswap.h"
7 #include "ay8910.h"
8
9 static UINT8 *AllMem;
10 static UINT8 *MemEnd;
11 static UINT8 *AllRam;
12 static UINT8 *RamEnd;
13 static UINT8 *DrvZ80ROM0;
14 static UINT8 *DrvZ80ROM1;
15 static UINT8 *DrvGfxROM0;
16 static UINT8 *DrvGfxROM1;
17 static UINT8 *DrvZ80RAM0;
18 static UINT8 *DrvZ80RAM1;
19 static UINT16 *DrvVidRAM;
20 static UINT8 *DrvPalRAM;
21 static UINT8 *DrvSprRAM;
22
23 static UINT32 *DrvPalette;
24 static UINT8 DrvRecalc;
25
26 static INT32 mrflea_io;
27 static INT32 mrflea_main;
28 static INT32 mrflea_status;
29 static UINT8 mrflea_select[4];
30 static UINT8 gfx_bank;
31
32 static UINT8 DrvJoy1[8];
33 static UINT8 DrvJoy2[8];
34 static UINT8 DrvDips[2];
35 static UINT8 DrvInputs[2];
36 static UINT8 DrvReset;
37
38 static struct BurnInputInfo DrvInputList[] = {
39 {"Start 1" , BIT_DIGITAL , DrvJoy1 + 3, "p1 start" },
40 {"Start 2" , BIT_DIGITAL , DrvJoy1 + 2, "p2 start" },
41 {"P1 Coin" , BIT_DIGITAL , DrvJoy2 + 2, "p1 coin" },
42
43 {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 4, "p1 right" },
44 {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 5, "p1 left" },
45 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 6, "p1 up", },
46 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 7, "p1 down", },
47 {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 1, "p1 fire 1"},
48
49 {"Reset", BIT_DIGITAL , &DrvReset, "reset" },
50 {"Dip 1", BIT_DIPSWITCH, DrvDips+0, "dip" },
51 {"Dip 2", BIT_DIPSWITCH, DrvDips+1, "dip" },
52 };
53
54 STDINPUTINFO(Drv)
55
56 static struct BurnDIPInfo DrvDIPList[]=
57 {
58 {0x09, 0xff, 0xff, 0xff, NULL },
59 {0x0a, 0xff, 0xff, 0xff, NULL },
60
61 {0 , 0xfe, 0 , 4 , "Bonus" },
62 {0x09, 0x01, 0x03, 0x03, "A" },
63 {0x09, 0x01, 0x03, 0x02, "B" },
64 {0x09, 0x01, 0x03, 0x01, "C" },
65 {0x09, 0x01, 0x03, 0x00, "D" },
66
67 {0 , 0xfe, 0 , 4 , "Coinage" },
68 {0x0a, 0x01, 0x03, 0x02, "2C 1C" },
69 {0x0a, 0x01, 0x03, 0x03, "1C 1C" },
70 {0x0a, 0x01, 0x03, 0x00, "2C 3C" },
71 {0x0a, 0x01, 0x03, 0x01, "1C 2C" },
72
73 {0 , 0xfe, 0 , 4 , "Lives" },
74 {0x0a, 0x01, 0x0c, 0x0c, "3" },
75 {0x0a, 0x01, 0x0c, 0x08, "4" },
76 {0x0a, 0x01, 0x0c, 0x04, "5" },
77 {0x0a, 0x01, 0x0c, 0x00, "7" },
78
79 {0 , 0xfe, 0 , 4 , "Difficulty" },
80 {0x0a, 0x01, 0x30, 0x30, "Easy" },
81 {0x0a, 0x01, 0x30, 0x20, "Medium" },
82 {0x0a, 0x01, 0x30, 0x10, "Hard" },
83 {0x0a, 0x01, 0x30, 0x00, "Hardest" },
84 };
85
STDDIPINFO(Drv)86 STDDIPINFO(Drv)
87
88 static void palette_write(INT32 offs)
89 {
90 UINT8 r = (DrvPalRAM[offs | 1] & 0x0f) | (DrvPalRAM[offs | 1] << 4);
91 UINT8 g = (DrvPalRAM[offs] & 0xf0) | (DrvPalRAM[offs] >> 4);
92 UINT8 b = (DrvPalRAM[offs] & 0x0f) | (DrvPalRAM[offs] << 4);
93
94 DrvPalette[offs/2] = BurnHighCol(r,g,b,0);
95 }
96
mrflea_write(UINT16 address,UINT8 data)97 static void __fastcall mrflea_write(UINT16 address, UINT8 data)
98 {
99 if ((address & 0xf800) == 0xe000)
100 {
101 DrvVidRAM[address & 0x3ff] = data | ((address & 0x400) >> 2);
102 return;
103 }
104
105 if ((address & 0xffc0) == 0xe800)
106 {
107 INT32 offs = address &= 0x3f;
108 DrvPalRAM[offs] = data;
109 palette_write(offs & ~1);
110 return;
111 }
112
113 if ((address & 0xff00) == 0xec00)
114 {
115 address &= 0xff;
116
117 if (address & 2) { // tile number
118 DrvSprRAM[address | 1] = address & 1;
119 address &= 0xfe;
120 }
121
122 DrvSprRAM[address] = data;
123 return;
124 }
125 }
126
mrflea_out_port(UINT16 port,UINT8 data)127 static void __fastcall mrflea_out_port(UINT16 port, UINT8 data)
128 {
129 switch (port & 0xff)
130 {
131 case 0x40:
132 {
133 mrflea_status |= 0x08;
134 mrflea_io = data;
135
136 ZetClose();
137 ZetOpen(1);
138 ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
139 ZetClose();
140 ZetOpen(0);
141 }
142 return;
143
144 case 0x60:
145 gfx_bank = data;
146 return;
147 }
148 }
149
mrflea_in_port(UINT16 port)150 static UINT8 __fastcall mrflea_in_port(UINT16 port)
151 {
152 switch (port & 0xff)
153 {
154 case 0x41:
155 mrflea_status &= ~0x01;
156 return mrflea_main;
157
158 case 0x42:
159 return mrflea_status ^ 0x08;
160 }
161
162 return 0;
163 }
164
mrflea_cpu1_out_port(UINT16 port,UINT8 data)165 static void __fastcall mrflea_cpu1_out_port(UINT16 port, UINT8 data)
166 {
167 switch (port & 0xff)
168 {
169 case 0x21:
170 mrflea_status |= 0x01;
171 mrflea_main = data;
172 return;
173
174 case 0x40:
175 AY8910Write(0, 0, mrflea_select[0]);
176 AY8910Write(0, 1, data);
177 return;
178
179 case 0x44:
180 AY8910Write(1, 0, mrflea_select[2]);
181 AY8910Write(1, 1, data);
182 return;
183
184 case 0x46:
185 AY8910Write(2, 0, mrflea_select[3]);
186 AY8910Write(2, 1, data);
187 return;
188
189 case 0x41:
190 case 0x43:
191 case 0x45:
192 case 0x47:
193 mrflea_select[(port >> 1) & 3] = data;
194 return;
195 }
196 }
197
mrflea_cpu1_in_port(UINT16 port)198 static UINT8 __fastcall mrflea_cpu1_in_port(UINT16 port)
199 {
200 switch (port & 0xff)
201 {
202 case 0x10:
203 return (mrflea_status & 0x08) ? 0x00 : 0x01;
204
205 case 0x20:
206 mrflea_status &= ~0x08;
207 return mrflea_io;
208
209 case 0x22:
210 return mrflea_status ^ 0x01;
211
212 case 0x40:
213 if ((mrflea_select[0] & 0x0e) == 0x0e) {
214 return DrvInputs[~mrflea_select[0] & 1];
215 }
216 return 0;
217
218 case 0x44:
219 if ((mrflea_select[2] & 0x0e) == 0x0e) return 0xff;
220 return 0;
221 }
222
223 return 0;
224 }
225
DrvDoReset()226 static INT32 DrvDoReset()
227 {
228 memset (AllRam, 0, RamEnd - AllRam);
229
230 ZetOpen(0);
231 ZetReset();
232 ZetClose();
233
234 ZetOpen(1);
235 ZetReset();
236 ZetClose();
237
238 AY8910Reset(0);
239 AY8910Reset(1);
240 AY8910Reset(2);
241
242 memset (mrflea_select, 0, 4);
243
244 mrflea_io = 0;
245 mrflea_main = 0;
246 mrflea_status = 0;
247 gfx_bank = 0;
248
249 HiscoreReset();
250
251 return 0;
252 }
253
MemIndex()254 static INT32 MemIndex()
255 {
256 UINT8 *Next; Next = AllMem;
257
258 DrvZ80ROM0 = Next; Next += 0x00c000;
259 DrvZ80ROM1 = Next; Next += 0x004000;
260
261 DrvGfxROM0 = Next; Next += 0x020000;
262 DrvGfxROM1 = Next; Next += 0x020000;
263
264 DrvPalette = (UINT32*)Next; Next += 0x0020 * sizeof(UINT32);
265
266 AllRam = Next;
267
268 DrvZ80RAM0 = Next; Next += 0x001000;
269 DrvZ80RAM1 = Next; Next += 0x000200;
270 DrvVidRAM = (UINT16*)Next; Next += 0x000400 * sizeof(UINT16);
271 DrvPalRAM = Next; Next += 0x000100;
272 DrvSprRAM = Next; Next += 0x000100;
273
274 RamEnd = Next;
275
276 MemEnd = Next;
277
278 return 0;
279 }
280
DrvGfxDecode()281 static INT32 DrvGfxDecode()
282 {
283 INT32 Plane0[4] = { 0, 0x4000*8*1, 0x4000*8*2, 0x4000*8*3 };
284 INT32 XOffs0[16] = { STEP16(0,1) };
285 INT32 YOffs0[16] = { STEP16(0,16) };
286 INT32 Plane1[4] = { STEP4(0,1) };
287 INT32 XOffs1[8] = { STEP8(0,4) };
288 INT32 YOffs1[8] = { STEP8(0,32) };
289 UINT8 *tmp = (UINT8*)BurnMalloc(0x10000);
290 if (tmp == NULL) {
291 return 1;
292 }
293
294 memcpy (tmp, DrvGfxROM0, 0x10000);
295
296 GfxDecode(0x0200, 4, 16, 16, Plane0, XOffs0, YOffs0, 0x100, tmp, DrvGfxROM0);
297
298 memcpy (tmp, DrvGfxROM1, 0x10000);
299
300 GfxDecode(0x0800, 4, 8, 8, Plane1, XOffs1, YOffs1, 0x100, tmp, DrvGfxROM1);
301
302 BurnFree(tmp);
303
304 return 0;
305 }
306
DrvInit()307 static INT32 DrvInit()
308 {
309 AllMem = NULL;
310 MemIndex();
311 INT32 nLen = MemEnd - (UINT8 *)0;
312 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
313 memset(AllMem, 0, nLen);
314 MemIndex();
315
316 {
317 if (BurnLoadRom(DrvZ80ROM0 + 0x0000, 0, 1)) return 1;
318 if (BurnLoadRom(DrvZ80ROM0 + 0x2000, 1, 1)) return 1;
319 if (BurnLoadRom(DrvZ80ROM0 + 0x4000, 2, 1)) return 1;
320 if (BurnLoadRom(DrvZ80ROM0 + 0x6000, 3, 1)) return 1;
321 if (BurnLoadRom(DrvZ80ROM0 + 0x8000, 4, 1)) return 1;
322 if (BurnLoadRom(DrvZ80ROM0 + 0xa000, 5, 1)) return 1;
323
324 if (BurnLoadRom(DrvZ80ROM1 + 0x0000, 6, 1)) return 1;
325 if (BurnLoadRom(DrvZ80ROM1 + 0x2000, 7, 1)) return 1;
326 if (BurnLoadRom(DrvZ80ROM1 + 0x3000, 8, 1)) return 1;
327
328 if (BurnLoadRom(DrvGfxROM0 + 0x0000, 9, 1)) return 1;
329 if (BurnLoadRom(DrvGfxROM0 + 0x2000, 10, 1)) return 1;
330 if (BurnLoadRom(DrvGfxROM0 + 0x4000, 11, 1)) return 1;
331 if (BurnLoadRom(DrvGfxROM0 + 0x6000, 12, 1)) return 1;
332 if (BurnLoadRom(DrvGfxROM0 + 0x8000, 13, 1)) return 1;
333 if (BurnLoadRom(DrvGfxROM0 + 0xa000, 14, 1)) return 1;
334 if (BurnLoadRom(DrvGfxROM0 + 0xc000, 15, 1)) return 1;
335 if (BurnLoadRom(DrvGfxROM0 + 0xe000, 16, 1)) return 1;
336
337 if (BurnLoadRom(DrvGfxROM1 + 0x0000, 17, 1)) return 1;
338 if (BurnLoadRom(DrvGfxROM1 + 0x2000, 18, 1)) return 1;
339 if (BurnLoadRom(DrvGfxROM1 + 0x4000, 19, 1)) return 1;
340 if (BurnLoadRom(DrvGfxROM1 + 0x6000, 20, 1)) return 1;
341 if (BurnLoadRom(DrvGfxROM1 + 0x8000, 21, 1)) return 1;
342 if (BurnLoadRom(DrvGfxROM1 + 0xa000, 22, 1)) return 1;
343 if (BurnLoadRom(DrvGfxROM1 + 0xc000, 23, 1)) return 1;
344 if (BurnLoadRom(DrvGfxROM1 + 0xe000, 24, 1)) return 1;
345
346 DrvGfxDecode();
347 }
348
349 ZetInit(0);
350 ZetOpen(0);
351 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xbfff, MAP_ROM);
352 ZetMapMemory(DrvZ80RAM0, 0xc000, 0xcfff, MAP_RAM);
353 ZetSetInHandler(mrflea_in_port);
354 ZetSetOutHandler(mrflea_out_port);
355 ZetSetWriteHandler(mrflea_write);
356 ZetClose();
357
358 ZetInit(1);
359 ZetOpen(1);
360 ZetMapMemory(DrvZ80ROM1, 0x0000, 0x3fff, MAP_ROM);
361 ZetMapMemory(DrvZ80RAM1, 0x8000, 0x80ff, MAP_RAM);
362 ZetMapMemory(DrvZ80RAM1 + 0x100,0x9000, 0x90ff, MAP_RAM);
363 ZetSetInHandler(mrflea_cpu1_in_port);
364 ZetSetOutHandler(mrflea_cpu1_out_port);
365 ZetClose();
366
367 AY8910Init(0, 2000000, 0);
368 AY8910Init(1, 2000000, 1);
369 AY8910Init(2, 2000000, 1);
370 AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
371 AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
372 AY8910SetAllRoutes(2, 0.15, BURN_SND_ROUTE_BOTH);
373
374 GenericTilesInit();
375
376 DrvDoReset();
377
378 return 0;
379 }
380
DrvExit()381 static INT32 DrvExit()
382 {
383 ZetExit();
384
385 AY8910Exit(0);
386 AY8910Exit(1);
387 AY8910Exit(2);
388
389 GenericTilesExit();
390
391 BurnFree(AllMem);
392
393 return 0;
394 }
395
draw_layer()396 static void draw_layer()
397 {
398 INT32 base = ((gfx_bank & 0x04) << 8) | ((gfx_bank & 0x10) << 5);
399
400 for (INT32 i = 0; i < 0x400 - 32; i++)
401 {
402 INT32 sy = (i >> 2) & 0xf8;
403 INT32 sx = (i << 3) & 0xf8;
404
405 Render8x8Tile(pTransDraw, base + DrvVidRAM[i], sx, sy, 0, 4, 0, DrvGfxROM1);
406 }
407 }
408
draw_sprites()409 static void draw_sprites()
410 {
411 GenericTilesSetClip(16, nScreenWidth-24, 0, nScreenHeight);
412
413 for (INT32 i = 0; i < 0x100; i+=4)
414 {
415 INT32 sx = DrvSprRAM[i + 1] - 3;
416 INT32 sy = DrvSprRAM[i + 0] - 13;
417
418 INT32 code = DrvSprRAM[i + 2] + ((DrvSprRAM[i + 3] & 1) << 8);
419
420 Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, 0, 4, 0, 0x10, DrvGfxROM0);
421 Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy + 256, 0, 4, 0, 0x10, DrvGfxROM0);
422 }
423
424 GenericTilesClearClip();
425 }
426
DrvDraw()427 static INT32 DrvDraw()
428 {
429 if (DrvRecalc) {
430 for (INT32 i = 0; i < 0x100; i+=2) {
431 palette_write(i);
432 }
433 DrvRecalc = 0;
434 }
435
436 if (~nBurnLayer & 1) BurnTransferClear();
437
438 if (nBurnLayer & 1) draw_layer();
439 if (nBurnLayer & 2) draw_sprites();
440
441 BurnTransferCopy(DrvPalette);
442
443 return 0;
444 }
445
DrvFrame()446 static INT32 DrvFrame()
447 {
448 if (DrvReset) {
449 DrvDoReset();
450 }
451
452 ZetNewFrame();
453
454 {
455 memset (DrvInputs, 0xff, 2);
456
457 for (INT32 i = 0; i < 8; i++) {
458 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
459 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
460 }
461 }
462
463 INT32 nInterleave = 200;
464 INT32 nCyclesTotal[2] = { 4000000 / 60, 6000000 / 60 };
465 INT32 nCyclesDone[2] = { 0, 0 };
466 INT32 nSoundBufferPos = 0;
467
468 for (INT32 i = 0; i < nInterleave; i++) {
469 INT32 nCurrentCPU, nNext;
470
471 nCurrentCPU = 0;
472 ZetOpen(nCurrentCPU);
473 nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
474 nCyclesDone[nCurrentCPU] += ZetRun(nNext - nCyclesDone[nCurrentCPU]);
475 if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
476 ZetClose();
477
478 nCurrentCPU = 1;
479 ZetOpen(nCurrentCPU);
480 nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
481 nCyclesDone[nCurrentCPU] += ZetRun(nNext - nCyclesDone[nCurrentCPU]);
482 if ((i == (nInterleave/2) && (mrflea_status&0x08)) || i == (nInterleave-1))
483 ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
484 ZetClose();
485
486 if (pBurnSoundOut && i&1) {
487 INT32 nSegmentLength = nBurnSoundLen / (nInterleave/2);
488 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
489 AY8910Render(pSoundBuf, nSegmentLength);
490 nSoundBufferPos += nSegmentLength;
491 }
492 }
493
494 if (pBurnSoundOut) {
495 INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
496 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
497 if (nSegmentLength) {
498 AY8910Render(pSoundBuf, nSegmentLength);
499 }
500 }
501
502 if (pBurnDraw) {
503 DrvDraw();
504 }
505
506 return 0;
507 }
508
DrvScan(INT32 nAction,INT32 * pnMin)509 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
510 {
511 struct BurnArea ba;
512
513 if (pnMin) {
514 *pnMin = 0x029521;
515 }
516
517 if (nAction & ACB_VOLATILE) {
518 memset(&ba, 0, sizeof(ba));
519
520 ba.Data = AllRam;
521 ba.nLen = RamEnd - AllRam;
522 ba.szName = "All Ram";
523 BurnAcb(&ba);
524
525 ZetScan(nAction);
526 AY8910Scan(nAction, pnMin);
527
528 SCAN_VAR(mrflea_io);
529 SCAN_VAR(mrflea_main);
530 SCAN_VAR(mrflea_status);
531 SCAN_VAR(gfx_bank);
532 SCAN_VAR(mrflea_select);
533 }
534
535 return 0;
536 }
537
538
539 // The Amazing Adventures of Mr. F. Lea
540
541 static struct BurnRomInfo mrfleaRomDesc[] = {
542 { "cpu_d1", 0x2000, 0xd286217c, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 0 Code
543 { "cpu_d3", 0x2000, 0x95cf94bc, 1 | BRF_ESS | BRF_PRG }, // 1
544 { "cpu_d5", 0x2000, 0x466ca77e, 1 | BRF_ESS | BRF_PRG }, // 2
545 { "cpu_b1", 0x2000, 0x721477d6, 1 | BRF_ESS | BRF_PRG }, // 3
546 { "cpu_b3", 0x2000, 0xf55b01e4, 1 | BRF_ESS | BRF_PRG }, // 4
547 { "cpu_b5", 0x2000, 0x79f560aa, 1 | BRF_ESS | BRF_PRG }, // 5
548
549 { "io_a11", 0x1000, 0x7a20c3ee, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 1 Code
550 { "io_c11", 0x1000, 0x8d26e0c8, 2 | BRF_ESS | BRF_PRG }, // 7
551 { "io_d11", 0x1000, 0xabd9afc0, 2 | BRF_ESS | BRF_PRG }, // 8
552
553 { "vd_l10", 0x2000, 0x48b2adf9, 3 | BRF_GRA }, // 9 Sprites
554 { "vd_l11", 0x2000, 0x2ff168c0, 3 | BRF_GRA }, // 10
555 { "vd_l6", 0x2000, 0x100158ca, 3 | BRF_GRA }, // 11
556 { "vd_l7", 0x2000, 0x34501577, 3 | BRF_GRA }, // 12
557 { "vd_j10", 0x2000, 0x3f29b8c3, 3 | BRF_GRA }, // 13
558 { "vd_j11", 0x2000, 0x39380bea, 3 | BRF_GRA }, // 14
559 { "vd_j6", 0x2000, 0x2b4b110e, 3 | BRF_GRA }, // 15
560 { "vd_j7", 0x2000, 0x3a3c8b1e, 3 | BRF_GRA }, // 16
561
562 { "vd_k1", 0x2000, 0x7540e3a7, 4 | BRF_GRA }, // 17 Characters
563 { "vd_k2", 0x2000, 0x6c688219, 4 | BRF_GRA }, // 18
564 { "vd_k3", 0x2000, 0x15e96f3c, 4 | BRF_GRA }, // 19
565 { "vd_k4", 0x2000, 0xfe5100df, 4 | BRF_GRA }, // 20
566 { "vd_l1", 0x2000, 0xd1e3d056, 4 | BRF_GRA }, // 21
567 { "vd_l2", 0x2000, 0x4d7fb925, 4 | BRF_GRA }, // 22
568 { "vd_l3", 0x2000, 0x6d81588a, 4 | BRF_GRA }, // 23
569 { "vd_l4", 0x2000, 0x423735a5, 4 | BRF_GRA }, // 24
570 };
571
572 STD_ROM_PICK(mrflea)
573 STD_ROM_FN(mrflea)
574
575 struct BurnDriver BurnDrvmrflea = {
576 "mrflea", NULL, NULL, NULL, "1982",
577 "The Amazing Adventures of Mr. F. Lea\0", NULL, "Pacific Novelty", "Miscellaneous",
578 NULL, NULL, NULL, NULL,
579 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_HISCORE_SUPPORTED, 1, HARDWARE_MISC_PRE90S, GBF_PLATFORM, 0,
580 NULL, mrfleaRomInfo, mrfleaRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
581 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x20,
582 248, 256, 3, 4
583 };
584