Beispiel #1
0
int32 ts_write (UNIT *uptr, int32 fc)
{
int32 i, t;
uint32 wa;
t_stat st;

msgrfc = fc;
if (fc == 0)                                            /* byte count */
    fc = 0200000;
tsba = (cmdadh << 16) | cmdadl;                         /* buf addr */
if (cmdhdr & CMD_SWP) {                                 /* swapped? */
    for (i = 0; i < fc; i++) {                          /* copy mem to buf */
        wa = tsba ^ 1;                                  /* apply OPP */
        if (Map_ReadB (wa, 1, &tsxb[i])) {              /* fetch byte, nxm? */
            tssr = ts_updtssr (tssr | TSSR_NXM);
            return TC5;
            }
        tsba = tsba + 1;
        }
    }
else {
    t = Map_ReadB (tsba, fc, tsxb);                     /* fetch record */
    tsba = tsba + (fc - t);                             /* update tsba */
    if (t) {                                            /* nxm? */
        tssr = ts_updtssr (tssr | TSSR_NXM);
        return TC5;
        }
    }
if ((st = sim_tape_wrrecf (uptr, tsxb, fc)))            /* write rec, err? */
    return ts_map_status (st);                          /* return status */
msgxs0 = msgxs0 | XS0_MOT;                              /* tape has moved */
msgrfc = 0;
if (sim_tape_eot (&ts_unit))                            /* EOT on write? */
    return XTC (XS0_EOT, TC2);
return 0;
}
Beispiel #2
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;
}