1
0
mirror of https://github.com/prirun/p50em.git synced 2026-04-15 23:51:06 +00:00

added table of generic instructions to ignore & log

initial disk controller support
began FP instruction work
This commit is contained in:
Jim
2005-04-23 00:00:00 -04:00
parent ff3fd68935
commit 655b35b0f9
4 changed files with 1348 additions and 167 deletions

892
em.c

File diff suppressed because it is too large Load Diff

313
emdev.h
View File

@@ -6,50 +6,95 @@
OCP instructions never skip
SKS instructions skip on specified conditions
INA/OTA instructions skip if they succeed (data was read/written)
Device numbers:
'01 = paper tape reader
'02 = paper tape punch
'03 = 1st MPC (line printer/card reader/card punch)
'04 = SOC board (system console/user terminal)
'05 = 2nd MPC (line printer/card reader/card punch)
'06 = card punch? (RTOS User Guide, A-1) / IPC (Engr Handbook p.101)
'07 = PNC
'12 = diskette
'13 = 2nd magtape controller
'14 = 1st magtape controller
'20 = control panel / real-time clock
'21 = 1st 4002 disk controller
'22 = obsolete: fixed head disk
'23 = obsolete: 30MB disk
'24 = tag monitor (tmain.pma) / writable control store
'25 = obsolete: moving head disk
'26 = 1st disk controller
'27 = 2nd disk controller
'30-32 = BPIOC #1-3 (RTOS User Guide, A-1)
'33 = 1st Versatec (verdim)
'34 = 2nd Versatec
'35 = 4th AMLC
'36-37 = ELFBUS #1 & 2
'40 = A/D converter type 6000
'41 = digital input type 6020
'42 = digital input #2
'43 = digital output type 6040
'44 = digital output #2
'45 = D/A converter type 6060 (analog output)
'50 = 1st HSSMLC (cs/slcdim.pma)
'51 = 2nd HSSMLC
'52 = 3rd AMLC
'53 = 2nd AMLC
'54 = 1st AMLC
'55 = MACI autocall unit
'56 = old SMLC (RTOS User Guide, A-1)
'60-67 = reserved for user devices
'70-'73 = Megatek graphics terminals
Devices emulated by Primos in ks/ptrap.ftn:
'04 = console, '01 = paper tape reader, '02 = paper tape punch,
'20 = control panel
*/
#include <fcntl.h>
#include <unistd.h>
void devnull (short class, short func, short device) {
switch (class) {
case 0:
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
fprintf(stderr," OCP '%02o%02o\n", func, device);
if (func == 0) {
;
} else {
fprintf(stderr," unimplemented OCP device %2#0o function\n", device);
fprintf(stderr," unimplemented OCP device '%02o function\n", device);
exit(1);
}
break;
case 1:
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
fprintf(stderr," SKS '%02o%02o\n", func, device);
if (func == 0)
mem[P]++; /* assume it's always ready */
else {
fprintf(stderr," unimplemented SKS device %2#0o function\n", device);
fprintf(stderr," unimplemented SKS device '%02o function\n", device);
exit(1);
}
break;
case 2:
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
fprintf(stderr," INA '%02o%02o\n", func, device);
if (func == 0) {
;
} else {
fprintf(stderr," unimplemented INA device %2#0o function\n", device);
fprintf(stderr," unimplemented INA device '%02o function\n", device);
exit(1);
}
break;
case 3:
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
fprintf(stderr," OTA '%02o%02o\n", func, device);
if (func == 0 | func == 1) {
mem[P]++; /* OTA '0004 always works on Unix */
} else {
fprintf(stderr," unimplemented OTA device %2#0o function\n", device);
fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
}
break;
@@ -87,11 +132,11 @@ void devasr (short class, short func, short device) {
switch (class) {
case 0:
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
fprintf(stderr," OCP '%02o%02o\n", func, device);
break;
case 1:
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
fprintf(stderr," SKS '%02o%02o\n", func, device);
if (func <= 7)
mem[P]++; /* assume it's always ready */
else {
@@ -101,7 +146,7 @@ void devasr (short class, short func, short device) {
break;
case 2:
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
fprintf(stderr," INA '%02o%02o\n", func, device);
if (func == 0 || func == 010) {
if (fcntl(ttydev, F_GETFL, ttyflags) == -1) {
perror(" unable to get tty flags");
@@ -143,7 +188,7 @@ void devasr (short class, short func, short device) {
break;
case 3:
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
fprintf(stderr," OTA '%02o%02o\n", func, device);
if (func == 0) {
fprintf(stderr," char to write=%o\n", mem[A]);
putchar(mem[A] & 0x7f);
@@ -162,6 +207,40 @@ void devasr (short class, short func, short device) {
/* Device '14 - magtape controller #1
*/
void devmt (short class, short func, short device) {
switch (class) {
case 0:
fprintf(stderr," OCP '%02o%02o\n", func, device);
break;
case 1:
fprintf(stderr," SKS '%02o%02o\n", func, device);
break;
case 2:
fprintf(stderr," INA '%02o%02o\n", func, device);
if (mem[mem[P]] == 03776) { /* JMP *-1 -> blocking read */
fprintf(stderr," Device not supported, so I/O hangs\n");
exit(1);
}
break;
case 3:
fprintf(stderr," OTA '%02o%02o\n", func, device);
if (mem[mem[P]] == 03776) { /* JMP *-1 -> blocking read */
fprintf(stderr," Device not supported, so I/O hangs\n");
exit(1);
}
break;
}
}
/* Device '20: control panel switches and lights
OTA '1720 = write to lights (sets CP fetch address)
@@ -174,33 +253,34 @@ void devcp (short class, short func, short device) {
switch (class) {
case 0:
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
fprintf(stderr," unimplemented OCP device %2#0o function\n", device);
fprintf(stderr," OCP '%02o%02o\n", func, device);
fprintf(stderr," unimplemented OCP device '%02o function\n", device);
exit(1);
break;
case 1:
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
fprintf(stderr," unimplemented SKS device %2#0o function\n", device);
fprintf(stderr," SKS '%02o%02o\n", func, device);
fprintf(stderr," unimplemented SKS device '%02o function\n", device);
exit(1);
break;
case 2:
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
fprintf(stderr," INA '%02o%02o\n", func, device);
if (func == 016) {
mem[A] = 014114;
mem[A] = 0;
} else {
fprintf(stderr," unimplemented INA device %2#0o function\n", device);
fprintf(stderr," unimplemented INA device '%02o function\n", device);
exit(1);
}
break;
case 3:
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
fprintf(stderr," OTA '%02o%02o\n", func, device);
if (func == 017) { /* write lights */
mem[P]++;
} else {
fprintf(stderr," unimplemented OTA device %2#0o function\n", device);
fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
}
break;
@@ -208,3 +288,196 @@ void devcp (short class, short func, short device) {
}
/* disk controller at '26 and '27
NOTES:
- in the DSEL disk channel program command, unit number is a 4-bit field,
with these binary values:
0001 = unit 0 (pdev 460/461)
0010 = unit 1 (pdev 462/463)
0100 = unit 2 (pdev 464/465)
1000 = unit 3 (pdev 466/467)
OCP '1626 = reset interrupt
OCP '1726 = reset controller
INA '1126 = input ID, don't clear A first, fails if no controller
INA '1726 = read status (or something), fails if controller busy
OTA '1726 = load OAR (Order Address Register), ie, run channel
program, address is in A
*/
void devdisk (short class, short func, short device) {
unsigned short oar;
unsigned short status; /* actual status */
unsigned short teststatus; /* status for order testing */
unsigned short memaddr;
unsigned short order;
short halt;
short unit;
short head, track, rec, recsize, nwords;
unsigned short dmachan, dmanch, dmaaddr;
short dmanw;
char ordertext[8];
char devfile[8];
char devopened[8]; /* device file that is open on devfd */
static int devfd=-1; /* device file descriptor */
int theads, spt, phyra;
switch (class) {
case 0:
fprintf(stderr," OCP '%2o%2o\n", func, device);
break;
case 1:
fprintf(stderr," SKS '%2o%2o\n", func, device);
break;
case 2:
fprintf(stderr," INA '%2o%2o\n", func, device);
if (func == 01) /* read device id, clear A first */
mem[A] = device;
else if (func == 011) /* read device id, don't clear A */
mem[A] |= device;
else if (func == 017) /* read status */
mem[A] = 0100000;
mem[P]++;
break;
case 3:
fprintf(stderr," OTA '%02o%02o\n", func, device);
if (func == 017) { /* set OAR (order address register) */
oar = mem[A];
halt = 0;
status = 0100000;
unit = -1;
while (!halt) {
order = mem[oar]>>12;
fprintf(stderr,"\n %o: %o %o %o\n", oar, mem[oar], mem[oar+1], mem[oar+2]);
if (mem[oar] & 04000) { /* "execute if ..." */
if (order == 2 || order == 5 || order == 6)
oar += 3;
else
oar += 2;
continue;
}
switch (order) {
case 0: /* DHLT = Halt */
halt = 1;
fprintf(stderr," channel program halt at '%o\n", oar);
break;
case 2: /* SFORM = Format */
case 5: /* SREAD = Read */
case 6: /* SWRITE = Write */
recsize = mem[oar] & 017;
track = mem[oar+1] & 01777;
rec = mem[oar+2] >> 8; /* # records for format, rec # for R/W */
head = mem[oar+2] & 077;
if (order == 2)
strcpy(ordertext,"Format");
else if (order == 5)
strcpy(ordertext,"Read");
else if (order == 6)
strcpy(ordertext,"Write");
fprintf(stderr," %s, head=%d, track=%d, rec=%d, recsize=%d\n", ordertext, head, track, rec, recsize);
dmanw = mem[dmachan];
dmanw = -(dmanw>>4);
dmaaddr = mem[dmachan+1];
fprintf(stderr, " DMA channels: nch-1=%d, ['%o]='%o, ['%o]='%o, nwords=%d\n", dmanch, dmachan, mem[dmachan], dmachan+1, mem[dmachan+1], dmanw);
if (devfd == -1) {
fprintf(stderr," Unit not selected or not ready\n");
status = 0100001;
} else if (order == 2)
fprintf(stderr," Format order not implemented\n");
else if (order == 5) {
/* translate head/track/sector to drive record address */
theads = 40; /* should get total heads from a config file */
spt = 9; /* and sectors per track too */
phyra = (track*theads*spt) + head*9 + rec;
fprintf(stderr, " phyra=%d, byte offset=%d\n", phyra, phyra*2080);
if (lseek(devfd, phyra*2080, SEEK_SET) == -1) {
perror("Unable to seek drive file");
exit(1);
}
if (read(devfd, mem+dmaaddr, dmanw*2) != dmanw*2) {
perror("Unable to read drive file");
exit(1);
}
mem[dmachan] = 0;
mem[dmachan+1] += dmanw;
} else if (order == 6)
fprintf(stderr," Write order not implemented\n");
oar += 3;
break;
case 3: /* SSEEK = Seek */
track = mem[oar+1] & 01777;
fprintf(stderr," seek track %d, restore=%d, clear=%d\n", track, (mem[oar+1] & 0100000) != 0, (mem[oar+1] & 040000) != 0);
oar += 2;
break;
case 4: /* DSEL = Select unit */
unit = (mem[oar+1] & 017) >> 1; /* unit = 0/1/2/4 */
if (unit == 4) unit = 3; /* unit = 0/1/2/3 */
snprintf(devfile,sizeof(devfile),"dev%ou%d", device, unit);
fprintf(stderr," select unit %d, filename %s\n", unit, devfile);
if (strcmp(devfile,devopened) != 0 || devfd == -1) {
if (devfd != -1) {
close(devfd);
devfd = -1;
}
if ((devfd = open(devfile, O_RDONLY, 0)) == -1)
status = 0100001; /* not ready */
else
strcpy(devopened, devfile);
}
oar += 2;
break;
case 7: /* DSTALL = Stall */
fprintf(stderr," stall\n");
oar += 2;
break;
case 9: /* DSTAT = Store status to memory */
memaddr = mem[oar+1];
fprintf(stderr, " store status to '%o\n", memaddr);
mem[memaddr] = status;
oar += 2;
break;
case 11: /* DOAR = Store OAR to memory (2 words) */
memaddr = mem[oar+1];
fprintf(stderr, " store OAR to '%o\n", memaddr);
mem[memaddr] = oar;
oar += 2;
break;
case 13: /* SDMA = select DMA channel(s) to use */
dmanch = mem[oar] & 017;
dmachan = mem[oar+1];
fprintf(stderr, " set DMA channels, nch-1=%d, channel='%o\n", dmanch, dmachan);
oar += 2;
break;
case 14: /* DINT = generate interrupt through vector address */
memaddr = mem[oar+1];
fprintf(stderr, " interrupt through '%o\n", memaddr);
exit(1);
oar += 2;
break;
case 15: /* DTRAN = channel program jump */
oar = mem[oar+1];
fprintf(stderr, " jump to '%o\n", oar);
break;
default:
fprintf(stderr, " unrecognized channel order = %d\n", order);
exit(1);
}
}
mem[P]++;
} else {
fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
}
break;
}
}

304
fp.c Normal file
View File

@@ -0,0 +1,304 @@
/* ** general conversion doc here, or (referenced) above. ***************** */
/* doc exponent details here: (-1 & bin pt. placement by prieee) vs.
vs. (-2 by ieeepr()): note that
IEEE denormalized bin pxxxxxxx prime (relative to the 23 bits);
in ieeepr the trick is to treat normalized #'s as the special case. */
void prieee4(xlongp) /* ****** convert from Prime to IEEE. ****** */
long *xlongp;
{
long xlong;
long sign; /* sign */
long mant; /* mantissa: note this is signed: mant = -mant below */
long exp; /* exponent */
/* note: when converting form Prime to IEEE, we need to check for exponent
underflow, but not for overflow. */
xlong = *xlongp;
mant = xlong & 0xffffff00; /* 24 bits: includes sign bit */
sign = mant & 0x80000000;
mant >>= 8; /* ok to trash upper byte, which will get masked out. */
if (sign)
mant = - mant;
/* now have 24 bit # w/ leading 0. */
exp = (xlong & 0x000000ff) - 1; /* exp now in excess 127 (IEEE) form. */
if (exp < 0) {
mant >>= 1; /* tiny tiny #; will get shifted once more below. */
++exp; /* Bring exp back up to 0. */
}
else /* *** normalize the mantissa. If input Prime mantissa was already
noramalized, this loop will still execute once, unless input #
was -(2**n) in which case it will execute 0 times. This is
because Prime mantissas are 2's compliment, and powers of 2
normalize differently when negated. Note no loop for 0 exp. */
while (exp && !(mant & 0x00800000)) {
mant <<= 1;
--exp;
}
/* we now have a 24 bit unsigned # w/ a leading 1. If the exponent is > 0,
we are all set: the resulting IEEE number will be normalized. This
leading (hidden) IEEE 1 will be masked out below. */
if ( ! exp) /* result must be denormalized: shift 1 further to */
mant >>= 1; /* include IEEE leading bit, which may be 0 or 1. */
mant &= 0x007fffff;
exp <<= 23;
*xlongp = sign | exp | mant;
}
void ieeepr4(xlongp) /* ****** convert from IEEE to Prime. ****** */
long *xlongp;
{
long xlong;
long sign; /* sign */
long mant; /* mantissa: note this is signed: mant = -mant below */
long exp; /* exponent */
long templ;
/* note: when converting form Prime to IEEE, we need to check for exponent
overflow, but not for underflow. */
xlong = *xlongp;
if ( ! (xlong & 0x7fffffff))
*xlongp = 0; /* +0 or -0 */
else {
sign = xlong & 0x80000000;
mant = (xlong & 0x007fffff) << 8; /* assume denormalized, adjust below */
exp = (xlong & 0x7f800000) >> 23; /* still in excess 127 (IEEE) form. */
if (exp == 0xff) { /* NaN (not a number) or +/- infinity? */
if (mant == 0) {
/* +/- infinity. */
if (sign == 0)
*xlongp = 0x7fffffff; /* largest Prime # in for +infinity. */
else /* note: 0x800000ff cant be negated; */
*xlongp = 0x800001ff; /* use - 0x7fffffff for -infinity. */
}
else {
/* NaN (not a number) */
if (sign == 0)
*xlongp = 0x539733ff; /* use 1.11111e+38 for NaN, since */
else /* it stands out if printed. */
*xlongp = 0xac68cdff; /* use -1.11111e+38 for -NaN. */
}
}
else { /* actual number */
if (exp != 0) {
if(mant != 0x7fffff00)/* Special case of mantissa value of all 1s*/
mant = (mant >> 1) + 0x40000080; /* ieee normalized number: */
/* shift to make room for */
/* hidden leading 1 bit, 'or'*/
/* it in and round truncated */
/* LSBit up. */
mant &= 0xffffff00;
}
exp += 2; /* exp now in excess 128 (Prime) form. */
if (sign != 0) /* sign bit of mant will be 0 at this point. */
mant = - mant;
/* mant is now a 24 bit signed mantissa (shifted to Prime position) */
/* *** normalize the number. In most cases, the number will already
be normalized. Negative powers of 2 will be shifted once, since
they normalize differently. IEEE denormalized numbers can be
adjusted at most 2 bits, due to the excess 127 vs. 128 exponent and
binary point position differences (cant negate exponent). *** */
while (exp && ((~(mant^(mant<<1))) & 0x80000000)) {
mant <<= 1; /* sign and next most significant */
--exp; /* bit are equal: normalize. */
}
if (exp > 0xff) {
if ( ! sign)
*xlongp = 0x7fffffff; /* largest Prime # in for +infinity. */
else /* note: 0x800000ff cant be negated; */
*xlongp = 0x800001ff; /* use - 0x7fffffff for -infinity. */
}
else
*xlongp = mant | exp; /* mant is signed; */
}
}
}
#define l1 0
#define l0 1
/* ** general conversion doc here, or (referenced) above. ***************** */
/* doc exponent details here: (-1 & bin pt. placement by prieee) vs.
vs. (-2 by ieeepr()): note that
IEEE denormalized bin pxxxxxxx prime (relative to the 23 bits);
in ieeepr the trick is to treat normalized #'s as the special case. */
void prieee8(xlongp) /* ****** convert from Prime to IEEE. ****** */
long *xlongp;
{
long xlong1,xlong0;
long mant1,mant0; /* mantissa: these are signed: mant = -mant below */
long sign; /* sign */
long exp; /* exponent */
/* note: when converting REAL*8 form Prime to IEEE, we need to check for both
exponent underflow, and overflow. */
xlong1 = xlongp[l1]; /* high 4 bytes */
xlong0 = xlongp[l0]; /* low 4 bytes */
sign = xlong1 & 0x80000000;
mant1 = xlong1 >> 11; /* 48 bits, includes */
mant0 = (xlong1 << 21) | ((xlong0 >> 11) & 0xfffe0); /* includes sign bit */
if ( ! mant0 && ! mant1) { /* zero (dirty or otherwise)? */
xlongp[l1] = xlongp[l0] = 0;
return; /* return ****** */
}
if (sign) { /* 2's comp mant1/mant0 pair */
mant0 = - mant0;
mant1 = ~ mant1;
if ( ! mant0)
++ mant1; /* mant0==0: have a carry fr. mant0 to mant1. */
}
/* now have 48 bit # w/ leading 0. */
exp = (xlong0 & 0xffff) - 0x80; /* convert 16 bit */
if (exp & 0x8000) /* Prime exponent */
exp |= 0xffff0000; /* from "excess 128" */
else /* form to 2's */
exp &= 0x0000ffff; /* complement form. */
exp += 0x3ff; /* exp now in excess 1023 (IEEE) form. */
if (exp < -50) { /* Prime exp too small? */
xlongp[l1] = xlongp[l0] = 0; /* closest IEEE is 0. */
return; /* return ****** */
}
if (exp < 0) {
/* note: can still get 0, iff have leading (non sign bit) 0's */
mant0 = (mant1 << 32+exp) | (mant0 >> -exp); /* mant >>= -exp; */
mant1 >>= -exp; /* tiny tiny #; will get shifted once more below. */
++mant0; /* lsb will get lost below, since # is denormalized; round */
if ( ! mant0)
++mant1;
exp = 0; /* exp += -exp. */
}
else /* *** normalize the mantissa. */
while (exp && !(mant1 & 0x00100000)) {
mant1 <<= 1;
if (mant0 & 0x80000000)
mant1 |= 1;
mant0 <<= 1;
--exp;
}
if (exp > 0x7fe) {
xlongp[l1] = sign | 0x7fefffff; /* Prime exp too big; closest */
xlongp[l0] = 0xffffffff; /* closest IEEE is (+/-) max. */
}
else {
/* we now have a 48 bit unsigned # w/ a leading 1. If the exponent is
> 0, we are all set: the resulting IEEE number will be normalized.
This leading (hidden) IEEE 1 will be masked out below. */
if ( ! exp) { /* result must be denormalized: shift 1 further to */
mant0 >>= 1; /* include IEEE leading bit, which may be 0 or 1. */
if (mant1 & 1)
mant0 |= 0x80000000;
mant1 >>= 1;
}
mant1 &= 0x000fffff;
exp <<= 20;
xlongp[l1] = sign | exp | mant1;
xlongp[l0] = mant0;
}
}
void ieeepr8(xlongp) /* ****** convert from IEEE to Prime. ****** */
long *xlongp;
{
long xlong1,xlong0;
long mant1,mant0; /* mantissa: these are signed: mant = -mant below */
long sign; /* sign */
long exp; /* exponent */
/* note: when converting REAL*8 form Prime to IEEE, we dont need to check for
exponent overflow, or underflow. */
xlong1 = xlongp[l1]; /* high 4 bytes */
xlong0 = xlongp[l0]; /* low 4 bytes */
if ((xlong1 & 0x7fffffff) == 0 && xlong0 == 0) {
xlongp[l1] = xlongp[l0] = 0; /* +0 or -0 */
return; /* return ****** */
}
sign = xlong1 & 0x80000000;
exp = (xlong1 & 0x7ff00000) >> 20; /* still in excess 1023 (IEEE) form. */
mant1 = ((xlong1 & 0xfffff) << 11) | ((xlong0 >> 21) & 0x7ff);
mant0 = xlong0 << 11; /* assume denormalized, adjust below */
if (exp == 0x7ff) { /* NaN (not a number) or +/- infinity? */
if (mant1 == 0 && mant0 == 0) {
/* +/- infinity. */
if (sign == 0) {
xlongp[l1] = 0x7fffffff; /* largest Prime # in for +infinity. */
xlongp[l0] = 0xffffffff;
}
else { /* note: 0x80000000 0000ffff cant be */
xlongp[l1] = 0x80000000; /* negated, use -0x7fffffff ffffffff */
xlongp[l0] = 0x0001ffff; /* -infinity. */
}
}
else {
/* NaN (not a number) */
if (sign == 0) {
xlongp[l1] = 0x7fffffff; /* For now, use +/- infinity values */
xlongp[l0] = 0xffffffff; /* for +/- NaN. */
}
else {
xlongp[l1] = 0x80000000;
xlongp[l0] = 0x0001ffff;
}
}
}
else { /* actual number */
if (exp != 0) {
/* ieee normalized number: shift mantissa to make room for hidden */
mant0 >>= 1; /* leading 1 bit and 'or' it in. */
if (mant1 & 1)
mant0 |= 0x80000000;
else
mant0 &= 0x7fffffff;
mant1 >>= 1;
mant1 |= 0x40000000;
}
exp -= 894; /* exp now in 'excess 128' (Prime) form. */
mant0 &= 0xffff0000;
if (sign) { /* sign bit of mant will be 0 at this point. */
mant0 |= 0xffff; /* 2's comp mant1/mant0 pair */
mant0 = - mant0;
mant1 = ~ mant1;
if ( ! mant0)
++ mant1; /* mant0==0: have a carry fr. mant0 to mant1. */
}
/* mant is now a 48 bit signed mantissa (shifted to Prime position) */
/* *** normalize the number. In most cases, the number will already
be normalized. Negative powers of 2 will be shifted once, since
they normalize differently. IEEE denormalized numbers can be
adjusted at most 2 bits, due to the excess 127 vs. 128 exponent and
binary point position differences (cant negate exponent). *** */
while (exp && ((~(mant1^(mant1<<1))) & 0x80000000)) {
mant1 <<= 1; /* sign and next most significant */
if (mant0 & 0x80000000) /* bit are equal: normalize. */
mant1 |= 1;
mant0 <<= 1;
--exp;
}
mant0 &= 0xffff0000;
xlongp[l1] = mant1; /* mant is signed; no sign to 'or' in. */
xlongp[l0] = mant0 | exp;
}
}

6
os.c
View File

@@ -125,6 +125,7 @@ os_rdtk$$(short *key, short *info, char *buf, short *buflen, short *code) {
}
os_t1ou(short *charg) {
fprintf(stderr," Character is '%o/%d, Prime is '%o/%d, (%c)\n", *charg, *charg, *charg & 0x7f, *charg & 0x7f, *charg & 0x7f);
putchar(*charg & 0x7f);
fflush(stdout);
}
@@ -156,8 +157,13 @@ os_timdat(short *userbuf, short *n) {
tod = time(NULL);
localtime_r(&tod, &tms);
strncpy(timbuf.mmddyy,"042105",6);
#if 0
timbuf.timemins = tms.tm_hour*60 + tms.tm_min;
timbuf.timesecs = tms.tm_sec;
#else
timbuf.timemins = 0;
timbuf.timesecs = 0;
#endif
timbuf.timeticks = 0;
timbuf.cpusecs = timbuf.cputicks = timbuf.iosecs = timbuf.ioticks = 0;
timbuf.tickspersec = 330;