mirror of
https://github.com/dingusdev/dingusppc.git
synced 2026-10-25 17:02:23 +00:00
This source should contain anything related to the physical properties of a CD/DVD drive like mechanical capabilities, formats supported as well as handling of the underlying images.
85 lines
2.5 KiB
C++
85 lines
2.5 KiB
C++
/*
|
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
|
Copyright (C) 2018-26 The DingusPPC Development Team
|
|
(See CREDITS.MD for more details)
|
|
|
|
(You may also contact divingkxt or powermax2286 on Discord)
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** @file Virtual CD-ROM device implementation. */
|
|
|
|
#include <devices/storage/cdromdrive.h>
|
|
#include <loguru.hpp>
|
|
|
|
#include <cinttypes>
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
CdromDrive::CdromDrive() : BlockStorageDevice(31, CDR_STD_DATA_SIZE, 0xfffffffe) {
|
|
this->is_writeable = false;
|
|
}
|
|
|
|
void CdromDrive::insert_image(std::string filename) {
|
|
if (this->set_host_file(filename) < 0)
|
|
ABORT_F("Could not open CD-ROM image file, %s", filename.c_str());
|
|
|
|
this->detect_raw_image();
|
|
|
|
// create single track descriptor
|
|
this->tracks[0] = {1, /*.trk_num*/ 0x14, /*.adr_ctrl*/ 0 /*.start_lba*/};
|
|
this->num_tracks = 1;
|
|
|
|
// create Lead-out descriptor containing all data
|
|
this->tracks[1] = {LEAD_OUT_TRK_NUM, /*.trk_num*/ 0x14, /*.adr_ctrl*/
|
|
static_cast<uint32_t>(this->size_blocks + 1) /*.start_lba*/};
|
|
}
|
|
|
|
bool CdromDrive::detect_raw_image() {
|
|
uint8_t block_hdr[16];
|
|
|
|
// let's see if the image data starts with the Mode 1/2 sync pattern
|
|
this->img_file.read(block_hdr, 0, sizeof(block_hdr));
|
|
|
|
for (int i = 1; i <= 10; i++)
|
|
if (block_hdr[i] != 0xFF)
|
|
return false;
|
|
|
|
if (block_hdr[0] != 0 || block_hdr[11] != 0)
|
|
return false;
|
|
|
|
// for now, we only support Mode 1 images
|
|
if (block_hdr[15] == 1) {
|
|
this->set_block_size(2352);
|
|
this->data_offset = 16;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
uint8_t CdromDrive::hex_to_bcd(const uint8_t val) {
|
|
uint8_t hi = val / 10;
|
|
uint8_t lo = val % 10;
|
|
return (hi << 4) | lo;
|
|
}
|
|
|
|
AddrMsf CdromDrive::lba_to_msf(const int lba) {
|
|
return {hex_to_bcd( lba / 4500), /*.min*/
|
|
hex_to_bcd((lba / 75) % 60), /*.sec*/
|
|
hex_to_bcd( lba % 75) /*.frm*/
|
|
};
|
|
}
|