mirror of
https://github.com/prirun/p50em.git
synced 2026-03-29 02:44:55 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7059340ad4 |
@@ -1,15 +0,0 @@
|
|||||||
# .editorconfig, Boone, 02/11/21
|
|
||||||
# Editor behavior settings
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[makefile]
|
|
||||||
indent_style = tab
|
|
||||||
26
.github/workflows/freebsdbuild.yml
vendored
26
.github/workflows/freebsdbuild.yml
vendored
@@ -1,26 +0,0 @@
|
|||||||
name: freebsdbuild
|
|
||||||
|
|
||||||
on: workflow_dispatch
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- uses: "actions/checkout@v2"
|
|
||||||
- uses: "vmactions/freebsd-vm@v0.1.3"
|
|
||||||
with:
|
|
||||||
usesh: true
|
|
||||||
prepare: pkg install -y curl git
|
|
||||||
run: |
|
|
||||||
make
|
|
||||||
- uses: "marvinpinto/action-automatic-releases@latest"
|
|
||||||
with:
|
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
automatic_release_tag: "latest"
|
|
||||||
prerelease: false
|
|
||||||
title: "Bleeding Edge Binary - FreeBSD"
|
|
||||||
files: |
|
|
||||||
LICENSE
|
|
||||||
README.md
|
|
||||||
em.1
|
|
||||||
em
|
|
||||||
22
.github/workflows/linuxbuild.yml
vendored
22
.github/workflows/linuxbuild.yml
vendored
@@ -1,22 +0,0 @@
|
|||||||
name: linuxbuild
|
|
||||||
|
|
||||||
on: workflow_dispatch
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: "actions/checkout@v2"
|
|
||||||
- name: make
|
|
||||||
run: make
|
|
||||||
- uses: "marvinpinto/action-automatic-releases@latest"
|
|
||||||
with:
|
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
automatic_release_tag: "latest"
|
|
||||||
prerelease: false
|
|
||||||
title: "Bleeding Edge Binary - Ubuntu"
|
|
||||||
files: |
|
|
||||||
LICENSE
|
|
||||||
README.md
|
|
||||||
em.1
|
|
||||||
em
|
|
||||||
22
.github/workflows/macbuild.yml
vendored
22
.github/workflows/macbuild.yml
vendored
@@ -1,22 +0,0 @@
|
|||||||
name: macbuild
|
|
||||||
|
|
||||||
on: workflow_dispatch
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- uses: "actions/checkout@v2"
|
|
||||||
- name: make
|
|
||||||
run: make
|
|
||||||
- uses: "marvinpinto/action-automatic-releases@latest"
|
|
||||||
with:
|
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
automatic_release_tag: "latest"
|
|
||||||
prerelease: false
|
|
||||||
title: "Bleeding Edge Binary - MacOS"
|
|
||||||
files: |
|
|
||||||
LICENSE
|
|
||||||
README.md
|
|
||||||
em.1
|
|
||||||
em
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,7 +3,6 @@
|
|||||||
*.log
|
*.log
|
||||||
*.swp
|
*.swp
|
||||||
tags
|
tags
|
||||||
cmraw
|
|
||||||
cscope.*
|
cscope.*
|
||||||
em
|
em
|
||||||
emlink
|
emlink
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ the host processor having a large set of general-purpose registers.
|
|||||||
Coming soon, we swear! There is a unix man page included in this
|
Coming soon, we swear! There is a unix man page included in this
|
||||||
repository.
|
repository.
|
||||||
|
|
||||||
Github discussions are now enabled for this repository, and can be
|
|
||||||
used to ask for help.
|
|
||||||
|
|
||||||
## Public Systems
|
## Public Systems
|
||||||
|
|
||||||
There are a set of emulators available for public use. These may be
|
There are a set of emulators available for public use. These may be
|
||||||
@@ -55,7 +52,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_installoview.html).
|
[here](https://sysovl.info/reference_prime_drb_installing_primos.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).
|
||||||
|
|||||||
62
devamlc.h
62
devamlc.h
@@ -150,8 +150,6 @@ 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 */
|
||||||
@@ -264,7 +262,6 @@ int devamlc (int class, int func, int device) {
|
|||||||
unsigned short ctinterrupt; /* 1 bit per line */
|
unsigned short ctinterrupt; /* 1 bit per line */
|
||||||
unsigned short dss; /* 1 bit per line */
|
unsigned short dss; /* 1 bit per line */
|
||||||
unsigned short connected; /* 1 bit per line */
|
unsigned short connected; /* 1 bit per line */
|
||||||
unsigned short dolineclear; /* 1 bit per line */
|
|
||||||
unsigned short serial; /* true if any CT_SERIAL lines */
|
unsigned short serial; /* true if any CT_SERIAL lines */
|
||||||
unsigned short dsstime; /* countdown to dss poll */
|
unsigned short dsstime; /* countdown to dss poll */
|
||||||
short fd[16]; /* Unix fd, 1 per line */
|
short fd[16]; /* Unix fd, 1 per line */
|
||||||
@@ -332,7 +329,6 @@ int devamlc (int class, int func, int device) {
|
|||||||
for (dx=0; dx<MAXBOARDS; dx++) {
|
for (dx=0; dx<MAXBOARDS; dx++) {
|
||||||
dc[dx].deviceid = 0;
|
dc[dx].deviceid = 0;
|
||||||
dc[dx].connected = 0;
|
dc[dx].connected = 0;
|
||||||
dc[dx].dolineclear = 0;
|
|
||||||
dc[dx].serial = 0;
|
dc[dx].serial = 0;
|
||||||
for (lx = 0; lx < 16; lx++) {
|
for (lx = 0; lx < 16; lx++) {
|
||||||
dc[dx].fd[lx] = -1;
|
dc[dx].fd[lx] = -1;
|
||||||
@@ -561,7 +557,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;
|
||||||
@@ -577,7 +573,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);
|
||||||
@@ -760,6 +756,7 @@ 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");
|
||||||
@@ -772,6 +769,7 @@ int devamlc (int class, int func, int device) {
|
|||||||
}
|
}
|
||||||
ioctl(fd, TIOCMSET, &modemstate);
|
ioctl(fd, TIOCMSET, &modemstate);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,7 +885,6 @@ int devamlc (int class, int func, int device) {
|
|||||||
close(dc[i].fd[lx]);
|
close(dc[i].fd[lx]);
|
||||||
dc[i].dss |= BITMASK16(lx+1);
|
dc[i].dss |= BITMASK16(lx+1);
|
||||||
dc[i].connected |= BITMASK16(lx+1);
|
dc[i].connected |= BITMASK16(lx+1);
|
||||||
dc[i].dolineclear |= BITMASK16(lx+1);
|
|
||||||
dc[i].fd[lx] = fd;
|
dc[i].fd[lx] = fd;
|
||||||
dc[i].tstate[lx] = TS_DATA;
|
dc[i].tstate[lx] = TS_DATA;
|
||||||
//printf("em: AMLC connection, fd=%d, device='%o, line=%d\n", fd, dc[i].deviceid, lx);
|
//printf("em: AMLC connection, fd=%d, device='%o, line=%d\n", fd, dc[i].deviceid, lx);
|
||||||
@@ -914,12 +911,10 @@ int devamlc (int class, int func, int device) {
|
|||||||
optval = 1;
|
optval = 1;
|
||||||
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) == -1)
|
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) == -1)
|
||||||
perror("unable to set TCP_NODELAY");
|
perror("unable to set TCP_NODELAY");
|
||||||
#ifndef __APPLE__
|
|
||||||
/* Set 600 second keepalive idle time for this socket */
|
/* Set 600 second keepalive idle time for this socket */
|
||||||
optval = 600;
|
optval = 600;
|
||||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, sizeof(optval)) == -1)
|
if (setsockopt(fd, 6 /* TCP */, TCP_KEEPIDLE, &optval, sizeof(optval)) == -1)
|
||||||
perror("unable to set TCP_KEEPIDLE");
|
perror("unable to set TCP_KEEPIDLE");
|
||||||
#endif
|
|
||||||
/* ... and turn on keepalive */
|
/* ... and turn on keepalive */
|
||||||
optval = 1;
|
optval = 1;
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
||||||
@@ -1143,53 +1138,6 @@ dorecv:
|
|||||||
if (dc[dx].deviceid == 0 || dc[dx].connected == 0 || dc[dx].eor)
|
if (dc[dx].deviceid == 0 || dc[dx].connected == 0 || dc[dx].eor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Inject xon / kill if dolineclear is true */
|
|
||||||
|
|
||||||
if (dolinecleararg)
|
|
||||||
for (lx = 0; lx < 16; lx++)
|
|
||||||
if (dc[dx].dolineclear & BITMASK16(lx+1))
|
|
||||||
{
|
|
||||||
unsigned char ch;
|
|
||||||
unsigned short utemp;
|
|
||||||
int dmcpair, lcount;
|
|
||||||
ea_t dmcea, dmcbufbegea, dmcbufendea;
|
|
||||||
unsigned short dmcnw;
|
|
||||||
|
|
||||||
if (dc[dx].bufnum)
|
|
||||||
dmcea = dc[dx].dmcchan + 2;
|
|
||||||
else
|
|
||||||
dmcea = dc[dx].dmcchan;
|
|
||||||
dmcpair = get32io(dmcea);
|
|
||||||
dmcbufbegea = dmcpair>>16;
|
|
||||||
dmcbufendea = dmcpair & 0xffff;
|
|
||||||
dmcnw = dmcbufendea - dmcbufbegea + 1;
|
|
||||||
|
|
||||||
if (dmcnw < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
utemp = lx<<12 | 0x0200 | 0221; /* dc1/xon */
|
|
||||||
put16io(utemp, dmcbufbegea);
|
|
||||||
dmcbufbegea = INCVA(dmcbufbegea, 1);
|
|
||||||
|
|
||||||
ch = (unsigned char)get16(MAKEVA(014, 0705));
|
|
||||||
utemp = lx<<12 | 0x0200 | ch; /* kill */
|
|
||||||
put16io(utemp, dmcbufbegea);
|
|
||||||
dmcbufbegea = INCVA(dmcbufbegea, 1);
|
|
||||||
|
|
||||||
dc[dx].recvlx = lx;
|
|
||||||
if (dmcbufbegea-1 > dmcbufendea)
|
|
||||||
fatal("AMLC tumble table overflowed?");
|
|
||||||
put16io(dmcbufbegea, dmcea);
|
|
||||||
if (dmcbufbegea > dmcbufendea) { /* end of range has occurred */
|
|
||||||
dc[dx].bufnum = 1-dc[dx].bufnum;
|
|
||||||
dc[dx].eor = 1;
|
|
||||||
neweor = 1;
|
|
||||||
anyeor = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc[dx].dolineclear &= ~BITMASK16(lx+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* select to see which lines have data to be read */
|
/* select to see which lines have data to be read */
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
|
|||||||
33
em.1
33
em.1
@@ -2,7 +2,7 @@
|
|||||||
.\" em.1, Boone, 03/13/20
|
.\" em.1, Boone, 03/13/20
|
||||||
.\" Man page for Jim Wilcoxson's Prime 50-Series emulator
|
.\" Man page for Jim Wilcoxson's Prime 50-Series emulator
|
||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
.TH em 1 "2020-06-23" "Jim Wilcoxson" "50-Series Emulator"
|
.TH em 1 "2020-03-14" "Jim Wilcoxson" "50-Series Emulator"
|
||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
.SH NAME
|
.SH NAME
|
||||||
em \- Emulator for Prime 50-Series systems
|
em \- Emulator for Prime 50-Series systems
|
||||||
@@ -35,8 +35,6 @@ a tape controller, 4 drives, using the .TAP format
|
|||||||
.IP \(bu
|
.IP \(bu
|
||||||
a PNC controller emulating RingNet over TCP/IP
|
a PNC controller emulating RingNet over TCP/IP
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
two sync serial controllers supporting up to 8 lines
|
|
||||||
.IP \(bu
|
|
||||||
a bypass for Primos system serial number checks
|
a bypass for Primos system serial number checks
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
Unix utilities to read/write physical tapes & Magsav tapes
|
Unix utilities to read/write physical tapes & Magsav tapes
|
||||||
@@ -145,15 +143,6 @@ on the host. Multiple trace types may be listed, separated by
|
|||||||
spaces. Tracing may be initially turned off by including the
|
spaces. Tracing may be initially turned off by including the
|
||||||
.I off
|
.I off
|
||||||
trace type.
|
trace type.
|
||||||
.PP
|
|
||||||
\fB-dolineclear\fR
|
|
||||||
.IP
|
|
||||||
Inject an XON (DC1, 0221) character and a line kill character into the
|
|
||||||
input buffers each time an AMLC line receives an incoming connection.
|
|
||||||
The system's configured line kill character is fetched from the
|
|
||||||
DEFKIL field of FIGCOM, at address 14(0)/705. This behavior helps
|
|
||||||
counteract lines which have been blocked by internet vulnerability
|
|
||||||
scanners injecting non-telnet data streams.
|
|
||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
@@ -174,18 +163,6 @@ Example:
|
|||||||
8 192.168.10.4:9000 # Outbound socket connection e.g. for spooler
|
8 192.168.10.4:9000 # Outbound socket connection e.g. for spooler
|
||||||
.EE
|
.EE
|
||||||
.TP
|
.TP
|
||||||
smlc.cfg
|
|
||||||
Used to associate outbound sync serial (MDLC or HSSMLC) lines with destination
|
|
||||||
IP addresses and port numbers, or to associate inbound sync serial lines
|
|
||||||
with port numbers. An outbound line corresponds to an RJE site defined as a
|
|
||||||
SLAVE site, and an inbound line corresponds to an RJE site defined as a MASTER
|
|
||||||
site. Optional. Comments work the same as amlc.cfg. Example:
|
|
||||||
|
|
||||||
.EX
|
|
||||||
0 10.1.1.3:2554 # Connect to TCP port 2554 of host 10.1.1.3 for outbound line 0
|
|
||||||
1 9951 # Listen on TCP port 9951 for inbound line 1
|
|
||||||
.EE
|
|
||||||
.TP
|
|
||||||
console.log
|
console.log
|
||||||
All console output is also written to this file. It is overwritten
|
All console output is also written to this file. It is overwritten
|
||||||
at each invocation. Created by
|
at each invocation. Created by
|
||||||
@@ -297,12 +274,9 @@ off|Start with tracing disabled
|
|||||||
all|Everything
|
all|Everything
|
||||||
flush|Flush trace file after each write
|
flush|Flush trace file after each write
|
||||||
tlb|STLB and IOTLB changes
|
tlb|STLB and IOTLB changes
|
||||||
smlc|MDLC/HSSMLC device I/O
|
|
||||||
OWNERL|Execution of this PCB
|
OWNERL|Execution of this PCB
|
||||||
#instruction count|Begin after specified number of instructions
|
instruction count|Begin after specified number of instructions
|
||||||
|(the leading # is literal)
|
|
||||||
octal segno|Execution in the given segment number
|
octal segno|Execution in the given segment number
|
||||||
|(may interact poorly with "off")
|
|
||||||
process number|Execution of this user number
|
process number|Execution of this user number
|
||||||
.TE
|
.TE
|
||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
@@ -386,8 +360,7 @@ CMD,1/3/5+1,Cartridge Module 32/64/96 MB
|
|||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
.PP
|
.PP
|
||||||
This emulator was written by Jim Wilcoxson. MDLC/HSSMLC support by
|
This emulator was written by Jim Wilcoxson. Man page by Dennis Boone.
|
||||||
Kevin Jordan. Man page by Dennis Boone.
|
|
||||||
.\" ---------------------------------------------------------------------------
|
.\" ---------------------------------------------------------------------------
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
This project is hosted at
|
This project is hosted at
|
||||||
|
|||||||
72
em.c
72
em.c
@@ -1,5 +1,5 @@
|
|||||||
/* Pr1me Computer emulator, Jim Wilcoxson (prirun@gmail.com), April 4, 2005
|
/* Pr1me Computer emulator, Jim Wilcoxson (prirun@gmail.com), April 4, 2005
|
||||||
Copyright (C) 2005-2021, Jim Wilcoxson. All Rights Reserved.
|
Copyright (C) 2005-2019, Jim Wilcoxson. All Rights Reserved.
|
||||||
|
|
||||||
Emulates a Prime Computer system by:
|
Emulates a Prime Computer system by:
|
||||||
- booting from a Prime disk image (normal usage)
|
- booting from a Prime disk image (normal usage)
|
||||||
@@ -274,7 +274,6 @@ 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
|
||||||
@@ -288,7 +287,6 @@ static void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int
|
|||||||
T_PX Process exchange
|
T_PX Process exchange
|
||||||
T_LM License manager
|
T_LM License manager
|
||||||
T_TLB STLB and IOTLB changes
|
T_TLB STLB and IOTLB changes
|
||||||
T_SMLC SMLC device I/O
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define T_EAR 0x00000001
|
#define T_EAR 0x00000001
|
||||||
@@ -311,8 +309,6 @@ static void macheck (unsigned short p300vec, unsigned short chkvec, unsigned int
|
|||||||
#define T_GET 0x00020000
|
#define T_GET 0x00020000
|
||||||
#define T_EAS 0x00040000
|
#define T_EAS 0x00040000
|
||||||
#define T_TLB 0x00080000
|
#define T_TLB 0x00080000
|
||||||
#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))
|
||||||
@@ -659,9 +655,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 tport; /* -tport option (incoming terminals) */
|
static int tport; /* -tport option (incoming terminals) */
|
||||||
static int nport; /* -nport option (PNC/Ringnet) */
|
static int nport; /* -nport option (PNC/Ringnet) */
|
||||||
@@ -1695,8 +1689,6 @@ static int devpoll[64] = {0};
|
|||||||
'35 = devamlc: 4th AMLC (16 lines)
|
'35 = devamlc: 4th AMLC (16 lines)
|
||||||
'45 = devdisk: 7th disk controller (8 drives)
|
'45 = devdisk: 7th disk controller (8 drives)
|
||||||
'46 = devdisk: 8th disk controller (8 drives)
|
'46 = devdisk: 8th disk controller (8 drives)
|
||||||
'50 = devsmlc: 1st HSSMLC/MDLC (4 lines)
|
|
||||||
'51 = devsmlc: 2nd HSSMLC/MDLC (4 lines)
|
|
||||||
'52 = devamlc: 3rd AMLC (16 lines)
|
'52 = devamlc: 3rd AMLC (16 lines)
|
||||||
'53 = devamlc: 2nd AMLC (16 lines)
|
'53 = devamlc: 2nd AMLC (16 lines)
|
||||||
'54 = devamlc: 1st AMLC (16 lines)
|
'54 = devamlc: 1st AMLC (16 lines)
|
||||||
@@ -1708,7 +1700,7 @@ static int (*devmap[64])(int, int, int) = {
|
|||||||
/* '2x */ devcp,devnone,devdisk,devdisk,devdisk,devdisk,devdisk,devdisk,
|
/* '2x */ devcp,devnone,devdisk,devdisk,devdisk,devdisk,devdisk,devdisk,
|
||||||
/* '3x */ devnone,devnone,devamlc,devnone,devnone,devamlc,devnone,devnone,
|
/* '3x */ devnone,devnone,devamlc,devnone,devnone,devamlc,devnone,devnone,
|
||||||
/* '4x */ devnone,devnone,devnone,devnone,devnone,devdisk,devdisk,devnone,
|
/* '4x */ devnone,devnone,devnone,devnone,devnone,devdisk,devdisk,devnone,
|
||||||
/* '5x */ devsmlc,devsmlc,devamlc,devamlc,devamlc,devnone,devnone,devnone,
|
/* '5x */ devnone,devnone,devamlc,devamlc,devamlc,devnone,devnone,devnone,
|
||||||
/* '6x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
/* '6x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
||||||
/* '7x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone};
|
/* '7x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone};
|
||||||
|
|
||||||
@@ -1722,7 +1714,6 @@ static int (*devmap[64])(int, int, int) = {
|
|||||||
'20 = devcp: clock / VCP / SOC
|
'20 = devcp: clock / VCP / SOC
|
||||||
'26 = devdisk: 1st disk controller (8 drives)
|
'26 = devdisk: 1st disk controller (8 drives)
|
||||||
'27 = devdisk: 2nd disk controller (8 drives)
|
'27 = devdisk: 2nd disk controller (8 drives)
|
||||||
'50 = devsmlc: 1st HSSMLC/MDLC (4 lines)
|
|
||||||
'54 = 1st amlc (terminal) controller (16 lines)
|
'54 = 1st amlc (terminal) controller (16 lines)
|
||||||
'53 = devamlc: 2nd AMLC (16 lines)
|
'53 = devamlc: 2nd AMLC (16 lines)
|
||||||
*/
|
*/
|
||||||
@@ -1733,7 +1724,7 @@ static int (*devmap[64])(int, int, int) = {
|
|||||||
/* '2x */ devcp,devnone,devnone,devnone,devnone,devnone,devdisk,devdisk,
|
/* '2x */ devcp,devnone,devnone,devnone,devnone,devnone,devdisk,devdisk,
|
||||||
/* '3x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
/* '3x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
||||||
/* '4x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
/* '4x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
||||||
/* '5x */ devsmlc,devnone,devnone,devamlc,devamlc,devnone,devnone,devnone,
|
/* '5x */ devnone,devnone,devnone,devamlc,devamlc,devnone,devnone,devnone,
|
||||||
/* '6x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
/* '6x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone,
|
||||||
/* '7x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone};
|
/* '7x */ devnone,devnone,devnone,devnone,devnone,devnone,devnone,devnone};
|
||||||
#endif
|
#endif
|
||||||
@@ -2355,7 +2346,7 @@ special:
|
|||||||
static ea_t apea(unsigned short *bitarg) {
|
static ea_t apea(unsigned short *bitarg) {
|
||||||
unsigned short ibr, ea_s, ea_w, bit, br, a;
|
unsigned short ibr, ea_s, ea_w, bit, br, a;
|
||||||
unsigned int utempl;
|
unsigned int utempl;
|
||||||
ea_t ea, ip, iwea;
|
ea_t ea, ip;
|
||||||
|
|
||||||
eap = &gv.brp[RPBR];
|
eap = &gv.brp[RPBR];
|
||||||
utempl = get32(RP);
|
utempl = get32(RP);
|
||||||
@@ -2381,11 +2372,8 @@ static ea_t apea(unsigned short *bitarg) {
|
|||||||
bit = get16(INCVA(ea,2)) >> 12;
|
bit = get16(INCVA(ea,2)) >> 12;
|
||||||
else
|
else
|
||||||
bit = 0;
|
bit = 0;
|
||||||
iwea = ea;
|
|
||||||
ea = ip;
|
ea = ip;
|
||||||
TRACE(T_EAAP, " After indirect, AP ea = %o/%o, bit=%d %s\n", ea>>16, ea & 0xFFFF, bit, searchloadmap(ea,' '));
|
TRACE(T_EAAP, " After indirect, AP ea = %o/%o, bit=%d %s\n", ea>>16, ea & 0xFFFF, bit, searchloadmap(ea,' '));
|
||||||
if (ea & 0x80000000)
|
|
||||||
fault(POINTERFAULT, ea>>16, iwea);
|
|
||||||
}
|
}
|
||||||
if (bitarg != NULL)
|
if (bitarg != NULL)
|
||||||
*bitarg = bit;
|
*bitarg = bit;
|
||||||
@@ -4375,7 +4363,7 @@ int main (int argc, char **argv) {
|
|||||||
#define XRBRACE 0375
|
#define XRBRACE 0375
|
||||||
|
|
||||||
printf("[Prime Emulator ver %s %s]\n", REV, __DATE__);
|
printf("[Prime Emulator ver %s %s]\n", REV, __DATE__);
|
||||||
printf("[Copyright (C) 2005-2021 Jim Wilcoxson prirun@gmail.com]\n");
|
printf("[Copyright (C) 2005-2019 Jim Wilcoxson prirun@gmail.com]\n");
|
||||||
if (argc > 1 && (strcmp(argv[1],"--version") == 0)) {
|
if (argc > 1 && (strcmp(argv[1],"--version") == 0)) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@@ -4457,9 +4445,7 @@ int main (int argc, char **argv) {
|
|||||||
|
|
||||||
#include "dispatch.h"
|
#include "dispatch.h"
|
||||||
|
|
||||||
noclock = 0;
|
|
||||||
domemdump = 0;
|
domemdump = 0;
|
||||||
dolinecleararg = 0;
|
|
||||||
bootarg = NULL;
|
bootarg = NULL;
|
||||||
bootfile[0] = 0;
|
bootfile[0] = 0;
|
||||||
gv.pmap32bits = 0;
|
gv.pmap32bits = 0;
|
||||||
@@ -4476,15 +4462,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;
|
||||||
|
|
||||||
} else if (strcmp(argv[i],"-dolineclear") == 0) {
|
|
||||||
dolinecleararg = 1;
|
|
||||||
|
|
||||||
} else if (strcmp(argv[i],"-ss") == 0) {
|
} else if (strcmp(argv[i],"-ss") == 0) {
|
||||||
if (i+1 < argc && argv[i+1][0] != '-') {
|
if (i+1 < argc && argv[i+1][0] != '-') {
|
||||||
sscanf(argv[++i],"%o", &templ);
|
sscanf(argv[++i],"%o", &templ);
|
||||||
@@ -4623,18 +4603,14 @@ int main (int argc, char **argv) {
|
|||||||
setlinebuf(gv.tracefile);
|
setlinebuf(gv.tracefile);
|
||||||
else if (strcmp(argv[i],"tlb") == 0)
|
else if (strcmp(argv[i],"tlb") == 0)
|
||||||
gv.traceflags |= T_TLB;
|
gv.traceflags |= T_TLB;
|
||||||
else if (strcmp(argv[i],"smlc") == 0)
|
|
||||||
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 (isdigit(argv[i][0]) && sscanf(argv[i],"%d", &templ) == 1)
|
||||||
|
gv.traceinstcount = templ;
|
||||||
else if (strlen(argv[i]) == 6 && sscanf(argv[i],"%o", &templ) == 1)
|
else if (strlen(argv[i]) == 6 && sscanf(argv[i],"%o", &templ) == 1)
|
||||||
gv.traceuser = templ; /* specify OWNERL directly */
|
gv.traceuser = templ; /* specify OWNERL directly */
|
||||||
else if (strlen(argv[i]) == 4 && sscanf(argv[i],"%o", &templ) == 1)
|
else if (strlen(argv[i]) == 4 && sscanf(argv[i],"%o", &templ) == 1)
|
||||||
gv.traceseg = templ; /* specify RPH segno */
|
gv.traceseg = templ; /* specify RPH segno */
|
||||||
else if (argv[i][0] == '#' && sscanf(argv[i]+1,"%d", &templ) == 1)
|
|
||||||
gv.traceinstcount = templ;
|
|
||||||
else if (strlen(argv[i]) <= 8 && argv[i][0] != '-') {
|
else if (strlen(argv[i]) <= 8 && argv[i][0] != '-') {
|
||||||
if (gv.numtraceprocs >= MAXTRACEPROCS)
|
if (gv.numtraceprocs >= MAXTRACEPROCS)
|
||||||
fprintf(stderr,"Only %d trace procs are allowed\n", MAXTRACEPROCS);
|
fprintf(stderr,"Only %d trace procs are allowed\n", MAXTRACEPROCS);
|
||||||
@@ -4725,7 +4701,6 @@ int main (int argc, char **argv) {
|
|||||||
/* finish setting up tracing after all options are read, ie, maps */
|
/* finish setting up tracing after all options are read, ie, maps */
|
||||||
|
|
||||||
#ifndef NOTRACE
|
#ifndef NOTRACE
|
||||||
TRACEA("Trace file initialized\n");
|
|
||||||
TRACEA("Trace flags = 0x%x\n", gv.traceflags);
|
TRACEA("Trace flags = 0x%x\n", gv.traceflags);
|
||||||
gv.savetraceflags = gv.traceflags;
|
gv.savetraceflags = gv.traceflags;
|
||||||
gv.traceflags = 0;
|
gv.traceflags = 0;
|
||||||
@@ -4735,14 +4710,6 @@ int main (int argc, char **argv) {
|
|||||||
TRACEA("Tracing enabled for all users\n");
|
TRACEA("Tracing enabled for all users\n");
|
||||||
if (gv.traceinstcount != 0)
|
if (gv.traceinstcount != 0)
|
||||||
TRACEA("Tracing enabled after instruction %u\n", gv.traceinstcount);
|
TRACEA("Tracing enabled after instruction %u\n", gv.traceinstcount);
|
||||||
if (gv.traceseg != 0)
|
|
||||||
{
|
|
||||||
TRACEA("Tracing enabled for segment %04o\n", gv.traceseg);
|
|
||||||
/* This could be splattering other settings that aren't really
|
|
||||||
compatible with RPH trace. C'est la vie? */
|
|
||||||
gv.savetraceflags |= T_FLOW;
|
|
||||||
gv.tracetriggered = 0;
|
|
||||||
}
|
|
||||||
for (i=0; i<gv.numtraceprocs; i++) {
|
for (i=0; i<gv.numtraceprocs; i++) {
|
||||||
for (j=0; j<numsyms; j++) {
|
for (j=0; j<numsyms; j++) {
|
||||||
if (strcasecmp(mapsym[j].symname, traceprocs[i].name) == 0 && mapsym[j].symtype == 'e') {
|
if (strcasecmp(mapsym[j].symname, traceprocs[i].name) == 0 && mapsym[j].symtype == 'e') {
|
||||||
@@ -4969,11 +4936,6 @@ fetch:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOTRACE
|
#ifndef NOTRACE
|
||||||
if (gv.traceseg != 0)
|
|
||||||
if (gv.traceseg == (RPH & 0xFFF))
|
|
||||||
gv.tracetriggered = 1;
|
|
||||||
else
|
|
||||||
gv.tracetriggered = 0;
|
|
||||||
gv.traceflags = 0;
|
gv.traceflags = 0;
|
||||||
if (gv.tracetriggered &&
|
if (gv.tracetriggered &&
|
||||||
(gv.instcount >= gv.traceinstcount) &&
|
(gv.instcount >= gv.traceinstcount) &&
|
||||||
@@ -6314,33 +6276,15 @@ d_hlt: /* 000000 */
|
|||||||
if (bootarg) {
|
if (bootarg) {
|
||||||
printf("\nCPU halt, instruction #%u at %o/%o %s: %o %o ^%06o^\nA='%o/%d B='%o/%d L='%o/%d X=%o/%d", gv.instcount, RPH, RPL, searchloadmap(gv.prevpc,' '), get16t(gv.prevpc), get16t(gv.prevpc+1), lights, getcrs16(A), getcrs16s(A), getcrs16(B), getcrs16s(B), getcrs32(A), getcrs32s(A), getcrs16(X), getcrs16s(X));
|
printf("\nCPU halt, instruction #%u at %o/%o %s: %o %o ^%06o^\nA='%o/%d B='%o/%d L='%o/%d X=%o/%d", gv.instcount, RPH, RPL, searchloadmap(gv.prevpc,' '), get16t(gv.prevpc), get16t(gv.prevpc+1), lights, getcrs16(A), getcrs16s(A), getcrs16(B), getcrs16s(B), getcrs32(A), getcrs32s(A), getcrs16(X), getcrs16s(X));
|
||||||
while (1) {
|
while (1) {
|
||||||
int n;
|
|
||||||
static int ttydev;
|
|
||||||
ttydev = open("/dev/tty", O_RDWR, 0);
|
|
||||||
if (ttydev < 0) {
|
|
||||||
perror(" error opening /dev/tty");
|
|
||||||
fatal(NULL);
|
|
||||||
}
|
|
||||||
printf("\nPress Enter to continue, h to halt... ");
|
printf("\nPress Enter to continue, h to halt... ");
|
||||||
fflush(stdout);
|
utempa = getchar();
|
||||||
utempa = ' ';
|
|
||||||
n = 0;
|
|
||||||
while (n == 0)
|
|
||||||
n = read(ttydev, &utempa, 1);
|
|
||||||
/* utempa = getchar(); */
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
if (utempa == '\r' || utempa == '\n')
|
if (utempa == '\r' || utempa == '\n')
|
||||||
{
|
|
||||||
close(ttydev);
|
|
||||||
goto fetch;
|
goto fetch;
|
||||||
}
|
|
||||||
if (utempa == 'h')
|
if (utempa == 'h')
|
||||||
{
|
|
||||||
close(ttydev);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fatal("CPU halt");
|
fatal("CPU halt");
|
||||||
|
|
||||||
d_pim: /* 000205 (R-mode) */
|
d_pim: /* 000205 (R-mode) */
|
||||||
|
|||||||
4
emdev.h
4
emdev.h
@@ -1413,9 +1413,7 @@ 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);
|
||||||
if (! noclock) {
|
|
||||||
put32r0(datnow, datnowea);
|
put32r0(datnow, datnowea);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2226,5 +2224,3 @@ int devdisk (int class, int func, int device) {
|
|||||||
#include "devpnc.h"
|
#include "devpnc.h"
|
||||||
|
|
||||||
#include "devamlc.h"
|
#include "devamlc.h"
|
||||||
|
|
||||||
#include "devsmlc.h"
|
|
||||||
|
|||||||
80
fp.h
80
fp.h
@@ -40,7 +40,6 @@ 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 */
|
||||||
}
|
}
|
||||||
@@ -60,29 +59,22 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -90,7 +82,6 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -98,7 +89,6 @@ 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--;
|
||||||
}
|
}
|
||||||
@@ -108,10 +98,7 @@ 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;
|
||||||
@@ -126,7 +113,6 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -148,7 +134,7 @@ retry:
|
|||||||
neg = frac64 < 0;
|
neg = frac64 < 0;
|
||||||
exp32 = (frac64 >> 52) & 0x7ff;
|
exp32 = (frac64 >> 52) & 0x7ff;
|
||||||
frac64 &= 0xfffffffffffffLL;
|
frac64 &= 0xfffffffffffffLL;
|
||||||
TRACE(T_FP, "d=%016llx, neg=%x, frac64=%016llx, exp32=%08x, \n", (long long)d, neg, frac64, exp32);
|
//printf("dp=%llx, neg=%d, frac64=%llx, exp32=%d, \n", *(long long *)dp, neg, frac64, exp32);
|
||||||
|
|
||||||
/* special case: NaN & +-infinity */
|
/* special case: NaN & +-infinity */
|
||||||
|
|
||||||
@@ -173,21 +159,12 @@ 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) */
|
||||||
@@ -196,14 +173,12 @@ 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
|
||||||
@@ -229,11 +204,8 @@ 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;
|
||||||
@@ -288,7 +260,6 @@ 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 */
|
||||||
@@ -319,7 +290,6 @@ 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--;
|
||||||
@@ -344,16 +314,11 @@ 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)
|
||||||
@@ -364,10 +329,8 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,37 +356,26 @@ 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 */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -452,35 +404,27 @@ 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;
|
||||||
TRACE(T_FP, " dfcs: FAC: %016llx %04x; op: %016llx %04x\n", templl, facexp, fop, fopexp);
|
#if 0
|
||||||
|
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 */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
makefile
2
makefile
@@ -7,7 +7,7 @@ all_deps = makefile
|
|||||||
em_objs = em.o em
|
em_objs = em.o em
|
||||||
em_deps = \
|
em_deps = \
|
||||||
em.c regs.h emdev.h ea64v.h ea32i.h fp.h dispatch.h geom.h \
|
em.c regs.h emdev.h ea64v.h ea32i.h fp.h dispatch.h geom.h \
|
||||||
devpnc.h devamlc.h devsmlc.h swap.h
|
devpnc.h devamlc.h swap.h
|
||||||
|
|
||||||
CFLAGS =
|
CFLAGS =
|
||||||
# Uncomment for building on SmartOS/Solaris:
|
# Uncomment for building on SmartOS/Solaris:
|
||||||
|
|||||||
35
util/cmraw.c
35
util/cmraw.c
@@ -1,35 +0,0 @@
|
|||||||
/* Show approximate minimum clock resolution
|
|
||||||
Derived from the example in the linux man page for clock_gettime() */
|
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 600
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static void displayClock(clockid_t clock, char *name)
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
time_t oldsec;
|
|
||||||
long oldnsec;
|
|
||||||
|
|
||||||
clock_gettime(clock, &ts);
|
|
||||||
oldsec = ts.tv_sec;
|
|
||||||
oldnsec = ts.tv_nsec;
|
|
||||||
while (ts.tv_sec == oldsec && ts.tv_nsec == oldnsec)
|
|
||||||
{
|
|
||||||
if (clock_gettime(clock, &ts) == -1) {
|
|
||||||
perror("clock_gettime");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%-15s: %10ld sec %09ld nsec\n", name,
|
|
||||||
(long) ts.tv_sec - oldsec, ts.tv_nsec - oldnsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
displayClock(CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
@@ -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(0240);
|
putchar(' ');
|
||||||
space--;
|
space--;
|
||||||
n++;
|
n++;
|
||||||
} else { /* write compressed spaces */
|
} else { /* write compressed spaces */
|
||||||
|
|||||||
Reference in New Issue
Block a user