;       SCCSID = @(#)bvfscrld.asm	6.1 90/11/16
;SCCSID = @(#)bvfscrld.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	BvfScrlD.Asm -- Base Video Subsystem Scrolling Routines

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

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

	extrn	BVSROUT:NEAR
	extrn	CheckScrlParms:NEAR

BVS3SEG SEGMENT BYTE PUBLIC 'CODE'
	ASSUME	CS:BVS3SEG

VIOSCROLLDN proc far
	public	VIOSCROLLDN
	pushi	<offset CS:BvsScrollDn>
	Call	BVSROUT
	ret	16			;7 words + VioHandle
VIOSCROLLDN endp

VIOSCROLLLF proc far
	public	VIOSCROLLLF
	pushi	<offset CS:BvsScrollLf>
	Call	BVSROUT
	ret	16			;7 words + VioHandle
VIOSCROLLLF endp

VIOSCROLLRT proc far
	public	VIOSCROLLRT
	pushi	<offset CS:BvsScrollRt>
	Call	BVSROUT
	ret	16			;7 words + VioHandle
VIOSCROLLRT endp

;Set equates used by the Scrolling routines

s_celloff equ	parmn			;Offset of fill Cell
s_cellsel equ	parmnm1 		;Selector of fill Cell
s_times equ	parmnm2 		;Number of times to scroll
s_rightcol equ	parmnm3 		;Rightmost column of window
s_botrow equ	parmnm4 		;Bottom row of window
s_leftcol equ	parmnm5 		;Leftmost column of window
s_toprow equ	parmnm6 		;Top row of window

s_cell	equ	s_celloff		;Cell passed from ptr to Cell
s_linelen equ	s_rightcol		;Number of cells per line
s_skiplen equ	s_leftcol		;Number of bytes per line to skip

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  BvsScrollDn					*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem Scroll Down 		*/
;/*									*/
;/* FUNCTION:  Scrolls a portion of the video buffer down a specified	*/
;/*	       number of times. 					*/
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*									*/
;/* ENTRY POINT:  BvsScrollDn						*/
;/*   LINKAGE:	Call BvsScrollDn from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= s_celloff	Offset of fill Cell			*/
;/*	parmnm1 = s_cellsel	Selector of fill Cell			*/
;/*	parmnm2 = s_times	Number of times to scroll		*/
;/*	parmnm3 = s_rightcol	Rightmost column of window		*/
;/*		= s_linelen	Number of cells per line		*/
;/*	parmnm4 = s_botrow	Bottom row of window			*/
;/*	parmnm5 = s_leftcol	Leftmost column of window		*/
;/*		= s_skiplen	Number of bytes per line to skip	*/
;/*	parmnm6 = s_toprow	Top row of window			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid TopRow value					*/
;/*		Invalid LeftCol value					*/
;/*									*/
;/* EFFECTS:  None							*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSCBsg					*/
;/*   ROUTINES:  CheckScrollParms					*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

;Bgnsub BvsScrollDn
;: Validate TopRow, BotRow, LeftCol, RightCol, Times, and Cell
;: If Error
;: : Indicate error in AX
;: Else
;: : Scroll the area using bios
;: : If fill character not blank
;: : : Write the fill character to the fill area
;: : Endif
;: : Set good return code
;: Endif
;Endsub

BvsScrollDn PROC NEAR			;Define subroutine
;	PUBLIC	BvsScrollDn

	Call	CheckScrlParms
	.if	z near			;Valid parameters, compute pointers
	    mov     ax,[bp].s_botrow
	    sub     ax,[bp].s_toprow
	    inc     ax
	    .if     <[bp].s_times a ax>
		mov	[bp].s_times,ax ;Limit times to window size
	    .endif

	    mov     al,byte ptr [bp].s_times
	    mov     ch,byte ptr [bp].s_toprow
	    mov     cl,byte ptr [bp].s_leftcol
	    mov     dh,byte ptr [bp].s_botrow
	    mov     dl,byte ptr [bp].s_rightcol
	    mov     bh,byte ptr [bp].s_celloff+1
	    mov     ah,7
	    int     10h 		;BIOS scroll down
	    sub     di,di

	    mov     ax,[bp].s_celloff	;AL <-- fill char
	    .if     <al ne 20h> 	;if non-blank fill char
		mov	bl,ah		;BL <-- fill attr
		mov	ax,40h
		mov	es,ax
		push	es:[di].real_cursorposn ;save current curpos

		mov	dh,byte ptr [bp].s_toprow ;DH <-- fill row
		mov	dl,byte ptr [bp].s_leftcol ;DL <-- fill column
		mov	bh,0		;display page=0

		.if	<[bp].s_leftcol eq di> and
		mov	ax,[di].bvs_cols
		dec	ax
		.if	<[bp].s_rightcol eq ax>
		    mov     es:[di].real_cursorposn,dx ;set curpos
		    mov     ax,[bp].s_times
		    mul     byte ptr [di].bvs_cols
		    mov     cx,ax	;Compute fill amount
		    mov     al,byte ptr [bp].s_celloff ;Get the character
		    mov     ah,9	;AH=9 ==> BIOS WrtNcell
		    int     10H
		.else
		    mov     cx,[bp].s_rightcol
		    sub     cx,[bp].s_leftcol
		    inc     cx		;CX <- Line length
		    mov     al,byte ptr [bp].s_celloff ;Get the character

		    mov     si,[bp].s_times
		    .repeat
			mov	es:[di].real_cursorposn,dx ;set curpos
			mov	ah,9	;AH=9 ==> BIOS WrtNcell
			int	10H
			inc	dh
			dec	si
		    .until  z
		.endif

		pop	es:[di].real_cursorposn ;restore curpos
	    .endif
	    sub     ax,ax
	.endif
	sub	bx,bx
	RET				;Return to caller
BvsScrollDn ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  BvsScrollLf					*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem Scroll Left 		*/
;/*									*/
;/* FUNCTION:  Scrolls a portion of the video buffer left a specified	*/
;/*	       number of times. 					*/
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*									*/
;/* ENTRY POINT:  BvsScrollLf						*/
;/*   LINKAGE:	Call BvsScrollLf from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= s_celloff	Offset of fill Cell			*/
;/*	parmnm1 = s_cellsel	Selector of fill Cell			*/
;/*	parmnm2 = s_times	Number of times to scroll		*/
;/*	parmnm3 = s_rightcol	Rightmost column of window		*/
;/*	parmnm4 = s_botrow	Bottom row of window			*/
;/*	parmnm5 = s_leftcol	Leftmost column of window		*/
;/*	parmnm6 = s_toprow	Top row of window			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid TopRow value					*/
;/*		Invalid LeftCol value					*/
;/*									*/
;/* EFFECTS:  None							*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSsg 					*/
;/*   ROUTINES:  CheckScrollParms, VioScrollDn				*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/
;
;Bgnsub BvsScrollLf
;: Validate TopRow, BotRow, LeftCol, RightCol, Times, and Cell
;: If Error
;: : Indicate error in AX
;: Else
;: : If not clearing entire area
;: : : For Row=TopRow to BotRow
;: : : : For Col=LeftCol to RightCol-Times
;: : : : : Read cell from (Row,Col+Times)
;: : : : : Write cell to (Row,Col)
;: : : : Endfor
;: : : Endfor
;: : Endif
;: : Call BvsScrollUp to clear the remaining area
;: : Set good return code
;: Endif
;Endsub

BvsScrollLf PROC NEAR			;Scroll Left
;	PUBLIC	BvsScrollLf

	Call	CheckScrlParms

	.if	z			;Valid parameters, compute pointers
	    mov     ax,[bp].s_rightcol
	    sub     ax,[bp].s_leftcol
	    inc     ax
	    .if     <[bp].s_times a ax>
		mov	[bp].s_times,ax ;Limit times to window size
	    .endif

	    mov     di,[bp].s_rightcol
	    sub     di,[bp].s_leftcol
	    inc     di
	    sub     di,[bp].s_times	;Number of cells to move per row

	    .if     nz			;Not full window
		mov	ax,40h
		mov	ds,ax		;DS <-- 40h = BIOS data segment
		sub	si,si
		push	[si].real_cursorposn ;Save current curpos
		mov	cx,1		;Count for "wrtcell INT 10H"

		mov	dh,byte ptr [bp].s_toprow

		.repeat
		    mov     dl,byte ptr [bp].s_leftcol
		    push    di

		    .repeat
			add	dl,byte ptr [bp].s_times
			mov	[si].real_cursorposn,dx ;Set requested curpos

			mov	ah,8
			int	10h	;Read cell at curpos

			sub	dl,byte ptr [bp].s_times
			mov	[si].real_cursorposn,dx ;Set requested curpos

			mov	bl,ah	;Attr to write <-- attr read
			mov	ah,9
			int	10h	;Write cells at curpos

			inc	dl
			dec	di
		    .until  z		;Until all of row moved

		    pop     di		;DI <-- # cells to move per row
		    inc     dh		;Set to next row
		.until	<dh a <byte ptr [bp].s_botrow>>

		pop	[si].real_cursorposn ;Restore current curpos
	    .endif

	    push    [bp].s_toprow
	    mov     ax,[bp].s_rightcol
	    sub     ax,[bp].s_times
	    inc     ax
	    push    ax			;Push left column
	    push    [bp].s_botrow
	    push    [bp].s_rightcol
	    mov     ax,-1
	    push    ax			;Maximum number of times
	    push    ss
	    lea     ax,[bp].s_celloff
	    push    ax			;Push cell pointer
	    sub     ax,ax
	    push    ax
	    Call    VioScrollDn 	;Let the other routine do it
	.endif

	sub	bx,bx
	RET
BvsScrollLf ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  BvsScrollRt					*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem Scroll Right		*/
;/*									*/
;/* FUNCTION:  Scrolls a portion of the video buffer right a specified	*/
;/*	       number of times. 					*/
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*									*/
;/* ENTRY POINT:  BvsScrollRt						*/
;/*   LINKAGE:	Call BvsScrollRt from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= s_celloff	Offset of fill Cell			*/
;/*	parmnm1 = s_cellsel	Selector of fill Cell			*/
;/*	parmnm2 = s_times	Number of times to scroll		*/
;/*	parmnm3 = s_rightcol	Rightmost column of window		*/
;/*	parmnm4 = s_botrow	Bottom row of window			*/
;/*	parmnm5 = s_leftcol	Leftmost column of window		*/
;/*	parmnm6 = s_toprow	Top row of window			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid TopRow value					*/
;/*		Invalid LeftCol value					*/
;/*									*/
;/* EFFECTS:  None							*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSCBsg					*/
;/*   ROUTINES:  CheckScrollParms, VioScrollDn				*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

;Bgnsub BvsScrollRt
;: Validate TopRow, BotRow, LeftCol, RightCol, Times, and Cell
;: If Error
;: : Indicate error in AX
;: Else
;: : If not clearing entire area
;: : : For Row=TopRow to BotRow
;: : : : For Col=RightCol to LeftCol+Times step -1
;: : : : : Read cell from (Row,Col-Times)
;: : : : : Write cell to (Row,Col)
;: : : : Endfor
;: : : Endfor
;: : Endif
;: : Call BvsScrollDn to clear the remaining area
;: : Set good return code
;: Endif
;Endsub

BvsScrollRt PROC NEAR			;Scroll Left
;	PUBLIC	BvsScrollRt

	Call	CheckScrlParms
	.if	z			;Valid parameters, compute pointers
	    mov     ax,[bp].s_rightcol
	    sub     ax,[bp].s_leftcol
	    inc     ax
	    .if     <[bp].s_times a ax>
		mov	[bp].s_times,ax ;Limit times to window size
	    .endif

	    mov     di,[bp].s_rightcol
	    sub     di,[bp].s_leftcol
	    inc     di
	    sub     di,[bp].s_times	;Number of cells to move per row
	    .if     nz			;Not full window

		mov	ax,40h
		mov	ds,ax
		sub	si,si
		push	[si].real_cursorposn ;Save current curpos
		mov	cx,1

		mov	dh,byte ptr [bp].s_toprow
		.repeat
		    mov     dl,byte ptr [bp].s_rightcol
		    push    di
		    .repeat

			sub	dl,byte ptr [bp].s_times
			mov	[si].real_cursorposn,dx ;Set requested curpos

			mov	ah,8
			int	10h	;Read cell at curpos

			add	dl,byte ptr [bp].s_times
			mov	[si].real_cursorposn,dx ;Set requested curpos

			mov	bl,ah	;Attribute
			mov	ah,9
			int	10h	;Write cells at curpos

			dec	dl
			dec	di
		    .until  z		;Until all of row moved
		    pop     di
		    inc     dh
		.until	<dh a <byte ptr [bp].s_botrow>>

		pop	[si].real_cursorposn ;Restore current curpos
	    .endif
	    push    [bp].s_toprow
	    push    [bp].s_leftcol
	    push    [bp].s_botrow
	    mov     ax,[bp].s_leftcol
	    add     ax,[bp].s_times
	    dec     ax
	    push    ax			;Push right column
	    mov     ax,-1
	    push    ax			;Maximum number of times
	    push    ss
	    lea     ax,[bp].s_celloff
	    push    ax			;Push cell pointer
	    sub     ax,ax
	    push    ax
	    Call    VioScrollDn 	;Let the other routine do it
	.endif
	sub	bx,bx
	RET
BvsScrollRt ENDP

BVS3SEG ENDS
	END
