;       SCCSID = @(#)d_ioctl.asm	6.1 91/02/15
;	SCCSID = @(#)d_ioctl.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_ioctl.asm - API stub routine DosDevIOCTL
;
;	Member of API library
;	David Silverstein
;	Copyright MicroSoft Corporation, 1986
;	01-May-1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Modification History
;
;	06-Jan-87 (billme): Replace initial pushes and final pops
;	with calls to __api_begin and __api_end resp.  This will
;	reduce the size of FAPI and allow support for signals.
;
;
;	02-Oct-87 (robertc): Added support for user defined ioctls

include error.inc
include d_ioctl.inc

	EXTRN	__api_begin:near
	EXTRN	__api_end:near
	EXTRN	_api_getvrsn:near

;***	DOSDEVIOCTL
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosDevIOCTL(Data, ParmList, Function, Category, DevHandle)
;
;	ENTRY:
;		Data - data area
;		ParamList - command specific argument list
;		Function - device specific function code
;		Category - device category
;		DevHandle - device handle returned by DosOpen
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	Pseudo Code:
;		save registers
;		use BP as pointer to stack parameters
;		Use category code to disbatch a call to individual category
;		 handler.
;		restore registers
;		return
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;

	title	DOSDEVIOCTL
;
;	EXTRN	DOSDEVIOCTL:FAR
;
;	PUSH	@ OTHER Data
;	PUSH	@ OTHER ParmList
;	PUSH	WORD	Function
;	PUSH	WORD	Category
;	PUSH	WORD	DevHandle
;	CALL	DOSDEVIOCTL
;

_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT, DS:nothing

	public	DOSDEVIOCTL

	extrn	SERIALCTRL   :NEAR
	extrn	SCREENCTRL   :NEAR
	extrn	PRINTERCTRL  :NEAR
	extrn	DISKCTRL     :NEAR
	extrn	USERIOCTL    :NEAR

Categories:	dw	offset _TEXT:Illegal
		dw	offset _TEXT:SERIALCTRL
		dw	offset _TEXT:Illegal
		dw	offset _TEXT:SCREENCTRL
		dw	offset _TEXT:NotSupported
		dw	offset _TEXT:PRINTERCTRL
		dw	offset _TEXT:NotSupported
		dw	offset _TEXT:NotSupported
		dw	offset _TEXT:DISKCTRL
		dw	offset _TEXT:Illegal
		dw	offset _TEXT:NotSupported
		dw	offset _TEXT:NotSupported
CategoriesSize	equ	($ - Categories)

DOSDEVIOCTL	proc	far

	call	__api_begin	; init bp and save bp,ds,bx,cx,dx,si,di,es
				; required to save: bp,bx
	mov	bx, [Category]			; get category code
	test	bx, USER_DEFINED		; is this a user defined IOCTL?
	jz	ioctl1				; no, continue
	call	User_category			; handle user ioctl
	jmp	short OkReturn			; go exit
ioctl1:
	shl	bx, 1				; convert to word index
	cmp	bx, CategoriesSize		; is category within bounds?
	jae	ErrorExit			; if not, go exit
	mov	bx, word ptr CS:Categories[bx]	; get call address
	call	bx				; call category handler
	jmp	short OkReturn

ErrorExit:
	call	Illegal				; invalid category

OkReturn:

	call	__api_end	; check sigs & restore es,di,si,dx,cx,bx,ds,bp

	ret	14	; clear stack of entry parameters (bytes)
DOSDEVIOCTL	endp


User_category:

	call	_api_getvrsn		; get Dos version
	cmp	ah, 10			; is it in the 3xBox
	jb	notsupported		; we are not running the 3xBox
	call	userioctl
	ret

NotSupported:
	xor	ax, ax
	test	word ptr [Function], IGNORE_ERROR
	jnz	notsup1
	mov	ax, error_not_supported
notsup1:
	ret

Illegal:
	mov	ax, error_invalid_category
	ret


_TEXT	ends
	end
