mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 07:54:28 +00:00
366 lines
9.1 KiB
NASM
366 lines
9.1 KiB
NASM
; File : $STACKS.ASM$
|
|
;
|
|
; Description :
|
|
;
|
|
; Original Author : DIGITAL RESEARCH
|
|
;
|
|
; Last Edited By : $CALDERA$
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
; Copyright Work of Caldera, Inc. All Rights Reserved.
|
|
;
|
|
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
|
|
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
|
|
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
|
|
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
|
|
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
|
|
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
|
|
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
|
|
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
|
|
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
|
|
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
|
|
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
|
|
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
|
|
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
|
|
; CIVIL LIABILITY.
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; *** Current Edit History ***
|
|
; *** End of Current Edit History ***
|
|
;
|
|
; $Log$
|
|
; STACKS.ASM 1.6 93/10/26 19:08:13
|
|
; Fix bug when we run out of stacks
|
|
; STACKS.ASM 1.4 93/09/02 22:36:47
|
|
; Add header to system allocations
|
|
; ENDLOG
|
|
|
|
CGROUP group INITCODE, STACKS
|
|
|
|
STACKS segment public para 'STACKS'
|
|
|
|
Assume CS:STACKS, DS:Nothing, ES:Nothing, SS:Nothing
|
|
|
|
StackCode:
|
|
|
|
;************
|
|
; FIXED DATA
|
|
;************
|
|
|
|
dw 0
|
|
NumOfStacks dw 0 ; we have this many stacks
|
|
StackCB dw 0 ; NumOfStacks*8 = size of control array
|
|
StackSize dw 0 ; size of an individual stack
|
|
StackPtr label dword ; pointer to stack data
|
|
StackOff dw offset STACKS:StackHeap
|
|
StackSeg dw 0
|
|
FirstStack dw offset STACKS:StackHeap
|
|
LastStack dw offset STACKS:StackHeap-STACK_CB_SIZE
|
|
NextStack dw offset STACKS:StackHeap-STACK_CB_SIZE
|
|
|
|
;************
|
|
; FIXED DATA
|
|
;************
|
|
|
|
STACK_CB_FLAGS equ word ptr 0 ; stack flags
|
|
STACK_CB_SP equ word ptr 2 ; old stack saved here
|
|
STACK_CB_SS equ word ptr 4
|
|
STACK_CB_TOP equ word ptr 6 ; stack top lives here
|
|
STACK_CB_SIZE equ 8
|
|
|
|
STACK_FREE equ 0 ; stack is available to allocate
|
|
STACK_INUSE equ 1 ; stack is in use
|
|
STACK_OVERFLOW equ 2 ; stack has overflowed
|
|
|
|
;
|
|
; Our hardware interrupt handlers which are of the form
|
|
;
|
|
; call SwapStack
|
|
; db 0EAh ; JMPF opcode
|
|
; dd oldIntHandler
|
|
;
|
|
; By looking at the near return address we can find the address of the old
|
|
; interrupt handler.
|
|
; We try to allocate a stack from our pool of stacks, working downward to
|
|
; reduce the problems of stack overflow.
|
|
;
|
|
; We check the top of the stack contains a pointer to our control block and
|
|
; if this is invalid we assume the stack has overflowed, and try the next one.
|
|
; We have no way of recovering a stack that has overflowed (eg. by zapping
|
|
; everything below us on exit).
|
|
;
|
|
; If we run out of stacks we just continue on the callers stack, rather than
|
|
; halting the system.
|
|
;
|
|
|
|
Int02:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i02Off dw 4*02h,0
|
|
|
|
Int08:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i08Off dw 4*08h,0
|
|
|
|
Int09:
|
|
call SwapStack
|
|
db 0EAh
|
|
i09Off dw 4*09h,0
|
|
|
|
Int0A:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i0AOff dw 4*0Ah,0
|
|
|
|
Int0B:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i0BOff dw 4*0Bh,0
|
|
|
|
Int0C:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i0COff dw 4*0Ch,0
|
|
|
|
Int0D:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i0DOff dw 4*0Dh,0
|
|
|
|
Int0E:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i0EOff dw 4*0Eh,0
|
|
|
|
Int70:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i70Off dw 4*70h,0
|
|
|
|
Int72:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i72Off dw 4*72h,0
|
|
|
|
Int73:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i73Off dw 4*73h,0
|
|
|
|
Int74:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i74Off dw 4*74h,0
|
|
|
|
Int76:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i76Off dw 4*76h,0
|
|
|
|
Int77:
|
|
call SwapStack
|
|
db 0EAh ; JMPF
|
|
i77Off dw 4*77h,0
|
|
|
|
SwapStack proc near
|
|
; On Entry:
|
|
; As per INT except word on stack from near call, which gives old vector
|
|
; On Exit:
|
|
; None
|
|
;
|
|
cli ; just in case
|
|
push bp
|
|
push si ; save work registers
|
|
mov si,cs:NextStack ; start looking here for a stack
|
|
SwapStack10:
|
|
cmp cs:STACK_CB_FLAGS[si],STACK_FREE
|
|
jne SwapStack20 ; use this stack if possible
|
|
mov bp,cs:STACK_CB_TOP[si] ; get the top of this stack
|
|
cmp si,cs:word ptr [bp] ; does the check match ?
|
|
jne SwapStack20 ; no, try the next one
|
|
mov cs:NextStack,si ; remember where we are
|
|
mov cs:STACK_CB_FLAGS[si],STACK_INUSE
|
|
mov cs:STACK_CB_SS[si],ss ; save old stack
|
|
mov cs:STACK_CB_SP[si],sp
|
|
|
|
mov bp,sp
|
|
xchg bx,ss:word ptr 4[bp] ; BX = return address, BX saved
|
|
|
|
mov bp,cs
|
|
mov ss,bp
|
|
mov sp,cs:STACK_CB_TOP[si] ; switch stacks
|
|
pushf
|
|
call cs:dword ptr 1[bx] ; fake an INT to old handler
|
|
mov ss,cs:STACK_CB_SS[si]
|
|
mov sp,cs:STACK_CB_SP[si] ; swap back to the original stack
|
|
mov cs:STACK_CB_FLAGS[si],STACK_FREE
|
|
mov cs:NextStack,si ; update in case we were nested
|
|
pop si ; restore registers
|
|
pop bp
|
|
pop bx ; (was return address, now saved BX)
|
|
iret ; exit interrupt handler
|
|
|
|
SwapStack20:
|
|
sub si,STACK_CB_SIZE ; it's not, so try the next
|
|
cmp si,cs:FirstStack ; if there is one
|
|
jae SwapStack10
|
|
pop si ; restore registers
|
|
pop bp
|
|
ret ; back to JMPF as we can't swap stacks
|
|
|
|
SwapStack endp
|
|
|
|
i19Table dw 4*02H, offset STACKS:i02Off
|
|
dw 4*08H, offset STACKS:i08Off
|
|
dw 4*09H, offset STACKS:i09Off
|
|
dw 4*0AH, offset STACKS:i0AOff
|
|
dw 4*0BH, offset STACKS:i0BOff
|
|
dw 4*0CH, offset STACKS:i0COff
|
|
dw 4*0DH, offset STACKS:i0DOff
|
|
dw 4*0EH, offset STACKS:i0EOff
|
|
dw 4*70H, offset STACKS:i70Off
|
|
dw 4*72H, offset STACKS:i72Off
|
|
dw 4*73H, offset STACKS:i73Off
|
|
dw 4*74H, offset STACKS:i74Off
|
|
dw 4*76H, offset STACKS:i76Off
|
|
dw 4*77H, offset STACKS:i77Off
|
|
dw 0
|
|
|
|
Int19:
|
|
; Trap the Int 19 reboot and restore any hardware vectors we have hooked
|
|
cli
|
|
cld
|
|
xor ax,ax
|
|
mov es,ax ; ES = interrupt vectors
|
|
push cs
|
|
pop ds
|
|
lea si,i19Table ; DS:SI -> table to restore
|
|
Int1910:
|
|
lodsw
|
|
xchg ax,di ; ES:DI -> address to restore to
|
|
lodsw
|
|
xchg ax,si ; CS:SI -> value to restore
|
|
movsw
|
|
movsw
|
|
xchg ax,si ; restore position in table
|
|
cmp ds:word ptr [si],0
|
|
jne Int1910
|
|
db 0EAh ; JMPF
|
|
i19Off dw 4*19h,0
|
|
|
|
even ; word align our stacks
|
|
|
|
StackHeap label word ; dynamically build stack CB's here
|
|
|
|
RELOCATE_SIZE equ ($ - StackCode)
|
|
|
|
STACKS ends
|
|
|
|
INITCODE segment public para 'INITCODE'
|
|
|
|
Assume CS:CGROUP, DS:CGROUP, ES:Nothing, SS:Nothing
|
|
|
|
extrn alloc_hiseg:near
|
|
|
|
Public InitStacks
|
|
;==========
|
|
InitStacks:
|
|
;==========
|
|
; On Entry:
|
|
; CX = number of stacks
|
|
; DX = size of stack
|
|
; Values are checked
|
|
; On Exit:
|
|
; None
|
|
;
|
|
push ds
|
|
push es
|
|
inc dx ; let's ensure stacks are WORD
|
|
and dx,0FFFEh ; aligned...
|
|
mov NumOfStacks,cx
|
|
mov StackSize,dx
|
|
mov ax,STACK_CB_SIZE
|
|
mul cx ; AX = bytes in control area
|
|
mov StackCB,ax
|
|
add LastStack,ax
|
|
add NextStack,ax
|
|
add StackOff,ax ; adjust our pointers
|
|
xchg ax,cx ; AX = NumOfStacks
|
|
mul StackSize ; AX bytes are required for stacks
|
|
add ax,StackOff ; add to start of stacks
|
|
push ax ; save length in bytes
|
|
add ax,15 ; allow for rounding
|
|
mov cl,4
|
|
shr ax,cl ; convert it to para's
|
|
mov dl,'S' ; allocation signature is Stacks
|
|
call alloc_hiseg ; allocate some memory
|
|
pop cx ; CX = length in bytes
|
|
mov StackSeg,ax ; remember where
|
|
mov es,ax
|
|
Assume ES:STACKS
|
|
xor di,di
|
|
mov al,0CCh ; fill stacks with CC for debug
|
|
rep stosb
|
|
xor di,di
|
|
mov si,offset CGROUP:StackCode
|
|
mov cx,RELOCATE_SIZE
|
|
rep movsb ; relocate the code
|
|
|
|
mov bx,FirstStack ; lets start building the CB's
|
|
mov cx,NumOfStacks
|
|
lds si,StackPtr ; SI = bottom of stack area
|
|
Assume DS:STACKS
|
|
sub si,WORD ; we want the word below top of stack
|
|
InitStacks10:
|
|
add si,StackSize ; SI = top of stack
|
|
mov ds:STACK_CB_FLAGS[bx],STACK_FREE
|
|
mov ds:STACK_CB_TOP[bx],si ; set top of stack
|
|
mov ds:word ptr [si],bx ; set backlink
|
|
add bx,STACK_CB_SIZE ; onto next control block
|
|
loop InitStacks10
|
|
|
|
xor ax,ax
|
|
mov ds,ax
|
|
Assume DS:Nothing
|
|
cli
|
|
mov si,offset CGROUP:iTable ; now we fixup the vectors
|
|
InitStacks20:
|
|
mov ax,cs:word ptr 0[si] ; ES:AX = entry point
|
|
mov di,cs:word ptr 2[si] ; ES:DI = fixup location
|
|
mov bx,es:word ptr [di] ; get the vector to fixup
|
|
xchg ax,ds:word ptr [bx] ; set entry offset while saving
|
|
stosw ; previous handler offset
|
|
mov ax,es
|
|
xchg ax,ds:word ptr 2[bx] ; now the segment
|
|
stosw
|
|
add si,2*WORD ; onto next entry
|
|
cmp cs:word ptr 0[si],0 ; (zero terminated)
|
|
jnz InitStacks20
|
|
sti
|
|
InitStacks30:
|
|
pop es
|
|
pop ds
|
|
ret
|
|
|
|
iTable dw offset STACKS:Int02, offset STACKS:i02Off
|
|
dw offset STACKS:Int08, offset STACKS:i08Off
|
|
dw offset STACKS:Int09, offset STACKS:i09Off
|
|
dw offset STACKS:Int0A, offset STACKS:i0AOff
|
|
dw offset STACKS:Int0B, offset STACKS:i0BOff
|
|
dw offset STACKS:Int0C, offset STACKS:i0COff
|
|
dw offset STACKS:Int0D, offset STACKS:i0DOff
|
|
dw offset STACKS:Int0E, offset STACKS:i0EOff
|
|
dw offset STACKS:Int70, offset STACKS:i70Off
|
|
dw offset STACKS:Int72, offset STACKS:i72Off
|
|
dw offset STACKS:Int73, offset STACKS:i73Off
|
|
dw offset STACKS:Int74, offset STACKS:i74Off
|
|
dw offset STACKS:Int76, offset STACKS:i76Off
|
|
dw offset STACKS:Int77, offset STACKS:i77Off
|
|
dw offset STACKS:Int19, offset STACKS:i19Off
|
|
dw 0
|
|
|
|
INITCODE ends
|
|
|
|
end
|