diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 6ba7e7d..0a30c86 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -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 */ diff --git a/PDP10/kx10_rh.c b/PDP10/kx10_rh.c index cf7de14..30521aa 100644 --- a/PDP10/kx10_rh.c +++ b/PDP10/kx10_rh.c @@ -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); diff --git a/PDP10/kx10_rp.c b/PDP10/kx10_rp.c index 28c93d2..56bdeba 100644 --- a/PDP10/kx10_rp.c +++ b/PDP10/kx10_rp.c @@ -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: diff --git a/PDP10/kx10_tu.c b/PDP10/kx10_tu.c index 34fb4ef..f6f17a2 100644 --- a/PDP10/kx10_tu.c +++ b/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;