OSDN Git Service

V161
[fast-forth/master.git] / ADDON / ARITHMETIC.asm
1 ; -*- coding: utf-8 -*-
2 ; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
3
4 ; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
5 ; Copyright (C) <2015>  <J.M. THOORENS>
6 ;
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.
11 ;
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.
16 ;
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/>.
19
20
21 ;https://forth-standard.org/standard/core/NIP
22 ;CE NIP    x1 x2 -- x2
23             FORTHWORD "NIP"
24 NIP         ADD     #2,PSP          ; 1
25             mNEXT                   ; 4
26
27 ;https://forth-standard.org/standard/core/StoD
28 ;C S>D    n -- d          single -> double prec.
29             FORTHWORD "S>D"
30 STOD:       SUB     #2,PSP
31             MOV     TOS,0(PSP)
32             JMP     ZEROLESS
33
34     .IFDEF MPY
35
36 ;https://forth-standard.org/standard/core/UMTimes
37 ;C UM*     u1 u2 -- ud   unsigned 16x16->32 mult.
38             FORTHWORD "UM*"
39 UMSTAR      MOV @PSP,&MPY       ; Load 1st operand
40             MOV TOS,&OP2        ; Load 2nd operand
41             MOV &RES0,0(PSP)    ; low result on stack
42             MOV &RES1,TOS       ; high result in TOS
43             mNEXT
44
45 ;https://forth-standard.org/standard/core/MTimes
46 ;C M*     n1 n2 -- dlo dhi  signed 16*16->32 multiply
47             FORTHWORD "M*"
48 MSTAR       MOV     @PSP,&MPYS
49             MOV     TOS,&OP2
50             MOV     &RES0,0(PSP)
51             MOV     &RES1,TOS
52             mNEXT
53
54     .ELSE
55
56 ;https://forth-standard.org/standard/core/MTimes
57 ;C M*     n1 n2 -- dlo dhi  signed 16*16->32 multiply
58             FORTHWORD "M*"
59 MSTAR:      MOV     TOS,S           ; TOS= n2
60             XOR     @PSP,S          ; S contains sign of result
61             CMP     #0,0(PSP)       ; n1 > -1 ?
62             JGE     u1MSTARn2       ; yes
63             XOR     #-1,0(PSP)      ; no : n1 --> u1
64             ADD     #1,0(PSP)       ;
65 u1MSTARn2   CMP     #0,TOS          ; n2 > -1 ?
66             JGE     u1MSTARu2       ; yes
67             XOR     #-1,TOS         ; no : n2 --> u2 
68             ADD     #1,TOS          ;
69 u1MSTARu2   
70            .word    151Dh           ; -- ud1lo ud1hi adr count          PUSHM IP,S (1+1 push,IP=D)
71             MOV     #MSTARud,IP
72             MOV     #UMSTAR,PC      ; UMSTAR use S,T,W,X,Y
73 MSTARud     FORTHtoASM
74            .word    171Ch           ; -- ud1lo ud1hi adr count          POPM S,IP (1+1 pop,S=C)
75             CMP     #0,S            ; result > -1 ?
76             JGE     MSTARend        ; yes
77             XOR     #-1,0(PSP)      ; no : ud --> d
78             XOR     #-1,TOS
79             ADD     #1,0(PSP)
80             ADDC    #0,TOS
81 MSTARend    mNEXT
82
83     .ENDIF ;MPY
84
85 ; TOS = DIVISOR
86 ; S   = DIVIDENDlo
87 ; W   = DIVIDENDhi
88 ; X   = count
89 ; Y   = QUOTIENT
90 ; T.I. UNSIGNED DIVISION SUBROUTINE 32-BIT BY 16-BIT
91 ; DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
92 ; RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
93
94 ;https://forth-standard.org/standard/core/UMDivMOD
95 ;C UM/MOD   udlo|udhi u1 -- r q   unsigned 32/16->16
96             FORTHWORD "UM/MOD"
97 UMSLASHMOD  MOV @PSP+,W     ;2 W = DIVIDENDhi
98             MOV @PSP,S      ;2 S = DIVIDENDlo
99             MOV #0,Y        ;1 CLEAR RESULT
100             MOV #16,X       ;2 INITIALIZE LOOP COUNTER
101 DIV1:       CMP TOS,W       ;1 dividendHI-divisor
102             JNC DIV2        ;2 jump if U<
103             SUB TOS,W       ;1
104 DIV2:       ADDC Y,Y        ;1 RLC quotient
105             SUB #1,X        ;1 Decrement loop counter
106             JN DIV3         ;2 If 0< --> end
107             ADD S,S         ;1 RLA
108             ADDC W,W        ;1 RLC
109             JNC DIV1        ;2 jump if U<   14~ loop
110             SUB TOS,W       ;1
111             BIS #1,SR       ;1 SETC
112             JMP DIV2        ;2              14~ loop
113 DIV3        MOV W,0(PSP)    ;3 remainder on stack
114             MOV Y,TOS       ;1 quotient in TOS
115             mNEXT           ;4 23 words  240 cycles
116
117 ;https://forth-standard.org/standard/core/SMDivREM
118 ;C SM/REM   d1lo d1hi n2 -- n3 n4  symmetric signed div
119             FORTHWORD "SM/REM"
120 SMSLASHREM  MOV TOS,S           ;1            S=divisor
121             MOV @PSP,T          ;2            T=rem_sign
122             CMP #0,TOS          ;1            n2 >= 0 ?
123             JGE d1u2SMSLASHREM  ;2            yes
124             XOR #-1,TOS         ;1
125             ADD #1,TOS          ;1
126 d1u2SMSLASHREM                  ;   -- d1 u2
127             CMP #0,0(PSP)       ;3           d1hi >= 0 ?
128             JGE ud1u2SMSLASHREM ;2           yes
129             XOR #-1,2(PSP)      ;4           d1lo
130             XOR #-1,0(PSP)      ;4           d1hi
131             ADD #1,2(PSP)       ;4           d1lo+1
132             ADDC #0,0(PSP)      ;4           d1hi+C
133 ud1u2SMSLASHREM                 ;   -- ud1 u2
134            .word 151Dh          ;4  -- ud1lo ud1hi adr count          PUSHM IP,S (1+1 push,IP=D)
135         MOV #SMSLASHREMu3u4,IP  ;2
136             JMP UMSLASHMOD      ;2 UM/MOD use S,W,X,Y, not T
137 SMSLASHREMu3u4
138             FORTHtoASM          ;240   -- u3 u4
139            .word 171Ch          ;4  -- ud1lo ud1hi adr count          POPM S,IP (1+1 pop,S=C)
140             CMP #0,T            ;1  -- u3 u4  T=rem_sign>=0?
141             JGE SMSLASHREMn3u4  ;2           yes
142             XOR #-1,0(PSP)      ;3
143             ADD #1,0(PSP)       ;3
144 SMSLASHREMn3u4
145             XOR S,T             ;1           S=divisor T=quot_sign
146             CMP #0,T            ;1  -- n3 u4  T=quot_sign>=0?
147             JGE SMSLASHREMn3n4  ;2           yes
148             XOR #-1,TOS         ;1
149             ADD #1,TOS          ;1
150 SMSLASHREMn3n4                  ;   -- n3 n4  S=divisor
151             mNEXT               ;4 36 words
152
153 ;https://forth-standard.org/standard/core/FMDivMOD
154 ;C FM/MOD   d1 n1 -- r q   floored signed div'n
155             FORTHWORD "FM/MOD"
156 FMSLASHMOD  PUSH    IP
157             MOV     #FMSLASHMOD1,IP
158             JMP     SMSLASHREM
159 FMSLASHMOD1 FORTHtoASM              ; -- remainder quotient       S=divisor
160             CMP     #0,0(PSP)       ;
161             JZ      FMSLASHMODEND
162             CMP     #1,TOS          ; quotient < 1 ?
163             JGE     FMSLASHMODEND   ;
164 QUOTLESSONE ADD     S,0(PSP)        ; add divisor to remainder
165             SUB     #1,TOS          ; decrement quotient
166 FMSLASHMODEND
167             MOV     @RSP+,IP
168             mNEXT                   ;
169
170 ;https://forth-standard.org/standard/core/Times
171 ;C *      n1 n2 -- n3       signed multiply
172             FORTHWORD "*"
173 STAR:       mDOCOL
174             .word   MSTAR,DROP,EXIT
175
176 ;https://forth-standard.org/standard/core/DivMOD
177 ;C /MOD   n1 n2 -- n3 n4    signed divide/rem'dr
178             FORTHWORD "/MOD"
179 SLASHMOD:   mDOCOL
180             .word   TOR,STOD,RFROM,FMSLASHMOD,EXIT
181
182 ;https://forth-standard.org/standard/core/Div
183 ;C /      n1 n2 -- n3       signed divide
184             FORTHWORD "/"
185 SLASH:      mDOCOL
186             .word   TOR,STOD,RFROM,FMSLASHMOD,NIP,EXIT
187
188 ;https://forth-standard.org/standard/core/MOD
189 ;C MOD    n1 n2 -- n3       signed remainder
190             FORTHWORD "MOD"
191 MODD:       mDOCOL
192             .word   TOR,STOD,RFROM,FMSLASHMOD,DROP,EXIT
193
194 ;https://forth-standard.org/standard/core/TimesDivMOD
195 ;C */MOD  n1 n2 n3 -- n4 n5    n1*n2/n3, rem&quot
196             FORTHWORD "*/MOD"
197 SSMOD:      mDOCOL
198             .word   TOR,MSTAR,RFROM,FMSLASHMOD,EXIT
199
200 ;https://forth-standard.org/standard/core/TimesDiv
201 ;C */     n1 n2 n3 -- n4        n1*n2/n3
202             FORTHWORD "*/"
203 STARSLASH   mDOCOL
204             .word   TOR,MSTAR,RFROM,FMSLASHMOD,NIP,EXIT
205
206
207