PIC18F Assembler

The PIC18F 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.

  MOVFF $000 ,POSTDEC0 becomes

  MOVFF FTOSL , DP-

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<, OVF before their use. They 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 PIC18F register use is described in the TLM-Forth section. Here is a résumé of that usage:

FSR0 - Data Stack Pointer

$000, $001 (FTOSL, FTOSH) - Top of the Data Stack

$004, $005 (RPL, RPH) - Forth Return Stack Pointer

STKPTR - PIC Return Stack Pointer

FSR1 - UP, Task Area

$00D, $010 - N, ScratchFile

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

  MOVFF FTOSH DP-

  MOVFF FTOSL 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;

  MOVFF FTOSH DP-

  MOVFF FTOSL DP-

POPT gets the data stack into TOS whith the following;

  MOVFF +DP FTOSL

  MOVFF +DP FTOSH

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 PIC18F 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 Microchip 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.

  BSF STATUS CY ,A

Will set the carry flag.

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

  $51 I/O PORTA 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

Modes

Immediate

The operand value used by the instruction is the value supplied by the operand field itself.

 Examples:

ADDLW 04

Adds 4 to the value originally contained in WREG.

MOVFF TOSL DP-

Pushes the Forth Top Stack lower to the data stack.

Register Direct

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

Example:

RLCF FTOSH ,A

Rotates the contents of $001 left one bit.

Data Indirect

In this mode the address of the data does not appear in the instruction, but is located in the 12 bit indirect registers, FSR0,1 or 2.

 Example:

MOVFF (DP) TOSL ,A

This moves the data pointed to by FSR0 to the TOSL.

Data Indirect with Displacement

The indirect working register acts as a base or starting value to which is added an offset held in WREG, to point to the data.  Example:

MOVLW 2

MOVFF TOSH UP+W ,A

Moves the value in TOSH to the LSB of DP0 in the user area.

Data Indirect Post-Increment

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

Example:

MOVWF DP+ ,A

Data Direct

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

Example:

MOVFF TOSL , COUNTER ,A

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

Direct Program

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

Example:

 GOTO ' 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.

Relative Program Addressing

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

Example:

BRA ' 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 .

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 PIC18F 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[ MOVFF SECL , TOSL ]C ;

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 PIC18F are done via vectors at $0008 and $0018 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.

During development an interrupt would be coded as;

The SET-INT is run during the initialisation to set the RAM vector, in this case for the priority vector at $0008. The interrupt may then be tested and when operational a jump to the interrupt <name> may be placed at location $0008 e.g.

HERE $0008 ORG

CODE INT-START GOTO ' <name> C;

ORG

Dumps

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

DUMP is for the code memory e.g.

$0000 50 DUMP

Data Memory Dump

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

Contents