MSP430 Assembler

The MSP430 assembler in the IRTC will allow you to do most that a conventional assembler will, and something's that it may not. It is a single pass interpreted assembler with conditional statements, such as

IF...ELSE...THEN

BEGIN...UNTIL

BEGIN...WHILE...REPEAT

BEGIN...AGAIN etc.

The syntax of the assembler is not that of Forth, Reverse Polish or Postfix notation but standard Prefix. This means that the source looks like standard assembly but with space delimiters. e.g.

  MOV #0123h,R7 becomes

  MOV # $0123 , R7

As all assemblers this checks the validity of the addressing mode for the instruction, and the size of the data. This is accomplished by flags that are set to indicate the various addressing modes.

Note: The only forward referencing available in the assembler is with the structures above.

Conditional Flags

The conditionals require a flag test, CS, 0=, 0<, 0>, >=, before their use. Each may be followed by a NOT to produce the inverse of the test. e.g.

  0= IF - branch if non zero.

  0= NOT IF - branch if zero.

Register Use

The MSP430 register use is described in the TLM-Forth section. Here is a résumé of that usage:

R5 - Data Stack Pointer

R7 - Top of the Data Stack

SP - Return Stack Pointer

R4 - UP, Task Area

R8 - N, ScratchFile Use

Macros

Because of the way Forth and the Assembler work it is possible to define Macros for use in the assembly process. If we make a Host definition which contains assembler words, when interpreted at compile time, the definition will execute these words. This will place the assembler code directly into the Target. An example of this technique is:

XASM DEFINITIONS

MACRO: PUSHT ADD # 2 , DP

  MOV TOS , 0 (DP)

MACRO;

IN-META

 Using this technique it is possible to construct repetitive code for insertion in your machine code programs

Note: You may also produce the same result with an H: definition and M[ .. ]M e.g.

PUSH and POP

Two other macros are pre-compiled to assist with stack control.

PUSHT places the TOS contents onto the data stack with the following code;

ADD # 2 , DP

MOV TOS , 0 (DP)

POPT gets the data stack into TOS whith the following;

  MOV @DP , TOS

If you wish to manipulate the stack you should do so with these macros. If you write in-line code and use these macros the optimiser will try to elliminate unnecessary stack use.

Addressing

The MSP430 has many and varied addressing modes. By no means all are used in the TLM, but many are. To understand their use it is strongly recommended that you read the TI data book for a full explanation. Here we will consider the addressing mnemonic used in the IRTC assembler.

Register Syntax

The same syntax that appears in the TI data book has been used for register identification. A upper case 'R' for a register, 0-15. For convenience and improved readability the registers, are pre-defined, R4, PC and SR etc.

The pre-defined versions are much more readable. Also all the I/O registers and the flags within them are predefined by name e.g.

  BIS # CAP , & CCTL0

Will enable the capture on TimerA

Note: When using the I/O Registers in a high level definition they must be preceeded by I/O. e.g.

  $51 I/O P1OUT C!

Note: When using the Register flags in a high level definition they must be preceeded by FLAG to generate a mask e.g.

  FLAG CAP I/0 CCTL0 ON

To differentiate between destination and source operands a space delimited comma is used e.g.

 ADD # 2 , TOS

BEWARE: of the use of a Forth , while in the assembler as very odd results will occur.

Modes

Immediate

The operand value used by the instruction is the value supplied by the operand field itself. The hashmark (#), optional, is used to distinguish data from an absolute address.

 Examples:

ADD # 04 , R6

Adds 4 to the value originally contained in register R6.

ADD UP , TOS

Adds UP TO the top stack item.

Register Direct

In this mode a register is be addressed by using its absolute address in the register file.

Example:

ROL R4

Rotates the contents of register number 4 left one bit.

Data Indirect

In this mode the address of the data does not appear in the instruction, but is located in a register.

 Example:

MOV . B @TOS , TOS

This is equivalent to a C@ in Forth, R7 being the top stack item holds the address of the data byte.

The .B indicates a byte not a word transfer.

Data Indirect with Displacement

The indirect working register acts as a base or starting value to which is added an immediate offset, to point to the data. The offset value is the immediate value given in the instruction while the index value is given by the contents of a register.

 Example:

MOV R10 , 5 (R4)

If R4 contains 55 then the contents of 60 (55+5) will be loaded with the contents of register 10.

Data Indirect Post-Increment

Here the destination or source addresses are given by the contents of a register, which are then post-incremented.

Example:

MOV @R5+ , TOS

In IRTC R5 contains the Data Stack pointer, DP. The above example is equivalent to a DROP.

Data Direct

This mode addresses the specific location within the data memory directly. It only needs the absolute address value.

Example:

MOV R7 , COUNTER

The data memory location COUNTER is loaded with the contents of the register 7.

Direct Program

The program execution continues at the address contained in the instruction.

Example:

 JMP ' # PAUSE

Jumps directly to PAUSE. The ' is used in Forth to find the CFA of the following word. If the word was created by a LABEL the ' is not required.

  CALL ' # STOP

Calls the subroutine STOP.

Indirect Program Addressing

The program execution is continued at the address contained in register.

Examples:

BR N

Jumps to the address in N.

CALL N

Calls the address in N.

Relative Program Addressing

The offset, -2048 to 2047, is held in the instruction causing the execution to continue from the Program Counter plus the signed offset.

Example:

JMP ' TEST

Jumps to TEST relative from the location of the instruction.

Code Definitions

To define a Forth code word the assembler must be invoked to allow the instruction words to be found. Three words will do this; CODE, LABEL and INTERRUPT.

CODE creates a Header for the word following and causes the assembled machine code to be run when the word is executed. This is just like a Forth : definition only in code.

LABEL creates a Header for the following word, that only leaves the address of the assembled machine code on the Host stack when the word is executed. This is often used as a reference for jumps or branches within a CODE definition.

All assembler definitions must end with END-CODE or C;. These words terminate the assembler and test the Host stack for irregularities. CODE definitions will usually end with RET.

In-Line Code

As MSP430 Forth is subroutine threaded and produces machine code, it is possible to put code fragments into a high level definition. The code is encompassed with C[ and ]C, for example;

: TEST C[ ADD # 4 , TOS ]C ;

This adds 4 to the item on top of the stack.

CODE Stubs

If you are only using assembler code you may still use TLM to test your routines.

TLM expects the CFA it receives to be that of a subroutine. If you have used CODE definitions for your routines these may be executed by name from the command line. If they are defined by LABELs then a stub is required e.g.

This assumes <name> is a routine ending in a return opcode and that it does not corrupt the TLM file space or stack.

To test parts of your code it may be necessary to insert return opcodes into the code at strategic points and then create stubs to test that section.

Interrupts

Interrupts in the MSP430 are done via vectors in the last 32 bytes of the program memory space. To enable these vectors to be changed during development the TLM has these locations programmed to jump to locations at the start of the development code RAM. These RAM locations may then be programmed with an absolute jump address to the interrupt routine. This adds about 0.5uSecs to the interrupt latency at 8MHz. The Forth word VECTOR! takes a vector address, and the interrupt code address to automatically create the jump in the RAM location.

The word INTERRUPT may be used to define an interrupt routine instead of CODE or LABEL. The associated interrupt vector address must preceed INTERRUPT and it will create a jump vector to the routine in the code vectors. This will only take effect when the whole image is REPROGRAMed.

Use: $0FFEC INTERRUPT <name> \ TMRA0 vector

During development the above interrupt would be coded as;

The SET-TIMA-INT is run during the initialisation to set the RAM vector. The interrupt may then be tested and when operational the CODE <name> replaced by the $0FFEC INTERRUPT <name>.

Dumps

To assist with code definitions in particular, memory dump utilities DUMP and RDUMP

DUMP is for the code memory e.g.

$0000 50 DUMP

Data Memory Dump

The Data memory may be dumped by BDUMP. This dumps the area defined as byte values rather than words.

Contents