1 // FB Alpha Wyvern F-0 driver module
2 // Based on MAME driver by Luca Elia
3
4 // Note: wyvernf0 sound hw has a dac @ 0xd600, but it is not used in the
5 // game at all except for initialization @ boot (0x80)
6
7 #include "tiles_generic.h"
8 #include "z80_intf.h"
9 #include "taito_m68705.h"
10 #include "ay8910.h"
11 #include "msm5232.h"
12
13 static UINT8 *AllMem;
14 static UINT8 *MemEnd;
15 static UINT8 *AllRam;
16 static UINT8 *RamEnd;
17 static UINT8 *DrvZ80ROM0;
18 static UINT8 *DrvZ80ROM1;
19 static UINT8 *DrvGfxROM0;
20 static UINT8 *DrvGfxROM1;
21 static UINT8 *DrvZ80RAM0;
22 static UINT8 *DrvMcuROM;
23 static UINT8 *DrvMcuRAM;
24 static UINT8 *DrvFgRAM;
25 static UINT8 *DrvBgRAM;
26 static UINT8 *DrvSprRAM;
27 static UINT8 *DrvPalRAM;
28 static UINT8 *DrvObjRAM;
29 static UINT8 *DrvZ80RAM1;
30
31 static UINT8 *soundlatch;
32 static UINT8 *flipscreen;
33 static UINT8 *coin_lockout;
34 static UINT8 *scroll;
35 static UINT8 *pending_nmi;
36 static UINT8 *nmi_enable;
37 static UINT8 *DrvZ80ROMBank;
38 static UINT8 *DrvZ80RAMBank;
39
40 static UINT32 *DrvPalette;
41 static UINT8 DrvRecalc;
42
43 static UINT8 DrvJoy1[8];
44 static UINT8 DrvJoy2[8];
45 static UINT8 DrvJoy3[8];
46 static UINT8 DrvJoy4[8];
47 static UINT8 DrvJoy5[8];
48 static UINT8 DrvDips[3];
49 static UINT8 DrvInputs[5];
50 static UINT8 DrvReset;
51
52 static struct BurnInputInfo Wyvernf0InputList[] = {
53 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 4, "p1 coin" },
54 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 0, "p1 start" },
55 {"P1 Up", BIT_DIGITAL, DrvJoy2 + 5, "p1 up" },
56 {"P1 Down", BIT_DIGITAL, DrvJoy2 + 4, "p1 down" },
57 {"P1 Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 left" },
58 {"P1 Right", BIT_DIGITAL, DrvJoy2 + 3, "p1 right" },
59 {"P1 Button 1", BIT_DIGITAL, DrvJoy3 + 5, "p1 fire 1" },
60 {"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 4, "p1 fire 2" },
61 {"P1 Button 3", BIT_DIGITAL, DrvJoy3 + 3, "p1 fire 3" },
62
63 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 5, "p2 coin" },
64 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 1, "p2 start" },
65 {"P2 Up", BIT_DIGITAL, DrvJoy4 + 5, "p2 up" },
66 {"P2 Down", BIT_DIGITAL, DrvJoy4 + 4, "p2 down" },
67 {"P2 Left", BIT_DIGITAL, DrvJoy4 + 2, "p2 left" },
68 {"P2 Right", BIT_DIGITAL, DrvJoy4 + 3, "p2 right" },
69 {"P2 Button 1", BIT_DIGITAL, DrvJoy5 + 5, "p2 fire 1" },
70 {"P2 Button 2", BIT_DIGITAL, DrvJoy5 + 4, "p2 fire 2" },
71 {"P2 Button 3", BIT_DIGITAL, DrvJoy5 + 3, "p2 fire 3" },
72
73 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
74 {"Service", BIT_DIGITAL, DrvJoy1 + 2, "service" },
75 {"Tilt", BIT_DIGITAL, DrvJoy1 + 3, "tilt" },
76 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
77 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
78 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
79 };
80
81 STDINPUTINFO(Wyvernf0)
82
83 static struct BurnDIPInfo Wyvernf0DIPList[]=
84 {
85 {0x15, 0xff, 0xff, 0x6f, NULL },
86 {0x16, 0xff, 0xff, 0x00, NULL },
87 {0x17, 0xff, 0xff, 0xdc, NULL },
88
89 {0 , 0xfe, 0 , 4, "Bonus Life" },
90 {0x15, 0x01, 0x03, 0x00, "?? 0" },
91 {0x15, 0x01, 0x03, 0x01, "?? 1" },
92 {0x15, 0x01, 0x03, 0x02, "?? 2" },
93 {0x15, 0x01, 0x03, 0x03, "?? 3" },
94
95 {0 , 0xfe, 0 , 2, "Free Play" },
96 {0x15, 0x01, 0x04, 0x04, "Off" },
97 {0x15, 0x01, 0x04, 0x00, "On" },
98
99 {0 , 0xfe, 0 , 4, "Lives" },
100 {0x15, 0x01, 0x18, 0x00, "2" },
101 {0x15, 0x01, 0x18, 0x08, "3" },
102 {0x15, 0x01, 0x18, 0x10, "4" },
103 {0x15, 0x01, 0x18, 0x18, "5" },
104
105 {0 , 0xfe, 0 , 2, "Flip Screen" },
106 {0x15, 0x01, 0x40, 0x40, "Off" },
107 {0x15, 0x01, 0x40, 0x00, "On" },
108
109 {0 , 0xfe, 0 , 2, "Cabinet" },
110 {0x15, 0x01, 0x80, 0x00, "Upright" },
111 {0x15, 0x01, 0x80, 0x80, "Cocktail" },
112
113 {0 , 0xfe, 0 , 16, "Coin A" },
114 {0x16, 0x01, 0x0f, 0x0f, "9 Coins 1 Credits" },
115 {0x16, 0x01, 0x0f, 0x0e, "8 Coins 1 Credits" },
116 {0x16, 0x01, 0x0f, 0x0d, "7 Coins 1 Credits" },
117 {0x16, 0x01, 0x0f, 0x0c, "6 Coins 1 Credits" },
118 {0x16, 0x01, 0x0f, 0x0b, "5 Coins 1 Credits" },
119 {0x16, 0x01, 0x0f, 0x0a, "4 Coins 1 Credits" },
120 {0x16, 0x01, 0x0f, 0x09, "3 Coins 1 Credits" },
121 {0x16, 0x01, 0x0f, 0x08, "2 Coins 1 Credits" },
122 {0x16, 0x01, 0x0f, 0x00, "1 Coin 1 Credits" },
123 {0x16, 0x01, 0x0f, 0x01, "1 Coin 2 Credits" },
124 {0x16, 0x01, 0x0f, 0x02, "1 Coin 3 Credits" },
125 {0x16, 0x01, 0x0f, 0x03, "1 Coin 4 Credits" },
126 {0x16, 0x01, 0x0f, 0x04, "1 Coin 5 Credits" },
127 {0x16, 0x01, 0x0f, 0x05, "1 Coin 6 Credits" },
128 {0x16, 0x01, 0x0f, 0x06, "1 Coin 7 Credits" },
129 {0x16, 0x01, 0x0f, 0x07, "1 Coin 8 Credits" },
130
131 {0 , 0xfe, 0 , 16, "Coin B" },
132 {0x16, 0x01, 0xf0, 0xf0, "9 Coins 1 Credits" },
133 {0x16, 0x01, 0xf0, 0xe0, "8 Coins 1 Credits" },
134 {0x16, 0x01, 0xf0, 0xd0, "7 Coins 1 Credits" },
135 {0x16, 0x01, 0xf0, 0xc0, "6 Coins 1 Credits" },
136 {0x16, 0x01, 0xf0, 0xb0, "5 Coins 1 Credits" },
137 {0x16, 0x01, 0xf0, 0xa0, "4 Coins 1 Credits" },
138 {0x16, 0x01, 0xf0, 0x90, "3 Coins 1 Credits" },
139 {0x16, 0x01, 0xf0, 0x80, "2 Coins 1 Credits" },
140 {0x16, 0x01, 0xf0, 0x00, "1 Coin 1 Credits" },
141 {0x16, 0x01, 0xf0, 0x10, "1 Coin 2 Credits" },
142 {0x16, 0x01, 0xf0, 0x20, "1 Coin 3 Credits" },
143 {0x16, 0x01, 0xf0, 0x30, "1 Coin 4 Credits" },
144 {0x16, 0x01, 0xf0, 0x40, "1 Coin 5 Credits" },
145 {0x16, 0x01, 0xf0, 0x50, "1 Coin 6 Credits" },
146 {0x16, 0x01, 0xf0, 0x60, "1 Coin 7 Credits" },
147 {0x16, 0x01, 0xf0, 0x70, "1 Coin 8 Credits" },
148
149 {0 , 0xfe, 0 , 2, "Coinage Display" },
150 {0x17, 0x01, 0x10, 0x00, "No" },
151 {0x17, 0x01, 0x10, 0x10, "Yes" },
152
153 {0 , 0xfe, 0 , 2, "Copyright" },
154 {0x17, 0x01, 0x20, 0x00, "Taito Corporation" },
155 {0x17, 0x01, 0x20, 0x20, "Taito Corp. 1985" },
156
157 {0 , 0xfe, 0 , 2, "Invulnerability" },
158 {0x17, 0x01, 0x40, 0x40, "Off" },
159 {0x17, 0x01, 0x40, 0x00, "On" },
160
161 {0 , 0xfe, 0 , 2, "Coin Slots" },
162 {0x17, 0x01, 0x80, 0x00, "1" },
163 {0x17, 0x01, 0x80, 0x80, "2" },
164 };
165
STDDIPINFO(Wyvernf0)166 STDDIPINFO(Wyvernf0)
167
168 static inline void palette_update(INT32 i)
169 {
170 INT32 r = DrvPalRAM[i+0] & 0x0f;
171 INT32 g = DrvPalRAM[i+1] >> 4;
172 INT32 b = DrvPalRAM[i+1] & 0x0f;
173
174 DrvPalette[i/2] = BurnHighCol(r | (r << 4), g | (g << 4), b | (b << 4), 0);
175 }
176
rambankswitch(INT32 data)177 static void rambankswitch(INT32 data)
178 {
179 INT32 bank = (data & 0x80) ? 0x1000 : 0;
180
181 *DrvZ80RAMBank = data;
182
183 *coin_lockout = (~data & 0x40) ? 0xcf : 0xff;
184
185 *flipscreen = data & 0x03;
186
187 ZetMapMemory(DrvObjRAM + bank, 0x9000, 0x9fff, MAP_RAM);
188 }
189
rombankswitch(INT32 data)190 static void rombankswitch(INT32 data)
191 {
192 INT32 bank = 0x10000 + (data & 0x07) * 0x2000;
193
194 *DrvZ80ROMBank = data;
195
196 ZetMapMemory(DrvZ80ROM0 + bank, 0xa000, 0xbfff, MAP_ROM);
197 }
198
wyvernf0_main_write(UINT16 address,UINT8 data)199 static void __fastcall wyvernf0_main_write(UINT16 address, UINT8 data)
200 {
201 if ((address & 0xfc00) == 0xd800) {
202 DrvPalRAM[address & 0x3ff] = data;
203 palette_update(address & 0x3fe);
204 return;
205 }
206
207 switch (address)
208 {
209 case 0xd000:
210 return; // nop
211
212 case 0xd100:
213 rambankswitch(data);
214 return;
215
216 case 0xd200:
217 rombankswitch(data);
218 return;
219
220 case 0xd300:
221 case 0xd301:
222 case 0xd302:
223 case 0xd303:
224 scroll[address & 0x03] = data;
225 return;
226
227 case 0xd400:
228 standard_taito_mcu_write(data);
229 return;
230
231 case 0xd610:
232 {
233 *soundlatch = data;
234 if (*nmi_enable) {
235 ZetNmi(1);
236 } else {
237 *pending_nmi = 1;
238 }
239 }
240 return;
241
242 case 0xdc00:
243 return; // nop
244 }
245 }
246
wyvernf0_main_read(UINT16 address)247 static UINT8 __fastcall wyvernf0_main_read(UINT16 address)
248 {
249 switch (address)
250 {
251 case 0xd400:
252 return standard_taito_mcu_read();
253
254 case 0xd401:
255 return ( (!main_sent ? 1 : 0) | (mcu_sent ? 2 : 0) );
256
257 case 0xd600:
258 case 0xd601:
259 case 0xd602:
260 return DrvDips[address - 0xd600];
261
262 case 0xd603:
263 case 0xd604:
264 case 0xd605:
265 case 0xd606:
266 case 0xd607:
267 return DrvInputs[address - 0xd603];
268
269 case 0xd610:
270 return *soundlatch;
271 }
272
273 return 0;
274 }
275
wyvernf0_sound_write(UINT16 address,UINT8 data)276 static void __fastcall wyvernf0_sound_write(UINT16 address, UINT8 data)
277 {
278 if ((address & 0xfff0) == 0xc900) {
279 MSM5232Write(address & 0x0f, data);
280 return;
281 }
282
283 switch (address)
284 {
285 case 0xc800:
286 case 0xc801:
287 case 0xc802:
288 case 0xc803:
289 AY8910Write((address/2) & 1, address & 1, data);
290 if (data==0x88) { // end of sound command, turn off all channels to get rid of unwanted high pitched noises
291 AY8910Write((address/2) & 1, 0, 0x08);
292 AY8910Write((address/2) & 1, 1, 0x00);
293 AY8910Write((address/2) & 1, 0, 0x09);
294 AY8910Write((address/2) & 1, 1, 0x00);
295 AY8910Write((address/2) & 1, 0, 0x0A);
296 AY8910Write((address/2) & 1, 1, 0x00);
297 }
298 return;
299
300 case 0xd000:
301 *soundlatch = data;
302 return;
303
304 case 0xd200:
305 {
306 *nmi_enable = 1;
307
308 if (*pending_nmi)
309 {
310 ZetNmi();
311 *pending_nmi = 0;
312 }
313 }
314 return;
315
316 case 0xd400:
317 *nmi_enable = 0;
318 return;
319
320 case 0xd600:
321 return; // ??
322 }
323 }
324
wyvernf0_sound_read(UINT16 address)325 static UINT8 __fastcall wyvernf0_sound_read(UINT16 address)
326 {
327 switch (address)
328 {
329 case 0xd000:
330 return *soundlatch;
331 }
332
333 return 0;
334 }
335
DrvDoReset()336 static INT32 DrvDoReset()
337 {
338 memset (AllRam, 0, RamEnd - AllRam);
339
340 ZetOpen(0);
341 ZetReset();
342 rombankswitch(0);
343 rambankswitch(0);
344 ZetClose();
345
346 ZetOpen(1);
347 ZetReset();
348 ZetClose();
349
350 m67805_taito_reset();
351
352 AY8910Reset(0);
353 AY8910Reset(1);
354
355 MSM5232Reset();
356
357 return 0;
358 }
359
MemIndex()360 static INT32 MemIndex()
361 {
362 UINT8 *Next; Next = AllMem;
363
364 DrvZ80ROM0 = Next; Next += 0x020000;
365 DrvZ80ROM1 = Next; Next += 0x010000;
366 DrvMcuROM = Next; Next += 0x000800;
367
368 DrvGfxROM0 = Next; Next += 0x020000;
369 DrvGfxROM1 = Next; Next += 0x010000;
370
371 DrvPalette = (UINT32*)Next; Next += 0x0200 * sizeof(UINT32);
372
373 AllRam = Next;
374
375 DrvZ80RAM0 = Next; Next += 0x001000;
376 DrvFgRAM = Next; Next += 0x000800;
377 DrvBgRAM = Next; Next += 0x000800;
378 DrvSprRAM = Next; Next += 0x000100;
379 DrvPalRAM = Next; Next += 0x000400;
380 DrvObjRAM = Next; Next += 0x002000;
381
382 DrvZ80RAM1 = Next; Next += 0x000800;
383
384 DrvMcuRAM = Next; Next += 0x000800;
385
386 soundlatch = Next; Next += 0x000001;
387 flipscreen = Next; Next += 0x000001;
388 coin_lockout = Next; Next += 0x000001;
389 pending_nmi = Next; Next += 0x000001;
390 nmi_enable = Next; Next += 0x000001;
391 scroll = Next; Next += 0x000004;
392 DrvZ80ROMBank = Next; Next += 0x000001;
393 DrvZ80RAMBank = Next; Next += 0x000001;
394
395 RamEnd = Next;
396
397 MemEnd = Next;
398
399 return 0;
400 }
401
DrvGfxDecode(UINT8 * rom,INT32 len)402 static void DrvGfxDecode(UINT8 *rom, INT32 len)
403 {
404 INT32 Planes[4] = { RGN_FRAC(len,0,4), RGN_FRAC(len,1,4), RGN_FRAC(len,2,4), RGN_FRAC(len,3,4) };
405 INT32 XOffs[8] = { STEP8(7,-1) };
406 INT32 YOffs[8] = { STEP8(0,8) };
407
408 UINT8 *tmp = (UINT8*)BurnMalloc(len);
409 if (tmp == NULL) {
410 return;
411 }
412
413 memcpy (tmp, rom, len);
414
415 GfxDecode(((len/4)*8)/(8*8), 4, 8, 8, Planes, XOffs, YOffs, 0x040, tmp, rom);
416
417 BurnFree(tmp);
418 }
419
DrvInit()420 static INT32 DrvInit()
421 {
422 AllMem = NULL;
423 MemIndex();
424 INT32 nLen = MemEnd - (UINT8 *)0;
425 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
426 memset(AllMem, 0, nLen);
427 MemIndex();
428
429 {
430 if (BurnLoadRom(DrvZ80ROM0 + 0x00000, 0, 1)) return 1;
431 if (BurnLoadRom(DrvZ80ROM0 + 0x04000, 1, 1)) return 1;
432 if (BurnLoadRom(DrvZ80ROM0 + 0x10000, 2, 1)) return 1;
433 if (BurnLoadRom(DrvZ80ROM0 + 0x14000, 3, 1)) return 1;
434 if (BurnLoadRom(DrvZ80ROM0 + 0x18000, 4, 1)) return 1;
435 if (BurnLoadRom(DrvZ80ROM0 + 0x1c000, 5, 1)) return 1;
436
437 if (BurnLoadRom(DrvZ80ROM1 + 0x00000, 6, 1)) return 1;
438 memset (DrvZ80ROM1 + 0xe000, 0xff, 0x2000);
439
440 if (BurnLoadRom(DrvGfxROM0 + 0x00000, 7, 1)) return 1;
441 if (BurnLoadRom(DrvGfxROM0 + 0x04000, 8, 1)) return 1;
442 if (BurnLoadRom(DrvGfxROM0 + 0x08000, 9, 1)) return 1;
443 if (BurnLoadRom(DrvGfxROM0 + 0x0c000, 10, 1)) return 1;
444
445 if (BurnLoadRom(DrvGfxROM1 + 0x00000, 11, 1)) return 1;
446 if (BurnLoadRom(DrvGfxROM1 + 0x02000, 12, 1)) return 1;
447 if (BurnLoadRom(DrvGfxROM1 + 0x04000, 13, 1)) return 1;
448 if (BurnLoadRom(DrvGfxROM1 + 0x06000, 14, 1)) return 1;
449
450 if (BurnLoadRom(DrvMcuROM + 0x00000, 15, 1)) return 1;
451
452 DrvGfxDecode(DrvGfxROM0, 0x10000);
453 DrvGfxDecode(DrvGfxROM1, 0x08000);
454 }
455
456 ZetInit(0);
457 ZetOpen(0);
458 ZetMapMemory(DrvZ80ROM0, 0x0000, 0x7fff, MAP_ROM);
459 ZetMapMemory(DrvZ80RAM0, 0x8000, 0x8fff, MAP_RAM);
460 ZetMapMemory(DrvFgRAM, 0xc000, 0xc7ff, MAP_RAM);
461 ZetMapMemory(DrvBgRAM, 0xc800, 0xcfff, MAP_RAM);
462 ZetMapMemory(DrvSprRAM, 0xd500, 0xd5ff, MAP_RAM);
463 ZetMapMemory(DrvPalRAM, 0xd800, 0xdbff, MAP_ROM);
464 ZetSetWriteHandler(wyvernf0_main_write);
465 ZetSetReadHandler(wyvernf0_main_read);
466 ZetClose();
467
468 ZetInit(1);
469 ZetOpen(1);
470 ZetMapMemory(DrvZ80ROM1, 0x0000, 0x3fff, MAP_ROM);
471 ZetMapMemory(DrvZ80RAM1, 0xc000, 0xc7ff, MAP_RAM);
472 ZetMapMemory(DrvZ80ROM1 + 0xe000, 0xe000, 0xefff, MAP_ROM);
473 ZetSetWriteHandler(wyvernf0_sound_write);
474 ZetSetReadHandler(wyvernf0_sound_read);
475 ZetClose();
476
477 m67805_taito_init(DrvMcuROM, DrvMcuRAM, &standard_m68705_interface);
478
479 AY8910Init(0, 3000000, 0);
480 AY8910Init(1, 3000000, 1);
481 AY8910SetAllRoutes(0, 0.14, BURN_SND_ROUTE_BOTH);
482 AY8910SetAllRoutes(1, 0.14, BURN_SND_ROUTE_BOTH);
483
484 MSM5232Init(2000000, 1);
485 MSM5232SetCapacitors(0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6);
486 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_0);
487 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_1);
488 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_2);
489 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_3);
490 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_4);
491 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_5);
492 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_6);
493 MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_7);
494
495 GenericTilesInit();
496
497 DrvDoReset();
498
499 return 0;
500 }
501
DrvExit()502 static INT32 DrvExit()
503 {
504 GenericTilesExit();
505
506 ZetExit();
507
508 m67805_taito_exit();
509
510 AY8910Exit(0);
511 AY8910Exit(1);
512
513 MSM5232Exit();
514
515 BurnFree(AllMem);
516
517 return 0;
518 }
519
draw_layer(UINT8 * ram,INT32 color_offset,UINT8 scrollx,UINT8 scrolly)520 static void draw_layer(UINT8 *ram, INT32 color_offset, UINT8 scrollx, UINT8 scrolly)
521 {
522 for (INT32 offs = 0; offs < 32 * 32; offs++)
523 {
524 INT32 sx = (offs & 0x1f) * 8;
525 INT32 sy = (offs / 0x20) * 8;
526
527 sx -= scrollx;
528 if (sx < -7) sx += 256;
529 sy -= scrolly;
530 if (sy < -7) sy += 256;
531
532 if (sy >= 224) continue;
533
534 INT32 code = ((ram[offs * 2 + 1] & 0x03) << 8) + ram[offs * 2];
535
536 INT32 color = (code >> 12) & 0x07;
537 INT32 flipx = (code >> 15) & 0x01;
538 INT32 flipy = (code >> 14) & 0x01;
539
540 if (flipy) {
541 if (flipx) {
542 Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
543 } else {
544 Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
545 }
546 } else {
547 if (flipx) {
548 Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
549 } else {
550 Render8x8Tile_Mask_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
551 }
552 }
553 }
554 }
555
draw_sprites(INT32 is_foreground)556 static void draw_sprites(INT32 is_foreground)
557 {
558 UINT8 *RAM = DrvSprRAM + (is_foreground ? 0x80 : 0);
559
560 for (INT32 offs = 0; offs < 0x100 / 2; offs += 4)
561 {
562 INT32 sx = RAM[offs + 3] - ((RAM[offs + 2] & 0x80) << 1);
563 INT32 sy = 256 - 8 - RAM[offs + 0] - 23;
564
565 INT32 flipx = RAM[offs + 2] & 0x40;
566 INT32 flipy = RAM[offs + 1] & 0x80;
567
568 if (*flipscreen & 0x01)
569 {
570 flipx = !flipx;
571 sx = 256 - 8 - sx - 3 * 8;
572 }
573 if (*flipscreen & 0x02)
574 {
575 flipy = !flipy;
576 sy = 256 - 8 - sy - 3 * 8;
577 }
578
579 INT32 code = (RAM[offs + 1] & 0x7f) + (is_foreground ? 0x80 : 0);
580 INT32 color = (RAM[offs + 2] & 0x0f) + (is_foreground ? 0x10 : 0);
581
582 for (INT32 y = 0; y < 4; y++)
583 {
584 for (INT32 x = 0; x < 4; x++)
585 {
586 INT32 objoffs = code * 0x20 + (x + y * 4) * 2;
587
588 INT32 sxx = sx + (flipx ? 3-x : x) * 8;
589 INT32 syy = sy + (flipy ? 3-y : y) * 8;
590
591 INT32 code1 = ((DrvObjRAM[objoffs + 1] & 0x07) << 8) + DrvObjRAM[objoffs];
592
593 if (flipy) {
594 if (flipx) {
595 Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
596 } else {
597 Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
598 }
599 } else {
600 if (flipx) {
601 Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
602 } else {
603 Render8x8Tile_Mask_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
604 }
605 }
606 }
607 }
608 }
609 }
610
DrvDraw()611 static INT32 DrvDraw()
612 {
613 if (DrvRecalc) {
614 for (INT32 i = 0; i < 0x400; i+=2) {
615 palette_update(i);
616 }
617 DrvRecalc = 0;
618 }
619
620 BurnTransferClear();
621
622 draw_layer(DrvBgRAM, 0x00, scroll[2] - 0x12, scroll[3] + 0x10);
623 draw_sprites(0);
624 draw_sprites(1);
625 draw_layer(DrvFgRAM, 0x80, scroll[0] - 0x10, scroll[1] + 0x10);
626
627 BurnTransferCopy(DrvPalette);
628
629 return 0;
630 }
631
DrvFrame()632 static INT32 DrvFrame()
633 {
634 if (DrvReset) {
635 DrvDoReset();
636 }
637
638 {
639 memset (DrvInputs, 0, 5);
640
641 for (INT32 i = 0; i < 8; i++) {
642 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
643 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
644 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
645 DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
646 DrvInputs[4] ^= (DrvJoy5[i] & 1) << i;
647 }
648
649 DrvInputs[0] = (DrvInputs[0] & *coin_lockout);// | 0xc0;
650 }
651
652 INT32 nInterleave = 100;
653 INT32 nCyclesTotal[3] = { 6000000 / 60, 4000000 / 60, 4000000 / 60 };
654 INT32 nCyclesDone[3] = { 0, 0, 0 };
655
656 for (INT32 i = 0; i < nInterleave; i++)
657 {
658 ZetOpen(0);
659 CPU_RUN(0, Zet);
660 if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
661 ZetClose();
662
663 ZetOpen(1);
664 CPU_RUN(1, Zet);
665 if (i == (nInterleave - 1) || i == (nInterleave / 2) - 1) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
666 ZetClose();
667
668 m6805Open(0);
669 CPU_RUN(2, m6805);
670 m6805Close();
671 }
672
673 if (pBurnSoundOut) {
674 AY8910Render(pBurnSoundOut, nBurnSoundLen);
675 MSM5232Update(pBurnSoundOut, nBurnSoundLen);
676 }
677
678 if (pBurnDraw) {
679 DrvDraw();
680 }
681
682 return 0;
683 }
684
DrvScan(INT32 nAction,INT32 * pnMin)685 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
686 {
687 struct BurnArea ba;
688
689 if (pnMin) {
690 *pnMin = 0x029702;
691 }
692
693 if (nAction & ACB_VOLATILE) {
694 memset(&ba, 0, sizeof(ba));
695
696 ba.Data = AllRam;
697 ba.nLen = RamEnd - AllRam;
698 ba.szName = "All Ram";
699 BurnAcb(&ba);
700
701 ZetScan(nAction);
702 m68705_taito_scan(nAction);
703
704 AY8910Scan(nAction, pnMin);
705 MSM5232Scan(nAction, pnMin);
706 }
707
708 if (nAction & ACB_WRITE) {
709 ZetOpen(0);
710 rambankswitch(*DrvZ80RAMBank);
711 rombankswitch(*DrvZ80ROMBank);
712 ZetClose();
713 }
714
715 return 0;
716 }
717
718
719 // Wyvern F-0 (Rev 1)
720
721 static struct BurnRomInfo wyvernf0RomDesc[] = {
722 { "a39_01-1.ic37", 0x4000, 0xa94887ec, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
723 { "a39_02-1.ic36", 0x4000, 0x171cfdbe, 1 | BRF_PRG | BRF_ESS }, // 1
724 { "a39_03.ic35", 0x4000, 0x50314281, 1 | BRF_PRG | BRF_ESS }, // 2
725 { "a39_04.ic34", 0x4000, 0x7a225bf9, 1 | BRF_PRG | BRF_ESS }, // 3
726 { "a39_05.ic33", 0x4000, 0x41f21a67, 1 | BRF_PRG | BRF_ESS }, // 4
727 { "a39_06.ic32", 0x4000, 0xdeb2d850, 1 | BRF_PRG | BRF_ESS }, // 5
728
729 { "a39_16.ic26", 0x4000, 0x5a681fb4, 2 | BRF_PRG | BRF_ESS }, // 6 Z80 #0 Code
730
731 { "a39_11.ic99", 0x4000, 0xaf70e1dc, 3 | BRF_GRA }, // 7 Sprites
732 { "a39_10.ic78", 0x4000, 0xa84380fb, 3 | BRF_GRA }, // 8
733 { "a39_09.ic96", 0x4000, 0xc0cee243, 3 | BRF_GRA }, // 9
734 { "a39_08.ic75", 0x4000, 0x0ad69501, 3 | BRF_GRA }, // 10
735
736 { "a39_15.ic99", 0x2000, 0x90a66147, 4 | BRF_GRA }, // 11 Tiles
737 { "a39_14.ic73", 0x2000, 0xa31f3507, 4 | BRF_GRA }, // 12
738 { "a39_13.ic100", 0x2000, 0xbe708238, 4 | BRF_GRA }, // 13
739 { "a39_12.ic74", 0x2000, 0x1cc389de, 4 | BRF_GRA }, // 14
740
741 { "a39_mc68705p5s.ic23", 0x0800, 0x14bff574, 4 | BRF_ESS | BRF_PRG }, // 15 MCU Code
742 };
743
744 STD_ROM_PICK(wyvernf0)
745 STD_ROM_FN(wyvernf0)
746
747 struct BurnDriver BurnDrvWyvernf0 = {
748 "wyvernf0", NULL, NULL, NULL, "1985",
749 "Wyvern F-0 (Rev 1)\0", NULL, "Taito Corporation", "Miscellaneous",
750 NULL, NULL, NULL, NULL,
751 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_TAITO_MISC, GBF_VERSHOOT, 0,
752 NULL, wyvernf0RomInfo, wyvernf0RomName, NULL, NULL, NULL, NULL, Wyvernf0InputInfo, Wyvernf0DIPInfo,
753 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
754 224, 256, 3, 4
755 };
756
757
758 // Wyvern F-0
759 /* Possibly the first version or even an earlier development version as A39 06 above isn't labeled as A39 06-1 */
760
761 static struct BurnRomInfo wyvernf0aRomDesc[] = {
762 { "soft1_c2a0.ic37", 0x4000, 0x15f0beb8, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
763 { "soft2_7b60.ic36", 0x4000, 0x569a40c4, 1 | BRF_PRG | BRF_ESS }, // 1
764 { "ext1.ic35", 0x4000, 0x50314281, 1 | BRF_PRG | BRF_ESS }, // 2
765 { "ext2.ic34", 0x4000, 0x7a225bf9, 1 | BRF_PRG | BRF_ESS }, // 3
766 { "ext3.ic33", 0x4000, 0x41f21a67, 1 | BRF_PRG | BRF_ESS }, // 4
767 { "ext4_8ca8.ic32", 0x4000, 0x793e36de, 1 | BRF_PRG | BRF_ESS }, // 5
768
769 { "sound_4182.ic26", 0x4000, 0x5a681fb4, 2 | BRF_PRG | BRF_ESS }, // 6 Z80 #0 Code
770
771 { "obj4_d779.ic99", 0x4000, 0xaf70e1dc, 3 | BRF_GRA }, // 7 Sprites
772 { "obj3_5852.ic78", 0x4000, 0xa84380fb, 3 | BRF_GRA }, // 8
773 { "obj2_50fd.ic96", 0x4000, 0xc0cee243, 3 | BRF_GRA }, // 9
774 { "obj1_bd50.ic75", 0x4000, 0x0ad69501, 3 | BRF_GRA }, // 10
775
776 { "sch_4.ic99", 0x2000, 0x90a66147, 4 | BRF_GRA }, // 11 Tiles
777 { "sch_3.ic73", 0x2000, 0xa31f3507, 4 | BRF_GRA }, // 12
778 { "sch_2.ic100", 0x2000, 0xbe708238, 4 | BRF_GRA }, // 13
779 { "sch_1.ic74", 0x2000, 0x1cc389de, 4 | BRF_GRA }, // 14
780
781 { "a39_mc68705p5s.ic23", 0x0800, 0x14bff574, 4 | BRF_ESS | BRF_PRG }, // 15 MCU Code
782 };
783
784 STD_ROM_PICK(wyvernf0a)
785 STD_ROM_FN(wyvernf0a)
786
787 struct BurnDriver BurnDrvWyvernf0a = {
788 "wyvernf0a", "wyvernf0", NULL, NULL, "1985",
789 "Wyvern F-0\0", NULL, "Taito Corporation", "Miscellaneous",
790 NULL, NULL, NULL, NULL,
791 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_TAITO_MISC, GBF_VERSHOOT, 0,
792 NULL, wyvernf0aRomInfo, wyvernf0aRomName, NULL, NULL, NULL, NULL, Wyvernf0InputInfo, Wyvernf0DIPInfo,
793 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
794 224, 256, 3, 4
795 };
796