1 // FB Alpha "Universal System 16" hardware driver module
2 // Based on MAME driver by Angelo Salese
3
4 #include "tiles_generic.h"
5 #include "m6809_intf.h"
6 #include "m68000_intf.h"
7 #include "namco_snd.h"
8 #include "namcoio.h"
9
10 static UINT8 *AllMem;
11 static UINT8 *MemEnd;
12 static UINT8 *AllRam;
13 static UINT8 *RamEnd;
14 static UINT8 *DrvM6809ROM0;
15 static UINT8 *DrvM6809ROM1;
16 static UINT8 *Drv68KROM;
17 static UINT8 *DrvGfxROM0;
18 static UINT8 *DrvGfxROM1;
19 static UINT8 *DrvColPROM;
20 static UINT8 *DrvSndPROM;
21 static UINT8 *DrvFgRAM;
22 static UINT8 *DrvShareRAM;
23 static UINT8 *Drv68KRAM;
24 static UINT8 *DrvBgVRAM;
25
26 static UINT32 *DrvPalette;
27 static UINT8 DrvRecalc;
28
29 static UINT16 slave_in_reset;
30 static UINT16 sound_in_reset;
31 static UINT16 palette_bank;
32 static UINT16 master_irq_enable;
33 static UINT16 slave_irq_enable;
34 static UINT16 flipscreen;
35
36 static UINT16 address_xor = 0; // toypop = 0x800
37
38 static UINT8 DrvJoy1[8];
39 static UINT8 DrvJoy2[8];
40 static UINT8 DrvJoy3[8];
41 static UINT8 DrvJoy4[8];
42 static UINT8 DrvJoy5[8];
43 static UINT8 DrvJoy6[8];
44 static UINT8 DrvDips[4];
45 static UINT8 DrvInputs[7];
46 static UINT8 DrvReset;
47
48 static struct BurnInputInfo LiblrablInputList[] = {
49 {"P1 Coin", BIT_DIGITAL, DrvJoy6 + 0, "p1 coin" },
50 {"P1 Start", BIT_DIGITAL, DrvJoy5 + 2, "p1 start" },
51 {"P1 Left Up", BIT_DIGITAL, DrvJoy3 + 0, "p1 up" },
52 {"P1 Left Down", BIT_DIGITAL, DrvJoy3 + 2, "p1 down" },
53 {"P1 Left Left", BIT_DIGITAL, DrvJoy3 + 3, "p1 left" },
54 {"P1 Left Right", BIT_DIGITAL, DrvJoy3 + 1, "p1 right" },
55 {"P1 Right Up", BIT_DIGITAL, DrvJoy1 + 0, "p3 up" },
56 {"P1 Right Down", BIT_DIGITAL, DrvJoy1 + 2, "p3 down" },
57 {"P1 Right Left", BIT_DIGITAL, DrvJoy1 + 3, "p3 left" },
58 {"P1 Right Right", BIT_DIGITAL, DrvJoy1 + 1, "p3 right" },
59 {"P1 Button 1", BIT_DIGITAL, DrvJoy5 + 0, "p1 fire 1" },
60
61 {"P2 Coin", BIT_DIGITAL, DrvJoy6 + 1, "p2 coin" },
62 {"P2 Start", BIT_DIGITAL, DrvJoy5 + 3, "p2 start" },
63 {"P2 Left Up", BIT_DIGITAL, DrvJoy4 + 0, "p2 up" },
64 {"P2 Left Down", BIT_DIGITAL, DrvJoy4 + 2, "p2 down" },
65 {"P2 Left Left", BIT_DIGITAL, DrvJoy4 + 3, "p2 left" },
66 {"P2 Left Right", BIT_DIGITAL, DrvJoy4 + 1, "p2 right" },
67 {"P2 Right Up", BIT_DIGITAL, DrvJoy2 + 0, "p4 up" },
68 {"P2 Right Down", BIT_DIGITAL, DrvJoy2 + 2, "p4 down" },
69 {"P2 Right Left", BIT_DIGITAL, DrvJoy2 + 3, "p4 left" },
70 {"P2 Right Right", BIT_DIGITAL, DrvJoy2 + 1, "p4 right" },
71 {"P2 Button 1", BIT_DIGITAL, DrvJoy5 + 1, "p2 fire 1" },
72
73 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
74 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
75 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
76 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
77 };
78
79 STDINPUTINFO(Liblrabl)
80
81 static struct BurnInputInfo ToypopInputList[] = {
82 {"P1 Coin", BIT_DIGITAL, DrvJoy6 + 0, "p1 coin" },
83 {"P1 Start", BIT_DIGITAL, DrvJoy5 + 2, "p1 start" },
84 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
85 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 2, "p1 down" },
86 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 3, "p1 left" },
87 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 1, "p1 right" },
88 {"P1 Button 1", BIT_DIGITAL, DrvJoy5 + 0, "p1 fire 1" },
89
90 {"P2 Coin", BIT_DIGITAL, DrvJoy6 + 1, "p2 coin" },
91 {"P2 Start", BIT_DIGITAL, DrvJoy5 + 3, "p2 start" },
92 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up" },
93 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 2, "p2 down" },
94 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 3, "p2 left" },
95 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 1, "p2 right" },
96 {"P2 Button 1", BIT_DIGITAL, DrvJoy5 + 1, "p2 fire 1" },
97
98 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
99 {"Service", BIT_DIGITAL, DrvJoy6 + 3, "service" },
100 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
101 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
102 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
103 };
104
105 STDINPUTINFO(Toypop)
106
107 static struct BurnDIPInfo LiblrablDIPList[]=
108 {
109 {0x17, 0xff, 0xff, 0xff, NULL },
110 {0x18, 0xff, 0xff, 0xff, NULL },
111 {0x19, 0xff, 0xff, 0x0f, NULL },
112
113 {0 , 0xfe, 0 , 4, "Lives" },
114 {0x17, 0x01, 0x03, 0x02, "1" },
115 {0x17, 0x01, 0x03, 0x00, "2" },
116 {0x17, 0x01, 0x03, 0x03, "3" },
117 {0x17, 0x01, 0x03, 0x01, "5" },
118
119 {0 , 0xfe, 0 , 13, "Bonus Life" },
120 {0x17, 0x01, 0x1c, 0x1c, "40k 120k 200k 400k 600k 1m" },
121 {0x17, 0x01, 0x1c, 0x0c, "40k 140k 250k 400k 700k 1m" },
122 {0x17, 0x01, 0x1c, 0x14, "50k 150k 300k 500k 700k 1m" },
123 {0x17, 0x01, 0x1c, 0x04, "40k 120k and every 120k" },
124 {0x17, 0x01, 0x1c, 0x18, "40k 150k and every 150k" },
125 {0x17, 0x01, 0x1c, 0x08, "50k 150k 300k" },
126 {0x17, 0x01, 0x1c, 0x10, "40k 120k 200k" },
127 {0x17, 0x01, 0x1c, 0x14, "40k 120k" },
128 {0x17, 0x01, 0x1c, 0x04, "50k 150k" },
129 {0x17, 0x01, 0x1c, 0x18, "50k 150k and every 150k" },
130 {0x17, 0x01, 0x1c, 0x08, "60k 200k and every 200k" },
131 {0x17, 0x01, 0x1c, 0x10, "50k" },
132 {0x17, 0x01, 0x1c, 0x00, "None" },
133
134 {0 , 0xfe, 0 , 8, "Coin A" },
135 {0x17, 0x01, 0xe0, 0x80, "3 Coins 1 Credits" },
136 {0x17, 0x01, 0xe0, 0xc0, "2 Coins 1 Credits" },
137 {0x17, 0x01, 0xe0, 0x00, "3 Coins 2 Credits" },
138 {0x17, 0x01, 0xe0, 0xe0, "1 Coin 1 Credits" },
139 {0x17, 0x01, 0xe0, 0x40, "2 Coins 3 Credits" },
140 {0x17, 0x01, 0xe0, 0x60, "1 Coin 2 Credits" },
141 {0x17, 0x01, 0xe0, 0xa0, "1 Coin 3 Credits" },
142 {0x17, 0x01, 0xe0, 0x20, "1 Coin 6 Credits" },
143
144 {0 , 0xfe, 0 , 2, "Freeze" },
145 {0x18, 0x01, 0x01, 0x01, "Off" },
146 {0x18, 0x01, 0x01, 0x00, "On" },
147
148 {0 , 0xfe, 0 , 2, "Rack Test" },
149 {0x18, 0x01, 0x02, 0x02, "Off" },
150 {0x18, 0x01, 0x02, 0x00, "On" },
151
152 {0 , 0xfe, 0 , 2, "Demo Sounds" },
153 {0x18, 0x01, 0x04, 0x00, "Off" },
154 {0x18, 0x01, 0x04, 0x04, "On" },
155
156 {0 , 0xfe, 0 , 4, "Coin B" },
157 {0x18, 0x01, 0x18, 0x00, "2 Coins 1 Credits" },
158 {0x18, 0x01, 0x18, 0x18, "1 Coin 1 Credits" },
159 {0x18, 0x01, 0x18, 0x08, "1 Coin 5 Credits" },
160 {0x18, 0x01, 0x18, 0x10, "1 Coin 7 Credits" },
161
162 {0 , 0xfe, 0 , 2, "Practice" },
163 {0x18, 0x01, 0x20, 0x00, "Off" },
164 {0x18, 0x01, 0x20, 0x20, "On" },
165
166 {0 , 0xfe, 0 , 4, "Difficulty" },
167 {0x18, 0x01, 0xc0, 0xc0, "A" },
168 {0x18, 0x01, 0xc0, 0x40, "B" },
169 {0x18, 0x01, 0xc0, 0x80, "C" },
170 {0x18, 0x01, 0xc0, 0x00, "D" },
171
172 {0 , 0xfe, 0 , 2, "Cabinet" },
173 {0x19, 0x01, 0x04, 0x04, "Upright" },
174 {0x19, 0x01, 0x04, 0x00, "Cocktail" },
175
176 {0 , 0xfe, 0 , 2, "Service Mode" },
177 {0x19, 0x01, 0x08, 0x00, "On" },
178 {0x19, 0x01, 0x08, 0x08, "Off" },
179 };
180
181 STDDIPINFO(Liblrabl)
182
183 static struct BurnDIPInfo ToypopDIPList[]=
184 {
185 {0x10, 0xff, 0xff, 0xbf, NULL },
186 {0x11, 0xff, 0xff, 0xff, NULL },
187 {0x12, 0xff, 0xff, 0xff, NULL },
188
189 {0 , 0xfe, 0 , 4, "Lives" },
190 {0x10, 0x01, 0x03, 0x02, "1" },
191 {0x10, 0x01, 0x03, 0x01, "2" },
192 {0x10, 0x01, 0x03, 0x03, "3" },
193 {0x10, 0x01, 0x03, 0x00, "5" },
194
195 {0 , 0xfe, 0 , 4, "Coin B" },
196 {0x10, 0x01, 0x0c, 0x00, "3 Coins 1 Credits" },
197 {0x10, 0x01, 0x0c, 0x04, "2 Coins 1 Credits" },
198 {0x10, 0x01, 0x0c, 0x0c, "1 Coin 1 Credits" },
199 {0x10, 0x01, 0x0c, 0x08, "1 Coin 2 Credits" },
200
201 {0 , 0xfe, 0 , 4, "Coin A" },
202 {0x10, 0x01, 0x30, 0x00, "3 Coins 1 Credits" },
203 {0x10, 0x01, 0x30, 0x10, "2 Coins 1 Credits" },
204 {0x10, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
205 {0x10, 0x01, 0x30, 0x20, "1 Coin 2 Credits" },
206
207 {0 , 0xfe, 0 , 2, "Flip Screen" },
208 {0x10, 0x01, 0x40, 0x00, "Off" },
209 {0x10, 0x01, 0x40, 0x40, "On" },
210
211 {0 , 0xfe, 0 , 2, "Service Mode" },
212 {0x10, 0x01, 0x80, 0x00, "On" },
213 {0x10, 0x01, 0x80, 0x80, "Off" },
214
215 {0 , 0xfe, 0 , 2, "Freeze" },
216 {0x11, 0x01, 0x01, 0x01, "Off" },
217 {0x11, 0x01, 0x01, 0x00, "On" },
218
219 {0 , 0xfe, 0 , 2, "Level Select" },
220 {0x11, 0x01, 0x02, 0x02, "Off" },
221 {0x11, 0x01, 0x02, 0x00, "On" },
222
223 {0 , 0xfe, 0 , 2, "2 Players Game" },
224 {0x11, 0x01, 0x04, 0x00, "1 Credit" },
225 {0x11, 0x01, 0x04, 0x04, "2 Credits" },
226
227 {0 , 0xfe, 0 , 2, "Demo Sounds" },
228 {0x11, 0x01, 0x08, 0x00, "Off" },
229 {0x11, 0x01, 0x08, 0x08, "On" },
230
231 {0 , 0xfe, 0 , 2, "Entering" },
232 {0x11, 0x01, 0x10, 0x00, "Off" },
233 {0x11, 0x01, 0x10, 0x10, "On" },
234
235 {0 , 0xfe, 0 , 4, "Difficulty" },
236 {0x11, 0x01, 0x60, 0x40, "Easy" },
237 {0x11, 0x01, 0x60, 0x60, "Normal" },
238 {0x11, 0x01, 0x60, 0x20, "Hard" },
239 {0x11, 0x01, 0x60, 0x00, "Very Hard" },
240
241 {0 , 0xfe, 0 , 2, "Bonus Life" },
242 {0x11, 0x01, 0x80, 0x80, "Every 15000 points" },
243 {0x11, 0x01, 0x80, 0x00, "Every 20000 points" },
244 };
245
STDDIPINFO(Toypop)246 STDDIPINFO(Toypop)
247
248 static void toypop_main_write(UINT16 address, UINT8 data)
249 {
250 if ((address & 0xf000) == 0x8000) {
251 slave_in_reset = address & 0x800;
252 if (!slave_in_reset) {
253 SekReset();
254 }
255 return;
256 }
257
258 if ((address & 0xf000) == 0x9000) {
259 sound_in_reset = address & 0x800;
260 if (sound_in_reset) {
261 M6809Close();
262 M6809Open(1);
263 M6809Reset();
264 M6809Close();
265 M6809Open(0);
266 }
267 return;
268 }
269
270 switch (address)
271 {
272 case 0xa000:
273 case 0xa001:
274 palette_bank = address & 1;
275 return;
276 }
277
278 if ((address & 0xf000) == 0x6000) address ^= address_xor;
279
280 if ((address & 0xfc00) == 0x6000) {
281 namco_15xx_sharedram_write(address,data);
282 return;
283 }
284
285 if ((address & 0xfff0) == 0x6800) {
286 namcoio_write(0, address & 0xf, data);
287 return;
288 }
289
290 if ((address & 0xfff0) == 0x6810) {
291 namcoio_write(1, address & 0xf, data);
292 return;
293 }
294
295 if ((address & 0xfff0) == 0x6820) {
296 namcoio_write(2, address & 0xf, data);
297 return;
298 }
299
300 if ((address & 0xf000) == 0x7000) {
301 master_irq_enable = (address & 0x0800) ? 0 : 1;
302 return;
303 }
304 }
305
toypop_main_read(UINT16 address)306 static UINT8 toypop_main_read(UINT16 address)
307 {
308 if ((address & 0xf000) == 0x6000) address ^= address_xor;
309
310 if ((address & 0xfc00) == 0x6000) {
311 return namco_15xx_sharedram_read(address);
312 }
313
314 if ((address & 0xfff0) == 0x6800) {
315 return namcoio_read(0, address & 0xf);
316 }
317
318 if ((address & 0xfff0) == 0x6810) {
319 return namcoio_read(1, address & 0xf);
320 }
321
322 if ((address & 0xfff0) == 0x6820) {
323 return namcoio_read(2, address & 0xf);
324 }
325
326 if ((address & 0xf000) == 0x7000 && (address_xor == 0x800)) { // only toypop!
327 master_irq_enable = 1;
328 return 0;
329 }
330
331 return 0;
332 }
333
toypop_slave_write_word(UINT32 address,UINT16 data)334 static void __fastcall toypop_slave_write_word(UINT32 address, UINT16 data)
335 {
336 if ((address & 0xfff000) == 0x100000) {
337 DrvShareRAM[(address / 2) & 0x7ff] = data & 0xff;
338 return;
339 }
340
341 if ((address & 0xff8000) == 0x180000) {
342 address = (address & 0x7ffe) * 2;
343 *((UINT16*)(DrvBgVRAM + (address+0))) = ((data & 0x00f0) << 4) | ((data & 0x000f));
344 *((UINT16*)(DrvBgVRAM + (address+2))) = ((data & 0xf000) >> 4) | ((data & 0xf00) >> 8);
345 return;
346 }
347
348 if ((address & 0xf00000) == 0x300000) {
349 slave_irq_enable = (address & 0x40000) ? 0 : 1;
350 return;
351 }
352 }
353
toypop_slave_write_byte(UINT32 address,UINT8 data)354 static void __fastcall toypop_slave_write_byte(UINT32 address, UINT8 data)
355 {
356 if ((address & 0xfff001) == 0x100001) {
357 DrvShareRAM[(address / 2) & 0x7ff] = data;
358 return;
359 }
360
361 if ((address & 0xf00000) == 0x300000) {
362 slave_irq_enable = (address & 0x40000) ? 0 : 1;
363 return;
364 }
365 }
366
toypop_slave_read_word(UINT32 address)367 static UINT16 __fastcall toypop_slave_read_word(UINT32 address)
368 {
369 if ((address & 0xfff000) == 0x100000) {
370 return DrvShareRAM[(address / 2) & 0x7ff];
371 }
372
373 if ((address & 0xff8000) == 0x180000) {
374 UINT16 *p = (UINT16*)DrvBgVRAM;
375 UINT16 ret;
376 ret = (p[(address & 0x7ffe)+0] & 0xf00) >> 4;
377 ret |= (p[(address & 0x7ffe)+0] & 0x00f) >> 0;
378 ret |= (p[(address & 0x7ffe)+1] & 0xf00) << 4;
379 ret |= (p[(address & 0x7ffe)+1] & 0x00f) << 8;
380
381 return ret;
382 }
383
384 return 0;
385 }
386
toypop_slave_read_byte(UINT32 address)387 static UINT8 __fastcall toypop_slave_read_byte(UINT32 address)
388 {
389 if ((address & 0xfff001) == 0x100001) {
390 return DrvShareRAM[(address / 2) & 0x7ff];
391 }
392
393 return 0;
394 }
395
toypop_sound_write(UINT16 address,UINT8 data)396 static void toypop_sound_write(UINT16 address, UINT8 data)
397 {
398 if (address <= 0x03ff) {
399 namco_15xx_sharedram_write(address,data);
400 return;
401 }
402 }
403
toypop_sound_read(UINT16 address)404 static UINT8 toypop_sound_read(UINT16 address)
405 {
406 if (address <= 0x03ff) {
407 return namco_15xx_sharedram_read(address);
408 }
409
410 return 0;
411 }
412
tilemap_scan(foreground)413 static tilemap_scan( foreground )
414 {
415 INT32 offs;
416
417 row += 2;
418 col -= 2;
419 if (col & 0x20)
420 offs = row + ((col & 0x1f) << 5);
421 else
422 offs = col + (row << 5);
423
424 return offs;
425 }
426
tilemap_callback(foreground)427 static tilemap_callback( foreground )
428 {
429 UINT8 attr = DrvFgRAM[offs + 0x400] & 0x3f;
430 UINT8 code = DrvFgRAM[offs] & 0x1ff;
431
432 TILE_SET_INFO(0, code, attr + palette_bank * 0x40, 0);
433 }
434
nio0_i0(UINT8)435 static UINT8 nio0_i0(UINT8) { return DrvInputs[5] & 0xf; } // COINS
nio0_i1(UINT8)436 static UINT8 nio0_i1(UINT8) { return DrvInputs[0] & 0xf; } // P1_RIGHT
nio0_i2(UINT8)437 static UINT8 nio0_i2(UINT8) { return DrvInputs[1] & 0xf; } // P2_RIGHT
nio0_i3(UINT8)438 static UINT8 nio0_i3(UINT8) { return DrvInputs[4] & 0xf; } // BUTTONS
439
nio1_i0(UINT8)440 static UINT8 nio1_i0(UINT8) { return DrvDips[0] >> 4; }
nio1_i1(UINT8)441 static UINT8 nio1_i1(UINT8) { return DrvDips[1] & 0xf; }
nio1_i2(UINT8)442 static UINT8 nio1_i2(UINT8) { return DrvDips[1] >> 4; }
nio1_i3(UINT8)443 static UINT8 nio1_i3(UINT8) { return DrvDips[0] & 0xf; }
nio1_o0(UINT8,UINT8 data)444 static void nio1_o0(UINT8, UINT8 data) { flipscreen = data; }
445
nio2_i1(UINT8)446 static UINT8 nio2_i1(UINT8) { return DrvInputs[2] & 0xf; } // P1_LEFT
nio2_i2(UINT8)447 static UINT8 nio2_i2(UINT8) { return DrvInputs[3] & 0xf; } // P2_LEFT
nio2_i3(UINT8)448 static UINT8 nio2_i3(UINT8) { return DrvDips[2] & 0xf; } // SERVICE
449
DrvDoReset()450 static INT32 DrvDoReset()
451 {
452 memset (AllRam, 0, RamEnd - AllRam);
453
454 M6809Open(0);
455 M6809Reset();
456 M6809Close();
457
458 SekOpen(0);
459 SekReset();
460 SekClose();
461
462 M6809Open(1);
463 M6809Reset();
464 NamcoSoundReset();
465 M6809Close();
466
467 namcoio_reset(0);
468 namcoio_reset(1);
469 namcoio_reset(2);
470
471 slave_in_reset = 1; // start with slave turned off
472 sound_in_reset = 1; // start with sound turned off
473 palette_bank = 0;
474 master_irq_enable = 0;
475 slave_irq_enable = 0;
476 flipscreen = 0;
477
478 return 0;
479 }
480
MemIndex()481 static INT32 MemIndex()
482 {
483 UINT8 *Next; Next = AllMem;
484
485 DrvM6809ROM0 = Next; Next += 0x008000;
486 DrvM6809ROM1 = Next; Next += 0x002000;
487 Drv68KROM = Next; Next += 0x008000;
488
489 DrvGfxROM0 = Next; Next += 0x008000;
490 DrvGfxROM1 = Next; Next += 0x010000;
491
492 DrvColPROM = Next; Next += 0x000600;
493
494 NamcoSoundProm = Next;
495 DrvSndPROM = Next; Next += 0x000100;
496
497 DrvPalette = (UINT32*)Next; Next += 0x0320 * sizeof(UINT32);
498
499 AllRam = Next;
500
501 DrvFgRAM = Next; Next += 0x002000;
502 DrvShareRAM = Next; Next += 0x000800;
503 Drv68KRAM = Next; Next += 0x040000;
504 DrvBgVRAM = Next; Next += 0x050000;
505
506 RamEnd = Next;
507
508 MemEnd = Next;
509
510 return 0;
511 }
512
DrvGfxDecode()513 static INT32 DrvGfxDecode()
514 {
515 INT32 Plane[2] = { 0, 4 };
516 INT32 XOffs0[8] = { STEP4(64,1), STEP4(0,1) };
517 INT32 XOffs1[16]= { STEP4(0,1), STEP4(64,1), STEP4(128,1), STEP4(192,1) };
518 INT32 YOffs[16] = { STEP8(0,8), STEP8(256,8) };
519
520 UINT8 *tmp = (UINT8*)BurnMalloc(0x4000);
521 if (tmp == NULL) {
522 return 1;
523 }
524
525 memcpy (tmp, DrvGfxROM0, 0x2000);
526
527 GfxDecode(0x0200, 2, 8, 8, Plane, XOffs0, YOffs, 0x080, tmp, DrvGfxROM0);
528
529 memcpy (tmp, DrvGfxROM1, 0x4000);
530
531 GfxDecode(0x0100, 2, 16, 16, Plane, XOffs1, YOffs, 0x200, tmp, DrvGfxROM1);
532
533 BurnFree(tmp);
534
535 return 0;
536 }
537
DrvInit(INT32 addr_xor)538 static INT32 DrvInit(INT32 addr_xor)
539 {
540 AllMem = NULL;
541 MemIndex();
542 INT32 nLen = MemEnd - (UINT8 *)0;
543 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
544 memset(AllMem, 0, nLen);
545 MemIndex();
546
547 {
548 if (BurnLoadRom(DrvM6809ROM0 + 0x0000, 0, 1)) return 1;
549 if (BurnLoadRom(DrvM6809ROM0 + 0x4000, 1, 1)) return 1;
550
551 if (BurnLoadRom(DrvM6809ROM1 + 0x0000, 2, 1)) return 1;
552
553 if (BurnLoadRom(Drv68KROM + 0x0001, 3, 2)) return 1;
554 if (BurnLoadRom(Drv68KROM + 0x0000, 4, 2)) return 1;
555
556 if (BurnLoadRom(DrvGfxROM0 + 0x0000, 5, 1)) return 1;
557
558 if (BurnLoadRom(DrvGfxROM1 + 0x0000, 6, 1)) return 1;
559
560 if (BurnLoadRom(DrvColPROM + 0x0000, 7, 1)) return 1;
561 if (BurnLoadRom(DrvColPROM + 0x0100, 8, 1)) return 1;
562 if (BurnLoadRom(DrvColPROM + 0x0200, 9, 1)) return 1;
563 if (BurnLoadRom(DrvColPROM + 0x0300, 10, 1)) return 1;
564 if (BurnLoadRom(DrvColPROM + 0x0400, 11, 1)) return 1;
565
566 if (BurnLoadRom(DrvSndPROM + 0x0000, 12, 1)) return 1;
567
568 DrvGfxDecode();
569 }
570
571 address_xor = addr_xor;
572
573 M6809Init(0);
574 M6809Open(0);
575 M6809MapMemory(DrvFgRAM, 0x0000, 0x1fff, MAP_RAM);
576 M6809MapMemory(DrvShareRAM, 0x2800, 0x2fff, MAP_RAM);
577 M6809MapMemory(DrvM6809ROM0, 0x8000, 0xffff, MAP_ROM);
578 M6809SetWriteHandler(toypop_main_write);
579 M6809SetReadHandler(toypop_main_read);
580 M6809Close();
581
582 SekInit(0, 0x68000);
583 SekOpen(0);
584 SekMapMemory(Drv68KROM, 0x000000, 0x007fff, MAP_ROM);
585 SekMapMemory(Drv68KRAM, 0x080000, 0x0bffff, MAP_RAM);
586 SekMapMemory(DrvBgVRAM, 0x190000, 0x1dffff, MAP_RAM);
587 SekSetWriteWordHandler(0, toypop_slave_write_word);
588 SekSetWriteByteHandler(0, toypop_slave_write_byte);
589 SekSetReadWordHandler(0, toypop_slave_read_word);
590 SekSetReadByteHandler(0, toypop_slave_read_byte);
591 SekClose();
592
593 M6809Init(1);
594 M6809Open(1);
595 M6809MapMemory(DrvM6809ROM1, 0xe000, 0xffff, MAP_ROM);
596 M6809SetWriteHandler(toypop_sound_write);
597 M6809SetReadHandler(toypop_sound_read);
598 M6809Close();
599
600 NamcoSoundInit(24000, 8, 0);
601 NacmoSoundSetAllRoutes(0.50 * 10.0 / 16.0, BURN_SND_ROUTE_BOTH);
602
603 namcoio_init(0, NAMCO58xx, nio0_i0, nio0_i1, nio0_i2, nio0_i3, NULL, NULL);
604 namcoio_init(1, NAMCO56xx, nio1_i0, nio1_i1, nio1_i2, nio1_i3, nio1_o0, NULL);
605 namcoio_init(2, NAMCO56xx, NULL, nio2_i1, nio2_i2, nio2_i3, NULL, NULL);
606
607 GenericTilesInit();
608 GenericTilemapInit(0, foreground_map_scan, foreground_map_callback, 8, 8, 36, 28);
609 GenericTilemapSetGfx(0, DrvGfxROM0, 2, 8, 8, 0x8000, 0, 0x7f);
610 GenericTilemapSetTransparent(0, 0);
611
612 DrvDoReset();
613
614 return 0;
615 }
616
DrvExit()617 static INT32 DrvExit()
618 {
619 GenericTilesExit();
620
621 M6809Exit();
622 SekExit();
623
624 NamcoSoundExit();
625 NamcoSoundProm = NULL;
626
627 BurnFree(AllMem);
628
629 return 0;
630 }
631
DrvPaletteInit()632 static void DrvPaletteInit()
633 {
634 UINT32 pal[0x100];
635
636 for (INT32 i = 0;i < 256;i++)
637 {
638 INT32 bit0 = (DrvColPROM[i] >> 0) & 0x01;
639 INT32 bit1 = (DrvColPROM[i] >> 1) & 0x01;
640 INT32 bit2 = (DrvColPROM[i] >> 2) & 0x01;
641 INT32 bit3 = (DrvColPROM[i] >> 3) & 0x01;
642 INT32 r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
643
644 bit0 = (DrvColPROM[i+0x100] >> 0) & 0x01;
645 bit1 = (DrvColPROM[i+0x100] >> 1) & 0x01;
646 bit2 = (DrvColPROM[i+0x100] >> 2) & 0x01;
647 bit3 = (DrvColPROM[i+0x100] >> 3) & 0x01;
648 INT32 g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
649
650 bit0 = (DrvColPROM[i+0x200] >> 0) & 0x01;
651 bit1 = (DrvColPROM[i+0x200] >> 1) & 0x01;
652 bit2 = (DrvColPROM[i+0x200] >> 2) & 0x01;
653 bit3 = (DrvColPROM[i+0x200] >> 3) & 0x01;
654 INT32 b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
655
656 pal[i] = BurnHighCol(r,g,b,0);
657 }
658
659 for (INT32 i = 0;i < 256;i++)
660 {
661 DrvPalette[i + 0x000] = pal[(DrvColPROM[i+0x300] & 0xf) + 0x70];
662 DrvPalette[i + 0x100] = pal[(DrvColPROM[i+0x300] & 0xf) + 0xf0];
663 DrvPalette[i + 0x200] = pal[(DrvColPROM[i+0x500])];
664 }
665
666 for (INT32 i = 0;i < 16;i++)
667 {
668 DrvPalette[i + 0x300] = pal[i + 0x60];
669 DrvPalette[i + 0x310] = pal[i + 0xe0];
670 }
671 }
672
draw_bg_layer()673 static void draw_bg_layer()
674 {
675 const UINT16 pal_base = 0x300 + (palette_bank * 16);
676 const UINT32 src_base = 0x200/2;
677 const UINT32 src_pitch = 288 / 2;
678 UINT16 *ram = (UINT16*)DrvBgVRAM;
679
680 for (INT32 y = 0; y < nScreenHeight; ++y)
681 {
682 UINT16 *src = &ram[y * src_pitch + src_base];
683 UINT16 *dst = pTransDraw + (((flipscreen) ? (nScreenHeight - 1 - y) : y) * nScreenWidth);
684
685 for (INT32 x = 0; x < nScreenWidth; x += 2)
686 {
687 UINT32 srcpix = *src++;
688 *dst++ = ((srcpix >> 8) & 0xf) + pal_base;
689 *dst++ = (srcpix & 0xf) + pal_base;
690 }
691 }
692 }
693
draw_sprites()694 static void draw_sprites()
695 {
696 UINT8 *base_spriteram = (DrvFgRAM + 0x800);
697 const UINT16 bank1 = 0x0800;
698 const UINT16 bank2 = 0x1000;
699
700 for (INT32 count = 0x780; count < 0x800; count+=2)
701 {
702 bool enabled = (base_spriteram[count+bank2+1] & 2) == 0;
703
704 if (enabled == false)
705 continue;
706
707 UINT8 tile = base_spriteram[count];
708 UINT8 color = base_spriteram[count+1];
709 INT32 x = base_spriteram[count+bank1+1] + (base_spriteram[count+bank2+1] << 8);
710 x -= 71;
711
712 INT32 y = 224 - (base_spriteram[count+bank1+0] + 7);
713 bool fx = (base_spriteram[count+bank2] & 1) == 1;
714 bool fy = (base_spriteram[count+bank2] & 2) == 2;
715 UINT8 width = ((base_spriteram[count+bank2] & 4) >> 2) + 1;
716 UINT8 height = ((base_spriteram[count+bank2] & 8) >> 3) + 1;
717
718 if (height == 2) y -=16;
719
720 for (INT32 yi = 0; yi < height; yi++)
721 {
722 for (INT32 xi = 0; xi < width; xi++)
723 {
724 UINT16 code = tile + (xi ^ ((width - 1) & fx)) + yi * 2;
725
726 RenderTileTranstabOffset(pTransDraw, DrvGfxROM1, code, (color << 2), 0xff, x + xi*16, y + yi *16, fx, fy, 16, 16, DrvColPROM + 0x500, 0x200);
727 }
728 }
729 }
730 }
731
DrvDraw()732 static INT32 DrvDraw()
733 {
734 if (DrvRecalc) {
735 DrvPaletteInit();
736 DrvRecalc = 0;
737 }
738
739 BurnTransferClear();
740
741 GenericTilemapSetFlip(0, flipscreen);
742
743 if (nBurnLayer & 1) draw_bg_layer();
744 if (nBurnLayer & 2) GenericTilemapDraw(0, pTransDraw, 0);
745 if (nSpriteEnable & 1) draw_sprites();
746
747 BurnTransferCopy(DrvPalette);
748
749 return 0;
750 }
751
master_scanline_callback(INT32 scanline)752 static void master_scanline_callback(INT32 scanline)
753 {
754 if (scanline == 224 && master_irq_enable)
755 M6809SetIRQLine(0, CPU_IRQSTATUS_AUTO);
756
757 if (scanline == 0)
758 {
759 if (!namcoio_read_reset_line(0))
760 namcoio_run(0);
761
762 if (!namcoio_read_reset_line(1))
763 namcoio_run(1);
764
765 if (!namcoio_read_reset_line(2))
766 namcoio_run(2);
767 }
768 }
769
DrvFrame()770 static INT32 DrvFrame()
771 {
772 if (DrvReset) {
773 DrvDoReset();
774 }
775
776 M6809NewFrame();
777 SekNewFrame();
778
779 {
780 memset (DrvInputs, 0xff, 6);
781
782 for (INT32 i = 0; i < 8; i++) {
783 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
784 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
785 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
786 DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
787 DrvInputs[4] ^= (DrvJoy5[i] & 1) << i;
788 DrvInputs[5] ^= (DrvJoy6[i] & 1) << i;
789 }
790 }
791
792 INT32 nInterleave = 264;
793 INT32 nCyclesTotal[3] = { (6144000 / 4) / 60, 6144000 / 60, (6144000 / 4) / 60 };
794 INT32 nCyclesDone[3] = { 0, 0, 0 };
795
796 SekOpen(0);
797
798 for (INT32 i = 0; i < nInterleave; i++)
799 {
800 INT32 nSegment = 0;
801
802 M6809Open(0);
803 master_scanline_callback(i);
804 nCyclesDone[0] += M6809Run(nCyclesTotal[0] / nInterleave);
805 nSegment = M6809TotalCycles();
806 M6809Close();
807
808 if (slave_in_reset) {
809 SekIdle((nSegment * 4) - SekTotalCycles());
810 } else {
811 nCyclesDone[1] += SekRun(nCyclesTotal[1] / nInterleave);
812 if (i == 223 && slave_irq_enable) SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
813 }
814
815 if (sound_in_reset) {
816 nCyclesDone[2] += nSegment - nCyclesDone[2];
817 } else {
818 M6809Open(1);
819 nCyclesDone[2] += M6809Run(nCyclesTotal[2] / nInterleave);
820 if (i == 223) M6809SetIRQLine(0, CPU_IRQSTATUS_AUTO);
821 M6809Close();
822 }
823 }
824
825 SekClose();
826
827 if (pBurnSoundOut) {
828 NamcoSoundUpdate(pBurnSoundOut, nBurnSoundLen);
829 }
830
831 if (pBurnDraw) {
832 DrvDraw();
833 }
834
835 return 0;
836 }
837
DrvScan(INT32 nAction,INT32 * pnMin)838 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
839 {
840 struct BurnArea ba;
841
842 if (pnMin) {
843 *pnMin = 0x029702;
844 }
845
846 if (nAction & ACB_VOLATILE) {
847 memset(&ba, 0, sizeof(ba));
848
849 ba.Data = AllRam;
850 ba.nLen = RamEnd - AllRam;
851 ba.szName = "All Ram";
852 BurnAcb(&ba);
853
854 M6809Scan(nAction);
855 SekScan(nAction);
856 NamcoSoundScan(nAction, pnMin);
857
858 namcoio_scan(0);
859 namcoio_scan(1);
860 namcoio_scan(2);
861
862 SCAN_VAR(slave_in_reset);
863 SCAN_VAR(sound_in_reset);
864 SCAN_VAR(palette_bank);
865 SCAN_VAR(master_irq_enable);
866 SCAN_VAR(slave_irq_enable);
867 SCAN_VAR(flipscreen);
868 }
869
870 return 0;
871 }
872
873
874 // Libble Rabble
875
876 static struct BurnRomInfo liblrablRomDesc[] = {
877 { "5b.rom", 0x4000, 0xda7a93c2, 1 | BRF_GRA }, // 0 M6809 Code (master)
878 { "5c.rom", 0x4000, 0x6cae25dc, 1 | BRF_GRA }, // 1
879
880 { "2c.rom", 0x2000, 0x7c09e50a, 2 | BRF_GRA }, // 2 M6809 Code (sound)
881
882 { "8c.rom", 0x4000, 0xa00cd959, 3 | BRF_GRA }, // 3 M68000 Code (slave)
883 { "10c.rom", 0x4000, 0x09ce209b, 3 | BRF_GRA }, // 4
884
885 { "5p.rom", 0x2000, 0x3b4937f0, 4 | BRF_GRA }, // 5 Foreground Tiles
886
887 { "9t.rom", 0x4000, 0xa88e24ca, 5 | BRF_GRA }, // 6 Sprites
888
889 { "lr1-3.1r", 0x0100, 0xf3ec0d07, 6 | BRF_GRA }, // 7 Color Data
890 { "lr1-2.1s", 0x0100, 0x2ae4f702, 6 | BRF_GRA }, // 8
891 { "lr1-1.1t", 0x0100, 0x7601f208, 6 | BRF_GRA }, // 9
892 { "lr1-5.5l", 0x0100, 0x940f5397, 6 | BRF_GRA }, // 10
893 { "lr1-6.2p", 0x0200, 0xa6b7f850, 6 | BRF_GRA }, // 11
894
895 { "lr1-4.3d", 0x0100, 0x16a9166a, 7 | BRF_GRA }, // 12 Sound data
896 };
897
898 STD_ROM_PICK(liblrabl)
STD_ROM_FN(liblrabl)899 STD_ROM_FN(liblrabl)
900
901 static INT32 LiblrablInit()
902 {
903 return DrvInit(0);
904 }
905
906 struct BurnDriver BurnDrvLiblrabl = {
907 "liblrabl", NULL, NULL, NULL, "1983",
908 "Libble Rabble\0", NULL, "Namco", "Miscellaneous",
909 NULL, NULL, NULL, NULL,
910 BDF_GAME_WORKING, 4, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
911 NULL, liblrablRomInfo, liblrablRomName, NULL, NULL, NULL, NULL, LiblrablInputInfo, LiblrablDIPInfo,
912 LiblrablInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x320,
913 288, 224, 4, 3
914 };
915
916
917 // Toypop
918
919 static struct BurnRomInfo toypopRomDesc[] = {
920 { "tp1-2.5b", 0x4000, 0x87469620, 1 | BRF_GRA }, // 0 M6809 Code (master)
921 { "tp1-1.5c", 0x4000, 0xdee2fd6e, 1 | BRF_GRA }, // 1
922
923 { "tp1-3.2c", 0x2000, 0x5f3bf6e2, 2 | BRF_GRA }, // 2 M6809 Code (sound)
924
925 { "tp1-4.8c", 0x4000, 0x76997db3, 3 | BRF_GRA }, // 3 M68000 Code (slave)
926 { "tp1-5.10c", 0x4000, 0x37de8786, 3 | BRF_GRA }, // 4
927
928 { "tp1-7.5p", 0x2000, 0x95076f9e, 4 | BRF_GRA }, // 5 Foreground Tiles
929
930 { "tp1-6.9t", 0x4000, 0x481ffeaf, 5 | BRF_GRA }, // 6 Sprites
931
932 { "tp1-3.1r", 0x0100, 0xcfce2fa5, 6 | BRF_GRA }, // 7 Color Data
933 { "tp1-2.1s", 0x0100, 0xaeaf039d, 6 | BRF_GRA }, // 8
934 { "tp1-1.1t", 0x0100, 0x08e7cde3, 6 | BRF_GRA }, // 9
935 { "tp1-4.5l", 0x0100, 0x74138973, 6 | BRF_GRA }, // 10
936 { "tp1-5.2p", 0x0200, 0x4d77fa5a, 6 | BRF_GRA }, // 11
937
938 { "tp1-6.3d", 0x0100, 0x16a9166a, 7 | BRF_GRA }, // 12 Sound data
939 };
940
941 STD_ROM_PICK(toypop)
STD_ROM_FN(toypop)942 STD_ROM_FN(toypop)
943
944 static INT32 ToypopInit()
945 {
946 return DrvInit(0x800);
947 }
948
949 struct BurnDriver BurnDrvToypop = {
950 "toypop", NULL, NULL, NULL, "1986",
951 "Toypop\0", NULL, "Namco", "Miscellaneous",
952 NULL, NULL, NULL, NULL,
953 BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_PUZZLE, 0,
954 NULL, toypopRomInfo, toypopRomName, NULL, NULL, NULL, NULL, ToypopInputInfo, ToypopDIPInfo,
955 ToypopInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x320,
956 288, 224, 4, 3
957 };
958