1 |
|
/* |
2 |
|
* sys_unix.cpp - System dependent routines, Unix implementation |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-1999 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2002 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
25 |
|
#include <errno.h> |
26 |
|
|
27 |
|
#ifdef __linux__ |
28 |
+ |
#include <sys/mount.h> |
29 |
|
#include <linux/cdrom.h> |
30 |
|
#include <linux/fd.h> |
31 |
|
#include <linux/major.h> |
33 |
|
#include <linux/unistd.h> |
34 |
|
|
35 |
|
#ifdef __NR__llseek |
36 |
< |
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); |
36 |
> |
_syscall5(int, _llseek, unsigned int, fd, unsigned long, hi, unsigned long, lo, loff_t *, res, unsigned int, wh); |
37 |
|
#else |
38 |
< |
static int _llseek(uint fd, ulong hi, ulong lo, loff_t *res, uint wh) |
38 |
> |
static int _llseek(unsigned int fd, unsigned long hi, unsigned long lo, loff_t *res, unsigned int wh) |
39 |
|
{ |
40 |
|
if (hi) |
41 |
|
return -1; |
47 |
|
#endif |
48 |
|
#endif |
49 |
|
|
50 |
< |
#ifdef __FreeBSD__ |
50 |
> |
#if defined(__FreeBSD__) || defined(__NetBSD__) |
51 |
|
#include <sys/cdio.h> |
52 |
|
#endif |
53 |
|
|
122 |
|
#if defined(__linux__) |
123 |
|
PrefsAddString("floppy", "/dev/fd0H1440"); |
124 |
|
PrefsAddString("floppy", "/dev/fd1H1440"); |
125 |
+ |
#elif defined(__NetBSD__) |
126 |
+ |
PrefsAddString("floppy", "/dev/fd0a"); |
127 |
+ |
PrefsAddString("floppy", "/dev/fd1a"); |
128 |
|
#else |
129 |
|
PrefsAddString("floppy", "/dev/fd0"); |
130 |
|
PrefsAddString("floppy", "/dev/fd1"); |
146 |
|
while(fgets(line, 255, f)) { |
147 |
|
// Read line |
148 |
|
int len = strlen(line); |
149 |
< |
if (len == 0) |
149 |
> |
if (len == 0 || line[0] == '#') |
150 |
|
continue; |
151 |
|
line[len-1] = 0; |
152 |
|
|
153 |
|
// Parse line |
154 |
|
char *dev, *mnt_point, *fstype; |
155 |
< |
if (sscanf(line, "%s %s %s", &dev, &mnt_point, &fstype) == 3) { |
155 |
> |
if (sscanf(line, "%as %as %as", &dev, &mnt_point, &fstype) == 3) { |
156 |
|
if (strcmp(fstype, "hfs") == 0) |
157 |
|
PrefsAddString("disk", dev); |
158 |
|
} |
159 |
+ |
free(dev); free(mnt_point); free(fstype); |
160 |
|
} |
161 |
|
fclose(f); |
162 |
|
} |
179 |
|
PrefsAddString("cdrom", "/dev/cdrom"); |
180 |
|
#elif defined(__FreeBSD__) |
181 |
|
PrefsAddString("cdrom", "/dev/cd0c"); |
182 |
+ |
#elif defined(__NetBSD__) |
183 |
+ |
PrefsAddString("cdrom", "/dev/cd0d"); |
184 |
|
#endif |
185 |
|
} |
186 |
|
|
197 |
|
#elif defined(__FreeBSD__) |
198 |
|
PrefsAddString("seriala", "/dev/cuaa0"); |
199 |
|
PrefsAddString("serialb", "/dev/cuaa1"); |
200 |
+ |
#elif defined(__NetBSD__) |
201 |
+ |
PrefsAddString("seriala", "/dev/tty00"); |
202 |
+ |
PrefsAddString("serialb", "/dev/tty01"); |
203 |
|
#endif |
204 |
|
} |
205 |
|
|
224 |
|
// Parse line |
225 |
|
if (strncmp(line, dev_name, strlen(dev_name)) == 0) { |
226 |
|
mount_name[0] = 0; |
227 |
< |
char dummy[256]; |
228 |
< |
sscanf(line, "%s %s", dummy, mount_name); |
227 |
> |
char *dummy; |
228 |
> |
sscanf(line, "%as %s", &dummy, mount_name); |
229 |
> |
free(dummy); |
230 |
|
fclose(f); |
231 |
|
return true; |
232 |
|
} |
245 |
|
void *Sys_open(const char *name, bool read_only) |
246 |
|
{ |
247 |
|
bool is_file = strncmp(name, "/dev/", 5) != 0; |
248 |
< |
#ifdef __FreeBSD__ |
248 |
> |
#if defined(__FreeBSD__) |
249 |
|
// SCSI IDE |
250 |
|
bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0; |
251 |
|
#else |
273 |
|
} |
274 |
|
|
275 |
|
// Open file/device |
276 |
< |
#ifdef __linux__ |
276 |
> |
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) |
277 |
|
int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0)); |
278 |
|
#else |
279 |
|
int fd = open(name, read_only ? O_RDONLY : O_RDWR); |
295 |
|
if (fh->is_file) { |
296 |
|
// Detect disk image file layout |
297 |
|
loff_t size = 0; |
298 |
< |
#ifdef __linux__ |
298 |
> |
#if defined(__linux__) |
299 |
|
_llseek(fh->fd, 0, 0, &size, SEEK_END); |
300 |
|
#else |
301 |
|
size = lseek(fd, 0, SEEK_END); |
330 |
|
#else |
331 |
|
fh->cdrom_cap = 0; |
332 |
|
#endif |
333 |
+ |
#elif defined(__NetBSD__) |
334 |
+ |
fh->is_floppy = ((st.st_rdev >> 16) == 2); |
335 |
|
#endif |
336 |
|
} |
337 |
|
} |
375 |
|
return 0; |
376 |
|
|
377 |
|
// Seek to position |
378 |
< |
#ifdef __linux__ |
378 |
> |
#if defined(__linux__) |
379 |
|
loff_t pos = offset + fh->start_byte, res; |
380 |
|
if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0) |
381 |
|
return 0; |
401 |
|
return 0; |
402 |
|
|
403 |
|
// Seek to position |
404 |
< |
#ifdef __linux__ |
404 |
> |
#if defined(__linux__) |
405 |
|
loff_t pos = offset + fh->start_byte, res; |
406 |
|
if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0) |
407 |
|
return 0; |
428 |
|
if (fh->is_file) |
429 |
|
return fh->file_size; |
430 |
|
else { |
431 |
< |
#ifdef __linux__ |
432 |
< |
loff_t pos = 0; |
433 |
< |
_llseek(fh->fd, 0, 0, &pos, SEEK_END); |
434 |
< |
return pos - fh->start_byte; |
431 |
> |
#if defined(__linux__) |
432 |
> |
long blocks; |
433 |
> |
if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0) |
434 |
> |
return 0; |
435 |
> |
D(bug(" BLKGETSIZE returns %d blocks\n", blocks)); |
436 |
> |
return (loff_t)blocks * 512; |
437 |
|
#else |
438 |
|
return lseek(fh->fd, 0, SEEK_END) - fh->start_byte; |
439 |
|
#endif |
461 |
|
close(fh->fd); // Close and reopen so the driver will see the media change |
462 |
|
fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); |
463 |
|
} |
464 |
< |
#elif defined(__FreeBSD__) |
464 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
465 |
|
if (fh->is_floppy) { |
466 |
|
fsync(fh->fd); |
467 |
|
//ioctl(fh->fd, FDFLUSH); |
500 |
|
if (!fh) |
501 |
|
return true; |
502 |
|
|
503 |
< |
#ifdef __linux__ |
503 |
> |
#if defined(__linux__) |
504 |
|
if (fh->is_floppy) { |
505 |
|
struct floppy_drive_struct stat; |
506 |
|
ioctl(fh->fd, FDGETDRVSTAT, &stat); |
549 |
|
lseek(fh->fd, 0, SEEK_SET); |
550 |
|
return read(fh->fd, block, 512) == 512; |
551 |
|
} else if (fh->is_cdrom) { |
552 |
+ |
#ifdef CDROM_MEDIA_CHANGED |
553 |
+ |
if (fh->cdrom_cap & CDC_MEDIA_CHANGED) { |
554 |
+ |
// If we don't do this, all attempts to read from a disc fail |
555 |
+ |
// once the tray has been open (altough the TOC reads fine). |
556 |
+ |
// Can somebody explain this to me? |
557 |
+ |
if (ioctl(fh->fd, CDROM_MEDIA_CHANGED) == 1) { |
558 |
+ |
close(fh->fd); |
559 |
+ |
fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); |
560 |
+ |
} |
561 |
+ |
} |
562 |
+ |
#endif |
563 |
|
#ifdef CDROM_DRIVE_STATUS |
564 |
|
if (fh->cdrom_cap & CDC_DRIVE_STATUS) { |
565 |
|
return ioctl(fh->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK; |
567 |
|
#endif |
568 |
|
cdrom_tochdr header; |
569 |
|
return ioctl(fh->fd, CDROMREADTOCHDR, &header) == 0; |
570 |
< |
#elif defined(__FreeBSD__) |
570 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
571 |
|
} else if (fh->is_floppy) { |
572 |
|
return false; //!! |
573 |
|
} else if (fh->is_cdrom) { |
607 |
|
if (!fh) |
608 |
|
return; |
609 |
|
|
610 |
< |
#ifdef defined(__linux__) && defined(CDROM_LOCKDOOR) |
610 |
> |
#if defined(__linux__) && defined(CDROM_LOCKDOOR) |
611 |
|
if (fh->is_cdrom) |
612 |
|
ioctl(fh->fd, CDROM_LOCKDOOR, 0); |
613 |
|
#endif |
717 |
|
*toc++ = toc_size >> 8; |
718 |
|
*toc++ = toc_size & 0xff; |
719 |
|
return true; |
720 |
+ |
#elif defined(__NetBSD__) |
721 |
+ |
uint8 *p = toc + 2; |
722 |
+ |
|
723 |
+ |
// Header |
724 |
+ |
struct ioc_toc_header header; |
725 |
+ |
if (ioctl(fh->fd, CDIOREADTOCHEADER, &header) < 0) |
726 |
+ |
return false; |
727 |
+ |
*p++ = header.starting_track; |
728 |
+ |
*p++ = header.ending_track; |
729 |
+ |
|
730 |
+ |
// Tracks (this is nice... :-) |
731 |
+ |
struct ioc_read_toc_entry entries; |
732 |
+ |
entries.address_format = CD_MSF_FORMAT; |
733 |
+ |
entries.starting_track = 1; |
734 |
+ |
entries.data_len = 800; |
735 |
+ |
entries.data = (cd_toc_entry *)p; |
736 |
+ |
if (ioctl(fh->fd, CDIOREADTOCENTRIES, &entries) < 0) |
737 |
+ |
return false; |
738 |
+ |
|
739 |
+ |
// TOC size |
740 |
+ |
int toc_size = p - toc; |
741 |
+ |
*toc++ = toc_size >> 8; |
742 |
+ |
*toc++ = toc_size & 0xff; |
743 |
+ |
return true; |
744 |
|
#endif |
745 |
|
} else |
746 |
|
return false; |
780 |
|
*pos++ = chan.cdsc_reladdr.msf.second; |
781 |
|
*pos++ = chan.cdsc_reladdr.msf.frame; |
782 |
|
return true; |
783 |
< |
#elif defined(__FreeBSD__) |
783 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
784 |
|
struct ioc_read_subchannel chan; |
785 |
|
chan.data_format = CD_MSF_FORMAT; |
786 |
|
chan.address_format = CD_MSF_FORMAT; |
830 |
|
play.cdmsf_sec1 = end_s; |
831 |
|
play.cdmsf_frame1 = end_f; |
832 |
|
return ioctl(fh->fd, CDROMPLAYMSF, &play) == 0; |
833 |
< |
#elif defined(__FreeBSD__) |
833 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
834 |
|
struct ioc_play_msf play; |
835 |
|
play.start_m = start_m; |
836 |
|
play.start_s = start_s; |
858 |
|
if (fh->is_cdrom) { |
859 |
|
#if defined(__linux__) |
860 |
|
return ioctl(fh->fd, CDROMPAUSE) == 0; |
861 |
< |
#elif defined(__FreeBSD__) |
861 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
862 |
|
return ioctl(fh->fd, CDIOCPAUSE) == 0; |
863 |
|
#endif |
864 |
|
} else |
879 |
|
if (fh->is_cdrom) { |
880 |
|
#if defined(__linux__) |
881 |
|
return ioctl(fh->fd, CDROMRESUME) == 0; |
882 |
< |
#elif defined(__FreeBSD__) |
882 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
883 |
|
return ioctl(fh->fd, CDIOCRESUME) == 0; |
884 |
|
#endif |
885 |
|
} else |
900 |
|
if (fh->is_cdrom) { |
901 |
|
#if defined(__linux__) |
902 |
|
return ioctl(fh->fd, CDROMSTOP) == 0; |
903 |
< |
#elif defined(__FreeBSD__) |
903 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
904 |
|
return ioctl(fh->fd, CDIOCSTOP) == 0; |
905 |
|
#endif |
906 |
|
} else |
939 |
|
vol.channel0 = vol.channel2 = left; |
940 |
|
vol.channel1 = vol.channel3 = right; |
941 |
|
ioctl(fh->fd, CDROMVOLCTRL, &vol); |
942 |
< |
#elif defined(__FreeBSD__) |
942 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
943 |
|
struct ioc_vol vol; |
944 |
|
vol.vol[0] = vol.vol[2] = left; |
945 |
|
vol.vol[1] = vol.vol[3] = right; |
966 |
|
ioctl(fh->fd, CDROMVOLREAD, &vol); |
967 |
|
left = vol.channel0; |
968 |
|
right = vol.channel1; |
969 |
< |
#elif defined(__FreeBSD__) |
969 |
> |
#elif defined(__FreeBSD__) || defined(__NetBSD__) |
970 |
|
struct ioc_vol vol; |
971 |
|
ioctl(fh->fd, CDIOCGETVOL, &vol); |
972 |
|
left = vol.vol[0]; |