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

Comparing BasiliskII/src/AmigaOS/sys_amiga.cpp (file contents):
Revision 1.1 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.8 by jlachmann, 2002-06-23T08:27:05Z

# Line 1 | Line 1
1   /*
2   *  sys_amiga.cpp - System dependent routines, Amiga implementation
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 24 | Line 24
24   #include <devices/trackdisk.h>
25   #include <devices/scsidisk.h>
26   #include <resources/disk.h>
27 + #define __USE_SYSBASE
28   #include <proto/dos.h>
29   #include <proto/exec.h>
30   #include <proto/disk.h>
31 + #include <inline/dos.h>
32 + #include <inline/exec.h>
33 + #include <inline/disk.h>
34  
35   #include "sysdeps.h"
36   #include "main.h"
# Line 52 | Line 56 | struct file_handle {
56          ULONG block_size;               // Block size of device (must be a power of two)
57          bool is_nsd;                    // New style device?
58          bool does_64bit;                // Supports 64 bit trackdisk commands?
59 +        bool is_ejected;                // Volume has been (logically) ejected
60 +        bool is_2060scsi;               // Enable workaround for 2060scsi.device CD-ROM TD_READ bug
61   };
62  
63  
# Line 76 | Line 82 | void SysInit(void)
82          the_port = CreateMsgPort();
83          tmp_buf = (UBYTE *)AllocMem(TMP_BUF_SIZE, MEMF_CHIP | MEMF_PUBLIC);
84          if (the_port == NULL || tmp_buf == NULL) {
85 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
85 >                ErrorAlert(STR_NO_MEM_ERR);
86                  QuitEmulator();
87          }
88   }
# Line 89 | Line 95 | void SysInit(void)
95   void SysExit(void)
96   {
97          // Delete port and temporary buffer
98 <        if (the_port)
98 >        if (the_port) {
99                  DeleteMsgPort(the_port);
100 <        if (tmp_buf)
100 >                the_port = NULL;
101 >        }
102 >        if (tmp_buf) {
103                  FreeMem(tmp_buf, TMP_BUF_SIZE);
104 +                tmp_buf = NULL;
105 +        }
106   }
107  
108  
# Line 103 | Line 113 | void SysExit(void)
113  
114   void SysAddFloppyPrefs(void)
115   {
106 #if 0
116          for (int i=0; i<4; i++) {
117                  ULONG id = GetUnitID(i);
118                  if (id == DRT_150RPM) { // We need an HD drive
119                          char str[256];
120 <                        sprintf(str, "/dev/mfm.device/%d/0/0/1474560/512", i);
120 >                        sprintf(str, "/dev/mfm.device/%d/0/0/2880/512", i);
121                          PrefsAddString("floppy", str);
122                  }
123          }
115 #endif
124   }
125  
126  
# Line 208 | Line 216 | void *Sys_open(const char *name, bool re
216                          return NULL;
217  
218                  // Open device
219 <                if (OpenDevice((UBYTE *)dev_name, dev_unit, (struct IORequest *)io, dev_flags)) {
219 >                if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)io, dev_flags)) {
220                          D(bug(" couldn't open device\n"));
221                          DeleteIORequest(io);
222                          return NULL;
# Line 257 | Line 265 | void *Sys_open(const char *name, bool re
265                  fh->block_size = dev_bsize;
266                  fh->is_nsd = is_nsd;
267                  fh->does_64bit = does_64bit;
268 +                fh->is_ejected = false;
269 +                fh->is_2060scsi = (strcmp(dev_name, "2060scsi.device") == 0);
270                  return fh;
271          }
272   }
# Line 298 | Line 308 | void Sys_close(void *arg)
308  
309  
310   /*
311 + *  Send one I/O request, using 64-bit addressing if the device supports it
312 + */
313 +
314 + static loff_t send_io_request(file_handle *fh, bool writing, ULONG length, loff_t offset, APTR data)
315 + {
316 +        if (fh->does_64bit) {
317 +                fh->io->io_Command = writing ? NSCMD_TD_WRITE64 : NSCMD_TD_READ64;
318 +                fh->io->io_Actual = offset >> 32;
319 +        } else {
320 +                fh->io->io_Command = writing ? CMD_WRITE : CMD_READ;
321 +                fh->io->io_Actual = 0;
322 +        }
323 +        fh->io->io_Length = length;
324 +        fh->io->io_Offset = offset;
325 +        fh->io->io_Data = data;
326 +
327 +        if (fh->is_2060scsi && fh->block_size == 2048) {
328 +
329 +                // 2060scsi.device has serious problems reading CD-ROMs via TD_READ
330 +                static struct SCSICmd scsi;
331 +                const int SENSE_LENGTH = 256;
332 +                static UBYTE sense_buffer[SENSE_LENGTH];                // Buffer for autosense data
333 +                static UBYTE cmd_buffer[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
334 +
335 +                D(bug("send_io_request length=%lu  offset=%lu\n", length, (ULONG) offset));
336 +
337 +                memset(sense_buffer, 0, sizeof(sense_buffer));
338 +
339 +                scsi.scsi_Command = cmd_buffer;
340 +                scsi.scsi_CmdLength = sizeof(cmd_buffer);
341 +                scsi.scsi_SenseData = sense_buffer;
342 +                scsi.scsi_SenseLength = SENSE_LENGTH;
343 +                scsi.scsi_Flags = SCSIF_AUTOSENSE | (writing ? SCSIF_WRITE : SCSIF_READ);
344 +                scsi.scsi_Data = (UWORD  *) data;
345 +                scsi.scsi_Length = length;
346 +
347 +                ULONG block_offset = (ULONG) offset / fh->block_size;
348 +                ULONG block_length = length / fh->block_size;
349 +
350 +                cmd_buffer[2] = block_offset >> 24;
351 +                cmd_buffer[3] = block_offset >> 16;
352 +                cmd_buffer[4] = block_offset >> 8;
353 +                cmd_buffer[5] = block_offset & 0xff;
354 +
355 +                cmd_buffer[7] = block_length >> 8;
356 +                cmd_buffer[8] = block_length & 0xff;
357 +
358 +                fh->io->io_Command = HD_SCSICMD;
359 +                fh->io->io_Actual = 0;
360 +                fh->io->io_Offset = 0;
361 +                fh->io->io_Data = &scsi;
362 +                fh->io->io_Length = sizeof(scsi);
363 +
364 +                BYTE result = DoIO((struct IORequest *)fh->io);
365 +
366 +                if (result) {
367 +                        D(bug("send_io_request SCSI FAIL result=%lu\n", result));
368 +
369 +                        if (result == HFERR_BadStatus) {
370 +                                D(bug("send_io_request SCSI Status=%lu\n", scsi.scsi_Status));
371 +                                if (scsi.scsi_Status == 2) {
372 +                                        D(bug("send_io_request Sense Key=%02lx\n", sense_buffer[2] & 0x0f));
373 +                                        D(bug("send_io_request ASC=%02lx  ASCQ=%02lx\n", sense_buffer[12], sense_buffer[13]));
374 +                                }
375 +                        }
376 +                        return 0;
377 +                }
378 +
379 +                D(bug("send_io_request SCSI Actual=%lu\n", scsi.scsi_Actual));
380 +
381 +                if (scsi.scsi_Actual != length)
382 +                        return 0;
383 +
384 +                return scsi.scsi_Actual;
385 +
386 +        } else {
387 +
388 + //              if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != length)
389 +                if (DoIO((struct IORequest *)fh->io))
390 +                        {
391 +                        D(bug("send_io_request/%ld: Actual=%lu  length=%lu  Err=%ld\n", __LINE__, fh->io->io_Actual, length, fh->io->io_Error));
392 +                        return 0;
393 +                        }
394 +                return fh->io->io_Actual;
395 +        }
396 + }
397 +
398 +
399 + /*
400   *  Read "length" bytes from file/device, starting at "offset", to "buffer",
401   *  returns number of bytes read (or 0)
402   */
# Line 306 | Line 405 | size_t Sys_read(void *arg, void *buffer,
405   {
406          file_handle *fh = (file_handle *)arg;
407          if (!fh)
408 +                {
409 +                D(bug("Sys_read/%ld return 0\n", __LINE__));
410                  return 0;
411 +                }
412 +
413 +        D(bug("Sys_read/%ld length=%ld\n", __LINE__, length));
414  
415          // File or device?
416          if (fh->is_file) {
417  
418                  // File, seek to position
419                  if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1)
420 +                        {
421 +                        D(bug("Sys_read/%ld return 0\n", __LINE__));
422                          return 0;
423 +                        }
424  
425                  // Read data
426                  LONG actual = Read(fh->f, buffer, length);
427                  if (actual == -1)
428 +                        {
429 +                        D(bug("Sys_read/%ld return 0\n", __LINE__));
430                          return 0;
431 +                        }
432                  else
433 +                        {
434 +                        D(bug("Sys_read/%ld return %ld\n", __LINE__, actual));
435                          return actual;
436 +                        }
437  
438          } else {
439  
440 <                // Device, pre-read (partial read of first block) neccessary?
440 >                // Device, pre-read (partial read of first block) necessary?
441                  loff_t pos = offset + fh->start_byte;
442                  size_t actual = 0;
443                  uint32 pre_offset = pos % fh->block_size;
444                  if (pre_offset) {
445  
446                          // Yes, read one block
447 <                        fh->io->io_Command = CMD_READ;
448 <                        fh->io->io_Length = fh->block_size;
449 <                        fh->io->io_Offset = pos - pre_offset;
337 <                        fh->io->io_Data = tmp_buf;
338 <                        if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != fh->block_size)
447 >                        if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0)
448 >                                {
449 >                                D(bug("Sys_read/%ld return %ld\n", __LINE__, 0));
450                                  return 0;
451 +                                }
452  
453                          // Copy data to destination buffer
454                          size_t pre_length = fh->block_size - pre_offset;
# Line 356 | Line 468 | size_t Sys_read(void *arg, void *buffer,
468  
469                          // Yes, read blocks
470                          size_t main_length = length & ~(fh->block_size - 1);
471 <                        fh->io->io_Command = CMD_READ;
472 <                        fh->io->io_Length = main_length;
473 <                        fh->io->io_Offset = pos;
362 <                        fh->io->io_Data = buffer;
363 <                        if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != main_length)
471 >                        if (send_io_request(fh, false, main_length, pos, buffer) == 0)
472 >                                {
473 >                                D(bug("Sys_read/%ld return %ld\n", __LINE__, 0));
474                                  return 0;
475 +                                }
476  
477                          // Adjust data pointers
478                          buffer = (uint8 *)buffer + main_length;
# Line 370 | Line 481 | size_t Sys_read(void *arg, void *buffer,
481                          actual += main_length;
482                  }
483  
484 <                // Post-read (partial read of last block) neccessary?
484 >                // Post-read (partial read of last block) necessary?
485                  if (length) {
486  
487                          // Yes, read one block
488 <                        fh->io->io_Command = CMD_READ;
489 <                        fh->io->io_Length = fh->block_size;
490 <                        fh->io->io_Offset = pos;
380 <                        fh->io->io_Data = tmp_buf;
381 <                        if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != fh->block_size)
488 >                        if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0)
489 >                                {
490 >                                D(bug("Sys_read/%ld return %ld\n", __LINE__, 0));
491                                  return 0;
492 +                                }
493  
494                          // Copy data to destination buffer
495                          memcpy(buffer, tmp_buf, length);
496                          actual += length;
497                  }
498  
499 +                D(bug("Sys_read/%ld return %ld\n", __LINE__, actual));
500                  return actual;
501          }
502   }
# Line 400 | Line 511 | size_t Sys_write(void *arg, void *buffer
511   {
512          file_handle *fh = (file_handle *)arg;
513          if (!fh)
514 +                {
515 +                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
516                  return 0;
517 +                }
518 +
519 +        D(bug("Sys_write/%ld length=%ld\n", __LINE__, length));
520  
521          // File or device?
522          if (fh->is_file) {
523  
524 <                // File, seek to position if neccessary
524 >                // File, seek to position if necessary
525                  if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1)
526 +                        {
527 +                        D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
528                          return 0;
529 +                        }
530  
531                  // Write data
532                  LONG actual = Write(fh->f, buffer, length);
533                  if (actual == -1)
534 +                        {
535 +                        D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
536                          return 0;
537 +                        }
538                  else
539 +                        {
540 +                        D(bug("Sys_write/%ld return %ld\n", __LINE__, actual));
541                          return actual;
542 +                        }
543  
544          } else {
545  
546 <                // Device, write data
547 <                fh->io->io_Command = CMD_WRITE;
548 <                fh->io->io_Length = length;
549 <                fh->io->io_Offset = offset + fh->start_byte;
550 <                fh->io->io_Data = buffer;
551 <                if (DoIO((struct IORequest *)fh->io))
552 <                        return 0;
553 <                else
554 <                        return fh->io->io_Actual;
546 >                // Device, pre-write (partial write of first block) necessary
547 >                loff_t pos = offset + fh->start_byte;
548 >                size_t actual = 0;
549 >                uint32 pre_offset = pos % fh->block_size;
550 >                if (pre_offset) {
551 >
552 >                        // Yes, read one block
553 >                        if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0)
554 >                                {
555 >                                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
556 >                                return 0;
557 >                                }
558 >
559 >                        // Copy data from source buffer
560 >                        size_t pre_length = fh->block_size - pre_offset;
561 >                        if (pre_length > length)
562 >                                pre_length = length;
563 >                        memcpy(tmp_buf + pre_offset, buffer, pre_length);
564 >
565 >                        // Write block back
566 >                        if (send_io_request(fh, true, fh->block_size, pos - pre_offset, tmp_buf) == 0)
567 >                                {
568 >                                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
569 >                                return 0;
570 >                                }
571 >
572 >                        // Adjust data pointers
573 >                        buffer = (uint8 *)buffer + pre_length;
574 >                        pos += pre_length;
575 >                        length -= pre_length;
576 >                        actual += pre_length;
577 >                }
578 >
579 >                // Main write (complete writes of middle blocks) possible?
580 >                if (length >= fh->block_size) {
581 >
582 >                        // Yes, write blocks
583 >                        size_t main_length = length & ~(fh->block_size - 1);
584 >                        if (send_io_request(fh, true, main_length, pos, buffer) == 0)
585 >                                {
586 >                                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
587 >                                return 0;
588 >                                }
589 >
590 >                        // Adjust data pointers
591 >                        buffer = (uint8 *)buffer + main_length;
592 >                        pos += main_length;
593 >                        length -= main_length;
594 >                        actual += main_length;
595 >                }
596 >
597 >                // Post-write (partial write of last block) necessary?
598 >                if (length) {
599 >
600 >                        // Yes, read one block
601 >                        if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0)
602 >                                {
603 >                                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
604 >                                return 0;
605 >                                }
606 >
607 >                        // Copy data from source buffer
608 >                        memcpy(buffer, tmp_buf, length);
609 >
610 >                        // Write block back
611 >                        if (send_io_request(fh, true, fh->block_size, pos, tmp_buf) == 0)
612 >                                {
613 >                                D(bug("Sys_write/%ld return %ld\n", __LINE__, 0));
614 >                                return 0;
615 >                                }
616 >                        actual += length;
617 >                }
618 >
619 >                D(bug("Sys_write/%ld return %ld\n", __LINE__, actual));
620 >                return actual;
621          }
622   }
623  
# Line 468 | Line 659 | void SysEject(void *arg)
659                  fh->io->io_Command = TD_EJECT;
660                  fh->io->io_Length = 1;
661                  DoIO((struct IORequest *)fh->io);
662 +
663 +                fh->is_ejected = true;
664          }
665   }
666  
# Line 505 | Line 698 | bool SysIsReadOnly(void *arg)
698          } else {
699  
700                  // Device, check write protection
508                fh->io->io_Flags = IOF_QUICK;
701                  fh->io->io_Command = TD_PROTSTATUS;
702 <                BeginIO((struct IORequest *)fh->io);
702 >                DoIO((struct IORequest *)fh->io);
703                  if (fh->io->io_Actual)
704                          return true;
705                  else
# Line 545 | Line 737 | bool SysIsDiskInserted(void *arg)
737          else {
738  
739                  // Check medium status
548                fh->io->io_Flags = IOF_QUICK;
740                  fh->io->io_Command = TD_CHANGESTATE;
741                  fh->io->io_Actual = 0;
742 <                BeginIO((struct IORequest *)fh->io);
743 <                return fh->io->io_Actual == 0;
742 >                DoIO((struct IORequest *)fh->io);
743 >                bool inserted = (fh->io->io_Actual == 0);
744 >
745 >                if (!inserted) {
746 >                        // Disk was ejected and has now been taken out
747 >                        fh->is_ejected = false;
748 >                }
749 >
750 >                if (fh->is_ejected) {
751 >                        // Disk was ejected but has not yet been taken out, report it as
752 >                        // no longer in the drive
753 >                        return false;
754 >                } else
755 >                        return inserted;
756          }
757   }
758  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines