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 <stdarg.h>
earlz 6:a4dff59ef214 35 #include <stdint.h>
earlz 6:a4dff59ef214 36 //Basically a non-conforming take on Forth, btw.
earlz 6:a4dff59ef214 37
earlz 6:a4dff59ef214 38 inline int internal_captureline(void* pBuffer, char const* pFormatString, ...)
earlz 6:a4dff59ef214 39 {
earlz 6:a4dff59ef214 40 char* pStringEnd = (char*)pBuffer + strlen((char*)pBuffer);
earlz 6:a4dff59ef214 41 va_list valist;
earlz 6:a4dff59ef214 42
earlz 6:a4dff59ef214 43 va_start(valist, pFormatString);
earlz 6:a4dff59ef214 44
earlz 6:a4dff59ef214 45 return vsprintf(pStringEnd, pFormatString, valist);
earlz 6:a4dff59ef214 46 }
earlz 6:a4dff59ef214 47 void printheapstats()
earlz 6:a4dff59ef214 48 {
earlz 6:a4dff59ef214 49 char buffer[256];
earlz 6:a4dff59ef214 50 __heapstats(internal_captureline, buffer);
earlz 6:a4dff59ef214 51 vputs("Memory info: ");
earlz 6:a4dff59ef214 52 vputs(buffer);
earlz 6:a4dff59ef214 53 }
earlz 6:a4dff59ef214 54
earlz 6:a4dff59ef214 55
earlz 6:a4dff59ef214 56
earlz 6:a4dff59ef214 57
earlz 6:a4dff59ef214 58
earlz 8:f356684767ef 59 BranchTarget *last_target=NULL;
earlz 7:2ac6752d47d2 60
earlz 6:a4dff59ef214 61 ErrorType pl_error=None;
earlz 6:a4dff59ef214 62
earlz 6:a4dff59ef214 63
earlz 6:a4dff59ef214 64 enum WordType
earlz 6:a4dff59ef214 65 {
earlz 6:a4dff59ef214 66 Unknown,
earlz 6:a4dff59ef214 67 Number,
earlz 6:a4dff59ef214 68 Word,
earlz 6:a4dff59ef214 69 Quote
earlz 6:a4dff59ef214 70 };
earlz 6:a4dff59ef214 71
earlz 6:a4dff59ef214 72 uint8_t *pl_codeblock;
earlz 6:a4dff59ef214 73 int pl_blockpos;
earlz 6:a4dff59ef214 74 int pl_blocksize;
earlz 6:a4dff59ef214 75
earlz 7:2ac6752d47d2 76 uint8_t* push_opcode_byte(uint8_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 pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 90 pl_blockpos++;
earlz 7:2ac6752d47d2 91 return &pl_codeblock[pl_blockpos-1];
earlz 6:a4dff59ef214 92 }
earlz 7:2ac6752d47d2 93 Opcode* push_opcode(Opcode val)
earlz 6:a4dff59ef214 94 {
earlz 6:a4dff59ef214 95 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 96 {
earlz 6:a4dff59ef214 97 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 98 if(tmp==NULL)
earlz 6:a4dff59ef214 99 {
earlz 6:a4dff59ef214 100 vputs("Out of memory!!");
earlz 6:a4dff59ef214 101 return;
earlz 6:a4dff59ef214 102 }
earlz 6:a4dff59ef214 103 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 104 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 105 }
earlz 6:a4dff59ef214 106 pl_codeblock[pl_blockpos]=(uint8_t)val;
earlz 6:a4dff59ef214 107 pl_blockpos++;
earlz 7:2ac6752d47d2 108 return (Opcode*)&pl_codeblock[pl_blockpos-1];
earlz 6:a4dff59ef214 109 }
earlz 7:2ac6752d47d2 110 uint16_t* push_opcode_word(uint16_t val)
earlz 6:a4dff59ef214 111 {
earlz 6:a4dff59ef214 112 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 113 {
earlz 6:a4dff59ef214 114 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 115 if(tmp==NULL)
earlz 6:a4dff59ef214 116 {
earlz 6:a4dff59ef214 117 vputs("Out of memory!!");
earlz 6:a4dff59ef214 118 return;
earlz 6:a4dff59ef214 119 }
earlz 6:a4dff59ef214 120 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 121 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 122 }
earlz 6:a4dff59ef214 123 *(uint16_t*)&pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 124 pl_blockpos+=2;
earlz 7:2ac6752d47d2 125 return (uint16_t*)(&pl_codeblock[pl_blockpos-2]);
earlz 6:a4dff59ef214 126 }
earlz 7:2ac6752d47d2 127 uint32_t* push_opcode_dword(uint32_t val)
earlz 6:a4dff59ef214 128 {
earlz 6:a4dff59ef214 129 if(pl_blockpos>=pl_blocksize)
earlz 6:a4dff59ef214 130 {
earlz 6:a4dff59ef214 131 void* tmp=realloc(pl_codeblock, pl_blocksize+CODEBLOCKSTEP);
earlz 6:a4dff59ef214 132 if(tmp==NULL)
earlz 6:a4dff59ef214 133 {
earlz 6:a4dff59ef214 134 vputs("Out of memory!!");
earlz 6:a4dff59ef214 135 return;
earlz 6:a4dff59ef214 136 }
earlz 6:a4dff59ef214 137 pl_codeblock=(uint8_t*)tmp;
earlz 6:a4dff59ef214 138 pl_blocksize+=CODEBLOCKSTEP;
earlz 6:a4dff59ef214 139 }
earlz 6:a4dff59ef214 140 *(uint32_t*)&pl_codeblock[pl_blockpos]=val;
earlz 6:a4dff59ef214 141 pl_blockpos+=4;
earlz 7:2ac6752d47d2 142 return (uint32_t*)&pl_codeblock[pl_blockpos-4];
earlz 6:a4dff59ef214 143 }
earlz 6:a4dff59ef214 144 void new_codeblock(bool freeit)
earlz 6:a4dff59ef214 145 {
earlz 6:a4dff59ef214 146 if(freeit)
earlz 6:a4dff59ef214 147 {
earlz 6:a4dff59ef214 148 free(pl_codeblock);
earlz 6:a4dff59ef214 149 }
earlz 6:a4dff59ef214 150 pl_codeblock=(uint8_t*)malloc(CODEBLOCKSTEP);
earlz 6:a4dff59ef214 151 pl_blockpos=0;
earlz 6:a4dff59ef214 152 pl_blocksize=CODEBLOCKSTEP;
earlz 7:2ac6752d47d2 153 last_target=NULL;
earlz 6:a4dff59ef214 154 }
earlz 6:a4dff59ef214 155 int execute_codeblock()
earlz 6:a4dff59ef214 156 {
earlz 6:a4dff59ef214 157 return forth_execute(pl_codeblock, pl_blockpos);
earlz 6:a4dff59ef214 158 }
earlz 7:2ac6752d47d2 159
earlz 7:2ac6752d47d2 160
earlz 8:f356684767ef 161 void push_target(int address)
earlz 7:2ac6752d47d2 162 {
earlz 8:f356684767ef 163 BranchTarget* target=(BranchTarget*)malloc(sizeof(BranchTarget));
earlz 7:2ac6752d47d2 164 target->previous=last_target;
earlz 7:2ac6752d47d2 165 target->target=address;
earlz 7:2ac6752d47d2 166 last_target=target;
earlz 7:2ac6752d47d2 167 }
earlz 7:2ac6752d47d2 168 void pop_target()
earlz 7:2ac6752d47d2 169 {
earlz 7:2ac6752d47d2 170 if(last_target==NULL)
earlz 7:2ac6752d47d2 171 {
earlz 7:2ac6752d47d2 172 vputs("Unmatched control statement!\n");
earlz 7:2ac6752d47d2 173 return;
earlz 7:2ac6752d47d2 174 }
earlz 7:2ac6752d47d2 175 volatile void* tmp=last_target;
earlz 7:2ac6752d47d2 176 last_target=last_target->previous;
earlz 7:2ac6752d47d2 177 free((void*)tmp);
earlz 7:2ac6752d47d2 178 }
earlz 8:f356684767ef 179 inline void write_blockword(int pos,uint16_t val)
earlz 8:f356684767ef 180 {
earlz 8:f356684767ef 181 *(uint16_t*)&pl_codeblock[pos]=val;
earlz 8:f356684767ef 182 }
earlz 6:a4dff59ef214 183
earlz 6:a4dff59ef214 184 int compile_word(char *word, WordType type) //returns 0 for success, 1 for ending word found, -1 for error
earlz 6:a4dff59ef214 185 {
earlz 6:a4dff59ef214 186 if(type==Number){
earlz 6:a4dff59ef214 187 push_opcode(Push);
earlz 6:a4dff59ef214 188 push_opcode_dword(atoi(word));
earlz 6:a4dff59ef214 189 }else{
earlz 6:a4dff59ef214 190 if(word[1]==0) //check the quick builtins first
earlz 6:a4dff59ef214 191 {
earlz 6:a4dff59ef214 192 if(word[0]=='.'){
earlz 6:a4dff59ef214 193 push_opcode(CallInt);
earlz 6:a4dff59ef214 194 push_opcode_dword((uint32_t)&bi_print);
earlz 6:a4dff59ef214 195 }else if(word[0]==';')
earlz 6:a4dff59ef214 196 {
earlz 7:2ac6752d47d2 197 push_opcode(Ret);
earlz 6:a4dff59ef214 198 //execute!
earlz 6:a4dff59ef214 199 return 1;
earlz 6:a4dff59ef214 200 }else if(word[0]=='+'){
earlz 6:a4dff59ef214 201 push_opcode(Add);
earlz 6:a4dff59ef214 202 }else if(word[0]=='/'){
earlz 6:a4dff59ef214 203 push_opcode(Div);
earlz 6:a4dff59ef214 204 }else if(word[0]=='-'){
earlz 6:a4dff59ef214 205 push_opcode(Sub);
earlz 6:a4dff59ef214 206 }else if(word[0]=='!'){
earlz 6:a4dff59ef214 207 //pl_push(pl_pop()-pl_pop());
earlz 6:a4dff59ef214 208 }else if(word[0]=='%'){
earlz 6:a4dff59ef214 209 push_opcode(Mod);
earlz 6:a4dff59ef214 210 }else if(word[0]=='*'){
earlz 6:a4dff59ef214 211 push_opcode(Mul);
earlz 6:a4dff59ef214 212 }else if(word[0]=='!'){
earlz 7:2ac6752d47d2 213 //push_opcode(Store);
earlz 6:a4dff59ef214 214 }else if(word[0]=='?'){
earlz 6:a4dff59ef214 215 pl_push(*(int*)pl_pop());
earlz 6:a4dff59ef214 216 }else if(word[0]=='='){
earlz 6:a4dff59ef214 217 pl_push(pl_pop() == pl_pop());
earlz 6:a4dff59ef214 218 }else if(word[0]=='`'){
earlz 6:a4dff59ef214 219 pl_push(pl_pop()>0);
earlz 6:a4dff59ef214 220 }else if(word[0]=='$'){
earlz 6:a4dff59ef214 221 //print string (address on stack
earlz 9:4211d638b2e9 222 }else if(word[0]=='['){
earlz 9:4211d638b2e9 223 //begin quotation
earlz 9:4211d638b2e9 224 push_opcode(Push);
earlz 9:4211d638b2e9 225 push_opcode_word(pl_blockpos+3);
earlz 9:4211d638b2e9 226 push_opcode(Branch);
earlz 9:4211d638b2e9 227 push_target(pl_blockpos);
earlz 9:4211d638b2e9 228 push_opcode_word(0);
earlz 9:4211d638b2e9 229 }else if(word[0] == ']'){
earlz 9:4211d638b2e9 230 //end quotation
earlz 9:4211d638b2e9 231 push_opcode(Ret);
earlz 9:4211d638b2e9 232 write_blockword(last_target->target, pl_blockpos);
earlz 9:4211d638b2e9 233 pop_target();
earlz 6:a4dff59ef214 234 }
earlz 6:a4dff59ef214 235 }else if(strlcmp("if", word, 3)==0){
earlz 7:2ac6752d47d2 236 push_opcode(BranchFalse);
earlz 8:f356684767ef 237 push_target(pl_blockpos);
earlz 8:f356684767ef 238 push_opcode_word(0);
earlz 7:2ac6752d47d2 239 }else if(strlcmp("else", word, 5)==0){
earlz 7:2ac6752d47d2 240 push_opcode(Branch);
earlz 8:f356684767ef 241 int tmp=pl_blockpos;
earlz 8:f356684767ef 242 push_opcode_word(0);
earlz 8:f356684767ef 243 write_blockword(last_target->target,pl_blockpos);
earlz 7:2ac6752d47d2 244 pop_target();
earlz 7:2ac6752d47d2 245 push_target(tmp); //have to do it after we pop it or we fall into an infinite loop!
earlz 7:2ac6752d47d2 246 }else if(strlcmp("end", word, 4)==0){
earlz 8:f356684767ef 247 write_blockword(last_target->target,(uint16_t)pl_blockpos);
earlz 7:2ac6752d47d2 248 pop_target();
earlz 9:4211d638b2e9 249 }else if(strlcmp("tif", word, 4)==0){
earlz 9:4211d638b2e9 250 /**
earlz 9:4211d638b2e9 251 swap value 2 behind stack to front
earlz 9:4211d638b2e9 252 call.true 1 from stack
earlz 9:4211d638b2e9 253 call.false top of stack
earlz 9:4211d638b2e9 254 _label:
earlz 9:4211d638b2e9 255 **/
earlz 9:4211d638b2e9 256 //alloca(10);
earlz 9:4211d638b2e9 257 push_opcode(Push);
earlz 9:4211d638b2e9 258 push_opcode_dword(3);
earlz 9:4211d638b2e9 259 push_opcode(Pick);
earlz 9:4211d638b2e9 260 push_opcode(BranchFalse);
earlz 9:4211d638b2e9 261 //push_opcode_word(pl_blockpos+
earlz 9:4211d638b2e9 262
earlz 6:a4dff59ef214 263 }else{
earlz 7:2ac6752d47d2 264 vputs("I don't know the word '");
earlz 6:a4dff59ef214 265 vputs(word);
earlz 7:2ac6752d47d2 266 vputs("'\n");
earlz 6:a4dff59ef214 267 }
earlz 6:a4dff59ef214 268 }
earlz 6:a4dff59ef214 269 return 0;
earlz 6:a4dff59ef214 270 }
earlz 6:a4dff59ef214 271
earlz 6:a4dff59ef214 272
earlz 6:a4dff59ef214 273
earlz 6:a4dff59ef214 274 void parse_line(char *line)
earlz 6:a4dff59ef214 275 {
earlz 6:a4dff59ef214 276 int len=strlen(line);
earlz 6:a4dff59ef214 277 char word[16];
earlz 6:a4dff59ef214 278 word[0]=0;
earlz 6:a4dff59ef214 279 int wordpos=0;
earlz 6:a4dff59ef214 280 WordType type=Unknown;
earlz 6:a4dff59ef214 281 for(int i=0;i<len;i++)
earlz 6:a4dff59ef214 282 {
earlz 6:a4dff59ef214 283 char c=line[i];
earlz 6:a4dff59ef214 284 if(is_whitespace(c) || c=='\\')
earlz 6:a4dff59ef214 285 {
earlz 6:a4dff59ef214 286 if(word[0]!=0)
earlz 6:a4dff59ef214 287 {
earlz 6:a4dff59ef214 288 word[wordpos]=0;
earlz 6:a4dff59ef214 289
earlz 6:a4dff59ef214 290 int tmp=compile_word(word,type);
earlz 6:a4dff59ef214 291 if(tmp==1)
earlz 6:a4dff59ef214 292 {
earlz 6:a4dff59ef214 293 execute_codeblock();
earlz 6:a4dff59ef214 294 new_codeblock(true);
earlz 6:a4dff59ef214 295 }
earlz 6:a4dff59ef214 296 word[0]=0;
earlz 6:a4dff59ef214 297 }
earlz 6:a4dff59ef214 298 wordpos=0;
earlz 6:a4dff59ef214 299 type=Unknown;
earlz 6:a4dff59ef214 300 if(c=='\\'){
earlz 6:a4dff59ef214 301 return; //rest is a comment
earlz 6:a4dff59ef214 302 }
earlz 6:a4dff59ef214 303 }else if(is_numeric(c)){
earlz 6:a4dff59ef214 304 if(type==Unknown){
earlz 6:a4dff59ef214 305 type=Number;
earlz 6:a4dff59ef214 306 }
earlz 6:a4dff59ef214 307 word[wordpos]=c;
earlz 6:a4dff59ef214 308 wordpos++;
earlz 6:a4dff59ef214 309 }else if(is_quote(c)){
earlz 9:4211d638b2e9 310 push_opcode(LoadStr);
earlz 9:4211d638b2e9 311 for(;i<len;i++)
earlz 9:4211d638b2e9 312 {
earlz 9:4211d638b2e9 313 //char c=line[
earlz 9:4211d638b2e9 314 }
earlz 6:a4dff59ef214 315 vputs("This isn't supported yet foo!");
earlz 6:a4dff59ef214 316 return;
earlz 6:a4dff59ef214 317 }else{
earlz 6:a4dff59ef214 318 if(type==Number){
earlz 6:a4dff59ef214 319 vputs("Syntax Error! Unexpected symbol in the middle of a number");
earlz 6:a4dff59ef214 320 return;
earlz 6:a4dff59ef214 321 }
earlz 6:a4dff59ef214 322 type=Word;
earlz 6:a4dff59ef214 323 word[wordpos]=c;
earlz 6:a4dff59ef214 324 wordpos++;
earlz 6:a4dff59ef214 325 }
earlz 6:a4dff59ef214 326 }
earlz 6:a4dff59ef214 327 }
earlz 6:a4dff59ef214 328
earlz 6:a4dff59ef214 329
earlz 6:a4dff59ef214 330 void tester()
earlz 6:a4dff59ef214 331 {
earlz 6:a4dff59ef214 332 printf("foo!");
earlz 6:a4dff59ef214 333 }
earlz 6:a4dff59ef214 334
earlz 6:a4dff59ef214 335 int pl_shell()
earlz 6:a4dff59ef214 336 {
earlz 6:a4dff59ef214 337 vputs(">>plEarlz -- A forth-ish shell<<\n");
earlz 6:a4dff59ef214 338 printheapstats();
earlz 6:a4dff59ef214 339 vputs("\n");
earlz 6:a4dff59ef214 340 char *line=(char*)malloc(MAXLINELENGTH);
earlz 9:4211d638b2e9 341 sprintf(line, "Stack Size: %i; Max Recursion Level %i; Loaded WORDs: %i", MAXSTACK, MAXTEMPSTACK, 0);
earlz 6:a4dff59ef214 342 vputs(line);
earlz 6:a4dff59ef214 343 sprintf(line, "Max line length: %i\n", MAXLINELENGTH);
earlz 6:a4dff59ef214 344 vputs(line);
earlz 6:a4dff59ef214 345 new_codeblock(false);
earlz 6:a4dff59ef214 346 char *tmp=(char*)malloc(32); //for constructing words/elements
earlz 6:a4dff59ef214 347 while(1)
earlz 6:a4dff59ef214 348 {
earlz 6:a4dff59ef214 349 vputs("cmd> ");
earlz 6:a4dff59ef214 350 vgetsl(line, MAXLINELENGTH);
earlz 6:a4dff59ef214 351 line[MAXLINELENGTH-1]=0;
earlz 6:a4dff59ef214 352 int len=strlen(line);
earlz 6:a4dff59ef214 353 line[len]='\n';
earlz 6:a4dff59ef214 354 line[len+1]=0;
earlz 6:a4dff59ef214 355 parse_line(line);
earlz 6:a4dff59ef214 356
earlz 6:a4dff59ef214 357 }
earlz 6:a4dff59ef214 358 free(line);
earlz 6:a4dff59ef214 359 free(tmp);
earlz 6:a4dff59ef214 360 return 0;
earlz 6:a4dff59ef214 361 }
earlz 6:a4dff59ef214 362
earlz 6:a4dff59ef214 363