diff --git a/PDP10/kl10_fe.c b/PDP10/kl10_fe.c index 0f7f4c3..ebaf7c2 100644 --- a/PDP10/kl10_fe.c +++ b/PDP10/kl10_fe.c @@ -104,8 +104,8 @@ #define SEC_RTM 05400 #define SEC_CMDMSK 07400 #define DTE_MON 00000001 /* Save in unit1 STATUS */ -#define SEC_CLK 00000001 /* Clock enabled */ -#define DTE_ACK_CTY 00000002 /* Send CTY Ack */ +#define SEC_CLK 00000002 /* Clock enabled */ +#define ITS_ON 00000004 /* ITS Is alive */ /* Primary or Queued protocol addresses */ #define PRI_CMTW_0 0 @@ -157,6 +157,20 @@ #define PRI_EMCLK 007 /* Clock */ #define PRI_EMFED 010 /* Front end device */ +#if KL_ITS +/* ITS Timesharing protocol locations */ +#define ITS_DTEVER 0400 /* Protocol version and number of devices */ +#define ITS_DTECHK 0401 /* Increment at 60Hz. Ten setom 2 times per second */ +#define ITS_DTEINP 0402 /* Input from 10 to 11. Line #, Count */ +#define ITS_DTEOUT 0403 /* Output from 10 to 11 Line #, Count */ +#define ITS_DTELSP 0404 /* Line # to set speed of */ +#define ITS_DTELPR 0405 /* Parameter */ +#define ITS_DTEOST 0406 /* Line # to start output on */ +#define ITS_DTETYI 0410 /* Received char (Line #, char) */ +#define ITS_DTEODN 0411 /* Output done (Line #, buffer size) */ +#define ITS_DTEHNG 0412 /* Hangup/dialup */ +#endif + #define TMR_RTC 2 extern int32 tmxr_poll; @@ -164,6 +178,9 @@ t_stat dte_devio(uint32 dev, uint64 *data); int dte_devirq(uint32 dev, int addr); void dte_second(UNIT *uptr); void dte_primary(UNIT *uptr); +#if KL_ITS +void dte_its(UNIT *uptr); +#endif void dte_transfer(UNIT *uptr); void dte_function(UNIT *uptr); int dte_start(UNIT *uptr); @@ -178,6 +195,11 @@ t_stat dte_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cpt const char *dte_description (DEVICE *dptr); extern uint64 SW; /* Switch register */ +#if KL_ITS +#define QITS (cpu_unit[0].flags & UNIT_ITSPAGE) +#else +#define QITS 0 +#endif #define STATUS u3 #define CNT u4 @@ -319,6 +341,7 @@ DEVICE lpt_dev = { #if (NUM_DEVS_TTY > 0) struct _buffer tty_out[NUM_LINES_TTY], tty_in[NUM_LINES_TTY]; +struct _buffer tty_done, tty_hang; TMLN tty_ldsc[NUM_LINES_TTY] = { 0 }; /* Line descriptors */ TMXR tty_desc = { NUM_LINES_TTY, 0, 0, tty_ldsc }; int tty_connect[NUM_LINES_TTY];; @@ -479,6 +502,14 @@ void dte_second(UNIT *uptr) { #endif /* read command */ word = M[SEC_DTCMD + base]; +#if KL_ITS + if (word == 0 && QITS && (uptr->STATUS & ITS_ON) != 0) { + dte_its(uptr); + uptr->STATUS |= DTE_10DB; + uptr->STATUS &= ~DTE_11DB; + return; + } +#endif /* Do it */ sim_debug(DEBUG_DETAIL, &dte_dev, "CTY secondary %012llo\n", word); switch(word & SEC_CMDMSK) { @@ -564,11 +595,142 @@ enter_pri: break; } /* Acknowledge command */ + M[SEC_DTCMD + base] = 0; M[SEC_DTFLG + base] = FMASK; uptr->STATUS |= DTE_10DB; uptr->STATUS &= ~DTE_11DB; } +#if KL_ITS +void dte_its(UNIT *uptr) { + uint64 word; + char ch; + uint16 data; + int cnt; + int ln; + t_stat r; + + /* Check for output Start */ + word = M[ITS_DTEOST]; + if ((word & SMASK) == 0) { + if (((tty_done.in_ptr + 1) & 0xff) != tty_done.out_ptr) { + tty_done.buff[tty_done.in_ptr] = (char)(word & 0xff); + tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff; + M[ITS_DTEOST] = FMASK; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOST = %012llo\n", word); + } + } + /* Check for input Start */ + word = M[ITS_DTEINP]; + if ((word & SMASK) == 0) { + M[ITS_DTEINP] = FMASK; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEINP = %012llo\n", word); + } + /* Check for output Start */ + word = M[ITS_DTEOUT]; + if ((word & SMASK) == 0) { + cnt = word & 017777; + ln = ((word >> 18) & 077) - 1; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOUT = %012llo\n", word); + while (cnt > 0) { + if (ln < 0) { + if (!Mem_read_byte(0, &data)) + return; + ch = (data >> 8) & 0177; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY type %x\n", ch); + ch = sim_tt_outcvt( ch, TT_GET_MODE(uptr->flags)); + if ((r = sim_putchar_s (ch)) != SCPE_OK) /* Output errors */ + return; + cnt--; + if (cnt) { + ch = data & 0177; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY type %x\n", ch); + ch = sim_tt_outcvt( ch, TT_GET_MODE(uptr->flags)); + if ((r = sim_putchar_s (ch)) != SCPE_OK) /* Output errors */ + return; + cnt--; + } + } else { + if (!Mem_read_byte(0, &data)) + return; + ch = (data >> 8) & 0177; + if (((tty_out[ln].in_ptr + 1) & 0xff) == tty_out[ln].out_ptr) + return; + sim_debug(DEBUG_DETAIL, &dte_dev, "TTY queue %x %d\n", ch, ln); + tty_out[ln].buff[tty_out[ln].in_ptr] = ch; + tty_out[ln].in_ptr = (tty_out[ln].in_ptr + 1) & 0xff; + cnt--; + if (cnt) { + ch = data & 0177; + if (((tty_out[ln].in_ptr + 1) & 0xff) == tty_out[ln].out_ptr) + return; + sim_debug(DEBUG_DETAIL, &dte_dev, "TTY queue %x %d\n", ch, ln); + tty_out[ln].buff[tty_out[ln].in_ptr] = ch; + tty_out[ln].in_ptr = (tty_out[ln].in_ptr + 1) & 0xff; + cnt--; + } + } + } + /* If on CTY Queue output done response */ + if (ln < 0) { + if (((tty_done.in_ptr + 1) & 0xff) != tty_done.out_ptr) { + tty_done.buff[tty_done.in_ptr] = (char)(0 & 0xff); + tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff; + } + } + M[ITS_DTEOUT] = FMASK; + uptr->STATUS |= DTE_11DN; + if (uptr->STATUS & DTE_PIE) + set_interrupt(DTE_DEVNUM, uptr->STATUS); + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOUT = %012llo\n", word); + } + /* Check for line speed */ + word = M[ITS_DTELSP]; + if ((word & SMASK) == 0) { + M[ITS_DTELSP] = FMASK; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTELSP = %012llo %012llo\n", word, M[ITS_DTELPR]); + } +#if 0 + /* Check for input */ + word = M[ITS_DTETYI]; + if ((word & SMASK) != 0) { + int l = uptr->CNT; + do { + if (tty_connect[l]) { +// if ((ch = dte_unit[1].CHHOLD) != 0) { +// word = ch; +// dte_unit[1].CHHOLD = 0; +// M[ITS_DTETYI] = word; +// /* Tell 10 something is ready */ +// uptr->STATUS |= DTE_10DB; +// if (uptr->STATUS & DTE_PIE) +// set_interrupt(DTE_DEVNUM, uptr->STATUS); +// } + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTETYI = %012llo\n", word); + } +#endif + /* Check for output done */ + word = M[ITS_DTEODN]; + if ((word & SMASK) != 0) { + if (tty_done.in_ptr != tty_done.out_ptr) { + ln = tty_done.buff[tty_done.out_ptr]; + tty_done.out_ptr = (tty_done.out_ptr + 1) & 0xff; + word = M[ITS_DTEODN] = (((uint64)ln) << 18)|1; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEODN = %012llo\n", word); + /* Tell 10 something is ready */ + uptr->STATUS |= DTE_10DB; + if (uptr->STATUS & DTE_PIE) + set_interrupt(DTE_DEVNUM, uptr->STATUS); + } + } + /* Check for hangup */ + word = M[ITS_DTEHNG]; + if ((word & SMASK) == 0) { + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEHNG = %012llo\n", word); + } +} +#endif + /* Handle primary protocol */ void dte_primary(UNIT *uptr) { uint64 word, iword; @@ -1049,10 +1211,12 @@ t_stat dtei_svc (UNIT *uptr) uint16 data1; #if KI_22BIT +#if KL_ITS + if ((cpu_unit[0].flags & UNIT_ITSPAGE) == 0) +#endif base = eb_ptr; #endif - - sim_clock_coschedule (uptr, 1000); + sim_activate (uptr, 1000); if ((uptr->STATUS & DTE_SEC) == 0) { dte_function(uptr); /* Process queue */ dte_start(optr); @@ -1067,6 +1231,24 @@ t_stat dtei_svc (UNIT *uptr) uptr->CHHOLD = ch; } sim_debug(DEBUG_DETAIL, &dte_dev, "CTY char %x\n", ch); +#if KL_ITS + if (QITS && (optr->STATUS & ITS_ON) != 0) { + uint64 word = M[ITS_DTETYI]; + if ((word & SMASK) != 0) { + if (ch != 0) { + word = ch; + uptr->CHHOLD = 0; + M[ITS_DTETYI] = word; + /* Tell 10 something is ready */ + optr->STATUS |= DTE_10DB; + if (optr->STATUS & DTE_PIE) + set_interrupt(DTE_DEVNUM, optr->STATUS); + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTETYI = %012llo\n", word); + } + } + return SCPE_OK; + } +#endif if (optr->STATUS & DTE_SEC) { if (optr->STATUS & DTE_MON && M[SEC_DTMTI + base] == 0) { sim_debug(DEBUG_DETAIL, &dte_dev, "CTY char %x\n", ch & 0177); @@ -1078,6 +1260,10 @@ t_stat dtei_svc (UNIT *uptr) uptr->CHHOLD = 0; } } else { +#if KL_ITS + if (QITS) + return SCPE_OK; +#endif data1 = (PRI_EMCTY << 8) | ch; if (dte_queue(uptr, PRI_EMLNC, PRI_EMCTY, 1, &data1) != 0) uptr->CHHOLD = 0; @@ -1091,7 +1277,6 @@ dtertc_srv(UNIT * uptr) int32 t; UNIT *optr = &dte_unit[0]; - t = sim_rtcn_calb (rtc_tps, TMR_RTC); sim_activate_after(uptr, 1000000/rtc_tps); if (uptr->STATUS & SEC_CLK) { rtc_tick++; @@ -1111,6 +1296,22 @@ dtertc_srv(UNIT * uptr) rtc_tick, rtc_wait, optr->STATUS); } } +#if KL_ITS + if (QITS) { + uint64 word; + + word = (M[ITS_DTECHK] + 1) & FMASK; + if (word == 0) { + optr->STATUS |= ITS_ON; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS ON\n"); + } else if (word >= (15 * 60)) { + optr->STATUS &= ~ITS_ON; + word = 15 * 60; + sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS OFF\n"); + } + M[ITS_DTECHK] = word; + } +#endif if ((optr->STATUS & DTE_SEC) == 0) { int addr = 0144 + eb_ptr; uint64 word; @@ -1409,9 +1610,7 @@ const char *lpt_description (DEVICE *dptr) t_stat ttyi_svc (UNIT *uptr) { int32 ln; - int n = 0; TMLN *lp; - uint16 data1[32]; int flg; if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ @@ -1419,68 +1618,45 @@ t_stat ttyi_svc (UNIT *uptr) sim_clock_coschedule(uptr, tmxr_poll); /* continue poll */ - /* Check if room in queue for at least one packet */ - if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) { - sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n", - dte_out_res, dte_out_ptr); - return SCPE_OK; + /* If we have room see if any new lines */ + if (((tty_hang.in_ptr + 1) & 0xff) != tty_hang.out_ptr) { + ln = tmxr_poll_conn (&tty_desc); /* look for connect */ + if (ln >= 0) { /* got one? rcv enb*/ + tty_hang.buff[tty_hang.in_ptr] = ln + 1; + tty_hang.in_ptr = (tty_hang.in_ptr + 1) & 0xff; + tty_connect[ln] = 1; + sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line connect %d\n", ln); + } } - ln = tmxr_poll_conn (&tty_desc); /* look for connect */ - if (ln >= 0) { /* got one? rcv enb*/ - tty_ldsc[ln].rcve = 1; - tty_ldsc[ln].xmte = 1; - data1[0] = ((ln + 1) << 8) | (ln + 1); - tty_connect[ln] = 1; - (void)dte_queue(&dte_unit[0], PRI_EMDSC, PRI_EMDLS, 1, data1); -// data1[0] = (ln + 1) << 8; - // /* Send out any data we got */ - // (void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, 1, data1); - sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line connect %d\n", ln); - } tmxr_poll_tx(&tty_desc); tmxr_poll_rx(&tty_desc); - /* Check if room in queue for at least one packet */ - if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) { - sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n", - dte_out_res, dte_out_ptr); - return SCPE_OK; - } - ln = uptr->CNT; - do { - flg = 0; - lp = &tty_ldsc[ln]; - /* Check to see if any pending data for this line */ - if (lp->rcve && tmxr_input_pending_ln(lp) > 0) { - int32 ch = tmxr_getc_ln (lp); - sim_debug(DEBUG_DETAIL, &tty_dev, "TTY recieve %d: %02x\n", ln, ch); - if ((ch & SCPE_BREAK) == 0) { /* break? */ - ch = sim_tt_inpcvt (ch, TT_GET_MODE(tty_unit[0].flags) | TTUF_KSR); - data1[n++] = ((ln + 1) << 8) | ch; - } - flg = 1; - } - if (++ln >= tty_desc.lines) - ln = 0; - } while (flg && n < 32); - uptr->CNT = ln; - - /* Send out any data we got */ - if (n > 0) - (void)dte_queue(&dte_unit[0], PRI_EMLNC, PRI_EMDLS, n, data1); - - /* Look for lines that have been disconnected */ + /* Scan each line for input */ for (ln = 0; ln < tty_desc.lines; ln++) { - if (tty_connect[ln] == 1 && tty_ldsc[ln].conn == 0) { - data1[0] = (ln + 1) << 8; - if (dte_queue(&dte_unit[0], PRI_EMHUD, PRI_EMDLS, 1, data1) != 0) { - /* Check if disconnect */ + lp = &tty_ldsc[ln]; + flg = 1; + /* Spool up as much as we have room for */ + while (flg && ((tty_out[ln].in_ptr + 1) & 0xff) != tty_out[ln].out_ptr) { + int32 ch = tmxr_getc_ln(lp); + if ((ch & TMXR_VALID) != 0) { + ch = sim_tt_inpcvt (ch, TT_GET_MODE(tty_unit[0].flags) | TTUF_KSR); + tty_in[ln].buff[tty_in[ln].in_ptr] = ch & 0377; + tty_in[ln].in_ptr = (tty_in[ln].in_ptr + 1) & 0xff; + sim_debug(DEBUG_DETAIL, &tty_dev, "TTY recieve %d: %02x\n", ln, ch); + } else + flg = 0; + } + /* Look for lines that have been disconnected */ + if (tty_connect[ln] == 1 && lp->conn == 0) { + if (((tty_hang.in_ptr + 1) & 0xff) != tty_hang.out_ptr) { + tty_hang.buff[tty_hang.in_ptr] = ln + 1; + tty_hang.in_ptr = (tty_hang.in_ptr + 1) & 0xff; tty_connect[ln] = 0; sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line disconnect %d\n", ln); } } - } + } return SCPE_OK; } @@ -1503,14 +1679,10 @@ t_stat ttyo_svc (UNIT *uptr) lp = &tty_ldsc[ln]; if (lp->conn == 0) continue; + if (((tty_done.in_ptr + 1) & 0xff) == tty_done.out_ptr) + return SCPE_OK; if (tty_out[ln].out_ptr == tty_out[ln].in_ptr) continue; - /* Check if room in queue for at least one packet */ - if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) { - sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n", - dte_out_res, dte_out_ptr); - return SCPE_OK; - } while (tty_out[ln].out_ptr != tty_out[ln].in_ptr) { int32 ch = tty_out[ln].buff[tty_out[ln].out_ptr]; ch = sim_tt_outcvt(ch, TT_GET_MODE (tty_unit[0].flags) | TTUF_KSR); @@ -1521,20 +1693,20 @@ t_stat ttyo_svc (UNIT *uptr) else if (r == SCPE_LOST) { tty_out[ln].out_ptr = tty_out[ln].in_ptr = 0; continue; - } + } else + continue; } - data1[n++] = (ln + 1) << 8; - /* Send out any data we got */ - if (n > 32) { - (void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, n, data1); - n = 0; - } - } - - /* Send out any data we got */ - if (n > 0) - (void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, n, data1); - + tty_done.buff[tty_done.in_ptr] = ln + 1; + tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff; +#if KL_ITS + /* Tell 10 we have something for it */ + if (QITS) { + dte_unit[0].STATUS |= DTE_10DB; + if (dte_unit[0].STATUS & DTE_PIE) + set_interrupt(DTE_DEVNUM, dte_unit[0].STATUS); + } +#endif + } return SCPE_OK; } diff --git a/PDP10/kx10_cpu.c b/PDP10/kx10_cpu.c index d8666c6..764afd1 100644 --- a/PDP10/kx10_cpu.c +++ b/PDP10/kx10_cpu.c @@ -1206,8 +1206,10 @@ t_stat dev_pag(uint32 dev, uint64 *data) { case CONO: eb_ptr = (*data & 017777) << 9; - for (i = 0; i < 512; i++) + for (i = 0; i < 512; i++) { e_tlb[i] = 0; + u_tlb[i] = 0; + } for (;i < 546; i++) u_tlb[i] = 0; page_enable = (*data & 020000) != 0; @@ -1224,17 +1226,17 @@ t_stat dev_pag(uint32 dev, uint64 *data) { page &= ~7; /* Map the page */ - for(i = 0; i < 8; i++) + for(i = 0; i < 8; i++) { u_tlb[page+i] = 0; - for(i = 0; i < 8; i++) e_tlb[page+i] = 0; + } /* If not user do exec mappping */ if (/*!uf && !t20_page &&*/ (page & 0740) == 0340) { /* Pages 340-377 via UBT */ page += 01000 - 0340; upmp = 1; - for(i = 0; i < 8; i++) - u_tlb[page+i] = 0; + for(i = 0; i < 8; i++) + u_tlb[page+i] = 0; } } else { res = *data; @@ -1257,8 +1259,10 @@ t_stat dev_pag(uint32 dev, uint64 *data) { } if (res & BIT2) { ub_ptr = (res & 017777) << 9; - for (i = 0; i < 512; i++) + for (i = 0; i < 512; i++) { u_tlb[i] = 0; + e_tlb[i] = 0; + } for (;i < 546; i++) u_tlb[i] = 0; } @@ -1290,6 +1294,7 @@ t_stat dev_pag(uint32 dev, uint64 *data) { */ t_stat dev_cca(uint32 dev, uint64 *data) { irq_flags |= 020; + *data = 0; check_apr_irq(); return SCPE_OK; } @@ -1618,8 +1623,8 @@ t_stat dev_pag(uint32 dev, uint64 *data) { e_tlb[i] = u_tlb[i] = 0; for (;i < 546; i++) u_tlb[i] = 0; - user_addr_cmp = (res & 00020000000000LL) != 0; - small_user = (res & 00040000000000LL) != 0; + user_addr_cmp = (res & BIT4) != 0; + small_user = (res & BIT3) != 0; fm_sel = (uint8)(res >> 29) & 060; } pag_reload = 0; @@ -1634,9 +1639,9 @@ t_stat dev_pag(uint32 dev, uint64 *data) { res |= 020000; res |= ((uint64)(ub_ptr)) << 9; if (user_addr_cmp) - res |= 00020000000000LL; + res |= BIT4; if (small_user) - res |= 00040000000000LL; + res |= BIT3; res |= ((uint64)(fm_sel)) << 29; *data = res; sim_debug(DEBUG_DATAIO, &cpu_dev, "DATAI PAG %012llo\n", *data); @@ -1933,9 +1938,19 @@ load_tlb(int uf, int page, int upmp, int wr, int trap, int flag) data &= RMASK; pg = 0; switch(data >> 16) { - case 0: break; /* No access */ + case 0: + fault_data = 033LL << 30 |((uf)?SMASK:0); + page_fault = 1; + return 0; /* No access */ case 1: /* Read Only */ - case 2: pg = RSIGN; break; /* R/W First */ + case 2: /* R/W First */ + if (wr) { + fault_data = 024LL << 30 |((uf)?SMASK:0); + page_fault = 1; + return 0; + } + pg = RSIGN; + break; case 3: pg = RSIGN|0100000; break; /* R/W */ } pg |= (data & 017777) << 1; @@ -2257,8 +2272,16 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch /* If not valid, go refill it */ if (data == 0) { data = load_tlb(uf, page, upmp, wr, 1, flag); - if (data == 0 && page_fault) + if (data == 0 && page_fault) { + fault_data |= ((uint64)addr); +#if KL_ITS + if (QITS && (xct_flag & 020) != 0) { + PC = (PC + 1) & AMASK; + page_fault = 0; + } +#endif return 0; + } } *loc = ((data & 017777) << 9) + (addr & 0777); @@ -2283,23 +2306,33 @@ fprintf(stderr, "Page fault %06o a=%o wr=%o w=%o %06o\n\r", addr, (data & RSIGN) } else { e_tlb[page] = 0; } - if (data & 0400000LL) /* A */ - fault_data |= 00100000000000LL; /* BIT2 */ - if (data & 0200000LL) /* P */ - fault_data |= 00004000000000LL; /* BIT6 */ - if (data & 0100000LL) /* W */ - fault_data |= 00040000000000LL; /* BIT3 */ - if (data & 0040000LL) /* S */ - fault_data |= 00020000000000LL; /* BIT4 */ - if (wr) /* T */ - fault_data |= 00010000000000LL; /* BIT5 */ if (data & 0020000LL) /* C */ - fault_data |= 00002000000000LL; /* BIT7 */ + fault_data |= BIT7; /* BIT7 */ + if (data & 0200000LL) /* P */ + fault_data |= BIT6; /* BIT6 */ #if KL_ITS - if (QITS && (xct_flag & 020) != 0) - PC = (PC + 1) & AMASK; - else + if (QITS) { + if ((xct_flag & 020) != 0) { + PC = (PC + 1) & AMASK; + page_fault = 0; + } else if ((data & RSIGN) == 0) { + fault_data = ((uint64)addr) | 033LL << 30 |((uf)?SMASK:0); + page_fault = 1; + } else {// if (wr & ((data & 0100000) == 0)) { + fault_data = ((uint64)addr) | 024LL << 30 |((uf)?SMASK:0); + page_fault = 1; + } + return 0; + } #endif + if (wr) /* T */ + fault_data |= BIT5; /* BIT5 */ + if (data & 0040000LL) /* S */ + fault_data |= BIT4; /* BIT4 */ + if (data & 0100000LL) /* W */ + fault_data |= BIT3; /* BIT3 */ + if (data & 0400000LL) /* A */ + fault_data |= BIT2; /* BIT2 */ page_fault = 1; return 0; } @@ -4255,7 +4288,7 @@ unasign: brk_flags = 017 & (MB >> 23); AB = (AB + 1) & RMASK; MB = M[AB]; /* WD 2 */ - fault_data = MB; + FM[(6<<4)|0] = MB; AB = (AB + 1) & RMASK; MB = M[AB]; /* WD 3 */ dbr1 = MB; @@ -4279,7 +4312,7 @@ unasign: MB |= ((uint64)brk_flags) << 23; M[AB] = MB; /* WD 1 */ AB = (AB + 1) & RMASK; - MB = fault_data; + MB = FM[(6<<4)|0]; M[AB] = MB; /* WD 2 */ AB = (AB + 1) & RMASK; MB = dbr1; @@ -6718,7 +6751,6 @@ xjrstf: goto xjrstf; /* Fall through */ - case 002: /* JRSTF */ BR = AR >> 23; /* Move into position */ jrstf: @@ -6932,8 +6964,8 @@ jrstf: if (!page_enable || AB < 020) { AR = AB; /* direct map */ if (flag1) /* U */ - AR |= SMASK; /* BIT8 */ - AR |= BIT8|BIT2|00040000000000LL; /* BIT3 */ + AR |= SMASK; /* BIT0 */ + AR |= BIT2|BIT3|BIT4|BIT8; set_reg(AC, AR); break; } @@ -6952,16 +6984,16 @@ jrstf: if (BR & 0400000LL) { /* A */ AR = ((AR & 017777LL) << 9) + (AB & 0777); if (flag1) /* U */ - AR |= SMASK; /* BIT8 */ - AR |= 00100000000000LL; /* BIT2 */ + AR |= SMASK; /* BIT0 */ + AR |= BIT2; /* BIT2 */ if (BR & 0200000LL) /* P */ - AR |= 00004000000000LL; /* BIT6 */ + AR |= BIT6; /* BIT6 */ if (BR & 0100000LL) /* W */ - AR |= 00040000000000LL; /* BIT3 */ + AR |= BIT3; /* BIT3 */ if (BR & 0040000LL) /* S */ - AR |= 00020000000000LL; /* BIT4 */ + AR |= BIT4; /* BIT4 */ if (BR & 0020000LL) /* C */ - AR |= 00002000000000LL; /* BIT7 */ + AR |= BIT7; /* BIT7 */ } else AR = (f & 01740) ? 0 : 0377777LL; AR |= BIT8; @@ -7730,6 +7762,12 @@ test_op: goto muuo; } else { int d = ((IR & 077) << 1) | ((AC & 010) != 0); +#if KL + if (d == 3) { + irq_flags |= 020; + goto last; + } +#endif fetch_opr: switch(AC & 07) { case 0: /* 00 BLKI */ @@ -7864,6 +7902,12 @@ last: } fprintf(stderr, "Page fault %06o %012llo %06o\n\r", PC, fault_data, FLAGS << 5); BYF5 = 0; +#if KL_ITS + if (QITS) { + AB = eb_ptr + 0500; + FM[(6<<4)|0] = fault_data; + } else +#endif AB = ub_ptr + 0500; MB = fault_data; Mem_write_nopage(); diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 6ea79cd..bbaff38 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -174,6 +174,9 @@ extern DEBTAB crd_debug[]; #define BIT1 00200000000000LL #define BIT2 00100000000000LL #define BIT3 00040000000000LL +#define BIT4 00020000000000LL +#define BIT5 00010000000000LL +#define BIT6 00004000000000LL #define BIT7 00002000000000LL #define BIT8 00001000000000LL #define BIT9 00000400000000LL @@ -405,6 +408,7 @@ extern DEVICE pmp_dev; extern DEVICE dk_dev; extern DEVICE pd_dev; extern DEVICE dpy_dev; +extern DEVICE iii_dev; extern DEVICE imx_dev; extern DEVICE imp_dev; extern DEVICE ch10_dev; @@ -514,7 +518,7 @@ int auxcpu_write (int addr, t_uint64); #define NUM_DEVS_DK 0 #define NUM_DEVS_DP 0 #define NUM_DEVS_TTY 1 -#define NUM_LINES_TTY 16 +#define NUM_LINES_TTY 40 #else #define NUM_DEVS_RC 1 #define NUM_DEVS_DT 1 @@ -527,6 +531,7 @@ int auxcpu_write (int addr, t_uint64); #define NUM_DEVS_TU 1 #define NUM_DEVS_PMP WAITS #define NUM_DEVS_DKB WAITS +#define NUM_DEVS_III 0 #define NUM_DEVS_PD ITS | KL_ITS #define NUM_DEVS_IMX ITS #define NUM_DEVS_STK ITS diff --git a/PDP10/kx10_sys.c b/PDP10/kx10_sys.c index 6febd27..a7ae6e1 100644 --- a/PDP10/kx10_sys.c +++ b/PDP10/kx10_sys.c @@ -42,11 +42,8 @@ sim_load binary loader */ -#if KLB -char sim_name[] = "KL-10B"; -#endif -#if KLA -char sim_name[] = "KL-10A"; +#if KL +char sim_name[] = "KL-10"; #endif #if KI char sim_name[] = "KI-10"; @@ -162,6 +159,9 @@ DEVICE *sim_devices[] = { &wcnsls_dev, #endif #endif +#if (NUM_DEVS_III > 0) + &iii_dev, +#endif #if NUM_DEVS_IMP > 0 &imp_dev, #endif @@ -203,7 +203,8 @@ DEVICE *sim_devices[] = { const char *sim_stop_messages[] = { "Unknown error", "HALT instruction", - "Breakpoint" + "Breakpoint", + "Invalid access" }; /* Simulator debug controls */ @@ -556,6 +557,7 @@ t_stat load_sav (FILE *fileref) wc = (int32)(data >> 18); pa = (uint32) (data & RMASK); if (wc == (OP_JRST << 9)) { + printf("Start addr=%06o\n", pa); PC = pa; return SCPE_OK; } @@ -673,12 +675,16 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */ if (get_word(fileref, &pagbuf[k])) return SCPE_FMT; } +// wc = sim_fread (pagbuf, sizeof (uint64), PAG_SIZE, fileref); + // if (wc < PAG_SIZE) + // return SCPE_FMT; fpage++; } ma = mpage << PAG_V_PN; /* mem addr */ for (k = 0; k < PAG_SIZE; k++, ma++) { /* copy buf to mem */ if (ma > MEMSIZE) return SCPE_NXM; +fprintf(stderr, "M %06o %012llo\n", ma, pagbuf[k]); M[ma] = fpage? (pagbuf[k] & FMASK): 0; } /* end copy */ } /* end rpt */