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.18 by cebix, 2002-04-28T14:06:17Z

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines