t_stat dp_attach(UNIT *uptr, CONST char *cptr) { struct dpio_unit *iou = (struct dpio_unit *)uptr->up7; const char *drivetype = ((uptr->flags & UNIT_854) != 0) ? "854" : "853"; t_addr capac = ((uptr->flags & UNIT_854) != 0) ? DP854_SIZE : DP853_SIZE; t_stat r; uptr->capac = capac; r = attach_unit(uptr, cptr); if (r != SCPE_OK) return r; /* * If this is a newly created file, set the drive size appropriately. */ if (sim_fsize_ex(uptr->fileref) == 0) sim_set_fsize(uptr->fileref, capac); if (sim_fsize_ex(uptr->fileref) != capac) { if (ExecutionStarted) { detach_unit(uptr); return sim_messagef(SCPE_OPENERR, "Unable to autosize drive after execution started\n"); } /* * This is not the correct size according the drive type but this is the * first attach. Force the drive to match the size of the disk. */ switch (sim_fsize_ex(uptr->fileref)) { case DP854_SIZE: uptr->capac = DP854_SIZE; uptr->flags |= UNIT_854; break; case DP853_SIZE: uptr->capac = DP853_SIZE; uptr->flags &= ~UNIT_854; break; default: detach_unit(uptr); return sim_messagef(SCPE_OPENERR, "Unsupported disk size\n"); } } /* * Set unit to cylinder 0, head 0, sector 0 and indicate on-cylinder. */ iou->cylinder = 0; iou->head = 0; iou->sector = 0; iou->oncyl = TRUE; return SCPE_OK; }
/* Format an entire track. The new track to be formatted must be after any existing tracks on * the disk. * * This routine should be enhanced to re-format an existing track to the same format (this * does not involve changing the disk image size.) * * Any existing data on the disk image will be destroyed when Track 0, Head 0 is formatted. * At that time, the IMD file is truncated. So for the trackWrite to be used to sucessfully * format a disk image, then format program must format tracks starting with Cyl 0, Head 0, * and proceed sequentially through all tracks/heads on the disk. * * Format programs that are known to work include: * Cromemco CDOS "INIT.COM" * ADC Super-Six (CP/M-80) "FMT8.COM" * 86-DOS "INIT.COM" * */ t_stat trackWrite(DISK_INFO *myDisk, uint32 Cyl, uint32 Head, uint32 numSectors, uint32 sectorLen, uint8 *sectorMap, uint8 mode, uint8 fillbyte, uint32 *flags) { FILE *fileref; IMD_HEADER track_header; uint8 *sectorData; unsigned long i; unsigned long dataLen; *flags = 0; /* Check parameters */ if(myDisk == NULL) { *flags |= IMD_DISK_IO_ERROR_GENERAL; return(SCPE_IOERR); } if(myDisk->flags & FD_FLAG_WRITELOCK) { sim_printf("Disk write-protected, cannot format tracks.\n"); *flags |= IMD_DISK_IO_ERROR_WPROT; return(SCPE_IOERR); } fileref = myDisk->file; sim_debug(myDisk->debugmask, myDisk->device, "Formatting C:%d/H:%d/N:%d, len=%d, Fill=0x%02x\n", Cyl, Head, numSectors, sectorLen, fillbyte); /* Truncate the IMD file when formatting Cyl 0, Head 0 */ if((Cyl == 0) && (Head == 0)) { /* Skip over IMD comment field. */ commentParse(myDisk, NULL, 0); /* Truncate the IMD file after the comment field. */ if (sim_set_fsize(fileref, (t_addr)ftell (fileref)) == -1) { sim_printf("Disk truncation failed.\n"); *flags |= IMD_DISK_IO_ERROR_GENERAL; return(SCPE_IOERR); } /* Flush and re-parse the IMD file. */ fflush(fileref); diskParse(myDisk, 0); } /* Check to make sure the Cyl / Head is not already formatted. */ if(sectSeek(myDisk, Cyl, Head) == 0) { sim_printf("SIM_IMD: ERROR: Not Formatting C:%d/H:%d, track already exists.\n", Cyl, Head); *flags |= IMD_DISK_IO_ERROR_GENERAL; return(SCPE_IOERR); } track_header.mode = mode; track_header.cyl = Cyl; track_header.head = Head; track_header.nsects = numSectors; track_header.sectsize = sectorLen; /* Forward to end of the file, write track header and sector map. */ sim_fseek(myDisk->file, 0, SEEK_END); sim_fwrite(&track_header, 1, sizeof(IMD_HEADER), fileref); sim_fwrite(sectorMap, 1, numSectors, fileref); /* Compute data length, and fill a sector buffer with the * sector record type as the first byte, and fill the sector * data with the fillbyte. */ dataLen = sectorLen + 1; sectorData = (uint8 *)malloc(dataLen); memset(sectorData, fillbyte, dataLen); sectorData[0] = SECT_RECORD_NORM; /* For each sector on the track, write the record type and sector data. */ for(i=0;i<numSectors;i++) { sim_fwrite(sectorData, 1, dataLen, fileref); } /* Flush the file, and free the sector buffer. */ fflush(fileref); free(sectorData); /* Now that the disk track/sector layout has been modified, re-parse the disk image. */ diskParse(myDisk, 0); return(SCPE_OK); }
/* * Create an ImageDisk (IMD) file. This function just creates the comment header, and allows * the user to enter a comment. After the IMD is created, it must be formatted with a format * program on the simulated operating system, ie CP/M, CDOS, 86-DOS. * * If the IMD file already exists, the user will be given the option of overwriting it. */ t_stat diskCreate(FILE *fileref, const char *ctlr_comment) { DISK_INFO *myDisk = NULL; char *comment; char *curptr; char *result; uint8 answer; int32 len, remaining; if(fileref == NULL) { return (SCPE_OPENERR); } if(sim_fsize(fileref) != 0) { sim_printf("SIM_IMD: Disk image already has data, do you want to overwrite it? "); answer = getchar(); if((answer != 'y') && (answer != 'Y')) { return (SCPE_OPENERR); } } if((curptr = comment = (char *)calloc(1, MAX_COMMENT_LEN)) == 0) { sim_printf("Memory allocation failure.\n"); return (SCPE_MEM); } sim_printf("SIM_IMD: Enter a comment for this disk.\n" "SIM_IMD: Terminate with a '.' on an otherwise blank line.\n"); remaining = MAX_COMMENT_LEN; do { sim_printf("IMD> "); result = fgets(curptr, remaining - 3, stdin); if ((result == NULL) || (strcmp(curptr, ".\n") == 0)) { remaining = 0; } else { len = strlen(curptr) - 1; if (curptr[len] != '\n') len++; remaining -= len; curptr += len; *curptr++ = 0x0d; *curptr++ = 0x0a; } } while (remaining > 4); *curptr = 0x00; /* rewind to the beginning of the file. */ rewind(fileref); /* Erase the contents of the IMD file in case we are overwriting an existing image. */ if (sim_set_fsize(fileref, (t_addr)ftell (fileref)) == -1) { sim_printf("SIM_IMD: Error overwriting disk image.\n"); return(SCPE_OPENERR); } fprintf(fileref, "IMD SIMH %s %s\n", __DATE__, __TIME__); fputs(comment, fileref); free(comment); fprintf(fileref, "\n\n$Id: sim_imd.c 1999 2008-07-22 04:25:28Z hharte $\n"); fprintf(fileref, "%s\n", ctlr_comment); fputc(0x1A, fileref); /* EOF marker for IMD comment. */ fflush(fileref); if((myDisk = diskOpen(fileref, 0)) == NULL) { sim_printf("SIM_IMD: Error opening disk for format.\n"); return(SCPE_OPENERR); } if(diskFormat(myDisk) != SCPE_OK) { sim_printf("SIM_IMD: error formatting disk.\n"); } return diskClose(&myDisk); }