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:
Mon Apr 15 02:37:02 2013 +0000
Revision:
20:13556e5bac04
Parent:
16:370b9e559f92
Finally got SD card support working. WOW that was trickier than I expected

Who changed what in which revision?

UserRevisionLine numberNew contents of line
earlz 16:370b9e559f92 1 /*
earlz 16:370b9e559f92 2 <Copyright Header>
earlz 16:370b9e559f92 3 Copyright (c) 2012 Jordan "Earlz" Earls <http://lastyearswishes.com>
earlz 16:370b9e559f92 4 All rights reserved.
earlz 16:370b9e559f92 5
earlz 16:370b9e559f92 6 Redistribution and use in source and binary forms, with or without
earlz 16:370b9e559f92 7 modification, are permitted provided that the following conditions
earlz 16:370b9e559f92 8 are met:
earlz 16:370b9e559f92 9
earlz 16:370b9e559f92 10 1. Redistributions of source code must retain the above copyright
earlz 16:370b9e559f92 11 notice, this list of conditions and the following disclaimer.
earlz 16:370b9e559f92 12 2. Redistributions in binary form must reproduce the above copyright
earlz 16:370b9e559f92 13 notice, this list of conditions and the following disclaimer in the
earlz 16:370b9e559f92 14 documentation and/or other materials provided with the distribution.
earlz 16:370b9e559f92 15 3. The name of the author may not be used to endorse or promote products
earlz 16:370b9e559f92 16 derived from this software without specific prior written permission.
earlz 16:370b9e559f92 17
earlz 16:370b9e559f92 18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
earlz 16:370b9e559f92 19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
earlz 16:370b9e559f92 20 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
earlz 16:370b9e559f92 21 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
earlz 16:370b9e559f92 22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
earlz 16:370b9e559f92 23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
earlz 16:370b9e559f92 24 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
earlz 16:370b9e559f92 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
earlz 16:370b9e559f92 26 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
earlz 16:370b9e559f92 27 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
earlz 16:370b9e559f92 28
earlz 16:370b9e559f92 29 This file is part of the MbedConsole project
earlz 16:370b9e559f92 30 */
earlz 16:370b9e559f92 31
earlz 6:a4dff59ef214 32 #include "mbedconsole.h"
earlz 6:a4dff59ef214 33 #include "plEarlz.h"
earlz 6:a4dff59ef214 34 #include <stdint.h>
earlz 6:a4dff59ef214 35 #include <stdarg.h>
earlz 6:a4dff59ef214 36
earlz 6:a4dff59ef214 37
earlz 6:a4dff59ef214 38 //An extremely simple virtual machine to make this implementation about 10 times easier and probably a bit faster
earlz 6:a4dff59ef214 39
earlz 6:a4dff59ef214 40
earlz 6:a4dff59ef214 41
earlz 6:a4dff59ef214 42
earlz 6:a4dff59ef214 43
earlz 6:a4dff59ef214 44 int pl_stackpos=0;
earlz 6:a4dff59ef214 45 int pl_stack[MAXSTACK];
earlz 6:a4dff59ef214 46
earlz 6:a4dff59ef214 47
earlz 6:a4dff59ef214 48
earlz 6:a4dff59ef214 49
earlz 6:a4dff59ef214 50 int pl_dictionary_count=0;
earlz 6:a4dff59ef214 51 int pl_dictionary_size=0;
earlz 6:a4dff59ef214 52 WordKey *pl_dictionary; //todo: a hash table would be much faster
earlz 6:a4dff59ef214 53
earlz 6:a4dff59ef214 54 void pl_push(int val)
earlz 6:a4dff59ef214 55 {
earlz 6:a4dff59ef214 56 if(pl_stackpos>=MAXSTACK)
earlz 6:a4dff59ef214 57 {
earlz 6:a4dff59ef214 58 vputs("Stack overflow!");
earlz 6:a4dff59ef214 59 pl_error=StackOverflow;
earlz 6:a4dff59ef214 60 return;
earlz 6:a4dff59ef214 61 }
earlz 6:a4dff59ef214 62 pl_stack[pl_stackpos]=val;
earlz 6:a4dff59ef214 63 pl_stackpos++;
earlz 6:a4dff59ef214 64 }
earlz 6:a4dff59ef214 65 int pl_pop()
earlz 6:a4dff59ef214 66 {
earlz 6:a4dff59ef214 67 if(pl_stackpos<=0)
earlz 6:a4dff59ef214 68 {
earlz 6:a4dff59ef214 69 vputs("Stack underflow!");
earlz 6:a4dff59ef214 70 pl_error=StackUnderflow;
earlz 6:a4dff59ef214 71 return 0;
earlz 6:a4dff59ef214 72 }
earlz 6:a4dff59ef214 73 pl_stackpos--;
earlz 6:a4dff59ef214 74 return pl_stack[pl_stackpos];
earlz 6:a4dff59ef214 75 }
earlz 6:a4dff59ef214 76
earlz 6:a4dff59ef214 77 WordKey *pl_lookup(char* name)
earlz 6:a4dff59ef214 78 {
earlz 6:a4dff59ef214 79 for(int i=0;i<pl_dictionary_count;i++)
earlz 6:a4dff59ef214 80 {
earlz 6:a4dff59ef214 81 if(strlcmp(name, pl_dictionary[i].name, 12)==0)
earlz 6:a4dff59ef214 82 {
earlz 6:a4dff59ef214 83 return &pl_dictionary[i];
earlz 6:a4dff59ef214 84 }
earlz 6:a4dff59ef214 85 }
earlz 6:a4dff59ef214 86 return NULL;
earlz 6:a4dff59ef214 87 }
earlz 6:a4dff59ef214 88
earlz 6:a4dff59ef214 89 int pl_addword()
earlz 6:a4dff59ef214 90 {
earlz 6:a4dff59ef214 91 if(pl_dictionary_size==0){
earlz 6:a4dff59ef214 92 pl_dictionary=(WordKey*)malloc(sizeof(WordKey)*12);
earlz 6:a4dff59ef214 93 pl_dictionary_size=12;
earlz 6:a4dff59ef214 94 return 0;
earlz 6:a4dff59ef214 95 }
earlz 6:a4dff59ef214 96 if(pl_dictionary_size<=pl_dictionary_count)
earlz 6:a4dff59ef214 97 {
earlz 6:a4dff59ef214 98 void* tmp=realloc(pl_dictionary, pl_dictionary_size+sizeof(WordKey)*DICTIONARYSTEP);
earlz 6:a4dff59ef214 99 if(tmp==NULL)
earlz 6:a4dff59ef214 100 {
earlz 6:a4dff59ef214 101 vputs("Out of memory!! Epic Fail!!");
earlz 6:a4dff59ef214 102 return -1;
earlz 6:a4dff59ef214 103 }
earlz 6:a4dff59ef214 104 pl_dictionary=(WordKey*)tmp;
earlz 6:a4dff59ef214 105 pl_dictionary_size+=sizeof(WordKey)*DICTIONARYSTEP;
earlz 6:a4dff59ef214 106 }
earlz 6:a4dff59ef214 107 return pl_dictionary_count++;
earlz 6:a4dff59ef214 108 }
earlz 6:a4dff59ef214 109
earlz 13:442bd2fb4ea0 110
earlz 13:442bd2fb4ea0 111 typedef struct CallStateStruct
earlz 13:442bd2fb4ea0 112 {
earlz 13:442bd2fb4ea0 113 int lastcall; //the pl_temppos when this word was first called
earlz 13:442bd2fb4ea0 114 CallStateStruct* previous;
earlz 13:442bd2fb4ea0 115 } CallState;
earlz 13:442bd2fb4ea0 116
earlz 9:4211d638b2e9 117 int pl_tempstack[MAXTEMPSTACK];
earlz 9:4211d638b2e9 118 int pl_temppos=0;
earlz 13:442bd2fb4ea0 119 CallState* callstate;
earlz 9:4211d638b2e9 120 void pl_temppush(int val)
earlz 9:4211d638b2e9 121 {
earlz 9:4211d638b2e9 122 if(pl_temppos>=MAXTEMPSTACK)
earlz 9:4211d638b2e9 123 {
earlz 9:4211d638b2e9 124 vputs("Temporary stack overflow\n");
earlz 9:4211d638b2e9 125 return;
earlz 9:4211d638b2e9 126 }
earlz 9:4211d638b2e9 127 pl_tempstack[pl_temppos]=val;
earlz 9:4211d638b2e9 128 pl_temppos++;
earlz 9:4211d638b2e9 129 }
earlz 9:4211d638b2e9 130 int pl_temppop()
earlz 9:4211d638b2e9 131 {
earlz 9:4211d638b2e9 132 if(pl_temppos<=0)
earlz 9:4211d638b2e9 133 {
earlz 9:4211d638b2e9 134 vputs("Temporary stack underflow\n");
earlz 9:4211d638b2e9 135 return 0;
earlz 9:4211d638b2e9 136 }
earlz 9:4211d638b2e9 137 return pl_tempstack[pl_temppos--];
earlz 9:4211d638b2e9 138 }
earlz 6:a4dff59ef214 139
earlz 6:a4dff59ef214 140 int forth_execute(uint8_t* block, int length)
earlz 6:a4dff59ef214 141 {
earlz 7:2ac6752d47d2 142 uint16_t pos=0;
earlz 8:f356684767ef 143 printf("block length: %x\r\n",length);
earlz 6:a4dff59ef214 144 while(pos<length)
earlz 6:a4dff59ef214 145 {
earlz 8:f356684767ef 146 //serial.getc();
earlz 6:a4dff59ef214 147 Opcode op=(Opcode)block[pos];
earlz 8:f356684767ef 148 printf("pos: %x -- opcode: %x\r\n",(int)pos, (int)op);
earlz 6:a4dff59ef214 149 switch(op)
earlz 6:a4dff59ef214 150 {
earlz 6:a4dff59ef214 151 case BranchTrue:
earlz 6:a4dff59ef214 152 if(pl_pop()){
earlz 6:a4dff59ef214 153 pos++;
earlz 6:a4dff59ef214 154 pos=*((uint16_t*)&block[pos]);
earlz 7:2ac6752d47d2 155
earlz 6:a4dff59ef214 156 }else{
earlz 6:a4dff59ef214 157 pos+=3;
earlz 6:a4dff59ef214 158 }
earlz 6:a4dff59ef214 159 break;
earlz 6:a4dff59ef214 160 case BranchFalse:
earlz 6:a4dff59ef214 161 if(!pl_pop()){
earlz 6:a4dff59ef214 162 pos++;
earlz 8:f356684767ef 163 serial.printf("branch false %x\r\n",(int)pos);
earlz 6:a4dff59ef214 164 pos=*((uint16_t*)&block[pos]);
earlz 7:2ac6752d47d2 165 serial.printf("branch false %x\r\n",(int)pos);
earlz 6:a4dff59ef214 166 }else{
earlz 6:a4dff59ef214 167 pos+=3;
earlz 7:2ac6752d47d2 168 serial.printf("branch false skip %x\r\n", (int)pos);
earlz 6:a4dff59ef214 169 }
earlz 6:a4dff59ef214 170 break;
earlz 6:a4dff59ef214 171 case Branch:
earlz 6:a4dff59ef214 172 pos++;
earlz 6:a4dff59ef214 173 pos=*((uint16_t*)&block[pos]);
earlz 6:a4dff59ef214 174 break;
earlz 6:a4dff59ef214 175 case Push:
earlz 6:a4dff59ef214 176 pos++;
earlz 6:a4dff59ef214 177 pl_push(*(uint32_t*)&block[pos]);
earlz 6:a4dff59ef214 178 pos+=4;
earlz 6:a4dff59ef214 179 break;
earlz 9:4211d638b2e9 180 case Drop:
earlz 6:a4dff59ef214 181 pos++;
earlz 6:a4dff59ef214 182 pl_pop();
earlz 6:a4dff59ef214 183 break;
earlz 6:a4dff59ef214 184 case Add:
earlz 6:a4dff59ef214 185 pos++;
earlz 6:a4dff59ef214 186 pl_push(pl_pop()+pl_pop());
earlz 6:a4dff59ef214 187 break;
earlz 6:a4dff59ef214 188 case Sub:
earlz 6:a4dff59ef214 189 pos++;
earlz 6:a4dff59ef214 190 pl_push(pl_pop()-pl_pop());
earlz 6:a4dff59ef214 191 break;
earlz 6:a4dff59ef214 192 case Mul:
earlz 6:a4dff59ef214 193 pos++;
earlz 6:a4dff59ef214 194 pl_push(pl_pop()*pl_pop());
earlz 6:a4dff59ef214 195 break;
earlz 6:a4dff59ef214 196 case Div:
earlz 6:a4dff59ef214 197 pos++;
earlz 6:a4dff59ef214 198 pl_push(pl_pop()/pl_pop());
earlz 6:a4dff59ef214 199 break;
earlz 6:a4dff59ef214 200 case Mod:
earlz 6:a4dff59ef214 201 pos++;
earlz 6:a4dff59ef214 202 pl_push(pl_pop()%pl_pop());
earlz 6:a4dff59ef214 203 break;
earlz 8:f356684767ef 204 case Cgt:
earlz 8:f356684767ef 205 pos++;
earlz 8:f356684767ef 206 pl_push(pl_pop()>pl_pop());
earlz 8:f356684767ef 207 break;
earlz 8:f356684767ef 208 case Clt:
earlz 8:f356684767ef 209 pos++;
earlz 8:f356684767ef 210 pl_push(pl_pop()<pl_pop());
earlz 8:f356684767ef 211 break;
earlz 8:f356684767ef 212 case Cgte:
earlz 8:f356684767ef 213 pos++;
earlz 8:f356684767ef 214 pl_push(pl_pop()>=pl_pop());
earlz 8:f356684767ef 215 break;
earlz 8:f356684767ef 216 case Clte:
earlz 8:f356684767ef 217 pos++;
earlz 8:f356684767ef 218 pl_push(pl_pop()<=pl_pop());
earlz 8:f356684767ef 219 break;
earlz 8:f356684767ef 220 case Ceq:
earlz 8:f356684767ef 221 pos++;
earlz 8:f356684767ef 222 pl_push(pl_pop()==pl_pop());
earlz 8:f356684767ef 223 break;
earlz 8:f356684767ef 224 case Cneq:
earlz 8:f356684767ef 225 pos++;
earlz 8:f356684767ef 226 pl_push(pl_pop()!=pl_pop());
earlz 8:f356684767ef 227 break;
earlz 9:4211d638b2e9 228 case CallInt:{
earlz 6:a4dff59ef214 229 pos++;
earlz 6:a4dff59ef214 230 uint32_t tmp=*(uint32_t*)&block[pos];
earlz 6:a4dff59ef214 231 ((BuiltinFunction)tmp)();
earlz 6:a4dff59ef214 232 pos+=4;
earlz 9:4211d638b2e9 233 break;}
earlz 9:4211d638b2e9 234 case Swap:{
earlz 9:4211d638b2e9 235 pos++;
earlz 9:4211d638b2e9 236 int tmp=pl_pop();
earlz 9:4211d638b2e9 237 int tmp2=pl_pop();
earlz 9:4211d638b2e9 238 pl_push(tmp);
earlz 9:4211d638b2e9 239 pl_push(tmp2);
earlz 6:a4dff59ef214 240 break;
earlz 9:4211d638b2e9 241 }
earlz 9:4211d638b2e9 242 case PushTemp:
earlz 9:4211d638b2e9 243 pos++;
earlz 9:4211d638b2e9 244 pl_temppush(pl_pop());
earlz 9:4211d638b2e9 245 break;
earlz 9:4211d638b2e9 246 case PopTemp:
earlz 9:4211d638b2e9 247 pos++;
earlz 9:4211d638b2e9 248 pl_push(pl_temppop());
earlz 9:4211d638b2e9 249 case Pick:{
earlz 9:4211d638b2e9 250 pos++;
earlz 9:4211d638b2e9 251 int tmp=pl_pop();
earlz 9:4211d638b2e9 252 if(pl_stackpos-tmp>0){
earlz 9:4211d638b2e9 253 pl_push(pl_stack[pl_stackpos-tmp]);
earlz 9:4211d638b2e9 254
earlz 9:4211d638b2e9 255 }else{
earlz 9:4211d638b2e9 256 pl_push(0);
earlz 9:4211d638b2e9 257 vputs("Stack underflow on pick\n");
earlz 9:4211d638b2e9 258 }
earlz 9:4211d638b2e9 259 break;}
earlz 7:2ac6752d47d2 260 case Ret:
earlz 8:f356684767ef 261 return 0;
earlz 6:a4dff59ef214 262
earlz 6:a4dff59ef214 263
earlz 6:a4dff59ef214 264 default:
earlz 6:a4dff59ef214 265 vputs("Unknown opcode!!");
earlz 6:a4dff59ef214 266 return;
earlz 6:a4dff59ef214 267 }
earlz 6:a4dff59ef214 268 }
earlz 6:a4dff59ef214 269 return 0;
earlz 6:a4dff59ef214 270 }