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