//----------------------------------------------------------------
//	trymouse.s
//
//	This program calls ROM-BIOS services that enable the PS/2
//	mouse to generate interrupts whenever the mouse is moved,
//	and when one of the mouse-buttons is pressed or released.
//
//	 to assemble:  $ as trymouse.s -o trymouse.o
//	 and to link:  $ ld trymouse.o -T ldscript -o trymouse.b
//	 and install:  $ dd if=trymouse.b of=/dev/sda4 seek=1
//
//	NOTE: This code begins executing with CS:IP = 1000:0002.
//
//	programmer: ALLAN CRUSE
//	written on: 09 APR 2008
//----------------------------------------------------------------


	.section	.text
#-----------------------------------------------------------------
	.word		0xABCD		# programming 'signature'
#-----------------------------------------------------------------
main:	.code16				# executes in 'real-mode' 

	mov	%sp, %cs:ldrtos+0	# save loader's SP-value
	mov	%ss, %cs:ldrtos+2	# save loader's SS-value

	mov	%cs, %ax		# address program's data
	mov	%ax, %ss		#  with the SS register
	lea	tos, %sp		# establish new stacktop

	call	exec_our_ps2_demo

	lss	%cs:ldrtos, %sp		# recover loader's stack
	lret				# for a return to loader
#-----------------------------------------------------------------
ldrtos:	.word	0, 0			# to store stack-address
#-----------------------------------------------------------------
#=================================================================
#-----------------------------------------------------------------
vgaptr: .word	(80*8+0)*2, 0xB800	# pointer to vram window
#-----------------------------------------------------------------
isrPS2:	# Here is our 'event-handler' for any type of mouse-event
	pusha
	push	%es

	cld				# do forward processing
	les	%ss:vgaptr, %di		# point ES:DI to window
	mov	$0x2F4D, %ax		# setup character/color
	stosw				# write character/color
	mov	%di, %ss:vgaptr		# update window-pointer

	pop	%es
	popa
	lret
#-----------------------------------------------------------------
#-----------------------------------------------------------------
exec_our_ps2_demo:

	# reset the pointing device 
	mov	$0xC201, %ax		# reset pointing device
	int	$0x15			# invoke ROM-BIOS service
	call	ax2hex			# draw diagnostic status

	# install our 'mouse-event' handler, for ROM-BIOS to call
	mov	%cs, %ax		# address our subroutine
	mov	%ax, %es		#    using ES register
	lea	isrPS2, %bx		# point ES:BX to handler
	mov	$0xC207, %ax		# install mouse-handler
	int	$0x15			# invoke ROM-BIOS service
	call	ax2hex			# draw diagnostic status

	# enable the pointing device
	mov	$0xC200, %ax		# enable/disable device
	mov	$1, %bh			# select 'enable' option
	int	$0x15			# invoke ROM-BIOS service
	call	ax2hex			# draw diagnostic status

	# await keypress (while a user tries moving the mouse)	
	xor	%ah, %ah		# get_keyboard_data
	int	$0x16			# invoke ROM-BIOS service

	# disable the pointing device 
	mov	$0xC200, %ax		# enable/disable mouse
	mov	$0, %bh			# select 'disable' option
	int	$0x15			# invoke ROM-BIOS service
	call	ax2hex			# draw diagnostic status

	ret
#-----------------------------------------------------------------
hex:	.ascii	"0123456789ABCDEF"	# array of the hex digits
#-----------------------------------------------------------------
ax2hex:	# draws value of AX into the current video-memory window
	
	mov	%ax, %dx		# copy accumulator to DX
	mov	$0x6E, %ah		# setup color attribute
	les	%ss:vgaptr, %di		# point ES:DI to window
	cld				# do forward processing
	mov	$4, %cx			# count of nybbles in DX 	
nxnyb:	rol	$4, %dx			# get next nybble into DL	
	mov	%dl, %bl		# and copy nybble into BL
	and	$0xF, %bx		# isolate nybble's bits
	mov	%ss:hex(%bx), %al	# lookup nybble's numeral
	stosw				# write character w/color
	loop	nxnyb			# process other nybbles

	mov	$' ', %al		# use blank as separator
	stosw				# write a blank character
	mov	%di, %ss:vgaptr		# update window pointer

	ret
#-----------------------------------------------------------------
#-----------------------------------------------------------------
	.align				# insure stack alignment
	.space	256			# reserved for stack use
tos:					# label for top-of-stack
#-----------------------------------------------------------------
	.end				# no more to be assembled