	TITLE	FILEHEX - Dump Diskette File in Hex
	PAGE	60,132
;
; Filehex Program
; Dick Gillmann, June 1982
;
; EQUATES
DISPLAY1 EQU	2			; DOS PRINT CHAR TO TERMINAL
DISPLAY	EQU	9			; DOS PRINT STRING TO TERMINAL
READ	EQU	0AH			; DOS READ STRING FROM TERMINAL
OPEN	EQU	0FH			; DOS FILE OPEN
SEQ_READ EQU	14H			; DOS SEQUENTIAL READ
DTA	EQU	1AH			; DOS SET DISK TRANSFER ADDRESS
PARSE	EQU	29H			; DOS PARSE FILENAME
DOS_FUNC EQU	21H			; DOS FUNCTION INTERRUPT CODE
LF	EQU	0AH			; ASCII LINEFEED
CR	EQU	0DH			; ASCII CARRIAGE RETURN
	SUBTTL	Stack Segment
	PAGE
STACK	SEGMENT	PARA STACK 'STACK'
	DB	100 DUP("STACK   ")	; MAKE VISIBLE FOR DEBUG
STACK	ENDS
	SUBTTL	Data Segment
	PAGE
DATA	SEGMENT	PARA PUBLIC 'DATA'
MSG1	DB	"Input file:  $"	; PROMPT FOR INPUT FILENAME
; PARAMETER BLOCK FOR DOS SCREEN READ
MAXCHAR	EQU	20			; FILENAME SIZE LIMIT
INF1	LABEL	BYTE			; BLOCK NAME
BUFSIZE	DB	MAXCHAR			; MAX CHARS ALLOWED
INSIZE	DB	?			; NUMBER ACTUALLY READ
TEXT	DB	MAXCHAR DUP(" ")	; BUFFER
	DB	"$"			; MARKS END OF BUFFER
; OTHER DATA
N	EQU	20			; NUMBER OF BYTES DUMPED/LINE
FCB	DB	37 DUP(?)		; FILE CONTROL BLOCK
BUFFER	DB	N DUP(?)		; INPUT BUFFER
HEX	DB	"0123456789ABCDEF"	; ASCII CODES FOR HEX
OUTBUF	DB	3*N DUP(" ")		; OUTPUT BUFFER
CRLF	DB	CR			; CRLF SEQUENCE
	DB	LF			; LINEFEED
	DB	"$"			; END OF PRINT STRING
DATA	ENDS
	SUBTTL	Main Program
	PAGE
CODE	SEGMENT	PARA PUBLIC 'CODE'
START	PROC	FAR			; MAIN ENTRY POINT
	ASSUME	CS:CODE,DS:DATA,SS:STACK,ES:DATA
; SAVE PARAMS FOR RETURN TO DOS
	PUSH	DS			; SAVE PREFIX ADDRESS
	XOR	AX,AX			; CLEAR AX
	PUSH	AX			; ZERO RETURN ADDRESS
; ESTABLISH ADDRESSABILITY
	MOV	AX,DATA			; DATA SEGMENT
	MOV	DS,AX			; TO DS
	MOV	ES,AX			; AND ES
; PROMPT FOR INPUT FILENAME
PROMPT:	MOV	DX,OFFSET MSG1		; MSG TO BE DISPLAYED
	MOV	AH,DISPLAY		; CONSOLE OUTPUT
	INT	DOS_FUNC		; REQUEST DOS SERVICE
; READ FILENAME
	MOV	DX,OFFSET INF1		; INPUT BUFFER
	MOV	AH,READ			; READ FUNCTION
	INT	DOS_FUNC		; REQUEST DOS SERVICE
; CRLF
	MOV	DX,OFFSET CRLF		; ADDRESS OF CRLF
	MOV	AH,DISPLAY		; DOS PRINT TO TERMINAL
	INT	DOS_FUNC		; REQUEST DOS SERVICE
; PARSE FILENAME & CREATE FCB
	MOV	SI,OFFSET TEXT		; FILENAME BUFFER ADDRESS
	MOV	DI,OFFSET FCB		; FCB ADDRESS
	MOV	AL,0			; DON'T STRIP COMMAS
	MOV	AH,PARSE		; DOS FILENAME PARSE
	INT	DOS_FUNC		; REQUEST DOS SERVICE
	CMP	FCB+1," "		; IF BLANK, NO FILENAME GIVEN
	JE	BYEBYE			; SO GIVE UP
	CMP	AL,0			; DRIVE OK?
	JNE	PROMPT			; NOPE, ASK AGAIN
; OPEN THE INPUT FILE
	MOV	DX,OFFSET FCB		; FILE CONTROL BLOCK
	MOV	AH,OPEN			; DOS OPEN
	INT	DOS_FUNC		; REQUEST DOS SERVICE
	CMP	AL,0			; FILE FOUND?
	JNE	PROMPT			; NOPE, ASK AGAIN
	MOV	WORD PTR FCB+0EH,LENGTH BUFFER	; SET RECLEN
; SET DISK TRANSFER ADDRESS
	MOV	DX,OFFSET BUFFER	; WHERE INPUT DATA GOES
	MOV	AH,DTA			; DOS SET DTA
	INT	DOS_FUNC		; REQUEST DOS SERVICE
; READ A RECORD
LUPE:	MOV	DX,OFFSET FCB		; FILE CONTROL BLOCK
	MOV	AH,SEQ_READ		; DOS SEQUENTIAL READ
	INT	DOS_FUNC		; REQUEST DOS SERVICE
	CMP	AL,1			; PAST EOF?
	JE	BYEBYE			; YES, DON'T DUMP ANYTHING
	PUSH	AX			; SAVE EOF INDICATION
; CALL DUMP ROUTINE
	CALL	DUMP			; CONVERT TO HEX
; DISPLAY RESULT
	MOV	DX,OFFSET OUTBUF	; OUTBUT BUFFER
	MOV	AH,DISPLAY		; DOS PRINT TO TERMINAL
	INT	DOS_FUNC		; REQUEST DOS SERVICE
	POP	AX			; RESTORE EOF INDICATION
; LOOP UNTIL EOF
	CMP	AL,0			; EOF?
	JE	LUPE			; NOPE, READ THE NEXT RECORD
; DONE
BYEBYE:	RET				; RETURN TO DOS
START	ENDP
	SUBTTL	Dump N bytes in hex
	PAGE
; CONVERT BYTES TO HEX
DUMP	PROC
	MOV	BX,0			; CLEAR ACCUMULATOR
	MOV	CX,LENGTH BUFFER	; LOOP N TIMES
	MOV	SI,0			; FIRST INPUT BYTE AT 0
	MOV	DI,0			; FIRST OUTPUT BYTE AT 0
NEXT:	MOV	BL,BUFFER[SI]		; GET NEXT BYTE
	SHR	BL,1			; HI-ORDER NYBBLE
	SHR	BL,1			; GRIND
	SHR	BL,1			;   "
	SHR	BL,1			;   "
	MOV	AL,HEX[BX]		; LOAD ASCII CODE FOR HEX DIGIT
	MOV	OUTBUF[DI],AL		; MOVE IT TO THE OUTPUT BUFFER
	INC	DI			; ADVANCE OUPUT BUFFER PTR
	MOV	BL,BUFFER[SI]		; GET BYTE AGAIN
	AND	BL,0FH    		; EXTRACT LO-ORDER NYBBLE
	MOV	AL,HEX[BX]		; LOAD ASCII CODE FOR IT
	MOV	OUTBUF[DI],AL		; MOVE IT TO OUTPUT BUFFER
	INC	DI			; ADVANCE OUTPUT PTR
	INC	DI			; TWICE
	INC	SI			; ADVANCE INPUT PTR
	LOOP	NEXT			; BACK FOR MORE
	RET				; DONE
DUMP	ENDP
CODE	ENDS
	END	START			; TRANSFER ADDRESS
