2025-04-27 07:49:33 -04:00

227 lines
8.3 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1988 - 1991
; * All Rights Reserved.
; */
PAGE ,132 ;AN000;
TITLE DOS - GRAPHICS Command - Interrupt 2FH Driver ;AN000;
;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
;; DOS - GRAPHICS Command
;;
;; ;AN000;
;; File Name: GRINT2FH.ASM ;AN000;
;; ---------- ;AN000;
;; ;AN000;
;; Description: ;AN000;
;; ------------ ;AN000;
;; This file contains the Interrupt 2FH driver. ;AN000;
;; ;AN000;
;; Documentation Reference: ;AN000;
;; ------------------------ ;AN000;
;; OASIS High Level Design ;AN000;
;; OASIS GRAPHICS I1 Overview ;AN000;
;; ;AN000;
;; Procedures Contained in This File: ;AN000;
;; ---------------------------------- ;AN000;
;; INT_2FH_DRIVER - Interrupt 2FH driver ;AN000;
;; ;AN000;
;; Include Files Required: ;AN000;
;; ----------------------- ;AN000;
;; GRLOAD.EXT - Externals for profile load ;AN000;
;; GRCTRL.EXT - Externals for print screen control ;AN000;
;; GRPRINT.EXT - Externals for print modules ;AN000;
;; GRCPSD.EXT - Externals for COPY_SHARED_DATA module ;AN000;
;; ;AN000;
;; External Procedure References: ;AN000;
;; ------------------------------ ;AN000;
;; Calls next Int 2FH handler in the chain. ;AN000;
;; ;AN000;
;; Linkage Instructions: ;AN000;
;; -------------------- ;AN000;
;; Refer to GRAPHICS.ASM ;AN000;
;; ;AN000;
;; Change History:
;; ---------------
;; M001 NSM 1/30/91 New int 10 handler to trap alt-prt-sc select
;; calls made by ANSI.SYS. For these calls, we
;; we need to reinstall our int 5 handler again
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
;; ;AN000;
;; ;AN000;
CODE SEGMENT PUBLIC 'CODE' ;; ;AN000;
ASSUME CS:CODE,DS:CODE ;; ;AN000;
;; ;AN000;
PUBLIC OLD_INT_2FH ;; ;AN000;
PUBLIC INT_2FH_DRIVER ;; ;AN000;
PUBLIC INT_10H_DRIVER ;; ;AN000;
PUBLIC PRT_SCR_2FH_NUMBER ;; ;AN000;
PUBLIC RESIDENT_CODE_SEG ;; ;AN000;
PUBLIC SHARED_DATA_AREA_PTR ;; ;AN000;
;; ;AN000;
;; ;AN000;
.XLIST ;AN000;
INCLUDE STRUC.INC ;AN000;
INCLUDE GRINST.EXT ;AN000;
INCLUDE GRCTRL.EXT ;AN000;
INCLUDE GRCPSD.EXT ;AN000;
.LIST ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
;; ;AN000;
;; Module: INT_2FH_DRIVER ;AN000;
;; ;AN000;
;; Description: ;AN000;
;; Respond to GRAPHICS Int 2FH calls. ;AN000;
;; The following calls are handled: ;AN000;
;; ;AN000;
;; AL = 0 <20> Install Check ;AN000;
;; ;AN000;
;; Invoked By: ;AN000;
;; INT 2FH instruction. ;AN000;
;; ;AN000;
;; Modules Called: ;AN000;
;; Lower level INT 2FH handlers. ;AN000;
;; ;AN000;
;; Input Registers: ;AN000;
;; Install Check - AH=ACH AL=0 ;AN000;
;; ;AN000;
;; ;AN000;
;; Output Registers: ;AN000;
;; Install Check: IF GRAPHICS installed ;AN000;
;; AH=FFH AL=FFH ;AN000;
;; ES : DI points to Shared Data Area ;AN000;
;; ELSE ;AN000;
;; AH=ACH AL=0 ;AN000;
;; ;AN000;
;; Logic: ;AN000;
;; IF AH=ACH THEN ;AN000;
;; IF AL=0 THEN ;AN000;
;; AH,AL := -1 ;AN000;
;; ES : DI := SHARED_DATA_AREA_PTR ;AN000;
;; ENDIF ;AN000;
;; IRET ;AN000;
;; ELSE ;AN000;
;; IF OLD_INT_2FH is a valid pointer THEN ;AN000;
;; Jump to Old Int 2FH ;AN000;
;; ELSE ;AN000;
;; IRET ;AN000;
;; ENDIF ;AN000;
;; ENDIF ;AN000;
;; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
;AN000;
INT_2FH_DRIVER PROC NEAR ;AN000;
JMP SHORT INT_2FH ;AN000;
PRT_SCR_2FH_NUMBER EQU 0ACH ; 2FH Multiplex interrupt number ;AN000;
; assigned to Print Screen. ;AN000;
OLD_INT_2FH DD ? ; Pointer to next 2FH interrupt handler ;AN000;
RESIDENT_CODE_SEG DW ? ; Segment for installed stuff ;AN000;
SHARED_DATA_AREA_PTR DW ? ; Offset of the start of the ;AN000;
; Shared Data Area ;AN000;
;AN000;
INT_2FH: ;AN000;
;-------------------------------------------------------------------------------;AN000;
; Verify if the 2FH Interrupt call is for our interrupt handler: ;AN000;
;-------------------------------------------------------------------------------;AN000;
.IF <AH EQ PRT_SCR_2FH_NUMBER> AND;If 2FH call is for us ;AN000;
.IF <ZERO AL> ; and request is "Get install state" ;AN000;
.THEN ; then, ;AN000;
;-------------------------------------------------------------------------------;AN000;
; Yes: return results ;AN000;
;-------------------------------------------------------------------------------;AN000;
MOV DI,CS:SHARED_DATA_AREA_PTR ; ES:DI := Pointer to shared ;AN000;
PUSH CS:RESIDENT_CODE_SEG ; data area ;AN000;
POP ES ; ;AN000;
MOV AH,0FFH ; AL and AH := "We are installed" ;AN000;
MOV AL,AH ; ;AN000;
IRET ; Return to interrupted process ;AN000;
;-------------------------------------------------------------------------------;AN000;
; No, pass control to next 2FH interrupt handler: ;AN000;
;-------------------------------------------------------------------------------;AN000;
.ELSE ; else, this call is not for us: ;AN000;
.IF <<WORD PTR CS:OLD_INT_2FH> NE 0> AND ;if there is another ;AN000;
.IF <<WORD PTR CS:OLD_INT_2FH+2> NE 0> ; 2FH driver ;AN000;
.THEN ; below us then, ;AN000;
JMP CS:OLD_INT_2FH ; pass control to it ;AN000;
.ELSE ; else, there is nobody to pass ;AN000;
IRET ; control to, just return. ;AN000;
.ENDIF ; END If there is a driver below us.;AN000;
.ENDIF ; END If this call is for us. ;AN000;
INT_2FH_DRIVER ENDP ;AN000;
;AN000;
;/*M001 BEGIN */
;========================================================================
; INT_10h_Driver :
; int 10 handler to check for alt-prt-sc-select calls (ah=12,bl=20h)
; Other int 10 calls are passed on. For alt-prt-sc-select calls,
; old int 10 is called and after return, we reinstall our int 5 (prt_sc)
; vector back again ( if it was changed by ANSI.SYS).
;=======================================================================
INT_10H_DRIVER PROC NEAR
sti ; restore interrupts
cmp ah,ALTERNATE_SELECT ; see if the call is for
jnz go_old_int10 ; alt_prt_sc; if so
cmp bl,ALT_PRT_SC_SELECT ; call int 10 and then
jz Set_Our_Int5_handler ; restore out PRT_SC vector
go_old_int10: ; other int 10 calls
jmp DWORD PTR cs:OLD_INT_10H ; ...pass it on.
; the call is for alternate prt Screen int 10
; call the old int 10 handler and then restore our int 5 vector back again
Set_Our_Int5_handler:
pushf
call DWORD PTR cs:OLD_INT_10H ; call the prev.int 10 handler
push ax
push bx
push cx
push dx
push si
push di
push ds
xor ax,ax
mov ds,ax ; ds-> 0 to get at int.vector table
mov si,5 * 4 ; ds:si -> ptr to int 5 vector
mov cx,cs
mov dx,offset PRT_SCR
cli
mov ax,ds:[si+2] ; segment for current int 5 vector
cmp ax,cx ; is it changed by ROM BIOS
je no_int5_chg
mov bx,ds:[si]
cmp bx, dx ;further sanity check for offset
je no_int5_chg
; cx:dx = our int 5 handler
; ax:bx = current int 5 handler
; store the current int 5 handler as the old handler and install ourselves
; again
mov ds:[si],dx ; store offset
mov ds:[si+2],cx ; store segment
mov CS:[BIOS_INT_5H],bx ; store old int5 vector
mov CS:[BIOS_INT_5H +2],ax
no_int5_chg:
sti
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
INT_10H_DRIVER ENDP
; /* M001 END */
CODE ENDS ;AN000;
END ;AN000;