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.6 by cebix, 2000-07-14T21:29:07Z vs.
Revision 1.23 by asvitkine, 2008-06-28T18:36:18Z

# Line 1 | Line 1
1   /*
2   *  cdrom.cpp - CD-ROM driver
3   *
4 < *  Basilisk II (C) 1997-2000 Christian Bauer
4 > *  Basilisk II (C) 1997-2008 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 28 | Line 28
28   *    Technote FL 36: "Apple Extensions to ISO 9660"
29   */
30  
31 + #include "sysdeps.h"
32 +
33   #include <string.h>
34 + #include <vector>
35 +
36 + #ifndef NO_STD_NAMESPACE
37 + using std::vector;
38 + #endif
39  
33 #include "sysdeps.h"
40   #include "cpu_emulation.h"
41   #include "main.h"
42   #include "macos_util.h"
# Line 97 | Line 103 | static const uint8 bin2bcd[256] = {
103   };
104  
105   static const uint8 bcd2bin[256] = {
106 <        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106 >         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107          10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108          20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109          30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
# Line 117 | Line 123 | static const uint8 bcd2bin[256] = {
123  
124  
125   // Struct for each drive
126 < struct DriveInfo {
127 <        DriveInfo()
128 <        {
129 <                next = NULL;
130 <                num = 0;
125 <                fh = NULL;
126 <                start_byte = 0;
127 <                status = 0;
128 <        }
126 > struct cdrom_drive_info {
127 >        cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {}
128 >        cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {}
129 >
130 >        void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); }
131  
130        DriveInfo *next;        // Pointer to next DriveInfo (must be first in struct!)
132          int num;                        // Drive number
133          void *fh;                       // File handle
134          int block_size;         // CD-ROM block size
135          int twok_offset;        // Offset of beginning of 2K block to last Prime position
136 <        uint32 start_byte;      // Start of HFS partition on disk
136 >        loff_t start_byte;      // Start of HFS partition on disk
137          bool to_be_mounted;     // Flag: drive must be mounted in accRun
138          bool mount_non_hfs;     // Flag: Issue disk-inserted events for non-HFS disks
139  
# Line 145 | Line 146 | struct DriveInfo {
146          uint32 status;          // Mac address of drive status record
147   };
148  
149 < // Linked list of DriveInfos
150 < static DriveInfo *first_drive_info;
149 > // List of drives handled by this driver
150 > typedef vector<cdrom_drive_info> drive_vec;
151 > static drive_vec drives;
152  
153   // Icon address (Mac address space, set by PatchROM())
154   uint32 CDROMIconAddr;
# Line 156 | Line 158 | static bool acc_run_called = false;
158  
159  
160   /*
161 < *  Get pointer to drive info, NULL = invalid drive number
161 > *  Get pointer to drive info or drives.end() if not found
162   */
163  
164 < static DriveInfo *get_drive_info(int num)
164 > static drive_vec::iterator get_drive_info(int num)
165   {
166 <        DriveInfo *info = first_drive_info;
167 <        while (info != NULL) {
166 >        drive_vec::iterator info, end = drives.end();
167 >        for (info = drives.begin(); info != end; ++info) {
168                  if (info->num == num)
169                          return info;
168                info = info->next;
170          }
171 <        return NULL;
171 >        return info;
172   }
173  
174  
# Line 175 | Line 176 | static DriveInfo *get_drive_info(int num
176   *  Find HFS partition, set info->start_byte (0 = no HFS partition)
177   */
178  
179 < static void find_hfs_partition(DriveInfo *info)
179 > static void find_hfs_partition(cdrom_drive_info &info)
180   {
181 <        info->start_byte = 0;
181 >        info.start_byte = 0;
182          uint8 *map = new uint8[512];
183 +        D(bug("Looking for HFS partitions on CD-ROM...\n"));
184  
185          // Search first 64 blocks for HFS partition
186          for (int i=0; i<64; i++) {
187 <                if (Sys_read(info->fh, map, i * 512, 512) != 512)
187 >                if (Sys_read(info.fh, map, i * 512, 512) != 512)
188                          break;
189 +                D(bug(" block %d, signature '%c%c' (%02x%02x)\n", i, map[0], map[1], map[0], map[1]));
190  
191 <                // Skip driver descriptor
192 <                uint16 sig = ntohs(((uint16 *)map)[0]);
193 <                if (sig == 'ER')
191 <                        continue;
192 <
193 <                // No partition map? Then look at next block
194 <                if (sig != 'PM')
191 >                // Not a partition map block? Then look at next block
192 >                uint16 sig = (map[0] << 8) | map[1];
193 >                if (sig != 0x504d)
194                          continue;
195  
196 <                // Partition map found, Apple HFS partition?
196 >                // Partition map block found, Apple HFS partition?
197                  if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
198 <                        info->start_byte = ntohl(((uint32 *)map)[2]) << 9;
199 <                        D(bug(" HFS partition found at %ld, %ld blocks\n", info->start_byte, ntohl(((uint32 *)map)[3])));
198 >                        info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9;
199 >                        uint32 num_blocks = (map[12] << 24) | (map[13] << 16) | (map[14] << 8) | map[15];
200 >                        D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, num_blocks));
201                          break;
202                  }
203          }
# Line 209 | Line 209 | static void find_hfs_partition(DriveInfo
209   *  Read TOC of disk and set lead_out
210   */
211  
212 < static void read_toc(DriveInfo *info)
212 > static void read_toc(cdrom_drive_info &info)
213   {
214          // Read TOC
215 <        memset(&info->toc, 0, sizeof(info->toc));
216 <        SysCDReadTOC(info->fh, info->toc);
217 <        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info->toc)[0]), ntohl(((uint32 *)info->toc)[1])));
215 >        memset(info.toc, 0, sizeof(info.toc));
216 >        SysCDReadTOC(info.fh, info.toc);
217 >
218 > #if DEBUG
219 >        // Dump TOC for debugging
220 >        D(bug(" TOC:\n  %02x%02x%02x%02x        : %d bytes, first track = %d, last track = %d\n", info.toc[0], info.toc[1], info.toc[2], info.toc[3], (info.toc[0] << 8) | info.toc[1], info.toc[2], info.toc[3]));
221 >        for (int i=4; i<804; i+=8) {
222 >                D(bug("  %02x%02x%02x%02x%02x%02x%02x%02x: ", info.toc[i+0], info.toc[i+1], info.toc[i+2], info.toc[i+3], info.toc[i+4], info.toc[i+5], info.toc[i+6], info.toc[i+7]));
223 >                const char *type = (info.toc[i+2] == 0xaa ? "lead-out" : (info.toc[i+1] & 0x04 ? "data" : "audio"));
224 >                D(bug("track %d (%s), addr/ctrl 0x%02x, M %d S %d F %d\n", info.toc[i+2], type, info.toc[i+1], info.toc[i+5], info.toc[i+6], info.toc[i+7]));
225 >                if (info.toc[i+2] == 0xaa)
226 >                        break;
227 >        }
228 > #endif
229  
230          // Find lead-out track
231 <        info->lead_out[0] = 0;
232 <        info->lead_out[1] = 0;
233 <        info->lead_out[2] = 0;
231 >        info.lead_out[0] = 0;
232 >        info.lead_out[1] = 0;
233 >        info.lead_out[2] = 0;
234          for (int i=4; i<804; i+=8) {
235 <                if (info->toc[i+2] == 0xaa) {
236 <                        info->stop_at[0] = info->lead_out[0] = info->toc[i+5];
237 <                        info->stop_at[1] = info->lead_out[1] = info->toc[i+6];
238 <                        info->stop_at[2] = info->lead_out[2] = info->toc[i+7];
235 >                if (info.toc[i+2] == 0xaa) {
236 >                        info.stop_at[0] = info.lead_out[0] = info.toc[i+5];
237 >                        info.stop_at[1] = info.lead_out[1] = info.toc[i+6];
238 >                        info.stop_at[2] = info.lead_out[2] = info.toc[i+7];
239                          break;
240                  }
241          }
242 <        D(bug(" Lead-Out M %d S %d F %d\n", info->lead_out[0], info->lead_out[1], info->lead_out[2]));
242 >        D(bug(" Lead-Out M %d S %d F %d\n", info.lead_out[0], info.lead_out[1], info.lead_out[2]));
243   }
244  
245  
# Line 237 | Line 248 | static void read_toc(DriveInfo *info)
248   *  Return: false = error
249   */
250  
251 < static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
251 > static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
252   {
253          switch (postype) {
254                  case 0:
# Line 255 | Line 266 | static bool position2msf(DriveInfo *info
266                          if (stopping)
267                                  track++;
268                          for (int i=4; i<804; i+=8) {
269 <                                if (info->toc[i+2] == track || info->toc[i+2] == 0xaa) {
270 <                                        m = info->toc[i+5];
271 <                                        s = info->toc[i+6];
272 <                                        f = info->toc[i+7];
269 >                                if (info.toc[i+2] == track || info.toc[i+2] == 0xaa) {
270 >                                        m = info.toc[i+5];
271 >                                        s = info.toc[i+6];
272 >                                        f = info.toc[i+7];
273                                          return true;
274                                  }
275                          }
# Line 276 | Line 287 | static bool position2msf(DriveInfo *info
287  
288   void CDROMInit(void)
289   {
279        first_drive_info = NULL;
280
290          // No drives specified in prefs? Then add defaults
291          if (PrefsFindString("cdrom", 0) == NULL)
292                  SysAddCDROMPrefs();
293  
294          // Add drives specified in preferences
295 <        int32 index = 0;
295 >        int index = 0;
296          const char *str;
297          while ((str = PrefsFindString("cdrom", index++)) != NULL) {
298                  void *fh = Sys_open(str, true);
299 <                if (fh) {
300 <                        DriveInfo *info = new DriveInfo;
292 <                        info->fh = fh;
293 <                        DriveInfo *p = (DriveInfo *)&first_drive_info;
294 <                        while (p->next != NULL)
295 <                                p = p->next;
296 <                        p->next = info;
297 <                }
299 >                if (fh)
300 >                        drives.push_back(cdrom_drive_info(fh));
301          }
302   }
303  
# Line 305 | Line 308 | void CDROMInit(void)
308  
309   void CDROMExit(void)
310   {
311 <        DriveInfo *info = first_drive_info, *next;
312 <        while (info != NULL) {
313 <                SysAllowRemoval(info->fh);
314 <                Sys_close(info->fh);
312 <                next = info->next;
313 <                delete info;
314 <                info = next;
315 <        }
311 >        drive_vec::iterator info, end = drives.end();
312 >        for (info = drives.begin(); info != end; ++info)
313 >                info->close_fh();
314 >        drives.clear();
315   }
316  
317  
# Line 322 | Line 321 | void CDROMExit(void)
321  
322   bool CDROMMountVolume(void *fh)
323   {
324 <        DriveInfo *info;
325 <        for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ;
326 <        if (info) {
324 >        drive_vec::iterator info = drives.begin(), end = drives.end();
325 >        while (info != end && info->fh != fh)
326 >                ++info;
327 >        if (info != end) {
328                  if (SysIsDiskInserted(info->fh)) {
329                          SysPreventRemoval(info->fh);
330                          WriteMacInt8(info->status + dsDiskInPlace, 1);
331 <                        read_toc(info);
332 <                        find_hfs_partition(info);
331 >                        read_toc(*info);
332 >                        find_hfs_partition(*info);
333                          if (info->start_byte != 0 || info->mount_non_hfs)
334                                  info->to_be_mounted = true;
335                  }
# Line 346 | Line 346 | bool CDROMMountVolume(void *fh)
346  
347   static void mount_mountable_volumes(void)
348   {
349 <        DriveInfo *info = first_drive_info;
350 <        while (info != NULL) {
349 >        drive_vec::iterator info, end = drives.end();
350 >        for (info = drives.begin(); info != end; ++info) {
351  
352                  // Disk in drive?
353                  if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
# Line 366 | Line 366 | static void mount_mountable_volumes(void
366                          Execute68kTrap(0xa02f, &r);             // PostEvent()
367                          info->to_be_mounted = false;
368                  }
369
370                info = info->next;
369          }
370   }
371  
# Line 385 | Line 383 | int16 CDROMOpen(uint32 pb, uint32 dce)
383          acc_run_called = false;
384  
385          // Install drives
386 <        for (DriveInfo *info = first_drive_info; info; info = info->next) {
386 >        drive_vec::iterator info, end = drives.end();
387 >        for (info = drives.begin(); info != end; ++info) {
388  
389                  info->num = FindFreeDriveNumber(1);
390                  info->to_be_mounted = false;
# Line 415 | Line 414 | int16 CDROMOpen(uint32 pb, uint32 dce)
414                          if (SysIsDiskInserted(info->fh)) {
415                                  SysPreventRemoval(info->fh);
416                                  WriteMacInt8(info->status + dsDiskInPlace, 1);
417 <                                read_toc(info);
418 <                                find_hfs_partition(info);
417 >                                read_toc(*info);
418 >                                find_hfs_partition(*info);
419                                  info->to_be_mounted = true;
420                          }
421  
# Line 440 | Line 439 | int16 CDROMPrime(uint32 pb, uint32 dce)
439          WriteMacInt32(pb + ioActCount, 0);
440  
441          // Drive valid and disk inserted?
442 <        DriveInfo *info;
443 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
442 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
443 >        if (info == drives.end())
444                  return nsDrvErr;
445          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
446                  return offLinErr;
# Line 507 | Line 506 | int16 CDROMControl(uint32 pb, uint32 dce
506          }
507  
508          // Drive valid?
509 <        DriveInfo *info;
510 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
511 <                if (first_drive_info == NULL)
509 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
510 >        if (info == drives.end()) {
511 >                if (drives.empty())
512                          return nsDrvErr;
513                  else
514 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
514 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
515 >        }
516  
517          // Drive-specific codes
518          switch (code) {
# Line 539 | Line 539 | int16 CDROMControl(uint32 pb, uint32 dce
539                          WriteMacInt32(pb + csParam, CDROMIconAddr);
540                          return noErr;
541  
542 <                case 23:                // DriveInfo
542 >                case 23:                // drive_info
543                          WriteMacInt32(pb + csParam, 0x00000b01);        // Unspecified external removable SCSI disk
544                          return noErr;
545  
# Line 674 | Line 674 | int16 CDROMControl(uint32 pb, uint32 dce
674                          return controlErr;
675  
676                  case 103: {             // AudioTrackSearch
677 <                        D(bug(" AudioTrackSearch postype %d, pos %08lx, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
677 >                        D(bug(" AudioTrackSearch postype %d, pos %08x, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
678                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
679                                  return offLinErr;
680  
681                          uint8 start_m, start_s, start_f;
682 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
682 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
683                                  return paramErr;
684                          info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
685                          if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
# Line 696 | Line 696 | int16 CDROMControl(uint32 pb, uint32 dce
696  
697                          if (ReadMacInt16(pb + csParam + 6)) {
698                                  // Given stopping address
699 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
699 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
700                                          return paramErr;
701                          } else {
702                                  // Given starting address
703                                  uint8 start_m, start_s, start_f;
704 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
704 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
705                                          return paramErr;
706                                  info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
707                                  if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
# Line 738 | Line 738 | int16 CDROMControl(uint32 pb, uint32 dce
738                                          return paramErr;
739                          } else {
740                                  // Given stopping address
741 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
741 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
742                                          return paramErr;
743                          }
744                          return noErr;
# Line 783 | Line 783 | int16 CDROMControl(uint32 pb, uint32 dce
783                                  return offLinErr;
784  
785                          uint8 start_m, start_s, start_f;
786 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
786 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
787                                  return paramErr;
788  
789                          if (!SysCDScan(info->fh, start_m, start_s, start_f, ReadMacInt16(pb + csParam + 6)))
# Line 861 | Line 861 | int16 CDROMControl(uint32 pb, uint32 dce
861  
862   int16 CDROMStatus(uint32 pb, uint32 dce)
863   {
864 <        DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
864 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
865          uint16 code = ReadMacInt16(pb + csCode);
866          D(bug("CDROMStatus %d\n", code));
867  
868 <        // General codes
868 >        // General codes (we can get these even if the drive was invalid)
869          switch (code) {
870                  case 43: {      // DriverGestalt
871                          uint32 sel = ReadMacInt32(pb + csParam);
872                          D(bug(" driver gestalt %c%c%c%c\n", sel >> 24, sel >> 16,  sel >> 8, sel));
873                          switch (sel) {
874 <                                case 'vers':    // Version
874 >                                case FOURCC('v','e','r','s'):   // Version
875                                          WriteMacInt32(pb + csParam + 4, 0x05208000);
876                                          break;
877 <                                case 'devt':    // Device type
878 <                                        WriteMacInt32(pb + csParam + 4, 'cdrm');
877 >                                case FOURCC('d','e','v','t'):   // Device type
878 >                                        WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m'));
879                                          break;
880 <                                case 'intf':    // Interface type
881 <                                        WriteMacInt32(pb + csParam + 4, 'basi');
880 >                                case FOURCC('i','n','t','f'):   // Interface type
881 >                                        WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
882                                          break;
883 <                                case 'sync':    // Only synchronous operation?
883 >                                case FOURCC('s','y','n','c'):   // Only synchronous operation?
884                                          WriteMacInt32(pb + csParam + 4, 0x01000000);
885                                          break;
886 <                                case 'boot':    // Boot ID
887 <                                        if (info != NULL)
886 >                                case FOURCC('b','o','o','t'):   // Boot ID
887 >                                        if (info != drives.end())
888                                                  WriteMacInt16(pb + csParam + 4, info->num);
889                                          else
890                                                  WriteMacInt16(pb + csParam + 4, 0);
891                                          WriteMacInt16(pb + csParam + 6, (uint16)CDROMRefNum);
892                                          break;
893 <                                case 'wide':    // 64-bit access supported?
893 >                                case FOURCC('w','i','d','e'):   // 64-bit access supported?
894                                          WriteMacInt16(pb + csParam + 4, 0);
895                                          break;
896 <                                case 'purg':    // Purge flags
896 >                                case FOURCC('p','u','r','g'):   // Purge flags
897                                          WriteMacInt32(pb + csParam + 4, 0);
898                                          break;
899 <                                case 'ejec':    // Eject flags
899 >                                case FOURCC('e','j','e','c'):   // Eject flags
900                                          WriteMacInt32(pb + csParam + 4, 0x00030003);    // Don't eject on shutdown/restart
901                                          break;
902 <                                case 'flus':    // Flush flags
902 >                                case FOURCC('f','l','u','s'):   // Flush flags
903                                          WriteMacInt16(pb + csParam + 4, 0);
904                                          break;
905 <                                case 'vmop':    // Virtual memory attributes
905 >                                case FOURCC('v','m','o','p'):   // Virtual memory attributes
906                                          WriteMacInt32(pb + csParam + 4, 0);     // Drive not available for VM
907                                          break;
908                                  default:
# Line 910 | Line 910 | int16 CDROMStatus(uint32 pb, uint32 dce)
910                          }
911                          return noErr;
912                  }
913 +
914 +                case 97: {      // WhoIsThere
915 +                        uint8 drives_present = 0;
916 +                        drive_vec::iterator info, end = drives.end();
917 +                        for (info = drives.begin(); info != end; ++info) {
918 +                                if (info->num <= 6)
919 +                                        drives_present |= (1 << info->num);
920 +                        }
921 +                        WriteMacInt8(pb + csParam + 1, drives_present);
922 +                        return noErr;
923 +                }
924          }
925  
926          // Drive valid?
927 <        if (info == NULL)
928 <                if (first_drive_info == NULL)
927 >        if (info == drives.end()) {
928 >                if (drives.empty())
929                          return nsDrvErr;
930                  else
931 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
931 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
932 >        }
933  
934          // Drive-specific codes
935          switch (code) {
936 +                case 6:                 // Return format list
937 +                        if (ReadMacInt16(pb + csParam) > 0) {
938 +                                uint32 adr = ReadMacInt32(pb + csParam + 2);
939 +                                WriteMacInt16(pb + csParam, 1);                                         // 1 format
940 +                                WriteMacInt32(adr, SysGetFileSize(info->fh) / 512);     // Number of blocks
941 +                                WriteMacInt32(adr + 4, 0);                                                      // heads/track/sectors
942 +                                return noErr;
943 +                        } else
944 +                                return paramErr;
945 +
946                  case 8:                 // DriveStatus
947                          Mac2Mac_memcpy(pb + csParam, info->status, 22);
948                          return noErr;
# Line 950 | Line 972 | int16 CDROMStatus(uint32 pb, uint32 dce)
972  
973                  case 121:               // Get CD features
974                          WriteMacInt16(pb + csParam, 0x0200);    // 300 KB/s
975 <                        WriteMacInt16(pb + csParam, 0x0300);    // SCSI-2, stereo
975 >                        WriteMacInt16(pb + csParam + 2, 0x0c00);        // SCSI-2, stereo
976                          return noErr;
977  
978                  default:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines