A project to implement a console using the Mbed using VGA for video output and a PS/2 keyboard for the input. The eventual goal is to also include tools for managing SD cards, and a semi-self-hosting programming environment.
Dependencies: PS2_MbedConsole fastlib SDFileSystem vga640x480g_mbedconsole lightvm mbed
MbedConsole is a cool little project to have a self-contained computer all on an Mbed. So far it has VGA and PS/2 support and can stand alone without a computer powering it. Next planned features are SD card support and a lightweight programmable VM complete with a file editor and self-hosted assembler.
You can view additional details about it at http://earlz.net/tags/mbedconsole
Diff: forth_machine.cpp
- Revision:
- 6:a4dff59ef214
- Child:
- 7:2ac6752d47d2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/forth_machine.cpp Fri Sep 21 04:53:45 2012 +0000 @@ -0,0 +1,154 @@ +#include "mbedconsole.h" +#include "plEarlz.h" +#include <stdint.h> +#include <stdarg.h> + + +//An extremely simple virtual machine to make this implementation about 10 times easier and probably a bit faster + + + + + +int pl_stackpos=0; +int pl_stack[MAXSTACK]; + + + + +int pl_dictionary_count=0; +int pl_dictionary_size=0; +WordKey *pl_dictionary; //todo: a hash table would be much faster + +void pl_push(int val) +{ + if(pl_stackpos>=MAXSTACK) + { + vputs("Stack overflow!"); + pl_error=StackOverflow; + return; + } + pl_stack[pl_stackpos]=val; + pl_stackpos++; +} +int pl_pop() +{ + if(pl_stackpos<=0) + { + vputs("Stack underflow!"); + pl_error=StackUnderflow; + return 0; + } + pl_stackpos--; + return pl_stack[pl_stackpos]; +} + +WordKey *pl_lookup(char* name) +{ + for(int i=0;i<pl_dictionary_count;i++) + { + if(strlcmp(name, pl_dictionary[i].name, 12)==0) + { + return &pl_dictionary[i]; + } + } + return NULL; +} + +int pl_addword() +{ + if(pl_dictionary_size==0){ + pl_dictionary=(WordKey*)malloc(sizeof(WordKey)*12); + pl_dictionary_size=12; + return 0; + } + if(pl_dictionary_size<=pl_dictionary_count) + { + void* tmp=realloc(pl_dictionary, pl_dictionary_size+sizeof(WordKey)*DICTIONARYSTEP); + if(tmp==NULL) + { + vputs("Out of memory!! Epic Fail!!"); + return -1; + } + pl_dictionary=(WordKey*)tmp; + pl_dictionary_size+=sizeof(WordKey)*DICTIONARYSTEP; + } + return pl_dictionary_count++; +} + + + +int forth_execute(uint8_t* block, int length) +{ + int pos=0; + while(pos<length) + { + + Opcode op=(Opcode)block[pos]; + //printf("opcode: %x\n",(int)op); + switch(op) + { + case BranchTrue: + if(pl_pop()){ + pos++; + pos=*((uint16_t*)&block[pos]); + }else{ + pos+=3; + } + break; + case BranchFalse: + if(!pl_pop()){ + pos++; + pos=*((uint16_t*)&block[pos]); + }else{ + pos+=3; + } + break; + case Branch: + pos++; + pos=*((uint16_t*)&block[pos]); + break; + case Push: + pos++; + pl_push(*(uint32_t*)&block[pos]); + pos+=4; + break; + case Pop: + pos++; + pl_pop(); + break; + case Add: + pos++; + pl_push(pl_pop()+pl_pop()); + break; + case Sub: + pos++; + pl_push(pl_pop()-pl_pop()); + break; + case Mul: + pos++; + pl_push(pl_pop()*pl_pop()); + break; + case Div: + pos++; + pl_push(pl_pop()/pl_pop()); + break; + case Mod: + pos++; + pl_push(pl_pop()%pl_pop()); + break; + case CallInt: + pos++; + uint32_t tmp=*(uint32_t*)&block[pos]; + ((BuiltinFunction)tmp)(); + pos+=4; + break; + + + default: + vputs("Unknown opcode!!"); + return; + } + } + return 0; +} \ No newline at end of file