This is the open source Pawn interpreter ported to mbed. See here: http://www.compuphase.com/pawn/pawn.htm and here: http://code.google.com/p/pawnscript/
Some instructions:
- Put the attached include folder next to your source, so when you compile you get all the proper definitions
- Use the attached main.p as a starting point if you wish
- Compile your main.p into main.amx - Put your main.amx on the mbed 'drive'
- Reset and be amazed.
Important Compile Notes:
- You should use the -S# option to define a smaller default stack size. Start with -S64 and go up from there if needed.
- To use on the Cortex-M0 version of the mbed (LPC11U24), you MUST include the TARGET=3 command-line option as well, so the pin names are properly defined. In the future this may be handled on the native code side.
Known Issues:
At the moment it appears the kbhit() function is not working right - at least on my mac. Will continue testing on Windows.Working fine.
Todo:
- Add more wrappers for the mbed peripherals
- Add Pawn overlay support, to allow much larger scripts to run (even on the LPC11U24)
Diff: amxaux.c
- Revision:
- 0:3ab1d2d14eb3
diff -r 000000000000 -r 3ab1d2d14eb3 amxaux.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amxaux.c Thu Nov 15 17:41:21 2012 +0000 @@ -0,0 +1,164 @@ +/* Support routines for the Pawn Abstract Machine + * + * Copyright (c) ITB CompuPhase, 2003-2011 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Version: $Id: amxaux.c 4523 2011-06-21 15:03:47Z thiadmer $ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "amx.h" +#include "amxaux.h" + +size_t AMXAPI aux_ProgramSize(const char *filename) +{ + FILE *fp; + AMX_HEADER hdr; + + if ((fp=fopen(filename,"rb")) == NULL) + return 0; + fread(&hdr, sizeof hdr, 1, fp); + fclose(fp); + + amx_Align16(&hdr.magic); + amx_Align32((uint32_t *)&hdr.stp); + return (hdr.magic==AMX_MAGIC) ? (size_t)hdr.stp : 0; +} + +int AMXAPI aux_LoadProgram(AMX *amx, const char *filename, void *memblock) +{ + FILE *fp; + AMX_HEADER hdr; + int result, didalloc; + + /* open the file, read and check the header */ + if ((fp = fopen(filename, "rb")) == NULL) + return AMX_ERR_NOTFOUND; + fread(&hdr, sizeof hdr, 1, fp); + amx_Align16(&hdr.magic); + amx_Align32((uint32_t *)&hdr.size); + amx_Align32((uint32_t *)&hdr.stp); + if (hdr.magic != AMX_MAGIC) { + fclose(fp); + return AMX_ERR_FORMAT; + } /* if */ + + /* allocate the memblock if it is NULL */ + didalloc = 0; + if (memblock == NULL) { + if ((memblock = malloc(hdr.stp)) == NULL) { + fclose(fp); + return AMX_ERR_MEMORY; + } /* if */ + didalloc = 1; + /* after amx_Init(), amx->base points to the memory block */ + } /* if */ + + /* read in the file */ + rewind(fp); + fread(memblock, 1, (size_t)hdr.size, fp); + fclose(fp); + + /* initialize the abstract machine */ + memset(amx, 0, sizeof *amx); + result = amx_Init(amx, memblock); + + /* free the memory block on error, if it was allocated here */ + if (result != AMX_ERR_NONE && didalloc) { + free(memblock); + amx->base = NULL; /* avoid a double free */ + } /* if */ + + return result; +} + +int AMXAPI aux_FreeProgram(AMX *amx) +{ + if (amx->base!=NULL) { + amx_Cleanup(amx); + free(amx->base); + memset(amx, 0, sizeof(AMX)); + } /* if */ + return AMX_ERR_NONE; +} + +char * AMXAPI aux_StrError(int errnum) +{ +static char *messages[] = { + /* AMX_ERR_NONE */ "(none)", + /* AMX_ERR_EXIT */ "Forced exit", + /* AMX_ERR_ASSERT */ "Assertion failed", + /* AMX_ERR_STACKERR */ "Stack/heap collision (insufficient stack size)", + /* AMX_ERR_BOUNDS */ "Array index out of bounds", + /* AMX_ERR_MEMACCESS */ "Invalid memory access", + /* AMX_ERR_INVINSTR */ "Invalid instruction", + /* AMX_ERR_STACKLOW */ "Stack underflow", + /* AMX_ERR_HEAPLOW */ "Heap underflow", + /* AMX_ERR_CALLBACK */ "No (valid) native function callback", + /* AMX_ERR_NATIVE */ "Native function failed", + /* AMX_ERR_DIVIDE */ "Divide by zero", + /* AMX_ERR_SLEEP */ "(sleep mode)", + /* AMX_ERR_INVSTATE */ "Invalid state", + /* 14 */ "(reserved)", + /* 15 */ "(reserved)", + /* AMX_ERR_MEMORY */ "Out of memory", + /* AMX_ERR_FORMAT */ "Invalid/unsupported P-code file format", + /* AMX_ERR_VERSION */ "File is for a newer version of the AMX", + /* AMX_ERR_NOTFOUND */ "File or function is not found", + /* AMX_ERR_INDEX */ "Invalid index parameter (bad entry point)", + /* AMX_ERR_DEBUG */ "Debugger cannot run", + /* AMX_ERR_INIT */ "AMX not initialized (or doubly initialized)", + /* AMX_ERR_USERDATA */ "Unable to set user data field (table full)", + /* AMX_ERR_INIT_JIT */ "Cannot initialize the JIT", + /* AMX_ERR_PARAMS */ "Parameter error", + /* AMX_ERR_DOMAIN */ "Domain error, expression result does not fit in range", + /* AMX_ERR_GENERAL */ "General error (unknown or unspecific error)", + /* AMX_ERR_OVERLAY */ "Overlays are unsupported (JIT) or uninitialized", + }; + if (errnum < 0 || errnum >= sizeof messages / sizeof messages[0]) + return "(unknown)"; + return messages[errnum]; +} + +int AMXAPI aux_GetSection(const AMX *amx, int section, cell **start, size_t *size) +{ + AMX_HEADER *hdr; + + if (amx == NULL || start == NULL || size == NULL) + return AMX_ERR_PARAMS; + + hdr = (AMX_HEADER*)amx->base; + switch(section) { + case CODE_SECTION: + *start = (cell *)(amx->base + hdr->cod); + *size = hdr->dat - hdr->cod; + break; + case DATA_SECTION: + *start = (cell *)(amx->data); + *size = hdr->hea - hdr->dat; + break; + case HEAP_SECTION: + *start = (cell *)(amx->data + hdr->hea); + *size = amx->hea - hdr->hea; + break; + case STACK_SECTION: + *start = (cell *)(amx->data + amx->stk); + *size = amx->stp - amx->stk; + break; + default: + return AMX_ERR_PARAMS; + } /* switch */ + return AMX_ERR_NONE; +}