;       SCCSID = @(#)d_allchg.asm	6.1 91/02/15
;	SCCSID = @(#)d_allchg.asm	1.4 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;***  d_allchg.asm - API stub routine DosAllocSeg
;
;	Member of API library
;	David Silverstein
;	Copyright MicroSoft Corporation, 1986
;	28-Apr-1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Special Information
;		none
;
;	Modification History
;
;	7/31/86 (davidsi) - Added Flags parameter for sharing
;	attributes.  Only a passed value of zero is accepted.
;
;	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.
;
;	20-Jul-87 (robertc): Create mask on flags (7fffh)
;	to allow the Movable bit to be ignored.
; ***************************************************************

include basemaca.inc
include dos2equ.inc
include error.inc

	EXTRN	__api_begin:near
	EXTRN	__api_end:near

;***	DOSALLOCHUGE
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosAllocHuge(NumSeg, LocSize, ptr_Selector, MaxNumSeg, Flags)
;
;	ENTRY:
;		NumSeg - the number of 65536-byte segments
;		LocSize - the number of bytes in last segment
;		ptr_Selector - pointer to block of mem allocated
;		MaxNumSeg - Ignored
;		Flags - sharing attributes
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	EXIT:
;		if no error (AX == 0) WORD at ptr_Selector contains
;		segment address of memory block
;
;	USES:
;		AX
;
;	Pseudo Code:
;		save registers
;		use BP as pointer to stack parameters
;		calculate number of paragraphs
;		execute int 21 with function 48h
;		restore registers
;		return
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;
;	EFFECTS:
;		none
;

	title	DOSALLOCHUGE
;
;	EXTRN	DOSALLOCHUGE:FAR
;
;	PUSH	WORD NumSeg
;	PUSH	WORD Size
;	PUSH	@ WORD ptr_Selector
;	PUSH	WORD MaxNumSeg
;	PUSH	WORD Flags
;	CALL	DOSALLOCHUGE
;

_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT, DS:nothing

	public	DOSALLOCHUGE


Mask_Movable	equ	07FFFh
NumSeg		equ	[BP+16]
LocSize		equ	[BP+14]
ptr_Selector	equ	[BP+10]
MaxNumSeg	equ	[BP+8]		; ignored, not supported
Flags		equ	[BP+6]

DOSALLOCHUGE	proc	far

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

	mov	bx,[NumSeg]		; get number of 65536-byte segments
	test	bx,0fff0h		; is too much being requested?
	jnz	ErrorExit		; if so, set DOS error

	mov	ax, error_invalid_parameter

	and	word ptr [Flags], Mask_Movable ;@@(1.11) ignore movable bit
	cmp	word ptr [Flags], 0	; were any sharing attributes used?
	jne	alloc2			; yes, this isn't supported

	clc				; make sure the first rotate loads zero
					; in the most significant bit
	ror	bx,1			; Convert NumSeg to paragraphs
	ror	bx,1			;    same as shift left 12 bits
	ror	bx,1
	ror	bx,1

	mov	ax,[LocSize]		; AX <- size requested
	test	ax,0fh
	jz	alloc1			; no round up needed
	inc	bx			; BX <- round up 1
	jc	ErrorExit		; error if we wrapped
alloc1:
	shr	ax,1			; convert Size to paragraphs
	shr	ax,1
	shr	ax,1
	shr	ax,1
	add	bx,ax			; BX <- number of paragraphs requested
	jc	ErrorExit		; overflow, exit with error

	mov	ah,D2_AllocMem
	int	21H			; allocate memory
	jc	alloc2			; exit with current error code
	lds	bx,[ptr_Selector]	; DS:BX <- pointer to addr of ret
	mov	ds:[bx],ax
	xor	ax,ax
	jmp	short alloc2

ErrorExit:
	mov	ax,error_not_enough_memory
alloc2:

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

	ret	12	; clear stack of entry parameters (bytes)
DOSALLOCHUGE	endp

_TEXT	ends

	end
