; Program to convert KERMIT.EXE to all printable characters.  For each
; byte of the file, convert to two characters in the range 20 to 2F. 
; This is done by adding a space to each nibble.  The file KERMIT.FIX
; is created with 64 characters per line.
;
; Daphne Tzoar
; 1/83
; Columbia University Center for Computing Activities

DOS	EQU	21H

STACK	SEGMENT	PARA STACK 'STACK'
	DW 	100 DUP (0)
STK	EQU	THIS WORD
STACK 	ENDS	

DATAS	SEGMENT	PARA PUBLIC 'DATAS'
buff	db	80H DUP(0)
bufone	db	80H DUP(0)
buftwo	db	80H DUP(0)
fcbold	db	25H DUP(0)
fcbnew	db	25H DUP(0)
oldstk	dw	?
kold	db	'KERMIT  EXE$'
knew	db	'KERMIT  FIX$'
chrcnt	db	0
datcnt	db	0
eoflag	db	0
crflg	db	0
cnt	db	0
DATAS	ENDS

MAIN	SEGMENT	PARA PUBLIC 'MAIN'
START	PROC	FAR
	ASSUME CS:MAIN,DS:DATAS,SS:STACK,ES:NOTHING

	push ds				; Initialization
	sub ax,ax
	push ax

	mov ax,datas
	mov ds,ax
	sub ax,ax

	mov oldstk,sp

	mov ah,1AH			; Use my own DTA
	mov dx,offset buff
	int dos
	call one
	mov sp,oldstk
	ret
START 	ENDP
	
ONE	PROC	NEAR
	mov bx,offset fcbold
	mov ah,0
	mov [bx],ah			; Use default drive.
	inc bx
	mov di,offset kold		; Get name of original file.
kerm3:	mov ah,[di]
	cmp ah,'$'			; Got all the data?
	je kerm4
	mov [bx],ah
	inc di
	inc bx
	jmp kerm3
kerm4:  mov bx,offset fcbnew
	mov ah,0
	mov [bx],ah
	inc bx
	mov di,offset knew
kerm5:	mov ah,[di]
	cmp ah,'$'
	je kerm6
	mov [bx],ah
	inc di
	inc bx
	jmp kerm5

kerm6:	mov ax,0
	mov bx,offset fcbold+0CH
	mov [bx],ax			; Zero current block number.
	mov bx,offset fcbold+0EH
	mov [bx],ax			; Lrecl.
	mov bx,offset fcbold+20H
	mov [bx],ah			; Current record (of block).
	inc bx
	mov [bx],ax			; Current record (of file).
	mov bx,offset fcbold+23H
	mov [bx],ax
	mov ah,0FH			; Open file.
	mov dx,offset fcbold
	int dos

	mov ax,0
	mov bx,offset fcbnew+0CH
	mov [bx],ax			; Zero current block number.
	mov bx,offset fcbnew+0EH
	mov [bx],ax			; Lrecl.
	mov bx,offset fcbnew+20H
	mov [bx],ah			; Current record (of block).
	inc bx
	mov [bx],ax			; Current record (of file).
	mov bx,offset fcbnew+23H
	mov [bx],ax
	mov ah,16H			; Create file.
	mov dx,offset fcbnew
	int dos
	mov eoflag,0			; Not end-of-file yet.
	mov datcnt,0			; Chars in write-out buffer.
	mov chrcnt,0			; Chars in read-to buffer.
	mov crflg,0
	mov cnt,0
	mov bx,offset bufone
	mov di,offset buftwo

kerm1:	cmp chrcnt,0H
	jne kerm0
	call inbuf			; Get a buffer-full.
	  jmp kerm9
	mov ax,ds
	mov es,ax			; Move for Dest uses ES register.
	mov si,offset buff
	push di
	mov di,offset bufone		; Move read-in data to bufone.
	mov cx,80H
	rep movs es:bufone,buff
	pop di

	mov bx,offset bufone		; Where the chars are.
	mov chrcnt,80H			; Number of chars.
kerm0:	cmp datcnt,80H
	je kerm2
	dec chrcnt
	mov ah,[bx]			; Get a char.
	mov ch,ah			; Save here.
	and ah,0F0H			; Get high nibble.
	and ch,0FH			; Lower nibble.
	mov cl,4
	shr ax,cl
	add ah,' '			; Make printable.
	mov [di],ah
	inc datcnt
	inc di
	add ch,' '
	mov [di],ch
	inc datcnt
	inc di
	inc bx
	add cnt,2
	cmp cnt,40H			; Time to add CRLF?
	jne kerm1
	mov cnt,0			; Reset counter.
	cmp datcnt,80H			; Have room for it?
	jne kerm8			; Yup, we do.
	mov crflg,0FFH
	jmp kerm2

kerm8:	mov crflg,0
	mov ax,0A0DH
	mov [di],ax
	inc di
	inc di
	add datcnt,2
	jmp kerm1

kerm2: 	mov ax,ds
	mov es,ax			; Move for Dest uses ES register.
	mov si,offset buftwo
	mov di,offset buff
	mov cx,80H
	rep movs es:buff,buftwo		; Must use BUFF for r/w to file.

	mov ah,15H			; Write out to file two.
	mov dx,offset fcbnew
	int dos
	mov datcnt,0
	mov di,offset buftwo		; Start at beginning of buffer.
	cmp crflg,0FFH			; Had our buffer filled prior to CRLF?
	je kerm8			; Yup.
	jmp kerm1			; Get new buffer-full.

kerm9:	mov ah,10H			; Close files.	
	mov dx,offset fcbold
	int dos
	mov dx,offset fcbnew
	int dos
	ret

inbuf:  cmp eoflag,0			; End of file?
	je inbuf0			; Nope.
	ret
inbuf0:	mov dx,offset fcbold
	mov ah,14H			; Read from file.
	int dos
	cmp al,0
	je inbuf2
	mov eoflag,0FFH
inbuf2: jmp rskp
ONE 	ENDP

RSKP	PROC  NEAR
	pop bp
	add bp,3
	push bp
	ret
RSKP	ENDP

MAIN	ENDS
	END 	START
