1 ; -*- coding: utf-8 -*-
2 ; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
4 ; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
5 ; Copyright (C) <2017> <J.M. THOORENS>
7 ; This program is free software: you can redistribute it and/or modify
8 ; it under the terms of the GNU General Public License as published by
9 ; the Free Software Foundation, either version 3 of the License, or
10 ; (at your option) any later version.
12 ; This program is distributed in the hope that it will be useful,
13 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ; GNU General Public License for more details.
17 ; You should have received a copy of the GNU General Public License
18 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ; ----------------------------------------------------------------------
22 ;forthMSP430FR_EXTD_ASM.asm
23 ; ----------------------------------------------------------------------
25 ; ----------------------------------------------------------------------
26 ; MOV(.B) #0, dst is coded as follow : MOV(.B) R3, dst ; 1 cycle, one word As=00 register mode
27 ; MOV(.B) #1, dst is coded as follow : MOV(.B) 0(R3), dst ; 2 cycles, one word AS=01 x(reg) mode
28 ; MOV(.B) #2, dst is coded as follow : MOV(.B) @R3, dst ; 2 cycles, one word AS=10 @reg mode
29 ; MOV(.B) #4, dst is coded as follow : MOV(.B) @R2, dst ; 2 cycles, one word AS=10 @reg mode
30 ; MOV(.B) #8, dst is coded as follow : MOV(.B) @R2+, dst ; 2 cycles, one word AS=11 @reg+ mode
31 ; MOV(.B) #-1,dst is coded as follow : MOV(.B) @R3+, dst ; 2 cycles, one word AS=11
32 ; MOV(.B) #xxxx,dst is coded a follow : MOV(.B) @PC+, dst ; 2 cycles, two words AS=11 @reg+ mode
33 ; MOV(.B) &EDE,&TON is coded as follow: MOV(.B) EDE(R2),TON(R2) ; (R2=0), three words AS=01, AD=1 x(reg) mode
34 ; ----------------------------------------------------------------------
36 ; PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
37 ; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
39 ; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
41 ; POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
42 ; POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
44 ; example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
47 ; ----------------------------------------------------------------------
48 ; DTCforthMSP430FR5xxx ASSEMBLER : search argument "xxxx", IP is free
49 ; ----------------------------------------------------------------------
51 ;SearchARG ; separator -- n|d or abort" not found"
52 ;; Search ARG of "#xxxx," ; <== PARAM10
53 ;; Search ARG of "&xxxx," ; <== PARAM111
54 ;; Search ARG of "xxxx(REG)," ; <== PARAM130
55 ;; Search ARG of ",&xxxx" ; <== PARAM111 <== PARAM20
56 ;; Search ARG of ",xxxx(REG)" ; <== PARAM210
57 ; PUSHM #2,S ; PUSHM S,T as OPCODE, OPCODEADR
58 ; ASMtoFORTH ; -- separator search word first
59 ; .word WORDD,FIND ; -- addr
60 ; .word QTBRAN,SearchARGW ; -- addr if word found
62 ; .word QFBRAN,NotFound ; -- addr ABORT if not found
63 ;FSearchEnd .word SearchEnd ; -- value goto SearchEnd if number found
64 ;SearchARGW FORTHtoASM ; -- xt xt = CFA
65 ; MOV @TOS+,X ; -- PFA
66 ;QDODOES SUB #DODOES,X ; DODOES = 1284h
68 ; ADD #2,TOS ; -- BODY leave BODY address for DOES words
70 ;QDOCON CMP #1,X ; -- PFA DOCON = 1285h
72 ; MOV @TOS,TOS ; -- cte replace PFA by [PFA] for CONSTANT and CREATE words
74 ;QDOVAR CMP #2,X ; -- PFA DOVAR = 1286h
75 ; JZ SearchEnd ; if DOVAR nothing to do
76 ; SUB #2,TOS ; -- CFA replace PFA by CFA for all other words
77 ;SearchEnd POPM #2,S ; POPM T,S
80 SearchARG ; separator -- n|d or abort" not found"
81 ; Search ARG of "#xxxx," ; <== PARAM10
82 ; Search ARG of "&xxxx," ; <== PARAM111
83 ; Search ARG of "xxxx(REG)," ; <== PARAM130
84 ; Search ARG of ",&xxxx" ; <== PARAM111 <== PARAM20
85 ; Search ARG of ",xxxx(REG)" ; <== PARAM210
86 PUSHM #2,S ; PUSHM S,T as OPCODE, OPCODEADR
87 ASMtoFORTH ; -- separator search word first
88 .word WORDD,FIND ; -- addr
89 .word QTBRAN,SearchARGW ; -- addr if word found
91 .word QFBRAN,NotFound ; -- addr ABORT if not found
92 FSearchEnd .word SearchEnd ; -- value goto SearchEnd if number found
93 SearchARGW FORTHtoASM ; -- xt xt = CFA
95 QDOVAR SUB #DOVAR,X ; DOVAR = 1286h
97 ADD #1,X ; -- PFA DOCON = 1285h
101 QDODOES ADD #2,TOS ; -- BODY leave BODY address for DOES words
102 ADD #1,X ; DODOES = 1284h
105 SearchEnd POPM #2,S ; POPM T,S
108 ; Arg_Double_to_single conversion needed only for OPCODE type V|VI, 2th pass.
109 ARGD2S BIT #UF9,SR ; -- Lo Hi
111 MOV @PSP+,TOS ; -- Lo skip hi
114 ; ----------------------------------------------------------------------
115 ; DTCforthMSP430FR5xxx ASSEMBLER : search REG
116 ; ----------------------------------------------------------------------
118 ; compute arg of "xxxx(REG)," ; <== PARAM130, sep=','
119 ; compute arg of ",xxxx(REG)" ; <== PARAM210, sep=' '
120 ComputeARGParenREG ; sep -- Rn
121 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
122 CALL #SearchARG ; -- xxxx aborted if not found
123 CALL #ARGD2S ; skip arg_hi if DOUBLE
126 MOV TOS,0(X) ; -- xxxx compile xxxx
127 MOV #')',TOS ; -- ")" prepare separator to search REG of "xxxx(REG)"
129 ; search REG of "xxxx(REG)," separator = ')'
130 ; search REG of ",xxxx(REG)" separator = ')'
131 ; search REG of "@REG," separator = ',' <== PARAM120
132 ; search REG of "@REG+," separator = '+' <== PARAM121
133 ; search REG of "REG," separator = ',' <== PARAM13
134 ; search REG of ",REG" separator = BL <== PARAM21
136 SearchREG PUSHM #2,S ; PUSHM S,T as OPCODE, OPCODEADR
137 PUSH &TOIN ; -- sep save >IN
138 ADD #1,&TOIN ; skip "R"
139 ASMtoFORTH ; search xx of Rxx
140 .word WORDD,QNUMBER ;
141 .word QFBRAN,NOTaREG ; -- xxxx if Not a Number
142 FORTHtoASM ; -- Rn number is found
143 ADD #2,RSP ; remove >IN
145 JHS BOUNDERROR ; abort if Rn out of bounds
146 JLO SearchEnd ; -- Rn Z=0 ==> found
148 NOTaREG FORTHtoASM ; -- addr Z=1
149 MOV @RSP+,&TOIN ; -- addr restore >IN
150 JMP SearchEnd ; -- addr Z=1 ==> not a register
153 ; ----------------------------------------------------------------------
154 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET FIRST OPERAND
155 ; ----------------------------------------------------------------------
157 ; PARAM1 is used for OPCODES type I (double operand) and OPCODES type II (single operand) instructions
158 ; PARAM1 is used for OPCODES type V (double operand) and OPCODES type VI (single operand) extended instructions
160 ; PARAM1 separator -- ; parse input buffer until separator and compute first operand of opcode
161 ; sep is comma for src and space for dst .
162 PARAM1 mDOCOL ; -- sep OPCODES types I|V sep = ',' OPCODES types II|VI sep = ' '
163 .word FBLANK,SKIP ; -- sep addr
164 FORTHtoASM ; -- sep addr
165 MOV #0,S ; -- sep addr reset OPCODE
166 MOV &DDP,T ; -- sep addr HERE --> OPCODEADR (opcode is preset to its address !)
167 ADD #2,&DDP ; -- sep addr cell allot for opcode
168 MOV.B @TOS,W ; -- sep addr W=first char of instruction code
169 MOV @PSP+,TOS ; -- sep W=c-addr
170 CMP.B #'#',W ; -- sep W=first char
172 ; "#" found : case of "#xxxx,"
173 PARAM10 ADD #1,&TOIN ; -- sep skip # prefix
174 CALL #SearchARG ; -- xxxx abort if not found
175 CALL #ARGD2S ; skip arg_hi of OPCODE type V
176 MOV #0300h,S ; OPCODE = 0300h : MOV #0,dst is coded MOV R3,dst
177 CMP #0,TOS ; -- xxxx #0 ?
179 MOV #0310h,S ; OPCODE = 0310h : MOV #1,dst is coded MOV 0(R3),dst
180 CMP #1,TOS ; -- xxxx #1 ?
182 MOV #0320h,S ; OPCODE = 0320h : MOV #2,dst is coded MOV @R3,dst
183 CMP #2,TOS ; -- xxxx #2 ?
185 MOV #0220h,S ; OPCODE = 0220h : MOV #4,dst is coded MOV @R2,dst
186 CMP #4,TOS ; -- xxxx #4 ?
188 MOV #0230h,S ; OPCODE = 0230h : MOV #8,dst is coded MOV @R2+,dst
189 CMP #8,TOS ; -- xxxx #8 ?
191 MOV #0330h,S ; -- -1 OPCODE = 0330h : MOV #-1,dst is coded MOV @R3+,dst
192 CMP #-1,TOS ; -- xxxx #-1 ?
194 MOV #0030h,S ; -- xxxx for all other cases : MOV @PC+,dst
195 ; case of "&xxxx," ; <== PARAM110
196 ; case of ",&xxxx" ; <== PARAM20
197 StoreArg MOV &DDP,X ;
198 ADD #2,&DDP ; cell allot for arg
199 StoreTOS ; <== TYPE1DOES
200 MOV TOS,0(X) ; compile arg
201 ; endcase of all "&xxxx" ;
202 ; endcase of all "#xxxx" ; <== PARAM101,102,104,108,10M1
203 ; endcase of all "REG"|"@REG"|"@REG+" <== PARAM124
204 PARAMENDOF MOV @PSP+,TOS ; --
206 mNEXT ; -- S=OPCODE,T=OPCODEADR
207 ; ----------------------------------;
208 PARAM11 CMP.B #'&',W ; -- sep
210 ; case of "&xxxx," ; -- sep search for "&xxxx,"
211 PARAM110 MOV #0210h,S ; -- sep set code type : xxxx(SR) with AS=0b01 ==> x210h (and SR=0 !)
213 ; case of ",&xxxx" ; <== PARAM20
214 PARAM111 ADD #1,&TOIN ; -- sep skip "&" prefix
215 CALL #SearchARG ; -- arg abort if not found
216 CALL #ARGD2S ; skip arg_hi of opcode type V
217 JMP StoreArg ; -- then ret
218 ; ----------------------------------;
219 PARAM12 CMP.B #'@',W ; -- sep
221 ; case of "@REG,"|"@REG+,"
222 PARAM120 MOV #0020h,S ; -- sep init OPCODE with indirect code type : AS=0b10
223 ADD #1,&TOIN ; -- sep skip "@" prefix
224 CALL #SearchREG ; Z = not found
225 JNZ PARAM123 ; -- value REG of "@REG," found
226 ; case of "@REG+," ; -- addr REG of "@REG" not found, search REG of "@REG+"
227 PARAM121 ADD #0010h,S ; change OPCODE from @REG to @REG+ type
228 MOV #'+',TOS ; -- "+" as WORD separator to find REG of "@REG+,"
229 CALL #SearchREG ; -- value|addr X = flag
231 ; case of "xxxx(REG)," ; <== PARAM130
232 ; case of double separator: +, and ),
233 PARAM122 CMP &SOURCE_LEN,&TOIN ; test OPCODE II parameter ending by REG+ or (REG) without comma,
234 JZ PARAM123 ; i.e. >IN = SOURCE_LEN : don't skip char CR !
235 ADD #1,&TOIN ; -- 000R skip "," ready for the second operand search
237 ; case of "xxxx(REG),"
238 ; case of "@REG," ; -- 000R <== PARAM120
239 ; case of "REG," ; -- 000R <== PARAM13
240 PARAM123 SWPB TOS ; -- 0R00 swap bytes because it's not a dst REG typeI (not a 2 ops inst.)
241 ; case of "@REG+," ; -- 0R00 (src REG typeI)
242 ; case of "xxxx(REG)," ; -- 0R00 (src REG typeI or dst REG typeII)
243 ; case of "@REG," ; -- 0R00 (src REG typeI)
244 ; case of "REG," ; -- 0R00 (src REG typeI or dst REG typeII)
245 ; case of ",REG" ; -- 000R <== PARAM21 (dst REG typeI)
246 ; case of ",xxxx(REG)" ; -- 000R <== PARAM210 (dst REG typeI)
247 PARAM124 ADD TOS,S ; -- 0R00|000R
249 ; ----------------------------------;
250 ; case of "REG,"|"xxxx(REG)," ; first, searg REG of "REG,"
251 PARAM13 CALL #SearchREG ; -- sep save >IN for second parsing (case of "xxxx(REG),")
252 JNZ PARAM123 ; -- 000R REG of "REG," found, S=OPCODE=0
253 ; case of "xxxx(REG)," ; -- c-addr "REG," not found
254 PARAM130 ADD #0010h,S ; AS=0b01 for indexing address
255 CALL #ComputeARGparenREG; compile xxxx and search REG of "(REG)"
258 ; ----------------------------------------------------------------------
259 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET 2th OPERAND
260 ; ----------------------------------------------------------------------
262 PARAM3 ; for OPCODES TYPE III
263 MOV #0,S ; init OPCODE=0
264 MOV &DDP,T ; T=OPCODEADR
265 ADD #2,&DDP ; make room for opcode
266 ; ----------------------------------;
267 PARAM2 mDOCOL ; parse input buffer until BL and compute this 2th operand
268 .word FBLANK,SKIP ; skip space(s) between "arg1," and "arg2" if any; use not S,T.
269 FORTHtoASM ; -- c-addr search for '&' of "&xxxx
271 MOV #20h,TOS ; -- ' ' as WORD separator to find xxxx of ",&xxxx"
272 JNE PARAM21 ; '&' not found
274 PARAM20 ADD #0082h,S ; change OPCODE : AD=1, dst = R2
275 JMP PARAM111 ; -- ' '
276 ; ----------------------------------;
277 ; case of ",REG"|",xxxx(REG) ; -- ' ' first, search REG of ",REG"
278 PARAM21 CALL #SearchREG ;
279 JNZ PARAM124 ; -- 000R REG of ",REG" found
280 ; case of ",xxxx(REG) ; -- addr REG not found
281 PARAM210 ADD #0080h,S ; set AD=1
282 CALL #ComputeARGparenREG; compile argument xxxx and search REG of "(REG)"
283 JMP PARAM124 ; -- 000R REG of "(REG) found
285 ; ----------------------------------------------------------------------
286 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODE TYPE 0 : zero operand f:-)
287 ; ----------------------------------------------------------------------
290 .word lit,1300h,COMMA,EXIT
292 ; ----------------------------------------------------------------------
293 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODES TYPE I : double operand
294 ; ----------------------------------------------------------------------
296 ; OPCODE(code) for TYPE I = 0bxxxx opcode I
298 ; = 0bxxxx src register
299 ; OPCODE(7) AD (dst addr type)
303 ; OPCODE(B) for TYPE I or TYPE II = 0b0 word
305 ; OPCODE(54) AS (src addr type)
306 ; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
311 ; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
312 ; ----------------------------------------------------------------------
314 ; TYPE1DOES -- BODYDOES search and compute PARAM1 & PARAM2 as src and dst operands then compile instruction
315 TYPE1DOES .word lit,',',PARAM1 ; -- BODYDOES
316 .word PARAM2 ; -- BODYDOES char separator (BL) included in PARAM2
318 MAKEOPCODE MOV T,X ; -- opcode X= OPCODEADR to compile opcode
319 MOV @TOS,TOS ; -- opcode part of instruction
320 BIS S,TOS ; -- opcode opcode is complete
321 JMP StoreTOS ; -- then EXIT
325 .word TYPE1DOES,4000h
328 .word TYPE1DOES,4040h
331 .word TYPE1DOES,5000h
334 .word TYPE1DOES,5040h
337 .word TYPE1DOES,6000h
340 .word TYPE1DOES,6040h
343 .word TYPE1DOES,7000h
346 .word TYPE1DOES,7040h
349 .word TYPE1DOES,8000h
352 .word TYPE1DOES,8040h
355 .word TYPE1DOES,9000h
358 .word TYPE1DOES,9040h
361 .word TYPE1DOES,0A000h
364 .word TYPE1DOES,0A040h
367 .word TYPE1DOES,0B000h
370 .word TYPE1DOES,0B040h
373 .word TYPE1DOES,0C000h
376 .word TYPE1DOES,0C040h
379 .word TYPE1DOES,0D000h
382 .word TYPE1DOES,0D040h
385 .word TYPE1DOES,0E000h
388 .word TYPE1DOES,0E040h
391 .word TYPE1DOES,0F000h
394 .word TYPE1DOES,0F040h
396 ; ----------------------------------------------------------------------
397 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE II : single operand
398 ; ----------------------------------------------------------------------
399 ; OPCODE(FEDCBA987) opcodeII
400 ; OPCODE(code) for TYPE II = 0bxxxxxxxxx
402 ; OPCODE(B) for TYPE I or TYPE II = 0b0 word
404 ; OPCODE(54) (dst addr type)
405 ; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
410 ; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
411 ; ----------------------------------------------------------------------
413 TYPE2DOES .word FBLANK,PARAM1 ; -- BODYDOES
416 AND #0070h,S ; keep B/W & AS infos in OPCODE
417 SWPB W ; (REG org --> REG dst)
418 AND #000Fh,W ; keep REG
419 BIS_ASMTYPE BIS W,S ; -- BODYDOES add it in OPCODE
420 JMP MAKEOPCODE ; -- then end
422 asmword "RRC" ; Rotate Right through Carry ( word)
424 .word TYPE2DOES,1000h
425 asmword "RRC.B" ; Rotate Right through Carry ( byte)
427 .word TYPE2DOES,1040h
428 asmword "SWPB" ; Swap bytes
430 .word TYPE2DOES,1080h
433 .word TYPE2DOES,1100h
436 .word TYPE2DOES,1140h
439 .word TYPE2DOES,1180h
442 .word TYPE2DOES,1200h
445 .word TYPE2DOES,1240h
448 .word TYPE2DOES,1280h
450 BOUNDERRWM1 ADD #1,W ; <== RRAM|RRUM|RRCM|RLAM error
451 BOUNDERRORW MOV W,TOS ; <== PUSHM|POPM|ASM_branch error
452 BOUNDERROR ; <== REG number error
453 mDOCOL ; -- n n = value out of bounds
455 .byte 13,"out of bounds"
458 ; --------------------------------------------------------------------------------
459 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE III : PUSHM|POPM|RLAM|RRAM|RRUM|RRCM
460 ; --------------------------------------------------------------------------------
461 ; PUSHM, syntax: PUSHM #n,REG with 0 < n < 17
462 ; POPM syntax: POPM #n,REG with 0 < n < 17
465 ; PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
466 ; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
468 ; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
470 ; POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
471 ; POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
473 ; example : POPM #6,IP pulls Y,X,W,T,S,IP registers from return stack
475 ; RxxM syntax: RxxM #n,REG with 0 < n < 5
477 TYPE3DOES .word FBLANK,SKIP ; skip spaces if any
478 FORTHtoASM ; -- BODYDOES c-addr
479 ADD #1,&TOIN ; skip "#"
480 MOV #',',TOS ; -- BODYDOES ","
483 .word QFBRAN,NotFound ; ABORT
484 .word PARAM3 ; -- BODYDOES 0x000N S=OPCODE = 0x000R
486 MOV TOS,W ; -- BODYDOES n W = n
487 MOV @PSP+,TOS ; -- BODYDOES
488 SUB #1,W ; W = n floored to 0
490 MOV @TOS,X ; X=OPCODE
491 RLAM #4,X ; OPCODE bit 1000h --> C
492 JNC RxxMINSTRU ; if bit 1000h = 0
493 PxxxINSTRU MOV S,Y ; S=REG, Y=REG to test
494 RLAM #3,X ; OPCODE bit 0200h --> C
495 JNC PUSHMINSTRU ; W=n-1 Y=REG
496 POPMINSTRU SUB W,S ; to make POPM opcode, compute first REG to POP; TI is complicated....
497 PUSHMINSTRU SUB W,Y ; Y=REG-(n-1)
499 JHS BOUNDERRWM1 ; JC=JHS (U>=)
500 RLAM #4,W ; W = n << 4
501 JMP BIS_ASMTYPE ; BODYDOES --
502 RxxMINSTRU CMP #4,W ;
503 JHS BOUNDERRWM1 ; JC=JHS (U>=)
504 SWPB W ; -- BODYDOES W = n << 8
505 RLAM #2,W ; W = N << 10
506 JMP BIS_ASMTYPE ; BODYDOES --
510 .word TYPE3DOES,0040h
513 .word TYPE3DOES,0050h
516 .word TYPE3DOES,0140h
519 .word TYPE3DOES,0150h
522 .word TYPE3DOES,0240h
525 .word TYPE3DOES,0250h
528 .word TYPE3DOES,0340h
531 .word TYPE3DOES,0350h
534 .word TYPE3DOES,1400h
537 .word TYPE3DOES,1500h
540 .word TYPE3DOES,1600h
543 .word TYPE3DOES,1700h
545 ; ----------------------------------------------------------------------
546 ; DTCforthMSP430FR5xxx ASSEMBLER, CONDITIONAL BRANCHS
547 ; ----------------------------------------------------------------------
548 ; ASSEMBLER FORTH OPCODE(FEDC)
549 ; OPCODE(code) for TYPE JNE,JNZ 0<>, <> = 0x20xx + (offset AND 3FF) ; branch if Z = 0
550 ; OPCODE(code) for TYPE JEQ,JZ 0=, = = 0x24xx + (offset AND 3FF) ; branch if Z = 1
551 ; OPCODE(code) for TYPE JNC,JLO U< = 0x28xx + (offset AND 3FF) ; branch if C = 0
552 ; OPCODE(code) for TYPE JC,JHS U>= = 0x2Cxx + (offset AND 3FF) ; branch if C = 1
553 ; OPCODE(code) for TYPE JN 0< = 0x30xx + (offset AND 3FF) ; branch if N = 1
554 ; OPCODE(code) for TYPE JGE >= = 0x34xx + (offset AND 3FF) ; branch if (N xor V) = 0
555 ; OPCODE(code) for TYPE JL < = 0x38xx + (offset AND 3FF) ; branch if (N xor V) = 1
556 ; OPCODE(code) for TYPE JMP = 0x3Cxx + (offset AND 3FF)
558 asmword "S>=" ; if >= assertion (opposite of jump if < )
562 asmword "S<" ; if < assertion
566 asmword "0>=" ; if 0>= assertion ; use only with IF UNTIL WHILE !
570 asmword "0<" ; jump if 0< ; use only with ?JMP ?GOTO !
574 asmword "U<" ; if U< assertion
578 asmword "U>=" ; if U>= assertion
582 asmword "0<>" ; if <>0 assertion
586 asmword "0=" ; if =0 assertion
590 ;ASM IF OPCODE -- @OPCODE1
593 MOV TOS,0(W) ; compile incomplete opcode
598 ;ASM THEN @OPCODE -- resolve forward branch
600 ASM_THEN MOV &DDP,W ; -- @OPCODE W=dst
601 MOV TOS,Y ; Y=@OPCODE
602 ASM_THEN1 MOV @PSP+,TOS ; --
604 ADD #2,X ; -- Y=@OPCODE W=dst X=src+2
605 SUB X,W ; -- Y=@OPCODE W=dst-src+2=displacement*2 (bytes)
606 RRA W ; -- Y=@OPCODE W=displacement (words)
608 JC BOUNDERRORW ; (JHS) unsigned branch if u> 511
609 BIS W,0(Y) ; -- [@OPCODE]=OPCODE completed
612 ;C ELSE @OPCODE1 -- @OPCODE2 branch for IF..ELSE
614 ASM_ELSE MOV &DDP,W ; -- W=HERE
615 MOV #3C00h,0(W) ; compile unconditionnal branch
616 ADD #2,&DDP ; -- DP+2
618 MOV W,0(PSP) ; -- @OPCODE2 @OPCODE1
619 JMP ASM_THEN ; -- @OPCODE2
621 ;C BEGIN -- @BEGIN same as FORTH counterpart
623 ;C UNTIL @BEGIN OPCODE -- resolve conditional backward branch
625 ASM_UNTIL MOV @PSP+,W ; -- OPCODE W=@BEGIN
626 ASM_UNTIL1 MOV TOS,Y ; Y=OPCODE W=@BEGIN
627 ASM_UNTIL2 MOV @PSP+,TOS ; --
628 MOV &DDP,X ; -- Y=OPCODE X=HERE W=dst
629 SUB #2,W ; -- Y=OPCODE X=HERE W=dst-2
630 SUB X,W ; -- Y=OPCODE X=src W=src-dst-2=displacement (bytes)
631 RRA W ; -- Y=OPCODE X=HERE W=displacement (words)
633 JL BOUNDERRORW ; signed branch if < -512
634 AND #3FFh,W ; -- Y=OPCODE X=HERE W=troncated negative displacement (words)
635 BIS W,Y ; -- Y=OPCODE (completed)
640 ;X AGAIN @BEGIN -- uncond'l backward branch
641 ; unconditional backward branch
643 ASM_AGAIN MOV TOS,W ; W=@BEGIN
644 MOV #3C00h,Y ; Y = asmcode JMP
647 ;C WHILE @BEGIN OPCODE -- @WHILE @BEGIN
649 ASM_WHILE mDOCOL ; -- @BEGIN OPCODE
650 .word ASM_IF,SWAP,EXIT
652 ;C REPEAT @WHILE @BEGIN -- resolve WHILE loop
654 ASM_REPEAT mDOCOL ; -- @WHILE @BEGIN
655 .word ASM_AGAIN,ASM_THEN,EXIT
657 ; ------------------------------------------------------------------------------------------
658 ; DTCforthMSP430FR5xxx ASSEMBLER : branch up to 3 backward labels and up to 3 forward labels
659 ; ------------------------------------------------------------------------------------------
660 ; used for non canonical branchs, as BASIC language: "goto line x"
661 ; labels BWx and FWx must be set at the beginning of line (>IN < 8).
662 ; FWx at the beginning of a line can resolve only one previous GOTO|?GOTO FWx.
663 ; BWx at the beginning of a line can be resolved by any subsequent GOTO|?GOTO BWx.
667 MOV TOS,Y ; -- PFA Y = ASMBWx addr
670 CMP #8,&TOIN ; are we colon 8 or more ?
671 BACKWUSE JHS ASM_UNTIL1 ; yes, use this label
672 BACKWSET MOV &DDP,0(Y) ; no, set LABEL = DP
694 MOV @TOS,Y ; -- PFA Y=[ASMFWx]
695 CMP #8,&TOIN ; are we colon 8 or more ?
696 FORWUSE JLO ASM_THEN1 ; no: resolve FWx with W=DDP, Y=ASMFWx
697 FORWSET MOV @PSP+,0(W) ; yes compile incomplete opcode
698 ADD #2,&DDP ; increment DDP
699 MOV W,0(TOS) ; store @OPCODE into ASMFWx
719 ;ASM <cond> ?GOTO <label> OPCODE -- conditionnal branch to label
721 INVJMP CMP #3000h,TOS ; invert code jump process
722 JZ GOTONEXT ; case of JN, do nothing
723 XOR #0400h,TOS ; case of: JNZ<-->JZ JNC<-->JC JL<-->JGE
724 BIT #1000h,TOS ; 3xxxh case ?
726 XOR #0800h,TOS ; complementary action for JL<-->JGE
728 .word TICK ; -- OPCODE CFA<label>
731 ;ASM GOTO <label> -- unconditionnal branch to label
735 MOV #3C00h,TOS ; asmcode JMP
738 ; ===============================================================
740 ; ===============================================================
742 ; ===============================================================
743 ; to allow data access beyond $FFFF
744 ; ===============================================================
746 ; MOVA (#$x.xxxx|&$x.xxxx|$.xxxx(Rs)|Rs|@Rs|@Rs+ , &|Rd|$.xxxx(Rd))
747 ; ADDA (#$x.xxxx|Rs , Rd)
748 ; CMPA (#$x.xxxx|Rs , Rd)
749 ; SUBA (#$x.xxxx|Rs , Rd)
751 ; first argument process ACMS1
752 ;-----------------------------------;
753 ACMS1 mDOCOL ; -- BODYDOES ','
754 .word FBLANK,SKIP ; -- BODYDOES ',' addr
756 MOV.B @TOS,X ; X=first char of opcode string
757 MOV @PSP+,TOS ; -- BODYDOES ','
758 MOV @PSP+,S ; -- ',' S=BODYDOES
761 ADD #2,&DDP ; make room for opcode
762 ;-----------------------------------;
763 ACMS10 CMP.B #'R',X ; -- ','
765 ACMS101 CALL #SearchREG ; -- Rn src
766 ACMS102 RLAM #4,TOS ; 8<<src
768 ACMS103 BIS S,TOS ; update opcode with src|dst
769 MOV TOS,0(T) ; save opcode
770 MOV T,TOS ; -- OPCODE_addr
772 ;-----------------------------------;
773 ACMS11 CMP.B #'#',X ; -- ',' X=addr
775 BIC #40h,S ; set #opcode
776 ACMS111 ADD #1,&TOIN ; skip '#'|'&'
777 ADD #2,&DDP ; make room for low #$xxxx|&$xxxx|$xxxx(REG)
778 CALL #SearchARG ; -- Lo Hi
779 MOV @PSP+,2(T) ; -- Hi store $xxxx of #$x.xxxx|&$x.xxxx|$x.xxxx(REG)
780 AND #0Fh,TOS ; -- Hi sel Hi src
782 ;-----------------------------------;
783 MOVA12 CMP.B #'&',X ; -- ',' case of MOVA &$x.xxxx
785 XOR #00E0h,S ; set MOVA &$x.xxxx, opcode
787 ;-----------------------------------;
788 MOVA13 BIC #00F0h,S ; set MOVA @REG, opcode
789 CMP.B #'@',X ; -- ','
791 ADD #1,&TOIN ; skip '@'
792 CALL #SearchREG ; -- Rn
793 JNZ ACMS102 ; if @REG found
794 ;-----------------------------------;
795 BIS #0010h,S ; set @REG+ opcode
796 MOV #'+',TOS ; -- '+'
797 MOVA131 CALL #SearchREG ; -- Rn case of MOVA @REG+,|MOVA $x.xxxx(REG),
798 CMP &SOURCE_LEN,&TOIN ; test TYPE II first parameter ending by @REG+ (REG) without comma,
799 JZ ACMS102 ; i.e. may be >IN = SOURCE_LEN: don't skip char CR !
800 ADD #1,&TOIN ; skip "," ready for the second operand search
802 ;-----------------------------------;
803 MOVA14 BIS #0030h,S ; set xxxx(REG), opcode
804 ADD #2,&DDP ; -- ',' make room for first $xxxx of $0.xxxx(REG),
805 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
806 CALL #SearchARG ; -- Lo Hi
807 MOV @PSP+,2(T) ; -- Hi store $xxxx as 2th word
808 MOV #')',TOS ; -- ')'
811 ; 2th argument process ACMS2
812 ;-----------------------------------;
813 ACMS2 mDOCOL ; -- OPCODE_addr
814 .word FBLANK,SKIP ; -- OPCODE_addr addr
816 MOV @PSP+,T ; -- addr T=OPCODE_addr
818 MOV.B @TOS,X ; -- addr X=first char of string instruction
819 MOV.B #' ',TOS ; -- ' '
820 ;-----------------------------------;
821 ACMS21 CMP.B #'R',X ; -- ' '
823 ACMS211 CALL #SearchREG ; -- Rn
825 ;-----------------------------------;
827 ADD #2,&DDP ; -- ' ' make room for $xxxx
830 BIS #060h,S ; set ,&$x.xxxx opcode
831 ADD #1,&TOIN ; skip '&'
832 CALL #SearchARG ; -- Lo Hi
833 MOV @PSP+,2(T) ; -- Hi store $xxxx as 2th word
834 JMP ACMS103 ; update opcode with dst $x and write opcode
835 ;-----------------------------------;
836 MOVA23 BIS #070h,S ; set ,xxxx(REG) opcode
837 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
838 CALL #SearchARG ; -- Lo Hi
839 MOV @PSP+,2(T) ; -- Hi write $xxxx of ,$0.xxxx(REG) as 2th word
840 MOV #')',TOS ; -- ")" as WORD separator to find REG of "xxxx(REG),"
843 ; --------------------------------------------------------------------------------
844 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES IV 2 operands: Adda|Cmpa|Mova|Suba (without extended word)
845 ; --------------------------------------------------------------------------------
846 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
847 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
848 ; --------------------------------------------------------------------------------
850 TYPE4DOES .word lit,',' ; -- BODYDOES "," char separator for PARAM1
851 .word ACMS1 ; -- OPCODE_addr
852 .word ACMS2 ; -- OPCODE_addr
857 .word TYPE4DOES,00C0h
860 .word TYPE4DOES,00D0h
863 .word TYPE4DOES,00E0h
866 .word TYPE4DOES,00F0h
868 ; --------------------------------------------------------------------------------
869 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODE TYPE III bis: CALLA (without extended word)
870 ; --------------------------------------------------------------------------------
871 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
872 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
873 ; --------------------------------------------------------------------------------
877 .word FBLANK,SKIP ; -- addr
880 ADD #2,&DDP ; make room for opcode
881 MOV.B @TOS,TOS ; -- char First char of opcode
882 CALLA0 MOV #134h,S ; 134h<<4 = 1340h = opcode for CALLA Rn
885 CALLA01 MOV.B #' ',TOS ;
886 CALLA02 CALL #SearchREG ; -- Rn
887 CALLA03 RLAM #4,S ; (opcode>>4)<<4 = opcode
888 BIS TOS,S ; update opcode
889 MOV S,0(T) ; store opcode
892 ;-----------------------------------;
893 CALLA1 ADD #2,S ; 136h<<4 = opcode for CALLA @REG
894 CMP.B #'@',TOS ; -- char Search @REG
896 ADD #1,&TOIN ; skip '@'
897 MOV.B #' ',TOS ; -- ' '
899 JNZ CALLA03 ; if REG found, update opcode
900 ;-----------------------------------;
901 ADD #1,S ; 137h<<4 = opcode for CALLA @REG+
902 MOV #'+',TOS ; -- '+'
904 ;-----------------------------------;
905 CALLA2 ADD #2,&DDP ; make room for xxxx of #$x.xxxx|&$x.xxxx|$0.xxxx(REG)
908 MOV #13Bh,S ; 13Bh<<4 = opcode for CALLA #$x.xxxx
909 CALLA21 ADD #1,&TOIN ; skip '#'|'&'
910 CALLA22 CALL #SearchARG ; -- Lo Hi
911 MOV @PSP+,2(T) ; -- Hi store #$xxxx|&$xxxx
912 JMP CALLA03 ; update opcode with $x. and store opcode
913 ;-----------------------------------;
914 CALLA3 CMP.B #'&',TOS
916 ADD #2,S ; 138h<<4 = opcode for CALLA &$x.xxxx
918 ;-----------------------------------;
919 CALLA4 MOV.B #'(',TOS ; -- "("
920 SUB #1,S ; 135h<<4 = opcode for CALLA $0.xxxx(REG)
921 CALLA41 CALL #SearchARG ; -- Lo Hi
922 MOV @PSP+,2(T) ; -- Hi store $xxxx
923 MOV #')',TOS ; -- ')'
924 JMP CALLA02 ; search Rn and update opcode
927 ; PRMX1 is used for OPCODES type V (double operand) and OPCODES type VI (single operand) extended instructions
929 PRMX1 mDOCOL ; -- sep OPCODES type V|VI separator = ','|' '
930 .word FBLANK,SKIP ; -- sep addr
932 MOV.B @TOS,X ; -- sep addr X= first char of opcode string
933 MOV @PSP+,TOS ; -- sep
934 MOV #1800h,S ; init S=Extended word
935 ;-----------------------------------;
936 PRMX10 CMP.B #'R',X ; -- sep
938 PRMX101 CALL #SearchREG ; -- Rn Rn of REG; call SearchREG only to update >IN
939 PRMX102 MOV S,TOS ; -- EW update Extended word
940 PRMX103 mSEMI ; -- Ext_Word
941 ;-----------------------------------;
942 PRMX11 MOV #0,&RPT_WORD ; clear RPT
943 CMP.B #'#',X ; -- sep
945 PRMX111 ADD #1,&TOIN ; -- sep skip '#'
946 PRMX112 CALL #SearchARG ; -- Lo Hi search $x.xxxx of #x.xxxx,
947 ADD #2,PSP ; -- Hi pop unused low word
948 PRMX113 AND #0Fh,TOS ;
950 RLAM #4,TOS ; -- 7<<Hi
951 PRMX115 BIS TOS,S ; update extended word with srcHi
953 ;-----------------------------------;
954 PRMX12 CMP.B #'&',X ; -- sep
956 ;-----------------------------------;
957 PRMX13 CMP.B #'@',X ; -- sep
959 PRMX131 ADD #1,&TOIN ; -- sep skip '@'
960 PRMX132 CALL #SearchREG ; -- Rn Rn of @REG,
961 JNZ PRMX102 ; if Rn found
962 ;-----------------------------------;
963 MOV #'+',TOS ; -- '+'
964 PRMX133 ADD #1,&TOIN ; skip '@'
965 CALL #SearchREG ; -- Rn Rn of @REG+,
966 PRMX134 CMP &SOURCE_LEN,&TOIN ; test case of TYPE VI first parameter without ','
967 JZ PRMX102 ; don't take the risk of skipping CR !
968 ADD #1,&TOIN ; skip ',' ready to search 2th operand
970 ;-----------------------------------;
971 PRMX14 MOV #'(',TOS ; -- '(' to find $x.xxxx of "x.xxxx(REG),"
972 CALL #SearchARG ; -- Lo Hi
973 MOV TOS,0(PSP) ; -- Hi Hi
974 PRMX141 MOV #')',TOS ; -- Hi ')'
975 CALL #SearchREG ; -- Hi Rn
976 MOV @PSP+,TOS ; -- Hi
980 ;-----------------------------------;
982 ; PRMX2 is used for OPCODES type V (double operand) extended instructions
984 ;-----------------------------------;
985 PRMX2 mDOCOL ; -- Extended_Word
986 .word FBLANK,SKIP ; -- Extended_Word addr
988 MOV @PSP+,S ; -- addr S=Extended_Word
989 MOV.B @TOS,X ; -- addr X=first char of code instruction
990 MOV #' ',TOS ; -- ' '
991 ;-----------------------------------;
992 PRMX20 CMP.B #'R',X ; -- ' '
993 JZ PRMX102 ; extended word not to be updated
994 ;-----------------------------------;
995 PRMX21 MOV #0,&RPT_WORD ;
998 PRMX211 ADD #1,&TOIN ; -- ' ' skip '&'
999 PRMX212 CALL #SearchARG ; -- Lo Hi
1000 PRMX213 ADD #2,PSP ; -- hi pop low word
1001 AND #0Fh,TOS ; -- Hi
1002 JMP PRMX115 ; update Extended word with dst_Hi
1003 ;-----------------------------------;
1004 PRMX22 MOV #'(',TOS ; -- '(' as WORD separator to find xxxx of "xxxx(REG)"
1005 CALL #SearchARG ; -- Lo Hi search x.xxxx of x.xxxx(REG)
1008 ; UPDATE_eXtendedWord
1009 ;-----------------------------------;
1010 UPDATE_XW ; BODYDOES Extended_Word -- BODYDOES+2 >IN R--
1012 ADD #2,&DDP ; make room for extended word
1013 MOV TOS,S ; S = Extended_Word
1014 MOV @PSP+,TOS ; -- BODYDOES
1015 BIS &RPT_WORD,S ; update Extended_word with RPT_WORD
1016 MOV #0,&RPT_WORD ; clear RPT before next instruction
1017 BIS @TOS+,S ; -- BODYDOES+2 update Extended_word with [BODYDOES] = A/L bit
1018 MOV S,0(T) ; store extended word
1019 MOV @RSP+,&TOIN ; >IN R-- restore >IN at the start of instruction string
1021 ;-----------------------------------;
1023 ; --------------------------------------------------------------------------------
1024 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES V extended double operand
1025 ; --------------------------------------------------------------------------------
1026 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
1027 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
1028 ; --------------------------------------------------------------------------------
1031 ; these instructions below are processed in two pass:
1032 ; pass 1: extended word process by TYPE5DOES with [BODYDOES] value
1033 ; pass 2: instruction process by TYPE1DOES with [BODYDOES+2] value
1034 ; all numeric arguments must be written as DOUBLE numbers (including a point) : $x.xxxx
1036 TYPE5DOES ; -- BODYDOES
1037 .word LIT,TOIN,FETCH,TOR ; R-- >IN save >IN for 2th pass
1038 .word lit,',' ; -- BODYDOES ',' char separator for PRMX1
1039 .word PRMX1,PRMX2 ; -- BODYDOES Extended_Word
1040 .word UPDATE_XW ; -- BODYDOES+2 >IN is restored ready for 2th pass
1041 .word BRAN,TYPE1DOES ; -- BODYDOES+2 2th pass: completes instruction with opcode = [BODYDOES+2]
1045 .word TYPE5DOES,40h,4000h ; [PFADOES]=TYPE5DOES, [BODYDOES]=A/L bit, [BODYDOES+2]=OPCODE,
1048 .word TYPE5DOES,0,4040h
1051 .word TYPE5DOES,40h,4040h
1054 .word TYPE5DOES,40h,5000h
1057 .word TYPE5DOES,0,5040h
1060 .word TYPE5DOES,40h,5040h
1063 .word TYPE5DOES,40h,6000h
1066 .word TYPE5DOES,0,6040h
1069 .word TYPE5DOES,40h,6040h
1072 .word TYPE5DOES,40h,7000h
1075 .word TYPE5DOES,0,7040h
1078 .word TYPE5DOES,40h,7040h
1081 .word TYPE5DOES,40h,8000h
1084 .word TYPE5DOES,0,8040h
1087 .word TYPE5DOES,40h,8040h
1090 .word TYPE5DOES,40h,9000h
1093 .word TYPE5DOES,0,9040h
1096 .word TYPE5DOES,40h,9040h
1099 .word TYPE5DOES,40h,0A000h
1102 .word TYPE5DOES,0,0A040h
1105 .word TYPE5DOES,40h,0A040h
1108 .word TYPE5DOES,40h,0B000h
1111 .word TYPE5DOES,0,0B040h
1114 .word TYPE5DOES,40h,0B040h
1117 .word TYPE5DOES,40h,0C000h
1120 .word TYPE5DOES,0,0C040h
1123 .word TYPE5DOES,40h,0C040h
1126 .word TYPE5DOES,40h,0D000h
1129 .word TYPE5DOES,0,0D040h
1132 .word TYPE5DOES,40h,0D040h
1135 .word TYPE5DOES,40h,0E000h
1138 .word TYPE5DOES,0,0E040h
1141 .word TYPE5DOES,40h,0E040h
1144 .word TYPE5DOES,40h,0F000h
1147 .word TYPE5DOES,0,0F040h
1150 .word TYPE5DOES,40h,0F040h
1152 ; --------------------------------------------------------------------------------
1153 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES VI extended single operand (take count of RPT)
1154 ; --------------------------------------------------------------------------------
1155 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
1156 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
1157 ; --------------------------------------------------------------------------------
1159 ; these instructions below are processed in two pass:
1160 ; pass 1: extended word process by TYPE6DOES with [BODYDOES] value
1161 ; pass 2: instruction process by TYPE2DOES with [BODYDOES+2] value
1162 ; all numeric arguments must be written as DOUBLE numbers (including a point) : $x.xxxx
1164 TYPE6DOES ; -- BODYDOES
1165 .word LIT,TOIN,FETCH,TOR ; save >IN for 2th pass
1166 .word FBLANK ; -- BODYDOES ' '
1167 .word PRMX1 ; -- BODYDOES Extended_Word
1168 .word UPDATE_XW ; -- BODYDOES+2
1169 .word BRAN,TYPE2DOES ; -- BODYDOES+2 pass 2: completes instruction with opcode = [BODYDOES+2]
1171 asmword "RRCX" ; ZC=0; RRCX Rx,Rx may be repeated by prefix RPT #n|Rn
1173 .word TYPE6DOES,40h,1000h
1174 asmword "RRCX.A" ; ZC=0; RRCX.A Rx may be repeated by prefix RPT #n|Rn
1176 .word TYPE6DOES,0,1040h
1177 asmword "RRCX.B" ; ZC=0; RRCX.B Rx may be repeated by prefix RPT #n|Rn
1179 .word TYPE6DOES,40h,1040h
1180 asmword "RRUX" ; ZC=1; RRUX Rx may be repeated by prefix RPT #n|Rn
1182 .word TYPE6DOES,140h,1000h
1183 asmword "RRUX.A" ; ZC=1; RRUX.A Rx may be repeated by prefix RPT #n|Rn
1185 .word TYPE6DOES,100h,1040h
1186 asmword "RRUX.B" ; ZC=1; RRUX.B Rx may be repeated by prefix RPT #n|Rn
1188 .word TYPE6DOES,140h,1040h
1191 .word TYPE6DOES,40h,1080h
1194 .word TYPE6DOES,0,1080h
1197 .word TYPE6DOES,40h,1100h
1200 .word TYPE6DOES,0,1140h
1203 .word TYPE6DOES,40h,1140h
1206 .word TYPE6DOES,40h,1180h
1209 .word TYPE6DOES,0,1180h
1212 .word TYPE6DOES,40h,1200h
1215 .word TYPE6DOES,0,1240h
1218 .word TYPE6DOES,40h,1240h
1220 ; ----------------------------------------------------------------------
1221 ; DTCforthMSP430FR5xxx ASSEMBLER, RPT instruction before REG|REG,REG eXtended instructions
1222 ; ----------------------------------------------------------------------
1223 ; RPT #1 is coded 0 in repetition count field (count n-1)
1224 ; please note that "RPT Rn" with [Rn]=0 has same effect as "RPT #1"
1228 asmword "RPT" ; RPT #n | RPT Rn repeat n | [Rn]+1 times modulo 16
1231 FORTHtoASM ; -- addr
1233 MOV.B #' ',TOS ; -- ' ' as separator
1236 CALL #SearchREG ; -- Rn
1237 JZ RPT1 ; if not found
1238 BIS #80h,TOS ; -- $008R R=Rn
1240 RPT1 CALL #SearchARG ; -- $xxxx
1242 AND #0Fh,TOS ; -- $000x
1243 RPT2 MOV TOS,&RPT_WORD