Fixed interrupt logic causing OS device timeouts when I/O was happening to multiple drives simultaneously (from Bob Supnik)
This commit is contained in:
parent
e0bb8fed91
commit
0290b4bee4
1 changed files with 287 additions and 38 deletions
325
PDP11/pdp11_hk.c
325
PDP11/pdp11_hk.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
hk RK611/RK06/RK07 disk
|
||||
|
||||
10-Dec-12 RMS Fixed interrupt logic
|
||||
19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato)
|
||||
29-Apr-07 RMS NOP and DCLR (at least) do not check drive type
|
||||
MR2 and MR3 only updated on NOP
|
||||
|
@ -136,12 +137,44 @@ extern uint16 *M;
|
|||
#define GET_UAE(x) (((x) >> CS1_V_UAE) & CS1_M_UAE)
|
||||
#define PUT_UAE(x,n) (((x) & ~ CS1_UAE) | (((n) << CS1_V_UAE) & CS1_UAE))
|
||||
|
||||
char *hk_funcs[] = {
|
||||
"NOP", "PACK", "DCLR", "UNLOAD", "START", "RECAL", "OFFSET", "SEEK",
|
||||
"READ", "WRITE", "READH", "WRITEH", "WCHK"};
|
||||
|
||||
BITFIELD hk_cs1_bits[] = {
|
||||
BIT(GO), /* go */
|
||||
BITFNAM(FNC,4,hk_funcs), /* function */
|
||||
BIT(SPARE), /* Spare Bit */
|
||||
BIT(IE), /* Interrupt Enable */
|
||||
BIT(RDY), /* Controller Ready */
|
||||
BIT(BA16), /* Unibus addr ext bit 16 */
|
||||
BIT(BA17), /* Unibus addr ext bit 17 */
|
||||
BIT(DT), /* Controller Drive Type */
|
||||
BIT(CTO), /* Controller Timeout */
|
||||
BIT(CFMT), /* Controller Format */
|
||||
BIT(DTCPAR), /* Drive-To-Controller Parity Error */
|
||||
BIT(DI), /* Drive Interrupt */
|
||||
BIT(ERR), /* error */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
|
||||
/* HKWC - 177442 - word count */
|
||||
|
||||
BITFIELD hk_wc_bits[] = {
|
||||
BITF(WC,16), /* Word Count */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKBA - 177444 - base address */
|
||||
|
||||
#define BA_MBZ 0000001 /* must be zero */
|
||||
|
||||
BITFIELD hk_ba_bits[] = {
|
||||
BITF(BA,16), /* Bus Address */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKDA - 177446 - sector/track */
|
||||
|
||||
#define DA_V_SC 0 /* sector pos */
|
||||
|
@ -152,6 +185,14 @@ extern uint16 *M;
|
|||
#define GET_SC(x) (((x) >> DA_V_SC) & DA_M_SC)
|
||||
#define GET_SF(x) (((x) >> DA_V_SF) & DA_M_SF)
|
||||
|
||||
BITFIELD hk_da_bits[] = {
|
||||
BITF(SA,5), /* Sector */
|
||||
BITNCF(3), /* 05:07 Zero */
|
||||
BITF(TA,3), /* Track */
|
||||
BITNCF(5), /* 11:15 Zero */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKCS2 - 177450 - control/status 2 */
|
||||
|
||||
#define CS2_V_UNIT 0 /* unit pos */
|
||||
|
@ -176,6 +217,25 @@ extern uint16 *M;
|
|||
CS2_NED | CS2_PE | CS2_WCE | CS2_DLT )
|
||||
#define GET_UNIT(x) (((x) >> CS2_V_UNIT) & CS2_M_UNIT)
|
||||
|
||||
BITFIELD hk_cs2_bits[] = {
|
||||
BITF(DS,3), /* Drive Select */
|
||||
BIT(RLS), /* Release */
|
||||
BIT(BAI), /* Bus Address Increment Inhibit */
|
||||
BIT(SCLR), /* Subsystem Clear */
|
||||
BIT(IR), /* Input Ready */
|
||||
BIT(OR), /* Output Ready */
|
||||
BIT(UFE), /* Unit Field Error */
|
||||
BIT(MDS), /* Multiple Drive Select */
|
||||
BIT(PGE), /* Programming Error */
|
||||
BIT(NEM), /* Nonexistant Memory */
|
||||
BIT(NED), /* Nonexistant Drive */
|
||||
BIT(UPE), /* Unibus Parity Error */
|
||||
BIT(WCE), /* Write Check Error */
|
||||
BIT(DLT), /* Data Late Error */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
|
||||
/* HKDS - 177452 - drive status ^ = calculated dynamically */
|
||||
|
||||
#define DS_DRA 0000001 /* ^drive avail */
|
||||
|
@ -192,6 +252,25 @@ extern uint16 *M;
|
|||
#define DS_VLD 0100000 /* ^status valid */
|
||||
#define DS_MBZ 0013002
|
||||
|
||||
BITFIELD hk_ds_bits[] = {
|
||||
BIT(DRA), /* Drive Available */
|
||||
BITNCF(1), /* 01 Spare */
|
||||
BIT(OFST), /* Offset */
|
||||
BIT(ACLO), /* Drive AC Low */
|
||||
BIT(SPLS), /* Speed Loss */
|
||||
BIT(DROT), /* Drive Off Track */
|
||||
BIT(VV), /* Volume Valid */
|
||||
BIT(DRDY), /* Drive Ready */
|
||||
BIT(DDT), /* Disk Drive Type */
|
||||
BITNCF(2), /* 09:10 Spare */
|
||||
BIT(WRL), /* Write Lock */
|
||||
BITNCF(1), /* 12 Spare */
|
||||
BIT(PIP), /* Positioning in Progress */
|
||||
BIT(ATA), /* Current Drive Attention */
|
||||
BIT(SVAL), /* Status Valid */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKER - 177454 - error status */
|
||||
|
||||
#define ER_ILF 0000001 /* illegal func */
|
||||
|
@ -211,11 +290,44 @@ extern uint16 *M;
|
|||
#define ER_UNS 0040000 /* drive unsafe */
|
||||
#define ER_DCK 0100000 /* data check NI */
|
||||
|
||||
BITFIELD hk_er_bits[] = {
|
||||
BIT(ILF), /* Illegal Function */
|
||||
BIT(SKI), /* Seek Incomplete */
|
||||
BIT(NXF), /* Nonexecutable Function */
|
||||
BIT(DROAR), /* Control-to-Drive Parity Error */
|
||||
BIT(FMTE), /* Format Error */
|
||||
BIT(DTYE), /* Drive Type Error */
|
||||
BIT(ECH), /* Error Correction Hard */
|
||||
BIT(BSE), /* Bad Sector Error */
|
||||
BIT(HRVC), /* Header Virtical Redundancy */
|
||||
BIT(COE), /* Cylinder Overflow Error */
|
||||
BIT(IDAE), /* Invalid Disk Address Error */
|
||||
BIT(WLE), /* Write Lock Error */
|
||||
BIT(DTE), /* Drive Timing Error */
|
||||
BIT(OPI), /* Operation Incomplete */
|
||||
BIT(UNS), /* Drive Unsafe */
|
||||
BIT(DCK), /* Data Check */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKAS - 177456 - attention summary/offset */
|
||||
|
||||
#define AS_U0 0000400 /* unit 0 flag */
|
||||
#define AS_OF 0000277 /* offset mask */
|
||||
|
||||
BITFIELD hk_as_bits[] = {
|
||||
BITF(OF,8), /* Offset */
|
||||
BIT(ATN0), /* Attention Drive 0 */
|
||||
BIT(ATN1), /* Attention Drive 1 */
|
||||
BIT(ATN2), /* Attention Drive 2 */
|
||||
BIT(ATN3), /* Attention Drive 3 */
|
||||
BIT(ATN4), /* Attention Drive 4 */
|
||||
BIT(ATN5), /* Attention Drive 5 */
|
||||
BIT(ATN6), /* Attention Drive 6 */
|
||||
BIT(ATN7), /* Attention Drive 7 */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKDC - 177460 - desired cylinder */
|
||||
|
||||
#define DC_V_CY 0 /* cylinder pos */
|
||||
|
@ -225,6 +337,12 @@ extern uint16 *M;
|
|||
#define GET_DA(c,fs) ((((GET_CY (c) * HK_NUMSF) + \
|
||||
GET_SF (fs)) * HK_NUMSC) + GET_SC (fs))
|
||||
|
||||
BITFIELD hk_dc_bits[] = {
|
||||
BITF(DC,10), /* Desired Cylinder */
|
||||
BITNCF(6), /* 10:15 Spare */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* Spare - 177462 - read/write */
|
||||
|
||||
#define XM_KMASK 0177700 /* Qbus XM key mask */
|
||||
|
@ -234,6 +352,11 @@ extern uint16 *M;
|
|||
|
||||
/* HKDB - 177464 - read/write */
|
||||
|
||||
BITFIELD hk_db_bits[] = {
|
||||
BITF(DB,16), /* Data Buffer Register */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKMR - 177466 - maintenance register 1 */
|
||||
|
||||
#define MR_V_MS 0 /* message select */
|
||||
|
@ -244,9 +367,37 @@ extern uint16 *M;
|
|||
#define MR_DMD 0000040 /* diagnostic mode */
|
||||
#define MR_RW 0001777
|
||||
|
||||
BITFIELD hk_mr_bits[] = {
|
||||
BITF(MS,4), /* Message Select */
|
||||
BIT(PAT), /* Parity Test */
|
||||
BIT(DMD), /* Diagnostic Mode */
|
||||
BIT(MSP), /* Maintenance Selector Pulse */
|
||||
BIT(MIND), /* Maintenance Index */
|
||||
BIT(MCLK), /* Maintenance Clock */
|
||||
BIT(MERD), /* Maintenance Encoded Read Data */
|
||||
BIT(MEWD), /* Maintenance Encoded Write Data */
|
||||
BIT(PCA), /* Precompensation Advance */
|
||||
BIT(PCD), /* Precompensation Delay */
|
||||
BIT(ECCW), /* ECC Word */
|
||||
BIT(WRTGT), /* Write Gate */
|
||||
BIT(RDGT), /* Read Gate */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKEC1 - 177470 - ECC status 1 - always reads as 0 */
|
||||
|
||||
BITFIELD hk_ec1_bits[] = {
|
||||
BITF(EC1,16), /* ECC status 1 */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKEC2 - 177472 - ECC status 2 - always reads as 0 */
|
||||
|
||||
BITFIELD hk_ec2_bits[] = {
|
||||
BITF(EC2,16), /* ECC status 2 */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKMR2 - 177474 - maintenance register 2 */
|
||||
|
||||
#define AX_V_UNIT 0 /* unit #, all msgs */
|
||||
|
@ -280,6 +431,11 @@ extern uint16 *M;
|
|||
|
||||
#define A3_V_SNO 3 /* serial # */
|
||||
|
||||
BITFIELD hk_mr2_bits[] = {
|
||||
BITF(MR2,16), /* Maintenance Register 2 */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
/* HKMR3 - 177476 - maintenance register 3 */
|
||||
|
||||
#define B0_IAE 0000040 /* invalid addr */
|
||||
|
@ -317,14 +473,58 @@ extern uint16 *M;
|
|||
#define RDH2_V_DHA 5 /* decoded head */
|
||||
#define RDH2_GOOD 0140000 /* good sector flags */
|
||||
|
||||
BITFIELD hk_mr3_bits[] = {
|
||||
BITF(MR3,16), /* Maintenance Register 3 */
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
char *hk_regnames[] = {
|
||||
"HKCS1",
|
||||
"HKWC",
|
||||
"HKBA",
|
||||
"HKDA",
|
||||
"HKCS2",
|
||||
"HKDS",
|
||||
"HKER",
|
||||
"HKAS",
|
||||
"HKDC",
|
||||
"spare",
|
||||
"HKDB",
|
||||
"HKMR",
|
||||
"HKEC1",
|
||||
"HKEC2",
|
||||
"HKMR2",
|
||||
"HKMR3"
|
||||
};
|
||||
|
||||
BITFIELD *hk_reg_bits[] = {
|
||||
hk_cs1_bits,
|
||||
hk_wc_bits,
|
||||
hk_ba_bits,
|
||||
hk_da_bits,
|
||||
hk_cs2_bits,
|
||||
hk_ds_bits,
|
||||
hk_er_bits,
|
||||
hk_as_bits,
|
||||
hk_dc_bits,
|
||||
NULL,
|
||||
hk_db_bits,
|
||||
hk_mr_bits,
|
||||
hk_ec1_bits,
|
||||
hk_ec2_bits,
|
||||
hk_mr2_bits,
|
||||
hk_mr3_bits,
|
||||
};
|
||||
|
||||
/* Debug detail levels */
|
||||
|
||||
#define HKDEB_OPS 001 /* transactions */
|
||||
#define HKDEB_RRD 002 /* reg reads */
|
||||
#define HKDEB_RWR 004 /* reg writes */
|
||||
#define HKDEB_TRC 010 /* trace */
|
||||
#define HKDEB_INT 020 /* interrupts */
|
||||
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
extern FILE *sim_deb;
|
||||
|
||||
uint16 *hkxb = NULL; /* xfer buffer */
|
||||
int32 hkcs1 = 0; /* control/status 1 */
|
||||
|
@ -464,6 +664,8 @@ DEBTAB hk_deb[] = {
|
|||
{ "OPS", HKDEB_OPS },
|
||||
{ "RRD", HKDEB_RRD },
|
||||
{ "RWR", HKDEB_RWR },
|
||||
{ "INTERRUPT", HKDEB_INT },
|
||||
{ "TRACE", HKDEB_TRC },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -563,14 +765,14 @@ switch (j) { /* decode PA<4:1> */
|
|||
break;
|
||||
}
|
||||
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_RRD))
|
||||
fprintf (sim_deb, ">>HK%d read: reg%d=%o\n", drv, j, *data);
|
||||
sim_debug (HKDEB_RRD, &hk_dev, ">>HK%d read: %s=0%o\n", drv, hk_regnames[j], *data);
|
||||
sim_debug_bits (HKDEB_RRD, &hk_dev, hk_reg_bits[j], *data, *data, 1);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat hk_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
int32 drv, i, j;
|
||||
int32 drv, i, j, old_val, new_val;
|
||||
UNIT *uptr;
|
||||
|
||||
drv = GET_UNIT (hkcs2); /* get current unit */
|
||||
|
@ -584,11 +786,11 @@ if ((hkcs1 & CS1_GO) && /* busy? */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_RWR))
|
||||
fprintf (sim_deb, ">>HK%d write: reg%d=%o\n", drv, j, data);
|
||||
sim_debug (HKDEB_RWR, &hk_dev, ">>HK%d write: %s=0%o\n", drv, hk_regnames[j], data);
|
||||
switch (j) { /* decode PA<4:1> */
|
||||
|
||||
case 000: /* HKCS1 */
|
||||
old_val = hkcs1;
|
||||
if (data & CS1_CCLR) { /* controller reset? */
|
||||
hkcs1 = CS1_DONE; /* CS1 = done */
|
||||
hkcs2 = CS2_IR; /* CS2 = ready */
|
||||
|
@ -599,68 +801,98 @@ switch (j) { /* decode PA<4:1> */
|
|||
CLR_INT (HK); /* clr int */
|
||||
for (i = 0; i < HK_NUMDR; i++) { /* stop data xfr */
|
||||
if (sim_is_active (&hk_unit[i]) &&
|
||||
((uptr->FNC & CS1_M_FNC) >= FNC_XFER))
|
||||
((hk_unit[i].FNC & CS1_M_FNC) >= FNC_XFER))
|
||||
sim_cancel (&hk_unit[i]);
|
||||
}
|
||||
drv = 0;
|
||||
break;
|
||||
}
|
||||
if (data & CS1_IE) { /* setting IE? */
|
||||
if (data & CS1_DONE) /* write to DONE+IE? */
|
||||
if (data & CS1_DONE) { /* write to DONE+IE? */
|
||||
sim_debug (HKDEB_INT, &hk_dev, "hk_wr(SET_INT)\n");
|
||||
SET_INT (HK);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sim_debug (HKDEB_INT, &hk_dev, "hk_wr(CLR_INT)\n");
|
||||
CLR_INT (HK); /* no, clr intr */
|
||||
}
|
||||
else CLR_INT (HK); /* no, clr intr */
|
||||
hkcs1 = (hkcs1 & ~CS1_RW) | (data & CS1_RW); /* merge data */
|
||||
if (SC02C)
|
||||
hkspr = (hkspr & ~CS1_M_UAE) | GET_UAE (hkcs1);
|
||||
if ((data & CS1_GO) && !(hkcs1 & CS1_ERR)) /* go? */
|
||||
hk_go (drv);
|
||||
new_val = hkcs1;
|
||||
break;
|
||||
|
||||
case 001: /* HKWC */
|
||||
hkwc = data;
|
||||
old_val = hkwc;
|
||||
new_val = hkwc = data;
|
||||
break;
|
||||
|
||||
case 002: /* HKBA */
|
||||
hkba = data & ~BA_MBZ;
|
||||
old_val = hkba;
|
||||
new_val = hkba = data & ~BA_MBZ;
|
||||
break;
|
||||
|
||||
case 003: /* HKDA */
|
||||
hkda = data & ~DA_MBZ;
|
||||
old_val = hkda;
|
||||
new_val = hkda = data & ~DA_MBZ;
|
||||
break;
|
||||
|
||||
case 004: /* HKCS2 */
|
||||
old_val = hkcs2;
|
||||
if (data & CS2_CLR) /* init? */
|
||||
hk_reset (&hk_dev);
|
||||
else hkcs2 = (hkcs2 & ~CS2_RW) | (data & CS2_RW) | CS2_IR;
|
||||
drv = GET_UNIT (hkcs2);
|
||||
new_val = hkcs2;
|
||||
break;
|
||||
|
||||
case 007: /* HKAS */
|
||||
hkof = data & AS_OF;
|
||||
old_val = hkof;
|
||||
new_val = hkof = data & AS_OF;
|
||||
break;
|
||||
|
||||
case 010: /* HKDC */
|
||||
hkdc = data & ~DC_MBZ;
|
||||
old_val = hkdc;
|
||||
new_val = hkdc = data & ~DC_MBZ;
|
||||
break;
|
||||
|
||||
case 011: /* spare */
|
||||
hkspr = data;
|
||||
old_val = hkspr;
|
||||
new_val = hkspr = data;
|
||||
if (SC02C) /* SC02C? upd UAE */
|
||||
hkcs1 = PUT_UAE (hkcs1, hkspr & 03);
|
||||
break;
|
||||
|
||||
case 012: /* HKDB */
|
||||
hkdb[0] = data;
|
||||
old_val = hkdb[0];
|
||||
new_val = hkdb[0] = data;
|
||||
break;
|
||||
|
||||
case 013: /* HKMR */
|
||||
hkmr = data & MR_RW;
|
||||
old_val = hkmr;
|
||||
new_val = hkmr = data & MR_RW;
|
||||
break;
|
||||
|
||||
default: /* all others RO */
|
||||
case 014: /* HKEC1 */
|
||||
new_val = old_val = hkmr;
|
||||
break;
|
||||
|
||||
case 015: /* HKEC2 */
|
||||
new_val = old_val = hkmr;
|
||||
break;
|
||||
|
||||
case 016: /* HKMR2 */
|
||||
new_val = old_val = hkmr2;
|
||||
break;
|
||||
|
||||
case 017: /* HKMR3 */
|
||||
new_val = old_val = hkmr3;
|
||||
break;
|
||||
} /* end switch */
|
||||
sim_debug_bits (HKDEB_RWR, &hk_dev, hk_reg_bits[j], old_val, new_val, 1);
|
||||
|
||||
update_hkcs (0, drv); /* update status */
|
||||
return SCPE_OK;
|
||||
|
@ -691,9 +923,8 @@ static uint8 fnc_cyl[16] = {
|
|||
};
|
||||
|
||||
fnc = GET_FNC (hkcs1);
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_OPS))
|
||||
fprintf (sim_deb, ">>HK%d strt: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
sim_debug (HKDEB_OPS, &hk_dev, ">>HK%d strt: fnc=%s, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, hk_funcs[fnc], hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
uptr = hk_dev.units + drv; /* get unit */
|
||||
if (fnc != FNC_NOP) /* !nop, clr msg sel */
|
||||
hkmr = hkmr & ~MR_MS;
|
||||
|
@ -730,7 +961,7 @@ switch (fnc) { /* case on function */
|
|||
|
||||
/* Instantaneous functions (unit may be busy, can't schedule thread) */
|
||||
|
||||
case FNC_NOP: /* no operation */
|
||||
case FNC_NOP: /* no operation/select drive */
|
||||
hkmr2 = hk_rdmr2 (GET_MS (hkmr)); /* get serial msgs */
|
||||
hkmr3 = hk_rdmr3 (GET_MS (hkmr));
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
|
@ -804,6 +1035,7 @@ uint16 comp;
|
|||
|
||||
drv = (uint32) (uptr - hk_dev.units); /* get drv number */
|
||||
fnc = uptr->FNC & CS1_M_FNC; /* get function */
|
||||
sim_debug (HKDEB_TRC, &hk_dev, "hk_svc(HK%d, fnc=%s)\n", drv, hk_funcs[fnc]);
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
/* Fast commands - start spindle only provides one interrupt
|
||||
|
@ -985,27 +1217,37 @@ return SCPE_OK;
|
|||
|
||||
void update_hkcs (int32 flag, int32 drv)
|
||||
{
|
||||
int32 i;
|
||||
int32 i, old_hkcs1 = hkcs1, old_hkcs2 = hkcs2;
|
||||
|
||||
sim_debug (HKDEB_TRC, &hk_dev, "update_hkcs(flag=0%o, drv=%d)\n", flag, drv);
|
||||
update_hkds (drv); /* upd drv status */
|
||||
if (flag & CS1_DONE) /* clear go */
|
||||
hkcs1 = hkcs1 & ~CS1_GO;
|
||||
if (hkcs1 & CS1_IE) { /* intr enable? */
|
||||
if (((flag & CS1_DONE) && ((hkcs1 & CS1_DONE) == 0)) ||
|
||||
((flag & CS1_DI) && (hkcs1 & CS1_DONE))) /* done 0->1 or DI? */
|
||||
SET_INT (HK);
|
||||
}
|
||||
else CLR_INT (HK);
|
||||
hkcs1 = (hkcs1 & (CS1_DT|CS1_UAE|CS1_DONE|CS1_IE|CS1_SPA|CS1_FNC|CS1_GO)) | flag;
|
||||
if (hkcs1 & CS1_DONE) /* done? clear GO */
|
||||
hkcs1 = hkcs1 & ~CS1_GO;
|
||||
for (i = 0; i < HK_NUMDR; i++) { /* if ATA, set DI */
|
||||
if (hkds[i] & DS_ATA) hkcs1 = hkcs1 | CS1_DI;
|
||||
if (hkds[i] & DS_ATA)
|
||||
hkcs1 = hkcs1 | CS1_DI;
|
||||
}
|
||||
if (hker[drv] | (hkcs1 & (CS1_PAR | CS1_CTO)) | /* if err, set ERR */
|
||||
(hkcs2 & CS2_ERR)) hkcs1 = hkcs1 | CS1_ERR;
|
||||
if ((flag & CS1_DONE) && /* set done && debug? */
|
||||
(DEBUG_PRI (hk_dev, HKDEB_OPS)))
|
||||
fprintf (sim_deb, ">>HK%d done: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, GET_FNC (hkcs1), hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
if (hker[drv] || (hkcs1 & (CS1_PAR | CS1_CTO)) || (hkcs2 & CS2_ERR))
|
||||
hkcs1 = hkcs1 | CS1_ERR; /* if err, set ERR */
|
||||
if (hkcs1 & CS1_IE) { /* intr enable? */
|
||||
if (((hkcs1 & CS1_DONE) && ((old_hkcs1 & CS1_DONE) == 0)) ||
|
||||
((hkcs1 & CS1_DI) && (hkcs1 & CS1_DONE))) { /* done 0->1 or DI&done? */
|
||||
sim_debug (HKDEB_INT, &hk_dev, "update_hkcs(SET_INT)\n");
|
||||
SET_INT (HK);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sim_debug (HKDEB_INT, &hk_dev, "update_hkcs(CLR_INT)\n");
|
||||
CLR_INT (HK);
|
||||
}
|
||||
if (old_hkcs1 != hkcs1)
|
||||
sim_debug_bits (HKDEB_OPS, &hk_dev, hk_cs1_bits, old_hkcs1, hkcs1, 1);
|
||||
if (old_hkcs2 != hkcs2)
|
||||
sim_debug_bits (HKDEB_OPS, &hk_dev, hk_cs2_bits, old_hkcs2, hkcs2, 1);
|
||||
if (flag & CS1_DONE) /* set done */
|
||||
sim_debug (HKDEB_OPS, &hk_dev, ">>HK%d done: fnc=%s, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, hk_funcs[GET_FNC (hkcs1)], hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1013,10 +1255,13 @@ return;
|
|||
|
||||
void update_hkds (int32 drv)
|
||||
{
|
||||
int old_ds = hkds[drv];
|
||||
|
||||
if (hk_unit[drv].flags & UNIT_DIS) { /* disabled? */
|
||||
hkds[drv] = hker[drv] = 0; /* all clear */
|
||||
return;
|
||||
}
|
||||
sim_debug (HKDEB_TRC, &hk_dev, "update_hkds(drv=%d)\n", drv);
|
||||
hkds[drv] = (hkds[drv] & (DS_VV | DS_PIP | DS_ATA)) | DS_VLD | DS_DRA;
|
||||
if (hk_unit[drv].flags & UNIT_ATT) { /* attached? */
|
||||
if (!sim_is_active (&hk_unit[drv])) /* not busy? */
|
||||
|
@ -1034,6 +1279,8 @@ else {
|
|||
}
|
||||
if (hk_unit[drv].flags & UNIT_RK07)
|
||||
hkds[drv] = hkds[drv] | DS_DT;
|
||||
if (old_ds != hkds[drv])
|
||||
sim_debug_bits (HKDEB_TRC, &hk_dev, hk_ds_bits, old_ds, hkds[drv], 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1041,6 +1288,7 @@ return;
|
|||
|
||||
void hk_cmderr (int32 err, int32 drv)
|
||||
{
|
||||
sim_debug (HKDEB_TRC, &hk_dev, "update_hkds(drv=%d, err=%d)\n", drv, err);
|
||||
hker[drv] = hker[drv] | err; /* set error */
|
||||
hkds[drv] = hkds[drv] | DS_ATA; /* set attn */
|
||||
update_hkcs (CS1_DONE, drv); /* set done */
|
||||
|
@ -1158,6 +1406,7 @@ t_stat hk_reset (DEVICE *dptr)
|
|||
int32 i;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (HKDEB_TRC, &hk_dev, "hk_reset()\n");
|
||||
hkcs1 = CS1_DONE; /* set done */
|
||||
hkcs2 = CS2_IR; /* clear state */
|
||||
hkmr = hkmr2 = hkmr3 = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue