diff --git a/PDP10/ka10_cpu.c b/PDP10/ka10_cpu.c index 62cd787..471efa2 100644 --- a/PDP10/ka10_cpu.c +++ b/PDP10/ka10_cpu.c @@ -174,7 +174,7 @@ char page_fault; /* Page fail */ uint32 ac_stack; /* Register stack pointer */ uint32 pag_reload; /* Page reload pointer */ uint64 fault_data; /* Fault data from last fault */ -int trap_flag; /* Last instruction was trapped */ +int trap_flag; /* In trap cycle */ int last_page; /* Last page mapped */ int modify; /* Modify cycle */ char xct_flag; /* XCT flags */ @@ -201,7 +201,7 @@ uint16 ofa; /* Output fault address */ uint32 qua_time; /* Quantum clock value */ #endif -char dev_irq[128]; /* Pending irq by device */ +uint8 dev_irq[128]; /* Pending irq by device */ t_stat (*dev_tab[128])(uint32 dev, uint64 *data); int (*dev_irqv[128])(uint32 dev, int addr); t_stat rtc_srv(UNIT * uptr); @@ -658,8 +658,16 @@ int opflags[] = { #define AOB(x) (x + 01000001LL) #define SOB(x) (x + 0777776777777LL) #endif +#if ITS #define QITS (cpu_unit[0].flags & UNIT_ITSPAGE) +#else +#define QITS 0 +#endif +#if BBN #define QBBN (cpu_unit[0].flags & UNIT_BBNPAGE) +#else +#define QBBN 0 +#endif /* * Set device to interrupt on a given level 1-7 @@ -670,7 +678,8 @@ void set_interrupt(int dev, int lvl) { if (lvl) { dev_irq[dev>>2] = 0200 >> lvl; pi_pending = 1; - sim_debug(DEBUG_IRQ, &cpu_dev, "set irq %o %o\n", dev & 0774, lvl); + sim_debug(DEBUG_IRQ, &cpu_dev, "set irq %o %o %03o %03o %03o\n", + dev & 0774, lvl, PIE, PIR, PIH); } } @@ -693,11 +702,14 @@ int check_irq_level() { if (xct_flag != 0) return 0; check_apr_irq(); + /* If not enabled, check if any pending Processor IRQ */ if (pi_enable == 0) { if (PIR != 0) { pi_enc = 1; for(lvl = 0100; lvl != 0; lvl >>= 1) { + if (lvl & PIH) + break; if (PIR & lvl) return 1; pi_enc++; @@ -737,6 +749,7 @@ void restore_pi_hold() { for(lvl = 0100; lvl != 0; lvl >>= 1) { if (lvl & PIH) { PIR &= ~lvl; + sim_debug(DEBUG_IRQ, &cpu_dev, "restore irq %o %03o\n", lvl, PIH); PIH &= ~lvl; break; } @@ -790,7 +803,7 @@ t_stat dev_pi(uint32 dev, uint64 *data) { parity_irq = 1; if (res & 0100000) parity_irq = 0; - sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data); + sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data); break; case CONI: @@ -802,7 +815,7 @@ t_stat dev_pi(uint32 dev, uint64 *data) { #endif res |= (parity_irq << 15); *data = res; - sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data); + sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data); break; case DATAO: @@ -943,10 +956,15 @@ t_stat dev_apr(uint32 dev, uint64 *data) { clk_flg = 0; clr_interrupt(4); } - if (res & 0002000) + if (res & 0002000) { clk_en = 1; - if (res & 0004000) + if (clk_flg) + set_interrupt(4, clk_irq); + } + if (res & 0004000) { clk_en = 0; + clr_interrupt(4); + } if (res & 0040000) timer_irq = 1; if (res & 0100000) @@ -956,7 +974,7 @@ t_stat dev_apr(uint32 dev, uint64 *data) { if (res & 0400000) timer_flg = 0; check_apr_irq(); - sim_debug(DEBUG_CONI, &cpu_dev, "CONO APR %012llo\n", *data); + sim_debug(DEBUG_CONO, &cpu_dev, "CONO APR %012llo\n", *data); break; case DATAO: @@ -1048,14 +1066,11 @@ void check_apr_irq() { if (pi_enable && apr_irq) { int flg = 0; clr_interrupt(0); - clr_interrupt(4); flg |= ((FLAGS & OVR) != 0) & ov_irq; flg |= ((FLAGS & FLTOVR) != 0) & fov_irq; flg |= nxm_flag | mem_prot | push_ovf; if (flg) set_interrupt(0, apr_irq); - if (clk_en & clk_flg) - set_interrupt(4, clk_irq); } } @@ -1082,7 +1097,6 @@ t_stat dev_apr(uint32 dev, uint64 *data) { res = *data; clk_irq = apr_irq = res & 07; clr_interrupt(0); - clr_interrupt(4); if (res & 010) FLAGS &= ~OVR; if (res & 020) @@ -1095,12 +1109,19 @@ t_stat dev_apr(uint32 dev, uint64 *data) { fov_irq = 1; if (res & 0400) fov_irq = 0; - if (res & 01000) + if (res & 0001000) { clk_flg = 0; - if (res & 02000) + clr_interrupt(4); + } + if (res & 0002000) { clk_en = 1; - if (res & 04000) + if (clk_flg) + set_interrupt(4, clk_irq); + } + if (res & 0004000) { clk_en = 0; + clr_interrupt(4); + } if (res & 010000) nxm_flag = 0; if (res & 020000) @@ -1203,7 +1224,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; page_fault = 1; -fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5); +//fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5); return !wr; } return 1; @@ -1237,7 +1258,7 @@ fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5); (!fetch || (M[*loc] & 00777040000000LL) != 0254040000000LL)) { /* Handle public violation */ fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; -fprintf(stderr, "pub PC=%06o, %012llo\n\r", PC, fault_data); +//fprintf(stderr, "pub PC=%06o, %012llo\n\r", PC, fault_data); page_fault = 1; return fetch; } @@ -1896,7 +1917,7 @@ int flag3; int instr_count = 0; /* Number of instructions to execute */ uint32 IA; #if ITS -char one_p_arm; /* One proceed arm */ +char one_p_arm = 0; /* One proceed arm */ #endif if (sim_step != 0) { @@ -1921,11 +1942,9 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ #if KI | KL page_fault = 0; #endif -#if ITS - one_p_arm = 0; -#endif #if ITS if (QITS) { + one_p_arm = 0; sim_activate(&cpu_unit[1], 10000); qua_time = 0; } @@ -2038,6 +2057,7 @@ no_fetch: /* If there is a interrupt handle it. */ if (pi_rq) { st_pi: + sim_debug(DEBUG_IRQ, &cpu_dev, "trap irq %o %03o %03o \n", pi_enc, PIR, PIH); set_pi_hold(); /* Hold off all lower interrupts */ pi_cycle = 1; pi_rq = 0; @@ -2092,7 +2112,7 @@ st_pi: if (hst_lnt && /*(fm_sel || */PC > 020 && (PC & 0777774) != 0777040 && (PC & 0777700) != 023700 && (PC != 0526772)) { #else - if (hst_lnt && /*(FLAGS & USER) &&*/ PC > 017/* && (PC & 0777774) != 0472174 && */ + if (hst_lnt /*&& (FLAGS & USER) && PC > 017 && (PC & 0777774) != 0472174 && */ /* (PC & 0777700) != 0113700 && (PC != 0527154)*/) { #endif hst_p = hst_p + 1; @@ -2181,7 +2201,7 @@ unasign: AB = ub_ptr | 0424; Mem_write_nopage(); AB |= 1; - MB = (FLAGS << 23) | ((PC + (trap_flag == 0)) & RMASK); + MB = ((uint64)(FLAGS) << 23) | ((PC + (trap_flag == 0)) & RMASK); Mem_write_nopage(); FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); AB = ub_ptr | 0430; @@ -2481,7 +2501,6 @@ dpnorm: case 0124: /* DMOVEM */ AR = get_reg(AC); - MQ = get_reg(AC + 1); /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { MB = AR; @@ -2489,6 +2508,7 @@ dpnorm: goto last; FLAGS |= BYTI; } + MQ = get_reg(AC + 1); if ((FLAGS & BYTI)) { AB = (AB + 1) & RMASK; MB = MQ; @@ -2771,6 +2791,7 @@ dpnorm: goto unasign; case 0247: /* UUO or ITS CIRC instruction */ +#if ITS if (QITS) { BR = AR; AR = get_reg(AC); @@ -2795,7 +2816,7 @@ dpnorm: set_reg(AC+1, MQ); break; } - +#endif /* UUO */ case 0105: case 0106: case 0107: case 0110: case 0111: case 0112: case 0113: @@ -2809,7 +2830,7 @@ unasign: Mem_write(uuo_cycle, 0); AB += 1; #if ITS - if (one_p_arm) { + if (QITS && one_p_arm) { FLAGS |= ONEP; one_p_arm = 0; } @@ -3006,19 +3027,22 @@ ldb_ptr: BR <<= 27; if (SCAD & 0400) { SCAD = 01000 - SCAD; - if (SCAD < 28) { - AD = (BR & (SMASK<<27))? (FMASK<<27|MMASK) : 0; + if (SCAD < 54) { + AD = (BR & (SMASK<<27))? DCMASK : 0; BR = (BR >> SCAD) | (AD << (54 - SCAD)); } else { - BR = 0; + if (SCAD < 64) + BR = (BR & (SMASK<<27))? DCMASK: 0; + else + BR = 0; } } /* Do the addition now */ AR = (AR + BR); /* Set flag1 to sign and make positive */ - if (AR & FPSMASK) { - AR = (AR ^ FPFMASK) + 1; + if (AR & DNMASK) { + AR = (AR ^ DFMASK) + 1; flag1 = 1; } else { flag1 = 0; @@ -3037,21 +3061,21 @@ fxnorm: if ((AR & 00740000000000000000LL) == 0) { SC -= 4; AR <<= 4; } if ((AR & 00600000000000000000LL) == 0) { SC -= 2; AR <<= 2; } if ((AR & 00400000000000000000LL) == 0) { SC -= 1; AR <<= 1; } - if (!nrf && !flag1 && - ((IR & 04) != 0) && ((AR & BIT9) != 0)) { - AR += BIT8; + if (!nrf && ((IR & 04) != 0)) { + AR += BIT9; + AR &= ~MMASK; + if ((AR & FPNMASK) != 0) { SC += 1; AR >>= 1; } nrf = 1; - goto fxnorm; } } - if (flag1) { - AR = (AR ^ FPCMASK) + 1; - } MQ = AR & MMASK; AR >>= 27; if (flag1) { + MQ = (MQ ^ MMASK) + 1; + AR = (AR ^ MMASK); + if (MQ & BIT8) + AR++; AR |= SMASK; - MQ |= SMASK; } } else if (flag1) { AR = BIT9 | SMASK; @@ -3065,6 +3089,7 @@ fxnorm: FLAGS |= OVR|FLTOVR|TRP1; if (!fxu_hold_set) { FLAGS |= FLTUND; + MQ = 0; } check_apr_irq(); } @@ -3074,12 +3099,17 @@ fxnorm: /* FADL FSBL FMPL */ if ((IR & 07) == 1) { SC = (SC + (0777 ^ 26)) & 0777; - if (MQ != 0) { + if ((SC & 0400) != 0) + MQ = 0; + if ((MQ & MMASK) != 0 && MQ != MMASK) { MQ &= MMASK; SC ^= (SC & SMASK) ? 0377 : 0; MQ |= ((uint64)(SC & 0377)) << 27; - } + } else + MQ = 0; } + if ((AR & MMASK) == 0) + AR = 0; /* Handle UFA */ if (IR == 0130) { @@ -3125,8 +3155,7 @@ fxnorm: case 0177: /* FDVRB */ flag1 = 0; SC = (int)((((BR & SMASK) ? 0777 : 0) ^ (BR >> 27)) & 0777); - SC += (int)((((AR & SMASK) ? 0 : 0777) ^ (AR >> 27)) & 0777); - SC = (SC + 0201) & 0777; + SCAD = (int)((((AR & SMASK) ? 0777 : 0) ^ (AR >> 27)) & 0777); if (BR & SMASK) { BR = CM(BR) + 1; flag1 = 1; @@ -3135,6 +3164,7 @@ fxnorm: AR = CM(AR) + 1; flag1 = !flag1; } + SC = (SC + ((0777 ^ SCAD) + 1) + 0201) & 0777; /* Clear exponents */ AR &= MMASK; BR &= MMASK; @@ -3146,26 +3176,29 @@ fxnorm: sac_inh = 1; break; /* Done */ } - BR = (BR << 27) + MQ; + BR = (BR << 28); MB = AR; AR = BR / AR; if (AR != 0) { - if (IR & 04) { - AR ++; - } - if ((AR & BIT8) != 0) { - SC += 1; + if ((AR & BIT7) != 0) { AR >>= 1; + } else { + SC--; } - if (SC >= 0600) + if (IR & 04) { + AR++; + } + AR >>= 1; + while ((AR & BIT9) == 0) { + AR <<= 1; + SC--; + } + if (((SC & 0400) != 0) ^ ((SC & 0200) != 0) || SC == 0600) fxu_hold_set = 1; - if (flag1) { - AR = (AR ^ MMASK) + 1; - AR |= SMASK; - } } else if (flag1) { AR = SMASK | BIT9; SC++; + flag1 = 0; } else { AR = 0; SC = 0; @@ -3177,13 +3210,16 @@ fxnorm: } check_apr_irq(); } + if (flag1) { + AR = ((AR ^ MMASK) + 1) & MMASK; + AR |= SMASK; + } SCAD = SC ^ ((AR & SMASK) ? 0377 : 0); - AR &= SMASK|MMASK; AR |= ((uint64)(SCAD & 0377)) << 27; break; case 0171: /* FDVL */ - flag1 = 0; + flag1 = flag3 = 0; SC = (int)((((BR & SMASK) ? 0777 : 0) ^ (BR >> 27)) & 0777); SC += (int)((((AR & SMASK) ? 0 : 0777) ^ (AR >> 27)) & 0777); SC = (SC + 0201) & 0777; @@ -3194,6 +3230,7 @@ fxnorm: if (MQ == 0) BR = BR + 1; flag1 = 1; + flag3 = 1; } MQ &= MMASK; if (AR & SMASK) { @@ -3218,6 +3255,7 @@ fxnorm: if (BR < AR) { BR <<= 1; SC--; + FE--; } for (SCAD = 0; SCAD < 27; SCAD++) { AD <<= 1; @@ -3232,10 +3270,15 @@ fxnorm: SC++; if (AR != 0) { if ((AR & BIT8) != 0) { - SC += 1; + SC++; + FE++; AR >>= 1; } - if (SC >= 0600) + while ((AR & BIT9) == 0) { + AR <<= 1; + SC--; + } + if (((SC & 0400) != 0) ^ ((SC & 0200) != 0)) fxu_hold_set = 1; if (flag1) { AR = (AR ^ MMASK) + 1; @@ -3261,14 +3304,18 @@ fxnorm: if (MQ != 0) { MQ &= MMASK; - if (SC & 0400) { - FE--; + if (flag3) { + MQ = (MQ ^ MMASK) + 1; + MQ |= SMASK; } - FE ^= (AR & SMASK) ? 0377 : 0; + if (FE & 0400) { + MQ = 0; + FE = 0; + } else + FE ^= (flag3) ? 0377 : 0; MQ |= ((uint64)(FE & 0377)) << 27; } break; - /* FWT */ case 0200: /* MOVE */ case 0201: /* MOVEI */ @@ -3346,7 +3393,7 @@ fxnorm: MQ += (AR << 18) & LMASK; /* low order bits */ AR >>= 18; AR = (AR << 1) + (MQ >> 35); - MQ &= CMASK; + MQ &= CMASK; /* low order only has 35 bits */ if ((IR & 4) == 0) { /* IMUL */ if (AR > flag3 && !pi_cycle) { FLAGS |= OVR|TRP1; @@ -3500,12 +3547,9 @@ fxnorm: break; case 0241: /* ROT */ -#if KI | KL SC = (AB & RSIGN) ? - ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377); -#else - SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; -#endif + ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) + : (AB & 0377); if (SC == 0) break; SC = SC % 36; @@ -3582,12 +3626,9 @@ fxnorm: break; case 0245: /* ROTC */ -#if KI | KL SC = (AB & RSIGN) ? - ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377); -#else - SC = ((AB & RSIGN) ? (0777 ^ AB) + 1 : AB) & 0777; -#endif + ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) + : (AB & 0377); if (SC == 0) break; SC = SC % 72; @@ -3757,7 +3798,7 @@ fxnorm: PC = AR & RMASK; /* JRSTF */ if (AC & 02) { - FLAGS &= ~(OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0); + FLAGS &= ~(OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0|TRP1|TRP2); AR >>= 23; /* Move into position */ /* If executive mode, copy USER and UIO */ if ((FLAGS & (PUBLIC|USER)) == 0) @@ -3956,8 +3997,7 @@ fxnorm: break; case 0264: /* JSR */ /* AR Frm PC */ - MB = ((uint64)(FLAGS) << 23) | - ((PC + !pi_cycle) & RMASK); + MB = ((uint64)(FLAGS) << 23) | ((PC + !pi_cycle) & RMASK); if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } diff --git a/PDP10/ka10_dc.c b/PDP10/ka10_dc.c index a9128cc..8f33c4c 100644 --- a/PDP10/ka10_dc.c +++ b/PDP10/ka10_dc.c @@ -242,7 +242,7 @@ t_stat dc_devio(uint32 dev, uint64 *data) { int32 ch = *data & DATA; ch = sim_tt_outcvt(ch, TT_GET_MODE (dc_unit.flags) | TTUF_KSR); tmxr_putc_ln (lp, ch); - if (lp->xmte) + if (lp->xmte) tx_enable |= (1 << ln); else tx_enable &= ~(1 << ln); diff --git a/PDP10/ka10_defs.h b/PDP10/ka10_defs.h index e4fe774..b08d4ab 100644 --- a/PDP10/ka10_defs.h +++ b/PDP10/ka10_defs.h @@ -139,8 +139,10 @@ extern DEBTAB crd_debug[]; #define EMASK 00777000000000LL #define MMASK 00000777777777LL #define BIT1 00200000000000LL +#define BIT7 00002000000000LL #define BIT8 00001000000000LL #define BIT9 00000400000000LL +#define BIT10 00000200000000LL #define BIT10_35 00000377777777LL #define MANT 00000777777777LL #define EXPO 00377000000000LL diff --git a/PDP10/ka10_df.c b/PDP10/ka10_df.c index 9c0e196..7b8c202 100644 --- a/PDP10/ka10_df.c +++ b/PDP10/ka10_df.c @@ -35,7 +35,7 @@ void df10_writecw(struct df10 *df) { void df10_bump_addr(struct df10 *df) { #if KA & ITS - if (cpu_unit[0].flags & UNIT_ITSPAGE) + if (cpu_unit[0].flags & UNIT_ITSPAGE) df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000); else #endif @@ -104,7 +104,7 @@ int df10_read(struct df10 *df) { return 0; } #if KA & ITS - if (cpu_unit[0].flags & UNIT_ITSPAGE) + if (cpu_unit[0].flags & UNIT_ITSPAGE) df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000); else #endif @@ -132,7 +132,7 @@ int df10_write(struct df10 *df) { return 0; } #if KA & ITS - if (cpu_unit[0].flags & UNIT_ITSPAGE) + if (cpu_unit[0].flags & UNIT_ITSPAGE) df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000); else #endif diff --git a/PDP10/ka10_dp.c b/PDP10/ka10_dp.c index a46079b..cdffa5f 100644 --- a/PDP10/ka10_dp.c +++ b/PDP10/ka10_dp.c @@ -264,9 +264,9 @@ DIB dp_dib[] = { MTAB dp_mod[] = { {UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL}, {UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL}, - {MTAB_XTD|MTAB_VDV, 0, NULL, "NOHEADERS", + {MTAB_XTD|MTAB_VDV, 0, NULL, "NOHEADERS", &dp_set_hdr, &dp_show_hdr, "No Headers", "Disable header writing"}, - {MTAB_XTD|MTAB_VDV, DEV_WHDR, "write header", "HEADERS", + {MTAB_XTD|MTAB_VDV, DEV_WHDR, "write header", "HEADERS", &dp_set_hdr, &dp_show_hdr, "Headers", "Enable header writing"}, {UNIT_DTYPE, (RP03_DTYPE << UNIT_V_DTYPE), "RP03", "RP03", &dp_set_type }, {UNIT_DTYPE, (RP02_DTYPE << UNIT_V_DTYPE), "RP02", "RP02", &dp_set_type }, @@ -440,8 +440,10 @@ t_stat dp_devio(uint32 dev, uint64 *data) { unit = (*data >> 30) & 07; dp_cur_unit[ctlr] = unit; uptr = &dp_unit[(ctlr * NUM_UNITS_DP) + unit]; - uptr->STATUS &= ~(SUF_ERR|SEC_ERR|SRC_ERR|NXM_ERR|ILL_WR| + if ((uptr->STATUS & NOT_RDY) == 0) { + uptr->STATUS &= ~(SUF_ERR|SEC_ERR|SRC_ERR|NXM_ERR|ILL_WR| NO_DRIVE|NOT_RDY|ILL_CMD|END_CYL|SRC_DONE); + } cyl = ((*data >> 22) & 0377); if (*data & CYL256) cyl += 0400; @@ -490,14 +492,12 @@ t_stat dp_devio(uint32 dev, uint64 *data) { case RC: cyl = 0; - uptr->STATUS |= NOT_RDY; /* Fall through */ case SK: - if ((uptr->flags & UNIT_ATT) == 0) { - return SCPE_OK; - } uptr->STATUS |= NOT_RDY; + if ((uptr->flags & UNIT_ATT) == 0) + return SCPE_OK; uptr->UFLAGS = (cyl << 20) | (tmp<<3) | ctlr | SEEK_STATE; break; @@ -677,7 +677,7 @@ t_stat dp_svc (UNIT *uptr) case WH: /* Cylinder, Surface, Sector all ok */ if (BUF_EMPTY(uptr)) { - if (uptr->DATAPTR == 0) + if (uptr->DATAPTR == 0) sim_debug(DEBUG_DETAIL, dptr, "DP %d cmd=%o cyl=%d (%o) sect=%d surf=%d %d\n", ctlr, uptr->UFLAGS, cyl, cyl, sect, surf,uptr->CUR_CYL); @@ -761,7 +761,8 @@ t_stat dp_svc (UNIT *uptr) uptr->UFLAGS |= SEEK_DONE; uptr->UFLAGS &= ~SEEK_STATE; uptr->STATUS &= ~(NOT_RDY); - df10_setirq(df10); + if ((df10->status & BUSY) == 0) + df10_setirq(df10); } else if (diff < 10 && diff > -10) { uptr->CUR_CYL += diffs; if (uptr->CUR_CYL < 0) { @@ -769,13 +770,15 @@ t_stat dp_svc (UNIT *uptr) uptr->UFLAGS &= ~SEEK_STATE; uptr->STATUS &= ~(NOT_RDY); uptr->CUR_CYL = 0; - df10_setirq(df10); + if ((df10->status & BUSY) == 0) + df10_setirq(df10); } else if (uptr->CUR_CYL > dp_drv_tab[dtype].cyl) { uptr->UFLAGS |= SEEK_DONE; uptr->UFLAGS &= ~SEEK_STATE; uptr->STATUS &= ~(NOT_RDY); uptr->CUR_CYL = dp_drv_tab[dtype].cyl; - df10_setirq(df10); + if ((df10->status & BUSY) == 0) + df10_setirq(df10); } else sim_activate(uptr, 500); } else if (diff > 100 || diff < -100) { @@ -829,7 +832,7 @@ t_stat dp_show_hdr (FILE *st, UNIT *uptr, int32 val, CONST void *desc) dptr = find_dev_from_unit(uptr); if (dptr == NULL) return SCPE_IERR; - if ((dptr->flags & DEV_WHDR) == val) + if ((dptr->flags & DEV_WHDR) == val) fprintf (st, "%s", (char *)desc); return SCPE_OK; } diff --git a/PDP10/ka10_mt.c b/PDP10/ka10_mt.c index 2a8951b..3063159 100644 --- a/PDP10/ka10_mt.c +++ b/PDP10/ka10_mt.c @@ -89,12 +89,12 @@ #define BOT_FLAG 00000100000 #define REW_FLAG 00000200000 #define TRAN_HUNG 00000400000 -#define CHAR_COUNT 00017000000 -#define WT_CW_DONE 00020000000 -#define DATA_PARITY 00040000000 -#define NXM_ERR 00100000000 -#define CW_PAR_ERR 00200000000 -#define B22_FLAG 01000000000 +#define CHAR_COUNT 00007000000 +#define WT_CW_DONE 00010000000 +#define DATA_PARITY 00020000000 +#define NXM_ERR 00040000000 +#define CW_PAR_ERR 00100000000 +#define B22_FLAG 00400000000 #define DATA_PIA 000000007 /* 0 */ #define FLAG_PIA 000000070 /* 3 */ @@ -115,6 +115,7 @@ #define MT_BUFFUL 000000004 /* Buffer full of data */ #define MT_BRFUL 000000010 /* BR register full */ #define MT_STOP 000000020 /* DF10 End of Channel */ +#define MT_LASTWD 000000040 /* Last data word of record */ /* in u3 is device address */ /* in u4 is current buffer position */ /* in u5 */ @@ -135,6 +136,7 @@ struct df10 mt_df10; uint16 pia; uint8 unit; uint8 next_unit; +uint8 wr_eor; uint64 status; uint64 hold_reg; int cc; @@ -205,6 +207,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) { res |= (uint64)(uptr->u3 & 077300); res |= ((uint64)unit) << 15; res |= ((uint64)next_unit) << 18; + res |= ((uint64)wr_eor) << 21; if (dptr->flags & MTDF_TYPEB) res |= 7LL; /* Force DATA PIA to 7 on type B */ *data = res; @@ -219,7 +222,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) { pia = (uint16)(*data) & (NEXT_UNIT_ENAB|FLAG_PIA|DATA_PIA); status &= ~(DATA_REQUEST|CHAN_ERR|JOB_DONE|DATA_LATE| \ BAD_TAPE|RLC_ERR|READ_CMP|EOF_FLAG|EOT_FLAG|BOT_FLAG| \ - PARITY_ERR|ILL_OPR|REW_FLAG|TRAN_HUNG|CHAR_COUNT| \ + PARITY_ERR|ILL_OPR|REW_FLAG|TRAN_HUNG| \ WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR|IDLE_UNIT| \ SEVEN_CHAN|NEXT_UNIT); /* Check if we can switch to new unit */ @@ -232,7 +235,6 @@ t_stat mt_devio(uint32 dev, uint64 *data) { set_interrupt(dev, pia >> 3); } uptr->u3 = (int32)(*data & 077300); - CLR_BUF(uptr); mt_df10.buf = 0; sim_debug(DEBUG_CONO, dptr, "MT CONO %03o start %o %o %o %012llo %012llo PC=%06o\n", @@ -244,6 +246,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) { switch(cmd & 07) { case NOP_CLR: uptr->u3 &= ~MT_BUSY; + wr_eor = 0; status |= NEXT_UNIT; if (cmd & 010) { status |= JOB_DONE; @@ -255,12 +258,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) { return SCPE_OK; case REWIND: - case WTM: - break; - - case READ: - CLR_BUF(uptr); - uptr->u5 = 0; + status |= REW_FLAG; break; case WRITE: @@ -270,14 +268,23 @@ t_stat mt_devio(uint32 dev, uint64 *data) { } /* Fall through */ + case WTM: + case READ: case CMP: CLR_BUF(uptr); uptr->u5 = 0; - /* Fall through */ + break; case SPC_REV: + if (sim_tape_bot(uptr)) { + status |= JOB_DONE|ILL_OPR; + set_interrupt(MT_DEVNUM+4, pia >> 3); + return SCPE_OK; + } + /* Fall through */ + case SPC_FWD: - if ((dptr->flags & MTDF_TYPEB) == 0) { + if ((dptr->flags & MTDF_TYPEB) == 0 && (cmd & 010) == 0) { status |= DATA_REQUEST; set_interrupt(MT_DEVNUM, pia); } @@ -336,6 +343,8 @@ t_stat mt_devio(uint32 dev, uint64 *data) { res |= BOT_FLAG; if (sim_tape_eot(uptr)) res |= EOT_FLAG; + if ((dptr->flags & MTDF_TYPEB) == 0) + res |= WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR; #if KI_22BIT if (dptr->flags & MTDF_TYPEB) res |= B22_FLAG; @@ -349,7 +358,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) { if (*data & 1) { uptr->u3 |= MT_STOP; hri_mode = 0; - sim_debug(DEBUG_DETAIL, dptr, "MT stop %03o\n", dev); + sim_debug(DEBUG_DETAIL, dptr, "MT stop %03o %012llo\n", dev, status); } if (*data & 2) { hold_reg ^= mt_df10.buf; @@ -468,7 +477,6 @@ t_stat mt_error(UNIT * uptr, t_stat r, DEVICE * dptr) break; case MTSE_INVRL: /* invalid rec lnt */ - status |= RLC_ERR; break; case MTSE_EOM: /* end of medium */ @@ -483,7 +491,7 @@ t_stat mt_error(UNIT * uptr, t_stat r, DEVICE * dptr) } status |= JOB_DONE; uptr->u3 &= ~MT_BUSY; - sim_debug(DEBUG_EXP, dptr, "Setting status %012llo\n", status); + sim_debug(DEBUG_EXP, dptr, "Setting status %d %012llo\n", r, status); set_interrupt(MT_DEVNUM+4, pia >> 3); return SCPE_OK; } @@ -505,7 +513,7 @@ t_stat mt_srv(UNIT * uptr) return mt_error(uptr, MTSE_UNATT, dptr); /* attached? */ } - if ((uptr->u3 & DENS_MSK) != DENS_800) { + if ((cmd & 6) != 0 && (uptr->u3 & DENS_MSK) != DENS_800) { uptr->u3 &= ~MT_MOTION; return mt_error(uptr, MTSE_FMT, dptr); /* wrong density? */ } @@ -542,15 +550,15 @@ t_stat mt_srv(UNIT * uptr) case READ: case READ_NOEOR: if (uptr->u3 & MT_STOP) { - if ((uint32)uptr->u6 < uptr->hwmark) - status |= RLC_ERR; + if ((uptr->u3 & MT_LASTWD) == 0) + status |= RLC_ERR; if (dptr->flags & MTDF_TYPEB) df10_writecw(&mt_df10); return mt_error(uptr, MTSE_OK, dptr); } if (BUF_EMPTY(uptr)) { uptr->u3 |= MT_MOTION; - status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR); + status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT); if ((r = sim_tape_rdrecf(uptr, &mt_buffer[0], &reclen, BUFFSIZE)) != MTSE_OK) { sim_debug(DEBUG_DETAIL, dptr, "MT%o read error %d\n", unit, r); @@ -567,7 +575,7 @@ t_stat mt_srv(UNIT * uptr) } if (uptr->u3 & MT_BRFUL) { status |= DATA_LATE; - sim_debug(DEBUG_DATA, dptr, "data late\n"); + sim_debug(DEBUG_EXP, dptr, "data late\n"); break; } if ((uint32)uptr->u6 < uptr->hwmark) { @@ -591,6 +599,8 @@ t_stat mt_srv(UNIT * uptr) } uptr->u6++; uptr->u5++; + if ((uptr->u6 + cc_max) >= uptr->hwmark) + uptr->u3 |= MT_LASTWD; status &= ~CHAR_COUNT; status |= (uint64)(uptr->u5) << 18; if (uptr->u5 == cc_max) @@ -612,15 +622,13 @@ t_stat mt_srv(UNIT * uptr) case CMP: case CMP_NOEOR: if (uptr->u3 & MT_STOP) { - if ((uint32)uptr->u6 < uptr->hwmark) - status |= RLC_ERR; if (dptr->flags & MTDF_TYPEB) df10_writecw(&mt_df10); return mt_error(uptr, MTSE_OK, dptr); } if (BUF_EMPTY(uptr)) { uptr->u3 |= MT_MOTION; - status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR); + status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT); if ((r = sim_tape_rdrecf(uptr, &mt_buffer[0], &reclen, BUFFSIZE)) != MTSE_OK) { sim_debug(DEBUG_DETAIL, dptr, "MT%o read error %d\n", unit, r); @@ -636,10 +644,20 @@ t_stat mt_srv(UNIT * uptr) status |= DATA_REQUEST; set_interrupt(MT_DEVNUM, pia); } + break; } if (uptr->u6 >= (int32)uptr->hwmark) { - if (cmd == CMP_NOEOR) + if (cmd == CMP_NOEOR) { CLR_BUF(uptr); + uptr->u3 &= ~MT_LASTWD; + } else { + if (dptr->flags & MTDF_TYPEB) { + df10_bump_addr(&mt_df10); + df10_writecw(&mt_df10); + } + uptr->u3 &= ~(MT_MOTION|MT_BUSY); + return mt_error(uptr, MTSE_INVRL, dptr); + } } else if ((uptr->u3 & MT_BRFUL) == 0) { /* Write out first character. */ mt_df10_read(dptr, uptr); @@ -669,7 +687,7 @@ t_stat mt_srv(UNIT * uptr) if ((dptr->flags & MTDF_TYPEB) == 0) { uptr->u6 = uptr->hwmark; status &= ~CHAR_COUNT; - status |= (uint64)(uptr->u5) << 18; + status |= (uint64)(uptr->u5+1) << 18; uptr->u3 &= ~(MT_MOTION|MT_BUSY); if (dptr->flags & MTDF_TYPEB) df10_writecw(&mt_df10); @@ -678,12 +696,14 @@ t_stat mt_srv(UNIT * uptr) } uptr->u6++; uptr->u5++; + if (uptr->u6 == uptr->hwmark) + uptr->u3 |= MT_LASTWD; if (uptr->u5 == cc_max) { uptr->u5 = 0; uptr->u3 &= ~MT_BRFUL; } status &= ~CHAR_COUNT; - status |= (uint64)(uptr->u5) << 18; + status |= (uint64)(uptr->u5+1) << 18; } break; @@ -692,11 +712,16 @@ t_stat mt_srv(UNIT * uptr) /* Writing and Type A, request first data word */ if (BUF_EMPTY(uptr)) { uptr->u3 |= MT_MOTION; - status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR); + status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT); sim_debug(DEBUG_EXP, dptr, "MT%o Init write\n", unit); uptr->hwmark = 0; uptr->u5 = 0; uptr->u6 = 0; + status |= (uint64)(1) << 18; + if ((dptr->flags & MTDF_TYPEB) == 0) { + status |= DATA_REQUEST; + set_interrupt(MT_DEVNUM, pia); + } break; } /* Force error if we exceed buffer size */ @@ -727,12 +752,13 @@ t_stat mt_srv(UNIT * uptr) uptr->u3 &= ~MT_BRFUL; } status &= ~CHAR_COUNT; - status |= (uint64)(uptr->u5) << 18; + status |= (uint64)(uptr->u5+1) << 18; } if ((uptr->u3 & (MT_STOP|MT_BRFUL|MT_BUFFUL)) == MT_STOP) { /* Write out the block */ + wr_eor = 1; reclen = uptr->hwmark; - status &= ~(BOT_FLAG|EOF_FLAG|EOT_FLAG); + status &= ~(BOT_FLAG|EOF_FLAG|EOT_FLAG|CHAR_COUNT); r = sim_tape_wrrecf(uptr, &mt_buffer[0], reclen); sim_debug(DEBUG_DETAIL, dptr, "MT%o Write %d\n", unit, reclen); uptr->u6 = 0; @@ -747,10 +773,21 @@ t_stat mt_srv(UNIT * uptr) case WTM: if ((uptr->flags & MTUF_WLK) != 0) return mt_error(uptr, MTSE_WRP, dptr); - uptr->u3 &= ~MT_MOTION; - status &= ~(IDLE_UNIT|BOT_FLAG|EOT_FLAG); - sim_debug(DEBUG_DETAIL, dptr, "MT%o WTM\n", unit); - return mt_error(uptr, sim_tape_wrtmk(uptr), dptr); + if (uptr->u5 == 0) { + status &= ~(IDLE_UNIT|BOT_FLAG|EOT_FLAG); + sim_debug(DEBUG_DETAIL, dptr, "MT%o WTM\n", unit); + r = sim_tape_wrtmk(uptr); + if (r != MTSE_OK) + return mt_error(uptr, r, dptr); + uptr->u5++; + wr_eor = 1; + } else { + wr_eor = 0; + status |= EOF_FLAG; + uptr->u3 &= ~MT_MOTION; + return mt_error(uptr, MTSE_OK, dptr); + } + break; case ERG: if ((uptr->flags & MTUF_WLK) != 0) @@ -780,6 +817,8 @@ t_stat mt_srv(UNIT * uptr) case MTSE_EOM: /* end of medium */ /* Stop motion if we recieve any of these */ uptr->u3 &= ~MT_MOTION; + status &= ~DATA_REQUEST; + clr_interrupt(MT_DEVNUM); return mt_error(uptr, r, dptr); } /* Clear tape mark, command, idle since we will need to change dir */ @@ -939,7 +978,7 @@ mt_reset(DEVICE * dptr) t_stat mt_attach(UNIT * uptr, CONST char *file) { - return sim_tape_attach(uptr, file); + return sim_tape_attach_ex(uptr, file, 0, 0); } t_stat diff --git a/PDP10/ka10_pd.c b/PDP10/ka10_pd.c index c619005..3414da9 100644 --- a/PDP10/ka10_pd.c +++ b/PDP10/ka10_pd.c @@ -100,14 +100,14 @@ const char *pd_description (DEVICE *dptr) t_stat pd_set_on(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { DEVICE *dptr = &pd_dev; - dptr->flags &= ~PD_OFF; + dptr->flags &= ~PD_OFF; return SCPE_OK; } t_stat pd_set_off(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { DEVICE *dptr = &pd_dev; - dptr->flags |= PD_OFF; + dptr->flags |= PD_OFF; return SCPE_OK; } diff --git a/PDP10/ka10_rp.c b/PDP10/ka10_rp.c index 18b98f5..a6f659d 100644 --- a/PDP10/ka10_rp.c +++ b/PDP10/ka10_rp.c @@ -193,7 +193,7 @@ #define LA_V_SC 6 /* sector pos */ /* RPER2 - 10 - error status 2 - drive unsafe conditions - unimplemented */ -/* u5 high */ +/* us10 */ /* RPOF - 11 - offset register */ /* u4 low */ /* RPDC - 12 - desired cylinder */ @@ -209,6 +209,7 @@ /* RPSN - 14 - serial number */ /* RPER3 - 15 - error status 3 - more unsafe conditions - unimplemented */ +/* us9 */ /* RPDB - 176722 - data buffer */ @@ -489,6 +490,17 @@ t_stat rp_devio(uint32 dev, uint64 *data) { df10->status &= ~07LL; df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE); /* Clear flags */ + if (*data & CONT_RESET) { + UNIT *uptr=dptr->units; + for(drive = 0; drive < NUM_UNITS_RP; drive++, uptr++) { + uptr->u3 &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076; + uptr->u4 &= 003400177777; + uptr->u5 &= 0177777; + uptr->up7 = 0; + uptr->us9 = 0; + uptr->us10 = 0; + } + } if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)) df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)); if (*data & OVER_CLR) @@ -524,7 +536,13 @@ t_stat rp_devio(uint32 dev, uint64 *data) { } else if (rp_reg[ctlr] == 054) { *data = (t_uint64)(rp_rae[ctlr]); } else if ((rp_reg[ctlr] & 040) == 0) { + int parity; *data = (t_uint64)(rp_read(ctlr, rp_drive[ctlr], rp_reg[ctlr]) & 0177777); + parity = (*data >> 8) ^ *data; + parity = (parity >> 4) ^ parity; + parity = (parity >> 2) ^ parity; + parity = ((parity >> 1) ^ parity) & 1; + *data |= ((t_uint64)(parity ^ 1)) << 17; *data |= ((t_uint64)(rp_drive[ctlr])) << 18; } *data |= ((t_uint64)(rp_reg[ctlr])) << 30; @@ -538,27 +556,29 @@ t_stat rp_devio(uint32 dev, uint64 *data) { rp_reg[ctlr] = ((int)(*data >> 30)) & 077; if (*data & LOAD_REG) { if (rp_reg[ctlr] == 040) { - if (df10->status & BUSY) { - df10->status |= CC_CHAN_ACT; - return SCPE_OK; - } if ((*data & 1) == 0) { return SCPE_OK; } + if (df10->status & BUSY) { + df10->status |= CC_CHAN_ACT; + return SCPE_OK; + } + + df10->status &= ~(1 << df10->ccw_comp); + df10->status &= ~PI_ENABLE; if (((*data >> 1) & 077) < FNC_XFER) { df10->status |= CXR_ILC; df10_setirq(df10); - sim_debug(DEBUG_DATAIO, dptr, - "RP %03o command abort %012llo, %d[%d] PC=%06o %06o\n", - dev, *data, ctlr, rp_drive[ctlr], PC, df10->status); + sim_debug(DEBUG_DATAIO, dptr, + "RP %03o command abort %012llo, %d[%d] PC=%06o %06o\n", + dev, *data, ctlr, rp_drive[ctlr], PC, df10->status); return SCPE_OK; } rp_drive[ctlr] = (int)(*data >> 18) & 07; /* Start command */ df10_setup(df10, (uint32)(*data >> 6)); rp_write(ctlr, rp_drive[ctlr], 0, (uint32)(*data & 077)); - df10->status &= ~PI_ENABLE; sim_debug(DEBUG_DATAIO, dptr, "RP %03o command %012llo, %d[%d] PC=%06o %06o\n", dev, *data, ctlr, rp_drive[ctlr], PC, df10->status); @@ -606,7 +626,7 @@ rp_devirq(uint32 dev, int addr) { } } for (drive = 0; drive < NUM_DEVS_RP; drive++) { - if (dptr == rp_devs[drive]) + if (dptr == rp_devs[drive]) return (rp_imode[drive] ? rp_ivect[drive] : addr); } return addr; @@ -614,89 +634,115 @@ rp_devirq(uint32 dev, int addr) { void rp_write(int ctlr, int unit, int reg, uint32 data) { - UNIT *uptr = &rp_unit[(ctlr * 8) + unit]; - int i; - DEVICE *dptr = rp_devs[ctlr]; + int i; + DEVICE *dptr = rp_devs[ctlr]; + UNIT *uptr = &dptr->units[unit]; struct df10 *df10 = &rp_df10[ctlr]; + int dtype = GET_DTYPE(uptr->flags); + if ((uptr->u3 & CR_GO) && reg != 04) { + uptr->u3 |= (ER1_RMR << 16)|DS_ERR; + return; + } switch(reg) { case 000: /* control */ sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d Status=%06o\n", unit, ctlr, uptr->u3); + /* Set if drive not writable */ if (uptr->flags & UNIT_WLK) uptr->u3 |= DS_WRL; - df10->status &= ~(1 << df10->ccw_comp); - if ((data & 01) != 0 && (uptr->u3 & DS_DRY) != 0) { - uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; - uptr->u3 |= data & 076; - switch (GET_FNC(data)) { - case FNC_NOP: - uptr->u3 |= DS_DRY; - break; + /* If drive not ready don't do anything */ + if ((uptr->u3 & DS_DRY) == 0) { + uptr->u3 |= (ER1_RMR << 16)|DS_ERR; + sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d busy\n", unit, ctlr); + return; + } + /* Check if GO bit set */ + if ((data & 1) == 0) { + uptr->u3 &= ~076; + uptr->u3 |= data & 076; + sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d no go\n", unit, ctlr); + return; /* No, nop */ + } + uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; + uptr->u3 |= data & 076; + switch (GET_FNC(data)) { + case FNC_NOP: + uptr->u3 |= DS_DRY; + break; - case FNC_RECAL: /* recalibrate */ - uptr->u4 &= ~0177777; - /* Fall through */ + case FNC_RECAL: /* recalibrate */ + uptr->u4 &= ~0177777; + /* Fall through */ - case FNC_SEARCH: /* search */ - case FNC_SEEK: /* seek */ - case FNC_RETURN: /* return to center */ - case FNC_OFFSET: /* offset */ - case FNC_UNLOAD: /* unload */ - uptr->u3 &= ~DS_OFF; - /* Fall through */ - - case FNC_WCHK: /* write check */ - case FNC_WRITE: /* write */ - case FNC_WRITEH: /* write w/ headers */ - case FNC_READ: /* read */ - case FNC_READH: /* read w/ headers */ - uptr->u3 |= DS_PIP|CR_GO; - CLR_BUF(uptr); - uptr->u6 = 0; - break; - - - case FNC_DCLR: /* drive clear */ - uptr->u3 |= DS_DRY; - uptr->u3 &= ~(DS_ATA|CR_GO); + case FNC_SEARCH: /* search */ + case FNC_SEEK: /* seek */ + if (GET_CY(uptr->u4) >= rp_drv_tab[dtype].cyl || + GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect || + GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) { rp_attn[ctlr] &= ~(1<devnum); + uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; if ((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0) df10_setirq(df10); break; - - case FNC_PRESET: /* read-in preset */ - uptr->u4 = 0; - uptr->u3 &= ~DS_OFF; - /* Fall through */ - - case FNC_RELEASE: /* port release */ - case FNC_PACK: /* pack acknowledge */ - if ((uptr->flags & UNIT_ATT) != 0) - uptr->u3 |= DS_VV; - uptr->u3 |= DS_DRY; - df10_setirq(df10); - break; - - default: - uptr->u3 |= DS_DRY|DS_ERR|DS_ATA; - uptr->u3 |= (ER1_ILF << 16); - rp_attn[ctlr] |= (1<u3 & DS_PIP) - sim_activate(uptr, 100); - sim_debug(DEBUG_DETAIL, dptr, "RPA%o AStatus=%06o\n", unit, - uptr->u3); - } else { + /* Fall through */ + + case FNC_RETURN: /* return to center */ + case FNC_OFFSET: /* offset */ + case FNC_UNLOAD: /* unload */ + uptr->u3 &= ~DS_OFF; + /* Fall through */ + + case FNC_WCHK: /* write check */ + case FNC_WRITE: /* write */ + case FNC_WRITEH: /* write w/ headers */ + case FNC_READ: /* read */ + case FNC_READH: /* read w/ headers */ + uptr->u3 |= DS_PIP|CR_GO; + CLR_BUF(uptr); + uptr->u6 = 0; + break; + + + case FNC_DCLR: /* drive clear */ + uptr->u3 |= DS_DRY; + uptr->u3 &= ~(DS_ATA|CR_GO); + rp_attn[ctlr] &= ~(1<devnum); + if ((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0) + df10_setirq(df10); + break; + + case FNC_PRESET: /* read-in preset */ + uptr->u4 = 0; + uptr->u5 &= 0177777; + uptr->u3 &= ~DS_OFF; + /* Fall through */ + + case FNC_RELEASE: /* port release */ + case FNC_PACK: /* pack acknowledge */ + if ((uptr->flags & UNIT_ATT) != 0) + uptr->u3 |= DS_VV; + uptr->u3 |= DS_DRY; df10_setirq(df10); + break; + + default: + uptr->u3 |= DS_DRY|DS_ERR|DS_ATA; + uptr->u3 |= (ER1_ILF << 16); + rp_attn[ctlr] |= (1<u3 & DS_PIP) + sim_activate(uptr, 1000); + sim_debug(DEBUG_DETAIL, dptr, "RPA%o AStatus=%06o\n", unit, uptr->u3); return; case 001: /* status */ break; case 002: /* error register 1 */ uptr->u3 &= 0177777; uptr->u3 |= data << 16; - if (data != 0) + uptr->u3 &= ~DS_ERR; + if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0) uptr->u3 |= DS_ERR; break; case 003: /* maintenance */ @@ -708,31 +754,42 @@ rp_write(int ctlr, int unit, int reg, uint32 data) { rp_attn[ctlr] &= ~(1<devnum); - if (((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0) || - (df10->status & PI_ENABLE)) - df10_setirq(df10); + if (df10->status & (IADR_ATTN|BUSY) == IADR_ATTN) { + if (rp_attn[ctlr] != 0) + df10_setirq(df10); + else + clr_interrupt(df10->devnum); + } break; case 005: /* sector/track */ uptr->u4 &= 0177777; uptr->u4 |= data << 16; break; case 014: /* error register 2 */ - if (data != 0) + uptr->us9 = data; + uptr->u3 &= ~DS_ERR; + if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0) uptr->u3 |= DS_ERR; - uptr->u5 &= 0177777; - uptr->u5 |= data << 16; + break; case 006: /* drive type */ case 007: /* look ahead */ + break; case 011: /* offset */ + uptr->u5 &= 0177777; + uptr->u5 |= data << 16; break; case 012: /* desired cylinder */ uptr->u4 &= ~0177777; uptr->u4 |= data; break; + case 015: /* error register 3 */ + uptr->us10 = data; + uptr->u3 &= ~DS_ERR; + if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0) + uptr->u3 |= DS_ERR; + break; case 013: /* current cylinder */ case 010: /* serial no */ - case 015: /* error register 3 */ case 016: /* ecc position */ case 017: /* ecc pattern */ break; @@ -744,7 +801,8 @@ rp_write(int ctlr, int unit, int reg, uint32 data) { uint32 rp_read(int ctlr, int unit, int reg) { - UNIT *uptr = &rp_unit[(ctlr * 8) + unit]; + DEVICE *dptr = rp_devs[ctlr]; + UNIT *uptr = &dptr->units[unit]; struct df10 *df10; uint32 temp = 0; int i; @@ -764,6 +822,8 @@ rp_read(int ctlr, int unit, int reg) { case 002: /* error register 1 */ temp = (uptr->u3 >> 16) & 0177777; break; + case 003: /* maintenance */ + break; case 004: /* atten summary */ for (i = 0; i < 8; i++) { if (rp_unit[(ctlr * 8) + i].u3 & DS_ATA) { @@ -789,10 +849,13 @@ rp_read(int ctlr, int unit, int reg) { case 010: /* serial no */ temp = (020 * ctlr) + (unit + 1); break; - case 003: /* maintenance */ - case 007: /* look ahead */ case 014: /* error register 2 */ + temp = uptr->us9; + break; case 015: /* error register 3 */ + temp = uptr->us10; + break; + case 007: /* look ahead */ case 016: /* ecc position */ case 017: /* ecc pattern */ break; @@ -811,7 +874,7 @@ t_stat rp_svc (UNIT *uptr) int unit; DEVICE *dptr; struct df10 *df; - int cyl = uptr->u4 & 01777; + int cyl = GET_CY(uptr->u4); int diff, da; t_stat r; @@ -831,7 +894,7 @@ t_stat rp_svc (UNIT *uptr) /* Check if seeking */ if (uptr->u3 & DS_PIP) { sim_debug(DEBUG_DETAIL, dptr, "RPA%o seek %d %d\n", unit, cyl, uptr->u5); - if (cyl > rp_drv_tab[dtype].cyl) { + if (cyl >= rp_drv_tab[dtype].cyl) { uptr->u3 &= ~DS_PIP; uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; } @@ -882,11 +945,13 @@ t_stat rp_svc (UNIT *uptr) case FNC_PRESET: /* read-in preset */ case FNC_RECAL: /* recalibrate */ case FNC_SEEK: /* seek */ + if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect || + GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) + uptr->u3 |= (ER1_IAE << 16)|DS_ERR; rp_attn[ctlr] |= 1<u3 |= DS_DRY|DS_ATA; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - if (df->status & IADR_ATTN) + if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN) df10_setirq(df); sim_debug(DEBUG_DETAIL, dptr, "RPA%o seekdone %d %o\n", unit, cyl, uptr->u3); break; @@ -898,8 +963,7 @@ t_stat rp_svc (UNIT *uptr) rp_attn[ctlr] |= 1<u3 |= DS_DRY|DS_ATA; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - if (df->status & IADR_ATTN) + if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN) df10_setirq(df); sim_debug(DEBUG_DETAIL, dptr, "RPA%o searchdone %d %o\n", unit, cyl, uptr->u3); break; @@ -913,15 +977,12 @@ t_stat rp_svc (UNIT *uptr) if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect || GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) { uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; - rp_attn[ctlr] |= 1<status &= ~BUSY; uptr->u3 &= ~CR_GO; - sim_debug(DEBUG_DETAIL, dptr, "RPA%o readx done\n", unit); - if (df->status & IADR_ATTN) - df10_setirq(df); + df10_finish_op(df, 0); + sim_debug(DEBUG_DETAIL, dptr, "RPA%o readx done\n", unit); return SCPE_OK; } - sim_debug(DEBUG_DETAIL, dptr, "RPA%o read (%d,%d,%d)\n", unit, cyl, + sim_debug(DEBUG_DETAIL, dptr, "RPA%o read (%d,%d,%d)\n", unit, cyl, GET_SC(uptr->u4), GET_SF(uptr->u4)); da = GET_DA(uptr->u4, dtype) * RP_NUMWD; (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); @@ -934,7 +995,8 @@ t_stat rp_svc (UNIT *uptr) } df->buf = rp_buf[ctlr][uptr->u6++]; - sim_debug(DEBUG_DATA, dptr, "RPA%o read word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr); + sim_debug(DEBUG_DATA, dptr, "RPA%o read word %d %012llo %09o %06o\n", + unit, uptr->u6, df->buf, df->cda, df->wcr); if (df10_write(df)) { if (uptr->u6 == uptr->hwmark) { /* Increment to next sector. Set Last Sector */ @@ -957,8 +1019,7 @@ t_stat rp_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "RPA%o read done\n", unit); uptr->u3 |= DS_DRY; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - df10_setirq(df); + df10_finish_op(df, 0); return SCPE_OK; } break; @@ -969,12 +1030,9 @@ t_stat rp_svc (UNIT *uptr) if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect || GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) { uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; - rp_attn[ctlr] |= 1<status &= ~BUSY; uptr->u3 &= ~CR_GO; - sim_debug(DEBUG_DETAIL, dptr, "RPA%o writex done\n", unit); - if (df->status & IADR_ATTN) - df10_setirq(df); + df10_finish_op(df, 0); + sim_debug(DEBUG_DETAIL, dptr, "RPA%o writex done\n", unit); return SCPE_OK; } uptr->u6 = 0; @@ -982,11 +1040,12 @@ t_stat rp_svc (UNIT *uptr) } r = df10_read(df); rp_buf[ctlr][uptr->u6++] = df->buf; - sim_debug(DEBUG_DATA, dptr, "RPA%o write word %d %012llo %06o\n", unit, uptr->u6, df->buf, df->wcr); + sim_debug(DEBUG_DATA, dptr, "RPA%o write word %d %012llo %06o\n", + unit, uptr->u6, df->buf, df->wcr); if (r == 0 || uptr->u6 == RP_NUMWD) { while (uptr->u6 < RP_NUMWD) rp_buf[ctlr][uptr->u6++] = 0; - sim_debug(DEBUG_DETAIL, dptr, "RPA%o write (%d,%d,%d)\n", unit, cyl, + sim_debug(DEBUG_DETAIL, dptr, "RPA%o write (%d,%d,%d)\n", unit, cyl, GET_SC(uptr->u4), GET_SF(uptr->u4)); da = GET_DA(uptr->u4, dtype) * RP_NUMWD; (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); @@ -1014,8 +1073,7 @@ t_stat rp_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "RPA%o write done\n", unit); uptr->u3 |= DS_DRY; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - df10_setirq(df); + df10_finish_op(df, 0); return SCPE_OK; } break; @@ -1073,12 +1131,10 @@ rp_boot(int32 unit_num, DEVICE * rptr) uptr->u3 |= DS_VV; addr = rp_buf[0][ptr] & RMASK; wc = (rp_buf[0][ptr++] >> 18) & RMASK; -fprintf(stderr, "Boot %06o %06o\n\r", addr, wc); while (wc != 0) { wc = (wc + 1) & RMASK; addr = (addr + 1) & RMASK; word = rp_buf[0][ptr++]; -fprintf(stderr, "data: %06o %06o %012llo\n\r", addr, wc, word); if (addr < 020) FM[addr] = word; else diff --git a/PDP10/ka10_rs.c b/PDP10/ka10_rs.c index 8b236d3..3c0f301 100644 --- a/PDP10/ka10_rs.c +++ b/PDP10/ka10_rs.c @@ -311,7 +311,7 @@ t_stat rs_devio(uint32 dev, uint64 *data) { if (dptr == NULL) return SCPE_OK; for (ctlr = 0; ctlr < NUM_DEVS_RS; ctlr++) { - if (dptr == rs_devs[ctlr]) + if (dptr == rs_devs[ctlr]) break; } df10 = &rs_df10[ctlr]; @@ -335,6 +335,14 @@ t_stat rs_devio(uint32 dev, uint64 *data) { df10->status &= ~07LL; df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE); /* Clear flags */ + if (*data & CONT_RESET) { + UNIT *uptr=dptr->units; + for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) { + uptr->u3 &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076; + uptr->u4 &= 003400177777; + uptr->u5 &= 0177777; + } + } if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)) df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR)); if (*data & OVER_CLR) @@ -351,8 +359,8 @@ t_stat rs_devio(uint32 dev, uint64 *data) { set_interrupt(dev, df10->status); if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0) set_interrupt(dev, df10->status); - sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n", - dev, (uint32)*data, ctlr, PC, df10->status); + sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n", + dev, (uint32)*data, ctlr, PC, df10->status); return SCPE_OK; case DATAI: @@ -370,8 +378,15 @@ t_stat rs_devio(uint32 dev, uint64 *data) { } else if (rs_reg[ctlr] == 054) { *data = (t_uint64)(rs_rae[ctlr]); } else if ((rs_reg[ctlr] & 040) == 0) { - *data = (t_uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777); - *data |= ((t_uint64)(rs_drive[ctlr])) << 18; + int parity; + + *data = (t_uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777); + parity = (*data >> 8) ^ *data; + parity = (parity >> 4) ^ parity; + parity = (parity >> 2) ^ parity; + parity = ((parity >> 1) ^ parity) & 1; + *data |= ((t_uint64)(parity ^ 1)) << 17; + *data |= ((t_uint64)(rs_drive[ctlr])) << 18; } *data |= ((t_uint64)(rs_reg[ctlr])) << 30; sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATI %012llo, %d %d PC=%06o\n", @@ -384,27 +399,29 @@ t_stat rs_devio(uint32 dev, uint64 *data) { rs_reg[ctlr] = ((int)(*data >> 30)) & 077; if (*data & LOAD_REG) { if (rs_reg[ctlr] == 040) { - if (df10->status & BUSY) { - df10->status |= CC_CHAN_ACT; - return SCPE_OK; - } if ((*data & 1) == 0) { return SCPE_OK; } + if (df10->status & BUSY) { + df10->status |= CC_CHAN_ACT; + return SCPE_OK; + } + + df10->status &= ~(1 << df10->ccw_comp); + df10->status &= ~PI_ENABLE; if (((*data >> 1) & 077) < FNC_XFER) { df10->status |= CXR_ILC; df10_setirq(df10); - sim_debug(DEBUG_DATAIO, dptr, - "RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n", - dev, *data, ctlr, rs_drive[ctlr], PC, df10->status); + sim_debug(DEBUG_DATAIO, dptr, + "RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n", + dev, *data, ctlr, rs_drive[ctlr], PC, df10->status); return SCPE_OK; } rs_drive[ctlr] = (int)(*data >> 18) & 07; /* Start command */ df10_setup(df10, (uint32)(*data >> 6)); - df10->status &= ~PI_ENABLE; rs_write(ctlr, rs_drive[ctlr], 0, (uint32)(*data & 077)); sim_debug(DEBUG_DATAIO, dptr, "RS %03o command %012llo, %d[%d] PC=%06o %06o\n", @@ -453,7 +470,7 @@ rs_devirq(uint32 dev, int addr) { } } for (drive = 0; drive < NUM_DEVS_RS; drive++) { - if (dptr == rs_devs[drive]) + if (dptr == rs_devs[drive]) return (rs_imode[drive] ? rs_ivect[drive] : addr); } return addr; @@ -461,65 +478,76 @@ rs_devirq(uint32 dev, int addr) { void rs_write(int ctlr, int unit, int reg, uint32 data) { - UNIT *uptr = &rs_unit[(ctlr * 8) + unit]; - int i; - DEVICE *dptr = rs_devs[ctlr]; + int i; + DEVICE *dptr = rs_devs[ctlr]; struct df10 *df10 = &rs_df10[ctlr]; - + UNIT *uptr = &dptr->units[unit]; + + if ((uptr->u3 & CR_GO) && reg != 04) { + uptr->u3 |= (ER1_RMR << 16)|DS_ERR; + return; + } switch(reg) { case 000: /* control */ sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d Status=%06o\n", unit, ctlr, uptr->u3); + /* Set if drive not writable */ if (uptr->flags & UNIT_WLK) uptr->u3 |= DS_WRL; - df10->status &= ~(1 << df10->ccw_comp); - if ((data & 01) != 0 && (uptr->u3 & DS_DRY) != 0) { - uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; - uptr->u3 |= data & 077; - switch (GET_FNC(data)) { - case FNC_NOP: - uptr->u3 |= DS_DRY; - break; - - case FNC_SEARCH: /* search */ - case FNC_WCHK: /* write check */ - case FNC_WRITE: /* write */ - case FNC_READ: /* read */ - uptr->u3 |= DS_PIP|CR_GO; - uptr->u6 = 0; - break; - - case FNC_PRESET: /* read-in preset */ - uptr->u4 = 0; - if ((uptr->flags & UNIT_ATT) != 0) - uptr->u3 |= DS_VV; - uptr->u3 |= DS_DRY; - df10_setirq(df10); - break; - - case FNC_DCLR: /* drive clear */ - uptr->u3 |= DS_DRY; - uptr->u3 &= ~(DS_ATA|CR_GO); - rs_attn[ctlr] = 0; - clr_interrupt(df10->devnum); - for (i = 0; i < 8; i++) { - if (rs_unit[(ctlr * 8) + i].u3 & DS_ATA) - rs_attn[ctlr] = 1; - } - if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0) - df10_setirq(df10); - break; - default: - uptr->u3 |= DS_DRY|DS_ERR|DS_ATA; - uptr->u3 |= (ER1_ILF << 16); - } - if (uptr->u3 & DS_PIP) - sim_activate(uptr, 100); - sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit, - uptr->u3); - } else { - df10->status &= ~BUSY; - df10_setirq(df10); + /* If drive not ready don't do anything */ + if ((uptr->u3 & DS_DRY) == 0) { + uptr->u3 |= (ER1_RMR << 16)|DS_ERR; + sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d busy\n", unit, ctlr); + return; } + /* Check if GO bit set */ + if ((data & 1) == 0) { + uptr->u3 &= ~076; + uptr->u3 |= data & 076; + sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d no go\n", unit, ctlr); + return; /* No, nop */ + } + uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL; + uptr->u3 |= data & 076; + switch (GET_FNC(data)) { + case FNC_NOP: + uptr->u3 |= DS_DRY; + break; + + case FNC_SEARCH: /* search */ + case FNC_WCHK: /* write check */ + case FNC_WRITE: /* write */ + case FNC_READ: /* read */ + uptr->u3 |= DS_PIP|CR_GO; + uptr->u6 = 0; + break; + + case FNC_PRESET: /* read-in preset */ + uptr->u4 = 0; + if ((uptr->flags & UNIT_ATT) != 0) + uptr->u3 |= DS_VV; + uptr->u3 |= DS_DRY; + df10_setirq(df10); + break; + + case FNC_DCLR: /* drive clear */ + uptr->u3 |= DS_DRY; + uptr->u3 &= ~(DS_ATA|CR_GO); + rs_attn[ctlr] = 0; + clr_interrupt(df10->devnum); + for (i = 0; i < 8; i++) { + if (rs_unit[(ctlr * 8) + i].u3 & DS_ATA) + rs_attn[ctlr] = 1; + } + if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0) + df10_setirq(df10); + break; + default: + uptr->u3 |= DS_DRY|DS_ERR|DS_ATA; + uptr->u3 |= (ER1_ILF << 16); + } + if (uptr->u3 & DS_PIP) + sim_activate(uptr, 100); + sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit, uptr->u3); return; case 001: /* status */ break; @@ -558,20 +586,19 @@ rs_write(int ctlr, int unit, int reg, uint32 data) { uint32 rs_read(int ctlr, int unit, int reg) { - UNIT *uptr = &rs_unit[(ctlr * 8) + unit]; - struct df10 *df10; + DEVICE *dptr = rs_devs[ctlr]; + struct df10 *df10 = &rs_df10[ctlr]; + UNIT *uptr = &dptr->units[unit]; uint32 temp = 0; int i; if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ - df10 = &rs_df10[ctlr]; df10->status |= 0002000000000; return 0; } switch(reg) { case 000: /* control */ - df10 = &rs_df10[ctlr]; temp = uptr->u3 & 077; if (uptr->flags & UNIT_ATT) temp |= CS1_DVA; @@ -657,7 +684,7 @@ t_stat rs_svc (UNIT *uptr) uptr->u3 |= DS_DRY|DS_ATA; uptr->u3 &= ~CR_GO; df->status &= ~BUSY; - if (df->status & IADR_ATTN) + if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN) df10_setirq(df); sim_debug(DEBUG_DETAIL, dptr, "RSA%o searchdone\n", unit); break; @@ -669,15 +696,13 @@ t_stat rs_svc (UNIT *uptr) if (GET_SC(uptr->u4) >= rs_drv_tab[dtype].sect || GET_SF(uptr->u4) >= rs_drv_tab[dtype].surf) { uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; - rs_attn[ctlr] = 1; df->status &= ~BUSY; uptr->u3 &= ~CR_GO; - sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit); - if (df->status & IADR_ATTN) - df10_setirq(df); + sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit); + df10_finish_op(df, 0); return SCPE_OK; } - sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit, + sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit, GET_SC(uptr->u4), GET_SF(uptr->u4)); da = GET_DA(uptr->u4, dtype) * RS_NUMWD; (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); @@ -689,7 +714,8 @@ t_stat rs_svc (UNIT *uptr) } df->buf = rs_buf[ctlr][uptr->u6++]; - sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr); + sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n", + unit, uptr->u6, df->buf, df->cda, df->wcr); if (df10_write(df)) { if (uptr->u6 == uptr->hwmark) { /* Increment to next sector. Set Last Sector */ @@ -707,8 +733,7 @@ t_stat rs_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "RSA%o read done\n", unit); uptr->u3 |= DS_DRY; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - df10_setirq(df); + df10_finish_op(df, 0); return SCPE_OK; } break; @@ -718,22 +743,20 @@ t_stat rs_svc (UNIT *uptr) if (GET_SC(uptr->u4) >= rs_drv_tab[dtype].sect || GET_SF(uptr->u4) >= rs_drv_tab[dtype].surf) { uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA; - rs_attn[ctlr] = 1; - df->status &= ~BUSY; uptr->u3 &= ~CR_GO; - sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit); - if (df->status & IADR_ATTN) - df10_setirq(df); + sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit); + df10_finish_op(df, 0); return SCPE_OK; } } r = df10_read(df); rs_buf[ctlr][uptr->u6++] = df->buf; - sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr); + sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n", + unit, uptr->u6, df->buf, df->cda, df->wcr); if (r == 0 || uptr->u6 == RS_NUMWD) { while (uptr->u6 < RS_NUMWD) rs_buf[ctlr][uptr->u6++] = 0; - sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit, + sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit, GET_SC(uptr->u4), GET_SF(uptr->u4)); da = GET_DA(uptr->u4, dtype) * RS_NUMWD; (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); @@ -756,8 +779,7 @@ t_stat rs_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "RSA%o write done\n", unit); uptr->u3 |= DS_DRY; uptr->u3 &= ~CR_GO; - df->status &= ~BUSY; - df10_setirq(df); + df10_finish_op(df, 0); return SCPE_OK; } break; diff --git a/PDP10/ka10_tu.c b/PDP10/ka10_tu.c index 0c34a0b..ae81f66 100644 --- a/PDP10/ka10_tu.c +++ b/PDP10/ka10_tu.c @@ -444,7 +444,7 @@ tu_devirq(uint32 dev, int addr) { } } for (drive = 0; drive < NUM_DEVS_TU; drive++) { - if (dptr == tu_devs[drive]) + if (dptr == tu_devs[drive]) return (tu_imode[drive] ? tu_ivect[drive] : addr); } return addr; @@ -1075,7 +1075,7 @@ tu_attach(UNIT * uptr, CONST char *file) uptr->u3 = 0; uptr->u5 = 0; - r = sim_tape_attach(uptr, file); + r = sim_tape_attach_ex(uptr, file, 0, 0); if (r == SCPE_OK) { uptr->u3 = CS_ATA|CS_CHANGE; tu_attn[ctlr] = 1;