/[gxemul]/upstream/0.3.7/src/diskimage.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /upstream/0.3.7/src/diskimage.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: diskimage.c,v 1.84 2005/04/17 00:15:24 debug Exp $   *  $Id: diskimage.c,v 1.102 2005/11/21 09:17:25 debug Exp $
29   *   *
30   *  Disk image support.   *  Disk image support.
31   *   *
# Line 36  Line 36 
36   *         that return feof (which results in a filemark).  This is probably   *         that return feof (which results in a filemark).  This is probably
37   *         trivial to fix, but I don't feel like it right now.   *         trivial to fix, but I don't feel like it right now.
38   *   *
39   *  TODO:  Non-SCSI disk images?   *  TODO:  diskimage_remove()? This would be useful for floppies in PC-style
40   *   *         machines, where disks may need to be swapped during boot etc.
  *  TODO:  diskimage_remove() ?  
  *         Actually test diskimage_access() to see that it works.  
41   */   */
42    
43  #include <stdio.h>  #include <stdio.h>
# Line 55  Line 53 
53  #include "misc.h"  #include "misc.h"
54    
55    
56  extern int quiet_mode;  /*  #define debug fatal  */
57    
58  extern int single_step;  extern int single_step;
59    
60    static char *diskimage_types[] = DISKIMAGE_TYPES;
61    
62  static struct scsi_transfer *first_free_scsi_transfer_alloc = NULL;  static struct scsi_transfer *first_free_scsi_transfer_alloc = NULL;
63    
# Line 209  void scsi_transfer_allocbuf(size_t *lenp Line 209  void scsi_transfer_allocbuf(size_t *lenp
209  /*  /*
210   *  diskimage_exist():   *  diskimage_exist():
211   *   *
212   *  Returns 1 if the specified SCSI id exists, 0 otherwise.   *  Returns 1 if the specified disk id (for a specific type) exists, 0
213     *  otherwise.
214   */   */
215  int diskimage_exist(struct machine *machine, int scsi_id)  int diskimage_exist(struct machine *machine, int id, int type)
216  {  {
217          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
218    
219          while (d != NULL) {          while (d != NULL) {
220                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
221                          return 1;                          return 1;
222                  d = d->next;                  d = d->next;
223          }          }
# Line 256  static void diskimage_recalc_size(struct Line 257  static void diskimage_recalc_size(struct
257    
258          d->total_size = size;          d->total_size = size;
259          d->ncyls = d->total_size / 1048576;          d->ncyls = d->total_size / 1048576;
260    
261            /*  TODO: There is a mismatch between d->ncyls and d->cylinders,
262                SCSI-based stuff usually doesn't care.  TODO: Fix this.  */
263  }  }
264    
265    
266  /*  /*
267   *  diskimage_getsize():   *  diskimage_getsize():
268   *   *
269   *  Returns -1 if the specified SCSI id does not exists, otherwise   *  Returns -1 if the specified disk id/type does not exists, otherwise
270   *  the size of the disk image is returned.   *  the size of the disk image is returned.
271   */   */
272  int64_t diskimage_getsize(struct machine *machine, int scsi_id)  int64_t diskimage_getsize(struct machine *machine, int id, int type)
273  {  {
274          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
275    
276          while (d != NULL) {          while (d != NULL) {
277                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
278                          return d->total_size;                          return d->total_size;
279                  d = d->next;                  d = d->next;
280          }          }
# Line 279  int64_t diskimage_getsize(struct machine Line 283  int64_t diskimage_getsize(struct machine
283    
284    
285  /*  /*
286     *  diskimage_getchs():
287     *
288     *  Returns the current CHS values of a disk image.
289     */
290    void diskimage_getchs(struct machine *machine, int id, int type,
291            int *c, int *h, int *s)
292    {
293            struct diskimage *d = machine->first_diskimage;
294    
295            while (d != NULL) {
296                    if (d->type == type && d->id == id) {
297                            *c = d->cylinders;
298                            *h = d->heads;
299                            *s = d->sectors_per_track;
300                            return;
301                    }
302                    d = d->next;
303            }
304            fatal("diskimage_getchs(): disk id %i (type %i) not found?\n",
305                id, diskimage_types[type]);
306            exit(1);
307    }
308    
309    
310    /*
311   *  diskimage__return_default_status_and_message():   *  diskimage__return_default_status_and_message():
312   *   *
313   *  Set the status and msg_in parts of a scsi_transfer struct   *  Set the status and msg_in parts of a scsi_transfer struct
# Line 381  static size_t diskimage_access__cdrom(st Line 410  static size_t diskimage_access__cdrom(st
410  static int diskimage__internal_access(struct diskimage *d, int writeflag,  static int diskimage__internal_access(struct diskimage *d, int writeflag,
411          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
412  {  {
413          size_t lendone;          ssize_t lendone;
414          int res;          int res;
415    
416          if (buf == NULL) {          if (buf == NULL) {
# Line 447  static int diskimage__internal_access(st Line 476  static int diskimage__internal_access(st
476   *      1 if otherwise ok,   *      1 if otherwise ok,
477   *      0 on error.   *      0 on error.
478   */   */
479  int diskimage_scsicommand(struct cpu *cpu, int scsi_id,  int diskimage_scsicommand(struct cpu *cpu, int id, int type,
480          struct scsi_transfer *xferp)          struct scsi_transfer *xferp)
481  {  {
482          int retlen, i;          char namebuf[16];
483            int retlen, i, q;
484          uint64_t size;          uint64_t size;
485          int64_t ofs;          int64_t ofs;
486          int pagecode;          int pagecode;
# Line 464  int diskimage_scsicommand(struct cpu *cp Line 494  int diskimage_scsicommand(struct cpu *cp
494    
495          d = machine->first_diskimage;          d = machine->first_diskimage;
496          while (d != NULL) {          while (d != NULL) {
497                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
498                          break;                          break;
499                  d = d->next;                  d = d->next;
500          }          }
501          if (d == NULL) {          if (d == NULL) {
502                  fprintf(stderr, "[ diskimage_scsicommand(): SCSI disk"                  fprintf(stderr, "[ diskimage_scsicommand(): %s "
503                      " with id %i not connected? ]\n", scsi_id);                      " id %i not connected? ]\n", diskimage_types[type], id);
504          }          }
505    
506          if (xferp->cmd == NULL) {          if (xferp->cmd == NULL) {
# Line 485  int diskimage_scsicommand(struct cpu *cp Line 515  int diskimage_scsicommand(struct cpu *cp
515          }          }
516    
517          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",
518              scsi_id, xferp->cmd[0]);              id, xferp->cmd[0]);
519    
520  #if 0  #if 0
521          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",
522              scsi_id, xferp->cmd[0], xferp->cmd_len);              id, xferp->cmd[0], xferp->cmd_len);
523          for (i=0; i<xferp->cmd_len; i++)          for (i=0; i<xferp->cmd_len; i++)
524                  fatal(" %02x", xferp->cmd[i]);                  fatal(" %02x", xferp->cmd[i]);
525          fatal("\n");          fatal("\n");
# Line 504  if (xferp->cmd_len > 7 && xferp->cmd[5] Line 534  if (xferp->cmd_len > 7 && xferp->cmd[5]
534                  f = fopen("scsi_log.txt", "w");                  f = fopen("scsi_log.txt", "w");
535          if (f != NULL) {          if (f != NULL) {
536                  int i;                  int i;
537                  fprintf(f, "id=%i cmd =", scsi_id);                  fprintf(f, "id=%i cmd =", id);
538                  for (i=0; i<xferp->cmd_len; i++)                  for (i=0; i<xferp->cmd_len; i++)
539                          fprintf(f, " %02x", xferp->cmd[i]);                          fprintf(f, " %02x", xferp->cmd[i]);
540                  fprintf(f, "\n");                  fprintf(f, "\n");
# Line 560  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 590  xferp->data_in[4] = 0x2c - 4;  /*  Additi
590                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */
591                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */
592    
593                  /*  These must be padded with spaces:  */                  /*  These are padded with spaces:  */
594                  memcpy(xferp->data_in+8,  "FAKE    ", 8);  
595                  memcpy(xferp->data_in+16, "DISK            ", 16);                  memcpy(xferp->data_in+8,  "GXemul  ", 8);
596                  memcpy(xferp->data_in+32, "V0.0", 4);                  if (diskimage_getname(cpu->machine, id,
597                        type, namebuf, sizeof(namebuf))) {
598                            int i;
599                            for (i=0; i<sizeof(namebuf); i++)
600                                    if (namebuf[i] == 0) {
601                                            for (; i<sizeof(namebuf); i++)
602                                                    namebuf[i] = ' ';
603                                            break;
604                                    }
605                            memcpy(xferp->data_in+16, namebuf, 16);
606                    } else
607                            memcpy(xferp->data_in+16, "DISK            ", 16);
608                    memcpy(xferp->data_in+32, "0   ", 4);
609    
610                  /*                  /*
611                   *  Some Ultrix kernels want specific responses from                   *  Some Ultrix kernels want specific responses from
# Line 582  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 624  xferp->data_in[4] = 0x2c - 4;  /*  Additi
624                  if (d->is_a_cdrom) {                  if (d->is_a_cdrom) {
625                          xferp->data_in[0] = 0x05;  /*  0x05 = CD-ROM  */                          xferp->data_in[0] = 0x05;  /*  0x05 = CD-ROM  */
626                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */
627                          memcpy(xferp->data_in+16, "CD-ROM          ", 16);                          /*  memcpy(xferp->data_in+16, "CD-ROM          ", 16);*/
628    
629                          if (machine->machine_type == MACHINE_DEC) {                          if (machine->machine_type == MACHINE_DEC) {
630                                  /*  SONY, CD-ROM:  */                                  /*  SONY, CD-ROM:  */
# Line 595  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 637  xferp->data_in[4] = 0x2c - 4;  /*  Additi
637                                  memcpy(xferp->data_in+16,                                  memcpy(xferp->data_in+16,
638                                      "RRD42   (C) DEC ", 16);                                      "RRD42   (C) DEC ", 16);
639                                  memcpy(xferp->data_in+32, "4.5d", 4);                                  memcpy(xferp->data_in+32, "4.5d", 4);
640                          } else {                          } else if (machine->machine_type == MACHINE_ARC) {
641                                  /*  NEC, CD-ROM:  */                                  /*  NEC, CD-ROM:  */
642                                  memcpy(xferp->data_in+8, "NEC     ", 8);                                  memcpy(xferp->data_in+8, "NEC     ", 8);
643                                  memcpy(xferp->data_in+16,                                  memcpy(xferp->data_in+16,
# Line 665  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 707  xferp->data_in[4] = 0x2c - 4;  /*  Additi
707                  break;                  break;
708    
709          case SCSICMD_MODE_SENSE:          case SCSICMD_MODE_SENSE:
710            case SCSICMD_MODE_SENSE10:      
711                  debug("MODE_SENSE");                  debug("MODE_SENSE");
712                    q = 4; retlen = xferp->cmd[4];
713                  if (xferp->cmd_len != 6)                  switch (xferp->cmd_len) {
714                          fatal(" (unimplemented mode_sense len=%i)",                  case 6: break;
715                    case 10:q = 8;
716                            retlen = xferp->cmd[7] * 256 + xferp->cmd[8];
717                            break;
718                    default:fatal(" (unimplemented mode_sense len=%i)",
719                              xferp->cmd_len);                              xferp->cmd_len);
720                    }
                 retlen = xferp->cmd[4];  
721    
722                  /*                  /*
723                   *  NOTE/TODO: This code doesn't handle too short retlens                   *  NOTE/TODO: This code doesn't handle too short retlens
# Line 694  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 740  xferp->data_in[4] = 0x2c - 4;  /*  Additi
740    
741                  pagecode = xferp->cmd[2] & 0x3f;                  pagecode = xferp->cmd[2] & 0x3f;
742    
743                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", scsi_id, pagecode);                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", id, pagecode);
744    
745                  /*  4 bytes of header for 6-byte command,                  /*  4 bytes of header for 6-byte command,
746                      8 bytes of header for 10-byte command.  */                      8 bytes of header for 10-byte command.  */
# Line 706  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 752  xferp->data_in[4] = 0x2c - 4;  /*  Additi
752                  xferp->data_in[3] = 8 * 1;      /*  block descriptor                  xferp->data_in[3] = 8 * 1;      /*  block descriptor
753                                                      length: 1 page (?)  */                                                      length: 1 page (?)  */
754    
755                  /*  TODO: update this when implementing 10-byte commands:  */                  xferp->data_in[q+0] = 0x00;     /*  density code  */
756                  xferp->data_in[4] = 0x00;       /*  density code  */                  xferp->data_in[q+1] = 0;        /*  nr of blocks, high  */
757                  xferp->data_in[5] = 0;          /*  nr of blocks, high  */                  xferp->data_in[q+2] = 0;        /*  nr of blocks, mid  */
758                  xferp->data_in[6] = 0;          /*  nr of blocks, mid  */                  xferp->data_in[q+3] = 0;        /*  nr of blocks, low */
759                  xferp->data_in[7] = 0;          /*  nr of blocks, low */                  xferp->data_in[q+4] = 0x00;     /*  reserved  */
760                  xferp->data_in[8] = 0x00;       /*  reserved  */                  xferp->data_in[q+5] = (d->logical_block_size >> 16) & 255;
761                  xferp->data_in[9] = (d->logical_block_size >> 16) & 255;                  xferp->data_in[q+6] = (d->logical_block_size >> 8) & 255;
762                  xferp->data_in[10] = (d->logical_block_size >> 8) & 255;                  xferp->data_in[q+7] = d->logical_block_size & 255;
763                  xferp->data_in[11] = d->logical_block_size & 255;                  q += 8;
764    
765                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
766    
# Line 726  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 772  xferp->data_in[4] = 0x2c - 4;  /*  Additi
772                          /*  TODO: Nothing here?  */                          /*  TODO: Nothing here?  */
773                          break;                          break;
774                  case 1:         /*  read-write error recovery page  */                  case 1:         /*  read-write error recovery page  */
775                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
776                          xferp->data_in[12 + 1] = 10;                          xferp->data_in[q + 1] = 10;
777                          break;                          break;
778                  case 3:         /*  format device page  */                  case 3:         /*  format device page  */
779                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
780                          xferp->data_in[12 + 1] = 22;                          xferp->data_in[q + 1] = 22;
781    
782                          /*  10,11 = sectors per track  */                          /*  10,11 = sectors per track  */
783                          xferp->data_in[12 + 10] = 0;                          xferp->data_in[q + 10] = 0;
784                          xferp->data_in[12 + 11] = 1;    /*  TODO  */                          xferp->data_in[q + 11] = d->sectors_per_track;
785    
786                          /*  12,13 = physical sector size  */                          /*  12,13 = physical sector size  */
787                          xferp->data_in[12 + 12] =                          xferp->data_in[q + 12] =
788                              (d->logical_block_size >> 8) & 255;                              (d->logical_block_size >> 8) & 255;
789                          xferp->data_in[12 + 13] = d->logical_block_size & 255;                          xferp->data_in[q + 13] = d->logical_block_size & 255;
790                          break;                          break;
791                  case 4:         /*  rigid disk geometry page  */                  case 4:         /*  rigid disk geometry page  */
792                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
793                          xferp->data_in[12 + 1] = 22;                          xferp->data_in[q + 1] = 22;
794                          xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255;                          xferp->data_in[q + 2] = (d->ncyls >> 16) & 255;
795                          xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255;                          xferp->data_in[q + 3] = (d->ncyls >> 8) & 255;
796                          xferp->data_in[12 + 4] = d->ncyls & 255;                          xferp->data_in[q + 4] = d->ncyls & 255;
797                          xferp->data_in[12 + 5] = 15;    /*  nr of heads  */                          xferp->data_in[q + 5] = d->heads;
798    
799                          xferp->data_in[12 + 20] = (d->rpms >> 8) & 255;                          xferp->data_in[q + 20] = (d->rpms >> 8) & 255;
800                          xferp->data_in[12 + 21] = d->rpms & 255;                          xferp->data_in[q + 21] = d->rpms & 255;
801                          break;                          break;
802                  case 5:         /*  flexible disk page  */                  case 5:         /*  flexible disk page  */
803                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
804                          xferp->data_in[12 + 1] = 0x1e;                          xferp->data_in[q + 1] = 0x1e;
805    
806                          /*  2,3 = transfer rate  */                          /*  2,3 = transfer rate  */
807                          xferp->data_in[12 + 2] = ((5000) >> 8) & 255;                          xferp->data_in[q + 2] = ((5000) >> 8) & 255;
808                          xferp->data_in[12 + 3] = (5000) & 255;                          xferp->data_in[q + 3] = (5000) & 255;
809    
810                          xferp->data_in[12 + 4] = 2;    /*  nr of heads  */                          xferp->data_in[q + 4] = d->heads;
811                          xferp->data_in[12 + 5] = 18;   /*  sectors per track  */                          xferp->data_in[q + 5] = d->sectors_per_track;
812    
813                          /*  6,7 = data bytes per sector  */                          /*  6,7 = data bytes per sector  */
814                          xferp->data_in[12 + 6] = (d->logical_block_size >> 8)                          xferp->data_in[q + 6] = (d->logical_block_size >> 8)
815                              & 255;                              & 255;
816                          xferp->data_in[12 + 7] = d->logical_block_size & 255;                          xferp->data_in[q + 7] = d->logical_block_size & 255;
817    
818                          xferp->data_in[12 + 8] = (d->ncyls >> 8) & 255;                          xferp->data_in[q + 8] = (d->ncyls >> 8) & 255;
819                          xferp->data_in[12 + 9] = d->ncyls & 255;                          xferp->data_in[q + 9] = d->ncyls & 255;
820    
821                          xferp->data_in[12 + 28] = (d->rpms >> 8) & 255;                          xferp->data_in[q + 28] = (d->rpms >> 8) & 255;
822                          xferp->data_in[12 + 29] = d->rpms & 255;                          xferp->data_in[q + 29] = d->rpms & 255;
823                          break;                          break;
824                  default:                  default:
825                          fatal("[ MODE_SENSE for page %i is not yet "                          fatal("[ MODE_SENSE for page %i is not yet "
# Line 819  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 865  xferp->data_in[4] = 0x2c - 4;  /*  Additi
865                          ofs = d->tape_offset;                          ofs = d->tape_offset;
866    
867                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"
868                              ", ofs=%lli ]\n", scsi_id, d->tape_filenr,                              ", ofs=%lli ]\n", id, d->tape_filenr,
869                              xferp->cmd[1], (int)size, (long long)ofs);                              xferp->cmd[1], (int)size, (long long)ofs);
870                  } else {                  } else {
871                          if (xferp->cmd[0] == SCSICMD_READ) {                          if (xferp->cmd[0] == SCSICMD_READ) {
# Line 882  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 928  xferp->data_in[4] = 0x2c - 4;  /*  Additi
928                   *   be set to NO SENSE"..                   *   be set to NO SENSE"..
929                   */                   */
930                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {
931                          debug(" feof id=%i\n", scsi_id);                          debug(" feof id=%i\n", id);
932                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */
933    
934                          d->filemark = 1;                          d->filemark = 1;
# Line 891  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 937  xferp->data_in[4] = 0x2c - 4;  /*  Additi
937                              xferp->data_in, size);                              xferp->data_in, size);
938    
939                  if (d->is_a_tape && d->f != NULL)                  if (d->is_a_tape && d->f != NULL)
940                          d->tape_offset = ftell(d->f);                          d->tape_offset = ftello(d->f);
941    
942                  /*  TODO: other errors?  */                  /*  TODO: other errors?  */
943                  break;                  break;
# Line 978  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1024  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1024                  if (xferp->cmd_len != 6)                  if (xferp->cmd_len != 6)
1025                          debug(" (weird len=%i)", xferp->cmd_len);                          debug(" (weird len=%i)", xferp->cmd_len);
1026    
1027                  for (i=0; i<xferp->cmd_len ; i++)                  for (i=0; i<xferp->cmd_len; i++)
1028                          debug(" %02x", xferp->cmd[i]);                          debug(" %02x", xferp->cmd[i]);
1029    
1030                  /*  TODO: actualy care about cmd[]  */                  /*  TODO: actualy care about cmd[]  */
# Line 1187  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1233  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1233                  scsi_transfer_allocbuf(&xferp->data_in_len,                  scsi_transfer_allocbuf(&xferp->data_in_len,
1234                      &xferp->data_in, retlen, 1);                      &xferp->data_in, retlen, 1);
1235    
1236                  /*  TODO  */                  xferp->data_in[0] = 0;
1237                    xferp->data_in[1] = 10;
1238                    xferp->data_in[2] = 0;          /*  First track.  */
1239                    xferp->data_in[3] = 0;          /*  Last track.  */
1240    
1241                    /*  Track 0 data:  */
1242                    xferp->data_in[4] = 0x00;       /*  Reserved.  */
1243                    xferp->data_in[5] = 0x04;       /*  ADR + CTRL:
1244                                                        Data, not audio  */
1245                    xferp->data_in[6] = 0x00;       /*  Track nr  */
1246                    xferp->data_in[7] = 0x00;       /*  Reserved  */
1247                    /*  8..11 = absolute CDROM address  */
1248    
1249                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1250                  break;                  break;
# Line 1240  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1297  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1297                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1298                  break;                  break;
1299    
1300          case 0x1e:          case SCSICMD_PREVENT_ALLOW_REMOVE:
1301                  debug("[ SCSI 0x%02x: TODO ]\n", xferp->cmd[0]);                  debug("[ SCSI 0x%02x Prevent/allow medium removal: "
1302                        "TODO ]\n", xferp->cmd[0]);
                 /*  TODO  */  
1303    
1304                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1305                  break;                  break;
# Line 1275  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1331  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1331                      &xferp->data_in, retlen, 1);                      &xferp->data_in, retlen, 1);
1332    
1333                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1334    
1335                  break;                  break;
1336    
1337          default:          default:
1338                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",
1339                      xferp->cmd[0], scsi_id);                      xferp->cmd[0], id);
1340                  exit(1);                  exit(1);
1341          }          }
1342          debug(" ]\n");          debug(" ]\n");
# Line 1295  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1352  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1352   *   *
1353   *  Returns 1 if the access completed successfully, 0 otherwise.   *  Returns 1 if the access completed successfully, 0 otherwise.
1354   */   */
1355  int diskimage_access(struct machine *machine, int scsi_id, int writeflag,  int diskimage_access(struct machine *machine, int id, int type, int writeflag,
1356          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
1357  {  {
1358          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1359    
         /*  
          *  TODO: How about mixing SCSI, IDE, and FLOPPY in one  
          *        emulated machine?  
          */  
   
1360          while (d != NULL) {          while (d != NULL) {
1361                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
1362                          break;                          break;
1363                  d = d->next;                  d = d->next;
1364          }          }
1365    
1366          if (d == NULL) {          if (d == NULL) {
1367                  fatal("[ diskimage_access(): ERROR: trying to access a "                  fatal("[ diskimage_access(): ERROR: trying to access a "
1368                      "non-existant SCSI disk image (%i)\n", scsi_id);                      "non-existant %s disk image (id %i)\n",
1369                        diskimage_types[type], id);
1370                  return 0;                  return 0;
1371          }          }
1372    
# Line 1328  int diskimage_access(struct machine *mac Line 1381  int diskimage_access(struct machine *mac
1381   *  The filename may be prefixed with one or more modifiers, followed   *  The filename may be prefixed with one or more modifiers, followed
1382   *  by a colon.   *  by a colon.
1383   *   *
1384   *      b       specifies that this is the boot device   *      b       specifies that this is a bootable device
1385   *      c       CD-ROM (instead of normal SCSI DISK)   *      c       CD-ROM (instead of a normal DISK)
1386   *      d       DISK (this is the default)   *      d       DISK (this is the default)
1387   *      f       FLOPPY (instead of SCSI)   *      f       FLOPPY (instead of SCSI)
1388     *      gH;S;   set geometry (H=heads, S=sectors per track, cylinders are
1389     *              automatically calculated). (This is ignored for floppies.)
1390   *      i       IDE (instead of SCSI)   *      i       IDE (instead of SCSI)
1391   *      r       read-only (don't allow changes to the file)   *      r       read-only (don't allow changes to the file)
1392   *      s       SCSI (this is the default)   *      s       SCSI (this is the default)
# Line 1344  int diskimage_access(struct machine *mac Line 1399  int diskimage_access(struct machine *mac
1399  int diskimage_add(struct machine *machine, char *fname)  int diskimage_add(struct machine *machine, char *fname)
1400  {  {
1401          struct diskimage *d, *d2;          struct diskimage *d, *d2;
1402          int id = 0;          int id = 0, override_heads=0, override_spt=0;
1403            int64_t bytespercyl;
1404          char *cp;          char *cp;
1405          int prefix_b = 0;          int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
1406          int prefix_c = 0;          int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id = -1;
         int prefix_d = 0;  
         int prefix_f = 0;  
         int prefix_i = 0;  
         int prefix_r = 0;  
         int prefix_s = 0;  
         int prefix_t = 0;  
         int prefix_id = -1;  
1407    
1408          if (fname == NULL) {          if (fname == NULL) {
1409                  fprintf(stderr, "diskimage_add(): NULL ptr\n");                  fprintf(stderr, "diskimage_add(): NULL ptr\n");
# Line 1389  int diskimage_add(struct machine *machin Line 1438  int diskimage_add(struct machine *machin
1438                          case 'f':                          case 'f':
1439                                  prefix_f = 1;                                  prefix_f = 1;
1440                                  break;                                  break;
1441                            case 'g':
1442                                    prefix_g = 1;
1443                                    override_heads = atoi(fname);
1444                                    while (*fname != '\0' && *fname != ';')
1445                                            fname ++;
1446                                    if (*fname == ';')
1447                                            fname ++;
1448                                    override_spt = atoi(fname);
1449                                    while (*fname != '\0' && *fname != ';' &&
1450                                        *fname != ':')
1451                                            fname ++;
1452                                    if (*fname == ';')
1453                                            fname ++;
1454                                    if (override_heads < 1 ||
1455                                        override_spt < 1) {
1456                                            fatal("Bad geometry: heads=%i "
1457                                                "spt=%i\n", override_heads,
1458                                                override_spt);
1459                                            exit(1);
1460                                    }
1461                                    break;
1462                          case 'i':                          case 'i':
1463                                  prefix_i = 1;                                  prefix_i = 1;
1464                                  break;                                  break;
# Line 1411  int diskimage_add(struct machine *machin Line 1481  int diskimage_add(struct machine *machin
1481                  }                  }
1482          }          }
1483    
         /*  Calculate which ID to use:  */  
         if (prefix_id == -1) {  
                 int free = 0, collision = 1;  
   
                 while (collision) {  
                         collision = 0;  
                         d = machine->first_diskimage;  
                         while (d != NULL) {  
                                 if (d->id == free) {  
                                         collision = 1;  
                                         break;  
                                 }  
                                 d = d->next;  
                         }  
                         if (!collision)  
                                 id = free;  
                         else  
                                 free ++;  
                 }  
         } else {  
                 id = prefix_id;  
   
                 d = machine->first_diskimage;  
                 while (d != NULL) {  
                         if (d->id == id) {  
                                 fprintf(stderr, "disk image SCSI id %i "  
                                     "already in use\n", id);  
                                 exit(1);  
                         }  
                         d = d->next;  
                 }  
         }  
   
1484          /*  Allocate a new diskimage struct:  */          /*  Allocate a new diskimage struct:  */
1485          d = malloc(sizeof(struct diskimage));          d = malloc(sizeof(struct diskimage));
1486          if (d == NULL) {          if (d == NULL) {
# Line 1462  int diskimage_add(struct machine *machin Line 1499  int diskimage_add(struct machine *machin
1499          }          }
1500    
1501          d->type = DISKIMAGE_SCSI;          d->type = DISKIMAGE_SCSI;
         d->id = id;  
1502    
1503          /*  Special cases: some machines usually have FLOPPY/IDE, not SCSI:  */          /*  Special cases: some machines usually have FLOPPY/IDE, not SCSI:  */
1504          if (machine->arch == ARCH_X86 ||          if (machine->arch == ARCH_X86 ||
1505              machine->machine_type == MACHINE_COBALT ||              machine->machine_type == MACHINE_COBALT ||
1506                machine->machine_type == MACHINE_EVBMIPS ||
1507              machine->machine_type == MACHINE_HPCMIPS ||              machine->machine_type == MACHINE_HPCMIPS ||
1508                machine->machine_type == MACHINE_BEBOX ||
1509                machine->machine_type == MACHINE_PREP ||
1510                machine->machine_type == MACHINE_CATS ||
1511                machine->machine_type == MACHINE_NETWINDER ||
1512              machine->machine_type == MACHINE_PS2)              machine->machine_type == MACHINE_PS2)
1513                  d->type = DISKIMAGE_IDE;                  d->type = DISKIMAGE_IDE;
1514    
# Line 1496  int diskimage_add(struct machine *machin Line 1537  int diskimage_add(struct machine *machin
1537           *  Is this a tape, CD-ROM or a normal disk?           *  Is this a tape, CD-ROM or a normal disk?
1538           *           *
1539           *  An intelligent guess, if no prefixes are used, would be that           *  An intelligent guess, if no prefixes are used, would be that
1540           *  filenames ending with .iso are CD-ROM images.           *  filenames ending with .iso or .cdr are CD-ROM images.
1541           */           */
1542          if (prefix_t) {          if (prefix_t) {
1543                  d->is_a_tape = 1;                  d->is_a_tape = 1;
1544          } else {          } else {
1545                  if (prefix_c ||                  if (prefix_c ||
1546                      ((strlen(d->fname) > 4 &&                      ((strlen(d->fname) > 4 &&
1547                      strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0)                      (strcasecmp(d->fname + strlen(d->fname) - 4, ".cdr") == 0 ||
1548                        strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0))
1549                      && !prefix_d)                      && !prefix_d)
1550                     ) {                     ) {
1551                          d->is_a_cdrom = 1;                          d->is_a_cdrom = 1;
# Line 1532  int diskimage_add(struct machine *machin Line 1574  int diskimage_add(struct machine *machin
1574    
1575          diskimage_recalc_size(d);          diskimage_recalc_size(d);
1576    
1577          if (d->total_size == 1474560 && !prefix_i && !prefix_s)          if ((d->total_size == 720*1024 || d->total_size == 1474560
1578                || d->total_size == 2949120 || d->total_size == 1228800)
1579                && !prefix_i && !prefix_s)
1580                  d->type = DISKIMAGE_FLOPPY;                  d->type = DISKIMAGE_FLOPPY;
1581    
1582            switch (d->type) {
1583            case DISKIMAGE_FLOPPY:
1584                    if (d->total_size < 737280) {
1585                            fatal("\nTODO: small (non-80-cylinder) floppies?\n\n");
1586                            exit(1);
1587                    }
1588                    d->cylinders = 80;
1589                    d->heads = 2;
1590                    d->sectors_per_track = d->total_size / (d->cylinders *
1591                        d->heads * 512);
1592                    break;
1593            default:/*  Non-floppies:  */
1594                    d->heads = 16;
1595                    d->sectors_per_track = 63;
1596                    if (prefix_g) {
1597                            d->chs_override = 1;
1598                            d->heads = override_heads;
1599                            d->sectors_per_track = override_spt;
1600                    }
1601                    bytespercyl = d->heads * d->sectors_per_track * 512;
1602                    d->cylinders = d->total_size / bytespercyl;
1603                    if (d->cylinders * bytespercyl < d->total_size)
1604                            d->cylinders ++;
1605            }
1606    
1607          d->rpms = 3600;          d->rpms = 3600;
1608    
1609          if (prefix_b)          if (prefix_b)
# Line 1551  int diskimage_add(struct machine *machin Line 1620  int diskimage_add(struct machine *machin
1620                  exit(1);                  exit(1);
1621          }          }
1622    
1623            /*  Calculate which ID to use:  */
1624            if (prefix_id == -1) {
1625                    int free = 0, collision = 1;
1626    
1627                    while (collision) {
1628                            collision = 0;
1629                            d2 = machine->first_diskimage;
1630                            while (d2 != NULL) {
1631                                    /*  (don't compare against ourselves :)  */
1632                                    if (d2 == d) {
1633                                            d2 = d2->next;
1634                                            continue;
1635                                    }
1636                                    if (d2->id == free && d2->type == d->type) {
1637                                            collision = 1;
1638                                            break;
1639                                    }
1640                                    d2 = d2->next;
1641                            }
1642                            if (!collision)
1643                                    id = free;
1644                            else
1645                                    free ++;
1646                    }
1647            } else {
1648                    id = prefix_id;
1649                    d2 = machine->first_diskimage;
1650                    while (d2 != NULL) {
1651                            /*  (don't compare against ourselves :)  */
1652                            if (d2 == d) {
1653                                    d2 = d2->next;
1654                                    continue;
1655                            }
1656                            if (d2->id == id && d2->type == d->type) {
1657                                    fprintf(stderr, "disk image id %i "
1658                                        "already in use\n", id);
1659                                    exit(1);
1660                            }
1661                            d2 = d2->next;
1662                    }
1663            }
1664    
1665            d->id = id;
1666    
1667          return id;          return id;
1668  }  }
1669    
# Line 1558  int diskimage_add(struct machine *machin Line 1671  int diskimage_add(struct machine *machin
1671  /*  /*
1672   *  diskimage_bootdev():   *  diskimage_bootdev():
1673   *   *
1674   *  Returns the disk id (0..7) of the device which we're booting from.   *  Returns the disk id of the device which we're booting from.  If typep is
1675     *  non-NULL, the type is returned as well.
1676   *   *
1677   *  If no disk was used as boot device, then -1 is returned. (In practice,   *  If no disk was used as boot device, then -1 is returned. (In practice,
1678   *  this is used to fake network (tftp) boot.)   *  this is used to fake network (tftp) boot.)
1679   */   */
1680  int diskimage_bootdev(struct machine *machine)  int diskimage_bootdev(struct machine *machine, int *typep)
1681  {  {
1682          struct diskimage *d = machine->first_diskimage;          struct diskimage *d;
1683    
1684            d = machine->first_diskimage;
1685          while (d != NULL) {          while (d != NULL) {
1686                  if (d->is_boot_device)                  if (d->is_boot_device) {
1687                            if (typep != NULL)
1688                                    *typep = d->type;
1689                          return d->id;                          return d->id;
1690                    }
1691                  d = d->next;                  d = d->next;
1692          }          }
1693    
1694          d = machine->first_diskimage;          d = machine->first_diskimage;
1695          if (d != NULL)          if (d != NULL) {
1696                    if (typep != NULL)
1697                            *typep = d->type;
1698                  return d->id;                  return d->id;
1699            }
1700    
1701          return -1;          return -1;
1702  }  }
1703    
1704    
1705  /*  /*
1706     *  diskimage_getname():
1707     *
1708     *  Returns 1 if a valid disk image name was returned, 0 otherwise.
1709     */
1710    int diskimage_getname(struct machine *machine, int id, int type,
1711            char *buf, size_t bufsize)
1712    {
1713            struct diskimage *d = machine->first_diskimage;
1714    
1715            if (buf == NULL)
1716                    return 0;
1717    
1718            while (d != NULL) {
1719                    if (d->type == type && d->id == id) {
1720                            char *p = strrchr(d->fname, '/');
1721                            if (p == NULL)
1722                                    p = d->fname;
1723                            else
1724                                    p ++;
1725                            snprintf(buf, bufsize, "%s", p);
1726                            return 1;
1727                    }
1728                    d = d->next;
1729            }
1730            return 0;
1731    }
1732    
1733    
1734    /*
1735   *  diskimage_is_a_cdrom():   *  diskimage_is_a_cdrom():
1736   *   *
1737   *  Returns 1 if a disk image is a SCSI CDROM, 0 otherwise.   *  Returns 1 if a disk image is a CDROM, 0 otherwise.
1738   */   */
1739  int diskimage_is_a_cdrom(struct machine *machine, int scsi_id)  int diskimage_is_a_cdrom(struct machine *machine, int id, int type)
1740  {  {
1741          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1742    
1743          while (d != NULL) {          while (d != NULL) {
1744                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1745                          return d->is_a_cdrom;                          return d->is_a_cdrom;
1746                  d = d->next;                  d = d->next;
1747          }          }
# Line 1601  int diskimage_is_a_cdrom(struct machine Line 1752  int diskimage_is_a_cdrom(struct machine
1752  /*  /*
1753   *  diskimage_is_a_tape():   *  diskimage_is_a_tape():
1754   *   *
1755   *  Returns 1 if a disk image is a SCSI tape, 0 otherwise.   *  Returns 1 if a disk image is a tape, 0 otherwise.
1756     *
1757   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation
1758   *  boot strings.)   *  boot strings.)
1759   */   */
1760  int diskimage_is_a_tape(struct machine *machine, int scsi_id)  int diskimage_is_a_tape(struct machine *machine, int id, int type)
1761  {  {
1762          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1763    
1764          while (d != NULL) {          while (d != NULL) {
1765                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1766                          return d->is_a_tape;                          return d->is_a_tape;
1767                  d = d->next;                  d = d->next;
1768          }          }
# Line 1656  void diskimage_dump_info(struct machine Line 1808  void diskimage_dump_info(struct machine
1808                  else                  else
1809                          debug("%lli MB", (long long) (d->total_size / 1048576));                          debug("%lli MB", (long long) (d->total_size / 1048576));
1810    
1811                  debug(" (%lli sectors)%s\n",                  if (d->type == DISKIMAGE_FLOPPY || d->chs_override)
1812                      (long long) (d->total_size / 512),                          debug(" (CHS=%i,%i,%i)", d->cylinders, d->heads,
1813                      d->is_boot_device? " (BOOT)" : "");                              d->sectors_per_track);
1814                    else
1815                            debug(" (%lli sectors)", (long long)
1816                               (d->total_size / 512));
1817    
1818                    if (d->is_boot_device)
1819                            debug(" (BOOT)");
1820                    debug("\n");
1821    
1822                  debug_indentation(-iadd);                  debug_indentation(-iadd);
1823    

Legend:
Removed from v.4  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26