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) <2015> <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/>.
26 ;C S>D n -- d single -> double prec.
34 ;C UM* u1 u2 -- ud unsigned 16x16->32 mult.
36 UMSTAR MOV @PSP,&MPY ; Load 1st operand
37 MOV TOS,&OP2 ; Load 2nd operand
38 MOV &RES0,0(PSP) ; low result on stack
39 MOV &RES1,TOS ; high result in TOS
42 ;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
52 ;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
54 MSTAR: MOV TOS,S ; TOS= n2
55 XOR @PSP,S ; S contains sign of result
56 CMP #0,0(PSP) ; n1 > -1 ?
58 XOR #-1,0(PSP) ; no : n1 --> u1
60 u1MSTARn2 CMP #0,TOS ; n2 > -1 ?
62 XOR #-1,TOS ; no : n2 --> u2
65 .word 151Dh ; -- ud1lo ud1hi adr count PUSHM IP,S (1+1 push,IP=D)
67 MOV #UMSTAR,PC ; UMSTAR use S,T,W,X,Y
69 .word 171Ch ; -- ud1lo ud1hi adr count POPM S,IP (1+1 pop,S=C)
70 CMP #0,S ; result > -1 ?
72 XOR #-1,0(PSP) ; no : ud --> d
85 ; T.I. UNSIGNED DIVISION SUBROUTINE 32-BIT BY 16-BIT
86 ; DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
87 ; RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
89 ;C UM/MOD udlo|udhi u1 -- r q unsigned 32/16->16
91 UMSLASHMOD MOV @PSP+,W ;2 W = DIVIDENDhi
92 MOV @PSP,S ;2 S = DIVIDENDlo
93 MOV #0,Y ;1 CLEAR RESULT
94 MOV #16,X ;2 INITIALIZE LOOP COUNTER
95 DIV1: CMP TOS,W ;1 dividendHI-divisor
96 JNC DIV2 ;2 jump if U<
98 DIV2: ADDC Y,Y ;1 RLC quotient
99 SUB #1,X ;1 Decrement loop counter
100 JN DIV3 ;2 If 0< --> end
103 JNC DIV1 ;2 jump if U< 14~ loop
107 DIV3 MOV W,0(PSP) ;3 remainder on stack
108 MOV Y,TOS ;1 quotient in TOS
109 mNEXT ;4 23 words 240 cycles
111 ;C SM/REM d1lo d1hi n2 -- n3 n4 symmetric signed div
113 SMSLASHREM MOV TOS,S ;1 S=divisor
114 MOV @PSP,T ;2 T=rem_sign
115 CMP #0,TOS ;1 n2 >= 0 ?
116 JGE d1u2SMSLASHREM ;2 yes
119 d1u2SMSLASHREM ; -- d1 u2
120 CMP #0,0(PSP) ;3 d1hi >= 0 ?
121 JGE ud1u2SMSLASHREM ;2 yes
122 XOR #-1,2(PSP) ;4 d1lo
123 XOR #-1,0(PSP) ;4 d1hi
124 ADD #1,2(PSP) ;4 d1lo+1
125 ADDC #0,0(PSP) ;4 d1hi+C
126 ud1u2SMSLASHREM ; -- ud1 u2
127 .word 151Dh ;4 -- ud1lo ud1hi adr count PUSHM IP,S (1+1 push,IP=D)
128 MOV #SMSLASHREMu3u4,IP ;2
129 JMP UMSLASHMOD ;2 UM/MOD use S,W,X,Y, not T
131 FORTHtoASM ;240 -- u3 u4
132 .word 171Ch ;4 -- ud1lo ud1hi adr count POPM S,IP (1+1 pop,S=C)
133 CMP #0,T ;1 -- u3 u4 T=rem_sign>=0?
134 JGE SMSLASHREMn3u4 ;2 yes
138 XOR S,T ;1 S=divisor T=quot_sign
139 CMP #0,T ;1 -- n3 u4 T=quot_sign>=0?
140 JGE SMSLASHREMn3n4 ;2 yes
143 SMSLASHREMn3n4 ; -- n3 n4 S=divisor
146 ;C FM/MOD d1 n1 -- r q floored signed div'n
151 FMSLASHMOD1 FORTHtoASM ; -- remainder quotient S=divisor
154 CMP #1,TOS ; quotient < 1 ?
156 QUOTLESSONE ADD S,0(PSP) ; add divisor to remainder
157 SUB #1,TOS ; decrement quotient
162 ;C * n1 n2 -- n3 signed multiply
165 .word MSTAR,DROP,EXIT
167 ;C /MOD n1 n2 -- n3 n4 signed divide/rem'dr
170 .word TOR,STOD,RFROM,FMSLASHMOD,EXIT
172 ;C / n1 n2 -- n3 signed divide
175 .word TOR,STOD,RFROM,FMSLASHMOD,NIP,EXIT
177 ;C MOD n1 n2 -- n3 signed remainder
180 .word TOR,STOD,RFROM,FMSLASHMOD,DROP,EXIT
182 ;C */MOD n1 n2 n3 -- n4 n5 n1*n2/n3, rem"
185 .word TOR,MSTAR,RFROM,FMSLASHMOD,EXIT
187 ;C */ n1 n2 n3 -- n4 n1*n2/n3
190 .word TOR,MSTAR,RFROM,FMSLASHMOD,NIP,EXIT