1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (c) 2022 Michal Necasek
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Screen switching hook written in assembler.
; See minidrv.h for more.
SCREEN_SWITCH_OUT equ 4001h
SCREEN_SWITCH_IN equ 4002h
; Defined by us, must match minidrv.h
PREVENT_SWITCH equ 80h
; Carry flag bit on the stack
FLAG_CF equ 0001h
public _OldInt2Fh
public SWHook_
; Callbacks written in C
extrn SwitchToBgnd_ : far
extrn SwitchToFgnd_ : far
_DATA segment public 'DATA'
; Defined in C code
extrn _SwitchFlags : byte
; Dispatch table. Only used locally.
dsp_tbl label word
dw SwitchToBgnd_ ; SCREEN_SWITCH_OUT handler
dw SwitchToFgnd_ ; SCREEN_SWITCH_IN handler
_DATA ends
DGROUP group _DATA
_TEXT segment public 'CODE'
; Defined in code segment so that we can chain to the old interrupt
; handler without needing to mess with DS.
_OldInt2Fh dd 0
.386
; Screen switching hook for INT 2Fh. We need to handle screen switch
; notifications ourselves and let the previous handler deal with the
; rest.
SWHook_ proc far
; Cannot assume anything
assume ds:nothing, es:nothing
; Check if the subfunction is one of those we're
; interested in and chain to previous handler if not.
cmp ax, SCREEN_SWITCH_OUT
jz handle_fn
cmp ax, SCREEN_SWITCH_IN
jz handle_fn
jmp _OldInt2Fh ; Registers undisturbed (except flags)
; We are going to handle this interrupt and not chain.
handle_fn:
push ds ; Save what we can
pushad
; Establish data segment addressing
mov bx, _DATA ; We'll overwrite BX later
mov ds, bx
assume ds:DGROUP
mov bx, ax ; We will need the function later
mov bp, sp ; So we can address stack
; See if switching is disabled
mov al, _SwitchFlags
test al, PREVENT_SWITCH
jz dispatch ; If not set, do do the work
; It's disabled; set carry flag and return.
; To get to the saved flags, we need to skip the
; return address (4 bytes), saved DS (2 bytes), and
; saved registers (8 * 4 bytes)
FLG_OFS equ 4 + 2 + 8 * 4
or word ptr [bp + FLG_OFS], FLAG_CF
jmp exit
; Screen switching is not disabled; clear carry flag,
; process the screen switch notification, and return.
dispatch:
and word ptr [bp + FLG_OFS], NOT FLAG_CF
and bx, 2 ; Bit 1 of the subfunction
call dsp_tbl[bx] ; Call handler in C
exit:
popad ; Restore and return
pop ds
iret
SWHook_ endp
_TEXT ends
end
|