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.11 by cebix, 2001-02-02T20:52:56Z vs.
Revision 1.12 by cebix, 2001-07-01T14:38:02Z

# Line 29 | Line 29
29   */
30  
31   #include <string.h>
32 + #include <vector>
33 +
34 + #ifndef NO_STD_NAMESPACE
35 + using std::vector;
36 + #endif
37  
38   #include "sysdeps.h"
39   #include "cpu_emulation.h"
# Line 97 | Line 102 | static const uint8 bin2bcd[256] = {
102   };
103  
104   static const uint8 bcd2bin[256] = {
105 <        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
105 >         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106          10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107          20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108          30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
# Line 117 | Line 122 | static const uint8 bcd2bin[256] = {
122  
123  
124   // Struct for each drive
125 < struct DriveInfo {
126 <        DriveInfo()
127 <        {
128 <                next = NULL;
129 <                num = 0;
125 <                fh = NULL;
126 <                start_byte = 0;
127 <                status = 0;
128 <        }
125 > struct cdrom_drive_info {
126 >        cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {}
127 >        cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {}
128 >
129 >        void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); }
130  
130        DriveInfo *next;        // Pointer to next DriveInfo (must be first in struct!)
131          int num;                        // Drive number
132          void *fh;                       // File handle
133          int block_size;         // CD-ROM block size
# Line 145 | Line 145 | struct DriveInfo {
145          uint32 status;          // Mac address of drive status record
146   };
147  
148 < // Linked list of DriveInfos
149 < static DriveInfo *first_drive_info;
148 > // List of drives handled by this driver
149 > typedef vector<cdrom_drive_info> drive_vec;
150 > static drive_vec drives;
151  
152   // Icon address (Mac address space, set by PatchROM())
153   uint32 CDROMIconAddr;
# Line 156 | Line 157 | static bool acc_run_called = false;
157  
158  
159   /*
160 < *  Get pointer to drive info, NULL = invalid drive number
160 > *  Get pointer to drive info or drives.end() if not found
161   */
162  
163 < static DriveInfo *get_drive_info(int num)
163 > static drive_vec::iterator get_drive_info(int num)
164   {
165 <        DriveInfo *info = first_drive_info;
166 <        while (info != NULL) {
165 >        drive_vec::iterator info, end = drives.end();
166 >        for (info = drives.begin(); info != end; ++info) {
167                  if (info->num == num)
168                          return info;
168                info = info->next;
169          }
170 <        return NULL;
170 >        return info;
171   }
172  
173  
# Line 175 | Line 175 | static DriveInfo *get_drive_info(int num
175   *  Find HFS partition, set info->start_byte (0 = no HFS partition)
176   */
177  
178 < static void find_hfs_partition(DriveInfo *info)
178 > static void find_hfs_partition(cdrom_drive_info &info)
179   {
180 <        info->start_byte = 0;
180 >        info.start_byte = 0;
181          uint8 *map = new uint8[512];
182  
183          // Search first 64 blocks for HFS partition
184          for (int i=0; i<64; i++) {
185 <                if (Sys_read(info->fh, map, i * 512, 512) != 512)
185 >                if (Sys_read(info.fh, map, i * 512, 512) != 512)
186                          break;
187  
188                  // Not a partition map block? Then look at next block
# Line 192 | Line 192 | static void find_hfs_partition(DriveInfo
192  
193                  // Partition map block found, Apple HFS partition?
194                  if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
195 <                        info->start_byte = ntohl(((uint32 *)map)[2]) << 9;
196 <                        D(bug(" HFS partition found at %d, %d blocks\n", info->start_byte, ntohl(((uint32 *)map)[3])));
195 >                        info.start_byte = ntohl(((uint32 *)map)[2]) << 9;
196 >                        D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, ntohl(((uint32 *)map)[3])));
197                          break;
198                  }
199          }
# Line 205 | Line 205 | static void find_hfs_partition(DriveInfo
205   *  Read TOC of disk and set lead_out
206   */
207  
208 < static void read_toc(DriveInfo *info)
208 > static void read_toc(cdrom_drive_info &info)
209   {
210          // Read TOC
211 <        memset(&info->toc, 0, sizeof(info->toc));
212 <        SysCDReadTOC(info->fh, info->toc);
213 <        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info->toc)[0]), ntohl(((uint32 *)info->toc)[1])));
211 >        memset(info.toc, 0, sizeof(info.toc));
212 >        SysCDReadTOC(info.fh, info.toc);
213 >        D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info.toc)[0]), ntohl(((uint32 *)info.toc)[1])));
214  
215          // Find lead-out track
216 <        info->lead_out[0] = 0;
217 <        info->lead_out[1] = 0;
218 <        info->lead_out[2] = 0;
216 >        info.lead_out[0] = 0;
217 >        info.lead_out[1] = 0;
218 >        info.lead_out[2] = 0;
219          for (int i=4; i<804; i+=8) {
220 <                if (info->toc[i+2] == 0xaa) {
221 <                        info->stop_at[0] = info->lead_out[0] = info->toc[i+5];
222 <                        info->stop_at[1] = info->lead_out[1] = info->toc[i+6];
223 <                        info->stop_at[2] = info->lead_out[2] = info->toc[i+7];
220 >                if (info.toc[i+2] == 0xaa) {
221 >                        info.stop_at[0] = info.lead_out[0] = info.toc[i+5];
222 >                        info.stop_at[1] = info.lead_out[1] = info.toc[i+6];
223 >                        info.stop_at[2] = info.lead_out[2] = info.toc[i+7];
224                          break;
225                  }
226          }
227 <        D(bug(" Lead-Out M %d S %d F %d\n", info->lead_out[0], info->lead_out[1], info->lead_out[2]));
227 >        D(bug(" Lead-Out M %d S %d F %d\n", info.lead_out[0], info.lead_out[1], info.lead_out[2]));
228   }
229  
230  
# Line 233 | Line 233 | static void read_toc(DriveInfo *info)
233   *  Return: false = error
234   */
235  
236 < static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
236 > static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f)
237   {
238          switch (postype) {
239                  case 0:
# Line 251 | Line 251 | static bool position2msf(DriveInfo *info
251                          if (stopping)
252                                  track++;
253                          for (int i=4; i<804; i+=8) {
254 <                                if (info->toc[i+2] == track || info->toc[i+2] == 0xaa) {
255 <                                        m = info->toc[i+5];
256 <                                        s = info->toc[i+6];
257 <                                        f = info->toc[i+7];
254 >                                if (info.toc[i+2] == track || info.toc[i+2] == 0xaa) {
255 >                                        m = info.toc[i+5];
256 >                                        s = info.toc[i+6];
257 >                                        f = info.toc[i+7];
258                                          return true;
259                                  }
260                          }
# Line 272 | Line 272 | static bool position2msf(DriveInfo *info
272  
273   void CDROMInit(void)
274   {
275        first_drive_info = NULL;
276
275          // No drives specified in prefs? Then add defaults
276          if (PrefsFindString("cdrom", 0) == NULL)
277                  SysAddCDROMPrefs();
278  
279          // Add drives specified in preferences
280 <        int32 index = 0;
280 >        int index = 0;
281          const char *str;
282          while ((str = PrefsFindString("cdrom", index++)) != NULL) {
283                  void *fh = Sys_open(str, true);
284 <                if (fh) {
285 <                        DriveInfo *info = new DriveInfo;
288 <                        info->fh = fh;
289 <                        DriveInfo *p = (DriveInfo *)&first_drive_info;
290 <                        while (p->next != NULL)
291 <                                p = p->next;
292 <                        p->next = info;
293 <                }
284 >                if (fh)
285 >                        drives.push_back(cdrom_drive_info(fh));
286          }
287   }
288  
# Line 301 | Line 293 | void CDROMInit(void)
293  
294   void CDROMExit(void)
295   {
296 <        DriveInfo *info = first_drive_info, *next;
297 <        while (info != NULL) {
298 <                SysAllowRemoval(info->fh);
299 <                Sys_close(info->fh);
308 <                next = info->next;
309 <                delete info;
310 <                info = next;
311 <        }
296 >        drive_vec::iterator info, end = drives.end();
297 >        for (info = drives.begin(); info != end; ++info)
298 >                info->close_fh();
299 >        drives.clear();
300   }
301  
302  
# Line 318 | Line 306 | void CDROMExit(void)
306  
307   bool CDROMMountVolume(void *fh)
308   {
309 <        DriveInfo *info;
310 <        for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ;
311 <        if (info) {
309 >        drive_vec::iterator info = drives.begin(), end = drives.end();
310 >        while (info != end && info->fh != fh)
311 >                ++info;
312 >        if (info != end) {
313                  if (SysIsDiskInserted(info->fh)) {
314                          SysPreventRemoval(info->fh);
315                          WriteMacInt8(info->status + dsDiskInPlace, 1);
316 <                        read_toc(info);
317 <                        find_hfs_partition(info);
316 >                        read_toc(*info);
317 >                        find_hfs_partition(*info);
318                          if (info->start_byte != 0 || info->mount_non_hfs)
319                                  info->to_be_mounted = true;
320                  }
# Line 342 | Line 331 | bool CDROMMountVolume(void *fh)
331  
332   static void mount_mountable_volumes(void)
333   {
334 <        DriveInfo *info = first_drive_info;
335 <        while (info != NULL) {
334 >        drive_vec::iterator info, end = drives.end();
335 >        for (info = drives.begin(); info != end; ++info) {
336  
337                  // Disk in drive?
338                  if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
# Line 362 | Line 351 | static void mount_mountable_volumes(void
351                          Execute68kTrap(0xa02f, &r);             // PostEvent()
352                          info->to_be_mounted = false;
353                  }
365
366                info = info->next;
354          }
355   }
356  
# Line 381 | Line 368 | int16 CDROMOpen(uint32 pb, uint32 dce)
368          acc_run_called = false;
369  
370          // Install drives
371 <        for (DriveInfo *info = first_drive_info; info; info = info->next) {
371 >        drive_vec::iterator info, end = drives.end();
372 >        for (info = drives.begin(); info != end; ++info) {
373  
374                  info->num = FindFreeDriveNumber(1);
375                  info->to_be_mounted = false;
# Line 411 | Line 399 | int16 CDROMOpen(uint32 pb, uint32 dce)
399                          if (SysIsDiskInserted(info->fh)) {
400                                  SysPreventRemoval(info->fh);
401                                  WriteMacInt8(info->status + dsDiskInPlace, 1);
402 <                                read_toc(info);
403 <                                find_hfs_partition(info);
402 >                                read_toc(*info);
403 >                                find_hfs_partition(*info);
404                                  info->to_be_mounted = true;
405                          }
406  
# Line 436 | Line 424 | int16 CDROMPrime(uint32 pb, uint32 dce)
424          WriteMacInt32(pb + ioActCount, 0);
425  
426          // Drive valid and disk inserted?
427 <        DriveInfo *info;
428 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
427 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
428 >        if (info == drives.end())
429                  return nsDrvErr;
430          if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
431                  return offLinErr;
# Line 503 | Line 491 | int16 CDROMControl(uint32 pb, uint32 dce
491          }
492  
493          // Drive valid?
494 <        DriveInfo *info;
495 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
496 <                if (first_drive_info == NULL)
494 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
495 >        if (info == drives.end()) {
496 >                if (drives.empty())
497                          return nsDrvErr;
498                  else
499 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
499 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
500 >        }
501  
502          // Drive-specific codes
503          switch (code) {
# Line 535 | Line 524 | int16 CDROMControl(uint32 pb, uint32 dce
524                          WriteMacInt32(pb + csParam, CDROMIconAddr);
525                          return noErr;
526  
527 <                case 23:                // DriveInfo
527 >                case 23:                // drive_info
528                          WriteMacInt32(pb + csParam, 0x00000b01);        // Unspecified external removable SCSI disk
529                          return noErr;
530  
# Line 857 | Line 846 | int16 CDROMControl(uint32 pb, uint32 dce
846  
847   int16 CDROMStatus(uint32 pb, uint32 dce)
848   {
849 <        DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
849 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
850          uint16 code = ReadMacInt16(pb + csCode);
851          D(bug("CDROMStatus %d\n", code));
852  
853 <        // General codes
853 >        // General codes (we can get these even if the drive was invalid)
854          switch (code) {
855                  case 43: {      // DriverGestalt
856                          uint32 sel = ReadMacInt32(pb + csParam);
# Line 880 | Line 869 | int16 CDROMStatus(uint32 pb, uint32 dce)
869                                          WriteMacInt32(pb + csParam + 4, 0x01000000);
870                                          break;
871                                  case FOURCC('b','o','o','t'):   // Boot ID
872 <                                        if (info != NULL)
872 >                                        if (info != drives.end())
873                                                  WriteMacInt16(pb + csParam + 4, info->num);
874                                          else
875                                                  WriteMacInt16(pb + csParam + 4, 0);
# Line 909 | Line 898 | int16 CDROMStatus(uint32 pb, uint32 dce)
898          }
899  
900          // Drive valid?
901 <        if (info == NULL)
902 <                if (first_drive_info == NULL)
901 >        if (info == drives.end()) {
902 >                if (drives.empty())
903                          return nsDrvErr;
904                  else
905 <                        info = first_drive_info;        // This is needed for Apple's Audio CD program
905 >                        info = drives.begin();  // This is needed for Apple's Audio CD program
906 >        }
907  
908          // Drive-specific codes
909          switch (code) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines