;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = CELLBLT.INC
;*
;* DESCRIPTIVE NAME = Common definitions of the CharRect functions
;*
;*
;* VERSION      V2.0
;*
;* DATE         11/15/91
;*
;* DESCRIPTION  This module contains the definition of the frame created by CharRect 
;*              and used by a variety of subfunctions.  It also includes anything else
;*              common to the separate *.asm files which constitute the CharRect       
;*              function(s).                                                           
;*
;* FUNCTIONS    
;*              
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   11/15/91                     KEZ  Original
;*****************************************************************************/

IFNDEF CELLBLT_DEFD     ; Don't include if already included

CELLBLT_DEFD EQU 1      ; Indicate it has been included

        INCLUDE PMAVIOP.INC

DosCallback           PROTO SYSCALL,Function:DWORD
GreGetHandle          PROTO SYSCALL
Vio16GetPSAddress  PROTO SYSCALL
SetDisplayDefaults PROTO SYSCALL

IFNDEF CLR2                ;  - non CGA only

;/*
;** VIO_FONT_ENTRIES is the format of the individual character records in   
;** a fixed or proportional font.                            
;*/

VIO_FONT_ENTRIES STRUCT ; 
   fe_dBits DWORD ?     ; 
   fe_width WORD  ?     ; 
VIO_FONT_ENTRIES ENDS   ; 

ENDIF ; !CLR2           ;

;/*
;**---------------------------------Macro---------------------------------;
;** define_CharRect_frame
;**
;** Macro for defining the frame for CharRect functions
;**
;** This file allows the frame definiton to be shared by all
;** the modules which make up the CharRect function.
;**
;** Calls:
;**       none
;*/

define_CharRect_frame MACRO  name

name PROC SYSCALL PUBLIC uses EBX EDI ESI,
        hdc        :HDC,
        lpPS       :DWORD,              ; pVioPresentationSpace,
        lpRectDesc :DWORD,
        hddc       :DWORD,
        FunN       :DWORD

;/*
;**  support non 8 pel wide AVIO characters
;*/

IFNDEF CLR2                             ; -  non CGA only

        LOCAL   wClipYmin   :DWORD
        LOCAL   wClipYmax   :DWORD
        LOCAL   wClipXmin   :DWORD
        LOCAL   wClipXmax   :DWORD
        LOCAL   wColor      :WORD       ; 
        LOCAL   wFunction   :WORD
        LOCAL   wX          :DWORD
        LOCAL   wY          :DWORD
        LOCAL   wMask       :WORD
        LOCAL   wBitAddr    :WORD
        LOCAL   wByteAddr   :DWORD
        LOCAL   wModeSet    :WORD
        LOCAL   wVGAchar    :WORD       ; 
        LOCAL   wCharCount  :WORD
        LOCAL   wFontPtr0   :DWORD      ; character 0 font pointer
        LOCAL   wFontPtr1   :DWORD      ; character 1 font pointer
        LOCAL   wFontPtr2   :DWORD      ; character 2 font pointer
        LOCAL   wFontPtr3   :DWORD      ; character 3 font pointer
        LOCAL   wFontPtr4   :DWORD      ; character 4 font pointer
        LOCAL   wFontPtr5   :DWORD      ; character 5 font pointer
        LOCAL   wFontPtr6   :DWORD      ; character 6 font pointer
        LOCAL   wFontPtr7   :DWORD      ; character 7 font pointer

ENDIF ; !CLR2                           ;  - end

;/*
;** Logical Video Buffer Information:
;*/

        LOCAL   wRowCount   :WORD       ; Dimensions of the logical
        LOCAL   wColCount   :WORD       ; video buffer.
        LOCAL   wCellSize   :WORD       ; Bytes per character cell in
                                        ; the logical video buffer.
        LOCAL   wLVBRowBytes:WORD       ; Number of bytes per LVB row.

;/*
;** Destintation Bitmap Information:
;*/


        LOCAL   lpBitmapBits:DWORD      ; Long pointer to the destination
                                        ; bit rectangle.
        LOCAL   wDestWidth  :WORD       ; Width and height of the
        LOCAL   wDestHeight :WORD       ; destination bitmap.
        LOCAL   wDestBMWidth:WORD       ; Width of the destination
                                        ; bit array in bytes.
;/*
;** Symbol Set Information
;*/


        LOCAL   wSymbolSetSelectors[4]:DWORD    ; Selectors and offsets for
        LOCAL   wSymbolSetOffsets[4]  :DWORD    ; the symbol sets used herein

;/*
;** Temporary Variables for DrawImageRect and friends
;*/

;/*
;** !!! The masks should be computed within CellDraw.asm. CellBlt and CellScan
;**    should be independent of cell pixel dimensions.
;*/


        LOCAL   bHorizontalClipMask:BYTE        ; Clip mask for the current
                                                ; column.
        LOCAL   bUnderscoreMask    :BYTE        ; Byte mask used to implement
                                                ; underscore AVio attribute
        LOCAL   wCellHeight        :WORD        ; Height in pixels of a cell
                                                ; image
        LOCAL   wCellWidth         :WORD        ; Width in pixels of a cell
                                                ; image

bCellHeight EQU BYTE PTR (wCellHeight)  ; No cell is taller than 255 pixels!
bCellWidth  EQU BYTE PTR (wCellWidth )  ; No cell is wider  than 255 pixels!

        LOCAL   wLastAttributes  :WORD  ; Holds the previous WORD of AVio
                                        ; attribute information
        LOCAL   wVertLineOffset  :WORD  ; Pixel coordinates of the
        LOCAL   wHorzPixelOffset :WORD  ; screen bitmap relative to
                                        ; the conceptual LVB image
        LOCAL   wDestColOffset   :WORD  ; Column offset corresponding to
                                        ; wHorzPixelOffset.  We presume
                                        ; strongly that columns are 8 pixels
                                        ; wide and aligned on BYTE boundaries
        LOCAL   wTopRow          :WORD  ; These four variables define the
        LOCAL   wBotRow          :WORD  ; bounds of the LVB cells which
        LOCAL   wLeftCol         :WORD  ; are to be drawn, and which don't
        LOCAL   wRightCol        :WORD  ; need to be clipped.
        LOCAL   wTopFullLine     :WORD  ; Topmost horizontal line of the LVB
                                        ; image corresponding to a cell image
                                        ; which is not vertically clipped.
        LOCAL   wBotFullLine     :WORD  ; Image line which bounds the bottom
                                        ; of the full cell region.
        LOCAL   wLeftFullLine    :WORD  ; Leftmost line vertical line for a
                                        ; cell image which is not horizontally
                                        ; clipped.
        LOCAL   wRightFullLine   :WORD  ; Image line which bounds the right
                                        ; side of the full cell region.
        LOCAL   wTopLines        :WORD  ; The height of the top border region.
        LOCAL   wBotLines        :WORD  ; The height of the bottom border
                                        ; region.
        LOCAL   wLeftLines       :WORD  ; The width of the left border region.
        LOCAL   wRightLines      :WORD  ; The width of the right border region
        LOCAL   wCellSizeShift   :WORD  ; A shift factor for simulating
                                        ; multiplications by the size of
                                        ; an LVB cell in bytes.
        LOCAL   seg_LVB          :DWORD ; Selector for the LVB.  Offset == 0!
        LOCAL   pFirstFullLVBCell:DWORD ; Offset to the first LVB cell in
                                        ; row major order whose cell image
                                        ; is to be drawn without clipping.
        LOCAL   pLastFullLVBCell :DWORD ; Offset to the last WORD of the
                                        ; the last LVB cell (in row major order)
                                        ; to be drawn without clipping.
        LOCAL   pFirstLVBCell    :DWORD ; These two variables parallel
        LOCAL   pLastLVBCell     :DWORD ; pFirstFullLVBCell and
                                        ; pLastFullLVBCell.  They're
                                        ; used as arguments to the routines
                                        ; ScanVerticalBorder and
                                        ; ScanHorizontalBorder.
;/*
;** !!! Should remove these destination addresses.  Or at least confine
;**     their use to CellDraw.asm.  CellScan shouldn't make such close
;**     assumptions about the nature of the destination bit map and the
;**     dimensions of the cell images.
;*/


        LOCAL   pReturnAddress:DWORD    ; The location in the pseudo code
                                        ; of the return address to be used
                                        ; InterpretAttributes.

;/*
;** The following increments are set up and used by CellDraw.asm.
;*/


        LOCAL   wDest1stIncr   :DWORD   ; Destination increment for moving
                                        ; from one scan line to the next for
                                        ; a single cell image.

        LOCAL   wDest2ndIncr   :DWORD   ; Destination increment for moving
                                        ; from just below one cell image
                                        ; to the top scan line of the next
                                        ; cell image.

        LOCAL   wDest2ndToggle :WORD    ; Interlace increment toggle for
                                        ; wDest2ndIncr

        LOCAL   wDest3rdIncr   :DWORD   ; Destination increment for moving
                                        ; from just beyond the end of one
                                        ; cell image row to the beginning
                                        ; of the next row (within a column
                                        ; set).  The number of columns in
                                        ; the set is given by wFullCols.

        LOCAL   wFullRows      :WORD    ; The number of rows of LVB cells
                                        ; in the unclipped central region.
                                        ; This value will be negative when
                                        ; the image consists of a single
                                        ; horizontal row image which must
                                        ; be clipped vertically.

        LOCAL   wFullCols      :DWORD   ; The number of columns of LVB
                                        ; cells in the unclipped central
                                        ; region.  This value will be
                                        ; negative when the image consists
                                        ; of a single vertical column
                                        ; image which must be clipped
                                        ; horizontally.

        LOCAL   pStackLimit    :DWORD   ; SP limit used to determine when
                                        ; the scan must be partitioned.

        LOCAL   wTopLineOffset :DWORD   ; Vertical offset within a cell
                                        ; image of the first horizontal
                                        ; line to draw.

        LOCAL   wScanLineCount :DWORD   ; Number of horizontal lines to
                                        ; draw for the current cell set.

        LOCAL   wLeftLineOffset:WORD    ; Horizontal offset within a cell
                                        ; of the first vertical line to draw.

        LOCAL   wVertLineCount :WORD    ; Number of vertical lines to draw
                                        ; for the current cell set.

    bScanLines  EQU BYTE PTR (wScanLineCount)
                                        ; No cell is taller than 255 pixels!

        LOCAL   npcpmap        :DWORD   ; DGroup offset for the current
                                        ; code page mapping vector.

        LOCAL   xcoordTopLeft  :WORD    ; Destination coordinates for the
        LOCAL   ycoordTopLeft  :WORD    ; top left corner of the drawing
                                        ; rectangle.

        LOCAL   xcoordStart    :WORD    ; Starting destination coordinates
        LOCAL   ycoordStart    :WORD    ; for a drawing pass.

        LOCAL   fSomethingDrawn:DWORD   ; True if something was drawn during
                                        ; a call to CharRectangle

;/*
;** The following frame variables are CGA ONLY
;** do to inconsitencies between EGA and CGA versions this was the easiest
;** way to fix things
;*/

        LOCAL   bColor   :BYTE  ; Translated foreground color.
        LOCAL   bAndMask :BYTE  ; And Mask for drawing opaque text.
        LOCAL   bXorMask :BYTE  ; Xor Mask for drawing opaque text.
        LOCAL   bReverse :BYTE  ; Reverse Video

;/*
;** The following frame variables characterize the currently active font.
;** See CellDraw.asm for details.
;*/

        LOCAL   selFont      :WORD      ; Selector for the font segment.
        LOCAL   wFirstGlyph  :DWORD     ; Lowest defined glyph index.
        LOCAL   wGlyphSpan   :DWORD     ; Number of glyphs in the font.
        LOCAL   wDefaultGlyph:DWORD     ; Glyph index to substitute for
                                        ; undefined glyphs.
        LOCAL   npinxGlyph   :DWORD     ; Used to reference pseudo code
                                        ; when we're out of registers.
;/*
;** Temporary Variables for the Scanning Functions...
;*/

;/*
;** !!! wSaveCounts and wRowChunk are used only within ScanVerticalBorder.
;**     Should adjust the code to eliminate them.
;*/

        LOCAL   wSaveCounts    :WORD    ; For preserving row/col counts.
        LOCAL   npNextCellLabel:DWORD   ; Code pointer for the scan loop
                                        ; to use next.

;/*
;** Temporary Variables for DrawFullCells...
;*/


        LOCAL   wLVBRowInc     :WORD
        LOCAL   pCell          :DWORD
        LOCAL   wfForceColors  :WORD
        LOCAL   wselfontsave   :DWORD
        LOCAL   wVertLVBIncr   :DWORD
        LOCAL   OpaqueColorSave:WORD    ; local storage for the opaque colors
                                        ; for EGAMono
;/*
;** Variables for enumerating the clip rectangles
;*/


        LOCAL   drBounds :RECTL         ; Screen pixel bounds for the
                                        ; image rectangle denoted by
                                        ; *lpRectDesc.  Note the use
                                        ; of double WORD fields and
                                        ; bottom-left origin.
        LOCAL   rClipRect:OurRECTS      ; The clip rect for each
                                        ; iteration of DrawImageRect.
;/*
;** Text cursor exclusion
;*/

        LOCAL   fExcluding:WORD
        LOCAL   fDontDraw :WORD         ; == 1 => doesn't drawn anything,
                                        ;         but may do bounds calc.
        ENDM ; define_CharRect_frame

define_Invert_Cursor_Frame  MACRO   name

name PROC SYSCALL PUBLIC,hdc:HDC,pDDC:DWORD,
                         afFunN:WORD,lpBitmapBits:DWORD,
                         wDestHeight:WORD,wDestBMWidth:WORD,
                         wXCoord:WORD,wYCoord:WORD,
                         wHeight:WORD,wWidth:WORD

        LOCAL   fSomethingDrawn :WORD
        LOCAL   drBounds        :RECTL

        ENDM ; define_Invert_Cursor_Frame

;/*
;** Variables for the DrawImageRect routine saved at top of ring 2 stack
;*/


cb_variables          STRUCT 4
   cb_BPSaveSlot      DWORD  ?  ; # of scans to output
   cb_Default_Glyph   WORD   ?  ; Delta to next scan of a bitmap
   cb_Dest_3rd_Incr   DWORD  ?  ; Function to do output
   cb_Dest_2nd_Toggle WORD   ?  ; Dest_2nd increment address toggle
cb_variables          ENDS

cb_variables_len EQU sizeof cb_variables

InnerGREEntry PROTO SYSCALL     ; Dispatcher for Engine calls

StackBottom       EQU 20000h    ; Offset of bottom of stack
StackFirewall     EQU 256       ; How much stack space to keep
                                ; for interrupt routines.
StackCallOverhead EQU 8         ; Stack space for two near
                                ; return addresses.



PushRet MACRO   Reg,Addr

        PUSH    offset Addr
        STC
        SBB     Reg,Reg
        PUSH    Reg

        ENDM

;/*
;** ::::::::::: Branchless Numeric Comparisons
;**
;** The following Macros compute several numeric functions which are
;** traditionally accomplished by code that includes a comparison and
;** a conditional jump.  Conditional jumps have the unfortunate property
;** of flushing the prefetch queue.  These code sequences don't flush the
;** prefetch queue and may be faster than code with conditional jumps.
;**
;** The macros USMin and USMax compute, respectively, the minimum and
;** maximum of two unsigned values.  The input values are given by the
;** registers leftReg and rightReg.  One additional work register (workReg)
;** is required.  The result value is left in leftReg.
;*/

USMin   MACRO   leftReg,rightReg,workReg

        SUB     rightReg,leftReg
        SBB     workReg,workReg
        AND     rightReg,workReg
        ADD     leftReg,rightReg

        ENDM

USMax   MACRO   leftReg,rightReg,workReg

        SUB     rightReg,leftReg
        CMC
        SBB     workReg,workReg
        AND     rightReg,workReg
        ADD     leftReg,rightReg

        ENDM

;/*
;** The macros SMin and SMax compute the minimum and maximum value of
;** two signed numbers.  One number must be in EAX.  The other is in
;** register Reg.  The result will be in Reg.  In the process EDX will
;** be trashed.
;*/


SMin    MACRO   Reg

        SUB     EAX,Reg
        CDQ
        AND     EAX,EDX
        ADD     Reg,EAX

        ENDM

SMax    MACRO   Reg

        SUB     EAX,Reg
        CDQ
        NOT     EDX
        AND     EAX,EDX
        ADD     Reg,EAX

        ENDM

;/*
;** The AbsVal MACRO takes the absolute value of the signed number in EAX.
;** EDX is trashed in the process.
;*/

AbsVal  MACRO

        CDQ
        XOR     EAX,EDX
        SUB     EAX,EDX

        ENDM

;/*
;** Attribute Field Definitions
;** These definitions are used internally to maintain attribute
;** information extracted from Logical Video Buffer cells.
;**
;** Vio/AVio attribute words:
;**
;** High Byte --  Byte & 0F0h is the background color.
;**               Byte & 00Fh is the foreground color.
;**
;** Low Byte  --  Byte & 080h == 1 when Underscoring.
;**               Byte & 040h == 1 for Reverse Video.
;**               Byte & 010h == 1 for Transparent cells.
;**               Byte & 003h gives the symbol set index to use.
;*/

AVioColorSetMask     EQU 0FF00h
AVioDefinedBits      EQU 0D3h
AVioLCIDMask         EQU 003h
AVioReverseVideoMask EQU 040h
AVioTransparentMask  EQU 010h
AVioUnderscoreMask   EQU 080h

;/*
;** When a cell refers to an LCID that's not loaded, we draw it as a blank in
;** the default font (LCID 0).  SURROGATE_CHARACTER is the assumed glyph index
;** for blank.
;*/

SURROGATE_CHARACTER EQU 20h

;/*
;** Cell & Symbol Set Macros
;*/

;/*
;** The macros PixToCol, ColToPix, and PixModCol below are used to transform
;** between pixel column coordinates and character cell column coordinates.
;** The code they contain is trivial.  They are defined to make the remaining
;** code less dependant on the exact width of the character cells supported.
;**
;**  Following changes to support non 8 pel wide characters.
;*/

IFNDEF CLR2                             ;  - non CGA versions

ColToPix MACRO reg             ; Start of macro

IFDIFI  <reg>,<AX>      ; Is register AX ?

        XCHG    AX,reg          ; No, so swap AX with reg

ENDIF                   ; End of IFDIFI

        MUL     BYTE PTR wCellWidth ; Multiply AX by char width

IFDIFI  <reg>,<AX>      ; Is register AX ?

        XCHG    AX,reg          ; Swap registers back

ENDIF ; Col                 ; End of IFDIFI

ENDM ; End of ColToPix macro

PixToCol MACRO reg             ; Start of macro

IFDIFI  <reg>,<AX>      ; Is register AX ?

        XCHG    AX,reg          ; copy the register into it

ENDIF ; End of IFDIFI

        PUSH    DX              ; save DX
        CWD
        IDIV    wCellWidth      ; Divide DX:AX by char width
        POP     DX              ; recover DX

IFDIFI  <reg>,<AX>      ; Is register AX ?

        XCHG    AX,reg          ; No, so copy back result and...

ENDIF                   ; End of IFDIFI

ENDM ; End of PixToCol macro

ELSE ; CLR2

;/*
;**  Following only works (and is only needed for) 8 pel
;** wide characters and the CGA driver.
;**
;** NB: The code is still closely bound to a cell width of 8.  For instance,
;**     all the drawing functions assume that.  Changing to a width of 16
;**     wouldn't be too difficult.  Anything else would likely be very painful.
;*/

SymbolImageWidth EQU 8

PixToCol MACRO Reg

        SAR     Reg,3

        ENDM ; PixToCol

ColToPix MACRO Reg

        SHL     Reg,3

        ENDM ; ColToPix

ENDIF ; CLR2    - end                                                                                           00723 00649

PixModCol MACRO Reg

        AND     Reg,7

        ENDM ; PixModCol

;/*
;** MaxSymbolLines defines the tallest image cell which can be drawn.
;*/

MaxSymbolLines EQU 18

EXTERNDEF CellBLTBlock:cb_variables

ENDIF ; CELLBLT_DEFD
