#include #include #include #include #include #include "uforth_opcodes.h" #define BFORTH_PGM_SIZE (1024) #define BFORTH_STACK_SIZE (64) #define BFORTH_RSTACK_SIZE (32) const uint8_t * bf_prog = NULL; uint16_t bf_prog_len = 0; const uint8_t * bfdict[26]; uint8_t bfvars[26]; uint8_t bf_stack[BFORTH_STACK_SIZE]; uint8_t * bf_stacktop; const uint8_t * bf_linkstack[BFORTH_RSTACK_SIZE]; const uint8_t ** bf_linkstacktop; const uint8_t * bf_pc; #define DSTKPUSH(x) (*(bf_stacktop++) = x) #define DSTKPOP (*(--bf_stacktop)) #define DSTKTOP (*(bf_stacktop - 1)) #define DSTKIDX(i) (*(bf_stacktop - 1 - i)) void BF_Step(void) { if(*bf_pc == '\0') return; uint8_t tmp = *bf_pc++; printf("op: 0x%02X\n", tmp); switch(tmp) { case OPCODE_ADD: tmp = DSTKPOP; DSTKTOP += tmp; break; case OPCODE_SUB: tmp = DSTKPOP; DSTKTOP -= tmp; break; case OPCODE_MUL: tmp = DSTKPOP; DSTKTOP *= tmp; break; case OPCODE_DIV: tmp = DSTKPOP; DSTKTOP /= tmp; break; case OPCODE_BITXOR: tmp = DSTKPOP; DSTKTOP ^= tmp; break; case OPCODE_BITAND: tmp = DSTKPOP; DSTKTOP &= tmp; break; case OPCODE_BITOR: tmp = DSTKPOP; DSTKTOP |= tmp; break; case OPCODE_LT: tmp = DSTKPOP; DSTKTOP = DSTKTOP < tmp; break; case OPCODE_GT: tmp = DSTKPOP; DSTKTOP = DSTKTOP > tmp; break; case OPCODE_EQ: tmp = DSTKPOP; DSTKTOP = DSTKTOP == tmp; break; case OPCODE_PUSH: DSTKPUSH(*bf_pc++); break; case OPCODE_POP: DSTKPOP; break; // case OPCODE_DUP: tmp = DSTKTOP; DSTKPUSH(tmp); break; // case OPCODE_SWAP: tmp = DSTKIDX(0); DSTKIDX(0) = DSTKIDX(1); DSTKIDX(1) = tmp; break; case OPCODE_DEF: tmp = bf_pc[0]; bfdict[tmp] = bf_pc + 2; bf_pc += bf_pc[1]; break; case OPCODE_CALL: *bf_linkstacktop++ = bf_pc; bf_pc = bfdict[bf_pc[0]]; break; case OPCODE_RET:// End definition/return bf_pc = *(--bf_linkstacktop); break; case OPCODE_CJMP_F: if(!DSTKPOP) bf_pc += bf_pc[0]; break; case OPCODE_JMP: bf_pc += bf_pc[0]; break; case OPCODE_PRINT: printf("0x%02X\n", DSTKPOP); break; // case '.': printf("%d\n", DSTKPOP); break; // case '.': printf("%c", DSTKPOP); break; case OPCODE_RESET_STACKS: bf_stacktop = bf_stack; bf_linkstacktop = bf_linkstack; break; } } void BF_Run(const uint8_t * src, uint16_t len) { bf_prog = src; bf_prog_len = len; bf_stacktop = bf_stack; bf_linkstacktop = bf_linkstack; bf_pc = src; while(*bf_pc) { BF_Step(); printf("pc: %d ", (int)(bf_pc - bf_prog)); printf("stk: %d ", (int)(bf_stacktop - bf_stack)); printf("lstk: %d\n", (int)(bf_linkstacktop - bf_linkstack)); } } int main(int argc, const char * argv[]) { FILE * fin = fopen( "microforthtest.bin" , "r" ); fseek(fin, 0, SEEK_END); size_t len = ftell(fin); fseek(fin, 0, SEEK_SET); uint8_t * prog = (uint8_t *)malloc(len); fread(prog, 1, len, fin); fclose(fin); printf("Program size: %d B\n", (int)len); BF_Run(prog, len); }