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