summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSSTACK.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/BIOS/MSSTACK.INC')
-rw-r--r--v4.0/src/BIOS/MSSTACK.INC306
1 files changed, 306 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/MSSTACK.INC b/v4.0/src/BIOS/MSSTACK.INC
new file mode 100644
index 0000000..21a2095
--- /dev/null
+++ b/v4.0/src/BIOS/MSSTACK.INC
@@ -0,0 +1,306 @@
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
48StackCount dw 0
49StackAt dw 0
50StackSize dw 0
51Stacks dw 0
52 dw 0
53
54FirstEntry dw Stacks
55LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
56NextEntry 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;*****************************
64Stack_Main MACRO AA
65 ASSUME DS:NOTHING
66 ASSUME ES:NOTHING
67 ASSUME SS:NOTHING
68PUBLIC Int&AA
69PUBLIC Old&AA
70;-----------------------------
71 ife IntSharingFlag ;if not IntSharingFlag
72;-----------------------------
73 Old&AA DD 0
74Int&AA PROC FAR
75;-----------------------------
76 else ;for shared interrupt. A Header exists.
77
78PUBLIC FirstFlag&AA
79Int&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.
86Entry_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
98Keyboard_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
144Special&aa:
145 pop ax
146 jmp dword ptr Old&aa
147
148Normal&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
166Found&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
195NewError&aa:
196 pop es
197 pop bp ; saved on entry
198 pop ax ; saved on entry
199
200INTRET_&AA: ;3.30
201 iret ; done with this interrupt
202
203NotFree&aa:
204 cmp al,Allocated ; error flag
205 je findnext&aa ; no, continue
206 xchg AllocByte,al ; yes, restore error value
207
208FindNext&aa:
209 call LongPath
210 jmp Found&aa
211
212FoundBad&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
222int&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
245longpath:
246 mov bp,LastEntry ; start with last entry in table
247
248LPLOOPP: ;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
262inuse:
263 cmp bp,FirstEntry
264 je Fatal
265 sub bp,EntrySize
266 JMP LPLOOPP ;3.30
267
268found:
269 ret
270
271 page
272
273fatal 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
284Skip_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
294fatal_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
304fatal_done:
305 jmp fatal_done
306fatal endp