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
Revision:
2:908338b1151a
Parent:
1:e74530ad6b9e
Child:
3:9f526f0d9720
diff -r e74530ad6b9e -r 908338b1151a main.cpp
--- a/main.cpp	Wed May 13 18:39:01 2015 +0900
+++ b/main.cpp	Sat May 23 16:50:59 2015 +0900
@@ -1,59 +1,60 @@
-// main.cpp 2015/5/13
+// 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"
-#include <string>
 
-#define CFG_FILE "/local/ips.cfg"
+const char* CFG_FILE = "/local/ips.cfg";
 
-#ifndef MBED_SPI0
+#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 vram;
+    VideoRAM<SERIAL_T> vram;
     VirtualRAM mem;
-    RawSerial& _pc;
+    SERIAL_T& _pc;
+    mbedAPI mbedapi;
     Timer t20ms;
 public:
-    myips(RawSerial& pc): vram(pc),_pc(pc) {
+    myips(SERIAL_T& pc): vram(pc),_pc(pc),mbedapi(*this) {
         t20ms.reset();
         t20ms.start();
     }
-     virtual u8 peekB(u16 a) {
+    virtual uint8_t mem_peek(uint16_t a) {
         return mem.peek(a);
     }
-    virtual void pokeB(u16 a, u8 b) {
+    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) {
-        string path = string("/local/") + filename;
-        return fopen(path.c_str(), 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) {
-        MBED_ASSERT(handle);
         int c = fgetc((FILE*)handle);
         return c == EOF ? (-1) : c;
     }
     virtual void file_putc(int c, void* handle) {
-        MBED_ASSERT(handle);
         fputc(c, (FILE*)handle);
     }
     virtual bool file_close(void* handle) {
-        MBED_ASSERT(handle);
-        if (fclose((FILE*)handle) == 0) {
-            return true;
-        }
-        return false;
+        return fclose((FILE*)handle) == 0 ? true : false;
     }
-
     virtual bool test_20ms() {
         if (t20ms.read_ms() >= 20) {
             t20ms.reset();
@@ -81,44 +82,70 @@
             }
         }
     }
+    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() {
-    string image = "IPS-Mu.bin";
-    string file;
-    string cmd;
-    ConfigFile cfg;
-    if(cfg.read(CFG_FILE)) {
-        char buf[128];
-        if (cfg.getValue("image", buf, sizeof(buf))) {
-            image = buf;
-        }
-        if (cfg.getValue("file", buf, sizeof(buf))) {
-            file = buf;
-            cmd = string("\" ") + file + string(" \" READ");
-        }
-        if (cfg.getValue("cmd", buf, sizeof(buf))) {
-            cmd = buf;
+    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* ips = new myips(pc);
-    void* fh = ips->file_open(image.c_str(), "rb");
-    MBED_ASSERT(fh);
-    if (fh) {
-        for(int i = 0; i <= 65535; i++) {
-            int c = ips->file_getc(fh);
-            if (c == (-1)) {
-                break;
+    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->pokeB(i, c);
+            ips.file_close(fh);
         }
-        ips->file_close(fh);
     }
-    if (cmd != "") {
-        ips->command(cmd.c_str());
+    if (image == NULL) {
+        for(size_t i = 0; i < sizeof(IPS_Mmbed_bin); i++) {
+            ips.pokeB(i, IPS_Mmbed_bin[i]);
+        }
     }
-    ips->emulator();
-    /* NOTREACHED */
+    if (cmd) {
+        ips.command(cmd);
+    }
+    ips.emulator();
+    std::exit(1);
 }