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.1.1.1 by cebix, 1999-10-03T14:16:25Z 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-1999 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;
155  
156 + // Flag: Control(accRun) has been called, interrupt routine is now active
157 + 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;
165                info = info->next;
170          }
171 <        return NULL;
171 >        return info;
172   }
173  
174  
# Line 172 | 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 >                // 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 <                // No partition map? Then look at next block
191 <                if (sig != 'PM')
192 <                        continue;
193 <
194 <                // 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 206 | 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 234 | 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 252 | 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 273 | Line 287 | static bool position2msf(DriveInfo *info
287  
288   void CDROMInit(void)
289   {
276        first_drive_info = NULL;
277
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;
289 <                        info->fh = fh;
290 <                        DriveInfo *p = (DriveInfo *)&first_drive_info;
291 <                        while (p->next != NULL)
292 <                                p = p->next;
293 <                        p->next = info;
294 <                }
299 >                if (fh)
300 >                        drives.push_back(cdrom_drive_info(fh));
301          }
302   }
303  
# Line 302 | Line 308 | void CDROMInit(void)
308  
309   void CDROMExit(void)
310   {
311 <        DriveInfo *info = first_drive_info, *next;
312 <        while (info != NULL) {
313 <                Sys_close(info->fh);
314 <                next = info->next;
309 <                delete info;
310 <                info = next;
311 <        }
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 318 | 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 336 | Line 340 | bool CDROMMountVolume(void *fh)
340  
341  
342   /*
343 + *  Mount volumes for which the to_be_mounted flag is set
344 + *  (called during interrupt time)
345 + */
346 +
347 + static void mount_mountable_volumes(void)
348 + {
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) {
354 +
355 +                        // No, check if disk was inserted
356 +                        if (SysIsDiskInserted(info->fh))
357 +                                CDROMMountVolume(info->fh);
358 +                }
359 +
360 +                // Mount disk if flagged
361 +                if (info->to_be_mounted) {
362 +                        D(bug(" mounting drive %d\n", info->num));
363 +                        M68kRegisters r;
364 +                        r.d[0] = info->num;
365 +                        r.a[0] = 7;     // diskEvent
366 +                        Execute68kTrap(0xa02f, &r);             // PostEvent()
367 +                        info->to_be_mounted = false;
368 +                }
369 +        }
370 + }
371 +
372 +
373 + /*
374   *  Driver Open() routine
375   */
376  
# Line 345 | Line 380 | int16 CDROMOpen(uint32 pb, uint32 dce)
380  
381          // Set up DCE
382          WriteMacInt32(dce + dCtlPosition, 0);
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 377 | 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 402 | 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 456 | Line 493 | int16 CDROMControl(uint32 pb, uint32 dce
493                  case 1:         // KillIO
494                          return noErr;
495  
496 <                case 65: {      // Periodic action ("insert" disks on startup and check for disk changes)
497 <                        DriveInfo *info = first_drive_info;
498 <                        while (info != NULL) {
499 <
463 <                                // Disk in drive?
464 <                                if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
465 <
466 <                                        // No, check if disk was inserted
467 <                                        if (SysIsDiskInserted(info->fh))
468 <                                                CDROMMountVolume(info->fh);
469 <                                }
470 <
471 <                                // Mount disk if flagged
472 <                                if (info->to_be_mounted) {
473 <                                        D(bug(" mounting drive %d\n", info->num));
474 <                                        M68kRegisters r;
475 <                                        r.d[0] = info->num;
476 <                                        r.a[0] = 7;     // diskEvent
477 <                                        Execute68kTrap(0xa02f, &r);             // PostEvent()
478 <                                        info->to_be_mounted = false;
479 <                                }
480 <
481 <                                info = info->next;
482 <                        }
496 >                case 65: {      // Periodic action (accRun, "insert" disks on startup)
497 >                        mount_mountable_volumes();
498 >                        WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000);        // Disable periodic action
499 >                        acc_run_called = true;
500                          return noErr;
501                  }
502  
# Line 489 | 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 521 | 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 581 | Line 599 | int16 CDROMControl(uint32 pb, uint32 dce
599                                          break;
600  
601                                  case 3: {               // Get track starting address
602 <                                        uint8 *buf = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
602 >                                        uint32 buf = ReadMacInt32(pb + csParam + 2);
603                                          uint16 buf_size = ReadMacInt16(pb + csParam + 6);
604                                          int track = bcd2bin[ReadMacInt8(pb + csParam + 8)];
605  
# Line 595 | Line 613 | int16 CDROMControl(uint32 pb, uint32 dce
613                                          // Fill buffer
614                                          if (i != 804)
615                                                  while (buf_size > 0) {
616 <                                                        *buf++ = info->toc[i+1] & 0x0f;         // Control
617 <                                                        *buf++ = bin2bcd[info->toc[i+5]];       // M
618 <                                                        *buf++ = bin2bcd[info->toc[i+6]];       // S
619 <                                                        *buf++ = bin2bcd[info->toc[i+7]];       // F
616 >                                                        WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++;        // Control
617 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++;      // M
618 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++;      // S
619 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++;      // F
620  
621                                                          // Lead-Out? Then stop
622                                                          if (info->toc[i+2] == 0xaa)
# Line 629 | Line 647 | int16 CDROMControl(uint32 pb, uint32 dce
647  
648                  case 101: {             // ReadTheQSubcode
649                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
650 <                                memset(Mac2HostAddr(pb + csParam), 0, 10);
650 >                                Mac_memset(pb + csParam, 0, 10);
651                                  return offLinErr;
652                          }
653  
654                          uint8 pos[16];
655                          if (SysCDGetPosition(info->fh, pos)) {
656 <                                uint8 *p = Mac2HostAddr(pb + csParam);
657 <                                *p++ = pos[5] & 0x0f;           // Control
658 <                                *p++ = bin2bcd[pos[6]];         // Track number
659 <                                *p++ = bin2bcd[pos[7]];         // Index number
660 <                                *p++ = bin2bcd[pos[13]];        // M (rel)
661 <                                *p++ = bin2bcd[pos[14]];        // S (rel)
662 <                                *p++ = bin2bcd[pos[15]];        // F (rel)
663 <                                *p++ = bin2bcd[pos[9]];         // M (abs)
664 <                                *p++ = bin2bcd[pos[10]];        // S (abs)
665 <                                *p++ = bin2bcd[pos[11]];        // F (abs)
666 <                                *p++ = 0;
656 >                                uint32 p = pb + csParam;
657 >                                WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
658 >                                WriteMacInt8(p, bin2bcd[pos[6]]); p++;  // Track number
659 >                                WriteMacInt8(p, bin2bcd[pos[7]]); p++;  // Index number
660 >                                WriteMacInt8(p, bin2bcd[pos[13]]); p++; // M (rel)
661 >                                WriteMacInt8(p, bin2bcd[pos[14]]); p++; // S (rel)
662 >                                WriteMacInt8(p, bin2bcd[pos[15]]); p++; // F (rel)
663 >                                WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
664 >                                WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
665 >                                WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
666 >                                WriteMacInt8(p, 0);
667                                  return noErr;
668                          } else
669                                  return ioErr;
# Line 656 | 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 678 | 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 720 | 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 733 | Line 751 | int16 CDROMControl(uint32 pb, uint32 dce
751                          if (!SysCDGetPosition(info->fh, pos))
752                                  return paramErr;
753  
754 <                        uint8 *p = Mac2HostAddr(pb + csParam);
754 >                        uint32 p = pb + csParam;
755                          switch (pos[1]) {
756                                  case 0x11:
757 <                                        *p++ = 0;       // Audio play in progress
757 >                                        WriteMacInt8(p, 0);     // Audio play in progress
758                                          break;
759                                  case 0x12:
760 <                                        *p++ = 1;       // Audio play paused
760 >                                        WriteMacInt8(p, 1);     // Audio play paused
761                                          break;
762                                  case 0x13:
763 <                                        *p++ = 3;       // Audio play completed
763 >                                        WriteMacInt8(p, 3);     // Audio play completed
764                                          break;
765                                  case 0x14:
766 <                                        *p++ = 4;       // Error occurred
766 >                                        WriteMacInt8(p, 4);     // Error occurred
767                                          break;
768                                  default:
769 <                                        *p++ = 5;       // No audio play operation requested
769 >                                        WriteMacInt8(p, 5);     // No audio play operation requested
770                                          break;
771                          }
772 <                        *p++ = info->play_mode;
773 <                        *p++ = pos[5] & 0x0f;           // Control
774 <                        *p++ = bin2bcd[pos[9]];         // M (abs)
775 <                        *p++ = bin2bcd[pos[10]];        // S (abs)
776 <                        *p++ = bin2bcd[pos[11]];        // F (abs)
772 >                        p++;
773 >                        WriteMacInt8(p, info->play_mode); p++;
774 >                        WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
775 >                        WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
776 >                        WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
777 >                        WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
778                          return noErr;
779                  }
780  
# Line 764 | 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 842 | 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 891 | 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 <                        memcpy(Mac2HostAddr(pb + csParam), Mac2HostAddr(info->status), 22);
947 >                        Mac2Mac_memcpy(pb + csParam, info->status, 22);
948                          return noErr;
949  
950                  case 70:                // GetPowerMode
# Line 931 | 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:
# Line 939 | Line 980 | int16 CDROMStatus(uint32 pb, uint32 dce)
980                          return statusErr;
981          }
982   }
983 +
984 +
985 + /*
986 + *  Driver interrupt routine (1Hz) - check for volumes to be mounted
987 + */
988 +
989 + void CDROMInterrupt(void)
990 + {
991 +        if (!acc_run_called)
992 +                return;
993 +
994 +        mount_mountable_volumes();
995 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines