This week I have been working on my tiny, Forth-like language SIMPL. in a few hours of spare time I have managed to optimise some of the routines and get the code size down from around 900 bytes to just 780.
The main way that I achieved this was by reducing the size of the jump table from 196 bytes to 120 bytes, and using less code intensive ways to achieve the same functionality.
By paring away at the kernel in this way, makes for more room to add additional functionality – and still stay within the target of just 1024 bytes.
SIMPL provides an extensible language framework allowing:
text entry – either from terminal or by file transfer
32 basic instructions (primitives)
26 lower level functions – I/O related
arithmetical and logical operations
Millisecond and microsecond timing operations
memory examination and modification
The kernel of SIMPL is extensible but in it minimum operational state fits into roughly 800 bytes and has the following main routines
set_up – sets up the clock, the UART and the GPIO
textRead – Read a waiting character from the uart and store it into a buffer area in RAM. The location of where it is stored is determined whether we are in immediate mode or compile mode. Immediate mode saves the character string into a text buffer at 0x0200. Compile mode saves into a buffer starting at 0x0220 for “A” 0x0240 for “B” and so on. textRead finishes when it encounters a newline or carriage return character. It puts ascii 0x80 on the end of the buffer to signify the end of the input and sets the instruction pointer to point at the start of the text buffer (0x0200). It then jumps to “next”
next – this is the key routine – central to the whole operation of SIMPL. It implements a very basic virtual machine that can work its way through an array of characters in memory, making decisions on their type and executing action routines based on the numeric ascii value of the character. It gets the next character from the buffer and test to see whether it is a numeric character, an uppercase character or something else.
number – determine whether the character is part of a string of numerical characters and form into a 16-bit integer to be placed on the stack. Jumps back to “next” on completion
alpha – determine if a character is an upper case letter, calculate the code address associated with it and modify the instruction pointer to point to that address. Jumps back to “next”
jumper – This looks up a jump address from a jump table based on the ascii value of the character. 60 table entries are stored – allowing for all the punctuation, arithmetic and logical symbols and the lower case letters. Each of the 60 characters has an action routine associated with it which is executed when the character is detected in RAM. All of the action routines jump back to “next” on completion
printnum – take a 16-bit integer and convert it into an ascii text string for display
The above routines of the kernel can be coded into about 782 bytes on the MSP430 – allowing the additional routines to fit into about 240 bytes. These will allow access to the peripherals including ADC, GPIO, Timers, SPI etc.