1 // FB Alpha Alien Invaders driver module
2 // Based on MAME driver by David Haywood, Mariusz Wojcieszek
3
4 #include "tiles_generic.h"
5 #include "m6502_intf.h"
6 #include "dac.h"
7
8 static UINT8 *AllMem;
9 static UINT8 *MemEnd;
10 static UINT8 *AllRam;
11 static UINT8 *RamEnd;
12 static UINT8 *Drv6502ROM;
13 static UINT8 *DrvProtPROM;
14 static UINT8 *Drv6502RAM;
15 static UINT8 *DrvVidRAM;
16
17 static UINT32 *DrvPalette;
18 static UINT8 DrvRecalc;
19
20 static UINT8 previrqmask;
21 static UINT8 irqmask;
22
23 static UINT8 DrvJoy1[6];
24 static UINT8 DrvDips[1];
25 static UINT8 DrvReset;
26
27 static struct BurnInputInfo AlinvadeInputList[] = {
28 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" },
29 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 4, "p1 start" },
30 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 3, "p1 left" },
31 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right" },
32 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 1, "p1 fire 1" },
33
34 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
35 {"Dips", BIT_DIPSWITCH, DrvDips + 0, "dip" },
36 };
37
38 STDINPUTINFO(Alinvade)
39
40 static struct BurnDIPInfo AlinvadeDIPList[]=
41 {
42 {0x06, 0xff, 0xff, 0x00, NULL },
43
44 {0 , 0xfe, 0 , 4, "Lives" },
45 {0x06, 0x01, 0x03, 0x00, "2" },
46 {0x06, 0x01, 0x03, 0x01, "3" },
47 {0x06, 0x01, 0x03, 0x02, "4" },
48 {0x06, 0x01, 0x03, 0x03, "5" },
49
50 {0 , 0xfe, 0 , 2, "�" },
51 {0x06, 0x01, 0x04, 0x00, "Off" },
52 {0x06, 0x01, 0x04, 0x04, "On" },
53 };
54
STDDIPINFO(Alinvade)55 STDDIPINFO(Alinvade)
56
57 static UINT8 alinvade_read(UINT16 address)
58 {
59 switch (address)
60 {
61 case 0x4000: return (~DrvJoy1[0] & 1) * 0x10;
62 case 0x6000: return DrvDips[0];
63 case 0x8000: return ( DrvJoy1[1] & 1) * 0x20;
64 case 0x8001: return ( DrvJoy1[2] & 1) * 0x20;
65 case 0x8002: return ( DrvJoy1[3] & 1) * 0x20;
66 case 0x8003: return ( DrvJoy1[4] & 1) * 0x20;
67 case 0x8004: return ( DrvJoy1[5] & 1) * 0x20;
68
69 case 0xe800: return 0;
70 }
71
72 return 0;
73 }
74
alinvade_write(UINT16 address,UINT8 data)75 static void alinvade_write(UINT16 address, UINT8 data)
76 {
77 switch (address)
78 {
79 case 0x2000: // definitely sound writes of some sort
80 DACWrite(0, data);
81 return;
82
83 case 0xa000:
84 return; // nop
85
86 case 0xe400:
87 return; // nop
88
89 case 0xe800:
90 if (previrqmask == 0 && (data & 1) == 1)
91 irqmask ^= 1;
92 previrqmask = data & 1;
93 return;
94 }
95 }
96
DrvSyncDAC()97 static INT32 DrvSyncDAC()
98 {
99 return (INT32)(float)(nBurnSoundLen * (M6502TotalCycles() / (2000000.000 / 60)));
100 }
101
DrvDoReset()102 static INT32 DrvDoReset()
103 {
104 memset (AllRam, 0, RamEnd - AllRam);
105
106 M6502Open(0);
107 M6502Reset();
108 M6502Close();
109
110 DACReset();
111
112 previrqmask = 0;
113 irqmask = 1;
114
115 return 0;
116 }
117
MemIndex()118 static INT32 MemIndex()
119 {
120 UINT8 *Next; Next = AllMem;
121
122 Drv6502ROM = Next; Next += 0x002000;
123
124 DrvProtPROM = Next; Next += 0x000100;
125
126 DrvPalette = (UINT32*)Next; Next += 0x0002 * sizeof(UINT32);
127
128 AllRam = Next;
129
130 Drv6502RAM = Next; Next += 0x000200;
131 DrvVidRAM = Next; Next += 0x000c00;
132
133 RamEnd = Next;
134
135 MemEnd = Next;
136
137 return 0;
138 }
139
DrvInit()140 static INT32 DrvInit()
141 {
142 AllMem = NULL;
143 MemIndex();
144 INT32 nLen = MemEnd - (UINT8 *)0;
145 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
146 memset(AllMem, 0, nLen);
147 MemIndex();
148
149 {
150 if (BurnLoadRom(Drv6502ROM + 0x0000, 0, 1)) return 1;
151 if (BurnLoadRom(Drv6502ROM + 0x0c00, 1, 1)) return 1;
152 if (BurnLoadRom(Drv6502ROM + 0x1000, 2, 1)) return 1;
153 if (BurnLoadRom(Drv6502ROM + 0x1400, 3, 1)) return 1;
154 if (BurnLoadRom(Drv6502ROM + 0x1800, 4, 1)) return 1;
155 if (BurnLoadRom(Drv6502ROM + 0x1c00, 5, 1)) return 1;
156 }
157
158 // Protection hack, since prom isn't dumped we replace it with this
159 {
160 for (INT32 i = 0; i < 0x100; i++) {
161 DrvProtPROM[i] = ((i & 0xf) == 0x0f) ? 0x60 : 0xea;
162 }
163 }
164
165 M6502Init(0, TYPE_M6502);
166 M6502Open(0);
167 M6502MapMemory(Drv6502RAM, 0x0000, 0x01ff, MAP_RAM);
168 M6502MapMemory(DrvVidRAM, 0x0400, 0x0fff, MAP_RAM);
169 for (INT32 i = 0; i < 0x1000; i+=0x100)
170 M6502MapMemory(DrvProtPROM, 0xc000+i, 0xc0ff+i, MAP_ROM); // mirrored
171 M6502MapMemory(Drv6502ROM, 0xe000, 0xffff, MAP_ROM);
172 M6502SetWriteHandler(alinvade_write);
173 M6502SetReadHandler(alinvade_read);
174 M6502Close();
175
176 DACInit(0, 0, 0, DrvSyncDAC);
177 DACSetRoute(0, 1.00, BURN_SND_ROUTE_BOTH);
178
179 GenericTilesInit();
180
181 DrvDoReset();
182
183 return 0;
184 }
185
DrvExit()186 static INT32 DrvExit()
187 {
188 GenericTilesExit();
189
190 DACExit();
191
192 M6502Exit();
193
194 BurnFree(AllMem);
195
196 return 0;
197 }
198
draw_bitmap()199 static void draw_bitmap()
200 {
201 for (INT32 offs = 0; offs < (128 * 128)/8; offs++)
202 {
203 UINT8 sx = (offs << 3) & 0x78;
204 INT32 sy = (offs >> 4) & 0x7f;
205 UINT8 data = DrvVidRAM[offs];
206 UINT16 *dst = pTransDraw + (sy * nScreenWidth) + sx;
207
208 for (INT32 x = 0; x < 8; x++)
209 {
210 dst[x] = data & 1;
211 data >>= 1;
212 }
213 }
214 }
215
DrvDraw()216 static INT32 DrvDraw()
217 {
218 DrvPalette[0] = BurnHighCol(0x00,0x00,0x00, 0);
219 DrvPalette[1] = BurnHighCol(0xff,0xff,0xff, 0);
220
221 draw_bitmap();
222
223 BurnTransferCopy(DrvPalette);
224
225 return 0;
226 }
227
DrvFrame()228 static INT32 DrvFrame()
229 {
230 if (DrvReset) {
231 DrvDoReset();
232 }
233
234 M6502NewFrame();
235
236 INT32 nTotalCycles = 2000000 / 60;
237
238 M6502Open(0);
239 M6502Run(nTotalCycles);
240 if (irqmask) M6502SetIRQLine(0, CPU_IRQSTATUS_AUTO);
241 M6502Close();
242
243 if (pBurnSoundOut) {
244 DACUpdate(pBurnSoundOut, nBurnSoundLen);
245 }
246
247 if (pBurnDraw) {
248 DrvDraw();
249 }
250
251 return 0;
252 }
253
DrvScan(INT32 nAction,INT32 * pnMin)254 static INT32 DrvScan(INT32 nAction,INT32 *pnMin)
255 {
256 struct BurnArea ba;
257
258 if (pnMin) {
259 *pnMin = 0x029722;
260 }
261
262 if (nAction & ACB_VOLATILE) {
263 memset(&ba, 0, sizeof(ba));
264 ba.Data = AllRam;
265 ba.nLen = RamEnd - AllRam;
266 ba.szName = "All Ram";
267 BurnAcb(&ba);
268
269 M6502Scan(nAction);
270
271 DACScan(nAction,pnMin);
272
273 SCAN_VAR(previrqmask);
274 SCAN_VAR(irqmask);
275 }
276
277 return 0;
278 }
279
280
281 // Alien Invaders
282
283 static struct BurnRomInfo alinvadeRomDesc[] = {
284 { "alien28.708", 0x0400, 0xde376295, 1 | BRF_PRG | BRF_ESS }, // 0 m6502 Code
285 { "alien29.708", 0x0400, 0x20212977, 1 | BRF_PRG | BRF_ESS }, // 1
286 { "alien30.708", 0x0400, 0x734b691c, 1 | BRF_PRG | BRF_ESS }, // 2
287 { "alien31.708", 0x0400, 0x5a70535c, 1 | BRF_PRG | BRF_ESS }, // 3
288 { "alien32.708", 0x0400, 0x332dd234, 1 | BRF_PRG | BRF_ESS }, // 4
289 { "alien33.708", 0x0400, 0xe0d57fc7, 1 | BRF_PRG | BRF_ESS }, // 5
290
291 { "prom", 0x0010, 0x00000000, 2 | BRF_NODUMP }, // 6 Protection prom
292 };
293
294 STD_ROM_PICK(alinvade)
295 STD_ROM_FN(alinvade)
296
297 struct BurnDriver BurnDrvAlinvade = {
298 "alinvade", NULL, NULL, NULL, "198?",
299 "Alien Invaders\0", "preliminary sound", "Forbes?", "Miscellaneous",
300 NULL, NULL, NULL, NULL,
301 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 1, HARDWARE_MISC_PRE90S, GBF_VERSHOOT, 0,
302 NULL, alinvadeRomInfo, alinvadeRomName, NULL, NULL, NULL, NULL, AlinvadeInputInfo, AlinvadeDIPInfo,
303 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 2,
304 128, 128, 4, 3
305 };
306