;       SCCSID = @(#)vioutil.asm        6.6 92/02/13
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        TITLE   VIO internal utility functions
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;@A0= add VIOREDRAWSIZE routine (DCR 85)
;     02-03-88
;$Z7= added VIOSSWSWITCH to clear/request fgSG's sem. during switch
;     07-15-87
;$Z8= suicide: terminate current PID after call to DOSKILLPROCESS
;     07-14-87
;$Z9= SESMGR can no longer kill any subtree, so this PID kills its own subtree
;     upon return from DOSFLAGPROCESS
;     07-10-87
;%A0= Add VIOFSRAMEXIT to cleanup currPID's fsRAMsem on termination
;     07-30-87
;%A1= Use FS RAM sems instead of system sems
;     07-30-87
;P2964= DosFSRAMSemRequest no longer sets count=1 during exitlist processing
;       06-15-88
;P3610= use CX to check for correct number of DOSFSRAMSEMCLEAR's until 0
;       09-13-88
;P3839= initCP called on SG's first VIO call (set video CP to process CP)
;       11-14-88 (1.2 PTM 2502)
;@T2  = 04/03/89 TPL, Sizzle work, PTR B701685
;@T5  = 05/10/89 TPL, PTR B701685 fix
;@T11 = 09/05/89 TPL, Register early and late exitlist routine, B785577
;D549 = 11/07/89 WKB, DCR549 Changes
;@T52 = 01/15/90 TPL, DCR 704 work
;@B50 = 03/21/90 WKB, Transparent popup over diff cp disallowed, B711349
;@T14 = 03/28/90 TPL, Remove duplication of functions
;@B722219 = 06/14/91 WKB, B722219 - Give up timeslice as appropriate
;@C51 = 08/01/91  CJJ, Get codepage during session init, VioSetCP in router.
;B727495 = 09/28/91 WKB, B727495 - Clear FSRamSem for up to use counts
;B728411 = 10/21/91 WKB, B728411 - Set fs_count to 1 before clear.
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.

.xlist
include error.inc
include error2.inc
include struc.inc
include infoseg.inc
include vioextrn.inc
include vioequ.inc
include viomac.inc
include vioidata.inc
include viocdata.inc
.list
.386p                                                                   ;D549

EXTRN   DOSGETDBCSEV:FAR        ;system call external definitions
EXTRN   DOSSEMREQUEST:FAR       ;
EXTRN   DOSSEMWAIT:FAR          ;
EXTRN   DOSFLAGPROCESS:FAR      ;
EXTRN   DOSKILLPROCESS:FAR      ;
EXTRN   DOSEXIT:FAR                                                     ;Z8I
EXTRN   DOSSLEEP:FAR                                                    ;B722219
EXTRN   DOSFSRAMSEMREQUEST:FAR                                          ;%A0I
EXTRN   DOSFSRAMSEMCLEAR:FAR                                            ;%A0I
EXTRN   DOSGETCP:FAR                                                    ;P3839
;@C51 EXTRN   VIOSETCP:FAR                                                    ;P3839
;EXTRN  Thunker:NEAR                                                    ;MDLL
;EXTRN  ThunkerFarRet:FAR                                               ;MDLL
EXTRN   BVSREDRAWSIZE:FAR                                               ;MDLL

public  check_dbc
public  suicide
public  VIOSSWSWITCH                                                    ;Z7I
public  VIOFSRAMEXIT0                                                   ;@T11
public  VIOFSRAMEXIT                                                    ;%A0I
public  VIOREDRAWSIZE                                                   ;@A0
public  initCP                                                          ;P3839

instance segment byte public 'data'     USE16                           ;D549
instance ends

common segment byte public 'far_data'   USE16                      ;D549;@T52
common ends

cseg    segment byte public 'code'      USE16                           ;D549
        assume  cs:cseg,ds:instance,es:common,ss:nothing
        page

        SUBTTL check_dbc - NZ if byte at ss:sp is first of double-byte
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAMES:  check_dbc                                        */
;/*                                                                     */
;/* DESCRIPTIVE NAMES:                                                  */
;/*                                                                     */
;/* FUNCTIONS:                                                          */
;/*                                                                     */
;/* NOTES:                                                              */
;/*                                                                     */
;/* ENTRY POINTS:  check_dbc                                            */
;/*     LINKAGES:  NEAR CALL                                            */
;/*                                                                     */
;/* INPUT:  sel:off (on stack) points to byte to be checked             */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0 (not double-byte)                              */
;/*                                                                     */
;/* EXIT-ERROR:  AX <> 0 (double-byte)                                  */
;/*                                                                     */
;/* EFFECTS:  None.                                                     */
;/*                                                                     */
;/* INTERNAL REFERENCES:  DS:dbcsrangebuf - DBCS environment vector     */
;/*                       ES:dbcsctrycode - DBCS country code           */
;/*            ROUTINES:  None.                                         */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None.                                         */
;/*            ROUTINES:  DOSGETDBCSEV - Get DBCS environment vector    */
;/*********************** END OF SPECIFICATIONS *************************/

check_dbc proc near
   enter 0,0
   push ds
   push es
   push gs                                                              ;@T80
   push bx
   push dx
   push di

   mov  ax,instance     ;DS <-- instance data selector
   mov  ds,ax           ;

   lgs   bx,ds:SGCB              ;load with SGCB ptr                    ;@T80

   mov  dx,common               ;ES <-- common data selector
   mov  es,dx                   ;

   .if <gs:[bx].VIO_dbcsflag e 0>                                       ;@T80
     push 10                    ;DBCS environment (list of valid        ;$Z6I
     push es                    ;ranges for double-byte's 1st byte  @T2 ;$Z6I
     push offset dbcsctrycode   ;terminated by 2 bytes of 0's)     ;$Z6I;@T52
     push gs                    ;                                       ;@T80
     lea  ax,gs:[bx].VIO_dbcsrangebuf                                   ;@T80
     push ax                    ;                                       ;$Z6I
     call DOSGETDBCSEV          ;                                       ;$Z6I
     mov  gs:[bx].VIO_dbcsflag,1        ;set DBCS flag                  ;@T80
   .endif

   mov  es,[bp]+6                                                       ;@T2
   mov  di,[bp]+4
   mov  al,es:[di]
   mov  di,0FFFFH
   cbw                                                                  ;@T2
   mov  es,dx                   ;ES <-- COMMON                          ;@T2

   mov  dx,word ptr gs:[bx].VIO_dbcsrangebuf                            ;@T80
   .while <nonzero dl> and
   .while <nonzero di>                                                  ;@T2

     .if <al ge dl> and         ;Within DBCS range?                     ;@T2
     .if <al le dh>                                                     ;@T2
       xor  di,di
       mov  ah,0FFH
     .endif

     add  bx,2
     mov  dx,word ptr gs:[bx].VIO_dbcsrangebuf ;Get next DBCS range     ;@T80
   .endwhile

   pop  di
   pop  dx
   pop  bx
   pop  gs                                                              ;@T80
   pop  es
   pop  ds
   leave
   ret  4                       ;return and pop parameters
check_dbc endp


        SUBTTL suicide - signal hard error task and wait to be killed
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAMES:  sucide                                           */
;/*                                                                     */
;/* DESCRIPTIVE NAMES: procedure used to commit suicide                 */
;/*                                                                     */
;/* FUNCTIONS:  signal Hard Error Task to kill this PID, then           */
;/*             call DOSSEMWAIT to wait forever until killed            */
;/*                                                                     */
;/* NOTES:                                                              */
;/*                                                                     */
;/* ENTRY POINTS:  suicide                                              */
;/*     LINKAGES:  NEAR CALL                                            */
;/*                                                                     */
;/* INPUT:  None.                                                       */
;/*                                                                     */
;/* EXIT-NORMAL:  no exit, wait to be killed                            */
;/*                                                                     */
;/* EXIT-ERROR:  no exit, wait to be killed                             */
;/*                                                                     */
;/* EFFECTS:  None.                                                     */
;/*                                                                     */
;/* INTERNAL REFERENCES:  None.                                         */
;/*            ROUTINES:  None.                                         */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None.                                         */
;/*            ROUTINES:  DOSFLAGPROCESS - set a process's event flag   */
;/*                       DOSSEMSETWAIT - wait for a DOSSEMCLEAR        */
;/*********************** END OF SPECIFICATIONS *************************/

suicide proc near

   .if <ds:currSG a 3>
     mov  ax,common
     mov  es,ax

     .repeat
       push es                                                          ;@T2
       push offset killramsem                                           ;@T52
       push wait_hi
       push wait_lo
       call DOSSEMREQUEST
     .until <ax ne ERROR_INTERRUPT>

     mov  ds,ds:ldtinfo
     mov  bx,ds:[LIS_CurProcID] ;BX <-- currPID <-- current process PID ;$Z9C
     mov  es:killPID,bx         ;                                       ;$Z9C
     mov  ax,ds:[LIS_CurScrnGrp];currSG <-- current screen group ID
     mov  es:killSG,ax          ;

     push 0                     ;enable signals
     call DOSHOLDSIGNAL         ;

     .repeat
       push es:hetpid           ;signal hard error task
       push 1                   ;signal hetpid ONLY
       push 0                   ;flag A
       push es                  ;                                       ;@T2
       call DOSFLAGPROCESS
     .until <zero ax>                                                   ;D549

     .repeat
       push es                                                          ;@T2
       push offset killramsem                                           ;@T52
       push wait_hi
       push wait_lo
       call DOSSEMWAIT
     .until <ax ne ERROR_INTERRUPT>

     push 0                     ;kill entire subtree                    ;$Z9I
     push bx                    ;my PID                                 ;$Z9I
     call DOSKILLPROCESS                                                ;$Z9I

     push 1                     ;terminate all threads                  ;$Z8I
     push 0                     ;return code                            ;$Z8I
     call DOSEXIT               ;terminate current PID                  ;$Z8I
   .endif

   ret
suicide endp


        SUBTTL VIOSSWSWITCH - clear/request per SG semaphore during switch
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAMES:  VIOSSWSWITCH                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAMES: clear/request semaphore for Screen Switcher      */
;/*                                                                     */
;/* FUNCTIONS:  Allows a process to make VIO calls during a VIOSCRLOCK  */
;/*             without timing out.                                     */
;/*                                                                     */
;/* ENTRY POINTS:  VIOSSWSWITCH                                         */
;/*     LINKAGES:  FAR CALL (undocumented, from SESMGR only)            */
;/*                                                                     */
;/* INPUT:  action = 0/1                                                */
;/*                  if action = 0:  clear current fgSG's semaphore     */
;/*                  if action = 1:  request current fgSG's semaphore   */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = NO_ERROR                                         */
;/*                                                                     */
;/* EXIT-ERROR:  AX = return code from DOSSEMCLEAR/DOSSEMREQUEST        */
;/*                                                                     */
;/* EFFECTS:  N/A                                                       */
;/*                                                                     */
;/* INTERNAL REFERENCES:                                                */
;/*            ROUTINES:                                                */
;/*                                                                     */
;/* EXTERNAL REFERENCES:                                                */
;/*            ROUTINES:                                                */
;/*********************** END OF SPECIFICATIONS *************************/

VIOSSWSWITCH proc far                                                   ;$Z7I
   enter 0,0    ;setup for BP
   push gs      ;save registers                                         ;@T80
   push ds      ;
   push bx      ;

   mov  ax,instance     ;DS <-- INSTANCE data selector
   mov  ds,ax           ;

   mov  gs,ds:gdtinfo           ;Get current foreground                 ;@T80
   mov  al,gs:[SIS_CurScrnGrp]  ;  Session ID                           ;@T80
   cbw                          ;                                       ;@T52

   push ds                      ;sel:off to SGCB address                ;@T52
   push offset SGCB_temp        ;  (returned)                           ;@T52
   push ax                      ;                                       ;@T52
   push Look_up_SGID            ;                                       ;@T52
   call DOSSMGETSGCB            ;Get SGCB pointer                       ;@T52

   .if  <zero ax>                                                       ;@T52

       lgs  bx,ds:SGCB_temp         ;load with SGCB ptr                 ;@T80
       add  bx,VIO_fsRAMsem                                             ;D549

       .if <<word ptr [bp+6]> eq 0>
         push gs                    ;clear fgSG's FS RAM sem   ;@T2;%A1C;@T80
         push bx                    ;                                   ;%A1C
         call DOSFSRAMSEMCLEAR      ;                                   ;%A1C
         mov ax, common                                                 ;B722219
         mov es, ax                                                     ;B722219
         mov ax, es:RamSem_SGID                                         ;B722219
         .if <ax eq ds:currSG>                                          ;B722219
            sub  eax,eax                                                ;B722219
            push eax                                                    ;B722219
            call DOSSLEEP           ;give up the timeslice              ;B722219
         .endif                                                         ;B722219
       .else

         .repeat
           push gs                  ;request fgSG's FS RAM sem ;@T2;%A1C;@T80
           push bx                  ;                                   ;%A1C
           push wait_hi             ;
           push wait_lo             ;
           call DOSFSRAMSEMREQUEST  ;                                   ;%A1C
         .until <ax ne ERROR_INTERRUPT>

       .endif
   .endif                                                               ;@T52
   pop  bx      ;restore registers
   pop  ds      ;
   pop  gs      ;                                                       ;@T80
   leave        ;restore BP
   ret  2
VIOSSWSWITCH endp                                                       ;$Z7I


        SUBTTL VIOFSRAMEXIT - fsRAMsem cleanup
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAMES:  VIOFSRAMEXIT                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAMES: cleanup this PID's fsRAMsem                      */
;/*                                                                     */
;/* FUNCTIONS:  If terminating PID owns its SG's fsRAMsem, call         */
;/*             DOSFSRAMSEMCLEAR enough times to set fs_count = 0       */
;/*                                                                     */
;/* ENTRY POINTS:  VIOFSRAMEXIT                                         */
;/*     LINKAGES:  FAR CALL (exit list routine)                         */
;/*                                                                     */
;/* INPUT: N/A                                                          */
;/*                                                                     */
;/* EXIT-NORMAL:  transfer to next exit list routine                    */
;/*                                                                     */
;/* EXIT-ERROR:  N/A                                                    */
;/*                                                                     */
;/* EFFECTS:  N/A                                                       */
;/*                                                                     */
;/* INTERNAL REFERENCES:                                                */
;/*            ROUTINES:                                                */
;/*                                                                     */
;/* EXTERNAL REFERENCES:                                                */
;/*            ROUTINES:                                                */
;/*********************** END OF SPECIFICATIONS *************************/

VIOFSRAMEXIT0 proc far                                                  ;@T11
   push ds                                                              ;@T11
   mov  ax,instance                                                     ;@T11
   mov  ds,ax                                                           ;@T11
   mov  ds:exitlist,1                                                   ;@T11
   pop  ds                                                              ;@T11
VIOFSRAMEXIT0 endp                                                      ;@T11

VIOFSRAMEXIT proc far                                                   ;$Z7I
   push gs      ;save registers                                         ;@T80
   push es      ;save registers
   push ds      ;
   push bx      ;
   push cx      ;

   mov  ax,instance     ;DS <-- INSTANCE data selector
   mov  ds,ax           ;

   mov  es,ds:ldtinfo           ;ES <-- local infoseg selector
   mov  dx,es:[LIS_CurProcID]   ;DX <-- current PID

   mov  ax,common       ;ES <-- COMMON data selector                    ;@T2
   mov  es,ax           ;                                               ;@T2

   lgs  bx,ds:SGCB              ;load gs:[bx] with FSRAMsem ptr         ;@T80
   add  bx,VIO_fsRAMsem         ;load gs:[bx] with FSRAMsem ptr         ;D549

     .if <gs:[bx].fs_PID eq dx> ;if currPID owns SG's FS RAM sem        ;@T80

       .repeat
         push gs                ;force ownership of FS RAM sem          ;@T80
         push bx                ;(always works in EXITLIST processing)
         push nowait_hi         ;
         push nowait_lo         ;
         call DOSFSRAMSEMREQUEST;
       .until <ax ne ERROR_INTERRUPT>

;B728411       mov  cx,gs:[bx].fs_count ;CX <-- number of times to clear sem.   ;P3610 ;D549
       mov  gs:[bx].fs_count,1  ;B728411                                ;@T80

;B728411      ;.repeat                                                          ;B727495
         push gs                                                        ;@T80
         push bx                ;
         call DOSFSRAMSEMCLEAR  ;
;B728411      ;.until <cx e 0>                                                  ;B727495

       mov ax, es:RamSem_SGID                                           ;B722219
       .if <ax eq ds:currSG>                                            ;B722219
          sub  eax,eax                                                  ;B722219
          push eax                                                      ;B722219
          call DOSSLEEP           ;give up the timeslice                ;B722219
       .endif                                                           ;B722219

       .if <ax eq ERROR_INTERRUPT>    ;if interrupted, try again      ;P3610
         inc  cx                      ;                               ;P3610
       .endif                         ;                               ;P3610

     .endif

   cmp  ds:exitlist,1           ;Early exitlist processing?             ;@T11
   .if  <z>                     ;                                       ;@T11
     mov  ds:exitlist,0         ;DON'T clear Z flag                     ;@T11
   .endif                       ;                                       ;@T11

   pop  cx      ;
   pop  bx      ;
   pop  ds      ;
   pop  es      ;
   pop  gs      ;                                                       ;@T80

   push 3                       ;transfer control to next routine on exit list
   push cs                      ;
   .if  <z>                                                             ;@T11
     push offset VIOFSRAMEXIT0                                          ;@T11
   .else                                                                ;@T11
     push offset VIOFSRAMEXIT   ;
   .endif                                                               ;@T11
   call DOSEXITLIST             ;
VIOFSRAMEXIT endp

cseg ends                                                               ;MDLL



CTEXT_TUNE4 segment byte public 'code'      USE16                       ;MDLL
        assume  cs:CTEXT_TUNE4,ds:instance,es:common,ss:nothing         ;MDLL

        SUBTTL VIOREDRAWSIZE - check screen size to be redrawn
        page
;/*********************** START OF SPECIFICATIONS *******************/  ;@A0
;/* SUBROUTINE NAMES:  VIOREDRAWSIZE                                */  ;@A0
;/*                                                                 */  ;@A0
;/* DESCRIPTIVE NAMES: check screen size to be redrawn              */  ;@A0
;/*                                                                 */  ;@A0
;/* FUNCTIONS:  Returns the number of bytes that may have been      */  ;@A0
;/*             dirtied by another SG since caller was in FG.       */  ;@A0
;/*                                                                 */  ;@A0
;/* ENTRY POINTS:  VIOREDRAWSIZE                                    */  ;@A0
;/*     LINKAGES:  FAR CALL (valid only from SHELLPID)              */  ;@A0
;/*                                                                 */  ;@A0
;/* INPUT: DWORD address of a DWORD data area where the number      */  ;@A0
;/*        of bytes is returned.                                    */  ;@A0
;/*                                                                 */  ;@A0
;/* EXIT-NORMAL:  AX = 0,  SIZE is returned to caller's data area   */  ;@A0
;/*                                                                 */  ;@A0
;/* EXIT-ERROR:  AX <> 0                                            */  ;@A0
;/*                                                                 */  ;@A0
;/* EFFECTS:  When VIOREDRAWSIZE is called from the shell process,  */  ;@A0
;/*           the "dirty" state is reset.                           */  ;@A0
;/*                                                                 */  ;@A0
;/* INTERNAL REFERENCES:                                            */  ;@A0
;/*            ROUTINES:                                            */  ;@A0
;/*                                                                 */  ;@A0
;/* EXTERNAL REFERENCES:                                            */  ;@A0
;/*            ROUTINES:                                            */  ;@A0
;/*********************** END OF SPECIFICATIONS *********************/  ;@A0

VIOREDRAWSIZE proc far                                                  ;@A0
   enter 0,0                                                            ;@A0
   push  es                                                             ;@A0
   push  ds                                                             ;@A0
   mov   ax,common                                                      ;@A0
   mov   es,ax                                                          ;@A0
   mov   ax,instance    ;AX <-- current PID                             ;@A0
   mov   ds,ax          ;                                          ;@T5 ;@A0
   mov   ax,ds:currPID  ;                                          ;@T5 ;@A0

   .if <ax ne es:SHELLPID>      ;error if caller not shell          ;@A0,@T14
     mov   ax,ERROR_VIO_SMG_ONLY;                                       ;@A0
   .else                                                                ;@A0
     CALL  BVSREDRAWSIZE        ;get redraw size from BVS               ;MDLL

     sub   ax,ax                ;no error if caller is shell            ;@T2
     .if <es:dirty a ax>        ;if screen has been "dirtied"      ;@T2 ;@A0
       push di                  ;                                       ;@T2
       mov  es:dirty,ax         ;reset "dirty" flag                ;@T2 ;@A0
       les  di,[bp+6]           ;ES:DI --> Size returned                ;@A0
       mov  es:[di],0FFFFH      ;Size returned = -1 (dword)             ;@A0
       mov  es:[di+2],0FFFFH    ;   means: redraw entire screen         ;@A0
       pop  di                  ;                                       ;@T2
     .endif                                                             ;@A0

   .endif                                                               ;@A0

   pop   ds                                                             ;@T5
   pop   es                                                             ;@A0
   leave                                                                ;@A0
   ret   4              ;return and pop parameters                      ;@A0
VIOREDRAWSIZE endp                                                      ;@A0
CTEXT_TUNE4   ends                                                      ;MDLL



CTEXT_TUNE2 segment byte public 'code'      USE16                       ;MDLL
        assume  cs:CTEXT_TUNE2,ds:instance,es:common,ss:nothing         ;MDLL

        SUBTTL initCP - setup a session's VIO codepage
        page
;/*********************** START OF SPECIFICATIONS *************************/
;/* SUBROUTINE NAMES:  initCP                                             */
;/*                                                                       */
;/* DESCRIPTIVE NAMES: initialize a session's VIO CP to the process CP    */
;/*                                                                       */
;/* FUNCTIONS:  The first VIO call for a session will SEM, call           */
;/*             DOSFSRAMSEMCLEAR enough times to set count = 0            */
;/*                                                                       */
;/* ENTRY POINTS:  initCP                                                 */
;/*     LINKAGES:  NEAR CALL (from viorout, VioRegister, & VioDeRegister) */
;/*                                                                       */
;/* INPUT: N/A                                                            */
;/*                                                                       */
;/* EXIT-NORMAL:  N/A                                                     */
;/*                                                                       */
;/* EXIT-ERROR:  N/A                                                      */
;/*                                                                       */
;/* EFFECTS:  sets a SG's video codepage to its process codepage          */
;/*                                                                       */
;/* INTERNAL REFERENCES:                                                  */
;/*            ROUTINES:                                                  */
;/*                                                                       */
;/* EXTERNAL REFERENCES:                                                  */
;/*            ROUTINES:                                                  */
;/*********************** END OF SPECIFICATIONS ***************************/

initCP proc near
   push ds      ;save registers
   push ax      ;

   mov  ax,instance     ;DS <-- INSTANCE data selector
   mov  ds,ax           ;

   .if <ds:procTYPE eq LIS_PT_FULLSCRN>  OR
   .if <ds:procTYPE eq LIS_PT_VIOWIN>
     push 2               ;get current session's process codepage
     push ds              ;
     push offset procCP   ;                                             ;@T52
     push ds              ;
     push offset procCPlength                                           ;@T52
     call DOSGETCP        ;

;@C51 ********* MOVED TO ROUTER ****
;@C51 push 0               ;set current session's video codepage
;@C51 push ds:procCP       ;
;@C51 push 0               ;
;@C51 call VIOSETCP        ;

;@C51 .if <zero ax>                             ;if codepage set ok      ;@B50
;@C51   mov  ax,ds:procCP                                                ;@B50
;@C51   mov  gs:[bx].VIO_CodePageID,ax          ;set SG codepage         ;@B50
;@C51 .endif                                                             ;@B50

   .endif

   pop  ax      ;restore registers
   pop  ds      ;

   ret
initCP endp

CTEXT_TUNE2   ends                                                      ;MDLL
     end
