Example #1
0
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;
}
Example #2
0
File: mfdc.c Project: ProtoSD/simh
/* 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;
}
Example #3
0
/* 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;
}
Example #4
0
/* 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;
}
Example #5
0
t_stat rp_detach (UNIT *uptr)
{
t_stat reason;

reason = detach_unit (uptr);
rp_updsta (0, 0);
return reason;
}
Example #6
0
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;
}
Example #7
0
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);
}
Example #8
0
File: id_dp.c Project: B-Rich/simh
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);
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
0
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;
}
Example #13
0
/* 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;
}
Example #14
0
/* 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;
}
Example #15
0
/* 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;
}
Example #16
0
/* 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;
}
Example #17
0
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;
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
0
t_stat
lpt_detach(UNIT * uptr)
{
	lpt_csr = lpt_csr | CSR_ERR;
	return detach_unit(uptr);
}
Example #21
0
/* 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;
}
Example #22
0
t_stat dqc_detach (UNIT* uptr)
{
dqc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL);        /* unload heads */
return detach_unit (uptr);                              /* detach unit */
}
Example #23
0
t_stat ptp_detach (UNIT *uptr)
{
ptp_csr = ptp_csr | CSR_ERR;
return detach_unit (uptr);
}
Example #24
0
t_stat pt_detach (UNIT *uptr)
{
if (!(sim_switches & SIM_SW_REST)) sim_cancel (uptr);   /* stop motion */
uptr->STA = 0;
return detach_unit (uptr);
}
Example #25
0
static t_stat sagelp_detach (UNIT *uptr)
{
    u39.portb |= U39B_PAPER;    /* no paper */
    return detach_unit (uptr);
}