1
0
mirror of https://github.com/prirun/p50em.git synced 2026-03-25 17:48:25 +00:00

19 Commits

Author SHA1 Message Date
Dennis Boone
d6d01cd05c Workaround for locked up AMLC lines
As it was in the real world, especially with dialup ports, it is possible
for an emulator AMLC line to get blocked by stray flow control characters.
The blocked port may appear dead to the next user to connect, if they are
not "serial savvy" enough to try sending an XON character.

A large number of vulnerability scanners have found and have been hitting
the public emulators, injecting HTTP transactions or worse into the AMLC
ports and often locking all of them daily.

This workaround injects an XON (DC1, 0221) and a line kill character as
extracted from the DEFKIL field in FIGCOM, into the AMLC line when a new
connection is received.

There is a -dolineclear command line switch to enable the behavior.
2021-02-07 00:37:15 -05:00
Dennis Boone
ea2edd89de Fix terminal i/o issue in d_hlt
Due to the configuration of the tty, the getchar() call in d_hlt
returns nothing.  Work around this in the same way the SOC console
code does, by opening it on a separate unit, and reading from that
instead.  Without this fix, the code which looks for certain halt
cases and offers "continue or exit" just spins, printing its message
and getting no input.
2021-02-06 17:11:55 -05:00
Dennis Boone
3d71fd85f0 Update copyrights. 2021-02-03 18:51:34 -05:00
Dennis Boone
5d119bb2c5 Update README.md
Github discussions.
2021-01-21 14:24:49 -05:00
Dennis Boone
aa8095217f Merge pull request #5 from kej715/master
Add support for RJE MASTER mode in MDLC/HSSMLC controller, and use TRACE system instead of separate debug tracing.
2020-08-07 10:19:32 -04:00
Kevin Jordan
89043d09a4 Add support for RJE MASTER mode in MDLC/HSSMLC controller, and use
TRACE macro in the controller implementation.
2020-08-06 23:43:50 -04:00
Dennis Boone
e61857e333 Man page enhancements
Credit Kevin Jordan for sync serial support.

Add smlc.cfg info.

Improved explanation for instruction count and octal segno tracing.
2020-06-23 17:53:01 -04:00
Dennis Boone
4771f09e1e Minor tracing enhancements
Deconflict some values of instruction count with some of the
other tracing options by making it require a leading # before
the integer count.

Add/fix support for tracing execution within a designated segno.

Announce to the trace file that tracing is initialized.
2020-06-23 17:35:53 -04:00
Dennis Boone
6bf6e2ea48 Nanosecond log resolution for SMLC debug log
Using clock_gettime(), fetch the realtime clock, which has as much as
nanosecond resolution.  (In reality, it will likely ben more like
microseconds, though it returns the value in nanoseconds.) Use the
nanosecond value in SMLC log entries.  On modern systems and over
ethernet links, second resolution is probably fairly coarse for trying
to debug RJE problems.
2020-06-23 17:15:35 -04:00
Dennis Boone
edf7129651 Merge remote-tracking branch 'refs/remotes/origin/master' 2020-06-22 23:58:37 -04:00
Dennis Boone
543aa3f963 Fix link fail on x64-64
Weird gcc behavior.  Code snippet:

   uint16_t data;
   char ch;
   ...
   i = (data >> 8) & 0xff;
   ch = data & 0xff;
   ...
   fprintf(smlclog, "%s OTA '01%02o line '%02o set special character %d <%02x>\n", smlctimestamp, device, dc[dx].lineno, i, ch);

Output on x86-64 before this change:

    17:13:51 OTA '0150 line '02 set special character 3 <ffffffff>

Output on armhf or on x86-64 after this change:

    19:05:00.130466808 OTA '0150 line '02 set special character 3 <ff>

WTH?  Masking an unsigned with an appropriately sized mask produces a
sign extension?
2020-06-22 23:54:22 -04:00
Dennis Boone
7d7504a02e Clock resolution sniffer
The cmraw tool shows the approximate minimum time a program could
nanosleep, which tends to be quite a bit bigger than the smallest
value one could pass to nanosleep (one ns).  For example, on my
i7-3770 running linux, the results tend to be between 90 and 120 ns.
2020-06-11 13:22:48 -04:00
Dennis Boone
43d2d863d7 Replace tabs with spaces
Mixed tabs/spaces gets hairy.  I've expanded the tabs on the basis
of 8-position tabstops.
2020-05-30 01:42:39 -04:00
Dennis Boone
80c1a57895 Merge pull request #4 from kej715/master
MDLC/HSSMLC controller emulation to support Bisync and HASP for RJE
2020-05-30 00:17:58 -04:00
Kevin Jordan
d566f42ea6 Eliminate compiler warnings. 2020-05-29 22:46:09 -04:00
Kevin Jordan
af1718f699 Merge branch 'master' of https://github.com/kej715/p50em 2020-05-29 22:38:06 -04:00
Kevin Jordan
91bddd02c3 Add emulation of MDLC/HSSMLC controller to support Bisync protocol and enable a Prime
system to operate as a HASP station in an RJE environment. This implementation is
compatible with Bisync/HASP emulation in the Hercules IBM mainframe emulator and the
DtCyber CDC mainframe emulator.
2020-05-29 12:53:58 -04:00
Dennis Boone
4def8fe397 Support for booting DOS pre-Rev20
PRIMOS2 was built to be relocated after being loaded by BOOT.
The build process rewrote the RVEC in the save file.  The SA was anded
with :160000; the result was subtracted from SA and EA in the RVEC,
and stored into RA in the RVEC.  The BOOT program knew to add the RA
value during the load process.

This change causes the emulator to recognize such an RVEC when booting
an R-mode executable from unix disk, and to adjust the RVEC before
actually loading the program.  This fixes failure to boot *DOS64 from
19.2.9, for example.

The code only makes this adjustment if RA is non-zero, and RP is not
between SA and EA.
2020-05-27 19:06:55 -04:00
Jim Wilcoxson
43bbf3cd8f TCP_KEEPALIVE timer not supported on OSX 2020-05-27 18:49:35 -04:00
14 changed files with 3709 additions and 2247 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
*.log *.log
*.swp *.swp
tags tags
cmraw
cscope.* cscope.*
em em
emlink emlink

View File

@@ -22,6 +22,9 @@ 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

View File

@@ -262,6 +262,7 @@ 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 */
@@ -329,6 +330,7 @@ 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;
@@ -885,6 +887,7 @@ 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);
@@ -911,10 +914,12 @@ 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, 6 /* TCP */, TCP_KEEPIDLE, &optval, sizeof(optval)) == -1) if (setsockopt(fd, IPPROTO_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)
@@ -1138,6 +1143,53 @@ 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);

1292
devsmlc.h Normal file

File diff suppressed because it is too large Load Diff

33
em.1
View File

@@ -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-03-14" "Jim Wilcoxson" "50-Series Emulator" .TH em 1 "2020-06-23" "Jim Wilcoxson" "50-Series Emulator"
.\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
.SH NAME .SH NAME
em \- Emulator for Prime 50-Series systems em \- Emulator for Prime 50-Series systems
@@ -35,6 +35,8 @@ 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
@@ -143,6 +145,15 @@ 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
@@ -163,6 +174,18 @@ 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
@@ -274,9 +297,12 @@ 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
.\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
@@ -360,7 +386,8 @@ CMD,1/3/5+1,Cartridge Module 32/64/96 MB
.\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
.SH AUTHOR .SH AUTHOR
.PP .PP
This emulator was written by Jim Wilcoxson. Man page by Dennis Boone. This emulator was written by Jim Wilcoxson. MDLC/HSSMLC support by
Kevin Jordan. Man page by Dennis Boone.
.\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
.SH SEE ALSO .SH SEE ALSO
This project is hosted at This project is hosted at

64
em.c
View File

@@ -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-2019, Jim Wilcoxson. All Rights Reserved. Copyright (C) 2005-2021, 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)
@@ -287,6 +287,7 @@ 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
@@ -309,6 +310,7 @@ 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 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))
@@ -656,6 +658,7 @@ static unsigned short *physmem = NULL; /* system's physical memory */
//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 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) */
@@ -1689,6 +1692,8 @@ 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)
@@ -1700,7 +1705,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 */ devnone,devnone,devamlc,devamlc,devamlc,devnone,devnone,devnone, /* '5x */ devsmlc,devsmlc,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};
@@ -1714,6 +1719,7 @@ 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)
*/ */
@@ -1724,7 +1730,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 */ devnone,devnone,devnone,devamlc,devamlc,devnone,devnone,devnone, /* '5x */ devsmlc,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
@@ -4363,7 +4369,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-2019 Jim Wilcoxson prirun@gmail.com]\n"); printf("[Copyright (C) 2005-2021 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);
} }
@@ -4446,6 +4452,7 @@ int main (int argc, char **argv) {
#include "dispatch.h" #include "dispatch.h"
domemdump = 0; domemdump = 0;
dolinecleararg = 0;
bootarg = NULL; bootarg = NULL;
bootfile[0] = 0; bootfile[0] = 0;
gv.pmap32bits = 0; gv.pmap32bits = 0;
@@ -4465,6 +4472,9 @@ int main (int argc, char **argv) {
} 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);
@@ -4603,14 +4613,16 @@ 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 (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);
@@ -4701,6 +4713,7 @@ 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;
@@ -4710,6 +4723,14 @@ 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') {
@@ -4770,6 +4791,12 @@ int main (int argc, char **argv) {
for (i=0; i<9; i++) for (i=0; i<9; i++)
rvec[i] = swap16(rvec[i]); rvec[i] = swap16(rvec[i]);
if (rvec[3] != 0) {
if (rvec[2] > rvec[1]) {
rvec[0] += rvec[3];
rvec[1] += rvec[3];
}
}
} else { } else {
/* If no filename follows -boot, then the sense switches are used to /* If no filename follows -boot, then the sense switches are used to
@@ -4930,6 +4957,11 @@ 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) &&
@@ -6270,15 +6302,33 @@ 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... ");
utempa = getchar(); fflush(stdout);
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) */

View File

@@ -2224,3 +2224,5 @@ int devdisk (int class, int func, int device) {
#include "devpnc.h" #include "devpnc.h"
#include "devamlc.h" #include "devamlc.h"
#include "devsmlc.h"

View File

@@ -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 swap.h devpnc.h devamlc.h devsmlc.h swap.h
CFLAGS = CFLAGS =
# Uncomment for building on SmartOS/Solaris: # Uncomment for building on SmartOS/Solaris:

35
util/cmraw.c Normal file
View File

@@ -0,0 +1,35 @@
/* 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);
}