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

Committer:
earlz
Date:
2012-09-22
Revision:
7:2ac6752d47d2
Parent:
6:a4dff59ef214
Child:
8:f356684767ef

File content as of revision 7:2ac6752d47d2:

#include "mbedconsole.h"
#include "plEarlz.h"
#include <stdint.h>
#include <stdarg.h>


//An extremely simple virtual machine to make this implementation about 10 times easier and probably a bit faster





int pl_stackpos=0;
int pl_stack[MAXSTACK];




int pl_dictionary_count=0;
int pl_dictionary_size=0;
WordKey *pl_dictionary; //todo: a hash table would be much faster

void pl_push(int val)
{
    if(pl_stackpos>=MAXSTACK)
    {
        vputs("Stack overflow!");
        pl_error=StackOverflow;
        return;
    }
    pl_stack[pl_stackpos]=val;
    pl_stackpos++;
}
int pl_pop()
{
    if(pl_stackpos<=0)
    {
        vputs("Stack underflow!");
        pl_error=StackUnderflow;
        return 0;
    }
    pl_stackpos--;
    return pl_stack[pl_stackpos];
}

WordKey *pl_lookup(char* name)
{
    for(int i=0;i<pl_dictionary_count;i++)
    {
        if(strlcmp(name, pl_dictionary[i].name, 12)==0)
        {
            return &pl_dictionary[i];
        }
    }
    return NULL;
}

int pl_addword()
{
    if(pl_dictionary_size==0){
        pl_dictionary=(WordKey*)malloc(sizeof(WordKey)*12);
        pl_dictionary_size=12;
        return 0;
    }
    if(pl_dictionary_size<=pl_dictionary_count)
    {
        void* tmp=realloc(pl_dictionary, pl_dictionary_size+sizeof(WordKey)*DICTIONARYSTEP);
        if(tmp==NULL)
        {
            vputs("Out of memory!! Epic Fail!!");
            return -1;
        }
        pl_dictionary=(WordKey*)tmp;
        pl_dictionary_size+=sizeof(WordKey)*DICTIONARYSTEP;
    }
    return pl_dictionary_count++;
}



int forth_execute(uint8_t* block, int length)
{
    uint16_t pos=0;
    while(pos<length)
    {
        serial.getc();
        Opcode op=(Opcode)block[pos];
        printf("opcode: %x\r\n",(int)op);
        switch(op)
        {
            case BranchTrue:
                if(pl_pop()){
                    pos++;
                    pos=*((uint16_t*)&block[pos]);
                    
                }else{
                    pos+=3;
                }
                break;
            case BranchFalse:
                if(!pl_pop()){
                    pos++;
                    pos=*((uint16_t*)&block[pos]);
                    serial.printf("branch false %x\r\n",(int)pos);
                }else{
                    pos+=3;
                    serial.printf("branch false skip %x\r\n", (int)pos);
                }
                break;
            case Branch:
                pos++;
                pos=*((uint16_t*)&block[pos]);
            break;
            case Push:
                pos++;
                pl_push(*(uint32_t*)&block[pos]);
                pos+=4;
                break;
            case Pop:
                pos++;
                pl_pop();
                break;
            case Add:
                pos++;
                pl_push(pl_pop()+pl_pop());
                break;
            case Sub:
                pos++;
                pl_push(pl_pop()-pl_pop());
                break;
            case Mul:
                pos++;
                pl_push(pl_pop()*pl_pop());
                break;
            case Div:
                pos++;
                pl_push(pl_pop()/pl_pop());
                break;
            case Mod:
                pos++;
                pl_push(pl_pop()%pl_pop());
                break;
            case CallInt:
                pos++;
                uint32_t tmp=*(uint32_t*)&block[pos];
                ((BuiltinFunction)tmp)();
                pos+=4;
                break;
            case Ret:
                return;
            
                
            default:
                vputs("Unknown opcode!!");
                return;
        }
    }
    return 0;
}