;*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.;
;*****************************************************************************/
        PAGE    60,132
        TITLE   XGABUFUP.ASM -- Common Buffer Update Routine for EGA, VGA, BGA

;/*****************************************************************************
;*
;* SOURCE FILE NAME = XGABUFUP.ASM
;*
;* DESCRIPTIVE NAME = Video Device Handler BufferUpdate routine
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Common Buffer Update Routine for EGA, VGA, BGA
;*              Mainline routine for video buffer read, write,
;*              scroll functions.
;*
;* INPUT:       STACK FRAME on entry
;*
;* SS:SP  --->  bvsip           dw      BVS IP offset
;*              bvscs           dw      BVS CS selector
;*              parmn           dw      Function number (256)
;*              parmnm1         dw      Parameter block offset
;*              parmnm2         dw      Parameter block selector
;*              parmnm3         dw      Environment buffer offset
;*              parmnm4         dw      Environment buffer selector
;*
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   ParmLength (length of structure - 28 bytes)
;*   WORD   Flags
;*            Bit 0 = 0, do not update physical display buffer
;*            Bit 0 = 1, update physical display buffer if possible
;*            Bit 1 = 0, logical display buffer update not required
;*            Bit 1 = 1, update logical display buffer
;*            Bit 2 = 0, use attribute as is
;*            Bit 2 = 1, convert attribute to or from CGA format
;*            Bit 3 - 15 are reserved and must be OFF
;*
;*          NOTE:  If bit 0 and 1 are both ON then the LVB will
;*                 be written first before the PVB is updated.
;*                 This will ensure that video devices with
;*                 slower VRAM will benefit from this algorithm.
;*
;*                 The caller of BufferUpdate routine (BVS) must
;*                 serialize access to this routine to insure
;*                 that the LVB and the PVB will not get out of sync.
;*
;*   DWORD  AppDataAddr (address of application data)
;*   DWORD  AppCellAddr (address of character, attribute, or cell)
;*   WORD   Index (BufferUpdate sub-function to be performed)
;*            0 = Read cell types
;*                  Bit 0 = 0, single cell character
;*                             (occupies one cell on the screen)
;*                  Bit 0 = 1, double cell character
;*                             (occupies two cells on the screen)
;*                  Bit 1 = 0, leading (or only) cell
;*                  Bit 1 = 1, trailing cell
;*                  Bit 2 - 15 are reserved and must be OFF
;*            1 = Read characters from (Row, Col)
;*            2 = Read cells from (Row, Col)
;*            3 = Scroll (Row, Col) through (Row2, Col2) Up
;*            4 = Scroll (Row, Col) through (Row2, Col2) Down
;*            5 = Scroll (Row, Col) through (Row2, Col2) Left
;*            6 = Scroll (Row, Col) through (Row2, Col2) Right
;*            7 = Write cells to (Row, Col)
;*            8 = Write characters to (Row, Col)
;*            9 = Write characters with constant attr to (Row, Col)
;*           10 = Write repeat character to (Row, Col)
;*           11 = Write repeat attribute to (Row, Col)
;*           12 = Write repeat cell to (Row, Col)
;*           13 = Copy LVB Rect to PVB
;*   WORD   Row  (Starting row)
;*   WORD   Col  (Starting column)
;*   WORD   Row2 (Secondary row)
;*   WORD   Col2 (Secondary column)
;*   WORD   RepeatFactor (# of character cells or rows/columns)
;*   WORD   LogicalBufSel (logical buffer selector - LVB)
;*   WORD   TouchXLeft   (left most column touched by the write)
;*   WORD   TouchYTop    (top most column touched by the write)
;*   WORD   TouchXRight  (right most column touched by the write)
;*   WORD   TouchYBottom (bottom most column touched by the write)
;*   WORD   LVBRowOff    (row offset of the LVB in PVB coordinates)
;*   WORD   LVBColOff    (column offset of the LVB in PVB coordinates)
;*   WORD   LVBWidth     (width of the LVB in cells)
;*   WORD   LVBHeight    (height of the LVB in cells)
;*   BYTE   LVBFormatID  (format id of the LVB)
;*   BYTE   LVBAttrCount (number of attributes in the LVB)
;*
;*
;* ENVIRONMENT BUFFER FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*   WORD   ModeDataOff (offset to mode data structure)
;*
;*
;* MODEDATA STRUCTURE FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*   WORD   Length (length of mode data structure - 34 bytes)
;*   BYTE   ModeType
;*            Bit 0 = 0, monochrome compatible
;*            Bit 0 = 1, other
;*            Bit 1 = 0, text mode
;*            Bit 1 = 1, graphics mode
;*            Bit 2 = 0, enable color burst
;*            Bit 2 = 1, disable color burst
;*            Bit 3 = 0, VGA compatible modes (0 - 13h)
;*            Bit 3 = 1, native mode
;*            Bit 4 - 15 are reserved
;*   BYTE   Color (number of colors as a power of 2)
;*   WORD   TextCols (number of text columns in current mode)
;*   WORD   TextRows (number of text rows in current mode)
;*   WORD   HorizRes (horizontal pel resolution)
;*   WORD   VertRes (vertical pel resolution)
;*   BYTE   AttrFormat (attribute format)
;*   BYTE   NAttributes (number of attributes in a character cell)
;*  DWORD   BufferAddr (32-bit physical address of PVB)
;*  DWORD   BufferLength (length of PVB in current mode)
;*  DWORD   FullBufSize (size of buffer required for screen save)
;*  DWORD   PartBufSize (size of buffer for popup save)
;*  DWORD   ExtDataAddr (extended mode data structure address)
;*
;* EXIT-NORMAL: AX = 0
;* EXIT-ERROR:  AX = error code, ERROR_VIO_COL
;*                               ERROR_VIO_INVALID_LENGTH
;*                               ERROR_VIO_INVALID_PARMS
;*                               ERRPR_VIO_MODE
;*                               ERROR_VIO_ROW
;*                               ERROR_VIO_INTERNAL_RESOURCE
;*
;* EFFECTS:     All other registers are preserved
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: ReadCellTypes           in XGAREAD.ASM
;*                      ReadCharStr             in XGAREAD.ASM
;*                      ReadCellStr             in XGAREAD.ASM
;*                      ScrollUp                in XGASCROL.ASM
;*                      ScrollDown              in XGASCROL.ASM
;*                      ScrollLeft              in XGASCROL.ASM
;*                      ScrollRight             in XGASCROL.ASM
;*                      WriteCellStr            in XGAWRITE.ASM
;*                      WriteCharStr            in XGAWRITE.ASM
;*                      WriteCharStrAttr        in XGAWRITE.ASM
;*                      WriteNChar              in XGAWRITE.ASM
;*                      WriteNAttr              in XGAWRITE.ASM
;*                      WriteNCell              in XGAWRITE.ASM
;*                      LVBToPVB                in XGASCROL.ASM
;*
;* FUNCTIONS    BUFFERUPDATE
;*              SetupPhysBuf
;*              SetGenParms
;*
;* NOTES:       Ring 2 conforming code, executable in either
;*              privilege level 2 or 3 in protect mode.
;*   LINKAGE:   Far Call from Base Video Subsystem (BVSCALLS.DLL)
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;* PSEUDOCODE
;*
;*   Begin BufferUpdate
;*       Preset return code to ERROR_VIO_MODE
;*       If text mode
;*           Preset return code to ERROR_VIO_INVALID_LENGTH
;*           If correct parameter length
;*               Preset return code to ERROR_VIO_INVALID_PARMS
;*               If valid reserved flags     AND
;*               If valid video buffer flags AND
;*               If valid function number    AND
;*               If valid index number
;*                   Call Read/Write/Scroll routines
;*               Endif
;*           Endif
;*       Endif
;*   End BufferUpdate
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   03/25/89  @P1        D132    TPL, DCR 132 changes
;*   05/22/89  @T30       D511    TPL, DCR 511 changes
;*   07/05/89  @B15       B702527 WKB, Performance enhancements,
;*   07/15/89  @T39       B784056 TPL, Remove hardware dependencies in VDHINIT,
;*   01/23/89  @T52       D704    TPL, DCR 704 work
;*   01/29/91  MS01               TPL, Rollover MS's runtime check for CGA
;*                                speedup
;*   06/21/89  J-KKJ              KKJ, Norikae 95
;*   09/01/89  J-KK0901           KKJ, Performance Up
;*   09/11/89  J-KK0911           KKJ, Changed Fill Cell Value in Clear_LVB
;*   09/12/89  J-KK129            KKJ, Norikae 129
;*   09/21/89  j-ys921            YS,  Real Mode Support
;*   10/05/89  J-KK1005           KKJ, [bp].Sub_AttrState -> .Sub_Option
;*   10/16/89  J-KK1016           KKJ, Add [bp].XVS_Session
;*   10/17/89  J-KK1017           KKJ, Re-Arrange Hide/Redraw/SetBuf logic & Delete JapanOFFOFF
;*   10/24/89  J-KK1024           KKJ, Add Error Consideration at XvioRedraw.
;*   10/25/89  J-KK1025           KKJ, Add Sub_attrnum.
;*   10/27/89  J-KK1027           KKJ, Deleted LVB_Changed
;*   10/20/89  j-ys1020           YS,  for MS-Xvio support.
;*   10/27/89  j-ys1027           YS,  for MS-Xvio support.
;*   11/08/89  J-KK1108           KKJ,     Fix - Trap-D at Clear_LVB
;*   11/17/89  J-KK1117           KKJ, Changed CLEAR_LVB Interface
;*   11/20/89  J-KK1120           KKJ, Norikae 161, LVB size is too small at PM session(1),
;*                                     threfore, ignore the update request to PM Session.
;*                                     ( By BVSCALLS Change. )
;*   12/13/89  J-KK1212           KKJ, Performance Up
;*   01/10/90  J-KK0110           KKJ, Add Real_Mode flag in a Sub_Option field.
;*   01/12/90  J-KK0112           KKJ, For Handling Bufferupdate in Real Mode at Transp-Popup.
;*   02/06/90  J-KK0206           KKJ, Add ALL_REDRAWN Handling.
;*   02/13/90  J-KK0213           KKJ, Delete Xvs_SetBuf and Add Xvs_LVBSelR field for performance-up.
;*   02/16/90  J-KKB12A           KKJ, PTR411 - If pre-Mode was graphics, LVB size => 0FFFFh.
;*   02/20/90  J-KKB12B           KKJ, Xvio should not redraw at the Read operation.
;*   06/22/90  @KK0622            KKJ, Must not call DOSGETSEG at HardError. Fix AS/400 Problem.
;*   09/04/90  @KK0904            KKJ, Popup handling in 3.X. Must call Suspend/Resume with pair.
;*   09/11/90  @KK0911                ( DOHHAKU san's DOALARM2 problem. - Semaphore Deadlock )
;*   01/11/91  @XVIO              KKJ, DCR JC13 131.1 DosLoadModule of XVIO
;*   01/28/91  @KK0128            KKJ, Fix PTR JC13 JS00845
;*   07/12/91  J-TS0712           TSO, If XVIOCALL doesn't exist, error code is returned.
;*   01/11/92  J-TS011792         TSO, PTR JS02380
;*   09/29/93  J-TS0929   JS06035 TSO, VioWrtNxxx call is trapped if it is
;*                                     called after VioWrtCellStr.
;*****************************************************************************/

        .286p                           ; 286 protect mode instructions

        .xlist
        INCLUDE struc.inc               ; Structure macro
        INCLUDE error.inc               ; System error equates          @XVIO
        INCLUDE error2.inc              ; Subsystem error equates
        INCLUDE vdhequ.inc              ; Buffer update equates
        INCLUDE vdhstruc.inc            ; Buffer update data structures
        INCLUDE xgamac.inc              ;                               @P1
        .list

        EXTRN   DOSGETDBCSEV:FAR        ;Get DBCS environment vector   ;J-KKJ
        EXTRN   DOSLOADMODULE:FAR       ;                               @XVIO
        EXTRN   DOSGETPROCADDR:FAR      ;                               @XVIO
        EXTRN   DOSFREEMODULE:FAR       ;                               @XVIO
        EXTRN   DOSFSRAMSEMREQUEST:FAR                                  ;J-TS011792
        EXTRN   DOSFSRAMSEMCLEAR:FAR                                    ;J-TS011792

_DATA       SEGMENT WORD PUBLIC 'DATA'  ;                               @KK0622
        IFNDEF  INSTALLATION            ; Not Installation              @KK0622
            EXTRN   _HarderrFlag:BYTE   ; Hard Error Flag               @KK0622
XVIO_EXIST  db      1                   ; XVIO exist?                   @XVIO
XVIO_NAME   db      'BXVSCALL',0        ; XVIO Module                   @XVIO
XVIO_PROCNAME db    'XVIOVDHIF',0       ; XVIO Proc                     @XVIO
        ENDIF                           ; Not Installation              @KK0622
            EXTRN   _SemAccessAPA:BYTE  ; APA exclusive access          ;J-TS011792

_DATA       ENDS                        ;                               @KK0622


;;J-KK129 INSTSEG SEGMENT PARA PUBLIC 'DATA'
INSTSEG SEGMENT WORD PUBLIC 'DATA'      ;@T39
XVIO_HANDLE dw  0                       ; XVIO Module Handle            @XVIO
XVIO_PROC dd    0                       ; XVIO Proc Address             @XVIO
;************************************************************************
;*  Per process instance data                                           *
;************************************************************************
        PVBPhysAddrLo dw      0         ; Physical address of PVB
        PVBPhysAddrHi dw      0         ; 
        PVBSizeLo dw      0             ; PVB buffer size
        PVBSizeHi dw      0             ; 
        PVBOffset dw      0             ; PVB Offset                    ;@T30
        PVBSelector dw      0           ; PVB Selector

INSTSEG ENDS

        PUBLIC  PVBPhysAddrLo
        PUBLIC  PVBPhysAddrHi
        PUBLIC  PVBSizeLo
        PUBLIC  PVBSizeHi
        PUBLIC  PVBSelector

        EXTRN   ReadCellTypes    : NEAR ; 
        EXTRN   ReadCharStr      : NEAR ; VioReadCharStr
        EXTRN   ReadCellStr      : NEAR ; VioReadCellStr
        EXTRN   ScrollUp         : NEAR ; VioScrollUp
        EXTRN   ScrollDown       : NEAR ; VioScrollDn
        EXTRN   ScrollLeft       : NEAR ; VioScrollLt
        EXTRN   ScrollRight      : NEAR ; VioScrollRt
        EXTRN   WriteCellStr     : NEAR ; VioWriteCellStr
        EXTRN   WriteCharStr     : NEAR ; VioWriteCharStr
        EXTRN   WriteCharStrAttr : NEAR ; VioWriteCharStrAttr
        EXTRN   WriteNChar       : NEAR ; VioWriteNChar
        EXTRN   WriteNAttr       : NEAR ; VioWriteNAttr
        EXTRN   WriteNCell       : NEAR ; VioWriteNCell
        EXTRN   LVBToPVB         : NEAR ;@P1

        EXTRN   _PhysToUVirt     : NEAR ; Allocate PVB selector         ;@B15
        EXTRN   _FreePhysToUVirt : NEAR ; Deallocate PVB selector       ;@B15

        PUBLIC  JBUFFERUPDATE           ;;J-KKJ

;;@XVIO IFNDEF  INSTALLATION            ; Not Installation              J-KK1017
;;@XVIO     EXTRN   XVIOVDHIF:FAR       ; Call Xvio Interface           J-KK1017
;;@XVIO ENDIF                           ; Not Installation              J-KK1017

R2CSEG  SEGMENT WORD    PUBLIC 'CODE'
        ASSUME  CS:R2CSEG,DS:NOTHING,ES:NOTHING

        PUBLIC  DispTbl
DispTbl DW      OFFSET R2CSEG:ReadCellTypes ; table for EGA format LVB
        DW      OFFSET R2CSEG:ReadCharStr ; Read characters
        DW      OFFSET R2CSEG:ReadCellStr ; Read character/attribute 's
        DW      OFFSET R2CSEG:ScrollUp  ; Scroll window up
        DW      OFFSET R2CSEG:ScrollDown ; Scroll window down
        DW      OFFSET R2CSEG:ScrollLeft ; Scroll window left
        DW      OFFSET R2CSEG:ScrollRight ; Scroll window right
        DW      OFFSET R2CSEG:WriteCellStr ; Write character/attribute 's
        DW      OFFSET R2CSEG:WriteCharStr ; Write characters
        DW      OFFSET R2CSEG:WriteCharStrAttr ; Write characters with attr
        DW      OFFSET R2CSEG:WriteNChar ; Write character N times
        DW      OFFSET R2CSEG:WriteNAttr ; Write attribute N times
        DW      OFFSET R2CSEG:WriteNCell ; Write cell N times
        DW      OFFSET R2CSEG:LVBToPVB  ; Copy the LVB to the PVB @P1



;;*****************************************************;;J-KKJ
        PUBLIC  _int3asm                ;;J-KKJ
_int3asm PROC   near                    ;;J-KKJ
        int     3                       ;;; Debug           ;;J-KKJ
        ret                             ;;J-KKJ
_int3asm ENDP                           ;;J-KKJ
;;*****************************************************;;J-KKJ

;;----------------------------------------------------------------------@XVIO
;; XVIO Interface
;;
;;  Calling Sequence
;;      rc     = XVIOVDHIF( Function,  (PUSHORT)&Params) ;
;;
;;  Session #    Handling
;;  ---------   -----------------------------------------------
;;     0         Not call XVIO at all.
;;   1, 3        Only XvsSetMode and XvsInitialize are called.
;;   2, 4-15     All APIs are called.
;;----------------------------------------------------------------------@XVIO
XVIOVDHIF PROC  near                    ; 
        public  XVIOVDHIF               ; 

IFNDEF  INSTALLATION                    ; Not Installation

        push    bp                      ; 
        mov     bp, sp                  ; 
        push    bx                      ; 
        push    es                      ; 

        les     bx, ss:[bp+4]           ; Address Parameter Block
        mov     al, es:[bx+3]           ; Get Session Number
        .if     < al ae 4 > or          ; Normal Session?
        .if     < al e  2 > near        ; Real Session?
XVIOVDHIF_0:                            ; 
            push    INSTSEG             ; 
            pop     es                  ; 
            mov     ax, word ptr es:[XVIO_PROC] ; 
            or      ax, word ptr es:[XVIO_PROC+2] ; 
            .if     < nonzero ax >      ; Already loaded?
                push    ss:[bp+8]       ; 
                push    ss:[bp+6]       ; 
                push    ss:[bp+4]       ; 
                Call    DWORD PTR ES:XVIO_PROC ; 
            .else                       ; 
                push    ds              ; 
                push    _DATA           ; 
                pop     ds              ; 
                .if     <<byte ptr ds:[XVIO_EXIST]> ne 0 > ; XVIO exists?
                    push    0           ; 
                    push    0           ; 
                    push    0           ; 
                    push    ds          ;module name
                    push    offset XVIO_NAME ; 
                    push    es          ; ES = INSTSEG
                    push    offset XVIO_HANDLE ; 
                    call    DOSLOADMODULE ; 
                    .if     < zero ax > ; No Error?
                        push    es:XVIO_HANDLE ; 
                        push    ds      ;entry  name
                        push    offset XVIO_PROCNAME ; 
                        push    es      ; 
                        push    offset XVIO_PROC ; 
                        call    DOSGETPROCADDR ; 
                        .if     < zero ax > ; No Error?
                            push    ss:[bp+8] ; 
                            push    ss:[bp+6] ; 
                            push    ss:[bp+4] ; 
                            Call    DWORD PTR ES:XVIO_PROC ; 
                        .else           ; Error
                            push    ax  ; 
                            push    es:XVIO_HANDLE ; 
                            call    DOSFREEMODULE ; 
                            mov     word ptr es:[XVIO_PROC], 0 ; 
                            mov     word ptr es:[XVIO_PROC+2], 0 ; 
                            pop     ax  ; 
                        .endif          ; 
                    .else               ; 
                        .if     < ax e ERROR_FILE_NOT_FOUND > ; 
                            mov     byte ptr ds:[XVIO_EXIST], 0 ; XVIO not exist.
                            xor     ax, ax      ; clear error code  ;J-TS0712
                        .endif          ; 
                    .endif              ; 
                .endif                  ; 
                pop     ds              ; 
            .endif                      ; 
        .else                           ; 
            .if     < al e 1 > or       ; PM Session?
            .if     < al e 3 >          ; Popup Session?
                mov     ax, word ptr ss:[bp+8] ; Function number
                .if     < al e XvsInitialize > ; 
                    jmp     XVIOVDHIF_0 ; 
                .elseif     < al e XvsSetMode > ; 
;;@KK0128           mov     byte ptr es:[bx+2], Suspend+Resume ; Allways
                    or      byte ptr es:[bx+2], Suspend+Resume ; @KK0128
                    jmp     XVIOVDHIF_0 ; 
                .endif                  ; 
            .endif                      ; 
            xor     ax, ax              ; No Error in Hard Error Session
        .endif                          ; 

        pop     es                      ; 
        pop     bx                      ; 
        pop     bp                      ; 
ELSE                                                                    ;J-TS00
        xor     ax, ax                                                  ;J-TS00
ENDIF                                   ; 
        ret     6                       ; 
XVIOVDHIF ENDP
;;----------------------------------------------------------------------@XVIO


JBUFFERUPDATE PROC near                 ;;J-KKJ129

;;****************************************************************
;;*  This mainline routine checks all high level errors before   *
;;*  control is transfer to the worker routine.                  *
;;*  On entry to each worker routine, the following registers    *
;;*  are setup:                                                  *
;;*      DS:SI -> Parameter block buffer                         *
;;*      ES:DI -> Mode data structure in the environment buffer  *
;;*      SS:BP -> Parameter stack frame                          *
;;*                                                              *
;;*      All registers are preserved                             *
;;****************************************************************

        sub     sp, WORK_END-PVB_Sel+2  ;Allocate storage for: PVB selector J-KKJ
        push    bp                      ; Save caller's BP
        mov     bp, sp                  ; Establish parameter addressability
        pusha                           ; Save all registers
        push    ds                      ; 
        push    es                      ; 

        lds     si, [bp].EnvBufParm     ; Copy DBCSEv                  ;J-KK1213
        add     si, offset DBCSEvBuff   ;                              ;J-KK1213
        lea     di, [bp].Sub_DBCSEv     ;                              ;J-KK1213
        push    ss                      ;                              ;J-KK1213
        pop     es                      ;                              ;J-KK1213
        mov     cx, DBCSEv_Size/2       ;                              ;J-KK1213
        rep     movsw                   ;                              ;J-KK1213

        les     di, [bp].EnvBufParm     ; ES:DI -> environment buffer

;;J-KK0110 mov     ax, word ptr es:[di].EnvFlags ;                         ;j-ys921
;;J-KK1120 .if     < bit AX and  ENVFLAG_3xBOX > ;                      ;j-ys921
;;J-KK0110 .if     < bit AX and  ENVFLAG_3xBOX > or ; Real Session     ;J-KK1120
;;                                                                      J-KK0110
;;      Must handle for Real Mode at Transp-Popup.                      J-KK0110
;;                                                                      J-KK0110

        .if     < <word ptr es:[di].SessionNum_Env> e 1 > ; PM Session ;J-KK1120
;;                                      ; If PM Session (SessionID=1)   J-KK1120
            xor     ax,ax               ;                               J-KK0110
                                        ;    Return Immediately.        ;j-ys921
        .else   near                    ;                               ;j-ys921

            lds     si, [bp].ParmBuf    ; DS:SI -> parameter buffer    ;J-KK0828
                                        ; Must be kept.                ;J-KK0828
            mov     ax, [si].Flags      ; Get  Flags                   ;J-KK0828
            mov     [bp].Sub_Flags, ax  ; Save Flags                   ;J-KK0828
            mov     ax, es:[di].Option  ; Get Option
            mov     [bp].Sub_Option, ax ; Save Option (Initialized)
            test    byte ptr es:[di].EnvFlags, ENVFLAG_3xBOX ;Real Mode J-KK0110
            .if     < nz >              ;                               J-KK0110
                or      [bp].Sub_Option, Real_Mode ; Set Real Mode Flag J-KK0110
            .endif                      ;                               J-KK0110

            .if     <<word ptr [si].FuncIndex> be I_ReadCellStr> ; Read?J-KKB12B
                or      [bp].Sub_Option, Read_Ope ; Read Operation     J-KKB12B
            .endif                      ;                               J-KKB12B

;; Check if this request is from MS-XVIO or not.
            mov     ax, [si].LogicalBufSel ;                            J-KK1026
            .if     < <word ptr [si].ParmLength> g 26 > ; CA Request ?  J-KK1026
;;                                      ; Set CA Request Flag
                or      [bp].Sub_Option, CA_Request ; Request From MS-XVIO J-KK1026
;;                                      ; Restore from LVB ?
                .if     < es:[di].LVB_Selector e  ax > ; From LVB       ;j-ys111
                    or      [bp].Sub_Option, f_restfromlvb ;            ;j-ys111
                .endif                  ;                               ;j-ys111
;;                                      ; Store CA FormatID
                .if     < ds:[si].LVBFormatID e 70h > ;                ;j-ys1027
                    mov     ax,COMMON_Format ;                         ;j-ys1027
                .elseif < ds:[si].LVBFormatID e 1 > ;                  ;j-ys1027
                    mov     ax,EPOCH_Format ;                          ;j-ys1027
                .else                   ;                              ;j-ys1027
                    mov     ax,ATLASUS_Format ;                        ;j-ys1027
                .endif                  ;                              ;j-ys1027
                mov     [bp].Sub_Format, ax ; Save Format Index        ;j-ys1027
;;                                      ; Store PVBend
                mov     ax, es:[di].ScreenSize ; Get Screen Size
                mov     [bp].Sub_PVBend,ax ; Save Screen Size for PVB update   ;j-ys1023

;;                                      ; Store Buffersize
;;         Adjust LVB buffsize in the case of LVB = CA.                ;j-ys1023
                mov     ax,ds:[si].LVBwidth ;                          ;j-ys1023
                mul     ds:[si].LVBheight ;                            ;j-ys1023
                shl     ax,1            ;                              ;j-ys1023
                cmp     ds:[si].ParmLength , LVBAttrCount +1 ;         ;j-ys1023
                .if     < ae > and      ;                              ;j-ys1023
                cmp     word ptr ds:[si].LVBFormatID,WorldFMTATTR ;    ;j-ys1023
                .if     < e >           ;                              ;j-ys1023
                    shl     ax,1        ;                              ;j-ys1023
                .endif                  ;                              ;j-ys1023
                mov     [bp].Sub_Buffsize,ax ; Save Screen Size        ;j-ys1023

            .else                       ; For Not CA                    J-KK1106
;;                                      ; Update LVB_Selector in Environment
                .if     < es:[di].LVB_Selector ne ax > ; Not Same Selector  J-KK1026
                    mov     es:[di].LVB_Selector, ax ; Save LVB SelectorJ-KK1026
                .endif                  ;                               J-KK1026
                mov     [bp].XVS_LVBSelR, ax ; Store LVB Selector       J-KK0213
;;
                mov     ax, es:[di].FormatIndex ; Get Format
                mov     [bp].Sub_Format, ax ; Save Format Index
                mov     ax, es:[di].ScreenSize ; Get Screen Size
                mov     [bp].Sub_Buffsize,ax ; Save Screen Size
                mov     [bp].Sub_PVBend,ax ; Save Screen Size for PVB update ;j-ys1023
;;                                      ; If Format is changed, Clear LVB.

                .if     < bit [bp].Sub_Option nand Real_Mode > and ; Not Real Mode
;                                                              ;     J-KK0110
                .if     < <BYTE PTR es:[di].FormatChanged> e 1 > ; 
                    mov     BYTE PTR es:[di].FormatChanged, 0 ; Flag Change
                    or      [bp].Sub_Option, CLEARED_LVB ; 

                    push    [bp].Sub_Format ; Push Format Index         J-KK1117
                    push    es:[di].LVB_Selector ; Push LVB Selector    J-KK1117
                    push    [bp].Sub_Buffsize ; Push Screen Size        J-KK1117
                    Call    CLEAR_LVB   ; Clear LVB

                .endif                  ; 
            .endif                      ;                               J-KK1026


            IFNDEF  INSTALLATION        ; Not Installation

;;J-KK0213                .if     < bit [bp].Sub_Option nand Real_Mode > ; Not Real Mode  J-KK0110
;;
;;    Request To Xvio : Suspend, SetBuf or Hide                         J-KK1017
;;
;;J-KK0213                    .if     < bit [bp].Sub_Flags and PVB_SEL_BIT > ; PVB Update Request
;;J-KK0213

                mov     ax, es:[di].SessionNum_Env ; Store Session Number
                mov     byte ptr [bp].XVS_Session, al ; 

                mov     byte ptr [bp].XVS_Option, Suspend ; Option


            ENDIF


;;J-KK1025  push    di                  ;<===
            add     di, es:[di].ModeDataOff ; ES:DI -> mode data structure
            mov     ax, es:[di].mode_cols ; Get Cols value
            mov     [bp].Sub_cols,ax    ; Save Cols value
            xor     ah,ah               ;                               ;j-ys711
            mov     al, es:[di].mode_colors ; Get Cols value            ;j-ys711
            mov     [bp].Sub_colors,ax  ; Save Cols value               ;j-ys711
            mov     al, es:[di].mode_attrcount ;Get Attr# of this mode ;J-KK1025
            mov     [bp].Sub_attrnum,ax ; Save Attr#                  ;J-KK1025
;;J-KK1025  pop     di                  ;<===

            .if     < bit [bp].Sub_Option and Real_Mode > ; Real Mode   J-KK0112
                dec     word ptr es:[di].mode_rows ; Dec Rows           J-KK0112
            .endif                      ;                               J-KK0112

;;;---------------------------------------------------------------      ;;J-KKJ

;;J-KK1025  add     di, es:[di].ModeDataOff ; ES:DI -> mode data structure
            mov     ax, ERROR_VIO_MODE  ; Preset invalid mode error
            test    es:[di].ModeType, GRAPHICS_MODE
            .if     <z>                 ; Text mode?
                lds     si, [bp].ParmBuf ; DS:SI -> parameter buffer
                mov     ax, ERROR_VIO_INVALID_LENGTH ; Preset error code
                .if     <[si].ParmLength ae LogicalBufSel+2> ; Valid parm length? @P1
                    mov     ax, ERROR_VIO_INVALID_PARMS ; Preset error code
                    test    [si].Flags, RESERVED_FLAGS ; 
                    .if     <z>                         AND ; Valid reserved flags?
                    test    [si].Flags, PVB_SEL_BIT + LVB_SEL_BIT
                    .if     <nz>                        AND ; Either bit is ON?
                    .if     <[bp].FuncNumHi e 0>        AND ; Correct function #?
                    .if     <[bp].FuncNumLo e FUNC_NUM> AND ; 
                    .if     <[si].FuncIndex be MAX_INDEX> ; Invalid index?
                        sub     ax, ax  ; Clear return code
                        test    [si].Flags, PVB_SEL_BIT ; 
                        .if     <nz>    ; Asked for PVB update?
                            call    SetupPhysBuf ; Go get PVB as needed
                        .endif          ; 
                        .if     <zero ax> ; No error?

                            pusha                                       ;J-TS011792
                            push    _DATA                               ;J-TS011792
                            push    offset _SemAccessAPA                ;J-TS011792
                            push    -1                                  ;J-TS011792
                            push    -1                                  ;J-TS011792
                            call    DOSFSRAMSEMREQUEST                  ;J-TS011792
                            popa                                        ;J-TS011792

                            cld         ; 
                            mov     bx, [si].FuncIndex ; 
                            shl     bx, 1 ; Word align jump table
                            call    cs:DispTbl[bx] ; Dispatch to handler

                            pusha                                       ;J-TS011792
                            push    _DATA                               ;J-TS011792
                            push    offset _SemAccessAPA                ;J-TS011792
                            call    DOSFSRAMSEMCLEAR                    ;J-TS011792
                            popa                                        ;J-TS011792

                        .endif          ; 
                    .endif              ; 
                .endif                  ; 
            .endif                      ; 

;;---------------------------------------------------------------------------

            .if     < bit [bp].Sub_Option and Real_Mode > ; Real Mode   J-KK0112
                les     di, [bp].EnvBufParm ; ES:DI -> environment buffer J-KK0112
                add     di, es:[di].ModeDataOff ; ES:DI -> mode data struc J-KK0112
                inc     word ptr es:[di].mode_rows ; Inc Rows           J-KK0112
            .endif                      ;                               J-KK0112

            IFNDEF  INSTALLATION        ; Not Installation

                push    ax              ; Return Code

;; If Real mode or Read operation, not Redraw !!                       ;J-KKB12B
                .if     < bit [bp].Sub_Option nand Real_Mode+Read_Ope > ;J-KKB12B
;;
;;    Request To Xvio : Redraw                                          J-KK1017
;;
                    .if     < [bp].XVS_StartRow ne -1 > and ; No Error  J-KK1024
                    test    [bp].Sub_Flags, PVB_SEL_BIT ; PVB Update Request
                    .if     < nz >      ; 
                        .if     < <byte ptr [bp].XVS_Session> e 0 > ;   @KK0622
;;                                      ; If HardError, not call Xvio.  @KK0622
                            push    ds  ;                               @KK0622
                            push    _DATA ; DS : Global Segment         @KK0622
                            pop     ds  ;                               @KK0622
                            mov     ds:_HarderrFlag, 1 ; On=Now HardErr @KK0622
                            pop     ds  ;                               @KK0622
                        .else           ;                               @KK0622
                            .if     < bit [bp].Sub_Option and SPE_REDRAWN > ;@KK0622
                                mov     [bp].XVS_StartRow, 0 ;          ;@KK0622
                                mov     [bp].XVS_EndRow, -1 ;           ;@KK0622
                                or      byte ptr [bp].XVS_Option, HardErr_Redraw ;;@KK0622
                            .endif      ;                               ;@KK0622

                            .if     < bit [bp].Sub_Option and ALL_REDRAWN > or ;J-KK0206
                            .if     < bit [bp].Sub_Option and CLEARED_LVB > ; LVB Cleared ?
                                mov     [bp].XVS_StartRow, 0 ; All Redraw
                                mov     [bp].XVS_EndRow, -1 ; 
                            .endif      ; 

                            or      byte ptr [bp].XVS_Option, Resume ;      J-KK0213
                            mov     [bp].XVS_Length, 8 ; Length for Redraw
                            push    XvsRedraw ; 
                            push    ss  ; 
                            lea     ax,[bp].XVS_Length ; 
                            push    ax  ; 
                            Call    XVIOVDHIF ; 
                        .endif          ;                               @KK0622
                    .endif              ; 


                .endif                  ;                               J-KK0110

                pop     ax              ; Return Code

            ENDIF

        .endif                          ;Check PM Session               J-KK0110

        mov     [bp-2], ax              ; Return Code

        pop     es                      ; 
        pop     ds                      ; 
        popa                            ; 
        pop     bp                      ; 
        add     sp, WORK_END            ; Deallocate local storage      J-KKJ
        ret     12                      ; 

JBUFFERUPDATE ENDP                      ;;J-KKJ


        PUBLIC  SetupPhysBuf
SetupPhysBuf PROC NEAR

;************************************************************************
;*  On entry:           AX = 0                                          *
;*                      DS:SI -> parameter block                        *
;*                      ES:DI -> environment buffer (mode data)         *
;*                                                                      *
;*  Error exit:         AX = ERROR_VIO_INTERNAL_RESOURCE                *
;*  Normal exit:        AX = 0                                          *
;*  Effects:            AX, BX, CX, DX                                  *
;************************************************************************

        mov     bx, INSTSEG             ; 
        mov     ds, bx                  ; Setup per process data area

;************************************************************************
;*  If PVBSelector in NULL, indicating that the current process does    *
;*  not have a PVB selector allocated then _PhysToUVirt is called       *
;*  to allocate one.  If there is a PVB selector then the current       *
;*  PVB size along with its physical address will be checked against    *
;*  those contained in the environment buffer to see if anything has    *
;*  changed due to a prior set mode.  If any of these fields changed    *
;*  then the current PVB selector will be deallocated and a new one     *
;*  will be allocated based on it new size and/or physical address.     *
;************************************************************************
        mov     bx, es:[di].BufferaddrLo ; Get the physical address and
        mov     dx, es:[di].BufferAddrHi ;   PVB size of the current
        mov     si, es:[di].BufferLenLo ; 
        mov     cx, ds:PVBSelector      ; 
        verw    cx                      ; BUGBUG replace this with the
                                        ; VerifyW macro
        .if     <nz>                     OR ; Write acess?
        .if     <ds:PVBPhysAddrLo ne bx> OR ; Anything different due
        .if     <ds:PVBPhysAddrHi ne dx> OR ;   to mode change?
        .if     <ds:PVBSizeLo ne si>    ; 
            mov     ds:PVBPhysAddrLo, bx ; Keep them up to date
            mov     ds:PVBPhysAddrHi, dx ; 
            mov     ds:PVBSizeLo, si    ; 
            push    si                  ; Setup paramters for
            push    ds                  ;   PhysToUVirt call
            push    OFFSET PVBOffset    ;   ('C' routine)       ;@T30
            push    dx                  ; 
            push    bx                  ; 
            .if     <ncxz>              ; PVB selector already exists?
                push    cx              ; Deallocate it 1st
                call    _FreePhysToUVirt ; 
                add     sp, 2           ; Balance stack
            .endif                      ; 
            call    _PhysToUVirt        ; Allocate new PVB selector
            add     sp, 10              ; Balance
            les     di, [bp].EnvBufParm ; Re-setup mode data address
            add     di, es:[di].ModeDataOff ;   from the environment block
            mov     cx, ds:PVBSelector  ; Setup PVB selector
        .endif                          ; 
        .if     <zero ax>               ; No error encountered?
            mov     [bp].PVB_Sel, cx    ; Put PVB selector on stack
            lds     si, [bp].ParmBuf    ; Re-setup parameter block addr
        .else                           ; Error encountered!
            mov     ds:PVBSizelo, 0     ; Clear the necessary per
            mov     ds:PVBSelector, 0   ;   process fields
            mov     ax, ERROR_VIO_INTERNAL_RESOURCE
        .endif                          ; 
        ret

SetupPhysBuf ENDP


;***    SetGenParms - Set general parameters used by all buffer update functions
;
;       SetGenParms sets up basic information relating to LVB substitution.
;       The routine sets up the boundaries for the write based on whether
;       the LVB has been superceeded by passed parameters.
;
;       ENTRY   SS:BP - local data storage area
;               DS:SI - user passed parameter block
;               ES:DI - mode data structure
;
;       EXIT  Carry Clear
;               AX - index of right most row in LVB
;               CX - index of bottom most column in LVB
;               [bp].minrow - index of top most row in LVB (PVB coordinates)
;               [bp].mincol - index of left most col in LVB (PVB coordinates)
;               [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;               [bp].maxcol - index of right most col in LVB (PVB coordinates)
;               [bp].lvb_width - width of the LVB in cells
;               [bp].lvb_height - height of the LVB in cells
;               [bp].PVB_SEL - PVB selector if PVB write, else 0
;               [bp].LVB_SEL - LVB selector if LVB write, else 0
;
;             Carry Set
;               PVB format == LVB format == CGA format
;
;       CALLS   none
;
;       USES    AX,CX,DX,FLAGS
;
;       NOTES
;
;   PSEUDOCODE
;
;       if !(parmflags & USEPVB)
;           PVB_SEL = 0
;
;       if (parmflags & USELVB)
;           LVB_SEL = parmLVB
;       else
;           LVB_SEL = 0
;
;       cellsize = modeattrcnt + 1
;       if (US format PVB and LVB) &&
;          (Read or Write [not scroll or lvbtopvb])
;           Indicate US buffer type
;           return
;
;       if (parmlength >= LVBHeight)
;           mincol = parmLVBColOff
;           maxcol = parmLVBWidth + mincol
;           minrow = parmLVBRowOff
;           maxrow = parmLVBHeight + minrow
;           lvb_width = parmLVBWidth
;           lvb_height = parmLVBHeight
;           if (parmlength >= LVBAttrCount)
;               if (parmAttrCount == 3)
;                   cellsize = 4
;               else
;                   cellsize = 2
;       else
;           mincol = 0
;           maxcol = modeCols - 1
;           minrow = 0
;           maxrow = modeRows - 1
;           lvb_width = modeCols
;           lvb_height = modeRows
;

        PUBLIC  SetGenParms
SetGenParms PROC                        ;@P1 begin

        mov     [bp].Sub_index, 0       ; clear function index      ;J-TS0929

        test    [si].Flags, PVB_SEL_BIT ; 
        .if     <z>                     ; Do not update PVB?
            mov     [bp].PVB_Sel,0      ; do not use PVB selector
        .endif                          ; 
        .if     <[si].ParmLength a TouchXLeft > ;                     ;j-ys!1020
            or      [bp].Sub_Option, CA_Request ;                       ;j-ys111
        .endif                          ;                             ;j-ys!1020

        mov     ax, [si].LogicalBufSel  ; yes, use LVB
        mov     [bp].LVB_Sel,ax         ; save the LVB selector

        cmp     word ptr es:[di].AttrFormat,WorldFMTATTR ; Special format?
;;J-KKJ .if     <e>                     ;   Yes, use three byte attributes
        .if     <e> or                  ;   Yes, use three byte attributes;J-KKJ
        cmp     word ptr es:[di].AttrFormat,ATLAS3FMTATTR ; Special format?;J-KKJ
        .if     <e>                     ;   Yes, use three byte attributes;J-KKJ
            mov     [bp].cellsize,WorldCellSize
        .else
            mov     [bp].cellsize,DefaultCellSize
            cmp     ds:[si].ParmLength,LogicalBufSel+2
            .if     <e>                 ; Everything US normal
                mov     ax,ds:[si].FuncIndex ; write or read (not scroll)
                .if     <ax be I_ReadCellStr> or
                .if     <ax ae I_WrtCellStr> and
                .if     <ax be I_WrtNCell>
                    stc
                    jmp     short sgpx
                .endif
            .endif
        .endif

        cmp     ds:[si].ParmLength,LVBFormatID ; Did the caller specify LVB info?
        .if     <ae>                    ;   Yes, use callers information
            mov     cx,ds:[si].LVBColOff ; (cx) = left most column
            mov     [bp].mincol,cx      ; store left most column
            mov     dx,ds:[si].LVBWidth ; (dx) = number of columns
            mov     [bp].lvb_width,dx   ; store number of columns
            add     cx,dx               ; (cx) = right most column + 1
            dec     cx                  ; (cx) = right most column
            mov     [bp].maxcol,cx      ; store right most column
            mov     ax,ds:[si].LVBRowOff ; (ax) = top most row
            mov     [bp].minrow,ax      ; store top most row
            mov     dx,ds:[si].LVBHeight ; (dx) = number of rows
            mov     [bp].lvb_height,dx  ; store number of rows
            add     ax,dx               ; (ax) = bottom most row + 1
            dec     ax                  ; (ax) = bottom most row
            mov     [bp].maxrow,ax      ; store bottom most row
            cmp     ds:[si].ParmLength,LVBAttrCount + 1 ; Is the parm present?
            .if     <ae> and near       ;   Yes, attribute count is included
            cmp     word ptr ds:[si].LVBFormatID,WorldFMTATTR ; Special format?
            .if     <e> near            ;   Yes, use three byte attributes
                mov     [bp].cellsize,WorldCellSize
            .else
                mov     [bp].cellsize,DefaultCellSize
            .endif
        .else                           ; Use default screen group information
            mov     [bp].mincol,0       ; store left most column
            mov     cx,es:[di].TextCols ; (ax) = number of columns
            mov     [bp].lvb_width,cx   ; store number of columns
            dec     cx                  ; (ax) = right most column
            mov     [bp].maxcol,cx      ; store right most column
            mov     [bp].minrow,0       ; store top most row
            mov     ax,es:[di].TextRows ; (ax) = number of rows
            mov     [bp].lvb_height,ax  ; store number of rows
            dec     ax                  ; (ax) = bottom most row
            mov     [bp].maxrow,ax      ; store bottom most row
        .endif

        clc
sgpx:   ret

SetGenParms ENDP                        ;@P1 end

;***********************************************************************
;*   Entry    : CLEAR_LVB                                               J-KK1117
;*
;*   Function : Clear LVB
;*
;*      Must clear LVB after SetMode with a different Mode Index.
;*
;*   Input    : In Stack
;*              CLS_LVBSize    ; Get LVB Size
;*              CLS_Format     ; Get Format Index
;*              CLS_LVBSel     ; Get LVB Selector
;*   Output   : AX  - No Error   0
;*                    Error      others
;***********************************************************************
CLEAR_LVB proc  near                    ; 
        public  CLEAR_LVB
        push    bp
        mov     bp, sp

        push    bx
        push    cx
        push    es                      ; 
        push    di                      ; 
                                        ; 
        mov     ax, [bp].CLS_LVBSel     ; Get LVB Selector
        verw    ax                      ; Verify Selector
        .if     <z> and                 ; Selector Available
        lsl     bx, ax                  ; Get Selector Limit
        .if     <z> and                 ; No Error
        .if     < bx e 0FFFFh > or      ; If PreMode=Graphs, BX=0FFFFh  J-KKB12A
        inc     bx                      ; Adjust
        .if     < bx ae [bp].CLS_LVBSize > ; Enough Space
            mov     es, ax              ; 
            xor     di,di               ; 
            mov     cx, [bp].CLS_LVBSize ; Get LVB Size
            mov     bx, [bp].CLS_Format ; Get Format Index
                                        ; 
            .if     < bl e EPOCH_Format > ; Epoch Format
                mov     ax, 0020h       ; 
                shr     cx, 1           ; 
                rep     stosw           ; 
            .elseif < bl e ATLASUS_Format > ; U.S. Emualtion Format
                mov     ax, 0720h       ; 
                shr     cx, 1           ; 
                push    cx              ; 
                rep     stosw           ; 
                pop     cx              ; 
                mov     di, 1000h       ; 
                xor     ax, ax          ; 
                rep     stosw           ; 
            .else                       ; Atlas 3 byte Attribute Format
                                        ; Common Format
                mov     ax, 0720h       ;                              ;J-KK0911
                shr     cx, 2           ;                              ;J-KK0911
                push    cx              ;                              ;J-KK0911
                push    di              ;                              ;J-KK0911
                .repeat                 ;                              ;J-KK0911
                    stosw               ;                              ;J-KK0911
                    inc     di          ;                              ;J-KK0911
                    inc     di          ;                              ;J-KK0911
                .loop                   ;                              ;J-KK0911
                pop     di              ;                              ;J-KK0911
                pop     cx              ;                              ;J-KK0911

                xor     ax, ax          ;                              ;J-KK0911
                .repeat                 ;                              ;J-KK0911
                    inc     di          ;                              ;J-KK0911
                    inc     di          ;                              ;J-KK0911
                    stosw               ;                              ;J-KK0911
                .loop                   ;                              ;J-KK0911

            .endif                      ; 
            xor     ax, ax              ; No Error
        .else                           ; Unavailable
            mov     ax, 0ffffh          ; Error
        .endif                          ; 
                                        ; 
        pop     di                      ; 
        pop     es                      ; 
        pop     cx                      ; 
        pop     bx                      ; 
        pop     bp
        ret     6                       ; 
CLEAR_LVB endp                          ; 

;***********************************************************************
;*   Entry    : CheckDBCS
;*
;*   Function : Check if DBCS or not
;*
;*   Input    : AL = Checked Character Code Point
;*   Output   : CF = 0 if SBCS
;*                   1 if DBCS
;***********************************************************************
CheckDBCS PROC  NEAR                    ;                               J-KK1213
        Public  CheckDBCS               ; 
        push    bx                      ; 
        push    cx                      ; 
        push    dx                      ; 

        clc                             ;clear carry flag
        mov     cx,5                    ;set loop count
        lea     bx, [bp].Sub_DBCSEv     ; 
        .repeat
            mov     dx, ss:[bx]         ; 
            or      dx,dx               ; 
            jz      short DBCS_END      ; 
            cmp     dl,al               ; comp start value
            ja      short DBCS_END      ; smaller than lower limit ;kkj0
            cmp     al,dh               ; comp stop value
            jbe     short DBCS_OK       ; in range     ====> DBCS Chars
            inc     bx                  ; next vecter
            inc     bx                  ; 
        .loop
DBCS_OK:                                ;dbcs
        stc                             ;set carry flag
DBCS_END:                               ; 
        pop     dx                      ; 
        pop     cx                      ; 
        pop     bx                      ; 
        ret                             ; 
CheckDBCS ENDP                          ;dbcs



R2CSEG  ENDS
        END
