Forp is now Jorth ( Jean Forth) - hook timer interrupt and expose ticks
This commit is contained in:
parent
ca25a4578e
commit
6552c1498b
|
@ -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
|
7
game.frp
7
game.frp
|
@ -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
37
game.jor
Executable 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
|
103
forp.c → jorth.c
103
forp.c → jorth.c
|
@ -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;
|
20
testbed.c
20
testbed.c
|
@ -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
36
timer.c
Executable 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
11
timer.h
Executable 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);
|
Loading…
Reference in a new issue