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: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: diskimage.c,v 1.98 2005/09/27 23:55:43 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 |
* |
* |
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; |
static char *diskimage_types[] = DISKIMAGE_TYPES; |
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(): |
* diskimage_getchs(): |
306 |
* |
* |
307 |
* Returns the current CHS values of a disk image. |
* Returns the current CHS values of a disk image. |
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 |
|
|
501 |
struct scsi_transfer *xferp) |
struct scsi_transfer *xferp) |
502 |
{ |
{ |
503 |
char namebuf[16]; |
char namebuf[16]; |
504 |
int retlen, i; |
int retlen, i, q; |
505 |
uint64_t size; |
uint64_t size; |
506 |
int64_t ofs; |
int64_t ofs; |
507 |
int pagecode; |
int pagecode; |
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 |
613 |
|
|
614 |
/* These are padded with spaces: */ |
/* These are padded with spaces: */ |
615 |
|
|
616 |
memcpy(xferp->data_in+8, "EMULATED", 8); |
memcpy(xferp->data_in+8, "GXemul ", 8); |
617 |
if (diskimage_getname(cpu->machine, id, |
if (diskimage_getname(cpu->machine, id, |
618 |
type, namebuf, sizeof(namebuf))) { |
type, namebuf, sizeof(namebuf))) { |
619 |
int i; |
size_t i; |
620 |
for (i=0; i<sizeof(namebuf); i++) |
for (i=0; i<sizeof(namebuf); i++) |
621 |
if (namebuf[i] == 0) { |
if (namebuf[i] == 0) { |
622 |
for (; i<sizeof(namebuf); i++) |
for (; i<sizeof(namebuf); i++) |
626 |
memcpy(xferp->data_in+16, namebuf, 16); |
memcpy(xferp->data_in+16, namebuf, 16); |
627 |
} else |
} else |
628 |
memcpy(xferp->data_in+16, "DISK ", 16); |
memcpy(xferp->data_in+16, "DISK ", 16); |
629 |
memcpy(xferp->data_in+32, "0000", 4); |
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); |
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, |
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, |
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 |
* |
* |
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 |
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 |
|
|
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] = d->sectors_per_track; |
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] = d->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] = d->heads; |
xferp->data_in[q + 4] = d->heads; |
832 |
xferp->data_in[12 + 5] = d->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 " |
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 |
|
|
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 |
|
|
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[] */ |
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", |
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); |
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 |
} |
} |
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; |
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 |
|
|
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 |
|
|
1446 |
* gH;S; set geometry (H=heads, S=sectors per track, cylinders are |
* gH;S; set geometry (H=heads, S=sectors per track, cylinders are |
1447 |
* automatically calculated). (This is ignored for floppies.) |
* 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 |
* s SCSI (this is the default) |
* s SCSI (this is the default) |
1452 |
* t tape |
* t tape |
1459 |
{ |
{ |
1460 |
struct diskimage *d, *d2; |
struct diskimage *d, *d2; |
1461 |
int id = 0, override_heads=0, override_spt=0; |
int id = 0, override_heads=0, override_spt=0; |
1462 |
int64_t bytespercyl; |
int64_t bytespercyl, override_base_offset=0; |
1463 |
char *cp; |
char *cp; |
1464 |
int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0; |
int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0; |
1465 |
int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id = -1; |
int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id=-1; |
1466 |
|
int prefix_o=0; |
1467 |
|
|
1468 |
if (fname == NULL) { |
if (fname == NULL) { |
1469 |
fprintf(stderr, "diskimage_add(): NULL ptr\n"); |
fprintf(stderr, "diskimage_add(): NULL ptr\n"); |
1522 |
case 'i': |
case 'i': |
1523 |
prefix_i = 1; |
prefix_i = 1; |
1524 |
break; |
break; |
1525 |
|
case 'o': |
1526 |
|
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; |
1539 |
case 'r': |
case 'r': |
1540 |
prefix_r = 1; |
prefix_r = 1; |
1541 |
break; |
break; |
1572 |
d2->next = d; |
d2->next = d; |
1573 |
} |
} |
1574 |
|
|
1575 |
d->type = DISKIMAGE_SCSI; |
/* Default to IDE disks... */ |
1576 |
|
d->type = DISKIMAGE_IDE; |
1577 |
|
|
1578 |
/* Special cases: some machines usually have FLOPPY/IDE, not SCSI: */ |
/* ... but some machines use SCSI by default: */ |
1579 |
if (machine->arch == ARCH_X86 || |
if (machine->machine_type == MACHINE_PMAX || |
1580 |
machine->machine_type == MACHINE_COBALT || |
machine->machine_type == MACHINE_ARC) |
1581 |
machine->machine_type == MACHINE_EVBMIPS || |
d->type = DISKIMAGE_SCSI; |
|
machine->machine_type == MACHINE_HPCMIPS || |
|
|
machine->machine_type == MACHINE_CATS || |
|
|
machine->machine_type == MACHINE_NETWINDER || |
|
|
machine->machine_type == MACHINE_PS2) |
|
|
d->type = DISKIMAGE_IDE; |
|
1582 |
|
|
1583 |
if (prefix_i + prefix_f + prefix_s > 1) { |
if (prefix_i + prefix_f + prefix_s > 1) { |
1584 |
fprintf(stderr, "Invalid disk image prefix(es). You can" |
fprintf(stderr, "Invalid disk image prefix(es). You can" |
1593 |
if (prefix_s) |
if (prefix_s) |
1594 |
d->type = DISKIMAGE_SCSI; |
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) { |
1601 |
fprintf(stderr, "out of memory\n"); |
fprintf(stderr, "out of memory\n"); |
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; |
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) { |