ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/sony.cpp
(Generate patch)

Comparing BasiliskII/src/sony.cpp (file contents):
Revision 1.9 by cebix, 2001-02-02T20:52:57Z vs.
Revision 1.11 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 99 | Line 104 | const uint8 SonyDriveIcon[258] = {
104  
105  
106   // Struct for each drive
107 < struct DriveInfo {
108 <        DriveInfo()
109 <        {
110 <                next = NULL;
111 <                num = 0;
107 <                fh = NULL;
108 <                read_only = false;
109 <                status = 0;
110 <        }
107 > struct sony_drive_info {
108 >        sony_drive_info() : num(0), fh(NULL), read_only(false), status(0) {}
109 >        sony_drive_info(void *fh_, bool ro) : num(0), fh(fh_), read_only(ro), status(0) {}
110 >
111 >        void close_fh(void) { Sys_close(fh); }
112  
112        DriveInfo *next;        // Pointer to next DriveInfo (must be first in struct!)
113          int num;                        // Drive number
114          void *fh;                       // Floppy driver file handle
115          bool to_be_mounted;     // Flag: drive must be mounted in accRun
# Line 118 | Line 118 | struct DriveInfo {
118          uint32 status;          // Mac address of drive status record
119   };
120  
121 < // Linked list of DriveInfos
122 < static DriveInfo *first_drive_info;
121 > // List of drives handled by this driver
122 > typedef vector<sony_drive_info> drive_vec;
123 > static drive_vec drives;
124  
125   // Icon addresses (Mac address space, set by PatchROM())
126   uint32 SonyDiskIconAddr;
# Line 130 | Line 131 | static bool acc_run_called = false;
131  
132  
133   /*
134 < *  Get pointer to drive info, NULL = invalid drive number
134 > *  Get reference to drive info or drives.end() if not found
135   */
136  
137 < static DriveInfo *get_drive_info(int num)
137 > static drive_vec::iterator get_drive_info(int num)
138   {
139 <        DriveInfo *info = first_drive_info;
140 <        while (info != NULL) {
139 >        drive_vec::iterator info, end = drives.end();
140 >        for (info = drives.begin(); info != end; ++info) {
141                  if (info->num == num)
142                          return info;
142                info = info->next;
143          }
144 <        return NULL;
144 >        return info;
145   }
146  
147  
# Line 151 | Line 151 | static DriveInfo *get_drive_info(int num
151  
152   void SonyInit(void)
153   {
154        first_drive_info = NULL;
155
154          // No drives specified in prefs? Then add defaults
155          if (PrefsFindString("floppy", 0) == NULL)
156                  SysAddFloppyPrefs();
157  
158          // Add drives specified in preferences
159 <        int32 index = 0;
159 >        int index = 0;
160          const char *str;
161          while ((str = PrefsFindString("floppy", index++)) != NULL) {
162                  bool read_only = false;
# Line 167 | Line 165 | void SonyInit(void)
165                          str++;
166                  }
167                  void *fh = Sys_open(str, read_only);
168 <                if (fh) {
169 <                        DriveInfo *info = new DriveInfo;
172 <                        info->fh = fh;
173 <                        info->read_only = SysIsReadOnly(fh);
174 <                        DriveInfo *p = (DriveInfo *)&first_drive_info;
175 <                        while (p->next != NULL)
176 <                                p = p->next;
177 <                        p->next = info;
178 <                }
168 >                if (fh)
169 >                        drives.push_back(sony_drive_info(fh, SysIsReadOnly(fh)));
170          }
171   }
172  
# Line 186 | Line 177 | void SonyInit(void)
177  
178   void SonyExit(void)
179   {
180 <        DriveInfo *info = first_drive_info, *next;
181 <        while (info != NULL) {
182 <                Sys_close(info->fh);
183 <                next = info->next;
193 <                delete info;
194 <                info = next;
195 <        }
180 >        drive_vec::iterator info, end = drives.end();
181 >        for (info = drives.begin(); info != end; ++info)
182 >                info->close_fh();
183 >        drives.clear();
184   }
185  
186  
# Line 202 | Line 190 | void SonyExit(void)
190  
191   bool SonyMountVolume(void *fh)
192   {
193 <        DriveInfo *info;
194 <        for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ;
195 <        if (info) {
193 >        drive_vec::iterator info = drives.begin(), end = drives.end();
194 >        while (info != end && info->fh != fh)
195 >                ++info;
196 >        if (info != end) {
197                  if (SysIsDiskInserted(info->fh)) {
198                          info->read_only = SysIsReadOnly(info->fh);
199                          WriteMacInt8(info->status + dsDiskInPlace, 1);  // Inserted removable disk
# Line 224 | Line 213 | bool SonyMountVolume(void *fh)
213  
214   static void mount_mountable_volumes(void)
215   {
216 <        DriveInfo *info = first_drive_info;
217 <        while (info != NULL) {
216 >        drive_vec::iterator info, end = drives.end();
217 >        for (info = drives.begin(); info != end; ++info) {
218  
219   #if DISK_INSERT_CHECK
220                  // Disk in drive?
# Line 246 | Line 235 | static void mount_mountable_volumes(void
235                          Execute68kTrap(0xa02f, &r);             // PostEvent()
236                          info->to_be_mounted = false;
237                  }
249
250                info = info->next;
238          }
239   }
240  
241  
242   /*
243 + *  Set error code in DskErr
244 + */
245 +
246 + static int16 set_dsk_err(int16 err)
247 + {
248 +        WriteMacInt16(0x142, err);
249 +        return err;
250 + }
251 +
252 +
253 + /*
254   *  Driver Open() routine
255   */
256  
# Line 273 | Line 271 | int16 SonyOpen(uint32 pb, uint32 dce)
271          WriteMacInt32(0x134, 0xdeadbeef);
272  
273          // Clear DskErr
274 <        WriteMacInt16(0x142, 0);
274 >        set_dsk_err(0);
275  
276          // Install drives
277 <        for (DriveInfo *info = first_drive_info; info; info = info->next) {
277 >        drive_vec::iterator info, end = drives.end();
278 >        for (info = drives.begin(); info != end; ++info) {
279  
280                  info->num = FindFreeDriveNumber(1);
281                  info->to_be_mounted = false;
# Line 330 | Line 329 | int16 SonyPrime(uint32 pb, uint32 dce)
329          WriteMacInt32(pb + ioActCount, 0);
330  
331          // Drive valid and disk inserted?
332 <        DriveInfo *info;
333 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
334 <                return nsDrvErr;
332 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
333 >        if (info == drives.end())
334 >                return set_dsk_err(nsDrvErr);
335          if (!ReadMacInt8(info->status + dsDiskInPlace))
336 <                return offLinErr;
336 >                return set_dsk_err(offLinErr);
337          WriteMacInt8(info->status + dsDiskInPlace, 2);  // Disk accessed
338  
339          // Get parameters
# Line 342 | Line 341 | int16 SonyPrime(uint32 pb, uint32 dce)
341          size_t length = ReadMacInt32(pb + ioReqCount);
342          loff_t position = ReadMacInt32(dce + dCtlPosition);
343          if ((length & 0x1ff) || (position & 0x1ff))
344 <                return paramErr;
344 >                return set_dsk_err(paramErr);
345  
346          size_t actual = 0;
347          if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {
# Line 350 | Line 349 | int16 SonyPrime(uint32 pb, uint32 dce)
349                  // Read
350                  actual = Sys_read(info->fh, buffer, position, length);
351                  if (actual != length)
352 <                        return readErr;
352 >                        return set_dsk_err(readErr);
353  
354                  // Clear TagBuf
355                  WriteMacInt32(0x2fc, 0);
# Line 361 | Line 360 | int16 SonyPrime(uint32 pb, uint32 dce)
360  
361                  // Write
362                  if (info->read_only)
363 <                        return wPrErr;
363 >                        return set_dsk_err(wPrErr);
364                  actual = Sys_write(info->fh, buffer, position, length);
365                  if (actual != length)
366 <                        return writErr;
366 >                        return set_dsk_err(writErr);
367          }
368  
369          // Update ParamBlock and DCE
370          WriteMacInt32(pb + ioActCount, actual);
371          WriteMacInt32(dce + dCtlPosition, ReadMacInt32(dce + dCtlPosition) + actual);
372 <        return noErr;
372 >        return set_dsk_err(noErr);
373   }
374  
375  
# Line 386 | Line 385 | int16 SonyControl(uint32 pb, uint32 dce)
385          // General codes
386          switch (code) {
387                  case 1:         // KillIO
388 <                        return -1;
388 >                        return set_dsk_err(-1);
389  
390                  case 9:         // Track cache
391 <                        return noErr;
391 >                        return set_dsk_err(noErr);
392  
393                  case 65:        // Periodic action (accRun, "insert" disks on startup)
394                          mount_mountable_volumes();
# Line 400 | Line 399 | int16 SonyControl(uint32 pb, uint32 dce)
399          }
400  
401          // Drive valid?
402 <        DriveInfo *info;
403 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
404 <                return nsDrvErr;
402 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
403 >        if (info == drives.end())
404 >                return set_dsk_err(nsDrvErr);
405  
406          // Drive-specific codes
407 +        int16 err = noErr;
408          switch (code) {
409                  case 5:         // Verify disk
410 <                        if (ReadMacInt8(info->status + dsDiskInPlace) > 0)
411 <                                return noErr;
412 <                        else
413 <                                return verErr;
410 >                        if (ReadMacInt8(info->status + dsDiskInPlace) <= 0)
411 >                                err = verErr;
412 >                        break;
413  
414                  case 6:         // Format disk
415                          if (info->read_only)
416 <                                return wPrErr;
416 >                                err = wPrErr;
417                          else if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
418 <                                if (SysFormat(info->fh))
419 <                                        return noErr;
421 <                                else
422 <                                        return writErr;
418 >                                if (!SysFormat(info->fh))
419 >                                        err = writErr;
420                          } else
421 <                                return offLinErr;
421 >                                err = offLinErr;
422 >                        break;
423  
424                  case 7:         // Eject
425                          if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
426                                  SysEject(info->fh);
427                                  WriteMacInt8(info->status + dsDiskInPlace, 0);
428                          }
429 <                        return noErr;
429 >                        break;
430  
431                  case 8:         // Set tag buffer
432                          info->tag_buffer = ReadMacInt32(pb + csParam);
433 <                        return noErr;
433 >                        break;
434  
435                  case 21:                // Get drive icon
436                          WriteMacInt32(pb + csParam, SonyDriveIconAddr);
437 <                        return noErr;
437 >                        break;
438  
439                  case 22:                // Get disk icon
440                          WriteMacInt32(pb + csParam, SonyDiskIconAddr);
441 <                        return noErr;
441 >                        break;
442  
443                  case 23:                // Get drive info
444                          if (info->num == 1)
445                                  WriteMacInt32(pb + csParam, 0x0004);    // Internal drive
446                          else
447                                  WriteMacInt32(pb + csParam, 0x0104);    // External drive
448 <                        return noErr;
448 >                        break;
449  
450 <                case 0x5343: {  // Format and write to disk ('SC'), used by DiskCopy
450 >                case 0x5343:    // Format and write to disk ('SC'), used by DiskCopy
451                          if (!ReadMacInt8(info->status + dsDiskInPlace))
452 <                                return offLinErr;
453 <                        if (info->read_only)
454 <                                return wPrErr;
455 <
456 <                        void *data = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
457 <                        size_t actual = Sys_write(info->fh, data, 0, 2880*512);
458 <                        if (actual != 2880*512)
459 <                                return writErr;
460 <                        else
461 <                                return noErr;
464 <                }
452 >                                err = offLinErr;
453 >                        else if (info->read_only)
454 >                                err = wPrErr;
455 >                        else {
456 >                                void *data = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
457 >                                size_t actual = Sys_write(info->fh, data, 0, 2880*512);
458 >                                if (actual != 2880*512)
459 >                                        err = writErr;
460 >                        }
461 >                        break;
462  
463                  default:
464                          printf("WARNING: Unknown SonyControl(%d)\n", code);
465 <                        return controlErr;
465 >                        err = controlErr;
466 >                        break;
467          }
468 +
469 +        return set_dsk_err(err);
470   }
471  
472  
# Line 480 | Line 480 | int16 SonyStatus(uint32 pb, uint32 dce)
480          D(bug("SonyStatus %d\n", code));
481  
482          // Drive valid?
483 <        DriveInfo *info;
484 <        if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
485 <                return nsDrvErr;
483 >        drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
484 >        if (info == drives.end())
485 >                return set_dsk_err(nsDrvErr);
486  
487 +        int16 err = noErr;
488          switch (code) {
489                  case 6:         // Return format list
490                          if (ReadMacInt16(pb + csParam) > 0) {
# Line 491 | Line 492 | int16 SonyStatus(uint32 pb, uint32 dce)
492                                  WriteMacInt16(pb + csParam, 1);         // 1 format
493                                  WriteMacInt32(adr, 2880);                       // 2880 sectors
494                                  WriteMacInt32(adr + 4, 0xd2120050);     // 2 heads, 18 secs/track, 80 tracks
494                                return noErr;
495                          } else
496 <                                return paramErr;
496 >                                err = paramErr;
497 >                        break;
498  
499                  case 8:         // Get drive status
500                          Mac2Mac_memcpy(pb + csParam, info->status, 22);
501 <                        return noErr;
501 >                        break;
502  
503                  case 10:        // Get disk type
504                          WriteMacInt32(pb + csParam, ReadMacInt32(info->status + dsMFMDrive) & 0xffffff00 | 0xfe);
505 <                        return noErr;
505 >                        break;
506  
507                  case 0x4456: // Duplicator version supported ('DV')
508                          WriteMacInt16(pb + csParam, 0x0410);
509 <                        return noErr;
509 >                        break;
510  
511                  case 0x5343: // Get address header format byte ('SC')
512                          WriteMacInt8(pb + csParam, 0x22);       // 512 bytes/sector
513 <                        return noErr;
513 >                        break;
514  
515                  default:
516                          printf("WARNING: Unknown SonyStatus(%d)\n", code);
517 <                        return statusErr;
517 >                        err = statusErr;
518 >                        break;
519          }
520 +
521 +        return set_dsk_err(err);
522   }
523  
524  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines