-
Notifications
You must be signed in to change notification settings - Fork 6
/
faddsub.asm
182 lines (173 loc) · 3.04 KB
/
faddsub.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
; Add two positive floating-point numbers
; In: HL,DE numbers to add
; Out: HL = sum HL + DE
; Pollutes: AF,DE
FADDP: CALL FCPP
JR NC,FADDPX
EX DE,HL
; Continue with FADDPX
; Add two positive floating-point numbers
; In: HL,DE numbers to add, HL >= DE
; Out: HL = sum HL + DE
; Pollutes: AF,DE
FADDPX: LD A,H
SUB D
JR Z,FADD0 ; same magnitude, cleared C flag
CP 10
RET NC ; magnitude too different, just return the bigger number
RR E
DEC A
JR Z,FADDLE
FADDL: SRL E
DEC A
JR NZ,FADDL
FADDLE: LD A,L
ADC A,E ; rounding
LD L,A
RET NC
SRL A
FADD1: ADC A,0 ; rounding
LD L,A
FADD2: INC H
BIT 7,H ; check overflow
RET Z
FINFTY: LD HL,MAXF ; positive maxfloat
RET
FADD0: LD A,L
ADD A,E
RRA
JR FADD1
; Round towards zero
; In: HL any floating-point number
; Out: HL same number rounded towards zero
; Pollutes: AF,B
FINT: LD A,H
AND $7F
SUB $40
JR C,FZERO ; Completely fractional
FINT2: SUB 8
RET NC ; Already integer
NEG
AND 7
JR Z,FINT0
LD B,A
LD A,$FF
FINTL: ADD A,A
DJNZ FINTL
AND L
FINT0: LD L,A
RET
FZERO: LD HL,MINF
RET
; Fractional part, remainder after division by 1
; In: HL any floating-point number
; Out: HL fractional part, with sign intact
; Pollutes: AF,AF',BC,DE
FRAC: LD A,H
AND $7F
SUB $40
RET C ; Pure fraction
PUSH HL
CALL FINT2
EX DE,HL
POP HL
JR FSUB
; Remainder after division
; In: BC dividend, HL modulus
; Out: HL remainder
; Pollutes: AF,AF',BC,DE
FMOD: PUSH BC ; Stack: dividend
PUSH HL ; Stack: dividend, modulus
CALL FDIV
CALL FINT ; integer ratio
EX DE,HL ; DE = int(BC/HL)
POP BC ; Stack: dividend; BC = modulus
CALL FMUL ; Stack: dividend
EX DE,HL
POP HL
; continue with FSUB
; Subtract two floating-point numbers
; In: HL,DE numbers to subtract, no restrictions
; Out: HL = difference HL - DE
; Pollutes: AF,AF',BC,DE
FSUB: LD A,D
XOR $80
LD D,A ; DE = -DE
; continue with FADD
; Add two floating-point numbers
; In: HL,DE numbers to add, no restrictions
; Out: HL = sum HL + DE
; Pollutes: AF,AF',BC,DE
FADD: LD B,H
LD C,D
LD A,B
XOR C
ADD A,A
EX AF,AF'
RES 7,H
RES 7,D
CALL FCPP
JR NC,FADDNS ; no swap
EX DE,HL
LD B,C
FADDNS: EX AF,AF'
JR C,FADDS
CALL FADDPX
JR FADDHB
FADDS: CALL FSUBP
FADDHB: LD A,B
AND $80
OR H
LD H,A
RET
; Compare two positive floating point numbers
; In: HL,DE numbers to compare
; Out: C flag if DE>HL, Z flag if DE=HL
; Pollutes: A
FCPP: LD A,H
CP D
RET NZ
LD A,L
CP E
RET
; Subtract two positive floating-point numbers
; In: HL,DE numbers to subtract, HL >= DE
; Out: HL = difference HL - DE
; Pollutes: AF,DE
FSUBP: LD A,H
SUB D
JR Z,FSUB0 ; same magnitude, cleared C flag
CP 10
RET NC ; magnitude too different, just return the bigger number
RR E
DEC A
JR Z,FSUBLE
FSUBL: SRL E
DEC A
JR NZ,FSUBL
FSUBLE: SBC A,A
LD D,A ; save C flag to D
LD A,L
SBC A,E ; rounding
LD L,A
JR C,FSUBN
RRC D ; restore C flag from D
RET NC
INC L
RET NZ
JP FADD2
FSUB0: LD A,L
SUB A,E
JR Z,FZERO2
LD D,0
FSUBN: RRC D ; restore C flag from D
FSUBL2: DEC H
BIT 7,H
JR NZ,FZERO2
ADC A,A
JR NC,FSUBL2
LD L,A
RET
; Return epsilon
FZERO2: LD HL,MINF
RET