/* UNIX style non-local goto */
setjmp()
	{
#asm
;setjmp(env)
;jmp_buf env;
	PUSH	BC	;save frame ptr
	LD	HL,8	;get value of SP to restore
	ADD	HL,SP
	LD	C,L	;save it
	LD	B,H
	DEC	HL
	LD	D,(HL)	;get contents of cell above SP
	DEC	HL
	LD	E,(HL)
	DEC	HL
	LD	A,(HL)	;get addr of env
	DEC	HL
	LD	L,(HL)
	LD	H,A
	LD	(HL),C	;save SP value to restore
	INC	HL
	LD	(HL),B
	INC	HL
	LD	(HL),E	;save cell above SP
	INC	HL
	LD	(HL),D
	POP	BC	;restore frame ptr
	POP	DE	;get RET addr
	PUSH	DE
	INC	HL
	LD	(HL),E	;save RET addr
	INC	HL
	LD	(HL),D
	INC	HL
	LD	(HL),C	;save frame pointer
	INC	HL
	LD	(HL),B
	XOR	A	;set Z flag
	LD	L,A	;load return value
	LD	H,A
#endasm
	}
longjmp()
	{
#asm
;longjmp(env, retval)
;jmp_buf env;
	POP	BC	;throw away RET address
	POP	BC	;get return value
	POP	HL	; and address of env
	LD	E,(HL)	;retrieve value of SP from env
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	LD	SP,HL	;reset stack pointer
	EX	DE,HL
	INC	HL
	LD	E,(HL)	;reset cell above SP
	INC	HL
	LD	D,(HL)
	PUSH	DE
	PUSH	DE	;fake the arg to setjmp which caller will remove
	INC	HL
	LD	E,(HL)	;restore RET address
	INC	HL
	LD	D,(HL)
	PUSH	DE
	PUSH	BC	;save return value for later
	INC	HL	;retrieve frame pointer
	LD	C,(HL)
	INC	HL
	LD	B,(HL)
	PUSH	BC
	POP	IX	;restore IX
	POP	HL	;retrieve return value
	LD	A,H	;set Z flag
	OR	L
#endasm
	}
