1
0
mirror of https://github.com/prirun/p50em.git synced 2026-04-16 07:56:21 +00:00

trace improvements, PCL indirect bit offset bug (SAC odd char bug) +

added T_TERM for system terminal output tracing
added specific user tracing:
- 2-digit number after trace (user number)
- 6-digit octal number = OWNERL (for devices)
added specific procedure tracing
major bug in PCL: indirect bit offsets not working,
  causing SAC JIM:PDALURW to be SAC JIM:PAUW
This commit is contained in:
Jim
2007-03-01 00:00:00 -05:00
parent ec2ba390d0
commit f9d4f6f3bb
3 changed files with 283 additions and 148 deletions

408
em.c
View File

@@ -1,8 +1,10 @@
/* Pr1me Computer emulator, Jim Wilcoxson (jim@meritnet.com), April 4, 2005
Copyright (C) 2005, Jim Wilcoxson (jim@meritnet.com). All Rights Reserved.
/* Pr1me Computer emulator, Jim Wilcoxson (prirun@gmail.com), April 4, 2005
Copyright (C) 2005, Jim Wilcoxson (prirun@gmail.com). All Rights Reserved.
Restores a Prime R-mode .save image from stdin to memory and
emulates execution, or boots from a Prime disk image.
Emulates a Prime Computer system by:
- booting from a Prime disk image (normal usage)
- booting from a Prime MAGSAV tape
- restoring a Prime R-mode .save image from the host file system
This is a project in development, so please don't publish it.
Comments, suggestions, corrections, and general notes that you're
@@ -19,6 +21,10 @@
and c=1/3/5/7 for controller 26/27/...
(See complete boot table below)
NOTE: the -map command is optional, but is needed to set the
real-time clock automatically. If not available, use the Primos SE
command to set the clock manually after the system boots.
-------------
Usage: (to load and start an R-mode runfile directly from the Unix FS)
@@ -217,27 +223,29 @@ char gen0nam[][5] = {
T_EAAP AP effective address calculation
T_DIO disk I/O
T_TIO tape I/O
T_TERM terminal output (tnou[a])
T_MAP segmentation
T_PCL PCL instructions
T_FAULT Faults
T_PX Process exchange
*/
#define TB_EAR 0x00000001
#define TB_EAV 0x00000002
#define TB_EAI 0x00000004
#define TB_INST 0x00000008
#define TB_FLOW 0x00000010
#define TB_MODE 0x00000020
#define TB_EAAP 0x00000040
#define TB_DIO 0x00000080
#define TB_MAP 0x00000100
#define TB_PCL 0x00000200
#define TB_EAR 0x00000001
#define TB_EAV 0x00000002
#define TB_EAI 0x00000004
#define TB_INST 0x00000008
#define TB_FLOW 0x00000010
#define TB_MODE 0x00000020
#define TB_EAAP 0x00000040
#define TB_DIO 0x00000080
#define TB_MAP 0x00000100
#define TB_PCL 0x00000200
#define TB_FAULT 0x00000400
#define TB_PX 0x00000800
#define TB_TIO 0x00001000
#define TB_PX 0x00000800
#define TB_TIO 0x00001000
#define TB_TERM 0x00002000
#define T_EAR TB_EAR
#define T_EAR TB_EAR
#define T_EAV TB_EAV
#define T_EAI TB_EAI
#define T_INST TB_INST
@@ -250,6 +258,7 @@ char gen0nam[][5] = {
#define T_FAULT TB_FAULT
#define T_PX TB_PX
#define T_TIO TB_TIO
#define T_TERM TB_TERM
#if defined(NOTRACE)
#define TRACE(flags, formatargs...)
@@ -258,9 +267,35 @@ char gen0nam[][5] = {
#define TRACEA(formatargs...) fprintf(tracefile,formatargs)
#endif
/* traceflags is the variable used to test tracing of each instruction
traceuser is the user number to trace, 0 meaning any user
savetraceflags hold the real traceflags, while "traceflags" switches
on and off for each instruction
traceprocs is an array of procedure names we're tracing, with flags
and various associated data
numtraceprocs is the number of entries in traceprocs, 0=none
TRACEUSER is a macro that is true if the current user is being traced
*/
int traceflags=0; /* each bit is a trace flag */
int savetraceflags=0; /* see ITLB */
int traceuser=0; /* OWNERL to trace */
int numtraceprocs=0;
#define MAXTRACEPROCS 2
struct {
char name[11]; /* procedure name */
int ecb; /* ecb ea of proc */
int sb; /* sb before the call */
int oneshot; /* disable trace after call? */
} traceprocs[MAXTRACEPROCS];
FILE *tracefile; /* trace.log file */
#define TRACEUSER (traceuser == 0 || crs[OWNERL] == traceuser)
int intvec=-1; /* currently raised interrupt (if >= zero) */
@@ -440,7 +475,7 @@ addsym(char *sym, unsigned short seg, unsigned short word, char type) {
if (ix+1 < numsyms) /* make room for the new symbol */
for (ix2 = numsyms; ix2 > ix; ix2--)
mapsym[ix2] = mapsym[ix2-1];
//printf("%s = %o/%o\n", sym, segno, wordno);
//TRACEA("%s = %o/%o\n", sym, seg, words);
strcpy(mapsym[ix+1].symname, sym);
mapsym[ix+1].address = addr;
mapsym[ix+1].symtype = type;
@@ -1329,9 +1364,6 @@ ea_t apea(unsigned short *bitarg) {
return ea;
}
#define GETFLR(n) (((crsl[FLR0+2*(n)] >> 11) & 0x1FFFE0) | (crsl[FLR0+2*(n)] & 0x1F))
#define PUTFLR(n,v) crsl[FLR0+2*(n)] = (((v) << 11) & 0xFFFF0000) | (crsl[FLR0+2*(n)] & 0xF000) | ((v) & 0x1F);
/* exception handler types:
'i' = integer exception
@@ -1381,19 +1413,22 @@ mathexception(unsigned char extype, unsigned short fcode, ea_t faddr)
memdump(int start, int end) {
int ea;
/* dump sector zero for debugging */
if (domemdump) {
TRACEA("\nSector 0:\n");
for (ea=0; ea<01000; ea=ea+8)
if (mem[ea]|mem[ea+1]|mem[ea+2]|mem[ea+3]|mem[ea+4]|mem[ea+5]|mem[ea+6]|mem[ea+7])
TRACEA("%3o: %6o %6o %6o %6o %6o %6o %6o %6o\n", ea, mem[ea], mem[ea+1], mem[ea+2], mem[ea+3], mem[ea+4], mem[ea+5], mem[ea+6], mem[ea+7]);
/* dump main memory for debugging */
/* dump sector zero for debugging */
TRACEA("\nMain memory:\n");
for (ea=start; ea<=end; ea=ea+8)
if (mem[ea]|mem[ea+1]|mem[ea+2]|mem[ea+3]|mem[ea+4]|mem[ea+5]|mem[ea+6]|mem[ea+7])
TRACEA("%o: %6o %6o %6o %6o %6o %6o %6o %6o\n", ea, mem[ea], mem[ea+1], mem[ea+2], mem[ea+3], mem[ea+4], mem[ea+5], mem[ea+6], mem[ea+7]);
TRACEA("\nSector 0:\n");
for (ea=0; ea<01000; ea=ea+8)
if (mem[ea]|mem[ea+1]|mem[ea+2]|mem[ea+3]|mem[ea+4]|mem[ea+5]|mem[ea+6]|mem[ea+7])
TRACEA("%3o: %6o %6o %6o %6o %6o %6o %6o %6o\n", ea, mem[ea], mem[ea+1], mem[ea+2], mem[ea+3], mem[ea+4], mem[ea+5], mem[ea+6], mem[ea+7]);
/* dump main memory for debugging */
TRACEA("\nMain memory:\n");
for (ea=start; ea<=end; ea=ea+8)
if (mem[ea]|mem[ea+1]|mem[ea+2]|mem[ea+3]|mem[ea+4]|mem[ea+5]|mem[ea+6]|mem[ea+7])
TRACEA("%o: %6o %6o %6o %6o %6o %6o %6o %6o\n", ea, mem[ea], mem[ea+1], mem[ea+2], mem[ea+3], mem[ea+4], mem[ea+5], mem[ea+6], mem[ea+7]);
}
}
@@ -1675,11 +1710,19 @@ fault: jumping to fault table entry at RP=60013/61212
fault(POINTERFAULT, ea>>16, iwea);
#endif
bit = 0;
#if 0
#if 1
/* 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 */
for a 3-word indirect pointer, even though the E bit remains set.
NOTE: this comment is screwy, and probably reflects a microcode bug on certain
machines. If this code is disabled, the SAC command doesn't work:
SAC X JIMMY:PDALURW sets permission as JIMMY:PAUW
NOTE 2: turns out that this code was fetching the bit offset from ea+2 instead
of from iwea+2, which could account for lots of weirdness! */
if (ea & EXTMASK32)
bit = get16(ea+2) >> 12;
bit = get16(iwea+2) >> 12;
#endif
TRACE(T_PCL, " After indirect, PCLAP ea = %o/%o, bit=%d\n", ea>>16, ea & 0xFFFF, bit);
}
@@ -1709,7 +1752,7 @@ fault: jumping to fault table entry at RP=60013/61212
pcl (ea_t ecbea) {
short i;
short i,j;
unsigned short access;
unsigned short ecb[9];
short bit; /* bit offset for args */
@@ -1726,8 +1769,9 @@ pcl (ea_t ecbea) {
pa_t pa; /* physical address of ecb */
unsigned short brsave[6]; /* old PB,SB,LB */
unsigned short utempa;
unsigned short tnstring[500];
unsigned short tnlen;
unsigned char tnstring[500];
unsigned short tnlen, tnword;
unsigned char tnchar;
#define FATAL$ MAKEVA(06,0164600)
#define INIT$3 MAKEVA(013,0174041)
@@ -1878,42 +1922,39 @@ pcl (ea_t ecbea) {
crs[XL] = 0;
argt();
#if 0
/* do something here to intercept TNOUx calls for user 1, to avoid
9600-bps system console issue. This sort of works, but not all
console output is trapped so it gets mixed together. Trapping
tolio$ may work better. However, that has the problem of not
putting characters into the como file. Could also trap, do
printf, let it go into asrbuf, ignore it in devasr. With a big
ASRBUF, this might work fine. */
/* if tracing terminal output, display it now. This has to occur
after ARGT has setup the argument pointers. Note that if a fault
occurs while accessing the arguments here, it will return to ARGT
in the main emulator loop and nothing will be logged. */
if (ecbea == tnou_ea || ecbea == tnoua_ea) {
TRACEA(" TNOUx called, ea=%o/%o\n", ecbea>>16, ecbea&0xffff);
if (TRACEUSER && ((ecbea & 0xFFFFFFF) == tnou_ea || (ecbea & 0xFFFFFFF) == tnoua_ea)) {
ea = *(unsigned int *)(crs+SB) + ecb[4];
utempa = get16(get32(ea)); /* userid */
if (utempa == 1) {
ea = ea + 6;
tnlen = get16(get32(ea)); /* length in bytes */
ea = get32(ea-3); /* address of string */
for (i=0; i<(tnlen+1)/2; i++)
tnstring[i] = get16(ea+i) & 0x7f7f;
tnstring[i] = 0;
if (ecbea == tnoua_ea) {
printf("%s", tnstring);
fflush(stdout);
} else
printf("%s\n", tnstring);
prtn();
return;
/* HOWEVER, RP really needs to point to a real PRTN
instruction in case prtn faults. Right now, RP points to
ARGT. Maybe use flags in the stackframe header to indicate
that the ARGT should actually prtn instead??
*/
utempa = get16(get32(ea)); /* 1st arg: userid */
if (utempa == ((crs[OWNERL]>>6) & 0xff)) {
ea = ea + 6; /* 3rd arg: length */
tnlen = get16(get32(ea));
ea = get32(ea-3); /* 2nd arg: string */
j = 0;
for (i=0; i<tnlen; i++) {
if (i & 1)
tnchar = tnword & 0x7f;
else {
tnword = get16(ea+i/2);
tnchar = (tnword >> 8) & 0x7f;
}
if (j > sizeof(tnstring)-5)
j = sizeof(tnstring)-5;
if (tnchar >= ' ' && tnchar < 0177)
tnstring[j++] = tnchar;
else {
sprintf((char *)(tnstring+j), "%03o ", tnchar);
j = j+4;
}
}
tnstring[j] = 0;
TRACE(T_TERM, " TNOUx user %d, len %d: %s\n", utempa, tnlen, tnstring);
}
}
#endif
RPL++; /* advance real RP past ARGT after argument transfer */
}
@@ -2476,7 +2517,7 @@ nfy(unsigned short inst) {
utempl = get32r(ea, 0); /* get count and BOL */
scount = utempl>>16; /* count (signed) */
bol = utempl & 0xFFFF; /* beginning of wait list */
TRACE(T_PX, "%o/%o: opcode %o %s, ea=%o/%o, count=%d, bol=%o, I am %o\n", RPH, RPL, inst, nfyname[inst-01200], ea>>16, ea&0xFFFF, scount, bol, crs[OWNERL]);
TRACE(T_PX, "%o/%o: opcode %o %s, ea=%o/%o, count=%d, bol=%o, I am %o\n", RPH, RPL, inst, nfyname[inst-01210], ea>>16, ea&0xFFFF, scount, bol, crs[OWNERL]);
/* on later models, semaphore overflow should cause a fault */
@@ -2581,8 +2622,8 @@ lpsw() {
}
#if 0
/* XXX: hack to disable serial number checking if E32I is enabled.
Look for ERA/ANA sequence after illegal shift instruction, set
the ANA operand to zero. */
Look for ERA/ANA sequence after illegal shift instruction (SSSN),
set the ANA operand to zero. */
ea = MAKEVA(014,040747);
put16(0,ea);
@@ -2592,6 +2633,9 @@ lpsw() {
/* Character instructions */
#define GETFLR(n) (((crsl[FLR0+2*(n)] >> 11) & 0x1FFFE0) | (crsl[FLR0+2*(n)] & 0x1F))
#define PUTFLR(n,v) crsl[FLR0+2*(n)] = (((v) << 11) & 0xFFFF0000) | (crsl[FLR0+2*(n)] & 0xF000) | ((v) & 0x1F);
ldc(n) {
unsigned int utempl;
unsigned short m;
@@ -2617,7 +2661,7 @@ ldc(n) {
//printf(" ldc %d = '%o (%c) from %o/%o right\n", n, crs[A], crs[A]&0x7f, ea>>16, ea&0xffff);
} else {
crs[A] = m >> 8;
crsl[flr] |= 0x8000;
crsl[flr] |= 0x8000; /* set bit offset */
TRACE(T_INST, " ldc %d = '%o (%c) from %o/%o left\n", n, crs[A], crs[A]&0x7f, ea>>16, ea&0xffff);
//printf(" ldc %d = '%o (%c) from %o/%o left\n", n, crs[A], crs[A]&0x7f, ea>>16, ea&0xffff);
}
@@ -2656,13 +2700,13 @@ stc(n) {
m = (m & 0xFF00) | (crs[A] & 0xFF);
put16(m,crsl[far]);
crsl[flr] &= 0xFFFF0FFF;
crsl[far] = (crsl[far] & 0x6FFF0000) | ((crsl[far]+1) & 0xFFFF); \
crsl[far] = (crsl[far] & 0x6FFF0000) | ((crsl[far]+1) & 0xFFFF);
} else {
TRACE(T_INST, " stc %d = '%o (%c) to %o/%o left\n", n, crs[A], crs[A]&0x7f, ea>>16, ea&0xffff);
//printf(" stc %d = '%o (%c) to %o/%o left\n", n, crs[A], crs[A]&0x7f, ea>>16, ea&0xffff);
m = (crs[A] << 8) | (m & 0xFF);
put16(m,crsl[far]);
crsl[flr] |= 0x8000;
crsl[flr] |= 0x8000; /* set bit offset */
}
utempl--;
PUTFLR(n,utempl);
@@ -2740,7 +2784,7 @@ main (int argc, char **argv) {
int bootskip=0; /* skip this many bytes on boot dev */
short tempa,tempa1,tempa2;
unsigned short utempa;
unsigned short utempa,utempa1,utempa2;
int templ,templ1,templ2;
long long templl,templl1, templl2;
unsigned long long utempll, utempll1, utempll2;
@@ -2834,61 +2878,82 @@ main (int argc, char **argv) {
domemdump = 1;
else if (strcmp(argv[i],"-ss") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[i+1],"%o", &templ);
sscanf(argv[++i],"%o", &templ);
sswitch = templ;
} else
sswitch = 0;
} else if (strcmp(argv[i],"-cpuid") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[i+1],"%d", &templ);
sscanf(argv[++i],"%d", &templ);
cpuid = templ;
} else
fprintf(stderr,"-cpuid needs an argument\n");
} else if (strcmp(argv[i],"-tport") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[i+1],"%d", &templ);
sscanf(argv[++i],"%d", &templ);
tport = templ;
} else
fprintf(stderr,"-tport needs an argument\n");
} else if (strcmp(argv[i],"-nport") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[i+1],"%d", &templ);
sscanf(argv[++i],"%d", &templ);
nport = templ;
} else
fprintf(stderr,"-nport needs an argument\n");
} else if (strcmp(argv[i],"-trace") == 0)
while (i+1 < argc && argv[i+1][0] != '-') {
if (strcmp(argv[i+1],"ear") == 0)
traceflags |= TB_EAR;
else if (strcmp(argv[i+1],"eav") == 0)
traceflags |= TB_EAV;
else if (strcmp(argv[i+1],"eai") == 0)
traceflags |= TB_EAI;
else if (strcmp(argv[i+1],"inst") == 0)
traceflags |= TB_INST;
else if (strcmp(argv[i+1],"flow") == 0)
traceflags |= TB_FLOW;
else if (strcmp(argv[i+1],"mode") == 0)
traceflags |= TB_MODE;
else if (strcmp(argv[i+1],"eaap") == 0)
traceflags |= TB_EAAP;
else if (strcmp(argv[i+1],"dio") == 0)
traceflags |= TB_DIO;
else if (strcmp(argv[i+1],"map") == 0)
traceflags |= TB_MAP;
else if (strcmp(argv[i+1],"pcl") == 0)
traceflags |= TB_PCL;
else if (strcmp(argv[i+1],"fault") == 0)
traceflags |= TB_FAULT;
else if (strcmp(argv[i+1],"px") == 0)
traceflags |= TB_PX;
else if (strcmp(argv[i+1],"tio") == 0)
traceflags |= TB_TIO;
else if (strcmp(argv[i+1],"all") == 0)
traceflags = ~0;
else
fprintf(stderr,"Unrecognized trace flag: %s\n", argv[i+1]);
i++;
if (strcmp(argv[i],"ear") == 0)
traceflags |= TB_EAR;
else if (strcmp(argv[i],"eav") == 0)
traceflags |= TB_EAV;
else if (strcmp(argv[i],"eai") == 0)
traceflags |= TB_EAI;
else if (strcmp(argv[i],"inst") == 0)
traceflags |= TB_INST;
else if (strcmp(argv[i],"flow") == 0)
traceflags |= TB_FLOW;
else if (strcmp(argv[i],"mode") == 0)
traceflags |= TB_MODE;
else if (strcmp(argv[i],"eaap") == 0)
traceflags |= TB_EAAP;
else if (strcmp(argv[i],"dio") == 0)
traceflags |= TB_DIO;
else if (strcmp(argv[i],"map") == 0)
traceflags |= TB_MAP;
else if (strcmp(argv[i],"pcl") == 0)
traceflags |= TB_PCL;
else if (strcmp(argv[i],"fault") == 0)
traceflags |= TB_FAULT;
else if (strcmp(argv[i],"px") == 0)
traceflags |= TB_PX;
else if (strcmp(argv[i],"tio") == 0)
traceflags |= TB_TIO;
else if (strcmp(argv[i],"term") == 0)
traceflags |= TB_TERM;
else if (strcmp(argv[i],"all") == 0)
traceflags = ~0;
else if (isdigit(argv[i][0]) && strlen(argv[i]) < 2 && sscanf(argv[i],"%d", &templ) == 1)
traceuser = 0100000 | (templ<<6); /* form OWNERL for user # */
else if (strlen(argv[i]) == 6 && sscanf(argv[i],"%o", &templ) == 1)
traceuser = templ; /* specify OWNERL directly */
else if (strlen(argv[i]) <= 8 && argv[i][0] != '-') {
if (numtraceprocs >= MAXTRACEPROCS)
fprintf(stderr,"Only %d trace procs are allowed\n", MAXTRACEPROCS);
else {
traceprocs[numtraceprocs].oneshot = 1;
for (j=0; argv[i][j]; j++)
if (argv[i][j] == '+')
traceprocs[numtraceprocs].oneshot = 0;
else
traceprocs[numtraceprocs].name[j] = argv[i][j];
traceprocs[numtraceprocs].name[j] = 0;
traceprocs[numtraceprocs].sb = -1;
traceprocs[numtraceprocs].ecb = 0;
numtraceprocs++;
}
} else
fprintf(stderr,"Unrecognized trace flag: %s\n", argv[i]);
}
else if (strcmp(argv[i],"-boot") == 0) {
boot = 1;
@@ -2900,10 +2965,31 @@ main (int argc, char **argv) {
bootarg = argv[i];
}
} else if (argv[i][0] == '-' && argv[i][1] == '-')
} else
fprintf(stderr,"Unrecognized argument: %s\n", argv[i]);
}
/* finish setting up tracing after all options are read, ie, maps */
if (traceuser != 0)
TRACEA("Tracing enabled for OWNERL %o\n", traceuser);
else
TRACEA("Tracing enabled for all users");
savetraceflags = traceflags;
for (i=0; i<numtraceprocs; i++) {
for (j=0; j<numsyms; j++) {
if (strcasecmp(mapsym[j].symname, traceprocs[i].name) == 0 && mapsym[j].symtype == 'e') {
ea = mapsym[j].address;
traceprocs[i].ecb = ea;
TRACEA("Tracing procedure %s ecb ea '%o/%o\n", traceprocs[i].name, SEGNO(ea), ea&0xFFFF);
printf("Tracing procedure %s ecb ea '%o/%o\n", traceprocs[i].name, SEGNO(ea), ea&0xFFFF);
break;
}
}
if (j == numsyms)
fprintf(stderr,"Can't find procedure %s in load maps for tracing.\n", traceprocs[i].name);
}
/* set some vars after the options have been read */
pmap32bits = (cpuid == 15 || cpuid == 18 || cpuid == 19 || cpuid == 24 || cpuid >= 26);
@@ -3039,8 +3125,7 @@ For disk boots, the last 3 digits can be:\n\
newkeys(rvec[6]);
RPL = rvec[2];
if (domemdump)
memdump(rvec[0], rvec[1]);
memdump(rvec[0], rvec[1]);
/* initialize the timer stuff */
@@ -3049,23 +3134,36 @@ For disk boots, the last 3 digits can be:\n\
fatal(NULL);
}
/* main instruction decode loop */
trapaddr = 0144003;
trapvalue = -12345;
trapaddr = 0;
/* faults longjmp here: the top of the instruction fetch loop */
/* main instruction decode loop
faults longjmp here: the top of the instruction fetch loop */
if (setjmp(jmpbuf))
;
while (1) {
#if 0
/* trace AC$SET call not working
NOTE: a 2-word range is needed for RPL because a procedure with
arguments may start executing at the ARGT instruction (listed
in the load map as procedure start), or at the instruction
following ARGT (if PCL completes w/o faults) */
if (TRACEUSER && SEGNO16(RPH) == 041 && 06200 <= RPL && RPL <= 06201) { /* ac$set */
savetraceflags = ~TB_MAP;
printf("enable trace, RPH=%o, RPL=%o\n", SEGNO16(RPH), RPL);
}
if (TRACEUSER && SEGNO16(RPH) == 013 && 044030 <= RPL && RPL <= 044031) { /* setrc$ */
savetraceflags = 0;
printf("disable trace, RPH=%o, RPL=%o\n", SEGNO16(RPH), RPL);
}
#endif
#if 0
/* this is for FTN Generic 3 trace */
if (crs[OWNERL] == 0100100 && RPL >= 034750 && RPL <= 034760)
traceflags = -1;
if (SEGNO16(RPH) == 4000 && RPL >= 034750 && RPL <= 034760)
traceflags = ~TB_MAP;
else
traceflags = 0;
#endif
@@ -3075,20 +3173,6 @@ For disk boots, the last 3 digits can be:\n\
traceflags = ~TB_MAP;
#endif
#if 0
if (traceflags != 0)
savetraceflags = traceflags;
#endif
#if 1
if (traceflags != 0)
savetraceflags = traceflags;
if (crs[OWNERL] == 0100200 && savetraceflags)
traceflags = savetraceflags;
else
traceflags = 0;
#endif
#if 0
/* NOTE: this tends to cause a page fault loop if the location
being monitored isn't wired */
@@ -3105,6 +3189,13 @@ For disk boots, the last 3 digits can be:\n\
}
#endif
/* is this user being traced? */
if (TRACEUSER)
traceflags = savetraceflags;
else
traceflags = 0;
/* poll any devices that requested a poll */
for (i=0; i<64; i++)
@@ -3216,8 +3307,17 @@ For disk boots, the last 3 digits can be:\n\
xec:
/* NOTE: don't trace JMP * instructions (used to test PX) */
#if 0
if (inst == 03777)
traceflags = 0;
#endif
#if 0
if (crs[OWNERL] == 0100200 && inst == 001114 && savetraceflags)
traceflags = ~0;
else
traceflags = 0;
#endif
TRACE(T_FLOW, "\n #%u [%s %o] IT=%d SB: %o/%o LB: %o/%o %s XB: %o/%o\n%o/%o: %o A='%o/%:0d B='%o/%d L='%o/%d E='%o/%d X=%o/%d Y=%o/%d C=%d L=%d LT=%d EQ=%d K=%o M=%o\n", instcount, searchloadmap(*(unsigned int *)(crs+OWNER),'x'), crs[OWNERL], *(short *)(crs+TIMER), crs[SBH], crs[SBL], crs[LBH], crs[LBL], searchloadmap(*(unsigned int *)(crs+LBH),'l'), crs[XBH], crs[XBL], RPH, RPL-1, inst, crs[A], *(short *)(crs+A), crs[B], *(short *)(crs+B), *(unsigned int *)(crs+L), *(int *)(crs+L), *(unsigned int *)(crs+E), *(int *)(crs+E), crs[X], *(short *)(crs+X), crs[Y], *(short *)(crs+Y), (crs[KEYS]&0100000) != 0, (crs[KEYS]&020000) != 0, (crs[KEYS]&0200) != 0, (crs[KEYS]&0100) != 0, crs[KEYS], crs[MODALS]);
@@ -3313,7 +3413,7 @@ xec:
ea = apea(&eabit);
crsl[FAR0] = ea;
crsl[FLR0] = (crsl[FLR0] & 0xFFFF0FFF) | (eabit << 12);
TRACE(T_INST, " FAR0=%o, eabit=%d, FLR=%x\n", crsl[FAR0], eabit, crsl[FLR0]);
TRACE(T_INST, " FAR0=%o/%o, eabit=%d, FLR=%x\n", crsl[FAR0]>>16, crsl[FAR0]&0xFFFF, eabit, crsl[FLR0]);
continue;
case 001310:
@@ -3321,25 +3421,27 @@ xec:
ea = apea(&eabit);
crsl[FAR1] = ea;
crsl[FLR1] = (crsl[FLR1] & 0xFFFF0FFF) | (eabit << 12);
TRACE(T_INST, " FAR1=%o, eabit=%d, FLR=%x\n", crsl[FAR1], eabit, crsl[FLR1]);
TRACE(T_INST, " FAR1=%o/%o, eabit=%d, FLR=%x\n", crsl[FAR1]>>16, crsl[FAR1]&0xFFFF, eabit, crsl[FLR1]);
continue;
case 001301:
TRACE(T_FLOW, " ALFA 0\n");
TRACE(T_INST, " before add, FAR0=%o, FLR=%o\n", crsl[FAR0], crsl[FLR0]);
TRACE(T_INST, " before add, FAR0=%o/%o, FLR=%o\n", crsl[FAR0]>>16, crsl[FAR0]&0xFFFF, crsl[FLR0]);
utempl = ((crsl[FAR0] & 0xFFFF) << 4) | ((crsl[FLR0] >> 12) & 0xF);
utempl += *(int *)(crs+L);
crsl[FAR0] = (crsl[FAR0] & 0xFFFF0000) | ((utempl >> 4) & 0xFFFF);
crsl[FLR0] = (crsl[FLR0] & 0xFFFF0FFF) | ((utempl & 0xF) << 12);
TRACE(T_INST, " after add, FAR0=%o, FLR=%o\n", crsl[FAR0], crsl[FLR0]);
TRACE(T_INST, " after add, FAR0=%o/%o, FLR=%o\n", crsl[FAR0]>>16, crsl[FAR0]&0xFFFF, crsl[FLR0]);
continue;
case 001311:
TRACE(T_FLOW, " ALFA 1\n");
TRACE(T_INST, " before add, FAR1=%o/%o, FLR=%o\n", crsl[FAR1]>>16, crsl[FAR1]&0xFFFF, crsl[FLR1]);
utempl = ((crsl[FAR1] & 0xFFFF) << 4) | ((crsl[FLR1] >> 12) & 0xF);
utempl += *(int *)(crs+L);
crsl[FAR1] = (crsl[FAR1] & 0xFFFF0000) | ((utempl >> 4) & 0xFFFF);
crsl[FLR1] = (crsl[FLR1] & 0xFFFF0FFF) | ((utempl & 0xF) << 12);
TRACE(T_INST, " after add, FAR1=%o/%o, FLR=%o\n", crsl[FAR1]>>16, crsl[FAR1]&0xFFFF, crsl[FLR1]);
continue;
case 001303:
@@ -3433,6 +3535,19 @@ stfa:
case 000611:
TRACE(T_FLOW, " PRTN\n");
prtn();
/* if this PRTN is for a procedure being traced, disable
tracing if one-shot is true */
if (numtraceprocs > 0 && TRACEUSER)
for (i=0; i<numtraceprocs; i++)
if (*(int *)(crs+SB) == traceprocs[i].sb) {
printf("Disabled trace for %s at sb '%o/%o\n", traceprocs[i].name, crs[SBH], crs[SBL]);
savetraceflags = 0;
traceprocs[i].sb = -1;
fflush(tracefile);
break;
}
continue;
case 001005:
@@ -5867,6 +5982,15 @@ keys = 14200, modals=100177
if (crs[KEYS] & 010000) { /* V/I mode */
//traceflags = ~TB_MAP;
//TRACE(T_FLOW|T_PCL, "#%d %o/%o: PCL %o/%o\n", instcount, RPH, RPL-2, ea>>16, ea&0xFFFF);
if (numtraceprocs > 0 && TRACEUSER)
for (i=0; i<numtraceprocs; i++)
if (traceprocs[i].ecb == (ea & 0xFFFFFFF) && traceprocs[i].sb == -1) {
traceflags = ~TB_MAP;
savetraceflags = traceflags;
traceprocs[i].sb = *(int *)(crs+SB);
printf("Enabled trace for %s at sb '%o/%o\n", traceprocs[i].name, crs[SBH], crs[SBL]);
break;
}
TRACE(T_FLOW|T_PCL, " PCL %s\n", searchloadmap(ea, 'e'));
pcl(ea);
} else {
@@ -6974,7 +7098,7 @@ pio(unsigned int inst) {
printf("pio: no handler, class=%d, func='%o, device='%o, A='%o\n", class, func, device, crs[A]);
fatal(NULL);
#else
TRACEA(, "pio: no handler, class=%d, func='%o, device='%o, A='%o\n", class, func, device, crs[A]);
TRACEA("pio: no handler, class=%d, func='%o, device='%o, A='%o\n", class, func, device, crs[A]);
#endif
}
}

12
emdev.h
View File

@@ -384,14 +384,14 @@ readasr:
}
} else if (n == 1) {
if (ch == '') {
traceflags = ~traceflags;
traceflags &= ~TB_MAP;
if (traceflags == 0)
TRACEA("\nTRACE DISABLED:\n\n");
else
if (savetraceflags == 0) {
TRACEA("\nTRACE ENABLED:\n\n");
savetraceflags = ~TB_MAP;;
} else {
TRACEA("\nTRACE DISABLED:\n\n");
savetraceflags = 0;
}
fflush(tracefile);
//memdump(0, 0xFFFF);
goto readasr;
}
if (func >= 010)

11
regs.h
View File

@@ -55,6 +55,17 @@
#define TIMERH 48
#define TIMERL 49
/* I-mode offsets for 16-bit access to registers, eg, crs[GR0H] */
#define GR0H 0
#define GR1H 2
#define GR2H 4
#define GR3H 6
#define GR4H 8
#define GR5H 10
#define GR6H 12
#define GR7H 14
/* these are 32-bit offsets into crsl (current register set long) */
#define GR0 0