@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 D8u00LWPlR PHH %U B P Vhh`H Ph`Hɛ Ph`HcT}Pȱ PcPh`L PHJJJJ Ph)PP PP` P P`0123456789ABCDEFa{8 `:.*?0 : A[8``PU} P P͸P`Qei\QTɛS O P PF*? H QQhPHюHihihQ QQLlQV}hPLQ`8`Q: P0Q QLQQ. Q QQQ QQ`PPPP` QW}`Ȫ`P Q Q: Q Q Q. Q Q Q Q`%R-%R-%R 豌` &R &R &RX}`SSSYD1:FOO.UUEFOO.COM            HPY} 0 UPP %U 5UPPP0h`HP  NThm P P Pi PPPPPPP`Z}jRɛ4jRei wQ LRjRɛ LTȱɛ jR`jR LR8`DE`HI`JK`B VC` UL5UHH[} -UhhL?UHH -UhhL?URm U %U 5U0Hh`HU +Ph P P8`Read error L L LLUS, \}S i?jRSS 4V`YAU>U +PmS U< %U 5UL/VmSjRH S 4V`S8`jRɛ L7V]}jR`jR8` mRLUV`8`begin endSfV OV`mRɛ9 LVȹmRɛ) ȹmRɛ imRi wQS)S^}`mRɛ`HV +PhmR `Bogus line! UUE file is bad.mR8 WlR WLWlR W V8 )?W WlR_}W WWJJJJ WWW WWJJ WWW WWW T WW T WW T WLW` 5U 5U`Yow! -> P`} PPPPS ULY:TS wQ:TT TS QS GU*HX +Ph P PLYOpen error on infile: gU@Xa} +PLYNo 'BEGIN ' found qV٩:TS wQST& T:T LRT LRˠS QW +PS FPW +PˠS FP P Sb} WU+HҠX +Ph P PLYOpen error on outfile: P NT gU ...to which you could r}answer D1:FOO.UUE D1:FOO.COM If Yau is took its args from a DOS XL command line, it will exit immediat s}ely after it runs. If it prompted for its args (regard- less of whether or not you're running DOS XL) it will keep pro t}mpt- ing until you feed it an empty line. Yau and Yaue Manual Page 2 Now, a u}ll that command stuff may look like a lot of typing, (yes, I know it's what the others make you do, but I thought it was v}a lot of typing when they did it, too) but it's not as bad as all that. Both source and target file specs are merge w}d against various de- faults, so you need not type them out explicitly. The default source pathname is 'D1:FOO x}.UUE'; the default target pathname is 'FOO.COM'. The default target pathname is overridden by the name in the 'b y}egin' line of the uue file, so typically you wouldn't type that at all; ie the command line to YAU would just l z}ook like: YAU FOO where the 'D1:' and the '.UUE' in the source pathname were de- faulted. (In t {}his, and the examples following, I'll be discussing the commands as you'd type them on the command line of DOS XL; |} they're exactly the same for other cases, except that you type line when Yau prompts for it, and you just type the }} args, not the word 'YAU'; it knows what it is) In that case, the target file spec gets read out of the 'begi ~}n' line, so if the uue file was originally created from something called 'FOO.COM', it'll use that name. Yau will a }lso merge the target pathname against the source pathname, in order to default the device of the target to the same o }ne as the source. The net result of all this merging is that the above example will do exactly the same thing as 'YAU } D1:FOO.UUE D1:FOO.COM', above. It's also easier to deal with the more com- plicated cases; ie you could say } YAU FOO D2: to decode a file on D1: to a the resultant file on D2:. You could say YAU FOO B }AR to override whatever's in the 'begin' line, and put the result into BAR.COM. Finally, if YAU senses that it }'s running under DOS XL, it'll inherit the default device spec, so you're not stuck do- ing everything on D1:. (No }prizes for guessing what OS I use on my 800). Lastly, in case you're old-fashioned, and don't want your computer } outsmarting you behind your back, after all the dust has settled, Yau will tell you what it's doing, as: } Yow! D1:SQUZ.UUE -> D1:SQUZ.BIN If you're REALLY old fashioned, and don't think you computer has any business t }rying to do smart things, don't use YAU and YAUE. Yau and Yaue Manual Page 3 Other } tidbits: Yau keeps a byte count and simple 16 bit checksum while it's decoding; when it's done with a file }, it will display them, as: Byte count = 2099 Checksum = #x1FC0 The byte count is in decimal, the } checksum is in hex; the #x is to remind you that it's hex, in case it's not obvious from the va- lue. The checksum } is the running unsigned sum of all the bytes in the resultant file, truncated to 16 bits. Yau tries to minimize }disk overhead by buffering up data destined for the target file. The buffer size is 8k, so most files will only }require one or two writes, ie you're not constantly seeking the disk head back and forth. If you're using ramdisks, you } won't care, but if you've got a real mechanical disk, it'll make a big difference. Yau is pretty good ab }out error checking; it tries to make sure the advertised byte count makes sense for what it finds in each line, }tries to make sure there's a legit looking 'end' line etc. It's a bit more lenient about trailing spaces that some }other implementations; it never requires them. It will gripe about er- rors as it finds them, and, of course, about } IO errors. Yau and Yaue Manual Page 4 YAUE: Yet Another UU Encoder. Yau }e is a companion program to Yau. It takes binary files (pro- grams, archives, etc) and encodes them into text suit }able for sending through predatory mail systems, etc. Needless to say, things encoded with Yaue can be decoded }with Yau. Yaue is run in exactly the same way as Yau; ei you can run it di- rectly from the command line if you'r }e using DOS XL, or just start it up and type things at it when it prompts. (yes, its prompt is 'YAUE>'). Pathname }defaulting works in exactly the same way as with Yau; the default pathames are 'D1:FOO.COM' for input and '.U }UE' for output. If you're using DOS XL, Yaue will inherit the current default device. One slightly wierd thing }about Yaue; there's currently no way to specify a name to go in the 'begin' line other than the name of the file } you're starting with, ie if you encode D1:FOO.COM, the begin line will look like begin 666 FOO.COM I }thought about making the command line parser smarter, to allow for something like that, and decided it wasn't worth the } effort. If you really care what the file claims to be called, edit the UUE or rename the file before you encode it. } Other bits: Yaue will dump byte count and checksum values for encoded files, in exactly the same form as Y }au does. (Shouldn't come as a com- plete surprise) That way, when you send around uuencoded binaries, you can send } the expected byte count and checksum with them. Yaue doesn't go to as great lengths as Yau to avoid disk overhead. } I figured that in general the decoder gets run a lot more fre- quently than the encoder, so it was the more import }ant one to op- timize. I may have another hack attack at some point, and put in the buffering stuff. A word } of warning for Spartados users: The algorithm used to guess which OS I'm running under is the one suggested by Dick } Cur- zon some months ago. Unfortunately, it has the characteristic that it can't distinguish Spartados from DOS } XL. What that means is that these things will almost certainly crash horribly when run under Spartados. If someon }e can tell me how to tell the differ- ence when booting, please do; but until this gets fixed, Sparta- dos users }probably can't use these things. Yau and Yaue Manual Page 5 One last word about } these guys, If you don't like the names 'YAU' and 'YAUE', you're completely free to rename them, they don't care wha }t their names are. The byte count and checksums for this release are: Yau: 2134. bytes, #x39F2 checksum. Ya }ue: 1988. bytes, #xE74D checksum. I guess that's about it. Happy coding! Yau: 2134. bytes, #x39F2 checksum. Ya S;.TITLE "YAU: Yet Another Uudecoder" ;.TAB 8,14,20 *= $3000 ; ; .INCLUDE D2:SYSEQU.ASM ;------------------------------------}----------------------- ; .PAGE "OSS SYSTEM EQUATES FOR ATARI" ; ; FILE = #DN:SYSEQU.ASM ; ; ; I/O CONTROL BLOCK EQUATES ; S}AVEPC = * ; SAVE CURRENT ORG ; *= $0340 ; START OF SYSTEM IOCBS IOCB ; ICHID *= *+1 ; DEVICE HANDLER IS (SET BY OS) ICDNO }*= *+1 ; DEVICE NUMBER (SET BY OS) ICCOM *= *+1 ; I/O COMMAND ICSTA *= *+1 ; I/O STATUS ICBADR *= *+2 ; BUFFER ADDRESS ICP}UT *= *+2 ; DH PUT ROUTINE (ADR-1) ICBLEN *= *+2 ; BUFFER LENGTH ICAUX1 *= *+1 ; AUX 1 ICAUX2 *= *+1 ; AUX 2 ICAUX3 *= *}+1 ; AUX 3 ICAUX4 *= *+1 ; AUX 4 ICAUX5 *= *+1 ; AUX 5 ICAUX6 *= *+1 ; AUX 6 ; IOCBLEN = *-IOCB ; LENGTH OF ONE IOCB ; ; I}OCB COMMAND VALUE EQUATES ; COPN = 3 ; OPEN CGBINR = 7 ; GET BINARY RECORD CGTXTR = 5 ; GET TEXT RECORD CPBINR = 11 ; PUT BIN}ARY RECORD CPTXTR = 9 ; PUT TEXT RECORD CCLOSE = 12 ; CLOSE CSTAT = 13 ; GET STATUS ; ; DEVICE DEPENDENT COMMAND EQUATES FOR} FILE MANAGER ; CREN = 32 ; RENAME CERA = 33 ; ERASE CPRO = 35 ; PROTECT CUNP = 36 ; UNPROTECT CPOINT = 37 ; POINT CNOTE = 38} ; NOTE ; ; AUX1 VALUES REQD FOR OPEN ; OPIN = 4 ; OPEN INPUT OPOUT = 8 ; OPEN OUTPUT OPUPD = 12 ; OPEN UPDATE OPAPND = 9 ; O}PEN APPEND OPDIR = 6 ; OPEN DIRECTORY ; ; .PAGE ; ; EXECUTE FLAG DEFINES ; EXCYES = $80 ; EXECUTE IN PROGRESS EXCSCR = $40} ; ECHO EXCUTE INPUT TO SCREEN EXCNEW = $10 ; EXECUTE START UP MODE EXCSUP = $20 ; COLD START EXEC FLAG ; ; MISC ADDRESS EQUA}TES ; CPALOC = $0A ; POINTER TO CP/A WARMST = $08 ; WARM START (0=COLD) MEMLO = $2E7 ; AVAIL MEM (LOW) PTR MEMTOP = $2E5 ; AV}AIL MEM (HIGH) PTR APPMHI = $0E ; UPPER LIMIT OF APPLICATION MEMORY INITADR = $2E2 ; ATARI LOAD/INIT ADR GOADR = $2E0 ; ATARI} LOAD/GO ADR CARTLOC = $BFFA ; CARTRIDGE RUN LOCATION CIO = $E456 ; CIO ENTRY ADR EOL = $9B ; END OF LINE CHAR ; ; Character }defs from sysmac.sml ; ATCLR = $7D ;CLEAR SCREEN CHARACTER ATRUB = $7E ;BACK SPACE (RUBOUT) ATTAB = $7F ;TAB ATEOL = $9B ;END}-OF-LINE ATBEL = $FD ;CONSOLE BELL ATURW = $1C ;UP-ARROW ATDRW = $1D ;DOWN-ARROW ATLRW = $1E ;LEFT-ARROW ATRRW = $1F ;RIGHT-A}RROW space = $20 ; ; CP/A FUNCTION AND VALUE DISPLACEMSNT ; (INDIRECT THROUGH CPALOC) ; IE. (CPALOC),Y ; CPGNF}N = 3 ; GET NEXT FILE NAME CPDFDV = $07 ; DEFAULT DRIVE (3 BYTES) CPBUFP = $0A ; CMD BUFF NEXT CHAR POINTR (1 BYTE) CPEXFL = }$0B ; EXECUTE FLAG CPEXFN = $0C ; EXECUTE FILE NAME (16 BYTES) CPEXNP = $1C ; EXECUTE NOTE/POINT VALUES CPFNAM = $21 ; FILENA}ME BUFFER RUNLOC = $3D ; CP/A LOAD/RUN ADR CPCMDB = $3F ; COMMAND BUFFER (60 BYTES) ;CPCMDGO = -6 ; CP SUBROUTINE VECTOR ; }*= SAVEPC ; RESTORE PC ; ;----------------------------------------------------------- ; ; .page "Page zero" zpc = $80 ; page }zero pc spc1 = * *= zpc cmdptr: .blkb 2 ; pointer to cmd line binp: .blkb 2 ; pointer into binary buf strptr: .blkb 2 dbgpt}r: .blkb 2 ; end of page zero defs zpc1 = * *= spc1 ; ; fp defs ; fr0 = $D4 fr1 = $E0 flptr = $FC inbuff = $F3 cix = $F2 ; f}asc = $D8E6 ; fp -> ascii ifp = $D9AA ; int -> fp fadd = $DA66 ; fr0 + fr1 -> fr0 fmul = $DADB ; fr0 * fr1 -> fr0 fmove = $DD}B6 ; fr0 -> fr1 ; ; .PAGE "Data defs" ; inf = $10 ; input file outf = $20 ; output file ; *= $3000 JMP START ; in case goad}r ignored ; ; binary buffering stuff ; binary buf size must be a ; multiple of 256 ; BINMAX = 8192 ; how much binary to buff}er up BINBUF: .blkb BINMAX BINSIZE: .word 0 BINEMPTY: .byte 1 ; nbytes: .byte 0,0,0 ; 3 ought to be big enough chksum: .byte }0,0 ; ones comp checksum ; ; debug flag ; debug: .byte 0 ; ; Debug code ; ; char in A out to tty ; ; ; debug code ; .byte 0} dbgchr: sta dbgchr-1 tya pha txa pha ldx #0 txa tay jsr SETLEN lda #CPBINR STA ICCOM,X lda dbgchr-1 JSR CIO pl}a tax pla tay rts ; ; dump a str, ptr in x,y, terminated by 0. ; preserves A ; dbgstr: pha stx dbgptr sty dbgptr+1 ld}y #0 dbgs1: lda (dbgptr),y beq dbgs2 jsr dbgchr iny bne dbgs1 inc dbgptr bne dbgs1 inc dbgptr+1 bne dbgs1 dbgs2: pl}a rts ; dbgstre: pha stx dbgptr sty dbgptr+1 ldy #0 dbge1: lda (dbgptr),y cmp #ateol beq dbge2 jsr dbgchr iny bne }dbge1 inc dbgptr bne dbge1 inc dbgptr+1 bne dbge1 dbge2: pla rts ; ; print a string, textc form ; .byte 0 dbgstrc: p}ha stx dbgptr sty dbgptr+1 ldy #0 lda (dbgptr),y beq dbgsc9 sta dbgstrc-1 dbgsc1: iny lda (dbgptr),y jsr dbgchr dec} dbgstrc-1 bne dbgsc1 dbgsc9: pla rts ; dbgeol: lda #ATEOL jmp dbgchr ; ; print a byte (in A) in hex ; .byte 0 dbghex: } pha lsr a lsr a lsr a lsr a jsr dbghd pla dbghd: and #$0F stx dbghex-1 tax lda hex,x jsr dbgchr ldx dbghex-1 rt}s dbghxy: tya jsr dbghex txa jsr dbghex rts HEX: .BYTE "0123456789ABCDEF" ; ; ;----------------------------------------}------------------------ ; ; pathname parsing stuff. ; ; a pathname consists of optional device, name, and optional ; extensi}on. ; ; a pathname descriptor is a structure containing three fields, ; each of which is a byte of max, a byte of length, and} a (max) bytes ; of data. they are: ; dev device spec (2 bytes) ; name file name (8 bytes) ; ext file type (3 bytes) ; ; equ}ates for pathname descriptor block ; pnd.fl = 0 ; flags byte pnd.dm = 1 ; dev max, 1 byte pnd.ds = 2 ; dev size, one byte} pnd.dt = 3 ; dev text, two bytes pnd.nm = 5 ; name max, 1 byte pnd.ns = 6 ; name size, 1 byte pnd.nt = 7 ; name text, 8 }bytes pnd.em = 15 ; ext max pnd.es = 16 pnd.et = 17 pndsiz = 20 ; total size ; ; generic component equates ; pnc.m = 0 ; m}ax this component pnc.s = 1 ; size this component pnc.t = 2 ; text this component ; ; bits in flag byte ; pnf.dp = $01 ; d}ev spec present pnf.np = $02 ; name present pnf.ep = $04 ; type present pnf.wl = $08 ; wild card somewhere ; ; if we had m}acros, the macro for building one of these would ; look like this: ; ; .byte 0 ; flags ; .byte 2 ; dev max ; .byte 0 ; .blk}b 2 ; .byte 8 ; name max ; .byte 0 ; .blkb 8 ; .byte 3 ; .byte 0 ; .blkb 3 ; ; pointers ; spc2 = * *= zpc1 pnptr .blkb 2 ;} string ptr pndptr .blkb 2 ; pathname struct pnddef .blkb 2 ; default pncptr .blkb 2 ; pathname component zpc2 = * *= spc2 }; ppnt0: .byte 0 ; temp for parse-pathname and friends ppnt1: .byte 0 ppnt2: .byte 0 ; ; pncupc: char-upcase char in A ; pn}cupc: cmp #'a ; >= 'a ? bcc pncupc9 ; nope, leave cmp #'z+1 ; < 'z? bcs pncupc9 ; nope, leave sec sbc #$20 ; shift} to up case. (carry's set) pncupc9: rts ; ; pnclgl: char in a legal pathname char? ; returns carry set if not legal ; pn}clgl: cmp #': ; colon's ok beq pnclgl9 cmp #'. ; dot's ok too beq pnclgl9 cmp #'* ; star is ok beq pnclgl9 cmp #'? } ; q-mark is ok beq pnclgl9 cmp #'0 ; 0..9 is ok bcc pnclgl8 ; less, no good cmp #'9+1 bcc pnclgl9 ; less, ok cmp #}'A ; alpha? bcc pnclgl8 ; less is no good cmp #'Z+1 bcc pnclgl9 ; A..Z's ok pnclgl8: sec ; error return rts pnclgl9}: clc ; ok return rts ; ; pnfindc: find a character, in x, in (pnptr), starting ; at y. returns idx or -1 in y, EQ if }found, NEQ ; if not found. Trashes A ; pnfindc: stx ppnt1 ; save char pnfindc1: lda (pnptr),y ; get a char beq pnfindc}8 ; 0? ok, stop here jsr pncupc ; upcase it jsr pnclgl ; legal pathname char? bcs pnfindc8 ; nope, go error cmp ppnt1 }; compare it beq pnfindc9 ; got it, return iny ; next! bne pnfindc1 pnfindc8: ldy #-1 ; return 'not found' pnfindc9: }rts ; ; parsepn:: ; grok a pathname string into a pathname descriptor. ; expects pathname string pointed to by x,y, desc in (}pndptr). ; pathname string terminated by any non-pathname char. ; ; this routine copies in one component. Initial idx in Y, }terminating ; character in X, component offset in desc in A ; ;ppndbg1: .byte "Enter parsepn",ATEOL,0 ;ppndbg2: .byte "Leave }parsepn",ATEOL,0 ppnct: .byte 0 ; terminator char ppncf: .byte 0 ; flags for pathname we're parsing ppncpf: .byte 0 ; flag} to set in component we're on ppncomp: stx ppnct ; save terminator clc ; first calculate adc pndptr ; pointer to pat}hname sta pncptr ; component lda pndptr+1 adc #0 sta pncptr+1 ppncp1: lda (pnptr),y ; get a char ; below? iny ; and }bump the string idx beq ppncp9 ; always terminate on nuls cmp ppnct ; hit terminator? beq ppncp8 ; yes, stop this compo}nent cmp #ATEOL ; eol? beq ppncp9 ; yes, always terminate on eols, too cmp #space ; space? beq ppncp9 ; yes, always t}erminate on spaces, too iny ; and bump the string idx jsr pncupc ; upcase it jsr pnclgl ; legal char? bcs ppncp9 ; n}ope, stop here cmp #'* ; is it one of the wild chars? beq ppncp2 ; yes, flag it as such cmp #'? bne ppncp3 ppncp2: pha} ; save char lda #pnf.wl ; or in the 'wild' flag ora ppncf sta ppncf pla ; get char back ppncp3: sty ppnt0 ; save }y for a bit pha ; save char ldy #pnc.s ; component size offset lda (pncptr),y ; get component size ; check size ldy #p}nc.m ; component max cmp (pncptr),y ; compare size to max bcs ppncp6 ; too big! ignore this byte ldy #pnc.s ; idx for s}ize again ; pha ; save size for later indexing clc ; add one to it for adc #1 ; next time sta (pncptr),y ; put it b}ack pla ; get the old size (index) back clc ; zap carry again, and adc #pnc.t ; add dev text offset tay ; into y } pla ; get char back sta (pncptr),y ; stuff into dev text lda ppncpf ; or in the flag corresponding to ora ppncf ; t}his component sta ppncf jmp ppncp7 ; and go back for more ppncp6: pla ; throw char away ppncp7: ldy ppnt0 ; get strin}g idx back jmp ppncp1 ppncp8: ; ; found terminator. Skip it. iny clc ; tell caller we saw it rts ; ppncp9: sec ; te}ll caller we didn't see it rts ; ; The main routine of the pathname parser. ; parsepn: stx pnptr ; set string pointer lo }sty pnptr+1 ; and hi ;zzz debug ; ldx #ppndbg1\ ; ldy #ppndbg1^ ; jsr pstrnul ;zzz lda #0 ; first zap len flds in desc s}ta ppncf ; and flags in progress ldy #pnd.ds ; dev size sta (pndptr),y ; zap ldy #pnd.ns sta (pndptr),y ldy #pnd.es s}ta (pndptr),y ldy #0 ; idx into name string ppndev: ldx #': ; do we have a colon? jsr pnfindc bmi ppndev9 ; nope, skip} this part lda #pnf.dp ; flag to set if we do it sta ppncpf ldy #0 ; start at zero please lda #pnd.dm ; do device comp}onent jsr ppncomp jmp ppnnam ; go do the name ppndev9: ldy #0 ; reset string ptr ppnnam: lda #pnf.np ; flag to set if }we do it sta ppncpf lda #pnd.nm ; do name component ldx #'. ; stop at dot ; y's already set jsr ppncomp ; ; rather }a kludge. If see a dot, always say ; ext present, even if no ext text ; bcs ppnext lda #pnf.ep ora ppncf sta ppncf ppnex}t: lda #pnf.ep ; flag to set if we do it sta ppncpf lda #pnd.em ; extension, please ldx #ATEOL ; sort of irrelevant, a}s we'll stop ; on any illegal char. jsr ppncomp ; y's already set. lda ppncf ; now put in accumulated flags ldy #pn}d.fl sta (pndptr),y ;zzz debug ; ldx #ppndbg2\ ; ldy #ppndbg2^ ; jsr pstrnul ;zzz rts ; done! ; ; pn2str: (parsed) pathn}ame to string. ; expects a pathname descriptor in (pndptr) ; and a string in X,Y. Generates a namestring ; terminated }by ATEOL, suitable for passing to ; CIO. Note that it wants a fully qualified ; parsed pathname. ;ppndbg3: .byte "Enter }pn2str",ATEOL,0 ;ppndbg4: .byte "Leave pn2str",ATEOL,0 ; ; this pushes one byte into output string ; pn2sp: sty ppnt2 ; sav}e y value for a bit ldy ppnt0 ; get string idx sta (pnptr),y ; shove the char ;zzz debug ; pha ; save a ; txa ; save x} ; pha ; lda (pnptr),y ; get char back ; pha ; lda #'| ; jsr prchr ; pla ; jsr prchr ; pla ; tax ; pla ;zzz inc ppnt0 ; bum}p the str idx ldy ppnt2 ; get y back rts ; ; copy one component into outgoing string. ; y contains offset into desc for co }mponent text, x contains size ; pn2scs: lda (pndptr),y ; get a char jsr pn2sp ; stuff it iny ; bump dev text idx dex  } ; dec size bne pn2scs ; back for more rts ; ; this inits regs, given an initial offset into the descriptor. ; returns Z i }f length 0. ; pn2sin: lda (pndptr),y ; get the component size ;zzz debug ; pha ; tya ; pha ; lda #'# ; jsr prchr ; pla ; y } val ; pha ; jsr prbyte ; pla ; pha ; tay ; lda (pndptr),y ; jsr prbyte ; pla ; tay ; pla ;zzz iny ; point y at text tax } ; save it as a counter, set Z for return rts ; ; the main routine ; pn2str: stx pnptr ; set pathname string lo sty pnp}tr+1 ; and hi ;zzz debug ; ldx #ppndbg3\ ; ldy #ppndbg3^ ; jsr pstrnul ; lda pnptr+1 ; jsr prbyte ; lda pnptr ; jsr prbyte };zzz ldy #0 ; string idx sty ppnt0 ldy #pnd.ds ; dev component size jsr pn2sin ; set up regs beq pn2str1 ; No dev???} ok, skip it jsr pn2scs ; copy a string lda #': ; get a colon jsr pn2sp ; push it in ; pn2str1: ldy #pnd.ns ; name c}omponent size jsr pn2sin ; set up beq pn2str2 ; zero length name?? this should error ... jsr pn2scs ; copy it in ; pn2s}tr2: lda #'. ; get a dot jsr pn2sp ; push it in ; ldy #pnd.es ; name component size jsr pn2sin beq pn2str3 ; zero le}ngth ext? jsr pn2scs ; copy it in pn2str3: lda #ATEOL ; get an eol jsr pn2sp ; push it in ;zzz debug ; ldx #ppndbg4\ ; }ldy #ppndbg4^ ; jsr pstrnul ;zzz rts ; done!!! ; ; pnmerge:: Merge two pathnames. Move components from the ; first into} missing components of the second, ie ; merge "D1:FOO.BAR","CRUD.BAZ" -> "D1:CRUD.BAZ" ; ; wants pnddef pointing at pn1, pnd}ptr at pn2 ; pnmflg: .byte 0 ; flag byte for which comp we're doing pnmc: sta pnmflg ; store component mask ldx #0 ; idx} for flags byte lda (pndptr,x) ; get flags and pnmflg ; target path have this component? bne pnmc9 ; if there, skip lda} (pndptr),y ; get component size in target pathname bne pnmc9 ; nonzero, try next lda (pnddef,x) ; get flags for default p}n and pnmflg ; and with mask beq pnmc9 ; if not there, skip component lda (pnddef),y ; ok, get the one we're merging fro}m beq pnmc9 ; this one zero too?? ok, skip it tax ; get size in x inx ; inc to include size byte pnmc1: lda (pnddef)},y ; get a byte sta (pndptr),y ; put it in target iny ; bump component ptr dex ; dec count bne pnmc1 ; round again p}nmc9: rts ; done with this component ;ppndbg5: .byte "Enter pnmerge",ATEOL,0 ;ppndbg6: .byte "Leave pnmerge",ATEOL,0 pnm}erge: ;zzz debug ; ldx #ppndbg5\ ; ldy #ppndbg5^ ; jsr pstrnul ;zzz lda #pnf.dp ; device flag ldy #pnd.ds ; look at dev c}omponent size jsr pnmc ; merge this component lda #pnf.np ; device flag ldy #pnd.ns ; do name jsr pnmc ; ... lda #p}nf.ep ; device flag ldy #pnd.es ; and extension jsr pnmc pnmzzz: ldy #pnd.fl ; merge flags flds lda (pnddef),y ora (p }ndptr),y sta (pndptr),y ;zzz debug ; ldx #ppndbg6\ ; ldy #ppndbg6^ ; jsr pstrnul ;zzz rts ; done! ; ; ;-----------------!}------------------------------------------------ ; cmdidx: .byte 0 ; idx into cmd line LINELEN: .byte 0 LINEIDX: .byte 0 LINE"}: .blkb 256 ; cmdmax = 60 ; command line max cmdbuf .blkb cmdmax cmddone: .byte 0 ; if command line already processed ; done:#} .byte 0 ; time to exit flag ; iname: .blkb 32 ; input file name oname: .blkb 32 ; output file name idname: .byte "D1:FOO.UUE$}",ateol ; input default defdrv = idname+1 odname: .byte "FOO.COM",ateol ; output default fpn: .byte 0,2,0," ",8,0," "%},3,0," " ; pathname from file ipn: .byte 0,2,0," ",8,0," ",3,0," " ; input pathame opn: .byte 0,2,0," ",8,0," &} ",3,0," " ; output pathname dpn: .byte 0,2,0," ",8,0," ",3,0," " ; default pathname ; ; ; .PAGE "Utils" ; FL'}USHBIN PHA LDA BINEMPTY BNE FLUSHB99 LDX #outf LDA #binbuf&$FF LDY #binbuf/256 JSR SETBUF LDY BINSIZE+1 LDA BINSIZE (} JSR SETLEN LDA #CPBINR JSR IOCMD FLUSHB99 LDA #1 ; say we're empty STA BINEMPTY LDA #0 ; say current size STA BINS)}IZE ; is zero STA BINSIZE+1 ; lda #BINBUF\ ; set ptr to beginning sta binp ; of buf lda #BINBUF^ sta binp+1 ; PLA ;*} get A back RTS ; GENBYTE ; ; Stuff it in out buf ; PHA LDA BINSIZE+1 CMP #BINMAX/256 ; buffer full? ; BCC GENB1A bne GE+}NB1A GENBF JSR FLUSHBIN GENB1A PLA LDY #0 sta (binp),y ; ; count and sum it ; clc adc chksum sta chksum lda chksum+1 ,} adc #0 sta chksum+1 inc nbytes bne genb1b inc nbytes+1 bne genb1b inc nbytes+2 genb1b: LDA #0 STA BINEMPTY INC BIN-}SIZE BNE GENB1C INC BINSIZE+1 GENB1C: INC binp bne GENB1D inc binp+1 GENB1D: RTS ; ; x,Y points to pathname ; GETFNAME .} stx pndptr sty pndptr+1 ; ; zap the pathname ; lda #0 ldy #pnd.fl sta (pndptr),y ldy #pnd.ds sta (pndptr),y ldy #pnd./}ns sta (pndptr),y ldy #pnd.es sta (pndptr),y ; ldy cmdidx ; get cmd line idx ; ; y points to pathname ; lda (cmdptr),y 0} cmp #ateol ; eol? beq getf9 ; yup, stop sty cmdidx ; for next time tya clc adc cmdptr tax ; lo byte lda cmdptr+11} adc #0 ; get carry tay ; points to namestring now jsr parsepn ; parse it jsr pnmerge ; ; now skip this one. This is2} sort of gross... ; ldy cmdidx getf1: lda (cmdptr),y ; find a space cmp #ateol beq getf3 cmp #space beq getf2 iny jmp3} getf1 getf2: iny ; skip it lda (cmdptr),y cmp #ateol beq getf3 cmp #space beq getf2 ; getf3: sty cmdidx clc ; sa4}y we win rts getf9: sty cmdidx jsr pnmerge ; merge defaults anyway sec ; say we lose rts ; ; IOCB in X, addr hi in Y,5} lo in A ; SETBUF STA ICBADR,X TYA STA ICBADR+1,X RTS SETLEN STA ICBLEN,X TYA STA ICBLEN+1,X RTS SETAUX STA ICAUX1,X6} TYA STA ICAUX2,X RTS ; ; IO command in A ; IOCMD STA ICCOM,X JSR CIO LDA ICSTA,X RTS ; ; A,Y point to name ; OPENF J7}SR SETBUF LDA #COPN JMP IOCMD OPENIN PHA TYA PHA LDA #OPIN LDY #0 JSR SETAUX PLA TAY PLA JMP OPENF OPENOUT PHA 8}TYA PHA LDA #OPOUT LDY #0 JSR SETAUX PLA TAY PLA JMP OPENF ; ; READLINE LDX #INF LDY #LINE/256 LDA #LINE&$FF JSR 9}SETBUF LDA #255 LDY #0 JSR SETLEN LDA #CGTXTR JSR IOCMD cpy #0 ; status? bmi readerr ; lose, die PHA ; ; debug ; ; :}ldx #line\ ; ldy #line^ ; jsr dbgstre ;; RDL2 PLA clc RTS readerr: tya pha ldx #rdemsg\ ldy #rdemsg^ jsr dbgstr pla ;} jsr dbghex jsr dbgeol sec rts rdemsg: .byte ATEOL,"Read error ",0 ; ; getcmd: get a pointer to command line. ; Leave cm<}didx pointing at ; first non-blank in the command line. ; getcmd: ; ; first try to guess what OS we're running under. ; Use t=}he algorithm suggested by Dick Curzon. ; Look thru $0A. Should see a jmp, another jmp, ; and something that's not a jump. ; >} ldy #0 lda ($0A),y cmp #$4C ; a jmp? bne getnxl ; nope ldy #3 lda ($0A),y cmp #$4C ; a jmp? bne getnxl ; nope ld?}y #6 lda ($0A),y cmp #$4C ; a jmp? bne getcxl ; nope, that means xl ; ; note that the above test will be passed by ; Spa@}rtados too, which means we'll die horribly. ; Someone should come up with a better test... ; getnxl: ; ; not xl; just prompt A}for it ; jmp ncmd getcxl: lda cmddone ; we already do this one? bne ncmd ; yup, don't do it again ; ; get default driveB} from dos xl, and stuff into our default drive ; ldy #cpdfdv+1 ; idx for drive num lda (cpaloc),y ; get the digit sta defdC}rv ; stuff it in ours ; ; get command line from DOS XL ; lda cpaloc sta cmdptr lda cpaloc+1 sta cmdptr+1 LDY #CPBUFP D}LDA (CPALOC),Y CLC ADC #CPCMDB sta cmdidx ; ; say we've processed this command line. ; lda #1 sta cmddone ; ; we got oneE} from cmd line; set done ; flag so we'll exit after we're done ; ; lda #1 sta done jsr cmdsk ; skip spaces bcs ncmd ; nF}one? ok, prompt rts ; return his codes ; ; no command line, prompt for one ; prompt: .byte "YAU>",0 ncmd: ldx #prompt\ lG}dy #prompt^ jsr dbgstr ldx #0 ; e: iocb lda #cmdbuf\ ldy #cmdbuf^ jsr setbuf lda #cmdmax\ ldy #cmdmax^ jsr setlen lH}da #CGTXTR ; get rec jsr iocmd cpy #0 ; win? bpl ncmd1 ; yes, go do it jmp cmderr ncmd1: lda #cmdbuf\ sta cmdptr ldI}a #cmdbuf^ sta cmdptr+1 ldy #0 sty cmdidx lda icblen,x ; get low order len beq cmderr ; if zero len cmd, exit lda #0 J}; if get here, not done sta done jsr cmdsk ; skip spaces bcs cmderr ; if none, say error rts ; return his flags ; cmdK}err: inc done sec rts ; cmdsk: ; ; skip spaces ; ldy cmdidx cmds1: lda (cmdptr),y ; get one cmp #ateol ; none?? beq cL}mds3 ; ok, prompt cmp #space ; sp? bne cmds2 ; nope, stop iny jmp cmds1 cmds2: sty cmdidx clc rts cmds3: sty cmdidxM} sec rts ; ; ; match: see if string in (x,y) matches stuff in LINE ; match: stx strptr sty strptr+1 ldy #0 m1: lda (strN}ptr),y ; get a byte beq m2 ; end of string? cmp line,y ; look like what's in line? bne m9 ; no match iny jmp m1 m2: O}clc ; say we won rts m9: sec ; say we lost rts ; ; find the 'begin ' line ; begtxt: .byte "begin ",0 endtxt: .byte "enP}d",0 beginp: lda #fpn\ ; set path ptr sta pndptr ; in case we lda #fpn^ ; find one sta pndptr+1 ; ldx #begtxt\ ldyQ} #begtxt^ jsr match bcc beg1 ; match? ok, go do pathname stuff rts ; say we lost beg1: ; ; Y points at first char afterR} 'begin ' ; lda line,y ; find non-blank cmp #ATEOL ; eol??? beq beg9 ; yup, quit cmp #space ; sp? bne beg2 iny jmpS} beg1 beg2: ; ; find a blank ; iny lda line,y cmp #ateol beq beg9 cmp #space bne beg2 beg3: ; ; find a non-blank ; inyT} lda line,y cmp #ateol beq beg9 cmp #space beq beg3 ; ; ok, pointing at pathname ; clc tya adc #line\ tax lda #lineU}^ adc #0 tay jsr parsepn ; ; look at the pathname we got back. if it's got ; anything in it, set name and type field bitsV}, ; to keep from having things spuriously merged in later. ; lda fpn+pnd.fl ; get flags byte and #pnf.np|pnf.ep ; either naW}me or ext? beq beg9 lda #pnf.np|pnf.ep ; ok, set both sta fpn+pnd.fl beg9: clc rts ; ; return next byte from line; barfX} if eol. ; starting idx in y ; nextb: lda line,y beq nextbn ; nul? cmp #ATEOL ; end of line??? beq nextbe ; that's an errY}or iny ; bump idx rts ; and return the char nextbe: tya pha ldx #shlerr\ ldy #shlerr^ jsr dbgstr ; bitch pla tay Z}lda #0 sta line,y ; so we only bitch once nextbn: lda #$20 ; return a space rts shlerr: .byte "Bogus line! UUE file is bad[}.",ATEOL,0 ; ; process a line ; ltxt: .byte 0,0,0,0 ; text bytes this line lbin: .byte 0,0,0 ; binary bytes this line lbc: .b\}yte 0 ; bin count this bytec: .byte 0 ; temp eatline: lda line ; get size byte sec sbc #$20 ; uncharacterify sta lbc ; s]}ave it lda #1 ; start line data sta lineidx ; at 1 uud1: lda lbc ; any remaining here? bne uud2 jmp uud9 uud2: ldy lin^}eidx ; get line idx into y ldx #4 ; get next 4 stx bytec ldx #0 uud3: ; lda line,y ; get a uu char jsr nextb sec sbc #$_}20 ; unchar it and #$3F ; mask, for sanity check sta ltxt,x ; shove it in hold area ; iny inx dec bytec bne uud3 sty li`}neidx ; save idx for next time ; ; guts of uudecode ; lda ltxt ; get byte 0 asl a asl a ; shift left 2 sta lbin ; store ta}op 6 bits lda ltxt+1 ; get byte 1 lsr a ; shift right lsr a ; by 4, lsr a ; leaving lsr a ; two bits ora lbin ; ORb} with 6 from before sta lbin ; making the first whole byte! ; lda ltxt+1 ; get byte 1 again asl a ; shift left asl a ; bc}y 4, asl a ; leaving asl a ; top 4 sta lbin+1 ; save temporarily lda ltxt+2 ; get byte 2 lsr a ; shift right 2, lsr d}a ; leaving bottom 4 ora lbin+1 ; OR em in sta lbin+1 ; and save em ; lda ltxt+2 ; get byte 2 asl a ; shift left 6, asle} a ; leaving top 2 asl a asl a asl a asl a ora ltxt+3 ; or with last byte sta lbin+2 ; done! ; ; now, that wasn't so hf}ard, was it? ; lda lbin ; get a byte jsr genbyte ; shove it out dec lbc ; dec line byte count beq uud9 ; done with line? g} lda lbin+1 ; get a byte jsr genbyte ; shove it out dec lbc ; dec line byte count beq uud9 ; done with line? lda lbin+2 ;q}aB%DOS SYSB*)DUP SYSBSYAU COMBFeYAU DOCBYAU M65BYAUE COMBYAUE M65 get a byte jsr genbyte ; shove it out dec lbc ; dec line byte count beq uud9 ; done with line? jmp uud1 ; around again ur}ud9: rts ; closef: LDX #INF LDA #CCLOSE JSR IOCMD LDx #outf LDA #CCLOSE JSR IOCMD rts ; ; commentary ; amuse1: .byte s}"Yow! ",0 amuse2: .byte " -> ",0 START: ; lda #0 ; zap counts etc sta chksum sta chksum+1 sta nbytes sta nbytes+1 sta nt}bytes+2 ; lda #1 sta done ; getcmd will clr it if cmd jsr getcmd bcc start1 jmp exit start1: lda #dpn\ sta pndptr ldau} #dpn^ sta pndptr+1 ldx #idname\ ldy #idname^ jsr parsepn ; parse the default pathname lda #dpn\ sta pnddef lda #dpn^v} sta pnddef+1 ; LDY #ipn/256 LDx #ipn&$FF JSR GETFNAME ldx #iname\ ldy #iname^ jsr pn2str ; ; Open the source file ; w}LDX #inf LDY #iname/256 LDA #iname&$FF JSR OPENin cpy #1 ; win? beq main1 tya pha ldx #err1\ ldy #err1^ jsr dbgstrx} pla jsr dbghex jsr dbgeol jmp finish err1: .byte "Open error on infile: ",0 main1: ; ; find the begin ; findb: jsr ready}line bcc findb1 ; got one ldx #nobtxt\ ldy #nobtxt^ jsr dbgstr jmp finish nobtxt: .byte "No 'begin ' found",ATEOL,0 finz}db1: jsr beginp ; try to parse 'begin ...' bcs findb ; nope, try again ; ; now do target path. beginp parsed fpn for us.{} ; lda #dpn\ sta pndptr lda #dpn^ sta pndptr+1 ldx #odname\ ldy #odname^ jsr parsepn ; parse the default pathname ; |}lda #fpn\ ; use fpn for defaults sta pnddef lda #fpn^ sta pnddef+1 ; LDY #opn/256 LDx #opn&$FF JSR GETFNAME ; lda #dp}}n\ ; use dpn for defaults sta pnddef lda #dpn^ sta pnddef+1 jsr pnmerge ; lda #ipn\ ; and merge in ipn sta pnddef ; ~}in case no device lda #ipn^ ; specified sta pnddef+1 jsr pnmerge ; ldx #oname\ ldy #oname^ jsr pn2str ; ; say what we'}re doing ; ldx #amuse1\ ldy #amuse1^ jsr dbgstr ldx #iname\ ldy #iname^ jsr dbgstre ldx #amuse2\ ldy #amuse2^ jsr db}gstr ldx #oname\ ldy #oname^ jsr dbgstre jsr dbgeol ; ; Open the bin file ; LDX #outf LDY #oname/256 LDA #oname&$FF J}SR OPENOUT cpy #1 ; win? beq main2 tya pha ldx #err2\ ldy #err2^ jsr dbgstr pla jsr dbghex jsr dbgeol jmp finish }err2: .byte "Open error on outfile: ",0 ; main2: LDA #1 STA BINEMPTY ; nothing in bin buf jsr FLUSHBIN ; init ptrs etc ; ;} Read til eof. ; MAINLOOP JSR READLINE bcs badeof ; couldn't get line? ldx #endtxt\ ; see end? ldy #endtxt^ jsr match }bcc cleanup JSR EATLINE jmp mainloop bctxt: .byte "Byte count = ",0 cktxt: .byte "Checksum = #x",0 eoftxt: .byte "Unexpecte}d EOF!",ATEOL,0 badeof: ldx #eoftxt\ ldy #eoftxt^ jsr dbgstr cleanup: jsr flushbin jsr closef ; close em ; ; display by}te count etc ; ldx #bctxt\ ldy #bctxt^ jsr dbgstr ; lda nbytes+2 ; jsr dbghex ; lda nbytes+1 ; jsr dbghex ; lda nbytes ; j}sr dbghex ; ; do it in decimal. what a pain ; ; ; rather a kludge here. We need to make an fp ; 256, then use it to get top} byte in. ; lda #1 ; 256^ sta fr0+1 lda #0 sta fr0 jsr ifp jsr fmove ; move fr0 -> fr1 lda nbytes+2 ; top byte sta }fr0+1 lda #0 sta fr0 jsr ifp ; make that a float jsr fmul ; mult em together jsr fmove ; move result back to fr1 ; l}da nbytes ; lo order sta fr0 lda nbytes+1 ; mid order sta fr0+1 jsr ifp ; make a float jsr fadd ; add top byte jsr f}asc ldy #0 dec1: lda (inbuff),y pha and #$7F jsr dbgchr iny pla cmp #0 bpl dec1 ; jsr dbgeol ldx #cktxt\ ldy #ckt}xt^ jsr dbgstr lda chksum+1 jsr dbghex lda chksum jsr dbghex jsr dbgeol finish: jsr closef ; close em ; ; unless done }flag, go back for more commands ; lda done bne exit jmp start exit: ; ; make dead sure they're closed ; jsr closef ; ; Al}l done! ; RTS *=GOADR .word START ; .END ; e exit jmp start exit: ; ; make dead sure they're closed ; jsr closef ; ; Al/0q2L[7 0HH 4 B 0 Vhh`H 0h`Hɛ 0h`H`0ȱ 0`}0h`L 0HJJJJ 0h)00 00` 0 0`0123456789ABCDEFa{8 `:.*?0 : A[8``0 0 0}͵0`1ei\1TɛS O 0 0F*? H 11h0HюHihih1 11Li1h0L1}`8`1: 001 1L11. 1 111 11`0000` 1`Ȫ`}0) 1 1: 1 1 1. 1 1 1 1`*2-*2-*2 豌` +2 +2 +2}`333%9D1:FOO.COM.UUE         <4* 4 4B V0}00 0Ln4<4Hm000i0h`o2ɛ4o2ei t1 Q2o2ɛ L4ȱɛ o2`o}2 Q28`DE`HI`JK`B VC` 4L4HH 4hhL4HH 4hhL4 4 4 40Hh`HQ5 (0h 0 |08`}Write error L L LL53- 3 i?o233 5`YAUE>5 (0r3 4< 4 4L5}r3o2H 3 5`38`o2ɛ L5o2`o28`begin 666 end44)46 16 } %5`W6q2T6U6V6 =4T6<4W6 =4U6<4W6 =4V6<4W6T6JJP6U6JJJJQ6T6 )0 Q6Q6U6 ) 00000<43 _5L"9(43 t1(44 43 13 5*H7 (0h 0 |0L9Op}en error on infile: (43 t1(4 Q24 44 Q2Р3 1N7 (03 C0V7 (0Р3 C0 |0 3 5+HJ8 (0}h 0 |0L9Open error on outfile: 16 Y6C<4+6 %5-6 %5L8Byte count = Checksum = #xUnexpected EOF!8 (0 ?78 (}0թ ݭ0թ ݭ0ԭ0 ؠH) 0h |08 (00 00 0 |0 ?73L[7 ?7`[7 (0 ?78 (q;.TITLE "YAUE: Yet Another Uu Encoder" ;.TAB 8,14,20 *= $3000 ; ; .INCLUDE D2:SYSEQU.ASM ;----------------------------------}------------------------- ; .PAGE "OSS SYSTEM EQUATES FOR ATARI" ; ; FILE = #DN:SYSEQU.ASM ; ; ; I/O CONTROL BLOCK EQUATES ;} SAVEPC = * ; SAVE CURRENT ORG ; *= $0340 ; START OF SYSTEM IOCBS IOCB ; ICHID *= *+1 ; DEVICE HANDLER IS (SET BY OS) ICDNO} *= *+1 ; DEVICE NUMBER (SET BY OS) ICCOM *= *+1 ; I/O COMMAND ICSTA *= *+1 ; I/O STATUS ICBADR *= *+2 ; BUFFER ADDRESS I}CPUT *= *+2 ; DH PUT ROUTINE (ADR-1) ICBLEN *= *+2 ; BUFFER LENGTH ICAUX1 *= *+1 ; AUX 1 ICAUX2 *= *+1 ; AUX 2 ICAUX3 *=} *+1 ; AUX 3 ICAUX4 *= *+1 ; AUX 4 ICAUX5 *= *+1 ; AUX 5 ICAUX6 *= *+1 ; AUX 6 ; IOCBLEN = *-IOCB ; LENGTH OF ONE IOCB ; ;} IOCB COMMAND VALUE EQUATES ; COPN = 3 ; OPEN CGBINR = 7 ; GET BINARY RECORD CGTXTR = 5 ; GET TEXT RECORD CPBINR = 11 ; PUT B}INARY RECORD CPTXTR = 9 ; PUT TEXT RECORD CCLOSE = 12 ; CLOSE CSTAT = 13 ; GET STATUS ; ; DEVICE DEPENDENT COMMAND EQUATES F}OR FILE MANAGER ; CREN = 32 ; RENAME CERA = 33 ; ERASE CPRO = 35 ; PROTECT CUNP = 36 ; UNPROTECT CPOINT = 37 ; POINT CNOTE = }38 ; NOTE ; ; AUX1 VALUES REQD FOR OPEN ; OPIN = 4 ; OPEN INPUT OPOUT = 8 ; OPEN OUTPUT OPUPD = 12 ; OPEN UPDATE OPAPND = 9 ;} OPEN APPEND OPDIR = 6 ; OPEN DIRECTORY ; ; .PAGE ; ; EXECUTE FLAG DEFINES ; EXCYES = $80 ; EXECUTE IN PROGRESS EXCSCR = $}40 ; ECHO EXCUTE INPUT TO SCREEN EXCNEW = $10 ; EXECUTE START UP MODE EXCSUP = $20 ; COLD START EXEC FLAG ; ; MISC ADDRESS EQ}UATES ; CPALOC = $0A ; POINTER TO CP/A WARMST = $08 ; WARM START (0=COLD) MEMLO = $2E7 ; AVAIL MEM (LOW) PTR MEMTOP = $2E5 ; }AVAIL MEM (HIGH) PTR APPMHI = $0E ; UPPER LIMIT OF APPLICATION MEMORY INITADR = $2E2 ; ATARI LOAD/INIT ADR GOADR = $2E0 ; ATA}RI LOAD/GO ADR CARTLOC = $BFFA ; CARTRIDGE RUN LOCATION CIO = $E456 ; CIO ENTRY ADR EOL = $9B ; END OF LINE CHAR ; ; Characte}r defs from sysmac.sml ; ATCLR = $7D ;CLEAR SCREEN CHARACTER ATRUB = $7E ;BACK SPACE (RUBOUT) ATTAB = $7F ;TAB ATEOL = $9B ;E}ND-OF-LINE ATBEL = $FD ;CONSOLE BELL ATURW = $1C ;UP-ARROW ATDRW = $1D ;DOWN-ARROW ATLRW = $1E ;LEFT-ARROW ATRRW = $1F ;RIGHT}-ARROW space = $20 ; ; CP/A FUNCTION AND VALUE DISPLACEMSNT ; (INDIRECT THROUGH CPALOC) ; IE. (CPALOC),Y ; CPG}NFN = 3 ; GET NEXT FILE NAME CPDFDV = $07 ; DEFAULT DRIVE (3 BYTES) CPBUFP = $0A ; CMD BUFF NEXT CHAR POINTR (1 BYTE) CPEXFL }= $0B ; EXECUTE FLAG CPEXFN = $0C ; EXECUTE FILE NAME (16 BYTES) CPEXNP = $1C ; EXECUTE NOTE/POINT VALUES CPFNAM = $21 ; FILE}NAME BUFFER RUNLOC = $3D ; CP/A LOAD/RUN ADR CPCMDB = $3F ; COMMAND BUFFER (60 BYTES) ;CPCMDGO = -6 ; CP SUBROUTINE VECTOR ;} *= SAVEPC ; RESTORE PC ; ;----------------------------------------------------------- ; ; .page "Page zero" zpc = $80 ; pag}e zero pc spc1 = * *= zpc cmdptr: .blkb 2 ; pointer to cmd line binp: .blkb 2 ; pointer into binary buf strptr: .blkb 2 dbg}ptr: .blkb 2 ; end of page zero defs zpc1 = * *= spc1 ; ; fp defs ; fr0 = $D4 fr1 = $E0 flptr = $FC inbuff = $F3 cix = $F2 ;} fasc = $D8E6 ; fp -> ascii ifp = $D9AA ; int -> fp fadd = $DA66 ; fp + fp fmul = $DADB ; fr0 * fr1 -> fr0 fmove = $DDB6 ; fr}0 -> fr1 ; ; .PAGE "Data defs" ; inf = $10 ; input file outf = $20 ; output file ; *= $3000 JMP START ; in case goadr ignor}ed ; ; binary buffering stuff ; binary buf size must be a ; multiple of 256 ; ; put it back if we decide to do buffering ; ;}BINMAX = 8192 ; how much binary to buffer up ;BINBUF: .blkb BINMAX ;BINSIZE: .word 0 ;BINEMPTY: .byte 1 ; nbytes: .byte 0,0,0} ; 3 ought to be big enough chksum: .byte 0,0 ; ones comp checksum ; ; debug flag ; debug: .byte 0 ; ; Debug code ; ; char i}n A out to tty ; ; ; debug code ; .byte 0 dbgchr: sta dbgchr-1 tya pha txa pha ldx #0 txa tay jsr SETLEN lda #CPBI}NR STA ICCOM,X lda dbgchr-1 JSR CIO pla tax pla tay rts ; ; dump a str, ptr in x,y, terminated by 0. ; preserves A ; }dbgstr: pha stx dbgptr sty dbgptr+1 ldy #0 dbgs1: lda (dbgptr),y beq dbgs2 jsr dbgchr iny bne dbgs1 inc dbgptr bne} dbgs1 inc dbgptr+1 bne dbgs1 dbgs2: pla rts ; dbgstre: pha stx dbgptr sty dbgptr+1 ldy #0 dbge1: lda (dbgptr),y cm}p #ateol beq dbge2 jsr dbgchr iny bne dbge1 inc dbgptr bne dbge1 inc dbgptr+1 bne dbge1 dbge2: pla rts ; ; print a} string, textc form ; .byte 0 dbgstrc: pha stx dbgptr sty dbgptr+1 ldy #0 lda (dbgptr),y beq dbgsc9 sta dbgstrc-1 dbg}sc1: iny lda (dbgptr),y jsr dbgchr dec dbgstrc-1 bne dbgsc1 dbgsc9: pla rts ; dbgeol: lda #ATEOL jmp dbgchr ; ; prin}t a byte (in A) in hex ; .byte 0 dbghex: pha lsr a lsr a lsr a lsr a jsr dbghd pla dbghd: and #$0F stx dbghex-1 ta}x lda hex,x jsr dbgchr ldx dbghex-1 rts dbghxy: tya jsr dbghex txa jsr dbghex rts HEX: .BYTE "0123456789ABCDEF" ; ;} ;---------------------------------------------------------------- ; ; pathname parsing stuff. ; ; a pathname consists of opt}ional device, name, and optional ; extension. ; ; a pathname descriptor is a structure containing three fields, ; each of whi}ch is a byte of max, a byte of length, and a (max) bytes ; of data. they are: ; dev device spec (2 bytes) ; name file name (}8 bytes) ; ext file type (3 bytes) ; ; equates for pathname descriptor block ; pnd.fl = 0 ; flags byte pnd.dm = 1 ; dev ma}x, 1 byte pnd.ds = 2 ; dev size, one byte pnd.dt = 3 ; dev text, two bytes pnd.nm = 5 ; name max, 1 byte pnd.ns = 6 ; nam}e size, 1 byte pnd.nt = 7 ; name text, 8 bytes pnd.em = 15 ; ext max pnd.es = 16 pnd.et = 17 pndsiz = 20 ; total size ; ; }generic component equates ; pnc.m = 0 ; max this component pnc.s = 1 ; size this component pnc.t = 2 ; text this component} ; ; bits in flag byte ; pnf.dp = $01 ; dev spec present pnf.np = $02 ; name present pnf.ep = $04 ; type present pnf.wl = }$08 ; wild card somewhere ; ; if we had macros, the macro for building one of these would ; look like this: ; ; .byte 0 ; f}lags ; .byte 2 ; dev max ; .byte 0 ; .blkb 2 ; .byte 8 ; name max ; .byte 0 ; .blkb 8 ; .byte 3 ; .byte 0 ; .blkb 3 ; ; poi}nters ; spc2 = * *= zpc1 pnptr .blkb 2 ; string ptr pndptr .blkb 2 ; pathname struct pnddef .blkb 2 ; default pncptr .blkb }2 ; pathname component zpc2 = * *= spc2 ; ppnt0: .byte 0 ; temp for parse-pathname and friends ppnt1: .byte 0 ppnt2: .byte} 0 ; ; pncupc: char-upcase char in A ; pncupc: cmp #'a ; >= 'a ? bcc pncupc9 ; nope, leave cmp #'z+1 ; < 'z? bcs pncu}pc9 ; nope, leave sec sbc #$20 ; shift to up case. (carry's set) pncupc9: rts ; ; pnclgl: char in a legal pathname cha}r? ; returns carry set if not legal ; pnclgl: cmp #': ; colon's ok beq pnclgl9 cmp #'. ; dot's ok too beq pnclgl9 cm}p #'* ; star is ok beq pnclgl9 cmp #'? ; q-mark is ok beq pnclgl9 cmp #'0 ; 0..9 is ok bcc pnclgl8 ; less, no good } cmp #'9+1 bcc pnclgl9 ; less, ok cmp #'A ; alpha? bcc pnclgl8 ; less is no good cmp #'Z+1 bcc pnclgl9 ; A..Z's ok p}nclgl8: sec ; error return rts pnclgl9: clc ; ok return rts ; ; pnfindc: find a character, in x, in (pnptr), starting} ; at y. returns idx or -1 in y, EQ if found, NEQ ; if not found. Trashes A ; pnfindc: stx ppnt1 ; save char pnfindc1}: lda (pnptr),y ; get a char beq pnfindc8 ; 0? ok, stop here jsr pncupc ; upcase it jsr pnclgl ; legal pathname char? }bcs pnfindc8 ; nope, go error cmp ppnt1 ; compare it beq pnfindc9 ; got it, return iny ; next! bne pnfindc1 pnfindc8: } ldy #-1 ; return 'not found' pnfindc9: rts ; ; parsepn:: ; grok a pathname string into a pathname descriptor. ; expects pa}thname string pointed to by x,y, desc in (pndptr). ; pathname string terminated by any non-pathname char. ; ; this routine co}pies in one component. Initial idx in Y, terminating ; character in X, component offset in desc in A ; ;ppndbg1: .byte "Ente}r parsepn",ATEOL,0 ;ppndbg2: .byte "Leave parsepn",ATEOL,0 ppnct: .byte 0 ; terminator char ppncf: .byte 0 ; flags for path}name we're parsing ppncpf: .byte 0 ; flag to set in component we're on ppncomp: stx ppnct ; save terminator clc ; first} calculate adc pndptr ; pointer to pathname sta pncptr ; component lda pndptr+1 adc #0 sta pncptr+1 ppncp1: lda (p}nptr),y ; get a char ; below? iny ; and bump the string idx beq ppncp9 ; always terminate on nuls cmp ppnct ; hit termi}nator? beq ppncp8 ; yes, stop this component cmp #ATEOL ; eol? beq ppncp9 ; yes, always terminate on eols, too cmp #sp}ace ; space? beq ppncp9 ; yes, always terminate on spaces, too iny ; and bump the string idx jsr pncupc ; upcase it }jsr pnclgl ; legal char? bcs ppncp9 ; nope, stop here cmp #'* ; is it one of the wild chars? beq ppncp2 ; yes, flag it} as such cmp #'? bne ppncp3 ppncp2: pha ; save char lda #pnf.wl ; or in the 'wild' flag ora ppncf sta ppncf pla ;} get char back ppncp3: sty ppnt0 ; save y for a bit pha ; save char ldy #pnc.s ; component size offset lda (pncptr),y} ; get component size ; check size ldy #pnc.m ; component max cmp (pncptr),y ; compare size to max bcs ppncp6 ; too big!} ignore this byte ldy #pnc.s ; idx for size again ; pha ; save size for later indexing clc ; add one to it for adc #}1 ; next time sta (pncptr),y ; put it back pla ; get the old size (index) back clc ; zap carry again, and adc #pnc.}t ; add dev text offset tay ; into y pla ; get char back sta (pncptr),y ; stuff into dev text lda ppncpf ; or in t}he flag corresponding to ora ppncf ; this component sta ppncf jmp ppncp7 ; and go back for more ppncp6: pla ; throw} char away ppncp7: ldy ppnt0 ; get string idx back jmp ppncp1 ppncp8: ; ; found terminator. Skip it. iny clc ; tell c}aller we saw it rts ; ppncp9: sec ; tell caller we didn't see it rts ; ; The main routine of the pathname parser. ; pars}epn: stx pnptr ; set string pointer lo sty pnptr+1 ; and hi ;zzz debug ; ldx #ppndbg1\ ; ldy #ppndbg1^ ; jsr pstrnul ;zz}z lda #0 ; first zap len flds in desc sta ppncf ; and flags in progress ldy #pnd.ds ; dev size sta (pndptr),y ; zap l}dy #pnd.ns sta (pndptr),y ldy #pnd.es sta (pndptr),y ldy #0 ; idx into name string ppndev: ldx #': ; do we have a colo}n? jsr pnfindc bmi ppndev9 ; nope, skip this part lda #pnf.dp ; flag to set if we do it sta ppncpf ldy #0 ; start at }zero please lda #pnd.dm ; do device component jsr ppncomp jmp ppnnam ; go do the name ppndev9: ldy #0 ; reset string p}tr ppnnam: lda #pnf.np ; flag to set if we do it sta ppncpf lda #pnd.nm ; do name component ldx #'. ; stop at dot }; y's already set jsr ppncomp ; ; rather a kludge. If see a dot, always say ; ext present, even if no ext text ; bcs ppnex}t lda #pnf.ep ora ppncf sta ppncf ppnext: lda #pnf.ep ; flag to set if we do it sta ppncpf lda #pnd.em ; extension, p}lease ldx #ATEOL ; sort of irrelevant, as we'll stop ; on any illegal char. jsr ppncomp ; y's already set. lda ppnc}f ; now put in accumulated flags ldy #pnd.fl sta (pndptr),y ;zzz debug ; ldx #ppndbg2\ ; ldy #ppndbg2^ ; jsr pstrnul ;zzz } rts ; done! ; ; pn2str: (parsed) pathname to string. ; expects a pathname descriptor in (pndptr) ; and a string in X,}Y. Generates a namestring ; terminated by ATEOL, suitable for passing to ; CIO. Note that it wants a fully qualified ; } parsed pathname. ;ppndbg3: .byte "Enter pn2str",ATEOL,0 ;ppndbg4: .byte "Leave pn2str",ATEOL,0 ; ; this pushes one byte int}o output string ; pn2sp: sty ppnt2 ; save y value for a bit ldy ppnt0 ; get string idx sta (pnptr),y ; shove the char ;z}zz debug ; pha ; save a ; txa ; save x ; pha ; lda (pnptr),y ; get char back ; pha ; lda #'| ; jsr prchr ; pla ; jsr prch}r ; pla ; tax ; pla ;zzz inc ppnt0 ; bump the str idx ldy ppnt2 ; get y back rts ; ; copy one component into outgoing st}ring. ; y contains offset into desc for component text, x contains size ; pn2scs: lda (pndptr),y ; get a char jsr pn2sp ; }stuff it iny ; bump dev text idx dex ; dec size bne pn2scs ; back for more rts ; ; this inits regs, given an initial} offset into the descriptor. ; returns Z if length 0. ; pn2sin: lda (pndptr),y ; get the component size ;zzz debug ; pha ; t}ya ; pha ; lda #'# ; jsr prchr ; pla ; y val ; pha ; jsr prbyte ; pla ; pha ; tay ; lda (pndptr),y ; jsr prbyte ; pla ; tay} ; pla ;zzz iny ; point y at text tax ; save it as a counter, set Z for return rts ; ; the main routine ; pn2str: st}x pnptr ; set pathname string lo sty pnptr+1 ; and hi ;zzz debug ; ldx #ppndbg3\ ; ldy #ppndbg3^ ; jsr pstrnul ; lda pnpt}r+1 ; jsr prbyte ; lda pnptr ; jsr prbyte ;zzz ldy #0 ; string idx sty ppnt0 ldy #pnd.fl ; get flags lda (pndptr),y an}d #pnf.dp ; device present? beq pn2str1 ; nope, skip it ldy #pnd.ds ; dev component size jsr pn2sin ; set up regs beq} pn2str1 ; No dev??? ok, skip it jsr pn2scs ; copy a string lda #': ; get a colon jsr pn2sp ; push it in ; pn2str1: }ldy #pnd.ns ; name component size jsr pn2sin ; set up beq pn2str2 ; zero length name?? this should error ... jsr pn2scs} ; copy it in ; pn2str2: lda #'. ; get a dot jsr pn2sp ; push it in ; ldy #pnd.es ; name component size jsr pn2sin b}eq pn2str3 ; zero length ext? jsr pn2scs ; copy it in pn2str3: lda #ATEOL ; get an eol jsr pn2sp ; push it in ;zzz deb }ug ; ldx #ppndbg4\ ; ldy #ppndbg4^ ; jsr pstrnul ;zzz rts ; done!!! ; ; pnmerge:: Merge two pathnames. Move components fr }om the ; first into missing components of the second, ie ; merge "D1:FOO.BAR","CRUD.BAZ" -> "D1:CRUD.BAZ" ; ; wants pnddef } pointing at pn1, pndptr at pn2 ; pnmflg: .byte 0 ; flag byte for which comp we're doing pnmc: sta pnmflg ; store componen }t mask ldx #0 ; idx for flags byte lda (pndptr,x) ; get flags and pnmflg ; target path have this component? bne pnmc9  }; if there, skip lda (pndptr),y ; get component size in target pathname bne pnmc9 ; nonzero, try next lda (pnddef,x) ; ge}t flags for default pn and pnmflg ; and with mask beq pnmc9 ; if not there, skip component lda (pnddef),y ; ok, get the }one we're merging from beq pnmc9 ; this one zero too?? ok, skip it tax ; get size in x inx ; inc to include size byte} pnmc1: lda (pnddef),y ; get a byte sta (pndptr),y ; put it in target iny ; bump component ptr dex ; dec count bne p}nmc1 ; round again pnmc9: rts ; done with this component ;ppndbg5: .byte "Enter pnmerge",ATEOL,0 ;ppndbg6: .byte "Leave }pnmerge",ATEOL,0 pnmerge: ;zzz debug ; ldx #ppndbg5\ ; ldy #ppndbg5^ ; jsr pstrnul ;zzz lda #pnf.dp ; device flag ldy #pn}d.ds ; look at dev component size jsr pnmc ; merge this component lda #pnf.np ; device flag ldy #pnd.ns ; do name jsr} pnmc ; ... lda #pnf.ep ; device flag ldy #pnd.es ; and extension jsr pnmc pnmzzz: ldy #pnd.fl ; merge flags flds l}da (pnddef),y ora (pndptr),y sta (pndptr),y ;zzz debug ; ldx #ppndbg6\ ; ldy #ppndbg6^ ; jsr pstrnul ;zzz rts ; done! ;} ; ;----------------------------------------------------------------- ; cmdidx: .byte 0 ; idx into cmd line LINELEN: .byte 0 }LINEIDX: .byte 0 LINE: .blkb 256 ; cmdmax = 60 ; command line max cmdbuf .blkb cmdmax cmddone: .byte 0 ; if command line alre}ady processed ; done: .byte 0 ; time to exit flag ; iname: .blkb 32 ; input file name oname: .blkb 32 ; output file name idna}me: .byte "D1:FOO.COM",ateol ; input default defdrv = idname+1 odname: .byte ".UUE",ateol ; output default ipn: .byte 0,2,0,"} ",8,0," ",3,0," " ; input pathame opn: .byte 0,2,0," ",8,0," ",3,0," " ; output pathname dpn: .byte 0,2,}0," ",8,0," ",3,0," " ; default pathname ineof: .byte 0 ; eof on inf ; ; ; .PAGE "Utils" ; getbyte: lda ineof bn}e getb8 ldx #inf lda #0 tay jsr setbuf jsr setlen lda #CGBINR ; get binary sta iccom,x jsr cio bmi getb7 inc nbyte}s bne getb9 inc nbytes+1 bne getb9 inc nbytes+2 jmp getb9 getb7: lda #1 sta ineof getb8: lda #0 getb9: pha clc adc} chksum sta chksum lda chksum+1 adc #0 sta chksum+1 pla rts ; ; x,Y points to pathname ; GETFNAME stx pndptr sty pndp}tr+1 ; ; zap the pathname ; lda #0 ldy #pnd.fl sta (pndptr),y ldy #pnd.ds sta (pndptr),y ldy #pnd.ns sta (pndptr),y l }dy #pnd.es sta (pndptr),y ; ldy cmdidx ; get cmd line idx ; ; y points to pathname ; lda (cmdptr),y cmp #ateol ; eol? !}beq getf9 ; yup, stop sty cmdidx ; for next time tya clc adc cmdptr tax ; lo byte lda cmdptr+1 adc #0 ; get carry"} tay ; points to namestring now jsr parsepn ; parse it jsr pnmerge ; ; now skip this one. This is sort of gross... ; #}ldy cmdidx getf1: lda (cmdptr),y ; find a space cmp #ateol beq getf3 cmp #space beq getf2 iny jmp getf1 getf2: iny $}; skip it lda (cmdptr),y cmp #ateol beq getf3 cmp #space beq getf2 ; getf3: sty cmdidx clc ; say we win rts getf9: %} sty cmdidx jsr pnmerge ; merge defaults anyway sec ; say we lose rts ; ; IOCB in X, addr hi in Y, lo in A ; SETBUF ST&}A ICBADR,X TYA STA ICBADR+1,X RTS SETLEN STA ICBLEN,X TYA STA ICBLEN+1,X RTS SETAUX STA ICAUX1,X TYA STA ICAUX2,X '}RTS ; ; IO command in A ; IOCMD STA ICCOM,X JSR CIO LDA ICSTA,X RTS ; ; A,Y point to name ; OPENF JSR SETBUF LDA #COPN (} JMP IOCMD OPENIN PHA TYA PHA LDA #OPIN LDY #0 JSR SETAUX PLA TAY PLA JMP OPENF OPENOUT PHA TYA PHA LDA #OPOUT )} LDY #0 JSR SETAUX PLA TAY PLA JMP OPENF ; ; write the line pointed to by x,y ; wrline: txa LDX #outF JSR SETBUF LDA*} #255 LDY #0 JSR SETLEN LDA #CPTXTR JSR IOCMD cpy #0 ; status? bmi wrerr ; lose, die PHA ; ; debug ; ; ldx #line\ ; +}ldy #line^ ; jsr dbgstre ;; wrl2 PLA clc RTS wrerr: tya pha ldx #wremsg\ ldy #wremsg^ jsr dbgstr pla jsr dbghex js,}r dbgeol sec rts wremsg: .byte ATEOL,"Write error ",0 ; ; getcmd: get a pointer to command line. ; Leave cmdidx pointing -}at ; first non-blank in the command line. ; getcmd: ; ; first try to guess what OS we're running under. ; Use the algorithm s.}uggested by Dick Curzon. ; Look thru $0A. Should see a jmp, another jmp, ; and something that's not a jump. ; ldy #0 lda (/}$0A),y cmp #$4C ; a jmp? bne getnxl ; nope ldy #3 lda ($0A),y cmp #$4C ; a jmp? bne getnxl ; nope ldy #6 lda ($0A0}),y cmp #$4C ; a jmp? bne getcxl ; nope, that means xl ; ; note that the above test will be passed by ; Spartados too, wh1}ich means we'll die horribly. ; Someone should come up with a better test... ; getnxl: ; ; not xl; just prompt for it ; jmp 2}ncmd getcxl: lda cmddone ; we already do this one? bne ncmd ; yup, don't do it again ; ; get dos xl's default dev ; ldy3} #cpdfdv+1 lda (cpaloc),y sta defdrv ; ; get command line from DOS XL ; lda cpaloc sta cmdptr lda cpaloc+1 sta cmdptr+14} LDY #CPBUFP LDA (CPALOC),Y CLC ADC #CPCMDB sta cmdidx ; ; say we've processed this command line. ; lda #1 sta cmddone5} ; ; we got one from cmd line; set done ; flag so we'll exit after we're done ; ; lda #1 sta done jsr cmdsk ; skip spaces6} bcs ncmd ; none? ok, prompt rts ; return his codes ; ; no command line, prompt for one ; prompt: .byte "YAUE>",0 ncmd: 7} ldx #prompt\ ldy #prompt^ jsr dbgstr ldx #0 ; e: iocb lda #cmdbuf\ ldy #cmdbuf^ jsr setbuf lda #cmdmax\ ldy #cmdmax8}^ jsr setlen lda #CGTXTR ; get rec jsr iocmd cpy #0 ; win? bpl ncmd1 ; yes, go do it jmp cmderr ncmd1: lda #cmdbuf\9} sta cmdptr lda #cmdbuf^ sta cmdptr+1 ldy #0 sty cmdidx lda icblen,x ; get low order len beq cmderr ; if zero len cmd:}, exit lda #0 ; if get here, not done sta done jsr cmdsk ; skip spaces bcs cmderr ; if none, say error rts ; return;} his flags ; cmderr: inc done sec rts ; cmdsk: ; ; skip spaces ; ldy cmdidx cmds1: lda (cmdptr),y ; get one cmp #ateol <} ; none?? beq cmds3 ; ok, prompt cmp #space ; sp? bne cmds2 ; nope, stop iny jmp cmds1 cmds2: sty cmdidx clc rts c=}mds3: sty cmdidx sec rts ; ; write the 'begin ' line ; begtxt: .byte "begin 666 " begfn: .byte " ",ateol>} endt1: .byte " ",ateol endt2: .byte "end",ateol wrbegin: lda #ipn\ ; set path ptr sta pndptr ; in case we lda #ipn^ ;?} find one sta pndptr+1 ; ; zap dev flg in ipn, so it won't show up in name ; lda ipn+pnd.fl and #$FF-pnf.dp sta ipn+pnd.@}fl ldx #begfn\ ldy #begfn^ jsr pn2str ; ; now write it ; LDY #begtxt/256 LDx #begtxt&$FF JSR wrline rts ; ; process a A}line ; ltxt: .byte 0,0,0,0 ; text bytes this line lbin: .byte 0,0,0 ; binary bytes this line lbc: .byte 0 ; bin count this bB}ytec: .byte 0 ; temp spitline: lda #0 ; bin count this line sta lbc ; save it lda #1 ; start line data sta lineidx ; at C}1 uue1: ; ; get 3 bytes ; lda #0 sta lbin sta lbin+1 sta lbin+2 jsr getbyte sta lbin lda ineof ; out of data? bne uueD}2 ; yup, don't inc count inc lbc jsr getbyte sta lbin+1 lda ineof ; out of data? bne uue2 ; yup, don't inc count inc lbE}c jsr getbyte sta lbin+2 lda ineof ; out of data? bne uue2 ; yup, don't inc count inc lbc uue2: ; ; guts of uuencode ; F}lda lbin ; get first byte lsr a ; shift right lsr a ; by 2 sta ltxt ; for the first byte ; lda lbin+1 ; get the second bG}yte lsr a ; shift right lsr a ; 4 lsr a ; . lsr a ; . sta ltxt+1 ; save here for a sec lda lbin ; get the first one H}again asl a ; shift left asl a ; 4 asl a ; . asl a ; . and #$30 ; mask the bits we want ora ltxt+1 ; or with top 4 oI}f second byte sta ltxt+1 ; yielding second encoded byte ; lda lbin+1 ; get second bin byte asl a ; shift left 2 asl a anJ}d #$3C ; mask 4 bits we're keeping sta ltxt+2 ; save for a sec lda lbin+2 ; get last bin byte lsr a ; shift right 6 lsr aK} lsr a lsr a lsr a lsr a ora ltxt+2 ; or in last 4 bits sta ltxt+2 ; yielding 3rd encoded ; lda lbin+2 ; get last byteL} and #$3f ; mask for bottom 6 sta ltxt+3 ; yielding last encoded! ; ; now, that wasn't so hard, was it? ; ldy lineidx ; geM}t line idx lda ltxt and #$3F ; sanity check clc adc #$20 ; make it a char sta line,y ; and store it iny ; lda ltxt+1 N}and #$3F ; sanity check clc adc #$20 ; make it a char sta line,y ; and store it iny ; lda ltxt+2 and #$3F ; sanity checO}k clc adc #$20 ; make it a char sta line,y ; and store it iny ; lda ltxt+3 and #$3F ; sanity check clc adc #$20 ; makP}e it a char sta line,y ; and store it iny ; sty lineidx ; ; see if time to flush ; lda lbc ; how many in this line? cmp Q}#45 bcs uue8 ; time to flush lda ineof ; eof on inf? bne uue8 ; yup, flush jmp uue1 ; go back for more uue8: lda lbc ; gR}et byte count clc adc #$20 ; make it a char sta line ; save as first byte ldy lineidx ; get line idx lda #'y ; our tradeS}mark sta line,y iny lda #ATEOL sta line,y ldx #line\ ldy #line^ jsr wrline ; write it for real clc rts ; closef: LDT}X #INF LDA #CCLOSE JSR IOCMD LDx #outf LDA #CCLOSE JSR IOCMD rts ; ; commentary ; amuse1: .byte "Yowee! ",0 amuse2: .byU}te " -> ",0 START: ; lda #0 ; zap counts etc sta chksum sta chksum+1 sta nbytes sta nbytes+1 sta nbytes+2 sta ineof ; V} lda #1 sta done ; getcmd will clr it if cmd jsr getcmd bcc start1 jmp exit start1: lda #dpn\ sta pndptr lda #dpn^ stW}a pndptr+1 ldx #idname\ ldy #idname^ jsr parsepn ; parse the default pathname lda #dpn\ sta pnddef lda #dpn^ sta pnddX}ef+1 ; LDY #ipn/256 LDx #ipn&$FF JSR GETFNAME ldx #iname\ ldy #iname^ jsr pn2str ; ; Open the source file ; LDX #inf Y}LDY #iname/256 LDA #iname&$FF JSR OPENin cpy #1 ; win? beq main1 tya pha ldx #err1\ ldy #err1^ jsr dbgstr pla jsrZ} dbghex jsr dbgeol jmp finish err1: .byte "Open error on infile: ",0 main1: ; ; now do target path. ; lda #dpn\ sta pndpt[}r lda #dpn^ sta pndptr+1 ldx #odname\ ldy #odname^ jsr parsepn ; parse the default pathname ; lda #dpn\ ; use dpn for\} defaults sta pnddef lda #dpn^ sta pnddef+1 jsr pnmerge ; LDY #opn/256 LDx #opn&$FF JSR GETFNAME ; lda #ipn\ ; and m]}erge in ipn sta pnddef ; in case no device lda #ipn^ ; specified sta pnddef+1 jsr pnmerge ; ldx #oname\ ldy #oname^ ^}jsr pn2str ; ; say what we're doing ; ldx #amuse1\ ldy #amuse1^ jsr dbgstr ldx #iname\ ldy #iname^ jsr dbgstre ldx #am_}use2\ ldy #amuse2^ jsr dbgstr ldx #oname\ ldy #oname^ jsr dbgstre jsr dbgeol ; ; Open the uue file ; LDX #outf LDY #o`}name/256 LDA #oname&$FF JSR OPENOUT cpy #1 ; win? beq main2 tya pha ldx #err2\ ldy #err2^ jsr dbgstr pla jsr dbgha}ex jsr dbgeol jmp finish err2: .byte "Open error on outfile: ",0 ; main2: ; LDA #1 ; STA BINEMPTY ; nothing in bin buf ; jsb}r FLUSHBIN ; init ptrs etc ; ; write the begin line ; jsr wrbegin ; ; Read til eof. ; MAINLOOP JSR spitLINE bcs badeof ; c}couldn't write line? lda ineof ; eof? beq mainloop ; nope, keep going ldx #endt1\ ; write blank line ldy #endt1^ jsr wd}rline ldx #endt2\ ; write end ldy #endt2^ jsr wrline jmp cleanup ; bctxt: .byte "Byte count = ",0 cktxt: .byte "Checksume} = #x",0 eoftxt: .byte "Unexpected EOF!",ATEOL,0 badeof: ldx #eoftxt\ ldy #eoftxt^ jsr dbgstr cleanup: jsr closef ; closf}e em ; ; display byte count etc ; ldx #bctxt\ ldy #bctxt^ jsr dbgstr ; lda nbytes+2 ; jsr dbghex ; lda nbytes+1 ; jsr dbghg}ex ; lda nbytes ; jsr dbghex ; ; do it in decimal. what a pain ; ; ; rather a kludge here. We need to make an fp ; 256, theh}n use it to get top byte in. ; lda #1 ; 256^ sta fr0+1 lda #0 sta fr0 jsr ifp jsr fmove ; move fr0 -> fr1 lda nbytesi}+2 ; top byte sta fr0+1 lda #0 sta fr0 jsr ifp ; make that a float jsr fmul ; mult em together jsr fmove ; move resuj}lt back to fr1 ; lda nbytes ; lo order sta fr0 lda nbytes+1 ; mid order sta fr0+1 jsr ifp ; make a float jsr fasc ldk}y #0 dec1: lda (inbuff),y pha and #$7F jsr dbgchr iny pla cmp #0 bpl dec1 ; jsr dbgeol ldx #cktxt\ ldy #cktxt^ jsl}r dbgstr lda chksum+1 jsr dbghex lda chksum jsr dbghex jsr dbgeol finish: jsr closef ; close em ; ; unless done flag, gm}o back for more commands ; lda done bne exit jmp start exit: ; ; make dead sure they're closed ; jsr closef ; ; All done!n} ; RTS *=GOADR .word START ; .END ; e exit jmp start exit: ; ; make dead sure they're closed ; jsr closef ; ; All done!(