Common Source Code Project for Qt (a.k.a for FM-7).
修订版 | 153e10b4100fa65f426b3c2a9ee123ced5d33290 (tree) |
---|---|
时间 | 2020-11-16 17:00:08 |
作者 | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[VM][FMTOWNS][CDROM] Implement ISO file feature, MODE1/2/RAW read feature.
[VM][FMTOWNS][CDROM] check sector status per sector.
@@ -138,6 +138,7 @@ void TOWNS_CDROM::initialize() | ||
138 | 138 | |
139 | 139 | cdda_status = CDDA_OFF; |
140 | 140 | is_cue = false; |
141 | + is_iso = false; | |
141 | 142 | current_track = 0; |
142 | 143 | read_sector = 0; |
143 | 144 |
@@ -747,7 +748,7 @@ void TOWNS_CDROM::read_cdrom() | ||
747 | 748 | param_queue[0], param_queue[1], param_queue[2], |
748 | 749 | param_queue[3], param_queue[4], param_queue[5], |
749 | 750 | pad1, dcmd); |
750 | - position = lba1 * physical_block_size(); | |
751 | + position = lba1 * ((is_iso) ? 2048 : physical_block_size()); | |
751 | 752 | __remain = (lba2 - lba1 + 1); |
752 | 753 | read_length = __remain * logical_block_size(); |
753 | 754 | read_length_bak = read_length; |
@@ -777,20 +778,22 @@ void TOWNS_CDROM::read_cdrom() | ||
777 | 778 | |
778 | 779 | void TOWNS_CDROM::read_cdrom_mode1() |
779 | 780 | { |
781 | + read_mode = CDROM_READ_MODE1; | |
780 | 782 | read_cdrom(); |
781 | 783 | } |
782 | 784 | |
783 | 785 | void TOWNS_CDROM::read_cdrom_mode2() |
784 | 786 | { |
787 | + read_mode = CDROM_READ_MODE2; | |
785 | 788 | read_cdrom(); |
786 | 789 | } |
787 | 790 | |
788 | 791 | void TOWNS_CDROM::read_cdrom_raw() |
789 | 792 | { |
793 | + read_mode = CDROM_READ_RAW; | |
790 | 794 | read_cdrom(); |
791 | 795 | } |
792 | 796 | |
793 | - | |
794 | 797 | void TOWNS_CDROM::set_status(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) |
795 | 798 | { |
796 | 799 | status_queue->clear(); |
@@ -1101,7 +1104,7 @@ uint32_t TOWNS_CDROM::read_signal(int id) | ||
1101 | 1104 | } |
1102 | 1105 | if(fio_img->IsOpened()) { |
1103 | 1106 | uint32_t cur_position = (uint32_t)fio_img->Ftell(); |
1104 | - cur_position = cur_position / physical_block_size(); | |
1107 | + cur_position = cur_position / (is_iso) ? 2048 : physical_block_size(); | |
1105 | 1108 | if(cur_position >= max_logical_block) { |
1106 | 1109 | cur_position = max_logical_block; |
1107 | 1110 | } |
@@ -1159,6 +1162,7 @@ const int TOWNS_CDROM::physical_block_size() | ||
1159 | 1162 | { |
1160 | 1163 | if(current_track <= 0) return 2352; // PAD |
1161 | 1164 | if(!mounted()) return 2352; // PAD |
1165 | + if(is_iso) return 2352; | |
1162 | 1166 | switch(toc_table[current_track].type) { |
1163 | 1167 | case MODE_AUDIO: |
1164 | 1168 | return 2352; |
@@ -1184,6 +1188,7 @@ const int TOWNS_CDROM::logical_block_size() | ||
1184 | 1188 | { |
1185 | 1189 | if(current_track <= 0) return 2352; // PAD |
1186 | 1190 | if(!mounted()) return 2352; // PAD |
1191 | + if(is_iso) return 2048; | |
1187 | 1192 | switch(toc_table[current_track].type) { |
1188 | 1193 | case MODE_AUDIO: |
1189 | 1194 | return 2352; |
@@ -1323,14 +1328,14 @@ void TOWNS_CDROM::event_callback(int event_id, int err) | ||
1323 | 1328 | clear_event(this, event_time_out); |
1324 | 1329 | // ToDo: Prefetch 20201116 |
1325 | 1330 | // if((databuffer->left() < logical_block_size()) && (read_length > 0)) { |
1326 | - if(!(databuffer->empty()) && (read_length > 0)) { | |
1327 | - register_event(this, EVENT_CDROM_SEEK_COMPLETED, | |
1328 | - (1.0e6 / ((double)transfer_speed * 150.0e3)) * | |
1329 | - 2.0, | |
1330 | - false, | |
1331 | - &event_seek_completed); | |
1332 | - break; // EXIT | |
1333 | - } | |
1331 | +// if(!(databuffer->empty()) && (read_length > 0)) { | |
1332 | +// register_event(this, EVENT_CDROM_SEEK_COMPLETED, | |
1333 | +// (1.0e6 / ((double)transfer_speed * 150.0e3)) * | |
1334 | +// 2.0, | |
1335 | +// false, | |
1336 | +// &event_seek_completed); | |
1337 | +// break; // EXIT | |
1338 | +// } | |
1334 | 1339 | if(read_length > 0) { |
1335 | 1340 | mcu_ready = false; |
1336 | 1341 | bool stat = false; |
@@ -1339,9 +1344,7 @@ void TOWNS_CDROM::event_callback(int event_id, int err) | ||
1339 | 1344 | // Note: Still error with reading D000h at TownsOS v1.1L30. |
1340 | 1345 | // Maybe data has changed to 1Fh from 8Eh. |
1341 | 1346 | /// 20200926 K.O |
1342 | - if(read_length > 0) { | |
1343 | - stat = read_buffer(1); | |
1344 | - } | |
1347 | + stat = read_buffer(1); | |
1345 | 1348 | if((stat)) { |
1346 | 1349 | register_event(this, EVENT_CDROM_NEXT_SECTOR, |
1347 | 1350 | (1.0e6 / ((double)transfer_speed * 150.0e3)) * |
@@ -1392,44 +1395,168 @@ void TOWNS_CDROM::event_callback(int event_id, int err) | ||
1392 | 1395 | } |
1393 | 1396 | } |
1394 | 1397 | |
1395 | -bool TOWNS_CDROM::read_buffer(int sectors) | |
1398 | +bool TOWNS_CDROM::read_mode1_iso(int sectors) | |
1396 | 1399 | { |
1397 | - if(!(mounted())) { | |
1398 | - status_not_ready(false); | |
1399 | - return false; | |
1400 | - } | |
1401 | - if(media_changed) { | |
1402 | - status_media_changed(false); | |
1403 | - return false; | |
1400 | + while(sectors > 0) { | |
1401 | + cd_data_iso_t tmpbuf; | |
1402 | + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); | |
1403 | + int tmp_length = sizeof(cd_data_iso_t); | |
1404 | + if(!(seek_relative_frame_in_image(read_sector))) { | |
1405 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1406 | + return false; | |
1407 | + } | |
1408 | + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { | |
1409 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1410 | + return false; | |
1411 | + } | |
1412 | + for(int i = 0; i < sizeof(tmpbuf.data); i++) { | |
1413 | +// if(read_length < 0) { | |
1414 | + // ToDo: Change to sector error. | |
1415 | +// status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1416 | +// return false; | |
1417 | +// } | |
1418 | +// if(databuffer->full()) { | |
1419 | + // ToDo: Change to buffer overflow | |
1420 | +// status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1421 | +// return false; | |
1422 | +// } | |
1423 | + uint8_t value = tmpbuf.data[i]; | |
1424 | + write_a_byte(value); | |
1425 | + read_length--; | |
1426 | + } | |
1427 | + position += 2048; | |
1428 | + read_sector++; | |
1429 | + sectors--; | |
1430 | + access = true; | |
1404 | 1431 | } |
1405 | - uint32_t offset = 0; | |
1406 | -// if(!(seek_relative_frame_in_image(position / physical_block_size()))) { | |
1407 | - if(!(seek_relative_frame_in_image(read_sector))) { | |
1408 | - status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1409 | - return false; | |
1432 | + return true; | |
1433 | +} | |
1434 | + | |
1435 | +bool TOWNS_CDROM::read_mode1(int sectors) | |
1436 | +{ | |
1437 | + while(sectors > 0) { | |
1438 | + cd_data_mode1_t tmpbuf; | |
1439 | + int tmp_length = sizeof(cd_data_mode1_t); | |
1440 | + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); | |
1441 | + if(!(seek_relative_frame_in_image(read_sector))) { | |
1442 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1443 | + return false; | |
1444 | + } | |
1445 | + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { | |
1446 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1447 | + return false; | |
1448 | + } | |
1449 | + //! ToDo: Check header address. | |
1450 | + pair32_t msf; | |
1451 | + msf.d = lba_to_msf(read_sector + toc_table[current_track].pregap); | |
1452 | + if((tmpbuf.header.addr_m != msf.b.h2) || | |
1453 | + (tmpbuf.header.addr_s != msf.b.h) || | |
1454 | + (tmpbuf.header.addr_f != msf.b.l)) { | |
1455 | + out_debug_log(_T("WARNING: Reading from different sector MSF\nEXPECTED=%02X/%02X/%02X\nREAD =%02X/%02X/%02X"), | |
1456 | + tmpbuf.header.addr_m, tmpbuf.header.addr_s, tmpbuf.header.addr_f, | |
1457 | + msf.b.h2, msf.b.h, msf.b.l); | |
1458 | + } | |
1459 | + for(int i = 0; i < sizeof(tmpbuf.data); i++) { | |
1460 | + if(read_length < 0) { | |
1461 | + // ToDo: Change to sector error. | |
1462 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1463 | + return false; | |
1464 | + } | |
1465 | + if(databuffer->full()) { | |
1466 | + // ToDo: Change to buffer overflow | |
1467 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1468 | + return false; | |
1469 | + } | |
1470 | + uint8_t value = tmpbuf.data[i]; | |
1471 | + write_a_byte(value); | |
1472 | + read_length--; | |
1473 | + } | |
1474 | + position += physical_block_size(); | |
1475 | + read_sector++; | |
1476 | + sectors--; | |
1477 | + access = true; | |
1410 | 1478 | } |
1479 | + return true; | |
1480 | +} | |
1481 | + | |
1482 | +bool TOWNS_CDROM::read_mode2(int sectors) | |
1483 | +{ | |
1411 | 1484 | while(sectors > 0) { |
1412 | - uint8_t tmp_buffer[2448] = {0}; | |
1413 | - int tmp_length = physical_block_size() - offset; | |
1414 | - | |
1415 | - if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) { | |
1485 | + cd_data_mode2_t tmpbuf; | |
1486 | + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); | |
1487 | + int tmp_length = sizeof(cd_data_mode2_t); | |
1488 | + if(!(seek_relative_frame_in_image(read_sector))) { | |
1489 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1490 | + return false; | |
1491 | + } | |
1492 | + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { | |
1416 | 1493 | status_illegal_lba(0, 0x00, 0x00, 0x00); |
1417 | 1494 | return false; |
1418 | 1495 | } |
1419 | - int noffset = 16; | |
1420 | - if(logical_block_size() >= physical_block_size()) { // Maybe raw | |
1421 | - noffset = 0; | |
1496 | + //! ToDo: Check header address. | |
1497 | + pair32_t msf; | |
1498 | + msf.d = lba_to_msf(read_sector + toc_table[current_track].pregap); | |
1499 | + if((tmpbuf.header.addr_m != msf.b.h2) || | |
1500 | + (tmpbuf.header.addr_s != msf.b.h) || | |
1501 | + (tmpbuf.header.addr_f != msf.b.l)) { | |
1502 | + out_debug_log(_T("WARNING: Reading from different sector MSF\nEXPECTED=%02X/%02X/%02X\nREAD =%02X/%02X/%02X"), | |
1503 | + tmpbuf.header.addr_m, tmpbuf.header.addr_s, tmpbuf.header.addr_f, | |
1504 | + msf.b.h2, msf.b.h, msf.b.l); | |
1505 | + } | |
1506 | + for(int i = 0; i < sizeof(tmpbuf.data); i++) { | |
1507 | + if(read_length < 0) { | |
1508 | + // ToDo: Change to sector error. | |
1509 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1510 | + return false; | |
1511 | + } | |
1512 | + if(databuffer->full()) { | |
1513 | + // ToDo: Change to buffer overflow | |
1514 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1515 | + return false; | |
1516 | + } | |
1517 | + uint8_t value = tmpbuf.data[i]; | |
1518 | + write_a_byte(value); | |
1519 | + read_length--; | |
1422 | 1520 | } |
1423 | - for(int i = 0; i < tmp_length; i++) { | |
1424 | - if((offset >= noffset) && (offset < (noffset + logical_block_size()))) { | |
1425 | - uint8_t value = tmp_buffer[i]; | |
1426 | - write_a_byte(value); | |
1427 | -// length--; | |
1428 | - read_length--; | |
1521 | + position += physical_block_size(); | |
1522 | + read_sector++; | |
1523 | + sectors--; | |
1524 | + access = true; | |
1525 | + } | |
1526 | + return true; | |
1527 | +} | |
1528 | + | |
1529 | + | |
1530 | +bool TOWNS_CDROM::read_raw(int sectors) | |
1531 | +{ | |
1532 | + while(sectors > 0) { | |
1533 | + uint8_t tmpbuf[2352]; | |
1534 | + int tmp_length = 2352; | |
1535 | + memset(tmpbuf, 0x00, sizeof(tmpbuf)); | |
1536 | + if(!(seek_relative_frame_in_image(read_sector))) { | |
1537 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1538 | + return false; | |
1539 | + } | |
1540 | + if(fio_img->Fread(tmpbuf, tmp_length, 1) != 1) { | |
1541 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1542 | + return false; | |
1543 | + } | |
1544 | + for(int i = 0; i < 2352; i++) { | |
1545 | + if(read_length < 0) { | |
1546 | + // ToDo: Change to sector error. | |
1547 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1548 | + return false; | |
1429 | 1549 | } |
1430 | - position++; | |
1431 | - offset = (offset + 1) % physical_block_size(); | |
1550 | + if(databuffer->full()) { | |
1551 | + // ToDo: Change to buffer overflow | |
1552 | + status_illegal_lba(0, 0x00, 0x00, 0x00); | |
1553 | + return false; | |
1554 | + } | |
1555 | + uint8_t value = tmpbuf[i]; | |
1556 | + write_a_byte(value); | |
1557 | + read_length--; | |
1432 | 1558 | } |
1559 | + position += physical_block_size(); | |
1433 | 1560 | read_sector++; |
1434 | 1561 | sectors--; |
1435 | 1562 | access = true; |
@@ -1437,6 +1564,34 @@ bool TOWNS_CDROM::read_buffer(int sectors) | ||
1437 | 1564 | return true; |
1438 | 1565 | } |
1439 | 1566 | |
1567 | +bool TOWNS_CDROM::read_buffer(int sectors) | |
1568 | +{ | |
1569 | + if(!(mounted())) { | |
1570 | + status_not_ready(false); | |
1571 | + return false; | |
1572 | + } | |
1573 | + if(media_changed) { | |
1574 | + status_media_changed(false); | |
1575 | + return false; | |
1576 | + } | |
1577 | + if(is_iso) return read_mode1_iso(sectors); | |
1578 | + switch(read_mode) { | |
1579 | + case CDROM_READ_MODE1: | |
1580 | + return read_mode1(sectors); | |
1581 | + break; // Below | |
1582 | + case CDROM_READ_MODE2: | |
1583 | + return read_mode2(sectors); | |
1584 | + break; // Below | |
1585 | + case CDROM_READ_RAW: | |
1586 | + return read_raw(sectors); | |
1587 | + break; // Below | |
1588 | + default: | |
1589 | + return false; | |
1590 | + break; | |
1591 | + } | |
1592 | + return false; | |
1593 | +} | |
1594 | + | |
1440 | 1595 | void TOWNS_CDROM::read_a_cdda_sample() |
1441 | 1596 | { |
1442 | 1597 | if(event_cdda_delay_play > -1) { |
@@ -1836,12 +1991,12 @@ double TOWNS_CDROM::get_seek_time(uint32_t lba) | ||
1836 | 1991 | break; |
1837 | 1992 | } |
1838 | 1993 | } |
1839 | - distance = abs((int)lba - (int)(cur_position / physical_block_size() + toc_table[current_track].index0)); | |
1994 | + distance = abs((int)lba - (int)(cur_position / ((is_iso) ? 2048 : physical_block_size()) + toc_table[current_track].index0)); | |
1840 | 1995 | if(track != current_track) { |
1841 | 1996 | current_track = get_track(lba); |
1842 | 1997 | } |
1843 | 1998 | } else { |
1844 | - distance = abs((int)lba - (int)(cur_position / physical_block_size())); | |
1999 | + distance = abs((int)lba - (int)(cur_position / ((is_iso) ? 2048 : physical_block_size()))); | |
1845 | 2000 | } |
1846 | 2001 | // if(distance < 100) { |
1847 | 2002 | // distance = 100; // Seek penalty. |
@@ -1952,11 +2107,12 @@ void TOWNS_CDROM::pause_cdda_from_cmd() | ||
1952 | 2107 | |
1953 | 2108 | bool TOWNS_CDROM::seek_relative_frame_in_image(uint32_t frame_no) |
1954 | 2109 | { |
2110 | + int phys_size = (is_iso) ? 2048 : physical_block_size(); | |
1955 | 2111 | if(frame_no >= toc_table[current_track].lba_offset) { |
1956 | 2112 | if(fio_img->IsOpened()) { |
1957 | 2113 | if(fio_img->Fseek( |
1958 | - (frame_no - toc_table[current_track].lba_offset) * physical_block_size(), | |
1959 | - FILEIO_SEEK_SET) != 0) { | |
2114 | + (frame_no - toc_table[current_track].lba_offset) * phys_size, | |
2115 | + FILEIO_SEEK_SET) != 0) { | |
1960 | 2116 | return false; |
1961 | 2117 | } |
1962 | 2118 | } |
@@ -2093,10 +2249,10 @@ void TOWNS_CDROM::set_subq(void) | ||
2093 | 2249 | if(fio_img->IsOpened()) { |
2094 | 2250 | uint32_t cur_position = (uint32_t)(fio_img->Ftell()); |
2095 | 2251 | if(is_cue) { |
2096 | - frame = (cur_position / physical_block_size()) + toc_table[track].lba_offset; | |
2252 | + frame = (cur_position / ((is_iso) ? 2048 : physical_block_size())) + toc_table[track].lba_offset; | |
2097 | 2253 | msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); |
2098 | 2254 | } else { |
2099 | - frame = cur_position / physical_block_size(); | |
2255 | + frame = cur_position / ((is_iso) ? 2048 : physical_block_size()); | |
2100 | 2256 | if(frame > toc_table[track].lba_offset) { |
2101 | 2257 | msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); |
2102 | 2258 | } else { |
@@ -2383,6 +2539,61 @@ int TOWNS_CDROM::parse_cue_index(std::string &_arg2, int nr_current_track) | ||
2383 | 2539 | return index; |
2384 | 2540 | } |
2385 | 2541 | |
2542 | +bool TOWNS_CDROM::open_iso_file(const _TCHAR* file_path) | |
2543 | +{ | |
2544 | + _TCHAR full_path_iso[_MAX_PATH] = {0}; | |
2545 | + | |
2546 | + int nr_current_track = 0; | |
2547 | + FILEIO* fio = new FILEIO(); | |
2548 | + if(fio == NULL) return false; | |
2549 | + | |
2550 | + get_long_full_path_name(file_path, full_path_iso, sizeof(full_path_iso)); | |
2551 | + const _TCHAR *parent_dir = get_parent_dir((const _TCHAR *)full_path_iso); | |
2552 | + memset(track_data_path[0], 0x00, _MAX_PATH * sizeof(_TCHAR)); | |
2553 | + | |
2554 | + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { // | |
2555 | + uint64_t total_size = (uint64_t)fio->FileLength(); | |
2556 | + uint64_t sectors = total_size / 2048; //! @note Support only MODE1/2352. | |
2557 | + toc_table[0].lba_offset = 0; | |
2558 | + toc_table[0].lba_size = 0; | |
2559 | + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; | |
2560 | + if(sectors > 1) { | |
2561 | + track_num = 2; | |
2562 | + max_logical_block = sectors - 1; | |
2563 | + | |
2564 | + toc_table[1].lba_offset = 0; | |
2565 | + toc_table[1].lba_size = sectors - 1; | |
2566 | + toc_table[1].is_audio = false; | |
2567 | + toc_table[1].index0 = 0; | |
2568 | + toc_table[1].index1 = 0; | |
2569 | + toc_table[1].pregap = 150; | |
2570 | + toc_table[1].physical_size = 2352; | |
2571 | + toc_table[1].logical_size = 2048; | |
2572 | + | |
2573 | + toc_table[2].lba_offset = sectors; | |
2574 | + toc_table[2].lba_size = 0; | |
2575 | + toc_table[2].is_audio = false; | |
2576 | + toc_table[2].index0 = sectors; | |
2577 | + toc_table[2].index1 = sectors; | |
2578 | + toc_table[2].pregap = 150; | |
2579 | + toc_table[2].physical_size = 0; | |
2580 | + toc_table[2].logical_size = 0; | |
2581 | + with_filename[1] = true; | |
2582 | + strncpy(track_data_path[0], full_path_iso, _MAX_PATH - 1); | |
2583 | + } else { | |
2584 | + track_num = 0; | |
2585 | + max_logical_block = 0; | |
2586 | + with_filename[1] = false; | |
2587 | + } | |
2588 | + fio->Fclose(); | |
2589 | + } else { | |
2590 | + delete fio; | |
2591 | + return false; | |
2592 | + } | |
2593 | + delete fio; | |
2594 | + return true; | |
2595 | +} | |
2596 | + | |
2386 | 2597 | bool TOWNS_CDROM::open_cue_file(const _TCHAR* file_path) |
2387 | 2598 | { |
2388 | 2599 | std::string line_buf; |
@@ -2607,7 +2818,18 @@ void TOWNS_CDROM::open_from_cmd(const _TCHAR* file_path) | ||
2607 | 2818 | if(open_cue_file(file_path)) { |
2608 | 2819 | strncpy(img_file_path_bak, file_path, _MAX_PATH - 1); |
2609 | 2820 | } |
2610 | - | |
2821 | + } else if(check_file_extension(file_path, _T(".iso"))) { | |
2822 | + is_cue = false; | |
2823 | + current_track = 0; | |
2824 | + if(open_iso_file(file_path)) { | |
2825 | + strncpy(img_file_path, file_path, _MAX_PATH - 1); | |
2826 | + strncpy(img_file_path_bak, file_path, _MAX_PATH - 1); | |
2827 | + } | |
2828 | + if(fio_img->Fopen(img_file_path, FILEIO_READ_BINARY)) { | |
2829 | + is_cue = false; | |
2830 | + current_track = 0; | |
2831 | + is_iso = true; | |
2832 | + } | |
2611 | 2833 | } else if(check_file_extension(file_path, _T(".ccd"))) { |
2612 | 2834 | // get image file name |
2613 | 2835 | my_stprintf_s(img_file_path, _MAX_PATH, _T("%s.img"), get_file_path_without_extensiton(file_path)); |
@@ -2681,11 +2903,11 @@ void TOWNS_CDROM::open_from_cmd(const _TCHAR* file_path) | ||
2681 | 2903 | } |
2682 | 2904 | |
2683 | 2905 | if(mounted() /*&& (__SCSI_DEBUG_LOG)*/) { |
2684 | - for(int i = 0; i < track_num + 1; i++) { | |
2906 | + for(int i = 1; i < track_num + 1; i++) { | |
2685 | 2907 | uint32_t idx0_msf = lba_to_msf(toc_table[i].index0); |
2686 | 2908 | uint32_t idx1_msf = lba_to_msf(toc_table[i].index1); |
2687 | 2909 | uint32_t pgap_msf = lba_to_msf(toc_table[i].pregap); |
2688 | - this->cdrom_debug_log(_T("Track%02d: Index0=%02x:%02x:%02x Index1=%02x:%02x:%02x PreGap=%02x:%02x:%02x\n"), i + 1, | |
2910 | + this->cdrom_debug_log(_T("Track%02d: Index0=%02x:%02x:%02x Index1=%02x:%02x:%02x PreGap=%02x:%02x:%02x\n"), i, | |
2689 | 2911 | (idx0_msf >> 16) & 0xff, (idx0_msf >> 8) & 0xff, idx0_msf & 0xff, |
2690 | 2912 | (idx1_msf >> 16) & 0xff, (idx1_msf >> 8) & 0xff, idx1_msf & 0xff, |
2691 | 2913 | (pgap_msf >> 16) & 0xff, (pgap_msf >> 8) & 0xff, pgap_msf & 0xff); |
@@ -2713,6 +2935,8 @@ void TOWNS_CDROM::close_from_cmd() | ||
2713 | 2935 | is_cue = false; |
2714 | 2936 | current_track = 0; |
2715 | 2937 | set_cdda_status(CDDA_OFF); |
2938 | + is_iso = false; | |
2939 | + read_mode = CDROM_READ_NONE; | |
2716 | 2940 | } |
2717 | 2941 | |
2718 | 2942 | bool TOWNS_CDROM::mounted() |
@@ -42,10 +42,6 @@ class FILEIO; | ||
42 | 42 | class DEBUGGER; |
43 | 43 | |
44 | 44 | namespace FMTOWNS { |
45 | - class CDC; | |
46 | -} | |
47 | - | |
48 | -namespace FMTOWNS { | |
49 | 45 | #pragma pack(1) |
50 | 46 | typedef union { |
51 | 47 | struct { |
@@ -61,7 +57,56 @@ namespace FMTOWNS { | ||
61 | 57 | uint8_t byte; |
62 | 58 | } SUBC_t; |
63 | 59 | #pragma pack() |
64 | - | |
60 | + /*! | |
61 | + * @note Belows are CD-ROM sector structuer. | |
62 | + * @note See https://en.wikipedia.org/wiki/CD-ROM#Sector_structure . | |
63 | + */ | |
64 | +#pragma pack(1) | |
65 | + typedef struct { | |
66 | + uint8_t sync[12]; | |
67 | + uint8_t addr_m; | |
68 | + uint8_t addr_s; | |
69 | + uint8_t addr_f; | |
70 | + uint8_t sector_type; //! 1 = MODE1, 2=MODE2 | |
71 | + } cd_data_head_t; | |
72 | +#pragma pack() | |
73 | +#pragma pack(1) | |
74 | + /*! | |
75 | + * @note ToDo: Still not implement crc32 and ecc. | |
76 | + * @note 20201116 K.O | |
77 | + */ | |
78 | + typedef struct { | |
79 | + cd_data_head_t header; | |
80 | + uint8_t data[2048]; | |
81 | + uint8_t crc32[4]; //! CRC32 checksum. | |
82 | + uint8_t reserved[8]; | |
83 | + uint8_t ecc[276]; //! ERROR CORRECTIOM DATA; by read solomon code. | |
84 | + } cd_data_mode1_t; | |
85 | +#pragma pack() | |
86 | +#pragma pack(1) | |
87 | + /*! | |
88 | + * | |
89 | + * | |
90 | + */ | |
91 | + typedef struct { | |
92 | + cd_data_head_t header; | |
93 | + uint8_t data[2336]; | |
94 | + } cd_data_mode2_t; | |
95 | +#pragma pack() | |
96 | +#pragma pack(1) | |
97 | + typedef struct { | |
98 | + uint8_t data[2352]; | |
99 | + } cd_audio_sector_t; | |
100 | +#pragma pack() | |
101 | +#pragma pack(1) | |
102 | + /*! | |
103 | + * @note ToDo: Add fake header and crc and ecc. | |
104 | + * @note 20201116 K.O | |
105 | + */ | |
106 | + typedef struct { | |
107 | + uint8_t data[2048]; | |
108 | + } cd_data_iso_t; | |
109 | +#pragma pack() | |
65 | 110 | // From Towns Linux : include/linux/towns_cd.h |
66 | 111 | enum { |
67 | 112 | MODE_AUDIO = 0, |
@@ -74,8 +119,12 @@ enum { | ||
74 | 119 | MODE_CDI_2352, |
75 | 120 | MODE_NONE |
76 | 121 | }; |
77 | - | |
78 | - | |
122 | +enum { | |
123 | + CDROM_READ_MODE1 = 1, | |
124 | + CDROM_READ_MODE2 = 2, | |
125 | + CDROM_READ_RAW = 3, | |
126 | + CDROM_READ_NONE = 0 | |
127 | +}; | |
79 | 128 | enum { |
80 | 129 | CDROM_COMMAND_SEEK = 0x00, |
81 | 130 | CDROM_COMMAND_READ_MODE2 = 0x01, |
@@ -199,6 +248,7 @@ protected: | ||
199 | 248 | int stat_track; |
200 | 249 | |
201 | 250 | bool is_cue; |
251 | + bool is_iso; | |
202 | 252 | struct { |
203 | 253 | uint8_t type; |
204 | 254 | int32_t index0, index1, pregap; |
@@ -346,6 +396,7 @@ protected: | ||
346 | 396 | void parse_cue_track(std::string &_arg2, int& nr_current_track, std::string imgpath); |
347 | 397 | int parse_cue_index(std::string &_arg2, int nr_current_track); |
348 | 398 | |
399 | + virtual bool open_iso_file(const _TCHAR* file_path); | |
349 | 400 | |
350 | 401 | virtual uint8_t read_subq(); |
351 | 402 | virtual uint8_t get_subq_status(); |
@@ -433,6 +484,11 @@ public: | ||
433 | 484 | virtual void set_volume(int volume); |
434 | 485 | virtual void set_volume(int ch, int decibel_l, int decibel_r); |
435 | 486 | virtual bool read_buffer(int sectors); |
487 | + | |
488 | + virtual bool read_raw(int sectors); | |
489 | + virtual bool read_mode1(int sectors); | |
490 | + virtual bool read_mode2(int sectors); | |
491 | + virtual bool read_mode1_iso(int sectors); | |
436 | 492 | |
437 | 493 | // unique functions |
438 | 494 | // Towns specified command |