home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ddkx86v5.zip
/
DDKX86
/
SRC
/
VDH
/
XGASCROL.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-04-14
|
74KB
|
1,728 lines
;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT Copyright (C) 1995 IBM Corporation
;
; The following IBM OS/2 WARP source code is provided to you solely for
; the purpose of assisting you in your development of OS/2 WARP device
; drivers. You may use this code in accordance with the IBM License
; Agreement provided in the IBM Device Driver Source Kit for OS/2. This
; Copyright statement may not be removed.;
;*****************************************************************************/
PAGE 60,132
TITLE XGASCROL.ASM -- Common Buffer Scroll Routines for EGA, VGA, BGA
;/*****************************************************************************
;*
;* SOURCE FILE NAME = XGASCROL.ASM
;*
;* DESCRIPTIVE NAME = BUFFERUPDATE scroll routines
;*
;*
;* VERSION V2.0
;*
;* DATE
;*
;* DESCRIPTION This module contains routines that run at ring 2 in
;* order to directly access the hardware.
;*
;* FUNCTIONS ScrollUp, ScrollDown
;* ScrollLeft, ScrollRight
;*
;* NOTES NONE
;*
;* STRUCTURES NONE
;*
;* EXTERNAL REFERENCES
;*
;* NONE
;*
;* EXTERNAL FUNCTIONS
;*
;* NONE
;*
;* CHANGE ACTIVIY =
;* DATE FLAG APAR CHANGE DESCRIPTION
;* -------- ---------- ----- --------------------------------------
;* mm/dd/yy @Vr.mpppxx xxxxx xxxxxxx
;* 03/25/89 @P1 D132 PL, DCR 132 changes
;* 04/11/91 D1348 NAKADA, Enable DBCS support in Vio-Window
;****************************************************************************/
.286c ; 286 protect mode instructions
.xlist
INCLUDE struc.inc ; Structure macro
INCLUDE error2.inc ; Subsystem error equates
INCLUDE vdhstruc.inc ; Buffer update data structures
INCLUDE vdhctl.inc ; Conditional Assemply Control ;MS01
INCLUDE vdhequ.inc ; Buffer update equates
INCLUDE xgamac.inc ;@P1
.list
EXTRN SetGenParms:NEAR ; Set up general buffer update parms @P1
IF VDHCGA AND (1 - CGA_ALWAYS_FAST) ; IF VDHCGA AND NOT CGA_ALWAYS_FAST ;@P1
;/*
;** If CGA video memory accesses may need to wait for retrace,
;** these routines are necessary. (See MAKEFILE)
;*/
extrn CGA_REP_MOVSW:far ;@P1
extrn CGA_REP_STOSW:far ;@P1
extrn CGA_REP_MOVSB_INCSI_LOOP:far ;@P1
extrn CGA_REP_MOVSW_STOSW_LOOP:far ;@P1
extrn CGA_REP_INCDI_STOSB_LOOP:far ;@P1
extrn CGA_REP_STOSB_INCDI_LOOP:far ;@P1
extrn CGA_REP_LODSB_STOSW_LOOP:far ;@P1
extrn CGA_REP_MOVSB_INCDI_LOOP:far ;@P1
extrn CGA_REP_MOVSW_ADDSI2_LOOP:far ;@P1
ENDIF ;VDHCGA ;@P1
IFDEF D1348 ;BufferUpdate with dbcs bits handling
extrn MoveUpLeftWrld:near
extrn MoveDownRightWrld:near
ENDIF ;D1348
R2CSEG SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:R2CSEG,DS:NOTHING,ES:NOTHING
;/****************************************************************************
;*
;* SUBROUTINE NAME: ScrollLeft
;*
;* DESCRIPTIVE NAME: Video device handler scroll left routine
;*
;* FUNCTION: Process scroll left sub-function
;* Scrolls a portion of the PVB, LVB left a specified
;* number of times and then fill the vacant portion
;* with the user specified cell.
;*
;* ENTRY POINT: ScrollLeft
;* LINKAGE: Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP ---> Stack frame (see VDHSTRUC.INC)
;* DS:SI ---> Parameter block buffer (see XGABUFUP.ASM)
;* ES:DI ---> Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;* SIZE DESCRIPTION
;* ---- -----------
;*
;* WORD Parameter length
;* WORD Flags (target buffer - LVB, PVB)
;* DWORD Application data address
;* DWORD Application data2 address (cell to be used to fill void)
;* WORD Index (5)
;* WORD Starting row (top row)
;* WORD Starting column (left column)
;* WORD Secondary row (bottom row)
;* WORD Secondary column (right column)
;* WORD RepeatFactor (# of times to scroll)
;* WORD LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR: AX = SetForScroll
;*
;* EFFECTS: All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/
PUBLIC ScrollLeft
ScrollLeft PROC
mov bx,LEFT
call SetForScroll
jc sclfx
test [bp].ScrollFlags,DOMOVE
jz sclf10
push bx
call MoveUpLeft
pop bx
sclf10: call FillRectWithCell
xor ax,ax
sclfx: ret
ScrollLeft ENDP
;/****************************************************************************
;*
;* SUBROUTINE NAME: ScrollUp
;*
;* DESCRIPTIVE NAME: Video device handler scroll up routine
;*
;* FUNCTION: Process scroll up sub-function
;* Scrolls a portion of the PVB, LVB up a specified
;* number of times and then fill the vacant portion
;* with the user specified cell.
;*
;* ENTRY POINT: ScrollUp
;* LINKAGE: Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP ---> Stack frame (see VDHSTRUC.INC)
;* DS:SI ---> Parameter block buffer (see XGABUFUP.ASM)
;* ES:DI ---> Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;* SIZE DESCRIPTION
;* ---- -----------
;*
;* WORD Parameter length
;* WORD Flags (target buffer - LVB, PVB)
;* DWORD Application data address
;* DWORD Application data2 address (cell to be used to fill void)
;* WORD Index (3)
;* WORD Starting row (top row)
;* WORD Starting column (left column)
;* WORD Secondary row (bottom row)
;* WORD Secondary column (right column)
;* WORD RepeatFactor (# of times to scroll)
;* WORD LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR: AX = SetForScroll
;*
;* EFFECTS: All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/
PUBLIC ScrollUp
ScrollUp PROC
mov bx,UP
call SetForScroll
jc scupx
test [bp].ScrollFlags,DOMOVE
jz scup10
push bx
call MoveUpLeft
pop bx
scup10: call FillRectWithCell
xor ax,ax
scupx: ret
ScrollUp ENDP
;/****************************************************************************
;*
;* SUBROUTINE NAME: ScrollRight
;*
;* DESCRIPTIVE NAME: Video device handler scroll right routine
;*
;* FUNCTION: Process scroll right sub-function
;* Scrolls a portion of the PVB, LVB right to a specified
;* number of times and then fill the vacant portion with
;* the user specified cell.
;*
;* ENTRY POINT: ScrollRight
;* LINKAGE: Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP ---> Stack frame (see VDHSTRUC.INC)
;* DS:SI ---> Parameter block buffer (see XGABUFUP.ASM)
;* ES:DI ---> Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;* SIZE DESCRIPTION
;* ---- -----------
;*
;* WORD Parameter length
;* WORD Flags (target buffer - LVB, PVB)
;* DWORD Application data address
;* DWORD Application data2 address (cell to be used to fill void)
;* WORD Index (6)
;* WORD Starting row (top row)
;* WORD Starting column (left column)
;* WORD Secondary row (bottom row)
;* WORD Secondary column (right column)
;* WORD RepeatFactor (# of times to scroll)
;* WORD LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR: AX = SetForScroll
;*
;* EFFECTS: All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/
PUBLIC ScrollRight
ScrollRight PROC
mov bx,RIGHT
call SetForScroll
jc scrtx
test [bp].ScrollFlags,DOMOVE
jz scrt10
push bx
call MoveDownRight
pop bx
scrt10: call FillRectWithCell
xor ax,ax
scrtx: ret
ScrollRight ENDP
;/****************************************************************************
;*
;* SUBROUTINE NAME: ScrollDown
;*
;* DESCRIPTIVE NAME: Video device handler scroll down routine
;*
;* FUNCTION: Process scroll down sub-function
;* Scrolls a portion of the PVB, LVB down a specified
;* number of times and then fill the vacant portion
;* with the user specified cell.
;*
;* ENTRY POINT: ScrollDown
;* LINKAGE: Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP ---> Stack frame (see VDHSTRUC.INC)
;* DS:SI ---> Parameter block buffer (see XGABUFUP.ASM)
;* ES:DI ---> Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;* SIZE DESCRIPTION
;* ---- -----------
;*
;* WORD Parameter length
;* WORD Flags (target buffer - LVB, PVB)
;* DWORD Application data address
;* DWORD Application data2 address (cell to be used to fill void)
;* WORD Index (4)
;* WORD Starting row (top row)
;* WORD Starting column (left column)
;* WORD Secondary row (bottom row)
;* WORD Secondary column (right column)
;* WORD RepeatFactor (# of times to scroll)
;* WORD LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR: AX = SetForScroll
;*
;* EFFECTS: All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/
PUBLIC ScrollDown
ScrollDown PROC
mov bx,DOWN
call SetForScroll
jc scdnx
test [bp].ScrollFlags,DOMOVE
jz scdn10
push bx
call MoveDownRight
pop bx
scdn10: call FillRectWithCell
xor ax,ax
scdnx: ret
ScrollDown ENDP
;/****************************************************************************
;*
;* SUBROUTINE NAME: LVBToPVB
;*
;* DESCRIPTIVE NAME: Video device handler copy LVB rectangle to PVB
;*
;* FUNCTION: Copy a rectangle from an LVB on to the PVB
;*
;* ENTRY POINT: LVBToPVB
;* LINKAGE: Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP ---> Stack frame (see VDHSTRUC.INC)
;* DS:SI ---> Parameter block buffer (see XGABUFUP.ASM)
;* ES:DI ---> Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;* SIZE DESCRIPTION
;* ---- -----------
;*
;* WORD Parameter length
;* WORD Flags (target buffer - LVB, PVB)
;* DWORD Application data address
;* DWORD Application data2 address (cell to be used to fill void)
;* WORD Index (4)
;* WORD Starting row (top row)
;* WORD Starting column (left column)
;* WORD Secondary row (bottom row)
;* WORD Secondary column (right column)
;* WORD RepeatFactor (# of times to scroll)
;* WORD LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR: AX = SetForScroll
;*
;* EFFECTS: All
;*
;* INTERNAL REFERENCES: SetForScroll,MoveLVBRectToPVB
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/
PUBLIC LVBToPVB ;@P1 begin
LVBToPVB PROC
xor ax,ax ; clear error code
push ds:[si].RepeatFactor ; save the old repeat factor
push ds:[si].Flags ; save the old flags
test [si].Flags, PVB_SEL_BIT ; write to the PVB
jz ltpx ; NO, do nothing
or [si].Flags, LVB_SEL_BIT ; LVB bit needs to be set
mov ds:[si].RepeatFactor,-1 ; this will be a scroll without move
mov bx,LVBPVB ; pretend to be a scroll function
call SetForScroll ; get the scroll parameters
jc ltpx
call MoveLVBRectToPVB ; The fill rect is the rect to move
xor ax,ax
ltpx: lds si,[bp].ParmBuf
pop ds:[si].Flags ; restore the old flags
pop ds:[si].RepeatFactor ;
ret
LVBToPVB ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = SetForScroll
;*
;* DESCRIPTION =
;*
;* Set up parameters for a scroll
;* SetForScroll does range checking and parameter adjustment for
;* all scroll functions. This is valid for 2 and 4 byte cell LVBs
;* and for the fill cell supplied as 2 or 4 bytes.
;*
;* All scrolls consist of two basic operations. The first is
;* move a rectangle. The second is fill a rectangle. The rectangle
;* to be moved will be NULL if the scroll is greater than the
;* depth of the rectangle in the direction of movement.
;*
;* This routine calculates the source rectangle and destination
;* rectangle for the move. For UP and LEFT scrolling, the rectangle
;* should be copied beginning to end. For DOWN and RIGHT the copy
;* should go from end to beginning. This routine provides the
;* correct buffer offset for the appropriate starting point of
;* the rectangle.
;*
;* INPUT =
;*
;* BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;* SS:BP - local data storage area
;* DS:SI - user passed parameter block
;* ES:DI - mode data structure
;* [bp].minrow - index of top most row in LVB (PVB coordinates)
;* [bp].mincol - index of left most row in LVB (PVB coordinates)
;* [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;* [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;* OUTPUT =
;*
;* CARRY CLEAR
;* BX = LVB selector if LVB scroll is indicated else 0
;*
;* [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;* [bp].ScrollFlags = either DOFILL or DOMOVE+DOFILL
;*
;* [bp].RowsToFill = rows to be filled with the default cell
;*
;* [bp].PVBFillOff = offset of start of PVB fill rectangle
;* [bp].PVBFillCount = # of bytes per fill line in PVB
;* [bp].PVBFillSkip = # of bytes to skip to reach next PVB line
;*
;* [bp].LVBFillOff = offset of start of LVB fill rectangle
;* [bp].LVBFillCount = # of bytes per fill line in LVB
;* [bp].LVBFillSkip = # of bytes to skip to reach next LVB line
;*
;* [bp].FillCellLow = first word of default fill cell
;* [bp].FillCellHigh = second word of default fill cell
;*
;* if DOMOVE is set in ScrollFlags
;*
;* [bp].RowsToMove = number of rows to move
;*
;* [bp].PVBMoveCount = # of bytes per PVB row to move
;* [bp].PVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].PVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;* [bp].LVBMoveCount = # of bytes per PVB row to move
;* [bp].LVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].LVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* CARRY SET
;* [bp].ScrollFlags = 0
;*
;* CALLS SetBaseRects, AdjustRects, CalcMoveValues, CalcFillValues
;*
;* USES AX,CX,DX,SI,DS,FLAGS
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;**************************************************************************/
PUBLIC SetForScroll ;@P1 begin
SetForScroll PROC
call SetGenParms ; set general parameters for all
; buffer update functions
call SetBaseRects ; do basic value setting on source,
; destination and fill rectangles
.if <nc> ; parms from SetBaseRects are good
call AdjustRects ; adjust the rectangle values for the
; specific type of scroll
; At this point we have source and
; and destination rectangles that are
; both entirely contained in the LVB.
; We have also calculated the
; rectangle that will be left void
; when the moved rectangle is copied.
test [bp].ScrollFlags,DOMOVE ; Are move rectangles != NULL?
.if <nz> ; Yes, calculate the move parms
call CalcMoveValues ; and buffer lengths
.endif
call CalcFillValues ; calculate the fill rectangle parms
mov bx, [bp].LVB_SEL ; (bx) = LVB selector
clc
.endif
ret
SetForScroll ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = SetBaseRects
;*
;* DESCRIPTION =
;*
;* Set default values for source, dest and fill rectangles
;*
;* SetBaseRects does basic rectangle value setting for the source
;* and destination rectangles for the rectangle that needs to be
;* moved as part of the scroll. Default values for the fill
;* rectangle are also set.
;*
;* This routine also checks and adjusts the RepeatFactor, the number
;* of rows or columns to be scrolled. If it is 0, an error is returned.
;*
;* INPUT = BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;* SS:BP - local data storage area
;* DS:SI - user passed parameter block
;* ES:DI - mode data structure
;* [bp].minrow - index of top most row in LVB (PVB coordinates)
;* [bp].mincol - index of left most row in LVB (PVB coordinates)
;* [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;* [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;* OUTPUT =
;*
;* CARRY CLEAR
;* CX = repeat factor
;* [bp].ScrollFlags = DOMOVE+DOFILL
;* [bp].topscroll = ParmBlock->Row
;* [bp].topdest = "
;* [bp].topfill = "
;* [bp].leftscroll = ParmBlock->Col
;* [bp].leftdest = "
;* [bp].leftfill = "
;* [bp].rightscroll = ParmBlock->Row2
;* [bp].rightdest = "
;* [bp].rightfill = "
;* [bp].bottomscroll = ParmBlock->Col2
;* [bp].bottomdest = "
;* [bp].bottomfill = "
;*
;* CARRY SET
;* [bp].ScrollFlags = 0
;*
;*
;* CALLS none
;*
;* USES AX,CX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* topscroll = parmrow
;* leftscroll = parmcol
;* bottomscroll = parmrow2
;* rightscroll = parmcol2
;* topdest = topscroll
;* leftdest = leftscroll
;* bottomdest = bottomscroll
;* rightdest = rightscroll
;* topfill = topscroll
;* leftfill = leftscroll
;* bottomfill = bottomscroll
;* rightfill = rightscroll
;* DoMoveFlag = TRUE
;* DoFillFlag = TRUE
;* if (RepCount == 0)
;* DoMoveFlag = FALSE
;* DoFillFlag = FALSE
;* set error
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC SetBaseRects ;@P1 begin
SetBaseRects PROC
mov ax,[si].Row ; set all of the top coordinates
.if <ax b [bp].minrow> near
mov ax,[bp].minrow
.endif
; BUGBUG this is really should not be
.if <ax a [bp].maxrow> near ; here, but it is necessary to pass
mov ax,[bp].maxrow ; the component tests. Remove it at
.endif ; the first opertunity.
test bx,LVBPVB
.if <z> ; NOT LVB to PVB
.if <ax b es:[di].ScrlRectTop> near
mov ax,es:[di].ScrlRectTop
.endif
.if <ax a es:[di].ScrlRectBottom> near
mov ax,es:[di].ScrlRectBottom
.endif
.endif
mov [bp].topscroll,ax
mov [bp].topdest,ax
mov [bp].topfill,ax
mov cx,[si].Row2 ; set all of the bottom coordinates
.if <cx a [bp].maxrow> near
mov cx,[bp].maxrow
.endif
test bx,LVBPVB
.if <z> ; NOT LVB to PVB
.if <cx a es:[di].ScrlRectBottom> near
mov cx,es:[di].ScrlRectBottom
.endif
.endif
mov [bp].bottomscroll,cx
mov [bp].bottomdest,cx
mov [bp].bottomfill,cx
.if <ax a cx> near ; rectangle is not valid
mov ax,ERROR_VIO_ROW
jmp sbrerr
.endif
mov ax,[si].Col ; set all of the left coordinates
.if <ax b [bp].mincol> near
mov ax,[bp].mincol
.endif
.if <ax a [bp].maxcol> near
mov ax,[bp].maxcol
.endif
test bx,LVBPVB
.if <z> ; NOT LVB to PVB
.if <ax b es:[di].ScrlRectLeft> near
mov ax,es:[di].ScrlRectLeft
.endif
.if <ax a es:[di].ScrlRectRight> near
mov ax,es:[di].ScrlRectRight
.endif
.endif
mov [bp].leftscroll,ax
mov [bp].leftdest,ax
mov [bp].leftfill,ax
mov cx,[si].Col2 ; set all of the right coordinates
.if <cx a [bp].maxcol> near
mov cx,[bp].maxcol
.endif
test bx,LVBPVB
.if <z> ; NOT LVB to PVB
.if <cx a es:[di].ScrlRectRight> near
mov cx,es:[di].ScrlRectRight
.endif
.endif
mov [bp].rightscroll,cx
mov [bp].rightdest,cx
mov [bp].rightfill,cx
.if <ax a cx> near ; rectangle is not valid
mov ax,ERROR_VIO_COL
jmp sbrerr
.endif
cmp ds:[si].ParmLength,LVBRowOff; Does caller want the touch rect?
.if <ae> ; Yes, return the Touch Rect
mov ax,[bp].leftscroll
mov ds:[si].TouchXLeft,ax
mov ax,[bp].topscroll
mov ds:[si].TouchYTop,ax
mov ax,[bp].rightscroll
mov ds:[si].TouchXRight,ax
mov ax,[bp].bottomscroll
mov ds:[si].TouchYBottom,ax
.endif
mov [bp].ScrollFlags, DOMOVE + DOFILL
mov cx, [si].RepeatFactor
or cx,cx ; clears carry
.if <z>
mov [bp].ScrollFlags,cx ; do not Move or Fill
xor ax,ax ; not an error not to scroll
stc
.endif
sbrx: ret
sbrerr: stc
jmp sbrx
SetBaseRects ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = AdjustRects
;*
;* DESCRIPTION =
;*
;* Adjust values for source, dest and fill rectangles
;*
;* AdjustRects does scroll specific rectangle value setting for the
;* source and destination rectangles for the rectangle that needs to
;* be moved as part of the scroll. Values for the fill rectangle are
;* also adjusted.
;*
;* This routine also checks and adjusts the RepeatFactor, the number
;* of rows or columns to be scrolled. If the value would clear the
;* entire scroll rectangle, (no area left to be moved) the DOMOVE
;* flag in the scroll flags is cleared.
;*
;* If the repeat factor is larger than the depth of the scroll rectangle
;* in the direction it is being scrolled, the repeat factor is reduced
;* to the depth of the scroll rectangle.
;*
;*
;* INPUT = BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;* CX = repeat factor
;* SS:BP - local data storage area
;* DS:SI - user passed parameter block
;* ES:DI - mode data structure
;* [bp].topscroll - source rectangle for move set to
;* [bp].leftscroll default values
;* [bp].rightscroll
;* [bp].bottomscroll
;* [bp].topdest - destination rectangle for move set
;* [bp].leftdest to default values
;* [bp].rightdest
;* [bp].bottomdest
;* [bp].topfill - rectangle left void by move set to
;* [bp].leftfill default values
;* [bp].rightfill
;* [bp].bottomfill
;*
;* OUTPUT =
;* CX = repeat factor adjusted to MIN (rect depth,repeat factor)
;* [bp].ScrollFlags = DOMOVE clear if entire rectangle is vacant
;*
;* [bp].topfill = Rectangle that the scroll leaves vacant
;* [bp].leftfill = "
;* [bp].rightfill = "
;* [bp].bottomfill = "
;*
;* if DOMOVE is set
;* [bp].topscroll = Rect adjusted to indicate source of move
;* [bp].leftscroll = "
;* [bp].rightscroll = "
;* [bp].bottomscroll = "
;*
;* [bp].topdest = Rect adjusted to indicate dest of move
;* [bp].leftdest = "
;* [bp].rightdest = "
;* [bp].bottomdest = "
;*
;* CALLS none
;*
;* USES AX,CX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* UP:
;* DOWN:
;* if (RepCount > bottomscroll - topscroll + 1)
;* RepCount = bottomscroll - topscroll + 1
;* DoMoveFlag = FALSE
;* UP:
;* topscroll = topscroll + RepCount
;* bottomdest = bottomscroll - RepCount
;* topfill = bottomdest + 1
;* DOWN:
;* bottomscroll = bottomscroll - RepCount
;* topdest = topscroll + RepCount
;* bottomfill = topdest - 1
;* LEFT:
;* RIGHT:
;* if (RepCount > rightscroll - leftscroll + 1)
;* RepCount = rightscroll - leftscroll + 1
;* DoMoveFlag = FALSE
;* LEFT:
;* leftscroll = leftscroll + RepCount
;* rightdest = rightscroll - RepCount
;* leftfill = rightdest + 1
;* RIGHT:
;* rightscroll = rightscroll - RepCount
;* leftdest = leftscroll + RepCount
;* rightfill = leftdest - 1
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC AdjustRects ;@P1 begin
AdjustRects PROC
; correct coordinates for scroll type
test bx,UP+DOWN ; Is this a scroll up or scroll down
.if <nz> ; Yes, do the up-down thing
mov ax,[bp].bottomscroll
sub ax,[bp].topscroll ; (ax) = maximum possible scroll w/move
.if <cx a ax>
and [bp].ScrollFlags,NOT DOMOVE
inc ax ; (ax) = scroll to clear entire rect
mov cx,ax ; (cx) = maximum repcount
.else
test bx,UP ; Is this a scroll up?
.if <nz> ; Yes, do the up thing
add [bp].topscroll,cx
mov ax,[bp].bottomscroll
sub ax,cx
mov [bp].bottomdest,ax
inc ax
mov [bp].topfill,ax
.else
sub [bp].bottomscroll,cx
mov ax,[bp].topscroll
add ax,cx
mov [bp].topdest,ax
dec ax
mov [bp].bottomfill,ax
.endif
.endif
.else ; Do the left-right thing
mov ax,[bp].rightscroll
sub ax,[bp].leftscroll ; (ax) = maximum possible scroll w/move
.if <cx a ax>
and [bp].ScrollFlags,NOT DOMOVE
inc ax ; (ax) = scroll to clear entire rect
mov cx,ax ; (cx) = maximum repcount
.else
test bx,LEFT ; Is this a scroll left?
.if <nz> ; Yes, do the left thing
add [bp].leftscroll,cx
mov ax,[bp].rightscroll
sub ax,cx
mov [bp].rightdest,ax
inc ax
mov [bp].leftfill,ax
.else ; Do the Right thing
sub [bp].rightscroll,cx
mov ax,[bp].leftscroll
add ax,cx
mov [bp].leftdest,ax
dec ax
mov [bp].rightfill,ax
.endif
.endif
.endif
ret
AdjustRects ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = CalcMoveValues
;*
;* DESCRIPTION =
;*
;* Calculate values the move rectangle functions need
;*
;* CalcMoveValues calculates the offsets into the source and destination
;* rectangles used by the move functions. The UP and LEFT scroll
;* functions copy from the beginning of the buffer to the end. The
;* DOWN and RIGHT functions copy from the end of the buffer to the
;* beginning. This function provides the correct starting point
;* for the scroll requested.
;*
;* This routine also calculates the number of rows that need to
;* be copied. This value will always be at least one.
;*
;* The number of bytes in each row is calculated. The value of
;* this number is always at least one * cellsize (2 or 4 bytes)
;* and is always a multiple of cell size.
;*
;* The number of bytes that need to be skipped to reach the start
;* of the next row to be copied is calculated. This value may be
;* zero.
;*
;* With the exception of the number of rows to move, all of the
;* values above are calculated separately for the LVB and the PVB
;* because the cell size may be different between the two.
;*
;* INPUT = BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;* SS:BP - local data storage area
;* DS:SI - user passed parameter block
;* ES:DI - mode data structure
;* [bp].lvb_width - width of the LVB in cells
;* [bp].cellsize - number of bytes per cell in the LVB
;*
;* [bp].minrow - index of top most row in LVB (PVB coordinates)
;* [bp].mincol - index of left most row in LVB (PVB coordinates)
;* [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;* [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;* [bp].topscroll = Rect adjusted to indicate source of move
;* [bp].leftscroll = "
;* [bp].rightscroll = "
;* [bp].bottomscroll = "
;*
;* [bp].topdest = Rect adjusted to indicate dest of move
;* [bp].leftdest = "
;* [bp].rightdest = "
;* [bp].bottomdest = "
;*
;* OUTPUT =
;* [bp].RowsToMove = number of rows to move
;*
;* [bp].PVBMoveCount = # of bytes per PVB row to move
;* [bp].PVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].PVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;* [bp].LVBMoveCount = # of bytes per PVB row to move
;* [bp].LVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].LVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* CALLS none
;*
;* USES AX,CX,DX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* RowsToMove = bottomscroll - topscroll + 1
;* PVBMoveCount = (rightscroll - leftscroll) * cellsize
;* PVBRowSkip = modeCols * cellsize - PVBMoveCount
;* LVBMoveCount = (rightscroll - leftscroll) * cellsize
;* LVBRowSkip = lvb_width * cellsize - LVBMoveCount
;* UP:
;* LEFT:
;* LVBMoveSrcOff = ((topscroll - minrow) * lvb_width +
;* (leftscroll - mincol)) * cellsize
;* PVBMoveSrcOff = (topscroll * modeCols + leftscroll) *
;* cellsize
;* LVBMoveDestOff = ((topdest - minrow) * lvb_width +
;* (leftdest - mincol)) * cellsize
;* PVBMoveDestOff = (topdest * modeCols + leftdest) *
;* cellsize
;* DOWN:
;* RIGHT:
;* LVBMoveSrcOff = ((bottomscroll - minrow) * lvb_width +
;* (rightscroll - mincol)) * cellsize
;* PVBMoveSrcOff = (bottomscroll * modeCols + rightscroll) *
;* cellsize
;* LVBMoveDestOff = ((bottomdest - minrow) * lvb_width +
;* (rightdest - mincol)) * cellsize
;* PVBMoveDestOff = (bottomdest * modeCols + rightdest) *
;* cellsize
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC CalcMoveValues ;@P1 begin
CalcMoveValues PROC
mov ax,[bp].bottomscroll ; calculate the number of rows
sub ax,[bp].topscroll ; to move
inc ax
mov [bp].RowsToMove,ax
mov cx,[bp].rightscroll ; calculate bytes to move in PVB
sub cx,[bp].leftscroll
inc cx
shl cx,1
mov [bp].PVBMoveCount,cx
mov ax,es:[di].TextCols ; calculate bytes to skip in PVB
shl ax,1
sub ax,cx
mov [bp].PVBMoveSkip,ax
mov ax,[bp].lvb_width ; calculate bytes to skip in LVB
shl ax,1
sub ax,cx
.if <[bp].cellsize e WorldCellSize>
shl cx,1
shl ax,1
.endif
mov [bp].LVBMoveCount,cx ; bytes to move in LVB
mov [bp].LVBMoveSkip,ax
; calculate buffer copy addresses
test bx,UP+LEFT
.if <nz> ; Do the UP-LEFT thing
mov ax,[bp].topscroll ; calculate PVB source offset
mul es:[di].TextCols
add ax,[bp].leftscroll
shl ax,1
mov [bp].PVBMoveSrcOff,ax
mov ax,[bp].topdest ; calculate PVB destination offset
mul [bp].lvb_width
add ax,[bp].leftdest
shl ax,1
mov [bp].PVBMoveDestOff,ax
mov ax,[bp].topscroll ; calculate LVB source offset
sub ax,[bp].minrow
mul [bp].lvb_width
add ax,[bp].leftscroll
sub ax,[bp].mincol
shl ax,1 ; (ax) = LVB src off for 2 byte cell
mov [bp].LVBMoveSrcOff,ax
mov ax,[bp].topdest ; calculate LVB destination offset
sub ax,[bp].minrow
mul [bp].lvb_width
add ax,[bp].leftdest
sub ax,[bp].mincol
shl ax,1 ; (cx)= LVB dest off for 2 byte cell
mov [bp].LVBMoveDestOff,ax
.if <[bp].cellsize e WorldCellSize>
shl [bp].LVBMoveSrcOff,1 ; 4 bytes per cell
shl [bp].LVBMoveDestOff,1 ; 4 bytes per cell
.endif
.else ; Do the DOWN-RIGHT thing
mov ax,[bp].bottomscroll; calculate PVB source offset
mul es:[di].TextCols
add ax,[bp].rightscroll
shl ax,1
mov [bp].PVBMoveSrcOff,ax
mov ax,[bp].bottomdest ; calculate PVB destination offset
mul [bp].lvb_width
add ax,[bp].rightdest
shl ax,1
mov [bp].PVBMoveDestOff,ax
mov ax,[bp].bottomscroll; calculate LVB source offset
sub ax,[bp].minrow
mul [bp].lvb_width
add ax,[bp].rightscroll
sub ax,[bp].mincol
shl ax,1 ; (ax) = LVB src off for 2 byte cell
mov [bp].LVBMoveSrcOff,ax
mov ax,[bp].bottomdest ; calculate LVB destination offset
sub ax,[bp].minrow
mul [bp].lvb_width
add ax,[bp].rightdest
sub ax,[bp].mincol
shl ax,1 ; (cx)= LVB dest off for 2 byte cell
mov [bp].LVBMoveDestOff,ax
.if <[bp].cellsize e WorldCellSize>
inc [bp].LVBMoveSrcOff ; start at last word of cell
inc [bp].LVBMoveDestOff ; start at last word of cell
shl [bp].LVBMoveSrcOff,1 ; 4 bytes per cell
shl [bp].LVBMoveDestOff,1 ; 4 bytes per cell
.endif
.endif
ret
CalcMoveValues ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = CalcFillValues
;*
;* DESCRIPTION =
;*
;* Calculate values the fill rectangle function needs
;*
;* CalcFillValues calculates the offset into the fill rectangle that
;* is used by the fill function.
;*
;* This routine also calculates the number of rows that need to
;* be filled. This value will always be at least one.
;*
;* The number of bytes in each row is calculated. The value of
;* this number is always at least one * cellsize (2 or 4 bytes)
;* and is always a multiple of cell size.
;*
;* The number of bytes that need to be skipped to reach the start
;* of the next row to be copied is calculated. This value may be
;* zero.
;*
;* With the exception of the number of rows to move, all of the
;* values above are calculated separately for the LVB and the PVB
;* because the cell size may be different between the two.
;*
;* INPUT = BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;* SS:BP - local data storage area
;* DS:SI - user passed parameter block
;* ES:DI - mode data structure
;* [bp].lvb_width - width of the LVB in cells
;* [bp].cellsize - number of bytes per cell in the LVB
;*
;* [bp].minrow - index of top most row in LVB (PVB coordinates)
;* [bp].mincol - index of left most row in LVB (PVB coordinates)
;*
;* [bp].topfill = Rect adjusted to indicate fill region
;* [bp].leftfill = "
;* [bp].rightfill = "
;* [bp].bottomfill = "
;*
;* OUTPUT =
;* [bp].RowsToFill = rows to be filled with the default cell
;*
;* [bp].PVBFillCount = # of bytes per fill line in PVB
;* [bp].PVBFillSkip = # of bytes to skip to reach next PVB line
;* [bp].PVBFillOff = offset of beginning of PVB fill rectangle
;*
;* [bp].LVBFillCount = # of bytes per fill line in LVB
;* [bp].LVBFillSkip = # of bytes to skip to reach next LVB line
;* [bp].LVBFillOff = offset of beginning of LVB fill rectangle
;*
;* [bp].FillCellLow = first word of default fill cell
;* [bp].FillCellHigh = second word of default fill cell
;*
;* CALLS none
;*
;* USES AX,CX,DX,SI,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* RowsToFill = bottomfill - topfill + 1
;* PVBFillOff = (topfill * modeCols + leftfill) * cellsize
;* PVBFillCount = rightfill - leftfill * cellsize
;* PVBFillSkip = modeCols * cellsize - PVBFillCount
;* LVBFillOff = (leftfill - minrow) * lvb_width +
;* (topfill - mincol) * cellsize
;* LVBFillCount = rightfill - leftfill * cellsize
;* LVBFillSkip = modeCols * cellsize - LVBFillCount
;* FillCellLow = first word of cell
;* if (inputcellsize = 4)
;* FillCellHigh = second word of cell
;* else
;* FillCellHigh = 0
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC CalcFillValues ;@P1 begin
CalcFillValues PROC
mov ax,[bp].bottomfill ; calculate the number of rows
sub ax,[bp].topfill ; to fill
inc ax
mov [bp].RowsToFill,ax
mov ax,[bp].topfill ; calculate PVB source offset
mul es:[di].TextCols
add ax,[bp].leftfill
shl ax,1
mov [bp].PVBFillOff,ax
mov cx,[bp].rightfill ; calculate byte per PVB fill row
sub cx,[bp].leftfill
inc cx
shl cx,1
mov [bp].PVBFillCount,cx
mov ax,es:[di].TextCols ; calculate bytes to skip in PVB
shl ax,1
sub ax,cx
mov [bp].PVBFillSkip,ax
mov ax,[bp].lvb_width ; calculate bytes to skip in LVB
shl ax,1
sub ax,cx
.if <[bp].cellsize e WorldCellSize>
shl cx,1
shl ax,1
.endif
mov [bp].LVBFillCount,cx ; bytes to fill in LVB
mov [bp].LVBFillSkip,ax
mov ax,[bp].topfill ; calculate LVB source offset
sub ax,[bp].minrow
mul [bp].lvb_width
add ax,[bp].leftfill
sub ax,[bp].mincol
shl ax,1
.if <[bp].cellsize e WorldCellSize>
shl ax,1
.endif
mov [bp].LVBFillOff,ax
test bx,LVBPVB
.if <z>
test [si].Flags,CGAAttr ; the jump is 5 lines down
lds si,[si].AppCellAddr
lodsw
mov [bp].FillCellLow,ax
mov [bp].FillCellHigh,0
.if <z> and
.if <[bp].cellsize e WorldCellSize>
lodsw
mov [bp].FillCellHigh,ax
.endif
lds si,[bp].ParmBuf ; (ds:si) -> parameter buffer
.endif
ret
CalcFillValues ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = MoveUpLeft
;*
;* DESCRIPTION =
;*
;* Move a rectangle for ScrollUp or ScrollLeft
;*
;* MoveUpLeft copys a rectangle in the LVB and/or PVB from beginning
;* to end, one line at a time.
;*
;* INPUT = BX = LVB selector or 0 if no LVB write indicated
;* SS:BP - local data storage area
;*
;* [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;* [bp].RowsToMove = number of rows to move
;*
;* [bp].PVBMoveCount = # of bytes per PVB row to move
;* [bp].PVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].PVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;* [bp].LVBMoveCount = # of bytes per PVB row to move
;* [bp].LVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].LVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* OUTPUT =
;* The rectangle in the LVB or PVB is moved as appropriate
;*
;* CALLS none
;*
;* USES AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* cursrcoff = FirstMoveSrcOff
;* curdestoff = FirstMoveDestOff
;* while (RowsToMove--)
;* curcount = MoveCount
;* while (curcount--)
;* *curdestoff++ = *cursrcoff++
;* cursrcoff += NextLineMove
;* curdestoff += NextLineMove
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC MoveUpLeft ;@P1 begin
MoveUpLeft PROC
cld ; increment si, di
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToMove
mov si,[bp].LVBMoveSrcOff
mov di,[bp].LVBMoveDestOff
mov dx,[bp].LVBMoveCount
shr dx,1 ; convert bytes to words
mulf10: mov cx,dx ; (cx) = bytes to move this row
IFDEF D1348 ;check if DBCS && common lvb.
.if <bit <[bp].flgDBCS> and anyDBCS> and
.if <[bp].j_funcindx eq WorldFmtIndx>
push bx ; save row count
call MoveUpLeftWrld
pop bx ; restore row count
.else
rep movsw ; move the line
.endif
ELSE ;D1348
rep movsw ; move the line
ENDIF ;D1348
add si,[bp].LVBMoveSkip ; advance to the next source line
add di,[bp].LVBMoveSkip ; advance to the next dest line
dec bx ; Are there more rows to move?
jnz mulf10 ; Yes, go do the next one
.endif
mov bx,[bp].PVB_SEL
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToMove
mov si,[bp].PVBMoveSrcOff
mov di,[bp].PVBMoveDestOff
mov dx,[bp].PVBMoveCount
shr dx,1 ; convert bytes to words
mulf20: mov cx,dx ; (cx) = bytes to move this row
REP_MOVSW ; Use this macro so CGA can share
; the same set of sources
add si,[bp].PVBMoveSkip ; advance to the next source line
add di,[bp].PVBMoveSkip ; advance to the next dest line
dec bx ; Are there more rows to move?
jnz mulf20 ; Yes, go do the next one
.endif
ret
MoveUpLeft ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = MoveDownRight
;*
;* DESCRIPTION =
;*
;* Move a rectangle for ScrollDown or ScrollRight
;*
;* MoveDownRight copys a rectangle in the LVB and/or PVB from beginning
;* to end, one line at a time.
;*
;* INPUT = BX = LVB selector or 0 if no LVB write indicated
;* SS:BP - local data storage area
;*
;* [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;* [bp].RowsToMove = number of rows to move
;*
;* [bp].PVBMoveCount = # of bytes per PVB row to move
;* [bp].PVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].PVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;* [bp].LVBMoveCount = # of bytes per PVB row to move
;* [bp].LVBMoveSkip = # of bytes to skip to get to the next row
;* [bp].LVBMoveSrcOff = offset to start of PVB source buffer
;* [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* OUTPUT =
;* The rectangle in the LVB or PVB is moved as appropriate
;*
;* CALLS none
;*
;* USES AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* cursrcoff = LastMoveSrcOff
;* curdestoff = LastMoveDestOff
;* while (RowsToMove--)
;* curcount = MoveCount
;* while (curcount--)
;* *curdestoff-- = *cursrcoff--
;* cursrcoff -= NextLineMove
;* curdestoff -= NextLineMove
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC MoveDownRight ;@P1 begin
MoveDownRight PROC
std ; decrement si, di
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToMove
mov si,[bp].LVBMoveSrcOff
mov di,[bp].LVBMoveDestOff
mov dx,[bp].LVBMoveCount
shr dx,1 ; convert bytes to words
mdrt10: mov cx,dx ; (cx) = bytes to move this row
IFDEF D1348 ;check if DBCS && common lvb.
.if <bit <[bp].flgDBCS> and anyDBCS> and
.if <[bp].j_funcindx eq WorldFmtIndx>
push bx ; save row count
call MoveDownRightWrld
pop bx ; restore row count
.else
rep movsw ; move the line
.endif
ELSE ;D1348
rep movsw ; move the line
ENDIF ;D1348
sub si,[bp].LVBMoveSkip ; advance to the next source line
sub di,[bp].LVBMoveSkip ; advance to the next dest line
dec bx ; Are there more rows to move?
jnz mdrt10 ; Yes, go do the next one
.endif
mov bx,[bp].PVB_SEL
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToMove
mov si,[bp].PVBMoveSrcOff
mov di,[bp].PVBMoveDestOff
mov dx,[bp].PVBMoveCount
shr dx,1 ; convert bytes to words
mdrt20: mov cx,dx ; (cx) = bytes to move this row
REP_MOVSW ; Use this macro so CGA can share
; the same set of sources
sub si,[bp].PVBMoveSkip ; advance to the next source line
sub di,[bp].PVBMoveSkip ; advance to the next dest line
dec bx ; Are there more rows to move?
jnz mdrt20 ; Yes, go do the next one
.endif
ret
MoveDownRight ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = FillRectWithCell
;*
;* DESCRIPTION =
;*
;* Fill a rectangle for with the default cell
;*
;* FillRectWithCell fills the specified rectangle in the LVB and/or
;* PVB with the given cell, beginning to end, one line at a time.
;*
;* INPUT = BX = LVB selector or 0 if no LVB write indicated
;* SS:BP - local data storage area
;*
;* [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;* [bp].RowsToFill = rows to be filled with the default cell
;*
;* [bp].PVBFillCount = # of bytes per fill line in PVB
;* [bp].PVBFillSkip = # of bytes to skip to reach next PVB line
;* [bp].PVBFillOff = offset of beginning of PVB fill rectangle
;*
;* [bp].LVBFillCount = # of bytes per fill line in LVB
;* [bp].LVBFillSkip = # of bytes to skip to reach next LVB line
;* [bp].LVBFillOff = offset of beginning of LVB fill rectangle
;*
;* [bp].FillCellLow = first word of default fill cell
;* [bp].FillCellHigh = second word of default fill cell
;*
;* OUTPUT =
;* The rectangle in the LVB or PVB is moved as appropriate
;*
;*
;* CALLS none
;*
;* USES AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* curdestoff = FirstFillDestOff
;* while (RowsToFill)
;* for (curline = FirstFillLine; curline <= LastFillLine; curline++)
;* curcount = FillCount
;* while (curcount--)
;* *curdestoff = fillcell
;* curdestoff += NextLineFill
;*
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC FillRectWithCell ;@P1 begin
FillRectWithCell PROC
cld ; increment si, di
mov ax,[bp].FillCellLow
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToFill
mov di,[bp].LVBFillOff
mov dx,[bp].LVBFillCount
.if <[bp].cellsize e WorldCellSize>
mov si,[bp].FillCellHigh
shr dx,2 ; convert bytes to cells
frwc10: mov cx,dx ; (cx) = bytes to move this row
.repeat ; fill the line with the cell
stosw
xchg ax,si
stosw
xchg ax,si
.loop
add di,[bp].LVBFillSkip ; advance to the next source line
dec bx ; Are there more rows to move?
jnz frwc10 ; Yes, go do the next one
.else
shr dx,1 ; convert bytes to cells
frwc20: mov cx,dx ; (cx) = bytes to move this row
rep stosw ; fill the line with the cell
add di,[bp].LVBFillSkip ; advance to the next source line
dec bx ; Are there more rows to move?
jnz frwc20 ; Yes, go do the next one
.endif
.endif
mov bx,[bp].PVB_SEL
.if <nonzero bx>
mov ds,bx
mov es,bx
mov bx,[bp].RowsToFill
mov di,[bp].PVBFillOff
mov dx,[bp].PVBFillCount
shr dx,1 ; convert bytes to words
frwc30: mov cx,dx ; (cx) = bytes to move this row
REP_STOSW ; Use this macro so CGA can share
; the same set of sources
add di,[bp].PVBFillSkip ; advance to the next dest line
dec bx ; Are there more rows to move?
jnz frwc30 ; Yes, go do the next one
.endif
ret
FillRectWithCell ENDP ;@P1 end
;/***************************************************************************
;*
;* FUNCTION NAME = MoveLVBRectToPVB
;*
;* Copy a rectangle from LVB to PVB
;*
;* MoveLVBRectToPVB copys the FillRect in the LVB to the FillRect in
;* the PVB. Conversions for different cell sizes are done at this time.
;*
;* INPUT = BX = LVB selector or 0 if no LVB write indicated
;* SS:BP - local data storage area
;*
;* [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;* [bp].RowsToFill = rows to be filled with the default cell
;*
;* [bp].PVBFillCount = # of bytes per fill line in PVB
;* [bp].PVBFillSkip = # of bytes to skip to reach next PVB line
;* [bp].PVBFillOff = offset of beginning of PVB fill rectangle
;*
;* [bp].LVBFillCount = # of bytes per fill line in LVB
;* [bp].LVBFillSkip = # of bytes to skip to reach next LVB line
;* [bp].LVBFillOff = offset of beginning of LVB fill rectangle
;*
;* [bp].FillCellLow = first word of default fill cell
;* [bp].FillCellHigh = second word of default fill cell
;*
;* OUTPUT =
;* The rectangle in the LVB or PVB is moved as appropriate
;*
;*
;* CALLS none
;*
;* USES AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* cursrcoff = LVBFillOff
;* curdestoff = PVBFillOff
;* while (RowsToFill)
;* curcount = FillCount
;* while (curcount--)
;* *curdestoff = *cursrcoff
;* curdestoff += PVBFillSkip
;* cursrcoff += LVBFillSkip
;*
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR = NONE
;*
;****************************************************************************/
PUBLIC MoveLVBRectToPVB ;@P1 begin
MoveLVBRectToPVB PROC
cld ; increment si, di
.if <nonzero bx> and
mov ds,bx ; (ds) = LVB segment
mov bx,[bp].PVB_Sel
.if <nonzero bx>
mov es,bx ; (es) = PVB segment
mov si,[bp].LVBFillOff ; (si) = LVB rectangle offset
mov di,[bp].PVBFillOff ; (di) = PVB rectangle offset
mov bx,[bp].RowsToFill
mov dx,[bp].LVBFillCount
.if <[bp].cellsize e WorldCellSize>
shr dx,2 ; convert bytes to cells
lrtp10: mov cx,dx ; (cx) = bytes to move this row
REP_MOVSW_ADDSI2_LOOP ; Use this macro so CGA can share
; the same set of sources
add si,[bp].LVBFillSkip ; advance to the next LVB line
add di,[bp].PVBFillSkip ; advance to the next PVB line
dec bx ; Are there more rows to move?
jnz lrtp10 ; Yes, go do the next one
.else
shr dx,1 ; convert bytes to cells
lrtp20: mov cx,dx ; (cx) = bytes to move this row
REP_MOVSW ; Use this macro so CGA can share
; the same set of sources
add si,[bp].LVBFillSkip ; advance to the next LVB line
add di,[bp].PVBFillSkip ; advance to the next PVB line
dec bx ; Are there more rows to move?
jnz lrtp20 ; Yes, go do the next one
.endif
.endif
ret
MoveLVBRectToPVB ENDP ;@P1 end
R2CSEG ENDS
END