Forp is now Jorth ( Jean Forth) - hook timer interrupt and expose ticks

This commit is contained in:
Jeremy Penner 2019-02-09 11:48:40 -05:00
parent ca25a4578e
commit 6552c1498b
10 changed files with 178 additions and 49 deletions

View file

@ -1,5 +1,5 @@
: stdout ' putc task-emit ! ; : stdout ' putc task-emit ! ;
s" forp.log" open const LOGFILE s" jorth.log" open const LOGFILE
: log-emit LOGFILE fputc ; : log-emit LOGFILE fputc ;
2 const cell 2 const cell
@ -25,6 +25,9 @@ key const sp
: ( begin key ')' = until ; immediate : ( begin key ')' = until ; immediate
' cells @ const docolon ( get the colon execution token )
: :noname here docolon , ] ;
: 2dup over over ; : 2dup over over ;
: decompile : decompile

BIN
game.exe

Binary file not shown.

View file

@ -1,7 +0,0 @@
: start-repl activate
' seremit task-emit !
' log-emit task-echo !
begin receive loadstring again ;
task const REPL
REPL start-repl

37
game.jor Executable file
View file

@ -0,0 +1,37 @@
: blah
' seremit task-emit !
' log-emit task-echo ! ;
: start-repl activate blah
s" .:: J O R T H ( jean forth) ::." type cr
begin receive loadstring again ;
task const REPL
REPL start-repl
task const TEST
1 const ^ESC
28 const ^ENTER
29 const ^CTRL
56 const ^ALT
57 const ^SPACE
72 const ^UP
75 const ^LEFT
77 const ^RIGHT
80 const ^DOWN
: wait-key ( k -- ) begin dup key-pressed not while suspend repeat drop ;
: udelta ( u u -- u )
2dup u> if
swap -1 swap - + 1 +
else
swap -
then ;
: sleep ( count -- )
ticks swap begin over ticks udelta over u< while suspend repeat drop drop ;
: test TEST activate blah
^SPACE wait-key
s" SPACE" type
30 sleep
s" is big" type ;
test

BIN
game.prj

Binary file not shown.

View file

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include "forp.h" #include "jorth.h"
#include "serial.h"
#define TASK_REGISTER_SIZE 3 #define TASK_REGISTER_SIZE 3
#define TASK_USER_SIZE 8 #define TASK_USER_SIZE 8
@ -66,23 +67,27 @@ void f_running() {
PUSHCP(RUNNING); PUSHCP(RUNNING);
} }
#define BINOP(name, op) \ #define BINOP(name, type, op) \
void name() { \ void name() { \
cell r = TOP(); \ cell r = TOP(); \
DROP(1); \ DROP(1); \
TOP().i = TOP().i op r.i; \ TOP().type = TOP().type op r.type; \
} }
BINOP(f_add, +) BINOP(f_add, i, +)
BINOP(f_sub, -) BINOP(f_sub, i, -)
BINOP(f_mul, *) BINOP(f_mul, i, *)
BINOP(f_div, /) BINOP(f_div, i, /)
BINOP(f_eq, ==) BINOP(f_eq, i, ==)
BINOP(f_neq, !=) BINOP(f_neq, i, !=)
BINOP(f_ge, >=) BINOP(f_ge, i, >=)
BINOP(f_gt, >) BINOP(f_gt, i, >)
BINOP(f_lt, <) BINOP(f_lt, i, <)
BINOP(f_le, <=) BINOP(f_le, i, <=)
BINOP(f_uge, u, >=)
BINOP(f_ugt, u, >)
BINOP(f_ult, u, <)
BINOP(f_ule, u, <=)
void f_eq0() { void f_eq0() {
TOP().i = (TOP().i == 0); TOP().i = (TOP().i == 0);
@ -141,7 +146,7 @@ void f_rot() { // a b c -- b c a
ST2() = b; ST2() = b;
} }
void f_execute(); void f_cexecute();
void f_key_string() { void f_key_string() {
cell *INPUT = RUNNING + TASK_USER_KEYSRC; cell *INPUT = RUNNING + TASK_USER_KEYSRC;
@ -183,7 +188,7 @@ void f_key() {
if (!QUIET.i && echoword->p) { if (!QUIET.i && echoword->p) {
f_dup(); f_dup();
PUSHCP(echoword->p); PUSHCP(echoword->p);
f_execute(); f_cexecute();
} }
} }
@ -215,12 +220,16 @@ void f_emit() {
if (echoword->p) { if (echoword->p) {
f_dup(); f_dup();
PUSHCP(echoword->p); PUSHCP(echoword->p);
f_execute(); f_cexecute();
} }
if (emitword->p) { if (emitword->p) {
PUSHCP(emitword->p); PUSHCP(emitword->p);
f_execute(); f_cexecute();
} else {
DROP(1);
} }
} else {
DROP(1);
} }
} }
@ -251,6 +260,13 @@ void f_dot() {
f_puts(); f_puts();
} }
void f_udot() {
static char num[16];
sprintf(num, "%u ", TOP().i);
TOP().s = num;
f_puts();
}
void f_printstack() { void f_printstack() {
cell *v = RUNNING + STACK_OFFSET; cell *v = RUNNING + STACK_OFFSET;
while (v != stack) { while (v != stack) {
@ -295,27 +311,25 @@ void f_cdef() { // func name --
} }
void f_docolon(); void f_docolon();
// C code must always call a colon word through f_execute() // C code must always call a colon word through f_cexecute()
void f_execute() { void f_cexecute() {
cell oldW = W; cell oldW = W;
cell oldIP = IP; cell oldIP = IP;
cell retIP; cell retIP;
retIP.p = NULL; retIP.p = NULL;
W = TOP();
DROP(1);
if (W.p->f == f_docolon) { if (W.p->f == f_docolon) {
RPUSH(retIP); RPUSH(retIP);
} }
W = TOP();
DROP(1);
W.p->f(); W.p->f();
W = oldW; W = oldW;
IP = oldIP; IP = oldIP;
} }
void f_colonloop() { void f_colondispatch() {
while (IP.p) {
cell codeptr; cell codeptr;
W = *IP.p;
IP.p++;
codeptr = *W.p; codeptr = *W.p;
if (codeptr.f == f_docolon) { if (codeptr.f == f_docolon) {
RPUSH(IP); RPUSH(IP);
@ -323,6 +337,13 @@ void f_colonloop() {
} else { } else {
codeptr.f(); codeptr.f();
} }
}
void f_colonloop() {
while (IP.p) {
W = *IP.p;
IP.p++;
f_colondispatch();
} }
} }
@ -331,6 +352,14 @@ void f_docolon() {
f_colonloop(); f_colonloop();
} }
// this version of f_execute can be run from a colon word
// (though not currently from the interpreter?)
void f_execute() {
W = TOP();
DROP(1);
f_colondispatch();
}
void f_noop() { void f_noop() {
} }
@ -423,7 +452,7 @@ void f_colon() {
void f_interpretword() { // codefield flags -- void f_interpretword() { // codefield flags --
if (!STATE.i || (TOP().u & F_IMMEDIATE)) { if (!STATE.i || (TOP().u & F_IMMEDIATE)) {
DROP(1); DROP(1);
f_execute(); f_cexecute();
} else { } else {
DROP(1); DROP(1);
f_comma(); f_comma();
@ -536,6 +565,19 @@ void f_const() {
f_comma(); f_comma();
} }
void f_dovar() {
PUSHCP(W.p + 1);
}
void f_var() {
f_word();
f_create();
PUSHP(f_dovar);
f_comma();
PUSHI(0);
f_comma();
}
void f_bz_() { void f_bz_() {
if (!TOP().u) { if (!TOP().u) {
IP.p = IP.p->p; // branch IP.p = IP.p->p; // branch
@ -682,6 +724,7 @@ void f_init() {
CDEF("emit", f_emit); CDEF("emit", f_emit);
CDEF("word", f_word); CDEF("word", f_word);
CDEF("immediate", f_immediate); CDEF("immediate", f_immediate);
CDEF("execute", f_execute);
CDEF("create", f_create); CDEF("create", f_create);
CDEF("here", f_here); CDEF("here", f_here);
CDEF("latest", f_latest); CDEF("latest", f_latest);
@ -692,6 +735,7 @@ void f_init() {
CDEF(":", f_colon); CDEF(":", f_colon);
CDEF(";", f_semicolon); f_immediate(); CDEF(";", f_semicolon); f_immediate();
CDEF("const", f_const); CDEF("const", f_const);
CDEF("var", f_var);
CDEF("+", f_add); CDEF("+", f_add);
CDEF("-", f_sub); CDEF("-", f_sub);
CDEF("*", f_mul); CDEF("*", f_mul);
@ -705,6 +749,10 @@ void f_init() {
CDEF("=", f_eq); CDEF("=", f_eq);
CDEF("<", f_lt); CDEF("<", f_lt);
CDEF("<=", f_le); CDEF("<=", f_le);
CDEF("u>=", f_uge);
CDEF("u>", f_ugt);
CDEF("u<", f_ult);
CDEF("u<=", f_ule);
CDEF("@", f_get); CDEF("@", f_get);
CDEF("!", f_set); CDEF("!", f_set);
CDEF("b@", f_bget); CDEF("b@", f_bget);
@ -726,6 +774,7 @@ void f_init() {
CDEF("BNZ_", f_bnz_); CDEF("BNZ_", f_bnz_);
CDEF("ret", f_ret); CDEF("ret", f_ret);
CDEF(".", f_dot); CDEF(".", f_dot);
CDEF("u.", f_udot);
CDEF("type", f_puts); CDEF("type", f_puts);
CDEF(".s", f_printstack); CDEF(".s", f_printstack);
CDEF(",", f_comma); CDEF(",", f_comma);
@ -747,7 +796,7 @@ void f_init() {
CDEF("rstacksize", f_rstacksize); CDEF("rstacksize", f_rstacksize);
CDEF("task-user-size", f_taskusersize); CDEF("task-user-size", f_taskusersize);
f_loadfile("defs.frp"); f_loadfile("defs.jor");
} }
int DIE = 0; int DIE = 0;

View file

View file

@ -8,7 +8,8 @@
#include "tiff.h" #include "tiff.h"
#include "tiles.h" #include "tiles.h"
#include "serial.h" #include "serial.h"
#include "forp.h" #include "timer.h"
#include "jorth.h"
/*** S C R A T C H ***/ /*** S C R A T C H ***/
@ -94,6 +95,7 @@ void game_init() {
atexit(vid_cleanup); atexit(vid_cleanup);
kbd_init(); kbd_init();
timer_init(TIMER_30HZ);
tile_init(); tile_init();
fillMap(); fillMap();
@ -148,12 +150,6 @@ void overworldThink() {
scroll(game.player.x - 152, game.player.y - 92); scroll(game.player.x - 152, game.player.y - 92);
} }
int main3() {
f_init();
f_repl();
return 0;
}
void f_seremit() { void f_seremit() {
ser_write_byte(TOP().i); ser_write_byte(TOP().i);
if (TOP().i == '\n') { if (TOP().i == '\n') {
@ -175,6 +171,9 @@ void f_drawSprite() { // ( x y sprite -- )
void f_scroll() { // ( x y -- ) void f_scroll() { // ( x y -- )
scroll(ST1().i, TOP().i); scroll(ST1().i, TOP().i);
} }
void f_ticks() {
PUSHU(timer_counter);
}
void game_f_init() { void game_f_init() {
f_init(); f_init();
@ -184,8 +183,9 @@ void game_f_init() {
CDEF("sprite", f_drawSprite); CDEF("sprite", f_drawSprite);
CDEF("scroll", f_scroll); CDEF("scroll", f_scroll);
CDEF("draw", drawScreen); CDEF("draw", drawScreen);
CDEF("ticks", f_ticks);
f_loadfile("game.frp"); f_loadfile("game.jor");
} }
void f_poll() { void f_poll() {
@ -213,14 +213,14 @@ void f_poll() {
line[i] = '\0'; line[i] = '\0';
} }
} }
f_taskloop();
} }
int main() { int main() {
ser_init(SER_COM2, BAUD_19200, SER_8N1);
game_init(); game_init();
game_f_init(); game_f_init();
ser_init(SER_COM2, BAUD_19200, SER_8N1);
while (!keyIsDown(K_ESC)) { while (!keyIsDown(K_ESC)) {
kbd_debounce(); kbd_debounce();
f_poll(); f_poll();

36
timer.c Executable file
View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <dos.h>
#include "timer.h"
#define TIMER_INTERRUPT 0x1c
#define REG_8253_CTL 0x43
#define REG_COUNTER0 0x40
volatile unsigned int timer_counter = 0;
static void interrupt (*oldTimerISR)() = NULL;
static void interrupt timer_isr() {
timer_counter ++;
oldTimerISR();
}
void timer_setrate(unsigned int rate) {
outp(REG_8253_CTL, 0x3c);
outp(REG_COUNTER0, rate & 0xff);
outp(REG_COUNTER0, (rate >> 8) & 0xff);
}
static void timer_cleanup() {
if (oldTimerISR != NULL) {
setvect(TIMER_INTERRUPT, oldTimerISR);
timer_setrate(TIMER_18HZ);
oldTimerISR = NULL;
}
}
void timer_init(unsigned int rate) {
timer_setrate(rate);
oldTimerISR = getvect(TIMER_INTERRUPT);
setvect(TIMER_INTERRUPT, timer_isr);
atexit(timer_cleanup);
}

11
timer.h Executable file
View file

@ -0,0 +1,11 @@
#define TIMER_60HZ 0x4dae
#define TIMER_50HZ 0x5d37
#define TIMER_40HZ 0x7486
#define TIMER_30HZ 0x965c
#define TIMER_20HZ 0xe90b
#define TIMER_18HZ 0xffff
extern volatile unsigned int timer_counter;
void timer_init(unsigned int rate);
void timer_setrate(unsigned int rate);