1 ; -*- coding: utf-8 -*-
3 ; ----------------------------------------------------------------------
4 ;forthMSP430FR_EXTD_ASM.asm
5 ; ----------------------------------------------------------------------
7 ; ----------------------------------------------------------------------
8 ; MOV(.B) #0, dst is coded as follow : MOV(.B) R3, dst ; 1 cycle, one word As=00 register mode
9 ; MOV(.B) #1, dst is coded as follow : MOV(.B) 0(R3), dst ; 2 cycles, one word AS=01 x(reg) mode
10 ; MOV(.B) #2, dst is coded as follow : MOV(.B) @R3, dst ; 2 cycles, one word AS=10 @reg mode
11 ; MOV(.B) #4, dst is coded as follow : MOV(.B) @R2, dst ; 2 cycles, one word AS=10 @reg mode
12 ; MOV(.B) #8, dst is coded as follow : MOV(.B) @R2+, dst ; 2 cycles, one word AS=11 @reg+ mode
13 ; MOV(.B) #-1,dst is coded as follow : MOV(.B) @R3+, dst ; 2 cycles, one word AS=11
14 ; MOV(.B) #xxxx,dst is coded a follow : MOV(.B) @PC+, dst ; 2 cycles, two words AS=11 @reg+ mode
15 ; 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
16 ; ----------------------------------------------------------------------
18 ; PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
19 ; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
21 ; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
23 ; POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
24 ; POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
26 ; example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
29 ;;Z SKIP char -- addr ; skip all occurring character 'char'
30 ; FORTHWORD "SKIP" ; used by assembler to parse input stream
31 SKIP MOV #SOURCE_LEN,Y ;2
32 MOV TOS,W ; -- char W=char
33 MOV @Y+,X ;2 -- char W=char X=buf_length
34 MOV @Y,TOS ;2 -- Start_buf_adr W=char X=buf_length
35 ADD TOS,X ; -- Start_buf_adr W=char X=Start_buf_adr+buf_length=End_buf_addr
36 ADD &TOIN,TOS ; -- Parse_Adr W=char X=End_buf_addr
37 SKIPLOOP CMP TOS,X ; -- Parse_Adr W=char X=End_buf_addr
38 JZ SKIPEND ; -- Parse_Adr if end of buffer
39 CMP.B @TOS+,W ; -- Parse_Adr does character match?
40 JZ SKIPLOOP ; -- Parse_Adr+1
41 SKIPNEXT SUB #1,TOS ; -- addr
43 SUB @Y,W ; -- addr W=Parse_Addr-Start_buf_adr=Toin
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
61 ; .word QFBRAN,ARGWORD ; -- addr if Word found
63 ; .word QFBRAN,NotFound ; -- addr ABORT if not found
64 ; FSearchEnd .word SearchEnd ; -- value goto SearchEnd if number found
65 ; ARGWORD .word $+2 ; -- CFA
66 ; MOV @TOS+,S ; -- PFA S=DOxxx
67 ; QDOVAR SUB #DOVAR,S ; DOxxx = 1287h = DOVAR
68 ; ISDOVAR JZ SearchEnd ; -- addr PFA = adr of VARIABLE
69 ; QDOCON ADD #1,S ; DOxxx = 1286h = DOCON
71 ; ISDOCON MOV @TOS,TOS ;
72 ; JMP SearchEnd ; -- cte
73 ; ISOTHER SUB #2,TOS ; -- CFA
74 ; SearchEnd POPM #2,S ; POPM T,S
77 SearchARG ; separator -- n|d or abort" not found"
78 ; Search ARG of "#xxxx," ; <== PARAM10
79 ; Search ARG of "&xxxx," ; <== PARAM111
80 ; Search ARG of "xxxx(REG)," ; <== ComputeARGpREG <== PARAM130
81 ; Search ARG of ",&xxxx" ; <== PARAM111 <== PARAM20
82 ; Search ARG of ",xxxx(REG)" ; <== ComputeARGpREG <== PARAM210
83 PUSHM #2,S ; PUSHM S,T as OPCODE,OPCODEADR
84 PUSH TOS ; push sep, for SrchARGPO
85 PUSH &TOIN ; push TOIN, for SrchARGPO
86 ;-----------------------------------;
87 ASMtoFORTH ; -- sep sep = ','|'('|' '
88 .word WORDD,FIND ; -- addr search word first
90 .word QFBRAN,ARGWORD ; -- addr if Word found
92 .word QFBRAN,SrchARGPO; -- addr search ARG Plus Offset if not found
93 .word SrchNext ; -- value goto SrchNext if number found
94 ARGWORD .word $+2 ; -- CFA
95 MOV @TOS+,S ; -- PFA S=DOxxx
96 QDOVAR SUB #1287h,S ; DOxxx = 1287h = CALL R7 = rDOVAR
97 ISDOVAR JZ SrchNext ; -- addr PFA = adr of VARIABLE
98 QDOCON ADD #1,S ; DOxxx = 1286h = DOCON
100 ISDOCON MOV @TOS,TOS ;
101 JMP SrchNext ; -- cte
102 ISOTHER SUB #2,TOS ; -- CFA
103 SrchNext ADD #4,RSP ; remove TOIN,sep
104 SearchEnd POPM #2,S ; POPM T,S
107 ;-----------------------------------;
108 ; search for ARGUMENT16+OFFSET ; up to $FFFF only (FORTH area)
109 ;-----------------------------------;
111 MOV @RSP+,&TOIN ; TOIN back
112 MOV @RSP+,TOS ; -- sep
114 .word LIT,'+' ; -- sep '+' search argument
115 .word WORDD,FIND ; -- sep CFA
117 .word QFBRAN,SrchOffst;
118 .word QNUMBER ; -- sep number
119 .word QFBRAN,NotFound ; see INTERPRET
120 SrchOffst .word SWAP ; -- CFA|number sep
121 .word WORDD,QNUMBER ; Search 'Offset,'|'Offset('|'Offset'
122 .word QFBRAN,NotFound ; see INTERPRET
123 .word $+2 ; -- CFA|number offset
124 ADD @PSP+,TOS ; -- (CFA|number + offset)
127 ; Arg_Double_to_single conversion needed only for OPCODE type V|VI, 2th pass.
128 ARGD2S BIT #UF9,SR ; -- Lo Hi
130 MOV @PSP+,TOS ; -- Lo skip hi
131 ARGD2SEND MOV @RSP+,PC ;
133 ; ----------------------------------------------------------------------
134 ; DTCforthMSP430FR5xxx ASSEMBLER : search REG
135 ; ----------------------------------------------------------------------
137 ; compute arg of "xxxx(REG)," ; <== PARAM130, sep=','
138 ; compute arg of ",xxxx(REG)" ; <== PARAM210, sep=' '
139 ComputeARGParenREG ; sep -- Rn
140 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
141 CALL #SearchARG ; -- xxxx aborted if not found
142 CALL #ARGD2S ; skip arg_hi if DOUBLE
145 MOV TOS,0(X) ; -- xxxx compile xxxx
146 MOV #')',TOS ; -- ")" prepare separator to search REG of "xxxx(REG)"
148 ; search REG of "xxxx(REG)," separator = ')'
149 ; search REG of ",xxxx(REG)" separator = ')'
150 ; search REG of "@REG," separator = ',' <== PARAM120
151 ; search REG of "@REG+," separator = '+' <== PARAM121
152 ; search REG of "REG," separator = ',' <== PARAM13
153 ; search REG of ",REG" separator = BL <== PARAM21
155 SearchREG PUSHM #2,S ; PUSHM S,T as OPCODE, OPCODEADR
156 CMP &SOURCE_LEN,&TOIN ; bad case of ,xxxx without prefix &
158 MOV #BAD_CSP,PC ; génère une erreur bidon
159 SearchREG1 PUSH &TOIN ; -- sep save >IN
160 ADD #1,&TOIN ; skip "R"
161 ASMtoFORTH ; search xx of Rxx
162 .word WORDD,QNUMBER ;
163 .word QFBRAN,NOTaREG ; -- xxxx if Not a Number
164 .word $+2 ; -- Rn number is found
165 ADD #2,RSP ; remove >IN
167 JC BOUNDERROR ; abort if Rn out of bounds
168 JNC SearchEnd ; -- Rn Z=0 ==> found
170 NOTaREG .word $+2 ; -- addr Z=1
171 MOV @RSP+,&TOIN ; -- addr restore >IN
172 JMP SearchEnd ; -- addr Z=1 ==> not a register
174 ; ----------------------------------------------------------------------
175 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET FIRST OPERAND
176 ; ----------------------------------------------------------------------
178 ; PARAM1 is used for OPCODES type I (double operand) and OPCODES type II (single operand) instructions
179 ; PARAM1 is used for OPCODES type V (double operand) and OPCODES type VI (single operand) extended instructions
181 ; PARAM1 separator -- ; parse input buffer until separator and compute first operand of opcode
182 ; sep is comma for src and space for dst .
183 PARAM1 mDOCOL ; -- sep OPCODES types I|V sep = ',' OPCODES types II|VI sep = ' '
184 .word FBLANK,SKIP ; -- sep addr
185 .word $+2 ; -- sep addr
186 MOV #0,S ; -- sep addr reset OPCODE
187 MOV &DDP,T ; -- sep addr HERE --> OPCODEADR (opcode is preset to its address !)
188 ADD #2,&DDP ; -- sep addr cell allot for opcode
189 MOV.B @TOS,W ; -- sep addr W=first char of instruction code
190 MOV @PSP+,TOS ; -- sep W=c-addr
191 CMP.B #'#',W ; -- sep W=first char
193 ; "#" found : case of "#xxxx,"
194 PARAM10 ADD #1,&TOIN ; -- sep skip # prefix
195 CALL #SearchARG ; -- xxxx abort if not found
196 CALL #ARGD2S ; skip arg_hi of OPCODE type V
197 MOV #0300h,S ; OPCODE = 0300h : MOV #0,dst is coded MOV R3,dst
198 CMP #0,TOS ; -- xxxx #0 ?
200 MOV #0310h,S ; OPCODE = 0310h : MOV #1,dst is coded MOV 0(R3),dst
201 CMP #1,TOS ; -- xxxx #1 ?
203 MOV #0320h,S ; OPCODE = 0320h : MOV #2,dst is coded MOV @R3,dst
204 CMP #2,TOS ; -- xxxx #2 ?
206 MOV #0220h,S ; OPCODE = 0220h : MOV #4,dst is coded MOV @R2,dst
207 CMP #4,TOS ; -- xxxx #4 ?
209 MOV #0230h,S ; OPCODE = 0230h : MOV #8,dst is coded MOV @R2+,dst
210 CMP #8,TOS ; -- xxxx #8 ?
212 MOV #0330h,S ; -- -1 OPCODE = 0330h : MOV #-1,dst is coded MOV @R3+,dst
213 CMP #-1,TOS ; -- xxxx #-1 ?
215 MOV #0030h,S ; -- xxxx for all other cases : MOV @PC+,dst
216 ; case of "&xxxx," ; <== PARAM110
217 ; case of ",&xxxx" ; <== PARAM20
218 StoreArg MOV &DDP,X ;
219 ADD #2,&DDP ; cell allot for arg
220 StoreTOS ; <== TYPE1DOES
221 MOV TOS,0(X) ; compile arg
222 ; endcase of all "&xxxx" ;
223 ; endcase of all "#xxxx" ; <== PARAM101,102,104,108,10M1
224 ; endcase of all "REG"|"@REG"|"@REG+" <== PARAM124
225 PARAMENDOF MOV @PSP+,TOS ; --
227 MOV @IP+,PC ; -- S=OPCODE,T=OPCODEADR
228 ; ----------------------------------;
229 PARAM11 CMP.B #'&',W ; -- sep
231 ; case of "&xxxx," ; -- sep search for "&xxxx,"
232 PARAM110 MOV #0210h,S ; -- sep set code type : xxxx(SR) with AS=0b01 ==> x210h (and SR=0 !)
234 ; case of ",&xxxx" ; <== PARAM20
235 PARAM111 ADD #1,&TOIN ; -- sep skip "&" prefix
236 CALL #SearchARG ; -- arg abort if not found
237 CALL #ARGD2S ; skip argD_hi of opcode type V
238 JMP StoreArg ; -- then ret
239 ; ----------------------------------;
240 PARAM12 CMP.B #'@',W ; -- sep
242 ; case of "@REG,"|"@REG+,"
243 PARAM120 MOV #0020h,S ; -- sep init OPCODE with indirect code type : AS=0b10
244 ADD #1,&TOIN ; -- sep skip "@" prefix
245 CALL #SearchREG ; Z = not found
246 JNZ PARAM123 ; -- value REG of "@REG," found
247 ; case of "@REG+," ; -- addr REG of "@REG" not found, search REG of "@REG+"
248 PARAM121 ADD #0010h,S ; change OPCODE from @REG to @REG+ type
249 MOV #'+',TOS ; -- "+" as WORD separator to find REG of "@REG+,"
250 CALL #SearchREG ; -- value|addr X = flag
252 ; case of "xxxx(REG)," ; <== PARAM130
253 ; case of double separator: +, and ),
254 PARAM122 CMP &SOURCE_LEN,&TOIN ; test OPCODE II parameter ending by REG+ or (REG) without comma,
255 JZ PARAM123 ; i.e. >IN = SOURCE_LEN : don't skip char CR !
256 ADD #1,&TOIN ; -- 000R skip "," ready for the second operand search
258 ; case of "xxxx(REG),"
259 ; case of "@REG," ; -- 000R <== PARAM120
260 ; case of "REG," ; -- 000R <== PARAM13
261 PARAM123 SWPB TOS ; -- 0R00 swap bytes because it's not a dst REG typeI (not a 2 ops inst.)
262 ; case of "@REG+," ; -- 0R00 (src REG typeI)
263 ; case of "xxxx(REG)," ; -- 0R00 (src REG typeI or dst REG typeII)
264 ; case of "@REG," ; -- 0R00 (src REG typeI)
265 ; case of "REG," ; -- 0R00 (src REG typeI or dst REG typeII)
266 ; case of ",REG" ; -- 000R <== PARAM21 (dst REG typeI)
267 ; case of ",xxxx(REG)" ; -- 000R <== PARAM210 (dst REG typeI)
268 PARAM124 ADD TOS,S ; -- 0R00|000R
270 ; ----------------------------------;
271 ; case of "REG,"|"xxxx(REG)," ; first, searg REG of "REG,"
272 PARAM13 CALL #SearchREG ; -- sep save >IN for second parsing (case of "xxxx(REG),")
273 JNZ PARAM123 ; -- 000R REG of "REG," found, S=OPCODE=0
274 ; case of "xxxx(REG)," ; -- c-addr "REG," not found
275 PARAM130 ADD #0010h,S ; AS=0b01 for indexing address
276 CALL #ComputeARGparenREG; compile xxxx and search REG of "(REG)"
279 ; ----------------------------------------------------------------------
280 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET 2th OPERAND
281 ; ----------------------------------------------------------------------
283 PARAM3 ; for OPCODES TYPE III
284 MOV #0,S ; init OPCODE=0
285 MOV &DDP,T ; T=OPCODEADR
286 ADD #2,&DDP ; make room for opcode
287 ; ----------------------------------;
288 PARAM2 mDOCOL ; parse input buffer until BL and compute this 2th operand
289 .word FBLANK,SKIP ; skip space(s) between "arg1," and "arg2" if any; use not S,T.
290 .word $+2 ; -- c-addr search for '&' of "&xxxx
292 MOV #20h,TOS ; -- ' ' as WORD separator to find xxxx of ",&xxxx"
293 JNE PARAM21 ; '&' not found
295 PARAM20 ADD #0082h,S ; change OPCODE : AD=1, dst = R2
296 JMP PARAM111 ; -- ' '
297 ; ----------------------------------;
298 ; case of ",REG"|",xxxx(REG) ; -- ' ' first, search REG of ",REG"
299 PARAM21 CALL #SearchREG ;
300 JNZ PARAM124 ; -- 000R REG of ",REG" found
301 ; case of ",xxxx(REG) ; -- addr REG not found
302 PARAM210 ADD #0080h,S ; set AD=1
303 CALL #ComputeARGparenREG; compile argument xxxx and search REG of "(REG)"
304 JMP PARAM124 ; -- 000R REG of "(REG) found
306 ; ----------------------------------------------------------------------
307 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODE TYPE 0 : zero operand f:-)
308 ; ----------------------------------------------------------------------
311 .word lit,1300h,COMMA,EXIT
313 ; ----------------------------------------------------------------------
314 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODES TYPE I : double operand
315 ; ----------------------------------------------------------------------
317 ; OPCODE(code) for TYPE I = 0bxxxx opcode I
319 ; = 0bxxxx src register
320 ; OPCODE(7) AD (dst addr type)
324 ; OPCODE(B) for TYPE I or TYPE II = 0b0 word
326 ; OPCODE(54) AS (src addr type)
327 ; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
332 ; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
333 ; ----------------------------------------------------------------------
335 ; TYPE1DOES -- BODYDOES search and compute PARAM1 & PARAM2 as src and dst operands then compile instruction
336 TYPE1DOES .word lit,',',PARAM1 ; -- BODYDOES
337 .word PARAM2 ; -- BODYDOES char separator (BL) included in PARAM2
339 MAKEOPCODE MOV T,X ; -- opcode X= OPCODEADR to compile opcode
340 MOV @TOS,TOS ; -- opcode part of instruction
341 BIS S,TOS ; -- opcode opcode is complete
342 JMP StoreTOS ; -- then EXIT
346 .word TYPE1DOES,4000h
349 .word TYPE1DOES,4040h
352 .word TYPE1DOES,5000h
355 .word TYPE1DOES,5040h
358 .word TYPE1DOES,6000h
361 .word TYPE1DOES,6040h
364 .word TYPE1DOES,7000h
367 .word TYPE1DOES,7040h
370 .word TYPE1DOES,8000h
373 .word TYPE1DOES,8040h
376 .word TYPE1DOES,9000h
379 .word TYPE1DOES,9040h
382 .word TYPE1DOES,0A000h
385 .word TYPE1DOES,0A040h
388 .word TYPE1DOES,0B000h
391 .word TYPE1DOES,0B040h
394 .word TYPE1DOES,0C000h
397 .word TYPE1DOES,0C040h
400 .word TYPE1DOES,0D000h
403 .word TYPE1DOES,0D040h
406 .word TYPE1DOES,0E000h
409 .word TYPE1DOES,0E040h
412 .word TYPE1DOES,0F000h
415 .word TYPE1DOES,0F040h
417 ; ----------------------------------------------------------------------
418 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE II : single operand
419 ; ----------------------------------------------------------------------
420 ; OPCODE(FEDCBA987) opcodeII
421 ; OPCODE(code) for TYPE II = 0bxxxxxxxxx
423 ; OPCODE(B) for TYPE I or TYPE II = 0b0 word
425 ; OPCODE(54) (dst addr type)
426 ; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
431 ; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
432 ; ----------------------------------------------------------------------
434 TYPE2DOES .word FBLANK,PARAM1 ; -- BODYDOES
437 AND #0070h,S ; keep B/W & AS infos in OPCODE
438 SWPB W ; (REG org --> REG dst)
439 AND #000Fh,W ; keep REG
440 BIS_ASMTYPE BIS W,S ; -- BODYDOES add it in OPCODE
441 JMP MAKEOPCODE ; -- then end
443 asmword "RRC" ; Rotate Right through Carry ( word)
445 .word TYPE2DOES,1000h
446 asmword "RRC.B" ; Rotate Right through Carry ( byte)
448 .word TYPE2DOES,1040h
449 asmword "SWPB" ; Swap bytes
451 .word TYPE2DOES,1080h
454 .word TYPE2DOES,1100h
457 .word TYPE2DOES,1140h
460 .word TYPE2DOES,1180h
463 .word TYPE2DOES,1200h
466 .word TYPE2DOES,1240h
469 .word TYPE2DOES,1280h
471 BOUNDERRWM1 ADD #1,W ; <== RRAM|RRUM|RRCM|RLAM error
472 BOUNDERRORW MOV W,TOS ; <== PUSHM|POPM|ASM_branch error
473 BOUNDERROR ; <== REG number error
474 mDOCOL ; -- n n = value out of bounds
476 .byte 13,"out of bounds"
479 ; ----------------------------------------------------------------------
480 ; DTCforthMSP430FR5xxx ASSEMBLER, CONDITIONAL BRANCHS
481 ; ----------------------------------------------------------------------
482 ; ASSEMBLER FORTH OPCODE(FEDC)
483 ; OPCODE(code) for TYPE JNE,JNZ 0<>, <> = 0x20xx + (offset AND 3FF) ; branch if Z = 0
484 ; OPCODE(code) for TYPE JEQ,JZ 0=, = = 0x24xx + (offset AND 3FF) ; branch if Z = 1
485 ; OPCODE(code) for TYPE JNC,JLO U< = 0x28xx + (offset AND 3FF) ; branch if C = 0
486 ; OPCODE(code) for TYPE JC,JHS U>= = 0x2Cxx + (offset AND 3FF) ; branch if C = 1
487 ; OPCODE(code) for TYPE JN 0< = 0x30xx + (offset AND 3FF) ; branch if N = 1
488 ; OPCODE(code) for TYPE JGE >= = 0x34xx + (offset AND 3FF) ; branch if (N xor V) = 0
489 ; OPCODE(code) for TYPE JL < = 0x38xx + (offset AND 3FF) ; branch if (N xor V) = 1
490 ; OPCODE(code) for TYPE JMP = 0x3Cxx + (offset AND 3FF)
492 asmword "S>=" ; if >= assertion (opposite of jump if < )
496 asmword "S<" ; if < assertion
500 asmword "0>=" ; if 0>= assertion ; use only with IF UNTIL WHILE !
504 asmword "0<" ; jump if 0< ; use only with ?JMP ?GOTO !
508 asmword "U<" ; if U< assertion
512 asmword "U>=" ; if U>= assertion
516 asmword "0<>" ; if <>0 assertion
520 asmword "0=" ; if =0 assertion
524 ;ASM IF OPCODE -- @OPCODE1
527 MOV TOS,0(W) ; compile incomplete opcode
532 ;ASM THEN @OPCODE -- resolve forward branch
534 ASM_THEN MOV &DDP,W ; -- @OPCODE W=dst
535 MOV TOS,Y ; Y=@OPCODE
536 ASM_THEN1 MOV @PSP+,TOS ; --
538 ADD #2,X ; -- Y=@OPCODE W=dst X=src+2
539 SUB X,W ; -- Y=@OPCODE W=dst-src+2=displacement*2 (bytes)
540 RRA W ; -- Y=@OPCODE W=displacement (words)
542 JC BOUNDERRORW ; (JHS) unsigned branch if u> 511
543 BIS W,0(Y) ; -- [@OPCODE]=OPCODE completed
546 ;C ELSE @OPCODE1 -- @OPCODE2 branch for IF..ELSE
548 ASM_ELSE MOV &DDP,W ; -- W=HERE
549 MOV #3C00h,0(W) ; compile unconditionnal branch
550 ADD #2,&DDP ; -- DP+2
552 MOV W,0(PSP) ; -- @OPCODE2 @OPCODE1
553 JMP ASM_THEN ; -- @OPCODE2
555 ; BEGIN -- BEGINadr initialize backward branch
559 ;C UNTIL @BEGIN OPCODE -- resolve conditional backward branch
561 ASM_UNTIL MOV @PSP+,W ; -- OPCODE W=@BEGIN
562 ASM_UNTIL1 MOV TOS,Y ; Y=OPCODE W=@BEGIN
563 ASM_UNTIL2 MOV @PSP+,TOS ; --
564 MOV &DDP,X ; -- Y=OPCODE X=HERE W=dst
565 SUB #2,W ; -- Y=OPCODE X=HERE W=dst-2
566 SUB X,W ; -- Y=OPCODE X=src W=src-dst-2=displacement (bytes)
567 RRA W ; -- Y=OPCODE X=HERE W=displacement (words)
569 JL BOUNDERRORW ; signed branch if < -512
570 AND #3FFh,W ; -- Y=OPCODE X=HERE W=troncated negative displacement (words)
571 BIS W,Y ; -- Y=OPCODE (completed)
576 ;X AGAIN @BEGIN -- uncond'l backward branch
577 ; unconditional backward branch
579 ASM_AGAIN MOV TOS,W ; W=@BEGIN
580 MOV #3C00h,Y ; Y = asmcode JMP
583 ;C WHILE @BEGIN OPCODE -- @WHILE @BEGIN
585 ASM_WHILE mDOCOL ; -- @BEGIN OPCODE
586 .word ASM_IF,SWAP,EXIT
588 ;C REPEAT @WHILE @BEGIN -- resolve WHILE loop
590 ASM_REPEAT mDOCOL ; -- @WHILE @BEGIN
591 .word ASM_AGAIN,ASM_THEN,EXIT
593 ; ------------------------------------------------------------------------------------------
594 ; DTCforthMSP430FR5xxx ASSEMBLER : branch up to 3 backward labels and up to 3 forward labels
595 ; ------------------------------------------------------------------------------------------
596 ; used for non canonical branchs, as BASIC language: "goto line x"
597 ; labels BWx and FWx must be set at the beginning of line (>IN < 8).
598 ; FWx at the beginning of a line can resolve only one previous GOTO|?GOTO FWx.
599 ; BWx at the beginning of a line can be resolved by any subsequent GOTO|?GOTO BWx.
603 MOV TOS,Y ; -- PFA Y = ASMBWx addr
606 CMP #8,&TOIN ; are we colon 8 or more ?
607 BACKWUSE JC ASM_UNTIL1 ; yes, use this label
608 BACKWSET MOV &DDP,0(Y) ; no, set LABEL = DP
630 MOV @TOS,Y ; -- PFA Y=[ASMFWx]
631 CMP #8,&TOIN ; are we colon 8 or more ?
632 FORWUSE JNC ASM_THEN1 ; no: resolve FWx with W=DDP, Y=ASMFWx
633 FORWSET MOV @PSP+,0(W) ; yes compile incomplete opcode
634 ADD #2,&DDP ; increment DDP
635 MOV W,0(TOS) ; store @OPCODE into ASMFWx
655 ;ASM <cond> ?GOTO <label> OPCODE -- conditionnal branch to label
657 INVJMP CMP #3000h,TOS ; invert code jump process
658 JZ GOTONEXT ; case of JN, do nothing
659 XOR #0400h,TOS ; case of: JNZ<-->JZ JNC<-->JC JL<-->JGE
660 BIT #1000h,TOS ; 3xxxh case ?
662 XOR #0800h,TOS ; complementary action for JL<-->JGE
664 .word TICK ; -- OPCODE CFA<label>
667 ;ASM GOTO <label> -- unconditionnal branch to label
671 MOV #3C00h,TOS ; asmcode JMP
674 ; --------------------------------------------------------------------------------
675 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE III : PUSHM|POPM|RLAM|RRAM|RRUM|RRCM
676 ; --------------------------------------------------------------------------------
677 ; PUSHM, syntax: PUSHM #n,REG with 0 < n < 17
678 ; POPM syntax: POPM #n,REG with 0 < n < 17
681 ; PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
682 ; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
684 ; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
686 ; POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
687 ; POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
689 ; example : POPM #6,IP pulls Y,X,W,T,S,IP registers from return stack
691 ; RxxM syntax: RxxM #n,REG with 0 < n < 5
693 TYPE3DOES .word FBLANK,SKIP ; skip spaces if any
694 .word $+2 ; -- BODYDOES c-addr
695 ADD #1,&TOIN ; skip "#"
696 MOV #',',TOS ; -- BODYDOES ","
699 .word QFBRAN,NotFound ; ABORT
700 .word PARAM3 ; -- BODYDOES 0x000N S=OPCODE = 0x000R
702 MOV TOS,W ; -- BODYDOES n W = n
703 MOV @PSP+,TOS ; -- BODYDOES
704 SUB #1,W ; W = n floored to 0
706 MOV @TOS,X ; X=OPCODE
707 RLAM #4,X ; OPCODE bit 1000h --> C
708 JNC RxxMINSTRU ; if bit 1000h = 0
709 PxxxINSTRU MOV S,Y ; S=REG, Y=REG to test
710 RLAM #3,X ; OPCODE bit 0200h --> C
711 JNC PUSHMINSTRU ; W=n-1 Y=REG
712 POPMINSTRU SUB W,S ; to make POPM opcode, compute first REG to POP; TI is complicated....
713 PUSHMINSTRU SUB W,Y ; Y=REG-(n-1)
715 JC BOUNDERRWM1 ; JC=JHS (U>=)
716 RLAM #4,W ; W = n << 4
717 JMP BIS_ASMTYPE ; BODYDOES --
718 RxxMINSTRU CMP #4,W ;
719 JC BOUNDERRWM1 ; JC=JHS (U>=)
720 SWPB W ; -- BODYDOES W = n << 8
721 RLAM #2,W ; W = N << 10
722 JMP BIS_ASMTYPE ; BODYDOES --
726 .word TYPE3DOES,0050h
729 .word TYPE3DOES,0150h
732 .word TYPE3DOES,0250h
735 .word TYPE3DOES,0350h
738 .word TYPE3DOES,1500h
741 .word TYPE3DOES,1700h
745 .word TYPE3DOES,0040h
748 .word TYPE3DOES,0140h
751 .word TYPE3DOES,0240h
754 .word TYPE3DOES,0340h
757 .word TYPE3DOES,1400h
760 .word TYPE3DOES,1600h
762 ; --------------------------------------------------------------------------------
763 ; DTCforthMSP430FR5xxx ASSEMBLER: OPCODE TYPE III bis: CALLA (without extended word)
764 ; --------------------------------------------------------------------------------
765 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
766 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
767 ; --------------------------------------------------------------------------------
771 .word FBLANK,SKIP ; -- addr
774 ADD #2,&DDP ; make room for opcode
775 MOV.B @TOS,TOS ; -- char First char of opcode
776 CALLA0 MOV #134h,S ; 134h<<4 = 1340h = opcode for CALLA Rn
779 CALLA01 MOV.B #' ',TOS ;
780 CALLA02 CALL #SearchREG ; -- Rn
781 CALLA03 RLAM #4,S ; (opcode>>4)<<4 = opcode
782 BIS TOS,S ; update opcode
783 MOV S,0(T) ; store opcode
787 ;-----------------------------------;
788 CALLA1 ADD #2,S ; 136h<<4 = opcode for CALLA @REG
789 CMP.B #'@',TOS ; -- char Search @REG
791 ADD #1,&TOIN ; skip '@'
792 MOV.B #' ',TOS ; -- ' '
794 JNZ CALLA03 ; if REG found, update opcode
795 ;-----------------------------------;
796 ADD #1,S ; 137h<<4 = opcode for CALLA @REG+
797 MOV #'+',TOS ; -- '+'
799 ;-----------------------------------;
800 CALLA2 ADD #2,&DDP ; make room for xxxx of #$x.xxxx|&$x.xxxx|$0.xxxx(REG)
803 MOV #13Bh,S ; 13Bh<<4 = opcode for CALLA #$x.xxxx
804 CALLA21 ADD #1,&TOIN ; skip '#'|'&'
805 CALLA22 CALL #SearchARG ; -- Lo Hi
806 MOV @PSP+,2(T) ; -- Hi store #$xxxx|&$xxxx
807 JMP CALLA03 ; update opcode with $x. and store opcode
808 ;-----------------------------------;
809 CALLA3 CMP.B #'&',TOS
811 ADD #2,S ; 138h<<4 = opcode for CALLA &$x.xxxx
813 ;-----------------------------------;
814 CALLA4 MOV.B #'(',TOS ; -- "("
815 SUB #1,S ; 135h<<4 = opcode for CALLA $0.xxxx(REG)
816 CALLA41 CALL #SearchARG ; -- Lo Hi
817 MOV @PSP+,2(T) ; -- Hi store $xxxx
818 MOV #')',TOS ; -- ')'
819 JMP CALLA02 ; search Rn and update opcode
822 ; ===============================================================
823 ; to allow data access beyond $FFFF
824 ; ===============================================================
826 ; MOVA (#$x.xxxx|&$x.xxxx|$.xxxx(Rs)|Rs|@Rs|@Rs+ , &|Rd|$.xxxx(Rd))
827 ; ADDA (#$x.xxxx|Rs , Rd)
828 ; CMPA (#$x.xxxx|Rs , Rd)
829 ; SUBA (#$x.xxxx|Rs , Rd)
831 ; first argument process ACMS1
832 ;-----------------------------------;
833 ACMS1 mDOCOL ; -- BODYDOES ','
834 .word FBLANK,SKIP ; -- BODYDOES ',' addr
836 MOV.B @TOS,X ; X=first char of opcode string
837 MOV @PSP+,TOS ; -- BODYDOES ','
838 MOV @PSP+,S ; -- ',' S=BODYDOES
841 ADD #2,&DDP ; make room for opcode
842 ;-----------------------------------;
843 ACMS10 CMP.B #'R',X ; -- ','
845 ACMS101 CALL #SearchREG ; -- Rn src
846 ACMS102 RLAM #4,TOS ; 8<<src
848 ACMS103 BIS S,TOS ; update opcode with src|dst
849 MOV TOS,0(T) ; save opcode
850 MOV T,TOS ; -- OPCODE_addr
853 ;-----------------------------------;
854 ACMS11 CMP.B #'#',X ; -- ',' X=addr
856 BIC #40h,S ; set #opcode
857 ACMS111 ADD #1,&TOIN ; skip '#'|'&'
858 ADD #2,&DDP ; make room for low #$xxxx|&$xxxx|$xxxx(REG)
859 CALL #SearchARG ; -- Lo Hi
860 MOV @PSP+,2(T) ; -- Hi store $xxxx of #$x.xxxx|&$x.xxxx|$x.xxxx(REG)
861 AND #0Fh,TOS ; -- Hi sel Hi src
863 ;-----------------------------------;
864 MOVA12 CMP.B #'&',X ; -- ',' case of MOVA &$x.xxxx
866 XOR #00E0h,S ; set MOVA &$x.xxxx, opcode
868 ;-----------------------------------;
869 MOVA13 BIC #00F0h,S ; set MOVA @REG, opcode
870 CMP.B #'@',X ; -- ','
872 ADD #1,&TOIN ; skip '@'
873 CALL #SearchREG ; -- Rn
874 JNZ ACMS102 ; if @REG found
875 ;-----------------------------------;
876 BIS #0010h,S ; set @REG+ opcode
877 MOV #'+',TOS ; -- '+'
878 MOVA131 CALL #SearchREG ; -- Rn case of MOVA @REG+,|MOVA $x.xxxx(REG),
879 CMP &SOURCE_LEN,&TOIN ; test TYPE II first parameter ending by @REG+ (REG) without comma,
880 JZ ACMS102 ; i.e. may be >IN = SOURCE_LEN: don't skip char CR !
881 ADD #1,&TOIN ; skip "," ready for the second operand search
883 ;-----------------------------------;
884 MOVA14 BIS #0030h,S ; set xxxx(REG), opcode
885 ADD #2,&DDP ; -- ',' make room for first $xxxx of $0.xxxx(REG),
886 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
887 CALL #SearchARG ; -- Lo Hi
888 MOV @PSP+,2(T) ; -- Hi store $xxxx as 2th word
889 MOV #')',TOS ; -- ')'
892 ; 2th argument process ACMS2
893 ;-----------------------------------;
894 ACMS2 mDOCOL ; -- OPCODE_addr
895 .word FBLANK,SKIP ; -- OPCODE_addr addr
897 MOV @PSP+,T ; -- addr T=OPCODE_addr
899 MOV.B @TOS,X ; -- addr X=first char of string instruction
900 MOV.B #' ',TOS ; -- ' '
901 ;-----------------------------------;
902 ACMS21 CMP.B #'R',X ; -- ' '
904 ACMS211 CALL #SearchREG ; -- Rn
906 ;-----------------------------------;
908 ADD #2,&DDP ; -- ' ' make room for $xxxx
911 BIS #060h,S ; set ,&$x.xxxx opcode
912 ADD #1,&TOIN ; skip '&'
913 CALL #SearchARG ; -- Lo Hi
914 MOV @PSP+,2(T) ; -- Hi store $xxxx as 2th word
915 JMP ACMS103 ; update opcode with dst $x and write opcode
916 ;-----------------------------------;
917 MOVA23 BIS #070h,S ; set ,xxxx(REG) opcode
918 MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
919 CALL #SearchARG ; -- Lo Hi
920 MOV @PSP+,2(T) ; -- Hi write $xxxx of ,$0.xxxx(REG) as 2th word
921 MOV #')',TOS ; -- ")" as WORD separator to find REG of "xxxx(REG),"
924 ; --------------------------------------------------------------------------------
925 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES IV 2 operands: Adda|Cmpa|Mova|Suba (without extended word)
926 ; --------------------------------------------------------------------------------
927 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
928 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
929 ; --------------------------------------------------------------------------------
931 TYPE4DOES .word lit,',' ; -- BODYDOES "," char separator for PARAM1
932 .word ACMS1 ; -- OPCODE_addr
933 .word ACMS2 ; -- OPCODE_addr
938 .word TYPE4DOES,00C0h
941 .word TYPE4DOES,00D0h
944 .word TYPE4DOES,00E0h
947 .word TYPE4DOES,00F0h
950 ; PRMX1 is used for OPCODES type V (double operand) and OPCODES type VI (single operand) extended instructions
952 PRMX1 mDOCOL ; -- sep OPCODES type V|VI separator = ','|' '
953 .word FBLANK,SKIP ; -- sep addr
955 MOV.B @TOS,X ; -- sep addr X= first char of opcode string
956 MOV @PSP+,TOS ; -- sep
957 MOV #1800h,S ; init S=Extended word
958 ;-----------------------------------;
959 PRMX10 CMP.B #'R',X ; -- sep
961 PRMX101 CALL #SearchREG ; -- Rn Rn of REG; call SearchREG only to update >IN
962 PRMX102 MOV S,TOS ; -- EW update Extended word
964 MOV @IP+,PC ; -- Ext_Word
965 ;-----------------------------------;
966 PRMX11 MOV #0,&RPT_WORD ; clear RPT
967 CMP.B #'#',X ; -- sep
969 PRMX111 ADD #1,&TOIN ; -- sep skip '#'
970 PRMX112 CALL #SearchARG ; -- Lo Hi search $x.xxxx of #x.xxxx,
971 ADD #2,PSP ; -- Hi pop unused low word
972 PRMX113 AND #0Fh,TOS ;
974 RLAM #4,TOS ; -- 7<<Hi
975 PRMX115 BIS TOS,S ; update extended word with srcHi
977 ;-----------------------------------;
978 PRMX12 CMP.B #'&',X ; -- sep
980 ;-----------------------------------;
981 PRMX13 CMP.B #'@',X ; -- sep
983 PRMX131 ADD #1,&TOIN ; -- sep skip '@'
984 PRMX132 CALL #SearchREG ; -- Rn Rn of @REG,
985 JNZ PRMX102 ; if Rn found
986 ;-----------------------------------;
987 MOV #'+',TOS ; -- '+'
988 PRMX133 ADD #1,&TOIN ; skip '@'
989 CALL #SearchREG ; -- Rn Rn of @REG+,
990 PRMX134 CMP &SOURCE_LEN,&TOIN ; test case of TYPE VI first parameter without ','
991 JZ PRMX102 ; don't take the risk of skipping CR !
992 ADD #1,&TOIN ; skip ',' ready to search 2th operand
994 ;-----------------------------------;
995 PRMX14 MOV #'(',TOS ; -- '(' to find $x.xxxx of "x.xxxx(REG),"
996 CALL #SearchARG ; -- Lo Hi
997 MOV TOS,0(PSP) ; -- Hi Hi
998 PRMX141 MOV #')',TOS ; -- Hi ')'
999 CALL #SearchREG ; -- Hi Rn
1000 MOV @PSP+,TOS ; -- Hi
1004 ;-----------------------------------;
1006 ; PRMX2 is used for OPCODES type V (double operand) extended instructions
1008 ;-----------------------------------;
1009 PRMX2 mDOCOL ; -- Extended_Word
1010 .word FBLANK,SKIP ; -- Extended_Word addr
1012 MOV @PSP+,S ; -- addr S=Extended_Word
1013 MOV.B @TOS,X ; -- addr X=first char of code instruction
1014 MOV #' ',TOS ; -- ' '
1015 ;-----------------------------------;
1016 PRMX20 CMP.B #'R',X ; -- ' '
1017 JZ PRMX102 ; extended word not to be updated
1018 ;-----------------------------------;
1019 PRMX21 MOV #0,&RPT_WORD ;
1022 PRMX211 ADD #1,&TOIN ; -- ' ' skip '&'
1023 PRMX212 CALL #SearchARG ; -- Lo Hi
1024 PRMX213 ADD #2,PSP ; -- hi pop low word
1025 AND #0Fh,TOS ; -- Hi
1026 JMP PRMX115 ; update Extended word with dst_Hi
1027 ;-----------------------------------;
1028 PRMX22 MOV #'(',TOS ; -- '(' as WORD separator to find xxxx of "xxxx(REG)"
1029 CALL #SearchARG ; -- Lo Hi search x.xxxx of x.xxxx(REG)
1032 ;; UPDATE_eXtendedWord
1033 ;;-----------------------------------;
1034 ;UPDATE_XW ; BODYDOES Extended_Word -- BODYDOES+2 >IN R--
1036 ; ADD #2,&DDP ; make room for extended word
1037 ; MOV TOS,S ; S = Extended_Word
1038 ; MOV @PSP+,TOS ; -- BODYDOES
1039 ; BIS &RPT_WORD,S ; update Extended_word with RPT_WORD
1040 ; MOV #0,&RPT_WORD ; clear RPT before next instruction
1041 ; BIS @TOS+,S ; -- BODYDOES+2 update Extended_word with [BODYDOES] = A/L bit
1042 ; MOV S,0(T) ; store extended word
1043 ; MOV @RSP+,&TOIN ; >IN R-- restore >IN at the start of instruction string
1045 ;;-----------------------------------;
1047 ;-----------------------------------;
1048 ; UPDATE_eXtendedWord
1049 ;-----------------------------------;
1050 UPDATE_XW ; BODYDOES >IN Extended_Word -- BODYDOES+2
1051 MOV @PSP+,&TOIN ; -- BODYDOES EW restore >IN at the start of instruction string
1053 ADD #2,&DDP ; make room for extended word
1054 MOV TOS,S ; S = Extended_Word
1056 BIS &RPT_WORD,S ; update Extended_word with RPT_WORD
1057 MOV #0,&RPT_WORD ; clear RPT before next instruction
1058 BIS @TOS+,S ; -- BODYDOES+2 update Extended_word with [BODYDOES] = A/L bit
1059 MOV S,0(T) ; store extended word
1061 ;-----------------------------------;
1063 ; --------------------------------------------------------------------------------
1064 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES V extended double operand
1065 ; --------------------------------------------------------------------------------
1066 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
1067 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
1068 ; --------------------------------------------------------------------------------
1071 ; these instructions below are processed in two pass:
1072 ; pass 1: extended word process by TYPE5DOES with [BODYDOES] value
1073 ; pass 2: instruction process by TYPE1DOES with [BODYDOES+2] value
1074 ; all numeric arguments must be written as DOUBLE numbers (including a point) : $x.xxxx
1076 TYPE5DOES ; -- BODYDOES
1077 ; .word LIT,TOIN,FETCH,TOR ; R-- >IN save >IN for 2th pass
1078 ; .word lit,',' ; -- BODYDOES ',' char separator for PRMX1
1079 ; .word PRMX1,PRMX2 ; -- BODYDOES Extended_Word
1080 ; .word UPDATE_XW ; -- BODYDOES+2 >IN is restored ready for 2th pass
1081 ; .word BRAN,TYPE1DOES ; -- BODYDOES+2 2th pass: completes instruction with opcode = [BODYDOES+2]
1082 .word LIT,TOIN,FETCH ; -- BODYDOES >IN
1083 .word lit,',' ; -- BODYDOES >IN ',' char separator for PRMX1
1084 .word PRMX1,PRMX2 ; -- BODYDOES >IN Extended_Word
1085 .word UPDATE_XW ; -- BODYDOES+2 >IN is restored ready for 2th pass
1086 .word BRAN,TYPE1DOES ; -- BODYDOES+2 2th pass: completes instruction with opcode = [BODYDOES+2]
1090 .word TYPE5DOES ; [PFADOES] = TYPE5DOES
1091 .word 40h ; [BODYDOES] = A/L bit
1092 .word 4000h ; [BODYDOES+2] = OPCODE
1095 .word TYPE5DOES,0,4040h
1098 .word TYPE5DOES,40h,4040h
1101 .word TYPE5DOES,40h,5000h
1104 .word TYPE5DOES,0,5040h
1107 .word TYPE5DOES,40h,5040h
1110 .word TYPE5DOES,40h,6000h
1113 .word TYPE5DOES,0,6040h
1116 .word TYPE5DOES,40h,6040h
1119 .word TYPE5DOES,40h,7000h
1122 .word TYPE5DOES,0,7040h
1125 .word TYPE5DOES,40h,7040h
1128 .word TYPE5DOES,40h,8000h
1131 .word TYPE5DOES,0,8040h
1134 .word TYPE5DOES,40h,8040h
1137 .word TYPE5DOES,40h,9000h
1140 .word TYPE5DOES,0,9040h
1143 .word TYPE5DOES,40h,9040h
1146 .word TYPE5DOES,40h,0A000h
1149 .word TYPE5DOES,0,0A040h
1152 .word TYPE5DOES,40h,0A040h
1155 .word TYPE5DOES,40h,0B000h
1158 .word TYPE5DOES,0,0B040h
1161 .word TYPE5DOES,40h,0B040h
1164 .word TYPE5DOES,40h,0C000h
1167 .word TYPE5DOES,0,0C040h
1170 .word TYPE5DOES,40h,0C040h
1173 .word TYPE5DOES,40h,0D000h
1176 .word TYPE5DOES,0,0D040h
1179 .word TYPE5DOES,40h,0D040h
1182 .word TYPE5DOES,40h,0E000h
1185 .word TYPE5DOES,0,0E040h
1188 .word TYPE5DOES,40h,0E040h
1191 .word TYPE5DOES,40h,0F000h
1194 .word TYPE5DOES,0,0F040h
1197 .word TYPE5DOES,40h,0F040h
1199 ; --------------------------------------------------------------------------------
1200 ; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES VI extended single operand (take count of RPT)
1201 ; --------------------------------------------------------------------------------
1202 ; absolute and immediate instructions must be written as $x.xxxx (DOUBLE numbers)
1203 ; indexed instructions must be written as $.xxxx(REG) (DOUBLE numbers)
1204 ; --------------------------------------------------------------------------------
1206 ; these instructions below are processed in two pass:
1207 ; pass 1: extended word process by TYPE6DOES with [BODYDOES] value
1208 ; pass 2: instruction process by TYPE2DOES with [BODYDOES+2] value
1209 ; all numeric arguments must be written as DOUBLE numbers (including a point) : $x.xxxx
1211 TYPE6DOES ; -- BODYDOES
1212 ; .word LIT,TOIN,FETCH,TOR ; R-- >IN save >IN for 2th pass
1213 ; .word FBLANK ; -- BODYDOES ' '
1214 ; .word PRMX1 ; -- BODYDOES Extended_Word
1215 ; .word UPDATE_XW ; -- BODYDOES+2
1216 ; .word BRAN,TYPE2DOES ; -- BODYDOES+2 pass 2: completes instruction with opcode = [BODYDOES+2]
1217 .word LIT,TOIN,FETCH ; -- BODYDOES >IN
1218 .word FBLANK ; -- BODYDOES >IN ' '
1219 .word PRMX1 ; -- BODYDOES >IN Extended_Word
1220 .word UPDATE_XW ; -- BODYDOES+2
1221 .word BRAN,TYPE2DOES ; -- BODYDOES+2 pass 2: completes instruction with opcode = [BODYDOES+2]
1223 asmword "RRCX" ; ZC=0; RRCX Rx,Rx may be repeated by prefix RPT #n|Rn
1225 .word TYPE6DOES,40h,1000h
1226 asmword "RRCX.A" ; ZC=0; RRCX.A Rx may be repeated by prefix RPT #n|Rn
1228 .word TYPE6DOES,0,1040h
1229 asmword "RRCX.B" ; ZC=0; RRCX.B Rx may be repeated by prefix RPT #n|Rn
1231 .word TYPE6DOES,40h,1040h
1232 asmword "RRUX" ; ZC=1; RRUX Rx may be repeated by prefix RPT #n|Rn
1234 .word TYPE6DOES,140h,1000h
1235 asmword "RRUX.A" ; ZC=1; RRUX.A Rx may be repeated by prefix RPT #n|Rn
1237 .word TYPE6DOES,100h,1040h
1238 asmword "RRUX.B" ; ZC=1; RRUX.B Rx may be repeated by prefix RPT #n|Rn
1240 .word TYPE6DOES,140h,1040h
1243 .word TYPE6DOES,40h,1080h
1246 .word TYPE6DOES,0,1080h
1249 .word TYPE6DOES,40h,1100h
1252 .word TYPE6DOES,0,1140h
1255 .word TYPE6DOES,40h,1140h
1258 .word TYPE6DOES,40h,1180h
1261 .word TYPE6DOES,0,1180h
1264 .word TYPE6DOES,40h,1200h
1267 .word TYPE6DOES,0,1240h
1270 .word TYPE6DOES,40h,1240h
1272 ; ----------------------------------------------------------------------
1273 ; DTCforthMSP430FR5xxx ASSEMBLER, RPT instruction before REG|REG,REG eXtended instructions
1274 ; ----------------------------------------------------------------------
1275 ; RPT #1 is coded 0 in repetition count field (count n-1)
1276 ; please note that "RPT Rn" with [Rn]=0 has same effect as "RPT #1"
1280 asmword "RPT" ; RPT #n | RPT Rn repeat n | [Rn]+1 times modulo 16
1285 MOV.B #' ',TOS ; -- ' ' as separator
1288 CALL #SearchREG ; -- Rn
1289 JZ RPT1 ; if not found
1290 BIS #80h,TOS ; -- $008R R=Rn
1292 RPT1 CALL #SearchARG ; -- $xxxx
1294 AND #0Fh,TOS ; -- $000x
1295 RPT2 MOV TOS,&RPT_WORD