1 // FB Alpha Renegade driver module
2 // Based on MAME driver by Phil Stroffolino, Carlos A. Lozano, Rob Rosenbrock
3
4 #include "tiles_generic.h"
5 #include "m6502_intf.h"
6 #include "m6805_intf.h"
7 #include "m6809_intf.h"
8 #include "burn_ym3526.h"
9 #include "msm5205.h"
10
11 static UINT8 DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0};
12 static UINT8 DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0};
13 static UINT8 DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0};
14 static UINT8 DrvDip[2] = {0, 0};
15 static UINT8 DrvInput[3] = {0x00, 0x00, 0x00};
16 static UINT8 DrvReset = 0;
17
18 static UINT8 *Mem = NULL;
19 static UINT8 *MemEnd = NULL;
20 static UINT8 *RamStart = NULL;
21 static UINT8 *RamEnd = NULL;
22 static UINT8 *DrvM6502Rom = NULL;
23 static UINT8 *DrvM6809Rom = NULL;
24 static UINT8 *DrvM68705Rom = NULL;
25 static UINT8 *DrvM68705Ram = NULL;
26 static UINT8 *DrvADPCMRom = NULL;
27 static UINT8 *DrvM6502Ram = NULL;
28 static UINT8 *DrvM6809Ram = NULL;
29 static UINT8 *DrvVideoRam1 = NULL;
30 static UINT8 *DrvVideoRam2 = NULL;
31 static UINT8 *DrvSpriteRam = NULL;
32 static UINT8 *DrvPaletteRam1 = NULL;
33 static UINT8 *DrvPaletteRam2 = NULL;
34 static UINT8 *DrvChars = NULL;
35 static UINT8 *DrvTiles = NULL;
36 static UINT8 *DrvSprites = NULL;
37 static UINT8 *DrvTempRom = NULL;
38 static UINT32 *DrvPalette = NULL;
39
40 static UINT8 DrvRomBank;
41 static UINT8 DrvVBlank;
42 static UINT8 DrvScrollX[2];
43 static UINT8 DrvSoundLatch;
44 static UINT8 DrvADPCMPlaying = 0;
45 static UINT32 DrvADPCMPos = 0;
46 static UINT32 DrvADPCMEnd = 0;
47
48 // MCU Simulation Variables
49 #define MCU_TYPE_NONE 0
50 #define MCU_TYPE_MCU 1
51
52 static INT32 DisableMCUEmulation = 0;
53
54 // MCU Emulation Variables
55 static INT32 MCUFromMain;
56 static INT32 MCUFromMcu;
57 static INT32 MCUMainSent;
58 static INT32 MCUMcuSent;
59 static UINT8 MCUDdrA;
60 static UINT8 MCUDdrB;
61 static UINT8 MCUDdrC;
62 static UINT8 MCUPortAOut;
63 static UINT8 MCUPortBOut;
64 static UINT8 MCUPortCOut;
65 static UINT8 MCUPortAIn;
66 static UINT8 MCUPortBIn;
67 static UINT8 MCUPortCIn;
68
69 static struct BurnInputInfo DrvInputList[] =
70 {
71 {"P1 Coin" , BIT_DIGITAL , DrvInputPort1 + 6, "p1 coin" },
72 {"P1 Start" , BIT_DIGITAL , DrvInputPort0 + 6, "p1 start" },
73 {"P1 Up" , BIT_DIGITAL , DrvInputPort0 + 2, "p1 up" },
74 {"P1 Down" , BIT_DIGITAL , DrvInputPort0 + 3, "p1 down" },
75 {"P1 Left" , BIT_DIGITAL , DrvInputPort0 + 1, "p1 left" },
76 {"P1 Right" , BIT_DIGITAL , DrvInputPort0 + 0, "p1 right" },
77 {"P1 Fire 1" , BIT_DIGITAL , DrvInputPort0 + 4, "p1 fire 1" },
78 {"P1 Fire 2" , BIT_DIGITAL , DrvInputPort0 + 5, "p1 fire 2" },
79 {"P1 Fire 3" , BIT_DIGITAL , DrvInputPort2 + 2, "p1 fire 3" },
80
81 {"P2 Coin" , BIT_DIGITAL , DrvInputPort1 + 7, "p2 coin" },
82 {"P2 Start" , BIT_DIGITAL , DrvInputPort0 + 7, "p2 start" },
83 {"P2 Up" , BIT_DIGITAL , DrvInputPort1 + 2, "p2 up" },
84 {"P2 Down" , BIT_DIGITAL , DrvInputPort1 + 3, "p2 down" },
85 {"P2 Left" , BIT_DIGITAL , DrvInputPort1 + 1, "p2 left" },
86 {"P2 Right" , BIT_DIGITAL , DrvInputPort1 + 0, "p2 right" },
87 {"P2 Fire 1" , BIT_DIGITAL , DrvInputPort1 + 4, "p2 fire 1" },
88 {"P2 Fire 2" , BIT_DIGITAL , DrvInputPort1 + 5, "p2 fire 2" },
89 {"P2 Fire 3" , BIT_DIGITAL , DrvInputPort2 + 3, "p2 fire 3" },
90
91 {"Reset" , BIT_DIGITAL , &DrvReset , "reset" },
92 {"Service" , BIT_DIGITAL , DrvInputPort2 + 7, "service" },
93 {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" },
94 {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" },
95 };
96
97
STDINPUTINFO(Drv)98 STDINPUTINFO(Drv)
99
100 static inline void DrvMakeInputs()
101 {
102 // Reset Inputs
103 DrvInput[0] = DrvInput[1] = 0xff;
104 DrvInput[2] = 0x9c;
105
106 // Compile Digital Inputs
107 for (INT32 i = 0; i < 8; i++) {
108 DrvInput[0] -= (DrvInputPort0[i] & 1) << i;
109 DrvInput[1] -= (DrvInputPort1[i] & 1) << i;
110 DrvInput[2] -= (DrvInputPort2[i] & 1) << i;
111 }
112 }
113
114 static struct BurnDIPInfo DrvDIPList[]=
115 {
116 // Default Values
117 {0x14, 0xff, 0xff, 0xbf, NULL },
118 {0x15, 0xff, 0xff, 0x03, NULL },
119
120 // Dip 1
121 {0 , 0xfe, 0 , 4 , "Coin A" },
122 {0x14, 0x01, 0x03, 0x00, "2 Coins 1 Play" },
123 {0x14, 0x01, 0x03, 0x03, "1 Coin 1 Play" },
124 {0x14, 0x01, 0x03, 0x02, "1 Coin 2 Plays" },
125 {0x14, 0x01, 0x03, 0x01, "1 Coin 3 Plays" },
126
127 {0 , 0xfe, 0 , 4 , "Coin B" },
128 {0x14, 0x01, 0x0c, 0x00, "2 Coins 1 Play" },
129 {0x14, 0x01, 0x0c, 0x0c, "1 Coin 1 Play" },
130 {0x14, 0x01, 0x0c, 0x08, "1 Coin 2 Plays" },
131 {0x14, 0x01, 0x0c, 0x04, "1 Coin 3 Plays" },
132
133 {0 , 0xfe, 0 , 2 , "Lives" },
134 {0x14, 0x01, 0x10, 0x10, "1" },
135 {0x14, 0x01, 0x10, 0x00, "2" },
136
137 {0 , 0xfe, 0 , 2 , "Bonus" },
138 {0x14, 0x01, 0x20, 0x20, "30k" },
139 {0x14, 0x01, 0x20, 0x00, "None" },
140
141 {0 , 0xfe, 0 , 2 , "Cabinet" },
142 {0x14, 0x01, 0x40, 0x00, "Upright" },
143 {0x14, 0x01, 0x40, 0x40, "Cocktail" },
144
145 {0 , 0xfe, 0 , 2 , "Flip Screen" },
146 {0x14, 0x01, 0x80, 0x80, "Off" },
147 {0x14, 0x01, 0x80, 0x00, "On" },
148
149 // Dip 2
150 {0 , 0xfe, 0 , 4 , "Difficulty" },
151 {0x15, 0x01, 0x03, 0x02, "Easy" },
152 {0x15, 0x01, 0x03, 0x03, "Normal" },
153 {0x15, 0x01, 0x03, 0x01, "Hard" },
154 {0x15, 0x01, 0x03, 0x00, "Very Hard" },
155 };
156
157 STDDIPINFO(Drv)
158
159 static struct BurnRomInfo DrvRomDesc[] = {
160 { "nb-5.ic51", 0x08000, 0xba683ddf, BRF_ESS | BRF_PRG }, // 0 M6502 Program Code
161 { "na-5.ic52", 0x08000, 0xde7e7df4, BRF_ESS | BRF_PRG }, // 1
162
163 { "n0-5.ic13", 0x08000, 0x3587de3b, BRF_ESS | BRF_PRG }, // 2 M6809 Program Code
164
165 { "nc-5.bin", 0x08000, 0x9adfaa5d, BRF_GRA }, // 3 Characters
166
167 { "n1-5.ic1", 0x08000, 0x4a9f47f3, BRF_GRA }, // 4 Tiles
168 { "n6-5.ic28", 0x08000, 0xd62a0aa8, BRF_GRA }, // 5
169 { "n7-5.ic27", 0x08000, 0x7ca5a532, BRF_GRA }, // 6
170 { "n2-5.ic14", 0x08000, 0x8d2e7982, BRF_GRA }, // 7
171 { "n8-5.ic26", 0x08000, 0x0dba31d3, BRF_GRA }, // 8
172 { "n9-5.ic25", 0x08000, 0x5b621b6a, BRF_GRA }, // 9
173
174 { "nh-5.bin", 0x08000, 0xdcd7857c, BRF_GRA }, // 10 Sprites
175 { "nd-5.bin", 0x08000, 0x2de1717c, BRF_GRA }, // 11
176 { "nj-5.bin", 0x08000, 0x0f96a18e, BRF_GRA }, // 12
177 { "nn-5.bin", 0x08000, 0x1bf15787, BRF_GRA }, // 13
178 { "ne-5.bin", 0x08000, 0x924c7388, BRF_GRA }, // 14
179 { "nk-5.bin", 0x08000, 0x69499a94, BRF_GRA }, // 15
180 { "ni-5.bin", 0x08000, 0x6f597ed2, BRF_GRA }, // 16
181 { "nf-5.bin", 0x08000, 0x0efc8d45, BRF_GRA }, // 17
182 { "nl-5.bin", 0x08000, 0x14778336, BRF_GRA }, // 18
183 { "no-5.bin", 0x08000, 0x147dd23b, BRF_GRA }, // 19
184 { "ng-5.bin", 0x08000, 0xa8ee3720, BRF_GRA }, // 20
185 { "nm-5.bin", 0x08000, 0xc100258e, BRF_GRA }, // 21
186
187 { "n3-5.ic33", 0x08000, 0x78fd6190, BRF_GRA }, // 22 ADPCM
188 { "n4-5.ic32", 0x08000, 0x6557564c, BRF_GRA }, // 23
189 { "n5-5.ic31", 0x08000, 0x7ee43a3c, BRF_GRA }, // 24
190
191 { "nz-5.ic97", 0x00800, 0x32e47560, BRF_ESS | BRF_PRG }, // 25 MCU
192 };
193
194 STD_ROM_PICK(Drv)
195 STD_ROM_FN(Drv)
196
197 static struct BurnRomInfo DrvjRomDesc[] = {
198 { "nb-01.bin", 0x08000, 0x93fcfdf5, BRF_ESS | BRF_PRG }, // 0 M6502 Program Code
199 { "ta18-11.bin", 0x08000, 0xf240f5cd, BRF_ESS | BRF_PRG }, // 1
200
201 { "n0-5.bin", 0x08000, 0x3587de3b, BRF_ESS | BRF_PRG }, // 2 M6809 Program Code
202
203 { "ta18-25.bin", 0x08000, 0x9bd2bea3, BRF_GRA }, // 3 Characters
204
205 { "ta18-01.bin", 0x08000, 0xdaf15024, BRF_GRA }, // 4 Tiles
206 { "ta18-06.bin", 0x08000, 0x1f59a248, BRF_GRA }, // 5
207 { "n7-5.bin", 0x08000, 0x7ca5a532, BRF_GRA }, // 6
208 { "ta18-02.bin", 0x08000, 0x994c0021, BRF_GRA }, // 7
209 { "ta18-04.bin", 0x08000, 0x55b9e8aa, BRF_GRA }, // 8
210 { "ta18-03.bin", 0x08000, 0x0475c99a, BRF_GRA }, // 9
211
212 { "ta18-20.bin", 0x08000, 0xc7d54139, BRF_GRA }, // 10 Sprites
213 { "ta18-24.bin", 0x08000, 0x84677d45, BRF_GRA }, // 11
214 { "ta18-18.bin", 0x08000, 0x1c770853, BRF_GRA }, // 12
215 { "ta18-14.bin", 0x08000, 0xaf656017, BRF_GRA }, // 13
216 { "ta18-23.bin", 0x08000, 0x3fd19cf7, BRF_GRA }, // 14
217 { "ta18-17.bin", 0x08000, 0x74c64c6e, BRF_GRA }, // 15
218 { "ta18-19.bin", 0x08000, 0xc8795fd7, BRF_GRA }, // 16
219 { "ta18-22.bin", 0x08000, 0xdf3a2ff5, BRF_GRA }, // 17
220 { "ta18-16.bin", 0x08000, 0x7244bad0, BRF_GRA }, // 18
221 { "ta18-13.bin", 0x08000, 0xb6b14d46, BRF_GRA }, // 19
222 { "ta18-21.bin", 0x08000, 0xc95e009b, BRF_GRA }, // 20
223 { "ta18-15.bin", 0x08000, 0xa5d61d01, BRF_GRA }, // 21
224
225 { "ta18-09.bin", 0x08000, 0x07ed4705, BRF_GRA }, // 22 ADPCM
226 { "ta18-08.bin", 0x08000, 0xc9312613, BRF_GRA }, // 23
227 { "ta18-07.bin", 0x08000, 0x02e3f3ed, BRF_GRA }, // 24
228
229 { "nz-0.bin", 0x00800, 0x98a39880, BRF_ESS | BRF_PRG }, // 25 MCU
230 };
231
232 STD_ROM_PICK(Drvj)
233 STD_ROM_FN(Drvj)
234
235 static struct BurnRomInfo DrvbRomDesc[] = {
236 { "ta18-10.bin", 0x08000, 0xa90cf44a, BRF_ESS | BRF_PRG }, // 0 M6502 Program Code
237 { "ta18-11.bin", 0x08000, 0xf240f5cd, BRF_ESS | BRF_PRG }, // 1
238
239 { "n0-5.bin", 0x08000, 0x3587de3b, BRF_ESS | BRF_PRG }, // 2 M6809 Program Code
240
241 { "ta18-25.bin", 0x08000, 0x9bd2bea3, BRF_GRA }, // 3 Characters
242
243 { "ta18-01.bin", 0x08000, 0xdaf15024, BRF_GRA }, // 4 Tiles
244 { "ta18-06.bin", 0x08000, 0x1f59a248, BRF_GRA }, // 5
245 { "n7-5.bin", 0x08000, 0x7ca5a532, BRF_GRA }, // 6
246 { "ta18-02.bin", 0x08000, 0x994c0021, BRF_GRA }, // 7
247 { "ta18-04.bin", 0x08000, 0x55b9e8aa, BRF_GRA }, // 8
248 { "ta18-03.bin", 0x08000, 0x0475c99a, BRF_GRA }, // 9
249
250 { "ta18-20.bin", 0x08000, 0xc7d54139, BRF_GRA }, // 10 Sprites
251 { "ta18-24.bin", 0x08000, 0x84677d45, BRF_GRA }, // 11
252 { "ta18-18.bin", 0x08000, 0x1c770853, BRF_GRA }, // 12
253 { "ta18-14.bin", 0x08000, 0xaf656017, BRF_GRA }, // 13
254 { "ta18-23.bin", 0x08000, 0x3fd19cf7, BRF_GRA }, // 14
255 { "ta18-17.bin", 0x08000, 0x74c64c6e, BRF_GRA }, // 15
256 { "ta18-19.bin", 0x08000, 0xc8795fd7, BRF_GRA }, // 16
257 { "ta18-22.bin", 0x08000, 0xdf3a2ff5, BRF_GRA }, // 17
258 { "ta18-16.bin", 0x08000, 0x7244bad0, BRF_GRA }, // 18
259 { "ta18-13.bin", 0x08000, 0xb6b14d46, BRF_GRA }, // 19
260 { "ta18-21.bin", 0x08000, 0xc95e009b, BRF_GRA }, // 20
261 { "ta18-15.bin", 0x08000, 0xa5d61d01, BRF_GRA }, // 21
262
263 { "ta18-09.bin", 0x08000, 0x07ed4705, BRF_GRA }, // 22 ADPCM
264 { "ta18-08.bin", 0x08000, 0xc9312613, BRF_GRA }, // 23
265 { "ta18-07.bin", 0x08000, 0x02e3f3ed, BRF_GRA }, // 24
266 };
267
268 STD_ROM_PICK(Drvb)
STD_ROM_FN(Drvb)269 STD_ROM_FN(Drvb)
270
271 static INT32 MemIndex()
272 {
273 UINT8 *Next; Next = Mem;
274
275 DrvM6502Rom = Next; Next += 0x10000;
276 DrvM6809Rom = Next; Next += 0x08000;
277 DrvM68705Rom = Next; Next += 0x00800;
278 DrvADPCMRom = Next; Next += 0x18000;
279
280 RamStart = Next;
281
282 DrvM6502Ram = Next; Next += 0x01800;
283 DrvM6809Ram = Next; Next += 0x01000;
284 DrvM68705Ram = Next; Next += 0x00070;
285 DrvSpriteRam = Next; Next += 0x00800;
286 DrvVideoRam1 = Next; Next += 0x00800;
287 DrvVideoRam2 = Next; Next += 0x00800;
288 DrvPaletteRam1 = Next; Next += 0x00100;
289 DrvPaletteRam2 = Next; Next += 0x00100;
290
291 RamEnd = Next;
292
293 DrvChars = Next; Next += 0x0400 * 8 * 8;
294 DrvTiles = Next; Next += 0x0800 * 16 * 16;
295 DrvSprites = Next; Next += 0x1000 * 16 * 16;
296 DrvPalette = (UINT32*)Next; Next += 0x00100 * sizeof(UINT32);
297
298 MemEnd = Next;
299
300 return 0;
301 }
302
mcu_reset_r()303 static UINT8 mcu_reset_r()
304 {
305 m6805Open(0);
306 m68705Reset();
307 m6805Close();
308
309 return 0;
310 }
311
mcu_w(UINT8 data)312 static void mcu_w(UINT8 data)
313 {
314 MCUFromMain = data;
315 MCUMainSent = 1;
316 m6805Open(0);
317 m68705SetIrqLine(0, 1);
318 m6805Close();
319 }
320
mcu_r()321 static UINT8 mcu_r()
322 {
323 MCUMcuSent = 0;
324 return MCUFromMcu;
325 }
326
mcu_status_r()327 static UINT8 mcu_status_r()
328 {
329 UINT8 Res = 0;
330
331 if (DisableMCUEmulation) {
332 Res = 1;
333 } else {
334 if (!MCUMainSent)
335 Res |= 0x01;
336 if (!MCUMcuSent)
337 Res |= 0x02;
338 }
339
340 return Res;
341 }
342
DrvDoReset()343 static INT32 DrvDoReset()
344 {
345 M6502Open(0);
346 M6502Reset();
347 M6502Close();
348
349 M6809Open(0);
350 M6809Reset();
351 M6809Close();
352
353 if (!DisableMCUEmulation) {
354 m6805Open(0);
355 m68705Reset();
356 m6805Close();
357
358 MCUFromMain = 0;
359 MCUFromMcu = 0;
360 MCUMainSent = 0;
361 MCUMcuSent = 0;
362 MCUDdrA = 0;
363 MCUDdrB = 0;
364 MCUDdrC = 0;
365 MCUPortAOut = 0;
366 MCUPortBOut = 0;
367 MCUPortCOut = 0;
368 MCUPortAIn = 0;
369 MCUPortBIn = 0;
370 MCUPortCIn = 0;
371 }
372
373 BurnYM3526Reset();
374 MSM5205Reset();
375
376 DrvRomBank = 0;
377 DrvVBlank = 0;
378 memset(DrvScrollX, 0, 2);
379 DrvSoundLatch = 0;
380 DrvADPCMPlaying = 0;
381 DrvADPCMPos = 0;
382 DrvADPCMEnd = 0;
383
384 return 0;
385 }
386
RenegadeReadByte(UINT16 Address)387 static UINT8 RenegadeReadByte(UINT16 Address)
388 {
389 switch (Address) {
390 case 0x3800: {
391 return DrvInput[0];
392 }
393
394 case 0x3801: {
395 return DrvInput[1];
396 }
397
398 case 0x3802: {
399 UINT8 MCUStatus = mcu_status_r();
400 if (MCUStatus) MCUStatus = (MCUStatus - 1) * 0x10;
401 return DrvInput[2] + DrvDip[1] + (DrvVBlank ? 0x40 : 0) + MCUStatus;
402 }
403
404 case 0x3803: {
405 return DrvDip[0];
406 }
407
408 case 0x3804: {
409 if (!DisableMCUEmulation) {
410 return mcu_r();
411 }
412 return 0;
413 }
414
415 case 0x3805: {
416 if (!DisableMCUEmulation) {
417 return mcu_reset_r();
418 }
419 }
420
421 default: {
422 bprintf(PRINT_NORMAL, _T("M6502 Read Byte %04X\n"), Address);
423 }
424 }
425
426 return 0;
427 }
428
bankswitch(UINT8 Data)429 static void bankswitch(UINT8 Data)
430 {
431 DrvRomBank = Data & 1;
432 M6502MapMemory(DrvM6502Rom + 0x8000 + (DrvRomBank * 0x4000), 0x4000, 0x7fff, MAP_ROM);
433 }
434
RenegadeWriteByte(UINT16 Address,UINT8 Data)435 static void RenegadeWriteByte(UINT16 Address, UINT8 Data)
436 {
437 switch (Address) {
438 case 0x3800: {
439 DrvScrollX[0] = Data;
440 return;
441 }
442
443 case 0x3801: {
444 DrvScrollX[1] = Data;
445 return;
446 }
447
448 case 0x3802: {
449 DrvSoundLatch = Data;
450 M6809Open(0);
451 M6809SetIRQLine(M6809_IRQ_LINE, CPU_IRQSTATUS_AUTO);
452 M6809Close();
453 return;
454 }
455
456 case 0x3803: {
457 // flipscreen
458 return;
459 }
460
461 case 0x3804: {
462 if (!DisableMCUEmulation) mcu_w(Data);
463 return;
464 }
465
466 case 0x3805: {
467 bankswitch(Data);
468 return;
469 }
470
471 case 0x3806: {
472 // nop
473 return;
474 }
475
476 case 0x3807: {
477 // coin counter
478 return;
479 }
480
481 default: {
482 bprintf(PRINT_NORMAL, _T("M6502 Write Byte %04X, %02X\n"), Address, Data);
483 }
484 }
485 }
486
RenegadeM6809ReadByte(UINT16 Address)487 static UINT8 RenegadeM6809ReadByte(UINT16 Address)
488 {
489 switch (Address) {
490 case 0x1000: {
491 return DrvSoundLatch;
492 }
493
494 default: {
495 bprintf(PRINT_NORMAL, _T("M6809 Read Byte %04X\n"), Address);
496 }
497 }
498
499 return 0;
500 }
501
RenegadeM6809WriteByte(UINT16 Address,UINT8 Data)502 static void RenegadeM6809WriteByte(UINT16 Address, UINT8 Data)
503 {
504 switch (Address) {
505 case 0x1800: {
506 MSM5205ResetWrite(0, 0);
507 DrvADPCMPlaying = 1;
508 return;
509 }
510
511 case 0x2000: {
512 switch (Data & 0x1c) {
513 case 0x18: DrvADPCMPos = 0 * 0x8000 * 2; break;
514 case 0x14: DrvADPCMPos = 1 * 0x8000 * 2; break;
515 case 0x0c: DrvADPCMPos = 2 * 0x8000 * 2; break;
516 default: DrvADPCMPos = DrvADPCMEnd = 0; return;
517 }
518 DrvADPCMPos |= (Data & 0x03) * 0x2000 * 2;
519 DrvADPCMEnd = DrvADPCMPos + 0x2000 * 2;
520 return;
521 }
522
523 case 0x2800: {
524 BurnYM3526Write(0, Data);
525 return;
526 }
527
528 case 0x2801: {
529 BurnYM3526Write(1, Data);
530 return;
531 }
532
533 case 0x3000: {
534 MSM5205ResetWrite(0, 1);
535 DrvADPCMPlaying = 0;
536 return;
537 }
538
539 default: {
540 bprintf(PRINT_NORMAL, _T("M6809 Write Byte %04X, %02X\n"), Address, Data);
541 }
542 }
543 }
544
MCUReadByte(UINT16 address)545 static UINT8 MCUReadByte(UINT16 address)
546 {
547 switch (address & 0x7ff) {
548 case 0x000: {
549 return (MCUPortAOut & MCUDdrA) | (MCUPortAIn & ~MCUDdrA);
550 }
551
552 case 0x001: {
553 return (MCUPortBOut & MCUDdrB) | (MCUPortBIn & ~MCUDdrB);
554 }
555
556 case 0x002: {
557 MCUPortCIn = 0;
558 if (MCUMainSent) MCUPortCIn |= 0x01;
559 if (!MCUMcuSent) MCUPortCIn |= 0x02;
560
561 return (MCUPortCOut & MCUDdrC) | (MCUPortCIn & ~MCUDdrC);
562 }
563
564 default: {
565 bprintf(PRINT_NORMAL, _T("MCU Read %x\n"), address);
566 }
567 }
568
569 return 0;
570 }
571
MCUWriteByte(UINT16 address,UINT8 data)572 static void MCUWriteByte(UINT16 address, UINT8 data)
573 {
574 switch (address & 0x7ff) {
575 case 0x000: {
576 MCUPortAOut = data;
577 break;
578 }
579
580 case 0x001: {
581 if ((MCUDdrB & 0x02) && (~data & 0x02) && (MCUPortBOut & 0x02)) {
582 MCUPortAIn = MCUFromMain;
583
584 if (MCUMainSent) {
585 m68705SetIrqLine(0, 0);
586 MCUMainSent = 0;
587 }
588 }
589
590 if ((MCUDdrB & 0x04) && (data & 0x04) && (~MCUPortBOut & 0x04)) {
591 MCUFromMcu = MCUPortAOut;
592 MCUMcuSent = 1;
593 }
594
595 MCUPortBOut = data;
596 break;
597 }
598
599 case 0x002: {
600 MCUPortCOut = data;
601 break;
602 }
603
604 case 0x004: {
605 MCUDdrA = data;
606 break;
607 }
608
609 case 0x005: {
610 MCUDdrB = data;
611 break;
612 }
613
614 case 0x006: {
615 MCUDdrC = data;
616 break;
617 }
618
619 default: {
620 bprintf(PRINT_NORMAL, _T("MCU Write %x, %x\n"), address, data);
621 }
622 }
623 }
624
625 static INT32 CharPlaneOffsets[3] = { 2, 4, 6 };
626 static INT32 CharXOffsets[8] = { 1, 0, 65, 64, 129, 128, 193, 192 };
627 static INT32 CharYOffsets[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
628 static INT32 Tile1PlaneOffsets[3] = { 0x00004, 0x40000, 0x40004 };
629 static INT32 Tile2PlaneOffsets[3] = { 0x00000, 0x60000, 0x60004 };
630 static INT32 Tile3PlaneOffsets[3] = { 0x20004, 0x80000, 0x80004 };
631 static INT32 Tile4PlaneOffsets[3] = { 0x20000, 0xa0000, 0xa0004 };
632 static INT32 TileXOffsets[16] = { 3, 2, 1, 0, 131, 130, 129, 128, 259, 258, 257, 256, 387, 386, 385, 384 };
633 static INT32 TileYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 };
634
DrvFMIRQHandler(INT32,INT32 nStatus)635 static void DrvFMIRQHandler(INT32, INT32 nStatus)
636 {
637 M6809SetIRQLine(M6809_FIRQ_LINE, (nStatus) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
638 }
639
DrvSynchroniseStream(INT32 nSoundRate)640 static INT32 DrvSynchroniseStream(INT32 nSoundRate)
641 {
642 return (INT64)M6809TotalCycles() * nSoundRate / 1500000;
643 }
644
DrvMSM5205Int()645 static void DrvMSM5205Int()
646 {
647 if (!DrvADPCMPlaying) {
648 MSM5205ResetWrite(0, 1);
649 return;
650 }
651
652 if (DrvADPCMPos >= DrvADPCMEnd) {
653 MSM5205ResetWrite(0, 1);
654 DrvADPCMPlaying = false;
655 M6809SetIRQLine(0x20, CPU_IRQSTATUS_AUTO);
656 } else {
657 UINT8 const data = DrvADPCMRom[DrvADPCMPos / 2];
658 MSM5205DataWrite(0, (DrvADPCMPos & 1) ? data & 0xf : data >> 4);
659 DrvADPCMPos++;
660 }
661 }
662
DrvInit(INT32 nMcuType)663 static INT32 DrvInit(INT32 nMcuType)
664 {
665 INT32 nRet = 0, nLen;
666
667 Mem = NULL;
668 MemIndex();
669 nLen = MemEnd - (UINT8 *)0;
670 if ((Mem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
671 memset(Mem, 0, nLen);
672 MemIndex();
673
674 DrvTempRom = (UINT8 *)BurnMalloc(0x60000);
675
676 nRet = BurnLoadRom(DrvM6502Rom + 0x00000, 0, 1); if (nRet != 0) return 1;
677 nRet = BurnLoadRom(DrvM6502Rom + 0x08000, 1, 1); if (nRet != 0) return 1;
678
679 nRet = BurnLoadRom(DrvM6809Rom + 0x00000, 2, 1); if (nRet != 0) return 1;
680
681 nRet = BurnLoadRom(DrvTempRom, 3, 1); if (nRet != 0) return 1;
682 GfxDecode(0x400, 3, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x100, DrvTempRom, DrvChars);
683
684 memset(DrvTempRom, 0, 0x60000);
685 nRet = BurnLoadRom(DrvTempRom + 0x00000, 4, 1); if (nRet != 0) return 1;
686 nRet = BurnLoadRom(DrvTempRom + 0x08000, 5, 1); if (nRet != 0) return 1;
687 nRet = BurnLoadRom(DrvTempRom + 0x10000, 6, 1); if (nRet != 0) return 1;
688 nRet = BurnLoadRom(DrvTempRom + 0x18000, 7, 1); if (nRet != 0) return 1;
689 nRet = BurnLoadRom(DrvTempRom + 0x20000, 8, 1); if (nRet != 0) return 1;
690 nRet = BurnLoadRom(DrvTempRom + 0x28000, 9, 1); if (nRet != 0) return 1;
691 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvTiles + (0x000 * 16 * 16));
692 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvTiles + (0x100 * 16 * 16));
693 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvTiles + (0x200 * 16 * 16));
694 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvTiles + (0x300 * 16 * 16));
695 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvTiles + (0x400 * 16 * 16));
696 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvTiles + (0x500 * 16 * 16));
697 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvTiles + (0x600 * 16 * 16));
698 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvTiles + (0x700 * 16 * 16));
699
700 memset(DrvTempRom, 0, 0x60000);
701 nRet = BurnLoadRom(DrvTempRom + 0x00000, 10, 1); if (nRet != 0) return 1;
702 nRet = BurnLoadRom(DrvTempRom + 0x08000, 11, 1); if (nRet != 0) return 1;
703 nRet = BurnLoadRom(DrvTempRom + 0x10000, 12, 1); if (nRet != 0) return 1;
704 nRet = BurnLoadRom(DrvTempRom + 0x18000, 13, 1); if (nRet != 0) return 1;
705 nRet = BurnLoadRom(DrvTempRom + 0x20000, 14, 1); if (nRet != 0) return 1;
706 nRet = BurnLoadRom(DrvTempRom + 0x28000, 15, 1); if (nRet != 0) return 1;
707 nRet = BurnLoadRom(DrvTempRom + 0x30000, 16, 1); if (nRet != 0) return 1;
708 nRet = BurnLoadRom(DrvTempRom + 0x38000, 17, 1); if (nRet != 0) return 1;
709 nRet = BurnLoadRom(DrvTempRom + 0x40000, 18, 1); if (nRet != 0) return 1;
710 nRet = BurnLoadRom(DrvTempRom + 0x48000, 19, 1); if (nRet != 0) return 1;
711 nRet = BurnLoadRom(DrvTempRom + 0x50000, 20, 1); if (nRet != 0) return 1;
712 nRet = BurnLoadRom(DrvTempRom + 0x58000, 21, 1); if (nRet != 0) return 1;
713 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvSprites + (0x000 * 16 * 16));
714 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvSprites + (0x100 * 16 * 16));
715 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvSprites + (0x200 * 16 * 16));
716 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x00000, DrvSprites + (0x300 * 16 * 16));
717 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvSprites + (0x400 * 16 * 16));
718 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvSprites + (0x500 * 16 * 16));
719 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvSprites + (0x600 * 16 * 16));
720 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x18000, DrvSprites + (0x700 * 16 * 16));
721 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x30000, DrvSprites + (0x800 * 16 * 16));
722 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x30000, DrvSprites + (0x900 * 16 * 16));
723 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x30000, DrvSprites + (0xa00 * 16 * 16));
724 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x30000, DrvSprites + (0xb00 * 16 * 16));
725 GfxDecode(0x100, 3, 16, 16, Tile1PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x48000, DrvSprites + (0xc00 * 16 * 16));
726 GfxDecode(0x100, 3, 16, 16, Tile2PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x48000, DrvSprites + (0xd00 * 16 * 16));
727 GfxDecode(0x100, 3, 16, 16, Tile3PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x48000, DrvSprites + (0xe00 * 16 * 16));
728 GfxDecode(0x100, 3, 16, 16, Tile4PlaneOffsets, TileXOffsets, TileYOffsets, 0x200, DrvTempRom + 0x48000, DrvSprites + (0xf00 * 16 * 16));
729
730 nRet = BurnLoadRom(DrvADPCMRom + 0x00000, 22, 1); if (nRet != 0) return 1;
731 nRet = BurnLoadRom(DrvADPCMRom + 0x08000, 23, 1); if (nRet != 0) return 1;
732 nRet = BurnLoadRom(DrvADPCMRom + 0x10000, 24, 1); if (nRet != 0) return 1;
733
734 BurnFree(DrvTempRom);
735
736 M6502Init(0, TYPE_M6502);
737 M6502Open(0);
738 M6502MapMemory(DrvM6502Ram , 0x0000, 0x17ff, MAP_RAM);
739 M6502MapMemory(DrvVideoRam2 , 0x1800, 0x1fff, MAP_RAM);
740 M6502MapMemory(DrvSpriteRam , 0x2000, 0x27ff, MAP_RAM);
741 M6502MapMemory(DrvVideoRam1 , 0x2800, 0x2fff, MAP_RAM);
742 M6502MapMemory(DrvPaletteRam1 , 0x3000, 0x30ff, MAP_RAM);
743 M6502MapMemory(DrvPaletteRam2 , 0x3100, 0x31ff, MAP_RAM);
744 M6502MapMemory(DrvM6502Rom + 0x8000 , 0x4000, 0x7fff, MAP_ROM);
745 M6502MapMemory(DrvM6502Rom , 0x8000, 0xffff, MAP_ROM);
746 M6502SetReadHandler(RenegadeReadByte);
747 M6502SetWriteHandler(RenegadeWriteByte);
748 M6502Close();
749
750 M6809Init(0);
751 M6809Open(0);
752 M6809MapMemory(DrvM6809Ram , 0x0000, 0x0fff, MAP_RAM);
753 M6809MapMemory(DrvM6809Rom , 0x8000, 0xffff, MAP_ROM);
754 M6809SetReadHandler(RenegadeM6809ReadByte);
755 M6809SetWriteHandler(RenegadeM6809WriteByte);
756 M6809Close();
757
758 MSM5205Init(0, DrvSynchroniseStream, 12000000 / 32, DrvMSM5205Int, MSM5205_S48_4B, 1);
759 MSM5205SetRoute(0, 1.00, BURN_SND_ROUTE_BOTH);
760
761 if (nMcuType == MCU_TYPE_MCU) {
762 nRet = BurnLoadRom(DrvM68705Rom, 25, 1); if (nRet != 0) return 1;
763
764 m6805Init(1, 0x800);
765 m6805Open(0);
766 m6805MapMemory(DrvM68705Ram , 0x0010, 0x007f, MAP_RAM);
767 m6805MapMemory(DrvM68705Rom + 0x0080, 0x0080, 0x07ff, MAP_ROM);
768 m6805SetWriteHandler(MCUWriteByte);
769 m6805SetReadHandler(MCUReadByte);
770 m6805Close();
771 }
772
773 if (nMcuType == MCU_TYPE_NONE) {
774 DisableMCUEmulation = 1;
775 }
776
777 BurnYM3526Init(3000000, &DrvFMIRQHandler, &DrvSynchroniseStream, 0);
778 BurnTimerAttachYM3526(&M6809Config, 1500000);
779 BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
780
781 GenericTilesInit();
782
783 DrvDoReset();
784
785 return 0;
786 }
787
RenegadeInit()788 static INT32 RenegadeInit()
789 {
790 return DrvInit(MCU_TYPE_MCU);
791 }
792
KuniokunbInit()793 static INT32 KuniokunbInit()
794 {
795 return DrvInit(MCU_TYPE_NONE);
796 }
797
DrvExit()798 static INT32 DrvExit()
799 {
800 M6502Exit();
801 M6809Exit();
802 if (!DisableMCUEmulation) m6805Exit();
803
804 BurnYM3526Exit();
805 MSM5205Exit();
806
807 GenericTilesExit();
808
809 BurnFree(Mem);
810
811 DisableMCUEmulation = 0;
812
813 MCUFromMain = 0;
814 MCUFromMcu = 0;
815 MCUMainSent = 0;
816 MCUMcuSent = 0;
817 MCUDdrA = 0;
818 MCUDdrB = 0;
819 MCUDdrC = 0;
820 MCUPortAOut = 0;
821 MCUPortBOut = 0;
822 MCUPortCOut = 0;
823 MCUPortAIn = 0;
824 MCUPortBIn = 0;
825 MCUPortCIn = 0;
826
827 DrvRomBank = 0;
828 DrvVBlank = 0;
829 memset(DrvScrollX, 0, sizeof(DrvScrollX));
830 DrvSoundLatch = 0;
831 DrvADPCMPlaying = 0;
832 DrvADPCMPos = 0;
833 DrvADPCMEnd = 0;
834
835 return 0;
836 }
837
pal4bit(UINT8 bits)838 static inline UINT8 pal4bit(UINT8 bits)
839 {
840 bits &= 0x0f;
841 return (bits << 4) | bits;
842 }
843
CalcCol(UINT16 nColour)844 inline static UINT32 CalcCol(UINT16 nColour)
845 {
846 INT32 r, g, b;
847
848 r = pal4bit(nColour >> 0);
849 g = pal4bit(nColour >> 4);
850 b = pal4bit(nColour >> 8);
851
852 return BurnHighCol(r, g, b, 0);
853 }
854
DrvCalcPalette()855 static void DrvCalcPalette()
856 {
857 for (INT32 i = 0; i < 0x100; i++) {
858 INT32 Val = DrvPaletteRam1[i] + (DrvPaletteRam2[i] << 8);
859
860 DrvPalette[i] = CalcCol(Val);
861 }
862 }
863
DrvRenderBgLayer()864 static void DrvRenderBgLayer()
865 {
866 INT32 mx, my, Attr, Code, Colour, x, y, TileIndex = 0, xScroll;
867
868 xScroll = DrvScrollX[0] + (DrvScrollX[1] << 8);
869 xScroll &= 0x3ff;
870 xScroll -= 256;
871
872 for (my = 0; my < 16; my++) {
873 for (mx = 0; mx < 64; mx++) {
874 Attr = DrvVideoRam1[TileIndex + 0x400];
875 Code = DrvVideoRam1[TileIndex + 0x000];
876 Colour = Attr >> 5;
877
878 x = 16 * mx;
879 y = 16 * my;
880
881 x -= xScroll;
882 if (x < -16) x += 1024;
883
884 x -= 8;
885
886 if (x > 0 && x < 224 && y > 0 && y < 224) {
887 Render16x16Tile(pTransDraw, Code, x, y, Colour, 3, 192, DrvTiles + ((Attr & 0x07) * 0x100 * 16 * 16));
888 } else {
889 Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 3, 192, DrvTiles + ((Attr & 0x07) * 0x100 * 16 * 16));
890 }
891
892 TileIndex++;
893 }
894 }
895 }
896
DrvRenderSprites()897 static void DrvRenderSprites()
898 {
899 UINT8 *Source = DrvSpriteRam;
900 UINT8 *Finish = Source + 96 * 4;
901
902 while (Source < Finish) {
903 INT32 sy = 240 - Source[0];
904
905 if (sy >= 16) {
906 INT32 Attr = Source[1];
907 INT32 sx = Source[3];
908 INT32 Code = Source[2];
909 INT32 SpriteBank = Attr & 0xf;
910 INT32 Colour = (Attr >> 4) & 0x3;
911 INT32 xFlip = Attr & 0x40;
912
913 if (sx > 248) sx -= 256;
914
915 sx -= 8;
916
917 if (Attr & 0x80) {
918 Code &= ~1;
919 if (sx > 16 && sx < 224 && (sy + 16) > 0 && (sy + 16) < 224) {
920 if (xFlip) {
921 Render16x16Tile_Mask_FlipX(pTransDraw, Code + 1, sx, sy + 16, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
922 } else {
923 Render16x16Tile_Mask(pTransDraw, Code + 1, sx, sy + 16, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
924 }
925 } else {
926 if (xFlip) {
927 Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code + 1, sx, sy + 16, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
928 } else {
929 Render16x16Tile_Mask_Clip(pTransDraw, Code + 1, sx, sy + 16, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
930 }
931 }
932 } else {
933 sy += 16;
934 }
935
936 if (sx > 16 && sx < 224 && sy > 0 && sy < 224) {
937 if (xFlip) {
938 Render16x16Tile_Mask_FlipX(pTransDraw, Code, sx, sy, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
939 } else {
940 Render16x16Tile_Mask(pTransDraw, Code, sx, sy, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
941 }
942 } else {
943 if (xFlip) {
944 Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, sy, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
945 } else {
946 Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 3, 0, 128, DrvSprites + (SpriteBank * 0x100 * 16 * 16));
947 }
948 }
949 }
950 Source += 4;
951 }
952 }
953
DrvRenderCharLayer()954 static void DrvRenderCharLayer()
955 {
956 INT32 mx, my, Attr, Code, Colour, x, y, TileIndex = 0;
957
958 for (my = 0; my < 32; my++) {
959 for (mx = 0; mx < 32; mx++) {
960 Attr = DrvVideoRam2[TileIndex + 0x400];
961 Code = ((Attr & 3) << 8) + DrvVideoRam2[TileIndex + 0x000];
962 Colour = Attr >> 6;
963
964 x = 8 * mx;
965 y = 8 * my;
966
967 x -= 8;
968
969 if (x > 0 && x < 232 && y > 0 && y < 232) {
970 Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 3, 0, 0, DrvChars);
971 } else {
972 Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 3, 0, 0, DrvChars);
973 }
974
975 TileIndex++;
976 }
977 }
978 }
979
DrvDraw()980 static INT32 DrvDraw()
981 {
982 BurnTransferClear();
983 DrvCalcPalette();
984 DrvRenderBgLayer();
985 DrvRenderSprites();
986 DrvRenderCharLayer();
987 BurnTransferCopy(DrvPalette);
988
989 return 0;
990 }
991
DrvFrame()992 static INT32 DrvFrame()
993 {
994 INT32 nInterleave = MSM5205CalcInterleave(0, 12000000 / 8);
995
996 if (DrvReset) DrvDoReset();
997
998 DrvMakeInputs();
999
1000 INT32 nCyclesTotal[3] = { (12000000 / 8) / 60, (12000000 / 8) / 60, (12000000 / 4) / 60 };
1001 INT32 nCyclesDone[3] = { 0, 0, 0 };
1002 INT32 nCyclesSegment;
1003
1004 DrvVBlank = 0;
1005
1006 M6502NewFrame();
1007 M6809NewFrame();
1008
1009 for (INT32 i = 0; i < nInterleave; i++) {
1010 INT32 nCurrentCPU, nNext;
1011
1012 M6502Open(0);
1013 nCurrentCPU = 0;
1014 nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
1015 nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
1016 nCyclesDone[nCurrentCPU] += M6502Run(nCyclesSegment);
1017 if (i == ((nInterleave / 10) * 7)) DrvVBlank = 1;
1018 if (i == (nInterleave / 2)) M6502SetIRQLine(M6502_INPUT_LINE_NMI, CPU_IRQSTATUS_AUTO);
1019 if (i == ((nInterleave / 10) * 9)) M6502SetIRQLine(M6502_IRQ_LINE, CPU_IRQSTATUS_HOLD);
1020 M6502Close();
1021
1022 if (!DisableMCUEmulation) {
1023 m6805Open(0);
1024 nCurrentCPU = 2;
1025 nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
1026 nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
1027 nCyclesDone[nCurrentCPU] += m6805Run(nCyclesSegment);
1028 m6805Close();
1029 }
1030
1031 M6809Open(0);
1032 BurnTimerUpdateYM3526((i + 1) * (nCyclesTotal[1] / nInterleave));
1033 MSM5205Update();
1034 M6809Close();
1035 }
1036
1037 M6809Open(0);
1038 BurnTimerEndFrameYM3526(nCyclesTotal[1]);
1039 BurnYM3526Update(pBurnSoundOut, nBurnSoundLen);
1040 MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
1041 M6809Close();
1042
1043 if (pBurnDraw) DrvDraw();
1044
1045 return 0;
1046 }
1047
DrvScan(INT32 nAction,INT32 * pnMin)1048 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
1049 {
1050 struct BurnArea ba;
1051
1052 if (pnMin != NULL) { // Return minimum compatible version
1053 *pnMin = 0x029696;
1054 }
1055
1056 if (nAction & ACB_MEMORY_RAM) {
1057 memset(&ba, 0, sizeof(ba));
1058 ba.Data = RamStart;
1059 ba.nLen = RamEnd-RamStart;
1060 ba.szName = "All Ram";
1061 BurnAcb(&ba);
1062 }
1063
1064 if (nAction & ACB_DRIVER_DATA) {
1065 M6502Scan(nAction);
1066 m6805Scan(nAction);
1067 M6809Scan(nAction);
1068
1069 BurnYM3526Scan(nAction, pnMin);
1070 MSM5205Scan(nAction, pnMin);
1071
1072 SCAN_VAR(DrvRomBank);
1073 SCAN_VAR(DrvScrollX);
1074 SCAN_VAR(DrvSoundLatch);
1075 SCAN_VAR(DrvADPCMPlaying);
1076 SCAN_VAR(DrvADPCMPos);
1077 SCAN_VAR(DrvADPCMEnd);
1078 SCAN_VAR(MCUFromMain);
1079 SCAN_VAR(MCUFromMcu);
1080 SCAN_VAR(MCUMainSent);
1081 SCAN_VAR(MCUMcuSent);
1082 SCAN_VAR(MCUDdrA);
1083 SCAN_VAR(MCUDdrB);
1084 SCAN_VAR(MCUDdrC);
1085 SCAN_VAR(MCUPortAOut);
1086 SCAN_VAR(MCUPortBOut);
1087 SCAN_VAR(MCUPortCOut);
1088 SCAN_VAR(MCUPortAIn);
1089 SCAN_VAR(MCUPortBIn);
1090 SCAN_VAR(MCUPortCIn);
1091 }
1092
1093 if (nAction & ACB_WRITE) {
1094 M6502Open(0);
1095 bankswitch(DrvRomBank);
1096 M6502Close();
1097 }
1098
1099 return 0;
1100 }
1101
1102 struct BurnDriver BurnDrvRenegade = {
1103 "renegade", NULL, NULL, NULL, "1986",
1104 "Renegade (US)\0", NULL, "Technos (Taito America license)", "Miscellaneous",
1105 NULL, NULL, NULL, NULL,
1106 BDF_GAME_WORKING, 2, HARDWARE_TECHNOS, GBF_SCRFIGHT, 0,
1107 NULL, DrvRomInfo, DrvRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1108 RenegadeInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1109 NULL, 0x100, 240, 240, 4, 3
1110 };
1111
1112 struct BurnDriver BurnDrvKuniokun = {
1113 "kuniokun", "renegade", NULL, NULL, "1986",
1114 "Nekketsu Kouha Kunio-kun (Japan)\0", NULL, "Technos", "Miscellaneous",
1115 NULL, NULL, NULL, NULL,
1116 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_TECHNOS, GBF_SCRFIGHT, 0,
1117 NULL, DrvjRomInfo, DrvjRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1118 RenegadeInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1119 NULL, 0x100, 240, 240, 4, 3
1120 };
1121
1122 struct BurnDriver BurnDrvKuniokunb = {
1123 "kuniokunb", "renegade", NULL, NULL, "1986",
1124 "Nekketsu Kouha Kunio-kun (Japan bootleg)\0", NULL, "bootleg", "Miscellaneous",
1125 NULL, NULL, NULL, NULL,
1126 BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_TECHNOS, GBF_SCRFIGHT, 0,
1127 NULL, DrvbRomInfo, DrvbRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1128 KuniokunbInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
1129 NULL, 0x100, 240, 240, 4, 3
1130 };
1131