@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u_CPUTC.OBJ kRWCOMMON.OBJgCGETS.OBJ cPARSELIN.OBJWRITE.OBJ UCLOSE.OBJ CFOPEN.OBJ (CGETC.OBJ kITOA.T}OBJ zTPRINTF.OBJ FPRINTF.OBJ STARTUP.OBJ ATOI.OBJ FPUTS.OBJ FGETS.OBJ GETS.OBJ ISCNTRL.OBJ ISPRU}INT.OBJ ITOX.OBJ ATOIB.OBJ OISALNUM.OBJ ISCONS.OBJ ISPUNCT.OBJ OTOI.OBJ STRCMP.OBJ DTOI.OBJ 1ISSV}PACE.OBJ ITOD.OBJ _PMALLOC.OBJ UTOI.OBJ FCLOSE.OBJ ISASCII.OBJ eISGRAPH.OBJ ISUPPER.OBJ ITOO.OBJ TIW}ME.OBJ XTOI.OBJ *ISATTY.OBJ ISLOWER.OBJ ISXDIGIT.OBJITOU.OBJ ETOASCII.OBJ NOPEN.OBJ RENAME.OBJ DX}ELETE.OBJ FNAME.OBJ FREAD.OBJ FWRITE.OBJ READARGS.OBJSTRCAT.OBJ STDIO.OBJ EFRENAME.OBJ xFDELETE.OBJ xY}CLOSEALL.OBJ/READ.OBJ ZHEAP.OBJ 8ISALPHA.OBJ FISODIGIT.OBJ:ISDIGIT.OBJ 9ISWHITE.OBJ ?BZERO.OBJ `BCOPY.OBJ lZ}STRCHR.OBJ gGETCH.OBJ ,TOLOWER.OBJ 7TOUPPER.OBJ 8REVERSE.OBJ ITOAB.OBJ aATOF.OBJ TCEIL.OBJ COSIN.OBJ [}!EXP.OBJ _EXP10.OBJ aFABS.OBJ LFADD.OBJ `FCMP.OBJ mFCPY.OBJ ZFDIV.OBJ oFLOOR.OBJ FMUL.OBJ \} `FPERROR.OBJ FP_SYS.OBJ FRAC.OBJ FSUB.OBJ `FTOA.OBJ FTOI.OBJ FTOU.OBJ UHYPOT.OBJ aITOF.OBJ ]} LOG.OBJ jLOG10.OBJ lPOLY.OBJ POW.OBJ SQRT.OBJ UTOF.OBJ P/+4POPAX_CPUTC_FPUT^}CIORETURN @ @HHIDE Bh VLC`'/8INCSP6 __RWSETUPLDAXYSP B_} BHI B DE @(`:D_CGETSPOPAX A A HI ADE`}B V0``y __PARSELIPOPAX A ANHɛD ma}ȥi mHhɛ`!8``(%_WRITEIORETURb}N __RWSETUP B B VLA HHIh`#_CLOSEPOPAX_CCLOSE A B V0``c}Il_STDERRPUSHBAXI_FOPEN_STDIN_STDOUTPUSHWYSP_ERRNOTOSLTAXEXITFUN ENTERFUN2d}INCSP2STAXYSP_COPENDECSP2LDAXYSP I M E N A L K E G e}NFF JLH N JLH/*4POPAX_FGETC_CGETCIORETURN @HIDEBf} VLC`` AR_ITOANEGAXPOPAX B BԆ A Ԇթ- ؠg}0L - )ȑ`$`_TPRINTF8NEGAXADDYSPHDEHI Bh V```8h}` ei "L % sdax&oV  L O " L i} " JJJJ)  ƒ&&&&L L tL t "Ԇ  AԆթ- ؠ0 j}L ) L t LB0123456789ABCDEF)0_ISDIGIT_ITOALDAI_STDERRSAVEAX_FPRINTFPUk}SHWAXILNEGAXPUSHBAXIPLOCYSPSUBYSP_STDINLOCYSPLDAXIENTERFUN_ATOIINCAX1Al}DDYSPTOSGTAXPUSHWYSP_STDOUT__PFGUTS_ERRNOTOSEQAXTSTAXSUBTOS_FPUTCINCSP4m}ADDTOSTOSNEAXASLAXTOSLTAXEXITFUNINCSP2STASPPDECSP4_ITOAB_PRINTFXSTAXYSPn}RESTAXDECSP2DECAX1_STRLEN_TOLOWERLDAXYSPPUSHAXDECAX2CASEJUMP N `# Io} I ^ \ M ^ \ `- ^ Y `& `, F `, `. `& `-  [L`  Np} `(TT `- I I ^ \ M ^ \ `- ^ Y `-  `!L`  N# Jq} `&% `, D `.% `& `' M `& `, B XL  `, H% ]3 `, D Pr} `& `' H) S Z `, P `&L L , `, P `& `, H% W0 `, D Ps} `& `' H) S Z `, P `&L  `, H- W `& `, P `&L t} `& `, H0 W 0 `&L   `& `, H @B `, D P `& `' `-u} O `& `, H @ `, P `&L L  `& `, H. W< `, P `v}& `- O `& `, H @ `, P `&L KL v `&% `, D `.% `& `' w}M! `& L `& `, D P `& `' H `+L r I# `, `" I \ `- x}`"L ! `, `&L ! S I AL ! S I `- `$L ! S I `- `$y}L ! S I `- `$L ! S I `- `$L  `,# QL` L  `/ c s z}d b o 0u IxL b S `* `& `, S `, _ X  `, `& S{} `, R S `, Y `&L  `& `, G X7 `, D `) `& `' X|} S) S Z `, P `&L  `, D `) `& `' X0 `, D P `& `' H}}) S Z `, P `&L ? `, X7 `, D `) `& `' X S) S Z `,~} P `&L L  `,# QL` a,E __PARSELI_MAINENTERFUN__ARGVPUSHWYSPEXITFUN}__MAINPUSHAX B D   G @ G   G ALE_ISDIGITLDAI}SAVEAXPUSHBAXIINCAX1_ATOIPUSHWYSPSUBTOSINCSP4ADDTOSMULTOS ENTERFUN1EXITFUN}_ISSPACEDECSP4STAXYSPRESTAXPUSHAXLDAXYSPCASEJUMP K N R C M R} D OL  O R AL P O R D OL ] S 7- @+ O R C @}= Q R J Q R B D O P A I Q0 G OL f F R J HLL}"2 _STDERR_FPUTS_STDIN_STDOUTPUSHWYSP_ERRNO_WRITEEXITFUN ENTERFUN2PUSHAX}_STRLEN H D D D J I FLG _STDERRSAVEAXLNEGAX_FGETC_STDI}NINCAX1TOSGTAX_STDOUTPUSHWYSP_ERRNOTOSEQAXTSTAX_FGETSINCSP4EXITFUN ENTE}RFUN3STASPPDECSP4STAXYSPRESTAXPUSHAXDECAX1LDAXYSP O Q R V U }R T FmL .L  H C R H JL  V B K  V R V A E} R S T V P H JL L + H P V MLNw. _STDERR_STDIN_}STDOUTPUSHWYSP_ERRNO_FGETS ENTERFUN1EXITFUN_GETSPUSHAX F C IAA }I ELGO&5PUSHWYSPTOSEQAX_ISCNTRL ENTERFUN1EXITFUNTOSULEAX C @ E} @ ALDN&5TOSGEAXPUSHWYSP ENTERFUN1EXITFUN_ISPRINTTOSLEAX B A} @ A~ ELCLNEGAXASRTOSPUSHBAXIINCAX1TOSGTAXPUSHWYSPTO}SEQAXTSTAXINCSP4ADDTOSTOSNEAXTOSLTAXEXITFUN ENTERFUN3STASPPDECSP4STAXYSP}ANDTOS_ITOXPUSHAXDECAX1LDAXYSP M O E D" E U T P I S} NL } E K U @ PL } E U I B J U C PL T U G}L  E Q P E A S Q P E K 0 PL 7 P E U} T P I S E U I N E FL L } U G" E U T P I S} NL  U HLL^LDAISAVEAXTOSGEAXPUSHBAXIINCAX1PUSHWYSP_ATOIBS}UBTOSINCSP4ADDTOSMULTOSEXITFUN ENTERFUN2_ISSPACEDECSP4STAXYSPANDTOSRESTAX}PUSHAXLDAXYSP L N O S C M S D OL  R S A D O Q} @ P O R0 BL  Ea B EW G OL  EA B E7 G} OL  E0 G O E S BL  E S J R S I OL , S HLK}Nj_ISALNUMTOSGEAXPUSHWYSP ENTERFUN1EXITFUNTOSLEAX C Bz E Ba A}B BZ E BA A  B9 E B0 ALDo _ISCONS}_STDERR_STDIN_STDOUTPUSHWYSP_ERRNOTOSEQAX ENTERFUN1EXITFUN G D FLH}[$7_ISALNUMLNEGAXPUSHWYSP_ISCNTRL ENTERFUN1EXITFUN_ISPUNCT D B @ A} B C ALE;H_STDERRSAVEAXASLTOSPUSHWAXI_OTOITOSGEAXPUSHBAXI_ST}DINLDAXIINCAX1_STDOUTPUSHWYSP_ERRNOSUBTOSSTAXSPPINCSP4ADDTOSTOSLTAXEXI}TFUN ENTERFUN2DECSP4STAXYSPANDTOSRESTAXPUSHAXLDAXYSPTOSLEAX S T U} K N Y F0 E X Y F7 Z VL  Y H U K B X Y A} I U W F0 M P U K E X Y C Q V  Y OLR Y A I} U W K Y NL  Y OLRxc LDAIPUSHBAXIINCAX1TOSEQAXSUBTOSEXI}TFUN ENTERFUN2STAXYSP_STRCMPLDAXYSP F I A I @ C5 I A CL}E I B G I B GL  I A I @ DLE _STDERRNEGAXPUSHWAXI}_UTOIPUSHBAXI_STDINLDAXIINCAX1_STDOUTPUSHWYSP_ERRNOTOSEQAXTSTAXSTAXSPP}INCSP4_DTOITOSLTAXEXITFUN ENTERFUN2DECSP4STAXYSPPUSHAXLDAXYSP R S V D}- K T V G TL 9 T I I C T U P  V NLQ V} B P  V NLQ V L) I V F A M V G T NLQL  V N}LQ NLQZNkTOSGEAXPUSHWYSPTOSEQAX ENTERFUN1EXITFUN_ISSPACETOSLEAX C A} F: A B" A F A @LDCp_STDERRNEGAX}MODTOSPUSHBAXILDAYSP_STDININCAX1TOSGTAX_STDOUTPUSHWYSPSTAYSP_ERRNOTOSEQ}AXTSTAXDIVTOSADDTOSTOSNEAXTOSLTAXEXITFUNINCSP1 ENTERFUN3STASPPSTAXYSPDE}CSP1PUSHAXDECAX1LDAXYSP_ITOD T W I Q Z A V- JL 6 J} I G" I Z Y V O X UL  I Q Z A VL  I }Z O C P Z F VL  Z MT I Z Y V O X I B X0} O U I N V X LL L  Z M  I Z Y V O X D U} I G" I Z Y V O X UL 5 Z SLRy3Q _PMALLOCADDTOS ENTERF}UN1EXITFUNINCSP2STAXYSPDECSP2LDAXYSPPUSHAX__HIMEM B FII EII} H G AII G DLC;J_STDERRSAVEAXPUSHWAXI_UTOITOSGEAXPUSHBAXI}_STDINLDAXIINCAX1_STDOUTPUSHWYSP_ERRNOSUBTOSSTAXSPPINCSP4ADDTOSTOSLTAX}MULTOSEXITFUN ENTERFUN2DECSP4STAXYSPANDTOSRESTAXPUSHAXLDAXYSPTOSLEAX S T} U J M Y E0 D X Y E9 Z VL  Y G U X Y }Q X Y A H U W E0 L O U J D X Y B P V  NLR} Y A H U W J Y ML  Y NLR&7 _STDERR_CLOSETOSGEAX_STDIN}_STDOUTPUSHWYSP_ERRNO_FCLOSE ENTERFUN1EXITFUNLDAXYSPPUSHAX H E A K} BL # JLICPUSHWYSP_ISASCII ENTERFUN1EXITFUNTOSULEAX B @ D}LCN&5_ISGRAPHTOSGEAXPUSHWYSP ENTERFUN1EXITFUNTOSLEAX C B! A B}~ ELDN&5_ISUPPERTOSGEAXPUSHWYSP ENTERFUN1EXITFUNTOSLEAX C BZ E} BA ALD%_ITOONEGAXASRTOSPUSHBAXIINCAX1TOSGTAXPUSHWYSP}TOSEQAXTSTAXADDTOSTOSNEAXTOSLTAXEXITFUNINCSP2 ENTERFUN3STASPPSTAXYSPANDTOS}DECSP2PUSHAXDECAX1LDAXYSP N R F E" F U T P I S OL }} F K U A PL } F U I C J U D PL T U Hg F} Q P F B S Q P F U T P I S F0 I O F G}L L } U H" F U T P I S OL  U MLL/b\LDAIMODTOS}PUSHWAXIPUSHBAXIPLOCYSPSUBYSPLOCYSPLDAXIADDYSPPUSHWYSPPUSHBYSPORTOSSTAXS}PPDIVTOSADDTOSASLAXMULTOS ENTERFUN1 ENTERFUN2EXITFUNSTASPP_GTIMEANDTOS_C}ALCTIMGLDAXYSPPUSHAX Q I @ T I N Y @ T I N Y @} TLS R E D  F XԆՠ8ԑԑԑ D O N Y D N C}? V Yd P Y@ M L D O N Y D N C V Y@ M Y D} N C V Y P K Y J V Y P K L D O N Y D }O N B< M L D O N Y D O N B< A L D D O N B}< M L D O N Y D O N B< A L I X T I N Y }D O N G T I N Y D O N G T I N Y D O N G} T HLS0SLDAI_STDERRSAVEAXASLTOSPUSHWAXIPUSHBAXI_STDININCAX1_XTOI}_STDOUTPUSHWYSP_ERRNOTOSEQAXSUBTOSSTAXSPPADDTOSINCSP6TOSLTAXEXITFUN ENT}ERFUN2STAXYSPDECSP6RESTAXPUSHAXLDAXYSPCASEJUMP S U J N T X T} X E0 L X G TL ! X @L 0 TL 7 TL W TL  J } X M PLRL  Y M0 M1 M2 M3 M4 M5 M6 M7 M8 M9 YA YB YC YD YE YF} ea eb ec ed ee efL q J Q X G TL  PLR J X D C} W X B G T V E X M O NL B PLRk/ _ISATTY_UDEVICELDAXIA}DDTOSASLAX ENTERFUN1EXITFUNLDAXYSPPUSHAX E H G D C BLFN&5}TOSGEAXPUSHWYSP ENTERFUN1EXITFUN_ISLOWERTOSLEAX B Az E Aa @}LCOjTOSGEAXPUSHWYSP ENTERFUN1EXITFUN _ISXDIGITTOSLEAX B Af E Aa} @B AF E AA @  A9 E A0 @LCNV_ST}DERRNEGAXASLTOSMODTOSASRTOSPUSHBAXI_STDININCAX1TOSGTAX_STDOUTPUSHWYSP_}ERRNOTOSEQAXTSTAXDIVTOSADDTOS_ITOUTOSNEAXTOSLTAXEXITFUNINCSP2 ENTERFUN3}STASPPSTAXYSPANDTOSDECSP2PUSHAXDECAX1LDAXYSP U Y J H" J \ [} W O Z VL } J R \ A WL } J \ O E Q \ G} WL T \ ML  J X W J D Z X W J \ [ W O Z} J C Z B Z \ O Z0 O V J N W Z LL L } \ }M" J \ [ W O Z VL  \ TLS5 _TOASCII ENTERFUN1EXITFUNLD}AXYSP A CLBvY} _OPENENTERFUNPUSHWYSPSTAYSPPUSHBYSPEXITFUNINCSP1_COPE}NANDTOSDECSP1 A I B H r CL D B H w CL D FLE }B D G FLE_STRCHRPUSH0PLOCYSPSUBYSPENTERFUNINCAX1ADDYSPPUSHWYS}P_STRCATEXITFUNSTAXYSP _FN_DEFAU_FRENAMELDAXYSPPUSHAX_RENAME DR CV G A} B K B"! N HT G: N @ J M E JL ]T M J B} G H B"! N H B LR FLI,?` _FDELETEPUSH0PLOCYSPSUBYSP}ENTERFUNADDYSPPUSHWYSP_DELETE_STRCATEXITFUN _FN_DEFAUPUSHAX DP CR F A} B J B"=!= K H B @P ELI_STRCHRPLOCYSPLNEGAXSUBYSP}ENTERFUNADDYSPPUSHWYSPTSTAX_STRCATEXITFUN _FN_DEFAULDAXYSPPUSHAX_STRCPY }DP CV F: L @ B2 A"! L M AX F HR F A ML _R F}X F MT K G%R F. L @ BR FV F HP ELID:k.F _READPUSHWYSP}DIVTOS_FREADMULTOSEXITFUN ENTERFUN4PUSHAXLDAXYSP F A A A H D} G @ G H BLEn;V PUSHWYSP_FWRITE_WRITEMULTOSEXITFUN ENTERFUN4PUSHAX}LDAXYSPTOSLEAX E @ @ @ G C F B F HLD GLD<\ __PA}RSELI_STDERR_FPUTS_STDIN_STDOUTPUSHWYSP_ERRNO_FGETSEXITFUN ENTERFUN3 _READARG}SPUSHAX I EAA K B EP KAA K G E E @LHc!3PUSHWY}SPADDTOS_STRCATEXITFUN ENTERFUN2PUSHAX_STRLEN_STRCPY D @ @ F A E} @ GLC__STDERRPOPAX_STDINFINDIOCB_STDOUT_ERRNOIORETURN_COPEN}@ iɀ` A A 0krwa dKJKHI})a0{8 DEB VL ``  `3/=POPAXFINDIOCB}IORETURN_FRENAME A  @ DE BJK VLB`3/=_FDELETEPOPAXFINDI}OCBIORETURN B  A DE!BJK VLC` _CLOSEALL B Vi}`' +_READIORETURN __RWSETUP B B VLA HHIh`* __FREELST __FREEM}EM__HIMEMA%_ISALPHAPOPAX AA[a{``POPAX _ISODIGIT} @08``_ISDIGITPOPAX A0:``POPAX_ISWHITE @)}!``/APOPAX_BZERO @ @ Ɠ Ē`9M}POPAX_BCOPY @ @ @ƓL Ē`"-=_STRCHRP}OPAXTSTAX A A`Œ eLBL _KBDCHAR ` %H$H`}POPAX_TOLOWER @A[i `POPAX_TOUPPER @a{8 `LDAI}SAVEAX_REVERSEINCAX1PUSHWYSPTOSULTAXSUBTOSINCSP4ADDTOS ENTERFUN1EXITFUNS}TASPPDECSP4STAXYSPRESTAXDECAX1LDAXYSPPUSHAX_STRLEN I L D D R H }Q F M D P EO P @ M P A C M N Q P @ K P A }O M N Q P KL % GLJdASLTOSMODTOSASRTOS_REVERSEPUSHBAXIINCAX1}PUSHWYSPTSTAXDIVTOSINCSP4ADDTOSTOSLTAXEXITFUN ENTERFUN3STASPPDECSP4STAXYS}P_ITOABANDTOSPUSHAXLDAXYSP M O T P F B P F R P F } B S R P F F T A S @ S T J N T D K T } S D0 J NL  T S D7 J N T E P F T H P GL ! F } N F C ILL-FPARGC_ATOFPOPAXRTN1FPN@@ B LC7] }GET1FPNFPARGCFC1RTN1FPN_CEILA @P)@) DL Z L Z)?, })  fLCo2 GET1FPNFPARGCTFP1_SINFCPIRTN1F }PN_COSFINTFC2PIFCP5FPERRL A @ ))Ԣ ݢ `ڐ } J^0\ ݢ (ې J fڐ J G ڐ J } `ڐ JL   ݢ",!, `ڐ J ڐ J"! @ݐ } J ILEV i9ww3GE`; gV'Us"=$0?ffgP@@W28GET1FPN }FPARGCRTN1FPN_EXPFPERRA @ ݐ DLB:GET1FPNFPARGCRTN1FPN_EXP1 }0FPERRA @ ݐ DLB/GET1FPNFPARGC_FABSRTN1FPNA @)LC9 }FPARGC_FADDRTN1FPNGET2FPNFPERR@ C fڐ DLB-)8FPARGC_FCMP }GET2FPNFPERR@ BE 0`` `ڐ C`!#1FPARGCPOPAX_FCPY@ }@ A@ A`9 .FPARGC_FDIVRTN1FPNGET2FPNFPERR@ C } D (ې DLBBaGET1FPNFPARGCFCN1_FLOORRTN1FPNFINT A @ LD }P)@) DL ` L `)?,ȩ)  f`9 }FPARGC_FMULRTN1FPNGET2FPNFPERR@ C ڐ DLB;/IFPARGCUSRERRPOPAX }ERRFLAG_FPERROR@@ BAA L + L +C`Ib!CLEANUPG }ET1FPNFSWAP|FPARGCTFC2_M_P5(FC0FC1 _M_2PI@USRERRU_M_PI8FCN1"POPAXTFP1H }TFP2N_EXIT_M_N1 ERRFLAGWADDYSP_M_10FCPI:_M_E0RTN1FPNGET2FPNFC10FC2PIBF }CP5*_M_2_M_0_M_1FPERRPUSHAXFCE2  @ @ @ " *?P 2 }@q :@e B@(11fp domain errorfp range error  Hh` T L } T L ` T L H h` T LR X Z WD+ B X i"\Di!\EHI V }LO hh"X!X _l U`/WsGET1FPNFPARGC_FRACRTN1FPNA @J)@F)? }; i,ƓL  )?Ԡ ԙ00LC DLC9FPARGCRTN1FPNGET2 }FPNFPERR_FSUB@ B `ڐ CLA-I\GET1FPNFPARGCPOPAX_FTOAAA B } @ آ0 -- ɀ)ȩ`6DZGET1FPNFPARGC_FTOISIG }NFPERRA @)C ) ٰ )L ( DCIԥIԐԦ`- GET1FPN }FPARGC_FTOUFPERRA @ ِ CԦ`UGET1FPNFPARGCTFP1TFP2TFP3 }RTN1FPN_HYPOTFPERRA @0L  G @0L 3 G } (ې G ݢ ݢ (ې G fڐ G ݢ f } ݢ f ݐ GLE68JFPARGCPOPAXRTN1FPNSIGN_ITOF@@ AԆ })Cԥ IԥI ٥ CLB8*GET1FPNFPARGCRTN1FPN_LOGFPERRA !}@0L  D LB:*GET1FPNFPARGC_LOG10RTN1FPNFPERRA @0L  "} D LCC-?GET1FPNFPARGCPOPAXRTN1FPN_POLYFPERRAA BA B #} @ @ݐ ELCB@VGET1FPNFPARGCPOPAXRTN1FPN_POWFPERRAA B $} @ E ަ ڐ E ݐ ELCB6NGET1FPNFPARGC_SQRTRTN1FPNFCP %}5FPERRA @ E ޢ ڐ E ݐ ELC-FPARGCPOPAX &}RTN1FPN_UTOF@@ AԆ LB ڐ E ݐ ELC-FPARGCPOPAX0/*\____________________________________ * * Floating point math for cc65 * by Duane Tribe * * ERROR.H * _______________ (}_____________________\*//* Useful definitions for user error * processing */char *fpnames[] = { "atof", "ftoa", "u )}tof", "ftou", "itof", "ftoi", "fadd", "fsub", "fmul", "fdiv", "exp", "exp10", "log", "log10", "fcpy", "fabs", *} "pow", "sqrt", "fcmp", "floor", "ceil", "poly", "hypot", "sin", "cos", "tan", "asin", "acos", "atan", "fmod", +} "frac", "trunc"};mp", "floor", "ceil", "poly", "hypot", "sin", "cos", "tan", "asin", "acos", "atan", "fmod",  f2Lf%HehL!`ܠؠԠРH8咅h`H8h`֠ҠΠʠƠ±-}HȱhL!``e` L L!L!L!L!L!L! ȘL! L! M Hȑh`HȱhL .}HȱhL Hȱh ` ` .!HȥhL! .!L! `HȑhL!L!HH hhL!HH /}hhL! H*h`L!`L!`HIhIi```IHIh`e` !L `0}` !L! !L! !L! ! !L ! !L  &L!L! 󨥂fjL! eHehL! 1}8H哪hL! HhL! EHEhL! %H%hL!`\_ łXTM łFBE 0>7ł86/ 䃐-&ł2}'% 0ł 䃐 ł`` 0ł 䃐ł۰ 0łʰ 䃐ł𹰼 3}L H hL lHh` !L !L hh捠ilŕŔ 4}liL#`L!  ! Ɣ !$ \$& $ \$& 򦓥 !`H5}eeh`` ! ! ! !Ńł &&L$FfFf3ō6}Ō8包卅FfFfͥ !ĕ !` t$L! ` 7}`S L L L i?H ihL%  ..l %%@%@%%?8}P%@q%@e ` ` % آ0 --Ƚɀ)9}` Ԇ L& % ٥Ԧ` ԆՊ)%ԥեIԥI ٥ %L& %)%) ٭%IԥIԐ:}Ԧ` % fL& % `L& % L& % (L& % L& % L& % L& % L& ` %)L& % ;}ަ L& % ޢŠ% L& % ޢՠ% L& % `ک`P)@) DL'͠% L')?,ȩ<}) ͠% f` % 'L& %P)@) DLJ(% LJ()?,ȩ) % =} fL& k# M M(  u  }! Y" !  &) M( ! "  ) B! u  "GL( u # >} B! $L( ) M(  u Y" ! "  )L( Z.[.  ))  Lq#0x%02X, 0x%02X HHIDE?} Bh VL.` k# a    }! Y" ! }! Y"  }! h" B! u # u  B!  ) # Lq# k# M Z.[.  @}   }! Y" ! }! Y"  }! h"  )  Lq# k## 7  B!% u # % B! $ ! B! u ! !L. u #%A} "3 u #  B! $ #) ! )) u  B!L*L* u  B! u #% "0 u #  B! $ #) ! )) u B}  B!L* u #- " B! u  B!L* B! u #0 " 0 B!L+  B! u # |0B u # C} B! $  / B! u # |0 u  B!LI+Lt+ B! u #. "< u  B!  / B! u # |0 uD}  B!L+L+ B!% u # % B! $ !! B!  B! u #  B! $ # 0L, # u i!  Y" iE}!L,! u  B!L,! !  x/L,! !   0L,! !   0L,! !  0L,! !  F}  0L, u #  Lq#L, # ,c3,s@,dR,bk,o,u,xL, ! M% B! u  ! u " !  u  B! !G} u # ! u h" B!LO- B! u ! !7 u #  B! $ ! !) ! )) u  B!L\- u #  B! $H} !0 u #  B! $ #) ! )) u  B!L- u !7 u #  B! $ ! !) ! )) u  B!L-L* uI} #  Lq# k# !,.-.  . ,.-.  S(Lq#@ iɀ` `.0krwa J}dKJKHI)a0{8 驛DEB VL.``^._.` NK}HɛD l/ȥi揠 l/Hhɛ`!8`` Ԇ !Ԇթ-L} ؠ0L/)ȑ` Y# a  u # 1 u  B!L/ B! u !L 0 B! u  B!L0 #/-/+M} B! u # |0=  u $  u #  B! $ ! Y" 0 h" B!L0 ! u $ # Lq# 0:`` AN}[i ` a# a  u  B! ! 8" B! ! " B! ! 8"  " B! ! ! u #%  "  u Y" i!O} u # " u #0 Y" i!LO1 u #7 Y" i! u  B! ! u t$ B! !L0 ! i! ! 1 # LP}q# Y# ! ": ! "" ! " ! 3#Lq# Y# a  ! ! M% Y"  h" B! ! Q}u "O u ! B! u #  B! $  u ! i! u #  B! $  u i!L2 # Lq# % Y"  h" B! ! bFP65 - FP math for CC65, V1.0 February 1993 Duane Tribe 120 112th st. Orofino, ID 83544 This archive contains the files forS} the FP65 package, which provides CC65 functions for most common floating-point operations. The files are in Atari format (iT}.e. newline=155). These files are Copyright 1993 by Duane Tribe. They may be freely distributed so long as all the files (iU}ncluding this one) remain in their original form. No fee, other than a nominal media charge, may be required to distribute tV}hese files. There is no waranty of any kind for this software. All other rights reserved. MANIFEST C0F1.OLB 264W}23 5 Feb 93 2:16p ERROR.H 521 8 May 90 12:13a EXPOSE.COM 4723 6 Feb 93 2:06p FP65DOC.ESC X} 19288 24 Feb 93 2:45p FP65DOC.TXT 18452 24 Feb 93 2:52p MATH.H 2386 24 Feb 93 3:48p QUICKREFY}.TXT 1898 10 Feb 93 1:50p README 1857 24 Feb 93 3:52p SUM.BAT 55 5 Feb 93 2:49p SZ}UM.C 283 5 Feb 93 2:43p SUM.LNK 35 5 Feb 93 2:45p 55 5 Feb 93 2:49p SW hpGFP65 - Floating-Point Math for CC65Hph Copyright 1992 by Duane Tribe. pW\}OVERVIEWWp FP65 provides C functions that manipulate floating-point (FP) numbers using the code and data]} format of the Atari ROMs. FP65 is similar to the ACE-C runtime package because neither CC65 nor ACE-C direct^}ly supports FP data. The speed of the functions is comparable to BASIC because both Atari BASIC and FP65 use the same R_}OM routines to perform the FP math. The FP65 functions are in the object library file C0F1.OLB which rep`}laces the file C.OLB from the CC65 distribution. The functions are: fcmp Compare two floats fca}py Copy floats atof, ftoa ASCII-float conversion utof, ftou Unsigned integer-float conversion b} itof, ftoi Signed integer-float conversion fadd, fsub Add, subtract floats fmul, fdiv Multiply, divc}ide floats exp, exp10 Raise e (2.71828...), 10.0 to a power log, log10 Find natural (base e), common (basd}e 10) logarithm pow Raise a float to a power sqrt Find square root of a float hypote} Find hyponenuse given length of two sides sin, cos Find sine, cosine of an angle floor,ceil Findf} nearest whole float equal or less, greater frac Find fractional portion of a float fabs Findg} absolute value of a float poly Calculate float polynomial fperror Control error behavior q}B%DOS SYSB*)DUP SYSBSC0F1 OLBB'ERROR H B&,EXPOSE COMB RFP65 TEXB[FP65DOC ESCBFP65DOC TXTBMATH H BQUICKREFTXTBREADME BSUM BATBSUM C BSUM LNK The FP65 functions in the file C0F1.OLB and the rest of the FP65 archive are copyright 1992 by Duane Tribe. See thr}e file README for details. The non-FP65 functions in C0F1.OLB are from the CC65 distribution's C.OLB file and are s}"copyleft" by John R. Dunning. Refer to the file COPYLEFT.JRD in the CC65 distributions for details. t}pWUSING FLOATING-POINT MATHWp First, 4do not use FP math5 unless it is required. Not only is it less u} convenient than integer math, it is also 4much5 slower. FP65 provides functions for algorithms where only FP math wv}ill do. Like all other C compilers currently available for the 8-bit Atari, CC65 does not directly support flw}oats. Instead of the usual float fpvar; /* not in CC65 */ storage for FP variables is declared asx} a six-byte character array page 1/10 FP65 versioy}n 1.0, 1992 Using FP Math char fpvar[6]; Also, you cannot direz}ctly use FP constants such as f = 1.2345; /* not in CC65 */ The FP constant -1.2345- must be c{}onverted to the internal six-byte format. This can be done indirectly via atof(f, "1.2345"); |}or directly via a C declaration such as char f[6] = { 0x40, 0x01, 0x23, 0x45, 0x00, 0x00 }; The lat}}ter version is faster (the compiler does all the work), but cannot be repeated. Use the supplied program EXPOSE.COM to ~}generate the values. Common FP operations, such as f = a + b; /* not in CC65 */ }are done via function calls. In this instance, fadd(f, a, b); is used instead. Complex expressi}ons must be broken down to the individual operations, and storage provided for all of the intermediate values. For} example, the C statement f = (1.0 / a) + (2.0 * b); /* not in CC65 */ would be implemented via } fdiv(f, M_1, a); fmul(temp, M_2, b); fadd(f, f, temp); Due to the nature of the ROM} FP format, the sign of an FP value can be manipulated via C bitwise operations: *f /* true if }f != 0.0 */ *f & 0x80 /* true if f < 0.0 */ *f &= 0x7F; /* make f positive */ } *f |= 0x80; /* make f negative */ *f ^= 0x80; /* invert sign of f */ When using this trick, }be sure to include comments that indicate your intent. } page 2/10 FP65 version 1.0, 1992 Using the FP65 Package pWUSING T}HE FP65 PACKAGEWp First, include the file MATH.H into your C program. Then, link the program with the C0}F1.OLB file instead of the usual C.OLB. For example, here is a program called SUM.C that will print the sum of two } numbers on the SpartaDOS or DOS-XL command line: #include "stdio.h" #include "math.h" } main (argc, argv) int argc; char *argv[]; { char buf[20]; char f1[6], f2[6]}; atof(f1, argv[1]); atof(f2, argv[2]); fadd(f1, f1, f2); print}f("%s + %s = ", argv[1], argv[2]); fputs(ftoa(buf, f1), stdout); fputc('\n', stdout); } } Also needed is the SUM.LNK file: D:RUNTIME.OBJ D:SUM.OBJ D:C0F1.OLB This ass}umes all the files are on the same disk and in the same directory. Then, issue the commands: CC65 SUM.C} RA65 SUM.M65 LN65 -O SUM.COM @SUM.LNK pWFLOATING-POINT CONSTANTSWp FP65} provides nine FP values already in the six-byte ROM format. Use the names as you would any FP variable, except 4never}5 assign a value to them. They are M_0 0.0 zero M_1 1.0 one} M_2 2.0 two M_10 10.0 ten M_N1 -1.0 negati}ve one M_P5 0.5 point five M_E 2.718281828 e M_PI 3.14159265}4 pi M_2PI 6.283185308 2*pi page }3/10 FP65 version 1.0, 1992 FP Constants These constants are declared} in the include file MATH.H. Other less-often used standard C constants are provided as C initialized declarations}: M_LOG2E 1.44269504 log2(e) M_LOG10E 0.4342944819 log10(e) M_LN2 0.693147180}6 log(2) M_LN10 2.30258509 log(10.0) M_PI_2 1.57079632 pi/2 M_PI_4 0.7}853981634 pi/4 M_1_PI 0.3183098862 1/pi M_2_PI 0.6366197724 2/pi M_2_SQRTPI 1.}128379167 2/sqrt(pi) M_SQRT2 1.41421356 sqrt(2) M_SQRT1_2 0.7071067812 sqrt(1/2) } M_MIN 1E-98 Minimum value M_MAX 9.999999999E99 Maximum value M_EPSILON 1E-9 } Accuracy limit To activate these extra constants, define the symbol FP65_CDEF before including MATH.H:} #define FP65_CDEF #include "math.h" See the file MATH.H for further details. } pWERROR CHECKINGWp Errors are detected where possible. The default action on an error is to prin}t a message and exit to DOS. You can also have FP65 ignore the error, or you can handle the error yourself. See the -}fperror- description below. If the error is detectable before the call to the OS ROM routine, then a }"domain error" is generated. If the ROM routine returns an error condition, a "range error" is generated. } pWPARAMETERS AND ACE-CWp Although many FP65 functions look just like ACE-C functions, their use i}s slightly different. The result value is always stored via the 4first5 parameter. This is based on how the expressi}on would look in a true C float expression. For example, the C float expression a = b + c; /* not in CC}65 */ implemented in ACE-C as fadd(b, c, a); /* ACE-C, not FP65 */ is implemented in FP}65 as fadd(a, b, c); page 4/10 FP6}5 version 1.0, 1992 Parameters and ACE-C Functions that have an FP result return fro}m their name the the value of the first parameter, the pointer to where the resulting value is stored. This return} value is for convenience only and can be ignored. Two functions available in ACE-C have C-style names in FP6}5: -log10- (ACE-C calls it "clog") and -pow- (ACE-C calls it "exp"). Also, ACE-C has two functions "ftoi" }and "itof" which really deal only in unsigned integers; the corresponding FP65 functions are -ftou- and -utof-.} pWCONVERSION FUNCTIONSWp GatofH char *atof (fpn, str) char fpn[6], str[}]; Converts C-style ASCII string at -str- to FP number at -fpn-. Stops converting at the first non-F}P character. Note that when using exponential notation the "E" 4must5 be in upper case. Returns -fpn-. } GftoaH char *ftoa (str, fpn) char str[], fpn[6]; Converts FP number at -fpn- to ASCII in b}uffer pointed to by -str-. Required to print out a number. Note that 1x10^8 will convert to the string "1E8",} but 1x10^9 will convert to the string "1.0E9". The buffer must be big enough to hold the number and terminating NULL, }at least 17 bytes. Returns -str-. GutofH char *utof (fpn, i) char fpn[6]; int i;} Convert unsigned integer -i- [0..65535] to FP number at -fpn-. Returns -fpn-. Gftou}H int ftou (fpn) char fpn[6]; Return unsigned integer [0..65535], converted from the FP number -}fpn-, rounded off by the ROM routine to the nearest integer. } page 5/10 FP65 version 1.0, 1992 Conversion Functions Gitof}H char *itof (fpn, i) char fpn[6]; int i; Convert signed integer -i- [-16385..16384] to }FP number at -fpn-. Returns -fpn-. GftoiH int ftoi (fpn) char fpn[6]; R}eturn signed integer [-16385..16384] converted from FP number -fpn-, rounded off by the ROM routine to the nearest i}nteger. pWARITHMETIC FUNCTIONSWp The names for these functions and the "True-C" notation }should make them self explanatory. Their arguments may be repeated, i.e. fadd(a, a, b); /* a += b; */} GfaddH char *fadd (dst, f1, f2) char dst[6], f1[6], f2[6]; Floating-point addition. }True-C: -dst = f1 + f2;- Returns -dst-. GfsubH char *fsub (dst, f1, f2) char dst[6], f1}[6], f2[6]; Floating-point subtraction. True-C: -dst = f1 - f2;- Returns -dst-. GfmulH } fmul (dst, f1, f2) char dst[6], f1[6], f2[6]; Floating-point multiplication. True-C: -dst = f1 * f2};- Returns -dst-. GfdivH char *fdiv (dst, f1, f2) char dst[6], f1[6], f2[6]; F}loating-point division. True-C: -dst = f1 / f2;- Returns -dst-. } page 6/10 FP65 version 1.0, 1992 Logarithm and Exponentiation } pWLOGARITHM AND EXPONENTIATIONWp If you have a choice between using the base e functions (-exp- and} -log-) and the base 10 functions (-exp10- and -log10-), use the base 10 functions. They are faster. } GexpH char *exp (dst, fpn) char dst[6], fpn[6]; Calculate e raised to the -fpn- po}wer, storing the result in -dst-. Returns -dst-. Gexp10H char *exp10 (dst, fpn) ch}ar dst[6], fpn[6]; Calculate 10.0 raised to the -fpn- power, storing the result in -dst-. Returns -}dst-. GlogH char *log (dst, fpn) char dst[6], fpn[6]; Calculate the natural (base }e) logarithm of -fpn-, storing the result in -dst-. Returns -dst-. Glog10H char *lo}g10 (dst, fpn) char dst[6], fpn[6]; Calculate the common (base 10) logarithm of -fpn-, storing the result} in -dst-. Returns -dst-. GpowH char *pow (dst, x, y) char dst[6], x[6], y[6]; } Find -x- raised to the -y- power, storing the result in -dst-. Only generates domain error if a com}plex number would result. Returns -dst-. GsqrtH char *sqrt (dst, fpn) char dst[6], fpn}[6]; Find square root of -fpn-, storing the result in -dst-. Returns -dst-. } page 7/10 FP65 version 1.0, 1992 Logarithm and }Exponentiation GhypotH char *hypot (dst, f1, f2) char dst[6], f1[6], f2[6]; Calculates t}he length of the hypotenuse of a right triangle with -f1- and -f2- as the two other sides, storing the result in} -dst-. Written to minimize range (overflow) errors, so may be slower than doing it by hand. Returns -dst-}. pWTRIGONOMETRYWp These functions work only in radians. GsinH c}har *sin (dst, fpn) char dst[6], fpn[6]; Computes the sine of -fpn- and stores the result at -dst-. }Returns -dst-. GcosH char *cos (dst, fpn) char dst[6], fpn[6]; Computes the cosin}e of -fpn- and stores the result at -dst-. Returns -dst-. pWINTEGER PORTIONWp } The first two functions have their proper C names that may be unfamiliar. Think of the real number line as runni}ng vertical in a multi-story building, with the integer numbers marking the floors (and ceilings). Since these fun}ctions do not use the ROM integer-FP routines, they are valid for any size or sign and do not round up or down. } GfloorH char *floor (dst, fpn) char dst[6], fpn[6]; Finds the largest whole FP number th}at is less than or equal to -fpn- and stores it at -dst-. (Drop the number down to the floor.) Returns -}dst-. GceilH char *ceil (dst, fpn) char dst[6], fpn[6]; Finds the smallest whole F}P number that is greater than or equal to -fpn- and stores it at -dst-. (Raise the number up to the ceiling.) } page 8/10 FP65 version 1.0, 1992 } Integer Portion Returns -dst-. GfracH char *frac (dst, fpn) char dst}[6], fpn[6]; Finds the fractional portion of -fpn- and stores it at -dst-. The value returned is alw}ays positive. Returns -dst-. pWGENERAL FP FUNCTIONSWp GfcpyH char *fcpy} (dst, fpn); char dst[6], fpn[6]; Copy FP number from -fpn- to -dst-. Returns -dst-. }GfabsH char *fabs (dst, fpn); char dst[6], fpn[6]; Store absolute value of -fpn- in -dst-}. Returns -dst-. Can be used as fabs(f, f); to make f positive. This can be accomplished in} C via bitwise operators, see "Using Floating-Point Math" above. GfcmpH int fcmp (f1, f2) }char f1[6], f2[6]; Compare the two FP numbers -f1- and -f2-. Returns integer giving the result of th}e comparison, as with -strcmp-: Negative: -f1 < f2- Zero: -f1 == f2- Positiv}e: -f1 > f2- The magnitude of the result, other than zero, is meaningless. GpolyH char} *poly (dst, x, coef, n) char dst[6], x[6], coef[6][]; int n; Calculates the value of the -n--degree} polynomial at -x- and stores the result at -dst-. The coeficients are passed in the array -coef- in d}escending order. Returns -dst-. This routine is very suceptable to overflow errors. It works best with small, fra}ctional coeficients. page 9/10 FP65 version 1.0,} 1992 General FP Functions See the file POLYEX.C for an example. GfperrorH } fperror (matherr) int (*matherr)(); Controls how errors are handled. The value of -matherr- is }either: 1. 0 ($0000) When an error occurs, the program will print a message indicating the error and ex}it to DOS. This is the default. 2. -1 ($FFFF) All FP errors will be ignored. The offending function will li}mp along the best it can, with unpredictable results. 3. A pointer to a C function that will be called to handle the er}ror. The function will be passed one argument, a pointer to the exception structure }struct exception { int fp_type; int fp_name; }; co}ntaining data about the error. The error-handling function will take the place of the offending F}P65 function, sending its 4integer5 return value to the 4caller5 of the offending FP65 function. In }-struct exception-, the value of fp_type is either 0 domain error 1 range error The value o}f fp_name is one of 0 atof 7 fsub 14 fcpy 21 poly 28 atan 1 ftoa 8 fmul 1}5 fabs 22 hypot 29 fmod 2 utof 9 fdiv 16 pow 23 sin 30 frac 3 ftou } 10 exp 17 sqrt 24 cos 31 trunc 4 itof 11 exp10 18 fcmp 25 tan 5 ftoi } 12 log 19 floor 26 asin 6 fadd 13 log10 20 ceil 27 acos Function codes 25 }through 29 and 31 are reserved for future expansion. See the file ERROR.C for an example of -fperror- in use. } } page 10/10 & FP65 - Floating-Point Math for CC65 Copyright 1992 by Duane Tribe. OVERVIEW F}P65 provides C functions that manipulate floating-point (FP) numbers using the code and data format of the Atari ROMs. } FP65 is similar to the ACE-C runtime package because neither CC65 nor ACE-C directly supports FP data. The sp}eed of the functions is comparable to BASIC because both Atari BASIC and FP65 use the same ROM routines to perform }the FP math. The FP65 functions are in the object library file C0F1.OLB which replaces the file C.OLB from th}e CC65 distribution. The functions are: fcmp Compare two floats fcpy Copy floats } atof, ftoa ASCII-float conversion utof, ftou Unsigned integer-float conversion itof, ftoi Signed inte}ger-float conversion fadd, fsub Add, subtract floats fmul, fdiv Multiply, divide floats exp, exp}10 Raise e (2.71828...), 10.0 to a power log, log10 Find natural (base e), common (base 10) logarithm pow} Raise a float to a power sqrt Find square root of a float hypot Find hyponenuse given } length of two sides sin, cos Find sine, cosine of an angle floor,ceil Find nearest whole float equal o }r less, greater frac Find fractional portion of a float fabs Find absolute value of a float  } poly Calculate float polynomial fperror Control error behavior The FP65 functions in t }he file C0F1.OLB and the rest of the FP65 archive are copyright 1992 by Duane Tribe. See the file README for detai }ls. The non-FP65 functions in C0F1.OLB are from the CC65 distribution's C.OLB file and are "copyleft" by John R. Dunnin}g. Refer to the file COPYLEFT.JRD in the CC65 distributions for details. USING FLOATING-POINT MATH } First, do not use FP math unless it is required. Not only is it less convenient than integer math, it is also m}uch slower. FP65 provides functions for algorithms where only FP math will do. Like all other C compilers cu}rrently available for the 8-bit Atari, CC65 does not directly support floats. Instead of the usual float} fpvar; /* not in CC65 */ storage for FP variables is declared as a six-byte character array } page 1/10 FP65 version 1.0, 1992 Us}ing FP Math char fpvar[6]; Also, you cannot directly use FP constants such as f =} 1.2345; /* not in CC65 */ The FP constant 1.2345 must be converted to the internal six-byte format. This c}an be done indirectly via atof(f, "1.2345"); or directly via a C declaration such as } char f[6] = { 0x40, 0x01, 0x23, 0x45, 0x00, 0x00 }; The latter version is faster (the compiler does all the work)}, but cannot be repeated. Use the supplied program EXPOSE.COM to generate the values. Common FP operati}ons, such as f = a + b; /* not in CC65 */ are done via function calls. In this instance, } fadd(f, a, b); is used instead. Complex expressions must be broken down to the individual operati}ons, and storage provided for all of the intermediate values. For example, the C statement f = (1.0 / a)} + (2.0 * b); /* not in CC65 */ would be implemented via fdiv(f, M_1, a); fmul(temp, M_2,} b); fadd(f, f, temp); Due to the nature of the ROM FP format, the sign of an FP value can be manipu}lated via C bitwise operations: *f /* true if f != 0.0 */ *f & 0x80 /* true if f <} 0.0 */ *f &= 0x7F; /* make f positive */ *f |= 0x80; /* make f negative */  } *f ^= 0x80; /* invert sign of f */ When using this trick, be sure to include comments that indicate your in!}tent. page 2/10 FP65 version 1.0, 1992 "} Using the FP65 Package USING THE FP65 PACKAGE First, include the file MATH.H in#}to your C program. Then, link the program with the C0F1.OLB file instead of the usual C.OLB. For example, here is$} a program called SUM.C that will print the sum of two numbers on the SpartaDOS or DOS-XL command line: #%}include "stdio.h" #include "math.h" main (argc, argv) int argc; char *argv[]; &} { char buf[20]; char f1[6], f2[6]; atof(f1, argv[1]); atof(f2, argv[2])'}; fadd(f1, f1, f2); printf("%s + %s = ", argv[1], argv[2]); fputs(ftoa(buf, f1),(} stdout); fputc('\n', stdout); } Also needed is the SUM.LNK file: D:RUNTIME.OBJ)} D:SUM.OBJ D:C0F1.OLB This assumes all the files are on the same disk and in the same direc*}tory. Then, issue the commands: CC65 SUM.C RA65 SUM.M65 LN65 -O SUM.COM @SUM.LNK +} FLOATING-POINT CONSTANTS FP65 provides nine FP values already in the six-byte ROM format. Use the nam,}es as you would any FP variable, except never assign a value to them. They are M_0 0.0 zer-}o M_1 1.0 one M_2 2.0 two M_10 10.0 ten.} M_N1 -1.0 negative one M_P5 0.5 point five M_E 2.7182/}81828 e M_PI 3.141592654 pi M_2PI 6.283185308 2*pi 0} page 3/10 FP65 version 1.0, 1992 FP Constants1} These constants are declared in the include file MATH.H. Other less-often used standard C constants are 2}provided as C initialized declarations: M_LOG2E 1.44269504 log2(e) M_LOG10E 0.4342944819 3} log10(e) M_LN2 0.6931471806 log(2) M_LN10 2.30258509 log(10.0) M_PI_2 1.4}57079632 pi/2 M_PI_4 0.7853981634 pi/4 M_1_PI 0.3183098862 1/pi M_2_PI 05}.6366197724 2/pi M_2_SQRTPI 1.128379167 2/sqrt(pi) M_SQRT2 1.41421356 sqrt(2) M_S6}QRT1_2 0.7071067812 sqrt(1/2) M_MIN 1E-98 Minimum value M_MAX 9.999999999E99 Ma7}ximum value M_EPSILON 1E-9 Accuracy limit To activate these extra constants, define the symb8}ol FP65_CDEF before including MATH.H: #define FP65_CDEF #include "math.h" See the fil9}e MATH.H for further details. ERROR CHECKING Errors are detected where possible. The default act:}ion on an error is to print a message and exit to DOS. You can also have FP65 ignore the error, or you can handle ;}the error yourself. See the fperror description below. If the error is detectable before the call to the OS <}ROM routine, then a "domain error" is generated. If the ROM routine returns an error condition, a "range error" is=} generated. PARAMETERS AND ACE-C Although many FP65 functions look just like ACE-C functions, the>}ir use is slightly different. The result value is always stored via the first parameter. This is based on how the?} expression would look in a true C float expression. For example, the C float expression a = b + c; /* @}not in CC65 */ implemented in ACE-C as fadd(b, c, a); /* ACE-C, not FP65 */ is implemenA}ted in FP65 as fadd(a, b, c); page 4/10B} FP65 version 1.0, 1992 Parameters and ACE-C Functions that have an FP result rC}eturn from their name the the value of the first parameter, the pointer to where the resulting value is stored. ThD}is return value is for convenience only and can be ignored. Two functions available in ACE-C have C-style namE}es in FP65: log10 (ACE-C calls it "clog") and pow (ACE-C calls it "exp"). Also, ACE-C has two functions "ftoi" andF} "itof" which really deal only in unsigned integers; the corresponding FP65 functions are ftou and utof. G} CONVERSION FUNCTIONS atof char *atof (fpn, str) char fpn[6], str[]; Converts C-style H}ASCII string at str to FP number at fpn. Stops converting at the first non-FP character. Note that when using expI}onential notation the "E" must be in upper case. Returns fpn. ftoa char *ftoa (str, fpn) char strJ}[], fpn[6]; Converts FP number at fpn to ASCII in buffer pointed to by str. Required to print out a number. K} Note that 1x10^8 will convert to the string "1E8", but 1x10^9 will convert to the string "1.0E9". The buffer mustL} be big enough to hold the number and terminating NULL, at least 17 bytes. Returns str. utof charM} *utof (fpn, i) char fpn[6]; int i; Convert unsigned integer i [0..65535] to FP number at fpn. ReturnsN} fpn. ftou int ftou (fpn) char fpn[6]; Return unsigned integer [0..65535], converteO}d from the FP number fpn, rounded off by the ROM routine to the nearest integer. P} page 5/10 FP65 version 1.0, 1992 Conversion FunctiQ}ons itof char *itof (fpn, i) char fpn[6]; int i; Convert signed integer i [-16385..16R}384] to FP number at fpn. Returns fpn. ftoi int ftoi (fpn) char fpn[6]; Return siS}gned integer [-16385..16384] converted from FP number fpn, rounded off by the ROM routine to the nearest integer. T} ARITHMETIC FUNCTIONS The names for these functions and the "True-C" notation should make them selfU} explanatory. Their arguments may be repeated, i.e. fadd(a, a, b); /* a += b; */ fadd V} char *fadd (dst, f1, f2) char dst[6], f1[6], f2[6]; Floating-point addition. True-C: dst = f1 + f2; ReturnW}s dst. fsub char *fsub (dst, f1, f2) char dst[6], f1[6], f2[6]; Floating-point subtractX}ion. True-C: dst = f1 - f2; Returns dst. fmul fmul (dst, f1, f2) char dst[6], f1[6], f2[6]; Y} Floating-point multiplication. True-C: dst = f1 * f2; Returns dst. fdiv char *fdiv (dst, f1, fZ}2) char dst[6], f1[6], f2[6]; Floating-point division. True-C: dst = f1 / f2; Returns dst. [} page 6/10 FP65 version 1.0, 1992 \} Logarithm and Exponentiation LOGARITHM AND EXPONENTIATION If you have a choice between using the base e f]}unctions (exp and log) and the base 10 functions (exp10 and log10), use the base 10 functions. They are faster. ^} exp char *exp (dst, fpn) char dst[6], fpn[6]; Calculate e raised to the fpn power, storin_}g the result in dst. Returns dst. exp10 char *exp10 (dst, fpn) char dst[6], fpn[6]; `} Calculate 10.0 raised to the fpn power, storing the result in dst. Returns dst. log char *log a}(dst, fpn) char dst[6], fpn[6]; Calculate the natural (base e) logarithm of fpn, storing the result in db}st. Returns dst. log10 char *log10 (dst, fpn) char dst[6], fpn[6]; Calculate the commoc}n (base 10) logarithm of fpn, storing the result in dst. Returns dst. pow char *pow (dst, x, y) d} char dst[6], x[6], y[6]; Find x raised to the y power, storing the result in dst. Only generates domain e}error if a complex number would result. Returns dst. sqrt char *sqrt (dst, fpn) char dst[6],f} fpn[6]; Find square root of fpn, storing the result in dst. Returns dst. g} page 7/10 FP65 version 1.0, 1992 Logarithm and Exponentiationh} hypot char *hypot (dst, f1, f2) char dst[6], f1[6], f2[6]; Calculates the length of the hi}ypotenuse of a right triangle with f1 and f2 as the two other sides, storing the result in dst. Written to minimizj}e range (overflow) errors, so may be slower than doing it by hand. Returns dst. TRIGONOMETRY k} These functions work only in radians. sin char *sin (dst, fpn) char dst[6], fpn[6]; Cl}omputes the sine of fpn and stores the result at dst. Returns dst. cos char *cos (dst, fpn) char m}dst[6], fpn[6]; Computes the cosine of fpn and stores the result at dst. Returns dst. INTEGn}ER PORTION The first two functions have their proper C names that may be unfamiliar. Think of the real numbeo}r line as running vertical in a multi-story building, with the integer numbers marking the floors (and ceilings). p}Since these functions do not use the ROM integer-FP routines, they are valid for any size or sign and do not round up orq} down. floor char *floor (dst, fpn) char dst[6], fpn[6]; Finds the largest whole Fr}P number that is less than or equal to fpn and stores it at dst. (Drop the number down to the floor.) Returns dsts}. ceil char *ceil (dst, fpn) char dst[6], fpn[6]; Finds the smallest whole FP number tht}at is greater than or equal to fpn and stores it at dst. (Raise the number up to the ceiling.) u} page 8/10 FP65 version 1.0, 1992 Integerv} Portion Returns dst. frac char *frac (dst, fpn) char dst[6], fpn[6]; Finds thew} fractional portion of fpn and stores it at dst. The value returned is always positive. Returns dst. x}GENERAL FP FUNCTIONS fcpy char *fcpy (dst, fpn); char dst[6], fpn[6]; Copy FP number fry}om fpn to dst. Returns dst. fabs char *fabs (dst, fpn); char dst[6], fpn[6]; Store absz}olute value of fpn in dst. Returns dst. Can be used as fabs(f, f); to make f positive. This can {}be accomplished in C via bitwise operators, see "Using Floating-Point Math" above. fcmp int fcmp |}(f1, f2) char f1[6], f2[6]; Compare the two FP numbers f1 and f2. Returns integer giving the result of }}the comparison, as with strcmp: Negative: f1 < f2 Zero: f1 == f2 Positive: f1 > f2 ~} The magnitude of the result, other than zero, is meaningless. poly char *poly (dst, x, coef, n) } char dst[6], x[6], coef[6][]; int n; Calculates the value of the n-degree polynomial at x and stores the} result at dst. The coeficients are passed in the array coef in descending order. Returns dst. This routine is ve}ry suceptable to overflow errors. It works best with small, fractional coeficients. } page 9/10 FP65 version 1.0, 1992 General FP Functions} See the file POLYEX.C for an example. fperror fperror (matherr) int (*matherr)(); } Controls how errors are handled. The value of matherr is either: 1. 0 ($0000) When an error occurs, the progra}m will print a message indicating the error and exit to DOS. This is the default. 2. -1 ($FFFF) All FP error}s will be ignored. The offending function will limp along the best it can, with unpredictable results. 3. A p}ointer to a C function that will be called to handle the error. The function will be passed one argument, a pointer }to the exception structure struct exception { int fp_type; } int fp_name; }; containing data about the error. The error-handli}ng function will take the place of the offending FP65 function, sending its integer return value to the caller of } the offending FP65 function. In struct exception, the value of fp_type is either 0 domain error } 1 range error The value of fp_name is one of 0 atof 7 fsub 14 fcpy 21 poly }28 atan 1 ftoa 8 fmul 15 fabs 22 hypot 29 fmod 2 utof 9 fdiv 16 pow } 23 sin 30 frac 3 ftou 10 exp 17 sqrt 24 cos 31 trunc 4 itof 11 exp10} 18 fcmp 25 tan 5 ftoi 12 log 19 floor 26 asin 6 fadd 13 log10 20 cei}l 27 acos Function codes 25 through 29 and 31 are reserved for future expansion. See the file ERROR.C f}or an example of fperror in use. } page 10/10 M/*\____________________________________ * * File: MATH.H * * Function declarations, FP constants, * Error codes... * "}* By Duane Tribe 4/29/90 * ____________________________________ * * To DEFINE extended FP constants, * #define FP_CDEF be"}fore this file. * * To REFERENCE extended FP contants * defined in another file, #define * FP_CREF before this file.\*/"}/* Useful built-in FP constants */extern char *M_0; /* 0.0 */extern char *M_1; /* 1.0 */extern c"}har *M_2; /* 2.0 */extern char *M_10; /* 10.0 */extern char *M_N1; /* -1.0 */extern char *"}M_P5; /* 0.5 */extern char *M_E; /* 2.718281828 */extern char *M_PI; /* 3.141592654 */extern char *M_2PI"}; /* 6.283185308 *//* Other optional constants */#ifdef FP_CDEFchar M_LOG2E[6] = /* 1.44269504 */{ 0x40, 0x01, "}0x44, 0x26, 0x95, 0x04 };char M_LOG10E[6] = /* 0.4342944819 */{ 0x3F, 0x43, 0x42, 0x94, 0x48, 0x19 };char M_LN2[6] = "} /* 0.6931471806 */{ 0x3F, 0x69, 0x31, 0x47, 0x18, 0x06 };char M_LN10[6] = /* 2.30258509 */{ 0x40, 0x02, 0x30, 0"}x25, 0x85, 0x09 };char M_PI_2[6] = /* 1.57079632 */{ 0x40, 0x01, 0x57, 0x07, 0x96, 0x32 };char M_PI_4[6] = /* "}0.7853981634 */{ 0x3F, 0x78, 0x53, 0x98, 0x16, 0x34 };char M_1_PI[6] = /* 0.3183098862 */{ 0x3F, 0x31, 0x83, 0x09, 0x"}88, 0x62 };char M_2_PI[6] = /* 0.6366197724 */{ 0x3F, 0x63, 0x66, 0x19, 0x77, 0x24 };char M_2_SQRTPI[6] = /* 1.1283"}79167 */{ 0x40, 0x01, 0x12, 0x83, 0x79, 0x16 };char M_SQRT2[6] = /* 1.41421356 */{ 0x40, 0x01, 0x41, 0x42, 0x13, 0x5"}6 };char M_SQRT1_2[6] = /* 0.7071067812 */{ 0x3F, 0x70, 0x71, 0x06, 0x78, 0x12 };char M_MIN[6] = /* 1E-98 *"}/{ 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00 };char M_MAX[6] = /* 9.999999999E99 */{ 0x71, 0x99, 0x99, 0x99, 0x99, 0x90 };c"}har M_EPSILON[6] = /* 1E-9 */{ 0x3B, 0x10, 0x00, 0x00, 0x00, 0x00 };#endif#ifdef FP_CREFextern char M_LOG2E[6"}], M_LOG10E[6];extern char M_LN2[6], M_LN10[6];extern char M_PI_2[6], M_PI_4[6];extern char M_1_PI[6], M_2"}_PI[6];extern char M_2_SQRTPI[6], M_SQRT2[6];extern char M_SQRT1_2[6], M_MIN[6];extern char M_EPSILON[6], M_MAX[6]; "}#endif/* FP error handling */struct exception{ int type, name;};#define DOMAIN 1#define RANGE 2/* End of "}MATH.H */FP error handling */struct exception{ int type, name;};#define DOMAIN 1#define RANGE 2/* End of ________________________ FP65 QUICK REFERENCE GUIDE ________________________CONVERSIONatof(fp, buf); &} ASCII to floatftoa(buf, fp); Float to ASCIIutof(fp, u); Unsigned to floatu = ftou(fp); Float to unsi&}gneditof(fp, i); Integer to floati = ftoi(fp); Float to integerMATHfadd(dst, f1, f2); Additionfsub(dst, &}f1, f2); Subtractionfmul(dst, f1, f2); Multiplicationfdiv(dst, f1, f2); DivisionPOWERS AND LOGSexp(dst, fp); B&}ase E powerexp10(dst, fp); Base 10 powerlog(dst, fp); Base E logarithmlog10(dst, fp); Base 10 logartihmpow(&}dst, f1, f2); General powersqrt(dst, fp); Square roothypot(dst, f1, f2); HypotenuseTRIGONOMETRYsin(dst, fp); &} Sinecos(dst, fp); CosineGENERALfloor(dst, fp); Integer smallerceil(dst, fp); Integer largerfrac(dst,&} fp); Fractional partfcpy(dst, fp); Copy floatfabs(dst, fp); Absolute valuei = fcmp(f1, f2); Compare floa&}tspoly(dst, x, c, n); Eval polynomialfperror(matherr); Control errorsCONSTANTSM_0 zero 0.0M_1 &} one 1.0 M_2 two 2.0 M_10 ten 10.0 M_N1 negative 1 -1.0&} M_P5 point five 0.5 M_E E 2.718281828M_PI PI 3.141592654M_2PI &} 2*PI 6.283185308M_LOG2E log2(E) 1.44269504M_LOG10E log10(E) 0.4342944819M_LN2 log(2) 0&}.6931471806M_LN10 log(10.0) 2.30258509M_PI_2 PI/2 1.57079632M_PI_4 PI/4 0.7853981634M_1_PI&} 1/PI 0.3183098862M_2_PI 2/PI 0.6366197724M_2_SQRTPI 2/sqrt(PI) 1.128379167M_SQRT2 sqrt(2) &} 1.41421356M_SQRT1_2 sqrt(1/2) 0.7071067812M_MIN minimum 1E-98M_MAX maximum 9.99999999E99M_EPSI&}LON accuracy 1E-9 sqrt(1/2) 0.7071067812M_MIN minimum 1E-98M_MAX maximum 9.99999999E99M_EPSI$FP65 1.0 for CC65February 1993By Duane Tribe,120 112th St.Orofino, ID 83544OVERVIEWFP65 a collection of routines *}forCC65 in object-library form that thatgive C programs access to the floating-point routines in the Atari ROMs.This is v*}ersion 1.0, released February1993.The routines were developed on an Atari800XL expanded via the ICD RamboXLexpansion run*}ning SpartaDOS X 4.20.The files in the FP65 package (exceptthe non-FP65 routines in C0F1.OLB) arecopyright 1993 by Duane *}Tribe. Thepackage can be freely distributed, butthe files listed in the manifest belowmust be included in their original*}form. No fee may be charged for thispackage other than a nominal mediacharge. There is no warranty of anykind for this s*}oftware.MANIFESTC0F1.OLB 26423 2-05-93 2:16p The new object library, containing the FP65 functions added to *}the file C.OLB from the CC65 distribution.ERROR.H 521 5-08-90 12:13a Include file defining the names of FP6*}5 functions for use in error reporting.EXPOSE.COM 4672 7-31-91 8:17p A program to print out the six bytes of a*} floating-point number in C hex format.FP65DOC.ESC 19288 2-24-93 2:45pFP65DOC.TXT 18452 2-24-93 2:52p The com*}plete documentation for FP65. Includes tips on how to use floating- point math in your CC65 programs and details about *}each FP65 function. The .ESC version includes Epson ESC/P codes, the .TXT version does not.MATH.H 2386 2-24-93*} 3:48p Include file for FP65, defines useful constants.README 1857 2-24-93 3:52p This fileQUICKREF.TXT*} 1898 2-10-93 1:50p FP65 function quick reference.SUM.BAT 55 2-05-93 2:49pSUM.C 283 2-05-93 *}2:43pSUM.LNK 35 2-05-93 2:45p A short floating-point example from the FP65 documentation. 283 2-05-93 (kX CC65 SUM.CX RA65 SUM.M65X LN65 -O SUM.COM @SUM.LNKoating-point example from the FP65 documentation. 283 2-05-93 ,7#include "stdio.h"#include "math.h"main (argc, argv)int argc;char *argv[];{ char buf[20]; char f1[6], f2[6]; ato2}f(f1, argv[1]); atof(f2, argv[2]); fadd(f1, f1, f2); printf("%s + %s = ", argv[1], argv[2]); fputs(ftoa(f1, buf), s2}tdout); fputc('\n', stdout);}]); fadd(f1, f1, f2); printf("%s + %s = ", argv[1], argv[2]); fputs(ftoa(f1, buf), s0!D:RUNTIME.OBJD:SUM.OBJD:C0F1.OLB; fadd(f1, f1, f2); printf("%s + %s = ", argv[1], argv[2]); fputs(ftoa(f1, buf), s4#