; programm     : printpro.asm  version 1.05        23.09.1988
; syntax       : a86   pd
; aufgabe      : konvertiert einen text in einen text mit linkem rand und
;              : fgt steuerzeichen fr kleinschrift ein.
;              : zus„tzlich wird alle 70 zeilen ein formfeed eingefgt.
; aufruf       : mit  printpro < quelle > prn  oder name.ext
           jmp haupt
fehlbe     db 'PRINTPRO.com versieht Textfiles mit einem linken Rand',13,10
           db 'und fgt alle 70 Zeilen eine Seitenvorschub ein.',13,10,10
           db 'Zu Begin wird ein Code eingefgt, der den Drucker auf',13,10
           db 'Kleinschrift und 8 Zeilen pro Zoll schaltet.',13,10,10
           db '* KEIN Copyright  by m.s.  Version 1.05   August 1988 *',13,10,10,10
           db 'Aufruf erfolgt mit PRINTPRO < ein.txt > aus.txt',13,10,10
           db 'Als Ziel ist auch der Drucker m”glich ( prn oder lpt )$',13,10
ns         db 12
zeile      db 00
outnum     dw 0000h
init       db 15,27,48,13
ende1      db 12
l_length   db 0
           org $
last_line  db 0
           org $+0fe
cu_len     db 0
           org $
mich       db 32,32,32,32,32,32,32,32,32,32,32
curr_line  db 0
           org $+0fe
buf_size   equ    1024               ;size of input and output buffers
@read      equ    3fh                ;read file/device
@write     equ    40h                ;write file/device
cr         equ    0dh                ;carriage return character
lf         equ    0ah                ;line feed character
stdin      equ    0000h              ;standard input
stdout     equ    0001h              ;standard output
para_c     equ    080h
haupt:     cmp b[para_c],00
           jne haupt1
           mov ax,0003h              ; ohne parameter aufrufen
           int 010h
           mov dx,offset fehlbe
           mov ah,09h
           int 021h
           mov ah,04ch
           mov al,0ffh
           int 021h
haupt1:    mov  ah, @write           ;write
           mov  dx, stdout           ;to stdout
           mov  cx, 4                ;number of chars for output
           mov  dx, offset init      ;from output buffer
           int  021h
           call process              ;count w, l, c from std i/o
           mov  ah, @write           ;write
           mov  bx, stdout           ;to stdout
           mov  cx, 1                ;number of chars for output
           mov  dx, offset ende1     ;from output buffer
           int  021h
           mov  ah,4ch
           mov  al,00
           int  021h             ;and return to dos

process:   mov  [outnum], 0000h      ;output buffer is empty
           mov  si, offset buf_in
           mov  di, offset buf_out
           call fillbuf            ;get 1st buffer's worth
           cmp  cx, 0000h          ;any chars?
           je   p_done             ;if not, quit
p_loop:    call read_line          ;get next line
           jc   p_done             ;none available? done
           call put_line           ;if so, output it
           jmp  p_loop             ;and continue til eof
p_done:    call dumpbuf            ;flush output buffer
           ret

read_line: push bx
           push dx
           xor  dx, dx
           mov  bx, offset curr_line
           call getchar
           jc   r_fail
r_loop:    mov  [bx], al               ;put char in string
           inc  bx                     ;bump string pointer
           inc  dl                     ;bump char count
           cmp  al, lf                 ;newline?
           je   r_exit                 ;done if so
           cmp  dl, 0ffh               ;string too long?
           je   r_exit                 ;abort if so
           call getchar                ;get next character
           jc   r_exit                 ;none available? exit
           jmp  r_loop                 ;otherwise continue
r_exit:    mov  [offset cu_len], dl    ;save length
           pop  dx
           pop  bx
           clc
           ret
r_fail:    pop  dx
           pop  bx
           stc
           ret

put_line:  push  bx
           push  dx
           add   [zeile],01
           cmp   [zeile],70
           ja    neusei
zuru:      mov   bx, offset mich   ; curr_line
           xor   dx, dx
           mov   dl, 10
pl_loop1:  mov   al, [bx]               ;get char
           call  putchar                ;output it
           inc   bx                     ;bump string pointer
           dec   dl                     ;used one char
           jnz   pl_loop1               ;loop til done
           mov   bx, offset curr_line   ; curr_line
           xor   dx, dx
           mov   dl, [offset cu_len]
           cmp   dl, 0
           je    pl_done
pl_loop:   mov   al, [bx]     ;get char
           call  putchar      ;output it
           inc   bx           ;bump string pointer
           dec   dl           ;used one char
           jnz   pl_loop      ;loop til done
pl_done:   pop   dx
           pop   bx
           ret

neusei:    mov  bx,offset ns
           xor  dx,dx
           mov  dl,01
           mov  al,[bx]
           call putchar
           mov  zeile,00
           jmp  zuru

getchar:   cmp  cx, 0000           ;is the buffer empty?
           jne  g1                 ;nope, skip
           call fillbuf            ;if so, try to refill it
           cmp  cx, 0000           ;still empty?
           je   g_abort            ;then return failure
g1:        lodsb                   ;get character from [si]
           dec  cx                 ;used up one char
           clc                     ;clear flag to indicate sucess
           ret                     ;and return
g_abort:   stc                     ;set flag for failure
           ret

fillbuf:   push    bx
           push    dx
           mov     ah, @read           ;read
           mov     bx, stdin           ;from stdin
           mov     cx, buf_size        ;one buffer's worth
           mov     dx, offset buf_in   ;into the input buffer
           int     021h
           mov     cx, ax              ;save number of chars read
           mov     si, offset buf_in   ;reset buffer
           pop     dx
           pop     bx
           ret

putchar:   stosb                    ;move character into buffer
           inc   [outnum]            ;bump count of chars in buffer
           cmp   [outnum], buf_size  ;is buffer full?
           jl    pu_exit            ;no, skip
           call  dumpbuf            ;yes, dump buffer to disk
pu_exit:   ret

dumpbuf:   push    ax                   ;save active registers
           push    bx                   ; "      "      "
           push    cx                   ; "      "      "
           push    dx                   ; "      "      "
           mov     ah, @write           ;write
           mov     bx, stdout           ;to stdout
           mov     cx, [outnum]         ;number of chars for output
           mov     dx, offset buf_out   ;from output buffer
           int     021h
           mov     [outnum], 0           ;reset buffer
           mov     di, offset buf_out    ;  "     "
           pop     dx                    ;restore active registers
           pop     cx                    ;   "       "       "
           pop     bx                    ;   "       "       "
           pop     ax                    ;   "       "       "
           ret

buf_in     db 0
           org ($+buf_size-1)
buf_out    db 0
           org ($+buf_size-1)
