From 87c24d0e9e0d97a82387530beebf7b2aac5d5180 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Mon, 29 May 2017 11:45:38 -0400 Subject: [PATCH] KA10: Major update. BBN Pager added. Added BBN Pager support Clean up instruction options table. Removed some unneeded loads. Removed unneeded FMB term. Cleaned up interrupt handling to properly handle PIR events. Moved dev_pi to be with rest of PI code. Don't check APR interrupts unless pi system enabled. CONO APR reset_all does not clear flags on KA10. Clean up handling of PUBLIC/CONCEALED mode on KI10. Clean up ITS pager support. Added fetch flag to page_lookup for ITS/KI and BBN support. Speed up LDB/DPB instructions to use bulk shift. Carry 0&1 Flags are not cleared until JFCL instruction. Fixed bug in LSHC with shift > 36 bits. Fixed bug in JFCL when run from trap/uuo, bumped PC when it should not.. Shortened loop for BLKI/BLKO instructions. Mask AR & MQ to FMASK before save in one place. --- PDP10/ka10_cpu.c | 2003 +++++++++++++++++++++++++++++---------------- PDP10/ka10_defs.h | 28 + PDP10/ka10_dp.c | 3 +- PDP10/ka10_sys.c | 4 +- 4 files changed, 1311 insertions(+), 727 deletions(-) diff --git a/PDP10/ka10_cpu.c b/PDP10/ka10_cpu.c index d4bb802..597004d 100644 --- a/PDP10/ka10_cpu.c +++ b/PDP10/ka10_cpu.c @@ -110,9 +110,11 @@ #else #define UNIT_MSIZE (017 << UNIT_V_MSIZE) #endif -#define UNIT_V_TWOSEG (UNIT_V_MSIZE + 8) -#define UNIT_TWOSEG (1 << UNIT_V_TWOSEG) -#define UNIT_ITSPAGE (2 << UNIT_V_TWOSEG) +#define UNIT_V_PAGE (UNIT_V_MSIZE + 8) +#define UNIT_TWOSEG (1 << UNIT_V_PAGE) +#define UNIT_ITSPAGE (2 << UNIT_V_PAGE) +#define UNIT_BBNPAGE (4 << UNIT_V_PAGE) +#define UNIT_M_PAGE (7 << UNIT_V_PAGE) uint64 M[MAXMEMSIZE]; /* Memory */ @@ -132,7 +134,7 @@ uint32 IR; /* Instruction register */ uint32 FLAGS; /* Flags */ uint32 AC; /* Operand accumulator */ uint64 SW; /* Switch register */ -int BYF5; /* Second half of LDB/DPB instruction */ +int BYF5; /* Flag for second half of LDB/DPB instruction */ int uuo_cycle; /* Uuo cycle in progress */ int sac_inh; /* Don't store AR in AC */ int SC; /* Shift count */ @@ -172,12 +174,10 @@ uint32 eb_ptr; /* Executive base pointer */ uint8 fm_sel; /* User fast memory block */ int32 apr_serial = -1; /* CPU Serial number */ char inout_fail; /* In out fail flag */ -int public_access; /* Last access from public page */ -int private_page; /* Access to private page */ char small_user; /* Small user flag */ char user_addr_cmp; /* User address compare flag */ #endif -#if KI | ITS +#if KI | ITS | BBN uint32 e_tlb[512]; /* Executive TLB */ uint32 u_tlb[546]; /* User TLB */ char page_enable; /* Enable paging */ @@ -190,6 +190,15 @@ int last_page; /* Last page mapped */ int modify; /* Modify cycle */ char xct_flag; /* XCT flags */ #endif +#if BBN +int exec_map; /* Enable executive mapping */ +int next_write; /* Clear next write mapping */ +int mon_base_reg; /* Monitor base register */ +int ac_base; /* Ac base register */ +int user_base_reg; /* User base register */ +int user_limit; /* User limit register */ +uint64 pur; /* Process use register */ +#endif #if ITS uint32 dbr1; /* User Low Page Table Address */ uint32 dbr2; /* User High Page Table Address */ @@ -200,7 +209,6 @@ uint32 fault_addr; /* Fault address */ uint64 opc; /* Saved PC and Flags */ uint32 mar; /* Memory address compare */ uint16 ofa; /* Output fault address */ -uint32 ac_ptr; /* AC Pointer */ #endif char dev_irq[128]; /* Pending irq by device */ @@ -297,14 +305,18 @@ MTAB cpu_mod[] = { &cpu_set_serial, &cpu_show_serial, NULL, "CPU Serial Number" }, #endif #if !KI - { UNIT_ITSPAGE|UNIT_TWOSEG, 0, "ONESEG", "ONESEG", NULL, NULL, NULL, + { UNIT_M_PAGE, 0, "ONESEG", "ONESEG", NULL, NULL, NULL, "One Relocation Register"}, - { UNIT_ITSPAGE|UNIT_TWOSEG, UNIT_TWOSEG, "TWOSEG", "TWOSEG", NULL, NULL, + { UNIT_M_PAGE, UNIT_TWOSEG, "TWOSEG", "TWOSEG", NULL, NULL, NULL, "Two Relocation Registers"}, #if ITS - { UNIT_ITSPAGE|UNIT_TWOSEG, UNIT_ITSPAGE, "ITS", "ITS", NULL, NULL, NULL, + { UNIT_M_PAGE, UNIT_ITSPAGE, "ITS", "ITS", NULL, NULL, NULL, "Paging hardware for ITS"}, #endif +#if BBN + { UNIT_M_PAGE, UNIT_BBNPAGE, "BBN", "BBN", NULL, NULL, NULL, + "Paging hardware for TENEX"}, +#endif #endif { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", &cpu_set_hist, &cpu_show_hist }, @@ -332,17 +344,16 @@ DEVICE cpu_dev = { #define FCE 000001 /* Fetch memory into AR */ #define FCEPSE 000002 /* Fetch and store memory into AR */ #define SCE 000004 /* Save AR into memory */ -#define FAC 000010 /* Fetch AC into AR */ +#define FAC 000010 /* Copy AR to BR, then Fetch AC into AR */ #define FAC2 000020 /* Fetch AC+1 into MQ */ #define SAC 000040 /* Save AC into AR */ #define SACZ 000100 /* Save AC into AR if AC not 0 */ #define SAC2 000200 /* Save MQ into AC+1 */ -#define MBR 000400 /* Load Mem to BR, AC to AR */ -#define SWAR 001000 /* Swap AR */ -#define FBR 002000 /* Load AC into BR */ -#define FMB 004000 /* Load MB into BR */ +#define SWAR 000400 /* Swap AR */ +#define FBR 001000 /* Load AC into BR */ int opflags[] = { + /* UUO Opcodes */ /* UUO00 */ /* LUUO01 */ /* LUUO02 */ /* LUUO03 */ 0, 0, 0, 0, /* LUUO04 */ /* LUUO05 */ /* LUUO06 */ /* LUUO07 */ @@ -375,6 +386,8 @@ int opflags[] = { 0, 0, 0, 0, /* MUUO74 */ /* MUUO75 */ /* MUUO76 */ /* MUUO77 */ 0, 0, 0, 0, + + /* Double precsision math */ /* UJEN */ /* UUO101 */ /* GFAD */ /* GFSB */ 0, 0, 0, 0, /* JSYS */ /* ADJSP */ /* GFMP */ /*GFDV */ @@ -391,6 +404,8 @@ int opflags[] = { FCE|FBR, FCE|FAC|SAC, FAC|SAC, 0, /* ILDB */ /* LDB */ /* IDPB */ /* DPB */ 0, 0, 0, 0, + + /* Floating point */ /* FAD */ /* FADL */ /* FADM */ /* FADB */ SAC|FBR|FCE, SAC|SAC2|FBR|FCE, FCEPSE|FBR, SAC|FBR|FCEPSE, /* FADR */ /* FADRI */ /* FADRM */ /* FADRB */ @@ -408,6 +423,7 @@ int opflags[] = { /* FDVR */ /* FDVRI */ /* FDVRM */ /* FDVRB */ SAC|FBR|FCE, SAC|FBR|SWAR, FCEPSE|FBR, SAC|FBR|FCEPSE, + /* Full word operators */ /* MOVE */ /* MOVEI */ /* MOVEM */ /* MOVES */ SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* MOVS */ /* MOVSI */ /* MOVSM */ /* MOVSS */ @@ -426,11 +442,13 @@ int opflags[] = { SAC2|SAC|FCE|FAC|FAC2, SAC2|SAC|FAC|FAC2, FCEPSE|FAC|FAC2, SAC2|SAC|FCEPSE|FAC\ |FAC2, + /* Shift operators */ /* ASH */ /* ROT */ /* LSH */ /* JFFO */ FAC|SAC, FAC|SAC, FAC|SAC, FAC, /* ASHC */ /* ROTC */ /* LSHC */ /* UUO247 */ FAC|SAC|SAC2|FAC2, FAC|SAC|SAC2|FAC2, FAC|SAC|SAC2|FAC2, 0, + /* Branch operators */ /* EXCH */ /* BLT */ /* AOBJP */ /* AOBJN */ FAC|FCEPSE, FAC, FAC|SAC, FAC|SAC, /* JRST */ /* JFCL */ /* XCT */ /* MAP */ @@ -444,6 +462,7 @@ int opflags[] = { /* SUB */ /* SUBI */ /* SUBM */ /* SUBB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, + /* Compare operators */ /* CAI */ /* CAIL */ /* CAIE */ /* CAILE */ FBR, FBR, FBR, FBR, /* CAIA */ /* CAIGE */ /* CAIN */ /* CAIG */ @@ -452,6 +471,8 @@ int opflags[] = { FBR|FCE, FBR|FCE, FBR|FCE, FBR|FCE, /* CAMA */ /* CAMGE */ /* CAMN */ /* CAMG */ FBR|FCE, FBR|FCE, FBR|FCE, FBR|FCE, + + /* Jump and skip operators */ /* JUMP */ /* JUMPL */ /* JUMPE */ /* JUMPLE */ FAC, FAC, FAC, FAC, /* JUMPA */ /* JUMPGE */ /* JUMPN */ /* JUMPG */ @@ -477,14 +498,15 @@ int opflags[] = { /* SOSA */ /* SOSGE */ /* SOSN */ /* SOSG */ SACZ|FCEPSE, SACZ|FCEPSE, SACZ|FCEPSE, SACZ|FCEPSE, + /* Boolean operators */ /* SETZ */ /* SETZI */ /* SETZM */ /* SETZB */ - FBR|SAC, FBR|SAC, FBR|SCE, FBR|SAC|SCE, + SAC, SAC, SCE, SAC|SCE, /* AND */ /* ANDI */ /* ANDM */ /* ANDB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* ANDCA */ /* ANDCAI */ /* ANDCAM */ /* ANDCAB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* SETM */ /* SETMI */ /* SETMM */ /* SETMB */ - FBR|SAC|FCE, FBR|SAC, FBR, FBR|SAC|FCE, + SAC|FCE, SAC, 0, SAC|FCE, /* ANDCM */ /* ANDCMI */ /* ANDCMM */ /* ANDCMB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* SETA */ /* SETAI */ /* SETAM */ /* SETAB */ @@ -502,55 +524,49 @@ int opflags[] = { /* ORCA */ /* ORCAI */ /* ORCAM */ /* ORCAB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* SETCM */ /* SETCMI */ /* SETCMM */ /* SETCMB */ - FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, + SAC|FCE, SAC, FCEPSE, SAC|FCEPSE, /* ORCM */ /* ORCMI */ /* ORCMM */ /* ORCMB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* ORCB */ /* ORCBI */ /* ORCBM */ /* ORCBB */ FBR|SAC|FCE, FBR|SAC, FBR|FCEPSE, FBR|SAC|FCEPSE, /* SETO */ /* SETOI */ /* SETOM */ /* SETOB */ - FBR|SAC, FBR|SAC, FBR|SCE, FBR|SAC|SCE, + SAC, SAC, SCE, SAC|SCE, + /* Half word operators */ /* HLL */ /* HLLI */ /* HLLM */ /* HLLS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + FBR|SAC|FCE, FBR|SAC, FAC|FCEPSE, SACZ|FCEPSE, /* HRL */ /* HRLI */ /* HRLM */ /* HRLS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, FAC|SWAR|FCEPSE,SACZ|FCEPSE, /* HLLZ */ /* HLLZI */ /* HLLZM */ /* HLLZS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HRLZ */ /* HRLZI */ /* HRLZM */ /* HRLZS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, /* HLLO */ /* HLLOI */ /* HLLOM */ /* HLLOS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HRLO */ /* HRLOI */ /* HRLOM */ /* HRLOS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, /* HLLE */ /* HLLEI */ /* HLLEM */ /* HLLES */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HRLE */ /* HRLEI */ /* HRLEM */ /* HRLES */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, /* HRR */ /* HRRI */ /* HRRM */ /* HRRS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + FBR|SAC|FCE, FBR|SAC, FAC|FCEPSE, SACZ|FCEPSE, /* HLR */ /* HLRI */ /* HLRM */ /* HLRS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, FAC|SWAR|FCEPSE,SACZ|FCEPSE, /* HRRZ */ /* HRRZI */ /* HRRZM */ /* HRRZS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HLRZ */ /* HLRZI */ /* HLRZM */ /* HLRZS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, /* HRRO */ /* HRROI */ /* HRROM */ /* HRROS */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HLRO */ /* HLROI */ /* HLROM */ /* HLROS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, /* HRRE */ /* HRREI */ /* HRREM */ /* HRRES */ - FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, + SAC|FCE, SAC, FAC|SCE, SACZ|FCEPSE, /* HLRE */ /* HLREI */ /* HLREM */ /* HLRES */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, - SWAR|FMB|SACZ|FCEPSE, + SWAR|SAC|FCE, SWAR|SAC, FAC|SWAR|SCE, SWAR|SACZ|FCEPSE, + /* Test operators */ /* TRN */ /* TLN */ /* TRNE */ /* TLNE */ FBR, FBR|SWAR, FBR, FBR|SWAR, /* TRNA */ /* TLNA */ /* TRNN */ /* TLNN */ @@ -560,29 +576,30 @@ int opflags[] = { /* TDNA */ /* TSNA */ /* TDNN */ /* TSNN */ FBR|FCE, FBR|SWAR|FCE, FBR|FCE, FBR|SWAR|FCE, /* TRZ */ /* TLZ */ /* TRZE */ /* TLZE */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TRZA */ /* TLZA */ /* TRZN */ /* TLZN */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TDZ */ /* TSZ */ /* TDZE */ /* TSZE */ - FBR|SAC|FCE, FBR|SAC|SWAR|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, /* TDZA */ /* TSZA */ /* TDZN */ /* TSZN */ - FBR|SAC|FCE, FBR|SAC|SWAR|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, /* TRC */ /* TLC */ /* TRCE */ /* TLCE */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TRCA */ /* TLCA */ /* TRCN */ /* TLCN */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TDC */ /* TSC */ /* TDCE */ /* TSCE */ - FBR|SAC|FCE, FBR|SAC|SWAR|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, /* TDCA */ /* TSCA */ /* TDCN */ /* TSCN */ - FBR|SAC|FCE, FBR|SAC|SWAR|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, /* TRO */ /* TLO */ /* TROE */ /* TLOE */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TROA */ /* TLOA */ /* TRON */ /* TLON */ - FBR|SAC, FBR|SAC|SWAR, FBR|SAC, FBR|SAC|SWAR, + FBR|SAC, FBR|SWAR|SAC, FBR|SAC, FBR|SWAR|SAC, /* TDO */ /* TSO */ /* TDOE */ /* TSOE */ - FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, /* TDOA */ /* TSOA */ /* TDON */ /* TSON */ - FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SAC|SWAR|FCE, + FBR|SAC|FCE, FBR|SWAR|SAC|FCE, FBR|SAC|FCE, FBR|SWAR|SAC|FCE, + /* IOT Instructions */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -641,42 +658,37 @@ void clr_interrupt(int dev) { */ int check_irq_level() { int i, lvl; - int pi_ok, pi_t; + + 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 (PIR & lvl) + return 1; + pi_enc++; + } + } + return 0; + } /* Scan all devices */ for(i = lvl = 0; i < 128; i++) lvl |= dev_irq[i]; if (lvl == 0) pi_pending = 0; - PIR |= (lvl & PIE); + pi_req = (lvl & PIE) | PIR; /* Handle held interrupt requests */ - pi_t = (~PIR & ~PIH) >> 1; - pi_ok = 0100 & (PIR & ~PIH); - /* Still have a valid interrupt? */ - if (!pi_ok) { - /* None at level 1, check for lower level */ - lvl = 0040; - for(i = 2; i <= 7; i++) { - if (lvl & pi_t) { - pi_ok |= lvl; - lvl >>= 1; - } else { - break; - } + i = 1; + for(lvl = 0100; lvl != 0; lvl >>= 1, i++) { + if (lvl & PIH) + break; + if (pi_req & lvl) { + pi_enc = i; + return 1; } } - /* We have 1 bit for each non held interrupt. */ - pi_req = PIR & ~PIH & pi_ok; - if (pi_req) { - int pi_r = pi_req; - for(lvl = i = 1; i<=7; i++, lvl++) { - if (pi_r & 0100) - break; - pi_r <<= 1; - } - pi_enc = lvl; - return 1; - } return 0; } @@ -688,16 +700,13 @@ void restore_pi_hold() { if (!pi_enable) return; - /* Compute mask for pi_ok */ - lvl = 0100; /* Clear HOLD flag for highest interrupt */ - for(i = 1; i <= 7; i++) { + for(lvl = 0100; lvl != 0; lvl >>= 1) { if (lvl & PIH) { PIR &= ~lvl; PIH &= ~lvl; break; } - lvl >>= 1; } pi_pending = 1; } @@ -706,10 +715,89 @@ void restore_pi_hold() { * Hold interrupts at the current level. */ void set_pi_hold() { - PIH |= 0200 >> pi_enc; PIR &= ~(0200 >> pi_enc); + if (pi_enable) + PIH |= (0200 >> pi_enc); } +/* + * PI device for KA and KI + */ +t_stat dev_pi(uint32 dev, uint64 *data) { + uint64 res = 0; + switch(dev & 3) { + case CONO: + /* Set PI flags */ + res = *data; + if (res & 010000) { + PIR = PIH = PIE = 0; + pi_enable = 0; + parity_irq = 0; + } + if (res & 0200) { + pi_enable = 1; + check_apr_irq(); + } + if (res & 0400) + pi_enable = 0; + if (res & 01000) + PIE &= ~(*data & 0177); + if (res & 02000) + PIE |= (*data & 0177); + if (res & 04000) { + PIR |= (*data & 0177); + pi_pending = 1; + } +#if KI + if (res & 020000) { + PIR &= ~(*data & 0177); + } +#endif + if (res & 040000) + parity_irq = 1; + if (res & 0100000) + parity_irq = 0; + sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data); + break; + + case CONI: + res = PIE; + res |= (pi_enable << 7); + res |= (PIH << 8); +#if KI + res |= ((uint64)(PIR) << 18); +#endif + res |= (parity_irq << 15); + *data = res; + sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data); + break; + + case DATAO: + /* Set lights */ + case DATAI: + break; + } + return SCPE_OK; +} + +/* + * Non existent device +*/ +t_stat null_dev(uint32 dev, uint64 *data) { + switch(dev & 3) { + case CONI: + case DATAI: + *data = 0; + break; + + case CONO: + case DATAO: + break; + } + return SCPE_OK; +} + + #if KI static int timer_irq, timer_flg; @@ -782,14 +870,14 @@ t_stat dev_pag(uint32 dev, uint64 *data) { * Check if the last operation caused a APR IRQ to be generated. */ void check_apr_irq() { - if (apr_irq) { + if (pi_enable && apr_irq) { int flg = 0; clr_interrupt(0); flg |= inout_fail | nxm_flag; if (flg) set_interrupt(0, apr_irq); } - if (clk_en && clk_flg) + if (pi_enable && clk_en && clk_flg) set_interrupt(4, clk_irq); } @@ -854,11 +942,77 @@ t_stat dev_apr(uint32 dev, uint64 *data) { #endif #if KA + +#if BBN +t_stat dev_pag(uint32 dev, uint64 *data) { + uint64 res = 0; + int i; + int page_limit[] = { + 01000, 0040, 0100, 0140, 0200, 0240, 0300, 0340}; + switch(dev & 03) { + case CONI: + break; + + case CONO: + switch (*data & 07) { + case 0: /* Clear page tables, reload from 71 & 72 */ + for (i = 0; i < 512; i++) + e_tlb[i] = u_tlb[i] = 0; + res = M[071]; + mon_base_reg = (res & 0377); + ac_base = (res >> 13) & 037; + user_base_reg = (res >> 18) & 0377; + user_limit = page_limit[(res >> 19) & 07]; + pur = M[072]; + break; + + case 1: /* Clear exec mapping */ + for (i = 0; i < 512; i++) + e_tlb[i] = 0; + break; + + case 2: /* Clear mapping for next write */ + next_write = 1; + break; + + case 3: /* Clear user mapping */ + for (i = 0; i < 512; i++) + u_tlb[i] = 0; + break; + + case 4: /* Turn off pager */ + case 5: /* same as 4 */ + page_enable = 0; + break; + + case 6: /* Pager on, no resident mapping */ + page_enable = 1; + exec_map = 0; + break; + + case 7: /* Pager on, resident mapping */ + page_enable = 1; + exec_map = 1; + break; + } + sim_debug(DEBUG_CONO, &cpu_dev, "CONO PAG %012llo\n", *data); + break; + + case DATAO: + break; + + case DATAI: + break; + } + return SCPE_OK; +} +#endif + /* * Check if the last operation caused a APR IRQ to be generated. */ void check_apr_irq() { - if (apr_irq) { + if (pi_enable && apr_irq) { int flg = 0; clr_interrupt(0); flg |= clk_en & clk_flg; @@ -870,6 +1024,7 @@ void check_apr_irq() { } } + /* * APR Device for KA10. */ @@ -915,10 +1070,8 @@ t_stat dev_apr(uint32 dev, uint64 *data) { nxm_flag = 0; if (res & 020000) mem_prot = 0; - if (res & 0200000) { + if (res & 0200000) reset_all(1); - clk_flg = ov_irq = fov_irq = nxm_flag = mem_prot = push_ovf = 0; - } if (res & 0400000) push_ovf = 0; check_apr_irq(); @@ -946,81 +1099,18 @@ t_stat dev_apr(uint32 dev, uint64 *data) { #endif -/* - * PI device for KA and KI - */ -t_stat dev_pi(uint32 dev, uint64 *data) { - uint64 res = 0; - switch(dev & 3) { - case CONO: - /* Set PI flags */ - res = *data; - if (res & 010000) { - PIR = PIH = PIE = 0; - pi_enable = 0; - parity_irq = 0; - } - if (res & 0200) - pi_enable = 1; - if (res & 0400) - pi_enable = 0; - if (res & 01000) - PIE &= ~(*data & 0177); - if (res & 02000) - PIE |= (*data & 0177); - if (res & 04000) { - PIR |= (*data & 0177); - pi_pending = 1; - } - if (res & 040000) - parity_irq = 1; - if (res & 0100000) - parity_irq = 0; - sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data); - break; - - case CONI: - res = PIE; - res |= (pi_enable << 7); - res |= (PIH << 8); -#if KI - res |= ((uint64)(PIR) << 18); -#endif - res |= (parity_irq << 15); - *data = res; - sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data); - break; - - case DATAO: - /* Set lights */ - case DATAI: - break; - } - return SCPE_OK; -} - -/* - * Non existent device -*/ -t_stat null_dev(uint32 dev, uint64 *data) { - switch(dev & 3) { - case CONI: - case DATAI: - *data = 0; - break; - - case CONO: - case DATAO: - break; - } - return SCPE_OK; -} - #if KI /* * Handle page lookup on KI10 + * + * addr is address to look up. + * flag is set for pi cycle and user overide. + * loc is final address. + * wr indicates whether cycle is read or write. + * cur_context is set when access should ignore xct_flag + * fetch is set for instruction fetches. */ -int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { +int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch) { uint64 data; int base = 0; int page = (RMASK & addr) >> 9; @@ -1070,12 +1160,17 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { /* Pages 000-037 direct map */ } else { /* Check if supervisory mode */ - if (!flag && ((FLAGS & PUBLIC) != 0)) { - /* Handle public violation */ - fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; - private_page = 1; - } *loc = addr; + /* If PUBLIC and private page, make sure we are fetching a Portal */ + if (!flag && ((FLAGS & PUBLIC) != 0) && + (!fetch || (M[addr] & 00777040000000LL) != 0254040000000LL)) { + /* Handle public violation */ + 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); + return !wr; + } return 1; } } @@ -1101,10 +1196,15 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { } *loc = ((data & 017777) << 9) + (addr & 0777); /* Access check logic */ - if (!flag && ((FLAGS & PUBLIC) != 0) && ((data & 0200000) == 0)) { + + /* If PUBLIC and private page, make sure we are fetching a Portal */ + if (!flag && ((FLAGS & PUBLIC) != 0) && ((data & 0200000) == 0) && + (!fetch || (M[*loc] & 00777040000000LL) != 0254040000000LL)) { /* Handle public violation */ fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; - private_page = 1; +fprintf(stderr, "pub PC=%06o, %012llo\n\r", PC, fault_data); + page_fault = 1; + return fetch; } if (cur_context && ((data & 0200000) != 0)) FLAGS |= PUBLIC; @@ -1115,12 +1215,10 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { fault_data |= (data & 0040000) ? 002LL : 0LL; /* S */ fault_data |= wr; page_fault = 1; -#if 0 fprintf(stderr, "xlat %06o %03o ", addr, page >> 1); - fprintf(stderr, " %06o %03o %012llo %o", base, page, data, uf); + fprintf(stderr, " %06o %04o %012llo %o", base, page, data, uf); fprintf(stderr, " -> %06llo wr=%o PC=%06o ", fault_data, wr, PC); fprintf(stderr, " fault\n\r"); -#endif return 0; } return 1; @@ -1129,14 +1227,14 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { /* * Register access on KI 10 */ -uint64 get_reg(int reg, int cur_context) { +uint64 get_reg(int reg) { if (FLAGS & USER) return FM[fm_sel|(reg & 017)]; else return FM[reg & 017]; } -void set_reg(int reg, uint64 value, int cur_context) { +void set_reg(int reg, uint64 value) { if (FLAGS & USER) FM[fm_sel|(reg & 017)] = value; else @@ -1155,7 +1253,6 @@ int Mem_read_nopage() { sim_interval--; if (AB >= (int)MEMSIZE) { nxm_flag = 1; - set_interrupt(0, apr_irq); return 1; } MB = M[AB]; @@ -1176,7 +1273,6 @@ int Mem_write_nopage() { sim_interval--; if (AB >= (int)MEMSIZE) { nxm_flag = 1; - set_interrupt(0, apr_irq); return 1; } M[AB] = MB; @@ -1185,21 +1281,53 @@ int Mem_write_nopage() { } -#else +#endif + +#if KA +#if ITS +int its_load_tlb(uint32 reg, int page, uint32 *tlb) { + uint64 data; + int len = (reg >> 19) & 077; + int entry = (reg & 01777777) + ((page & 0377) >> 1); + if ((page >> 1) > len) { + fault_data |= 0200; + return 1; + } + if (entry > (int)MEMSIZE) { + nxm_flag = 1; + fault_data |= 0400; + return 1; + } + data = M[entry]; + if (page & 1) { + data &= ~017000LL; + data |= ((uint64)(age & 017)) << 9; + } else { + data &= ~(017000LL << 18); + data |= ((uint64)(age & 017)) << (9+18); + } + M[entry] = data; + if ((page & 1) == 0) + data >>= 18; + data &= RMASK; + *tlb = data; + pag_reload = ((pag_reload + 1) & 017); + return 0; +} +#endif /* * Translation logic for KA10 */ -int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { +int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch) { #if ITS if (cpu_unit.flags & UNIT_ITSPAGE) { uint64 data; int base = 0; - int page = (RMASK & addr) >> 9; + int page = (RMASK & addr) >> 10; + int entry; int uf = (FLAGS & USER) != 0; - if (page_fault) - return 0; /* If paging is not enabled, address is direct */ if (!page_enable) { @@ -1224,79 +1352,82 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { } } - /* If user, check if small user enabled */ + /* AC & 1 = ??? */ + /* AC & 2 = Read User */ + /* AC & 4 = Write User */ + /* AC & 8 = Inhibit mem protect, skip */ + + /* Add in MAR checking */ + if (addr == (mar & RMASK)) { + switch((mar >> 18) & 03) { + case 0: break; + case 1: if (fetch) { + mem_prot = 1; + fault_data |= 2; + } + break; + case 2: if (!wr) + break; + /* Fall through */ + case 3: mem_prot = 1; + fault_data |= 2; + break; + } + } + + /* Map the page */ if (!uf) { /* Handle system mapping */ - /* Pages 400-777 via EBR */ - if (page & 0400) { - base = 1; - } else { - /* Pages 000-037 direct map */ + if ((page & 0400) == 0 || (fault_data & 04) == 0) { + /* Direct map 0-377 or all if bit 2 off */ *loc = addr; return 1; } - } - /* Map the page */ - if (base) { - data = e_tlb[page]; - if (data == 0) { - int len = (dbr3 >> 19) & 077; - if ((page >> 1) > len) - goto fault; - data = M[(dbr3 & 01777777) + (page >> 1)]; - e_tlb[page & 0776] = RMASK & (data >> 18); - e_tlb[page | 1] = RMASK & data; - if (page & 1) { - data &= ~017000LL; - data |= ((uint64)(age & 017)) << 9; - } else { - data &= ~(017000LL << 18); - data |= ((uint64)(age & 017)) << (9+18); - } - M[(dbr3 & 01777777) + (page >> 1)] = data; - data = e_tlb[page]; - pag_reload = ((pag_reload + 1) & 037) | 040; - } + if (its_load_tlb(dbr3, page, &e_tlb[page])) + goto fault; } else { data = u_tlb[page]; if (data == 0) { if (page & 0400) { - int len = (dbr2 >> 19) & 077; - if (((page & 0377) >> 1) > len) + if (its_load_tlb(dbr2, page, &u_tlb[page])) goto fault; - data = M[(dbr2 & 01777777) + ((page & 0377) >> 1)]; } else { - int len = (dbr1 >> 19) & 077; - if ((page >> 1) > len) + if (its_load_tlb(dbr1, page, &u_tlb[page])) goto fault; - data = M[(dbr1 & 01777777) + (page >> 1)]; } - if (page & 1) { - data &= ~017000LL; - data |= ((uint64)(age & 017)) << 9; - } else { - data &= ~(017000LL << 18); - data |= ((uint64)(age & 017)) << (9+18); - } - if (page & 0400) { - M[(dbr2 & 01777777) + ((page & 0377) >> 1)] = data; - } else { - M[(dbr1 & 01777777) + (page >> 1)] = data; - } - u_tlb[page & 01776] = RMASK & (data >> 18); - u_tlb[page | 1] = RMASK & data; - data = u_tlb[page]; - pag_reload = ((pag_reload + 1) & 037) | 040; } } - *loc = ((data & 0777) << 9) + (addr & 0777); - /* Access check logic */ + *loc = ((data & 0777) << 10) + (addr & 01777); + if (fetch && (FLAGS & PURE) && (data & 0600000) != 0100000) { + fault_data |= 020; + fault_addr = (page << 10) | ((base == 0)? 01000000 : 0) | + (data & 01777) ; + if (xct_flag & 010) { + PC = (PC + 1) & RMASK; + } else { + mem_prot = 1; + fault_data |= 01000; + } + return 0; + } + /* Access check logic */ if ((data & 0600000) == 0 || (wr & ((data & 0600000) != 0600000))) { + switch ((data & 0600000) >> 15) { + case 0: fault_data |= 0010; break; + case 1: fault_data |= 0100; break; + case 2: fault_data |= 0040; break; + case 3: break; + } fault: - fault_addr = (page << 9) | ((base == 0)? 01000000 : 0) | - (data & 0777) ; - page_fault = 1; + /* Update fault data */ + fault_addr = (page) | ((uf)? 0400 : 0) | ((data & 0777) << 9); + if (xct_flag & 010) { + PC = (PC + 1) & RMASK; + } else { + mem_prot = 1; + fault_data |= 01000; + } fprintf(stderr, "xlat %06o %03o ", addr, page >> 1); fprintf(stderr, " %06o %03o %012llo %o", base, page, data, uf); fprintf(stderr, " -> %06o wr=%o PC=%06o ", fault_addr, wr, PC); @@ -1306,55 +1437,268 @@ fault: return 1; } #endif +#if BBN + /* Group 0, 01 = 00 + bit 2 = Age 00x 0100000 + bit 3 = Age 02x 0040000 + bit 4 = Age 04x 0020000 + bit 5 = Age 06x 0010000 + bit 6 = Monitor after loading AR trap 0004000 */ + /* Group 1, 01 = 01 0200000 + bit 3 = Shared page not in core 0040000 + bit 4 = page table not in core (p.t.2) 0020000 + bit 5 = 2nd indirect, private not in core (p.t.3) 0010000 + bit 6 = Indirect shared not in core (p.t.2 || p.t.3) 0004000 + bit 7 = Indirect page table not in core (p.t.3) 0002000 + bit 8 = Excessive indirect pointers (>2) 0001000 */ + /* Group 2, 01 = 10 0400000 + bit 2 = Private not in core + bit 3 = Write copy trap (bit 9 in p.t.) + bit 4 = user trap (bit 8 in p.t.) + bit 5 = access trap (p.t. bit 12 = 0 or bits 10-11=3) + bit 6 = illegal read or execute + bit 7 = illegal write + bit 8 = address limit register violation or p.t. bits + 0,1 = 3 (illegal format) */ + /* Group 3, 01 = 11 (in 2nd or 3rd p.t.) 060000 + bit 2 = private not in core + bit 3 = write copy trap (bit 9 in p.t.) + bit 4 = user trap (bit 8 in p.t.) + bit 5 = access trap (p.t. bit 12 = 0 or bits 10-11=3) + bit 6 = illegal read or execute + bit 7 = illegal write + bit 8 = address limit register violation or p.t. bits + 0,1 = 3 (illegal format */ + if (cpu_unit.flags & UNIT_BBNPAGE) { + uint64 data; + uint32 tlb_data; + uint64 traps; + int base = 0; + int trap = 0; + int lvl = 0; + int page = (RMASK & addr) >> 9; + int uf = (FLAGS & USER) != 0; + + if (page_fault) + return 0; + + /* If paging is not enabled, address is direct */ + if (!page_enable) { + *loc = addr; + return 1; + } + + /* If this is modify instruction use write access */ + wr |= modify; + + /* Umove instructions handled here */ + if ((IR & 0774) == 0100 && (FLAGS & EXJSYS) == 0) + uf = 1; + /* Figure out if this is a user space access */ + if (flag) + uf = 0; + else if ((FLAGS & EXJSYS) == 0 && xct_flag != 0) { + if (xct_flag & 010 && cur_context) + uf = 1; + if (xct_flag & 004 && wr == 0) + uf = 1; + if (xct_flag & 002 && BYF5) + uf = 1; + if (xct_flag & 001 && wr == 1) + uf = 1; + } + + /* If not really user mode and register access */ + if (uf && (FLAGS & USER) == 0 && addr < 020) { + addr |= 0775000 | (ac_base << 4); + uf = 0; + } + + if (uf) { + if (page > user_limit) { + /* over limit violation */ + fault_data = 0401000; + goto fault_bbn; + } + base = user_base_reg; + tlb_data = u_tlb[page]; + } else { + /* 000 - 077 resident map */ + /* 100 - 177 per processor map */ + /* 200 - 577 monitor map */ + /* 600 - 777 per process map */ + if ((page & 0700) == 0 && exec_map == 0) { + *loc = addr; + return 1; + } + if ((page & 0600) == 0600) + base = mon_base_reg; + else + base = 03000; + tlb_data = e_tlb[page]; + } + if (tlb_data != 0) { +access: + *loc = ((tlb_data & 03777) << 9) + (addr & 0777); + /* Check access */ + if (wr && (tlb_data & 0200000) == 0) { + fault_data = 0402000; + goto fault_bbn; + } else if (fetch && (tlb_data & 0100000) == 0) { + fault_data = 0404000; + goto fault_bbn; + } else if ((tlb_data & 0400000) == 0) { + fault_data = 0404000; + goto fault_bbn; + } + return 1; + } + traps = FMASK; + /* Map the page */ +map_page: + while (tlb_data == 0) { + data = M[base + page]; + + switch ((data >> 33) & 03) { + case 0: /* Direct page */ + /* Bit 4 = execute */ + /* Bit 3 = Write */ + /* Bit 2 = Read */ + page = data & BBN_PAGE; + traps &= data & (BBN_MERGE|BBN_TRPPG); + tlb_data = (data & (BBN_EXEC|BBN_WRITE|BBN_READ) >> 16) | + (data & 03777); + break; + + case 1: /* Shared page */ + /* Check trap */ + base = 020000; + page = (data & BBN_SPT) >> 9; + traps &= data & (BBN_MERGE|BBN_PAGE); + data = 0; + lvl ++; + break; + + case 2: /* Indirect page */ + if (lvl == 2) { + /* Trap */ + fault_data = 0201000; + goto fault_bbn; + } + page = data & BBN_PN; + base = 020000 + ((data & BBN_SPT) >> 9); + traps &= data & (BBN_MERGE|BBN_PAGE); + data = 0; + lvl ++; + break; + + case 3: /* Invalid page */ + /* Trap all */ + fault_data = ((lvl != 0)? 0200000: 0) | 0401000; + goto fault_bbn; + } + if ((traps & (BBN_TRP|BBN_TRP1)) == (BBN_TRP|BBN_TRP1)) { + fault_data = 04000; + goto fault_bbn; + } + } + if (uf) { + u_tlb[page] = tlb_data; + } else { + e_tlb[page] = tlb_data; + } + /* Handle traps */ + if (page_fault) + goto fault_bbn1; + if (wr && (traps & BBN_TRPMOD)) { + fault_data = ((lvl != 0)? 0200000: 0) | 0440000; + goto fault_bbn; + } + if ((traps & BBN_TRPUSR)) { + fault_data = ((lvl != 0)? 0200000: 0) | 0420000; + goto fault_bbn; + } + if ((traps & BBN_ACC) == 0 || (traps & BBN_TRP)) { + fault_data = ((lvl != 0)? 0200000: 0) | 0410000; + goto fault_bbn; + } + /* Update CST */ + data = M[04000 + (tlb_data & 03777)]; + if ((data & 00700000000000LL) == 0) { + fault_data = 0100000 >> ((data >> 31) & 03); + goto fault_bbn; + } + data &= ~00777000000000LL; /* Clear age */ + if (wr) + data |= 00000400000000LL; /* Set modify */ + data |= pur; + M[04000 + (tlb_data & 03777)] = data; + goto access; + /* Handle fault */ +fault_bbn: + /* Write location of trap to PSB 571 */ + /* If write write MB to PSB 752 */ + /* Force APR to execute at location 70 */ + + /* Status word */ + /* RH = Effective address */ + /* Bit 17 = Exec Mode 0000001 */ + /* Bit 16 = Execute request 0000002 */ + /* Bit 15 = Write 0000004 */ + /* Bit 14 = Read 0000010 */ + /* Bit 13 = Ind 0000020 */ + /* Bit 12 = PI in progress 0000040 */ + /* Bit 11 = Key in progress 0000100 */ + /* Bit 10 = non-ex-mem 0000200 */ + /* Bit 9 = Parity 0000400 */ + /* Bit 0-8 = status */ + if ((FLAGS & USER) == 0) + fault_data |= 01; + if (fetch) + fault_data |= 02; + if (wr) + fault_data |= 04; + else + fault_data |= 010; + if (cur_context) + fault_data |= 020; + if (uuo_cycle) + fault_data |= 040; + page_fault = 1; + base = mon_base_reg; + tlb_data = e_tlb[0777]; + page = 0777; + goto map_page; +fault_bbn1: + M[((tlb_data & 03777) << 9) | 0571] = ((uint64)fault_data) << 18 | addr; + if (wr) + M[((tlb_data & 03777) << 9) | 0572] = MB; + return 0; + } +#endif if (!flag && (FLAGS & USER) != 0) { - if (addr <= ((Pl << 10) + 01777)) - *loc = (AB + (Rl << 10)) & RMASK; - else if (cpu_unit.flags & UNIT_TWOSEG && - (!Pflag & wr) == wr && - (AB & 0400000) != 0 && - (addr <= ((Ph << 10) + 01777))) - *loc = (AB + (Rh << 10)) & RMASK; - else { - mem_prot = 1; - set_interrupt(0, apr_irq); - return 0; + if (addr <= ((Pl << 10) + 01777)) { + *loc = (addr + (Rl << 10)) & RMASK; + return 1; } + if (cpu_unit.flags & UNIT_TWOSEG && + (addr & 0400000) != 0 && (addr <= ((Ph << 10) + 01777))) { + if ((Pflag == 0) || (Pflag == 1 && wr == 0)) { + *loc = (addr + (Rh << 10)) & RMASK; + return 1; + } + } + mem_prot = 1; + return 0; } else { *loc = addr; } return 1; } -/* - * Register access on KA 10 under ITS - */ -uint64 get_reg(int reg, int cur_context) { -#if ITS - if (cpu_unit.flags & UNIT_ITSPAGE) { - if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && - (xct_flag & 2) != 0) - return M[ac_ptr + (reg & 017)]; - } -#endif - return FM[reg & 017]; -} - -void set_reg(int reg, uint64 value, int cur_context) { -#if ITS - if (cpu_unit.flags & UNIT_ITSPAGE) { - if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && - (xct_flag & 4) != 0) { - M[ac_ptr + (reg & 017)] = value; - return; - } - } -#endif - FM[reg & 017] = value; -} - -//#define get_reg(reg) FM[(reg) & 017] -//#define set_reg(reg, value) FM[(reg) & 017] = value +#define get_reg(reg) FM[(reg) & 017] +#define set_reg(reg, value) FM[(reg) & 017] = value #endif /* @@ -1362,13 +1706,29 @@ void set_reg(int reg, uint64 value, int cur_context) { * * Return of 0 if successful, 1 if there was an error. */ -int Mem_read(int flag, int cur_context) { +int Mem_read(int flag, int cur_context, int fetch) { int addr; if (AB < 020) { +#if ITS + if (cpu_unit.flags & UNIT_ITSPAGE) { + if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && + (xct_flag & 2) != 0) + MB = M[ac_stack + AB]; + return 0; + } +#endif +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && + (xct_flag & 2) != 0) + MB = M[ac_stack + AB]; + return 0; + } +#endif #if KI | KL if (FLAGS & USER) { - MB = get_reg(AB, cur_context); + MB = get_reg(AB); return 0; } else { if (!cur_context && ((xct_flag & 1) != 0)) { @@ -1383,17 +1743,16 @@ int Mem_read(int flag, int cur_context) { } } #endif - MB = get_reg(AB, cur_context); + MB = get_reg(AB); } else { #if KI | KL read: #endif sim_interval--; - if (!page_lookup(AB, flag, &addr, 0, cur_context)) + if (!page_lookup(AB, flag, &addr, 0, cur_context, fetch)) return 1; if (addr >= (int)MEMSIZE) { nxm_flag = 1; - set_interrupt(0, apr_irq); return 1; } MB = M[addr]; @@ -1410,9 +1769,27 @@ int Mem_write(int flag, int cur_context) { int addr; if (AB < 020) { +#if ITS + if (cpu_unit.flags & UNIT_ITSPAGE) { + if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && + (xct_flag & 4) != 0) { + M[ac_stack + AB] = MB; + return 0; + } + } +#endif +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + if (xct_flag != 0 && !cur_context && (FLAGS & USER) == 0 && + (xct_flag & 4) != 0) { + M[ac_stack + AB] = MB; + return 0; + } + } +#endif #if KI | KL if (FLAGS & USER) { - set_reg(AB, MB, cur_context); + set_reg(AB, MB); return 0; } else { if (!cur_context && @@ -1430,21 +1807,16 @@ int Mem_write(int flag, int cur_context) { } } #endif - set_reg(AB, MB, cur_context); + set_reg(AB, MB); } else { #if KI | KL write: #endif sim_interval--; - if (!page_lookup(AB, flag, &addr, 1, cur_context)) + if (!page_lookup(AB, flag, &addr, 1, cur_context, 0)) return 1; -#if KI | KL - if (private_page) - return 1; -#endif if (addr >= (int)MEMSIZE) { nxm_flag = 1; - set_interrupt(0, apr_irq); return 1; } M[addr] = MB; @@ -1486,6 +1858,9 @@ int flag1; int flag3; int instr_count = 0; /* Number of instructions to execute */ uint32 IA; +#if ITS +char one_p_arm; /* One proceed arm */ +#endif if (sim_step != 0) { instr_count = sim_step; @@ -1507,9 +1882,11 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ pi_ov = 0; BYF5 = 0; #if KI | KL - private_page = 0; page_fault = 0; #endif +#if ITS + one_p_arm = 0; +#endif while ( reason == 0) { /* loop until ABORT */ if (sim_interval <= 0) { /* check clock queue */ @@ -1518,54 +1895,59 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ } } - if (sim_brk_summ && sim_brk_test(PC, SWMASK('E'))) { + if (sim_brk_summ && f_inst_fetch && sim_brk_test(PC, SWMASK('E'))) { reason = STOP_IBKPT; break; } + check_apr_irq(); /* Normal instruction */ if (f_load_pc) { - AB = PC; - uuo_cycle = 0; -#if KI | KL +#if ITS + if (one_p_arm) { + fault_data |= 02000; + mem_prot = 1; + one_p_arm = 0; + } +#endif +#if KI | KL | ITS | BBN + modify = 0; xct_flag = 0; trap_flag = 0; - modify = 0; #endif + AB = PC; + uuo_cycle = 0; + f_pc_inh = 0; } if (f_inst_fetch) { #if !(KI | KL) fetch: #endif - if (Mem_read(pi_cycle | uuo_cycle, 1)) + + if (Mem_read(pi_cycle | uuo_cycle, 1, 1)) { + pi_rq = check_irq_level(); + if (pi_rq) + goto st_pi; goto last; -#if KI | KL + } + no_fetch: -#endif IR = (MB >> 27) & 0777; AC = (MB >> 23) & 017; AD = MB; /* Save for historical sake */ IA = AB; - i_flags = opflags[IR]; BYF5 = 0; } - /* Second half of byte instruction */ - if (BYF5) { - i_flags = FCE; - AB = AR & RMASK; - } - #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(); @@ -1576,7 +1958,7 @@ no_fetch: /* Handle indirection repeat until no longer indirect */ do { - if (pi_enable & !pi_cycle & pi_pending + if (!pi_cycle & pi_pending #if KI | KL & !trap_flag #endif @@ -1587,13 +1969,13 @@ no_fetch: AR = MB; AB = MB & RMASK; if (MB & 017000000) { - AR = MB = (AB + get_reg((MB >> 18) & 017, 1)) & FMASK; + AR = MB = (AB + get_reg((MB >> 18) & 017)) & FMASK; AB = MB & RMASK; } if (IR != 0254) AR &= RMASK; if (ind & !pi_rq) - if (Mem_read(pi_cycle | uuo_cycle, 1)) + if (Mem_read(pi_cycle | uuo_cycle, 1, 0)) goto last; /* Handle events during a indirect loop */ if (sim_interval-- <= 0) { @@ -1603,8 +1985,10 @@ no_fetch: } } while (ind & !pi_rq); + /* If there is a interrupt handle it. */ if (pi_rq) { +st_pi: set_pi_hold(); /* Hold off all lower interrupts */ pi_cycle = 1; pi_rq = 0; @@ -1640,19 +2024,32 @@ no_fetch: #endif } + +#if KI | KL + if (page_enable && page_fault) { + if (!f_pc_inh && !pi_cycle) + PC = (PC + 1) & RMASK; + goto last; + } +#endif + #if ITS if (pi_cycle == 0 && cpu_unit.flags & UNIT_ITSPAGE) { opc = PC | (FLAGS << 18); + if (!f_pc_inh && (FLAGS & ONEP) != 0) { + one_p_arm = 1; + FLAGS &= ~ONEP; + } } #endif /* Update history */ #if KI - if (hst_lnt && (fm_sel || PC > 020) && (PC & 0777774) != 0777040 && - (PC & 0777700) != 023700 && (PC != 0527154)) { + if (hst_lnt && /*(fm_sel || */PC > 020 && (PC & 0777774) != 0777040 && + (PC & 0777700) != 023700 && (PC != 0526772)) { #else - if (hst_lnt && PC > 020 /*&& (PC & 0777774) != 0472174 && - (PC & 0777700) != 023700 && (PC != 0527154)*/) { + if (hst_lnt && /*(FLAGS & USER) && */ PC > 020 && /*(PC & 0777774) != 0472174 && */ + (PC & 0777700) != 0113700 && (PC != 0527154)) { #endif hst_p = hst_p + 1; if (hst_p >= hst_lnt) { @@ -1666,18 +2063,17 @@ no_fetch: | (mem_prot << 4) | (push_ovf << 3) #endif ; - hst[hst_p].ac = get_reg(AC, 1); + hst[hst_p].ac = get_reg(AC); } -fetch_opr: /* Set up to execute instruction */ f_inst_fetch = 1; f_load_pc = 1; nrf = 0; fxu_hold_set = 0; sac_inh = 0; -#if KI | KL +#if KI | KL | ITS | BBN modify = 0; f_pc_inh = (trap_flag != 0); #else @@ -1685,9 +2081,9 @@ fetch_opr: #endif /* Load pseudo registers based on flags */ if (i_flags & (FCEPSE|FCE)) { - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; -#if KI | KL +#if KI | KL | ITS | BBN modify = 1; #endif AR = MB; @@ -1695,19 +2091,11 @@ fetch_opr: if (i_flags & FAC) { BR = AR; - AR = get_reg(AC, 1); - } - - if (i_flags & SWAR) { - AR = SWAP_AR; + AR = get_reg(AC); } if (i_flags & FBR) { - BR = get_reg(AC, 1); - } - - if (i_flags & FMB) { - BR = MB; + BR = get_reg(AC); } if (hst_lnt) { @@ -1715,11 +2103,15 @@ fetch_opr: } if (i_flags & FAC2) { - MQ = get_reg(AC + 1, 1); + MQ = get_reg(AC + 1); } else if (!BYF5) { MQ = 0; } + if (i_flags & SWAR) { + AR = SWAP_AR; + } + /* Process the instruction */ switch (IR) { muuo: @@ -1764,8 +2156,8 @@ unasign: FLAGS |= OVR; } PC = MB & RMASK; - f_pc_inh = 1; trap_flag = 0; + f_pc_inh = 1; break; #else uuo_cycle = 1; @@ -1804,16 +2196,16 @@ unasign: /* On Load AR,MQ has memory operand */ /* AR,MQ = AC BR,MB = mem */ /* AR High */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; modify = 1; AR = MB; BR = AR; - AR = get_reg(AC, 1); - MQ = get_reg(AC + 1, 1); + AR = get_reg(AC); + MQ = get_reg(AC + 1); AB = (AB + 1) & RMASK; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; SC = GET_EXPO(BR); SMEAR_SIGN(BR); @@ -1892,23 +2284,23 @@ dpnorm: AR |= ((uint64)(SCAD & 0377)) << 27; MQ = ARX; - set_reg(AC, AR, 1); - set_reg(AC+1, MQ, 1); + set_reg(AC, AR); + set_reg(AC+1, MQ); break; case 0112: /* DFMP */ /* On Load AR,MQ has memory operand */ /* AR,MQ = AC BR,MB = mem */ /* AR High */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; modify = 1; AR = MB; BR = AR; - AR = get_reg(AC, 1); - MQ = get_reg(AC + 1, 1); + AR = get_reg(AC); + MQ = get_reg(AC + 1); AB = (AB + 1) & RMASK; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; SC = GET_EXPO(AR); SMEAR_SIGN(AR); @@ -1944,15 +2336,15 @@ dpnorm: /* On Load AR,MQ has memory operand */ /* AR,MQ = AC BR,MB = mem */ /* AR High */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; modify = 1; AR = MB; BR = AR; - AR = get_reg(AC, 1); - MQ = get_reg(AC + 1, 1); + AR = get_reg(AC); + MQ = get_reg(AC + 1); AB = (AB + 1) & RMASK; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; SC = GET_EXPO(AR); SMEAR_SIGN(AR); @@ -2009,47 +2401,43 @@ dpnorm: goto unasign; case 0120: /* DMOVE */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = MB; AB = (AB + 1) & RMASK; modify = 0; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; MQ = MB; - set_reg(AC, AR, 1); - set_reg(AC+1, MQ, 1); + set_reg(AC, AR); + set_reg(AC+1, MQ); break; case 0121: /* DMOVN */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = MB; AB = (AB + 1) & RMASK; modify = 0; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; MQ = ((MB & CMASK) ^ CMASK) + 1; /* Low */ /* High */ AR = (CM(AR) + ((MQ & SMASK) != 0)) & FMASK; MQ &= CMASK; - set_reg(AC, AR, 1); - set_reg(AC+1, MQ, 1); + set_reg(AC, AR); + set_reg(AC+1, MQ); break; case 0124: /* DMOVEM */ - AR = get_reg(AC, 1); - MQ = get_reg(AC + 1, 1); + AR = get_reg(AC); + MQ = get_reg(AC + 1); /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { MB = AR; if (Mem_write(0, 0)) goto last; FLAGS |= BYTI; -#if KI /* KL does this in one shot */ - f_pc_inh = 1; - break; -#endif } if ((FLAGS & BYTI)) { AB = (AB + 1) & RMASK; @@ -2061,8 +2449,8 @@ dpnorm: break; case 0125: /* DMOVNM */ - AR = get_reg(AC, 1); - MQ = get_reg(AC + 1, 1); + AR = get_reg(AC); + MQ = get_reg(AC + 1); /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { BR = AR = CM(AR); @@ -2075,12 +2463,9 @@ dpnorm: if (Mem_write(0, 0)) goto last; FLAGS |= BYTI; -#if KI - f_pc_inh = 1; - break; -#endif } if ((FLAGS & BYTI)) { + MQ = get_reg(AC + 1); MQ = (CM(MQ) + 1) & CMASK; AB = (AB + 1) & RMASK; MB = MQ; @@ -2092,7 +2477,7 @@ dpnorm: case 0122: /* FIX */ case 0126: /* FIXR */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = MB; MQ = 0; @@ -2127,11 +2512,11 @@ dpnorm: if (flag1) AR = (CM(AR) + 1) & FMASK; if (!sac_inh) - set_reg(AC, AR, 1); + set_reg(AC, AR); break; case 0127: /* FLTR */ - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = MB; if (AR & SMASK) { @@ -2144,57 +2529,98 @@ dpnorm: i_flags = SAC; goto fnorm; #else - /* MUUO */ - case 0102: /* ITS LPM */ + case 0100: /* TENEX UMOVE */ +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + if (Mem_read(0, 0, 0)) { + IR = 0; + goto last; + } + AR = MB; + set_reg(AC, AR); /* blank, I, B */ + IR = 0; + break; + } +#endif + goto unasign; + case 0101: /* TENEX UMOVEI */ +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + set_reg(AC, AR); /* blank, I, B */ + IR = 0; + break; + } +#endif + goto unasign; + case 0102: /* TENEX UMOVEM */ /* ITS LPM */ #if ITS if ((FLAGS & USER) == 0 && cpu_unit.flags & UNIT_ITSPAGE) { /* Load store ITS pager info */ /* AC & 1 = Store */ if (AC & 1) { + if ((AB + 8) > MEMSIZE) { + fault_data |= 0400; + mem_prot = 1; + break; + } MB = ((uint64)age) << 27 | - ((uint64)fault_addr & 0777000) << 9 | + ((uint64)fault_addr & 0777) << 18 | (uint64)jpc; - Mem_write(1,0); + M[AB] = MB; AB = (AB + 1) & RMASK; MB = opc; - Mem_write(1,0); + M[AB] = MB; AB = (AB + 1) & RMASK; - MB = (uint64)mar; - Mem_write(1,0); + MB = ((uint64)mar) | ((uint64)pag_reload) << 20; + M[AB] = MB; AB = (AB + 1) & RMASK; - MB = 0 /* Flags | Quant */; - Mem_write(1,0); + MB = ((uint64)fault_data) << 18; + /* Add quantum */ + M[AB] = MB; AB = (AB + 1) & RMASK; - MB = ((uint64)fault_addr & 0777) << 24 | + MB = ((uint64)fault_addr & 00760000) << 12 | (uint64)dbr1; - Mem_write(1,0); + M[AB] = MB; AB = (AB + 1) & RMASK; - MB = (uint64)dbr2; - Mem_write(1,0); + MB = ((uint64)fault_addr & 00017000) << 8 | + (uint64)dbr2; + M[AB] = MB; AB = (AB + 1) & RMASK; MB = (uint64)dbr3; - Mem_write(1,0); + M[AB] = MB; AB = (AB + 1) & RMASK; - MB = (uint64)ac_ptr; - Mem_write(1,0); + MB = (uint64)ac_stack; + M[AB] = MB; } else { - Mem_read(1,0); /* WD 0 */ + if ((AB + 8) > MEMSIZE) { + fault_data |= 0400; + mem_prot = 1; + break; + } + MB = M[AB]; /* WD 0 */ age = (MB >> 27) & 017; + fault_addr = 0; AB = (AB + 2) & RMASK; - Mem_read(1,0); /* WD 2 */ + MB = M[AB]; /* WD 2 */ mar = 03777777 & MB; - AB = (AB + 2) & RMASK; - Mem_read(1,0); /* WD 4 */ + pag_reload = 0; + AB = (AB + 1) & RMASK; + MB = M[AB]; /* WD 3 */ + /* Store Quantum */ + fault_data = (MB >> 18) & RMASK; + AB = (AB + 1) & RMASK; + MB = M[AB]; /* WD 4 */ dbr1 = ((077 << 18) | RMASK) & MB; AB = (AB + 1) & RMASK; - Mem_read(1,0); /* WD 5 */ + MB = M[AB]; /* WD 5 */ dbr2 = ((077 << 18) | RMASK) & MB; AB = (AB + 1) & RMASK; - Mem_read(1,0); /* WD 6 */ + MB = M[AB]; /* WD 6 */ dbr3 = ((077 << 18) | RMASK) & MB; AB = (AB + 1) & RMASK; - Mem_read(1,0); /* WD 7 */ - ac_ptr = MB & RMASK; + MB = M[AB]; /* WD 7 */ + ac_stack = MB & RMASK; + page_enable = 1; } /* AC & 2 = Clear TLB */ if (AC & 2) { @@ -2208,10 +2634,22 @@ dpnorm: } break; } - goto unasign; #endif +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + AR = get_reg(AC); + MB = AR; + if (Mem_write(0, 0)) { + IR = 0; + goto last; + } + IR = 0; + break; + } +#endif + goto unasign; - case 0103: /* ITS XCTR */ + case 0103: /* TENEX UMOVES */ /* ITS XCTR */ #if ITS if (cpu_unit.flags & UNIT_ITSPAGE) { /* AC & 1 = ??? */ @@ -2225,9 +2663,55 @@ dpnorm: break; } #endif +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + if (Mem_read(0, 0, 0)) { + IR = 0; + goto last; + } + modify = 1; + AR = MB; + if (Mem_write(0, 0)) { + IR = 0; + goto last; + } + if (AC != 0) + set_reg(AC, AR); /* blank, I, B */ + IR = 0; + break; + } +#endif + goto unasign; - case 0100: case 0101: - case 0104: case 0105: case 0106: case 0107: + /* MUUO */ + case 0104: /* TENEX JSYS */ +#if BBN + if (cpu_unit.flags & UNIT_BBNPAGE) { + BR = ((uint64)(FLAGS) << 23) | ((PC + !pi_cycle) & RMASK); + if (AB < 01000) { + AB += 01000; + if ((FLAGS & USER) == 0) + FLAGS |= EXJSYS; + FLAGS &= ~USER; + } + if (Mem_read(0, 0, 0)) { + FLAGS = (uint32)(BR >> 23); /* On error restore flags */ + goto last; + } + AR = MB; + AB = (AR >> 18) & RMASK; + MB = BR; + if (Mem_write(0, 0)) { + FLAGS = (uint32)(BR >> 23); /* On error restore flags */ + goto last; + } + PC = AR & RMASK; + break; + } +#endif + goto unasign; + + case 0105: case 0106: case 0107: case 0110: case 0111: case 0112: case 0113: case 0114: case 0115: case 0116: case 0117: case 0120: case 0121: case 0122: case 0123: @@ -2240,7 +2724,6 @@ unasign: Mem_write(uuo_cycle, 0); AB += 1; f_load_pc = 0; - f_pc_inh = 1; break; #endif @@ -2248,10 +2731,10 @@ unasign: case 0134: /* ILDB */ case 0136: /* IDPB */ if ((FLAGS & BYTI) == 0) { /* BYF6 */ -#if KI | KL +#if KI | KL | ITS | BBN modify = 1; #endif - if (Mem_read(0, 1)) + if (Mem_read(0, 1, 0)) goto last; AR = MB; SC = (AR >> 24) & 077; @@ -2272,50 +2755,50 @@ unasign: goto last; if ((IR & 04) == 0) break; + goto ldb_ptr; } /* Fall through */ case 0135:/* LDB */ case 0137:/* DPB */ - if (((FLAGS & BYTI) == 0) | !BYF5) { - if (Mem_read(0, 1)) + if ((FLAGS & BYTI) == 0 || !BYF5) { + if (Mem_read(0, 1, 0)) goto last; AR = MB; +ldb_ptr: SC = (AR >> 30) & 077; MQ = (uint64)(1) << ( 077 & (AR >> 24)); MQ -= 1; - SC = ((0777 ^ SC) + 1) & 0777; f_load_pc = 0; f_inst_fetch = 0; f_pc_inh = 1; - FLAGS |= BYTI; /* BYF6 */ + FLAGS |= BYTI; BYF5 = 1; - break; - } - if ((IR & 06) == 4) { - AR = MB; - while(SC != 0) { - AR >>= 1; - SC = (SC + 1) & 0777; - } - AR &= MQ; - set_reg(AC, AR, 1); } else { - BR = MB; - AR = get_reg(AC, 1) & MQ; - while(SC != 0) { - AR <<= 1; - MQ <<= 1; - SC = (SC + 1) & 0777; + AB = AR & RMASK; +#if KI | KL | ITS | BBN + if ((IR & 06) == 6) + modify = 1; +#endif + if (Mem_read(0, 0, 0)) + goto last; + AR = MB; + if ((IR & 06) == 4) { + AR = AR >> SC; + AR &= MQ; + set_reg(AC, AR); + } else { + BR = get_reg(AC); + BR = BR << SC; + MQ = MQ << SC; + AR &= CM(MQ); + AR |= BR & MQ; + MB = AR & FMASK; + Mem_write(0, 0); } - BR &= CM(MQ); - AR &= FMASK; - BR |= AR & MQ; - MB = BR; - Mem_write(0, 0); + FLAGS &= ~BYTI; + BYF5 = 0; } - FLAGS &= ~BYTI; /* BYF6 */ - BYF5 = 0; break; #if !PDP6 @@ -2504,7 +2987,7 @@ fxnorm: /* Handle UFA */ if (IR == 0130) { - set_reg(AC + 1, AR, 1); + set_reg(AC + 1, AR); break; } break; @@ -2699,6 +3182,8 @@ fxnorm: case 0205: /* MOVSI */ case 0206: /* MOVSM */ case 0207: /* MOVSS */ + case 0503: /* HLLS */ + case 0543: /* HRRS */ break; case 0214: /* MOVM */ @@ -2707,13 +3192,13 @@ fxnorm: case 0217: /* MOVMS */ if ((AR & SMASK) == 0) break; + /* Fall though */ case 0210: /* MOVN */ case 0211: /* MOVNI */ case 0212: /* MOVNM */ case 0213: /* MOVNS */ flag1 = flag3 = 0; - FLAGS &= 01777; if ((((AR & CMASK) ^ CMASK) + 1) & SMASK) { FLAGS |= CRY1; flag1 = 1; @@ -2833,7 +3318,6 @@ fxnorm: case 0236: /* DIVM */ case 0237: /* DIVB */ flag1 = 0; - flag3 = 0; if (AR & SMASK) { AD = (CM(MQ) + 1) & FMASK; MQ = AR; @@ -2949,11 +3433,16 @@ fxnorm: #if !PDP6 SC = 0; if (AR != 0) { +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AB; f_pc_inh = 1; SC = nlzero(AR); } - set_reg(AC + 1, SC, 1); + set_reg(AC + 1, SC); #endif break; @@ -3029,11 +3518,11 @@ fxnorm: } else { if (SC > 36) { if (AB & RSIGN) { - AR = MQ; - MQ = 0; - } else { MQ = AR; AR = 0; + } else { + AR = MQ; + MQ = 0; } SC -= 36; } @@ -3049,7 +3538,7 @@ fxnorm: /* Branch */ case 0250: /* EXCH */ - set_reg(AC, BR, 1); + set_reg(AC, BR); break; case 0251: /* BLT */ @@ -3059,26 +3548,26 @@ fxnorm: sim_process_event(); } /* Allow for interrupt */ - if (pi_enable && pi_pending) { + 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, 1); + set_reg(AC, AR); break; } } AB = (AR >> 18) & RMASK; - if (Mem_read(0, 0)) { + if (Mem_read(0, 0, 0)) { f_pc_inh = 1; - set_reg(AC, AR, 1); + set_reg(AC, AR); goto last; } AB = (AR & RMASK); if (Mem_write(0, 0)) { f_pc_inh = 1; - set_reg(AC, AR, 1); + set_reg(AC, AR); goto last; } AD = (AR & RMASK) + CM(BR) + 1; @@ -3089,19 +3578,27 @@ fxnorm: case 0252: /* AOBJP */ AR = AOB(AR); if ((AR & SMASK) == 0) { +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AB; f_pc_inh = 1; } - AR &= FMASK; break; case 0253: /* AOBJN */ AR = AOB(AR); if ((AR & SMASK) != 0) { +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AB; f_pc_inh = 1; } - AR &= FMASK; break; case 0254: /* JRST */ /* AR Frm PC */ @@ -3134,6 +3631,11 @@ fxnorm: reason = STOP_HALT; } } +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AR & RMASK; /* JRSTF */ if (AC & 02) { @@ -3153,7 +3655,6 @@ fxnorm: if (AC & 01) { /* Enter User Mode */ #if KI | KL FLAGS &= ~PUBLIC; - private_page = 0; #else FLAGS |= USER; #endif @@ -3162,19 +3663,27 @@ fxnorm: break; case 0255: /* JFCL */ - if ((FLAGS >> 9) & AC) + if ((FLAGS >> 9) & AC) { +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AR & RMASK; - else - PC = (PC + 1) & RMASK; - f_pc_inh = 1; + f_pc_inh = 1; + } FLAGS &= 017777 ^ (AC << 9); break; case 0256: /* XCT */ f_load_pc = 0; f_pc_inh = 1; +#if BBN + if ((FLAGS & USER) == 0 && cpu_unit.flags & UNIT_BBNPAGE) + xct_flag = AC; +#endif #if KI | KL - if ((FLAGS & USER) == 0) + if ((FLAGS & USER) == 0) xct_flag = AC; #endif break; @@ -3187,7 +3696,7 @@ fxnorm: /* Check if Paging Enabled */ if (!page_enable) { AR = 0020000LL + f; /* direct map */ - set_reg(AC, AR, 1); + set_reg(AC, AR); break; } AR = ub_ptr; @@ -3195,7 +3704,7 @@ fxnorm: /* Check if small user and outside range */ if (small_user && (f & 0340) != 0) { AR = 0420000LL; /* Page failure, no match */ - set_reg(AC, AR, 1); + set_reg(AC, AR); break; } } else { @@ -3207,14 +3716,14 @@ fxnorm: AR = eb_ptr; } else { AR = 0020000LL + f; /* direct map */ - set_reg(AC, AR, 1); + set_reg(AC, AR); break; } last_page |= 1; } AB = (AR + (f >> 1)) & RMASK; pag_reload = ((pag_reload + 1) & 037) | 040; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = MB; if ((f & 1) == 0) @@ -3226,8 +3735,7 @@ fxnorm: if ((AR & 0100000LL) == 0) AR |= RSIGN; } -fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); - set_reg(AC, AR, 1); + set_reg(AC, AR); #endif break; @@ -3249,10 +3757,14 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); check_apr_irq(); #endif } - AR &= FMASK; if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = BR & RMASK; f_pc_inh = 1; break; @@ -3269,7 +3781,6 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); check_apr_irq(); #endif } - AR &= FMASK; MB = BR; if (Mem_write(0, 0)) goto last; @@ -3277,7 +3788,7 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); case 0262: /* POP */ AB = AR & RMASK; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; AR = SOB(AR); AB = BR & RMASK; @@ -3292,13 +3803,17 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); check_apr_irq(); #endif } - AR &= FMASK; break; case 0263: /* POPJ */ AB = AR & RMASK; - if (Mem_read(0, 0)) + if (Mem_read(0, 0, 0)) goto last; +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = MB & RMASK; AR = SOB(AR); if ((AR & C1) == 0) { @@ -3310,7 +3825,6 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); check_apr_irq(); #endif } - AR &= FMASK; f_pc_inh = 1; break; @@ -3323,6 +3837,11 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); if (Mem_write(0, 0)) goto last; FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = (AR + 1) & RMASK; f_pc_inh = 1; break; @@ -3334,26 +3853,41 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AR & RMASK; AR = AD; f_pc_inh = 1; break; case 0266: /* JSA */ /* AR Frm PC */ - set_reg(AC, (AR << 18) | ((PC + 1) & RMASK), 1); + set_reg(AC, (AR << 18) | ((PC + 1) & RMASK)); if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AR & RMASK; AR = BR; break; case 0267: /* JRA */ AD = AB; - AB = (get_reg(AC, 1) >> 18) & RMASK; - if (Mem_read(uuo_cycle | pi_cycle, 0)) + AB = (get_reg(AC) >> 18) & RMASK; + if (Mem_read(uuo_cycle | pi_cycle, 0, 0)) goto last; - set_reg(AC, MB, 1); + set_reg(AC, MB); +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif PC = AD & RMASK; f_pc_inh = 1; break; @@ -3363,14 +3897,14 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); case 0272: /* ADDM */ case 0273: /* ADDB */ flag1 = flag3 = 0; - FLAGS &= 01777; if (((AR & CMASK) + (BR & CMASK)) & SMASK) { FLAGS |= CRY1; flag1 = 1; } - BR = AR + BR; - if (BR & C1) { - FLAGS |= CRY0; + AR = AR + BR; + if (AR & C1) { + if (!pi_cycle) + FLAGS |= CRY0; flag3 = 1; } if (flag1 != flag3) { @@ -3378,8 +3912,6 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); FLAGS |= OVR|TRP1; check_apr_irq(); } - BR &= FMASK; - AR = BR; break; case 0274: /* SUB */ @@ -3387,14 +3919,14 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); case 0276: /* SUBM */ case 0277: /* SUBB */ flag1 = flag3 = 0; - FLAGS &= 01777; if ((((AR & CMASK) ^ CMASK) + (BR & CMASK) + 1) & SMASK) { FLAGS |= CRY1; flag1 = 1; } - BR = CM(AR) + BR + 1; - if (BR & C1) { - FLAGS |= CRY0; + AR = CM(AR) + BR + 1; + if (AR & C1) { + if (!pi_cycle) + FLAGS |= CRY0; flag3 = 1; } if (flag1 != flag3) { @@ -3402,27 +3934,24 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); FLAGS |= OVR|TRP1; check_apr_irq(); } - BR &= FMASK; - AR = BR; break; - /* SKIP */ - case 0300: /* CAI */ - case 0301: /* CAIL */ - case 0302: /* CAIE */ + case 0300: /* CAI */ + case 0301: /* CAIL */ + case 0302: /* CAIE */ case 0303: /* CAILE */ - case 0304: /* CAIA */ + case 0304: /* CAIA */ case 0305: /* CAIGE */ - case 0306: /* CAIN */ - case 0307: /* CAIG */ - case 0310: /* CAM */ - case 0311: /* CAML */ - case 0312: /* CAME */ + case 0306: /* CAIN */ + case 0307: /* CAIG */ + case 0310: /* CAM */ + case 0311: /* CAML */ + case 0312: /* CAME */ case 0313: /* CAMLE */ - case 0314: /* CAMA */ + case 0314: /* CAMA */ case 0315: /* CAMGE */ - case 0316: /* CAMN */ - case 0317: /* CAMG */ + case 0316: /* CAMN */ + case 0317: /* CAMG */ f = 0; AD = (CM(AR) + BR) + 1; if (((BR & SMASK) != 0) && (AR & SMASK) == 0) @@ -3432,61 +3961,61 @@ fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); f = 1; goto skip_op; - case 0320: /* JUMP */ - case 0321: /* JUMPL */ - case 0322: /* JUMPE */ - case 0323: /* JUMPLE */ - case 0324: /* JUMPA */ - case 0325: /* JUMPGE */ - case 0326: /* JUMPN */ - case 0327: /* JUMPG */ + case 0320: /* JUMP */ + case 0321: /* JUMPL */ + case 0322: /* JUMPE */ + case 0323: /* JUMPLE */ + case 0324: /* JUMPA */ + case 0325: /* JUMPGE */ + case 0326: /* JUMPN */ + case 0327: /* JUMPG */ AD = AR; f = ((AD & SMASK) != 0); goto jump_op; /* JUMP, SKIP */ - case 0330: /* SKIP */ - case 0331: /* SKIPL */ - case 0332: /* SKIPE */ - case 0333: /* SKIPLE */ - case 0334: /* SKIPA */ - case 0335: /* SKIPGE */ - case 0336: /* SKIPN */ - case 0337: /* SKIPG */ + case 0330: /* SKIP */ + case 0331: /* SKIPL */ + case 0332: /* SKIPE */ + case 0333: /* SKIPLE */ + case 0334: /* SKIPA */ + case 0335: /* SKIPGE */ + case 0336: /* SKIPN */ + case 0337: /* SKIPG */ AD = AR; f = ((AD & SMASK) != 0); goto skip_op; /* JUMP, SKIP */ - case 0340: /* AOJ */ - case 0341: /* AOJL */ - case 0342: /* AOJE */ - case 0343: /* AOJLE */ - case 0344: /* AOJA */ - case 0345: /* AOJGE */ - case 0346: /* AOJN */ - case 0347: /* AOJG */ - case 0360: /* SOJ */ - case 0361: /* SOJL */ - case 0362: /* SOJE */ - case 0363: /* SOJLE */ - case 0364: /* SOJA */ - case 0365: /* SOJGE */ - case 0366: /* SOJN */ - case 0367: /* SOJG */ + case 0340: /* AOJ */ + case 0341: /* AOJL */ + case 0342: /* AOJE */ + case 0343: /* AOJLE */ + case 0344: /* AOJA */ + case 0345: /* AOJGE */ + case 0346: /* AOJN */ + case 0347: /* AOJG */ + case 0360: /* SOJ */ + case 0361: /* SOJL */ + case 0362: /* SOJE */ + case 0363: /* SOJLE */ + case 0364: /* SOJA */ + case 0365: /* SOJGE */ + case 0366: /* SOJN */ + case 0367: /* SOJG */ flag1 = flag3 = 0; - FLAGS &= 01777; AD = (IR & 020) ? FMASK : 1; if (((AR & CMASK) + (AD & CMASK)) & SMASK) { - FLAGS |= CRY1; + if (!pi_cycle) + FLAGS |= CRY1; flag1 = 1; } AD = AR + AD; if (AD & C1) { - FLAGS |= CRY0; + if (!pi_cycle) + FLAGS |= CRY0; flag3 = 1; } - if (flag1 != flag3) { - if (!pi_cycle) - FLAGS |= OVR|TRP1; + if (flag1 != flag3 && !pi_cycle) { + FLAGS |= OVR|TRP1; check_apr_irq(); } f = ((AD & SMASK) != 0); @@ -3496,32 +4025,37 @@ jump_op: f |= ((AD == 0) << 1); f = f & IR; if (((IR & 04) != 0) == (f == 0)) { - PC = AB; - f_pc_inh = 1; +#if ITS + if ((FLAGS & USER) && cpu_unit.flags & UNIT_ITSPAGE) { + jpc = PC; + } +#endif + PC = AB; + f_pc_inh = 1; } break; - case 0350: /* AOS */ - case 0351: /* AOSL */ - case 0352: /* AOSE */ - case 0353: /* AOSLE */ - case 0354: /* AOSA */ - case 0355: /* AOSGE */ - case 0356: /* AOSN */ - case 0357: /* AOSG */ - case 0370: /* SOS */ - case 0371: /* SOSL */ - case 0372: /* SOSE */ - case 0373: /* SOSLE */ - case 0374: /* SOSA */ - case 0375: /* SOSGE */ - case 0376: /* SOSN */ - case 0377: /* SOSG */ + case 0350: /* AOS */ + case 0351: /* AOSL */ + case 0352: /* AOSE */ + case 0353: /* AOSLE */ + case 0354: /* AOSA */ + case 0355: /* AOSGE */ + case 0356: /* AOSN */ + case 0357: /* AOSG */ + case 0370: /* SOS */ + case 0371: /* SOSL */ + case 0372: /* SOSE */ + case 0373: /* SOSLE */ + case 0374: /* SOSA */ + case 0375: /* SOSGE */ + case 0376: /* SOSN */ + case 0377: /* SOSG */ flag1 = flag3 = 0; - FLAGS &= 01777; AD = (IR & 020) ? FMASK : 1; if (((AR & CMASK) + (AD & CMASK)) & SMASK) { - FLAGS |= CRY1; + if (!pi_cycle) + FLAGS |= CRY1; flag1 = 1; } AD = AR + AD; @@ -3530,9 +4064,8 @@ jump_op: FLAGS |= CRY0; flag3 = 1; } - if (flag1 != flag3) { - if (!pi_cycle) - FLAGS |= OVR|TRP1; + if (flag1 != flag3 && !pi_cycle) { + FLAGS |= OVR|TRP1; check_apr_irq(); } f = ((AD & SMASK) != 0); @@ -3551,281 +4084,286 @@ skip_op: break; /* Bool */ - case 0400: /* SETZ */ + case 0400: /* SETZ */ case 0401: /* SETZI */ case 0402: /* SETZM */ case 0403: /* SETZB */ AR = 0; /* SETZ */ break; - case 0404: /* AND */ + case 0404: /* AND */ case 0405: /* ANDI */ case 0406: /* ANDM */ case 0407: /* ANDB */ AR = AR & BR; /* AND */ break; - case 0410: /* ANDCA */ + case 0410: /* ANDCA */ case 0411: /* ANDCAI */ case 0412: /* ANDCAM */ case 0413: /* ANDCAB */ AR = AR & CM(BR); /* ANDCA */ break; - case 0414: /* SETM */ + case 0414: /* SETM */ case 0415: /* SETMI */ case 0416: /* SETMM */ case 0417: /* SETMB */ /* SETM */ break; - case 0420: /* ANDCM */ + case 0420: /* ANDCM */ case 0421: /* ANDCMI */ case 0422: /* ANDCMM */ case 0423: /* ANDCMB */ AR = CM(AR) & BR; /* ANDCM */ break; - case 0424: /* SETA */ + case 0424: /* SETA */ case 0425: /* SETAI */ case 0426: /* SETAM */ case 0427: /* SETAB */ AR = BR; /* SETA */ break; - case 0430: /* XOR */ + case 0430: /* XOR */ case 0431: /* XORI */ case 0432: /* XORM */ case 0433: /* XORB */ AR = AR ^ BR; /* XOR */ break; - case 0434: /* IOR */ + case 0434: /* IOR */ case 0435: /* IORI */ case 0436: /* IORM */ case 0437: /* IORB */ AR = CM(CM(AR) & CM(BR)); /* IOR */ break; - case 0440: /* ANDCB */ + case 0440: /* ANDCB */ case 0441: /* ANDCBI */ case 0442: /* ANDCBM */ case 0443: /* ANDCBB */ AR = CM(AR) & CM(BR); /* ANDCB */ break; - case 0444: /* EQV */ + case 0444: /* EQV */ case 0445: /* EQVI */ case 0446: /* EQVM */ case 0447: /* EQVB */ AR = CM(AR ^ BR); /* EQV */ break; - case 0450: /* SETCA */ + case 0450: /* SETCA */ case 0451: /* SETCAI */ case 0452: /* SETCAM */ case 0453: /* SETCAB */ AR = CM(BR); /* SETCA */ break; - case 0454: /* ORCA */ + case 0454: /* ORCA */ case 0455: /* ORCAI */ case 0456: /* ORCAM */ case 0457: /* ORCAB */ AR = CM(CM(AR) & BR); /* ORCA */ break; - case 0460: /* SETCM */ + case 0460: /* SETCM */ case 0461: /* SETCMI */ case 0462: /* SETCMM */ case 0463: /* SETCMB */ AR = CM(AR); /* SETCM */ break; - case 0464: /* ORCM */ + case 0464: /* ORCM */ case 0465: /* ORCMI */ case 0466: /* ORCMM */ case 0467: /* ORCMB */ AR = CM(AR & CM(BR)); /* ORCM */ break; - case 0470: /* ORCB */ + case 0470: /* ORCB */ case 0471: /* ORCBI */ case 0472: /* ORCBM */ case 0473: /* ORCBB */ AR = CM(AR & BR); /* ORCB */ break; - case 0474: /* SETO */ + case 0474: /* SETO */ case 0475: /* SETOI */ case 0476: /* SETOM */ case 0477: /* SETOB */ AR = FMASK; /* SETO */ break; - case 0500: /* HLL */ - case 0501: /* HLLI */ - case 0502: /* HLLM */ - case 0503: /* HLLS */ - case 0504: /* HRL */ - case 0505: /* HRLI */ - case 0506: /* HRLM */ - case 0507: /* HRLS */ + + case 0547: /* HLRS */ + BR = SWAP_AR; + /* Fall Through */ + + case 0500: /* HLL */ + case 0501: /* HLLI */ + case 0502: /* HLLM */ + case 0504: /* HRL */ + case 0505: /* HRLI */ + case 0506: /* HRLM */ AR = (AR & LMASK) | (BR & RMASK); break; - case 0510: /* HLLZ */ - case 0511: /* HLLZI */ - case 0512: /* HLLZM */ - case 0513: /* HLLZS */ - case 0514: /* HRLZ */ - case 0515: /* HRLZI */ - case 0516: /* HRLZM */ - case 0517: /* HRLZS */ + case 0510: /* HLLZ */ + case 0511: /* HLLZI */ + case 0512: /* HLLZM */ + case 0513: /* HLLZS */ + case 0514: /* HRLZ */ + case 0515: /* HRLZI */ + case 0516: /* HRLZM */ + case 0517: /* HRLZS */ AR = (AR & LMASK); break; - case 0520: /* HLLO */ - case 0521: /* HLLOI */ - case 0522: /* HLLOM */ - case 0523: /* HLLOS */ - case 0524: /* HRLO */ - case 0525: /* HRLOI */ - case 0526: /* HRLOM */ - case 0527: /* HRLOS */ + case 0520: /* HLLO */ + case 0521: /* HLLOI */ + case 0522: /* HLLOM */ + case 0523: /* HLLOS */ + case 0524: /* HRLO */ + case 0525: /* HRLOI */ + case 0526: /* HRLOM */ + case 0527: /* HRLOS */ AR = (AR & LMASK) | RMASK; break; - case 0530: /* HLLE */ - case 0531: /* HLLEI */ - case 0532: /* HLLEM */ - case 0533: /* HLLES */ - case 0534: /* HRLE */ - case 0535: /* HRLEI */ - case 0536: /* HRLEM */ - case 0537: /* HRLES */ + case 0530: /* HLLE */ + case 0531: /* HLLEI */ + case 0532: /* HLLEM */ + case 0533: /* HLLES */ + case 0534: /* HRLE */ + case 0535: /* HRLEI */ + case 0536: /* HRLEM */ + case 0537: /* HRLES */ AD = ((AR & SMASK) != 0) ? RMASK : 0; AR = (AR & LMASK) | AD; break; - case 0540: /* HRR */ - case 0541: /* HRRI */ - case 0542: /* HRRM */ - case 0543: /* HRRS */ - case 0544: /* HLR */ - case 0545: /* HLRI */ - case 0546: /* HLRM */ - case 0547: /* HLRS */ + case 0507: /* HRLS */ + BR = SWAP_AR; + /* Fall Through */ + + case 0540: /* HRR */ + case 0541: /* HRRI */ + case 0542: /* HRRM */ + case 0544: /* HLR */ + case 0545: /* HLRI */ + case 0546: /* HLRM */ AR = (BR & LMASK) | (AR & RMASK); break; - case 0550: /* HRRZ */ - case 0551: /* HRRZI */ - case 0552: /* HRRZM */ - case 0553: /* HRRZS */ - case 0554: /* HLRZ */ - case 0555: /* HLRZI */ - case 0556: /* HLRZM */ - case 0557: /* HLRZS */ + case 0550: /* HRRZ */ + case 0551: /* HRRZI */ + case 0552: /* HRRZM */ + case 0553: /* HRRZS */ + case 0554: /* HLRZ */ + case 0555: /* HLRZI */ + case 0556: /* HLRZM */ + case 0557: /* HLRZS */ AR = (AR & RMASK); break; - case 0560: /* HRRO */ - case 0561: /* HRROI */ - case 0562: /* HRROM */ - case 0563: /* HRROS */ - case 0564: /* HLRO */ - case 0565: /* HLROI */ - case 0566: /* HLROM */ - case 0567: /* HLROS */ + case 0560: /* HRRO */ + case 0561: /* HRROI */ + case 0562: /* HRROM */ + case 0563: /* HRROS */ + case 0564: /* HLRO */ + case 0565: /* HLROI */ + case 0566: /* HLROM */ + case 0567: /* HLROS */ AR = LMASK | (AR & RMASK); break; - case 0570: /* HRRE */ - case 0571: /* HRREI */ - case 0572: /* HRREM */ - case 0573: /* HRRES */ - case 0574: /* HLRE */ - case 0575: /* HLREI */ - case 0576: /* HLREM */ - case 0577: /* HLRES */ + case 0570: /* HRRE */ + case 0571: /* HRREI */ + case 0572: /* HRREM */ + case 0573: /* HRRES */ + case 0574: /* HLRE */ + case 0575: /* HLREI */ + case 0576: /* HLREM */ + case 0577: /* HLRES */ AD = ((AR & RSIGN) != 0) ? LMASK: 0; AR = AD | (AR & RMASK); break; - case 0600: /* TxN */ - case 0601: /* TxN */ - case 0602: /* TxN */ - case 0603: /* TxN */ - case 0604: /* TxN */ - case 0605: /* TxN */ - case 0606: /* TxN */ - case 0607: /* TxN */ - case 0610: - case 0611: - case 0612: - case 0613: - case 0614: - case 0615: - case 0616: - case 0617: + case 0600: /* TRN */ + case 0601: /* TLN */ + case 0602: /* TRNE */ + case 0603: /* TLNE */ + case 0604: /* TRNA */ + case 0605: /* TLNA */ + case 0606: /* TRNN */ + case 0607: /* TLNN */ + case 0610: /* TDN */ + case 0611: /* TSN */ + case 0612: /* TDNE */ + case 0613: /* TSNE */ + case 0614: /* TDNA */ + case 0615: /* TSNA */ + case 0616: /* TDNN */ + case 0617: /* TSNN */ MQ = AR; /* N */ goto test_op; - case 0620: /* TxZ */ - case 0621: /* TxZ */ - case 0622: /* TxZ */ - case 0623: /* TxZ */ - case 0624: /* TxZ */ - case 0625: /* TxZ */ - case 0626: /* TxZ */ - case 0627: /* TxZ */ - case 0630: - case 0631: - case 0632: - case 0633: - case 0634: - case 0635: - case 0636: - case 0637: + case 0620: /* TRZ */ + case 0621: /* TLZ */ + case 0622: /* TRZE */ + case 0623: /* TLZE */ + case 0624: /* TRZA */ + case 0625: /* TLZA */ + case 0626: /* TRZN */ + case 0627: /* TLZN */ + case 0630: /* TDZ */ + case 0631: /* TSZ */ + case 0632: /* TDZE */ + case 0633: /* TSZE */ + case 0634: /* TDZA */ + case 0635: /* TSZA */ + case 0636: /* TDZN */ + case 0637: /* TSZN */ MQ = CM(AR) & BR; /* Z */ goto test_op; - case 0640: /* TxC */ - case 0641: /* TxC */ - case 0642: /* TxC */ - case 0643: /* TxC */ - case 0644: /* TxC */ - case 0645: /* TxC */ - case 0646: /* TxC */ - case 0647: /* TxC */ - case 0650: - case 0651: - case 0652: - case 0653: - case 0654: - case 0655: - case 0656: - case 0657: + case 0640: /* TRC */ + case 0641: /* TLC */ + case 0642: /* TRCE */ + case 0643: /* TLCE */ + case 0644: /* TRCA */ + case 0645: /* TLCA */ + case 0646: /* TRCN */ + case 0647: /* TLCN */ + case 0650: /* TDC */ + case 0651: /* TSC */ + case 0652: /* TDCE */ + case 0653: /* TSCE */ + case 0654: /* TDCA */ + case 0655: /* TSCA */ + case 0656: /* TDCN */ + case 0657: /* TSCN */ MQ = AR ^ BR; /* C */ goto test_op; - case 0660: /* TxO */ - case 0661: /* TxO */ - case 0662: /* TxO */ - case 0663: /* TxO */ - case 0664: /* TxO */ - case 0665: /* TxO */ - case 0666: /* TxO */ - case 0667: /* TxO */ - case 0670: - case 0671: - case 0672: - case 0673: - case 0674: - case 0675: - case 0676: - case 0677: + case 0660: /* TRO */ + case 0661: /* TLO */ + case 0662: /* TROE */ + case 0663: /* TLOE */ + case 0664: /* TROA */ + case 0665: /* TLOA */ + case 0666: /* TRON */ + case 0667: /* TLON */ + case 0670: /* TDO */ + case 0671: /* TSO */ + case 0672: /* TDOE */ + case 0673: /* TSOE */ + case 0674: /* TDOA */ + case 0675: /* TSOA */ + case 0676: /* TDON */ + case 0677: /* TSON */ MQ = AR | BR; /* O */ test_op: AR &= BR; @@ -3853,8 +4391,8 @@ test_op: 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))) { + if (!pi_cycle && ((((FLAGS & (USER|USERIO)) == USER) && (IR & 040) == 0) + || ((FLAGS & (USER|PUBLIC)) == PUBLIC))) { #else if ((FLAGS & (USER|USERIO)) == USER && !pi_cycle) { @@ -3863,39 +4401,38 @@ test_op: goto muuo; } else { int d = ((IR & 077) << 1) | ((AC & 010) != 0); +fetch_opr: switch(AC & 07) { case 0: /* 00 BLKI */ case 2: /* 10 BLKO */ - if (Mem_read(pi_cycle, 0)) - break; + if (Mem_read(pi_cycle, 0, 0)) + goto last; AR = MB; if (hst_lnt) { hst[hst_p].mb = AR; } AC |= 1; /* Make into DATAI/DATAO */ - f_load_pc = 0; - f_inst_fetch = 0; AR = AOB(AR); - if (AR & C1) { - pi_ov = f_pc_inh = 1; - } else if (!pi_cycle) { + if (AR & C1) + pi_ov = 1; + else if (!pi_cycle) PC = (PC + 1) & RMASK; - } AR &= FMASK; MB = AR; if (Mem_write(pi_cycle, 0)) - break; + goto last; AB = AR & RMASK; goto fetch_opr; - break; + case 1: /* 04 DATAI */ dev_tab[d](DATAI|(d<<2), &AR); MB = AR; - Mem_write(pi_cycle, 0); + if (Mem_write(pi_cycle, 0)) + goto last; break; case 3: /* 14 DATAO */ - if (Mem_read(pi_cycle, 0)) - break; + if (Mem_read(pi_cycle, 0, 0)) + goto last; AR = MB; dev_tab[d](DATAO|(d<<2), &AR); break; @@ -3905,7 +4442,8 @@ test_op: case 5: /* 24 CONI */ dev_tab[d](CONI|(d<<2), &AR); MB = AR; - Mem_write(pi_cycle, 0); + if (Mem_write(pi_cycle, 0)) + goto last; break; case 6: /* 30 CONSZ */ dev_tab[d](CONI|(d<<2), &AR); @@ -3924,26 +4462,39 @@ test_op: break; } + AR &= FMASK; if (!sac_inh && (i_flags & (SCE|FCEPSE))) { MB = AR; - if (Mem_write(0, 0)) + if (Mem_write(0, 0)) { goto last; + } } if (!sac_inh && ((i_flags & SAC) || ((i_flags & SACZ) && AC != 0))) - set_reg(AC, AR, 1); /* blank, I, B */ + set_reg(AC, AR); /* blank, I, B */ - if (!sac_inh && (i_flags & SAC2)) - set_reg(AC+1, MQ, 1); + if (!sac_inh && (i_flags & SAC2)) { + MQ &= FMASK; + set_reg(AC+1, MQ); + } if (hst_lnt) { hst[hst_p].fmb = AR; } last: +#if BBN + if ((cpu_unit.flags & UNIT_BBNPAGE) && page_fault) { + page_fault = 0; + AB = 070; + f_pc_inh = 1; + pi_cycle = 1; + goto fetch; + } +#endif #if KI | KL /* Handle page fault and traps */ - if (page_enable && (page_fault || private_page)) { - page_fault = private_page = 0; + if (page_enable && page_fault) { + page_fault = 0; AB = ub_ptr + ((FLAGS & USER) ? 0427 : 0426); MB = fault_data; Mem_write_nopage(); @@ -3957,16 +4508,16 @@ last: goto no_fetch; } #endif + if (!f_pc_inh && !pi_cycle) { PC = (PC + 1) & RMASK; } - /* Dismiss an interrupt */ if (pi_cycle) { #if KI | KL - if (page_enable && (page_fault || private_page)) { - page_fault = private_page = 0; + if (page_enable && page_fault) { + page_fault = 0; inout_fail = 1; } #endif @@ -3983,10 +4534,10 @@ last: #if KI | KL AB |= eb_ptr; Mem_read_nopage(); - goto no_fetch; #else - goto fetch; + Mem_read(1, 0, 1); #endif + goto no_fetch; } } else if (pi_hold) { AB = 040 | (pi_enc << 1) | pi_ov; @@ -3995,10 +4546,10 @@ last: #if KI | KL AB |= eb_ptr; Mem_read_nopage(); - goto no_fetch; #else - goto fetch; + Mem_read(1, 0, 1); #endif + goto no_fetch; } else { f_inst_fetch = 1; f_load_pc = 1; @@ -4135,6 +4686,10 @@ dev_tab[1] = &dev_pi; #if KI | KL dev_tab[2] = &dev_pag; #endif +#if BBN +if (cpu_unit.flags & UNIT_BBNPAGE) + dev_tab[024] = &dev_pag; +#endif for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { dibp = (DIB *) dptr->ctxt; if (dibp && !(dptr->flags & DEV_DIS)) { /* enabled? */ diff --git a/PDP10/ka10_defs.h b/PDP10/ka10_defs.h index 9050582..0c84aac 100644 --- a/PDP10/ka10_defs.h +++ b/PDP10/ka10_defs.h @@ -58,10 +58,16 @@ #define KI_22BIT KI|KL #endif +/* Support for ITS Pager */ #ifndef ITS #define ITS KA #endif +/* Support for TENEX Pager */ +#ifndef BBN +#define BBN KA +#endif + /* Digital Equipment Corporation's 36b family had six implementations: name mips comments @@ -198,6 +204,13 @@ extern DEBTAB crd_debug[]; #define CRY1 002000 /* 100000 */ #define CRY0 004000 /* 200000 */ #define OVR 010000 /* 400000 */ +#ifdef BBN +#define EXJSYS 000040 /* 002000 */ +#endif +#ifdef ITS +#define PURE 000040 /* 002000 */ +#define ONEP 000010 /* 000400 */ +#endif #define DATAI 00 #define DATAO 01 @@ -233,6 +246,21 @@ extern DEBTAB crd_debug[]; #define DEF_SERIAL 514 /* Default dec test machine */ #endif +#if BBN +#define BBN_PAGE 0000017777777LL +#define BBN_TRPPG 0000017000000LL +#define BBN_SPT 0000017777000LL +#define BBN_PN 0000000000777LL +#define BBN_ACC 0000040000000LL +#define BBN_TRP1 0000100000000LL +#define BBN_TRP 0000200000000LL +#define BBN_TRPMOD 0000400000000LL +#define BBN_TRPUSR 0001000000000LL +#define BBN_EXEC 0020000000000LL +#define BBN_WRITE 0040000000000LL +#define BBN_READ 0100000000000LL +#define BBN_MERGE 0161740000000LL +#endif typedef unsigned long long int uint64; typedef unsigned int uint18; diff --git a/PDP10/ka10_dp.c b/PDP10/ka10_dp.c index 8f33dd3..926d487 100644 --- a/PDP10/ka10_dp.c +++ b/PDP10/ka10_dp.c @@ -549,6 +549,7 @@ t_stat dp_svc (UNIT *uptr) uptr->STATUS |= SRC_DONE; if (uptr->STATUS & END_CYL) { uptr->UFLAGS |= DONE; + uptr->STATUS &= ~END_CYL; uptr->STATUS &= ~BUSY; df10_finish_op(df10, 0); return SCPE_OK; @@ -595,7 +596,7 @@ t_stat dp_svc (UNIT *uptr) sect = 0; surf = surf + 1; if (surf >= dp_drv_tab[dtype].surf) { - uptr->STATUS|= END_CYL; + uptr->STATUS |= END_CYL; } else { uptr->UFLAGS &= ~(01757000); uptr->UFLAGS |= (surf << 14); diff --git a/PDP10/ka10_sys.c b/PDP10/ka10_sys.c index f014726..27dbd81 100644 --- a/PDP10/ka10_sys.c +++ b/PDP10/ka10_sys.c @@ -493,7 +493,7 @@ static const char *opcode[] = { "JFOV", "JCRY1", "JCRY0", "JCRY", "JOV", - "LUUO01", "LUUO02", "LUUO03", "LUUO04", "LUUO05", "LUUO06", "LUUO07", +"LUUO00", "LUUO01", "LUUO02", "LUUO03", "LUUO04", "LUUO05", "LUUO06", "LUUO07", "LUUO10", "LUUO11", "LUUO12", "LUUO13", "LUUO14", "LUUO15", "LUUO16", "LUUO17", "LUUO20", "LUUO21", "LUUO22", "LUUO23", "LUUO24", "LUUO25", "LUUO26", "LUUO27", "LUUO30", "LUUO31", "LUUO32", "LUUO33", "LUUO34", "LUUO35", "LUUO36", "LUUO37", @@ -571,7 +571,7 @@ static const t_int64 opc_val[] = { 0255400000000+I_OP, - 0001000000000+I_AC, 0002000000000+I_AC, 0003000000000+I_AC, + 0000000000000+I_AC, 0001000000000+I_AC, 0002000000000+I_AC, 0003000000000+I_AC, 0004000000000+I_AC, 0005000000000+I_AC, 0006000000000+I_AC, 0007000000000+I_AC, 0010000000000+I_AC, 0011000000000+I_AC, 0012000000000+I_AC, 0013000000000+I_AC, 0014000000000+I_AC, 0015000000000+I_AC, 0016000000000+I_AC, 0017000000000+I_AC,