;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;       SCCSID = @(#)celldraw.asm       6.1 89/06/26
        page    ,132
;---------------------------Module-Header-------------------------------;
; Module Name: CELLDRAW.INC
;
; Abstract:  This module contains drawing functions which materialize
;            the image of a logical video buffer based on pseudocode
;            placed in the stack by routines from the CellScan.asm
;            module.
;
; Created:  26-Jun-87
; Author:   ronm
;
;
;
;
; Description:
;
;         Extracted from celldraw.asm, because too much modifications
;         are necessary to support DBCS device fonts - Soh Ohta
;
;-----------------------------------------------------------------------;

;---------------------------Private Routine-----------------------------;
; GetAVioAttributes
;
; Convert miscellenious attribute format to AVio format.
; We will check current PS format and interpret color attributes
; as nessesary.
;
; Entry:
;       ESI = cell attribute to be translated to AVio attributes.
;       EBP = CharRect frame
; Returns:
;       ESI = AVio compatible cell attributes
; Error Returns:
;       None
; Registers Destroyed:
;       EAX,FLAGS
; Registers Preserved:
;       EAX,EBX,EDX,EBP,EDI
; Calls:
;       None
; History:
;  Thu 26-Dec-90 20:00:00 -by Soh Ohta [soh]
; Wrote it!
;-----------------------------------------------------------------------;

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;ALIGN 4
define_CharRect_frame   GetAVioAttributes

 push ecx

ifdef IBMJ  ; IBM-Japan Vio attribute support                           ;IBMJ

; Translate IBM Japan unique attributes to common DBCS format.

        cmp     FormatID,FORMATID_IBMJ_COLOR
        je      ps_ibmj_vio
        cmp     FormatID,FORMATID_IBMJ_MONO
        je      ps_ibmj_vio
        jmp     have_attributes

ps_ibmj_vio:
        mov     ecx,esi                 ; CH = IBM-Japan Vio attribute bits
        xor     esi,esi                 ; SI = AVio compatible attributes

        test    ch,IBMJVioVerticalGridMask
        jz      @f
        or      esi,AVioVerticalGridMask
@@:     test    ch,IBMJVioHorizontalGridMask
        jz      @f
        or      esi,AVioHorizontalGridMask
@@:     cmp     FormatID,FORMATID_IBMJ_COLOR
        jne     ps_mono

ps_color:
        or      esi,AVioColorRMask+AVioColorGMask+AVioColorBMask
        test    dQualifier,IBMJPhysHiLighted
        jz      @f
        or      esi,AVioColorIMask
@@:     test    ch,IBMJVioColorRoffMask
        jz      @f
        and     esi,not AVioColorRMask
@@:     test    ch,IBMJVioColorGoffMask
        jz      @f
        and     esi,not AVioColorGMask
@@:     test    ch,IBMJVioColorBoffMask
        jz      @f
        and     esi,not AVioColorBMask
@@:     test    ch,IBMJVioReverseVideoMask
        jz      have_attributes
        or      esi,AVioReverseVideoMask
        jmp     have_attributes

ps_mono:
        or      esi,AVioColorRMask+AVioColorGMask+AVioColorBMask+AVioColorIMask
        and     ch,IBMJVioInvisibleMask
        cmp     ch,IBMJVioInvisibleMask
        jne     @f
        and     esi,not (AVioColorRMask+AVioColorGMask+AVioColorBMask+AVioColorIMask)
        jmp     have_attributes

@@:     mov     cl,MM_ALL               ; white
        test    ch,IBMJVioIntensityMask
        jnz     @f
        and     cl,bPhysColor           ; specified color
        and     esi,not AVioColorIMask
@@:     mov     bCellColor,cl           ; color used for mono text
        test    ch,IBMJVioReverseVideoMask
        jz      @f
        or      esi,AVioReverseVideoMask
@@:     test    ch,IBMJVioUnderscoreMask
        jz      have_attributes
        or      esi,AVioUnderscoreMask

have_attributes:
endif;IBMJ                                                              ;IBMJ

filter_horz_grid:
        mov     bHorzGridMask,0
        test    esi,AVioHorizontalGridMask
        jz      filter_vert_grid
        and     esi,(NOT AVioHorizontalGridMask)
        cmp     wTopLineOffset,0
        jne     filter_vert_grid
        or      esi,AVioHorizontalGridMask
        mov     bHorzGridMask,0FFh      ; horizontal grid pattern

filter_vert_grid:
        mov     bVertGridMask,0
        test    esi,AVioVerticalGridMask
        jz      save_attributes
        and     esi,(NOT AVioVerticalGridMask)
        cmp     wLeftLineOffset,0
        jne     save_attributes
        or      esi,AVioVerticalGridMask
        mov     bVertGridMask,080h      ; vertical grid pattern

save_attributes:
        mov     wAVioAttributes,esi

 pop ecx
        ret

GetAVioAttributes       endp

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

        SUBTITLE        GetFontOffset8
        PAGE +

;---------------------------Private Routine-----------------------------;
; GetFontOffset8
;
; Get effective font offset for specified pseudo code of 8 wide cells.
; Be sure that the pseudo code must be the DBCS cell indicators.
;
; Entry:
;       ESI = pseudo code
; Returns:
;       ESI = effective font offset
; Registers Destroyed:
;       none.
; Registers Preserved:
;       EAX,EBX,ECX,EDX,EBP,EDI
; Calls:
;       None
; History:
;  Wed 14-Aug-1991 -by-  Soh Ohta [jl09057 @ ymtvm3]
; Subroutinized to reduce actual code size.
;-----------------------------------------------------------------------;

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;ALIGN 4
define_CharRect_frame   GetFontOffset8

        and     esi,not PSEUDO_DBCS_1ST ; get array (cb_adbcschar) index
        test    esi,1                   ; odd number ?
        jnz     gfo8_dbcs_2nd           ;   means DBCS trailing byte

gfo8_dbcs_1st:                          ; DBCS leading byte
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
        imul    esi,esi,6
        push    ebp
        mov     ebp,CellBLTBlock.cb_BPSaveSlot
        add     esi,wselfontsave                ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        pop     ebp
        ret

gfo8_dbcs_2nd:                          ; DBCS trailing byte
        dec     esi
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
        imul    esi,esi,6
        push    ebp
        mov     ebp,CellBLTBlock.cb_BPSaveSlot
        add     esi,wselfontsave                ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        pop     ebp
        add     esi,CellBLTBlock.cb_dbcs_2nd
                                        ; ESI --> DBCS 2nd byte font address
        ret

GetFontOffset8          endp

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

        SUBTITLE AVioDrawText
        PAGE +
;***************************** Private Function ******************************
;    Function: AVioDrawText                                                  *
;      Author: Kenton E. Zahrt                                               *
;        Date: December 13, 1991                                             *
;----------------------------------------------------------------------------*
; Description:                                                               *
;   Interprets pseudo code on the stack to draw Vio character cell images    *
;   with possible horizontal clipping, but no underscoring.                  *
;----------------------------------------------------------------------------*
; C Prototype:                                                               *
;                                                                            *
;    where:                                                                  *
;       EBX -- Destination X coordinate                                      *
;       EDI -- Destination Y coordinate                                      *
;       ESP -- Pseudocode pointer.  This points to the next pseudo code      *
;              syllable to process.                                          *
;                                                                            *
;  Return values:                                                            *
; Registers Destroyed:
;       ???
; Registers Preserved:
;       None
;----------------------------------------------------------------------------*
; Functions called:                                                          *
;   External:                                                                *
;     None                                                                   *
;   Local:                                                                   *
;     None                                                                   *
;----------------------------------------------------------------------------*
; Revision history:                                                          *
;   PTR/DCR    Date    Who  Remarks                                          *
;   -------  --------  ---  ------------------------------------------------ *
;    Orig.   12/13/91  KEZ  Original                                         *
;*****************************************************************************

define_CharRect_frame   DrawText

        public  AVioDrawText
AVioDrawText::

        CLD

        XOR     EAX,EAX         ; No mode set
        MOV     wModeSet,AX     ; Remember no modeset
        MOV     wX,EBX          ; EBX = Destination X for this column
        MOV     wY,EDI          ; EDI = Destination Y for this column

;JMW Begin *******************************************************************
        mov     bx,wColor
        cmp     bx,lookup_table_color
        jz      Process_pseudo_code
        mov     lookup_table_color,bx
        mov     edi,offset lookup_table
        mov     dl,255
@@:
 mov ch,dl

 rept 8
 mov ax,bx ; al = BG color, ah = FG color
 shl ch,1 ; get left side bit ON/OFF
 sbb cl,cl ; ON: cl = 0FFH, OFF: cl = 0
 and cl,8 ; ON: cl = 8,  OFF: cl = 0
 shr ax,cl ; ON: al = FG color, OFF: al = BG color
 stosb  ; put color
 endm

 dec dl
 jnz @B

        mov     al,bl
        mov     ah,bl
        shl     eax,16
        mov     al,bl
        mov     ah,bl
        stosd
        stosd
;JMW End *********************************************************************

; ---------------------------------------------------------------------------+
; Get next value from stack into SI                                          |
; If SI is non-negative, it's a glyph index.  Negative values denote control |
; actions:                                                                   |
;                                                                            |
;    -1 => A signal to return control to InterpretAttributes.                |
;    -2 => The end of a row of cell images has been reached.  Move to the    |
;          beginning of the next row.                                        |
;----------------------------------------------------------------------------+

        PUBLIC  Process_pseudo_code
Process_pseudo_code::
        POP     ESI                     ; Fetch glyph index
ifdef  JTUNE        ;IBMJ
 MOV CellBLTBlock.dLastPseudoCode,ESI
endif ;JTUNE        ;IBMJ
        MOVSX   ESI,SI
        SUB     ESI,wFirstGlyph         ; Subtract the lowest defined glyph
        CMP     ESI,wGlyphSpan          ; Check against number of defined
                                        ; glyphs
        JB      Have_glyph_index        ; Jump if in range

; Glyph index is out of range - use default if not control code.

        ADD     ESI,wFirstGlyph         ; Add back in lowest defined glyph
        JS      @f                      ; Signed value is control code
        MOV     ESI,wDefaultGlyph       ; Use default value
        JMP     Have_glyph_index        ; and skip to process

; Check for -1 value meaning end of string (attribute or return)

@@:
        cmp     esi,-1                  ;;; -1 => an attribute or return addr.
        je      next_attribute          ;;;
        cmp     esi,-2                  ;;; -2 => goto the next row
        je      Next_row                ;;;
        push    OFFSET have_font_offset ;;;
        jmp     GetFontOffsetNS         ;;; get DBCS font image offset

next_attribute:                         ;;;
        MOV     EBX,wX                  ; Restore EBX = dest X
        MOV     EDI,wY                  ; Restore EDI = dest Y

        DebugMsgKZ <Leaving AVioDrawText>

        JMP     Next_attribute_cluster2 ; Need to return to attribute
                                        ; processing

; Still negative - assume -2 = new line. Bump addresses and get next code.

        PUBLIC  Next_row
Next_row::
        MOV     EAX,wDest3rdIncr        ; X decrement to start of row
        SUB     wX,EAX                  ; Adjust x
        MOVZX   EAX,wCellHeight         ; Get cell height
        ADD     wY,EAX                  ; Adjust y
        JMP     Process_pseudo_code     ; and fetch next code

; Have a valid glyph index to process

        PUBLIC  Have_glyph_index
Have_glyph_index::

 mov eax,esi   ;;;
 shl esi,2   ;;;
 add eax,eax   ;;;
 add esi,eax   ;;; glyph entries are 6 bytes
        add     esi,wselfontsave        ;;; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits  ;;;
        add     esi,wselfontsave        ;;; ESI --> Character bitmap
        xor     cl,cl                   ;;; phase align = 0

have_font_offset:
        mov     bFontRot0,cl            ;;;

;----------------------------------------------------------------------------+
; First, determine whether we are clear to draw 16 chars ahead without       |
; clipping.                                                                  |
;----------------------------------------------------------------------------+


; Calculate character block limits into EAX, EBX, ECX, EDX

        MOV     EAX,wX          ; Get X
        MOVZX   EBX,wCellWidth  ; Get cell width
 IMUL    EBX,EBX,16      ; Calculate end of block of 16 chars
        ADD     EBX,EAX         ; Add to start position
        DEC     EBX             ; Last pos
        MOV     ECX,wY          ; Get Y
        MOVZX   EDX,wCellHeight ; Subtract cell height from Y
        NEG     EDX
        ADD     EDX,ECX
        INC     EDX             ; Top row

; Determine whether clipped totally out.

        CMP     EBX,wClipXmin   ; Clipped out on l ?
        JL      Bclip_invis     ; Go if yes
        CMP     EAX,wClipXmax   ; Clipped out on r ?
        JGE     Bclip_invis     ; Go if yes
        CMP     ECX,wClipYmin   ; Clipped out at bottom ?
        JL      Bclip_invis     ; Go if yes
        CMP     EDX,wClipYmax   ; Clipped out at top ?
        JGE     Bclip_invis     ; Go if yes

; Determine whether clipped totally in.

        CMP     EAX,wClipXmin   ; Clipped in on l ?
        JL      Bclip_invis     ; Go if yes
        CMP     EBX,wClipXmax   ; Clipped in on r ?
        JGE     Bclip_invis     ; Go if yes
        CMP     EDX,wClipYmin   ; Clipped in at bottom ?
        JL      Bclip_invis     ; Go if yes
        CMP     ECX,wClipYmax   ; Clipped in at top ?
        JGE     Bclip_invis     ; Go if yes

;----------------------------------------------------------------------------+
; We are totally visible for 16 chars ahead, call routine to get going fast. |
;----------------------------------------------------------------------------+

        MOV     EAX,16                  ; Maximum character count to draw
        JMP     Draw_n_wide_noclip      ; Else jump to n wide unclipped

;----------------------------------------------------------------------------+
; The clip window intersects some part of a 16 character string starting     |
; here.  Determine whether this current character is clipped itself          |
;----------------------------------------------------------------------------+

        PUBLIC  Bclip_invis
Bclip_invis::

; Recalulate character box right edge.

        MOVZX   EBX,wCellWidth          ; Get cell width
        ADD     EBX,EAX                 ; Add to start position
        DEC     EBX                     ; Last pos

; Determine whether this character is clipped totally out.

        CMP     EBX,wClipXmin           ; Clipped out on l ?
        JL      Clipped_out              ; Go if yes

        CMP     EAX,wClipXmax           ; Clipped out on r ?
        JGE     Clipped_out              ; Go if yes

        CMP     ECX,wClipYmin           ; Clipped out at bottom ?
        JL      Clipped_out              ; Go if yes

        CMP     EDX,wClipYmax           ; Clipped out at top ?
        JGE     Clipped_out             ; Go if yes

; Determine whether clipped totally in.

        CMP     EAX,wClipXmin           ; Clipped in on l ?
        JL      Clip_not_in             ; Go if yes

        CMP     EBX,wClipXmax           ; Clipped in on r ?
        JGE     Clip_not_in             ; Go if yes

        CMP     EDX,wClipYmin           ; Clipped in at bottom ?
        JL      Clip_not_in             ; Go if yes

        CMP     ECX,wClipYmax           ; Clipped in at top ?
        JGE     Clip_not_in             ; Go if yes

;----------------------------------------------------------------------------+
; We are totally visible for this char, call routine to draw it.             |
;----------------------------------------------------------------------------+

        MOV     EAX,1                   ; Maximum character count to draw
        JMP     Draw_n_wide_noclip      ; Else jump to n wide unclipped

;----------------------------------------------------------------------------+
; We have a character that needs some clip attention - call the routine.     |
;----------------------------------------------------------------------------+

        PUBLIC  Clip_not_in
Clip_not_in::
        JMP     Draw_n_wide_clip        ; Jump to draw clipped

;----------------------------------------------------------------------------+
; We have a character that is totally clipped out - update ptrs and continue.|
;----------------------------------------------------------------------------+

        PUBLIC  Clipped_out
Clipped_out::

; Bump horizontal address by cell width.

        MOVZX   EAX,wCellWidth          ; Get cell width
        ADD     wX,EAX                  ; Bump X value

; test for horizontal clip (?) - move to next row if yes.

        CMP     bHorizontalClipMask,0   ; Is this text clipped?
        JE      Process_pseudo_code     ;  N - Return to fetch next code
        JMP     Next_row                ;  Y - Return to fetch next code

;=============================================================================
; Draw any width character on arbitrary boundary clipped.                    |
;                                                                            |
; Characters of any width any any boundary and opaque or transparent are     |
; drawn clipped by this code. Character drawing will continue until either   |
; the block count reaches zero, or a non-glyph index value is found on the   |
; stack.                                                                     |
; ============================================================================

        PUBLIC  Draw_n_wide_clip
Draw_n_wide_clip::

; Calculate Byte address of first character to be drawn.

        MOV     EBX,wY                  ; Get y
        MOV     EAX,SCREEN_CBSCAN       ; Screen pitch in bytes
        MUL     EBX                     ; Result to EAX
        MOVSX   EBX,word ptr wX         ; Get x
        CMP     EBX,-1
        JLE     X_neg                   ; X negative

        ADD     EAX,EBX                 ; Add to line address

        PUBLIC  X_neg
X_neg::

        PUBLIC  Sv_byte_addr
Sv_byte_addr::

        ROR     EAX,16
        MOV     DL,AL                   ; isolate bank number
        MOV     Origin_bank,DL
        MOV     bColor,DL               ; save in a temp var in case char
        call    set_bank_select         ; straddles a bank boundary
        XOR     Al,AL                   ; remove bank # from address
        ROL     EAX,16                  ; restore address

        ADD     EAX,lpBitmapBits        ; Point to video memory
        MOV     wByteAddr,EAX           ; and save

; Calculate font address for glpyh.

;;;     MOVSX   ESI,SI
;;;     IMUL    ESI,ESI,6               ; Glyph entries are 6 bytes
;;;     ADD     ESI,wselfontsave        ; ESI --> Glyph description
;;;     MOV     ESI,[ESI].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
;;;                                     ; ESI --> Character data offset
;;;     ADD     ESI,wselfontsave        ; ESI -> Character bitmap

        MOVZX   EBX,wCellHeight         ; Load EBX with char height
        LEA     ESI,[ESI+EBX-1]         ; Move ESI to end of definition


; Now draw the character. Construct a shift count to handle
; left side clipping, and set the total number bytes writen
; to handle right side clipping

        XOR     DL,DL                   ; will hold left clip rotate count
        MOV     EBX,wX                  ; fetch x coord in case its negative
        MOVZX   ECX,wCellWidth          ; get max loop count
        MOV     DH,CL                   ; dh holds num pixels this column
        CMP     DH,8
        JBE     @F
        MOV     DH,8
@@:
        OR      EBX,EBX
        JNS     cxstart_ok
        ADD     ECX,EBX                 ; reduce width by amount off screen
        NEG     EBX
        MOV     DL,BL
        SUB     DH,DL
        XOR     EBX,EBX                 ; and set start x to 0

        public  cxstart_ok
cxstart_ok::

        MOV     EDI,wByteAddr           ; Get byte address
        CMP     EBX,wClipXmin           ; Compare with xmin
        JGE     cleft_clip_ok
        SUB     EBX,wClipXmin
        ADD     ECX,EBX                 ; reduce loop count by amount of left clip
        NEG     EBX
        ADD     EDI,EBX                 ; and adjust start addr to left border of clip rect
        ADD     DL,BL                   ; set right clip rotate count
        SUB     DH,BL                   ; and total pixels this column
        jae     @f                      ;CMVC_53383 @PRK
        mov     dh,cl                   ;CMVC_53383 @PRK 
@@:                                     ;CMVC_53383 @PRK 
        MOV     EBX,wClipXmin

cleft_clip_ok:

        ADD     EBX,ECX                 ; now add width and check right clip
        DEC     EBX
        SUB     EBX,wClipXmax           ; Compare with xmax
        JLE     cright_clip_ok
        SUB     ECX,EBX                 ; Reduce loop cnt by amount of right clip
        CMP     DH,CL                   ; this column less than total ?
        JBE     cright_clip_ok
        MOV     DH,CL

cright_clip_ok:

        PUSH    ESI
        SUB     CL,DH                   ; calc num pixels next column
;CMVC_53383 BEGIN @PRK
; PUSH ECX
ifdef   cross_seg
        push    edx
        xor     edx,edx
        mov     ax,di           ;Only need offset into bank for this
        mov     bx,SCREEN_CBSCAN
        div     bx
        mov     bx,dx
        pop     edx
else    ;cross_seg
        mov     ebx,edi
        and     ebx,03ffh
        ;This only works when the bytes per scanline = 1024
endif   ;cross_seg
        movzx   eax,dh
        add     ebx,eax
        sub     ebx,wClipXmax           ; Compare with xmax
        jl      @f
        xor     ecx,ecx                 ; Reduce loop cnt by amount of right clip
@@:
        cmp     ecx,ebx
        jbe     @f
        mov     ecx,ebx
@@:
        push    ecx
;CMVC_53383 END @PRK
        ADD     EAX,EDI                 ; calc start addr for next column
        PUSH    EAX
;;;     MOV     AX,wColor

 TEST wAVioAttributes,AVioVerticalGridMask  ;;;
 JZ @F      ;;;
 mov bAvioGridFuncOffset,AVIO_VERT_FUNC_OFFSET ;;;
 jmp chk_avio_attr_ok    ;;;
@@:        ;;;
 mov bAvioGridFuncOffset,0    ;;;
chk_avio_attr_ok:      ;;;

; now draw bottom line of this char column with underscore

        MOV     EBX,wY                  ; Get Y coordinate
        CMP     EBX,wClipYmin           ; Compare with ymin
        JL      done_underscore_line    ; Go if outside
        CMP     EBX,wClipYmax           ; Compare with ymax
        JGE     done_underscore_line    ; Go if outside
        MOV     CH,[ESI]                ; Read font
 mov cl,bFontRot0  ;;;
 or cl,cl   ;;;
 jz @F   ;;;
 movzx eax,wCellHeight  ;;;
 mov al,[esi+eax]  ;;;
 mov ah,ch   ;;;
 shl ax,cl   ;;;
 mov ch,ah   ;;;
@@:     ;;;
        MOV     AX,wColor  ;;;
        OR      CH,bUnderscoreMask      ; OR underscore
        PUSH    EDI
        MOV     CL,DL                   ; get rotate mask
        SHL     CH,CL
        CMP     wFunction,0
        JE @F     ;;;
 MOVZX EAX,DH     ;;;
 ADD AL,bAvioGridFuncOffset   ;;;
 PUSH EBX     ;;;
 CALL PutCharFontFuncTable[EAX*SIZE DWORD] ;;;
 POP EBX     ;;;
 JMP finis_underscore_line   ;;;
@@:       ;;;
 OR DH,DH     ;;;
 JZ finis_underscore_line   ;;;
        MOV     CL,DH                   ; get store count
usl_t_loop:
        SHL     CH,1
        JC      @F
        INC     EDI
usl_t_ctr:
        DEC     CL
        JNZ     usl_t_loop
        JMP     finis_underscore_line
@@:
        STOSB
        JMP     SHORT usl_t_ctr

finis_underscore_line:

        POP     EDI


done_underscore_line:


; Loop for remaining slices to do foreground first part.

        SHL     EDX,16
        MOV     DX,wCellHeight          ; OUTER Loop count = cell height
        DEC     DX                      ; Already did 1
        ROR     EDX,16                  ; GET BACK SHIFT AND INNER LOOP CNTS

        PUBLIC  CL_FG_Box_loop_1
CL_FG_Box_loop_1::

        DEC     EBX                     ; Y =Y - 1
        SUB     ESI,1                   ; Up one line
        MOV     EAX,SCREEN_CBSCAN       ; Up one line
        NEG     EAX
        CALL    Update_Bank

        CMP     EBX,wClipYmin           ; Compare with ymin
        JL      done_reg_line           ; Go if outside
        CMP     EBX,wClipYmax           ; Compare with ymax
        JGE     done_reg_line           ; Go if outside
        MOV     CH,[ESI]                ; Read font
 mov cl,bFontRot0  ;;;
 or cl,cl   ;;;
 jz @F   ;;;
 movzx eax,wCellHeight  ;;;
 mov al,[esi+eax]  ;;;
 mov ah,ch   ;;;
 shl ax,cl   ;;;
 mov ch,ah   ;;;
@@:     ;;;
        MOV     AX,wColor  ;;;
        PUSH    EDI
        MOV     CL,DL                   ; get rotate mask
        SHL     CH,CL
        CMP     wFunction,0
        JE @F     ;;;
 MOVZX EAX,DH     ;;;
 ADD AL,bAvioGridFuncOffset   ;;;
 PUSH EBX     ;;;
 CALL PutCharFontFuncTable[EAX*SIZE DWORD] ;;;
 POP EBX     ;;;
 JMP finis_reg_line    ;;;
@@:
        or      dh,dh                   ;CMVC_53468 @PRK
        je      finis_reg_line          ;CMVC_53468 @PRK 
        MOV     CL,DH                   ; get store count
regl_t_loop:
        SHL     CH,1
        JC      @F
        INC     EDI
regl_t_ctr:
        DEC     CL
        JNZ     regl_t_loop
        JMP     finis_reg_line
@@:
        STOSB
        JMP     SHORT regl_t_ctr

finis_reg_line:

        POP     EDI

 done_reg_line:

        ROR     EDX,16
 TEST wAVioAttributes,AVioHorizontalGridMask  ;;;
 JZ @F      ;;;
 CMP DX,2      ;;;
 JNE @F      ;;;
 MOV bAvioGridFuncOffset,AVIO_HORZ_FUNC_OFFSET ;;;
@@:        ;;;
        DEC     DX
        JZ      done_column
        ROR     EDX,16
        JMP     CL_FG_Box_loop_1        ; Loop

done_column:

        POP     EDI                     ; get addr. of last line next column
        POP     ECX
        POP     ESI                     ; recover font pointer
        JECXZ   CL_FG_Box_end           ; if all done then get out
        MOVZX   EDX,wCellHeight
        ADD     ESI,EDX                 ; point to last byte next column
        MOV     DL,bColor               ; see if we changed banks
        CMP     DL,Origin_bank
        JE      @f
        MOV     Origin_bank,DL
        CALL    set_bank_select
@@:
        MOV     DX,800H                 ; set new shift and store counts
        CMP     DH,CL
        JBE     @F
        MOV     DH,CL                   ; set final count
@@:
        JMP     cright_clip_ok

        PUBLIC  CL_FG_Box_end
CL_FG_Box_end::

; Bump horizontal address by cell width.

        MOVZX   EAX,wCellWidth          ; Get cell width
        ADD     wX,EAX                  ; Bump X value

; Test for horizontal clip (?) - move to next row if yes.

        CMP     bHorizontalClipMask,0   ; Is this text clipped?
        JE      Process_pseudo_code     ;  N - Jump to fetch next code
        JMP     Next_row                ;  Y - Return to fetch next code

;=============================================================================
; Draw any width characters on arbitrary boundary unclipped.                 |
;       ;                                                                    |
; Characters of any width and any boundary and opaque or transparent and     |
; drawn totally unclipped by this code. Drawing will continue until either   |
; the block count reaches zero, or a non-glyph index value is found on the   |
; stack.                                                                     |
; ============================================================================

        PUBLIC  Draw_n_wide_noclip
Draw_n_wide_noclip::

; Save character count.

        MOV     wCharCount,AX           ; Save char count

;;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 public special_case_chk
special_case_chk::
 test bUnderscoreMask,0ffh
 jnz not_special_case
 cmp wFunction,0
        je not_special_case
 test wAVioAttributes,AVioVerticalGridMask or AVioHorizontalGridMask
        jnz not_special_case
 movzx ecx,wCellWidth
 cmp cl,13
 ja not_special_case
 mov eax,SBCSSpecialFuncTable[ecx*4]
 mov pfnSBCSSpecialFunc,eax
 mov eax,DBCSSpecialFuncTable[ecx*4]
 mov pfnDBCSSpecialFunc,eax

        MOV     EBX,wY                  ; Get y
        MOV     EAX,SCREEN_CBSCAN       ; Screen pitch in bytes
        MUL     EBX                     ; Result to EAX
        MOV     EBX,wX                  ; Get x
        ADD     EAX,EBX                 ; Add to line address

        ROR     EAX,16
        MOV     DL,AL                   ; isolate bank number
        MOV     Origin_bank,DL
        MOV     bColor,DL               ; save in a temp var in case char
        call    set_bank_select         ; straddles a bank boundary
        XOR     Al,AL                   ; remove bank # from address
        ROL     EAX,16                  ; restore address

        ADD     EAX,lpBitmapBits        ; Point to video memory
        MOV     EDI,EAX

 movzx ebx,wCellHeight
 mov edx,ebx
 neg edx
 dec edx
 cmp bFontRot0,0
 jnz nw_dbcs_second_case  ;;;
ifdef  JTUNE        ;IBMJ
 TEST swFlags,SW_CT_DISABLE
 JNZ @F
 TEST CellBLTBlock.dLastPseudoCode,not EXT_CELL_SAME_CHAR
 JZ FG_Box_end2
@@:
endif ;JTUNE        ;IBMJ
 jmp pfnSBCSSpecialFunc  ;;;
nw_dbcs_second_case:    ;;;
 jmp pfnDBCSSpecialFunc  ;;;
not_special_case:
 mov pfnSBCSSpecialFunc,offset SpecialCase_Not_Available
 mov pfnDBCSSpecialFunc,offset SpecialCase_Not_Available
        mov     cl,bFontRot0                 ;;;
 jmp SpecialCase_Not_Available
;;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        PUBLIC  FG_Box_end3
FG_Box_end3::

; Bump horizontal address by cell width.

        MOV EAX,wDest1stIncr ; Get cell width
        ADD     wX,EAX                  ; Bump X value
 add di,word ptr wDest2ndIncr
 jnc @F
 xchg dl,Origin_bank
 inc dl
 call set_bank_select
 xchg dl,Origin_bank
 jmp @F

        PUBLIC  FG_Box_end2
FG_Box_end2::

; Bump horizontal address by cell width.

        MOV EAX,wDest1stIncr ; Get cell width
        ADD     wX,EAX                  ; Bump X value
 add di,ax
if ( SCAN_CNT eq 480 ) or ( SCAN_CNT eq 600 )
 jnc @F
 xchg dl,Origin_bank
 inc dl
 call set_bank_select
 xchg dl,Origin_bank
 jmp @F
endif
@@:
; Test for horizontal clip (?) - move to next row if yes.

        CMP     bHorizontalClipMask,0   ; Is this text clipped?
        JNE     Next_row                ;  Y - Jump to force new row

; Check character count, return if zero else decrement.

        DEC     wCharCount              ; Dec and test character count
        JZ Process_pseudo_code     ; Return to fetch next code

; Fetch glyph code - check for valid index value.

        PUBLIC  Draw_n_wide_noclip_next
Draw_n_wide_noclip_next::
        POP     ESI                     ; Get glyph index
ifdef  JTUNE        ;IBMJ
 TEST swFlags,SW_CT_DISABLE
 JNZ @F
 TEST ESI,not EXT_CELL_SAME_CHAR
 JZ FG_Box_end2
@@:
endif ;JTUNE        ;IBMJ
        MOVSX   ESI,SI
        SUB     ESI,wFirstGlyph         ; Subtract the lowest defined glyph
        CMP     ESI,wGlyphSpan          ; Check against number of defined
                                        ; glyphs
        JAE     Draw_nw_out_of_range    ; Jump if in range

; Valid glyph index - Calculate address of font.

        PUBLIC  Draw_nw_glyph_ok
Draw_nw_glyph_ok::

 mov eax,esi   ;;;
 shl esi,2   ;;;
 add esi,eax   ;;;
 add esi,eax   ;;; glyph entries are 6 bytes
        ADD     ESI,wselfontsave        ; ESI --> Glyph to use
        MOV     ESI,[ESI].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
                                        ; ESI --> character data offset
        ADD     ESI,wselfontsave        ; ESI -> Character bitmap
 jmp pfnSBCSSpecialFunc ;;;

Draw_nw_out_of_range:
        ADD     ESI,wFirstGlyph         ; Add back in lowest defined glyph
        JNS     NW_default_glyph    ; Unsigned value is non-control code
        cmp     esi,-2                       ;;;
        jae     nw_its_control               ;;;
        and     esi,not PSEUDO_DBCS_1ST ; get array (cb_adbcschar) index
        test    esi,1                   ; odd number ?
        jnz     nw_dbcs_2nd             ;   means DBCS trailing byte
nw_dbcs_1st:                            ; DBCS leading byte
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
 mov eax,esi   ;;;
 shl esi,2   ;;;
 add esi,eax   ;;;
 add esi,eax   ;;; glyph entries are 6 bytes
        add     esi,wselfontsave        ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        xor     cl,cl                   ; phase align = 0
 jmp pfnSBCSSpecialFunc ;;;
nw_dbcs_2nd:                            ; DBCS trailing byte
        dec     esi
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
 mov eax,esi   ;;;
 shl esi,2   ;;;
 add esi,eax   ;;;
 add esi,eax   ;;; glyph entries are 6 bytes
        add     esi,wselfontsave        ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        add     esi,CellBLTBlock.cb_dbcs_2nd
                                        ; ESI --> DBCS 2nd byte font address
        mov     cl,bCellWidth           ; phase align = for DBCS 2nd byte
 and cl,7
 jmp pfnDBCSSpecialFunc ;;;

; Control code - put pcode back on stack and return to process.

        PUBLIC  NW_default_glyph
NW_default_glyph::
        MOV     ESI,wDefaultGlyph       ; Use default value
        JMP     Draw_nw_glyph_ok        ; Jump if in range

nw_its_control:                              ;;;

        PUSH    ESI                     ; Return code to stack
        JMP     Draw_NW_Exit            ; and exit

 public SpecialCase_Not_Available ;;;
SpecialCase_Not_Available::   ;;;

        MOV     wFontPtr0,ESI           ; Save
        mov     bFontRot0,cl            ;;;

        MOVZX   EAX,wCellHeight         ; Load EAX with char height
        LEA     ESI,[ESI+EAX-1]         ; Move ESI to end of definition

; Calculate Byte address of first character to be drawn.

        MOV     ECX,wY                  ; Get y
        MOV     EAX,SCREEN_CBSCAN       ; Screen pitch in bytes
        MUL     ECX                     ; Result to EAX
        MOV     ECX,wX                  ; Get x
        ADD     EAX,ECX                 ; Add to line address

        ROR     EAX,16
        MOV     DL,AL                   ; isolate bank number
        MOV     Origin_bank,DL
        MOV     bColor,DL               ; save in a temp var in case char
        call    set_bank_select         ; straddles a bank boundary
        XOR     Al,AL                   ; remove bank # from address
        ROL     EAX,16                  ; restore address

        ADD     EAX,lpBitmapBits        ; Point to video memory
        MOV     EDI,EAX

        MOVZX   ECX,wCellWidth          ; get max loop count

        MOV     DH,CL                   ; dh holds num pixels this column
        CMP     DH,8
        JBE     @F
        MOV     DH,8
@@:
nc_outer_loop:

 TEST wAVioAttributes,AVioVerticalGridMask  ;;;
 JZ @F      ;;;
 mov bAvioGridFuncOffset,AVIO_VERT_FUNC_OFFSET ;;;
 jmp nc_chk_avio_attr_ok    ;;;
@@:        ;;;
 mov bAvioGridFuncOffset,0    ;;;
nc_chk_avio_attr_ok:      ;;;

        PUSH    ESI                     ; SAVE FONT ADDR
        SUB     CL,DH                   ; calc num pixels next column
        PUSH    ECX
        MOVZX   EAX,DH
        ADD     EAX,EDI                 ; calc start addr for next column
        PUSH    EAX
;;;     MOV     AX,wColor

; now draw bottom line of this char column with underscore

        MOV     CH,[ESI]                ; Read font
 mov cl,bFontRot0  ;;;
 or cl,cl   ;;;
 jz @F   ;;;
 movzx eax,wCellHeight  ;;;
 mov al,[esi+eax]  ;;;
 mov ah,ch   ;;;
 shl ax,cl   ;;;
 mov ch,ah   ;;;
@@:     ;;;
        MOV     AX,wColor  ;;;
        OR      CH,bUnderscoreMask      ; OR underscore
        PUSH    EDI
        CMP     wFunction,0
        JE @F     ;;;
 MOVZX EAX,DH     ;;;
 ADD AL,bAvioGridFuncOffset   ;;;
 PUSH OFFSET nc_finis_underscore_line  ;;;
 JMP PutCharFontFuncTable[EAX*SIZE DWORD] ;;;
@@:       ;;;
 OR DH,DH     ;;;
 JZ nc_finis_underscore_line  ;;;
        MOV     CL,DH                   ; get store count
nc_usl_t_loop:
        SHL     CH,1
        JC      @F
        INC     EDI
nc_usl_t_ctr:
        DEC     CL
        JNZ     nc_usl_t_loop
        JMP     nc_finis_underscore_line
@@:
        STOSB
        JMP     SHORT nc_usl_t_ctr

nc_finis_underscore_line:

        POP     EDI


nc_done_underscore_line:


; Loop for remaining slices to do foreground first part.

        SHL     EDX,16
        MOV     DX,wCellHeight          ; OUTER Loop count = cell height
        DEC     DX                      ; Already did 1
        ROR     EDX,16                  ; GET BACK SHIFT AND INNER LOOP CNTS

        PUBLIC  FG_Box_loop_1
FG_Box_loop_1::

        SUB     ESI,1                   ; Up one line
        MOV     EAX,SCREEN_CBSCAN       ; Up one line
        NEG     EAX
        CALL    Update_Bank

        MOV     CH,[ESI]                ; Read font
 mov cl,bFontRot0  ;;;
 or cl,cl   ;;;
 jz @F   ;;;
 movzx eax,wCellHeight  ;;;
 mov al,[esi+eax]  ;;;
 mov ah,ch   ;;;
 shl ax,cl   ;;;
 mov ch,ah   ;;;
@@:     ;;;
        MOV     AX,wColor  ;;;
        PUSH    EDI
        CMP     wFunction,0
        JE @F     ;;;
 MOVZX EAX,DH     ;;;
 ADD AL,bAvioGridFuncOffset   ;;;
 PUSH OFFSET nc_finis_reg_line  ;;;
 JMP PutCharFontFuncTable[EAX*SIZE DWORD] ;;;
@@:       ;;;
 OR DH,DH     ;;;
 JZ nc_finis_reg_line   ;;;
        MOV     CL,DH                   ; get store count
nc_regl_t_loop:
        SHL     CH,1
        JC      @F
        INC     EDI
nc_regl_t_ctr:
        DEC     CL
        JNZ     nc_regl_t_loop
        JMP     nc_finis_reg_line
@@:
        STOSB
        JMP     SHORT nc_regl_t_ctr

nc_finis_reg_line:

        POP     EDI

nc_done_reg_line:

        ROR     EDX,16
 TEST wAVioAttributes,AVioHorizontalGridMask  ;;;
 JZ @F      ;;;
 CMP DX,2      ;;;
 JNE @F      ;;;
 MOV bAvioGridFuncOffset,AVIO_HORZ_FUNC_OFFSET ;;;
@@:        ;;;
        DEC     DX
        JZ      nc_done_column
        ROR     EDX,16
        JMP     FG_Box_loop_1   ; Loop

nc_done_column:

        POP     EDI                     ; get addr. of last line next column
        POP     ECX
        POP     ESI                     ; recover font pointer
        JECXZ   FG_Box_end              ; if all done then get out

        MOVZX   EDX,wCellHeight
        ADD     ESI,EDX                 ; point to last byte next column
        MOV     DL,bColor               ; see if we changed banks
        CMP     DL,Origin_bank
        JE      @f
        MOV     Origin_bank,DL
        CALL    set_bank_select
@@:
        MOV     DX,800H                 ; set new shift and store counts
        CMP     DH,CL
        JBE     @F
        MOV     DH,CL                   ; set final count
@@:
        JMP     nc_outer_loop

        PUBLIC  FG_Box_end
FG_Box_end::

; Bump horizontal address by cell width.

        MOVZX   EAX,wCellWidth          ; Get cell width
        ADD     wX,EAX                  ; Bump X value

; Test for horizontal clip (?) - move to next row if yes.

        CMP     bHorizontalClipMask,0   ; Is this text clipped?
        JNE     Next_row                ;  Y - Jump to force new row

; Check character count, return if zero else decrement.

        DEC     wCharCount              ; Dec and test character count
        JNZ     Draw_n_wide_noclip_next ; Jump back to fetch next code

; Exit n-wide unclipped code.

        PUBLIC  Draw_NW_Exit
Draw_NW_Exit::
        JMP     Process_pseudo_code     ; Return to fetch next code

DrawText ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

        SUBTITLE        GetFontOffset
        PAGE +

;---------------------------Private Routine-----------------------------;
; GetFontOffset     - with    default substitution
; GetFontOffsetNS   - without default substitution
;
; Get effective font offset for specified pseudo code.
;
; Entry:
;       ESI = pseudo code
;       EBP = CharRect frame
; Returns:
;       ESI = effective font offset
;       CL = phase for this cell
; Registers Destroyed:
;       none.
; Registers Preserved:
;       EAX,EBX,EDX,EBP,EDI
; History:
;  Tue 30-Jul-1991 -by-  Soh Ohta [jl09057 @ ymtvm3]
; Created.
;-----------------------------------------------------------------------;

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;ALIGN 4
define_CharRect_frame   GetFontOffset

        cmp     esi,-2                  ; DBCS virtual glyph index?
        jb      GetFontOffsetNS         ; yes...

        mov     esi,wDefaultGlyph
        imul    esi,esi,6               ; glyph entries are 6 bytes
        add     esi,wselfontsave        ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        xor     cl,cl                   ; phase align = 0
        ret

        public  GetFontOffsetNS
GetFontOffsetNS::

        and     esi,not PSEUDO_DBCS_1ST ; get array (cb_adbcschar) index
        test    esi,1                   ; odd number ?
        jnz     gfo_dbcs_2nd            ;   means DBCS trailing byte

gfo_dbcs_1st:                           ; DBCS leading byte
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
        imul    esi,esi,6
        add     esi,wselfontsave        ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        xor     cl,cl                   ; phase align = 0
        ret

gfo_dbcs_2nd:                           ; DBCS trailing byte
        dec     esi
        mov     esi,CellBLTBlock.cb_adbcschar[esi]
        imul    esi,esi,6
        add     esi,wselfontsave        ; ESI --> Glyph description
        mov     esi,[esi].FONTMAP.fsCharOffset.VIO_FONT_ENTRIES.fe_dBits
        add     esi,wselfontsave        ; ESI --> Character bitmap
        add     esi,CellBLTBlock.cb_dbcs_2nd
                                        ; ESI --> DBCS 2nd byte font address
        mov     cl,bCellWidth           ; phase align = for DBCS 2nd byte
 and cl,7
        ret

GetFontOffset   endp

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

        SUBTITLE        PutCharFont2Apa
        PAGE +

;---------------------------Private Routine-----------------------------;
; PutCharFont2Apa
;
; Put charactor font to physical APA (for one horz line).
;
; Entry:
; EDI = APA address
; CH  = charactor font for one horz line.
;       EBP = CharRect frame
; Returns:
; None
; Registers Destroyed:
;       EAX,EBX
; Registers Preserved:
;       ECX,EDX,EBP,ESI
; History:
;  Mon 12-Oct-1992 -by-  Hidemasa Muta [jl25345 @ ymtvm3]
; Created.
;-----------------------------------------------------------------------;

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;ALIGN 4
define_CharRect_frame PutCharFont2Apa

 public PutCharFont2ApaDoNothing
PutCharFont2ApaDoNothing::
 ret

 public PutCharFont2Apa1
PutCharFont2Apa1::
 movzx eax,ch
 shl eax,3
 mov al,byte ptr lookup_table[eax]
 stosb
 ret

 public PutCharFont2Apa2
PutCharFont2Apa2::
 movzx eax,ch
 shl eax,3
 mov ax,word ptr lookup_table[eax]
 stosw
 ret

 public PutCharFont2Apa3
PutCharFont2Apa3::
 movzx eax,ch
 shl eax,3
 mov eax,dword ptr lookup_table[eax]
 stosw
 shr eax,16
 stosb
 ret

 public PutCharFont2Apa4
PutCharFont2Apa4::
 movzx eax,ch
 shl eax,3
 mov eax,dword ptr lookup_table[eax]
 stosd
 ret

 public PutCharFont2Apa5
PutCharFont2Apa5::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 stosd
 mov al,[ebx+4]
 stosb
 ret

 public PutCharFont2Apa6
PutCharFont2Apa6::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 stosd
 mov ax,[ebx+4]
 stosw
 ret

 public PutCharFont2Apa7
PutCharFont2Apa7::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 stosd
 mov ax,[ebx+4]
 stosw
 mov al,[ebx+6]
 stosb
 ret

 public PutCharFont2Apa8
PutCharFont2Apa8::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 stosd
 mov eax,[ebx+4]
 stosd
 ret

 public PutCharFont2Apa5VertGrid
PutCharFont2Apa5VertGrid::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 mov al,bPhysColor
 stosd
 mov al,[ebx+4]
 stosb
 ret

 public PutCharFont2Apa6VertGrid
PutCharFont2Apa6VertGrid::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 mov al,bPhysColor
 stosd
 mov ax,[ebx+4]
 stosw
 ret

 public PutCharFont2Apa7VertGrid
PutCharFont2Apa7VertGrid::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 mov al,bPhysColor
 stosd
 mov ax,[ebx+4]
 stosw
 mov al,[ebx+6]
 stosb
 ret

 public PutCharFont2Apa8VertGrid
PutCharFont2Apa8VertGrid::
 movzx ebx,ch
 shl ebx,3
 add ebx,offset lookup_table
 mov eax,[ebx]
 mov al,bPhysColor
 stosd
 mov eax,[ebx+4]
 stosd
 ret

 public PutCharFont2Apa1HorzGrid
PutCharFont2Apa1HorzGrid::
 mov al,byte ptr dPhysColor
 stosb
 ret

 public PutCharFont2Apa2HorzGrid
PutCharFont2Apa2HorzGrid::
 mov ax,word ptr dPhysColor
 stosw
 ret

 public PutCharFont2Apa3HorzGrid
PutCharFont2Apa3HorzGrid::
 mov ax,word ptr dPhysColor
 stosw
 stosb
 ret

 public PutCharFont2Apa4HorzGrid
PutCharFont2Apa4HorzGrid::
 mov eax,dword ptr dPhysColor
 stosd
 ret

 public PutCharFont2Apa5HorzGrid
PutCharFont2Apa5HorzGrid::
 mov eax,dword ptr dPhysColor
 stosd
 stosb
 ret

 public PutCharFont2Apa6HorzGrid
PutCharFont2Apa6HorzGrid::
 mov eax,dword ptr dPhysColor
 stosd
 stosw
 ret

 public PutCharFont2Apa7HorzGrid
PutCharFont2Apa7HorzGrid::
 mov eax,dword ptr dPhysColor
 stosd
 stosw
 stosb
 ret

 public PutCharFont2Apa8HorzGrid
PutCharFont2Apa8HorzGrid::
 mov eax,dword ptr dPhysColor
 stosd
 stosd
 ret

PutCharFont2Apa endp

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

        SUBTITLE        SpecialCaseFunctions
        PAGE +

;---------------------------Private Routine-----------------------------;
; SpecialCaseFunctions
;
; Put whole one charactor to physical APA without any overhead.
; This routines are called when charctor has no special attribute.
;
; Entry:
; EDI = APA address
; ESI = font address
; EBX = wCellHeight
; EDX = -wCellHeight-1
;       EBP = CharRect frame
; Returns:
; None
; Registers Destroyed:
;       EAX,ECX,ESI
; Registers Preserved:
;       EBX,EDX,EBP
; History:
;  Mon 12-Oct-1992 -by-  Hidemasa Muta [jl25345 @ ymtvm3]
; Created.
;-----------------------------------------------------------------------;

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;ALIGN 4
define_CharRect_frame SpecialCaseFunctions

;--- pochi added --- 01-27-92 <begin> -- Enable SBCS 5 wide font ---
;                                        See CELLDRAW.ASM
        public  Sbcs_5_Special
Sbcs_5_Special::
        mov     ecx,ebx         ; wCellHeight
        lea     eax,[esi+ecx-1]
Sbcs_5_Special_loop:
        movzx   esi,byte ptr [eax]
        dec     eax
        shl     esi,3
        add     esi,offset lookup_table
        movsd
        movsb
        dec     edi
        sub     di,SCREEN_CBSCAN+4
        jc      Sbcs_5_Change_Bank
        loop    Sbcs_5_Special_loop
        jmp     FG_Box_end3
Sbcs_5_Change_Bank:
        xchg    dl,Origin_bank
        dec     dl
        call    set_bank_select
        xchg    dl,Origin_bank
        loop    Sbcs_5_Special_loop
        jmp     FG_Box_end3

;--- pochi added --- 01-27-92 <end> ---------------------------

 public Sbcs_6_Special
Sbcs_6_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_6_Special_loop:
 movzx esi,byte ptr [eax]
 dec eax
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+5
 jc Sbcs_6_Change_Bank
 loop Sbcs_6_Special_loop
 jmp FG_Box_end3
Sbcs_6_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_6_Special_loop
 jmp FG_Box_end3

 public Sbcs_7_Special
Sbcs_7_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_7_Special_loop:
 movzx esi,byte ptr [eax]
 dec eax
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsw
 movsb
 dec edi
 sub di,SCREEN_CBSCAN+6
 jc Sbcs_7_Change_Bank
 loop Sbcs_7_Special_loop
 jmp FG_Box_end3
Sbcs_7_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_7_Special_loop
 jmp FG_Box_end3

 public Sbcs_8_Special
Sbcs_8_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_8_Special_loop:
 movzx esi,byte ptr [eax]
 dec eax
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 dec edi
 sub di,SCREEN_CBSCAN+7
 jc Sbcs_8_Change_Bank
 loop Sbcs_8_Special_loop
 jmp FG_Box_end3
Sbcs_8_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_8_Special_loop
 jmp FG_Box_end3


 public Sbcs_9_Special
Sbcs_9_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_9_Special_loop:
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsb
 dec edi
 sub di,SCREEN_CBSCAN+8
 jc Sbcs_9_Change_Bank
 loop Sbcs_9_Special_loop
 jmp FG_Box_end3
Sbcs_9_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_9_Special_loop
 jmp FG_Box_end3


 public Sbcs_10_Special
Sbcs_10_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_10_Special_loop:
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+9
 jc Sbcs_10_Change_Bank
 loop Sbcs_10_Special_loop
 jmp FG_Box_end3
Sbcs_10_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_10_Special_loop
 jmp FG_Box_end3

 public Sbcs_11_Special
Sbcs_11_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_11_Special_loop:
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsw
 movsb
 dec edi
 sub di,SCREEN_CBSCAN+10
 jc Sbcs_11_Change_Bank
 loop Sbcs_11_Special_loop
 jmp FG_Box_end3
Sbcs_11_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_11_Special_loop
 jmp FG_Box_end3

 public Sbcs_12_Special
Sbcs_12_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_12_Special_loop:
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 dec edi
 sub di,SCREEN_CBSCAN+11
 jc Sbcs_12_Change_Bank
 loop Sbcs_12_Special_loop
 jmp FG_Box_end3
Sbcs_12_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_12_Special_loop
 jmp FG_Box_end3

 public Sbcs_13_Special
Sbcs_13_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Sbcs_13_Special_loop:
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsb
 dec edi
 sub di,SCREEN_CBSCAN+12
 jc Sbcs_13_Change_Bank
 loop Sbcs_13_Special_loop
 jmp FG_Box_end3
Sbcs_13_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Sbcs_13_Special_loop
 jmp FG_Box_end3

 public Dbcs_6_Special
Dbcs_6_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_6_Special_loop:
 movzx esi,byte ptr [eax]
 and si,03h
 shl si,9
 add esi,offset lookup_table
 movsw
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 dec edi
 sub di,SCREEN_CBSCAN+5
 jc Dbcs_6_Change_Bank
 loop Dbcs_6_Special_loop
 jmp FG_Box_end3
Dbcs_6_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_6_Special_loop
 jmp FG_Box_end3

 public Dbcs_7_Special
Dbcs_7_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_7_Special_loop:
 movzx esi,byte ptr [eax]
 and si,01h
 shl si,10
 add esi,offset lookup_table
 movsb
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+6
 jc Dbcs_7_Change_Bank
 loop Dbcs_7_Special_loop
 jmp FG_Box_end3
Dbcs_7_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_7_Special_loop
 jmp FG_Box_end3

 public Dbcs_9_Special
Dbcs_9_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_9_Special_loop:
 movzx esi,byte ptr [eax]
 and si,7fh
 shl si,4
 add esi,offset lookup_table
 movsb
 movsw
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+8
 jc Dbcs_9_Change_Bank
 loop Dbcs_9_Special_loop
 jmp FG_Box_end3
Dbcs_9_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_9_Special_loop
 jmp FG_Box_end3

 public Dbcs_10_Special
Dbcs_10_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_10_Special_loop:
 movzx esi,byte ptr [eax]
 and si,3fh
 shl si,5
 add esi,offset lookup_table
 movsw
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 dec edi
 sub di,SCREEN_CBSCAN+9
 jc Dbcs_10_Change_Bank
 loop Dbcs_10_Special_loop
 jmp FG_Box_end3
Dbcs_10_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_10_Special_loop
 jmp FG_Box_end3

 public Dbcs_11_Special
Dbcs_11_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_11_Special_loop:
 movzx esi,byte ptr [eax]
 and si,1fh
 shl si,6
 add esi,offset lookup_table
 movsb
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+10
 jc Dbcs_11_Change_Bank
 loop Dbcs_11_Special_loop
 jmp FG_Box_end3
Dbcs_11_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_11_Special_loop
 jmp FG_Box_end3

 public Dbcs_12_Special
Dbcs_12_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_12_Special_loop:
 movzx esi,byte ptr [eax]
 and si,0fh
 shl si,7
 add esi,offset lookup_table
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 dec edi
 sub di,SCREEN_CBSCAN+11
 jc Dbcs_12_Change_Bank
 loop Dbcs_12_Special_loop
 jmp FG_Box_end3
Dbcs_12_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_12_Special_loop
 jmp FG_Box_end3

 public Dbcs_13_Special
Dbcs_13_Special::
 mov ecx,ebx  ; wCellHeight
 lea eax,[esi+ecx-1]
Dbcs_13_Special_loop:
 movzx esi,byte ptr [eax]
 and si,7
 shl si,8
 add esi,offset lookup_table
 movsb
 movsw
 add eax,ebx
 movzx esi,byte ptr [eax]
 shl esi,3
 add esi,offset lookup_table
 movsd
 movsd
 add eax,ebx
 movzx esi,byte ptr [eax]
 add eax,edx
 add eax,edx
 inc eax
 shl esi,3
 add esi,offset lookup_table
 movsw
 dec edi
 sub di,SCREEN_CBSCAN+12
 jc Dbcs_13_Change_Bank
 loop Dbcs_13_Special_loop
 jmp FG_Box_end3
Dbcs_13_Change_Bank:
 xchg dl,Origin_bank
 dec dl
 call set_bank_select
 xchg dl,Origin_bank
 loop Dbcs_13_Special_loop
 jmp FG_Box_end3

SpecialCaseFunctions endp

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef
