Пример #1
0
uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
{
    int                 chan = UNIT_G_CHAN(uptr->flags);
    int                 u = (uptr - cdp_unit);
    extern uint16   IC;

    if ((uptr->flags & UNIT_ATT) != 0 && cmd == IO_WRS) {
        /* Start device */
        if (!(uptr->u5 & CDPSTA_CMD)) {
            dev_pulse[chan] &= ~PUNCH_M;
            uptr->u5 &= ~CDPSTA_PUNCH;
            if ((uptr->u5 & CDPSTA_ON) == 0) {
                uptr->wait = 330;       /* Startup delay */
            } else if (uptr->u5 & CDPSTA_IDLE && uptr->wait <= 30) {
                uptr->wait += 85;       /* Wait for next latch point */
            }
            uptr->u5 |= (CDPSTA_WRITE | CDPSTA_CMD);
            uptr->u5 &= ~CDPSTA_POSMASK;
            chan_set_sel(chan, 1);
            chan_clear_status(chan);
            sim_activate(uptr, us_to_ticks(1000));      /* activate */
            sim_debug(DEBUG_CMD, &cdp_dev, "%05o WRS unit=%d\n", IC, u);
            return SCPE_OK;
        }
    }
    chan_set_attn(chan);
    return SCPE_IOERR;
}
Пример #2
0
t_stat
cdr_attach(UNIT * uptr, CONST char *file)
{
    t_stat              r;

    if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
        return r;
    if (uptr->up7 == 0) {
        uptr->up7 = malloc(sizeof(uint16)*80);
        uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO;
        uptr->u4 = 0;
        uptr->u6 = 0;
    }
#ifdef I7010
    chan_set_attn_urec(UNIT_G_CHAN(uptr->flags), cdr_dib.addr);
#endif
    return SCPE_OK;
}
Пример #3
0
t_stat cdp_srv(UNIT * uptr)
{
    int                 chan = UNIT_G_CHAN(uptr->flags);
    int                 u = (uptr - cdp_unit);
    int                 pos;
    t_uint64            wd;
    int                 bit;
    t_uint64            mask;
    int                 b;
    int                 col;
    struct _card_data   *data;

    /* Channel has disconnected, abort current card. */
    if (uptr->u5 & CDPSTA_CMD && chan_stat(chan, DEV_DISCO)) {
        if ((uptr->u5 & CDPSTA_POSMASK) != 0) {
            sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
            sim_punch_card(uptr, NULL);
            uptr->u5 &= ~CDPSTA_PUNCH;
        }
        uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_CMD | CDPSTA_POSMASK);
        chan_clear(chan, DEV_WEOR | DEV_SEL);
        sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
    }

    /* Check to see if we have timed out */
    if (uptr->wait != 0) {
        uptr->wait--;
        /* If at end of record and channel is still active, do another read */
        if (
            ((uptr->u5 & (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_WRITE | CDPSTA_ON))
                  == (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_ON)) && uptr->wait > 30
                  && chan_test(chan, STA_ACTIVE)) {
            uptr->u5 |= CDPSTA_WRITE;
            uptr->u5 &= ~CDPSTA_IDLE;
            chan_set(chan, DEV_WRITE);
            chan_clear(chan, DEV_WEOR);
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d restarting\n", u);
        }
        sim_activate(uptr, us_to_ticks(1000));  /* activate */
        return SCPE_OK;
    }

    /* If no write request, go to idle mode */
    if ((uptr->u5 & CDPSTA_WRITE) == 0) {
        if ((uptr->u5 & (CDPSTA_IDLE | CDPSTA_ON)) ==
            (CDPSTA_IDLE | CDPSTA_ON)) {
            uptr->wait = 85;    /* Delay 85ms */
            uptr->u5 &= ~CDPSTA_IDLE;   /* Not running */
            sim_activate(uptr, us_to_ticks(1000));
        } else {
            uptr->u5 &= ~CDPSTA_ON;     /* Turn motor off */
        }
        return SCPE_OK;
    }

    /* Motor is up to speed now */
    uptr->u5 |= CDPSTA_ON;
    uptr->u5 &= ~CDPSTA_IDLE;   /* Not running */

    if (dev_pulse[chan] & PUNCH_M)
        uptr->u5 |= CDPSTA_PUNCH;

    pos = (uptr->u5 & CDPSTA_POSMASK) >> CDPSTA_POSSHIFT;
    if (pos == 24) {
        if (chan_test(chan, STA_ACTIVE)) {
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d set EOR\n", u);
            chan_set(chan, DEV_REOR);
        } else {
            chan_clear(chan, DEV_WEOR | DEV_SEL);
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
        }
        sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
        sim_punch_card(uptr, NULL);
        uptr->u5 |= CDPSTA_IDLE;
        uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
        uptr->wait = 85;
        sim_activate(uptr, us_to_ticks(1000));
        return SCPE_OK;
    }



    sim_debug(DEBUG_DATA, &cdp_dev, "unit=%d write column %d ", u, pos);
    wd = 0;
    data = (struct _card_data *)uptr->up7;
    switch (chan_read(chan, &wd, 0)) {
    case DATA_OK:
        sim_debug(DEBUG_DATA, &cdp_dev, " %012llo\n", wd);
        /* Bit flip into temp buffer */
        bit = 1 << (pos / 2);
        mask = 1;
        b = (pos & 1)?36:0;

        for (col = 35; col >= 0; mask <<= 1, col--) {
            if (wd & mask)
                data->image[col + b] |= bit;
        }
        pos++;
        uptr->wait = 0;
        uptr->u5 &= ~CDPSTA_POSMASK;
        uptr->u5 |= (pos << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        sim_activate(uptr, (pos & 1) ? us_to_ticks(300) : us_to_ticks(8000));
        return SCPE_OK;
    case END_RECORD:
        sim_debug(DEBUG_DATA, &cdp_dev, "eor\n");
        uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
        uptr->u5 &= ~(CDPSTA_POSMASK);
        uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        break;
    case TIME_ERROR:
        sim_debug(DEBUG_DATA, &cdp_dev, "no data\n");
        uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
        uptr->u5 &= ~(CDPSTA_POSMASK);
        uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        break;
    }

    sim_activate(uptr, us_to_ticks(1000));
    return SCPE_OK;
}
Пример #4
0
/* Handle transfer of data for card reader */
t_stat
cdr_srv(UNIT *uptr) {
    int                 chan = UNIT_G_CHAN(uptr->flags);
    int                 u = (uptr - cdr_unit);
    uint16             *image = (uint16 *)(uptr->up7);

    /* Waiting for disconnect */
    if (uptr->u5 & URCSTA_WDISCO) {
        if (chan_stat(chan, DEV_DISCO)) {
            chan_clear(chan, DEV_SEL|DEV_WEOR);
            uptr->u5 &= ~ URCSTA_WDISCO;
        } else {
            /* No disco yet, try again in a bit */
            sim_activate(uptr, 50);
            return SCPE_OK;
        }
        /* If still busy, schedule another wait */
        if (uptr->u5 & URCSTA_BUSY)
             sim_activate(uptr, uptr->wait);
    }

    if (uptr->u5 & URCSTA_BUSY) {
        uptr->u5 &= ~URCSTA_BUSY;
#ifdef I7070
        switch(uptr->flags & (ATTENA|ATTENB)) {
        case ATTENA: chan_set_attn_a(chan); break;
        case ATTENB: chan_set_attn_b(chan); break;
        }
#endif
    }

    /* Check if new card requested. */
    if (uptr->u4 == 0 && uptr->u5 & URCSTA_READ &&
                (uptr->u5 & URCSTA_CARD) == 0) {
        switch(sim_read_card(uptr, image)) {
        case CDSE_EOF:
             sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: EOF\n", u);
             /* Fall through */

        case CDSE_EMPTY:
             chan_set_eof(chan);
             chan_set_attn(chan);
             chan_clear(chan, DEV_SEL);
             uptr->u5 |= URCSTA_EOF;
             uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
             return SCPE_OK;
        case CDSE_ERROR:
             sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: ERF\n", u);
             uptr->u5 |= URCSTA_ERR;
             uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
             chan_set_attn(chan);
             chan_clear(chan, DEV_SEL);
             return SCPE_OK;
        case CDSE_OK:
             uptr->u5 |= URCSTA_CARD;
#ifdef I7010
             chan_set_attn_urec(chan, cdr_dib.addr);
#endif
             break;
        }
#ifdef I7070
        /* Check if load card. */
        if (uptr->capac && (image[uptr->capac-1] & 0x800)) {
             uptr->u5 |= URCSTA_LOAD;
             chan_set_load_mode(chan);
        } else {
             uptr->u5 &= ~URCSTA_LOAD;
        }
#endif
    }

    if (uptr->u5 & URCSTA_NOXFER) {
        uptr->u5 &= ~(URCSTA_NOXFER|URCSTA_READ);
        return SCPE_OK;
    }

    /* Copy next column over */
    if (uptr->u5 & URCSTA_READ && uptr->u4 < 80) {
        uint8                ch = 0;

#ifdef I7080
        /* Detect RSU */
        if (image[uptr->u4] == 0x924) {
             uptr->u5 &= ~URCSTA_READ;
             uptr->u5 |= URCSTA_WDISCO;
             chan_set(chan, DEV_REOR);
             sim_activate(uptr, 10);
             return SCPE_OK;
        }
#endif

        ch = sim_hol_to_bcd(image[uptr->u4]);

        /* Handle invalid punch */
        if (ch == 0x7f) {
#ifdef I7080
             uptr->u5 &= ~(URCSTA_READ|URCSTA_BUSY);
             sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: bad punch %d\n", u,
                       uptr->u4);
             chan_set_attn(chan);
             chan_set_error(chan);
             chan_clear(chan, DEV_SEL);
#else
             uptr->u5 |= URCSTA_ERR;
             ch = 017;
#endif
        }

#ifdef I7070
        /* During load, only sign on every 10 columns */
        if (uptr->u5 & URCSTA_LOAD && (uptr->u4 % 10) != 9)
            ch &= 0xf;
#endif

        switch(chan_write_char(chan, &ch, (uptr->u4 == 79)? DEV_REOR: 0)) {
        case TIME_ERROR:
        case END_RECORD:
            uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY;
            uptr->u5 &= ~URCSTA_READ;
            break;
        case DATA_OK:
            uptr->u4++;
            break;
        }
        sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch);
        sim_activate(uptr, 10);
    }
    return SCPE_OK;
}
Пример #5
0
/*
 * Device entry points for card reader.
 */
uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
{
    int                 chan = UNIT_G_CHAN(uptr->flags);
    int                 u = (uptr - cdr_unit);
    int                 stk = dev & 017;

    /* Are we currently tranfering? */
    if (uptr->u5 & URCSTA_READ)
        return SCPE_BUSY;

    /* Test ready */
    if (cmd == IO_TRS && uptr->flags & UNIT_ATT) {
        sim_debug(DEBUG_CMD, &cdr_dev, "%d: Test Rdy\n", u);
        return SCPE_OK;
    }

    if (stk == 10)
        stk = 0;

#ifdef STACK_DEV
    uptr->u5 &= ~0xF0000;
    uptr->u5 |= stk << 16;
#endif
    if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR))
        return SCPE_IOERR;

    /* Process commands */
    switch(cmd) {
    case IO_RDS:
        sim_debug(DEBUG_CMD, &cdr_dev, "%d: Cmd RDS %02o\n", u, dev & 077);
#ifdef I7010
        if (stk!= 9)
#endif
        uptr->u5 &= ~(URCSTA_CARD|URCSTA_ERR);
        break;
    case IO_CTL:
        sim_debug(DEBUG_CMD, &cdr_dev, "%d: Cmd CTL %02o\n", u, dev & 077);
#ifdef I7010
        uptr->u5 |= URCSTA_NOXFER;
#endif
        break;
    default:
        chan_set_attn(chan);
        return SCPE_IOERR;
    }

    /* If at eof, just return EOF */
    if (uptr->u5 & URCSTA_EOF) {
        chan_set_eof(chan);
        chan_set_attn(chan);
        return SCPE_OK;
    }

    uptr->u5 |= URCSTA_READ;
    uptr->u4 = 0;

    if ((uptr->u5 & URCSTA_NOXFER) == 0)
        chan_set_sel(chan, 0);
    /* Wake it up if not busy */
    if ((uptr->u5 & URCSTA_BUSY) == 0)
        sim_activate(uptr, 50);
    return SCPE_OK;
}