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));
/* Set packet length */
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 */
if (cmd & (NIA_FLG_BSD << 8)) {
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) &&
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++;
}
}

View file

@ -489,8 +489,8 @@ struct df10 {
/* RH10/RH20 Interface */
struct rh_if {
void (*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_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
int (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 *data);
void (*dev_reset)(DEVICE *dptr);
t_uint64 buf; /* Data buffer */
uint32 status; /* DF10 status word */

View file

@ -117,7 +117,7 @@ extern uint64 SW; /* switch register */
* number of DPY_CYCLES to delay int
* 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 INT_COUNTDOWN u4
@ -181,10 +181,23 @@ const char *dpy_description (DEVICE *dptr)
/* until it's done just one place! */
static void dpy_set_int_done(UNIT *uptr)
{
uptr->STAT_REG |= CONI_INT_DONE;
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 */
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! */
dpy_set_int_done(uptr);
}
if (uptr->STAT_REG & CONI_INT_SPEC) {
uint32 sc = uptr->STAT_REG & CONX_SC;
if (sc) { /* PI channel set? */
set_interrupt(DPY_DEVNUM, sc >> CONX_SC_SHIFT);
}
}
check_interrupt(uptr);
return running;
}
@ -287,12 +295,8 @@ t_stat dpy_svc (UNIT *uptr)
display_age(DPY_CYCLE_US, 0); /* age the display */
if (uptr->INT_COUNTDOWN && --uptr->INT_COUNTDOWN == 0) {
if (uptr->STAT_REG & CONI_INT_DONE) { /* delayed int? */
uint32 dc = uptr->STAT_REG & CONX_DC;
if (dc) { /* PI channel set? */
set_interrupt(DPY_DEVNUM, dc>>CONX_DC_SHIFT);
}
}
uptr->STAT_REG |= CONI_INT_DONE;
check_interrupt (uptr);
}
return SCPE_OK;
}

View file

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

View file

@ -224,8 +224,8 @@ struct drvtyp rp_drv_tab[] = {
t_stat rp_devio(uint32 dev, uint64 *data);
int rp_devirq(uint32 dev, int addr);
void 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_write(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
int rp_read(DEVICE *dptr, struct rh_if *rh, int reg, uint32 *data);
void rp_rst(DEVICE *dptr);
t_stat rp_svc(UNIT *);
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) {
int i;
int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit];
int dtype = GET_DTYPE(uptr->flags);
if ((uptr->flags & UNIT_DIS) != 0 && reg != 04)
return 1;
if ((uptr->CMD & CS1_GO) && reg != 04) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
return;
return 0;
}
switch(reg) {
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) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "%s%o not ready\n", dptr->name, unit);
return;
return 0;
}
/* Check if GO bit set */
if ((data & 1) == 0) {
uptr->CMD &= ~076;
uptr->CMD |= data & 076;
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 |= data & 076;
@ -592,7 +594,7 @@ rp_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if (uptr->CMD & CS1_GO)
sim_activate(uptr, 1000);
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
return;
return 0;
case 001: /* status */
break;
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;
rhc->rae |= 1 << unit;
}
return 0;
}
uint32
rp_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
int
rp_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit];
uint32 temp = 0;
int i;
if ((uptr->flags & UNIT_DIS) != 0 && reg != 04)
return 1;
if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */
*data = 0;
return 0;
}
switch(reg) {
@ -722,7 +728,8 @@ rp_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
uptr->CMD |= (ER1_ILR<<16);
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];
void 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_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
int rs_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data);
void rs_rst(DEVICE *dptr);
t_stat rs_svc(UNIT *);
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) {
int i;
int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit];
if ((uptr->flags & UNIT_DIS) != 0)
return 1;
if ((uptr->CMD & CS1_GO) && reg != 04) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
return;
return 0;
}
switch(reg) {
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) {
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "%s%o busy\n", dptr->name, unit);
return;
return 0;
}
/* Check if GO bit set */
if ((data & 1) == 0) {
uptr->CMD &= ~076;
uptr->CMD |= data & 076;
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 |= data & 076;
@ -343,7 +345,7 @@ rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
if (uptr->CMD & CS1_GO)
sim_activate(uptr, 100);
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
return;
return 0;
case 001: /* status */
break;
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;
rhc->rae |= 1 << unit;
}
return 0;
}
uint32
rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
int
rs_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int unit = rhc->drive;
UNIT *uptr = &dptr->units[unit];
uint32 temp = 0;
int i;
if ((uptr->flags & UNIT_DIS) != 0)
return 1;
if ((uptr->flags & UNIT_ATT) == 0 && reg != 04) { /* not attached? */
*data = 0;
return 0;
}
@ -420,7 +426,8 @@ rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
uptr->CMD |= (ER1_ILR<<16);
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];
static uint64 tu_boot_buffer;
void 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_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
int tu_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data);
void tu_rst(DEVICE *dptr);
t_stat tu_srv(UNIT *);
t_stat tu_boot(int32, DEVICE *);
@ -247,19 +247,19 @@ DEVICE *tu_devs[] = {
&tua_dev,
};
void
int
tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
int ctlr = GET_CNTRL_RH(dptr->units[0].flags);
int unit = tu_tcr[ctlr] & 07;
UNIT *uptr = &dptr->units[unit];
int i;
if (rhc->drive != 0) /* Only one unit at 0 */
return;
if (rhc->drive != 0 && reg != 04) /* Only one unit at 0 */
return 1;
if (uptr->CMD & CS1_GO) {
uptr->STATUS |= (ER1_RMR);
return;
return 0;
}
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,
uptr->CMD);
}
return;
return 0;
case 001: /* status */
break;
case 002: /* error register 1 */
@ -334,11 +334,9 @@ tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
break;
case 004: /* atten summary */
rhc->attn = 0;
for (i = 0; i < 8; i++) {
if (data & (1<<i))
if (data & 1) {
for (i = 0; i < 8; i++)
dptr->units[i].CMD &= ~CS_ATA;
if (dptr->units[i].CMD & CS_ATA)
rhc->attn = 1;
}
break;
case 005: /* frame count */
@ -356,24 +354,24 @@ tu_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
rhc->attn = 1;
rhc->rae = 1;
}
return 0;
}
uint32
tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
int
tu_read(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 *data) {
int ctlr = GET_CNTRL_RH(dptr->units[0].flags);
int unit = tu_tcr[ctlr] & 07;
UNIT *uptr = &dptr->units[unit];
uint32 temp = 0;
int i;
if (rhc->drive != 0) /* Only one unit at 0 */
return 0;
if (rhc->drive != 0 && reg != 4) /* Only one unit at 0 */
return 1;
switch(reg) {
case 000: /* control */
temp = uptr->CMD & 076;
if (uptr->flags & UNIT_ATT)
temp |= CS1_DVA;
temp |= CS1_DVA;
if (uptr->CMD & CS1_GO)
temp |= CS1_GO;
break;
@ -408,16 +406,16 @@ tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
break;
case 004: /* atten summary */
for (i = 0; i < 8; i++) {
if (dptr->units[i].CMD & CS_ATA) {
temp |= 1 << i;
}
if (dptr->units[i].CMD & CS_ATA)
temp |= 1;
}
break;
case 005: /* frame count */
temp = tu_frame[ctlr];
break;
case 006: /* drive type */
temp = 042054;
if ((uptr->flags & UNIT_DIS) == 0)
temp = 042054;
break;
case 011: /* tape control register */
temp = tu_tcr[ctlr];
@ -434,7 +432,8 @@ tu_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
rhc->attn = 1;
rhc->rae = 1;
}
return temp;
*data = temp;
return 0;
}