;;************ DIGPLAY.ASM, flat-model link layer to DIGPAK functions.
;;************ written using Borland Assembler in IDEAL mode.  Assumes
;;************ a DPMI with a flat model address space where selectors
;;************ DS and ES always point to flat address 0000000000000h!
;;************ Written and tested with DOS4GW and Watcom C.  Uses
;;************ standard C calling convention.  Getting this to work
;;************ under any other DPMI is an excercise left for ths student.
;;************ Warning!! The Watcom compiler passes 4 bytes on the stack
;;************ to a cdecl external routine, even if the parameter is only
;;************ a char.	All of these assembly routines have been defined
;;************ this way.  If you are usinga compiler that passes different
;;************ size arguments to cdecl routines, you may want to double
;;************ check for compatibilities sake.
;;************ The FLAT-MODEL DIGPAK DOES NOT SUPPORT 8253 TIMER BASED
;;************ DRIVERS!  Their interrupt requirements are too excessive
;;************ and create too many incompatibility problems for protected
;;************ mode applications.
;;***
;;*** Written by John W. Ratcliff (c) 1994
;;***		 Compuserve: 70253,3237
;;***		 Genie: J.RATCLIFF3
;;***		 BBS: 1-314-939-0200
;;***		 Addresss:
;;***			   747 Napa Lane
;;***			   St. Charles, MO 63304
;;***
;;***	 A $500 per product license fee applies to all commercial software
;;***	 products distributed with any DIGPAK drivers.
;;***	 To pay a license, simply write a check for $500 payable to
;;***	 The Audio Solution, 747 Napa Lane, St. Charles, MO 63304
;;***	 with a copy of your commerical product.  You will receive a signed
;;***	 license agreement from The Audio Solution shortly thereafter.
;;***	 This license fee applies specifically to the inclusion with your
;;***	 distribution disk any of the DIGPAK drivers from The Audio Solution
;;***	 These drivers are copyrighted works, created by me, to enhance the
;;***	 use of sound and music in DOS based commercial software.	 The
;;***	 license fees collected are used to maintain the drivers and keep
;;***	 the BBS running.	 There is a seperate license fee for the use
;;***	 and distribution of MIDPAK drivers.
;;***	 See accompaning documentation regarding license fees for MIDPAK
;;***	 distribution.	You would be ill-advised to distribute a commercial
;;***	 product containing either DIGPAK and/or MIDPAK drivers without
;;***	 having paid the distribution license fee.  Since your product would
;;***	 contain unlicensed copyrighted software from The Audio Solution,
;;***	 your product could be immediatly required to be removed from retail
;;***	 distribution.	I doubt this is going to be a problem.	Clearly if
;;***	 your product is enhanced by the use of these drivers, your company
;;***	 can easily afford a nominal license fee of $500 in exchange for
;;***	 getting the use of several man-years of software engineering
;;***	 resources.
;;******************************************************************************


	IDEAL
	P386
	JUMPS
	MODEL FLAT,C

	CODESEG

	public	CheckIn
	public	DigPlay
	public	SetDPMIMode
	public	ReportVersionNumber
	public	SoundStatus
	public	MassageAudio
	public	DigPlay2
	public	AudioCapabilities
	public	DigPakIdentityString
	public	StopSound
	public	WaitSound
	public	PostAudioPending
	public	AudioPendingStatus
	public	SetStereoPan
	public	SetPlayMode
	public	PendingAddress
	public	ReportSemaphoreAddress
	public	SetRecordMode
	public	SetBackFillMode
	public	ReportDMAC
	public	NullSound
	public	VerifyDMA
	public	InitDP
	public	DeInitDP

;; DIGPAK sound function equates.

DIG_DIGPLAY	equ	688h
DIG_SOUNDSTATUS equ	689h
DIG_MASSAGEAUDIO equ	68Ah
DIG_DIGPLAY2	equ	68Bh
DIG_AUDIOCAP	equ	68Ch
DIG_IDENTITY	equ	68Ch
DIG_STOPSOUND	equ	68Fh
DIG_POSTPEND	equ	695h
DIG_PENDSTATUS	equ	696h
DIG_STEREOPAN	equ	697h
DIG_PLAYMODE	equ	698h
DIG_PENDADDRESS equ	699h
DIG_SEMAPHORE	equ	699h
DIG_DIVISOR	equ	693h
DIG_RECORD	equ	69Ah
DIG_BACKFILL	equ	69Ch
DIG_REPORTDMA	equ	69Dh
DIG_VERIFYDMA	equ	69Eh
DIG_REPORTVERSION equ	689h
DIG_SETDPMIMODE equ	6A0h

SOUNDINT	equ	66h	; Interrupt vector.

Proc	C CheckIn	near
	uses	ebx,ds,es

	mov	ebx,SOUNDINT*4h
	mov	eax,[ds:ebx]	; Get addresss or interrupt vector.
	or	eax,eax
	jz	@@CIOUT 	; Exit if vector is null.
	mov	bx,ax		; Get offset portion.
	shr	eax,(16-4)	; Get segment portion down.
	and	eax,0FFFFF0h
	add	ebx,eax 	; now have real-address.
	sub	ebx,6		; point back to identifier
	xor	eax,eax 	; Zero out entire EAX return register.

	cmp	[word ebx],'IM'  ; Midi driver?
	jne	@@NEX
	cmp	[word ebx+2],'ID'  ; full midi driver identity string?
	jne	@@NEX
;; Ok, a MIDI driver is loaded at this address.
	mov	ax,701h 	; Digitized Sound capabilities request.
	int	SOUNDINT	     ; Request.
	or	ax,ax		; digitized sound driver available?
	jnz	@@OK		; yes, report that to the caller.
	jz	@@CIOUT 	; exit, sound driver not available.
@@NEX:
	cmp	[word ebx],454Bh ; equal?
        jne     @@CIOUT         ; exit if not equal
	cmp	[word ebx+2],4E52h    ; equal?
        jne     @@CIOUT
@@OK:	mov	ax,1
@@EXT:
	ret
@@CIOUT: xor	ax,ax		; Zero return code.
	jmp short @@EXT
	endp

Proc	C DigPlay	near
	ARG	SND:DWORD
	uses	esi,ds,es

	mov	esi,[SND]
	mov	eax,DIG_DIGPLAY
	int	SOUNDINT

	ret
	endp

Proc	C SetDPMIMode	near
	ARG	MODE:DWORD
	uses	edx,ds,es

	mov	edx,[MODE]
	mov	ax,DIG_SETDPMIMODE
	int	SOUNDINT

	ret
	endp

PROC	C ReportVersionNumber	near
	uses	ebx,ds,es
	xor	ebx,ebx 	  ; Default version number.
	mov	eax,DIG_REPORTVERSION	     ; Get version number/status call.
	int	SOUNDINT
	mov	eax,ebx 	  ; Return version number.
	ret
	endp

Proc	C SoundStatus near
	uses	ds,es
	mov	eax,DIG_SOUNDSTATUS	  ; Check sound status.
	int	SOUNDINT	     ; Sound driver interrupt.
	ret
	endp

Proc	C MassageAudio	  near
	ARG	DATA:DWORD
	uses	esi,ds,es

	mov	eax,DIG_MASSAGEAUDIO	   ; Identity
	mov	esi,[DATA]	; Data structure.
	int	SOUNDINT	     ; Do sound interupt.

	ret
	endp

Proc	C DigPlay2 near
	ARG	DATA:DWORD
	uses	esi,ds,es

	mov	eax,DIG_DIGPLAY2	; Identity
	mov	esi,[DATA]	 ; Data structure.
	int	SOUNDINT	     ; Do sound interupt.

	ret
	endp

Proc	C AudioCapabilities near
	uses	ds,es
	mov	eax,DIG_AUDIOCAP
	int	SOUNDINT
	ret
	endp

Proc	C DigPakIdentityString near
        ARG     string:DWORD
	uses	ebx,ecx,esi,edi,ds,es

	xor	ecx,ecx 	; Zero high portion of ECX
	xor	ebx,ebx 	; Zero ebx
	mov	eax,DIG_IDENTITY
	int	SOUNDINT
	mov	edi,[string]
	mov	esi,ebx 	; Get segment.
	shl	esi,4		; Into flat-model address space.
	add	esi,ecx 	; Add the offset portion.
	mov	ecx,-1
@@MV:   lodsb
        stosb
	inc	ecx
	or	al,al
	jnz	@@MV
	mov	eax,ecx 	  ; Return string length.

	ret
	endp

;; void StopSound(void);    // 68Fh -> Stop current sound from playing.
Proc	C StopSound near
	uses	ds,es
	mov	eax,DIG_STOPSOUND
	int	SOUNDINT
	ret
	endp

Proc	C WaitSound near
	uses	ds,es
@@WS:	mov	eax,DIG_SOUNDSTATUS
	int	SOUNDINT
	or	ax,ax
	jnz	@@WS
	ret
	endp

Proc	C PostAudioPending near
	ARG	SOUND:DWORD
	uses	edi,ds,es
	mov	esi,[SOUND]
	mov	eax,DIG_POSTPEND
	int	SOUNDINT
	ret
	endp

PROC	C AudioPendingStatus near
	uses	ds,es
	mov	eax,DIG_PENDSTATUS
	int	SOUNDINT
	ret
	endp

Proc	C SetStereoPan near
	ARG	PAN:DWORD
	uses	edx,ds,es
	mov	edx,[PAN]
	mov	eax,DIG_STEREOPAN
	int	SOUNDINT
	ret
	endp

Proc	C SetPlayMode
	ARG	MODE:DWORD
	uses	edx,ds,es
	mov	edx,[MODE]
	mov	eax,DIG_PLAYMODE
	int	SOUNDINT
	ret
	endp

Proc	C PendingAddress near
	uses	edx,ds,es
	xor	edx,edx
	mov	eax,DIG_PENDADDRESS
	int	SOUNDINT
	shl	edx,4		; Into flat-model address space.
	add	eax,edx 	; Form full flat-model address.
	ret
	endp

Proc	C ReportSemaphoreAddress near
	uses	ebx,edx,ds,es
	xor	edx,edx
	xor	ebx,ebx
	mov	ax,DIG_SEMAPHORE
	int	SOUNDINT
	mov	eax,edx 	; get segment.
	shl	eax,4		; into flat space.
	add	eax,ebx 	; Add offset portion.
	ret
	endp

Proc	C  SetRecordMode near
	ARG	MODE:DWORD
	uses	edx,ds,es
	mov	edx,[MODE]
	mov	eax,DIG_RECORD
	int	SOUNDINT
	ret
	endp


Proc	C SetBackFillMode near
	ARG	MODE:DWORD
	uses	edx,ds,es
	mov	edx,[MODE]
	mov	eax,DIG_BACKFILL
	int	SOUNDINT
	ret
	endp

Proc	C ReportDMAC near
	uses	ds,es
	mov	eax,DIG_REPORTDMA
	int	SOUNDINT
	ret
	endp


Proc	C NullSound near
	ARG	SOUND:DWORD,SNDLEN:DWORD,VALUE:DWORD
	uses	ecx,edi

	mov	edi,[SOUND]
	mov	eax,[VALUE]
	mov	ecx,[SNDLEN]
	rep	stosb

	ret
	endp

Proc	C VerifyDMA near
	ARG	SDATA:DWORD,SLEN:DWORD
	uses	ebx,ecx,ds,es
	mov	ebx,[SDATA]
	mov	ecx,[SLEN]
	mov	eax,DIG_VERIFYDMA
	int	SOUNDINT
	ret
	endp


Proc	C InitDP near
	ARG	DIGPAK:DWORD
	uses	ebx,ecx,esi,edi,ds,es

	mov	ebx,[DIGPAK]	; Get the address of the 'supposed' DIGPAK.
	cmp	[byte ebx+3],'D'        ; Does it say digpak?
	jne	@@FREE
	cmp	[byte ebx+4],'I'        ;
	jne	@@FREE
	cmp	[byte ebx+5],'G'
	jne	@@FREE
	cmp	[byte ebx+6],'P'
	jne	@@FREE
	cmp	[byte ebx+7],'A'
	jne	@@FREE
	cmp	[byte ebx+8],'K'
	jne	@@FREE
;; Ok, it SAY's DIGPAK.
	shr	ebx,4		; Into segment size.
	sub	ebx,10h 	; org 100h, segment
	mov	ecx,200h	; offset
	mov	eax,0301h	; simulate realmode far proc.
	int	66h
	or	ax,ax
	jnz	@@FREE
	mov	ax,1		; Success.
@@RET:
	ret
@@FREE:
	xor	ax,ax	; Zero failed return code
	jmp short @@RET
	endp

Proc	C DeInitDP near
	ARG	DIGPAK:DWORD
	uses	ebx,ecx,esi,edi,ds,es

	mov	ebx,[DIGPAK]
	shr	ebx,4		; Into segment size.
	sub	ebx,10h 	; org 100h
	mov	ecx,203h	; offset.
	mov	eax,0301h	; simulate realmode far proc.
	int	66h
	or	ax,ax
	jnz	@@FREE
	mov	ax,1		; Success.
@@RET:
	ret
@@FREE:
	xor	ax,ax	; Zero failed return code
	jmp short @@RET
	ret
	endp

	ends
	end
