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.1 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.10 by cebix, 2001-02-10T20:03:55Z

# Line 1 | Line 1
1   /*
2   *  sony.cpp - Replacement .Sony driver (floppy drives)
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 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 42 | Line 42
42   #define DEBUG 0
43   #include "debug.h"
44  
45 +
46 + // Check for inserted disks by polling?
47   #ifdef AMIGA
48 < #define DISK_INSERT_CHECK 1             // Check for inserted disks (problem: on most hardware, disks are not ejected and automatically remounted)
48 > #define DISK_INSERT_CHECK 1
49   #else
50   #define DISK_INSERT_CHECK 0
51   #endif
# Line 123 | Line 125 | static DriveInfo *first_drive_info;
125   uint32 SonyDiskIconAddr;
126   uint32 SonyDriveIconAddr;
127  
128 < // Flag: accRun called for the first time, run PatchAfterStartup()
129 < static bool periodic_first_time = false;
128 > // Flag: Control(accRun) has been called, interrupt routine is now active
129 > static bool acc_run_called = false;
130  
131  
132   /*
# Line 216 | Line 218 | bool SonyMountVolume(void *fh)
218  
219  
220   /*
221 + *  Mount volumes for which the to_be_mounted flag is set
222 + *  (called during interrupt time)
223 + */
224 +
225 + static void mount_mountable_volumes(void)
226 + {
227 +        DriveInfo *info = first_drive_info;
228 +        while (info != NULL) {
229 +
230 + #if DISK_INSERT_CHECK
231 +                // Disk in drive?
232 +                if (!ReadMacInt8(info->status + dsDiskInPlace)) {
233 +
234 +                        // No, check if disk was inserted
235 +                        if (SysIsDiskInserted(info->fh))
236 +                                SonyMountVolume(info->fh);
237 +                }
238 + #endif
239 +
240 +                // Mount disk if flagged
241 +                if (info->to_be_mounted) {
242 +                        D(bug(" mounting drive %d\n", info->num));
243 +                        M68kRegisters r;
244 +                        r.d[0] = info->num;
245 +                        r.a[0] = 7;     // diskEvent
246 +                        Execute68kTrap(0xa02f, &r);             // PostEvent()
247 +                        info->to_be_mounted = false;
248 +                }
249 +
250 +                info = info->next;
251 +        }
252 + }
253 +
254 +
255 + /*
256 + *  Set error code in DskErr
257 + */
258 +
259 + static int16 set_dsk_err(int16 err)
260 + {
261 +        WriteMacInt16(0x142, err);
262 +        return err;
263 + }
264 +
265 +
266 + /*
267   *  Driver Open() routine
268   */
269  
# Line 226 | Line 274 | int16 SonyOpen(uint32 pb, uint32 dce)
274          // Set up DCE
275          WriteMacInt32(dce + dCtlPosition, 0);
276          WriteMacInt16(dce + dCtlQHdr + qFlags, ReadMacInt16(dce + dCtlQHdr + qFlags) & 0xff00 | 3);     // Version number, must be >=3 or System 8 will replace us
277 <        periodic_first_time = true;
277 >        acc_run_called = false;
278  
279          // Install driver again with refnum -2 (HD20)
280          uint32 utab = ReadMacInt32(0x11c);
# Line 236 | Line 284 | int16 SonyOpen(uint32 pb, uint32 dce)
284          WriteMacInt32(0x134, 0xdeadbeef);
285  
286          // Clear DskErr
287 <        WriteMacInt16(0x142, 0);
287 >        set_dsk_err(0);
288  
289          // Install drives
290          for (DriveInfo *info = first_drive_info; info; info = info->next) {
# Line 295 | Line 343 | int16 SonyPrime(uint32 pb, uint32 dce)
343          // Drive valid and disk inserted?
344          DriveInfo *info;
345          if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
346 <                return nsDrvErr;
346 >                return set_dsk_err(nsDrvErr);
347          if (!ReadMacInt8(info->status + dsDiskInPlace))
348 <                return offLinErr;
348 >                return set_dsk_err(offLinErr);
349          WriteMacInt8(info->status + dsDiskInPlace, 2);  // Disk accessed
350  
351          // Get parameters
# Line 305 | Line 353 | int16 SonyPrime(uint32 pb, uint32 dce)
353          size_t length = ReadMacInt32(pb + ioReqCount);
354          loff_t position = ReadMacInt32(dce + dCtlPosition);
355          if ((length & 0x1ff) || (position & 0x1ff))
356 <                return paramErr;
356 >                return set_dsk_err(paramErr);
357  
358          size_t actual = 0;
359          if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {
# Line 313 | Line 361 | int16 SonyPrime(uint32 pb, uint32 dce)
361                  // Read
362                  actual = Sys_read(info->fh, buffer, position, length);
363                  if (actual != length)
364 <                        return readErr;
364 >                        return set_dsk_err(readErr);
365  
366                  // Clear TagBuf
367                  WriteMacInt32(0x2fc, 0);
# Line 324 | Line 372 | int16 SonyPrime(uint32 pb, uint32 dce)
372  
373                  // Write
374                  if (info->read_only)
375 <                        return wPrErr;
375 >                        return set_dsk_err(wPrErr);
376                  actual = Sys_write(info->fh, buffer, position, length);
377                  if (actual != length)
378 <                        return writErr;
378 >                        return set_dsk_err(writErr);
379          }
380  
381          // Update ParamBlock and DCE
382          WriteMacInt32(pb + ioActCount, actual);
383          WriteMacInt32(dce + dCtlPosition, ReadMacInt32(dce + dCtlPosition) + actual);
384 <        return noErr;
384 >        return set_dsk_err(noErr);
385   }
386  
387  
# Line 349 | Line 397 | int16 SonyControl(uint32 pb, uint32 dce)
397          // General codes
398          switch (code) {
399                  case 1:         // KillIO
400 <                        return -1;
400 >                        return set_dsk_err(-1);
401  
402                  case 9:         // Track cache
403 <                        return noErr;
356 <
357 <                case 65: {      // Periodic action ("insert" disks on startup and check for disk changes)
358 <                        DriveInfo *info = first_drive_info;
359 <                        while (info != NULL) {
360 <
361 <                                // Disk in drive?
362 <                                if (!ReadMacInt8(info->status + dsDiskInPlace)) {
403 >                        return set_dsk_err(noErr);
404  
405 < #if DISK_INSERT_CHECK
406 <                                        // No, check if disk was inserted
407 <                                        if (SysIsDiskInserted(info->fh))
408 <                                                SonyMountVolume(info->fh);
409 < #endif
369 <                                }
370 <
371 <                                // Mount disk if flagged
372 <                                if (info->to_be_mounted) {
373 <                                        D(bug(" mounting drive %d\n", info->num));
374 <                                        M68kRegisters r;
375 <                                        r.d[0] = info->num;
376 <                                        r.a[0] = 7;     // diskEvent
377 <                                        Execute68kTrap(0xa02f, &r);             // PostEvent()
378 <                                        info->to_be_mounted = false;
379 <                                }
380 <
381 <                                info = info->next;
382 <                        }
383 <                        if (periodic_first_time) {
384 <                                periodic_first_time = false;
385 <                                PatchAfterStartup();            // Install patches after system startup
386 <                        }
405 >                case 65:        // Periodic action (accRun, "insert" disks on startup)
406 >                        mount_mountable_volumes();
407 >                        PatchAfterStartup();            // Install patches after system startup
408 >                        WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000);        // Disable periodic action
409 >                        acc_run_called = true;
410                          return noErr;
388                }
411          }
412  
413          // Drive valid?
414          DriveInfo *info;
415          if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
416 <                return nsDrvErr;
416 >                return set_dsk_err(nsDrvErr);
417  
418          // Drive-specific codes
419 +        int16 err = noErr;
420          switch (code) {
421                  case 5:         // Verify disk
422 <                        if (ReadMacInt8(info->status + dsDiskInPlace) > 0)
423 <                                return noErr;
424 <                        else
402 <                                return verErr;
422 >                        if (ReadMacInt8(info->status + dsDiskInPlace) <= 0)
423 >                                err = verErr;
424 >                        break;
425  
426                  case 6:         // Format disk
427                          if (info->read_only)
428 <                                return wPrErr;
428 >                                err = wPrErr;
429                          else if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
430 <                                if (SysFormat(info->fh))
431 <                                        return noErr;
410 <                                else
411 <                                        return writErr;
430 >                                if (!SysFormat(info->fh))
431 >                                        err = writErr;
432                          } else
433 <                                return offLinErr;
433 >                                err = offLinErr;
434 >                        break;
435  
436                  case 7:         // Eject
437                          if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
438                                  SysEject(info->fh);
439                                  WriteMacInt8(info->status + dsDiskInPlace, 0);
440                          }
441 <                        return noErr;
441 >                        break;
442  
443                  case 8:         // Set tag buffer
444                          info->tag_buffer = ReadMacInt32(pb + csParam);
445 <                        return noErr;
445 >                        break;
446  
447                  case 21:                // Get drive icon
448                          WriteMacInt32(pb + csParam, SonyDriveIconAddr);
449 <                        return noErr;
449 >                        break;
450  
451                  case 22:                // Get disk icon
452                          WriteMacInt32(pb + csParam, SonyDiskIconAddr);
453 <                        return noErr;
453 >                        break;
454  
455                  case 23:                // Get drive info
456                          if (info->num == 1)
457                                  WriteMacInt32(pb + csParam, 0x0004);    // Internal drive
458                          else
459                                  WriteMacInt32(pb + csParam, 0x0104);    // External drive
460 <                        return noErr;
460 >                        break;
461  
462 <                case 'SC': {    // Format and write to disk
462 >                case 0x5343:    // Format and write to disk ('SC'), used by DiskCopy
463                          if (!ReadMacInt8(info->status + dsDiskInPlace))
464 <                                return offLinErr;
465 <                        if (info->read_only)
466 <                                return wPrErr;
467 <
468 <                        void *data = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
469 <                        size_t actual = Sys_write(info->fh, data, 0, 2880*512);
470 <                        if (actual != 2880*512)
471 <                                return writErr;
472 <                        else
473 <                                return noErr;
453 <                }
464 >                                err = offLinErr;
465 >                        else if (info->read_only)
466 >                                err = wPrErr;
467 >                        else {
468 >                                void *data = Mac2HostAddr(ReadMacInt32(pb + csParam + 2));
469 >                                size_t actual = Sys_write(info->fh, data, 0, 2880*512);
470 >                                if (actual != 2880*512)
471 >                                        err = writErr;
472 >                        }
473 >                        break;
474  
475                  default:
476                          printf("WARNING: Unknown SonyControl(%d)\n", code);
477 <                        return controlErr;
477 >                        err = controlErr;
478 >                        break;
479          }
480 +
481 +        return set_dsk_err(err);
482   }
483  
484  
# Line 471 | Line 494 | int16 SonyStatus(uint32 pb, uint32 dce)
494          // Drive valid?
495          DriveInfo *info;
496          if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL)
497 <                return nsDrvErr;
497 >                return set_dsk_err(nsDrvErr);
498  
499 +        int16 err = noErr;
500          switch (code) {
501                  case 6:         // Return format list
502                          if (ReadMacInt16(pb + csParam) > 0) {
# Line 480 | Line 504 | int16 SonyStatus(uint32 pb, uint32 dce)
504                                  WriteMacInt16(pb + csParam, 1);         // 1 format
505                                  WriteMacInt32(adr, 2880);                       // 2880 sectors
506                                  WriteMacInt32(adr + 4, 0xd2120050);     // 2 heads, 18 secs/track, 80 tracks
483                                return noErr;
507                          } else
508 <                                return paramErr;
508 >                                err = paramErr;
509 >                        break;
510  
511                  case 8:         // Get drive status
512 <                        memcpy(Mac2HostAddr(pb + csParam), Mac2HostAddr(info->status), 22);
513 <                        return noErr;
512 >                        Mac2Mac_memcpy(pb + csParam, info->status, 22);
513 >                        break;
514  
515                  case 10:        // Get disk type
516                          WriteMacInt32(pb + csParam, ReadMacInt32(info->status + dsMFMDrive) & 0xffffff00 | 0xfe);
517 <                        return noErr;
517 >                        break;
518  
519 <                case 'DV':      // Duplicator version supported
519 >                case 0x4456: // Duplicator version supported ('DV')
520                          WriteMacInt16(pb + csParam, 0x0410);
521 <                        return noErr;
521 >                        break;
522  
523 <                case 'SC':      // Get address header format byte
523 >                case 0x5343: // Get address header format byte ('SC')
524                          WriteMacInt8(pb + csParam, 0x22);       // 512 bytes/sector
525 <                        return noErr;
525 >                        break;
526  
527                  default:
528                          printf("WARNING: Unknown SonyStatus(%d)\n", code);
529 <                        return statusErr;
529 >                        err = statusErr;
530 >                        break;
531          }
532 +
533 +        return set_dsk_err(err);
534 + }
535 +
536 +
537 + /*
538 + *  Driver interrupt routine (1Hz) - check for volumes to be mounted
539 + */
540 +
541 + void SonyInterrupt(void)
542 + {
543 +        if (!acc_run_called)
544 +                return;
545 +
546 +        mount_mountable_volumes();
547   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines