	page 64, 131
	title mscdex.asm - interface to mscdex interrupt 2F

;	/*\
;	|*|	mscdex.asm
;	|*|	
;	|*|	routines for c-interface to mscdex
;	|*|	support for those functions defined in mscdex v(2.
;	|*|
;	|*|	Copyright (c) 1992, Media Vision, Inc.  All Rights Reserved
;	|*|
;	\*/

	.xlist 
	include model.inc
	include masm.inc
	include common.inc
	include binary.inc
	.list

if MODELSIZE eq 0
	.code
else
	.data
endif

;; this holds the last value returned with carry set from int 2F
	public lasterror
lasterror	dw 0

	.code

;	/*\
;	|*|	int ismscdex(void) 
;	|*|	
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	return TRUE (not zero) if mscdex exists, 
;	|*|		else FALSE (zero) 
;	|*|
;	\*/

	public	ismscdex
ismscdex	proc
	push bp
	mov bp, sp

	mov ax, 1500h			; is function 15h available?
	xor bx, bx
	int 2Fh

	xor ax, ax			; ready to return 0

	or bx, bx			; does mscdex report available?
	jz done				; not here, return 0

	inc ax				; yes here, return 1

done:
	pop bp
	ret
ismscdex	endp


;	/*\
;	|*|	int getnumcdroms(void)
;	|*|
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	return total count of cdrom drives in system 
;	|*|
;	\*/

	public	getnumcdroms
getnumcdroms	proc
	push bp
	mov bp, sp

	mov ax, 1500h
	xor bx, bx
	int 2Fh

	mov ax, bx
	pop bp
	ret
getnumcdroms	endp

;	/*\
;	|*|	int getfirstcdrom(void) 
;	|*|
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	return number of first cdrom drive 
;	|*|
;	\*/

	public getfirstcdrom
getfirstcdrom	proc
	push bp
	mov bp, sp

	mov ax, 1500h
	xor bx, bx
	int 2Fh

	mov ax, cx

	pop bp
	ret
getfirstcdrom endp

;	/*\
;	|*|	int getcdromlist(struct cdromdrivestruct far *cdromlist) 
;	|*|
;	|*|	fill buffer with drive identifiers and addresses 
;	|*|
;	|*|	Entry:	address of buffer
;	|*|
;	|*|	Exit:	0 if successful, -1 if error occurred
;	|*|
;	\*/

	public getcdromlist
getcdromlist proc
	push bp
	mov bp, sp

	mov ax, 1501h
	les bx, dParm1
	int 2Fh

	pop bp
	ret
getcdromlist endp

;	/*\
;	|*|	int getcopyrightfname(int drive, char far *copyrightfname) 
;	|*|
;	|*|	fill buffer with name of copyright file for drive 
;	|*|
;	|*|	Entry:	drive number, address of buffer
;	|*|
;	|*|	Exit:	0 if successful, -1 if error occurred
;	|*|
;	\*/

	public getcopyrightfname
getcopyrightfname proc
	push bp
	mov bp, sp

	mov ax, 1502h
	mov cx, wParm1
	les bx, wParm2
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1
	jmp short done

okay:
	xor ax, ax

done:
	pop bp
	ret
getcopyrightfname endp

;	/*\
;	|*|	int getabstractfname(int drive, char far *abstractfname)
;	|*|
;	|*|	fill buffer with name of abstract file for drive 
;	|*|
;	|*|	Entry:	drive number, address of buffer
;	|*|
;	|*|	Exit:	0 if successful, -1 if error occurred
;	|*|
;	\*/

	public getabstractfname
getabstractfname proc
	push bp
	mov bp, sp

	mov ax, 1503h
	mov cx, wParm1
	les bx, wParm2
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1
	jmp short done

okay:
	xor ax, ax

done:
	pop bp
	ret
getabstractfname endp
		

;	/*\
;	|*|	int getbibliofname(int drive, char far *bibliofname)
;	|*|
;	|*|	fill buffer with name of bibliographic file for drive 
;	|*|
;	|*|	Entry:	drive number, address of buffer
;	|*|
;	|*|	Exit:	0 if successful, -1 if error occurred
;	|*|
;	\*/

getbibliofname proc
	push bp
	mov bp, sp

	mov ax, 1504h
	mov cx, wParm1
	les bx, wParm2
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1
	jmp short done

okay:
	xor ax, ax

done:
	pop bp
	ret
getbibliofname endp

;	/*\
;	|*|	int readvtoc(int drive, int index, char far *dscbuf)
;	|*|
;	|*|	read entry from volume table of contents for drive 
;	|*|
;	|*|	Entry:	drive number, entry number, address of buffer
;	|*|
;	|*|	Exit:	return type of descriptor read, or -2 if error 
;	|*|
;	\*/

	public readvtoc
readvtoc proc
	push bp
	mov bp, sp

	mov ax, 1505h
	mov cx, wParm1
	mov dx, wParm2
	les bx, wParm3
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -2

okay:
	cbw

	pop bp
	ret
readvtoc endp

;	/*\
;	|*|	int absdiscread(int drive, int count, long sector, char far *buffer)
;	|*|
;	|*|	read one or more logical sectors for drive 
;	|*|	Entry:	drive number, count of sectors, 
;	|*|		starting sector number, address of buffer for data
;	|*|
;	|*|	Exit:	returns count of sectors read, -1 if error 
;	|*|
;	\*/

	public absdiscread
absdiscread proc
	push bp
	mov bp, sp
	push si
	push di

	mov ax, 1508h
	mov cx, wParm1
	mov dx, wParm2
	mov di, wParm3
	mov si, wParm4
	les bx, wParm5
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1
	jmp short done

okay:
	mov ax, wParm2

done:
	pop di
	pop si
	pop bp
	ret
absdiscread endp

;	/*\
;	|*|	int absdiscwrite(int drive, int count, long sector, char far *buffer)
;	|*|
;	|*|	write one or more logical sectors for drive 
;	|*|
;	|*|	Entry:	drive number, count of sectors to write,
;	|*|		starting sector, address of buffer
;	|*|
;	|*|	Exit:	returns count of sectors written, -1 if error 
;	|*|
;	\*/

	public absdiscwrite
absdiscwrite proc
	push bp
	mov bp, sp
	push si
	push di

	mov ax, 1509h
	mov cx, wParm1
	mov dx, wParm2
	mov di, wParm3
	mov si, wParm4
	les bx, wParm5
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1
	jmp short done

okay:
	mov ax, wParm2

done:
	pop di
	pop si
	pop bp
	ret
absdiscwrite endp

;	/*\
;	|*|	int chkdrive(int drive)
;	|*|
;	|*|	check if drive supported by mscdex 
;	|*|
;	|*|	Entry:	drive number
;	|*|
;	|*|	Exit:	return 0 if mscdex installed and drive is supported
;	|*|		return 1 if mscdex installed and drive not supported
;	|*|		return -1 if mscdex not installed 
;	|*|
;	\*/

	public chkdrive
chkdrive proc
	push bp
	mov bp, sp

	mov ax, 150Bh
	mov bx, 0
	mov cx, wParm1
	int 2Fh

	cmp bx, 0ADADh
	jnz nomscdex

	cmp ax, 0
	jz notcdrom

	mov ax, 0
	jmp short done

nomscdex:
	mov ax, -1
	jmp short done

notcdrom:
	mov ax, 1

done:
	pop bp
	ret
chkdrive endp

;	/*\
;	|*|	int getmscdexversion(void) 
;	|*|
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	return version of mscdex 
;	|*|
;	\*/

	public getmscdexversion
getmscdexversion proc
	push bp
	mov bp, sp

	mov ax, 150Ch
	xor bx, bx
	int 2Fh

	mov ax, bx

	pop bp
	ret
getmscdexversion endp

;	/*\
;	|*|	int getcdromunits(char far *cdromunits)
;	|*|
;	|*|	fill buffer with list of cdrom drives 
;	|*|
;	|*|	Entry:	address of buffer
;	|*|
;	|*|	Exit:	none
;	|*|
;	\*/

	public getcdromunits
getcdromunits proc
	push bp
	mov bp, sp

	mov ax, 150Dh
	les bx, dParm1
	int 2Fh

	pop bp
	ret
getcdromunits endp

;	/*\
;	|*|	int getvdescpref(int drive)
;	|*|
;	|*|	get preference for primary or supplementary descriptors 
;	|*|
;	|*|	Entry:	drive number
;	|*|
;	|*|	Exit:	return 0 or 1 (preference), or -1 if error 
;	|*|
;	\*/

	public getvdescpref
getvdescpref proc
	push bp
	mov bp, sp

	mov ax, 150Eh
	xor bx, bx
	mov cx, wParm1
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1

okay:
	pop bp
	ret
getvdescpref endp

;	/*\
;	|*|	int setvdescpref(int drive, int pref)
;	|*|
;	|*|	set preference for primary or supplementary descriptors 
;	|*|
;	|*|	Entry:	drive number, preference (0 primary, 1 secondary)
;	|*|
;	|*|	Exit:	return 0 if successful, -1 if error occurred
;	|*|
;	\*/

	public setvdescpref
setvdescpref proc
	push bp
	mov bp, sp

	mov ax, 150Eh
	mov bx, 1
	mov cx, wParm1
	mov dx, wParm2

	cmp dh, 1
	jnz isvalid
	cmp dl, 0
	jnz invalid

isvalid:
	int 2Fh
	jnc okay

	mov lasterror, ax

invalid:
	mov ax, -1
	jmp short done

okay:
	xor ax, ax

done:
	pop bp
	ret
setvdescpref endp

;	/*\
;	|*|	int getdirentry(int drive, char far *name, char far *buffer)
;	|*|
;	|*|	search directory for entry, fill buffer if found 
;	|*|
;	|*|	Entry:	drive number, address of file name, address of buffer
;	|*|
;	|*|	Exit:	return format of volume, -1 if error 
;	|*|
;	\*/

	public getdirentry
getdirentry proc
	push bp
	mov bp, sp
	push si
	push di

	mov ax, 150Fh
	mov cx, wParm1
	les bx, wParm2
	mov di, wParm4
	mov si, wParm5
	int 2Fh
	jnc okay

	mov lasterror, ax
	mov ax, -1

okay:
	pop di
	pop si
	pop bp
	ret
getdirentry endp

;	/*\
;	|*|	int senddevreq(int drive, void far *cdh) 
;	|*|
;	|*|	send device request 
;	|*|
;	|*|	Entry:	drive number, address of buffer
;	|*|
;	|*|	Exit:	none (status placed in buffer by driver)
;	|*|
;	\*/

	public senddevreq
senddevreq proc
	push bp
	mov bp, sp

	mov ax, 1510h
	mov cx, wParm1
	les bx, wParm2
	int 2Fh

	pop bp
	ret
senddevreq endp

;	/*\
;	|*|	int getlasterror(void) 
;	|*|
;	|*|	return value in lasterror
;	|*|
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	last error value saved 
;	|*|
;	\*/

	public getlasterror
getlasterror proc
	push bp
	mov bp, sp

	mov ax, lasterror

	pop bp
	ret
getlasterror endp

;	/*\
;	|*|	int clearlasterror(void) 
;	|*|
;	|*|	Entry:	none
;	|*|
;	|*|	Exit:	last saved error value
;	|*|
;	\*/

	public clearlasterror
clearlasterror proc
	push bp
	mov bp, sp

	xor ax, ax
	xchg lasterror, ax

	pop bp
	ret
clearlasterror endp
end
