retro-extend: now use current nga implementation

FossilOrigin-Name: 31078bf1252c2981b46217efcd936ed0ff85f2f65faa7730e29ac267a2cecdcb
This commit is contained in:
crc 2019-01-04 01:41:02 +00:00
parent e2b6adc122
commit 8da5f7ab09

View file

@ -1,15 +1,11 @@
/* ____ ____ ______ ____ ___
|| \\ || | || | || \\ // \\
||_// ||== || ||_// (( ))
|| \\ ||___ || || \\ \\_//
a personal, minimalistic forth
/* RETRO: a personal, minimalistic forth
This is a quick interface layer that loads and runs a
source file, then saves a new image file. It's used to
merge the `retro.forth` into the base `rx` image.
This is a quick interface layer that loads and runs a
source file, then saves a new image file. It's used to
merge the `retro.forth` into the base `rx` image.
Copyright (c) 2016, 2017 Charles Childers
*/
Copyright (c) 2016 - 2019, Charles Childers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#include <stdio.h>
#include <stdint.h>
@ -22,13 +18,25 @@
#define ADDRESSES 2048
#define STACK_DEPTH 512
#define NUM_DEVICES 1
typedef void (*Handler)(void);
Handler IO_deviceHandlers[NUM_DEVICES + 1];
Handler IO_queryHandlers[NUM_DEVICES + 1];
enum vm_opcode {
VM_NOP, VM_LIT, VM_DUP, VM_DROP, VM_SWAP, VM_PUSH, VM_POP,
VM_JUMP, VM_CALL, VM_CCALL, VM_RETURN, VM_EQ, VM_NEQ, VM_LT,
VM_GT, VM_FETCH, VM_STORE, VM_ADD, VM_SUB, VM_MUL, VM_DIVMOD,
VM_AND, VM_OR, VM_XOR, VM_SHIFT, VM_ZRET, VM_END
VM_AND, VM_OR, VM_XOR, VM_SHIFT, VM_ZRET, VM_END, VM_IE,
VM_IQ, VM_II
};
#define NUM_OPS VM_END + 1
#define NUM_OPS VM_II + 1
#ifndef NUM_DEVICES
#define NUM_DEVICES 0
#endif
CELL sp, rp, ip;
CELL data[STACK_DEPTH];
@ -77,6 +85,16 @@ int not_eol(int ch);
void read_token(FILE *file, char *token_buffer, int echo);
char *read_token_str(char *s, char *token_buffer, int echo);
void generic_output() {
putc(stack_pop(), stdout);
fflush(stdout);
}
void generic_output_query() {
stack_push(0);
stack_push(0);
}
void dump_stack() {
CELL i;
if (sp == 0)
@ -127,6 +145,8 @@ void stats() {
int main(int argc, char **argv) {
int tokens;
FILE *fp;
IO_deviceHandlers[0] = generic_output;
IO_queryHandlers[0] = generic_output_query;
ngaPrepare();
max_sp = 0;
max_rsp = 0;
@ -236,29 +256,19 @@ void update_rx() {
}
/* The `execute` function runs a word in the Retro image.
It also handles the additional I/O instructions. */
/* The `execute` function runs a word in the Retro image. */
void execute(int cell) {
void execute(CELL cell) {
CELL opcode;
rp = 1;
ip = cell;
while (ip < IMAGE_SIZE) {
if (ip == notfound) {
printf("%s ?\n", string_extract(TIB));
}
opcode = memory[ip];
if (ngaValidatePackedOpcodes(opcode) != 0) {
ngaProcessPackedOpcodes(opcode);
} else if (opcode >= 0 && opcode < 27) {
ngaProcessOpcode(opcode);
} else {
switch (opcode) {
case IO_TTY_PUTC: putc(stack_pop(), stdout); fflush(stdout); break;
default: printf("Invalid instruction!\n");
printf("At %d, opcode %d\n", ip, opcode);
exit(1);
}
printf("Invalid instruction!\n");
exit(1);
}
ip++;
if (sp > max_sp) max_sp = sp;
@ -403,7 +413,7 @@ void inst_drop() {
}
void inst_swap() {
int a;
CELL a;
a = TOS;
TOS = NOS;
NOS = a;
@ -434,7 +444,7 @@ void inst_call() {
}
void inst_ccall() {
int a, b;
CELL a, b;
a = TOS; inst_drop(); /* False */
b = TOS; inst_drop(); /* Flag */
if (b != 0) {
@ -479,9 +489,13 @@ void inst_fetch() {
}
void inst_store() {
memory[TOS] = NOS;
inst_drop();
inst_drop();
if (TOS <= IMAGE_SIZE && TOS >= 0) {
memory[TOS] = NOS;
inst_drop();
inst_drop();
} else {
ip = IMAGE_SIZE;
}
}
void inst_add() {
@ -500,7 +514,7 @@ void inst_mul() {
}
void inst_divmod() {
int a, b;
CELL a, b;
a = TOS;
b = NOS;
TOS = b / a;
@ -548,13 +562,29 @@ void inst_end() {
ip = IMAGE_SIZE;
}
typedef void (*Handler)(void);
void inst_ie() {
sp++;
TOS = NUM_DEVICES;
}
void inst_iq() {
CELL Device = TOS;
inst_drop();
IO_queryHandlers[Device]();
}
void inst_ii() {
CELL Device = TOS;
inst_drop();
IO_deviceHandlers[Device]();
}
Handler instructions[NUM_OPS] = {
inst_nop, inst_lit, inst_dup, inst_drop, inst_swap, inst_push, inst_pop,
inst_jump, inst_call, inst_ccall, inst_return, inst_eq, inst_neq, inst_lt,
inst_gt, inst_fetch, inst_store, inst_add, inst_sub, inst_mul, inst_divmod,
inst_and, inst_or, inst_xor, inst_shift, inst_zret, inst_end
inst_and, inst_or, inst_xor, inst_shift, inst_zret, inst_end, inst_ie,
inst_iq, inst_ii
};
void ngaProcessOpcode(CELL opcode) {
@ -569,14 +599,14 @@ int ngaValidatePackedOpcodes(CELL opcode) {
int i;
for (i = 0; i < 4; i++) {
current = raw & 0xFF;
if (!(current >= 0 && current <= 26))
if (!(current >= 0 && current <= 29))
valid = 0;
raw = raw >> 8;
}
return valid;
}
void ngaProcessPackedOpcodes(int opcode) {
void ngaProcessPackedOpcodes(CELL opcode) {
CELL raw = opcode;
int i;
for (i = 0; i < 4; i++) {