;VDMSAVE.ASM 10/25/79 BY WARD CHRISTENSEN
;
;Write an image of the current VDM screen to disk.
;Scans for end of lines, puts in CR/LF where appropriate.
;
;	VDMSAVE fn.ft
;
;DEPENDENCIES:
;	Written for a VDM screen using a scroll routine
;which does not do hardware scrolling.  Therefore, the first
;line written is the lowest memory address line of the VDM.
;May work for other contiguous memory mapped displays.
;
;
LINES	EQU	16  	;<----CHANGE
COLUMNS	EQU	64  	;<----THESE
ADDRESS	EQU	0CC00H 	;<----EQUATES
;
	ORG	100H
;
;INIT LOCAL STACK
;
	LXI	H,0
	DAD	SP
	SHLD	STACK
	LXI	SP,STACK
;
;START OF PROGRAM EXECUTION
;
	CALL	MAKEFIL	;MAKE THE FILE
LINE	CALL	TESTL	;TEST THE LINE
	CNZ	WRLINE	;WRITE NON-BLANK LINE
	CALL	WRCRLF
	CALL	NEXTL	;MORE?
	JNZ	LINE	;YES.
	CALL	WREOF	;NO, END
	CALL	ERXIT	;ALL DONE
	DB	'++DONE++$'
;
;---------------- SUBROUTINES ----------------
;
;---->	ERASE, THEN MAKE, THE FILE
;
MAKEFIL	LXI	D,FCB
	MVI	C,ERASE	;<--
	CALL	BDOS
	LXI	D,FCB
	MVI	C,MAKE	;<--
	CALL	BDOS
	INR	A
	RNZ
	CALL	ERXIT
	DB	'++MAKE FAILED++$'
;
;---->	TEST A LINE.
;	RETURNS ZERO IF LINE IS BLANK
;	DE POINTS TO LAST NON BLANK CHAR.
;
TESTL	LHLD	LINEPTR
	LXI	D,0
	MVI	B,COLUMNS ;LINE LENGTH
TESTLP	MOV	A,M	;GET CHAR
	ANI	7FH	;DELETE CURSOR
	CPI	' '
	JZ	TESTB
	MOV	D,H	;SAVE POSITION IN DE
	MOV	E,L	
TESTB	INX	H
	DCR	B
	JNZ	TESTLP
;SET ZERO BASED ON HAVING FOUND A CHAR
	MOV	A,D
	ORA	E
	RET
;
;---->	WRITE A LINE (BUT NOT C/R L/F)
;
WRLINE	INX	D	;FACILITATE TESTING
	LHLD	LINEPTR
WRLP	MOV	A,M
	INX	H
	ANI	7FH	;DELETE CURSOR BIT
	CALL	WRBYTE
	MOV	A,L
	CMP	E
	JNZ	WRLP
	MOV	A,H
	CMP	D
	JNZ	WRLP
	RET
;
;---->	WRITE A CR/LF TO THE FILE
;
WRCRLF	MVI	A,0DH
	CALL	WRBYTE
	MVI	A,0AH
	CALL	WRBYTE
	RET
;
;---->	POINT TO NEXT LINE, RETURN ZERO
;	IF END OF SCREEN
;
NEXTL	LHLD	LINEPTR
	LXI	D,COLUMNS
	DAD	D
	SHLD	LINEPTR
	LDA	NLINES
	DCR	A
	STA	NLINES	;ZERO SET..
	RET		;..IF DONE
;
;---->	WRITE CTL-Z TO THE FILE, CLOSE IT
;
WREOF	MVI	A,1AH
	CALL	WRBYTE
	LDA	BUFPTR	;FULL SECTOR?
	CPI	80H
	JNZ	WREOF
	LXI	D,FCB
	MVI	C,CLOSE
	CALL	BDOS
	INR	A
	RNZ
	CALL	ERXIT
	DB	'++CLOSE ERROR++$'
;
;---->	WRITE A BYTE TO THE FILE
;
WRBYTE	PUSH	H
	LHLD	BUFPTR
	MOV	M,A
	INR	L	;AT 100?
	JNZ	NOWRITE
;
;HAVE TO WRITE A SECTOR
;
	PUSH	B
	PUSH	D
	LXI	D,FCB
	MVI	C,WRITE
	CALL	BDOS
	ORA	A
	JNZ	WRERR
	POP	D
	POP	B
	LXI	H,80H
NOWRITE	SHLD	BUFPTR
	POP	H
	RET
;
WRERR	CALL	ERXIT
	DB	'++WRITE ERROR++$'
;
;FOLLOWING FROM 'EQU8.LIB'---->
;
;EXIT WITH ERROR MESSAGE
;MSGEXIT	EQU	$	
;EXIT W/"INFORMATIONAL" MSG
ERXIT	POP	D	;GET MSG
	MVI	C,PRINT
	CALL	BDOS
;
;EXIT, RESTORING STACK AND RETURN
;
EXIT	LHLD	STACK
	SPHL
	RET		;TO CCP;
LINEPTR	DW	ADDRESS
NLINES	DB	LINES
BUFPTR	DW	80H
;
	DS	100	;STACK AREA
STACK	DS	2
;
;BDOS/CBIOS EQUATES (VERSION 8)	
;
PRINT	EQU	9
CLOSE	EQU	16
ERASE	EQU	19
WRITE	EQU	21
MAKE	EQU	22
BDOS	EQU	5
FCB	EQU	5CH
