* This is a UUDECODE program for the ATARI ST. * It can be assembled using the public domain assembler, AS68; * since this assembler does NOT assemble register shifts and rotates, * all such shifts and rotates have been pre-assembled by hand. * Disassemble a file.... * ... 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