From a683b42e3c797d877f01339651ff3fceca254255 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 22 Jan 2017 23:07:37 -0500 Subject: [PATCH] KA10: Updated CPU to support KI10 TLB, Start of ITS support. --- PDP10/ka10_cpu.c | 385 ++++++++++++++++++++++++++++++---------------- PDP10/ka10_cty.c | 3 +- PDP10/ka10_defs.h | 19 ++- PDP10/ka10_df.c | 1 + PDP10/ka10_mt.c | 5 +- PDP10/ka10_sys.c | 2 + 6 files changed, 272 insertions(+), 143 deletions(-) diff --git a/PDP10/ka10_cpu.c b/PDP10/ka10_cpu.c index 5a119bb..856f918 100644 --- a/PDP10/ka10_cpu.c +++ b/PDP10/ka10_cpu.c @@ -23,13 +23,13 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Richard Cornwell - cpu KA10 central processor + cpu KA10/KL10 central processor The 36b system family had six different implementions: PDP-6, KA10, KI10, - L10, KL10 extended, and KS10. + KL10, KL10 extended, and KS10. - The register state for the KI10 is: + The register state for the KA10 is: AC[16] accumulators PC program counter @@ -112,6 +112,7 @@ #endif #define UNIT_V_TWOSEG (UNIT_V_MSIZE + 8) #define UNIT_TWOSEG (1 << UNIT_V_TWOSEG) +#define UNIT_ITSPAGE (2 << UNIT_V_TWOSEG) uint64 M[MAXMEMSIZE]; /* Memory */ @@ -169,21 +170,30 @@ uint64 ADX; /* Extension to AD */ uint32 ub_ptr; /* User base pointer */ uint32 eb_ptr; /* Executive base pointer */ uint8 fm_sel; /* User fast memory block */ -char small_user; /* Small user flag */ -char user_addr_cmp; /* User address compare flag */ -char page_enable; /* Enable paging */ -char page_fault; /* Page fail */ -char xct_flag; /* XCT flags */ -uint32 ac_stack; /* Register stack pointer */ -uint32 pag_reload; /* Page reload pointer */ +int32 apr_serial = -1; /* CPU Serial number */ char inout_fail; /* In out fail flag */ int modify; /* Modify cycle */ 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 +uint32 e_tlb[512]; /* Executive TLB */ +uint32 u_tlb[546]; /* User TLB */ +char page_enable; /* Enable paging */ +char page_fault; /* Page fail */ +uint32 ac_stack; /* Register stack pointer */ +uint32 pag_reload; /* Page reload pointer */ uint64 fault_data; /* Fault data from last fault */ -int32 apr_serial = -1; /* CPU Serial number */ int trap_flag; /* Last instruction was trapped */ int last_page; /* Last page mapped */ +char xct_flag; /* XCT flags */ +#endif +#if ITS +uint32 dbr1; /* User Low Page Table Address */ +uint32 dbr2; /* User High Page Table Address */ +uint32 dbr3; /* Exec High Page Table Address */ #endif char dev_irq[128]; /* Pending irq by device */ @@ -277,11 +287,17 @@ MTAB cpu_mod[] = { #endif #if KI { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "SERIAL", "SERIAL", - &cpu_set_serial, &cpu_show_serial }, + &cpu_set_serial, &cpu_show_serial, NULL, "CPU Serial Number" }, #endif #if !KI - { UNIT_TWOSEG, 0, "ONESEG", "ONESEG", NULL, NULL, NULL}, - { UNIT_TWOSEG, UNIT_TWOSEG, "TWOSEG", "TWOSEG", NULL, NULL, NULL}, + { UNIT_ITSPAGE|UNIT_TWOSEG, 0, "ONESEG", "ONESEG", NULL, NULL, NULL, + "One Relocation Register"}, + { UNIT_ITSPAGE|UNIT_TWOSEG, UNIT_TWOSEG, "TWOSEG", "TWOSEG", NULL, NULL, + NULL, "Two Relocation Registers"}, +#if ITS + { UNIT_ITSPAGE|UNIT_TWOSEG, UNIT_ITSPAGE, "ITS", "ITS", NULL, NULL, NULL, + "Paging hardware for ITS"}, +#endif #endif { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", &cpu_set_hist, &cpu_show_hist }, @@ -356,17 +372,6 @@ int opflags[] = { 0, 0, 0, 0, /* JSYS */ /* ADJSP */ /* GFMP */ /*GFDV */ 0, 0, 0, 0, -#if KI - /* DFAD */ /* DFSB */ /* DFMP */ /* DFDV */ - FCE|FAC|FAC2|SAC|SAC2, FCE|FAC|FAC2|SAC|SAC2, - FCE|FAC|FAC2|SAC|SAC2, FCE|FAC|FAC2|SAC|SAC2, - /* DADD */ /* DSUB */ /* DMUL */ /* DDIV */ - 0, 0, 0, 0, - /* DMOVE */ /* DMOVN */ /* FIX */ /* EXTEND */ - FCE|SAC|SAC2, FCE|SAC|SAC2, FCE|SAC, 0, - /* DMOVEM */ /* DMOVNM */ /* FIXR */ /* FLTR */ - FAC|FAC2, FAC|FAC2, FCE|SAC, FCE|SAC, -#else /* DFAD */ /* DFSB */ /* DFMP */ /* DFDV */ 0, 0, 0, 0, /* DADD */ /* DSUB */ /* DMUL */ /* DDIV */ @@ -375,7 +380,6 @@ int opflags[] = { 0, 0, 0, 0, /* DMOVEM */ /* DMOVNM */ /* FIXR */ /* FLTR */ 0, 0, 0, 0, -#endif /* UFA */ /* DFN */ /* FSC */ /* IBP */ FCE|FBR, FCE|FAC|SAC, FAC|SAC, 0, /* ILDB */ /* LDB */ /* IDPB */ /* DPB */ @@ -413,7 +417,8 @@ int opflags[] = { SAC2|SAC|FCE|FAC, SAC2|SAC|FAC, FCEPSE|FAC, SAC2|SAC|FCEPSE|FAC, /* DIV */ /* DIVI */ /* DIVM */ /* DIVB */ SAC2|SAC|FCE|FAC|FAC2, SAC2|SAC|FAC|FAC2, - FCEPSE|FAC|FAC2, SAC2|SAC|FCEPSE|FAC|FAC2, + FCEPSE|FAC|FAC2, SAC2|SAC|FCEPSE|FAC\ + |FAC2, /* ASH */ /* ROT */ /* LSH */ /* JFFO */ FAC|SAC, FAC|SAC, FAC|SAC, FAC, /* ASHC */ /* ROTC */ /* LSHC */ /* UUO247 */ @@ -422,11 +427,7 @@ int opflags[] = { /* EXCH */ /* BLT */ /* AOBJP */ /* AOBJN */ FAC|FCEPSE, FAC, FAC|SAC, FAC|SAC, /* JRST */ /* JFCL */ /* XCT */ /* MAP */ -#if KI - 0, 0, 0, SAC, -#else 0, 0, 0, 0, -#endif /* PUSHJ */ /* PUSH */ /* POP */ /* POPJ */ FAC|SAC, FAC|FCE|SAC, FAC|SAC, FAC|SAC, /* JSR */ /* JSP */ /* JSA */ /* JRA */ @@ -505,35 +506,43 @@ int opflags[] = { /* HLL */ /* HLLI */ /* HLLM */ /* HLLS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|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, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HLLZ */ /* HLLZI */ /* HLLZM */ /* HLLZS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HRLZ */ /* HRLZI */ /* HRLZM */ /* HRLZS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HLLO */ /* HLLOI */ /* HLLOM */ /* HLLOS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HRLO */ /* HRLOI */ /* HRLOM */ /* HRLOS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HLLE */ /* HLLEI */ /* HLLEM */ /* HLLES */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HRLE */ /* HRLEI */ /* HRLEM */ /* HRLES */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HRR */ /* HRRI */ /* HRRM */ /* HRRS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|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, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HRRZ */ /* HRRZI */ /* HRRZM */ /* HRRZS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HLRZ */ /* HLRZI */ /* HLRZM */ /* HLRZS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HRRO */ /* HRROI */ /* HRROM */ /* HRROS */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HLRO */ /* HLROI */ /* HLROM */ /* HLROS */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* HRRE */ /* HRREI */ /* HRREM */ /* HRRES */ FBR|SAC|FCE, FBR|SAC, FAC|FMB|FCEPSE, FMB|SACZ|FCEPSE, /* HLRE */ /* HLREI */ /* HLREM */ /* HLRES */ - SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, SWAR|FMB|SACZ|FCEPSE, + SWAR|FBR|SAC|FCE, SWAR|FBR|SAC, SWAR|FAC|FMB|FCEPSE, + SWAR|FMB|SACZ|FCEPSE, /* TRN */ /* TLN */ /* TRNE */ /* TLNE */ FBR, FBR|SWAR, FBR, FBR|SWAR, @@ -600,7 +609,7 @@ int opflags[] = { /* * Set device to interrupt on a given level 1-7 - * Level 0 means that device interrupt is not enabled + * Level 0 means that device interrupt is not enabled */ void set_interrupt(int dev, int lvl) { lvl &= 07; @@ -630,7 +639,7 @@ int check_irq_level() { /* Scan all devices */ for(i = lvl = 0; i < 128; i++) lvl |= dev_irq[i]; - if (lvl == 0) + if (lvl == 0) pi_pending = 0; PIR |= (lvl & PIE); /* Handle held interrupt requests */ @@ -664,7 +673,7 @@ int check_irq_level() { return 0; } -/* +/* * Recover from held interrupt. */ void restore_pi_hold() { @@ -697,11 +706,12 @@ void set_pi_hold() { #if KI static int timer_irq, timer_flg; -/* +/* * Page device for KI10. */ t_stat dev_pag(uint32 dev, uint64 *data) { uint64 res = 0; + int i; switch(dev & 03) { case CONI: /* Complement of vpn */ @@ -720,19 +730,27 @@ t_stat dev_pag(uint32 dev, uint64 *data) { case DATAO: res = *data; - if (res & LSIGN) { + if (res & RSIGN) { eb_ptr = (res & 017777) << 9; + for (i = 0; i < 512; i++) + e_tlb[i] = u_tlb[i] = 0; + for (;i < 546; i++) + u_tlb[i] = 0; page_enable = (res & 020000) != 0; } if (res & SMASK) { ub_ptr = ((res >> 18) & 017777) << 9; + for (i = 0; i < 512; i++) + e_tlb[i] = u_tlb[i] = 0; + for (;i < 546; i++) + u_tlb[i] = 0; user_addr_cmp = (res & 00020000000000LL) != 0; small_user = (res & 00040000000000LL) != 0; fm_sel = (uint8)(res >> 29) & 060; } pag_reload = 0; - sim_debug(DEBUG_DATAIO, &cpu_dev, - "DATAO PAG %012llo ebr=%06o ubr=%06o\n", + sim_debug(DEBUG_DATAIO, &cpu_dev, + "DATAO PAG %012llo ebr=%06o ubr=%06o\n", *data, eb_ptr, ub_ptr); break; @@ -769,7 +787,7 @@ void check_apr_irq() { } -/* +/* * APR device for KI10. */ t_stat dev_apr(uint32 dev, uint64 *data) { @@ -880,7 +898,7 @@ t_stat dev_apr(uint32 dev, uint64 *data) { fov_irq = 1; if (res & 0400) fov_irq = 0; - if (res & 01000) + if (res & 01000) clk_flg = 0; if (res & 02000) clk_en = 1; @@ -992,12 +1010,12 @@ t_stat null_dev(uint32 dev, uint64 *data) { } #if KI -/* +/* * Handle page lookup on KI10 */ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { uint64 data; - int base = ub_ptr; + int base = 0; int page = (RMASK & addr) >> 9; int uf = (FLAGS & USER) != 0; @@ -1011,14 +1029,14 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { } /* If fetching byte data, use write access */ - if (BYF5 && (IR & 06) == 6) + if (BYF5 && (IR & 06) == 6) wr = 1; /* If this is modify instruction use write access */ wr |= modify; /* Figure out if this is a user space access */ - if (flag) + if (flag) uf = 0; else if (xct_flag != 0 && !cur_context && !uf) { if (((xct_flag & 2) != 0 && wr != 0) || @@ -1032,7 +1050,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { if (small_user && (page & 0340) != 0) { fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 020LL; page_fault = 1; - fprintf(stderr, " %03o small fault\n\r", page); + // fprintf(stderr, " %03o small fault\n\r", page); return 0; } } else { @@ -1042,7 +1060,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { page += 01000 - 0340; /* Pages 400-777 via EBR */ } else if (page & 0400) { - base = eb_ptr; + base = 1; /* Pages 000-037 direct map */ } else { /* Check if supervisory mode */ @@ -1050,18 +1068,37 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { /* Handle public violation */ fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL; private_page = 1; - fprintf(stderr, " public"); + // fprintf(stderr, " public"); } *loc = addr; return 1; } } /* Map the page */ - data = M[base + (page >> 1)]; + if (base) { + data = e_tlb[page]; + if (data == 0) { + data = M[eb_ptr + (page >> 1)]; + e_tlb[page & 0776] = RMASK & (data >> 18); + e_tlb[page | 1] = RMASK & data; + data = e_tlb[page]; + pag_reload = ((pag_reload + 1) & 037) | 040; + } + } else { + data = u_tlb[page]; + if (data == 0) { + data = M[ub_ptr + (page >> 1)]; + u_tlb[page & 01776] = RMASK & (data >> 18); + u_tlb[page | 1] = RMASK & data; + data = u_tlb[page]; + pag_reload = ((pag_reload + 1) & 037) | 040; + } + } +// data = M[base + (page >> 1)]; /* Even in left half, Odd in right half. */ - if ((page & 1) == 0) - data >>= 18; - data &= RMASK; + // if ((page & 1) == 0) + // data >>= 18; + // data &= RMASK; *loc = ((data & 017777) << 9) + (addr & 0777); /* Access check logic */ if (!flag && ((FLAGS & PUBLIC) != 0) && ((data & 0200000) == 0)) { @@ -1071,8 +1108,8 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { } if (cur_context && ((data & 0200000) != 0)) FLAGS |= PUBLIC; - if ((data & LSIGN) == 0 || (wr & ((data & 0100000) == 0))) { - fault_data = ((((uint64)(addr))<<9) | ((uint64)(uf) << 27)) & LMASK; + if ((data & RSIGN) == 0 || (wr & ((data & 0100000) == 0))) { + fault_data = ((((uint64)(addr))<<9) | ((uint64)(uf) << 27)) & LMASK; fault_data |= (data & 0400000) ? 010LL : 0LL; /* A */ fault_data |= (data & 0100000) ? 004LL : 0LL; /* W */ fault_data |= (data & 0040000) ? 002LL : 0LL; /* S */ @@ -1084,8 +1121,8 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { fprintf(stderr, " fault\n\r"); return 0; } -// fprintf(stderr, "xlat %06o %03o %06o %o", addr, page >> 1, *loc, uf); -// fprintf(stderr, " PC=%06o\n\r", PC); +// fprintf(stderr, "xlat %06o %03o %06o %012llo -> %o %o", addr, page >> 1, base, data, *loc, uf); + // fprintf(stderr, "%06o %06o PC=%06o\n\r", eb_ptr, ub_ptr, PC); return 1; } @@ -1093,16 +1130,16 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { * Register access on KI 10 */ uint64 get_reg(int reg) { - if (FLAGS & USER) + if (FLAGS & USER) return FM[fm_sel|(reg & 017)]; - else + else return FM[reg & 017]; } void set_reg(int reg, uint64 value) { - if (FLAGS & USER) + if (FLAGS & USER) FM[fm_sel|(reg & 017)] = value; - else + else FM[reg & 017] = value; } @@ -1193,7 +1230,7 @@ int Mem_read(int flag, int cur_context) { } else { if (!cur_context && ((xct_flag & 1) != 0)) { if (FLAGS & USERIO) { - if (fm_sel == 0) + if (fm_sel == 0) goto read; MB = FM[fm_sel|AB]; return 0; @@ -1235,11 +1272,11 @@ int Mem_write(int flag, int cur_context) { set_reg(AB, MB); return 0; } else { - if (!cur_context && + if (!cur_context && (((xct_flag & 1) != 0 && modify) || (xct_flag & 2) != 0)) { if (FLAGS & USERIO) { - if (fm_sel == 0) + if (fm_sel == 0) goto write; else FM[fm_sel|AB] = MB; @@ -1391,7 +1428,7 @@ no_fetch: /* Handle indirection repeat until no longer indirect */ do { - if (pi_enable & !pi_cycle & pi_pending + if (pi_enable & !pi_cycle & pi_pending #if KI | KL & !trap_flag #endif @@ -1408,7 +1445,7 @@ no_fetch: 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)) goto last; /* Handle events during a indirect loop */ if (sim_interval-- <= 0) { @@ -1458,22 +1495,20 @@ no_fetch: /* Update history */ #if KI -// if (hst_lnt && PC > 020 && (FLAGS & USER) != 0) { - if (hst_lnt && (fm_sel || PC > 020) && (PC & 0777774) != 0777040 && + if (hst_lnt && (fm_sel || PC > 020) && (PC & 0777774) != 0777040 && (PC & 0777700) != 023700 && (PC != 0527154)) { #else - if (hst_lnt && PC > 020 && (PC & 0777774) != 0472174 && + if (hst_lnt && PC > 020 && (PC & 0777774) != 0472174 && (PC & 0777700) != 023700 && (PC != 0527154)) { #endif hst_p = hst_p + 1; if (hst_p >= hst_lnt) { hst_p = 0; -// reason = STOP_IBKPT; } hst[hst_p].pc = HIST_PC | ((BYF5)? (HIST_PC2|PC) : IA); hst[hst_p].ea = AB; hst[hst_p].ir = AD; - hst[hst_p].flags = (FLAGS << 5) |(clk_flg << 2) | (nxm_flag << 1) + hst[hst_p].flags = (FLAGS << 5) |(clk_flg << 2) | (nxm_flag << 1) #if KA | (mem_prot << 4) | (push_ovf << 3) #endif @@ -1536,7 +1571,7 @@ fetch_opr: switch (IR) { muuo: case 0000: /* UUO */ - case 0040: case 0041: case 0042: case 0043: + case 0040: case 0041: case 0042: case 0043: case 0044: case 0045: case 0046: case 0047: case 0050: case 0051: case 0052: case 0053: case 0054: case 0055: case 0056: case 0057: @@ -1550,9 +1585,9 @@ muuo: #if KI | KL case 0100: case 0101: case 0102: case 0103: case 0104: case 0105: case 0106: case 0107: - case 0123: + case 0123: case 0247: /* UUO */ -unasign: +unasign: MB = ((uint64)(IR) << 27) | ((uint64)(AC) << 23) | (uint64)(AB); AB = ub_ptr | 0424; Mem_write_nopage(); @@ -1561,7 +1596,7 @@ unasign: Mem_write_nopage(); FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); AB = ub_ptr | 0430; - if (trap_flag != 0) + if (trap_flag != 0) AB |= 1; if (FLAGS & PUBLIC) AB |= 2; @@ -1572,7 +1607,7 @@ unasign: /* If transistioning from user to executive adjust flags */ if ((FLAGS & USER) != 0 && (AB & 4) != 0) { FLAGS |= USERIO; - if (AB & 2) + if (AB & 2) FLAGS |= OVR; } PC = MB & RMASK; @@ -1611,12 +1646,19 @@ unasign: break; #if KI | KL - case 0110: /* DFAD */ case 0111: /* DFSB */ /* On Load AR,MQ has memory operand */ /* AR,MQ = AC BR,MB = mem */ /* AR High */ + if (Mem_read(0, 0)) + goto last; + modify = 1; + AR = MB; + BR = AR; + AR = get_reg(AC); + MQ = get_reg(AC + 1); + AB = (AB + 1) & RMASK; if (Mem_read(0, 0)) goto last; @@ -1697,12 +1739,21 @@ dpnorm: AR |= ((uint64)(SCAD & 0377)) << 27; MQ = ARX; + 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)) + goto last; + modify = 1; + AR = MB; + BR = AR; + AR = get_reg(AC); + MQ = get_reg(AC + 1); AB = (AB + 1) & RMASK; if (Mem_read(0, 0)) goto last; @@ -1740,6 +1791,13 @@ dpnorm: /* On Load AR,MQ has memory operand */ /* AR,MQ = AC BR,MB = mem */ /* AR High */ + if (Mem_read(0, 0)) + goto last; + modify = 1; + AR = MB; + BR = AR; + AR = get_reg(AC); + MQ = get_reg(AC + 1); AB = (AB + 1) & RMASK; if (Mem_read(0, 0)) goto last; @@ -1798,14 +1856,22 @@ dpnorm: goto unasign; case 0120: /* DMOVE */ + if (Mem_read(0, 0)) + goto last; + AR = MB; AB = (AB + 1) & RMASK; modify = 0; if (Mem_read(0, 0)) goto last; MQ = MB; + set_reg(AC, AR); + set_reg(AC+1, MQ); break; case 0121: /* DMOVN */ + if (Mem_read(0, 0)) + goto last; + AR = MB; AB = (AB + 1) & RMASK; modify = 0; if (Mem_read(0, 0)) @@ -1814,9 +1880,13 @@ dpnorm: /* High */ AR = (CM(AR) + ((MQ & SMASK) != 0)) & FMASK; MQ &= CMASK; + set_reg(AC, AR); + set_reg(AC+1, MQ); break; case 0124: /* DMOVEM */ + AR = get_reg(AC); + MQ = get_reg(AC + 1); /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { MB = AR; @@ -1838,6 +1908,8 @@ dpnorm: break; case 0125: /* DMOVNM */ + AR = get_reg(AC); + MQ = get_reg(AC + 1); /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { BR = AR = CM(AR); @@ -1867,6 +1939,9 @@ dpnorm: case 0122: /* FIX */ case 0126: /* FIXR */ + if (Mem_read(0, 0)) + goto last; + AR = MB; MQ = 0; SC = ((((AR & SMASK) ? 0377 : 0 ) ^ ((AR >> 27) & 0377)) + 0600) & 0777; @@ -1892,15 +1967,20 @@ dpnorm: if ((IR & 04) && (MQ & SMASK) != 0) AR ++; } else { - if (!pi_cycle) + if (!pi_cycle) FLAGS |= OVR|TRP1; /* OV & T1 */ sac_inh = 1; } if (flag1) AR = (CM(AR) + 1) & FMASK; + if (!sac_inh) + set_reg(AC, AR); break; case 0127: /* FLTR */ + if (Mem_read(0, 0)) + goto last; + AR = MB; if (AR & SMASK) { flag1 = 1; AR = (CM(AR) + 1) & CMASK; @@ -1908,11 +1988,43 @@ dpnorm: flag1 = 0; AR <<= 19; SC = 163; + i_flags = SAC; goto fnorm; #else /* MUUO */ - case 0100: case 0101: case 0102: case 0103: - case 0104: case 0105: case 0106: case 0107: + case 0102: /* ITS LPM */ +#if ITS + if ((FLAGS & USER) == 0 && cpu_unit.flags & UNIT_ITSPAGE) { + /* Load store ITS pager info */ + /* AC & 1 = Store */ + /* AC & 2 = Clear TLB */ + /* AC & 4 = Set Prot Interrupt */ + if (AC & 4) { + mem_prot = 1; + set_interrupt(0, apr_irq); + } + break; + } + goto unasign; +#endif + + case 0103: /* ITS XCTR */ +#if ITS + if (cpu_unit.flags & UNIT_ITSPAGE) { + /* AC & 1 = ??? */ + /* AC & 2 = Read User */ + /* AC & 4 = Write User */ + /* AC & 8 = Inhibit mem protect, skip */ + f_load_pc = 0; + f_pc_inh = 1; + if ((FLAGS & USER) == 0) + xct_flag = AC; + break; + } +#endif + + case 0100: case 0101: + case 0104: 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: @@ -1936,7 +2048,7 @@ unasign: #if KI | KL modify = 1; #endif - if (Mem_read(0, 1)) + if (Mem_read(0, 1)) goto last; AR = MB; SC = (AR >> 24) & 077; @@ -1953,7 +2065,7 @@ unasign: AR &= PMASK; AR |= (uint64)(SC & 077) << 30; MB = AR; - if (Mem_write(0, 1)) + if (Mem_write(0, 1)) goto last; if ((IR & 04) == 0) break; @@ -1962,7 +2074,7 @@ unasign: case 0135:/* LDB */ case 0137:/* DPB */ if (((FLAGS & BYTI) == 0) | !BYF5) { - if (Mem_read(0, 1)) + if (Mem_read(0, 1)) goto last; AR = MB; SC = (AR >> 30) & 077; @@ -2020,7 +2132,7 @@ unasign: #endif case 0132:/* FSC */ - SC = ((AB & LSIGN) ? 0400 : 0) | (AB & 0377); + SC = ((AB & RSIGN) ? 0400 : 0) | (AB & 0377); SCAD = GET_EXPO(AR); SC = (SCAD + SC) & 0777; @@ -2245,7 +2357,7 @@ fxnorm: /* Check if we need to fix things */ if (BR >= (AR << 1)) { if (!pi_cycle) - FLAGS |= OVR|NODIV|FLTOVR|TRP1; + FLAGS |= OVR|NODIV|FLTOVR|TRP1; check_apr_irq(); sac_inh = 1; break; /* Done */ @@ -2309,7 +2421,7 @@ fxnorm: BR &= MMASK; /* Check if we need to fix things */ if (BR >= (AR << 1)) { - if (!pi_cycle) + if (!pi_cycle) FLAGS |= OVR|NODIV|FLTOVR|TRP1; check_apr_irq(); sac_inh = 1; @@ -2584,11 +2696,11 @@ fxnorm: /* Shift */ case 0240: /* ASH */ - SC = ((AB & LSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; + SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; if (SC == 0) break; AD = (AR & SMASK) ? FMASK : 0; - if (AB & LSIGN) { + if (AB & RSIGN) { if (SC < 35) AR = ((AR >> SC) | (AD << (36 - SC))) & FMASK; else @@ -2604,24 +2716,24 @@ fxnorm: case 0241: /* ROT */ #if KI | KL - SC = (AB & LSIGN) ? + SC = (AB & RSIGN) ? ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377); #else - SC = ((AB & LSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; + SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; #endif if (SC == 0) break; SC = SC % 36; - if (AB & LSIGN) + if (AB & RSIGN) SC = 36 - SC; AR = ((AR << SC) | (AR >> (36 - SC))) & FMASK; break; case 0242: /* LSH */ - SC = ((AB & LSIGN) ? (0377 ^ AB) + 1 : AB) & 0777; + SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0777; if (SC == 0) break; - if (AB & LSIGN) { + if (AB & RSIGN) { AR = AR >> SC; } else { AR = (AR << SC) & FMASK; @@ -2641,7 +2753,7 @@ fxnorm: break; case 0244: /* ASHC */ - SC = ((AB & LSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; + SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; if (SC == 0) break; if (SC > 70) @@ -2649,7 +2761,7 @@ fxnorm: AD = (AR & SMASK) ? FMASK : 0; AR &= CMASK; MQ &= CMASK; - if (AB & LSIGN) { + if (AB & RSIGN) { if (SC >= 35) { MQ = ((AR >> (SC - 35)) | (AD << (70 - SC))) & FMASK; AR = AD; @@ -2681,15 +2793,15 @@ fxnorm: case 0245: /* ROTC */ #if KI | KL - SC = (AB & LSIGN) ? + SC = (AB & RSIGN) ? ((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377); #else - SC = ((AB & LSIGN) ? (0777 ^ AB) + 1 : AB) & 0777; + SC = ((AB & RSIGN) ? (0777 ^ AB) + 1 : AB) & 0777; #endif if (SC == 0) break; SC = SC % 72; - if (AB & LSIGN) + if (AB & RSIGN) SC = 72 - SC; if (SC >= 36) { AD = MQ; @@ -2703,7 +2815,7 @@ fxnorm: break; case 0246: /* LSHC */ - SC = ((AB & LSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; + SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377; if (SC == 0) break; if (SC > 71) { @@ -2711,7 +2823,7 @@ fxnorm: MQ = 0; } else { if (SC > 36) { - if (AB & LSIGN) { + if (AB & RSIGN) { AR = MQ; MQ = 0; } else { @@ -2720,7 +2832,7 @@ fxnorm: } SC -= 36; } - if (AB & LSIGN) { + if (AB & RSIGN) { MQ = ((MQ >> SC) | (AR << (36 - SC))) & FMASK; AR = AR >> SC; } else { @@ -2795,7 +2907,7 @@ fxnorm: if (AC & 010) { /* Restore interrupt level. */ #if KI | KL if ((FLAGS & (USER|USERIO)) == USER || - (FLAGS & (USER|PUBLIC)) == PUBLIC) { + (FLAGS & (USER|PUBLIC)) == PUBLIC) { #else if ((FLAGS & (USER|USERIO)) == USER) { #endif @@ -2808,7 +2920,7 @@ fxnorm: if (AC & 04) { #if KI | KL if ((FLAGS & (USER|USERIO)) == USER || - (FLAGS & (USER|PUBLIC)) == PUBLIC) { + (FLAGS & (USER|PUBLIC)) == PUBLIC) { #else if ((FLAGS & (USER|USERIO)) == USER) { #endif @@ -2845,10 +2957,11 @@ fxnorm: break; case 0255: /* JFCL */ - if ((FLAGS >> 9) & AC) { + if ((FLAGS >> 9) & AC) PC = AR & RMASK; - f_pc_inh = 1; - } + else + PC = (PC + 1) & RMASK; + f_pc_inh = 1; FLAGS &= 017777 ^ (AC << 9); break; @@ -2864,30 +2977,32 @@ fxnorm: case 0257: /* MAP */ #if KI | KL f = AB >> 9; - last_page = ((f ^ 0777) << 1); + last_page = ((f ^ 0777) << 1); pag_reload &= 037; + /* Check if Paging Enabled */ + if (!page_enable) { + AR = 0020000LL + f; /* direct map */ + set_reg(AC, AR); + break; + } + AR = ub_ptr; if ((FLAGS & USER) != 0) { /* Check if small user and outside range */ if (small_user && (f & 0340) != 0) { AR = 0420000LL; /* Page failure, no match */ + set_reg(AC, AR); break; } - AR = ub_ptr; } else { - if (!page_enable) { - AR = 0020000LL + f; /* direct map */ - break; - } - /* Map executive to use space */ if ((f & 0740) == 0340) { - AR = ub_ptr; f += 01000 - 0340; /* Executive high segment */ } else if (f & 0400) { AR = eb_ptr; } else { AR = 0020000LL + f; /* direct map */ + set_reg(AC, AR); break; } last_page |= 1; @@ -2899,13 +3014,15 @@ fxnorm: AR = MB; if ((f & 1) == 0) AR >>= 18; - if ((AR & LSIGN) == 0) { + if ((AR & RSIGN) == 0) { AR = 0437777LL; /* Return invalid if not accessable */ } else { AR &= 0357777LL; if ((AR & 0100000LL) == 0) - AR |= LSIGN; + AR |= RSIGN; } +fprintf(stderr, "Map %06o %012llo PC=%06o\n\r", f, AR, PC); + set_reg(AC, AR); #endif break; @@ -2920,7 +3037,7 @@ fxnorm: FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2); if (AR & C1) { #if KI | KL - if (!pi_cycle) + if (!pi_cycle) FLAGS |= TRP2; #else push_ovf = 1; @@ -2940,7 +3057,7 @@ fxnorm: AB = AR & RMASK; if (AR & C1) { #if KI | KL - if (!pi_cycle) + if (!pi_cycle) FLAGS |= TRP2; #else push_ovf = 1; @@ -2963,7 +3080,7 @@ fxnorm: goto last; if ((AR & C1) == 0) { #if KI | KL - if (!pi_cycle) + if (!pi_cycle) FLAGS |= TRP2; #else push_ovf = 1; @@ -2981,7 +3098,7 @@ fxnorm: AR = SOB(AR); if ((AR & C1) == 0) { #if KI | KL - if (!pi_cycle) + if (!pi_cycle) FLAGS |= TRP2; #else push_ovf = 1; @@ -3027,7 +3144,7 @@ fxnorm: break; case 0267: /* JRA */ - AD = AB; + AD = AB; AB = (get_reg(AC) >> 18) & RMASK; if (Mem_read(uuo_cycle | pi_cycle, 0)) goto last; @@ -3168,7 +3285,7 @@ fxnorm: check_apr_irq(); } f = ((AD & SMASK) != 0); -jump_op: +jump_op: AD &= FMASK; AR = AD; f |= ((AD == 0) << 1); @@ -3224,7 +3341,7 @@ skip_op: #if KI | KL } else if (pi_cycle) { pi_ov = pi_hold = 1; -#endif +#endif } break; @@ -3427,7 +3544,7 @@ skip_op: case 0575: /* HLREI */ case 0576: /* HLREM */ case 0577: /* HLRES */ - AD = ((AR & LSIGN) != 0) ? LMASK: 0; + AD = ((AR & RSIGN) != 0) ? LMASK: 0; AR = AD | (AR & RMASK); break; @@ -3531,8 +3648,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) { @@ -3604,7 +3721,7 @@ test_op: 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))) @@ -3635,11 +3752,11 @@ last: goto no_fetch; } #endif - if (!f_pc_inh && !pi_cycle) { PC = (PC + 1) & RMASK; } + /* Dismiss an interrupt */ if (pi_cycle) { #if KI | KL diff --git a/PDP10/ka10_cty.c b/PDP10/ka10_cty.c index e44d93a..73754d0 100644 --- a/PDP10/ka10_cty.c +++ b/PDP10/ka10_cty.c @@ -26,6 +26,7 @@ */ #include "ka10_defs.h" +#if PDP6 | KA | KI #define UNIT_DUMMY (1 << UNIT_V_UF) extern int32 tmxr_poll; @@ -204,4 +205,4 @@ const char *cty_description (DEVICE *dptr) { return "Console TTY Line"; } - +#endif diff --git a/PDP10/ka10_defs.h b/PDP10/ka10_defs.h index 74843bd..9fb11c5 100644 --- a/PDP10/ka10_defs.h +++ b/PDP10/ka10_defs.h @@ -58,6 +58,10 @@ #define KI_22BIT KI|KL #endif +#ifndef ITS +#define ITS KA +#endif + /* Digital Equipment Corporation's 36b family had six implementations: name mips comments @@ -123,7 +127,7 @@ extern DEBTAB crd_debug[]; #define CMASK 00377777777777LL #define SMASK 00400000000000LL #define C1 01000000000000LL -#define LSIGN 00000000400000LL +#define RSIGN 00000000400000LL #define PMASK 00007777777777LL #define XMASK 03777777777777LL #define EMASK 00777000000000LL @@ -176,16 +180,16 @@ extern DEBTAB crd_debug[]; #define ADRFLT 000020 /* 001000 */ #define PUBLIC 000040 /* 002000 */ #else -#define TRP1 000000 -#define TRP2 000000 -#define ADRFLT 000000 -#define PUBLIC 000000 +#define TRP1 000000 +#define TRP2 000000 +#define ADRFLT 000000 +#define PUBLIC 000000 #endif #define USERIO 000100 /* 004000 */ #define USER 000200 /* 010000 */ #define BYTI 000400 /* 020000 */ #if PDP6 -#define FLTOVR 000000 +#define FLTOVR 000000 #define PCHNG 001000 /* 040000 */ #else #define FLTOVR 001000 /* 040000 */ @@ -233,7 +237,8 @@ extern DEBTAB crd_debug[]; typedef unsigned long long int uint64; typedef unsigned int uint18; -extern uint64 M[]; +extern uint64 M[]; +extern uint64 FM[]; extern uint18 PC; extern uint32 FLAGS; diff --git a/PDP10/ka10_df.c b/PDP10/ka10_df.c index c302c4e..cb5084d 100644 --- a/PDP10/ka10_df.c +++ b/PDP10/ka10_df.c @@ -45,6 +45,7 @@ void df10_setup(struct df10 *df, uint32 addr) { df->ccw = df->cia; df->wcr = 0; df->status |= BUSY; + df->status &= ~(1 << df->ccw_comp); } int df10_fetch(struct df10 *df) { diff --git a/PDP10/ka10_mt.c b/PDP10/ka10_mt.c index 2f2df24..e59db98 100644 --- a/PDP10/ka10_mt.c +++ b/PDP10/ka10_mt.c @@ -812,7 +812,10 @@ mt_boot(int32 unit_num, DEVICE * dptr) uptr->u6 = 0; } mt_read_word(uptr); - M[addr] = mt_df10.buf; + if (addr < 020) + FM[addr] = mt_df10.buf; + else + M[addr] = mt_df10.buf; } PC = addr; return SCPE_OK; diff --git a/PDP10/ka10_sys.c b/PDP10/ka10_sys.c index 156fb34..09b21b7 100644 --- a/PDP10/ka10_sys.c +++ b/PDP10/ka10_sys.c @@ -59,7 +59,9 @@ int32 sim_emax = 1; DEVICE *sim_devices[] = { &cpu_dev, +#if PDP6 | KA | KI &cty_dev, +#endif #if (NUM_DEVS_PT > 0) &ptp_dev, &ptr_dev,