/[gxemul]/trunk/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 /trunk/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 14 by dpavlin, Mon Oct 8 16:18:51 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.98 2005/09/27 23:55:43 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 58  Line 56 
56  extern int quiet_mode;  extern int quiet_mode;
57  extern int single_step;  extern int single_step;
58    
59    static char *diskimage_types[] = DISKIMAGE_TYPES;
60    
61  static struct scsi_transfer *first_free_scsi_transfer_alloc = NULL;  static struct scsi_transfer *first_free_scsi_transfer_alloc = NULL;
62    
# Line 209  void scsi_transfer_allocbuf(size_t *lenp Line 208  void scsi_transfer_allocbuf(size_t *lenp
208  /*  /*
209   *  diskimage_exist():   *  diskimage_exist():
210   *   *
211   *  Returns 1 if the specified SCSI id exists, 0 otherwise.   *  Returns 1 if the specified disk id (for a specific type) exists, 0
212     *  otherwise.
213   */   */
214  int diskimage_exist(struct machine *machine, int scsi_id)  int diskimage_exist(struct machine *machine, int id, int type)
215  {  {
216          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
217    
218          while (d != NULL) {          while (d != NULL) {
219                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
220                          return 1;                          return 1;
221                  d = d->next;                  d = d->next;
222          }          }
# Line 256  static void diskimage_recalc_size(struct Line 256  static void diskimage_recalc_size(struct
256    
257          d->total_size = size;          d->total_size = size;
258          d->ncyls = d->total_size / 1048576;          d->ncyls = d->total_size / 1048576;
259    
260            /*  TODO: There is a mismatch between d->ncyls and d->cylinders,
261                SCSI-based stuff usually doesn't care.  TODO: Fix this.  */
262  }  }
263    
264    
265  /*  /*
266   *  diskimage_getsize():   *  diskimage_getsize():
267   *   *
268   *  Returns -1 if the specified SCSI id does not exists, otherwise   *  Returns -1 if the specified disk id/type does not exists, otherwise
269   *  the size of the disk image is returned.   *  the size of the disk image is returned.
270   */   */
271  int64_t diskimage_getsize(struct machine *machine, int scsi_id)  int64_t diskimage_getsize(struct machine *machine, int id, int type)
272  {  {
273          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
274    
275          while (d != NULL) {          while (d != NULL) {
276                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
277                          return d->total_size;                          return d->total_size;
278                  d = d->next;                  d = d->next;
279          }          }
# Line 279  int64_t diskimage_getsize(struct machine Line 282  int64_t diskimage_getsize(struct machine
282    
283    
284  /*  /*
285     *  diskimage_getchs():
286     *
287     *  Returns the current CHS values of a disk image.
288     */
289    void diskimage_getchs(struct machine *machine, int id, int type,
290            int *c, int *h, int *s)
291    {
292            struct diskimage *d = machine->first_diskimage;
293    
294            while (d != NULL) {
295                    if (d->type == type && d->id == id) {
296                            *c = d->cylinders;
297                            *h = d->heads;
298                            *s = d->sectors_per_track;
299                            return;
300                    }
301                    d = d->next;
302            }
303            fatal("diskimage_getchs(): disk id %i (type %i) not found?\n",
304                id, diskimage_types[type]);
305            exit(1);
306    }
307    
308    
309    /*
310   *  diskimage__return_default_status_and_message():   *  diskimage__return_default_status_and_message():
311   *   *
312   *  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 409  static size_t diskimage_access__cdrom(st
409  static int diskimage__internal_access(struct diskimage *d, int writeflag,  static int diskimage__internal_access(struct diskimage *d, int writeflag,
410          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
411  {  {
412          size_t lendone;          ssize_t lendone;
413          int res;          int res;
414    
415          if (buf == NULL) {          if (buf == NULL) {
# Line 447  static int diskimage__internal_access(st Line 475  static int diskimage__internal_access(st
475   *      1 if otherwise ok,   *      1 if otherwise ok,
476   *      0 on error.   *      0 on error.
477   */   */
478  int diskimage_scsicommand(struct cpu *cpu, int scsi_id,  int diskimage_scsicommand(struct cpu *cpu, int id, int type,
479          struct scsi_transfer *xferp)          struct scsi_transfer *xferp)
480  {  {
481            char namebuf[16];
482          int retlen, i;          int retlen, i;
483          uint64_t size;          uint64_t size;
484          int64_t ofs;          int64_t ofs;
# Line 464  int diskimage_scsicommand(struct cpu *cp Line 493  int diskimage_scsicommand(struct cpu *cp
493    
494          d = machine->first_diskimage;          d = machine->first_diskimage;
495          while (d != NULL) {          while (d != NULL) {
496                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
497                          break;                          break;
498                  d = d->next;                  d = d->next;
499          }          }
500          if (d == NULL) {          if (d == NULL) {
501                  fprintf(stderr, "[ diskimage_scsicommand(): SCSI disk"                  fprintf(stderr, "[ diskimage_scsicommand(): %s "
502                      " with id %i not connected? ]\n", scsi_id);                      " id %i not connected? ]\n", diskimage_types[type], id);
503          }          }
504    
505          if (xferp->cmd == NULL) {          if (xferp->cmd == NULL) {
# Line 485  int diskimage_scsicommand(struct cpu *cp Line 514  int diskimage_scsicommand(struct cpu *cp
514          }          }
515    
516          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",          debug("[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",
517              scsi_id, xferp->cmd[0]);              id, xferp->cmd[0]);
518    
519  #if 0  #if 0
520          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",          fatal("[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",
521              scsi_id, xferp->cmd[0], xferp->cmd_len);              id, xferp->cmd[0], xferp->cmd_len);
522          for (i=0; i<xferp->cmd_len; i++)          for (i=0; i<xferp->cmd_len; i++)
523                  fatal(" %02x", xferp->cmd[i]);                  fatal(" %02x", xferp->cmd[i]);
524          fatal("\n");          fatal("\n");
# Line 504  if (xferp->cmd_len > 7 && xferp->cmd[5] Line 533  if (xferp->cmd_len > 7 && xferp->cmd[5]
533                  f = fopen("scsi_log.txt", "w");                  f = fopen("scsi_log.txt", "w");
534          if (f != NULL) {          if (f != NULL) {
535                  int i;                  int i;
536                  fprintf(f, "id=%i cmd =", scsi_id);                  fprintf(f, "id=%i cmd =", id);
537                  for (i=0; i<xferp->cmd_len; i++)                  for (i=0; i<xferp->cmd_len; i++)
538                          fprintf(f, " %02x", xferp->cmd[i]);                          fprintf(f, " %02x", xferp->cmd[i]);
539                  fprintf(f, "\n");                  fprintf(f, "\n");
# Line 560  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 589  xferp->data_in[4] = 0x2c - 4;  /*  Additi
589                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */                  xferp->data_in[6] = 0x04;  /*  ACKREQQ  */
590                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */                  xferp->data_in[7] = 0x60;  /*  WBus32, WBus16  */
591    
592                  /*  These must be padded with spaces:  */                  /*  These are padded with spaces:  */
593                  memcpy(xferp->data_in+8,  "FAKE    ", 8);  
594                  memcpy(xferp->data_in+16, "DISK            ", 16);                  memcpy(xferp->data_in+8,  "EMULATED", 8);
595                  memcpy(xferp->data_in+32, "V0.0", 4);                  if (diskimage_getname(cpu->machine, id,
596                        type, namebuf, sizeof(namebuf))) {
597                            int i;
598                            for (i=0; i<sizeof(namebuf); i++)
599                                    if (namebuf[i] == 0) {
600                                            for (; i<sizeof(namebuf); i++)
601                                                    namebuf[i] = ' ';
602                                            break;
603                                    }
604                            memcpy(xferp->data_in+16, namebuf, 16);
605                    } else
606                            memcpy(xferp->data_in+16, "DISK            ", 16);
607                    memcpy(xferp->data_in+32, "0000", 4);
608    
609                  /*                  /*
610                   *  Some Ultrix kernels want specific responses from                   *  Some Ultrix kernels want specific responses from
# Line 694  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 735  xferp->data_in[4] = 0x2c - 4;  /*  Additi
735    
736                  pagecode = xferp->cmd[2] & 0x3f;                  pagecode = xferp->cmd[2] & 0x3f;
737    
738                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", scsi_id, pagecode);                  debug("[ MODE SENSE id %i, pagecode=%i ]\n", id, pagecode);
739    
740                  /*  4 bytes of header for 6-byte command,                  /*  4 bytes of header for 6-byte command,
741                      8 bytes of header for 10-byte command.  */                      8 bytes of header for 10-byte command.  */
# Line 735  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 776  xferp->data_in[4] = 0x2c - 4;  /*  Additi
776    
777                          /*  10,11 = sectors per track  */                          /*  10,11 = sectors per track  */
778                          xferp->data_in[12 + 10] = 0;                          xferp->data_in[12 + 10] = 0;
779                          xferp->data_in[12 + 11] = 1;    /*  TODO  */                          xferp->data_in[12 + 11] = d->sectors_per_track;
780    
781                          /*  12,13 = physical sector size  */                          /*  12,13 = physical sector size  */
782                          xferp->data_in[12 + 12] =                          xferp->data_in[12 + 12] =
# Line 748  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 789  xferp->data_in[4] = 0x2c - 4;  /*  Additi
789                          xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255;                          xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255;
790                          xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255;                          xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255;
791                          xferp->data_in[12 + 4] = d->ncyls & 255;                          xferp->data_in[12 + 4] = d->ncyls & 255;
792                          xferp->data_in[12 + 5] = 15;    /*  nr of heads  */                          xferp->data_in[12 + 5] = d->heads;
793    
794                          xferp->data_in[12 + 20] = (d->rpms >> 8) & 255;                          xferp->data_in[12 + 20] = (d->rpms >> 8) & 255;
795                          xferp->data_in[12 + 21] = d->rpms & 255;                          xferp->data_in[12 + 21] = d->rpms & 255;
# Line 761  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 802  xferp->data_in[4] = 0x2c - 4;  /*  Additi
802                          xferp->data_in[12 + 2] = ((5000) >> 8) & 255;                          xferp->data_in[12 + 2] = ((5000) >> 8) & 255;
803                          xferp->data_in[12 + 3] = (5000) & 255;                          xferp->data_in[12 + 3] = (5000) & 255;
804    
805                          xferp->data_in[12 + 4] = 2;    /*  nr of heads  */                          xferp->data_in[12 + 4] = d->heads;
806                          xferp->data_in[12 + 5] = 18;   /*  sectors per track  */                          xferp->data_in[12 + 5] = d->sectors_per_track;
807    
808                          /*  6,7 = data bytes per sector  */                          /*  6,7 = data bytes per sector  */
809                          xferp->data_in[12 + 6] = (d->logical_block_size >> 8)                          xferp->data_in[12 + 6] = (d->logical_block_size >> 8)
# Line 819  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 860  xferp->data_in[4] = 0x2c - 4;  /*  Additi
860                          ofs = d->tape_offset;                          ofs = d->tape_offset;
861    
862                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"                          fatal("[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i"
863                              ", ofs=%lli ]\n", scsi_id, d->tape_filenr,                              ", ofs=%lli ]\n", id, d->tape_filenr,
864                              xferp->cmd[1], (int)size, (long long)ofs);                              xferp->cmd[1], (int)size, (long long)ofs);
865                  } else {                  } else {
866                          if (xferp->cmd[0] == SCSICMD_READ) {                          if (xferp->cmd[0] == SCSICMD_READ) {
# Line 882  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 923  xferp->data_in[4] = 0x2c - 4;  /*  Additi
923                   *   be set to NO SENSE"..                   *   be set to NO SENSE"..
924                   */                   */
925                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {                  if (d->is_a_tape && d->f != NULL && feof(d->f)) {
926                          debug(" feof id=%i\n", scsi_id);                          debug(" feof id=%i\n", id);
927                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */                          xferp->status[0] = 0x02;        /*  CHECK CONDITION  */
928    
929                          d->filemark = 1;                          d->filemark = 1;
# Line 891  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 932  xferp->data_in[4] = 0x2c - 4;  /*  Additi
932                              xferp->data_in, size);                              xferp->data_in, size);
933    
934                  if (d->is_a_tape && d->f != NULL)                  if (d->is_a_tape && d->f != NULL)
935                          d->tape_offset = ftell(d->f);                          d->tape_offset = ftello(d->f);
936    
937                  /*  TODO: other errors?  */                  /*  TODO: other errors?  */
938                  break;                  break;
# Line 978  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1019  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1019                  if (xferp->cmd_len != 6)                  if (xferp->cmd_len != 6)
1020                          debug(" (weird len=%i)", xferp->cmd_len);                          debug(" (weird len=%i)", xferp->cmd_len);
1021    
1022                  for (i=0; i<xferp->cmd_len ; i++)                  for (i=0; i<xferp->cmd_len; i++)
1023                          debug(" %02x", xferp->cmd[i]);                          debug(" %02x", xferp->cmd[i]);
1024    
1025                  /*  TODO: actualy care about cmd[]  */                  /*  TODO: actualy care about cmd[]  */
# Line 1275  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1316  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1316                      &xferp->data_in, retlen, 1);                      &xferp->data_in, retlen, 1);
1317    
1318                  diskimage__return_default_status_and_message(xferp);                  diskimage__return_default_status_and_message(xferp);
1319    
1320                  break;                  break;
1321    
1322          default:          default:
1323                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",                  fatal("[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",
1324                      xferp->cmd[0], scsi_id);                      xferp->cmd[0], id);
1325                  exit(1);                  exit(1);
1326          }          }
1327          debug(" ]\n");          debug(" ]\n");
# Line 1295  xferp->data_in[4] = 0x2c - 4;  /*  Additi Line 1337  xferp->data_in[4] = 0x2c - 4;  /*  Additi
1337   *   *
1338   *  Returns 1 if the access completed successfully, 0 otherwise.   *  Returns 1 if the access completed successfully, 0 otherwise.
1339   */   */
1340  int diskimage_access(struct machine *machine, int scsi_id, int writeflag,  int diskimage_access(struct machine *machine, int id, int type, int writeflag,
1341          off_t offset, unsigned char *buf, size_t len)          off_t offset, unsigned char *buf, size_t len)
1342  {  {
1343          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1344    
         /*  
          *  TODO: How about mixing SCSI, IDE, and FLOPPY in one  
          *        emulated machine?  
          */  
   
1345          while (d != NULL) {          while (d != NULL) {
1346                  if ( /* d->type == DISKIMAGE_SCSI && */ d->id == scsi_id)                  if (d->type == type && d->id == id)
1347                          break;                          break;
1348                  d = d->next;                  d = d->next;
1349          }          }
1350    
1351          if (d == NULL) {          if (d == NULL) {
1352                  fatal("[ diskimage_access(): ERROR: trying to access a "                  fatal("[ diskimage_access(): ERROR: trying to access a "
1353                      "non-existant SCSI disk image (%i)\n", scsi_id);                      "non-existant %s disk image (id %i)\n",
1354                        diskimage_types[type], id);
1355                  return 0;                  return 0;
1356          }          }
1357    
# Line 1328  int diskimage_access(struct machine *mac Line 1366  int diskimage_access(struct machine *mac
1366   *  The filename may be prefixed with one or more modifiers, followed   *  The filename may be prefixed with one or more modifiers, followed
1367   *  by a colon.   *  by a colon.
1368   *   *
1369   *      b       specifies that this is the boot device   *      b       specifies that this is a bootable device
1370   *      c       CD-ROM (instead of normal SCSI DISK)   *      c       CD-ROM (instead of a normal DISK)
1371   *      d       DISK (this is the default)   *      d       DISK (this is the default)
1372   *      f       FLOPPY (instead of SCSI)   *      f       FLOPPY (instead of SCSI)
1373     *      gH;S;   set geometry (H=heads, S=sectors per track, cylinders are
1374     *              automatically calculated). (This is ignored for floppies.)
1375   *      i       IDE (instead of SCSI)   *      i       IDE (instead of SCSI)
1376   *      r       read-only (don't allow changes to the file)   *      r       read-only (don't allow changes to the file)
1377   *      s       SCSI (this is the default)   *      s       SCSI (this is the default)
# Line 1344  int diskimage_access(struct machine *mac Line 1384  int diskimage_access(struct machine *mac
1384  int diskimage_add(struct machine *machine, char *fname)  int diskimage_add(struct machine *machine, char *fname)
1385  {  {
1386          struct diskimage *d, *d2;          struct diskimage *d, *d2;
1387          int id = 0;          int id = 0, override_heads=0, override_spt=0;
1388            int64_t bytespercyl;
1389          char *cp;          char *cp;
1390          int prefix_b = 0;          int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
1391          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;  
1392    
1393          if (fname == NULL) {          if (fname == NULL) {
1394                  fprintf(stderr, "diskimage_add(): NULL ptr\n");                  fprintf(stderr, "diskimage_add(): NULL ptr\n");
# Line 1389  int diskimage_add(struct machine *machin Line 1423  int diskimage_add(struct machine *machin
1423                          case 'f':                          case 'f':
1424                                  prefix_f = 1;                                  prefix_f = 1;
1425                                  break;                                  break;
1426                            case 'g':
1427                                    prefix_g = 1;
1428                                    override_heads = atoi(fname);
1429                                    while (*fname != '\0' && *fname != ';')
1430                                            fname ++;
1431                                    if (*fname == ';')
1432                                            fname ++;
1433                                    override_spt = atoi(fname);
1434                                    while (*fname != '\0' && *fname != ';' &&
1435                                        *fname != ':')
1436                                            fname ++;
1437                                    if (*fname == ';')
1438                                            fname ++;
1439                                    if (override_heads < 1 ||
1440                                        override_spt < 1) {
1441                                            fatal("Bad geometry: heads=%i "
1442                                                "spt=%i\n", override_heads,
1443                                                override_spt);
1444                                            exit(1);
1445                                    }
1446                                    break;
1447                          case 'i':                          case 'i':
1448                                  prefix_i = 1;                                  prefix_i = 1;
1449                                  break;                                  break;
# Line 1411  int diskimage_add(struct machine *machin Line 1466  int diskimage_add(struct machine *machin
1466                  }                  }
1467          }          }
1468    
         /*  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;  
                 }  
         }  
   
1469          /*  Allocate a new diskimage struct:  */          /*  Allocate a new diskimage struct:  */
1470          d = malloc(sizeof(struct diskimage));          d = malloc(sizeof(struct diskimage));
1471          if (d == NULL) {          if (d == NULL) {
# Line 1462  int diskimage_add(struct machine *machin Line 1484  int diskimage_add(struct machine *machin
1484          }          }
1485    
1486          d->type = DISKIMAGE_SCSI;          d->type = DISKIMAGE_SCSI;
         d->id = id;  
1487    
1488          /*  Special cases: some machines usually have FLOPPY/IDE, not SCSI:  */          /*  Special cases: some machines usually have FLOPPY/IDE, not SCSI:  */
1489          if (machine->arch == ARCH_X86 ||          if (machine->arch == ARCH_X86 ||
1490              machine->machine_type == MACHINE_COBALT ||              machine->machine_type == MACHINE_COBALT ||
1491                machine->machine_type == MACHINE_EVBMIPS ||
1492              machine->machine_type == MACHINE_HPCMIPS ||              machine->machine_type == MACHINE_HPCMIPS ||
1493                machine->machine_type == MACHINE_CATS ||
1494                machine->machine_type == MACHINE_NETWINDER ||
1495              machine->machine_type == MACHINE_PS2)              machine->machine_type == MACHINE_PS2)
1496                  d->type = DISKIMAGE_IDE;                  d->type = DISKIMAGE_IDE;
1497    
# Line 1496  int diskimage_add(struct machine *machin Line 1520  int diskimage_add(struct machine *machin
1520           *  Is this a tape, CD-ROM or a normal disk?           *  Is this a tape, CD-ROM or a normal disk?
1521           *           *
1522           *  An intelligent guess, if no prefixes are used, would be that           *  An intelligent guess, if no prefixes are used, would be that
1523           *  filenames ending with .iso are CD-ROM images.           *  filenames ending with .iso or .cdr are CD-ROM images.
1524           */           */
1525          if (prefix_t) {          if (prefix_t) {
1526                  d->is_a_tape = 1;                  d->is_a_tape = 1;
1527          } else {          } else {
1528                  if (prefix_c ||                  if (prefix_c ||
1529                      ((strlen(d->fname) > 4 &&                      ((strlen(d->fname) > 4 &&
1530                      strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0)                      (strcasecmp(d->fname + strlen(d->fname) - 4, ".cdr") == 0 ||
1531                        strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0))
1532                      && !prefix_d)                      && !prefix_d)
1533                     ) {                     ) {
1534                          d->is_a_cdrom = 1;                          d->is_a_cdrom = 1;
# Line 1532  int diskimage_add(struct machine *machin Line 1557  int diskimage_add(struct machine *machin
1557    
1558          diskimage_recalc_size(d);          diskimage_recalc_size(d);
1559    
1560          if (d->total_size == 1474560 && !prefix_i && !prefix_s)          if ((d->total_size == 720*1024 || d->total_size == 1474560
1561                || d->total_size == 2949120 || d->total_size == 1228800)
1562                && !prefix_i && !prefix_s)
1563                  d->type = DISKIMAGE_FLOPPY;                  d->type = DISKIMAGE_FLOPPY;
1564    
1565            switch (d->type) {
1566            case DISKIMAGE_FLOPPY:
1567                    if (d->total_size < 737280) {
1568                            fatal("\nTODO: small (non-80-cylinder) floppies?\n\n");
1569                            exit(1);
1570                    }
1571                    d->cylinders = 80;
1572                    d->heads = 2;
1573                    d->sectors_per_track = d->total_size / (d->cylinders *
1574                        d->heads * 512);
1575                    break;
1576            default:/*  Non-floppies:  */
1577                    d->heads = 16;
1578                    d->sectors_per_track = 63;
1579                    if (prefix_g) {
1580                            d->chs_override = 1;
1581                            d->heads = override_heads;
1582                            d->sectors_per_track = override_spt;
1583                    }
1584                    bytespercyl = d->heads * d->sectors_per_track * 512;
1585                    d->cylinders = d->total_size / bytespercyl;
1586                    if (d->cylinders * bytespercyl < d->total_size)
1587                            d->cylinders ++;
1588            }
1589    
1590          d->rpms = 3600;          d->rpms = 3600;
1591    
1592          if (prefix_b)          if (prefix_b)
# Line 1551  int diskimage_add(struct machine *machin Line 1603  int diskimage_add(struct machine *machin
1603                  exit(1);                  exit(1);
1604          }          }
1605    
1606            /*  Calculate which ID to use:  */
1607            if (prefix_id == -1) {
1608                    int free = 0, collision = 1;
1609    
1610                    while (collision) {
1611                            collision = 0;
1612                            d2 = machine->first_diskimage;
1613                            while (d2 != NULL) {
1614                                    /*  (don't compare against ourselves :)  */
1615                                    if (d2 == d) {
1616                                            d2 = d2->next;
1617                                            continue;
1618                                    }
1619                                    if (d2->id == free && d2->type == d->type) {
1620                                            collision = 1;
1621                                            break;
1622                                    }
1623                                    d2 = d2->next;
1624                            }
1625                            if (!collision)
1626                                    id = free;
1627                            else
1628                                    free ++;
1629                    }
1630            } else {
1631                    id = prefix_id;
1632                    d2 = machine->first_diskimage;
1633                    while (d2 != NULL) {
1634                            /*  (don't compare against ourselves :)  */
1635                            if (d2 == d) {
1636                                    d2 = d2->next;
1637                                    continue;
1638                            }
1639                            if (d2->id == id && d2->type == d->type) {
1640                                    fprintf(stderr, "disk image id %i "
1641                                        "already in use\n", id);
1642                                    exit(1);
1643                            }
1644                            d2 = d2->next;
1645                    }
1646            }
1647    
1648            d->id = id;
1649    
1650          return id;          return id;
1651  }  }
1652    
# Line 1558  int diskimage_add(struct machine *machin Line 1654  int diskimage_add(struct machine *machin
1654  /*  /*
1655   *  diskimage_bootdev():   *  diskimage_bootdev():
1656   *   *
1657   *  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
1658     *  non-NULL, the type is returned as well.
1659   *   *
1660   *  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,
1661   *  this is used to fake network (tftp) boot.)   *  this is used to fake network (tftp) boot.)
1662   */   */
1663  int diskimage_bootdev(struct machine *machine)  int diskimage_bootdev(struct machine *machine, int *typep)
1664  {  {
1665          struct diskimage *d = machine->first_diskimage;          struct diskimage *d;
1666    
1667            d = machine->first_diskimage;
1668          while (d != NULL) {          while (d != NULL) {
1669                  if (d->is_boot_device)                  if (d->is_boot_device) {
1670                            if (typep != NULL)
1671                                    *typep = d->type;
1672                          return d->id;                          return d->id;
1673                    }
1674                  d = d->next;                  d = d->next;
1675          }          }
1676    
1677          d = machine->first_diskimage;          d = machine->first_diskimage;
1678          if (d != NULL)          if (d != NULL) {
1679                    if (typep != NULL)
1680                            *typep = d->type;
1681                  return d->id;                  return d->id;
1682            }
1683    
1684          return -1;          return -1;
1685  }  }
1686    
1687    
1688  /*  /*
1689     *  diskimage_getname():
1690     *
1691     *  Returns 1 if a valid disk image name was returned, 0 otherwise.
1692     */
1693    int diskimage_getname(struct machine *machine, int id, int type,
1694            char *buf, size_t bufsize)
1695    {
1696            struct diskimage *d = machine->first_diskimage;
1697    
1698            if (buf == NULL)
1699                    return 0;
1700    
1701            while (d != NULL) {
1702                    if (d->type == type && d->id == id) {
1703                            char *p = strrchr(d->fname, '/');
1704                            if (p == NULL)
1705                                    p = d->fname;
1706                            else
1707                                    p ++;
1708                            snprintf(buf, bufsize, "%s", p);
1709                            return 1;
1710                    }
1711                    d = d->next;
1712            }
1713            return 0;
1714    }
1715    
1716    
1717    /*
1718   *  diskimage_is_a_cdrom():   *  diskimage_is_a_cdrom():
1719   *   *
1720   *  Returns 1 if a disk image is a SCSI CDROM, 0 otherwise.   *  Returns 1 if a disk image is a CDROM, 0 otherwise.
1721   */   */
1722  int diskimage_is_a_cdrom(struct machine *machine, int scsi_id)  int diskimage_is_a_cdrom(struct machine *machine, int id, int type)
1723  {  {
1724          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1725    
1726          while (d != NULL) {          while (d != NULL) {
1727                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1728                          return d->is_a_cdrom;                          return d->is_a_cdrom;
1729                  d = d->next;                  d = d->next;
1730          }          }
# Line 1601  int diskimage_is_a_cdrom(struct machine Line 1735  int diskimage_is_a_cdrom(struct machine
1735  /*  /*
1736   *  diskimage_is_a_tape():   *  diskimage_is_a_tape():
1737   *   *
1738   *  Returns 1 if a disk image is a SCSI tape, 0 otherwise.   *  Returns 1 if a disk image is a tape, 0 otherwise.
1739     *
1740   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation   *  (Used in src/machine.c, to select 'rz' vs 'tz' for DECstation
1741   *  boot strings.)   *  boot strings.)
1742   */   */
1743  int diskimage_is_a_tape(struct machine *machine, int scsi_id)  int diskimage_is_a_tape(struct machine *machine, int id, int type)
1744  {  {
1745          struct diskimage *d = machine->first_diskimage;          struct diskimage *d = machine->first_diskimage;
1746    
1747          while (d != NULL) {          while (d != NULL) {
1748                  if (d->type == DISKIMAGE_SCSI && d->id == scsi_id)                  if (d->type == type && d->id == id)
1749                          return d->is_a_tape;                          return d->is_a_tape;
1750                  d = d->next;                  d = d->next;
1751          }          }
# Line 1656  void diskimage_dump_info(struct machine Line 1791  void diskimage_dump_info(struct machine
1791                  else                  else
1792                          debug("%lli MB", (long long) (d->total_size / 1048576));                          debug("%lli MB", (long long) (d->total_size / 1048576));
1793    
1794                  debug(" (%lli sectors)%s\n",                  if (d->type == DISKIMAGE_FLOPPY || d->chs_override)
1795                      (long long) (d->total_size / 512),                          debug(" (CHS=%i,%i,%i)", d->cylinders, d->heads,
1796                      d->is_boot_device? " (BOOT)" : "");                              d->sectors_per_track);
1797                    else
1798                            debug(" (%lli sectors)", (long long)
1799                               (d->total_size / 512));
1800    
1801                    if (d->is_boot_device)
1802                            debug(" (BOOT)");
1803                    debug("\n");
1804    
1805                  debug_indentation(-iadd);                  debug_indentation(-iadd);
1806    

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

  ViewVC Help
Powered by ViewVC 1.1.26