1
0
mirror of https://github.com/prirun/p50em.git synced 2026-01-24 19:12:02 +00:00

changed mem[] to be Prime physical memory array, removed direct references +

more work on PCL
This commit is contained in:
Jim 2005-06-10 00:00:00 -04:00
parent 22f4c22f8f
commit 0b2994585c
2 changed files with 284 additions and 109 deletions

306
em.c
View File

@ -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<GEN0TABSIZE; i++) {
@ -3091,6 +3217,13 @@ lcgt:
if (T_INST) fprintf(stderr," unrecognized generic class 3 instruction!\n");
printf(" unrecognized generic class 3 instruction %o!\n", inst);
/* XXX: these are hacks for CPU.FAULT; not sure how to determine whether
an instruction is illegal or unimplemented... */
if (inst == 0141700)
fault(ILLINSTFAULT, RPL, 0);
else
fault(UIIFAULT, RPL, 0);
fatal(NULL);
}
@ -3690,7 +3823,7 @@ lcgt:
if (opcode == 01603) {
if (T_FLOW) fprintf(stderr," MPL\n");
templ = (get16(ea)<<16) | get16(ea+1);
templ = get32(ea);
templl = (long long)(*(int *)(crs+L)) * (long long)templ;
*(long long *)(crs+L) = templl;
SETCC_LE;
@ -3723,7 +3856,7 @@ lcgt:
if (opcode == 01703) {
if (T_FLOW) fprintf(stderr," DVL\n");
templl = *(long long *)(crs+L);
templ = (get16(ea)<<16) | get16(ea+1);
templ = get32(ea);
if (templ != 0) {
*(int *)(crs+L) = templl / templ;
*(int *)(crs+E) = templl % templ;
@ -3755,8 +3888,7 @@ lcgt:
if (opcode == 00203) {
if (crs[KEYS] & 010000) { /* V/I mode */
if (T_FLOW) fprintf(stderr," LDL\n");
crs[A] = get16(ea);
crs[B] = get16(ea+1);
*(unsigned int *)(crs+L) = get32(ea);
} else {
if (T_FLOW) fprintf(stderr," JEQ\n");
if (*(short *)(crs+A) == 0)
@ -3769,7 +3901,7 @@ lcgt:
if (crs[KEYS] & 010000) { /* V/I mode */
if (T_FLOW) fprintf(stderr," SBL\n");
utempl = *(unsigned int *)(crs+L);
utempl2 = get16(ea)<<16 | get16(ea+1);
utempl2 = get32(ea);
*(int *)(crs+L) -= *(int *)&utempl2;
crs[KEYS] &= ~0300;
if (utempl == utempl2) {
@ -3800,7 +3932,8 @@ lcgt:
if (opcode == 01002) {
if (crs[KEYS] & 010000) { /* V/I mode */
if (T_FLOW || T_PCL) fprintf(stderr,"%o/%o: PCL %o/%o\n", RPH, RPL, ea>>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;
}

87
emdev.h
View File

@ -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;