diff --git a/PDP10/ka10_cpu.c b/PDP10/ka10_cpu.c index 64d632d..fdc4932 100644 --- a/PDP10/ka10_cpu.c +++ b/PDP10/ka10_cpu.c @@ -182,6 +182,7 @@ int private_page; /* Access to private page */ uint64 fault_data; /* Fault data from last fault */ int32 apr_serial = -1; /* CPU Serial number */ int trap_flag; /* Last instruction was trapped */ +int last_page; /* Last page mapped */ #endif char dev_irq[128]; /* Pending irq by device */ @@ -427,7 +428,7 @@ int opflags[] = { /* PUSHJ */ /* PUSH */ /* POP */ /* POPJ */ FAC|SAC, FAC|FCE|SAC, FAC|SAC, FAC|SAC, /* JSR */ /* JSP */ /* JSA */ /* JRA */ - SCE, SAC, FBR|SCE, 0, + 0, SAC, FBR|SCE, 0, /* ADD */ /* ADDI */ /* ADDM */ /* ADDB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* SUB */ /* SUBI */ /* SUBM */ /* SUBB */ @@ -702,7 +703,8 @@ t_stat dev_pag(uint32 dev, uint64 *data) { switch(dev & 03) { case CONI: /* Complement of vpn */ - *data = ((uint64)pag_reload) | 040LL; + *data = (uint64)(pag_reload ^ 040); + *data |= ((uint64)last_page) << 8; *data |= (uint64)((apr_serial == -1) ? DEF_SERIAL : apr_serial) << 26; sim_debug(DEBUG_CONI, &cpu_dev, "CONI PAG %012llo\n", *data); break; @@ -710,7 +712,7 @@ t_stat dev_pag(uint32 dev, uint64 *data) { case CONO: /* Set Stack AC and Page Table Reload Counter */ ac_stack = (*data >> 9) & 0760; - pag_reload = *data & 037; + pag_reload = (*data & 037) | (pag_reload & 040); sim_debug(DEBUG_CONO, &cpu_dev, "CONI PAG %012llo\n", *data); break; @@ -726,6 +728,7 @@ t_stat dev_pag(uint32 dev, uint64 *data) { user_addr_cmp = (res & 00020000000000LL) != 0; small_user = (res & 00040000000000LL) != 0; fm_sel = (uint8)(res >> 29) & 060; + pag_reload = 0; sim_debug(DEBUG_DATAIO, &cpu_dev, "DATAO PAG %012llo ebr=%06o ubr=%06o\n", *data, eb_ptr, ub_ptr); @@ -759,6 +762,8 @@ void check_apr_irq() { if (flg) set_interrupt(0, apr_irq); } + if (clk_en && clk_flg) + set_interrupt(4, clk_irq); } @@ -858,6 +863,8 @@ t_stat dev_apr(uint32 dev, uint64 *data) { /* Set trap conditions */ res = *data; clk_irq = apr_irq = res & 07; + clr_interrupt(0); + clr_interrupt(4); if (res & 010) FLAGS &= ~OVR; if (res & 020) @@ -870,10 +877,8 @@ t_stat dev_apr(uint32 dev, uint64 *data) { fov_irq = 1; if (res & 0400) fov_irq = 0; - if (res & 01000) { + if (res & 01000) clk_flg = 0; - clr_interrupt(4); - } if (res & 02000) clk_en = 1; if (res & 04000) @@ -988,13 +993,19 @@ t_stat null_dev(uint32 dev, uint64 *data) { */ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { uint64 data; - int base; + int base = ub_ptr; int page = addr >> 9; int uf = (FLAGS & USER) != 0; if (page_fault) return 0; + /* If fetching byte data, use write access */ + if (BYF5 && (IR & 06) == 6) + wr = 1; + + wr |= modify; + if (flag) uf = 0; else if (!uf && !cur_context && ((((xct_flag & 2) != 0 && wr != 0)) || @@ -1002,11 +1013,10 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { uf = (FLAGS & USERIO) != 0; if (uf) { - base = ub_ptr; - if (small_user && (addr & 0340000) != 0) { - fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 28) | 060LL; + if (small_user && (page & 0340) != 0) { + fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 020LL; page_fault = 1; -// fprintf(stderr, " small fault\n\r"); + fprintf(stderr, " %03o small fault\n\r", page); return 0; } } else { @@ -1016,15 +1026,20 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { return 1; } /* Pages 340-377 via UBR */ - // fprintf(stderr, "xlat %06o %03o ", addr, page >> 1); + // fprintf(stderr, "xlat %06o %03o ", addr, page >> 1); if ((page & 0740) == 0340) { - base = ub_ptr; page += 01000 - 0340; /* Pages 400-777 via EBR */ } else if (page & 0400) { base = eb_ptr; } else { - // fprintf(stderr, "\n\r"); + // fprintf(stderr, "\n\r"); + if (!flag && ((FLAGS & PUBLIC) != 0)) { + /* Handle public violation */ + fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; + private_page = 1; + fprintf(stderr, " public"); + } *loc = addr; return 1; } @@ -1034,19 +1049,19 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { if ((page & 1) == 0) data >>= 18; data &= RMASK; -// fprintf(stderr, " -> %06llo wr=%o ", data, wr); - *loc = ((data & 037777) << 9) + (addr & 0777); -// fprintf(stderr, " -> %06o", *loc); + // fprintf(stderr, " -> %06llo wr=%o ", data, wr); + *loc = ((data & 017777) << 9) + (addr & 0777); + // fprintf(stderr, " -> %06o\n", *loc); if (!flag && ((FLAGS & PUBLIC) != 0) && ((data & 0200000) == 0)) { /* Handle public violation */ - fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 28) | 061LL; + fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; private_page = 1; -// fprintf(stderr, " public"); + // fprintf(stderr, " public"); } if (cur_context && ((data & 0200000) != 0)) FLAGS |= PUBLIC; if ((data & LSIGN) == 0 || (wr & ((data & 0100000) == 0))) { - fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 28) | 020LL; + fault_data = ((((uint64)(addr))<<9) | ((uint64)(uf) << 27)) & LMASK; fault_data |= (data & 0400000) ? 010LL : 0LL; /* A */ fault_data |= (data & 0100000) ? 004LL : 0LL; /* W */ fault_data |= (data & 0040000) ? 002LL : 0LL; /* S */ @@ -1054,12 +1069,11 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { page_fault = 1; fprintf(stderr, "xlat %06o %03o ", addr, page >> 1); fprintf(stderr, " %06o %03o %012llo ", base, page, data); - fprintf(stderr, " -> %06llo wr=%o ", data, wr); + fprintf(stderr, " -> %06llo wr=%o PC=%06o ", data, wr, PC); fprintf(stderr, " fault\n\r"); - // fprintf(stderr, " fault\n\r"); return 0; } - // fprintf(stderr, "\n\r"); +// fprintf(stderr, "\n\r"); return 1; } @@ -1311,26 +1325,6 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ break; } -#if KI | KL - /* Handle page fault and traps */ - if (page_enable && (page_fault || private_page || (FLAGS & (TRP1|TRP2)))) { - if (page_fault || private_page) { - page_fault = private_page = 0; - AB = ub_ptr + (FLAGS & USER) ? 0427 : 0426; - MB = fault_data; - Mem_write_nopage(); - AB = 0420; - } else { - AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2); - FLAGS &= ~(TRP1|TRP2); - } - f_pc_inh = 1; - trap_flag = 1; - AB += (FLAGS & USER) ? ub_ptr : eb_ptr; - Mem_read_nopage(); - goto no_fetch; - } -#endif /* Normal instruction */ if (f_load_pc) { @@ -1339,6 +1333,7 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ #if KI | KL xct_flag = 0; trap_flag = 0; + modify = 0; #endif } @@ -1346,12 +1341,15 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ #if !(KI | KL) fetch: #endif - Mem_read(pi_cycle | uuo_cycle, 1); + if (Mem_read(pi_cycle | uuo_cycle, 1)) + goto last; #if KI | KL no_fetch: #endif IR = (MB >> 27) & 0777; AC = (MB >> 23) & 017; + AD = MB; /* Save for historical sake */ + i_flags = opflags[IR]; BYF5 = 0; } @@ -1362,28 +1360,28 @@ no_fetch: AB = AR & RMASK; } - /* Update history */ - if (hst_lnt && PC > 020 && (PC & 0777774) != 0472174 && - (PC & 0777700) != 023700 && (PC != 0527154)) { - hst_p = hst_p + 1; - if (hst_p >= hst_lnt) { - hst_p = 0; -// reason = STOP_IBKPT; - } - hst[hst_p].pc = HIST_PC | ((BYF5)? (HIST_PC2|PC) : AB); - hst[hst_p].ea = AB; - hst[hst_p].ir = MB; - hst[hst_p].flags = (FLAGS << 5) |(clk_flg << 2) | (nxm_flag << 1) -#if KA - | (mem_prot << 4) | (push_ovf << 3) -#endif - ; - hst[hst_p].ac = get_reg(AC); +#if KI | KL + /* Handle page fault and traps */ + if (page_enable && trap_flag == 0 && (FLAGS & (TRP1|TRP2))) { + AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2); + trap_flag = FLAGS & (TRP1|TRP2); + FLAGS &= ~(TRP1|TRP2); + f_pc_inh = 1; + pi_cycle = 1; + AB += (FLAGS & USER) ? ub_ptr : eb_ptr; + Mem_read_nopage(); + goto no_fetch; } +#endif + /* Handle indirection repeat until no longer indirect */ do { - if (pi_enable & !pi_cycle & pi_pending) { + if (pi_enable & !pi_cycle & pi_pending +#if KI | KL + & trap_flag == 0 +#endif + ) { pi_rq = check_irq_level(); } ind = (MB & 020000000) != 0; @@ -1407,10 +1405,28 @@ no_fetch: } } while (ind & !pi_rq); - /* Update final address into history. */ - if (hst_lnt) { - hst[hst_p].ea = AB; + /* Update history */ + if (hst_lnt && PC > 020 && (PC & 0777774) != 0472174 && + (PC & 0777700) != 023700 && (PC != 0527154)) { + hst_p = hst_p + 1; + if (hst_p >= hst_lnt) { + hst_p = 0; +// reason = STOP_IBKPT; + } + hst[hst_p].pc = HIST_PC | ((BYF5)? (HIST_PC2|PC) : PC); + hst[hst_p].ea = AB; + hst[hst_p].ir = AD; + hst[hst_p].flags = (FLAGS << 5) |(clk_flg << 2) | (nxm_flag << 1) +#if KA + | (mem_prot << 4) | (push_ovf << 3) +#endif + ; + hst[hst_p].ac = get_reg(AC); } +// /* Update final address into history. */ +// if (hst_lnt) { +// hst[hst_p].ea = AB; +// } /* If there is a interrupt handle it. */ if (pi_rq) { @@ -1458,7 +1474,7 @@ fetch_opr: sac_inh = 0; #if KI | KL modify = 0; - f_pc_inh = trap_flag; + f_pc_inh = (trap_flag != 0); #else f_pc_inh = 0; #endif @@ -1522,10 +1538,11 @@ unasign: AB = ub_ptr | 0424; Mem_write_nopage(); AB |= 1; - MB = (FLAGS << 23) | ((PC + 1) & RMASK); + MB = (FLAGS << 23) | ((PC + (trap_flag == 0)) & RMASK); Mem_write_nopage(); + FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); AB = ub_ptr | 0430; - if (trap_flag) + if (trap_flag != 0) AB |= 1; if (FLAGS & PUBLIC) AB |= 2; @@ -1763,6 +1780,9 @@ dpnorm: case 0120: /* DMOVE */ AB = (AB + 1) & RMASK; +#if KI | KL + modify = 0; +#endif if (Mem_read(0, 0)) goto last; MQ = MB; @@ -1770,6 +1790,9 @@ dpnorm: case 0121: /* DMOVN */ AB = (AB + 1) & RMASK; +#if KI | KL + modify = 0; +#endif if (Mem_read(0, 0)) goto last; MQ = ((MB & CMASK) ^ CMASK) + 1; /* Low */ @@ -1894,12 +1917,12 @@ unasign: case 0134: /* ILDB */ case 0136: /* IDPB */ if ((FLAGS & BYTI) == 0) { /* BYF6 */ - if (Mem_read(0, 1)) - goto last; - AR = MB; #if KI | KL modify = 1; #endif + if (Mem_read(0, 1)) + goto last; + AR = MB; SC = (AR >> 24) & 077; SCAD = (((AR >> 30) & 077) + (0777 ^ SC) + 1) & 0777; if (SCAD & 0400) { @@ -2717,11 +2740,17 @@ fxnorm: } } AB = (AR >> 18) & RMASK; - if (Mem_read(0, 0)) - break; + if (Mem_read(0, 0)) { + f_pc_inh = 1; + set_reg(AC, AR); + goto last; + } AB = (AR & RMASK); - if (Mem_write(0, 0)) - break; + if (Mem_write(0, 0)) { + f_pc_inh = 1; + set_reg(AC, AR); + goto last; + } AD = (AR & RMASK) + CM(BR) + 1; AR = AOB(AR); } while ((AD & C1) == 0); @@ -2746,13 +2775,17 @@ fxnorm: break; case 0254: /* JRST */ /* AR Frm PC */ - PC = AR & RMASK; if (uuo_cycle | pi_cycle) { FLAGS &= ~USER; /* Clear USER */ } /* JEN */ if (AC & 010) { /* Restore interrupt level. */ +#if KI | KL + if ((FLAGS & (USER|USERIO)) == USER || + (FLAGS & (USER|PUBLIC)) == PUBLIC) { +#else if ((FLAGS & (USER|USERIO)) == USER) { +#endif goto muuo; } else { pi_restore = 1; @@ -2760,23 +2793,30 @@ fxnorm: } /* HALT */ if (AC & 04) { +#if KI | KL + if ((FLAGS & (USER|USERIO)) == USER || + (FLAGS & (USER|PUBLIC)) == PUBLIC) { +#else if ((FLAGS & (USER|USERIO)) == USER) { +#endif goto muuo; } else { reason = STOP_HALT; } } + PC = AR & RMASK; /* JRSTF */ if (AC & 02) { FLAGS &= ~(OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0); AR >>= 23; /* Move into position */ /* If executive mode, copy USER and UIO */ - if ((FLAGS & USER) == 0) - FLAGS |= AR & (USER|USERIO); + if ((FLAGS & (PUBLIC|USER)) == 0) + FLAGS |= AR & (USER|USERIO|PUBLIC); /* Can always clear UIO */ if ((AR & USERIO) == 0) FLAGS &= ~USERIO; - FLAGS |= AR & (OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0|PUBLIC); + FLAGS |= AR & (OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0|\ + TRP1|TRP2|PUBLIC); check_apr_irq(); } @@ -2794,8 +2834,10 @@ fxnorm: case 0255: /* JFCL */ if ((FLAGS >> 9) & AC) { PC = AR & RMASK; - f_pc_inh = 1; + } else { + PC = (PC + 1) & RMASK; } + f_pc_inh = 1; FLAGS &= 017777 ^ (AC << 9); break; @@ -2811,6 +2853,8 @@ fxnorm: case 0257: /* MAP */ #if KI | KL f = AB >> 9; + last_page = ((f ^ 0777) << 1); + pag_reload &= 037; if ((FLAGS & USER) != 0) { /* Check if small user and outside range */ if (small_user && (f & 0340) != 0) { @@ -2835,24 +2879,34 @@ fxnorm: AR = 0020000LL + f; /* direct map */ break; } + last_page |= 1; } AB = (AR + (f >> 1)) & RMASK; + pag_reload = ((pag_reload + 1) & 037) | 040; if (Mem_read(0, 0)) goto last; AR = MB; if ((f & 1) == 0) AR >>= 18; - AR &= 0357777LL; + if ((AR & LSIGN) == 0) { + AR = 0437777LL; /* Return invalid if not accessable */ + } else { + AR &= 0357777LL; + if ((AR & 0100000LL) == 0) + AR |= LSIGN; + } #endif break; /* Stack, JUMP */ case 0260: /* PUSHJ */ /* AR Frm PC */ MB = ((uint64)(FLAGS) << 23) | ((PC + !pi_cycle) & RMASK); - FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); BR = AB; AR = AOB(AR); AB = AR & RMASK; + if (Mem_write(uuo_cycle | pi_cycle, 0)) + goto last; + FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); if (AR & C1) { #if KI | KL if (!pi_cycle) @@ -2866,7 +2920,6 @@ fxnorm: if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } - Mem_write(uuo_cycle | pi_cycle, 0); PC = BR & RMASK; f_pc_inh = 1; break; @@ -2929,14 +2982,16 @@ fxnorm: break; case 0264: /* JSR */ /* AR Frm PC */ - AD = ((uint64)(FLAGS) << 23) | + MB = ((uint64)(FLAGS) << 23) | ((PC + !pi_cycle) & RMASK); - FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } - PC = (AR + pi_cycle) & RMASK; - AR = AD; + if (Mem_write(0, 0)) + goto last; + FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); + PC = (AR + 1) & RMASK; + f_pc_inh = 1; break; case 0265: /* JSP */ /* AR Frm PC */ @@ -3464,7 +3519,13 @@ test_op: case 0764: case 0765: case 0766: case 0767: case 0770: case 0771: case 0772: case 0773: case 0774: case 0775: case 0776: case 0777: +#if KI + if (!pi_cycle && ((FLAGS & (USER|USERIO)) == USER && + (IR & 040) == 0 || (FLAGS & (USER|PUBLIC)) == PUBLIC)) { + +#else if ((FLAGS & (USER|USERIO)) == USER && !pi_cycle) { +#endif /* User and not User I/O */ goto muuo; } else { @@ -3545,8 +3606,24 @@ test_op: hst[hst_p].fmb = AR; } - last: +#if KI | KL + /* Handle page fault and traps */ + if (page_enable && (page_fault || private_page)) { + page_fault = private_page = 0; + AB = ub_ptr + ((FLAGS & USER) ? 0427 : 0426); + MB = fault_data; + Mem_write_nopage(); + FLAGS |= trap_flag & (TRP1|TRP2); + trap_flag = 1; + AB = 0420; + f_pc_inh = 1; + pi_cycle = 1; + AB += (FLAGS & USER) ? ub_ptr : eb_ptr; + Mem_read_nopage(); + goto no_fetch; + } +#endif if (!f_pc_inh && !pi_cycle) { PC = (PC + 1) & RMASK; diff --git a/PDP10/ka10_cty.c b/PDP10/ka10_cty.c index 5568378..e44d93a 100644 --- a/PDP10/ka10_cty.c +++ b/PDP10/ka10_cty.c @@ -55,7 +55,7 @@ t_stat cty_devio(uint32 dev, uint64 *data); DIB cty_dib = { CTY_DEVNUM, 1, cty_devio, NULL}; UNIT cty_unit[] = { - { UDATA (&ctyo_svc, TT_MODE_7P, 0), 100 }, + { UDATA (&ctyo_svc, TT_MODE_7P, 0), 10000 }, { UDATA (&ctyi_svc, TT_MODE_7P|UNIT_IDLE, 0), 0 }, }; @@ -109,6 +109,7 @@ t_stat cty_devio(uint32 dev, uint64 *data) { break; case DATAO: cty_unit[0].u4 = *data & 0x7f; + cty_unit[0].u3 &= ~TEL_RDY; cty_unit[0].u3 |= TEL_BSY; sim_activate(&cty_unit[0], cty_unit[0].wait); break; @@ -123,11 +124,13 @@ t_stat ctyo_svc (UNIT *uptr) t_stat r; int32 ch; + if (uptr->u4 != 0) { ch = sim_tt_outcvt ( uptr->u4, TT_GET_MODE (uptr->flags)) ; - if ((r = sim_putchar_s (ch)) != SCPE_OK) { /* output; error? */ - sim_activate (uptr, uptr->wait); /* try again */ - return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */ + if ((r = sim_putchar_s (ch)) != SCPE_OK) { /* output; error? */ + sim_activate (uptr, uptr->wait); /* try again */ + return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */ } + } uptr->u3 &= ~TEL_BSY; uptr->u3 |= TEL_RDY; set_interrupt(CTY_DEVNUM, uptr->u5); @@ -139,10 +142,10 @@ t_stat ctyi_svc (UNIT *uptr) int32 ch; sim_clock_coschedule (uptr, tmxr_poll); - /* continue poll */ - if ((ch = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */ + /* continue poll */ + if ((ch = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */ return ch; - if (ch & SCPE_BREAK) /* ignore break */ + if (ch & SCPE_BREAK) /* ignore break */ return SCPE_OK; uptr->u4 = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (uptr->flags)); uptr->u4 = ch & 0177; diff --git a/PDP10/ka10_defs.h b/PDP10/ka10_defs.h index 78473b8..d658e5a 100644 --- a/PDP10/ka10_defs.h +++ b/PDP10/ka10_defs.h @@ -184,7 +184,7 @@ extern DEBTAB crd_debug[]; #define USERIO 000100 /* 004000 */ #define USER 000200 /* 010000 */ #define BYTI 000400 /* 020000 */ -#ifdef PDP6 +#if PDP6 #define FLTOVR 000000 #define PCHNG 001000 /* 040000 */ #else diff --git a/PDP10/ka10_df.c b/PDP10/ka10_df.c index c913632..4650642 100644 --- a/PDP10/ka10_df.c +++ b/PDP10/ka10_df.c @@ -55,7 +55,7 @@ int df10_fetch(struct df10 *df) { } data = M[df->ccw]; while((data & (WMASK << CSHIFT)) == 0) { - if ((data & AMASK) == 0) { + if ((data & AMASK) == 0 || (uint32)(data & AMASK) == df->ccw) { df10_finish_op(df,0); return 0; } diff --git a/PDP10/ka10_dp.c b/PDP10/ka10_dp.c index 5636aa6..8d40288 100644 --- a/PDP10/ka10_dp.c +++ b/PDP10/ka10_dp.c @@ -52,11 +52,12 @@ #define DATAPTR u4 /* data pointer */ #define UFLAGS u5 /* Function */ #define STATUS u6 /* Drive status */ +#define SECT_CNT up7 /* Sector counter */ +#define CONTROL 007 +#define CMD_MASK 070 #define SEEK_DONE 0100 /* Seek finished */ #define SEEK_STATE 0200 /* Seek in progress */ #define DONE 0400 /* Done bit */ -#define CMD_MASK 070 -#define CONTROL 007 /* CONI/CONO Flags */ @@ -101,6 +102,7 @@ #define NO 6 #define RC 7 +/* DATAI Flags */ #define ATTN 0000000000776LL #define DEFECT 0000000001000LL #define SEL_RP03 0000000002000LL @@ -328,6 +330,7 @@ t_stat dp_devio(uint32 dev, uint64 *data) { int unit; int cyl; int tmp; + static int sect_count; if (ctlr < 0 || ctlr > NUM_DEVS_DP) return SCPE_OK; @@ -343,15 +346,15 @@ t_stat dp_devio(uint32 dev, uint64 *data) { #endif sim_debug(DEBUG_CONI, dptr, "DP %03o CONI %012llo %d PC=%o\n", dev, *data, ctlr, PC); - return SCPE_OK; + break; case CONO: clr_interrupt(dev); df10->status &= ~07LL; df10->status |= *data & 07LL; - if (*data & BUSY && df10->status & BUSY) { - /* Stop controller */ - sim_cancel(uptr); + if (*data & BUSY) { + /* Stop controller */ + uptr->STATUS &= ~BUSY; df10_finish_op(df10, 0); } /* Clear flags */ @@ -379,7 +382,7 @@ t_stat dp_devio(uint32 dev, uint64 *data) { } sim_debug(DEBUG_CONO, dptr, "DP %03o CONO %06o %d PC=%o %06o\n", dev, (uint32)*data, ctlr, PC, df10->status); - return SCPE_OK; + break; case DATAI: res = (uint64)(unit) << 33; @@ -394,6 +397,10 @@ t_stat dp_devio(uint32 dev, uint64 *data) { res |= ((uint64)(cyl & 0377)) << 25; if (cyl & 0400) res |= SEL_CYL256; + if (sect_count > 20) + sect_count = 0; + res |= SEL_SEC & (uint64)(sect_count << 13); + sect_count++; if ((uptr->UFLAGS & SEEK_STATE) == 0) res |= ON_CYL; if (uptr->flags & UNIT_WPRT) @@ -405,10 +412,10 @@ t_stat dp_devio(uint32 dev, uint64 *data) { res |= 0400>>unit; uptr++; } - sim_debug(DEBUG_DATAIO, dptr, "DP %03o DATI %012llo %d PC=%o F=%o\n", - dev, res, ctlr, PC, uptr->UFLAGS); + sim_debug(DEBUG_DATAIO, dptr, "DP %03o DATI %012llo %d PC=%o F=%o %o\n", + dev, res, ctlr, PC, uptr->UFLAGS, sect_count); *data = res; - return SCPE_OK; + break; case DATAO: sim_debug(DEBUG_DATAIO, dptr, "DP %03o DATO %012llo, %d PC=%o\n", @@ -450,12 +457,12 @@ t_stat dp_devio(uint32 dev, uint64 *data) { df10_setirq(df10); return SCPE_OK; } - //uptr->STATUS &= ~(SRC_DONE|END_CYL); uptr->UFLAGS = ((*data & (SURFACE|SECTOR)) >> 3) | (cyl << 20) | (tmp << 3) | ctlr; uptr->DATAPTR = 0; /* Set no data */ CLR_BUF(uptr); df10_setup(df10, (uint32)*data); + uptr->STATUS |= BUSY; break; case WH: @@ -470,6 +477,7 @@ t_stat dp_devio(uint32 dev, uint64 *data) { case RC: cyl = 0; + uptr->STATUS |= NOT_RDY; case SK: if ((uptr->flags & UNIT_ATT) == 0) { uptr->STATUS |= NOT_RDY; @@ -502,10 +510,9 @@ t_stat dp_devio(uint32 dev, uint64 *data) { } return SCPE_OK; } - sim_activate(uptr, 100); - return SCPE_OK; + sim_activate(uptr, 150); } - return SCPE_OK; /* Unreached */ + return SCPE_OK; } @@ -513,10 +520,10 @@ t_stat dp_svc (UNIT *uptr) { int dtype = GET_DTYPE(uptr->flags); int ctlr = uptr->UFLAGS & 03; - int cyl = (uptr->UFLAGS >> 20) & 0777; int cmd = (uptr->UFLAGS & 070) >> 3; int sect = (uptr->UFLAGS >> 9); int surf = (sect >> 5) & 037; + int cyl = (uptr->UFLAGS >> 20) & 0777; DEVICE *dptr = dp_devs[ctlr]; struct df10 *df10 = &dp_df10[ctlr]; int diff, diffs, wc; @@ -532,6 +539,7 @@ t_stat dp_svc (UNIT *uptr) 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); + uptr->STATUS |= SRC_DONE; if (uptr->STATUS & END_CYL) { uptr->UFLAGS |= DONE; df10_finish_op(df10, 0); @@ -555,6 +563,10 @@ t_stat dp_svc (UNIT *uptr) df10_finish_op(df10, 0); return SCPE_OK; } + if ((uptr->STATUS & BUSY) == 0) { + df10_finish_op(df10, 0); + return SCPE_OK; + } if (cmd != WR) { /* Read the block */ int da = ((cyl * dp_drv_tab[dtype].surf + surf) @@ -562,7 +574,6 @@ t_stat dp_svc (UNIT *uptr) sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); wc = sim_fread (&dp_buf[ctlr][0], sizeof(uint64), RP_NUMWD, uptr->fileref); - uptr->STATUS |= SRC_DONE; for (; wc < RP_NUMWD; wc++) dp_buf[ctlr][wc] = 0; uptr->hwmark = RP_NUMWD; @@ -583,8 +594,10 @@ t_stat dp_svc (UNIT *uptr) } } else { uptr->DATAPTR = 0; - CLR_BUF(uptr); + uptr->hwmark = 0; } + sim_activate(uptr, 50); + return SCPE_OK; } switch(cmd) { case WR: @@ -594,8 +607,6 @@ t_stat dp_svc (UNIT *uptr) dp_buf[ctlr][uptr->DATAPTR] = df10->buf; break; case RV: - r = 1; - break; case RD: df10->buf = dp_buf[ctlr][uptr->DATAPTR]; r = df10_write(df10); @@ -635,8 +646,10 @@ t_stat dp_svc (UNIT *uptr) } if (r) sim_activate(uptr, 25); - else + else { + uptr->STATUS &= ~(SRC_DONE|BUSY); uptr->UFLAGS |= DONE; + } break; case CL: @@ -653,20 +666,20 @@ t_stat dp_svc (UNIT *uptr) if (diff == 0) { uptr->UFLAGS |= SEEK_DONE; uptr->UFLAGS &= ~SEEK_STATE; - uptr->STATUS &= ~BUSY; + uptr->STATUS &= ~(BUSY|NOT_RDY); df10_setirq(df10); } else if (diff < 10 && diff > -10) { uptr->CUR_CYL += diffs; if (uptr->CUR_CYL < 0) { uptr->UFLAGS |= SEEK_DONE; uptr->UFLAGS &= ~SEEK_STATE; - uptr->STATUS &= ~BUSY; + uptr->STATUS &= ~(BUSY|NOT_RDY); uptr->CUR_CYL = 0; df10_setirq(df10); } else if (uptr->CUR_CYL > dp_drv_tab[dtype].cyl) { uptr->UFLAGS |= SEEK_DONE; uptr->UFLAGS &= ~SEEK_STATE; - uptr->STATUS &= ~BUSY; + uptr->STATUS &= ~(BUSY|NOT_RDY); uptr->CUR_CYL = dp_drv_tab[dtype].cyl; df10_setirq(df10); } else @@ -714,6 +727,7 @@ dp_reset(DEVICE * dptr) uptr++; } for (ctlr = 0; ctlr < NUM_DEVS_DP; ctlr++) { + dp_df10[ctlr].status = 0; dp_df10[ctlr].devnum = dp_dib[ctlr].dev_num; dp_df10[ctlr].nxmerr = 12; dp_df10[ctlr].ccw_comp = 5; @@ -782,10 +796,9 @@ t_stat dp_detach (UNIT *uptr) t_stat dp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { fprintf (st, "RP10 RP01/2/3 Disk Pack Drives (DP)\n\n"); -fprintf (st, "The DP controller implements the Massbus family of large disk drives. RP\n"); +fprintf (st, "The DP controller implements the RP10 disk drives. RP\n"); fprintf (st, "options include the ability to set units write enabled or write locked, to\n"); -fprintf (st, "set the drive type to one of six disk types or autosize, and to write a DEC\n"); -fprintf (st, "standard 044 compliant bad block table on the last track.\n\n"); +fprintf (st, "set the drive type to one of three disk types.\n"); fprint_set_help (st, dptr); fprint_show_help (st, dptr); fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n"); diff --git a/PDP10/ka10_rc.c b/PDP10/ka10_rc.c index 19dbb18..bf7d8a9 100644 --- a/PDP10/ka10_rc.c +++ b/PDP10/ka10_rc.c @@ -29,9 +29,6 @@ #if (NUM_DEVS_RC > 0) -#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) -#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF - #define RC_DEVNUM 0170 /* 0174 */ #define NUM_UNITS_RC 4 @@ -200,6 +197,8 @@ t_stat rc_devio(uint32 dev, uint64 *data) { int unit; int tmp; int drv; + int cyl; + int dtype; if (ctlr < 0 || ctlr > NUM_DEVS_RC) return SCPE_OK; @@ -221,19 +220,25 @@ t_stat rc_devio(uint32 dev, uint64 *data) { df10->status &= ~07; df10->status |= *data & 07; df10->status &= ~(RST_MSK & *data); - if ((*data & BUSY) && (df10->status & BUSY)) { + if ((*data & BUSY) != 0) { unit = rc_ipr[ctlr] & 3; drv = unit + (ctlr * NUM_UNITS_RC); uptr = &rc_unit[drv]; - sim_cancel(uptr); - df10_finish_op(df10, 0); + if ((df10->status & BUSY) != 0) { + sim_cancel(uptr); + df10_finish_op(df10, 0); + } else { + df10->status &= ~BUSY; + df10_setirq(df10); + } } rc_ipr[ctlr] &= ~SEC_SCTR; rc_ipr[ctlr] |= *data & SEC_SCTR; - if (*data & CCW_COMP) { + if ((df10->status & BUSY) != 0 && (*data & CCW_COMP) != 0) { df10_writecw(df10); - } + } else + df10->status &= ~CCW_COMP; sim_debug(DEBUG_CONO, dptr, "HK %03o CONO %06o PC=%o %06o\n", dev, (uint32)*data, PC, df10->status); break; @@ -260,21 +265,48 @@ t_stat rc_devio(uint32 dev, uint64 *data) { drv = unit + (ctlr * NUM_UNITS_RC); uptr = &rc_unit[drv]; if ((uptr->flags & UNIT_ATT) == 0) { + df10->status &= ~BUSY; df10->status |= NOT_RDY; df10_setirq(df10); return SCPE_OK; } if ((uptr->flags & UNIT_WPRT) && *data & WRITE) { + df10->status &= ~BUSY; df10->status |= ILL_WR; df10_setirq(df10); return SCPE_OK; } - tmp = (uint32)(*data >> 15); df10_setup(df10, (uint32)*data); + tmp = (uint32)(*data >> 15) & ~07; + cyl = (tmp >> 10) & 0777; + if (((cyl & 017) > 9) || (((cyl >> 4) & 017) > 9)) { + sim_debug(DEBUG_DETAIL, dptr, "HK %d non-bcd cyl %02x\n", + ctlr, cyl); + df10_finish_op(df10, TRK_SEL_E); + return SCPE_OK; + } + cyl = (((cyl >> 4) & 017) * 10) + (cyl & 017) + + ((cyl & 0x100) ? 100 : 0); + dtype = GET_DTYPE(uptr->flags); + if (cyl >= rc_drv_tab[dtype].cyl) { + sim_debug(DEBUG_DETAIL, dptr, "HK %d invalid cyl %d %d\n", + ctlr, cyl, rc_drv_tab[dtype].cyl); + df10_finish_op(df10, TRK_SEL_E); + return SCPE_OK; + } + cyl = (tmp >> 3) & 0177; + if ((cyl & 017) > 9) { + sim_debug(DEBUG_DETAIL, dptr, "HK %d non-bcd seg %02x\n", + ctlr, cyl); + df10_finish_op(df10, TRK_SEL_E); + return SCPE_OK; + } uptr->UFLAGS = tmp | ((*data & WRITE) != 0) | (ctlr << 1); uptr->DATAPTR = -1; /* Set no data */ - CLR_BUF(uptr); - sim_activate(uptr, 200); + if ((*data & WRITE) != 0) + df10_read(df10); + sim_debug(DEBUG_DETAIL, dptr, "HK %d cyl %o\n", ctlr, uptr->UFLAGS); + sim_activate(uptr, 100); break; } return SCPE_OK; @@ -297,18 +329,12 @@ t_stat rc_svc (UNIT *uptr) dptr = rc_devs[ctlr]; /* Check if we need to seek */ if (uptr->DATAPTR == -1) { - if (((cyl & 017) > 10) || (((cyl >> 4) & 017) > 10)) { - sim_debug(DEBUG_DETAIL, dptr, "HK %d non-bcd cyl %02x %d %o\n", - ctlr, cyl, rc_drv_tab[dtype].seg, uptr->UFLAGS); - df10_finish_op(df10, TRK_SEL_E); - return SCPE_OK; - } cyl = (((cyl >> 4) & 017) * 10) + (cyl & 017) + ((cyl & 0x100) ? 100 : 0); if (cyl >= rc_drv_tab[dtype].cyl) { sim_debug(DEBUG_DETAIL, dptr, "HK %d invalid cyl %d %d %o\n", ctlr, cyl, rc_drv_tab[dtype].cyl, uptr->UFLAGS); - df10_finish_op(df10, S_ERROR); + df10_finish_op(df10, TRK_SEL_E); return SCPE_OK; } /* Convert segment from BCD to binary */ @@ -342,12 +368,15 @@ t_stat rc_svc (UNIT *uptr) df10->status |= SCRCHCMP; } if (wr) { - r = df10_read(df10); rc_buf[ctlr][uptr->DATAPTR] = df10->buf; + r = df10_read(df10); } else { df10->buf = rc_buf[ctlr][uptr->DATAPTR]; r = df10_write(df10); } + sim_debug(DEBUG_DATA, dptr, "Xfer %d %012llo %06o %06o\n", uptr->DATAPTR, df10->buf, + df10->wcr, df10->cda); + uptr->DATAPTR++; if (uptr->DATAPTR >= seg_size || r == 0 ) { /* Check if writing */ @@ -364,7 +393,7 @@ t_stat rc_svc (UNIT *uptr) } da = ((cyl * rc_drv_tab[dtype].seg) + seg) * seg_size; sim_debug(DEBUG_DETAIL, dptr, "HK %d Write %d %d %d %x %d\n", - ctlr, da, cyl, seg, uptr->UFLAGS << 1, uptr->hwmark ); + ctlr, da, cyl, seg, uptr->UFLAGS << 1, uptr->DATAPTR ); err = sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET); wc = sim_fwrite(&rc_buf[ctlr][0],sizeof(uint64), seg_size, uptr->fileref); @@ -394,7 +423,7 @@ t_stat rc_svc (UNIT *uptr) uptr->UFLAGS = (uptr->UFLAGS & 7) + (seg << 3) + (cyl << 10); } if ((df10->status & PI_ENABLE) == 0) { - sim_activate(uptr, 25); + sim_activate(uptr, 20); } return SCPE_OK; } @@ -427,6 +456,8 @@ rc_reset(DEVICE * dptr) uptr++; } for (ctlr = 0; ctlr < NUM_DEVS_RC; ctlr++) { + rc_ipr[ctlr] = 0; + rc_df10[ctlr].status = 0; rc_df10[ctlr].devnum = rc_dib[ctlr].dev_num; rc_df10[ctlr].nxmerr = 8; rc_df10[ctlr].ccw_comp = 5; @@ -491,14 +522,14 @@ return detach_unit (uptr); t_stat rc_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { fprintf (st, "RD10/RM10 Disk Pack Drives (RC)\n\n"); -fprintf (st, "The RC controller implements the Massbus family of large disk drives. RP\n"); -fprintf (st, "options include the ability to set units write enabled or write locked, to\n"); -fprintf (st, "set the drive type to one of six disk types or autosize, and to write a DEC\n"); -fprintf (st, "standard 044 compliant bad block table on the last track.\n\n"); +fprintf (st, "The RC controller implements the RC-10 disk controller that talked\n"); +fprintf (st, "to either RD10 mountable pack or RM10 drum drives.\n"); +fprintf (st, "Options include the ability to set units write enabled or write locked, to\n"); +fprintf (st, "set the drive type to one of two disk types\n\n"); fprint_set_help (st, dptr); fprint_show_help (st, dptr); fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n"); -fprintf (st, "The RP device supports the BOOT command.\n"); +fprintf (st, "The RC device supports the BOOT command.\n"); fprint_reg_help (st, dptr); return SCPE_OK; }