diff --git a/BasiliskII/src/MacOSX/ToDo.html b/BasiliskII/src/MacOSX/ToDo.html
index 78afaefc..216d1536 100644
--- a/BasiliskII/src/MacOSX/ToDo.html
+++ b/BasiliskII/src/MacOSX/ToDo.html
@@ -10,8 +10,6 @@ Bugs:
Disturbing, but not damaging.
Ejecting a CD only works in 10.2 or higher, and it freezes the emulation
for about 5 seconds.
-Inserting a second CD after ejecting the first one
- doesn't currently remount the disk.
Status of 'dd' command is not always correct. (If it runs out of space,
an error about file not found is printed?)
The Snapshot function is currently broken in some situations
diff --git a/BasiliskII/src/MacOSX/sys_darwin.cpp b/BasiliskII/src/MacOSX/sys_darwin.cpp
index 47f6dd4a..9778fceb 100644
--- a/BasiliskII/src/MacOSX/sys_darwin.cpp
+++ b/BasiliskII/src/MacOSX/sys_darwin.cpp
@@ -38,92 +38,169 @@
#import
#import
-#import "sysdeps.h"
+#include "sysdeps.h"
-#import "prefs.h"
+#include "sys.h"
+#include "prefs.h"
#define DEBUG 0
#import "debug.h"
+// Global variables
+static CFRunLoopRef media_poll_loop = NULL;
+static bool media_thread_active = false;
+static pthread_t media_thread;
+
+// Prototypes
+static void *media_poll_func(void *);
+
+// From sys_unix.cpp
+extern void SysMediaArrived(const char *path, int type);
+extern void SysMediaRemoved(const char *path, int type);
+
/*
- * This gets called when no "cdrom" prefs items are found
- * It scans for available CD-ROM drives and adds appropriate prefs items
+ * Initialization
*/
-void DarwinAddCDROMPrefs(void)
+void DarwinSysInit(void)
{
- mach_port_t masterPort; // The way to talk to the kernel
- io_iterator_t allCDs; // List of CD drives on the system
- CFMutableDictionaryRef classesToMatch;
- io_object_t nextCD;
+ media_thread_active = (pthread_create(&media_thread, NULL, media_poll_func, NULL) == 0);
+ D(bug("Media poll thread installed (%ld)\n", media_thread));
+}
- // Don't scan for drives if nocdrom option given
- if ( PrefsFindBool("nocdrom") )
- return;
+/*
+ * Deinitialization
+ */
+
+void DarwinSysExit(void)
+{
+ // Stop media poll thread
+ if (media_poll_loop)
+ CFRunLoopStop(media_poll_loop);
+ if (media_thread_active)
+ pthread_join(media_thread, NULL);
+}
- // Let this task talk to the guts of the kernel:
- if ( IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS )
- bug("IOMasterPort failed. Won't be able to do anything with CD drives\n");
+/*
+ * Get the BSD-style path of specified object
+ */
-
- // CD media are instances of class kIOCDMediaClass
- classesToMatch = IOServiceMatching(kIOCDMediaClass);
- if ( classesToMatch )
- {
- // Narrow the search a little further. Each IOMedia object
- // has a property with key kIOMediaEjectable. We limit
- // the match only to those CDs that are actually ejectable
- CFDictionarySetValue(classesToMatch,
- CFSTR(kIOMediaEjectableKey), kCFBooleanTrue);
- }
-
- if ( IOServiceGetMatchingServices(masterPort,
- classesToMatch, &allCDs) != KERN_SUCCESS )
- {
- D(bug("IOServiceGetMatchingServices failed. No CD media drives found?\n"));
- return;
+static kern_return_t get_device_path(io_object_t obj, char *path, size_t maxPathLength)
+{
+ kern_return_t kernResult = KERN_FAILURE;
+ CFTypeRef pathAsCFString = IORegistryEntryCreateCFProperty(obj, CFSTR(kIOBSDNameKey),
+ kCFAllocatorDefault, 0);
+ if (pathAsCFString) {
+ strcpy(path, "/dev/");
+ size_t pathLength = strlen(path);
+ if (CFStringGetCString((const __CFString *)pathAsCFString,
+ path + pathLength,
+ maxPathLength - pathLength,
+ kCFStringEncodingASCII))
+ kernResult = KERN_SUCCESS;
+ CFRelease(pathAsCFString);
}
+ return kernResult;
+}
- // Iterate through each CD drive
- while ( nextCD = IOIteratorNext(allCDs))
- {
- char bsdPath[MAXPATHLEN];
- CFTypeRef bsdPathAsCFString =
- IORegistryEntryCreateCFProperty(nextCD,
- CFSTR(kIOBSDNameKey),
- kCFAllocatorDefault, 0);
- *bsdPath = '\0';
- if ( bsdPathAsCFString )
- {
- size_t devPathLength;
+/*
+ * kIOMatchedNotification handler
+ */
- strcpy(bsdPath, "/dev/");
- devPathLength = strlen(bsdPath);
-
- if ( CFStringGetCString((const __CFString *)bsdPathAsCFString,
- bsdPath + devPathLength,
- MAXPATHLEN - devPathLength,
- kCFStringEncodingASCII) )
- {
- D(bug("CDROM BSD path: %s\n", bsdPath));
- PrefsAddString("cdrom", bsdPath);
- }
- else
- D(bug("Could not get BSD device path for CD\n"));
-
- CFRelease(bsdPathAsCFString);
+static void media_arrived(int type, io_iterator_t iterator)
+{
+ io_object_t obj;
+ while ((obj = IOIteratorNext(iterator)) != NULL) {
+ char path[MAXPATHLEN];
+ kern_return_t kernResult = get_device_path(obj, path, sizeof(path));
+ if (kernResult == KERN_SUCCESS) {
+ D(bug("Media Arrived: %s\n", path));
+ SysMediaArrived(path, type);
}
- else
- D(bug("Cannot determine bsdPath for CD\n"));
+ kernResult = IOObjectRelease(obj);
+ if (kernResult != KERN_SUCCESS) {
+ fprintf(stderr, "IOObjectRelease() returned %d\n", kernResult);
+ }
+ }
+}
+
+
+/*
+ * kIOTerminatedNotification handler
+ */
+
+static void media_removed(int type, io_iterator_t iterator)
+{
+ io_object_t obj;
+ while ((obj = IOIteratorNext(iterator)) != NULL) {
+ char path[MAXPATHLEN];
+ kern_return_t kernResult = get_device_path(obj, path, sizeof(path));
+ if (kernResult == KERN_SUCCESS) {
+ D(bug("Media Removed: %s\n", path));
+ SysMediaRemoved(path, type);
+ }
+ kernResult = IOObjectRelease(obj);
+ if (kernResult != KERN_SUCCESS) {
+ fprintf(stderr, "IOObjectRelease() returned %d\n", kernResult);
+ }
+ }
+}
+
+
+/*
+ * Media poll function
+ */
+
+static void *media_poll_func(void *)
+{
+ media_poll_loop = CFRunLoopGetCurrent();
+
+ mach_port_t masterPort;
+ kern_return_t kernResult = IOMasterPort(bootstrap_port, &masterPort);
+ if (kernResult != KERN_SUCCESS) {
+ fprintf(stderr, "IOMasterPort() returned %d\n", kernResult);
+ return NULL;
}
- IOObjectRelease(nextCD);
- IOObjectRelease(allCDs);
+ CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOCDMediaClass);
+ if (matchingDictionary == NULL) {
+ fprintf(stderr, "IOServiceMatching() returned a NULL dictionary\n");
+ return NULL;
+ }
+ matchingDictionary = (CFMutableDictionaryRef)CFRetain(matchingDictionary);
+
+ IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
+ CFRunLoopAddSource(media_poll_loop,
+ IONotificationPortGetRunLoopSource(notificationPort),
+ kCFRunLoopDefaultMode);
+
+ io_iterator_t mediaArrivedIterator;
+ kernResult = IOServiceAddMatchingNotification(notificationPort,
+ kIOMatchedNotification,
+ matchingDictionary,
+ (IOServiceMatchingCallback)media_arrived,
+ (void *)MEDIA_CD, &mediaArrivedIterator);
+ if (kernResult != KERN_SUCCESS)
+ fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
+ media_arrived(MEDIA_CD, mediaArrivedIterator);
+
+ io_iterator_t mediaRemovedIterator;
+ kernResult = IOServiceAddMatchingNotification(notificationPort,
+ kIOTerminatedNotification,
+ matchingDictionary,
+ (IOServiceMatchingCallback)media_removed,
+ (void *)MEDIA_CD, &mediaRemovedIterator);
+ if (kernResult != KERN_SUCCESS)
+ fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
+ media_removed(MEDIA_CD, mediaRemovedIterator);
+
+ CFRunLoopRun();
+ return NULL;
}
diff --git a/BasiliskII/src/Unix/sys_unix.cpp b/BasiliskII/src/Unix/sys_unix.cpp
index de378b3b..5f4a02aa 100644
--- a/BasiliskII/src/Unix/sys_unix.cpp
+++ b/BasiliskII/src/Unix/sys_unix.cpp
@@ -41,6 +41,15 @@
#include
#endif
+#if defined __APPLE__ && defined __MACH__
+#include
+#if (defined AQUA || defined HAVE_FRAMEWORK_COREFOUNDATION)
+#ifndef __MACOSX__
+#define __MACOSX__ MAC_OS_X_VERSION_MIN_REQUIRED
+#endif
+#endif
+#endif
+
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
@@ -61,6 +70,7 @@ struct file_handle {
bool read_only; // Copy of Sys_open() flag
loff_t start_byte; // Size of file header (if any)
loff_t file_size; // Size of file data (only valid if is_file is true)
+ bool is_media_present; // Flag: media is inserted and available
#if defined(__linux__)
int cdrom_cap; // CD-ROM capability flags (only valid if is_cdrom is true)
@@ -72,9 +82,20 @@ struct file_handle {
#endif
};
+// Open file handles
+struct open_file_handle {
+ file_handle *fh;
+ open_file_handle *next;
+};
+static open_file_handle *open_file_handles = NULL;
+
// File handle of first floppy drive (for SysMountFirstFloppy())
static file_handle *first_floppy = NULL;
+// Prototypes
+static void cdrom_close(file_handle *fh);
+static bool cdrom_open(file_handle *fh, const char *path = NULL);
+
/*
* Initialization
@@ -82,6 +103,10 @@ static file_handle *first_floppy = NULL;
void SysInit(void)
{
+#if defined __MACOSX__
+ extern void DarwinSysInit(void);
+ DarwinSysInit();
+#endif
}
@@ -91,6 +116,113 @@ void SysInit(void)
void SysExit(void)
{
+#if defined __MACOSX__
+ extern void DarwinSysExit(void);
+ DarwinSysExit();
+#endif
+}
+
+
+/*
+ * Manage open file handles
+ */
+
+static void sys_add_file_handle(file_handle *fh)
+{
+ open_file_handle *p = new open_file_handle;
+ p->fh = fh;
+ p->next = open_file_handles;
+ open_file_handles = p;
+}
+
+static void sys_remove_file_handle(file_handle *fh)
+{
+ open_file_handle *p = open_file_handles;
+ open_file_handle *q = NULL;
+
+ while (p) {
+ if (p->fh == fh) {
+ if (q)
+ q->next = p->next;
+ else
+ open_file_handles = p->next;
+ delete p;
+ break;
+ }
+ q = p;
+ p = p->next;
+ }
+}
+
+
+/*
+ * Account for media that has just arrived
+ */
+
+void SysMediaArrived(const char *path, int type)
+{
+ // Replace the "cdrom" entry (we are polling, it's unique)
+ if (type == MEDIA_CD && !PrefsFindBool("nocdrom"))
+ PrefsReplaceString("cdrom", path);
+
+ // Wait for media to be available for reading
+ if (open_file_handles) {
+ const int MAX_WAIT = 5;
+ for (int i = 0; i < MAX_WAIT; i++) {
+ if (access(path, R_OK) == 0)
+ break;
+ switch (errno) {
+ case ENOENT: // Unlikely
+ case EACCES: // MacOS X is mounting the media
+ sleep(1);
+ continue;
+ }
+ printf("WARNING: Cannot access %s (%s)\n", path, strerror(errno));
+ return;
+ }
+ }
+
+ for (open_file_handle *p = open_file_handles; p != NULL; p = p->next) {
+ file_handle * const fh = p->fh;
+
+ // Re-open CD-ROM device
+ if (fh->is_cdrom && type == MEDIA_CD) {
+ cdrom_close(fh);
+ if (cdrom_open(fh, path)) {
+ fh->is_media_present = true;
+ MountVolume(fh);
+ }
+ }
+ }
+}
+
+
+/*
+ * Account for media that has just been removed
+ */
+
+void SysMediaRemoved(const char *path, int type)
+{
+ if ((type & MEDIA_REMOVABLE) != MEDIA_CD)
+ return;
+
+ for (open_file_handle *p = open_file_handles; p != NULL; p = p->next) {
+ file_handle * const fh = p->fh;
+
+ // Mark media as not available
+ if (!fh->is_cdrom || !fh->is_media_present)
+ continue;
+ if (fh->name && strcmp(fh->name, path) == 0) {
+ fh->is_media_present = false;
+ break;
+ }
+#if defined __MACOSX__
+ if (fh->ioctl_name && strcmp(fh->ioctl_name, path) == 0) {
+ fh->is_media_present = false;
+ break;
+ }
+#endif
+ }
}
@@ -211,15 +343,12 @@ void SysAddCDROMPrefs(void)
closedir(cd_dir);
}
}
-#elif defined(__APPLE__) && defined(__MACH__)
- #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
- extern void DarwinAddCDROMPrefs(void);
-
- DarwinAddCDROMPrefs();
- #else
- // Until I can convince the other guys that my Darwin code is useful,
- // we just do nothing (it is safe to have no cdrom device)
- #endif
+#elif defined __MACOSX__
+ // There is no predefined path for CD-ROMs on MacOS X. Rather, we
+ // define a single fake CD-ROM entry for the emulated MacOS.
+ // XXX this means we handle only CD-ROM drive at a time, wherever
+ // the disk is, the latest one is used.
+ PrefsAddString("cdrom", "/dev/poll/cdrom");
#elif defined(__FreeBSD__) || defined(__NetBSD__)
PrefsAddString("cdrom", "/dev/cd0c");
#endif
@@ -261,6 +390,74 @@ void SysAddSerialPrefs(void)
}
+/*
+ * Open CD-ROM device and initialize internal data
+ */
+
+static bool cdrom_open_1(file_handle *fh)
+{
+#if defined __MACOSX__
+ // In OS X, the device name is OK for sending ioctls to,
+ // but not for reading raw CDROM data from.
+ // (it seems to have extra data padded in)
+ //
+ // So, we keep the already opened file handle,
+ // and open a slightly different file for CDROM data
+ //
+ fh->ioctl_fd = fh->fd;
+ fh->ioctl_name = fh->name;
+ fh->fd = -1;
+ fh->name = (char *)malloc(strlen(fh->ioctl_name) + 3);
+ if (fh->name) {
+ strcpy(fh->name, fh->ioctl_name);
+ strcat(fh->name, "s1");
+ fh->fd = open(fh->name, O_RDONLY, O_NONBLOCK);
+ }
+ if (fh->ioctl_fd < 0)
+ return false;
+#endif
+ return true;
+}
+
+bool cdrom_open(file_handle *fh, const char *path)
+{
+ if (path)
+ fh->name = strdup(path);
+ fh->fd = open(fh->name, O_RDONLY, O_NONBLOCK);
+ fh->start_byte = 0;
+ if (!cdrom_open_1(fh))
+ return false;
+ return fh->fd >= 0;
+}
+
+
+/*
+ * Close a CD-ROM device
+ */
+
+void cdrom_close(file_handle *fh)
+{
+ if (fh->fd >= 0) {
+ close(fh->fd);
+ fh->fd = -1;
+ }
+ if (fh->name) {
+ free(fh->name);
+ fh->name = NULL;
+ }
+#if defined __MACOSX__
+ if (fh->ioctl_fd >= 0) {
+ close(fh->ioctl_fd);
+ fh->ioctl_fd = -1;
+ }
+ if (fh->ioctl_name) {
+ free(fh->ioctl_name);
+ fh->ioctl_name = NULL;
+ }
+#endif
+}
+
+
/*
* Check if device is a mounted HFS volume, get mount name
*/
@@ -310,23 +507,23 @@ void *Sys_open(const char *name, bool read_only)
#endif
bool is_floppy = strncmp(name, "/dev/fd", 7) == 0;
-#if defined(__APPLE__) && defined(__MACH__)
- //
+ bool is_polled_media = strncmp(name, "/dev/poll/", 10) == 0;
+ if (is_floppy) // Floppy open fails if there's no disk inserted
+ is_polled_media = true;
+
+#if defined __MACOSX__
// There is no set filename in /dev which is the cdrom,
// so we have to see if it is any of the devices that we found earlier
- //
- const char *cdrom;
- int tmp = 0;
-
- while ( (cdrom = PrefsFindString("cdrom", tmp) ) != NULL )
{
- if ( strcmp(name, cdrom) == 0 )
- {
- is_cdrom = 1;
- read_only = 1;
- break;
+ int index = 0;
+ const char *str;
+ while ((str = PrefsFindString("cdrom", index++)) != NULL) {
+ if (is_polled_media || strcmp(str, name) == 0) {
+ is_cdrom = true;
+ read_only = true;
+ break;
+ }
}
- ++tmp;
}
#endif
@@ -351,7 +548,7 @@ void *Sys_open(const char *name, bool read_only)
}
// Open file/device
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__)
int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0));
#else
int fd = open(name, read_only ? O_RDONLY : O_RDWR);
@@ -361,7 +558,7 @@ void *Sys_open(const char *name, bool read_only)
read_only = true;
fd = open(name, O_RDONLY);
}
- if (fd >= 0 || is_floppy) { // Floppy open fails if there's no disk inserted
+ if (fd >= 0 || is_polled_media) {
file_handle *fh = new file_handle;
fh->name = strdup(name);
fh->fd = fd;
@@ -370,7 +567,13 @@ void *Sys_open(const char *name, bool read_only)
fh->start_byte = 0;
fh->is_floppy = is_floppy;
fh->is_cdrom = is_cdrom;
+ fh->is_media_present = false;
+#if defined __MACOSX__
+ fh->ioctl_fd = -1;
+ fh->ioctl_name = NULL;
+#endif
if (fh->is_file) {
+ fh->is_media_present = true;
// Detect disk image file layout
loff_t size = 0;
size = lseek(fd, 0, SEEK_END);
@@ -381,6 +584,7 @@ void *Sys_open(const char *name, bool read_only)
} else {
struct stat st;
if (fstat(fd, &st) == 0) {
+ fh->is_media_present = true;
if (S_ISBLK(st.st_mode)) {
fh->is_cdrom = is_cdrom;
#if defined(__linux__)
@@ -408,39 +612,19 @@ void *Sys_open(const char *name, bool read_only)
fh->is_floppy = ((st.st_rdev >> 16) == 2);
#endif
}
-#if defined(__APPLE__) && defined(__MACH__)
-
- // In OS X, the device name is OK for sending ioctls to,
- // but not for reading raw CDROM data from.
- // (it seems to have extra data padded in)
- //
- // So, we keep the already opened fiole handle,
- // and open a slightly different file for CDROM data
- //
- if ( is_cdrom )
- {
- fh->ioctl_name = fh->name;
- fh->ioctl_fd = fh->fd;
-
- fh->name = (char *) malloc(strlen(name) + 2);
- if ( fh->name )
- {
- *fh->name = '\0';
- strcat(fh->name, name);
- strcat(fh->name, "s1");
- fh->fd = open(fh->name, (read_only ? O_RDONLY : O_RDWR));
- if ( fh->fd < 0 ) {
- printf("WARNING: Cannot open %s (%s)\n",
- fh->name, strerror(errno));
- return NULL;
- }
- }
+#if defined __MACOSX__
+ if (is_cdrom) {
+ fh->is_cdrom = true;
+ fh->is_floppy = false;
+ if (cdrom_open_1(fh))
+ fh->is_media_present = true;
}
#endif
}
}
if (fh->is_floppy && first_floppy == NULL)
first_floppy = fh;
+ sys_add_file_handle(fh);
return fh;
} else {
printf("WARNING: Cannot open %s (%s)\n", name, strerror(errno));
@@ -459,6 +643,10 @@ void Sys_close(void *arg)
if (!fh)
return;
+ sys_remove_file_handle(fh);
+
+ if (fh->is_cdrom)
+ cdrom_close(fh);
if (fh->fd >= 0)
close(fh->fd);
if (fh->name)
@@ -526,6 +714,16 @@ loff_t SysGetFileSize(void *arg)
return 0;
D(bug(" BLKGETSIZE returns %d blocks\n", blocks));
return (loff_t)blocks * 512;
+#elif defined __MACOSX__
+ uint32 block_size;
+ if (ioctl(fh->ioctl_fd, DKIOCGETBLOCKSIZE, &block_size) < 0)
+ return 0;
+ D(bug(" DKIOCGETBLOCKSIZE returns %lu bytes\n", (unsigned long)block_size));
+ uint64 block_count;
+ if (ioctl(fh->ioctl_fd, DKIOCGETBLOCKCOUNT, &block_count) < 0)
+ return 0;
+ D(bug(" DKIOCGETBLOCKCOUNT returns %llu blocks\n", (unsigned long long)block_count));
+ return block_count * block_size;
#else
return lseek(fh->fd, 0, SEEK_END) - fh->start_byte;
#endif
@@ -566,31 +764,26 @@ void SysEject(void *arg)
fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
}
#elif defined(__APPLE__) && defined(__MACH__)
- if ( fh->is_cdrom ) {
-
- // Stolen from IOKit/storage/IOMediaBSDClient.h
- #define DKIOCEJECT _IO('d', 21)
-
+ if (fh->is_cdrom && fh->is_media_present) {
close(fh->fd);
- if ( ioctl(fh->ioctl_fd, DKIOCEJECT) < 0 )
- {
- printf("ioctl(DKIOCEJECT) failed on file %s: %s\n",
- fh->ioctl_name, strerror(errno));
+ fh->fd = -1;
+ if (ioctl(fh->ioctl_fd, DKIOCEJECT) < 0) {
+ D(bug(" DKIOCEJECT failed on file %s: %s\n",
+ fh->ioctl_name, strerror(errno)));
- // If we are running OSX, the device may be is busy
- // due to the Finder having the disk mounted and open,
- // so we have to use another method.
-
- // The only problem is that this takes about 5 seconds:
-
- char *cmd = (char *) malloc(30+sizeof(fh->name));
-
- if ( ! cmd )
- return;
+ // If we are running MacOS X, the device may be in busy
+ // state because the Finder has mounted the disk
close(fh->ioctl_fd);
- sprintf(cmd, "diskutil eject %s 2>&1 >/dev/null", fh->name);
+ fh->ioctl_fd = -1;
+
+ // Try to use "diskutil eject" but it can take up to 5
+ // seconds to complete
+ static const char eject_cmd[] = "/usr/sbin/diskutil eject %s 2>&1 >/dev/null";
+ char *cmd = (char *)alloca(strlen(eject_cmd) + strlen(fh->ioctl_name) + 1);
+ sprintf(cmd, eject_cmd, fh->ioctl_name);
system(cmd);
}
+ fh->is_media_present = false;
}
#endif
}
@@ -703,6 +896,9 @@ bool SysIsDiskInserted(void *arg)
} else if (fh->is_cdrom) {
struct ioc_toc_header header;
return ioctl(fh->fd, CDIOREADTOCHEADER, &header) == 0;
+#elif defined __MACOSX__
+ } else if (fh->is_cdrom || fh->is_floppy) {
+ return fh->is_media_present;
#endif
} else
@@ -801,10 +997,12 @@ bool SysCDReadTOC(void *arg, uint8 *toc)
*toc++ = toc_size >> 8;
*toc++ = toc_size & 0xff;
return true;
-#elif defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_2) && defined(HAVE_FRAMEWORK_COREFOUNDATION)
- extern bool DarwinCDReadTOC(char *name, uint8 *toc);
-
- return DarwinCDReadTOC(fh->name, toc);
+#elif defined __MACOSX__ && defined MAC_OS_X_VERSION_10_2
+ if (fh->is_media_present) {
+ extern bool DarwinCDReadTOC(char *name, uint8 *toc);
+ return DarwinCDReadTOC(fh->name, toc);
+ }
+ return false;
#elif defined(__FreeBSD__)
uint8 *p = toc + 2;
diff --git a/BasiliskII/src/Windows/sys_windows.cpp b/BasiliskII/src/Windows/sys_windows.cpp
index 0c866e49..825926df 100755
--- a/BasiliskII/src/Windows/sys_windows.cpp
+++ b/BasiliskII/src/Windows/sys_windows.cpp
@@ -45,14 +45,6 @@ using std::min;
#include "debug.h"
-// Supported media types
-enum {
- MEDIA_FLOPPY = 1,
- MEDIA_CD = 2,
- MEDIA_HD = 4,
- MEDIA_REMOVABLE = MEDIA_FLOPPY | MEDIA_CD
-};
-
// File handles are pointers to these structures
struct file_handle {
char *name; // Copy of device/file name
diff --git a/BasiliskII/src/include/sys.h b/BasiliskII/src/include/sys.h
index 1921bc91..7bb8096d 100644
--- a/BasiliskII/src/include/sys.h
+++ b/BasiliskII/src/include/sys.h
@@ -21,6 +21,14 @@
#ifndef SYS_H
#define SYS_H
+// Supported media types
+enum {
+ MEDIA_FLOPPY = 1,
+ MEDIA_CD = 2,
+ MEDIA_HD = 4,
+ MEDIA_REMOVABLE = MEDIA_FLOPPY | MEDIA_CD
+};
+
extern void SysInit(void);
extern void SysExit(void);