1
0
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:
Richard Cornwell 2019-10-20 22:52:46 -04:00
parent 4d0724b21d
commit 851f477700
4 changed files with 241 additions and 225 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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:

View File

@ -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;