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/

Dependents:   Pawn4Test

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)
Revision:
0:3ab1d2d14eb3
--- /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;
+}