]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/BIOS/MSSTACK.INC

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / BIOS / MSSTACK.INC
1 ; MSStack.inc
2 ;
3 ; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level)
4 ; should follow the standard Interrupt Sharing Scheme which has
5 ; a standard header structure.
6 ; Fyi, the following shows the relations between
7 ; the interrupt vector and interrupt level.
8 ; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77
9 ; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15
10 ; MSSTACK module modifies the following interrupt vectors
11 ; to meet the standard Interrupt Sharing standard;
12 ; A, B, C, D, E, 72, 73, 74, 76, 77.
13 ; Also, for interrupt level 7 and 15, the FirstFlag in a standard header
14 ; should be initialized to indicat whether this interrupt handler is
15 ; the first (= 80h) or not. The FirstFlag entry of INT77h's
16 ; program header is initialized in STKINIT.INC module.
17 ; FirstFlag is only meaningful for interrupt level 7 and 15.
18 ;
19
20 ; User specifies the number of stack elements - default = 9
21 ; minimum = 8
22 ; maximum = 64
23 ;
24 ; Intercepts Asynchronous Hardware Interrupts only
25 ;
26 ; Picks a stack from pool of stacks and switches to it
27 ;
28 ; Calls the previously saved interrupt vector after pushing flags
29 ;
30 ; On return, returns the stack to the stack pool
31 ;
32
33
34 ; This is a modification of STACKS:
35 ; 1. To fix a bug which was causing the program to take up too much space.
36 ; 2. To dispense stack space from hi-mem first rather than low-mem first.
37 ; . Clobbers the stack that got too big instead of innocent stack
38 ; . Allows system to work if the only stack that got too big was the most
39 ; deeply nested one
40 ; 3. Disables NMI interrupts while setting the NMI vector.
41 ; 4. Does not intercept any interupts on a PCjr.
42 ; 5. Double checks that a nested interrupt didn't get the same stack.
43 ; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products
44
45 ;The following variables are for MSSTACK.inc
46 EVEN
47 dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER
48 StackCount dw 0
49 StackAt dw 0
50 StackSize dw 0
51 Stacks dw 0
52 dw 0
53
54 FirstEntry dw Stacks
55 LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
56 NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
57
58 ;End of variables defined for MSSTACK.
59
60 ;*******************************************************************
61 ;Macro Interrupt handler for the ordinary interrupt vectors and
62 ;the shared interrupt vectors.
63 ;*****************************
64 Stack_Main MACRO AA
65 ASSUME DS:NOTHING
66 ASSUME ES:NOTHING
67 ASSUME SS:NOTHING
68 PUBLIC Int&AA
69 PUBLIC Old&AA
70 ;-----------------------------
71 ife IntSharingFlag ;if not IntSharingFlag
72 ;-----------------------------
73 Old&AA DD 0
74 Int&AA PROC FAR
75 ;-----------------------------
76 else ;for shared interrupt. A Header exists.
77
78 PUBLIC FirstFlag&AA
79 Int&AA PROC FAR
80 jmp short Entry_Int&AA&_Stk
81 Old&AA dd 0 ;Forward pointer
82 dw 424Bh ;compatible signature for Int. Sharing
83 FirstFlag&AA db 0 ;the firstly hooked.
84 jmp short Intret_&AA ;Reset routine. We don't care this.
85 db 7 dup (0) ;Reserved for future.
86 Entry_Int&AA&_Stk:
87 ;-----------------------------
88 endif
89 ;-----------------------------
90
91 ;
92 ; Keyboard interrupt must have a three byte jump, a NOP and a zero byte
93 ; as its first instruction for compatibility reasons
94 ifidn <&aa>,<09>
95 jmp Keyboard_lbl
96 nop
97 db 0
98 Keyboard_lbl label near
99 endif
100
101 ; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness,
102 ; rather than never hooking INT 75h, to maintain maximum compat. with IBMs
103 ; post production patch.
104 push ax
105
106 ifidn <&aa>,<02>
107
108 ; *********************************************************************
109 ;
110 ; This is special support for the PC Convertible / NMI handler
111 ;
112 ; On the PC Convertible, there is a situation where an NMI can be
113 ; caused by using the "OUT" instructions to certain ports. When this
114 ; occurs, the PC Convertible hardware *GUARANTEES* that **NOTHING**
115 ; can stop the NMI or interfere with getting to the NMI handler. This
116 ; includes other type of interrupts (hardware and software), and
117 ; also includes other type of NMI's. When any NMI has occured,
118 ; no other interrtupt (hardware, software or NMI) can occur until
119 ; the software takes specific steps to allow further interrupting.
120 ;
121 ; For PC Convertible, the situation where the NMI is generated by the
122 ; "OUT" to a control port requires "fixing-up" and re-attempting. In
123 ; otherwords, it is actually a "restartable exception". In this
124 ; case, the software handler must be able to get to the stack in
125 ; order to figure out what instruction caused the problem, where
126 ; it was "OUT"ing to and what value it was "OUT"ing. Therefore,
127 ; we will not switch stacks in this situation. This situation is
128 ; detected by interrogating port 62h, and checking for a bit value
129 ; of 80h. If set, *****DO NOT SWITCH STACKS*****.
130 ;
131 ; *********************************************************************
132
133 push es
134 mov ax,0f000h
135 mov es,ax
136 cmp byte ptr es:[0fffeh],mdl_convert ;check if convertible
137 pop es
138 jne Normal&aa
139
140 in al,62h
141 test al,80h
142 jz Normal&aa
143
144 Special&aa:
145 pop ax
146 jmp dword ptr Old&aa
147
148 Normal&aa:
149
150 ; *********************************************************************
151
152 endif
153
154 push bp
155 push es
156 mov es, cs:[STACKS+2] ; Get segment of stacks
157
158 mov bp,NextEntry ; get most likely candidate
159 mov al,Allocated
160 xchg AllocByte,al ; grab the entry
161 cmp al,Free ; still avail?
162 jne NotFree&aa
163
164 sub NextEntry,EntrySize ; set for next interrupt
165
166 Found&aa:
167 mov SavedSP,sp ; save sp value
168 mov SavedSS,ss ; save ss also
169 ; mov IntLevel,aa&h ; save the int level
170
171 mov ax,bp ; temp save of table offset
172
173 mov bp,NewSP ; get new SP value
174 cmp es:[bp],ax ; check for offset into table
175 jne FoundBad&aa
176
177 mov ax,es ; point ss,sp to the new stack
178 mov ss,ax
179 mov sp,bp
180
181 pushf ; go execute the real interrupt handler
182 call dword ptr old&aa ; which will iret back to here
183
184 mov bp,sp ; retrieve the table offset for us
185 mov bp,es:[bp] ; but leave it on the stack
186 mov ss,SavedSS ; get old stack back
187 mov sp,SavedSP
188
189 ; cmp AllocByte,Allocated ; If an error occured,
190 ; jne NewError&aa ; do not free us
191
192 mov AllocByte,Free ; free the entry
193 mov NextEntry,bp ; setup to use next time
194
195 NewError&aa:
196 pop es
197 pop bp ; saved on entry
198 pop ax ; saved on entry
199
200 INTRET_&AA: ;3.30
201 iret ; done with this interrupt
202
203 NotFree&aa:
204 cmp al,Allocated ; error flag
205 je findnext&aa ; no, continue
206 xchg AllocByte,al ; yes, restore error value
207
208 FindNext&aa:
209 call LongPath
210 jmp Found&aa
211
212 FoundBad&aa:
213 cmp bp,FirstEntry
214 jc findnext&aa
215 mov bp,ax ; flag this entry
216 mov AllocByte,Clobbered
217 ; add bp,EntrySize ; and previous entry
218 ; mov AllocByte,Overflowed
219 ; sub bp,EntrySize
220 jmp findnext&aa ; keep looking
221
222 int&aa endp
223
224
225 endm
226
227 ;***************************** ;3.30
228 ;End of Macro definition ;3.30
229 ;******************************************************************** ;3.30
230 ; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30
231 ;3.30
232 IRP A,<02,08,09,70> ;3.30
233 IntSharingFlag=0 ;3.30
234 Stack_Main &A ;3.30
235 ENDM ;3.30
236 ;3.30
237 IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30
238 IntSharingFlag=1 ;3.30
239 Stack_Main &A ;3.30
240 ENDM ;3.30
241 ;3.30
242 ;******************************************************************** ;3.30
243 ;Common routines ;3.30
244
245 longpath:
246 mov bp,LastEntry ; start with last entry in table
247
248 LPLOOPP: ;3.30
249 cmp AllocByte,Free ; is entry free?
250 jne inuse ; no, try next one
251
252 mov al,Allocated
253 xchg AllocByte,al ; allocate entry
254 cmp al,Free ; is it still free?
255 je found ; yes, go use it
256
257 cmp al,Allocated ; is it other than Allocated or Free?
258 je inuse ; no, check the next one
259
260 mov AllocByte,al ; yes, put back the error state
261
262 inuse:
263 cmp bp,FirstEntry
264 je Fatal
265 sub bp,EntrySize
266 JMP LPLOOPP ;3.30
267
268 found:
269 ret
270
271 page
272
273 fatal proc near
274 push ds ;3.30
275 mov ax, 0f000h ;loook at the model byte ;3.30
276 mov ds, ax ;3.30
277 cmp ds:byte ptr [0fffeh], mdl_convert ;convertible? ;3.30
278 pop ds ;3.30
279 jne Skip_NMIS ;3.30
280 ;3.30
281 mov al,07h ; disable PC Convertible NMIs
282 out 72h,al
283
284 Skip_NMIS: ;3.30
285 cli ; disable and mask
286 mov al,0ffh ; all other ints
287 out 021h,al
288 out 0a1h,al
289
290 mov si,cs
291 mov ds,si
292 mov si,offset fatal_msg
293
294 fatal_loop:
295 lodsb
296 cmp al,'$'
297 je fatal_done
298
299 mov bl,7 ;3.30*
300 mov ah,14 ;3.30*
301 int 010h ; whoops, this enables ints ;3.30*
302 jmp fatal_loop
303
304 fatal_done:
305 jmp fatal_done
306 fatal endp