/* Set disk format routine */ static t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) { char fmtname[DPB_NAME_LENGTH + 1]; int32 i; if (cptr == NULL) return SCPE_ARG; if (uptr == NULL) return SCPE_IERR; if (sscanf(cptr, "%" QUOTE2(DPB_NAME_LENGTH) "s", fmtname) == 0) return SCPE_ARG; if (((uptr -> flags) & UNIT_ATT) == 0) { printf("Cannot set format for not attached unit %i.\n", find_unit_index(uptr)); return SCPE_ARG; } for (i = 0; dpb[i].capac != 0; i++) { if (strncmp(fmtname, dpb[i].name, strlen(fmtname)) == 0) { uptr -> HDSK_FORMAT_TYPE = i; uptr -> capac = dpb[i].capac; /* Set capacity */ /* Configure physical disk geometry */ uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh); uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh; uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac + uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE - 1) / (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); return SCPE_OK; } }
/* Detach routine */ static t_stat disk3_detach(UNIT *uptr) { DISK3_DRIVE_INFO *pDrive; t_stat r; int8 i; i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } pDrive = &disk3_info->drive[i]; pDrive->ready = 0; if (uptr->flags & UNIT_DISK3_VERBOSE) printf("Detach DISK3%d\n", i); r = detach_unit(uptr); /* detach unit */ if ( r != SCPE_OK) return r; return SCPE_OK; }
/* Detach routine */ t_stat hdc1001_detach(UNIT *uptr) { HDC1001_DRIVE_INFO *pDrive; t_stat r; int8 i; i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } pDrive = &hdc1001_info->drive[i]; pDrive->ready = 0; if (uptr->flags & UNIT_HDC1001_VERBOSE) printf("Detach HDC1001%d\n", i); r = detach_unit(uptr); /* detach unit */ if ( r != SCPE_OK) return r; return SCPE_OK; }
/* Attach routine */ t_stat mfdc_attach(UNIT *uptr, char *cptr) { t_stat r; unsigned int i = 0; r = attach_unit(uptr, cptr); /* attach unit */ if ( r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ if(sim_fsize(uptr->fileref) != 0) { uptr->capac = sim_fsize(uptr->fileref); } else { uptr->capac = MFDC_CAPACITY; } i = find_unit_index(uptr); /* Default for new file is DSK */ uptr->u3 = IMAGE_TYPE_DSK; if(uptr->capac > 0) { r = assignDiskType(uptr); if (r != SCPE_OK) { mfdc_detach(uptr); return r; } } if (uptr->flags & UNIT_MFDC_VERBOSE) printf("MDSK%d, attached to '%s', type=%s, len=%d\n", i, cptr, uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", uptr->capac); if(uptr->u3 == IMAGE_TYPE_IMD) { if(uptr->capac < 318000) { printf("Cannot create IMD files with SIMH.\nCopy an existing file and format it with CP/M.\n"); mfdc_detach(uptr); return SCPE_OPENERR; } if (uptr->flags & UNIT_MFDC_VERBOSE) printf("--------------------------------------------------------\n"); mfdc_info->drive[i].imd = diskOpen((uptr->fileref), (uptr->flags & UNIT_MFDC_VERBOSE)); if (uptr->flags & UNIT_MFDC_VERBOSE) printf("\n"); } else { mfdc_info->drive[i].imd = NULL; } return SCPE_OK; }
static t_stat hdsk_detach(UNIT *uptr) { t_stat result; int32 unitIndex; if (uptr == NULL) return SCPE_IERR; if (is_imd(uptr)) { unitIndex = find_unit_index(uptr); if (unitIndex == -1) return SCPE_IERR; assert((0 <= unitIndex) && (unitIndex < HDSK_NUMBER)); diskClose(&hdsk_imd[unitIndex]); } result = detach_unit(uptr); uptr -> capac = HDSK_CAPACITY; uptr -> HDSK_FORMAT_TYPE = 0; uptr -> HDSK_SECTOR_SIZE = 0; uptr -> HDSK_SECTORS_PER_TRACK = 0; uptr -> HDSK_NUMBER_OF_TRACKS = 0; return result; }
/* Detach routine */ t_stat i8272_detach(UNIT *uptr) { t_stat r; int8 i; i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } DBG_PRINT(("Detach I8272%d\n", i)); r = diskClose(&i8272_info->drive[i].imd); i8272_info->drive[i].ready = 0; if (r != SCPE_OK) return r; r = detach_unit(uptr); /* detach unit */ if (r != SCPE_OK) return r; return SCPE_OK; }
/* Detach routine */ t_stat wd179x_detach(UNIT *uptr) { t_stat r; int8 i; i = find_unit_index(uptr); if (i == -1) { return SCPE_IERR; } DBG_PRINT(("Detach WD179X%d\n", i)); r = diskClose(&wd179x_info->drive[i].imd); wd179x_info->drive[i].ready = 0; if (r != SCPE_OK) return r; r = detach_unit(uptr); /* detach unit */ if (r != SCPE_OK) return r; return SCPE_OK; }
/* Set disk geometry routine */ static t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) { uint32 numberOfTracks, numberOfSectors, sectorSize; int result, n; if (cptr == NULL) return SCPE_ARG; if (uptr == NULL) return SCPE_IERR; if (((uptr -> flags) & UNIT_ATT) == 0) { printf("Cannot set geometry for not attached unit %i.\n", find_unit_index(uptr)); return SCPE_ARG; } result = sscanf(cptr, "%d/%d/%d%n", &numberOfTracks, &numberOfSectors, §orSize, &n); if ((result != 3) || (result == EOF) || (cptr[n] != 0)) { result = sscanf(cptr, "T:%d/N:%d/S:%d%n", &numberOfTracks, &numberOfSectors, §orSize, &n); if ((result != 3) || (result == EOF) || (cptr[n] != 0)) return SCPE_ARG; } uptr -> HDSK_NUMBER_OF_TRACKS = numberOfTracks; uptr -> HDSK_SECTORS_PER_TRACK = numberOfSectors; uptr -> HDSK_SECTOR_SIZE = sectorSize; uptr -> capac = numberOfTracks * numberOfSectors * sectorSize; return SCPE_OK; }
/* Attach routine */ static t_stat disk3_attach(UNIT *uptr, char *cptr) { t_stat r = SCPE_OK; DISK3_DRIVE_INFO *pDrive; int i = 0; i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } pDrive = &disk3_info->drive[i]; pDrive->ready = 1; pDrive->track = 5; pDrive->ntracks = C20MB_NTRACKS; pDrive->nheads = C20MB_NHEADS; pDrive->nsectors = C20MB_NSECTORS; pDrive->sectsize = C20MB_SECTSIZE; r = attach_unit(uptr, cptr); /* attach unit */ if ( r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ if(sim_fsize(uptr->fileref) != 0) { uptr->capac = sim_fsize(uptr->fileref); } else { uptr->capac = (pDrive->ntracks * pDrive->nsectors * pDrive->nheads * pDrive->sectsize); } pDrive->uptr = uptr; /* Default for new file is DSK */ uptr->u3 = IMAGE_TYPE_DSK; if(uptr->capac > 0) { r = assignDiskType(uptr); if (r != SCPE_OK) { disk3_detach(uptr); return r; } } if (uptr->flags & UNIT_DISK3_VERBOSE) printf("DISK3%d, attached to '%s', type=%s, len=%d\n", i, cptr, uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", uptr->capac); if(uptr->u3 == IMAGE_TYPE_IMD) { if(uptr->capac < 318000) { printf("Cannot create IMD files with SIMH.\nCopy an existing file and format it with CP/M.\n"); disk3_detach(uptr); return SCPE_OPENERR; } if (uptr->flags & UNIT_DISK3_VERBOSE) printf("--------------------------------------------------------\n"); disk3_info->drive[i].imd = diskOpenEx((uptr->fileref), (uptr->flags & UNIT_DISK3_VERBOSE), &disk3_dev, VERBOSE_MSG, VERBOSE_MSG); if (uptr->flags & UNIT_DISK3_VERBOSE) printf("\n"); } else { disk3_info->drive[i].imd = NULL; } return SCPE_OK; }
/* Attach routine */ static t_stat hdc1001_attach(UNIT *uptr, char *cptr) { t_stat r = SCPE_OK; HDC1001_DRIVE_INFO *pDrive; char header[4]; unsigned int i = 0; i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } pDrive = &hdc1001_info->drive[i]; pDrive->ready = 1; pDrive->track = 5; pDrive->ntracks = 243; pDrive->nheads = 8; pDrive->nsectors = 11; pDrive->sectsize = 1024; r = attach_unit(uptr, cptr); /* attach unit */ if ( r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ if(sim_fsize(uptr->fileref) != 0) { uptr->capac = sim_fsize(uptr->fileref); } else { uptr->capac = (pDrive->ntracks * pDrive->nsectors * pDrive->nheads * pDrive->sectsize); } pDrive->uptr = uptr; /* Default for new file is DSK */ uptr->u3 = IMAGE_TYPE_DSK; if(uptr->capac > 0) { fgets(header, 4, uptr->fileref); if(!strcmp(header, "IMD")) { uptr->u3 = IMAGE_TYPE_IMD; } else if(!strcmp(header, "CPT")) { printf("CPT images not yet supported\n"); uptr->u3 = IMAGE_TYPE_CPT; hdc1001_detach(uptr); return SCPE_OPENERR; } else { uptr->u3 = IMAGE_TYPE_DSK; } } if (uptr->flags & UNIT_HDC1001_VERBOSE) printf("HDC1001%d, attached to '%s', type=%s, len=%d\n", i, cptr, uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", uptr->capac); if(uptr->u3 == IMAGE_TYPE_IMD) { if(uptr->capac < 318000) { printf("Cannot create IMD files with SIMH.\nCopy an existing file and format it with CP/M.\n"); hdc1001_detach(uptr); return SCPE_OPENERR; } if (uptr->flags & UNIT_HDC1001_VERBOSE) printf("--------------------------------------------------------\n"); hdc1001_info->drive[i].imd = diskOpen((uptr->fileref), (uptr->flags & UNIT_HDC1001_VERBOSE)); if (uptr->flags & UNIT_HDC1001_VERBOSE) printf("\n"); } else { hdc1001_info->drive[i].imd = NULL; } return SCPE_OK; }
/* Attach routine */ t_stat i8272_attach(UNIT *uptr, char *cptr) { char header[4]; t_stat r; int32 i = 0; r = attach_unit(uptr, cptr); /* attach unit */ if ( r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ uptr->capac = sim_fsize(uptr->fileref); i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } DBG_PRINT(("Attach I8272%d\n", i)); i8272_info->drive[i].uptr = uptr; /* Default to drive not ready */ i8272_info->drive[i].ready = 0; if(uptr->capac > 0) { char *rtn = fgets(header, 4, uptr->fileref); if((rtn != NULL) && strncmp(header, "IMD", 3)) { printf("I8272: Only IMD disk images are supported\n"); i8272_info->drive[i].uptr = NULL; return SCPE_OPENERR; } } else { /* create a disk image file in IMD format. */ if (diskCreate(uptr->fileref, "$Id: i8272.c 1999 2008-07-22 04:25:28Z hharte $") != SCPE_OK) { printf("I8272: Failed to create IMD disk.\n"); i8272_info->drive[i].uptr = NULL; return SCPE_OPENERR; } uptr->capac = sim_fsize(uptr->fileref); } uptr->u3 = IMAGE_TYPE_IMD; if (uptr->flags & UNIT_I8272_VERBOSE) { printf("I8272%d: attached to '%s', type=%s, len=%d\n", i, cptr, uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", uptr->capac); } if(uptr->u3 == IMAGE_TYPE_IMD) { if (uptr->flags & UNIT_I8272_VERBOSE) printf("--------------------------------------------------------\n"); i8272_info->drive[i].imd = diskOpen(uptr->fileref, uptr->flags & UNIT_I8272_VERBOSE); if (uptr->flags & UNIT_I8272_VERBOSE) printf("\n"); if (i8272_info->drive[i].imd == NULL) { printf("I8272: IMD disk corrupt.\n"); i8272_info->drive[i].uptr = NULL; return SCPE_OPENERR; } i8272_info->drive[i].ready = 1; } else { i8272_info->drive[i].imd = NULL; } return SCPE_OK; }
/* Attach routine */ static t_stat hdsk_attach(UNIT *uptr, char *cptr) { int32 thisUnitIndex; char unitChar; const t_stat r = attach_unit(uptr, cptr); /* attach unit */ if (r != SCPE_OK) /* error? */ return r; assert(uptr != NULL); thisUnitIndex = find_unit_index(uptr); unitChar = '0' + thisUnitIndex; assert((0 <= thisUnitIndex) && (thisUnitIndex < HDSK_NUMBER)); if (is_imd(uptr)) { if ((sim_fsize(uptr -> fileref) == 0) && (diskCreate(uptr -> fileref, "$Id: SIMH hdsk.c $") != SCPE_OK)) { printf("HDSK%c (IMD): Failed to create IMD disk.\n", unitChar); detach_unit(uptr); return SCPE_OPENERR; } hdsk_imd[thisUnitIndex] = diskOpen(uptr -> fileref, sim_deb && (hdsk_dev.dctrl & VERBOSE_MSG)); if (hdsk_imd[thisUnitIndex] == NULL) return SCPE_IOERR; verifyDiskInfo(*hdsk_imd[thisUnitIndex], '0' + thisUnitIndex); uptr -> HDSK_NUMBER_OF_TRACKS = hdsk_imd[thisUnitIndex] -> ntracks; uptr -> HDSK_SECTORS_PER_TRACK = hdsk_imd[thisUnitIndex] -> track[1][0].nsects; uptr -> HDSK_SECTOR_SIZE = hdsk_imd[thisUnitIndex] -> track[1][0].sectsize; uptr -> capac = ((uptr -> HDSK_NUMBER_OF_TRACKS) * (uptr -> HDSK_SECTORS_PER_TRACK) * (uptr -> HDSK_SECTOR_SIZE)); assignFormat(uptr); if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/ uptr -> HDSK_FORMAT_TYPE = 0; printf("HDSK%c (IMD): WARNING: Unsupported disk capacity, assuming HDSK type " "with capacity %iKB.\n", unitChar, uptr -> capac / 1000); uptr -> flags |= UNIT_HDSK_WLK; printf("HDSK%c (IMD): WARNING: Forcing WRTLCK.\n", unitChar); } return SCPE_OK; } /* Step 1: Determine capacity of this disk */ uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good indication */ if (uptr -> capac == 0) { /* file does not exist or has length 0 */ uptr -> capac = (uptr -> HDSK_NUMBER_OF_TRACKS * uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); if (uptr -> capac == 0) uptr -> capac = HDSK_CAPACITY; } /* post condition: uptr -> capac > 0 */ assert(uptr -> capac); /* Step 2: Determine format based on disk capacity */ assignFormat(uptr); /* Step 3: Set number of sectors per track and sector size */ if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found */ uptr -> HDSK_FORMAT_TYPE = 0; printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n", unitChar, uptr -> capac / 1000); uptr -> flags |= UNIT_HDSK_WLK; printf("HDSK%c: WARNING: Forcing WRTLCK.\n", unitChar); /* check whether capacity corresponds to setting of tracks, sectors per track and sector size */ if (uptr -> capac != (uint32)(uptr -> HDSK_NUMBER_OF_TRACKS * uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE)) { printf("HDSK%c: WARNING: Fixing geometry.\n", unitChar); if (uptr -> HDSK_SECTORS_PER_TRACK == 0) uptr -> HDSK_SECTORS_PER_TRACK = 32; if (uptr -> HDSK_SECTOR_SIZE == 0) uptr -> HDSK_SECTOR_SIZE = 128; } } else { /* Case 2: disk parameter block found */ uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh; uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh); } assert((uptr -> HDSK_SECTORS_PER_TRACK) && (uptr -> HDSK_SECTOR_SIZE) && (uptr -> HDSK_FORMAT_TYPE >= 0)); /* Step 4: Number of tracks is smallest number to accomodate capacity */ uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac + uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE - 1) / (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); assert( ( (t_addr) ((uptr -> HDSK_NUMBER_OF_TRACKS - 1) * uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) < uptr -> capac) && (uptr -> capac <= (t_addr) (uptr -> HDSK_NUMBER_OF_TRACKS * uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) ) ); return SCPE_OK; }
/* Attach routine */ t_stat wd179x_attach(UNIT *uptr, char *cptr) { char header[4]; t_stat r; int32 i = 0; r = attach_unit(uptr, cptr); /* attach unit */ if ( r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ uptr->capac = sim_fsize(uptr->fileref); i = find_unit_index(uptr); if (i == -1) { return (SCPE_IERR); } DBG_PRINT(("Attach WD179X%d\n", i)); wd179x_info->drive[i].uptr = uptr; /* Default to drive not ready */ wd179x_info->drive[i].ready = 0; if(uptr->capac > 0) { char *rtn = fgets(header, 4, uptr->fileref); if ((rtn != NULL) && strncmp(header, "IMD", 3)) { printf("WD179X: Only IMD disk images are supported\n"); wd179x_info->drive[i].uptr = NULL; return SCPE_OPENERR; } } else { /* create a disk image file in IMD format. */ if (diskCreate(uptr->fileref, "$Id: wd179x.c 1999 2008-07-22 04:25:28Z hharte $") != SCPE_OK) { printf("WD179X: Failed to create IMD disk.\n"); wd179x_info->drive[i].uptr = NULL; return SCPE_OPENERR; } uptr->capac = sim_fsize(uptr->fileref); } uptr->u3 = IMAGE_TYPE_IMD; if (uptr->flags & UNIT_WD179X_VERBOSE) printf("WD179X%d: attached to '%s', type=%s, len=%d\n", i, cptr, uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", uptr->capac); if(uptr->u3 == IMAGE_TYPE_IMD) { if (uptr->flags & UNIT_WD179X_VERBOSE) printf("--------------------------------------------------------\n"); wd179x_info->drive[i].imd = diskOpen(uptr->fileref, uptr->flags & UNIT_WD179X_VERBOSE); if (uptr->flags & UNIT_WD179X_VERBOSE) printf("\n"); if (wd179x_info->drive[i].imd == NULL) { printf("WD179X: IMD disk corrupt.\n"); wd179x_info->drive[i].uptr = NULL; return SCPE_OPENERR; } /* Write-protect the unit if IMD think's it's writelocked. */ if(imdIsWriteLocked(wd179x_info->drive[i].imd)) { uptr->flags |= UNIT_WD179X_WLK; } wd179x_info->drive[i].ready = 1; } else { wd179x_info->drive[i].imd = NULL; } wd179x_info->fdc_sec_len = 0; /* 128 byte sectors, fixme */ wd179x_info->sel_drive = 0; return SCPE_OK; }