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
forth_machine.cpp@6:a4dff59ef214, 2012-09-21 (annotated)
- Committer:
- earlz
- Date:
- Fri Sep 21 04:53:45 2012 +0000
- Revision:
- 6:a4dff59ef214
- 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?
User | Revision | Line number | New 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 | 6:a4dff59ef214 | 79 | |
earlz | 6:a4dff59ef214 | 80 | |
earlz | 6:a4dff59ef214 | 81 | int forth_execute(uint8_t* block, int length) |
earlz | 6:a4dff59ef214 | 82 | { |
earlz | 6:a4dff59ef214 | 83 | int pos=0; |
earlz | 6:a4dff59ef214 | 84 | while(pos<length) |
earlz | 6:a4dff59ef214 | 85 | { |
earlz | 6:a4dff59ef214 | 86 | |
earlz | 6:a4dff59ef214 | 87 | Opcode op=(Opcode)block[pos]; |
earlz | 6:a4dff59ef214 | 88 | //printf("opcode: %x\n",(int)op); |
earlz | 6:a4dff59ef214 | 89 | switch(op) |
earlz | 6:a4dff59ef214 | 90 | { |
earlz | 6:a4dff59ef214 | 91 | case BranchTrue: |
earlz | 6:a4dff59ef214 | 92 | if(pl_pop()){ |
earlz | 6:a4dff59ef214 | 93 | pos++; |
earlz | 6:a4dff59ef214 | 94 | pos=*((uint16_t*)&block[pos]); |
earlz | 6:a4dff59ef214 | 95 | }else{ |
earlz | 6:a4dff59ef214 | 96 | pos+=3; |
earlz | 6:a4dff59ef214 | 97 | } |
earlz | 6:a4dff59ef214 | 98 | break; |
earlz | 6:a4dff59ef214 | 99 | case BranchFalse: |
earlz | 6:a4dff59ef214 | 100 | if(!pl_pop()){ |
earlz | 6:a4dff59ef214 | 101 | pos++; |
earlz | 6:a4dff59ef214 | 102 | pos=*((uint16_t*)&block[pos]); |
earlz | 6:a4dff59ef214 | 103 | }else{ |
earlz | 6:a4dff59ef214 | 104 | pos+=3; |
earlz | 6:a4dff59ef214 | 105 | } |
earlz | 6:a4dff59ef214 | 106 | break; |
earlz | 6:a4dff59ef214 | 107 | case Branch: |
earlz | 6:a4dff59ef214 | 108 | pos++; |
earlz | 6:a4dff59ef214 | 109 | pos=*((uint16_t*)&block[pos]); |
earlz | 6:a4dff59ef214 | 110 | break; |
earlz | 6:a4dff59ef214 | 111 | case Push: |
earlz | 6:a4dff59ef214 | 112 | pos++; |
earlz | 6:a4dff59ef214 | 113 | pl_push(*(uint32_t*)&block[pos]); |
earlz | 6:a4dff59ef214 | 114 | pos+=4; |
earlz | 6:a4dff59ef214 | 115 | break; |
earlz | 6:a4dff59ef214 | 116 | case Pop: |
earlz | 6:a4dff59ef214 | 117 | pos++; |
earlz | 6:a4dff59ef214 | 118 | pl_pop(); |
earlz | 6:a4dff59ef214 | 119 | break; |
earlz | 6:a4dff59ef214 | 120 | case Add: |
earlz | 6:a4dff59ef214 | 121 | pos++; |
earlz | 6:a4dff59ef214 | 122 | pl_push(pl_pop()+pl_pop()); |
earlz | 6:a4dff59ef214 | 123 | break; |
earlz | 6:a4dff59ef214 | 124 | case Sub: |
earlz | 6:a4dff59ef214 | 125 | pos++; |
earlz | 6:a4dff59ef214 | 126 | pl_push(pl_pop()-pl_pop()); |
earlz | 6:a4dff59ef214 | 127 | break; |
earlz | 6:a4dff59ef214 | 128 | case Mul: |
earlz | 6:a4dff59ef214 | 129 | pos++; |
earlz | 6:a4dff59ef214 | 130 | pl_push(pl_pop()*pl_pop()); |
earlz | 6:a4dff59ef214 | 131 | break; |
earlz | 6:a4dff59ef214 | 132 | case Div: |
earlz | 6:a4dff59ef214 | 133 | pos++; |
earlz | 6:a4dff59ef214 | 134 | pl_push(pl_pop()/pl_pop()); |
earlz | 6:a4dff59ef214 | 135 | break; |
earlz | 6:a4dff59ef214 | 136 | case Mod: |
earlz | 6:a4dff59ef214 | 137 | pos++; |
earlz | 6:a4dff59ef214 | 138 | pl_push(pl_pop()%pl_pop()); |
earlz | 6:a4dff59ef214 | 139 | break; |
earlz | 6:a4dff59ef214 | 140 | case CallInt: |
earlz | 6:a4dff59ef214 | 141 | pos++; |
earlz | 6:a4dff59ef214 | 142 | uint32_t tmp=*(uint32_t*)&block[pos]; |
earlz | 6:a4dff59ef214 | 143 | ((BuiltinFunction)tmp)(); |
earlz | 6:a4dff59ef214 | 144 | pos+=4; |
earlz | 6:a4dff59ef214 | 145 | break; |
earlz | 6:a4dff59ef214 | 146 | |
earlz | 6:a4dff59ef214 | 147 | |
earlz | 6:a4dff59ef214 | 148 | default: |
earlz | 6:a4dff59ef214 | 149 | vputs("Unknown opcode!!"); |
earlz | 6:a4dff59ef214 | 150 | return; |
earlz | 6:a4dff59ef214 | 151 | } |
earlz | 6:a4dff59ef214 | 152 | } |
earlz | 6:a4dff59ef214 | 153 | return 0; |
earlz | 6:a4dff59ef214 | 154 | } |