1 // FinalBurn Neo Limenko Power System 2 hardware driver module
2 // Based on MAME driver by Pierpaolo Prazzoli, Tomasz Slanina
3
4 #include "tiles_generic.h"
5 #include "e132xs_intf.h"
6 #include "mcs51.h"
7 #include "qs1000.h"
8 #include "msm6295.h"
9 #include "eeprom.h"
10 #include "burn_pal.h"
11
12 static UINT8 *AllMem;
13 static UINT8 *AllRam;
14 static UINT8 *RamEnd;
15 static UINT8 *MemEnd;
16 static UINT8 *DrvMainROM;
17 static UINT8 *DrvBootROM;
18 static UINT8 *DrvQSROM;
19 static UINT8 *DrvGfxROM;
20 static UINT8 *DrvSndROM;
21 static UINT8 *DrvMainRAM;
22 static UINT8 *DrvFgRAM;
23 static UINT8 *DrvMdRAM;
24 static UINT8 *DrvBgRAM;
25 static UINT8 *DrvSprRAM;
26 static UINT8 *DrvRegRAM;
27
28 static UINT8 DrvRecalc;
29
30 static UINT32 *video_regs;
31
32 static INT32 audiocpu_data[4];
33 static INT32 soundlatch;
34 static INT32 spriteram_bit;
35 static UINT32 prev_sprites_count;
36
37 static UINT32 security_bit_config = 0x00400000;
38 static UINT32 eeprom_bit_config = 0x00800000;
39 static UINT32 spriteram_bit_config = 0x80000000;
40 static INT32 sound_type;
41 static INT32 graphicsrom_len;
42 static UINT32 speedhack_address = 0xffffffff;
43 static UINT32 speedhack_pc = 0;
44 static INT32 cpu_clock;
45
46 void limenko_draw_sprites();
47
48 static UINT8 DrvJoy1[16];
49 static UINT8 DrvJoy2[16];
50 static UINT8 DrvJoy3[16];
51 static UINT8 DrvDips[1];
52 static UINT8 DrvReset;
53 static UINT16 DrvInputs[3];
54
55 static struct BurnInputInfo LegendohInputList[] = {
56 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 2, "p1 coin" },
57 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 0, "p1 start" },
58 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
59 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" },
60 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 2, "p1 left" },
61 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 3, "p1 right" },
62 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
63 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
64 {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 3" },
65 {"P1 Button 4", BIT_DIGITAL, DrvJoy1 + 7, "p1 fire 4" },
66
67 {"P2 Coin", BIT_DIGITAL, DrvJoy3 + 3, "p2 coin" },
68 {"P2 Start", BIT_DIGITAL, DrvJoy3 + 1, "p2 start" },
69 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up" },
70 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down" },
71 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 2, "p2 left" },
72 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 3, "p2 right" },
73 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" },
74 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" },
75 {"P2 Button 3", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire 3" },
76 {"P2 Button 4", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire 4" },
77
78 {"P3 Coin", BIT_DIGITAL, DrvJoy3 + 10, "p3 coin" },
79 {"P3 Start", BIT_DIGITAL, DrvJoy3 + 8, "p3 start" },
80 {"P3 Up", BIT_DIGITAL, DrvJoy1 + 8, "p3 up" },
81 {"P3 Down", BIT_DIGITAL, DrvJoy1 + 9, "p3 down" },
82 {"P3 Left", BIT_DIGITAL, DrvJoy1 + 10, "p3 left" },
83 {"P3 Right", BIT_DIGITAL, DrvJoy1 + 11, "p3 right" },
84 {"P3 Button 1", BIT_DIGITAL, DrvJoy1 + 12, "p3 fire 1" },
85 {"P3 Button 2", BIT_DIGITAL, DrvJoy1 + 13, "p3 fire 2" },
86 {"P3 Button 3", BIT_DIGITAL, DrvJoy1 + 14, "p3 fire 3" },
87 {"P3 Button 4", BIT_DIGITAL, DrvJoy1 + 15, "p3 fire 4" },
88
89 {"P4 Coin", BIT_DIGITAL, DrvJoy3 + 11, "p4 coin" },
90 {"P4 Start", BIT_DIGITAL, DrvJoy3 + 9, "p4 start" },
91 {"P4 Up", BIT_DIGITAL, DrvJoy2 + 8, "p4 up" },
92 {"P4 Down", BIT_DIGITAL, DrvJoy2 + 9, "p4 down" },
93 {"P4 Left", BIT_DIGITAL, DrvJoy2 + 10, "p4 left" },
94 {"P4 Right", BIT_DIGITAL, DrvJoy2 + 11, "p4 right" },
95 {"P4 Button 1", BIT_DIGITAL, DrvJoy2 + 12, "p4 fire 1" },
96 {"P4 Button 2", BIT_DIGITAL, DrvJoy2 + 13, "p4 fire 2" },
97 {"P4 Button 3", BIT_DIGITAL, DrvJoy2 + 14, "p4 fire 3" },
98 {"P4 Button 4", BIT_DIGITAL, DrvJoy2 + 15, "p4 fire 4" },
99
100 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
101 {"Service", BIT_DIGITAL, DrvJoy3 + 4, "service" },
102 {"Service Mode", BIT_DIGITAL, DrvJoy3 + 5, "diag" },
103 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
104 };
105
106 STDINPUTINFO(Legendoh)
107
108 static struct BurnInputInfo Sb2003InputList[] = {
109 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 2, "p1 coin" },
110 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 0, "p1 start" },
111 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
112 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" },
113 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 2, "p1 left" },
114 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 3, "p1 right" },
115 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
116 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
117 {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 3" },
118 {"P1 Button 4", BIT_DIGITAL, DrvJoy1 + 7, "p1 fire 4" },
119
120 {"P2 Coin", BIT_DIGITAL, DrvJoy3 + 3, "p2 coin" },
121 {"P2 Start", BIT_DIGITAL, DrvJoy3 + 1, "p2 start" },
122 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up" },
123 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down" },
124 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 2, "p2 left" },
125 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 3, "p2 right" },
126 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" },
127 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" },
128 {"P2 Button 3", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire 3" },
129 {"P2 Button 4", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire 4" },
130
131 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
132 {"Service", BIT_DIGITAL, DrvJoy3 + 4, "service" },
133 {"Service Mode", BIT_DIGITAL, DrvJoy3 + 5, "diag" },
134 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
135 };
136
137 STDINPUTINFO(Sb2003)
138
139 static struct BurnInputInfo SpottyInputList[] = {
140 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 2, "p1 coin" },
141 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 0, "p1 start" },
142 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
143 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" },
144 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 2, "p1 left" },
145 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 3, "p1 right" },
146 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
147 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
148 {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 3" },
149 {"P1 Button 4", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 4" },
150 {"P1 Button 5", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 5" },
151 {"P1 Button 6", BIT_DIGITAL, DrvJoy2 + 6, "p1 fire 6" },
152
153 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
154 {"Service Mode", BIT_DIGITAL, DrvJoy3 + 5, "diag" },
155 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
156 };
157
158 STDINPUTINFO(Spotty)
159
160 static struct BurnDIPInfo LegendohDIPList[]=
161 {
162 {0x2b, 0xff, 0xff, 0x00, NULL },
163
164 {0 , 0xfe, 0 , 2, "Sound Enable" },
165 {0x2b, 0x01, 0x20, 0x20, "Off" },
166 {0x2b, 0x01, 0x20, 0x00, "On" },
167 };
168
169 STDDIPINFO(Legendoh)
170
171 static struct BurnDIPInfo Sb2003DIPList[]=
172 {
173 {0x17, 0xff, 0xff, 0x00, NULL },
174
175 {0 , 0xfe, 0 , 2, "Sound Enable" },
176 {0x17, 0x01, 0x20, 0x20, "Off" },
177 {0x17, 0x01, 0x20, 0x00, "On" },
178 };
179
180 STDDIPINFO(Sb2003)
181
182 static struct BurnDIPInfo SpottyDIPList[]=
183 {
184 {0x0e, 0xff, 0xff, 0x20, NULL },
185
186 {0 , 0xfe, 0 , 2, "Demo Sounds" },
187 {0x0e, 0x01, 0x20, 0x00, "Off" },
188 {0x0e, 0x01, 0x20, 0x20, "On" },
189 };
190
STDDIPINFO(Spotty)191 STDDIPINFO(Spotty)
192
193 static void sprite_buffer()
194 {
195 spriteram_bit ^= 1;
196 limenko_draw_sprites();
197 prev_sprites_count = (BURN_ENDIAN_SWAP_INT32(video_regs[0]) >> 0) & 0x1ff; // reg0
198 }
199
limenko_write_long(UINT32 address,UINT32 data)200 static void limenko_write_long(UINT32 address, UINT32 data)
201 {
202 switch (address)
203 {
204 case 0x8003e000:
205 sprite_buffer();
206 return;
207 }
208 }
209
limenko_write_word(UINT32 address,UINT16 data)210 static void limenko_write_word(UINT32 address, UINT16 data)
211 {
212 switch (address & ~3)
213 {
214 case 0x8003e000:
215 sprite_buffer();
216 return;
217 }
218 }
219
limenko_write_byte(UINT32 address,UINT8 data)220 static void limenko_write_byte(UINT32 address, UINT8 data)
221 {
222 switch (address & ~3)
223 {
224 case 0x8003e000:
225 sprite_buffer();
226 return;
227 }
228 }
229
speedhack_callback(UINT32 address)230 static inline void speedhack_callback(UINT32 address)
231 {
232 if (address == speedhack_address) {
233 if (E132XSGetPC(0) == speedhack_pc) {
234 E132XSBurnCycles(50);
235 }
236 }
237 }
238
limenko_read_long(UINT32 address)239 static UINT32 limenko_read_long(UINT32 address)
240 {
241 if (address < 0x200000) {
242 speedhack_callback(address);
243 UINT32 ret = BURN_ENDIAN_SWAP_INT32(*((UINT32*)(DrvMainRAM + address)));
244 return (ret << 16) | (ret >> 16);
245 }
246
247 return 0;
248 }
249
limenko_read_word(UINT32 address)250 static UINT16 limenko_read_word(UINT32 address)
251 {
252 if (address < 0x200000) {
253 speedhack_callback(address);
254 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvMainRAM + address)));
255 }
256
257 return 0;
258 }
259
limenko_read_byte(UINT32 address)260 static UINT8 limenko_read_byte(UINT32 address)
261 {
262 if (address < 0x200000) {
263 speedhack_callback(address);
264 return DrvMainRAM[address^1];
265 }
266
267 return 0;
268 }
269
DrvMCUSync()270 static inline void DrvMCUSync()
271 {
272 INT32 todo = ((double)E132XSTotalCycles() * (24000000/12) / 80000000) - mcs51TotalCycles();
273
274 if (todo > 0) mcs51Run(todo);
275 }
276
limenko_io_write(UINT32 address,UINT32 data)277 static void limenko_io_write(UINT32 address, UINT32 data)
278 {
279 switch (address)
280 {
281 case 0x4000:
282 // coin counter / hopper?
283 return;
284
285 case 0x4800:
286 EEPROMWriteBit((data & 0x40000));
287 EEPROMSetCSLine((data & 0x10000) ? EEPROM_CLEAR_LINE : EEPROM_ASSERT_LINE );
288 EEPROMSetClockLine((data & 0x20000) ? EEPROM_ASSERT_LINE : EEPROM_CLEAR_LINE );
289 return;
290
291 case 0x5000:
292 soundlatch = (data >> 16) & 0xff;
293 switch (sound_type)
294 {
295 case 0: DrvMCUSync(); qs1000_set_irq(1); break;
296 case 1: soundlatch |= 0x100; break; // spotty
297 }
298 return;
299 }
300 }
301
limenko_io_read(UINT32 address)302 static UINT32 limenko_io_read(UINT32 address)
303 {
304 switch (address)
305 {
306 case 0x0000:
307 return (DrvInputs[0] << 16) | 0xffff;
308
309 case 0x0800:
310 return (DrvInputs[1] << 16) | 0xffff;
311
312 case 0x1000:
313 {
314 UINT32 ret = (DrvInputs[2] << 16) | 0xffff;
315
316 ret &= security_bit_config ^ 0xffffffff;
317 ret &= eeprom_bit_config ^ 0xffffffff;
318 ret &= 0x20000000 ^ 0xffffffff;
319 ret &= spriteram_bit_config ^ 0xffffffff;
320
321 if (spriteram_bit) ret |= spriteram_bit_config;
322 if (EEPROMRead()) ret |= eeprom_bit_config;
323 ret |= (DrvDips[0] & 0x20) << 24;
324
325 return ret;
326 }
327 }
328
329 return 0;
330 }
331
tilemap_callback(bg)332 static tilemap_callback( bg )
333 {
334 UINT32 attr = BURN_ENDIAN_SWAP_INT32(*((UINT32*)(DrvBgRAM + offs * 4)));
335 attr = (attr << 16) | (attr >> 16);
336
337 TILE_SET_INFO(0, attr & 0x7ffff, attr >> 28, 0);
338 }
339
tilemap_callback(md)340 static tilemap_callback( md )
341 {
342 UINT32 attr = BURN_ENDIAN_SWAP_INT32(*((UINT32*)(DrvMdRAM + offs * 4)));
343 attr = (attr << 16) | (attr >> 16);
344
345 TILE_SET_INFO(0, attr & 0x7ffff, attr >> 28, 0);
346 }
347
tilemap_callback(fg)348 static tilemap_callback( fg )
349 {
350 UINT32 attr = BURN_ENDIAN_SWAP_INT32(*((UINT32*)(DrvFgRAM + offs * 4)));
351 attr = (attr << 16) | (attr >> 16);
352
353 TILE_SET_INFO(0, attr & 0x7ffff, attr >> 28, 0);
354 }
355
qs1000_p3_write(UINT8 data)356 static void qs1000_p3_write(UINT8 data)
357 {
358 qs1000_set_bankedrom(DrvQSROM + (data & 7) * 0x10000);
359
360 if (~data & 0x20)
361 qs1000_set_irq(0);
362 }
363
spotty_sound_write(INT32 port,UINT8 data)364 static void spotty_sound_write(INT32 port, UINT8 data)
365 {
366 switch (port)
367 {
368 case MCS51_PORT_P1:
369 audiocpu_data[0] = data;
370 return;
371
372 case MCS51_PORT_P3:
373 {
374 if ((audiocpu_data[3] & 0x01) == 0x01 && (data & 0x81) == 0) audiocpu_data[0] = MSM6295Read(0);
375 if ((audiocpu_data[3] & 0x02) == 0x02 && (data & 0x82) == 0) MSM6295Write(0, audiocpu_data[0]);
376 if ((audiocpu_data[3] & 0x08) == 0x08 && (data & 0x08) == 0) { audiocpu_data[0] = soundlatch; soundlatch &= 0xff; }
377 audiocpu_data[3] = data;
378 }
379 return;
380 }
381 }
382
spotty_sound_read(INT32 port)383 static UINT8 spotty_sound_read(INT32 port)
384 {
385 switch (port)
386 {
387 case MCS51_PORT_P1:
388 return audiocpu_data[0];
389
390 case MCS51_PORT_P3:
391 return (soundlatch & 0x100) ? 0 : 4;
392 }
393
394 return 0;
395 }
396
qs1000_p1_read()397 static UINT8 qs1000_p1_read()
398 {
399 return soundlatch;
400 }
401
DrvDoReset()402 static INT32 DrvDoReset()
403 {
404 memset (AllRam, 0, RamEnd - AllRam);
405
406 E132XSOpen(0);
407 E132XSReset();
408 E132XSClose();
409
410 switch (sound_type)
411 {
412 case 0: qs1000_reset(); break;
413
414 case 1: // spotty
415 {
416 mcs51Open(0);
417 mcs51_reset();
418 mcs51Close();
419 MSM6295Reset();
420 }
421 break;
422 }
423
424 EEPROMReset();
425
426 soundlatch = 0;
427 spriteram_bit = 1;
428 prev_sprites_count = 0;
429 memset (audiocpu_data, 0, sizeof(audiocpu_data)); // spotty
430
431 return 0;
432 }
433
MemIndex()434 static INT32 MemIndex()
435 {
436 UINT8 *Next; Next = AllMem;
437
438 DrvMainROM = Next; Next += 0x400000;
439 DrvBootROM = Next; Next += 0x200000;
440
441 DrvQSROM = Next; Next += 0x080000;
442
443 DrvGfxROM = Next; Next += graphicsrom_len;
444
445 MSM6295ROM = Next;
446 DrvSndROM = Next; Next += 0x400000;
447
448 BurnPalette = (UINT32*)Next; Next += 0x1000 * sizeof(UINT32);
449
450 AllRam = Next;
451
452 DrvMainRAM = Next; Next += 0x200000;
453 DrvFgRAM = Next; Next += 0x008000;
454 DrvMdRAM = Next; Next += 0x008000;
455 DrvBgRAM = Next; Next += 0x008000;
456 DrvSprRAM = Next; Next += 0x002000;
457 BurnPalRAM = Next; Next += 0x002000;
458 DrvRegRAM = Next; Next += 0x002000;
459
460 video_regs = (UINT32*)(DrvRegRAM + 0x1fec);
461
462 RamEnd = Next;
463
464 MemEnd = Next;
465
466 return 0;
467 }
468
LimenkoCommonInit(INT32 cputype,INT32 cpuclock,INT32 (* pLoadRoms)(),INT32 graphics_size,INT32 soundtype)469 static INT32 LimenkoCommonInit(INT32 cputype, INT32 cpuclock, INT32 (*pLoadRoms)(), INT32 graphics_size, INT32 soundtype)
470 {
471 graphicsrom_len = graphics_size;
472
473 BurnAllocMemIndex();
474
475 memset (DrvMainROM, 0xff, 0x400000);
476 memset (DrvQSROM, 0xff, 0x80000);
477
478 if (pLoadRoms) {
479 if (pLoadRoms()) return 1;
480 }
481
482 cpu_clock = cpuclock;
483
484 E132XSInit(0, cputype, cpu_clock);
485 E132XSOpen(0);
486 E132XSMapMemory(DrvMainRAM, 0x00000000, 0x001fffff, MAP_RAM);
487 E132XSMapMemory(DrvMainROM, 0x40000000, 0x403fffff, MAP_ROM);
488 E132XSMapMemory(DrvFgRAM, 0x80000000, 0x80007fff, MAP_RAM);
489 E132XSMapMemory(DrvMdRAM, 0x80008000, 0x8000ffff, MAP_RAM);
490 E132XSMapMemory(DrvBgRAM, 0x80010000, 0x80017fff, MAP_RAM);
491 E132XSMapMemory(DrvSprRAM, 0x80018000, 0x80019fff, MAP_RAM);
492 E132XSMapMemory(BurnPalRAM, 0x8001c000, 0x8001dfff, MAP_RAM);
493 E132XSMapMemory(DrvRegRAM, 0x8001e000, 0x8001ffff, MAP_RAM);
494 E132XSMapMemory(DrvBootROM, 0xffe00000, 0xffffffff, MAP_ROM);
495 E132XSSetWriteLongHandler(limenko_write_long);
496 E132XSSetWriteWordHandler(limenko_write_word);
497 E132XSSetWriteByteHandler(limenko_write_byte);
498 E132XSSetIOWriteHandler(limenko_io_write);
499 E132XSSetIOReadHandler(limenko_io_read);
500
501 if (speedhack_pc)
502 {
503 E132XSMapMemory(NULL, speedhack_address & ~0xfff, speedhack_address | 0xfff, MAP_ROM);
504 E132XSSetReadLongHandler(limenko_read_long);
505 E132XSSetReadWordHandler(limenko_read_word);
506 E132XSSetReadByteHandler(limenko_read_byte);
507 }
508 E132XSClose();
509
510 EEPROMInit(&eeprom_interface_93C46);
511
512 switch(soundtype)
513 {
514 case 0:
515 {
516 qs1000_init(DrvQSROM, DrvSndROM, 0x400000);
517 qs1000_set_write_handler(3, qs1000_p3_write);
518 qs1000_set_read_handler(1, qs1000_p1_read);
519 qs1000_set_volume(3.00);
520
521 sound_type = 0;
522 }
523 break;
524
525 case 1:
526 {
527 i80c51_init();
528 mcs51Open(0);
529 mcs51_set_program_data(DrvQSROM); // not really qs!
530 mcs51_set_write_handler(spotty_sound_write);
531 mcs51_set_read_handler(spotty_sound_read);
532 mcs51Close();
533
534 MSM6295Init(0, 1000000 / MSM6295_PIN7_HIGH, 0);
535 MSM6295SetRoute(0, 1.00, BURN_SND_ROUTE_BOTH);
536
537 sound_type = 1;
538 }
539 break;
540 }
541
542 GenericTilesInit();
543 GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 8, 8, 128, 64);
544 GenericTilemapInit(1, TILEMAP_SCAN_ROWS, md_map_callback, 8, 8, 128, 64);
545 GenericTilemapInit(2, TILEMAP_SCAN_ROWS, fg_map_callback, 8, 8, 128, 64);
546 GenericTilemapSetGfx(0, DrvGfxROM, 8, 8, 8, graphicsrom_len, 0, 0xf);
547 GenericTilemapSetTransparent(1, 0);
548 GenericTilemapSetTransparent(2, 0);
549 BurnBitmapAllocate(1, 512, 512, true);
550
551 DrvDoReset();
552
553 return 0;
554 }
555
LegendohLoadCallback()556 static INT32 LegendohLoadCallback()
557 {
558 INT32 k = 0;
559 if (BurnLoadRom(DrvBootROM + 0x0180000, k++, 1)) return 1;
560
561 if (BurnLoadRom(DrvMainROM + 0x0000000, k++, 1)) return 1;
562 if (BurnLoadRom(DrvMainROM + 0x0200000, k++, 1)) return 1;
563
564 if (BurnLoadRom(DrvGfxROM + 0x0000000, k++, 4)) return 1;
565 if (BurnLoadRom(DrvGfxROM + 0x0000001, k++, 4)) return 1;
566 if (BurnLoadRom(DrvGfxROM + 0x0000002, k++, 4)) return 1;
567 if (BurnLoadRom(DrvGfxROM + 0x0000003, k++, 4)) return 1;
568 if (BurnLoadRom(DrvGfxROM + 0x0800000, k++, 4)) return 1;
569 if (BurnLoadRom(DrvGfxROM + 0x0800001, k++, 4)) return 1;
570 if (BurnLoadRom(DrvGfxROM + 0x0800002, k++, 4)) return 1;
571 if (BurnLoadRom(DrvGfxROM + 0x0800003, k++, 4)) return 1;
572 if (BurnLoadRom(DrvGfxROM + 0x1000000, k++, 4)) return 1;
573 if (BurnLoadRom(DrvGfxROM + 0x1000001, k++, 4)) return 1;
574 if (BurnLoadRom(DrvGfxROM + 0x1000002, k++, 4)) return 1;
575 if (BurnLoadRom(DrvGfxROM + 0x1000003, k++, 4)) return 1;
576
577 if (BurnLoadRom(DrvQSROM + 0x0000000, k++, 1)) return 1;
578
579 if (BurnLoadRom(DrvSndROM + 0x0000000, k++, 1)) return 1;
580 if (BurnLoadRom(DrvSndROM + 0x0080000, k++, 1)) return 1;
581 if (BurnLoadRom(DrvSndROM + 0x0200000, k++, 1)) return 1;
582
583 security_bit_config = ~0 & 0x00400000; // = bit is high
584
585 return 0;
586 }
587
DynabombLoadCallback()588 static INT32 DynabombLoadCallback()
589 {
590 INT32 k = 0;
591 if (BurnLoadRom(DrvBootROM + 0x0000000, k++, 1)) return 1;
592
593 if (BurnLoadRom(DrvMainROM + 0x0000000, k++, 1)) return 1;
594
595 if (BurnLoadRom(DrvQSROM + 0x0000000, k++, 1)) return 1;
596
597 if (BurnLoadRom(DrvGfxROM + 0x0000000, k++, 4)) return 1;
598 if (BurnLoadRom(DrvGfxROM + 0x0000001, k++, 4)) return 1;
599 if (BurnLoadRom(DrvGfxROM + 0x0000002, k++, 4)) return 1;
600 if (BurnLoadRom(DrvGfxROM + 0x0000003, k++, 4)) return 1;
601
602 if (BurnLoadRom(DrvSndROM + 0x0000000, k++, 1)) return 1;
603 if (BurnLoadRom(DrvSndROM + 0x0080000, k++, 1)) return 1;
604 if (BurnLoadRom(DrvSndROM + 0x0200000, k++, 1)) return 1;
605
606 security_bit_config = 0 & 0x00400000; // = bit is low
607
608 return 0;
609 }
610
Sb2003LoadCallback()611 static INT32 Sb2003LoadCallback()
612 {
613 INT32 k = 0;
614 if (BurnLoadRom(DrvBootROM + 0x0000000, k++, 1)) return 1;
615
616 if (BurnLoadRom(DrvQSROM + 0x0000000, k++, 1)) return 1;
617
618 if (BurnLoadRom(DrvGfxROM + 0x0000000, k++, 4)) return 1;
619 if (BurnLoadRom(DrvGfxROM + 0x0000001, k++, 4)) return 1;
620 if (BurnLoadRom(DrvGfxROM + 0x0000002, k++, 4)) return 1;
621 if (BurnLoadRom(DrvGfxROM + 0x0000003, k++, 4)) return 1;
622
623 if (BurnLoadRom(DrvSndROM + 0x0000000, k++, 1)) return 1;
624 if (BurnLoadRom(DrvSndROM + 0x0200000, k++, 1)) return 1;
625
626 security_bit_config = 0 & 0x00400000; // = bit is low
627
628 return 0;
629 }
630
SpottyLoadCallback()631 static INT32 SpottyLoadCallback()
632 {
633 INT32 k = 0;
634 if (BurnLoadRom(DrvBootROM + 0x0180000, k++, 1)) return 1;
635
636 if (BurnLoadRom(DrvQSROM + 0x0000000, k++, 1)) return 1; // not qs
637
638 if (BurnLoadRom(DrvGfxROM + 0x0000000, k++, 4)) return 1;
639 if (BurnLoadRom(DrvGfxROM + 0x0000002, k++, 4)) return 1;
640
641 if (BurnLoadRom(DrvSndROM + 0x0000000, k++, 1)) return 1;
642
643 {
644 for (INT32 x = 0; x < 0x200000; x += 2)
645 {
646 DrvGfxROM[x+1] = (DrvGfxROM[x]&0xf0) >> 4;
647 DrvGfxROM[x+0] = (DrvGfxROM[x]&0x0f) >> 0;
648 }
649 }
650
651 security_bit_config = 0 & 0x00400000; // = bit is low
652 eeprom_bit_config = 0x00800000;
653 spriteram_bit_config = 0x00080000; // different
654
655 return 0;
656 }
657
DrvExit()658 static INT32 DrvExit()
659 {
660 GenericTilesExit();
661
662 E132XSExit();
663 EEPROMExit();
664
665 switch (sound_type)
666 {
667 case 0: qs1000_exit(); break;
668 case 1: // spotty
669 {
670 mcs51_exit();
671 MSM6295Exit();
672 }
673 break;
674 }
675
676 BurnFreeMemIndex();
677
678 security_bit_config = 0x00400000;
679 eeprom_bit_config = 0x00800000;
680 spriteram_bit_config = 0x80000000;
681 sound_type = 0;
682
683 speedhack_address = 0xffffffff;
684 speedhack_pc = 0;
685
686 MSM6295ROM = NULL;
687
688 return 0;
689 }
690
draw_single_sprite(UINT8 width,UINT8 height,UINT32 code,UINT32 color,bool flipx,bool flipy,int offsx,int offsy,UINT8 transparent_color,UINT8 priority)691 static void draw_single_sprite(UINT8 width, UINT8 height, UINT32 code, UINT32 color,bool flipx,bool flipy,int offsx,int offsy, UINT8 transparent_color, UINT8 priority)
692 {
693 UINT16 pal = color << 8;
694 UINT8 *source_base = DrvGfxROM + code;
695
696 int xinc = flipx ? -1 : 1;
697 int yinc = flipy ? -1 : 1;
698
699 int x_index_base = flipx ? width - 1 : 0;
700 int y_index = flipy ? height - 1 : 0;
701
702 int sx = offsx;
703 int sy = offsy;
704
705 int ex = sx + width;
706 int ey = sy + height;
707
708 if (sx < 0)
709 {
710 int pixels = 0 - sx;
711 sx += pixels;
712 x_index_base += xinc * pixels;
713 }
714
715 if (sy < 0)
716 {
717 int pixels = 0 - sy;
718 sy += pixels;
719 y_index += yinc * pixels;
720 }
721
722 if (ex > 512) ey = 512;
723 if (ex > 512) ex = 512;
724
725 if (ex > sx)
726 {
727 for (int y = sy; y < ey; y++)
728 {
729 const UINT8 *source = source_base + y_index * width;
730 UINT16 *dest = BurnBitmapGetPosition(1, 0, y);
731 UINT8 *pri = BurnBitmapGetPrimapPosition(1, 0, y);
732 int x_index = x_index_base;
733 for (int x = sx; x < ex; x++)
734 {
735 const UINT8 c = source[x_index];
736 if (c != transparent_color)
737 {
738 if (pri[x] < priority)
739 {
740 dest[x] = BURN_ENDIAN_SWAP_INT16(pal + c);
741 pri[x] = priority;
742 }
743 }
744 x_index += xinc;
745 }
746 y_index += yinc;
747 }
748 }
749 }
750
limenko_draw_sprites()751 void limenko_draw_sprites()
752 {
753 BurnBitmapFill(1, 0);
754 BurnBitmapPrimapClear(1);
755
756 UINT32 *sprites = (UINT32*)(DrvSprRAM + (0x1000 * spriteram_bit));
757
758 for (UINT32 i = 0; i <= prev_sprites_count * 2; i += 2)
759 {
760 UINT32 sprites0 = BURN_ENDIAN_SWAP_INT32(sprites[i + 0]);
761 UINT32 sprites1 = BURN_ENDIAN_SWAP_INT32(sprites[i + 1]);
762
763 sprites0 = (sprites0 << 16) | (sprites0 >> 16);
764 sprites1 = (sprites1 << 16) | (sprites1 >> 16);
765
766 if (~sprites0 & 0x80000000) continue;
767
768 int x = ((sprites0 & 0x01ff0000) >> 16);
769 int width = (((sprites0 & 0x0e000000) >> 25) + 1) * 8;
770 bool flipx = sprites0 & 0x10000000;
771 int y = sprites0 & 0x000001ff;
772 int height = (((sprites0 & 0x00000e00) >> 9) + 1) * 8;
773 bool flipy = sprites0 & 0x00001000;
774 UINT32 code= (sprites1 & 0x0007ffff) << 6;
775 UINT32 color= (sprites1 & 0xf0000000) >> 28;
776
777 int pri = 0;
778 if (sprites1 & 0x04000000)
779 {
780 pri = 1;
781 }
782 else
783 {
784 pri = 2;
785 }
786
787 /* Bounds checking */
788 if ((code + (width * height)) > (UINT32)graphicsrom_len)
789 continue;
790
791 draw_single_sprite(width,height,code,color,flipx,flipy,x,y,0,pri);
792
793 // wrap around x
794 draw_single_sprite(width,height,code,color,flipx,flipy,x-512,y,0,pri);
795
796 // wrap around y
797 draw_single_sprite(width,height,code,color,flipx,flipy,x,y-512,0,pri);
798
799 // wrap around x and y
800 draw_single_sprite(width,height,code,color,flipx,flipy,x-512,y-512,0,pri);
801 }
802 }
803
copy_sprites()804 static void copy_sprites()
805 {
806 for (INT32 y = 0; y < nScreenHeight; y++)
807 {
808 UINT16 *dest = BurnBitmapGetPosition(0, 0, y);
809 UINT16 *source = BurnBitmapGetPosition(1, 0, y);
810 UINT8 *dest_pri = BurnBitmapGetPrimapPosition(0, 0, y);
811 UINT8 *source_pri = BurnBitmapGetPrimapPosition(1, 0, y);
812
813 for (INT32 x = 0; x < nScreenWidth; x++)
814 {
815 if (source[x] != 0)
816 {
817 if (dest_pri[x] < source_pri[x])
818 dest[x] = BURN_ENDIAN_SWAP_INT16(source[x]);
819 }
820 }
821 }
822 }
823
DrvDraw()824 static INT32 DrvDraw()
825 {
826 if (DrvRecalc) {
827 BurnPaletteUpdate_xBBBBBGGGGGRRRRR();
828 DrvRecalc = 1; // force update
829 }
830
831 GenericTilemapSetEnable(0, (BURN_ENDIAN_SWAP_INT32(video_regs[0]) >> 16) & 0x04);
832 GenericTilemapSetEnable(1, (BURN_ENDIAN_SWAP_INT32(video_regs[0]) >> 16) & 0x02);
833 GenericTilemapSetEnable(2, (BURN_ENDIAN_SWAP_INT32(video_regs[0]) >> 16) & 0x01);
834
835 GenericTilemapSetScrollX(0, BURN_ENDIAN_SWAP_INT32(video_regs[3]) >> 0);
836 GenericTilemapSetScrollX(1, BURN_ENDIAN_SWAP_INT32(video_regs[2]) >> 0);
837 GenericTilemapSetScrollX(2, BURN_ENDIAN_SWAP_INT32(video_regs[1]) >> 0);
838 GenericTilemapSetScrollY(0, BURN_ENDIAN_SWAP_INT32(video_regs[3]) >> 16);
839 GenericTilemapSetScrollY(1, BURN_ENDIAN_SWAP_INT32(video_regs[2]) >> 16);
840 GenericTilemapSetScrollY(2, BURN_ENDIAN_SWAP_INT32(video_regs[1]) >> 16);
841
842 BurnTransferClear();
843
844 if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 0);
845 if (nBurnLayer & 2) GenericTilemapDraw(1, pTransDraw, 0);
846 if (nBurnLayer & 4) GenericTilemapDraw(2, pTransDraw, 1);
847
848 if ((BURN_ENDIAN_SWAP_INT32(video_regs[0]) >> 16) & 0x08)
849 if (nSpriteEnable & 1) copy_sprites();
850
851 BurnTransferCopy(BurnPalette);
852
853 return 0;
854 }
855
DrvFrame()856 static INT32 DrvFrame()
857 {
858 if (DrvReset) {
859 DrvDoReset();
860 }
861
862 E132XSNewFrame();
863 mcs51NewFrame();
864
865 {
866 memset (DrvInputs, 0xff, sizeof(DrvInputs));
867
868 for (INT32 i = 0; i < 16; i++) {
869 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
870 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
871 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
872 }
873 }
874
875 INT32 nInterleave = 10;
876 INT32 nCyclesTotal[2] = { cpu_clock / 60, (sound_type ? 4000000 : 2000000) / 60 };
877 INT32 nCyclesDone[2] = { 0, 0 };
878
879 E132XSOpen(0);
880 mcs51Open(0);
881
882 for (INT32 i = 0; i < nInterleave; i++)
883 {
884 CPU_RUN(0, E132XS);
885 if (i == (nInterleave - 1)) E132XSSetIRQLine(0, CPU_IRQSTATUS_HOLD);
886
887 CPU_RUN_SYNCINT(1, mcs51);
888 }
889
890 if (pBurnSoundOut) {
891 switch (sound_type)
892 {
893 case 0: qs1000_update(pBurnSoundOut, nBurnSoundLen); break;
894 case 1: MSM6295Render(pBurnSoundOut, nBurnSoundLen); break;
895 }
896 }
897
898 mcs51Close();
899 E132XSClose();
900
901 if (pBurnDraw) {
902 BurnDrvRedraw();
903 }
904
905 return 0;
906 }
907
DrvScan(INT32 nAction,INT32 * pnMin)908 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
909 {
910 struct BurnArea ba;
911
912 if (pnMin != NULL) {
913 *pnMin = 0x029698;
914 }
915
916 if (nAction & ACB_MEMORY_RAM) {
917 memset(&ba, 0, sizeof(ba));
918 ba.Data = AllRam;
919 ba.nLen = RamEnd-AllRam;
920 ba.szName = "All Ram";
921 BurnAcb(&ba);
922 }
923
924 if (nAction & ACB_DRIVER_DATA) {
925 E132XSScan(nAction);
926 mcs51_scan(nAction);
927
928 switch (sound_type)
929 {
930 case 0: qs1000_scan(nAction, pnMin); break;
931 case 1: MSM6295Scan(nAction, pnMin); break;
932 }
933
934 SCAN_VAR(audiocpu_data);
935 SCAN_VAR(soundlatch);
936 SCAN_VAR(spriteram_bit);
937 SCAN_VAR(prev_sprites_count);
938 }
939
940 if (nAction & ACB_NVRAM) {
941 EEPROMScan(nAction, pnMin);
942 }
943
944 return 0;
945 }
946
947
948 // Dynamite Bomber (Korea, Rev 1.5)
949
950 static struct BurnRomInfo dynabombRomDesc[] = {
951 { "rom.u6", 0x200000, 0x457e015d, 1 | BRF_PRG | BRF_ESS }, // 0 Hyperstone Boot ROM
952
953 { "rom.u5", 0x200000, 0x7e837adf, 2 | BRF_PRG | BRF_ESS }, // 1 Hyperstone Main ROM
954
955 { "rom.u16", 0x020000, 0xf66d7e4d, 3 | BRF_PRG | BRF_ESS }, // 2 qs1000:cpu
956
957 { "rom.u1", 0x200000, 0xbf33eff6, 4 | BRF_GRA }, // 3 Graphics
958 { "rom.u2", 0x200000, 0x790bbcd5, 4 | BRF_GRA }, // 4
959 { "rom.u3", 0x200000, 0xec094b12, 4 | BRF_GRA }, // 5
960 { "rom.u4", 0x200000, 0x88b24e3c, 4 | BRF_GRA }, // 6
961
962 { "rom.u18", 0x080000, 0x50d76732, 5 | BRF_SND }, // 7 QS1000 Samples
963 { "rom.u17", 0x080000, 0x20f2417c, 5 | BRF_SND }, // 8
964 { "qs1003.u4", 0x200000, 0x19e4b469, 5 | BRF_SND }, // 9
965 };
966
967 STD_ROM_PICK(dynabomb)
STD_ROM_FN(dynabomb)968 STD_ROM_FN(dynabomb)
969
970 static INT32 DynabombInit()
971 {
972 speedhack_address = 0xe2784;
973 speedhack_pc = 0xc25b8;
974
975 security_bit_config = 0x00400000 & 0; // low
976 eeprom_bit_config = 0x00800000;
977 spriteram_bit_config = 0x80000000;
978
979 return LimenkoCommonInit(TYPE_E132XN, 80000000, DynabombLoadCallback, 0x800000, 0);
980 }
981
982 struct BurnDriver BurnDrvDynabomb = {
983 "dynabomb", NULL, NULL, NULL, "2000",
984 "Dynamite Bomber (Korea, Rev 1.5)\0", NULL, "Limenko", "Miscellaneous",
985 NULL, NULL, NULL, NULL,
986 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_MAZE, 0,
987 NULL, dynabombRomInfo, dynabombRomName, NULL, NULL, NULL, NULL, Sb2003InputInfo, Sb2003DIPInfo,
988 DynabombInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
989 384, 240, 4, 3
990 };
991
992
993 // Super Bubble 2003 (World, Ver 1.0)
994
995 static struct BurnRomInfo sb2003RomDesc[] = {
996 { "sb2003_05.u6", 0x200000, 0x8aec4554, 1 | BRF_PRG | BRF_ESS }, // 0 Hyperstone Boot ROM
997
998 { "07.u16", 0x020000, 0x78acc607, 3 | BRF_PRG | BRF_ESS }, // 1 QS1000 Code
999
1000 { "01.u1", 0x200000, 0xd2c7091a, 4 | BRF_GRA }, // 2 Graphics
1001 { "02.u2", 0x200000, 0xa0734195, 4 | BRF_GRA }, // 3
1002 { "03.u3", 0x200000, 0x0f020280, 4 | BRF_GRA }, // 4
1003 { "04.u4", 0x200000, 0xfc2222b9, 4 | BRF_GRA }, // 5
1004
1005 { "06.u18", 0x200000, 0xb6ad0d32, 5 | BRF_SND }, // 6 QS1000 Samples
1006 { "qs1003.u4", 0x200000, 0x19e4b469, 5 | BRF_SND }, // 7
1007 };
1008
1009 STD_ROM_PICK(sb2003)
STD_ROM_FN(sb2003)1010 STD_ROM_FN(sb2003)
1011
1012 static INT32 Sb2003Init()
1013 {
1014 speedhack_address = 0x135800;
1015 speedhack_pc = 0x26da4;
1016
1017 security_bit_config = 0x00400000 & 0; // low
1018 eeprom_bit_config = 0x00800000;
1019 spriteram_bit_config = 0x80000000;
1020
1021 return LimenkoCommonInit(TYPE_E132XN, 80000000, Sb2003LoadCallback, 0x800000, 0);
1022 }
1023
1024 struct BurnDriver BurnDrvSb2003 = {
1025 "sb2003", NULL, NULL, NULL, "2003",
1026 "Super Bubble 2003 (World, Ver 1.0)\0", NULL, "Limenko", "Miscellaneous",
1027 NULL, NULL, NULL, NULL,
1028 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PLATFORM, 0,
1029 NULL, sb2003RomInfo, sb2003RomName, NULL, NULL, NULL, NULL, Sb2003InputInfo, Sb2003DIPInfo,
1030 Sb2003Init, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
1031 384, 240, 4, 3
1032 };
1033
1034
1035 // Super Bubble 2003 (Asia, Ver 1.0)
1036
1037 static struct BurnRomInfo sb2003aRomDesc[] = {
1038 { "sb2003a_05.u6", 0x200000, 0x265e45a7, 1 | BRF_PRG | BRF_ESS }, // 0 Hyperstone Boot ROM
1039
1040 { "07.u16", 0x020000, 0x78acc607, 3 | BRF_PRG | BRF_ESS }, // 1 QS1000 Code
1041
1042 { "01.u1", 0x200000, 0xd2c7091a, 4 | BRF_GRA }, // 2 Graphics
1043 { "02.u2", 0x200000, 0xa0734195, 4 | BRF_GRA }, // 3
1044 { "03.u3", 0x200000, 0x0f020280, 4 | BRF_GRA }, // 4
1045 { "04.u4", 0x200000, 0xfc2222b9, 4 | BRF_GRA }, // 5
1046
1047 { "06.u18", 0x200000, 0xb6ad0d32, 5 | BRF_SND }, // 6 QS1000 Samples
1048 { "qs1003.u4", 0x200000, 0x19e4b469, 5 | BRF_SND }, // 7
1049 };
1050
1051 STD_ROM_PICK(sb2003a)
1052 STD_ROM_FN(sb2003a)
1053
1054 struct BurnDriver BurnDrvSb2003a = {
1055 "sb2003a", "sb2003", NULL, NULL, "2003",
1056 "Super Bubble 2003 (Asia, Ver 1.0)\0", NULL, "Limenko", "Miscellaneous",
1057 NULL, NULL, NULL, NULL,
1058 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_PLATFORM, 0,
1059 NULL, sb2003aRomInfo, sb2003aRomName, NULL, NULL, NULL, NULL, Sb2003InputInfo, Sb2003DIPInfo,
1060 Sb2003Init, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
1061 384, 240, 4, 3
1062 };
1063
1064
1065 // Legend of Heroes
1066
1067 static struct BurnRomInfo legendohRomDesc[] = {
1068 { "01.sys_rom4", 0x080000, 0x49b4a91f, 1 | BRF_PRG | BRF_ESS }, // 0 Hyperstone Boot ROM
1069
1070 { "sys_rom6", 0x200000, 0x5c13d467, 2 | BRF_PRG | BRF_ESS }, // 1 Hyperstone Main ROM
1071 { "sys_rom5", 0x200000, 0x19dc8d23, 2 | BRF_PRG | BRF_ESS }, // 2
1072
1073 { "cg_rom10", 0x200000, 0x93a48489, 4 | BRF_GRA }, // 3 Graphics
1074 { "cg_rom20", 0x200000, 0x1a6c0258, 4 | BRF_GRA }, // 4
1075 { "cg_rom30", 0x200000, 0xa0559ef4, 4 | BRF_GRA }, // 5
1076 { "cg_rom40", 0x200000, 0xa607b2b5, 4 | BRF_GRA }, // 6
1077 { "cg_rom11", 0x200000, 0xa9fd5a50, 4 | BRF_GRA }, // 7
1078 { "cg_rom21", 0x200000, 0xb05cdeb2, 4 | BRF_GRA }, // 8
1079 { "cg_rom31", 0x200000, 0xa9a0d386, 4 | BRF_GRA }, // 9
1080 { "cg_rom41", 0x200000, 0x1c014f45, 4 | BRF_GRA }, // 10
1081 { "02.cg_rom12", 0x080000, 0x8b2e8cbc, 4 | BRF_GRA }, // 11
1082 { "03.cg_rom22", 0x080000, 0xa35960c8, 4 | BRF_GRA }, // 12
1083 { "04.cg_rom32", 0x080000, 0x3f486cab, 4 | BRF_GRA }, // 13
1084 { "05.cg_rom42", 0x080000, 0x5d807bec, 4 | BRF_GRA }, // 14
1085
1086 { "sou_prg.06", 0x080000, 0xbfafe7aa, 3 | BRF_PRG | BRF_ESS }, // 15 QS1000 Code
1087
1088 { "sou_rom.07", 0x080000, 0x4c6eb6d2, 5 | BRF_SND }, // 16 QS1000 Samples
1089 { "sou_rom.08", 0x080000, 0x42c32dd5, 5 | BRF_SND }, // 17
1090 { "qs1003.u4", 0x200000, 0x19e4b469, 5 | BRF_SND }, // 18
1091 };
1092
1093 STD_ROM_PICK(legendoh)
STD_ROM_FN(legendoh)1094 STD_ROM_FN(legendoh)
1095
1096 static INT32 LegendohInit()
1097 {
1098 speedhack_address = 0x32ab0;
1099 speedhack_pc = 0x23e32;
1100
1101 security_bit_config = 0x00400000; // high
1102 eeprom_bit_config = 0x00800000;
1103 spriteram_bit_config = 0x80000000;
1104
1105 return LimenkoCommonInit(TYPE_E132XN, 80000000, LegendohLoadCallback, 0x1200000, 0);
1106 }
1107
1108 struct BurnDriver BurnDrvLegendoh = {
1109 "legendoh", NULL, NULL, NULL, "2000",
1110 "Legend of Heroes\0", NULL, "Limenko", "Miscellaneous",
1111 NULL, NULL, NULL, NULL,
1112 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_SCRFIGHT, 0,
1113 NULL, legendohRomInfo, legendohRomName, NULL, NULL, NULL, NULL, LegendohInputInfo, LegendohDIPInfo,
1114 LegendohInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
1115 384, 240, 4, 3
1116 };
1117
1118
1119 // Spotty (Ver. 2.0.2)
1120
1121 static struct BurnRomInfo spottyRomDesc[] = {
1122 { "sys_rom2", 0x80000, 0x6ded8d9b, 1 | BRF_PRG | BRF_ESS }, // 0 Hyperstone Boot ROM
1123
1124 { "at89c4051.mcu", 0x01000, 0x82ceab26, 3 | BRF_PRG | BRF_ESS }, // 1 at89c4051 Code
1125
1126 { "gc_rom1", 0x80000, 0xea03f9c5, 2 | BRF_PRG | BRF_ESS }, // 2 Hyperstone Main ROM / Graphics
1127 { "gc_rom3", 0x80000, 0x0ddac0b9, 2 | BRF_PRG | BRF_ESS }, // 3
1128
1129 { "sou_rom1", 0x40000, 0x5791195b, 4 | BRF_SND }, // 4 OKI Samples
1130 };
1131
1132 STD_ROM_PICK(spotty)
STD_ROM_FN(spotty)1133 STD_ROM_FN(spotty)
1134
1135 static INT32 SpottyInit()
1136 {
1137 speedhack_address = 0x6626c;
1138 speedhack_pc = 0x8560;
1139
1140 security_bit_config = 0x00400000 & 0; // low
1141 eeprom_bit_config = 0x00800000;
1142 spriteram_bit_config = 0x00080000;
1143
1144 return LimenkoCommonInit(TYPE_GMS30C2232, 20000000, SpottyLoadCallback, 0x200000, 1);
1145 }
1146
1147 struct BurnDriver BurnDrvSpotty = {
1148 "spotty", NULL, NULL, NULL, "2001",
1149 "Spotty (Ver. 2.0.2)\0", NULL, "Prince Co.", "Miscellaneous",
1150 NULL, NULL, NULL, NULL,
1151 BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_CASINO, 0,
1152 NULL, spottyRomInfo, spottyRomName, NULL, NULL, NULL, NULL, SpottyInputInfo, SpottyDIPInfo,
1153 SpottyInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
1154 384, 240, 4, 3
1155 };
1156