Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e707b2bd9a | ||
|
|
ba6692a67f | ||
|
|
a83cdf8510 | ||
|
|
115b9f06bb | ||
|
|
d7fea97432 |
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# ignore these files
|
||||
*~
|
||||
*.o
|
||||
*.exe
|
||||
# the end
|
||||
17
README.md
17
README.md
@@ -8,7 +8,7 @@ Each emulated .dsk image file is exactly 256KB (512 blocks of 512 bytes) of data
|
||||
|
||||
Note: <B>tu58em</B> is compiled using the CYGWIN serial interface library routines (ie, termios.h) and is the preferred version that should be used. <B>tu58ew</B> bypasses the CYGWIN serial interface layer and makes direct Windows serial comm routine calls. This version was done early on because of deficiencies in the CYGWIN serial library. However, the required features are now present so in reality <B>tu58ew</B> should be considered deprecated.
|
||||
|
||||
The latest version (as of 1.4m) integrates Mark Blair's updates for VAX mode operation (for VAX-730 microcode boot support) and background mode.
|
||||
As of v1.4m Mark Blair's updates for VAX mode operation (for VAX-730 microcode boot support) and background mode are integrated.
|
||||
|
||||
A cygwin folder with a precompiled 32b cygwin executable (tu58em.exe) is included for those without cygwin environment access. Under Windows, just open a standard CMD.EXE window, change to the cygwin folder, and run the <B>tu58em.exe</B> executable as a command line program.
|
||||
|
||||
@@ -18,7 +18,7 @@ If the emulator is run with no options, it prints a usage screen:
|
||||
E:\DEC> tu58em
|
||||
ERROR: no units were specified
|
||||
FATAL: illegal command line
|
||||
tu58 tape emulator v1.4m
|
||||
tu58 tape emulator v1.4p
|
||||
Usage: ./tu58em [-options] -[rwci] file1 ... -[rwci] file7
|
||||
Options: -V | --version output version string
|
||||
-v | --verbose enable verbose output to terminal
|
||||
@@ -29,7 +29,8 @@ FATAL: illegal command line
|
||||
-b | --background run in background mode, no console I/O except errors
|
||||
-t | --timing 1 add timing delays to spoof diagnostic into passing
|
||||
-T | --timing 2 add timing delays to mimic a real TU58
|
||||
-s | --speed BAUD set line speed [1200..3000000; default 9600]
|
||||
-s | --speed BAUD set line speed to BAUD; default 9600
|
||||
-S | --stop BITS set stop bits 1..2; default 1
|
||||
-p | --port PORT set port to PORT [1..N or /dev/comN; default 1]
|
||||
-r | --read|rd FILENAME readonly drive
|
||||
-w | --write FILENAME read/write drive
|
||||
@@ -51,10 +52,12 @@ Most of the switches should be pretty obvious:
|
||||
-b run in background mode, no console I/O except errors
|
||||
-t adds time delays to allow the emulator to pass the DEC ZTUUF0 TU-58 Performance Exerciser diagnostic
|
||||
-T adds time delays to make the emulator nearly as slow as a real TU-58 (just for fun)
|
||||
-s BAUD sets the baud rate; the following rates are supported. the default will be 9600 if not set.
|
||||
3000000, 2500000, 2000000, 1500000, 1152000, 1000000, 921600, 576000, 500000,
|
||||
460800, 256000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200
|
||||
-s BAUD sets the baud rate; the following rates may be supported. the default will be 9600 if not set.
|
||||
3000000, 2500000, 2000000, 1500000, 1152000, 1000000, 921600, 576000, 500000,
|
||||
460800, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200
|
||||
exact list of baud rate support is system dependent (especially for rates above 230400)
|
||||
-p PORT sets the com port as a number (1,2,3,...) or if not numeric the full path (/dev/com1)
|
||||
-S STOP sets the number of stop bits (1 or 2), default is 1
|
||||
-r FILENAME set the next unit as a read only drive using file FILENAME
|
||||
-w FILENAME set the next unit as a read/write drive using file FILENAME
|
||||
-c FILENAME set the next unit as a read/write drive using file FILENAME, zero the file before use
|
||||
@@ -69,7 +72,7 @@ E:\DEC> tu58em -p 3 -s 38400 -r boot.dsk -i rt11.dsk
|
||||
info: initialize RT-11 directory on 'rt11.dsk'
|
||||
info: unit 0 r file 'boot.dsk'
|
||||
info: unit 1 rwci file 'rt11.dsk'
|
||||
info: serial port 3 at 38400 baud
|
||||
info: serial port 3 at 38400 baud 1 stop
|
||||
info: TU58 emulation start
|
||||
info: R restart, S toggle send init, V toggle verbose, D toggle debug, Q quit
|
||||
info: emulator started
|
||||
|
||||
2
common.h
2
common.h
@@ -106,7 +106,7 @@ void devrxinit (void);
|
||||
int32_t devrxavail (void);
|
||||
int32_t devrxerror (void);
|
||||
uint8_t devrxget (void);
|
||||
void devinit (char *, int32_t);
|
||||
void devinit (char *, int32_t, int32_t);
|
||||
void devrestore (void);
|
||||
void coninit (void);
|
||||
void conrestore (void);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
63
main.c
63
main.c
@@ -2,7 +2,7 @@
|
||||
// tu58 - Emulate a TU58 over a serial line
|
||||
//
|
||||
// Original (C) 1984 Dan Ts'o <Rockefeller Univ. Dept. of Neurobiology>
|
||||
// Update (C) 2005-2016 Donald N North <ak6dn_at_mindspring_dot_com>
|
||||
// Update (C) 2005-2017 Donald N North <ak6dn_at_mindspring_dot_com>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -73,6 +73,11 @@
|
||||
// v1.4m - 23 Feb 2016 - donorth - Added M. Blair's vax console timeout changes for '730
|
||||
// - Added M. Blair's background mode option (no status).
|
||||
// v1.4n - 06 Apr 2016 - donorth - Added capability for baud rates >230K, up to 3M
|
||||
// v1.4o - 09 Jan 2017 - donorth - Removed baud rate 256000, it is nonstandard for unix.
|
||||
// Changed serial setup to use cfsetispeed()/cfsetospeed().
|
||||
// Added capability for 1 or 2 stop bits; default is 1
|
||||
// v1.4p - 05 May 2017 - donorth - Updated serial baud rate table with #ifdef detection
|
||||
// Update clock_gettime() for MAC OSX support
|
||||
//
|
||||
|
||||
|
||||
@@ -80,13 +85,14 @@
|
||||
#include <getopt.h>
|
||||
|
||||
|
||||
static char copyright[] = "(C) 2005-2016 Don North <ak6dn" "@" "mindspring.com>, " \
|
||||
static char copyright[] = "(C) 2005-2017 Don North <ak6dn" "@" "mindspring.com>, " \
|
||||
"(C) 1984 Dan Ts'o <Rockefeller University>";
|
||||
|
||||
static char version[] = "tu58 tape emulator v1.4n";
|
||||
static char version[] = "tu58 tape emulator v1.4p";
|
||||
|
||||
static char port[32] = "1"; // default port number (COM1, /dev/ttyS0)
|
||||
static long speed = 9600; // default line speed
|
||||
static long stop = 1; // default stop bits, 1 or 2
|
||||
|
||||
uint8_t verbose = 0; // set nonzero to output more info
|
||||
uint8_t timing = 0; // set nonzero to add timing delays
|
||||
@@ -152,7 +158,7 @@ void fatal (char *fmt, ...)
|
||||
// main program
|
||||
//
|
||||
int main (int argc,
|
||||
char **argv)
|
||||
char *argv[])
|
||||
{
|
||||
long i;
|
||||
long n = 0;
|
||||
@@ -160,37 +166,39 @@ int main (int argc,
|
||||
|
||||
// switch options
|
||||
int opt_index = 0;
|
||||
char opt_short[] = "dvVmnxbTtp:s:r:w:c:i:z:";
|
||||
char opt_short[] = "dvVmnxbTtp:s:r:w:c:i:z:S:";
|
||||
static struct option opt_long[] = {
|
||||
{ "debug", no_argument, 0, 'd' },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ "version", no_argument, 0, 'V' },
|
||||
{ "mrsp", no_argument, 0, 'm' },
|
||||
{ "nosync", no_argument, 0, 'n' },
|
||||
{ "vax", no_argument, 0, 'x' },
|
||||
{ "background", no_argument, 0, 'b' },
|
||||
{ "timing", required_argument, 0, -2 },
|
||||
{ "port", required_argument, 0, 'p' },
|
||||
{ "baud", required_argument, 0, 's' },
|
||||
{ "speed", required_argument, 0, 's' },
|
||||
{ "rd", required_argument, 0, 'r' },
|
||||
{ "read", required_argument, 0, 'r' },
|
||||
{ "write", required_argument, 0, 'w' },
|
||||
{ "create", required_argument, 0, 'c' },
|
||||
{ "initrt11", required_argument, 0, 'i' },
|
||||
{ "initxxdp", required_argument, 0, 'z' },
|
||||
{ 0, no_argument, 0, 0 }
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "mrsp", no_argument, NULL, 'm' },
|
||||
{ "nosync", no_argument, NULL, 'n' },
|
||||
{ "vax", no_argument, NULL, 'x' },
|
||||
{ "background", no_argument, NULL, 'b' },
|
||||
{ "timing", required_argument, NULL, -2 },
|
||||
{ "port", required_argument, NULL, 'p' },
|
||||
{ "baud", required_argument, NULL, 's' },
|
||||
{ "speed", required_argument, NULL, 's' },
|
||||
{ "stop", required_argument, NULL, 'S' },
|
||||
{ "rd", required_argument, NULL, 'r' },
|
||||
{ "read", required_argument, NULL, 'r' },
|
||||
{ "write", required_argument, NULL, 'w' },
|
||||
{ "create", required_argument, NULL, 'c' },
|
||||
{ "initrt11", required_argument, NULL, 'i' },
|
||||
{ "initxxdp", required_argument, NULL, 'z' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
// init file structures
|
||||
fileinit();
|
||||
|
||||
// process command line options
|
||||
while ((i = getopt_long(argc, argv, opt_short, opt_long, &opt_index)) != EOF) {
|
||||
while ((i = getopt_long(argc, argv, opt_short, opt_long, &opt_index)) != -1) {
|
||||
switch (i) {
|
||||
case -2 : timing = atoi(optarg); if (timing > 2) errors++; break;
|
||||
case 'p': strcpy(port, optarg); break;
|
||||
case 's': speed = atoi(optarg); break;
|
||||
case 'S': stop = atoi(optarg); break;
|
||||
case 'r': fileopen(optarg, FILEREAD); n++; break;
|
||||
case 'w': fileopen(optarg, FILEWRITE); n++; break;
|
||||
case 'c': fileopen(optarg, FILECREATE); n++; break;
|
||||
@@ -232,7 +240,8 @@ int main (int argc,
|
||||
" -b | --background run in background mode, no console I/O except errors\n" \
|
||||
" -t | --timing 1 add timing delays to spoof diagnostic into passing\n" \
|
||||
" -T | --timing 2 add timing delays to mimic a real TU58\n" \
|
||||
" -s | --speed BAUD set line speed [1200..3000000; default 9600]\n" \
|
||||
" -s | --speed BAUD set line speed to BAUD; default 9600\n" \
|
||||
" -S | --stop BITS set stop bits 1..2; default 1\n" \
|
||||
" -p | --port PORT set port to PORT [1..N or /dev/comN; default 1]\n" \
|
||||
" -r | --read|rd FILENAME readonly drive\n" \
|
||||
" -w | --write FILENAME read/write drive\n" \
|
||||
@@ -242,11 +251,11 @@ int main (int argc,
|
||||
version, argv[0], NTU58-1);
|
||||
|
||||
// give some info
|
||||
info("serial port %s at %d baud", port, speed);
|
||||
info("serial port %s at %d baud %d stop", port, speed, stop);
|
||||
if (mrspen) info("MRSP mode enabled (NOT fully tested - use with caution)");
|
||||
|
||||
// setup serial and console ports
|
||||
devinit(port, speed);
|
||||
devinit(port, speed, stop);
|
||||
coninit();
|
||||
|
||||
// play TU58
|
||||
|
||||
152
serial.c
152
serial.c
@@ -405,49 +405,89 @@ void devtxput (uint8_t c)
|
||||
static int32_t devbaud (int32_t rate)
|
||||
{
|
||||
#ifdef WINCOMM
|
||||
static int32_t baudlist[] = { 3000000, 3000000,
|
||||
2500000, 2500000,
|
||||
2000000, 2000000,
|
||||
1500000, 1500000,
|
||||
1152000, 1152000,
|
||||
1000000, 1000000,
|
||||
921600, 921600,
|
||||
576000, 576000,
|
||||
500000, 500000,
|
||||
460800, 460800,
|
||||
256000, 256000,
|
||||
230400, 230400,
|
||||
115200, 115200,
|
||||
57600, 57600,
|
||||
38400, 38400,
|
||||
19200, 19200,
|
||||
9600, 9600,
|
||||
4800, 4800,
|
||||
2400, 2400,
|
||||
1200, 1200,
|
||||
-1, -1 };
|
||||
static int32_t baudlist[] = {
|
||||
3000000, 3000000,
|
||||
2500000, 2500000,
|
||||
2000000, 2000000,
|
||||
1500000, 1500000,
|
||||
1152000, 1152000,
|
||||
1000000, 1000000,
|
||||
921600, 921600,
|
||||
576000, 576000,
|
||||
500000, 500000,
|
||||
460800, 460800,
|
||||
230400, 230400,
|
||||
115200, 115200,
|
||||
57600, 57600,
|
||||
38400, 38400,
|
||||
19200, 19200,
|
||||
9600, 9600,
|
||||
4800, 4800,
|
||||
2400, 2400,
|
||||
1200, 1200,
|
||||
-1, -1
|
||||
};
|
||||
#else // !WINCOMM
|
||||
static int32_t baudlist[] = { 3000000, B3000000,
|
||||
2500000, B2500000,
|
||||
2000000, B2000000,
|
||||
1500000, B1500000,
|
||||
1152000, B1152000,
|
||||
1000000, B1000000,
|
||||
921600, B921600,
|
||||
576000, B576000,
|
||||
500000, B500000,
|
||||
460800, B460800,
|
||||
256000, B256000,
|
||||
230400, B230400,
|
||||
115200, B115200,
|
||||
57600, B57600,
|
||||
38400, B38400,
|
||||
19200, B19200,
|
||||
9600, B9600,
|
||||
4800, B4800,
|
||||
2400, B2400,
|
||||
1200, B1200,
|
||||
-1, -1 };
|
||||
static int32_t baudlist[] = {
|
||||
#ifdef B3000000
|
||||
3000000, B3000000,
|
||||
#endif // B3000000
|
||||
#ifdef B2500000
|
||||
2500000, B2500000,
|
||||
#endif // B2500000
|
||||
#ifdef B2000000
|
||||
2000000, B2000000,
|
||||
#endif // B2000000
|
||||
#ifdef B1500000
|
||||
1500000, B1500000,
|
||||
#endif // B1500000
|
||||
#ifdef B1152000
|
||||
1152000, B1152000,
|
||||
#endif // B1152000
|
||||
#ifdef B1000000
|
||||
1000000, B1000000,
|
||||
#endif // B1000000
|
||||
#ifdef B921600
|
||||
921600, B921600,
|
||||
#endif // B921600
|
||||
#ifdef B576000
|
||||
576000, B576000,
|
||||
#endif // B576000
|
||||
#ifdef B500000
|
||||
500000, B500000,
|
||||
#endif // B500000
|
||||
#ifdef B460800
|
||||
460800, B460800,
|
||||
#endif // B460800
|
||||
#ifdef B230400
|
||||
230400, B230400,
|
||||
#endif // B230400
|
||||
#ifdef B115200
|
||||
115200, B115200,
|
||||
#endif // B115200
|
||||
#ifdef B57600
|
||||
57600, B57600,
|
||||
#endif // B57600
|
||||
#ifdef B38400
|
||||
38400, B38400,
|
||||
#endif // B38400
|
||||
#ifdef B19200
|
||||
19200, B19200,
|
||||
#endif // B19200
|
||||
#ifdef B9600
|
||||
9600, B9600,
|
||||
#endif // B9600
|
||||
#ifdef B4800
|
||||
4800, B4800,
|
||||
#endif // B4800
|
||||
#ifdef B2400
|
||||
2400, B2400,
|
||||
#endif // B2400
|
||||
#ifdef B1200
|
||||
1200, B1200,
|
||||
#endif // B1200
|
||||
-1, -1
|
||||
};
|
||||
#endif // !WINCOMM
|
||||
int32_t *p = baudlist;
|
||||
int32_t r;
|
||||
@@ -465,7 +505,8 @@ static int32_t devbaud (int32_t rate)
|
||||
// open/initialize serial port
|
||||
//
|
||||
void devinit (char *port,
|
||||
int32_t speed)
|
||||
int32_t speed,
|
||||
int32_t stop)
|
||||
{
|
||||
#ifdef WINCOMM
|
||||
|
||||
@@ -515,7 +556,7 @@ void devinit (char *port,
|
||||
dcb.fAbortOnError = FALSE;
|
||||
dcb.ByteSize = 8;
|
||||
dcb.Parity = NOPARITY;
|
||||
dcb.StopBits = TWOSTOPBITS;
|
||||
dcb.StopBits = (stop == 2) ? TWOSTOPBITS : ONESTOPBIT;
|
||||
|
||||
// timing/read param
|
||||
cto.ReadIntervalTimeout = MAXDWORD;
|
||||
@@ -550,12 +591,6 @@ void devinit (char *port,
|
||||
// copy current parameters
|
||||
line = lineSave;
|
||||
|
||||
// set baud rate
|
||||
if (devbaud(speed) == -1)
|
||||
error("illegal serial speed %d., ignoring", speed);
|
||||
else
|
||||
line.c_ospeed = line.c_ispeed = devbaud(speed);
|
||||
|
||||
// input param
|
||||
line.c_iflag &= ~( IGNBRK | BRKINT | IMAXBEL | INPCK | ISTRIP |
|
||||
INLCR | IGNCR | ICRNL | IXON | IXOFF |
|
||||
@@ -571,7 +606,10 @@ void devinit (char *port,
|
||||
// control param
|
||||
line.c_cflag &= ~( CBAUD | CSIZE | CSTOPB | PARENB | PARODD |
|
||||
HUPCL | CRTSCTS | CLOCAL | CREAD );
|
||||
line.c_cflag |= ( CLOCAL | CREAD | CS8 | CSTOPB ); // 8b+2stop
|
||||
line.c_cflag |= ( CLOCAL | CREAD | CS8 );
|
||||
|
||||
// set two stop bits if requested, else default to one
|
||||
if (stop == 2) line.c_cflag |= CSTOPB;
|
||||
|
||||
// local param
|
||||
line.c_lflag &= ~( ISIG | ICANON | ECHO | ECHOE | ECHOK |
|
||||
@@ -583,8 +621,18 @@ void devinit (char *port,
|
||||
line.c_cc[VMIN] = 1; // return a min of 1 chars
|
||||
line.c_cc[VTIME] = 0; // no timer
|
||||
|
||||
// ok, set new param
|
||||
// flush all existing input data
|
||||
tcflush(device, TCIFLUSH);
|
||||
|
||||
// set baud rate, if it is legal
|
||||
if (devbaud(speed) == -1) {
|
||||
error("illegal serial speed %d., ignoring", speed);
|
||||
} else {
|
||||
cfsetispeed(&line, devbaud(speed));
|
||||
cfsetospeed(&line, devbaud(speed));
|
||||
}
|
||||
|
||||
// set new device parameters
|
||||
tcsetattr(device, TCSANOW, &line);
|
||||
|
||||
// and non-blocking also
|
||||
|
||||
@@ -52,11 +52,13 @@
|
||||
#include "tu58.h"
|
||||
|
||||
#ifdef MACOSX
|
||||
// clock_gettime() is not available under OSX
|
||||
// clock_gettime() is not available under MACOSX
|
||||
#define CLOCK_REALTIME 1
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
void clock_gettime(int dummy, timespec_t *t) {
|
||||
void clock_gettime (int dummy, struct timespec *t) {
|
||||
uint64_t mt;
|
||||
mt = mach_absolute_time();
|
||||
t->tv_sec = mt / 1000000000;
|
||||
|
||||
Reference in New Issue
Block a user