;*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.;
;*****************************************************************************/
        page ,132
;***********************************************************************
;
;   Module          = VIOURECT.ASM
;
;   Description     = Private AI code
;
;   Function        = Does AVIO text work
;
;
;   Change log:
;   Date      Mark         APAR      Description
;   --------  ------------ --------- -----------------------------------
;
;***********************************************************************

INCL_GPIBITMAPS EQU     1
INCL_FONTFILEFORMAT     equ     1       ; to include pmfont.inc
include os2.inc
include eddinclt.inc

include eddhcone.inc
include eddhmacr.inc
include eddhtype.inc

?DF     equ     1       ; we dont want _TEXT segment defined
include cmacros.inc
include eddhavio.inc

ifdef _8514
include 8514.inc
endif


ifdef   AVIO_CGA_TEXT
extrn _IniCheckCellType2                :PROC
extrn _CheckCellType2                   :PROC
IniCheckCellType        equ <_IniCheckCellType2>
CheckCellType           equ <_CheckCellType2>
MOVE_CELL               equ 1
BYTE_PER_CELL           equ 2
endif ; AVIO_CGA_TEXT

ifdef   AVIO_MFI_TEXT
extrn _IniCheckCellType4                :PROC
extrn _CheckCellType4                   :PROC
IniCheckCellType        equ <_IniCheckCellType4>
CheckCellType           equ <_CheckCellType4>
MOVE_CELL               equ 2
BYTE_PER_CELL           equ 4
AVIO_HAS_LCID           equ 1
endif ; AVIO_MFI_TEXT

ifdef   AVIO_DBCS_TEXT
extrn _ExplisitCheckCellType4           :PROC
IniCheckCellType        equ <_ExplisitCheckCellType4>
CheckCellType           equ <_ExplisitCheckCellType4>
MOVE_CELL               equ 2
BYTE_PER_CELL           equ 4
AVIO_HAS_LCID           equ 1
endif ; AVIO_DBCS_TEXT

ifdef   AVIO_EPOCH_TEXT
extrn _ExplisitCheckCellType2           :PROC
IniCheckCellType        equ <_ExplisitCheckCellType2>
CheckCellType           equ <_ExplisitCheckCellType2>
MOVE_CELL               equ 1
BYTE_PER_CELL           equ 2
endif ; AVIO_CGA_TEXT



_DATA           segment dword use32 public 'DATA'

extrn _CIAArray                         :dword
extrn _CTArray                          :byte

ifdef _8514
extrn _CfpoArray                        :byte
endif ; _8514

ifdef BPP24
extrn _CIndexArray                      :dword
endif ; BPP24

_DATA           ends


CIAArray        equ     _CIAArray
CTArray         equ     _CTArray

ifdef _8514
CfpoArray       equ     _CfpoArray
endif ; _8514

ifdef BPP24
CIndexArray     equ     _CIndexArray
endif ; BPP24


_TEXT           segment dword use32 public 'CODE'
                assume  cs:FLAT, ds:FLAT, es:FLAT


;/********************************************************************/
;/* update_cache_charrect_2                                          */
;/*                                                                  */
;/* This subroutine ensures all 2 byte cell characters in a row of   */
;/* charrect that is about to be drawn are cached. This routine has  */
;/* capability to handle DBCS character codepoints, added to SBCS    */
;/* character codepoint handling.                                    */
;/*                                                                  */
;/* Entry - pfdBaseFont   : pointer to base FONTDETAILS              */
;/*       - pCharBuffer   : pointer in char buffer corresponds to    */
;/*                         first column in a row of clipped rect    */
;/*                                                                  */
;/* Exit  -  EAX             (no error: 0FFFFFFFFh  error: 0)        */
;/*                                                                  */
;/* Registers: EBX,ESI,EDI,DS,ES -- will be preserved                */
;/********************************************************************/

;/********************************************************************/
;/* update_cache_charrect_4                                          */
;/*                                                                  */
;/* This subroutine ensures all 4 byte cell characters in a row of   */
;/* clipped rect that is about to be drawn are cached. This routine  */
;/* has capability to handle DBCS character codepoints, add to SBCS  */
;/* character codepoint handling.                                    */
;/*                                                                  */
;/* Besides checking chars are cached, this routine also constructs  */
;/* char image array that is used by drawing routine.                */
;/*                                                                  */
;/* Entry - pfdBaseFont   : pointer to base FONTDETAILS              */
;/*       - pCharBuffer   : pointer in char buffer corresponds to    */
;/*                         first column in a row of clipped rect    */
;/*                                                                  */
;/* Exit  -  EAX             (no error: 0FFFFFFFFh  error: 0)        */
;/*                                                                  */
;/* Registers: EBX,ESI,EDI,DS,ES -- will be preserved                */
;/********************************************************************/

;/********************************************************************/
;/* common_update_cache_charrect                                     */
;/*                                                                  */
;/* This subroutine ensures all 4 byte cell characters in a row      */
;/* (DBCS Common) of clipped rect that is about to be drawn are      */
;/* cached. This routine has capability to handle DBCS character     */
;/* codepoints, add to SBCS character codepoint handling.            */
;/*                                                                  */
;/* Besides checking chars are cached, this routine also constructs  */
;/* char image array that is used by drawing routine.                */
;/*                                                                  */
;/* Entry - pfdBaseFont   : pointer to base FONTDETAILS              */
;/*       - pCharBuffer   : pointer in char buffer corresponds to    */
;/*                         first column in a row of clipped rect    */
;/*                                                                  */
;/* Exit  -  EAX             (no error: 0FFFFFFFFh  error: 0)        */
;/*                                                                  */
;/* Registers: EBX,ESI,EDI,DS,ES -- will be preserved                */
;/********************************************************************/

;/********************************************************************/
;/* epoch_update_cache_charrect                                      */
;/*                                                                  */
;/* This subroutine ensures all 2 byte cell characters in a row      */
;/* (Epoch format) of charrect that is about to be drawn are cached. */
;/* This routine has capability to handle DBCS character codepoints, */
;/* add to SBCS character codepoint handling.                        */
;/*                                                                  */
;/* Entry - pfdBaseFont   : pointer to base FONTDETAILS              */
;/*       - pCharBuffer   : pointer in char buffer corresponds to    */
;/*                         first column in a row of clipped rect    */
;/*                                                                  */
;/* Exit  -  EAX             (no error: 0FFFFFFFFh  error: 0)        */
;/*                                                                  */
;/* Registers: EBX,ESI,EDI,DS,ES -- will be preserved                */
;/********************************************************************/

        align   4

ifdef   AVIO_CGA_TEXT
cProc update_cache_charrect_2,<PUBLIC>,<ebx,esi,edi,ds,es>
endif ; AVIO_CGA_TEXT

ifdef   AVIO_MFI_TEXT
cProc update_cache_charrect_4,<PUBLIC>,<ebx,esi,edi,ds,es>
endif ; AVIO_MFI_TEXT

ifdef   AVIO_DBCS_TEXT
cProc common_update_cache_charrect,<PUBLIC>,<ebx,esi,edi,ds,es>
endif ; AVIO_DBCS_TEXT

ifdef   AVIO_EPOCH_TEXT
cProc epoch_update_cache_charrect,<PUBLIC>,<ebx,esi,edi,ds,es>
endif ; AVIO_CGA_TEXT

        parmD   pfdBaseFont
        parmD   pCharBuffer
        localD  numColumn
        localD  pfdLcidFont
        localD  ulLastChar
        localD  ulLastCharAddr
        localD  bMoveBack
        localD  bMoveFore
        localD  arrIndex
        localB  bNumCell
ifdef _8514
        localW  LastCharFpo
endif ; _8514
ifdef BPP24
        localD  LastCharIdx
endif ; BPP24
cBegin

        ;/************************************************************/
        ;/* Setup for starting                                       */
        ;/************************************************************/
        movzx   eax,AIxfer.bNumOfColumn ; load number of column
        mov     numColumn,eax           ; set it to internal counter
        mov     arrIndex,0              ; reset array index

        mov     ulLastChar, -1          ; force setup first time
        mov     ulLastCharAddr,-1       ; force setup first time

        ;/************************************************************/
        ;/* we are at the first column in a row. we have to          */
        ;/* determine type of this cell, SBCS/DBCSLeading            */
        ;/* /DBCSTrailing by calling IniCheckCellType2.              */
        ;/************************************************************/
        push    pCharBuffer             ; ptr in char buffer
        push    pfdBaseFont             ; ptr to base fontdetails
;TMP    sub     eax,eax                 ; indicate caller
        call    IniCheckCellType
        add     esp,8
ifndef  AVIO_HAS_LCID
        mov     edx, pfdBaseFont
endif ; AVIO_HAS_LCID
        mov     pfdLcidFont, edx        ; updated fontdetails
        or      eax,eax                 ; SBCS column?
        jz short uc_ini_sbcs_cell       ; yes
        cmp     eax,1                   ; DBCSLeading?
        je short uc_ini_dl_cell         ; yes
        cmp     eax,2                   ; DBCSTrailing?
        je  short uc_ini_dt_cell        ; yes
        cmp     eax,-1                  ; invalid dl?
        je  short uc_ini_dl_inv         ; yes
        jmp short uc_ini_dt_inv         ; invalid dt

uc_ini_sbcs_cell:
        ;/************************************************************/
        ;/* first column is SBCS.                                    */
        ;/************************************************************/
        mov     bNumCell,1              ; we'll check 1 cell
        mov     edx,arrIndex
        mov     CTArray[edx],al
        jmp short uc_ini_check_cached   ; go checking

uc_ini_dl_cell:
        ;/************************************************************/
        ;/* First column is DBCSLeading.                             */
        ;/************************************************************/
        mov     bNumCell,2              ; we'll check 2 cells
        mov     bMoveBack,0             ; no, we can construct DBCS cp
        mov     edx,arrIndex
        mov     CTArray[edx],al
        inc     edx
        inc     eax
        mov     CTArray[edx],al
        jmp short uc_ini_check_cached   ; go checking

uc_ini_dt_cell:
        ;/************************************************************/
        ;/* first column is DBCSTrailing                             */
        ;/************************************************************/
        mov     bNumCell,1              ; we'll check 1 cell
        mov     bMoveBack,(MOVE_CELL SHL 1) ; to move back one cell
        mov     edx,arrIndex            ; 
        mov     CTArray[edx],al         ; 
        jmp short uc_ini_check_cached   ; go checking

uc_ini_dl_inv:
        ;/************************************************************/
        ;/* First column is Invalid DBCSLeading.                     */
        ;/************************************************************/
        mov     bNumCell,2              ; we'll check 2 cells
        mov     bMoveBack,0             ; no, we can construct DBCS cp
        mov     edx,arrIndex
        sub     eax,eax                 ; indicate SBCS
        mov     CTArray[edx],al
        inc     edx
        mov     CTArray[edx],al
        jmp short uc_ini_check_cached   ; go checking

uc_ini_dt_inv:
        ;/************************************************************/
        ;/* first column is Invalid DBCSTrailing                     */
        ;/************************************************************/
        mov     bNumCell,1              ; we'll check 1 cell
        mov     bMoveBack,(MOVE_CELL SHL 1) ; to move back one cell
        mov     edx,arrIndex
        sub     eax,eax                 ; indicate SBCS
        mov     CTArray[edx],al

uc_ini_check_cached:
        ;/************************************************************/
        ;/* now check cached or not                                  */
        ;/************************************************************/
        push    ebx                     ; to aviod to be corrupted
        push    esi                     ; regsters..
        push    edi

        mov     ulLastChar,ecx          ; save it

ifdef   AVIO_HAS_LCID
        and     ecx, 00000ffffh         ; mask high-word
endif ; AVIO_HAS_LCID

        push    ecx                     ; codepoint
        push    pfdLcidFont             ; FONTDETAILS
        call    _AvioForceCharInCache   ; cache it
                                        ; (EAX holds char image index in cache)
                                        ; (C routine _AvioForceCharInCache
                                        ; seemes to clear pushed arguments)
        add     esp,8
        pop     edi                     ; restore registers...
        pop     esi
        pop     ebx

        cmp     eax,0FFFFFFFFh          ; caching succeeded?
        je update_error_exit            ; no, exit at once

uc_ini_store_charimage_addr:
        ;/************************************************************/
        ;/* Char image must be cached. It should not fail.           */
        ;/* Save char address in char iamge address array.           */
        ;/************************************************************/
        mov     edi, eax                ; to preserve char image index
        mov     ecx, pfdLcidFont
        movzx   ecx, [ecx].usCachedFontIndex
        mov     eax, SIZE FontCacheInfo
        mul     ecx
        mov     esi, _pFontCacheInfo
        add     esi, eax
        mov     eax,[esi].fci_aulCachedCharOffset[edi*4]
                                        ; get address of char image in cache
        mov     ulLastCharAddr,eax      ; also save into local var

ifdef BPP24
        mov     LastCharIdx, edi
endif ; BPP24

ifdef _8514
        mov     dx,[esi].fci_ausFontPlaneOffset[edi*2]
        cmp     dx,-1                   ; are we in 16 bit color?
        jz short @f                     ; no

        and     dx,1                    ; just in case
        shl     dx,3                    ; 0 -> 0, 1 -> 8
        add     cx,dx
@@:
        mov     LastCharFpo, cx
endif ; _8514

        cmp     bNumCell,2              ; address for DBCS char?
        je short uc_ini_store_2times    ; yes, store for DBCSLeading &
                                        ; DBCSTrailing

        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; no, so store for SBCS char
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24
        jmp short uc_ini_sbcs_check_exhaust_row

uc_ini_store_2times:
        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; store for DBCSLeading
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24
        inc     arrIndex
        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; store for DBCSTrailing
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24


uc_ini_dbcs_check_exhaust_row:
        ;/************************************************************/
        ;/* Here we should check this row is exhausted, bacause we   */
        ;/* allow one cell row.                                      */
        ;/************************************************************/
        mov     eax,bMoveBack
        sub     pCharBuffer,eax         ; adjust for backward move
        add     pCharBuffer,(BYTE_PER_CELL SHL 1) ; we checked 2 cells
        shr     bMoveBack,MOVE_CELL     ; number of cell backed
        mov     eax,bMoveBack
        add     numColumn,eax           ; adjust for backward move
        sub     numColumn,2             ; because checked 2 cells
        jle     ok_exit                 ; yes, go for prepare exiting
        jmp short uc_rest_of_cells      ; go checking rest of cells

uc_ini_sbcs_check_exhaust_row:
        add     pCharBuffer,BYTE_PER_CELL ; we checked 1 cell
        dec     numColumn               ; exhaust cell?
        jz      ok_exit                 ; yes, go for prepare exiting

uc_rest_of_cells:
        ;/************************************************************/
        ;/* Now check rest cells in a row until we exhaust them      */
        ;/************************************************************/
        inc     arrIndex                ; increase index in array
        push    pCharBuffer             ; ptr in char buffer
        push    pfdBaseFont             ; ptr to base fontdetails
;TMP    sub     eax,eax                 ; indicate caller
        call    CheckCellType
        add     esp,8
        or      eax,eax                 ; SBCS column?
        jz  short uc_sbcs_cell          ; yes
        cmp     eax,1                   ; DBCSLeading?
        je  short uc_dl_cell            ; yes
        jmp short uc_dl_inv             ; invalid dl

uc_sbcs_cell:
        ;/************************************************************/
        ;/* this cell is SBCS                                        */
        ;/************************************************************/
        mov     bNumCell,1              ; we'll check 1 cell
        mov     bMoveFore,0             ; no moving to forward
        mov     edx,arrIndex
        mov     CTArray[edx],al
        jmp short uc_check_cached

uc_dl_cell:
        ;/************************************************************/
        ;/* this cell is DBCSLeading.                                */
        ;/************************************************************/
        mov     bNumCell,2              ; we'll check 1 cell
        mov     bMoveFore,(MOVE_CELL SHL 1) ; indicate 2/4 byte move forward
        mov     edx,arrIndex
        mov     CTArray[edx],al
        inc     edx
        inc     eax
        mov     CTArray[edx],al
        jmp short uc_check_cached

uc_dl_inv:
        ;/************************************************************/
        ;/* this cell is Invalid DBCSLeading.                        */
        ;/************************************************************/
        mov     bNumCell,2              ; we'll check 2 cell
        mov     bMoveFore,(MOVE_CELL SHL 1) ; indicate 2/4 byte move forward
        mov     edx,arrIndex
        sub     eax,eax                 ; indicate SBCS
        mov     CTArray[edx],al
        inc     edx
        mov     CTArray[edx],al

uc_check_cached:
        ;/************************************************************/
        ;/* now check cached or not                                  */
        ;/************************************************************/
        cmp     ecx,ulLastChar          ; same cp as last char?
        jne short uc_different_cp       ; no, check cached or not
        mov     eax,ulLastCharAddr      ; same cp, so get last char
                                        ; index
ifdef _8514
        mov     cx, LastCharFpo
endif ; _8514
ifdef BPP24
        mov     edi, LastCharIdx
endif ; BPP24
        jmp short uc_store_same_addr

uc_different_cp:
        ;/************************************************************/
        ;/* It's different cp from last char. Check if cached or not */
        ;/************************************************************/
        push    ebx
        push    esi
        push    edi

        mov     ulLastChar,ecx          ; save it

ifdef   AVIO_HAS_LCID
        and     ecx, 00000ffffh         ; mask high-word
endif ; AVIO_HAS_LCID

        push    ecx                     ; codepoint
        push    pfdLcidFont             ; FONTDETAILS
        call    _AvioForceCharInCache   ; cache it
                                        ; (EAX holds char image index in cache)
                                        ; (C routine _AvioForceCharIn Cache
                                        ; seemes to clear pushed arguments)
        add     esp,8

        pop     edi                     ; restore registers...
        pop     esi
        pop     ebx

        cmp     eax,0FFFFFFFFh          ; caching succeeded?
        je update_error_exit            ; no, exit at once
;        je short update_error_exit      ; no, exit at once

uc_store_charimage_addr:
        ;/************************************************************/
        ;/* Char image should have been cached. It should not fail.  */
        ;/* Now store char image address for this char.              */
        ;/************************************************************/
        mov     edi, eax                ; to preserve char image index
        mov     ecx, pfdLcidFont
        movzx   ecx, [ecx].usCachedFontIndex
        mov     eax, SIZE FontCacheInfo
        mul     ecx
        mov     esi, _pFontCacheInfo
        add     esi, eax
        mov     eax,[esi].fci_aulCachedCharOffset[edi*4]
                                        ; get address of char image in cache
        mov     ulLastCharAddr,eax      ; also save in local var

ifdef BPP24
        mov     LastCharIdx, edi
endif ; BPP24

ifdef _8514
        mov     dx,[esi].fci_ausFontPlaneOffset[edi*2]
        cmp     dx,-1                   ; are we in 16 bit color?
        jz short @f                     ; no

        and     dx,1                    ; just in case
        shl     dx,3                    ; 0 -> 0, 1 -> 8
        add     cx,dx
@@:
        mov     LastCharFpo, cx
endif ; _8514

uc_store_same_addr:
        cmp     bNumCell,2              ; address for DBCS char?
        je short uc_store_2times        ; yes, store for DBCSLeading &
                                        ; DBCSTrailing

        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; no, so store for SBCS char
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24
        jmp short uc_check_exhaust_row

uc_store_2times:
        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; store for DBCSLeading
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24
        inc     arrIndex
        mov     edx,arrIndex
        mov     CIAArray[edx*4],eax     ; store for DBCSTrailing
ifdef _8514
        mov     CfpoArray[edx], cl
endif ; _8514
ifdef BPP24
        mov     CIndexArray[edx*4], edi
endif ; BPP24

uc_check_exhaust_row:
        add     pCharBuffer,BYTE_PER_CELL ; at least we checked one cell
        mov     eax,bMoveFore
        add     pCharBuffer,eax         ; in case we checked DBCS char
        shr     bMoveFore,MOVE_CELL     ; change to num of cell
        dec     numColumn               ; at least we checked one cell
        mov     eax,bMoveFore
        sub     numColumn,eax           ; in case we checked DBCS char
        jle short ok_exit               ; yes, so prepare to exit
        jmp uc_rest_of_cells            ; no, so go for check next cell

ok_exit:
        call    _eddt_TidyUpAfterCaching ; allow the caching code to
                                        ; tidy up

        mov     eax,0FFFFFFFFh          ; indicate success
        jmp short exit

update_error_exit:
        sub     eax,eax                 ; indicate failure
exit:

cEnd

_TEXT           ends

END

