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]) |