MOEWS@UCONNVM.BITNET (09/09/86)
There's been a lot of UUENCODEd stuff on INFO-ATARI16 recently. If you're on an IBM system running VM/CMS, you will have two problems with raw UUENCODEd files: (1) Trailing blanks will be removed when the files are shipped over BITNET. (2) Trailing blanks will be removed if you use VM/CMS Kermit to transmit the files from VM/CMS to your Atari ST. (Try it and see!) I have written a version of UUDECODE that ignores the absence of trailing blanks in a file to be UUDECODEd; using it, I have been able to decode most of the UUENCODEd stuff that has been posted this summer. The program is written in assembly language and as a result is much faster than, for example, the UUENCODE distributed in Franco's starter kit. It can be assembled with the public domain assembler, AS68, which can be found in Franco's starter kit or on the Atari BBS. This assembler does not assemble register shifts, so all the register shifts in the code have been commented out and hand-assembled to dc.w's. David Moews MOEWS@UCONNVM.BITNET ---------------cut here---------------- * UUDECODE a file. Copyright (C) 1986 by David Moews. * Permission to use and redistribute for non-commercial purposes granted. * ... print an explanatory message ... pfile pea openm move.w #pline, -(a7) trap #1 addq.l #6, a7 * ... get the line ... lea buffer, a1 move.l #blen, d2 bsr getln * Open file! clr.w -(a7) Open for reading pea buffer move.w #fopen, -(a7) trap #1 addq.l #8, a7 * Check for error... tst.w d0 bmi error move.w d0, d1 Save handle number * Skip over first 10 characters ('begin xxx ') clr.w -(a7) move.w d1, -(a7) move.l #10, -(a7) move.w #lseek, -(a7) trap #1 add.l #10, a7 tst.l d0 bmi erroro * Initialize I/O pointers bsr init * Get filename (terminated with CR/LF) lea buf2, a1 gfloop bsr getch cmp.b #$0d, d7 beq gfdone move.b d7, (a1)+ bra gfloop gfdone clr.b (a1) bsr getch Discard $0a * * Open file! * clr.w -(a7) R/W file will be created pea buf2 move.w #fcreat, -(a7) trap #1 addq.l #8, a7 * Check for error... tst.w d0 bmi erroro move.w d0, d2 Save handle number * ... now the fun begins ... * GEM uses a0; input buffer pointers a2-a3; output ptrs a4-a5; stack ptr a7 * GEM uses d0; d3=byte count in this line; d4=byte count in this 4-character * group -or- char count while reading; * d5=group of 4 characters -or- 3 bytes. * Scratch in d7. * * LINE LOOP * * Get count. If 0, we are done. loop bsr getnn sub.b #$20, d7 Subtract space beq done * Otherwise, get that many characters. clr.w d3 High byte 0 for "dbf" move.b d7, d3 subq.w #1, d3 Correct for "dbf" bsr init3 Reset counters loop3 bsr getch3 bsr prtch dbf d3, loop3 bsr skipnl Skip over junk + $0d/$0a bra loop * * Initialize state of 3-characters. * init3 clr.w d4 rts * * Get another character from a group of 3. * getch3 tst.w d4 bne get32 * Read in another group of 4 into d3; reset count to 3. move.w #3, d4 clr.l d5 *et3l lsl.l #6, d5 get3l dc.w $ed8d bsr getnn sub.b #$20, d7 or.b d7, d5 dbf d4, get3l move.w #3, d4 Set byte count swap d5 Pattern from [0123] to [2301] * Get a character out of d3, decrement count in d2, & return! get32 move.b d5, d7 * rol.l #8, d5 dc.w $e19d subq.w #1, d4 rts * Read until we come to a newline; then skip over $0d/$0a. skipnl bsr getch cmp.b #$0d, d7 bne skipnl bra getch * * Buffered I/O subroutines. Input buffer pointer a2, end ptr in a3; * output buffer pointer a4, end prt a5. * * Sets up. init lea inpend, a2 lea inpend, a3 lea outbuf, a4 lea outend, a5 rts * Get a character in d7.b, EXCEPT that if we are at a newline, get a blank * instead. getnn cmp.l a3, a2 bcc getrn cmp.b #$0d, (a2) beq getsn move.b (a2)+, d7 rts getsn move.b #$20, d7 rts getrn bsr getrec bra getnn * Gets a character in d7.b. getch cmp.l a3, a2 bcc getr move.b (a2)+, d7 rts getr bsr getrec bra getch * * Get a new record into the buffer. getrec pea inpbuf move.l #inplen, -(a7) move.w d1, -(a7) move.w #fread, -(a7) trap #1 add.l #12, a7 tst.l d0 bmi error2 beq done No bytes read, file over, done. * Actual number of bytes read in d0! lea inpbuf, a2 lea 0(a2, d0.l), a3 rts * * Prints byte in d7.b. prtch cmp.l a5, a4 bcc putr move.b d7, (a4)+ rts putr bsr putrec bra prtch * * Dump buffer out. * Compute number of bytes to put out. putrec lea outbuf, a5 move.l a5, -(a7) sub.l a5, a4 move.l a4, -(a7) move.w d2, -(a7) move.w #fwrite, -(a7) trap #1 add.l #12, a7 tst.l d0 bmi error2 lea outbuf, a4 lea outend, a5 rts * * * We come here in case of error. error bsr pmsg bra xit * Here for error after opening 1 file. erroro bsr pmsg bsr close1 bra xit * Here for error after opening 2 files. error2 bsr pmsg bsr close1 bsr close2 bra xit * Here for normal end. Notice that we flush output buffer. done bsr putrec bsr close1 bsr close2 xit clr.w -(a7) trap #1 * pmsg pea msg move.w #pline,-(a7) trap #1 addq.l #6,a7 rts * close1 move.w d1, -(a7) move.w #fclose, -(a7) trap #1 addq.l #4, a7 rts * close2 move.w d2, -(a7) move.w #fclose, -(a7) trap #1 addq.l #4, a7 rts * * * * This subroutine reads a line of input into the buffer at a1. * Maximum buffer length should be passed in d2. Actual count is * returned in d1. The buffer should have one more byte than d2 * (to allow for a zero at the end.) getln movem.l d0/a0, -(a7) * Clear char count clr.l d1 glloop move.w #conine,-(a7) trap #1 addq.l #2, a7 * A BS? cmp.b #$08, d0 beq bs * A CR? cmp.b #$0d, d0 beq crret * Just a plain character ... are we at EOL? cmp.l d1, d2 * Yes, ignore it. beq glloop * Otherwise, store it... move.b d0, 0(a1, d1.l) addq.l #1, d1 * ... and echo. bsr echo bra glloop * A BS --- are we at start of line? bs tst.l d1 * If so, ignore keystroke. beq glloop * Otherwise, decrement counter... subq.l #1, d1 * ... print BS, space, BS to wipe out char move.b #$08, d0 bsr echo move.b #$20, d0 bsr echo move.b #$08, d0 bsr echo bra glloop * A CR --- echo & return. crret bsr echo move.b #$0a, d0 bsr echo clr.b 0(a1, d1.l) movem.l (a7)+, d0/a0 rts * * * Echo --- echoes a character in d0 to the screen. Destroys d0 & a0. echo move.w d0, -(a7) move.w #conout, -(a7) trap #1 addq.l #4, a7 rts * * * openm dc.b 'Enter filename to read: ' dc.b 0 msg dc.b 'TOS error occurred!', 13, 10 dc.b 0 buffer ds.b 51 buf2 ds.b 51 blen equ 50 * Buffer for reading from file inpbuf ds.b $400 inpend ds.b 0 inplen equ $400 * ... and for writing ... outbuf ds.b $400 outend ds.b 0 outlen equ $400 * Codes for GEMDOS conout equ $02 rawcon equ $06 conine equ $07 pline equ $09 fcreat equ $3c fopen equ $3d fclose equ $3e fread equ $3f fwrite equ $40 lseek equ $42 end