plato: Add the plato term hacks
authorAlan Cox <alan@linux.intel.com>
Fri, 7 Sep 2018 18:34:04 +0000 (19:34 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 7 Sep 2018 18:34:04 +0000 (19:34 +0100)
It's currently set up for a giant ascii vt100 console and directly codes
the irata.online address.

Very much a beginning

28 files changed:
Applications/plato/Makefile.z80 [new file with mode: 0644]
Applications/plato/NOTES [new file with mode: 0644]
Applications/plato/fuzix/font.c [new file with mode: 0644]
Applications/plato/fuzix/io.c [new file with mode: 0644]
Applications/plato/fuzix/keyboard.c [new file with mode: 0644]
Applications/plato/fuzix/scale.c [new file with mode: 0644]
Applications/plato/fuzix/screen.c [new file with mode: 0644]
Applications/plato/fuzix/splash.c [new file with mode: 0644]
Applications/plato/fuzix/terminal_char_load.c [new file with mode: 0644]
Applications/plato/fuzix/touch.c [new file with mode: 0644]
Applications/plato/io.h [new file with mode: 0644]
Applications/plato/io_base.c [new file with mode: 0644]
Applications/plato/keyboard.h [new file with mode: 0644]
Applications/plato/keyboard_base.c [new file with mode: 0644]
Applications/plato/plato.c [new file with mode: 0644]
Applications/plato/plato_key.h [new file with mode: 0644]
Applications/plato/protocol.c [new file with mode: 0644]
Applications/plato/protocol.h [new file with mode: 0644]
Applications/plato/screen.h [new file with mode: 0644]
Applications/plato/screen_base.c [new file with mode: 0644]
Applications/plato/terminal.c [new file with mode: 0644]
Applications/plato/terminal.h [new file with mode: 0644]
Applications/plato/tools/Makefile [new file with mode: 0644]
Applications/plato/tools/mk_ascii_key_h.c [new file with mode: 0644]
Applications/plato/tools/mk_font.c [new file with mode: 0644]
Applications/plato/tools/mk_scale.c [new file with mode: 0644]
Applications/plato/touch.h [new file with mode: 0644]
Applications/plato/touch_base.c [new file with mode: 0644]

diff --git a/Applications/plato/Makefile.z80 b/Applications/plato/Makefile.z80
new file mode 100644 (file)
index 0000000..e106796
--- /dev/null
@@ -0,0 +1,35 @@
+.SUFFIXES: .c .rel
+
+CC = fcc -m$(USERCPU) $(Z80_PLATFORM)
+COPT = $(FUZIX_CCOPTS)
+
+SRCS = io_base.c keyboard_base.c plato.c protocol.c screen_base.c terminal.c \
+       touch_base.c
+
+FSRCS = font.c io.c keyboard.c scale.c screen.c splash.c \
+       terminal_char_load.c touch.c
+
+INC = io.h keyboard.h plato_key.h protocol.h screen.h terminal.h touch.h
+
+all:    plato
+
+OBJS = $(SRCS:.c=.rel)
+FOBJS = $(patsubst fuzix/%.c,%.rel, $(FSRCS))
+
+plato: $(OBJS) $(FOBJS)
+       $(CC) -o plato --nostdio $(OBJS) $(FOBJS)
+
+$(OBJS):.c.rel:
+       $(CC) $(COPT) $(CFLAGS) -c $< -o $@
+
+$(FOBJS):.c.rel:
+       $(CC) $(COPT) $(CFLAGS) -c $< -o $@
+
+
+$(OBJS) : $(INC)
+
+$(FOBJS) : $(INC)
+
+clean:
+       rm -f *.o *.rel *.lst *.sym *.asm *.map *.noi *.lk *.bin *~ plato
+       (cd fuzix; rm -f *.o *.rel *.lst *.sym *.asm *.map *.noi *.lk *.bin *~ )
\ No newline at end of file
diff --git a/Applications/plato/NOTES b/Applications/plato/NOTES
new file mode 100644 (file)
index 0000000..68a1766
--- /dev/null
@@ -0,0 +1,11 @@
+Implement
+
+- Fix up our output code to buffer into a 256 byte buffer
+- Keep shovelling every tick
+- Set the tty up and atexit properly
+- Block all the signals we don't want (inc PIPE)
+- Actually look up the address properly
+- Get the splash screen off disk instead
+
+
+It would be nice to squash it to the point we can afford 576 byte I/O buffers
diff --git a/Applications/plato/fuzix/font.c b/Applications/plato/fuzix/font.c
new file mode 100644 (file)
index 0000000..31a2ca5
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * Font definitions for font memories M0 and M1
+ */
+
+#include <stdint.h>
+
+uint8_t FONT_SIZE_X = 4;
+uint8_t FONT_SIZE_Y = 6;
+
+uint8_t font[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     /* SPACE 0x20 */
+       0x80, 0x80, 0x80, 0x00, 0x80, 0x00,     /* ! 0x21     */
+       0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00,     /* " 0x22     */
+       0xA0, 0xE0, 0xA0, 0xE0, 0xA0, 0x00,     /* # 0x23     */
+       0x40, 0xE0, 0xC0, 0x60, 0xE0, 0x40,     /* $ 0x24     */
+       0xA0, 0x20, 0x40, 0x80, 0xA0, 0x00,     /* % 0x25     */
+       0x40, 0xA0, 0x40, 0xA0, 0x60, 0x00,     /* & 0x26     */
+       0x80, 0x80, 0x00, 0x00, 0x00, 0x00,     /* ' 0x27     */
+       0x20, 0x40, 0x40, 0x40, 0x20, 0x00,     /* ( 0x28     */
+       0x40, 0x20, 0x20, 0x20, 0x40, 0x00,     /* ) 0x29     */
+       0xa0, 0x40, 0xe0, 0x40, 0xa0, 0x00,     /* * 0x2a     */
+       0x00, 0x40, 0xe0, 0x40, 0x00, 0x00,     /* + 0x2b     */
+       0x00, 0x00, 0x00, 0x40, 0x80, 0x00,     /* , 0x2c     */
+       0x00, 0x00, 0xE0, 0x00, 0x00, 0x00,     /* - 0x2d     */
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x00,     /* . 0x2e     */
+       0x00, 0x20, 0x60, 0xc0, 0x80, 0x00,     /* / 0x2f     */
+       0x60, 0xA0, 0xA0, 0xA0, 0xC0, 0x00,     /* 0 0x30     */
+       0x40, 0xC0, 0x40, 0x40, 0xE0, 0x00,     /* 1 0x31     */
+       0xC0, 0x20, 0x40, 0x80, 0xE0, 0x00,     /* 2 0x32     */
+       0xC0, 0x20, 0x40, 0x20, 0xC0, 0x00,     /* 3 0x33     */
+       0x20, 0xA0, 0xE0, 0x20, 0x20, 0x00,     /* 4 0x34     */
+       0xE0, 0x80, 0xC0, 0x20, 0xC0, 0x00,     /* 5 0x35     */
+       0x40, 0x80, 0xC0, 0xA0, 0x40, 0x00,     /* 6 0x36     */
+       0xE0, 0x20, 0x20, 0x40, 0x40, 0x00,     /* 7 0x37     */
+       0x40, 0xA0, 0x40, 0xA0, 0x40, 0x00,     /* 8 0x38     */
+       0x40, 0xA0, 0x60, 0x20, 0x40, 0x00,     /* 9 0x39     */
+       0x80, 0x00, 0x00, 0x80, 0x00, 0x00,     /* : 0x3A     */
+       0x40, 0x00, 0x00, 0x40, 0x80, 0x00,     /* ; 0x3B     */
+       0x20, 0x40, 0x80, 0x40, 0x20, 0x00,     /* < 0x3C     */
+       0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00,     /* = 0x3D     */
+       0x80, 0x40, 0x20, 0x40, 0x80, 0x00,     /* < 0x3E     */
+       0xC0, 0x20, 0x40, 0x00, 0x40, 0x00,     /* ? 0x3F     */
+       0x40, 0xA0, 0xA0, 0xA0, 0x80, 0x60,     /* @ 0x40     */
+       0x40, 0xA0, 0xE0, 0xA0, 0xA0, 0x00,     /* A 0x41     */
+       0xC0, 0xA0, 0xC0, 0xA0, 0xC0, 0x00,     /* B 0x42     */
+       0x60, 0x80, 0x80, 0x80, 0x60, 0x00,     /* C 0x43     */
+       0xC0, 0xA0, 0xA0, 0xA0, 0xC0, 0x00,     /* D 0x44     */
+       0xE0, 0x80, 0xC0, 0x80, 0xE0, 0x00,     /* E 0x45     */
+       0xE0, 0x80, 0xC0, 0x80, 0x80, 0x00,     /* F 0x46     */
+       0x60, 0x80, 0xA0, 0xA0, 0x60, 0x00,     /* G 0x47     */
+       0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0x00,     /* H 0x48     */
+       0xE0, 0x40, 0x40, 0x40, 0xE0, 0x00,     /* I 0x49     */
+       0x20, 0x20, 0x20, 0x20, 0xC0, 0x00,     /* J 0x4A     */
+       0xA0, 0xA0, 0xC0, 0xA0, 0xA0, 0x00,     /* K 0x4B     */
+       0x80, 0x80, 0x80, 0x80, 0xE0, 0x00,     /* L 0x4C     */
+       0xA0, 0xE0, 0xE0, 0xA0, 0xA0, 0x00,     /* M 0x4D     */
+       0xC0, 0xA0, 0xA0, 0xA0, 0xA0, 0x00,     /* N 0x4E     */
+       0x40, 0xA0, 0XA0, 0xA0, 0x40, 0x00,     /* O 0x4F     */
+       0xC0, 0xA0, 0xC0, 0x80, 0x80, 0x00,     /* P 0x50     */
+       0x40, 0xA0, 0xA0, 0xA0, 0x40, 0x20,     /* Q 0x51     */
+       0xC0, 0xA0, 0xC0, 0xA0, 0xA0, 0x00,     /* R 0x52     */
+       0x60, 0x80, 0x40, 0x20, 0xC0, 0x00,     /* S 0x53     */
+       0xE0, 0x40, 0x40, 0x40, 0x40, 0x00,     /* T 0x54     */
+       0xA0, 0xA0, 0xA0, 0xA0, 0x40, 0x00,     /* U 0x55     */
+       0xA0, 0xA0, 0xA0, 0x40, 0x40, 0x00,     /* V 0x56     */
+       0xA0, 0xA0, 0xE0, 0xE0, 0xA0, 0x00,     /* W 0x57     */
+       0xA0, 0xA0, 0x40, 0xA0, 0xA0, 0x00,     /* X 0x58     */
+       0xA0, 0xA0, 0x40, 0x40, 0x40, 0x00,     /* Y 0x59     */
+       0xE0, 0x20, 0x40, 0x80, 0xE0, 0x00,     /* Z 0x5A     */
+       0xE0, 0x80, 0x80, 0x80, 0xE0, 0x00,     /* [ 0x5B     */
+       0x80, 0xC0, 0x60, 0x20, 0x00, 0x00,     /* \ 0x5C     */
+       0xE0, 0x20, 0x20, 0x20, 0xE0, 0x00,     /* ] 0x5D     */
+       0x40, 0xA0, 0x00, 0x00, 0x00, 0x00,     /* ^ 0x5E     */
+       0x00, 0x00, 0x00, 0x00, 0xE0, 0x00,     /* _ 0x5F     */
+       0x80, 0x40, 0x00, 0x00, 0x00, 0x00,     /* ` 0x60     */
+       0x00, 0x60, 0xA0, 0xA0, 0x60, 0x00,     /* a 0x61     */
+       0x80, 0xC0, 0xA0, 0xA0, 0xC0, 0x00,     /* b 0x62     */
+       0x00, 0x60, 0x80, 0x80, 0x60, 0x00,     /* c 0x63     */
+       0x20, 0x60, 0xA0, 0xA0, 0x60, 0x00,     /* d 0x64     */
+       0x00, 0x60, 0xA0, 0xC0, 0x60, 0x00,     /* e 0x65     */
+       0x20, 0x40, 0xE0, 0x40, 0x40, 0x00,     /* f 0x66     */
+       0x00, 0x60, 0xA0, 0xA0, 0x60, 0xC0,     /* g 0x67     */
+       0x80, 0xC0, 0xA0, 0xA0, 0xA0, 0x00,     /* h 0x68     */
+       0x40, 0x00, 0xC0, 0x40, 0xE0, 0x00,     /* i 0x69     */
+       0x20, 0x00, 0x60, 0x20, 0x20, 0xC0,     /* j 0x6a     */
+       0x80, 0xA0, 0xC0, 0xA0, 0xA0, 0x00,     /* k 0x6b     */
+       0xC0, 0x40, 0x40, 0x40, 0xE0, 0x00,     /* l 0x6c     */
+       0x00, 0xA0, 0xE0, 0xA0, 0xA0, 0x00,     /* m 0x6d     */
+       0x00, 0xC0, 0xA0, 0xA0, 0xA0, 0x00,     /* n 0x6e     */
+       0x00, 0x40, 0xA0, 0xA0, 0x40, 0x00,     /* o 0x6f     */
+       0x00, 0x60, 0xA0, 0xA0, 0xC0, 0x80,     /* p 0x70     */
+       0x00, 0x60, 0xA0, 0xA0, 0x60, 0x20,     /* q 0x71     */
+       0x00, 0xC0, 0xA0, 0x80, 0x80, 0x00,     /* r 0x72     */
+       0x00, 0x20, 0x40, 0x20, 0xC0, 0x00,     /* s 0x73     */
+       0x40, 0xE0, 0x40, 0x40, 0x20, 0x00,     /* t 0x74     */
+       0x00, 0xA0, 0xA0, 0xA0, 0x60, 0x00,     /* u 0x75     */
+       0x00, 0xA0, 0xA0, 0x40, 0x40, 0x00,     /* v 0x76     */
+       0x00, 0xA0, 0xA0, 0xE0, 0xA0, 0x00,     /* w 0x77     */
+       0x00, 0xA0, 0x40, 0x40, 0xA0, 0x00,     /* x 0x78     */
+       0x00, 0xA0, 0xA0, 0xA0, 0x60, 0xC0,     /* y 0x79     */
+       0x00, 0xE0, 0x40, 0x80, 0xE0, 0x00,     /* z 0x7A     */
+       0x60, 0x40, 0x80, 0x80, 0x40, 0x60,     /* { 0x7B     */
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80,     /* | 0x7C     */
+       0xC0, 0x40, 0x20, 0x20, 0x40, 0xC0,     /* } 0x7D     */
+       0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,     /* ~ 0x7E     */
+       0x00, 0xF0, 0x90, 0x90, 0xF0, 0x00,     /* BOX 0x7F   */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     /* SPACE 0xA0 */
+       0x00, 0x10, 0x20, 0x40, 0x80, 0x00,     /* / 0xA1     */
+       0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,     /* EQUIV 0xA2 */
+       0x00, 0x00, 0x00, 0x00, 0x60, 0xC0,     /* LOW TILDE 0xA3 */
+       0x20, 0x70, 0x80, 0x70, 0x20, 0x00,     /* ASSIGN 0xA4 */
+       0x20, 0xE0, 0x40, 0xE0, 0x80, 0x00,     /* nEqual 0xA5 */
+       0x40, 0xE0, 0x40, 0x40, 0x00, 0x00,     /* up arrow 0xA6 */
+       0x00, 0x20, 0xF0, 0x20, 0x00, 0x00,     /* rt arrow 0xA7 */
+       0x40, 0x40, 0xE0, 0x40, 0x00, 0x00,     /* dn arrow 0xA8 */
+       0x00, 0x40, 0xF0, 0x40, 0x00, 0x00,     /* lf arrow 0xA9 */
+       0x00, 0xA0, 0x40, 0xA0, 0x00, 0x00,     /* multiply 0xAA */
+       0xF0, 0x80, 0x60, 0x80, 0xF0, 0x00,     /* sigma    0xAB */
+       0x00, 0x00, 0x40, 0xA0, 0xE0, 0x00,     /* delta    0xAC */
+       0x00, 0x90, 0x90, 0x60, 0x00, 0x00,     /* union    0xAD */
+       0x00, 0x60, 0x90, 0x90, 0x00, 0x00,     /* intrsect 0xAE */
+       0x40, 0x00, 0xE0, 0x00, 0x40, 0x00,     /* divide   0xAF */
+       0x00, 0x50, 0xA0, 0x70, 0x00, 0x00,     /* alpha    0xB0 */
+       0x20, 0x50, 0xA0, 0x90, 0xE0, 0x80,     /* beta     0xB1 */
+       0x40, 0x80, 0x40, 0xA0, 0xE0, 0x00,     /* delta    0xB2 */
+       0x80, 0x40, 0x20, 0x50, 0x90, 0x00,     /* lambda   0xB3 */
+       0x00, 0x00, 0x50, 0x50, 0x60, 0x80,     /* mu       0xB4 */
+       0x00, 0x00, 0xF0, 0x60, 0x60, 0x00,     /* pi       0xB5 */
+       0x00, 0x20, 0x50, 0x50, 0xA0, 0x80,     /* rho      0xB6 */
+       0x00, 0x00, 0xE0, 0xA0, 0x40, 0x00,     /* sigma    0xB7 */
+       0x00, 0x00, 0x90, 0xB0, 0x60, 0x00,     /* omega    0xB8 */
+       0x20, 0x40, 0x80, 0x40, 0x20, 0x70,     /* lt ||=   0xB9 */
+       0x80, 0x40, 0x20, 0x40, 0x80, 0xE0,     /* gt ||=   0xBA */
+       0x40, 0xA0, 0xE0, 0xA0, 0x40, 0x00,     /* theta    0xBB */
+       0x30, 0x60, 0xA0, 0x60, 0x30, 0x00,     /* l-embed  0xBC */
+       0x00, 0x60, 0x90, 0x60, 0x00, 0x00,     /* degree   0xBD */
+       0xC0, 0x60, 0x50, 0x60, 0xC0, 0x00,     /* r-embed  0xBE */
+       0xC0, 0xA0, 0x50, 0x50, 0xA0, 0xC0,     /* arrow    0xBF */
+       0xF0, 0x20, 0x40, 0x40, 0x20, 0xF0,     /* copyrig  0xC0 */
+       0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,     /* diaeresis 0xC1 */
+       0x00, 0xE0, 0xA0, 0xE0, 0x00, 0x00,     /* box      0xC2 */
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00,     /* interpunct 0xC3 */
+       0x00, 0x00, 0x60, 0xF0, 0x60, 0x00,     /* diamond  0xC4 */
+       0x00, 0x90, 0x60, 0x60, 0x90, 0x00,     /* multiply 0xC5 */
+       0x20, 0x40, 0x00, 0x00, 0x00, 0x00,     /* acute ac 0xC6 */
+       0x00, 0x00, 0x00, 0x10, 0x20, 0x00,     /* cedilla  0xC7 */
+       0xA0, 0x40, 0xA0, 0x00, 0x00, 0x00,     /* hacek    0xC8 */
+       0x00, 0x00, 0x60, 0xF0, 0x60, 0x00,     /* diamond  0xC9 */
+       0x40, 0x40, 0x40, 0x40, 0x40, 0x40,     /* | 0xca */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t fontm23[768];
+
+uint16_t fontptr[] =
+    { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96,
+102, 108, 114, 120, 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192,
+198, 204, 210, 216, 222, 228, 234, 240, 246, 252, 258, 264, 270, 276, 282, 288,
+294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360, 366, 372, 378, 384,
+390, 396, 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480,
+486, 492, 498, 504, 510, 516, 522, 528, 534, 540, 546, 552, 558, 564, 570, 576,
+582, 588, 594, 600, 606, 612, 618, 624, 630, 636, 642, 648, 654, 660, 666, 672,
+678, 684, 690, 696, 702, 708, 714, 720, 726, 732, 738, 744, 750, 756, 762, 768,
+774, 780, 786, 792, 798, 804, 810, 816, 822, 828, 834, 840, 846, 852, 858, 864,
+870, 876, 882, 888, 894, 900, 906, 912, 918, 924, 930, 936, 942, 948, 954 };
diff --git a/Applications/plato/fuzix/io.c b/Applications/plato/fuzix/io.c
new file mode 100644 (file)
index 0000000..5a5f767
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * io.c - Input/output functions (serial/ethernet) (apple2 specific)
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../io.h"
+#include "../screen.h"
+
+extern int io_fd;
+static char buf[64];
+static char *bufp = buf;
+
+void io_process_queue(void)
+{
+       int len;
+
+       if (buf == bufp)
+               return;
+       len = write(io_fd, buf, bufp-buf);
+       if (len == 0 || (len == -1 && errno == EAGAIN))
+               return;
+       if (len < 0) {
+               perror("write");
+               return;
+       }
+       /* Circular buffers are elegant, ldir is small and faster for 64 bytes */
+       memmove(buf, buf + len, len);
+       bufp -= len;
+}
+
+/**
+ * io_send_byte(b) - Send specified byte out
+ */
+void io_send_byte(uint8_t b)
+{
+       /* We need to do proper buffering/queueing here ! */
+       if (bufp != &buf[64])
+               *bufp++ = b;
+       else
+               screen_beep();
+}
diff --git a/Applications/plato/fuzix/keyboard.c b/Applications/plato/fuzix/keyboard.c
new file mode 100644 (file)
index 0000000..43b8dc1
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * keyboard.c - Keyboard functions (apple2)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#include "../screen.h"
+#include "../keyboard.h"
+#include "../protocol.h"
+#include "key.h"
+
+static uint8_t ch;
+static uint8_t shift_lock = false;
+static uint8_t is_escape = false;
+extern uint8_t xoff_enabled;
+extern padBool TTY;
+
+/**
+ * keyboard_main - Handle the keyboard presses
+ */
+void keyboard_main(void)
+{
+       uint8_t ch;
+
+       switch (read(0, &ch, 1)) {
+       case 0:
+               return;
+       case -1:
+               if (errno != EAGAIN) {
+                       perror("read");
+                       exit(1);
+               }
+               return;
+       }
+       if (is_escape == true && ch == 0x1B)    // ESC
+       {
+               screen_beep();
+
+               if (shift_lock == true)
+                       shift_lock = false;
+               else
+                       shift_lock = true;
+
+               is_escape = false;
+       } else if (is_escape == false && ch == 0x1B)
+               is_escape = true;
+       else if (TTY) {
+               keyboard_out_tty(ch);
+       } else if (is_escape == true) {
+               keyboard_out(esc_key_to_pkey[ch]);
+               is_escape = false;
+       } else if (shift_lock == true) {
+               keyboard_out(shiftlock_key_to_pkey[ch]);
+       } else {
+               keyboard_out(key_to_pkey[ch]);
+       }
+}
+
+/**
+ * keyboard_clear() - Clear the keyboard buffer
+ */
+void keyboard_clear(void)
+{
+       /* We can do this but do we need to ? */
+}
diff --git a/Applications/plato/fuzix/scale.c b/Applications/plato/fuzix/scale.c
new file mode 100644 (file)
index 0000000..356f9ce
--- /dev/null
@@ -0,0 +1,147 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * scale.c - Scaling table to scale 512x512 to 256x192 (x+12 for apple2)
+ */
+
+#include <stdint.h>
+
+/* X and Y tables used to scale 512x512 PLATO display to 320x192 */
+/* ! Autogenerated by tools/mk_scale.c */
+
+uint16_t scalex[] = {
+       12, 13, 13, 14, 14, 15, 15, 16,
+       16, 17, 17, 18, 18, 19, 19, 20,
+       20, 21, 21, 22, 22, 23, 23, 24,
+       24, 25, 25, 26, 26, 27, 27, 28,
+       28, 29, 29, 30, 30, 31, 31, 32,
+       32, 33, 33, 34, 34, 35, 35, 36,
+       36, 37, 37, 38, 38, 39, 39, 40,
+       40, 41, 41, 42, 42, 43, 43, 44,
+       44, 45, 45, 46, 46, 47, 47, 48,
+       48, 49, 49, 50, 50, 51, 51, 52,
+       52, 53, 53, 54, 54, 55, 55, 56,
+       56, 57, 57, 58, 58, 59, 59, 60,
+       60, 61, 61, 62, 62, 63, 63, 64,
+       64, 65, 65, 66, 66, 67, 67, 68,
+       68, 69, 69, 70, 70, 71, 71, 72,
+       72, 73, 73, 74, 74, 75, 75, 76,
+       76, 77, 77, 78, 78, 79, 79, 80,
+       80, 81, 81, 82, 82, 83, 83, 84,
+       84, 85, 85, 86, 86, 87, 87, 88,
+       88, 89, 89, 90, 90, 91, 91, 92,
+       92, 93, 93, 94, 94, 95, 95, 96,
+       96, 97, 97, 98, 98, 99, 99, 100,
+       100, 101, 101, 102, 102, 103, 103, 104,
+       104, 105, 105, 106, 106, 107, 107, 108,
+       108, 109, 109, 110, 110, 111, 111, 112,
+       112, 113, 113, 114, 114, 115, 115, 116,
+       116, 117, 117, 118, 118, 119, 119, 120,
+       120, 121, 121, 122, 122, 123, 123, 124,
+       124, 125, 125, 126, 126, 127, 127, 128,
+       128, 129, 129, 130, 130, 131, 131, 132,
+       132, 133, 133, 134, 134, 135, 135, 136,
+       136, 137, 137, 138, 138, 139, 139, 140,
+       140, 140, 141, 141, 142, 142, 143, 143,
+       144, 144, 145, 145, 146, 146, 147, 147,
+       148, 148, 149, 149, 150, 150, 151, 151,
+       152, 152, 153, 153, 154, 154, 155, 155,
+       156, 156, 157, 157, 158, 158, 159, 159,
+       160, 160, 161, 161, 162, 162, 163, 163,
+       164, 164, 165, 165, 166, 166, 167, 167,
+       168, 168, 169, 169, 170, 170, 171, 171,
+       172, 172, 173, 173, 174, 174, 175, 175,
+       176, 176, 177, 177, 178, 178, 179, 179,
+       180, 180, 181, 181, 182, 182, 183, 183,
+       184, 184, 185, 185, 186, 186, 187, 187,
+       188, 188, 189, 189, 190, 190, 191, 191,
+       192, 192, 193, 193, 194, 194, 195, 195,
+       196, 196, 197, 197, 198, 198, 199, 199,
+       200, 200, 201, 201, 202, 202, 203, 203,
+       204, 204, 205, 205, 206, 206, 207, 207,
+       208, 208, 209, 209, 210, 210, 211, 211,
+       212, 212, 213, 213, 214, 214, 215, 215,
+       216, 216, 217, 217, 218, 218, 219, 219,
+       220, 220, 221, 221, 222, 222, 223, 223,
+       224, 224, 225, 225, 226, 226, 227, 227,
+       228, 228, 229, 229, 230, 230, 231, 231,
+       232, 232, 233, 233, 234, 234, 235, 235,
+       236, 236, 237, 237, 238, 238, 239, 239,
+       240, 240, 241, 241, 242, 242, 243, 243,
+       244, 244, 245, 245, 246, 246, 247, 247,
+       248, 248, 249, 249, 250, 250, 251, 251,
+       252, 252, 253, 253, 254, 254, 255, 255,
+       256, 256, 257, 257, 258, 258, 259, 259,
+       260, 260, 261, 261, 262, 262, 263, 263,
+       264, 264, 265, 265, 266, 266, 267, 267,
+};
+
+uint16_t scaley[] = {
+       191, 191, 190, 190, 190, 189, 189, 189,
+       188, 188, 187, 187, 187, 186, 186, 186,
+       185, 185, 184, 184, 184, 183, 183, 183,
+       182, 182, 181, 181, 181, 180, 180, 180,
+       179, 179, 178, 178, 178, 177, 177, 177,
+       176, 176, 175, 175, 175, 174, 174, 174,
+       173, 173, 172, 172, 172, 171, 171, 171,
+       170, 170, 169, 169, 169, 168, 168, 168,
+       167, 167, 167, 166, 166, 165, 165, 165,
+       164, 164, 164, 163, 163, 162, 162, 162,
+       161, 161, 161, 160, 160, 159, 159, 159,
+       158, 158, 158, 157, 157, 156, 156, 156,
+       155, 155, 155, 154, 154, 153, 153, 153,
+       152, 152, 152, 151, 151, 150, 150, 150,
+       149, 149, 149, 148, 148, 147, 147, 147,
+       146, 146, 146, 145, 145, 144, 144, 144,
+       143, 143, 143, 142, 142, 142, 141, 141,
+       140, 140, 140, 139, 139, 139, 138, 138,
+       137, 137, 137, 136, 136, 136, 135, 135,
+       134, 134, 134, 133, 133, 133, 132, 132,
+       131, 131, 131, 130, 130, 130, 129, 129,
+       128, 128, 128, 127, 127, 127, 126, 126,
+       125, 125, 125, 124, 124, 124, 123, 123,
+       122, 122, 122, 121, 121, 121, 120, 120,
+       120, 119, 119, 118, 118, 118, 117, 117,
+       117, 116, 116, 115, 115, 115, 114, 114,
+       114, 113, 113, 112, 112, 112, 111, 111,
+       111, 110, 110, 109, 109, 109, 108, 108,
+       108, 107, 107, 106, 106, 106, 105, 105,
+       105, 104, 104, 103, 103, 103, 102, 102,
+       102, 101, 101, 100, 100, 100, 99, 99,
+       99, 98, 98, 97, 97, 97, 96, 96,
+       96, 95, 95, 95, 94, 94, 93, 93,
+       93, 92, 92, 92, 91, 91, 90, 90,
+       90, 89, 89, 89, 88, 88, 87, 87,
+       87, 86, 86, 86, 85, 85, 84, 84,
+       84, 83, 83, 83, 82, 82, 81, 81,
+       81, 80, 80, 80, 79, 79, 78, 78,
+       78, 77, 77, 77, 76, 76, 75, 75,
+       75, 74, 74, 74, 73, 73, 72, 72,
+       72, 71, 71, 71, 70, 70, 70, 69,
+       69, 68, 68, 68, 67, 67, 67, 66,
+       66, 65, 65, 65, 64, 64, 64, 63,
+       63, 62, 62, 62, 61, 61, 61, 60,
+       60, 59, 59, 59, 58, 58, 58, 57,
+       57, 56, 56, 56, 55, 55, 55, 54,
+       54, 53, 53, 53, 52, 52, 52, 51,
+       51, 50, 50, 50, 49, 49, 49, 48,
+       48, 48, 47, 47, 46, 46, 46, 45,
+       45, 45, 44, 44, 43, 43, 43, 42,
+       42, 42, 41, 41, 40, 40, 40, 39,
+       39, 39, 38, 38, 37, 37, 37, 36,
+       36, 36, 35, 35, 34, 34, 34, 33,
+       33, 33, 32, 32, 31, 31, 31, 30,
+       30, 30, 29, 29, 28, 28, 28, 27,
+       27, 27, 26, 26, 25, 25, 25, 24,
+       24, 24, 23, 23, 23, 22, 22, 21,
+       21, 21, 20, 20, 20, 19, 19, 18,
+       18, 18, 17, 17, 17, 16, 16, 15,
+       15, 15, 14, 14, 14, 13, 13, 12,
+       12, 12, 11, 11, 11, 10, 10, 9,
+       9, 9, 8, 8, 8, 7, 7, 6,
+       6, 6, 5, 5, 5, 4, 4, 3,
+       3, 3, 2, 2, 2, 1, 1, 0,
+};
diff --git a/Applications/plato/fuzix/screen.c b/Applications/plato/fuzix/screen.c
new file mode 100644 (file)
index 0000000..af29fbf
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * screen.c - Display output functions
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+
+static uint8_t bp = 0;
+static uint8_t bd = 0;
+
+/**
+ * screen_load_driver()
+ * Load the TGI driver
+ */
+void screen_load_driver(void)
+{
+}
+
+/**
+ * screen_init_hook()
+ * Called after tgi_init to set any special features, e.g. nmi trampolines.
+ */
+void screen_init_hook(void)
+{
+}
+
+/**
+ * Set the terminal colors
+ */
+void screen_update_colors(void)
+{
+}
+
+/**
+ * Wait(void) - Sleep for approx 16.67ms
+ */
+void screen_wait(void)
+{
+       // TODO: 60hz wait
+}
+
+/**
+ * screen_beep(void) - Beep the terminal
+ */
+void screen_beep(void)
+{
+       char c = '\007';
+       write(1, &c, 1);
+}
diff --git a/Applications/plato/fuzix/splash.c b/Applications/plato/fuzix/splash.c
new file mode 100644 (file)
index 0000000..2c1b5a0
--- /dev/null
@@ -0,0 +1,144 @@
+#include "../protocol.h"
+padByte splash[] = {
+       0x1B, 0x02, 0x1B, 0x0C, 0x1B, 0x12, 0x1B, 0xD1, 0xC0, 0x50, 0xC0,
+       0x1B, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0xE2, 0xC0, 0xC0,
+       0xC0, 0xC0, 0x1B, 0x0C, 0x1B, 0x12, 0x1D, 0xAF, 0xF0, 0xC0,
+       0x1B, 0x5A, 0x1B, 0xD1, 0xC0, 0x44, 0x41, 0x1B, 0xD1, 0xC0,
+       0x50, 0xC0, 0x1B, 0x0C, 0x1B, 0x12, 0x1B, 0xD1, 0xC0, 0x50,
+       0xC0, 0x1B, 0x5A, 0x1B, 0x50, 0x00, 0x41, 0xC0, 0x1B, 0xD1,
+       0xC0, 0x50, 0xC0, 0x1D, 0x2E, 0xF0, 0x22, 0x48, 0x1B, 0x5A,
+       0x1D, 0x2D, 0xF3, 0x21, 0xD4, 0xAF, 0xED, 0xD4, 0xF0, 0x55,
+       0x72, 0xD7, 0x74, 0xD8, 0xF5, 0x5A, 0xDE, 0xF5, 0x22, 0x4B,
+       0x50, 0xF3, 0xD2, 0x71, 0x55, 0x6F, 0xD7, 0xED, 0xD8, 0xEB,
+       0x5A, 0xE8, 0xDB, 0xE4, 0x5C, 0x2E, 0xFF, 0x5C, 0xFA, 0xDB,
+       0x78, 0x59, 0xF6, 0xD8, 0x74, 0x55, 0x72, 0x53, 0x71, 0x50,
+       0x6F, 0x4B, 0xEE, 0xC3, 0x42, 0x2D, 0xF3, 0x42, 0xF3, 0x21,
+       0xD4, 0x1D, 0x2E, 0xFA, 0x22, 0x42, 0xAF, 0xE8, 0x42, 0x48,
+       0xCA, 0x4B, 0xE7, 0x4B, 0x66, 0xCC, 0xE4, 0x4D, 0xE2, 0x4E,
+       0x2E, 0xFF, 0x4D, 0x7D, 0x4B, 0x7B, 0xC9, 0xFA, 0x48, 0x42,
+       0x1D, 0x2D, 0xFA, 0xA3, 0xC0, 0xAF, 0xF5, 0xC0, 0x4E, 0x2E,
+       0x60, 0x4E, 0x60, 0x24, 0x41, 0x2D, 0xF3, 0x41, 0xF3, 0xA3,
+       0x47, 0xC5, 0xF5, 0xC3, 0x77, 0xC0, 0xFA, 0xC0, 0x1D, 0xF3,
+       0x24, 0xC0, 0xAF, 0xF0, 0xD2, 0x72, 0x53, 0xF3, 0xD4, 0xF5,
+       0x55, 0x56, 0xF6, 0xD8, 0x77, 0x5A, 0x5C, 0xF6, 0xDE, 0xF5,
+       0xA5, 0x41, 0xF3, 0x42, 0x71, 0x44, 0x2D, 0xF3, 0x56, 0x48,
+       0x2E, 0x60, 0xC5, 0x60, 0x24, 0xD2, 0x2D, 0xF3, 0x4E, 0xC0,
+       0x1D, 0x2E, 0xED, 0x55, 0xAF, 0x69, 0xDB, 0x2E, 0xED, 0xA5,
+       0x41, 0xED, 0x24, 0x55, 0x1D, 0x2D, 0xF3, 0xA5, 0xDD, 0xAF,
+       0x69, 0xDD, 0x50, 0xF5, 0x50, 0xF5, 0xA6, 0xD7, 0x69, 0xD7,
+       0xCA, 0x2D, 0xF3, 0xCA, 0xF3, 0xA5, 0xDD, 0x1D, 0x2E, 0xF0,
+       0x27, 0xD1, 0x1D, 0x2D, 0xF3, 0xD4, 0x74, 0xCC, 0xF5, 0x48,
+       0xF6, 0xC5, 0xFA, 0x41, 0xFC, 0xA6, 0x5F, 0x2E, 0x60, 0x5C,
+       0x63, 0x59, 0x65, 0x59, 0xE8, 0xD7, 0xEE, 0x56, 0x74, 0xD4,
+       0xF5, 0xD4, 0x78, 0xD4, 0xFC, 0x55, 0xFF, 0x56, 0xAF, 0xE2,
+       0xD7, 0x65, 0x59, 0xE8, 0xDB, 0xEB, 0xDD, 0x6C, 0xDE, 0xEE,
+       0x27, 0xC0, 0xF0, 0xC3, 0x72, 0xC5, 0xF3, 0x47, 0xF5, 0x4B,
+       0xF6, 0xD1, 0x77, 0xD7, 0xD8, 0xF6, 0xDD, 0xF5, 0x28, 0x41,
+       0x74, 0xC6, 0x72, 0x48, 0x71, 0xCA, 0x6F, 0xCC, 0xED, 0x4E,
+       0xEB, 0xD1, 0xE7, 0x53, 0x63, 0x55, 0x2E, 0xFF, 0xD7, 0xFA,
+       0xD8, 0xF9, 0xD8, 0xF5, 0xD8, 0x72, 0xD8, 0xEE, 0xD8, 0x6A,
+       0xD7, 0xE7, 0x55, 0xE4, 0xD4, 0x60, 0xD1, 0x2D, 0x7D, 0xCF,
+       0xFA, 0xCC, 0x78, 0xCA, 0xF6, 0xC6, 0x74, 0xC3, 0xF3, 0x27,
+       0x5F, 0xD4, 0x1D, 0xAF, 0xE8, 0xD4, 0xD7, 0xDB, 0xE7, 0xDE,
+       0xE4, 0x28, 0x42, 0xE2, 0x44, 0x2E, 0xFF, 0x47, 0xFC, 0x48,
+       0xF9, 0xC9, 0xF6, 0xCA, 0xF3, 0xCA, 0xEE, 0xC9, 0xEB, 0x47,
+       0x69, 0xC6, 0xE7, 0x44, 0x65, 0x42, 0xE4, 0x41, 0xE2, 0x27,
+       0xDD, 0xE1, 0x5A, 0x60, 0xD7, 0xD4, 0xE1, 0xD1, 0x63, 0x4D,
+       0xE4, 0x4B, 0x66, 0xC9, 0xE8, 0x47, 0x6A, 0xC5, 0x6C, 0x44,
+       0xEE, 0xC3, 0x71, 0xC3, 0x74, 0xC3, 0x77, 0xC3, 0xFC, 0x44,
+       0xFF, 0xC6, 0xAF, 0xE1, 0x48, 0x63, 0xCA, 0xE4, 0x4B, 0x65,
+       0xCC, 0x66, 0x4D, 0xE7, 0x4E, 0xE8, 0xD1, 0xD4, 0x1D, 0x2D,
+       0xF3, 0xA9, 0x44, 0xAF, 0x69, 0x44, 0x69, 0x28, 0xD7, 0xF5,
+       0xD7, 0xF5, 0xA9, 0xDE, 0x69, 0xDE, 0xD1, 0x2D, 0xF3, 0xD1,
+       0x44, 0x1D, 0x2E, 0x60, 0xAA, 0xC3, 0xAF, 0xED, 0xC3, 0x6F,
+       0x44, 0x72, 0xC5, 0xF3, 0xC6, 0x74, 0xC6, 0xF5, 0x47, 0xC9,
+       0xF6, 0x4B, 0xF6, 0x2B, 0x44, 0xE8, 0x44, 0xE8, 0xAA, 0x50,
+       0x2E, 0x7D, 0x50, 0x7D, 0x2B, 0xC3, 0x71, 0xC3, 0x71, 0xAA,
+       0x50, 0xE1, 0x50, 0xE1, 0x2B, 0x44, 0x2D, 0xF3, 0x44, 0xF3,
+       0xAA, 0xCC, 0x74, 0xC9, 0xF5, 0x48, 0xF6, 0x47, 0x77, 0xC6,
+       0xF9, 0x44, 0xFA, 0xC3, 0x2E, 0x60, 0xC3, 0x1D, 0x2D, 0xF3,
+       0x2B, 0xC6, 0xAF, 0xED, 0xC6, 0xF0, 0x47, 0x72, 0x48, 0xC9,
+       0xF3, 0xCA, 0x74, 0xCA, 0xF5, 0x4B, 0x4D, 0xDD, 0x5F, 0xF5,
+       0xAC, 0x42, 0x74, 0x44, 0xF3, 0xC6, 0x72, 0x47, 0x71, 0xC9,
+       0xF0, 0xCA, 0xEE, 0x4B, 0xCC, 0xED, 0x4D, 0xEB, 0x4E, 0x6A,
+       0x4E, 0xE8, 0xCF, 0x66, 0x50, 0xE4, 0x50, 0x63, 0x50, 0xE1,
+       0x50, 0x2E, 0x7E, 0xCF, 0x7B, 0x4E, 0xFA, 0x4E, 0x78, 0x4D,
+       0x77, 0x4B, 0xF5, 0xCA, 0x74, 0x47, 0xF3, 0xC5, 0x72, 0x44,
+       0x71, 0xC3, 0x2D, 0xF3, 0xD4, 0x44, 0x2E, 0xF0, 0x2B, 0x56,
+       0x71, 0x55, 0x74, 0x55, 0x77, 0x56, 0x78, 0xD7, 0xF9, 0x59,
+       0xFA, 0x5A, 0xDB, 0x7B, 0xDD, 0x7D, 0x5F, 0x7E, 0xAC, 0xC0,
+       0xAF, 0x60, 0x41, 0xE4, 0x41, 0x66, 0xC0, 0xE8, 0x2B, 0xDE,
+       0x69, 0xDD, 0xD4, 0x2D, 0xF3, 0xD4, 0xC6, 0x1D, 0xF3, 0xAC,
+       0x53, 0xAF, 0xF0, 0x53, 0xF3, 0xD4, 0xF5, 0x56, 0xD8, 0xF6,
+       0x5A, 0x5C, 0xF5, 0x2D, 0xC0, 0x42, 0xF3, 0x44, 0x72, 0xC5,
+       0xF0, 0xC5, 0x2E, 0x65, 0xD2, 0xAF, 0xF0, 0x5C, 0x72, 0xDD,
+       0x74, 0x5F, 0xF5, 0x5F, 0xF5, 0x2E, 0xC0, 0xF6, 0x42, 0x77,
+       0x44, 0x47, 0xF6, 0xCA, 0xF5, 0xCC, 0xF3, 0x4E, 0xF0, 0x50,
+       0xEE, 0x50, 0x2D, 0xF3, 0x50, 0x44, 0xAF, 0xE2, 0x44, 0x2D,
+       0xFA, 0x2D, 0x59, 0x77, 0xD8, 0xF5, 0xD7, 0xF3, 0x55, 0xCF,
+       0xF5, 0x4D, 0xF6, 0xCC, 0x77, 0xCC, 0xFC, 0xCA, 0x2E, 0xE1,
+       0x48, 0xE7, 0x47, 0x6C, 0xC5, 0xAF, 0xE1, 0xAC, 0xDE, 0x2D,
+       0xF3, 0xDE, 0x53, 0x1D, 0x2E, 0xF0, 0xAF, 0xC0, 0x1B, 0xD1,
+       0xC0, 0x50, 0xC0, 0x1D, 0xAC, 0x78, 0x24, 0x5C, 0x1B, 0x5A,
+       0x9F, 0x1B, 0x12, 0x1B, 0xCC, 0x1B, 0xCF, 0x1B, 0xCA, 0x66,
+       0x6F, 0x72, 0x1B, 0xCC, 0x1B, 0x4E, 0x1B, 0xCA, 0x1B, 0xD1,
+       0xC0, 0x50, 0xC0, 0x1D, 0xA3, 0x78, 0x2B, 0xD8, 0x1B, 0x5A,
+       0x1D, 0xAA, 0xED, 0xA3, 0x56, 0xAC, 0xE8, 0x56, 0xE8, 0x22,
+       0x47, 0x1D, 0x2B, 0xEB, 0x50, 0x1D, 0xAC, 0xE8, 0x47, 0xE4,
+       0x21, 0x5F, 0x2B, 0x7E, 0x59, 0x77, 0xD4, 0x6F, 0xD2, 0xE7,
+       0xD2, 0xAA, 0xFF, 0xD4, 0x78, 0x59, 0x72, 0x5F, 0xEE, 0x22,
+       0x47, 0x5C, 0x7E, 0x5C, 0x4D, 0x1D, 0x2B, 0xEB, 0x50, 0x1D,
+       0xAA, 0xFF, 0xCF, 0x2B, 0x60, 0x4B, 0xE2, 0x47, 0x65, 0xC5,
+       0x69, 0x44, 0xED, 0x44, 0x71, 0xC5, 0x74, 0x47, 0xF6, 0x4B,
+       0x77, 0xCF, 0x77, 0xA3, 0x44, 0xAA, 0xED, 0x44, 0x56, 0x1D,
+       0xA9, 0x7D, 0x5F, 0xAC, 0xE8, 0x5F, 0xE8, 0xA5, 0x4E, 0x1D,
+       0x2B, 0xEB, 0xC6, 0x1D, 0xAC, 0xE8, 0xCF, 0xE4, 0xD7, 0x2B,
+       0x7E, 0xDD, 0x77, 0xA6, 0x42, 0x6F, 0x44, 0xE7, 0x44, 0xAA,
+       0xFF, 0x42, 0x78, 0xA5, 0xDD, 0x72, 0xD7, 0xEE, 0xCF, 0xEE,
+       0x24, 0x59, 0x7E, 0x59, 0x7E, 0xA5, 0xC6, 0x1D, 0x2B, 0xEB,
+       0xC5, 0x1D, 0xAA, 0xFF, 0xC6, 0x2B, 0x60, 0xCA, 0xE2, 0x4D,
+       0x65, 0x50, 0x69, 0xD1, 0xED, 0xD1, 0x71, 0x50, 0x74, 0x4D,
+       0xF6, 0xCA, 0x77, 0xC6, 0x77, 0x24, 0x50, 0xA9, 0x7D, 0x50,
+       0x7D, 0xA3, 0x5F, 0x1D, 0x7D, 0xA6, 0xCC, 0xAC, 0xE8, 0xCC,
+       0xE8, 0x27, 0xDB, 0x1D, 0x2B, 0xEB, 0x53, 0x1D, 0xAC, 0xE7,
+       0xDB, 0xE4, 0x28, 0xC3, 0x2B, 0x7E, 0xC9, 0x77, 0x4E, 0x6F,
+       0x50, 0xE7, 0x50, 0xAA, 0xFF, 0x4E, 0x78, 0xC9, 0x72, 0xC3,
+       0x6F, 0x27, 0xDB, 0xC6, 0x7E, 0xC6, 0xD4, 0x1D, 0x2B, 0xEB,
+       0xD2, 0x1D, 0xAA, 0xFF, 0xD4, 0x2B, 0x60, 0xD8, 0xE2, 0xDB,
+       0x66, 0xDD, 0x69, 0xDE, 0xED, 0xDE, 0xF0, 0xDD, 0x74, 0xDB,
+       0xF6, 0xD8, 0x77, 0xD4, 0x77, 0xA6, 0xDE, 0xA9, 0x7D, 0xDE,
+       0xCC, 0x1D, 0xAA, 0xED, 0x28, 0x59, 0xED, 0xA9, 0xCA, 0xAC,
+       0xFA, 0xCA, 0xFA, 0x28, 0x59, 0xAA, 0xED, 0x59, 0x1D, 0xED,
+       0x2B, 0xD7, 0xED, 0xAA, 0xCA, 0x1D, 0x2B, 0xEB, 0xD2, 0x1D,
+       0xAA, 0xEE, 0xCA, 0x71, 0x42, 0x77, 0xA9, 0xDB, 0x7E, 0x56,
+       0x2B, 0xE7, 0xD4, 0x6F, 0xD4, 0x78, 0x56, 0xFF, 0xDB, 0xAC,
+       0x65, 0xAA, 0x42, 0xE8, 0xCA, 0xE8, 0x2B, 0xD7, 0x2B, 0x71,
+       0xD7, 0x63, 0xCA, 0x63, 0xAA, 0xD4, 0x77, 0x2B, 0x48, 0x77,
+       0xAA, 0x4E, 0x1D, 0x6A, 0x50, 0x1D, 0xF6, 0x4E, 0xF5, 0xCA,
+       0xF3, 0x47, 0x6F, 0xC5, 0x6C, 0x44, 0xE8, 0x44, 0x65, 0xC5,
+       0xE1, 0x47, 0xAA, 0xFF, 0xCA, 0x7E, 0x4E, 0x7E, 0x2B, 0xD7,
+       0xED, 0xD7, 0x1D, 0xED, 0x2D, 0xC3, 0xED, 0xAC, 0xC3, 0x7D,
+       0xC3, 0xD1, 0xAC, 0x69, 0xD1, 0x42, 0xF9, 0x42, 0xF9, 0x2D,
+       0xC3, 0xAA, 0xED, 0xC3, 0x1D, 0xEE, 0x48, 0xAC, 0xF9, 0x48,
+       0xF9, 0x2E, 0x47, 0x69, 0x47, 0x69, 0x2D, 0xD8, 0xAA, 0x7D,
+       0xD8, 0x7D, 0x2E, 0x47, 0xED, 0x47, 0xED, 0x2D, 0x48, 0x1D,
+       0xA9, 0x60, 0xA0, 0xC0, 0x1B, 0x5A, 0x9F, 0x1B, 0x12, 0xC3,
+       0x6F, 0xF0, 0xF9, 0x72, 0x69, 0xE7, 0xE8, 0x74, 0xA0, 0x28,
+       0x1B, 0xC3, 0xC0, 0x1B, 0x42, 0xA9, 0xA0, 0xB2, 0x30, 0xB1,
+       0xB8, 0xA0, 0xC9, 0xD2, 0x41, 0xD4, 0x41, 0x2E, 0xCF, 0x4E,
+       0xCC, 0xC9, 0x4E, 0xC5, 0x2E, 0xA0, 0xD4, 0xE8, 0x69, 0xF3,
+       0xA0, 0x74, 0x65, 0x72, 0xED, 0x69, 0xEE, 0xE1, 0x6C, 0xA0,
+       0x69, 0xF3, 0xA0, 0x72, 0x65, 0x6C, 0x65, 0xE1, 0xF3, 0x65,
+       0xE4, 0xA0, 0xF5, 0xEE, 0xE4, 0x65, 0x72, 0x8D, 0x74, 0xE8,
+       0x65, 0xA0, 0x47, 0x4E, 0x55, 0xA0, 0x50, 0xF5, 0xE2, 0x6C,
+       0x69, 0x63, 0xA0, 0xCC, 0x69, 0x63, 0x65, 0xEE, 0xF3, 0x65,
+       0x2E, 0xA0, 0xD2, 0xF5, 0xEE, 0xA0, 0x74, 0xE8, 0x65, 0xA0,
+       0xF0, 0x72, 0x6F, 0xE7, 0x72, 0xE1, 0xED, 0xA0, 0x47, 0x50,
+       0xCC, 0xAC, 0xA0, 0x66, 0x6F, 0x72, 0xA0, 0xE4, 0x65, 0x74,
+       0xE1, 0x69, 0x6C, 0xF3, 0x2E, 0x1D, 0x1B, 0x12, 0x28, 0xF0,
+       0x2E, 0x48, 0x1D, 0xA9, 0x74, 0xA0, 0xC0, 0x74, 0xAF, 0x5F,
+       0x1D, 0x28, 0x6C, 0xA0, 0xC0, 0x6C, 0xAF, 0x5F, 0x1D, 0x27,
+       0x60, 0xA0, 0xC0, 0x1B, 0x5A, 0x1B, 0x03
+};
+
+short splash_size = 1388;
diff --git a/Applications/plato/fuzix/terminal_char_load.c b/Applications/plato/fuzix/terminal_char_load.c
new file mode 100644 (file)
index 0000000..74689ab
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * terminal_char_load.c - Character set loading routine for 4x6 font.
+ */
+
+// TODO: change 5x6 constraints to fit 4x6, pix_thresh, etc.
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "../terminal.h"
+#include "../protocol.h"
+
+// Temporary PLATO character data, 8x16 matrix
+static unsigned char char_data[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char BTAB[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };      // flip one bit on (OR)
+static unsigned char BTAB_5[] = { 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80 };    // flip one bit on for the 5x6 matrix (OR)
+
+static unsigned char TAB_0_5[] =
+    { 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01,
+0x01, 0x01, 0x00, 0x00, 0x00 };
+static unsigned char TAB_0_5i[] =
+    { 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
+0x04, 0x04, 0x05, 0x05, 0x05 };
+
+static unsigned char TAB_0_4[] = { 0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04 };   // return 0..4 given index 0 to 7
+
+static unsigned char PIX_THRESH[] = { 0x03, 0x02, 0x03, 0x03, 0x02,    // Pixel threshold table.
+       0x03, 0x02, 0x03, 0x03, 0x02,
+       0x02, 0x01, 0x02, 0x02, 0x01,
+       0x02, 0x01, 0x02, 0x02, 0x01,
+       0x03, 0x02, 0x03, 0x03, 0x02,
+       0x03, 0x02, 0x03, 0x03, 0x02
+};
+
+static unsigned char PIX_WEIGHTS[] = { 0x00, 0x00, 0x00, 0x00, 0x00,   // Pixel weights
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char TAB_0_25[] = { 0, 5, 10, 15, 20, 25 };    // Given index 0 of 5, return multiple of 5.
+
+static unsigned char pix_cnt;  // total # of pixels
+static unsigned char curr_word;        // current word
+static unsigned char u, v;     // loop counters
+
+extern unsigned char fontm23[768];
+extern unsigned short fontptr[160];
+
+/**
+ * terminal_char_load - Store a character into the user definable
+ * character set.
+ */
+void terminal_char_load(padWord charnum, charData theChar)
+{
+       // Clear char data. 
+       memset(char_data, 0, sizeof(char_data));
+       memset(PIX_WEIGHTS, 0, sizeof(PIX_WEIGHTS));
+       memset(&fontm23[fontptr[charnum]], 0, 6);
+
+       // Transpose character data.  
+       for (curr_word = 0; curr_word < 8; curr_word++) {
+               for (u = 16; u-- > 0;) {
+                       if (theChar[curr_word] & 1 << u) {
+                               pix_cnt++;
+                               PIX_WEIGHTS[TAB_0_25[TAB_0_5[u]] +
+                                           TAB_0_4[curr_word]]++;
+                               char_data[u ^ 0x0F & 0x0F] |=
+                                   BTAB[curr_word];
+                       }
+               }
+       }
+
+       // Determine algorithm to use for number of pixels.
+       // Algorithm A is used when roughly half of the # of pixels are set.
+       // Algorithm B is used either when the image is densely or sparsely populated (based on pix_cnt).
+       if ((54 <= pix_cnt) && (pix_cnt < 85)) {
+               // Algorithm A - approx Half of pixels are set
+               for (u = 6; u-- > 0;) {
+                       for (v = 5; v-- > 0;) {
+                               if (PIX_WEIGHTS[TAB_0_25[u] + v] >=
+                                   PIX_THRESH[TAB_0_25[u] + v])
+                                       fontm23[fontptr[charnum] + u] |=
+                                           BTAB[v];
+                       }
+               }
+       } else if ((pix_cnt < 54) || (pix_cnt >= 85)) {
+               // Algorithm B - Sparsely or heavily populated bitmaps
+               for (u = 16; u-- > 0;) {
+                       for (v = 8; v-- > 0;) {
+                               if (char_data[u] & (1 << v)) {
+                                       fontm23[fontptr[charnum] +
+                                               TAB_0_5i[u]] |= BTAB_5[v];
+                               }
+                       }
+               }
+       }
+
+}
diff --git a/Applications/plato/fuzix/touch.c b/Applications/plato/fuzix/touch.c
new file mode 100644 (file)
index 0000000..9ec9737
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * touch.c - Touchscreen functions (apple2)
+ */
+
+#include <stdint.h>
+
+/* Scaling tables for touch to convert 320x192 to 512x512 */
+uint16_t scaletx[] = {
+       0, 2, 4, 5, 7, 8, 10, 12,
+       13, 15, 16, 18, 20, 21, 23, 24,
+       26, 28, 29, 31, 32, 34, 36, 37,
+       39, 40, 42, 44, 45, 47, 48, 50,
+       52, 53, 55, 56, 58, 60, 61, 63,
+       64, 66, 68, 69, 71, 72, 74, 76,
+       77, 79, 80, 82, 84, 85, 87, 88,
+       90, 92, 93, 95, 96, 98, 100, 101,
+       103, 104, 106, 108, 109, 111, 112, 114,
+       116, 117, 119, 120, 122, 124, 125, 127,
+       128, 130, 132, 133, 135, 136, 138, 140,
+       141, 143, 144, 146, 148, 149, 151, 152,
+       154, 156, 157, 159, 160, 162, 164, 165,
+       167, 168, 170, 172, 173, 175, 176, 178,
+       180, 181, 183, 184, 186, 188, 189, 191,
+       192, 194, 196, 197, 199, 200, 202, 204,
+       205, 207, 208, 210, 212, 213, 215, 216,
+       218, 220, 221, 223, 224, 226, 228, 229,
+       231, 232, 234, 236, 237, 239, 240, 242,
+       244, 245, 247, 248, 250, 252, 253, 255,
+       256, 258, 260, 261, 263, 264, 266, 268,
+       269, 271, 272, 274, 276, 277, 279, 280,
+       282, 284, 285, 287, 288, 290, 292, 293,
+       295, 296, 298, 300, 301, 303, 304, 306,
+       308, 309, 311, 312, 314, 316, 317, 319,
+       320, 322, 324, 325, 327, 328, 330, 332,
+       333, 335, 336, 338, 340, 341, 343, 344,
+       346, 348, 349, 351, 352, 354, 356, 357,
+       359, 360, 362, 364, 365, 367, 368, 370,
+       372, 373, 375, 376, 378, 380, 381, 383,
+       384, 386, 388, 389, 391, 392, 394, 396,
+       397, 399, 400, 402, 404, 405, 407, 408,
+       410, 412, 413, 415, 416, 418, 420, 421,
+       423, 424, 426, 428, 429, 431, 432, 434,
+       436, 437, 439, 440, 442, 444, 445, 447,
+       448, 450, 452, 453, 455, 456, 458, 460,
+       461, 463, 464, 466, 468, 469, 471, 472,
+       474, 476, 477, 479, 480, 482, 484, 485,
+       487, 488, 490, 492, 493, 495, 496, 498,
+       500, 501, 503, 504, 506, 508, 509,
+};
+
+uint16_t scalety[] = {
+       510, 507, 504, 502, 499, 496, 494, 491,
+       488, 486, 483, 480, 478, 475, 472, 470,
+       467, 464, 462, 459, 456, 454, 451, 448,
+       446, 443, 440, 438, 435, 432, 430, 427,
+       424, 422, 419, 416, 414, 411, 408, 406,
+       403, 400, 398, 395, 392, 390, 387, 384,
+       382, 379, 376, 374, 371, 368, 366, 363,
+       360, 358, 355, 352, 350, 347, 344, 342,
+       339, 336, 334, 331, 328, 326, 323, 320,
+       318, 315, 312, 310, 307, 304, 302, 299,
+       296, 294, 291, 288, 286, 283, 280, 278,
+       275, 272, 270, 267, 264, 262, 259, 256,
+       254, 251, 248, 246, 243, 240, 238, 235,
+       232, 230, 227, 224, 222, 219, 216, 214,
+       211, 208, 206, 203, 200, 198, 195, 192,
+       190, 187, 184, 182, 179, 176, 174, 171,
+       168, 166, 163, 160, 158, 155, 152, 150,
+       147, 144, 142, 139, 136, 134, 131, 128,
+       126, 123, 120, 118, 115, 112, 110, 107,
+       104, 102, 99, 96, 94, 91, 88, 86,
+       83, 80, 78, 75, 72, 70, 67, 64,
+       62, 59, 56, 54, 51, 48, 46, 43,
+       40, 38, 35, 32, 30, 27, 24, 22,
+       19, 16, 14, 11, 8, 6, 3, 0,
+};
diff --git a/Applications/plato/io.h b/Applications/plato/io.h
new file mode 100644 (file)
index 0000000..4b2c6a9
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * io.h - Input/output functions (serial/ethernet)
+ */
+
+#ifndef IO_H
+#define IO_H
+
+/**
+ * io_init() - Set-up the I/O
+ */
+void io_init(void);
+
+/**
+ * io_send_byte(b) - Send specified byte out
+ */
+void io_send_byte(uint8_t b);
+
+/**
+ * io_main() - The IO main loop
+ */
+void io_main(void);
+
+/**
+ * io_done() - Called to close I/O
+ */
+void io_done(void);
+
+/**
+ * io_process_queue() - Process the outbound queue
+ */
+
+void io_process_queue(void);
+
+#endif /* IO_H */
diff --git a/Applications/plato/io_base.c b/Applications/plato/io_base.c
new file mode 100644 (file)
index 0000000..0035745
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * io.c - Input/output functions (serial/ethernet)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "io.h"
+#include "protocol.h"
+
+static uint8_t ch=0;
+int io_fd = -1;
+int io_eof;
+
+
+/**
+ * io_init() - Open the device
+ */
+void io_init(void)
+{
+  int s = socket(AF_INET, SOCK_STREAM, 0);
+  struct sockaddr_in sin;
+  if (s == -1) {
+    perror("socket");
+    return;
+  }
+  sin.sin_family = AF_INET;
+  sin.sin_port = htons(8005);
+  /* FIXME: don't hard code! */
+  sin.sin_addr.s_addr = htonl(0x60E2F5B3);
+  if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+    perror("connect");
+    return;
+  }
+  fcntl(s, F_SETFL, FNDELAY);
+  io_fd = s;
+}
+
+/**
+ * io_recv() - Receive and interpret data.
+ */
+void io_main(void)
+{
+  char buf[256];
+  int l;
+
+  /* The OS does our buffering (badly or not varies) */
+  while((l = read(io_fd,  buf, 256)) > 0)
+    ShowPLATO(buf, l);
+  if (l <= 0) {
+    if (l == -1 && errno != EAGAIN) {
+      io_eof = 1;
+      perror("read");
+    }
+  }
+  io_process_queue();
+}
+
+/**
+ * io_done() - Called to close I/O
+ */
+void io_done(void)
+{
+  close(io_fd);
+  io_fd = -1;
+}
diff --git a/Applications/plato/keyboard.h b/Applications/plato/keyboard.h
new file mode 100644 (file)
index 0000000..1d32e5e
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * keyboard.h - Keyboard functions
+ */
+
+#ifndef KEYBOARD_H
+#define KEYBOARD_H
+
+/**
+ * keyboard_out - If platoKey < 0x7f, pass off to protocol
+ * directly. Otherwise, platoKey is an access key, and the
+ * ACCESS key must be sent, followed by the particular
+ * access key from PTAT_ACCESS.
+ */
+void keyboard_out(uint8_t platoKey);
+
+/**
+ * keyboard_main - Handle the keyboard presses
+ */
+void keyboard_main(void);
+
+/**
+ * keyboard_clear() - Clear the keyboard buffer
+ */
+void keyboard_clear(void);
+
+/**
+ * keyboard_out_tty - keyboard output to serial I/O in TTY mode
+ */
+void keyboard_out_tty(char ch);
+
+#endif
diff --git a/Applications/plato/keyboard_base.c b/Applications/plato/keyboard_base.c
new file mode 100644 (file)
index 0000000..95fc379
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * keyboard_base.c - Keyboard functions (base)
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "keyboard.h"
+#include "screen.h"
+#include "protocol.h"
+#include "io.h"
+#include "plato_key.h"
+
+/**
+ * keyboard_out - If platoKey < 0x7f, pass off to protocol
+ * directly. Otherwise, platoKey is an access key, and the
+ * ACCESS key must be sent, followed by the particular
+ * access key from PTAT_ACCESS.
+ */
+void keyboard_out(uint8_t platoKey)
+{
+  if (platoKey==0xff)
+    return;
+  
+  if (platoKey>0x7F)
+    {
+      Key(ACCESS);
+      Key(ACCESS_KEYS[platoKey-0x80]);
+      return;
+    }
+  Key(platoKey);
+  return;
+}
+
+/**
+ * keyboard_out_tty - keyboard output to serial I/O in TTY mode
+ */
+void keyboard_out_tty(char ch)
+{
+  io_send_byte(ch);
+}
diff --git a/Applications/plato/plato.c b/Applications/plato/plato.c
new file mode 100644 (file)
index 0000000..83f90d2
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * plato.c - main program
+ */
+
+#include <stdbool.h>
+#include "terminal.h"
+#include "screen.h"
+#include "touch.h"
+#include "keyboard.h"
+#include "io.h"
+
+uint8_t already_started=false;
+extern padByte splash[];
+extern short splash_size;
+
+/**
+ * greeting(void) - Show terminal greeting
+ */
+void greeting(void)
+{
+  ShowPLATO(splash,splash_size);
+  terminal_initial_position();
+}
+
+void main(void)
+{
+  screen_init();
+  io_init();
+  touch_init();
+  terminal_init();
+  greeting();
+  screen_beep();
+  
+  already_started=true;
+  
+  // And do the terminal
+  for (;;)
+    {
+      io_main();
+      keyboard_main();
+      touch_main();
+    }
+  
+  screen_done();
+  touch_done();
+}
diff --git a/Applications/plato/plato_key.h b/Applications/plato/plato_key.h
new file mode 100644 (file)
index 0000000..29178f5
--- /dev/null
@@ -0,0 +1,252 @@
+/**
+ * plato_key.h
+ * PLATO specific key mappings
+ * used by key.h
+ * this define table is ordered as in s0ascers document.
+ */
+
+#ifndef PLATO_KEY_H
+#define PLATO_KEY_H
+
+#define PKEY_a 0x41
+#define PKEY_A 0x61
+#define PKEY_b 0x42
+#define PKEY_B 0x62
+#define PKEY_c 0x43
+#define PKEY_C 0x63
+#define PKEY_d 0x44
+#define PKEY_D 0x64
+#define PKEY_e 0x45
+#define PKEY_E 0x65
+#define PKEY_f 0x46
+#define PKEY_F 0x66
+#define PKEY_g 0x47
+#define PKEY_G 0x67
+#define PKEY_h 0x48
+#define PKEY_H 0x68
+#define PKEY_i 0x49
+#define PKEY_I 0x69
+#define PKEY_j 0x4a
+#define PKEY_J 0x6a
+#define PKEY_k 0x4b
+#define PKEY_K 0x6b
+#define PKEY_l 0x4c
+#define PKEY_L 0x6C
+#define PKEY_m 0x4d
+#define PKEY_M 0x6d
+#define PKEY_n 0x4e
+#define PKEY_N 0x6e
+#define PKEY_o 0x4f
+#define PKEY_O 0x6f
+#define PKEY_p 0x50
+#define PKEY_P 0x70
+#define PKEY_q 0x51
+#define PKEY_Q 0x71
+#define PKEY_r 0x52
+#define PKEY_R 0x72
+#define PKEY_s 0x53
+#define PKEY_S 0x73
+#define PKEY_t 0x54
+#define PKEY_T 0x74
+#define PKEY_u 0x55
+#define PKEY_U 0x75
+#define PKEY_v 0x56
+#define PKEY_V 0x76
+#define PKEY_w 0x57
+#define PKEY_W 0x77
+#define PKEY_x 0x58
+#define PKEY_X 0x78
+#define PKEY_y 0x59
+#define PKEY_Y 0x79
+#define PKEY_z 0x5a
+#define PKEY_Z 0x7A
+#define PKEY_0 0x00
+#define PKEY_LESS_THAN 0x20
+#define PKEY_1 0x01
+#define PKEY_GREATER_THAN 0x21
+#define PKEY_2 0x02
+#define PKEY_BRACKET_LEFT 0x22
+#define PKEY_3 0x03
+#define PKEY_BRACKET_RIGHT 0x23
+#define PKEY_4 0x04
+#define PKEY_DOLLAR 0x24
+#define PKEY_5 0x05
+#define PKEY_PERCENT 0x25
+#define PKEY_6 0x06
+#define PKEY_UNDERSCORE 0x26
+#define PKEY_7 0x07
+#define PKEY_APOSTROPHE 0x27
+#define PKEY_8 0x08
+#define PKEY_ASTERISK 0x28
+#define PKEY_9 0x09
+#define PKEY_PARENTHESIS_LEFT 0x29
+#define PKEY_EQUALS 0x5B
+#define PKEY_PARENTHESIS_RIGHT 0x7B
+#define PKEY_PLUS 0x0E
+#define PKEY_SIGMA 0x2E
+#define PKEY_ASSIGN 0x0D
+#define PKEY_SHIFT 0x2D
+#define PKEY_MINUS 0x0F
+#define PKEY_DELTA 0x2F
+#define PKEY_DIVIDE 0x0B
+#define PKEY_INTERSECT 0x2B
+#define PKEY_MULTIPLY 0x0A
+#define PKEY_UNION 0x2A
+#define PKEY_SEMICOLON 0x5c
+#define PKEY_COLON 0x7c
+#define PKEY_PERIOD 0x5e
+#define PKEY_EXCLAMATION 0x7e
+#define PKEY_COMMA 0x5f
+#define PKEY_QUOTE 0x7f
+#define PKEY_SLASH 0x5d
+#define PKEY_QUESTION_MARK 0x7d
+#define PKEY_SUPER 0x10
+#define PKEY_SUPER1 0x30
+#define PKEY_SUB 0x11
+#define PKEY_SUB1 0x31
+#define PKEY_ANS 0x12
+#define PKEY_TERM 0x32
+#define PKEY_COPY 0x1B
+#define PKEY_COPY1 0x3B
+#define PKEY_TAB 0x0c
+#define PKEY_CR 0x2c
+#define PKEY_ERASE 0x13
+#define PKEY_ERASE1 0x33
+#define PKEY_MICRO 0x14
+#define PKEY_FONT 0x34
+#define PKEY_HELP 0x15
+#define PKEY_HELP1 0x35
+#define PKEY_SQUARE 0x1C
+#define PKEY_ACCESS 0x3C
+#define PKEY_NEXT 0x16
+#define PKEY_NEXT1 0x36
+#define PKEY_EDIT 0x17
+#define PKEY_EDIT1 0x37
+#define PKEY_BACK 0x18
+#define PKEY_BACK1 0x38
+#define PKEY_LAB 0x1D
+#define PKEY_LAB1 0x3D
+#define PKEY_DATA 0x19
+#define PKEY_DATA1 0x39
+#define PKEY_STOP 0x1a
+#define PKEY_STOP1 0x3a
+#define PKEY_SPACE 0x40
+#define PKEY_BACKSPACE 0x60
+#define PKEY_PRINT 0x1F
+#define PKEY_PRINT1 0x3F
+#define PKEY_NOKEY 0xFF /* no key mapping */
+
+/* The following keys require an ACCESS key combination */
+#define PKEY_ALPHA 0x80
+#define PKEY_BETA 0x81
+#define PKEY_CEDILLA 0x82
+#define PKEY_LOWERCASE_DELTA 0x83
+#define PKEY_ACUTE_ACCENT 0x84
+#define PKEY_LOWERCASE_AE 0x85
+#define PKEY_LOWERCASE_OE 0x86
+#define PKEY_LOWERCASE_A_WITH_RING 0x87
+#define PKEY_LOWERCASE_A_WITH_DIAERESIS 0x88
+#define PKEY_LAMBDA 0x89
+#define PKEY_MU 0x8A
+#define PKEY_TILDE 0x8B
+#define PKEY_DEGREE 0x8C
+#define PKEY_PI 0x8D
+#define PKEY_GRAVE 0x8E
+#define PKEY_RHO 0x8F
+#define PKEY_LOWERCASE_SIGMA 0x90
+#define PKEY_THETA 0x91
+#define PKEY_DIARESIS 0x92
+#define PKEY_HACEK 0x93
+#define PKEY_CAPITAL_PI 0x94
+#define PKEY_CIRCUMFLEX 0x95
+#define PKEY_LEFT_EMBED 0x96
+#define PKEY_RIGHT_EMBED 0x97
+#define PKEY_AT 0x98
+#define PKEY_ARROW 0x99
+#define PKEY_AMPERSAND 0x9A
+#define PKEY_INTERPUNCT 0x9B
+#define PKEY_LOWER_TILDE 0x9C
+#define PKEY_DELIMITER 0x9D
+#define PKEY_BACKSLASH 0x9E
+#define PKEY_NOT_EQUAL 0x9F
+#define PKEY_LOWERCASE_O_WITH_DIARESIS 0xA0
+#define PKEY_LEFT_ARROW 0xA1
+#define PKEY_DOWN_ARROW 0xA2
+#define PKEY_RIGHT_ARROW 0xA3
+#define PKEY_UP_ARROW 0xA4
+#define PKEY_COPYRIGHT 0xA5
+#define PKEY_DIAMOND 0xA6
+#define PKEY_UPPERCASE_AE 0xA7
+#define PKEY_UPPERCASE_OE 0xA8
+#define PKEY_BAR 0xA9
+#define PKEY_UPPERCASE_A_WITH_RING 0xAA
+#define PKEY_UPPERCASE_A_WITH_DIAERESIS 0xAB
+#define PKEY_ACCESS_SQUARE 0xAC
+#define PKEY_UPPERCASE_O_WITH_DIARESIS 0xAD
+#define PKEY_LESS_THAN_OR_EQUAL 0xAE
+#define PKEY_GREATER_THAN_OR_EQUAL 0xAF
+#define PKEY_LEFT_CURLY_BRACE 0xB0
+#define PKEY_RIGHT_CURLY_BRACE 0xB1
+#define PKEY_POUND 0xB2
+#define PKEY_BIG_CROSS 0xB3
+#define PKEY_EQUIVALENT 0xB4
+
+/* ACCESS Key combinations. */
+static uint8_t ACCESS_KEYS[] = {
+  PKEY_a, /* 0x80 a É‘ alpha */ 
+  PKEY_B, /* 0x81 b ß beta */
+  PKEY_c, /* 0x82 c cedilla */
+  PKEY_d, /* 0x83 d Î´ delta */
+  PKEY_e, /* 0x84 e ' acute accent */
+  PKEY_g, /* 0x85 g æ ae */
+  PKEY_h, /* 0x86 h oe oe */
+  PKEY_j, /* 0x87 j å a with ring */
+  PKEY_k, /* 0x88 k ä a with diaeresis */
+  PKEY_l, /* 0x89 l Æ› lambda */
+  PKEY_m, /* 0x8A m Î¼ mu */
+  PKEY_n, /* 0x8B n ~ tilde */
+  PKEY_o, /* 0x8C o ° degree */
+  PKEY_p, /* 0x8D p Ï€ pi */
+  0x51, /* 0x8E q ` grave */
+  PKEY_r, /* 0x8F r Ï rho */
+  PKEY_s, /* 0x90 s Ïƒ sigma */
+  PKEY_t, /* 0x91 t Î¸ theta */
+  PKEY_u, /* 0x92 u ¨ diaeresis */
+  PKEY_v, /* 0x93 v hacek (upside down circumflex) */
+  PKEY_w, /* 0x94 w Ï– capital pi */
+  PKEY_x, /* 0x95 x ^ circumflex */
+  PKEY_0, /* 0x96 0 l-embed */
+  PKEY_1, /* 0x97 1 r-embed */
+  PKEY_5, /* 0x98 5 @ */
+  PKEY_6, /* 0x99 6 arrow */
+  PKEY_PLUS, /* 0x9a + & */
+  0x26, /* 0x9b & interpunct */
+  PKEY_COLON, /* 0x9c : ~ lower tilde */
+  0x5f, /* 0x9d , delimiter */
+  PKEY_SLASH, /* 0x9e / \ */
+  PKEY_EQUALS, /* 0x9f = not equal */
+  PKEY_y, /* 0xA0 y ö */
+  0x61, /* 0xA1 A left arrow */
+  0x78, /* 0xA2 X down arrow */
+  0x64, /* 0xA3 D right arrow */
+  0x77, /* 0xA4 W up arrow */
+  0x63, /* 0xA5 C © */
+  0x66, /* 0xA6 F â™¦ */
+  0x67, /* 0xA7 G Æ */
+  0x68, /* 0xA8 H OE */
+  0x69, /* 0xA9 I | */
+  0x6A, /* 0xAA J Å */
+  0x6B, /* 0xAB K Ä */
+  0x6F, /* 0xAC O SQUARE */
+  0x79, /* 0xAD Y Ö */
+  0x20, /* 0xAE < â‰¤ */
+  0x21, /* 0xAF > â‰¥ */
+  0x5B, /* 0xB0 [ { */
+  PKEY_SLASH, /* 0xB1 ] } */
+  0x24, /* 0xB2 $ # */
+  0x9a, /* 0xB3 & big cross */
+  0x7B  /* 0xB4 EQUIVALENT */
+};
+
+#endif /* PLATO_KEY_H */
+
diff --git a/Applications/plato/protocol.c b/Applications/plato/protocol.c
new file mode 100644 (file)
index 0000000..5523a54
--- /dev/null
@@ -0,0 +1,981 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ * This file written by Steve Peltz. Copyright notice preserved.
+ * and this code has been used with permission, and can be considered
+ * public domain.
+ *
+ * protocol.c - Protocol decoder functions 
+ */
+
+/* Copyright (c) 1990 by Steve Peltz */
+
+#include <stdbool.h>
+#include "protocol.h"
+
+#define        BSIZE   64
+
+static padBool EscFlag;                /* Currently in an escape sequence */
+static Mode PMode,             /* Mode */
+  CMode;                       /* Command */
+static uint16_t SubMode;       /* Block/Line modes */
+static DataType PType,         /* Mode type */
+  CType;                       /* Current type */
+static uint16_t Phase;         /* Phase of current type */
+static padWord theWord;                /* Data received for various data types */
+static padByte theChar;
+static padByte rawChar;
+static padByte lastChar;
+static padRGB theColor;
+static uint16_t LowX,          /* Previous coordinates received */
+  HiX, LowY, HiY;
+static padPt CurCoord;         /* Current coordinate */
+static padWord Margin;         /* Margin for CR */
+static padWord MemAddr;                /* Load address for program data */
+static uint16_t CharCnt;       /* Current count for loading chars */
+static charData Char;          /* Character data */
+static padByte charBuff[BSIZE];
+static uint16_t charCount;     /* Count of characters currently buffered */
+static padPt charCoord;
+
+extern uint8_t terminal_get_features(void);
+extern uint8_t terminal_get_type(void);
+extern uint8_t terminal_get_subtype(void);
+extern uint8_t terminal_get_load_file(void);
+extern uint8_t terminal_get_configuration(void);
+extern uint16_t terminal_get_char_address(void);
+extern padByte terminal_mem_read(padWord addr);
+extern padByte terminal_ext_in(void);
+
+extern void screen_wait(void);
+extern void screen_beep(void);
+extern void io_send_byte(uint8_t b);
+extern void screen_block_draw(padPt* Coord1, padPt* Coord2);
+extern void screen_dot_draw(padPt* Coord);
+extern void screen_line_draw(padPt* Coord1, padPt* Coord2);
+extern void screen_char_draw(padPt* Coord, unsigned char* ch, unsigned char count);
+extern void screen_tty_char(padByte theChar);
+extern void terminal_mem_load(padWord addr, padWord value);
+extern void terminal_char_load(padWord charnum, charData theChar);
+extern void terminal_mode_5(padWord value);
+extern void terminal_mode_6(padWord value);
+extern void terminal_mode_7(padWord value);
+extern void touch_allow(padBool allow);
+extern void terminal_ext_allow(padBool allow);
+extern void terminal_set_ext_in(padWord device);
+extern void terminal_set_ext_out(padWord device);
+extern void terminal_ext_out(padByte value);
+extern void screen_clear(void);
+extern void terminal_set_tty(void);
+extern void terminal_set_plato(void);
+
+#ifdef PROTOCOL_DEBUG
+extern void log(const char* format, ...);
+#endif
+
+static padByte PTAT0[128] = {  /* PLATO to ASCII lookup table */
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,      /* original mapping */
+  0x38, 0x39, 0x26, 0x60, 0x0a, 0x5e, 0x2b, 0x2d,
+  0x13, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a,
+  0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85,
+  0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x7c,
+  0x2a, 0x28, 0x40, 0x27, 0x1c, 0x5c, 0x23, 0x7e,
+  0x17, 0x05, 0x14, 0x19, 0x7f, 0x09, 0x1e, 0x18,
+  0x0e, 0x1d, 0x11, 0x16, 0x00, 0x0f, 0x87, 0x88,
+  0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c,
+  0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+  0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22
+};
+
+static padByte PTAT1[128] = {
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,      /* flow control mapping */
+  0x38, 0x39, 0x26, 0x60, 0x09, 0x5e, 0x2b, 0x2d,
+  0x17, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a,
+  0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85,
+  0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x27,
+  0x2a, 0x28, 0x40, 0x7c, 0x1c, 0x5c, 0x23, 0x7e,
+  0x97, 0x84, 0x14, 0x19, 0x7f, 0x0a, 0x1e, 0x18,
+  0x0e, 0x1d, 0x05, 0x16, 0x9d, 0x0f, 0x87, 0x88,
+  0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c,
+  0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+  0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22
+};
+
+/*     externally referenced variables */
+
+padPt PLATOSize={512,512};     /* Logical screen size */
+CharMem CurMem;                        /* Font to plot in */
+padBool TTY,                   /* TTY mode */
+  FlowControl,                 /* Flow control on */
+  ModeBold,                    /* Character plotting conditions */
+  Rotate, Reverse;
+DispMode CurMode;              /* Current PLATO plotting mode */
+padBool FastText;               /* Indicate to main program if text optimizations can be done. */
+
+
+/*----------------------------------------------*
+ *     InitPAD, InitTTY, InitPLATO             *
+ *                                             *
+ *     Called to initialize PAD variables.     *
+ *     Calls back to external routines to      *
+ *     set up proper plotting conditions.      *
+ *----------------------------------------------*/
+
+void
+InitPAD (void)
+{
+  InitTTY ();
+}
+
+void
+InitTTY (void)
+{
+  charCount = 0;
+  EscFlag = false;
+  TTY = true;
+  FastText = true;
+  FlowControl = false;
+  terminal_set_tty();
+}
+
+void
+InitPLATO (void)
+{
+  // Key (0x382);                      /* master reset key */
+  if (TTY)
+    InitPLATOx ();
+}
+
+void
+InitPLATOx (void)
+{
+  charCount = 0;
+  EscFlag = false;
+  TTY = false;
+  terminal_set_plato ();
+  SetMode (mAlpha, tByte);
+  LowX = 0;
+  HiX = 0;
+  LowY = 0;
+  HiY = 0;
+  CurCoord.x = 0;
+  CurCoord.y = 0;
+  MemAddr = 0;
+  CharCnt = 0;
+  Margin = 0;
+  ModeBold = false;
+  Rotate = false;
+  Reverse = false;
+  FastText = true;
+  CurMem = M0;
+  CurMode = ModeRewrite;
+}
+
+
+/*----------------------------------------------*
+ *     Key                                     *
+ *                                             *
+ *     Send a 10-bit internal key. If a keyset *
+ *     key, translate, else send as escaped    *
+ *     sequence.                               *
+ *----------------------------------------------*/
+
+void
+Key (padWord theKey)
+{
+  if (theKey >> 7)
+    {
+      io_send_byte (0x1b);
+      io_send_byte (0x40 | (theKey & 0x3f));
+      io_send_byte (0x60 | ((theKey >> 6) & 0x0f));
+    }
+  else
+    {
+
+      if (FlowControl == 0)
+       theKey = PTAT0[theKey];
+      else
+       theKey = PTAT1[theKey];
+
+      if (theKey & 0x80)
+       {
+         io_send_byte (0x1b);
+         io_send_byte (theKey & 0x7f);
+       }
+      else
+       io_send_byte (theKey);
+    }
+}
+
+/*----------------------------------------------*
+ *     Touch                                   *
+ *                                             *
+ *     Send a touch key (01yyyyxxxx).          *
+ *----------------------------------------------*/
+
+void   Touch(padPt* where)
+{
+  // Send FGT (Fine Grained Touch) data.
+  io_send_byte(0x1b);
+  io_send_byte(0x1f);
+  io_send_byte(0x40 + (where->x & 0x1f));
+  io_send_byte(0x40 + ((where->x >> 5) & 0x0f));
+  io_send_byte(0x40 + (where->y & 0x1f));
+  io_send_byte(0x40 + ((where->y >> 5) & 0x0f));
+  
+  // Send coarse touch data
+  Key(0x100 | ((where->x >> 1) & 0xF0) |
+      ((where->y >> 5) & 0x0F));
+}
+
+/*----------------------------------------------*
+ *     Ext                                     *
+ *                                             *
+ *     Send an external key (10xxxxxxxx).      *
+ *----------------------------------------------*/
+
+void
+Ext (padWord theKey)
+{
+  Key (0x200 | (theKey & 0xFF));
+}
+
+
+/*----------------------------------------------*
+ *     Echo                                    *
+ *                                             *
+ *     Send an echo key (001xxxxxx).           *
+ *----------------------------------------------*/
+
+void
+Echo (padWord theKey)
+{
+  Key (0x080 | theKey);
+}
+
+
+
+/*----------------------------------------------*
+ *     SetCommand, SetMode                     *
+ *                                             *
+ *     Set state machine variables.            *
+ *----------------------------------------------*/
+
+void
+SetCommand (Mode theMode, DataType theType)
+{
+  CMode = theMode;
+  CType = theType;
+  Phase = 0;
+}
+
+void
+SetMode (Mode theMode, DataType theType)
+{
+  PMode = theMode;
+  PType = theType;
+  SubMode = 0;
+  SetCommand (theMode, theType);
+}
+
+
+/*----------------------------------------------*
+ *     FixXY                                   *
+ *                                             *
+ *     Move location by offset, then make sure *
+ *     it is still on the screen.              *
+ *----------------------------------------------*/
+
+void
+FixXY (int16_t DX, int16_t DY)
+{
+  if (ModeBold)
+    {
+      DX = DX * 2;
+      DY = DY * 2;
+    }
+  if (Reverse)
+    DX = -DX;
+  if (Rotate)
+    {
+      CurCoord.x = CurCoord.x + DY;
+      CurCoord.y = CurCoord.y + DX;
+    }
+  else
+    {
+      CurCoord.x = CurCoord.x + DX;
+      CurCoord.y = CurCoord.y + DY;
+    }
+
+  if (CurCoord.x < 0)
+    CurCoord.x += PLATOSize.x;
+  else if (CurCoord.x >= PLATOSize.x)
+    CurCoord.x -= PLATOSize.x;
+
+  if (CurCoord.y < 0)
+    CurCoord.y += PLATOSize.y;
+  else if (CurCoord.y >= PLATOSize.y)
+    CurCoord.y -= PLATOSize.y;
+}
+
+
+/*----------------------------------------------*
+ *     Superx, Subx, etc.                      *
+ *                                             *
+ *     Various character positioning commands. *
+ *----------------------------------------------*/
+
+void
+Superx (void)
+{
+  FixXY (0, 5);
+}
+
+void
+Subx (void)
+{
+  FixXY (0, -5);
+}
+
+void
+Marginx (void)
+{
+  if (Rotate)
+    Margin = CurCoord.y;
+  else
+    Margin = CurCoord.x;
+}
+
+void
+BSx (void)
+{
+  FixXY (-8, 0);
+}
+
+void
+HTx (void)
+{
+  FixXY (8, 0);
+}
+
+void
+LFx (void)
+{
+  FixXY (0, -16);
+}
+
+void
+VTx (void)
+{
+  FixXY (0, 16);
+}
+
+void
+FFx (void)
+{
+  CurCoord.y = 0;
+  CurCoord.x = 0;
+  LFx ();
+}
+
+void
+CRx (void)
+{
+  if (Rotate)
+    CurCoord.y = Margin;
+  else
+    CurCoord.x = Margin;
+  LFx ();
+}
+
+
+/*----------------------------------------------*
+ *     LoadCoordx                              *
+ *                                             *
+ *     Assemble completed coordinate.          *
+ *----------------------------------------------*/
+
+void
+LoadCoordx (padPt * SetCoord)
+{
+  SetCoord->x = (HiX << 5) + LowX;
+  SetCoord->y = (HiY << 5) + LowY;
+}
+
+
+/*----------------------------------------------*
+ *     Blockx, Pointx, Linex, Alphax           *
+ *                                             *
+ *     Plot the specified item at the          *
+ *     current location.                       *
+ *----------------------------------------------*/
+
+void
+Blockx (void)
+{
+  padPt NewCoord;
+
+  if (SubMode == 0)
+    {
+      LoadCoordx (&CurCoord);
+      SubMode = 1;
+    }
+  else
+    {
+      LoadCoordx (&NewCoord);
+      screen_block_draw (&CurCoord, &NewCoord);
+      SubMode = 0;
+    }
+}
+
+void
+Pointx (void)
+{
+  LoadCoordx (&CurCoord);
+  screen_dot_draw (&CurCoord);
+}
+
+void
+Linex (void)
+{
+  padPt OldCoord;
+
+  if (SubMode == 0)
+    {
+      LoadCoordx (&CurCoord);
+      SubMode = 1;
+    }
+  else
+    {
+      OldCoord.y = CurCoord.y;
+      OldCoord.x = CurCoord.x;
+      LoadCoordx (&CurCoord);
+      screen_line_draw (&OldCoord, &CurCoord);
+    }
+}
+
+void
+Alphax (void)
+{
+  if (charCount == 0) {
+    charCoord.x = CurCoord.x;
+    charCoord.y = CurCoord.y;
+  }
+  charBuff[charCount++] = theChar;
+  HTx ();
+  if (charCount >= BSIZE)
+    {
+      screen_char_draw (&charCoord, charBuff, charCount);
+      charCount = 0;
+    }
+}
+
+
+/*----------------------------------------------*
+ *     LoadEchox                               *
+ *                                             *
+ *     Echo responses to system.               *
+ *----------------------------------------------*/
+
+void
+LoadEchox (void)
+{
+  theWord &= 0x7f;
+  switch (theWord)
+    {
+
+    case 0x52:
+      FlowControl=true;
+      if (FlowControl)
+       Echo (0x53);            /* flow control on */
+      else
+       Echo (0x52);            /* flow control not on */
+      break;
+    case 0x60:                  /* Inquire about ascii specific features. */
+      Echo (terminal_get_features());
+      break;
+    case 0x70:
+      Echo (terminal_get_type ());     /* terminal type */
+      break;
+
+    case 0x71:
+      Echo (terminal_get_subtype());   /* subtype */
+      break;
+
+    case 0x72:
+      Echo (terminal_get_load_file ());        /* load file */
+      break;
+
+    case 0x73:
+      Echo (terminal_get_configuration ());    /* configuration */
+      break;
+
+    case 0x7A:
+      Key (0x3FF);             /* send backout */
+      break;
+
+    case 0x7B:
+      screen_beep ();
+      break;                   /* beep */
+
+    case 0x7D:
+      Echo (terminal_mem_read (MemAddr) & 0x7F);
+      break;
+
+    default:
+      Echo (theWord);          /* normal echo */
+      break;
+    }
+}
+
+void
+LoadAddrx (void)
+{
+  MemAddr = theWord;
+  CharCnt = 0;
+}
+
+void
+LoadCharx (void)
+{
+  Char[CharCnt] = theWord;
+  if (CharCnt < 7)
+    CharCnt++;
+  else
+    {
+      terminal_char_load ((((MemAddr - terminal_get_char_address ()) >> 4) & 0x7f), Char);
+      CharCnt = 0;
+      MemAddr += 16;
+    }
+}
+
+void
+LoadMemx (void)
+{
+  terminal_mem_load (MemAddr, theWord);
+  MemAddr += 2;
+}
+
+void
+SSFx (void)
+{
+  padByte device;
+
+  device = (theWord >> 10) & 0xFF;
+  if (device == 1)
+    {
+      terminal_ext_allow ((theWord >> 3) & 1);
+      touch_allow ((theWord >> 5) & 1);
+    }
+  else if ((theWord >> 9) & 1)
+    {
+      terminal_set_ext_in (device);
+      if (!((theWord >> 8) & 1))
+       Ext (terminal_ext_in ());
+    }
+  else
+    {
+      terminal_set_ext_out (device);
+      if (!((theWord >> 8) & 1))
+       terminal_ext_out (theWord & 0xFF);
+    }
+}
+
+void
+Externalx (void)
+{
+  terminal_ext_out ((theWord >> 8) & 0xFF);
+  terminal_ext_out (theWord & 0xFF);
+}
+
+void
+GoMode (void)
+{
+  switch (CMode)
+    {
+    case mBlock:
+      Blockx ();
+      break;
+    case mPoint:
+      Pointx ();
+      break;
+    case mLine:
+      Linex ();
+      break;
+    case mAlpha:
+      Alphax ();
+      break;
+    case mLoadCoord:
+      LoadCoordx (&CurCoord);
+      break;
+    case mLoadAddr:
+      LoadAddrx ();
+      break;
+    case mSSF:
+      SSFx ();
+      break;
+    case mExternal:
+      Externalx ();
+      break;
+    case mLoadEcho:
+      LoadEchox ();
+      break;
+    case mLoadChar:
+      LoadCharx ();
+      break;
+    case mLoadMem:
+      LoadMemx ();
+      break;
+    case mMode5:
+      terminal_mode_5 (theWord);
+      break;
+    case mMode6:
+      terminal_mode_6 (theWord);
+      break;
+    case mMode7:
+      terminal_mode_7 (theWord);
+      break;
+    case mFore:
+      /* ForeGround (&theColor); */
+      break;
+    case mBack:
+      /* BackGround (&theColor); */
+      break;
+    }
+  CMode = PMode;
+  CType = PType;
+  Phase = 0;
+}
+
+void
+GoWord (void)
+{
+  switch (Phase)
+    {
+    case 0:
+      theWord = theChar & 0x3F;
+      Phase = 1;
+      break;
+    case 1:
+      theWord |= ((theChar & 0x3F) << 6);
+      Phase = 2;
+      break;
+    case 2:
+      theWord |= ((theChar & 0x3F) << 12);
+      GoMode ();
+      break;
+    }
+}
+
+void
+GoCoord (void)
+{
+  uint16_t CoordType, CoordValue;
+
+  CoordValue = theChar & 0x1F;
+  CoordType = ((theChar >> 5) & 3);
+  switch (CoordType)
+    {
+    case 1:
+      switch (Phase)
+       {
+       case 0:
+         HiY = CoordValue;
+         break;
+       case 1:
+         HiX = CoordValue;
+         break;
+       }
+      Phase = 1;
+      break;
+    case 2:
+      LowX = CoordValue;
+      GoMode ();
+      break;
+    case 3:
+      LowY = CoordValue;
+      Phase = 1;
+      break;
+    }
+}
+
+void
+GoColor (void)
+{
+  switch (Phase)
+    {
+    case 0:
+      theColor.blue = (theChar & 0x3f);
+      break;
+    case 1:
+      theColor.blue |= (theChar & 0x03) << 6;
+      theColor.green = (theChar & 0x3c) >> 2;
+      break;
+    case 2:
+      theColor.green |= (theChar & 0x0f) << 4;
+      theColor.red = (theChar & 0x30) >> 4;
+      break;
+    case 3:
+      theColor.red |= (theChar & 0x3f) << 2;
+      break;
+    }
+  if (Phase < 3)
+    Phase++;
+  else
+    GoMode ();
+}
+
+void
+GoPaint (void)
+{
+  if (Phase == 0)
+    Phase = 1;
+  else
+    GoMode ();
+
+}
+
+void
+DataChar (void)
+{
+  switch (CType)
+    {
+    case tByte:
+      Alphax ();
+      break;
+    case tWord:
+      GoWord ();
+      break;
+    case tCoord:
+      GoCoord ();
+      break;
+    case tColor:
+      GoColor ();
+      break;
+    case tPaint:
+      GoPaint ();
+      break;
+    }
+}
+
+void
+ShowPLATO (padByte *buff, uint16_t count)
+{
+  while (count--)
+    {
+      theChar = *buff++;
+      if (lastChar==0xFF && theChar==0xFF)
+       {
+         // Drop this character, it is an escaped TELNET IAC.
+         lastChar=0;
+       }
+      else
+       {
+         rawChar=theChar;
+         theChar &=0x7F;
+         if (TTY)
+           {
+             if (!EscFlag)
+               screen_tty_char (theChar);
+             else if (theChar == 0x02)
+               InitPLATOx ();
+           }
+         else if (EscFlag)
+           {
+             switch (theChar)
+               {
+               case 0x03:
+                 InitTTY ();
+                 break;
+                 
+               case 0x0C:
+                 screen_clear ();
+                 break;
+                 
+               case 0x11:
+                 CurMode = ModeInverse;
+                 SetFast();
+                 break;
+               case 0x12:
+                 CurMode = ModeWrite;
+                 SetFast();
+                 break;
+               case 0x13:
+                 CurMode = ModeErase;
+                 SetFast();
+                 break;
+               case 0x14:
+                 CurMode = ModeRewrite;
+                 SetFast();
+                 break;
+                 
+               case 0x32:
+                 SetCommand (mLoadCoord, tCoord);
+                 break;
+                 
+               case 0x40:
+                 Superx ();
+                 break;
+               case 0x41:
+                 Subx ();
+                 break;
+                 
+               case 0x42:
+                 CurMem = M0;
+                 break;
+               case 0x43:
+                 CurMem = M1;
+                 break;
+               case 0x44:
+                 CurMem = M2;
+                 break;
+               case 0x45:
+                 CurMem = M3;
+                 break;
+                 
+               case 0x4A:
+                 Rotate = false;
+                 SetFast();
+                 break;
+               case 0x4B:
+                 Rotate = true;
+                 SetFast();
+                 break;
+               case 0x4C:
+                 Reverse = false;
+                 SetFast();
+                 break;
+               case 0x4D:
+                 Reverse = true;
+                 SetFast();
+                 break;
+               case 0x4E:
+                 ModeBold = false;
+                 SetFast();
+                 break;
+               case 0x4F:
+                 ModeBold = true;
+                 SetFast();
+                 break;
+                 
+               case 0x50:
+                 SetMode (mLoadChar, tWord);
+                 break;
+               case 0x51:
+                 SetCommand (mSSF, tWord);
+                 break;
+               case 0x52:
+                 SetCommand (mExternal, tWord);
+                 break;
+               case 0x53:
+                 SetMode (mLoadMem, tWord);
+                 break;
+               case 0x54:
+                 SetMode (mMode5, tWord);
+                 break;
+               case 0x55:
+                 SetMode (mMode6, tWord);
+                 break;
+               case 0x56:
+                 SetMode (mMode7, tWord);
+                 break;
+               case 0x57:
+                 SetCommand (mLoadAddr, tWord);
+                 break;
+               case 0x59:
+                 SetCommand (mLoadEcho, tWord);
+                 break;
+                 
+               case 0x5A:
+                 Marginx ();
+                 break;
+                 
+               case 0x61:
+                 SetCommand (mFore, tColor);
+                 break;
+               case 0x62:
+                 SetCommand (mBack, tColor);
+                 break;
+               case 0x63:
+                 SetCommand (mPaint, tPaint);
+                 break;
+               }
+           }
+         else if (theChar < 0x20)
+           {
+             if (charCount > 0)
+               {
+                 screen_char_draw (&charCoord, charBuff, charCount);
+                 charCount = 0;
+               }
+             switch (theChar)
+               {
+               case 0x00:
+                 screen_wait();
+               case 0x08:
+                 BSx ();
+                 break;
+               case 0x09:
+                 HTx ();
+                 break;
+               case 0x0A:
+                 LFx ();
+                 break;
+               case 0x0B:
+                 VTx ();
+                 break;
+               case 0x0C:
+                 FFx ();
+                 break;
+               case 0x0D:
+                 CRx ();
+                 break;
+                 
+               case 0x19:
+                 SetMode (mBlock, tCoord);
+                 break;
+               case 0x1C:
+                 SetMode (mPoint, tCoord);
+                 break;
+               case 0x1D:
+                 SetMode (mLine, tCoord);
+                 break;
+               case 0x1F:
+                 SetMode (mAlpha, tByte);
+                 break;
+               }
+           }
+         else
+           DataChar ();
+         
+         EscFlag = (theChar == 0x1B);
+         lastChar=rawChar;
+       }
+    }
+  if (charCount > 0)
+    {
+      screen_char_draw (&charCoord, charBuff, charCount);
+      charCount = 0;
+    }
+}
+
+/**
+ * SetFast()
+ * Toggle fast text output if mode = write or erase, and no rotate or bold
+ */
+void SetFast(void)
+{
+  FastText = (((CurMode == ModeWrite) || (CurMode == ModeErase)) && ((Rotate == padF) && (ModeBold == padF))); 
+}
diff --git a/Applications/plato/protocol.h b/Applications/plato/protocol.h
new file mode 100644 (file)
index 0000000..6366c04
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ * This file written by Steve Peltz. Copyright notice preserved.
+ * and this code has been used with permission, and can be considered
+ * public domain.
+ *
+ * protocol.h - Protocol decoder functions 
+ */
+
+/* Copyright (c) 1990 by Steve Peltz */
+
+#ifndef PROTOCOL_H
+#define PROTOCOL_H
+
+#include <stdint.h>
+
+#define ACCESS 0x3c
+
+typedef        unsigned char   padByte;
+typedef        enum {padF, padT} padBool;
+typedef        unsigned char   padChar;
+typedef        short   padWord;
+typedef        padWord charData[8];
+typedef        struct {
+       padByte red,
+               green,
+               blue;
+       } padRGB;
+
+typedef struct {
+       padWord x,
+               y;
+       } padPt;
+
+typedef enum {ModeWrite, ModeErase, ModeRewrite, ModeInverse} DispMode;
+typedef enum {M0, M1, M2, M3} CharMem;
+
+typedef enum { mBlock, mPoint, mLine, mAlpha, mLoadCoord, mLoadChar, mSSF,
+               mExternal, mLoadMem, mMode5, mMode6, mMode7, mLoadAddr,
+               mLoadEcho, mFore, mBack, mPaint } Mode;
+typedef enum { tByte, tWord, tCoord, tColor, tPaint } DataType;
+
+extern padPt           PLATOSize;
+extern CharMem         CurMem;
+extern padBool         TTY,
+                       FlowControl,
+                       ModeBold,
+                       Rotate,
+                       Reverse;
+extern DispMode        CurMode;
+
+void InitPAD(void);
+void InitTTY(void);
+void InitPLATO(void);
+void InitPLATOx(void);
+void Key(padWord theKey);
+void Touch(padPt* where);
+void Ext(padWord theKey);
+void Echo(padWord theKey);
+void SetCommand(Mode theMode, DataType theType);
+void SetMode(Mode theMode, DataType theType);
+void FixXY(int16_t DX, int16_t DY);
+void Superx(void);
+void Subx(void);
+void Marginx(void);
+void BSx(void);
+void HTx(void);
+void LFx(void);
+void VTx(void);
+void FFx(void);
+void CRx(void);
+void LoadCoordx(padPt* SetCoord);
+void Blockx(void);
+void Pointx(void);
+void Linex(void);
+void Alphax(void);
+void LoadEchox(void);
+void LoadAddrx(void);
+void LoadCharx(void);
+void LoadMemx(void);
+void SSFx(void);
+void Externalx(void);
+void GoMode(void);
+void GoWord(void);
+void GoCoord(void);
+void GoColor(void);
+void GoPaint(void);
+void DataChar(void);
+void ShowPLATO(padByte* buff, uint16_t count);
+void SetFast(void);
+
+#endif
diff --git a/Applications/plato/screen.h b/Applications/plato/screen.h
new file mode 100644 (file)
index 0000000..b47a26f
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * screen.h - Display output functions
+ */
+
+#ifndef SCREEN_H
+#define SCREEN_H
+
+#include "protocol.h"
+
+/**
+ * screen_init() - Set up the screen
+ */
+void screen_init(void);
+
+/**
+ * screen_load_driver()
+ * Load the TGI driver
+ */
+void screen_load_driver(void);
+
+/**
+ * screen_init_hook()
+ * Called after tgi_init to set any special features, e.g. nmi trampolines.
+ */
+void screen_init_hook(void);
+
+/**
+ * screen_cycle_foreground()
+ * Go to the next foreground color in palette
+ */
+void screen_cycle_foreground(void);
+
+/**
+ * screen_cycle_background()
+ * Go to the next background color in palette
+ */
+void screen_cycle_background(void);
+
+/**
+ * screen_cycle_border()
+ * Go to the next border color in palette
+ */
+void screen_cycle_border(void);
+
+/**
+ * screen_cycle_foreground_back()
+ * Go to the previous foreground color in palette
+ */
+void screen_cycle_foreground_back(void);
+
+/**
+ * screen_cycle_background_back()
+ * Go to the previous background color in palette
+ */
+void screen_cycle_background_back(void);
+
+/**
+ * screen_cycle_border_back()
+ * Go to the previous border color in palette
+ */
+void screen_cycle_border_back(void);
+
+/**
+ * screen_update_colors() - Set the terminal colors
+ */
+void screen_update_colors(void);
+
+/**
+ * screen_wait(void) - Sleep for approx 16.67ms
+ */
+void screen_wait(void);
+
+/**
+ * screen_beep(void) - Beep the terminal
+ */
+void screen_beep(void);
+
+/**
+ * screen_clear - Clear the screen
+ */
+void screen_clear(void);
+
+/**
+ * screen_block_draw(Coord1, Coord2) - Perform a block fill from Coord1 to Coord2
+ */
+void screen_block_draw(padPt* Coord1, padPt* Coord2);
+
+/**
+ * screen_dot_draw(Coord) - Plot a mode 0 pixel
+ */
+void screen_dot_draw(padPt* Coord);
+
+/**
+ * screen_line_draw(Coord1, Coord2) - Draw a mode 1 line
+ */
+void screen_line_draw(padPt* Coord1, padPt* Coord2);
+
+/**
+ * screen_char_draw(Coord, ch, count) - Output buffer from ch* of length count as PLATO characters
+ */
+void screen_char_draw(padPt* Coord, unsigned char* ch, unsigned char count);
+
+/**
+ * screen_tty_char - Called to plot chars when in tty mode
+ */
+void screen_tty_char(padByte theChar);
+
+/**
+ * screen_done()
+ * Close down TGI
+ */
+void screen_done(void);
+
+#endif /* SCREEN_H */
diff --git a/Applications/plato/screen_base.c b/Applications/plato/screen_base.c
new file mode 100644 (file)
index 0000000..133701f
--- /dev/null
@@ -0,0 +1,439 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * screen_base.c - Display output functions (base)
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include "screen.h"
+#include "protocol.h"
+#include "io.h"
+
+uint8_t CharWide=8;
+uint8_t CharHigh=16;
+padPt TTYLoc;
+uint8_t pal[2];
+
+extern padBool FastText; /* protocol.c */
+
+#ifndef __ATARI__
+extern unsigned short scalex[];
+extern unsigned short scaley[];
+#endif
+
+extern uint8_t font[];
+extern uint8_t fontm23[];
+extern uint16_t fontptr[];
+extern uint8_t FONT_SIZE_X;
+extern uint8_t FONT_SIZE_Y;
+
+extern void (*io_recv_serial_flow_on)(void);
+extern void (*io_recv_serial_flow_off)(void);
+
+// Atari uses fast frac multiplies to save memory
+#ifdef __ATARI__
+extern uint16_t mul0625(uint16_t val);
+extern uint16_t mul0375(uint16_t val);
+#endif
+
+/*
+ *     Silly functions to get us going
+ */
+
+static uint8_t pen;
+
+static void tgi_init(void)
+{
+}
+
+static void tgi_done(void)
+{
+}
+
+static void tgi_setpalette(const unsigned char *palette)
+{
+}
+
+static void tgi_clear(void)
+{
+//  printf("[CLR]");
+  printf("\033[0;0H\033[J");
+  fflush(stdout);
+}
+
+static void tgi_setcolor(unsigned char c)
+{
+  pen = c;
+}
+
+static void tgi_setpixel(int x, int y)
+{
+  printf("\033[%d;%dH%c", y, x, " #"[pen]);
+//  printf("[%d,%d->%d]", x, y, pen);
+  fflush(stdout);
+}
+
+static void tgi_bar(int x1, int y1, int x2, int y2)
+{
+  int x,y;
+  for (y = y1; y < y2; y++) {
+    printf("\033[%d;%dH", y, x1);
+    if (pen)
+      for(x = x1; x < x2; x++)
+        putchar('#');
+    else
+      for(x = x1; x < x2; x++)
+        putchar(' ');
+  }
+  fflush(stdout);
+//  printf("[R %d,%d,%d,%d->%d]", x1, y1, x2,y2, pen);
+}
+
+static void tgi_line(int x1, int y1, int x2, int y2)
+{
+   int dx =  abs(x2-x1), sx = x1<x2 ? 1 : -1;
+   int dy = -abs(y2-y1), sy = y1<y2 ? 1 : -1; 
+   int err = dx+dy, e2; /* error value e_xy */
+   for(;;){  /* loop */
+      tgi_setpixel(x1,y1);
+      if (x1==x2 && y1==y2) break;
+      e2 = 2*err;
+      if (e2 >= dy) { err += dy; x1 += sx; } /* e_xy+e_x > 0 */
+      if (e2 <= dx) { err += dx; y1 += sy; } /* e_xy+e_y < 0 */
+   }
+
+//  printf("[L %d,%d,%d,%d->%d]", x1, y1, x2,y2, pen);
+}
+
+/**
+ * screen_init() - Set up the screen
+ */
+void screen_init(void)
+{
+  screen_load_driver();
+  tgi_init();
+  screen_init_hook();
+  screen_update_colors();
+  tgi_setpalette(pal);
+  tgi_clear();
+}
+
+/**
+ * screen_clear - Clear the screen
+ */
+void screen_clear(void)
+{
+  tgi_clear();
+}
+
+/**
+ * screen_block_draw(Coord1, Coord2) - Perform a block fill from Coord1 to Coord2
+ */
+void screen_block_draw(padPt* Coord1, padPt* Coord2)
+{
+  if (CurMode==ModeErase || CurMode==ModeInverse)
+    tgi_setcolor(0);
+  else
+    tgi_setcolor(1);
+
+#ifdef __ATARI__
+  tgi_bar(mul0625(Coord1->x),mul0375(Coord1->y^0x1FF),mul0625(Coord2->x),mul0375(Coord2->y^0x1FF));
+#else
+  tgi_bar(scalex[Coord1->x],scaley[Coord1->y],scalex[Coord2->x],scaley[Coord2->y]);
+#endif
+  
+}
+
+/**
+ * screen_dot_draw(Coord) - Plot a mode 0 pixel
+ */
+void screen_dot_draw(padPt* Coord)
+{
+  if (CurMode==ModeErase || CurMode==ModeInverse)
+    tgi_setcolor(0);
+  else
+    tgi_setcolor(1);
+#ifdef __ATARI__
+  tgi_setpixel(mul0625(Coord->x),mul0375(Coord->y^0x1FF));
+#else
+  tgi_setpixel(scalex[Coord->x],scaley[Coord->y]);
+#endif
+}
+
+/**
+ * screen_line_draw(Coord1, Coord2) - Draw a mode 1 line
+ */
+void screen_line_draw(padPt* Coord1, padPt* Coord2)
+{
+#ifdef __ATARI__
+  uint16_t x1=mul0625(Coord1->x);
+  uint16_t x2=mul0625(Coord2->x);
+  uint16_t y1=mul0375(Coord1->y^0x1FF);
+  uint16_t y2=mul0375(Coord2->y^0x1FF);  
+#else
+  uint16_t x1=scalex[Coord1->x];
+  uint16_t x2=scalex[Coord2->x];
+  uint16_t y1=scaley[Coord1->y];
+  uint16_t y2=scaley[Coord2->y];
+#endif
+
+  if (CurMode==ModeErase || CurMode==ModeInverse)
+    tgi_setcolor(0);
+  else
+    tgi_setcolor(1);
+
+  tgi_line(x1,y1,x2,y2);
+}
+
+/**
+ * screen_char_draw(Coord, ch, count) - Output buffer from ch* of length count as PLATO characters
+ */
+void screen_char_draw(padPt* Coord, unsigned char* ch, unsigned char count)
+{
+  int16_t offset; /* due to negative offsets */
+  uint16_t x;      /* Current X and Y coordinates */
+  uint16_t y;
+  uint16_t* px;   /* Pointers to X and Y coordinates used for actual plotting */
+  uint16_t* py;
+  uint8_t i; /* current character counter */
+  uint8_t a; /* current character byte */
+  uint8_t j,k; /* loop counters */
+  int8_t b; /* current character row bit signed */
+  uint8_t width=FONT_SIZE_X;
+  uint8_t height=FONT_SIZE_Y;
+  uint16_t deltaX=1;
+  uint16_t deltaY=1;
+  uint8_t mainColor=1;
+  uint8_t altColor=0;
+  uint8_t *p;
+  uint8_t* curfont;
+  
+  switch(CurMem)
+    {
+    case M0:
+      curfont=font;
+      offset=-32;
+      break;
+    case M1:
+      curfont=font;
+      offset=64;
+      break;
+    case M2:
+      curfont=fontm23;
+      offset=-32;
+      break;
+    case M3:
+      curfont=fontm23;
+      offset=32;      
+      break;
+    }
+
+  if (CurMode==ModeRewrite)
+    {
+      altColor=0;
+    }
+  else if (CurMode==ModeInverse)
+    {
+      altColor=1;
+    }
+  
+  if (CurMode==ModeErase || CurMode==ModeInverse)
+    mainColor=0;
+  else
+    mainColor=1;
+
+  tgi_setcolor(mainColor);
+
+#ifdef __ATARI__
+  x=mul0625((Coord->x&0x1FF));
+  y=mul0375((Coord->y+14^0x1FF)&0x1FF);
+#else
+  x=scalex[(Coord->x&0x1FF)];
+  y=scaley[(Coord->y)+14&0x1FF];
+#endif
+  
+  if (FastText==padF)
+    {
+      goto chardraw_with_fries;
+    }
+
+  /* the diet chardraw routine - fast text output. */
+  
+  for (i=0;i<count;++i)
+    {
+      a=*ch;
+      ++ch;
+      a+=offset;
+      p=&curfont[fontptr[a]];
+      
+      for (j=0;j<FONT_SIZE_Y;++j)
+       {
+         b=*p;
+         
+         for (k=0;k<FONT_SIZE_X;++k)
+           {
+             if (b<0) /* check sign bit. */
+               {
+                 tgi_setcolor(mainColor);
+                 tgi_setpixel(x,y);
+               }
+
+             ++x;
+             b<<=1;
+           }
+
+         ++y;
+         x-=width;
+         ++p;
+       }
+
+      x+=width;
+      y-=height;
+    }
+
+  return;
+
+ chardraw_with_fries:
+  if (Rotate)
+    {
+      deltaX=-abs(deltaX);
+      width=-abs(width);
+      px=&y;
+      py=&x;
+    }
+    else
+    {
+      px=&x;
+      py=&y;
+    }
+  
+  if (ModeBold)
+    {
+      deltaX = deltaY = 2;
+      width<<=1;
+      height<<=1;
+    }
+  
+  for (i=0;i<count;++i)
+    {
+      a=*ch;
+      ++ch;
+      a+=offset;
+      p=&curfont[fontptr[a]];
+      for (j=0;j<FONT_SIZE_Y;++j)
+       {
+         b=*p;
+
+         if (Rotate)
+           {
+             px=&y;
+             py=&x;
+           }
+         else
+           {
+             px=&x;
+             py=&y;
+           }
+
+         for (k=0;k<FONT_SIZE_X;++k)
+           {
+             if (b<0) /* check sign bit. */
+               {
+                 tgi_setcolor(mainColor);
+                 if (ModeBold)
+                   {
+                     tgi_setpixel(*px+1,*py);
+                     tgi_setpixel(*px,*py+1);
+                     tgi_setpixel(*px+1,*py+1);
+                   }
+                 tgi_setpixel(*px,*py);
+               }
+             else
+               {
+                 if (CurMode==ModeInverse || CurMode==ModeRewrite)
+                   {
+                     tgi_setcolor(altColor);
+                     if (ModeBold)
+                       {
+                         tgi_setpixel(*px+1,*py);
+                         tgi_setpixel(*px,*py+1);
+                         tgi_setpixel(*px+1,*py+1);
+                       }
+                     tgi_setpixel(*px,*py); 
+                   }
+               }
+
+             x += deltaX;
+             b<<=1;
+           }
+
+         y+=deltaY;
+         x-=width;
+         ++p;
+       }
+
+      Coord->x+=width;
+      x+=width;
+      y-=height;
+    }
+
+  return;
+  
+}
+
+/**
+ * screen_tty_char - Called to plot chars when in tty mode
+ */
+void screen_tty_char(padByte theChar)
+{
+  if ((theChar >= 0x20) && (theChar < 0x7F)) {
+    screen_char_draw(&TTYLoc, &theChar, 1);
+    TTYLoc.x += CharWide;
+  }
+  else if ((theChar == 0x0b)) /* Vertical Tab */
+    {
+      TTYLoc.y += CharHigh;
+    }
+  else if ((theChar == 0x08) && (TTYLoc.x > 7))        /* backspace */
+    {
+      TTYLoc.x -= CharWide;
+      tgi_setcolor(0);
+#ifdef __ATARI__
+      tgi_bar(mul0625(TTYLoc.x),mul0375(TTYLoc.y^0x1FF),mul0625(TTYLoc.x+CharWide),mul0375(TTYLoc.y^0x1FF+CharHigh));
+#else
+      tgi_bar(scalex[TTYLoc.x],scaley[TTYLoc.y],scalex[TTYLoc.x+CharWide],scaley[TTYLoc.y+CharHigh]);
+#endif
+      tgi_setcolor(1);
+    }
+  else if (theChar == 0x0A)                    /* line feed */
+    TTYLoc.y -= CharHigh;
+  else if (theChar == 0x0D)                    /* carriage return */
+    TTYLoc.x = 0;
+  
+  if (TTYLoc.x + CharWide > 511) {     /* wrap at right side */
+    TTYLoc.x = 0;
+    TTYLoc.y -= CharHigh;
+  }
+  
+  if (TTYLoc.y < 0) {
+    tgi_clear();
+    TTYLoc.y=495;
+  }
+
+}
+
+/**
+ * screen_done()
+ * Close down TGI
+ */
+void screen_done(void)
+{
+  tgi_done();
+}
diff --git a/Applications/plato/terminal.c b/Applications/plato/terminal.c
new file mode 100644 (file)
index 0000000..f35d98b
--- /dev/null
@@ -0,0 +1,244 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * terminal.c - Terminal state functions
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <termios.h>
+#include "terminal.h"
+#include "screen.h"
+
+/**
+ * ASCII Features to return in Features
+ */
+#define ASC_ZFGT        0x01
+#define ASC_ZPCKEYS     0x02
+#define ASC_ZKERMIT     0x04
+#define ASC_ZWINDOW     0x08
+
+/**
+ * protocol.c externals
+ */
+extern CharMem CurMem;
+extern padBool TTY;
+extern padBool ModeBold;
+extern padBool Rotate;
+extern padBool Reverse;
+extern DispMode CurMode;
+extern padBool FlowControl;
+
+/**
+ * screen.c externals
+ */
+extern uint8_t CharWide;
+extern uint8_t CharHigh;
+extern padPt TTYLoc;
+
+extern uint8_t already_started;
+
+/**
+ * terminal_init()
+ * Initialize terminal state
+ */
+
+static struct termios saved_term;
+
+void exit_cleanup(void)
+{
+       tcsetattr(0, TCSADRAIN, &saved_term);
+}
+
+void cleanup(int sig)
+{
+       exit(1);
+}
+
+void terminal_init(void)
+{
+       struct termios term;
+
+       if (tcgetattr(0, &term) == 0) {
+               memcpy(&saved_term, &term, sizeof(saved_term));
+               atexit(exit_cleanup);
+               signal(SIGINT, cleanup);
+               signal(SIGQUIT, cleanup);
+               signal(SIGPIPE, cleanup);
+               term.c_lflag &= ~(ICANON | ECHO);
+               term.c_cc[VMIN] = 0;
+               term.c_cc[VTIME] = 1;
+               term.c_cc[VINTR] = 0;
+               term.c_cc[VSUSP] = 0;
+               term.c_cc[VSTOP] = 0;
+               tcsetattr(0, TCSADRAIN, &term);
+       }
+       terminal_set_tty();
+}
+
+/**
+ * terminal_initial_position()
+ * Set terminal initial position after splash screen.
+ */
+void terminal_initial_position(void)
+{
+       TTYLoc.x = 0;
+       TTYLoc.y = 100;         // Right under splashscreen.
+}
+
+/**
+ * terminal_set_tty(void) - Switch to TTY mode
+ */
+void terminal_set_tty(void)
+{
+       if (already_started)
+               screen_clear();
+       TTY = true;
+       ModeBold = padF;
+       Rotate = padF;
+       Reverse = padF;
+       CurMem = M0;
+       /* CurMode=ModeRewrite; */
+       CurMode = ModeWrite;    /* For speed reasons. */
+       CharWide = 8;
+       CharHigh = 16;
+       TTYLoc.x = 0;           // leftmost coordinate on screen
+       TTYLoc.y = 495;         // Top of screen - one character height
+}
+
+/**
+ * terminal_set_plato(void) - Switch to PLATO mode
+ */
+void terminal_set_plato(void)
+{
+       TTY = false;
+       screen_clear();
+}
+
+/**
+ * terminal_get_features(void) - Inquire about terminal ASCII features
+ */
+uint8_t terminal_get_features(void)
+{
+       return ASC_ZFGT;        /* This terminal can do Fine Grained Touch (FGT) */
+}
+
+/**
+ * terminal_get_type(void) - Return the appropriate terminal type
+ */
+uint8_t terminal_get_type(void)
+{
+       return 12;              /* ASCII terminal type */
+}
+
+/**
+ * terminal_get_subtype(void) - Return the appropriate terminal subtype
+ */
+uint8_t terminal_get_subtype(void)
+{
+       return 1;               /* ASCII terminal subtype IST-III */
+}
+
+/**
+ * terminal_get_load_file(void) - Return the appropriate terminal loadfile (should just be 0)
+ */
+uint8_t terminal_get_load_file(void)
+{
+       return 0;               /* This terminal does not load its resident from the PLATO system. */
+}
+
+/**
+ * terminal_get_configuration(void) - Return the terminal configuration
+ */
+uint8_t terminal_get_configuration(void)
+{
+       return 0x40;            /* Touch panel is present. */
+}
+
+/**
+ * terminal_get_char_address(void) - Return the base address of the character set.
+ */
+uint16_t terminal_get_char_address(void)
+{
+       return 0x3000;          /* What the? Shouldn't this be 0x3800? */
+}
+
+/**
+ * terminal_mem_read - Read a byte of program memory.
+ * not needed for our terminal, but must
+ * be decoded.
+ */
+padByte terminal_mem_read(padWord addr)
+{
+       return (0xFF);
+}
+
+/**
+ * terminal_mem_load - Write a byte to non-character memory.
+ * not needed for our terminal, but must be decoded.
+ */
+void terminal_mem_load(padWord addr, padWord value)
+{
+       /* Not Implemented */
+}
+
+/**
+ * Mode5, 6, and 7 are basically stubbed.
+ */
+void terminal_mode_5(padWord value)
+{
+}
+
+void terminal_mode_6(padWord value)
+{
+}
+
+void terminal_mode_7(padWord value)
+{
+}
+
+/**
+ * terminal_ext_allow - External Input allowed. Not implemented.
+ */
+void terminal_ext_allow(padBool allow)
+{
+       /* Not Implemented */
+}
+
+/**
+ * terminal_set_ext_in - Set which device to get input from.
+ * Not implemented
+ */
+void terminal_set_ext_in(padWord device)
+{
+}
+
+/**
+ * terminal_set_ext_out - Set which device to send external data to.
+ * Not implemented
+ */
+void terminal_set_ext_out(padWord device)
+{
+}
+
+/**
+ * terminal_ext_in - get an external input from selected device.
+ * Not implemented.
+ */
+padByte terminal_ext_in(void)
+{
+       return 0;
+}
+
+/**
+ * terminal_ext_out - Send an external output to selected device
+ * Not implemented.
+ */
+void terminal_ext_out(padByte value)
+{
+}
diff --git a/Applications/plato/terminal.h b/Applications/plato/terminal.h
new file mode 100644 (file)
index 0000000..1e82ac4
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * terminal.c - Terminal state functions
+ */
+
+#ifndef TERMINAL_H
+#define TERMINAL_H
+
+#include "protocol.h"
+
+/**
+ * terminal_init()
+ * Initialize terminal state
+ */
+void terminal_init(void);
+
+/**
+ * terminal_initial_position()
+ * Set terminal initial position after splash screen.
+ */
+void terminal_initial_position(void);
+
+/**
+ * terminal_set_tty(void) - Switch to TTY mode
+ */
+void terminal_set_tty(void);
+
+/**
+ * terminal_set_plato(void) - Switch to PLATO mode
+ */
+void terminal_set_plato(void);
+
+/**
+ * terminal_get_features(void) - Inquire about terminal ASCII features
+ */
+uint8_t terminal_get_features(void);
+
+/**
+ * terminal_get_type(void) - Return the appropriate terminal type
+ */
+uint8_t terminal_get_type(void);
+
+/**
+ * terminal_get_subtype(void) - Return the appropriate terminal subtype
+ */
+uint8_t terminal_get_subtype(void);
+
+/**
+ * terminal_get_load_file(void) - Return the appropriate terminal loadfile (should just be 0)
+ */
+uint8_t terminal_get_load_file(void);
+
+/**
+ * terminal_get_configuration(void) - Return the terminal configuration
+ */
+uint8_t terminal_get_configuration(void);
+
+/**
+ * terminal_get_char_address(void) - Return the base address of the character set.
+ */
+uint16_t terminal_get_char_address(void);
+
+/**
+ * terminal_mem_read - Read a byte of program memory.
+ * not needed for our terminal, but must
+ * be decoded.
+ */
+padByte terminal_mem_read(padWord addr);
+
+/**
+ * terminal_mem_load - Write a byte to non-character memory.
+ * not needed for our terminal, but must be decoded.
+ */
+void terminal_mem_load(padWord addr, padWord value);
+
+/**
+ * terminal_char_load - Store a character into the user definable
+ * character set.
+ */
+void terminal_char_load(padWord charnum, charData theChar);
+
+/**
+ * terminal_mode_5, 6, and 7 are basically stubbed.
+ */
+void terminal_mode_5(padWord value);
+void terminal_mode_6(padWord value);
+void terminal_mode_7(padWord value);
+
+/**
+ * terminal_ext_allow - External Input allowed. Not implemented.
+ */
+void terminal_ext_allow(padBool allow);
+
+/**
+ * terminal_set_ext_in - Set which device to get input from.
+ * Not implemented
+ */
+void terminal_set_ext_in(padWord device);
+
+/**
+ * terminal_set_ext_out - Set which device to send external data to.
+ * Not implemented
+ */
+void terminal_set_ext_out(padWord device);
+
+/**
+ * terminal_ext_in - get an external input from selected device.
+ * Not implemented.
+ */
+padByte terminal_ext_in(void);
+
+/**
+ * terminal_ext_out - Send an external output to selected device
+ * Not implemented.
+ */
+void terminal_ext_out(padByte value);
+
+#endif
diff --git a/Applications/plato/tools/Makefile b/Applications/plato/tools/Makefile
new file mode 100644 (file)
index 0000000..6e5fe97
--- /dev/null
@@ -0,0 +1,14 @@
+
+all: mk_scale mk_font mk_ascii_key_h
+
+mk_font: mk_font.c
+       $(CC) -o mk_font mk_font.c
+
+mk_scale: mk_scale.c
+       $(CC) -lm -o mk_scale mk_scale.c
+
+mk_ascii_key_h: mk_ascii_key_h.c
+       $(CC) -o mk_ascii_key_h mk_ascii_key_h.c
+
+clean:
+       rm -f *~ mk_scale mk_font mk_ascii_key_h
diff --git a/Applications/plato/tools/mk_ascii_key_h.c b/Applications/plato/tools/mk_ascii_key_h.c
new file mode 100644 (file)
index 0000000..52ba910
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Tool to create initial key map for ASCII keyboards (apple II)
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes@gmail.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void main(void)
+{
+  unsigned int i=0;
+  printf("/**\n");
+  printf(" *\n");
+  printf(" * KEY_H generated by mk_ascii_key_h.c\n");
+  printf(" */\n");
+  printf("\n\n");
+
+  printf("unsigned char key_to_pkey[]={\n");
+
+  for (i=0;i<133;++i)
+    {
+      printf("    PKEY_NOKEY, /* %03d */\n",i);
+    }
+
+  printf("};\n\n");
+
+  /* printf("unsigned char esc_key_to_pkey[]={\n"); */
+
+  /* for (i=0;i<128;++i) */
+  /*   { */
+  /*     printf("    PKEY_NOKEY, /\* 0x%02x *\/\n",i);       */
+  /*   } */
+  
+  /* printf("};\n"); */
+  
+}
diff --git a/Applications/plato/tools/mk_font.c b/Applications/plato/tools/mk_font.c
new file mode 100644 (file)
index 0000000..9249046
--- /dev/null
@@ -0,0 +1,185 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[]) 
+{ 
+    int i=0;
+    printf("/* ! Autogenerated by tools/mk_font.c */\n\n"
+          "#ifndef FONT_H\n"
+          "#define FONT_H\n\n");
+
+    printf("unsigned char font[]={\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,    /* SPACE 0x20 */\n"
+  "0x40,0x40,0x40,0x00,0x40,0x00,    /* ! 0x21 */\n"
+  "0x50,0x50,0x00,0x00,0x00,0x00,    /* \" 0x22 */\n"
+  "0x50,0xF8,0x50,0xF8,0x50,0x00,    /* # 0x23 */\n"
+  "0x40,0xF0,0xC0,0x30,0xF0,0x20,    /* $ 0x24 */\n"
+  "0x90,0x20,0x20,0x40,0x90,0x00,    /* %% 0x25 */\n"
+  "0x40,0xA0,0x40,0xB0,0x50,0x00,    /* & 0x26 */\n"
+  "0x20,0x40,0x00,0x00,0x00,0x00,    /* ' 0x27 */\n"
+  "0x20,0x40,0x40,0x40,0x20,0x00,    /* ( 0x28 */\n"
+  "0x40,0x20,0x20,0x20,0x40,0x00,    /* ) 0x29 */\n"
+  "0x90,0x60,0xF0,0x60,0x90,0x00,    /* * 0x2a */\n"
+  "0x20,0x20,0xF8,0x20,0x20,0x00,    /* + 0x2b */\n"
+  "0x00,0x00,0x40,0x40,0x80,0x00,    /* , 0x2c */\n"
+  "0x00,0x00,0xF0,0x00,0x00,0x00,    /* - 0x2d */\n"
+  "0x00,0x00,0x00,0x40,0x40,0x00,    /* . 0x2e */\n"
+  "0x00,0x10,0x20,0x40,0x80,0x00,    /* / 0x2f */\n"
+  "0x60,0x90,0x90,0x90,0x60,0x00,    /* 0 0x30 */\n"
+  "0x20,0x60,0x20,0x20,0x70,0x00,    /* 1 0x31 */\n"
+  "0x60,0x90,0x20,0x40,0xF0,0x00,    /* 2 0x32 */\n"
+  "0xF0,0x10,0x20,0x10,0xE0,0x00,    /* 3 0x33 */\n"
+  "0x20,0x60,0xA0,0xF0,0x20,0x00,    /* 4 0x34 */\n"
+  "0xE0,0x80,0xE0,0x10,0xE0,0x00,    /* 5 0x35 */\n"
+  "0x60,0x80,0xE0,0x90,0xE0,0x00,    /* 6 0x36 */\n"
+  "0xF0,0x10,0x20,0x40,0x40,0x00,    /* 7 0x37 */\n"
+  "0x60,0x90,0x60,0x90,0x60,0x00,    /* 8 0x38 */\n"
+  "0x60,0x90,0x70,0x10,0xE0,0x00,    /* 9 0x39 */\n"
+  "0x00,0x40,0x00,0x40,0x00,0x00,    /* : 0x3a */\n"
+  "0x00,0x40,0x00,0x40,0x80,0x00,    /* ; 0x3b */\n"
+  "0x20,0x40,0x80,0x40,0x20,0x00,    /* < 0x3c */\n"
+  "0x00,0xF0,0x00,0xF0,0x00,0x00,    /* = 0x3d */\n"
+  "0x40,0x20,0x10,0x20,0x40,0x00,    /* > 0x3e */\n"
+  "0x60,0x90,0x20,0x00,0x40,0x00,    /* ? 0x3f */\n"
+  "0x60,0x90,0xB0,0x80,0x60,0x00,    /* @ 0x40 */\n"
+  "0x60,0x90,0xF0,0x90,0x90,0x00,    /* A 0x41 */\n"
+  "0xE0,0x90,0xE0,0x90,0xE0,0x00,    /* B 0x42 */\n"
+  "0x70,0x80,0x80,0x80,0x70,0x00,    /* C 0x43 */\n"
+  "0xE0,0x90,0x90,0x90,0xE0,0x00,    /* D 0x44 */\n"
+  "0xF0,0x80,0xE0,0x80,0xF0,0x00,    /* E 0x45 */\n"
+  "0xF0,0x80,0xE0,0x80,0x80,0x00,    /* F 0x46 */\n"
+  "0x60,0x80,0x90,0x90,0x70,0x00,    /* G 0x47 */\n"
+  "0x90,0x90,0xF0,0x90,0x90,0x00,    /* H 0x48 */\n"
+  "0xE0,0x40,0x40,0x40,0xE0,0x00,    /* I 0x49 */\n"
+  "0x10,0x10,0x10,0x90,0x60,0x00,    /* J 0x4a */\n"
+  "0x90,0xA0,0xC0,0xA0,0x90,0x00,    /* K 0x4b */\n"
+  "0x80,0x80,0x80,0x80,0xF0,0x00,    /* L 0x4c */\n"
+  "0x88,0xD8,0xA8,0x88,0x88,0x00,    /* M 0x4d */\n"
+  "0x90,0xD0,0xB0,0x90,0x90,0x00,    /* N 0x4e */\n"
+  "0xF0,0x90,0x90,0x90,0xF0,0x00,    /* O 0x4f */\n"
+  "0xE0,0x90,0xE0,0x80,0x80,0x00,    /* P 0x50 */\n"
+  "0xF0,0x90,0x90,0xB0,0xF8,0x00,    /* Q 0x51 */\n"
+  "0xE0,0x90,0xE0,0xA0,0x90,0x00,    /* R 0x52 */\n"
+  "0x70,0x80,0xE0,0x10,0xE0,0x00,    /* S 0x53 */\n"
+  "0xF8,0x20,0x20,0x20,0x20,0x00,    /* T 0x54 */\n"
+  "0x90,0x90,0x90,0x90,0xF0,0x00,    /* U 0x55 */\n"
+  "0x90,0x90,0x90,0x60,0x60,0x00,    /* V 0x56 */\n"
+  "0x88,0x88,0xA8,0xD8,0x88,0x00,    /* W 0x57 */\n"
+  "0x90,0x90,0x60,0x90,0x90,0x00,    /* X 0x58 */\n"
+  "0x90,0x90,0xE0,0x40,0x40,0x00,    /* Y 0x59 */\n"
+  "0xF0,0x10,0x20,0x40,0xF0,0x00,    /* Z 0x5a */\n"
+  "0x70,0x40,0x40,0x40,0x70,0x00,    /* [ 0x5b */\n"
+  "0x00,0x80,0x40,0x20,0x10,0x00,    /* \\ 0x5c */ \n"
+  "0x70,0x10,0x10,0x10,0x70,0x00,    /* ] 0x5d */\n"
+  "0x20,0x50,0x00,0x00,0x00,0x00,    /* CIRCUMFLEX ^ 0x5e*/\n"
+  "0x00,0x00,0x00,0x00,0x00,0xF0,    /* _ 0x5f */\n"
+  "0x40,0x20,0x00,0x00,0x00,0x00,    /* GRAVE ACCENT ` 0x60 */\n"
+  "0x00,0xC0,0x20,0xA0,0XF0,0x00,    /* a 0x61 */\n"
+  "0x80,0xE0,0x90,0x90,0xE0,0x00,    /* b 0x62 */\n"
+  "0x00,0x60,0x80,0x80,0x60,0x00,    /* c 0x63 */\n"
+  "0x10,0x70,0x90,0x90,0x70,0x00,    /* d 0x64 */\n"
+  "0x00,0x60,0xB0,0x80,0x60,0x00,    /* e 0x65 */\n"
+  "0x60,0x80,0xE0,0x80,0x80,0x00,    /* f 0x66 */\n"
+  "0x00,0x60,0x90,0xF0,0x10,0x60,    /* g 0x67 */\n"
+  "0x80,0xE0,0x90,0x90,0x90,0x00,    /* h 0x68 */\n"
+  "0x40,0x00,0x40,0x40,0x40,0x00,    /* i 0x69 */\n"
+  "0x20,0x00,0x20,0x20,0x20,0xC0,    /* j 0x6a */\n"
+  "0x80,0xA0,0xC0,0xA0,0x90,0x00,    /* k 0x6b */\n"
+  "0x40,0x40,0x40,0x40,0x40,0x00,    /* l 0x6c */\n"
+  "0x00,0x90,0xF0,0x90,0x90,0x00,    /* m 0x6d */\n"
+  "0x00,0xE0,0x90,0x90,0x90,0x00,    /* n 0x6e */\n"
+  "0x00,0x60,0x90,0x90,0x60,0x00,    /* o 0x6f */\n"
+  "0x00,0xE0,0x90,0x90,0xE0,0x80,    /* p 0x70 */\n"
+  "0x00,0x70,0x90,0x90,0x70,0x10,    /* q 0x71 */\n"
+  "0x00,0x70,0x40,0x40,0x40,0x00,    /* r 0x72 */\n"
+  "0x00,0x70,0xC0,0x30,0xE0,0x00,    /* s 0x73 */\n"
+  "0x40,0xE0,0x40,0x40,0x60,0x00,    /* t 0x74 */\n"
+  "0x00,0x90,0x90,0x90,0x70,0x00,    /* u 0x75 */\n"
+  "0x00,0x90,0xA0,0xA0,0x40,0x00,    /* v 0x76 */\n"
+  "0x00,0x90,0x90,0xF0,0x90,0x00,    /* w 0x77 */\n"
+  "0x00,0x90,0x60,0x60,0x90,0x00,    /* x 0x78 */\n"
+  "0x00,0x90,0x90,0x70,0x10,0x60,    /* y 0x79 */\n"
+  "0x00,0xF0,0x20,0x40,0xF0,0x00,    /* z 0x7a */\n"
+  "0x60,0x40,0x80,0x40,0x60,0x00,    /* { 0x7b */\n"
+  "0x20,0x20,0x20,0x20,0x20,0x20,    /* | 0x7c */\n"
+  "0xC0,0x40,0x20,0x40,0xC0,0x00,    /* } 0x7d */\n"
+  "0x00,0x00,0x68,0xB0,0x00,0x00,    /* ~ 0x7e */\n"
+  "0x00,0x70,0x50,0x70,0x00,0x00,    /* BOX 0x7f */\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,    /* SPACE 0xa0 */\n"
+  "0x00,0x10,0x20,0x40,0x80,0x00,    /* / 0xa1 */\n"
+  "0x00,0xF0,0x00,0xF0,0x00,0xF0,    /* EQUIVALENT 0xa2 */\n"
+  "0x00,0x00,0x00,0x00,0x68,0xB0,    /* LOW TILDE 0xa3 */\n"
+  "0x20,0x70,0x80,0x70,0x20,0x00,    /* ASSIGN 0xa4 */\n"
+  "0x20,0xF0,0x20,0xF0,0x40,0x00,    /* NOT EQUAL 0xa5 */\n"
+  "0x00,0x20,0x70,0x20,0x20,0x00,    /* UP ARROW 0xa6 */\n"
+  "0x00,0x00,0x20,0xF0,0x20,0x00,    /* RIGHT ARROW 0xa7 */\n"
+  "0x00,0x20,0x20,0x70,0x20,0x00,    /* DOWN ARROW 0xa8 */\n"
+  "0x00,0x00,0x40,0xF0,0x40,0x00,    /* LEFT ARROW 0xa9 */\n"
+  "0x00,0x50,0x20,0x50,0x00,0x00,    /* MULTIPLY 0xaa */\n"
+  "0xF0,0x80,0x60,0x80,0xF0,0x00,    /* SIGMA 0xab */\n"
+  "0x00,0x20,0x50,0x88,0xF8,0x00,    /* DELTA 0xac*/\n"
+  "0x00,0x90,0x90,0x60,0x00,0x00,    /* UNION 0xad*/\n"
+  "0x00,0x60,0x90,0x90,0x00,0x00,    /* INTERSECT 0xae*/\n"
+  "0x00,0x60,0x00,0x60,0x00,0x00,    /* DIVIDE 0xaf */\n"
+  "0x00,0x50,0xA0,0x70,0x00,0x00,    /* ALPHA 0xb0 */\n"
+  "0x20,0x50,0xA0,0x90,0xE0,0x80,    /* BETA 0xb1 */\n"
+  "0x20,0x40,0x20,0x50,0x70,0x00,    /* DELTA 0xb2 */\n"
+  "0x80,0x40,0x20,0x50,0x90,0x00,    /* LAMBDA 0xb3 */\n"
+  "0x00,0x00,0x50,0x50,0x60,0x80,    /* MU 0xb4 */\n"
+  "0x08,0x78,0xD0,0x50,0x50,0x00,    /* PI 0xb5 */\n"
+  "0x00,0x20,0x50,0x50,0xA0,0x80,    /* RHO 0xb6 */\n"
+  "0x30,0x40,0xA0,0xA0,0x40,0x00,    /* SIGMA 0xb7 */\n"
+  "0x00,0x00,0x90,0xB0,0x60,0x00,    /* OMEGA 0xb8 */\n"
+  "0x20,0x40,0x80,0x40,0x20,0xE0,    /* LESS THAN OR EQUAL 0xb9 */\n"
+  "0x80,0x40,0x20,0x40,0x80,0xE0,    /* GREATER THAN OR EQUAL 0xba */\n"
+  "0x20,0x50,0x70,0x50,0x20,0x00,    /* THETA 0xbb */\n"
+  "0x30,0x60,0xA0,0x60,0x30,0x00,    /* l-embed 0xbc */\n"
+  "0x00,0x60,0x90,0x60,0x00,0x00,    /* DEGREE 0xbd */\n"
+  "0xC0,0x60,0x50,0x60,0xC0,0x00,    /* r-embed 0xbe */\n"
+  "0xC0,0xA0,0x50,0x50,0xA0,0xC0,    /* ANSWER ARROW 0xbf */\n"
+  "0xF8,0x20,0x40,0x40,0x20,0xF8,    /* COPYRIGHT 0xc0 */\n"
+  "0x50,0x00,0x00,0x00,0x00,0x00,    /* DIERESIS 0xc1 */\n"
+  "0x00,0x70,0x50,0x70,0x00,0x00,    /* BOX 0xc2 */\n"
+  "0x00,0x00,0x20,0x00,0x00,0x00,    /* INTERPUNCT 0xc3 */\n"
+  "0x20,0x70,0xF8,0x70,0x20,0x00,    /* DIAMOND 0xc4 */\n"
+  "0x00,0x50,0x20,0x50,0x00,0x00,    /* MULTIPLY 0xc5 */\n"
+  "0x10,0x20,0x00,0x00,0x00,0x00,    /* ACUTE ACCENT 0xc6 */\n"
+  "0x00,0x00,0x00,0x08,0x10,0x00,    /* CEDILLA 0xc7 */\n"
+  "0x10,0x20,0x00,0x00,0x00,0x00,    /* HACEK 0xc8 */\n"
+  "0x20,0x70,0xF8,0x70,0x20,0x00,    /* DIAMOND 0xc9 */\n"
+  "0x20,0x20,0x20,0x20,0x20,0x20,    /* | 0xca */\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00,\n"
+  "0x00,0x00,0x00,0x00,0x00,0x00\n"
+    "};\n\n");
+
+
+    printf("unsigned int fontptr[]={\n");
+    for (i=0;i<160;i++) { 
+       printf("%d,",i*12);
+       if (i % 8 == 7 )
+           printf("\n");
+    } 
+    printf("};\n\n"
+          "#endif /* FONT_H */\n");
+
+    return 0;
+}
diff --git a/Applications/plato/tools/mk_scale.c b/Applications/plato/tools/mk_scale.c
new file mode 100644 (file)
index 0000000..eef4041
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+int main(int argc, char *argv[]) 
+{ 
+    int i=0;
+    double sx;
+    double sy;
+    double zx;
+    double zy;
+    int rx;
+    int ry;
+
+    if (argc < 3) {
+       fprintf(stderr,"usage: mk_scale x y\n");
+       return 1;
+    }
+
+    sx = strtod(argv[1],NULL) / 512;
+    sy = strtod(argv[2],NULL) / 512;
+    rx = atoi(argv[1])-1;
+    ry = atoi(argv[2])-1;
+    zx = 512 / strtod(argv[1],NULL);
+    zy = 512 / strtod(argv[2],NULL);
+    
+    printf(
+          "/* ! Autogenerated by tools/mk_scale.c */\n\n"
+          "#ifndef SCALE_H\n"
+          "#define SCALE_H\n\n"
+          "unsigned short scalex[]={\n");
+
+    for (i=0;i<512;i++) { 
+       printf("%d,",(int)ceil(i*sx));
+       if( i % 8 == 7 )
+           printf("\n");
+    }
+    printf("};\n\n");
+    
+    printf("unsigned short scaley[]={\n");
+    for (i=511;i>=0;i-=1) {
+       printf("%d,",(int)ceil(i*sy));
+       if (i % 8 == 0 )
+           printf("\n");
+    } 
+    printf("};\n\n");
+
+    printf("unsigned short scaletx[]={\n");
+
+    for (i=0;i<rx;i++) { 
+       printf("%d,",(int)ceil(i*zx));
+       if( i % 8 == 7 )
+           printf("\n");
+    }
+    printf("};\n\n");
+
+    printf("unsigned short scalety[]={\n");
+    for (i=ry;i>=0;i-=1) {
+       printf("%d,",(int)ceil(i*zy));
+       if (i % 8 == 0 )
+           printf("\n");
+    } 
+    printf("};\n\n");
+
+    printf("#endif  /* scale_h */\n");
+    
+    return 0;
+}
diff --git a/Applications/plato/touch.h b/Applications/plato/touch.h
new file mode 100644 (file)
index 0000000..9f2a492
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * touch.c - Touchscreen functions
+ */
+
+#ifndef TOUCH_H
+#define TOUCH_H
+
+#include "protocol.h"
+
+/**
+ * touch_init() - Set up touch screen
+ */
+void touch_init(void);
+
+/**
+ * touch_main() - Main loop for touch screen
+ */
+void touch_main(void);
+
+/**
+ * touch_allow - Set whether touchpanel is active or not.
+ */
+void touch_allow(padBool allow);
+
+/**
+ * handle_mouse - Process mouse events and turn into scaled touch events
+ */
+void handle_mouse(void);
+
+/**
+ * touch_hide() - hide the mouse cursor
+ */
+void touch_hide(void);
+
+/**
+ * touch_done() - Stop the mouse driver
+ */
+void touch_done(void);
+
+#endif /* TOUCH_H */
diff --git a/Applications/plato/touch_base.c b/Applications/plato/touch_base.c
new file mode 100644 (file)
index 0000000..4098204
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * PLATOTerm64 - A PLATO Terminal for the Commodore 64
+ * Based on Steve Peltz's PAD
+ * 
+ * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
+ *
+ * touch.c - Touchscreen functions
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include "touch.h"
+
+static padBool TouchActive;
+
+static uint16_t screen_w;
+static uint16_t screen_h;
+static uint8_t mouse_present=false;
+static uint8_t mou_res=0;
+
+extern uint16_t scaletx[];
+extern uint16_t scalety[];
+
+/**
+ * touch_init() - Set up touch screen
+ */
+void touch_init(void)
+{
+}
+
+/**
+ * touch_allow - Set whether touchpanel is active or not.
+ */
+void touch_allow(padBool allow)
+{
+  TouchActive=allow;
+}
+
+/**
+ * touch_main - Process mouse events and turn into scaled touch events
+ */
+void touch_main(void)
+{
+}
+
+/**
+ * touch_hide() - hide the mouse cursor
+ */
+void touch_hide(void)
+{
+}
+
+/**
+ * touch_done() - Stop the mouse driver
+ */
+void touch_done(void)
+{
+}