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:
Fri Sep 21 04:53:45 2012 +0000
Revision:
6:a4dff59ef214
Parent:
5:367397a82ddc
Child:
7:2ac6752d47d2
Switched a virtual machine instead of trying to interpret directly. This is much easier for development, and should amazingly make it both faster and use less memory  :D

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 <stdarg.h>
earlz 6:a4dff59ef214 4 #include <stdint.h>
earlz 6:a4dff59ef214 5 //Basically a non-conforming take on Forth, btw.
earlz 6:a4dff59ef214 6
earlz 6:a4dff59ef214 7 inline int internal_captureline(void* pBuffer, char const* pFormatString, ...)
earlz 6:a4dff59ef214 8 {
earlz 6:a4dff59ef214 9 char* pStringEnd = (char*)pBuffer + strlen((char*)pBuffer);
earlz 6:a4dff59ef214 10 va_list valist;
earlz 6:a4dff59ef214 11
earlz 6:a4dff59ef214 12 va_start(valist, pFormatString);
earlz 6:a4dff59ef214 13
earlz 6:a4dff59ef214 14 return vsprintf(pStringEnd, pFormatString, valist);
earlz 6:a4dff59ef214 15 }
earlz 6:a4dff59ef214 16 void printheapstats()
earlz 6:a4dff59ef214 17 {
earlz 6:a4dff59ef214 18 char buffer[256];
earlz 6:a4dff59ef214 19 __heapstats(internal_captureline, buffer);
earlz 6:a4dff59ef214 20 vputs("Memory info: ");
earlz 6:a4dff59ef214 21 vputs(buffer);
earlz 6:a4dff59ef214 22 }
earlz 6:a4dff59ef214 23
earlz 6:a4dff59ef214 24
earlz 6:a4dff59ef214 25
earlz 6:a4dff59ef214 26
earlz 6:a4dff59ef214 27
earlz 6:a4dff59ef214 28 ErrorType pl_error=None;
earlz 6:a4dff59ef214 29
earlz 6:a4dff59ef214 30
earlz 6:a4dff59ef214 31 enum WordType
earlz 6:a4dff59ef214 32 {
earlz 6:a4dff59ef214 33 Unknown,
earlz 6:a4dff59ef214 34 Number,
earlz 6:a4dff59ef214 35 Word,
earlz 6:a4dff59ef214 36 Quote
earlz 6:a4dff59ef214 37 };
earlz 6:a4dff59ef214 38
earlz 6:a4dff59ef214 39
earlz 6:a4dff59ef214 40 uint8_t *pl_codeblock;
earlz 6:a4dff59ef214 41 int pl_blockpos;
earlz 6:a4dff59ef214 42 int pl_blocksize;
earlz 6:a4dff59ef214 43
earlz 6:a4dff59ef214 44 void push_opcode_byte(uint8_t val)
earlz 6:a4dff59ef214 45 {
earlz 6:a4dff59ef214 46 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 47 {
earlz 6:a4dff59ef214 48 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 49 if(tmp==NULL)
earlz 6:a4dff59ef214 50 {
earlz 6:a4dff59ef214 51 vputs("Out of memory!!");
earlz 6:a4dff59ef214 52 return;
earlz 6:a4dff59ef214 53 }
earlz 6:a4dff59ef214 54 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 55 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 56 }
earlz 6:a4dff59ef214 57 pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 58 pl_blockpos++;
earlz 6:a4dff59ef214 59 }
earlz 6:a4dff59ef214 60 void push_opcode(Opcode val)
earlz 6:a4dff59ef214 61 {
earlz 6:a4dff59ef214 62 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 63 {
earlz 6:a4dff59ef214 64 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 65 if(tmp==NULL)
earlz 6:a4dff59ef214 66 {
earlz 6:a4dff59ef214 67 vputs("Out of memory!!");
earlz 6:a4dff59ef214 68 return;
earlz 6:a4dff59ef214 69 }
earlz 6:a4dff59ef214 70 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 71 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 72 }
earlz 6:a4dff59ef214 73 pl_codeblock[pl_blockpos]=(uint8_t)val;
earlz 6:a4dff59ef214 74 pl_blockpos++;
earlz 6:a4dff59ef214 75 }
earlz 6:a4dff59ef214 76 void push_opcode_word(uint16_t val)
earlz 6:a4dff59ef214 77 {
earlz 6:a4dff59ef214 78 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 79 {
earlz 6:a4dff59ef214 80 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 81 if(tmp==NULL)
earlz 6:a4dff59ef214 82 {
earlz 6:a4dff59ef214 83 vputs("Out of memory!!");
earlz 6:a4dff59ef214 84 return;
earlz 6:a4dff59ef214 85 }
earlz 6:a4dff59ef214 86 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 87 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 88 }
earlz 6:a4dff59ef214 89 *(uint16_t*)&pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 90 pl_blockpos+=2;
earlz 6:a4dff59ef214 91 }
earlz 6:a4dff59ef214 92 void push_opcode_dword(uint32_t val)
earlz 6:a4dff59ef214 93 {
earlz 6:a4dff59ef214 94 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 95 {
earlz 6:a4dff59ef214 96 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 97 if(tmp==NULL)
earlz 6:a4dff59ef214 98 {
earlz 6:a4dff59ef214 99 vputs("Out of memory!!");
earlz 6:a4dff59ef214 100 return;
earlz 6:a4dff59ef214 101 }
earlz 6:a4dff59ef214 102 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 103 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 104 }
earlz 6:a4dff59ef214 105 *(uint32_t*)&pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 106 pl_blockpos+=4;
earlz 6:a4dff59ef214 107 }
earlz 6:a4dff59ef214 108 void new_codeblock(bool freeit)
earlz 6:a4dff59ef214 109 {
earlz 6:a4dff59ef214 110 if(freeit)
earlz 6:a4dff59ef214 111 {
earlz 6:a4dff59ef214 112 free(pl_codeblock);
earlz 6:a4dff59ef214 113 }
earlz 6:a4dff59ef214 114 pl_codeblock=(uint8_t*)malloc(CODEBLOCKSTEP);
earlz 6:a4dff59ef214 115 pl_blockpos=0;
earlz 6:a4dff59ef214 116 pl_blocksize=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 117 }
earlz 6:a4dff59ef214 118 int execute_codeblock()
earlz 6:a4dff59ef214 119 {
earlz 6:a4dff59ef214 120 return forth_execute(pl_codeblock, pl_blockpos);
earlz 6:a4dff59ef214 121 }
earlz 6:a4dff59ef214 122
earlz 6:a4dff59ef214 123 int compile_word(char *word, WordType type) //returns 0 for success, 1 for ending word found, -1 for error
earlz 6:a4dff59ef214 124 {
earlz 6:a4dff59ef214 125 if(type==Number){
earlz 6:a4dff59ef214 126 push_opcode(Push);
earlz 6:a4dff59ef214 127 push_opcode_dword(atoi(word));
earlz 6:a4dff59ef214 128 }else{
earlz 6:a4dff59ef214 129 if(word[1]==0) //check the quick builtins first
earlz 6:a4dff59ef214 130 {
earlz 6:a4dff59ef214 131 if(word[0]=='.'){
earlz 6:a4dff59ef214 132 push_opcode(CallInt);
earlz 6:a4dff59ef214 133 push_opcode_dword((uint32_t)&bi_print);
earlz 6:a4dff59ef214 134 }else if(word[0]==';')
earlz 6:a4dff59ef214 135 {
earlz 6:a4dff59ef214 136 //execute!
earlz 6:a4dff59ef214 137 return 1;
earlz 6:a4dff59ef214 138 }else if(word[0]=='+'){
earlz 6:a4dff59ef214 139 push_opcode(Add);
earlz 6:a4dff59ef214 140 }else if(word[0]=='/'){
earlz 6:a4dff59ef214 141 push_opcode(Div);
earlz 6:a4dff59ef214 142 }else if(word[0]=='-'){
earlz 6:a4dff59ef214 143 push_opcode(Sub);
earlz 6:a4dff59ef214 144 }else if(word[0]=='!'){
earlz 6:a4dff59ef214 145 //pl_push(pl_pop()-pl_pop());
earlz 6:a4dff59ef214 146 }else if(word[0]=='%'){
earlz 6:a4dff59ef214 147 push_opcode(Mod);
earlz 6:a4dff59ef214 148 }else if(word[0]=='*'){
earlz 6:a4dff59ef214 149 push_opcode(Mul);
earlz 6:a4dff59ef214 150 }else if(word[0]=='!'){
earlz 6:a4dff59ef214 151 int tmp=pl_pop();
earlz 6:a4dff59ef214 152 int* tmp2=(int*)pl_pop();
earlz 6:a4dff59ef214 153 *tmp2=tmp;
earlz 6:a4dff59ef214 154 }else if(word[0]=='?'){
earlz 6:a4dff59ef214 155 pl_push(*(int*)pl_pop());
earlz 6:a4dff59ef214 156 }else if(word[0]=='='){
earlz 6:a4dff59ef214 157 pl_push(pl_pop() == pl_pop());
earlz 6:a4dff59ef214 158 }else if(word[0]=='`'){
earlz 6:a4dff59ef214 159 pl_push(pl_pop()>0);
earlz 6:a4dff59ef214 160 }else if(word[0]=='$'){
earlz 6:a4dff59ef214 161 //print string (address on stack
earlz 6:a4dff59ef214 162 }
earlz 6:a4dff59ef214 163
earlz 6:a4dff59ef214 164 }else if(strlcmp("if", word, 3)==0){
earlz 6:a4dff59ef214 165
earlz 6:a4dff59ef214 166
earlz 6:a4dff59ef214 167 }else{
earlz 6:a4dff59ef214 168 vputs("I don't know the word ");
earlz 6:a4dff59ef214 169 vputs(word);
earlz 6:a4dff59ef214 170 vputs("\n");
earlz 6:a4dff59ef214 171 }
earlz 6:a4dff59ef214 172 }
earlz 6:a4dff59ef214 173 return 0;
earlz 6:a4dff59ef214 174 }
earlz 6:a4dff59ef214 175
earlz 6:a4dff59ef214 176
earlz 6:a4dff59ef214 177
earlz 6:a4dff59ef214 178 void parse_line(char *line)
earlz 6:a4dff59ef214 179 {
earlz 6:a4dff59ef214 180 int len=strlen(line);
earlz 6:a4dff59ef214 181 char word[16];
earlz 6:a4dff59ef214 182 word[0]=0;
earlz 6:a4dff59ef214 183 int wordpos=0;
earlz 6:a4dff59ef214 184 WordType type=Unknown;
earlz 6:a4dff59ef214 185 for(int i=0;i<len;i++)
earlz 6:a4dff59ef214 186 {
earlz 6:a4dff59ef214 187 char c=line[i];
earlz 6:a4dff59ef214 188 if(is_whitespace(c) || c=='\\')
earlz 6:a4dff59ef214 189 {
earlz 6:a4dff59ef214 190 if(word[0]!=0)
earlz 6:a4dff59ef214 191 {
earlz 6:a4dff59ef214 192 word[wordpos]=0;
earlz 6:a4dff59ef214 193
earlz 6:a4dff59ef214 194 int tmp=compile_word(word,type);
earlz 6:a4dff59ef214 195 if(tmp==1)
earlz 6:a4dff59ef214 196 {
earlz 6:a4dff59ef214 197 execute_codeblock();
earlz 6:a4dff59ef214 198 new_codeblock(true);
earlz 6:a4dff59ef214 199 }
earlz 6:a4dff59ef214 200 word[0]=0;
earlz 6:a4dff59ef214 201 }
earlz 6:a4dff59ef214 202 wordpos=0;
earlz 6:a4dff59ef214 203 type=Unknown;
earlz 6:a4dff59ef214 204 if(c=='\\'){
earlz 6:a4dff59ef214 205 return; //rest is a comment
earlz 6:a4dff59ef214 206 }
earlz 6:a4dff59ef214 207 }else if(is_numeric(c)){
earlz 6:a4dff59ef214 208 if(type==Unknown){
earlz 6:a4dff59ef214 209 type=Number;
earlz 6:a4dff59ef214 210 }
earlz 6:a4dff59ef214 211 word[wordpos]=c;
earlz 6:a4dff59ef214 212 wordpos++;
earlz 6:a4dff59ef214 213 }else if(is_quote(c)){
earlz 6:a4dff59ef214 214 vputs("This isn't supported yet foo!");
earlz 6:a4dff59ef214 215 return;
earlz 6:a4dff59ef214 216 }else{
earlz 6:a4dff59ef214 217 if(type==Number){
earlz 6:a4dff59ef214 218 vputs("Syntax Error! Unexpected symbol in the middle of a number");
earlz 6:a4dff59ef214 219 return;
earlz 6:a4dff59ef214 220 }
earlz 6:a4dff59ef214 221 type=Word;
earlz 6:a4dff59ef214 222 word[wordpos]=c;
earlz 6:a4dff59ef214 223 wordpos++;
earlz 6:a4dff59ef214 224 }
earlz 6:a4dff59ef214 225 }
earlz 6:a4dff59ef214 226 }
earlz 6:a4dff59ef214 227
earlz 6:a4dff59ef214 228
earlz 6:a4dff59ef214 229 void tester()
earlz 6:a4dff59ef214 230 {
earlz 6:a4dff59ef214 231 printf("foo!");
earlz 6:a4dff59ef214 232 }
earlz 6:a4dff59ef214 233
earlz 6:a4dff59ef214 234 int pl_shell()
earlz 6:a4dff59ef214 235 {
earlz 6:a4dff59ef214 236 vputs(">>plEarlz -- A forth-ish shell<<\n");
earlz 6:a4dff59ef214 237 printheapstats();
earlz 6:a4dff59ef214 238 vputs("\n");
earlz 6:a4dff59ef214 239 char *line=(char*)malloc(MAXLINELENGTH);
earlz 6:a4dff59ef214 240 sprintf(line, "Stack Size: %i; Max Recursion Level %i; Loaded WORDs: %i", MAXSTACK, MAXCALLS, 0);
earlz 6:a4dff59ef214 241 vputs(line);
earlz 6:a4dff59ef214 242 sprintf(line, "Max line length: %i\n", MAXLINELENGTH);
earlz 6:a4dff59ef214 243 vputs(line);
earlz 6:a4dff59ef214 244 new_codeblock(false);
earlz 6:a4dff59ef214 245 char *tmp=(char*)malloc(32); //for constructing words/elements
earlz 6:a4dff59ef214 246 while(1)
earlz 6:a4dff59ef214 247 {
earlz 6:a4dff59ef214 248 vputs("cmd> ");
earlz 6:a4dff59ef214 249 vgetsl(line, MAXLINELENGTH);
earlz 6:a4dff59ef214 250 line[MAXLINELENGTH-1]=0;
earlz 6:a4dff59ef214 251 int len=strlen(line);
earlz 6:a4dff59ef214 252 line[len]='\n';
earlz 6:a4dff59ef214 253 line[len+1]=0;
earlz 6:a4dff59ef214 254 parse_line(line);
earlz 6:a4dff59ef214 255
earlz 6:a4dff59ef214 256 }
earlz 6:a4dff59ef214 257 free(line);
earlz 6:a4dff59ef214 258 free(tmp);
earlz 6:a4dff59ef214 259 return 0;
earlz 6:a4dff59ef214 260 }
earlz 6:a4dff59ef214 261
earlz 6:a4dff59ef214 262