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.
20 ; User specifies the number of stack elements - default = 9
24 ; Intercepts Asynchronous Hardware Interrupts only
26 ; Picks a stack from pool of stacks and switches to it
28 ; Calls the previously saved interrupt vector after pushing flags
30 ; On return, returns the stack to the stack pool
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
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
45 ;The following variables are for MSSTACK.inc
47 dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER
55 LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
56 NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
58 ;End of variables defined for MSSTACK.
60 ;*******************************************************************
61 ;Macro Interrupt handler for the ordinary interrupt vectors and
62 ;the shared interrupt vectors.
63 ;*****************************
70 ;-----------------------------
71 ife IntSharingFlag ;if not IntSharingFlag
72 ;-----------------------------
75 ;-----------------------------
76 else ;for shared interrupt. A Header exists.
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.
87 ;-----------------------------
89 ;-----------------------------
92 ; Keyboard interrupt must have a three byte jump, a NOP and a zero byte
93 ; as its first instruction for compatibility reasons
98 Keyboard_lbl label near
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.
108 ; *********************************************************************
110 ; This is special support for the PC Convertible / NMI handler
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.
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*****.
131 ; *********************************************************************
136 cmp byte ptr es:[0fffeh],mdl_convert ;check if convertible
150 ; *********************************************************************
156 mov es, cs:[STACKS+2] ; Get segment of stacks
158 mov bp,NextEntry ; get most likely candidate
160 xchg AllocByte,al ; grab the entry
161 cmp al,Free ; still avail?
164 sub NextEntry,EntrySize ; set for next interrupt
167 mov SavedSP,sp ; save sp value
168 mov SavedSS,ss ; save ss also
169 ; mov IntLevel,aa&h ; save the int level
171 mov ax,bp ; temp save of table offset
173 mov bp,NewSP ; get new SP value
174 cmp es:[bp],ax ; check for offset into table
177 mov ax,es ; point ss,sp to the new stack
181 pushf ; go execute the real interrupt handler
182 call dword ptr old&aa ; which will iret back to here
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
189 ; cmp AllocByte,Allocated ; If an error occured,
190 ; jne NewError&aa ; do not free us
192 mov AllocByte,Free ; free the entry
193 mov NextEntry,bp ; setup to use next time
197 pop bp ; saved on entry
198 pop ax ; saved on entry
201 iret ; done with this interrupt
204 cmp al,Allocated ; error flag
205 je findnext&aa ; no, continue
206 xchg AllocByte,al ; yes, restore error value
215 mov bp,ax ; flag this entry
216 mov AllocByte,Clobbered
217 ; add bp,EntrySize ; and previous entry
218 ; mov AllocByte,Overflowed
220 jmp findnext&aa ; keep looking
227 ;***************************** ;3.30
228 ;End of Macro definition ;3.30
229 ;******************************************************************** ;3.30
230 ; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30
232 IRP A,<02,08,09,70> ;3.30
233 IntSharingFlag=0 ;3.30
237 IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30
238 IntSharingFlag=1 ;3.30
242 ;******************************************************************** ;3.30
243 ;Common routines ;3.30
246 mov bp,LastEntry ; start with last entry in table
249 cmp AllocByte,Free ; is entry free?
250 jne inuse ; no, try next one
253 xchg AllocByte,al ; allocate entry
254 cmp al,Free ; is it still free?
255 je found ; yes, go use it
257 cmp al,Allocated ; is it other than Allocated or Free?
258 je inuse ; no, check the next one
260 mov AllocByte,al ; yes, put back the error state
275 mov ax, 0f000h ;loook at the model byte ;3.30
277 cmp ds:byte ptr [0fffeh], mdl_convert ;convertible? ;3.30
281 mov al,07h ; disable PC Convertible NMIs
285 cli ; disable and mask
286 mov al,0ffh ; all other ints
292 mov si,offset fatal_msg
301 int 010h ; whoops, this enables ints ;3.30*