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

Comparing BasiliskII/src/cdrom.cpp (file contents):
Revision 1.3 by cebix, 1999-10-23T17:57:42Z vs.
Revision 1.14 by cebix, 2001-07-14T20:01:14Z

# Line 1 | Line 1
1   /*
2   *  cdrom.cpp - CD-ROM driver
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 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 29 | Line 29
29   */
30  
31   #include <string.h>
32 + #include <vector>
33 +
34 + #ifndef NO_STD_NAMESPACE
35 + using std::vector;
36 + #endif
37  
38   #include "sysdeps.h"
39   #include "cpu_emulation.h"
# Line 97 | Line 102 | static const uint8 bin2bcd[256] = {
102   };
103  
104   static const uint8 bcd2bin[256] = {
105 <        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
105 >         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106          10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107          20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108          30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
# Line 117 | Line 122 | static const uint8 bcd2bin[256] = {
122  
123  
124   // Struct for each drive
125 < struct DriveInfo {
126 <        DriveInfo()
127 <        {
128 <                next = NULL;
129 <                num = 0;
125 <                fh = NULL;
126 <                start_byte = 0;
127 <                status = 0;
128 <        }
125 > struct cdrom_drive_info {
126 >        cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {}
127 >        cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {}
128 >
129 >        void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); }
130  
130        DriveInfo *next;        // Pointer to next DriveInfo (must be first in struct!)
131          int num;                        // Drive number
132          void *fh;                       // File handle
133          int block_size;         // CD-ROM block size
134          int twok_offset;        // Offset of beginning of 2K block to last Prime position
135 <        uint32 start_byte;      // Start of HFS partition on disk
135 >        loff_t start_byte;      // Start of HFS partition on disk
136          bool to_be_mounted;     // Flag: drive must be mounted in accRun
137          bool mount_non_hfs;     // Flag: Issue disk-inserted events for non-HFS disks
138  
# Line 145 | Line 145 | struct DriveInfo {
145          uint32 status;          // Mac address of drive status record
146   };
147  
148 < // Linked list of DriveInfos
149 < static DriveInfo *first_drive_info;
148 > // List of drives handled by this driver
149 > typedef vector<cdrom_drive_info> drive_vec;
150 > static drive_vec drives;
151  
152   // Icon address (Mac address space, set by PatchROM())
153   uint32 CDROMIconAddr;
154  
154 // Number of ticks between checks for disk insertion
155 const int driver_delay = 120;
156
155   // Flag: Control(accRun) has been called, interrupt routine is now active
156   static bool acc_run_called = false;
157  
158  
159   /*
160 < *  Get pointer to drive info, NULL = invalid drive number
160 > *  Get pointer to drive info or drives.end() if not found
161   */
162  
163 < static DriveInfo *get_drive_info(int num)
163 > static drive_vec::iterator get_drive_info(int num)
164   {
165 <        DriveInfo *info = first_drive_info;
166 <        while (info != NULL) {
165 >        drive_vec::iterator info, end = drives.end();
166 >        for (info = drives.begin(); info != end; ++info) {
167                  if (info->num == num)
168                          return info;
171                info = info->next;
169          }
170 <        return NULL;
170 >        return info;
171   }
172  
173  
# Line 178 | Line 175 | static DriveInfo *get_drive_info(int num
175   *  Find HFS partition, set info->start_byte (0 = no HFS partition)
176   */
177  
178 < static void find_hfs_partition(DriveInfo *info)
178 > static void find_hfs_partition(cdrom_drive_info &info)
179   {
180 <        info->start_byte = 0;
180 >        info.start_byte = 0;
181          uint8 *map = new uint8[512];
182  
183          // Search first 64 blocks for HFS partition
184          for (int i=0; i<64; i++) {
185 <                if (Sys_read(info->fh, map, i * 512, 512) != 512)
185 >                if (Sys_read(info.fh, map, i * 512, 512) != 512)
186                          break;
187  
188 <                // Skip driver descriptor
189 <                uint16 sig = ntohs(((uint16 *)map)[0]);
190 <                if (sig == 'ER')
188 >                // Not a partition map block? Then look at next block
189 >                uint16 sig = (map[0] << 8) | map[1];
190 >                if (sig != 0x504d)
191                          continue;
192  
193 <                // No partition map? Then look at next block
197 <                if (sig != 'PM')
198 <                        continue;
199 <
200 <                // Partition map found, Apple HFS partition?
193 >                // Partition map block found, Apple HFS partition?
194                  if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
195 <                        info->start_byte = ntohl(((uint32 *)map)[2]) << 9;
196 <                        D(bug(" HFS partition found at %ld, %ld blocks\n", info->start_byte, ntohl(((uint32 *)map)[3])));
195 >                        info.start_byte = ntohl(((uint32 *)map)[2]) << 9;
196 >                        D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, ntohl(((uint32 *)map)[3])));
197                          break;
198                  }
199          }
# Line 212 | Line 205 | static void find_hfs_partition(DriveInfo
205   *  Read TOC of disk and set lead_out
206   */
207  
208 < static void read_toc(DriveInfo *info)
208 > static void read_toc(cdrom_drive_info &info)
209   {
210          // Read TOC
211 <        memset(&info->toc, 0, sizeof(info->toc));
212 <        SysCDReadTOC(info->fh, info->toc);
213 <        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info->toc)[0]), ntohl(((uint32 *)info->toc)[1])));
211 >        memset(info.toc, 0, sizeof(info.toc));
212 >        SysCDReadTOC(info.fh, info.toc);
213 >        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info.toc)[0]), ntohl(((uint32 *)info.toc)[1])));
214  
215          // Find lead-out track
216 <        info->lead_out[0] = 0;
217 <        info->lead_out[1] = 0;
218 <        info->lead_out[2] = 0;
216 >        info.lead_out[0] = 0;
217 >        info.lead_out[1] = 0;
218 >        info.lead_out[2] = 0;
219          for (int i=4; i<804; i+=8) {
220 <                if (info->toc[i+2] == 0xaa) {
221 <                        info->stop_at[0] = info->lead_out[0] = info->toc[i+5];
222 <                        info->stop_at[1] = info->lead_out[1] = info->toc[i+6];
223 <                        info->stop_at[2] = info->lead_out[2] = info->toc[i+7];
220 >                if (info.toc[i+2] == 0xaa) {
221 >                        info.stop_at[0] = info.lead_out[0] = info.toc[i+5];
222 >                        info.stop_at[1] = info.lead_out[1] = info.toc[i+6];
223 >                        info.stop_at[2] = info.lead_out[2] = info.toc[i+7];
224                          break;
225                  }
226          }
227 <        D(bug(" Lead-Out M %d S %d F %d\n", info->lead_out[0], info->lead_out[1], info->lead_out[2]));
227 >        D(bug(" Lead-Out M %d S %d F %d\n", info.lead_out[0], info.lead_out[1], info.lead_out[2]));
228   }
229  
230  
# Line 240 | Line 233 | static void read_toc(DriveInfo *info)
233   *  Return: false = error
234   */
235  
236 < static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
236 > static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
237   {
238          switch (postype) {
239                  case 0:
# Line 258 | Line 251 | static bool position2msf(DriveInfo *info
251                          if (stopping)
252                                  track++;
253                          for (int i=4; i<804; i+=8) {
254 <                                if (info->toc[i+2] == track || info->toc[i+2] == 0xaa) {
255 <                                        m = info->toc[i+5];
256 <                                        s = info->toc[i+6];
257 <                                        f = info->toc[i+7];
254 >                                if (info.toc[i+2] == track || info.toc[i+2] == 0xaa) {
255 >                                        m = info.toc[i+5];
256 >                                        s = info.toc[i+6];
257 >                                        f = info.toc[i+7];
258                                          return true;
259                                  }
260                          }
# Line 279 | Line 272 | static bool position2msf(DriveInfo *info
272  
273   void CDROMInit(void)
274   {
282        first_drive_info = NULL;
283
275          // No drives specified in prefs? Then add defaults
276          if (PrefsFindString("cdrom", 0) == NULL)
277                  SysAddCDROMPrefs();
278  
279          // Add drives specified in preferences
280 <        int32 index = 0;
280 >        int index = 0;
281          const char *str;
282          while ((str = PrefsFindString("cdrom", index++)) != NULL) {
283                  void *fh = Sys_open(str, true);
284 <                if (fh) {
285 <                        DriveInfo *info = new DriveInfo;
295 <                        info->fh = fh;
296 <                        DriveInfo *p = (DriveInfo *)&first_drive_info;
297 <                        while (p->next != NULL)
298 <                                p = p->next;
299 <                        p->next = info;
300 <                }
284 >                if (fh)
285 >                        drives.push_back(cdrom_drive_info(fh));
286          }
287   }
288  
# Line 308 | Line 293 | void CDROMInit(void)
293  
294   void CDROMExit(void)
295   {
296 <        DriveInfo *info = first_drive_info, *next;
297 <        while (info != NULL) {
298 <                SysAllowRemoval(info->fh);
299 <                Sys_close(info->fh);
315 <                next = info->next;
316 <                delete info;
317 <                info = next;
318 <        }
296 >        drive_vec::iterator info, end = drives.end();
297 >        for (info = drives.begin(); info != end; ++info)
298 >                info->close_fh();
299 >        drives.clear();
300   }
301  
302  
# Line 325 | Line 306 | void CDROMExit(void)
306  
307   bool CDROMMountVolume(void *fh)
308   {
309 <        DriveInfo *info;
310 <        for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ;
311 <        if (info) {
309 >        drive_vec::iterator info = drives.begin(), end = drives.end();
310 >        while (info != end && info->fh != fh)
311 >                ++info;
312 >        if (info != end) {
313                  if (SysIsDiskInserted(info->fh)) {
314                          SysPreventRemoval(info->fh);
315                          WriteMacInt8(info->status + dsDiskInPlace, 1);
316 <                        read_toc(info);
317 <                        find_hfs_partition(info);
316 >                        read_toc(*info);
317 >                        find_hfs_partition(*info);
318                          if (info->start_byte != 0 || info->mount_non_hfs)
319                                  info->to_be_mounted = true;
320                  }
# Line 349 | Line 331 | bool CDROMMountVolume(void *fh)
331  
332   static void mount_mountable_volumes(void)
333   {
334 <        DriveInfo *info = first_drive_info;
335 <        while (info != NULL) {
334 >        drive_vec::iterator info, end = drives.end();
335 >        for (info = drives.begin(); info != end; ++info) {
336  
337                  // Disk in drive?
338                  if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
# Line 369 | Line 351 | static void mount_mountable_volumes(void
351                          Execute68kTrap(0xa02f, &r);             // PostEvent()
352                          info->to_be_mounted = false;
353                  }
372
373                info = info->next;
354          }
355   }
356  
# Line 388 | Line 368 | int16 CDROMOpen(uint32 pb, uint32 dce)
368          acc_run_called = false;
369  
370          // Install drives
371 <        for (DriveInfo *info = first_drive_info; info; info = info->next) {
371 >        drive_vec::iterator info, end = drives.end();
372 >        for (info = drives.begin(); info != end; ++info) {
373  
374                  info->num = FindFreeDriveNumber(1);
375                  info->to_be_mounted = false;
# Line 418 | Line 399 | int16 CDROMOpen(uint32 pb, uint32 dce)
399                          if (SysIsDiskInserted(info->fh)) {
400                                  SysPreventRemoval(info->fh);
401                                  WriteMacInt8(info->status + dsDiskInPlace, 1);
402 <                                read_toc(info);
403 <                                find_hfs_partition(info);
402 >                                read_toc(*info);
403 >                                find_hfs_partition(*info);
404                                  info->to_be_mounted = true;
405                          }
406  
# Line 443 | Line 424 | int16 CDROMPrime(uint32 pb, uint32 dce)
424          WriteMacInt32(pb + ioActCount, 0);
425  
426          // Drive valid and disk inserted?
427 <        DriveInfo *info;
428 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
427 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
428 >        if (info == drives.end())
429                  return nsDrvErr;
430          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
431                  return offLinErr;
# Line 510 | Line 491 | int16 CDROMControl(uint32 pb, uint32 dce
491          }
492  
493          // Drive valid?
494 <        DriveInfo *info;
495 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
496 <                if (first_drive_info == NULL)
494 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
495 >        if (info == drives.end()) {
496 >                if (drives.empty())
497                          return nsDrvErr;
498                  else
499 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
499 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
500 >        }
501  
502          // Drive-specific codes
503          switch (code) {
# Line 542 | Line 524 | int16 CDROMControl(uint32 pb, uint32 dce
524                          WriteMacInt32(pb + csParam, CDROMIconAddr);
525                          return noErr;
526  
527 <                case 23:                // DriveInfo
527 >                case 23:                // drive_info
528                          WriteMacInt32(pb + csParam, 0x00000b01);        // Unspecified external removable SCSI disk
529                          return noErr;
530  
# Line 602 | Line 584 | int16 CDROMControl(uint32 pb, uint32 dce
584                                          break;
585  
586                                  case 3: {               // Get track starting address
587 <                                        uint8 *buf = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
587 >                                        uint32 buf = ReadMacInt32(pb + csParam + 2);
588                                          uint16 buf_size = ReadMacInt16(pb + csParam + 6);
589                                          int track = bcd2bin[ReadMacInt8(pb + csParam + 8)];
590  
# Line 616 | Line 598 | int16 CDROMControl(uint32 pb, uint32 dce
598                                          // Fill buffer
599                                          if (i != 804)
600                                                  while (buf_size > 0) {
601 <                                                        *buf++ = info->toc[i+1] & 0x0f;         // Control
602 <                                                        *buf++ = bin2bcd[info->toc[i+5]];       // M
603 <                                                        *buf++ = bin2bcd[info->toc[i+6]];       // S
604 <                                                        *buf++ = bin2bcd[info->toc[i+7]];       // F
601 >                                                        WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++;        // Control
602 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++;      // M
603 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++;      // S
604 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++;      // F
605  
606                                                          // Lead-Out? Then stop
607                                                          if (info->toc[i+2] == 0xaa)
# Line 650 | Line 632 | int16 CDROMControl(uint32 pb, uint32 dce
632  
633                  case 101: {             // ReadTheQSubcode
634                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
635 <                                memset(Mac2HostAddr(pb + csParam), 0, 10);
635 >                                Mac_memset(pb + csParam, 0, 10);
636                                  return offLinErr;
637                          }
638  
639                          uint8 pos[16];
640                          if (SysCDGetPosition(info->fh, pos)) {
641 <                                uint8 *p = Mac2HostAddr(pb + csParam);
642 <                                *p++ = pos[5] & 0x0f;           // Control
643 <                                *p++ = bin2bcd[pos[6]];         // Track number
644 <                                *p++ = bin2bcd[pos[7]];         // Index number
645 <                                *p++ = bin2bcd[pos[13]];        // M (rel)
646 <                                *p++ = bin2bcd[pos[14]];        // S (rel)
647 <                                *p++ = bin2bcd[pos[15]];        // F (rel)
648 <                                *p++ = bin2bcd[pos[9]];         // M (abs)
649 <                                *p++ = bin2bcd[pos[10]];        // S (abs)
650 <                                *p++ = bin2bcd[pos[11]];        // F (abs)
651 <                                *p++ = 0;
641 >                                uint32 p = pb + csParam;
642 >                                WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
643 >                                WriteMacInt8(p, bin2bcd[pos[6]]); p++;  // Track number
644 >                                WriteMacInt8(p, bin2bcd[pos[7]]); p++;  // Index number
645 >                                WriteMacInt8(p, bin2bcd[pos[13]]); p++; // M (rel)
646 >                                WriteMacInt8(p, bin2bcd[pos[14]]); p++; // S (rel)
647 >                                WriteMacInt8(p, bin2bcd[pos[15]]); p++; // F (rel)
648 >                                WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
649 >                                WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
650 >                                WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
651 >                                WriteMacInt8(p, 0);
652                                  return noErr;
653                          } else
654                                  return ioErr;
# Line 677 | Line 659 | int16 CDROMControl(uint32 pb, uint32 dce
659                          return controlErr;
660  
661                  case 103: {             // AudioTrackSearch
662 <                        D(bug(" AudioTrackSearch postype %d, pos %08lx, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
662 >                        D(bug(" AudioTrackSearch postype %d, pos %08x, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
663                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
664                                  return offLinErr;
665  
666                          uint8 start_m, start_s, start_f;
667 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
667 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
668                                  return paramErr;
669                          info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
670                          if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
# Line 699 | Line 681 | int16 CDROMControl(uint32 pb, uint32 dce
681  
682                          if (ReadMacInt16(pb + csParam + 6)) {
683                                  // Given stopping address
684 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
684 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
685                                          return paramErr;
686                          } else {
687                                  // Given starting address
688                                  uint8 start_m, start_s, start_f;
689 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
689 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
690                                          return paramErr;
691                                  info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
692                                  if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
# Line 741 | Line 723 | int16 CDROMControl(uint32 pb, uint32 dce
723                                          return paramErr;
724                          } else {
725                                  // Given stopping address
726 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
726 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
727                                          return paramErr;
728                          }
729                          return noErr;
# Line 754 | Line 736 | int16 CDROMControl(uint32 pb, uint32 dce
736                          if (!SysCDGetPosition(info->fh, pos))
737                                  return paramErr;
738  
739 <                        uint8 *p = Mac2HostAddr(pb + csParam);
739 >                        uint32 p = pb + csParam;
740                          switch (pos[1]) {
741                                  case 0x11:
742 <                                        *p++ = 0;       // Audio play in progress
742 >                                        WriteMacInt8(p, 0);     // Audio play in progress
743                                          break;
744                                  case 0x12:
745 <                                        *p++ = 1;       // Audio play paused
745 >                                        WriteMacInt8(p, 1);     // Audio play paused
746                                          break;
747                                  case 0x13:
748 <                                        *p++ = 3;       // Audio play completed
748 >                                        WriteMacInt8(p, 3);     // Audio play completed
749                                          break;
750                                  case 0x14:
751 <                                        *p++ = 4;       // Error occurred
751 >                                        WriteMacInt8(p, 4);     // Error occurred
752                                          break;
753                                  default:
754 <                                        *p++ = 5;       // No audio play operation requested
754 >                                        WriteMacInt8(p, 5);     // No audio play operation requested
755                                          break;
756                          }
757 <                        *p++ = info->play_mode;
758 <                        *p++ = pos[5] & 0x0f;           // Control
759 <                        *p++ = bin2bcd[pos[9]];         // M (abs)
760 <                        *p++ = bin2bcd[pos[10]];        // S (abs)
761 <                        *p++ = bin2bcd[pos[11]];        // F (abs)
757 >                        p++;
758 >                        WriteMacInt8(p, info->play_mode); p++;
759 >                        WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
760 >                        WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
761 >                        WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
762 >                        WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
763                          return noErr;
764                  }
765  
# Line 785 | Line 768 | int16 CDROMControl(uint32 pb, uint32 dce
768                                  return offLinErr;
769  
770                          uint8 start_m, start_s, start_f;
771 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
771 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
772                                  return paramErr;
773  
774                          if (!SysCDScan(info->fh, start_m, start_s, start_f, ReadMacInt16(pb + csParam + 6)))
# Line 863 | Line 846 | int16 CDROMControl(uint32 pb, uint32 dce
846  
847   int16 CDROMStatus(uint32 pb, uint32 dce)
848   {
849 <        DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
849 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
850          uint16 code = ReadMacInt16(pb + csCode);
851          D(bug("CDROMStatus %d\n", code));
852  
853 <        // General codes
853 >        // General codes (we can get these even if the drive was invalid)
854          switch (code) {
855                  case 43: {      // DriverGestalt
856                          uint32 sel = ReadMacInt32(pb + csParam);
857                          D(bug(" driver gestalt %c%c%c%c\n", sel >> 24, sel >> 16,  sel >> 8, sel));
858                          switch (sel) {
859 <                                case 'vers':    // Version
859 >                                case FOURCC('v','e','r','s'):   // Version
860                                          WriteMacInt32(pb + csParam + 4, 0x05208000);
861                                          break;
862 <                                case 'devt':    // Device type
863 <                                        WriteMacInt32(pb + csParam + 4, 'cdrm');
862 >                                case FOURCC('d','e','v','t'):   // Device type
863 >                                        WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m'));
864                                          break;
865 <                                case 'intf':    // Interface type
866 <                                        WriteMacInt32(pb + csParam + 4, 'basi');
865 >                                case FOURCC('i','n','t','f'):   // Interface type
866 >                                        WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
867                                          break;
868 <                                case 'sync':    // Only synchronous operation?
868 >                                case FOURCC('s','y','n','c'):   // Only synchronous operation?
869                                          WriteMacInt32(pb + csParam + 4, 0x01000000);
870                                          break;
871 <                                case 'boot':    // Boot ID
872 <                                        if (info != NULL)
871 >                                case FOURCC('b','o','o','t'):   // Boot ID
872 >                                        if (info != drives.end())
873                                                  WriteMacInt16(pb + csParam + 4, info->num);
874                                          else
875                                                  WriteMacInt16(pb + csParam + 4, 0);
876                                          WriteMacInt16(pb + csParam + 6, (uint16)CDROMRefNum);
877                                          break;
878 <                                case 'wide':    // 64-bit access supported?
878 >                                case FOURCC('w','i','d','e'):   // 64-bit access supported?
879                                          WriteMacInt16(pb + csParam + 4, 0);
880                                          break;
881 <                                case 'purg':    // Purge flags
881 >                                case FOURCC('p','u','r','g'):   // Purge flags
882                                          WriteMacInt32(pb + csParam + 4, 0);
883                                          break;
884 <                                case 'ejec':    // Eject flags
884 >                                case FOURCC('e','j','e','c'):   // Eject flags
885                                          WriteMacInt32(pb + csParam + 4, 0x00030003);    // Don't eject on shutdown/restart
886                                          break;
887 <                                case 'flus':    // Flush flags
887 >                                case FOURCC('f','l','u','s'):   // Flush flags
888                                          WriteMacInt16(pb + csParam + 4, 0);
889                                          break;
890 <                                case 'vmop':    // Virtual memory attributes
890 >                                case FOURCC('v','m','o','p'):   // Virtual memory attributes
891                                          WriteMacInt32(pb + csParam + 4, 0);     // Drive not available for VM
892                                          break;
893                                  default:
# Line 915 | Line 898 | int16 CDROMStatus(uint32 pb, uint32 dce)
898          }
899  
900          // Drive valid?
901 <        if (info == NULL)
902 <                if (first_drive_info == NULL)
901 >        if (info == drives.end()) {
902 >                if (drives.empty())
903                          return nsDrvErr;
904                  else
905 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
905 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
906 >        }
907  
908          // Drive-specific codes
909          switch (code) {
910 +                case 6:                 // Return format list
911 +                        if (ReadMacInt16(pb + csParam) > 0) {
912 +                                uint32 adr = ReadMacInt32(pb + csParam + 2);
913 +                                WriteMacInt16(pb + csParam, 1);                                         // 1 format
914 +                                WriteMacInt32(adr, SysGetFileSize(info->fh) / 512);     // Number of blocks
915 +                                WriteMacInt32(adr + 4, 0);                                                      // heads/track/sectors
916 +                                return noErr;
917 +                        } else
918 +                                return paramErr;
919 +
920                  case 8:                 // DriveStatus
921 <                        memcpy(Mac2HostAddr(pb + csParam), Mac2HostAddr(info->status), 22);
921 >                        Mac2Mac_memcpy(pb + csParam, info->status, 22);
922                          return noErr;
923  
924                  case 70:                // GetPowerMode
# Line 963 | Line 957 | int16 CDROMStatus(uint32 pb, uint32 dce)
957  
958  
959   /*
960 < *  Driver interrupt routine - check for volumes to be mounted
960 > *  Driver interrupt routine (1Hz) - check for volumes to be mounted
961   */
962  
963   void CDROMInterrupt(void)
964   {
971        static int tick_count = 0;
965          if (!acc_run_called)
966                  return;
967  
968 <        tick_count++;
976 <        if (tick_count > driver_delay) {
977 <                tick_count = 0;
978 <                mount_mountable_volumes();
979 <        }
968 >        mount_mountable_volumes();
969   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines