;STACK.ASM

;Define segment names used by C
;
_TEXT   segment byte public 'CODE'
_TEXT   ends

CONST   segment word public 'CONST'
CONST   ends

_BSS    segment word public 'BSS'
_BSS    ends

_DATA   segment word public 'DATA'
_DATA   ends

DGROUP  GROUP   CONST, _BSS, _DATA

    assume  CS:_TEXT, DS:DGROUP  

    public  _set_stack, _restore_stack
    extrn   _stack_ptr:near     ;our TSR stack
    extrn   _ss_save:near       ;save foreground SS
    extrn   _sp_save:near       ;save foreground SP

_TEXT   segment
;*****
;void far set_stack(void) - 
;   save current stack and setup our local stack
;*****
_set_stack  proc    far

;save foreground stack

;we need to get the return values from the stack 
;since the current stack will change
    pop ax  ;get return offset
    pop bx  ;get return segment

;save away foreground process' stack
    mov word ptr _ss_save,ss
    mov word ptr _sp_save,sp

;setup our local stack
    mov ss,word ptr _stack_ptr+2
    mov sp,word ptr _stack_ptr    

IFDEF MULTI 
   mov bp,sp   ;make bp relative to our stack frame
ENDIF

;setup for ret
    push    bx  
    push    ax
            
    ret
_set_stack  endp

;*****
;void far restore_stack(void) - 
;   restore foreground stack, throw ours away 
;*****
_restore_stack  proc    far

;we need to get the return values from the stack 
;since the current stack will change
    pop cx  ;get return offset
    pop bx  ;get return segment

;save background stack
    mov word ptr _stack_ptr+2,ss
    mov word ptr _stack_ptr,sp

;restore foreground stack here
    mov ss,word ptr _ss_save
    mov sp,word ptr _sp_save      

IFDEF MULTI 
   mov bp,sp   ;make bp relative to our stack frame
ENDIF

;setup for ret
    push bx 
    push cx
            
    ret
_restore_stack  endp
_TEXT   ends

_DATA   segment 

_DATA   ends

    end

