;++
;
; Filter to remove CRs before LFs.
;
; 05/31/94	JMBW	Created.
;
;--
	.radix	8
;
lf=	12
cr=	15
;
bufsiz=	30000d			;buffer size
;
code	segment
	assume	cs:code
	org	100h
;
start:	cld			;DF=0
lp1:	; load input buf
	xor	al,al		;don't check for LF
lp2:	push	ax		;save
	mov	dx,offset buf	;pt at buf
	mov	cx,bufsiz	;size
	xor	bx,bx		;stdin
	mov	ah,3Fh		;func=read
	int	21h
	mov	cx,ax		;[copy # bytes actually read]
	pop	ax		;[restore]
	jc	sk3
	mov	di,dx		;pt at buf
	mov	bx,di
	jcxz	sk3		;eof
	or	al,al		;was previous char CR?
	jz	lp3		;no
	cmp	byte ptr [di],lf ;yes, is this LF?
	je	lp3		;yes
	mov	dl,cr		;no, write a CR after all
	mov	ah,02h		;func=conout
	int	21h
lp3:	; di=next start posn, cx=length, bx=end of compressed part,
	mov	si,di		;save
lp4:	mov	al,cr		;search for CRs
	repne	scasb		;find one?
	jne	sk1		;flush and refill if not
	; found a CR
	jcxz	sk2		;end of buf, can't check for LF
	cmp	byte ptr [di],lf ;is there an LF after it?
	jne	lp4		;keep going if not
	; copy this block back to start at [bx]
	dec	di		;unget CR
	call	copy		;copy the block
	inc	di		;restore
	jmp	short lp3	;loop
sk1:	call	copy		;copy
	call	flush		;flush output buf
	jmp	short lp1	;go refill
sk2:	dec	di		;don't write the CR in case there's an LF
	call	copy		;copy
	call	flush		;flush output buf
	mov	al,1		;check for LF after reading
	jmp	short lp2
sk3:	int	20h
;+
;
; Copy a chunk between two CRLFs back to the contiguous block at the beginning
; of the buffer.
;
; si	begn of block
; di	char after end of block (preserved)
; bx	ptr into buffer (updated)
;
; Preserves cx.
;
;-
copy:	mov	ax,cx		;save
	mov	cx,di		;find length
	sub	cx,si
	xchg	di,bx		;get dest loc, save starting posn
	rep	movsb		;copy
	xchg	bx,di		;get updated dest, restore curr posn
	mov	cx,ax		;restore
	ret
;+
;
; Flush output buffer.
;
; bx	current ptr into buf
;
;-
flush:	mov	dx,offset buf	;pt at buffer
	mov	cx,bx		;copy ending ptr
	sub	cx,dx		;length
	mov	bx,1		;stdout
	mov	ah,40h		;func=write
	int	21h
	ret
;
buf	db	bufsiz dup(?)	;buffer
;
code	ends
	end	start

