trunk/src/mess/machine/psxcd.c
r22505 | r22506 | |
2 | 2 | #include "psxcd.h" |
3 | 3 | #include "debugger.h" |
4 | 4 | |
5 | | // |
6 | | // |
7 | | // |
| 5 | #define VERBOSE_LEVEL ( 0 ) |
8 | 6 | |
9 | | //#define debug_cdrom |
10 | | //#define debug_cdrom_registers |
11 | | //#define skip_reads |
12 | | //#define dump_subheader |
| 7 | INLINE void ATTR_PRINTF(3,4) verboselog( running_machine& machine, int n_level, const char *s_fmt, ... ) |
| 8 | { |
| 9 | if( VERBOSE_LEVEL >= n_level ) |
| 10 | { |
| 11 | va_list v; |
| 12 | char buf[ 32768 ]; |
| 13 | va_start( v, s_fmt ); |
| 14 | vsprintf( buf, s_fmt, v ); |
| 15 | va_end( v ); |
| 16 | logerror( "%s: %s", machine.describe_context(), buf ); |
| 17 | } |
| 18 | } |
13 | 19 | |
14 | | // |
15 | | // |
16 | | // |
17 | | |
18 | 20 | enum cdrom_events |
19 | 21 | { |
20 | 22 | event_cmd_complete=0, |
21 | | event_preread_sector, |
22 | 23 | event_read_sector, |
23 | 24 | event_play_sector, |
24 | 25 | event_change_disk |
25 | 26 | }; |
26 | 27 | |
27 | | // |
28 | | // |
29 | | // |
30 | | |
31 | 28 | enum intr_status |
32 | 29 | { |
33 | 30 | intr_nointr=0, |
r22505 | r22506 | |
44 | 41 | mode_adpcm=0x40, |
45 | 42 | mode_size=0x20, |
46 | 43 | mode_size2=0x10, |
47 | | mode_size_shift=4, |
48 | | mode_size_mask=(3<<mode_size_shift), |
| 44 | mode_size_mask=0x30, |
49 | 45 | mode_channel=0x08, |
50 | 46 | mode_report=0x04, |
51 | 47 | mode_autopause=0x02, |
r22505 | r22506 | |
66 | 62 | |
67 | 63 | struct subheader |
68 | 64 | { |
69 | | unsigned char file, |
70 | | channel, |
71 | | submode, |
72 | | coding; |
| 65 | UINT8 file, channel, submode, coding; |
73 | 66 | }; |
74 | 67 | |
75 | 68 | enum submode_flags |
r22505 | r22506 | |
84 | 77 | submode_eor=0x01 |
85 | 78 | }; |
86 | 79 | |
87 | | // |
88 | | // |
89 | | // |
90 | | |
91 | 80 | //************************************************************************** |
92 | 81 | // DEVICE DEFINITIONS |
93 | 82 | //************************************************************************** |
r22505 | r22506 | |
123 | 112 | |
124 | 113 | m_sysclock = sysclk; |
125 | 114 | |
126 | | secleft = 0; |
127 | | secsize = 2048; |
128 | 115 | res_queue = NULL; |
129 | | cur_res = NULL; |
130 | | streaming = false; |
131 | | sechead = 0; |
132 | | sectail = 0; |
133 | | secskip = 0; |
134 | | next_read_event = -1; |
135 | | cbp = cmdbuf; |
136 | | m_mute = false; |
137 | | |
138 | 116 | status=status_shellopen; |
139 | | sr=8|1; |
140 | | res=0; |
141 | | ir=0; |
142 | 117 | mode=0; |
143 | 118 | |
144 | 119 | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
r22505 | r22506 | |
146 | 121 | m_timers[i] = timer_alloc(i); |
147 | 122 | m_timerinuse[i] = false; |
148 | 123 | } |
149 | | |
150 | | curpos.w = 0; |
151 | | m_param_count = 0; |
152 | 124 | } |
153 | 125 | |
154 | | // |
155 | | // |
156 | | // |
157 | | |
158 | 126 | void psxcd_device::device_reset() |
159 | 127 | { |
160 | 128 | stop_read(); |
r22505 | r22506 | |
168 | 136 | if(m_cdrom_handle) |
169 | 137 | add_system_event(event_change_disk, m_sysclock, NULL); |
170 | 138 | |
171 | | next_read_event = -1; |
172 | | |
173 | | if(cur_res) |
174 | | { |
175 | | global_free(cur_res); |
176 | | cur_res = NULL; |
177 | | } |
178 | | |
179 | 139 | while(res_queue) |
180 | 140 | { |
181 | | cur_res = res_queue->next; |
| 141 | command_result *res = res_queue->next; |
182 | 142 | global_free(res_queue); |
183 | | res_queue = cur_res; |
| 143 | res_queue = res; |
184 | 144 | } |
185 | 145 | |
186 | 146 | m_param_count = 0; |
| 147 | m_regs.sr = 0x18; |
| 148 | m_regs.ir = 0; |
| 149 | m_regs.imr = 0x1f; |
| 150 | sechead = 0; |
| 151 | sectail = 0; |
| 152 | next_read_event = -1; |
| 153 | m_mute = false; |
| 154 | m_dmaload = false; |
| 155 | curpos.w = 0; |
187 | 156 | } |
188 | 157 | |
189 | | // |
190 | | // |
191 | | // |
192 | | |
193 | 158 | bool psxcd_device::call_load() |
194 | 159 | { |
195 | 160 | bool ret = cdrom_image_device::call_load(); |
r22505 | r22506 | |
210 | 175 | |
211 | 176 | READ8_MEMBER( psxcd_device::read ) |
212 | 177 | { |
213 | | unsigned char ret = 0; |
214 | | |
215 | | switch (offset&3) |
| 178 | UINT8 ret = 0; |
| 179 | switch (offset & 3) |
216 | 180 | { |
217 | 181 | /* |
218 | 182 | x--- ---- command/parameter busy flag |
r22505 | r22506 | |
222 | 186 | ---- x--- parameter fifo empty (active high) |
223 | 187 | ---- --xx cmd mode |
224 | 188 | */ |
225 | | case 0: ret=sr; break; |
| 189 | case 0: |
| 190 | ret = m_regs.sr; |
| 191 | break; |
| 192 | |
226 | 193 | case 1: |
227 | | ret=res; |
228 | | if ((cur_res) && (rdp<cur_res->sz)) |
| 194 | if ((res_queue) && (rdp < res_queue->sz)) |
229 | 195 | { |
230 | | res=cur_res->data[rdp++]; |
231 | | sr|=(1<<5); |
232 | | } else |
| 196 | ret = res_queue->data[rdp++]; |
| 197 | if(rdp == res_queue->sz) |
| 198 | m_regs.sr &= ~0x20; |
| 199 | else |
| 200 | m_regs.sr |= 0x20; |
| 201 | } |
| 202 | else |
| 203 | ret = 0; |
| 204 | break; |
| 205 | |
| 206 | case 2: |
| 207 | if(!m_dmaload) |
| 208 | ret = 0; |
| 209 | else |
233 | 210 | { |
234 | | if ((cur_res) && (cur_res->res&0x10)) |
| 211 | ret = m_transbuf[m_transcurr++]; |
| 212 | if(m_transcurr >= raw_sector_size) |
235 | 213 | { |
236 | | global_free(cur_res); |
237 | | cur_res=NULL; |
| 214 | m_dmaload = false; |
| 215 | m_regs.sr &= ~0x40; |
238 | 216 | } |
239 | | |
240 | | sr&=~(1<<5); |
241 | 217 | } |
242 | 218 | break; |
243 | | case 2: ret=0; break; |
244 | | case 3: ret=ir; break; |
| 219 | |
| 220 | case 3: |
| 221 | if(m_regs.sr & 1) |
| 222 | ret = m_regs.ir | 0xe0; |
| 223 | else |
| 224 | ret = m_regs.imr | 0xe0; |
| 225 | break; |
245 | 226 | } |
246 | 227 | |
247 | | #ifdef debug_cdrom_registers |
248 | | printf("cdrom: read byte %08x = %02x (PC=%08x)\n",offset,ret,space.device().safe_pc()); |
249 | | #endif |
| 228 | verboselog(machine(), 2, "psxcd: read byte %08x = %02x\n",offset,ret); |
250 | 229 | |
251 | 230 | return ret; |
252 | 231 | } |
253 | 232 | |
254 | | // |
255 | | // |
256 | | // |
257 | | |
258 | 233 | WRITE8_MEMBER( psxcd_device::write ) |
259 | 234 | { |
260 | | #ifdef debug_cdrom_registers |
261 | | printf("cdrom: write byte %08x = %02x (PC=%08x)\n",offset,data,space.device().safe_pc()); |
262 | | #endif |
| 235 | verboselog(machine(), 2, "psxcd: write byte %08x = %02x\n",offset,data); |
263 | 236 | |
264 | | switch (offset&3) |
| 237 | switch ((offset & 3) | ((m_regs.sr & 3) << 4)) |
265 | 238 | { |
266 | | case 0: |
267 | | //if(data & 2) |
268 | | // popmessage("cmdmode = %02x, contact MESSdev",data); |
| 239 | case 0x00: |
| 240 | case 0x10: |
| 241 | case 0x20: |
| 242 | case 0x30: |
| 243 | m_regs.sr = (m_regs.sr & ~3) | (data & 3); |
| 244 | break; |
269 | 245 | |
270 | | cmdmode=data&1; |
271 | | if (cmdmode==0) |
272 | | { |
273 | | cbp=cmdbuf; |
274 | | } else |
275 | | { |
276 | | if (! cur_res) |
277 | | { |
278 | | if (cur_res) global_free(cur_res); |
| 246 | case 0x01: |
| 247 | write_command(data); |
| 248 | break; |
279 | 249 | |
280 | | if (res_queue) |
281 | | { |
282 | | #ifdef debug_cdrom_registers |
283 | | printf("cdrom: nextres\n"); |
284 | | #endif |
| 250 | case 0x11: |
| 251 | case 0x21: |
| 252 | break; |
285 | 253 | |
286 | | cur_res=res_queue; |
287 | | res_queue=res_queue->next; |
288 | | ir=cur_res->res&0xf; |
289 | | rdp=0; |
| 254 | case 0x31: |
| 255 | m_regs.vol.rr = data; |
| 256 | break; |
290 | 257 | |
291 | | if (cur_res->sz) |
292 | | { |
293 | | res=cur_res->data[rdp++]; |
294 | | sr|=(1<<5); |
295 | | } else |
296 | | { |
297 | | sr&=~(1<<5); |
298 | | } |
299 | | } else |
300 | | { |
301 | | //ir=0; |
302 | | cur_res=NULL; |
303 | | } |
304 | | } |
305 | | /*else |
306 | | { |
307 | | if (rdp>=cur_res->sz) |
308 | | { |
309 | | sr&=~(1<<5); |
310 | | } else |
311 | | { |
312 | | sr|=~(1<<5); |
313 | | res=cur_res->data[rdp++]; |
314 | | } |
315 | | } |
316 | | */ |
317 | | } |
| 258 | case 0x02: |
| 259 | cmdbuf[m_param_count] = data; |
| 260 | m_param_count++; |
318 | 261 | break; |
319 | 262 | |
320 | | case 1: |
321 | | if (cmdmode==0) |
322 | | { |
323 | | write_command(data); |
324 | | } |
| 263 | case 0x12: |
| 264 | m_regs.imr = data & 0x1f; |
325 | 265 | break; |
326 | 266 | |
327 | | case 2: |
328 | | if (cmdmode==0) |
329 | | { |
330 | | *cbp++=data; |
331 | | m_param_count++; |
332 | | } else |
333 | | { |
334 | | // ?flush buffer? |
335 | | //if(data & 0xf8) |
336 | | //popmessage("Interrupt enable register mode 1 [%02x] -> %02x",offset,data); |
337 | | } |
| 267 | case 0x22: |
| 268 | m_regs.vol.ll = data; |
338 | 269 | break; |
339 | 270 | |
| 271 | case 0x32: |
| 272 | m_regs.vol.rl = data; |
| 273 | break; |
340 | 274 | /* |
341 | 275 | x--- ---- unknown |
342 | 276 | -x-- ---- Reset parameter FIFO |
r22505 | r22506 | |
344 | 278 | ---x ---- Command start |
345 | 279 | ---- -xxx Response received |
346 | 280 | */ |
347 | | case 3: |
348 | | //if(data & 0x78) |
349 | | // popmessage("IRQ flag = %02x, contact MESSdev",data); |
| 281 | case 0x03: |
| 282 | if((data & 0x80) && !m_dmaload) |
| 283 | { |
| 284 | if(sechead == sectail) |
| 285 | break; |
350 | 286 | |
351 | | if (data==0x07) |
| 287 | m_dmaload = true; |
| 288 | memcpy(m_transbuf, secbuf[sechead], raw_sector_size); |
| 289 | m_regs.sr |= 0x40; |
| 290 | sechead++; |
| 291 | sechead %= sector_buffer_size; |
| 292 | |
| 293 | switch(mode & mode_size_mask) |
| 294 | { |
| 295 | case 0x00: |
| 296 | default: |
| 297 | m_transcurr = 24; |
| 298 | break; |
| 299 | case 0x10: |
| 300 | m_transcurr = 24; |
| 301 | break; |
| 302 | case 0x20: |
| 303 | m_transcurr = 12; |
| 304 | break; |
| 305 | } |
| 306 | #if (VERBOSE_LEVEL > 0) |
| 307 | char str[1024]; |
| 308 | for (int i=0; i<12; i++) |
| 309 | sprintf(&str[i*4], "%02x ", m_transbuf[i+12]); |
| 310 | verboselog(machine(), 1, "psxcd: request data=%s\n",str); |
| 311 | #endif |
| 312 | } |
| 313 | else if(!(data & 0x80)) |
352 | 314 | { |
353 | | if (cur_res) |
| 315 | m_dmaload = false; |
| 316 | m_regs.sr &= ~0x40; |
| 317 | } |
| 318 | break; |
| 319 | |
| 320 | case 0x13: |
| 321 | if(data & 0x1f) |
| 322 | { |
| 323 | m_regs.ir &= ~(data & 0x1f); |
| 324 | if(m_regs.ir) |
| 325 | break; |
| 326 | |
| 327 | if (res_queue) |
354 | 328 | { |
355 | | global_free(cur_res); |
356 | | cur_res=NULL; |
357 | | sr&=~(1<<5); |
| 329 | command_result *res = res_queue; |
| 330 | res_queue = res->next; |
| 331 | global_free(res); |
| 332 | m_regs.sr &= ~0x20; |
| 333 | rdp = 0; |
| 334 | if(res_queue) |
| 335 | { |
| 336 | m_regs.sr |= 0x20; |
| 337 | m_regs.ir = res_queue->res; |
| 338 | } |
| 339 | verboselog(machine(), 1, "psxcd: nextres\n"); |
358 | 340 | } |
359 | | ir=0; |
360 | 341 | } |
| 342 | if(data & 0x40) |
| 343 | m_param_count = 0; |
| 344 | break; |
| 345 | |
| 346 | case 0x23: |
| 347 | m_regs.vol.lr = data; |
| 348 | break; |
| 349 | |
| 350 | case 0x33: |
| 351 | break; |
361 | 352 | } |
362 | 353 | } |
363 | 354 | |
364 | | psxcd_device::command_info psxcd_device::cmd_table[num_commands]= |
| 355 | const psxcd_device::cdcmd psxcd_device::cmd_table[]= |
365 | 356 | { |
366 | | { &psxcd_device::cdcmd_sync, "sync" }, // 00 |
367 | | { &psxcd_device::cdcmd_nop, "nop" }, // 01 |
368 | | { &psxcd_device::cdcmd_setloc, "setloc" }, // 02 |
369 | | { &psxcd_device::cdcmd_play, "play" }, // 03 |
370 | | { &psxcd_device::cdcmd_forward, "forward" }, // 04 |
371 | | { &psxcd_device::cdcmd_backward, "backward" }, // 05 |
372 | | { &psxcd_device::cdcmd_readn, "readn" }, // 06 |
373 | | { &psxcd_device::cdcmd_standby, "standby" }, // 07 |
374 | | { &psxcd_device::cdcmd_stop, "stop" }, // 08 |
375 | | { &psxcd_device::cdcmd_pause, "pause" }, // 09 |
376 | | { &psxcd_device::cdcmd_init, "init" }, // 0a |
377 | | { &psxcd_device::cdcmd_mute, "mute" }, // 0b |
378 | | { &psxcd_device::cdcmd_demute, "demute" }, // 0c |
379 | | { &psxcd_device::cdcmd_setfilter, "setfilter" }, // 0d |
380 | | { &psxcd_device::cdcmd_setmode, "setmode" }, // 0e |
381 | | { &psxcd_device::cdcmd_getparam, "getparam" }, // 0f |
382 | | { &psxcd_device::cdcmd_getlocl, "getlocl" }, // 10 |
383 | | { &psxcd_device::cdcmd_getlocp, "getlocp" }, // 11 |
384 | | { &psxcd_device::cdcmd_illegal, "illegal" }, // 12 |
385 | | { &psxcd_device::cdcmd_gettn, "gettn" }, // 13 |
386 | | { &psxcd_device::cdcmd_gettd, "gettd" }, // 14 |
387 | | { &psxcd_device::cdcmd_seekl, "seekl" }, // 15 |
388 | | { &psxcd_device::cdcmd_seekp, "seekp" }, // 16 |
389 | | { &psxcd_device::cdcmd_illegal, "illegal" }, // 17 |
390 | | { &psxcd_device::cdcmd_illegal, "illegal" }, // 18 |
391 | | { &psxcd_device::cdcmd_test, "test" }, // 19 |
392 | | { &psxcd_device::cdcmd_id, "id" }, // 1a |
393 | | { &psxcd_device::cdcmd_reads, "reads" }, // 1b |
394 | | { &psxcd_device::cdcmd_reset, "reset" }, // 1c |
395 | | { &psxcd_device::cdcmd_illegal, "illegal" }, // 1d |
396 | | { &psxcd_device::cdcmd_readtoc, "readtoc" }, // 1e |
| 357 | &psxcd_device::cdcmd_sync, |
| 358 | &psxcd_device::cdcmd_nop, |
| 359 | &psxcd_device::cdcmd_setloc, |
| 360 | &psxcd_device::cdcmd_play, |
| 361 | &psxcd_device::cdcmd_forward, |
| 362 | &psxcd_device::cdcmd_backward, |
| 363 | &psxcd_device::cdcmd_readn, |
| 364 | &psxcd_device::cdcmd_standby, |
| 365 | &psxcd_device::cdcmd_stop, |
| 366 | &psxcd_device::cdcmd_pause, |
| 367 | &psxcd_device::cdcmd_init, |
| 368 | &psxcd_device::cdcmd_mute, |
| 369 | &psxcd_device::cdcmd_demute, |
| 370 | &psxcd_device::cdcmd_setfilter, |
| 371 | &psxcd_device::cdcmd_setmode, |
| 372 | &psxcd_device::cdcmd_getparam, |
| 373 | &psxcd_device::cdcmd_getlocl, |
| 374 | &psxcd_device::cdcmd_getlocp, |
| 375 | &psxcd_device::cdcmd_unknown12, |
| 376 | &psxcd_device::cdcmd_gettn, |
| 377 | &psxcd_device::cdcmd_gettd, |
| 378 | &psxcd_device::cdcmd_seekl, |
| 379 | &psxcd_device::cdcmd_seekp, |
| 380 | &psxcd_device::cdcmd_illegal17, |
| 381 | &psxcd_device::cdcmd_illegal18, |
| 382 | &psxcd_device::cdcmd_test, |
| 383 | &psxcd_device::cdcmd_id, |
| 384 | &psxcd_device::cdcmd_reads, |
| 385 | &psxcd_device::cdcmd_reset, |
| 386 | &psxcd_device::cdcmd_illegal1d, |
| 387 | &psxcd_device::cdcmd_readtoc |
397 | 388 | }; |
398 | 389 | |
399 | | // |
400 | | // |
401 | | // |
402 | | |
403 | | void psxcd_device::write_command(const unsigned char byte) |
| 390 | void psxcd_device::write_command(UINT8 byte) |
404 | 391 | { |
405 | | assert(byte<num_commands); |
406 | | (this->*cmd_table[byte].func)(); |
| 392 | if(byte > 31) |
| 393 | illegalcmd(byte); |
| 394 | else |
| 395 | (this->*cmd_table[byte])(); |
407 | 396 | m_param_count = 0; |
408 | 397 | } |
409 | 398 | |
410 | | // |
411 | | // |
412 | | // |
413 | | |
414 | 399 | void psxcd_device::cdcmd_sync() |
415 | 400 | { |
416 | | #ifdef debug_cdrom |
417 | | printf("cdrom: sync\n"); |
418 | | #endif |
| 401 | verboselog(machine(), 1, "psxcd: sync\n"); |
419 | 402 | |
420 | 403 | stop_read(); |
421 | 404 | send_result(intr_acknowledge); |
r22505 | r22506 | |
423 | 406 | |
424 | 407 | void psxcd_device::cdcmd_nop() |
425 | 408 | { |
426 | | #ifdef debug_cdrom |
427 | | printf("cdrom: nop\n"); |
428 | | #endif |
| 409 | verboselog(machine(), 1, "psxcd: nop\n"); |
429 | 410 | |
430 | | //stop_read(); |
431 | | |
432 | 411 | if (!open) |
433 | 412 | status &= ~status_shellopen; |
434 | 413 | |
r22505 | r22506 | |
437 | 416 | |
438 | 417 | void psxcd_device::cdcmd_setloc() |
439 | 418 | { |
440 | | #ifdef debug_cdrom |
441 | | printf("cdrom: setloc %08x:%08x:%08x\n", |
442 | | cmdbuf[0], |
443 | | cmdbuf[1], |
444 | | cmdbuf[2]); |
445 | | #endif |
| 419 | verboselog(machine(), 1, "psxcd: setloc %08x:%08x:%08x\n", cmdbuf[0], cmdbuf[1], cmdbuf[2]); |
446 | 420 | |
447 | 421 | stop_read(); |
448 | 422 | |
r22505 | r22506 | |
455 | 429 | if ((l.b[M]>0) || (l.b[S]>=2)) |
456 | 430 | loc.w=l.w; |
457 | 431 | else |
458 | | logerror("setloc out of range: %02d:%02d:%02d\n",l.b[M],l.b[S],l.b[F]); |
| 432 | verboselog(machine(), 0, "psxcd: setloc out of range: %02d:%02d:%02d\n",l.b[M],l.b[S],l.b[F]); |
459 | 433 | |
460 | 434 | send_result(intr_complete); |
461 | 435 | } |
r22505 | r22506 | |
469 | 443 | if (!curpos.w) |
470 | 444 | curpos.b[S] = 2; |
471 | 445 | |
472 | | #ifdef debug_cdrom |
473 | | printf("cdrom: play %02x %02x %02x => %d\n", loc.b[M], loc.b[S], loc.b[F], msf_to_lba_ps(loc.w)); |
474 | | #endif |
| 446 | verboselog(machine(), 1, "psxcd: play %02x %02x %02x => %d\n", loc.b[M], loc.b[S], loc.b[F], msf_to_lba_ps(loc.w)); |
475 | 447 | |
476 | 448 | stop_read(); |
477 | 449 | start_play(); |
r22505 | r22506 | |
480 | 452 | |
481 | 453 | void psxcd_device::cdcmd_forward() |
482 | 454 | { |
483 | | #ifdef debug_cdrom |
484 | | printf("cdrom: forward\n"); |
485 | | #endif |
| 455 | verboselog(machine(), 1, "psxcd: forward\n"); |
486 | 456 | } |
487 | 457 | |
488 | 458 | void psxcd_device::cdcmd_backward() |
489 | 459 | { |
490 | | #ifdef debug_cdrom |
491 | | printf("cdrom: backward\n"); |
492 | | #endif |
| 460 | verboselog(machine(), 1, "psxcd: backward\n"); |
493 | 461 | } |
494 | 462 | |
495 | 463 | void psxcd_device::cdcmd_readn() |
496 | 464 | { |
497 | 465 | if(!open) |
498 | 466 | { |
499 | | #ifdef debug_cdrom |
500 | | printf("cdrom: readn\n"); |
501 | | #endif |
| 467 | verboselog(machine(), 1, "psxcd: readn\n"); |
502 | 468 | |
503 | 469 | curpos.w=loc.w; |
504 | 470 | |
505 | 471 | stop_read(); |
506 | 472 | start_read(); |
507 | | send_result(intr_complete); |
508 | 473 | } else |
509 | 474 | { |
510 | 475 | send_result(intr_diskerror); |
r22505 | r22506 | |
513 | 478 | |
514 | 479 | void psxcd_device::cdcmd_standby() |
515 | 480 | { |
516 | | #ifdef debug_cdrom |
517 | | printf("cdrom: standby\n"); |
518 | | #endif |
| 481 | verboselog(machine(), 1, "psxcd: standby\n"); |
519 | 482 | |
520 | 483 | stop_read(); |
521 | 484 | send_result(intr_acknowledge); |
r22505 | r22506 | |
523 | 486 | |
524 | 487 | void psxcd_device::cdcmd_stop() |
525 | 488 | { |
526 | | #ifdef debug_cdrom |
527 | | printf("cdrom: stop\n"); |
528 | | #endif |
| 489 | verboselog(machine(), 1, "psxcd: stop\n"); |
529 | 490 | |
530 | 491 | stop_read(); |
531 | 492 | send_result(intr_acknowledge); |
r22505 | r22506 | |
533 | 494 | |
534 | 495 | void psxcd_device::cdcmd_pause() |
535 | 496 | { |
536 | | #ifdef debug_cdrom |
537 | | printf("cdrom: pause\n"); |
538 | | #endif |
| 497 | verboselog(machine(), 1, "psxcd: pause\n"); |
539 | 498 | |
540 | 499 | stop_read(); |
541 | 500 | |
r22505 | r22506 | |
544 | 503 | |
545 | 504 | void psxcd_device::cdcmd_init() |
546 | 505 | { |
547 | | #ifdef debug_cdrom |
548 | | printf("cdrom: init\n"); |
549 | | #endif |
| 506 | verboselog(machine(), 1, "psxcd: init\n"); |
550 | 507 | |
551 | 508 | stop_read(); |
552 | 509 | mode=0; |
553 | | sr|=0x10; |
| 510 | m_regs.sr |= 0x10; |
554 | 511 | |
555 | 512 | send_result(intr_acknowledge); |
556 | 513 | } |
557 | 514 | |
558 | 515 | void psxcd_device::cdcmd_mute() |
559 | 516 | { |
560 | | #ifdef debug_cdrom |
561 | | printf("cdrom: mute\n"); |
562 | | #endif |
| 517 | verboselog(machine(), 1, "psxcd: mute\n"); |
563 | 518 | |
564 | 519 | m_mute = true; |
565 | 520 | send_result(intr_acknowledge); |
r22505 | r22506 | |
567 | 522 | |
568 | 523 | void psxcd_device::cdcmd_demute() |
569 | 524 | { |
570 | | #ifdef debug_cdrom |
571 | | printf("cdrom: demute\n"); |
572 | | #endif |
| 525 | verboselog(machine(), 1, "psxcd: demute\n"); |
573 | 526 | |
574 | 527 | m_mute = false; |
575 | 528 | send_result(intr_acknowledge); |
r22505 | r22506 | |
577 | 530 | |
578 | 531 | void psxcd_device::cdcmd_setfilter() |
579 | 532 | { |
580 | | #ifdef debug_cdrom |
581 | | printf("cdrom: setfilter %08x,%08x\n",cmdbuf[0],cmdbuf[1]); |
582 | | #endif |
| 533 | verboselog(machine(), 1, "psxcd: setfilter %08x,%08x\n",cmdbuf[0],cmdbuf[1]); |
583 | 534 | |
584 | 535 | filter_file=cmdbuf[0]; |
585 | 536 | filter_channel=cmdbuf[1]; |
r22505 | r22506 | |
589 | 540 | |
590 | 541 | void psxcd_device::cdcmd_setmode() |
591 | 542 | { |
592 | | #ifdef debug_cdrom |
593 | | printf("cdrom: setmode %08x\n",cmdbuf[0]); |
594 | | #endif |
| 543 | verboselog(machine(), 1, "psxcd: setmode %08x\n",cmdbuf[0]); |
595 | 544 | |
596 | 545 | mode=cmdbuf[0]; |
597 | | |
598 | | switch ((mode&mode_size_mask)>>mode_size_shift) |
599 | | { |
600 | | case 1: |
601 | | secsize=2328; |
602 | | secskip=24; |
603 | | break; |
604 | | |
605 | | case 2: |
606 | | secsize=2340; |
607 | | secskip=12; |
608 | | break; |
609 | | |
610 | | default: |
611 | | secsize=2048; |
612 | | secskip=24; |
613 | | break; |
614 | | } |
615 | | |
616 | 546 | send_result(intr_complete); |
617 | 547 | } |
618 | 548 | |
r22505 | r22506 | |
628 | 558 | 0 |
629 | 559 | }; |
630 | 560 | |
631 | | #ifdef debug_cdrom |
632 | | printf("cdrom: getparam [%02x %02x %02x %02x %02x %02x]\n", |
633 | | data[0], |
634 | | data[1], |
635 | | data[2], |
636 | | data[3], |
637 | | data[4], |
638 | | data[5]); |
639 | | #endif |
| 561 | verboselog(machine(), 1, "psxcd: getparam [%02x %02x %02x %02x %02x %02x]\n", |
| 562 | data[0], data[1], data[2], data[3], data[4], data[5]); |
640 | 563 | |
641 | 564 | send_result(intr_complete,data,6); |
642 | 565 | } |
r22505 | r22506 | |
662 | 585 | |
663 | 586 | void psxcd_device::cdcmd_getlocl() |
664 | 587 | { |
665 | | #ifdef debug_cdrom |
666 | | printf("cdrom: getlocl\n"); |
667 | | #endif |
| 588 | verboselog(machine(), 1, "psxcd: getlocl [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
| 589 | lastsechdr[0], lastsechdr[1], lastsechdr[2], lastsechdr[3], |
| 590 | lastsechdr[4], lastsechdr[5], lastsechdr[6], lastsechdr[7]); |
668 | 591 | |
669 | | #ifdef debug_cdrom |
670 | | printf("cdrom: getlocl [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
671 | | lastsechdr[0], |
672 | | lastsechdr[1], |
673 | | lastsechdr[2], |
674 | | lastsechdr[3], |
675 | | lastsechdr[4], |
676 | | lastsechdr[5], |
677 | | lastsechdr[6], |
678 | | lastsechdr[7]); |
679 | | #endif |
680 | | |
681 | 592 | send_result(intr_complete,lastsechdr,8); |
682 | 593 | } |
683 | 594 | |
r22505 | r22506 | |
700 | 611 | decimal_to_bcd(loc.b[F]) // aframe |
701 | 612 | }; |
702 | 613 | |
703 | | //unsigned char data[8]={ 2,1,0,0xff,0xff,0xff,0xff,0xff }; |
| 614 | verboselog(machine(), 1, "psxcd: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
| 615 | data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); |
704 | 616 | |
705 | | #ifdef debug_cdrom |
706 | | printf("cdrom: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
707 | | data[0], |
708 | | data[1], |
709 | | data[2], |
710 | | data[3], |
711 | | data[4], |
712 | | data[5], |
713 | | data[6], |
714 | | data[7]); |
715 | | #endif |
716 | | |
717 | 617 | send_result(intr_complete,data,8); |
718 | 618 | } |
719 | 619 | |
720 | | void psxcd_device::cdcmd_illegal() |
721 | | { |
722 | | assert(0); |
723 | | } |
724 | | |
725 | 620 | void psxcd_device::cdcmd_gettn() |
726 | 621 | { |
727 | | #ifdef debug_cdrom |
728 | | printf("cdrom: gettn\n"); |
729 | | #endif |
| 622 | verboselog(machine(), 1, "psxcd: gettn\n"); |
730 | 623 | |
731 | 624 | |
732 | 625 | if(!open) |
r22505 | r22506 | |
738 | 631 | decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle)) |
739 | 632 | }; |
740 | 633 | |
741 | | //stop_read(); |
742 | 634 | send_result(intr_complete,data,3); |
743 | 635 | } |
744 | 636 | else |
r22505 | r22506 | |
767 | 659 | decimal_to_bcd(trkstart.b[S]) |
768 | 660 | }; |
769 | 661 | |
770 | | #ifdef debug_cdrom |
771 | | printf("cdrom: gettd %02x [%02x %02x %02x]\n", |
772 | | cmdbuf[0], |
773 | | data[0], |
774 | | data[1], |
775 | | data[2]); |
776 | | #endif |
| 662 | verboselog(machine(), 1, "psxcd: gettd %02x [%02x %02x %02x]\n", cmdbuf[0], data[0], data[1], data[2]); |
777 | 663 | |
778 | | //stop_read(); |
779 | 664 | send_result(intr_acknowledge,data,3); |
780 | 665 | } |
781 | 666 | else |
r22505 | r22506 | |
787 | 672 | |
788 | 673 | void psxcd_device::cdcmd_seekl() |
789 | 674 | { |
790 | | #ifdef debug_cdrom |
791 | | printf("cdrom: seekl [%02d:%02d:%02d]\n",loc.b[M],loc.b[S],loc.b[F]); |
792 | | #endif |
| 675 | verboselog(machine(), 1, "psxcd: seekl [%02d:%02d:%02d]\n", loc.b[M], loc.b[S], loc.b[F]); |
793 | 676 | |
794 | 677 | curpos.w=loc.w; |
795 | 678 | |
r22505 | r22506 | |
798 | 681 | |
799 | 682 | void psxcd_device::cdcmd_seekp() |
800 | 683 | { |
801 | | #ifdef debug_cdrom |
802 | | printf("cdrom: seekp\n"); |
803 | | #endif |
| 684 | verboselog(machine(), 1, "psxcd: seekp\n"); |
804 | 685 | |
805 | 686 | curpos.w=loc.w; |
806 | 687 | |
r22505 | r22506 | |
809 | 690 | |
810 | 691 | void psxcd_device::cdcmd_test() |
811 | 692 | { |
812 | | #ifdef debug_cdrom |
813 | | printf("cdrom: test %08x\n",cmdbuf[0]); |
814 | | #endif |
| 693 | verboselog(machine(), 1, "psxcd: test %08x\n",cmdbuf[0]); |
815 | 694 | |
816 | 695 | static unsigned char data[4]= |
817 | 696 | { |
r22505 | r22506 | |
826 | 705 | |
827 | 706 | void psxcd_device::cdcmd_id() |
828 | 707 | { |
829 | | #ifdef debug_cdrom |
830 | | printf("cdrom: id\n"); |
831 | | #endif |
| 708 | verboselog(machine(), 1, "psxcd: id\n"); |
832 | 709 | |
833 | 710 | if (!open) |
834 | 711 | { |
r22505 | r22506 | |
854 | 731 | |
855 | 732 | void psxcd_device::cdcmd_reads() |
856 | 733 | { |
857 | | curpos.w=loc.w; |
| 734 | if(!open) |
| 735 | { |
| 736 | verboselog(machine(), 1, "psxcd: reads\n"); |
858 | 737 | |
859 | | #ifdef skip_reads |
860 | | #ifdef debug_cdrom |
861 | | log("cdrom: reads [SKIPPING - RETURN COMPLETE]\n"); |
862 | | #endif |
| 738 | curpos.w=loc.w; |
863 | 739 | |
864 | | send_result(intr_complete); |
865 | | #else |
866 | | #ifdef debug_cdrom |
867 | | printf("cdrom: reads\n"); |
868 | | #endif |
869 | | |
870 | 740 | stop_read(); |
871 | | start_streaming(); |
872 | | #endif |
| 741 | start_read(); |
| 742 | } else |
| 743 | { |
| 744 | send_result(intr_diskerror); |
| 745 | } |
873 | 746 | } |
874 | 747 | |
875 | 748 | void psxcd_device::cdcmd_reset() |
876 | 749 | { |
877 | | #ifdef debug_cdrom |
878 | | printf("cdrom: reset\n"); |
879 | | #endif |
| 750 | verboselog(machine(), 1, "psxcd: reset\n"); |
880 | 751 | } |
881 | 752 | |
882 | 753 | void psxcd_device::cdcmd_readtoc() |
883 | 754 | { |
884 | | #ifdef debug_cdrom |
885 | | printf("cdrom: readtoc\n"); |
886 | | #endif |
| 755 | verboselog(machine(), 1, "psxcd: readtoc\n"); |
887 | 756 | |
888 | | static unsigned char data[4]= |
889 | | { |
890 | | 0x00, |
891 | | 0x00, |
892 | | 0xff, |
893 | | 0xfe |
894 | | }; |
895 | | |
896 | | send_result(intr_complete|0x10,data,2); |
| 757 | send_result(intr_complete); |
897 | 758 | } |
898 | 759 | |
899 | | // |
900 | | // |
901 | | // |
902 | | |
903 | | void psxcd_device::cmd_complete(command_result *res) |
| 760 | void psxcd_device::cdcmd_unknown12() |
904 | 761 | { |
905 | | bool doint=((res->res&0x10)==0); |
906 | | #ifdef debug_cdrom |
907 | | command_result *rf; |
908 | | #endif |
909 | | |
910 | | if (doint) |
| 762 | verboselog(machine(), 1, "psxcd: unknown 12\n"); |
| 763 | // set session? readt? |
| 764 | if(cmdbuf[0] == 1) |
| 765 | send_result(intr_complete); |
| 766 | else |
911 | 767 | { |
912 | | m_irq_handler(1); |
| 768 | status |= status_error; |
| 769 | send_result(intr_diskerror); |
913 | 770 | } |
| 771 | } |
914 | 772 | |
915 | | add_result(res); |
| 773 | void psxcd_device::cdcmd_illegal17() |
| 774 | { |
| 775 | illegalcmd(0x17); // set clock? |
| 776 | } |
916 | 777 | |
917 | | #ifdef debug_cdrom |
918 | | if (doint) |
919 | | { |
920 | | printf("cdrom: irq ["); |
921 | | for (rf=res_queue; ((rf) && (rf->next)); rf=rf->next); |
922 | | printf("%d ",rf->res); |
923 | | printf("]\n"); |
924 | | } |
925 | | #endif |
| 778 | void psxcd_device::cdcmd_illegal18() |
| 779 | { |
| 780 | illegalcmd(0x18); // get clock? |
926 | 781 | } |
927 | 782 | |
928 | | // |
929 | | // |
930 | | // |
| 783 | void psxcd_device::cdcmd_illegal1d() |
| 784 | { |
| 785 | illegalcmd(0x1d); // read q subchannel |
| 786 | } |
931 | 787 | |
932 | | void psxcd_device::add_result(command_result *res) |
| 788 | void psxcd_device::illegalcmd(UINT8 cmd) |
933 | 789 | { |
| 790 | verboselog(machine(), 0, "psxcd: unimplemented cd command %02x\n", cmd); |
| 791 | command_result *res=global_alloc(command_result); |
| 792 | res->res=intr_diskerror; |
| 793 | res->data[0]=status | status_error; |
| 794 | res->data[1]=0x40; //invalid command |
| 795 | res->sz=2; |
| 796 | cmd_complete(res); |
| 797 | } |
| 798 | |
| 799 | void psxcd_device::cmd_complete(command_result *res) |
| 800 | { |
934 | 801 | command_result *rf; |
935 | 802 | |
| 803 | verboselog(machine(), 1, "psxcd: irq [%d]\n", res->res); |
| 804 | |
936 | 805 | if (res_queue) |
937 | 806 | { |
938 | 807 | for (rf=res_queue; rf->next; rf=rf->next); |
939 | 808 | rf->next=res; |
940 | | } else |
| 809 | } |
| 810 | else |
941 | 811 | { |
942 | | res_queue=res; |
| 812 | res_queue = res; |
| 813 | m_regs.ir = res_queue->res & m_regs.imr; // or should it not trigger a masked irq? |
| 814 | if(m_regs.ir) |
| 815 | m_irq_handler(1); |
| 816 | m_regs.sr |= 0x20; |
943 | 817 | } |
944 | | |
945 | | res->next=NULL; |
| 818 | res->next = NULL; |
946 | 819 | } |
947 | 820 | |
948 | | // |
949 | | // |
950 | | // |
951 | | |
952 | | void psxcd_device::send_result(const unsigned int res, |
953 | | const unsigned char *data, |
954 | | const unsigned int sz, |
955 | | const unsigned int delay) |
| 821 | void psxcd_device::send_result(UINT8 res, UINT8 *data, int sz, int delay) |
956 | 822 | { |
957 | 823 | command_result *cr=global_alloc(command_result); |
958 | 824 | |
r22505 | r22506 | |
982 | 848 | add_system_event(event_cmd_complete, delay, (void *)cr); |
983 | 849 | } |
984 | 850 | |
985 | | // |
986 | | // |
987 | | // |
988 | | |
989 | 851 | void psxcd_device::start_dma(UINT8 *mainram, UINT32 size) |
990 | 852 | { |
991 | | if ((int)size>secleft) |
992 | | { |
993 | | logerror("cdrom: dma past end of sector (secleft=%d sz=%d)\n",secleft,size); |
994 | | } |
| 853 | verboselog(machine(), 1, "psxcd: start dma %d bytes at %d\n", size, m_transcurr); |
995 | 854 | |
996 | | // printf("cdrom: start dma %d bytes, %d remaining, secptr %p\n", size, secleft, secptr); |
997 | | #ifdef debug_cdrom |
998 | | if (size==12) |
999 | | { |
1000 | | char poo[1024],*pp=poo; |
1001 | | for (unsigned int i=0; i<12; i++) |
1002 | | { |
1003 | | sprintf(pp,"%02x ",secptr[i]); |
1004 | | pp+=3; |
1005 | | } |
1006 | | printf("cdrom: data=%s\n",poo); |
1007 | | } |
1008 | | #endif |
| 855 | if(!m_dmaload) |
| 856 | return; |
1009 | 857 | |
1010 | | memcpy(mainram, secptr, size); |
1011 | | memset(secptr, 0xff, size); |
| 858 | if(size > (raw_sector_size - m_transcurr)) |
| 859 | size = (raw_sector_size - m_transcurr); |
1012 | 860 | |
1013 | | secptr += size; |
1014 | | secleft -= size; |
1015 | | |
1016 | | if (secleft<0) secleft=0; |
1017 | | if (secleft==0) sr&=~0x40; |
| 861 | memcpy(mainram, &m_transbuf[m_transcurr], size); |
| 862 | m_transcurr += size; |
| 863 | if(raw_sector_size <= m_transcurr) |
| 864 | m_regs.sr &= ~0x40; |
1018 | 865 | } |
1019 | 866 | |
1020 | | bool psxcd_device::read_next_sector() |
1021 | | { |
1022 | | UINT32 pos=msf_to_lba_ps(curpos.w); |
1023 | | unsigned char *buf=secbuf[sechead]; |
1024 | | |
1025 | | // printf("read_next_sector: sec %d, sechead %d, raw_sector_size %d\n", pos, sechead, raw_sector_size); |
1026 | | if (cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE)) |
1027 | | { |
1028 | | // printf("buf contents = %02x %02x | %02x %02x\n", buf[0], buf[1], buf[0x20], buf[0x21]); |
1029 | | |
1030 | | sechead=(sechead+1)&(sector_buffer_size-1); |
1031 | | |
1032 | | memcpy(lastsechdr,&secbuf[sectail][12],8); |
1033 | | |
1034 | | return true; |
1035 | | } else |
1036 | | { |
1037 | | return false; |
1038 | | } |
1039 | | } |
1040 | | |
1041 | | // |
1042 | | // |
1043 | | // |
1044 | | |
1045 | 867 | void psxcd_device::read_sector() |
1046 | 868 | { |
1047 | 869 | next_read_event=-1; |
1048 | 870 | |
1049 | 871 | if (status & status_reading) |
1050 | 872 | { |
1051 | | bool isend=false; |
1052 | | |
1053 | | if (read_next_sector()) |
| 873 | bool isend = false; |
| 874 | UINT32 sector = msf_to_lba_ps(curpos.w); |
| 875 | UINT8 *buf = secbuf[sectail]; |
| 876 | if (cdrom_read_data(m_cdrom_handle, sector, buf, CD_TRACK_RAW_DONTCARE)) |
1054 | 877 | { |
1055 | | unsigned char *rawsec; |
| 878 | subheader *sub=(subheader *)(buf+16); |
| 879 | memcpy(lastsechdr, buf+12, 8); |
1056 | 880 | |
1057 | | if ((mode&mode_adpcm) && (streaming)) |
| 881 | verboselog(machine(), 2, "psxcd: subheader file=%02x chan=%02x submode=%02x coding=%02x [%02x%02x%02x%02x]\n", |
| 882 | sub->file, sub->channel, sub->submode, sub->coding, buf[0xc], buf[0xd], buf[0xe], buf[0xf]); |
| 883 | |
| 884 | if ((mode & mode_adpcm) && (sub->submode & submode_audio)) |
1058 | 885 | { |
1059 | | rawsec=secbuf[sectail]; |
1060 | | secptr=rawsec+24; |
1061 | | secleft=2048; |
| 886 | if ((sub->submode & submode_eof) && (mode & mode_autopause)) |
| 887 | { |
| 888 | isend=true; |
| 889 | //printf("end of file\n"); |
| 890 | } |
| 891 | if((!(mode & mode_channel) || |
| 892 | ((sub->file == filter_file) && (sub->channel == filter_channel))) && !m_mute) |
| 893 | m_spu->play_xa(0,buf+16); |
1062 | 894 | } |
1063 | 895 | else |
1064 | 896 | { |
1065 | | rawsec=secbuf[sectail]; |
1066 | | secptr=rawsec+secskip; |
1067 | | secleft=secsize; |
1068 | | } |
| 897 | command_result *res=global_alloc(command_result); |
| 898 | res->res=intr_dataready; |
| 899 | res->data[0]=status; |
| 900 | res->sz=1; |
| 901 | cmd_complete(res); |
| 902 | sectail++; |
| 903 | sectail %= sector_buffer_size; |
1069 | 904 | |
1070 | | sectail=(sectail+1)&(sector_buffer_size-1); |
1071 | | |
1072 | | subheader *sub=(subheader *)(rawsec+16); |
1073 | | |
1074 | | #ifdef dump_subheader |
1075 | | printf("cdrom: subheader file=%02x chan=%02x submode=%02x coding=%02x [%02x%02x%02x%02x]\n", |
1076 | | sub->file, |
1077 | | sub->channel, |
1078 | | sub->submode, |
1079 | | sub->coding, |
1080 | | rawsec[0xc], |
1081 | | rawsec[0xd], |
1082 | | rawsec[0xe], |
1083 | | rawsec[0xf]); |
1084 | | #endif |
1085 | | |
1086 | | status&=~status_playing; |
1087 | | bool isxa=((mode&mode_adpcm) && (sub->submode&submode_audio)); |
1088 | | |
1089 | | if (((mode&mode_channel)==0) || |
1090 | | ((sub->file==filter_file) && (sub->channel==filter_channel))) |
1091 | | { |
1092 | | if (isxa) |
1093 | | { |
1094 | | if (sub->submode&submode_eof) |
1095 | | { |
1096 | | isend=true; |
1097 | | //printf("end of file\n"); |
1098 | | } |
1099 | | m_spu->play_xa(0,rawsec+16); |
1100 | | |
1101 | | status|=status_playing; |
1102 | | } |
| 905 | if(sectail == sechead) |
| 906 | verboselog(machine(), 0, "psxcd: sector buffer overrun\n"); |
1103 | 907 | } |
1104 | 908 | |
1105 | | if ((mode&mode_autopause)==0) |
1106 | | isend=false; |
1107 | | |
1108 | | // |
1109 | | |
1110 | 909 | curpos.b[F]++; |
1111 | 910 | if (curpos.b[F]==75) |
1112 | 911 | { |
r22505 | r22506 | |
1120 | 919 | } |
1121 | 920 | |
1122 | 921 | loc.w=curpos.w; |
1123 | | |
1124 | | sr|=0x40; |
1125 | | |
1126 | | if(!(streaming && isxa)) |
1127 | | { |
1128 | | command_result *res=global_alloc(command_result); |
1129 | | res->res=isend?intr_dataend:intr_dataready; |
1130 | | res->data[0]=status; |
1131 | | res->sz=1; |
1132 | | cmd_complete(res); |
1133 | | } |
1134 | 922 | } |
| 923 | else |
| 924 | isend = true; |
1135 | 925 | |
1136 | 926 | if (! isend) |
1137 | 927 | { |
r22505 | r22506 | |
1141 | 931 | next_sector_t+=cyc; |
1142 | 932 | |
1143 | 933 | next_read_event = add_system_event(event_read_sector, cyc, NULL); |
1144 | | |
1145 | | //read_next_sector(); |
1146 | 934 | } else |
1147 | 935 | { |
1148 | | #ifdef debug_cdrom |
1149 | | printf("autopause xa\n"); |
1150 | | #endif |
| 936 | verboselog(machine(), 1, "psxcd: autopause xa\n"); |
| 937 | |
| 938 | command_result *res=global_alloc(command_result); |
| 939 | res->res=intr_dataend; |
| 940 | res->data[0]=status; |
| 941 | res->sz=1; |
| 942 | cmd_complete(res); |
1151 | 943 | stop_read(); |
1152 | 944 | } |
1153 | 945 | } |
1154 | 946 | } |
1155 | 947 | |
1156 | | // |
1157 | | // |
1158 | | // |
1159 | | |
1160 | 948 | void psxcd_device::play_sector() |
1161 | 949 | { |
1162 | 950 | next_read_event=-1; |
1163 | 951 | |
1164 | 952 | if (status&status_playing) |
1165 | 953 | { |
1166 | | if(!m_mute) |
1167 | | m_spu->play_cdda(0,secbuf[sectail]); |
1168 | | sectail=(sectail+1)&(sector_buffer_size-1); |
| 954 | UINT32 sector = msf_to_lba_ps(curpos.w); |
1169 | 955 | |
| 956 | if(cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_AUDIO)) |
| 957 | { |
| 958 | if(!m_mute) |
| 959 | m_spu->play_cdda(0, secbuf[sectail]); |
| 960 | } |
| 961 | else |
| 962 | { |
| 963 | if(!cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_RAW_DONTCARE)) |
| 964 | { |
| 965 | stop_read(); // assume we've reached the end |
| 966 | command_result *res=global_alloc(command_result); |
| 967 | res->res=intr_dataend; |
| 968 | res->data[0]=status; |
| 969 | res->sz=1; |
| 970 | cmd_complete(res); |
| 971 | return; |
| 972 | } |
| 973 | } |
| 974 | |
1170 | 975 | curpos.b[F]++; |
1171 | 976 | if (curpos.b[F]==75) |
1172 | 977 | { |
r22505 | r22506 | |
1180 | 985 | } |
1181 | 986 | |
1182 | 987 | loc.w=curpos.w; |
| 988 | sector++; |
| 989 | sectail++; |
| 990 | sectail %= sector_buffer_size; |
1183 | 991 | |
1184 | | // |
1185 | | |
1186 | | UINT32 sector = msf_to_lba_ps(loc.w); |
1187 | | |
1188 | 992 | if (mode&mode_autopause) |
1189 | 993 | { |
1190 | 994 | if (sector>=autopause_sector) |
1191 | 995 | { |
1192 | | #ifdef debug_cdrom |
1193 | | printf("autopause cdda\n"); |
1194 | | #endif |
| 996 | verboselog(machine(), 1, "psxcd: autopause cdda\n"); |
| 997 | |
1195 | 998 | stop_read(); |
1196 | 999 | command_result *res=global_alloc(command_result); |
1197 | 1000 | res->res=intr_dataend; |
r22505 | r22506 | |
1237 | 1040 | next_sector_t+=cyc>>1; |
1238 | 1041 | |
1239 | 1042 | next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL); |
1240 | | |
1241 | | if(!read_next_sector()) |
1242 | | { |
1243 | | stop_read(); // assume we've reached the end |
1244 | | command_result *res=global_alloc(command_result); |
1245 | | res->res=intr_dataend; |
1246 | | res->data[0]=status; |
1247 | | res->sz=1; |
1248 | | cmd_complete(res); |
1249 | | } |
1250 | 1043 | } |
1251 | 1044 | } |
1252 | 1045 | |
1253 | | |
1254 | | // |
1255 | | // |
1256 | | // |
1257 | | |
1258 | | void psxcd_device::preread_sector() |
| 1046 | void psxcd_device::start_read() |
1259 | 1047 | { |
1260 | | UINT64 next_clock; |
1261 | | int type; |
1262 | | next_read_event=-1; |
| 1048 | UINT32 sector = msf_to_lba_ps(curpos.w); |
1263 | 1049 | |
1264 | | UINT32 pos=msf_to_lba_ps(curpos.w); |
1265 | | // |
1266 | | if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, pos + 150)) == CD_TRACK_AUDIO)) |
| 1050 | assert((status&(status_reading|status_playing))==0); |
| 1051 | |
| 1052 | if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, sector + 150)) == CD_TRACK_AUDIO)) |
1267 | 1053 | { |
| 1054 | stop_read(); |
1268 | 1055 | command_result *res=global_alloc(command_result); |
1269 | 1056 | res->res=intr_diskerror; |
1270 | 1057 | res->data[0]=status | status_error; |
r22505 | r22506 | |
1273 | 1060 | cmd_complete(res); |
1274 | 1061 | return; |
1275 | 1062 | } |
| 1063 | send_result(intr_complete); |
| 1064 | status |= status_reading; |
1276 | 1065 | |
1277 | | unsigned char *buf=secbuf[sechead]; |
1278 | | if (! cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE)) |
1279 | | { |
1280 | | next_clock=(m_sysclock/60); |
1281 | | type=event_preread_sector; |
1282 | | |
1283 | | unsigned int cyc=read_sector_cycles; |
1284 | | if (mode&mode_double_speed) cyc>>=1; |
1285 | | next_sector_t=next_clock+(cyc-preread_delay)+m_maincpu->total_cycles(); |
1286 | | } else |
1287 | | { |
1288 | | memcpy(lastsechdr,buf+12,8); |
1289 | | |
1290 | | // |
1291 | | |
1292 | | command_result *res=global_alloc(command_result); |
1293 | | res->res=intr_complete; |
1294 | | res->data[0]=status; |
1295 | | res->sz=1; |
1296 | | |
1297 | | #ifdef debug_cdrom |
1298 | | printf("cdrom: read acknowledge\n"); |
1299 | | #endif |
1300 | | |
1301 | | cmd_complete(res); |
1302 | | |
1303 | | // |
1304 | | |
1305 | | next_clock=next_sector_t - m_maincpu->total_cycles(); |
1306 | | type=event_read_sector; |
1307 | | |
1308 | | //read_next_sector(); |
1309 | | } |
1310 | | |
1311 | | next_read_event = add_system_event(type, next_clock, NULL); |
1312 | | } |
1313 | | |
1314 | | // |
1315 | | // |
1316 | | // |
1317 | | |
1318 | | void psxcd_device::start_read() |
1319 | | { |
1320 | | #ifdef debug_cdrom |
1321 | | printf("cdrom: start read\n"); |
1322 | | #endif |
1323 | | |
1324 | | assert((status&(status_reading|status_playing))==0); |
1325 | | |
1326 | | status|=status_reading; |
1327 | | |
1328 | 1066 | sechead=sectail=0; |
1329 | 1067 | |
1330 | 1068 | unsigned int cyc=read_sector_cycles; |
r22505 | r22506 | |
1335 | 1073 | systime+=start_read_delay; |
1336 | 1074 | |
1337 | 1075 | next_sector_t=systime+cyc; |
1338 | | next_read_event = add_system_event(event_preread_sector, start_read_delay+preread_delay, NULL); |
| 1076 | next_read_event = add_system_event(event_read_sector, start_read_delay+preread_delay, NULL); |
1339 | 1077 | } |
1340 | 1078 | |
1341 | | // |
1342 | | // |
1343 | | // |
1344 | | |
1345 | | void psxcd_device::start_streaming() |
1346 | | { |
1347 | | assert(! streaming); |
1348 | | |
1349 | | streaming=true; |
1350 | | start_read(); |
1351 | | } |
1352 | | |
1353 | | // |
1354 | | // |
1355 | | // |
1356 | | |
1357 | 1079 | void psxcd_device::start_play() |
1358 | 1080 | { |
1359 | | #ifdef debug_cdrom |
1360 | | printf("cdrom: start play\n"); |
1361 | | #endif |
| 1081 | UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150); |
1362 | 1082 | |
| 1083 | if(cdrom_get_track_type(m_cdrom_handle, track) != CD_TRACK_AUDIO) |
| 1084 | verboselog(machine(), 0, "psxcd: playing data track\n"); |
| 1085 | |
1363 | 1086 | status|=status_playing; |
1364 | 1087 | |
1365 | 1088 | sechead=sectail=0; |
1366 | 1089 | |
1367 | 1090 | if (mode&mode_autopause) |
1368 | 1091 | { |
1369 | | UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150); |
1370 | 1092 | autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + cdrom_get_toc(m_cdrom_handle)->tracks[track].frames; |
1371 | 1093 | // printf("pos=%d auto=%d\n",pos,autopause_sector); |
1372 | 1094 | } |
r22505 | r22506 | |
1378 | 1100 | next_sector_t+=cyc>>1; |
1379 | 1101 | |
1380 | 1102 | next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL); |
1381 | | |
1382 | | read_next_sector(); |
1383 | 1103 | } |
1384 | 1104 | |
1385 | | // |
1386 | | // |
1387 | | // |
1388 | | |
1389 | 1105 | void psxcd_device::stop_read() |
1390 | 1106 | { |
1391 | | #ifdef debug_cdrom |
1392 | | if (status&status_reading) |
1393 | | printf("cdrom: stop read\n"); |
1394 | | #endif |
| 1107 | if (status & (status_reading|status_playing)) |
| 1108 | verboselog(machine(), 1, "psxcd: stop read\n"); |
| 1109 | |
1395 | 1110 | status&=~(status_reading|status_playing); |
1396 | | streaming=false; |
1397 | 1111 | |
1398 | 1112 | if (next_read_event != -1) |
1399 | 1113 | { |
r22505 | r22506 | |
1407 | 1121 | m_spu->flush_cdda(sector); |
1408 | 1122 | } |
1409 | 1123 | |
1410 | | // |
1411 | | // |
1412 | | // |
1413 | 1124 | void psxcd_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) |
1414 | 1125 | { |
1415 | 1126 | if (!m_timerinuse[tid]) |
1416 | 1127 | { |
1417 | | printf("cdrom:: timer fired for free event\n"); |
| 1128 | verboselog(machine(), 0, "psxcd: timer fired for free event\n"); |
1418 | 1129 | return; |
1419 | 1130 | } |
1420 | 1131 | |
r22505 | r22506 | |
1423 | 1134 | { |
1424 | 1135 | case event_cmd_complete: |
1425 | 1136 | { |
1426 | | #ifdef debug_cdrom |
1427 | | printf("cdrom:: event cmd complete\n"); |
1428 | | #endif |
| 1137 | verboselog(machine(), 1, "psxcd: event cmd complete\n"); |
1429 | 1138 | |
1430 | 1139 | cmd_complete((command_result *)ptr); |
1431 | 1140 | break; |
1432 | 1141 | } |
1433 | 1142 | |
1434 | | case event_preread_sector: |
1435 | | preread_sector(); |
1436 | | break; |
1437 | | |
1438 | 1143 | case event_read_sector: |
1439 | 1144 | read_sector(); |
1440 | 1145 | break; |
r22505 | r22506 | |
1454 | 1159 | { |
1455 | 1160 | // t is in maincpu clock cycles |
1456 | 1161 | UINT32 hz = m_sysclock / t; |
1457 | | // printf("add_system_event: event type %d for %d hz (using timer %d)\n", ev->type, hz, tnum); |
1458 | 1162 | for(int i = 0; i < MAX_PSXCD_TIMERS; i++) |
1459 | 1163 | { |
1460 | 1164 | if(!m_timerinuse[i]) |