;       SCCSID = @(#)vioprtsc.asm       6.2 92/02/13
;# SCCSID = @(#)vioprtsc.asm    6.2 92/02/13
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        SUBTTL  AVS_PRTSC, AVS_PRTSCTOGGLE
        TITLE   VIOPRTSC.ASM
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;$$$= new code for created threads on registered PRTSC/PRTSCTOGGLE
;     06-04-87
;@T2  = 04/03/89 TPL, Sizzle work, PTR B700???
;D549 = 11/07/89 WKB, DCR549 Changes
;@T52 = 01/15/90 TPL, DCR 704 work
;@T13 = 02/27/90 TPL, Fix multiple register/deregister requests, B711643
;@T14 = 03/28/90 TPL, Remove duplication of functions
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;@TAK = 03/06/93 T Kirschner, Defect 62883 VioRegister Trap.
;JLO1 = 10/05/94 JLO, Defect 101282 : AVS_PRTSC saves tkstack in wrong segment

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

EXTRN   DOSENTERCRITSEC:FAR                                             ;@T13
EXTRN   DOSSEMSETWAIT:FAR
EXTRN   DOSEXIT:FAR
EXTRN   DOSSEMCLEAR:FAR
EXTRN   vioattach:NEAR


public  AVS_PRTSC
public  AVS_PRTSCTOGGLE

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 AVS_PRTSC - registered VIOPRTSC routine
        page
;/*********************** START OF SPECIFICATIONS ***************************/
;/* SUBROUTINE NAME: AVS_PRTSC                                              */
;/*                                                                         */
;/* DESCRIPTIVE NAME: Thread created for this proc. when VIOPRTSC is        */
;/*                   registered via VIOREGISTER,                           */
;/*                                                                         */
;/* FUNCTION: Waits to be signaled via semaphore, then calls AVS's          */
;/*           entry point.                                                  */
;/*                                                                         */
;/* NOTES: kills self when released with ES:[BX].prtscAX = -1               */
;/*                                                                         */
;/* ENTRY POINT: AVS_PRTSC                                                  */
;/*     LINKAGE: FAR CALL (from VIOREGISTER via DOSCREATETHREAD)            */
;/*                                                                         */
;/* INPUT: N/A                                                              */
;/*                                                                         */
;/* EXIT-NORMAL: returns error code from AVS to viorout through             */
;/*              ES:[BX].prtscAX                                            */
;/*                                                                         */
;/* EXIT-ERROR: N/A                                                         */
;/*                                                                         */
;/* EFFECTS:                                                                */
;/*                                                                         */
;/* INTERNAL                                                                */
;/* REFERENCES:                                                             */
;/*   ROUTINES:                                                             */
;/*                                                                         */
;/* EXTERNAL                                                                */
;/* REFERENCES:                                                             */
;/*   ROUTINES:                                                             */
;/*                                                                         */
;/*********************** END OF SPECIFICATIONS *****************************/

AVS_PRTSC proc far
   mov  ax,instance             ;DS <-- INSTANCE data seg. selector
   mov  ds,ax                   ;

   mov  es,ds:ldtinfo           ;currSG <-- current screen group
   mov  ax,es:[LIS_CurScrnGrp]  ;

   push common                  ;ES <-- COMMON data seg. selector
   pop  es                      ;

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

   les   di,gs:[bx].VIO_avscbptr;ptr to avscb                      ;D549,@T80

ps_loop:
   push es              ;RAMsem handle
   lea  ax,es:[di].ps_enter                                             ;D549?
   push ax              ;
   push 0FFFFH          ;no timeout
   push 0FFFFH          ;
   call DOSSEMWAIT      ;wait until signaled                            ;@T13

   .if <es:[di].prtscAX eq 0FFFFH>                                      ;D549
     call DOSENTERCRITSEC                                               ;@T13

     push es            ;RAMsem handle                                  ;D549
     lea  ax,es:[di].ps_exit                                            ;D549
     push ax                                                            ;D549
     call DOSSEMCLEAR   ;clear ps_exit sem                              ;D549

     push 0             ;kill current thread
     push 0             ;resultcode
     call DOSEXIT
   .else
     mov  ax,ds:oldtimes

     .if <ax ne gs:[bx].VIO_times>                                 ;D549,@T80
       sub   sp,4       ;Include dummy function code & return IP        ;@T2
       push  ds         ;save DS
       enter 10,0       ;setup BP and allocate 4 words local storage    ;1.2
       push  es         ;save registers
       push  gs                                                    ;D549,@T80
       pusha            ;
       call  vioattach
       popa
       pop   gs                                                    ;D549,@T80
       pop   es
       leave
       pop   ds         ;restore DS
       add  sp,4        ;remove dummy IP and function code
     .endif

     ; Save key registers and stack reference, so printscreen           ;@TAK
     ; handler can clobber.                                             ;@TAK

     push es            ;save ES                                        ;@TAK
     push si            ;save SI                                        ;@TAK
     push di            ;save DI                                        ;@TAK
     push bx            ;save BX                                        ;@TAK

     mov  bx,common                                                     ;JLO1
     mov  es,bx                                                         ;JLO1
     mov  es:tkstack,sp ;save stack ref - application may nuke          ;JLO1
;;;  mov  tkstack, sp   ;save stack ref - application may nuke          ;@TAK ;JLO1

     push 0000H         ;VIO handle
     sub  sp,4          ;Include dummy CS:IP                            ;@T2
     push fc_prtsc      ;VIOPRTSC function code
     push 0000H         ;VIOPRTSC near IP (dummy)
     push ds            ;caller's DS

     call dword ptr ds:avs_off  ;call AVS entry point

     mov  bx,common                                                     ;JLO1
     mov  es,bx                                                         ;JLO1
     mov  sp,es:tkstack ;restore stack                                  ;JLO1
;;;  mov  sp, tkstack   ;restore stack                                  ;@TAK ;JLO1
;    add  sp,12                                                         ;@T14@TAK

     pop     bx         ;save BX                                        ;@TAK
     pop     di         ;save DI                                        ;@TAK
     pop     si         ;save SI                                        ;@TAK
     pop     es         ;save ES                                        ;@TAK

     mov  es:[di].prtscAX,ax    ;tell viorout what ret. AX was          ;D549

     push  es           ;RAMsem handle                                  ;@T13
     lea   ax,[di].ps_enter                                             ;@T13
     push  ax           ;                                               ;@T13
     call  DOSSEMSET    ;unconditionally set RAM sem                    ;@T13

     push es            ;RAMsem handle
     lea  ax,es:[di].ps_exit                                            ;D549
     push ax            ;
     call DOSSEMCLEAR   ;tell viorout that we are done
   .endif

   jmp  ps_loop
AVS_PRTSC endp

        page

        SUBTTL AVS_prtsctoggle - registered VIOprtsctoggle routine
        page
;/*********************** START OF SPECIFICATIONS ***************************/
;/* SUBROUTINE NAME: AVS_prtsctoggle                                        */
;/*                                                                         */
;/* DESCRIPTIVE NAME: Thread created for this proc. when VIOprtsctoggle is  */
;/*                   registered via VIOREGISTER,                           */
;/*                                                                         */
;/* FUNCTION: Waits to be signaled via semaphore, then calls AVS's          */
;/*           entry point.                                                  */
;/*                                                                         */
;/* NOTES: kills self when released with ES:[BX].prtsctogAX = -1            */
;/*                                                                         */
;/* ENTRY POINT: AVS_prtsctoggle                                            */
;/*     LINKAGE: FAR CALL (from VIOREGISTER via DOSCREATETHREAD)            */
;/*                                                                         */
;/* INPUT: N/A                                                              */
;/*                                                                         */
;/* EXIT-NORMAL: returns error code from AVS to viorout through             */
;/*              ES:[BX].prtsctogAX                                         */
;/*                                                                         */
;/* EXIT-ERROR: N/A                                                         */
;/*                                                                         */
;/* EFFECTS:                                                                */
;/*                                                                         */
;/* INTERNAL                                                                */
;/* REFERENCES:                                                             */
;/*   ROUTINES:                                                             */
;/*                                                                         */
;/* EXTERNAL                                                                */
;/* REFERENCES:                                                             */
;/*   ROUTINES:                                                             */
;/*                                                                         */
;/*********************** END OF SPECIFICATIONS *****************************/

AVS_PRTSCTOGGLE proc far
   mov  ax,instance             ;DS <-- INSTANCE data seg. selector
   mov  ds,ax                   ;

   mov  es,ds:ldtinfo           ;currSG <-- current screen group
   mov  ax,es:[LIS_CurScrnGrp]  ;

   push common                  ;ES <-- COMMON data seg. selector
   pop  es                      ;

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

pstog_loop:
   les   di,gs:[bx].VIO_avscbptr;ptr to avscb                      ;D549,@T80
   push es              ;RAMsem handle
   lea  ax,es:[di].pstog_enter                                          ;D549
   push ax              ;
   push 0FFFFH          ;no timeout
   push 0FFFFH          ;
   call DOSSEMWAIT      ;wait until signaled                            ;@T13

   .if <es:[di].prtsctogAX eq 0FFFFH>                                   ;D549
     call DOSENTERCRITSEC                                               ;@T13

     push es            ;RAMsem handle                                  ;D549
     lea  ax,es:[di].pstog_exit                                         ;D549
     push ax                                                            ;D549
     call DOSSEMCLEAR   ;clear ps_exit sem                              ;D549

     push 0             ;kill current thread
     push 0             ;resultcode
     call DOSEXIT
   .else
     mov  ax,ds:oldtimes

     .if <ax ne gs:[bx].VIO_times>                                 ;D549;@T80
       sub   sp,4       ;Include dummy function code & return IP        ;@T2
       push  ds         ;save DS
       enter 10,0       ;setup BP and allocate 4 words local storage    ;1.2
       push  es         ;save registers
       push  gs                                                    ;D549,@T80
       pusha            ;
       call  vioattach
       popa
       pop   gs                                                    ;D549,@T80
       pop   es
       leave
       pop   ds         ;restore DS
       add  sp,4        ;remove dummy IP and function code
     .endif

     push 0000H           ;VIO handle
     sub  sp,4            ;Include dummy CS:IP                          ;@T2
     push fc_prtsctoggle  ;VIOPRTSC function code
     push 0000H           ;VIOPRTSC near IP (dummy)
     push ds              ;caller's DS

     call dword ptr ds:avs_off  ;call AVS entry point
     mov  gs:[bx].prtsctogAX,ax ;tell viorout what ret. AX was     ;D549,@T80
     add  sp,12                                                         ;@T14

     push  es           ;RAMsem handle                                  ;@T13
     lea   ax,[di].pstog_enter                                          ;@T13
     push  ax           ;                                               ;@T13
     call  DOSSEMSET    ;unconditionally set RAM sem                    ;@T13

     push es            ;RAMsem handle
     lea  ax,es:[di].pstog_exit                                         ;D549
     push ax            ;
     call DOSSEMCLEAR     ;tell viorout that we are done
   .endif

   jmp  pstog_loop
AVS_PRTSCTOGGLE endp

cseg ends
     end
