Compare commits
19 Commits
Author | SHA1 | Date |
---|---|---|
Kelvin Sherlock | 4da75367c1 | |
Kelvin Sherlock | d77291a0c0 | |
Kelvin Sherlock | d3addc3050 | |
Kelvin Sherlock | 2079d4b442 | |
Kelvin Sherlock | 58ab674589 | |
Kelvin Sherlock | 5c0764e5b9 | |
Kelvin Sherlock | 58e63dc252 | |
Kelvin Sherlock | b838f724d8 | |
Kelvin Sherlock | bcc69350e1 | |
Kelvin Sherlock | c46aadf52d | |
Kelvin Sherlock | d2e0554bc8 | |
Kelvin Sherlock | 3f0a195014 | |
Kelvin Sherlock | 12032fe800 | |
Kelvin Sherlock | 517dfd3ad6 | |
Kelvin Sherlock | 77be11f696 | |
Kelvin Sherlock | db779e12e6 | |
Kelvin Sherlock | 246c8a8464 | |
Kelvin Sherlock | e82452f216 | |
Kelvin Sherlock | 3cd69c8e8b |
32
GNUmakefile
32
GNUmakefile
|
@ -1,5 +1,7 @@
|
|||
PROG = marlene
|
||||
OBJS = o/main.a o/vt100.a o/telnet.a o/ansi.a o/chars.a o/marinetti.a o/display.a
|
||||
COMMON_OBJS = o/vt100.a o/ansi.a o/chars.a o/display.a o/screen.a
|
||||
|
||||
MARLENE_OBJS = o/marlene.a o/telnet.a o/marinetti.a
|
||||
DARLENE_OBJS = o/darlene.a
|
||||
|
||||
CC = occ --gno
|
||||
|
||||
|
@ -8,18 +10,27 @@ OPTIMIZE ?= 79
|
|||
CFLAGS = -w-1 -O $(OPTIMIZE)
|
||||
ASMFLAGS =
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(RM) o/ansi.root
|
||||
$(RM) o/chars.root
|
||||
$(CC) $(OBJS) -o $@
|
||||
.PHONY: all clean clobber
|
||||
|
||||
all: marlene darlene
|
||||
|
||||
marlene: $(MARLENE_OBJS) $(COMMON_OBJS)
|
||||
$(CC) -o $@ $^
|
||||
|
||||
darlene: $(DARLENE_OBJS) $(COMMON_OBJS)
|
||||
$(CC) -lutil -o $@ $^
|
||||
# iix chtyp -a 0xdc00 $@
|
||||
|
||||
|
||||
main.o: main.c
|
||||
|
||||
marlene.o: marlene.c
|
||||
darlene.o: darlene.c
|
||||
vt100.o: vt100.c CLAGS+=-r
|
||||
ansi.o: ansi.asm
|
||||
chars.o: chars.asm
|
||||
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
|
||||
|
||||
o :
|
||||
mkdir o
|
||||
|
@ -29,9 +40,10 @@ o/%.a : %.c | o
|
|||
|
||||
o/%.a : %.asm | o
|
||||
$(CC) -c $(ASMFLAGS) -o $@ $^
|
||||
$(RM) o/$*.root
|
||||
|
||||
|
||||
clean:
|
||||
$(RM) -rf o
|
||||
clobber: clean
|
||||
$(RM) -f $(PROG)
|
||||
$(RM) -f marlene darlene
|
||||
|
|
137
ansi.asm
137
ansi.asm
|
@ -1,8 +1,14 @@
|
|||
case on
|
||||
mcopy ansi.mac
|
||||
|
||||
dummy start
|
||||
end
|
||||
|
||||
RDMAINRAM gequ $E0C002 ; Read from main memory
|
||||
RDCARDRAM gequ $E0C003 ; Read from auxiliary memory
|
||||
WRMAINRAM gequ $E0C004 ; Write to main memory
|
||||
WRCARDRAM gequ $E0C005 ; Write to auxiliary memory
|
||||
|
||||
tables privdata
|
||||
|
||||
;
|
||||
|
@ -641,6 +647,137 @@ exit anop
|
|||
end
|
||||
|
||||
|
||||
; FillChar(char, andMask, xorMask)
|
||||
gen on
|
||||
FillChar START
|
||||
|
||||
using tables
|
||||
|
||||
subroutine (2:char,2:andMask,2:xorMask),(16:cdata)
|
||||
|
||||
xx equ andMask
|
||||
yy equ xorMask
|
||||
|
||||
lda <char
|
||||
cmp #$7f
|
||||
bcs space
|
||||
sec
|
||||
sbc #$20
|
||||
bmi space
|
||||
asl a ; x2
|
||||
asl a ; x4
|
||||
asl a ; x8
|
||||
asl a ; x16
|
||||
tax
|
||||
bra ok
|
||||
|
||||
|
||||
space anop
|
||||
ldx #0 ; char
|
||||
|
||||
ok anop
|
||||
|
||||
; pre-calc the char mask to data.
|
||||
|
||||
lda CHAR_SPACE,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata
|
||||
|
||||
lda CHAR_SPACE+2,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+2
|
||||
|
||||
lda CHAR_SPACE+4,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+4
|
||||
|
||||
lda CHAR_SPACE+6,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+6
|
||||
|
||||
lda CHAR_SPACE+8,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+8
|
||||
|
||||
lda CHAR_SPACE+10,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+10
|
||||
|
||||
lda CHAR_SPACE+12,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+12
|
||||
|
||||
lda CHAR_SPACE+14,x
|
||||
eor <xorMask
|
||||
and <andMask
|
||||
sta cdata+14
|
||||
|
||||
|
||||
pea $e1e1
|
||||
plb
|
||||
plb
|
||||
|
||||
|
||||
lda #24
|
||||
sta yy
|
||||
|
||||
ldx #0*8*160+4*160+$2000
|
||||
yloop anop
|
||||
|
||||
lda cdata+0
|
||||
jsr one_line
|
||||
|
||||
lda cdata+2
|
||||
jsr one_line
|
||||
|
||||
lda cdata+4
|
||||
jsr one_line
|
||||
|
||||
lda cdata+6
|
||||
jsr one_line
|
||||
|
||||
lda cdata+8
|
||||
jsr one_line
|
||||
|
||||
lda cdata+10
|
||||
jsr one_line
|
||||
|
||||
lda cdata+12
|
||||
jsr one_line
|
||||
|
||||
lda cdata+14
|
||||
jsr one_line
|
||||
|
||||
dec yy
|
||||
bne yloop
|
||||
|
||||
exit anop
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
one_line private
|
||||
; a = character data
|
||||
; x = memory address
|
||||
|
||||
ldy #80
|
||||
loop anop
|
||||
sta |$0000,x
|
||||
inx
|
||||
inx
|
||||
dey
|
||||
bne loop
|
||||
rts
|
||||
end
|
||||
|
||||
HideCursor start
|
||||
using cursor_data
|
||||
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
macro
|
||||
&l _ldy &r
|
||||
&l anop
|
||||
aif "&r"="@a",.a
|
||||
aif "&r"="@x",.x
|
||||
aif "&r"="@y",.y
|
||||
ldy &r
|
||||
ago .y
|
||||
.a
|
||||
tay
|
||||
ago .y
|
||||
.x
|
||||
txy
|
||||
ago .y
|
||||
.y
|
||||
mend
|
||||
macro
|
||||
&l subroutine &parms,&locals
|
||||
&l anop
|
||||
gbla &totallen
|
||||
gbla &worklen
|
||||
gbla &returnlen
|
||||
&worklen seta 0
|
||||
&totallen seta 0
|
||||
&returnlen seta 4
|
||||
lclc &len
|
||||
lclc &p
|
||||
lcla &i
|
||||
|
||||
phb
|
||||
|
||||
aif c:&locals=0,.doparms
|
||||
.dolocals
|
||||
&i seta 1
|
||||
.bb
|
||||
&p setc &locals(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.cc
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .dd
|
||||
.cc
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.dd
|
||||
&p equ &worklen+1
|
||||
&worklen seta &worklen+&len
|
||||
&i seta &i+1
|
||||
aif &i<=c:&locals,^bb
|
||||
.doparms
|
||||
|
||||
aif c:&parms=0,.e
|
||||
&i seta 1
|
||||
.b
|
||||
&p setc &parms(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.c
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .d
|
||||
.c
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.d
|
||||
&p equ &totallen+&returnlen+1+&worklen
|
||||
&totallen seta &totallen+&len
|
||||
&i seta &i+1
|
||||
aif &i<=c:&parms,^b
|
||||
.e
|
||||
tsc
|
||||
aif &worklen=0,.f
|
||||
sec
|
||||
sbc #&worklen
|
||||
tcs
|
||||
.f
|
||||
phd
|
||||
tcd
|
||||
mend
|
||||
|
||||
|
||||
macro
|
||||
&l lsubroutine &parms,&locals
|
||||
&l anop
|
||||
gbla &totallen
|
||||
gbla &worklen
|
||||
gbla &returnlen
|
||||
&worklen seta 0
|
||||
&totallen seta 0
|
||||
&returnlen seta 2
|
||||
lclc &len
|
||||
lclc &p
|
||||
lcla &i
|
||||
|
||||
aif c:&locals=0,.doparms
|
||||
.dolocals
|
||||
&i seta 1
|
||||
.bb
|
||||
&p setc &locals(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.cc
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .dd
|
||||
.cc
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.dd
|
||||
&p equ &worklen+1
|
||||
&worklen seta &worklen+&len
|
||||
&i seta &i+1
|
||||
aif &i<=c:&locals,^bb
|
||||
.doparms
|
||||
aif c:&parms=0,.e
|
||||
&i seta 1
|
||||
.b
|
||||
&p setc &parms(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.c
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .d
|
||||
.c
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.d
|
||||
&p equ &totallen+&return+1+&worklen
|
||||
&totallen seta &totallen+&len
|
||||
&i seta &i+1
|
||||
aif &i<=c:&parms,^b
|
||||
.e
|
||||
tsc
|
||||
aif &worklen=0,.f
|
||||
sec
|
||||
sbc #&worklen
|
||||
tcs
|
||||
.f
|
||||
phd
|
||||
tcd
|
||||
mend
|
||||
|
||||
macro
|
||||
&l return &r
|
||||
&l anop
|
||||
lclc &len
|
||||
aif c:&r,.a
|
||||
lclc &r
|
||||
&r setc 0
|
||||
&len setc 0
|
||||
ago .h
|
||||
.a
|
||||
&len amid &r,2,1
|
||||
aif "&len"=":",.b
|
||||
&len amid &r,1,2
|
||||
&r amid &r,4,l:&r-3
|
||||
ago .c
|
||||
.b
|
||||
&len amid &r,1,1
|
||||
&r amid &r,3,l:&r-2
|
||||
.c
|
||||
aif &len<>2,.d
|
||||
_ldy &r
|
||||
ago .h
|
||||
.d
|
||||
aif &len<>4,.e
|
||||
ldx &r+2
|
||||
ldy &r
|
||||
ago .h
|
||||
.e
|
||||
aif &len<>10,.g
|
||||
ldy #&r
|
||||
ldx #^&r
|
||||
ago .h
|
||||
.g
|
||||
mnote 'Not a valid return length',16
|
||||
mexit
|
||||
.h
|
||||
aif &totallen=0,.i
|
||||
lda &worklen+3
|
||||
sta &worklen+&totallen+3
|
||||
lda &worklen+1
|
||||
sta &worklen+&totallen+1
|
||||
.i
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #&worklen+&totallen
|
||||
tcs
|
||||
aif &len=0,.j
|
||||
tya
|
||||
.j
|
||||
plb
|
||||
rtl
|
||||
mend
|
||||
|
||||
macro
|
||||
&l lreturn &r
|
||||
&l anop
|
||||
lclc &len
|
||||
aif c:&r,.a
|
||||
lclc &r
|
||||
&r setc 0
|
||||
&len setc 0
|
||||
ago .h
|
||||
.a
|
||||
&len amid &r,2,1
|
||||
aif "&len"=":",.b
|
||||
&len amid &r,1,2
|
||||
&r amid &r,4,l:&r-3
|
||||
ago .c
|
||||
.b
|
||||
&len amid &r,1,1
|
||||
&r amid &r,3,l:&r-2
|
||||
.c
|
||||
aif &len<>2,.d
|
||||
_ldy &r
|
||||
ago .h
|
||||
.d
|
||||
aif &len<>4,.e
|
||||
ldx &r+2
|
||||
ldy &r
|
||||
ago .h
|
||||
.e
|
||||
aif &len<>10,.g
|
||||
ldy #&r
|
||||
ldx #^&r
|
||||
ago .h
|
||||
.g
|
||||
mnote 'Not a valid return length',16
|
||||
mexit
|
||||
.h
|
||||
aif &totallen=0,.i
|
||||
lda &worklen+1
|
||||
sta &worklen+&totallen+1
|
||||
.i
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #&worklen+&totallen
|
||||
tcs
|
||||
aif &len=0,.j
|
||||
tya
|
||||
.j
|
||||
rts
|
||||
mend
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* The original concept. Not the original code :)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Event.h>
|
||||
#include <gsos.h>
|
||||
#include <Locator.h>
|
||||
#include <Memory.h>
|
||||
#include <shell.h>
|
||||
#include <texttool.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libutil.h>
|
||||
#include <sgtty.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.compat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <gno/gno.h>
|
||||
#include <gno/kerntool.h>
|
||||
|
||||
#include "vt100.h"
|
||||
|
||||
extern void screen_init(void);
|
||||
extern void screen_on(void);
|
||||
extern void screen_off(void);
|
||||
|
||||
void display_pstr(const char *);
|
||||
void display_cstr(const char *);
|
||||
|
||||
|
||||
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
|
||||
openpty2(int *amaster, int *aslave, char *name, struct sgttyb *sg, struct winsize *winp) {
|
||||
|
||||
char ptyname[] = ".ptyq0";
|
||||
char ttyname[] = ".ttyq0";
|
||||
|
||||
int master;
|
||||
int slave;
|
||||
unsigned i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
char c = "0123456789abcdef"[i];
|
||||
ptyname[5] = c;
|
||||
ttyname[5] = c;
|
||||
master = open(ptyname, O_RDWR);
|
||||
if (master < 0) continue;
|
||||
|
||||
slave = open(ttyname, O_RDWR);
|
||||
if (slave < 0) {
|
||||
close(master);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
*amaster = master;
|
||||
*aslave = slave;
|
||||
|
||||
if (name) strcpy(name, ttyname);
|
||||
if (sg) stty(slave, sg);
|
||||
if (winp) ioctl(slave, TIOCSWINSZ, (char *)winp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define _write(fd, msg) write(fd, msg, sizeof(msg) - 1);
|
||||
|
||||
static SetGSPB term_var = {
|
||||
3, "\x04\x00TERM", "\x05\x00vt100", 1
|
||||
};
|
||||
|
||||
static char **child_argv = NULL;
|
||||
static struct passwd *pwd = NULL;
|
||||
static char *whoami = "";
|
||||
#pragma databank 1
|
||||
static int _child(int master, int slave) {
|
||||
|
||||
static unsigned zero = 0;
|
||||
int ok;
|
||||
close(master);
|
||||
|
||||
|
||||
ok = login_tty(slave);
|
||||
if (ok < 0) {
|
||||
_write(slave, "login_tty failed.\r\n");
|
||||
close(slave);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* work around GNO bug where environment leaks into parent */
|
||||
PushVariablesGS(&zero);
|
||||
|
||||
SetGS(&term_var);
|
||||
|
||||
if (child_argv) {
|
||||
execvp(child_argv[0], child_argv);
|
||||
} else {
|
||||
static char buffer[64] = "login -f ";
|
||||
strcpy(buffer + 9, whoami);
|
||||
/* should sniff the correct TERM value from /etc/ttys */
|
||||
_execve(":usr:bin:login", buffer);
|
||||
_execve(":usr:sbin:login", buffer);
|
||||
_execve(":bin:gsh", "gsh");
|
||||
}
|
||||
|
||||
_write(STDERR_FILENO, "_execve failed.\r\n");
|
||||
return 1;
|
||||
}
|
||||
#undef _write
|
||||
#pragma databank 0
|
||||
|
||||
int
|
||||
forkpty2(int *amaster, char *name, struct sgttyb *sg, struct winsize *winp) {
|
||||
|
||||
int ok;
|
||||
int master, slave, pid;
|
||||
|
||||
ok = openpty2(&master, &slave, name, sg, winp);
|
||||
if (ok < 0) return -1;
|
||||
|
||||
pid = fork2(_child, 512, 0, "darlene child", 2, master, slave);
|
||||
if (pid < 0) {
|
||||
close(master);
|
||||
close(slave);
|
||||
return -1;
|
||||
}
|
||||
*amaster = master;
|
||||
close(slave);
|
||||
return pid;
|
||||
}
|
||||
|
||||
#pragma databank 1
|
||||
static void sigchild(int sig, int x) {
|
||||
//display_cstr("\r\nsigchild\r\n");
|
||||
|
||||
PostEvent(app4Evt,0);
|
||||
}
|
||||
#pragma databank 0
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
static EventRecord event;
|
||||
|
||||
int pid;
|
||||
unsigned i;
|
||||
Word MyID;
|
||||
unsigned vt100_flags = vtDEFAULT;
|
||||
Handle dpHandle = NULL;
|
||||
Handle shrHandle = NULL;
|
||||
Handle shdHandle = NULL;
|
||||
|
||||
master = -1;
|
||||
kernStatus();
|
||||
if (_toolErr) {
|
||||
ErrWriteCString("GNO/ME required.\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!isatty(STDIN_FILENO)) {
|
||||
ErrWriteCString("stdin required.\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
term_var.value = "\x05\x00vt100";
|
||||
child_argv = NULL;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
char *cp = argv[i];
|
||||
if (cp[0] != '-') break;
|
||||
if (strcmp(cp, "--") == 0) {
|
||||
break;
|
||||
} else if (strcmp(cp, "--vt52") == 0) {
|
||||
term_var.value = "\x04\x00vt52";
|
||||
vt100_flags &= ~vtDECANM;
|
||||
} else if (strcmp(cp, "--vt100") == 0) {
|
||||
term_var.value = "\x05\x00vt100";
|
||||
vt100_flags |= vtDECANM;
|
||||
} else {
|
||||
ErrWriteCString("Unknown option: ");
|
||||
ErrWriteCString(cp);
|
||||
ErrWriteCString("\r\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= i;
|
||||
argv += i;
|
||||
|
||||
if (argc) {
|
||||
child_argv = malloc(argc * 4 + 4);
|
||||
/* <= argc so trailing NULL copies */
|
||||
for(i = 0; i <= argc; ++i) child_argv[i] = argv[i];
|
||||
}
|
||||
|
||||
pwd = getpwuid(getuid());
|
||||
whoami = pwd ? pwd->pw_name : "";
|
||||
|
||||
MyID = MMStartUp();
|
||||
|
||||
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(vt100_flags);
|
||||
|
||||
signal(SIGCHLD,sigchild);
|
||||
pid = forkpty2(&master, NULL, NULL, NULL);
|
||||
if ( pid < 0) {
|
||||
display_cstr("Unable to forkpty.\r\n");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* reset the controlling terminal, which was clobbered by opening a pty */
|
||||
/* standard TIOCSCTTY causes ORCA/C shift errors */
|
||||
#undef TIOCSCTTY
|
||||
#define TIOCSCTTY (0x20000000ul | ('t' << 8) | 97)
|
||||
ioctl(STDIN_FILENO, TIOCSCTTY, (void *)0);
|
||||
|
||||
|
||||
for(;;) {
|
||||
static char buffer[1024];
|
||||
int fio = 0;
|
||||
int ok;
|
||||
ok = ioctl(master, FIONREAD, &fio);
|
||||
if (fio > sizeof(buffer)) fio = sizeof(buffer);
|
||||
if (fio > 0) {
|
||||
fio = read(master, buffer, fio);
|
||||
if (fio > 0) vt100_process(buffer, fio);
|
||||
}
|
||||
|
||||
if (GetNextEvent(everyEvent, &event)) {
|
||||
fio = 1;
|
||||
if (event.what == keyDownEvt) {
|
||||
|
||||
unsigned char key = event.message;
|
||||
|
||||
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 == app4Evt) {
|
||||
/* child signal received! */
|
||||
union wait wt;
|
||||
ok = waitpid(pid, &wt, WNOHANG);
|
||||
if (ok <= 0) continue;
|
||||
display_cstr("\r\nChild exited.\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
flush();
|
||||
if (fio <= 0) asm { cop 0x7f }
|
||||
}
|
||||
_exit1:
|
||||
flush();
|
||||
if (master > 0) close(master);
|
||||
|
||||
_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;
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <string.h>
|
||||
#include "Marinetti.h"
|
||||
|
||||
|
||||
struct errlist {
|
||||
Word Error;
|
||||
Word MsgLen;
|
||||
unsigned Error;
|
||||
unsigned MsgLen;
|
||||
const char *Msg;
|
||||
};
|
||||
|
||||
|
@ -32,7 +30,7 @@ static struct errlist errors[] = {
|
|||
_ERR(0x0e,"tcperrConRefused"),
|
||||
};
|
||||
|
||||
void display_err(Word err) {
|
||||
void display_err(unsigned err) {
|
||||
|
||||
if (err == 0 || err >= 0x0f) return;
|
||||
--err;
|
||||
|
|
5
makefile
5
makefile
|
@ -1,5 +1,5 @@
|
|||
PROG = marlene
|
||||
OBJS = main.o vt100.o telnet.o ansi.o chars.o marinetti.o display.o
|
||||
OBJS = marlene.o vt100.o telnet.o ansi.o chars.o marinetti.o display.o
|
||||
|
||||
OPTIMIZE *= 79
|
||||
|
||||
|
@ -11,7 +11,8 @@ $(PROG): $(OBJS)
|
|||
$(CC) $(CFLAGS) $(OBJS) -o $@
|
||||
|
||||
|
||||
main.o: main.c
|
||||
marlene.o: marlene.c
|
||||
darlene.o: darlene.c
|
||||
vt100.o: vt100.c
|
||||
ansi.o: ansi.asm
|
||||
chars.o: chars.asm
|
||||
|
|
72
marinetti.c
72
marinetti.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
145
marinetti.h
145
marinetti.h
|
@ -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
|
||||
|
||||
|
|
|
@ -1,42 +1,28 @@
|
|||
#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);
|
||||
|
||||
extern pascal void GrafOn(void) inline(0x0a04, dispatcher);
|
||||
extern pascal void GrafOff(void) inline(0x0b04, dispatcher);
|
||||
|
||||
extern pascal void SetColorTable(Word, ColorTable) inline(0x0E04,dispatcher);
|
||||
extern pascal void SysBeep2(Word) inline(0x3803,dispatcher);
|
||||
extern pascal void SetAllSCBs(Word) inline(0x1404,dispatcher);
|
||||
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);
|
||||
|
||||
#include "marinetti.h"
|
||||
#include "vt100.h"
|
||||
|
||||
void display_pstr(const char *);
|
||||
void display_cstr(const char *);
|
||||
|
@ -45,21 +31,15 @@ void display_err(Word);
|
|||
extern void telnet_init(void);
|
||||
extern void telnet_process(void);
|
||||
|
||||
extern void vt100_init(void);
|
||||
extern void vt100_process(const unsigned char *buffer, unsigned buffer_size);
|
||||
extern void vt100_event(EventRecord *event);
|
||||
|
||||
|
||||
|
||||
|
||||
Word MyID;
|
||||
Word __gno;
|
||||
extern void screen_init(void);
|
||||
extern void screen_on(void);
|
||||
extern void screen_off(void);
|
||||
|
||||
|
||||
#define ESC "\x1b"
|
||||
|
||||
|
||||
|
||||
#pragma databank 1
|
||||
|
||||
/*
|
||||
|
@ -76,64 +56,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, disable shadowing.
|
||||
asm
|
||||
{
|
||||
phb
|
||||
pea 0xe0e0
|
||||
plb
|
||||
plb
|
||||
sep #0x20
|
||||
lda #0xC1
|
||||
tsb 0xc029
|
||||
lda #0x08
|
||||
tsb 0xc035
|
||||
rep #0x20
|
||||
plb
|
||||
}
|
||||
|
||||
SetMasterSCB(0xc080);
|
||||
SetAllSCBs(0xc080);
|
||||
//InitColorTable(ct);
|
||||
for (i = 0; i < 16; i++)
|
||||
SetColorTable(i, ct);
|
||||
|
||||
ClearScreen();
|
||||
GrafOn();
|
||||
}
|
||||
|
||||
static char out_buffer[1024];
|
||||
static char out_buffer_size = 0;
|
||||
|
@ -167,6 +90,8 @@ unsigned buffer_size;
|
|||
unsigned char buffer[2048]; // 1500 is normal MTU size?
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
static EventRecord event;
|
||||
|
@ -176,78 +101,93 @@ int main(int argc, char **argv) {
|
|||
static QuitRecGS qDCB = {2, 0, 0x4000};
|
||||
|
||||
|
||||
Word iLoaded;
|
||||
Word iConnected;
|
||||
Word iStarted;
|
||||
Handle dp;
|
||||
|
||||
Handle dpHandle = NULL;
|
||||
Handle shrHandle = NULL;
|
||||
Handle shdHandle = NULL;
|
||||
Word err;
|
||||
int ok;
|
||||
unsigned i;
|
||||
int mf = 0;
|
||||
Word MyID;
|
||||
Word __gno;
|
||||
unsigned vt100_flags = vtDEFAULT;
|
||||
|
||||
|
||||
iLoaded = iStarted = iConnected = false;
|
||||
__gno = false;
|
||||
ipid = -1;
|
||||
|
||||
MyID = MMStartUp();
|
||||
|
||||
kernStatus();
|
||||
if (!_toolErr) __gno = true;
|
||||
|
||||
TextStartUp();
|
||||
SetOutputDevice(1,3);
|
||||
SetOutGlobals(0x7f, 0);
|
||||
|
||||
kernStatus();
|
||||
if (!_toolErr) __gno = true;
|
||||
|
||||
dp = NewHandle(0x0100, MyID,
|
||||
|
||||
// todo:keypad flag of some sort?
|
||||
for (i = 1; i < argc; ++i) {
|
||||
char *cp = argv[i];
|
||||
if (cp[0] != '-') break;
|
||||
if (strcmp(cp, "--") == 0) {
|
||||
break;
|
||||
} else if (strcmp(cp, "--vt52") == 0) {
|
||||
vt100_flags &= ~vtDECANM;
|
||||
} else if (strcmp(cp, "--vt100") == 0) {
|
||||
vt100_flags |= vtDECANM;
|
||||
} else {
|
||||
ErrWriteCString("Unknown option: ");
|
||||
ErrWriteCString(cp);
|
||||
ErrWriteCString("\r\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
argv += i;
|
||||
argc -= i;
|
||||
|
||||
if (argc != 1) {
|
||||
ErrWriteCString("Usage: marlene host[:port]\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dpHandle = NewHandle(0x0100, MyID,
|
||||
attrBank | attrPage |attrNoCross | attrFixed | attrLocked,
|
||||
0x000000);
|
||||
EMStartUp((Word)*dp, 0x14, 0, 0, 0, 0, MyID);
|
||||
|
||||
shdHandle = NewHandle(0x8000, MyID,
|
||||
attrAddr | attrFixed | attrLocked,
|
||||
(void *)0x012000);
|
||||
|
||||
// todo: -vt52 -> start in vt52 mode (DECANM = 0)
|
||||
// todo:keypad flag of some sort?
|
||||
shrHandle = NewHandle(0x8000, MyID,
|
||||
attrAddr | attrFixed | attrLocked,
|
||||
(void *)0xe12000);
|
||||
|
||||
if (argc != 2) {
|
||||
ErrWriteCString("Usage: marlene host[:port]\r\n");
|
||||
goto _exit;
|
||||
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();
|
||||
vt100_init(vt100_flags);
|
||||
|
||||
|
||||
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[1], &cvt)) {
|
||||
if (!ResolveHost(argv[0], &cvt)) {
|
||||
display_cstr("Unable to resolve address.\r\n");
|
||||
goto _exit;
|
||||
}
|
||||
|
@ -266,15 +206,13 @@ 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");
|
||||
|
||||
telnet_init();
|
||||
|
||||
//fd = open ("tcp.log", O_TRUNC | O_WRONLY | O_CREAT, 0777);
|
||||
|
||||
for(;;) {
|
||||
static rrBuff rr;
|
||||
|
||||
|
@ -302,7 +240,7 @@ int main(int argc, char **argv) {
|
|||
vt100_process(buffer, buffer_size);
|
||||
}
|
||||
|
||||
GetNextEvent(keyDownMask | autoKeyMask, &event);
|
||||
GetNextEvent(everyEvent, &event);
|
||||
if (event.what == keyDownEvt) {
|
||||
|
||||
unsigned char key = event.message;
|
||||
|
@ -320,15 +258,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;
|
||||
}
|
||||
|
@ -348,34 +285,28 @@ _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
|
||||
while (GetNextEvent(keyDownMask | autoKeyMask, &event)) ;
|
||||
FlushEvents(everyEvent, 0);
|
||||
display_cstr("\n\rPress any key to exit.\n\r");
|
||||
while (!GetNextEvent(keyDownMask | autoKeyMask, &event)) ;
|
||||
|
||||
|
||||
EMShutDown();
|
||||
DisposeHandle(dp);
|
||||
GrafOff();
|
||||
DisposeHandle(dpHandle);
|
||||
DisposeHandle(shdHandle);
|
||||
DisposeHandle(shrHandle);
|
||||
|
||||
screen_off();
|
||||
TextShutDown();
|
||||
QuitGS(&qDCB);
|
||||
//QuitGS(&qDCB);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
10
telnet.c
10
telnet.c
|
@ -108,12 +108,16 @@ void telnet_process(void) {
|
|||
IAC, SE
|
||||
};
|
||||
|
||||
static unsigned char telopt_ttype[] = {
|
||||
static unsigned char telopt_ttype_vt100[] = {
|
||||
IAC, SB, TELOPT_TTYPE, TELQUAL_IS,
|
||||
'V', 'T', '1', '0', '0',
|
||||
IAC, SE
|
||||
};
|
||||
|
||||
static unsigned char telopt_ttype_vt52[] = {
|
||||
IAC, SB, TELOPT_TTYPE, TELQUAL_IS,
|
||||
'V', 'T', '5', '2',
|
||||
IAC, SE
|
||||
};
|
||||
|
||||
|
||||
/* don't need to process if no state, no IACs in buffer */
|
||||
|
@ -186,7 +190,7 @@ void telnet_process(void) {
|
|||
send(telopt_tspeed, sizeof(telopt_tspeed));
|
||||
break;
|
||||
case TELOPT_TTYPE:
|
||||
send(telopt_ttype, sizeof(telopt_ttype));
|
||||
send(telopt_ttype_vt100, sizeof(telopt_ttype_vt100));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
292
telnet.h
292
telnet.h
|
@ -1,6 +1,43 @@
|
|||
#ifndef __TELNET_H__
|
||||
#define __TELNET_H__
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_TELNET_H_
|
||||
#define _ARPA_TELNET_H_
|
||||
|
||||
/*
|
||||
* Definitions for the TELNET protocol.
|
||||
*/
|
||||
#define IAC 255 /* interpret as command: */
|
||||
#define DONT 254 /* you are not to use option */
|
||||
#define DO 253 /* please, you use option */
|
||||
|
@ -24,9 +61,21 @@
|
|||
|
||||
#define SYNCH 242 /* for telfunc calls */
|
||||
|
||||
#ifdef TELCMDS
|
||||
const char *telcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR",
|
||||
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
|
||||
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *telcmds[];
|
||||
#endif
|
||||
|
||||
#define TELCMD_FIRST xEOF
|
||||
#define TELCMD_LAST IAC
|
||||
#define TELCMD_OK(x) ((x) <= TELCMD_LAST && (x) >= TELCMD_FIRST)
|
||||
#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
|
||||
(unsigned int)(x) >= TELCMD_FIRST)
|
||||
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
|
||||
|
||||
/* telnet options */
|
||||
|
@ -65,19 +114,232 @@
|
|||
#define TELOPT_TSPEED 32 /* terminal speed */
|
||||
#define TELOPT_LFLOW 33 /* remote flow control */
|
||||
#define TELOPT_LINEMODE 34 /* Linemode option */
|
||||
#define TELOPT_XDISPLOC 35
|
||||
#define TELOPT_OLD_ENVIRON 36
|
||||
#define TELOPT_AUTHENTICATION 37 /* authenticate */
|
||||
#define TELOPT_ENCRYPT 38 /* encryption */
|
||||
#define TELOPT_NEW_ENVIRON 39
|
||||
|
||||
#define TELOPT_XDISPLOC 35 /* X Display Location */
|
||||
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
|
||||
#define TELOPT_AUTHENTICATION 37/* Authenticate */
|
||||
#define TELOPT_ENCRYPT 38 /* Encryption option */
|
||||
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
|
||||
#define TELOPT_TN3270E 40 /* RFC2355 - TN3270 Enhancements */
|
||||
#define TELOPT_CHARSET 42 /* RFC2066 - Charset */
|
||||
#define TELOPT_COMPORT 44 /* RFC2217 - Com Port Control */
|
||||
#define TELOPT_KERMIT 47 /* RFC2840 - Kermit */
|
||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||
|
||||
#define TELQUAL_IS 0
|
||||
#define TELQUAL_SEND 1
|
||||
#define TELQUAL_INFO 2
|
||||
#define TELQUAL_REPLY 2
|
||||
#define TELQUAL_NAME 3
|
||||
|
||||
|
||||
#define NTELOPTS (1+TELOPT_KERMIT)
|
||||
#ifdef TELOPTS
|
||||
const char *telopts[NTELOPTS+1] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
|
||||
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
|
||||
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
|
||||
"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
|
||||
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
|
||||
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
|
||||
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
|
||||
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
|
||||
"ENCRYPT", "NEW-ENVIRON", "TN3270E", "XAUTH", "CHARSET",
|
||||
"RSP", "COM-PORT", "SLE", "STARTTLS", "KERMIT",
|
||||
0
|
||||
};
|
||||
#define TELOPT_FIRST TELOPT_BINARY
|
||||
#define TELOPT_LAST TELOPT_KERMIT
|
||||
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
|
||||
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
|
||||
#endif
|
||||
|
||||
/* sub-option qualifiers */
|
||||
#define TELQUAL_IS 0 /* option is... */
|
||||
#define TELQUAL_SEND 1 /* send option */
|
||||
#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
|
||||
#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
|
||||
#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
|
||||
|
||||
#define LFLOW_OFF 0 /* Disable remote flow control */
|
||||
#define LFLOW_ON 1 /* Enable remote flow control */
|
||||
#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
|
||||
#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
|
||||
|
||||
/*
|
||||
* LINEMODE suboptions
|
||||
*/
|
||||
|
||||
#define LM_MODE 1
|
||||
#define LM_FORWARDMASK 2
|
||||
#define LM_SLC 3
|
||||
|
||||
#define MODE_EDIT 0x01
|
||||
#define MODE_TRAPSIG 0x02
|
||||
#define MODE_ACK 0x04
|
||||
#define MODE_SOFT_TAB 0x08
|
||||
#define MODE_LIT_ECHO 0x10
|
||||
|
||||
#define MODE_MASK 0x1f
|
||||
|
||||
/* Not part of protocol, but needed to simplify things... */
|
||||
#define MODE_FLOW 0x0100
|
||||
#define MODE_ECHO 0x0200
|
||||
#define MODE_INBIN 0x0400
|
||||
#define MODE_OUTBIN 0x0800
|
||||
#define MODE_FORCE 0x1000
|
||||
|
||||
#define SLC_SYNCH 1
|
||||
#define SLC_BRK 2
|
||||
#define SLC_IP 3
|
||||
#define SLC_AO 4
|
||||
#define SLC_AYT 5
|
||||
#define SLC_EOR 6
|
||||
#define SLC_ABORT 7
|
||||
#define SLC_EOF 8
|
||||
#define SLC_SUSP 9
|
||||
#define SLC_EC 10
|
||||
#define SLC_EL 11
|
||||
#define SLC_EW 12
|
||||
#define SLC_RP 13
|
||||
#define SLC_LNEXT 14
|
||||
#define SLC_XON 15
|
||||
#define SLC_XOFF 16
|
||||
#define SLC_FORW1 17
|
||||
#define SLC_FORW2 18
|
||||
#define SLC_MCL 19
|
||||
#define SLC_MCR 20
|
||||
#define SLC_MCWL 21
|
||||
#define SLC_MCWR 22
|
||||
#define SLC_MCBOL 23
|
||||
#define SLC_MCEOL 24
|
||||
#define SLC_INSRT 25
|
||||
#define SLC_OVER 26
|
||||
#define SLC_ECR 27
|
||||
#define SLC_EWR 28
|
||||
#define SLC_EBOL 29
|
||||
#define SLC_EEOL 30
|
||||
|
||||
#define NSLC 30
|
||||
|
||||
/*
|
||||
* For backwards compatibility, we define SLC_NAMES to be the
|
||||
* list of names if SLC_NAMES is not defined.
|
||||
*/
|
||||
#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
|
||||
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
|
||||
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
|
||||
"MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
|
||||
"MCEOL", "INSRT", "OVER", "ECR", "EWR", \
|
||||
"EBOL", "EEOL", \
|
||||
0
|
||||
|
||||
#ifdef SLC_NAMES
|
||||
const char *slc_names[] = {
|
||||
SLC_NAMELIST
|
||||
};
|
||||
#else
|
||||
extern char *slc_names[];
|
||||
#define SLC_NAMES SLC_NAMELIST
|
||||
#endif
|
||||
|
||||
#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
|
||||
#define SLC_NAME(x) slc_names[x]
|
||||
|
||||
#define SLC_NOSUPPORT 0
|
||||
#define SLC_CANTCHANGE 1
|
||||
#define SLC_VARIABLE 2
|
||||
#define SLC_DEFAULT 3
|
||||
#define SLC_LEVELBITS 0x03
|
||||
|
||||
#define SLC_FUNC 0
|
||||
#define SLC_FLAGS 1
|
||||
#define SLC_VALUE 2
|
||||
|
||||
#define SLC_ACK 0x80
|
||||
#define SLC_FLUSHIN 0x40
|
||||
#define SLC_FLUSHOUT 0x20
|
||||
|
||||
#define OLD_ENV_VAR 1
|
||||
#define OLD_ENV_VALUE 0
|
||||
#define NEW_ENV_VAR 0
|
||||
#define NEW_ENV_VALUE 1
|
||||
#define ENV_ESC 2
|
||||
#define ENV_USERVAR 3
|
||||
|
||||
/*
|
||||
* AUTHENTICATION suboptions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Who is authenticating who ...
|
||||
*/
|
||||
#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
|
||||
#define AUTH_WHO_SERVER 1 /* Server authenticating client */
|
||||
#define AUTH_WHO_MASK 1
|
||||
|
||||
/*
|
||||
* amount of authentication done
|
||||
*/
|
||||
#define AUTH_HOW_ONE_WAY 0
|
||||
#define AUTH_HOW_MUTUAL 2
|
||||
#define AUTH_HOW_MASK 2
|
||||
|
||||
#define AUTHTYPE_NULL 0
|
||||
#define AUTHTYPE_KERBEROS_V4 1
|
||||
#define AUTHTYPE_KERBEROS_V5 2
|
||||
#define AUTHTYPE_SPX 3
|
||||
#define AUTHTYPE_MINK 4
|
||||
#define AUTHTYPE_SRA 6
|
||||
#define AUTHTYPE_CNT 7
|
||||
|
||||
#define AUTHTYPE_TEST 99
|
||||
|
||||
#ifdef AUTH_NAMES
|
||||
const char *authtype_names[] = {
|
||||
"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", NULL, "SRA",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *authtype_names[];
|
||||
#endif
|
||||
|
||||
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
|
||||
#define AUTHTYPE_NAME(x) authtype_names[x]
|
||||
|
||||
/*
|
||||
* ENCRYPTion suboptions
|
||||
*/
|
||||
#define ENCRYPT_IS 0 /* I pick encryption type ... */
|
||||
#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
|
||||
#define ENCRYPT_REPLY 2 /* Initial setup response */
|
||||
#define ENCRYPT_START 3 /* Am starting to send encrypted */
|
||||
#define ENCRYPT_END 4 /* Am ending encrypted */
|
||||
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
|
||||
#define ENCRYPT_REQEND 6 /* Request you end encrypting */
|
||||
#define ENCRYPT_ENC_KEYID 7
|
||||
#define ENCRYPT_DEC_KEYID 8
|
||||
#define ENCRYPT_CNT 9
|
||||
|
||||
#define ENCTYPE_ANY 0
|
||||
#define ENCTYPE_DES_CFB64 1
|
||||
#define ENCTYPE_DES_OFB64 2
|
||||
#define ENCTYPE_CNT 3
|
||||
|
||||
#ifdef ENCRYPT_NAMES
|
||||
const char *encrypt_names[] = {
|
||||
"IS", "SUPPORT", "REPLY", "START", "END",
|
||||
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
|
||||
0
|
||||
};
|
||||
const char *enctype_names[] = {
|
||||
"ANY", "DES_CFB64", "DES_OFB64",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *encrypt_names[];
|
||||
extern char *enctype_names[];
|
||||
#endif
|
||||
|
||||
|
||||
#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
|
||||
#define ENCRYPT_NAME(x) encrypt_names[x]
|
||||
|
||||
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
|
||||
#define ENCTYPE_NAME(x) enctype_names[x]
|
||||
|
||||
#endif /* !_TELNET_H_ */
|
||||
|
|
111
vt100.c
111
vt100.c
|
@ -2,11 +2,12 @@
|
|||
* This handles vt100 commands.
|
||||
*
|
||||
*/
|
||||
#pragma noroot
|
||||
|
||||
#include <Event.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "vt100.h"
|
||||
|
||||
#define ESC "\x1b"
|
||||
#define send_str(x) send((const unsigned char *)x, sizeof(x)-1)
|
||||
|
||||
|
@ -20,6 +21,7 @@ extern unsigned buffer_size;
|
|||
extern void ReverseScrollRegion(unsigned, unsigned);
|
||||
extern void ScrollRegion(unsigned, unsigned);
|
||||
extern void PrintChar(unsigned x, unsigned y, unsigned the_char, unsigned andMask, unsigned eorMask);
|
||||
extern void FillChar(unsigned the_char, unsigned andMask, unsigned eorMask);
|
||||
|
||||
extern void ClearScreen(void);
|
||||
extern void ClearScreen2(unsigned start, unsigned end);
|
||||
|
@ -63,8 +65,11 @@ static unsigned parm_count;
|
|||
static unsigned private;
|
||||
static unsigned state;
|
||||
|
||||
void vt100_init(void)
|
||||
static unsigned initial_state = vtDEFAULT;
|
||||
|
||||
void vt100_init(unsigned flags)
|
||||
{
|
||||
|
||||
__x = 0;
|
||||
__y = 0;
|
||||
saved_cursor[0] = 0;
|
||||
|
@ -74,20 +79,32 @@ void vt100_init(void)
|
|||
and_mask = 0xffff;
|
||||
xor_mask = 0x0000;
|
||||
|
||||
DECANM = 1;
|
||||
DECAWM = 1;
|
||||
DECCKM = 0;
|
||||
DECKPAM = 0;
|
||||
DECCOLM = 80;
|
||||
DECOM = 0;
|
||||
DECSCNM = 0;
|
||||
LNM = 0;
|
||||
initial_state = flags;
|
||||
if (flags == -1) {
|
||||
DECANM = 1;
|
||||
DECAWM = 1;
|
||||
DECCKM = 0;
|
||||
DECKPAM = 0;
|
||||
DECCOLM = 80;
|
||||
DECOM = 0;
|
||||
DECSCNM = 0;
|
||||
LNM = 0;
|
||||
} else {
|
||||
DECANM = flags & vtDECANM;
|
||||
DECAWM = flags & vtDECAWM;
|
||||
DECCKM = flags & vtDECCKM;
|
||||
DECKPAM = flags & vtDECKPAM;
|
||||
DECCOLM = flags & vtDECCOLM ? 132 : 80;
|
||||
DECOM = flags & vtDECOM;
|
||||
DECSCNM = flags & vtDECSCNM;
|
||||
LNM = flags & vtLNM;
|
||||
}
|
||||
|
||||
tabs[0] = 0x8080;
|
||||
tabs[1] = 0x8080;
|
||||
tabs[2] = 0x8080;
|
||||
tabs[3] = 0x8080;
|
||||
tabs[4] = 0x0080;
|
||||
tabs[0] = 0x0100;
|
||||
tabs[1] = 0x0101;
|
||||
tabs[2] = 0x0101;
|
||||
tabs[3] = 0x0101;
|
||||
tabs[4] = 0x0101;
|
||||
|
||||
parms[0] = 0;
|
||||
parm_count = 0;
|
||||
|
@ -170,15 +187,15 @@ static void cursor_position(void) {
|
|||
if (y) --y;
|
||||
if (x) --x;
|
||||
|
||||
__x = x;
|
||||
if (x >= 80) x = 79;
|
||||
if (DECOM) {
|
||||
__y = window[0] + y;
|
||||
if (__y > window[1]) __y = window[1];
|
||||
y = window[0] + y;
|
||||
if (y > window[1]) y = window[1];
|
||||
} else {
|
||||
__y = y;
|
||||
if (__y >= 24) __y = 23;
|
||||
if (y >= 24) y = 23;
|
||||
}
|
||||
__x = x;
|
||||
__y = y;
|
||||
}
|
||||
|
||||
static void cursor_position_vt52(void) {
|
||||
|
@ -338,7 +355,7 @@ static void clear_tabs(void) {
|
|||
tabs[chunk] &= ~mask;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 3:
|
||||
tabs[0] = 0;
|
||||
tabs[1] = 0;
|
||||
tabs[2] = 0;
|
||||
|
@ -521,7 +538,7 @@ void vt100_process(const unsigned char *buffer, unsigned buffer_size) {
|
|||
case '8': restore_cursor(); break;
|
||||
case '=': DECKPAM = 1; break;
|
||||
case '>': DECKPAM = 0; break;
|
||||
case 'c': vt100_init(); ClearScreen(); break;
|
||||
case 'c': vt100_init(initial_state); ClearScreen(); break;
|
||||
case '1': case '2': /* vt105 graphic stuff */ break;
|
||||
default:
|
||||
break;
|
||||
|
@ -531,6 +548,9 @@ void vt100_process(const unsigned char *buffer, unsigned buffer_size) {
|
|||
|
||||
case st_pound:
|
||||
/* #8 -> fill with Es */
|
||||
if (c == '8') {
|
||||
FillChar('E', 0xffff, 0x0000);
|
||||
}
|
||||
state = st_text; break;
|
||||
case st_lparen:
|
||||
case st_rparen:
|
||||
|
@ -548,6 +568,12 @@ void vt100_process(const unsigned char *buffer, unsigned buffer_size) {
|
|||
state = st_parm;
|
||||
break;
|
||||
}
|
||||
if (c == ';') {
|
||||
++parm_count;
|
||||
parms[parm_count] = 0;
|
||||
state = st_parm;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case st_lbracket2:
|
||||
lbracket2:
|
||||
|
@ -623,6 +649,39 @@ void vt100_process(const unsigned char *buffer, unsigned buffer_size) {
|
|||
ShowCursor(__x, __y);
|
||||
}
|
||||
|
||||
/* adb codes for extended keys. passed as-is with keypad bit set */
|
||||
/* nb - kegs gobbles up fkeys for his own use */
|
||||
enum {
|
||||
kVK_F17 = 0x40,
|
||||
kVK_VolumeUp = 0x48,
|
||||
kVK_VolumeDown = 0x49,
|
||||
kVK_Mute = 0x4A,
|
||||
kVK_F18 = 0x4F,
|
||||
kVK_F19 = 0x50,
|
||||
kVK_F20 = 0x5A,
|
||||
kVK_F5 = 0x60,
|
||||
kVK_F6 = 0x61,
|
||||
kVK_F7 = 0x62,
|
||||
kVK_F3 = 0x63,
|
||||
kVK_F8 = 0x64,
|
||||
kVK_F9 = 0x65,
|
||||
kVK_F11 = 0x67,
|
||||
kVK_F13 = 0x69,
|
||||
kVK_F16 = 0x6A,
|
||||
kVK_F14 = 0x6B,
|
||||
kVK_F10 = 0x6D,
|
||||
kVK_F12 = 0x6F,
|
||||
kVK_F15 = 0x71,
|
||||
kVK_Help = 0x72,
|
||||
kVK_Home = 0x73,
|
||||
kVK_PageUp = 0x74,
|
||||
kVK_ForwardDelete = 0x75,
|
||||
kVK_F4 = 0x76,
|
||||
kVK_End = 0x77,
|
||||
kVK_F2 = 0x78,
|
||||
kVK_PageDown = 0x79,
|
||||
kVK_F1 = 0x7A
|
||||
};
|
||||
|
||||
//
|
||||
// remap the iigs key to a vt100 code (if necessary) and send it out.
|
||||
|
@ -698,22 +757,22 @@ void vt100_event(EventRecord *event) {
|
|||
break;
|
||||
|
||||
|
||||
case 0x7a: // f1
|
||||
case kVK_F1: // f1
|
||||
if (DECANM) { cp = ESC "OP"; len = 3; }
|
||||
else { cp = ESC "P"; len = 2; }
|
||||
break;
|
||||
|
||||
case 0x78: // f2
|
||||
case kVK_F2: // f2
|
||||
if (DECANM) { cp = ESC "OQ"; len = 3; }
|
||||
else { cp = ESC "Q"; len = 2; }
|
||||
break;
|
||||
|
||||
case 0x63: // f3
|
||||
case kVK_F3: // f3
|
||||
if (DECANM) { cp = ESC "OR"; len = 3; }
|
||||
else { cp = ESC "R"; len = 2; }
|
||||
break;
|
||||
|
||||
case 0x76: // f4
|
||||
case kVK_F4: // f4
|
||||
if (DECANM) { cp = ESC "OS"; len = 3; }
|
||||
else { cp = ESC "S"; len = 2; }
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
#
|
||||
# some settings so gsh works better with vt100.
|
||||
# source vt100.gsh
|
||||
#
|
||||
set term=vt100
|
||||
bindkey backward-delete-char "^H"
|
||||
bindkey up-history "^[[A"
|
||||
bindkey down-history "^[[B"
|
||||
bindkey forward-char "^[[C"
|
||||
bindkey backward-char "^[[D"
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef vt100_h
|
||||
#define vt100_h
|
||||
|
||||
enum {
|
||||
vtDECCKM = 1 << 1, /* Cursor key */
|
||||
vtDECANM = 1 << 2, /* ANSI/VT52 */
|
||||
vtDECCOLM = 1 << 3, /* Column */
|
||||
vtDECSCNM = 1 << 4, /* Screen */
|
||||
vtDECOM = 1 << 6, /* Origin */
|
||||
vtDECAWM = 1 << 7, /* Auto wrap */
|
||||
vtDECKPAM = 1 << 8, /* Keypad Application Mode */
|
||||
vtLNM = 1 << 9, /* Line Feed/New Line Mode */
|
||||
vtDEFAULT = vtDECANM | vtDECAWM,
|
||||
};
|
||||
|
||||
void vt100_init(unsigned flags);
|
||||
extern void vt100_process(const unsigned char *buffer, unsigned buffer_size);
|
||||
extern void vt100_event(struct EventRecord *event);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue