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