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:
7:2ac6752d47d2
Parent:
6:a4dff59ef214
Child:
8:f356684767ef
--- a/plEarlz.cpp	Fri Sep 21 04:53:45 2012 +0000
+++ b/plEarlz.cpp	Sat Sep 22 03:00:55 2012 +0000
@@ -25,6 +25,8 @@
 
 
 
+volatile BranchTarget *last_target=NULL;   
+
 ErrorType pl_error=None;
 
 
@@ -36,12 +38,11 @@
     Quote
 };
 
-
 uint8_t *pl_codeblock;
 int pl_blockpos;
 int pl_blocksize;
 
-void push_opcode_byte(uint8_t val)
+uint8_t* push_opcode_byte(uint8_t val)
 {
     if(pl_blockpos>=pl_blocksize)
     {
@@ -56,8 +57,9 @@
     }
     pl_codeblock[pl_blockpos]=val;
     pl_blockpos++;
+    return &pl_codeblock[pl_blockpos-1];
 }
-void push_opcode(Opcode val)
+Opcode* push_opcode(Opcode val)
 {
     if(pl_blockpos>=pl_blocksize)
     {
@@ -72,8 +74,9 @@
     }
     pl_codeblock[pl_blockpos]=(uint8_t)val;
     pl_blockpos++;
+    return (Opcode*)&pl_codeblock[pl_blockpos-1];
 }
-void push_opcode_word(uint16_t val)
+uint16_t* push_opcode_word(uint16_t val)
 {
     if(pl_blockpos>=pl_blocksize)
     {
@@ -88,8 +91,9 @@
     }
     *(uint16_t*)&pl_codeblock[pl_blockpos]=val;
     pl_blockpos+=2;
+    return (uint16_t*)(&pl_codeblock[pl_blockpos-2]);
 }
-void push_opcode_dword(uint32_t val)
+uint32_t* push_opcode_dword(uint32_t val)
 {
     if(pl_blockpos>=pl_blocksize)
     {
@@ -104,6 +108,7 @@
     }
     *(uint32_t*)&pl_codeblock[pl_blockpos]=val;
     pl_blockpos+=4;
+    return (uint32_t*)&pl_codeblock[pl_blockpos-4];
 }
 void new_codeblock(bool freeit)
 {
@@ -114,11 +119,32 @@
     pl_codeblock=(uint8_t*)malloc(CODEBLOCKSTEP);
     pl_blockpos=0;
     pl_blocksize=CODEBLOCKSTEP;
+    last_target=NULL;
 }
 int execute_codeblock()
 {
     return forth_execute(pl_codeblock, pl_blockpos);
 }
+ 
+
+void push_target(uint16_t* address)
+{
+    volatile BranchTarget* target=(BranchTarget*)malloc(sizeof(BranchTarget));
+    target->previous=last_target;
+    target->target=address;
+    last_target=target;
+}
+void pop_target()
+{
+    if(last_target==NULL)
+    {
+        vputs("Unmatched control statement!\n");
+        return;
+    }
+    volatile void* tmp=last_target;
+    last_target=last_target->previous;
+    free((void*)tmp);
+}
 
 int compile_word(char *word, WordType type) //returns 0 for success, 1 for ending word found, -1 for error
 {
@@ -133,6 +159,7 @@
                 push_opcode_dword((uint32_t)&bi_print);
             }else if(word[0]==';')
             {
+                push_opcode(Ret);
                 //execute!
                 return 1;
             }else if(word[0]=='+'){
@@ -148,9 +175,7 @@
             }else if(word[0]=='*'){
                 push_opcode(Mul);
             }else if(word[0]=='!'){
-                int tmp=pl_pop();
-                int* tmp2=(int*)pl_pop();
-                *tmp2=tmp;
+                //push_opcode(Store);
             }else if(word[0]=='?'){
                 pl_push(*(int*)pl_pop());
             }else if(word[0]=='='){
@@ -162,12 +187,24 @@
             }
         
         }else if(strlcmp("if", word, 3)==0){
-        
-        
+            printf("if statement %x\r\n", pl_blockpos);
+            push_opcode(BranchFalse);
+            push_target(push_opcode_word(0));
+        }else if(strlcmp("else", word, 5)==0){
+            printf("else statement %x\r\n", pl_blockpos);
+            push_opcode(Branch);
+            uint16_t* tmp=push_opcode_word(0); 
+            volatile uint16_t* tmp2=last_target->target;
+            *tmp2=pl_blockpos;
+            pop_target(); 
+            push_target(tmp); //have to do it after we pop it or we fall into an infinite loop!
+        }else if(strlcmp("end", word, 4)==0){
+            *(last_target->target)=pl_blockpos;
+            pop_target();
         }else{
-            vputs("I don't know the word ");
+            vputs("I don't know the word '");
             vputs(word);
-            vputs("\n");
+            vputs("'\n");
         }
     }
     return 0;
@@ -233,6 +270,15 @@
 
 int pl_shell()
 {
+    uint8_t* tmpf[20];
+    push_target((uint16_t*)&tmpf[2]);
+    *last_target->target=50;
+    pop_target();
+    push_target((uint16_t*)&tmpf[4]);
+    *last_target->target=200;
+    pop_target();
+    
+    printf("foo: %i %i\r\n", (int)*(uint16_t*)&tmpf[2], (int)*(uint16_t*)&tmpf[4]);
     vputs(">>plEarlz -- A forth-ish shell<<\n");
     printheapstats();
     vputs("\n");