;       SCCSID = @(#)d_ioacc.asm	6.1 91/02/15
;	SCCSID = @(#)d_ioacc.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_IOACC.ASM - API stub routine DosIOAccess
;
;	Member of API library
;	David Silverstein
;	Copyright MicroSoft Corporation, 1986
;	30-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.
;

include dos2equ.inc
include	error.inc

	EXTRN	__api_begin:near
	EXTRN	__api_end:near

;***	DOSIOACCESS
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosIOAccess(TypeOfAccess, Range, FirstPort, LastPort)
;
;	ENTRY:
;		TypeOfAccess - Request or Release
;		Range - Contiguous or not
;		FirstPort - First I/O port #
;		LastPort - Last I/O port #  (0 - no port; >0 - port #)
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	Pseudo Code:
;		save registers
;		use BP as pointer to stack parameters
;		check parameters for validity
;		restore registers
;		return
;
;	WARNING:
;		This routine only checks for valid parameters.
;		It does not actually reserve and free and port addresses.
;		This is because Dos 2.x, 3.x has no multitasking, making
;		port reservations unneccessary.
;
;	EFFECTS:
;		none
;

	title	DOSIOACCESS
;
;	EXTRN	DOSIOACCESS:FAR
;
;	PUSH	WORD TypeOfAccess
;	PUSH	WORD Range
;	PUSH	WORD FirstPort
;	PUSH	WORD LastPort
;	CALL	DOSIOACCESS
;

_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT, DS:nothing

	public	DOSIOACCESS

TypeOfAccess		equ	[BP+12]
Range			equ	[BP+10]
FirstPort		equ	[BP+8]
LastPort		equ	[BP+6]

ACCESS_BIT		equ	1
RANGE_BIT		equ	1
CONTIG_RANGE		equ	0
MAX_PORT_NUM		equ	400h


DOSIOACCESS	proc	far

	call	__api_begin	; init bp and save bp,ds,bx,cx,dx,si,di,es
				; required to save: bp,ds,bx

	; validate input parameters

	test	word ptr [TypeOfAccess], NOT ACCESS_BIT	; is access type valid?
	jnz	ioacc1					; no, exit with error
	test	word ptr [Range], NOT RANGE_BIT		; is range valid?
	jnz	ioacc1					; no, exit with error
	mov	ax, [FirstPort]				; first port address
	cmp	ax, MAX_PORT_NUM			; is it within range?
	ja	ioacc1					; no, exit with error
	cmp	word ptr [LastPort], MAX_PORT_NUM	; is last port in range?
	ja	ioacc1					; no, exit with error

	cmp	word ptr [Range], CONTIG_RANGE		; continuous range?
	jne	ioacc2
	cmp	ax, [LastPort]				; last port after first?
	jb	ioacc2					; exit with no error
ioacc1:
	mov	ax, error_invalid_parameter		; load error code
	jmp	short ioacc3
ioacc2:
	xor	ax, ax

ioacc3:

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

	ret	8	; clear stack of entry parameters (bytes)
DOSIOACCESS	endp

_TEXT	ends

	end
