1
0
mirror of https://github.com/prirun/p50em.git synced 2026-01-30 05:04:04 +00:00

more work on PCL

This commit is contained in:
Jim
2005-06-11 00:00:00 -04:00
parent 0b2994585c
commit 32c4116e52

127
em.c
View File

@@ -1095,6 +1095,42 @@ C
}
unsigned short dumppcb(unsigned short pcb) {
short i;
unsigned short nextpcb;
ea_t ea;
ea = MAKEVA(crs[OWNERH],pcb);
fprintf(stderr,"PCB %06o:\n", pcb);
fprintf(stderr," Level: %o\n", get16(ea+0));
nextpcb = get16(ea+1);
fprintf(stderr," Link: %o\n", nextpcb);
fprintf(stderr," Wait list: %o/%o\n", get16(ea+2), get16(ea+3));
fprintf(stderr," Abort flags: %o\n", get16(ea+4));
fprintf(stderr," CPU flags: %o\n", get16(ea+5));
fprintf(stderr," 6,7 (reserved): %o %o\n", get16(ea+6), get16(ea+7));
fprintf(stderr," Elapsed timers: %d %d\n", get16(ea+8), get16(ea+9));
fprintf(stderr," DTAR 2 & 3: %o|%o %o|%o\n", get16(ea+10), get16(ea+11), get16(ea+12), get16(ea+13));
fprintf(stderr," Process interval timer: %o\n", get16(ea+14));
fprintf(stderr," 15 (reserved): %o\n", get16(ea+15));
fprintf(stderr," Save mask: %o\n", get16(ea+16));
fprintf(stderr," Keys: %o\n", get16(ea+17));
for (i=0; i<16; i++) {
fprintf(stderr," %06o %06o", get16(ea+18+2*i), get16(ea+19+2*i));
if (i==7 || i==15)
fprintf(stderr,"\n");
}
fprintf(stderr," R0 Fault vec: %o/%o\n", get16(ea+50), get16(ea+51));
fprintf(stderr," R1 Fault vec: %o/%o\n", get16(ea+52), get16(ea+53));
fprintf(stderr," R2 Fault vec: %o/%o\n", get16(ea+54), get16(ea+55));
fprintf(stderr," R3 Fault vec: %o/%o\n", get16(ea+56), get16(ea+57));
fprintf(stderr," PG Fault vec: %o/%o\n", get16(ea+58), get16(ea+59));
fprintf(stderr," Conc. Stack Hdr: %o %o %o\n", get16(ea+60), get16(ea+61), get16(ea+62));
fprintf(stderr,"\n");
return nextpcb;
}
ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) {
unsigned short ibr, br, ea_s, ea_w, bit, a;
ea_t xbsave;
@@ -1111,28 +1147,10 @@ ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) {
*store = ibr & 0100;
*lastarg = ibr & 0200;
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);
if (T_PCL) printf(" 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;
#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) {
@@ -1142,16 +1160,15 @@ ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) {
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 (T_PCL) printf(" PCLAP ea = %o/%o, bit=%d\n", ea_s, ea_w, bit);
if (ibr & 004000) {
if (ea & 0x80000000)
fault(POINTERFAULT, ea>>16, 0);
newea = get32(ea) | (RP & RINGMASK32);
if (T_PCL) fprintf(stderr," Indirect pointer is %o/%o\n", newea>>16, newea & 0xFFFF);
if (T_PCL) printf(" 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)
@@ -1165,7 +1182,7 @@ ea_t pclea(ea_t *rp, unsigned short *bitarg, short *store, short *lastarg) {
if (ea & EXTMASK32)
bit = get16(ea+2) >> 12;
#endif
if (T_PCL) fprintf(stderr," After indirect, PCLAP ea = %o/%o, bit=%d\n", ea>>16, ea & 0xFFFF, bit);
if (T_PCL) printf(" After indirect, PCLAP ea = %o/%o, bit=%d\n", ea>>16, ea & 0xFFFF, bit);
}
if (!*store)
*(unsigned int *)(crs+XB) = ea;
@@ -1201,13 +1218,12 @@ pcl (ea_t ea) {
ea_t argp; /* where to store next arg in new frame */
ea_t stackfp; /* new stack frame pointer */
pa_t pa; /* physical address of ecb */
short extension; /* true if extension pointer was used */
ea_t xbsave;
/* get segment access; mapva ensures either read or gate */
pa = mapva(ea, PACC, &access);
if (T_PCL) fprintf(stderr," ecb @ %o/%o, access=%d\n", ea>>16, ea&0xFFFF, access);
if (T_PCL) printf(" ecb @ %o/%o, access=%d\n", ea>>16, ea&0xFFFF, access);
/* 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
@@ -1230,7 +1246,7 @@ pcl (ea_t ea) {
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]);
if (T_PCL) printf(" 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)
@@ -1245,30 +1261,28 @@ pcl (ea_t ea) {
stackrootseg = ecb[3];
if (stackrootseg == 0) {
stackrootseg = get16((*(unsigned int *)(crs+SB)) + 1);
if (T_PCL) fprintf(stderr," stack root in ecb was zero, stack root from caller is %o\n", stackrootseg);
if (T_PCL) printf(" stack root in ecb was zero, stack root from caller is %o\n", stackrootseg);
}
if (stackrootseg == 0)
fatal("Stack base register root segment is zero");
stackfp = get32(MAKEVA(stackrootseg,0));
if (stackfp == 0)
fatal("Stack free pointer is zero");
if (T_PCL) fprintf(stderr," stack free pointer: %o/%o, current ring=%o\n", stackfp>>16, stackfp&0xFFFF, RPH&RINGMASK16);
if (T_PCL) printf(" stack free pointer: %o/%o, current ring=%o\n", stackfp>>16, stackfp&0xFFFF, RPH&RINGMASK16);
stacksize = ecb[2];
/* if there isn't room for this frame, check the stack extension
pointer */
extension = 0;
if ((stackfp & 0xFFFF) + stacksize > 0xFFFF) {
stackfp = get32(MAKEVA(stackrootseg,2));
if (T_PCL) fprintf(stderr," no room for frame, extension pointer is %o/%o\n", stackfp>>16, stackfp&0xFFFF);
if (T_PCL) printf(" no room for frame, extension pointer is %o/%o\n", stackfp>>16, stackfp&0xFFFF);
/* XXX: faddr may need to be the last segment tried when this is changed to loop.
CPU.PCL Case 26 wants fault address word number to be 3 (?) */
if (stackfp == 0 || (stackfp & 0xFFFF) + stacksize > 0xFFFF)
fault(STACKFAULT, 0, MAKEVA(stackrootseg,3) | (newrp & RINGMASK32));
extension = 1;
fault(STACKFAULT, 0, MAKEVA(stackrootseg,0) | (newrp & RINGMASK32));
}
/* setup the new stack frame at stackfp
@@ -1325,38 +1339,25 @@ pcl (ea_t ea) {
/* update the stack free pointer; this has to wait until after all
memory accesses, in case of stack page faults (PCL restarts).
The ring is stored only if the extension pointer was followed.
This is probably some goofy microcode bug: CPU.PCL Case 25 expects
no ring number, but Case 27 does. */
Some ucode versions incorrectly store the ring in the free
pointer if the extension pointer was followed. Set EHDB to
suppress this spurious DIAG error. */
ea = MAKEVA(stackrootseg,0) | (newrp & RINGMASK32);
if (extension)
put32(stackfp+stacksize, ea);
else
put32((stackfp+stacksize) & ~RINGMASK32, ea);
put32((stackfp+stacksize) & ~RINGMASK32, 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 (T_PCL) printf(" before update, stackfp=%o/%o, SB=%o/%o\n", stackfp>>16, stackfp&0xFFFF, crs[SBH], crs[SBL]);
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]);
if (T_PCL) printf(" new SB=%o/%o\n", crs[SBH], crs[SBL]);
*(unsigned int *)(crs+LB) = *(unsigned int *)(ecb+6);
newkeys(ecb[8] & 0177760);
RP = newrp;
if (T_PCL) fprintf(stderr," new RP=%o/%o\n", RPH, RPL);
if (T_PCL) printf(" new RP=%o/%o\n", RPH, RPL);
}
@@ -1375,7 +1376,7 @@ void prtn() {
*(unsigned int *)(crs+SB) = newsb;
*(unsigned int *)(crs+LB) = newlb;
crs[KEYS] = newkeys & 0177760;
if (T_INST) fprintf(stderr," Finished PRTN, RP=%o/%o\n", RPH, RPL);
if (T_INST) printf(" Finished PRTN, RP=%o/%o\n", RPH, RPL);
}
main (int argc, char **argv) {
@@ -1408,7 +1409,7 @@ main (int argc, char **argv) {
/* master clear:
- clear all registers
- set register set to 2
- register set is 2
- set P to '1000
- 16S mode, single precision
- interrupts and machine checks inhibited
@@ -1417,9 +1418,8 @@ main (int argc, char **argv) {
for (i=0; i < 32*REGSETS; i++)
regs.u32[i] = 0;
crs = (void *)regs.rs[2];
crs = (void *)regs.rs[2]; /* boot w/register set 2 */
crsl = (void *)crs;
crs[MODALS] = 000100; /* boot w/ CURREG=2 (current register set) */
newkeys(0);
RPL = 01000;
@@ -1529,6 +1529,8 @@ main (int argc, char **argv) {
trapvalue = -12345;
trapaddr = 0;
/* faults may longjmp here: the top of the instruction fetch loop */
if (setjmp(jmpbuf))
;
@@ -2146,11 +2148,13 @@ stfa:
RPH = get16(ea);
RPL = get16(ea+1);
newkeys(get16(ea+2));
crs[MODALS] = get16(ea+3);
m = get16(ea+3);
if ((m & 0340) != (crs[MODALS] & 0340))
printf("WARNING: LPSW changed current register set: current modals=%o, new modals=%o\n", crs[MODALS], m);
crs[MODALS] = m;
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);
@@ -2158,7 +2162,10 @@ stfa:
printf(" Level %o: BOL=%o, EOL=%o\n", i, utempa, get16(ea+1));
if (utempa == 1)
break;
while (utempa > 0)
utempa = dumppcb(utempa);
}
traceflags = -1;
}
if (crs[MODALS] & 020)
printf("Mapped I/O enabled\n");
@@ -3933,7 +3940,7 @@ lcgt:
if (opcode == 01002) {
if (crs[KEYS] & 010000) { /* V/I mode */
//traceflags = ~TB_MAP;
if (T_FLOW || T_PCL) fprintf(stderr,"%o/%o: PCL %o/%o\n", RPH, RPL-2, ea>>16, ea&0xFFFF);
if (T_FLOW || T_PCL) printf("#%d %o/%o: PCL %o/%o\n", instcount, RPH, RPL-2, ea>>16, ea&0xFFFF);
pcl(ea);
} else {
if (T_FLOW) fprintf(stderr," CREP\n");
@@ -4393,7 +4400,6 @@ lcgt:
if (opcode == 01401) {
if (T_FLOW) fprintf(stderr," EIO\n");
if (restrict()) break;
crs[KEYS] &= ~0100; /* reset EQ */
pio(ea & 0xFFFF);
continue;
@@ -5058,6 +5064,7 @@ pio(unsigned int inst) {
short func;
short device;
restrict();
class = inst >> 14;
func = (inst >> 6) & 017;
device = inst & 077;