trunk/src/mess/machine/psxcddrv.c
| r22065 | r22066 | |
| 1 | | #include "emu.h" |
| 2 | | #include "psxcd.h" |
| 3 | | #include "psxcddrv.h" |
| 4 | | |
| 5 | | //#define debug_mess_driver |
| 6 | | |
| 7 | | // |
| 8 | | // |
| 9 | | // |
| 10 | | |
| 11 | | static const unsigned int num_pf_sectors=32, num_pf_buffers=16; |
| 12 | | |
| 13 | | // |
| 14 | | // |
| 15 | | // |
| 16 | | |
| 17 | | cdrom_driver::cdrom_driver() |
| 18 | | { |
| 19 | | pf_head = 0; |
| 20 | | pf_tail = 0; |
| 21 | | num_pf = 0; |
| 22 | | pf_head_sector = 0; |
| 23 | | pf_status = NULL; |
| 24 | | native_sector_size = raw_sector_size; |
| 25 | | last_pf_status = NULL; |
| 26 | | m_cd = NULL; |
| 27 | | m_machine = NULL; |
| 28 | | |
| 29 | | // printf("cdrom_driver base class init, pf_buffer size is %d\n", num_pf_sectors*num_pf_buffers*raw_sector_size); |
| 30 | | |
| 31 | | pf_buffer=new unsigned char [num_pf_sectors*num_pf_buffers*raw_sector_size]; |
| 32 | | |
| 33 | | timestamp_frequency = 1; |
| 34 | | } |
| 35 | | |
| 36 | | cdrom_driver::~cdrom_driver() |
| 37 | | { |
| 38 | | global_free(pf_buffer); |
| 39 | | } |
| 40 | | |
| 41 | | // |
| 42 | | // |
| 43 | | // |
| 44 | | |
| 45 | | void cdrom_driver::set_native_sector_size(const unsigned int sz) |
| 46 | | { |
| 47 | | native_sector_size=sz; |
| 48 | | } |
| 49 | | |
| 50 | | // |
| 51 | | // |
| 52 | | // |
| 53 | | |
| 54 | | void cdrom_driver::cancel_io() |
| 55 | | { |
| 56 | | if (pf_status) |
| 57 | | { |
| 58 | | pf_status->cancel(); |
| 59 | | pf_status->release(); |
| 60 | | } |
| 61 | | |
| 62 | | pf_status=NULL; |
| 63 | | } |
| 64 | | |
| 65 | | // |
| 66 | | // |
| 67 | | // |
| 68 | | |
| 69 | | void cdrom_driver::prefetch_sector(const unsigned int sec) |
| 70 | | { |
| 71 | | int numpfsec=num_pf*num_pf_sectors, |
| 72 | | pfsec=sec-pf_head_sector; |
| 73 | | |
| 74 | | // printf("prefetch_sector: %d\n", sec); |
| 75 | | |
| 76 | | if ((pfsec<0) || (pfsec>numpfsec)) |
| 77 | | { |
| 78 | | // Sector is not in prefetch buffer, abort current prefetch |
| 79 | | |
| 80 | | if (pf_status) |
| 81 | | { |
| 82 | | pf_status->cancel(); |
| 83 | | pf_status->release(); |
| 84 | | } |
| 85 | | |
| 86 | | // Reset the buffer and begin a new prefetch |
| 87 | | |
| 88 | | pf_head=0; |
| 89 | | pf_tail=0; |
| 90 | | num_pf=1; |
| 91 | | pf_head_sector=sec; |
| 92 | | |
| 93 | | last_pf_status=NULL; |
| 94 | | pf_status=read_sectors(sec, num_pf_sectors, pf_buffer); |
| 95 | | } |
| 96 | | } |
| 97 | | |
| 98 | | // |
| 99 | | // |
| 100 | | // |
| 101 | | |
| 102 | | bool cdrom_driver::is_prefetch_sector_loaded(const unsigned int sec) |
| 103 | | { |
| 104 | | int numpfsec=num_pf*num_pf_sectors, |
| 105 | | pfsec=sec-pf_head_sector; |
| 106 | | |
| 107 | | if ((pfsec<0) || (pfsec>=numpfsec)) |
| 108 | | { |
| 109 | | // Requested sector is not in prefetch buffer, begin a new prefetch |
| 110 | | |
| 111 | | prefetch_sector(sec); |
| 112 | | pfsec=sec-pf_head_sector; |
| 113 | | numpfsec=num_pf*num_pf_sectors; |
| 114 | | } |
| 115 | | |
| 116 | | int blk=pfsec/num_pf_sectors; |
| 117 | | |
| 118 | | if (blk>0) |
| 119 | | { |
| 120 | | // Discard blocks below the prefetch point |
| 121 | | |
| 122 | | pf_head=(pf_head+blk)%num_pf_buffers; |
| 123 | | pf_head_sector+=num_pf_sectors*blk; |
| 124 | | pfsec-=num_pf_sectors*blk; |
| 125 | | num_pf-=blk; |
| 126 | | blk=0; |
| 127 | | } |
| 128 | | |
| 129 | | bool comp=((! pf_status) || (pf_status->complete())); |
| 130 | | |
| 131 | | if (! comp) |
| 132 | | { |
| 133 | | INT64 curtime=m_machine->device<cpu_device>("maincpu")->total_cycles(); |
| 134 | | |
| 135 | | if (last_pf_status!=pf_status) |
| 136 | | { |
| 137 | | last_pf_status=pf_status; |
| 138 | | pf_timeout_begin=curtime; |
| 139 | | } |
| 140 | | |
| 141 | | INT64 timeout=curtime-pf_timeout_begin; |
| 142 | | int timeout_sec=(int)(timeout/timestamp_frequency); |
| 143 | | if (timeout_sec>20) |
| 144 | | { |
| 145 | | printf("cdrom: prefetch timed out, trying again...\n"); |
| 146 | | num_pf=0; |
| 147 | | pf_head_sector=-1; |
| 148 | | prefetch_sector(sec); |
| 149 | | return is_prefetch_sector_loaded(sec); |
| 150 | | } |
| 151 | | } |
| 152 | | |
| 153 | | if ((num_pf<num_pf_buffers) && (comp)) |
| 154 | | { |
| 155 | | // The prefetch buffer is not full and we are not waiting on IO, |
| 156 | | // prefetch the next block |
| 157 | | |
| 158 | | pf_tail=(pf_tail+1)%num_pf_buffers; |
| 159 | | num_pf++; |
| 160 | | |
| 161 | | int nxtsec=pf_head_sector+((num_pf-1)*num_pf_sectors); |
| 162 | | unsigned char *ptr=pf_buffer+((pf_tail*num_pf_sectors)*native_sector_size); |
| 163 | | |
| 164 | | if (pf_status) |
| 165 | | { |
| 166 | | pf_status->release(); |
| 167 | | pf_status=last_pf_status=NULL; |
| 168 | | } |
| 169 | | |
| 170 | | pf_status=read_sectors(nxtsec, num_pf_sectors, ptr); |
| 171 | | } |
| 172 | | |
| 173 | | if (blk==(num_pf-1)) |
| 174 | | { |
| 175 | | // The sector we want is in the last block in the prefetch buffer |
| 176 | | // which might still be loading, check if the sector we want is loaded |
| 177 | | #if 0 // we do not load async in MESS |
| 178 | | INT64 trans=pf_status->bytes_transferred(); |
| 179 | | unsigned int secmod=pfsec%num_pf_sectors, |
| 180 | | needbytes=(secmod+1)*native_sector_size; |
| 181 | | |
| 182 | | if (trans<needbytes) |
| 183 | | { |
| 184 | | // The sector is not loaded yet |
| 185 | | |
| 186 | | return false; |
| 187 | | } else |
| 188 | | #endif |
| 189 | | { |
| 190 | | // The sector is loaded |
| 191 | | |
| 192 | | return true; |
| 193 | | } |
| 194 | | } else |
| 195 | | { |
| 196 | | // The sector is not in the last block so it must be loaded |
| 197 | | |
| 198 | | return true; |
| 199 | | } |
| 200 | | } |
| 201 | | |
| 202 | | // |
| 203 | | // |
| 204 | | // |
| 205 | | |
| 206 | | unsigned char *cdrom_driver::get_prefetch_sector(const unsigned int sec, unsigned int *sz) |
| 207 | | { |
| 208 | | int numpfsec=num_pf*num_pf_sectors, |
| 209 | | pfsec=sec-pf_head_sector; |
| 210 | | if ((pfsec>=0) && (pfsec<numpfsec)) |
| 211 | | { |
| 212 | | int blk=(pf_head+(pfsec/num_pf_sectors))%num_pf_buffers, |
| 213 | | off=((blk*num_pf_sectors)+(pfsec%num_pf_sectors))*native_sector_size; |
| 214 | | *sz=native_sector_size; |
| 215 | | return pf_buffer+off; |
| 216 | | } else |
| 217 | | { |
| 218 | | return NULL; |
| 219 | | } |
| 220 | | } |
| 221 | | |
| 222 | | // |
| 223 | | // |
| 224 | | // |
| 225 | | |
| 226 | | bool cdrom_driver::read_sector(const unsigned int sec, unsigned char *buf, const bool block) |
| 227 | | { |
| 228 | | bool loaded=is_prefetch_sector_loaded(sec); |
| 229 | | |
| 230 | | // printf("read_sector: %d (loaded=%c)\n", sec, loaded ? 'Y' : 'N'); |
| 231 | | |
| 232 | | if ((! loaded) && (block)) |
| 233 | | { |
| 234 | | pf_status->block_until_complete(); |
| 235 | | loaded=true; |
| 236 | | } |
| 237 | | |
| 238 | | if (loaded) |
| 239 | | { |
| 240 | | unsigned int secsz=0; |
| 241 | | unsigned char *ptr=get_prefetch_sector(sec,&secsz); |
| 242 | | assert(ptr); |
| 243 | | |
| 244 | | // printf("got sector %d @ %p, size %d = %02x %02x | %02x %02x\n", sec, ptr, secsz, ptr[0], ptr[1], ptr[0x20], ptr[0x21]); |
| 245 | | |
| 246 | | if (secsz<2352) |
| 247 | | { |
| 248 | | // Add sector header |
| 249 | | |
| 250 | | buf[0]=0; |
| 251 | | memset(buf+1,0xff,10); |
| 252 | | buf[11]=0; |
| 253 | | sector_to_msf(sec,buf+12); |
| 254 | | buf[12]=decimal_to_bcd(buf[12]); |
| 255 | | buf[13]=decimal_to_bcd(buf[13]); |
| 256 | | buf[14]=decimal_to_bcd(buf[14]); |
| 257 | | buf[15]=2; |
| 258 | | |
| 259 | | if (secsz<2336) |
| 260 | | { |
| 261 | | memset(buf+16,0xff,8); |
| 262 | | } |
| 263 | | } |
| 264 | | |
| 265 | | switch (secsz) |
| 266 | | { |
| 267 | | case 2048: |
| 268 | | memcpy(buf+24,ptr,2048); |
| 269 | | break; |
| 270 | | |
| 271 | | case 2336: |
| 272 | | memcpy(buf+16,ptr,2336); |
| 273 | | break; |
| 274 | | |
| 275 | | case 2352: |
| 276 | | memcpy(buf,ptr,raw_sector_size); |
| 277 | | break; |
| 278 | | } |
| 279 | | |
| 280 | | return true; |
| 281 | | } else |
| 282 | | { |
| 283 | | return false; |
| 284 | | } |
| 285 | | } |
| 286 | | |
| 287 | | void cdrom_driver::set_machine(const running_machine &machine) |
| 288 | | { |
| 289 | | m_machine = (running_machine *)&machine; |
| 290 | | |
| 291 | | timestamp_frequency = m_machine->device<cpu_device>("maincpu")->clock(); |
| 292 | | |
| 293 | | // printf("cdrom_driver::set_machine: timestamp frequency = %d\n", timestamp_frequency); |
| 294 | | } |
| 295 | | |
| 296 | | /* |
| 297 | | MAME/MESS driver implementation |
| 298 | | */ |
| 299 | | |
| 300 | | class mess_cdrom_driver : public cdrom_driver |
| 301 | | { |
| 302 | | enum track_type |
| 303 | | { |
| 304 | | track_illegal=-1, |
| 305 | | track_mode1_2048=0, |
| 306 | | track_mode2_2352, |
| 307 | | track_mode2_2336, |
| 308 | | track_audio |
| 309 | | }; |
| 310 | | |
| 311 | | struct toc_entry |
| 312 | | { |
| 313 | | unsigned int type; |
| 314 | | unsigned char address[3]; |
| 315 | | }; |
| 316 | | |
| 317 | | int num_sectors, num_tracks; |
| 318 | | toc_entry toc[100]; |
| 319 | | int bin_sector_size; |
| 320 | | //const char *err; |
| 321 | | |
| 322 | | io_status *read_sectors(const unsigned int startsec, const unsigned int numsec, unsigned char *buf); |
| 323 | | |
| 324 | | public: |
| 325 | | mess_cdrom_driver(); |
| 326 | | ~mess_cdrom_driver(); |
| 327 | | |
| 328 | | bool is_usable(char *error_msg, const int msglen) const |
| 329 | | { |
| 330 | | return true; |
| 331 | | } |
| 332 | | |
| 333 | | bool read_toc(); |
| 334 | | unsigned int get_first_track() const; |
| 335 | | unsigned int get_num_tracks() const; |
| 336 | | bool get_track_address(const unsigned int track,unsigned char *address) const; |
| 337 | | tracktype get_track_type(const unsigned int track) const; |
| 338 | | unsigned int find_track(const unsigned int sector, unsigned int *start_sector, unsigned int *end_sector) const; |
| 339 | | cdromtype get_type() const; |
| 340 | | }; |
| 341 | | |
| 342 | | mess_cdrom_driver::mess_cdrom_driver() |
| 343 | | //: err(NULL) |
| 344 | | { |
| 345 | | for (int i=0; i<100; i++) |
| 346 | | toc[i].type=track_illegal; |
| 347 | | num_tracks=0; |
| 348 | | num_sectors=0; |
| 349 | | } |
| 350 | | |
| 351 | | // |
| 352 | | // |
| 353 | | // |
| 354 | | |
| 355 | | mess_cdrom_driver::~mess_cdrom_driver() |
| 356 | | { |
| 357 | | cancel_io(); |
| 358 | | } |
| 359 | | |
| 360 | | // |
| 361 | | // |
| 362 | | // |
| 363 | | |
| 364 | | bool mess_cdrom_driver::read_toc() |
| 365 | | { |
| 366 | | if (m_cd) |
| 367 | | { |
| 368 | | const cdrom_toc *toc = cdrom_get_toc(m_cd); |
| 369 | | |
| 370 | | num_tracks = cdrom_get_last_track(m_cd); |
| 371 | | |
| 372 | | switch (toc->tracks[0].trktype) |
| 373 | | { |
| 374 | | case CD_TRACK_MODE1: bin_sector_size=2048; break; |
| 375 | | case CD_TRACK_MODE2_FORM1: bin_sector_size=2048; break; |
| 376 | | case CD_TRACK_MODE2: bin_sector_size=2336; break; |
| 377 | | case CD_TRACK_MODE2_FORM_MIX: bin_sector_size=2336; break; |
| 378 | | default: bin_sector_size=2352; break; |
| 379 | | } |
| 380 | | |
| 381 | | set_native_sector_size(bin_sector_size); |
| 382 | | num_sectors = cdrom_get_track_start(m_cd, num_tracks) + toc->tracks[num_tracks].frames; |
| 383 | | |
| 384 | | // printf("mess_cdrom_driver: %d sectors, native size %d\n",num_sectors, bin_sector_size); |
| 385 | | |
| 386 | | return true; |
| 387 | | } |
| 388 | | |
| 389 | | return false; |
| 390 | | } |
| 391 | | |
| 392 | | // |
| 393 | | // |
| 394 | | // |
| 395 | | |
| 396 | | io_status *mess_cdrom_driver::read_sectors(const unsigned int startsec, const unsigned int numsec, unsigned char *buf) |
| 397 | | { |
| 398 | | const cdrom_toc *toc = cdrom_get_toc(m_cd); |
| 399 | | UINT32 track = cdrom_get_track(m_cd, startsec); |
| 400 | | UINT32 secsize = toc->tracks[track].datasize; |
| 401 | | |
| 402 | | #ifdef debug_mess_driver |
| 403 | | printf("mess: read %d sectors from %d (secsize %d)\n",numsec,startsec,secsize); |
| 404 | | #endif |
| 405 | | |
| 406 | | if (1) // && ((int)startsec<num_sectors)) |
| 407 | | { |
| 408 | | // fin->seek((INT64)startsec*(INT64)bin_sector_size); |
| 409 | | |
| 410 | | // io_status *ios=fin->async_read(buf,numsec*bin_sector_size); |
| 411 | | // if (! ios) |
| 412 | | for (int i = 0; i < numsec; i++) |
| 413 | | { |
| 414 | | // printf("[%d/%d] Reading to pf_buffer %p at offset %d, size %d\n", i, numsec, &buf[secsize*i], secsize*i, secsize); |
| 415 | | cdrom_read_data(m_cd, startsec+i, &buf[secsize*i], CD_TRACK_RAW_DONTCARE); |
| 416 | | } |
| 417 | | |
| 418 | | return NULL; |
| 419 | | |
| 420 | | // return ios; |
| 421 | | } |
| 422 | | else |
| 423 | | { |
| 424 | | printf("mess: read sector out of range (%d, max=%d)\n", |
| 425 | | startsec, |
| 426 | | num_sectors); |
| 427 | | |
| 428 | | memset(buf,0xff,numsec*bin_sector_size); |
| 429 | | return NULL; |
| 430 | | } |
| 431 | | } |
| 432 | | |
| 433 | | // |
| 434 | | // |
| 435 | | // |
| 436 | | |
| 437 | | unsigned int mess_cdrom_driver::get_first_track() const |
| 438 | | { |
| 439 | | return 1; |
| 440 | | } |
| 441 | | |
| 442 | | unsigned int mess_cdrom_driver::get_num_tracks() const |
| 443 | | { |
| 444 | | // printf("get_num_tracks = %d\n", num_tracks); |
| 445 | | return num_tracks; |
| 446 | | } |
| 447 | | |
| 448 | | bool mess_cdrom_driver::get_track_address(const unsigned int track, unsigned char *address) const |
| 449 | | { |
| 450 | | if ((track>=1) && ((int)track<=num_tracks)) |
| 451 | | { |
| 452 | | UINT32 trkstart = cdrom_get_track_start(m_cd, track); |
| 453 | | |
| 454 | | sector_to_msf(trkstart, address); |
| 455 | | |
| 456 | | address[0] = address[0]; |
| 457 | | address[1] = address[1]; |
| 458 | | address[2] = address[2]; |
| 459 | | |
| 460 | | // printf("get_track_address %d = %02x:%02x:%02x\n", track, address[0], address[1], address[2]); |
| 461 | | |
| 462 | | return true; |
| 463 | | } |
| 464 | | else |
| 465 | | { |
| 466 | | address[0]=address[1]=address[2]=0; |
| 467 | | return false; |
| 468 | | } |
| 469 | | } |
| 470 | | |
| 471 | | unsigned int mess_cdrom_driver::find_track(const unsigned int sector, unsigned int *start_sector, unsigned int *end_sector) const |
| 472 | | { |
| 473 | | const cdrom_toc *toc = cdrom_get_toc(m_cd); |
| 474 | | UINT32 track = cdrom_get_track(m_cd, sector); |
| 475 | | int start; |
| 476 | | |
| 477 | | start = cdrom_get_track_start(m_cd, track); |
| 478 | | |
| 479 | | if (start_sector != NULL) |
| 480 | | { |
| 481 | | *start_sector = start; |
| 482 | | } |
| 483 | | |
| 484 | | if (end_sector != NULL) |
| 485 | | { |
| 486 | | *end_sector = start + toc->tracks[track].frames; |
| 487 | | } |
| 488 | | |
| 489 | | printf("find_track: track %d start %d end %d\n", track, start, start + toc->tracks[track].frames); |
| 490 | | |
| 491 | | return -1; |
| 492 | | } |
| 493 | | |
| 494 | | // |
| 495 | | // |
| 496 | | // |
| 497 | | |
| 498 | | cdromtype mess_cdrom_driver::get_type() const |
| 499 | | { |
| 500 | | // printf("get_type\n"); |
| 501 | | return cdromtype_cd; |
| 502 | | } |
| 503 | | |
| 504 | | // |
| 505 | | // |
| 506 | | // |
| 507 | | |
| 508 | | tracktype mess_cdrom_driver::get_track_type(const unsigned int track) const |
| 509 | | { |
| 510 | | const cdrom_toc *toc = cdrom_get_toc(m_cd); |
| 511 | | |
| 512 | | // printf("get_track_type %d = %d\n", track, toc->tracks[track].trktype); |
| 513 | | |
| 514 | | switch (toc->tracks[track].trktype) |
| 515 | | { |
| 516 | | case CD_TRACK_MODE1: return tracktype_mode1; |
| 517 | | case CD_TRACK_MODE2_RAW: return tracktype_mode2; |
| 518 | | case CD_TRACK_MODE2_FORM_MIX: return tracktype_mode2; |
| 519 | | case CD_TRACK_AUDIO: return tracktype_audio; |
| 520 | | default: return tracktype_unknown; |
| 521 | | } |
| 522 | | } |
| 523 | | |
| 524 | | // |
| 525 | | // |
| 526 | | // |
| 527 | | |
| 528 | | cdrom_driver *open_mess_drv() |
| 529 | | { |
| 530 | | return new mess_cdrom_driver(); |
| 531 | | } |
trunk/src/mess/machine/psxcd.c
| r22065 | r22066 | |
| 1 | | |
| 2 | 1 | #include "emu.h" |
| 3 | 2 | #include "psxcd.h" |
| 4 | 3 | #include "debugger.h" |
| r22065 | r22066 | |
| 11 | 10 | //#define debug_cdrom_registers |
| 12 | 11 | //#define skip_reads |
| 13 | 12 | //#define dump_subheader |
| 14 | | //#define disable_xa_prefetch |
| 15 | | //#define disable_cdda_prefetch |
| 16 | 13 | |
| 17 | 14 | // |
| 18 | 15 | // |
| r22065 | r22066 | |
| 23 | 20 | event_cmd_complete=0, |
| 24 | 21 | event_preread_sector, |
| 25 | 22 | event_read_sector, |
| 26 | | event_play_sector |
| 23 | event_play_sector, |
| 24 | event_change_disk |
| 27 | 25 | }; |
| 28 | 26 | |
| 29 | 27 | // |
| r22065 | r22066 | |
| 89 | 87 | // |
| 90 | 88 | // |
| 91 | 89 | |
| 92 | | static const unsigned int max_xa_prefetch_distance=32, |
| 93 | | max_cdda_prefetch_distance=32; |
| 94 | | |
| 95 | 90 | //************************************************************************** |
| 96 | 91 | // DEVICE DEFINITIONS |
| 97 | 92 | //************************************************************************** |
| 98 | 93 | |
| 99 | 94 | const device_type PSXCD = &device_creator<psxcd_device>; |
| 100 | 95 | |
| 101 | | void psxcd_device::static_set_devname(device_t &device, const char *devname) |
| 96 | static struct cdrom_interface psx_cdrom = |
| 102 | 97 | { |
| 103 | | psxcd_device &psxcd = downcast<psxcd_device &>(device); |
| 104 | | psxcd.m_devname = devname; |
| 105 | | } |
| 98 | "psx_cdrom", |
| 99 | NULL |
| 100 | }; |
| 106 | 101 | |
| 107 | 102 | psxcd_device::psxcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 108 | | device_t(mconfig, PSXCD, "PSXCD", tag, owner, clock), |
| 103 | cdrom_image_device(mconfig, PSXCD, "Cdrom", tag, owner, clock), |
| 109 | 104 | m_irq_handler(*this) |
| 110 | 105 | { |
| 106 | static_set_static_config(*this, &psx_cdrom); |
| 111 | 107 | } |
| 112 | 108 | |
| 109 | |
| 113 | 110 | void psxcd_device::device_start() |
| 114 | 111 | { |
| 112 | cdrom_image_device::device_start(); |
| 115 | 113 | m_irq_handler.resolve_safe(); |
| 116 | 114 | |
| 117 | 115 | m_maincpu = machine().device<cpu_device>("maincpu"); |
| r22065 | r22066 | |
| 134 | 132 | sectail = 0; |
| 135 | 133 | secin = 0; |
| 136 | 134 | secskip = 0; |
| 137 | | next_read_event = NULL; |
| 135 | next_read_event = -1; |
| 138 | 136 | cbp = cmdbuf; |
| 139 | 137 | first_open = true; |
| 140 | 138 | |
| r22065 | r22066 | |
| 144 | 142 | ir=0; |
| 145 | 143 | mode=0; |
| 146 | 144 | |
| 147 | | driver = NULL; |
| 148 | | |
| 149 | 145 | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
| 150 | 146 | { |
| 151 | | m_timers[i] = timer_alloc(i, NULL); |
| 147 | m_timers[i] = timer_alloc(i); |
| 152 | 148 | m_timerinuse[i] = false; |
| 153 | 149 | } |
| 154 | 150 | |
| 155 | | for(int i = 0; i < 3; ++i) |
| 156 | | curpos[i] = 0; |
| 151 | curpos.w = 0; |
| 152 | m_param_count = 0; |
| 157 | 153 | } |
| 158 | 154 | |
| 159 | 155 | // |
| r22065 | r22066 | |
| 170 | 166 | m_timerinuse[i] = false; |
| 171 | 167 | } |
| 172 | 168 | |
| 173 | | m_cddevice = machine().device<cdrom_image_device>(m_devname); |
| 174 | | if (m_cddevice) |
| 169 | if(cur_res) |
| 175 | 170 | { |
| 176 | | m_cd = m_cddevice->get_cdrom_file(); |
| 177 | | |
| 178 | | if (m_cd) |
| 179 | | { |
| 180 | | // printf("psxcd: found disc!\n"); |
| 181 | | driver = open_mess_drv(); |
| 182 | | driver->set_machine(machine()); |
| 183 | | driver->set_cdrom_file(m_cd); |
| 184 | | } |
| 185 | | else |
| 186 | | { |
| 187 | | driver = NULL; |
| 188 | | // printf("psxcd: Found device, but no disc\n"); |
| 189 | | } |
| 171 | global_free(cur_res); |
| 172 | cur_res = NULL; |
| 190 | 173 | } |
| 191 | | else |
| 174 | |
| 175 | while(res_queue) |
| 192 | 176 | { |
| 193 | | driver = NULL; |
| 194 | | // printf("psxcd: Device [%s] not found!\n", m_devname); |
| 177 | cur_res = res_queue->next; |
| 178 | global_free(res_queue); |
| 179 | res_queue = cur_res; |
| 195 | 180 | } |
| 196 | 181 | |
| 182 | m_param_count = 0; |
| 197 | 183 | } |
| 198 | 184 | |
| 199 | 185 | // |
| 200 | 186 | // |
| 201 | 187 | // |
| 202 | 188 | |
| 189 | bool psxcd_device::call_load() |
| 190 | { |
| 191 | bool ret = cdrom_image_device::call_load(); |
| 192 | open = true; |
| 193 | if(ret == IMAGE_INIT_PASS) |
| 194 | add_system_event(event_change_disk, m_sysclock, NULL); // 1 sec to spin up the disk |
| 195 | return ret; |
| 196 | } |
| 197 | |
| 198 | void psxcd_device::call_unload() |
| 199 | { |
| 200 | stop_read(); |
| 201 | cdrom_image_device::call_unload(); |
| 202 | open = true; |
| 203 | send_result(intr_diskerror); |
| 204 | } |
| 205 | |
| 203 | 206 | READ8_MEMBER( psxcd_device::read ) |
| 204 | 207 | { |
| 205 | 208 | unsigned char ret = 0; |
| r22065 | r22066 | |
| 320 | 323 | if (cmdmode==0) |
| 321 | 324 | { |
| 322 | 325 | *cbp++=data; |
| 326 | m_param_count++; |
| 323 | 327 | } else |
| 324 | 328 | { |
| 325 | 329 | // ?flush buffer? |
| r22065 | r22066 | |
| 349 | 353 | } |
| 350 | 354 | ir=0; |
| 351 | 355 | } |
| 352 | | break; |
| 353 | 356 | } |
| 354 | 357 | } |
| 355 | 358 | |
| r22065 | r22066 | |
| 396 | 399 | { |
| 397 | 400 | assert(byte<num_commands); |
| 398 | 401 | (this->*cmd_table[byte].func)(); |
| 402 | m_param_count = 0; |
| 399 | 403 | } |
| 400 | 404 | |
| 401 | 405 | // |
| r22065 | r22066 | |
| 412 | 416 | send_result(intr_acknowledge); |
| 413 | 417 | } |
| 414 | 418 | |
| 415 | | static int open_nops=0; |
| 419 | static int open_nops=10; |
| 416 | 420 | |
| 417 | 421 | void psxcd_device::cdcmd_nop() |
| 418 | 422 | { |
| r22065 | r22066 | |
| 422 | 426 | |
| 423 | 427 | //stop_read(); |
| 424 | 428 | |
| 425 | | if ((! open) && (driver)) |
| 429 | if (!open) |
| 426 | 430 | { |
| 427 | | if (open_nops==0) |
| 428 | | { |
| 429 | | open=driver->read_toc(); |
| 430 | | } else |
| 431 | | { |
| 431 | if (open_nops!=0) |
| 432 | 432 | open_nops--; |
| 433 | | } |
| 434 | 433 | } |
| 435 | 434 | |
| 436 | 435 | send_result(intr_complete); |
| r22065 | r22066 | |
| 447 | 446 | |
| 448 | 447 | stop_read(); |
| 449 | 448 | |
| 450 | | unsigned char l[3]; |
| 451 | | l[0]=bcd_to_decimal(cmdbuf[0]); |
| 452 | | l[1]=bcd_to_decimal(cmdbuf[1]); |
| 453 | | l[2]=bcd_to_decimal(cmdbuf[2]); |
| 454 | 449 | |
| 455 | | if ((l[0]>0) || (l[1]>=2)) |
| 456 | | { |
| 457 | | loc[0]=l[0]; |
| 458 | | loc[1]=l[1]; |
| 459 | | loc[2]=l[2]; |
| 460 | | } else |
| 461 | | { |
| 462 | | printf("setloc out of range: %02d:%02d:%02d\n", |
| 463 | | l[0],l[1],l[2]); |
| 464 | | } |
| 450 | CDPOS l; |
| 451 | l.b[M]=bcd_to_decimal(cmdbuf[0]); |
| 452 | l.b[S]=bcd_to_decimal(cmdbuf[1]); |
| 453 | l.b[F]=bcd_to_decimal(cmdbuf[2]); |
| 465 | 454 | |
| 455 | if ((l.b[M]>0) || (l.b[S]>=2)) |
| 456 | loc.w=l.w; |
| 457 | else |
| 458 | logerror("setloc out of range: %02d:%02d:%02d\n",l.b[M],l.b[S],l.b[F]); |
| 459 | |
| 466 | 460 | send_result(intr_complete); |
| 467 | 461 | } |
| 468 | 462 | |
| 469 | 463 | void psxcd_device::cdcmd_play() |
| 470 | 464 | { |
| 471 | | #ifdef debug_cdrom |
| 472 | | printf("cdrom: play %02x %02x %02x => %d\n", loc[0], loc[1], loc[2], msf_to_sector(loc)); |
| 473 | | #endif |
| 465 | if(cmdbuf[0] && m_param_count) |
| 466 | loc.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, bcd_to_decimal(cmdbuf[0]) - 1)); |
| 474 | 467 | |
| 475 | | curpos[0]=loc[0]; |
| 476 | | curpos[1]=loc[1]; |
| 477 | | curpos[2]=loc[2]; |
| 468 | curpos.w = loc.w; |
| 469 | if (!curpos.w) |
| 470 | curpos.b[S] = 2; |
| 478 | 471 | |
| 479 | | if ((curpos[0]==0) && |
| 480 | | (curpos[1]==0) && |
| 481 | | (curpos[2]==0)) |
| 482 | | { |
| 483 | | send_result(intr_acknowledge); |
| 484 | | } else |
| 485 | | { |
| 486 | | stop_read(); |
| 487 | | start_play(); |
| 488 | | send_result(intr_acknowledge); |
| 489 | | } |
| 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 |
| 475 | |
| 476 | stop_read(); |
| 477 | start_play(); |
| 478 | send_result(intr_complete); |
| 490 | 479 | } |
| 491 | 480 | |
| 492 | 481 | void psxcd_device::cdcmd_forward() |
| r22065 | r22066 | |
| 505 | 494 | |
| 506 | 495 | void psxcd_device::cdcmd_readn() |
| 507 | 496 | { |
| 508 | | if (driver) |
| 497 | if(!open) |
| 509 | 498 | { |
| 510 | 499 | #ifdef debug_cdrom |
| 511 | 500 | printf("cdrom: readn\n"); |
| 512 | 501 | #endif |
| 513 | 502 | |
| 514 | | curpos[0]=loc[0]; |
| 515 | | curpos[1]=loc[1]; |
| 516 | | curpos[2]=loc[2]; |
| 503 | curpos.w=loc.w; |
| 517 | 504 | |
| 518 | 505 | stop_read(); |
| 519 | 506 | start_read(); |
| 520 | 507 | send_result(intr_complete); |
| 521 | 508 | } else |
| 522 | 509 | { |
| 523 | | printf("read without driver\n"); |
| 524 | 510 | send_result(intr_diskerror); |
| 525 | 511 | } |
| 526 | 512 | } |
| r22065 | r22066 | |
| 653 | 639 | send_result(intr_complete,data,6); |
| 654 | 640 | } |
| 655 | 641 | |
| 656 | | #if 0 |
| 657 | | static void add_loc(unsigned char *dst, const unsigned char *src1, const unsigned char *src2) |
| 642 | UINT32 psxcd_device::sub_loc(CDPOS src1, CDPOS src2) |
| 658 | 643 | { |
| 659 | | int f=src1[2]+src2[2], |
| 660 | | s=src1[1]+src2[1], |
| 661 | | m=src1[0]+src2[0]; |
| 662 | | while (f>=75) { s++; f-=75; } |
| 663 | | while (s>=60) { m++; s-=60; } |
| 664 | | |
| 665 | | dst[0]=m; |
| 666 | | dst[1]=s; |
| 667 | | dst[2]=f; |
| 668 | | } |
| 669 | | #endif |
| 670 | | static void sub_loc(unsigned char *dst, const unsigned char *src1, const unsigned char *src2) |
| 671 | | { |
| 672 | | int f=src1[2]-src2[2], |
| 673 | | s=src1[1]-src2[1], |
| 674 | | m=src1[0]-src2[0]; |
| 644 | CDPOS dst; |
| 645 | int f=src1.b[F]-src2.b[F], |
| 646 | s=src1.b[S]-src2.b[S], |
| 647 | m=src1.b[M]-src2.b[M]; |
| 675 | 648 | while (f<0) { s--; f+=75; } |
| 676 | 649 | while (s<0) { m--; s+=60; } |
| 677 | 650 | |
| 678 | 651 | if (m<0) |
| 679 | 652 | m=s=f=0; |
| 680 | 653 | |
| 681 | | dst[0]=m; |
| 682 | | dst[1]=s; |
| 683 | | dst[2]=f; |
| 654 | dst.b[M]=m; |
| 655 | dst.b[S]=s; |
| 656 | dst.b[F]=f; |
| 657 | |
| 658 | return dst.w; |
| 684 | 659 | } |
| 685 | 660 | |
| 686 | 661 | void psxcd_device::cdcmd_getlocl() |
| r22065 | r22066 | |
| 706 | 681 | |
| 707 | 682 | void psxcd_device::cdcmd_getlocp() |
| 708 | 683 | { |
| 709 | | unsigned char tloc[3], |
| 710 | | twosec[3]={ 0,2,0 }; |
| 711 | | sub_loc(tloc,loc,twosec); |
| 684 | CDPOS tloc, start; |
| 685 | UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(loc.w) + 150) + 1; |
| 686 | start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1)); |
| 687 | tloc.w = sub_loc(loc, start); |
| 712 | 688 | |
| 713 | 689 | unsigned char data[8]= |
| 714 | 690 | { |
| 715 | | 0x01, // track |
| 691 | decimal_to_bcd(track), // track |
| 716 | 692 | 0x01, // index |
| 717 | | decimal_to_bcd(tloc[0]), // min |
| 718 | | decimal_to_bcd(tloc[1]), // sec |
| 719 | | decimal_to_bcd(tloc[2]), // frame |
| 720 | | decimal_to_bcd(loc[0]), // amin |
| 721 | | decimal_to_bcd(loc[1]), // asec |
| 722 | | decimal_to_bcd(loc[2]) // aframe |
| 693 | decimal_to_bcd(tloc.b[M]), // min |
| 694 | decimal_to_bcd(tloc.b[S]), // sec |
| 695 | decimal_to_bcd(tloc.b[F]), // frame |
| 696 | decimal_to_bcd(loc.b[M]), // amin |
| 697 | decimal_to_bcd(loc.b[S]), // asec |
| 698 | decimal_to_bcd(loc.b[F]) // aframe |
| 723 | 699 | }; |
| 724 | 700 | |
| 725 | 701 | //unsigned char data[8]={ 2,1,0,0xff,0xff,0xff,0xff,0xff }; |
| r22065 | r22066 | |
| 750 | 726 | printf("cdrom: gettn\n"); |
| 751 | 727 | #endif |
| 752 | 728 | |
| 753 | | assert(driver); |
| 754 | 729 | |
| 755 | | unsigned char data[3]= |
| 730 | if(!open) |
| 756 | 731 | { |
| 757 | | status, |
| 758 | | decimal_to_bcd(driver->get_first_track()), |
| 759 | | decimal_to_bcd(driver->get_num_tracks()) |
| 760 | | }; |
| 732 | unsigned char data[3]= |
| 733 | { |
| 734 | status, |
| 735 | decimal_to_bcd(1), |
| 736 | decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle)) |
| 737 | }; |
| 761 | 738 | |
| 762 | | //stop_read(); |
| 763 | | send_result(intr_acknowledge,data,3); |
| 739 | //stop_read(); |
| 740 | send_result(intr_complete,data,3); |
| 741 | } |
| 742 | else |
| 743 | send_result(intr_diskerror); |
| 764 | 744 | } |
| 765 | 745 | |
| 766 | 746 | void psxcd_device::cdcmd_gettd() |
| 767 | 747 | { |
| 768 | | unsigned char addr[3]; |
| 769 | | driver->get_track_address(bcd_to_decimal(cmdbuf[0]), addr); |
| 770 | | |
| 771 | | unsigned char data[3]= |
| 748 | UINT8 track = bcd_to_decimal(cmdbuf[0]); |
| 749 | UINT8 last = cdrom_get_last_track(m_cdrom_handle); |
| 750 | if(track <= last) |
| 772 | 751 | { |
| 773 | | status, |
| 774 | | decimal_to_bcd(addr[0]), |
| 775 | | decimal_to_bcd(addr[1]) |
| 776 | | }; |
| 752 | CDPOS trkstart; |
| 753 | if(!track) // length of disk |
| 754 | trkstart.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, 0xaa)); |
| 755 | else |
| 756 | trkstart.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1)); |
| 777 | 757 | |
| 778 | | #ifdef debug_cdrom |
| 779 | | printf("cdrom: gettd %02x [%02x %02x %02x]\n", |
| 780 | | cmdbuf[0], |
| 781 | | data[0], |
| 782 | | data[1], |
| 783 | | data[2]); |
| 784 | | #endif |
| 758 | unsigned char data[3]= |
| 759 | { |
| 760 | status, |
| 761 | decimal_to_bcd(trkstart.b[M]), |
| 762 | decimal_to_bcd(trkstart.b[S]) |
| 763 | }; |
| 785 | 764 | |
| 786 | | //stop_read(); |
| 787 | | send_result(intr_acknowledge,data,3); |
| 765 | #ifdef debug_cdrom |
| 766 | printf("cdrom: gettd %02x [%02x %02x %02x]\n", |
| 767 | cmdbuf[0], |
| 768 | data[0], |
| 769 | data[1], |
| 770 | data[2]); |
| 771 | #endif |
| 772 | |
| 773 | //stop_read(); |
| 774 | send_result(intr_acknowledge,data,3); |
| 775 | } |
| 776 | else |
| 777 | { |
| 778 | status |= status_error; |
| 779 | send_result(intr_diskerror); |
| 780 | } |
| 788 | 781 | } |
| 789 | 782 | |
| 790 | 783 | void psxcd_device::cdcmd_seekl() |
| 791 | 784 | { |
| 792 | 785 | #ifdef debug_cdrom |
| 793 | | printf("cdrom: seekl [%02d:%02d:%02d]\n",loc[0],loc[1],loc[2]); |
| 786 | printf("cdrom: seekl [%02d:%02d:%02d]\n",loc.b[M],loc.b[S],loc.b[F]); |
| 794 | 787 | #endif |
| 795 | 788 | |
| 796 | | curpos[0]=loc[0]; |
| 797 | | curpos[1]=loc[1]; |
| 798 | | curpos[2]=loc[2]; |
| 789 | curpos.w=loc.w; |
| 799 | 790 | |
| 800 | 791 | send_result(intr_acknowledge); |
| 801 | 792 | } |
| r22065 | r22066 | |
| 806 | 797 | printf("cdrom: seekp\n"); |
| 807 | 798 | #endif |
| 808 | 799 | |
| 809 | | curpos[0]=loc[0]; |
| 810 | | curpos[1]=loc[1]; |
| 811 | | curpos[2]=loc[2]; |
| 800 | curpos.w=loc.w; |
| 812 | 801 | |
| 813 | 802 | send_result(intr_acknowledge); |
| 814 | 803 | } |
| r22065 | r22066 | |
| 836 | 825 | printf("cdrom: id\n"); |
| 837 | 826 | #endif |
| 838 | 827 | |
| 839 | | if (! open) |
| 828 | if (!open) |
| 840 | 829 | { |
| 841 | | if (driver) |
| 842 | | open=driver->read_toc(); |
| 843 | | } |
| 830 | static unsigned char gamedata[8] = { 0x00, 0x00, 0x00, 0x00, 'S', 'C', 'E', 'A' }; |
| 831 | static unsigned char audiodata[8] = { 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // drops into the audio CD player. 08 80 goes to the menu. |
| 844 | 832 | |
| 845 | | if (open) |
| 846 | | { |
| 847 | | static unsigned char gamedata[8] = { 0x08, 0x00, 0x00, 0x00, 'S', 'C', 'E', 'A' }; |
| 848 | | static unsigned char audiodata[8] = { 0x08, 0x90, 0x00, 0x00, 'S', 'C', 'E', 'A' }; // drops into the audio CD player. 08 80 goes to the menu. |
| 849 | | |
| 850 | | if (cdrom_get_track_type(m_cd, 0) == CD_TRACK_AUDIO) |
| 833 | if (cdrom_get_track_type(m_cdrom_handle, 0) == CD_TRACK_AUDIO) |
| 851 | 834 | { |
| 835 | audiodata[0] = status | 8; |
| 852 | 836 | send_result(intr_acknowledge,audiodata,8); |
| 853 | 837 | } |
| 854 | 838 | else |
| 855 | 839 | { |
| 840 | gamedata[0] = status; |
| 856 | 841 | send_result(intr_acknowledge,gamedata,8); |
| 857 | 842 | } |
| 858 | 843 | } else |
| r22065 | r22066 | |
| 864 | 849 | |
| 865 | 850 | void psxcd_device::cdcmd_reads() |
| 866 | 851 | { |
| 867 | | curpos[0]=loc[0]; |
| 868 | | curpos[1]=loc[1]; |
| 869 | | curpos[2]=loc[2]; |
| 852 | curpos.w=loc.w; |
| 870 | 853 | |
| 871 | 854 | #ifdef skip_reads |
| 872 | 855 | #ifdef debug_cdrom |
| r22065 | r22066 | |
| 961 | 944 | // |
| 962 | 945 | // |
| 963 | 946 | |
| 964 | | event *psxcd_device::send_result(const unsigned int res, |
| 947 | void psxcd_device::send_result(const unsigned int res, |
| 965 | 948 | const unsigned char *data, |
| 966 | 949 | const unsigned int sz, |
| 967 | 950 | const unsigned int delay) |
| 968 | 951 | { |
| 969 | 952 | // Update shell open status |
| 970 | 953 | |
| 971 | | if (! open) |
| 954 | if (open) |
| 972 | 955 | { |
| 973 | 956 | status=status_error|status_shellopen; |
| 974 | 957 | } |
| r22065 | r22066 | |
| 978 | 961 | status=status_standby; |
| 979 | 962 | } |
| 980 | 963 | |
| 981 | | // Prepare event |
| 982 | 964 | |
| 983 | | event *ev=new event; |
| 984 | | ev->t=delay; |
| 985 | | ev->type=event_cmd_complete; |
| 965 | command_result *cr=global_alloc(command_result); |
| 986 | 966 | |
| 987 | | command_result *cr=(command_result *)ev->data; |
| 988 | | |
| 989 | 967 | cr->res=res; |
| 990 | 968 | if (sz) |
| 991 | 969 | { |
| r22065 | r22066 | |
| 997 | 975 | cr->data[0]=status; |
| 998 | 976 | cr->sz=1; |
| 999 | 977 | } |
| 978 | status &= ~status_error; |
| 1000 | 979 | |
| 1001 | 980 | // Avoid returning results after sector read results - |
| 1002 | 981 | // delay the sector read slightly if necessary |
| 1003 | 982 | |
| 1004 | 983 | UINT64 systime = m_maincpu->total_cycles(); |
| 1005 | | if ((next_read_event) && ((systime+ev->t)>(next_sector_t))) |
| 984 | if ((next_read_event != -1) && ((systime+delay)>(next_sector_t))) |
| 1006 | 985 | { |
| 1007 | 986 | UINT32 hz = m_sysclock / (delay + 2000); |
| 1008 | | next_read_event->timer->adjust(attotime::from_hz(hz), 0, attotime::never); |
| 1009 | | |
| 1010 | | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
| 1011 | | { |
| 1012 | | if (m_eventfortimer[i] == next_read_event) |
| 1013 | | { |
| 1014 | | printf("Adjusting timer %d to %d hz]n", i, hz); |
| 1015 | | } |
| 1016 | | } |
| 987 | m_timers[next_read_event]->adjust(attotime::from_hz(hz), 0, attotime::never); |
| 1017 | 988 | } |
| 1018 | 989 | |
| 1019 | | add_system_event(ev); |
| 1020 | | return ev; |
| 990 | add_system_event(event_cmd_complete, delay, (void *)cr); |
| 1021 | 991 | } |
| 1022 | 992 | |
| 1023 | 993 | // |
| r22065 | r22066 | |
| 1028 | 998 | { |
| 1029 | 999 | if ((int)size>secleft) |
| 1030 | 1000 | { |
| 1031 | | printf("cdrom: dma past end of sector (secleft=%d sz=%d)\n",secleft,size); |
| 1001 | logerror("cdrom: dma past end of sector (secleft=%d sz=%d)\n",secleft,size); |
| 1032 | 1002 | } |
| 1033 | 1003 | |
| 1034 | 1004 | // printf("cdrom: start dma %d bytes, %d remaining, secptr %p\n", size, secleft, secptr); |
| r22065 | r22066 | |
| 1055 | 1025 | if (secleft==0) sr&=~0x40; |
| 1056 | 1026 | } |
| 1057 | 1027 | |
| 1058 | | // |
| 1059 | | // |
| 1060 | | // |
| 1061 | | |
| 1062 | | void psxcd_device::prefetch_next_sector() |
| 1028 | bool psxcd_device::read_next_sector() |
| 1063 | 1029 | { |
| 1064 | | unsigned int pos=msf_to_sector(curpos); |
| 1065 | | assert(driver); |
| 1066 | | driver->prefetch_sector(pos); |
| 1067 | | } |
| 1068 | | |
| 1069 | | // |
| 1070 | | // |
| 1071 | | // |
| 1072 | | |
| 1073 | | bool psxcd_device::read_next_sector(const bool block) |
| 1074 | | { |
| 1075 | | unsigned int pos=msf_to_sector(curpos); |
| 1030 | UINT32 pos=msf_to_lba_ps(curpos.w); |
| 1076 | 1031 | unsigned char *buf=&secbuf[sechead*raw_sector_size]; |
| 1077 | | assert(driver); |
| 1078 | 1032 | assert(secin<sector_buffer_size); |
| 1079 | 1033 | |
| 1080 | 1034 | // printf("read_next_sector: sec %d, sechead %d, raw_sector_size %d\n", pos, sechead, raw_sector_size); |
| 1081 | | if (driver->read_sector(pos, buf, block)) |
| 1035 | if (cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE)) |
| 1082 | 1036 | { |
| 1083 | 1037 | // printf("buf contents = %02x %02x | %02x %02x\n", buf[0], buf[1], buf[0x20], buf[0x21]); |
| 1084 | 1038 | |
| r22065 | r22066 | |
| 1100 | 1054 | |
| 1101 | 1055 | void psxcd_device::read_sector() |
| 1102 | 1056 | { |
| 1103 | | next_read_event=NULL; |
| 1057 | next_read_event=-1; |
| 1104 | 1058 | |
| 1105 | 1059 | if (status & status_reading) |
| 1106 | 1060 | { |
| 1107 | 1061 | bool isend=false; |
| 1108 | 1062 | |
| 1109 | | if (read_next_sector(false)) |
| 1063 | if (read_next_sector()) |
| 1110 | 1064 | { |
| 1111 | 1065 | unsigned char *rawsec; |
| 1112 | 1066 | |
| r22065 | r22066 | |
| 1123 | 1077 | secleft=secsize; |
| 1124 | 1078 | } |
| 1125 | 1079 | |
| 1080 | bool isxa=false; |
| 1081 | |
| 1126 | 1082 | secin--; |
| 1127 | 1083 | sectail=(sectail+1)&(sector_buffer_size-1); |
| 1128 | 1084 | |
| 1129 | | // |
| 1130 | | |
| 1131 | | bool isxa=false; |
| 1132 | | |
| 1133 | 1085 | subheader *sub=(subheader *)(rawsec+16); |
| 1134 | 1086 | |
| 1135 | 1087 | #ifdef dump_subheader |
| r22065 | r22066 | |
| 1157 | 1109 | isend=true; |
| 1158 | 1110 | //printf("end of file\n"); |
| 1159 | 1111 | } |
| 1112 | m_spu->play_xa(0,rawsec+16); |
| 1160 | 1113 | |
| 1161 | | #ifndef disable_xa_prefetch |
| 1162 | | unsigned int cursec=msf_to_sector(curpos); |
| 1163 | | |
| 1164 | | if (xa_prefetch_sector==-1) |
| 1165 | | { |
| 1166 | | xa_prefetch_sector=cursec; |
| 1167 | | m_spu->flush_xa(); |
| 1168 | | } |
| 1169 | | |
| 1170 | | unsigned char *xaptr; |
| 1171 | | unsigned int xasecsz; |
| 1172 | | |
| 1173 | | while (1) |
| 1174 | | { |
| 1175 | | int dist=xa_prefetch_sector-cursec; |
| 1176 | | if (dist>max_xa_prefetch_distance) break; |
| 1177 | | |
| 1178 | | xaptr=driver->get_prefetch_sector(xa_prefetch_sector,&xasecsz); |
| 1179 | | if (! xaptr) break; |
| 1180 | | |
| 1181 | | switch (xasecsz) |
| 1182 | | { |
| 1183 | | case 2336: |
| 1184 | | break; |
| 1185 | | |
| 1186 | | default: |
| 1187 | | xaptr+=16; |
| 1188 | | break; |
| 1189 | | } |
| 1190 | | |
| 1191 | | subheader *xasub=(subheader *)xaptr; |
| 1192 | | |
| 1193 | | if ((xasub->submode&submode_audio) && |
| 1194 | | (((mode&mode_channel)==0) || |
| 1195 | | ((xasub->file==sub->file) && |
| 1196 | | (xasub->channel==sub->channel)))) |
| 1197 | | { |
| 1198 | | if (! m_spu->play_xa(xa_prefetch_sector,xaptr)) |
| 1199 | | break; |
| 1200 | | } |
| 1201 | | xa_prefetch_sector++; |
| 1202 | | } |
| 1203 | | #else |
| 1204 | | m_spu->play_xa(0,rawsec+16); |
| 1205 | | #endif |
| 1206 | | |
| 1207 | 1114 | status|=status_playing; |
| 1208 | 1115 | } |
| 1209 | 1116 | } |
| r22065 | r22066 | |
| 1213 | 1120 | |
| 1214 | 1121 | // |
| 1215 | 1122 | |
| 1216 | | curpos[2]++; |
| 1217 | | if (curpos[2]==75) |
| 1123 | curpos.b[F]++; |
| 1124 | if (curpos.b[F]==75) |
| 1218 | 1125 | { |
| 1219 | | curpos[2]=0; |
| 1220 | | curpos[1]++; |
| 1221 | | if (curpos[1]==60) |
| 1126 | curpos.b[F]=0; |
| 1127 | curpos.b[S]++; |
| 1128 | if (curpos.b[S]==60) |
| 1222 | 1129 | { |
| 1223 | | curpos[1]=0; |
| 1224 | | curpos[0]++; |
| 1130 | curpos.b[S]=0; |
| 1131 | curpos.b[M]++; |
| 1225 | 1132 | } |
| 1226 | 1133 | } |
| 1227 | 1134 | |
| 1228 | | loc[0]=curpos[0]; |
| 1229 | | loc[1]=curpos[1]; |
| 1230 | | loc[2]=curpos[2]; |
| 1135 | loc.w=curpos.w; |
| 1231 | 1136 | |
| 1232 | | // |
| 1233 | | |
| 1234 | | command_result *res=new command_result; |
| 1235 | | res->res=isend?intr_dataend:intr_dataready; |
| 1236 | | res->data[0]=status; |
| 1237 | | res->sz=1; |
| 1238 | | |
| 1239 | 1137 | sr|=0x40; |
| 1240 | 1138 | |
| 1241 | | if ((streaming) && (isxa)) |
| 1139 | if(!(streaming && isxa)) |
| 1242 | 1140 | { |
| 1243 | | global_free(res); |
| 1244 | | res=NULL; |
| 1245 | | } |
| 1246 | | |
| 1247 | | if (res) |
| 1248 | | { |
| 1249 | | #ifdef debug_cdrom |
| 1250 | | printf("cdrom:: data ready\n"); |
| 1251 | | #endif |
| 1252 | | |
| 1141 | command_result *res=global_alloc(command_result); |
| 1142 | res->res=isend?intr_dataend:intr_dataready; |
| 1143 | res->data[0]=status; |
| 1144 | res->sz=1; |
| 1253 | 1145 | cmd_complete(res); |
| 1254 | 1146 | } |
| 1255 | 1147 | } |
| r22065 | r22066 | |
| 1261 | 1153 | |
| 1262 | 1154 | next_sector_t+=cyc; |
| 1263 | 1155 | |
| 1264 | | event *ev=new event; |
| 1265 | | ev->t=cyc; |
| 1266 | | ev->type=event_read_sector; |
| 1267 | | next_read_event=ev; |
| 1268 | | add_system_event(ev); |
| 1156 | next_read_event = add_system_event(event_read_sector, cyc, NULL); |
| 1269 | 1157 | |
| 1270 | 1158 | //read_next_sector(); |
| 1271 | 1159 | } else |
| r22065 | r22066 | |
| 1291 | 1179 | |
| 1292 | 1180 | void psxcd_device::play_sector() |
| 1293 | 1181 | { |
| 1294 | | next_read_event=NULL; |
| 1182 | next_read_event=-1; |
| 1295 | 1183 | |
| 1296 | 1184 | if (status&status_playing) |
| 1297 | 1185 | { |
| 1298 | | #ifdef disable_cdda_prefetch |
| 1299 | 1186 | unsigned char *rawsec=&secbuf[raw_sector_size*sectail]; |
| 1300 | | #endif |
| 1301 | 1187 | secin--; |
| 1302 | 1188 | sectail=(sectail+1)&(sector_buffer_size-1); |
| 1189 | play_cdda_sector(0,rawsec); |
| 1303 | 1190 | |
| 1304 | | // |
| 1305 | | |
| 1306 | | #ifndef disable_cdda_prefetch |
| 1307 | | unsigned int cursec=msf_to_sector(curpos); |
| 1308 | | |
| 1309 | | if (cdda_prefetch_sector==-1) |
| 1310 | | { |
| 1311 | | cdda_prefetch_sector=cursec; |
| 1312 | | m_spu->flush_cdda(); |
| 1313 | | } |
| 1314 | | |
| 1315 | | unsigned char *cddaptr; |
| 1316 | | // bool full=false; |
| 1317 | | unsigned int cddasecsz; |
| 1318 | | |
| 1319 | | while (1) |
| 1320 | | { |
| 1321 | | int dist=cdda_prefetch_sector-cursec; |
| 1322 | | if (dist>max_cdda_prefetch_distance) break; |
| 1323 | | |
| 1324 | | cddaptr=driver->get_prefetch_sector(cdda_prefetch_sector,&cddasecsz); |
| 1325 | | if (! cddaptr) break; |
| 1326 | | |
| 1327 | | if (! play_cdda_sector(cdda_prefetch_sector,cddaptr)) |
| 1328 | | break; |
| 1329 | | |
| 1330 | | cdda_prefetch_sector++; |
| 1331 | | } |
| 1332 | | #else |
| 1333 | | play_cdda_sector(0,rawsec); |
| 1334 | | #endif |
| 1335 | | |
| 1336 | | // |
| 1337 | | |
| 1338 | | curpos[2]++; |
| 1339 | | if (curpos[2]==75) |
| 1191 | curpos.b[F]++; |
| 1192 | if (curpos.b[F]==75) |
| 1340 | 1193 | { |
| 1341 | | curpos[2]=0; |
| 1342 | | curpos[1]++; |
| 1343 | | if (curpos[1]==60) |
| 1194 | curpos.b[F]=0; |
| 1195 | curpos.b[S]++; |
| 1196 | if (curpos.b[S]==60) |
| 1344 | 1197 | { |
| 1345 | | curpos[1]=0; |
| 1346 | | curpos[0]++; |
| 1198 | curpos.b[S]=0; |
| 1199 | curpos.b[M]++; |
| 1347 | 1200 | } |
| 1348 | 1201 | } |
| 1349 | 1202 | |
| 1350 | | loc[0]=curpos[0]; |
| 1351 | | loc[1]=curpos[1]; |
| 1352 | | loc[2]=curpos[2]; |
| 1203 | loc.w=curpos.w; |
| 1353 | 1204 | |
| 1354 | 1205 | // |
| 1355 | 1206 | |
| 1207 | UINT32 sector = msf_to_lba_ps(loc.w); |
| 1208 | |
| 1356 | 1209 | if (mode&mode_autopause) |
| 1357 | 1210 | { |
| 1358 | | if (msf_to_sector(loc)>=autopause_sector) |
| 1211 | if (sector>=autopause_sector) |
| 1359 | 1212 | { |
| 1360 | 1213 | printf("autopause cdda\n"); |
| 1361 | 1214 | |
| 1362 | | command_result *res=new command_result; |
| 1215 | command_result *res=global_alloc(command_result); |
| 1363 | 1216 | res->res=intr_dataend; |
| 1364 | 1217 | res->data[0]=status_standby; |
| 1365 | 1218 | res->sz=1; |
| r22065 | r22066 | |
| 1369 | 1222 | } |
| 1370 | 1223 | } |
| 1371 | 1224 | |
| 1372 | | if (mode&mode_report) |
| 1225 | if ((mode&mode_report) && !(sector & 15)) // slow the int rate |
| 1373 | 1226 | { |
| 1374 | | command_result *res=new command_result; |
| 1375 | | res->res=intr_complete; //dataready; |
| 1227 | command_result *res=global_alloc(command_result); |
| 1228 | UINT8 track = cdrom_get_track(m_cdrom_handle, sector) + 1; |
| 1229 | res->res=intr_dataready; |
| 1376 | 1230 | |
| 1377 | 1231 | res->data[0]=status_playing|status_standby; |
| 1378 | | res->data[1]=0x01; |
| 1379 | | res->data[2]=0x80; |
| 1380 | | res->data[3]=decimal_to_bcd(loc[0]); |
| 1381 | | res->data[4]=decimal_to_bcd(loc[1])|0x80; |
| 1382 | | res->data[5]=decimal_to_bcd(loc[2]); |
| 1232 | res->data[1]=decimal_to_bcd(track); |
| 1233 | res->data[2]=1; |
| 1234 | if(sector & 0x10) |
| 1235 | { |
| 1236 | CDPOS tloc, start; |
| 1237 | start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1)); |
| 1238 | tloc.w = sub_loc(loc, start); |
| 1239 | res->data[3]=decimal_to_bcd(tloc.b[M]); |
| 1240 | res->data[4]=decimal_to_bcd(tloc.b[S]) | 0x80; |
| 1241 | res->data[5]=decimal_to_bcd(tloc.b[F]); |
| 1242 | } |
| 1243 | else |
| 1244 | { |
| 1245 | res->data[3]=decimal_to_bcd(loc.b[M]); |
| 1246 | res->data[4]=decimal_to_bcd(loc.b[S]); |
| 1247 | res->data[5]=decimal_to_bcd(loc.b[F]); |
| 1248 | } |
| 1383 | 1249 | |
| 1384 | 1250 | res->sz=8; |
| 1385 | 1251 | |
| r22065 | r22066 | |
| 1388 | 1254 | |
| 1389 | 1255 | unsigned int cyc=read_sector_cycles; |
| 1390 | 1256 | |
| 1391 | | event *ev=new event; |
| 1392 | | ev->t=next_sector_t - m_maincpu->total_cycles(); |
| 1393 | | ev->type=event_play_sector; |
| 1394 | | |
| 1395 | 1257 | next_sector_t+=cyc>>1; |
| 1396 | 1258 | |
| 1397 | | next_read_event=ev; |
| 1398 | | add_system_event(ev); |
| 1259 | next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL); |
| 1399 | 1260 | |
| 1400 | | read_next_sector(); |
| 1261 | if(!read_next_sector()) |
| 1262 | { |
| 1263 | command_result *res=global_alloc(command_result); |
| 1264 | res->res=intr_dataend; |
| 1265 | res->data[0]=status_standby; |
| 1266 | res->sz=1; |
| 1267 | cmd_complete(res); |
| 1268 | stop_read(); // assume we've reached the end |
| 1269 | } |
| 1401 | 1270 | } |
| 1402 | 1271 | } |
| 1403 | 1272 | |
| r22065 | r22066 | |
| 1408 | 1277 | |
| 1409 | 1278 | void psxcd_device::preread_sector() |
| 1410 | 1279 | { |
| 1411 | | next_read_event=NULL; |
| 1280 | UINT64 next_clock; |
| 1281 | int type; |
| 1282 | next_read_event=-1; |
| 1412 | 1283 | |
| 1413 | 1284 | // |
| 1414 | 1285 | |
| 1415 | | event *ev=new event; |
| 1416 | | |
| 1417 | | unsigned int pos=msf_to_sector(curpos); |
| 1286 | UINT32 pos=msf_to_lba_ps(curpos.w); |
| 1418 | 1287 | unsigned char *buf=&secbuf[sechead*raw_sector_size]; |
| 1419 | | if (! driver->read_sector(pos,buf,false)) |
| 1288 | if (! cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE)) |
| 1420 | 1289 | { |
| 1421 | | ev->t=(m_sysclock/60); |
| 1422 | | ev->type=event_preread_sector; |
| 1290 | next_clock=(m_sysclock/60); |
| 1291 | type=event_preread_sector; |
| 1423 | 1292 | |
| 1424 | 1293 | unsigned int cyc=read_sector_cycles; |
| 1425 | 1294 | if (mode&mode_double_speed) cyc>>=1; |
| 1426 | | next_sector_t=ev->t+(cyc-preread_delay)+m_maincpu->total_cycles(); |
| 1295 | next_sector_t=next_clock+(cyc-preread_delay)+m_maincpu->total_cycles(); |
| 1427 | 1296 | } else |
| 1428 | 1297 | { |
| 1429 | 1298 | memcpy(lastsechdr,buf+12,8); |
| 1430 | 1299 | |
| 1431 | 1300 | // |
| 1432 | 1301 | |
| 1433 | | command_result *res=new command_result; |
| 1302 | command_result *res=global_alloc(command_result); |
| 1434 | 1303 | res->res=intr_complete; |
| 1435 | 1304 | res->data[0]=status; |
| 1436 | 1305 | res->sz=1; |
| r22065 | r22066 | |
| 1443 | 1312 | |
| 1444 | 1313 | // |
| 1445 | 1314 | |
| 1446 | | ev->t=next_sector_t - m_maincpu->total_cycles(); |
| 1447 | | ev->type=event_read_sector; |
| 1315 | next_clock=next_sector_t - m_maincpu->total_cycles(); |
| 1316 | type=event_read_sector; |
| 1448 | 1317 | |
| 1449 | 1318 | //read_next_sector(); |
| 1450 | 1319 | } |
| 1451 | 1320 | |
| 1452 | | next_read_event=ev; |
| 1453 | | add_system_event(ev); |
| 1321 | next_read_event = add_system_event(type, next_clock, NULL); |
| 1454 | 1322 | } |
| 1455 | 1323 | |
| 1456 | 1324 | // |
| r22065 | r22066 | |
| 1468 | 1336 | status|=status_reading; |
| 1469 | 1337 | |
| 1470 | 1338 | secin=sechead=sectail=0; |
| 1471 | | xa_prefetch_sector=-1; |
| 1472 | 1339 | |
| 1473 | 1340 | unsigned int cyc=read_sector_cycles; |
| 1474 | 1341 | if (mode&mode_double_speed) cyc>>=1; |
| r22065 | r22066 | |
| 1477 | 1344 | |
| 1478 | 1345 | systime+=start_read_delay; |
| 1479 | 1346 | |
| 1480 | | event *ev=new event; |
| 1481 | | ev->t=start_read_delay+preread_delay; |
| 1482 | | ev->type=event_preread_sector; |
| 1483 | | |
| 1484 | 1347 | next_sector_t=systime+cyc; |
| 1485 | | next_read_event=ev; |
| 1486 | | add_system_event(ev); |
| 1487 | | |
| 1488 | | prefetch_next_sector(); |
| 1348 | next_read_event = add_system_event(event_preread_sector, start_read_delay+preread_delay, NULL); |
| 1489 | 1349 | } |
| 1490 | 1350 | |
| 1491 | 1351 | // |
| r22065 | r22066 | |
| 1513 | 1373 | status|=status_playing; |
| 1514 | 1374 | |
| 1515 | 1375 | secin=sechead=sectail=0; |
| 1516 | | cdda_prefetch_sector=-1; |
| 1517 | 1376 | |
| 1518 | 1377 | if (mode&mode_autopause) |
| 1519 | 1378 | { |
| 1520 | | unsigned int pos=msf_to_sector(curpos); |
| 1521 | | driver->find_track(pos+150,NULL,&autopause_sector); |
| 1379 | UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150); |
| 1380 | autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + cdrom_get_toc(m_cdrom_handle)->tracks[track].frames; |
| 1522 | 1381 | // printf("pos=%d auto=%d\n",pos,autopause_sector); |
| 1523 | 1382 | } |
| 1524 | 1383 | |
| r22065 | r22066 | |
| 1526 | 1385 | |
| 1527 | 1386 | next_sector_t=m_maincpu->total_cycles()+cyc; |
| 1528 | 1387 | |
| 1529 | | event *ev=new event; |
| 1530 | | ev->t=next_sector_t - m_maincpu->total_cycles(); |
| 1531 | | ev->type=event_play_sector; |
| 1532 | | |
| 1533 | 1388 | next_sector_t+=cyc>>1; |
| 1534 | 1389 | |
| 1535 | | next_read_event=ev; |
| 1536 | | add_system_event(ev); |
| 1390 | next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL); |
| 1537 | 1391 | |
| 1538 | 1392 | read_next_sector(); |
| 1539 | 1393 | } |
| r22065 | r22066 | |
| 1551 | 1405 | status&=~(status_reading|status_playing); |
| 1552 | 1406 | streaming=false; |
| 1553 | 1407 | |
| 1554 | | if (next_read_event) |
| 1408 | if (next_read_event != -1) |
| 1555 | 1409 | { |
| 1556 | | next_read_event->timer->adjust(attotime::never, 0, attotime::never); |
| 1557 | | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
| 1558 | | { |
| 1559 | | if (m_timers[i] == next_read_event->timer) |
| 1560 | | { |
| 1561 | | m_timerinuse[i] = false; |
| 1562 | | m_eventfortimer[i] = NULL; |
| 1563 | | break; |
| 1564 | | } |
| 1565 | | } |
| 1566 | | global_free(next_read_event); |
| 1567 | | next_read_event=NULL; |
| 1410 | m_timers[next_read_event]->adjust(attotime::never, 0, attotime::never); |
| 1411 | m_timerinuse[next_read_event] = false; |
| 1412 | next_read_event = -1; |
| 1568 | 1413 | } |
| 1569 | 1414 | |
| 1570 | | unsigned int sector=msf_to_sector(curpos); |
| 1415 | UINT32 sector=msf_to_lba_ps(curpos.w); |
| 1571 | 1416 | m_spu->flush_xa(sector); |
| 1572 | 1417 | m_spu->flush_cdda(sector); |
| 1573 | 1418 | } |
| r22065 | r22066 | |
| 1575 | 1420 | // |
| 1576 | 1421 | // |
| 1577 | 1422 | // |
| 1578 | | |
| 1579 | | void psxcd_device::set_driver(cdrom_driver *d) |
| 1580 | | { |
| 1581 | | char err[1024]; |
| 1582 | | |
| 1583 | | if (d) |
| 1584 | | { |
| 1585 | | if (d->is_usable(err,1024)) |
| 1586 | | { |
| 1587 | | driver=d; |
| 1588 | | open=false; |
| 1589 | | |
| 1590 | | if (! first_open) |
| 1591 | | { |
| 1592 | | command_result *res=new command_result; |
| 1593 | | res->res=intr_acknowledge; |
| 1594 | | res->data[0]=status_standby; |
| 1595 | | res->sz=1; |
| 1596 | | |
| 1597 | | cmd_complete(res); |
| 1598 | | |
| 1599 | | open_nops=10; |
| 1600 | | } |
| 1601 | | |
| 1602 | | first_open=false; |
| 1603 | | } |
| 1604 | | } else |
| 1605 | | { |
| 1606 | | driver=NULL; |
| 1607 | | open=false; |
| 1608 | | |
| 1609 | | command_result *res=new command_result; |
| 1610 | | res->res=intr_acknowledge; |
| 1611 | | res->data[0]=status_shellopen; |
| 1612 | | res->sz=1; |
| 1613 | | |
| 1614 | | cmd_complete(res); |
| 1615 | | } |
| 1616 | | } |
| 1617 | | |
| 1618 | | // |
| 1619 | | // |
| 1620 | | // |
| 1621 | 1423 | void psxcd_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) |
| 1622 | 1424 | { |
| 1623 | | event *ev = m_eventfortimer[tid]; |
| 1624 | | |
| 1625 | | // printf("timer %d fired, performing event type %d\n", tid, ev->type); |
| 1626 | | |
| 1627 | | switch (ev->type) |
| 1425 | m_timerinuse[tid] = false; |
| 1426 | switch (param) |
| 1628 | 1427 | { |
| 1629 | 1428 | case event_cmd_complete: |
| 1630 | 1429 | { |
| r22065 | r22066 | |
| 1632 | 1431 | printf("cdrom:: event cmd complete\n"); |
| 1633 | 1432 | #endif |
| 1634 | 1433 | |
| 1635 | | command_result *res=new command_result; |
| 1636 | | memcpy(res,ev->data,sizeof(command_result)); |
| 1637 | | cmd_complete(res); |
| 1434 | cmd_complete((command_result *)ptr); |
| 1638 | 1435 | break; |
| 1639 | 1436 | } |
| 1640 | 1437 | |
| r22065 | r22066 | |
| 1649 | 1446 | case event_play_sector: |
| 1650 | 1447 | play_sector(); |
| 1651 | 1448 | break; |
| 1652 | | } |
| 1653 | 1449 | |
| 1654 | | // free the timer |
| 1655 | | // printf("Freeing timer %d\n", tid); |
| 1656 | | m_timers[tid]->adjust(attotime::never, 0, attotime::never); |
| 1657 | | m_timerinuse[tid] = false; |
| 1658 | | m_eventfortimer[tid] = NULL; |
| 1659 | | |
| 1660 | | global_free(ev); |
| 1450 | case event_change_disk: |
| 1451 | open = false; |
| 1452 | break; |
| 1453 | } |
| 1661 | 1454 | } |
| 1662 | 1455 | |
| 1663 | | void psxcd_device::add_system_event(event *ev) |
| 1456 | int psxcd_device::add_system_event(int type, UINT64 t, void *ptr) |
| 1664 | 1457 | { |
| 1665 | | emu_timer *timer = NULL; |
| 1666 | | int tnum = -1; |
| 1667 | | |
| 1668 | | // allocate a timer for this event |
| 1669 | | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
| 1458 | // t is in maincpu clock cycles |
| 1459 | UINT32 hz = m_sysclock / t; |
| 1460 | // printf("add_system_event: event type %d for %d hz (using timer %d)\n", ev->type, hz, tnum); |
| 1461 | for(int i = 0; i < MAX_PSXCD_TIMERS; i++) |
| 1670 | 1462 | { |
| 1671 | | if (!m_timerinuse[i]) |
| 1463 | if(!m_timerinuse[i]) |
| 1672 | 1464 | { |
| 1673 | | tnum = i; |
| 1674 | | timer = m_timers[i]; |
| 1465 | m_timers[i]->adjust(attotime::from_hz(hz), type, attotime::never); |
| 1466 | m_timers[i]->set_ptr(ptr); |
| 1675 | 1467 | m_timerinuse[i] = true; |
| 1676 | | m_eventfortimer[i] = ev; |
| 1677 | | break; |
| 1468 | return i; |
| 1678 | 1469 | } |
| 1679 | 1470 | } |
| 1680 | | |
| 1681 | | if (tnum == -1) |
| 1682 | | { |
| 1683 | | fatalerror("PSXCD: ran out of timers!\n"); |
| 1684 | | } |
| 1685 | | |
| 1686 | | // ev->t is in maincpu clock cycles |
| 1687 | | UINT32 hz = m_sysclock / ev->t; |
| 1688 | | // printf("add_system_event: event type %d for %d hz (using timer %d)\n", ev->type, hz, tnum); |
| 1689 | | timer->adjust(attotime::from_hz(hz), tnum, attotime::never); |
| 1690 | | |
| 1691 | | // back-reference the timer from the event |
| 1692 | | ev->timer = timer; |
| 1471 | fatalerror("psxcd: out of timers\n"); |
| 1472 | return 0; |
| 1693 | 1473 | } |