;*************** 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 *****************