--- BasiliskII/src/Unix/sys_unix.cpp 1999/10/03 14:16:25 1.1.1.1 +++ BasiliskII/src/Unix/sys_unix.cpp 2002/04/28 14:06:17 1.18 @@ -1,7 +1,7 @@ /* * sys_unix.cpp - System dependent routines, Unix implementation * - * Basilisk II (C) 1997-1999 Christian Bauer + * Basilisk II (C) 1997-2002 Christian Bauer * * 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 @@ -25,16 +25,18 @@ #include #ifdef __linux__ +#include #include #include #include #include #include +#include #ifdef __NR__llseek -_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); +_syscall5(int, _llseek, unsigned int, fd, unsigned long, hi, unsigned long, lo, loff_t *, res, unsigned int, wh); #else -static int _llseek(uint fd, ulong hi, ulong lo, loff_t *res, uint wh) +static int _llseek(unsigned int fd, unsigned long hi, unsigned long lo, loff_t *res, unsigned int wh) { if (hi) return -1; @@ -46,7 +48,7 @@ static int _llseek(uint fd, ulong hi, ul #endif #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) #include #endif @@ -119,8 +121,26 @@ void SysMountFirstFloppy(void) void SysAddFloppyPrefs(void) { #if defined(__linux__) - PrefsAddString("floppy", "/dev/fd0H1440"); - PrefsAddString("floppy", "/dev/fd1H1440"); + if (access("/dev/.devfsd", F_OK) < 0) { + PrefsAddString("floppy", "/dev/fd0u1440"); + PrefsAddString("floppy", "/dev/fd1u1440"); + } else { + DIR *fd_dir = opendir("/dev/floppy"); + if (fd_dir) { + struct dirent *floppy_dev; + while ((floppy_dev = readdir(fd_dir)) != NULL) { + if (strstr(floppy_dev->d_name, "u1440") != NULL) { + char fd_dev[20]; + sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name); + PrefsAddString("floppy", fd_dev); + } + } + closedir(fd_dir); + } + } +#elif defined(__NetBSD__) + PrefsAddString("floppy", "/dev/fd0a"); + PrefsAddString("floppy", "/dev/fd1a"); #else PrefsAddString("floppy", "/dev/fd0"); PrefsAddString("floppy", "/dev/fd1"); @@ -142,16 +162,17 @@ void SysAddDiskPrefs(void) while(fgets(line, 255, f)) { // Read line int len = strlen(line); - if (len == 0) + if (len == 0 || line[0] == '#') continue; line[len-1] = 0; // Parse line char *dev, *mnt_point, *fstype; - if (sscanf(line, "%s %s %s", &dev, &mnt_point, &fstype) == 3) { + if (sscanf(line, "%as %as %as", &dev, &mnt_point, &fstype) == 3) { if (strcmp(fstype, "hfs") == 0) PrefsAddString("disk", dev); } + free(dev); free(mnt_point); free(fstype); } fclose(f); } @@ -171,8 +192,23 @@ void SysAddCDROMPrefs(void) return; #if defined(__linux__) - PrefsAddString("cdrom", "/dev/cdrom"); -#elif defined(__FreeBSD__) + if (access("/dev/.devfsd", F_OK) < 0) + PrefsAddString("cdrom", "/dev/cdrom"); + else { + DIR *cd_dir = opendir("/dev/cdroms"); + if (cd_dir) { + struct dirent *cdrom_dev; + while ((cdrom_dev = readdir(cd_dir)) != NULL) { + if (strcmp(cdrom_dev->d_name, ".") != 0 && strcmp(cdrom_dev->d_name, "..") != 0) { + char cd_dev[20]; + sprintf(cd_dev, "/dev/cdroms/%s", cdrom_dev->d_name); + PrefsAddString("cdrom", cd_dev); + } + } + closedir(cd_dir); + } + } +#elif defined(__FreeBSD__) || defined(__NetBSD__) PrefsAddString("cdrom", "/dev/cd0c"); #endif } @@ -185,11 +221,19 @@ void SysAddCDROMPrefs(void) void SysAddSerialPrefs(void) { #if defined(__linux__) - PrefsAddString("seriala", "/dev/ttyS0"); - PrefsAddString("serialb", "/dev/ttyS1"); + if (access("/dev/.devfsd", F_OK) < 0) { + PrefsAddString("seriala", "/dev/ttyS0"); + PrefsAddString("serialb", "/dev/ttyS1"); + } else { + PrefsAddString("seriala", "/dev/tts/0"); + PrefsAddString("serialb", "/dev/tts/1"); + } #elif defined(__FreeBSD__) PrefsAddString("seriala", "/dev/cuaa0"); PrefsAddString("serialb", "/dev/cuaa1"); +#elif defined(__NetBSD__) + PrefsAddString("seriala", "/dev/tty00"); + PrefsAddString("serialb", "/dev/tty01"); #endif } @@ -214,8 +258,9 @@ static bool is_drive_mounted(const char // Parse line if (strncmp(line, dev_name, strlen(dev_name)) == 0) { mount_name[0] = 0; - char dummy[256]; - sscanf(line, "%s %s", dummy, mount_name); + char *dummy; + sscanf(line, "%as %s", &dummy, mount_name); + free(dummy); fclose(f); return true; } @@ -234,7 +279,7 @@ static bool is_drive_mounted(const char void *Sys_open(const char *name, bool read_only) { bool is_file = strncmp(name, "/dev/", 5) != 0; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) // SCSI IDE bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0; #else @@ -262,7 +307,7 @@ void *Sys_open(const char *name, bool re } // Open file/device -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) 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); @@ -284,7 +329,7 @@ void *Sys_open(const char *name, bool re if (fh->is_file) { // Detect disk image file layout loff_t size = 0; -#ifdef __linux__ +#if defined(__linux__) _llseek(fh->fd, 0, 0, &size, SEEK_END); #else size = lseek(fd, 0, SEEK_END); @@ -319,6 +364,8 @@ void *Sys_open(const char *name, bool re #else fh->cdrom_cap = 0; #endif +#elif defined(__NetBSD__) + fh->is_floppy = ((st.st_rdev >> 16) == 2); #endif } } @@ -362,7 +409,7 @@ size_t Sys_read(void *arg, void *buffer, return 0; // Seek to position -#ifdef __linux__ +#if defined(__linux__) loff_t pos = offset + fh->start_byte, res; if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0) return 0; @@ -388,7 +435,7 @@ size_t Sys_write(void *arg, void *buffer return 0; // Seek to position -#ifdef __linux__ +#if defined(__linux__) loff_t pos = offset + fh->start_byte, res; if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0) return 0; @@ -415,10 +462,12 @@ loff_t SysGetFileSize(void *arg) if (fh->is_file) return fh->file_size; else { -#ifdef __linux__ - loff_t pos = 0; - _llseek(fh->fd, 0, 0, &pos, SEEK_END); - return pos - fh->start_byte; +#if defined(__linux__) + long blocks; + if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0) + return 0; + D(bug(" BLKGETSIZE returns %d blocks\n", blocks)); + return (loff_t)blocks * 512; #else return lseek(fh->fd, 0, SEEK_END) - fh->start_byte; #endif @@ -441,16 +490,16 @@ void SysEject(void *arg) fsync(fh->fd); ioctl(fh->fd, FDFLUSH); ioctl(fh->fd, FDEJECT); + close(fh->fd); // Close and reopen so the driver will see the media change + fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR); } else if (fh->is_cdrom) { ioctl(fh->fd, CDROMEJECT); close(fh->fd); // Close and reopen so the driver will see the media change fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) if (fh->is_floppy) { fsync(fh->fd); - //ioctl(fh->fd, FDFLUSH); - //ioctl(fh->fd, FDEJECT); } else if (fh->is_cdrom) { ioctl(fh->fd, CDIOCEJECT); close(fh->fd); // Close and reopen so the driver will see the media change @@ -485,7 +534,7 @@ bool SysIsReadOnly(void *arg) if (!fh) return true; -#ifdef __linux__ +#if defined(__linux__) if (fh->is_floppy) { struct floppy_drive_struct stat; ioctl(fh->fd, FDGETDRVSTAT, &stat); @@ -532,8 +581,25 @@ bool SysIsDiskInserted(void *arg) } else if (fh->is_floppy) { char block[512]; lseek(fh->fd, 0, SEEK_SET); - return read(fh->fd, block, 512) == 512; + ssize_t actual = read(fh->fd, block, 512); + if (actual < 0) { + close(fh->fd); // Close and reopen so the driver will see the media change + fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR); + actual = read(fh->fd, block, 512); + } + return actual == 512; } else if (fh->is_cdrom) { +#ifdef CDROM_MEDIA_CHANGED + if (fh->cdrom_cap & CDC_MEDIA_CHANGED) { + // If we don't do this, all attempts to read from a disc fail + // once the tray has been opened (altough the TOC reads fine). + // Can somebody explain this to me? + if (ioctl(fh->fd, CDROM_MEDIA_CHANGED) == 1) { + close(fh->fd); + fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); + } + } +#endif #ifdef CDROM_DRIVE_STATUS if (fh->cdrom_cap & CDC_DRIVE_STATUS) { return ioctl(fh->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK; @@ -541,7 +607,7 @@ bool SysIsDiskInserted(void *arg) #endif cdrom_tochdr header; return ioctl(fh->fd, CDROMREADTOCHDR, &header) == 0; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) } else if (fh->is_floppy) { return false; //!! } else if (fh->is_cdrom) { @@ -581,7 +647,7 @@ void SysAllowRemoval(void *arg) if (!fh) return; -#ifdef defined(__linux__) && defined(CDROM_LOCKDOOR) +#if defined(__linux__) && defined(CDROM_LOCKDOOR) if (fh->is_cdrom) ioctl(fh->fd, CDROM_LOCKDOOR, 0); #endif @@ -691,6 +757,32 @@ bool SysCDReadTOC(void *arg, uint8 *toc) *toc++ = toc_size >> 8; *toc++ = toc_size & 0xff; return true; +#elif defined(__NetBSD__) + uint8 *p = toc + 2; + + // Header + struct ioc_toc_header header; + if (ioctl(fh->fd, CDIOREADTOCHEADER, &header) < 0) + return false; + *p++ = header.starting_track; + *p++ = header.ending_track; + + // Tracks (this is nice... :-) + struct ioc_read_toc_entry entries; + entries.address_format = CD_MSF_FORMAT; + entries.starting_track = 1; + entries.data_len = 800; + entries.data = (cd_toc_entry *)p; + if (ioctl(fh->fd, CDIOREADTOCENTRIES, &entries) < 0) + return false; + + // TOC size + int toc_size = p - toc; + *toc++ = toc_size >> 8; + *toc++ = toc_size & 0xff; + return true; +#else + return false; #endif } else return false; @@ -730,7 +822,7 @@ bool SysCDGetPosition(void *arg, uint8 * *pos++ = chan.cdsc_reladdr.msf.second; *pos++ = chan.cdsc_reladdr.msf.frame; return true; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) struct ioc_read_subchannel chan; chan.data_format = CD_MSF_FORMAT; chan.address_format = CD_MSF_FORMAT; @@ -754,6 +846,8 @@ bool SysCDGetPosition(void *arg, uint8 * *pos++ = chan.data->what.position.reladdr.msf.second; *pos++ = chan.data->what.position.reladdr.msf.frame; return true; +#else + return false; #endif } else return false; @@ -780,7 +874,7 @@ bool SysCDPlay(void *arg, uint8 start_m, play.cdmsf_sec1 = end_s; play.cdmsf_frame1 = end_f; return ioctl(fh->fd, CDROMPLAYMSF, &play) == 0; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) struct ioc_play_msf play; play.start_m = start_m; play.start_s = start_s; @@ -789,6 +883,8 @@ bool SysCDPlay(void *arg, uint8 start_m, play.end_s = end_s; play.end_f = end_f; return ioctl(fh->fd, CDIOCPLAYMSF, &play) == 0; +#else + return false; #endif } else return false; @@ -808,8 +904,10 @@ bool SysCDPause(void *arg) if (fh->is_cdrom) { #if defined(__linux__) return ioctl(fh->fd, CDROMPAUSE) == 0; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) return ioctl(fh->fd, CDIOCPAUSE) == 0; +#else + return false; #endif } else return false; @@ -829,8 +927,10 @@ bool SysCDResume(void *arg) if (fh->is_cdrom) { #if defined(__linux__) return ioctl(fh->fd, CDROMRESUME) == 0; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) return ioctl(fh->fd, CDIOCRESUME) == 0; +#else + return false; #endif } else return false; @@ -850,8 +950,10 @@ bool SysCDStop(void *arg, uint8 lead_out if (fh->is_cdrom) { #if defined(__linux__) return ioctl(fh->fd, CDROMSTOP) == 0; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) return ioctl(fh->fd, CDIOCSTOP) == 0; +#else + return false; #endif } else return false; @@ -889,7 +991,7 @@ void SysCDSetVolume(void *arg, uint8 lef vol.channel0 = vol.channel2 = left; vol.channel1 = vol.channel3 = right; ioctl(fh->fd, CDROMVOLCTRL, &vol); -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) struct ioc_vol vol; vol.vol[0] = vol.vol[2] = left; vol.vol[1] = vol.vol[3] = right; @@ -916,7 +1018,7 @@ void SysCDGetVolume(void *arg, uint8 &le ioctl(fh->fd, CDROMVOLREAD, &vol); left = vol.channel0; right = vol.channel1; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) struct ioc_vol vol; ioctl(fh->fd, CDIOCGETVOL, &vol); left = vol.vol[0];