1
0
mirror of https://github.com/prirun/p50em.git synced 2026-03-10 12:18:24 +00:00

New ea64v, missing memory check, #ifdef FAST

This commit is contained in:
Jim
2007-09-02 00:00:00 -04:00
parent 0ea78958b0
commit fdb4d4ae4c
3 changed files with 127 additions and 70 deletions

70
ea64v.h
View File

@@ -17,7 +17,10 @@ static inline ea_t ea64v (ea_t earp, unsigned short inst, short x, unsigned shor
unsigned short m;
unsigned short rph,rpl;
i = inst & 0100000; /* indirect is bit 1 (left/MS bit) */
if (crs[MODALS] & 4) /* segmentation enabled? */
live = 010; /* yes, limit register traps */
else
live = 040;
/* rph/rpl (and earp) are usually = RPH/RPL in the register file,
except for the case of an XEC instruction; in that case, these
@@ -27,12 +30,40 @@ static inline ea_t ea64v (ea_t earp, unsigned short inst, short x, unsigned shor
rpl = earp & 0xFFFF;
//TRACE(T_EAV, " inst=%o, rph=%o, rpl=%o\n", inst, rph, rpl);
if (crs[MODALS] & 4) /* segmentation enabled? */
live = 010; /* yes, limit register traps */
else
live = 040;
ea_s = rph;
/* first check for direct short-form - the most commonly occurring case */
if ((inst & 0101000) == 0) {
ea_w = (inst & 0777);
if (x) {
TRACE(T_EAV, " Postindex, old ea_w=%o, X='%o/%d\n", ea_w, crs[X], *(short *)(crs+X));
ea_w += crs[X];
TRACE(T_EAV, " Postindex, new ea_w=%o\n", ea_w);
}
if (inst & 0400) {
TRACE(T_EAV, " Short LB relative, LB=%o/%o\n", crs[LBH], crs[LBL]);
#if 1
ea_s = crs[LBH] | (ea_s & RINGMASK16);
ea_w += crs[LBL];
return MAKEVA(ea_s, ea_w);
#else
ea_w += crs[LBL];
return (((*(int *)(crs+LBH) | (earp & RINGMASK32)) & 0xFFFF0000) | ea_w);
#endif;
}
if (ea_w >= live) {
ea_s = crs[SBH] | (ea_s & RINGMASK16);
ea_w += crs[SBL];
TRACE(T_EAV, " Short SB relative, SB=%o/%o\n", crs[SBH], crs[SBL]);
return MAKEVA(ea_s, ea_w);
}
TRACE(T_EAV, " Live register '%o\n", ea_w);
return 0x80000000 | ea_w;
}
i = inst & 0100000; /* indirect is bit 1 (left/MS bit) */
if (inst & 001000) /* sector bit 7 set? */
if ((inst & 0740) != 0400) { /* PC relative? */
ea_w = rpl + (((short) (inst << 7)) >> 7); /* yes, sign extend D */
@@ -50,7 +81,7 @@ static inline ea_t ea64v (ea_t earp, unsigned short inst, short x, unsigned shor
x = 0;
}
} else
goto labA;
fatal("goto labA?");
if (i) {
if (ea_w < live) {
@@ -75,34 +106,11 @@ static inline ea_t ea64v (ea_t earp, unsigned short inst, short x, unsigned shor
return 0x80000000 | ea_w;
labA:
ea_w = (inst & 0777);
if (x) {
TRACE(T_EAV, " Postindex, old ea_w=%o, X='%o/%d\n", ea_w, crs[X], *(short *)(crs+X));
ea_w += crs[X];
TRACE(T_EAV, " Postindex, new ea_w=%o\n", ea_w);
}
if ((inst & 0777) >= 0400) {
ea_s = crs[LBH] | (ea_s & RINGMASK16);
ea_w += crs[LBL];
TRACE(T_EAV, " Short LB relative, LB=%o/%o\n", crs[LBH], crs[LBL]);
return MAKEVA(ea_s, ea_w);
}
if (ea_w >= live) {
ea_s = crs[SBH] | (ea_s & RINGMASK16);
ea_w += crs[SBL];
TRACE(T_EAV, " Short SB relative, SB=%o/%o\n", crs[SBH], crs[SBL]);
return MAKEVA(ea_s, ea_w);
}
TRACE(T_EAV, " Live register '%o\n", ea_w);
return 0x80000000 | ea_w;
/* here for long, 2-word, V-mode memory reference */
labB:
a = iget16(RP);
RPL++;
INCRP;
TRACE(T_EAV, " 2-word format, a=%o\n", a);
y = (inst & 020);
ixy = ((i != 0)<<2) | ((x != 0)<<1) | (y != 0);

99
em.c
View File

@@ -98,6 +98,7 @@ OK:
#include <setjmp.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
/* In SR modes, Prime CPU registers are mapped to memory locations
0-'37, but only 0-7 are user accessible. In the post-P300
@@ -121,6 +122,7 @@ typedef unsigned int pa_t; /* physical address */
static void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) __attribute__ ((noreturn));
static void fatal(char *msg) __attribute__ ((noreturn));
static void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int dswstat, unsigned int dswrma) __attribute__ ((noreturn));
/* condition code macros */
@@ -454,7 +456,7 @@ static int memlimit; /* user's desired memory limit (-mem) */
increment on RP (segment gets incremented too)!
*/
#if FAST
#ifdef FAST
#define RPADD(n) (RP+n)
#define INCRP RP++
#else
@@ -777,17 +779,23 @@ static pa_t mapva(ea_t ea, ea_t rp, short intacc, unsigned short *access) {
pa = (stlbp->ppn << 10) | (ea & 0x3FF);
TRACE(T_MAP," for ea %o/%o, stlbix=%d, pa=%o loaded at #%d\n", ea>>16, ea&0xffff, stlbix, pa, stlbp->load_ic);
} else {
/* XXX: this test looks bogus and should be removed, but causes boot failures related to disk I/O if removed */
pa = ea & (MEMSIZE-1);
pa = ea;
}
stopwatch_pop(&sw_mapva);
#if DBG
#ifndef FAST
if (pa < memlimit)
#endif
return pa;
printf(" map: Memory address '%o (%o/%o) is out of range 0-'%o!\n", ea, ea>>16, ea & 0xffff, memlimit-1);
fatal(NULL);
/* NOTE: could also take a missing memory check here... */
#if DBG
printf(" map: Memory address '%o (%o/%o) is out of range 0-'%o (%o/%o) at #%d!\n", pa, pa>>16, pa & 0xffff, memlimit-1, (memlimit-1)>>16, (memlimit-1) & 0xffff, gvp->instcount);
#endif
/* take a missing memory check
XXX: not sure if dswstat and dswrma are right, but Primos doesn't
seem to look at them for this check */
macheck(071, 0310, 0xd000, pa);
fatal("Return from macheck");
}
/* for I/O, ea is either an 18-bit physical address (which is just
@@ -810,6 +818,7 @@ static unsigned int mapio(ea_t ea) {
return ea;
}
/* these are I/O versions of get/put that use the IOTLB rather than
the STLB */
@@ -1147,6 +1156,39 @@ static put64r(long long value, ea_t ea, ea_t rpring) {
}
}
/* machine check handler, called with check vector locations
The first arg is used when PX is disabled, the 2nd when PX is enabled. */
void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int dswstat, unsigned int dswrma) {
unsigned short m;
/* set check registers in the register file */
regs.sym.dswpb = RP;
regs.sym.dswstat = dswstat;
regs.sym.dswrma = dswrma;
/* if process exchange is enabled, follow the standard check protocol;
if PX not enabled, simulate JST p300vec,* to invoke the check.
Then longjmp back to the fetch loop */
if (crs[MODALS] & 010) {
printf(" map: missing memory while PX enabled\n");
} else {
m = get16(p300vec);
put16(RPL, m);
RP = m+1;
}
/* similar code in the fault handler */
grp = RP;
gcrsl = crsl;
longjmp(jmpbuf, 1);
fatal("macheck: returned after longjmp\n");
}
static warn(char *msg) {
printf("emulator warning:\n instruction #%d at %o/%o: %o %o keys=%o, modals=%o\n %s\n", gvp->instcount, gvp->prevpc >> 16, gvp->prevpc & 0xFFFF, get16(gvp->prevpc), get16(gvp->prevpc+1),crs[KEYS], crs[MODALS], msg);
}
@@ -1517,7 +1559,8 @@ static void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
}
}
/* on longjmp, register globals are reset (PPC); save them before jumping */
/* on longjmp, register globals are reset (PPC); save them before jumping
See also macheck */
grp = RP;
gcrsl = crsl;
@@ -2301,7 +2344,7 @@ static pcl (ea_t ecbea) {
/* load new execution state from ecb */
TRACE(T_PCL, " before update, stackfp=%o/%o, SB=%o/%o\n", stackfp>>16, stackfp&0xFFFF, crs[SBH], crs[SBL]);
if (access == 1)
if (access == 1) /* for gate access, don't weaken ring */
*(unsigned int *)(crs+SB) = stackfp;
else
*(unsigned int *)(crs+SB) = (stackfp & ~RINGMASK32) | (RP & RINGMASK32);
@@ -2311,12 +2354,16 @@ static pcl (ea_t ecbea) {
/* update the stack free pointer; this has to wait until after all
memory accesses, in case of stack page faults (PCL restarts).
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. */
pointer if the extension pointer was followed. Try setting EHDB
to suppress this spurious DIAG error. */
ea = MAKEVA(stackrootseg,0) | (newrp & RINGMASK32);
put32r((stackfp+stacksize) & ~RINGMASK32, ea, newrp);
if (cpuid == 15)
put32r(stackfp+stacksize, ea, newrp);
else
put32r((stackfp+stacksize) & ~RINGMASK32, ea, newrp);
/* transfer arguments if arguments are expected. There is no
documentation explaining how the Y register is used during
@@ -3727,6 +3774,7 @@ main (int argc, char **argv) {
fatal("-cpuid arg range is 0 to 44\n");
} else
fatal("-cpuid needs an argument\n");
#ifndef FAST
} else if (strcmp(argv[i],"-mem") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[++i],"%d", &templ);
@@ -3736,6 +3784,7 @@ main (int argc, char **argv) {
fatal("-mem arg range is 1 to 1024 (megabytes)\n");
} else
fatal("-mem needs an argument\n");
#endif
} else if (strcmp(argv[i],"-tport") == 0) {
if (i+1 < argc && argv[i+1][0] != '-') {
sscanf(argv[++i],"%d", &templ);
@@ -4028,7 +4077,7 @@ For disk boots, the last 3 digits can be:\n\
fetch:
#if 0
if (gvp->instcount > 20500000)
if (gvp->instcount > 32727500)
gvp->savetraceflags = ~0;
#endif
@@ -5561,7 +5610,7 @@ d_bdy: /* 0140724 */
d_bdx: /* 0140734 */
TRACE(T_FLOW, " BDX\n");
crs[X]--;
#if 1
#if 0
m = iget16(RP);
if (crs[X] > 100 && m == RPL-1) {
struct timeval tv0,tv1;
@@ -8610,7 +8659,17 @@ nonimode:
stopwatch_push(&sw_cas);
m = get16t(ea);
TRACE(T_FLOW, " CAS ='%o/%d\n", m, *(short *)&m);
#if 1
#ifdef FAST
CLEARCC;
if (crs[A] == m) {
INCRP;
SETEQ;
} else if (*(short *)(crs+A) < *(short *)&m) {
RPL += 2;
SETLT;
}
XSETL(0);
#else
crs[KEYS] &= ~020300; /* clear L, and CC */
utempa = crs[A];
utempl = crs[A];
@@ -8631,16 +8690,6 @@ nonimode:
INCRP;
else if (*(short *)(crs+A) < *(short *)&m)
RPL += 2;
#else
CLEARCC;
if (crs[A] == m) {
INCRP;
SETEQ;
} else if (*(short *)(crs+A) < *(short *)&m) {
RPL += 2;
SETLT;
}
XSETL(0);
#endif
stopwatch_pop(&sw_cas);
goto fetch;

28
regs.h
View File

@@ -104,20 +104,20 @@ static union {
/* symbolic register file locations */
struct {
unsigned int tr0,tr1,tr2,tr3,tr4,tr5,tr6,tr7;
unsigned int rdmx1,rdmx2;
unsigned short rdum1[1],ratmpl;
unsigned int rsgt1,rsgt2,recc1,recc2;
unsigned short rdum2[1],reoiv,zero,one;
unsigned int pbsave,rdmx3,rdmx4,c377,rdum3[3];
unsigned int pswpb;
unsigned short pswkeys,rdum4[1];
unsigned short pla,pcba,plb,pcbb;
unsigned int dswrma;
unsigned int dswstat;
unsigned int dswpb,rsavptr;
unsigned short regdmx[64];
unsigned int userregs[REGSETS-2][32];
unsigned int tr0,tr1,tr2,tr3,tr4,tr5,tr6,tr7; /* '0-7 */
unsigned int rdmx1,rdmx2; /* '10-11 */
unsigned short rdum1[1],ratmpl; /* '12 */
unsigned int rsgt1,rsgt2,recc1,recc2; /* '13-16 */
unsigned short rdum2[1],reoiv,zero,one; /* '17-20 */
unsigned int pbsave,rdmx3,rdmx4,c377,rdum3[3]; /* '21-27 */
unsigned int pswpb; /* '30 */
unsigned short pswkeys,rdum4[1]; /* '31 */
unsigned short pla,pcba,plb,pcbb; /* '32-33 */
unsigned int dswrma; /* '34 */
unsigned int dswstat; /* '35 */
unsigned int dswpb,rsavptr; /* '36-37 */
unsigned short regdmx[64]; /* '40-77 */
unsigned int userregs[REGSETS-2][32]; /* '100- */
} sym;
} regs;