;
;   Dumper - file dump - Jim Butterfield.  Feburary 15/89.

; Exec library calls
            xref _LVOOpenLibrary       ;-$228
            xref _LVOCloseLibrary      ;-$19E
            xref _LVOSetSignal         ;-$132
; DOS library calls
            xref _LVOOpen              ;-$1E
            xref _LVOClose             ;-$24
            xref _LVOOutput            ;-$3C
            xref _LVOWrite             ;-$30
            xref _LVORead              ;-$2A
;
BufSize EQU 10
;-- Initial setup:
Startup     move.l a0,a4       ; Remember ptr to argument line. cf MOVEA
            move.l d0,d4             ; Remember len of argument line.
            lea    dosname(pc),a1    ; Name 'dos.library'.
            clr.l  d0                ;   Any version (0)
            move.l $4,a6             ;   Using Exec library
            jsr    _LVOOpenLibrary(a6)  ;   Open Dos library.
            move.l d0,a6             ; Remember DosBase ptr.
            tst.l  d0                ; Check for error (d0=0 means
            beq.s  StartupQuit       ;      dos not opened
            bsr.s  DOSinit
            move.l a6,a1             ;-Specify Dos library in a1;
            move.l $4,a6             ;   then using Exec library,
            jsr    _LVOCloseLibrary(a6)    ;   close Dos library.
StartupQuit rts                      ; End of Program
;
;-- Get CLI outhandle:
DOSinit     jsr    _LVOOutput(a6)    ;   get CLI outhandle,
            move.l d0,a5             ;   & then remember it.
;
; -- Change arg file name to C string:
checklen    move.b #0,-$1(a4,d4.W)   ; binary zero at end
skipspc     cmp.b  #$20,(a4)+
            beq.s  skipspc
            subq.l #1,a4
            move.l a4,d1             ; filename pointer
            move.l #1005,d2          ; MODE_OLDFILE (for reading)
            jsr    _LVOOpen(A6)
            move.l d0,d6             ; file inhandle
            beq.s  DOSquit           ; no good, quit
            link   a4,#-$10
            bsr.s  DumpFile          ; the main job
            unlk   a4
            move.l d6,d1             ; use the handle..
            jsr    _LVOClose(A6)     ; to close the file
DOSquit     rts                      ;   exit program.
;
; DOS is open and we have our in/out handles.  Let's go!
DumpFile    moveq  #0,d7             ; zero column count
ReadBlock   move.l d6,d1             ; input file handle
            lea    -$10(a4),a2       ; input buffer (stack) address
            lea    -$4(a4),a3        ; output buffer (stack) adds
            move.l a2,d2             ; copy to D2 for read
            moveq  #BufSize,d3       ; input buffer size
            jsr    _LVORead(A6)      ; so read it
            move.l d0,d5             ; size of data
; Here's where we scan and output
            moveq  #0,d4             ; start of buffer pointer
; Note that A2 still contains input buffer address
; Character loop; are we at end of buffer?
NextChar    cmp.l  d5,d4
            bcc.s EndBuf
; We have data!  Let's crunch it.
            move.b $0(a2,d4),d0
            addq.l #1,d4
            cmp.b  #$0a,d0           ; is it NewLine?
            beq.s  NuLiner
            cmp.b  #$1F,d0           ; is it printable?
            bgt.s  NotDot
            move.b #$2e,d0           ; no, substitute a dot.
NotDot      move.b d0,(a3)
            move.l a5,d1             ;file handle
            move.l a3,d2             ;outbuffer
            moveq  #1,d3             ;length
            jsr    _LVOWrite(A6)
; count and send NewLine if needed
            addq.b #1,d7             ;bump column count
            cmp.b  #64,d7            ; at limit?
            bls.s  NextChar
NuLiner     move.b #$0a,(a3)
            move.l a5,d1             ;file handle
            move.l a3,d2             ;buffer
            moveq  #1,d3             ;length
            jsr    _LVOWrite(A6)
            move.l a6,d7             ;stash DOSbase

            moveq  #0,d0
            move.l #$1000,d1
            movea.l $4,a6
            jsr    _LVOSetSignal(A6) ;test CTRL-C
            move.l d7,a6             ;restore DOSBase
            andi.l #$1000,d0
            tst.l  d0
            beq.s  NotCtrlC
            move.l a5,d1             ;file handle
            lea    CtrlCMess(pc),a0  ;message to
            move.l a0,d2             ;       buffer
            moveq  #3,d3             ;length
            jsr    _LVOWrite(A6)
            moveq  #0,d5             ;zap buffer causing exit
NotCtrlC    moveq  #0,d7             ;colcount = 0
            bra.s  NextChar
; The buffer is bare.  If twas full, refill it.
EndBuf      cmp.w  #BufSize,d5       ; was it a full buffer?
            beq    ReadBlock         ; yes, get more
            move.b #$0a,(a3)         ; no, send NewLine
            move.l a5,d1             ; file handle
            move.l a3,d2             ; buffer
            moveq  #1,d3             ; length
            jsr    _LVOWrite(A6)
            rts                      ; job complete
dosname     dc.b 'dos.library',0
CtrlCMess   dc.b '^C',$0a


   end
