ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sys_unix.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/sys_unix.cpp (file contents):
Revision 1.3 by cebix, 1999-10-14T11:37:47Z vs.
Revision 1.20 by gbeauche, 2003-10-12T21:55:44Z

# Line 1 | Line 1
1   /*
2   *  sys_unix.cpp - System dependent routines, Unix implementation
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2003 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
# Line 25 | Line 25
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>
32   #include <linux/kdev_t.h>
33   #include <linux/unistd.h>
34 + #include <dirent.h>
35  
36   #ifdef __NR__llseek
37 < _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
37 > _syscall5(int, _llseek, unsigned int, fd, unsigned long, hi, unsigned long, lo, loff_t *, res, unsigned int, wh);
38   #else
39 < static int _llseek(uint fd, ulong hi, ulong lo, loff_t *res, uint wh)
39 > static int _llseek(unsigned int fd, unsigned long hi, unsigned long lo, loff_t *res, unsigned int wh)
40   {
41          if (hi)
42                  return -1;
# Line 75 | Line 77 | struct file_handle {
77          int cdrom_cap;          // CD-ROM capability flags (only valid if is_cdrom is true)
78   #elif defined(__FreeBSD__)
79          struct ioc_capability cdrom_cap;
80 + #elif defined(__APPLE__) && defined(__MACH__)
81 +        char    *ioctl_name;    // For CDs on OS X - a device for special ioctls
82 +        int             ioctl_fd;
83   #endif
84   };
85  
# Line 119 | Line 124 | void SysMountFirstFloppy(void)
124   void SysAddFloppyPrefs(void)
125   {
126   #if defined(__linux__)
127 <        PrefsAddString("floppy", "/dev/fd0H1440");
128 <        PrefsAddString("floppy", "/dev/fd1H1440");
127 >        if (access("/dev/.devfsd", F_OK) < 0) {
128 >                PrefsAddString("floppy", "/dev/fd0u1440");
129 >                PrefsAddString("floppy", "/dev/fd1u1440");
130 >        } else {
131 >                DIR *fd_dir = opendir("/dev/floppy");
132 >                if (fd_dir) {
133 >                        struct dirent *floppy_dev;
134 >                        while ((floppy_dev = readdir(fd_dir)) != NULL) {
135 >                                if (strstr(floppy_dev->d_name, "u1440") != NULL) {
136 >                                        char fd_dev[20];
137 >                                        sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name);
138 >                                        PrefsAddString("floppy", fd_dev);
139 >                                }
140 >                        }
141 >                        closedir(fd_dir);
142 >                }
143 >        }
144   #elif defined(__NetBSD__)
145          PrefsAddString("floppy", "/dev/fd0a");
146          PrefsAddString("floppy", "/dev/fd1a");
147 + #elif defined(__APPLE__) && defined(__MACH__)
148 +        // FIXME: We assume an Aqua build causes <AvailabilityMacros.h> to
149 +        // be included, thusly enabling this part of code that would cause
150 +        // Basilisk II to hang otherwise.
151 + #ifdef MAC_OS_X_VERSION_10_0
152 +        PrefsAddString("floppy", "/dev/fd/0");
153 +        PrefsAddString("floppy", "/dev/fd/1");
154 + #endif
155   #else
156          PrefsAddString("floppy", "/dev/fd0");
157          PrefsAddString("floppy", "/dev/fd1");
# Line 134 | Line 162 | void SysAddFloppyPrefs(void)
162   /*
163   *  This gets called when no "disk" prefs items are found
164   *  It scans for available HFS volumes and adds appropriate prefs items
165 + *      On OS X, we could do the same, but on an OS X machine I think it is
166 + *      very unlikely that any mounted volumes would contain a system which
167 + *      is old enough to boot a 68k Mac, so we just do nothing here for now.
168   */
169  
170   void SysAddDiskPrefs(void)
# Line 145 | Line 176 | void SysAddDiskPrefs(void)
176                  while(fgets(line, 255, f)) {
177                          // Read line
178                          int len = strlen(line);
179 <                        if (len == 0)
179 >                        if (len == 0 || line[0] == '#')
180                                  continue;
181                          line[len-1] = 0;
182  
# Line 175 | Line 206 | void SysAddCDROMPrefs(void)
206                  return;
207  
208   #if defined(__linux__)
209 <        PrefsAddString("cdrom", "/dev/cdrom");
210 < #elif defined(__FreeBSD__)
209 >        if (access("/dev/.devfsd", F_OK) < 0)
210 >                PrefsAddString("cdrom", "/dev/cdrom");
211 >        else {
212 >                DIR *cd_dir = opendir("/dev/cdroms");
213 >                if (cd_dir) {
214 >                        struct dirent *cdrom_dev;
215 >                        while ((cdrom_dev = readdir(cd_dir)) != NULL) {
216 >                                if (strcmp(cdrom_dev->d_name, ".") != 0 && strcmp(cdrom_dev->d_name, "..") != 0) {
217 >                                        char cd_dev[20];
218 >                                        sprintf(cd_dev, "/dev/cdroms/%s", cdrom_dev->d_name);
219 >                                        PrefsAddString("cdrom", cd_dev);
220 >                                }
221 >                        }
222 >                        closedir(cd_dir);
223 >                }
224 >        }
225 > #elif defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_0)
226 >        extern  void DarwinAddCDROMPrefs(void);
227 >
228 >        DarwinAddCDROMPrefs();
229 > #elif defined(__FreeBSD__) || defined(__NetBSD__)
230          PrefsAddString("cdrom", "/dev/cd0c");
181 #elif defined(__NetBSD__)
182        PrefsAddString("cdrom", "/dev/cd0d");
231   #endif
232   }
233  
# Line 191 | Line 239 | void SysAddCDROMPrefs(void)
239   void SysAddSerialPrefs(void)
240   {
241   #if defined(__linux__)
242 <        PrefsAddString("seriala", "/dev/ttyS0");
243 <        PrefsAddString("serialb", "/dev/ttyS1");
242 >        if (access("/dev/.devfsd", F_OK) < 0) {
243 >                PrefsAddString("seriala", "/dev/ttyS0");
244 >                PrefsAddString("serialb", "/dev/ttyS1");
245 >        } else {
246 >                PrefsAddString("seriala", "/dev/tts/0");
247 >                PrefsAddString("serialb", "/dev/tts/1");
248 >        }
249   #elif defined(__FreeBSD__)
250          PrefsAddString("seriala", "/dev/cuaa0");
251          PrefsAddString("serialb", "/dev/cuaa1");
252   #elif defined(__NetBSD__)
253          PrefsAddString("seriala", "/dev/tty00");
254          PrefsAddString("serialb", "/dev/tty01");
255 + #elif defined(__APPLE__) && defined(__MACH__)
256 +        // FIXME: We assume an Aqua build causes <AvailabilityMacros.h> to
257 +        // be included, thusly enabling this part of code that would cause
258 +        // Basilisk II to hang otherwise.
259 + #ifdef MAC_OS_X_VERSION_10_0
260 +        PrefsAddString("seriala", "/dev/ttys0");
261 +        PrefsAddString("serialb", "/dev/ttys1");
262 + #endif
263 + //      PrefsAddString("seriala", "/dev/cu.modem");
264 + //      PrefsAddString("serialb", "/dev/cu.IrDA-IrCOMMch-b");
265   #endif
266   }
267  
# Line 251 | Line 314 | void *Sys_open(const char *name, bool re
314          bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
315   #endif
316  
317 + #if defined(__APPLE__) && defined(__MACH__)
318 +        //
319 +        // There is no set filename in /dev which is the cdrom,
320 +        // so we have to see if it is any of the devices that we found earlier
321 +        //
322 +        const char      *cdrom;
323 +        int                     tmp = 0;
324 +
325 +        while ( (cdrom = PrefsFindString("cdrom", tmp) ) != NULL )
326 +        {
327 +                if ( strcmp(name, cdrom) == 0 )
328 +                {
329 +                        is_cdrom = 1;
330 +                        read_only = 1;
331 +                        break;
332 +                }
333 +                ++tmp;
334 +        }
335 + #endif
336 +
337          D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));
338  
339          // Check if write access is allowed, set read-only flag if not
# Line 272 | Line 355 | void *Sys_open(const char *name, bool re
355          }
356  
357          // Open file/device
358 < #if defined(__linux__)
358 > #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
359          int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0));
360   #else
361          int fd = open(name, read_only ? O_RDONLY : O_RDWR);
# Line 319 | Line 402 | void *Sys_open(const char *name, bool re
402   #else
403                                          fh->cdrom_cap = 0;
404   #endif
405 < #elif defined(__FreeBSD__) || defined(__NetBSD__)
405 > #elif defined(__FreeBSD__)
406                                          fh->is_floppy = ((st.st_rdev >> 16) == 2);
407   #ifdef CDIOCCAPABILITY
408                                          if (is_cdrom) {
# Line 329 | Line 412 | void *Sys_open(const char *name, bool re
412   #else
413                                          fh->cdrom_cap = 0;
414   #endif
415 + #elif defined(__NetBSD__)
416 +                                        fh->is_floppy = ((st.st_rdev >> 16) == 2);
417   #endif
418                                  }
419 + #if defined(__APPLE__) && defined(__MACH__)
420 +
421 +                                // In OS X, the device name is OK for sending ioctls to,
422 +                                // but not for reading raw CDROM data from.
423 +                                // (it seems to have extra data padded in)
424 +                                //
425 +                                // So, we keep the already opened fiole handle,
426 +                                // and open a slightly different file for CDROM data
427 +                                //
428 +                                if ( is_cdrom )
429 +                                {
430 +                                        fh->ioctl_name  = fh->name;
431 +                                        fh->ioctl_fd    = fh->fd;
432 +
433 +                                        fh->name = (char *) malloc(strlen(name) + 2);
434 +                                        if ( fh->name )
435 +                                        {
436 +                                                *fh->name = '\0';
437 +                                                strcat(fh->name, name);
438 +                                                strcat(fh->name, "s1");
439 +                                                fh->fd = open(fh->name, (read_only ? O_RDONLY : O_RDWR));
440 +                                                if ( fh->fd < 0 ) {
441 +                                                        printf("WARNING: Cannot open %s (%s)\n",
442 +                                                                                        fh->name, strerror(errno));
443 +                                                        return NULL;
444 +                                                }
445 +                                        }
446 +                                }
447 + #endif
448                          }
449                  }
450                  if (fh->is_floppy && first_floppy == NULL)
# Line 426 | Line 540 | loff_t SysGetFileSize(void *arg)
540                  return fh->file_size;
541          else {
542   #if defined(__linux__)
543 <                loff_t pos = 0;
544 <                _llseek(fh->fd, 0, 0, &pos, SEEK_END);
545 <                return pos - fh->start_byte;
543 >                long blocks;
544 >                if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0)
545 >                        return 0;
546 >                D(bug(" BLKGETSIZE returns %d blocks\n", blocks));
547 >                return (loff_t)blocks * 512;
548   #else
549                  return lseek(fh->fd, 0, SEEK_END) - fh->start_byte;
550   #endif
# Line 451 | Line 567 | void SysEject(void *arg)
567                  fsync(fh->fd);
568                  ioctl(fh->fd, FDFLUSH);
569                  ioctl(fh->fd, FDEJECT);
570 +                close(fh->fd);  // Close and reopen so the driver will see the media change
571 +                fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR);
572          } else if (fh->is_cdrom) {
573                  ioctl(fh->fd, CDROMEJECT);
574                  close(fh->fd);  // Close and reopen so the driver will see the media change
# Line 459 | Line 577 | void SysEject(void *arg)
577   #elif defined(__FreeBSD__) || defined(__NetBSD__)
578          if (fh->is_floppy) {
579                  fsync(fh->fd);
462                //ioctl(fh->fd, FDFLUSH);
463                //ioctl(fh->fd, FDEJECT);
580          } else if (fh->is_cdrom) {
581                  ioctl(fh->fd, CDIOCEJECT);
582                  close(fh->fd);  // Close and reopen so the driver will see the media change
583                  fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
584          }
585 + #elif defined(__APPLE__) && defined(__MACH__)
586 +        if ( fh->is_cdrom ) {
587 +
588 +                // Stolen from IOKit/storage/IOMediaBSDClient.h
589 +                #define DKIOCEJECT _IO('d', 21)
590 +
591 +                close(fh->fd);
592 +                if ( ioctl(fh->ioctl_fd, DKIOCEJECT) < 0 )
593 +                {
594 +                        printf("ioctl(DKIOCEJECT) failed on file %s: %s\n",
595 +                                                                fh->ioctl_name, strerror(errno));
596 +
597 +                        // If we are running OSX, the device may be is busy
598 +                        // due to the Finder having the disk mounted and open,
599 +                        // so we have to use another method.
600 +
601 +                        // The only problem is that this takes about 5 seconds:
602 +
603 +                        char    *cmd = (char *) malloc(30+sizeof(fh->name));
604 +
605 +                        if ( ! cmd )
606 +                                return;
607 +                        close(fh->ioctl_fd);
608 +                        sprintf(cmd, "diskutil eject %s 2>&1 >/dev/null", fh->name);
609 +                        system(cmd);
610 +                }
611 +        }
612   #endif
613   }
614  
# Line 542 | Line 685 | bool SysIsDiskInserted(void *arg)
685          } else if (fh->is_floppy) {
686                  char block[512];
687                  lseek(fh->fd, 0, SEEK_SET);
688 <                return read(fh->fd, block, 512) == 512;
688 >                ssize_t actual = read(fh->fd, block, 512);
689 >                if (actual < 0) {
690 >                        close(fh->fd);  // Close and reopen so the driver will see the media change
691 >                        fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR);
692 >                        actual = read(fh->fd, block, 512);
693 >                }
694 >                return actual == 512;
695          } else if (fh->is_cdrom) {
696 + #ifdef CDROM_MEDIA_CHANGED
697 +                if (fh->cdrom_cap & CDC_MEDIA_CHANGED) {
698 +                        // If we don't do this, all attempts to read from a disc fail
699 +                        // once the tray has been opened (altough the TOC reads fine).
700 +                        // Can somebody explain this to me?
701 +                        if (ioctl(fh->fd, CDROM_MEDIA_CHANGED) == 1) {
702 +                                close(fh->fd);
703 +                                fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
704 +                        }
705 +                }
706 + #endif
707   #ifdef CDROM_DRIVE_STATUS
708                  if (fh->cdrom_cap & CDC_DRIVE_STATUS) {
709                          return ioctl(fh->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
# Line 655 | Line 815 | bool SysCDReadTOC(void *arg, uint8 *toc)
815                  *toc++ = toc_size >> 8;
816                  *toc++ = toc_size & 0xff;
817                  return true;
818 < #elif defined(__FreeBSD__) || defined(__NetBSD__)
818 > #elif defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_2)
819 >                extern  bool    DarwinCDReadTOC(char *name, uint8 *toc);
820 >
821 >                return  DarwinCDReadTOC(fh->name, toc);
822 > #elif defined(__FreeBSD__)
823                  uint8 *p = toc + 2;
824  
825                  // Header
# Line 701 | Line 865 | bool SysCDReadTOC(void *arg, uint8 *toc)
865                  *toc++ = toc_size >> 8;
866                  *toc++ = toc_size & 0xff;
867                  return true;
868 + #elif defined(__NetBSD__)
869 +                uint8 *p = toc + 2;
870 +
871 +                // Header
872 +                struct ioc_toc_header header;
873 +                if (ioctl(fh->fd, CDIOREADTOCHEADER, &header) < 0)
874 +                        return false;
875 +                *p++ = header.starting_track;
876 +                *p++ = header.ending_track;
877 +
878 +                // Tracks (this is nice... :-)
879 +                struct ioc_read_toc_entry entries;
880 +                entries.address_format = CD_MSF_FORMAT;
881 +                entries.starting_track = 1;
882 +                entries.data_len = 800;
883 +                entries.data = (cd_toc_entry *)p;
884 +                if (ioctl(fh->fd, CDIOREADTOCENTRIES, &entries) < 0)
885 +                        return false;
886 +
887 +                // TOC size
888 +                int toc_size = p - toc;
889 +                *toc++ = toc_size >> 8;
890 +                *toc++ = toc_size & 0xff;
891 +                return true;
892 + #else
893 +                return false;
894   #endif
895          } else
896                  return false;
# Line 764 | Line 954 | bool SysCDGetPosition(void *arg, uint8 *
954                  *pos++ = chan.data->what.position.reladdr.msf.second;
955                  *pos++ = chan.data->what.position.reladdr.msf.frame;
956                  return true;
957 + #else
958 +                return false;
959   #endif
960          } else
961                  return false;
# Line 799 | Line 991 | bool SysCDPlay(void *arg, uint8 start_m,
991                  play.end_s = end_s;
992                  play.end_f = end_f;
993                  return ioctl(fh->fd, CDIOCPLAYMSF, &play) == 0;
994 + #else
995 +                return false;
996   #endif
997          } else
998                  return false;
# Line 820 | Line 1014 | bool SysCDPause(void *arg)
1014                  return ioctl(fh->fd, CDROMPAUSE) == 0;
1015   #elif defined(__FreeBSD__) || defined(__NetBSD__)
1016                  return ioctl(fh->fd, CDIOCPAUSE) == 0;
1017 + #else
1018 +                return false;
1019   #endif
1020          } else
1021                  return false;
# Line 841 | Line 1037 | bool SysCDResume(void *arg)
1037                  return ioctl(fh->fd, CDROMRESUME) == 0;
1038   #elif defined(__FreeBSD__) || defined(__NetBSD__)
1039                  return ioctl(fh->fd, CDIOCRESUME) == 0;
1040 + #else
1041 +                return false;
1042   #endif
1043          } else
1044                  return false;
# Line 862 | Line 1060 | bool SysCDStop(void *arg, uint8 lead_out
1060                  return ioctl(fh->fd, CDROMSTOP) == 0;
1061   #elif defined(__FreeBSD__) || defined(__NetBSD__)
1062                  return ioctl(fh->fd, CDIOCSTOP) == 0;
1063 + #else
1064 +                return false;
1065   #endif
1066          } else
1067                  return false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines