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 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.17 by cebix, 2002-02-07T16:10:54Z

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines