/[gxemul]/upstream/0.4.4/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.4.4/src/diskimage.c

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

trunk/src/diskimage.c revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC upstream/0.4.4/src/diskimage.c revision 35 by dpavlin, Mon Oct 8 16:21:26 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: diskimage.c,v 1.81 2005/04/04 21:50:05 debug Exp $   *  $Id: diskimage.c,v 1.116 2006/12/30 13:30:51 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_get_baseoffset():
287     *
288     *  Returns -1 if the specified disk id/type does not exists, otherwise
289     *  the base offset of the disk image is returned.
290     */
291    int64_t diskimage_get_baseoffset(struct machine *machine, int id, int type)
292    {
293            struct diskimage *d = machine->first_diskimage;
294    
295            while (d != NULL) {
296                    if (d->type == type && d->id == id)
297                            return d->override_base_offset;
298                    d = d->next;
299            }
300            return -1;
301    }
302    
303    
304    /*
305     *  diskimage_getchs():
306     *
307     *  Returns the current CHS values of a disk image.
308     */
309    void diskimage_getchs(struct machine *machine, int id, int type,
310            int *c, int *h, int *s)
311    {
312            struct diskimage *d = machine->first_diskimage;
313    
314            while (d != NULL) {
315                    if (d->type == type && d->id == id) {
316                            *c = d->cylinders;
317                            *h = d->heads;
318                            *s = d->sectors_per_track;
319                            return;
320                    }
321                    d = d->next;
322            }
323            fatal("diskimage_getchs(): disk id %i (type %i) not found?\n",
324                id, diskimage_types[type]);
325            exit(1);
326    }
327    
328    
329    /*
330   *  diskimage__return_default_status_and_message():   *  diskimage__return_default_status_and_message():
331   *   *
332   *  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 429  static size_t diskimage_access__cdrom(st
429  static int diskimage__internal_access(struct diskimage *d, int writeflag,  static int diskimage__internal_access(struct diskimage *d, int writeflag,
430          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
431  {  {
432          size_t lendone;          ssize_t lendone;
433          int res;          int res;
434    
435          if (buf == NULL) {          if (buf == NULL) {
# Line 422  static int diskimage__internal_access(st Line 470  static int diskimage__internal_access(st
470    
471          /*  Warn about non-complete data transfers:  */          /*  Warn about non-complete data transfers:  */
472          if (lendone != (ssize_t)len) {          if (lendone != (ssize_t)len) {
473    #ifdef UNSTABLE_DEVEL
474                  fatal("[ diskimage__internal_access(): disk_id %i, offset %lli"                  fatal("[ diskimage__internal_access(): disk_id %i, offset %lli"
475                      ", transfer not completed. len=%i, len_done=%i ]\n",                      ", transfer not completed. len=%i, len_done=%i ]\n",
476                      d->id, (long long)offset, (int)len, (int)lendone);                      d->id, (long long)offset, (int)len, (int)lendone);
477    #endif
478                  return 0;                  return 0;
479          }          }
480    
# Line 447  static int diskimage__internal_access(st Line 497  static int diskimage__internal_access(st
497   *      1 if otherwise ok,   *      1 if otherwise ok,
498   *      0 on error.   *      0 on error.
499   */   */
500  int diskimage_scsicommand(struct cpu *cpu, int scsi_id,  int diskimage_scsicommand(struct cpu *cpu, int id, int type,
501          struct scsi_transfer *xferp)          struct scsi_transfer *xferp)
502  {  {
503          int retlen, i;          char namebuf[16];
504            int retlen, i, q;
505          uint64_t size;          uint64_t size;
506          int64_t ofs;          int64_t ofs;
507          int pagecode;          int pagecode;
# Line 464  int diskimage_scsicommand(struct cpu *cp Line 515  int diskimage_scsicommand(struct cpu *cp
515    
516          d = machine->first_diskimage;          d = machine->first_diskimage;
517          while (d != NULL) {          while (d != NULL) {
518                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
519                          break;                          break;
520                  d = d->next;                  d = d->next;
521          }          }
522          if (d == NULL) {          if (d == NULL) {
523                  fprintf(stderr, "[ diskimage_scsicommand(): SCSI disk"                  fprintf(stderr, "[ diskimage_scsicommand(): %s "
524                      " with id %i not connected? ]\n", scsi_id);                      " id %i not connected? ]\n", diskimage_types[type], id);
525          }          }
526    
527          if (xferp->cmd == NULL) {          if (xferp->cmd == NULL) {
# Line 485  int diskimage_scsicommand(struct cpu *cp Line 536  int diskimage_scsicommand(struct cpu *cp
536          }          }
537    
538          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",
539              scsi_id, xferp->cmd[0]);              id, xferp->cmd[0]);
540    
541  #if 0  #if 0
542          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",
543              scsi_id, xferp->cmd[0], xferp->cmd_len);              id, xferp->cmd[0], xferp->cmd_len);
544          for (i=0; i<xferp->cmd_len; i++)          for (i=0; i<xferp->cmd_len; i++)
545                  fatal(" %02x", xferp->cmd[i]);                  fatal(" %02x", xferp->cmd[i]);
546          fatal("\n");          fatal("\n");
547  if (xferp->cmd_len > 7 && xferp->cmd[5] == 0x11)  if (xferp->cmd_len > 7 && xferp->cmd[5] == 0x11)
548          single_step = 1;          single_step = ENTER_SINGLE_STEPPING;
549  #endif  #endif
550    
551  #if 0  #if 0
# Line 504  if (xferp->cmd_len > 7 && xferp->cmd[5] Line 555  if (xferp->cmd_len > 7 && xferp->cmd[5]
555                  f = fopen("scsi_log.txt", "w");                  f = fopen("scsi_log.txt", "w");
556          if (f != NULL) {          if (f != NULL) {
557                  int i;                  int i;
558                  fprintf(f, "id=%i cmd =", scsi_id);                  fprintf(f, "id=%i cmd =", id);
559                  for (i=0; i<xferp->cmd_len; i++)                  for (i=0; i<xferp->cmd_len; i++)
560                          fprintf(f, " %02x", xferp->cmd[i]);                          fprintf(f, " %02x", xferp->cmd[i]);
561                  fprintf(f, "\n");                  fprintf(f, "\n");
# Line 560  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 611  xferp->data_in[4] = 0x2c - 4;  /*  Additi
611                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */
612                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */
613    
614                  /*  These must be padded with spaces:  */                  /*  These are padded with spaces:  */
615                  memcpy(xferp->data_in+8,  "FAKE    ", 8);  
616                  memcpy(xferp->data_in+16, "DISK            ", 16);                  memcpy(xferp->data_in+8,  "GXemul  ", 8);
617                  memcpy(xferp->data_in+32, "V0.0", 4);                  if (diskimage_getname(cpu->machine, id,
618                        type, namebuf, sizeof(namebuf))) {
619                            size_t i;
620                            for (i=0; i<sizeof(namebuf); i++)
621                                    if (namebuf[i] == 0) {
622                                            for (; i<sizeof(namebuf); i++)
623                                                    namebuf[i] = ' ';
624                                            break;
625                                    }
626                            memcpy(xferp->data_in+16, namebuf, 16);
627                    } else
628                            memcpy(xferp->data_in+16, "DISK            ", 16);
629                    memcpy(xferp->data_in+32, "0   ", 4);
630    
631                  /*                  /*
632                   *  Some Ultrix kernels want specific responses from                   *  Some Ultrix kernels want specific responses from
633                   *  the drives.                   *  the drives.
634                   */                   */
635    
636                  if (machine->machine_type == MACHINE_DEC) {                  if (machine->machine_type == MACHINE_PMAX) {
637                          /*  DEC, RZ25 (rev 0900) = 832527 sectors  */                          /*  DEC, RZ25 (rev 0900) = 832527 sectors  */
638                          /*  DEC, RZ58 (rev 2000) = 2698061 sectors  */                          /*  DEC, RZ58 (rev 2000) = 2698061 sectors  */
639                          memcpy(xferp->data_in+8,  "DEC     ", 8);                          memcpy(xferp->data_in+8,  "DEC     ", 8);
# Line 582  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 645  xferp->data_in[4] = 0x2c - 4;  /*  Additi
645                  if (d->is_a_cdrom) {                  if (d->is_a_cdrom) {
646                          xferp->data_in[0] = 0x05;  /*  0x05 = CD-ROM  */                          xferp->data_in[0] = 0x05;  /*  0x05 = CD-ROM  */
647                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */
648                          memcpy(xferp->data_in+16, "CD-ROM          ", 16);                          /*  memcpy(xferp->data_in+16, "CD-ROM          ", 16);*/
649    
650                          if (machine->machine_type == MACHINE_DEC) {                          if (machine->machine_type == MACHINE_PMAX) {
651                                  /*  SONY, CD-ROM:  */                                  /*  SONY, CD-ROM:  */
652                                  memcpy(xferp->data_in+8, "SONY    ", 8);                                  memcpy(xferp->data_in+8, "SONY    ", 8);
653                                  memcpy(xferp->data_in+16,                                  memcpy(xferp->data_in+16,
# Line 595  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 658  xferp->data_in[4] = 0x2c - 4;  /*  Additi
658                                  memcpy(xferp->data_in+16,                                  memcpy(xferp->data_in+16,
659                                      "RRD42   (C) DEC ", 16);                                      "RRD42   (C) DEC ", 16);
660                                  memcpy(xferp->data_in+32, "4.5d", 4);                                  memcpy(xferp->data_in+32, "4.5d", 4);
661                          } else {                          } else if (machine->machine_type == MACHINE_ARC) {
662                                  /*  NEC, CD-ROM:  */                                  /*  NEC, CD-ROM:  */
663                                  memcpy(xferp->data_in+8, "NEC     ", 8);                                  memcpy(xferp->data_in+8, "NEC     ", 8);
664                                  memcpy(xferp->data_in+16,                                  memcpy(xferp->data_in+16,
# Line 610  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 673  xferp->data_in[4] = 0x2c - 4;  /*  Additi
673                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */                          xferp->data_in[1] = 0x80;  /*  0x80 = removable  */
674                          memcpy(xferp->data_in+16, "TAPE            ", 16);                          memcpy(xferp->data_in+16, "TAPE            ", 16);
675    
676                          if (machine->machine_type == MACHINE_DEC) {                          if (machine->machine_type == MACHINE_PMAX) {
677                                  /*                                  /*
678                                   *  TODO:  find out if these are correct.                                   *  TODO:  find out if these are correct.
679                                   *                                   *
# Line 665  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 728  xferp->data_in[4] = 0x2c - 4;  /*  Additi
728                  break;                  break;
729    
730          case SCSICMD_MODE_SENSE:          case SCSICMD_MODE_SENSE:
731            case SCSICMD_MODE_SENSE10:      
732                  debug("MODE_SENSE");                  debug("MODE_SENSE");
733                    q = 4; retlen = xferp->cmd[4];
734                  if (xferp->cmd_len != 6)                  switch (xferp->cmd_len) {
735                          fatal(" (unimplemented mode_sense len=%i)",                  case 6: break;
736                    case 10:q = 8;
737                            retlen = xferp->cmd[7] * 256 + xferp->cmd[8];
738                            break;
739                    default:fatal(" (unimplemented mode_sense len=%i)",
740                              xferp->cmd_len);                              xferp->cmd_len);
741                    }
                 retlen = xferp->cmd[4];  
742    
743                  /*                  /*
744                   *  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 761  xferp->data_in[4] = 0x2c - 4;  /*  Additi
761    
762                  pagecode = xferp->cmd[2] & 0x3f;                  pagecode = xferp->cmd[2] & 0x3f;
763    
764                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", scsi_id, pagecode);                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", id, pagecode);
765    
766                  /*  4 bytes of header for 6-byte command,                  /*  4 bytes of header for 6-byte command,
767                      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 773  xferp->data_in[4] = 0x2c - 4;  /*  Additi
773                  xferp->data_in[3] = 8 * 1;      /*  block descriptor                  xferp->data_in[3] = 8 * 1;      /*  block descriptor
774                                                      length: 1 page (?)  */                                                      length: 1 page (?)  */
775    
776                  /*  TODO: update this when implementing 10-byte commands:  */                  xferp->data_in[q+0] = 0x00;     /*  density code  */
777                  xferp->data_in[4] = 0x00;       /*  density code  */                  xferp->data_in[q+1] = 0;        /*  nr of blocks, high  */
778                  xferp->data_in[5] = 0;          /*  nr of blocks, high  */                  xferp->data_in[q+2] = 0;        /*  nr of blocks, mid  */
779                  xferp->data_in[6] = 0;          /*  nr of blocks, mid  */                  xferp->data_in[q+3] = 0;        /*  nr of blocks, low */
780                  xferp->data_in[7] = 0;          /*  nr of blocks, low */                  xferp->data_in[q+4] = 0x00;     /*  reserved  */
781                  xferp->data_in[8] = 0x00;       /*  reserved  */                  xferp->data_in[q+5] = (d->logical_block_size >> 16) & 255;
782                  xferp->data_in[9] = (d->logical_block_size >> 16) & 255;                  xferp->data_in[q+6] = (d->logical_block_size >> 8) & 255;
783                  xferp->data_in[10] = (d->logical_block_size >> 8) & 255;                  xferp->data_in[q+7] = d->logical_block_size & 255;
784                  xferp->data_in[11] = d->logical_block_size & 255;                  q += 8;
785    
786                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
787    
# Line 726  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 793  xferp->data_in[4] = 0x2c - 4;  /*  Additi
793                          /*  TODO: Nothing here?  */                          /*  TODO: Nothing here?  */
794                          break;                          break;
795                  case 1:         /*  read-write error recovery page  */                  case 1:         /*  read-write error recovery page  */
796                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
797                          xferp->data_in[12 + 1] = 10;                          xferp->data_in[q + 1] = 10;
798                          break;                          break;
799                  case 3:         /*  format device page  */                  case 3:         /*  format device page  */
800                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
801                          xferp->data_in[12 + 1] = 22;                          xferp->data_in[q + 1] = 22;
802    
803                          /*  10,11 = sectors per track  */                          /*  10,11 = sectors per track  */
804                          xferp->data_in[12 + 10] = 0;                          xferp->data_in[q + 10] = 0;
805                          xferp->data_in[12 + 11] = 1;    /*  TODO  */                          xferp->data_in[q + 11] = d->sectors_per_track;
806    
807                          /*  12,13 = physical sector size  */                          /*  12,13 = physical sector size  */
808                          xferp->data_in[12 + 12] =                          xferp->data_in[q + 12] =
809                              (d->logical_block_size >> 8) & 255;                              (d->logical_block_size >> 8) & 255;
810                          xferp->data_in[12 + 13] = d->logical_block_size & 255;                          xferp->data_in[q + 13] = d->logical_block_size & 255;
811                          break;                          break;
812                  case 4:         /*  rigid disk geometry page  */                  case 4:         /*  rigid disk geometry page  */
813                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
814                          xferp->data_in[12 + 1] = 22;                          xferp->data_in[q + 1] = 22;
815                          xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255;                          xferp->data_in[q + 2] = (d->ncyls >> 16) & 255;
816                          xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255;                          xferp->data_in[q + 3] = (d->ncyls >> 8) & 255;
817                          xferp->data_in[12 + 4] = d->ncyls & 255;                          xferp->data_in[q + 4] = d->ncyls & 255;
818                          xferp->data_in[12 + 5] = 15;    /*  nr of heads  */                          xferp->data_in[q + 5] = d->heads;
819    
820                          xferp->data_in[12 + 20] = (d->rpms >> 8) & 255;                          xferp->data_in[q + 20] = (d->rpms >> 8) & 255;
821                          xferp->data_in[12 + 21] = d->rpms & 255;                          xferp->data_in[q + 21] = d->rpms & 255;
822                          break;                          break;
823                  case 5:         /*  flexible disk page  */                  case 5:         /*  flexible disk page  */
824                          xferp->data_in[12 + 0] = pagecode;                          xferp->data_in[q + 0] = pagecode;
825                          xferp->data_in[12 + 1] = 0x1e;                          xferp->data_in[q + 1] = 0x1e;
826    
827                          /*  2,3 = transfer rate  */                          /*  2,3 = transfer rate  */
828                          xferp->data_in[12 + 2] = ((5000) >> 8) & 255;                          xferp->data_in[q + 2] = ((5000) >> 8) & 255;
829                          xferp->data_in[12 + 3] = (5000) & 255;                          xferp->data_in[q + 3] = (5000) & 255;
830    
831                          xferp->data_in[12 + 4] = 2;    /*  nr of heads  */                          xferp->data_in[q + 4] = d->heads;
832                          xferp->data_in[12 + 5] = 18;   /*  sectors per track  */                          xferp->data_in[q + 5] = d->sectors_per_track;
833    
834                          /*  6,7 = data bytes per sector  */                          /*  6,7 = data bytes per sector  */
835                          xferp->data_in[12 + 6] = (d->logical_block_size >> 8)                          xferp->data_in[q + 6] = (d->logical_block_size >> 8)
836                              & 255;                              & 255;
837                          xferp->data_in[12 + 7] = d->logical_block_size & 255;                          xferp->data_in[q + 7] = d->logical_block_size & 255;
838    
839                          xferp->data_in[12 + 8] = (d->ncyls >> 8) & 255;                          xferp->data_in[q + 8] = (d->ncyls >> 8) & 255;
840                          xferp->data_in[12 + 9] = d->ncyls & 255;                          xferp->data_in[q + 9] = d->ncyls & 255;
841    
842                          xferp->data_in[12 + 28] = (d->rpms >> 8) & 255;                          xferp->data_in[q + 28] = (d->rpms >> 8) & 255;
843                          xferp->data_in[12 + 29] = d->rpms & 255;                          xferp->data_in[q + 29] = d->rpms & 255;
844                          break;                          break;
845                  default:                  default:
846                          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 886  xferp->data_in[4] = 0x2c - 4;  /*  Additi
886                          ofs = d->tape_offset;                          ofs = d->tape_offset;
887    
888                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"
889                              ", ofs=%lli ]\n", scsi_id, d->tape_filenr,                              ", ofs=%lli ]\n", id, d->tape_filenr,
890                              xferp->cmd[1], (int)size, (long long)ofs);                              xferp->cmd[1], (int)size, (long long)ofs);
891                  } else {                  } else {
892                          if (xferp->cmd[0] == SCSICMD_READ) {                          if (xferp->cmd[0] == SCSICMD_READ) {
# Line 851  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 918  xferp->data_in[4] = 0x2c - 4;  /*  Additi
918                                   *  blocks to transfer. (NOTE: If the value is                                   *  blocks to transfer. (NOTE: If the value is
919                                   *  0, this means 0, not 65536. :-)                                   *  0, this means 0, not 65536. :-)
920                                   */                                   */
921                                  ofs = (xferp->cmd[2] << 24) + (xferp->cmd[3]                                  ofs = ((uint64_t)xferp->cmd[2] << 24) +
922                                      << 16) + (xferp->cmd[4] << 8) +                                      (xferp->cmd[3] << 16) + (xferp->cmd[4] << 8)
923                                      xferp->cmd[5];                                      + xferp->cmd[5];
924                                  retlen = (xferp->cmd[7] << 8) + xferp->cmd[8];                                  retlen = (xferp->cmd[7] << 8) + xferp->cmd[8];
925                          }                          }
926    
# Line 882  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 949  xferp->data_in[4] = 0x2c - 4;  /*  Additi
949                   *   be set to NO SENSE"..                   *   be set to NO SENSE"..
950                   */                   */
951                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {
952                          debug(" feof id=%i\n", scsi_id);                          debug(" feof id=%i\n", id);
953                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */
954    
955                          d->filemark = 1;                          d->filemark = 1;
# Line 891  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 958  xferp->data_in[4] = 0x2c - 4;  /*  Additi
958                              xferp->data_in, size);                              xferp->data_in, size);
959    
960                  if (d->is_a_tape && d->f != NULL)                  if (d->is_a_tape && d->f != NULL)
961                          d->tape_offset = ftell(d->f);                          d->tape_offset = ftello(d->f);
962    
963                  /*  TODO: other errors?  */                  /*  TODO: other errors?  */
964                  break;                  break;
# Line 929  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 996  xferp->data_in[4] = 0x2c - 4;  /*  Additi
996                           *  transfer. (NOTE: If the value is 0 this means 0,                           *  transfer. (NOTE: If the value is 0 this means 0,
997                           *  not 65536.)                           *  not 65536.)
998                           */                           */
999                          ofs = (xferp->cmd[2] << 24) + (xferp->cmd[3] << 16) +                          ofs = ((uint64_t)xferp->cmd[2] << 24) +
1000                                (xferp->cmd[4] << 8) + xferp->cmd[5];                              (xferp->cmd[3] << 16) + (xferp->cmd[4] << 8) +
1001                                xferp->cmd[5];
1002                          retlen = (xferp->cmd[7] << 8) + xferp->cmd[8];                          retlen = (xferp->cmd[7] << 8) + xferp->cmd[8];
1003                  }                  }
1004    
# Line 978  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1046  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1046                  if (xferp->cmd_len != 6)                  if (xferp->cmd_len != 6)
1047                          debug(" (weird len=%i)", xferp->cmd_len);                          debug(" (weird len=%i)", xferp->cmd_len);
1048    
1049                  for (i=0; i<xferp->cmd_len ; i++)                  for (i=0; i<(ssize_t)xferp->cmd_len; i++)
1050                          debug(" %02x", xferp->cmd[i]);                          debug(" %02x", xferp->cmd[i]);
1051    
1052                  /*  TODO: actualy care about cmd[]  */                  /*  TODO: actualy care about cmd[]  */
# Line 1094  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1162  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1162    
1163                  /*                  /*
1164                   *  Bits 2..0 of buf[1] contain the 'code' which describes how                   *  Bits 2..0 of buf[1] contain the 'code' which describes how
1165                   *  we should space, and buf[2..4] contain the number of                   *  spacing should be done, and buf[2..4] contain the number of
1166                   *  operations.                   *  operations.
1167                   */                   */
1168                  debug("[ SPACE: buf[] = %02x %02x %02x %02x %02x %02x ]\n",                  debug("[ SPACE: buf[] = %02x %02x %02x %02x %02x %02x ]\n",
# Line 1187  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1255  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1255                  scsi_transfer_allocbuf(&xferp->data_in_len,                  scsi_transfer_allocbuf(&xferp->data_in_len,
1256                      &xferp->data_in, retlen, 1);                      &xferp->data_in, retlen, 1);
1257    
1258                    xferp->data_in[0] = 0;
1259                    xferp->data_in[1] = 10;
1260                    xferp->data_in[2] = 0;          /*  First track.  */
1261                    xferp->data_in[3] = 0;          /*  Last track.  */
1262    
1263                    /*  Track 0 data:  */
1264                    xferp->data_in[4] = 0x00;       /*  Reserved.  */
1265                    xferp->data_in[5] = 0x04;       /*  ADR + CTRL:
1266                                                        Data, not audio  */
1267                    xferp->data_in[6] = 0x00;       /*  Track nr  */
1268                    xferp->data_in[7] = 0x00;       /*  Reserved  */
1269                    /*  8..11 = absolute CDROM address  */
1270    
1271                    diskimage__return_default_status_and_message(xferp);
1272                    break;
1273    
1274            case SCSICDROM_READ_DISCINFO:
1275                    debug("(SCSICDROM_READ_DISCINFO: ");
1276                    debug("TODO");
1277                    retlen = 0;
1278    
1279                    /*  Return data:  */
1280                    scsi_transfer_allocbuf(&xferp->data_in_len,
1281                        &xferp->data_in, retlen, 1);
1282    
1283                    /*  TODO  */
1284    
1285                    diskimage__return_default_status_and_message(xferp);
1286                    break;
1287    
1288            case SCSICDROM_READ_TRACKINFO:
1289                    debug("(SCSICDROM_READ_TRACKINFO: ");
1290                    debug("TODO");
1291                    retlen = 0;
1292    
1293                    /*  Return data:  */
1294                    scsi_transfer_allocbuf(&xferp->data_in_len,
1295                        &xferp->data_in, retlen, 1);
1296    
1297                  /*  TODO  */                  /*  TODO  */
1298    
1299                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
# Line 1228  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1335  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1335                  } else {                  } else {
1336                          int i;                          int i;
1337                          fatal("[ unknown MODE_SELECT: cmd =");                          fatal("[ unknown MODE_SELECT: cmd =");
1338                          for (i=0; i<xferp->cmd_len; i++)                          for (i=0; i<(ssize_t)xferp->cmd_len; i++)
1339                                  fatal(" %02x", xferp->cmd[i]);                                  fatal(" %02x", xferp->cmd[i]);
1340                          fatal(", data_out =");                          fatal(", data_out =");
1341                          for (i=0; i<xferp->data_out_len; i++)                          for (i=0; i<(ssize_t)xferp->data_out_len; i++)
1342                                  fatal(" %02x", xferp->data_out[i]);                                  fatal(" %02x", xferp->data_out[i]);
1343                          fatal(" ]");                          fatal(" ]");
1344                  }                  }
# Line 1240  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1347  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1347                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1348                  break;                  break;
1349    
1350          case 0x1e:          case SCSICMD_PREVENT_ALLOW_REMOVE:
1351                  debug("[ SCSI 0x%02x: TODO ]\n", xferp->cmd[0]);                  debug("[ SCSI 0x%02x Prevent/allow medium removal: "
1352                        "TODO ]\n", xferp->cmd[0]);
                 /*  TODO  */  
1353    
1354                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1355                  break;                  break;
# Line 1251  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1357  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1357          case 0xbd:          case 0xbd:
1358                  fatal("[ SCSI 0x%02x (len %i), TODO: ", xferp->cmd[0],                  fatal("[ SCSI 0x%02x (len %i), TODO: ", xferp->cmd[0],
1359                      xferp->cmd_len);                      xferp->cmd_len);
1360                  for (i=0; i<xferp->cmd_len; i++)                  for (i=0; i<(ssize_t)xferp->cmd_len; i++)
1361                          fatal(" %02x", xferp->cmd[i]);                          fatal(" %02x", xferp->cmd[i]);
1362                  fatal(" ]\n");                  fatal(" ]\n");
1363    
# Line 1275  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1381  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1381                      &xferp->data_in, retlen, 1);                      &xferp->data_in, retlen, 1);
1382    
1383                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1384    
1385                  break;                  break;
1386    
1387          default:          default:
1388                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",
1389                      xferp->cmd[0], scsi_id);                      xferp->cmd[0], id);
1390                  exit(1);                  exit(1);
1391          }          }
1392          debug(" ]\n");          debug(" ]\n");
# Line 1295  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1402  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1402   *   *
1403   *  Returns 1 if the access completed successfully, 0 otherwise.   *  Returns 1 if the access completed successfully, 0 otherwise.
1404   */   */
1405  int diskimage_access(struct machine *machine, int scsi_id, int writeflag,  int diskimage_access(struct machine *machine, int id, int type, int writeflag,
1406          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
1407  {  {
1408          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1409    
1410          while (d != NULL) {          while (d != NULL) {
1411                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1412                          break;                          break;
1413                  d = d->next;                  d = d->next;
1414          }          }
1415    
1416          if (d == NULL) {          if (d == NULL) {
1417                  fatal("[ diskimage_access(): ERROR: trying to access a "                  fatal("[ diskimage_access(): ERROR: trying to access a "
1418                      "non-existant SCSI disk image (%i)\n", scsi_id);                      "non-existant %s disk image (id %i)\n",
1419                        diskimage_types[type], id);
1420                  return 0;                  return 0;
1421          }          }
1422    
1423            offset -= d->override_base_offset;
1424            if (offset < 0 && offset + d->override_base_offset >= 0) {
1425                    debug("[ reading before start of disk image ]\n");
1426                    /*  Returning zeros.  */
1427                    memset(buf, 0, len);
1428                    return 1;
1429            }
1430    
1431          return diskimage__internal_access(d, writeflag, offset, buf, len);          return diskimage__internal_access(d, writeflag, offset, buf, len);
1432  }  }
1433    
# Line 1323  int diskimage_access(struct machine *mac Line 1439  int diskimage_access(struct machine *mac
1439   *  The filename may be prefixed with one or more modifiers, followed   *  The filename may be prefixed with one or more modifiers, followed
1440   *  by a colon.   *  by a colon.
1441   *   *
1442   *      b       specifies that this is the boot device   *      b       specifies that this is a bootable device
1443   *      c       CD-ROM (instead of normal SCSI DISK)   *      c       CD-ROM (instead of a normal DISK)
1444   *      d       SCSI DISK (this is the default)   *      d       DISK (this is the default)
1445     *      f       FLOPPY (instead of SCSI)
1446     *      gH;S;   set geometry (H=heads, S=sectors per track, cylinders are
1447     *              automatically calculated). (This is ignored for floppies.)
1448   *      i       IDE (instead of SCSI)   *      i       IDE (instead of SCSI)
1449     *      oOFS;   set base offset in bytes, when booting from an ISO9660 fs
1450   *      r       read-only (don't allow changes to the file)   *      r       read-only (don't allow changes to the file)
1451   *      t       SCSI tape   *      s       SCSI (this is the default)
1452     *      t       tape
1453   *      0-7     force a specific SCSI ID number   *      0-7     force a specific SCSI ID number
1454   *   *
1455   *  machine is assumed to be non-NULL.   *  machine is assumed to be non-NULL.
# Line 1337  int diskimage_access(struct machine *mac Line 1458  int diskimage_access(struct machine *mac
1458  int diskimage_add(struct machine *machine, char *fname)  int diskimage_add(struct machine *machine, char *fname)
1459  {  {
1460          struct diskimage *d, *d2;          struct diskimage *d, *d2;
1461          int id = 0;          int id = 0, override_heads=0, override_spt=0;
1462            int64_t bytespercyl, override_base_offset=0;
1463          char *cp;          char *cp;
1464          int prefix_b = 0;          int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
1465          int prefix_c = 0;          int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id=-1;
1466          int prefix_d = 0;          int prefix_o=0;
         int prefix_i = 0;  
         int prefix_t = 0;  
         int prefix_id = -1;  
         int prefix_r = 0;  
1467    
1468          if (fname == NULL) {          if (fname == NULL) {
1469                  fprintf(stderr, "diskimage_add(): NULL ptr\n");                  fprintf(stderr, "diskimage_add(): NULL ptr\n");
# Line 1377  int diskimage_add(struct machine *machin Line 1495  int diskimage_add(struct machine *machin
1495                          case 'd':                          case 'd':
1496                                  prefix_d = 1;                                  prefix_d = 1;
1497                                  break;                                  break;
1498                            case 'f':
1499                                    prefix_f = 1;
1500                                    break;
1501                            case 'g':
1502                                    prefix_g = 1;
1503                                    override_heads = atoi(fname);
1504                                    while (*fname != '\0' && *fname != ';')
1505                                            fname ++;
1506                                    if (*fname == ';')
1507                                            fname ++;
1508                                    override_spt = atoi(fname);
1509                                    while (*fname != '\0' && *fname != ';' &&
1510                                        *fname != ':')
1511                                            fname ++;
1512                                    if (*fname == ';')
1513                                            fname ++;
1514                                    if (override_heads < 1 ||
1515                                        override_spt < 1) {
1516                                            fatal("Bad geometry: heads=%i "
1517                                                "spt=%i\n", override_heads,
1518                                                override_spt);
1519                                            exit(1);
1520                                    }
1521                                    break;
1522                          case 'i':                          case 'i':
1523                                  prefix_i = 1;                                  prefix_i = 1;
1524                                  break;                                  break;
1525                          case 't':                          case 'o':
1526                                  prefix_t = 1;                                  prefix_o = 1;
1527                                    override_base_offset = atoi(fname);
1528                                    while (*fname != '\0' && *fname != ':'
1529                                        && *fname != ';')
1530                                            fname ++;
1531                                    if (*fname == ':' || *fname == ';')
1532                                            fname ++;
1533                                    if (override_base_offset < 0) {
1534                                            fatal("Bad base offset: %"PRIi64
1535                                                "\n", override_base_offset);
1536                                            exit(1);
1537                                    }
1538                                  break;                                  break;
1539                          case 'r':                          case 'r':
1540                                  prefix_r = 1;                                  prefix_r = 1;
1541                                  break;                                  break;
1542                            case 's':
1543                                    prefix_s = 1;
1544                                    break;
1545                            case 't':
1546                                    prefix_t = 1;
1547                                    break;
1548                          case ':':                          case ':':
1549                                  break;                                  break;
1550                          default:                          default:
# Line 1396  int diskimage_add(struct machine *machin Line 1555  int diskimage_add(struct machine *machin
1555                  }                  }
1556          }          }
1557    
         /*  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;  
                 }  
         }  
   
1558          /*  Allocate a new diskimage struct:  */          /*  Allocate a new diskimage struct:  */
1559          d = malloc(sizeof(struct diskimage));          d = malloc(sizeof(struct diskimage));
1560          if (d == NULL) {          if (d == NULL) {
# Line 1446  int diskimage_add(struct machine *machin Line 1572  int diskimage_add(struct machine *machin
1572                  d2->next = d;                  d2->next = d;
1573          }          }
1574    
1575          d->type = DISKIMAGE_SCSI;          /*  Default to IDE disks...  */
1576          d->id = id;          d->type = DISKIMAGE_IDE;
1577    
1578            /*  ... but some machines use SCSI by default:  */
1579            if (machine->machine_type == MACHINE_PMAX ||
1580                machine->machine_type == MACHINE_ARC)
1581                    d->type = DISKIMAGE_SCSI;
1582    
1583            if (prefix_i + prefix_f + prefix_s > 1) {
1584                    fprintf(stderr, "Invalid disk image prefix(es). You can"
1585                        "only use one of i, f, and s\nfor each disk image.\n");
1586                    exit(1);
1587            }
1588    
1589          if (prefix_i)          if (prefix_i)
1590                  d->type = DISKIMAGE_IDE;                  d->type = DISKIMAGE_IDE;
1591            if (prefix_f)
1592                    d->type = DISKIMAGE_FLOPPY;
1593            if (prefix_s)
1594                    d->type = DISKIMAGE_SCSI;
1595    
1596            if (prefix_o)
1597                    d->override_base_offset = override_base_offset;
1598    
1599          d->fname = strdup(fname);          d->fname = strdup(fname);
1600          if (d->fname == NULL) {          if (d->fname == NULL) {
# Line 1464  int diskimage_add(struct machine *machin Line 1608  int diskimage_add(struct machine *machin
1608           *  Is this a tape, CD-ROM or a normal disk?           *  Is this a tape, CD-ROM or a normal disk?
1609           *           *
1610           *  An intelligent guess, if no prefixes are used, would be that           *  An intelligent guess, if no prefixes are used, would be that
1611           *  filenames ending with .iso are CD-ROM images.           *  filenames ending with .iso or .cdr are CD-ROM images.
1612           */           */
1613          if (prefix_t) {          if (prefix_t) {
1614                  d->is_a_tape = 1;                  d->is_a_tape = 1;
1615          } else {          } else {
1616                  if (prefix_c ||                  if (prefix_c ||
1617                      ((strlen(d->fname) > 4 &&                      ((strlen(d->fname) > 4 &&
1618                      strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0)                      (strcasecmp(d->fname + strlen(d->fname) - 4, ".cdr") == 0 ||
1619                        strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0))
1620                      && !prefix_d)                      && !prefix_d)
1621                     ) {                     ) {
1622                          d->is_a_cdrom = 1;                          d->is_a_cdrom = 1;
# Line 1489  int diskimage_add(struct machine *machin Line 1634  int diskimage_add(struct machine *machin
1634                           */                           */
1635    
1636  #if 0  #if 0
1637                          if (machine->machine_type == MACHINE_DEC)                          if (machine->machine_type == MACHINE_PMAX)
1638                                  d->logical_block_size = 512;                                  d->logical_block_size = 512;
1639                          else                          else
1640                                  d->logical_block_size = 2048;                                  d->logical_block_size = 2048;
# Line 1500  int diskimage_add(struct machine *machin Line 1645  int diskimage_add(struct machine *machin
1645    
1646          diskimage_recalc_size(d);          diskimage_recalc_size(d);
1647    
1648            if ((d->total_size == 720*1024 || d->total_size == 1474560
1649                || d->total_size == 2949120 || d->total_size == 1228800)
1650                && !prefix_i && !prefix_s)
1651                    d->type = DISKIMAGE_FLOPPY;
1652    
1653            switch (d->type) {
1654            case DISKIMAGE_FLOPPY:
1655                    if (d->total_size < 737280) {
1656                            fatal("\nTODO: small (non-80-cylinder) floppies?\n\n");
1657                            exit(1);
1658                    }
1659                    d->cylinders = 80;
1660                    d->heads = 2;
1661                    d->sectors_per_track = d->total_size / (d->cylinders *
1662                        d->heads * 512);
1663                    break;
1664            default:/*  Non-floppies:  */
1665                    d->heads = 16;
1666                    d->sectors_per_track = 63;
1667                    if (prefix_g) {
1668                            d->chs_override = 1;
1669                            d->heads = override_heads;
1670                            d->sectors_per_track = override_spt;
1671                    }
1672                    bytespercyl = d->heads * d->sectors_per_track * 512;
1673                    d->cylinders = d->total_size / bytespercyl;
1674                    if (d->cylinders * bytespercyl < d->total_size)
1675                            d->cylinders ++;
1676            }
1677    
1678          d->rpms = 3600;          d->rpms = 3600;
1679    
1680          if (prefix_b)          if (prefix_b)
# Line 1516  int diskimage_add(struct machine *machin Line 1691  int diskimage_add(struct machine *machin
1691                  exit(1);                  exit(1);
1692          }          }
1693    
1694            /*  Calculate which ID to use:  */
1695            if (prefix_id == -1) {
1696                    int free = 0, collision = 1;
1697    
1698                    while (collision) {
1699                            collision = 0;
1700                            d2 = machine->first_diskimage;
1701                            while (d2 != NULL) {
1702                                    /*  (don't compare against ourselves :)  */
1703                                    if (d2 == d) {
1704                                            d2 = d2->next;
1705                                            continue;
1706                                    }
1707                                    if (d2->id == free && d2->type == d->type) {
1708                                            collision = 1;
1709                                            break;
1710                                    }
1711                                    d2 = d2->next;
1712                            }
1713                            if (!collision)
1714                                    id = free;
1715                            else
1716                                    free ++;
1717                    }
1718            } else {
1719                    id = prefix_id;
1720                    d2 = machine->first_diskimage;
1721                    while (d2 != NULL) {
1722                            /*  (don't compare against ourselves :)  */
1723                            if (d2 == d) {
1724                                    d2 = d2->next;
1725                                    continue;
1726                            }
1727                            if (d2->id == id && d2->type == d->type) {
1728                                    fprintf(stderr, "disk image id %i "
1729                                        "already in use\n", id);
1730                                    exit(1);
1731                            }
1732                            d2 = d2->next;
1733                    }
1734            }
1735    
1736            d->id = id;
1737    
1738          return id;          return id;
1739  }  }
1740    
# Line 1523  int diskimage_add(struct machine *machin Line 1742  int diskimage_add(struct machine *machin
1742  /*  /*
1743   *  diskimage_bootdev():   *  diskimage_bootdev():
1744   *   *
1745   *  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
1746     *  non-NULL, the type is returned as well.
1747   *   *
1748   *  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,
1749   *  this is used to fake network (tftp) boot.)   *  this is used to fake network (tftp) boot.)
1750   */   */
1751  int diskimage_bootdev(struct machine *machine)  int diskimage_bootdev(struct machine *machine, int *typep)
1752  {  {
1753          struct diskimage *d = machine->first_diskimage;          struct diskimage *d;
1754    
1755            d = machine->first_diskimage;
1756          while (d != NULL) {          while (d != NULL) {
1757                  if (d->is_boot_device)                  if (d->is_boot_device) {
1758                            if (typep != NULL)
1759                                    *typep = d->type;
1760                          return d->id;                          return d->id;
1761                    }
1762                  d = d->next;                  d = d->next;
1763          }          }
1764    
1765          d = machine->first_diskimage;          d = machine->first_diskimage;
1766          if (d != NULL)          if (d != NULL) {
1767                    if (typep != NULL)
1768                            *typep = d->type;
1769                  return d->id;                  return d->id;
1770            }
1771    
1772          return -1;          return -1;
1773  }  }
1774    
1775    
1776  /*  /*
1777     *  diskimage_getname():
1778     *
1779     *  Returns 1 if a valid disk image name was returned, 0 otherwise.
1780     */
1781    int diskimage_getname(struct machine *machine, int id, int type,
1782            char *buf, size_t bufsize)
1783    {
1784            struct diskimage *d = machine->first_diskimage;
1785    
1786            if (buf == NULL)
1787                    return 0;
1788    
1789            while (d != NULL) {
1790                    if (d->type == type && d->id == id) {
1791                            char *p = strrchr(d->fname, '/');
1792                            if (p == NULL)
1793                                    p = d->fname;
1794                            else
1795                                    p ++;
1796                            snprintf(buf, bufsize, "%s", p);
1797                            return 1;
1798                    }
1799                    d = d->next;
1800            }
1801            return 0;
1802    }
1803    
1804    
1805    /*
1806   *  diskimage_is_a_cdrom():   *  diskimage_is_a_cdrom():
1807   *   *
1808   *  Returns 1 if a disk image is a SCSI CDROM, 0 otherwise.   *  Returns 1 if a disk image is a CDROM, 0 otherwise.
1809   */   */
1810  int diskimage_is_a_cdrom(struct machine *machine, int scsi_id)  int diskimage_is_a_cdrom(struct machine *machine, int id, int type)
1811  {  {
1812          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1813    
1814          while (d != NULL) {          while (d != NULL) {
1815                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1816                          return d->is_a_cdrom;                          return d->is_a_cdrom;
1817                  d = d->next;                  d = d->next;
1818          }          }
# Line 1566  int diskimage_is_a_cdrom(struct machine Line 1823  int diskimage_is_a_cdrom(struct machine
1823  /*  /*
1824   *  diskimage_is_a_tape():   *  diskimage_is_a_tape():
1825   *   *
1826   *  Returns 1 if a disk image is a SCSI tape, 0 otherwise.   *  Returns 1 if a disk image is a tape, 0 otherwise.
1827     *
1828   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation
1829   *  boot strings.)   *  boot strings.)
1830   */   */
1831  int diskimage_is_a_tape(struct machine *machine, int scsi_id)  int diskimage_is_a_tape(struct machine *machine, int id, int type)
1832  {  {
1833          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1834    
1835          while (d != NULL) {          while (d != NULL) {
1836                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1837                          return d->is_a_tape;                          return d->is_a_tape;
1838                  d = d->next;                  d = d->next;
1839          }          }
# Line 1590  int diskimage_is_a_tape(struct machine * Line 1848  int diskimage_is_a_tape(struct machine *
1848   */   */
1849  void diskimage_dump_info(struct machine *machine)  void diskimage_dump_info(struct machine *machine)
1850  {  {
1851          int iadd=4;          int iadd = DEBUG_INDENTATION;
1852          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1853    
1854          while (d != NULL) {          while (d != NULL) {
# Line 1604  void diskimage_dump_info(struct machine Line 1862  void diskimage_dump_info(struct machine
1862                  case DISKIMAGE_IDE:                  case DISKIMAGE_IDE:
1863                          debug("IDE");                          debug("IDE");
1864                          break;                          break;
1865                    case DISKIMAGE_FLOPPY:
1866                            debug("FLOPPY");
1867                            break;
1868                  default:                  default:
1869                          debug("UNKNOWN type %i", d->type);                          debug("UNKNOWN type %i", d->type);
1870                  }                  }
# Line 1613  void diskimage_dump_info(struct machine Line 1874  void diskimage_dump_info(struct machine
1874                  debug(" id %i, ", d->id);                  debug(" id %i, ", d->id);
1875                  debug("%s, ", d->writable? "read/write" : "read-only");                  debug("%s, ", d->writable? "read/write" : "read-only");
1876    
1877                  debug("%lli MB (%lli sectors)%s\n",                  if (d->type == DISKIMAGE_FLOPPY)
1878                      (long long) (d->total_size / 1048576),                          debug("%lli KB", (long long) (d->total_size / 1024));
1879                      (long long) (d->total_size / 512),                  else
1880                      d->is_boot_device? " (BOOT)" : "");                          debug("%lli MB", (long long) (d->total_size / 1048576));
1881    
1882                    if (d->type == DISKIMAGE_FLOPPY || d->chs_override)
1883                            debug(" (CHS=%i,%i,%i)", d->cylinders, d->heads,
1884                                d->sectors_per_track);
1885                    else
1886                            debug(" (%lli sectors)", (long long)
1887                               (d->total_size / 512));
1888    
1889                    if (d->is_boot_device)
1890                            debug(" (BOOT)");
1891                    debug("\n");
1892    
1893                  debug_indentation(-iadd);                  debug_indentation(-iadd);
1894    

Legend:
Removed from v.2  
changed lines
  Added in v.35

  ViewVC Help
Powered by ViewVC 1.1.26