KA10: Corrected error in NIA Padding. Handle disabled RH devices.

This commit is contained in:
Richard Cornwell 2020-03-25 20:24:13 -07:00 committed by Mark Pizzolato
parent 7d1a81b9f9
commit c22766b760
7 changed files with 118 additions and 75 deletions

View file

@ -1143,6 +1143,12 @@ int nia_send_pkt(uint64 cmd)
memcpy(hdr->src, nia_data.mac, sizeof(ETH_MAC)); memcpy(hdr->src, nia_data.mac, sizeof(ETH_MAC));
/* Set packet length */ /* Set packet length */
nia_data.snd_buff.len = len + sizeof(struct nia_eth_hdr); nia_data.snd_buff.len = len + sizeof(struct nia_eth_hdr);
/* Preappend length if asking for pad */
if ((cmd & (NIA_FLG_PAD << 8)) != 0) {
*data++ = len & 0377;
*data++ = (len >> 8) & 0377;
nia_data.snd_buff.len += 2;
}
/* Copy over rest of packet */ /* Copy over rest of packet */
if (cmd & (NIA_FLG_BSD << 8)) { if (cmd & (NIA_FLG_BSD << 8)) {
if (Mem_read_word(nia_data.cmd_entry + 9, &word1, 0)) { if (Mem_read_word(nia_data.cmd_entry + 9, &word1, 0)) {
@ -1175,7 +1181,7 @@ int nia_send_pkt(uint64 cmd)
if (((cmd & (NIA_FLG_PAD << 8)) != 0) && if (((cmd & (NIA_FLG_PAD << 8)) != 0) &&
nia_data.snd_buff.len < ETH_MIN_PACKET) { nia_data.snd_buff.len < ETH_MIN_PACKET) {
while (nia_data.snd_buff.len < ETH_MIN_PACKET) { while (nia_data.snd_buff.len < ETH_MIN_PACKET) {
*data = 0; *data++ = 0;
nia_data.snd_buff.len++; nia_data.snd_buff.len++;
} }
} }

View file

@ -489,8 +489,8 @@ struct df10 {
/* RH10/RH20 Interface */ /* RH10/RH20 Interface */
struct rh_if { struct rh_if {
void (*dev_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data); int (*dev_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
uint32 (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg); int (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 *data);
void (*dev_reset)(DEVICE *dptr); void (*dev_reset)(DEVICE *dptr);
t_uint64 buf; /* Data buffer */ t_uint64 buf; /* Data buffer */
uint32 status; /* DF10 status word */ uint32 status; /* DF10 status word */

View file

@ -117,7 +117,7 @@ extern uint64 SW; /* switch register */
* number of DPY_CYCLES to delay int * number of DPY_CYCLES to delay int
* too small and host CPU doesn't run enough! * too small and host CPU doesn't run enough!
*/ */
#define INT_COUNT (500/DPY_CYCLE_US) #define INT_COUNT (100/DPY_CYCLE_US)
#define STAT_REG u3 #define STAT_REG u3
#define INT_COUNTDOWN u4 #define INT_COUNTDOWN u4
@ -181,10 +181,23 @@ const char *dpy_description (DEVICE *dptr)
/* until it's done just one place! */ /* until it's done just one place! */
static void dpy_set_int_done(UNIT *uptr) static void dpy_set_int_done(UNIT *uptr)
{ {
uptr->STAT_REG |= CONI_INT_DONE;
uptr->INT_COUNTDOWN = INT_COUNT; uptr->INT_COUNTDOWN = INT_COUNT;
} }
/* update interrupt request */
static void check_interrupt (UNIT *uptr)
{
if (uptr->STAT_REG & CONI_INT_SPEC) {
uint32 sc = uptr->STAT_REG & CONX_SC;
set_interrupt(DPY_DEVNUM, sc >> CONX_SC_SHIFT);
} else if (uptr->STAT_REG & CONI_INT_DONE) {
uint32 dc = uptr->STAT_REG & CONX_DC;
set_interrupt(DPY_DEVNUM, dc>>CONX_DC_SHIFT);
} else {
clr_interrupt(DPY_DEVNUM);
}
}
/* return true if display not stopped */ /* return true if display not stopped */
int dpy_update_status (UNIT *uptr, ty340word status, int done) int dpy_update_status (UNIT *uptr, ty340word status, int done)
{ {
@ -199,12 +212,7 @@ int dpy_update_status (UNIT *uptr, ty340word status, int done)
/* XXX also set in "rfd" callback: decide! */ /* XXX also set in "rfd" callback: decide! */
dpy_set_int_done(uptr); dpy_set_int_done(uptr);
} }
if (uptr->STAT_REG & CONI_INT_SPEC) { check_interrupt(uptr);
uint32 sc = uptr->STAT_REG & CONX_SC;
if (sc) { /* PI channel set? */
set_interrupt(DPY_DEVNUM, sc >> CONX_SC_SHIFT);
}
}
return running; return running;
} }
@ -287,12 +295,8 @@ t_stat dpy_svc (UNIT *uptr)
display_age(DPY_CYCLE_US, 0); /* age the display */ display_age(DPY_CYCLE_US, 0); /* age the display */
if (uptr->INT_COUNTDOWN && --uptr->INT_COUNTDOWN == 0) { if (uptr->INT_COUNTDOWN && --uptr->INT_COUNTDOWN == 0) {
if (uptr->STAT_REG & CONI_INT_DONE) { /* delayed int? */ uptr->STAT_REG |= CONI_INT_DONE;
uint32 dc = uptr->STAT_REG & CONX_DC; check_interrupt (uptr);
if (dc) { /* PI channel set? */
set_interrupt(DPY_DEVNUM, dc>>CONX_DC_SHIFT);
}
}
} }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -24,6 +24,7 @@
#include "kx10_defs.h" #include "kx10_defs.h"
/* CONI Flags */ /* CONI Flags */
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */ #define IADR_ATTN 0000000000040LL /* Interrupt on attention */
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */ #define IARD_RAE 0000000000100LL /* Interrupt on register access error */
@ -182,6 +183,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
DEVICE *dptr = NULL; DEVICE *dptr = NULL;
struct rh_if *rhc = NULL; struct rh_if *rhc = NULL;
int drive; int drive;
uint32 drdat;
for (drive = 0; rh[drive].dev_num != 0; drive++) { for (drive = 0; rh[drive].dev_num != 0; drive++) {
if (rh[drive].dev_num == (dev & 0774)) { if (rh[drive].dev_num == (dev & 0774)) {
@ -220,8 +222,10 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
rhc->status &= ~(RH20_SBAR|RH20_SCR_FULL); rhc->status &= ~(RH20_SBAR|RH20_SCR_FULL);
if (*data & (RH20_RCLP|RH20_CLR_MBC)) if (*data & (RH20_RCLP|RH20_CLR_MBC))
rhc->cia = eb_ptr | (rhc->devnum - 0540); rhc->cia = eb_ptr | (rhc->devnum - 0540);
if (*data & (RH20_CLR_RAE|RH20_CLR_MBC)) if (*data & (RH20_CLR_RAE|RH20_CLR_MBC)) {
rhc->rae = 0; rhc->rae = 0;
}
rhc->status &= ~RH20_DR_RESP;
if (*data & PI_ENABLE) if (*data & PI_ENABLE)
rhc->status &= ~PI_ENABLE; rhc->status &= ~PI_ENABLE;
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0) if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
@ -239,7 +243,9 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
} }
if (rhc->reg < 040) { if (rhc->reg < 040) {
int parity; int parity;
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777); if (rhc->dev_read(dptr, rhc, rhc->reg, &drdat))
rhc->status |= RH20_DR_RESP;
*data = (uint64)(drdat & 0177777);
parity = (int)((*data >> 8) ^ *data); parity = (int)((*data >> 8) ^ *data);
parity = (parity >> 4) ^ parity; parity = (parity >> 4) ^ parity;
parity = (parity >> 2) ^ parity; parity = (parity >> 2) ^ parity;
@ -282,7 +288,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
set_interrupt(rhc->devnum, rhc->status); set_interrupt(rhc->devnum, rhc->status);
return SCPE_OK; return SCPE_OK;
} }
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777)); if (rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777)))
rhc->status |= RH20_DR_RESP;
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0) if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|| (rhc->status & PI_ENABLE)) || (rhc->status & PI_ENABLE))
set_interrupt(rhc->devnum, rhc->status); set_interrupt(rhc->devnum, rhc->status);
@ -293,7 +300,7 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
rhc->rae &= ~(1 << rhc->drive); rhc->rae &= ~(1 << rhc->drive);
} else if ((rhc->reg & 070) != 070) { } else if ((rhc->reg & 070) != 070) {
if ((*data & BIT9) == 0) { if ((*data & BIT9) == 0) {
rhc->rae = (1 << rhc->drive); rhc->rae |= 1 << rhc->drive;
set_interrupt(rhc->devnum, rhc->status); set_interrupt(rhc->devnum, rhc->status);
} }
} else { } else {
@ -329,8 +336,11 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
*data = rhc->status & ~(IADR_ATTN|IARD_RAE); *data = rhc->status & ~(IADR_ATTN|IARD_RAE);
if (rhc->attn != 0 && (rhc->status & IADR_ATTN)) if (rhc->attn != 0 && (rhc->status & IADR_ATTN))
*data |= IADR_ATTN; *data |= IADR_ATTN;
if (rhc->rae != 0 && (rhc->status & IARD_RAE)) if (rhc->rae != 0 && (rhc->status & IARD_RAE)) {
*data |= IARD_RAE; *data |= IARD_RAE;
if (rhc->rae & (1 << rhc->drive))
*data |= CXR_SD_RAE;
}
#if KI_22BIT #if KI_22BIT
*data |= B22_FLAG; *data |= B22_FLAG;
#endif #endif
@ -343,8 +353,10 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
rhc->status &= ~(07LL|IADR_ATTN|IARD_RAE); rhc->status &= ~(07LL|IADR_ATTN|IARD_RAE);
rhc->status |= *data & (07LL|IADR_ATTN|IARD_RAE); rhc->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
/* Clear flags */ /* Clear flags */
if (*data & CONT_RESET && rhc->dev_reset != NULL) if (*data & CONT_RESET && rhc->dev_reset != NULL) {
rhc->dev_reset(dptr); rhc->dev_reset(dptr);
rhc->status &= (07LL|IADR_ATTN|IARD_RAE);
}
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)) if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
rhc->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)); rhc->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
if (*data & OVER_CLR) if (*data & OVER_CLR)
@ -353,6 +365,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
rhc->status &= ~(DIB_CBOV); rhc->status &= ~(DIB_CBOV);
if (*data & CXR_ILC) if (*data & CXR_ILC)
rhc->status &= ~(CXR_ILFC|CXR_SD_RAE); rhc->status &= ~(CXR_ILFC|CXR_SD_RAE);
if (*data & DRE_CLR)
rhc->status &= ~(CR_DRE);
if (*data & WRT_CW) if (*data & WRT_CW)
rh_writecw(rhc, 0); rh_writecw(rhc, 0);
if (*data & PI_ENABLE) if (*data & PI_ENABLE)
@ -372,7 +386,9 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
return SCPE_OK; return SCPE_OK;
} }
if (rhc->reg == 040) { if (rhc->reg == 040) {
*data = (uint64)(rhc->dev_read(dptr, rhc, 0) & 077); if (rhc->dev_read(dptr, rhc, 0, &drdat))
rhc->status |= CR_DRE;
*data = (uint64)(drdat & 077);
*data |= ((uint64)(rhc->cia)) << 6; *data |= ((uint64)(rhc->cia)) << 6;
*data |= ((uint64)(rhc->xfer_drive)) << 18; *data |= ((uint64)(rhc->xfer_drive)) << 18;
} else if (rhc->reg == 044) { } else if (rhc->reg == 044) {
@ -385,7 +401,11 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
*data = (uint64)(rhc->rae); *data = (uint64)(rhc->rae);
} else if ((rhc->reg & 040) == 0) { } else if ((rhc->reg & 040) == 0) {
int parity; int parity;
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777); if (rhc->dev_read(dptr, rhc, rhc->reg, &drdat)) {
rhc->rae |= 1 << rhc->drive;
rhc->status |= CR_DRE;
}
*data = (uint64)(drdat & 0177777);
parity = (int)((*data >> 8) ^ *data); parity = (int)((*data >> 8) ^ *data);
parity = (parity >> 4) ^ parity; parity = (parity >> 4) ^ parity;
parity = (parity >> 2) ^ parity; parity = (parity >> 2) ^ parity;
@ -432,7 +452,9 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
/* Start command */ /* Start command */
rh_setup(rhc, (uint32)(*data >> 6)); rh_setup(rhc, (uint32)(*data >> 6));
rhc->xfer_drive = (int)(*data >> 18) & 07; rhc->xfer_drive = (int)(*data >> 18) & 07;
rhc->dev_write(dptr, rhc, 0, (uint32)(*data & 077)); if (rhc->dev_write(dptr, rhc, 0, (uint32)(*data & 077))) {
rhc->status |= CR_DRE;
}
sim_debug(DEBUG_DATAIO, dptr, sim_debug(DEBUG_DATAIO, dptr,
"%s %03o command %012llo, %d PC=%06o %06o\n", "%s %03o command %012llo, %d PC=%06o %06o\n",
dptr->name, dev, *data, rhc->drive, PC, rhc->status); dptr->name, dev, *data, rhc->drive, PC, rhc->status);
@ -453,7 +475,8 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
if (rhc->rae & (1 << rhc->drive)) { if (rhc->rae & (1 << rhc->drive)) {
return SCPE_OK; return SCPE_OK;
} }
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777)); if (rhc->dev_write(dptr, rhc, rhc->reg & 037, (uint32)(*data & 0777777)))
rhc->status |= CR_DRE;
} }
} }
clr_interrupt(dev); clr_interrupt(dev);
@ -506,7 +529,6 @@ int rh_blkend(struct rh_if *rhc)
{ {
#if KL #if KL
if (rhc->imode == 2) { if (rhc->imode == 2) {
//fprintf(stderr, "RH blkend %o\n\r", rhc->cia);
rhc->cia = (rhc->cia + 1) & 01777; rhc->cia = (rhc->cia + 1) & 01777;
if (rhc->cia == 0) { if (rhc->cia == 0) {
rhc->status |= RH20_XEND; rhc->status |= RH20_XEND;
@ -564,7 +586,6 @@ void rh_writecw(struct rh_if *rhc, int nxm) {
((uint64)(rhc->cda) & AMASK); ((uint64)(rhc->cda) & AMASK);
(void)Mem_write_word(chan+1, &wrd1, 1); (void)Mem_write_word(chan+1, &wrd1, 1);
(void)Mem_write_word(chan+2, &wrd2, 1); (void)Mem_write_word(chan+2, &wrd2, 1);
//fprintf(stderr, "RH20 final %012llo %012llo %06o\n\r", wrd1, wrd2, wc);
} }
return; return;
} }
@ -619,7 +640,7 @@ void rh20_setup(struct rh_if *rhc)
if (rhc->status & RH20_SBAR) { if (rhc->status & RH20_SBAR) {
rhc->drive = (rhc->pbar >> 18) & 07; rhc->drive = (rhc->pbar >> 18) & 07;
if (rhc->dev_write != NULL) if (rhc->dev_write != NULL)
rhc->dev_write(dptr, rhc, 5, (rhc->pbar & 0177777)); (void)rhc->dev_write(dptr, rhc, 5, (rhc->pbar & 0177777));
rhc->status &= ~RH20_SBAR; rhc->status &= ~RH20_SBAR;
} }
if (rhc->ptcr & BIT7) { /* If RCPL reset I/O pointers */ if (rhc->ptcr & BIT7) { /* If RCPL reset I/O pointers */
@ -630,11 +651,10 @@ void rh20_setup(struct rh_if *rhc)
rhc->drive = (rhc->ptcr >> 18) & 07; rhc->drive = (rhc->ptcr >> 18) & 07;
rhc->cia = (rhc->ptcr >> 6) & 01777; rhc->cia = (rhc->ptcr >> 6) & 01777;
if (rhc->dev_write != NULL) if (rhc->dev_write != NULL)
rhc->dev_write(dptr, rhc, 0, (rhc->ptcr & 077)); (void)rhc->dev_write(dptr, rhc, 0, (rhc->ptcr & 077));
rhc->cop = 0; rhc->cop = 0;
rhc->wcr = 0; rhc->wcr = 0;
rhc->status &= ~RH20_CHAN_RDY; rhc->status &= ~RH20_CHAN_RDY;
//fprintf(stderr, "RH setup %06o %06o %o\n\r", rhc->ptcr, rhc->ccw, rhc->cia);
} }
#endif #endif

View file

@ -224,8 +224,8 @@ struct drvtyp rp_drv_tab[] = {
t_stat rp_devio(uint32 dev, uint64 *data); t_stat rp_devio(uint32 dev, uint64 *data);
int rp_devirq(uint32 dev, int addr); int rp_devirq(uint32 dev, int addr);
void rp_write(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data); int rp_write(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
uint32 rp_read(DEVICE *dptr, struct rh_if *rh, int reg); int rp_read(DEVICE *dptr, struct rh_if *rh, int reg, uint32 *data);
void rp_rst(DEVICE *dptr); void rp_rst(DEVICE *dptr);
t_stat rp_svc(UNIT *); t_stat rp_svc(UNIT *);
t_stat rp_boot(int32, DEVICE *); t_stat rp_boot(int32, DEVICE *);
@ -490,16 +490,18 @@ rp_rst(DEVICE *dptr)
} }
} }
void int
rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) { rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
int i; int i;
int unit = rhc->drive; int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
int dtype = GET_DTYPE(uptr->flags); int dtype = GET_DTYPE(uptr->flags);
if ((uptr->flags & UNIT_DIS) != 0 && reg != 04)
return 1;
if ((uptr->CMD & CS1_GO) && reg != 04) { if ((uptr->CMD & CS1_GO) && reg != 04) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR; uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
return; return 0;
} }
switch(reg) { switch(reg) {
case 000: /* control */ case 000: /* control */
@ -511,14 +513,14 @@ rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if ((uptr->CMD & DS_DRY) == 0) { if ((uptr->CMD & DS_DRY) == 0) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR; uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "%s%o not ready\n", dptr->name, unit); sim_debug(DEBUG_DETAIL, dptr, "%s%o not ready\n", dptr->name, unit);
return; return 0;
} }
/* Check if GO bit set */ /* Check if GO bit set */
if ((data & 1) == 0) { if ((data & 1) == 0) {
uptr->CMD &= ~076; uptr->CMD &= ~076;
uptr->CMD |= data & 076; uptr->CMD |= data & 076;
sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit); sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit);
return; /* No, nop */ return 0; /* No, nop */
} }
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->CMD |= data & 076; uptr->CMD |= data & 076;
@ -592,7 +594,7 @@ rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if (uptr->CMD & CS1_GO) if (uptr->CMD & CS1_GO)
sim_activate(uptr, 1000); sim_activate(uptr, 1000);
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD); sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
return; return 0;
case 001: /* status */ case 001: /* status */
break; break;
case 002: /* error register 1 */ case 002: /* error register 1 */
@ -649,16 +651,20 @@ rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
uptr->CMD |= (ER1_ILR<<16)|DS_ERR; uptr->CMD |= (ER1_ILR<<16)|DS_ERR;
rhc->rae |= 1 << unit; rhc->rae |= 1 << unit;
} }
return 0;
} }
uint32 int
rp_read(DEVICE *dptr, struct rh_if *rhc, int reg) { rp_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int unit = rhc->drive; int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
uint32 temp = 0; uint32 temp = 0;
int i; int i;
if ((uptr->flags & UNIT_DIS) != 0 && reg != 04)
return 1;
if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */ if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */
*data = 0;
return 0; return 0;
} }
switch(reg) { switch(reg) {
@ -722,7 +728,8 @@ rp_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
uptr->CMD |= (ER1_ILR<<16); uptr->CMD |= (ER1_ILR<<16);
rhc->rae |= 1 << unit; rhc->rae |= 1 << unit;
} }
return temp; *data = temp;
return 0;
} }

View file

@ -173,8 +173,8 @@ struct drvtyp rs_drv_tab[] = {
uint64 rs_buf[NUM_DEVS_RS][RS_NUMWD]; uint64 rs_buf[NUM_DEVS_RS][RS_NUMWD];
void rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data); int rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
uint32 rs_read(DEVICE *dptr, struct rh_if *rhc, int reg); int rs_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data);
void rs_rst(DEVICE *dptr); void rs_rst(DEVICE *dptr);
t_stat rs_svc(UNIT *); t_stat rs_svc(UNIT *);
t_stat rs_boot(int32, DEVICE *); t_stat rs_boot(int32, DEVICE *);
@ -273,15 +273,17 @@ rs_rst(DEVICE *dptr)
} }
} }
void int
rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) { rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
int i; int i;
int unit = rhc->drive; int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
if ((uptr->flags & UNIT_DIS) != 0)
return 1;
if ((uptr->CMD & CS1_GO) && reg != 04) { if ((uptr->CMD & CS1_GO) && reg != 04) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR; uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
return; return 0;
} }
switch(reg) { switch(reg) {
case 000: /* control */ case 000: /* control */
@ -293,14 +295,14 @@ rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if ((uptr->CMD & DS_DRY) == 0) { if ((uptr->CMD & DS_DRY) == 0) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR; uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "%s%o busy\n", dptr->name, unit); sim_debug(DEBUG_DETAIL, dptr, "%s%o busy\n", dptr->name, unit);
return; return 0;
} }
/* Check if GO bit set */ /* Check if GO bit set */
if ((data & 1) == 0) { if ((data & 1) == 0) {
uptr->CMD &= ~076; uptr->CMD &= ~076;
uptr->CMD |= data & 076; uptr->CMD |= data & 076;
sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit); sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit);
return; /* No, nop */ return 0; /* No, nop */
} }
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->CMD |= data & 076; uptr->CMD |= data & 076;
@ -343,7 +345,7 @@ rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if (uptr->CMD & CS1_GO) if (uptr->CMD & CS1_GO)
sim_activate(uptr, 100); sim_activate(uptr, 100);
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD); sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
return; return 0;
case 001: /* status */ case 001: /* status */
break; break;
case 002: /* error register 1 */ case 002: /* error register 1 */
@ -373,16 +375,20 @@ rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
uptr->CMD |= (ER1_ILR<<16)|DS_ERR; uptr->CMD |= (ER1_ILR<<16)|DS_ERR;
rhc->rae |= 1 << unit; rhc->rae |= 1 << unit;
} }
return 0;
} }
uint32 int
rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) { rs_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int unit = rhc->drive; int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
uint32 temp = 0; uint32 temp = 0;
int i; int i;
if ((uptr->flags & UNIT_DIS) != 0)
return 1;
if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */ if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */
*data = 0;
return 0; return 0;
} }
@ -420,7 +426,8 @@ rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
uptr->CMD |= (ER1_ILR<<16); uptr->CMD |= (ER1_ILR<<16);
rhc->rae |= 1 << unit; rhc->rae |= 1 << unit;
} }
return temp; *data = temp;
return 0;
} }

View file

@ -161,8 +161,8 @@ uint16 tu_frame[NUM_DEVS_TU];
uint16 tu_tcr[NUM_DEVS_TU]; uint16 tu_tcr[NUM_DEVS_TU];
static uint64 tu_boot_buffer; static uint64 tu_boot_buffer;
void tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data); int tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
uint32 tu_read(DEVICE *dptr, struct rh_if *rhc, int reg); int tu_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data);
void tu_rst(DEVICE *dptr); void tu_rst(DEVICE *dptr);
t_stat tu_srv(UNIT *); t_stat tu_srv(UNIT *);
t_stat tu_boot(int32, DEVICE *); t_stat tu_boot(int32, DEVICE *);
@ -247,19 +247,19 @@ DEVICE *tu_devs[] = {
&tua_dev, &tua_dev,
}; };
void int
tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) { tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
int ctlr = GET_CNTRL_RH(dptr->units[0].flags); int ctlr = GET_CNTRL_RH(dptr->units[0].flags);
int unit = tu_tcr[ctlr] & 07; int unit = tu_tcr[ctlr] & 07;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
int i; int i;
if (rhc->drive != 0) /* Only one unit at 0 */ if (rhc->drive != 0 && reg != 04) /* Only one unit at 0 */
return; return 1;
if (uptr->CMD & CS1_GO) { if (uptr->CMD & CS1_GO) {
uptr->STATUS |= (ER1_RMR); uptr->STATUS |= (ER1_RMR);
return; return 0;
} }
switch(reg) { switch(reg) {
@ -323,7 +323,7 @@ tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit,
uptr->CMD); uptr->CMD);
} }
return; return 0;
case 001: /* status */ case 001: /* status */
break; break;
case 002: /* error register 1 */ case 002: /* error register 1 */
@ -334,11 +334,9 @@ tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
break; break;
case 004: /* atten summary */ case 004: /* atten summary */
rhc->attn = 0; rhc->attn = 0;
for (i = 0; i < 8; i++) { if (data & 1) {
if (data & (1<<i)) for (i = 0; i < 8; i++)
dptr->units[i].CMD &= ~CS_ATA; dptr->units[i].CMD &= ~CS_ATA;
if (dptr->units[i].CMD & CS_ATA)
rhc->attn = 1;
} }
break; break;
case 005: /* frame count */ case 005: /* frame count */
@ -356,23 +354,23 @@ tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
rhc->attn = 1; rhc->attn = 1;
rhc->rae = 1; rhc->rae = 1;
} }
return 0;
} }
uint32 int
tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) { tu_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int ctlr = GET_CNTRL_RH(dptr->units[0].flags); int ctlr = GET_CNTRL_RH(dptr->units[0].flags);
int unit = tu_tcr[ctlr] & 07; int unit = tu_tcr[ctlr] & 07;
UNIT *uptr = &dptr->units[unit]; UNIT *uptr = &dptr->units[unit];
uint32 temp = 0; uint32 temp = 0;
int i; int i;
if (rhc->drive != 0) /* Only one unit at 0 */ if (rhc->drive != 0 && reg != 4) /* Only one unit at 0 */
return 0; return 1;
switch(reg) { switch(reg) {
case 000: /* control */ case 000: /* control */
temp = uptr->CMD & 076; temp = uptr->CMD & 076;
if (uptr->flags & UNIT_ATT)
temp |= CS1_DVA; temp |= CS1_DVA;
if (uptr->CMD & CS1_GO) if (uptr->CMD & CS1_GO)
temp |= CS1_GO; temp |= CS1_GO;
@ -408,15 +406,15 @@ tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
break; break;
case 004: /* atten summary */ case 004: /* atten summary */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (dptr->units[i].CMD & CS_ATA) { if (dptr->units[i].CMD & CS_ATA)
temp |= 1 << i; temp |= 1;
}
} }
break; break;
case 005: /* frame count */ case 005: /* frame count */
temp = tu_frame[ctlr]; temp = tu_frame[ctlr];
break; break;
case 006: /* drive type */ case 006: /* drive type */
if ((uptr->flags & UNIT_DIS) == 0)
temp = 042054; temp = 042054;
break; break;
case 011: /* tape control register */ case 011: /* tape control register */
@ -434,7 +432,8 @@ tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
rhc->attn = 1; rhc->attn = 1;
rhc->rae = 1; rhc->rae = 1;
} }
return temp; *data = temp;
return 0;
} }