mirror of https://github.com/AR1972/DOS3.3
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
8.2 KiB
306 lines
8.2 KiB
; MSStack.inc
|
|
;
|
|
; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level)
|
|
; should follow the standard Interrupt Sharing Scheme which has
|
|
; a standard header structure.
|
|
; Fyi, the following shows the relations between
|
|
; the interrupt vector and interrupt level.
|
|
; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77
|
|
; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15
|
|
; MSSTACK module modifies the following interrupt vectors
|
|
; to meet the standard Interrupt Sharing standard;
|
|
; A, B, C, D, E, 72, 73, 74, 76, 77.
|
|
; Also, for interrupt level 7 and 15, the FirstFlag in a standard header
|
|
; should be initialized to indicat whether this interrupt handler is
|
|
; the first (= 80h) or not. The FirstFlag entry of INT77h's
|
|
; program header is initialized in STKINIT.INC module.
|
|
; FirstFlag is only meaningful for interrupt level 7 and 15.
|
|
;
|
|
|
|
; User specifies the number of stack elements - default = 9
|
|
; minimum = 8
|
|
; maximum = 64
|
|
;
|
|
; Intercepts Asynchronous Hardware Interrupts only
|
|
;
|
|
; Picks a stack from pool of stacks and switches to it
|
|
;
|
|
; Calls the previously saved interrupt vector after pushing flags
|
|
;
|
|
; On return, returns the stack to the stack pool
|
|
;
|
|
|
|
|
|
; This is a modification of STACKS:
|
|
; 1. To fix a bug which was causing the program to take up too much space.
|
|
; 2. To dispense stack space from hi-mem first rather than low-mem first.
|
|
; . Clobbers the stack that got too big instead of innocent stack
|
|
; . Allows system to work if the only stack that got too big was the most
|
|
; deeply nested one
|
|
; 3. Disables NMI interrupts while setting the NMI vector.
|
|
; 4. Does not intercept any interupts on a PCjr.
|
|
; 5. Double checks that a nested interrupt didn't get the same stack.
|
|
; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products
|
|
|
|
;The following variables are for MSSTACK.inc
|
|
EVEN
|
|
dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER
|
|
StackCount dw 0
|
|
StackAt dw 0
|
|
StackSize dw 0
|
|
Stacks dw 0
|
|
dw 0
|
|
|
|
FirstEntry dw Stacks
|
|
LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
|
|
NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
|
|
|
|
;End of variables defined for MSSTACK.
|
|
|
|
;*******************************************************************
|
|
;Macro Interrupt handler for the ordinary interrupt vectors and
|
|
;the shared interrupt vectors.
|
|
;*****************************
|
|
Stack_Main MACRO AA
|
|
ASSUME DS:NOTHING
|
|
ASSUME ES:NOTHING
|
|
ASSUME SS:NOTHING
|
|
PUBLIC Int&AA
|
|
PUBLIC Old&AA
|
|
;-----------------------------
|
|
ife IntSharingFlag ;if not IntSharingFlag
|
|
;-----------------------------
|
|
Old&AA DD 0
|
|
Int&AA PROC FAR
|
|
;-----------------------------
|
|
else ;for shared interrupt. A Header exists.
|
|
|
|
PUBLIC FirstFlag&AA
|
|
Int&AA PROC FAR
|
|
jmp short Entry_Int&AA&_Stk
|
|
Old&AA dd 0 ;Forward pointer
|
|
dw 424Bh ;compatible signature for Int. Sharing
|
|
FirstFlag&AA db 0 ;the firstly hooked.
|
|
jmp short Intret_&AA ;Reset routine. We don't care this.
|
|
db 7 dup (0) ;Reserved for future.
|
|
Entry_Int&AA&_Stk:
|
|
;-----------------------------
|
|
endif
|
|
;-----------------------------
|
|
|
|
;
|
|
; Keyboard interrupt must have a three byte jump, a NOP and a zero byte
|
|
; as its first instruction for compatibility reasons
|
|
ifidn <&aa>,<09>
|
|
jmp Keyboard_lbl
|
|
nop
|
|
db 0
|
|
Keyboard_lbl label near
|
|
endif
|
|
|
|
; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness,
|
|
; rather than never hooking INT 75h, to maintain maximum compat. with IBMs
|
|
; post production patch.
|
|
push ax
|
|
|
|
ifidn <&aa>,<02>
|
|
|
|
; *********************************************************************
|
|
;
|
|
; This is special support for the P12 / NMI handler
|
|
;
|
|
; On the P12, there is a situation where an NMI can be caused by
|
|
; using the "OUT" instructions to certain ports. When this
|
|
; occurs, the P12 hardware *GUARANTEES* that **NOTHING** can stop
|
|
; the NMI or interfere with getting to the NMI handler. This
|
|
; includes other type of interrupts (hardware and software), and
|
|
; also includes other type of NMI's. When any NMI has occured,
|
|
; no other interrtupt (hardware, software or NMI) can occur until
|
|
; the software takes specific steps to allow further interrupting.
|
|
;
|
|
; For P12, the situation where the NMI is generated by the "OUT"
|
|
; to a control port requires "fixing-up" and re-attempting. In
|
|
; otherwords, it is actually a "restartable exception". In this
|
|
; case, the software handler must be able to get to the stack in
|
|
; order to figure out what instruction caused the problem, where
|
|
; it was "OUT"ing to and what value it was "OUT"ing. Therefore,
|
|
; we will not switch stacks in this situation. This situation is
|
|
; detected by interrogating port 62h, and checking for a bit value
|
|
; of 80h. If set, *****DO NOT SWITCH STACKS*****.
|
|
;
|
|
; *********************************************************************
|
|
|
|
push ds
|
|
mov ax,0f000h
|
|
mov ds,ax
|
|
cmp byte ptr ds:[0fffeh],0f9h ;check if P12
|
|
pop ds
|
|
jne Normal&aa
|
|
|
|
in al,62h
|
|
test al,80h
|
|
jz Normal&aa
|
|
|
|
Special&aa:
|
|
pop ax
|
|
jmp dword ptr Old&aa
|
|
|
|
Normal&aa:
|
|
|
|
; *********************************************************************
|
|
|
|
endif
|
|
|
|
push bp
|
|
push es
|
|
mov es, cs:[STACKS+2] ; Get segment of stacks
|
|
|
|
mov bp,NextEntry ; get most likely candidate
|
|
mov al,Allocated
|
|
xchg AllocByte,al ; grab the entry
|
|
cmp al,Free ; still avail?
|
|
jne NotFree&aa
|
|
|
|
sub NextEntry,EntrySize ; set for next interrupt
|
|
|
|
Found&aa:
|
|
mov SavedSP,sp ; save sp value
|
|
mov SavedSS,ss ; save ss also
|
|
; mov IntLevel,aa&h ; save the int level
|
|
|
|
mov ax,bp ; temp save of table offset
|
|
|
|
mov bp,NewSP ; get new SP value
|
|
cmp es:[bp],ax ; check for offset into table
|
|
jne FoundBad&aa
|
|
|
|
mov ax,es ; point ss,sp to the new stack
|
|
mov ss,ax
|
|
mov sp,bp
|
|
|
|
pushf ; go execute the real interrupt handler
|
|
call dword ptr old&aa ; which will iret back to here
|
|
|
|
mov bp,sp ; retrieve the table offset for us
|
|
mov bp,es:[bp] ; but leave it on the stack
|
|
mov ss,SavedSS ; get old stack back
|
|
mov sp,SavedSP
|
|
|
|
; cmp AllocByte,Allocated ; If an error occured,
|
|
; jne NewError&aa ; do not free us
|
|
|
|
mov AllocByte,Free ; free the entry
|
|
mov NextEntry,bp ; setup to use next time
|
|
|
|
NewError&aa:
|
|
pop es
|
|
pop bp ; saved on entry
|
|
pop ax ; saved on entry
|
|
|
|
INTRET_&AA: ;3.30
|
|
iret ; done with this interrupt
|
|
|
|
NotFree&aa:
|
|
cmp al,Allocated ; error flag
|
|
je findnext&aa ; no, continue
|
|
xchg AllocByte,al ; yes, restore error value
|
|
|
|
FindNext&aa:
|
|
call LongPath
|
|
jmp Found&aa
|
|
|
|
FoundBad&aa:
|
|
cmp bp,FirstEntry
|
|
jc findnext&aa
|
|
mov bp,ax ; flag this entry
|
|
mov AllocByte,Clobbered
|
|
; add bp,EntrySize ; and previous entry
|
|
; mov AllocByte,Overflowed
|
|
; sub bp,EntrySize
|
|
jmp findnext&aa ; keep looking
|
|
|
|
int&aa endp
|
|
|
|
|
|
endm
|
|
|
|
;***************************** ;3.30
|
|
;End of Macro definition ;3.30
|
|
;******************************************************************** ;3.30
|
|
; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30
|
|
;3.30
|
|
IRP A,<02,08,09,70> ;3.30
|
|
IntSharingFlag=0 ;3.30
|
|
Stack_Main &A ;3.30
|
|
ENDM ;3.30
|
|
;3.30
|
|
IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30
|
|
IntSharingFlag=1 ;3.30
|
|
Stack_Main &A ;3.30
|
|
ENDM ;3.30
|
|
;3.30
|
|
;******************************************************************** ;3.30
|
|
;Common routines ;3.30
|
|
|
|
longpath:
|
|
mov bp,LastEntry ; start with last entry in table
|
|
|
|
LPLOOPP: ;3.30
|
|
cmp AllocByte,Free ; is entry free?
|
|
jne inuse ; no, try next one
|
|
|
|
mov al,Allocated
|
|
xchg AllocByte,al ; allocate entry
|
|
cmp al,Free ; is it still free?
|
|
je found ; yes, go use it
|
|
|
|
cmp al,Allocated ; is it other than Allocated or Free?
|
|
je inuse ; no, check the next one
|
|
|
|
mov AllocByte,al ; yes, put back the error state
|
|
|
|
inuse:
|
|
cmp bp,FirstEntry
|
|
je Fatal
|
|
sub bp,EntrySize
|
|
JMP LPLOOPP ;3.30
|
|
|
|
found:
|
|
ret
|
|
|
|
page
|
|
|
|
fatal proc near
|
|
push ds ;3.30
|
|
mov ax, 0f000h ;loook at the model byte ;3.30
|
|
mov ds, ax ;3.30
|
|
cmp ds:byte ptr [0fffeh], 0f9h ;convertible ;3.30
|
|
pop ds ;3.30
|
|
jne Skip_NMIS ;3.30
|
|
;3.30
|
|
mov al,07h ; disable p12 NMIs
|
|
out 72h,al
|
|
|
|
Skip_NMIS: ;3.30
|
|
cli ; disable and mask
|
|
mov al,0ffh ; all other ints
|
|
out 021h,al
|
|
out 0a1h,al
|
|
|
|
mov si,cs
|
|
mov ds,si
|
|
mov si,offset fatal_msg
|
|
|
|
fatal_loop:
|
|
lodsb
|
|
cmp al,'$'
|
|
je fatal_done
|
|
|
|
mov bl,7 ;3.30*
|
|
mov ah,14 ;3.30*
|
|
int 010h ; whoops, this enables ints ;3.30*
|
|
jmp fatal_loop
|
|
|
|
fatal_done:
|
|
jmp fatal_done
|
|
fatal endp
|