This commit is contained in:
Kelvin Sherlock 2018-05-10 21:06:58 -04:00
parent 517dfd3ad6
commit 12032fe800
6 changed files with 383 additions and 287 deletions

View File

@ -1,5 +1,4 @@
PROG = marlene
OBJS = o/vt100.a o/telnet.a o/ansi.a o/chars.a o/marinetti.a o/display.a
OBJS = o/vt100.a o/telnet.a o/ansi.a o/chars.a o/marinetti.a o/display.a o/screen.a
CC = occ --gno
@ -10,7 +9,7 @@ ASMFLAGS =
.PHONY: all clean clobber
all: marlene
all: marlene darlene
marlene: o/marlene.a $(OBJS)
$(CC) $^ -o $@
@ -25,6 +24,7 @@ darlene.o: darlene.c
vt100.o: vt100.c CLAGS+=-r
marinetti.o: marinetti.c CLAGS+=-r
telnet.o: telnet.c CLAGS+=-r
screen.o: screen.c CLAGS+=-r
ansi.o: ansi.asm
chars.o: chars.asm
@ -42,4 +42,4 @@ o/%.a : %.asm | o
clean:
$(RM) -rf o
clobber: clean
$(RM) -f $(PROG)
$(RM) -f marlene darlene

189
darlene.c
View File

@ -3,20 +3,55 @@
*
*/
#include <texttool.h>
#include <gsos.h>
#include <Event.h>
#include <fcntl.h>
#include <gsos.h>
#include <Locator.h>
#include <Memory.h>
#include <texttool.h>
#include <sgtty.h>
#include <errno.h>
#include <fcntl.h>
#include <gno/gno.h>
#include <gno/kerntool.h>
#include <libutil.h>
#include <unistd.h>
#include <sgtty.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/ioctl.compat.h>
#include <sys/ioctl.h>
#include <unistd.h>
extern void screen_init(void);
extern void screen_on(void);
extern void screen_off(void);
static char out_buffer[1024];
static char out_buffer_size = 0;
static int master = -1;
static void flush(void) {
if (out_buffer_size) {
write(master, out_buffer, out_buffer_size);
out_buffer_size = 0;
}
}
void send(char *data, unsigned size) {
if (out_buffer_size + size > sizeof(out_buffer)) {
flush();
}
if (size > sizeof(out_buffer) / 2) {
write(master, data, size);
return;
}
memcpy(out_buffer + out_buffer_size, data, size);
out_buffer_size += size;
}
int
@ -96,43 +131,151 @@ static void sigchild(int sig, int x) {
int main(int argc, char **argv) {
int fd;
int pid;
unsigned i;
Handle dpHandle = NULL;
Handle shrHandle = NULL;
Handle shdHandle = NULL;
master = -1;
kernStatus();
if (_toolErr) {
ErrWriteCString("GNO/ME required.\r\n");
return 1;
}
for (i = 1; i < argc; ++i) {
char *cp = argv[i];
if (cp[0] != '-') break;
if (strcmp(cp, "--vt52") == 0) {
} else if (strcmp(cp, "--vt100") == 0) {
} else {
ErrWriteCString("Unknown option: ");
ErrWriteCString(cp);
ErrWriteCString("\r\n");
return 1;
}
}
argc -= i;
argv += i;
signal(SIGCHLD,sigchild);
pid = forkpty2(&fd, NULL, NULL, NULL);
pid = forkpty2(&master, NULL, NULL, NULL);
if ( pid < 0) {
ErrWriteCString("Unable to forkpty.\r\n");
return 1;
}
dpHandle = NewHandle(0x0100, MyID,
attrBank | attrPage |attrNoCross | attrFixed | attrLocked,
0x000000);
shdHandle = NewHandle(0x8000, MyID,
attrAddr | attrFixed | attrLocked,
(void *)0x012000);
shrHandle = NewHandle(0x8000, MyID,
attrAddr | attrFixed | attrLocked,
(void *)0xe12000);
if (!dpHandle || !shdHandle || !shrHandle) {
ErrWriteCString("Unable to allocate memory.\r\n");
if (dpHandle) DisposeHandle(dpHandle);
if (shdHandle) DisposeHandle(shdHandle);
if (shrHandle) DisposeHandle(shrHandle);
return 1;
}
EMStartUp((Word)*dpHandle, 0x14, 0, 0, 0, 0, MyID);
screen_init();
vt100_init();
screen_init();
vt100_init();
for(;;) {
static char buffer[1024];
int fio = 0;
ioctl(fd, FIONREAD, &fio);
ioctl(master, FIONREAD, &fio);
if (fio > sizeof(buffer)) fio = sizeof(buffer);
if (fio > 0) {
fio = read(fd, buffer, fio);
fio = read(master, buffer, fio);
if (fio > 0) vt100_process(buffer, fio);
}
GetNextEvent(everyEvent, &event);
if (event.what == keyDownEvt) {
if (GetNextEvent(everyEvent, &event)) {
fio = 1;
if (event.what == keyDownEvt) {
}
unsigned char key = event.message;
if (event.what == app4Mask) {
/* child signal received! */
union wait wt;
ok = waitpid(pid, &wt, WNOHANG);
if (ok <= 0) continue;
display_str("\r\nChild exited.\r\n");
break;
if (event.modifiers & appleKey) {
switch (key) {
case 'Q': // quit
case 'q':
goto _exit1;
break;
case 'V': // paste...
case 'v':
break;
case 'Z': // suspend (gnome)
case 'z': {
/* EMStartUp puts the tty in RAW mode. */
static struct sgttyb sb;
gtty(1,&sb);
sb.sg_flags &= ~RAW;
stty(1,&sb);
screen_off();
Kkill(Kgetpid(), SIGSTOP, &errno);
sb.sg_flags |= RAW;
stty(1,&sb);
screen_on();
}
break;
}
} else {
vt100_event(&event);
}
}
if (event.what == app4Mask) {
/* child signal received! */
union wait wt;
ok = waitpid(pid, &wt, WNOHANG);
if (ok <= 0) continue;
display_str("\r\nChild exited.\r\n");
break;
}
}
asm { cop 0x7f }
flush();
if (fio <= 0) asm { cop 0x7f }
}
_exit1:
flush();
if (master >= 0) close(master);
if (fd >= 0) close(fd);
_exit:
// flush q
FlushEvents(everyEvent, 0);
display_cstr("\n\rPress any key to exit.\n\r");
while (!GetNextEvent(keyDownMask | autoKeyMask, &event)) ;
EMShutDown();
DisposeHandle(dpHandle);
DisposeHandle(shdHandle);
DisposeHandle(shrHandle);
screen_off();
return 0;
}

View File

@ -2,7 +2,10 @@
#pragma lint -1
#include <Event.h>
#include "Marinetti.h"
#include <tcpip.h>
#include <locator.h>
#include "marinetti.h"
#include <stdlib.h>
#include <string.h>
@ -64,7 +67,7 @@ EventRecord event;
free(pstr);
return false;
}
while (dnr.DNRStatus == DNRPending) {
while (dnr.DNRstatus == DNR_Pending) {
TCPIPPoll();
GetNextEvent(keyDownMask | autoKeyMask, &event);
if ((event.what == keyDownEvt)
@ -74,8 +77,8 @@ EventRecord event;
break;
}
}
if (dnr.DNRStatus == DNROK) {
cvt->cvtIPAddress = dnr.DNRIPAddress;
if (dnr.DNRstatus == DNR_OK) {
cvt->cvtIPAddress = dnr.DNRIPaddress;
cvt->cvtPort = port;
free(pstr);
return true;
@ -88,7 +91,7 @@ EventRecord event;
}
int WaitForStatus(word ipid, word status_mask) {
static srBuffer sr;
static srBuff sr;
EventRecord event;
Word err;
unsigned bits;
@ -111,4 +114,63 @@ int WaitForStatus(word ipid, word status_mask) {
return 0;
}
int StartUpTCP(displayPtr fx)
{
word status;
word flags = 0;
// TCPIP is an init, not a tool, so it should always
// be loaded.
status = TCPIPStatus();
if (_toolErr) {
LoadOneTool(54, 0x0300);
if (_toolErr == toolVersionErr) return kVersionError;
if (_toolErr) return kLoadError;
status = 0;
flags |= kLoaded;
}
// require 3.0b3
if (TCPIPLongVersion() < 0x03006003) {
if (flags & kLoaded)
UnloadOneTool(54);
return kVersionError;
}
if (!status) {
TCPIPStartUp();
if (_toolErr) return kLoadError;
flags |= kStarted;
}
status = TCPIPGetConnectStatus();
if (!status) {
TCPIPConnect(fx);
flags |= kConnected;
}
return flags;
}
void ShutDownTCP(int flags, Boolean force, displayPtr fx) {
if (flags <= 0) return;
if (flags & kConnected)
{
TCPIPDisconnect(force, fx);
if (_toolErr) return;
}
if (flags & kStarted) {
TCPIPShutDown();
if (_toolErr) return;
}
if (flags & kLoaded) {
UnloadOneTool(54);
}
}

View File

@ -1,139 +1,22 @@
#ifndef __TCPIP_H__
#define __TCPIP_H__
#ifndef __marinetti_h__
#define __marinetti_h__
#include <types.h>
struct dnrBuffer
{
Word DNRStatus;
LongWord DNRIPAddress;
enum {
kLoaded = 1,
kStarted = 2,
kConnected = 4,
kLoadError = -1,
kVersionError = -2
};
typedef struct dnrBuffer dnrBuffer, *dnrBufferPtr, **dnrBufferHndl;
#define DNRPending 0x0000
#define DNROK 0x0001
#define DNRFailed 0x0002
#define DNRNoDNSEntry 0x0003
#define DNRCancelled 0x0004
struct srBuffer
{
Word srState;
Word srNetworkError;
LongWord srSndQueued;
LongWord srRcvQueued;
LongWord srDestIP;
Word srDestPort;
Word srConnectType;
Word srAcceptCount;
};
typedef struct srBuffer srBuffer, *srBufferPtr, **srBufferHndl;
struct rrBuff
{
LongWord rrBuffCount;
Handle rrBuffHandle;
Word rrMoreFlag;
Word rrPushFlag;
Word rrUrgentFlag;
};
typedef struct rrBuff rrBuff, *rrBuffPtr, **rrBuffHndl;
struct cvtRec
{
LongWord cvtIPAddress;
Word cvtPort;
};
typedef struct cvtRec cvtRec, *cvtRecPtr, **cvtRecHndl;
/*
* TCP states
*/
#define tcpsCLOSED 0x0000
#define tcpsLISTEN 0x0001
#define tcpsSYNSENT 0x0002
#define tcpsSYNRCVD 0x0003
#define tcpsESTABLISHED 0x0004
#define tcpsFINWAIT1 0x0005
#define tcpsFINWAIT2 0x0006
#define tcpsCLOSEWAIT 0x0007
#define tcpsLASTACK 0x0008
#define tcpsCLOSING 0x0009
#define tcpsTIMEWAIT 0x000A
pascal void TCPIPStartUp(void)
inline(0x0236 ,0xe10000);
pascal void TCPIPShutDown(void)
inline(0x0336 ,0xe10000);
pascal Word TCPIPStatus(void)
inline(0x0636 ,0xe10000);
pascal Word TCPIPGetConnectStatus(void)
inline(0x0936, 0xe10000);
pascal void TCPIPConvertIPToHex(cvtRecPtr, const char *)
inline(0x0d36 ,0xe10000);
pascal void TCPIPConvertIPCToHex(cvtRecPtr, const char *)
inline(0x3f36 ,0xe10000);
pascal Word TCPIPConvertIPToAscii(LongWord, const char *, Word)
inline(0x0e36 ,0xe10000);
pascal Word TCPIPConvertIPToCAscii(LongWord, const char *, Word)
inline(0x5836 ,0xe10000);
pascal Word TCPIPMangleDomainName(Word, char *)
inline(0x5936 ,0xe10000);
pascal Word TCPIPValidateIPString(const char *)
inline(0x4836 ,0xe10000);
pascal Word TCPIPValidateIPCString(const char *)
inline(0x1536 ,0xe10000);
pascal void TCPIPConnect(void *)
inline(0x1236 ,0xe10000);
pascal void TCPIPDisconnect(word, void *)
inline(0x1336 ,0xe10000);
pascal void TCPIPCancelDNR(dnrBufferPtr)
inline(0x2036 ,0xe10000);
pascal void TCPIPDNRNameToIP(const char *, dnrBufferPtr)
inline(0x2136 ,0xe10000);
pascal void TCPIPPoll(void)
inline(0x2236 ,0xe10000);
pascal Word TCPIPLogin(Word, LongWord, Word, Word, Word)
inline(0x2336 ,0xe10000);
pascal void TCPIPLogout(Word)
inline(0x2436 ,0xe10000);
pascal Word TCPIPOpenTCP(Word)
inline(0x2C36 ,0xe10000);
pascal Word TCPIPWriteTCP(Word, void *, LongWord, Word, Word)
inline(0x2D36 ,0xe10000);
pascal Word TCPIPReadTCP(Word, Word, Ref, LongWord, rrBuffPtr)
inline(0x2E36 ,0xe10000);
pascal Word TCPIPCloseTCP(Word)
inline(0x2F36 ,0xe10000);
pascal Word TCPIPStatusTCP(Word, srBufferPtr)
inline(0x3136, 0xe10000);
Word ResolveHost(const char *name, cvtRecPtr cvt);
int WaitForStatus(word ipid, word status_mask);
int StartUpTCP(displayPtr fx);
void ShutDownTCP(int flags, Boolean force, displayPtr fx);
#endif

162
marlene.c
View File

@ -1,28 +1,27 @@
#include <tcpip.h>
#include <Event.h>
#include <gsos.h>
#include <Locator.h>
#include <Memory.h>
#include <tcpip.h>
#include <texttool.h>
#include <gsos.h>
#include <Event.h>
#include <fcntl.h>
#include <sgtty.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <gno/gno.h>
#include <gno/kerntool.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sgtty.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/ioctl.compat.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/ioctl.compat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "telnet.h"
extern void ClearScreen(void);
#include "marinetti.h"
extern pascal void GrafOn(void) inline(0x0a04, dispatcher);
extern pascal void GrafOff(void) inline(0x0b04, dispatcher);
@ -34,9 +33,6 @@ extern pascal void SetMasterSCB(Word) inline(0x1604,dispatcher);
extern pascal void InitColorTable(ColorTable) inline(0x0D04,dispatcher);
Word ResolveHost(const char *name, cvtRecPtr cvt);
int WaitForStatus(word ipid, word status_mask);
void display_pstr(const char *);
void display_cstr(const char *);
@ -49,6 +45,9 @@ extern void vt100_init(void);
extern void vt100_process(const unsigned char *buffer, unsigned buffer_size);
extern void vt100_event(EventRecord *event);
extern void screen_init(void);
extern void screen_on(void);
extern void screen_off(void);
@ -76,63 +75,7 @@ void printCallBack(const char *msg) {
#pragma databank 0
static void screen_init(void) {
#define WHITE 0x0fff
#define YELLOW 0x0ff0
#define BLACK 0x0000
#define BLUE 0x000f
#define GREEN 0x0080
#define RED 0x0f00
static ColorTable ct =
{
WHITE, // background
RED, // underline / blink
BLUE, // bold
GREEN, // foreground
WHITE,
RED,
BLUE,
GREEN,
WHITE,
RED,
BLUE,
GREEN,
WHITE,
RED,
BLUE,
GREEN,
};
unsigned i;
// linearize memory, enable shadowing.
asm
{
phb
pea 0xe0e0
plb
plb
sep #0x20
lda #0xC1
tsb 0xc029
lda #0x08
trb 0xc035
rep #0x20
plb
}
SetMasterSCB(0xc080);
SetAllSCBs(0xc080);
for (i = 0; i < 16; i++)
SetColorTable(i, ct);
ClearScreen();
GrafOn();
}
static char out_buffer[1024];
static char out_buffer_size = 0;
@ -166,6 +109,8 @@ unsigned buffer_size;
unsigned char buffer[2048]; // 1500 is normal MTU size?
int main(int argc, char **argv) {
static EventRecord event;
@ -175,22 +120,22 @@ int main(int argc, char **argv) {
static QuitRecGS qDCB = {2, 0, 0x4000};
Word iLoaded;
Word iConnected;
Word iStarted;
Handle dpHandle = NULL;
Handle shrHandle = NULL;
Handle shdHandle = NULL;
Word err;
int ok;
unsigned i;
int mf = 0;
iLoaded = iStarted = iConnected = false;
__gno = false;
ipid = -1;
MyID = MMStartUp();
TextStartUp();
SetOutputDevice(1,3);
SetOutGlobals(0x7f, 0);
kernStatus();
if (!_toolErr) __gno = true;
@ -219,11 +164,6 @@ int main(int argc, char **argv) {
return 1;
}
TextStartUp();
SetOutputDevice(1,3);
SetOutGlobals(0x7f, 0);
dpHandle = NewHandle(0x0100, MyID,
attrBank | attrPage |attrNoCross | attrFixed | attrLocked,
0x000000);
@ -238,7 +178,12 @@ int main(int argc, char **argv) {
if (!dpHandle || !shdHandle || !shrHandle) {
ErrWriteCString("Unable to allocate memory.\r\n");
goto _exit;
if (dpHandle) DisposeHandle(dpHandle);
if (shdHandle) DisposeHandle(shdHandle);
if (shrHandle) DisposeHandle(shrHandle);
return 1;
}
EMStartUp((Word)*dpHandle, 0x14, 0, 0, 0, 0, MyID);
@ -248,34 +193,13 @@ int main(int argc, char **argv) {
vt100_init();
TCPIPStatus();
if (_toolErr) {
display_cstr("Loading Marinetti...\n\r");
LoadOneTool(0x36, 0x200); //load Marinetti
if (_toolErr) {
display_cstr("Unable to load Marinetti.\r\n");
goto _exit;
}
iLoaded = true;
mf = StartUpTCP(printCallBack);
if (mf < 0) {
display_cstr("Marinetti 3.0b3 or greater is required.\r\n");
goto _exit;
}
// Marinetti now loaded
if (!TCPIPStatus()) {
display_cstr("Starting Marinetti...\n\r");
TCPIPStartUp();
iStarted = true;
}
if (!TCPIPGetConnectStatus()) {
display_cstr("Connecting Marinetti...\n\r");
TCPIPConnect(printCallBack);
if (_toolErr) {
display_cstr("Unable to establish network connection.\r\n");
goto _exit;
}
iConnected = true;
}
// marinetti is now connected
if (!ResolveHost(argv[0], &cvt)) {
@ -297,7 +221,7 @@ int main(int argc, char **argv) {
// wait for the connection to occur.
ok = WaitForStatus(ipid, 1 << TCPSESTABLISHED);
if (ok > 0) display_err(ok);
if (ok != 0) goto _exit2;
if (ok != 0) goto _exit;
display_cstr("Connected.\n\r");
@ -349,15 +273,14 @@ int main(int argc, char **argv) {
case 'z':
if (__gno) {
static struct sgttyb sb;
static int err;
gtty(1,&sb);
sb.sg_flags &= ~RAW;
stty(1,&sb);
GrafOff();
Kkill(Kgetpid(), SIGSTOP, &err);
screen_off();
Kkill(Kgetpid(), SIGSTOP, &errno);
sb.sg_flags |= RAW;
stty(1,&sb);
GrafOn();
screen_on();
}
break;
}
@ -377,21 +300,12 @@ _exit1:
TCPIPCloseTCP(ipid);
WaitForStatus(ipid, (1 << TCPSCLOSED) | (1 << TCPSTIMEWAIT));
_exit2:
_exit:
if (ipid != -1) TCPIPLogout(ipid);
if (iConnected)
TCPIPDisconnect(false, printCallBack);
if (iStarted)
TCPIPShutDown();
if (iLoaded)
UnloadOneTool(0x36);
if (mf > 0) ShutDownTCP(mf, false, printCallBack);
// flush q
@ -405,9 +319,9 @@ _exit:
DisposeHandle(shdHandle);
DisposeHandle(shrHandle);
GrafOff();
screen_off();
TextShutDown();
QuitGS(&qDCB);
//QuitGS(&qDCB);
return 0;
}

94
screen.c Normal file
View File

@ -0,0 +1,94 @@
#include <types.h>
extern pascal void SetMasterSCB(Word) inline(0x1604,dispatcher);
extern pascal void SetAllSCBs(Word) inline(0x1404,dispatcher);
extern pascal void SetColorTable(Word, ColorTable) inline(0x0E04,dispatcher);
void ClearScreen(void);
void screen_init(void) {
#define WHITE 0x0fff
#define YELLOW 0x0ff0
#define BLACK 0x0000
#define BLUE 0x000f
#define GREEN 0x0080
#define RED 0x0f00
static ColorTable ct =
{
WHITE, // background
RED, // underline / blink
BLUE, // bold
GREEN, // foreground
WHITE,
RED,
BLUE,
GREEN,
WHITE,
RED,
BLUE,
GREEN,
WHITE,
RED,
BLUE,
GREEN,
};
unsigned i;
SetMasterSCB(0xc080);
SetAllSCBs(0xc080);
for (i = 0; i < 16; i++)
SetColorTable(i, ct);
ClearScreen();
// linearize memory, enable shadowing.
asm {
phb
pea 0xe0e0
plb
plb
sep #0x20
lda #0xC1
tsb 0xc029
lda #0x08
trb 0xc035
rep #0x20
plb
}
}
asm void screen_on(void) {
phb
pea 0xe0e0
plb
plb
sep #0x20
lda #0x80
tsb 0xc029
rep #0x20
plb
rtl
}
asm void screen_off(void) {
phb
pea 0xe0e0
plb
plb
sep #0x20
lda #0x80
trb 0xc029
rep #0x20
plb
rtl
}