Пример #1
0
uint32 clkio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data)
{
IOSIGNAL signal;
IOCYCLE  working_set = IOADDSIR (signal_set);           /* add ioSIR if needed */

while (working_set) {
    signal = IONEXT (working_set);                      /* isolate next signal */

    switch (signal) {                                   /* dispatch I/O signal */

        case ioCLF:                                     /* clear flag flip-flop */
            clk.flag = clk.flagbuf = CLEAR;
            break;


        case ioSTF:                                     /* set flag flip-flop */
        case ioENF:                                     /* enable flag */
            clk.flag = clk.flagbuf = SET;
            break;


        case ioSFC:                                     /* skip if flag is clear */
            setstdSKF (clk);
            break;


        case ioSFS:                                     /* skip if flag is set */
            setstdSKF (clk);
            break;


        case ioIOI:                                     /* I/O data input */
            stat_data = IORETURN (SCPE_OK, clk_error);  /* merge in return status */
            break;


        case ioIOO:                                     /* I/O data output */
            clk_select = IODATA (stat_data) & 07;       /* save select */
            sim_cancel (&clk_unit);                     /* stop the clock */
            clk.control = CLEAR;                        /* clear control */
            working_set = working_set | ioSIR;          /* set interrupt request (IOO normally doesn't) */
            break;


        case ioPOPIO:                                   /* power-on preset to I/O */
            clk.flag = clk.flagbuf = SET;               /* set flag and flag buffer */
            break;


        case ioCRS:                                     /* control reset */
        case ioCLC:                                     /* clear control flip-flop */
            clk.control = CLEAR;
            sim_cancel (&clk_unit);                     /* deactivate unit */
            break;


        case ioSTC:                                             /* set control flip-flop */
            clk.control = SET;
            if (clk_unit.flags & UNIT_DIAG)                     /* diag mode? */
                clk_unit.flags = clk_unit.flags & ~UNIT_IDLE;   /* not calibrated */
            else
                clk_unit.flags = clk_unit.flags | UNIT_IDLE;    /* is calibrated */

            if (!sim_is_active (&clk_unit)) {                   /* clock running? */
                clk_tick = clk_delay (0);                       /* get tick count */

                if ((clk_unit.flags & UNIT_DIAG) == 0)          /* calibrated? */
                    if (clk_select == 2)                        /* 10 msec. interval? */
                        clk_tick = sync_poll (INITIAL);         /* sync poll */
                    else
                        sim_rtcn_init (clk_tick, TMR_CLK);      /* initialize timer */

                sim_activate (&clk_unit, clk_tick);             /* start clock */
                clk_ctr = clk_delay (1);                        /* set repeat ctr */
                }
            clk_error = 0;                                      /* clear error */
            break;


        case ioSIR:                                     /* set interrupt request */
            setstdPRL (clk);                            /* set standard PRL signal */
            setstdIRQ (clk);                            /* set standard IRQ signal */
            setstdSRQ (clk);                            /* set standard SRQ signal */
            break;


        case ioIAK:                                     /* interrupt acknowledge */
            clk.flagbuf = CLEAR;
            break;


        default:                                        /* all other signals */
            break;                                      /*   are ignored */
        }

    working_set = working_set & ~signal;                /* remove current signal from set */
    }

return stat_data;
}
Пример #2
0
t_stat ptr_reset (DEVICE *dptr)
{
IOPRESET (&ptr_dib);                                    /* PRESET device (does not use PON) */
sim_cancel (&ptr_unit);                                 /* deactivate unit */
return SCPE_OK;
}
Пример #3
0
int32 dpio (int32 inst, int32 fnc, int32 dat, int32 dev)
{
int32 ch = dp_dib.chan - 1;                             /* DMA/DMC chan */
int32 u;
UNIT *uptr;

switch (inst) {                                         /* case on opcode */

    case ioOCP:                                         /* OCP */
        switch (fnc) {                                  /* case on function */

        case FNC_SK0: case FNC_SEEK: case FNC_RCA:      /* data transfer */
        case FNC_UNL: case FNC_FMT: case FNC_RW:
            dp_go (fnc);                                /* if !busy, start */
            break;

        case FNC_STOP:                                  /* stop transfer */
            if (dp_xip) {                               /* transfer in prog? */
                uptr = dp_dev.units + (dp_xip & XIP_UMSK);      /* get unit */
                sim_cancel (uptr);                      /* stop operation */
                if (dp_xip & (XIP_WRT|XIP_FMT))         /* write or format? */
                    dp_wrdone (uptr,                    /* write track */
                        ((dp_xip & XIP_FMT) &&          /* check fmt state */
                        (uptr->FNC != (FNC_FMT|FNC_2ND)))?
                        STA_DTRER: 0);
                else dp_done (1, dp_csum? STA_CSMER: 0);/* no, just clr busy */
                dp_xip = 0;                             /* clear flag */
                }
            dp_otas = OTA_NOP;                          /* clear state */
            dp_sta = dp_sta & ~STA_BUSY;                /* clear busy */
            break;      

        case FNC_RDS:                                   /* read status */
            if (dp_sta & STA_BUSY)                      /* ignore if busy */
                return dat;
            dp_sta = (dp_sta | STA_RDY) & ~(STA_MBZ | STA_ANYER);
            if (dp_sta & STA_ALLERR) dp_sta = dp_sta | STA_ANYER;
            dp_buf = dp_sta;
            if (dp_dma && Q_DMA (ch))                   /* DMA? set chan req */
                SET_CH_REQ (ch);
            break;

        case FNC_DMA:                                   /* set DMA/DMC */
            dp_dma = 1;
            break;

        case FNC_IOBUS:                                 /* set IO bus */
            dp_dma = 0;
            break;

        case FNC_AKI:                                   /* ack intr */
            CLR_INT (INT_DP);
            break;

        default:                                        /* undefined */
            return IOBADFNC (dat);
            }
        break;

    case ioINA:                                         /* INA */
        if (fnc)                                        /* fnc 0 only */
            return IOBADFNC (dat);
        if (dp_sta & STA_RDY) {                         /* ready? */
            dp_sta = dp_sta & ~STA_RDY;                 /* clear ready */
            return IOSKIP (dat | dp_buf);               /* ret buf, skip */
            }
        break;

    case ioOTA:                                         /* OTA */
        if (fnc)                                        /* fnc 0 only */
            return IOBADFNC (dat);
        if (dp_sta & STA_RDY) {                         /* ready? */
            dp_sta = dp_sta & ~STA_RDY;                 /* clear ready */
            dp_buf = dat;                               /* store buf */
            if (dp_otas == OTA_CW1)                     /* expecting CW1? */
                dp_go1 (dat);
            else if (dp_otas == OTA_CW2)                /* expecting CW2? */
                dp_go2 (dat);
            return IOSKIP (dat);
            }
        break;

    case ioSKS:                                         /* SKS */
        u = 7;                                          /* assume unit 7 */
        switch (fnc) {

        case 000:                                       /* ready */
            if (dp_sta & STA_RDY)
                return IOSKIP (dat);
            break;

        case 001:                                       /* !interrupting */
            if (!TST_INTREQ (INT_DP))
                return IOSKIP (dat);
            break;

        case 002:                                       /* operational */
            if (!(dp_sta & (STA_BUSY | STA_ALLERR)))
                return IOSKIP (dat);
            break;

        case 003:                                       /* !error */
            if (!(dp_sta & STA_ALLERR))
                return IOSKIP (dat);
            break;

        case 004:                                       /* !busy */
            if (!(dp_sta & STA_BUSY))
                return IOSKIP (dat);
            break;

        case 011: case 012: case 013:                   /* !not seeking 0-6 */
        case 014: case 015: case 016: case 017:
            u = fnc - 011;
        case 007:                                       /* !not seeking 7 */
            if (!sim_is_active (&dp_unit[u]) ||         /* quiescent? */
                (dp_unit[u].FNC != (FNC_SEEK | FNC_2ND)))
                return IOSKIP (dat);                    /* seeking sets late */
            break;
            }
        break;

    case ioEND:                                         /* end of range */
        dp_eor = 1;                                     /* transfer done */
        break;
        }

return dat;
}
Пример #4
0
t_stat fl_wr_txdb (int32 data)
{
int32 sel = TXDB_GETSEL (data);                         /* get selection */

if (sel == TXDB_FCMD) {                                 /* floppy command? */
    fl_fnc = FL_GETFNC (data);                          /* get function */
    if (fl_state != FL_IDLE)                            /* cmd in prog? */
        switch (fl_fnc) {

        case FL_FNCCA:                                  /* cancel? */
            sim_cancel (&fl_unit);                      /* stop op */
            fl_state = FL_DONE;
            break;

        default:                                        /* all others */
            fl_protocol_error ();
            return SCPE_OK;
            }

        else switch (fl_fnc) {                          /* idle, case */

        case FL_FNCRS:                                  /* read status */
            fl_state = FL_READSTA;
            break;

        case FL_FNCCA:                                  /* cancel, nop */
            fl_state = FL_DONE;
            break;

        case FL_FNCRD: case FL_FNCWR:                   /* data xfer */
        case FL_FNCWD:
            fl_esr = 0;                                 /* clear errors */
            fl_ecode = 0;
            fl_bptr = 0;                                /* init buffer */
            fl_state = FL_RWDS;                         /* sector next */
            break;

        default:                                        /* all others */
            fl_protocol_error ();
            return SCPE_OK;
            }

    sim_activate (&fl_unit, fl_cwait);                  /* sched command */
    }                                                   /* end command */
else if (sel == TXDB_FDAT) {                            /* floppy data? */
    switch (fl_state) {                                 /* data */

        case FL_RWDS:                                   /* expecting sector */
            fl_sector = data & FL_M_SECTOR;
            fl_state = FL_RWDT;
            break;

        case FL_RWDT:                                   /* expecting track */
            fl_track = data & FL_M_TRACK;
            if (fl_fnc == FL_FNCRD)
                fl_state = FL_READ;
            else fl_state = FL_FILL;
            break;

        case FL_FILL:                                   /* expecting wr data */
            fl_buf[fl_bptr++] = data & BMASK;
            if (fl_bptr >= FL_NUMBY)
                fl_state = FL_WRITE;
            break;

        default:
            fl_protocol_error ();
            return SCPE_OK;
            }

    sim_activate (&fl_unit, fl_xwait);                  /* schedule xfer */
    }                                                   /* end else data */
else {
    sim_activate (&tto_unit, tto_unit.wait);            /* set up timeout */
    if (sel == TXDB_COMM) {                             /* read comm region? */
        data = data & COMM_MASK;                        /* byte to select */
        tti_buf = comm_region[data] | COMM_DATA;
        tti_csr = tti_csr | CSR_DONE;                   /* set input flag */
        if (tti_csr & CSR_IE)
            tti_int = 1;
        }
    else if (sel == TXDB_MISC) {                        /* misc function? */
        switch (data & MISC_MASK) {                     /* case on function */
        case MISC_CLWS:
            comm_region[COMM_WRMS] = 0;
        case MISC_CLCS:
            comm_region[COMM_CLDS] = 0;
            break;
        case MISC_SWDN:
            ABORT (STOP_SWDN);
            break;
        case MISC_BOOT:
            ABORT (STOP_BOOT);
            break;
            }
        }
    }
return SCPE_OK;
}
Пример #5
0
int32 rk (int32 IR, int32 AC)
{
int32 i;
UNIT *uptr;

switch (IR & 07) {                                      /* decode IR<9:11> */

    case 0:                                             /* unused */
        return (stop_inst << IOT_V_REASON) + AC;

    case 1:                                             /* DSKP */
        return (rk_sta & (RKS_DONE + RKS_ERR))?         /* skip on done, err */
            IOT_SKP + AC: AC;

    case 2:                                             /* DCLR */
        rk_sta = 0;                                     /* clear status */
        switch (AC & 03) {                              /* decode AC<10:11> */

        case RKX_CLS:                                   /* clear status */
            if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY;
        case RKX_CLSA:                                  /* clear status alt */
            break;

        case RKX_CLC:                                   /* clear control */
            rk_cmd = rk_busy = 0;                       /* clear registers */
            rk_ma = rk_da = 0;
            for (i = 0; i < RK_NUMDR; i++)
                sim_cancel (&rk_unit[i]);
            break;

        case RKX_CLD:                                   /* reset drive */
            if (rk_busy != 0)
                rk_sta = rk_sta | RKS_BUSY;
            else rk_go (RKC_SEEK, 0);                   /* seek to 0 */
            break;
            }                                           /* end switch AC */
        break;

    case 3:                                             /* DLAG */
        if (rk_busy != 0)
            rk_sta = rk_sta | RKS_BUSY;
        else {
            rk_da = AC;                                 /* load disk addr */
            rk_go (GET_FUNC (rk_cmd), GET_CYL (rk_cmd, rk_da));
            }
        break;

    case 4:                                             /* DLCA */
        if (rk_busy != 0)
            rk_sta = rk_sta | RKS_BUSY;
        else rk_ma = AC;                                /* load curr addr */
        break;

    case 5:                                             /* DRST */
        uptr = rk_dev.units + GET_DRIVE (rk_cmd);       /* selected unit */
        rk_sta = rk_sta & ~(RKS_HMOV + RKS_NRDY);       /* clear dynamic */
        if ((uptr->flags & UNIT_ATT) == 0)
            rk_sta = rk_sta | RKS_NRDY;
        if (sim_is_active (uptr))
            rk_sta = rk_sta | RKS_HMOV;
        return rk_sta;

    case 6:                                             /* DLDC */
        if (rk_busy != 0)
            rk_sta = rk_sta | RKS_BUSY;
        else {
            rk_cmd = AC;                                /* load command */
            rk_sta = 0;                                 /* clear status */
            }
        break;

    case 7:                                             /* DMAN */
        break;
        }                                               /* end case pulse */

RK_INT_UPDATE;                                          /* update int req */
return 0;                                               /* clear AC */
}
Пример #6
0
t_stat rtc_reset (DEVICE *dptr)
{
dev_done = dev_done & ~INT_RTC;                         /* clear ready */
sim_cancel (&rtc_unit);                                 /* stop clock */
return SCPE_OK;
}
Пример #7
0
t_stat qty_detach( UNIT * unitp )
{
    sim_cancel( unitp ) ;
    return ( tmxr_detach(&qty_desc,unitp) ) ;
}   /*  end of 'qty_detach'  */
Пример #8
0
uint32 dqcio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data)
{
int32 fnc, drv;
IOSIGNAL signal;
IOCYCLE  working_set = IOADDSIR (signal_set);           /* add ioSIR if needed */

while (working_set) {
    signal = IONEXT (working_set);                      /* isolate next signal */

    switch (signal) {                                   /* dispatch I/O signal */

        case ioCLF:                                     /* clear flag flip-flop */
            dqc.flag = dqc.flagbuf = CLEAR;
            break;


        case ioSTF:                                     /* set flag flip-flop */
        case ioENF:                                     /* enable flag */
            dqc.flag = dqc.flagbuf = SET;
            break;


        case ioSFC:                                     /* skip if flag is clear */
            setstdSKF (dqc);
            break;


        case ioSFS:                                     /* skip if flag is set */
            setstdSKF (dqc);
            break;


        case ioIOI:                                     /* I/O data input */
            stat_data = IORETURN (SCPE_OK, 0);          /* no data */
            break;


        case ioIOO:                                     /* I/O data output */
            dqc_obuf = IODATA (stat_data);              /* clear supplied status */
            break;


        case ioPOPIO:                                   /* power-on preset to I/O */
            dqc.flag = dqc.flagbuf = SET;               /* set flag and flag buffer */
            dqc_obuf = 0;                               /* clear output buffer */
            break;


        case ioCRS:                                     /* control reset */
        case ioCLC:                                     /* clear control flip-flop */
            dqc.command = CLEAR;                        /* clear command */
            dqc.control = CLEAR;                        /* clear control */

            if (dqc_busy)
                sim_cancel (&dqc_unit[dqc_busy - 1]);

            sim_cancel (&dqd_unit);                     /* cancel dch */
            dqd_xfer = 0;                               /* clr dch xfer */
            dqc_busy = 0;                               /* clr busy */
            break;


        case ioSTC:                                     /* set control flip-flop */
            dqc.control = SET;                          /* set ctl */

            if (!dqc.command) {                         /* cmd clr? */
                dqc.command = SET;                      /* set cmd */
                drv = CW_GETDRV (dqc_obuf);             /* get fnc, drv */
                fnc = CW_GETFNC (dqc_obuf);             /* from cmd word */

                switch (fnc) {                          /* case on fnc */
                    case FNC_SEEK: case FNC_RCL:        /* seek, recal */
                    case FNC_CHK:                       /* check */
                        dqc_sta[drv] = 0;               /* clear status */
                    case FNC_STA: case FNC_LA:          /* rd sta, load addr */
                        dq_god (fnc, drv, dqc_dtime);   /* sched dch xfer */
                        break;
                    case FNC_RD: case FNC_WD:           /* read, write */
                    case FNC_RA: case FNC_WA:           /* rd addr, wr addr */
                    case FNC_AS:                        /* address skip */
                        dq_goc (fnc, drv, dqc_ctime);   /* sched drive */
                        break;
                    }                                   /* end case */
                }                                       /* end if !CMD */
            break;


        case ioSIR:                                     /* set interrupt request */
            setstdPRL (dqc);                            /* set standard PRL signal */
            setstdIRQ (dqc);                            /* set standard IRQ signal */
            setstdSRQ (dqc);                            /* set standard SRQ signal */
            break;


        case ioIAK:                                     /* interrupt acknowledge */
            dqc.flagbuf = CLEAR;
            break;


        default:                                        /* all other signals */
            break;                                      /*   are ignored */
        }

    working_set = working_set & ~signal;                /* remove current signal from set */
    }
return stat_data;
}
Пример #9
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);
}
Пример #10
0
t_stat i8251_write(I8251* chip,int port,uint32 value)
{
    int bits;

    if (port==0) { /* data port */
        chip->obuf = value & chip->bitmask;
        TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf);
        if (chip->init==3) { /* is fully initialized */
            if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) {
                sim_printf("i8251: sync mode not implemented\n");
                return STOP_IMPL;
            }
            if (chip->cmd & I8251_CMD_TXEN) {
                /* transmit data */
                chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY);
                sim_activate(chip->out,chip->out->wait);
            }
        }
        return SCPE_OK;
    } else { /* control port */
        switch (chip->init) {
        case 0: /* expect mode word */
            chip->mode = value; 
            TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value);
            chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3;
            bits = (chip->mode & I8251_AMODE_BITS) >> 2;
            chip->bitmask = i8251_bitmask[bits];
            break;
        case 1: /* expect sync1 */
            chip->sync1 = value;
            TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value);
            chip->init = 2;
            break;
        case 2: /* expect sync2 */
            chip->sync2 = value;
            TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value);
            chip->init = 3;
            break;
        case 3: /* expect cmd word */
            chip->cmd = value;
            TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value);
            if (value & I8251_CMD_EH) {
                sim_printf("i8251: hunt mode not implemented\n");
                return STOP_IMPL;
            }
            if (value & I8251_CMD_IR)
                chip->init = 0;
            if (value & I8251_CMD_ER)
                chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE);
            if (value & I8251_CMD_SBRK)
                sim_printf("i8251: BREAK sent\n");
            if (value & I8251_CMD_RXE) {
                sim_activate(chip->in,chip->in->wait);
            } else {
                if (!chip->oob) sim_cancel(chip->in);
            }
            if (value & I8251_CMD_TXEN) {
                if (!(chip->status & I8251_ST_TXEMPTY))
                    sim_activate(chip->out,chip->out->wait);
                else {
                    chip->status |= I8251_ST_TXRDY;
                    if (chip->txint) chip->txint(chip);
                }
            } else {
                chip->status &= ~I8251_ST_TXRDY;
                sim_cancel(chip->out);
            }
            }
            return SCPE_OK;
    }
}
Пример #11
0
t_stat lpt (uint32 fnc, uint32 inst, uint32 *dat)
{
int32 i, t, new_ch;
char asc;

switch (fnc) {                                          /* case function */

    case IO_CONN:                                       /* connect */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != lpt_dib.chan)                     /* wrong chan? */
            return SCPE_IERR;
        for (i = 0; i < LPT_WIDTH; i++)                 /* clr buffer */
            lpt_buf[i] = 0;
        lpt_bptr = 0;                                   /* clr buf ptr */
        lpt_err = 0;                                    /* err = 0 */
        xfr_req = xfr_req & ~XFR_LPT;                   /* clr xfr flag */
        lpt_sta = lpt_sta | SET_XFR;                    /* need xfr */
        sim_activate (&lpt_unit, lpt_ctime);            /* start timer */
        break;

    case IO_EOM1:                                       /* EOM mode 1 */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != lpt_dib.chan)                     /* wrong chan? */
            CRETIOP;
        if (inst & 0400) {                              /* space? */
            lpt_spc = inst;                             /* save instr */
            lpt_sta = lpt_sta | SET_SPC;                /* need space */
            sim_cancel (&lpt_unit);                     /* cancel timer */
            sim_activate (&lpt_unit, lpt_stime);        /* start timer */
            }
        break;

    case IO_DISC:                                       /* disconnect */
        lpt_end_op (0);                                 /* normal term */
        return lpt_bufout (&lpt_unit);                  /* dump output */

    case IO_WREOR:                                      /* write eor */
        lpt_sta = (lpt_sta | SET_EOR) & ~SET_XFR;       /* need eor */
        sim_activate (&lpt_unit, lpt_ptime);            /* start timer */
        break;

    case IO_SKS:                                        /* SKS */
        new_ch = I_GETSKCH (inst);                      /* sks chan */
        if (new_ch != lpt_dib.chan)                     /* wrong chan? */
            return SCPE_IERR;
        t = I_GETSKCND (inst);                          /* sks cond */
        if (((t == 020) && (!CHP (7, lpt_cct[lpt_ccp]))) || /* 14062: !ch 7 */
            ((t == 010) && (lpt_unit.flags & UNIT_ATT)) ||  /* 12062: !online */
            ((t == 004) && !lpt_err))                   /* 11062: !err */
            *dat = 1;
        break;

    case IO_WRITE:                                      /* write */
        asc = sds_to_ascii(*dat);                       /* convert data */
        xfr_req = xfr_req & ~XFR_LPT;                   /* clr xfr flag */
        if (lpt_bptr < LPT_WIDTH)                       /* store data */
            lpt_buf[lpt_bptr++] = asc;
        lpt_sta = lpt_sta | SET_XFR;                    /* need xfr */
        sim_activate (&lpt_unit, lpt_ctime);            /* start ch timer */
        break;

    default:
        CRETINS;
        }

return SCPE_OK;
}
Пример #12
0
t_stat mt (uint32 fnc, uint32 inst, uint32 *dat)
{
int32 u = inst & MT_UNIT;                               /* get unit */
UNIT *uptr = mt_dev.units + u;                          /* get unit ptr */
int32 t, new_ch;
uint8 chr;
t_stat r;

switch (fnc) {                                          /* case function */

    case IO_CONN:                                       /* connect */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            return SCPE_IERR;
        if (mt_gap) {                                   /* in gap? */
            mt_gap = 0;                                 /* clr gap flg */
            sim_cancel (uptr);                          /* cancel timer */
            }
        else if (sim_is_active (uptr))                  /* busy? */
            CRETIOP;
        uptr->eotf = 0;                                 /* clr eot flag */      
        mt_eof = 0;                                     /* clr eof flag */
        mt_skip = 0;                                    /* clr skp flag */
        mt_bptr = mt_blnt = 0;                          /* init buffer */
        if ((inst & DEV_MTS)? (CHC_GETCPW (inst) < 2):  /* scn & cpw<3? */
            (inst & CHC_REV))                           /* rw & rev? */
            return STOP_INVIOP;
        mt_inst = inst;                                 /* save inst */
        if ((inst & DEV_MTS) && !(inst & DEV_OUT))      /* scanning? */
            chan_set_flag (mt_dib.chan, CHF_SCAN);      /* set chan flg */
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        sim_activate (uptr, mt_gtime);                  /* start timer */
        break;

    case IO_EOM1:                                       /* EOM mode 1 */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            CRETIOP;
        t = inst & 07670;                               /* get command */
        if ((t == 04010) && !sim_is_active (uptr)) {    /* rewind? */
            sim_tape_rewind (uptr);                     /* rewind unit */
            uptr->eotf = 0;                             /* clr eot */
            uptr->botf = 1;                             /* set bot */
            }
        else if ((t == 03610) && sim_is_active (uptr) &&/* skip rec? */
            ((mt_inst & DEV_OUT) == 0))
            mt_skip = 1;                                /* set flag */
        else CRETINS;
        break;

    case IO_DISC:                                       /* disconnect */
        sim_cancel (uptr);                              /* no more xfr's */
        if (inst & DEV_OUT) {                           /* write? */
            if (r = mt_wrend (inst))                    /* end record */
                return r;
            }
        break;

    case IO_WREOR:                                      /* write eor */
        chan_set_flag (mt_dib.chan, CHF_EOR);           /* set eor flg */
        if (r = mt_wrend (inst))                        /* end record */
            return r;
        mt_gap = 1;                                     /* in gap */
        sim_activate (uptr, mt_gtime);                  /* start timer */        
        break;

    case IO_SKS:                                        /* SKS */
        new_ch = I_GETSKCH (inst);                      /* get chan # */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            return SCPE_IERR;
        if ((inst & (DEV_OUT | DEV_MTS)) == 0) {        /* not sks 1n? */
            t = I_GETSKCND (inst);                      /* get skip cond */
            switch (t) {                                /* case sks cond */
            case 001:                                   /* sks 1021n */
                *dat = 1;                               /* not magpak */
                break;
            case 002:                                   /* sks 1041n */
                if (!(uptr->flags & UNIT_ATT) ||        /* not ready */
                    sim_is_active (uptr)) *dat = 1;
                break;
            case 004:                                   /* sks 1101n */
                if (!uptr->eotf) *dat = 1;              /* not EOT */
                break;
            case 010:                                   /* sks 1201n */
                if (!uptr->botf) *dat = 1;              /* not BOT */
                break;
            case 013:                                   /* sks 12610 */
                if (!mt_gap) *dat = 1;                  /* not in gap */
                break;
            case 017:                                   /* sks 13610 */
                if (!mt_eof) *dat = 1;                  /* not EOF */
                break;
            case 020:                                   /* sks 1401n */
                if (!sim_tape_wrp (uptr)) *dat = 1;     /* not wrp */
                break;
            case 031:                                   /* sks 1621n */
            case 033:                                   /* sks 1661n */
                *dat = 1;                               /* not 556bpi */
            case 035:                                   /* sks 1721n */
                break;                                  /* not 800bpi */
                }
            }                                           /* end if */
        break;

    case IO_READ:                                       /* read */
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        if (mt_blnt == 0) {                             /* first read? */
            r = mt_readrec (uptr);                      /* get data */
            if ((r != SCPE_OK) || (mt_blnt == 0))       /* err, inv reclnt? */
                return r;
            }
        uptr->botf = 0;                                 /* off BOT */
        if (mt_inst & CHC_REV)                          /* get next rev */
            chr = mtxb[--mt_bptr] & 077;
        else chr = mtxb[mt_bptr++] & 077;               /* get next fwd */
        if (!(mt_inst & CHC_BIN))                       /* bcd? */
            chr = bcd_to_sds[chr];
        *dat = chr & 077;                               /* give to chan */
        if ((mt_inst & CHC_REV)? (mt_bptr <= 0):        /* rev or fwd, */
            (mt_bptr >= mt_blnt))                       /* recd done? */
            mt_readend (uptr);
        break;

    case IO_WRITE:                                      /* write */
        uptr->botf = 0;                                 /* off BOT */
        chr = (*dat) & 077;
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        if (!(mt_inst & CHC_BIN))                       /* bcd? */
            chr = sds_to_bcd[chr];
        if (mt_bptr < MT_MAXFR) mtxb[mt_bptr++] = chr;  /* insert in buf */
        break;

    default:
        CRETINS;
        }

return SCPE_OK;
} 
Пример #13
0
uint32 mt (uint32 dev, uint32 op, uint32 dat)
{
uint32 i, f, t;
uint32 u = (dev - mt_dib.dno) / o_MT0;
UNIT *uptr = mt_dev.units + u;

switch (op) {                                           /* case IO op */

    case IO_ADR:                                        /* select */
        sch_adr (mt_dib.sch, dev);                      /* inform sel ch */
        return BY;                                      /* byte only */

    case IO_RD:                                         /* read data */
        if (mt_xfr)                                     /* xfr? set busy */
            mt_sta = mt_sta | STA_BSY;
        return mt_db;                                   /* return data */

    case IO_WD:                                         /* write data */
        if (mt_xfr) {                                   /* transfer? */
            mt_sta = mt_sta | STA_BSY;                  /* set busy */
            if ((uptr->UCMD & (MTC_STOP1 | MTC_STOP2)) &&
                ((uptr->UCMD & MTC_MASK) == MTC_WR))    /* while stopping? */
                mt_sta = mt_sta | STA_ERR;              /* write overrun */
            }
        mt_db = dat & DMASK8;                           /* store data */
        break;

    case IO_SS:                                         /* status */
        mt_sta = mt_sta & STA_MASK;                     /* ctrl status */
        if (uptr->flags & UNIT_ATT)                     /* attached? */
            t = mt_sta | (uptr->UST & STA_UFLGS);       /* yes, unit status */
        else t = mt_sta | STA_DU;                       /* no, dev unavail */
        if (t & SET_EX)                                 /* test for ex */
            t = t | STA_EX;
        return t;

    case IO_OC:                                         /* command */
        mt_arm[u] = int_chg (v_MT + u, dat, mt_arm[u]);
        f = dat & MTC_MASK;                             /* get cmd */
        if (f == MTC_CLR) {                             /* clear? */
            mt_reset (&mt_dev);                         /* reset world */
            break;
            }
        if (((uptr->flags & UNIT_ATT) == 0) ||          /* ignore if unatt */
            bad_cmd[f] ||                               /* or bad cmd */
           (((f == MTC_WR) || (f == MTC_WEOF)) &&       /* or write */
            sim_tape_wrp (uptr)))                       /* and protected */
            break;
        for (i = 0; i < MT_NUMDR; i++) {                /* check other drvs */
            if (sim_is_active (&mt_unit[i]) &&          /* active? */
                (mt_unit[i].UCMD != MTC_REW)) {         /* not rewind? */
                sim_cancel (&mt_unit[i]);               /* stop */
                mt_unit[i].UCMD = 0;
                }
            }
        if (sim_is_active (uptr) &&                     /* unit active? */
           !(uptr->UCMD & (MTC_STOP1 | MTC_STOP2)))     /* not stopping? */
            break;                                      /* ignore */
        if ((f == MTC_WR) || (f == MTC_REW))            /* write, rew: bsy=0 */
            mt_sta = 0;
        else mt_sta = STA_BSY;                          /* bsy=1,nmtn,eom,err=0 */
        mt_bptr = mt_blnt = 0;                          /* not yet started */
        if ((f == MTC_RD) || (f == MTC_WR))             /* data xfr? */
            mt_xfr =  1;                                /* set xfr flag */
        else mt_xfr = 0;
        uptr->UCMD = f;                                 /* save cmd */
        uptr->UST = 0;                                  /* clr tape stat */
        sim_activate (uptr, mt_rtime);                  /* start op */
        break;
        }

return 0;
}
Пример #14
0
static SIGNALS_DATA clk_interface (DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
{
INBOUND_SIGNAL signal;
INBOUND_SET    working_set      = inbound_signals;
HP_WORD        outbound_value   = 0;
OUTBOUND_SET   outbound_signals = NO_SIGNALS;

dprintf (clk_dev, DEB_IOB, "Received data %06o with signals %s\n",
         inbound_value, fmt_bitset (inbound_signals, inbound_format));

while (working_set) {
    signal = IONEXTSIG (working_set);                   /* isolate the next signal */

    switch (signal) {                                   /* dispatch an I/O signal */

        case DCONTSTB:
            control_word = inbound_value;               /* save the control word */

            if (control_word & CN_RESET_LOAD_SEL) {     /* if the reset/load selector is set */
                rate = CN_RATE (control_word);          /*   then load the clock rate */

                if (clk_unit [0].flags & UNIT_CALTIME)  /* if in calibrated timing mode */
                    prescaler = scale [rate];           /*   then set the prescaler */
                else                                    /* otherwise */
                    prescaler = 1;                      /*   the prescaler isn't used */

                sim_cancel (&clk_unit [0]);             /* changing the rate restarts the timing divider */

                if (rate > 0) {                                 /* if the rate is valid */
                    clk_unit [0].wait = delay [rate];           /*   then set the initial service delay */
                    sim_rtcn_init (clk_unit [0].wait, TMR_CLK); /* initialize the clock */
                    resync_clock ();                            /*   and reschedule the service */
                    }
                }

            else if (control_word & CN_MR) {            /* otherwise, if the master reset bit is set */
                clk_reset (&clk_dev);                   /*   then reset the interface */
                control_word = 0;                       /*     (which clears the other settings) */
                }

            if (control_word & CN_IRQ_RESET_ALL) {      /* if a reset of all interrupts is requested */
                limit_irq     = CLEAR;                  /*   then clear the limit = count, */
                lost_tick_irq = CLEAR;                  /*     limit = count overflow, */
                system_irq    = CLEAR;                  /*       and system flip-flops */
                }

            else if (control_word & CN_IRQ_RESET_MASK)  /* otherwise if any single resets are requested */
                switch (CN_RESET (control_word)) {      /*   then reset the specified flip-flop */
                    case 1:
                        limit_irq = CLEAR;              /* clear the limit = count interrupt request */
                        break;

                    case 2:
                        lost_tick_irq = CLEAR;          /* clear the limit = count overflow interrupt request */
                        break;

                    case 3:
                        system_irq = CLEAR;             /* clear the system interrupt request */
                        break;

                    default:                            /* the rest of the values do nothing */
                        break;
                    }

            if (dibptr->interrupt_active == CLEAR)      /* if no interrupt is active */
                working_set |= DRESETINT;               /*   then recalculate interrupt requests */

            dprintf (clk_dev, DEB_CSRW, (inbound_value & CN_RESET_LOAD_SEL
                                           ? "Control is %s | %s rate%s\n"
                                           : "Control is %s%.0s%s\n"),
                     fmt_bitset (inbound_value, control_format),
                     rate_name [CN_RATE (inbound_value)],
                     irq_reset_name [CN_RESET (inbound_value)]);
            break;


        case DSTATSTB:
            status_word = ST_DIO_OK | ST_RATE (rate);   /* set the clock rate */

            if (limit_irq)                              /* if the limit = count flip-flop is set */
                status_word |= ST_LR_EQ_CR;             /*   set the corresponding status bit */

            if (lost_tick_irq)                          /* if the limit = count overflow flip-flop is set */
                status_word |= ST_LR_EQ_CR_OVFL;        /*   set the corresponding status bit */

            if (system_irq)                             /* if the system interrupt request flip-flop is set */
                status_word |= ST_SYSTEM_IRQ;           /*   set the corresponding status bit */

            if (control_word & CN_LIMIT_COUNT_SEL)      /* if the limit/count selector is set */
                status_word |= ST_LIMIT_COUNT_SEL;      /*   set the corresponding status bit */

            if (control_word & CN_COUNT_RESET)          /* if the reset-after-interrupt selector is set */
                status_word |= ST_COUNT_RESET;          /*   set the corresponding status bit */

            outbound_value = status_word;               /* return the status word */

            dprintf (clk_dev, DEB_CSRW, "Status is %s%s rate\n",
                     fmt_bitset (outbound_value, status_format),
                     rate_name [ST_TO_RATE (outbound_value)]);
            break;


        case DREADSTB:
            clk_update_counter ();                          /* update the clock counter register */
            outbound_value = LOWER_WORD (count_register);   /*   and then read it */

            dprintf (clk_dev, DEB_CSRW, "Count register value %u returned\n",
                     count_register);
            break;


        case DWRITESTB:
            if (control_word & CN_LIMIT_COUNT_SEL) {    /* if the limit/count selector is set */
                clk_update_counter ();                  /*   then update the clock counter register */
                count_register = 0;                     /*     and then clear it */

                dprintf (clk_dev, DEB_CSRW, "Count register cleared\n");
                }

            else {                                      /* otherwise */
                limit_register = inbound_value;         /*   set the limit register to the supplied value */

                dprintf (clk_dev, DEB_CSRW, "Limit register value %u set\n",
                         limit_register);

                coschedulable = (ticks [rate] == 1000           /* the clock can be coscheduled if the rate */
                                  && limit_register == 100);    /*   is 1 msec and the limit is 100 ticks */
                }
            break;


        case DSETINT:
            system_irq = SET;                           /* set the system interrupt request flip-flop */

            dibptr->interrupt_request = SET;            /* request an interrupt */
            outbound_signals |= INTREQ;                 /*   and notify the IOP */
            break;


        case DRESETINT:
            dibptr->interrupt_active  = CLEAR;          /* clear the Interrupt Active flip-flop */

            if ((limit_irq == SET || lost_tick_irq == SET)  /* if the limit or lost tick flip-flops are set */
              && control_word & CN_IRQ_ENABLE)              /*   and interrupts are enabled */
                dibptr->interrupt_request = SET;            /*     then set the interrupt request flip-flop */
            else                                            /* otherwise */
                dibptr->interrupt_request = system_irq;     /*   request an interrupt if the system flip-flop is set */

            if (dibptr->interrupt_request)              /* if a request is pending */
                outbound_signals |= INTREQ;             /*   then notify the IOP */
            break;


        case INTPOLLIN:
            if (dibptr->interrupt_request) {            /* if a request is pending */
                dibptr->interrupt_request = CLEAR;      /*   then clear it */
                dibptr->interrupt_active  = SET;        /*     and mark it as now active */

                outbound_signals |= INTACK;             /* acknowledge the interrupt */
                outbound_value = dibptr->device_number; /*   and return our device number */
                }

            else                                        /* otherwise the request has been reset */
                outbound_signals |= INTPOLLOUT;         /*   so let the IOP know to cancel it */
            break;


        case DSTARTIO:                                  /* not used by this interface */
        case DSETMASK:                                  /* not used by this interface */
        case ACKSR:                                     /* not used by this interface */
        case TOGGLESR:                                  /* not used by this interface */
        case SETINT:                                    /* not used by this interface */
        case PCMD1:                                     /* not used by this interface */
        case PCONTSTB:                                  /* not used by this interface */
        case SETJMP:                                    /* not used by this interface */
        case PSTATSTB:                                  /* not used by this interface */
        case PWRITESTB:                                 /* not used by this interface */
        case PREADSTB:                                  /* not used by this interface */
        case EOT:                                       /* not used by this interface */
        case TOGGLEINXFER:                              /* not used by this interface */
        case TOGGLEOUTXFER:                             /* not used by this interface */
        case READNEXTWD:                                /* not used by this interface */
        case TOGGLESIOOK:                               /* not used by this interface */
        case DEVNODB:                                   /* not used by this interface */
        case XFERERROR:                                 /* not used by this interface */
        case CHANSO:                                    /* not used by this interface */
        case PFWARN:                                    /* not used by this interface */
            break;
        }

    IOCLEARSIG (working_set, signal);                   /* remove the current signal from the set */
    }

dprintf (clk_dev, DEB_IOB, "Returned data %06o with signals %s\n",
         outbound_value, fmt_bitset (outbound_signals, outbound_format));

return IORETURN (outbound_signals, outbound_value);     /* return the outbound signals and value */
}
Пример #15
0
static t_stat u39_reset(I8255* chip)
{
    sagelp_unit.buf = 0;
    sim_cancel (&sagelp_unit);
    return SCPE_OK;
}