From 0b2994585c41625d696fa0fc94d4f8986ba9e7d5 Mon Sep 17 00:00:00 2001 From: Jim Date: Fri, 10 Jun 2005 00:00:00 -0400 Subject: [PATCH] changed mem[] to be Prime physical memory array, removed direct references + more work on PCL --- em.c | 306 ++++++++++++++++++++++++++++++++++++++++---------------- emdev.h | 87 +++++++++++----- 2 files changed, 284 insertions(+), 109 deletions(-) diff --git a/em.c b/em.c index cba3fba..7ad0567 100644 --- a/em.c +++ b/em.c @@ -31,9 +31,7 @@ - not all C-bit, L-bit, and condition code updates are correct - - restricted-mode instruction checking is missing, as well as all - restricted-mode instructions and environment (for example, no page - mapping) + - restricted-mode instruction checking is missing */ @@ -223,12 +221,19 @@ unsigned int instcount=0; jmp_buf jmpbuf; -/* mem is 1 user's virtual memory address space in this version, - but eventually should be the system's physical memory -*/ +/* define a 4 million 16-bit word system memory; later systems seem to + have had more memory, like 32MB, but I'm not sure how this was + implemented since it would require more bits in the page map entry + for the physical page number. If the page size was made larger, + like 8K instead of 2K, the number of entries in a page table would + change from 64 to 16, which also seems drastic... */ +#if 0 #define MEMSIZE 07776*64*1024 -unsigned short mem[MEMSIZE]; /* 4095 segments of 64K words each */ +#else +#define MEMSIZE 4*1024*1024 +#endif +unsigned short mem[MEMSIZE]; /* system's physical memory */ unsigned int bitmask32[33] = {0, 0x80000000, 0x40000000, 0x20000000, 0x10000000, @@ -318,7 +323,7 @@ pa_t mapva(ea_t ea, short intacc, short *access) { if (T_MAP) fprintf(stderr,"MAP: ea=%o/%o, seg=%o, dtar=%o, nsegs=%d, relseg=%d, page=%d\n", ea>>16, ea&0xFFFF, seg, dtar, nsegs, relseg, PAGENO(ea)); if (relseg >= nsegs) fault(SEGFAULT, 1, ea); /* fcode = segment too big */ - staddr = (dtar & 0x003F0000) | ((dtar & 0xFFFF)<<1); + staddr = (dtar & 0x003F0000) | ((dtar & 0x7FFF)<<1); sdw = *(unsigned int *)(mem+staddr+relseg*2); if (T_MAP) fprintf(stderr," staddr=%o, sdw=%o\n", staddr, sdw); if (sdw & 0x8000) @@ -344,7 +349,7 @@ pa_t mapva(ea_t ea, short intacc, short *access) { mem[pmaddr] &= ~020000; /* reset unmodified bit */ pa = ((pte & 0xFFF) << 10) | (ea & 0x3FF); } else { - pa = ea & 0xFFFFFFF; /* should probably truncate this... */ + pa = ea & 0x3FFFFF; } if (pa <= MEMSIZE) return pa; @@ -354,7 +359,6 @@ pa_t mapva(ea_t ea, short intacc, short *access) { } -/* XXX: needs to check for restricted addresses */ /* Can V-mode do JMP# 4 to start executing from the register file? Might need to "or" 0x80000000 with PBH to indicate this?? */ @@ -384,17 +388,33 @@ unsigned short get16(ea_t ea) { unsigned int get32(ea_t ea) { pa_t pa; unsigned short access; + unsigned short m[2]; pa = mapva(ea, RACC, &access); - return *(unsigned int *)(mem+pa); + if ((pa & 01777) <= 01776) + return *(unsigned int *)(mem+pa); + else { + m[0] = mem[pa]; + m[1] = get16(ea+1); + return *(unsigned int *)m; + } } double get64(ea_t ea) { pa_t pa; unsigned short access; + unsigned short m[4]; pa = mapva(ea, RACC, &access); - return *(double *)(mem+pa); + if ((pa & 01777) <= 01774) + return *(double *)(mem+pa); + else { + m[0] = mem[pa]; + m[1] = get16(ea+1); + m[2] = get16(ea+2); + m[3] = get16(ea+3); + return *(double *)m; + } } @@ -428,32 +448,56 @@ put16(unsigned short value, ea_t ea) { put32(unsigned int value, ea_t ea) { pa_t pa; unsigned short access; + unsigned short *m; pa = mapva(ea, WACC, &access); - *(unsigned int *)(mem+pa) = value; + if ((pa & 01777) <= 01776) + *(unsigned int *)(mem+pa) = value; + else { + m = (void *)&value; + mem[pa] = m[0]; + put16(m[1], ea+1); + } } put64(double value, ea_t ea) { pa_t pa; unsigned short access; + unsigned short *m; pa = mapva(ea, WACC, &access); - *(double *)(mem+pa) = value; + if ((pa & 01777) <= 01774) + *(double *)(mem+pa) = value; + else { + m = (void *)&value; + mem[pa] = m[0]; + put16(m[1], ea+1); + put16(m[2], ea+2); + put16(m[3], ea+3); + } } void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) { unsigned short m; ea_t faultrp; - + if (fvec == PROCESSFAULT || fvec == SVCFAULT || fvec == ARITHFAULT) faultrp = RP; else faultrp = prevpc; - printf("fault '%o, fcode=%o, faddr=%o/%o, faultrp=%o/%o\n", fvec, fcode, faddr>>16, faddr&0xFFFF, faultrp>>16, faultrp&0xFFFF); + + /* save RP and keys in regfile */ + + regs.sym.pswpb = faultrp; + regs.sym.pswkeys = crs[KEYS]; + + printf("#%d: fault '%o, fcode=%o, faddr=%o/%o, faultrp=%o/%o\n", instcount, fvec, fcode, faddr>>16, faddr&0xFFFF, faultrp>>16, faultrp&0xFFFF); fprintf(stderr,"fault '%o, fcode=%o, faddr=%o/%o, faultrp=%o/%o\n", fvec, fcode, faddr>>16, faddr&0xFFFF, faultrp>>16, faultrp&0xFFFF); crs[FCODE] = fcode; *(unsigned int *)(crs+FADDR) = faddr; - if (!(crs[MODALS] & 010)) { /* process exchange is disabled */ + if (crs[MODALS] & 010) { /* process exchange is enabled */ + fatal("fault: fault '%o at RP=%o/%o with PX enabled\n", fvec, RPH, RPL); + } else { /* process exchange is disabled */ m = get16(fvec); if (m != 0) { if (1 || T_FLOW) fprintf(stderr," JST* '%o [%o]\n", fvec, m); @@ -463,9 +507,8 @@ void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) { longjmp(jmpbuf, 1); fatal("fault: returned after longjmp\n"); } - fatal("fault: JST vector '%o not set, RP=%o/%o\n", fvec, RPH, RPL); - } else { - fatal("fault: fault '%o at RP=%o/%o with PX enabled\n", fvec, RPH, RPL); + printf("#%d: fault '%o, fcode=%o, faddr=%o/%o, faultrp=%o/%o\n", instcount, fvec, fcode, faddr>>16, faddr&0xFFFF, faultrp>>16, faultrp&0xFFFF); + fatal("Fault vector is zero, process exchange is disabled."); } } @@ -563,6 +606,7 @@ ea_t ea16s (unsigned short inst, short i, short x) { ea += crs[X]; if (!i) /* not indirect */ break; + /* NOTE: this test is already in get16... */ if (ea < 040) m = get16(0x80000000|ea); else @@ -899,18 +943,19 @@ unsigned int ea32i (ea_t earp, unsigned short inst, short i, short x) { ea_t apea(unsigned short *bitarg) { - unsigned short ibr, ea_s, ea_w, bit; + unsigned short ibr, ea_s, ea_w, bit, br; ea_t ea; ibr = get16(RP); RPL++; bit = (ibr >> 12) & 0xF; - if (T_EAAP) fprintf(stderr," AP ibr=%o, br=%d, i=%d, bit=%d\n", ibr, ((ibr >> 8) & 3), (ibr & 004000) != 0, bit); + br = (ibr >> 8) & 3; + if (T_EAAP) fprintf(stderr," AP ibr=%o, br=%d, i=%d, bit=%d\n", ibr, br, (ibr & 004000) != 0, bit); /* XXX: should ea ring be weakened with RP ring? */ - ea_s = crs[PBH + 2*((ibr >> 8) & 3)]; - ea_w = crs[PBL + 2*((ibr >> 8) & 3)]; + ea_s = crs[PBH + 2*br]; + ea_w = crs[PBL + 2*br]; ea_w += get16(RP); RPL++; ea = MAKEVA(ea_s, ea_w); @@ -1051,37 +1096,75 @@ C ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) { - unsigned short ibr, ea_s, ea_w, bit, a; + unsigned short ibr, br, ea_s, ea_w, bit, a; ea_t xbsave; - ea_t ea; - + ea_t ea, newea; + xbsave = *(unsigned int *)(crs+XB); *store = 0; while (!*store && !*lastarg) { ibr = get16(*rp); (*rp)++; a = get16(*rp); + (*rp)++; bit = (ibr >> 12) & 0xF; *store = ibr & 0100; *lastarg = ibr & 0200; - if (T_PCL) fprintf(stderr," PCLAP ibr=%o, br=%d, i=%d, bit=%d, store=%d, lastarg=%d, a=%o\n", ibr, ((ibr >> 8) & 3), (ibr & 004000) != 0, bit, (*store != 0), (*lastarg != 0), a); - - /* XXX: should ea ring be weakened with RP ring? */ - - ea_s = crs[PBH + 2*((ibr >> 8) & 3)]; - ea_w = crs[PBL + 2*((ibr >> 8) & 3)]; + br = (ibr >> 8) & 3; + if (T_PCL) fprintf(stderr," PCLAP ibr=%o, br=%d, i=%d, bit=%d, store=%d, lastarg=%d, a=%o\n", ibr, br, (ibr & 004000) != 0, bit, (*store != 0), (*lastarg != 0), a); + ea_s = crs[PBH + 2*br] | (RPH & RINGMASK16); + ea_w = crs[PBL + 2*br]; ea_w += a; - (*rp)++; +#if 1 + /* this hack is for CPU.PCL Case 32: +4000/26434: PCL 4000/26543 + ecb @ 4000/26543, access=7 + ecb.pb: 4000/26532 + ecb.framesize: 16 + ecb.stackroot 4000 + ecb.argdisp: 12 + ecb.nargs: 1 + ecb.lb: 4000/60000 + ecb.keys: 14000 + stack free pointer: 4000/70000, current ring=0 + PCLAP ibr=11000, br=2, i=0, bit=1, store=0, lastarg=0, a=0 + PCLAP ea = 0/0 + PCLAP ibr=1700, br=3, i=0, bit=0, store=1, lastarg=1, a=0 + PCLAP ea = 10000/0 + new RP=4000/26533 + */ + if (br == 3 && (crs[XB] & EXTMASK16)) { + bit += crs[X]; + if (bit > 15) { + bit -= 16; + ea_w++; + } + if (bit == 0) + ea_s &= ~EXTMASK16; + } +#endif ea = MAKEVA(ea_s, ea_w); + if (bit) + ea |= EXTMASK32; if (T_PCL) fprintf(stderr," PCLAP ea = %o/%o\n", ea_s, ea_w); if (ibr & 004000) { if (ea & 0x80000000) fault(POINTERFAULT, ea>>16, 0); - ea = get32(ea); + newea = get32(ea) | (RP & RINGMASK32); + if (T_PCL) fprintf(stderr," Indirect pointer is %o/%o\n", newea>>16, newea & 0xFFFF); +#if 1 + /* Case 37 doesn't like this, Cases 35 & 36 seem to want it. Looks wrong to me */ + if ((newea & 0x80000000) && (newea>>16) != 0x8000) + fault(POINTERFAULT, newea>>16, ea); +#endif + ea = newea; + bit = 0; +#if 0 + /* CPU.PCL Case 33 shows that the bit field is not stored in the stack frame + for a 3-word indirect pointer, even though the E bit remains set */ if (ea & EXTMASK32) bit = get16(ea+2) >> 12; - else - bit = 0; +#endif if (T_PCL) fprintf(stderr," After indirect, PCLAP ea = %o/%o, bit=%d\n", ea>>16, ea & 0xFFFF, bit); } if (!*store) @@ -1106,7 +1189,7 @@ ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) { pcl (ea_t ea) { short i; short access; - short ecb[9]; + unsigned short ecb[9]; short bit; /* bit offset for args */ ea_t newrp; /* start of new proc */ ea_t rp; /* return pointer */ @@ -1126,31 +1209,35 @@ pcl (ea_t ea) { pa = mapva(ea, PACC, &access); if (T_PCL) fprintf(stderr," ecb @ %o/%o, access=%d\n", ea>>16, ea&0xFFFF, access); - /* gates must be aligned on a 16-word boundary */ + /* get a copy of the ecb. gates must be aligned on a 16-word + boundary, therefore can't cross a page boundary, and mapva has + already ensured that the ecb page is resident. For a non-gate + ecb, use individual memory accesses instead of memcpy. (Could be + optimized later by checking to see if the ecb crosses a page, + accessing the last word, then doing the memcpy.) */ - if (access == 1 && (ea & 0xF) != 0) - fault(ACCESSFAULT, 0, ea); + if (access == 1) { + if ((ea & 0xF) != 0) + fault(ACCESSFAULT, 0, ea); + memcpy(ecb,mem+pa,sizeof(ecb)); + } else { + for (i=0; i<9; i++) + ecb[i]=get16(ea+i); + } - /* get a copy of the ecb and determine new RP - - NOTE: can't just memcpy ecb, because it may cross a page - if this isn't a gate PCL - - XXX: P400 docs say "no ring change takes place if not a + /* XXX: P400 docs say "no ring change takes place if not a gate"; does that mean that if R0 calls a R3 ecb, it's - still in R0, or should it be weakened to the ecb ring? */ - - for (i=0; i<9; i++) - ecb[i]=get16(ea+i); + still in R0, or should it be weakened to the ecb ring? + (Case 24 of CPU.PCL indicates it should be weakened) */ if (T_PCL) fprintf(stderr," ecb.pb: %o/%o\n ecb.framesize: %d\n ecb.stackroot %o\n ecb.argdisp: %o\n ecb.nargs: %d\n ecb.lb: %o/%o\n ecb.keys: %o\n", ecb[0], ecb[1], ecb[2], ecb[3], ecb[4], ecb[5], ecb[6], ecb[7], ecb[8]); newrp = *(unsigned int *)(ecb+0); if (access != 1) #if 0 - newrp = (newrp & ~RINGMASK32) | (RP & RINGMASK32); + newrp = (newrp & ~RINGMASK32) | (RP & RINGMASK32); /* no ring change */ #else - newrp = newrp | (RP & RINGMASK32); /* Case 24 */ + newrp = newrp | (RP & RINGMASK32); /* Case 24 indicates to weaken ring */ #endif /* setup stack frame */ @@ -1219,12 +1306,11 @@ pcl (ea_t ea) { if (storedargs < ecb[5] && store) { put32(ea, argp); if (ea & EXTMASK32) - put16(bit, argp+2); + put16(bit<<12, argp+2); argp += 3; storedargs++; } } - //*(unsigned int *)(crs+XB) = xbsave; /* since proc has args, advance newrp past ARGT */ @@ -1251,10 +1337,22 @@ pcl (ea_t ea) { /* load new execution state from ecb */ + if (T_PCL) fprintf(stderr," before update, stackfp=%o/%o, SB=%o/%o\n", stackfp>>16, stackfp&0xFFFF, crs[SBH], crs[SBL]); +#if 0 if (access == 1) + /* NOTE: Case 21 shows that SB(r) should be 3 when calling from R1 to R3, but + Case 24 shows that SB(r) should be 0 when calling from R0 to R1 (??) */ + *(unsigned int *)(crs+SB) = stackfp; else *(unsigned int *)(crs+SB) = stackfp |= newrp & RINGMASK32; +#else + if (access == 1) + *(unsigned int *)(crs+SB) = stackfp; + else + *(unsigned int *)(crs+SB) = (stackfp & ~RINGMASK32) | (RP & RINGMASK32); +#endif + if (T_PCL) fprintf(stderr," new SB=%o/%o\n", crs[SBH], crs[SBL]); *(unsigned int *)(crs+LB) = *(unsigned int *)(ecb+6); newkeys(ecb[8] & 0177760); RP = newrp; @@ -1427,17 +1525,15 @@ main (int argc, char **argv) { /* main instruction decode loop */ - trapaddr = 02360; + trapaddr = 0144003; trapvalue = -12345; trapaddr = 0; if (setjmp(jmpbuf)) - goto fetch; + ; while (1) { -fetch: - if (trapaddr != 0 && mem[trapaddr] != trapvalue) { printf("TRAP: at #%d, old value of '%o was %o; new value is %o\n", instcount, trapaddr, trapvalue, mem[trapaddr]); trapvalue = mem[trapaddr]; @@ -1450,7 +1546,8 @@ fetch: prevpc = RP; inst = get16(RP); RPL++; - m = get16(RP); /* this is dangerous and should be removed! */ + //m = get16(RP); /* this is dangerous and should be removed! */ + m = -1; /* while a process is running, RP is the real program counter, PBH is the active procedure segment, and PBL is zero. When a @@ -1519,7 +1616,11 @@ xec: if (inst == 000505) { /* SVC */ if (T_FLOW) fprintf(stderr," SVC\n"); +#if 1 + fault(SVCFAULT, 0, 0); +#else svc(); +#endif continue; } @@ -1612,7 +1713,7 @@ xec: if (1 <= crs[A] && crs[A] < tempa) RPL = get16(RP+crs[A]); else - RPL = get16(RP+tempa); + RPL += tempa; continue; } @@ -2046,9 +2147,19 @@ stfa: RPL = get16(ea+1); newkeys(get16(ea+2)); crs[MODALS] = get16(ea+3); - if (T_INST) fprintf(stderr," RPH=%o, RPL=%o, keys=%o, modals=%o\n", RPH, RPL, crs[KEYS], crs[MODALS]); - if (crs[MODALS] & 010) - printf("Process exchange enabled\n"); + if (1 || T_INST) fprintf(stderr," RPH=%o, RPL=%o, keys=%o, modals=%o\n", RPH, RPL, crs[KEYS], crs[MODALS]); + if (crs[MODALS] & 010) { + printf("Process exchange enabled:\n"); + traceflags = -1; + printf(" OWNERH=%o, PLA=%o, PCBA=%o, PLB=%o, PCBB=%o\n", crs[OWNERH], regs.sym.pla, regs.sym.pcba, regs.sym.plb, regs.sym.pcbb); + for (i=regs.sym.pla;; i += 2) { + ea = MAKEVA(crs[OWNERH], i); + utempa = get16(ea); + printf(" Level %o: BOL=%o, EOL=%o\n", i, utempa, get16(ea+1)); + if (utempa == 1) + break; + } + } if (crs[MODALS] & 020) printf("Mapped I/O enabled\n"); if (crs[MODALS] & 4) { @@ -2076,6 +2187,21 @@ stfa: continue; } + /* Decimal and character instructions */ + + if (001100 <= inst && inst <= 001146) { + //traceflags = -1; + if (T_FLOW) fprintf(stderr," X/Z UII %o\n", inst); + fault(UIIFAULT, RPL, 0); + continue; + } + + if (inst == 001702) { + if (T_FLOW) fprintf(stderr," IDLE?\n", inst); + fatal("IDLE loop"); + continue; + } + /* unusual restricted instructions */ for (i=0; i>16, ea&0xFFFF); + //traceflags = ~TB_MAP; + if (T_FLOW || T_PCL) fprintf(stderr,"%o/%o: PCL %o/%o\n", RPH, RPL-2, ea>>16, ea&0xFFFF); pcl(ea); } else { if (T_FLOW) fprintf(stderr," CREP\n"); @@ -3813,7 +3946,7 @@ lcgt: if (opcode == 00503) { if (crs[KEYS] & 010000) { /* V/I mode */ if (T_FLOW) fprintf(stderr," ERL\n"); - templ = get16(ea)<<16 | get16(ea+1); + templ = get32(ea); *(int *)(crs+A) ^= templ; } else { if (T_FLOW) fprintf(stderr," JGT\n"); @@ -3826,8 +3959,7 @@ lcgt: if (opcode == 00403) { if (crs[KEYS] & 010000) { /* V/I mode */ if (T_FLOW) fprintf(stderr," STL\n"); - put16(crs[A],ea); - put16(crs[B],ea+1); + put32(*(unsigned int *)(crs+L),ea); } else { if (T_FLOW) fprintf(stderr," JLE\n"); if (*(short *)(crs+A) <= 0) @@ -3840,7 +3972,7 @@ lcgt: if (crs[KEYS] & 010000) { /* V/I mode */ if (T_FLOW) fprintf(stderr," ADL\n"); utempl = *(unsigned int *)(crs+L); - templ = get16(ea)<<16 | get16(ea+1); + templ = get32(ea); *(int *)(crs+L) += templ; EXPC(((~utempl ^ templ) & (utempl ^ *(int *)(crs+L))) & 0x80000000); SETCC_L; @@ -3862,8 +3994,7 @@ lcgt: if (opcode == 00303) { if (crs[KEYS] & 010000) { /* V/I mode */ if (T_FLOW) fprintf(stderr," ANL\n"); - crs[A] &= get16(ea); - crs[B] &= get16(ea+1); + *(unsigned int *)(crs+L) &= get32(ea); } else { if (T_FLOW) fprintf(stderr," JNE\n"); if (*(short *)(crs+A) != 0) @@ -3889,9 +4020,9 @@ lcgt: if (opcode == 03502) { if (T_FLOW) fprintf(stderr," STY\n"); - if (T_FLOW) printf("STY, RPL=%o, inst=%o, next word=%o, Y=%o, ea=%o, [ea]=%o\n", RPL-1, inst, get16(RP), crs[Y], ea, get16(ea)); + //if (T_FLOW) printf("STY, RPL=%o, inst=%o, next word=%o, Y=%o, ea=%o, [ea]=%o\n", RPL-1, inst, get16(RP), crs[Y], ea, get16(ea)); put16(crs[Y],ea); - if (T_FLOW) printf("executed STY, [ea]=%o\n", get16(ea)); + //if (T_FLOW) printf("executed STY, [ea]=%o\n", get16(ea)); continue; } @@ -3939,7 +4070,7 @@ lcgt: if (opcode == 01103) { if (T_FLOW) fprintf(stderr," CLS\n"); - templ = get16(ea)<<16 | get16(ea+1); + templ = get32(ea); if (*(int *)(crs+L) == templ) RPL++; else if (*(int *)(crs+L) < templ) @@ -3955,7 +4086,7 @@ lcgt: if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00)); *(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF); prieee4(&tempf); - *(int *)&tempf1 = get16(ea)<<16 | get16(ea+1); + *(int *)&tempf1 = get32(ea); prieee4(&tempf1); tempf += tempf1; ieeepr4(&tempf); @@ -3991,7 +4122,7 @@ lcgt: if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00)); *(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF); prieee4(&tempf); - *(int *)&tempf1 = get16(ea)<<16 | get16(ea+1); + *(int *)&tempf1 = get32(ea); prieee4(&tempf1); tempf /= tempf1; ieeepr4(&tempf); @@ -4017,7 +4148,7 @@ lcgt: if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00)); *(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF); prieee4(&tempf); - *(int *)&tempf1 = get16(ea)<<16 | get16(ea+1); + *(int *)&tempf1 = get32(ea); prieee4(&tempf1); tempf *= tempf1; ieeepr4(&tempf); @@ -4034,7 +4165,7 @@ lcgt: if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00)); *(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF); prieee4(&tempf); - *(int *)&tempf1 = get16(ea)<<16 | get16(ea+1); + *(int *)&tempf1 = get32(ea); prieee4(&tempf1); tempf -= tempf1; ieeepr4(&tempf); @@ -4148,7 +4279,7 @@ lcgt: if (opcode == 0202) { if (T_FLOW) fprintf(stderr," DFLD\n"); - *(double *)tempda = *(double *)(mem+ea); + *(double *)tempda = get64(ea); crs[FLTH] = tempda[0]; crs[FLTL] = tempda[1]; crs[FLTD] = tempda[2]; @@ -4200,10 +4331,17 @@ lcgt: if (opcode == 0402) { if (T_FLOW) fprintf(stderr," DFST\n"); + tempda[0] = crs[FLTH]; + tempda[1] = crs[FLTL]; + tempda[2] = crs[FLTD]; + tempda[3] = crs[FEXP]; + put64(*(double *)tempda, ea); +#if 0 put16(crs[FLTH], ea); put16(crs[FLTL], ea+1); put16(crs[FLTD], ea+2); put16(crs[FEXP], ea+3); +#endif continue; } diff --git a/emdev.h b/emdev.h index 8f2edfb..67bc2e9 100644 --- a/emdev.h +++ b/emdev.h @@ -82,7 +82,7 @@ void devnull (short class, short func, short device) { if (func == 0) { ; } else { - if (T_INST) fprintf(stderr," unimplemented OCP device '%02o function\n", device); + printf("Unimplemented OCP device '%02o function '%02o\n", device, func); fatal(NULL); } break; @@ -92,7 +92,7 @@ void devnull (short class, short func, short device) { if (func == 0) IOSKIP; /* assume it's always ready */ else { - if (T_INST) fprintf(stderr," unimplemented SKS device '%02o function\n", device); + printf("Unimplemented SKS device '%02o function '%02o\n", device, func); fatal(NULL); } break; @@ -102,7 +102,7 @@ void devnull (short class, short func, short device) { if (func == 0) { ; } else { - if (T_INST) fprintf(stderr," unimplemented INA device '%02o function\n", device); + printf("Unimplemented INA device '%02o function '%02o\n", device, func); fatal(NULL); } break; @@ -112,7 +112,7 @@ void devnull (short class, short func, short device) { if (func == 0 | func == 1) { IOSKIP; /* OTA '0004 always works on Unix */ } else { - if (T_INST) fprintf(stderr," unimplemented OTA device '%02o function\n", device); + printf("Unimplemented OTA device '%02o function '%02o\n", device, func); fatal(NULL); } break; @@ -238,7 +238,8 @@ readasr: } } else if (n == 1) { if (ch == '') { - traceflags = ~traceflags; + traceflags = ~TB_MAP; + traceflags = -1; goto readasr; } if (func >= 010) @@ -247,7 +248,7 @@ readasr: if (T_INST) fprintf(stderr," character read=%o: %c\n", crs[A], crs[A]); IOSKIP; } else if (n != 0) { - if (T_INST) fprintf(stderr," unexpected error reading from tty, n=%d", n); + printf("Unexpected error reading from tty, n=%d", n); fatal(NULL); } } else if (func == 011) { /* read device id? */ @@ -257,7 +258,7 @@ readasr: crs[A] = 04110; IOSKIP; } else { - if (T_INST) fprintf(stderr," unimplemented INA '04 function\n"); + printf("Unimplemented INA '04 function '%02o\n", func); fatal(NULL); } break; @@ -275,7 +276,7 @@ readasr: } else if (func == 1) { /* write control word */ IOSKIP; } else { - if (T_INST) fprintf(stderr," unimplemented OTA '04 function\n"); + printf("Unimplemented OTA '04 function '%02o\n", func); fatal(NULL); } break; @@ -303,7 +304,7 @@ void devmt (short class, short func, short device) { case 2: if (T_INST) fprintf(stderr," INA '%02o%02o\n", func, device); if (BLOCKIO) { - if (T_INST) fprintf(stderr," Device not supported, so I/O hangs\n"); + printf("Device '%o not supported, so I/O hangs\n", device); fatal(NULL); } break; @@ -311,7 +312,7 @@ void devmt (short class, short func, short device) { case 3: if (T_INST) fprintf(stderr," OTA '%02o%02o\n", func, device); if (BLOCKIO) { - if (T_INST) fprintf(stderr," Device not supported, so I/O hangs\n"); + printf("Device '%o not supported, so I/O hangs\n", device); fatal(NULL); } break; @@ -319,11 +320,37 @@ void devmt (short class, short func, short device) { } -/* Device '20: control panel switches and lights +/* Device '20: control panel switches and lights, and realtime clock + OCP '0020 = start Line Frequency Clock, enable mem increment, ack previous overflow + OCP '0120 = ack PIC interrupt + OCP '0220 = stop LFC, disable mem increment, ack previous overflow + OCP '0420 = select LFC for memory increment + OCP '0520 = select external clock for memory increment + OCP '0620 = starts a new 50-ms watchdog timeout interval + OCP '0720 = stops the watchdog timer + OCP '1520 = set interrupt mask + OCP '1620 = reset interrupt mask + OCP '1720 = initialize as in Master Clear + + SKS '0020 = skip if clock IS interrupting + SKS '0220 = skip if clock IS NOT interrupting + SKS '0520 = skip if WDT timed out + SKS '0720 = skip if WDT caused external interrupt (loc '60) + + OTA '0220 = set PIC Interval register (negative, interrupts on incr to zero) + OTA '0720 = set control register + OTA '1220 = set Memory Increment Cell address + OTA '1320 = set interrupt vector address OTA '1720 = write to lights (sets CP fetch address) + + INA '0220 = read PIC Interval register + INA '1120 = read device ID, don't clear A first + INA '1220 = read Memory Increment Cell address + INA '1320 = read interrupt vector address INA '1420 = read location from CP ROM (not implemented, used to boot) - INA '1620 = read control panel switches + INA '1620 = read control panel up switches + INA '1720 = read control panel down switches */ void devcp (short class, short func, short device) { @@ -332,34 +359,43 @@ void devcp (short class, short func, short device) { case 0: if (T_INST) fprintf(stderr," OCP '%02o%02o\n", func, device); - if (T_INST) fprintf(stderr," unimplemented OCP device '%02o function\n", device); - fatal(NULL); + printf("OCP '%02o%02o\n", func, device); + //printf("Unimplemented OCP device '%02o function '%02o\n", device, func); + //fatal(NULL); break; case 1: if (T_INST) fprintf(stderr," SKS '%02o%02o\n", func, device); - if (T_INST) fprintf(stderr," unimplemented SKS device '%02o function\n", device); + printf("Unimplemented SKS device '%02o function '%02o\n", device, func); fatal(NULL); break; case 2: if (T_INST) fprintf(stderr," INA '%02o%02o\n", func, device); - if (func == 016) { + if (func == 011) { /* input ID, don't clear A first */ + crs[A] |= 0120; /* this is the SOC board */ + } else if (func == 016) { crs[A] = sswitch; } else if (func == 017) { /* read switches in momentary down position */ crs[A] = 0; } else { - if (T_INST) fprintf(stderr," unimplemented INA device '%02o function\n", device); + printf("Unimplemented INA device '%02o function '%02o\n", device, func); fatal(NULL); } break; case 3: if (T_INST) fprintf(stderr," OTA '%02o%02o\n", func, device); - if (func == 017) { /* write lights */ + if (func == 02) { /* set PIC interval */ + printf("Clock PIC interval set to %d\n", *(short *)(crs+A)); + } else if (func == 07) { + printf("Clock control register set to '%o\n", crs[A]); + } else if (func == 013) { + printf("Clock interrupt vector address = '%o\n", crs[A]); + } else if (func == 017) { /* write lights */ IOSKIP; } else { - if (T_INST) fprintf(stderr," unimplemented OTA device '%02o function\n", device); + printf("Unimplemented OTA device '%02o function '%02o\n", device, func); fatal(NULL); } break; @@ -428,7 +464,7 @@ void devdisk (short class, short func, short device) { else if (func == 017) /* read status */ crs[A] = 0100000; else { - if (T_INST || T_DIO) fprintf(stderr," unimplemented INA device '%02o function\n", device); + printf("Unimplemented INA device '%02o function '%02o\n", device, func); fatal(NULL); } IOSKIP; @@ -474,7 +510,8 @@ void devdisk (short class, short func, short device) { if (T_INST || T_DIO) fprintf(stderr," Unit not selected or not ready\n"); status = 0100001; } else if (order == 2) { - if (T_INST || T_DIO) fprintf(stderr," Format order not implemented\n"); + if (T_INST || T_DIO) fprintf(stderr," Format order\n"); + fatal("DFORMAT channel order not implemented"); } else if (order == 5) { /* translate head/track/sector to drive record address */ @@ -526,8 +563,7 @@ void devdisk (short class, short func, short device) { } } else if (order == 6) { - printf(" Write order not implemented\n"); - exit(1); + fatal("DWRITE channel order not implemented"); } oar += 3; break; @@ -578,6 +614,7 @@ void devdisk (short class, short func, short device) { case 14: /* DINT = generate interrupt through vector address */ memaddr = mem[oar+1]; if (T_INST || T_DIO) fprintf(stderr, " interrupt through '%o\n", memaddr); + printf("DINT not supported (emdev.h)\n"); fatal(NULL); oar += 2; break; @@ -586,13 +623,13 @@ void devdisk (short class, short func, short device) { if (T_INST || T_DIO) fprintf(stderr, " jump to '%o\n", oar); break; default: - if (T_INST || T_DIO) fprintf(stderr, " unrecognized channel order = %d\n", order); + printf("Unrecognized channel order = %d\n", order); fatal(NULL); } } IOSKIP; } else { - if (T_INST || T_DIO) fprintf(stderr," unimplemented OTA device '%02o function\n", device); + printf("Unimplemented OTA device '%02o function '%02o\n", device, func); fatal(NULL); } break;