1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-04-29 13:32:51 +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
18 changed files with 1107 additions and 102 deletions

View File

@@ -72,10 +72,30 @@ IF(MAIKO_DISPLAY_X11)
) )
ENDIF() 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") IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
LIST(APPEND MAIKO_DEFINITIONS LIST(APPEND MAIKO_DEFINITIONS
"-DOS5" "-DOS5"
"-DUSE_DLPI"
) )
ENDIF() ENDIF()
@@ -142,7 +162,9 @@ SET(MAIKO_SRCS
src/dspif.c src/dspif.c
src/dspsubrs.c src/dspsubrs.c
src/eqf.c src/eqf.c
src/ether.c src/ether_common.c
src/ether_sunos.c
src/ether_nethub.c
src/findkey.c src/findkey.c
src/foreign.c src/foreign.c
src/fp.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 passed to the Lisp ethernet handler. Available on Sun systems
for both the NIT and DLPI cases. 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 bitbltsub.c:#ifdef GETBASE
testdisplay.c:#ifdef NOTUSED 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 # Options for Linux, Intel x86_64 and X-Window
#CC = gcc -m64 $(GCC_CFLAGS) #CC = gcc -m64 $(GCC_CFLAGS)
CC = clang -m64 $(CLANG_CFLAGS) CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB
XFILES = $(OBJECTDIR)xmkicon.o \ XFILES = $(OBJECTDIR)xmkicon.o \
$(OBJECTDIR)xbbt.o \ $(OBJECTDIR)xbbt.o \

View File

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

View File

@@ -115,7 +115,9 @@ DEVICES = $(OBJECTDIR)dspsubrs.o \
$(OBJECTDIR)dir.o \ $(OBJECTDIR)dir.o \
$(OBJECTDIR)keyevent.o \ $(OBJECTDIR)keyevent.o \
$(OBJECTDIR)kbdsubrs.o \ $(OBJECTDIR)kbdsubrs.o \
$(OBJECTDIR)ether.o \ $(OBJECTDIR)ether_common.o \
$(OBJECTDIR)ether_sunos.o \
$(OBJECTDIR)ether_nethub.o \
$(OBJECTDIR)tty.o \ $(OBJECTDIR)tty.o \
$(OBJECTDIR)initkbd.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 $(INCDIR)dbprint.h $(INCDIR)devif.h
$(CC) $(RFLAGS) $(SRCDIR)mouseif.c -o $(OBJECTDIR)mouseif.o $(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)commondefs.h $(INCDIR)lispemul.h \
$(INCDIR)lispmap.h $(INCDIR)emlglob.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.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)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)adr68k.h \
$(INCDIR)ether.h $(INCDIR)dbprint.h $(INCDIR)etherdefs.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) \ $(OBJECTDIR)findkey.o: $(SRCDIR)findkey.c $(REQUIRED-INCS) \
$(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(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_ifpage_ether(void);
void init_ether(void); void init_ether(void);
LispPTR check_sum(LispPTR *args); 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 #endif

View File

@@ -17,6 +17,8 @@
# define MAIKO_OS_CYGWIN 1 # define MAIKO_OS_CYGWIN 1
# define MAIKO_OS_NAME "Cygwin" # define MAIKO_OS_NAME "Cygwin"
# define MAIKO_OS_UNIX_LIKE 1 # define MAIKO_OS_UNIX_LIKE 1
# define MAIKO_EMULATE_TIMER_INTERRUPTS 1
# define MAIKO_EMULATE_ASYNC_INTERRUPTS 1
# define MAIKO_OS_DETECTED 1 # define MAIKO_OS_DETECTED 1
#endif #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" #include "version.h"
#if defined(USE_DLPI) #if defined(USE_DLPI)
@@ -79,17 +81,17 @@
#define NIOCSETF PFIOCSETF #define NIOCSETF PFIOCSETF
#endif #endif
int ether_fd = -1; /* file descriptor for ether socket */ extern int ether_fd; /* file descriptor for ether socket */
int ether_intf_type = 0; static int ether_intf_type = 0;
u_char ether_host[6] = {0, 0, 0, 0, 0, 0}; /* 48 bit address of this node */ extern u_char ether_host[6]; /* 48 bit address of this node */
u_char broadcast[6] = {255, 255, 255, 255, 255, 255}; extern u_char broadcast[6];
int ether_bsize = 0; /* if nonzero then a receive is pending */ extern int ether_bsize; /* if nonzero then a receive is pending */
u_char *ether_buf; /* address of receive buffer */ extern u_char *ether_buf; /* address of receive buffer */
u_char nit_buf[3000]; /* the current chunk read from NIT (one packet) */ static u_char nit_buf[3000]; /* the current chunk read from NIT (one packet) */
extern LispPTR *PENDINGINTERRUPT68k; extern LispPTR *PENDINGINTERRUPT68k;
extern fd_set LispReadFds; extern fd_set LispReadFds;
int ETHEREventCount = 0; extern int ETHEREventCount;
#define PacketTypeIP 0x0800 #define PacketTypeIP 0x0800
#define PacketTypeARP 0x0806 #define PacketTypeARP 0x0806
@@ -120,7 +122,6 @@ int ETHEREventCount = 0;
ments of the stack and replaces them with its result. When ments of the stack and replaces them with its result. When
both an action and operator are specified in the same short- both an action and operator are specified in the same short-
word, the action is performed followed by the operation. word, the action is performed followed by the operation.
The binary operator can also be from the set { ENF_COR, The binary operator can also be from the set { ENF_COR,
ENF_CAND, ENF_CNOR, ENF_CNAND }. These are "short-circuit" ENF_CAND, ENF_CNOR, ENF_CNAND }. These are "short-circuit"
operators, in that they terminate the execution of the 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 false; ENF_CNOR returns false if the result is true. Unlike
the other binary operators, these four do not leave a result the other binary operators, these four do not leave a result
on the stack, even if they continue. on the stack, even if they continue.
The short-circuit operators should be used when possible, to The short-circuit operators should be used when possible, to
reduce the amount of time spent evaluating filters. When reduce the amount of time spent evaluating filters. When
they are used, you should also arrange the order of the 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 possible; for example, checking the IP destination field of
a UDP packet is more likely to indicate failure than the a UDP packet is more likely to indicate failure than the
packet type field. packet type field.
The special action ENF_NOPUSH and the special operator The special action ENF_NOPUSH and the special operator
ENF_NOP can be used to only perform the binary operation or ENF_NOP can be used to only perform the binary operation or
to only push a value on the stack. Since both are (con- 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- actually specifies the action followed by ENF_NOP, and indi-
cating only an operation actually specifies ENF_NOPUSH fol- cating only an operation actually specifies ENF_NOPUSH fol-
lowed by the operation. lowed by the operation.
After executing the filter command list, a non-zero value After executing the filter command list, a non-zero value
(true) left on top of the stack (or an empty stack) causes (true) left on top of the stack (or an empty stack) causes
the incoming packet to be accepted and a zero value (false) the incoming packet to be accepted and a zero value (false)
@@ -746,23 +744,7 @@ static void init_uid() {
rid = getuid(); rid = getuid();
setuid(rid); 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 */ /* 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 */ /* But MAIKO_ENABLE_ETHERNET doesn't support NIT, so dyke it out for MAIKO_ENABLE_ETHERNET */
#if defined(USE_NIT) #if defined(USE_NIT)
@@ -1085,49 +1067,4 @@ void init_ether() {
#endif /* MAIKO_ENABLE_ETHERNET */ #endif /* MAIKO_ENABLE_ETHERNET */
} }
#define MASKWORD1 0xffff #endif /* defined(MAIKO_ENABLE_ETHERNET) */
/************************************************************************/
/* */
/* 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 */

View File

@@ -46,7 +46,7 @@
#include "mkcelldefs.h" // for N_OP_createcell #include "mkcelldefs.h" // for N_OP_createcell
#include "testtooldefs.h" // for MakeAtom68k, MAKEATOM #include "testtooldefs.h" // for MakeAtom68k, MAKEATOM
#ifdef MAIKO_ENABLE_ETHERNET #if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
#include "etherdefs.h" #include "etherdefs.h"
#endif #endif
@@ -117,9 +117,9 @@ void init_ifpage(int sysout_size) {
Initialize IFPAGE Initialize IFPAGE
*/ */
InterfacePage->machinetype = KATANA; /* 3 is katana */ 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 */ 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 == 32? 0xffff : 0);*/
InterfacePage->dl24bitaddressable = (sysout_size == 8 ? 0 : 0xffff); InterfacePage->dl24bitaddressable = (sysout_size == 8 ? 0 : 0xffff);
new_lastvmem = (sysout_size * PAGES_IN_MBYTE) - 1; 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 "osmsgdefs.h"
#include "xwinmandefs.h" #include "xwinmandefs.h"
#ifdef MAIKO_ENABLE_ETHERNET #if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
#include "etherdefs.h" #include "etherdefs.h"
#endif /* MAIKO_ENABLE_ETHERNET */ #endif /* MAIKO_ENABLE_ETHERNET or MAIKO_ENABLE_NETHUB */
#include "dbprint.h" #include "dbprint.h"
#if (defined(DOS) || defined(XWINDOW)) #if (defined(DOS) || defined(XWINDOW))
@@ -124,9 +124,9 @@ extern volatile sig_atomic_t XNeedSignal;
extern int LogFileFd; extern int LogFileFd;
#ifdef MAIKO_ENABLE_ETHERNET #if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB)
extern int ether_fd; extern int ether_fd;
#endif /* MAIKO_ENABLE_ETHERNET */ #endif /* MAIKO_ENABLE_ETHERNET or MAIKO_ENABLE_NETHUB */
extern DLword *DisplayRegion68k; extern DLword *DisplayRegion68k;
@@ -263,6 +263,10 @@ void process_io_events()
} }
#endif /* MAIKO_ENABLE_ETHERNET */ #endif /* MAIKO_ENABLE_ETHERNET */
#ifdef MAIKO_ENABLE_NETHUB
check_ether();
#endif /* MAIKO_ENABLE_NETHUB */
#ifdef RS232 #ifdef RS232
if (RS232C_Fd >= 0 && (FD_ISSET(RS232C_Fd, &rfds) || (RS232C_remain_data && rs232c_lisp_is_ready()))) if (RS232C_Fd >= 0 && (FD_ISSET(RS232C_Fd, &rfds) || (RS232C_remain_data && rs232c_lisp_is_ready())))
rs232c_read(); rs232c_read();

View File

@@ -285,6 +285,22 @@ const char *helpstring =
-help Print this message\n"; -help Print this message\n";
#endif /* DOS */ #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 */ /* 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))) { 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); exit(0);
} }
@@ -356,7 +372,7 @@ int main(int argc, char *argv[])
} }
if (access(sysout_name, R_OK)) { if (access(sysout_name, R_OK)) {
perror("Couldn't find a sysout to run"); perror("Couldn't find a sysout to run");
fprintf(stderr, "%s", helpstring); fprintf(stderr, "%s%s", helpstring, nethubHelpstring);
exit(1); exit(1);
} }
/* OK, sysout name is now in sysout_name, and i is moved past a supplied name */ /* 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 */ #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 */ /* diagnostic flag for big vmem write() calls */
else if (!strcmp(argv[i], "-xpages")) { else if (!strcmp(argv[i], "-xpages")) {
if (argc > ++i) { if (argc > ++i) {
@@ -491,6 +581,10 @@ int main(int argc, char *argv[])
init_ether(); /* modified by kiuchi Nov. 4 */ init_ether(); /* modified by kiuchi Nov. 4 */
#endif /* MAIKO_ENABLE_ETHERNET */ #endif /* MAIKO_ENABLE_ETHERNET */
#ifdef MAIKO_ENABLE_NETHUB
connectToHub();
#endif
#ifdef DOS #ifdef DOS
init_host_filesystem(); init_host_filesystem();
#else #else

View File

@@ -162,6 +162,17 @@ static const int n_mask_array[16] = {
extern int TIMER_INTERVAL; 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) { void dispatch(void) {
InstPtr pccache; InstPtr pccache;
@@ -260,6 +271,17 @@ nextopcode:
#endif /* PCTRACE */ #endif /* PCTRACE */
/* quick_stack_check();*/ /* JDS 2/12/98 */ /* 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) { switch (Get_BYTE_PCMAC0) {
case 000: 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, " -iconbitmap <path> | -ibm <path> -bitmap for the medley icon\n");
fprintf(stderr, fprintf(stderr,
" -xsync -turn XSynchronize on. (default is off)\n\n"); " -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"); fprintf(stderr, "Please refer to the manual for further information.\n\n");
exit(0); exit(0);
} /* end print_Xusage() */ } /* end print_Xusage() */