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

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