mirror of
https://github.com/prirun/p50em.git
synced 2026-03-03 01:48:16 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74aa7fe23e | ||
|
|
1819fed512 | ||
|
|
64c5970e97 | ||
|
|
c6c0344004 | ||
|
|
0466b4b603 |
@@ -55,7 +55,7 @@ business unit ceased to exist. A reformatted copy is available
|
|||||||
A growing collection of Prime and related documentation is available
|
A growing collection of Prime and related documentation is available
|
||||||
at [sysovl.info](https://sysovl.info/reference_prime.html).
|
at [sysovl.info](https://sysovl.info/reference_prime.html).
|
||||||
A howto on installing PRIMOS in the emulator is
|
A howto on installing PRIMOS in the emulator is
|
||||||
[here](https://sysovl.info/reference_prime_drb_installing_primos.html).
|
[here](https://sysovl.info/reference_prime_drb_installoview.html).
|
||||||
Discussion of adapting these instructions to
|
Discussion of adapting these instructions to
|
||||||
22.1.4 has been occurring on the [cctalk mailing
|
22.1.4 has been occurring on the [cctalk mailing
|
||||||
list](http://classiccmp.org/pipermail/cctalk/2020-March/052126.html).
|
list](http://classiccmp.org/pipermail/cctalk/2020-March/052126.html).
|
||||||
|
|||||||
40
devamlc.h
40
devamlc.h
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
Implements the AMLC subsystem for Primos. In earlier versions
|
Implements the AMLC subsystem for Primos. In earlier versions
|
||||||
(r186), a more hardware-centric implementation was used that closely
|
(r186), a more hardware-centric implementation was used that closely
|
||||||
followed the design of Prime's real AMLC board. For example, every
|
followed the design of Prime's real AMLC board. For example, every
|
||||||
@@ -52,9 +52,9 @@
|
|||||||
NOTE: varying the AMLC poll rates dynamically is the default, but
|
NOTE: varying the AMLC poll rates dynamically is the default, but
|
||||||
this can lead to unpredictable performance. If consistent,
|
this can lead to unpredictable performance. If consistent,
|
||||||
predictable performance is more important than absolute
|
predictable performance is more important than absolute
|
||||||
performance, MAXAMLCSPEEDUP can be set to 1. Then this
|
performance, MAXAMLCSPEEDUP can be set to 1. Then this
|
||||||
implementation will function more or less like a real Prime.
|
implementation will function more or less like a real Prime.
|
||||||
|
|
||||||
|
|
||||||
AMLC I/O operations:
|
AMLC I/O operations:
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
AMLC status word (from AMLCT5):
|
AMLC status word (from AMLCT5):
|
||||||
|
|
||||||
BITS DESCRIPTION
|
BITS DESCRIPTION
|
||||||
|
|
||||||
1 END OF RANGE INTERRUPT
|
1 END OF RANGE INTERRUPT
|
||||||
2 CLOCK RUNNING
|
2 CLOCK RUNNING
|
||||||
3-6 LINE # OF LINE WHOSE DATA SET STATUS HAS CHANGED
|
3-6 LINE # OF LINE WHOSE DATA SET STATUS HAS CHANGED
|
||||||
@@ -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 */
|
||||||
@@ -202,11 +204,11 @@ int devamlc (int class, int func, int device) {
|
|||||||
#define DSSCOUNTDOWN 25
|
#define DSSCOUNTDOWN 25
|
||||||
|
|
||||||
/* connection types for each line. This _doesn't_ imply the line is
|
/* connection types for each line. This _doesn't_ imply the line is
|
||||||
actually connected, ie, an AMLC line may be tied to a specific
|
actually connected, ie, an AMLC line may be tied to a specific
|
||||||
serial device (like a USB->serial gizmo), but the USB device may
|
serial device (like a USB->serial gizmo), but the USB device may
|
||||||
not be plugged in. The connection type would be CT_SERIAL but
|
not be plugged in. The connection type would be CT_SERIAL but
|
||||||
the line's fd would be -1 and the "connected" bit would be 0 */
|
the line's fd would be -1 and the "connected" bit would be 0 */
|
||||||
|
|
||||||
#define CT_SOCKET 1
|
#define CT_SOCKET 1
|
||||||
#define CT_SERIAL 2
|
#define CT_SERIAL 2
|
||||||
#define CT_DEDIP 3
|
#define CT_DEDIP 3
|
||||||
@@ -324,7 +326,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
int tempport;
|
int tempport;
|
||||||
struct hostent* host;
|
struct hostent* host;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
/* initially, we don't know about any AMLC boards */
|
/* initially, we don't know about any AMLC boards */
|
||||||
|
|
||||||
for (dx=0; dx<MAXBOARDS; dx++) {
|
for (dx=0; dx<MAXBOARDS; dx++) {
|
||||||
@@ -346,7 +348,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
/* read the amlc.cfg file. This file has 3 uses:
|
/* read the amlc.cfg file. This file has 3 uses:
|
||||||
|
|
||||||
1. maps Prime async lines to real serial devices, like host
|
1. maps Prime async lines to real serial devices, like host
|
||||||
serial ports or USB serial boxes.
|
serial ports or USB serial boxes.
|
||||||
|
|
||||||
Format: <line #> /dev/<Unix usb device name>
|
Format: <line #> /dev/<Unix usb device name>
|
||||||
|
|
||||||
@@ -418,7 +420,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
fprintf(stderr,"Line %d of amlc.cfg ignored: IP address too long\n", lc);
|
fprintf(stderr,"Line %d of amlc.cfg ignored: IP address too long\n", lc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* break out host and port number; no port means this is
|
/* break out host and port number; no port means this is
|
||||||
an incoming dedicated line: no connects out. With a
|
an incoming dedicated line: no connects out. With a
|
||||||
port means we need to connect to it. */
|
port means we need to connect to it. */
|
||||||
@@ -553,13 +555,13 @@ int devamlc (int class, int func, int device) {
|
|||||||
/* XXX: this constant is redefined because of a bug in the
|
/* XXX: this constant is redefined because of a bug in the
|
||||||
OSX Prolific USB serial driver at version 1.2.1r2. They should be
|
OSX Prolific USB serial driver at version 1.2.1r2. They should be
|
||||||
turning on bit 0100, but are turning on 0x0100. */
|
turning on bit 0100, but are turning on 0x0100. */
|
||||||
#define TIOCM_CD 0x0100
|
#define TIOCM_CD 0x0100
|
||||||
|
|
||||||
if (func == 00) { /* input Data Set Sense (carrier) */
|
if (func == 00) { /* input Data Set Sense (carrier) */
|
||||||
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);
|
||||||
@@ -634,10 +636,10 @@ int devamlc (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case CT_SERIAL: {
|
case CT_SERIAL: {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* setup line characteristics if they have changed (check for
|
/* setup line characteristics if they have changed (check for
|
||||||
something other than DTR changing) */
|
something other than DTR changing) */
|
||||||
|
|
||||||
@@ -707,7 +709,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
1_0 - cts/rts flow control (2413 becomes 6413)
|
1_0 - cts/rts flow control (2413 becomes 6413)
|
||||||
1_1 - dsr/dtr flow control (2413 becomes 7413)
|
1_1 - dsr/dtr flow control (2413 becomes 7413)
|
||||||
|
|
||||||
NOTE: bit 11 also appears to be free, but Primos doesn't
|
NOTE: bit 11 also appears to be free, but Primos doesn't
|
||||||
let it flow through to the AMLC controller. :(
|
let it flow through to the AMLC controller. :(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,7 +841,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
double ts;
|
double ts;
|
||||||
int neweor, activelines;
|
int neweor, activelines;
|
||||||
//printf("poll device '%o, speedup=%5.2f, cti=%x, xmit=%x, recv=%x, dss=%x\n", device, pollspeedup, dc[dx].ctinterrupt, dc[dx].xmitenabled, dc[dx].recvenabled, dc[dx].dss);
|
//printf("poll device '%o, speedup=%5.2f, cti=%x, xmit=%x, recv=%x, dss=%x\n", device, pollspeedup, dc[dx].ctinterrupt, dc[dx].xmitenabled, dc[dx].recvenabled, dc[dx].dss);
|
||||||
|
|
||||||
/* check for 1 new telnet connection every AMLCACCEPTSECS seconds
|
/* check for 1 new telnet connection every AMLCACCEPTSECS seconds
|
||||||
(10 times per second) */
|
(10 times per second) */
|
||||||
|
|
||||||
@@ -1036,7 +1036,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
|
|
||||||
int fd, sockflags;
|
int fd, sockflags;
|
||||||
struct sockaddr_in raddr;
|
struct sockaddr_in raddr;
|
||||||
|
|
||||||
dc[dx].obtimer[lx] = tv.tv_sec + AMLCCONNECT;
|
dc[dx].obtimer[lx] = tv.tv_sec + AMLCCONNECT;
|
||||||
//printf("em: trying to connect to 0x%08x:%d\n", dc[dx].obhost[lx], dc[dx].obport[lx]); /***/
|
//printf("em: trying to connect to 0x%08x:%d\n", dc[dx].obhost[lx], dc[dx].obport[lx]); /***/
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
@@ -1121,7 +1121,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* process input, but only as much as will fit into the DMC
|
/* process input, but only as much as will fit into the DMC
|
||||||
buffer.
|
buffer.
|
||||||
|
|
||||||
Because the size of the AMLC tumble tables is limited, this
|
Because the size of the AMLC tumble tables is limited, this
|
||||||
could pose a denial of service issue. Input is processed in a
|
could pose a denial of service issue. Input is processed in a
|
||||||
|
|||||||
9
em.c
9
em.c
@@ -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))
|
||||||
@@ -657,6 +659,7 @@ static unsigned short *physmem = NULL; /* system's physical memory */
|
|||||||
#define LASTFAULT 077
|
#define LASTFAULT 077
|
||||||
|
|
||||||
//static ea_t tnoua_ea=0, tnou_ea=0, tsrc_ea=0;
|
//static ea_t tnoua_ea=0, tnou_ea=0, tsrc_ea=0;
|
||||||
|
static int noclock; /* -noclock arg */
|
||||||
static int domemdump; /* -memdump arg */
|
static int domemdump; /* -memdump arg */
|
||||||
static int dolinecleararg; /* -dolineclear arg */
|
static int dolinecleararg; /* -dolineclear arg */
|
||||||
|
|
||||||
@@ -4454,6 +4457,7 @@ int main (int argc, char **argv) {
|
|||||||
|
|
||||||
#include "dispatch.h"
|
#include "dispatch.h"
|
||||||
|
|
||||||
|
noclock = 0;
|
||||||
domemdump = 0;
|
domemdump = 0;
|
||||||
dolinecleararg = 0;
|
dolinecleararg = 0;
|
||||||
bootarg = NULL;
|
bootarg = NULL;
|
||||||
@@ -4472,6 +4476,9 @@ int main (int argc, char **argv) {
|
|||||||
while (i+1 < argc && argv[i+1][0] != '-')
|
while (i+1 < argc && argv[i+1][0] != '-')
|
||||||
readloadmap(argv[++i], 1);
|
readloadmap(argv[++i], 1);
|
||||||
|
|
||||||
|
} else if (strcmp(argv[i],"-noclock") == 0) {
|
||||||
|
noclock = 1;
|
||||||
|
|
||||||
} else if (strcmp(argv[i],"-memdump") == 0) {
|
} else if (strcmp(argv[i],"-memdump") == 0) {
|
||||||
domemdump = 1;
|
domemdump = 1;
|
||||||
|
|
||||||
@@ -4618,6 +4625,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)
|
||||||
|
|||||||
44
emdev.h
44
emdev.h
@@ -51,7 +51,7 @@
|
|||||||
'50 = #1 HSSMLC/MDLC (synchronous comm)
|
'50 = #1 HSSMLC/MDLC (synchronous comm)
|
||||||
'51 = #2 HSSMLC/MDLC
|
'51 = #2 HSSMLC/MDLC
|
||||||
* '52 = #3 AMLC or ICS1
|
* '52 = #3 AMLC or ICS1
|
||||||
* '53 = #2 AMLC
|
* '53 = #2 AMLC
|
||||||
* '54 = #1 AMLC
|
* '54 = #1 AMLC
|
||||||
'55 = MACI autocall unit
|
'55 = MACI autocall unit
|
||||||
'56 = old SMLC (RTOS User Guide, A-1 & Hacker's Guide)
|
'56 = old SMLC (RTOS User Guide, A-1 & Hacker's Guide)
|
||||||
@@ -229,7 +229,7 @@ int devnone (int class, int func, int device) {
|
|||||||
OCP '0604 = enable transmit DMA/C
|
OCP '0604 = enable transmit DMA/C
|
||||||
OCP '0704 = reset transmit interrupt mask and DMA/C enable
|
OCP '0704 = reset transmit interrupt mask and DMA/C enable
|
||||||
OCP '1004 = Full duplex; software must echo
|
OCP '1004 = Full duplex; software must echo
|
||||||
OCP '1104 = output a sync pulse (diagnostics)
|
OCP '1104 = output a sync pulse (diagnostics)
|
||||||
OCP '1204 = Prime normal, independent xmit and recv w/echoplex
|
OCP '1204 = Prime normal, independent xmit and recv w/echoplex
|
||||||
OCP '1304 = Self test mode (internally connects transmitter to receiver)
|
OCP '1304 = Self test mode (internally connects transmitter to receiver)
|
||||||
OCP '1504 = Set both xmit & rcv interrupt masks
|
OCP '1504 = Set both xmit & rcv interrupt masks
|
||||||
@@ -302,7 +302,7 @@ int devasr (int class, int func, int device) {
|
|||||||
int doblock;
|
int doblock;
|
||||||
time_t unixtime;
|
time_t unixtime;
|
||||||
struct tm *tms;
|
struct tm *tms;
|
||||||
|
|
||||||
doblock = BLOCKIO;
|
doblock = BLOCKIO;
|
||||||
|
|
||||||
switch (class) {
|
switch (class) {
|
||||||
@@ -330,7 +330,7 @@ int devasr (int class, int func, int device) {
|
|||||||
perror(" unable to get tty attributes");
|
perror(" unable to get tty attributes");
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save initial terminal setup to restore when exiting */
|
/* save initial terminal setup to restore when exiting */
|
||||||
|
|
||||||
origterminfo = terminfo;
|
origterminfo = terminfo;
|
||||||
@@ -497,7 +497,7 @@ readasr:
|
|||||||
goto readasr;
|
goto readasr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* if doing local echo, do xon/xoff processing here. If Unix
|
/* if doing local echo, do xon/xoff processing here. If Unix
|
||||||
does it, the emulator might block on a console write. If
|
does it, the emulator might block on a console write. If
|
||||||
the console is running full-duplex (no local echo), we can
|
the console is running full-duplex (no local echo), we can
|
||||||
@@ -650,7 +650,7 @@ readasr:
|
|||||||
|
|
||||||
/* Device '14 - magtape controller #1
|
/* Device '14 - magtape controller #1
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
|
|
||||||
This code only supports 1 tape controller (4 units), but could be
|
This code only supports 1 tape controller (4 units), but could be
|
||||||
extended to support 2 controllers (eg, see disk controller code)
|
extended to support 2 controllers (eg, see disk controller code)
|
||||||
@@ -863,7 +863,7 @@ fmterr:
|
|||||||
*mtstat |= 0x100; /* set filemark status */
|
*mtstat |= 0x100; /* set filemark status */
|
||||||
goto repo;
|
goto repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ignore attempts to backspace over error records. This will
|
/* ignore attempts to backspace over error records. This will
|
||||||
cause Magsav to read the next record instead, and it may
|
cause Magsav to read the next record instead, and it may
|
||||||
recover. Re-reading the error record 10 times won't help! */
|
recover. Re-reading the error record 10 times won't help! */
|
||||||
@@ -881,7 +881,7 @@ fmterr:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read leading reclen again to make sure we're positioned correctly */
|
/* read leading reclen again to make sure we're positioned correctly */
|
||||||
|
|
||||||
n = read(fd, buf, 4);
|
n = read(fd, buf, 4);
|
||||||
if (n == -1) goto readerr;
|
if (n == -1) goto readerr;
|
||||||
if (n != 4) {
|
if (n != 4) {
|
||||||
@@ -974,7 +974,7 @@ int devmt (int class, int func, int device) {
|
|||||||
enabled = 1;
|
enabled = 1;
|
||||||
if (interrupting == 1) /* if interrupt is pending */
|
if (interrupting == 1) /* if interrupt is pending */
|
||||||
devpoll[device] = 10; /* try to interrupt soon */
|
devpoll[device] = 10; /* try to interrupt soon */
|
||||||
|
|
||||||
} else if (func == 016) { /* reset interrupt mask */
|
} else if (func == 016) { /* reset interrupt mask */
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
|
|
||||||
@@ -1092,7 +1092,7 @@ int devmt (int class, int func, int device) {
|
|||||||
} else
|
} else
|
||||||
unit[u].mtstat = 0x00C8; /* Ready, Online, BOT */
|
unit[u].mtstat = 0x00C8; /* Ready, Online, BOT */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "select only" is ignored. On a real tape controller, this
|
/* "select only" is ignored. On a real tape controller, this
|
||||||
blocks (I think) if the previous tape operation is in progress */
|
blocks (I think) if the previous tape operation is in progress */
|
||||||
|
|
||||||
@@ -1276,12 +1276,12 @@ int devmt (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
IOSKIP;
|
IOSKIP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (func == 02) {
|
} else if (func == 02) {
|
||||||
ready = 1;
|
ready = 1;
|
||||||
if (getcrs16(A) & 0x8000) { /* status word 1 */
|
if (getcrs16(A) & 0x8000) { /* status word 1 */
|
||||||
datareg = unit[usel].mtstat;
|
datareg = unit[usel].mtstat;
|
||||||
|
|
||||||
/* if the tape was rewinding, return rewinding status once, then
|
/* if the tape was rewinding, return rewinding status once, then
|
||||||
change it to BOT */
|
change it to BOT */
|
||||||
|
|
||||||
@@ -1413,7 +1413,9 @@ void initclock(ea_t datnowea) {
|
|||||||
unixtime = time(NULL);
|
unixtime = time(NULL);
|
||||||
tms = localtime(&unixtime);
|
tms = localtime(&unixtime);
|
||||||
datnow = tms->tm_year<<25 | (tms->tm_mon+1)<<21 | tms->tm_mday<<16 | ((tms->tm_hour*3600 + tms->tm_min*60 + tms->tm_sec)/4);
|
datnow = tms->tm_year<<25 | (tms->tm_mon+1)<<21 | tms->tm_mday<<16 | ((tms->tm_hour*3600 + tms->tm_min*60 + tms->tm_sec)/4);
|
||||||
put32r0(datnow, datnowea);
|
if (! noclock) {
|
||||||
|
put32r0(datnow, datnowea);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1438,7 +1440,7 @@ int devcp (int class, int func, int device) {
|
|||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
|
|
||||||
/* if -map is used, lookup DATNOW symbol and set the 32-bit
|
/* if -map is used, lookup DATNOW symbol and set the 32-bit
|
||||||
Primos time value (DATNOW+TIMNOW) */
|
Primos time value (DATNOW+TIMNOW) */
|
||||||
|
|
||||||
datnowea = 0;
|
datnowea = 0;
|
||||||
@@ -1455,10 +1457,10 @@ int devcp (int class, int func, int device) {
|
|||||||
;
|
;
|
||||||
|
|
||||||
} else if (func == 01) { /* ack PIC interrupt */
|
} else if (func == 01) { /* ack PIC interrupt */
|
||||||
;
|
;
|
||||||
|
|
||||||
} else if (func == 02) { /* stop LFC (IO.PNC DIAG) */
|
} else if (func == 02) { /* stop LFC (IO.PNC DIAG) */
|
||||||
;
|
;
|
||||||
|
|
||||||
} else if (func == 04) { /* does something on VCP during boot */
|
} else if (func == 04) { /* does something on VCP during boot */
|
||||||
;
|
;
|
||||||
@@ -1581,7 +1583,7 @@ int devcp (int class, int func, int device) {
|
|||||||
previnstcount = gv.instcount;
|
previnstcount = gv.instcount;
|
||||||
if (datnowea != 0)
|
if (datnowea != 0)
|
||||||
initclock(datnowea);
|
initclock(datnowea);
|
||||||
}
|
}
|
||||||
elapsedms = (tv.tv_sec-start_tv.tv_sec)*1000.0 + (tv.tv_usec-start_tv.tv_usec)/1000.0;
|
elapsedms = (tv.tv_sec-start_tv.tv_sec)*1000.0 + (tv.tv_usec-start_tv.tv_usec)/1000.0;
|
||||||
targetticks = elapsedms/(-clkpic*clkrate/1000);
|
targetticks = elapsedms/(-clkpic*clkrate/1000);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -1595,7 +1597,7 @@ int devcp (int class, int func, int device) {
|
|||||||
available (no Primos maps), then we have to tick our way to
|
available (no Primos maps), then we have to tick our way to
|
||||||
the correct time. In addition to lowering overhead, slower
|
the correct time. In addition to lowering overhead, slower
|
||||||
clock tick rates make catching up much faster.
|
clock tick rates make catching up much faster.
|
||||||
|
|
||||||
When ticking faster, we need to be careful not to tick too
|
When ticking faster, we need to be careful not to tick too
|
||||||
fast, because that will cause timed events like disk I/O to
|
fast, because that will cause timed events like disk I/O to
|
||||||
timeout prematurely. With rev 20 Primos, setting the
|
timeout prematurely. With rev 20 Primos, setting the
|
||||||
@@ -1812,7 +1814,7 @@ int devdisk (int class, int func, int device) {
|
|||||||
dc[dx].unit[u].modrecs = NULL;
|
dc[dx].unit[u].modrecs = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
TRACE(T_INST|T_DIO, " OCP '%2o%2o\n", func, device);
|
TRACE(T_INST|T_DIO, " OCP '%2o%2o\n", func, device);
|
||||||
if (func == 016) { /* reset interrupt */
|
if (func == 016) { /* reset interrupt */
|
||||||
@@ -2017,7 +2019,7 @@ int devdisk (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
dmaaddr = ((getar16(REGDMX16+dmareg) & 3)<<16) | getar16(REGDMX16+dmareg+1);
|
dmaaddr = ((getar16(REGDMX16+dmareg) & 3)<<16) | getar16(REGDMX16+dmareg+1);
|
||||||
TRACE(T_INST|T_DIO, " DMA channels: nch-1=%d, ['%o]='%o, ['%o]='%o, nwords=%d\n", dc[dx].dmanch, dc[dx].dmachan, swap16(regs.sym.regdmx[dmareg]), dc[dx].dmachan+1, dmaaddr, dmanw);
|
TRACE(T_INST|T_DIO, " DMA channels: nch-1=%d, ['%o]='%o, ['%o]='%o, nwords=%d\n", dc[dx].dmanch, dc[dx].dmachan, swap16(regs.sym.regdmx[dmareg]), dc[dx].dmachan+1, dmaaddr, dmanw);
|
||||||
|
|
||||||
if (order == 5) { /* read */
|
if (order == 5) { /* read */
|
||||||
if (getcrs16(MODALS) & 020) /* mapped read */
|
if (getcrs16(MODALS) & 020) /* mapped read */
|
||||||
if ((dmaaddr & 01777) || dmanw > 1024)
|
if ((dmaaddr & 01777) || dmanw > 1024)
|
||||||
@@ -2078,7 +2080,7 @@ int devdisk (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
TRACE(T_INST|T_DIO, " seek track %d, restore=%d, clear=%d\n", track, (m1 & 0100000) != 0, (m1 & 040000) != 0);
|
TRACE(T_INST|T_DIO, " seek track %d, restore=%d, clear=%d\n", track, (m1 & 0100000) != 0, (m1 & 040000) != 0);
|
||||||
#if 0
|
#if 0
|
||||||
/* this has been disabled because SCSI drives sometimes seek to
|
/* this has been disabled because SCSI drives sometimes seek to
|
||||||
track 512 (special meaning in controller?) */
|
track 512 (special meaning in controller?) */
|
||||||
|
|
||||||
if (track > dc[dx].unit[u].maxtrack) {
|
if (track > dc[dx].unit[u].maxtrack) {
|
||||||
|
|||||||
84
fp.h
84
fp.h
@@ -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,13 +90,15 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -386,7 +434,7 @@ int fcs (unsigned long long fac, int fop) {
|
|||||||
|
|
||||||
NOTE: This code doesn't pass Prime diagnostics for higher model
|
NOTE: This code doesn't pass Prime diagnostics for higher model
|
||||||
CPU's, I'm guessing because comparison is implemented as subtract,
|
CPU's, I'm guessing because comparison is implemented as subtract,
|
||||||
and we can't do that because numbers with huge exponents (and
|
and we can't do that because numbers with huge exponents (and
|
||||||
Prime ASCII characters in the DAC) won't convert to IEEE.
|
Prime ASCII characters in the DAC) won't convert to IEEE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -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 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* utextp.c, Jim Wilcoxson, March 16, 2005
|
/* utextp.c, Jim Wilcoxson, March 16, 2005
|
||||||
Reads a Unix text file and converts it to a compressed Prime text file.
|
Reads a Unix text file and converts it to a compressed Prime text file.
|
||||||
This means:
|
This means:
|
||||||
- turn high bit on
|
- turn high bit on
|
||||||
- expand Unix tabs to spaces
|
- expand Unix tabs to spaces
|
||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user