þþÛr X; Part #2X;"A›FAST FLOATING POINT (ATARI)A(A“SYSTEM EQUATES USEDA2X;<CX; FAST FLOATING POINT ROM FOR THE ATARI 800/400 (TM ATARI, INC)F=X; Written by Charles W. Marslett, August-November, 1981P+X; Copyright 1981, Charles W. MarslettZ4X; Copyright 1982 and 1984, Charles W. MarslettdX;nHX; Permission is granted by the author for any use whatsoever of thisxGX; code, so long as this notice remains in the source code, and so‚KX; long as the source to this routine, however modified or unmodified,Œ-X; is made available for a nominal cost.–X; DX; SPEED IMPROVED OVER ATARI ROM, IN MOST CASES BY A FACTOR OF 3.ª4X; ERRORS IN LOG AND DIVIDE ALGORITHMS CORRECTED.´2X; ACCURACY IN EXP FUNCTION IMPROVED (I THINK).¾X;ÈLX; REVISION A, ASCII-->FLOATING CONVERSION OF 9 DIGITS ONLY (LIKE ATARI),ÒX; 19 NOVEMBER 1981.ÜHX; REVISION B, RETURNED TO USING REDARG IN LOG (LIKE ATARI), TO ALLOWæ=X; INCLUSION OF SIN/COS/SQR CONSTANTS FOR BASIC CARTRIDGEðX; 27 NOVEMBER 1981.úLX; REVISION C, ELIMINATED USE OF DEGRAD AND FRX IN THE FMUL/FDIV CODE ANDAX; FURTHER SPEEDED UP FMUL BY UNROLLING SHIFT LOOP, 30-NOV-81@X; REVISION D, INSERTED COPYRIGHT NOTICE IN THE ROM, 1-DEC-81;X; REVISION E, ADDED ASCII HEX DISPLAY ROUTINE, 4-MAR-82">X; REVISION F, MODIFIED EXP AND LOG FUNCTIONS FOR THE 600XL,8X; AND 800XL BASIC ROM POWER ROUTINE BUG, 17-JUNE-846X;@-‡ROMBASEØ;;STARTING ADDRESS OF F.P. ROMJ.…FPREC;;NUMBER OF BYTES IN A F.P. NUMBERTX;^X; BASE PAGE DEFINITIONShX;rÔ|ƒFR0…FPREC†ƒFRE…FPRECƒFR1…FPRECšƒFR2…FPREC¤ƒFRX…FPREC®„EEXPƒFRX¸…NSIGNƒFRXÂ…ESIGNƒFRẊFCHRFLGƒFRXÖ…DIGRTƒFRXà ƒCIXê †INBUFFô ‚Z1þ ‚Z2 ‚Z3/†DEGRAD;;DEGREE OR RADIAN UNITS FOR BASIC …FLPTR& …FPTR20X;:X; POLYNOMIAL WORK AREADX;N~X …LBPR1b …LBPR2l …LBUFF`v†PLYARG…FPREC€„FSCR…FPRECŠ…FSCR1…FPREC”€`…FPREC…FPREC…FPRECž†LBFEND ¨/A¨FLOATING POINT/ASCII CONVERSION ROUTINESA²X;¼ƒFRX;;ZERO FRX AND FR0  ƒZF1 „ZFR0 "…DIGRT;;STORE -1 INTO DIGRT*X;48…CHRLPP‡FCHRFLG;;CLEAR THE FIRST CHARACTER INDICATION>" …GETCH;;GET THE NEXT CHARACTERHE…INVLD;;IF NOT NUMERICR$ƒFR0\!H†NOTZER;;IF FR0 IS NORMALIZEDf, …SH0L4;;ELSE, SHIFT CONTENTS LEFT 4 BITSpLƒFR0…FPRECz&PƒFR0…FPREC;;MERGE IN NEW DIGIT„ $…DIGRTŽ0G†CHRLP0;;IF STILL AN INTEGER, JUST LOOP BACK˜X;¢6†DECFND#…DIGRT;;ELSE, BUMP NUMBER OF DECIMAL PLACES¬X;¶9†NOTZER$…DIGRT;;FILLED UP THE 10 DIGITS FOR THE NUMBERÀ5I†CHRLP0;;IF AFTER DECIMAL, IGNORE REMAINING DIGITÊ)#„EEXP;;IF NOT, BUMP THE EXPONENT BY 1Ô*†CHRLP0Q>ÿ;;RESET FIRST CHARACTER FLAGÞ H…CHRLPèX;ò…INVLDR> .;;FOUND DECIMAL?ü-H†NODEC0;;YES, START DECIMAL PLACE COUNTER-$…DIGRT;;BY MAKING NEGATIVE DIGRT POSITIVE3G†DECFND;;IF NOT NEGATIVE, SECOND '.' ENDS FIELDX;$†NODEC0R> E.1H…NOEXP;;IF NOT 'E', THEN NO EXPONENT SUBFIELD8$ƒCIXB …GETCHL4D…NOESG;;X CONTAINS 'CIX' BEFORE PARSING EXPONENTVR> +` F…SKESGjR> -t4H†RSTEXP;;IF NO + OR - AFTER 'E' THEN NO EXPONENT~&P…ESIGN;;MARK NEGATIVE IF '-' FOUNDˆ?…SKESG …GETCH;;IN ANY CASE, SEE IF NEXT CHARACTER IS NUMERIC’)E†RSTEXP;;IF NOT, NO EXPONENT SUBFIELDœ…EXPLP?;;SAVE NEXT DIGIT¦QƒFRX°T?º$T?;;MULTIPLY PREVIOUS TOTAL BY 10ÄOƒFRXÎT?Ø'PƒFRX;;THEN ADD TO THIS DIGIT (IN Y)âCìOƒFRXö…NOESGPƒFRX;;AND UPDATE FRX …GETCH 5D…EXPLP;;IF NO OVERFLOW AND NEXT CHARACTER NUMERIC-E†NUMEND;;IF NONNUMERIC, END OF THE NUMBERX;(EX; STUFF A BYTE INTO THE TEXT BUFFER (CONVERTING TO ASCII IF REQ.)2X;</…CVASCL> 0;;CONVERT DIGIT TO ASCII CHARACTERFX;P)…STUFFP…LBUFF8;;STORE BYTE INTO BUFFERZ3;;BUMP THE INDEXd „EXIT:nX;x3X; CONDITIONALLY PUT A DECIMAL POINT IN A BUFFER‚X;Œ …CDPNT"‚Z2–$H„EXIT;;IF NO POINT TO BE STUFFED Q> .;;ELSE, PUT IT INª H…STUFF´X;¾…NOEXP$‡FCHRFLGÈ H†NUMENDÒR> +Ü&F†CHRLP0;;IF LEADING '+', IGNORE ITæR> -ð.H†NUMEND;;IF LEADING '-', SET NEGATIVE FLAGú P…NSIGN F†CHRLP0X;:†RSTEXP&ƒCIX;;RESTORE POINTER AT BEGINNING OF PARSE TRY"Q>,PƒFRX;;REZERO EXPONENT6†NUMENDQ„EEXP@,JO>ˆT $…DIGRT^)G„NODP;;IF NO DECIMAL POINT ADJUSTMENTh;r:S…DIGRT;;ELSE, SUBTRACT NUMBER OF DIGITS TO RIGHT OF DP|$„NODP$…ESIGN;;CHECK EXPONENT SIGN†(H†SUBEXP;;IF NEGATIVE, SUBTRACT VALUE,š1OƒFRX;;ELSE, ADD VALUE OF EXPONENT TO BASE ONE¤ !…EXPOK®X;¸8X; REST OF THE BYTE TO ASCII (HEX) CONVERSION ROUTINEÂX;Ì"†CTUHEX7;;RESTORE ORIGINAL BYTEÖV?àV?êV?ô+V?;;POSITION UPPER 4 BITS FOR CONVERSIONþ2!†HEXDGT;;RETURN THROUGH THE CONVERSION ROUTINEX; †EXP3DGA)S>d;;TAKE THE 100 OUT OF THE EXPONENT&>0Q> 1;;PRINT THE LEADING '1': H…NNEXPDX;N †SUBEXP;XSƒFRXb%…EXPOKV?;;CONVERT TO POWERS OF 100l D…EVEXP;;SKIP AROUND TIMES 10v …SH0L4€…EVEXP%ƒFR0Š F…NORGT”O>ž$>…FPREC¨„SH0R%ƒFR09² 'ƒFR09¼0Æ I„SH0RÐ…NORGT$…NSIGNÚ F…NOXORäN>€î:…NOXOR"ƒCIX;;BACK UP OVER THE FINAL (INVALID) CHARACTERø'!„IFPE;;STORE EXPONENT AND NORMALIZEX; 9†NOEXPF †PRTDGT;;GO PUT ASCII DIGIT STRING INTO BUFFER3 L>€*-H†PUTSGN;;GO PUT MINUS SIGN IN IF REQUIRED4X;>"X; RETURN A VALUE OF ASCII ZEROHX;R&†ASCZERQ>€ 0;;ZERO, END OF STRING\ H†STZEROfX;p4X; FLOATING POINT TO ASCII CONVERSION (ADDR=D8E6)zX;„ ƒAFPæŽ2„FASC †INITBF;;PUT ADDRESS OF LBUFF INTO INBUFF˜QƒFR0;;IS THE NUMBER ZERO?¢&F†ASCZER;;IF YES, RETURN ASCII ZERO¬X;¶T?;;GET RID OF SIGN BITÀ;Ê*S>~;;DO RANGE CHECK (>0.01 AND < 1E10)Ô*R> ;;11 POSSIBLE DECIMAL POINTS (0-10)Þ D†NOEXPFè)S>;;CONVERT TO SIGNED EXPONENT OF 10ò)P„EEXP;;AND SAVE IT FOR LATER PRINTINGü5Q>;;SET CODE FOR XX.XXXXXXXX, BIT0=1, EXP FORMAT †PRTDGT 3 "Q> E;;FOLLOW DIGITS WITH AN 'E'$ …STUFF. X;8 Q> +;;ASSUME SIGN IS POSITIVEB $„EEXPL #I…NNEXP;;IF EXPONENT IS POSITIVEV +Q>;;COMPUTE ABSOLUTE VALUE OF EXPONENT` ;j S„EEXPt >~ Q> -;;THEN, DISPLAY A '-'ˆ …NNEXP …STUFF;;DISPLAY SIGN’ (>d;;EXPONENT > 100?œ 3E†EXP3DG;;IF SO, GO PRINT 3 DIGIT EXPONENT (1XX)¦ A;;RESTORE EXPONENT TO ACC° &3;;ALLOW FOR 10-S DIGIT OF EXPONENTº ,$>/;;'0-1 ;SET UP FOR CONVERT-TO-DECIMALÄ ;Î #…CVDLPS> ;;SUBTRACT 10 FROM ACCØ 2â 1E…CVDLP;;AND CONTINUE DOING SO UNTIL CONVERTEDì -O>€ 0 ;;RESTORE THE LAST 10 SUBTRACTEDö %P…LBUFF8;;STUFF IT INTO THE BUFFER A;;MOVE 10-S DIGIT TO ACC 1†PUTSGNP…LBUFF8;;AND PUT IT INTO THE BUFFER !QƒFR0;;STRIP OFF LEADING ZERO? "I†MINXIT;;IF NOT, ALL IS OK NOW( &"†INBUFF;;ELSE, MAKE ROOM FOR MINUS2 Q> -< †STZERO%>F &P@†INBUFF7;;PUT MINUS IN THE BUFFERP "†MINXIT:;;THEN FINALLY, WE EXITZ X;d &X; COPYRIGHT NOTICE IN THE ROM TEXTn $X; COPYRIGHT 1984, C. W. MARSLETTx X;‚  A“CPYRT.1984,MARSLETTAŒ 1AªFLOATING POINT/INTEGER CONVERSION ROUTINESA– X;  ,X; INTEGER TO FLOATING POINT CONTINUATIONª X;´ …IFPSU'ƒFR0¾ /%>;;SIXTEEN BITS IN NUMBER TO BE CONVERTEDÈ „IFPSTƒFR0Ò U?;;FIND FIRST 1 BITÜ 1æ E…IFPEN;;EXIT IF FOUNDð !I„IFPS;;ELSE, CONTINUE LOOPINGú !:;;ELSE, RETURN ZERO TO CALLER X; …IFPEN< #P‚Z3;;SAVE UPPER BYTE OF INTEGER" „IFPLQƒFR0, 7OƒFR0;;DOUBLE FR0 AND AND IN ONE BIT FROM INTEGER6 PƒFR0@ QƒFR0J OƒFR0T PƒFR0^ 8UƒFR0;;UPPER TWO DIGITS MAY BE ROTATED (NEVER > 9)h U‚Z3r 1| .I„IFPL;;THEN GO BACK TO HANDLE THE NEXT BIT† X; Q>B;;GENERATE THE EXPONENTš )!„IFPE;;THEN STORE, NORMALIZE AND EXIT¤ X;® ,X; FLOATING POINT TO INTEGER CONTINUATION¸ X; †FPICTU%>Ì 'ƒFR0Ö >à .F…FFRAC;;IF PROPER FRACTION, GO DO ROUNDINGê 0T?;;ELSE, MULTIPLY BY 16 (NUMBER OF BITS * 2)ô T?þ T? T? >;;PUT INTO X REGISTER X;& 3…CVTLPTƒFR0;;SHIFT NUMBER LEFT FOR CONVERSION0 UƒFR0: UƒFR0D UƒFR0N D…CVTST;;IF NO BIT, DO NO ADDX QƒFR0;;FIRST ADD LOW BITSb O†BITTAB9l PƒFR0v C;;THEN THE HIGH BITS€ O†BITTAB9Š ?;;STORE BACK INTO Y-REG” …CVTST0ž 0¨ 0H…CVTLP;;IF NOT SHIFTED OUT, LOOK AT NEXT BIT² X;¼ %…FFRACQƒFR0;;ROUND OFF FRACTIONÆ R>PÐ D†FFEXITÚ #ƒFR0ä H†FFEXITî 3;;ADD CARRY TO UPPER BYTEø †FFEXIT'ƒFR0 , :;;FINALLY, RETURN X; X;* 8X; INTEGER --> FLOATING POINT ENTRY POINT (ADDR=D9AA)4 X;>  `;;filler byteH X;R ƒAFPª\ ƒIFPQƒFR0f $ƒFR0p &ƒFR0z %>;;ZERO FR0+2 TO FR0+5„ 'ƒFR0Ž 'ƒFR0˜ 'ƒFR0¢ 7F…IFPSU;;GO FINISH SETUP (DUE TO LACK OF SPACE HERE)¬ X;¶ …FDIF5QƒFR09À SƒFR18Ê PƒFR09Ô 0Þ 1è I…FDIF5ò X;ü …FDIF60!G„FNME;;IF NO CARRY PROP. REQ. QƒFR09S>$ PƒFR09.'D…FDIF6;;IF CARRY PROP. NOT COMPLETE8!E…FNORM;;IF DONE, GO NORMALIZEBX;L=X; FLOATING POINT NUMBER TO INTEGER CONVERSION (ADDR=D9D2)VX;` ƒAFPÒj7ƒFPIQƒFR0;;USED HEAVILY BY BASIC ! ! ! ! ! ! ! ! ! !tR>C;;IS IT TOO BIG?~%E„ZFR0;;IF SO, EXIT WITH CARRY SETˆ2S>>;;ELSE, SUBTRACT 3F (NOTE CARRY IS CLEARED)’4E†FPICTU;;IF CARRY, THEN AT LEAST ROUNDING NEEDEDœ3D„ZFR0;;IF LESS THAN 0.01, RETURN ZERO, NO CARRY¦X;°/X; CONVERSION ROUTINE FOR A SINGLE HEX DIGITºX;Ä †HEXDGT;Î<Ø.S ;;CONVERSION USES A VERY FUNNY ALGORITHMâO> 9ì-ö:X; =X; FLOATING POINT ADD/SUBTRACT CODE (SPREAD ABOUT YOU SEE)X; ;;filler byte(X;2*ƒAFPç;;LINE UP ZFR0, ZF1 AND INITBF<„FNMEE…FNORMF;P$>…FPRECZ „FNM0Q>d SƒFR09n PƒFR09x0‚ H„FNM0ŒX;–QƒFR0 N>€ª „IFPEPƒFR0´ …FNORM-¾%>…FPRECÈ„FNMLQƒFR0Ò4F„FNM2;;IF UNNORMALIZED, GET RID OF LEADING ZEROSÜ",;;ELSE, CLEAR CARRY AND RETURNæ:ðX;ú„FNM3$>…FPREC„FNM4QƒFR0…FPREC9PƒFR0…FPREC92" H„FNM4,16,H„FNML;;GO BACK AND CHECK NEXT DIGIT PAIR@,F…RZERO;;IF SHIFTED 5 TIMES, THEN = ZERO!JX;T6†FR0BIGN>ÿ;;IF THE OTHER WAY AROUND, COMPUTE 4-DIF^O>…FPRECh.D„FNML;;IF SECOND NUMBER IS NON-SIGNIFICANTr?|<†QƒFR0NƒFR1š G…FDIF5¤,;;CLEAR CARRY FOR ADD®…FADD5QƒFR09¸ OƒFR18 PƒFR09Ì0Ö1à I…FADD5êX;ô …FADD60þ*G…FHTST;;IF NO CARRY PROPOGATE REQUIRED QƒFR09O> PƒFR09&0E…FADD6;;IF CARRY OUT, PROPOGATE TO NEXT BYTE0 D…FHTST:X;D„FNM2PƒFR0…FPRECN…FNMULQƒFR0X"ƒFR0bNƒFR0l I„FNM3v*…RZERO,;;RETURN A ZERO WITH CARRY CLEAR€X;ŠX; ZERO FR0 (ADDR=DA44)”X;ž0„ZFR0$>ƒFR0;;POINT AT FIRST BYTE TO BE ZEROED¨X;²?X; ZERO ANY (6-BYTE) FLOATING REGISTER ON PAGE 0 (ADDR=DA46)¼X;ƃZF1%>…FPRECÐX;Ú3X; ZERO ANY PART OR ALL OF PAGE ZERO (ADDR=DA48)äX;î „ZPG0Q>ø …ZF1LPP92 1 H…ZF1LP :;;THEN RETURN*X;4'X; POINT INBUFF TO LBUFF (ADDR=DA51)>X;H9†INITBFQ>…LBUFF;;COPY ADDRESS OF LBUFF INTO INBUFFRP†INBUFF\Q>…LBUFFÿf P†INBUFFp:zX;„%X; SHIFT 2-BYTE POINTER LEFT 1 BITŽX;˜5…DBLZ2T‚Z2;;SHIFT 0 INTO LOW BIT OF SECOND BYTE¢.U‚Z2;;SHIFT HIGH BYTE INTO LOW BIT OF FIRST¬:;;THEN RETURN¶X;À `;;filler byteÊX;ÔA•ADD/SUBTRACT ROUTINESAÞ ƒAFP`èX;ò/X; FLOATING SUBTRACT ENTRY POINT (ADDR=DA60)üX; „FSUBQƒFR1(N>€;;FLIP THE SECOND ARGUMENT-S SIGNPƒFR1;;BEFORE DOING AN ADD!$X;.*X; FLOATING ADD ENTRY POINT (ADDR=DA66)8X;B<„FADD$>…FPREC;;GET THE NUMBER OF MANTISSA BYTES INTO XL1QƒFR1;;GET THE EXPONENT OF THE SECOND ARGUMENTVM>;;STRIP OFF THE SIGN BIT`%P‚Z2;;SAVE IT FOR EXPONENT COMPAREj0QƒFR0;;GET THE EXPONENT OF THE FIRST ARGUMENTtM>;;STRIP OFF ITS SIGN BIT~;ˆ!S‚Z2;;SUBTRACT SECOND EXPONENT’3I†FR0BIG;;IF THE FIRST IS GREATER, GO ON WITH ITœ4O>…FPREC;;SEE IF THE FIRST IS EVEN SIGNIFICANT¦'?;;STORE NUMBER OF SIGNIFICANT BYTES°'<;;GO TO DECIMAL MODE FOR ARITHMETICº/QƒFR0;;COMPUTE REAL OPERATION (XOR OF SIGNS)ÄNƒFR1Î3G…FDIF0;;IF DIFFERENT, THIS IS REALLY A SUBTRACTØ,;;CLEAR CARRYâ 1;;Y=0?ìG…FADD1;;IF SO, SKIP ADDö4…FADD0QƒFR08;;ELSE, ADD THE TWO SELECTED BYTES OƒFR19  PƒFR0901('I…FADD0;;AND LOOP UNTIL ALL ARE DONE2X;<?…FADD1QƒFR19;;THEN PROPOGATE CARRY TO TOP OF LARGER ARGUMENTFO>P PƒFR09Z0d H…FADD1nX;x0QƒFR1;;COPY EXPONENT FROM SECOND TO FIRST ARG‚PƒFR0Œ3…FHTSTD…FADDX;;IF NO CARRY, EXIT (ADD COMPLETE!)–1$>…FPREC;;ELSE, SHIFT MANTISSA RIGHT 1 BYTE …FADD2QƒFR09ª PƒFR09´0¾+H…FADD2;;UNTIL ENTIRE BYTE IS MOVED OVERÈ,Q>;;PUT A '1' IN THE HIGH MANTISSA BYTEÒ PƒFR0Ü%QƒFR0;;THEN INCREMENT THE EXPONENTæ#ƒFR0ð3NƒFR0;;SEE IF OVERFLOW (SIGN CHANGE FROM INCR.!)úU?!…FADDX-;;RETURN TO BINARY MODE:;;THEN RETURN (OV==>CY SET)X;"…FDIF0;;;SET THE CARRY FLAG,167G…FDIF2;;SKIP SUBTRACT PHASE IF NO SIGNIFICANT BYTES@:…FDIF1QƒFR19;;SUBTRACT FR0 FROM FR1*10^N STORING IN FR0J SƒFR08T PƒFR09^0h1r I…FDIF1|X;†…FDIF2QƒFR19S>šPƒFR09;;PROPOGATE CARRIES¤0® H…FDIF2¸&QƒFR1;;THEN COPY EXPONENT TO RESULTÂPƒFR0Ì!„FNME;;AND DO NORMALIZATIONÖ(A¡FLOATING POINT (DECIMAL) MULTIPLYAàX;ê)X; FLOATING (DECIMAL) MULTIPLY ROUTINEôX;þ Ê;;filler byteX;7ƒAFPÕ;;FORCE ADDRESS OF ROUTINE TO MATCH ATARI-SC†NOOVFL$>…FPREC;;SET UP MAJOR LOOP COUNTER FOR EITHER MUL/DIV&&‚Z30 <;;DECIMAL MODE FOR ADD LOOPS:4:;;NOTE THAT X IS ALSO SET UP AS LOOP COUNTER TOODX;N „FMULQƒFR1X F…JZERObQƒFR0l$F…FDXIT;;IF ZERO FR0, JUST RETURNvX;€ >;;SAVE FOR LATER ERROR CHECKŠ;”S>?;;EXCESS 64 ADJUSTMENTž,¨OƒFR1²9 …MDEXP;;GO CHECK FOR OVER/UNDER-FLOW IN EXPONENT CALC¼…MOVELQƒFR09Æ PƒFRE9Ð PƒFR29Ú+Q>;;THEN ZERO FR0 TO ACCUMULATE RESULTä PƒFR09î0ø#H…MOVEL;;SETUP FOR MULTIPLY LOOP6PƒFRE;;ZERO HIGH ORDER 2 DIGITS OF BOTH FRE AND FR2 PƒFR2 P‚Z3  $>ƒFRE* „SHL44)F…LOOPE;;GO DO ACTUAL MULTIPLYING LOOP>X;H…MDEXPPƒFR0R%A;;COMPUTE SIGN OF RESULT WITH XOR\NƒFR1f,NƒFR0;;THEN SEE IF THE SIGNS ARE THE SAMEp+I†NOOVFL;;IF NOT, THIS IS OVER/UNDERFLOWzX;„7;;FLUSH TOP RETURN ADDRESSŽ7˜,QƒFR0;;RESTORE OVER(UNDER)FLOWED EXPONENT¢#U?;;IS IT OVERFLOW OR UNDERFLOW?¬6G…JZERO;;IF UNDERFLOW, RETURN A ZERO FOR THE RESULT¶7†OVFLDV;;;IF OVERFLOW, RETURN GARBAGE AND CARRY SET!À:ÊX;Ô2…FDXIT,;;RETURN ORIGINAL CONTENTS OF FR0 (ZERO)Þ:;;WITH NO ERROR INDICATIONèX;ò*…JZERO!…RZERO;;RESULT IS UNDERFLOW (=0)üX;X; L=;;filler bytes9X; FLOATING POINT DIVIDE (DECIMAL) ROUTINE ENTRY POINT$X;.>ƒAFP ;;FDIV IS ATARI ENTRY POINT, FLDDIV USED BY REDARG8;RFCONT IS USED BY LOG10B†RFCONTQ>L †CTUEVL;;CALCULATE NUMERATORVB†FLDDIV …FLD1P;;LOAD THE DIVISOR FROM LOC POINTED TO BY (FLPTR)`X;j&„FDIVQƒFR1;;IS THIS DIVIDE BY ZERO?t&F†OVFLDV;;IF SO, IT IS AN OVERFLOW!~QƒFR0ˆ F…FDXIT’&>;;ELSE, COMPUTE RESULTANT EXPONENTœ;¦SƒFR1°,ºO>@;;EXCESS 64 ADJUSTMENTÄ4 …MDEXP;;GO CHECK FOR EXPONENT OVER OR UNDER FLOWÎX;Ø5†DSETUPQƒFR19;;LOOP CTR (X) ALREADY SET TO FPREC-1â PƒFR29ì QƒFR09ö7PƒFR09;;PROVIDE A LEADING BYTE OF 0 FOR ALGORITHM0  H†DSETUP&ƒFR20&ƒFR0;;STUFF ZERO AFTER SHIFTING FR0 RIGHT( $>ƒFR22 „SHL4<;F<$>…FPREC;;POINTER TO CURRENTLY GENERATED QUOTIENT BYTEP-!†SUB10E;;SKIP ZEROING 7-TH BYTE OF NUMBERZX;dX; MAIN MULTIPLY LOOPnX;x…LOOP0QƒFR0‚ P‚Z3Œ QƒFR0– PƒFR0 5QƒFR0;;SHIFT ACCUMULATED PRODUCT RIGHT ONE BYTEª PƒFR0´ QƒFR0¾ PƒFR0È QƒFR0Ò PƒFR0Ü)'ƒFR0;;AND SHIFT IN 00 AT HIGH BYTEæX;ð)…LOOPE$‚Z3;;LOAD DIGIT PAIR BEING USEDú-QƒFR19;;GET NEXT DIGIT PAIR TO MULTIPLY BY-F…NOONE;;IF ZERO, SKIP BOTH MULTIPLY LOOPSV?V?"V?,V?;;EXTRACT UPPER DIGIT6!F…NOTEN;;IF 10-S DIGIT IS ZERO@,$>ƒFRE;;GO ADD IN FRE-S (MULTIPLIER X 10)J †DOMULTTX;^$‚Z3h(…NOTENQƒFR19;;GET 1-S DIGIT FROM BYTErM>|(F…NOONE;;IF ONES DIGIT IS ZERO, DONE!† $>ƒFR2 †DOMULTšX;¤$…NOONE"‚Z3;;DONE WITH ALL DIGITS?®H…LOOP0;;IF NOT, CONTINUE¸+Q‚Z3;;COPY 6-TH QUOTIENT DIGIT TO FR0 PƒFR0Ì$…FNDIV-;;BACK OUT OF DECIMAL MODEÖ QƒFR0à1H…FDXIT;;IF ALREADY NORMALIZED, EXIT TO CALLERê-%>…FPREC;;ELSE, NORMALIZE WITH GUARD DIGITô !…FNMULþX;X; LOAD 0.5 INTO FR1X;‡GETHALF%>„HALF& $>„HALFÿ0 !…FLD1R:X;D>X; SKIP OVER A STRING OF BLANKS IN INPUT BUFFER (ADDR=DBA1)NX;X ƒAFP¡b%…SKBLK%ƒCIX;;SKIP BLANKS IN BUFFERlQ> ;; (SPACE)v!H†FSTTST;;TEST FIRST CHARACTER€ …LPBLK3Š†FSTTSTR@†INBUFF7” F…LPBLKž"'ƒCIX;;UPDATE INDEX INTO BUFFER¨%:;;FOUND A NON-BLANK CHAR. RETURN!²X;¼DX; GET A CHARACTER (AND TRY TO CONVERT IT TO DECIMAL) (ADDR=DBAF)ÆX;ÐX;Ú ƒAFP¯ä'…GCHAR%ƒCIX;;GET POINTER INTO BUFFERî#Q@†INBUFF7;;GET BYTE FROM BUFFERø;%S> 0;;CONVERT FROM ASCII TO BINARY .R> ;;SEE IF IT FALLS OFF ON THE OTHER SIDE:;;CARRY SET==>NOT A DIGIT X;*CX; GET THE NEXT CHARACTER IF IT IS NOT A VALID NUMERIC CHARACTER4X;>+…NXTCH …GETCH;;GET THE CURRENT CHARACTERHD…GDCHR;;IF NUMERICRR> .\%F†DOTVLD;;DECIMAL, GO SEE IF VALIDfR> +p+F†SGNCHK;;PLUS OR MINUS, GO SEE IF VALIDzR> -„ H…BADCHŽX;˜†SGNCHKQ@†INBUFF7¢(R> .;;IF FOLLOWED BY A DECIMAL, VALID¬ F…GDCHR¶>†DOTVLDQ@†INBUFF7;;MAKE SURE ACC HAS NEXT CHARACTER IN IT!!ÀR> 0Ê+E…MAYBE;;IF DIGIT FOLLOWS, SIGN IS VALIDÔX;Þ,…BADCH;;;IF INVALID, SET CARRY AND RETURNè:òX;ü(X; GET A CHARACTER FROM A TEXT BUFFERX;-…GETCH …GCHAR;;GET A CHARACTER FROM BUFFER D…UPCIX;;IF DIGIT, UPDATE CIX$.Q@†INBUFF7;;ELSE, RESTORE ACTUAL ASCII CODE. …UPCIX38!'ƒCIX;;BUMP BOTH CIX AND Y-REGB:;;AND RETURNLX;V0X; SHIFT FR0 LEFT 4 BIT POSITIONS (ADDR=DBE4)`X;j …;;filler bytetX;~ ƒAFP䈅SH0L4$>ƒFR0’ „SHL4%>œ „SHLMT9¦U9°U9ºU9ÄU9ÎU9Ø1â H„SHLMì:öX;…MAYBER>:;;'9'+1  E…BADCHX; …GDCHR,(-"ƒCIX;;ADJUST INDEX BACK (NOT INCREMENTED)2:;;AND RETURN<X;F#ƒAFP;;NORMALIZE ENTRY POINTP7†NORMAL!…FNORM;;MOVED UP INTO THE FADD/FSUB ROUTINESZX;dX;n6X; DIVISION LOOP (GENERATE RESULTANT FRACTION ONLY)xX;‚X;Œ0†FDIVLP'ƒFRE…FPREC9;;ZERO NEW LOW ORDER BYTE–)G†SUB10E;;THEN GO TO LOOP NORMAL ENTRY X;ª0†SUB10N3;;ADD ANOTHER 10 TO QUOTIENT LOW BYTE´†SUB10EQƒFRE9¾ SƒFR2È PƒFRE9Ò QƒFRE9Ü SƒFR2æ PƒFRE9ð QƒFRE9ú SƒFR2 PƒFRE9 QƒFRE9 SƒFR2" PƒFRE9, QƒFRE96 SƒFR2@ PƒFRE9J QƒFRE9TSƒFR2^ PƒFRE9h2E†SUB10N;;IF NOT NEGATIVE YET, CONTINUE LOOPINGrX;|C†T?'T?;;SHIFT QUOTIENT DIGIT LEFT 4 BITSšT?¤T?®.L> ;;THEN ADD IN UNITS DIGIT (FIRST GUESS)¸?;;RESTORE TO Y-REGÂX;̆ADD01NQƒFRE9Ö OƒFR1à PƒFRE9ê QƒFRE9ô OƒFR1þ PƒFRE9 QƒFRE9 OƒFR1 PƒFRE9& QƒFRE90 OƒFR1: PƒFRE9D QƒFRE9N OƒFR1X PƒFRE9b QƒFRE9l O>v PƒFRE9€ 1;;DECREMENT THE 1-S DIGITŠ ;D†ADD01N;;AND IF NOT POSITIVE, DO ANOTHER ADD OF DIVISOR” ,'ƒFRE9;;ELSE, STORE RESULTANT 2 DIGITSž ?;;REZERO THE Y-ACCUMULATOR¨ "2;;THEN SEE IF DIVIDE COMPLETED² .G†FDIVLP;;IF NOT, GO GENERATE NEXT 2 DIGITS¼ /!…FNDIV;;IF SO, GO NORMALIZE RESULT AND EXITÆ X;Ð 1†DOMULT?;;SAVE NUMBER OF TIMES TO ADD IN Y-REGÚ ,ä …MULLPQ‚Z3î O9ø P‚Z3! QƒFR0 !O9! PƒFR0 ! QƒFR0*!O94! PƒFR0>! QƒFR0H!O9R! PƒFR0\! QƒFR0f!O9p! PƒFR0z! QƒFR0„!O9Ž! PƒFR0˜!1;;ALL ADDITIONS DONE?¢!%H…MULLP;;IF NOT GO DO THE NEXT ONE¬!:;;ELSE, RETURN¶!X;À!?X; TABLE TO CONVERT FROM DECIMAL TO BINARY (BITWISE) QUICKLYÊ!X;Ô!†BITTAB Þ! ===è!  =='=Oò! c=Ç==ü! ç=Ï=Ÿ=?" '=N=Ác=" ==="#AœGENERALLY USEFUL SUBROUTINESA$"X;."@X; CONVERT PACKED DECIMAL MANTISSA (WITH DECIMAL INFORMATION)8"/X; TO AN ASCII (NUMERIC) CHARACTER STRINGB"X;L"6†PRTDGTV?;;GET NUMBER OF BYTES BEFORE DECIMAL POINTV"'WƒCIX;;SAVE LOW BIT AS E-FORMAT FLAG`")P‚Z2;;SAVE DIGITS BEFORE DECIMAL POINTj"5$>…FPREC;;SET UP BYTE COUNTER FOR A F.P. NUMBERt"%>;;ZERO BOTH INDICES~"#‚Z2;;OFFSET FIRST DECREMENTˆ"5…DGTLP …CDPNT;;CONDITIONALLY PRINT A DECIMAL POINT’"QƒFR0…FPREC9œ"V?¦" V?;;POSITION HIGH 4-BIT DIGIT°"V?º"V?Ä", …CVASC;;PUT THAT CHARACTER IN THE BUFFERÎ"QƒFR0…FPREC9Ø"M>;;EXTRACT SECOND DIGITâ"& …CVASC;;AND PUT IT INTO THE BUFFERì"2;;NEXT DIGIT PAIRö")G…DGTLP;;IF NOT FINISHED, PROCESS THEM#X; #. …CDPNT;;ELSE, SEE IF TRAILING DECIMAL REQ.#*Q> 0;;CHECK FOR LEADING DECIMAL OR ZERO# R…LBUFF(#8F†TRNKZE;;IF ZERO, CLIP IT OFF LEAVING 9 DIGIT RESULT2#>D†DECSFT;;IF SIGNIFICANT DIGIT, MOVE DECIMAL IF IN E-FORMAT<#8"†INBUFF;;ELSE, IT IS A DECIMAL, BACK UP AND INSERT AF#P…LBUFF;;LEADING ZERO!P#)E…ZSCAN;;THEN STRIP OFF TRAILING ZEROSZ#X;d#@†TRNKZE#†INBUFF;;STEP TO SECOND DIGIT (WHICH CANNOT BE ZERO!)n# E…ZSCANx#X;‚#/†DECSFTQƒCIX;;SEE IF IN E-FORMAT TRANSLATIONŒ#:I…ZSCAN;;IF NOT, BUFFER IS OK, STRIP OFF TRAILING ZEROS–# Q…LBUFF #6P…LBUFF;;ELSE, MOVE DECIMAL POINT LEFT ONE DIGITª#Q> .´# P…LBUFF¾#/#„EEXP;;AND ADJUST EXPONENT FOR THE MOVEMENTÈ#X;Ò#'X; SCAN TO ELIMINATE TRAILING ZEROESÜ#X;æ#:…ZSCAN%> ;;START WITH DIGIT 10 (AFTER FOLLOWING 'DEC')ð# †ZSCNLP1ú#5F†LSTCHR;;IF FIRST CHARACTER, THEN USE 1 CHARACTER$#Q…LBUFF8;;GET THE LAST CHARACTER$R>0;;IS IT A TRAILING ZERO?$@F†ZSCNLP;;IF SO, CONTINUE SCAN TIL NONZERO OR FIRST CHARACTER"$'R> .;;IF NOT, IS IT A DECIMAL POINT?,$/H…TRXIT;;NO, THEN THIS IS THE LAST CHARACTER6$51;;YES, THEN DIGIT BEFORE IT IS THE LAST CHARACTER@$0†LSTCHRQ…LBUFF8;;LOAD IT AND RETURN TO CALLERJ$ …TRXIT:T$X;^$ •==Ê=ˆ;;filler bytesh$X;r$$APOLYNOMIAL EVALUATION ROUTINEA|$ ƒAFP"†$)†RSTARG$>…FPREC;;COPY PLYARG TO FR1$†RSTALPQ†PLYARG9š$ PƒFR19¤$0®$ I†RSTALP¸$:Â$X;Ì$…LDARG$>…FPRECÖ$…LDALPQ†PLYARG9à$ PƒFR09ê$0ô$ I…LDALPþ$:%X;%8†PLYONE †SAVARG;;SAVE ARGUMENT AND POLYNOMIAL ADDRESS%)†CTUONEPƒCIX;;SAVE ORDER OF POLYNOMIAL&%#H†PLYADD;;ENTER LOOP WITH AN ADD0%:;;IF A=0, VALUE IS ARGUMENT:%X;D%-X; POLYNOMIAL EVALUATION ENTRY (ADDR=DD40)N%X;X%/†PLYEVL †SAVARG;;SAVE FR0, X, Y AS ARGUMENTSb%(†CTUEVLPƒCIX;;SEE IF MORE THAN 1 TERMl%" …LDPLY;;LOAD FIRST COEFFICIENTv%"ƒCIX€%*H†PLYENT;;IF OK, GO DO MULTIPLY AND ADDŠ%:;;ELSE, JUST RETURN”%X;ž%"…PLYLP"ƒCIX;;END OF POLYNOMIAL?¨%F†PLYXIT;;YES, EXIT²% †RSTARG;;RESTORE ARGUMENT¼%,†PLYENT „FMUL;;ARGUMENT TIMES PARTIAL SUMÆ%#E†PLYXIT;;EXIT IF OVERFLOW HERE!Ð%/†PLYADD …LDPLY;;LOAD NEXT COEFFICIENT IN FR1Ú% „FADD;;ADD NEXT COEFFICIENTä% D…PLYLPî%†PLYXIT:;;ELSE, RETURNø%X;&9…LDPLY%>…FPREC;;INDEX BY Y SINCE INDIRECT REFERENCE &&†LDPLYLQ@…FPTR27;;GET ARGUMENT BYTE&PƒFR18;;STORE IN FR1 &1*&I†LDPLYL;;DO ALL 6 BYTES4&,;;THEN ADVANCE THE POINTER>& Q…FPTR2H&5O>…FPREC;;BY THE LENGTH OF 1 FLOATING POINT NUMBERR& P…FPTR2\&D†LDPXIT;;EXIT IF NO CARRYf&$#…FPTR2;;ELSE, BUMP UPPER BYTEp&†LDPXIT:;;AND RETURNz&X;„&†SAVARG'…FPTR2Ž&'&…FPTR2;;STORE ADDRESS OF POLYNOMIAL˜&†PUTARG?;;SAVE ACC¢&"$>…FPREC;;COPY FR0 TO PLYARG¬&†SAVALPQƒFR09¶& P†PLYARG9À&0Ê&)I†SAVALP;;LOOP UNTIL ALL 6 BYTES MOVEDÔ&C;;RESTORE ACCÞ&:è&(A¡MEMORY TO MEMORY MOVE SUBROUTINESAò&X;ü&X; LOAD FLOATING REGISTER 0'X;' ƒAFP‰'+…FLD0R'…FLPTR;;STORE (Y,X) AS ADDRESS$' &…FLPTR.'…FLD0P%>…FPREC8'…FLD0LQ@…FLPTR7B' PƒFR08L'1V'(I…FLD0L;;COPY ALL BYTES OF THE NUMBER`':j'X;t'X; LOAD FLOATING REGISTER 1~'X;ˆ' ƒAFP˜’'+…FLD1R'…FLPTR;;STORE (Y,X) AS ADDRESSœ' &…FLPTR¦'…FLD1P%>…FPREC°'…FLD1LQ@…FLPTR7º' PƒFR18Ä'1Î'I…FLD1L;;COPY ALL BYTESØ':â'X;ì'X; STORE FLOATING REGISTER 0ö'X;(5…FST0R'…FLPTR;;STORE (Y,X) AS ADDRESS OF TARGET ( &…FLPTR(…FST0P%>…FPREC(…FST0LQƒFR08(( P@…FLPTR72(1<(-I…FST0L;;LOOP UNTIL ENTIRE FIELD IS STOREDF(:P(X;Z(X; MOVE FR0 TO FR1d(X;n( ƒAFP¶x(…FMOVE$>…FPREC‚(…FMOVLQƒFR09Œ( PƒFR19–(0 ( I…FMOVLª( †OVFEXP:´(A•EXPONENTIAL FUNCTIONSA¾(X;È(!X; BASE e EXPONENTIAL FUNCTIONÒ(X;Ü( ƒAFPÀæ(ƒEXP%>†INVL10ð($>†INVL10ÿú(: …FLD1R;;MULTIPLY ARGUMENT TO CONVERT FUNCTION TO EXP10) „FMUL)*E†OVFEXP;;IF OVERFLOW, RETURN CARRY SET)X;")"X; BASE 10 EXPONENTIAL FUNCTION,)X;6);…EXP10 …FMOVE;;SAVE UNMODIFIED ARGUMENT (PRECISION REQ.)@)TƒFR0J)VƒFR0;;STRIP OFF SIGN BITT) ƒFPI;;CONVERT TO INTEGER^).;;;SAVE A BYTE BY SETTING CARRY BEFORE TESTh)QƒFR1;;SEE WHAT SIGN WASr),I†PLSEXP;;IF EXPONENT IS ALREADY POSITIVE|)Q>€†)*SƒFR0;;NEGATE RESULT OF IFP CALL IF NOT) P‚Z1š)Q>¤) SƒFR0®) F…EXPRV¸) !…RZEROÂ)X;Ì)†PLSEXPQƒFR0Ö)$O>;;SEE IF EXPONENT IS IN RANGEà) P‚Z1ê),E†OVFEXP;;IF EXPONENT BETWEEN 128 AND 255ô);;;RETURN ERRORþ)2QƒFR0;;IS THE EXPONENT BETWEEN -128 AND 127?*H†OVFEXP;;<-128 OR > 255*&…EXPRVP‚Z1;;MARK RANGE AS UNSHIFTED* ƒIFP;;BACK TO FLOATING POINT&*,TƒFR0;;GET RID OF INTEGER SIGN (ALWAYS +)0*-Q>;;COPY COMPLIMENT OF SIGN OF FR1 TO CY:*RƒFR1D*$WƒFR0;;PUT NEW SIGN BACK INTO FR0N*/ „FADD;;GENERATE FRACTIONAL PART OF EXPONENTX*X;b* QƒFR0;;SEE IF FRACTION > 0.25l*M>v*(R>?;;IF EXPONENT NOT 3F THEN ITS NOT€* H…EVALGŠ*)QƒFR0;;ELSE, LOOK AT UPPER 2 DIGITS”*R>%ž*'D…EVALG;;IF < 25 THEN FRACTION IS OK¨*#P‚Z1;;MARK AS NEEDING ADJUSTMENT²* ‡GETHALF¼*QƒFR0Æ*TƒFR1Ð*T?Ú**WƒFR1;;COPY SIGN TO 0.5 LOADED INTO FR1ä* I…NODECî* "‚Z1ø*…NODEC „FSUB+X; +7…EVALG%>„FSCR;;SAVE V (REDUCED ARGUMENT) IN FSCR+ $>„FSCRÿ + …FST0R*+ …FMOVE4+ „FMUL;;SQUARE V>+%>†EXPPLYH+ $>†EXPPLYÿ;;GENERATE P(V^2)R+Q>;;2 TERM POLYNOMIAL\+ †PLYEVLf+! …FLD1P;;GET ORIGINAL ARGUMENTp+ „FMUL;;COMPUTE V*P(V^2)z+ …FST0P;;SAVE RESULT„+ …LDARG;;COPY ARG TO FR0Ž+Q>˜+6 †CTUONE;;CONTINUE (ARG AND POLY PTR BOTH RETAINED)¢+ …FLD1P;;GET NUMERATOR¬+& „FSUB;;COMPUTE DENOMINATOR (Q-V*P)¶+ …FMOVE;;PUT IN FR1À+ …FLD0P;;GET NUMERATORÊ+ „FDIVÔ+ ‡GETHALFÞ+ „FADDè+ …FMOVE;;THEN DOUBLE RESULTò+ „FADDü+#Q‚Z1;;SEE IF ADJUSTMENT REQUIRED, F…NOSQR,( †LDPMUL;;ELSE, LOAD FR1 WITH SQR(10),*…NOSQRV‚Z1;;THEN SEE IF *10 REQUIRED$,*D…NOSFT;;IF NOT, SKIP TO EXPONENT BUILD., %>ƒC108, $>ƒC10ÿB,! …FLD1R;;MULTIPLY RESULT BY 10L, „FMULV, …NOSFT,`,QƒFR0j,$O‚Z1;;ADD EXPONENT TO ORIGINALt,S>?~,$PƒFR0;;GENERATED EXP(X) COMPLETE!ˆ,',;;TURN OFF CARRY (RANGE ERROR) FLAG’, †OVFLOG:œ,X;¦,@X; REDUCE AN ARGUMENT WITH THE FORMULA REDARG=(ARG-K)/(ARG+K)°,X; (ADDR=DE95)º,X;Ä, C=B=”;;filler bytesÎ,X;Ø, ƒAFPâ,-†LOGREDE…RARG1;;IF SO, SKIP MULTIPLY BY 10ì,"‚Z1ö,&&ƒFR1;;CHANGING CONSTANT TO 0.05- D…RARG1 -X;--†REDARG …FLD1R;;GET K FROM MEMORY INTO FR1-4…RARG1 †PUTARG;;SAVE UNREDUCED ARGUMENT IN PLYARG(- „FADD;;COMPUTE ARG+K2-(%>„FSCR;;SAVE DENOMINATOR IN FSCR<- $>„FSCRÿF- …FST0RP-- …LDARG;;RESTORE UNREDUCED ARGUMENT TO FR0Z- „FSUBd- !†FLDDIVn-X;x-X;‚-  ;;filler byteŒ-X;–-A”LOGRITHMIC FUNCTIONSA -2ƒAFP¯;;PUT RIGHT BEFORE THE LOG ENTRY POINTª-†EXPPLY @==p=8=ƒ=e´- @=i== =1=&¾-X;È- @=4==@= =gÒ- @=Y=”=!=3='Ü-X;æ-…SQR10 @==="=w=fð-X;ú-,X; LOGRITHM FUNCTIONS (BASE e, ADDR=DECD).X;.'ƒAFPÍ;;ATARI DEFINED ENTRY POINT.9ƒLOGQ>€;;SET FLAG TO INDICATE THIS IS NOT BASE 10 LOG". H„LOGS,.X;6.-X; LOGRITHM FUNCTIONS (BASE 10, ADDR=DED1)@.X;J. …LOG10Q>T.;„LOGSP‚Z1;;STORE FLAG TO INDICATE WHICH CLASS OF LOGS^.QƒFR0h.T?r.,E†OVFLOG;;IF LOG OVERFLOW (NEGATIVE ARG.)|.S>}†.P‚Z1;;SAVE RANGE DATA.QƒFR0;;IS NUMBER > 0.1?š.R>¤.3E†NOLSFT;;IF SO, SHIFT DENOMINATOR RIGHT 1 DIGIT®.4"‚Z1;;UPDATE EXPONENT FOR LEADING ZERO ELIMINATED¸.. …SH0L4;;ELSE, SHIFT NUMERATOR LEFT 1 DIGITÂ.*†NOLSFTQ>?;;INITIAL VALUE FOR EXPONENTÌ.PƒFR0Ö.' ‡GETHALF;;REDUCTION CONSTANT = 0.50à. „FMUL;;HALVE ARGUMENTê. QƒFR0ô.$>þ.2R>;;IS THE REDUCED ARGUMENT > 0.32 (SQR(0.1))/X;/. †LOGRED;;REDUCE ARGUMENT VIA Z=(X-1)/(X+1)/$ƒFR0&/ I…LNORM0/(#ƒFR0¿9;;FORCE NEGATIVE ROUNDING:/#ƒFR0¿9D/ …LNORMN/" …FST0P;;THEN STORE Z IN 'FSCR'X/ …FMOVEb/ „FMUL;;SQUARE ITl/%>†LOGPLYv/$>†LOGPLYÿ€/Q>Š/3 †PLYONE;;CALCULATE DENOMINATOR OF RAT. FRACTION”/$>…FSCR1ÿž/8 …FST0R;;NOTE THAT HIGH BYTE OF FLPTR IS UNCHANGED¨/& …LDARG;;PUT ARGUMENT BACK INTO FR0²/0 †RFCONT;;CALC. DENOM. & R(Z), THE RAT. FRAC.¼/X;Æ/! †RSTARG;;THEN MULTIPLY BY 'Z'Ð/ „FMULÚ/ …LDPLYä/ „FADDî/ $>„FSCRÿø/8 …FLD1R;;NOTE THAT HIGH BYTE OF FLPTR IS UNCHANGED0 „FMUL 0 †PUTARG0$2;;CONVERT X (FROM FMOVE) TO ZERO 01&ƒFR0;;ZERO HIGH BYTE OF INTEGER (EXPONENT)*0Q‚Z140=I†INTPRT;;IF EXPONENT IS NEGATIVE, THEN GET ABSOLUTE VALUE>0;H0A;;ZERO ACCR0!S‚Z1;;SUBTRACT FROM 0 (NEGATE)\0/†INTPRTPƒFR0;;STORE Z1 OR -Z1 AS APPROPRIATEf0 ƒIFPp01TƒFR0;;NEXT, CHANGE SIGN OF RESULT IF NEGATIVEz0T‚Z1„0WƒFR0Ž0 ‡GETHALF˜0 „FMUL¢0 …FMOVE¬0 …LDARG¶0X;À0" „FADD;;ADD INTEGER TO FRACTIONÊ0 „FADDÔ0 Q‚Z1Þ0F†LOG10E;;IF LOG BASE 10è02†LDPMUL …LDPLY;;ELSE, MULTIPLY RESULT BY LN(10)ò0 !„FMULü0X;1X;1 w=f;;filler bytes1X;$12X; CONSTANTS USED IN THE FLOATING POINT PACKAGE.1X;811ƒAFPl;;REFERENCED BY BASIC SIN/COS ROUTINEB1„HALF ?=P====L1X;V1.X; COEFFICIENTS USED IN THE LOG POLYNOMIALS`1X;j1*†LOGPLY À=====E;; -8.19080045t1# @==–=i==@;; 16.96698140~1# À=====•;;-10.07040695ˆ1X;’1#†LOG10E ;;RETURN INSTRUCTIONœ1$ ¿=g=5==`=;;-0.6735816015¦1" @===0=4=’;; 3.16303492°1" À==‘=V==D;;-2.91568144º1X;Ä1% ?=†=…=ˆ=–=8;; 0.8685889638Î1(„LN10 @==0=%=…= ;; 2.30258509Ø1X;â1†INVL10 ?=C=B=”=H=ì1X;ö1ƒC10 @=====2X; 28X; POLYNOMIAL FOR SIN/COS FUNCTIONS (11 COEFFICIENTS)2X;2 ƒAFP®(2;†PLYSIN >===D=I=;;REF BY BASIC SIN/COS ROUTINES22 ¾=•=h=8=E=<2 ?==h=y=”=F2 ¿==’=x==€P2 ?==== =Z2 ¿==’=)==Dd2 ?===@= =n2 ¿==(=1=V=x2 ?==™=˜=w=D‚2 ¿=3=3=3=1=Œ2K„NONE ?=™=™=™=™=™;;ALMOST EQUAL TO 1.0 (USED FOR ROUNDOFF PROBLEM)–2X; 2X; SIN OF 45 DEG.ª2X;´2…SIN45 ?=x=S=˜==4¾2X;È2.X; CONVERT A BYTE TO TWO HEX DIGITSIN (A,X)Ò2X;Ü2†CVTHEX5;;SAVE UPPER DIGITæ2M>ð2 †HEXDGT;;CONVERT LOWER DIGITú2>3,!†CTUHEX;;RESTORE AND CONVERT UPPER DIGIT3X; THE END!