OSDN Git Service

raz
[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 ;X NIP    x1 x2 -- x2
22             FORTHWORD "NIP"
23 NIP         ADD     #2,PSP          ; 1
24             mNEXT                   ; 4
25
26 ;C S>D    n -- d          single -> double prec.
27             FORTHWORD "S>D"
28 STOD:       SUB     #2,PSP
29             MOV     TOS,0(PSP)
30             JMP     ZEROLESS
31
32     .IFDEF MPY
33
34 ;C UM*     u1 u2 -- ud   unsigned 16x16->32 mult.
35             FORTHWORD "UM*"
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
40             mNEXT
41
42 ;C M*     n1 n2 -- dlo dhi  signed 16*16->32 multiply
43             FORTHWORD "M*"
44 MSTAR       MOV     @PSP,&MPYS
45             MOV     TOS,&OP2
46             MOV     &RES0,0(PSP)
47             MOV     &RES1,TOS
48             mNEXT
49
50     .ELSE
51
52 ;C M*     n1 n2 -- dlo dhi  signed 16*16->32 multiply
53             FORTHWORD "M*"
54 MSTAR:      MOV     TOS,S           ; TOS= n2
55             XOR     @PSP,S          ; S contains sign of result
56             CMP     #0,0(PSP)       ; n1 > -1 ?
57             JGE     u1MSTARn2       ; yes
58             XOR     #-1,0(PSP)      ; no : n1 --> u1
59             ADD     #1,0(PSP)       ;
60 u1MSTARn2   CMP     #0,TOS          ; n2 > -1 ?
61             JGE     u1MSTARu2       ; yes
62             XOR     #-1,TOS         ; no : n2 --> u2 
63             ADD     #1,TOS          ;
64 u1MSTARu2   
65            .word    151Dh           ; -- ud1lo ud1hi adr count          PUSHM IP,S (1+1 push,IP=D)
66             MOV     #MSTARud,IP
67             MOV     #UMSTAR,PC      ; UMSTAR use S,T,W,X,Y
68 MSTARud     FORTHtoASM
69            .word    171Ch           ; -- ud1lo ud1hi adr count          POPM S,IP (1+1 pop,S=C)
70             CMP     #0,S            ; result > -1 ?
71             JGE     MSTARend        ; yes
72             XOR     #-1,0(PSP)      ; no : ud --> d
73             XOR     #-1,TOS
74             ADD     #1,0(PSP)
75             ADDC    #0,TOS
76 MSTARend    mNEXT
77
78     .ENDIF ;MPY
79
80 ; TOS = DIVISOR
81 ; S   = DIVIDENDlo
82 ; W   = DIVIDENDhi
83 ; X   = count
84 ; Y   = QUOTIENT
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
88
89 ;C UM/MOD   udlo|udhi u1 -- r q   unsigned 32/16->16
90             FORTHWORD "UM/MOD"
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<
97             SUB TOS,W       ;1
98 DIV2:       ADDC Y,Y        ;1 RLC quotient
99             SUB #1,X        ;1 Decrement loop counter
100             JN DIV3         ;2 If 0< --> end
101             ADD S,S         ;1 RLA
102             ADDC W,W        ;1 RLC
103             JNC DIV1        ;2 jump if U<   14~ loop
104             SUB TOS,W       ;1
105             BIS #1,SR       ;1 SETC
106             JMP DIV2        ;2              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
110
111 ;C SM/REM   d1lo d1hi n2 -- n3 n4  symmetric signed div
112             FORTHWORD "SM/REM"
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
117             XOR #-1,TOS         ;1
118             ADD #1,TOS          ;1
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
130 SMSLASHREMu3u4
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
135             XOR #-1,0(PSP)      ;3
136             ADD #1,0(PSP)       ;3
137 SMSLASHREMn3u4
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
141             XOR #-1,TOS         ;1
142             ADD #1,TOS          ;1
143 SMSLASHREMn3n4                  ;   -- n3 n4  S=divisor
144             mNEXT               ;4 36 words
145
146 ;C FM/MOD   d1 n1 -- r q   floored signed div'n
147             FORTHWORD "FM/MOD"
148 FMSLASHMOD  PUSH    IP
149             MOV     #FMSLASHMOD1,IP
150             JMP     SMSLASHREM
151 FMSLASHMOD1 FORTHtoASM              ; -- remainder quotient       S=divisor
152             CMP     #0,0(PSP)       ;
153             JZ      FMSLASHMODEND
154             CMP     #1,TOS          ; quotient < 1 ?
155             JGE     FMSLASHMODEND   ;
156 QUOTLESSONE ADD     S,0(PSP)        ; add divisor to remainder
157             SUB     #1,TOS          ; decrement quotient
158 FMSLASHMODEND
159             MOV     @RSP+,IP
160             mNEXT                   ;
161
162 ;C *      n1 n2 -- n3       signed multiply
163             FORTHWORD "*"
164 STAR:       mDOCOL
165             .word   MSTAR,DROP,EXIT
166
167 ;C /MOD   n1 n2 -- n3 n4    signed divide/rem'dr
168             FORTHWORD "/MOD"
169 SLASHMOD:   mDOCOL
170             .word   TOR,STOD,RFROM,FMSLASHMOD,EXIT
171
172 ;C /      n1 n2 -- n3       signed divide
173             FORTHWORD "/"
174 SLASH:      mDOCOL
175             .word   TOR,STOD,RFROM,FMSLASHMOD,NIP,EXIT
176
177 ;C MOD    n1 n2 -- n3       signed remainder
178             FORTHWORD "MOD"
179 MODD:       mDOCOL
180             .word   TOR,STOD,RFROM,FMSLASHMOD,DROP,EXIT
181
182 ;C */MOD  n1 n2 n3 -- n4 n5    n1*n2/n3, rem&quot
183             FORTHWORD "*/MOD"
184 SSMOD:      mDOCOL
185             .word   TOR,MSTAR,RFROM,FMSLASHMOD,EXIT
186
187 ;C */     n1 n2 n3 -- n4        n1*n2/n3
188             FORTHWORD "*/"
189 STARSLASH   mDOCOL
190             .word   TOR,MSTAR,RFROM,FMSLASHMOD,NIP,EXIT
191
192
193