--- trunk/src/diskimage.c 2007/10/08 16:18:38 12 +++ trunk/src/diskimage.c 2007/10/08 16:19:37 22 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2003-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: diskimage.c,v 1.95 2005/08/10 22:25:50 debug Exp $ + * $Id: diskimage.c,v 1.108 2006/01/11 20:14:41 debug Exp $ * * Disk image support. * @@ -53,7 +53,8 @@ #include "misc.h" -extern int quiet_mode; +/* #define debug fatal */ + extern int single_step; static char *diskimage_types[] = DISKIMAGE_TYPES; @@ -478,7 +479,8 @@ int diskimage_scsicommand(struct cpu *cpu, int id, int type, struct scsi_transfer *xferp) { - int retlen, i; + char namebuf[16]; + int retlen, i, q; uint64_t size; int64_t ofs; int pagecode; @@ -588,17 +590,29 @@ xferp->data_in[6] = 0x04; /* ACKREQQ */ xferp->data_in[7] = 0x60; /* WBus32, WBus16 */ - /* These must be padded with spaces: */ - memcpy(xferp->data_in+8, "FAKE ", 8); - memcpy(xferp->data_in+16, "DISK ", 16); - memcpy(xferp->data_in+32, "V0.0", 4); + /* These are padded with spaces: */ + + memcpy(xferp->data_in+8, "GXemul ", 8); + if (diskimage_getname(cpu->machine, id, + type, namebuf, sizeof(namebuf))) { + size_t i; + for (i=0; idata_in+16, namebuf, 16); + } else + memcpy(xferp->data_in+16, "DISK ", 16); + memcpy(xferp->data_in+32, "0 ", 4); /* * Some Ultrix kernels want specific responses from * the drives. */ - if (machine->machine_type == MACHINE_DEC) { + if (machine->machine_type == MACHINE_PMAX) { /* DEC, RZ25 (rev 0900) = 832527 sectors */ /* DEC, RZ58 (rev 2000) = 2698061 sectors */ memcpy(xferp->data_in+8, "DEC ", 8); @@ -610,9 +624,9 @@ if (d->is_a_cdrom) { xferp->data_in[0] = 0x05; /* 0x05 = CD-ROM */ xferp->data_in[1] = 0x80; /* 0x80 = removable */ - memcpy(xferp->data_in+16, "CD-ROM ", 16); + /* memcpy(xferp->data_in+16, "CD-ROM ", 16);*/ - if (machine->machine_type == MACHINE_DEC) { + if (machine->machine_type == MACHINE_PMAX) { /* SONY, CD-ROM: */ memcpy(xferp->data_in+8, "SONY ", 8); memcpy(xferp->data_in+16, @@ -623,7 +637,7 @@ memcpy(xferp->data_in+16, "RRD42 (C) DEC ", 16); memcpy(xferp->data_in+32, "4.5d", 4); - } else { + } else if (machine->machine_type == MACHINE_ARC) { /* NEC, CD-ROM: */ memcpy(xferp->data_in+8, "NEC ", 8); memcpy(xferp->data_in+16, @@ -638,7 +652,7 @@ xferp->data_in[1] = 0x80; /* 0x80 = removable */ memcpy(xferp->data_in+16, "TAPE ", 16); - if (machine->machine_type == MACHINE_DEC) { + if (machine->machine_type == MACHINE_PMAX) { /* * TODO: find out if these are correct. * @@ -693,13 +707,17 @@ break; case SCSICMD_MODE_SENSE: + case SCSICMD_MODE_SENSE10: debug("MODE_SENSE"); - - if (xferp->cmd_len != 6) - fatal(" (unimplemented mode_sense len=%i)", + q = 4; retlen = xferp->cmd[4]; + switch (xferp->cmd_len) { + case 6: break; + case 10:q = 8; + retlen = xferp->cmd[7] * 256 + xferp->cmd[8]; + break; + default:fatal(" (unimplemented mode_sense len=%i)", xferp->cmd_len); - - retlen = xferp->cmd[4]; + } /* * NOTE/TODO: This code doesn't handle too short retlens @@ -734,15 +752,15 @@ xferp->data_in[3] = 8 * 1; /* block descriptor length: 1 page (?) */ - /* TODO: update this when implementing 10-byte commands: */ - xferp->data_in[4] = 0x00; /* density code */ - xferp->data_in[5] = 0; /* nr of blocks, high */ - xferp->data_in[6] = 0; /* nr of blocks, mid */ - xferp->data_in[7] = 0; /* nr of blocks, low */ - xferp->data_in[8] = 0x00; /* reserved */ - xferp->data_in[9] = (d->logical_block_size >> 16) & 255; - xferp->data_in[10] = (d->logical_block_size >> 8) & 255; - xferp->data_in[11] = d->logical_block_size & 255; + xferp->data_in[q+0] = 0x00; /* density code */ + xferp->data_in[q+1] = 0; /* nr of blocks, high */ + xferp->data_in[q+2] = 0; /* nr of blocks, mid */ + xferp->data_in[q+3] = 0; /* nr of blocks, low */ + xferp->data_in[q+4] = 0x00; /* reserved */ + xferp->data_in[q+5] = (d->logical_block_size >> 16) & 255; + xferp->data_in[q+6] = (d->logical_block_size >> 8) & 255; + xferp->data_in[q+7] = d->logical_block_size & 255; + q += 8; diskimage__return_default_status_and_message(xferp); @@ -754,54 +772,54 @@ /* TODO: Nothing here? */ break; case 1: /* read-write error recovery page */ - xferp->data_in[12 + 0] = pagecode; - xferp->data_in[12 + 1] = 10; + xferp->data_in[q + 0] = pagecode; + xferp->data_in[q + 1] = 10; break; case 3: /* format device page */ - xferp->data_in[12 + 0] = pagecode; - xferp->data_in[12 + 1] = 22; + xferp->data_in[q + 0] = pagecode; + xferp->data_in[q + 1] = 22; /* 10,11 = sectors per track */ - xferp->data_in[12 + 10] = 0; - xferp->data_in[12 + 11] = d->sectors_per_track; + xferp->data_in[q + 10] = 0; + xferp->data_in[q + 11] = d->sectors_per_track; /* 12,13 = physical sector size */ - xferp->data_in[12 + 12] = + xferp->data_in[q + 12] = (d->logical_block_size >> 8) & 255; - xferp->data_in[12 + 13] = d->logical_block_size & 255; + xferp->data_in[q + 13] = d->logical_block_size & 255; break; case 4: /* rigid disk geometry page */ - xferp->data_in[12 + 0] = pagecode; - xferp->data_in[12 + 1] = 22; - xferp->data_in[12 + 2] = (d->ncyls >> 16) & 255; - xferp->data_in[12 + 3] = (d->ncyls >> 8) & 255; - xferp->data_in[12 + 4] = d->ncyls & 255; - xferp->data_in[12 + 5] = d->heads; + xferp->data_in[q + 0] = pagecode; + xferp->data_in[q + 1] = 22; + xferp->data_in[q + 2] = (d->ncyls >> 16) & 255; + xferp->data_in[q + 3] = (d->ncyls >> 8) & 255; + xferp->data_in[q + 4] = d->ncyls & 255; + xferp->data_in[q + 5] = d->heads; - xferp->data_in[12 + 20] = (d->rpms >> 8) & 255; - xferp->data_in[12 + 21] = d->rpms & 255; + xferp->data_in[q + 20] = (d->rpms >> 8) & 255; + xferp->data_in[q + 21] = d->rpms & 255; break; case 5: /* flexible disk page */ - xferp->data_in[12 + 0] = pagecode; - xferp->data_in[12 + 1] = 0x1e; + xferp->data_in[q + 0] = pagecode; + xferp->data_in[q + 1] = 0x1e; /* 2,3 = transfer rate */ - xferp->data_in[12 + 2] = ((5000) >> 8) & 255; - xferp->data_in[12 + 3] = (5000) & 255; + xferp->data_in[q + 2] = ((5000) >> 8) & 255; + xferp->data_in[q + 3] = (5000) & 255; - xferp->data_in[12 + 4] = d->heads; - xferp->data_in[12 + 5] = d->sectors_per_track; + xferp->data_in[q + 4] = d->heads; + xferp->data_in[q + 5] = d->sectors_per_track; /* 6,7 = data bytes per sector */ - xferp->data_in[12 + 6] = (d->logical_block_size >> 8) + xferp->data_in[q + 6] = (d->logical_block_size >> 8) & 255; - xferp->data_in[12 + 7] = d->logical_block_size & 255; + xferp->data_in[q + 7] = d->logical_block_size & 255; - xferp->data_in[12 + 8] = (d->ncyls >> 8) & 255; - xferp->data_in[12 + 9] = d->ncyls & 255; + xferp->data_in[q + 8] = (d->ncyls >> 8) & 255; + xferp->data_in[q + 9] = d->ncyls & 255; - xferp->data_in[12 + 28] = (d->rpms >> 8) & 255; - xferp->data_in[12 + 29] = d->rpms & 255; + xferp->data_in[q + 28] = (d->rpms >> 8) & 255; + xferp->data_in[q + 29] = d->rpms & 255; break; default: fatal("[ MODE_SENSE for page %i is not yet " @@ -879,9 +897,9 @@ * blocks to transfer. (NOTE: If the value is * 0, this means 0, not 65536. :-) */ - ofs = (xferp->cmd[2] << 24) + (xferp->cmd[3] - << 16) + (xferp->cmd[4] << 8) + - xferp->cmd[5]; + ofs = ((uint64_t)xferp->cmd[2] << 24) + + (xferp->cmd[3] << 16) + (xferp->cmd[4] << 8) + + xferp->cmd[5]; retlen = (xferp->cmd[7] << 8) + xferp->cmd[8]; } @@ -957,8 +975,9 @@ * transfer. (NOTE: If the value is 0 this means 0, * not 65536.) */ - ofs = (xferp->cmd[2] << 24) + (xferp->cmd[3] << 16) + - (xferp->cmd[4] << 8) + xferp->cmd[5]; + ofs = ((uint64_t)xferp->cmd[2] << 24) + + (xferp->cmd[3] << 16) + (xferp->cmd[4] << 8) + + xferp->cmd[5]; retlen = (xferp->cmd[7] << 8) + xferp->cmd[8]; } @@ -1006,7 +1025,7 @@ if (xferp->cmd_len != 6) debug(" (weird len=%i)", xferp->cmd_len); - for (i=0; icmd_len; i++) + for (i=0; i<(ssize_t)xferp->cmd_len; i++) debug(" %02x", xferp->cmd[i]); /* TODO: actualy care about cmd[] */ @@ -1215,7 +1234,18 @@ scsi_transfer_allocbuf(&xferp->data_in_len, &xferp->data_in, retlen, 1); - /* TODO */ + xferp->data_in[0] = 0; + xferp->data_in[1] = 10; + xferp->data_in[2] = 0; /* First track. */ + xferp->data_in[3] = 0; /* Last track. */ + + /* Track 0 data: */ + xferp->data_in[4] = 0x00; /* Reserved. */ + xferp->data_in[5] = 0x04; /* ADR + CTRL: + Data, not audio */ + xferp->data_in[6] = 0x00; /* Track nr */ + xferp->data_in[7] = 0x00; /* Reserved */ + /* 8..11 = absolute CDROM address */ diskimage__return_default_status_and_message(xferp); break; @@ -1256,10 +1286,10 @@ } else { int i; fatal("[ unknown MODE_SELECT: cmd ="); - for (i=0; icmd_len; i++) + for (i=0; i<(ssize_t)xferp->cmd_len; i++) fatal(" %02x", xferp->cmd[i]); fatal(", data_out ="); - for (i=0; idata_out_len; i++) + for (i=0; i<(ssize_t)xferp->data_out_len; i++) fatal(" %02x", xferp->data_out[i]); fatal(" ]"); } @@ -1268,10 +1298,9 @@ diskimage__return_default_status_and_message(xferp); break; - case 0x1e: - debug("[ SCSI 0x%02x: TODO ]\n", xferp->cmd[0]); - - /* TODO */ + case SCSICMD_PREVENT_ALLOW_REMOVE: + debug("[ SCSI 0x%02x Prevent/allow medium removal: " + "TODO ]\n", xferp->cmd[0]); diskimage__return_default_status_and_message(xferp); break; @@ -1279,7 +1308,7 @@ case 0xbd: fatal("[ SCSI 0x%02x (len %i), TODO: ", xferp->cmd[0], xferp->cmd_len); - for (i=0; icmd_len; i++) + for (i=0; i<(ssize_t)xferp->cmd_len; i++) fatal(" %02x", xferp->cmd[i]); fatal(" ]\n"); @@ -1470,15 +1499,11 @@ d2->next = d; } - d->type = DISKIMAGE_SCSI; + d->type = DISKIMAGE_IDE; - /* Special cases: some machines usually have FLOPPY/IDE, not SCSI: */ - if (machine->arch == ARCH_X86 || - machine->machine_type == MACHINE_COBALT || - machine->machine_type == MACHINE_EVBMIPS || - machine->machine_type == MACHINE_HPCMIPS || - machine->machine_type == MACHINE_PS2) - d->type = DISKIMAGE_IDE; + if (machine->machine_type == MACHINE_PMAX || + machine->machine_type == MACHINE_ARC) + d->type = DISKIMAGE_SCSI; if (prefix_i + prefix_f + prefix_s > 1) { fprintf(stderr, "Invalid disk image prefix(es). You can" @@ -1505,14 +1530,15 @@ * Is this a tape, CD-ROM or a normal disk? * * An intelligent guess, if no prefixes are used, would be that - * filenames ending with .iso are CD-ROM images. + * filenames ending with .iso or .cdr are CD-ROM images. */ if (prefix_t) { d->is_a_tape = 1; } else { if (prefix_c || ((strlen(d->fname) > 4 && - strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0) + (strcasecmp(d->fname + strlen(d->fname) - 4, ".cdr") == 0 || + strcasecmp(d->fname + strlen(d->fname) - 4, ".iso") == 0)) && !prefix_d) ) { d->is_a_cdrom = 1; @@ -1530,7 +1556,7 @@ */ #if 0 - if (machine->machine_type == MACHINE_DEC) + if (machine->machine_type == MACHINE_PMAX) d->logical_block_size = 512; else d->logical_block_size = 2048; @@ -1670,6 +1696,35 @@ /* + * diskimage_getname(): + * + * Returns 1 if a valid disk image name was returned, 0 otherwise. + */ +int diskimage_getname(struct machine *machine, int id, int type, + char *buf, size_t bufsize) +{ + struct diskimage *d = machine->first_diskimage; + + if (buf == NULL) + return 0; + + while (d != NULL) { + if (d->type == type && d->id == id) { + char *p = strrchr(d->fname, '/'); + if (p == NULL) + p = d->fname; + else + p ++; + snprintf(buf, bufsize, "%s", p); + return 1; + } + d = d->next; + } + return 0; +} + + +/* * diskimage_is_a_cdrom(): * * Returns 1 if a disk image is a CDROM, 0 otherwise. @@ -1715,7 +1770,7 @@ */ void diskimage_dump_info(struct machine *machine) { - int iadd=4; + int iadd = DEBUG_INDENTATION; struct diskimage *d = machine->first_diskimage; while (d != NULL) {