From 12032fe800b1108687bc0afe657660a4e2e595eb Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 10 May 2018 21:06:58 -0400 Subject: [PATCH] cleanup. --- GNUmakefile | 8 +-- darlene.c | 189 +++++++++++++++++++++++++++++++++++++++++++++------- marinetti.c | 72 ++++++++++++++++++-- marinetti.h | 145 ++++------------------------------------ marlene.c | 162 +++++++++++--------------------------------- screen.c | 94 ++++++++++++++++++++++++++ 6 files changed, 383 insertions(+), 287 deletions(-) create mode 100644 screen.c diff --git a/GNUmakefile b/GNUmakefile index 3fbd15c..ee2c059 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -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 diff --git a/darlene.c b/darlene.c index 87f895d..b4b311c 100644 --- a/darlene.c +++ b/darlene.c @@ -3,20 +3,55 @@ * */ -#include -#include #include -#include +#include #include #include +#include - -#include +#include +#include +#include +#include #include -#include +#include #include -#include +#include #include +#include +#include + +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; } \ No newline at end of file diff --git a/marinetti.c b/marinetti.c index abb6836..b7dae12 100644 --- a/marinetti.c +++ b/marinetti.c @@ -2,7 +2,10 @@ #pragma lint -1 #include -#include "Marinetti.h" +#include +#include + +#include "marinetti.h" #include #include @@ -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); + } +} diff --git a/marinetti.h b/marinetti.h index dfb9ce5..68b422d 100644 --- a/marinetti.h +++ b/marinetti.h @@ -1,139 +1,22 @@ -#ifndef __TCPIP_H__ -#define __TCPIP_H__ +#ifndef __marinetti_h__ +#define __marinetti_h__ #include -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 diff --git a/marlene.c b/marlene.c index aa54412..7846166 100644 --- a/marlene.c +++ b/marlene.c @@ -1,28 +1,27 @@ -#include +#include +#include #include #include +#include #include -#include -#include -#include -#include + +#include #include +#include #include #include -#include -#include +#include #include -#include -#include - #include -#include #include +#include +#include +#include +#include #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; } diff --git a/screen.c b/screen.c new file mode 100644 index 0000000..317bd10 --- /dev/null +++ b/screen.c @@ -0,0 +1,94 @@ + +#include + + +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 +} \ No newline at end of file