trunk/src/mame/machine/megacdcd.c
| r19302 | r19303 | |
| 24 | 24 | CDD_RX[i] = 0; |
| 25 | 25 | NeoCDCommsWordCount = 0; |
| 26 | 26 | NeoCDAssyStatus = 0; |
| 27 | | NeoCDTrack = 0; |
| 28 | | NeoCDSectorMin = 0; |
| 29 | | NeoCDSectorSec = 0; |
| 30 | | NeoCDSectorFrm = 0; |
| 31 | 27 | SCD_CURLBA = 0; |
| 32 | 28 | for (int i=0;i<2352;i++) |
| 33 | 29 | NeoCDSectorData[i] = 0; |
| r19302 | r19303 | |
| 116 | 112 | CDD_RX[9] = checksum; |
| 117 | 113 | } |
| 118 | 114 | |
| 115 | // converts our 16-bit working regs to 8-bit regs and checksums them |
| 119 | 116 | void lc89510_temp_device::CDD_Export(void) |
| 120 | 117 | { |
| 121 | 118 | CDD_RX[0] = (CDD_STATUS & 0xff00)>>8; |
| r19302 | r19303 | |
| 277 | 274 | CDD_FRAME |= 0x0800; |
| 278 | 275 | } |
| 279 | 276 | |
| 277 | // verify what this is.. the NeoCd emu code only checked the track type but |
| 278 | // checked it where we put CDD_EXT, not CDD_FRAME (RX[7] vs RX[8] in Export) |
| 279 | void lc89510_temp_device::CDD_GetTrackType(void) |
| 280 | { |
| 281 | CLEAR_CDD_RESULT |
| 282 | |
| 283 | int track = (CDD_TX[5] & 0xF) + (CDD_TX[4] & 0xF) * 10; |
| 284 | int last_track = cdrom_get_last_track(segacd.cd); |
| 285 | |
| 286 | CDD_STATUS &= 0xFF; |
| 287 | if(segacd.cd == NULL) // no cd is there, bail out |
| 288 | return; |
| 289 | CDD_STATUS |= SCD_STATUS; |
| 290 | |
| 291 | if (track > last_track) |
| 292 | track = last_track; |
| 293 | |
| 294 | if (track < 1) |
| 295 | track = 1; |
| 296 | |
| 297 | if (segacd.toc->tracks[track - 1].trktype != CD_TRACK_AUDIO) |
| 298 | { |
| 299 | CDD_EXT = 0x08; |
| 300 | CDD_FRAME |= 0x0800; |
| 301 | } |
| 302 | |
| 303 | |
| 304 | |
| 305 | } |
| 306 | |
| 280 | 307 | UINT32 lc89510_temp_device::getmsf_from_regs(void) |
| 281 | 308 | { |
| 282 | 309 | UINT32 msf = 0; |
| r19302 | r19303 | |
| 631 | 658 | case TOCCMD_LENGTH: CDD_Length(); break; |
| 632 | 659 | case TOCCMD_FIRSTLAST: CDD_FirstLast(); break; |
| 633 | 660 | case TOCCMD_TRACKADDR: CDD_GetTrackAdr(); break; |
| 661 | case 6: CDD_GetTrackType(); break; // NGCD, might be wrong, make sure Sega CD doesn't hate it |
| 634 | 662 | default: CDD_GetStatus(); break; |
| 635 | 663 | } |
| 636 | 664 | } |
| r19302 | r19303 | |
| 958 | 986 | return CDEmuStatus; |
| 959 | 987 | } |
| 960 | 988 | |
| 961 | | UINT8* lc89510_temp_device::CDEmuReadQChannel(int SCD_CURLBA) |
| 962 | | { |
| 963 | | // printf("CDEmuReadQChannel\n"); |
| 964 | | static unsigned char QChannelData[8]; |
| 965 | 989 | |
| 966 | | if(segacd.cd == NULL) // no cd is there, bail out |
| 967 | | return QChannelData; |
| 968 | | |
| 969 | | // SCD_CURLBA |
| 970 | | switch (CDEmuStatus) { |
| 971 | | case reading: |
| 972 | | case playing: { |
| 973 | | |
| 974 | | UINT32 msf; |
| 975 | | msf = lba_to_msf_alt(SCD_CURLBA+150); |
| 976 | | |
| 977 | | |
| 978 | | |
| 979 | | QChannelData[0] = cdrom_get_track(segacd.cd, SCD_CURLBA); |
| 980 | | |
| 981 | | QChannelData[1] = (msf >> 16)&0xff; |
| 982 | | QChannelData[2] = (msf >> 8)&0xff; |
| 983 | | QChannelData[3] = (msf >> 0)&0xff; |
| 984 | | |
| 985 | | int elapsedlba; |
| 986 | | elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].physframeofs; |
| 987 | | msf = lba_to_msf_alt (elapsedlba); |
| 988 | | |
| 989 | | QChannelData[4] = (msf >> 16)&0xff; |
| 990 | | QChannelData[5] = (msf >> 8)&0xff; |
| 991 | | QChannelData[6] = (msf >> 0)&0xff; |
| 992 | | |
| 993 | | if (QChannelData[0]==1) |
| 994 | | QChannelData[7] = 0x4; |
| 995 | | else |
| 996 | | QChannelData[7] = 0x0; |
| 997 | | |
| 998 | | break; |
| 999 | | } |
| 1000 | | case paused: { |
| 1001 | | break; |
| 1002 | | } |
| 1003 | | default: { |
| 1004 | | memset(QChannelData, 0, sizeof(QChannelData)); |
| 1005 | | } |
| 1006 | | } |
| 1007 | | |
| 1008 | | return QChannelData; |
| 1009 | | } |
| 1010 | | |
| 1011 | | UINT8* lc89510_temp_device::CDEmuReadTOC(INT32 track) |
| 1012 | | { |
| 1013 | | // printf("CDEmuReadTOC\n"); |
| 1014 | | |
| 1015 | | static unsigned char TOCEntry[4]; |
| 1016 | | |
| 1017 | | if(segacd.cd == NULL) |
| 1018 | | return TOCEntry; |
| 1019 | | |
| 1020 | | |
| 1021 | | if (track == -1) { |
| 1022 | | printf("get first/last track nums\n"); |
| 1023 | | TOCEntry[0] = 1; |
| 1024 | | TOCEntry[1] = cdrom_get_last_track(segacd.cd); |
| 1025 | | TOCEntry[2] = 0; |
| 1026 | | TOCEntry[3] = 0; |
| 1027 | | |
| 1028 | | return TOCEntry; |
| 1029 | | } |
| 1030 | | else if (track == -2) { |
| 1031 | | printf("get disc length\n"); |
| 1032 | | |
| 1033 | | UINT32 startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].physframeofs); |
| 1034 | | UINT32 startmsf = lba_to_msf_alt( startlba ); |
| 1035 | | |
| 1036 | | |
| 1037 | | TOCEntry[0] = (startmsf >> 16)&0xff; |
| 1038 | | TOCEntry[1] = (startmsf >> 8)&0xff; |
| 1039 | | TOCEntry[2] = (startmsf >> 0)&0xff; |
| 1040 | | |
| 1041 | | TOCEntry[3] = 0; |
| 1042 | | |
| 1043 | | return TOCEntry; |
| 1044 | | } |
| 1045 | | else |
| 1046 | | { |
| 1047 | | printf("get track address\n"); |
| 1048 | | |
| 1049 | | int last_track = cdrom_get_last_track(segacd.cd); |
| 1050 | | |
| 1051 | | if (track > last_track) |
| 1052 | | track = last_track; |
| 1053 | | |
| 1054 | | if (track < 1) |
| 1055 | | track = 1; |
| 1056 | | |
| 1057 | | UINT32 startlba = (segacd.toc->tracks[track-1].physframeofs); |
| 1058 | | UINT32 startmsf = lba_to_msf_alt( startlba+150 ); |
| 1059 | | |
| 1060 | | TOCEntry[0] = (startmsf >> 16)&0xff; |
| 1061 | | TOCEntry[1] = (startmsf >> 8)&0xff; |
| 1062 | | TOCEntry[2] = (startmsf >> 0)&0xff; |
| 1063 | | TOCEntry[3] = track % 10;; |
| 1064 | | } |
| 1065 | | |
| 1066 | | return TOCEntry; |
| 1067 | | |
| 1068 | | } |
| 1069 | | |
| 1070 | 990 | static void CDEmuStartRead() |
| 1071 | 991 | { |
| 1072 | 992 | printf("CDEmuStartRead\n"); |
| r19302 | r19303 | |
| 1103 | 1023 | |
| 1104 | 1024 | |
| 1105 | 1025 | |
| 1106 | | void lc89510_temp_device::NeoCDLBAToMSF(const INT32 LBA) |
| 1107 | | { |
| 1108 | | NeoCDSectorMin = (LBA + CD_FRAMES_PREGAP) / CD_FRAMES_MINUTE; |
| 1109 | | NeoCDSectorSec = (LBA + CD_FRAMES_PREGAP) % CD_FRAMES_MINUTE / CD_FRAMES_SECOND; |
| 1110 | | NeoCDSectorFrm = (LBA + CD_FRAMES_PREGAP) % CD_FRAMES_SECOND; |
| 1111 | | } |
| 1112 | 1026 | |
| 1113 | 1027 | |
| 1114 | 1028 | void lc89510_temp_device::NeoCDCommsReset() |
| r19302 | r19303 | |
| 1397 | 1311 | break; |
| 1398 | 1312 | case CMD_GETTOC: // CDD_Handle_TOC_Commands(); |
| 1399 | 1313 | // //bprintf(PRINT_ERROR, _T(" CD comms received command %i\n"), CDD_TX[0]); |
| 1400 | | CDD_RX[1] = CDD_TX[3]; |
| 1401 | | switch (CDD_TX[3]) { |
| 1402 | | |
| 1403 | | |
| 1404 | | |
| 1405 | | case TOCCMD_CURPOS: { // CDD_GetPos(); |
| 1406 | | UINT8* ChannelData = CDEmuReadQChannel(SCD_CURLBA); |
| 1407 | | |
| 1408 | | CDD_RX[2] = ChannelData[1] / 10; |
| 1409 | | CDD_RX[3] = ChannelData[1] % 10; |
| 1410 | | |
| 1411 | | CDD_RX[4] = ChannelData[2] / 10; |
| 1412 | | CDD_RX[5] = ChannelData[2] % 10; |
| 1413 | | |
| 1414 | | CDD_RX[6] = ChannelData[3] / 10; |
| 1415 | | CDD_RX[7] = ChannelData[3] % 10; |
| 1416 | | |
| 1417 | | CDD_RX[8] = ChannelData[7]; |
| 1418 | | |
| 1419 | | // //bprintf(PRINT_ERROR, _T(" %02i %02i:%02i:%02i %02i:%02i:%02i %02i\n"), ChannelData[0], ChannelData[1], ChannelData[2], ChannelData[3], ChannelData[4], ChannelData[5], ChannelData[6], ChannelData[7]); |
| 1420 | | |
| 1421 | | break; |
| 1422 | | } |
| 1423 | | case TOCCMD_TRKPOS: { // CDD_GetTrackPos(); |
| 1424 | | UINT8* ChannelData = CDEmuReadQChannel(SCD_CURLBA); |
| 1425 | | |
| 1426 | | CDD_RX[2] = ChannelData[4] / 10; |
| 1427 | | CDD_RX[3] = ChannelData[4] % 10; |
| 1428 | | |
| 1429 | | CDD_RX[4] = ChannelData[5] / 10; |
| 1430 | | CDD_RX[5] = ChannelData[5] % 10; |
| 1431 | | |
| 1432 | | CDD_RX[6] = ChannelData[6] / 10; |
| 1433 | | CDD_RX[7] = ChannelData[6] % 10; |
| 1434 | | |
| 1435 | | CDD_RX[8] = ChannelData[7]; |
| 1436 | | |
| 1437 | | break; |
| 1438 | | } |
| 1439 | | case TOCCMD_CURTRK: { // CDD_GetTrack(); |
| 1440 | | |
| 1441 | | UINT8* ChannelData = CDEmuReadQChannel(SCD_CURLBA); |
| 1442 | | |
| 1443 | | CDD_RX[2] = ChannelData[0] / 10; |
| 1444 | | CDD_RX[3] = ChannelData[0] % 10; |
| 1445 | | |
| 1446 | | |
| 1447 | | CDD_RX[8] = ChannelData[7]; |
| 1448 | | |
| 1449 | | break; |
| 1450 | | } |
| 1451 | | case TOCCMD_LENGTH: { // CDD_Length(); |
| 1452 | | UINT8* TOCEntry = CDEmuReadTOC(-2); |
| 1453 | | |
| 1454 | | CDD_RX[2] = TOCEntry[0] / 10; |
| 1455 | | CDD_RX[3] = TOCEntry[0] % 10; |
| 1456 | | |
| 1457 | | CDD_RX[4] = TOCEntry[1] / 10; |
| 1458 | | CDD_RX[5] = TOCEntry[1] % 10; |
| 1459 | | |
| 1460 | | CDD_RX[6] = TOCEntry[2] / 10; |
| 1461 | | CDD_RX[7] = TOCEntry[2] % 10; |
| 1462 | | |
| 1463 | | break; |
| 1464 | | } |
| 1465 | | case TOCCMD_FIRSTLAST: { // CDD_FirstLast(); |
| 1466 | | UINT8* TOCEntry = CDEmuReadTOC(-1); |
| 1467 | | |
| 1468 | | CDD_RX[2] = TOCEntry[0] / 10; |
| 1469 | | CDD_RX[3] = TOCEntry[0] % 10; |
| 1470 | | |
| 1471 | | CDD_RX[4] = TOCEntry[1] / 10; |
| 1472 | | CDD_RX[5] = TOCEntry[1] % 10; |
| 1473 | | |
| 1474 | | break; |
| 1475 | | } |
| 1476 | | case TOCCMD_TRACKADDR: { // CDD_GetTrackAdr(); |
| 1477 | | NeoCDTrack = CDD_TX[4] * 10 + CDD_TX[5]; |
| 1478 | | |
| 1479 | | UINT8* TOCEntry = CDEmuReadTOC(NeoCDTrack); |
| 1480 | | |
| 1481 | | CDD_RX[2] = TOCEntry[0] / 10; |
| 1482 | | CDD_RX[3] = TOCEntry[0] % 10; |
| 1483 | | |
| 1484 | | CDD_RX[4] = TOCEntry[1] / 10; |
| 1485 | | CDD_RX[5] = TOCEntry[1] % 10; |
| 1486 | | |
| 1487 | | CDD_RX[6] = TOCEntry[2] / 10; |
| 1488 | | CDD_RX[7] = TOCEntry[2] % 10; |
| 1489 | | |
| 1490 | | // bit 3 of the 1st minutes digit indicates a data track |
| 1491 | | if (TOCEntry[3] & 4) { |
| 1492 | | CDD_RX[6] |= 8; |
| 1493 | | } |
| 1494 | | |
| 1495 | | CDD_RX[8] = NeoCDTrack % 10; |
| 1496 | | |
| 1497 | | break; |
| 1498 | | } |
| 1499 | | |
| 1500 | | case 6: { |
| 1501 | | |
| 1502 | | UINT8* ChannelData = CDEmuReadQChannel(SCD_CURLBA); |
| 1503 | | |
| 1504 | | CDD_RX[8] = ChannelData[7]; |
| 1505 | | |
| 1506 | | break; |
| 1507 | | } |
| 1508 | | |
| 1509 | | case 7: { |
| 1510 | | |
| 1511 | | // must be 02, 0E, 0F, or 05 |
| 1512 | | CDD_RX[2] = 0; |
| 1513 | | CDD_RX[3] = 5; |
| 1514 | | |
| 1515 | | CDD_RX[4] = 0; |
| 1516 | | CDD_RX[5] = 0; |
| 1517 | | |
| 1518 | | CDD_RX[6] = 0; |
| 1519 | | CDD_RX[7] = 0; |
| 1520 | | break; |
| 1521 | | } |
| 1522 | | } |
| 1314 | |
| 1315 | CDD_Handle_TOC_Commands(); |
| 1316 | CDD_Export(); |
| 1523 | 1317 | break; |
| 1524 | 1318 | |
| 1525 | 1319 | |
| r19302 | r19303 | |
| 1689 | 1483 | |
| 1690 | 1484 | void lc89510_temp_device::LC8951UpdateHeader() // neocd |
| 1691 | 1485 | { |
| 1692 | | NeoCDLBAToMSF(SCD_CURLBA); |
| 1693 | 1486 | |
| 1694 | 1487 | if (LC8951RegistersW[REG_W_CTRL1] & 1) { |
| 1695 | 1488 | |
| r19302 | r19303 | |
| 1703 | 1496 | } else { |
| 1704 | 1497 | |
| 1705 | 1498 | // HEAD registers have header |
| 1499 | UINT32 msf = lba_to_msf_alt(SCD_CURLBA+150); |
| 1706 | 1500 | |
| 1707 | | LC8951RegistersR[REG_R_HEAD0] = ((NeoCDSectorMin / 10) << 4) | (NeoCDSectorMin % 10); // HEAD0 |
| 1708 | | LC8951RegistersR[REG_R_HEAD1] = ((NeoCDSectorSec / 10) << 4) | (NeoCDSectorSec % 10); // HEAD1 |
| 1709 | | LC8951RegistersR[REG_R_HEAD2] = ((NeoCDSectorFrm / 10) << 4) | (NeoCDSectorFrm % 10); // HEAD2 |
| 1710 | | LC8951RegistersR[REG_R_HEAD3] = 1; // HEAD3 |
| 1501 | LC8951RegistersR[REG_R_HEAD0] = to_bcd (((msf & 0x00ff0000)>>16), true); // HEAD0 |
| 1502 | LC8951RegistersR[REG_R_HEAD1] = to_bcd (((msf & 0x0000ff00)>>8), true); // HEAD1 |
| 1503 | LC8951RegistersR[REG_R_HEAD2] = to_bcd (((msf & 0x000000ff)>>0), true); // HEAD2 |
| 1504 | LC8951RegistersR[REG_R_HEAD3] = 0x1; // HEAD3 |
| 1711 | 1505 | } |
| 1712 | 1506 | } |
| 1713 | 1507 | |