diff --git a/PDP11/pdp11_rp.c b/PDP11/pdp11_rp.c index 89339dc3..a98463ff 100644 --- a/PDP11/pdp11_rp.c +++ b/PDP11/pdp11_rp.c @@ -131,6 +131,29 @@ #define CS1_DVA 04000 /* drive avail */ #define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC) +static const char *rp_fname[CS1_N_FNC] = { + "NOP", "UNLD", "SEEK", "RECAL", "DCLR", "RLS", "OFFS", "RETN", + "PRESET", "PACK", "12", "13", "SEARCH", "15", "16", "17", + "20", "21", "22", "23", "WRCHK", "25", "26", "27", + "WRITE", "WRHDR", "32", "33", "READ", "RDHDR", "36", "37" + }; + +BITFIELD rp_cs1_bits[] = { + BIT(GO), /* Go */ + BITFNAM(FUNC,5,rp_fname), /* Function Code */ + BIT(IE), /* Interrupt Enable */ + BIT(RDY), /* Drive Ready */ + BIT(A16), /* Bus Address Extension Bit 16 */ + BIT(A17), /* Bus Address Extension Bit 17 */ + BIT(PSEL), /* Port Select */ + BIT(DVA), /* Drive Available */ + BITNCF(1), /* 12 Reserved */ + BIT(MCPE), /* Massbus Control Parity Error */ + BIT(TRE), /* Transfer Error */ + BIT(SC), /* Special Condition */ + ENDBITS +}; + /* RPDS, RMDS - drive status - offset 1 */ #define RP_DS_OF 1 @@ -148,6 +171,22 @@ #define DS_ATA 0100000 /* attention active */ #define DS_MBZ 0000076 +BITFIELD rp_ds_bits[] = { + BIT(OM), /* offset mode */ + BITF(MBZ,5), /* must be zero */ + BIT(VV), /* volume valid */ + BIT(RDY), /* drive ready */ + BIT(DPR), /* drive present */ + BIT(PGM), /* programmable NI */ + BIT(LST), /* write clk fail NI */ + BIT(WRL), /* ECC hard err NI */ + BIT(MOL), /* hdr comp err NI */ + BIT(PIP), /* hdr CRC err NI */ + BIT(ERR), /* addr ovflo err */ + BIT(ATA), /* invalid addr err */ + ENDBITS +}; + /* RPER1, RMER1 - error status 1 - offset 2 */ #define RP_ER1_OF 2 @@ -169,17 +208,55 @@ #define ER1_UNS 0040000 /* drive unsafe */ #define ER1_DCK 0100000 /* data check NI */ +BITFIELD rp_er1_bits[] = { + BIT(ILF), /* Illegal Function */ + BIT(ILR), /* Illegal Register */ + BIT(RMR), /* reg mod refused */ + BIT(PAR), /* parity err */ + BIT(FER), /* format err NI */ + BIT(WCF), /* write clk fail NI */ + BIT(ECH), /* ECC hard err NI */ + BIT(HCE), /* hdr comp err NI */ + BIT(HCR), /* hdr CRC err NI */ + BIT(AOE), /* addr ovflo err */ + BIT(IAE), /* invalid addr err */ + BIT(WLE), /* write lock err */ + BIT(DTE), /* drive time err NI */ + BIT(OPI), /* op incomplete */ + BIT(UNS), /* drive unsafe */ + BIT(DCK), /* data check NI */ + ENDBITS +}; + /* RPMR, RMMR - maintenace register - offset 3*/ #define RP_MR_OF 3 #define RM_MR_OF (3 + RM_OF) +BITFIELD rp_mr_bits[] = { + BITF(MR,16), /* Maintenance Register */ + ENDBITS +}; + /* RPAS, RMAS - attention summary - offset 4 */ #define RP_AS_OF 4 #define RM_AS_OF (4 + RM_OF) #define AS_U0 0000001 /* unit 0 flag */ +BITFIELD rp_as_bits[] = { + BIT(ATA0), /* Drive 0 Attention */ + BIT(ATA1), /* Drive 1 Attention */ + BIT(ATA2), /* Drive 2 Attention */ + BIT(ATA3), /* Drive 3 Attention */ + BIT(ATA4), /* Drive 4 Attention */ + BIT(ATA5), /* Drive 5 Attention */ + BIT(ATA6), /* Drive 6 Attention */ + BIT(ATA7), /* Drive 7 Attention */ + BITNCF(8), /* 08:15 Reserved */ + ENDBITS +}; + /* RPDA, RMDA - sector/track - offset 5 */ #define RP_DA_OF 5 @@ -192,22 +269,52 @@ #define GET_SC(x) (((x) >> DA_V_SC) & DA_M_SC) #define GET_SF(x) (((x) >> DA_V_SF) & DA_M_SF) +BITFIELD rp_da_bits[] = { + BITF(SA,5), /* Sector Address */ + BITNCF(3), /* 05:07 Reserved */ + BITF(TA,5), /* Track Address */ + BITNCF(3), /* 13:15 Reserved */ + ENDBITS +}; + /* RPDT, RMDT - drive type - offset 6 */ #define RP_DT_OF 6 #define RM_DT_OF (6 + RM_OF) +BITFIELD rp_dt_bits[] = { + BITF(DT,9), /* Drive Type */ + BITNCF(2), /* 09:10 Reserved */ + BIT(DRQ), /* Drive Request Required */ + BITNCF(1), /* 12 Reserved */ + BIT(MOH), /* Moving Head */ + BITNCF(2), /* 14:15 Reserved */ + ENDBITS +}; + /* RPLA, RMLA - look ahead register - offset 7 */ #define RP_LA_OF 7 #define RM_LA_OF (7 + RM_OF) #define LA_V_SC 6 /* sector pos */ +BITFIELD rp_la_bits[] = { + BITNCF(6), /* 00:05 Reserved */ + BITF(SC,5), /* sector pos */ + BITNCF(5), /* 12:15 Reserved */ + ENDBITS +}; + /* RPSN, RMSN - serial number - offset 8 */ #define RP_SN_OF 8 #define RM_SN_OF (8 + RM_OF) +BITFIELD rp_sn_bits[] = { + BITF(SN,16), /* Serial Number */ + ENDBITS +}; + /* RPOF, RMOF - offset register - offset 9 */ #define RP_OF_OF 9 @@ -217,6 +324,17 @@ #define OF_F22 0010000 /* format NI */ #define OF_MBZ 0161400 +BITFIELD rp_of_bits[] = { + BITNCF(7), /* 00:06 Reserved */ + BIT(OFFDIR), /* Offset Direction */ + BITNCF(2), /* 08:09 Reserved */ + BIT(HCI), /* hdr comp inh NI */ + BIT(ECI), /* ECC inh NI */ + BIT(FMT), /* format NI */ + BITNCF(3), /* 13:15 Reserved */ + ENDBITS +}; + /* RPDC, RMDC - desired cylinder - offset 10 */ #define RP_DC_OF 10 @@ -228,34 +346,125 @@ #define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \ GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs)) +BITFIELD rp_dc_bits[] = { + BITF(DC,10), /* Offset Direction */ + BITNCF(6), /* 10:15 Unused */ + ENDBITS +}; + /* RPCC - current cylinder - offset 11 RMHR - holding register - offset 11 */ #define RP_CC_OF 11 #define RM_HR_OF (11 + RM_OF) +BITFIELD rp_cc_bits[] = { + BITF(CC,16), /* current cylinder */ + ENDBITS +}; + /* RPER2 - error status 2 - drive unsafe conditions - unimplemented - offset 12 RMMR2 - maintenance register - unimplemented - offset 12 */ #define RP_ER2_OF 12 #define RM_MR2_OF (12 + RM_OF) +BITFIELD rp_er2_bits[] = { + BITNCF(3), /* 00:02 Unused */ + BIT(DPE), /* data parity error */ + BITNCF(3), /* 04:06 Unused */ + BIT(DVC), /* device check */ + BITNCF(2), /* 08:09 Unused */ + BIT(LBC), /* Loss of bit clock */ + BIT(LSC), /* Loss of system clock */ + BIT(IVC), /* Invalid Command */ + BIT(OPE), /* Operator Plug Error */ + BIT(SKI), /* Seek Incomplete */ + BIT(BSE), /* Bad Sector Error */ + ENDBITS +}; + /* RPER3 - error status 3 - more unsafe conditions - unimplemented - offset 13 RMER2 - error status 2 - unimplemented - offset 13 */ #define RP_ER3_OF 13 #define RM_ER2_OF (13 + RM_OF) +BITFIELD rp_er3_bits[] = { + BITNCF(3), /* 00:02 Unused */ + BIT(DPE), /* data parity error */ + BITNCF(3), /* 04:06 Unused */ + BIT(DVC), /* device check */ + BITNCF(2), /* 08:09 Unused */ + BIT(LBC), /* Loss of bit clock */ + BIT(LSC), /* Loss of system clock */ + BIT(IVC), /* Invalid Command */ + BIT(OPE), /* Operator Plug Error */ + BIT(SKI), /* Seek Incomplete */ + BIT(BSE), /* Bad Sector Error */ + ENDBITS +}; + /* RPEC1, RMEC1 - ECC status 1 - unimplemented - offset 14 */ #define RP_EC1_OF 14 #define RM_EC1_OF (14 + RM_OF) +BITFIELD rp_ec1_bits[] = { + BITF(P,13), /* ECC Position Register */ + BITNCF(3), /* 13:15 Unused */ + ENDBITS +}; + /* RPEC2, RMEC1 - ECC status 2 - unimplemented - offset 15 */ #define RP_EC2_OF 15 #define RM_EC2_OF (15 + RM_OF) +BITFIELD rp_ec2_bits[] = { + BITF(PAT,11), /* ECC Pattern Register */ + BITNCF(5), /* 11:15 Unused */ + ENDBITS +}; + +BITFIELD *rp_reg_bits[] = { + rp_cs1_bits, + rp_ds_bits, + rp_er1_bits, + rp_mr_bits, + rp_as_bits, + rp_da_bits, + rp_dt_bits, + rp_la_bits, + rp_sn_bits, + rp_of_bits, + rp_dc_bits, + rp_cc_bits, + rp_er2_bits, + rp_er3_bits, + rp_ec1_bits, + rp_ec2_bits, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rp_cs1_bits, + rp_ds_bits, + rp_er1_bits, + rp_mr_bits, + rp_as_bits, + rp_da_bits, + rp_dt_bits, + rp_la_bits, + rp_sn_bits, + rp_of_bits, + rp_dc_bits, + rp_cc_bits, + rp_er2_bits, + rp_er3_bits, + rp_ec1_bits, + rp_ec2_bits, +}; + + + /* This controller supports many different disk drive types: type #sectors/ #surfaces/ #cylinders/ @@ -357,14 +566,6 @@ uint16 rpec2[RP_NUMDR] = { 0 }; /* ECC correction 2 */ int32 rp_stopioe = 1; /* stop on error */ int32 rp_swait = 26; /* seek time */ int32 rp_rwait = 10; /* rotate time */ -static const char *rp_fname[CS1_N_FNC] = { - "NOP", "UNLD", "SEEK", "RECAL", "DCLR", "RLS", "OFFS", "RETN", - "PRESET", "PACK", "12", "13", "SCH", "15", "16", "17", - "20", "21", "22", "23", "WRCHK", "25", "26", "27", - "WRITE", "WRHDR", "32", "33", "READ", "RDHDR", "36", "37" - }; - -extern FILE *sim_deb; t_stat rp_mbrd (int32 *data, int32 ofs, int32 drv); t_stat rp_mbwr (int32 data, int32 ofs, int32 drv); @@ -571,6 +772,7 @@ char *rp_regnam[] = "62", /* 62 */ "63", /* 63 */ }; + /* Massbus register read */ t_stat rp_mbrd (int32 *data, int32 ofs, int32 drv) @@ -672,7 +874,8 @@ switch (ofs) { /* decode offset */ return MBE_NXR; } -sim_debug(DBG_REG, &rp_dev, "rp_mbrd(drv=%d, %s=0x%08X, )\n", drv, rp_regnam[ofs], val); +sim_debug(DBG_REG, &rp_dev, "rp_mbrd(drv=%d(%s), %s=0x%X)\n", drv, drv_tab[dtype].name, rp_regnam[ofs], val); +sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], val, val, 1); *data = val; return SCPE_OK; @@ -682,12 +885,12 @@ return SCPE_OK; t_stat rp_mbwr (int32 data, int32 ofs, int32 drv) { -int32 dtype; -UNIT *uptr; +uint32 old_reg; +UNIT *uptr = rp_dev.units + drv; /* get unit */ +int32 dtype = GET_DTYPE (uptr->flags); /* get drive type */ -sim_debug(DBG_REG, &rp_dev, "rp_mbwr(drv=%d, %s=0x%08X)\n", drv, rp_regnam[ofs], data); +sim_debug(DBG_REG, &rp_dev, "rp_mbwr(drv=%d(%s), %s=0x%X)\n", drv, drv_tab[dtype].name, rp_regnam[ofs], data); -uptr = rp_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) /* nx disk */ return MBE_NXD; if ((ofs != RP_AS_OF) && sim_is_active (uptr)) { /* unit busy? */ @@ -696,7 +899,6 @@ if ((ofs != RP_AS_OF) && sim_is_active (uptr)) { /* unit busy? */ return SCPE_OK; } rmhr[drv] = data; /* save write */ -dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */ ofs = ofs + RM_OF; @@ -704,33 +906,46 @@ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */ switch (ofs) { /* decode PA<5:1> */ case RP_CS1_OF: case RM_CS1_OF: /* RPCS1 */ + old_reg = rpcs1[drv]; rpcs1[drv] = data & CS1_RW; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpcs1[drv], 1); if (data & CS1_GO) /* start op */ return rp_go (drv); break; case RP_DA_OF: case RM_DA_OF: /* RPDA */ + old_reg = rpds[drv]; rpda[drv] = data & ~DA_MBZ; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpds[drv], 1); break; case RP_AS_OF: case RM_AS_OF: /* RPAS */ + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], data, data, 1); rp_clr_as (data); break; case RP_MR_OF: case RM_MR_OF: /* RPMR */ + old_reg = rpmr[drv]; rpmr[drv] = data; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpmr[drv], 1); break; case RP_OF_OF: case RM_OF_OF: /* RPOF */ + old_reg = rpof[drv]; rpof[drv] = data & ~OF_MBZ; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpof[drv], 1); break; case RP_DC_OF: case RM_DC_OF: /* RPDC */ + old_reg = rpdc[drv]; rpdc[drv] = data & ~DC_MBZ; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpdc[drv], 1); break; case RM_MR2_OF: /* RMMR2 */ + old_reg = rmmr2[drv]; rmmr2[drv] = data; + sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rmmr2[drv], 1); break; case RP_ER1_OF: case RM_ER1_OF: /* RPER1 */ @@ -758,17 +973,17 @@ return SCPE_OK; t_stat rp_go (int32 drv) { -int32 dc, fnc, dtype, t; -UNIT *uptr; +int32 dc, fnc, t; +DEVICE *dptr = &rp_dev; +UNIT *uptr = dptr->units + drv; /* get unit */ +int32 dtype = GET_DTYPE (uptr->flags); /* get drive type */ -sim_debug(DBG_REQ, &rp_dev, "rp_go(drv=%d)\n", drv); +sim_debug(DBG_REQ, dptr, "rp_go(drv=%d(%s))\n", drv, drv_tab[dtype].name); fnc = GET_FNC (rpcs1[drv]); /* get function */ -sim_debug(DBG_REQ, &rp_dev, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n", +sim_debug(DBG_REQ, dptr, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n", drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]); -uptr = rp_dev.units + drv; /* get unit */ rp_clr_as (AS_U0 << drv); /* clear attention */ -dtype = GET_DTYPE (uptr->flags); /* get drive type */ dc = rpdc[drv]; /* assume seek, sch */ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */ rp_set_er (ER1_ILF, drv); /* not allowed */ @@ -778,14 +993,17 @@ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */ switch (fnc) { /* case on function */ + case FNC_RELEASE: /* port release */ case FNC_DCLR: /* drive clear */ rper1[drv] = rper2[drv] = rper3[drv] = 0; /* clear errors */ rpec2[drv] = 0; /* clear EC2 */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? */ rpmr[drv] = 0; /* clear maint */ else rpec1[drv] = 0; /* RP, clear EC1 */ + rpds[drv] = rpds[drv] & ~DS_ERR; /* Clear ERR */ case FNC_NOP: /* no operation */ - case FNC_RELEASE: /* port release */ + sim_debug (DBG_REQ, dptr, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n", + drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]); return SCPE_OK; case FNC_PRESET: /* read-in preset */ @@ -870,7 +1088,9 @@ return rp_reset (&rp_dev); void rp_io_complete (UNIT *uptr, t_stat status) { -sim_debug(DBG_TRC, &rp_dev, "rp_io_complete(status=%d)\n", status); +DEVICE *dptr = find_dev_from_unit (uptr); + +sim_debug(DBG_TRC, dptr, "rp_io_complete(rp%d, status=%d)\n", (int)(uptr - dptr->units), status); uptr->io_status = status; uptr->io_complete = 1; /* Initiate Bottom End processing */ @@ -888,18 +1108,20 @@ t_stat rp_svc (UNIT *uptr) { int32 i, fnc, dtype, drv, err; int32 wc, abc, awc, mbc, da; +DEVICE *dptr = find_dev_from_unit (uptr); +DIB *dibp = (DIB *) dptr->ctxt; dtype = GET_DTYPE (uptr->flags); /* get drive type */ drv = (int32) (uptr - rp_dev.units); /* get drv number */ da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD; /* get disk addr */ fnc = GET_FNC (rpcs1[drv]); /* get function */ -sim_debug(DBG_TRC, &rp_dev, "rp_svc(rp%d, %s, dtype=%d, da=%08X, fnc=%d)\n", drv, uptr->io_complete ? "Bottom" : "Top", dtype, da, fnc); +sim_debug(DBG_TRC, dptr, "rp_svc(rp%d(%s), %s, da=0x%X, fnc=%s)\n", drv, drv_tab[dtype].name, uptr->io_complete ? "Bottom" : "Top", da, rp_fname[fnc]); if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* set drive error */ if (fnc >= FNC_XFER) /* xfr? set done */ - mba_set_don (rp_dib.ba); + mba_set_don (dibp->ba); rp_update_ds (DS_ATA, drv); /* set attn */ return (rp_stopioe? SCPE_UNATT: SCPE_OK); } @@ -929,32 +1151,32 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */ case FNC_WRITE: /* write */ if (uptr->flags & UNIT_WPRT) { /* write locked? */ rp_set_er (ER1_WLE, drv); /* set drive error */ - mba_set_exc (rp_dib.ba); /* set exception */ + mba_set_exc (dibp->ba); /* set exception */ rp_update_ds (DS_ATA, drv); /* set attn */ return SCPE_OK; } case FNC_WCHK: /* write check */ case FNC_READ: /* read */ case FNC_READH: /* read headers */ - mbc = mba_get_bc (rp_dib.ba); /* get byte count */ + mbc = mba_get_bc (dibp->ba); /* get byte count */ wc = (mbc + 1) >> 1; /* convert to words */ if ((da + wc) > drv_tab[dtype].size) { /* disk overrun? */ rp_set_er (ER1_AOE, drv); /* set err */ wc = drv_tab[dtype].size - da; /* trim xfer */ mbc = wc << 1; /* trim mb count */ if (da >= drv_tab[dtype].size) { /* none left? */ - mba_set_exc (rp_dib.ba); /* set exception */ + mba_set_exc (dibp->ba); /* set exception */ rp_update_ds (DS_ATA, drv); /* set attn */ break; } } if (fnc == FNC_WRITE) { /* write? */ - abc = mba_rdbufW (rp_dib.ba, mbc, rpxb[drv]);/* get buffer */ + abc = mba_rdbufW (dibp->ba, mbc, rpxb[drv]);/* get buffer */ wc = (abc + 1) >> 1; /* actual # wds */ awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1); for (i = wc; i < awc; i++) /* fill buf */ rpxb[drv][i] = 0; - sim_disk_data_trace (uptr, (void *)rpxb[drv], da/RP_NUMWD, awc, "sim_disk_wrsect-WR", DBG_DAT & rp_dev.dctrl, DBG_REQ); + sim_disk_data_trace (uptr, (void *)rpxb[drv], da/RP_NUMWD, awc, "sim_disk_wrsect-WR", DBG_DAT & dptr->dctrl, DBG_REQ); sim_disk_wrsect_a (uptr, da/RP_NUMWD, (void *)rpxb[drv], NULL, awc/RP_NUMWD, rp_io_complete); return SCPE_OK; } /* end if wr */ @@ -965,7 +1187,7 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */ } /* end if read */ case FNC_WRITEH: /* write headers stub */ - mba_set_don (rp_dib.ba); /* set done */ + mba_set_don (dibp->ba); /* set done */ rp_update_ds (0, drv); /* update ds */ break; } /* end case func */ @@ -989,18 +1211,18 @@ else { /* Bottom End (After I/O processing) */ case FNC_WCHK: /* write check */ case FNC_READ: /* read */ case FNC_READH: /* read headers */ - mbc = mba_get_bc (rp_dib.ba); /* get byte count */ + mbc = mba_get_bc (dibp->ba); /* get byte count */ wc = (mbc + 1) >> 1; /* convert to words */ if (fnc == FNC_WRITE) { /* write? */ } /* end if wr */ else { /* read or wchk */ awc = uptr->sectsread * RP_NUMWD; - sim_disk_data_trace (uptr, (uint8*)rpxb[drv], da/RP_NUMWD, awc << 1, "sim_disk_rdsect", DBG_DAT & rp_dev.dctrl, DBG_REQ); + sim_disk_data_trace (uptr, (uint8*)rpxb[drv], da/RP_NUMWD, awc << 1, "sim_disk_rdsect", DBG_DAT & dptr->dctrl, DBG_REQ); for (i = awc; i < wc; i++) /* fill buf */ rpxb[drv][i] = 0; if (fnc == FNC_WCHK) /* write check? */ - mba_chbufW (rp_dib.ba, mbc, rpxb[drv]); /* check vs mem */ - else mba_wrbufW (rp_dib.ba, mbc, rpxb[drv]);/* store in mem */ + mba_chbufW (dibp->ba, mbc, rpxb[drv]); /* check vs mem */ + else mba_wrbufW (dibp->ba, mbc, rpxb[drv]);/* store in mem */ } /* end if read */ da = da + wc + (RP_NUMWD - 1); if (da >= drv_tab[dtype].size) @@ -1014,20 +1236,20 @@ else { /* Bottom End (After I/O processing) */ if (err != 0) { /* error? */ rp_set_er (ER1_PAR, drv); /* set drive error */ - mba_set_exc (rp_dib.ba); /* set exception */ + mba_set_exc (dibp->ba); /* set exception */ rp_update_ds (DS_ATA, drv); perror ("RP I/O error"); return SCPE_IOERR; } - mba_set_don (rp_dib.ba); /* set done */ + mba_set_don (dibp->ba); /* set done */ rp_update_ds (0, drv); /* update ds */ break; } /* end case func */ } rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY; /* change drive status */ -sim_debug (DBG_REQ, &rp_dev, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n", +sim_debug (DBG_REQ, dptr, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n", drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]); return SCPE_OK; } @@ -1049,14 +1271,15 @@ void rp_clr_as (int32 mask) { uint32 i, as; -sim_debug(DBG_TRC, &rp_dev, "rp_clr_as(mask=0x%X)\n", mask); - for (i = as = 0; i < RP_NUMDR; i++) { if (mask & (AS_U0 << i)) rpds[i] &= ~DS_ATA; if (rpds[i] & DS_ATA) as = 1; } + +sim_debug(DBG_TRC, &rp_dev, "rp_clr_as(mask=0x%X, as=0x%X)\n", mask, as); + mba_upd_ata (rp_dib.ba, as); return; } @@ -1065,7 +1288,7 @@ return; void rp_update_ds (int32 flag, int32 drv) { -sim_debug(DBG_TRC, &rp_dev, "rp_update_ds(rp%d, flag=0x%X)\n", drv, flag); +uint16 o_ds = rpds[drv]; if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0; @@ -1079,6 +1302,12 @@ else rpds[drv] = rpds[drv] & ~DS_ERR; rpds[drv] = rpds[drv] | flag; if (flag & DS_ATA) mba_upd_ata (rp_dib.ba, 1); + +if (o_ds != rpds[drv]) { + sim_debug(DBG_TRC, &rp_dev, "rp_update_ds(rp%d, flag=0x%X, ds=0x%X)\n", drv, flag, rpds[drv]); + sim_debug_bits(DBG_TRC, &rp_dev, rp_ds_bits, o_ds, rpds[drv], 1); + } + return; } @@ -1091,9 +1320,9 @@ UNIT *uptr; sim_debug(DBG_TRC, dptr, "rp_reset()\n"); -mba_set_enbdis (MBA_RP, rp_dev.flags & DEV_DIS); +mba_set_enbdis (MBA_RP, dptr->flags & DEV_DIS); for (i = 0; i < RP_NUMDR; i++) { - uptr = rp_dev.units + i; + uptr = dptr->units + i; sim_cancel (uptr); uptr->CYL = 0; if (uptr->flags & UNIT_ATT) @@ -1128,6 +1357,7 @@ t_stat rp_attach (UNIT *uptr, char *cptr) { int32 drv, i, p; t_stat r; +DEVICE *dptr = find_dev_from_unit (uptr); uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16), @@ -1135,7 +1365,7 @@ r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16), drv_tab[GET_DTYPE (uptr->flags)].name, drv_tab[GET_DTYPE (uptr->flags)].sect, 0); if (r != SCPE_OK) /* error? */ return r; -drv = (int32) (uptr - rp_dev.units); /* get drv number */ +drv = (int32) (uptr - dptr->units); /* get drv number */ rpds[drv] = DS_MOL | DS_RDY | DS_DPR | /* upd drv status */ ((uptr->flags & UNIT_WPRT)? DS_WRL: 0); rper1[drv] = 0; @@ -1159,12 +1389,12 @@ return SCPE_OK; t_stat rp_detach (UNIT *uptr) { int32 drv; +DEVICE *dptr = find_dev_from_unit (uptr); if (!(uptr->flags & UNIT_ATT)) /* attached? */ return SCPE_OK; -drv = (int32) (uptr - rp_dev.units); /* get drv number */ +drv = (int32) (uptr - dptr->units); /* get drv number */ rpds[drv] = rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OFM); -rp_update_ds (DS_ATA, drv); /* request intr */ return sim_disk_detach (uptr); } @@ -1226,7 +1456,7 @@ t_stat rp_boot (int32 unitno, DEVICE *dptr) int32 i; extern int32 saved_PC; extern uint16 *M; -UNIT *uptr = rp_dev.units + unitno; +UNIT *uptr = dptr->units + unitno; for (i = 0; i < BOOT_LEN; i++) M[(BOOT_START >> 1) + i] = boot_rom[i];