1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-11 23:43:19 +00:00

Dodo Nethub support (#445)

* added support for XNS networking via Dodo-Nethub

* NetHub connection now optional (only if -nh-host is given); released NetHub-related changes to 'ether.c' to the public domain

* Added file using-dodo-networking-with-maiko.md

Documentation for building and using the Dodo-networking addition to Maiko

* Added support for running Maiko unter cygwin/x86_64-x

* Migrate Addr68k/NativeAlignment{2,4} in Nethub code, move timer/async defines to platform.h

* added missing include <netinet/in.h> for FreeBSD

* updated 'compile-flags' with added flags

* splitted ether.c in 3 (_common, _sunos, _nethub)

* reworks/modifications for nbriggs' pull-request review comments

* addintional additions for nbriggs' pull-request review comments

* get the Lisp packet lengths with 'LispInt2CInt'

* renamed variables in dblwordsSwap to indicate it's about double-words

* fixed wrong preprocessor directive unnoticed by clang

* added networking choice option to cmake build, fix to printf warning

- for cmake specify the networking to use with -DMAIKO_NETWORK_TYPE=<type>
- with <type> one of: NONE, SUN_DLPI, SUN_NIT, NETHUB
- e.g.: cmake .. -DMAIKO_NETWORK_TYPE=NETHUB

* integrated improvement to sendPacket() proposed by nbriggs

* integrated fix for SIGBUS on 32-bit big-endian, provided by nbriggs

* MAIKO_ENABLE_ETHERNET should not be unconditionally set on Solaris systems

* Receiving an ethernet packet is an ether interrupt but not an i/o interrupt.

Co-authored-by: dev hawala <devhawala@x.y>
Co-authored-by: Nick Briggs <nicholas.h.briggs@gmail.com>
This commit is contained in:
devhawala 2022-10-11 23:21:55 +02:00 committed by GitHub
parent 2509a796ce
commit 82577ce951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1107 additions and 102 deletions

View File

@ -72,10 +72,30 @@ IF(MAIKO_DISPLAY_X11)
)
ENDIF()
# according to: https://cmake.org/pipermail/cmake/2016-October/064342.html
# the following 2 lines should produce a dropdown-box in the cmake-gui
# but this will happen only after running the command line version of cmake,
# possibly after "clearing the cache" (i.e. starting with a fresh build directory)
SET(MAIKO_NETWORK_TYPE NONE CACHE STRING "Type of networking to use: one of: NONE, SUN_DLPI, SUN_NIT, NETHUB")
SET_PROPERTY(CACHE MAIKO_NETWORK_TYPE PROPERTY STRINGS NONE SUN_DLPI SUN_NIT NETHUB)
# configure networking implementation to use
IF(MAIKO_NETWORK_TYPE STREQUAL "NETHUB")
LIST(APPEND MAIKO_DEFINITIONS "-DMAIKO_ENABLE_NETHUB")
MESSAGE("-- Configured for NETHUB network support")
ELSEIF(MAIKO_NETWORK_TYPE STREQUAL "SUN_DLPI")
LIST(APPEND MAIKO_DEFINITIONS "-DMAIKO_ENABLE_ETHERNET -DUSE_DLPI")
MESSAGE("-- Configured for (SunOS) DLPI networking")
ELSEIF(MAIKO_NETWORK_TYPE STREQUAL "SUN_NIT")
LIST(APPEND MAIKO_DEFINITIONS "-DMAIKO_ENABLE_ETHERNET -DUSE_NIT")
MESSAGE("-- Configured for (SunOS) NIT networking")
ELSEIF(NOT MAIKO_NETWORK_TYPE STREQUAL "NONE")
MESSAGE(WARNING "Invalid option given for MAIKO_NETWORK_TYPE, must be one of:\nNONE, SUN_DLPI, SUN_NIT, NETHUB")
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
LIST(APPEND MAIKO_DEFINITIONS
"-DOS5"
"-DUSE_DLPI"
)
ENDIF()
@ -142,7 +162,9 @@ SET(MAIKO_SRCS
src/dspif.c
src/dspsubrs.c
src/eqf.c
src/ether.c
src/ether_common.c
src/ether_sunos.c
src/ether_nethub.c
src/findkey.c
src/foreign.c
src/fp.c

View File

@ -134,6 +134,24 @@ PKTFILTER True if the ethernet packets are to be filtered before being
passed to the Lisp ethernet handler. Available on Sun systems
for both the NIT and DLPI cases.
MAIKO_ENABLE_NETHUB enables the support for Dodo Nethub networking for Dodo
XNS services, see documentation: using-dodo-networking-with-maiko.md
(implicitely disables USE_DLPI and USE_NIT)
MAIKO_EMULATE_TIMER_INTERRUPTS enables emulation of recurring timer interrupts for
platforms where SIGVTALRM/ITIMER_VIRTUAL or SIGALRM/ITIMER_REAL
do not work as expected (like cygwin)
timer is emulated by signaling an interrupt after a number of
executed instructions, by default 20.000 instructions, this can be
overriden by defining MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN
with the number of instructions between 2 interrupts
additionally this adds the command line arguments -intr-emu-insns
for overriding the compiled in instruction interval
(not working if OPDISP (fast opcode dispatch) is used)
MAIKO_EMULATE_ASYNC_INTERRUPTS same as MAIKO_EMULATE_TIMER_INTERRUPTS, but also
signals an I/O interrupt after each instruction interval
bitbltsub.c:#ifdef GETBASE
testdisplay.c:#ifdef NOTUSED

2
bin/makefile-cygwin.x86_64-x Normal file → Executable file
View File

@ -1,7 +1,7 @@
# Options for Linux, Intel x86_64 and X-Window
#CC = gcc -m64 $(GCC_CFLAGS)
CC = clang -m64 $(CLANG_CFLAGS)
CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB
XFILES = $(OBJECTDIR)xmkicon.o \
$(OBJECTDIR)xbbt.o \

View File

@ -1,7 +1,7 @@
# Options for Linux, Intel x86_64 and X-Window
#CC = gcc -m64 $(GCC_CFLAGS)
CC = clang -m64 $(CLANG_CFLAGS)
CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB
XFILES = $(OBJECTDIR)xmkicon.o \
$(OBJECTDIR)xbbt.o \

View File

@ -115,7 +115,9 @@ DEVICES = $(OBJECTDIR)dspsubrs.o \
$(OBJECTDIR)dir.o \
$(OBJECTDIR)keyevent.o \
$(OBJECTDIR)kbdsubrs.o \
$(OBJECTDIR)ether.o \
$(OBJECTDIR)ether_common.o \
$(OBJECTDIR)ether_sunos.o \
$(OBJECTDIR)ether_nethub.o \
$(OBJECTDIR)tty.o \
$(OBJECTDIR)initkbd.o
@ -472,12 +474,26 @@ $(OBJECTDIR)mouseif.o: $(SRCDIR)mouseif.c $(REQUIRED-INCS) $(INCDIR)lispemul.h \
$(INCDIR)dbprint.h $(INCDIR)devif.h
$(CC) $(RFLAGS) $(SRCDIR)mouseif.c -o $(OBJECTDIR)mouseif.o
$(OBJECTDIR)ether.o: $(SRCDIR)ether.c $(REQUIRED-INCS) \
$(OBJECTDIR)ether_common.o: $(SRCDIR)ether_common.c $(REQUIRED-INCS) \
$(INCDIR)commondefs.h $(INCDIR)lispemul.h \
$(INCDIR)lispmap.h $(INCDIR)emlglob.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.h \
$(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)adr68k.h \
$(INCDIR)ether.h $(INCDIR)dbprint.h $(INCDIR)etherdefs.h
$(CC) $(RFLAGS) $(SRCDIR)ether.c -o $(OBJECTDIR)ether.o
$(CC) $(RFLAGS) $(SRCDIR)ether_common.c -o $(OBJECTDIR)ether_common.o
$(OBJECTDIR)ether_sunos.o: $(SRCDIR)ether_sunos.c $(REQUIRED-INCS) \
$(INCDIR)commondefs.h $(INCDIR)lispemul.h \
$(INCDIR)lispmap.h $(INCDIR)emlglob.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.h \
$(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)adr68k.h \
$(INCDIR)ether.h $(INCDIR)dbprint.h $(INCDIR)etherdefs.h
$(CC) $(RFLAGS) $(SRCDIR)ether_sunos.c -o $(OBJECTDIR)ether_sunos.o
$(OBJECTDIR)ether_nethub.o: $(SRCDIR)ether_nethub.c $(REQUIRED-INCS) \
$(INCDIR)commondefs.h $(INCDIR)lispemul.h \
$(INCDIR)lispmap.h $(INCDIR)emlglob.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.h \
$(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)adr68k.h \
$(INCDIR)ether.h $(INCDIR)dbprint.h $(INCDIR)etherdefs.h
$(CC) $(RFLAGS) $(SRCDIR)ether_nethub.c -o $(OBJECTDIR)ether_nethub.o
$(OBJECTDIR)findkey.o: $(SRCDIR)findkey.c $(REQUIRED-INCS) \
$(INCDIR)lispemul.h $(INCDIR)lispmap.h \

View File

@ -0,0 +1,86 @@
# Using Dodo-networking with Maiko
The [Dodo XNS services](https://github.com/devhawala/dodo) provide an emulation for a usable
subset of the Xerox 8000 Network Services from the 1980-ies. Dodo uses its own virtual
network infrastructure - the Dodo *Nethub* - for avoiding the problems involved with
implementing the transmission of XNS protocol packets over (real or virtual) network
adapters of the diverse contemporary operating systems.
The Dodo Nethub provides a simple virtual network, a kind of *XNS-over-TCP/IP*,
where clients and servers connect with TCP/IP to the central Nethub program, which relays all
packets ingoing from one connection to the other connections.
The following sections describe the support for Dodo-networking added to
Maiko. The Dodo Nethub support was implemented and tested with Linux on the x86_64
architecture. However as only standard system calls for TCP/IP were used, adapting to other
platforms if necessary should be possible.
This extension allows Medley 3.51 running in a Maiko VM to use the XNS services
*Clearinghouse*, *Filing* and *Printing* provided by Dodo (using the *Mail* service may
also be possible, but this was not verified so far)
## Building Maiko with Dodo-networking support
As long as Dodo-networking support is not merged into the `master`-branch
of the primary Maiko repository, this networking option is only available in this
clone of the original Maiko repository in the branch `dodo-nethub-support`.
(however: this branch should already be checked out if this file is present)
The Dodo-networking support is enabled by defining `MAIKO_ENABLE_NETHUB`
when compiling Maiko. This can be done in the Makefile for the relevant platform
(file `bin/makefile-`*platform*) for example in the line where the compiler-command
variable is defined.
This is already done in the Makefile for the *Linux-x86_64-X* platform (file
`bin/makefile-linux.x86_64-x`), where the compiler-command defined as follows:
```
CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB
```
After a complete (re-)build, this Maiko VM optionally allows to connect to a Dodo Nethub
and through this to use Dodo XNS services.
## Running Maiko with Dodo-networking
With Dodo-networking support compiled in, Maiko (i.e. the program `ldex`) accepts the
following additional commandline options:
- `-nh-host` *dodo-host*
the name or IP-address of the host where the Dodo Nethub program runs; no connection to
Dodo services will be opened if this option is not specified
Default: (*none*)
- `-nh-port` *port-number*
the port which the Dodo Nethub is listening to at *dodo-host*
Default: `3333`
- `-nh-mac` *machine-id*
the machine-id (aka. MAC-address) that this Maiko VM instance will use in the Dodo network;
the machine-id must be given as 48 bit hexadecimal value with a dash as byte-separator, i.e.
in the format *XX-XX-XX-XX-XX-XX* (with *XX* the hexcode for a single byte)
Default: `CA-FF-EE-12-34-56`
- `-nh-loglevel` *log-level*
the detail level of logging to `stdout`, one of:
`0`: log only main events (connect, disconnect or the like)
`1`: log network events each with a single line
`2`: detailled log of network events
Default: `0`
So by default Maiko will not connect to a Dodo nethub and behave like a "standard" version
without networking support.
To use Dodo XNS services, the option `-nh-host` must be given to specify the location
of the Dodo nethub. In the simplest (and probably most usual) case where Dodo is run on the
same machine as Maiko/Medley, the value for option `-nh-host` will be *localhost*, so
adding the option `-nh-host localhost` when starting the Medley Lisp system will allow
to use the XNS services of a Dodo system running locally.
Specifying the *machine-id* is optional unless more than one Maiko/Medley instances are to use
Dodo XNS services concurrently: in this case, each Maiko VM *must* use a *unique* machine-id,
so at most one Maiko VM may omit the `-nh-mac` option.
However, each machine-id used by the Maiko VMs should have an entry in the `machine.cfg`
file of the Dodo installation, cloning or copying the low-level SPP-configuration of the
`maiko-Lisp-One` example entry in the `machine.cfg` of the Dodo `dist.zip`
distribution.

View File

@ -14,4 +14,10 @@ LispPTR check_ether(void);
void init_ifpage_ether(void);
void init_ether(void);
LispPTR check_sum(LispPTR *args);
void setNethubHost(char* host);
void setNethubPort(int port);
void setNethubMac(int m0, int m1, int m2, int m3, int m4, int m5);
void setNethubLogLevel(int ll);
void connectToHub();
#endif

View File

@ -17,6 +17,8 @@
# define MAIKO_OS_CYGWIN 1
# define MAIKO_OS_NAME "Cygwin"
# define MAIKO_OS_UNIX_LIKE 1
# define MAIKO_EMULATE_TIMER_INTERRUPTS 1
# define MAIKO_EMULATE_ASYNC_INTERRUPTS 1
# define MAIKO_OS_DETECTED 1
#endif

View File

@ -218,17 +218,6 @@ typedef intptr_t INT;
/********************************************************/
/* */
/********************************************************/
#ifdef OS5
/* Solaris, sort of SYSV-ish, but not really */
#define MAIKO_ENABLE_ETHERNET
#endif /* OS5 */
/********************************************************/
/* */
/********************************************************/

204
src/ether_common.c Normal file
View File

@ -0,0 +1,204 @@
/* $Id: ether.c,v 1.4 2001/12/24 01:09:02 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */
/************************************************************************/
/* */
/* (C) Copyright 1989-1996 inclusive Venue. All Rights Reserved. */
/* Manufactured in the United States of America. */
/* */
/************************************************************************/
#include "version.h"
#include <unistd.h>
#include <sys/types.h>
#include "lsptypes.h"
#include "lspglob.h"
#include "adr68k.h"
/*
* global variables exported to ether_*.c and possibly others
*/
int ether_fd = -1; /* file descriptor for ether socket */
u_char ether_host[6] = {0, 0, 0, 0, 0, 0}; /* 48 bit address of this node */
u_char broadcast[6] = {255, 255, 255, 255, 255, 255};
int ether_bsize = 0; /* if nonzero then a receive is pending */
u_char *ether_buf = NULL; /* address of receive buffer */
int ETHEREventCount = 0;
/*
* public procedures
*/
/************************************************************************/
/* i n i t _ i f p a g e _ e t h e r */
/* */
/* sets Lisp's idea of \my.nsaddress. Clears it if ether not */
/* enabled */
/* */
/************************************************************************/
void init_ifpage_ether() {
InterfacePage->nshost0 = (DLword)((ether_host[0] << 8) + ether_host[1]);
InterfacePage->nshost1 = (DLword)((ether_host[2] << 8) + ether_host[3]);
InterfacePage->nshost2 = (DLword)((ether_host[4] << 8) + ether_host[5]);
}
#define MASKWORD1 0xffff
/************************************************************************/
/* */
/* c h e c k _ s u m */
/* */
/* Implements the CHECKSUM opcode; compute the checksum for an */
/* ethernet packet. */
/* */
/* args[0] LispPTR base; */
/* args[1] LispPTR nwords; */
/* args[2] LispPTR initsum; */
/* */
/* */
/************************************************************************/
LispPTR check_sum(LispPTR *args)
{
LispPTR checksum;
DLword *address;
int nwords;
address = (DLword *)NativeAligned2FromLAddr(*args++);
nwords = *args++;
if (*args != NIL)
checksum = (*args) & MASKWORD1;
else
checksum = 0;
for (; nwords > (S_POSITIVE); address++, nwords--) {
checksum = checksum + GETWORD(address);
if (checksum > 0xffff) checksum = (checksum & 0xffff) + 1; /* add carry */
if (checksum > 0x7fff) /* ROTATE LEFT 1 */
checksum = ((checksum & 0x7fff) << 1) | 1;
else
checksum = checksum << 1;
}
if (checksum == MASKWORD1)
return (S_POSITIVE); /* ret 0 */
else
return (S_POSITIVE | checksum);
} /*check_sum */
/*
* dummy implementation of SUBRs if none of the networking options is compiled in
*/
#if !defined(MAIKO_ENABLE_ETHERNET) && !defined(MAIKO_ENABLE_NETHUB)
/************************************************************************/
/* */
/* e t h e r _ s u s p e n d */
/* */
/* Suspend receiving packets. */
/* 175/70/0 */
/* */
/************************************************************************/
LispPTR ether_suspend(LispPTR args[])
{
return (ATOM_T);
}
/************************************************************************/
/* */
/* e t h e r _ r e s u m e */
/* */
/* resume nit socket to receive all types of packets 175/71/0 */
/* */
/************************************************************************/
LispPTR ether_resume(LispPTR args[])
{
return (ATOM_T);
}
/************************************************************************/
/* */
/* e t h e r _ c t r l r */
/* */
/* return T if ether controller is available 175/72/0 */
/* */
/************************************************************************/
LispPTR ether_ctrlr(LispPTR args[])
{
return (NIL);
}
/**********************************************************************
* ether_reset(args) 175/73/0
* reset ether controller and disable receipt of packets
**********************************************************************/
LispPTR ether_reset(LispPTR args[])
{
return (NIL);
}
/************************************************************************/
/* */
/* e t h e r _ g e t (175/74/2) */
/* */
/* Set up the Ethernet driver to receive a packet. The driver */
/* first tries to read any pending packet from the net, and if */
/* there is one, ether_get returns T. If there is no pending */
/* packet, the failing read sets us up to get an interrupt when */
/* a packet DOES arrive, and ether_get returns NIL. */
/* */
/* args[0] Length of the buffer we're passed */
/* args[1] LISP address of a packet buffer */
/* */
/* sets ether_buf to the buffer address, for check_ether's use */
/* sets ether_bsize to the buffer size. ether_bsize>0 means */
/* it's OK to read packets from the network on interrupt. */
/* */
/************************************************************************/
LispPTR ether_get(LispPTR args[])
{
return (NIL);
}
/**********************************************************************
* ether_send(args) 175/75/2 max_words,buffer_addr
* send a packet
**********************************************************************/
LispPTR ether_send(LispPTR args[])
{
return (NIL);
}
/**********************************************************************
* ether_setfilter(args) 175/76/1 filterbits
* check whether a packet has come. if does, notify iocb
**********************************************************************/
LispPTR ether_setfilter(LispPTR args[])
{
return (NIL);
}
/**********************************************************************
* check_ether() 175/77/0
* checks an incoming packet
**********************************************************************/
LispPTR check_ether()
{
return (NIL);
}
#endif

598
src/ether_nethub.c Normal file
View File

@ -0,0 +1,598 @@
/*******************************************************************************/
/* */
/* Support for Dodo Nethub networking (see: https://github.com/devhawala/dodo) */
/* */
/* Copyright (c) 2022, Dr. Hans-Walter Latz. All rights reserved. */
/* Released to the Public Domain. */
/* */
/*******************************************************************************/
#if defined(MAIKO_ENABLE_NETHUB) && !defined(MAIKO_ENABLE_ETHERNET)
#include "version.h"
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/poll.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include "commondefs.h"
#include "lispemul.h"
#include "lispmap.h"
#include "emlglob.h"
#include "lsptypes.h"
#include "lspglob.h"
#include "adr68k.h"
#include "ether.h"
#include "dbprint.h"
#include "etherdefs.h"
#include "ifpage.h"
#include "iopage.h"
#include "byteswapdefs.h"
#include "dbprint.h"
#include "timerdefs.h"
#include "lisp2cdefs.h"
/*
** --- ether implementation common data -------------------------------------------
*/
extern int ether_fd; /* file descriptor for ether socket */
extern u_char ether_host[6]; /* 48 bit address of this node */
extern u_char broadcast[6];
extern int ether_bsize; /* if nonzero then a receive is pending */
extern u_char *ether_buf; /* address of receive buffer */
extern LispPTR *PENDINGINTERRUPT68k;
extern fd_set LispReadFds;
extern int ETHEREventCount;
/*
** --- nethub configuration data --------------------------------------------------
*/
static char* nethubHost = NULL;
static int nethubPort = 3333;
static int mac0 = 0xCA;
static int mac1 = 0xFF;
static int mac2 = 0xEE;
static int mac3 = 0x12;
static int mac4 = 0x34;
static int mac5 = 0x56;
void setNethubHost(char* host) {
if (host && *host) {
nethubHost = host;
DBPRINT(("nh :: host now: '%s'\n", nethubHost));
}
}
void setNethubPort(int port) {
if (port > 0 && port <= 65535) {
nethubPort = port;
DBPRINT(("nh :: port now: %d\n", nethubPort));
}
}
void setNethubMac(int m0, int m1, int m2, int m3, int m4, int m5) {
if ( m0 >= 0 && m0 <= 255
&& m1 >= 0 && m1 <= 255
&& m2 >= 0 && m2 <= 255
&& m3 >= 0 && m3 <= 255
&& m4 >= 0 && m4 <= 255
&& m5 >= 0 && m5 <= 255) {
mac0 = m0;
mac1 = m1;
mac2 = m2;
mac3 = m3;
mac4 = m4;
mac5 = m5;
DBPRINT(("nh :: mac now: %02X-%02X-%02X-%02X-%02X-%02X\n", mac0, mac1, mac2, mac3, mac4, mac5));
}
}
/*
** --- very simple logging --------------------------------------------------------
*/
static int loglevel = 0;
static int logcnt = 0;
void setNethubLogLevel(int ll) {
loglevel = ll;
DBPRINT(("nh :: loglevel now: %d\n", loglevel));
}
#define log_info(line) { if (loglevel == 1) \
{ printf("nh-info[%d]: ", logcnt++); printf line; }}
#define log_debug(line) { if (loglevel >= 2) \
{ printf("nh-debug[%d]: ", logcnt++); printf line; }}
#define log_all(line) { if (loglevel < 1) \
{ printf("nh[%d]: ", logcnt++); printf line; }}
/*
** --- utilities ------------------------------------------------------------------
*/
#define LONG_PTR_MASK ((long)(~((long)3)))
static void dblwordsSwap(u_char* basePtr, int forBytes) {
u_char* dblwordPtr = (u_char*)((long)basePtr & LONG_PTR_MASK);
int neededBytes = forBytes + (basePtr - dblwordPtr);
int dblwordCount = (neededBytes + 3) / 4;
word_swap_page((unsigned short*)dblwordPtr, dblwordCount);
}
/*
** --- connect, disconnect and transmit packets -----------------------------------
*/
void connectToHub() {
if (nethubHost == NULL) {
return;
}
if (ether_fd > -1) {
return;
}
log_debug(("connectToHub() - begin\n"));
ether_host[0] = mac0;
ether_host[1] = mac1;
ether_host[2] = mac2;
ether_host[3] = mac3;
ether_host[4] = mac4;
ether_host[5] = mac5;
log_debug((" resolving nethub hostname\n"));
struct hostent *host = gethostbyname(nethubHost);
if (host == NULL || host->h_addr_list == NULL) {
log_debug(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
log_info(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
log_all(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
return;
}
log_debug((" connecting to nethub\n"));
struct sockaddr_in hubaddr;
hubaddr.sin_family = AF_INET;
hubaddr.sin_addr.s_addr = *(in_addr_t *)host->h_addr_list[0];
hubaddr.sin_port = htons(nethubPort);
ether_fd = socket(AF_INET, SOCK_STREAM, 0);
if (ether_fd < 0) {
log_info(("connectToHub(): FAILED to create AF_INET/SOCK_STREAM socket\n"));
return;
}
if (connect(ether_fd, (struct sockaddr*)&hubaddr, sizeof(hubaddr)) < 0) {
perror("connectToHub() - connect failed");
close(ether_fd);
ether_fd = -1;
log_info(("connectToHub(): FAILED to connect to nethub\n"));
return;
}
log_debug((" connected to nethub, ether_fd = %d\n", ether_fd));
FD_SET(ether_fd, &LispReadFds);
log_debug((" added ether_fd to LispReadFds\n"));
log_debug(("connectToHub() - end\n\n"));
log_info(("connectToHub() - connected to nethub\n"));
log_all(("connectToHub() - connected to nethub\n"));
}
static void disconnectFromHub() {
if (ether_fd > -1) {
close(ether_fd);
ether_fd = -1;
log_debug(("disconnectFromHub() - disconnected from nethub\n"));
log_info(("disconnectFromHub() - disconnected from nethub\n"));
log_all(("disconnectFromHub() - disconnected from nethub\n"));
}
}
/* buffering for multipe packets:
** if interrupts are'nt processed fast enough, recv() may deliver >1 packets at once
*/
static u_char multiBuffer[65536]; /* should be enough for > 100 IDP packets with ~ 600 bytes */
static u_char* nextPacket = NULL;
static u_char* rcvBuffer = multiBuffer;
static int rcvLen = 0;
/* -1: failed/not connected, 0: no packet available, > 0: received byte count */
static int recvPacket() {
if (ether_fd < 0) {
log_debug((" recvPacket() :: not connected to hub !!!\n"));
return -1;
}
if (ether_bsize < 1) {
log_debug((" recvPacket() :: no receive buffer present -> return 0\n"));
return 0;
}
if (nextPacket == NULL) {
/* try to get the next packet(s) from network */
rcvLen = recv(ether_fd, multiBuffer, sizeof(multiBuffer), MSG_DONTWAIT);
if (rcvLen < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
perror("recvPacket() :: recv(ether_fd, rcvBuffer, sizeof(rcvBuffer), MSG_DONTWAIT)");
disconnectFromHub();
return -1;
}
if (rcvLen <= 0) {
log_debug((" recvPacket() :: no network packet available -> return 0\n"));
return 0;
}
rcvBuffer = multiBuffer;
} else {
/* move to next packet in multi packet buffer */
rcvBuffer = nextPacket;
}
nextPacket = NULL;
int bLen = ((rcvBuffer[0] << 8) & 0xFF00) | (rcvBuffer[1] & 0x00FF);
log_debug((" recvPacket() :: received %d bytes, logical packet length = %d bytes\n", rcvLen, bLen));
if (bLen & 0x0001) {
log_debug(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
log_info(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
log_all(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
disconnectFromHub();
return -1;
}
if (bLen > (rcvLen - 2)) {
log_debug((" recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
log_info(("recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
log_all(("recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
disconnectFromHub();
return -1;
}
if (bLen < 14) {
/* not even enough bytes for the ethernet header */
/* -> discard packet */
log_debug((" recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
log_info(("recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
log_all(("recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
return 0;
}
if ((bLen + 2) != rcvLen) {
log_debug((" recvPacket() ***** :: logical/physical length differ -> preserving next packet in multiBuffer\n"));
log_info(("recvPacket() ***** :: logical/physical length differ -> preserving next packet in multiBuffer\n"));
nextPacket = &rcvBuffer[bLen + 2];
rcvLen -= bLen + 2;
log_debug((" recvPacket() ***** :: next packet in multiBuffer at +%d , remaining length = %d\n",
(int)(nextPacket - multiBuffer), rcvLen));
log_info(("recvPacket() ***** :: next packet in multiBuffer at +%d , remaining length = %d\n",
(int)(nextPacket - multiBuffer), rcvLen));
}
if ( memcmp(&rcvBuffer[2], ether_host, 6) != 0
&& memcmp(&rcvBuffer[2], broadcast, 6) != 0) {
log_debug((" recvPacket() :: packet is not for us and not a broadcast, ignoring packet\n"));
return 0;
}
DLword copyLen = (bLen < ether_bsize) ? bLen : ether_bsize;
#if defined(BYTESWAP)
log_debug((" recvPacket() :: byte-swap copying %d bytes to 0x%016lX\n", copyLen, (unsigned long)ether_buf));
dblwordsSwap(ether_buf, copyLen);
memcpy(ether_buf, &rcvBuffer[2], copyLen);
dblwordsSwap(ether_buf, copyLen);
#else
log_debug((" recvPacket() :: copying %d bytes to 0x%016X\n", copyLen, (unsigned long)ether_buf));
memcpy(ether_buf, &rcvBuffer[2], copyLen);
#endif
ether_bsize = 0;
#if defined(BYTESWAP)
log_debug((" recvPacket() :: IOPage->dlethernet[2] = 0x%04X (before)\n", IOPage->dlethernet[2]));
/* byte-order in IOPage->dlethernet[2] does not seem to matter ... boolean ? */
IOPage->dlethernet[2] = copyLen;
log_debug((" recvPacket() :: IOPage->dlethernet[2] = 0x%04X (after)\n", IOPage->dlethernet[2]));
#else
log_debug((" recvPacket() :: IOPage->dlethernet[3] = 0x%04X (before)\n", IOPage->dlethernet[3]));
IOPage->dlethernet[3] = copyLen;
log_debug((" recvPacket() :: IOPage->dlethernet[3] = 0x%04X (after)\n", IOPage->dlethernet[3]));
#endif
return copyLen;
}
/* -1: failed/not connected; >= 0: packet bytes sent */
static int sendPacket(u_char *source, int sourceLen) {
struct msghdr msg = {0};
struct iovec iov[2];
uint16_t nhlength;
if (ether_fd < 0) {
log_debug((" sendPacket() :: not connected to hub !!!\n"));
return -1;
}
if (sourceLen < 14) {
log_debug((" sendPacket() :: invalid packet length: %d !!!\n", sourceLen));
return -1;
}
if (sourceLen & 0x0001) {
log_debug((" sendPacket() :: packet length not even (mutiple of 2) !!!\n"));
return -1;
}
nhlength = htons(sourceLen);
iov[0].iov_base = &nhlength;
iov[0].iov_len = 2;
iov[1].iov_base = source;
iov[1].iov_len = sourceLen;
msg.msg_iov = iov;
msg.msg_iovlen = 2;
int result = sendmsg(ether_fd, &msg, 0);
return result;
}
/*
** --- SUBR implementations -------------------------------------------------------
*/
/************************************************************************/
/* */
/* e t h e r _ s u s p e n d */
/* */
/* Suspend receiving packets. */
/* 175/70/0 */
/* */
/************************************************************************/
LispPTR ether_suspend(LispPTR args[])
{
if (nethubHost == NULL) {
return (ATOM_T);
}
log_debug(("ether_suspend() -- ignored!\n\n"));
log_info(("ether_suspend()\n"));
return (ATOM_T);
}
/************************************************************************/
/* */
/* e t h e r _ r e s u m e */
/* */
/* resume nit socket to receive all types of packets 175/71/0 */
/* */
/************************************************************************/
LispPTR ether_resume(LispPTR args[])
{
if (nethubHost == NULL) {
return (ATOM_T);
}
log_debug(("ether_resume() - begin\n"));
int_io_open(ether_fd);
log_debug(("ether_resume() - end\n\n"));
log_info(("ether_resume()\n"));
return (ATOM_T);
}
/************************************************************************/
/* */
/* e t h e r _ c t r l r */
/* */
/* return T if ether controller is available 175/72/0 */
/* */
/************************************************************************/
LispPTR ether_ctrlr(LispPTR args[])
{
if (nethubHost == NULL) {
return (NIL);
}
log_debug(("ether_ctrlr() - begin\n"));
connectToHub();
if (ether_fd < 0) {
log_debug(("ether_ctrlr() - end -> NIL\n\n"));
log_info(("ether_ctrlr() -> NIL\n"));
return (NIL);
} else {
int_io_open(ether_fd);
log_debug(("ether_ctrlr() - end -> ATOM_T\n\n"));
log_info(("ether_ctrlr() -> ATOM_T\n"));
return (ATOM_T);
}
}
/**********************************************************************
* ether_reset(args) 175/73/0
* reset ether controller and disable receipt of packets
**********************************************************************/
LispPTR ether_reset(LispPTR args[])
{
if (nethubHost == NULL) {
return (NIL);
}
log_debug(("ether_reset() - begin\n"));
if (ether_fd < 0) {
log_debug(("ether_reset() - end -> NIL\n\n"));
log_info(("ether_reset() -> NIL\n"));
return (NIL);
}
ether_bsize = 0; /* deactivate receiver */
log_debug(("ether_reset() - end -> ATOM_T\n\n"));
log_info(("ether_reset() -> ATOM_T\n"));
return (ATOM_T);
}
/************************************************************************/
/* */
/* e t h e r _ g e t (175/74/2) */
/* */
/* Set up the Ethernet driver to receive a packet. The driver */
/* first tries to read any pending packet from the net, and if */
/* there is one, ether_get returns T. If there is no pending */
/* packet, the failing read sets us up to get an interrupt when */
/* a packet DOES arrive, and ether_get returns NIL. */
/* */
/* args[0] Length of the buffer we're passed */
/* args[1] LISP address of a packet buffer */
/* */
/* sets ether_buf to the buffer address, for check_ether's use */
/* sets ether_bsize to the buffer size. ether_bsize>0 means */
/* it's OK to read packets from the network on interrupt. */
/* */
/************************************************************************/
LispPTR ether_get(LispPTR args[])
{
if (nethubHost == NULL) {
return (NIL);
}
log_debug(("ether_get() - begin\n"));
u_char *target = (u_char *)NativeAligned2FromLAddr(args[1]);
int maxByteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */
log_debug((" target = 0x%016lX maxBytecount: %d bytes\n", (unsigned long)target, maxByteCount));
sigset_t signals;
sigemptyset(&signals);
sigaddset(&signals, SIGIO);
sigprocmask(SIG_BLOCK, &signals, NULL);
ether_buf = target;
ether_bsize = maxByteCount;
int receivedBytes = recvPacket();
sigprocmask(SIG_UNBLOCK, &signals, NULL);
log_debug(("ether_get() :: receivedBytes: %d bytes\n", receivedBytes));
if (receivedBytes <= 0) {
log_debug(("ether_get() - end -> NIL\n\n"));
return (NIL);
}
log_debug(("ether_get() - end -> ATOM_T\n\n"));
log_info(("ether_get(): received packet, len = %d bytes\n", receivedBytes));
return (ATOM_T);
}
/**********************************************************************
* ether_send(args) 175/75/2 max_words,buffer_addr
* send a packet
**********************************************************************/
LispPTR ether_send(LispPTR args[])
{
if (nethubHost == NULL) {
return (NIL);
}
log_debug(("ether_send() - begin\n"));
u_char *source = (u_char *)NativeAligned2FromLAddr(args[1]);
int byteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */
log_debug((" source = 0x%08lX , bytecount: %d bytes\n", (unsigned long)source, byteCount));
#if defined(BYTESWAP)
dblwordsSwap(source, byteCount);
int bytesSent = sendPacket(source, byteCount);
dblwordsSwap(source, byteCount);
#else
int bytesSent = sendPacket(source, byteCount);
#endif
if (bytesSent < 0) {
log_debug(("ether_send() - failed (bytesSent: %d bytes) -> NIL\n\n", bytesSent));
log_info(("ether_send(): FAILED to send packet, len = %d\n", byteCount));
return (NIL);
}
log_debug(("ether_send() - end -> ATOM_T\n\n"));
log_info(("ether_send(): sent packet, len = %d\n", bytesSent));
return (ATOM_T);
}
/**********************************************************************
* ether_setfilter(args) 175/76/1 filterbits
* check whether a packet has come. if does, notify iocb
**********************************************************************/
LispPTR ether_setfilter(LispPTR args[])
{
log_debug(("ether_setfilter() - ????\n\n"));
return (NIL);
}
/**********************************************************************
* check_ether() 175/77/0
* checks an incoming packet
**********************************************************************/
LispPTR check_ether()
{
LispPTR result = (NIL);
if (ether_fd < 0) {
return result;
}
struct pollfd pfds[1];
pfds[0].fd = ether_fd;
pfds[0].events = POLLIN;
pfds[0].revents = 0;
poll(pfds, 1, 0);
if (pfds[0].revents & POLLIN) {
log_debug(("check_ether() - begin\n"));
int receivedBytes = recvPacket();
if (receivedBytes > 0) {
((INTSTAT *)NativeAligned4FromLAddr(*INTERRUPTSTATE_word))->ETHERInterrupt = 1;
ETHEREventCount++;
Irq_Stk_Check = Irq_Stk_End = 0; /* ??? */
*PENDINGINTERRUPT68k = (ATOM_T);
log_debug(("check_ether() :: raised LISP interrupt\n"));
log_debug(("check_ether() :: INTERRUPTSTATE_word = 0x%08X\n",
*((int*)NativeAligned4FromLAddr(*INTERRUPTSTATE_word))));
log_debug(("check_ether() :: PENDINGINTERRUPT_word = 0x%08X\n",
*((int*)PENDINGINTERRUPT68k)));
result = (ATOM_T);
log_debug(("check_ether() - end -> ATOM_T\n\n"));
log_info(("check_ether(): received packet, len = %d bytes\n", receivedBytes));
} else {
log_debug(("check_ether() - end -> NIL\n\n"));
}
}
return result;
}
#endif /* MAIKO_ENABLE_NETHUB */

View File

@ -7,6 +7,8 @@
/* */
/************************************************************************/
#if defined(MAIKO_ENABLE_ETHERNET) && !defined(MAIKO_ENABLE_NETHUB)
#include "version.h"
#if defined(USE_DLPI)
@ -79,17 +81,17 @@
#define NIOCSETF PFIOCSETF
#endif
int ether_fd = -1; /* file descriptor for ether socket */
int ether_intf_type = 0;
u_char ether_host[6] = {0, 0, 0, 0, 0, 0}; /* 48 bit address of this node */
u_char broadcast[6] = {255, 255, 255, 255, 255, 255};
int ether_bsize = 0; /* if nonzero then a receive is pending */
u_char *ether_buf; /* address of receive buffer */
u_char nit_buf[3000]; /* the current chunk read from NIT (one packet) */
extern int ether_fd; /* file descriptor for ether socket */
static int ether_intf_type = 0;
extern u_char ether_host[6]; /* 48 bit address of this node */
extern u_char broadcast[6];
extern int ether_bsize; /* if nonzero then a receive is pending */
extern u_char *ether_buf; /* address of receive buffer */
static u_char nit_buf[3000]; /* the current chunk read from NIT (one packet) */
extern LispPTR *PENDINGINTERRUPT68k;
extern fd_set LispReadFds;
extern fd_set LispReadFds;
int ETHEREventCount = 0;
extern int ETHEREventCount;
#define PacketTypeIP 0x0800
#define PacketTypeARP 0x0806
@ -120,7 +122,6 @@ int ETHEREventCount = 0;
ments of the stack and replaces them with its result. When
both an action and operator are specified in the same short-
word, the action is performed followed by the operation.
The binary operator can also be from the set { ENF_COR,
ENF_CAND, ENF_CNOR, ENF_CNAND }. These are "short-circuit"
operators, in that they terminate the execution of the
@ -132,7 +133,6 @@ int ETHEREventCount = 0;
false; ENF_CNOR returns false if the result is true. Unlike
the other binary operators, these four do not leave a result
on the stack, even if they continue.
The short-circuit operators should be used when possible, to
reduce the amount of time spent evaluating filters. When
they are used, you should also arrange the order of the
@ -140,7 +140,6 @@ int ETHEREventCount = 0;
possible; for example, checking the IP destination field of
a UDP packet is more likely to indicate failure than the
packet type field.
The special action ENF_NOPUSH and the special operator
ENF_NOP can be used to only perform the binary operation or
to only push a value on the stack. Since both are (con-
@ -148,7 +147,6 @@ int ETHEREventCount = 0;
actually specifies the action followed by ENF_NOP, and indi-
cating only an operation actually specifies ENF_NOPUSH fol-
lowed by the operation.
After executing the filter command list, a non-zero value
(true) left on top of the stack (or an empty stack) causes
the incoming packet to be accepted and a zero value (false)
@ -746,23 +744,7 @@ static void init_uid() {
rid = getuid();
setuid(rid);
}
#endif /* MAIKO_ENABLE_ETHERNET */
/************************************************************************/
/* i n i t _ i f p a g e _ e t h e r */
/* */
/* sets Lisp's idea of \my.nsaddress. Clears it if ether not */
/* enabled */
/* */
/************************************************************************/
void init_ifpage_ether() {
InterfacePage->nshost0 = (DLword)((ether_host[0] << 8) + ether_host[1]);
InterfacePage->nshost1 = (DLword)((ether_host[2] << 8) + ether_host[3]);
InterfacePage->nshost2 = (DLword)((ether_host[4] << 8) + ether_host[5]);
}
#ifdef MAIKO_ENABLE_ETHERNET
/* this needs to be a global so the name can be set by main() in Ctest */
/* But MAIKO_ENABLE_ETHERNET doesn't support NIT, so dyke it out for MAIKO_ENABLE_ETHERNET */
#if defined(USE_NIT)
@ -1085,49 +1067,4 @@ void init_ether() {
#endif /* MAIKO_ENABLE_ETHERNET */
}
#define MASKWORD1 0xffff
/************************************************************************/
/* */
/* c h e c k _ s u m */
/* */
/* Implements the CHECKSUM opcode; compute the checksum for an */
/* ethernet packet. */
/* */
/* args[0] LispPTR base; */
/* args[1] LispPTR nwords; */
/* args[2] LispPTR initsum; */
/* */
/* */
/************************************************************************/
LispPTR check_sum(LispPTR *args)
{
LispPTR checksum;
DLword *address;
int nwords;
address = (DLword *)NativeAligned2FromLAddr(*args++);
nwords = *args++;
if (*args != NIL)
checksum = (*args) & MASKWORD1;
else
checksum = 0;
for (; nwords > (S_POSITIVE); address++, nwords--) {
checksum = checksum + GETWORD(address);
if (checksum > 0xffff) checksum = (checksum & 0xffff) + 1; /* add carry */
if (checksum > 0x7fff) /* ROTATE LEFT 1 */
checksum = ((checksum & 0x7fff) << 1) | 1;
else
checksum = checksum << 1;
}
if (checksum == MASKWORD1)
return (S_POSITIVE); /* ret 0 */
else
return (S_POSITIVE | checksum);
} /*check_sum */
#endif /* defined(MAIKO_ENABLE_ETHERNET) */

View File

@ -46,7 +46,7 @@
#include "mkcelldefs.h" // for N_OP_createcell
#include "testtooldefs.h" // for MakeAtom68k, MAKEATOM
#ifdef MAIKO_ENABLE_ETHERNET
#if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
#include "etherdefs.h"
#endif
@ -117,9 +117,9 @@ void init_ifpage(int sysout_size) {
Initialize IFPAGE
*/
InterfacePage->machinetype = KATANA; /* 3 is katana */
#ifdef MAIKO_ENABLE_ETHERNET
#if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
init_ifpage_ether(); /* store ethernet ID in IF page */
#endif /* MAIKO_ENABLE_ETHERNET */
#endif /* MAIKO_ENABLE_ETHERNET or MAIKO_ENABLE_NETHUB */
/*InterfacePage->dl24bitaddressable = (sysout_size == 32? 0xffff : 0);*/
InterfacePage->dl24bitaddressable = (sysout_size == 8 ? 0 : 0xffff);
new_lastvmem = (sysout_size * PAGES_IN_MBYTE) - 1;

View File

@ -61,9 +61,9 @@ void Mouse_hndlr(void); /* Fields mouse events from driver */
#include "osmsgdefs.h"
#include "xwinmandefs.h"
#ifdef MAIKO_ENABLE_ETHERNET
#if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
#include "etherdefs.h"
#endif /* MAIKO_ENABLE_ETHERNET */
#endif /* MAIKO_ENABLE_ETHERNET or MAIKO_ENABLE_NETHUB */
#include "dbprint.h"
#if (defined(DOS) || defined(XWINDOW))
@ -124,9 +124,9 @@ extern volatile sig_atomic_t XNeedSignal;
extern int LogFileFd;
#ifdef MAIKO_ENABLE_ETHERNET
#if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
extern int ether_fd;
#endif /* MAIKO_ENABLE_ETHERNET */
#endif /* MAIKO_ENABLE_ETHERNET or MAIKO_ENABLE_NETHUB */
extern DLword *DisplayRegion68k;
@ -263,6 +263,10 @@ void process_io_events()
}
#endif /* MAIKO_ENABLE_ETHERNET */
#ifdef MAIKO_ENABLE_NETHUB
check_ether();
#endif /* MAIKO_ENABLE_NETHUB */
#ifdef RS232
if (RS232C_Fd >= 0 && (FD_ISSET(RS232C_Fd, &rfds) || (RS232C_remain_data && rs232c_lisp_is_ready())))
rs232c_read();

View File

@ -285,6 +285,22 @@ const char *helpstring =
-help Print this message\n";
#endif /* DOS */
#if defined(MAIKO_ENABLE_NETHUB)
const char *nethubHelpstring =
"\
-nh-host dodo-host Hostname for Dodo Nethub (no networking if missing)\n\
-nh-port port-number Port for Dodo Nethub (optional, default: 3333)\n\
-nh-mac XX-XX-XX-XX-XX-XX Machine-ID for Maiko-VM (optional, default: CA-FF-EE-12-34-56) \n\
-nh-loglevel level Loglevel for Dodo networking (0..2, optional, default: 0)\n\
";
#else
const char *nethubHelpstring = "";
#endif
#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS)
extern int insnsCountdownForTimerAsyncEmulation;
#endif
/************************************************************************/
/* */
/* M A I N E N T R Y P O I N T */
@ -333,7 +349,7 @@ int main(int argc, char *argv[])
}
if (argv[i] && ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "-HELP") == 0))) {
fprintf(stderr, "%s", helpstring);
fprintf(stderr, "%s%s", helpstring, nethubHelpstring);
exit(0);
}
@ -356,7 +372,7 @@ int main(int argc, char *argv[])
}
if (access(sysout_name, R_OK)) {
perror("Couldn't find a sysout to run");
fprintf(stderr, "%s", helpstring);
fprintf(stderr, "%s%s", helpstring, nethubHelpstring);
exit(1);
}
/* OK, sysout name is now in sysout_name, and i is moved past a supplied name */
@ -454,6 +470,80 @@ int main(int argc, char *argv[])
#endif /* MAIKO_ENABLE_ETHERNET */
}
#ifdef MAIKO_ENABLE_NETHUB
else if (!strcmp(argv[i], "-nh-host")) {
if (argc > ++i) {
setNethubHost(argv[i]);
} else {
fprintf(stderr, "Missing argument after -nh-host\n");
exit(1);
}
}
else if (!strcmp(argv[i], "-nh-port")) {
if (argc > ++i) {
errno = 0;
tmpint = strtol(argv[i], (char **)NULL, 10);
if (errno == 0 && tmpint > 0) {
setNethubPort(tmpint);
} else {
fprintf(stderr, "Bad value for -nh-port\n");
exit(1);
}
} else {
fprintf(stderr, "Missing argument after -nh-port\n");
exit(1);
}
}
else if (!strcmp(argv[i], "-nh-mac")) {
if (argc > ++i) {
int b0, b1, b2, b3, b4, b5;
if (sscanf(argv[i], "%x-%x-%x-%x-%x-%x", &b0, &b1, &b2, &b3, &b4, &b5) == 6) {
setNethubMac(b0, b1, b2, b3, b4, b5);
} else {
fprintf(stderr, "Invalid argument for -nh-mac\n");
exit(1);
}
} else {
fprintf(stderr, "Missing argument after -nh-mac\n");
exit(1);
}
}
else if (!strcmp(argv[i], "-nh-loglevel")) {
if (argc > ++i) {
errno = 0;
tmpint = strtol(argv[i], (char **)NULL, 10);
if (errno == 0 && tmpint >= 0) {
setNethubLogLevel(tmpint);
} else {
fprintf(stderr, "Bad value for -nh-loglevel\n");
exit(1);
}
} else {
fprintf(stderr, "Missing argument after -nh-loglevel\n");
exit(1);
}
}
#endif /* MAIKO_ENABLE_NETHUB */
#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS)
else if (!strcmp(argv[i], "-intr-emu-insns")) {
if (argc > ++i) {
errno = 0;
tmpint = strtol(argv[i], (char **)NULL, 10);
if (errno == 0 && tmpint > 1000) {
insnsCountdownForTimerAsyncEmulation = tmpint;
} else {
fprintf(stderr, "Bad value for -intr-emu-insns (integer > 1000)\n");
exit(1);
}
} else {
fprintf(stderr, "Missing argument after -intr-emu-insns\n");
exit(1);
}
}
#endif
/* diagnostic flag for big vmem write() calls */
else if (!strcmp(argv[i], "-xpages")) {
if (argc > ++i) {
@ -491,6 +581,10 @@ int main(int argc, char *argv[])
init_ether(); /* modified by kiuchi Nov. 4 */
#endif /* MAIKO_ENABLE_ETHERNET */
#ifdef MAIKO_ENABLE_NETHUB
connectToHub();
#endif
#ifdef DOS
init_host_filesystem();
#else

View File

@ -162,6 +162,17 @@ static const int n_mask_array[16] = {
extern int TIMER_INTERVAL;
#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS)
# if !defined(MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN)
# define MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN 20000
# endif
int insnsCountdownForTimerAsyncEmulation = MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN;
static int pseudoTimerAsyncCountdown = MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN;
#endif
void dispatch(void) {
InstPtr pccache;
@ -260,6 +271,17 @@ nextopcode:
#endif /* PCTRACE */
/* quick_stack_check();*/ /* JDS 2/12/98 */
#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS)
if (--pseudoTimerAsyncCountdown <= 0) {
Irq_Stk_Check = 0;
Irq_Stk_End = 0;
#if defined(MAIKO_EMULATE_ASYNC_INTERRUPTS)
IO_Signalled = TRUE;
#endif
pseudoTimerAsyncCountdown = insnsCountdownForTimerAsyncEmulation;
}
#endif
switch (Get_BYTE_PCMAC0) {
case 000:

View File

@ -121,6 +121,13 @@ void print_Xusage(const char *prog)
fprintf(stderr, " -iconbitmap <path> | -ibm <path> -bitmap for the medley icon\n");
fprintf(stderr,
" -xsync -turn XSynchronize on. (default is off)\n\n");
#if defined(MAIKO_ENABLE_NETHUB)
fprintf(stderr,"\
-nh-host dodo-host Hostname for Dodo Nethub (no networking if missing)\n\
-nh-port port-number Port for Dodo Nethub (optional, default: 3333)\n\
-nh-mac XX-XX-XX-XX-XX-XX Machine-ID for Maiko-VM (optional, default: CA-FF-EE-12-34-56) \n\
-nh-loglevel level Loglevel for Dodo networking (0..2, optional, default: 0)\n\n");
#endif
fprintf(stderr, "Please refer to the manual for further information.\n\n");
exit(0);
} /* end print_Xusage() */