diff --git a/defs.frp b/defs.frp index e38ff3b..47b8bf5 100755 --- a/defs.frp +++ b/defs.frp @@ -69,11 +69,3 @@ key const sp begin dup @ not while suspend repeat ( wait for mail ) dup @ 0 rot ! ; - -: start-repl activate - stdout - ' log-emit task-echo ! - begin receive loadstring again ; -task const REPL - -REPL start-repl \ No newline at end of file diff --git a/game.exe b/game.exe index 2fb1c44..309ff68 100755 Binary files a/game.exe and b/game.exe differ diff --git a/game.frp b/game.frp new file mode 100755 index 0000000..89c3051 --- /dev/null +++ b/game.frp @@ -0,0 +1,7 @@ +: start-repl activate + ' seremit task-emit ! + ' log-emit task-echo ! + begin receive loadstring again ; +task const REPL + +REPL start-repl diff --git a/game.prj b/game.prj index e87f257..71e7b98 100755 Binary files a/game.prj and b/game.prj differ diff --git a/serial.c b/serial.c index 5c2050f..d40ce44 100755 --- a/serial.c +++ b/serial.c @@ -1,3 +1,4 @@ +#include #include #include "serial.h" @@ -6,18 +7,72 @@ int comport = 0; #define SER_LATCH_LO 0 #define SER_LATCH_HI 1 #define SER_TX 0 +#define SER_RX 0 +#define SER_IER 1 #define SER_LCR 3 +#define SER_MCR 4 #define SER_LSR 5 +#define PIC1 0x20 +#define OCW1 0x21 +#define PIC_EOI 0x20 + +// COM1 - IRQ4, COM2 - IRQ3, COM3 - IRQ4, COM4 - IRQ3 +#define SER_IRQ(port) (4 - (port % 2)) +#define SER_VECTOR(irq) (0x08 + (irq)) + +static char readbuf[SER_READ_BUFFER_SIZE]; +static int ireadbufStart = 0; +static volatile int ireadbufLim = 0; +static int irq = 0; + +static void interrupt (*oldSerISR)() = NULL; + +static void interrupt ser_isr() { + while (inp(comport + SER_LSR) & 0x01) { + readbuf[ireadbufLim] = inp(comport + SER_RX); + ireadbufLim = (ireadbufLim + 1) % SER_READ_BUFFER_SIZE; + } + outp(PIC1, PIC_EOI); +} + +static void ser_cleanup() { + if (irq) { + int ocw = inp(OCW1) | (1 << irq); + outp(OCW1, ocw); + setvect(SER_VECTOR(irq), oldSerISR); + irq = 0; + } +} + void ser_init(int port, int baudrate, int protocol) { int far *comport_addr = MK_FP(0x0040, 0x0000); - int lcr; + int lcr, ocw; comport = comport_addr[port]; + irq = SER_IRQ(port); outp(comport + SER_LCR, 0x80); outp(comport + SER_LATCH_HI, baudrate >> 8); outp(comport + SER_LATCH_LO, baudrate & 0xff); outp(comport + SER_LCR, protocol); + outp(comport + SER_MCR, 0x0b); + + oldSerISR = getvect(SER_VECTOR(irq)); + setvect(SER_VECTOR(irq), ser_isr); + ocw = inp(OCW1) & ~(1 << irq); + outp(OCW1, ocw); + outp(comport + SER_IER, 0x01); + + atexit(ser_cleanup); +} + +int ser_poll() { + int result = SER_NODATA; + if (ireadbufStart != ireadbufLim) { + result = readbuf[ireadbufStart]; + ireadbufStart = (ireadbufStart + 1) % SER_READ_BUFFER_SIZE; + } + return result; } void ser_write_byte(char byte) { diff --git a/serial.h b/serial.h index 1bf917a..361cb38 100755 --- a/serial.h +++ b/serial.h @@ -19,6 +19,10 @@ #define BAUD_57600 0x0002 #define BAUD_115200 0x0001 +#define SER_READ_BUFFER_SIZE 0x200 +#define SER_NODATA -1 + void ser_init(int port, int baudrate, int protocol); +int ser_poll(); void ser_write_byte(char byte); void ser_write(char *str); diff --git a/testbed.c b/testbed.c index f511b93..e0e4b13 100755 --- a/testbed.c +++ b/testbed.c @@ -148,17 +148,83 @@ void overworldThink() { scroll(game.player.x - 152, game.player.y - 92); } -int main() { +int main3() { f_init(); f_repl(); + return 0; } -int main2() { + +void f_seremit() { + ser_write_byte(TOP().i); + if (TOP().i == '\n') { + ser_write_byte('\r'); + } + DROP(1); +} + +void f_keyWasPressed() { + TOP().i = keyWasPressed(TOP().i); +} +void f_keyIsDown() { + TOP().i = keyIsDown(TOP().i); +} +void f_drawSprite() { // ( x y sprite -- ) + drawSprite(&sprites[TOP().i * SPRITE_STRIDE], ST2().i, ST1().i); + DROP(3); +} +void f_scroll() { // ( x y -- ) + scroll(ST1().i, TOP().i); +} + +void game_f_init() { + f_init(); + CDEF("seremit", f_seremit); + CDEF("key-pressed", f_keyWasPressed); + CDEF("key-down", f_keyIsDown); + CDEF("sprite", f_drawSprite); + CDEF("scroll", f_scroll); + CDEF("draw", drawScreen); + + f_loadfile("game.frp"); +} + +void f_poll() { + static char line[256] = { 0 }; + + int i = strlen(line); + int value; + for (value = ser_poll(); value != SER_NODATA; value = ser_poll()) { + if (value == '\b' || value == 127) { + i --; + } else { + line[i] = value; + i ++; + } + line[i] = '\0'; + ser_write_byte(value); // echo + + if (value == '\r') { + line[i - 1] = '\n'; + ser_write_byte('\n'); + PUSHS(line); + f_runstring("REPL send"); + f_taskloop(); + i = 0; + line[i] = '\0'; + } + } +} + +int main() { game_init(); + game_f_init(); + ser_init(SER_COM2, BAUD_19200, SER_8N1); - ser_write("JORTS QUEST DEBUG OUTPUT\r\n"); while (!keyIsDown(K_ESC)) { kbd_debounce(); + f_poll(); + if (game.state == STATE_MAP) { overworldThink(); } else if (game.state == STATE_DIALOG) {