1 #include "driver.h"
2 
3 static int counter,vector_reg,imr_status;
4 static data16_t es5510_dsp_ram[0x200];
5 static data32_t	es5510_gpr[0xc0];
6 static data32_t   es5510_dram[1<<16];
7 static data32_t   es5510_dol_latch;
8 static data32_t   es5510_dil_latch;
9 static data32_t   es5510_dadr_latch;
10 static data32_t	es5510_gpr_latch;
11 static data8_t    es5510_ram_sel;
12 static void *timer_68681=NULL;
13 extern data32_t *f3_shared_ram;
14 static int timer_mode,m68681_imr;
15 
16 static int es_tmp=1;
17 
18 #define M68000_CLOCK	16000000
19 #define M68681_CLOCK	2000000 /* Actually X1, not the main clock */
20 
21 enum { TIMER_SINGLESHOT, TIMER_PULSE };
22 
READ16_HANDLER(f3_68000_share_r)23 READ16_HANDLER(f3_68000_share_r)
24 {
25 	if ((offset&3)==0) return (f3_shared_ram[offset/4]&0xff000000)>>16;
26 	if ((offset&3)==1) return (f3_shared_ram[offset/4]&0x00ff0000)>>8;
27 	if ((offset&3)==2) return (f3_shared_ram[offset/4]&0x0000ff00)>>0;
28 	return (f3_shared_ram[offset/4]&0x000000ff)<<8;
29 }
30 
WRITE16_HANDLER(f3_68000_share_w)31 WRITE16_HANDLER(f3_68000_share_w)
32 {
33 	if ((offset&3)==0) f3_shared_ram[offset/4]=(f3_shared_ram[offset/4]&0x00ffffff)|((data&0xff00)<<16);
34 	else if ((offset&3)==1) f3_shared_ram[offset/4]=(f3_shared_ram[offset/4]&0xff00ffff)|((data&0xff00)<<8);
35 	else if ((offset&3)==2) f3_shared_ram[offset/4]=(f3_shared_ram[offset/4]&0xffff00ff)|((data&0xff00)<<0);
36 	else f3_shared_ram[offset/4]=(f3_shared_ram[offset/4]&0xffffff00)|((data&0xff00)>>8);
37 }
38 
WRITE16_HANDLER(f3_es5505_bank_w)39 WRITE16_HANDLER( f3_es5505_bank_w )
40 {
41 	unsigned int max_banks_this_game=(memory_region_length(REGION_SOUND1)/0x200000)-1;
42 
43 #if 0
44 {
45 	static char count[10];
46 	char t[32];
47 	count[data&7]++;
48 	sprintf(t,"%d %d %d %d %d %d %d %d",count[0],count[1],count[2],count[3],count[4],count[5],count[6],count[7]);
49 	usrintf_showmessage(t);
50 }
51 #endif
52 
53 	/* If game is using a out of range (empty) bank - just set it to the last empty bank */
54 	if ((data&0x7)>max_banks_this_game)
55 		ES5506_voice_bank_0_w(offset,max_banks_this_game<<20);
56 	else
57 		ES5506_voice_bank_0_w(offset,(data&0x7)<<20);
58 }
59 
WRITE16_HANDLER(f3_volume_w)60 WRITE16_HANDLER( f3_volume_w )
61 {
62 	static data16_t channel[8],last_l,last_r;
63 	static int latch;
64 
65 	if (offset==0) latch=(data>>8)&0x7;
66 	if (offset==1) channel[latch]=data>>8;
67 
68 	if(Machine->sample_rate) {
69 /*		if (channel[7]!=last_l) mixer_set_volume(0, (int)((float)channel[7]*1.58));*/ /* Left master volume */
70 /*		if (channel[6]!=last_r) mixer_set_volume(1, (int)((float)channel[6]*1.58));*/ /* Right master volume */
71 		last_l=channel[7];
72 		last_r=channel[6];
73 	}
74 	/* Channel 5 - Left Aux?  Always set to volume, but never used for panning */
75 	/* Channel 4 - Right Aux?  Always set to volume, but never used for panning */
76 	/* Channels 0, 1, 2, 3 - Unused */
77 }
78 
timer_callback(int param)79 static void timer_callback(int param)
80 {
81 	/* Only cause IRQ if the mask is set to allow it */
82 	if (m68681_imr&8) {
83 		cpu_irq_line_vector_w(1, 6, vector_reg);
84 		cpu_set_irq_line(1, 6, ASSERT_LINE);
85 		imr_status|=0x8;
86 	}
87 }
88 
f3_68681_reset(void)89 void f3_68681_reset(void)
90 {
91 	timer_68681 = timer_alloc(timer_callback);
92 }
93 
READ16_HANDLER(f3_68681_r)94 READ16_HANDLER(f3_68681_r)
95 {
96 	if (offset==0x5) {
97 		int ret=imr_status;
98 		imr_status=0;
99 		return ret;
100 	}
101 
102 	if (offset==0xe)
103 		return 1;
104 
105 	/* IRQ ack */
106 	if (offset==0xf) {
107 		cpu_set_irq_line(1, 6, CLEAR_LINE);
108 		return 0;
109 	}
110 
111 	return 0xff;
112 }
113 
WRITE16_HANDLER(f3_68681_w)114 WRITE16_HANDLER(f3_68681_w)
115 {
116 	switch (offset) {
117 		case 0x04: /* ACR */
118 			switch ((data>>4)&7) {
119 				case 0:
120 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Counter:  Unimplemented external IP2\n");
121 					break;
122 				case 1:
123 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Counter:  Unimplemented TxCA - 1X clock of channel A\n");
124 					break;
125 				case 2:
126 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Counter:  Unimplemented TxCB - 1X clock of channel B\n");
127 					break;
128 				case 3:
129 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Counter:  X1/Clk - divided by 16, counter is %04x, so interrupt every %d cycles\n",counter,(M68000_CLOCK/M68681_CLOCK)*counter*16);
130 					timer_mode=TIMER_SINGLESHOT;
131 					timer_adjust(timer_68681, TIME_IN_CYCLES((M68000_CLOCK/M68681_CLOCK)*counter*16,1), 0, 0);
132 					break;
133 				case 4:
134 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Timer:  Unimplemented external IP2\n");
135 					break;
136 				case 5:
137 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Timer:  Unimplemented external IP2/16\n");
138 					break;
139 				case 6:
140 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Timer:  X1/Clk, counter is %04x, so interrupt every %d cycles\n",counter,(M68000_CLOCK/M68681_CLOCK)*counter);
141 					timer_mode=TIMER_PULSE;
142 					timer_adjust(timer_68681, TIME_IN_CYCLES((M68000_CLOCK/M68681_CLOCK)*counter,1), 0, TIME_IN_CYCLES((M68000_CLOCK/M68681_CLOCK)*counter,1));
143 					break;
144 				case 7:
145 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Timer:  Unimplemented X1/Clk - divided by 16\n");
146 					break;
147 			}
148 			break;
149 
150 		case 0x05: /* IMR */
151 			log_cb(RETRO_LOG_DEBUG, LOGPRE "68681:  %02x %02x\n",offset,data&0xff);
152 			m68681_imr=data&0xff;
153 			break;
154 
155 		case 0x06: /* CTUR */
156 			counter=((data&0xff)<<8)|(counter&0xff);
157 			break;
158 		case 0x07: /* CTLR */
159 			counter=(counter&0xff00)|(data&0xff);
160 			break;
161 		case 0x08: break; /* MR1B (Mode register B) */
162 		case 0x09: break; /* CSRB (Clock select register B) */
163 		case 0x0a: break; /* CRB (Command register B) */
164 		case 0x0b: break; /* TBB (Transmit buffer B) */
165 		case 0x0c: /* IVR (Interrupt vector) */
166 			vector_reg=data&0xff;
167 			break;
168 		default:
169 			log_cb(RETRO_LOG_DEBUG, LOGPRE "68681:  %02x %02x\n",offset,data&0xff);
170 			break;
171 	}
172 }
173 
READ16_HANDLER(es5510_dsp_r)174 READ16_HANDLER(es5510_dsp_r)
175 {
176 /*	log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x: DSP read offset %04x (data is %04x)\n",activecpu_get_pc(),offset,es5510_dsp_ram[offset]);*/
177 /*	if (es_tmp) return es5510_dsp_ram[offset];*/
178 /*
179 	switch (offset) {
180 		case 0x00: return (es5510_gpr_latch>>16)&0xff;
181 		case 0x01: return (es5510_gpr_latch>> 8)&0xff;
182 		case 0x02: return (es5510_gpr_latch>> 0)&0xff;
183 		case 0x03: return 0;
184 	}
185 */
186 /*	offset<<=1;*/
187 
188 /*if (offset<7 && es5510_dsp_ram[0]!=0xff) return rand()%0xffff;*/
189 
190 	if (offset==0x12) return 0;
191 
192 /*	if (offset>4)*/
193 	if (offset==0x16) return 0x27;
194 
195 	return es5510_dsp_ram[offset];
196 }
197 
WRITE16_HANDLER(es5510_dsp_w)198 WRITE16_HANDLER(es5510_dsp_w)
199 {
200 	UINT8 *snd_mem = (UINT8 *)memory_region(REGION_SOUND1);
201 
202 	if (offset>4 && offset!=0x80  && offset!=0xa0  && offset!=0xc0  && offset!=0xe0)
203 		log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x: DSP write offset %04x %04x\n",activecpu_get_pc(),offset,data);
204 
205 	COMBINE_DATA(&es5510_dsp_ram[offset]);
206 
207 	switch (offset) {
208 		case 0x00: es5510_gpr_latch=(es5510_gpr_latch&0x00ffff)|((data&0xff)<<16);
209 		case 0x01: es5510_gpr_latch=(es5510_gpr_latch&0xff00ff)|((data&0xff)<< 8);
210 		case 0x02: es5510_gpr_latch=(es5510_gpr_latch&0xffff00)|((data&0xff)<< 0);
211 		case 0x03: break;
212 
213 		case 0x80: /* Read select - GPR + INSTR */
214 			log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Read GPR/INSTR %06x (%06x)\n",data,es5510_gpr[data]);
215 
216 			/* Check if a GPR is selected */
217 			if (data<0xc0) {
218 				es_tmp=0;
219 				es5510_gpr_latch=es5510_gpr[data];
220 			} else es_tmp=1;
221 			break;
222 
223 		case 0xa0: /* Write select - GPR */
224 			log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write GPR %06x %06x (0x%04x:=0x%06x\n",data,es5510_gpr_latch,data,snd_mem[es5510_gpr_latch>>8]);
225 			if (data<0xc0)
226 				es5510_gpr[data]=snd_mem[es5510_gpr_latch>>8];
227 			break;
228 
229 		case 0xc0: /* Write select - INSTR */
230 			log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write INSTR %06x %06x\n",data,es5510_gpr_latch);
231 			break;
232 
233 		case 0xe0: /* Write select - GPR + INSTR */
234 			log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write GPR/INSTR %06x %06x\n",data,es5510_gpr_latch);
235 			break;
236 	}
237 }
238 
READ16_HANDLER(ridingf_dsp_r)239 READ16_HANDLER(ridingf_dsp_r)
240 {
241 	switch(offset)
242 	{
243 		case 0x09: return (es5510_dil_latch >> 16) & 0xff;
244 		case 0x0a: return (es5510_dil_latch >> 8) & 0xff;
245 		case 0x0b: return (es5510_dil_latch >> 0) & 0xff; /* TODO: docs says that this always returns 0 */
246 	}
247 
248 	if (offset==0x12) return 0;
249 
250 /*	if (offset>4) */
251 	if (offset==0x16) return 0x27;
252 
253 	return es5510_dsp_ram[offset];
254 }
255 
WRITE16_HANDLER(ridingf_dsp_w)256 WRITE16_HANDLER(ridingf_dsp_w)
257 {
258 	UINT8 *snd_mem = (UINT8 *)memory_region(REGION_SOUND1);
259 
260 /*	if (offset>4 && offset!=0x80  && offset!=0xa0  && offset!=0xc0  && offset!=0xe0)
261 		log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x: DSP write offset %04x %04x\n",activecpu_get_pc(),offset,data);
262 */
263 
264 	COMBINE_DATA(&es5510_dsp_ram[offset]);
265 
266 	switch (offset) {
267 		case 0x00: es5510_gpr_latch=(es5510_gpr_latch&0x00ffff)|((data&0xff)<<16); break;
268 		case 0x01: es5510_gpr_latch=(es5510_gpr_latch&0xff00ff)|((data&0xff)<< 8); break;
269 		case 0x02: es5510_gpr_latch=(es5510_gpr_latch&0xffff00)|((data&0xff)<< 0); break;
270 
271 		/* 0x03 to 0x08 INSTR Register */
272 		/* 0x09 to 0x0b DIL Register (r/o) */
273 
274 		case 0x0c: es5510_dol_latch=(es5510_dol_latch&0x00ffff)|((data&0xff)<<16); break;
275 		case 0x0d: es5510_dol_latch=(es5510_dol_latch&0xff00ff)|((data&0xff)<< 8); break;
276 		case 0x0e: es5510_dol_latch=(es5510_dol_latch&0xffff00)|((data&0xff)<< 0); break; /* TODO: docs says that this always returns 0xff */
277 
278 		case 0x0f:
279 			es5510_dadr_latch=(es5510_dadr_latch&0x00ffff)|((data&0xff)<<16);
280 
281             if(es5510_ram_sel)
282                 es5510_dil_latch = es5510_dram[es5510_dadr_latch&(1<<16)-2];
283             else
284                 es5510_dram[es5510_dadr_latch&(1<<16)-2] = es5510_dol_latch;
285             break;
286 
287 		case 0x10: es5510_dadr_latch=(es5510_dadr_latch&0xff00ff)|((data&0xff)<< 8); break;
288 		case 0x11: es5510_dadr_latch=(es5510_dadr_latch&0xffff00)|((data&0xff)<< 0); break;
289 
290 		/* 0x12 Host Control */
291 
292 		case 0x14: es5510_ram_sel = data & 0x80; /* bit 6 is i/o select, everything else is undefined */break;
293 
294 		/* 0x16 Program Counter (test purpose, r/o?) */
295 		/* 0x17 Internal Refresh counter (test purpose) */
296 		/* 0x18 Host Serial Control */
297 		/* 0x1f Halt enable (w) / Frame Counter (r) */
298 
299 		case 0x80: /* Read select - GPR + INSTR */
300 	/*		log_cb(RETRO_LOG_DEBUG, LOGPRE ES5510:  Read GPR/INSTR %06x (%06x)\n",data,es5510_gpr[data]); */
301 
302 			/* Check if a GPR is selected */
303 			if (data<0xc0) {
304 				es_tmp=0;
305 				es5510_gpr_latch=es5510_gpr[data];
306 			} else es_tmp=1;
307 			break;
308 
309 		case 0xa0: /* Write select - GPR */
310 	/*		log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write GPR %06x %06x (0x%04x:=0x%06x\n",data,es5510_gpr_latch,data,snd_mem[es5510_gpr_latch>>8]); */
311 			if (data<0xc0)
312 				es5510_gpr[data]=snd_mem[es5510_gpr_latch>>8];
313 			break;
314 
315 		case 0xc0: /* Write select - INSTR */
316 	/*		log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write INSTR %06x %06x\n",data,es5510_gpr_latch); */
317 			break;
318 
319 		case 0xe0: /* Write select - GPR + INSTR */
320 	/*		log_cb(RETRO_LOG_DEBUG, LOGPRE "ES5510:  Write GPR/INSTR %06x %06x\n",data,es5510_gpr_latch); */
321 			break;
322 	}
323 }
324