Date: Friday, 2 May 1986  16:39-MDT
From: Dana Myers <bilbo.dana at LOCUS.UCLA.EDU>
To:   Info-IBMPC at USC-ISIB.ARPA
Re:   20 File Limit

 Jeff Jacobsen recently sent a message repeating a clipping from DDJ
(5/86) about expanded file handles. Having been aware of this
mechanism existing for a while (2.X or 3.X), I thought I would try it.
Something that seems to be ommitted from the DDJ article (16 Bit
Toolbox, I believe) is that it is important to copy all the file
descriptors in the original table.  Also, depending what you
initialize your new table to, the 'new' entries (extra entries on the
end) MUST be initialized to 0xFF. Otherwise, DOS will (a) believe you
have a bunch of open files and (b) not let you open nearly as many as
you might expect. In the case of Asm, you can DUP fill the new table
with 0xFF. In the case of C, you can either prefill, initialize or do
what I did; while copying the table, add on a remaining count of
0xFFs. Of course, if your new tabke is SMALLER than the 20 file table,
be sure to close any file descriptors which will not be copied. (Of
course, who is going to make a smaller new table?)

  It seems (as I expected) that the larger table will be closed and
forgotten by DOS on exit; there is no need to restore the PSP table or
such.

The source to mfile.asm

use as:
mfile(size, arr)
int	size;		/* sizeof(arr) */
char	*arr;		/* pointer to an arry at least size big */

written for S model Microsoft C V3

;	Static Name Aliases
;
	TITLE   mfile

_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
_TEXT	ENDS

CONST	SEGMENT  WORD PUBLIC 'CONST'
CONST	ENDS

_BSS	SEGMENT  WORD PUBLIC 'BSS'
_BSS	ENDS

_DATA	SEGMENT  WORD PUBLIC 'DATA'
_DATA	ENDS

DGROUP	GROUP	CONST,	_BSS,	_DATA
	ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP

PUBLIC  _mfile


;
; PSP structure of the filetable header
;

pspf	struc

p_count	dw	?
p_ptr	dd	?

pspf	ends

PSPF_OFF	equ	0032h


_TEXT      SEGMENT

;	p = 6
;	n = 4
;	rem = -2

_mfile	PROC NEAR
	push	bp
	mov	bp,sp
	push	SI
	push	DI
	push	ES

;
; copy the old table to the new, if possible
;

	mov	AH, 051h	; get PSP
	int	021h
	mov	ES, BX
	mov	BX, PSPF_OFF
	mov	AX, ES:[BX.p_count]	; current size
	mov	CX, [BP+4]
	sub	CX, AX			; any leftover?
	jle	mf_001
	mov	[BP-2], CX		; save rem count
	jmp	short mf_004		; leave count in AX

mf_001:
	mov	AX, [BP+4]
	mov	word ptr [BP-2], 0

mf_004:
	mov	DI, [BP+6]		; get dest
	mov	DX, DI
	mov	CX, AX			; AX has count in bytes
	push	ES
	push	DS
	lds	SI, dword ptr ES:[BX.p_ptr]
	cld
	mov	AX, DGROUP
	mov	ES, AX
	rep	movsb
	mov	CX, [BP-2]	; get remnant
	or	CX, CX
	jz	mf_003
	xchg	AX, [BP-2]
	mov	AL, -1
	rep	stosb		; fill in table
	xchg	AX, [BP-2]
mf_003:
	pop	DS
	pop	ES
	mov	word ptr ES:[BX.p_ptr], DX	; DX has offest
	mov	word ptr ES:[BX.p_ptr+2], AX	; AX has segment
	mov	AX, [BP+4]			; get new size
	mov	ES:[BX.p_count], AX

mf_002:
	pop	ES
	pop	DI
	pop	SI
	mov	sp,bp
	pop	bp
	ret

_mfile	ENDP

_TEXT	ENDS
	END
