;
;  dosio.asm
;  Support for BIOS calls in ImProVise
;****************************************************************************
;*																			*
;*																			*
;*	  part of ImProVise													 	*
;*	  by Quincey Koziol													 	*
;*																			*
;*																		 	*
;*																		 	*
;****************************************************************************

	TITLE	DOSIO	-- LOW-LEVEL I/O FOR SANE HARDWARE HANDLING

;
;	From original code by Tim Krauskopf	1984-1985
;	National Center for Supercomputing Applications
;
	NAME	DOSIO

;
;  Macros for reading and writing I/O ports
;
MOUT	MACRO	REG,STUFF		; one byte to the given I/O register
	MOV	DX,REG
	MOV	AL,STUFF
	OUT	DX,AL
	ENDM
;
MIN	MACRO	REG		 	; get one byte to al
	MOV	DX,REG
	IN	AL,DX
	ENDM
;
;  Internal data 
;
	X EQU	6				;  for the large model programs

.model large
.data
;	INCLUDE	DOS.MAC
;	DSEG

	PUBLIC	_DTAPTR				; POINTER TO DTA LOCATION

_DTAPTR	DW	0000H				; dta ADDRESS FOR ME
DTADS	DW	0000H				; ds FOR dta

;	ENDDS
;
;
;
;	The subroutines to call from C
;
;	PSEG
.code

	PUBLIC  _FIND_1ST,_FINDNEXT,_MEM2CPY,_MEMQCPY,_MEMQSIZE


;**********************************************************************
;
;  find first
;	make dos find file names according to wildcards
;  findfirst(filename,attr)
;	char *filename; int attr;
;
_FIND_1ST	PROC	FAR
	PUSH	BP
	MOV		BP,SP
	PUSH	DS
	PUSH	ES
	
	MOV		AH,02FH					; dos FUNCTION GET dta
	INT		21H
	MOV		_DTAPTR,BX				; SQUIRREL A COPY FOR ME
	MOV		AX,ES
	MOV		DTADS,AX

	MOV		AX,[BP+X+2]				; DS OF FILENAME PTR
	MOV		DS,AX
	MOV		DX,[BP+X]				; PTR PART OF FILENAME
	MOV		CX,[BP+X+4]				; ATTRIBUTE TO SEARCH FOR
	MOV		AH,04EH					; FIND MATCHING FILE dos CALL
	INT		21H
	JC		BADRET					; AX ALREADY CONTAINS ERROR CODE
	XOR		AX,AX

BADRET:
	POP		ES
	POP		DS
	POP		BP
	RET
_FIND_1ST	ENDP

;
;  findnext()
;  will find entries that follow findfirst
;  no need to respecify file name
;
_FINDNEXT	PROC	FAR
	PUSH	BP
	PUSH	DS
	PUSH	ES

	MOV		AH,04FH					; FIND NEXT dos CALL
	INT		21H
	JC		NBADRET
	XOR		AX,AX

NBADRET:
	POP		ES
	POP		DS
	POP		BP
	RET
_FINDNEXT	ENDP

;
;	PROCEDURE TO MOVE MEMORY IN WORDS RATHER THAN IN BYTES
;		USAGE	_MEM2CPY(&TO,&FROM,# OF WORDS);
;
_MEM2CPY	PROC	FAR
	PUSH	BP
	MOV	BP,SP
	PUSH	DS
	PUSH	ES
	PUSH	SI
	PUSH	DI

	LES	DI,DWORD PTR [BP+X]			; GET THE SEGMENT AND OFFSET OF THE DESTINATION ARRAY
	LDS	SI,DWORD PTR [BP+X+4]		; GET THE SEGMENT AND OFFSET OF THE SOURCE MEMORY
	MOV	CX,[BP+X+8]					; GET THE COUNT

	REP	MOVSW						; MOVE WORDS

	POP		DI
	POP		SI
	POP		ES
	POP		DS
	POP	BP
	RET
_MEM2CPY	ENDP	
;
;	PROCEDURE TO MOVE MEMORY IN WORDS RATHER THAN IN BYTES IF IT IS POSSIBLE
;		USAGE	_MEMQCPY(&TO,&FROM,# OF BYTES);
;
_MEMQCPY	PROC	FAR
	PUSH	BP
	MOV	BP,SP
	PUSH	DS
	PUSH	ES
	PUSH	SI
	PUSH	DI

	LES	DI,DWORD PTR [BP+X]			; GET THE SEGMENT AND OFFSET OF THE DESTINATION ARRAY
	LDS	SI,DWORD PTR [BP+X+4]		; GET THE SEGMENT AND OFFSET OF THE SOURCE MEMORY
	MOV	CX,[BP+X+8]					; GET THE COUNT
	SHR	CX,1						; CHECK WHETHER THIS CAN BE WORD MOV'ED OR NOT
	JC	DOBYTES						; NO, CANNOT USE WORD MOVE
	REP	MOVSW						; MOVE WORDS
	JMP	SHORT	DONECOPY			; JUMP AROUND THE BYTE COPY

DOBYTES:
	MOV	CX,[BP+X+8]					; GET THE COUNT OF BYTES TO MOVE
	REP	MOVSB						; MOV THE MEMORY
	
DONECOPY:
	POP		DI
	POP		SI
	POP		ES
	POP		DS
	POP	BP
	RET
_MEMQCPY	ENDP
;
;	FUNCTION TO DETERMINE THE MEMORY SIZE IN 1KB BLOCKS OF EXTENDED MEMORY
;		USAGE	_MEMQSIZE();
;
_MEMQSIZE	PROC	FAR
	PUSH	BP
	MOV	BP,SP

	MOV		AH,88H				; SET AH FOR GETTING EXTENDED MEMORY SIZE
	INT		15H					; SYSTEM SERVICES INTERUPT

	POP	BP
	RET
_MEMQSIZE	ENDP

;	ENDPS
	END
