Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ if (APPLE)
# MACOSX_BUNDLE_ICON_FILE "icon.icns"
)

if (NOT IOS)
set_target_properties(dingusppc PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/cmake/DingusPPCInfo.plist.in"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUNDLE_ID}"
)
endif()

find_library(COCOA_LIBRARY Cocoa)
find_library(IOKIT_LIBRARY IOKit)
find_library(COREAUDIO_LIBRARY CoreAudio)
Expand Down
70 changes: 70 additions & 0 deletions cmake/DingusPPCInfo.plist.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>CD-ROM image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.iso-image</string>
<string>com.roxio.disk-image-toast</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.disk-image</string>
</array>
<key>UTTypeDescription</key>
<string>Toast disk image</string>
<key>UTTypeIdentifier</key>
<string>com.roxio.disk-image-toast</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>toast</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>
28 changes: 28 additions & 0 deletions core/hostevents_sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <core/coresignal.h>
#include <cpu/ppc/ppcemu.h>
#include <devices/common/adb/adbkeyboard.h>
#include <machines/machinebase.h>
#include <loguru.hpp>
#include <SDL.h>

Expand Down Expand Up @@ -322,6 +323,33 @@ void EventManager::poll_events() {
}
break;

case SDL_DROPFILE: {
const char* path = event.drop.file;
CdromInsertionResult result = gMachineObj
? gMachineObj->insert_cdrom_image(path)
: CdromInsertionResult::NO_DRIVE;

switch (result) {
case CdromInsertionResult::SUCCESS:
LOG_F(INFO, "Inserted CD-ROM image: %s", path);
break;
case CdromInsertionResult::NO_DRIVE:
LOG_F(ERROR, "Cannot insert CD-ROM image; no CD-ROM drive is available: %s",
path);
break;
case CdromInsertionResult::MEDIA_PRESENT:
LOG_F(ERROR, "Cannot insert CD-ROM image; eject the current media first: %s",
path);
break;
case CdromInsertionResult::IMAGE_OPEN_FAILED:
LOG_F(ERROR, "Cannot insert CD-ROM image: %s", path);
break;
}

SDL_free(event.drop.file);
}
break;

default:
unhandled_events++;
}
Expand Down
3 changes: 2 additions & 1 deletion devices/common/ata/atapicdrom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ int AtapiCdrom::device_postinit() {

std::string cdr_image_path = GET_STR_PROP("cdr_img");
if (!cdr_image_path.empty()) {
this->insert_image(cdr_image_path);
if (!this->insert_image(cdr_image_path))
return -1;
}

return 0;
Expand Down
10 changes: 10 additions & 0 deletions devices/common/scsi/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ enum ScsiCommand : uint8_t {
READ_CD = 0xBE,
};

/** START STOP UNIT command flags in CDB byte 4. */
namespace ScsiStartStopUnit {
enum : uint8_t {
START = 1 << 0,
LOAD_EJECT = 1 << 1,
};
}

enum ScsiSense : uint8_t {
NO_SENSE = 0x0,
RECOVERED = 0x1,
Expand All @@ -200,8 +208,10 @@ enum ScsiError : uint8_t {
INVALID_CDB = 0x24,
INVALID_LUN = 0x25,
WRITE_PROTECT = 0x27,
MEDIUM_CHANGED = 0x28,
SAVING_NOT_SUPPORTED = 0x39,
MEDIUM_NOT_PRESENT = 0x3A,
REMOVAL_PREVENTED = 0x53,
};

/** SCSI device types used in INQUIRY. */
Expand Down
6 changes: 3 additions & 3 deletions devices/common/scsi/scsiblockcmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ int ScsiBlockCmds::write() {
}

int ScsiBlockCmds::start_stop_unit() {
if (this->cdb_ptr[4] & 1) {
if (this->cdb_ptr[4] & 2)
if (this->cdb_ptr[4] & ScsiStartStopUnit::START) {
if (this->cdb_ptr[4] & ScsiStartStopUnit::LOAD_EJECT)
LOG_F(INFO, "START_STOP_UNIT: medium load requested");
} else {
if (this->cdb_ptr[4] & 2) {
if (this->cdb_ptr[4] & ScsiStartStopUnit::LOAD_EJECT) {
LOG_F(INFO, "START_STOP_UNIT: medium eject requested");
}
}
Expand Down
3 changes: 2 additions & 1 deletion devices/common/scsi/scsibus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ void ScsiBus::attach_scsi_devices(const std::string bus_suffix)
gMachineObj->add_device(scsi_device_name,
std::unique_ptr<ScsiCdrom>(scsi_device));
this->register_device(scsi_id, scsi_device);
scsi_device->insert_image(path);
if (!scsi_device->insert_image(path))
ABORT_F("Could not insert CD-ROM image, %s", path.c_str());
}
else {
LOG_F(ERROR, "%s: Too many devices. CD-ROM \"%s\" was not added.",
Expand Down
1 change: 1 addition & 0 deletions devices/common/scsi/scsicdrom.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ScsiCdrom : public ScsiPhysDevice, public ScsiCdromCmds {

protected:
bool is_device_ready() override { return this->is_ready; }
uint8_t not_ready_reason() override { return ScsiError::MEDIUM_NOT_PRESENT; }

void mode_select_6(uint8_t param_len);

Expand Down
37 changes: 37 additions & 0 deletions devices/common/scsi/scsicdromcmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,43 @@ void ScsiCdromCmds::process_command() {
phy_impl->switch_phase(next_phase);
}

int ScsiCdromCmds::test_unit_ready() {
if (this->take_media_change()) {
this->sense_key = ScsiSense::UNIT_ATTENTION;
this->asc = ScsiError::MEDIUM_CHANGED;
this->ascq = 0;
phy_impl->set_status(ScsiStatus::CHECK_CONDITION, this->sense_key);
return ScsiPhase::STATUS;
}

return ScsiCommonCmds::test_unit_ready();
}

int ScsiCdromCmds::start_stop_unit() {
bool load_eject = this->cdb_ptr[4] & ScsiStartStopUnit::LOAD_EJECT;
bool start = this->cdb_ptr[4] & ScsiStartStopUnit::START;

if (!load_eject)
return ScsiPhase::STATUS;

if (start) {
LOG_F(INFO, "START_STOP_UNIT: medium load requested");
return ScsiPhase::STATUS;
}

if (this->drive_locked) {
LOG_F(INFO, "START_STOP_UNIT: medium eject prevented");
this->field_ptr_valid = false;
this->bit_ptr_valid = false;
this->illegal_request(ScsiError::REMOVAL_PREVENTED, 2, false);
} else {
LOG_F(INFO, "START_STOP_UNIT: medium eject requested");
this->eject_image();
}

return ScsiPhase::STATUS;
}

int ScsiCdromCmds:: read_toc() {
uint8_t start_track, session_num;
int tot_tracks, resp_len = 0;
Expand Down
2 changes: 2 additions & 0 deletions devices/common/scsi/scsicdromcmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class ScsiCdromCmds : public ScsiBlockCmds, public CdromDrive {

protected:
virtual void process_command() override;
int test_unit_ready() override;
int start_stop_unit() override;

int get_apple_page_49(uint8_t subpage, uint8_t ctrl,
uint8_t *out_ptr, int avail_len);
Expand Down
19 changes: 13 additions & 6 deletions devices/storage/blockstoragedevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,18 @@ BlockStorageDevice::BlockStorageDevice(const uint32_t cache_blocks,
}

BlockStorageDevice::~BlockStorageDevice() {
this->img_file.close();
if (this->is_ready)
this->img_file.close();
}

int BlockStorageDevice::set_host_file(std::string file_path) {
this->is_ready = false;

if (!this->img_file.open(file_path))
return -1;

this->is_ready = false;
this->size_bytes = this->img_file.size();
this->remain_size = 0;
this->write_size = 0;

this->set_fpos(0);

Expand All @@ -66,10 +68,15 @@ int BlockStorageDevice::set_block_size(const int blk_size) {
return -1;
}

this->cache_size = this->cache_blocks * this->raw_blk_size;
uint32_t new_cache_size = this->cache_blocks * this->raw_blk_size;
// Preserve pointers held by an in-progress transfer when the cache geometry
// does not change during a media replacement.
if (new_cache_size != this->cache_size) {
this->cache_size = new_cache_size;

// allocate data cache and fill it with zeroes
this->data_cache = std::unique_ptr<char[]>(new char[this->cache_size] ());
// allocate data cache and fill it with zeroes
this->data_cache = std::unique_ptr<char[]>(new char[this->cache_size] ());
}

return 0;
}
Expand Down
38 changes: 35 additions & 3 deletions devices/storage/cdromdrive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,18 @@ 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());
bool CdromDrive::insert_image(const std::string& filename, bool notify_guest) {
if (this->medium_present()) {
LOG_F(ERROR, "Cannot insert CD-ROM image while media is present");
return false;
}

if (this->set_host_file(filename) < 0) {
LOG_F(ERROR, "Could not open CD-ROM image file, %s", filename.c_str());
return false;
}

this->data_offset = 0;
this->detect_raw_image();

// create single track descriptor
Expand All @@ -45,6 +53,30 @@ void CdromDrive::insert_image(std::string filename) {
// 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*/};

this->media_changed |= notify_guest;
return true;
}

bool CdromDrive::eject_image() {
if (!this->is_ready)
return false;

this->is_ready = false;
this->img_file.close();

this->size_bytes = 0;
this->size_blocks = 0;
this->cur_fpos = 0;
this->write_size = 0;
this->remain_size = 0;
this->raw_blk_size = this->block_size;
this->data_offset = 0;
this->num_tracks = 0;
this->media_changed = false;
std::memset(this->tracks, 0, sizeof(this->tracks));

return true;
}

bool CdromDrive::detect_raw_image() {
Expand Down
10 changes: 9 additions & 1 deletion devices/storage/cdromdrive.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@ class CdromDrive : public BlockStorageDevice {

bool medium_present() { return this->is_ready; }

void insert_image(std::string filename);
bool insert_image(const std::string& filename, bool notify_guest = false);
bool eject_image();

bool take_media_change() {
bool changed = this->media_changed;
this->media_changed = false;
return changed;
}

protected:
uint8_t hex_to_bcd(const uint8_t val);
Expand All @@ -101,6 +108,7 @@ class CdromDrive : public BlockStorageDevice {
uint8_t sw_lock_sup = 1; // drive supports locking/unlocking via SW
uint8_t sw_eject_sup = 1; // drive supports ejecting via SW
uint8_t drive_locked = 0; // 1 - drive is currently locked
bool media_changed = false;
uint8_t prevent_jump = 0; // prevent jumper not present
uint8_t more_support = 0;
uint16_t max_rd_speed = 706; // defaults to 4x
Expand Down
Loading
Loading