mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-28 04:38:00 +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:
204
src/ether_common.c
Normal file
204
src/ether_common.c
Normal 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
598
src/ether_nethub.c
Normal 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 */
|
||||
|
||||
@@ -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) */
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
98
src/main.c
98
src/main.c
@@ -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
|
||||
|
||||
22
src/xc.c
22
src/xc.c
@@ -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:
|
||||
|
||||
@@ -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() */
|
||||
|
||||
Reference in New Issue
Block a user