asm68k is a full-featured symbolic assembler for the Motorola 68000
processor, ported to run in Quartus Forth. With it you can write assembler code
directly for the CPU in the PalmPilot, either as wholly-assembler code words,
or as inline assembler sequences embedded within Forth words. Features of asm68k
include:
IF
...THEN
...ELSE
BEGIN
...AGAIN
BEGIN
...UNTIL
BEGIN
...WHILE
...REPEAT
FOR
...NEXT
As at version 1.21, the source for the assembler is in two files, asm68k and asm68k.part2, together totalling 7191 bytes. When compiled it occupies approximately 7516 bytes of code space, and 292 bytes of data space.
To use it, download
both of the files and import each of them to your pilot as memos using the Pilot
Desktop software. From the Quartus Forth command line, type: include
asm68k
<enter>
You will see: Loading asm68k v1.21...done.
Check the File Area for sample assembler code to get you started.
The original author of asm68k was Michael Perry of F83 fame (an early and very popular implementation of the Forth-83 standard, together with Henry Laxen). The listing appeared in a special edition of Dr. Dobb's Journal, the Toolbook of Forth. His source (F83 compatible, in block format) can be found at ftp://ftp.taygeta.com/pub/Forth/Compilers/cross/68000/68kasm.arc.
68000 mnemonics are implemented in asm68k as Forth words that process
operand information from the data stack and compile machine instructions into
code space. In prefix
mode, the remainder of the current line is
evaluated before operand information is processed.
The mnemonics are normal non-immediate words, which means that in order to assemble instructions, they must execute either in interpretation state, or from within another immediate word. Here's an example:
code under+ ( a b c -- a+c b ) tos 2 sp d) add ] drop [ end-code
Note that because drop
is a Forth word, we must switch into compilation
state with ]
before it and back into interpretation state with [
after. Here's a differently-coded but otherwise identical implementation of
under+
:
: under+ ( a b c -- a+c b ) [ also assembler tos 2 sp d) add previous ] drop ;
Here we switch into interpretation state with [
to assemble the
add
instruction, and then back into compilation state with ]
to compile drop
.
Another word:
code 2- ( n -- n-2 ) 2 tos subq end-code inline
When mixing Forth and assembler within a definition, bear in mind that the
following words have a different meaning when found in the ASSEMBLER
wordlist:
# 0< 0= < > A0 AGAIN AND BEGIN D0 ELSE FOR IF MOVE NEXT OR
REPEAT SWAP THEN UNTIL WHILE
Addressing Mode |
Generation | asm68k Syntax | asm68k Example (Postfix) |
Register Direct Addressing |
|||
Data register direct | ea = Dn | Dn |
d0 d1 move |
Address register direct | ea = An | An |
a3 a0 move |
Absolute Data Addressing |
|||
Absolute short | ea = (next word) | n #) |
3700 #) d0 move |
Absolute long | ea = (next two words) | n L#) |
123456. l#) jmp |
Program Counter Relative Addressing |
|||
Relative with offset | ea = PC + d16 | n PCD) |
d0 56 pcd) .b move |
Relative with index and offset | ea = PC + Xn + d8 | n Xn PCDI) |
100 d1 pcdi) a0 lea |
Register Indirect Addressing |
|||
Register indirect | ea = (An) | An ) |
d0 a0 ) .b move |
Postincrement register indirect | ea = (An), An := An + N | An )+ |
a7 +) d7 .w move |
Predecrement register indirect | An := An N, ea = (An) | An -) |
d0 a6 -) .w move |
Register indirect with offset | ea = (An) + d16 | n An D) |
15 a1 d) .b clr |
Indexed register indirect with offset | ea = (An) + (Xn) + d8 | n Xn An DI) |
16 d0 a0 di) .l neg |
Immediate Data Addressing |
|||
Immediate | data = next word(s) | n # |
42 # d0 move |
Quick immediate | Inherent data | n |
7 d1 addq |
Assembler Directive | Action | Example |
.W |
Cause subsequent generation of word-sized operations (2-byte) | d0 d1 .w move |
.L |
Cause subsequent generation of long-sized operations (4-byte) | 24 # d5 .l add |
.B |
Cause subsequent generation of byte-sized operations (1-byte) | 3 a1 d) .b clr |
ASSEMBLER |
Replace the first wordlist in the search-order with the ASSEMBLER wordlist. | |
FORTH |
Replace the first wordlist in the search-order with the FORTH wordlist. | |
CODE <name> ... END-CODE |
Creates <name>, saves the current search-order, performs
.W ALSO ASSEMBLER and assembles code until END-CODE ,
which restores the former search-order. <name> becomes
a findable Forth word that can be flagged IMMEDIATE or INLINE . |
code under+ tos 2 sp d) add ] drop [ end-code |
POSTFIX |
Switch the assembler to postfix mode (the default), where operands preceed instructions. | |
PREFIX |
Switch the assembler to prefix mode, where operands follow instructions. Note that in this mode, each mnemonic/operand sequence must be on its own line. |
code rot- prefix move tos d0 move sp ) tos move 2 sp d) sp ) move d0 2 sp d) postfix end-code |
Structured Conditionals (8-bit displacement) |
||
---|---|---|
0= 0<> 0< 0>= < >= <= > |
Branch conditions; use where <condition> appears below. Note: these test the flags in the 68000 status register, and do not consume cells from the stack as do their Forth counterparts. | |
<condition> IF ... ELSE ... THEN |
Conditional branching, as in Forth. |
0< if d0 neg else 1 d0 subq then |
BEGIN ... AGAIN |
A simple loop. As in Forth. | |
BEGIN ... <condition> UNTIL |
As in Forth. | |
BEGIN ... <condition> WHILE ...
REPEAT |
As in Forth. | |
D n FOR ... NEXT |
Loops backwards from Dn-1 to 0. |
Addressing Modes | Instructions |
( ) | RESET NOP RTE RTS |
( n ) | ANDI>SR EORI>SR ORI>SR STOP TRAP |
( n ea ) | ORI ANDI SUBI ADDI EORI CMPI ADDQ SUBQ MOVEM> MOVEM< |
( n An ) | LINK |
( n Dn ) | MOVEQ |
( ea ) | SET SNI SLS SCC SCS SNE SEQ SVC SVS SPL SMI SSE SLT SGT SLE JSR
JMP MOVE>CCR MOVE<SCR MOVE>SCR NBCD PEA TAS CLR NOT NEG NEGX TST |
( ea ea ) | MOVE |
( ea An ) | ADDA CMPA LEA SUBA |
( ea Dn ) | CMP CHK DIVU DIVS MULU MULS |
( ea Dn ) ( Dn ea ) | ADD AND OR SUB |
( ea Dn ) ( ea n # ) | BCHG BCLR BSET BTST |
( An ) | MOVE<USP MOVE>USP UNLK |
( Dn ) | EXT SWAP |
( Dn ea ) | EOR |
( Dm Dn ) ( m # Dn ) ( ea ) | ASL ASR LSL LSR ROL ROR ROXL ROXR |
( Da d An ) ( d An Da ) | MOVEP |
( Dn Dm ) ( An@- Am@ ) | ABCD SBCD ADDX SUBX |
( An@+ Am@+ ) | CMPM |
( Xn Xa ) | EXG |
( target ) | BRA BSR BHI BLS BCC BCS BNE BEQ BVC BVS BPL BMI BGE BLT BGT BLE |
( target Dn ) | DBRA DBHI DBLS DBCC DBCS DBNE DBEQ DBVC DBVS DBPL DBMI DBGE DBLT
DBGT DBLE |
Register | Symbolic name | Purpose within Quartus Forth |
A2 | CS | Codespace segment pointer |
A4 | SP | Data stack pointer |
A5 | DS | Dataspace segment pointer |
A7 | RP | Return stack pointer |
D7 | TOS | Top element of the data stack |
1998.7.20 | Fixed a bug relating to MULU .Released version 1.21. |
1998.7.5 | Fixed a bug in the original source affecting imm words. Fixed a bug affecting isr words. Released version 1.2. |
1998.7.5 | Removed LABEL , due to a conflict with the semantics of CODE
in my port.Released version 1.1. |