Пример #1
0
t_stat rx_svc (UNIT *uptr)
{
int32 i, func;
uint32 da;
int8 *fbuf = uptr->filebuf;

func = RXCS_GETFNC (rx_csr);                            /* get function */
switch (rx_state) {                                     /* case on state */

    case IDLE:                                          /* idle */
        return SCPE_IERR;                               /* done */

    case EMPTY:                                         /* empty buffer */
        if (rx_bptr >= RX_NUMBY)                        /* done all? */
            rx_done (0, 0);
        else {
            rx_dbr = rx_buf[rx_bptr];                   /* get next */
            rx_bptr = rx_bptr + 1;
            rx_csr = rx_csr | RXCS_TR;                  /* set xfer */
            }
        break;

    case FILL:                                          /* fill buffer */
        rx_buf[rx_bptr] = rx_dbr;                       /* write next */
        rx_bptr = rx_bptr + 1;
        if (rx_bptr < RX_NUMBY)                         /* more? set xfer */
            rx_csr = rx_csr | RXCS_TR;
        else rx_done (0, 0);                            /* else done */
        break;

    case RWDS:                                          /* wait for sector */
        rx_sector = rx_dbr & RX_M_SECTOR;               /* save sector */
        rx_csr = rx_csr | RXCS_TR;                      /* set xfer */
        rx_state = RWDT;                                /* advance state */
        return SCPE_OK;

    case RWDT:                                          /* wait for track */
        rx_track = rx_dbr & RX_M_TRACK;                 /* save track */
        rx_state = RWXFR;
        sim_activate (uptr,                             /* sched done */
                rx_swait * abs (rx_track - uptr->TRACK));
        return SCPE_OK;

    case RWXFR:
        if ((uptr->flags & UNIT_BUF) == 0) {            /* not buffered? */
            rx_done (0, 0110);                          /* done, error */
            return IORETURN (rx_stopioe, SCPE_UNATT);
            }
        if (rx_track >= RX_NUMTR) {                     /* bad track? */
            rx_done (0, 0040);                          /* done, error */
            break;
            }
        uptr->TRACK = rx_track;                         /* now on track */
        if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */
            rx_done (0, 0070);                          /* done, error */
            break;
            }
        da = CALC_DA (rx_track, rx_sector);             /* get disk address */
        if (func == RXCS_WRDEL)                         /* del data? */
            rx_esr = rx_esr | RXES_DD;
        if (func == RXCS_READ) {                        /* read? */
            for (i = 0; i < RX_NUMBY; i++)
                rx_buf[i] = fbuf[da + i];
            }
        else {
            if (uptr->flags & UNIT_WPRT) {              /* write and locked? */
                rx_done (RXES_WLK, 0100);               /* done, error */
                break;
                }
            for (i = 0; i < RX_NUMBY; i++)              /* write */
                fbuf[da + i] = rx_buf[i];
            da = da + RX_NUMBY;
            if (da > uptr->hwmark)
                uptr->hwmark = da;
            }
        rx_done (0, 0);                                 /* done */
        break;

    case CMD_COMPLETE:                                  /* command complete */
        if (func == RXCS_ECODE) {                       /* read ecode? */
            rx_dbr = rx_ecode;                          /* set dbr */
            rx_done (0, -1);                            /* don't update */
            }
        else rx_done (0, 0);
        break;

    case INIT_COMPLETE:                                 /* init complete */
        rx_unit[0].TRACK = 1;                           /* drive 0 to trk 1 */
        rx_unit[1].TRACK = 0;                           /* drive 1 to trk 0 */
        if ((rx_unit[0].flags & UNIT_BUF) == 0) {       /* not buffered? */
            rx_done (RXES_ID, 0010);                    /* init done, error */
            break;
            }
        da = CALC_DA (1, 1);                            /* track 1, sector 1 */
        for (i = 0; i < RX_NUMBY; i++)                  /* read sector */
            rx_buf[i] = fbuf[da + i];
        rx_done (RXES_ID, 0);                           /* set done */
        if ((rx_unit[1].flags & UNIT_ATT) == 0)
            rx_ecode = 0020;
        break;
        }                                               /* end case state */

return SCPE_OK;
}
Пример #2
0
t_stat fl_svc (UNIT *uptr)
{
int32 i, t;
uint32 da;
int8 *fbuf = uptr->filebuf;

switch (fl_state) {                                     /* case on state */

    case FL_IDLE:                                       /* idle */
        return SCPE_IERR;                               /* done */

    case FL_READ: case FL_WRITE:                        /* read, write */
        fl_state = fl_state + 1;                        /* set next state */
        t = abs (fl_track - uptr->TRACK);               /* # tracks to seek */
        if (t == 0)                                     /* minimum 1 */
            t = 1;
        sim_activate (uptr, fl_swait * t);              /* schedule seek */
                                                        /* fall thru, set flag */
    case FL_RWDS: case FL_RWDT: case FL_FILL:           /* rwds, rwdt, fill */
        tto_csr = tto_csr | CSR_DONE;                   /* set output done */
        if (tto_csr & CSR_IE)
            tto_int = 1;
        break;

    case FL_READ1:                                      /* read, seek done */
        if (fl_test_xfr (uptr, FALSE)) {                /* transfer ok? */
            da = CALC_DA (fl_track, fl_sector);         /* get disk address */
            for (i = 0; i < FL_NUMBY; i++)              /* copy sector to buf */
                fl_buf[i] = fbuf[da + i];
            tti_buf = fl_esr | FL_CDONE;                /* completion code */
            tti_csr = tti_csr | CSR_DONE;               /* set input flag */
            if (tti_csr & CSR_IE)
                tti_int = 1;      
            fl_state = FL_EMPTY;                        /* go empty */
            }
        else fl_state = FL_DONE;                        /* error? cmd done */
        sim_activate (uptr, fl_xwait);                  /* schedule next */
        break;

    case FL_EMPTY:                                      /* empty buffer */
        if ((tti_csr & CSR_DONE) == 0) {                /* prev data taken? */
            tti_buf = FL_CDATA | fl_buf[fl_bptr++];     /* get next byte */
            tti_csr = tti_csr | CSR_DONE;               /* set input flag */
            if (tti_csr & CSR_IE)
                tti_int = 1;
            if (fl_bptr >= FL_NUMBY) {                  /* buffer empty? */
                fl_state = FL_IDLE;                     /* cmd done */
                break;
                }
            }
        sim_activate (uptr, fl_xwait);                  /* schedule next */
        break;

    case FL_WRITE1:                                     /* write, seek done */
        if (fl_test_xfr (uptr, TRUE)) {                 /* transfer ok? */
            da = CALC_DA (fl_track, fl_sector);         /* get disk address */
            for (i = 0; i < FL_NUMBY; i++)              /* copy buf to sector */
                fbuf[da + i] = fl_buf[i];
            da = da + FL_NUMBY;
            if (da > uptr->hwmark)                      /* update hwmark */
                uptr->hwmark = da;
            }
        if (fl_fnc == FL_FNCWD)                         /* wrdel? set status */
            fl_esr |= FL_STADDA;
        fl_state = FL_DONE;                             /* command done */
        sim_activate (uptr, fl_xwait);                  /* schedule */
        break;

    case FL_DONE:                                       /* command done */
        if (tti_csr & CSR_DONE)                         /* input buf empty? */
            sim_activate (uptr, fl_xwait);              /* no, wait */
        else {                                          /* yes */
            tti_buf = fl_esr | FL_CDONE;                /* completion code */
            tti_csr = tti_csr | CSR_DONE;               /* set input flag */
            if (tti_csr & CSR_IE)
                tti_int = 1;
            fl_state = FL_IDLE;                         /* floppy idle */
            }
        break;    

    case FL_READSTA:                                    /* read status */
        if ((tti_csr & CSR_DONE) == 0) {                /* input buf empty? */
            tti_buf = fl_ecode;                         /* return err code */
            tti_csr = tti_csr | CSR_DONE;               /* set input flag */
            if (tti_csr & CSR_IE)
                tti_int = 1;
            fl_state = FL_DONE;                         /* command done */
            }
        sim_activate (uptr, fl_xwait);
        break;
        }
return SCPE_OK;
}
Пример #3
0
t_stat ry_svc (UNIT *uptr)
{
int32 i, t, func, bps;
static uint8 estat[8];
uint32 ba, da;
int8 *fbuf = uptr->filebuf;

func = RYCS_GETFNC (ry_csr);                            /* get function */
bps = (ry_csr & RYCS_DEN)? RY_NUMBY: RX_NUMBY;          /* get sector size */
ba = (RYCS_GETUAE (ry_csr) << 16) | ry_ba;              /* get mem addr */
switch (ry_state) {                                     /* case on state */

    case IDLE:                                          /* idle */
        return SCPE_IERR;

    case FEWC:                                          /* word count */
        ry_wc = ry_dbr & 0377;                          /* save WC */
        ry_csr = ry_csr | RYCS_TR;                      /* set TR */
        ry_state = FEBA;                                /* next state */
        return SCPE_OK;

    case FEBA:                                          /* buffer address */
        ry_ba = ry_dbr;                                 /* save buf addr */
        ry_state = FEXFR;                               /* next state */
        sim_activate (uptr, ry_cwait);                  /* schedule xfer */
        return SCPE_OK;

    case FEXFR:                                         /* transfer */
        if ((ry_wc << 1) > bps) {                       /* wc too big? */
            ry_done (RYES_WCO, 0230);                   /* error */
            break;
            }
        if (func == RYCS_FILL) {                        /* fill? read */
            for (i = 0; i < RY_NUMBY; i++)
                rx2xb[i] = 0;
            t = Map_ReadB (ba, ry_wc << 1, rx2xb);
            }
        else t = Map_WriteB (ba, ry_wc << 1, rx2xb);
        ry_wc = t >> 1;                                 /* adjust wc */
        ry_done (t? RYES_NXM: 0, 0);                    /* done */
        break;

    case RWDS:                                          /* wait for sector */
        ry_sector = ry_dbr & RX_M_SECTOR;               /* save sector */
        ry_csr = ry_csr | RYCS_TR;                      /* set xfer */
        ry_state = RWDT;                                /* advance state */
        return SCPE_OK;

    case RWDT:                                          /* wait for track */
        ry_track = ry_dbr & RX_M_TRACK;                 /* save track */
        ry_state = RWXFR;                               /* next state */
        sim_activate (uptr,                             /* sched xfer */
            ry_swait * abs (ry_track - uptr->TRACK));
        return SCPE_OK;

    case RWXFR:                                         /* read/write */
        if ((uptr->flags & UNIT_BUF) == 0) {            /* not buffered? */
            ry_done (0, 0110);                          /* done, error */
            return IORETURN (ry_stopioe, SCPE_UNATT);
            }
        if (ry_track >= RX_NUMTR) {                     /* bad track? */
            ry_done (0, 0040);                          /* done, error */
            break;
            }
        uptr->TRACK = ry_track;                         /* now on track */
        if ((ry_sector == 0) || (ry_sector > RX_NUMSC)) { /* bad sect? */
            ry_done (0, 0070);                          /* done, error */
            break;
            }
        if (((uptr->flags & UNIT_DEN) != 0) ^
            ((ry_csr & RYCS_DEN) != 0)) {               /* densities agree? */
            ry_done (RYES_DERR, 0240);                  /* no, error */
            break;
            }
        da = CALC_DA (ry_track, ry_sector, bps);        /* get disk address */
        if (func == RYCS_WRDEL)                         /* del data? */
            ry_esr = ry_esr | RYES_DD;
        if (func == RYCS_READ) {                        /* read? */
            for (i = 0; i < bps; i++)
                rx2xb[i] = fbuf[da + i];
             }
        else {
            if (uptr->flags & UNIT_WPRT) {              /* write and locked? */
                ry_done (0, 0100);                      /* done, error */
                break;
                }
            for (i = 0; i < bps; i++)                   /* write */
                fbuf[da + i] = rx2xb[i];
            da = da + bps;
            if (da > uptr->hwmark)
                uptr->hwmark = da;
            }
        ry_done (0, 0);                                 /* done */
        break;

    case SDCNF:                                         /* confirm set density */
        if ((ry_dbr & 0377) != 0111) {                  /* confirmed? */
            ry_done (0, 0250);                          /* no, error */
            break;
            }
        ry_state = SDXFR;                               /* next state */
        sim_activate (uptr, ry_cwait * 100);            /* schedule operation */
        break;

	case SDXFR:                                         /* erase disk */
		for (i = 0; i < (int32) uptr->capac; i++)
            fbuf[i] = 0;
		uptr->hwmark = (uint32) uptr->capac;
		if (ry_csr & RYCS_DEN)
            uptr->flags = uptr->flags | UNIT_DEN;
		else uptr->flags = uptr->flags & ~UNIT_DEN;
		ry_done (0, 0);
		break;


	case ESBA:
		ry_ba = ry_dbr;                                 /* save WC */
		ry_state = ESXFR;                               /* next state */
		sim_activate (uptr, ry_cwait);                  /* schedule xfer */
		return SCPE_OK;

	case ESXFR:
		estat[0] = ry_ecode;                            /* fill 8B status */
		estat[1] = ry_wc;
		estat[2] = ry_unit[0].TRACK;
		estat[3] = ry_unit[1].TRACK;
		estat[4] = ry_track;
		estat[5] = ry_sector;
		estat[6] = ((ry_csr & RYCS_DRV)? 0200: 0) |
			       ((ry_unit[1].flags & UNIT_DEN)? 0100: 0) |
                   ((uptr->flags & UNIT_ATT)? 0040: 0) |
                   ((ry_unit[0].flags & UNIT_DEN)? 0020: 0) |
                   ((ry_csr & RYCS_DEN)? 0001: 0);
		estat[7] = uptr->TRACK;
		t = Map_WriteB (ba, 8, estat);                  /* DMA to memory */
		ry_done (t? RYES_NXM: 0, 0);                    /* done */
		break;

	case CMD_COMPLETE:                                  /* command complete */
		ry_done (0, 0);
		break;

	case INIT_COMPLETE:                                 /* init complete */
		ry_unit[0].TRACK = 1;                           /* drive 0 to trk 1 */
		ry_unit[1].TRACK = 0;                           /* drive 1 to trk 0 */
		if ((uptr->flags & UNIT_BUF) == 0) {            /* not buffered? */
			ry_done (RYES_ID, 0010);                    /* init done, error */
			break;
			}
		da = CALC_DA (1, 1, bps);                       /* track 1, sector 1 */
		for (i = 0; i < bps; i++)                       /* read sector */
			rx2xb[i] = fbuf[da + i];
		ry_done (RYES_ID, 0);                           /* set done */
		if ((ry_unit[1].flags & UNIT_ATT) == 0)
            ry_ecode = 0020;
		break;
		}                                               /* end case state */

return SCPE_OK;
}