IPS(Interpreter for Process Structures) for mbed

Dependencies:   ConfigFile FATFileSystem mbed

IPS port from linux/unix version.

mbed_blinky.ips

0 VAR led1
" LED1 " DigitalOut led1 !
: main
    ANFANG
    1 JA?
      1 led1 @ write
      200 wait_ms
      0 led1 @ write
      200 wait_ms
    DANN/NOCHMAL
;
main

main.cpp

Committer:
va009039
Date:
2015-05-23
Revision:
2:908338b1151a
Parent:
1:e74530ad6b9e
Child:
3:9f526f0d9720

File content as of revision 2:908338b1151a:

// main.cpp 2015/5/23
#include <new>
#include "mbed.h"
#include "BaseIPS.h"
#include "VideoRAM.h"
#include "VirtualRAM.h"
#include "IPS-Mmbed_bin.h"
#include "mbedAPI.h"
#include "SDFileSystem.h"
#include "ConfigFile.h"

const char* CFG_FILE = "/local/ips.cfg";

#ifdef TARGET_FF_ARDUINO
#define MBED_SPI0 D11, D12, D13, D4
#endif
SDFileSystem local(MBED_SPI0, "local");  //  mosi, miso, sclk, cs, name

RawSerial pc(USBTX,USBRX);

template<class SERIAL_T>
class myips : public BaseIPS {
    VideoRAM<SERIAL_T> vram;
    VirtualRAM mem;
    SERIAL_T& _pc;
    mbedAPI mbedapi;
    Timer t20ms;
public:
    myips(SERIAL_T& pc): vram(pc),_pc(pc),mbedapi(*this) {
        t20ms.reset();
        t20ms.start();
    }
    virtual uint8_t mem_peek(uint16_t a) {
        return mem.peek(a);
    }
    virtual void mem_poke(uint16_t a, uint8_t b) {
        mem.poke(a, b);
        vram.vpoke(a, b);
    }
    virtual void* file_open(const char* filename, const char* mode) {
        if (filename[0] == '/') {
            return fopen(filename, mode);
        }
        char path[128];
        snprintf(path, sizeof(path), "/local/%s", filename);
        return fopen(path, mode);
    }
    virtual int file_getc(void* handle) {
        int c = fgetc((FILE*)handle);
        return c == EOF ? (-1) : c;
    }
    virtual void file_putc(int c, void* handle) {
        fputc(c, (FILE*)handle);
    }
    virtual bool file_close(void* handle) {
        return fclose((FILE*)handle) == 0 ? true : false;
    }
    virtual bool test_20ms() {
        if (t20ms.read_ms() >= 20) {
            t20ms.reset();
            return true;
        }
        return false;
    }

    virtual void do_io() {
        if (_pc.readable()) {
            int c = _pc.getc();
            if (c == '\n' || c == '\r') {
                if (input_ptr != peek(a_PI)) {
                   pokeB(READYFLAG, 1);
                   poke(a_PE, input_ptr - 1);
                }
            else if (c == 0x08) // BS
                if (input_ptr > 0) {
                    input_ptr--;
                }
            } else {
                if (input_ptr <= TVE) {
                    pokeB(input_ptr++, c);
                }
            }
        }
    }
    virtual void usercode(uint16_t cpc) {
        switch(cpc) {
            case 80: break; // c_sleepifidle(void)
            case 96: mbedapi.code(); break;
            default: error("code(#%x) not implemented!", cpc);
        }
    }
};

void no_memory () {
  perror("Failed to allocate memory!");
}

int main() {
    std::set_new_handler(no_memory);

    char* image = NULL;
    char* cmd = NULL;
    if (CFG_FILE) {
        ConfigFile cfg;
        if(cfg.read(const_cast<char*>(CFG_FILE))) {
            char buf[128];
            if (cfg.getValue(const_cast<char*>("image"), buf, sizeof(buf))) {
                static char buf2[128];
                snprintf(buf2, sizeof(buf2), "%s", buf);
                image = buf2;
            }
            if (cfg.getValue(const_cast<char*>("file"), buf, sizeof(buf))) {
                static char buf2[128];
                snprintf(buf2, sizeof(buf2), "\" %s \" READ", buf);
                cmd = buf2;
            }
            if (cfg.getValue(const_cast<char*>("cmd"), buf, sizeof(buf))) {
                cmd = buf;
            }
        }
    }

    myips<RawSerial> ips(pc);
    if (image != NULL) {
        void* fh = ips.file_open(image, "rb");
        if (fh == NULL) {
            pc.printf("file open error [%s]\n", image);
            image = NULL;
        } else {
            for(int i = 0; i <= 65535; i++) {
                int c = ips.file_getc(fh);
                if (c == (-1)) {
                    break;
                }
                ips.pokeB(i, c);
            }
            ips.file_close(fh);
        }
    }
    if (image == NULL) {
        for(size_t i = 0; i < sizeof(IPS_Mmbed_bin); i++) {
            ips.pokeB(i, IPS_Mmbed_bin[i]);
        }
    }
    if (cmd) {
        ips.command(cmd);
    }
    ips.emulator();
    std::exit(1);
}