1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-04-03 12:22:52 +00:00

KA10: KS10 now will run Tops 10 7.03. Still has stablity issues.

This commit is contained in:
Richard Cornwell
2021-02-11 23:06:54 -05:00
parent 793c4cd8f0
commit 288e6adb90
6 changed files with 379 additions and 177 deletions

View File

@@ -96,8 +96,8 @@ MTAB cty_mod[] = {
};
UNIT cty_unit[] = {
{ UDATA (&ctyo_svc, TT_MODE_7B, 0), 500},
{ UDATA (&ctyi_svc, TT_MODE_7B|UNIT_DIS, 0), 1000 },
{ UDATA (&ctyo_svc, TT_MODE_7B, 0), 2000},
{ UDATA (&ctyi_svc, TT_MODE_7B|UNIT_DIS, 0), 2000 },
{ UDATA (&ctyrtc_srv, UNIT_IDLE|UNIT_DIS, 0), 1000 }
};
@@ -121,6 +121,7 @@ void
cty_wakeup()
{
sim_debug(DEBUG_EXP, &cty_dev, "CTY wakeup\n");
sim_cancel(&cty_unit[0]);
sim_activate(&cty_unit[0], cty_unit[0].wait);
}
@@ -186,7 +187,16 @@ t_stat ctyo_svc (UNIT *uptr)
cty_interrupt();
}
} else {
sim_activate(uptr, uptr->wait);
sim_activate(uptr, tmxr_poll);
}
}
if (Mem_read_word(KLINK_OUT, &buffer, 0))
return SCPE_OK;
if (buffer != 0) {
buffer = 0;
if (Mem_write_word(CTY_OUT, &buffer, 0) == 0) {
cty_interrupt();
}
}
@@ -195,7 +205,7 @@ t_stat ctyo_svc (UNIT *uptr)
char ch = cty_out.buff[cty_out.out_ptr];
if (ch != 0) {
if (sim_putchar_s(ch) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
sim_activate(uptr, tmxr_poll);
return SCPE_OK;
}
}

View File

@@ -80,6 +80,8 @@
#define CS1_TRE 0040000 /* Set if CS2 0177400 */
#define CS1_SC 0100000 /* Set if TRE or ATTN */
#define CSX_BUSY 02 /* RH11 is doing a transfer */
/* RPWC - 176702 - word count */
@@ -262,6 +264,8 @@ struct drvtyp rp_drv_tab[] = {
int rp_write(t_addr addr, uint16 data, int32 access);
int rp_read(t_addr addr, uint16 *data, int32 access);
uint16 rp_vect(struct pdp_dib *dibp);
t_stat rp_svc(UNIT *);
t_stat rp_boot(int32, DEVICE *);
void rp_ini(UNIT *, t_bool);
@@ -300,7 +304,7 @@ UNIT rpa_unit[] = {
UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) },
};
DIB rpa_dib = {0776700, 077, 0254, 6, 1, &rp_read, &rp_write, 0};
DIB rpa_dib = {0776700, 077, 0254, 6, 1, &rp_read, &rp_write, &rp_vect, 0};
MTAB rp_mod[] = {
@@ -345,23 +349,22 @@ rp_write(t_addr addr, uint16 data, int32 access) {
UNIT *uptr = &rpa_unit[rp_unit];
int dtype = GET_DTYPE(uptr->flags);
/* If drive not ready don't do anything */
if ((rp_ie & CS1_GO) != 0|| (uptr->STATUS & DS_PIP) != 0) {
uptr->CMD |= (ER1_RMR << 16);
// rp_cs2 |= CS2_PGE;
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready\n", rp_unit);
return 0;
}
switch(addr & 076) {
/* u3 low */
case 000: /* RPC - 176700 - control */
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o Status=%06o\n", rp_unit, uptr->CMD);
if (access == BYTE && addr & 1)
break;
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o Status=%06o\n", rp_unit, uptr->CMD);
rp_ie &= ~(CS1_IE);
rp_ie |= data & (CS1_IE);
if ((uptr->CMD & CS1_GO) != 0) {
uptr->CMD |= (ER1_RMR << 16);
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
addr & 077, data);
return 0;
}
rp_ba = ((data << 8) & 0600000) | (rp_ba & 0177777);
rp_ie = data & (CS1_IE);
uptr->CMD = data & 076;
/* Check if GO bit set */
if ((data & 1) == 0) {
@@ -372,6 +375,7 @@ rp_write(t_addr addr, uint16 data, int32 access) {
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o unattached %06o\n", rp_unit, data);
return 0; /* No, nop */
}
uba_clr_irq(&rpa_dib);
switch (GET_FNC(data)) {
case FNC_NOP:
break;
@@ -403,27 +407,28 @@ rp_write(t_addr addr, uint16 data, int32 access) {
break;
}
rp_ie |= CS1_GO;
if (GET_FNC(data) >= FNC_XFER)
rp_ie |= CSX_BUSY;
uptr->CMD |= CS1_GO;
CLR_BUF(uptr);
uptr->DATAPTR = 0;
break;
case FNC_DCLR: /* drive clear */
uptr->STATUS &= ~(DS_ATA);
rp_ie &= ~(CS1_GO);
uptr->STATUS &= DS_VV;
uptr->DA &= 003400177777;
uptr->CCYL &= 0177777;
rp_ie = 0;
break;
case FNC_PRESET: /* read-in preset */
uptr->DA = 0;
uptr->CCYL &= 0177777;
/* Fall through */
case FNC_RELEASE: /* port release */
case FNC_PACK: /* pack acknowledge */
uptr->STATUS |= DS_VV;
/* Fall through */
case FNC_RELEASE: /* port release */
break;
default:
@@ -431,12 +436,18 @@ rp_write(t_addr addr, uint16 data, int32 access) {
uptr->CMD |= (ER1_ILF << 16);
}
if (GET_FNC(data) >= FNC_XFER)
uptr->STATUS = 0;
if (rp_ie & CS1_GO)
uptr->STATUS &= (DS_VV);
if (uptr->CMD & CS1_GO)
sim_activate(uptr, 1000);
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o AStatus=%06o\n", rp_unit, uptr->CMD);
break;
case 002: /* RPWC - 176702 - word count */
if ((rp_ie & (CSX_BUSY)) != 0) {
uptr->CMD |= (ER1_RMR << 16);
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
addr & 077, data);
return 0;
}
if (access == BYTE) {
if (addr & 1)
data = data | (rp_wc & 0377);
@@ -446,6 +457,12 @@ rp_write(t_addr addr, uint16 data, int32 access) {
rp_wc = data;
break;
case 004: /* RPBA - 176704 - base address */
if ((rp_ie & (CSX_BUSY)) != 0) {
uptr->CMD |= (ER1_RMR << 16);
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
addr & 077, data);
return 0;
}
if (access == BYTE) {
if (addr & 1)
data = data | (rp_ba & 0377);
@@ -466,6 +483,12 @@ rp_write(t_addr addr, uint16 data, int32 access) {
break;
case 010: /* RPCS2 - 176710 - Control and Status register 2 */
// if ((rp_ie & (CSX_BUSY)) != 0) {
// uptr->CMD |= (ER1_RMR << 16);
// sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
// addr & 077, data);
// return 0;
// }
if (access == BYTE) {
if (addr & 1)
data = data | (rp_cs2 & 0377);
@@ -549,13 +572,21 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
/* RPDB - 176722 - data buffer */
switch(addr & 076) {
case 000: /* RPC - 176700 - control */
temp = uptr->CMD & 076;
temp |= (uint16)rp_ie;
temp = uptr->CMD & 077;
temp |= (uint16)(rp_ie & (CS1_IE));
temp |= (rp_ba & 0600000) >> 8;
if ((rp_ie & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
if ((rp_ie & CSX_BUSY) == 0)
temp |= CS1_RDY;
if (uptr->flags & UNIT_ATT) {
if (uptr->flags & UNIT_ATT)
temp |= CS1_DVA;
if (rp_cs2 & (CS2_MDPE|CS2_MXF|CS2_PGE|CS2_NEM|CS2_NED|CS2_PE|CS2_WCE|CS2_DLT))
temp |= CS1_TRE|CS1_SC;
for (i = 0; i < 8; i++) {
UNIT *u = &rpa_unit[i];
if (u->STATUS & DS_ATA) {
temp |= CS1_SC;
break;
}
}
break;
case 002: /* RPWC - 176702 - word count */
@@ -579,10 +610,10 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
if ((uptr->flags & UNIT_DIS) == 0)
temp |= DS_DPR;
if ((uptr->flags & UNIT_ATT) != 0)
temp |= DS_VV|DS_MOL;
temp |= DS_MOL;
if ((uptr->flags & UNIT_WLK) != 0)
temp |= DS_WRL;
if ((rp_ie & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
if ((uptr->CMD & CS1_GO) == 0)
temp |= DS_DRY;
break;
case 014: /* RPER1 - 176714 - error status 1 */
@@ -639,11 +670,19 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
return 0;
}
uint16
rp_vect(struct pdp_dib *dibp)
{
rp_ie &= ~CS1_IE;
return dibp->uba_vect;
}
/* Set the attention flag for a unit */
void rp_setattn(int unit)
void rp_setattn(UNIT *uptr)
{
if (rp_ie)
uptr->STATUS |= DS_ATA;
uptr->CMD &= ~CS1_GO;
if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0)
uba_set_irq(&rpa_dib);
}
@@ -664,12 +703,13 @@ t_stat rp_svc (UNIT *uptr)
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
uptr->CMD |= (ER1_UNS << 16); /* set drive error */
uptr->STATUS |= DS_ATA;
rp_ie &= ~(CS1_GO);
rp_ie &= ~(CSX_BUSY);
uptr->CMD &= ~CS1_GO;
if (GET_FNC(uptr->CMD) >= FNC_XFER) { /* xfr? set done */
if (rp_ie)
if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0)
uba_set_irq(&rpa_dib);
} else {
rp_setattn(unit);
rp_setattn(uptr);
}
return (SCPE_OK);
}
@@ -679,10 +719,10 @@ t_stat rp_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, "%s%o seek %d %d\n", dptr->name, unit, cyl, uptr->CCYL);
if (cyl >= rp_drv_tab[dtype].cyl) {
uptr->STATUS &= ~DS_PIP;
uptr->STATUS |= DS_ATA;
// uptr->STATUS |= DS_ATA;
uptr->CMD |= (ER1_IAE << 16);
rp_ie &= ~CS1_GO;
rp_setattn(unit);
// uptr->CMD &= ~CS1_GO;
rp_setattn(uptr);
}
diff = cyl - (uptr->CCYL & 01777);
if (diff < 0) {
@@ -733,9 +773,7 @@ t_stat rp_svc (UNIT *uptr)
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
uptr->CMD |= (ER1_IAE << 16);
uptr->STATUS |= DS_ATA;
rp_ie &= ~CS1_GO;
rp_setattn(unit);
rp_setattn(uptr);
sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
break;
@@ -743,9 +781,7 @@ t_stat rp_svc (UNIT *uptr)
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
uptr->CMD |= (ER1_IAE << 16);
uptr->STATUS |= DS_ATA;
rp_ie &= ~CS1_GO;
rp_setattn(unit);
rp_setattn( uptr);
sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
break;
@@ -757,8 +793,9 @@ t_stat rp_svc (UNIT *uptr)
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
uptr->CMD |= (ER1_IAE << 16);
uptr->STATUS |= DS_ATA;
rp_ie &= ~CS1_GO;
if (uptr->CMD & CS1_IE)
rp_ie &= ~(CSX_BUSY);
uptr->CMD &= ~CS1_GO;
if (rp_ie & CS1_IE)
uba_set_irq(&rpa_dib);
sim_debug(DEBUG_DETAIL, dptr, "%s%o readx done\n", dptr->name, unit);
return SCPE_OK;
@@ -832,8 +869,9 @@ t_stat rp_svc (UNIT *uptr)
}
rd_end:
sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit);
rp_ie &= ~CS1_GO;
if (rp_ie)
uptr->CMD &= ~CS1_GO;
rp_ie &= ~(CSX_BUSY);
if (rp_ie & CS1_IE)
uba_set_irq(&rpa_dib);
return SCPE_OK;
@@ -843,8 +881,10 @@ rd_end:
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
uptr->CMD |= (ER1_IAE << 16);
uptr->STATUS |= DS_ATA;
rp_ie &= ~CS1_GO;
uba_set_irq(&rpa_dib);
rp_ie &= ~(CSX_BUSY);
uptr->CMD &= ~CS1_GO;
if (rp_ie & CS1_IE)
uba_set_irq(&rpa_dib);
sim_debug(DEBUG_DETAIL, dptr, "%s%o writex done\n", dptr->name, unit);
return SCPE_OK;
}
@@ -917,8 +957,9 @@ wr_done:
} else {
sim_debug(DEBUG_DETAIL, dptr, "RP%o write done\n", unit);
uptr->STATUS &= ~DS_PIP;
rp_ie &= ~CS1_GO;
if (rp_ie)
rp_ie &= ~(CSX_BUSY);
uptr->CMD &= ~CS1_GO;
if (rp_ie & CS1_IE)
uba_set_irq(&rpa_dib);
}
return SCPE_OK;
@@ -947,11 +988,13 @@ rp_reset(DEVICE * dptr)
int i;
rp_ba = 0;
rp_wc = 0177777;
rp_ie = 0;
rp_cs2 = CS2_IR;
for (i = 0; i < 8; i++) {
UNIT *u = &rpa_unit[i];
u->STATUS = 0;
u->STATUS &= DS_VV;
}
uba_clr_irq(&rpa_dib);
sim_debug(DEBUG_DETAIL, dptr, "RP reset done\n");
return SCPE_OK;
}
@@ -968,6 +1011,10 @@ rp_boot(int32 unit_num, DEVICE * rptr)
uint64 len;
int i;
int da;
t_stat r;
if ((r = rp_reset(dptr) )!= SCPE_OK)
return r;
/* Read in block 1 and see if it is a home block */
disk_read(uptr, &rp_buf[0], 1, RP_NUMWD);
if (rp_buf[0] != 0505755000000LL) {
@@ -1043,14 +1090,12 @@ t_stat rp_attach (UNIT *uptr, CONST char *cptr)
if (rptr == 0)
return SCPE_OK;
dib = (DIB *) rptr->ctxt;
// if (uptr->flags & UNIT_WLK)
// uptr->CMD |= DS_WRL;
if (sim_switches & SIM_SW_REST)
return SCPE_OK;
uptr->DA = 0;
// uptr->CMD &= ~DS_VV;
// uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
rp_setattn(uptr - &rpa_unit[0]);
uptr->STATUS = DS_ATA;
if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0)
uba_set_irq(&rpa_dib);
return SCPE_OK;
}
@@ -1062,7 +1107,7 @@ t_stat rp_detach (UNIT *uptr)
return SCPE_OK;
if (sim_is_active (uptr)) /* unit active? */
sim_cancel (uptr); /* cancel operation */
// uptr->CMD &= ~(DS_VV|DS_WRL|DS_DPR|DS_DRY);
uptr->STATUS = 0;
return disk_detach (uptr);
}

View File

@@ -73,6 +73,8 @@
#define CS1_TRE 0040000 /* */
#define CS1_SC 0100000 /* */
#define CSX_BUSY 02 /* RH11 is doing a transfer */
/* TUWC - 772442 - word count. */
/* TUBA - 772444 - bus address */
@@ -197,6 +199,7 @@ static uint64 tu_boot_buffer;
int tu_write(t_addr addr, uint16 data, int32 access);
int tu_read(t_addr addr, uint16 *data, int32 access);
uint16 tu_vect(struct pdp_dib *dibp);
void tu_rst(DEVICE *dptr);
t_stat tu_srv(UNIT *);
t_stat tu_boot(int32, DEVICE *);
@@ -217,7 +220,7 @@ UNIT tua_unit[] = {
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
};
DIB tua_dib = {0772440, 037, 0224, 6, 3, &tu_read, &tu_write, 0};
DIB tua_dib = {0772440, 037, 0224, 6, 3, &tu_read, &tu_write, &tu_vect, 0};
MTAB tu_mod[] = {
{MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL},
@@ -277,69 +280,86 @@ tu_write(t_addr addr, uint16 data, int32 access) {
if (access == BYTE && addr & 1)
return 0;
tu_ie &= ~CS1_IE;
tu_ie |= data & CS1_IE;
tu_ba = ((data << 8) & 0600000) | (tu_ba & 0177777);
tu_ie = data & CS1_IE;
uptr->CMD = data & 076;
if ((data & 01) != 0 && (uptr->flags & UNIT_ATT) != 0) {
switch (GET_FNC(data)) {
case FNC_NOP:
break;
case FNC_PRESET: /* read-in preset */
case FNC_READ: /* read */
case FNC_READREV: /* read w/ headers */
tu_frame = 0;
tu_tcr |= TC_FCS;
/* Fall through */
case FNC_WRITE: /* write */
case FNC_SPACEF: /* Space forward */
case FNC_SPACEB: /* Space backward */
if ((tu_tcr & TC_FCS) == 0) {
uptr->STATUS |= ER1_NEF << 16;
break;
}
/* Fall through */
case FNC_ERASE: /* Erase gap */
case FNC_WTM: /* Write tape mark */
case FNC_WCHK: /* write check */
case FNC_REWIND: /* rewind */
case FNC_UNLOAD: /* unload */
case FNC_WCHKREV: /* write w/ headers */
uptr->CMD |= CS1_GO;
uptr->STATUS = DS_PIP;
tu_attn = 0;
for (i = 0; i < NUM_UNITS_TU; i++) {
if (tua_unit[i].STATUS & DS_ATA)
tu_attn = 1;
}
CLR_BUF(uptr);
uptr->DATAPTR = 0;
sim_activate(uptr, 100);
break;
case FNC_DCLR: /* drive clear */
uptr->CMD &= ~(CS1_GO);
uptr->STATUS = 0;
tu_ie = 0;
tu_attn = 0;
for (i = 0; i < NUM_UNITS_TU; i++) {
if (tua_unit[i].STATUS & DS_ATA)
tu_attn = 1;
}
break;
default:
uptr->STATUS |= (ER1_ILF << 16) | DS_ATA;
tu_attn = 1;
}
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o AStatus=%06o\n", unit, uptr->CMD);
if (tu_attn && tu_ie)
uba_set_irq(&tua_dib);
if ((data & 1) == 0) {
sim_debug(DEBUG_DETAIL, &tua_dev, "RP%o no go %06o\n", unit, data);
return 0; /* No, nop */
}
if ((uptr->flags & UNIT_ATT) == 0) {
sim_debug(DEBUG_DETAIL, &tua_dev, "RP%o unattached %06o\n", unit, data);
return 0; /* No, nop */
}
uba_clr_irq(&tua_dib);
switch (GET_FNC(data)) {
case FNC_NOP:
break;
case FNC_PRESET: /* read-in preset */
case FNC_READ: /* read */
case FNC_READREV: /* read w/ headers */
tu_frame = 0;
tu_tcr |= TC_FCS;
/* Fall through */
case FNC_WRITE: /* write */
case FNC_SPACEF: /* Space forward */
case FNC_SPACEB: /* Space backward */
if ((tu_tcr & TC_FCS) == 0) {
uptr->STATUS |= ER1_NEF << 16;
break;
}
/* Fall through */
case FNC_ERASE: /* Erase gap */
case FNC_WTM: /* Write tape mark */
case FNC_WCHK: /* write check */
case FNC_REWIND: /* rewind */
case FNC_UNLOAD: /* unload */
case FNC_WCHKREV: /* write w/ headers */
uptr->CMD |= CS1_GO;
uptr->STATUS = DS_PIP;
tu_attn = 0;
for (i = 0; i < NUM_UNITS_TU; i++) {
if (tua_unit[i].STATUS & DS_ATA)
tu_attn = 1;
}
CLR_BUF(uptr);
uptr->DATAPTR = 0;
if (GET_FNC(data) >= FNC_XFER)
tu_ie |= CSX_BUSY;
sim_activate(uptr, 100);
break;
case FNC_DCLR: /* drive clear */
uptr->CMD &= ~(CS1_GO);
uptr->STATUS = 0;
tu_ie = 0;
tu_attn = 0;
for (i = 0; i < NUM_UNITS_TU; i++) {
if (tua_unit[i].STATUS & DS_ATA)
tu_attn = 1;
}
break;
default:
uptr->STATUS |= (ER1_ILF << 16) | DS_ATA;
tu_attn = 1;
}
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o AStatus=%06o\n", unit, uptr->CMD);
if (tu_attn && tu_ie)
uba_set_irq(&tua_dib);
break;
case 002: /* TUWC - 172442 - word count */
if ((tu_ie & (CSX_BUSY)) != 0) {
uptr->CMD |= (ER1_RMR << 16);
sim_debug(DEBUG_DETAIL, &tua_dev, "RP%o not ready %02o %06o\n", unit,
addr & 077, data);
return 0;
}
if (access == BYTE) {
if (addr & 1)
data = data | (tu_wc & 0377);
@@ -349,6 +369,12 @@ tu_write(t_addr addr, uint16 data, int32 access) {
tu_wc = data;
break;
case 004: /* TUBA - 172444 - base address */
if ((tu_ie & (CSX_BUSY)) != 0) {
uptr->CMD |= (ER1_RMR << 16);
sim_debug(DEBUG_DETAIL, &tua_dev, "RP%o not ready %02o %06o\n", unit,
addr & 077, data);
return 0;
}
if (access == BYTE) {
if (addr & 1)
data = data | (tu_ba & 0377);
@@ -364,6 +390,12 @@ tu_write(t_addr addr, uint16 data, int32 access) {
break;
case 010: /* 772450 CS2 */
// if ((tu_ie & (CSX_BUSY)) != 0) {
// uptr->CMD |= (ER1_RMR << 16);
// sim_debug(DEBUG_DETAIL, &tua_dev, "RP%o not ready %02o %06o\n", unit,
// addr & 077, data);
// return 0;
// }
if (access == BYTE) {
if (addr & 1)
data = data | tu_cs2;
@@ -420,17 +452,17 @@ tu_read(t_addr addr, uint16 *data, int32 access)
switch(addr & 036) {
case 000: /* 772440 control */
temp = uptr->CMD & 076;
temp = uptr->CMD & 077;
if ((tu_cs2 & 07) == 0)
temp |= CS1_DVA;
temp |= (uint16)tu_ie;
temp |= (uint16)(tu_ie & CS1_IE);
temp |= (tu_ba & 0600000) >> 8;
if (uptr->CMD & CS1_GO)
temp |= CS1_GO;
else if ((uptr->STATUS & DS_PIP) == 0)
if ((tu_ie & CSX_BUSY) == 0)
temp |= CS1_RDY;
if ((tu_cs2 & 07) != 0 || (uptr->STATUS & (ER1_RMR << 16)) != 0)
temp |= CS1_TRE;
if (tu_cs2 & (CS2_MDPE|CS2_MXF|CS2_PGE|CS2_NEM|CS2_NED|CS2_PE|CS2_WCE|CS2_DLT))
temp |= CS1_TRE;
if (tu_attn || temp & CS1_TRE)
temp |= CS1_SC;
break;
@@ -511,6 +543,12 @@ tu_read(t_addr addr, uint16 *data, int32 access)
return 0;
}
uint16
tu_vect(struct pdp_dib *dibp)
{
tu_ie &= ~CS1_IE;
return dibp->uba_vect;
}
/* Map simH errors into machine errors */
void tu_error(UNIT * uptr, t_stat r)
@@ -553,7 +591,7 @@ void tu_error(UNIT * uptr, t_stat r)
uptr->CMD &= ~(CS1_GO);
uptr->STATUS &= ~DS_PIP;
sim_debug(DEBUG_EXP, dptr, "Setting status %d\n", r);
if (tu_ie)
if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0)
uba_set_irq(&tua_dib);
}
@@ -593,7 +631,7 @@ t_stat tu_srv(UNIT * uptr)
uptr->STATUS |= DS_SSC|DS_ATA;
uptr->STATUS &= ~DS_PIP;
tu_attn = 1;
if (tu_ie)
if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0)
uba_set_irq(&tua_dib);
(void)sim_tape_rewind(uptr);
}
@@ -613,6 +651,7 @@ t_stat tu_srv(UNIT * uptr)
if ((r = sim_tape_rdrecr(uptr, &tu_buf[0], &reclen,
TU_NUMFR)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
tu_ie &= ~(CSX_BUSY);
if (r == MTSE_BOT)
uptr->STATUS |= ER1_NEF << 16;
tu_error(uptr, r);
@@ -640,6 +679,7 @@ t_stat tu_srv(UNIT * uptr)
uptr->CPOS = cc_max;
if (GET_FNC(uptr->CMD) == FNC_READREV &&
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) {
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
@@ -650,6 +690,7 @@ t_stat tu_srv(UNIT * uptr)
tu_ba -= 4;
tu_wc = (tu_wc + 2) & 0177777;
if (tu_wc == 0) {
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
@@ -657,6 +698,7 @@ t_stat tu_srv(UNIT * uptr)
} else {
if (uptr->CPOS != cc_max)
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf);
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
@@ -668,6 +710,7 @@ t_stat tu_srv(UNIT * uptr)
if ((r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen,
TU_NUMFR)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
tu_ie &= ~(CSX_BUSY);
if (r == MTSE_TMK)
uptr->STATUS |= ER1_FCE << 16;
tu_error(uptr, r);
@@ -697,6 +740,7 @@ t_stat tu_srv(UNIT * uptr)
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) {
if ((uint32)uptr->DATAPTR == uptr->hwmark)
goto rd_end;
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
@@ -718,6 +762,7 @@ t_stat tu_srv(UNIT * uptr)
rd_end:
if (tu_frame != 0)
uptr->STATUS |= ER1_FCE << 16;
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
@@ -727,10 +772,12 @@ rd_end:
if (BUF_EMPTY(uptr)) {
if (tu_frame == 0) {
uptr->STATUS |= (ER1_NEF << 16) | DS_ATA;
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_OK);
return SCPE_OK;
}
if ((uptr->flags & MTUF_WLK) != 0) {
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, MTSE_WRP);
return SCPE_OK;
}
@@ -783,6 +830,7 @@ wr_end:
dptr->name, unit, reclen, uptr->CPOS);
uptr->DATAPTR = 0;
uptr->hwmark = 0;
tu_ie &= ~(CSX_BUSY);
tu_error(uptr, r); /* Record errors */
return SCPE_OK;
}
@@ -864,6 +912,7 @@ tu_reset(DEVICE * dptr)
for (i = 0; i < NUM_UNITS_TU; i++) {
tua_unit[i].STATUS = 0;
}
uba_clr_irq(&tua_dib);
return SCPE_OK;
}
@@ -935,7 +984,7 @@ tu_attach(UNIT * uptr, CONST char *file)
if (r == SCPE_OK && (sim_switches & SIM_SW_REST) == 0) {
uptr->STATUS = DS_ATA|DS_SSC;
tu_attn = 1;
if (tu_ie)
if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0)
uba_set_irq(&tua_dib);
}
return r;

View File

@@ -68,7 +68,22 @@ uba_read(t_addr addr, int ctl, uint64 *data, int access)
*data = (uint64)uba_map[ubm][addr & 077];
return 0;
} else if ((addr & 077) == 0) {
int pih, pil;
*data = (uint64)uba_status[ubm];
pih = 0200 >> ((uba_status[ubm] >> 3) & 07);
pil = 0200 >> (uba_status[ubm] & 07);
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
DIB *dibp = (DIB *) dptr->ctxt;
if (dibp == NULL)
continue;
/* If device is pending on this level save */
if (dibp->uba_ctl == ctl) {
if ((dibp->uba_irq_pend & pil) != 0)
*data |= UBST_INTL;
if ((dibp->uba_irq_pend & pih) != 0)
*data |= UBST_INTH;
}
}
return 0;
} else if ((addr & 077) == 1) {
*data = 0;
@@ -81,11 +96,10 @@ uba_read(t_addr addr, int ctl, uint64 *data, int access)
DIB *dibp = (DIB *) dptr->ctxt;
if (dibp == NULL)
continue;
if (ctl == dibp->uba_ctl && dibp->uba_addr == (addr & (~dibp->uba_mask))) {
if (ctl == dibp->uba_ctl &&
dibp->uba_addr == (addr & (~dibp->uba_mask))) {
uint16 buf;
int r = dibp->rd_io(addr, &buf, access);
// if (access == BYTE && (addr & 1) != 0)
// buf >>= 8;
*data = (uint64)buf;
return r;
}
@@ -120,7 +134,8 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
uint32 map = (uint32)(data & 03777) << 9;
map |= (uint32)(data & 0740000) << 13;
uba_map[ubm][addr & 077] = map;
sim_debug(DEBUG_EXP, &cpu_dev, "Wr MAP %02o %012llo %06o\n\r", addr & 077, data, map);
sim_debug(DEBUG_EXP, &cpu_dev, "Wr MAP %02o %012llo %06o\n\r",
addr & 077, data, map);
return 0;
} else if ((addr & 077) == 0) {
uba_status[ubm] &= (uint32)(074000 ^ data) | 0746000;
@@ -232,29 +247,62 @@ uba_set_irq(DIB *dibp)
/* Figure out what channel device should IRQ on */
if (dibp->uba_br > 5) {
pi = uba_status[ubm] >> 3;
uba_status[ubm] |= UBST_INTH;
} else {
pi = uba_status[ubm];
uba_status[ubm] |= UBST_INTL;
}
/* Save in device temp the irq value */
dibp->uba_irq_pend = 0200 >> (pi & 07);
set_interrupt(dibp->uba_ctl << 2, pi);
set_interrupt(dibp->uba_ctl<<2, pi);
}
void
uba_clr_irq(DIB *idev)
{
DEVICE *dptr;
int ubm = uba_device[idev->uba_ctl];
int pi;
int i;
int high = 0;
if (ubm < 0)
return;
/* Figure out what channel device should IRQ on */
if (idev->uba_br > 5) {
pi = uba_status[ubm] >> 3;
} else {
pi = uba_status[ubm];
}
/* Save in device temp the irq value */
idev->uba_irq_pend = 0;
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
DIB *dibp = (DIB *) dptr->ctxt;
if (dibp == NULL)
continue;
/* If device is pending on this level save */
if (dibp->uba_ctl == idev->uba_ctl &&
dibp->uba_irq_pend != 0) {
/* At least one, no need to continue */
return;
}
}
/* Nothing, so clear it */
clr_interrupt(idev->uba_ctl<<2);
}
t_addr
uba_get_vect(t_addr addr, int lvl)
uba_get_vect(t_addr addr, int lvl, int *dev, int *new_lvl)
{
DEVICE *dptr;
DIB *idev = NULL;
uint64 buffer;
uint16 ivect;
int i;
int high = 0;
int ctl = 17;
int pi;
int ubm;
*dev = 0; /* Adaptor 0 is special */
/* Look for device */
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
DIB *dibp = (DIB *) dptr->ctxt;
@@ -271,40 +319,32 @@ uba_get_vect(t_addr addr, int lvl)
}
/* Should have a device */
if (idev != NULL) {
*new_lvl = 0;
*dev = idev->uba_ctl;
/* Figure out what pi channel this will interrupt on */
ubm = uba_device[idev->uba_ctl];
if (idev->uba_br > 5) {
pi = (uba_status[ubm] >> 3) & 07;
high = 1;
uba_status[ubm] &= ~UBST_INTH;
} else {
pi = uba_status[ubm] & 07;
uba_status[ubm] &= ~UBST_INTL;
}
/* Clear interrupts */
idev->uba_irq_pend = 0;
/* Fetch vector */
if (Mem_read_word(0100 | idev->uba_ctl, &buffer, 1))
return addr;
idev->uba_irq_pend = 0;
ivect = idev->uba_vect;
if (idev->irqv != NULL)
ivect = (idev->irqv)(idev);
addr = (buffer + (ivect >> 2)) & RMASK;
/* Any other devices waiting on this PI channel? */
clr_interrupt(idev->uba_ctl << 2);
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
for(pi = i = 0; (dptr = sim_devices[i]) != NULL; i++) {
DIB *dibp = (DIB *) dptr->ctxt;
if (dibp == NULL)
continue;
/* If device is pending on this level save */
if (dibp->uba_ctl == idev->uba_ctl &&
(dibp->uba_irq_pend & lvl) != 0) {
set_interrupt(idev->uba_ctl << 2, pi);
uba_status[ubm] |= UBST_INTL << high;
dibp->uba_irq_pend != 0) {
/* At least one, no need to continue */
break;
*new_lvl |= dibp->uba_irq_pend;
}
}
/* Fetch vector */
if (Mem_read_word(0100 | idev->uba_ctl, &buffer, 1))
return addr;
ivect = idev->uba_vect;
if (idev->irqv != NULL)
ivect = (idev->irqv)(idev);
addr = (buffer & RMASK) + (idev->uba_vect >> 2);
}
return addr;
}

View File

@@ -280,6 +280,7 @@ int watch_stop; /* Stop at memory watch point */
int maoff = 0; /* Offset for traps */
uint16 dev_irq[128]; /* Pending irq by device */
uint8 dev_map[128]; /* Map device to irq slot */
t_stat (*dev_tab[128])(uint32 dev, uint64 *data);
t_addr (*dev_irqv[128])(uint32 dev, t_addr addr);
t_stat rtc_srv(UNIT * uptr);
@@ -1074,7 +1075,11 @@ get_quantum()
void set_interrupt(int dev, int lvl) {
lvl &= 07;
if (lvl) {
dev_irq[dev>>2] = 0200 >> lvl;
#if KS
dev_irq[dev>>2] |= 0200 >> lvl;
#else
dev_irq[dev_map[dev>>2]] = 0200 >> lvl;
#endif
pi_pending = 1;
sim_debug(DEBUG_IRQ, &cpu_dev, "set irq %o %o %03o %03o %03o\n",
dev & 0774, lvl, PIE, PIR, PIH);
@@ -1085,9 +1090,9 @@ void set_interrupt(int dev, int lvl) {
void set_interrupt_mpx(int dev, int lvl, int mpx) {
lvl &= 07;
if (lvl) {
dev_irq[dev>>2] = 0200 >> lvl;
dev_irq[dev_map[dev>>2]] = 0200 >> lvl;
if (lvl == 1 && mpx != 0)
dev_irq[dev>>2] |= mpx << 8;
dev_irq[dev_map[dev>>2]] |= mpx << 8;
pi_pending = 1;
sim_debug(DEBUG_IRQ, &cpu_dev, "set mpx irq %o %o %o %03o %03o %03o\n",
dev & 0774, lvl, mpx, PIE, PIR, PIH);
@@ -1099,7 +1104,7 @@ void set_interrupt_mpx(int dev, int lvl, int mpx) {
* Clear the interrupt flag for a device
*/
void clr_interrupt(int dev) {
dev_irq[dev>>2] = 0;
dev_irq[dev_map[dev>>2]] = 0;
if (dev > 4)
sim_debug(DEBUG_IRQ, &cpu_dev, "clear irq %o\n", dev & 0774);
}
@@ -1134,7 +1139,7 @@ int check_irq_level() {
}
/* Scan all devices */
for(i = lvl = 0; i <= (int)max_dev; i++)
for(i = lvl = 0; i < (int)max_dev; i++)
lvl |= dev_irq[i];
if (lvl == 0)
pi_pending = 0;
@@ -1144,7 +1149,7 @@ int check_irq_level() {
if (mpx_enable && cpu_unit[0].flags & UNIT_MPX &&
(pi_req & 0100) && (PIH & 0100) == 0) {
pi_enc = 010;
for(i = lvl = 0; i <= (int)max_dev; i++) {
for(i = lvl = 0; i < (int)max_dev; i++) {
if (dev_irq[i] & 0100) {
int l = dev_irq[i] >> 8;
if (l != 0 && l < pi_enc)
@@ -4778,7 +4783,14 @@ st_pi:
AB |= eb_ptr;
extend = 0;
if ((dev_irq[0] & pi_mask) == 0) {
AB = uba_get_vect(AB, pi_mask);
int new_lvl;
int dev;
AB = uba_get_vect(AB, pi_mask, &dev, &new_lvl);
if (dev != 0) {
dev_irq[dev] = new_lvl;
if (new_lvl != 0)
pi_pending = 1;
}
sim_debug(DEBUG_IRQ, &cpu_dev, "vect irq %o %06o\n", pi_enc, AB);
}
Mem_read_nopage();
@@ -4789,11 +4801,11 @@ st_pi:
* Scan through the devices and allow KI devices to have first
* hit at a given level.
*/
for (f = 0; f <= (int)max_dev; f++) {
if (dev_irqv[f] != 0 && dev_irq[f] & pi_mask) {
for (f = 0; f < 128; f++) {
if (dev_irqv[f] != 0 && dev_irq[dev_map[f]] & pi_mask) {
AB = dev_irqv[f](f << 2, AB);
sim_debug(DEBUG_IRQ, &cpu_dev, "vect irq %o %03o %06o\n",
pi_enc, dev_irq[f], AB);
pi_enc, dev_irq[dev_map[f]], AB);
break;
}
}
@@ -9688,7 +9700,7 @@ test_op:
xct_flag = 0;
break;
case 010: /* TIOE */
case 010: /* TIOE , ITS RDIOI */
#if KS_ITS
if (QITS) {
ctl = 3;
@@ -9707,7 +9719,7 @@ io_fault:
PC = (PC + 1) & RMASK;
break;
case 011: /* TION */
case 011: /* TION, ITS RDIOQ */
#if KS_ITS
if (QITS) {
ctl = 1;
@@ -9751,7 +9763,7 @@ its_wr:
goto io_fault;
break;
case 014: /* BSIO */
case 014: /* BSIO, ITS WRIOI */
#if KS_ITS
if (QITS) {
ctl = 3;
@@ -9766,7 +9778,7 @@ its_wr:
goto io_fault;
break;
case 015: /* BCIO */
case 015: /* BCIO, ITS WRIOQ */
#if KS_ITS
if (QITS) {
ctl = 1;
@@ -9782,6 +9794,12 @@ its_wr:
break;
case 020: /* TIOEB */
#if KS_ITS
if (QITS) {
ctl = 3;
goto its_rdb;
}
#endif
BR = get_reg(AC);
if (uba_read(AB, ctl, &MB, BYTE))
goto io_fault;
@@ -9790,6 +9808,12 @@ its_wr:
break;
case 021: /* TIONB */
#if KS_ITS
if (QITS) {
ctl = 1;
goto its_rdb;
}
#endif
BR = get_reg(AC);
if (uba_read(AB, ctl, &MB, BYTE))
goto io_fault;
@@ -9798,18 +9822,42 @@ its_wr:
break;
case 022: /* RDIOB */
#if KS_ITS
if (QITS) {
if (Mem_read(pi_cycle, 0, 0))
goto last;
AB = MB & RMASK;
ctl = (int)((MB >> 18) & 017);
}
its_rdb:
#endif
if (uba_read(AB, ctl, &AR, BYTE))
goto io_fault;
i_flags = SAC;
break;
case 023: /* WRIOB */
#if KS_ITS
if (QITS) {
if (Mem_read(pi_cycle, 0, 0))
goto last;
AB = MB & RMASK;
ctl = (int)((MB >> 18) & 017);
}
its_wrb:
#endif
MB = get_reg(AC);
if (uba_write(AB, ctl, MB, BYTE))
goto io_fault;
break;
case 024: /* BSIOB */
#if KS_ITS
if (QITS) {
ctl = 3;
goto its_wrb;
}
#endif
BR = get_reg(AC);
if (uba_read(AB, ctl, &MB, BYTE))
goto io_fault;
@@ -9819,6 +9867,12 @@ its_wr:
break;
case 025: /* BCIOB */
#if KS_ITS
if (QITS) {
ctl = 1;
goto its_wrb;
}
#endif
BR = get_reg(AC);
if (uba_read(AB, ctl, &MB, BYTE))
goto io_fault;
@@ -11749,6 +11803,7 @@ max_dev = 16;
#endif
for(i=0; i < 128; dev_irq[i++] = 0);
for(i=0; i < 128; dev_map[i++] = 0);
sim_brk_types = SWMASK('E') | SWMASK('W') | SWMASK('R');
sim_brk_dflt = SWMASK ('E');
sim_clock_precalibrate_commands = pdp10_clock_precalibrate_commands;
@@ -11882,7 +11937,6 @@ t_bool build_dev_tab (void)
/* Set trap offset based on MAOFF flag */
maoff = (cpu_unit[0].flags & UNIT_MAOFF)? 0100 : 0;
max_dev = 2;
#if KA
/* Set up memory access routines based on current CPU type. */
@@ -11914,11 +11968,13 @@ t_bool build_dev_tab (void)
for (i = 0; i < 128; i++) {
dev_tab[i] = &null_dev;
dev_irqv[i] = NULL;
dev_map[i] = 0;
}
/* Set up basic devices. */
dev_tab[0] = &dev_apr;
dev_tab[1] = &dev_pi;
max_dev = 2;
#if KI | KL
dev_tab[2] = &dev_pag;
max_dev++;
@@ -11927,13 +11983,16 @@ t_bool build_dev_tab (void)
dev_tab[4] = &dev_tim;
dev_irqv[4] = &tim_irq;
dev_tab[5] = &dev_mtr;
max_dev+=4;
max_dev+=3;
#endif
#endif
for (i = 0; i < max_dev; i++) {
dev_map[i] = i;
}
#if BBN
if (QBBN) {
dev_tab[024>>2] = &dev_pag;
max_dev = 024>>2;
dev_map[024>>2] = max_dev++;
}
#endif
@@ -11970,13 +12029,12 @@ t_bool build_dev_tab (void)
#endif
}
dev_tab[(d >> 2)] = dibp->io;
dev_map[(d >> 2)] = max_dev++;
dev_irqv[(d >> 2)] = dibp->irq;
rh[rh_idx].dev_num = d;
rh[rh_idx].dev = dptr;
rh[rh_idx].rh = dibp->rh;
dibp->rh->devnum = d;
if ((d >> 2) > max_dev)
max_dev = d >> 2;
rh_idx++;
}
}
@@ -11998,9 +12056,8 @@ t_bool build_dev_tab (void)
return TRUE;
}
dev_tab[(d >> 2) + j] = dibp->io; /* fill */
dev_map[(d >> 2) + j] = max_dev++;
dev_irqv[(d >> 2) + j] = dibp->irq;
if (((d >> 2) + j)> max_dev)
max_dev = (d >> 2) + j;
}
}
}

View File

@@ -528,7 +528,7 @@ struct pdp_dib {
uint16 uba_ctl; /* Unibus controller number */
t_stat (*rd_io)(t_addr addr, uint16 *data, int32 access);
t_stat (*wr_io)(t_addr addr, uint16 data, int32 access);
uint8 (*irqv)(struct pdp_dib *dibp);
uint16 (*irqv)(struct pdp_dib *dibp);
uint8 uba_irq_pend; /* Device has pending */
};
typedef struct pdp_dib DIB;
@@ -549,7 +549,8 @@ int uba_write_npr_byte(t_addr addr, uint16 ctl, uint16 data);
int uba_read_npr_word(t_addr addr, uint16 ctl, uint16 *data);
int uba_write_npr_word(t_addr addr, uint16 ctl, uint16 data);
void uba_set_irq(DIB *dibp);
t_addr uba_get_vect(t_addr addr, int lvl);
void uba_clr_irq(DIB *dibp);
t_addr uba_get_vect(t_addr addr, int lvl, int *dev, int *new_lvl);
t_stat uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat uba_show_addr (FILE *st, UNIT *uptr, int32 val, CONST void *desc);