@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 D8u9?POPAX_DOSCMD @ ?  H) h`BJKHI_ doscmd.objThis function for the CC65 compileris not coprighted in any form. Use anyway you want.format: doscmd U}(cmd)where: cmd :is the spartados command ex. : doscmd("CD utility"); will change te current directory V} to utilityAny problems can be addresed to cat 3top 48 or mail to J.FULLER."); will change te current directory O;FPT8.M65;ptr1 = $8Cfr0 = $D4 ; float reg 0fr1 = $E0 ; float reg 1flptr = $FC ; pointer to a fp numcix X} =$F2 ;index inbuff = $F3 ; pointer to ascii numintlbf =$DA51lbuf = $580;afp = $D800 ;ascii -> floY}atifp = $D9AA ; int in fr0 -> float in fr0fpi = $D9D2 ; float in fr0 -> int in fr0fasc = $D8E6 ; fr0 -> (inZ}buff)fadd = $DA66 ; fr0 + fr1 -> fr0fsub = $DA60 ; fr0 - fr1 -> fr0fmul = $DADB ; fr0 * fr1 -> fr0fdiv = [} $DB28 ; fr0 / fr1 -> fr0; .globl _atofp;atofp(ascii,float)_atofp:; jsr popax sta flptr \} stx flptr+1 jsr popax sta inbuff stx inbuff+1 jsr addeol lda ]} #0 sta cix jsr afp jsr store rts;------------------------------------ .globl^} _itofp; itofp(int,float)_itofp:; jsr popax sta flptr stx flptr+1 jsr _} popax sta fr0 stx fr0+1 jsr ifp jsr store rts;--------------------------`}---------- .globl _fptoi; int=fptoi(float)_fptoi:; jsr popax jsr loadfr0 jsr a}fpi lda fr0 ldx fr0+1 jsr pushax rts;------------------------------------ b}.globl _fptoa; fptoa(ascii,float)_fptoa: jsr popax jsr loadfr0 jsr popax sta c} ptr1 stx ptr1+1 lda #0 sta cix jsr intlbf jsr fasc ldy #d}$FF ldx #$FFloop2: inx lda lbuf,x cmp #$30 beq loop2 dexloop: iny e} inx lda lbuf,x sta (ptr1),y bpl loop and #$7F sta (ptr1),y inf}y lda #0 sta (ptr1),y rts;------------------------------------ .globl _fpadd; fpadg}d(fp a,fp b,fp c); a+b=c_fpadd: jsr getready jsr fadd jsr store rts;-h}----------------------------------- .globl _fpsub; fpsub(fp a,fp b,fp c); a-b=c_fpsub: jsri} getready jsr fsub jsr store rts;------------------------------------ .globl _fpmulj}; fpmul(fp a,fp b,fp c); a*b=c_fpmul: jsr getready jsr fmul jsr store k} rts;------------------------------------ .globl _fpdiv; fpdiv(fp a,fp b,fp c); a/b=c_fpdiv:l} jsr getready jsr fdiv jsr store rts;------------------------------------getready:m} jsr popax sta flptr stx flptr+1 jsr popax jsr loadfr1 jsr pn}opax jsr loadfr0 rts;------------------------------------store:; ldx #$05 ldy #$05o}l1: lda fr0,x sta (flptr),y dex dey bpl l1 rts;--------------------------p}----------loadfr0: sta ptr1 stx ptr1+1 ldx #$05 ldy #$05l2: lda (ptr1),q}y sta fr0,x dex dey bpl l2 rts;------------------------------------loadfr1: r} sta ptr1 stx ptr1+1 ldx #$05 ldy #$05l3: lda (ptr1),y sta fr1,x s} dex dey bpl l3 rts;------------------------------------addeol ldy #$FFl4: inyt} lda (inbuff),y bpl l4 lda #$9B sta (inbuff),y rts;-----------------------u}-------------(inbuff),y bpl l4 lda #$9B sta (inbuff),y rts;-----------------------c _FPSUBPOPAX_ATOFP_FPLOG_FPTOI1_FPEXP_FPSQRT_FPTOAB_FPADDy_ITOFPPUSHw}AX_FPMUL_FPDIV A A W (` A AԆ (` A 5 ٥Ԧ J` A x}5 A Q ؠ轀0轀 )ȩ`  f (`  ` (`  (`  ( (` Ay} A 5 (` A A A 5 ޥ (` A A 5?P z} (` A A F A 5`ԑʈ`ʈ`ʈ`ȱ` y Floating point numbers used here are really char strings dimensioned to sixplaces. ex: char float1[6],float2[6]. I admit |}it is very cumbersome changingfrom strings to floats and back again but if you want floats with CC65 as itstands this seems}} to be the only alternative. The functions and a briefdescription of each follows: ascii = a number in string format. ~} float = a six place char array for fp storage. int = integer atofp(ascii,float) convert string to float f}ptoa(float,ascii) convert float to string itofp(int,float) convert integer to float int=fptoi(float) } convert float to integer fpadd(a,b,c) a+b=c where a b and c are floats fpsub(a,b,c) } a-b=c fpmul(a,b,c) a*b=c fpdiv(a,b,c) a/b=c These functions do no checking to see if} the input is actually a number so your routine should do that before calling any of the fp functions. If you have an}y problems either send me mail (J.FULLER) or reply to CAT 3 TOP 48. There are no copyrights on these functions and th}ey may be used and distributed freely. James C. Fuller 9-1-90 There are no copyrights on these functions and thI&&_GETCHE_KBDCHAR_GETCH ` ` %H$H`  `e no copyrights on these functions and thTmLDAISAVEAXENTERFUNINCAX1TOSGTAX_FGETSEXITFUN_GETSINCSP2STASPPSTA }XYSPRESTAXDECSP2PUSHAXLDAXYSP B L N M M M E J N @ M } D N A C J K @L & N M I N HLF M E J N @ M Xgets() is a replacement for thegets()funtion in the cc65 c.olblibrary.The one in the libraryreturned an eol along with the$} stringwhich I believe is not standard C. in the cc65 c.olblibrary.The one in the libraryreturned an eol along with the$-;; Runtime code for scc65.; assemble with atari.m65 and global.m65.globl__start; program lo memory boundary__start:(};; this is the first piece of actual generated code...;jmpstart; so we don't need a start vector;; routines for inc/(}dec'ing sp;;.globldecsp2;decsp2:; dec sp by 2;pha; save a;ldasp; get sp lo;sec;sbc#2; sub 2;sta(}sp;ldasp+1; get sp hi;sbc#0; sub carry;stasp+1;pla; get a back;rts.globladdysp; add Y to SPaddysp:(}pha; save Aclctya; get the valueadcsp; add lo bytestasp; put it backbccaddysp_1; if no carry, we're(} doneincsp+1; inc hi byteaddysp_1:pla; get A back;rts; donejmptstax; return condition codes;.globlin(}csp1;incsp1:;ldy#1;bneaddysp.globlincsp2; inc sp by 2incsp2:; do this by hand, cause it gets used a lot;ldy(}#2;bneaddyspincspbne*+4incsp+1; might as well do incsp1 here, as we have the code....globlincsp1incsp1:inc(}spbne*+4incsp+1rts.globlincsp3; inc sp by 3incsp3:ldy#3bneaddysp.globlincsp4; inc sp by 4incsp(}4:ldy#4bneaddysp.globlincsp5; inc sp by 5incsp5:ldy#5bneaddysp.globlincsp6; inc sp by 6incsp6:ldy(}#6bneaddysp.globlincsp7; inc sp by 7incsp7:ldy#7bneaddysp.globlincsp8; inc sp by 8incsp8:ldy#8bn(}eaddysp.globlsubysp; sub Y from SPsubysp:pha; save Astytmp1; save the valueldasp; get lo bytesecsb(}ctmp1; sub y valstasp; put it back; wrong!;bcssubysp_1; if carry, we're done;decsp+1; dec hi byteldasp+1(}sbc#0stasp+1subysp_1:pla; get A backrts; done.globldecsp1decsp1:ldy#1bnesubysp.globldecsp2de(}csp2:;; do this one by hand, cause it gets used a lot;;ldy#2;bnesubyspphasecldaspsbc#2staspldasp+1(}sbc#0stasp+1plarts.globldecsp3decsp3:ldy#3bnesubysp.globldecsp4decsp4:ldy#4bnesubysp.globld(}ecsp5decsp5:ldy#5bnesubysp.globldecsp6decsp6:ldy#6bnesubysp.globldecsp7decsp7:ldy#7bnesubysp.(}globldecsp8decsp8:ldy#8bnesubysp;; ops for loading/indexing stack slots;.globlldaxysp; load AX from SP@(Y)l(}daxysp:lda(sp),y; get lo bytephainylda(sp),y; get hi bytetax; into xpla; get lo byte back;rtsjmp(}tstax; return cc;.globlldsrysp; load SREG from SP@(Y);ldsrysp:;pha; save A;lda(sp),y; get lo byte;stasr(}eg; store it;iny;lda(sp),y; get hi byte;stasreg+1; store it;pla; get A back;jsrldaxysp; just do the t(}hings we optimized;jsrswapsreg; out.;rts.globlldaysp; load A from SP@(Y)ldaysp:; zzz maybe do this on line?(}ldx#0lda(sp),yrts.globllocysp; compute location of SP@(Y) in AXlocysp:ldxsp+1; get hi byteclc; set u(}p for addtya; get offsetadcsp; compute lo bytebcclocysp_1inx; add in carrylocysp_1:rts.globlplocysp(}; push addr y(sp)plocysp:jsrlocyspjmppushax;; routines for inc/dec'ing AX;.globlincax8incax8:ldy#8jmpi(}ndexax.globlincax7incax7:ldy#7jmpindexax.globlincax6incax6:ldy#6jmpindexax.globlincax5incax5:ldy#5(}jmpindexax.globlincax4incax4:ldy#4jmpindexax.globlincax3incax3:ldy#7jmpindexax.globlincax2; inc (}AX by 2incax2:jsrincax1; inc it once, and fall thru.globlincax1; inc AX by 1incax1:tay; use Y as a tempin(}ytyabneincax1_1; if not zero, we're doneinx; inc top halfincax1_1:;rts; donejmptstax; return cond codes(};.globlincaxi1; load AX indirect, and increment by 1;incaxi1:;jsrldaxi;jmpincax1;.globlincaxi2; load AX in(}direct, and increment by 2;incaxi2:;jsrldaxi;jmpincax2;.globlinci1spp; load AX indirect, inc 1, store thru SP@+;(}inci1spp:;jsrincaxi1;jmpstaxspp;.globlinci2spp; load AX indirect, inc 2, store thru SP@+;inci2spp:;jsrincaxi2(};jmpstaxspp;.globldecax2; dec AX by 2decax2:jsrdecax1; dec it once, and fall thru.globldecax1; dec AX b(}y 1decax1:tay; use Y as a tempdeytyacmp#$FF; wrap?bnedecax1_1; if not -1, we're donedex; dec top half(}decax1_1:;rts; donejmptstax; return cond codes;.globldecaxi1; load AX indirect, and decrement by 1;decaxi1:(};jsrldaxi;jmpdecax1;.globldecaxi2; load AX indirect, and decrement by 2;decaxi2:;jsrldaxi;jmpdecax2;.gl(}obldeci1spp; load AX indirect, dec 1, store thru SP@+;deci1spp:;jsrdecaxi1;jmpstaxspp;.globldeci2spp; load AX i(}ndirect, dec 2, store thru SP@+;deci2spp:;jsrdecaxi2;jmpstaxspp;; push/pop things on stack;.globlpush0push0:(}lda#0tax; ....globlpushax; push AXpushax:jsrdecsp2; dec spldy#0; get indexsta(sp),y; store lo byte(}pha; save ittxa; get hi byteiny; bump idxsta(sp),y; store hi bytepla; get A backrts; done.glo(}blpopax; pop stack into AXpopax:ldy#0lda(sp),y; get lo bytepha; stash itinylda(sp),y; get hi byteta(}x; into xpla; get lo byte backjmpincsp2; bump stack and return.globlpopsreg; pop stack into SREGpopsreg:(}pha; save Aldy#0lda(sp),y; get lo bytestasreg; store itinylda(sp),y; get hi bytestasreg+1; stor(}e itpla; get A backjmpincsp2; bump stack and return.globlpushwysp; push a word from SP@(Y)pushwysp:;pha(}; save A;txa;pha; save Xlda(sp),y; get lo bytepha; Save itiny; bump idxlda(sp),y; get hi bytetax(}; into Xpla; get back lo bytejsrpushax; push that;pla; get original X;tax; into X;pla; get back o(}riginal Arts.globlpushbysp; push a byte from SP@(Y)pushbysp:lda(sp),y; get lo byteldx#0jsrpushax; push t(}hatrts;; Various kinds of store operators;.globlstaxspidx; store AX at SP@@(Y)staxspidx:jsrstaspic; use commo(}n partphainyldatmp2sta(ptr1),ytaxplajmptstax.globlstaspidxstaspidx:jsrstaspic; use common partldx(}tmp2jmptstaxstaspic:statmp1stxtmp2stytmp3jsrpopax; get the pointerstaptr1stxptr1+1ldytmp3ldatm(}p1sta(ptr1),yrts.globlstaxyspstaxysp:sta(sp),yphatxainysta(sp),yplajmptstax.globlstayspstaysp(}:sta(sp),yjmptstax;.globlstasreg; store A thru SREG;stasreg:;ldy#0;sta(sreg),y;rts;.globlstaxsreg; s(}tore AX thru SREG;staxsreg:;ldy#0;sta(sreg),y; store lo byte;pha; save A;iny; bump idx;txa; get hi byt(}e;sta(sreg),y; store it;pla; get A back;;rts; done;jmptstax; return cc.globlstaxspp; store AX thru ((}sp), and popstaxspp:pha; save Atxapha; save Xjsrpopax; pop addr into AXstaptr1; save into a pointers(}txptr1+1ldy#1pla; get hi byte backsta(ptr1),y; store ittax; back into Xpla; get lo bytedeysta(ptr(}1),y; store itjmptstax; return cc.globlstaspp; store A thru (sp), and popstaspp:pha; save Atxapha; s(}ave Xjsrpopax; pop addr into AXstaptr1; save into a pointerstxptr1+1pla; get Xtaxpla; get lo bytel(}dy#0sta(ptr1),y; store itjmptstax; return cc;; Operations on AX;.globlaslax; shift AX left 1aslax:asl(}AphatxarolAtaxplarts;.globlasrax; shift AX right 1;asrax:;pha;txa;pha;rolA; get carry set rig(}ht;pla;rorA; do the real rotate;tax;pla;rorA;rts.globlldaxi; load AX indirect thru AXldaxi:statmppt(}rstxtmpptr+1ldy#1lda(tmpptr),ytaxdeylda(tmpptr),y;rtsjmptstax; return cond codes;; load A indirect (}thru AX;.globlldaildai:statmpptr; set pointerstxtmpptr+1ldy#0; set idxlda(tmpptr),y; get bytebplldai(}_1; pos...ldx#$FFrtsldai_1:ldx#0;rtsjmptstax; return cond codes.globlnegax; negate axnegax:pha;(} save Atxa; get Xeor#$FF; inverttax; back to Xpla; get A backeor#$FF; invertclcadc#1; incbc(}cnegax_1inx; bump Xnegax_1:rts.globllnegax; logical complement AXlnegax:stxtmp3oratmp3beqlneg1; it(}'s zero, so return 1lda#0taxrtslneg1:ldx#0lda#1rts.globlcomplax; one's complement AXcomplax:eor#$FF(}; Not Aphatxaeor #$FF; Not Xtaxplarts.globlindexax; index in Y, add Y to AXindexax:statmp1tyac(}lcadctmp1bcc*+3inxrts.globlplocidx; push location of AX@(Y)plocidx:jsrindexaxjmppushax;; test (AX)(};;.globltstaxi;tstaxi:;jsrldaxi; and fall thru...;; test AX for nonzero-ness. return result in CC;.globlts(}taxtstax:;cmp#0;beqtstax_0;bpltstax_p;; A was negative, try X;tstax_0:; A was 0, try X;cpx#0;tstax_9:(};rts;tstax_p:; A was positive;cpx#0; try X;bpltstaxcpx#0; test Xbeqtstax_x0; 0, go see what A hasrts(}tstax_x0:; X was 0, try Acmp#0; test Abpltstax_9; pos or zero is ok, just returnldy#1; force 'positive'ts(}tax_9:rts; done, just return.globlldaxidx; load AX from (AX)Yldaxidx:jsrindexax; compute addressjmpldaxi(}; load indirect.globlldaidx; load A from (AX)Yldaidx:jsrindexax; compute addressjmpldai; load indirect.(}globlpushwidx; push word at (AX)Ypushwidx:jsrindexax; indexjsrldaxijmppushax.globlpushbidx; push byte at ((}AX)Ypushbidx:jsrindexax; indexjsrldaijmppushax;; operations on SREG;.globlasltosasltos:jsrpopsreg; f(}or optimized code.globlaslsreg; shift SREG left AX times, result in AXaslsreg:cpx#0; X nonzero?bneaslsreg_0; n(}o, just return 0tay; use Y as counterldasreg+1statmp1; use A and tmp1 as registerldasregcpy#0; shift cou(}nt 0?beqaslsreg_9; done shiftingaslsreg_1:aslA; shift Aroltmp1dey; dec counterbneaslsreg_1aslsreg_9:l(}dxtmp1; get hi byte;rts; donejmptstaxaslsreg_0:lda#0tax;rtsjmptstax; return status for optimized co(}de.globlasrtosasrtos:jsrpopsreg; for optimized code.globlasrsreg; shift SREG right by AX, result in AXasrsreg(}:cpx#0; X nonzero?bneaslsreg_0; no, just return 0;tax; use X as counter;php; save Z flag, for zero counter(};ldasreg;statmp1; use tmp1 and A as register;ldasreg+1;and#$80; keep top bit;statmp2;plp; get Z flag (}back;beqasrsreg_9; done shifting;asrsreg_1:;lsrA; shift hi byte;rortmp1; and lo byte;oratmp2; keep top bi(}t;dex; dec counter;bneasrsreg_1;asrsreg_9:;tax; put hi byte in X;ldatmp1; and get lo byte;rts;this is(}n't right... test after loading AX...;cmp#0; shift count 0?;beqaslsreg_0; yes, return 0tay; use Y as shift coun(}terldasregldxsreg+1; get the value into AXcpy#0beqasrsreg_9; zero, return now;cpx#0; test AX for minus-ne(}ss;bpl*+5;jsrnegaxstxtmp1; leave hi byte in tmp1asrsreg_1:ldxtmp1; get hi byte,cpx#$80; compare, to se(}t carry bit if negrortmp1; shift hi byte, preserving hi bitrorA; shift lo bytedey; dec shift countbneasrsre(}g_1; 0? doneldxtmp1; get hi byte;ldysreg+1; original value negative?;bpl*+5;jsrnegax; negate resultasrsre(}g_9:jmptstax; return status for optimized code.globladdtosaddtos:jsrpopsreg; for optimized code.globladdsre(}g; add SREG to AXaddsreg:clcadcsreg; add lo bytephatxaadcsreg+1; add hi bytetaxpla;rtsjmptstax;(} return status for optimized code;.globladdimm; add immediate following word;addimm:;statmp1; save A;stxtmp1+1(}; and X;pla; get return addr;staptr1;pla;staptr1+1;ldy#1;lda(ptr1),y; get lo byte;clc;adctmp1; a(}dd to old A value;statmp1; put it back;iny;lda(ptr1),y; get hi byte;adctmp1+1;statmp1+1;clc; adjust ret(}urn addr;ldaptr1;adc#3; so we can jump thru it;staptr1;bcc*+4;incptr1+1;ldatmp1; get A back;ldxtmp1+(}1;jmp(ptr1).globlsubtossubtos:jsrpopsreg; for optimized code.globlsubsreg; sub AX from SREG, result in AXs(}ubsreg:statmp1stxtmp2; save AXldasregsecsbctmp1; sub lo bytephaldasreg+1sbctmp2; sub hi bytetax(}pla;rtsjmptstax; return status for optimized code;.globlswapsreg; swap AX and SREG;swapsreg:;statmp1;stx(}tmp2;ldasreg; get lo byte;ldxsreg+1; get hi byte;ldytmp1;stysreg;ldytmp2;stysreg+1;rts.globlortos(}ortos:jsrpopsreg; for optimized code.globlorsreg; OR sreg into AXorsreg:orasregphatxaorasreg+1taxpl(}a;rtsjmptstax; return status for optimized code.globlxortosxortos:jsrpopsreg; for optimized code.globlxor(}sreg; XOR sreg into AXxorsreg:eorsregphatxaeorsreg+1taxpla;rtsjmptstax; return status for optimized c(}ode.globlandtosandtos:jsrpopsreg; for optimized code.globlandsreg; AND sreg into AXandsreg:andsregphat(}xaandsreg+1taxpla;rtsjmptstax; return status for optimized code;.globlldsr; load sreg from following word(};ldsr:;statmp1; save A;pla; get return addr;staptr1;pla;staptr1+1;ldy#1;lda(ptr1),y; get lo byte;(}stasreg;iny;lda(ptr1),y; get hi byte;stasreg+1;clc; adjust return addr;ldaptr1;adc#3; so we can jump t(}hru it;staptr1;bcc*+4;incptr1+1;ldatmp1; get A back;jmp(ptr1);; comparisons;.globlaxzeropaxzerop:c(}mp#0bnereturn1cpx#0bnereturn1beqreturn0.globltoseqaxtoseqax:jsrpopsreg; for optimized code.globlsre(}geqax; SREG == AXsregeqax:cmpsreg; A == sreg lo?bnereturn0; nope, return 0cpxsreg+1; X == sreg hi?bneretu(}rn0beqreturn1.globltosneaxtosneax:jsrpopsreg; for optimized code.globlsregneax; SREG != AXsregneax:cmpsr(}eg; A == sreg lo?bnereturn1; nope, return 1cpxsreg+1; X == sreg hi?bnereturn1beqreturn0.globltosltaxto(}sltax:jsrpopsreg; for optimized code.globlsregltax; SREG < AXsregltax:; really AX > SREG...cpxsreg+1; X < s(}reg hi?bmireturn0; X < SR^ , return 0bnereturn1; not =, so >; return 1cmpsreg; A < sreg lo?bccreturn0; A (}< SR\, return 0beqreturn0bcsreturn1.globltosultaxtosultax:jsrpopsreg; for optimized code.globlsregultax; (}SREG u< AXsregultax:; AX u> SREGcpxsreg+1bccreturn0; tos^ u< ax^ , return 0bnereturn1; if ne, must be u>; re)}turn 1cmpsregbccreturn0beqreturn0bcsreturn1.globltosleaxtosleax:jsrpopsreg; for optimized code.globl)}sregleax; SREG <= AXsregleax:; AX >= SRcpxsreg+1bmireturn0; X < SR^, return 0bnereturn1; X > SR^, return 1)}cmpsregbccreturn0; u> , return 0bcsreturn1.globltosuleaxtosuleax:jsrpopsreg; for optimized code.globls)}reguleax; SREG u<= AXsreguleax:cpxsreg+1bccreturn0; X < SR^, return 0bnereturn1; X > SR^, return 1cmpsreg)}bccreturn0bcsreturn1;; return functions for comparison ops. these guys are careful; to leave the condition codes cor)}rect for the AX value. Compiler; depends on that when optimizing; beware!;return1:ldx#0lda#1rtsreturn0:lda#0)}taxrts.globltosgtaxtosgtax:jsrpopsreg; for optimized code.globlsreggtax; SREG > AXsreggtax:; AX < SRc)}pxsreg+1bmireturn1; < , return 1bnereturn0; not =, so >; return 0cmpsregbccreturn1; < , return 1bcsretu)}rn0.globltosugtaxtosugtax:jsrpopsreg; for optimized code.globlsregugtax; SREG u> AXsregugtax:cpxsreg+1bcc) }return1; < , return 1bnereturn0; not =, so >; return 0cmpsregbccreturn1; < , return 1bcsreturn0.globlt) }osgeaxtosgeax:jsrpopsreg; for optimized code.globlsreggeax; SREG >= AXsreggeax:; AX <= SRcpxsreg+1bmiretu) }rn1; < , return 1bnereturn0; not =, so >; return 0cmpsregbccreturn1; < , return 1beqreturn1bcsreturn0) }.globltosugeaxtosugeax:jsrpopsreg; for optimized code.globlsregugeax; AX u<= SREGsregugeax:cpxsreg+1bccretu) }rn1; < , return 1bnereturn0; not =, so >; return 0cmpsregbccreturn1; < , return 1beqreturn1bcsreturn0;)} kludgey constant for DIV, MOD;onehalf:;.byte$3F,$49,$99,$99,$99,$99;; function ops;.globlenterfun0enterfun0:)}ldy#0beqenterfun.globlenterfun1enterfun1:ldy#1bneenterfun.globlenterfun2enterfun2:ldy#2bneenterfun)}.globlenterfun3enterfun3:ldy#3bneenterfun.globlenterfun4enterfun4:ldy#4bneenterfun.globlenterfun5en)}terfun5:ldy#5;bneenterfun;; expect frame size in Y, push fp;.globlenterfunenterfun:tya; get arg count;as)}lA;clc;adcsp; add to sp;pha;ldasp+1;adc#0;tax;plaldx#0; just push arg countjmppushax.globlexi)}tfun; exit a function. pop stack and rtsexitfun:pha; save A a secldy#0lda(sp),y; that's the pushed arg count)}aslA; loses big for large arg counts...tayinyiny; count the word the count's stored inpla; get it backjm)}paddysp; pop that many word-sized things;; random stuff;;; call value on in AX;.globlcallaxcallax:;jsrpopa)}x; pop function ptr;jsrtos2ax; get tosstatmp1stxtmp1+1jmp(tmp1); jump there;; swap AX with TOS;.globl)}swapstkswapstk:statmpptrstxtmpptr+1ldy#1; indexlda(sp),ytaxldatmpptr+1sta(sp),ydeylda(sp),ypha)}ldatmpptrsta(sp),yplarts; whew!.globlpushwaxipushwaxi:; push word (ax)jsrldaxijmppushax.globlp)}ushbaxi; push byte at (ax)pushbaxi:jsrldaijmppushax;.globlldaxysp;ldaxysp:;jsrlocysp;jmpldaxi;; or ax )}with tos, pop;;.globloraxtos;oraxtos:;ldy#0;ora(sp),y;pha;txa;iny;ora(sp),y;tax;pla;jmpincsp2;; )}eor ax with tos, pop;;.globleoraxtos;eoraxtos:;ldy#0;eor(sp),y;pha;txa;iny;eor(sp),y;tax;pla;jmpin)}c2sp;; and ax with tos, pop;;.globlandaxtos;andaxtos:;ldy#0;and(sp),y;pha;txa;iny;and(sp),y;tax;pl)}a;jmpinc2sp;; add Y to sp, leave result in AX;;.globladdrysp;addrysp:;tya; get offset;clc; set up for...)};adcsp; add low byte;pha;ldasp+1; get hi byte;adc#0; add carry;tax; xfer to x;pla; get a back;r)}ts; done;; handler for case jump inst.;.globlcasejumpcasejump:;; case table after the call to casejmp. val in A) }X.; table is of the form ,,...,0.; rts from casejmp for default case, else pop return addr; addr and j)!}mp to address;statmp3stxtmp4; save valuepla; get return addrstaptr1plastaptr1+1; store in ptr 1inc)"}ptr1; and adjust it, because of way 6502 worksbne*+4incptr1+1case1:ldy#1; first see if at endlda(ptr1),y; t)#}est address byte hibnecase2; nope, not yetdeylda(ptr1),y; test address byte lobnecase2; oops, we're out of cas)$}es. compute return address; 2 + ptr1clcldaptr1; get lo byteadc#2; inc past the 0staptr1bcc*+4; deal with)%} carryincptr1+1jmp(ptr1); go therecase2:; test case value against this valueldy#3lda(ptr1),y; value hi)&}cmptmp4; match switchval hi?bnecase3; no match, try nextdeylda(ptr1),y; val locmptmp3; match switchval lo?)'}bnecase3; match!dey; point at hi byte of addrlda(ptr1),ystaptr2+1; stuff in ptr to jump thrudey; point )(}at lo byte of addrlda(ptr1),ystaptr2jmp(ptr2); go therecase3:; no match, try next case clauseclcldaptr1))}; get case ptradc#4; add 4staptr1; put it backbcc*+4incptr1+1; deal with carryjmpcase1; and go try a)*}gain;; save and restore AX;.globlsaveaxsaveax:stasvaxstxsvax+1rts.globlrestaxrestax:ldasvaxldxsvax+)+}1jmptstax;; support routines for runtime;;tos2ax:;ldy#0;ytos2ax:;iny;lda(sp),y;tax;dey;lda(sp),y;rt),}s;.globlpopax;popax:;jsrtos2ax;jsrinc2sp;rts;; mult and div, using fp routines;;.globlumul;umul:;)-} unsigned multiply;stafr0; set up the first num;stxfr0+1;jsrifp; make a float out of it;jsrfmove; move to f).}r1;jsrpopax; get second arg;stafr0; set this one up;stxfr0+1;jsrifp; floatify...;jsrfmul; mult them;)/}jsrfpi; back to int;ldafr0;ldxfr0+1; load it up;rts; and return.globlmultosmultos:jsrpopsreg.globl)0}smul; signed multiply AX by SREGsmul:ldy#0stytmp3; zap negative flagcpx#0bpl*+7inctmp3jsrnegaxstatm)1}pptr; use sreg and tmpptrstxtmpptr+1; as regsldasregldxsreg+1bplxsmul0dectmp3jsrnegaxstasregstxsr)2}eg+1xsmul0:lda#0statmp1; tmp1/2 as accumulatorstatmp1+1lda#1; use A as bit mask against SREGxsmul1:bitsr)3}eg; this bit in sreg set?beqxsmul2; nope, try nextjsrxsmadd; add AX val to accumxsmul2:asltmpptr; shift AX )4}val left oneroltmpptr+1aslA; shift bitmask left onebccxsmul1; if bit not off end, keep working on lo bytelda#)5}1; set up mask for hi bytexsmul3:bitsreg+1; this bit in sreg set?beqxsmul4; nope, try nextjsrxsmadd; add AX)6} val to accumxsmul4:asltmpptr; shift AX val left oneroltmpptr+1aslA; shift bitmask left onebccxsmul3; if n)7}ot off end, keep working on hi byteldxtmp1+1; load up accumldatmp1ldytmp3; negate flag?beqxsmul9jsrnegaxx)8}smul9:rts; done!xsmadd:; helper funpha; save bit maskclcldatmpptr; add AX valueadctmp1; to accu)9}mulatorstatmp1ldatmpptr+1adctmp1+1statmp1+1pla; get bitmask backrts; donexsdiv0:; error return):}lda#0taxstasregstasreg+1rts.globldivtosdivtos:jsrpopsreg; pop other value into sreg.globlsdiv; sig);}ned divide SREG by AX, sdiv:; result in AX, remainder in SREGldy#0stytmp3; zap denominator-negative flagsty)<}tmp4; and numerator-negative flagjsrtstax; AX zero?beqxsdiv0; yup, give up nowbplxsdiv1; positive, it's ok)=}inctmp3; denom negativejsrnegax; negate itxsdiv1:staptr1; use tmpptr1 and SREG as regsstxptr1+1ldasregl)>}dxsreg+1; load up sregjsrtstax; what sort of value?beqxsdiv0; zero, we losebplxsdiv2; positive, it's okin)?}ctmp4; set numerator-negative flagjsrnegax; negate itstasregstxsreg+1xsdiv2:ldy#1; bit maskstyptr2de)@}ystyptr2+1stytmp1; use tmp1 as accumstytmp1+1;; shift ptr1 and ptr2 left until ptr1 is greater than SREG,; then)A} shift right until it's <=;xsdiv3:ldaptr1+1; comparecmpsreg+1; p1 to sregbeqxsdiv3a; eq, try second byteb)B}csxsdiv4; >, we're done shifting leftbccxsdiv3b; <, shift leftxsdiv3a:ldaptr1cmpsreg; compare lo bytebeqx)C}sdiv5; =, skip the right shiftbcsxsdiv4; >, go right onexsdiv3b:aslptr1; shift p1 left 1rolptr1+1aslptr2)D}; shift bitmask left onerolptr2+1jmpxsdiv3; round again.xsdiv4:; shift p1, mask right onelsrptr1+1; shift p)E}1rorptr1lsrptr2+1; shift bitmaskrorptr2bcsxsdiv7a; bit fell out end?!? ok, do exit processing;; whew! tmppt)F}r1 (the divisor register) and tmpptr2 (the quotient bitmask); are now all set to enter the divide loop;xsdiv5:; compar)G}e sreg to p1. if >=, subtractldasreg+1cmpptr1+1beqxsdiv5a; try lo bytebcsxsdiv6; >, go subtractbccxsdiv7)H}; <, go shift rightxsdiv5a:ldasregcmpptr1bccxsdiv7; < go shift rightxsdiv6:; subtract p1 from sreg, and set)I} bit in accumsecldasreg; subtract sbcptr1; p1 stasreg; from ldasreg+1; sregsbcptr1+1stasreg)J}+1ldaptr2; or oratmp1; bitmaskstatmp1; into ldaptr2+1; quotientoratmp1+1statmp1+1xsdiv7:ls)K}rptr1+1; shift p1 rightrorptr1lsrptr2+1rorptr2bccxsdiv5; if no carry, round againxsdiv7a:;; done!;lda)L}tmp4; negate remainder?beqxsdiv8ldasregldxsreg+1jsrnegaxstasregstxsreg+1xsdiv8:ldatmp1ldxtmp1+1l)M}dytmp3; numerator neg...cpytmp4; same as denom-neg?beqxsdiv9; yes, skip the negatejsrnegaxxsdiv9:rts.gl)N}oblmodtosmodtos:jsrdivtosldasregldxsreg+1jmptstax;; library routines;.globl_strcpy_strcpy:jsrpopax)O}staptr1stxptr1+1jsrpopaxstaptr2stxptr2+1ldy#0strc1:lda(ptr1),ysta(ptr2),ybeqstrc9inybnestrc1)P}incptr1+1incptr2+1bnestrc1strc9:rts.globl_strlen_strlen:jsrpopaxstaptr1stxptr1+1ldx#0; YX used )Q}as counterldy#0strlen1:lda(ptr1),ybeqstrlen9inybnestrlen1incptr1+1inxbnestrlen1strlen9:tya; get )R}low byte of counter, hi's all setrts;; find (char * str, int len, char c) -> index;;_find:;jsrtos2ax;staptr1;s)S}txptr1+1;ldy#2;jsrytos2ax;statmp1;stxtmp1+1;ldy#4;jsrytos2ax; gets char in A;ldx#0;stxptr2; us)T}e as counter here;stxptr2+1;ldy#0;find1:;cmp(ptr1),y; match?;beqfind9; yup, return; zzz;find9:;rts;)U}; startup;;argv:;.word0,0,0,0,0,0,0,0;.word0,0,0,0,0,0,0,0start:tsxstxorigsp; save system stk ptr;;lda#0)V}; init stk ptr;stasp;lda#$80; $80 for debugging...;stasp+1;ldamemtop; memtop for real codestaspldame)W}mtop+1stasp+1;; if running under SpartaDos, pass the command line to _main;lda$0700; check the sparta flagcmp#')X}S'beqstartcmd; nope, check for dos xl;; Try to guess what OS we're running under.; Use the algorithm suggested by Dick)Y} Curzon.; Look thru $0A. Should see a jmp, another jmp,; and something that's not a jump.;ldy#0lda(cpaloc),ycmp#)Z}$4C; a jmp?bnestart0; nope, give upldy#3lda(cpaloc),ycmp#$4C; a jmp?bnestart0; nopeldy#6lda(cpal)[}oc),ycmp#$4C; a jmp?beqstart0; if yes, it's mydos or somethingstartcmd:;; parse command line etc. for now, ass)\}ume Sparta or Dos XL;clcldacpaloc; get pointer toadc#cpcmdb; cmd bufpha; save lo byteldacpaloc+1adc#0)]}tax; get hi bytepla; get lo byte backjmpstart1start0:; no command line, just pass nulllda#0taxstart1:j)^}srpushax; push the ptrldy#1; 1 argjsr__main;; fall thru to exit...;rts; done!;.globl_exit_exit:ldxo)_}rigsptxs;rtsjmp(dosvec);; 1 argjsr__main;; fall thru to exit...;rts; done!;.globl_exit_exit:ldxo(!]uLDAISAVEAXANDSREGNEGAXMODTOS ASLTOSTOSUGEAX,PUSHBIDXPUSHWAXICALLAXf-a}ASRTOS POPSREG SREGULTAXINCAX8SREGGEAXTOSUGTAX POPAXPUSH0INCAX4PUSHBAXITOSGEAX-b}PUSHWIDXLNEGAXINCAX5PLOCYSPINCAX6LDAYSPSUBYSP7SWAPSTKmLDAXIDXINCAX7LOCYS-c}P_EXITENTERFUNSSREGGTAXLDAXI{INCAX1INCAX2INCAX3ADDYSPTOSGTAXSREGEQAXPUSH-d}WYSPSTAYSPD SREGULEAXTOSULTAXPUSHBYSPTOSEQAXSUBSREGSSUBTOSPPLOCIDXTSTAXAXZEROP-e}SREGNEAXORTOSfSTAXSPPIDIVTOS\SREGLTAXORSREGiADDTOSAINCSP4#INCSP5'TOSNEAXASLAXt-f}INCSP6+ ENTERFUN0=TOSLTAXINCSP7/MULTOS ENTERFUN1AADDSREGDEXITFUNY ENTERFUN2EINCSP1-g} ENTERFUN3IXORTOStINCSP2 ENTERFUN4MLDAIDXSTASPP`DECSP4aINCSP3 ENTERFUN5QTOSULEAXDEC-q}8B%DOS SYSB*)DUP SYSBSDOSCMD OBJBTDOSCMD TXTBWFLOAT M65BvFLOAT OBJB {FLOAT TXTBGETCH OBJBGETS OBJBGETS TXTBRUNTIME M65B`RUNTIME OBJB SCANF OBJBSFREADMETXTBXIO OBJBXIO TXTSP5eASRSREG#STAXYSP9INDEXAXDECSP6i__MAINANDTOSCOMPLAXSTASPIDXDECSP7mRESTAX S-r}REGUGEAX/ASLSREGDECSP1IINCSP83DECSP2M__STARTSMULSREGLEAXDECSP3]_STRLEN5DECAX1-s}PUSHAXLDAXYSPu_STRCPYSDIV_XORSREGwDECAX2 SREGUGTAXTOSLEAX STAXSPIDXCASEJUMPDECS-t}P8qL NHehL `H8咅h`H8h`-u} HȱhL `e` L L L L L L L  -v}ȘL  L  M Hȑh` HȱhL HȱhL  Hȱh ` ` % Hȥ-w}hL  %L  ` HȑhL L HH hhL HH hhL  H*h` -x}L  `L  HIhIi``` IHIh` e` L `-y}` L { L   {L   L    &L L   -z}fjL  eHehL  8H哪hL  HhL  EHEhL  %H%hL `-{}\_ łXTM łFBE 0>7ł86/ 䃐-&ł'% 0-|} 䃐 ł`` 0ł 䃐ł 0ł -}} 䃐ł L H hL lHh` {L -~} L hhilŕŔ l iL `L  -}    Ɣ $ D& $ D&  `Heeh-}``       Ńł &&L -} FfFf3ōŌ8包卅 FfFf   ĕ ` \-}L    ` `S L L-} L  i?H ihL   `Yl `S L L,3m LDAI __PARSELISAVEAX_UTOI_SCANFSUBYSPLOCYSP_ISWHITE_SF_GUTSBLDAXIE1}NTERFUNINCAX1ADDYSPTSTAXSUBTOSSTAXSPP_DTOIADDTOSTOSNEAXASLAX_GETSEXITF1}UNINCSP2STAXYSPRESTAXDECSP2_TOLOWERLDAXYSPPUSHAX_STRCPYDECAX2CASEJUMP 1}J Y F \ F \ S Q I S Q \ S N \ B VLU Jn Ep [ B1} ^p W X IV WV [l WR Wp [ B ^p W X IV W F \ T F \1}Z F \ Al [ @ ML l [ @ \ Gl [ B Kl W X @L l [ @ \%1} R n LLUl [ B Kl W X @l [ B Kl W X @ \ ZL mV [ \Z F1} \V [ S Q I \ ]p [ B ^p W X IV WR [ B KR W XL X F \1}T [ S Q I \ F \ PV [ \ [ Op [ B ^p W X IV WR [ B K1}R W XL X F \T [ S Q I \ F \ CV [ \ [ Op [ B ^p W X1} IV WR [ B KR W XL n LLUL  _ ?c ?s d uL ^L n LLU X0x This is a limited scanf function that supports %d,%u,%c,and %s only. Unlike the standard function it makes no differen5}ce if there are spaces in the first argument or not: %d%c%s or %d %c %s are treated the same. The input MUST be delimite5}d by spaces only. I have also included getch() function in this archive. getch() alsoincludes getche(). getche() will no5}t work with older 800's. Please address any problems to me J.FULLER or CAT 3 TOP 48 James C. Fullergetche() will no4mN`POPAX_XIO @ B @ @ @ @ BJKDE V`ȱ`8} xio.objThis function for the CC65 compileris not coprighted in any form. Use anyway you want.format: xio(cmd,c=}han,aux1,aux2,fname)where: cmd :the xio command number chan:iocb number ex :xio(44,1,0,0,"D4:>games"); =} will change the directory on D4: to the games directory.Any problems can be addresed to cat 3top 48 or mail to J.FU=}LLER.change the directory on D4: to the games directory.Any problems can be addresed to cat 3top 48 or mail to J.FU<