;
; ### Mouse v 1.25 ###
;
; - Created 881021 by TM -
;
;
; NOTES:
;
;
; BUGS:
;
; - None, I hope
;
;
; Edited:
;
; - 881217 by TM -> v0.60	- Code compressed from 1408 to 900 bytes.
; - 881217 by JM -> v0.80	- Code compressed from 900 to 724 bytes.
; - 881217 by JM -> v1.00	- Code commented and compressed to 720 bytes.
; - 881224 by JM -> v1.10	- Some structure offsets changed to labels.
;				- Executable now 716 bytes.
; - 881224 by JM -> v1.15	- Crunching, version id added.
;				  Executable 688 bytes only.
; - 881225 by JM -> v1.20	- A bug fixed with NEWLIST macro.  Executable
;				  692 bytes.
; - 881227 by JM -> v1.25	- LN_PRI and LN_NAME set to NULL.  Executable
;				  700 bytes.
;
;

		include	"jmplibs.i"
		include	"exec/types.i"
		include	"exec/nodes.i"
		include	"exec/lists.i"
		include	"exec/ports.i"
		include	"exec/io.i"
		include	"devices/input.i"
		include	"com.i"
		include	"exec.xref"
		include	"dos.xref"
		include	"relative.i"
		include	"string.i"
		include	"intuition.xref"

RELATIVE 	equ	-1			allocates memory from stack


*
* Variables allocated from stack:
*

		.var
		dl	_DosBase,_IntuitionBase
		dl	cmdbuf
		dl	ODerror,ASerror
		dw	mouseport
		da	iorequest,48
		da	msgport,34
		da	prefs,128


start		.begin
		move.l	a0,cmdbuf(a4)		start of command line buffer
		clr.b	-1(a0,d0.w)

		openlib	Dos,clean		open libraries
		openlib	Intuition,clean

		lea	prefs(a4),a0		get current Preferences settings
		moveq	#116,d0
		lib	Intuition,GetPrefs

		move.l	cmdbuf(a4),a5		check if info needed
		move.b	(a5),d0
		cmp.b	#'?',d0			'?' -> print usage
		beq	info
		tst.b	d0
		bne.s	mowlawn			command not empty -> jump

		lea	tcmsi(pc),a0		if cmdline is empty...
		lea	prefs(a4),a1		...output current mouse speed
		move.w	108(a1),d0		current speed from Preferences
		cmp.w	#9,d0
		bhi.s	msunkwn			more than 9 -> output other msg
		lea	speedy(pc),a1
		or.b	d0,(a1)			store speed into buffer
		bra.s	eclean			...and print string

msunkwn		lea	mt9(pc),a0		mouse is very slow!
		bra.s	eclean

mowlawn		bsr	skipblk			change settings
		move.b	(a5)+,d0
		beq	clean
		bsr	ucase
mowwell		cmp.b	#'0',d0			check if speed in allowed range
		blo.s	mow1
		cmp.b	#'9',d0
		bhi.s	mow1
		and.w	#15,d0			convert to binary
		lea	prefs(a4),a0
		move.w	d0,108(a0)		write new speed into structure
		moveq	#116,d0
		moveq	#-1,d1
		lib	Intuition,SetPrefs	set mouse speed
		addq.l	#1,a5
		bra.s	mowlawn

mow1		cmp.b	#'S',d0			S command
		bne.s	mow2
		bsr	skipblk
		move.b	(a5)+,d0
		beq.s	info
		bra.s	mowwell

mow2		cmp.b	#'P',d0			set port - P command
		bne.s	info
		bsr	skipblk
		move.b	(a5)+,d0
		sub.b	#'1',d0			check if port 1 or 2
		blo.s	info
		cmp.b	#1,d0
		bhi.s	info
		bsr	mport			set port in subrtn
		bra.s	mowlawn


info		lea	infotxt(pc),a0		print info text
eclean		printa	a0			print message
clean		closlib	Intuition		close libraries
		closlib	Dos
		moveq.l	#0,d0
		.end


skipblk		move.b	(a5)+,d0		skip blank (SPC/TAB)
		cmp.b	#' ',d0
		beq.s	skipblk
		cmp.b	#9,d0
		beq.s	skipblk
		subq.w	#1,a5
		rts

ucase		cmp.b	#'a',d0			convert a char to UPPER CASE
		blo.s	ucase1
		cmp.b	#'z',d0
		bhi.s	ucase1
		sub.b	#$20,d0
ucase1		rts


*
* This routine sets the mouse port. D0 must contain 0 or 1 for port
* 1 or 2, respectively.
*

mport		move.b	d0,mouseport(a4)
		lea	indevname(pc),a0	input.device
		moveq.l	#0,d0			unit#
		lea	iorequest(a4),a1	IoReq
		moveq.l	#0,d1			flags
		lib	Exec,OpenDevice		open input.device
		move.l	d0,ODerror(a4)		error -> ODerror != 0
		bne.s	mpclean			if error

		lea	msgport(a4),a2
		move.b	#NT_MSGPORT,LN_TYPE(a2)	node type = messageport
		clr.b	LN_PRI(a2)		priority = 0
		clr.l	LN_NAME(a2)		no name
		clr.b	MP_FLAGS(a2)		Flags = 0


		moveq.l	#-1,d0			get a signal bit
		move.l	d0,ASerror(a4)
		flib	Exec,AllocSignal
		move.l	d0,ASerror(a4)		signal bit number or error
		bmi.s	mpclean

		move.b	d0,MP_SIGBIT(a2)	set signal bit number

		sub.l	a1,a1
		flib	Exec,FindTask		find this task
		move.l	d0,MP_SIGTASK(a2)	set task pointer

		lea	MP_MSGLIST(a2),a0
		NEWLIST	a0			NewList(list) (macro)

		move.l	a2,d0
		lea	iorequest(a4),a2
		move.l	d0,MN_REPLYPORT(a2)	set reply port pointer

		move.w	#IND_SETMPORT,IO_COMMAND(a2) set io_Command
		lea	mouseport(a4),a0
		move.l	a0,IO_DATA(a2)		io_Data = &mouseport
		moveq.l	#1,d0
		move.l	d0,IO_LENGTH(a2)	io_Length = 1

		move.l	a2,a1
		flib	Exec,DoIO		set mouseport

mpclean		move.l	ODerror(a4),d0		test if input.device open
		bne.s	mpclea1			no -> don't try to close it
		lea	iorequest(a4),a1
		flib	Exec,CloseDevice	close input.device

mpclea1		move.l	ASerror(a4),d0		test if a signal allocated
		bmi.s	mpclea2			no -> don't try to free it
		flib	Exec,FreeSignal		free signal

mpclea2		rts



infotxt		dc.b	'Mouse v1.25',10
		dc.b	'Usage: mouse [P <port>] [[S] <speed>]',10,0
indevname	dc.b	'input.device',0
mt9		dc.b	'more than 9',10,0
tcmsi		dc.b	'The current mouse speed is '
speedy		dc.b	'0.',10,0


		libnames

		end

