1 /*******************************************************************************
2
3 Equites (c) 1984 Alpha Denshi Co./Sega
4 Bull Fighter (c) 1984 Alpha Denshi Co./Sega
5 The Koukouyakyuh (c) 1985 Alpha Denshi Co.
6 Splendor Blast (c) 1985 Alpha Denshi Co.
7 High Voltage (c) 1985 Alpha Denshi Co.
8
9 drivers by Acho A. Tang
10
11 *******************************************************************************/
12 /* Directives*/
13
14 #include "driver.h"
15 #include "cpu/i8085/i8085.h"
16 #include "machine/random.h"
17
18 #define MCU_RTNMSB 0x80
19
20 #if 0 /* ** cut-and-pasted to driver module ***/
21
22 /* Common Hardware Start*/
23 #define EQUITES_ADD_SOUNDBOARD7 \
24 MDRV_CPU_ADD(8085A, 5000000) \
25 MDRV_CPU_FLAGS(CPU_AUDIO_CPU) \
26 MDRV_CPU_MEMORY(equites_s_readmem, equites_s_writemem) \
27 MDRV_CPU_PORTS(0, equites_s_writeport) \
28 MDRV_CPU_PERIODIC_INT(nmi_line_pulse, 4000) \
29 MDRV_SOUND_ADD(MSM5232, equites_5232intf) \
30 MDRV_SOUND_ADD(AY8910, equites_8910intf) \
31 MDRV_SOUND_ADD(DAC, equites_dacintf)
32
33 extern void equites_8404init(void);
34 extern void equites_8404rule(unsigned pc, int offset, int data);
35
36 extern READ16_HANDLER(equites_8404_r);
37 extern WRITE_HANDLER(equites_5232_w);
38 extern WRITE_HANDLER(equites_8910control_w);
39 extern WRITE_HANDLER(equites_8910data_w);
40 extern WRITE_HANDLER(equites_dac0_w);
41 extern WRITE_HANDLER(equites_dac1_w);
42
43 extern data16_t *equites_8404ram;
44 extern struct MSM5232interface equites_5232intf;
45 extern struct AY8910interface equites_8910intf;
46 extern struct DACinterface equites_dacintf;
47
48 static MEMORY_READ_START( equites_s_readmem )
49 { 0x0000, 0xbfff, MRA_ROM }, /* sound program*/
50 { 0xc000, 0xc000, soundlatch_r },
51 { 0xe000, 0xe0ff, MRA_RAM }, /* stack and variables*/
52 MEMORY_END
53
54 static MEMORY_WRITE_START( equites_s_writemem )
55 { 0x0000, 0xbfff, MWA_ROM }, /* sound program*/
56 { 0xc080, 0xc08d, equites_5232_w },
57 { 0xc0a0, 0xc0a0, equites_8910data_w },
58 { 0xc0a1, 0xc0a1, equites_8910control_w },
59 { 0xc0b0, 0xc0b0, MWA_NOP }, /* INTR: sync with main melody*/
60 { 0xc0c0, 0xc0c0, MWA_NOP }, /* INTR: sync with specific beats*/
61 { 0xc0d0, 0xc0d0, equites_dac0_w },
62 { 0xc0e0, 0xc0e0, equites_dac1_w },
63 { 0xc0f8, 0xc0fe, MWA_NOP }, /* soundboard I/O, ignored*/
64 { 0xc0ff, 0xc0ff, soundlatch_clear_w },
65 { 0xe000, 0xe0ff, MWA_RAM }, /* stack and variables*/
66 MEMORY_END
67
68 static PORT_WRITE_START( equites_s_writeport )
69 { 0x00e0, 0x00e5, MWA_NOP }, /* soundboard I/O, ignored*/
70 PORT_END
71 /* Common Hardware End*/
72
73 #endif
74
75 /******************************************************************************/
76 /* Imports*/
77
78 extern data16_t *equites_workram;
79
80 /******************************************************************************/
81 /* Locals*/
82
83 static UINT16 e_ent_addr[8][4] =
84 {
85 {0xce25, 0xcd3c, 0xcd89, 0xcdd5},
86 { 0, 0xce6e, 0xcebe, 0xcff2},
87 { 0, 0xcf07, 0xcf55, 0xcfa2},
88 { 0, 0xcff2, 0xd03a, 0},
89 { 0, 0xd08e, 0xd0e1, 0xd132},
90 { 0, 0xd17a, 0, 0},
91 { 0, 0xd1c0, 0xcff2, 0},
92 { 0, 0, 0, 0},
93 };
94
95 static UINT16 e_exit_pos[8][4] =
96 {
97 {0x1878, 0x4878, 0x7878, 0x3878},
98 { 0, 0x3878, 0x4878, 0x4878},
99 { 0, 0x3878, 0x0060, 0x4878},
100 { 0, 0x0060, 0x4878, 0},
101 { 0, 0x7878, 0x4878, 0x4878},
102 { 0, 0x4878, 0, 0},
103 { 0, 0x3878, 0x4878, 0},
104 { 0, 0, 0, 0},
105 };
106
107 static UINT16 e_swap_addr[4][4] =
108 {
109 { 0, 0x92ec, 0, 0x92ec},
110 { 0, 0x92ec, 0, 0x92ec},
111 { 0, 0, 0, 0x92ec},
112 { 0, 0x92d2, 0, 0x92d2},
113 };
114
115 static UINT16 e_respawn_addr[4][4] =
116 {
117 { 0, 0x9382, 0, 0x9382},
118 { 0, 0x9382, 0, 0x9382},
119 { 0, 0, 0, 0x9382},
120 { 0, 0x0cc8, 0, 0x9382},
121 };
122
123 static UINT16 h_respawn_addr[2][4] =
124 {
125 {0x1026, 0x0fb6, 0x0fb6, 0x0fb6},
126 {0x11ac, 0x20b0, 0x1c44, 0x1996},
127 };
128
129 static UINT16 s_respawn_addr[3][6] =
130 {
131 {0x0b6a, 0x0b52, 0x29da, 0x0846, 0x1610, 0x0c84}, /* game over seq*/
132 {0x347e, 0x0e10, 0x0c2c, 0x0c2c, 0x0c2c, 0x0c2c}, /* depth seq*/
133 {0x0c2e, 0x1fbe, 0x166a, 0x0c84, 0x0c2c, 0x0c2c}, /* level change seq*/
134 };
135
136 static UINT16 s_lvdata_addr[6] = {0xccc2, 0xd04a, 0xd408, 0xd796, 0xdaa8, 0xdbd6};
137
138 static UINT16 s_objdata_addr[6] = {0xb7ce, 0xba64, 0xbdbc, 0xc0f2, 0xc446, 0xc810};
139
140 static UINT8 s_spawn_list[8] = {0x07, 0x08, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26};
141
142 static UINT8 s_pow_list[8] = {0, 0, 2, 2, 2, 2, 2, 1};
143
144 static struct MRULE
145 {
146 struct MRULE *next;
147 UINT16 pc;
148 UINT8 data;
149 UINT8 mode;
150 } *mrulepool;
151
152 static struct MRULELIST
153 {
154 struct MRULE *head;
155 struct MRULE *tail;
156 } *mrulemap;
157
158 /******************************************************************************/
159 /* Exports*/
160
161 data16_t *equites_8404ram;
162
163 /******************************************************************************/
164 /* Local Functions*/
165
equites_synth_callback(int param)166 static void equites_synth_callback (int param)
167 {
168 static int parity = 0;
169
170 if (parity^=1) cpu_set_irq_line(1, I8085_INTR_LINE, HOLD_LINE);
171 cpu_set_irq_line(1, I8085_RST75_LINE, HOLD_LINE);
172 }
173
174 /* Optimized Mersenne Twister - courtesy of Shawn J. Cokus, University of Washington*/
175
176 typedef unsigned long uint32;
177
178 #define N (624) /* length of state vector*/
179 #define M (397) /* a period parameter*/
180 #define K (0x9908B0DFU) /* a magic constant*/
181 #define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u*/
182 #define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u*/
183 #define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u*/
184 #define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v*/
185
186 static uint32 state[N+1]; /* state vector + 1 extra to not violate ANSI C*/
187 static uint32 *next; /* next random value is computed from here*/
188 static int left = -1; /* can *next++ this many times before reloading*/
189
seedMT(uint32 seed)190 static void seedMT(uint32 seed)
191 {
192 register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
193 register int j;
194
195 for(left=0, *s++=x, j=N; --j;
196 *s++ = (x*=69069U) & 0xFFFFFFFFU);
197 }
198
reloadMT(void)199 static uint32 reloadMT(void)
200 {
201 register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
202 register int j;
203
204 if(left < -1)
205 seedMT(4357U);
206
207 left=N-1, next=state+1;
208
209 for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
210 *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
211
212 for(pM=state, j=M; --j; s0=s1, s1=*p2++)
213 *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
214
215 s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
216 s1 ^= (s1 >> 11);
217 s1 ^= (s1 << 7) & 0x9D2C5680U;
218 s1 ^= (s1 << 15) & 0xEFC60000U;
219 return(s1 ^ (s1 >> 18));
220 }
221
randomMT(void)222 static INLINE uint32 randomMT(void)
223 {
224 uint32 y;
225
226 if(--left < 0)
227 return(reloadMT());
228
229 y = *next++;
230 y ^= (y >> 11);
231 y ^= (y << 7) & 0x9D2C5680U;
232 y ^= (y << 15) & 0xEFC60000U;
233 return(y ^ (y >> 18));
234 }
235
236 /******************************************************************************/
237 /* Export Functions*/
238
equites_8404init(void)239 void equites_8404init(void)
240 {
241 UINT8 *byte_ptr;
242
243 byte_ptr = auto_malloc(0x8000);
244 memset(byte_ptr, 0, 0x8000);
245
246 mrulemap = (struct MRULELIST *)byte_ptr; /* pointer table to rule lists*/
247 mrulepool = (struct MRULE *)(byte_ptr + 0x4000); /* rules pool*/
248
249 timer_pulse(TIME_IN_HZ(106.0), 0, equites_synth_callback); /* hand tuned*/
250
251 seedMT(mame_rand());
252 }
253
equites_8404rule(unsigned pc,int offset,int data)254 void equites_8404rule(unsigned pc, int offset, int data)
255 {
256 struct MRULELIST *listptr;
257
258 mrulepool->pc = pc;
259
260 if (data >= 0)
261 mrulepool->data = data & 0xff;
262 else
263 {
264 data = -data;
265 if (data > 0x0f) data = (data>>4 & 0x0f) | MCU_RTNMSB;
266 mrulepool->mode = data;
267 }
268
269 listptr = mrulemap + (offset>>1);
270
271 if (!listptr->head)
272 listptr->head = mrulepool;
273 else
274 listptr->tail->next = mrulepool;
275
276 listptr->tail = mrulepool++;
277 }
278
279 /******************************************************************************/
280 /* Export Handlers*/
281
READ16_HANDLER(equites_8404_r)282 READ16_HANDLER(equites_8404_r)
283 {
284 int pc, data, mode, col, row;
285 struct MRULE *ruleptr;
286
287 if (ACCESSING_LSB)
288 {
289 pc = activecpu_get_pc();
290
291 /*logerror("%04x: 8404 reads offset %04x\n", pc, offset<<1);*/
292
293 ruleptr = mrulemap[offset].head;
294 while (ruleptr)
295 {
296 if (pc == ruleptr->pc)
297 {
298 mode = ruleptr->mode;
299 if (!mode) return (ruleptr->data);
300 switch (mode & 0xf)
301 {
302 case 1:
303 col = equites_8404ram[0x47d>>1] & 3;
304 row = equites_8404ram[0x47f>>1] & 7;
305 data = e_ent_addr[row][col];
306 break;
307
308 case 2:
309 col = equites_8404ram[0x47d>>1] & 3;
310 row = equites_8404ram[0x47f>>1] & 7;
311 data = e_exit_pos[row][col];
312 break;
313
314 case 3:
315 data = equites_workram[0x130>>1];
316 break;
317
318 case 4:
319 col = equites_8404ram[0x27b>>1] & 3;
320 row = equites_8404ram[0x279>>1] & 3;
321 data = e_respawn_addr[row][col];
322 break;
323
324 case 5:
325 col = equites_8404ram[0x27b>>1] & 3;
326 row = equites_8404ram[0x279>>1] & 3;
327 data = e_swap_addr[row][col];
328 break;
329
330 case 6:
331 col = offset - (0x493>>1);
332 row = (equites_8404ram[0x495>>1] & 0xff) ? 1 : 0;
333 data = h_respawn_addr[row][col>>1];
334 break;
335
336 case 7:
337 col = offset - (0x5e3>>1);
338 if ((equites_8404ram[0xf>>1] & 0xf) == 2)
339 {
340 if (col >= 0xb) equites_8404ram[0xf>>1] = 0;
341 row = 2;
342 }
343 else
344 row = (equites_8404ram[0x4f9>>1] & 0xff) ? 1 : 0;
345 data = s_respawn_addr[row][col>>1];
346 break;
347
348 case 8:
349 data = s_pow_list[randomMT()&7];
350 break;
351
352 case 9:
353 data = s_spawn_list[randomMT()&7];
354 break;
355
356 case 0xa:
357 data = s_objdata_addr[equites_workram[0x90>>1]%6];
358 break;
359
360 case 0xb:
361 data = s_lvdata_addr[equites_workram[0x90>>1]%6];
362 break;
363
364 case 0xc:
365 data = equites_workram[0x90>>1]%6;
366 break;
367
368 default:
369 return (equites_8404ram[offset]);
370 }
371 if (mode & MCU_RTNMSB) data >>= 8;
372 return (data & 0xff);
373 }
374 ruleptr = ruleptr->next;
375 }
376 }
377 return (equites_8404ram[offset]);
378 }
379
WRITE_HANDLER(equites_5232_w)380 WRITE_HANDLER(equites_5232_w)
381 {
382 if (offset < 0x08 && data) data |= 0x80; /* gets around a current 5232 emulation restriction*/
383 MSM5232_0_w(offset, data);
384 }
385
WRITE_HANDLER(equites_8910control_w)386 WRITE_HANDLER(equites_8910control_w)
387 {
388 AY8910Write(0, 0, data);
389 }
390
WRITE_HANDLER(equites_8910data_w)391 WRITE_HANDLER(equites_8910data_w)
392 {
393 AY8910Write(0, 1, data);
394 }
395
WRITE_HANDLER(equites_8910porta_w)396 static WRITE_HANDLER(equites_8910porta_w)
397 {
398 /* sync with one or more MSM5232 channels. MIDI out?*/
399 }
400
WRITE_HANDLER(equites_8910portb_w)401 static WRITE_HANDLER(equites_8910portb_w)
402 {
403 /* sync with one or more MSM5232 channels. MIDI out?*/
404 }
405
WRITE_HANDLER(equites_dac0_w)406 WRITE_HANDLER(equites_dac0_w)
407 {
408 DAC_signed_data_w(0, data<<2);
409 }
410
WRITE_HANDLER(equites_dac1_w)411 WRITE_HANDLER(equites_dac1_w)
412 {
413 DAC_signed_data_w(1, data<<2);
414 }
415
416 /******************************************************************************/
417 /* Alpha "Soundboard 7" Chip Definitions*/
418
419 struct MSM5232interface equites_5232intf =
420 {
421 1,
422 2500000, /* 2.5MHz*/
423 { { 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6 } }, /* needs verification*/
424 { 75 }
425 };
426
427 struct AY8910interface equites_8910intf =
428 {
429 1,
430 6144444/4, /* OSC: 6.144MHz*/
431 { 50 },
432 { 0 },
433 { 0 },
434 { equites_8910porta_w },
435 { equites_8910portb_w },
436 { 0 }
437 };
438
439 struct DACinterface equites_dacintf =
440 {
441 2,
442 { 75, 75 }
443 };
444
445 /******************************************************************************/
446