         .MODEL  LARGE
         .DATA
         PUBLIC _G8000_
         _G8000_     dw      220h
         PUBLIC _G8001_
         _G8001_    db      0
         _G8002_     dw      0
         G8003_         db      20 dup (0)
         _G8004_    db      0
         _G8005_     dw      0
         _G8006_     dw      0
         _G8007_    db      0
         _G8008_     dw      0
         _G8009_     dw      0
         _G8010_     dw      0
         .CODE
F8000_	proc near
		push	cx
		mov	cx, 200h
		mov	ah, al
loc_1050A:
		in	al, dx
		or	al, al
		jns	short loc_10514
		loop	loc_1050A
		stc
		jmp	short loc_10518
loc_10514:
		mov	al, ah
		out	dx, al
		clc
loc_10518:
		pop	cx
		retn
F8000_	endp

F8001_	proc near
		push	cx
		push	dx
		mov	dx, _G8000_
		add	dl, 0Eh
		mov	cx, 200h
loc_10526:
		in	al, dx
		or	al, al
		js	short loc_10530
		loop	loc_10526
		stc
		jmp	short loc_10535
loc_10530:
		sub	dl, 4
		in	al, dx
		clc
loc_10535:
		pop	dx
		pop	cx
		retn
F8001_	endp

F8002_	proc near
		mov	ah, al
		mov	al, 0F0h
loc_1053C:
		in	al, dx
		or	al, al
		js	loc_1053C
		mov	al, ah
		out	dx, al
		retn
F8002_	endp

F8003_	proc near
		push	dx
		mov	dx, _G8000_
		add	dl, 0Eh
		sub	al, al
loc_1054F:
		in	al, dx
		or	al, al
		jns	loc_1054F
		sub	dl, 4
		in	al, dx
		pop	dx
		retn
F8003_	endp

F8004_	proc near
		mov	dx, _G8000_
		add	dl, 6
		mov	al, 1
		out	dx, al
		in	al, dx
loc_10565:
		inc	al
		jnz	loc_10565
		out	dx, al
		mov	cl, 20h
loc_1056C:
		call	F8001_
		cmp	al, 0AAh
		jz	short loc_1057C
		dec	cl
		jnz	loc_1056C
		mov	ax, 2
		jmp	short loc_1057E
loc_1057C:
		sub	ax, ax
loc_1057E:
		or	ax, ax
		retn
F8004_	endp

F8005_	proc near
		mov	bx, 2
		mov	al, 0E0h
		mov	dx, _G8000_
		add	dx, 0Ch
		call	F8000_
		jb	short loc_105A4
		mov	al, 0AAh
		call	F8000_
		jb	short loc_105A4
		call	F8001_
		jb	short loc_105A4
		cmp	al, 55h
		jnz	short loc_105A4
		sub	bx, bx
loc_105A4:
		mov	ax, bx
		or	ax, ax
		retn
F8005_	endp

F8006_	proc near
		mov	al, 2
		mov	dx, offset F8013_
		mov	bx, offset G8003_
		call	F8011_
		mov	al, 3
		mov	dx, offset loc_10704
		mov	bx, 9Ah
		call	F8011_
		mov	al, 5
		mov	dx, offset loc_10709
		mov	bx, 9Fh
		call	F8011_
		mov	al, 7
		mov	dx, offset loc_1070E
		mov	bx, 0A4h
		call	F8011_
		mov	dx, _G8000_
		add	dx, 0Ch
		mov	al, 0F2h
		call	F8002_
		sub	ax, ax
		mov	cx, 800h
loc_105E6:
		cmp	_G8001_, 0
		jnz	short loc_105F2
		loop	loc_105E6
		mov	ax, 3
loc_105F2:
		push	ax
		mov	al, 2
		mov	bx, offset G8003_
		call	F8012_
		mov	al, 3
		mov	bx, 9Ah
		call	F8012_
		mov	al, 5
		mov	bx, 9Fh
		call	F8012_
		mov	al, 7
		mov	bx, 0A4h
		call	F8012_
		pop	ax
		or	ax, ax
		retn
F8006_	endp

F8007_	proc near
		mov	al, 0E1h
		mov	dx, _G8000_
		add	dl, 0Ch
		call	F8002_
		call	F8003_
		mov	ah, al
		call	F8003_
		mov	bx, 1
		cmp	ax, 101h
		jb	short loc_10635
		sub	bx, bx
loc_10635:
		mov	ax, bx
		or	ax, ax
		retn
F8007_	endp

F8008_	proc near
		pushf
		mov	ah, 0D0h
		mov	bx, 93h
		sub	cx, cx
		mov	dx, _G8000_
		add	dl, 0Ch
loc_10649:
		sti
		cmp	cx, [bx]
		jz	short loc_1065C
		cli
		in	al, dx
		or	al, al
		jns	loc_10649
loc_10654:
		in	al, dx
		or	al, al
		js	loc_10654
		mov	al, ah
		out	dx, al
loc_1065C:
		popf
		retn
F8008_	endp

F8009_	proc near
		push	bx
		mov	bx, ax
		mov	al, 5
		out	0Ah, al		; DMA controller, 8237A-5.
					; single mask bit register
					; 0-1: select channel (00=0; 01=1; 10=2; 11=3)
					; 2: 1=set mask	for channel; 0=clear mask (enable)
		sub	al, al
		out	0Ch, al		; DMA controller, 8237A-5.
					; clear	byte pointer flip-flop.
		mov	al, dh
		out	0Bh, al		; DMA 8237A-5. mode register bits:
					; 0-1: channel (00=0; 01=1; 10=2; 11=3)
					; 2-3: transfer	type (00=verify=Nop; 01=write; 10=read)
					; 4: 1=enable auto-initialization
					; 5: 1=address increment; 0=address decrement
					; 6-7: 00=demand mode; 01=single; 10=block; 11=cascade
		mov	al, bl
		out	2, al		; DMA controller, 8237A-5.
					; channel 1 base address
					; (also	sets current address)
		mov	al, bh
		out	2, al		; DMA controller, 8237A-5.
					; channel 1 base address
					; (also	sets current address)
		mov	al, cl
		out	3, al		; DMA controller, 8237A-5.
					; channel 1 base address and word count
		mov	al, ch
		out	3, al		; DMA controller, 8237A-5.
					; channel 1 base address and word count
		mov	al, dl
		out	83h, al		; DMA page register 74LS612:
					; Channel 1 (address bits 16-23)
		mov	al, 1
		out	0Ah, al		; DMA controller, 8237A-5.
					; single mask bit register
					; 0-1: select channel (00=0; 01=1; 10=2; 11=3)
					; 2: 1=set mask	for channel; 0=clear mask (enable)
		pop	bx
		retn
F8009_	endp

F8010_	proc near
		push	cx
		mov	cl, 4
		rol	dx, cl
		mov	cx, dx
		and	dx, 0Fh
		and	cx, 0FFF0h
		add	ax, cx
		adc	dx, 0
		pop	cx
		retn
F8010_	endp

F8011_	proc near
		push	es
		push	ax
		add	al, 8
		push	ax
		push	dx
		push	bx
		push	ax
		in	al, 21h		; Interrupt controller,	8259A.
		mov	[bx+4],	al
		pop	ax
		mov	ah, 35h
		int	21h		; DOS -	2+ - GET INTERRUPT VECTOR
					; AL = interrupt number
					; Return: ES:BX	= value	of interrupt vector
		mov	dx, bx
		pop	bx
		mov	[bx], dx
		mov	ax, es
		mov	[bx+2],	ax
		pop	dx
		pop	ax
		push	ds
		mov	bx, cs
		mov	ds, bx
		mov	ah, 25h
		int	21h		; DOS -	SET INTERRUPT VECTOR
					; AL = interrupt number
					; DS:DX	= new vector to	be used	for specified interrupt
		pop	ds
		pop	cx
		mov	ah, 1
		shl	ah, cl
		not	ah
		pushf
		cli
		in	al, 21h		; Interrupt controller,	8259A.
		and	al, ah
		out	21h, al		; Interrupt controller,	8259A.
		popf
		pop	es
		retn
F8011_	endp

F8012_	proc near
		push	ax
		push	cx
		pushf
		cli
		mov	ch, 1
		mov	cl, al
		shl	ch, cl
		mov	cl, [bx+4]
		and	cl, ch
		not	ch
		in	al, 21h		; Interrupt controller,	8259A.
		and	al, ch
		or	al, cl
		out	21h, al		; Interrupt controller,	8259A.
		popf
		pop	cx
		pop	ax
		push	ds
		mov	dx, [bx+2]
		mov	ds, dx
		mov	dx, [bx]
		mov	ah, 25h
		int	21h		; DOS -	SET INTERRUPT VECTOR
					; AL = interrupt number
					; DS:DX	= new vector to	be used	for specified interrupt
		pop	ds
		retn
F8012_	endp

F8013_	proc far
		push	dx
		mov	dl, 2
		jmp	short loc_10711
loc_10704:
		push	dx
		mov	dl, 3
		jmp	short loc_10711
loc_10709:
		push	dx
		mov	dl, 5
		jmp	short loc_10711
loc_1070E:
		push	dx
		mov	dl, 7
loc_10711:
		push	ds
		push	ax
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	_G8001_, dl
		mov	dx, _G8000_
		add	dx, 0Eh
		in	al, dx
		mov	al, 20h
		out	20h, al		; Interrupt controller,	8259A.
		pop	ax
		pop	ds
		pop	dx
		iret
F8013_	endp

F8014_	proc far
		push	ds
		push	es
		push	ax
		push	bx
		push	cx
		push	dx
		push	di
		push	si
		push	bp
		cld
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	es, ax
		mov	dx, _G8000_
		add	dl, 0Eh
		in	al, dx
		mov	ax, _G8008_
		or	ax, ax
		jnz	short loc_10751
		call	F8016_
		jmp	short loc_10754
loc_10751:
		call	F8015_
loc_10754:
		mov	al, 20h
		out	20h, al		; Interrupt controller,	8259A.
		pop	bp
		pop	si
		pop	di
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		pop	es
		pop	ds
		iret
F8014_	endp

F8015_	proc near
		mov	cx, 0FFFFh
		cmp	_G8007_, 0
		jnz	short loc_10774
		inc	_G8007_
		mov	cx, _G8010_
loc_10774:
		sub	cx, _G8005_
		mov	_G8006_, cx
		inc	cx
		jz	short loc_1078A
		sub	_G8008_, cx
		sbb	_G8009_, 0
		jmp	short loc_1078E
loc_1078A:
		dec	_G8009_
loc_1078E:
		mov	dh, 49h
		mov	dl, _G8004_
		mov	ax, _G8005_
		mov	cx, _G8006_
		call	F8009_
		dec	_G8007_
		inc	_G8004_
		mov	_G8005_, 0
		mov	cx, _G8006_
		mov	dx, _G8000_
		add	dl, 0Ch
		mov	al, 14h
		call	F8002_
		mov	al, cl
		call	F8002_
		mov	al, ch
		call	F8002_
		retn
F8015_	endp

F8016_	proc near
		mov	al, 5
		out	0Ah, al		; DMA controller, 8237A-5.
					; single mask bit register
					; 0-1: select channel (00=0; 01=1; 10=2; 11=3)
					; 2: 1=set mask	for channel; 0=clear mask (enable)
		mov	al, _G8001_
		mov	bx, offset G8003_
		call	F8012_
		mov	_G8002_, 0
		mov	dx, _G8000_
		add	dl, 0Eh
		in	al, dx
		retn
F8016_	endp

PUBLIC _F8017_
_F8017_	proc far
		push	ds
		push	es
		push	di
		push	si
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	es, ax
		call	F8004_
		jnz	short loc_10809
		call	F8005_
		jnz	short loc_10809
		call	F8007_
		jnz	short loc_10809
		call	F8006_
		jnz	short loc_10809
		mov	al, 1
		call	F8018_
		sub	ax, ax
loc_10809:
		pop	si
		pop	di
		pop	es
		pop	ds
		retf
_F8017_	endp

F8018_	proc near
		mov	dx, _G8000_
		add	dx, 0Ch
		mov	ah, 0D1h
		or	al, al
		jnz	short loc_1081D
		mov	ah, 0D3h
loc_1081D:
		mov	al, ah
		call	F8002_
		sub	ax, ax
		retn
F8018_	endp

; Attributes: bp-based frame
F8019_	proc far
arg_0		= word ptr  6
arg_2		= word ptr  8
arg_4		= word ptr  0Ah
arg_6		= word ptr  0Ch
		push	bp
		mov	bp, sp
		push	ds
		push	es
		push	di
		push	si
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	es, ax
		cmp	_G8002_, 0
		jz	short loc_1083F
		mov	ax, 1
		jmp	short loc_108B1
loc_1083F:
		mov	_G8002_, 1
		mov	dx, _G8000_
		add	dl, 0Ch
		mov	dx, 0Fh
		mov	ax, 4240h
		mov	cx, [bp+arg_6]
		div	cx
		mov	cl, al
		neg	cl
		mov	dx, _G8000_
		add	dl, 0Ch
		mov	al, 40h
		call	F8002_
		mov	al, cl
		call	F8002_
		mov	al, _G8001_
		mov	dx, offset F8014_
		mov	bx, offset G8003_
		call	F8011_
		mov	dx, [bp+arg_2]
		mov	ax, [bp+arg_0]
		call	F8010_
		mov	_G8004_, dl
		mov	_G8005_, ax
		mov	cx, [bp+arg_4]
		mov	_G8008_, cx
		mov	_G8009_, 0
		add	ax, [bp+arg_4]
		adc	dl, 0
		sub	ax, 1
		sbb	dl, 0
		mov	_G8010_, ax
		sub	dl, _G8004_
		mov	_G8007_, dl
		call	F8015_
		sub	ax, ax
loc_108B1:
		pop	si
		pop	di
		pop	es
		pop	ds
		pop	bp
		retf
F8019_	endp

F8020_	proc far
		push	ds
		push	es
		push	di
		push	si
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	es, ax
		mov	ax, 1
		cmp	_G8002_, 0
		jz	short loc_108D4
		call	F8008_
		call	F8016_
		sub	ax, ax
loc_108D4:
		pop	si
		pop	di
		pop	es
		pop	ds
		retf
F8020_	endp

PUBLIC _F8021_
_F8021_	proc far
		push	ds
		push	es
		push	di
		push	si
		mov	ax, seg	DGROUP
		mov	ds, ax
		mov	es, ax
		cmp	_G8002_, 0
		jz	short loc_108F1
		call	F8008_
		call	F8016_
loc_108F1:
		sub	al, al
		call	F8018_
		sub	ax, ax
		pop	si
		pop	di
		pop	es
		pop	ds
		retf
_F8021_	endp

PUBLIC _F8022_IsSoundBlasterPresent
_F8022_IsSoundBlasterPresent	proc far
		push	ds
		mov	ax, seg	DGROUP
		mov	ds, ax
		sub	bx, bx
		mov	dx, _G8000_
		add	dl, 6
		mov	al, 0C6h
		out	dx, al
		sub	al, al
		add	dl, 4
		out	dx, al
		in	al, dx
		cmp	al, 0C6h
		jnz	short loc_10930
		sub	dl, 4
		mov	al, 39h
		out	dx, al
		sub	al, al
		add	dl, 4
		out	dx, al
		in	al, dx
		cmp	al, 39h
		jnz	short loc_10930
		mov	bx, 1
		jmp	short loc_10956
loc_10930:
		call	F8004_
		jnz	short loc_10956
		mov	dx, _G8000_
		add	dl, 0Ch
		mov	al, 0E0h
		call	F8000_
		jb	short loc_10956
		mov	al, 0C6h
		call	F8000_
		jb	short loc_10956
		call	F8001_
		jb	short loc_10956
		cmp	al, 39h
		jnz	short loc_10956
		mov	bx, 5
loc_10956:
		mov	ax, bx
		pop	ds
		retf
_F8022_IsSoundBlasterPresent	endp

END
