msp4th: vector table to specify user-custom arrays
authorDan White <dan@whiteaudio.com>
Mon, 6 May 2013 19:20:33 +0000 (14:20 -0500)
committerDan White <dan@whiteaudio.com>
Tue, 7 May 2013 03:19:05 +0000 (22:19 -0500)
NOTE: the test430.c PC program does not work, but a cursory usage on the actual
NS430 seems to work fine.

msp4th/flashboot.s
msp4th/ldscript_ns430
msp4th/ldscript_ns430_bootrom
msp4th/main.c
msp4th/msp4th.c
msp4th/msp4th.h
msp4th/test4th.c

index b673c16194411d3cf60c7f96e57b9effa0d5fc99..7270dc1f4316d5026da94fe17a98aea37d8ca73d 100644 (file)
@@ -2,7 +2,6 @@
 
 
 .equ StackStart, 0xff00
-.equ RAMCodeStart, 0x4000
 
 ; msp430-gcc uses r[0,1,2] not pc,sp,sr
 
index 26212a1915f14b22f83c62c52c264374cf4d347a..a95097251b9339174841d5c89428c50dd93d9a7e 100644 (file)
@@ -6,8 +6,8 @@ MEMORY {
   peripheral_8bit  : ORIGIN = 0x0010, LENGTH = 0x00f0
   peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100
 
-  ram (wx)         : ORIGIN = 0x4000, LENGTH = 0x3fe0
-  /*rom (rx)         : ORIGIN = 0xf800, LENGTH = 2048-32*/
+  ram (wx)         : ORIGIN = 0x4000, LENGTH = 0xbf00
+  /*rom (rx)         : ORIGIN = 0x3000, LENGTH = 0x1000 */
 
   vectors          : ORIGIN = 0xffc0, LENGTH = 64
 
@@ -218,6 +218,13 @@ SECTIONS
    PROVIDE (__data_start_rom = _etext);
    PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));
 }
+/* hard-coded addresses for on-line re-sizing of the msp4th arrays */
+__mathStackStartAddress     = 0xff00;
+__addrStackStartAddress     = 0xff02;
+__progStartAddress          = 0xff04;
+__progOpcodesStartAddress   = 0xff06;
+__cmdListStartAddress       = 0xff08;
+
 __PC_AFTER_RESET = 0x3000;
 __CRCDI = 0x0000;
 __CRCDI_L = 0x0000;
index c52562dbbf144382661c164dd707d71f1a53cd18..d40a2a5c2ca79d67d7d8e2564c07ebcbf1b5b2c7 100644 (file)
@@ -6,7 +6,7 @@ MEMORY {
   peripheral_8bit  : ORIGIN = 0x0010, LENGTH = 0x00f0
   peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100
 
-  ram (wx)         : ORIGIN = 0x4000, LENGTH = 0xbfe0
+  ram (wx)         : ORIGIN = 0x4000, LENGTH = 0xbf00
   rom (rx)         : ORIGIN = 0x3000, LENGTH = 0x1000
 
   vectors          : ORIGIN = 0xffc0, LENGTH = 64
@@ -218,6 +218,13 @@ SECTIONS
    PROVIDE (__data_start_rom = _etext);
    PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));
 }
+/* hard-coded addresses for on-line re-sizing of the msp4th arrays */
+__mathStackStartAddress     = 0xff00;
+__addrStackStartAddress     = 0xff02;
+__progStartAddress          = 0xff04;
+__progOpcodesStartAddress   = 0xff06;
+__cmdListStartAddress       = 0xff08;
+
 __PC_AFTER_RESET = 0x3000;
 __CRCDI = 0x0000;
 __CRCDI_L = 0x0000;
index 6a2175bb7dc8d669c0e0ce81a987ffae08d807ee..4177b3031c81180b13ec2a3ddc6ec4d9caf7b321 100644 (file)
@@ -73,6 +73,53 @@ void init_uart(void)
 
 
 
+/*
+ * Default msp4th settings
+ */
+#define MATH_STACK_SIZE 32
+#define ADDR_STACK_SIZE 64
+
+//total length of all user programs in opcodes
+#define USER_PROG_SIZE 256
+
+//max number of user-defined words
+#define USER_OPCODE_MAPPING_SIZE 32
+
+//total string length of all word names (+ 1x<space> each)
+#define USER_CMD_LIST_SIZE 128
+
+/*
+ * The ".lastram" section should be placed so these vectors are the last part
+ * of allocated RAM.  All space beyond, up until 0xff00, is empty or unused.
+ */
+int16_t __attribute__ ((section(".noinit"))) mathStackArray[MATH_STACK_SIZE];
+int16_t __attribute__ ((section(".noinit"))) addrStackArray[ADDR_STACK_SIZE];
+int16_t __attribute__ ((section(".noinit"))) progArray[USER_PROG_SIZE];
+int16_t __attribute__ ((section(".noinit"))) progOpcodesArray[USER_OPCODE_MAPPING_SIZE];
+uint8_t __attribute__ ((section(".noinit"))) cmdListArray[USER_CMD_LIST_SIZE];
+
+
+void config_default_msp4th(void)
+{
+    int16_t i;
+
+    mathStackStartAddress = (uint16_t)&mathStackArray[MATH_STACK_SIZE - 1];
+    addrStackStartAddress = (uint16_t)&addrStackArray[ADDR_STACK_SIZE - 1];
+    progStartAddress = (uint16_t)&progArray[0];
+    progOpcodesStartAddress = (uint16_t)&progOpcodesArray[0];
+    cmdListStartAddress = (uint16_t)&cmdListArray[0];
+
+
+    for (i=0; i < MATH_STACK_SIZE; i++) {
+        mathStackArray[i] = 0;
+    }
+
+    for (i=0; i < ADDR_STACK_SIZE; i++) {
+        addrStackArray[i] = 0;
+    }
+}
+
+
 
 int main(void){
     /*
@@ -109,6 +156,8 @@ int main(void){
      *
      * word "exit" makes processLoop() return
      */
+    config_default_msp4th();
+
     while (1) {
         init_msp4th();
         processLoop();
index 80453286b69e8b570a3af275fb29788910593cb5..596d3e100b8ca6ad2d94584b1b813d6d7e6c7ec6 100644 (file)
@@ -5,7 +5,8 @@
  *  - speed up pop/pushMathStack (need bounds check??)
  *  - UART usage is blocking, convert to interrupt-based
  *  - allow configurable user-code space
- *      prog[], cmdList[], progOps[]
+ *      mathStack[], addrStack[]
+ *      prog[], cmdList[], progOpcodes[]
  *      array locations come from a vector table instead of hard-coded
  *      locations in bss space.  init_msp4th() populates the pointers
  *      with values from the table (which can be user-written to effect
@@ -36,18 +37,13 @@ void uart_puts(uint8_t *s) { puts((char *)s); }
 #define ALIGN_2 __attribute__ ((aligned (2)))
 
 /* 
- * Configuration constants
+ * Hard-coded constants
+ *
+ * buffer lengths don't need to be configurable, right?
  */
-#define MATH_STACK_SIZE 32
-#define ADDR_STACK_SIZE 64
-#define CMD_LIST_SIZE 128
-#define PROG_SPACE 256
-#define USR_OPCODE_SIZE 32
-
 #define LINE_SIZE 128
 #define WORD_SIZE 32
 
-#define BI_PROG_SHIFT 10000
 
 /*
  * Local function prototypes
@@ -81,9 +77,8 @@ void execFunc(void);
  *
  ***************************************************************************/
 
-// must end in a space !!!!
-// The order is important .... don't insert anything!
-// the order matches the execN function
+// The order matches the execN function and determines the opcode value.
+// NOTE: must end in a space !!!!
 const uint8_t cmdListBi[] = 
              {"exit + - * / "                       // 1 -> 5
               ". dup drop swap < "                  // 6 -> 10
@@ -330,6 +325,9 @@ uint8_t wordBuffer[WORD_SIZE];      // just get a word
  * sizes can be (re-)specified by changing the table and calling init_msp4th()
  * again.
  */
+
+
+
 #if defined(MSP430)
 int16_t register *mathStackPtr asm("r6");
 #else
@@ -342,16 +340,18 @@ int16_t register *addrStackPtr asm("r7");
 int16_t *addrStackPtr;
 #endif
 
-uint16_t progIdx;           // next open space for user opcodes
-uint16_t cmdListIdx;
+int16_t *prog;          // user programs (opcodes) are placed here
+uint16_t progIdx;       // next open space for user opcodes
+
+int16_t *progOpcodes;   // mapping between user word index and program opcodes
+                        // start index into prog[]
+
+uint8_t *cmdList;       // string of user defined word names
+uint16_t cmdListIdx;    // next open space for user word strings
+
 
 // TODO re-defined
-int16_t mathStack[MATH_STACK_SIZE];
-int16_t addrStack[ADDR_STACK_SIZE];
 
-uint8_t cmdList[CMD_LIST_SIZE];  // just a string of user defined names
-int16_t prog[PROG_SPACE];  // user programs are placed here
-int16_t progOps[USR_OPCODE_SIZE];
 
 
 
@@ -510,7 +510,7 @@ int16_t popMathStack(void)
     i = *mathStackPtr;
 
     // prevent stack under-flow
-    if (mathStackPtr < &mathStack[MATH_STACK_SIZE - 1]) {
+    if (mathStackPtr < (int16_t *)mathStackStartAddress) {
         mathStackPtr++;
     }
 
@@ -743,7 +743,7 @@ void dfnFunc(){
   cmdList[cmdListIdx++] = ' ';
   cmdList[cmdListIdx] = 0;
   i = lookupToken(wordBuffer,cmdList);
-  progOps[i] = progIdx;
+  progOpcodes[i] = progIdx;
 }
 
 
@@ -817,7 +817,7 @@ void execFunc(){
   } else {
 
     pushAddrStack(progCounter);
-    progCounter = progOps[opcode];
+    progCounter = progOpcodes[opcode];
 
   }
 
@@ -933,9 +933,6 @@ void execN(int16_t opcode){
 
     case 17: // allot  ( opcode -- ) \ push opcode to prog space
       prog[progIdx++] = popMathStack();
-      if(progIdx >= PROG_SPACE){
-        uart_puts((str_t *)"ERR: prog full");
-      }
       break;
 
     case 18: // p@  ( opaddr -- opcode )
@@ -1204,23 +1201,29 @@ void init_msp4th(void)
 
     xit = 0;
 
-    mathStackPtr = &mathStack[MATH_STACK_SIZE - 1];
-    addrStackPtr = &addrStack[ADDR_STACK_SIZE - 1];
+    /*
+     * Get addresses of user-configurable arrays from the pre-known vector
+     * table locations.
+     *
+     * Changing the values in the xStartAddress locations and calling
+     * init_msp4th() again restarts the interpreter with the new layout;
+     */
+    mathStackPtr = (int16_t *)mathStackStartAddress;
+    addrStackPtr = (int16_t *)addrStackStartAddress;
+    prog = (int16_t *)progStartAddress;
+    progOpcodes = (int16_t *)progOpcodesStartAddress;
+    cmdList = (uint8_t *)cmdListStartAddress;
+
+
+
     progCounter = 10000;
     progIdx = 1;                       // this will be the first opcode
-    i=0;
+
+
     cmdListIdx = 0;
-    cmdList[0] = 0;
 
     dirMemory = (void *) 0;   // its an array starting at zero
 
-    for (i=0; i < MATH_STACK_SIZE; i++) {
-        mathStack[i] = 0;
-    }
-
-    for (i=0; i < ADDR_STACK_SIZE; i++) {
-        addrStack[i] = 0;
-    }
 
     lineBufferIdx = 0;
     for (i=0; i < LINE_SIZE; i++) {
@@ -1255,7 +1258,7 @@ void processLoop() // this processes the forth opcodes.
             execN(opcode - 20000);
         } else {
             pushAddrStack(progCounter);
-            progCounter = progOps[opcode];
+            progCounter = progOpcodes[opcode];
         }
     } // while ()
 }
index 8f8a16f2283854f33fbaa44323f5fd15a75bf492..92505677dd18839b365cbeff7df72cde91afbd7b 100644 (file)
@@ -1,6 +1,20 @@
 #if !defined(__MSP4TH)
 #define __MSP4TH
 
+#if defined(MSP430)
+extern volatile uint16_t mathStackStartAddress asm("__mathStackStartAddress");
+extern volatile uint16_t addrStackStartAddress asm("__addrStackStartAddress");
+extern volatile uint16_t progStartAddress asm("__progStartAddress");
+extern volatile uint16_t progOpcodesStartAddress asm("__progOpcodesStartAddress");
+extern volatile uint16_t cmdListStartAddress asm("__cmdListStartAddress");
+#else
+extern volatile uint16_t mathStackStartAddress;
+extern volatile uint16_t addrStackStartAddress;
+extern volatile uint16_t progStartAddress;
+extern volatile uint16_t progOpcodesStartAddress;
+extern volatile uint16_t cmdListStartAddress;
+#endif
+
 void init_msp4th(void);
 void processLoop(void);
 
index 18b96b71bb9dc406da7586d8a04540ae4955363c..0432846bf42dce73ee941ce08b296f641f1f11c8 100644 (file)
@@ -4,8 +4,50 @@
 #include "msp4th.h"
 
 
+#define MATH_STACK_SIZE 32
+#define ADDR_STACK_SIZE 64
+#define CMD_LIST_SIZE 128
+#define PROG_SPACE 256
+#define USR_OPCODE_SIZE 32
+
+int16_t mathStackArray[MATH_STACK_SIZE];
+int16_t addrStackArray[ADDR_STACK_SIZE];
+int16_t progArray[USR_OPCODE_SIZE];
+int16_t progOpcodesArray[USR_OPCODE_SIZE];
+uint8_t cmdListArray[CMD_LIST_SIZE];
+
+volatile uint16_t mathStackStartAddress;
+volatile uint16_t addrStackStartAddress;
+volatile uint16_t progStartAddress;
+volatile uint16_t progOpcodesStartAddress;
+volatile uint16_t cmdListStartAddress;
+
+
+void config_msp4th(void)
+{
+    int16_t i;
+
+    mathStackStartAddress = (uint16_t)&mathStackArray[MATH_STACK_SIZE - 1];
+    addrStackStartAddress = (uint16_t)&addrStackArray[ADDR_STACK_SIZE - 1];
+    progStartAddress = (uint16_t)&progArray[0];
+    progOpcodesStartAddress = (uint16_t)&progOpcodesArray[0];
+    cmdListStartAddress = (uint16_t)&cmdListArray[0];
+
+    for (i=0; i < MATH_STACK_SIZE; i++) {
+        mathStackArray[i] = 0;
+    }
+
+    for (i=0; i < ADDR_STACK_SIZE; i++) {
+        addrStackArray[i] = 0;
+    }
+}
+
+
+
 int main(void)
 {
+    config_msp4th();
+
     init_msp4th();
     processLoop();