Interface Age, November 1976, pages 103-111.

Floating Point Routines for the 6502* by Roy Rankin Department of Mechanical Engineering, Stanford University and Steve Wozniak Apple Computer Company *First appeared in Dr. DOBB's Journal of Computer Calisthenics & Orthodontia, Box 310, Menlo Park, CA 94025 The following floating point routines represent a joint effort between Steve Wozniak who wrote the basic floating point routines of FADD, FSUB, FMUL, FDIV and their support routines and myself, Roy Rankin, who added FIX, FLOAT, LOG, LOG10, and EXP. The basic floating point routines are failry Machine dependent, but the transcendental programs should be very easy to transport from one machine to another. The routines consist of the following math functions * * * * * * * * * LOG LOG10 EXP FADD FSUB FMUL FDIV FIX FLOAT Natural log Base 10 log Exponential Floating add Floating subtraction Floating multiplication Floating division Convert floating to fixed Convert fixed to floating

Two additional routines exchange the contents of exp/mant1 with exp/mant2 and compliments exp/ mant1. These routines are SWAP FCOMPL Exchange the contents of exp/mant 1 with exp/mant 2 Compliment exp/mant 1

Floating point numbers are represented by 4 bytes as shown in the following +- SIGN BIT +- SIGN BIT | 0 = + | 0 = + | 1 = | 1 = v v |S| |S| +- PRESUMED DECIMAL POINT |B| |B| v |_|_ _ _ _ _ _ _|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| |7 6 5 4 3 2 1 0|7 6.5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| | | | | | | BYTE N | BYTE N+1 | BYTE N+2 | BYTE N+3 | | | | | | | | MOST SIG BYTE | | LEAST SIG BYTE| | | MANTISSA | | MANTISSA |

| |<- EXPONENT | |<----

| ->|<---

| | THREE BYTE MANTISSA (TWOS COMPLEMENT REPRESENTATION) FOUR-BYTE FLOATING POINT OPERAND

| --->| | ---->|

The exponent byte is a binary scaling factor for the Mantissa. The exponent is a standard two's complement representation except that the sign bit is complemented and runs from +128 to +127. For example: $00 is -128 $01 is -127 * * $7F is -1 $80 is 0 $81 is -1 * * $FF is 127 The mantissa is standard two's complement representation with the sign bit in the most significant bit of the high order byte. The assumed decimal point is between bits 6 and 7 of the most significant byte. Thus the normalized mantissa ranges in absolute value from 1 to 2. Except when the exponent has a value of +128 the mantissa is normalized to retain maximum precision. The mantissa is normalized if the upper two bits of the high-order mantissa byte are unequal. Thus a normalized mantissa is of the following form: 01.xxxxxx positive mantissa (high byte) 10.xxxxxx negative mantissa (high byte) Assumed binary point Some sample floating point numbers in hex 83 80 7C 00 FC 7F 83 50 40 66 00 99 80 B0 00 00 66 00 99 00 00 00 00 66 00 9A 00 00 10. 1. .1 0. -.1 -1. -10.

The routines are all entered using a JSR instruction. Base page locations $004-$007 are referred to as exp/mant2 while $0008-000b are referred to as exp/ mant1 and act as floating point registers. On entry to the subroutines these registers contain the numbers to be operated upon and contain the result on return, The function of the registers is given before each entry point in the source listing. There are three error traps which will cause a software interrupts. ERROT (1D06) is encountered if the argument in the log routine is less than or equal to zero. OVFLW (1E3B) will be executed if the argument of EXP is too large. Overflow detected by

the basic floating point routines will cause OVFL (1FE4) to be executed. The routines do not give underflow errors, but set the number to zero if underflow occurs. Readers of Dr. Dobbs's journal should note that when these routines were published in that journal the math function LOG contained an error which prevented the correct result from being given if the argument was less than 1. This error has been correted in the present listing and marked with "MOD 9/76." 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 SIGN IN 20 WITH AN 21 HIGH-ORDER 22 EXCEPT 23 24 25 THE 26 SIGN 27 COMPARISON 28 INCREASING 29 (+127) 30 31 32 FLOATING 33 APPROXIMATE 34 SIGNIFICANT * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SEPTEMBER 11, 1976 BASIC FLOATING POINT ROUTINES FOR 6502 MICROPROCESSOR BY R. RANKIN AND S. WOZNIAK CONSISTING OF: NATURAL LOG COMMON LOG EXPONENTIAL (E**X) FLOAT FIX FADD FSUB FMUL FDIV FLOATING POINT REPRESENTATION (4-BYTES) EXPONENT BYTE 1 MANTISSA BYTES 2-4 MANTISSA: TWO'S COMPLIMENT REPRESENTATION WITH MANTISSA IS NORMALIZED

MSB OF HIGH-ORDER BYTE.

ASSUMED DECIMAL POINT BETWEEN BITS 5 AND 6 OF THE BYTE. THUS THE MANTISSA IS IN THE RANGE 1. TO 2.

WHEN THE NUMBER IS LESS THAN 2**(-128). EXPONENT: THE EXPONENT REPRESENTS POWERS OF TWO.

REPRESENTATION IS 2'S COMPLIMENT EXCEPT THAT THE BIT (BIT 7) IS COMPLIMENTED. THIS ALLOWS DIRECT

OF EXPONENTS FOR SIZE SINCE THEY ARE STORED IN NUMERICAL SEQUENCE RANGING FROM $00 (-128) TO $FF ($ MEANS NUMBER IS HEXADECIMAL). REPRESENTATION OF DECIMAL NUMBERS: THE PRESENT

POINT REPRESENTATION ALLOWS DECIMAL NUMBERS IN THE RANGE OF 10**(-38) THROUGH 10**(38) WITH 6 TO 7

35 36 37 38 0003 39 0003 40 0004 41 0005 42 0008 43 0009 44 000C 45 0010 46 0014 47 0018 48 001C 49 50 1D00 51 52 53 54 1D00 55 1D02 56 1D04 57 1D06 58 59 1D07 60 1D0A 61 1D0C 62 1D0E 63 1D10 64 1D12 EXPONENT 65 1D14 66 1D16 67 1D18 68 1D19 69 1D1B 70 1D1E 71 1D20 72 1D22 73 1D24 74 1D26 75 1D28 76 1D2B 77 1D2D 78 1D2E 79 1D30 80 1D33 81 1D35 82 1D37 83 1D39 84 1D3B 85 1D3D 86 1D40 87 1D42 88 1D43 89 1D45 90 1D48 91 1D4A

* * * EA EA 00 00 00 EA 00 00 00 SIGN X2 M2 X1 M1 E Z T SEXP INT * * * * LOG ERROR * CONT

DIGITS. ORG NOP NOP BSS NOP BSS BSS BSS BSS BSS BSS 3 3 3 4 4 4 4 1 SET BASE PAGE ADRESSES EXPONENT MANTISSA EXPONENT MANTISSA SCRATCH 2 2 1 1

00

ORG $1D00

STARTING LOCATION FOR LOG

NATURAL LOG OF MANT/EXP1 WITH RESULT IN MANT/EXP1 LDA M1 BEQ ERROR BPL CONT BRK JSR LDX LDA LDY STY EOR STA BPL DEX STX JSR LDX LDA STA LDA STA LDA STA DEX BPL JSR LDX LDA STA LDA STA LDA STA DEX BPL JSR LDX LDA SWAP =0 X2 =$80 X2 =$80 M1+1 *+3 M1 FLOAT =3 X2,X Z,X X1,X SEXP,X R22,X X1,X SEXP1 FSUB =3 X1,X T,X Z,X X1,X R22,X X2,X SAVET FADD =3 T,X

A5 09 F0 02 10 01 00 20 A2 A5 A0 84 49 85 10 CA 86 20 A2 B5 95 B5 95 BD 95 CA 10 20 A2 B5 95 B5 95 BD 95 CA 10 20 A2 B5 1C 1F 00 04 80 04 80 0A 01 09 2C 1F 03 04 10 08 18 D4 1D 08 F0 4A 1F 03 08 14 10 08 D4 1D 04 F0 50 1F 03 14

IF ARG>0 OK ERROR ARG<=0 MOVE ARG TO EXP/MANT2 MOD 9/76: LOAD X FOR LATER HOLD EXPONENT SET EXPONENT 2 TO 0 ($80) COMPLIMENT SIGN BIT OF ORIGINAL SET EXPONENT INTO MANTISSA 1 FOR FLOAT MOD 9/76: IS EXPONENT ZERO? MOD 9/76: YES SET X TO $FF MOD 9/76: SET UPPER BYTE OF EXPONENT CONVERT TO FLOATING POINT 4 BYTE TRANSFERS COPY MANTISSA TO Z SAVE EXPONENT IN SEXP LOAD EXP/MANT1 WITH SQRT(2)

SEXP1

SAVET

Z-SQRT(2) 4 BYTE TRANSFER SAVE EXP/MANT1 AS T LOAD EXP/MANT1 WITH Z LOAD EXP/MANT2 WITH SQRT(2)

Z+SQRT(2) 4 BYTE TRANSFER

TM2

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

1D4C 1D4E 1D4F 1D51 1D54 1D56 1D58 1D5A 1D5C 1D5D 1D5F 1D62 1D65 1D67 1D6A 1D6C 1D6D 1D6F 1D72 1D74 1D77 1D79 1D7A 1D7C 1D7F 1D81 1D84 1D86 1D87 1D89 1D8C 1D8E 1D90 1D92 1D93 1D95 1D98 1D9A 1D9D 1D9F 1DA0 1DA2 1DA5 1DA7 1DA9 1DAB 1DAC 1DAE 1DB1 1DB3 1DB6 1DB8 1DB9 1DBB 1DBE

95 CA 10 20 A2 B5 95 95 CA 10 20 20 A2 BD 95 CA 10 20 A2 BD 95 CA 10 20 A2 BD 95 CA 10 20 A2 B5 95 CA 10 20 A2 BD 95 CA 10 20 A2 B5 95 CA 10 20 A2 BD 95 CA 10 20 60

04 F9 9D 1F 03 08 14 04 F7 77 1F 1C 1F 03 E4 1D 08 F8 4A 1F 03 E0 1D 04 F8 9D 1F 03 DC 1D 04 F8 50 1F 03 14 04 F9 77 1F 03 E8 1D 04 F8 50 1F 03 18 04 F9 50 1F 03 D8 1D 04 F8 77 1F * * *

MIT

MIC

M2MB

M2A1

M2T

M2MHL

LDEXP

MLE2

STA DEX BPL JSR LDX LDA STA STA DEX BPL JSR JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR RTS

X2,X TM2 FDIV =3 X1,X T,X X2,X MIT FMUL SWAP =3 C,X X1,X MIC FSUB =3 MB,X X2,X M2MB FDIV =3 A1,X X2,X M2A1 FADD =3 T,X X2,X M2T FMUL =3 MHLF,X X2,X M2MHL FADD =3 SEXP,X X2,X LDEXP FADD =3 LE2,X X2,X MLE2 FMUL

LOAD T INTO EXP/MANT2 T=(Z-SQRT(2))/(Z+SQRT(2)) 4 BYTE TRANSFER COPY EXP/MANT1 TO T AND LOAD EXP/MANT2 WITH T T*T MOVE T*T TO EXP/MANT2 4 BYTE TRANSFER LOAD EXP/MANT1 WITH C T*T-C 4 BYTE TRANSFER LOAD EXP/MANT2 WITH MB MB/(T*T-C) LOAD EXP/MANT2 WITH A1 MB/(T*T-C)+A1 4 BYTE TRANSFER LOAD EXP/MANT2 WITH T (MB/(T*T-C)+A1)*T 4 BYTE TRANSFER LOAD EXP/MANT2 WITH MHLF (.5) +.5 4 BYTE TRANSFER LOAD EXP/MANT2 WITH ORIGINAL EXPONENT +EXPN 4 BYTE TRANSFER LOAD EXP/MANT2 WITH LN(2) *LN(2) RETURN RESULT IN MANT/EXP1

COMMON LOG OF MANT/EXP1 RESULT IN MANT/EXP1

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

1DBF 1DC2 1DC4 1DC7 1DC9 1DCA 1DCC 1DCF 1DD0 1DD4 1DD8 1DDC 1DE0 1DE4 1DE8

20 A2 BD 95 CA 10 20 60 7E 2D 80 82 7F B9 80 B0 81 86 80 08 7F 00

00 1D 03 D0 1D 04 F8 77 1F 6F ED 5A 7A 58 0C 52 40 AB 49 6A 66 40 00

LOG10 L10

* LN10 R22 LE2 A1 MB C MHLF * * * * EXP

JSR LDX LDA STA DEX BPL JSR RTS DCM DCM DCM DCM DCM DCM DCM

LOG =3 LN10,X X2,X L10 FMUL

COMPUTE NATURAL LOG LOAD EXP/MANT2 WITH 1/LN(10) LOG10(X)=LN(X)/LN(10)

0.4342945 1.4142136 0.69314718 1.2920074 -2.6398577 1.6567626 0.5 STARTING LOCATION FOR EXP SQRT(2) LOG BASE E OF 2

166 167 1E00 168 169 170 171 1E00 172 1E02 173 1E05 174 1E07 175 1E08 176 1E0A 177 1E0D 178 1E0F 179 1E11 180 1E13 181 1E14 182 1E16 INTEGER 183 1E19 184 1E1B 185 1E1D 186 1E1E 187 1E20 188 1E22 189 1E24 190 1E26 191 1E27 192 1E29 193 1E2B 194 1E2D 195 1E2F 196 1E31 197 1E33 198 1E35 199 1E37

ORG $1E00

EXP OF MANT/EXP1 RESULT IN MANT/EXP1 LDX LDA STA DEX BPL JSR LDX LDA STA DEX BPL JSR LDA STA SEC SBC LDA SBC BPL CLC LDA ADC LDA ADC BPL LDA LDX STA DEX =3 L2E,X X2,X EXP+2 FMUL =3 X1,X Z,X FSA FIX M1+1 INT =124 M1 =0 OVFLW M1+1 =120 M1 =0 CONTIN =0 =3 X1,X 4 BYTE TRANSFER LOAD EXP/MANT2 WITH LOG BASE 2 OF E LOG2(3)*X 4 BYTE TRANSFER STORE EXP/MANT1 IN Z SAVE Z=LN(2)*X CONVERT CONTENTS OF EXP/MANT1 TO AN SAVE RESULT AS INT SET CARRY FOR SUBTRACTION INT-124 OVERFLOW INT>=124 CLEAR CARRY FOR ADD ADD 120 TO INT IF RESULT POSITIVE CONTINUE INT<-120 SET RESULT TO ZERO AND RETURN 4 BYTE MOVE SET EXP/MANT1 TO ZERO

A2 BD 95 CA 10 20 A2 B5 95 CA 10 20 A5 85 38 E9 A5 E9 10 18 A5 69 A5 69 10 A9 A2 95 CA

03 D8 1E 04 F8 77 1F 03 08 10 F9 E8 1F 0A 1C 7C 09 00 15 0A 78 09 00 0B 00 03 08

FSA

ZERO

200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

1E38 1E3A 1E3B 1E3C 1E3F 1E41 1E43 1E45 1E46 1E48 1E4B 1E4D 1E4F 1E51 1E53 1E54 1E56 1E59 1E5B 1E5E 1E60 1E62 1E64 1E65 1E67 1E6A 1E6C 1E6F 1E71 1E72 1E74 1E77 1E79 1E7B 1E7D 1E80 1E82 1E84 1E86 1E87 1E89 1E8C 1E8F 1E91 1E93 1E95 1E96 1E98 1E9B 1E9D 1EA0 1EA2 1EA3 1EA5 1EA8 1EAB

10 FB 60 00 20 A2 B5 95 CA 10 20 A2 B5 95 95 CA 10 20 A2 BD 95 B5 95 CA 10 20 A2 BD 95 CA 10 20 A2 B5 95 BD 95 B5 95 CA 10 20 20 A2 B5 95 CA 10 20 A2 BD 95 CA 10 20 20 A2 2C 1F 03 10 04 F9 4A 1F 03 08 10 04 F7 77 1F 03 DC 1E 04 08 18 F4 50 1F 03 E0 1E 04 F8 9D 1F 03 08 14 E4 1E 08 18 04 F0 77 1F 1C 1F 03 14 08 F9 4A 1F 03 E8 1E 04 F8 50 1F 1C 1F 03

* OVFLW BRK * CONTIN JSR FLOAT LDX =3 ENTD LDA Z,X STA X2,X DEX BPL ENTD JSR FSUB LDX =3 ZSAV LDA X1,X STA Z,X STA X2,X DEX BPL ZSAV JSR FMUL LDX =3 LA2 LDA A2,X STA X2,X LDA X1,X STA SEXP,X DEX BPL LA2 JSR FADD LDX =3 LB2 LDA B2,X STA X2,X DEX BPL LB2 JSR FDIV LDX =3 DLOAD LDA X1,X STA T,X LDA C2,X STA X1,X LDA SEXP,X STA X2,X DEX BPL DLOAD JSR FMUL JSR SWAP LDX =3 LTMP LDA T,X STA X1,X DEX BPL LTMP JSR FSUB LDX =3 LDD LDA D,X STA X2,X DEX BPL LDD JSR FADD JSR SWAP LDX =3

BPL ZERO RTS

RETURN OVERFLOW FLOAT INT LOAD EXP/MANT2 WITH Z Z*Z-FLOAT(INT) 4 BYTE MOVE SAVE EXP/MANT1 IN Z COPY EXP/MANT1 TO EXP/MANT2 Z*Z 4 BYTE MOVE LOAD EXP/MANT2 WITH A2 SAVE EXP/MANT1 AS SEXP Z*Z+A2 4 BYTE MOVE LOAD EXP/MANT2 WITH B2 T=B/(Z*Z+A2) 4 BYTE MOVE SAVE EXP/MANT1 AS T LOAD EXP/MANT1 WITH C2 LOAD EXP/MANT2 WITH SEXP Z*Z*C2 MOVE EXP/MANT1 TO EXP/MANT2 4 BYTE TRANSFER LOAD EXP/MANT1 WITH T C2*Z*Z-B2/(Z*Z+A2) 4 BYTE TRANSFER LOAD EXP/MANT2 WITH D D+C2*Z*Z-B2/(Z*Z+A2) MOVE EXP/MANT1 TO EXP/MANT2 4 BYTE TRANSFER

258 1EAD B5 10 LFA LDA Z,X 259 1EAF 95 08 STA X1,X LOAD EXP/MANT1 WITH Z 260 1EB1 CA DEX 261 1EB2 10 F9 BPL LFA 262 1EB4 20 4A 1F JSR FSUB -Z+D+C2*Z*Z-B2/(Z*Z+A2) 263 1EB7 A2 03 LDX =3 4 BYTE TRANSFER 264 1EB9 B5 10 LF3 LDA Z,X 265 1EBB 95 04 STA X2,X LOAD EXP/MANT2 WITH Z 266 1EBD CA DEX 267 1EBE 10 F9 BPL LF3 268 1EC0 20 9D 1F JSR FDIV Z/(**** ) 269 1EC3 A2 03 LDX =3 4 BYTE TRANSFER 270 1EC5 BD E8 1D LD12 LDA MHLF,X 271 1EC8 95 04 STA X2,X LOAD EXP/MANT2 WITH .5 272 1ECA CA DEX 273 1ECB 10 F8 BPL LD12 274 1ECD 20 50 1F JSR FADD +Z/(***)+.5 275 1ED0 38 SEC ADD INT TO EXPONENT WITH CARRY SET 276 1ED1 A5 1C LDA INT TO MULTIPLY BY 277 1ED3 65 08 ADC X1 2**(INT+1) 278 1ED5 85 08 STA X1 RETURN RESULT TO EXPONENT 279 1ED7 60 RTS RETURN ANS=(.5+Z/(-Z+D+C2*Z*ZB2/(Z*Z+A2))*2**(INT+1) 280 1ED8 80 5C L2E DCM 1.4426950409 LOG BASE 2 OF E 55 1E 281 1EDC 86 57 A2 DCM 87.417497202 6A E1 282 1EE0 89 4D B2 DCM 617.9722695 3F 1D 283 1EE4 7B 46 C2 DCM .03465735903 4A 70 284 1EE8 83 4F D DCM 9.9545957821 A3 03 285 * 286 * 287 * BASIC FLOATING POINT ROUTINES 288 * 289 1F00 ORG $1F00 START OF BASIC FLOATING POINT ROUTINES 290 1F00 18 ADD CLC CLEAR CARRY 291 1F01 A2 02 LDX =$02 INDEX FOR 3-BYTE ADD 292 1F03 B5 09 ADD1 LDA M1,X 293 1F05 75 05 ADC M2,X ADD A BYTE OF MANT2 TO MANT1 294 1F07 95 09 STA M1,X 295 1F09 CA DEX ADVANCE INDEX TO NEXT MORE SIGNIF.BYTE 296 1F0A 10 F7 BPL ADD1 LOOP UNTIL DONE. 297 1F0C 60 RTS RETURN 298 1F0D 06 03 MD1 ASL SIGN CLEAR LSB OF SIGN 299 1F0F 20 12 1F JSR ABSWAP ABS VAL OF MANT1, THEN SWAP MANT2 300 1F12 24 09 ABSWAP BIT M1 MANT1 NEG? 301 1F14 10 05 BPL ABSWP1 NO,SWAP WITH MANT2 AND RETURN 302 1F16 20 8F 1F JSR FCOMPL YES, COMPLIMENT IT. 303 1F19 E6 03 INC SIGN INCR SIGN, COMPLEMENTING LSB 304 1F1B 38 ABSWP1 SEC SET CARRY FOR RETURN TO MUL/DIV 305 * 306 * SWAP EXP/MANT1 WITH EXP/MANT2 307 * 308 1F1C A2 04 SWAP LDX =$04 INDEX FOR 4-BYTE SWAP. 309 1F1E 94 0B SWAP1 STY E-1,X

310 1F20 B5 311 1F22 B4 312 1F24 94 313 1F26 95 314 1F28 CA 315 1F29 D0 316 1F2B 60 317 318 319 320 F.P. 321 322 323 324 1F2C A9 325 1F2E 85 326 1F30 A9 327 1F32 85 328 1F34 F0 329 1F36 C6 330 1F38 06 331 1F3A 26 332 1F3C 26 333 1F3E A5 334 1F40 0A 335 1F41 45 336 1F43 30 337 1F45 A5 338 1F47 D0 339 1F49 60 340 341 342 343 344 1F4A 20 345 1F4D 20 CARRY 346 347 348 349 1F50 A5 350 1F52 C5 351 1F54 D0 MANTISSAS 352 1F56 20 353 1F59 50 354 1F5B 70 CORRECT SIGN 355 1F5D 90 ARITH. 356 1F5F A5 357 1F61 0A 358 1F62 E6 359 1F64 F0 360 1F66 A2 361 1F68 A9 362 1F6A B0

07 03 07 03 F3 * * * *

LDA LDY STY STA DEX BNE RTS

X1-1,X X2-1,X X1-1,X X2-1,X SWAP1

SWAP A BYTE OF EXP/MANT1 WITH EXP/MANT2 AND LEAVEA COPY OF MANT1 IN E(3BYTES). E+3 USED. ADVANCE INDEX TO NEXT BYTE LOOP UNTIL DONE.

CONVERT 16 BIT INTEGER IN M1(HIGH) AND M1+1(LOW) TO

8E 08 00 0B 08 08 0B 0A 09 09 09 04 08 ED

8F 1F 5D 1F

* RESULT IN EXP/MANT1. EXP/MANT2 UNEFFECTED * * FLOAT LDA =$8E STA X1 SET EXPN TO 14 DEC LDA =0 CLEAR LOW ORDER BYTE STA M1+2 BEQ NORM NORMALIZE RESULT NORM1 DEC X1 DECREMENT EXP1 ASL M1+2 ROL M1+1 SHIFT MANT1 (3 BYTES) LEFT ROL M1 NORM LDA M1 HIGH ORDER MANT1 BYTE ASL UPPER TWO BITS UNEQUAL? EOR M1 BMI RTS1 YES,RETURN WITH MANT1 NORMALIZED LDA X1 EXP1 ZERO? BNE NORM1 NO, CONTINUE NORMALIZING RTS1 RTS RETURN * * * EXP/MANT2-EXP/MANT1 RESULT IN EXP/MANT1 * FSUB JSR FCOMPL CMPL MANT1 CLEARS CARRY UNLESS ZERO SWPALG JSR ALGNSW RIGHT SHIFT MANT1 OR SWAP WITH MANT2 ON * * * FADD ADD EXP/MANT1 AND EXP/MANT2 RESULT IN EXP/MANT1 LDA X2 CMP X1 BNE SWPALG COMPARE EXP1 WITH EXP2 IF UNEQUAL, SWAP ADDENDS OR ALIGN ADD ALIGNED MANTISSAS NO OVERFLOW, NORMALIZE RESULTS OV: SHIFT MANT1 RIGHT. NOTE CARRY IS SWAP IF CARRY CLEAR, ELSE SHIFT RIGHT SIGN OF MANT1 INTO CARRY FOR RIGHT ARITH SHIFT INCR EXP1 TO COMPENSATE FOR RT SHIFT EXP1 OUT OF RANGE. INDEX FOR 6 BYTE RIGHT SHIFT

04 08 F7 00 1F E3 05 BD 09 08 7E FA 80 01

JSR ADD ADDEND BVC NORM BVS RTLOG ALGNSW BCC SWAP RTAR LDA ASL RTLOG INC BEQ RTLOG1 LDX ROR1 LDA BCS M1 X1 OVFL =$FA =$80 ROR2

363 1F6C 364 1F6D 365 1F6F 366 1F71 367 1F73 368 1F74 369 1F76 370 371 372 373 374 1F77 375 1F7A 376 1F7C 377 1F7F 378 1F80 379 1F83 380 1F85 381 1F88 382 1F89 383 1F8B 384 1F8D COMPLEMENT 385 1F8F 386 1F90 387 1F92 388 1F94 389 1F96 390 1F98 391 1F99 392 1F9B 393 394 395 396 397 1F9D 398 1FA0 399 1FA2 400 1FA5 401 1FA6 402 1FA8 403 1FAA 404 1FAC 405 1FAD 406 1FAE 407 1FB0 408 1FB2 409 1FB3 410 1FB5 411 1FB7 412 1FB8 413 1FBA 414 1FBC 415 1FBE 416 1FC0 417 1FC2 418 1FC4 419 1FC6

0A 56 15 95 E8 D0 60

0F 0F 0F F2

ROR2

ASL LSR ORA STA INX BNE RTS

E+3,X E+3,X E+3,X ROR1

SIMULATE ROR E+3,X NEXT BYTE OF SHIFT LOOP UNTIL DONE RETURN

20 65 20 18 20 90 20 88 10 46 90 38 A2 A9 F5 95 CA D0 F0

0D 1F 08 CD 1F 66 1F 03 00 1F F5 03 AF 03 00 08 08 F7 BC

* * * * FMUL

EXP/MANT1 X EXP/MANT2 RESULT IN EXP/MANT1 JSR ADC JSR CLC JSR BCC JSR DEY BPL LSR BCC MD1 X1 MD2 RTLOG1 MUL2 ADD MUL1 SIGN NORM ABS. VAL OF MANT1, MANT2 ADD EXP1 TO EXP2 FOR PRODUCT EXPONENT CHECK PRODUCT EXP AND PREPARE FOR MUL CLEAR CARRY MANT1 AND E RIGHT.(PRODUCT AND MPLIER) IF CARRY CLEAR, SKIP PARTIAL PRODUCT ADD MULTIPLICAN TO PRODUCT NEXT MUL ITERATION LOOP UNTIL DONE TEST SIGN (EVEN/ODD) IF EXEN, NORMALIZE PRODUCT, ELSE

MUL1 MUL2 MDEND NORMX

20 E5 20 38 A2 B5 F5 48 CA 10 A2 68 90 95 E8 D0 26 26 26 06 26 26 B0

0D 1F 08 CD 1F 02 05 0C F8 FD 02 08 F8 0B 0A 09 07 06 05 1C

FCOMPL SEC SET CARRY FOR SUBTRACT LDX =$03 INDEX FOR 3 BYTE SUBTRACTION COMPL1 LDA =$00 CLEAR A SBC X1,X SUBTRACT BYTE OF EXP1 STA X1,X RESTORE IT DEX NEXT MORE SIGNIFICANT BYTE BNE COMPL1 LOOP UNTIL DONE BEQ ADDEND NORMALIZE (OR SHIFT RIGHT IF OVERFLOW) * * * EXP/MANT2 / EXP/MANT1 RESULT IN EXP/MANT1 * FDIV JSR MD1 TAKE ABS VAL OF MANT1, MANT2 SBC X1 SUBTRACT EXP1 FROM EXP2 JSR MD2 SAVE AS QUOTIENT EXP DIV1 SEC SET CARRY FOR SUBTRACT LDX =$02 INDEX FOR 3-BYTE INSTRUCTION DIV2 LDA M2,X SBC E,X SUBTRACT A BYTE OF E FROM MANT2 PHA SAVE ON STACK DEX NEXT MORE SIGNIF BYTE BPL DIV2 LOOP UNTIL DONE LDX =$FD INDEX FOR 3-BYTE CONDITIONAL MOVE DIV3 PLA PULL A BYTE OF DIFFERENCE OFF STACK BCC DIV4 IF MANT2<E THEN DONT RESTORE MANT2 STA M2+3,X DIV4 INX NEXT LESS SIGNIF BYTE BNE DIV3 LOOP UNTIL DONE ROL M1+2 ROL M1+1 ROLL QUOTIENT LEFT, CARRY INTO LSB ROL M1 ASL M2+2 ROL M2+1 SHIFT DIVIDEND LEFT ROL M2 BCS OVFL OVERFLOW IS DUE TO UNNORMALIZED DIVISOR

420 1FC8 421 1FC9 422 1FCB 423 1FCD 424 1FCF 425 1FD1 426 1FD3 427 1FD5 428 1FD7 429 1FD8 430 1FD9 431 1FDB 432 1FDD 433 1FDF 434 1FE1 435 1FE2 436 1FE4 437 438 439 M1+1(LOW) 440 441 442 1FE5 443 1FE8 444 1FEA 445 1FEC 446 1FEE 447

88 D0 F0 86 86 86 B0 30 68 68 90 49 85 A0 60 10 00

DA BE 0B 0A 09 0D 04 B2 80 08 17 F7

MD2

MD3

OVCHK MD3 OVFL * * * CONVERT EXP/MANT1 TO INTEGER IN M1 (HIGH) AND * * EXP/MANT2 UNEFFECTED JSR LDA CMP BNE RTS END RTAR X1 =$8E FIX-3

DEY BNE BEQ STX STX STX BCS BMI PLA PLA BCC EOR STA LDY RTS BPL BRK

DIV1 MDEND M1+2 M1+1 M1 OVCHK MD3 NORMX =$80 X1 =$17

NEXT DIVIDE ITERATION LOOP UNTIL DONE 23 ITERATIONS NORMALIZE QUOTIENT AND CORRECT SIGN CLR MANT1 (3 BYTES) FOR MUL/DIV IF EXP CALC SET CARRY, CHECK FOR OVFL IF NEG NO UNDERFLOW POP ONE RETURN LEVEL CLEAR X1 AND RETURN COMPLIMENT SIGN BIT OF EXP STORE IT COUNT FOR 24 MUL OR 23 DIV ITERATIONS RETURN IF POS EXP THEN NO OVERFLOW

20 A5 C9 D0 60

5F 1F 08 8E F7

FIX RTRN

SHIFT MANT1 RT AND INCREMENT EXPNT CHECK EXPONENT IS EXPONENT 14? NO, SHIFT RETURN

OBJECT CODE DUMP 1D00 1D10 1D20 1D30 1D40 1D50 1D60 1D70 1D80 1D90 1DA0 1DB0 1DC0 1DD0 1DE0 1E00 1E10 1E20 1E30 1E40 1E50 1E60 1E70 1E80 1E90 A5 84 B5 20 95 F9 77 4A 03 95 10 1F 00 73 81 A2 08 A5 0B 03 10 B5 04 95 03 09 04 04 4A 04 20 1F 1F BD 04 F8 A2 1D 6F AB 03 95 09 A9 B5 95 08 CA 08 B5 F0 49 95 1F CA 9D 20 A2 DC CA 20 03 A2 2D 86 BD 10 E9 00 10 04 95 10 B5 14 02 80 10 A2 10 1F 1C 03 1D 10 50 BD 03 ED 49 D8 CA 00 A2 95 CA 18 F8 18 95 10 85 B5 03 F0 A2 1F BD 95 F9 1F D8 BD 80 80 1E 10 10 03 04 10 CA 20 95 08 01 0A 08 B5 20 03 A2 E0 04 20 A2 1D D0 5A 6A 95 F9 15 95 CA F7 10 9D 04 CA 00 10 95 08 50 B5 03 1D CA 77 03 95 1D 82 08 04 20 18 08 10 20 F4 1F CA 10 20 01 18 95 1F 08 BD 95 10 1F B5 04 95 7A 66 CA E8 A5 CA F9 77 20 A2 10 F9 1C CA BD 14 A2 95 E4 04 F8 A2 18 CA 04 7F 7F 10 1F 0A 10 20 1F 50 03 F0 20 1F 86 D4 B5 03 14 1D CA 20 03 95 10 CA 58 40 F8 A5 69 FB 4A A2 1F B5 20 4A A2 09 1D 10 B5 95 95 10 50 BD 04 F8 10 B9 00 20 0A 78 60 1F 03 A2 08 77 1F 00 20 95 95 14 04 08 F8 1F E8 CA 20 F8 0C 00 77 85 A5 00 A2 BD 03 95 1F A2 A5 2C 08 08 95 CA CA 20 A2 1D 10 77 20 80 1F 1C 09 20 03 DC BD 14 20 03 04 1F CA BD 04 10 10 9D 03 95 F9 1F 77 52 A2 38 69 2C B5 1E E0 BD 1C BD A0 A2 10 D4 CA F7 F8 1F B5 04 20 60 1F B0 03 E9 00 1F 08 95 1E E4 1F E8 80 03 F0 1D 10 20 20 A2 14 CA 50 20 60 40 B5 7C 10 A2 95 04 95 1E A2 1E

1EA0 1EB0 1EC0 1ED0 1EE0 1F00 1F10 1F20 1F30 1F40 1F50 1F60 1F70 1F80 1F90 1FA0 1FB0 1FC0 1FD0 1FE0

95 08 20 38 89 18 12 B5 A9 0A A5 09 0F 20 A2 E5 A2 06 0A 17

04 CA 9D A5 4D A2 1F 07 00 45 04 0A 95 66 03 08 FD 07 86 60

CA 10 1F 1C 3F 02 24 B4 85 09 C5 E6 0F 1F A9 20 68 26 09 10

10 F9 A2 65 1D B5 09 03 0B 30 08 08 E8 90 00 CD 90 06 B0 F7

F8 20 03 08 7B 09 10 94 F0 04 D0 F0 D0 03 F5 1F 02 26 0D 00

20 4A BD 85 46 75 05 07 08 A5 F7 7E F2 20 08 38 95 05 30 20

50 1F E8 08 FA 05 20 95 C6 08 20 A2 60 00 95 A2 08 B0 04 5F

1F A2 1D 60 70 95 8F 03 08 D0 00 FA 20 1F 08 02 E8 1C 68 1F

20 03 95 80 83 09 1F CA 06 ED 1F A9 0D 88 CA B5 D0 88 68 A5

1C B5 04 5C 4F CA E6 D0 0B 60 50 80 1F 10 D0 05 F8 D0 90 08

1F 10 CA 55 A3 10 03 F3 26 20 E3 B0 65 F5 F7 F5 26 DA B2 C9

A2 95 10 1E 03 F7 38 60 0A 8F 70 01 08 46 F0 0C 0B F0 49 8E

03 04 F8 86 60 A2 A9 26 1F 05 0A 20 03 BC 48 26 BE 80 D0

B5 CA 20 57 06 04 8E 09 20 90 56 CD 90 20 CA 0A 86 85 F7

10 10 50 6A 03 94 85 A5 5D BD 0F 1F AF 0D 10 26 0B 08 60

95 F9 1F E1 20 0B 08 09 1F A5 15 18 38 1F F8 09 86 A0

Sign up to vote on this title
UsefulNot useful