home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v2.zip / DDKX86 / DBCSDD / SRC_DBCS / VDHWNDW / XGAREAD.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  33KB  |  795 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   XGAREAD.ASM -- Common Buffer Read Routines for EGA, VGA, BGA
  14. ;/*****************************************************************************
  15. ;*
  16. ;* SOURCE FILE NAME = XGAREAD.ASM
  17. ;*
  18. ;* DESCRIPTIVE NAME = BUFFERUPDATE read routines
  19. ;*
  20. ;*
  21. ;* VERSION      V2.0
  22. ;*
  23. ;* DATE
  24. ;*
  25. ;* DESCRIPTION  Common Buffer Read Routines for EGA, VGA, BGA
  26. ;*
  27. ;* FUNCTIONS    ReadCellTypes
  28. ;*              ReadCharStr
  29. ;*              ReadCellStr
  30. ;*              SetBuffAddr
  31. ;*              FastBuffAddr
  32. ;*              CalcTouchRect
  33. ;*
  34. ;* NOTES        NONE
  35. ;*
  36. ;* STRUCTURES   NONE
  37. ;*
  38. ;* EXTERNAL REFERENCES
  39. ;*
  40. ;*              NONE
  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. ;*  03/25/89   @P1                TPL, DCR 132 changes
  51. ;*  06/25/89   @T37       B703759 TPL, DCR 132 fix
  52. ;*  01/29/91   MS00               TPL, Convert IFDEF to IF
  53. ;*  01/29/91   MS01               TPL, Rollover MS's runtime
  54. ;*                                check for CGA speedup
  55. ;*  04/11/91   D1348      D1348   NAKADA, Enable DBCS support in Vio-Window
  56. ;*****************************************************************************/
  57.  
  58.         .286c                           ; 286 protect mode instructions
  59.  
  60.         .xlist
  61.         INCLUDE struc.inc               ; Structure macro
  62.         INCLUDE error2.inc              ; Subsystem error equates
  63.         INCLUDE vdhstruc.inc            ; Buffer update data structures
  64.         INCLUDE vdhctl.inc              ; Conditional Assembly Control  ;MS01
  65.         INCLUDE vdhequ.inc              ; Buffer update equates
  66.         INCLUDE xgamac.inc                                              ;@P1
  67.         .list
  68.  
  69.         EXTRN   SetGenParms:NEAR        ; Set up general buffer update parms @P1
  70.  
  71. IF VDHCGA AND (1 - CGA_ALWAYS_FAST)     ; IF VDHCGA AND NOT CGA_ALWAYS_FAST ;MS01
  72.  
  73. ;/*
  74. ;**  If CGA video memory accesses may need to wait for retrace,
  75. ;**  these routines are necessary. (See MAKEFILE)
  76. ;*/
  77.         extrn   CGA_REP_MOVSW:far                                       ;@P1
  78.         extrn   CGA_REP_STOSW:far                                       ;@P1
  79.         extrn   CGA_REP_MOVSB_INCSI_LOOP:far                            ;@P1
  80.         extrn   CGA_REP_MOVSW_STOSW_LOOP:far                            ;@P1
  81.         extrn   CGA_REP_INCDI_STOSB_LOOP:far                            ;@P1
  82.         extrn   CGA_REP_STOSB_INCDI_LOOP:far                            ;@P1
  83.         extrn   CGA_REP_LODSB_STOSW_LOOP:far                            ;@P1
  84.         extrn   CGA_REP_MOVSB_INCDI_LOOP:far                            ;@P1
  85.         extrn   CGA_REP_MOVSW_ADDSI2_LOOP:far                           ;@P1
  86. ENDIF   ;VDHCGA                                                         ;MS00
  87.  
  88. IFDEF D1348 ;See whether it is of DBCS or not.
  89.         extrn   ReadCellTypesWrld:near
  90.     IFDEF MSKK  ;DBCS bits read
  91.         extrn   ReadCharStrWrld:near
  92.         extrn   ReadCellStrWrld:near
  93.     ENDIF
  94. ENDIF ;D1348
  95.  
  96. R2CSEG  SEGMENT WORD PUBLIC 'CODE'
  97.         ASSUME  CS:R2CSEG,DS:NOTHING,ES:NOTHING
  98.  
  99. ;/****************************************************************************
  100. ;*
  101. ;* SUBROUTINE NAME:     ReadCellTypes  ReadCellTypes3
  102. ;*
  103. ;* DESCRIPTIVE NAME:    Video device handler read cell types
  104. ;*
  105. ;* FUNCTION:    Process read cell types sub-function.
  106. ;*
  107. ;* ENTRY POINT: ReadCellTypes
  108. ;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
  109. ;*
  110. ;* INPUT:
  111. ;*
  112. ;* AX = 0
  113. ;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
  114. ;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
  115. ;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
  116. ;*
  117. ;* PARAMETER BLOCK FORMAT:
  118. ;*
  119. ;*   SIZE   DESCRIPTION
  120. ;*   ----   -----------
  121. ;*
  122. ;*   WORD   Parameter length
  123. ;*   WORD   Flags                     (source data buffer - LVB, PVB)
  124. ;*   DWORD  Application data address  (target data buffer)
  125. ;*   DWORD  Application data2 address (not used in this call)
  126. ;*   WORD   Index (0)
  127. ;*   WORD   Starting row              (source row)
  128. ;*   WORD   Starting column           (source column)
  129. ;*   WORD   Secondary row             (not used in this call)
  130. ;*   WORD   Secondary column          (not used in this call)
  131. ;*   WORD   RepeatFactor              (input and output length)
  132. ;*   WORD   LogicalBufSel
  133. ;*
  134. ;* OUTPUT:
  135. ;*
  136. ;* EXIT-NORMAL: AX = 0
  137. ;*
  138. ;* EXIT-ERROR:  AX = Error from LocateBuffAddr
  139. ;*
  140. ;* EFFECTS:     All
  141. ;*
  142. ;* INTERNAL REFERENCES: LocateBuffAddr
  143. ;*
  144. ;* EXTERNAL REFERENCES: None
  145. ;*
  146. ;****************************************************************************/
  147.  
  148.         PUBLIC  ReadCellTypes
  149.         PUBLIC  ReadCellTypes3                                          ;@P1
  150. ReadCellTypes   PROC    NEAR
  151. ReadCellTypes3:                                                         ;@P1
  152. IFDEF D1348 ;CheckCharType of DBCS
  153.         mov     bx,0                            ; Operation in terms of cells
  154. ELSE  ;D1348
  155.         mov     bx, 1                           ; Set indicator for word move
  156. ENDIF ;D1348
  157.         call    SetBuffAddr                     ; On exit: BX = sel, AX = off @P1
  158.         .if     <nc>                            ; Continue?
  159.             shr     cx, 1                       ; Adjust for word move
  160.             les     di, [si].AppDataAddr        ; Setup destination address @P1
  161.  
  162. IFDEF D1348 ;CheckCharType of DBCS
  163. IFNDEF MSKK                                                             ;;MSKK  ;; added for J-FUNC
  164.             .if    <bit <[bp].flgDBCS> and anyDBCS> and
  165.             .if    <[bp].j_funcindx eq WorldFmtIndx>
  166. ELSE                                                                    ;;MSKK  ;; added for J-FUNC
  167.             .if    <bit <[bp].flgDBCS> and anyDBCS>                     ;;MSKK  ;; added for J-FUNC
  168. ENDIF ; MSKK                                                            ;;MSKK  ;; added for J-FUNC
  169.                 mov     ds,bx                   ; Use LVB as source
  170.                 mov     si,ax                   ; Setup source offset
  171.                 call    ReadCellTypesWrld
  172.                 sub     ax,ax                   ; Clear return code
  173.             .else
  174. ENDIF ;D1348
  175.  
  176.                 sub     ax, ax                  ; Clear return code         @P1
  177.                 rep     stosw                   ; Transfer zeros to user buffer @P1
  178. IFDEF D1348
  179.             .endif
  180. ENDIF ;D1348
  181.         .endif                                  ; 
  182.         ret
  183.  
  184. ReadCellTypes   ENDP
  185.  
  186. ;/****************************************************************************
  187. ;*
  188. ;* SUBROUTINE NAME:     ReadCharStr
  189. ;*
  190. ;* DESCRIPTIVE NAME:    Video device handler read characters
  191. ;*
  192. ;* FUNCTION:    Process read characters sub-function.
  193. ;*              The characters are read from either PVB or LVB
  194. ;*              starting at the specified row, column location.
  195. ;*              Line wrap occurs if the end of a line is reached.
  196. ;*              Read function is terminated if the end of PVB or
  197. ;*              LVB is reached.  The characters read are placed
  198. ;*              in the specified buffer and the number of chars
  199. ;*              read is returned in the RepeatFactor field of
  200. ;*              the parameter block.
  201. ;*
  202. ;* ENTRY POINT: ReadCharStr
  203. ;*   LINKAGE:   Near Call from BUFFERUPDATE routine
  204. ;*
  205. ;* INPUT:
  206. ;*
  207. ;* AX = 0
  208. ;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
  209. ;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
  210. ;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
  211. ;*
  212. ;* PARAMETER BLOCK FORMAT:
  213. ;*
  214. ;*   SIZE   DESCRIPTION
  215. ;*   ----   -----------
  216. ;*
  217. ;*   WORD   Parameter length
  218. ;*   WORD   Flags                     (source data buffer - LVB, PVB)
  219. ;*   DWORD  Application data address  (target data buffer)
  220. ;*   DWORD  Application data2 address (not used in this call)
  221. ;*   WORD   Index (1)
  222. ;*   WORD   Starting row              (source row)
  223. ;*   WORD   Starting column           (source column)
  224. ;*   WORD   Secondary row             (not used in this call)
  225. ;*   WORD   Secondary column          (not used in this call)
  226. ;*   WORD   RepeatFactor              (input and output length)
  227. ;*   WORD   LogicalBufSel
  228. ;*
  229. ;* OUTPUT:      Application data buffer = characters read
  230. ;*              RepeatFactor = number of characters read
  231. ;*
  232. ;* EXIT-NORMAL: AX = 0
  233. ;*
  234. ;* EXIT-ERROR:  AX = Error from LocateBuffAddr
  235. ;*
  236. ;* EFFECTS:     All registers
  237. ;*
  238. ;* INTERNAL REFERENCES: LocateBuffAddr
  239. ;*
  240. ;* EXTERNAL REFERENCES: None
  241. ;*
  242. ;****************************************************************************/
  243.  
  244.         PUBLIC  ReadCharStr
  245. ReadCharStr     PROC    NEAR
  246.  
  247.         mov     bx, 0                           ; Move in terms of Cell count
  248.         call    SetBuffAddr                     ; On exit: BX = sel, AX = off @P1
  249.         .if     <nc>                            ; Continue?
  250.             .if     <nonzero bx>                ; LVB flag set?             @P1
  251.                 les     di, [si].AppDataAddr    ; Setup destination address @P1
  252.                 mov     ds, bx                  ; Use LVB as source         @P1
  253.                 mov     si, ax                  ; Setup source offset       @P1
  254.                 .if     <[bp].cellsize e WorldCellSize> near                @P1
  255.                     .repeat                     ;                           @P1
  256.                         movsb                   ; Transfer chars to destination
  257.                         add     si, 3           ; skip the attribute bytes  @P1
  258.                     .loop                       ;                           @P1
  259.                 .else                           ;                           @P1
  260.                     .repeat                     ;                           @P1
  261.                         movsb                   ; Transfer chars to destination
  262.                         inc     si              ; skip the attribute byte   @P1
  263.                     .loop                       ;                           @P1
  264.                 .endif                          ;                           @P1
  265.             .else                               ; read from PVB             @P1
  266.                 les     di, [si].AppDataAddr    ; Setup destination address @P1
  267.                 mov     bx, [bp].PVB_Sel        ; Use PVB as source         @P1
  268.                 .if     <nonzero bx>            ;                           @P1
  269.                     mov     ds, bx              ; Setup source selector     @P1
  270.                     mov     si, [bp].PVBOff     ; Setup source offset       @P1
  271.                     REP_MOVSB_INCSI_LOOP        ; Use the above macro so CGA can
  272.                                                 ; use the same set of sources
  273.                 .endif                          ;                           @P1
  274.             .endif                              ;                           @P1
  275.             sub     ax,ax                       ; Clear return code
  276.         .endif                                  ; 
  277.         ret
  278.  
  279. ReadCharStr     ENDP
  280.  
  281. ;/****************************************************************************
  282. ;*
  283. ;* SUBROUTINE NAME:     ReadCellStr
  284. ;*
  285. ;* DESCRIPTIVE NAME:    Video device handler read cells
  286. ;*
  287. ;* FUNCTION:    Process read cells sub-function.
  288. ;*              The cells are read from either PVB or LVB starting
  289. ;*              at the specified row, column location.  Line wrap
  290. ;*              occurs if the end of a line is reached.  Read
  291. ;*              function is terminated if the end of PVB or LVB
  292. ;*              is reached.  The cells read are placed in the
  293. ;*              specified buffer and the number of cells read
  294. ;*              is returned in the RepeatFactor field of the
  295. ;*              parameter block.
  296. ;*
  297. ;* ENTRY POINT: ReadCellStr
  298. ;*   LINKAGE:   Near Call from BUFFERUPDATE routine
  299. ;*
  300. ;* INPUT:
  301. ;*
  302. ;* AX =   0
  303. ;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
  304. ;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
  305. ;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
  306. ;*
  307. ;* PARAMETER BLOCK FORMAT:
  308. ;*
  309. ;*   SIZE   DESCRIPTION
  310. ;*   ----   -----------
  311. ;*
  312. ;*   WORD   Parameter length
  313. ;*   WORD   Flags                     (source data buffer - LVB, PVB)
  314. ;*   DWORD  Application data address  (target data buffer)
  315. ;*   DWORD  Application data2 address (not used in this call)
  316. ;*   WORD   Index (2)
  317. ;*   WORD   Starting row              (source row)
  318. ;*   WORD   Starting column           (source column)
  319. ;*   WORD   Secondary row             (not used in this call)
  320. ;*   WORD   Secondary column          (not used in this call)
  321. ;*   WORD   RepeatFactor              (input and output length)
  322. ;*   WORD   LogicalBufSel
  323. ;*
  324. ;* OUTPUT:      Application data buffer = character cells read
  325. ;*              RepeatFactor = sum of char/attr pairs read
  326. ;*
  327. ;* EXIT-NORMAL: AX = 0
  328. ;*
  329. ;* EXIT-ERROR:  AX = Error from LocateBuffAddr
  330. ;*
  331. ;* EFFECTS:     All
  332. ;*
  333. ;* INTERNAL REFERENCES: LocateBuffAddr
  334. ;*
  335. ;* EXTERNAL REFERENCES: None
  336. ;*
  337. ;****************************************************************************/
  338.  
  339.         PUBLIC  ReadCellStr
  340. ReadCellStr     PROC    NEAR
  341.  
  342.         mov     bx, 1                       ; Move in terms of buffer length
  343.         call    SetBuffAddr                 ; On exit: BX = sel, AX = off @P1
  344.         .if     <nc>                        ; Continue?
  345.             shr     cx, 1                   ; Adjust for word move
  346.             les     di, [si].AppDataAddr    ; Setup destination address   @P1
  347.             .if     <nonzero bx>            ; LVB flag set?               @P1
  348.                 mov     ds, bx              ; Setup source selector       @P1
  349.                 mov     si, ax              ; Setup source offset         @P1
  350.                 rep     movsw               ; Transfer cells to destination @P1
  351.             .else                           ;                             @P1
  352.                 mov     bx, [bp].PVB_Sel    ; Use PVB as source           @P1
  353.                 .if     <nonzero bx>        ;                             @P1
  354.                     mov     ds, bx          ; Setup source selector       @P1
  355.                     mov     si, [bp].PVBOff ; Setup source offset         @P1
  356.                     .if     <[bp].cellsize e WorldCellSize>              ;@P1
  357.                         shr     cx, 1       ; Adjust for dword move       @P1
  358.                         xor     ax,ax       ; (ax) = final word of attribute @P1
  359.                         REP_MOVSW_STOSW_LOOP; Use macro so CGA can use the same
  360.                                             ; sources as everyone else    @P1
  361.  
  362.                     .else                   ;                             @P1
  363.                         REP_MOVSW           ; Use macro so CGA can use the same
  364.                                             ; sources as everyone else    @P1
  365.                     .endif                  ;                             @P1
  366.                 .endif                      ;                             @P1
  367.             .endif                          ;                             @P1
  368.             xor     ax,ax                   ; set a good return code
  369.         .endif
  370.         ret
  371.  
  372. ReadCellStr     ENDP
  373.  
  374.  
  375. ;/****************************************************************************
  376. ;*
  377. ;* SUBROUTINE NAME:     SetBuffAddr
  378. ;*
  379. ;* DESCRIPTIVE NAME:    Video device handler locate video buffer addr
  380. ;*
  381. ;* FUNCTION:    Determine the source/target buffer address for the
  382. ;*              read/write function based on the information in the
  383. ;*              parameter buffer and the mode data buffer.
  384. ;*
  385. ;* ENTRY POINT: SetBuffAddr
  386. ;*   LINKAGE:   Near Call
  387. ;*
  388. ;* INPUT:
  389. ;*
  390. ;* AX = 0
  391. ;* BX = Type of transfer
  392. ;*      0 - the RepeatFactor is a count of cells or characters
  393. ;*     !0 - the RepeatFactor is a user buffer length
  394. ;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
  395. ;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
  396. ;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
  397. ;*
  398. ;* OUTPUT:  AX = LVB offset
  399. ;*          BX = LVB selector OR 0 if LVB not requested
  400. ;*          CX = adjusted LVB repeat factor
  401. ;*          DS:[SI].RepeatFactor = # of bytes to be transfered
  402. ;*          CY = 1 Error encountered
  403. ;*          [BP].PVB_Sel    - Selector to the PVB or 0
  404. ;*          [BP].LVB_Sel    - Selector to the LVB or 0
  405. ;*          [BP].cellsize   - number of bytes per cell in LVB
  406. ;*          [BP].FirstRow   - number of cells or bytes in first row
  407. ;*          [BP].RowLength  - number of cells or bytes in later rows
  408. ;*          [BP].LVBCount   - number of cells or bytes to move, LVB
  409. ;*          [BP].LVBOff     - offset for read or write in LVB
  410. ;*          [BP].PVBSkip    - number of bytes to next row in PVB
  411. ;*          [BP].PVBCount   - number of cells or bytes to move, PVB
  412. ;*          [BP].PVBOff     - offset for read or write in LVB
  413. ;*
  414. ;* EXIT-NORMAL: CY = clear
  415. ;*
  416. ;* EXIT-ERROR:  CY = set
  417. ;*              AX = 0  if RepeatFactor = 0 for char or attr move
  418. ;*                                      = 0 or 1 for cell move
  419. ;*              AX = ERROR_VIO_INVALID_PARMS
  420. ;*
  421. ;* EFFECTS:     AX, BX, CX, DX, CY
  422. ;*
  423. ;* INTERNAL REFERENCES: None
  424. ;*
  425. ;* EXTERNAL REFERENCES: None
  426. ;*
  427. ;* PSEUDOCODE
  428. ;*
  429. ;*      if !( (mincol <= parmcol <= maxcol) &&
  430. ;*            (minrow <= parmrow <= maxrow) )
  431. ;*          exit with error
  432. ;*
  433. ;*      PVBSkip = (modeRows - lvb_width) * cellsize
  434. ;*      RowLength = lvb_width * cellsize
  435. ;*      LVBOff = (parmrow - minrow) * lvb_width +
  436. ;*                    (parmcol - mincol) * cellsize
  437. ;*      PVBOff = (parmrow * modeCols + parmcol) * cellsize
  438. ;*      BytesLeft = lvb_width * lvb_height * cellsize - LVBOff
  439. ;*      if (Read/Write Buffer Cells length)
  440. ;*          if (parmcount > BytesLeft)
  441. ;*              parmcount = BytesLeft
  442. ;*          LVBCount = parmcount
  443. ;*          PVBCount = parmcount
  444. ;*      else (Read/Write Chars or Cell count)
  445. ;*          CellsLeft = BytesLeft/CellSize
  446. ;*          if (parmcount > CellsLeft)
  447. ;*              parmcount = CellsLeft
  448. ;*          LVBCount = parmcount
  449. ;*          PVBCount = parmcount
  450. ;*
  451. ;*      if  (cellsize == 4)
  452. ;*          PVBOff = PVBOff / 2
  453. ;*          if (Read/Write Buffer Cells length)
  454. ;*              PVBCount = parmcount/2
  455. ;*
  456. ;****************************************************************************/
  457.  
  458.         PUBLIC  SetBuffAddr                                     ;@P1 begin
  459. SetBuffAddr PROC    NEAR
  460.  
  461.         call    SetGenParms             ; set general parameters for all
  462.  
  463.         .if     <c>                     ; US default values
  464.             jmp     FastBuffAddr        ; do fast version of the calculations
  465.         .endif
  466.  
  467.         ;/*
  468.         ;**  Possible bizarre LVB.  (cx) = maxcolumn, (ax) = maxrow
  469.         ;*/
  470.  
  471.         .if     <cx b ds:[si].Col> or
  472.         mov     cx,[bp].mincol
  473.         .if     <cx a ds:[si].Col>      ;   No, return error
  474.             mov     ax,ERROR_VIO_COL
  475.             jmp     sbaerr
  476.         .endif
  477.  
  478.         .if     <ax b ds:[si].Row> or   ; Is the column coordinate valid?
  479.         mov     ax,[bp].minrow
  480.         .if     <ax a ds:[si].Row>      ;   No, exit with error
  481.             mov     ax,ERROR_VIO_ROW
  482.             jmp     sbaerr
  483.         .endif
  484.  
  485.         .if     <nonzero bx>
  486.             mov     ax,[bp].cellsize    ; cell size must be a power of 2
  487.             dec     ax                  ; (ax) = bitmask for MOD
  488.             xor     ax,-1               ; (ax) = bitmask for round down
  489.             and     ds:[si].RepeatFactor,ax
  490.         .endif
  491.  
  492.         .if     <ds:[si].RepeatFactor e 0>  ; check for NOP read or write
  493.             xor     ax,ax               ; zero length writes and reads are
  494.             jmp     sbaerr              ; valid, but do nothing
  495.         .endif
  496.  
  497.         mov     ax,[bp].maxcol              ; calculate the number of cells
  498.         sub     ax,ds:[si].Col              ; in the first row of the read or
  499.         inc     ax                          ; or write
  500.         mov     [bp].FirstRow,ax
  501.  
  502.         mov     ax,es:[di].TextCols         ; calculate number of bytes per row
  503.         sub     ax,[bp].lvb_width           ; skipped when moving from PVB line
  504.         shl     ax,1                        ; to PVB line
  505.         mov     [bp].PVBSkip,ax
  506.  
  507.         mov     cx,[bp].lvb_width           ; caluculate the Row Length of the LVB
  508.         shl     cx,1                        ; in bytes in a two byte cell LVB
  509.         mov     [bp].RowLength,cx
  510.                                             ; (cx) = bytes per LVB row
  511.         mov     ax,ds:[si].Row              ; calculate offset into the LVB
  512.         sub     ax,[bp].minrow
  513.         mul     cx
  514.         mov     cx,ds:[si].Col
  515.         sub     cx,[bp].mincol
  516.         shl     cx,1
  517.         add     ax,cx
  518.         mov     [bp].LVBOff,ax
  519.  
  520.         mov     ax,ds:[si].Row              ; calculate the PVB offset
  521.         mul     es:[di].TextCols
  522.         add     ax,ds:[si].Col
  523.         shl     ax,1
  524.         mov     [bp].PVBOff,ax
  525.  
  526.         mov     ax,[bp].lvb_width           ; calculate longest possible write/read
  527.         mul     [bp].lvb_height
  528.         shl     ax,1
  529.         sub     ax,[bp].LVBOff              ; (ax) = longest write in bytes
  530.  
  531.         cmp     [bp].cellsize,DefaultCellSize   ; Is this the default Cell Size?
  532.         .if     <nz>
  533.  
  534.             or      bx,bx                   ; Is this a cell or char count?
  535.             .if     <z>                     ;   Yes, calculate cell or char count
  536.                 shr     ax,1                ; (ax) = longest write in cells
  537.                 shr     [bp].RowLength,1    ; convert row length to cells
  538.                 .if     <ax b ds:[si].RepeatFactor> ; truncate the length if needed
  539.                     mov     ds:[si].RepeatFactor,ax
  540.                 .else
  541.                     mov     ax,ds:[si].RepeatFactor
  542.                 .endif
  543.                 mov     [bp].LVBCount,ax
  544.                 mov     [bp].PVBCount,ax
  545.             .else
  546.                 shl     ax,1                ; (ax) = longest write in bytes
  547. IFDEF D1348 ;support of 64K PS
  548.                 .if     <nc> and            ; if 64K, CY is set
  549. ENDIF ;D1348
  550.                 .if     <ax b ds:[si].RepeatFactor> ; truncate the length if needed
  551.                     mov     ds:[si].RepeatFactor,ax
  552.                 .else
  553.                     mov     ax,ds:[si].RepeatFactor
  554.                 .endif
  555.                 mov     [bp].LVBCount,ax    ; byte count for 4 byte cell LVB
  556.                 shr     ax,1
  557.                 mov     [bp].PVBCount,ax; byte count for 2 byte cell PVB
  558.                 shl     [bp].FirstRow,2     ; Adjust LVB first row length
  559.                 shl     [bp].RowLength,1    ; Adjust LVB row length for cell size
  560.             .endif
  561.             shl     [bp].LVBOff,1           ; Adjust LVB start offset for cell size
  562.         .else
  563.             or      bx,bx                   ; Is this a cell or char count?
  564.             .if     <z>                     ;   Yes, calculate cell or char count
  565.                 shr     ax,1                ; (ax) = longest write in cells
  566.                 shr     [bp].RowLength,1    ; convert row length to cells
  567.             .else
  568.                 shl     [bp].FirstRow,1     ; Adjust LVB first row length
  569.             .endif
  570.             .if     <ax b ds:[si].RepeatFactor> ; truncate the length if needed
  571.                 mov     ds:[si].RepeatFactor,ax
  572.             .else
  573.                 mov     ax,ds:[si].RepeatFactor
  574.             .endif
  575.             mov     [bp].LVBCount,ax
  576.             mov     [bp].PVBCount,ax
  577.         .endif
  578.  
  579.         cmp     ds:[si].ParmLength,LVBRowOff; Does caller want the touch rect?
  580.         .if     <ae>                    ;   Yes, return the Touch Rect
  581.             call    CalcTouchRect
  582.         .endif
  583.  
  584.         mov     bx,[bp].LVB_Sel         ; (bx) = LVB or 0
  585.         mov     ax,[bp].LVBOff          ; (ax) = offset into LVB
  586.         mov     cx,[bp].LVBCount        ; (cx) = LVB repeat count
  587.  
  588.         clc
  589. sbax:   ret
  590.  
  591. sbaerr: stc
  592.         jmp     sbax
  593.  
  594. SetBuffAddr ENDP                                                ;@P1 end
  595.  
  596.  
  597. ;/****************************************************************************
  598. ;*
  599. ;* FUNCTION NAME = FastBuffAddr
  600. ;*
  601. ;* DESCRIPTION   = Set buffer addresses for US case
  602. ;*
  603. ;*      FastBuffAddr takes advantage of the fact the the PVB and LVB are
  604. ;*      both the same size and format.  It calculates all of the end values
  605. ;*      that SetBuffAddr does, but does it for the CGA format LVB/PVB only.
  606. ;*
  607. ;* INPUT         = SS:BP - local data storage area
  608. ;*                 DS:SI - user passed parameter block
  609. ;*                 ES:DI - environment data
  610. ;*                 BX - 0 if write in cells, !0 if write in bytes
  611. ;*                 [bp].cellsize - number of bytes per cell
  612. ;*
  613. ;* OUTPUT        =
  614. ;*
  615. ;*            Carry Clear
  616. ;*              AX = LVB offset
  617. ;*              BX = LVB selector OR 0 if LVB not requested
  618. ;*              CX = adjusted LVB repeat factor
  619. ;*              DS:[SI].RepeatFactor = # of bytes to be transfered
  620. ;*              CY = 1 Error encountered
  621. ;*              [BP].PVB_Sel    - Selector to the PVB or 0
  622. ;*              [BP].LVB_Sel    - Selector to the LVB or 0
  623. ;*              [BP].cellsize   - number of bytes per cell in LVB
  624. ;*              [BP].FirstRow   - number of cells or bytes in first row
  625. ;*              [BP].RowLength  - number of cells or bytes in later rows
  626. ;*              [BP].LVBCount   - number of cells or bytes to move, LVB
  627. ;*              [BP].LVBOff     - offset for read or write in LVB
  628. ;*              [BP].PVBSkip    - number of bytes to next row in PVB
  629. ;*              [BP].PVBCount   - number of cells or bytes to move, PVB
  630. ;*              [BP].PVBOff     - offset for read or write in LVB
  631. ;*
  632. ;*            Carry Set
  633. ;*              AX = error code
  634. ;*
  635. ;*      USES    AX,BX,CX,DX,FLAGS
  636. ;*
  637. ;* RETURN-NORMAL = NONE
  638. ;* RETURN-ERROR  = NONE
  639. ;*
  640. ;****************************************************************************/
  641.  
  642.             Public  FastBuffAddr                                ;@P1 begin
  643. FastBuffAddr    PROC
  644.  
  645.         mov     cx,ds:[si].Col
  646.         mov     ax,es:[di].TextCols
  647.         .if     <cx ae ax>      ;   No, return error
  648.             mov     ax,ERROR_VIO_COL
  649.             jmp     sbaerr
  650.         .endif
  651.  
  652.         mov     [bp].RowLength,ax
  653.         sub     ax,cx
  654.         mov     [bp].FirstRow,ax
  655.  
  656.         mov     ax,ds:[si].Row
  657.         .if     <ax ae es:[di].TextRows>      ;   No, return error
  658.             mov     ax,ERROR_VIO_ROW
  659.             jmp     sbaerr
  660.         .endif
  661.  
  662.         mul     es:[di].TextCols    ; calculate the LVB/PVB offset
  663.         add     ax,cx
  664.         shl     ax,1
  665.         mov     [bp].PVBOff,ax
  666.         mov     [bp].LVBOff,ax
  667.         mov     cx,ax               ; (cx) = offset of beginning of write
  668.  
  669.         mov     ax,es:[di].TextCols ; calculate longest possible write/read
  670.         mul     es:[di].TextRows    ; calculate longest possible write/read
  671.         shl     ax,1
  672.         sub     ax,cx               ; (ax) = longest write in bytes
  673.  
  674.         or      bx,bx               ; Is this a cell or char count?
  675.         .if     <z>                 ;   Yes, calculate cell or char count
  676.             shr     ax,1            ; (ax) = longest write in cells
  677.         .else
  678.             and     ds:[si].RepeatFactor,0FFFEh
  679.             shl     [bp].FirstRow,1 ; Adjust LVB first row length
  680.             shl     [bp].RowLength,1; convert row length to bytes
  681.         .endif
  682.         .if     <ax b ds:[si].RepeatFactor> ; truncate the length if needed
  683.             mov     ds:[si].RepeatFactor,ax
  684.         .else
  685.             mov     ax,ds:[si].RepeatFactor
  686.         .endif
  687.         mov     [bp].LVBCount,ax
  688.         mov     [bp].PVBCount,ax
  689.         .if     <zero ax>
  690.             jmp     fbaerr
  691.         .endif
  692.  
  693.         mov     [bp].PVBSkip,0
  694.         mov     bx,[bp].LVB_Sel         ; (bx) = LVB or 0
  695.         mov     ax,[bp].LVBOff          ; (ax) = offset into LVB
  696.         mov     cx,[bp].LVBCount        ; (cx) = LVB repeat count
  697.  
  698.         clc
  699. fbax:   ret
  700.  
  701. fbaerr: stc
  702.         jmp     fbax
  703.  
  704. FastBuffAddr    ENDP                                            ;@P1 end
  705.  
  706. ;/****************************************************************************
  707. ;*
  708. ;* FUNCTION NAME = CalcTouchRect
  709. ;*
  710. ;* DESCRIPTION   = Calculate the rectangle touched by the given function
  711. ;*
  712. ;*       CalcTouchRect calculate the tightest rectangle that includes all of
  713. ;*       the cells that may have been changed by the given call.
  714. ;*
  715. ;* INPUT         =
  716. ;*
  717. ;*              SS:BP - local data storage area
  718. ;*              DS:SI - user passed parameter block
  719. ;*              BX - 0 if write in cells, !0 if write in bytes
  720. ;*              [bp].LVBCount   -  number of units to write, LVB
  721. ;*              [bp].mincol     -  left most column of LVB
  722. ;*              [bp].maxcol     -  right most column of LVB
  723. ;*              [bp].FirstRow   -  number of units to write first row of LVB
  724. ;*              [bp].RowLength  -  number of units per row, LVB
  725. ;*              [bp].cellsize   -  number of bytes per cell
  726. ;*
  727. ;* OUTPUT    =  ds:si-> Touchxxx - set to reflect rectangle affected
  728. ;*
  729. ;*      USES    AX,CX,DX,FLAGS
  730. ;*
  731. ;*                 ds:si - 2nd attribute pointer
  732. ;*                 es:di - LVB pointer
  733. ;*                 cx    - attr count
  734. ;*
  735. ;* RETURN-NORMAL = NONE
  736. ;* RETURN-ERROR  = NONE
  737. ;*
  738. ;****************************************************************************/
  739.  
  740.             Public  CalcTouchRect                               ;@P1 begin
  741. CalcTouchRect   PROC
  742.  
  743.         cmp     ds:[si].FuncIndex,MIN_WRT_INDEX ; Is this a write?
  744.         .if     <ae>                ;   Yes, return the Touch Rect
  745.             mov     cx,ds:[si].Row
  746.             mov     ds:[si].TouchYTop,cx
  747.             mov     ax,[bp].LVBCount    ; (ax) = read or write count
  748.             .if     <ax a [bp].FirstRow>; multiple row write
  749.                 mov     dx,[bp].mincol
  750.                 mov     ds:[si].TouchXLeft,dx
  751.                 mov     dx,[bp].maxcol
  752.                 mov     ds:[si].TouchXRight,dx
  753.  
  754.                 ;/*
  755.                 ;**  This calculation is complicated.
  756.                 ;**  ax = number of units to be written
  757.                 ;**  ax-FirstRow give the number of units in 2nd
  758.                 ;**      and later rows
  759.                 ;**  ((ax-FirstRow - 1)/RowLength) + 1 = # of rows beyond 1st
  760.                 ;*/
  761.  
  762.                 xor     dx,dx           ; (dx:ax) = (ax) = w count
  763.                 sub     ax,[bp].FirstRow; (ax) = w count for 2nd+ rows
  764.                 dec     ax              ; zero index bytes in the last row
  765.                 div     [bp].RowLength  ; (ax) = # rows written - 1
  766.                 inc     ax              ; (ax) = # of 2nd+ rows written
  767.                 add     cx,ax           ; (cx) = bottom row written
  768.                 mov     ds:[si].TouchYBottom,cx
  769.             .else                       ; single row write
  770.                 mov     ds:[si].TouchYBottom,cx
  771.                 mov     dx,ds:[si].Col
  772.                 mov     ds:[si].TouchXLeft,dx
  773.                 .if     <nonzero bx>
  774.                     mov     cx,[bp].cellsize
  775.                     shr     cx,1
  776.                     shr     ax,cl
  777.                 .endif
  778.                 dec     ax              ; a 1 cell write has same lf,rt col
  779.                 add     ax,dx           ; (ax) = right most column
  780.                 mov     ds:[si].TouchXRight,ax
  781.             .endif
  782.         .else                       ; read call, no data affected
  783.             mov     ds:[si].TouchYTop,-1
  784.             mov     ds:[si].TouchXLeft,-1
  785.             mov     ds:[si].TouchXRight,-1
  786.             mov     ds:[si].TouchYBottom,-1
  787.         .endif
  788.         ret
  789.  
  790. CalcTouchRect   ENDP                                            ;@P1 end
  791.  
  792. R2CSEG  ENDS
  793.         END
  794.  
  795.