mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-14 15:44:49 +00:00
KA10: RH20 fixes to allow Tops 10 7.03 to start.
This commit is contained in:
parent
4d0724b21d
commit
851f477700
@ -464,9 +464,9 @@ struct df10 {
|
||||
|
||||
/* RH10/RH20 Interface */
|
||||
struct rh_if {
|
||||
void (*rh_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
|
||||
uint32 (*rh_read)(DEVICE *dptr, struct rh_if *rh, int reg);
|
||||
void (*rh_reset)(DEVICE *dptr);
|
||||
void (*dev_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
|
||||
uint32 (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg);
|
||||
void (*dev_reset)(DEVICE *dptr);
|
||||
t_uint64 buf; /* Data buffer */
|
||||
uint32 status; /* DF10 status word */
|
||||
uint32 cia; /* Initial transfer address */
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
/* RH20 channel status flags */
|
||||
#define RH20_MEM_PAR 00200000000000LL /* Memory parity error */
|
||||
#define RH20_ADR_PAR 00100000000000LL /* Address parity error */
|
||||
#define RH20_NADR_PAR 00100000000000LL /* Address parity error */
|
||||
#define RH20_NOT_WC0 00040000000000LL /* Word count not zero */
|
||||
#define RH20_NXM_ERR 00020000000000LL /* Non existent memory */
|
||||
#define RH20_LAST_ERR 00000400000000LL /* Last transfer error */
|
||||
@ -206,8 +206,6 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
*data |= RH20_ATTN;
|
||||
if (rhc->rae != 0)
|
||||
*data |= RH20_RAE;
|
||||
if ((rhc->status & PI_ENABLE) == 0)
|
||||
*data |= RH20_CHAN_RDY;
|
||||
sim_debug(DEBUG_CONI, dptr, "%s %03o CONI %06o PC=%o %o\n",
|
||||
dptr->name, dev, (uint32)*data, PC, rhc->attn);
|
||||
return SCPE_OK;
|
||||
@ -218,8 +216,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
rhc->status |= *data & (07LL|IADR_ATTN|RH20_MASS_EN);
|
||||
/* Clear flags */
|
||||
if (*data & RH20_CLR_MBC) {
|
||||
if (rhc->rh_reset != NULL)
|
||||
rhc->rh_reset(dptr);
|
||||
if (rhc->dev_reset != NULL)
|
||||
rhc->dev_reset(dptr);
|
||||
rhc->imode = 2;
|
||||
}
|
||||
if (*data & RH20_DELETE_SCR)
|
||||
@ -245,12 +243,12 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
}
|
||||
if (rhc->reg < 040) {
|
||||
int parity;
|
||||
*data = (uint64)(rhc->rh_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
parity = (int)((*data >> 8) ^ *data);
|
||||
parity = (parity >> 4) ^ parity;
|
||||
parity = (parity >> 2) ^ parity;
|
||||
parity = ((parity >> 1) ^ parity) & 1;
|
||||
*data |= ((uint64)(parity ^ 1)) << 17;
|
||||
*data |= ((uint64)(!parity)) << 16;
|
||||
*data |= ((uint64)(rhc->drive)) << 18;
|
||||
*data |= BIT10;
|
||||
} else if ((rhc->reg & 070) != 070) {
|
||||
@ -278,9 +276,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
dptr->name, dev, *data, PC, rhc->status);
|
||||
rhc->reg = ((int)(*data >> 30)) & 077;
|
||||
rhc->imode |= 2;
|
||||
if (rhc->reg < 040 && rhc->reg != 04) {
|
||||
rhc->drive = (int)(*data >> 18) & 07;
|
||||
}
|
||||
if (rhc->reg < 040)
|
||||
rhc->drive = (int)(*data >> 18) & 07;
|
||||
if (*data & LOAD_REG) {
|
||||
if (rhc->reg < 040) {
|
||||
clr_interrupt(dev);
|
||||
@ -289,7 +286,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
rhc->rh_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||
|| (rhc->status & PI_ENABLE))
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
@ -350,8 +347,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
rhc->status &= ~(07LL|IADR_ATTN|IARD_RAE);
|
||||
rhc->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
|
||||
/* Clear flags */
|
||||
if (*data & CONT_RESET && rhc->rh_reset != NULL)
|
||||
rhc->rh_reset(dptr);
|
||||
if (*data & CONT_RESET && rhc->dev_reset != NULL)
|
||||
rhc->dev_reset(dptr);
|
||||
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
|
||||
rhc->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
|
||||
if (*data & OVER_CLR)
|
||||
@ -379,7 +376,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (rhc->reg == 040) {
|
||||
*data = (uint64)(rhc->rh_read(dptr, rhc, 0) & 077);
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, 0) & 077);
|
||||
*data |= ((uint64)(rhc->cia)) << 6;
|
||||
*data |= ((uint64)(rhc->xfer_drive)) << 18;
|
||||
} else if (rhc->reg == 044) {
|
||||
@ -392,7 +389,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
*data = (uint64)(rhc->rae);
|
||||
} else if ((rhc->reg & 040) == 0) {
|
||||
int parity;
|
||||
*data = (uint64)(rhc->rh_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
parity = (int)((*data >> 8) ^ *data);
|
||||
parity = (parity >> 4) ^ parity;
|
||||
parity = (parity >> 2) ^ parity;
|
||||
@ -439,7 +436,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
/* Start command */
|
||||
rh_setup(rhc, (uint32)(*data >> 6));
|
||||
rhc->xfer_drive = (int)(*data >> 18) & 07;
|
||||
rhc->rh_write(dptr, rhc, 0, (uint32)(*data & 077));
|
||||
rhc->dev_write(dptr, rhc, 0, (uint32)(*data & 077));
|
||||
sim_debug(DEBUG_DATAIO, dptr,
|
||||
"%s %03o command %012llo, %d PC=%06o %06o\n",
|
||||
dptr->name, dev, *data, rhc->drive, PC, rhc->status);
|
||||
@ -460,7 +457,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
if (rhc->rae & (1 << rhc->drive)) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
rhc->rh_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
}
|
||||
}
|
||||
clr_interrupt(dev);
|
||||
@ -506,7 +503,8 @@ int rh_blkend(struct rh_if *rhc)
|
||||
{
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
rhc->cia = (rhc->cia + 1) & RH20_WMASK;
|
||||
//fprintf(stderr, "RH blkend %o\n\r", rhc->cia);
|
||||
rhc->cia = (rhc->cia + 1) & 01777;
|
||||
if (rhc->cia == 0) {
|
||||
rhc->status |= RH20_XEND;
|
||||
return 1;
|
||||
@ -527,25 +525,31 @@ void rh_writecw(struct rh_if *rhc, int nxm) {
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
uint32 chan = (rhc->devnum - 0540);
|
||||
if (rhc->ptcr & BIT10) {
|
||||
int wc = (rhc->wcr ^ RH20_WMASK) + 1;
|
||||
int wc = ((rhc->wcr ^ RH20_WMASK) + 1) & RH20_WMASK;
|
||||
rhc->status |= RH20_CHAN_RDY;
|
||||
if (wc != 0 || (rhc->status & RH20_XEND) == 0 ||
|
||||
(rhc->ptcr & BIT10) != 0) {
|
||||
uint64 wrd1 = SMASK|(uint64)(rhc->ccw);
|
||||
if (nxm)
|
||||
if (nxm) {
|
||||
wrd1 |= RH20_NXM_ERR;
|
||||
rhc->status |= RH20_CHAN_ERR;
|
||||
}
|
||||
if (wc != 0) {
|
||||
wrd1 |= RH20_NOT_WC0;
|
||||
if (rhc->status & RH20_XEND) {
|
||||
wrd1 |= RH20_LONG_STS;
|
||||
rhc->status |= RH20_LONG_WC;
|
||||
rhc->status |= RH20_LONG_WC|RH20_CHAN_ERR;
|
||||
}
|
||||
} else if ((rhc->status & RH20_XEND) == 0) {
|
||||
wrd1 |= RH20_SHRT_STS;
|
||||
rhc->status |= RH20_SHRT_WC;
|
||||
rhc->status |= RH20_SHRT_WC|RH20_CHAN_ERR;
|
||||
}
|
||||
wrd1 |= RH20_NADR_PAR;
|
||||
M[eb_ptr|chan|1] = wrd1;
|
||||
M[eb_ptr|chan|2] = ((uint64)rhc->cop << 30) |
|
||||
(((uint64)wc & RH20_WMASK) << CSHIFT) |
|
||||
((uint64)(rhc->cda) & AMASK);
|
||||
M[eb_ptr|chan|2] = ((uint64)rhc->cop << 33) |
|
||||
(((uint64)wc) << CSHIFT) |
|
||||
((uint64)(rhc->cda) & AMASK);
|
||||
//fprintf(stderr, "RH20 final %012llo %012llo %06o\n\r", M[eb_ptr|chan|1], M[eb_ptr|chan|2], wc);
|
||||
}
|
||||
rhc->status &= ~(RH20_PCR_FULL);
|
||||
return;
|
||||
@ -575,7 +579,6 @@ void rh_finish_op(struct rh_if *rhc, int nxm) {
|
||||
}
|
||||
|
||||
#if KL
|
||||
|
||||
/* Set up for a RH20 transfer */
|
||||
void rh20_setup(struct rh_if *rhc)
|
||||
{
|
||||
@ -596,12 +599,12 @@ void rh20_setup(struct rh_if *rhc)
|
||||
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||
rhc->status &= ~(RH20_SCR_FULL|PI_ENABLE|RH20_XEND);
|
||||
rhc->status |= RH20_PCR_FULL;
|
||||
reg = rhc->rh_read(dptr, rhc, 1);
|
||||
reg = rhc->dev_read(dptr, rhc, 1);
|
||||
if ((reg & (DS_DRY|DS_DPR|DS_ERR)) != (DS_DRY|DS_DPR))
|
||||
return;
|
||||
if (rhc->status & RH20_SBAR) {
|
||||
rhc->drive = (rhc->pbar >> 18) & 07;
|
||||
rhc->rh_write(dptr, rhc, 5, (rhc->pbar & 0177777));
|
||||
rhc->dev_write(dptr, rhc, 5, (rhc->pbar & 0177777));
|
||||
rhc->status &= ~RH20_SBAR;
|
||||
}
|
||||
if (rhc->ptcr & BIT7) { /* If RCPL reset I/O pointers */
|
||||
@ -609,9 +612,13 @@ void rh20_setup(struct rh_if *rhc)
|
||||
rhc->wcr = 0;
|
||||
}
|
||||
/* Hold block count in cia */
|
||||
rhc->cia = (rhc->ptcr >> 6);
|
||||
rhc->rh_write(dptr, rhc, 0, (rhc->ptcr & 077));
|
||||
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||
rhc->cia = (rhc->ptcr >> 6) & 01777;
|
||||
rhc->dev_write(dptr, rhc, 0, (rhc->ptcr & 077));
|
||||
rhc->cop = 0;
|
||||
rhc->wcr = 0;
|
||||
rhc->status &= ~RH20_CHAN_RDY;
|
||||
//fprintf(stderr, "RH setup %06o %06o %o\n\r", rhc->ptcr, rhc->ccw, rhc->cia);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -630,7 +637,7 @@ int rh_fetch(struct rh_if *rhc) {
|
||||
uint64 data;
|
||||
#if KL
|
||||
if (rhc->imode == 2 && (rhc->cop & 2) != 0) {
|
||||
rh_finish_op(rhc, 0);
|
||||
// rh_finish_op(rhc, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -641,17 +648,19 @@ int rh_fetch(struct rh_if *rhc) {
|
||||
data = M[rhc->ccw];
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
//fprintf(stderr, "RH20 fetch %06o %012llo\n\r", rhc->ccw, data);
|
||||
while((data & RH20_XFER) == 0) {
|
||||
rhc->ccw = (uint32)(data & AMASK);
|
||||
if ((data & (BIT1|BIT2)) == 0) {
|
||||
rh_finish_op(rhc, 0);
|
||||
break;
|
||||
// rh_finish_op(rhc, 0);
|
||||
return 0;
|
||||
}
|
||||
if (rhc->ccw > MEMSIZE) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
data = M[rhc->ccw];
|
||||
//fprintf(stderr, "RH20 fetch2 %06o %012llo\n\r", rhc->ccw, data);
|
||||
}
|
||||
rhc->wcr = (((data >> CSHIFT) & RH20_WMASK) ^ WMASK) + 1;
|
||||
rhc->cda = (data & AMASK);
|
||||
@ -662,7 +671,7 @@ int rh_fetch(struct rh_if *rhc) {
|
||||
#endif
|
||||
while((data & (WMASK << CSHIFT)) == 0) {
|
||||
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == rhc->ccw) {
|
||||
rh_finish_op(rhc,0);
|
||||
rh_finish_op(rhc, 0);
|
||||
return 0;
|
||||
}
|
||||
rhc->ccw = (uint32)(data & AMASK);
|
||||
|
||||
@ -738,6 +738,7 @@ t_stat rp_svc (UNIT *uptr)
|
||||
struct rh_if *rhc;
|
||||
int diff, da;
|
||||
t_stat r;
|
||||
int sts;
|
||||
|
||||
dptr = rp_devs[ctlr];
|
||||
rhc = &rp_rh[ctlr];
|
||||
@ -887,7 +888,7 @@ t_stat rp_svc (UNIT *uptr)
|
||||
}
|
||||
}
|
||||
if (rh_blkend(rhc))
|
||||
goto rd_end;
|
||||
goto rd_end;
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
} else {
|
||||
@ -930,13 +931,15 @@ rd_end:
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
}
|
||||
r = rh_read(rhc);
|
||||
sts = rh_read(rhc);
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %06o\n",
|
||||
dptr->name, unit, uptr->DATAPTR, rhc->buf, rhc->wcr);
|
||||
rp_buf[ctlr][uptr->DATAPTR++] = rhc->buf;
|
||||
if (r == 0 || uptr->DATAPTR == RP_NUMWD) {
|
||||
if (sts == 0) {
|
||||
while (uptr->DATAPTR < RP_NUMWD)
|
||||
rp_buf[ctlr][uptr->DATAPTR++] = 0;
|
||||
}
|
||||
if (uptr->DATAPTR == RP_NUMWD) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d,%d)\n", dptr->name,
|
||||
unit, cyl, GET_SF(uptr->DA), GET_SC(uptr->DA));
|
||||
da = GET_DA(uptr->DA, dtype) * RP_NUMWD;
|
||||
@ -945,7 +948,7 @@ rd_end:
|
||||
uptr->fileref);
|
||||
uptr->DATAPTR = 0;
|
||||
CLR_BUF(uptr);
|
||||
if (r) {
|
||||
if (sts) {
|
||||
uptr->DA += 1 << DA_V_SC;
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect) {
|
||||
uptr->DA &= (DA_M_SF << DA_V_SF) | (DC_M_CY << DC_V_CY);
|
||||
@ -956,11 +959,11 @@ rd_end:
|
||||
uptr->CMD |= DS_PIP;
|
||||
}
|
||||
}
|
||||
if (rh_blkend(rhc))
|
||||
goto wr_end;
|
||||
}
|
||||
}
|
||||
if (rh_blkend(rhc))
|
||||
goto wr_end;
|
||||
}
|
||||
if (r) {
|
||||
if (sts) {
|
||||
sim_activate(uptr, 10);
|
||||
} else {
|
||||
wr_end:
|
||||
|
||||
362
PDP10/kx10_tu.c
362
PDP10/kx10_tu.c
@ -233,7 +233,7 @@ REG tua_reg[] = {
|
||||
{ORDATA(BUF, tu_rh[0].buf, 36), REG_HRO},
|
||||
{BRDATA(BUFF, &tu_buf[0][0], 16, 64, TU_NUMFR), REG_HRO},
|
||||
{0}
|
||||
};
|
||||
};
|
||||
|
||||
DEVICE tua_dev = {
|
||||
"TUA", tu_unit, NULL, tu_mod,
|
||||
@ -496,135 +496,139 @@ t_stat tu_srv(UNIT * uptr)
|
||||
switch (GET_FNC(uptr->CMD)) {
|
||||
case FNC_NOP:
|
||||
case FNC_DCLR:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o nop\n", dptr->name, unit);
|
||||
tu_error(uptr, MTSE_OK); /* Nop */
|
||||
rh_setirq(rhc);
|
||||
return SCPE_OK;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o nop\n", dptr->name, unit);
|
||||
tu_error(uptr, MTSE_OK); /* Nop */
|
||||
rh_setirq(rhc);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_REWIND:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o rewind\n", dptr->name, unit);
|
||||
if (uptr->CMD & CS1_GO) {
|
||||
sim_activate(uptr,40000);
|
||||
uptr->CMD |= CS_MOTION;
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o rewind\n", dptr->name, unit);
|
||||
if (uptr->CMD & CS1_GO) {
|
||||
sim_activate(uptr,40000);
|
||||
uptr->CMD |= CS_MOTION;
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
} else {
|
||||
uptr->CMD &= ~(CS_MOTION|CS_PIP);
|
||||
uptr->CMD |= CS_CHANGE|CS_ATA;
|
||||
tu_error(uptr, sim_tape_rewind(uptr));
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_UNLOAD:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o unload\n", dptr->name, unit);
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->CMD |= CS_CHANGE|CS_ATA;
|
||||
tu_error(uptr, sim_tape_detach(uptr));
|
||||
return SCPE_OK;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o unload\n", dptr->name, unit);
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->CMD |= CS_CHANGE|CS_ATA;
|
||||
tu_error(uptr, sim_tape_detach(uptr));
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_WCHKREV:
|
||||
case FNC_READREV:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
uptr->CMD &= ~CS_PIP;
|
||||
if ((r = sim_tape_rdrecr(uptr, &tu_buf[ctlr][0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
if (r == MTSE_BOT)
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
tu_error(uptr, r);
|
||||
rh_finish_op(rhc, 0);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d\n", dptr->name, unit, reclen);
|
||||
uptr->CMD |= CS_MOTION;
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = uptr->hwmark-1;
|
||||
uptr->CPOS = cc_max;
|
||||
rhc->buf = 0;
|
||||
sim_activate(uptr, 100);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (uptr->DATAPTR >= 0) {
|
||||
tu_frame[ctlr]++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[ctlr][uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
rhc->buf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
rhc->buf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR--;
|
||||
uptr->CPOS--;
|
||||
if (uptr->CPOS == 0) {
|
||||
uptr->CPOS = cc_max;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READREV && rh_write(rhc) == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readrev %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rhc->buf = 0;
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != cc_max)
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
uptr->CMD &= ~CS_PIP;
|
||||
if ((r = sim_tape_rdrecr(uptr, &tu_buf[ctlr][0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
if (r == MTSE_BOT)
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
tu_error(uptr, r);
|
||||
rh_finish_op(rhc, 0);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d\n", dptr->name, unit, reclen);
|
||||
uptr->CMD |= CS_MOTION;
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = uptr->hwmark-1;
|
||||
uptr->CPOS = cc_max;
|
||||
rhc->buf = 0;
|
||||
sim_activate(uptr, 100);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (uptr->DATAPTR >= 0) {
|
||||
tu_frame[ctlr]++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[ctlr][uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
rhc->buf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
rhc->buf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR--;
|
||||
uptr->CPOS--;
|
||||
if (uptr->CPOS == 0) {
|
||||
uptr->CPOS = cc_max;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READREV && rh_write(rhc) == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readrev %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rhc->buf = 0;
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != cc_max)
|
||||
rh_write(rhc);
|
||||
(void)rh_blkend(rhc);
|
||||
tu_error(uptr, MTSE_OK);
|
||||
(void)rh_blkend(rhc);
|
||||
tu_error(uptr, MTSE_OK);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WCHK:
|
||||
case FNC_READ:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
uptr->CMD &= ~CS_PIP;
|
||||
uptr->CMD |= CS_MOTION;
|
||||
if ((r = sim_tape_rdrecf(uptr, &tu_buf[ctlr][0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
tu_error(uptr, r);
|
||||
rh_finish_op(rhc, 0);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d %d\n", dptr->name, unit, reclen, uptr->pos);
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->CPOS = 0;
|
||||
rhc->buf = 0;
|
||||
sim_activate(uptr, 100);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((uint32)uptr->DATAPTR < uptr->hwmark) {
|
||||
tu_frame[ctlr]++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[ctlr][uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
rhc->buf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
rhc->buf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR++;
|
||||
uptr->CPOS++;
|
||||
if (uptr->CPOS == cc_max) {
|
||||
uptr->CPOS = 0;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READ && rh_write(rhc) == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rhc->buf = 0;
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != 0) {
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rh_write(rhc);
|
||||
}
|
||||
tu_error(uptr, MTSE_OK);
|
||||
(void)rh_blkend(rhc);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
uptr->CMD &= ~CS_PIP;
|
||||
uptr->CMD |= CS_MOTION;
|
||||
if ((r = sim_tape_rdrecf(uptr, &tu_buf[ctlr][0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
tu_error(uptr, r);
|
||||
rh_finish_op(rhc, 0);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d %d\n", dptr->name, unit, reclen, uptr->pos);
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->CPOS = 0;
|
||||
rhc->buf = 0;
|
||||
sim_activate(uptr, 100);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((uint32)uptr->DATAPTR < uptr->hwmark) {
|
||||
tu_frame[ctlr]++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[ctlr][uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
rhc->buf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
rhc->buf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR++;
|
||||
uptr->CPOS++;
|
||||
if (uptr->CPOS == cc_max) {
|
||||
uptr->CPOS = 0;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READ && rh_write(rhc) == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
if (uptr->DATAPTR == uptr->hwmark)
|
||||
(void)rh_blkend(rhc);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rhc->buf = 0;
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != 0) {
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo\n",
|
||||
dptr->name, unit, rhc->buf);
|
||||
rh_write(rhc);
|
||||
}
|
||||
tu_error(uptr, MTSE_OK);
|
||||
(void)rh_blkend(rhc);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WRITE:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
@ -675,81 +679,81 @@ t_stat tu_srv(UNIT * uptr)
|
||||
uptr->CPOS = 010;
|
||||
}
|
||||
if (uptr->CPOS == 010) {
|
||||
/* Write out the block */
|
||||
reclen = uptr->hwmark;
|
||||
r = sim_tape_wrrecf(uptr, &tu_buf[ctlr][0], reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o Write %d %d\n",
|
||||
dptr->name, unit, reclen, uptr->CPOS);
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
(void)rh_blkend(rhc);
|
||||
tu_error(uptr, r); /* Record errors */
|
||||
rh_finish_op(rhc,0 );
|
||||
return SCPE_OK;
|
||||
/* Write out the block */
|
||||
reclen = uptr->hwmark;
|
||||
r = sim_tape_wrrecf(uptr, &tu_buf[ctlr][0], reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o Write %d %d\n",
|
||||
dptr->name, unit, reclen, uptr->CPOS);
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
(void)rh_blkend(rhc);
|
||||
tu_error(uptr, r); /* Record errors */
|
||||
rh_finish_op(rhc,0 );
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WTM:
|
||||
uptr->CMD |= CS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrtmk(uptr));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o WTM\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
uptr->CMD |= CS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrtmk(uptr));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o WTM\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_ERASE:
|
||||
uptr->CMD |= CS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrgap(uptr, 35));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o ERG\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
uptr->CMD |= CS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrgap(uptr, 35));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o ERG\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_SPACEF:
|
||||
case FNC_SPACEB:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o space %o\n", dptr->name, unit, GET_FNC(uptr->CMD));
|
||||
if (tu_frame[ctlr] == 0) {
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
uptr->CMD |= CS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->CMD |= CS_MOTION;
|
||||
/* Always skip at least one record */
|
||||
if (GET_FNC(uptr->CMD) == FNC_SPACEF)
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
else
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
switch (r) {
|
||||
case MTSE_OK: /* no error */
|
||||
break;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o space %o\n", dptr->name, unit, GET_FNC(uptr->CMD));
|
||||
if (tu_frame[ctlr] == 0) {
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
uptr->CMD |= CS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->CMD |= CS_MOTION;
|
||||
/* Always skip at least one record */
|
||||
if (GET_FNC(uptr->CMD) == FNC_SPACEF)
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
else
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
switch (r) {
|
||||
case MTSE_OK: /* no error */
|
||||
break;
|
||||
|
||||
case MTSE_BOT: /* beginning of tape */
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
/* Fall Through */
|
||||
case MTSE_BOT: /* beginning of tape */
|
||||
uptr->STATUS |= ER1_NEF;
|
||||
/* Fall Through */
|
||||
|
||||
case MTSE_TMK: /* tape mark */
|
||||
case MTSE_EOM: /* end of medium */
|
||||
if (tu_frame[ctlr] != 0)
|
||||
uptr->STATUS |= ER1_FCE;
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->CMD |= CS_ATA;
|
||||
/* Stop motion if we recieve any of these */
|
||||
tu_error(uptr, r);
|
||||
return SCPE_OK;
|
||||
}
|
||||
tu_frame[ctlr] = 0177777 & (tu_frame[ctlr] + 1);
|
||||
if (tu_frame[ctlr] == 0) {
|
||||
uptr->CMD |= CS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
sim_activate(uptr, 5000);
|
||||
return SCPE_OK;
|
||||
case MTSE_TMK: /* tape mark */
|
||||
case MTSE_EOM: /* end of medium */
|
||||
if (tu_frame[ctlr] != 0)
|
||||
uptr->STATUS |= ER1_FCE;
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->CMD |= CS_ATA;
|
||||
/* Stop motion if we recieve any of these */
|
||||
tu_error(uptr, r);
|
||||
return SCPE_OK;
|
||||
}
|
||||
tu_frame[ctlr] = 0177777 & (tu_frame[ctlr] + 1);
|
||||
if (tu_frame[ctlr] == 0) {
|
||||
uptr->CMD |= CS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
sim_activate(uptr, 5000);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_activate(uptr, 100);
|
||||
return SCPE_OK;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user