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.102 2005/11/21 09:17:25 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; |
480 |
struct scsi_transfer *xferp) |
struct scsi_transfer *xferp) |
481 |
{ |
{ |
482 |
char namebuf[16]; |
char namebuf[16]; |
483 |
int retlen, i; |
int retlen, i, q; |
484 |
uint64_t size; |
uint64_t size; |
485 |
int64_t ofs; |
int64_t ofs; |
486 |
int pagecode; |
int pagecode; |
592 |
|
|
593 |
/* These are padded with spaces: */ |
/* These are padded with spaces: */ |
594 |
|
|
595 |
memcpy(xferp->data_in+8, "EMULATED", 8); |
memcpy(xferp->data_in+8, "GXemul ", 8); |
596 |
if (diskimage_getname(cpu->machine, id, |
if (diskimage_getname(cpu->machine, id, |
597 |
type, namebuf, sizeof(namebuf))) { |
type, namebuf, sizeof(namebuf))) { |
598 |
int i; |
int i; |
605 |
memcpy(xferp->data_in+16, namebuf, 16); |
memcpy(xferp->data_in+16, namebuf, 16); |
606 |
} else |
} else |
607 |
memcpy(xferp->data_in+16, "DISK ", 16); |
memcpy(xferp->data_in+16, "DISK ", 16); |
608 |
memcpy(xferp->data_in+32, "0000", 4); |
memcpy(xferp->data_in+32, "0 ", 4); |
609 |
|
|
610 |
/* |
/* |
611 |
* Some Ultrix kernels want specific responses from |
* Some Ultrix kernels want specific responses from |
624 |
if (d->is_a_cdrom) { |
if (d->is_a_cdrom) { |
625 |
xferp->data_in[0] = 0x05; /* 0x05 = CD-ROM */ |
xferp->data_in[0] = 0x05; /* 0x05 = CD-ROM */ |
626 |
xferp->data_in[1] = 0x80; /* 0x80 = removable */ |
xferp->data_in[1] = 0x80; /* 0x80 = removable */ |
627 |
memcpy(xferp->data_in+16, "CD-ROM ", 16); |
/* memcpy(xferp->data_in+16, "CD-ROM ", 16);*/ |
628 |
|
|
629 |
if (machine->machine_type == MACHINE_DEC) { |
if (machine->machine_type == MACHINE_DEC) { |
630 |
/* SONY, CD-ROM: */ |
/* SONY, CD-ROM: */ |
637 |
memcpy(xferp->data_in+16, |
memcpy(xferp->data_in+16, |
638 |
"RRD42 (C) DEC ", 16); |
"RRD42 (C) DEC ", 16); |
639 |
memcpy(xferp->data_in+32, "4.5d", 4); |
memcpy(xferp->data_in+32, "4.5d", 4); |
640 |
} else { |
} else if (machine->machine_type == MACHINE_ARC) { |
641 |
/* NEC, CD-ROM: */ |
/* NEC, CD-ROM: */ |
642 |
memcpy(xferp->data_in+8, "NEC ", 8); |
memcpy(xferp->data_in+8, "NEC ", 8); |
643 |
memcpy(xferp->data_in+16, |
memcpy(xferp->data_in+16, |
707 |
break; |
break; |
708 |
|
|
709 |
case SCSICMD_MODE_SENSE: |
case SCSICMD_MODE_SENSE: |
710 |
|
case SCSICMD_MODE_SENSE10: |
711 |
debug("MODE_SENSE"); |
debug("MODE_SENSE"); |
712 |
|
q = 4; retlen = xferp->cmd[4]; |
713 |
if (xferp->cmd_len != 6) |
switch (xferp->cmd_len) { |
714 |
fatal(" (unimplemented mode_sense len=%i)", |
case 6: break; |
715 |
|
case 10:q = 8; |
716 |
|
retlen = xferp->cmd[7] * 256 + xferp->cmd[8]; |
717 |
|
break; |
718 |
|
default:fatal(" (unimplemented mode_sense len=%i)", |
719 |
xferp->cmd_len); |
xferp->cmd_len); |
720 |
|
} |
|
retlen = xferp->cmd[4]; |
|
721 |
|
|
722 |
/* |
/* |
723 |
* NOTE/TODO: This code doesn't handle too short retlens |
* NOTE/TODO: This code doesn't handle too short retlens |
752 |
xferp->data_in[3] = 8 * 1; /* block descriptor |
xferp->data_in[3] = 8 * 1; /* block descriptor |
753 |
length: 1 page (?) */ |
length: 1 page (?) */ |
754 |
|
|
755 |
/* TODO: update this when implementing 10-byte commands: */ |
xferp->data_in[q+0] = 0x00; /* density code */ |
756 |
xferp->data_in[4] = 0x00; /* density code */ |
xferp->data_in[q+1] = 0; /* nr of blocks, high */ |
757 |
xferp->data_in[5] = 0; /* nr of blocks, high */ |
xferp->data_in[q+2] = 0; /* nr of blocks, mid */ |
758 |
xferp->data_in[6] = 0; /* nr of blocks, mid */ |
xferp->data_in[q+3] = 0; /* nr of blocks, low */ |
759 |
xferp->data_in[7] = 0; /* nr of blocks, low */ |
xferp->data_in[q+4] = 0x00; /* reserved */ |
760 |
xferp->data_in[8] = 0x00; /* reserved */ |
xferp->data_in[q+5] = (d->logical_block_size >> 16) & 255; |
761 |
xferp->data_in[9] = (d->logical_block_size >> 16) & 255; |
xferp->data_in[q+6] = (d->logical_block_size >> 8) & 255; |
762 |
xferp->data_in[10] = (d->logical_block_size >> 8) & 255; |
xferp->data_in[q+7] = d->logical_block_size & 255; |
763 |
xferp->data_in[11] = d->logical_block_size & 255; |
q += 8; |
764 |
|
|
765 |
diskimage__return_default_status_and_message(xferp); |
diskimage__return_default_status_and_message(xferp); |
766 |
|
|
772 |
/* TODO: Nothing here? */ |
/* TODO: Nothing here? */ |
773 |
break; |
break; |
774 |
case 1: /* read-write error recovery page */ |
case 1: /* read-write error recovery page */ |
775 |
xferp->data_in[12 + 0] = pagecode; |
xferp->data_in[q + 0] = pagecode; |
776 |
xferp->data_in[12 + 1] = 10; |
xferp->data_in[q + 1] = 10; |
777 |
break; |
break; |
778 |
case 3: /* format device page */ |
case 3: /* format device page */ |
779 |
xferp->data_in[12 + 0] = pagecode; |
xferp->data_in[q + 0] = pagecode; |
780 |
xferp->data_in[12 + 1] = 22; |
xferp->data_in[q + 1] = 22; |
781 |
|
|
782 |
/* 10,11 = sectors per track */ |
/* 10,11 = sectors per track */ |
783 |
xferp->data_in[12 + 10] = 0; |
xferp->data_in[q + 10] = 0; |
784 |
xferp->data_in[12 + 11] = d->sectors_per_track; |
xferp->data_in[q + 11] = d->sectors_per_track; |
785 |
|
|
786 |
/* 12,13 = physical sector size */ |
/* 12,13 = physical sector size */ |
787 |
xferp->data_in[12 + 12] = |
xferp->data_in[q + 12] = |
788 |
(d->logical_block_size >> 8) & 255; |
(d->logical_block_size >> 8) & 255; |
789 |
xferp->data_in[12 + 13] = d->logical_block_size & 255; |
xferp->data_in[q + 13] = d->logical_block_size & 255; |
790 |
break; |
break; |
791 |
case 4: /* rigid disk geometry page */ |
case 4: /* rigid disk geometry page */ |
792 |
xferp->data_in[12 + 0] = pagecode; |
xferp->data_in[q + 0] = pagecode; |
793 |
xferp->data_in[12 + 1] = 22; |
xferp->data_in[q + 1] = 22; |
794 |
xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255; |
xferp->data_in[q + 2] = (d->ncyls >> 16) & 255; |
795 |
xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255; |
xferp->data_in[q + 3] = (d->ncyls >> 8) & 255; |
796 |
xferp->data_in[12 + 4] = d->ncyls & 255; |
xferp->data_in[q + 4] = d->ncyls & 255; |
797 |
xferp->data_in[12 + 5] = d->heads; |
xferp->data_in[q + 5] = d->heads; |
798 |
|
|
799 |
xferp->data_in[12 + 20] = (d->rpms >> 8) & 255; |
xferp->data_in[q + 20] = (d->rpms >> 8) & 255; |
800 |
xferp->data_in[12 + 21] = d->rpms & 255; |
xferp->data_in[q + 21] = d->rpms & 255; |
801 |
break; |
break; |
802 |
case 5: /* flexible disk page */ |
case 5: /* flexible disk page */ |
803 |
xferp->data_in[12 + 0] = pagecode; |
xferp->data_in[q + 0] = pagecode; |
804 |
xferp->data_in[12 + 1] = 0x1e; |
xferp->data_in[q + 1] = 0x1e; |
805 |
|
|
806 |
/* 2,3 = transfer rate */ |
/* 2,3 = transfer rate */ |
807 |
xferp->data_in[12 + 2] = ((5000) >> 8) & 255; |
xferp->data_in[q + 2] = ((5000) >> 8) & 255; |
808 |
xferp->data_in[12 + 3] = (5000) & 255; |
xferp->data_in[q + 3] = (5000) & 255; |
809 |
|
|
810 |
xferp->data_in[12 + 4] = d->heads; |
xferp->data_in[q + 4] = d->heads; |
811 |
xferp->data_in[12 + 5] = d->sectors_per_track; |
xferp->data_in[q + 5] = d->sectors_per_track; |
812 |
|
|
813 |
/* 6,7 = data bytes per sector */ |
/* 6,7 = data bytes per sector */ |
814 |
xferp->data_in[12 + 6] = (d->logical_block_size >> 8) |
xferp->data_in[q + 6] = (d->logical_block_size >> 8) |
815 |
& 255; |
& 255; |
816 |
xferp->data_in[12 + 7] = d->logical_block_size & 255; |
xferp->data_in[q + 7] = d->logical_block_size & 255; |
817 |
|
|
818 |
xferp->data_in[12 + 8] = (d->ncyls >> 8) & 255; |
xferp->data_in[q + 8] = (d->ncyls >> 8) & 255; |
819 |
xferp->data_in[12 + 9] = d->ncyls & 255; |
xferp->data_in[q + 9] = d->ncyls & 255; |
820 |
|
|
821 |
xferp->data_in[12 + 28] = (d->rpms >> 8) & 255; |
xferp->data_in[q + 28] = (d->rpms >> 8) & 255; |
822 |
xferp->data_in[12 + 29] = d->rpms & 255; |
xferp->data_in[q + 29] = d->rpms & 255; |
823 |
break; |
break; |
824 |
default: |
default: |
825 |
fatal("[ MODE_SENSE for page %i is not yet " |
fatal("[ MODE_SENSE for page %i is not yet " |
1233 |
scsi_transfer_allocbuf(&xferp->data_in_len, |
scsi_transfer_allocbuf(&xferp->data_in_len, |
1234 |
&xferp->data_in, retlen, 1); |
&xferp->data_in, retlen, 1); |
1235 |
|
|
1236 |
/* TODO */ |
xferp->data_in[0] = 0; |
1237 |
|
xferp->data_in[1] = 10; |
1238 |
|
xferp->data_in[2] = 0; /* First track. */ |
1239 |
|
xferp->data_in[3] = 0; /* Last track. */ |
1240 |
|
|
1241 |
|
/* Track 0 data: */ |
1242 |
|
xferp->data_in[4] = 0x00; /* Reserved. */ |
1243 |
|
xferp->data_in[5] = 0x04; /* ADR + CTRL: |
1244 |
|
Data, not audio */ |
1245 |
|
xferp->data_in[6] = 0x00; /* Track nr */ |
1246 |
|
xferp->data_in[7] = 0x00; /* Reserved */ |
1247 |
|
/* 8..11 = absolute CDROM address */ |
1248 |
|
|
1249 |
diskimage__return_default_status_and_message(xferp); |
diskimage__return_default_status_and_message(xferp); |
1250 |
break; |
break; |
1297 |
diskimage__return_default_status_and_message(xferp); |
diskimage__return_default_status_and_message(xferp); |
1298 |
break; |
break; |
1299 |
|
|
1300 |
case 0x1e: |
case SCSICMD_PREVENT_ALLOW_REMOVE: |
1301 |
debug("[ SCSI 0x%02x: TODO ]\n", xferp->cmd[0]); |
debug("[ SCSI 0x%02x Prevent/allow medium removal: " |
1302 |
|
"TODO ]\n", xferp->cmd[0]); |
|
/* TODO */ |
|
1303 |
|
|
1304 |
diskimage__return_default_status_and_message(xferp); |
diskimage__return_default_status_and_message(xferp); |
1305 |
break; |
break; |
1505 |
machine->machine_type == MACHINE_COBALT || |
machine->machine_type == MACHINE_COBALT || |
1506 |
machine->machine_type == MACHINE_EVBMIPS || |
machine->machine_type == MACHINE_EVBMIPS || |
1507 |
machine->machine_type == MACHINE_HPCMIPS || |
machine->machine_type == MACHINE_HPCMIPS || |
1508 |
|
machine->machine_type == MACHINE_BEBOX || |
1509 |
|
machine->machine_type == MACHINE_PREP || |
1510 |
machine->machine_type == MACHINE_CATS || |
machine->machine_type == MACHINE_CATS || |
1511 |
machine->machine_type == MACHINE_NETWINDER || |
machine->machine_type == MACHINE_NETWINDER || |
1512 |
machine->machine_type == MACHINE_PS2) |
machine->machine_type == MACHINE_PS2) |