* CONSUME.S
* Steven Frank / Vision of Epsilon
* $VER: consume v1.0 (24.04.93)
*
* Shows how to set up an input handler that consumes (mm, delicious) all 
* keyboard and mouse activity.  Hit left mouse button to unlock everything.

; -------------------------------------------------------------------------

		incdir	'df0:include/'
		include	'exec/io.i'
		include	'exec/exec_lib.i'
		include	'devices/input.i'
		include	'devices/inputevent.i'
		include	'libraries/dosextens.i'
		include	'libraries/dos_lib.i'

NULL		equ	0

CALLSYS		MACRO
		movea.l	(4).w,a6
		jsr	_LVO\1(a6)
		ENDM

; -------------------------------------------------------------------------
; This first hunk, handily based on the ProTracker Source, will run the next  
; code hunk in the background and release the CLI for other uses.             

		section	RunBackHunk,CODE

rb_HunkStart:	suba.l	a1,a1			; a1 = 0 = find our task
		CALLSYS	FindTask		; Find our task/process
		move.l	d0,a4			; process in a4
		moveq.l	#0,d0			; no WB msg ptr
		tst.l	pr_CLI(a4)		; are we called from CLI?
		bne.s	CalledFromCLI		; yes, do other stuff
		lea	pr_MsgPort(a4),a0	; running from wb, otherwise
		CALLSYS	WaitPort		; wait for the WB msg
		lea	pr_MsgPort(a4),a0	;
		CALLSYS	GetMsg			; get the WB msg
		
CalledFromCLI:	move.l	d0,d7			; d7 = WB msg
		lea	DOSLib,a1		; 'dos.library'
		moveq.l	#0,d0			; and ol' version
		CALLSYS	OpenLibrary		; open it
		tst.l	d0			; did we get it?
		beq.s	QuickExit		; I sure hope so!!
		move.l	d0,_DOSBase		; save dosbase ptr

		CALLSYS	Forbid			; stop multitasking for a sec
		move.l	#ProgName,d1		; ptr to the name of the prog
		moveq.l	#0,d2			; zero out d2
		move.b	LN_PRI(a4),d2		; priority
		lea	rb_HunkStart-4(pc),a0	; get ptr to next hunk
		move.l	(a0),d3			; ptr to next segment
		clr.l	(a0)			; unlink segment
		move.l	#4000,d4		; stack size
		CALLDOS	CreateProc		; spawn the process
		CALLSYS	Permit			; multitasking on

QuickExit:	tst.l	d7			; is there a WB msg?
		beq.b	RBExit			; no, skip this part
		CALLSYS	Forbid			; yes, multitask off
		move.l	d7,a1			; move msg ptr to a1
		CALLSYS	ReplyMsg		; reply to the message
RBExit:		moveq.l	#0,d0			; result code = 0
		rts				; program returns to DOS here
		
; -------------------------------------------------------------------------

		section	Main,CODE
		
MainStart:	bra.w	OpenAll			; open everything we need

main:		tst.b	Exit			; are we done?
		beq.b	main			; no, so repeat

		bra.w	CloseAll		; clean up everything
		
; -------------------------------------------------------------------------

InputHandler:	movem.l	d1-d7/a0-a6,-(sp)

		move.l	a0,a1			; save ptr to first event
ih_Start:	cmpi.b	#IECLASS_RAWKEY,ie_Class(a0)
		bne.b	NotAKey			; it was not a rawkey event

		move.b	#IECLASS_NULL,ie_Class(a0)
		bra.b	Next			; look for next event

NotAKey:	cmpi.b	#IECLASS_RAWMOUSE,ie_Class(a0)
		bne.b	Next			; not a mouse event

		move.b	#IECLASS_NULL,ie_Class(a0)

		cmpi.w	#IECODE_LBUTTON,ie_Code(a0)
		bne.b	Next

		st.b	Exit		

Next:		move.l	(a0),a0			; get ptr to next event
		cmp.l	#NULL,a0		; is there a next event?
		bne.b	ih_Start		; yes, loop again
		move.l	a1,d0			; pass ptr to first event
		movem.l	(sp)+,d1-d7/a0-a6	;   in list to next handler
		rts				; end of interrupt

; -------------------------------------------------------------------------

OpenAll:	suba.l	a1,a1			; a1 = 0 = find our task
		CALLSYS	FindTask		; do it
		lea	InputPort,a1		; reply port for input device
		move.l	d0,MP_SIGTASK(a1)	; signal us when msg received
		CALLSYS	AddPort			; add the port to the system
		
		lea	InputDevName,a0		; 'input.device'
		lea	InputIOReq,a1		; IOStdReq structure for it
		move.l	#InputPort,MN_REPLYPORT(a1)
		moveq.l	#0,d0			; unit number (n/a)
		moveq.l	#0,d1			; flags (n/a)
		CALLSYS	OpenDevice		; try to open input.device
		tst.l	d0			; got it?
		beq.b	NoError			; yes, all is well
		moveq.l	#1,d0			; d0 = 1 = device error
		bra.w	Error			; shut down
NoError:
		lea	InputIOReq,a1		; input.device io request
		move.w	#IND_ADDHANDLER,IO_COMMAND(a1)
		move.l	#InputInterrupt,IO_DATA(a1)
		CALLSYS	DoIO			; install my input handler
				
		bra.w	main			; resume with main program

; -------------------------------------------------------------------------

CloseAll:	cmp.l	#1,d0			; an opendevice error?
		beq.b	DeviceError		; yep

		lea	InputIOReq,a1		
		move.w	#IND_REMHANDLER,IO_COMMAND(a1)
		move.l	#InputInterrupt,IO_DATA(a1)
		CALLSYS	DoIO			; remove my input handler
		lea	InputIOReq,a1		
		CALLSYS	CloseDevice		; close the input.device

DeviceError:	lea	InputPort,a1		; ptr to the msgport
		CALLSYS	RemPort			; uninstall it

ca_1:		CALLSYS	Forbid
		lea	MainStart-4(pc),a0	; ptr to start of process code
		move.l	a0,d1			; move to d1
		lsr.l	#2,d1			; BCPL! Acckk!
		CALLDOS	UnLoadSeg		; free memory used by process
		move.l	_DOSBase,a1
		CALLSYS	CloseLibrary		; close dos.library
		CALLSYS	Permit
		rts				; exit the program

; -------------------------------------------------------------------------
; Now HERE'S a happy little subroutine.

Error:		moveq.l	#-1,d0			; repeat 65000+ times
e_Loop:		move.w	#$f00,$dff180		; flash screen red
		dbra	d0,e_Loop		; repeat
		bra.w	CloseAll		; shut ourself down

; -------------------------------------------------------------------------

		section	TheData,DATA

Version:	dc.b	'$VER: consume v1.0 (24.04.93)',0
ProgName:	dc.b	'Consume!',0
DOSLib:		dc.b	'dos.library',0
InputDevName:	dc.b	'input.device',0
		even

InputInterrupt:	dc.l	NULL,NULL
		dc.b	NT_INTERRUPT,52		
		dc.l	InputInterruptName,NULL,InputHandler
InputInterruptName:
		dc.b	'Consume.Int',0
		even

; -------------------------------------------------------------------------

		section	TheBSS,BSS

_DOSBase:	ds.l	1
InputIOReq:	ds.b	IOSTD_SIZE
InputPort:	ds.b	MP_SIZE
Exit:		ds.b	1
		even

; -------------------------------------------------------------------------

