;[]-----------------------------------------------------------------[]
;|      SETJMP.ASM -- entry points for Windows versions of setjmp()  |
;[]-----------------------------------------------------------------[]

;
;       C/C++ Run Time Library - Version 6.5
; 
;       Copyright (c) 1987, 1994 by Borland International
;       All Rights Reserved.
; 

	INCLUDE RULES.ASI

IFDEF NOXX        
	assume cs:_TEXT

public  SETJMP
public  LONGJMP

extrn   CATCH : far
extrn   THROW : far

_TEXT   segment

SETJMP  proc DIST
	jmp CATCH       ; the catch buffer used by Windows is smaller
			; than the one used by TC, so we can simply
			; call the Windows function with our buffer
SETJMP  endp

LONGJMP proc DIST
	push    bp
	mov     bp, sp
	pushf
	cmp     word ptr [bp+6], 1      ; generates carry if param == 0
	adc     word ptr [bp+6], 0      ; if it was zero now it's one
	popf
	pop     bp
	jmp THROW
LONGJMP endp


ELSE

	LOCALS

	assume cs:_TEXT

public  SETJMP
public  LONGJMP

extrn   CATCH            : FAR
extrn   THROW            : FAR
extrn   __CurrExcContext : DIST
extrn   __Local_unwind   : DIST
extrn   __Global_unwind  : DIST

ExceptionList   EQU     14h

JMPBuff STRUC
    j_sp        DW      ?
    j_ss        DW      ?
    j_flag      DW      ?
    j_cs        DW      ?
    j_ip        DW      ?
    j_bp        DW      ?
    j_di        DW      ?
    j_es        DW      ?
    j_si        DW      ?
    j_ds        DW      ?
    j_excep     DW      ?
    j_context   DW      ?
    ENDS

_TEXT   segment

SETJMP  proc PASCAL FAR

	mov     bx, sp
	push    di                              ;save this
	les     di, DWORD PTR ss:[bx + 4]       ;get jmp buff
	mov     ax, ss:[ExceptionList]          ;get exception reg rec
	mov     es:[di].j_excep, ax             ;save it
	push    es                              ;save this
	push    ax                              ;push exception reg rec as arg
	call    __CurrExcContext                ;get context
	pop     cx
	pop     es                              ;restore this
	mov     es:[di].j_context, 0            ;save it
	pop     di                              ;restore this

	jmp    CATCH   ; the catch buffer used by Windows is smaller
			; than the one used by TC, so we can simply
			; call the Windows function with our buffer
SETJMP  endp

LONGJMP proc PASCAL FAR

	ARG     jmpb    :DWORD, \
		value   :WORD

	;;
	;;  Note:  Because we call Windows to restore the state, if
	;;  we are on another stack, we will do something horrible here.
	;;  In the DOS version of setjmp, we restore the stack before
	;;  we attempt to do the unwinds.
	;;

	;;
	;;  If exception list hasn't changed, don't do global unwind:
	;;
	les     di, jmpb
	mov     ax, es:[di].j_excep
	cmp     ss:[ExceptionList], ax
	je      @@noGlobalUnwind

	push    es                      ;save this across C call
	push    0
	push    ax                      ;push exception reg rec as arg
	call    __Global_unwind
	pop     cx
	pop     cx
	pop     es                      ;restore this

	;;
	;;  Reset the exception registration record for safety:
	;;
	mov     ax, es:[di].j_excep
	mov     ss:[ExceptionList], ax

@@noGlobalUnwind:
	push    es                      ;save this
	push    ax                      ;push as arg
	call    __CurrExcContext        ;get context for exception reg rec
	pop     cx                      ;dump arg
	pop     es                      ;restore this
	cmp     ax, -1                  ;our exception record?
	je      @@doneUnwind            ;no
	cmp     ax, es:[di].j_context   ;are context recs the same?
	je      @@doneUnwind            ;yes, we're done
	push    es:[di].j_context       ;push as arg
	push    es                      ;save this
	call    __Local_unwind
	pop     cx                      ;dump arg
	pop     es                      ;restore this
@@doneUnwind:

	pushf
	cmp     word ptr [bp+6], 1      ;generates carry if param == 0
	adc     word ptr [bp+6], 0      ;if it was zero now it's one
	popf

	mov     sp, bp                  ;dump TASM built stack frame
	pop     bp
	jmp THROW                       ;just as if nothing ever happened

LONGJMP endp

ENDIF  ; NOXX

ends

end
