; PCKFIX.ASM -- 
; Input file: KERMIT.EXE
; Output file: KERMIT.FIX
; The new file is a printable version of the executable file.  Each byte
; in the EXE file is converted to two bytes in the FIX file: a constant
; of "0" (30H) is added to each nibble.  
;
; Daphne Tzoar, December 1983
; 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)		; Use our own DTA.
bufone	db	80H DUP(0)		; Data read from EXE file.
buftwo	db	80H DUP(0)		; Data to write out to FIX file.
fcbold	db	25H DUP(0)		; For the EXE file. 
fcbnew	db	25H DUP(0)		; File the FIX file.
oldstk	dw	?
kold	db	'KERMIT  EXE$'
knew	db	'KERMIT  FIX$'
chrcnt	db	0			; Number of chars left in BUFONE.
datcnt	db	0			; Number of chars in BUFTWO.
eoflag	db	0			; Remember when we hit the EOF. 
crflg	db	0			; Flag when it's time to add a CRLF.
cnt	db	0			; Determine when to add a CRLF.
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			; More of the same.......
	mov ds,ax
	sub ax,ax

	mov oldstk,sp

	mov ah,1AH			; Use my own DTA
	mov dx,offset buff
	int dos
	call one			; Do the important stuff.
	mov sp,oldstk
	ret				; Done.
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		; Put name of new file here.
	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			; Any chars left in buffer?
	jne kerm0			; Yes, continue.
	call inbuf			; Else get a buffer-full.
	  jmp kerm9			; Hit the EOF.
	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			; Time to write out the buffer?
	je kerm2			; Yup.
	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,'0'			; Make printable.
	mov [di],ah
	inc datcnt
	inc di
	add ch,'0'
	mov [di],ch
	inc datcnt
	inc di
	inc bx
	add cnt,2
	cmp cnt,3EH			; Time to add CRLF?
	jne kerm1			; Nope, keep going.
	mov cnt,0			; Reset counter.
	cmp datcnt,80H			; Have room for it?
	jne kerm8			; Yup, we do.
	mov crflg,0FFH			; No - remember add it later.
	jmp kerm2

kerm8:	mov crflg,0
	mov ax,0A0DH			; Add the CRLF.
	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
