/*
 * setjmp.S86  -  far-call routines for C runtime code
 *
 *                This file is in the libc subdirectory (and not in the
 *                asm subdirectory), because the routines within this
 *                file should never get called by any assembly code. They
 *                are meant for getting called by C code only.
 *
 * Copyright (C) 2003-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: setjmp.S86,v 1.5 2007/01/06 18:30:51 gkminix Exp $
 *
 *====================================================================
 */


#include <common.i86>
#include <i386/setjmp.i86>

.file __FILE__
.line __LINE__



/*
 *====================================================================
 *
 * Start the text segment and define all public entry points
 */

	.text

	.global	_setjmp
	.global	_longjmp



/*
 *====================================================================
 *
 * Set a new jump environment
 * Input:  AX    -  Offset to jump buffer
 * Output: AX    -  Zero on intial call, or the parameter value of longjmp
 * Registers changed: AX
 */
_setjmp:

	xchg	eax,ebx
	mov	jmpbuf_ebx[bx],eax
	mov	jmpbuf_esi[bx],esi
	mov	jmpbuf_edi[bx],edi
	mov	jmpbuf_ebp[bx],ebp
	mov	jmpbuf_es[bx],es
	pop	word ptr jmpbuf_pc[bx]
	mov	jmpbuf_esp[bx],esp
	push	word ptr jmpbuf_pc[bx]
	xchg	ebx,eax
	xor	ax,ax
	ret



/*
 *====================================================================
 *
 * Jump to a previously defined environment block
 * Input:  AX      -  Offset to jump buffer
 *         1. Arg  -  Value to return
 * Output: Routine doesnt return
 * Registers changed: all
 */
_longjmp:

	mov	bp,sp
	mov	bx,ax
	mov	ax,[bp + 2]		# get return value
	or	ax,ax			# never return a value of 0
	jnz	1f
	inc	ax
1:	mov	esi,jmpbuf_esi[bx]
	mov	edi,jmpbuf_edi[bx]
	mov	ebp,jmpbuf_ebp[bx]	# restore registers
	mov	esp,jmpbuf_esp[bx]
	mov	es,jmpbuf_es[bx]
	push	word ptr jmpbuf_pc[bx]
	mov	ebx,jmpbuf_ebx[bx]
	ret				# jump back to old destination




/*
 *====================================================================
 */
	.end

