1
0
mirror of https://github.com/prirun/p50em.git synced 2026-03-03 17:56:27 +00:00

add access bits to brp.vpn entries, use brp cache for put16 & put32

added get32m & put32m: these always map
changed get32 and put32 to be inlined
changed mem[] references to MEM[] to allow experiments
tried using register for MEM pointer - not so great
tried using register for instcount - screwed up (very sluggish)
This commit is contained in:
Jim
2007-09-12 00:00:00 -04:00
parent 0948124f29
commit e095020a55
3 changed files with 185 additions and 113 deletions

View File

@@ -111,13 +111,13 @@ MRGEN(03503, "JSX", d_jsx);
#define GENIX(inst) ((inst>>4) & 06000) | (inst & 01777)
#define DIGEN(opcode, name, target) \
gvp->disp_gen[GENIX(opcode)] = &⌖ \
disp_gen[GENIX(opcode)] = &⌖ \
//printf("Opcode %06o (%s), ix=%0o\n", opcode, name, GENIX(opcode))
/* initialize entire table to jump to bad generic label */
for (i=0; i < 010000; i++) {
gvp->disp_gen[i] = &&d_badgen;
disp_gen[i] = &&d_badgen;
}
/* initialize class 0 generics (first 2 bits are zero) */
@@ -230,14 +230,14 @@ DIGEN(001324, "MDIW", d_mdxx);
/* initialize class 1 generics (shift group) */
for (i = 02000; i < 04000; i++) {
gvp->disp_gen[i] = &&d_gen1;
disp_gen[i] = &&d_gen1;
}
/* initialize class 2 generics (skip group) */
#if 0
for (i = 04000; i < 06000; i++) {
gvp->disp_gen[i] = &&d_gen2;
disp_gen[i] = &&d_gen2;
}
#endif

282
em.c
View File

@@ -379,7 +379,7 @@ typedef struct {
} iotlbe_t;
/* the emulator uses a special, very small address translation cache
to hold the virtual page address and corresponding mem[] pointer
to hold the virtual page address and corresponding MEM[] pointer
for a few special pages:
- the current instruction page (RPBR)
@@ -419,11 +419,23 @@ typedef struct {
#define UNBR 6
#define BRP_SIZE 7
/* NOTE: vpn is a segment number/word offset Prime virtual address
corresponding to the physical page of memory in memp. The high-
order fault bit of vpn is never set. The ring and extension bits
are used to store the 3-bit access field from the STLB for the
current ring (remember that all brp entries are invalidated by
PCL and PRTN when the ring might change).
Storing the access bits in the vpn allows use of of the brp
supercache for write accesses as well as read accesses. */
typedef struct {
unsigned short *memp; /* mem[] physical page address */
unsigned short *memp; /* MEM[] physical page address */
ea_t vpn; /* corresponding virtual page address */
} brp_t;
void *disp_gen[4096]; /* generic dispatch table */
/* "gv" is a static structure used to hold "hot" global variables. These
are pointed to by a dedicated register, so that the usual PowerPC global
variable instructions aren't needed: these variables can be directly
@@ -431,24 +443,7 @@ typedef struct {
typedef struct {
void *disp_gen[4096]; /* generic dispatch table */
void *disp_mr[128]; /* V/R memory ref dispatch table */
/* traceflags is the variable used to test tracing of each instruction
traceuser is the user number to trace, 0 meaning any user
traceseg is the procedure segment number to trace, 0 meaning any
savetraceflags hold the real traceflags, while "traceflags" switches
on and off for each instruction
TRACEUSER is a macro that is true if the current user is being traced
*/
FILE *tracefile; /* trace.log file */
int traceflags; /* each bit is a trace flag */
int savetraceflags;
int traceuser; /* OWNERL to trace */
int traceseg; /* RPH segment # to trace */
int numtraceprocs; /* # of procedures we're tracing */
unsigned short *physmem; /* pointer to Prime physical memory */
int intvec; /* currently raised interrupt (if >= zero) */
@@ -480,9 +475,29 @@ typedef struct {
int mapvamisses; /* STLB misses */
int supercalls; /* supercache hits */
int supermisses;
void *disp_mr[128]; /* V/R memory ref dispatch table */
/* traceflags is the variable used to test tracing of each instruction
traceuser is the user number to trace, 0 meaning any user
traceseg is the procedure segment number to trace, 0 meaning any
savetraceflags hold the real traceflags, while "traceflags" switches
on and off for each instruction
TRACEUSER is a macro that is true if the current user is being traced
*/
FILE *tracefile; /* trace.log file */
int traceflags; /* each bit is a trace flag */
int savetraceflags;
int traceuser; /* OWNERL to trace */
int traceseg; /* RPH segment # to trace */
int numtraceprocs; /* # of procedures we're tracing */
} gv_t;
static gv_t gv;
#if 1
register gv_t *gvp asm ("r28");
register brp_t *eap asm ("r27"); /* effective address brp pointer */
@@ -508,8 +523,9 @@ static jmp_buf jmpbuf; /* for longjumps to the fetch loop */
#define MAXMB 512
#define MEMSIZE MAXMB/2*1024*1024
#define MEM physmem
static unsigned short mem[MEMSIZE]; /* system's physical memory */
static unsigned short physmem[MEMSIZE]; /* system's physical memory */
static int memlimit; /* user's desired memory limit (-mem) */
#define MAKEVA(seg,word) ((((int)(seg))<<16) | (word))
@@ -766,12 +782,10 @@ char *searchloadmap(int addr, char type) {
0 = PCL (PACC)
2 = read (RACC)
3 = write (WACC) = read+write
4 = execute (XACC)
*/
#define PACC 0
#define RACC 2
#define WACC 3
#define XACC 4
/* NOTE: this is the 6350 STLB hash function, giving a 9-bit index 0-511.
@@ -835,14 +849,14 @@ static pa_t mapva(ea_t ea, ea_t rp, short intacc, unsigned short *access) {
if (relseg >= nsegs)
fault(SEGFAULT, 1, ea); /* fcode = segment too big */
staddr = (dtar & 0x003F0000) | ((dtar & 0x7FFF)<<1);
sdw = *(unsigned int *)(mem+staddr+relseg*2);
sdw = *(unsigned int *)(MEM+staddr+relseg*2);
TRACE(T_MAP," staddr=%o, sdw=%o\n", staddr, sdw);
if (sdw & 0x8000)
fault(SEGFAULT, 2, ea); /* fcode = sdw fault bit set */
ptaddr = (((sdw & 0x3F)<<10) | (sdw>>22)) << 6;
if (gvp->pmap32bits) {
pmaddr = ptaddr + 2*PAGENO(ea);
pte = mem[pmaddr];
pte = MEM[pmaddr];
/* this is probably correct (don't have any references) for
the 53xx and later machines that support more than 128MB of
@@ -851,16 +865,16 @@ static pa_t mapva(ea_t ea, ea_t rp, short intacc, unsigned short *access) {
example). Need to have a mask for each CPU type to make it
technically correct. */
ppn = ((mem[pmaddr] & gvp->pmap32mask) << 16) | mem[pmaddr+1];
ppn = ((MEM[pmaddr] & gvp->pmap32mask) << 16) | MEM[pmaddr+1];
} else {
pmaddr = ptaddr + PAGENO(ea);
pte = mem[pmaddr];
pte = MEM[pmaddr];
ppn = pte & 0xFFF;
}
TRACE(T_MAP," ptaddr=%o, pmaddr=%o, pte=%o\n", ptaddr, pmaddr, pte);
if (!(pte & 0x8000))
fault(PAGEFAULT, 0, ea);
mem[pmaddr] |= 040000; /* set referenced bit */
MEM[pmaddr] |= 040000; /* set referenced bit */
stlbp->access[0] = 7;
stlbp->access[1] = (sdw >> 12) & 7;
stlbp->access[STLB_UNMODIFIED_BIT] = 1;
@@ -868,7 +882,7 @@ static pa_t mapva(ea_t ea, ea_t rp, short intacc, unsigned short *access) {
stlbp->procid = crs[OWNERL];
stlbp->seg = seg;
stlbp->ppn = ppn;
stlbp->pmep = mem+pmaddr;
stlbp->pmep = MEM+pmaddr;
#ifndef NOTRACE
stlbp->load_ic = gvp->instcount;
#endif
@@ -976,9 +990,9 @@ const static unsigned int mapio(ea_t ea) {
/* these are I/O versions of get/put that use the IOTLB rather than
the STLB */
#define get16io(ea) mem[mapio((ea))]
#define get32io(ea) *(unsigned int *)(mem+mapio((ea)))
#define put16io(word,ea) mem[mapio((ea))] = word
#define get16io(ea) MEM[mapio((ea))]
#define get32io(ea) *(unsigned int *)(MEM+mapio((ea)))
#define put16io(word,ea) MEM[mapio((ea))] = word
/* these are shorthand macros for get/put that use the current program
counter - the typical usage - or Ring 0, the other typical case.
@@ -1010,6 +1024,12 @@ const static unsigned int mapio(ea_t ea) {
- in V-mode long instruction address calculation or execution
get16trap handles 16-bit fetches that are KNOWN to be address traps
get16r handles 16-bit fetches that used a passed-in virtual address;
(only the ring part is used from this address).
VERY IMPORTANT: get16r _cannot_ use the supercache! You don't want to
cache Ring 0 accesses to data, then let Ring 3 use the cache!
*/
@@ -1025,26 +1045,26 @@ static inline unsigned short get16(ea_t ea) {
/* idle loop runs faster if this is enabled, but executable is 27K
bigger and programs (ADD) run slower. Maybe inline expansions of
get16 & fastmap are too big for cache (?) */
return mem[fastmap(ea, RP, RACC)];
return MEM[fastmap(ea, RP, RACC)];
#endif
#ifdef FAST
#ifndef NOTRACE
gvp->supercalls++;
#endif
if ((ea & 0x0FFFFC00) == eap->vpn) {
if ((ea & 0x0FFFFC00) == (eap->vpn & 0x0FFFFFFF)) {
TRACE(T_MAP, " get16: supercached %o/%o [%s]\n", ea>>16, ea&0xFFFF, brp_name());
return eap->memp[ea & 0x3FF];
} else {
#ifndef NOTRACE
gvp->supermisses++;
#endif
eap->memp = mem + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
eap->vpn = ea & 0x0FFFFC00;
eap->memp = MEM + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
eap->vpn = (ea & 0x0FFFFC00) | (access << 28);
return eap->memp[ea & 0x3FF];
}
#else
return mem[mapva(ea, RP, RACC, &access)];
return MEM[mapva(ea, RP, RACC, &access)];
#endif
}
@@ -1082,14 +1102,37 @@ static unsigned short get16r(ea_t ea, ea_t rpring) {
warn("address trap in get16r");
#endif
return mem[mapva(ea, rpring, RACC, &access)];
return MEM[mapva(ea, rpring, RACC, &access)];
}
static unsigned int get32(ea_t ea) {
/* get32m always uses the map and isn't inlined */
static unsigned int get32m(ea_t ea) {
pa_t pa;
unsigned short access;
unsigned short m[2];
#if DBG
if (ea & 0x80000000) /* check for live register access */
warn("address trap in get32m");
#endif
#ifndef NOTRACE
gvp->supermisses++;
#endif
if ((ea & 01777) <= 01776) {
eap->memp = MEM + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
eap->vpn = (ea & 0x0FFFFC00) | (access << 28);
return *(unsigned int *)&eap->memp[ea & 0x3FF];
}
return (get16(ea) << 16) | get16(INCVA(ea,1));
}
/* get32 tries to use the supercache and is inlined */
static inline unsigned int get32(ea_t ea) {
pa_t pa;
#if DBG
if (ea & 0x80000000) /* check for live register access */
warn("address trap in get32");
@@ -1100,24 +1143,16 @@ static unsigned int get32(ea_t ea) {
gvp->supercalls++;
#endif
if ((ea & 01777) <= 01776)
if ((ea & 0x0FFFFC00) == eap->vpn) {
if ((ea & 0x0FFFFC00) == (eap->vpn & 0x0FFFFFFF)) {
TRACE(T_MAP, " get32: supercached %o/%o [%s]\n", ea>>16, ea&0xFFFF, brp_name());
return *(unsigned int *)&eap->memp[ea & 0x3FF];
} else {
#ifndef NOTRACE
gvp->supermisses++;
#endif
eap->memp = mem + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
eap->vpn = ea & 0x0FFFFC00;
return *(unsigned int *)&eap->memp[ea & 0x3FF];
}
/* XXX: could see if 1st word is supercached -- painful! */
return (get16(ea) << 16) | get16(INCVA(ea,1));
return get32m(ea);
#else
pa = mapva(ea, RP, RACC, &access);
if ((ea & 01777) <= 01776)
return *(unsigned int *)(mem+pa);
return (mem[pa] << 16) | get16(INCVA(ea,1));
return *(unsigned int *)(MEM+pa);
return (MEM[pa] << 16) | get16(INCVA(ea,1));
#endif
}
@@ -1133,8 +1168,8 @@ static unsigned int get32r(ea_t ea, ea_t rpring) {
pa = mapva(ea, rpring, RACC, &access);
if ((pa & 01777) <= 01776)
return *(unsigned int *)(mem+pa);
return (mem[pa] << 16) | get16r(INCVA(ea,1), rpring);
return *(unsigned int *)(MEM+pa);
return (MEM[pa] << 16) | get16r(INCVA(ea,1), rpring);
}
static long long get64r(ea_t ea, ea_t rpring) {
@@ -1152,36 +1187,36 @@ static long long get64r(ea_t ea, ea_t rpring) {
pa = mapva(ea, rpring, RACC, &access);
#if FAST
if ((ea & 01777) <= 01774) { /* no page wrap */
*(int *)(m+0) = *(int *)(mem+pa);
*(int *)(m+2) = *(int *)(mem+pa+2);
*(int *)(m+0) = *(int *)(MEM+pa);
*(int *)(m+2) = *(int *)(MEM+pa+2);
} else /* wraps page (maybe seg too) */
switch (ea & 3) {
case 1:
m[0] = mem[pa];
*(int *)(m+1) = *(int *)(mem+pa+1);
m[0] = MEM[pa];
*(int *)(m+1) = *(int *)(MEM+pa+1);
pa = mapva(INCVA(ea,3), rpring, RACC, &access);
m[3] = mem[pa];
m[3] = MEM[pa];
break;
case 2:
*(int *)(m+0) = *(int *)(mem+pa);
*(int *)(m+0) = *(int *)(MEM+pa);
pa = mapva(INCVA(ea,2), rpring, RACC, &access);
*(int *)(m+2) = *(int *)(mem+pa);
*(int *)(m+2) = *(int *)(MEM+pa);
break;
case 3:
m[0] = mem[pa];
m[0] = MEM[pa];
pa = mapva(INCVA(ea,1), rpring, RACC, &access);
*(int *)(m+1) = *(int *)(mem+pa);
m[3] = mem[pa+2];
*(int *)(m+1) = *(int *)(MEM+pa);
m[3] = MEM[pa+2];
break;
default:
fatal("Page cross error in get64r");
}
#else
if ((pa & 01777) <= 01774) { /* no page wrap */
*(int *)(m+0) = *(int *)(mem+pa);
*(int *)(m+2) = *(int *)(mem+pa+2);
*(int *)(m+0) = *(int *)(MEM+pa);
*(int *)(m+2) = *(int *)(MEM+pa+2);
} else {
m[0] = mem[pa];
m[0] = MEM[pa];
m[1] = get16r(INCVA(ea,1), rpring);
m[2] = get16r(INCVA(ea,2), rpring);
m[3] = get16r(INCVA(ea,3), rpring);
@@ -1216,8 +1251,8 @@ unsigned short iget16t(ea_t ea) {
unsigned short access;
if (*(int *)&ea > 0) {
gvp->brp[RPBR].vpn = ea & 0x0FFFFC00;
gvp->brp[RPBR].memp = mem + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
gvp->brp[RPBR].memp = MEM + (mapva(ea, RP, RACC, &access) & 0xFFFFFC00);
gvp->brp[RPBR].vpn = (ea & 0x0FFFFC00) | (access << 28);
return gvp->brp[RPBR].memp[ea & 0x3FF];
}
return get16trap(ea);
@@ -1226,7 +1261,7 @@ unsigned short iget16t(ea_t ea) {
static inline unsigned short iget16(ea_t ea) {
unsigned short access;
if ((ea & 0x8FFFFC00) == gvp->brp[RPBR].vpn)
if ((ea & 0x8FFFFC00) == (gvp->brp[RPBR].vpn & 0x0FFFFFFF))
return gvp->brp[RPBR].memp[ea & 0x3FF];
else
return iget16t(ea);
@@ -1247,15 +1282,26 @@ static inline put16(unsigned short value, ea_t ea) {
#ifdef FAST
/* there is no access stored in the supercache, so writes
always have to go through mapva, but the cache is updated
so that the next read might avoid mapva */
#ifndef NOTRACE
gvp->supercalls++;
#endif
eap->memp = mem + (mapva(ea, RP, WACC, &access) & 0xFFFFFC00);
eap->vpn = ea & 0x0FFFFC00;
eap->memp[ea & 0x3FF] = value;
/* access bits are stored in bits 2-4 of the supercache vpn.
write access is indicated by bit 4 (MSB = bit 1) */
if ((ea & 0x0FFFFC00) == (eap->vpn & 0x0FFFFFFF) && (eap->vpn & 0x10000000)) {
TRACE(T_MAP, " put16: supercached %o/%o [%s]\n", ea>>16, ea&0xFFFF, brp_name());
eap->memp[ea & 0x3FF] = value;
} else {
#ifndef NOTRACE
gvp->supermisses++;
#endif
eap->memp = MEM + (mapva(ea, RP, WACC, &access) & 0xFFFFFC00);
eap->vpn = (ea & 0x0FFFFC00) | (access << 28);
eap->memp[ea & 0x3FF] = value;
}
#else
mem[mapva(ea, RP, WACC, &access)] = value;
MEM[mapva(ea, RP, WACC, &access)] = value;
#endif
}
@@ -1267,7 +1313,7 @@ static put16r(unsigned short value, ea_t ea, ea_t rpring) {
warn("address trap in put16r");
#endif
mem[mapva(ea, rpring, WACC, &access)] = value;
MEM[mapva(ea, rpring, WACC, &access)] = value;
}
/* put16t handles stores that ARE address traps */
@@ -1318,14 +1364,36 @@ static put32(unsigned int value, ea_t ea) {
warn("address trap in put32");
#endif
#ifdef FAST
#ifndef NOTRACE
gvp->supercalls++;
#endif
if ((ea & 01777) <= 01776) {
if ((ea & 0x0FFFFC00) == (eap->vpn & 0x0FFFFFFF) && (eap->vpn & 0x10000000)) {
TRACE(T_MAP, " put32: supercached %o/%o [%s]\n", ea>>16, ea&0xFFFF, brp_name());
*(unsigned int *)&eap->memp[ea & 0x3FF] = value;
} else {
#ifndef NOTRACE
gvp->supermisses++;
#endif
eap->memp = MEM + (mapva(ea, RP, WACC, &access) & 0xFFFFFC00);
eap->vpn = (ea & 0x0FFFFC00) | (access << 28);
*(unsigned int *)&eap->memp[ea & 0x3FF] = value;
}
} else {
put16(value >> 16, ea);
put16(value & 0xFFFF, INCVA(ea,1));
}
#else
pa = mapva(ea, RP, WACC, &access);
if ((pa & 01777) <= 01776)
*(unsigned int *)(mem+pa) = value;
*(unsigned int *)(MEM+pa) = value;
else {
m = (void *)&value;
mem[pa] = m[0];
MEM[pa] = m[0];
put16(m[1], INCVA(ea,1));
}
#endif
}
static put32r(unsigned int value, ea_t ea, ea_t rpring) {
@@ -1340,10 +1408,10 @@ static put32r(unsigned int value, ea_t ea, ea_t rpring) {
pa = mapva(ea, rpring, WACC, &access);
if ((pa & 01777) <= 01776)
*(unsigned int *)(mem+pa) = value;
*(unsigned int *)(MEM+pa) = value;
else {
m = (void *)&value;
mem[pa] = m[0];
MEM[pa] = m[0];
put16r(m[1], INCVA(ea,1), rpring);
}
}
@@ -1362,10 +1430,10 @@ static put64r(long long value, ea_t ea, ea_t rpring) {
pa = mapva(ea, rpring, WACC, &access);
if ((pa & 01777) <= 01774)
*(long long *)(mem+pa) = value;
*(long long *)(MEM+pa) = value;
else {
m = (void *)&value;
mem[pa] = m[0];
MEM[pa] = m[0];
put16r(m[1], INCVA(ea,1), rpring);
put16r(m[2], INCVA(ea,2), rpring);
put16r(m[3], INCVA(ea,3), rpring);
@@ -1444,7 +1512,7 @@ static int rtq(ea_t qcbea, unsigned short *qent, ea_t rp) {
else {
RESTRICTR(rp);
/* XXX: this should probably go through mapio */
*qent = mem[qentea];
*qent = MEM[qentea];
}
qtop = (qtop & ~qmask) | ((qtop+1) & qmask);
put16r(qtop & 0xFFFF, qcbea, rp);
@@ -1471,7 +1539,7 @@ static int abq(ea_t qcbea, unsigned short qent, ea_t rp) {
else {
RESTRICTR(rp);
/* XXX: this should probably go through mapio */
mem[qentea] = qent;
MEM[qentea] = qent;
}
put16r(qtemp, qcbea+1, rp);
return 1;
@@ -2124,15 +2192,15 @@ static memdump(int start, int end) {
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]);
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]);
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]);
}
}
@@ -2150,7 +2218,7 @@ static dumpsegs() {
TRACEA("DTAR %d: register=%o, size=%d, seg table addr=%o\n", i, dtar, nsegs, staddr);
for (seg=0; seg<nsegs; seg++) {
segno = (i<<10)+seg;
sdw = *(unsigned int *)(mem+staddr);
sdw = *(unsigned int *)(MEM+staddr);
ptaddr = ((sdw & 0x3F)<<10) | (sdw>>22);
TRACEA("Segment '%o: F=%d, R1:%o R3:%o PT = %o\n", segno, (sdw>>15)&1, (sdw>>12)&7, (sdw>>6)&7, ptaddr);
xxx = (sdw>>16)&0x3F;
@@ -2158,7 +2226,7 @@ static dumpsegs() {
if (ptaddr != 0)
for (page=0; page<64; page++) {
pmaddr = (ptaddr<<6) + page;
pte = mem[pmaddr];
pte = MEM[pmaddr];
TRACEA(" Seg %o page %d: pmaddr=%o, V=%d R=%d U=%d S=%d PPA=%o\n", segno, page, pmaddr, pte>>15, (pte>>14)&1, (pte>>13)&1, (pte>>12)&1, pte&0xFFF);
}
staddr += 2;
@@ -2493,9 +2561,9 @@ static pcl (ea_t ecbea) {
invalidate_brp();
if ((ecbea & 0xF) != 0)
fault(ACCESSFAULT, 0, ecbea);
memcpy(ecb,mem+pa,sizeof(ecb));
memcpy(ecb,MEM+pa,sizeof(ecb));
} else if ((pa & 01777) <= 01750) {
memcpy(ecb,mem+pa,sizeof(ecb));
memcpy(ecb,MEM+pa,sizeof(ecb));
} else {
*(long long *)(ecb+0) = get64(ecbea+0);
*(long long *)(ecb+4) = get64(ecbea+4);
@@ -3880,12 +3948,11 @@ main (int argc, char **argv) {
/* initialize global variables */
if (sizeof(gv) > 16*1024)
printf("em: size of global vars = %d\n", sizeof(gv));
gvp = &gv;
gvp->traceflags = 0;
gvp->savetraceflags = 0;
gvp->traceuser = 0;
gvp->traceseg = 0;
gvp->numtraceprocs = 0;
gvp->physmem = physmem;
gvp->intvec = -1;
gvp->instcount = 0;
gvp->inhcount = 0;
@@ -3895,6 +3962,11 @@ main (int argc, char **argv) {
gvp->mapvamisses = 0;
gvp->supercalls = 0;
gvp->supermisses = 0;
gvp->traceflags = 0;
gvp->savetraceflags = 0;
gvp->traceuser = 0;
gvp->traceseg = 0;
gvp->numtraceprocs = 0;
invalidate_brp();
eap = &gvp->brp[0];
@@ -3952,7 +4024,7 @@ main (int argc, char **argv) {
gvp->stlb[i].seg = 0xFFFF; /* marker for invalid STLB entry */
for (i=0; i < IOTLBENTS; i++)
gvp->iotlb[i].valid = 0;
bzero(mem, 64*1024*2); /* zero first 64K words */
bzero(MEM, 64*1024*2); /* zero first 64K words */
verbose = 0;
domemdump = 0;
@@ -4230,7 +4302,7 @@ For disk boots, the last 3 digits can be:\n\
/* read memory image from SA to EA inclusive */
nw = rvec[1]-rvec[0]+1;
if ((nw2=read(bootfd, mem+rvec[0], nw*2)) == -1) {
if ((nw2=read(bootfd, MEM+rvec[0], nw*2)) == -1) {
perror("Error reading memory image");
fatal(NULL);
}
@@ -4513,7 +4585,7 @@ xec:
if ((inst & 036000) == 0) {
TRACE(T_INST, " generic class %d\n", inst>>14);
goto *gvp->disp_gen[GENIX(inst)];
goto *disp_gen[GENIX(inst)];
}
/* get x bit and adjust opcode so that PMA manual opcode
@@ -4887,7 +4959,7 @@ d_calf: /* 000705 */
*/
#define ZSTEP(zea, zlen, zcp, zclen, zacc) \
zcp = (unsigned char *) (mem+mapva(zea, RP, zacc, &zaccess)); \
zcp = (unsigned char *) (MEM+mapva(zea, RP, zacc, &zaccess)); \
zclen = 2048 - (zea & 01777)*2; \
if (zea & EXTMASK32) { \
zcp++; \
@@ -8897,7 +8969,7 @@ d_irs: /* 01200 */
stopwatch_push(&sw_irs);
TRACE(T_FLOW, " IRS\n");
if (*(int *)&ea >= 0)
utempa = ++mem[mapva(ea, RP, WACC, &access)];
utempa = ++MEM[mapva(ea, RP, WACC, &access)];
else {
utempa = get16t(ea) + 1;
put16t(utempa, ea);
@@ -8911,8 +8983,8 @@ d_ima: /* 01300 */
TRACE(T_FLOW, " IMA\n");
if (*(int *)&ea >= 0) {
pa = mapva(ea, RP, WACC, &access);
utempa = mem[pa];
mem[pa] = crs[A];
utempa = MEM[pa];
MEM[pa] = crs[A];
} else {
utempa = get16t(ea);
put16t(crs[A],ea);

View File

@@ -1513,7 +1513,7 @@ int devcp (int class, int func, int device) {
if (gvp->instcount-previnstcount > gvp->instpermsec*1000*5) {
gvp->instpermsec = (gvp->instcount-previnstcount) /
((tv.tv_sec-prev_tv.tv_sec-1)*1000 + (tv.tv_usec+1000000-prev_tv.tv_usec)/1000);
//printf("instcount = %d, previnstcount = %d, diff=%d, instpermsec=%d\n", gvp->instcount, previnstcount, gvp->instcount-previnstcount, gvp->instpermsec);
//printf("gvp->instcount = %d, previnstcount = %d, diff=%d, instpermsec=%d\n", gvp->instcount, previnstcount, gvp->instcount-previnstcount, gvp->instpermsec);
#ifdef NOIDLE
printf("\ninstpermsec=%d\n", gvp->instpermsec);
#endif
@@ -1909,9 +1909,9 @@ int devdisk (int class, int func, int device) {
if ((dmaaddr & 01777) || dmanw > 1024)
iobufp = iobuf;
else
iobufp = mem+mapio(dmaaddr);
iobufp = MEM+mapio(dmaaddr);
else
iobufp = mem+dmaaddr;
iobufp = MEM+dmaaddr;
if (hashp != NULL) {
memcpy((char *)iobufp, hashp, dmanw*2);
hashp += dmanw*2;
@@ -1929,7 +1929,7 @@ int devdisk (int class, int func, int device) {
for (i=0; i<dmanw; i++)
iobuf[i] = get16io(dmaaddr+i);
} else
iobufp = mem+dmaaddr;
iobufp = MEM+dmaaddr;
if (hashp != NULL) {
memcpy(hashp, (char *)iobufp, dmanw*2);
hashp += dmanw*2;