

		.model small, c		

		.stack 256

		locals

		assume cs:@code, ds:@data

.data
ports		dw	220h
		dw	240h
		dw	280h
		dw	2c0h

success0	db	"Port search successfull - port 0x220", 0dh, 0ah, "$"
success1	db	"Port search successfull - port 0x240", 0dh, 0ah, "$"
success2	db	"Port search successfull - port 0x280", 0dh, 0ah, "$"
success3	db	"Port search successfull - port 0x2c0", 0dh, 0ah, "$"

failure		db	"Unable to detect port", 0dh, 0ah, "$"


.code

main		proc

		mov	ax, @data
		mov	ds, ax

		call	PortSearch

		mov	ax, 4c00h
		int	21h

main		endp



PortSearch	proc

		mov	cx, 4

		;
		; for each defined port
		;
@@loop1:	mov	bx, cx
		dec	bx
		shl	bx, 1
		mov	dx, [ports][bx]
		
		;
		; write to the first 6 registers
		;
		xor	ax, ax			; start with register zero and data zero
@@loop2:	call	WriteRegister		; select and write to the register
		inc	ah			; increment register index
		mov	al, ah			; use register index as data
		cmp	ah, 6			; check if registers 0-5 processed
		jb	short @@loop2		; repeat until first 6 registers set

		;
		; read the first 6 registers and verify the value
		;
		xor	ah, ah			; start with register zero
@@loop3:	call	ReadRegister		; read the current register
		cmp	al, ah			; does data equal the register index
		jnz	short @@notfound	; branch if not (do next port)
		inc	ah			; increment register index
		cmp	ah, 6			; check if registers 0-5 processed
		jb	short @@loop3		; repeat until first 6 registers verified

		;
		; the current port has responded 
		;
		call	DisplaySuccess
		jmp	short @@exit

		;
		; process the next port address
		;
@@notfound:	loop	@@loop1

		;
		; a sound master has not been detected
		;
		call	DisplayFailure

@@exit:		mov	ax, 4c00h
		int	21h

PortSearch	endp



; dx = port
; ah = register
; al = data
WriteRegister	proc

		push 	ax
		push	cx
		push	dx

		xchg	al, ah
		out	dx, al
		inc	dx
		xchg	al, ah

		mov	ah, al

		mov	cx, 100

@@loop1:	out	dx, al
		jmp	short @@1
@@1:		in	al, dx
		cmp	al, ah
		je	short @@2
		mov	al, ah
		loop	@@loop1

@@2:		pop	dx
		pop	cx
		pop	ax

		ret

WriteRegister	endp


; dx = port
; ah = register
ReadRegister	proc

		push	bx
		push	dx

		mov	bx, ax
		
		mov	al, ah
		out	dx, al
		inc	dx
		jmp	short @@1
@@1:		in	al, dx
		
		mov	ah, bh

		pop	dx
		pop	bx

		ret

ReadRegister	endp


DisplaySuccess	proc

		cmp	dx, 220h
		jne	short @@1
		mov	dx, offset success0
		jmp	short @@x
@@1:		cmp	dx, 240h
		jne	short @@2
		mov	dx, offset success1
		jmp	short @@x
@@2:		cmp	dx, 280h
		jne	short @@3
		mov	dx, offset success2
		jmp	short @@x
@@3:		mov	dx, offset success3
@@x:		mov	ax, 0900h
		int	21h

		ret

DisplaySuccess	endp

DisplayFailure	proc

		mov	dx, offset failure
		mov	ax, 0900h
		int	21h

		ret

DisplayFailure	endp


	end	main

