.equ StackStart, 0xff00
-.equ RAMCodeStart, 0x4000
; msp430-gcc uses r[0,1,2] not pc,sp,sr
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
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;
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
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;
+/*
+ * 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){
/*
*
* word "exit" makes processLoop() return
*/
+ config_default_msp4th();
+
while (1) {
init_msp4th();
processLoop();
* - 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
#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
*
***************************************************************************/
-// 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
* sizes can be (re-)specified by changing the table and calling init_msp4th()
* again.
*/
+
+
+
#if defined(MSP430)
int16_t register *mathStackPtr asm("r6");
#else
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];
i = *mathStackPtr;
// prevent stack under-flow
- if (mathStackPtr < &mathStack[MATH_STACK_SIZE - 1]) {
+ if (mathStackPtr < (int16_t *)mathStackStartAddress) {
mathStackPtr++;
}
cmdList[cmdListIdx++] = ' ';
cmdList[cmdListIdx] = 0;
i = lookupToken(wordBuffer,cmdList);
- progOps[i] = progIdx;
+ progOpcodes[i] = progIdx;
}
} else {
pushAddrStack(progCounter);
- progCounter = progOps[opcode];
+ progCounter = progOpcodes[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 )
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++) {
execN(opcode - 20000);
} else {
pushAddrStack(progCounter);
- progCounter = progOps[opcode];
+ progCounter = progOpcodes[opcode];
}
} // while ()
}
#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);
#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();