home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / VDH / CGASCROL.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  63KB  |  1,164 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT (C) Microsoft Corporation, 1989
  4. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  5. ;
  6. ;    The following IBM OS/2 WARP source code is provided to you solely for
  7. ;    the purpose of assisting you in your development of OS/2 WARP device
  8. ;    drivers. You may use this code in accordance with the IBM License
  9. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  10. ;    Copyright statement may not be removed.;
  11. ;*****************************************************************************/
  12.         PAGE    60,132
  13.         TITLE   CGASCROL.ASM -- CGA Buffer Scroll Routines
  14. ;/*****************************************************************************
  15. ;*
  16. ;* SOURCE FILE NAME = CGASCROL.ASM
  17. ;*
  18. ;* DESCRIPTIVE NAME = CGA Buffer Scroll Routines 
  19. ;*
  20. ;*
  21. ;* VERSION      V2.0
  22. ;*
  23. ;* DATE         
  24. ;*
  25. ;* DESCRIPTION  BUFFERUPDATE scroll routines  
  26. ;*
  27. ;* FUNCTIONS    ScrollUp        
  28. ;*              ScrollDown
  29. ;*              ScrollLeft
  30. ;*              ScrollRight
  31. ;*              ValidateScrollParms
  32. ;*              GetScrollByteCount
  33. ;*              GetLineSkipByteCount
  34. ;*              GetLVB_PVB_Cell
  35. ;*
  36. ;* NOTES        NONE
  37. ;*             
  38. ;* STRUCTURES   NONE
  39. ;*
  40. ;* EXTERNAL REFERENCES   _MOVSW, _STOSW   
  41. ;*
  42. ;* EXTERNAL FUNCTIONS
  43. ;*
  44. ;*              NONE
  45. ;*
  46. ;* CHANGE ACTIVIY =
  47. ;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
  48. ;*   --------  ---------- -----   --------------------------------------
  49. ;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
  50. ;****************************************************************************/
  51.  
  52.         .286c                                     ; 286 protect mode instructions
  53.  
  54.         .xlist
  55.         INCLUDE struc.inc                         ; Structure macro
  56.         INCLUDE error2.inc                        ; Subsystem error equates
  57.         INCLUDE vdhstruc.inc                      ; Buffer update data structures
  58.         INCLUDE vdhequ.inc                        ; Buffer update equates
  59.         .list
  60.  
  61.         EXTRN   _MOVSW  : FAR                     ; Move words from DS:SI to ES:DI
  62.         EXTRN   _STOSW  : FAR                     ; Store words from AX to ES:DI
  63.  
  64.  
  65. R2CSEG  SEGMENT WORD    PUBLIC 'CODE'
  66.         ASSUME  CS:R2CSEG,DS:NOTHING,ES:NOTHING
  67.  
  68. ;/****************************************************************************
  69. ;*                                                    
  70. ;* SUBROUTINE NAME:     ScrollUp                     
  71. ;*                                                    
  72. ;* DESCRIPTIVE NAME:    Video device handler scroll up routine  
  73. ;*                                                    
  74. ;* FUNCTION:    Process scroll up sub-function      
  75. ;*              Scrolls a portion of the PVB, LVB up a specified 
  76. ;*              number of times and then fill the vacant portion 
  77. ;*              with the user specified cell.       
  78. ;*                                                    
  79. ;* ENTRY POINT: ScrollUp                              
  80. ;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte   
  81. ;*                                                    
  82. ;* INPUT:                                             
  83. ;*                                                    
  84. ;* AX = 0                                             
  85. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  86. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  87. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  88. ;*                                                    
  89. ;* PARAMETER BLOCK FORMAT:                            
  90. ;*                                                    
  91. ;*   SIZE   DESCRIPTION                               
  92. ;*   ----   -----------                               
  93. ;*                                                    
  94. ;*   WORD   Parameter length                          
  95. ;*   WORD   Flags                                      (target buffer - LVB, PVB) 
  96. ;*   DWORD  Application data address                 
  97. ;*   DWORD  Application data2 address (cell to be used to fill void) 
  98. ;*   WORD   Index (3)                                 
  99. ;*   WORD   Starting row                               (top row)    
  100. ;*   WORD   Starting column                            (left column)   
  101. ;*   WORD   Secondary row                              (bottom row)   
  102. ;*   WORD   Secondary column                           (right column)   
  103. ;*   WORD   RepeatFactor                               (# of times to scroll)
  104. ;*   WORD   LogicalBufSel                             
  105. ;*                                                    
  106. ;* OUTPUT:                                            
  107. ;*                                                    
  108. ;* EXIT-NORMAL: AX = 0                                
  109. ;*                                                    
  110. ;* EXIT-ERROR:  AX = ValidateScrollParms            
  111. ;*                                                    
  112. ;* EFFECTS:     All                                   
  113. ;*                                                    
  114. ;* INTERNAL REFERENCES: ValidateScrollParms,        
  115. ;*                                                    
  116. ;* EXTERNAL REFERENCES: _MOVSW, _STOSW               
  117. ;*                                                    
  118. ;****************************************************************************/
  119.  
  120.         PUBLIC  ScrollUp
  121. ScrollUp        PROC    NEAR
  122.  
  123. ;/*
  124. ;**   Validate input row, column parameters.  The carry flag is used 
  125. ;**   to indicate whether an abnormal condition occured. On exit the 
  126. ;**   following registers are also setup if the carry flag is not set: 
  127. ;**       AX, [bp].TopRow    = Adjusted starting row   
  128. ;**       BX, [bp].BottomRow = Adjusted ending row   
  129. ;**       CX, [bp].LeftCol   = Adjusted starting column   
  130. ;**       DX, [bp].RightCol  = Adjusted ending column   
  131. ;*/
  132.  
  133.         call    ValidateScrollParms                ; Validate row, column values
  134.         .if     <nc>    NEAR                       ; Continue?
  135.  
  136. ;/*
  137. ;**  Locate the offset to the upper right hand corner of the target
  138. ;**  rectangle to be scrolled.  This is achieved by taking the TopRow
  139. ;**  value, multiply it by the screen width and then add LeftCol value
  140. ;**  to the result.
  141. ;*/
  142.  
  143.             mul     es:[di].TextCols               ; Target offset = (TopRow
  144.             add     ax, cx                         ;   * screen columns
  145.             add     ax, ax                         ;   + LeftCol) * 2
  146.             push    ax                             ; Save Target offset
  147.  
  148. ;/*
  149. ;**  Use the scroll scale factor to calculate the total number of bytes
  150. ;**  neccessary to determine where the source offset is located.
  151. ;**  GetScrollByteCount returns this value in AX.
  152. ;*/
  153.  
  154.             call    GetScrollByteCount             ; AX = byte count
  155.  
  156.             pop     bx                             ; BX = Target offset
  157.  
  158. ;/*
  159. ;**  Determine the source offset by taking the byte count obtained
  160. ;**  above and add to it the target buffer offset.
  161. ;*/
  162.  
  163.             add     ax, bx                         ; Source offset = Target offset
  164.             push    ax                             ;   + (# of lines to scroll *
  165.                                                    ;   screen columns * 2)
  166.  
  167. ;/*
  168. ;**  Locate the offset to the bottom right hand corner of the target
  169. ;**  rectangle to be scrolled.  This is achieved by taking the BottomRow
  170. ;**  value, multiply it by the screen width and then add RightCol value
  171. ;**  to the result.
  172. ;*/
  173.  
  174.             mov     ax, es:[di].TextCols           ; End offset = (BottomRow *
  175.             mul     [bp].BottomRow                 ;   screen columns + RightCol
  176.             add     ax, [bp].RightCol              ;   + 1) * 2
  177.             inc     ax                             ; 
  178.             add     ax, ax                         ; 
  179.             mov     dx, ax                         ; DX = End offset
  180.  
  181. ;/*
  182. ;**  Calculate the number of bytes to skip between the end of one line 
  183. ;**  and the beginning of the next line.  This is achieved by taking 
  184. ;**  the screen width and subtract it by the number of columns between 
  185. ;**  the RightCol and LeftCol and then multiply it by 2.   
  186. ;**  GetLineSkipByteCount returns this value in CX.   
  187. ;*/
  188.  
  189.             call    GetLineSkipByteCount           ; CX = # of bytes to skip
  190.  
  191. ;/*
  192. ;**  Setup source and destination selectors.  If both LVB and PVB are
  193. ;**  selected for update then all changes will go to the LVB first
  194. ;**  before transfering the changes to the PVB.   GetLVB_PVB_Cell will
  195. ;**  also return the cell in AX.
  196. ;*/
  197.  
  198.             call    GetLVB_PVB_Cell                ; AX = cell
  199.                                                    ; BX = Target offset
  200.                                                    ; DX = End offset
  201.             pop     si                             ; DS:SI -> Source buffer
  202.             mov     di, bx                         ; ES:DI -> Target buffer
  203.  
  204. ;/*
  205. ;**  If each line within the target rectangle to be scrolled occupies
  206. ;**  the entire width of the screen then a contiguous block move will
  207. ;**  be opted.
  208. ;**  For non-contiguous lines, scroll up is done by moving each line up
  209. ;**  one at a time until the requested number of lines are scrolled.
  210. ;*/
  211.  
  212.             .if     <ncxz>                         ; Non-contiguous lines?
  213.                 push    bx                         ; Save Target offset
  214.                 push    ax                         ; Save cell
  215.                 mov     ax, [bp].SkipLength        ; AX = skip length
  216.                 mov     bx, [bp].Retrace           ; Setup retrace indicator
  217.                 .if     <si b dx>                  ; Any to scroll?
  218.                     .repeat                        ; 
  219.                         mov                      cx, [bp].LineLength
  220.                         call                     _MOVSW  ; Copy one line
  221.                         add                      si, ax  ; Advance to start of
  222.                         add                      di, ax  ;   next line
  223.                     .until  <si ae dx>             ; More to scroll?
  224.                 .endif                             ; 
  225.                 mov     si, [bp].SkipLength        ; SI = Skip length
  226.                 pop     ax                         ; AX = cell
  227.                 .repeat                            ; 
  228.                     mov     cx, [bp].LineLength ; CX = line length
  229.                     call    _STOSW                 ; Fill line with cell
  230.                     add     di, si                 ; Advance to start of next line
  231.                 .until  <di ae dx>                 ; More lines to fill?
  232.                 pop     di                         ; DI = Target offset
  233.                                                    ; DX = End offset
  234. ;/*
  235. ;**  If PVB update is also required then transfer the updated rectangle
  236. ;**  from the LVB to the corresponding location in the PVB.
  237. ;*/
  238.  
  239.                 .if     <[bp].PVB_Sel a cx>        ; Required update to PVB?
  240.                     mov     es, [bp].PVB_Sel       ; ES:DI -> PVB buffer
  241.                     mov     ax, [bp].SkipLength    ; AX = skip length
  242.                     mov     si, di                 ; DS:SI -> LVB buffer
  243.                     inc     bx                     ; Retrace wait required
  244.                     .while  <di b dx>              ; More to copy?
  245.                         mov                      cx, [bp].LineLength
  246.                         call                     _MOVSW  ; Copy a line from LVB to PVB
  247.                         add                      si, ax  ; Advance to start of
  248.                         add                      di, ax  ;   next line
  249.                     .endwhile                      ; 
  250.                 .endif                             ; 
  251.             .else                                  ; Non contiguous lines!
  252.                                                    ; DX = End offset
  253.                 push    di                         ; Save target offset
  254.                 mov     cx, dx                     ; CX = (End offset - Source
  255.                 sub     cx, si                     ;      offset) / 2
  256.                 shr     cx, 1                      ; CX = transfer count
  257.                 mov     bx, [bp].Retrace           ; Pass retrace indicator
  258.                 .if     <ncxz>                     ; Source = Destination?
  259.                     call    _MOVSW                 ; Block copy
  260.                 .endif                             ; 
  261.                 mov     cx, dx                     ; CX = (End offset - current
  262.                 sub     cx, di                     ;      Target offset) / 2
  263.                 shr     cx, 1                      ; CX = cell transfer count
  264.                 call    _STOSW                     ; Copy cell to remaining lines
  265.  
  266. ;/*
  267. ;**  If PVB update is also required then transfer the updated rectangle
  268. ;**  from the LVB to the corresponding location in the PVB.
  269. ;*/
  270.  
  271.                 pop     di                         ; DI = target offset
  272.                 .if     <[bp].PVB_Sel a cx>        ; Required update to PVB?
  273.                     mov     es, [bp].PVB_Sel       ; ES:DI -> PVB buffer
  274.                     mov     si, di                 ; DS:SI -> LVB buffer
  275.                     mov     cx, dx                 ; CX = End offset - Target
  276.                     sub     cx, di                 ;      offset) / 2
  277.                     shr     cx, 1                  ; CX = entire rectangle
  278.                     inc     bx                     ; Retrace wait required
  279.                     call    _MOVSW                 ; Copy rectangle to PVB
  280.                 .endif                             ; 
  281.             .endif                                 ; 
  282.             sub     ax, ax                         ; Clear return code
  283.         .endif                                     ; 
  284.         ret                                        ; 
  285.  
  286. ScrollUp        ENDP
  287.  
  288. ;/****************************************************************************
  289. ;*                                                    
  290. ;* SUBROUTINE NAME:     ScrollDown                   
  291. ;*                                                    
  292. ;* DESCRIPTIVE NAME:    Video device handler scroll down routine 
  293. ;*                                                    
  294. ;* FUNCTION:    Process scroll down sub-function   
  295. ;*              Scrolls a portion of the PVB, LVB down a specified 
  296. ;*              number of times and then fill the vacant portion 
  297. ;*              with the user specified cell.       
  298. ;*                                                    
  299. ;* ENTRY POINT: ScrollDown                            
  300. ;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte   
  301. ;*                                                    
  302. ;* INPUT:                                             
  303. ;*                                                    
  304. ;* AX = 0                                             
  305. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  306. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  307. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  308. ;*                                                    
  309. ;* PARAMETER BLOCK FORMAT:                            
  310. ;*                                                    
  311. ;*   SIZE   DESCRIPTION                               
  312. ;*   ----   -----------                               
  313. ;*                                                    
  314. ;*   WORD   Parameter length                          
  315. ;*   WORD   Flags                                      (target buffer - LVB, PVB) 
  316. ;*   DWORD  Application data address                 
  317. ;*   DWORD  Application data2 address (cell to be used to fill void) 
  318. ;*   WORD   Index (4)                                 
  319. ;*   WORD   Starting row                               (top row)    
  320. ;*   WORD   Starting column                            (left column)   
  321. ;*   WORD   Secondary row                              (bottom row)   
  322. ;*   WORD   Secondary column                           (right column)   
  323. ;*   WORD   RepeatFactor                               (# of times to scroll)  
  324. ;*   WORD   LogicalBufSel                             
  325. ;*                                                    
  326. ;* OUTPUT:                                            
  327. ;*                                                    
  328. ;* EXIT-NORMAL: AX = 0                                
  329. ;*                                                    
  330. ;* EXIT-ERROR:  AX = ValidateScrollParms            
  331. ;*                                                    
  332. ;* EFFECTS:     All                                   
  333. ;*                                                    
  334. ;* INTERNAL REFERENCES: ValidateScrollParms,        
  335. ;*                                                    
  336. ;* EXTERNAL REFERENCES: _MOVSW, _STOSW               
  337. ;*                                                    
  338. ;****************************************************************************/
  339.  
  340.         PUBLIC  ScrollDown
  341. ScrollDown      PROC    NEAR
  342.  
  343. ;/*
  344. ;** Validate input row, column parameters.  The carry flag is used 
  345. ;** to indicate whether an abnormal condition occured. On exit the 
  346. ;** following registers are also setup if the carry flag is not set: 
  347. ;**     AX, [bp].TopRow    = Adjusted starting row   
  348. ;**     BX, [bp].BottomRow = Adjusted ending row   
  349. ;**     CX, [bp].LeftCol   = Adjusted starting column   
  350. ;**     DX, [bp].RightCol  = Adjusted ending column   
  351. ;*/
  352.  
  353.         call    ValidateScrollParms                ; Validate row, column values
  354.         .if     <nc>    NEAR                       ; Continue?
  355.  
  356. ;/*
  357. ;**  Locate the offset to the bottom right hand corner of the target
  358. ;**  rectangle to be scrolled.  This is achieved by taking the BottomRow
  359. ;**  value, multiply it by the screen width and then add RightCol value
  360. ;**  to the result.
  361. ;*/
  362.  
  363.             mov     ax, es:[di].TextCols           ; Target offset = (BottomRow
  364.             mul     bx                             ;   * screen columns +
  365.             add     ax, [bp].RightCol              ;   right column) * 2
  366.             add     ax, ax                         ; 
  367.             push    ax                             ; Save Target offset
  368.  
  369. ;/*
  370. ;**  Use the scroll scale factor to calculate the total number of bytes
  371. ;**  neccessary to determine where the source offset is located.
  372. ;**  GetScrollByteCount returns this value in AX.
  373. ;*/
  374.  
  375.             call    GetScrollByteCount             ; AX = byte count
  376.  
  377.             pop     bx                             ; BX = Target offset
  378.  
  379. ;/*
  380. ;**  Determine the source offset by taking the byte count obtained
  381. ;**  above and subtract from the target buffer offset.
  382. ;*/
  383.  
  384.             mov     dx, bx                         ; Source offset = Target offset
  385.             sub     dx, ax                         ;   - (# of lines to scroll *
  386.                                                    ;   screen columns * 2)
  387.             push    dx                             ; Save Source offset
  388.  
  389. ;/*
  390. ;**  Locate the offset to the top left hand corner of the target
  391. ;**  rectangle to be scrolled.  This is achieved by taking the TopRow
  392. ;**  value, multiply it by the screen width and then add LeftCol value
  393. ;**  to the result.
  394. ;*/
  395.  
  396.             mov     ax, es:[di].TextCols           ; End offset = (TopRow *
  397.             mul     [bp].TopRow                    ;   screen columns + LeftCol
  398.             add     ax, [bp].LeftCol               ;   -1) * 2
  399.             dec     ax                             ; 
  400.             add     ax, ax                         ; 
  401.             mov     dx, ax                         ; DX = End offset
  402.  
  403. ;/*
  404. ;**  Calculate the number of bytes to skip between the end of one line
  405. ;**  and the beginning of the next line.  This is achieved by taking
  406. ;**  the screen width and subtract it by the number of columns between
  407. ;**  the RightCol and LeftCol and then multiply it by 2.
  408. ;**  GetLineSkipByteCount returns this value in CX.
  409. ;*/
  410.  
  411.             call    GetLineSkipByteCount           ; CX = # of bytes to skip
  412.  
  413. ;/*
  414. ;**  Setup source and destination selectors.  If both LVB and PVB are
  415. ;**  selected for update then all changes will go to the LVB first
  416. ;**  before transfering the changes to the PVB.   GetLVB_PVB_Cell will
  417. ;**  also return the cell in AX.
  418. ;*/
  419.  
  420.             call    GetLVB_PVB_Cell                ; AX = cell
  421.                                                    ; BX = Target offset
  422.                                                    ; DX = End offset
  423.             pop     si                             ; DS:SI -> Source buffer
  424.             mov     di, bx                         ; ES:DI -> Target buffer
  425.             std                                    ; Transfer from right to
  426.                                                    ;   left, bottom up
  427. ;/*
  428. ;**  If each line within the target rectangle to be scrolled occupies
  429. ;**  the entire width of the screen then a contiguous block move will
  430. ;**  be opted.
  431. ;**  For non-contiguous lines, scroll down is done by moving each line
  432. ;**  down one at a time until the requested number of lines are scrolled.
  433. ;*/
  434.  
  435.             .if     <ncxz>                         ; Non-contiguous lines?
  436.                 mov     dx, [bp].BottomRow         ; DX = row count between
  437.                 sub     dx, [bp].TopRow            ;      TopRow and BottomRow
  438.                 inc     dx                         ; 
  439.                 push    dx                         ; Save total row count
  440.                 push    di                         ; Save Target offset
  441.                 push    ax                         ; Save cell
  442.                 sub     dx, [bp].ScrollCount       ; DX = # of row to move down
  443.                 mov     ax, [bp].SkipLength        ; AX = skip length
  444.                 mov     bx, [bp].Retrace           ; Setup retrace indicator
  445.                 .if     <nonzero dx>               ; Any lines to scroll?
  446.                     .repeat                        ; 
  447.                         mov                      cx, [bp].LineLength
  448.                         call                     _MOVSW  ; Copy one line
  449.                         sub                      si, ax  ; Advance to start of
  450.                         sub                      di, ax  ;   next line
  451.                         dec                      dx  ; Adjust row count
  452.                     .until  <z>                    ; More lines to scroll?
  453.                 .endif                             ; 
  454.                 mov     si, ax                     ; SI = skip length
  455.                 pop     ax                         ; AX = cell
  456.                 mov     dx, [bp].ScrollCount       ; DX = remaining row count
  457.                 .repeat                            ; 
  458.                     mov     cx, [bp].LineLength    ; CX = line length
  459.                     call    _STOSW                 ; Fill line with cell
  460.                     sub     di, si                 ; Advance to start of next line
  461.                     dec     dx                     ; Adjust row count
  462.                 .until  <z>                        ; More lines to fill?
  463.                 pop     di                         ; DI = Target offset
  464.                 pop     dx                         ; DX = total row count
  465. ;/*
  466. ;**  If PVB update is also required then transfer the updated rectangle
  467. ;**  from the LVB to the corresponding location in the PVB.
  468. ;*/
  469.  
  470.                 .if     <[bp].PVB_Sel a 0>         ; Required update to PVB?
  471.                     mov     es, [bp].PVB_Sel       ; ES:DI -> PVB buffer
  472.                     mov     ax, si                 ; AX = skip length
  473.                     mov     si, di                 ; DS:SI -> LVB buffer
  474.                     inc     bx                     ; Retrace wait required
  475.                     .repeat                        ; 
  476.                         mov                      cx, [bp].LineLength
  477.                         call                     _MOVSW  ; Copy a line to PVB
  478.                         sub                      si, ax  ; Advance to start of
  479.                         sub                      di, ax  ;   next line
  480.                         dec                      dx  ; Adjust row count
  481.                     .until  <z>                    ; More lines to copy?
  482.                 .endif                             ; 
  483.             .else                                  ; Non contiguous lines!
  484.                                                    ; DX = End offset
  485.                 push    di                         ; Save Target offset
  486.                 push    dx                         ; Save End offset
  487.                 mov     cx, si                     ; CX = (Source offset -
  488.                 sub     cx, dx                     ;      End offset) / 2
  489.                 shr     cx, 1                      ; CX = transfer count
  490.                 mov     bx, [bp].Retrace           ; Setup retrace indicator
  491.                 .if     <ncxz>                     ; Source = destination?
  492.                     call    _MOVSW                 ; Block copy
  493.                 .endif                             ; 
  494.                 pop     dx                         ; DX = End offset
  495.                 mov     cx, di                     ; CX = (current destination
  496.                 sub     cx, dx                     ;      offset - End offset) / 2
  497.                 shr     cx, 1                      ; 
  498.                 call    _STOSW                     ; Copy cell to remaining lines
  499. ;/*
  500. ;**  If PVB update is also required then transfer the updated rectangle
  501. ;**  from the LVB to the corresponding location in the PVB.
  502. ;*/
  503.  
  504.                 pop     di                         ; DI = Target offset
  505.                 .if     <[bp].PVB_Sel a cx>        ; Required update to PVB?
  506.                     mov     es, [bp].PVB_Sel       ; 
  507.                     mov     si, di                 ; DS:SI -> LVB buffer
  508.                     mov     cx, di                 ; CX = (Target offset - End
  509.                     sub     cx, dx                 ;      offset) / 2
  510.                     shr     cx, 1                  ; 
  511.                     inc     bx                     ; Retrace wait required
  512.                     call    _MOVSW                 ; Copy rectangle to PVB
  513.                 .endif                             ; 
  514.             .endif                                 ; 
  515.             cld                                    ; 
  516.             sub     ax, ax                         ; Clear return code
  517.         .endif                                     ; 
  518.         ret                                        ; 
  519.  
  520. ScrollDown      ENDP
  521.  
  522. ;/****************************************************************************
  523. ;*                                                    
  524. ;* SUBROUTINE NAME:     ScrollLeft                   
  525. ;*                                                    
  526. ;* DESCRIPTIVE NAME:    Video device handler scroll left routine 
  527. ;*                                                    
  528. ;* FUNCTION:    Process scroll left sub-function   
  529. ;*              Scrolls a portion of the PVB, LVB left a specified 
  530. ;*              number of times and then fill the vacant portion 
  531. ;*              with the user specified cell.      
  532. ;*                                                   
  533. ;* ENTRY POINT: ScrollLeft                           
  534. ;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte  
  535. ;*                                                   
  536. ;* INPUT:                                            
  537. ;*                                                   
  538. ;* AX = 0                                            
  539. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
  540. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM)
  541. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM)
  542. ;*                                                   
  543. ;* PARAMETER BLOCK FORMAT:                            
  544. ;*                                                    
  545. ;*   SIZE   DESCRIPTION                               
  546. ;*   ----   -----------                               
  547. ;*                                                    
  548. ;*   WORD   Parameter length                          
  549. ;*   WORD   Flags                                      (target buffer - LVB, PVB) 
  550. ;*   DWORD  Application data address                 
  551. ;*   DWORD  Application data2 address (cell to be used to fill void) 
  552. ;*   WORD   Index (5)                                 
  553. ;*   WORD   Starting row                               (top row)    
  554. ;*   WORD   Starting column                            (left column)   
  555. ;*   WORD   Secondary row                              (bottom row)   
  556. ;*   WORD   Secondary column                           (right column)   
  557. ;*   WORD   RepeatFactor                               (# of times to scroll)  
  558. ;*   WORD   LogicalBufSel                             
  559. ;*                                                    
  560. ;* OUTPUT:                                            
  561. ;*                                                    
  562. ;* EXIT-NORMAL: AX = 0                                
  563. ;*                                                    
  564. ;* EXIT-ERROR:  AX = ValidateScrollParms            
  565. ;*                                                    
  566. ;* EFFECTS:     All                                   
  567. ;*                                                    
  568. ;* INTERNAL REFERENCES: ValidateScrollParms,        
  569. ;*                                                    
  570. ;* EXTERNAL REFERENCES: _MOVSW, _STOSW               
  571. ;*                                                    
  572. ;****************************************************************************/
  573.  
  574.         PUBLIC  ScrollLeft
  575. ScrollLeft      PROC    NEAR
  576.  
  577. ;/*
  578. ;**  Validate input row, column parameters.  The carry flag is used 
  579. ;**  to indicate whether an abnormal condition occured. On exit the 
  580. ;**  following registers are also setup if the carry flag is not set: 
  581. ;**      AX, [bp].TopRow    = Adjusted starting row   
  582. ;**      BX, [bp].BottomRow = Adjusted ending row   
  583. ;**      CX, [bp].LeftCol   = Adjusted starting column   
  584. ;**      DX, [bp].RightCol  = Adjusted ending column   
  585. ;*/
  586.  
  587.         call    ValidateScrollParms                ; Validate row, column values
  588.         .if     <nc>    NEAR                       ; Continue?
  589.  
  590. ;/*
  591. ;**  Locate the offset to the upper right hand corner of the target
  592. ;**  rectangle to be scrolled.  This is achieved by taking the TopRow
  593. ;**  value, multiply it by the screen width and then add LeftCol value
  594. ;**  to the result.
  595. ;*/
  596.  
  597.             mul     es:[di].TextCols               ; Target offset = (TopRow
  598.             add     ax, cx                         ;   * screen columns
  599.             add     ax, ax                         ;   + LeftCol) * 2
  600.             push    ax                             ; Save Target offset
  601.  
  602. ;/*
  603. ;**  Scroll left is accomplished by moving each line left starting from
  604. ;**  a source location within the same line.  The source location is
  605. ;**  obtained by advancing from the target location N cells to the right
  606. ;**  where each advancement of a cell represents one scroll factor to
  607. ;**  the left.
  608. ;*/
  609.  
  610.             mov     dx, ax                         ; DX = Source offset
  611.             mov     ax, [bp].RightCol              ; AX = column count between
  612.             sub     ax, [bp].LeftCol               ;      RightCol and LeftCol
  613.             inc     ax                             ; 
  614.             mov     cx, ax                         ; CX = column count
  615.             .if     <cx a [si].RepeatFactor>       ; Column count > scroll count?
  616.                 mov     ax, [si].RepeatFactor      ; Source offset = N cells to
  617.                 add     dx, ax                     ;   the right of the target
  618.                 add     dx, ax                     ;   location
  619.             .endif                                 ; 
  620.             push    dx                             ; Save Source offset
  621.             mov     [bp].ScrollCount, ax           ; Column count < scroll count
  622.             sub     cx, ax                         ; Line length = column count -
  623.             mov     [bp].LineLength, cx            ;  scroll count
  624.  
  625.             sub     ax, es:[di].TextCols           ; AX = # of bytes to skip
  626.             neg     ax                             ;      between lines
  627.             sub     ax, cx                         ; 
  628.             add     ax, ax                         ; 
  629.             mov     [bp].SkipLength, ax            ; 
  630.  
  631.             mov     dx, [bp].ScrollCount           ; DX = adjustment byte count to
  632.             shl     dx, 1                          ;      compensate for cell fill
  633.  
  634.             mov     cx, [bp].BottomRow             ; CX = # of rows between
  635.             sub     cx, [bp].TopRow                ;      TopRow and BottomRow
  636.             inc     cx                             ; 
  637.  
  638. ;/*
  639. ;**  Setup source and destination selectors.  If both LVB and PVB are
  640. ;**  selected for update then all changes will go to the LVB first
  641. ;**  before transfering the changes to the PVB.   GetLVB_PVB_Cell will
  642. ;**  also return the cell in AX.
  643. ;*/
  644.  
  645.             call    GetLVB_PVB_Cell                ; AX = cell
  646.  
  647.             pop     si                             ; DS:SI -> Source buffer
  648.             pop     di                             ; DS:SI -> Target buffer
  649.             push    di                             ; Save Target offset
  650.             push    cx                             ; Save total row count
  651.  
  652.             mov     bx, [bp].Retrace               ; Setup retrace indicator
  653.             .repeat                                ; 
  654.                 push    cx                         ; Save current row count
  655.                 mov     cx, [bp].LineLength        ; CX = line length
  656.                 .if     <ncxz>                     ; Source = destination?
  657.                     call    _MOVSW                 ; Shift line left
  658.                 .endif                             ; 
  659.                 mov     cx, [bp].ScrollCount       ; CX = cell count
  660.                 call    _STOSW                     ; Fill N cells
  661.                 add     si, dx                     ; Account for cells filled
  662.                 add     si, [bp].SkipLength        ; Advance to start of
  663.                 add     di, [bp].SkipLength        ;   next line
  664.                 pop     cx                         ; Restore current row count
  665.             .loop                                  ; 
  666.             pop     cx                             ; CX = total row count
  667.             pop     di                             ; DI = Target offset
  668.                                                    ; DX = cell adjustment byte
  669.                                                    ;      count
  670. ;/*
  671. ;**  If PVB update is also required then transfer the updated rectangle
  672. ;**  from the LVB to the corresponding location in the PVB.
  673. ;*/
  674.  
  675.             .if     <[bp].PVB_Sel a 0>             ; Required update to PVB?
  676.                 mov     es, [bp].PVB_Sel           ; ES:DI -> PVB buffer
  677.                 mov     si, di                     ; DS:SI -> LVB buffer
  678.                 shr     dx, 1                      ; Word align cell byte count
  679.                 add     [bp].LineLength, dx        ; Gross line length
  680.                 mov     dx, [bp].SkipLength        ; 
  681.                 inc     bx                         ; Retrace wait required
  682.                 .repeat                            ; 
  683.                     push    cx                     ; Save current row count
  684.                     mov     cx, [bp].LineLength    ; CX = line length
  685.                     call    _MOVSW                 ; Copy a line to PVB
  686.                     add     si, dx                 ; Skip to next line
  687.                     add     di, dx                 ; 
  688.                     pop     cx                     ; Restore current row count
  689.                 .loop                              ; 
  690.             .endif                                 ; 
  691.             sub     ax, ax                         ; Clear return code
  692.         .endif                                     ; 
  693.         ret                                        ; 
  694.  
  695. ScrollLeft      ENDP
  696.  
  697. ;/****************************************************************************
  698. ;*                                                    
  699. ;* SUBROUTINE NAME:     ScrollRight                  
  700. ;*                                                    
  701. ;* DESCRIPTIVE NAME:    Video device handler scroll right routine 
  702. ;*                                                    
  703. ;* FUNCTION:    Process scroll right sub-function   
  704. ;*              Scrolls a portion of the PVB, LVB right to a specified 
  705. ;*              number of times and then fill the vacant portion with 
  706. ;*              the user specified cell.            
  707. ;*                                                    
  708. ;* ENTRY POINT: ScrollRight                           
  709. ;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte   
  710. ;*                                                    
  711. ;* INPUT:                                             
  712. ;*                                                    
  713. ;* AX = 0                                             
  714. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  715. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  716. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  717. ;*                                                    
  718. ;* PARAMETER BLOCK FORMAT:                            
  719. ;*                                                    
  720. ;*   SIZE   DESCRIPTION                               
  721. ;*   ----   -----------                               
  722. ;*                                                    
  723. ;*   WORD   Parameter length                          
  724. ;*   WORD   Flags                                      (target buffer - LVB, PVB) 
  725. ;*   DWORD  Application data address                 
  726. ;*   DWORD  Application data2 address (cell to be used to fill void) 
  727. ;*   WORD   Index (6)                                 
  728. ;*   WORD   Starting row                               (top row)    
  729. ;*   WORD   Starting column                            (left column)   
  730. ;*   WORD   Secondary row                              (bottom row)   
  731. ;*   WORD   Secondary column                           (right column)   
  732. ;*   WORD   RepeatFactor                               (# of times to scroll)  
  733. ;*   WORD   LogicalBufSel                             
  734. ;*                                                    
  735. ;* OUTPUT:                                            
  736. ;*                                                    
  737. ;* EXIT-NORMAL: AX = 0                                
  738. ;*                                                    
  739. ;* EXIT-ERROR:  AX = ValidateScrollParms            
  740. ;*                                                    
  741. ;* EFFECTS:     All                                   
  742. ;*                                                    
  743. ;* INTERNAL REFERENCES: ValidateScrollParms,        
  744. ;*                                                    
  745. ;* EXTERNAL REFERENCES: _MOVSW, _STOSW               
  746. ;*                                                    
  747. ;****************************************************************************/
  748.  
  749.         PUBLIC  ScrollRight
  750. ScrollRight     PROC    NEAR
  751.  
  752. ;/*
  753. ;**   Validate input row, column parameters.  The carry flag is used 
  754. ;**   to indicate whether an abnormal condition occured. On exit the 
  755. ;**   following registers are also setup if the carry flag is not set: 
  756. ;**       AX, [bp].TopRow    = Adjusted starting row   
  757. ;**       BX, [bp].BottomRow = Adjusted ending row   
  758. ;**       CX, [bp].LeftCol   = Adjusted starting column   
  759. ;**       DX, [bp].RightCol  = Adjusted ending column   
  760. ;*/
  761.  
  762.         call    ValidateScrollParms                ; Validate row, column values
  763.         .if     <nc>    NEAR                       ; Continue?
  764.  
  765. ;/*
  766. ;**  Locate the offset to the bottom right hand corner of the target
  767. ;**  rectangle to be scrolled.  This is achieved by taking the BottomRow
  768. ;**  value, multiply it by the screen width and then add RightCol value
  769. ;**  to the result.
  770. ;*/
  771.  
  772.             mov     ax, es:[di].TextCols           ; Target offset = (BottomRow
  773.             mul     bx                             ;   * screen columns +
  774.             add     ax, [bp].RightCol              ;   RightCol) * 2
  775.             add     ax, ax                         ; 
  776.             push    ax                             ; Save Target offset
  777.  
  778. ;/*
  779. ;**  Scroll right is accomplished by moving each line right starting
  780. ;**  from a source location within the same line.  The source location
  781. ;**  is obtained by descending from the target location N cells to the
  782. ;**  left where each descending movement of a cell represents one scroll
  783. ;**  factor to the right.
  784. ;*/
  785.  
  786.             mov     dx, ax                         ; DX = Source offset
  787.             mov     ax, [bp].RightCol              ; AX = column count between
  788.             sub     ax, [bp].LeftCol               ;      RightCol and LeftCol
  789.             inc     ax                             ; 
  790.             mov     cx, ax                         ; CX = column count
  791.             .if     <cx a [si].RepeatFactor>       ; Column count > scroll count?
  792.                 mov     ax, [si].RepeatFactor      ; Source offset = N cells to
  793.                 sub     dx, ax                     ;   the left of the target
  794.                 sub     dx, ax                     ;   location
  795.             .endif                                 ; 
  796.             push    dx                             ; Save Source offset
  797.             mov     [bp].ScrollCount, ax           ; Column count < scroll count
  798.             sub     cx, ax                         ; Line length = column count -
  799.             mov     [bp].LineLength, cx            ;  scroll count
  800.  
  801.             sub     ax, es:[di].TextCols           ; AX = # of bytes to skip
  802.             neg     ax                             ;      between lines
  803.             sub     ax, cx                         ; 
  804.             add     ax, ax                         ; 
  805.             mov     [bp].SkipLength, ax            ; 
  806.  
  807.             mov     dx, [bp].ScrollCount           ; DX = adjustment byte count to
  808.             shl     dx, 1                          ;      compensate for cell fill
  809.  
  810.             mov     cx, [bp].BottomRow             ; CX = row count between
  811.             sub     cx, [bp].TopRow                ;      TopRow and BottomRow
  812.             inc     cx                             ; 
  813.  
  814. ;/*
  815. ;**  Setup source and destination selectors.  If both LVB and PVB are
  816. ;**  selected for update then all changes will go to the LVB first
  817. ;**  before transfering the changes to the PVB.   GetLVB_PVB_Cell will
  818. ;**  also return the cell in AX.
  819. ;*/
  820.  
  821.             call    GetLVB_PVB_Cell                ; AX = cell
  822.  
  823.             pop     si                             ; DS:SI -> Source buffer
  824.             pop     di                             ; ES:DI -> Target buffer
  825.             push    di                             ; Save Target offset
  826.             push    cx                             ; Save total row count
  827.  
  828.             mov     bx, [bp].Retrace               ; Setup retrace indicator
  829.             std                                    ; Transfer from right to
  830.                                                    ;   left, bottom up
  831.             .repeat                                ; 
  832.                 push    cx                         ; Save current row count
  833.                 mov     cx, [bp].LineLength        ; CX = line length
  834.                 .if     <ncxz>                     ; Source = destination?
  835.                     call    _MOVSW                 ; Shift line right
  836.                 .endif                             ; 
  837.                 mov     cx, [bp].ScrollCount       ; CX = cell count
  838.                 call    _STOSW                     ; Fill N cells
  839.                 sub     si, dx                     ; Account for cells filled
  840.                 sub     si, [bp].SkipLength        ; Advance to start of
  841.                 sub     di, [bp].SkipLength        ;   next line
  842.                 pop     cx                         ; Restore current row count
  843.             .loop                                  ; 
  844.             pop     cx                             ; CX = total row count
  845.             pop     di                             ; DI = Target offset
  846.                                                    ; DX = cell adjustment byte
  847.                                                    ;      count
  848. ;/*
  849. ;**  If PVB update is also required then transfer the updated rectangle
  850. ;**  from the LVB to the corresponding location in the PVB.
  851. ;*/
  852.  
  853.             .if     <[bp].PVB_Sel a 0>             ; Required update to PVB?
  854.                 mov     es, [bp].PVB_Sel           ; ES:DI -> PVB buffer
  855.                 mov     si, di                     ; DS:SI -> LVB buffer
  856.                 shr     dx, 1                      ; Word align cell byte count
  857.                 add     [bp].LineLength, dx        ; Gross line length
  858.                 mov     dx, [bp].SkipLength        ; 
  859.                 inc     bx                         ; Retrace wait required
  860.                 .repeat                            ; 
  861.                     push    cx                     ; Save current row count
  862.                     mov     cx, [bp].LineLength    ; CX = line length
  863.                     call    _MOVSW                 ; Copy a line to PVB
  864.                     sub     si, dx                 ; Skip to next line
  865.                     sub     di, dx                 ; 
  866.                     pop     cx                     ; Restore current row count
  867.                 .loop                              ; 
  868.             .endif                                 ; 
  869.             sub     ax, ax                         ; Clear return code
  870.             cld                                    ; 
  871.         .endif                                     ; 
  872.         ret                                        ; 
  873.  
  874. ScrollRight     ENDP
  875.  
  876. ;/****************************************************************************
  877. ;*                                                  
  878. ;* SUBROUTINE NAME:     ValidateScrollParms       
  879. ;*                                                  
  880. ;* DESCRIPTIVE NAME:    Video device handler scroll parameter
  881. ;*                      validation procedure      
  882. ;*                                                  
  883. ;* FUNCTION:    Determine whether the row, column parameters given
  884. ;*              are ambiguous.     For example:  ending row is greater
  885. ;*              than starting row or ending column is greater than
  886. ;*              starting column.                   
  887. ;*                                                  
  888. ;* ENTRY POINT: ValidateScrollParms                 
  889. ;*   LINKAGE:   Near Call from ScrollUp, ScrollDown,   
  890. ;*                             ScrollLeft, ScrollRight   
  891. ;*                                                    
  892. ;* INPUT:                                             
  893. ;*                                                    
  894. ;* AX = 0                                             
  895. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  896. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  897. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  898. ;*                                                    
  899. ;* OUTPUT:      AX, [bp].TopRow    = starting row   
  900. ;*              BX, [bp].BottomRow = ending row    
  901. ;*              CX, [bp].LeftCol   = starting column   
  902. ;*              DX, [bp].RightCol  = ending column   
  903. ;*              CY = 1 for invalid parameters or [SI].RepeatCount = 0 
  904. ;*                                                    
  905. ;* EXIT-NORMAL: CY = 0                                
  906. ;*              CY = 1  AND  AX = 0                  
  907. ;*                                                    
  908. ;* EXIT-ERROR:  CY = 1                              
  909. ;*              AX = ERROR_VIO_COL                   
  910. ;*              AX = ERROR_VIO_ROW                   
  911. ;*                                                    
  912. ;* EFFECTS:     AX, BX, CX, DX, CY                   
  913. ;*                                                    
  914. ;* INTERNAL REFERENCES: None                          
  915. ;*                                                    
  916. ;* EXTERNAL REFERENCES: None                          
  917. ;*                                                    
  918. ;****************************************************************************/
  919.  
  920.         PUBLIC  ValidateScrollParms
  921. ValidateScrollParms     PROC                     NEAR
  922.  
  923.         .if     <[si].RepeatFactor a ax>           ; Anything to scroll?
  924.             push    bp                             ; 
  925.  
  926. ;/*
  927. ;**  If either of the starting and ending row value is beyond the
  928. ;**  normalized text resolution of the current display mode then
  929. ;**  convert it to the current maximum row value allowed.
  930. ;*/
  931.  
  932.             mov     bp, es:[di].TextRows           ; Get max row resolution
  933.             dec     bp                             ; Normalize it
  934.             mov     ax, [si].Row                   ; Get input starting row value
  935.             .if     <ax a bp>                      ; Starting row beyond limit?
  936.                 mov     ax, bp                     ; Set it to max allowed
  937.             .endif                                 ; 
  938.             mov     bx, [si].Row2                  ; Get input ending row value
  939.             .if     <bx a bp>                      ; Ending row beyond limit?
  940.                 mov     bx, bp                     ; Set it to max allowed
  941.             .endif                                 ; 
  942.  
  943. ;/*
  944. ;**  If either of the starting and ending column value is beyond the
  945. ;**  normalized text resolution of the current display mode then
  946. ;**  convert it to the current maximum column value allowed.
  947. ;*/
  948.  
  949.             mov     bp, es:[di].TextCols           ; Get max column resolution
  950.             dec     bp                             ; Normalize it
  951.             mov     cx, [si].Col                   ; Get input starting col value
  952.             .if     <cx a bp>                      ; Starting col beyond limit?
  953.                 mov     cx, bp                     ; Set it to max allowed
  954.             .endif                                 ; 
  955.             mov     dx, [si].Col2                  ; Get input ending col value
  956.             .if     <dx a bp>                      ; Ending col beyond limit?
  957.                 mov     dx, bp                     ; Set it to max allowed
  958.             .endif                                 ; 
  959.  
  960.             pop     bp                             ; 
  961.  
  962. ;/*
  963. ;**   Validate input row, column values.  An error is returned if either 
  964. ;**   the ending row value is greater than the starting row value or the 
  965. ;**   the ending column value is greater than the starting column value. 
  966. ;**                                                     
  967. ;**   Notice that the comparison is made in such a way that the carry 
  968. ;**   flag is set when the comparison fails.          
  969. ;*/
  970.  
  971.             .if     <bx ae ax>                     ; Ending row >= starting row?
  972.                 .if     <dx ae cx>                 ; Ending col >= starting col?
  973.                     mov     [bp].TopRow, ax        ; Save the converted input
  974.                     mov     [bp].BottomRow, bx     ;   row, column values
  975.                     mov     [bp].LeftCol, cx       ; 
  976.                     mov     [bp].RightCol, dx      ; Carry flag bit must be clear
  977.                 .else                              ; 
  978.                     mov     ax, ERROR_VIO_COL      ; Carry flag should be set
  979.                 .endif                             ; 
  980.             .else                                  ; 
  981.                 mov     ax, ERROR_VIO_ROW          ; Carry flag shoud be set
  982.             .endif                                 ; 
  983.         .else                                      ; 
  984.             stc                                    ; Force normal exit
  985.         .endif                                     ; 
  986.         ret                                        ; 
  987.  
  988. ValidateScrollParms     ENDP
  989.  
  990. ;/****************************************************************************
  991. ;*                                                    
  992. ;* SUBROUTINE NAME:     GetScrollByteCount          
  993. ;*                                                    
  994. ;* DESCRIPTIVE NAME:    Video device handler get scroll byte count 
  995. ;*                                                    
  996. ;* FUNCTION:    Determine how many lines the caller is intended to 
  997. ;*              scroll up within the rectangle specified and then 
  998. ;*              use this number to calculate the number of bytes 
  999. ;*              it takes from the beginning of the target location 
  1000. ;*              to the start of the source line.   
  1001. ;*                                                    
  1002. ;* ENTRY POINT: GetScrollByteCount                   
  1003. ;*   LINKAGE:   Near Call from ScrollUp, ScrollDown   
  1004. ;*                                                    
  1005. ;* INPUT:                                             
  1006. ;*                                                    
  1007. ;* BX = Bottom row                                    
  1008. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  1009. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  1010. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  1011. ;*                                                    
  1012. ;* OUTPUT:      AX = # of bytes from the beginning of the buffer 
  1013. ;*                   to the start of the first scroll line  
  1014. ;*              [si].RepeatFactor = Actual # of lines to scroll  
  1015. ;*              [bp].ScrollCount  = Actual # of lines to scroll  
  1016. ;*                                                    
  1017. ;* EXIT-NORMAL: None                                  
  1018. ;*                                                    
  1019. ;* EXIT-ERROR:  None                                  
  1020. ;*                                                    
  1021. ;* EFFECTS:     AX, DX                                
  1022. ;*                                                    
  1023. ;* INTERNAL REFERENCES: None                          
  1024. ;*                                                    
  1025. ;* EXTERNAL REFERENCES: None                          
  1026. ;*                                                    
  1027. ;****************************************************************************/
  1028.  
  1029.         PUBLIC  GetScrollByteCount
  1030. GetScrollByteCount      PROC                     NEAR
  1031.         ASSUME  CS:R2CSEG, DS:NOTHING, ES:NOTHING
  1032.  
  1033.         mov     ax, bx                             ; Calculate the number of
  1034.         sub     ax, [bp].TopRow                    ;   rows between top row
  1035.         inc     ax                                 ;   and bottom row
  1036.         .if     <ax b [si].RepeatFactor>           ; Use the user supplied repeat
  1037.             mov     [si].RepeatFactor, ax          ;   factor if it is less than
  1038.         .endif                                     ;   number of rows in the
  1039.         mov     ax, [si].RepeatFactor              ;   target rectangle
  1040.         mov     [bp].ScrollCount, ax               ; Save scroll count on stack
  1041.         mul     es:[di].TextCols                   ; Calculate the total byte
  1042.         add     ax, ax                             ;   count based on the # of
  1043.         ret                                        ;   lines to scroll
  1044.  
  1045. GetScrollByteCount      ENDP
  1046.  
  1047. ;/****************************************************************************
  1048. ;*                                                    
  1049. ;* SUBROUTINE NAME:     GetLineSkipByteCount        
  1050. ;*                                                    
  1051. ;* DESCRIPTIVE NAME:    Video device handler get scroll byte count 
  1052. ;*                                                    
  1053. ;* FUNCTION:    Determine the number of bytes to skip between the 
  1054. ;*              end of one line and the beginning of the next line. 
  1055. ;*                                                    
  1056. ;* ENTRY POINT: GetLineSkipByteCount                 
  1057. ;*   LINKAGE:   Near Call from ScrollUp, ScrollDown   
  1058. ;*                                                    
  1059. ;* INPUT:                                             
  1060. ;*                                                    
  1061. ;* CX = Left column                                   
  1062. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  1063. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  1064. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  1065. ;*                                                    
  1066. ;* OUTPUT:      AX, [bp].LineLength = Actual length in cells for 
  1067. ;*                                                     each line    
  1068. ;*              CX, [bp].SkipLength = # of bytes to skip between 
  1069. ;*                                                     lines    
  1070. ;* EXIT-NORMAL: None                                  
  1071. ;*                                                    
  1072. ;* EXIT-ERROR:  None                                  
  1073. ;*                                                    
  1074. ;* EFFECTS:     AX, CX                                
  1075. ;*                                                    
  1076. ;* INTERNAL REFERENCES: None                          
  1077. ;*                                                    
  1078. ;* EXTERNAL REFERENCES: None                          
  1079. ;*                                                    
  1080. ;****************************************************************************/
  1081.  
  1082.         PUBLIC  GetLineSkipByteCount
  1083. GetLineSkipByteCount    PROC                     NEAR
  1084.         ASSUME  CS:R2CSEG, DS:NOTHING, ES:NOTHING
  1085.  
  1086.         mov     ax, [bp].RightCol                  ; Calculate the number of
  1087.         sub     ax, cx                             ;   columns between right
  1088.         inc     ax                                 ;   column and left column
  1089.         mov     [bp].LineLength, ax                ; Save line length
  1090.         mov     cx, es:[di].Textcols               ; Calculate the number of
  1091.         sub     cx, ax                             ;   bytes to skip between
  1092.         add     cx, cx                             ;   lines
  1093.         mov     [bp].SkipLength, cx                ; CX = bytes to skip between
  1094.         ret                                        ;      lines
  1095.  
  1096. GetLineSkipByteCount    ENDP
  1097.  
  1098. ;/****************************************************************************
  1099. ;*                                                    
  1100. ;* SUBROUTINE NAME:     GetLVB_PVB_Cell             
  1101. ;*                                                    
  1102. ;* DESCRIPTIVE NAME:    Video device handler get LVB, PVB and cell 
  1103. ;*                                                    
  1104. ;* FUNCTION:    Determine which buffer address to use based on  
  1105. ;*              the input flags set.  If the user wishes to  
  1106. ;*              scroll both the LVB and the PVB then the LVB  
  1107. ;*              will be updated first before the PVB is refreshed. 
  1108. ;*                                                    
  1109. ;* ENTRY POINT: GetLVB_PVB_Cell                      
  1110. ;*   LINKAGE:   Near Call from ScrollUp, ScrollDown,   
  1111. ;*                             ScrollLeft, ScrollRight   
  1112. ;*                                                    
  1113. ;* INPUT:                                             
  1114. ;*                                                    
  1115. ;* CX = Left column                                   
  1116. ;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC) 
  1117. ;* DS:SI  --->  Parameter block buffer            (see CGABUFUP.ASM) 
  1118. ;* ES:DI  --->  Mode data in environment buffer (see CGABUFUP.ASM) 
  1119. ;*                                                    
  1120. ;* OUTPUT:      DS = PVB or LVB                      
  1121. ;*              ES = PVB or LVB                      
  1122. ;*              [bp].PVB_Sel = PVB if user requests both LVB & PVB 
  1123. ;*              AX = Cell                             
  1124. ;*                                                    
  1125. ;* EXIT-NORMAL: None                                  
  1126. ;*                                                    
  1127. ;* EXIT-ERROR:  None                                  
  1128. ;*                                                    
  1129. ;* EFFECTS:     AX, SI, DI, DS, ES                   
  1130. ;*                                                    
  1131. ;* INTERNAL REFERENCES: None                          
  1132. ;*                                                    
  1133. ;* EXTERNAL REFERENCES: None                          
  1134. ;*                                                    
  1135. ;****************************************************************************/
  1136.  
  1137.         PUBLIC  GetLVB_PVB_Cell
  1138. GetLVB_PVB_Cell PROC    NEAR
  1139.         ASSUME  CS:R2CSEG, DS:NOTHING, ES:NOTHING
  1140.  
  1141.         mov     di, [bp].PVB_Sel                   ; Assume PVB update
  1142.         test    [si].Flags, LVB_SEL_BIT            ; 
  1143.         .if     <nz>                               ; LVB requested?
  1144.             test    [si].Flags, PVB_SEL_BIT        ; 
  1145.             .if     <z>                            ; LVB update only?
  1146.                 mov     [bp].PVB_Sel, 0            ; Indicate as such
  1147.             .endif                                 ; 
  1148.             mov     di, [si].LogicalBufSel         ; Use LVB instead
  1149.         .else                                      ; PVB only!
  1150.             mov     [bp].PVB_Sel, 0                ; Indicate PVB update only
  1151.             inc     [bp].Retrace                   ; Retrace wait required
  1152.         .endif                                     ; 
  1153.  
  1154.         lds     si, [si].AppCellAddr               ; 
  1155.         lodsw                                      ; AX = user supplied cell
  1156.         mov     ds, di                             ; DS, ES = PVB or LVB
  1157.         mov     es, di                             ; 
  1158.         ret                                        ; 
  1159.  
  1160. GetLVB_PVB_Cell ENDP
  1161.  
  1162. R2CSEG  ENDS
  1163.         END
  1164.