1
0
mirror of https://github.com/prirun/p50em.git synced 2026-03-30 18:54:45 +00:00

3 Commits

Author SHA1 Message Date
Dennis Boone
64c5970e97 Added tracing for floating point operations. 2021-12-13 14:02:01 -05:00
Dennis Boone
c6c0344004 Additional #ifdef __APPLE__ sections removed
Some DTR handling was still inside of such #ifdefs, and thus
I was unable to make a modem work on a serial port.  I believe
this code is portable to OSX, Linux, FreeBSD, and Solaris.
2021-09-05 16:40:13 -04:00
Dennis Boone
0466b4b603 Emit mark parity space(s) in the "less than three" case, not space
parity ones.  Discovered by Daiyu.
2021-07-27 14:59:27 -04:00
4 changed files with 96 additions and 36 deletions

View File

@@ -150,6 +150,8 @@ AMLC status word (from AMLCT5):
*/ */
#include <termio.h>
/* this macro closes an AMLC connection - used in several places /* this macro closes an AMLC connection - used in several places
NOTE: don't print disconnect message on dedicated lines */ NOTE: don't print disconnect message on dedicated lines */
@@ -559,7 +561,7 @@ int devamlc (int class, int func, int device) {
if (dc[dx].serial) { /* any serial connections? */ if (dc[dx].serial) { /* any serial connections? */
if (--dc[dx].dsstime == 0) { if (--dc[dx].dsstime == 0) {
dc[dx].dsstime = DSSCOUNTDOWN; dc[dx].dsstime = DSSCOUNTDOWN;
#ifdef __APPLE__ /* #ifdef __APPLE__ */
for (lx = 0; lx < 16; lx++) { /* yes, poll them */ for (lx = 0; lx < 16; lx++) { /* yes, poll them */
if (dc[dx].ctype[lx] == CT_SERIAL) { if (dc[dx].ctype[lx] == CT_SERIAL) {
int modemstate; int modemstate;
@@ -575,7 +577,7 @@ int devamlc (int class, int func, int device) {
} }
} }
} }
#endif /* #endif */
} }
} }
//printf("devamlc: dss for device '%o = 0x%x\n", device, dc[dx].dss); //printf("devamlc: dss for device '%o = 0x%x\n", device, dc[dx].dss);
@@ -758,7 +760,6 @@ int devamlc (int class, int func, int device) {
/* set DTR high (02000) or low if it has changed */ /* set DTR high (02000) or low if it has changed */
#ifdef __APPLE__
if ((getcrs16(A) ^ dc[dx].lconf[lx]) & 02000) { if ((getcrs16(A) ^ dc[dx].lconf[lx]) & 02000) {
int modemstate; int modemstate;
//printf("devamlc: DTR state changed\n"); //printf("devamlc: DTR state changed\n");
@@ -771,7 +772,6 @@ int devamlc (int class, int func, int device) {
} }
ioctl(fd, TIOCMSET, &modemstate); ioctl(fd, TIOCMSET, &modemstate);
} }
#endif
break; break;
} }

4
em.c
View File

@@ -274,6 +274,7 @@ static void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int
T_EAV trace V-mode effective address calculation T_EAV trace V-mode effective address calculation
T_EAI trace I-mode effective address calculation T_EAI trace I-mode effective address calculation
T_FLOW instruction summary T_FLOW instruction summary
T_FP floating point
T_INST detailed instruction trace T_INST detailed instruction trace
T_MODE trace CPU mode changes T_MODE trace CPU mode changes
T_EAAP AP effective address calculation T_EAAP AP effective address calculation
@@ -311,6 +312,7 @@ static void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int
#define T_EAS 0x00040000 #define T_EAS 0x00040000
#define T_TLB 0x00080000 #define T_TLB 0x00080000
#define T_SMLC 0x00100000 #define T_SMLC 0x00100000
#define T_FP 0x00200000
#define BITMASK16(b) (0x8000 >> ((b)-1)) #define BITMASK16(b) (0x8000 >> ((b)-1))
#define BITMASK32(b) ((unsigned int)(0x80000000) >> ((b)-1)) #define BITMASK32(b) ((unsigned int)(0x80000000) >> ((b)-1))
@@ -4618,6 +4620,8 @@ int main (int argc, char **argv) {
gv.traceflags |= T_TLB; gv.traceflags |= T_TLB;
else if (strcmp(argv[i],"smlc") == 0) else if (strcmp(argv[i],"smlc") == 0)
gv.traceflags |= T_SMLC; gv.traceflags |= T_SMLC;
else if (strcmp(argv[i],"fp") == 0)
gv.traceflags |= T_FP;
else if (isdigit(argv[i][0]) && strlen(argv[i]) <= 3 && sscanf(argv[i],"%d", &templ) == 1) else if (isdigit(argv[i][0]) && strlen(argv[i]) <= 3 && sscanf(argv[i],"%d", &templ) == 1)
gv.traceuser = 0100000 | (templ<<6); /* form OWNERL for user # */ gv.traceuser = 0100000 | (templ<<6); /* form OWNERL for user # */
else if (strlen(argv[i]) == 6 && sscanf(argv[i],"%o", &templ) == 1) else if (strlen(argv[i]) == 6 && sscanf(argv[i],"%o", &templ) == 1)

80
fp.h
View File

@@ -40,6 +40,7 @@ http://tima-cmp.imag.fr/~guyot/Cours/Oparithm/english/Op_Ar2.htm
inline void getdp (unsigned long long p, long long *frac64, int *exp32) { inline void getdp (unsigned long long p, long long *frac64, int *exp32) {
TRACE(T_FP, " getdp(%016llx)\n", p);
*frac64 = p & 0xFFFFFFFFFFFF0000LL; /* unpack fraction */ *frac64 = p & 0xFFFFFFFFFFFF0000LL; /* unpack fraction */
*exp32 = (short) (p & 0xFFFFLL); /* unpack SIGNED exponent */ *exp32 = (short) (p & 0xFFFFLL); /* unpack SIGNED exponent */
} }
@@ -59,22 +60,29 @@ int prieee8(unsigned long long dp, double *d) {
/* unpack Prime DPFP */ /* unpack Prime DPFP */
getdp (dp, &frac64, &exp32); getdp (dp, &frac64, &exp32);
TRACE(T_FP, " prieee8: unpacked frac %016llx exp %08x\n", frac64, exp32);
/* if negative, change to sign-magnitude */ /* if negative, change to sign-magnitude */
sign = 0; sign = 0;
if (frac64 < 0) { if (frac64 < 0) {
TRACE(T_FP, " prieee8: changing to sign-magnitude\n");
/* special case: negative power of 2 */ /* special case: negative power of 2 */
if (frac64 == 0x8000000000000000LL) { if (frac64 == 0x8000000000000000LL) {
TRACE(T_FP, " prieee8: frac is negative power of 2\n");
exp32 += (1023-128); exp32 += (1023-128);
if (exp32 < 0 || exp32 > 0x7fe) if (exp32 < 0 || exp32 > 0x7fe)
{
TRACE(T_FP, " prieee8: exp %x out of range\n", exp32);
return 0; return 0;
}
frac64 |= ((long long)exp32 << 52); frac64 |= ((long long)exp32 << 52);
*d = *(double *)&frac64; *d = *(double *)&frac64;
return 1; return 1;
} else { } else {
TRACE(T_FP, " prieee8: frac is just negative\n");
sign = 0x8000000000000000LL; sign = 0x8000000000000000LL;
frac64 = -frac64; frac64 = -frac64;
} }
@@ -82,6 +90,7 @@ int prieee8(unsigned long long dp, double *d) {
/* special case: zero */ /* special case: zero */
} else if (frac64 == 0) { } else if (frac64 == 0) {
TRACE(T_FP, " prieee8: frac is 0\n");
*d = 0.0; *d = 0.0;
return 1; return 1;
} }
@@ -89,6 +98,7 @@ int prieee8(unsigned long long dp, double *d) {
/* normalize positive fraction until bit 2 is 1 */ /* normalize positive fraction until bit 2 is 1 */
while ((frac64 & 0x4000000000000000LL) == 0) { while ((frac64 & 0x4000000000000000LL) == 0) {
TRACE(T_FP, " prieee8: normalizing positive fraction\n");
frac64 = frac64 << 1; frac64 = frac64 << 1;
exp32--; exp32--;
} }
@@ -98,7 +108,10 @@ int prieee8(unsigned long long dp, double *d) {
exp32 += (1023-128) - 1; exp32 += (1023-128) - 1;
#if 1 #if 1
if (exp32 < 0 || exp32 > 0x7fe) if (exp32 < 0 || exp32 > 0x7fe)
{
TRACE(T_FP, " prieee8: exponent %x out of range\n", exp32);
return 0; return 0;
}
#else #else
if (exp32 < 0) { if (exp32 < 0) {
*d = 0.0; *d = 0.0;
@@ -113,6 +126,7 @@ int prieee8(unsigned long long dp, double *d) {
/* pack into an IEEE DPFP, losing the leading 1 bit in the process */ /* pack into an IEEE DPFP, losing the leading 1 bit in the process */
frac64 = sign | ((long long)exp32 << 52) | ((frac64 >> 10) & 0xfffffffffffffLL); frac64 = sign | ((long long)exp32 << 52) | ((frac64 >> 10) & 0xfffffffffffffLL);
TRACE(T_FP, " prieee8: packed ieee dpfp %016llx\n", frac64);
*d = *(double *)&frac64; *d = *(double *)&frac64;
return 1; return 1;
} }
@@ -134,7 +148,7 @@ retry:
neg = frac64 < 0; neg = frac64 < 0;
exp32 = (frac64 >> 52) & 0x7ff; exp32 = (frac64 >> 52) & 0x7ff;
frac64 &= 0xfffffffffffffLL; frac64 &= 0xfffffffffffffLL;
//printf("dp=%llx, neg=%d, frac64=%llx, exp32=%d, \n", *(long long *)dp, neg, frac64, exp32); TRACE(T_FP, "d=%016llx, neg=%x, frac64=%016llx, exp32=%08x, \n", (long long)d, neg, frac64, exp32);
/* special case: NaN & +-infinity */ /* special case: NaN & +-infinity */
@@ -159,12 +173,21 @@ retry:
and subnormal */ and subnormal */
if (exp32 != 0) /* typical IEEE normalized */ if (exp32 != 0) /* typical IEEE normalized */
{
TRACE(T_FP, " ieeepr8: is normalized\n");
frac64 |= 0x10000000000000LL; frac64 |= 0x10000000000000LL;
else if (frac64 == 0) { /* IEEE +-0.0 (zero exp+frac) */ }
else if (frac64 == 0) /* IEEE +-0.0 (zero exp+frac) */
{
TRACE(T_FP, " ieeepr8: zero exp and frac\n");
*p = 0; /* IEEE and Prime zero are the same */ *p = 0; /* IEEE and Prime zero are the same */
return okay; return okay;
} else }
else
{
TRACE(T_FP, " ieeepr8: subnormal value\n");
; /* subnormal: no hidden 1 bit */ ; /* subnormal: no hidden 1 bit */
}
/* adjust exponent, change sign-magnitude to 2's complement, /* adjust exponent, change sign-magnitude to 2's complement,
and shift fraction into Prime placement (high 48 bits) */ and shift fraction into Prime placement (high 48 bits) */
@@ -173,12 +196,14 @@ retry:
if (neg) if (neg)
frac64 = -frac64; frac64 = -frac64;
frac64 <<= 10; frac64 <<= 10;
TRACE(T_FP, " ieeepr8: de-biased prime-ised frac %016llx exp %08x\n", frac64, exp32);
/* normalize Prime DPFP */ /* normalize Prime DPFP */
while ((frac64 ^ (frac64 << 1)) >= 0) { while ((frac64 ^ (frac64 << 1)) >= 0) {
frac64 = frac64 << 1; frac64 = frac64 << 1;
exp32--; exp32--;
TRACE(T_FP, " ieeepr8: normalized prime frac %016llx exp %08x\n", frac64, exp32);
} }
#if 0 #if 0
@@ -204,8 +229,11 @@ retry:
if (round) if (round)
if ((frac64 & 0x8000) && ((frac64 & 0x7fffffffffff0000LL) != 0x7fffffffffff0000LL)) if ((frac64 & 0x8000) && ((frac64 & 0x7fffffffffff0000LL) != 0x7fffffffffff0000LL))
{
/* XXX: should this be a subtract for negative numbers? */ /* XXX: should this be a subtract for negative numbers? */
frac64 += 0x10000; frac64 += 0x10000;
TRACE(T_FP, " ieeepr8: rounded frac %016llx\n", frac64);
}
*p = swap64((frac64 & 0xffffffffffff0000LL) | (exp32 & 0xffff)); *p = swap64((frac64 & 0xffffffffffff0000LL) | (exp32 & 0xffff));
return okay; return okay;
@@ -260,6 +288,7 @@ unsigned long long dfcm (unsigned long long dp, int *oflow) {
CLEARC; CLEARC;
*oflow = 0; *oflow = 0;
getdp(dp, &frac64, &exp32); getdp(dp, &frac64, &exp32);
TRACE(T_FP, " dfcm: unpacked frac %016llx exp %08x\n", frac64, exp32);
if (frac64 != 0) { /* can't normalize zero */ if (frac64 != 0) { /* can't normalize zero */
if (frac64 == 0x8000000000000000LL) { /* overflow case? */ if (frac64 == 0x8000000000000000LL) { /* overflow case? */
frac64 = 0x4000000000000000LL; /* complement power of 2 */ frac64 = 0x4000000000000000LL; /* complement power of 2 */
@@ -290,6 +319,7 @@ unsigned long long norm(unsigned long long dp, int *oflow) {
*oflow = 0; *oflow = 0;
getdp(dp, &frac64, &exp32); getdp(dp, &frac64, &exp32);
TRACE(T_FP, " norm: unpacked frac %016llx exp %08x\n", frac64, exp32);
while ((frac64 ^ (frac64 << 1)) >= 0) { while ((frac64 ^ (frac64 << 1)) >= 0) {
frac64 = frac64 << 1; frac64 = frac64 << 1;
exp32--; exp32--;
@@ -314,11 +344,16 @@ unsigned long long frn(unsigned long long dp, int *oflow) {
*oflow = 0; *oflow = 0;
getdp(dp, &frac64, &exp32); getdp(dp, &frac64, &exp32);
TRACE(T_FP, " frn: unpacked frac %016llx exp %08x\n", frac64, exp32);
if (frac64 == 0) if (frac64 == 0)
{
TRACE(T_FP, " frn: returning 0\n");
return 0; return 0;
}
else { else {
doround1 = ((frac64 & 0x18000000000LL) != 0); doround1 = ((frac64 & 0x18000000000LL) != 0);
doround2 = ((frac64 & 0x8000000000LL) != 0) && ((frac64 & 0x7FFFFF0000LL) != 0); doround2 = ((frac64 & 0x8000000000LL) != 0) && ((frac64 & 0x7FFFFF0000LL) != 0);
TRACE(T_FP, " frn: doround1 %x doround2 %x\n", doround1, doround2);
if (doround1 || doround2) { if (doround1 || doround2) {
frac64 &= 0xFFFFFF0000000000LL; frac64 &= 0xFFFFFF0000000000LL;
if (frac64 != 0x7FFFFF0000000000LL) if (frac64 != 0x7FFFFF0000000000LL)
@@ -329,8 +364,10 @@ unsigned long long frn(unsigned long long dp, int *oflow) {
} }
frac64 |= (exp32 & 0xFFFF); frac64 |= (exp32 & 0xFFFF);
frac64 = norm(frac64, oflow); frac64 = norm(frac64, oflow);
TRACE(T_FP, " frn: rounded frac %016llx\n", frac64);
return frac64; return frac64;
} }
TRACE(T_FP, " frn: dp %016llx\n", dp);
return dp; return dp;
} }
} }
@@ -356,26 +393,37 @@ int fcs (unsigned long long fac, int fop) {
fop = fop & 0xffffff00; fop = fop & 0xffffff00;
if (fop == 0) /* fix dirty zero */ if (fop == 0) /* fix dirty zero */
fopexp = 0; fopexp = 0;
TRACE(T_FP, " fcs: FAC: %016llx %04x; op: %016llx %04x\n", templ, facexp, fop, fopexp);
if ((templ & 0x80000000) == (fop & 0x80000000)) { /* compare signs */ if ((templ & 0x80000000) == (fop & 0x80000000)) { /* compare signs */
if (facexp == fopexp) /* compare exponents */ if (facexp == fopexp) /* compare exponents */
if (templ == fop) { /* compare fractions */ if (templ == fop) { /* compare fractions */
TRACE(T_FP, " fcs: frac cmp returning eq / skip 1\n");
SETEQ; SETEQ;
return 1; return 1;
} else if (templ < fop) { /* compare fractions */ } else if (templ < fop) { /* compare fractions */
TRACE(T_FP, " fcs: frac cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " fcs: frac cmp returning gt / skip 0\n");
return 0; /* FAC > operand */ return 0; /* FAC > operand */
}
else if (facexp < fopexp) { /* compare exponents */ else if (facexp < fopexp) { /* compare exponents */
TRACE(T_FP, " fcs: exp cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " fcs: exp cmp returning gt / skip 0\n");
return 0; return 0;
}
} else if (templ & 0x80000000) { } else if (templ & 0x80000000) {
TRACE(T_FP, " fcs: sign cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " fcs: sign cmp returning gt / skip 0\n");
return 0; /* FAC > operand */ return 0; /* FAC > operand */
}
} }
@@ -404,27 +452,35 @@ int dfcs (unsigned long long fac, long long fop) {
fop = fop & 0xffffffffffff0000LL; fop = fop & 0xffffffffffff0000LL;
if (fop == 0) /* fix dirty zero */ if (fop == 0) /* fix dirty zero */
fopexp = 0; fopexp = 0;
#if 0 TRACE(T_FP, " dfcs: FAC: %016llx %04x; op: %016llx %04x\n", templl, facexp, fop, fopexp);
printf("dfcs: FAC: %016llx %04x; op: %016llx %04x\n", templl, facexp, fop, fopexp);
#endif
if ((templl & 0x8000000000000000LL) == (fop & 0x8000000000000000LL)) { /* compare signs */ if ((templl & 0x8000000000000000LL) == (fop & 0x8000000000000000LL)) { /* compare signs */
if (facexp == fopexp) /* compare exponents */ if (facexp == fopexp) /* compare exponents */
if (templl == fop) { /* compare fractions */ if (templl == fop) { /* compare fractions */
TRACE(T_FP, " dfcs: frac cmp returning eq / skip 1\n");
SETEQ; SETEQ;
return 1; return 1;
} else if (templl < fop) { /* compare fractions */ } else if (templl < fop) { /* compare fractions */
TRACE(T_FP, " dfcs: frac cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " dfcs: frac cmp returning gt / skip 0\n");
return 0; /* FAC > operand */ return 0; /* FAC > operand */
}
else if (facexp < fopexp) { /* compare exponents */ else if (facexp < fopexp) { /* compare exponents */
TRACE(T_FP, " dfcs: exp cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " dfcs: exp cmp returning eq / skip 1\n");
return 0; return 0;
}
} else if (templl & 0x8000000000000000LL) { } else if (templl & 0x8000000000000000LL) {
TRACE(T_FP, " dfcs: sign cmp returning lt / skip 2\n");
SETLT; /* FAC < operand */ SETLT; /* FAC < operand */
return 2; return 2;
} else } else {
TRACE(T_FP, " dfcs: sign cmp returning gt / skip 0\n");
return 0; /* FAC > operand */ return 0; /* FAC > operand */
}
} }

View File

@@ -29,7 +29,7 @@ main () {
else { /* not a space character */ else { /* not a space character */
while (space) { /* dump held-back spaces first */ while (space) { /* dump held-back spaces first */
if (space < 3) { /* write regular spaces */ if (space < 3) { /* write regular spaces */
putchar(' '); putchar(0240);
space--; space--;
n++; n++;
} else { /* write compressed spaces */ } else { /* write compressed spaces */