;       SCCSID = @(#)d_holds.asm	6.1 91/02/15
;	SCCSID = @(#)d_holds.asm	6.2 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;***  D_HOLDS.ASM - API stub routine DosHoldSignal
;
;	Member of API library
;	David Silverstein
;	Copyright MicroSoft Corporation, 1986
;	September 1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Special Information
;		none
;
;	Modification History
;

include dos2equ.inc
include error.inc
include api.inc

;***	DosHoldSignal - stub to emulate function call
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;
;	errorcode = unsigned far pascal
;	DosHoldSignal(ActionCode);
;
;	ENTRY:
;		ActionCode - Indicate to enable or disable signals
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	Pseudo Code:
;
;		if ActionCode = ENABLE then
;			increment enable counter
;			install control C handling routine
;
;		else if ActionCode = DISABLE then
;			decrement enable counter
;			remove control C handling routine
;			if a ctrlC event occured, simulate it.
;		else
;			report error
;

	title	DOSHOLDSIGNAL
;
;	EXTRN	DOSHOLDSIGNAL:FAR
;
;	PUSH	WORD ActionCode
;	CALL	DOSHOLDSIGNAL
;

CTRLCINT	equ	23h
CTRLBREAK	equ	1bh

_TEXT	segment byte public 'CODE'
	assume CS:_TEXT, DS:NOTHING

	PUBLIC	DOSHOLDSIGNAL
	extrn	FapiAddSigCatch :FAR
	extrn	FapiSubSigCatch :FAR

ActionCode	equ	[bp + 6]

ENABLE		equ	0		; enable control C
DISABLE		equ	1		; disable control C

HoldCnt		db	0		; count of outstanding HoldSignal calls
CtrlCEvent	db	0		; control C event flag

DOSHOLDSIGNAL	proc	far
	push	bp
	mov	bp, sp
	push	ds
	push	bx

	mov	ax, SEG _TEXT		; set up data seg for addressability
	mov	ds, ax			; of local variables
	mov	ax, ERROR_INVALID_FUNCTION
	cmp	word ptr [ActionCode], ENABLE	; enable signals?
	je	holds1
	cmp	word ptr [ActionCode], DISABLE	; disable signals?
	jne	ErrorExit			; invalid ActionCode was passed

	; fall through to install CtrlC handling routine

	mov	bl, [HoldCnt]		; get DOSHOLDSIGNAL call counter
	inc	bl			; will it overflow?
	jo	ErrorExit		; yes, go exit with error
	inc	[HoldCnt]		; count the # of holds
	cmp	[HoldCnt], 1		; is this the first time?
	jne	holds2			; no, don't install ctrlC hook

	mov	dx, offset CtrlChandler	; address of ctrlC handler
	mov	bx, HOLDSIGNAL		; Fapi library function number
	call	FapiAddSigCatch		; add ctrlC handler
	mov	[CtrlCEvent], 0		; clear control C event flag
	jmp	short holds2

	; If there is only one outstanding call to disable signals,
	; renable signals by removing CtrlC handling routine

holds1:
	cmp	[HoldCnt], 0		; is the call counter already zero?
	je	ErrorExit		; yes, go exit with error
	dec	[HoldCnt]		; decrement call counter
	jnz	holds2			; reenable on 0 # of outstanding holds

	mov	bx, HOLDSIGNAL		; Fapi library function number
	call	FapiSubSigCatch		; disable CtrlC handler

	; check to see if a CtrlC occured.  If one did, simulate it by
	; calling the ctrl-break handler.

	cmp	[CtrlCEvent], 0		; did a signal occur?
	je	holds2			; no, go exit
	mov	[CtrlCEvent], 0		; reset signal flag
	int	CTRLBREAK		; call signal handler

	mov	ah, D2_GetKbdStat	; arbitrary int 21 to
	int	21h			; check for CtrlC

holds2:
	xor	ax, ax			; clear error code

ErrorExit:

	pop	bx
	pop	ds
	pop	bp
	ret	2

DOSHOLDSIGNAL	endp



; This is the control C handler installed when signals are disabled.

CtrlCHandler	proc	far

	mov	_TEXT:[CtrlCEvent], 1	; flag event
	iret

CtrlCHandler	endp


_TEXT	ends

	end
