; FROM INTERFACE AGE NOVEMBER 1981
; PAGES 112 AND 170-172
; By Alan R. Miller
; SHOW - DISPAY FILES BY TYPING - SHOW(Filename.xxx)
; DISPLAYS 22 LINES - WAITS FOR "SPACE BAR"
; ELIMINATES NEED FOR CONTROL "S" TO STOP LISTING
; A CP/M PROGRAM TO DISPLAY ASCII FILES
;				chs
;
	ORG	100H
;
LMAX	EQU	22	;MAX LINES/SCREEN
BDOS	EQU	5	;DOS ENTRY POINT
CONS	EQU	1	;READ CONSOLE
TYPEF	EQU 	2	;WRITE CONSOLE
PBUF	EQU	9	;PRINT CONSLOE BUFFER
BRKF	EQU	11	;CONSOLE READY
OPENF	EQU	15	;FILE OPEN
READF	EQU	20	;READ FUNCTION
;
FCB	EQU	5CH	;FILE CONTROL BLOCK
BUFF	EQU	80H	;DISK BUFFER ADDRESS
;
CR	EQU     0DH	;CARRIAGE RETURN
LF	EQU	0AH	;LINE FEED
EOF	EQU	1AH	;END OF FILE
;
; FILE-CONTROL BLOCK DEFINITIONS
;
FCBFN	EQU	FCB+1	;FILE NAME
FCBFT	EQU	FCB+9	;FILE TYPE
FCBCR	EQU	FCB+32	;NEXT RECORD
;
; SAVE OLD STACK, SET UP NEW ONE
;
START:	LXI	H,0
	DAD	SP
	SHLD	OLDSP	;SAVE STACK
	LXI	SP,STACK
	CALL	SETUP	;SET UP INPUT FILE
	CPI	255
	JZ	NOFILE	;FILE NOT PRESENT
  	MVI	A,80H
	STA	IBP	;BUFFER POINTER END
	LXI	H,0	;START POINTER AT 0
;
GLOOP:	PUSH	H	;SAVE POINTER
	CALL 	GNB
	POP	H
	JZ	FINIS	;END OF FILE
	MOV	B,A
	CPI	EOF	;END?
	JZ	FINIS	;YES
	CALL	PCHAR	;PRINT BYTE 
	MOV	A,B
	ANI	7FH
	CPI	CR	;END OF LINE?
	JNZ	GLOOP	;NO


;
; NEW LINE, INCREMENT COUNT
;
	LDA	LCOUNT
	INR 	A
	STA	LCOUNT
	CPI	LMAX	;FULL PAGE?
	JNZ	GLOOP
;
; FREEZE SCREEN UNTIL SPACE BAR PRESSED
; OR ABORT IF OTHER KEY PRESSED
;
	PUSH	D
	LXI	D,LMES	;MESSAGE
	CALL	PRINT
	POP	D
FREEZE:	CALL	ABORT	;CHECK CONSOLE
	RRC	
	JNC	FREEZE	;LOOP UNTIL CHAR
	CALL	READ	;GET THE CHAR
	ANI	7FH	
	CPI	' ' 	;BLANK?
	JNZ	FINIS	;ABORT
	XRA	A
	STA	LCOUNT	;RESET LINE COUNT
	MVI	A,CR
 	CALL	PCHAR	;SEND CARRIAGE RETURN
 	JMP	GLOOP
;
; NO SUCH FILE, GIVE ERROR MESSAGE AND QUIT
;
NOFILE: LXI	D,OPNMSG
	CALL 	PRINT
;
;DONE, RETURN TO CCP
;
FINIS:	CALL	CRLF
	LHLD	OLDSP	;GET OLD STACK
	SPHL
	RET		;TO THE CCP
;
; READ CONSOLE CHARACTER
;
READ:	PUSH H		;SAVE REGISTERS
	PUSH D
	PUSH B
	MVI	C,CONS	;CONSOLE INPUT
	CALL	BDOS
	POP B		;RESTORE REGISTERS
	POP D
	POP H
	RET
;
; CHECK CONSOLE FOR KEY PRESSED
;
ABORT:	PUSH H		;SAVE THE REGISTERS
	PUSH D
	PUSH B
	MVI	C,BRKF
	CALL	BDOS
	POP B		;RESTORE REGISTERS
	POP D
	POP H
	RET
;
; SEND CARRIAGE RETURN AND LINE FEED
;
CRLF:	MVI	A,CR
	CALL	PCHAR
	MVI	A,LF
;
; PRINT CHARACTER IN ACCUMULATOR
;
PCHAR:	PUSH H		;SAVE REGISTERS
	PUSH D	
	PUSH B
	MVI	C,TYPEF
	MOV	E,A
	CALL	BDOS
	POP B		;RESTORE REGISTERS
	POP D
	POP H
	RET
;
; PRINT BUFFER UP TO $, POINTER IS DE
;
PRINT:	MVI	C,PBUF
 	JMP	BDOS
;
; GET NEXT BUTE FROM DISK BUFFER
;
GNB:	LDA	IBP
	CPI	80H
	JNZ	GBYTE
;
; READ ANOTHER BUFFER
;
	CALL 	DISKR
	ORA	A	;ZERO IF READ OK
	JZ	GBYTE	;FOR ANOTHER BYTE
	STC		;END IF DATA
	RET
;
; READ THE BUTE AT BUFF + ACCUMULATOR
;
GBYTE:	MOV	E,A	;PUT A IN DE
	MVI	D,0
	INR	A	;NEXT
	STA 	IBP	;SAVE ADDRESS
	LXI	H,BUFF
	DAD	D	;ADD OFFSET
	MOV	A,M	;GET BYTE
	ORA     A	;RESET CARRY
	RET
;
; SET UP FILE AND OPEN FOR INPUT
;
SETUP:	XRA	A	;ZERO ACCUMULATOR
	STA	FCBCR	;RESET RECORD
;
; CHECK FOR COM FILE
;
	LHLD	FCBFT	;FILE TYPE
	MOV	A,L	;FIRST CHARACTER
	CPI	'C'
	JNZ	SET2	;NOT COM
	MOV	A,H 	;SECOND CHARACTER
	CPI	'O'	 
	JNZ	SET2 	;NOT COM
;
; TELL ABOUT COM FILE AND THEN ABORT
;
	LXI	D,CMES	;ERROR MESSAGE
	CALL	PRINT	;SEND
	JMP	FINIS
;
SET2:	LXI	D,FCB
	MVI	C,OPENF
	JMP	BDOS
;
; READ DISK FILE RECORD
;
DISKR:	PUSH H	;SAVE REGISTERS
	PUSH D
	PUSH B
	LXI	D,FCB
	MVI	C,READF
	CALL	BDOS
	POP B		;RESTORE REGISTERS
	POP D
	POP H
	RET
;
; STORAGE AREA
;
OPNMSG:	DB	CR,LF
	DB	'ERROR--Disk file not found$'
CMES:   DB	CR,LF,'Can''t print com files$'
LMES:	DB	CR,LF
	DB	'Press space bar to continue,'
	DB	' or anything else to quit.$'
;
LCOUNT:	DB	0	;LINES PER SCREEN
IBP:	DS	2  	;INPUT BUFFER POINTER
OLDSP:	DS	2	;INCOMING STACK POINTER
;
	DS	30	;STACK SPACE
STACK:
	END