; ===========================================================================
kstacks macro
; ===========================================================================
     cld
     cli
     _cstods
     _cstoes
     mov  word ptr ds:[NXDOSSEG], ax
     sti
IF (CHAOS)
     ;
     ; 0050:ffffh  internal primary dos stack    
     ; Or I could 0060h - 0010h = stack 
     ; mov  bx, 0010h
     ; sub  ax, bx      
     ; Could be a problem if prog was loaded at 0010h ?
     ;
     ;push cs
     ;pop  ax        
     ;mov  bx, 0010h ; 0050:FFFF
     ;sub  ax, bx
     ;cmp  ax, 0
     ;jne  short nstack_def
     ;mov  ax, dos_data
     ;
     _setstack dos_data, stack_top ; mov  ax, 0050h
                                   ; mov  sp, 0ffffh
     ;xor  ax, ax
     ;xor  bp, bp
     ;mov  es:bx, bl
ENDIF
     endm

; ===========================================================================
SegCheck proc far
; Check for consistant internal varible alignment
; Entry: Nothing
; Exit : releases a assert message if segment is not aligned
; ===========================================================================
      ; verify segment
      mov  ax, word ptr ds:[_serialno]  
      cmp  ax, DSMAGIC
      jne  _segchk_dserror
      mov  ax, ss
      cmp  ax, dos_data
      jne  _segchk_sserror
     ; mov  ax, cs
     ; cmp  ax, NXDOSBIO
     ; je   _segchkok
_segchkok:
      clc
      ret
_segchk_dserror:
      mov  ax, 1
      jmp  _segchk_error
_segchk_sserror:     
      mov  ax, 2
_segchk_error:
      push ax
      call beep
      assert 23, 1, 1, 1
      pop  ax
IF (DEBUG)
      _newline
      call debugregisters
      _newline
      Call pauseprompt
      _newline
ENDIF
      stc
      ret
SegCheck endp

save_ss macro
      cli
      mov  ax, ss
      mov  word ptr cs:[ks_ss], ax
      mov  ax, sp
      mov  word ptr cs:[ks_sp], ax
      sti
      endm

rest_ss macro
      cli
      mov  ax, word ptr cs:[ks_ss]
      mov  ss, ax
      mov  ax, word ptr cs:[ks_sp]
      mov  sp, ax
      sti
      endm

; ===========================================================================
; Stacks.asm - Internal use by the NXDOS kernel
;            - 2005, 2006 Christopher Robert Evans; tekno1911@yahoo.com
; 2008-MAY-31: Stackdata is now on the heap using chimaira memmgr. -CE
; ===========================================================================

$stacksize  EQU 128

StackCode:  

; dynamically build stack CB's here
Stackdata:

stackptr    dw 0
stackseg    dw 0
stackofs    dw 0
stacksize   dw 0
stackhnd    dw 0

; stack_data  dw stacksize dup(1)

stacksetup macro
          mov  ax, word ptr cs:[stackseg]
IF NOT (MSDOS)
          mov  dx, word ptr cs:[stackofs]
          push ax
          pop  es
          push dx
ELSE
          xor  ax, ax
          push ax
ENDIF
          pop  si
          mov  bx, word ptr cs:[stackptr]
          push bx
          pop  bp
          ; es:si+bp
      endm

ssize proc far
      mov  ax, word ptr cs:[stackptr]
      ret
ssize endp

sitems proc far
      mov  ax, word ptr cs:[stackptr]
      shr  ax, 1
      ret
sitems endp

spush proc far
; AX is stored in stack
      push ds
      push bx
      push cs
      pop  ds
      push ax
      stacksetup
      push ax
      mov  ax, word ptr cs:[stacksize]
      mov  bx, 2
      xor  dx, dx
      mul  bx
      dec  ax
      dec  ax
      mov  dx, ax
      pop  ax
      pop  ax
      push bp
      pop  bx
      cmp  bx, dx        ; ((stacksize*2)-2)
      jae  stackoverflow
           ; mov  word ptr ds:[stack_data][bx], ax
           mov  word ptr es:[si+bp], ax
           inc  bp  ; inc bx
           inc  bp  ; inc bx
           push bp
           pop  bx
           mov  word ptr cs:[stackptr], bx
      jmp  stkp_x
stkp_x:   
      pop  bx
      pop  ds
      ret
spush endp

spop  proc far
; last word stored is returned in AX
      push ds
      push bx
      push cs
      pop  ds
      push ax
      stacksetup
      pop  ax
      cmp  bx, 2
      jb   stackoverflow
           dec  bp  ; dec bx
           dec  bp  ; dec bx
           mov  ax, word ptr es:[si+bp]
           ; mov  ax, word ptr ds:[stack_data][bx]
           push bp
           pop  bx
           mov  word ptr cs:[stackptr], bx
      jmp  stkp_xx
stackoverflow:
      _print ErrMsg0012, 1
      _panic
      ; falls though once in spop
stkp_xx:   
      pop  bx
      pop  ds
      ret
spop  endp

debugstack proc far
IF (DEBUG)
      ;mov  ax, es
      ;sub  ax, 1
      ;mov  es, ax
      mov  cx, 64
      call debugdump
      pushregs
      call debugregisters
      _newline
      popregs
ENDIF
      ret
debugstack endp

sinit proc far
IF (MSDOS)
      mov  ax, ($stacksize / PARAGRAPH)
      call AllocMemBlock
      jnc  dosstackok
           _panic
dosstackok:
      mov  ax, es
      mov  word ptr cs:[stackseg], ax
      mov  ax, cx
      mov  bx, PARAGRAPH
      xor  dx, dx
      mul  bx
      mov  word ptr cs:[stacksize], ax
      xor  dx, dx
      mov  word ptr cs:[stackofs], dx
ELSE
      mov  cx, $stacksize
      call smm_alloc
      jnc  stackok
           _panic
stackok:
      mov  word ptr cs:[stackseg], ax
      mov  word ptr cs:[stackofs], dx
      mov  word ptr cs:[stackhnd], bx
      mov  word ptr cs:[stacksize], $stacksize
ENDIF
IF (DEBUG)
;      mov  ax, 0ceh
;      call spush
;      mov  ax, 0ech
;      call spush
;      call spop
;      call spop
ENDIF
      ; call debugstack
      ret
sinit endp

STACK_RELOCATE_SIZE equ ($ - StackCode)

