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

Committer:
earlz
Date:
Sun Sep 30 05:26:32 2012 +0000
Revision:
13:442bd2fb4ea0
Parent:
9:4211d638b2e9
Child:
16:370b9e559f92
finally a graphic

Who changed what in which revision?

UserRevisionLine numberNew contents of line
earlz 6:a4dff59ef214 1 #include "mbedconsole.h"
earlz 6:a4dff59ef214 2 #include "plEarlz.h"
earlz 6:a4dff59ef214 3 #include <stdint.h>
earlz 6:a4dff59ef214 4 #include <stdarg.h>
earlz 6:a4dff59ef214 5
earlz 6:a4dff59ef214 6
earlz 6:a4dff59ef214 7 //An extremely simple virtual machine to make this implementation about 10 times easier and probably a bit faster
earlz 6:a4dff59ef214 8
earlz 6:a4dff59ef214 9
earlz 6:a4dff59ef214 10
earlz 6:a4dff59ef214 11
earlz 6:a4dff59ef214 12
earlz 6:a4dff59ef214 13 int pl_stackpos=0;
earlz 6:a4dff59ef214 14 int pl_stack[MAXSTACK];
earlz 6:a4dff59ef214 15
earlz 6:a4dff59ef214 16
earlz 6:a4dff59ef214 17
earlz 6:a4dff59ef214 18
earlz 6:a4dff59ef214 19 int pl_dictionary_count=0;
earlz 6:a4dff59ef214 20 int pl_dictionary_size=0;
earlz 6:a4dff59ef214 21 WordKey *pl_dictionary; //todo: a hash table would be much faster
earlz 6:a4dff59ef214 22
earlz 6:a4dff59ef214 23 void pl_push(int val)
earlz 6:a4dff59ef214 24 {
earlz 6:a4dff59ef214 25 if(pl_stackpos>=MAXSTACK)
earlz 6:a4dff59ef214 26 {
earlz 6:a4dff59ef214 27 vputs("Stack overflow!");
earlz 6:a4dff59ef214 28 pl_error=StackOverflow;
earlz 6:a4dff59ef214 29 return;
earlz 6:a4dff59ef214 30 }
earlz 6:a4dff59ef214 31 pl_stack[pl_stackpos]=val;
earlz 6:a4dff59ef214 32 pl_stackpos++;
earlz 6:a4dff59ef214 33 }
earlz 6:a4dff59ef214 34 int pl_pop()
earlz 6:a4dff59ef214 35 {
earlz 6:a4dff59ef214 36 if(pl_stackpos<=0)
earlz 6:a4dff59ef214 37 {
earlz 6:a4dff59ef214 38 vputs("Stack underflow!");
earlz 6:a4dff59ef214 39 pl_error=StackUnderflow;
earlz 6:a4dff59ef214 40 return 0;
earlz 6:a4dff59ef214 41 }
earlz 6:a4dff59ef214 42 pl_stackpos--;
earlz 6:a4dff59ef214 43 return pl_stack[pl_stackpos];
earlz 6:a4dff59ef214 44 }
earlz 6:a4dff59ef214 45
earlz 6:a4dff59ef214 46 WordKey *pl_lookup(char* name)
earlz 6:a4dff59ef214 47 {
earlz 6:a4dff59ef214 48 for(int i=0;i<pl_dictionary_count;i++)
earlz 6:a4dff59ef214 49 {
earlz 6:a4dff59ef214 50 if(strlcmp(name, pl_dictionary[i].name, 12)==0)
earlz 6:a4dff59ef214 51 {
earlz 6:a4dff59ef214 52 return &pl_dictionary[i];
earlz 6:a4dff59ef214 53 }
earlz 6:a4dff59ef214 54 }
earlz 6:a4dff59ef214 55 return NULL;
earlz 6:a4dff59ef214 56 }
earlz 6:a4dff59ef214 57
earlz 6:a4dff59ef214 58 int pl_addword()
earlz 6:a4dff59ef214 59 {
earlz 6:a4dff59ef214 60 if(pl_dictionary_size==0){
earlz 6:a4dff59ef214 61 pl_dictionary=(WordKey*)malloc(sizeof(WordKey)*12);
earlz 6:a4dff59ef214 62 pl_dictionary_size=12;
earlz 6:a4dff59ef214 63 return 0;
earlz 6:a4dff59ef214 64 }
earlz 6:a4dff59ef214 65 if(pl_dictionary_size<=pl_dictionary_count)
earlz 6:a4dff59ef214 66 {
earlz 6:a4dff59ef214 67 void* tmp=realloc(pl_dictionary, pl_dictionary_size+sizeof(WordKey)*DICTIONARYSTEP);
earlz 6:a4dff59ef214 68 if(tmp==NULL)
earlz 6:a4dff59ef214 69 {
earlz 6:a4dff59ef214 70 vputs("Out of memory!! Epic Fail!!");
earlz 6:a4dff59ef214 71 return -1;
earlz 6:a4dff59ef214 72 }
earlz 6:a4dff59ef214 73 pl_dictionary=(WordKey*)tmp;
earlz 6:a4dff59ef214 74 pl_dictionary_size+=sizeof(WordKey)*DICTIONARYSTEP;
earlz 6:a4dff59ef214 75 }
earlz 6:a4dff59ef214 76 return pl_dictionary_count++;
earlz 6:a4dff59ef214 77 }
earlz 6:a4dff59ef214 78
earlz 13:442bd2fb4ea0 79
earlz 13:442bd2fb4ea0 80 typedef struct CallStateStruct
earlz 13:442bd2fb4ea0 81 {
earlz 13:442bd2fb4ea0 82 int lastcall; //the pl_temppos when this word was first called
earlz 13:442bd2fb4ea0 83 CallStateStruct* previous;
earlz 13:442bd2fb4ea0 84 } CallState;
earlz 13:442bd2fb4ea0 85
earlz 9:4211d638b2e9 86 int pl_tempstack[MAXTEMPSTACK];
earlz 9:4211d638b2e9 87 int pl_temppos=0;
earlz 13:442bd2fb4ea0 88 CallState* callstate;
earlz 9:4211d638b2e9 89 void pl_temppush(int val)
earlz 9:4211d638b2e9 90 {
earlz 9:4211d638b2e9 91 if(pl_temppos>=MAXTEMPSTACK)
earlz 9:4211d638b2e9 92 {
earlz 9:4211d638b2e9 93 vputs("Temporary stack overflow\n");
earlz 9:4211d638b2e9 94 return;
earlz 9:4211d638b2e9 95 }
earlz 9:4211d638b2e9 96 pl_tempstack[pl_temppos]=val;
earlz 9:4211d638b2e9 97 pl_temppos++;
earlz 9:4211d638b2e9 98 }
earlz 9:4211d638b2e9 99 int pl_temppop()
earlz 9:4211d638b2e9 100 {
earlz 9:4211d638b2e9 101 if(pl_temppos<=0)
earlz 9:4211d638b2e9 102 {
earlz 9:4211d638b2e9 103 vputs("Temporary stack underflow\n");
earlz 9:4211d638b2e9 104 return 0;
earlz 9:4211d638b2e9 105 }
earlz 9:4211d638b2e9 106 return pl_tempstack[pl_temppos--];
earlz 9:4211d638b2e9 107 }
earlz 6:a4dff59ef214 108
earlz 6:a4dff59ef214 109 int forth_execute(uint8_t* block, int length)
earlz 6:a4dff59ef214 110 {
earlz 7:2ac6752d47d2 111 uint16_t pos=0;
earlz 8:f356684767ef 112 printf("block length: %x\r\n",length);
earlz 6:a4dff59ef214 113 while(pos<length)
earlz 6:a4dff59ef214 114 {
earlz 8:f356684767ef 115 //serial.getc();
earlz 6:a4dff59ef214 116 Opcode op=(Opcode)block[pos];
earlz 8:f356684767ef 117 printf("pos: %x -- opcode: %x\r\n",(int)pos, (int)op);
earlz 6:a4dff59ef214 118 switch(op)
earlz 6:a4dff59ef214 119 {
earlz 6:a4dff59ef214 120 case BranchTrue:
earlz 6:a4dff59ef214 121 if(pl_pop()){
earlz 6:a4dff59ef214 122 pos++;
earlz 6:a4dff59ef214 123 pos=*((uint16_t*)&block[pos]);
earlz 7:2ac6752d47d2 124
earlz 6:a4dff59ef214 125 }else{
earlz 6:a4dff59ef214 126 pos+=3;
earlz 6:a4dff59ef214 127 }
earlz 6:a4dff59ef214 128 break;
earlz 6:a4dff59ef214 129 case BranchFalse:
earlz 6:a4dff59ef214 130 if(!pl_pop()){
earlz 6:a4dff59ef214 131 pos++;
earlz 8:f356684767ef 132 serial.printf("branch false %x\r\n",(int)pos);
earlz 6:a4dff59ef214 133 pos=*((uint16_t*)&block[pos]);
earlz 7:2ac6752d47d2 134 serial.printf("branch false %x\r\n",(int)pos);
earlz 6:a4dff59ef214 135 }else{
earlz 6:a4dff59ef214 136 pos+=3;
earlz 7:2ac6752d47d2 137 serial.printf("branch false skip %x\r\n", (int)pos);
earlz 6:a4dff59ef214 138 }
earlz 6:a4dff59ef214 139 break;
earlz 6:a4dff59ef214 140 case Branch:
earlz 6:a4dff59ef214 141 pos++;
earlz 6:a4dff59ef214 142 pos=*((uint16_t*)&block[pos]);
earlz 6:a4dff59ef214 143 break;
earlz 6:a4dff59ef214 144 case Push:
earlz 6:a4dff59ef214 145 pos++;
earlz 6:a4dff59ef214 146 pl_push(*(uint32_t*)&block[pos]);
earlz 6:a4dff59ef214 147 pos+=4;
earlz 6:a4dff59ef214 148 break;
earlz 9:4211d638b2e9 149 case Drop:
earlz 6:a4dff59ef214 150 pos++;
earlz 6:a4dff59ef214 151 pl_pop();
earlz 6:a4dff59ef214 152 break;
earlz 6:a4dff59ef214 153 case Add:
earlz 6:a4dff59ef214 154 pos++;
earlz 6:a4dff59ef214 155 pl_push(pl_pop()+pl_pop());
earlz 6:a4dff59ef214 156 break;
earlz 6:a4dff59ef214 157 case Sub:
earlz 6:a4dff59ef214 158 pos++;
earlz 6:a4dff59ef214 159 pl_push(pl_pop()-pl_pop());
earlz 6:a4dff59ef214 160 break;
earlz 6:a4dff59ef214 161 case Mul:
earlz 6:a4dff59ef214 162 pos++;
earlz 6:a4dff59ef214 163 pl_push(pl_pop()*pl_pop());
earlz 6:a4dff59ef214 164 break;
earlz 6:a4dff59ef214 165 case Div:
earlz 6:a4dff59ef214 166 pos++;
earlz 6:a4dff59ef214 167 pl_push(pl_pop()/pl_pop());
earlz 6:a4dff59ef214 168 break;
earlz 6:a4dff59ef214 169 case Mod:
earlz 6:a4dff59ef214 170 pos++;
earlz 6:a4dff59ef214 171 pl_push(pl_pop()%pl_pop());
earlz 6:a4dff59ef214 172 break;
earlz 8:f356684767ef 173 case Cgt:
earlz 8:f356684767ef 174 pos++;
earlz 8:f356684767ef 175 pl_push(pl_pop()>pl_pop());
earlz 8:f356684767ef 176 break;
earlz 8:f356684767ef 177 case Clt:
earlz 8:f356684767ef 178 pos++;
earlz 8:f356684767ef 179 pl_push(pl_pop()<pl_pop());
earlz 8:f356684767ef 180 break;
earlz 8:f356684767ef 181 case Cgte:
earlz 8:f356684767ef 182 pos++;
earlz 8:f356684767ef 183 pl_push(pl_pop()>=pl_pop());
earlz 8:f356684767ef 184 break;
earlz 8:f356684767ef 185 case Clte:
earlz 8:f356684767ef 186 pos++;
earlz 8:f356684767ef 187 pl_push(pl_pop()<=pl_pop());
earlz 8:f356684767ef 188 break;
earlz 8:f356684767ef 189 case Ceq:
earlz 8:f356684767ef 190 pos++;
earlz 8:f356684767ef 191 pl_push(pl_pop()==pl_pop());
earlz 8:f356684767ef 192 break;
earlz 8:f356684767ef 193 case Cneq:
earlz 8:f356684767ef 194 pos++;
earlz 8:f356684767ef 195 pl_push(pl_pop()!=pl_pop());
earlz 8:f356684767ef 196 break;
earlz 9:4211d638b2e9 197 case CallInt:{
earlz 6:a4dff59ef214 198 pos++;
earlz 6:a4dff59ef214 199 uint32_t tmp=*(uint32_t*)&block[pos];
earlz 6:a4dff59ef214 200 ((BuiltinFunction)tmp)();
earlz 6:a4dff59ef214 201 pos+=4;
earlz 9:4211d638b2e9 202 break;}
earlz 9:4211d638b2e9 203 case Swap:{
earlz 9:4211d638b2e9 204 pos++;
earlz 9:4211d638b2e9 205 int tmp=pl_pop();
earlz 9:4211d638b2e9 206 int tmp2=pl_pop();
earlz 9:4211d638b2e9 207 pl_push(tmp);
earlz 9:4211d638b2e9 208 pl_push(tmp2);
earlz 6:a4dff59ef214 209 break;
earlz 9:4211d638b2e9 210 }
earlz 9:4211d638b2e9 211 case PushTemp:
earlz 9:4211d638b2e9 212 pos++;
earlz 9:4211d638b2e9 213 pl_temppush(pl_pop());
earlz 9:4211d638b2e9 214 break;
earlz 9:4211d638b2e9 215 case PopTemp:
earlz 9:4211d638b2e9 216 pos++;
earlz 9:4211d638b2e9 217 pl_push(pl_temppop());
earlz 9:4211d638b2e9 218 case Pick:{
earlz 9:4211d638b2e9 219 pos++;
earlz 9:4211d638b2e9 220 int tmp=pl_pop();
earlz 9:4211d638b2e9 221 if(pl_stackpos-tmp>0){
earlz 9:4211d638b2e9 222 pl_push(pl_stack[pl_stackpos-tmp]);
earlz 9:4211d638b2e9 223
earlz 9:4211d638b2e9 224 }else{
earlz 9:4211d638b2e9 225 pl_push(0);
earlz 9:4211d638b2e9 226 vputs("Stack underflow on pick\n");
earlz 9:4211d638b2e9 227 }
earlz 9:4211d638b2e9 228 break;}
earlz 7:2ac6752d47d2 229 case Ret:
earlz 8:f356684767ef 230 return 0;
earlz 6:a4dff59ef214 231
earlz 6:a4dff59ef214 232
earlz 6:a4dff59ef214 233 default:
earlz 6:a4dff59ef214 234 vputs("Unknown opcode!!");
earlz 6:a4dff59ef214 235 return;
earlz 6:a4dff59ef214 236 }
earlz 6:a4dff59ef214 237 }
earlz 6:a4dff59ef214 238 return 0;
earlz 6:a4dff59ef214 239 }