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.16 by cebix, 2002-01-15T14:58:32Z

# 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-2002 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# 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  
184          // Search first 64 blocks for HFS partition
185          for (int i=0; i<64; i++) {
186 <                if (Sys_read(info->fh, map, i * 512, 512) != 512)
186 >                if (Sys_read(info.fh, map, i * 512, 512) != 512)
187                          break;
188  
189 <                // Skip driver descriptor
190 <                uint16 sig = ntohs(((uint16 *)map)[0]);
191 <                if (sig == 'ER')
188 <                        continue;
189 <
190 <                // No partition map? Then look at next block
191 <                if (sig != 'PM')
189 >                // Not a partition map block? Then look at next block
190 >                uint16 sig = (map[0] << 8) | map[1];
191 >                if (sig != 0x504d)
192                          continue;
193  
194 <                // Partition map found, Apple HFS partition?
194 >                // Partition map block found, Apple HFS partition?
195                  if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
196 <                        info->start_byte = ntohl(((uint32 *)map)[2]) << 9;
197 <                        D(bug(" HFS partition found at %ld, %ld blocks\n", info->start_byte, ntohl(((uint32 *)map)[3])));
196 >                        info.start_byte = ntohl(((uint32 *)map)[2]) << 9;
197 >                        D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, ntohl(((uint32 *)map)[3])));
198                          break;
199                  }
200          }
# Line 206 | Line 206 | static void find_hfs_partition(DriveInfo
206   *  Read TOC of disk and set lead_out
207   */
208  
209 < static void read_toc(DriveInfo *info)
209 > static void read_toc(cdrom_drive_info &info)
210   {
211          // Read TOC
212 <        memset(&info->toc, 0, sizeof(info->toc));
213 <        SysCDReadTOC(info->fh, info->toc);
214 <        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info->toc)[0]), ntohl(((uint32 *)info->toc)[1])));
212 >        memset(info.toc, 0, sizeof(info.toc));
213 >        SysCDReadTOC(info.fh, info.toc);
214 >        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info.toc)[0]), ntohl(((uint32 *)info.toc)[1])));
215  
216          // Find lead-out track
217 <        info->lead_out[0] = 0;
218 <        info->lead_out[1] = 0;
219 <        info->lead_out[2] = 0;
217 >        info.lead_out[0] = 0;
218 >        info.lead_out[1] = 0;
219 >        info.lead_out[2] = 0;
220          for (int i=4; i<804; i+=8) {
221 <                if (info->toc[i+2] == 0xaa) {
222 <                        info->stop_at[0] = info->lead_out[0] = info->toc[i+5];
223 <                        info->stop_at[1] = info->lead_out[1] = info->toc[i+6];
224 <                        info->stop_at[2] = info->lead_out[2] = info->toc[i+7];
221 >                if (info.toc[i+2] == 0xaa) {
222 >                        info.stop_at[0] = info.lead_out[0] = info.toc[i+5];
223 >                        info.stop_at[1] = info.lead_out[1] = info.toc[i+6];
224 >                        info.stop_at[2] = info.lead_out[2] = info.toc[i+7];
225                          break;
226                  }
227          }
228 <        D(bug(" Lead-Out M %d S %d F %d\n", info->lead_out[0], info->lead_out[1], info->lead_out[2]));
228 >        D(bug(" Lead-Out M %d S %d F %d\n", info.lead_out[0], info.lead_out[1], info.lead_out[2]));
229   }
230  
231  
# Line 234 | Line 234 | static void read_toc(DriveInfo *info)
234   *  Return: false = error
235   */
236  
237 < static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
237 > static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
238   {
239          switch (postype) {
240                  case 0:
# Line 252 | Line 252 | static bool position2msf(DriveInfo *info
252                          if (stopping)
253                                  track++;
254                          for (int i=4; i<804; i+=8) {
255 <                                if (info->toc[i+2] == track || info->toc[i+2] == 0xaa) {
256 <                                        m = info->toc[i+5];
257 <                                        s = info->toc[i+6];
258 <                                        f = info->toc[i+7];
255 >                                if (info.toc[i+2] == track || info.toc[i+2] == 0xaa) {
256 >                                        m = info.toc[i+5];
257 >                                        s = info.toc[i+6];
258 >                                        f = info.toc[i+7];
259                                          return true;
260                                  }
261                          }
# Line 273 | Line 273 | static bool position2msf(DriveInfo *info
273  
274   void CDROMInit(void)
275   {
276        first_drive_info = NULL;
277
276          // No drives specified in prefs? Then add defaults
277          if (PrefsFindString("cdrom", 0) == NULL)
278                  SysAddCDROMPrefs();
279  
280          // Add drives specified in preferences
281 <        int32 index = 0;
281 >        int index = 0;
282          const char *str;
283          while ((str = PrefsFindString("cdrom", index++)) != NULL) {
284                  void *fh = Sys_open(str, true);
285 <                if (fh) {
286 <                        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 <                }
285 >                if (fh)
286 >                        drives.push_back(cdrom_drive_info(fh));
287          }
288   }
289  
# Line 302 | Line 294 | void CDROMInit(void)
294  
295   void CDROMExit(void)
296   {
297 <        DriveInfo *info = first_drive_info, *next;
298 <        while (info != NULL) {
299 <                Sys_close(info->fh);
300 <                next = info->next;
309 <                delete info;
310 <                info = next;
311 <        }
297 >        drive_vec::iterator info, end = drives.end();
298 >        for (info = drives.begin(); info != end; ++info)
299 >                info->close_fh();
300 >        drives.clear();
301   }
302  
303  
# Line 318 | Line 307 | void CDROMExit(void)
307  
308   bool CDROMMountVolume(void *fh)
309   {
310 <        DriveInfo *info;
311 <        for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ;
312 <        if (info) {
310 >        drive_vec::iterator info = drives.begin(), end = drives.end();
311 >        while (info != end && info->fh != fh)
312 >                ++info;
313 >        if (info != end) {
314                  if (SysIsDiskInserted(info->fh)) {
315                          SysPreventRemoval(info->fh);
316                          WriteMacInt8(info->status + dsDiskInPlace, 1);
317 <                        read_toc(info);
318 <                        find_hfs_partition(info);
317 >                        read_toc(*info);
318 >                        find_hfs_partition(*info);
319                          if (info->start_byte != 0 || info->mount_non_hfs)
320                                  info->to_be_mounted = true;
321                  }
# Line 336 | Line 326 | bool CDROMMountVolume(void *fh)
326  
327  
328   /*
329 + *  Mount volumes for which the to_be_mounted flag is set
330 + *  (called during interrupt time)
331 + */
332 +
333 + static void mount_mountable_volumes(void)
334 + {
335 +        drive_vec::iterator info, end = drives.end();
336 +        for (info = drives.begin(); info != end; ++info) {
337 +
338 +                // Disk in drive?
339 +                if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
340 +
341 +                        // No, check if disk was inserted
342 +                        if (SysIsDiskInserted(info->fh))
343 +                                CDROMMountVolume(info->fh);
344 +                }
345 +
346 +                // Mount disk if flagged
347 +                if (info->to_be_mounted) {
348 +                        D(bug(" mounting drive %d\n", info->num));
349 +                        M68kRegisters r;
350 +                        r.d[0] = info->num;
351 +                        r.a[0] = 7;     // diskEvent
352 +                        Execute68kTrap(0xa02f, &r);             // PostEvent()
353 +                        info->to_be_mounted = false;
354 +                }
355 +        }
356 + }
357 +
358 +
359 + /*
360   *  Driver Open() routine
361   */
362  
# Line 345 | Line 366 | int16 CDROMOpen(uint32 pb, uint32 dce)
366  
367          // Set up DCE
368          WriteMacInt32(dce + dCtlPosition, 0);
369 +        acc_run_called = false;
370  
371          // Install drives
372 <        for (DriveInfo *info = first_drive_info; info; info = info->next) {
372 >        drive_vec::iterator info, end = drives.end();
373 >        for (info = drives.begin(); info != end; ++info) {
374  
375                  info->num = FindFreeDriveNumber(1);
376                  info->to_be_mounted = false;
# Line 377 | Line 400 | int16 CDROMOpen(uint32 pb, uint32 dce)
400                          if (SysIsDiskInserted(info->fh)) {
401                                  SysPreventRemoval(info->fh);
402                                  WriteMacInt8(info->status + dsDiskInPlace, 1);
403 <                                read_toc(info);
404 <                                find_hfs_partition(info);
403 >                                read_toc(*info);
404 >                                find_hfs_partition(*info);
405                                  info->to_be_mounted = true;
406                          }
407  
# Line 402 | Line 425 | int16 CDROMPrime(uint32 pb, uint32 dce)
425          WriteMacInt32(pb + ioActCount, 0);
426  
427          // Drive valid and disk inserted?
428 <        DriveInfo *info;
429 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
428 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
429 >        if (info == drives.end())
430                  return nsDrvErr;
431          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
432                  return offLinErr;
# Line 456 | Line 479 | int16 CDROMControl(uint32 pb, uint32 dce
479                  case 1:         // KillIO
480                          return noErr;
481  
482 <                case 65: {      // Periodic action ("insert" disks on startup and check for disk changes)
483 <                        DriveInfo *info = first_drive_info;
484 <                        while (info != NULL) {
485 <
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 <                        }
482 >                case 65: {      // Periodic action (accRun, "insert" disks on startup)
483 >                        mount_mountable_volumes();
484 >                        WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000);        // Disable periodic action
485 >                        acc_run_called = true;
486                          return noErr;
487                  }
488  
# Line 489 | Line 492 | int16 CDROMControl(uint32 pb, uint32 dce
492          }
493  
494          // Drive valid?
495 <        DriveInfo *info;
496 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
497 <                if (first_drive_info == NULL)
495 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
496 >        if (info == drives.end()) {
497 >                if (drives.empty())
498                          return nsDrvErr;
499                  else
500 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
500 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
501 >        }
502  
503          // Drive-specific codes
504          switch (code) {
# Line 521 | Line 525 | int16 CDROMControl(uint32 pb, uint32 dce
525                          WriteMacInt32(pb + csParam, CDROMIconAddr);
526                          return noErr;
527  
528 <                case 23:                // DriveInfo
528 >                case 23:                // drive_info
529                          WriteMacInt32(pb + csParam, 0x00000b01);        // Unspecified external removable SCSI disk
530                          return noErr;
531  
# Line 581 | Line 585 | int16 CDROMControl(uint32 pb, uint32 dce
585                                          break;
586  
587                                  case 3: {               // Get track starting address
588 <                                        uint8 *buf = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
588 >                                        uint32 buf = ReadMacInt32(pb + csParam + 2);
589                                          uint16 buf_size = ReadMacInt16(pb + csParam + 6);
590                                          int track = bcd2bin[ReadMacInt8(pb + csParam + 8)];
591  
# Line 595 | Line 599 | int16 CDROMControl(uint32 pb, uint32 dce
599                                          // Fill buffer
600                                          if (i != 804)
601                                                  while (buf_size > 0) {
602 <                                                        *buf++ = info->toc[i+1] & 0x0f;         // Control
603 <                                                        *buf++ = bin2bcd[info->toc[i+5]];       // M
604 <                                                        *buf++ = bin2bcd[info->toc[i+6]];       // S
605 <                                                        *buf++ = bin2bcd[info->toc[i+7]];       // F
602 >                                                        WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++;        // Control
603 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++;      // M
604 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++;      // S
605 >                                                        WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++;      // F
606  
607                                                          // Lead-Out? Then stop
608                                                          if (info->toc[i+2] == 0xaa)
# Line 629 | Line 633 | int16 CDROMControl(uint32 pb, uint32 dce
633  
634                  case 101: {             // ReadTheQSubcode
635                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
636 <                                memset(Mac2HostAddr(pb + csParam), 0, 10);
636 >                                Mac_memset(pb + csParam, 0, 10);
637                                  return offLinErr;
638                          }
639  
640                          uint8 pos[16];
641                          if (SysCDGetPosition(info->fh, pos)) {
642 <                                uint8 *p = Mac2HostAddr(pb + csParam);
643 <                                *p++ = pos[5] & 0x0f;           // Control
644 <                                *p++ = bin2bcd[pos[6]];         // Track number
645 <                                *p++ = bin2bcd[pos[7]];         // Index number
646 <                                *p++ = bin2bcd[pos[13]];        // M (rel)
647 <                                *p++ = bin2bcd[pos[14]];        // S (rel)
648 <                                *p++ = bin2bcd[pos[15]];        // F (rel)
649 <                                *p++ = bin2bcd[pos[9]];         // M (abs)
650 <                                *p++ = bin2bcd[pos[10]];        // S (abs)
651 <                                *p++ = bin2bcd[pos[11]];        // F (abs)
652 <                                *p++ = 0;
642 >                                uint32 p = pb + csParam;
643 >                                WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
644 >                                WriteMacInt8(p, bin2bcd[pos[6]]); p++;  // Track number
645 >                                WriteMacInt8(p, bin2bcd[pos[7]]); p++;  // Index number
646 >                                WriteMacInt8(p, bin2bcd[pos[13]]); p++; // M (rel)
647 >                                WriteMacInt8(p, bin2bcd[pos[14]]); p++; // S (rel)
648 >                                WriteMacInt8(p, bin2bcd[pos[15]]); p++; // F (rel)
649 >                                WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
650 >                                WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
651 >                                WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
652 >                                WriteMacInt8(p, 0);
653                                  return noErr;
654                          } else
655                                  return ioErr;
# Line 656 | Line 660 | int16 CDROMControl(uint32 pb, uint32 dce
660                          return controlErr;
661  
662                  case 103: {             // AudioTrackSearch
663 <                        D(bug(" AudioTrackSearch postype %d, pos %08lx, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
663 >                        D(bug(" AudioTrackSearch postype %d, pos %08x, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
664                          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
665                                  return offLinErr;
666  
667                          uint8 start_m, start_s, start_f;
668 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
668 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
669                                  return paramErr;
670                          info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
671                          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 682 | int16 CDROMControl(uint32 pb, uint32 dce
682  
683                          if (ReadMacInt16(pb + csParam + 6)) {
684                                  // Given stopping address
685 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
685 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
686                                          return paramErr;
687                          } else {
688                                  // Given starting address
689                                  uint8 start_m, start_s, start_f;
690 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
690 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
691                                          return paramErr;
692                                  info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
693                                  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 724 | int16 CDROMControl(uint32 pb, uint32 dce
724                                          return paramErr;
725                          } else {
726                                  // Given stopping address
727 <                                if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
727 >                                if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
728                                          return paramErr;
729                          }
730                          return noErr;
# Line 733 | Line 737 | int16 CDROMControl(uint32 pb, uint32 dce
737                          if (!SysCDGetPosition(info->fh, pos))
738                                  return paramErr;
739  
740 <                        uint8 *p = Mac2HostAddr(pb + csParam);
740 >                        uint32 p = pb + csParam;
741                          switch (pos[1]) {
742                                  case 0x11:
743 <                                        *p++ = 0;       // Audio play in progress
743 >                                        WriteMacInt8(p, 0);     // Audio play in progress
744                                          break;
745                                  case 0x12:
746 <                                        *p++ = 1;       // Audio play paused
746 >                                        WriteMacInt8(p, 1);     // Audio play paused
747                                          break;
748                                  case 0x13:
749 <                                        *p++ = 3;       // Audio play completed
749 >                                        WriteMacInt8(p, 3);     // Audio play completed
750                                          break;
751                                  case 0x14:
752 <                                        *p++ = 4;       // Error occurred
752 >                                        WriteMacInt8(p, 4);     // Error occurred
753                                          break;
754                                  default:
755 <                                        *p++ = 5;       // No audio play operation requested
755 >                                        WriteMacInt8(p, 5);     // No audio play operation requested
756                                          break;
757                          }
758 <                        *p++ = info->play_mode;
759 <                        *p++ = pos[5] & 0x0f;           // Control
760 <                        *p++ = bin2bcd[pos[9]];         // M (abs)
761 <                        *p++ = bin2bcd[pos[10]];        // S (abs)
762 <                        *p++ = bin2bcd[pos[11]];        // F (abs)
758 >                        p++;
759 >                        WriteMacInt8(p, info->play_mode); p++;
760 >                        WriteMacInt8(p, pos[5] & 0x0f); p++;    // Control
761 >                        WriteMacInt8(p, bin2bcd[pos[9]]); p++;  // M (abs)
762 >                        WriteMacInt8(p, bin2bcd[pos[10]]); p++; // S (abs)
763 >                        WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
764                          return noErr;
765                  }
766  
# Line 764 | Line 769 | int16 CDROMControl(uint32 pb, uint32 dce
769                                  return offLinErr;
770  
771                          uint8 start_m, start_s, start_f;
772 <                        if (!position2msf(info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
772 >                        if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
773                                  return paramErr;
774  
775                          if (!SysCDScan(info->fh, start_m, start_s, start_f, ReadMacInt16(pb + csParam + 6)))
# Line 842 | Line 847 | int16 CDROMControl(uint32 pb, uint32 dce
847  
848   int16 CDROMStatus(uint32 pb, uint32 dce)
849   {
850 <        DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
850 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
851          uint16 code = ReadMacInt16(pb + csCode);
852          D(bug("CDROMStatus %d\n", code));
853  
854 <        // General codes
854 >        // General codes (we can get these even if the drive was invalid)
855          switch (code) {
856                  case 43: {      // DriverGestalt
857                          uint32 sel = ReadMacInt32(pb + csParam);
858                          D(bug(" driver gestalt %c%c%c%c\n", sel >> 24, sel >> 16,  sel >> 8, sel));
859                          switch (sel) {
860 <                                case 'vers':    // Version
860 >                                case FOURCC('v','e','r','s'):   // Version
861                                          WriteMacInt32(pb + csParam + 4, 0x05208000);
862                                          break;
863 <                                case 'devt':    // Device type
864 <                                        WriteMacInt32(pb + csParam + 4, 'cdrm');
863 >                                case FOURCC('d','e','v','t'):   // Device type
864 >                                        WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m'));
865                                          break;
866 <                                case 'intf':    // Interface type
867 <                                        WriteMacInt32(pb + csParam + 4, 'basi');
866 >                                case FOURCC('i','n','t','f'):   // Interface type
867 >                                        WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
868                                          break;
869 <                                case 'sync':    // Only synchronous operation?
869 >                                case FOURCC('s','y','n','c'):   // Only synchronous operation?
870                                          WriteMacInt32(pb + csParam + 4, 0x01000000);
871                                          break;
872 <                                case 'boot':    // Boot ID
873 <                                        if (info != NULL)
872 >                                case FOURCC('b','o','o','t'):   // Boot ID
873 >                                        if (info != drives.end())
874                                                  WriteMacInt16(pb + csParam + 4, info->num);
875                                          else
876                                                  WriteMacInt16(pb + csParam + 4, 0);
877                                          WriteMacInt16(pb + csParam + 6, (uint16)CDROMRefNum);
878                                          break;
879 <                                case 'wide':    // 64-bit access supported?
879 >                                case FOURCC('w','i','d','e'):   // 64-bit access supported?
880                                          WriteMacInt16(pb + csParam + 4, 0);
881                                          break;
882 <                                case 'purg':    // Purge flags
882 >                                case FOURCC('p','u','r','g'):   // Purge flags
883                                          WriteMacInt32(pb + csParam + 4, 0);
884                                          break;
885 <                                case 'ejec':    // Eject flags
885 >                                case FOURCC('e','j','e','c'):   // Eject flags
886                                          WriteMacInt32(pb + csParam + 4, 0x00030003);    // Don't eject on shutdown/restart
887                                          break;
888 <                                case 'flus':    // Flush flags
888 >                                case FOURCC('f','l','u','s'):   // Flush flags
889                                          WriteMacInt16(pb + csParam + 4, 0);
890                                          break;
891 <                                case 'vmop':    // Virtual memory attributes
891 >                                case FOURCC('v','m','o','p'):   // Virtual memory attributes
892                                          WriteMacInt32(pb + csParam + 4, 0);     // Drive not available for VM
893                                          break;
894                                  default:
# Line 894 | Line 899 | int16 CDROMStatus(uint32 pb, uint32 dce)
899          }
900  
901          // Drive valid?
902 <        if (info == NULL)
903 <                if (first_drive_info == NULL)
902 >        if (info == drives.end()) {
903 >                if (drives.empty())
904                          return nsDrvErr;
905                  else
906 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
906 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
907 >        }
908  
909          // Drive-specific codes
910          switch (code) {
911 +                case 6:                 // Return format list
912 +                        if (ReadMacInt16(pb + csParam) > 0) {
913 +                                uint32 adr = ReadMacInt32(pb + csParam + 2);
914 +                                WriteMacInt16(pb + csParam, 1);                                         // 1 format
915 +                                WriteMacInt32(adr, SysGetFileSize(info->fh) / 512);     // Number of blocks
916 +                                WriteMacInt32(adr + 4, 0);                                                      // heads/track/sectors
917 +                                return noErr;
918 +                        } else
919 +                                return paramErr;
920 +
921                  case 8:                 // DriveStatus
922 <                        memcpy(Mac2HostAddr(pb + csParam), Mac2HostAddr(info->status), 22);
922 >                        Mac2Mac_memcpy(pb + csParam, info->status, 22);
923                          return noErr;
924  
925                  case 70:                // GetPowerMode
# Line 939 | Line 955 | int16 CDROMStatus(uint32 pb, uint32 dce)
955                          return statusErr;
956          }
957   }
958 +
959 +
960 + /*
961 + *  Driver interrupt routine (1Hz) - check for volumes to be mounted
962 + */
963 +
964 + void CDROMInterrupt(void)
965 + {
966 +        if (!acc_run_called)
967 +                return;
968 +
969 +        mount_mountable_volumes();
970 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines