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; }
/* Detach routine */ t_stat mfdc_detach(UNIT *uptr) { t_stat r; int8 i; for(i = 0; i < MFDC_MAX_DRIVES; i++) { if(mfdc_dev.units[i].fileref == uptr->fileref) { break; } } if (i >= MFDC_MAX_DRIVES) return SCPE_ARG; DBG_PRINT(("Detach MFDC%d\n", i)); r = diskClose(&mfdc_info->drive[i].imd); 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 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; }
/* 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; }
t_stat rp_detach (UNIT *uptr) { t_stat reason; reason = detach_unit (uptr); rp_updsta (0, 0); return reason; }
t_stat clk_detach (UNIT *uptr) { t_stat r; r = detach_unit (uptr); if ((uptr->flags & UNIT_ATT) == 0) uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); return r; }
t_stat cdp_detach (UNIT *uptr) { t_stat r; r = cdp_npr (NULL, 0, NULL, NULL); if (r != SCPE_OK) return r; return detach_unit (uptr); }
t_stat dp_detach (UNIT *uptr) { uint32 u = uptr - dp_dev.units; if (!(uptr->flags & UNIT_ATT)) /* attached? */ return SCPE_OK; if (dpd_arm[u]) /* if arm, intr */ SET_INT (v_DPC + u + 1); return detach_unit (uptr); }
t_stat dp_detach(UNIT *uptr) { struct dpio_unit *iou = (struct dpio_unit *)uptr->up7; t_stat stat; sim_cancel(uptr); stat = detach_unit(uptr); iou->oncyl = FALSE; return stat; }
t_stat cdr_detach (UNIT *uptr) { t_stat r; cdr_unit.flags |= UNIT_ATTABLE; /* must be attachable */ r = detach_unit (uptr); /* detach */ if (((cdr_unit.flags & UNIT_ATT) == 0) && /* attached clear? */ ((cdr_unit.flags & UNIT_CONS) != 0)) /* default on? */ cdr_unit.flags &= ~UNIT_ATTABLE; /* clear attachable */ return r; }
static t_stat hdsk_detach(UNIT *uptr) { t_stat result; if (uptr == NULL) return SCPE_IERR; 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; }
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 */ static t_stat vfdhd_detach(UNIT *uptr) { t_stat r; int8 i; for(i = 0; i < VFDHD_MAX_DRIVES; i++) { if(vfdhd_dev.units[i].fileref == uptr->fileref) { break; } } DBG_PRINT(("Detach VFDHD%d\n", i)); r = diskClose(&vfdhd_info->drive[i].imd); 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 mdsad_detach(UNIT *uptr) { t_stat r; int8 i; for(i = 0; i < MDSAD_MAX_DRIVES; i++) { if(mdsad_dev.units[i].fileref == uptr->fileref) { break; } } if (i >= MDSAD_MAX_DRIVES) return SCPE_ARG; DBG_PRINT(("Detach MDSAD%d\n", i)); r = detach_unit(uptr); /* detach unit */ if(r != SCPE_OK) return r; mdsad_dev.units[i].fileref = NULL; 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; }
/* 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; }
t_stat sim_tape_detach (UNIT *uptr) { uint32 f = MT_GET_FMT (uptr); t_stat r; r = detach_unit (uptr); /* detach unit */ if (r != SCPE_OK) return r; switch (f) { /* case on format */ case MTUF_F_TPC: /* TPC */ if (uptr->filebuf) /* free map */ free (uptr->filebuf); uptr->filebuf = NULL; uptr->hwmark = 0; break; default: break; } sim_tape_rewind (uptr); return SCPE_OK; }
t_stat dp_svc (UNIT *uptr) { int32 dcyl = 0; /* assume recalibrate */ int32 ch = dp_dib.chan - 1; /* DMA/DMC chan */ uint32 h = CW1_GETHEAD (dp_cw1); /* head */ int32 st; uint32 i, offs, lnt, ming, tpos; t_stat r; if (!(uptr->flags & UNIT_ATT)) { /* not attached? */ dp_done (1, STA_OFLER); /* offline */ return IORETURN (dp_stopioe, SCPE_UNATT); } switch (uptr->FNC) { /* case on function */ case FNC_SEEK: /* seek, need cyl */ offs = CW1_GETOFFS (dp_cw1); /* get offset */ if (dp_cw1 & CW1_DIR) /* get desired cyl */ dcyl = uptr->CYL - offs; else dcyl = uptr->CYL + offs; if ((offs == 0) || (dcyl < 0) || (dcyl >= (int32) dp_tab[dp_ctype].cyl)) return dp_done (1, STA_SEKER); /* bad seek? */ case FNC_SK0: /* recalibrate */ dp_sta = dp_sta & ~STA_BUSY; /* clear busy */ uptr->FNC = FNC_SEEK | FNC_2ND; /* next state */ st = (abs (dcyl - uptr->CYL)) * dp_stime; /* schedule seek */ if (st == 0) st = dp_stime; uptr->CYL = dcyl; /* put on cylinder */ sim_activate (uptr, st); return SCPE_OK; case FNC_SEEK | FNC_2ND: /* seek, 2nd state */ if (dp_sta & STA_BUSY) /* busy? queue intr */ dp_defint = 1; else SET_INT (INT_DP); /* no, req intr */ return SCPE_OK; case FNC_UNL: /* unload */ detach_unit (uptr); /* detach unit */ return dp_done (0, 0); /* clear busy, no intr */ case FNC_RCA: /* read current addr */ if (h >= dp_tab[dp_ctype].surf) /* invalid head? */ return dp_done (1, STA_ADRER); /* error */ if (r = dp_rdtrk (uptr, dpxb, uptr->CYL, h)) /* get track; error? */ return r; dp_rptr = 0; /* init rec ptr */ if (dpxb[dp_rptr + REC_LNT] == 0) /* unformated? */ return dp_done (1, STA_ADRER); /* error */ tpos = (uint32) (fmod (sim_gtime () / (double) dp_xtime, DP_TRKLEN)); do { /* scan down track */ dp_buf = dpxb[dp_rptr + REC_ADDR]; /* get rec addr */ dp_rptr = dp_rptr + dpxb[dp_rptr + REC_LNT] + REC_OVHD; } while ((dp_rptr < tpos) && (dpxb[dp_rptr + REC_LNT] != 0)); if (dp_dma) { /* DMA/DMC? */ if (Q_DMA (ch)) /* DMA? */ dma_ad[ch] = dma_ad[ch] | DMA_IN; /* force input */ SET_CH_REQ (ch); /* request chan */ } return dp_done (1, STA_RDY); /* clr busy, set rdy */ /* Formating takes place in five states: init - clear track buffer, start at first record address - store address word data - store data word(s) until end of range pause - wait for gap word or stop command gap - validate gap word, advance to next record Note that formating is stopped externally by an OCP command; the track buffer is flushed at that point. If the stop does not occur in the proper state (gap word received), a format error occurs. */ case FNC_FMT: /* format */ for (i = 0; i < DP_TRKLEN; i++) /* clear track */ dpxb[i] = 0; dp_xip = dp_xip | XIP_FMT; /* format in progress */ dp_rptr = 0; /* init record ptr */ dp_gap = 0; /* no gap before first */ dp_bctr = (uint32) (16.0 * dp_tab[dp_ctype].wrds); /* init bit cntr */ uptr->FNC = uptr->FNC | FNC_2ND; /* address state */ break; /* set up next word */ case FNC_FMT | FNC_2ND: /* format, address word */ dp_wptr = 0; /* clear word ptr */ if (dp_bctr < (dp_gap + REC_OVHD_BITS + 16)) /* room for gap, record? */ return dp_wrdone (uptr, STA_FMTER); /* no, format error */ dp_bctr = dp_bctr - dp_gap - REC_OVHD_BITS; /* charge for gap, ovhd */ dpxb[dp_rptr + REC_ADDR] = dp_buf; /* store address */ uptr->FNC = FNC_FMT | FNC_3RD; /* data state */ if (dp_eor) { /* record done? */ dp_eor = 0; /* clear for restart */ if (dp_dma) /* DMA/DMC? intr */ SET_INT (INT_DP); } break; /* set up next word */ case FNC_FMT | FNC_3RD: /* format, data word */ if (dp_sta & STA_RDY) /* timing failure? */ return dp_wrdone (uptr, STA_DTRER); /* write trk, err */ else { /* no, have word */ if (dp_bctr < 16) /* room for it? */ return dp_wrdone (uptr, STA_FMTER); /* no, error */ dp_bctr = dp_bctr - 16; /* charge for word */ dp_csum = dp_csum ^ dp_buf; /* update checksum */ dpxb[dp_rptr + REC_DATA + dp_wptr] = dp_buf;/* store word */ dpxb[dp_rptr + REC_LNT]++; /* incr rec lnt */ dp_wptr++; /* incr word ptr */ } if (dp_eor) { /* record done? */ dp_eor = 0; /* clear for restart */ if (dp_dma) /* DMA/DMC? intr */ SET_INT (INT_DP); dpxb[dp_rptr + REC_DATA + dp_wptr] = dp_csum; /* store checksum */ uptr->FNC = uptr->FNC | FNC_4TH; /* pause state */ sim_activate (uptr, 5 * dp_xtime); /* schedule pause */ return SCPE_OK; /* don't request word */ } break; /* set up next word */ case FNC_FMT | FNC_4TH: /* format, pause */ uptr->FNC = FNC_FMT | FNC_5TH; /* gap state */ break; /* request word */ case FNC_FMT | FNC_5TH: /* format, gap word */ ming = ((16 * dp_wptr) + REC_OVHD_BITS) / 20; /* min 5% gap */ if (dp_buf < ming) /* too small? */ return dp_wrdone (uptr, STA_FMTER); /* yes, format error */ dp_rptr = dp_rptr + dp_wptr + REC_OVHD; /* next record */ uptr->FNC = FNC_FMT | FNC_2ND; /* address state */ if (dp_eor) { /* record done? */ dp_eor = 0; /* clear for restart */ if (dp_dma) SET_INT (INT_DP); /* DMA/DMC? intr */ } dp_gap = dp_buf; /* save gap */ dp_csum = 0; /* clear checksum */ break; /* set up next word */ /* Read and write take place in two states: init - read track into buffer, find record, validate parameters data - (read) fetch data from buffer, stop on end of range - (write) write data into buffer, flush on end of range */ case FNC_RW: /* read/write */ if (h >= dp_tab[dp_ctype].surf) /* invalid head? */ return dp_done (1, STA_ADRER); /* error */ if (r = dp_rdtrk (uptr, dpxb, uptr->CYL, h)) /* get track; error? */ return r; if (!dp_findrec (dp_cw2)) /* find rec; error? */ return dp_done (1, STA_ADRER); /* address error */ if ((dpxb[dp_rptr + REC_LNT] >= (DP_TRKLEN - dp_rptr - REC_OVHD)) || (dpxb[dp_rptr + REC_EXT] >= REC_MAXEXT)) { /* bad lnt or ext? */ dp_done (1, STA_UNSER); /* stop simulation */ return STOP_DPFMT; /* bad format */ } uptr->FNC = uptr->FNC | FNC_2ND; /* next state */ if (dp_cw1 & CW1_RW) { /* write? */ if (uptr->flags & UNIT_WPRT) /* write protect? */ return dp_done (1, STA_WPRER); /* error */ dp_xip = dp_xip | XIP_WRT; /* write in progress */ dp_sta = dp_sta | STA_RDY; /* set ready */ if (dp_dma) /* if DMA/DMC, req chan */ SET_CH_REQ (ch); } else if (Q_DMA (ch)) /* read; DMA? */ dma_ad[ch] = dma_ad[ch] | DMA_IN; /* force input */ sim_activate (uptr, dp_xtime); /* schedule word */ dp_wptr = 0; /* init word pointer */ return SCPE_OK; case FNC_RW | FNC_2ND: /* read/write, word */ if (dp_cw1 & CW1_RW) { /* write? */ if (dp_sta & STA_RDY) /* timing failure? */ return dp_wrdone (uptr, STA_DTRER); /* yes, error */ if (r = dp_wrwd (uptr, dp_buf)) /* wr word, error? */ return r; if (dp_eor) { /* transfer done? */ dpxb[dp_rptr + REC_DATA + dp_wptr] = dp_csum; return dp_wrdone (uptr, 0); /* clear busy, intr req */ } } else { /* read? */ lnt = dpxb[dp_rptr + REC_LNT] + dpxb[dp_rptr + REC_EXT]; dp_buf = dpxb[dp_rptr + REC_DATA + dp_wptr];/* current word */ dp_csum = dp_csum ^ dp_buf; /* xor to csum */ if ((dp_wptr > lnt) || dp_eor) /* transfer done? */ return dp_done (1, (dp_csum? STA_CSMER: 0) | ((dp_wptr >= lnt)? STA_EOR: 0)); if (dp_sta & STA_RDY) /* data buf full? */ return dp_done (1, STA_DTRER); /* no, underrun */ dp_wptr++; /* next word */ } break; default: return SCPE_IERR; } /* end case */ dp_sta = dp_sta | STA_RDY; /* set ready */ if (dp_dma) /* if DMA/DMC, req chan */ SET_CH_REQ (ch); sim_activate (uptr, dp_xtime); /* schedule word */ return SCPE_OK; }
t_stat mtu_svc (UNIT *uptr) { uint32 cmd = uptr->UCMD; uint32 un = uptr - mt_unit; uint32 c; uint32 st; int32 t; t_mtrlnt tbc; t_stat r; if (cmd == MCM_INIT) { /* init state */ if ((t = sim_activate_time (uptr + MT_REW)) != 0) { /* rewinding? */ sim_activate (uptr, t); /* retry later */ return SCPE_OK; } st = chan_get_cmd (mt_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((cmd & 0x80) || /* invalid cmd? */ (mt_op[cmd] == 0)) { uptr->UCMD = MCM_END; /* end state */ sim_activate (uptr, chan_ctl_time); /* resched ctlr */ return SCPE_OK; } else { /* valid cmd */ if ((mt_op[cmd] & O_REV) && /* reverse op */ (mt_unit[un].UST & MTDV_BOT)) { /* at load point? */ chan_uen (mt_dib.dva); /* channel end */ return SCPE_OK; } uptr->UCMD = cmd; /* unit state */ if (!(mt_op[cmd] & O_NMT)) /* motion? */ uptr->UST = 0; /* clear status */ } mt_blim = 0; /* no buffer yet */ sim_activate (uptr, chan_ctl_time); /* continue thread */ return SCPE_OK; /* done */ } if (cmd == MCM_END) { /* end state */ st = chan_end (mt_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if (st == CHS_CCH) { /* command chain? */ uptr->UCMD = MCM_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } else uptr->UCMD = 0; /* ctlr idle */ return SCPE_OK; /* done */ } if ((mt_op[cmd] & O_ATT) && /* op req att and */ ((uptr->flags & UNIT_ATT) == 0)) { /* not attached? */ sim_activate (uptr, mt_ctime); /* retry */ return mt_stopioe? SCPE_UNATT: SCPE_OK; } if ((mt_op[cmd] & O_WRE) && /* write op and */ sim_tape_wrp (uptr)) { /* write protected? */ uptr->UST |= MTDV_WLE; /* set status */ chan_uen (mt_dib.dva); /* unusual end */ return SCPE_OK; } r = SCPE_OK; switch (cmd) { /* case on command */ case MCM_SFWR: /* space forward */ if (r = sim_tape_sprecf (uptr, &tbc)) /* spc rec fwd, err? */ r = mt_map_err (uptr, r); /* map error */ break; case MCM_SBKR: /* space reverse */ if (r = sim_tape_sprecr (uptr, &tbc)) /* spc rec rev, err? */ r = mt_map_err (uptr, r); /* map error */ break; case MCM_SFWF: /* space fwd file */ while ((r = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ; if (r != MTSE_TMK) /* stopped by tmk? */ r = mt_map_err (uptr, r); /* no, map error */ else r = SCPE_OK; break; case MCM_SBKF: /* space rev file */ while ((r = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ; if (r != MTSE_TMK) /* stopped by tmk? */ r = mt_map_err (uptr, r); /* no, map error */ else r = SCPE_OK; break; case MCM_WTM: /* write eof */ if (r = sim_tape_wrtmk (uptr)) /* write tmk, err? */ r = mt_map_err (uptr, r); /* map error */ uptr->UST |= MTDV_EOF; /* set eof */ break; case MCM_RWU: /* rewind unload */ r = detach_unit (uptr); break; case MCM_REW: /* rewind */ case MCM_RWI: /* rewind and int */ if (r = sim_tape_rewind (uptr)) /* rewind */ r = mt_map_err (uptr, r); /* map error */ mt_unit[un + MT_REW].UCMD = uptr->UCMD; /* copy command */ sim_activate (uptr + MT_REW, mt_rwtime); /* sched compl */ break; case MCM_READ: /* read */ if (mt_blim == 0) { /* first read? */ r = sim_tape_rdrecf (uptr, mt_xb, &mt_blim, MT_MAXFR); if (r != MTSE_OK) { /* tape error? */ r = mt_map_err (uptr, r); /* map error */ break; } mt_bptr = 0; /* init rec ptr */ } c = mt_xb[mt_bptr++]; /* get char */ st = chan_WrMemB (mt_dib.dva, c); /* write to memory */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((st != CHS_ZBC) && (mt_bptr != mt_blim)) { /* not done? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } if (((st == CHS_ZBC) ^ (mt_bptr == mt_blim)) && /* length err? */ chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ return SCPE_OK; /* finished */ break; /* normal end */ case MCM_RDBK: /* read reverse */ if (mt_blim == 0) { /* first read? */ r = sim_tape_rdrecr (uptr, mt_xb, &mt_blim, MT_MAXFR); if (r != MTSE_OK) { /* tape error? */ r = mt_map_err (uptr, r); /* map error */ break; } mt_bptr = mt_blim; /* init rec ptr */ } c = mt_xb[--mt_bptr]; /* get char */ st = chan_WrMemBR (mt_dib.dva, c); /* write mem rev */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((st != CHS_ZBC) && (mt_bptr != 0)) { /* not done? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } if (((st == CHS_ZBC) ^ (mt_bptr == 0)) && /* length err? */ chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ return SCPE_OK; /* finished */ break; /* normal end */ case MCM_WRITE: /* write */ st = chan_RdMemB (mt_dib.dva, &c); /* read char */ if (CHS_IFERR (st)) { /* channel error? */ mt_flush_buf (uptr); /* flush buffer */ return mt_chan_err (st); } mt_xb[mt_blim++] = c; /* store in buffer */ if (st != CHS_ZBC) { /* end record? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } r = mt_flush_buf (uptr); /* flush buffer */ break; } if (r != SCPE_OK) /* error? abort */ return CHS_IFERR(r)? SCPE_OK: r; uptr->UCMD = MCM_END; /* end state */ sim_activate (uptr, mt_ctime); /* sched ctlr */ return SCPE_OK; }
t_stat lpt_detach(UNIT * uptr) { lpt_csr = lpt_csr | CSR_ERR; return detach_unit(uptr); }
/* 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; }
t_stat dqc_detach (UNIT* uptr) { dqc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */ return detach_unit (uptr); /* detach unit */ }
t_stat ptp_detach (UNIT *uptr) { ptp_csr = ptp_csr | CSR_ERR; return detach_unit (uptr); }
t_stat pt_detach (UNIT *uptr) { if (!(sim_switches & SIM_SW_REST)) sim_cancel (uptr); /* stop motion */ uptr->STA = 0; return detach_unit (uptr); }
static t_stat sagelp_detach (UNIT *uptr) { u39.portb |= U39B_PAPER; /* no paper */ return detach_unit (uptr); }