1 // FB Alpha Jackal driver module
2 // Based on MAME driver by Kenneth Lin
3
4 #include "tiles_generic.h"
5 #include "m6809_intf.h"
6 #include "burn_ym2151.h"
7
8 static UINT8 *AllMem;
9 static UINT8 *DrvM6809ROM0;
10 static UINT8 *DrvM6809ROM1;
11 static UINT8 *DrvGfxROM0;
12 static UINT8 *DrvGfxROM1;
13 static UINT8 *DrvGfxROM2;
14 static UINT8 *DrvColPROM;
15 static UINT8 *DrvPalRAM;
16 static UINT32 *DrvPaletteTab;
17 static UINT32 *DrvPalette;
18 static UINT8 DrvRecalc;
19 static UINT8 *AllRam;
20 static UINT8 *DrvShareRAM;
21 static UINT8 *DrvSprRAM;
22 static UINT8 *DrvZRAM;
23 static UINT8 *DrvVORAM;
24 static UINT8 *DrvVidControl;
25 static UINT8 *RamEnd;
26 static UINT8 *MemEnd;
27
28 static INT32 DrvZRAMBank;
29 static INT32 DrvVORAMBank;
30 static INT32 DrvSprRAMBank;
31 static INT32 DrvROMBank;
32 static INT32 DrvIRQEnable;
33 static INT32 flipscreen;
34
35 static UINT8 DrvJoy1[8];
36 static UINT8 DrvJoy2[8];
37 static UINT8 DrvJoy3[8];
38 static UINT8 DrvInputs[3];
39 static UINT8 DrvDips[3];
40 static UINT8 DrvReset;
41
42 static INT32 watchdog;
43 static INT32 layer_offset_x = 8;
44 static INT32 layer_offset_y = 16;
45
46 static INT32 bootleg = 0;
47
48 //static INT32 nRotate[2] = { 0, 0 };
49 //static UINT32 nRotateTime[2] = { 0, 0 };
50 //static UINT8 DrvFakeInput[4] = { 0, 0, 0, 0 };
51 // Rotation stuff! -dink
52 static UINT8 DrvFakeInput[6] = {0, 0, 0, 0, 0, 0};
53 static UINT8 nRotateHoldInput[2] = {0, 0};
54 static INT32 nRotate[2] = {0, 0};
55 static INT32 nRotateTarget[2] = {0, 0};
56 static INT32 nRotateTry[2] = {0, 0};
57 static UINT32 nRotateTime[2] = {0, 0};
58 static UINT8 game_rotates = 0;
59
60 static struct BurnInputInfo DrvInputList[] = {
61 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 0, "p1 coin" },
62 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 3, "p1 start" },
63 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 0, "p1 left" },
64 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 1, "p1 right" },
65 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up" },
66 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down" },
67 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
68 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
69
70 {"P2 Coin", BIT_DIGITAL, DrvJoy3 + 1, "p2 coin" },
71 {"P2 Start", BIT_DIGITAL, DrvJoy3 + 4, "p2 start" },
72 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 0, "p2 left" },
73 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 1, "p2 right" },
74 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up" },
75 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down" },
76 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" },
77 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" },
78
79 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
80 {"Service", BIT_DIGITAL, DrvJoy3 + 2, "service" },
81 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
82 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
83 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
84 };
85
86 STDINPUTINFO(Drv)
87
88 static struct BurnInputInfo DrvrotateInputList[] = {
89 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 0, "p1 coin" },
90 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 3, "p1 start" },
91 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 0, "p1 left" },
92 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 1, "p1 right" },
93 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up" },
94 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down" },
95 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
96 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
97 {"P1 Rotate Left", BIT_DIGITAL, DrvFakeInput + 0, "p1 rotate left" },
98 {"P1 Rotate Right", BIT_DIGITAL, DrvFakeInput + 1, "p1 rotate right" },
99 {"P1 Button 3 (rotate)" , BIT_DIGITAL , DrvFakeInput + 4, "p1 fire 3" },
100
101 {"P2 Coin", BIT_DIGITAL, DrvJoy3 + 1, "p2 coin" },
102 {"P2 Start", BIT_DIGITAL, DrvJoy3 + 4, "p2 start" },
103 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 0, "p2 left" },
104 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 1, "p2 right" },
105 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up" },
106 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down" },
107 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" },
108 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" },
109 {"P2 Rotate Left", BIT_DIGITAL, DrvFakeInput + 2, "p2 rotate left" },
110 {"P2 Rotate Right", BIT_DIGITAL, DrvFakeInput + 3, "p2 rotate right" },
111 {"P2 Button 3 (rotate)" , BIT_DIGITAL , DrvFakeInput + 5, "p2 fire 3" },
112
113 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
114 {"Service", BIT_DIGITAL, DrvJoy3 + 2, "service" },
115 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
116 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
117 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
118 };
119
120 STDINPUTINFO(Drvrotate)
121
122 static struct BurnDIPInfo DrvDIPList[]=
123 {
124 {0x12, 0xff, 0xff, 0xff, NULL },
125 {0x13, 0xff, 0xff, 0xff, NULL },
126 {0x14, 0xff, 0xff, 0x20, NULL },
127
128 {0 , 0xfe, 0 , 16, "Coin A" },
129 {0x12, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" },
130 {0x12, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" },
131 {0x12, 0x01, 0x0f, 0x06, "2 Coins 1 Credit" },
132 {0x12, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" },
133 {0x12, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" },
134 {0x12, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" },
135 {0x12, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" },
136 {0x12, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" },
137 {0x12, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" },
138 {0x12, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" },
139 {0x12, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" },
140 {0x12, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" },
141 {0x12, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" },
142 {0x12, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" },
143 {0x12, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" },
144 {0x12, 0x01, 0x0f, 0x00, "Free Play" },
145
146 {0 , 0xfe, 0 , 16, "Coin B" },
147 {0x12, 0x01, 0xf0, 0x20, "4 Coins 1 Credit" },
148 {0x12, 0x01, 0xf0, 0x50, "3 Coins 1 Credit" },
149 {0x12, 0x01, 0xf0, 0x60, "2 Coins 1 Credit" },
150 {0x12, 0x01, 0xf0, 0x40, "3 Coins 2 Credits" },
151 {0x12, 0x01, 0xf0, 0x10, "4 Coins 3 Credits" },
152 {0x12, 0x01, 0xf0, 0xf0, "1 Coin 1 Credit" },
153 {0x12, 0x01, 0xf0, 0x30, "3 Coins 4 Credits" },
154 {0x12, 0x01, 0xf0, 0x70, "2 Coins 3 Credits" },
155 {0x12, 0x01, 0xf0, 0xe0, "1 Coin 2 Credits" },
156 {0x12, 0x01, 0xf0, 0x60, "2 Coins 5 Credits" },
157 {0x12, 0x01, 0xf0, 0xd0, "1 Coin 3 Credits" },
158 {0x12, 0x01, 0xf0, 0xc0, "1 Coin 4 Credits" },
159 {0x12, 0x01, 0xf0, 0xb0, "1 Coin 5 Credits" },
160 {0x12, 0x01, 0xf0, 0xa0, "1 Coin 6 Credits" },
161 {0x12, 0x01, 0xf0, 0x90, "1 Coin 7 Credits" },
162 {0x12, 0x01, 0xf0, 0x00, "No Coin B" },
163
164 {0 , 0xfe, 0 , 4, "Lives" },
165 {0x13, 0x01, 0x03, 0x03, "2" },
166 {0x13, 0x01, 0x03, 0x02, "3" },
167 {0x13, 0x01, 0x03, 0x01, "4" },
168 {0x13, 0x01, 0x03, 0x00, "7" },
169
170 {0 , 0xfe, 0 , 4, "Bonus Life" },
171 {0x13, 0x01, 0x18, 0x18, "30k 150k" },
172 {0x13, 0x01, 0x18, 0x10, "50k 200k" },
173 {0x13, 0x01, 0x18, 0x08, "30k" },
174 {0x13, 0x01, 0x18, 0x00, "50k" },
175
176 {0 , 0xfe, 0 , 4, "Difficulty" },
177 {0x13, 0x01, 0x60, 0x60, "Easy" },
178 {0x13, 0x01, 0x60, 0x40, "Normal" },
179 {0x13, 0x01, 0x60, 0x20, "Difficult" },
180 {0x13, 0x01, 0x60, 0x00, "Very Difficult" },
181
182 {0 , 0xfe, 0 , 2, "Demo Sounds" },
183 {0x13, 0x01, 0x80, 0x80, "Off" },
184 {0x13, 0x01, 0x80, 0x00, "On" },
185
186 {0 , 0xfe, 0 , 2, "Flip Screen" },
187 {0x14, 0x01, 0x20, 0x20, "Off" },
188 {0x14, 0x01, 0x20, 0x00, "On" },
189
190 {0 , 0xfe, 0 , 2, "Sound Adjustment" },
191 {0x14, 0x01, 0x40, 0x00, "Upright" },
192 {0x14, 0x01, 0x40, 0x40, "Cocktail" },
193
194 {0 , 0xfe, 0 , 2, "Sound Mode" },
195 {0x14, 0x01, 0x80, 0x00, "Stereo" },
196 {0x14, 0x01, 0x80, 0x80, "Mono" },
197 };
198
199 STDDIPINFO(Drv)
200
201 static struct BurnDIPInfo DrvrotateDIPList[]=
202 {
203 {0x18, 0xff, 0xff, 0xff, NULL },
204 {0x19, 0xff, 0xff, 0xff, NULL },
205 {0x1a, 0xff, 0xff, 0x20, NULL },
206
207 {0 , 0xfe, 0 , 16, "Coin A" },
208 {0x18, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" },
209 {0x18, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" },
210 {0x18, 0x01, 0x0f, 0x06, "2 Coins 1 Credit" },
211 {0x18, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" },
212 {0x18, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" },
213 {0x18, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" },
214 {0x18, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" },
215 {0x18, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" },
216 {0x18, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" },
217 {0x18, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" },
218 {0x18, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" },
219 {0x18, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" },
220 {0x18, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" },
221 {0x18, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" },
222 {0x18, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" },
223 {0x18, 0x01, 0x0f, 0x00, "Free Play" },
224
225 {0 , 0xfe, 0 , 16, "Coin B" },
226 {0x18, 0x01, 0xf0, 0x20, "4 Coins 1 Credit" },
227 {0x18, 0x01, 0xf0, 0x50, "3 Coins 1 Credit" },
228 {0x18, 0x01, 0xf0, 0x60, "2 Coins 1 Credit" },
229 {0x18, 0x01, 0xf0, 0x40, "3 Coins 2 Credits" },
230 {0x18, 0x01, 0xf0, 0x10, "4 Coins 3 Credits" },
231 {0x18, 0x01, 0xf0, 0xf0, "1 Coin 1 Credit" },
232 {0x18, 0x01, 0xf0, 0x30, "3 Coins 4 Credits" },
233 {0x18, 0x01, 0xf0, 0x70, "2 Coins 3 Credits" },
234 {0x18, 0x01, 0xf0, 0xe0, "1 Coin 2 Credits" },
235 {0x18, 0x01, 0xf0, 0x60, "2 Coins 5 Credits" },
236 {0x18, 0x01, 0xf0, 0xd0, "1 Coin 3 Credits" },
237 {0x18, 0x01, 0xf0, 0xc0, "1 Coin 4 Credits" },
238 {0x18, 0x01, 0xf0, 0xb0, "1 Coin 5 Credits" },
239 {0x18, 0x01, 0xf0, 0xa0, "1 Coin 6 Credits" },
240 {0x18, 0x01, 0xf0, 0x90, "1 Coin 7 Credits" },
241 {0x18, 0x01, 0xf0, 0x00, "No Coin B" },
242
243 {0 , 0xfe, 0 , 4, "Lives" },
244 {0x19, 0x01, 0x03, 0x03, "2" },
245 {0x19, 0x01, 0x03, 0x02, "3" },
246 {0x19, 0x01, 0x03, 0x01, "4" },
247 {0x19, 0x01, 0x03, 0x00, "7" },
248
249 {0 , 0xfe, 0 , 4, "Bonus Life" },
250 {0x19, 0x01, 0x18, 0x18, "30k 150k" },
251 {0x19, 0x01, 0x18, 0x10, "50k 200k" },
252 {0x19, 0x01, 0x18, 0x08, "30k" },
253 {0x19, 0x01, 0x18, 0x00, "50k" },
254
255 {0 , 0xfe, 0 , 4, "Difficulty" },
256 {0x19, 0x01, 0x60, 0x60, "Easy" },
257 {0x19, 0x01, 0x60, 0x40, "Normal" },
258 {0x19, 0x01, 0x60, 0x20, "Difficult" },
259 {0x19, 0x01, 0x60, 0x00, "Very Difficult" },
260
261 {0 , 0xfe, 0 , 2, "Demo Sounds" },
262 {0x19, 0x01, 0x80, 0x80, "Off" },
263 {0x19, 0x01, 0x80, 0x00, "On" },
264
265 {0 , 0xfe, 0 , 2, "Flip Screen" },
266 {0x1a, 0x01, 0x20, 0x20, "Off" },
267 {0x1a, 0x01, 0x20, 0x00, "On" },
268
269 {0 , 0xfe, 0 , 2, "Sound Adjustment" },
270 {0x1a, 0x01, 0x40, 0x00, "Upright" },
271 {0x1a, 0x01, 0x40, 0x40, "Cocktail" },
272
273 {0 , 0xfe, 0 , 2, "Sound Mode" },
274 {0x1a, 0x01, 0x80, 0x00, "Stereo" },
275 {0x1a, 0x01, 0x80, 0x80, "Mono" },
276 };
277
STDDIPINFO(Drvrotate)278 STDDIPINFO(Drvrotate)
279
280 // Rotation-handler code
281
282 static void RotateReset() {
283 for (INT32 playernum = 0; playernum < 2; playernum++) {
284 nRotate[playernum] = 0; // start out pointing straight up (0=up)
285 nRotateTarget[playernum] = -1;
286 nRotateTime[playernum] = 0;
287 nRotateHoldInput[0] = nRotateHoldInput[1] = 0;
288 }
289 }
290
RotationTimer(void)291 static UINT32 RotationTimer(void) {
292 return nCurrentFrame;
293 }
294
RotateRight(INT32 * v)295 static void RotateRight(INT32 *v) {
296 (*v)++;
297 if (*v > 7) *v = 0;
298 }
299
RotateLeft(INT32 * v)300 static void RotateLeft(INT32 *v) {
301 (*v)--;
302 if (*v < 0) *v = 7;
303 }
304
Joy2Rotate(UINT8 * joy)305 static UINT8 Joy2Rotate(UINT8 *joy) { // ugly code, but the effect is awesome. -dink
306 if (joy[2] && joy[0]) return 7; // up left
307 if (joy[2] && joy[1]) return 1; // up right
308
309 if (joy[3] && joy[0]) return 5; // down left
310 if (joy[3] && joy[1]) return 3; // down right
311
312 if (joy[2]) return 0; // up
313 if (joy[3]) return 4; // down
314 if (joy[0]) return 6; // left
315 if (joy[1]) return 2; // right
316
317 return 0xff;
318 }
319
dialRotation(INT32 playernum)320 static int dialRotation(INT32 playernum) {
321 // p1 = 0, p2 = 1
322 UINT8 player[2] = { 0, 0 };
323 static UINT8 lastplayer[2][2] = { { 0, 0 }, { 0, 0 } };
324
325 if ((playernum != 0) && (playernum != 1)) {
326 bprintf(PRINT_NORMAL, _T("Strange Rotation address => %06X\n"), playernum);
327 return 0;
328 }
329 if (playernum == 0) {
330 player[0] = DrvFakeInput[0]; player[1] = DrvFakeInput[1];
331 }
332 if (playernum == 1) {
333 player[0] = DrvFakeInput[2]; player[1] = DrvFakeInput[3];
334 }
335
336 if (player[0] && (player[0] != lastplayer[playernum][0] || (RotationTimer() > nRotateTime[playernum]+0xf))) {
337 RotateLeft(&nRotate[playernum]);
338 //bprintf(PRINT_NORMAL, _T("Player %d Rotate Left => %06X\n"), playernum+1, nRotate[playernum]);
339 nRotateTime[playernum] = RotationTimer();
340 nRotateTarget[playernum] = -1;
341 }
342
343 if (player[1] && (player[1] != lastplayer[playernum][1] || (RotationTimer() > nRotateTime[playernum]+0xf))) {
344 RotateRight(&nRotate[playernum]);
345 //bprintf(PRINT_NORMAL, _T("Player %d Rotate Right => %06X\n"), playernum+1, nRotate[playernum]);
346 nRotateTime[playernum] = RotationTimer();
347 nRotateTarget[playernum] = -1;
348 }
349
350 lastplayer[playernum][0] = player[0];
351 lastplayer[playernum][1] = player[1];
352
353 return ~(1 << nRotate[playernum]);
354 }
355
356 static UINT8 *rotate_gunpos[2] = {NULL, NULL};
357 static UINT8 rotate_gunpos_multiplier = 1;
358
359 // Gun-rotation memory locations - do not remove this tag. - dink :)
360 // game p1 p2 clockwise value in memory multiplier
361 // jackal 0xbd8 0xc00 0 1 2 3 4 5 6 7 1
362 // topgunbl SAME
363
RotateSetGunPosRAM(UINT8 * p1,UINT8 * p2,UINT8 multiplier)364 static void RotateSetGunPosRAM(UINT8 *p1, UINT8 *p2, UINT8 multiplier) {
365 rotate_gunpos[0] = p1;
366 rotate_gunpos[1] = p2;
367 rotate_gunpos_multiplier = multiplier;
368 }
369
get_distance(INT32 from,INT32 to)370 static INT32 get_distance(INT32 from, INT32 to) {
371 // this function finds the easiest way to get from "from" to "to", wrapping at 0 and 7
372 INT32 countA = 0;
373 INT32 countB = 0;
374 INT32 fromtmp = from / rotate_gunpos_multiplier;
375 INT32 totmp = to / rotate_gunpos_multiplier;
376
377 while (1) {
378 fromtmp++;
379 countA++;
380 if(fromtmp>7) fromtmp = 0;
381 if(fromtmp == totmp || countA > 32) break;
382 }
383
384 fromtmp = from / rotate_gunpos_multiplier;
385 totmp = to / rotate_gunpos_multiplier;
386
387 while (1) {
388 fromtmp--;
389 countB++;
390 if(fromtmp<0) fromtmp = 7;
391 if(fromtmp == totmp || countB > 32) break;
392 }
393
394 if (countA > countB) {
395 return 1; // go negative
396 } else {
397 return 0; // go positive
398 }
399 }
400
RotateDoTick()401 static void RotateDoTick() {
402 // since the game only allows for 1 rotation every other frame, we have to
403 // do this.
404 if (nCurrentFrame&1) return;
405
406 for (INT32 i = 0; i < 2; i++) {
407 if (rotate_gunpos[i] && (nRotateTarget[i] != -1) && (nRotateTarget[i] != (*rotate_gunpos[i] & 0xff))) {
408 if (get_distance(nRotateTarget[i], *rotate_gunpos[i] & 0xff)) {
409 RotateRight(&nRotate[i]); // --
410 } else {
411 RotateLeft(&nRotate[i]); // ++
412 }
413 bprintf(0, _T("p%X target %X mempos %X nRotate %X.\n"), i, nRotateTarget[i], *rotate_gunpos[i] & 0xff, nRotate[i]);
414 nRotateTry[i]++;
415 if (nRotateTry[i] > 10) nRotateTarget[i] = -1; // don't get stuck in a loop if something goes horribly wrong here.
416 } else {
417 nRotateTarget[i] = -1;
418 }
419 }
420 }
421
SuperJoy2Rotate()422 static void SuperJoy2Rotate() {
423 for (INT32 i = 0; i < 2; i++) { // p1 = 0, p2 = 1
424 if (DrvFakeInput[4 + i]) { // rotate-button had been pressed
425 UINT8 rot = Joy2Rotate(((!i) ? &DrvJoy1[0] : &DrvJoy2[0]));
426 if (rot != 0xff) {
427 nRotateTarget[i] = rot * rotate_gunpos_multiplier;
428 }
429 //DrvInput[i] &= ~0xf; // cancel out directionals since they are used to rotate here.
430 DrvInputs[i] = (DrvInputs[i] & ~0xf) | (nRotateHoldInput[i] & 0xf); // for midnight resistance! be able to duck + change direction of gun.
431 nRotateTry[i] = 0;
432 } else { // cache joystick UDLR if the rotate button isn't pressed.
433 // This feature is for Midnight Resistance, if you are crawling on the
434 // ground and need to rotate your gun WITHOUT getting up.
435 nRotateHoldInput[i] = DrvInputs[i];
436 }
437 }
438
439 RotateDoTick();
440 }
441
442 // end Rotation-handler
443
bankswitch()444 static void bankswitch()
445 {
446 INT32 banks[3] = { DrvVORAMBank * 0x1000, DrvSprRAMBank * 0x1000, DrvROMBank * 0x8000 };
447
448 M6809MapMemory(DrvVORAM + banks[0], 0x2000, 0x2fff, MAP_RAM);
449 M6809MapMemory(DrvSprRAM + banks[1], 0x3000, 0x3fff, MAP_RAM);
450 M6809MapMemory(DrvM6809ROM0 + 0x10000 + banks[2], 0x4000, 0xbfff, MAP_ROM);
451 }
452
jackal_main_write(UINT16 address,UINT8 data)453 static void jackal_main_write(UINT16 address, UINT8 data)
454 {
455 if (address >= 0x0020 && address <= 0x005f) {
456 DrvZRAM[(address - 0x20) + DrvZRAMBank] = data;
457 return;
458 }
459
460 if (address >= 0x0060 && address <= 0x1fff) {
461 DrvShareRAM[address] = data;
462 return;
463 }
464
465 switch (address)
466 {
467 case 0x0000:
468 case 0x0001:
469 case 0x0002:
470 case 0x0003:
471 DrvVidControl[address] = data;
472 return;
473
474 case 0x0004:
475 flipscreen = data & 0x08;
476 DrvIRQEnable = data & 0x02;
477 return;
478
479 case 0x0019:
480 watchdog = 0;
481 return;
482
483 case 0x001c:
484 DrvSprRAMBank = (data & 0x08) >> 3;
485 DrvZRAMBank = (data & 0x10) << 2; // 0x40
486 DrvROMBank = (data & 0x20) >> 5;
487 DrvVORAMBank = (data & 0x10) >> 4;
488 bankswitch();
489 return;
490 }
491 }
492
jackal_main_read(UINT16 address)493 static UINT8 jackal_main_read(UINT16 address)
494 {
495 if (address >= 0x0020 && address <= 0x005f) {
496 return DrvZRAM[(address - 0x20) + DrvZRAMBank];
497 }
498
499 if (address >= 0x0060 && address <= 0x1fff) {
500 return DrvShareRAM[address];
501 }
502
503 switch (address)
504 {
505 case 0x0000: // actually read?
506 case 0x0001:
507 case 0x0002:
508 case 0x0003:
509 return DrvVidControl[address];
510
511 case 0x0010:
512 return DrvDips[0];
513
514 case 0x0011:
515 return DrvInputs[0];
516
517 case 0x0012:
518 return DrvInputs[1];
519
520 case 0x0013:
521 return (DrvInputs[2] & 0x1f) | (DrvDips[2] & 0xe0);
522
523 case 0x0014:
524 case 0x0015:
525 return dialRotation(address - 0x14); // rotary
526
527 case 0x0018:
528 return DrvDips[1];
529 }
530
531 return 0;
532 }
533
jackal_sub_write(UINT16 address,UINT8 data)534 static void jackal_sub_write(UINT16 address, UINT8 data)
535 {
536 switch (address)
537 {
538 case 0x2000:
539 BurnYM2151SelectRegister(data);
540 return;
541
542 case 0x2001:
543 BurnYM2151WriteRegister(data);
544 return;
545 }
546 }
547
jackal_sub_read(UINT16 address)548 static UINT8 jackal_sub_read(UINT16 address)
549 {
550 switch (address)
551 {
552 case 0x2000:
553 case 0x2001:
554 return BurnYM2151Read();
555 }
556
557 return 0;
558 }
559
DrvDoReset(INT32 clear_mem)560 static INT32 DrvDoReset(INT32 clear_mem)
561 {
562 if (clear_mem) {
563 memset (AllRam, 0, RamEnd - AllRam);
564 }
565
566 DrvZRAMBank = 0;
567 DrvVORAMBank = 0;
568 DrvSprRAMBank = 0;
569 DrvROMBank = 0;
570 DrvIRQEnable = 0;
571 flipscreen = 0;
572
573 M6809Open(0);
574 bankswitch();
575 M6809Reset();
576 M6809Close();
577
578 M6809Open(1);
579 M6809Reset();
580 M6809Close();
581
582 BurnYM2151Reset();
583
584 RotateReset();
585
586 watchdog = 0;
587
588 HiscoreReset();
589
590 return 0;
591 }
592
MemIndex()593 static INT32 MemIndex()
594 {
595 UINT8 *Next; Next = AllMem;
596
597 DrvM6809ROM0 = Next; Next += 0x020000;
598 DrvM6809ROM1 = Next; Next += 0x010000;
599
600 DrvGfxROM0 = Next; Next += 0x140000;
601 DrvGfxROM1 = Next; Next += 0x180000;
602 DrvGfxROM2 = Next; Next += 0x180000;
603
604 DrvColPROM = Next; Next += 0x000200;
605
606 DrvPaletteTab = (UINT32*)Next; Next += 0x0300 * sizeof(UINT32);
607 DrvPalette = (UINT32*)Next; Next += 0x0300 * sizeof(UINT32);
608
609 AllRam = Next;
610
611 DrvShareRAM = Next; Next += 0x002000;
612 DrvSprRAM = Next; Next += 0x004000;
613 DrvZRAM = Next; Next += 0x000080;
614 DrvVORAM = Next; Next += 0x002000;
615 DrvPalRAM = Next; Next += 0x000400;
616
617 DrvVidControl = Next; Next += 0x000004;
618
619 RamEnd = Next;
620
621 MemEnd = Next;
622
623 return 0;
624 }
625
DrvGfxDecode()626 static INT32 DrvGfxDecode()
627 {
628 INT32 Planes[8] = { STEP4(0,1), STEP4(0x40000*8, 1) };
629 INT32 XOffs[16] = { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4, 32*8+0*4, 32*8+1*4, 32*8+2*4, 32*8+3*4, 32*8+4*4, 32*8+5*4, 32*8+6*4, 32*8+7*4 };
630 //STEP8(0,4), STEP8(32*8, ??)
631 INT32 YOffs[16] = { STEP8(0,32), STEP8(16*32,32) };
632
633 UINT8 *tmp = (UINT8*)BurnMalloc(0x80000);
634 if (tmp == NULL) {
635 return 1;
636 }
637
638 memcpy (tmp, DrvGfxROM2, 0x80000);
639
640 GfxDecode(0x1000, 8, 8, 8, Planes, XOffs, YOffs, 0x100, tmp, DrvGfxROM0);
641
642 memcpy (tmp + 0x00000, tmp + 0x20000, 0x20000);
643 memcpy (tmp + 0x20000, tmp + 0x60000, 0x20000);
644
645 GfxDecode(0x0800, 4, 16, 16, Planes, XOffs, YOffs, 0x400, tmp, DrvGfxROM1);
646 GfxDecode(0x2000, 4, 8, 8, Planes, XOffs, YOffs, 0x100, tmp, DrvGfxROM2);
647
648 BurnFree(tmp);
649
650 return 0;
651 }
652
DrvPaletteInit()653 static void DrvPaletteInit()
654 {
655 for (INT32 i = 0; i < 0x100; i++) {
656 DrvPaletteTab[0x000 + i] = i + 0x100;
657 DrvPaletteTab[0x100 + i] = DrvColPROM[0x000 + i] & 0xf;
658 DrvPaletteTab[0x200 + i] = (DrvColPROM[0x100 + i] & 0xf) + 0x10;
659 }
660 }
661
DrvInit()662 static INT32 DrvInit()
663 {
664 AllMem = NULL;
665 MemIndex();
666 INT32 nLen = MemEnd - (UINT8 *)0;
667 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
668 memset(AllMem, 0, nLen);
669 MemIndex();
670
671 if (!bootleg) {
672 // Jackal
673 if (BurnLoadRom(DrvM6809ROM0 + 0x10000, 0, 1)) return 1;
674 if (BurnLoadRom(DrvM6809ROM0 + 0x0c000, 1, 1)) return 1;
675
676 if (BurnLoadRom(DrvM6809ROM1 + 0x08000, 2, 1)) return 1;
677
678 if (BurnLoadRom(DrvGfxROM2 + 0x00000, 3, 2)) return 1;
679 if (BurnLoadRom(DrvGfxROM2 + 0x00001, 4, 2)) return 1;
680 if (BurnLoadRom(DrvGfxROM2 + 0x40000, 5, 2)) return 1;
681 if (BurnLoadRom(DrvGfxROM2 + 0x40001, 6, 2)) return 1;
682
683 if (BurnLoadRom(DrvColPROM + 0x00000, 7, 1)) return 1;
684 if (BurnLoadRom(DrvColPROM + 0x00100, 8, 1)) return 1;
685 } else {
686 // Bootleg
687 if (BurnLoadRom(DrvM6809ROM0 + 0x10000, 0, 1)) return 1;
688 if (BurnLoadRom(DrvM6809ROM0 + 0x18000, 1, 1)) return 1;
689 if (BurnLoadRom(DrvM6809ROM0 + 0x0c000, 2, 1)) return 1;
690
691 if (BurnLoadRom(DrvM6809ROM1 + 0x08000, 3, 1)) return 1;
692
693 if (BurnLoadRom(DrvGfxROM2 + 0x00000, 4, 1)) return 1;
694 if (BurnLoadRom(DrvGfxROM2 + 0x08000, 5, 1)) return 1;
695 if (BurnLoadRom(DrvGfxROM2 + 0x10000, 6, 1)) return 1;
696 if (BurnLoadRom(DrvGfxROM2 + 0x18000, 7, 1)) return 1;
697 if (BurnLoadRom(DrvGfxROM2 + 0x20000, 8, 1)) return 1;
698 if (BurnLoadRom(DrvGfxROM2 + 0x28000, 9, 1)) return 1;
699 if (BurnLoadRom(DrvGfxROM2 + 0x30000, 10, 1)) return 1;
700 if (BurnLoadRom(DrvGfxROM2 + 0x38000, 11, 1)) return 1;
701 if (BurnLoadRom(DrvGfxROM2 + 0x40000, 12, 1)) return 1;
702 if (BurnLoadRom(DrvGfxROM2 + 0x48000, 13, 1)) return 1;
703 if (BurnLoadRom(DrvGfxROM2 + 0x50000, 14, 1)) return 1;
704 if (BurnLoadRom(DrvGfxROM2 + 0x58000, 15, 1)) return 1;
705 if (BurnLoadRom(DrvGfxROM2 + 0x60000, 16, 1)) return 1;
706 if (BurnLoadRom(DrvGfxROM2 + 0x68000, 17, 1)) return 1;
707 if (BurnLoadRom(DrvGfxROM2 + 0x70000, 18, 1)) return 1;
708 if (BurnLoadRom(DrvGfxROM2 + 0x78000, 19, 1)) return 1;
709
710 if (BurnLoadRom(DrvColPROM + 0x00000, 20, 1)) return 1;
711 if (BurnLoadRom(DrvColPROM + 0x00100, 21, 1)) return 1;
712 BurnByteswap(DrvGfxROM2, 0x80000);
713 }
714
715 DrvGfxDecode();
716 DrvPaletteInit();
717
718 M6809Init(0);
719 M6809Open(0);
720 M6809MapMemory(DrvShareRAM + 0x100, 0x0100, 0x1fff, MAP_RAM);
721 M6809MapMemory(DrvVORAM, 0x2000, 0x2fff, MAP_RAM);
722 M6809MapMemory(DrvSprRAM, 0x3000, 0x3fff, MAP_RAM);
723 M6809MapMemory(DrvM6809ROM0 + 0x0c000, 0xc000, 0xffff, MAP_ROM);
724 M6809SetWriteHandler(jackal_main_write);
725 M6809SetReadHandler(jackal_main_read);
726 M6809Close();
727
728 M6809Init(1);
729 M6809Open(1);
730 M6809MapMemory(DrvPalRAM, 0x4000, 0x43ff, MAP_RAM);
731 M6809MapMemory(DrvShareRAM, 0x6000, 0x7fff, MAP_RAM);
732 M6809MapMemory(DrvM6809ROM1 + 0x08000, 0x8000, 0xffff, MAP_ROM);
733 M6809SetWriteHandler(jackal_sub_write);
734 M6809SetReadHandler(jackal_sub_read);
735 M6809Close();
736
737 BurnYM2151Init(3580000);
738 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.50, BURN_SND_ROUTE_LEFT);
739 BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.50, BURN_SND_ROUTE_RIGHT);
740
741 GenericTilesInit();
742 if (game_rotates)
743 RotateSetGunPosRAM(DrvShareRAM + 0xbd8, DrvShareRAM + 0xc00, 1);
744 DrvDoReset(1);
745
746 return 0;
747 }
748
DrvExit()749 static INT32 DrvExit()
750 {
751 M6809Exit();
752
753 BurnYM2151Exit();
754
755 GenericTilesExit();
756
757 BurnFree(AllMem);
758
759 bootleg = 0;
760 game_rotates = 1;
761
762 return 0;
763 }
764
DrvPaletteUpdate()765 static void DrvPaletteUpdate()
766 {
767 UINT32 pens[0x200];
768
769 for (INT32 i = 0; i < 0x200; i++) {
770 if (i >= 0x20 && i < 0x100) continue; // not used, save cycles
771
772 UINT16 p = (DrvPalRAM[(i * 2)] | (DrvPalRAM[(i * 2) + 1] << 8));
773
774 UINT8 r = (p >> 0) & 0x1f;
775 UINT8 g = (p >> 5) & 0x1f;
776 UINT8 b = (p >> 10) & 0x1f;
777
778 r = (r << 3) | (r >> 2);
779 g = (g << 3) | (g >> 2);
780 b = (b << 3) | (b >> 2);
781
782 pens[i] = BurnHighCol(r,g,b,0);
783 }
784
785 for (INT32 i = 0; i < 0x300; i++) {
786 DrvPalette[i] = pens[DrvPaletteTab[i]];
787 }
788 }
789
draw_layer()790 static void draw_layer()
791 {
792 INT32 layer_control = DrvVidControl[2];
793
794 INT32 xscroll = DrvVidControl[1];
795 INT32 yscroll = DrvVidControl[0];
796
797 UINT8 *scrollram = DrvZRAM;
798
799 for (INT32 offs = 0; offs < 32 * 32; offs++)
800 {
801 INT32 attr = DrvVORAM[0x0000 + offs];
802 INT32 code = DrvVORAM[0x0400 + offs] + ((attr & 0xc0) << 2) + ((attr & 0x30) << 6);
803
804 INT32 flipx = attr & 0x10;
805 INT32 flipy = attr & 0x20;
806
807 INT32 sy = (((offs / 0x20) & 0x1f) * 8) - layer_offset_y;
808 INT32 sx = ((offs & 0x1f) * 8) - layer_offset_x;
809
810 if (layer_control & 0x02) {
811 if (layer_control & 0x08) {
812 sx -= scrollram[(sy + layer_offset_y)/8]; // maybe apply the offset here? I guess we'll know for sure after playtesting. -dink
813 sy -= yscroll;
814 }
815 else if (layer_control & 0x04) {
816 sy -= scrollram[(sx + layer_offset_x)/8]; // offset applied here fixes the konami logo on the titlescreen. -dink
817 sx -= xscroll;
818 }
819 } else {
820 sy -= yscroll;
821 sx -= xscroll;
822 }
823 if (sy < -7) sy += 256;
824 if (sx < -7) sx += 256;
825
826 if (flipy) {
827 if (flipx) {
828 Render8x8Tile_FlipXY_Clip(pTransDraw, code, sx, sy, 0, 8, 0, DrvGfxROM0);
829 } else {
830 Render8x8Tile_FlipY_Clip(pTransDraw, code, sx, sy, 0, 8, 0, DrvGfxROM0);
831 }
832 } else {
833 if (flipx) {
834 Render8x8Tile_FlipX_Clip(pTransDraw, code, sx, sy, 0, 8, 0, DrvGfxROM0);
835 } else {
836 Render8x8Tile_Clip(pTransDraw, code, sx, sy, 0, 8, 0, DrvGfxROM0);
837 }
838 }
839 }
840 }
841
draw_sprite(INT32 bank,INT32 code,INT32 color,INT32 sx,INT32 sy,INT32 flipx,INT32 flipy)842 static void draw_sprite(INT32 bank, INT32 code, INT32 color, INT32 sx, INT32 sy, INT32 flipx, INT32 flipy)
843 {
844 sx -= layer_offset_x;
845 sy -= layer_offset_y;
846 color += (bank & 2) ? 0x20 : 0x10;
847
848 if (bank & 8) // 8x8
849 {
850 if (flipy) {
851 if (flipx) {
852 Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM2);
853 } else {
854 Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM2);
855 }
856 } else {
857 if (flipx) {
858 Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM2);
859 } else {
860 Render8x8Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM2);
861 }
862 }
863 }
864 else // 16x16
865 {
866 if (flipy) {
867 if (flipx) {
868 Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM1);
869 } else {
870 Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM1);
871 }
872 } else {
873 if (flipx) {
874 Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM1);
875 } else {
876 Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, DrvGfxROM1);
877 }
878 }
879 }
880 }
881
draw_sprites(INT32 rambase,INT32 length,INT32 bank)882 static void draw_sprites(INT32 rambase, INT32 length, INT32 bank)
883 {
884 const UINT8 *sram = DrvSprRAM + rambase + ((DrvVidControl[3] & 0x08) ? 0x0800 : 0);
885
886 for (INT32 offs = 0; offs < length; offs += 5)
887 {
888 INT32 attr = sram[offs + 4];
889 INT32 sn1 = sram[offs];
890 INT32 sn2 = sram[offs + 1];
891 INT32 sy = sram[offs + 2];
892 INT32 sx = sram[offs + 3] - ((attr & 1) << 8);
893 INT32 flipx = attr & 0x20;
894 INT32 flipy = attr & 0x40;
895 INT32 color = sn2 >> 4;
896
897 if (sy > 0xf0) sy -= 256;
898
899 if (flipscreen)
900 {
901 sx = 240 - sx;
902 sy = 240 - sy;
903 flipx = !flipx;
904 flipy = !flipy;
905 }
906
907 if (attr & 0x0c)
908 {
909 INT32 spritenum = sn1 * 4 + ((sn2 & 0x0c) >> 2) + ((sn2 & 3) << 10) + ((bank & 2) << 11); // was << 12 -dink
910
911 INT32 mod = -8;
912
913 if (flipscreen)
914 {
915 sx += 8;
916 sy -= 8;
917 mod = 8;
918 }
919
920 if ((attr & 0x0c) == 0x0C) // 1x1
921 {
922 if (flipscreen) sy += 16;
923 draw_sprite(bank+8, spritenum, color, sx, sy, flipx, flipy);
924 }
925
926 if ((attr & 0x0c) == 0x08) // 1x2
927 {
928 sy += 8;
929 draw_sprite(bank+8, spritenum, color, sx, sy, flipx, flipy);
930 draw_sprite(bank+8, spritenum - 2, color, sx, sy + mod, flipx, flipy);
931 }
932
933 if ((attr & 0x0c) == 0x04) // 2x1
934 {
935 draw_sprite(bank+8, spritenum, color, sx, sy, flipx, flipy);
936 draw_sprite(bank+8, spritenum + 1, color, sx + mod, sy, flipx, flipy);
937 }
938 }
939 else
940 {
941 INT32 spritenum = sn1 + (((sn2 & 0x03) << 8) + ((bank & 2) << 9));
942
943 if (attr & 0x10) // 2x2
944 {
945 if (flipscreen)
946 {
947 sx -= 16;
948 sy -= 16;
949 }
950
951 draw_sprite(bank, spritenum, color, flipx ? sx+16 : sx, flipy ? sy+16 : sy, flipx, flipy);
952 draw_sprite(bank, spritenum + 1, color, flipx ? sx : sx+16, flipy ? sy+16 : sy, flipx, flipy);
953 draw_sprite(bank, spritenum + 2, color, flipx ? sx+16 : sx, flipy ? sy : sy+16, flipx, flipy);
954 draw_sprite(bank, spritenum + 3, color, flipx ? sx : sx+16, flipy ? sy : sy+16, flipx, flipy);
955 }
956 else // 1x1
957 {
958 draw_sprite(bank, spritenum, color, sx, sy, flipx, flipy);
959 }
960 }
961 }
962 }
963
DrvDraw()964 static INT32 DrvDraw()
965 {
966 //if (DrvRecalc) {
967 DrvPaletteUpdate();
968 DrvRecalc = 0;
969 //}
970 BurnTransferClear();
971 if (nBurnLayer & 2) draw_layer();
972
973 if (nBurnLayer & 4) draw_sprites(0x1000, 0x0f5, 2);
974 if (nBurnLayer & 8) draw_sprites(0x0000, 0x500, 0);
975
976 BurnTransferCopy(DrvPalette);
977
978 return 0;
979 }
980
DrvFrame()981 static INT32 DrvFrame()
982 {
983 watchdog++;
984 if (watchdog >= 180) {
985 DrvDoReset(0);
986 }
987
988 if (DrvReset) {
989 DrvDoReset(1);
990 }
991
992 {
993 memset (DrvInputs, 0xff, 3);
994 for (INT32 i = 0; i < 8; i++) {
995 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
996 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
997 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
998 }
999
1000 if (game_rotates) {
1001 SuperJoy2Rotate();
1002 }
1003 }
1004
1005 INT32 nInterleave = 100;
1006 INT32 nCyclesTotal[2] = { 1536000 / 60, ((1536000 * 12) / 10) / 60 };
1007 INT32 nSoundBufferPos = 0;
1008
1009 M6809NewFrame();
1010
1011 for (INT32 i = 0; i < nInterleave; i++)
1012 {
1013 M6809Open(0);
1014 M6809Run(nCyclesTotal[0] / nInterleave);
1015 if (i == (nInterleave - 1) && DrvIRQEnable)
1016 M6809SetIRQLine(0x00, CPU_IRQSTATUS_AUTO);
1017 M6809Close();
1018
1019 M6809Open(1);
1020 M6809Run(nCyclesTotal[1] / nInterleave);
1021 if (i == (nInterleave - 1) && DrvIRQEnable)
1022 M6809SetIRQLine(0x20, CPU_IRQSTATUS_AUTO); // nmi
1023 M6809Close();
1024
1025 if (pBurnSoundOut) {
1026 INT32 nSegmentLength = nBurnSoundLen / nInterleave;
1027 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
1028 BurnYM2151Render(pSoundBuf, nSegmentLength);
1029 nSoundBufferPos += nSegmentLength;
1030 }
1031 }
1032
1033 if (pBurnSoundOut) {
1034 INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
1035 if (nSegmentLength) {
1036 INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
1037 BurnYM2151Render(pSoundBuf, nSegmentLength);
1038 }
1039 }
1040
1041 if (pBurnDraw) {
1042 DrvDraw();
1043 }
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) {
1053 *pnMin = 0x029737;
1054 }
1055
1056 if (nAction & ACB_VOLATILE) {
1057 memset(&ba, 0, sizeof(ba));
1058 ba.Data = AllRam;
1059 ba.nLen = RamEnd - AllRam;
1060 ba.szName = "All Ram";
1061 BurnAcb(&ba);
1062
1063 M6809Scan(nAction);
1064
1065 BurnYM2151Scan(nAction, pnMin);
1066
1067 SCAN_VAR(DrvZRAMBank);
1068 SCAN_VAR(DrvVORAMBank);
1069 SCAN_VAR(DrvSprRAMBank);
1070 SCAN_VAR(DrvROMBank);
1071 SCAN_VAR(DrvIRQEnable);
1072 }
1073
1074 if (nAction & ACB_WRITE) {
1075 M6809Open(0);
1076 bankswitch();
1077 M6809Close();
1078 }
1079
1080 return 0;
1081 }
1082
1083 // Jackal (World, 8-way Joystick)
1084
1085 static struct BurnRomInfo jackalRomDesc[] = {
1086 { "631_v02.15d", 0x10000, 0x0b7e0584, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1087 { "631_v03.16d", 0x04000, 0x3e0dfb83, 0 | BRF_PRG | BRF_ESS }, // 1
1088
1089 { "631_t01.11d", 0x08000, 0xb189af6a, 1 | BRF_PRG | BRF_ESS }, // 2 - M6809 #1 Code
1090
1091 { "631t04.7h", 0x20000, 0x457f42f0, 2 | BRF_GRA }, // 3 - Graphics Tiles
1092 { "631t05.8h", 0x20000, 0x732b3fc1, 2 | BRF_GRA }, // 4
1093 { "631t06.12h", 0x20000, 0x2d10e56e, 2 | BRF_GRA }, // 5
1094 { "631t07.13h", 0x20000, 0x4961c397, 2 | BRF_GRA }, // 6
1095
1096 { "631r08.9h", 0x00100, 0x7553a172, 3 | BRF_GRA }, // 7 - Color PROMs
1097 { "631r09.14h", 0x00100, 0xa74dd86c, 3 | BRF_GRA }, // 8
1098 };
1099
1100 STD_ROM_PICK(jackal)
1101 STD_ROM_FN(jackal)
1102
1103 // Jackal (World, Rotary Joystick)
1104
1105 static struct BurnRomInfo jackalrRomDesc[] = {
1106 { "631_q02.15d", 0x10000, 0xed2a7d66, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1107 { "631_q03.16d", 0x04000, 0xb9d34836, 0 | BRF_PRG | BRF_ESS }, // 1
1108
1109 { "631_q01.11d", 0x08000, 0x54aa2d29, 1 | BRF_PRG | BRF_ESS }, // 2 - M6809 #1 Code
1110
1111 { "631t04.7h", 0x20000, 0x457f42f0, 2 | BRF_GRA }, // 3 - Graphics Tiles
1112 { "631t05.8h", 0x20000, 0x732b3fc1, 2 | BRF_GRA }, // 4
1113 { "631t06.12h", 0x20000, 0x2d10e56e, 2 | BRF_GRA }, // 5
1114 { "631t07.13h", 0x20000, 0x4961c397, 2 | BRF_GRA }, // 6
1115
1116 { "631r08.9h", 0x00100, 0x7553a172, 3 | BRF_GRA }, // 7 - Color PROMs
1117 { "631r09.14h", 0x00100, 0xa74dd86c, 3 | BRF_GRA }, // 7 - Color PROMs
1118 };
1119
1120 STD_ROM_PICK(jackalr)
1121 STD_ROM_FN(jackalr)
1122
1123 // Tokushu Butai Jackal (Japan, 8-way Joystick)
1124
1125 static struct BurnRomInfo jackaljRomDesc[] = {
1126 { "631_t02.15d", 0x10000, 0x14db6b1a, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1127 { "631_t03.16d", 0x04000, 0xfd5f9624, 0 | BRF_PRG | BRF_ESS }, // 1
1128
1129 { "631_t01.11d", 0x08000, 0xb189af6a, 1 | BRF_PRG | BRF_ESS }, // 2 - M6809 #1 Code
1130
1131 { "631t04.7h", 0x20000, 0x457f42f0, 2 | BRF_GRA }, // 3 - Graphics Tiles
1132 { "631t05.8h", 0x20000, 0x732b3fc1, 2 | BRF_GRA }, // 4
1133 { "631t06.12h", 0x20000, 0x2d10e56e, 2 | BRF_GRA }, // 5
1134 { "631t07.13h", 0x20000, 0x4961c397, 2 | BRF_GRA }, // 6
1135
1136 { "631r08.9h", 0x00100, 0x7553a172, 3 | BRF_GRA }, // 7 - Color PROMs
1137 { "631r09.14h", 0x00100, 0xa74dd86c, 3 | BRF_GRA }, // 8
1138 };
1139
1140 STD_ROM_PICK(jackalj)
1141 STD_ROM_FN(jackalj)
1142
1143 // Jackal (bootleg, Rotary Joystick)
1144 // This is based on jackalr. Was dumped from 2 different PCBs.
1145
1146 static struct BurnRomInfo jackalblRomDesc[] = {
1147 { "epr-a-3.bin", 0x8000, 0x5fffee27, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1148 { "epr-a-4.bin", 0x8000, 0x976c8431, 0 | BRF_PRG | BRF_ESS }, // 1
1149 { "epr-a-2.bin", 0x4000, 0xae2a290a, 0 | BRF_PRG | BRF_ESS }, // 2
1150
1151 { "epr-a-1.bin", 0x8000, 0x54aa2d29, 1 | BRF_PRG | BRF_ESS }, // 3 - M6809 #1 Code
1152
1153 { "epr-a-17.bin", 0x8000, 0xa96720b6, 2 | BRF_GRA }, // 4 - Graphics Tiles
1154 { "epr-a-18.bin", 0x8000, 0x932d0ecb, 2 | BRF_GRA }, // 5
1155 { "epr-a-19.bin", 0x8000, 0x1e3412e7, 2 | BRF_GRA }, // 6
1156 { "epr-a-20.bin", 0x8000, 0x4b0d15be, 2 | BRF_GRA }, // 7
1157 { "epr-a-6.bin", 0x8000, 0xec7141ad, 2 | BRF_GRA }, // 8
1158 { "epr-a-5.bin", 0x8000, 0xc6375c74, 2 | BRF_GRA }, // 9
1159 { "epr-a-7.bin", 0x8000, 0x03e1de04, 2 | BRF_GRA }, // 10
1160 { "epr-a-8.bin", 0x8000, 0xf946ada7, 2 | BRF_GRA }, // 11
1161 { "epr-a-13.bin", 0x8000, 0x7c29c59e, 2 | BRF_GRA }, // 12
1162 { "epr-a-14.bin", 0x8000, 0xf2bbff39, 2 | BRF_GRA }, // 13
1163 { "epr-a-15.bin", 0x8000, 0x594dbaaf, 2 | BRF_GRA }, // 14
1164 { "epr-a-16.bin", 0x8000, 0x069bf945, 2 | BRF_GRA }, // 15
1165 { "epr-a-9.bin", 0x8000, 0xc00cef79, 2 | BRF_GRA }, // 16
1166 { "epr-a-10.bin", 0x8000, 0x0aed6cd7, 2 | BRF_GRA }, // 17
1167 { "epr-a-11.bin", 0x8000, 0xa48e9f60, 2 | BRF_GRA }, // 18
1168 { "epr-a-12.bin", 0x8000, 0x79b7c71c, 2 | BRF_GRA }, // 19
1169
1170 { "n82s129n.prom2", 0x0100, 0x7553a172, 3 | BRF_GRA }, // 20 - Color PROMs
1171 { "n82s129n.prom1", 0x0100, 0xa74dd86c, 3 | BRF_GRA }, // 21
1172
1173 /* currently not used by the emulation */
1174 { "pal16r6cn.pal1", 0x0104, 0x9bba948f, 4 | BRF_OPT }, // 22 - Pals
1175 { "ampal16l8pc.pal2", 0x0104, 0x17c9de2f, 4 | BRF_OPT }, // 23
1176 { "ampal16r4pc.pal3", 0x0104, 0xe54cd288, 4 | BRF_OPT }, // 24
1177 { "pal16r8acn.pal4", 0x0104, 0x5cc45e00, 4 | BRF_OPT }, // 25
1178 { "pal20l8a-2cns.pal5", 0x0144, 0x00000000, 4 | BRF_OPT | BRF_NODUMP }, // 26
1179 { "pal20l8acns.pal6", 0x0144, 0x00000000, 4 | BRF_OPT | BRF_NODUMP }, // 27
1180 { "pal16l8pc.pal7", 0x0104, 0xe8cdc259, 4 | BRF_OPT }, // 28
1181 { "d5c121.ep1200", 0x0200, 0x00000000, 4 | BRF_OPT | BRF_NODUMP }, // 29
1182 };
1183
1184 STD_ROM_PICK(jackalbl)
1185 STD_ROM_FN(jackalbl)
1186
1187 // Top Gunner (US, 8-way Joystick)
1188
1189 static struct BurnRomInfo topgunrRomDesc[] = {
1190 { "631_u02.15d", 0x10000, 0xf7e28426, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1191 { "631_u03.16d", 0x04000, 0xc086844e, 0 | BRF_PRG | BRF_ESS }, // 1
1192
1193 { "631_t01.11d", 0x08000, 0xb189af6a, 1 | BRF_PRG | BRF_ESS }, // 2 - M6809 #1 Code
1194
1195 { "631u04.7h", 0x20000, 0x50122a12, 2 | BRF_GRA }, // 3 - Graphics Tiles
1196 { "631u05.8h", 0x20000, 0x6943b1a4, 2 | BRF_GRA }, // 4
1197 { "631u06.12h", 0x20000, 0x37dbbdb0, 2 | BRF_GRA }, // 5
1198 { "631u07.13h", 0x20000, 0x22effcc8, 2 | BRF_GRA }, // 6
1199
1200 { "631r08.9h", 0x00100, 0x7553a172, 3 | BRF_GRA }, // 7 - Color PROMs
1201 { "631r09.14h", 0x00100, 0xa74dd86c, 3 | BRF_GRA }, // 8
1202 };
1203
1204 STD_ROM_PICK(topgunr)
1205 STD_ROM_FN(topgunr)
1206
1207 // Top Gunner (bootleg, Rotary Joystick)
1208
1209 static struct BurnRomInfo topgunblRomDesc[] = {
1210 { "t-3.c5", 0x8000, 0x7826ad38, 0 | BRF_PRG | BRF_ESS }, // 0 - M6809 #0 Code
1211 { "t-4.c4", 0x8000, 0x976c8431, 0 | BRF_PRG | BRF_ESS }, // 1
1212 { "t-2.c6", 0x4000, 0xd53172e5, 0 | BRF_PRG | BRF_ESS }, // 2
1213
1214 { "t-1.c14", 0x8000, 0x54aa2d29, 1 | BRF_PRG | BRF_ESS }, // 3 - M6809 #1 Code
1215
1216 { "t-17.n12", 0x8000, 0xe8875110, 2 | BRF_GRA }, // 4 - Graphics Tiles
1217 { "t-18.n13", 0x8000, 0xcf14471d, 2 | BRF_GRA }, // 5
1218 { "t-19.n14", 0x8000, 0x46ee5dd2, 2 | BRF_GRA }, // 6
1219 { "t-20.n15", 0x8000, 0x3f472344, 2 | BRF_GRA }, // 7
1220 { "t-6.n1", 0x8000, 0x539cc48c, 2 | BRF_GRA }, // 8
1221 { "t-5.m1", 0x8000, 0xdbc26afe, 2 | BRF_GRA }, // 9
1222 { "t-7.n2", 0x8000, 0x0ecd31b1, 2 | BRF_GRA }, // 10
1223 { "t-8.n3", 0x8000, 0xf946ada7, 2 | BRF_GRA }, // 11
1224 { "t-13.n8", 0x8000, 0x5d669abb, 2 | BRF_GRA }, // 12
1225 { "t-14.n9", 0x8000, 0xf349369b, 2 | BRF_GRA }, // 13
1226 { "t-15.n10", 0x8000, 0x7c5a91dd, 2 | BRF_GRA }, // 14
1227 { "t-16.n11", 0x8000, 0x5ec46d8e, 2 | BRF_GRA }, // 15
1228 { "t-9.n4", 0x8000, 0x8269caca, 2 | BRF_GRA }, // 16
1229 { "t-10.n5", 0x8000, 0x25393e4f, 2 | BRF_GRA }, // 17
1230 { "t-11.n6", 0x8000, 0x7895c22d, 2 | BRF_GRA }, // 18
1231 { "t-12.n7", 0x8000, 0x15606dfc, 2 | BRF_GRA }, // 19
1232
1233 { "631r08.bpr", 0x0100, 0x7553a172, 3 | BRF_GRA }, // 20 - Color PROMs
1234 { "631r09.bpr", 0x0100, 0xa74dd86c, 3 | BRF_GRA }, // 21
1235 };
1236
1237 STD_ROM_PICK(topgunbl)
STD_ROM_FN(topgunbl)1238 STD_ROM_FN(topgunbl)
1239
1240 INT32 DrvInitbl()
1241 {
1242 bootleg = 1;
1243 game_rotates = 1;
1244
1245 return DrvInit();
1246 }
1247
DrvInitRo()1248 INT32 DrvInitRo()
1249 {
1250 game_rotates = 1;
1251
1252 return DrvInit();
1253 }
1254
1255 struct BurnDriver BurnDrvJackal = {
1256 "jackal", NULL, NULL, NULL, "1986",
1257 "Jackal (World, 8-way Joystick)\0", NULL, "Konami", "Miscellaneous",
1258 NULL, NULL, NULL, NULL,
1259 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1260 NULL, jackalRomInfo, jackalRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1261 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1262 224, 240, 3, 4
1263 };
1264
1265 struct BurnDriver BurnDrvJackalr = {
1266 "jackalr", "jackal", NULL, NULL, "1986",
1267 "Jackal (World, Rotary Joystick)\0", NULL, "Konami", "Miscellaneous",
1268 NULL, NULL, NULL, NULL,
1269 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1270 NULL, jackalrRomInfo, jackalrRomName, NULL, NULL, NULL, NULL, DrvrotateInputInfo, DrvrotateDIPInfo,
1271 DrvInitRo, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1272 224, 240, 3, 4
1273 };
1274
1275 struct BurnDriver BurnDrvJackalj = {
1276 "jackalj", "jackal", NULL, NULL, "1986",
1277 "Tokushu Butai Jackal (Japan, 8-way Joystick)\0", NULL, "Konami", "Miscellaneous",
1278 NULL, NULL, NULL, NULL,
1279 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1280 NULL, jackaljRomInfo, jackaljRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1281 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1282 224, 240, 3, 4
1283 };
1284
1285 struct BurnDriver BurnDrvJackalbl = {
1286 "jackalbl", "jackal", NULL, NULL, "1986",
1287 "Jackal (bootleg, Rotary Joystick)\0", NULL, "bootleg", "Miscellaneous",
1288 NULL, NULL, NULL, NULL,
1289 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1290 NULL, jackalblRomInfo, jackalblRomName, NULL, NULL, NULL, NULL, DrvrotateInputInfo, DrvrotateDIPInfo,
1291 DrvInitbl, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1292 224, 240, 3, 4
1293 };
1294
1295 struct BurnDriver BurnDrvTopgunr = {
1296 "topgunr", "jackal", NULL, NULL, "1986",
1297 "Top Gunner (US, 8-way Joystick)\0", NULL, "Konami", "Miscellaneous",
1298 NULL, NULL, NULL, NULL,
1299 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1300 NULL, topgunrRomInfo, topgunrRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
1301 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1302 224, 240, 3, 4
1303 };
1304
1305 struct BurnDriver BurnDrvTopgunbl = {
1306 "topgunbl", "jackal", NULL, NULL, "1986",
1307 "Top Gunner (bootleg, Rotary Joystick)\0", NULL, "bootleg", "Miscellaneous",
1308 NULL, NULL, NULL, NULL,
1309 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
1310 NULL, topgunblRomInfo, topgunblRomName, NULL, NULL, NULL, NULL, DrvrotateInputInfo, DrvrotateDIPInfo,
1311 DrvInitbl, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
1312 224, 240, 3, 4
1313 };
1314