1 ; ----------------------------------------------------------------------------------
2 ; ANS complement for MSP430FR4xxx devices without hardware_MPY, to pass CORETEST.4th
3 ; ----------------------------------------------------------------------------------
6 \ R4 to R7 must be saved before use and restored after
7 \ scratch registers Y to S are free for use
8 \ under interrupt, IP is free for use
10 \ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
11 \ example : PUSHM IP,Y
13 \ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
16 \ ASSEMBLER conditionnal usage before IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
17 \ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
19 \ FORTH conditionnal usage before IF UNTIL WHILE : 0= 0< = < > U<
23 \ ECHO ; if an error occurs, uncomment this line before new download to find it.
26 CODE INVERT \ x1 -- x2 bitwise inversion
32 CODE LSHIFT \ x1 u -- x2 logical L shift u places
34 AND #$1F,TOS \ no need to shift more than 16
44 CODE RSHIFT \ x1 u -- x2 logical R shift u places
46 AND #$1F,TOS \ no need to shift more than 16
48 BEGIN BIC #C,SR \ Clr Carry
57 CODE 1+ \ n1/u1 -- n2/u2 add 1 to TOS
63 CODE 1- \ n1/u1 -- n2/u2 subtract 1 from TOS
69 CODE MAX \ n1 n2 -- n3 signed maximum
77 CODE MIN \ n1 n2 -- n3 signed minimum
85 CODE 2* \ x1 -- x2 arithmetic left shift
91 CODE 2/ \ x1 -- x2 arithmetic right shift
97 \ --------------------
98 \ ARITHMETIC OPERATORS
99 \ --------------------
101 CODE NIP \ a b c -- a c
107 : S>D \ n -- d single -> double
112 \ \ C UM* u1 u2 -- ud unsigned 16x16->32 mult.
115 \ \ u2 = TOS register
121 \ \ T.I. SIGNED MULTIPLY SUBROUTINE: u2 x u1 -> ud
122 \ MOV #0,Y \ 0 -> LSBs RESULT
123 \ MOV #0,T \ 0 -> MSBs RESULT
124 \ MOV #0,W \ 0 -> MSBs MULTIPLIER
125 \ MOV #1,X \ BIT TEST REGISTER
126 \ BEGIN BIT X,TOS \ 1 TEST ACTUAL BIT ; IF 0: DO NOTHING
127 \ 0<> IF \ 2 IF 1: ADD MULTIPLIER TO RESULT
130 \ THEN ADD S,S \ 1 (RLA LSBs) MULTIPLIER x 2
131 \ ADDC W,W \ 1 (RLC MSBs)
132 \ ADD X,X \ 1 (RLA) NEXT BIT TO TEST
133 \ U>= UNTIL \ 2 IF BIT IN CARRY: FINISHED 10~ loop
134 \ MOV Y,0(PSP) \ low result on stack
135 \ MOV T,TOS \ high result in TOS
140 CODE M* \ n1 n2 -- dlo dhi signed 16*16->32 multiply
142 XOR @PSP,S \ S contains sign of result
143 CMP #0,0(PSP) \ n1 > -1 ?
145 XOR #-1,0(PSP) \ n1 --> u1
148 CMP #0,TOS \ n2 > -1 ?
150 XOR #-1,TOS \ n2 --> u2
155 UM* \ UMSTAR use S,T,W,X,Y
158 CMP #0,S \ sign of result > -1 ?
160 XOR #-1,0(PSP) \ ud --> d
174 \ DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
175 \ RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
177 \ C UM/MOD udlo|udhi u1 -- ur uq
179 MOV @PSP+,W \ 2 W = DIVIDENDhi
180 MOV @PSP,S \ 2 S = DIVIDENDlo
181 MOV #16,X \ 2 INITIALIZE LOOP COUNTER
182 BW1 CMP TOS,W \ 1 dividendHI-divisor
183 U< ?GOTO FW1 \ 2 if not carry
184 SUB TOS,W \ 1 if carry
185 FW1 \ FW1 is resolved therefore reusable
186 BW2 ADDC Y,Y \ 1 RLC quotient
187 SUB #1,X \ 1 Decrement loop counter
188 0< ?GOTO FW1 \ 2 if 0< terminate
191 U< ?GOTO BW1 \ 2 if not carry 14~ loop
194 GOTO BW2 \ 2 14~ loop
195 FW1 MOV W,0(PSP) \ 3 remainder on stack
196 MOV Y,TOS \ 1 quotient in TOS
201 CODE SM/REM \ d1lo d1hi n2 -- n3 n4 symmetric signed div
202 MOV TOS,S \ S=divisor
203 MOV @PSP,T \ T=dividend_sign=rem_sign
204 CMP #0,TOS \ n2 >= 0 ?
207 ADD #1,TOS \ -- d1 u2
209 CMP #0,0(PSP) \ d1hi >= 0 ?
211 XOR #-1,2(PSP) \ d1lo
212 XOR #-1,0(PSP) \ d1hi
213 ADD #1,2(PSP) \ d1lo+1
214 ADDC #0,0(PSP) \ d1hi+C
218 UM/MOD \ UM/MOD use S,W,X,Y, not T
221 CMP #0,T \ T=rem_sign
226 XOR S,T \ S=divisor T=quot_sign
227 CMP #0,T \ T=quot_sign
231 THEN \ -- n3 n4 S=divisor
237 : FM/MOD \ d1 n1 -- n2 n3 floored signed div'n
239 HI2LO \ -- remainder quotient S=divisor
242 CMP #1,TOS \ quotient < 1 ?
244 ADD S,0(PSP) \ add divisor to remainder
245 SUB #1,TOS \ decrement quotient
253 : * \ n1 n2 -- n3 n1*n2 --> n3
258 : /MOD \ n1 n2 -- n3 n4 n1/n2 --> rem quot
263 : / \ n1 n2 -- n3 n1/n2 --> quot
264 >R DUP 0< R> FM/MOD NIP
268 : MOD \ n1 n2 -- n3 n1/n2 --> rem
269 >R DUP 0< R> FM/MOD DROP
273 : */MOD \ n1 n2 n3 -- n4 n5 n1*n2/n3 --> rem quot
278 : */ \ n1 n2 n3 -- n4 n1*n2/n3 --> quot
283 \ ----------------------------------------------------------------------
285 \ ----------------------------------------------------------------------
287 CODE 2@ \ a-addr -- x1 x2 fetch 2 cells \ the lower address will appear on top of stack
295 CODE 2! \ x1 x2 a-addr -- store 2 cells \ the top of stack is stored at the lower adr
303 CODE 2DUP \ x1 x2 -- x1 x2 x1 x2 dup top 2 cells
304 SUB #4,PSP \ -- x1 x x x2
305 MOV TOS,2(PSP) \ -- x1 x2 x x2
306 MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x2
311 CODE 2DROP \ x1 x2 -- drop 2 cells
318 CODE 2SWAP \ x1 x2 x3 x4 -- x3 x4 x1 x2
319 MOV @PSP,W \ -- x1 x2 x3 x4 W=x3
320 MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x4
321 MOV W,4(PSP) \ -- x3 x2 x1 x4
322 MOV TOS,W \ -- x3 x2 x1 x4 W=x4
323 MOV 2(PSP),TOS \ -- x3 x2 x1 x2 W=x4
324 MOV W,2(PSP) \ -- x3 x4 x1 x2
329 CODE 2OVER \ x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
330 SUB #4,PSP \ -- x1 x2 x3 x x x4
331 MOV TOS,2(PSP) \ -- x1 x2 x3 x4 x x4
332 MOV 8(PSP),0(PSP) \ -- x1 x2 x3 x4 x1 x4
333 MOV 6(PSP),TOS \ -- x1 x2 x3 x4 x1 x2
339 \ ----------------------------------------------------------------------
340 \ ALIGNMENT OPERATORS
341 \ ----------------------------------------------------------------------
343 CODE ALIGNED \ addr -- a-addr align given addr
350 CODE ALIGN \ -- align HERE
357 \ ---------------------
358 \ PORTABILITY OPERATORS
359 \ ---------------------
361 CODE CHARS \ n1 -- n2 chars->adrs units
366 CODE CHAR+ \ c-addr1 -- c-addr2 add char size
372 CODE CELLS \ n1 -- n2 cells->adrs units
378 CODE CELL+ \ a-addr1 -- a-addr2 add cell size
383 \ ---------------------------
384 \ BLOCK AND STRING COMPLEMENT
385 \ ---------------------------
387 : CHAR \ -- char parse ASCII character
392 : [CHAR] \ -- compile character literal
397 CODE +! \ n/u a-addr -- add to memory
405 CODE FILL \ c-addr u char -- fill memory with char
407 MOV @PSP+,W \ address
411 MOV.B TOS,0(W) \ store char in memory
416 MOV @PSP+,TOS \ empties stack
421 \ --------------------
422 \ INTERPRET COMPLEMENT
423 \ --------------------
441 : .( \ -- dotparen \ type comment immediatly.
442 \ CAPS_OFF \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
445 \ CAPS_ON \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
449 CODE SOURCE \ -- adr u current input buffer
453 MOV &SOURCE_ADR,0(PSP)
465 PWR_HERE ; to protect this app against a RESET, type: RST_HERE
467 ; added : INVERT LSHIFT RSHIFT 1+ 1- MAX MIN 2* 2/ CHAR [CHAR] +! FILL HEX DECIMAL ( .( SOURCE >BODY
468 ; added ARITHMETIC : NIP S>D M* UM/MOD SM/REM FM/MOD * /MOD / MOD */MOD */
469 ; added DOUBLE : 2@ 2! 2DUP 2DROP 2SWAP 2OVER
470 ; added ALIGMENT : ALIGNED ALIGN
471 ; added PORTABIITY : CHARS CHAR+ CELLS CELL+