Test program for Pawn 4 interpreter. Looks for a main.amx on the mbed 'drive', loads it, and calls the main() function within it.

Dependencies:   Pawn4 mbed

Welcome to the Pawn 4 mbed test program. This program is designed to show off all features of the Pawn mbed port. Currently, it will do the following:

- Create a Pawn VM instance - Add the following modules to the Pawn VM - mbed - console (used only for printf currently) - time (date/time, delay functions) - Look for a main.amx file at the root of the mbed file system. If found, will attempt to load whole file into memory. IMPORTANT: when the program opens the file on the mbed file system, the mbed will unmount itself from any connected PC/Mac, possibly resulting in a rude-looking OS message (I am looking at you OS X). It will reappear when the program closes the main.amx file. - Attempt to execute the main function in the loaded script - When the main routine returns, it will currently sit in a loop blinking LED4. It may be better to simply re-run the main routine. Perhaps a special return value can determine what we do...

Also see the Pawn4 library project for details on how to set up your development environment on the mbed itself and how to build scripts.

main.cpp

Committer:
tylerwilson
Date:
2012-11-15
Revision:
0:389e183c9e47
Child:
1:3b4d6ea39002

File content as of revision 0:389e183c9e47:

// 
// Simple Pawn 4.x test, built for the mbed LPC11U24 version
//
// Copyright (c) 2012 Tyler Wilson
//
#include <stdarg.h>
#include <stdlib.h>

#include "mbed.h"

#include "amx.h"
#include "amxaux.h"
#include "amxconsole.h"
#include "amxmbed.h"
#include "amxpool.h"

#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
    #define MAX_IMAGE 1024*32
#elif defined(TARGET_LPC11U24)
    #define MAX_IMAGE 1024*4
#endif

// Objects we may need
DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
Serial pc(USBTX, USBRX);
LocalFileSystem local("local");

// local prototypes
//int aux_LoadProgram(AMX* amx, const char* filename);
//int aux_FreeProgram(AMX* amx);
void mbed_set_serial(Serial* serial);
//int heap_stats_callback(void* pBuffer, char const* pFormatString, ...);


int main()
{
    // set up our default speed
    pc.baud(115200);
    
    // so the Pawn interpreter sends/gets to/from the right place
    mbed_set_serial(&pc);
    
    pc.printf("Pawn running on ");
#if defined(TARGET_LPC1768)
    pc.printf("mbed LPC1768");
#elif defined(TARGET_LPC2368)
    pc.printf("mbed LPC2368");
#elif defined(TARGET_LPC11U24)
    pc.printf("mbed LPC11U24");
#else
    pc.printf("unknown");
#endif    
    pc.printf("\n\r");

    int err = AMX_ERR_NONE;
    AMX amx;
    
    // init pool for the overlays (not on M0 [most likely])
//    void* pool = malloc(4096);
//    amx_poolinit(pool, 4096);

    // how much memory to completely load and run this script
    size_t size = aux_ProgramSize("/local/main.amx");
    pc.printf("/local/main.amx needs %d of memory\n\r", size);

    pc.printf("loading /local/main.amx\n\r");
    err = aux_LoadProgram(&amx, "/local/main.amx", 0);

#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
    pc.printf("Finished loading, with result %s.\n\r", aux_StrError(err));
#else
    pc.printf("Finished loading, with result %d.\n\r", err);
#endif

    if (err == AMX_ERR_NONE)
    {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
        // some debug output. remove on M0 part due to low memory
        
        int count = 0, r = 0, i = 0;
        ucell uaddr;
        cell *addr;

        // what natives this script calls
        r = amx_NumNatives(&amx, &count);
        pc.printf("natives: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetNative(&amx, i, temp);
            pc.printf("native: %s\n\r", temp);
        }

        // what public functions this script exposes
        r = amx_NumPublics(&amx, &count);
        pc.printf("publics: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetPublic(&amx, i, temp, &uaddr);
            pc.printf("public: %s, %x\n\r", temp, uaddr);
        }

        // what public variables are defined in this script
        r = amx_NumPubVars(&amx, &count);
        pc.printf("pubvars: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetPubVar(&amx, i, temp, &addr);
            pc.printf("pubvar: %s, %x\n\r", temp, addr);
        }
        
        // what tags are defined in this script
        r = amx_NumTags(&amx, &count);
        pc.printf("tags: %d (result:%d)\n\r", count, r);
        pc.printf("\n\r");
#endif
        
        // for print and friends
        amx_ConsoleInit(&amx);
        
        // for mbed-specific functions
        amx_mbedInit(&amx);
        
        // make the first call into the main function.
        cell ret;
        pc.printf("calling main() via amx_Exec\n\r");
        err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN);
        pc.printf("amx_Exec returned %d, main returned %d\n\r", err, ret);
        
        // as long as the script is waiting, we will keep running
        while (err == AMX_ERR_SLEEP)
        {
            // let other parts of the system run (needed? script should be calling wait as well)
//            wait_ms(10);
            
            err = amx_Exec(&amx, &ret, AMX_EXEC_CONT);
            pc.printf("amx_Exec returned %d, main returned %d\n\r", err, ret);
        }
        
        // should not get here in most cases, but we should be clean anyway
        pc.printf("calling auxFreeProgram\n\r");
        aux_FreeProgram(&amx);
        pc.printf("called auxFreeProgram\n\r");
    }        

    // go into a loop so the user knows we have exited the script
    while (true)
    {
        led4 = !led4;
        wait_ms(500);
    }
}

#if 0
// additions to amx.h (for CC254x):
//
#if defined __ICC8051__
  #define HAVE_STDINT_H 0
  #define AMX_ANSIONLY 1
#endif

// additions to osdefs.h (for mbed):
//
//#if defined(__ARMCC_VERSION)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
    #define AMX_ANSIONLY 1
    #define AMX_NODYNALOAD 1
    #define AMX_TERMINAL 1

    #define stime(x) (x)
    
    // for the io functions putc, getc, etc.
//    #include "_amxmbed.h"
#endif
#endif