;       SCCSID = @(#)bvfread.asm	6.1 90/11/16
;SCCSID = @(#)bvfread.asm	6.2 90/01/23
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
	PAGE	58,132
	TITLE	BvsRead.Asm -- Base Video Subsystem Read Routines

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SOURCE FILE NAME:	 BvsRead.Asm					*/
;/*									*/
;/* DESCRIPTIVE NAME:	 BVS Read Routines				*/
;/*									*/
;/* COPYRIGHT:	 na							*/
;/*									*/
;/* STATUS:	 na							*/
;/*									*/
;/* NOTES:	 Executes on level 3 - Protect Mode ONLY		*/
;/*									*/
;/*    DEPENDENCIES:	None						*/
;/*									*/
;/*    RESTRICTIONS:	None						*/
;/*									*/
;/*    PATCH LABEL:	na						*/
;/*									*/
;/* ENTRY POINTS: BvsReadCharStr, BvsReadCellStr			*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/************************ END OF SPECIFICATIONS ************************/

	.xlist
	INCLUDE bvfcb.inc		;BVS Data Structures
	INCLUDE error2.inc		;Error Equates
	INCLUDE struc.inc		;Structured Macros
	.list

BVSNSEG SEGMENT PARA PUBLIC 'DATA'
BVSNSEG ENDS

	extrn	BVSROUT:NEAR

BVS3SEG SEGMENT BYTE PUBLIC 'CODE'
	ASSUME	CS:BVS3SEG

VIOREADCHARSTR proc far
	public	VIOREADCHARSTR
	pushi	<offset CS:BvsReadCharStr>
	call	BVSROUT
	ret	14			;6 words + VioHandle
VIOREADCHARSTR endp

VIOREADCELLSTR proc far
	public	VIOREADCELLSTR
	pushi	<offset CS:BvsReadCellStr>
	call	BVSROUT
	ret	14			;6 words + VioHandle
VIOREADCELLSTR endp

r_column EQU	parmn			;Column
r_row	EQU	parmnm1 		;Row
r_lenoff EQU	parmnm2 		;Offset of Length
r_lensel EQU	parmnm3 		;Selector of Length
r_stroff EQU	parmnm4 		;Offset of String
r_strsel EQU	parmnm5 		;Selector of String
	PAGE
;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:	BvsReadCharStr					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Read Characters String				*/
;/*									*/
;/* FUNCTION:	The characters are read from the display		*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The read is terminated if it comes to the end of the	*/
;/*		screen.  The characters that are read are		*/
;/*		placed in the specified buffer.  The length of the cell */
;/*		string read is returned.				*/
;/*									*/
;/* NOTES:	Executes on level 3					*/
;/*									*/
;/* ENTRY POINT:  BvsReadCharStr					*/
;/*   LINKAGE:	Call BvsReadCharStr from BVSMAIN			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= r_column	Starting column 			*/
;/*	parmnm1 = r_row 	Starting row				*/
;/*	parmnm2 = r_lenoff	Offset of Length			*/
;/*	parmnm3 = r_lensel	Selector of Length			*/
;/*	parmnm4 = r_stroff	Offset of String			*/
;/*	parmnm5 = r_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;if  (input row not valid)
;    set AX to error code
;    exit subroutine
;endif
;if  (input column not valid)
;    set AX to error code
;    exit subroutine
;endif
;save_start := (row * #ROWSIZE + column) * 2
;save_end := save_start - length
;if  (save_end > #end_of_screen)
;    save_end := #end_of_screen
;    char_str_len := #end_of_screen - save_start
;endif
;move characters at ds:(save_start) to char string buffer
;return char_str_len

BvsReadCharStr PROC NEAR
;	PUBLIC	BvsReadCharStr

	les	di,dword ptr [bp].r_lenoff ;Get length ptr
	mov	cx,es:[di]		;get requested length
	Call	CheckReadParms
	.if	z
	    .if     ncxz
		mov	si,cx
		mov	ax,40h
		mov	ds,ax
		push	[bx].real_cursorposn ;Get current curpos

		.repeat
		    mov     [bx].real_cursorposn,dx ;Set requested curpos
		    mov     ah,8
		    int     10h 	;Read cell at curpos
		    stosb		;Save the Character

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr [bx].real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     si
		.until	z

		pop	[bx].real_cursorposn ;Restore curpos
	    .endif

	    SUB     AX,AX		;clear AX
	.endif
	RET				;exit
BvsReadCharStr ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsReadCellStr					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Read Cell String				*/
;/*									*/
;/* FUNCTION:	The cells are read from the display			*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The read is terminated if it comes to the end of the	*/
;/*		screen.  The cells that are read are			*/
;/*		placed in the specified buffer.  The length of the cell */
;/*		string read is returned.				*/
;/*									*/
;/* NOTES:   Executes on level 3, protect mode only			*/
;/*									*/
;/* ENTRY POINT:  BvsReadCellStr					*/
;/*   LINKAGE:	Call BvsReadCellStr from BVSMAIN			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= r_column	Starting column 			*/
;/*	parmnm1 = r_row 	Starting row				*/
;/*	parmnm2 = r_lenoff	Offset of Length			*/
;/*	parmnm3 = r_lensel	Selector of Length			*/
;/*	parmnm4 = r_stroff	Offset of String			*/
;/*	parmnm5 = r_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;if  (input row not valid)
;    set AX to error code
;    exit subroutine
;endif
;if  (input column not valid)
;    set AX to error code
;    exit subroutine
;endif
;save_start := (row * #ROWSIZE + column) * 2
;save_end := save_start - length
;if  (save_end > #end_of_screen)
;    save_end := #end_of_screen
;    cell_str_len := #end_of_screen - save_start
;endif
;move cells at ds:(save_start) to char string buffer
;return cell_str_len

BvsReadCellStr PROC NEAR
;	PUBLIC	BvsReadCellStr

	les	di,dword ptr [bp].r_lenoff ;Get length ptr
	mov	cx,es:[di]		;get requested length
	shr	cx,1			;Get number of cells
	Call	CheckReadParms
	.if	z
	    .if     ncxz
		lds	si,dword ptr [bp].r_lenoff ;Get length ptr
		add	[si],cx 	;Change #cells to #bytes
		mov	si,cx
		mov	ax,40h
		mov	ds,ax
		push	[bx].real_cursorposn ;Get current curpos

		.repeat
		    mov     [bx].real_cursorposn,dx ;Set requested curpos
		    mov     ah,8
		    int     10h 	;Read cell at curpos
		    stosw		;Save the Cell

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr [bx].real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     si
		.until	z

		pop	[bx].real_cursorposn ;Restore curpos
	    .endif

	    SUB     AX,AX		;clear AX
	.endif
	RET				;go back to bvsmain
BvsReadCellStr ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	CheckReadParms					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Validate Common Read Parameters 		*/
;/*									*/
;/* FUNCTION:	The chars are read from the string buffer and put	*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen.  The specified attribute is			*/
;/*		written at the attribute positions.			*/
;/*									*/
;/* NOTES:	Executes on level 3, Protect mode ONLY			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtCharStrAtt					*/
;/*   LINKAGE:	Call BvsWrtCharStrAtt from BVSMAIN			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= r_column	Starting column 			*/
;/*	parmnm1 = r_row 	Starting row				*/
;/*	parmnm2 = r_lenoff	Offset of Length			*/
;/*	parmnm3 = r_lensel	Selector of Length			*/
;/*	parmnm4 = r_stroff	Offset of String			*/
;/*	parmnm5 = r_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX	= 0						*/
;/*		  SI	= Offset computed from Row and Column		*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute/String		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCBsg					*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

CheckReadParms PROC NEAR
	MOV	si,[BP].r_column	;put the starting column in CX
	.IF	<si ae [bx].bvs_cols>	;check if valid column
	    MOV     AX,error_vio_col	;set bad column return code
	.else
	    MOV     AX,[BP].r_row	;put the starting row in AX
	    .IF     <AX ae [bx].bvs_rows> ;check if valid row
		MOV	AX,error_vio_row ;set bad row return code
	    .else
		mul	[bx].bvs_cols	;calculate the row offset ...
		add	si,ax		;add in the column offset ...

		mov	ax,[bx].bvs_rows
		mul	[bx].bvs_cols
		sub	ax,si		;Compute maximum length

		.if	<cx a ax>	;if they want more than screen end
		    mov     cx,ax	;set to maximum length
		.endif
		mov	es:[di],cx	;Return the correct number of items
		SUB	AX,AX		;clear AX
	    .endif
	.endif
	mov	dh,byte ptr [bp].r_row
	mov	dl,byte ptr [bp].r_column
	les	di,dword ptr [bp].r_stroff ;Get string ptr
	and	ax,ax			;Set zero flag for caller
	RET
CheckReadParms ENDP

BVS3SEG ENDS
	END
