diff --git a/PDP10/ks10_cty.c b/PDP10/ks10_cty.c index 587a05f..9defb59 100644 --- a/PDP10/ks10_cty.c +++ b/PDP10/ks10_cty.c @@ -42,25 +42,25 @@ #define BOOT_DRIVE 037 #define MAG_FMT 040 -#define KA_FAIL 0000000000001 /* Keep Alive failed to change */ -#define FORCE_RELOAD 0000000000002 /* Force reload */ -#define PWR_FAIL1 0000000000004 /* Power failure */ -#define BOOT_SW 0000000000010 /* Boot switch */ -#define KEEP_ALIVE 0000000077400 /* Keep alive */ -#define TRAPS_ENB 0000400000000 /* Traps enabled */ -#define ONE_MS 0001000000000 /* 1ms enabled */ -#define CACHE_ENB 0002000000000 /* Cache enable */ -#define DP_PAR_ENB 0004000000000 /* DP parity error enable */ -#define CRAM_PAR_ENB 0010000000000 /* CRAM parity error enable */ -#define PAR_ENB 0020000000000 /* Parity error detect enable */ -#define KLINK_ENB 0040000000000 /* Klink active */ -#define EX_KEEP_ALV 0100000000000 /* Examine Keep Alive */ -#define RELOAD 0200000000000 /* Reload */ +#define KA_FAIL 0000000000001LL /* Keep Alive failed to change */ +#define FORCE_RELOAD 0000000000002LL /* Force reload */ +#define PWR_FAIL1 0000000000004LL /* Power failure */ +#define BOOT_SW 0000000000010LL /* Boot switch */ +#define KEEP_ALIVE 0000000177400LL /* Keep alive */ +#define TRAPS_ENB 0000040000000LL /* Traps enabled */ +#define ONE_MS 0000100000000LL /* 1ms enabled */ +#define CACHE_ENB 0000200000000LL /* Cache enable */ +#define DP_PAR_ENB 0000400000000LL /* DP parity error enable */ +#define CRAM_PAR_ENB 0001000000000LL /* CRAM parity error enable */ +#define PAR_ENB 0002000000000LL /* Parity error detect enable */ +#define KLINK_ENB 0004000000000LL /* Klink active */ +#define EX_KEEP_ALV 0010000000000LL /* Examine Keep Alive */ +#define RELOAD 0020000000000LL /* Reload */ -#define CTY_CHAR 0000000000400 /* Character pending */ -#define KLINK_CHAR 0000000000400 /* Character pending */ -#define KLINK_ACT 0000000001000 /* KLINK ACTIVE */ -#define KLINK_HANG 0000000001400 /* KLINK HANGUP */ +#define CTY_CHAR 0000000000400LL /* Character pending */ +#define KLINK_CHAR 0000000000400LL /* Character pending */ +#define KLINK_ACT 0000000001000LL /* KLINK ACTIVE */ +#define KLINK_HANG 0000000001400LL /* KLINK HANGUP */ extern int32 tmxr_poll; t_stat ctyi_svc (UNIT *uptr); @@ -71,6 +71,8 @@ t_stat cty_stop_os (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat tty_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat cty_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); const char *cty_description (DEVICE *dptr); +uint64 keep_alive = 0; +int keep_num = 0; static int32 rtc_tps = 1; @@ -85,7 +87,7 @@ MTAB cty_mod[] = { UNIT cty_unit[] = { { UDATA (&ctyo_svc, TT_MODE_7B, 0), 4000}, - { UDATA (&ctyi_svc, TT_MODE_7B|UNIT_DIS, 0), 3000 }, + { UDATA (&ctyi_svc, TT_MODE_7B|UNIT_DIS, 0), 4000 }, { UDATA (&ctyrtc_srv, UNIT_IDLE|UNIT_DIS, 0), 1000 } }; @@ -117,21 +119,25 @@ t_stat ctyi_svc (UNIT *uptr) uint64 buffer; int32 ch; - sim_clock_coschedule (uptr, tmxr_poll * 2); + sim_clock_coschedule (uptr, tmxr_poll * 3); if (Mem_read_word(CTY_IN, &buffer, 0)) return SCPE_OK; + sim_debug(DEBUG_DETAIL, &cty_dev, "CTY Read %012llo\n", buffer); if (buffer & CTY_CHAR) return SCPE_OK; - sim_debug(DEBUG_DETAIL, &cty_dev, "CTY Read %012llo\n", buffer); ch = sim_poll_kbd (); if (ch & SCPE_KFLAG) { ch = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (cty_unit[0].flags)); sim_debug(DEBUG_DETAIL, &cty_dev, "CTY char %o '%c'\n", ch, ((ch > 040 && ch < 0177)? ch: '.')); buffer = (uint64)(ch) | CTY_CHAR; - if (Mem_write_word(CTY_IN, &buffer, 0) == 0) + if (Mem_write_word(CTY_IN, &buffer, 0) == 0) { cty_interrupt(); + } else { + sim_debug(DEBUG_DETAIL, &cty_dev, "CTY write failed %o '%c'\n", ch, + ((ch > 040 && ch < 0177)? ch: '.')); + } } return SCPE_OK; } @@ -156,6 +162,9 @@ t_stat ctyo_svc (UNIT *uptr) buffer = 0; if (Mem_write_word(CTY_OUT, &buffer, 0) == 0) { cty_interrupt(); + } else { + sim_debug(DEBUG_DETAIL, &cty_dev, "CTY write failed %o '%c'\n", ch, + ((ch > 040 && ch < 0177)? ch: '.')); } } @@ -176,9 +185,38 @@ t_stat ctyo_svc (UNIT *uptr) t_stat ctyrtc_srv(UNIT * uptr) { + uint64 buffer; sim_activate_after(uptr, 1000000/rtc_tps); + if (Mem_read_word(STATUS, &buffer, 0)) + return SCPE_OK; + if (buffer & ONE_MS) { + fprintf(stderr, "1MS\n\r"); + } + if (buffer & RELOAD && rh_boot_dev != NULL) { + reset_all(1); /* Reset everybody */ + if (rh_boot_dev->boot(rh_boot_unit, rh_boot_dev) != SCPE_OK) + return SCPE_STOP; + } /* Check if clock requested */ + if (buffer & EX_KEEP_ALV) { + if (keep_alive != (buffer & KEEP_ALIVE)) { + keep_alive = buffer; + keep_num = 0; + } else { + if (++keep_num >= 15) { + keep_num = 0; + buffer &= ~0377LL; + buffer |= 1; + cty_execute(071); + M[STATUS] = buffer; + M[CTY_IN] = 0; + M[CTY_OUT] = 0; + M[KLINK_IN] = 0; + M[KLINK_OUT] = 0; + } + } + } return SCPE_OK; } diff --git a/PDP10/ks10_dz.c b/PDP10/ks10_dz.c index e7ede75..1e1cd63 100644 --- a/PDP10/ks10_dz.c +++ b/PDP10/ks10_dz.c @@ -209,7 +209,7 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) dz_recv[base].in_ptr = dz_recv[base].out_ptr = 0; dz_recv[base].len = 0; /* Set up the current status */ - ln = base << 3; + ln = base << 3; for (i = 0; i < 8; i++) { dz_flags[ln + i] &= ~LINE_EN; } @@ -286,7 +286,7 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) ln = (ln & 070) | ((ln + 1) & 07); lp = &dz_ldsc[ln]; /* Connected and empty xmit_buffer */ - if ((dz_flags[ln] & LINE_EN) != 0 && lp->conn && dz_xmit[ln] == 0) { + if ((dz_flags[ln] & LINE_EN) != 0 && dz_xmit[ln] == 0) { dz_csr[base] &= ~(TLINE); dz_csr[base] |= TRDY | ((ln & 07) << TLINE_V); break; diff --git a/PDP10/ks10_lp.c b/PDP10/ks10_lp.c index 1e51f72..a909558 100644 --- a/PDP10/ks10_lp.c +++ b/PDP10/ks10_lp.c @@ -41,6 +41,65 @@ #define LPST us9 #define LPCNT us10 +/* LPCSRA (765400) */ + +#define CS1_GO 0000001 /* Go command */ +#define CS1_PAR 0000002 /* Enable Parity interrupt */ +#define CS1_V_FNC 2 /* Function shift */ +#define CS1_M_FNC 03 /* Function mask */ +#define FNC_PRINT 0 /* Print */ +#define FNC_TEST 1 /* Test */ +#define FNC_DVU 2 /* Load DAVFU */ +#define FNC_RAM 2 /* Load translation RAM */ +#define CS1_UBA 0000060 /* Upper Unibus address */ +#define CS1_IE 0000100 /* Interrupt enable */ +#define CS1_DONE 0000200 /* Done flag */ +#define CS1_INIT 0000400 /* Init */ +#define CS1_ECLR 0001000 /* Clear errors */ +#define CS1_DHOLD 0002000 /* Delimiter hold */ +#define CS1_ONL 0004000 /* Online */ +#define CS1_DVON 0010000 /* DAVFU online */ +#define CS1_PZERO 0020000 /* Page counter zero */ +#define CS1_ERR 0100000 /* Errors */ + +/* LPCSRB (765402) */ +#define CS2_GOE 0000001 /* Go error */ +#define CS2_DTE 0000002 /* DEM timing error */ +#define CS2_MTE 0000004 /* MSYN error */ +#define CS2_RPE 0000010 /* RAM parity error */ +#define CS2_MPE 0000020 /* Memory parity error */ +#define CS2_LPE 0000040 /* LPT parity error */ +#define CS2_DVOF 0000100 /* DAVFU not ready */ +#define CS2_OFFL 0000200 /* Offline */ +#define CS2_TEST 0003400 /* Test mode */ +#define CS2_OVFU 0004000 /* Optical VFU */ +#define CS2_PBIT 0010000 /* data parity bit */ +#define CS2_NRDY 0020000 /* Printer error */ +#define CS2_LA180 0040000 /* LA180 printer */ +#define CS2_VLD 0100000 /* Valid data */ + +/* LPBA (765404) */ +/* Unibus address */ +#define LPBA u4 /* Save address in u4 */ + +/* LPBC (765406) */ +/* byte count */ +#define LPBC u5 /* Save byte count in u5 */ + +/* LPPAGC (765410) */ +/* Page count */ +#define LINE u6 /* Save line counter in u6 */ + +/* LPRDAT (765412) */ +/* RAM Data register */ + +/* LPCOLC/LPCBUF (765414) */ +/* Column counter / Character buffer */ + +/* LPCSUM/LPPDAT (765416) */ +/* Checksum / Printer data */ + + #define EOFFLG 001 /* Tops 20 wants EOF */ #define HDSFLG 002 /* Tell Tops 20 The current device status */ #define ACKFLG 004 /* Post an acknowwledge message */ @@ -155,6 +214,9 @@ uint16 lp20_dvfu[] = { /* Default VFU */ lp20_reg LPT register list */ +DIB lp20_dib = { 0775400, 037, 0745, 5, 3, &lp20_read, &lp20_write, &lp20_vect, 0, 0 }; + + UNIT lp20_unit = { UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 66), 100 }; @@ -188,12 +250,12 @@ DEVICE lp20_dev = { 1, 10, 31, 1, 8, 8, NULL, NULL, &lp20_reset, NULL, &lp20_attach, &lp20_detach, - NULL, DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &lp20_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug, NULL, NULL, &lp20_help, NULL, NULL, &lp20_description }; int -dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) +lp20_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) { struct pdp_dib *dibp = (DIB *)dptr->ctxt; int base; @@ -206,33 +268,72 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) sim_debug(DEBUG_DETAIL, dptr, "DZ%o write %06o %06o %o\n", base, addr, data, access); + switch (addr & 016) { + case 000: /* LPCSA */ + break; + + case 002: /* LPCSB */ + break; + + case 004: /* LPBA */ + if (access == BYTE) { + if (addr & 1) + data = data | (uptr->LPBA & 0377); + else + data = (uptr->LPBA & 0177400) | data; + } + uptr->LPBA = (uptr->LPBA & 060000) | (data & 0177777); + break; + + case 006: /* LPBC */ + if (access == BYTE) { + if (addr & 1) + data = data | (uptr->LPBC & 0377); + else + data = (uptr->LPBC & 0177400) | data; + } + uptr->LPBC = (data & 0177777); + break; + + case 010: /* LPPAGC */ + if (access == BYTE) { + if (addr & 1) + data = data | (uptr->LINE & 0377); + else + data = (uptr->LINE & 0177400) | data; + } + uptr->LINE = (data & 0177777); + case 012: /* LPRDAT */ + case 014: /* LPCOL/LPCBUF */ + case 016: /* LPCSUM/LPPDAT */ + } switch (addr & 06) { case 0: if (access == BYTE) { - temp = dz_csr[base]; + temp = lp20_csr[base]; if (addr & 1) data = data | (temp & 0377); else data = (temp & 0177400) | data; } if (data & CLR) { - dz_csr[base] = 0; - dz_recv[base].in_ptr = dz_recv[base].out_ptr = 0; - dz_recv[base].len = 0; + lp20_csr[base] = 0; + lp20_recv[base].in_ptr = lp20_recv[base].out_ptr = 0; + lp20_recv[base].len = 0; /* Set up the current status */ ln = base << 3; for (i = 0; i < 8; i++) { - dz_flags[ln + i] &= ~LINE_EN; + lp20_flags[ln + i] &= ~LINE_EN; } return 0; } - dz_csr[base] &= ~(TIE|SAE|RIE|MSE|CLR|MAINT); - dz_csr[base] |= data & (TIE|SAE|RIE|MSE|MAINT); + lp20_csr[base] &= ~(TIE|SAE|RIE|MSE|CLR|MAINT); + lp20_csr[base] |= data & (TIE|SAE|RIE|MSE|MAINT); break; case 2: ln = (data & 07) + (base << 3); - dz_ldsc[ln].rcve = (data & RXON) != 0; + lp20_ldsc[ln].rcve = (data & RXON) != 0; break; case 4: @@ -240,11 +341,11 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) ln = base << 3; /* Set up the current status */ for (i = 0; i < 8; i++) { - if (dz_flags[ln + i] & LINE_EN) + if (lp20_flags[ln + i] & LINE_EN) temp |= LINE_ENB << i; - if (dz_flags[ln + i] & DTR_FLAG) + if (lp20_flags[ln + i] & DTR_FLAG) temp |= DTR << i; - dz_flags[ln + i] = 0; + lp20_flags[ln + i] = 0; } if (access == BYTE) { if (addr & 1) @@ -253,16 +354,16 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) data = (temp & 0177400) | data; } for (i = 0; i < 8; i++) { - lp = &dz_ldsc[ln + i]; + lp = &lp20_ldsc[ln + i]; if ((data & (LINE_ENB << i)) != 0) - dz_flags[ln + i] |= LINE_EN; + lp20_flags[ln + i] |= LINE_EN; if ((data & (DTR << i)) != 0) - dz_flags[ln + i] |= DTR_FLAG; - if (dz_flags[ln + i] & DTR_FLAG) + lp20_flags[ln + i] |= DTR_FLAG; + if (lp20_flags[ln + i] & DTR_FLAG) tmxr_set_get_modem_bits(lp, TMXR_MDM_OUTGOING, 0, NULL); else tmxr_set_get_modem_bits(lp, 0, TMXR_MDM_OUTGOING, NULL); - sim_debug(DEBUG_DETAIL, dptr, "DZ%o sstatus %07o %o %o\n", base, data, i, dz_flags[ln+i]); + sim_debug(DEBUG_DETAIL, dptr, "DZ%o sstatus %07o %o %o\n", base, data, i, lp20_flags[ln+i]); } break; @@ -271,44 +372,44 @@ dz_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) break; } - if ((dz_csr[base] & TRDY) == 0) + if ((lp20_csr[base] & TRDY) == 0) break; - ln = ((dz_csr[base] & TLINE) >> TLINE_V) + (base << 3); - lp = &dz_ldsc[ln]; + ln = ((lp20_csr[base] & TLINE) >> TLINE_V) + (base << 3); + lp = &lp20_ldsc[ln]; - if ((dz_flags[ln] & LINE_EN) != 0 && lp->conn) { + if ((lp20_flags[ln] & LINE_EN) != 0 && lp->conn) { int32 ch = data & 0377; /* Try and send character */ t_stat r = tmxr_putc_ln(lp, ch); /* If character did not send, queue it */ if (r == SCPE_STALL) - dz_xmit[ln] = TRDY | ch; + lp20_xmit[ln] = TRDY | ch; } break; } - dz_csr[base] &= ~TRDY; - if ((dz_csr[base] & MSE) == 0) + lp20_csr[base] &= ~TRDY; + if ((lp20_csr[base] & MSE) == 0) return 0; - ln = ((dz_csr[base] & TLINE) >> TLINE_V) + (base << 3); + ln = ((lp20_csr[base] & TLINE) >> TLINE_V) + (base << 3); /* See if there is another line ready */ for (i = 0; i < 8; i++) { ln = (ln & 070) | ((ln + 1) & 07); - lp = &dz_ldsc[ln]; + lp = &lp20_ldsc[ln]; /* Connected and empty xmit_buffer */ - if ((dz_flags[ln] & LINE_EN) != 0 && lp->conn && dz_xmit[ln] == 0) { - dz_csr[base] &= ~(TLINE); - dz_csr[base] |= TRDY | ((ln & 07) << TLINE_V); + if ((lp20_flags[ln] & LINE_EN) != 0 && lp->conn && lp20_xmit[ln] == 0) { + lp20_csr[base] &= ~(TLINE); + lp20_csr[base] |= TRDY | ((ln & 07) << TLINE_V); break; } } - dz_checkirq(dibp); + lp20_checkirq(dibp); return 0; } int -dz_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) +lp20_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) { struct pdp_dib *dibp = (DIB *)dptr->ctxt; int base; @@ -318,51 +419,27 @@ dz_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) int i; addr &= dibp->uba_mask; - switch (addr & 06) { - case 0: - *data = dz_csr[base]; + switch (addr & 016) { + case 000: /* LPCSA */ + *data = lp20_csr; break; - case 2: + case 002: /* LPCSB */ *data = 0; - if ((dz_csr[base] & MSE) == 0) - return 0; - dz_csr[base] &= ~(SA|RDONE); - if (!empty(&dz_recv[base])) { - *data = dz_recv[base].buff[dz_recv[base].out_ptr]; - inco(&dz_recv[base]); - dz_recv[base].len = 0; - } - if (!empty(&dz_recv[base])) - dz_csr[base] |= RDONE; - dz_checkirq(dibp); break; - case 4: - temp = 0; - ln = base << 3; - /* Set up the current status */ - for (i = 0; i < 8; i++) { - sim_debug(DEBUG_DETAIL, dptr, "DZ%o status %o %o\n", base, i, dz_flags[ln+i]); - if (dz_flags[ln + i] & LINE_EN) - temp |= LINE_ENB << i; - if (dz_flags[ln + i] & DTR_FLAG) - temp |= DTR << i; - } - *data = temp; + case 004: /* LPBA */ + *data = uptr->LPBA & 0177777; break; - case 6: - temp = (uint16)dz_ring[base]; - ln = base << 3; - for (i = 0; i < 8; i++) { - lp = &dz_ldsc[ln + i]; - if (lp->conn) - temp |= CO << i; - } - dz_ring[base] = 0; - *data = temp; + case 006: /* LPBC */ + *data = uptr->LPBC; break; + + case 010: /* LPPAGC */ + case 012: /* LPRDAT */ + case 014: /* LPCOL/LPCBUF */ + case 016: /* LPCSUM/LPPDAT */ } sim_debug(DEBUG_DETAIL, dptr, "DZ%o read %06o %06o %o\n", base, addr, *data, access); diff --git a/PDP10/ks10_uba.c b/PDP10/ks10_uba.c index f675776..63789ed 100644 --- a/PDP10/ks10_uba.c +++ b/PDP10/ks10_uba.c @@ -191,7 +191,7 @@ uba_write(t_addr addr, int ctl, uint64 data, int access) int uba_read_npr(t_addr addr, uint16 ctl, uint64 *data) { - int ubm = uba_device[ctl]; + int ubm = uba_device[ctl]; uint32 map = uba_map[ubm][(077) & (addr >> 11)]; if ((addr & 0400000) != 0) return 0; @@ -207,8 +207,8 @@ uba_read_npr(t_addr addr, uint16 ctl, uint64 *data) int uba_write_npr(t_addr addr, uint16 ctl, uint64 data) { - int ubm = uba_device[ctl]; - t_addr oaddr = addr; + int ubm = uba_device[ctl]; + t_addr oaddr = addr; uint32 map = uba_map[ubm][(077) & (addr >> 11)]; if ((addr & 0400000) != 0) return 0; @@ -225,29 +225,95 @@ uba_write_npr(t_addr addr, uint16 ctl, uint64 data) int uba_read_npr_byte(t_addr addr, uint16 ctl, uint16 *data) { - int ubm = uba_device[ctl]; - return 0; + int ubm = uba_device[ctl]; + uint32 map = uba_map[ubm][(077) & (addr >> 11)]; + uint64 wd; + if ((addr & 0400000) != 0) + return 0; + if ((map & MAP_VALID) == 0) + return 0; + addr = (map & PAGE_MASK) | (addr >> 2) & 0777; + wd = M[addr]; + if (addr & 02) + wd >>= 18; + if (addr & 01) + wd >>= 8; + *data = (uint16)(wd & 0377); + return 1; } int uba_write_npr_byte(t_addr addr, uint16 ctl, uint16 data) { - int ubm = uba_device[ctl]; - return 0; + int ubm = uba_device[ctl]; + uint32 map = uba_map[ubm][(077) & (addr >> 11)]; + uint64 wd; + uint64 msk; + uint64 buf; + if ((addr & 0400000) != 0) + return 0; + if ((map & MAP_VALID) == 0) + return 0; + addr = (map & PAGE_MASK) | (addr >> 2) & 0777; + msk = 0377; + buf = (uint64)(data & msk); + wd = M[addr]; + if (addr & 02) { + buf <<= 18; + msk <<= 18; + } + if (addr & 01) { + buf <<= 8; + msk <<= 8; + } + wd &= ~msk; + wd |= buf; + M[addr] = wd; + return 1; } int uba_read_npr_word(t_addr addr, uint16 ctl, uint16 *data) { - int ubm = uba_device[ctl]; - return 0; + int ubm = uba_device[ctl]; + uint32 map = uba_map[ubm][(077) & (addr >> 11)]; + uint64 wd; + if ((addr & 0400000) != 0) + return 0; + if ((map & MAP_VALID) == 0) + return 0; + addr = (map & PAGE_MASK) | (addr >> 2) & 0777; + wd = M[addr]; + if (addr & 02) + wd >>= 18; + *data = (uint16)(wd & 0177777); + return 1; } int uba_write_npr_word(t_addr addr, uint16 ctl, uint16 data) { - int ubm = uba_device[ctl]; - return 0; + int ubm = uba_device[ctl]; + uint32 map = uba_map[ubm][(077) & (addr >> 11)]; + uint64 wd; + uint64 msk; + uint64 buf; + if ((addr & 0400000) != 0) + return 0; + if ((map & MAP_VALID) == 0) + return 0; + addr = (map & PAGE_MASK) | (addr >> 2) & 0777; + msk = 0177777; + buf = (uint64)(data & msk); + wd = M[addr]; + if (addr & 02) { + buf <<= 18; + msk <<= 18; + } + wd &= ~msk; + wd |= buf; + M[addr] = wd; + return 1; } void @@ -273,9 +339,10 @@ void uba_clr_irq(DIB *idev) { DEVICE *dptr; - int ubm = uba_device[idev->uba_ctl]; - int pi; - int i; + int ubm = uba_device[idev->uba_ctl]; + int pi; + int i; + int j; int high = 0; if (ubm < 0) @@ -288,6 +355,7 @@ uba_clr_irq(DIB *idev) } /* Save in device temp the irq value */ idev->uba_irq_pend = 0; + clr_interrupt(idev->uba_ctl<<2); for(i = 0; (dptr = sim_devices[i]) != NULL; i++) { DIB *dibp = (DIB *) dptr->ctxt; if (dibp == NULL) @@ -295,12 +363,16 @@ uba_clr_irq(DIB *idev) /* If device is pending on this level save */ if (dibp->uba_ctl == idev->uba_ctl && dibp->uba_irq_pend != 0) { + pi = 0; + for (j = 0200; j != 0; j>>=2, pi++) { /* At least one, no need to continue */ - return; + if ((dibp->uba_irq_pend & (0200 >> pi)) != 0) { + set_interrupt(dibp->uba_ctl<<2, pi); + return; + } + } } } - /* Nothing, so clear it */ - clr_interrupt(idev->uba_ctl<<2); } void diff --git a/PDP10/kx10_cpu.c b/PDP10/kx10_cpu.c index 74b79a7..b916a12 100644 --- a/PDP10/kx10_cpu.c +++ b/PDP10/kx10_cpu.c @@ -183,6 +183,7 @@ uint64 int_cur; /* Current interval */ int t20_page; /* Tops 20 paging selected */ int ptr_flg; /* Access to pointer value */ int extend = 0; /* Process extended instruction */ +int fe_xct = 0; /* Execute instruction at address */ #elif KL int pi_vect; /* Last pi location used for IRQ */ int ext_ac; /* Extended instruction AC */ @@ -1762,9 +1763,18 @@ void check_apr_irq() { void cty_interrupt() { irq_flags |= CON_IRQ; + sim_debug(DEBUG_IRQ, &cpu_dev, "cty interrupt %06o\n", irq_enable); check_apr_irq(); } +/* + * Execute instruction at location 071. + */ +void cty_execute(int addr) +{ + fe_xct = addr; +} + int load_tlb(int uf, int page, int wr) { @@ -4387,6 +4397,12 @@ fetch: FLAGS &= ~ONEP; } } +#endif +#if KS + if (fe_xct != 0) { + AB = (t_addr)fe_xct; + fe_xct = 0; + } #endif if (Mem_read(pi_cycle | uuo_cycle, 1, 1, 0)) { #if KA | PDP6 @@ -10676,7 +10692,7 @@ skip_op: /* Bit 5 for TOPS-20 paging */ #if KS_ITS if (QITS) - MB |= 00020000000000LL; + MB |= BIT2; #endif MB |= (uint64)((apr_serial == -1) ? DEF_SERIAL : apr_serial); sim_debug(DEBUG_DATAIO, &cpu_dev, "APRID %012llo\n", MB); @@ -11137,6 +11153,7 @@ skip_op: } break; + /* 70400 */ case 004: /* UMOVE */ xct_flag = 4; AB &= RMASK; @@ -11147,6 +11164,7 @@ skip_op: xct_flag = 0; break; + /* 70500 */ case 005: /* UMOVEM */ MB = BR; AB &= RMASK; @@ -11250,6 +11268,67 @@ its_wr: AR = MB; break; + case 016: /* BLTBU */ + case 017: /* BLTUB */ + AR = get_reg(AC); + BR = AB; + /* Precompute end of transfer address */ + AD = (CM(AR) + BR + 1) & RMASK; + AD = ((AR + (AD << 18)) & LMASK) | ((AR + AD) & RMASK); + set_reg(AC, AOB(AD)); + do { + AIO_CHECK_EVENT; /* queue async events */ + if (sim_interval <= 0) { + if ((reason = sim_process_event()) != SCPE_OK) { + f_pc_inh = 1; + f_load_pc = 0; + f_inst_fetch = 0; + set_reg(AC, AR); + break; + } + /* Allow for interrupt */ + if (pi_pending) { + pi_rq = check_irq_level(); + if (pi_rq) { + f_pc_inh = 1; + f_load_pc = 0; + f_inst_fetch = 0; + set_reg(AC, AR); + break; + } + } + } + AB = (AR >> 18) & RMASK; + BYF5 = 1; + if (Mem_read(0, 0, 0, 0)) { + BYF5 = 0; + f_pc_inh = 1; + set_reg(AC, AR); + goto last; + } +#define BMASK1 0776000000000LL +#define BMASK2 0001774000000LL +#define BMASK3 0000003770000LL +#define BMASK4 0000000007760LL + if (IR & 1) { + MB = ((MB << 10) & BMASK1) | ((MB >> 6) & BMASK2) | + ((MB << 12) & BMASK3) | ((MB >> 4) & BMASK4); + } else { + MB = ((MB & BMASK1) >> 10) | ((MB & BMASK2) << 6) | + ((MB & BMASK3) >> 12) | ((MB & BMASK4) << 4); + } + AB = (AR & RMASK); + BYF5 = 0; + 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); + break; + case 020: /* TIOEB */ #if KS_ITS if (QITS) { diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 01573a6..b5cda04 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -560,6 +560,7 @@ typedef struct pdp_dib DIB; void cty_wakeup(); void cty_interrupt(); +void cty_execute(int addr); t_stat cty_reset (DEVICE *dptr); @@ -601,6 +602,8 @@ void rh_writecw(struct rh_if *rh, int nxm); void rh_finish_op(struct rh_if *rh, int flags); int rh_read(struct rh_if *rh); int rh_write(struct rh_if *rh); +DEVICE *rh_boot_dev; +int rh_boot_unit; #else extern t_stat (*dev_tab[128])(uint32 dev, t_uint64 *data); diff --git a/PDP10/kx10_rh.c b/PDP10/kx10_rh.c index 7e44717..3624e9d 100644 --- a/PDP10/kx10_rh.c +++ b/PDP10/kx10_rh.c @@ -191,6 +191,11 @@ int rh_map[] = { 0, /* 776700 */ #define DS_ATA 0100000 /* attention active */ #if KS + +DEVICE *rh_boot_dev = NULL; +int rh_boot_num = 0; + + int uba_rh_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) { int r = 0; diff --git a/PDP10/kx10_rp.c b/PDP10/kx10_rp.c index f888c5c..5e40d28 100644 --- a/PDP10/kx10_rp.c +++ b/PDP10/kx10_rp.c @@ -1170,6 +1170,8 @@ if (len == 0) word = 01000; M[036] = rhc->dib->uba_addr | (rhc->dib->uba_ctl << 18); M[037] = unit_num; + rh_boot_dev = rptr; + rh_boot_unit = unit_num; #elif KL int sect; /* KL does not support readin, so fake it by reading in sectors 4 to 7 */ diff --git a/PDP10/kx10_tu.c b/PDP10/kx10_tu.c index 5cbb020..82c0517 100644 --- a/PDP10/kx10_tu.c +++ b/PDP10/kx10_tu.c @@ -917,6 +917,8 @@ tu_boot(int32 unit_num, DEVICE * dptr) M[037] = 0; M[040] = regs[TUTC]; PC = 01000; + rh_boot_dev = dptr; + rh_boot_unit = unit_num; #else r = sim_tape_rdrecf(uptr, &tu_buf[0][0], &reclen, TU_NUMFR); if (r != SCPE_OK)