;*************** START OF ASYNCF.ASM FILE *****************

	TITLE	ASYNCF
	IF MLARGE
	INCLUDE L8086.INC
	ELSE
	INCLUDE S8086.INC
	ENDIF

	; Far call outside ANY segment!
	EXTRN	_anr: FAR	;

	DSEG
	; Just for MASM's sake!
	ENDDS

;************************************************************
; * Allocate stack segment
;************************************************************
STACKSIZE	equ	1024	; How many bytes are allocated for Stack
M_STACK	segment PARA PUBLIC 'CODE'
	db	STACKSIZE dup(0)	; Stack space for USER called function
M_STACK	ENDS
;************************************************************

	PSEG	ASYNCF

Running		dw	0	; Set if already running, don't send further events!

OldSS	dw	0		; SCRATCH Saved area for SS
OldSP	dw	0		; SCRATCH Saved area for SP

	PUBLIC	_asyncf
_asyncf	proc	far
	cli			; No interrupt here

	cmp	cs:Running, 1	; Already running?
	jne	U_cont		;

	jmp	U_quit		; Yes, don't process this event

U_cont:
	mov	cs:Running, 1	; Set running

	sti			; Allow interrupts

	SAVE_REG                ; Save All Registers

	mov	ax, DGROUP	; Satisfy ASSUME statement
	mov	ds, ax		;

	mov	ax, SS		; Save SS
	mov	CS:OldSS, ax	;
	mov	ax, SP		; Save SP
	mov	CS:OldSP, ax	;

	; Set stack for User call
	mov	ax, SEG M_STACK	; Create STACK for USER
	mov	cx, STACKSIZE	; Load new SP

	cli			; No interrupts now!
	mov	ss, ax		; Load it
	mov	sp, cx		; Load it
	sti			; Reenable interrupts

	push    es              ; (es:bx) points
	push    bx              ; to the ACB

	call    _anr            ; Call user (C) ANR

;       add     sp, +4          ; Unecessary because we reload SP

	; Reload old SS and SP
	mov	cx, CS:OldSS	;
	mov	bx, CS:OldSP	;

	cli			; No interrupts now!
	mov	ss, cx		; Load it
	mov	sp, bx		; Load it
	sti			; Reenable interrupts
	
	REST_REG                ; Restore All Registers

	mov	cs:Running, 0	; Clear running

U_quit:
	sti			; Allow interrupts

	ret
_asyncf	endp

	ENDPS	ASYNCF
	END

;*************** END OF ASYNCF.ASM FILE *****************
