;  Breakout Box V1.0
;	Displays a little window which shows the status of the serial
;	port bits:  Clear to Send (CTS), Ready to Send (RTS), Carrier
;	Detect (CD), Data Set Ready (DSR), Data Terminal Ready (DTR).
;	The program runs constantly, updating the display 5 times per
;	second.  It also monitors for a Close-gadget message from
;	intuition.
;
;	To execute:  From CLI,		BRBOX or RUN BRBOX or RUNBACK BRBOX
;		     From WorkBench,	just double-click the icon
;
;	The monitor window has a drag bar hidden under the status
;	indicators, which means you can move it around on the WorkBench
;	window and get it out of your way.
;
;
****************************************************************************
*
*                   INCLUDE FILES
*
****************************************************************************

	NOLIST					; don't list included files
	INCLUDE	"exec/types.i"			; for following includes
	INCLUDE	"exec/alerts.i"			; to access ALERT macro
	INCLUDE "exec/ports.i"			; to access message structure
	INCLUDE	"libraries/dosextens.i"		; to access process structure
	INCLUDE	"intuition/intuition.i"		; to access intuition structures

****************************************************************************
*
*              External References
*
****************************************************************************

	XREF	_AbsExecBase

	XREF	_LVOAlert
	XREF	_LVOCloseLibrary
	XREF	_LVOCloseWindow
	XREF	_LVODelay
	XREF	_LVOFindTask
	XREF	_LVOForbid
	XREF	_LVOGetMsg
	XREF	_LVOOpenLibrary
	XREF	_LVOOpenWindow
	XREF	_LVOPrintIText
	XREF	_LVOReplyMsg
	XREF	_LVOWaitPort
	XREF	_LVOWrite

	LIST					; turn on program listing


***************************************************************************
*
*                         Program Startup Code
*
***************************************************************************

Begin:
	move.l		#0,returnMsg		; zap return message hold
	move.l		sp,initialSP		; initial task stack pointer
	movea.l		_AbsExecBase,a6		; get exec base
	move.l		a6,ExecBase		; save it off somewhere close
	bsr		openDOS			; attempt to open DOS library
	bsr		openINT			; open Intuition library

	suba.l		a1,a1			; zero task name pointer
	jsr		_LVOFindTask(a6)	; get the address of this task
	movea.l		d0,a4			; task address in a4

	tst.l		pr_CLI(a4)		; are we running in WB?
	bne		DoMain			; no, skip WB-specific stuff

	
***************************************************************************
*
*                  Workbench Startup Code
*
***************************************************************************

	bsr		waitmsg			; wait for start message
	move.l		d0,returnMsg		; save message for later

***************************************************************************
*
*                      Main Program
*
***************************************************************************
DoMain:
	bsr		DrawWind		; draw display window
check:
	move.b		$BFD000,d3		; grab CIAB data reg. 1 contents
	lea		IText1,a1		; get address of IntuiText 1
chkbit:
	move.l		a1,d0			; is the address in a1 0?
	beq		outofit			; yes, end of loop
	moveq		#3,d0			; put a color 3 into d0
	moveq		#0,d2			; put a 0 into d2
	asl.b		#1,d3			; push top bit into Xtend flag
	subx.b		d2,d0			; sub d2(0) and X bit from d2(3)
	move.b		d0,it_FrontPen(a1)	; make foreground pen 2 or 3
	movea.l		it_NextText(a1),a1	; get address of next IntuiText
	bra		chkbit			; now check again
outofit:
	movea.l		windptr,a0		; grab window pointer
	movea.l		wd_RPort(a0),a0		; get the RasterPort of window
	lea		IText1,a1		; snatch up the IText struct
	moveq.l		#0,d0			; set up left offset
	moveq.l		#0,d1			; ditto for top offset
	movea.l		IntBase,a6		; grab base of intuition lib.
	jsr		_LVOPrintIText(a6)	; print the texts
	movea.l		windptr,a0		; grab window pointer
	movea.l		wd_UserPort(a0),a0	; get UserPort from window
	movea.l		ExecBase,a6		; get Execbase
	jsr		_LVOGetMsg(a6)		; grab any messages pending
	tst.l		d0			; was there anything?
	beq		endloop			; no, just do it again
	movea.l		d0,a1			; message waiting: set up...
	move.l		im_Class(a1),d4		; to reply to it
	move.w		im_Code(a1),d5		; 
	movea.l		im_IAddress(a1),a2	;
	jsr		_LVOReplyMsg(a6)	; reply to message
	cmpi.l		#CLOSEWINDOW,d4		; was the message CLOSEWINDOW?
	beq		bye			; yep, we gotta go now!
endloop:					; no CLOSEWINDOW message, loop!
	movea.l		DOSBase,a6		; DOS pointer
	move.l		#10,d1			; 10 20 ms clock ticks delay
	jsr		_LVODelay(a6)		; delay 1/5 second
	bra		check			; and check again
;
; termination code
;
bye	movea.l		IntBase,a6		; get intuition library base
	movea.l		windptr,a0		; set up to close the window
	jsr		_LVOCloseWindow(a6)	; shut that window!
	moveq.l		#0,d0			; sucess return code for CLI

exit
	movea.l		initialSP,sp		; restore stack pointer
	move.l		d0,-(sp)		; push return code
	movea.l		ExecBase,a6		; use exec library pointer
	move.l		DOSBase,d0		; get dos.library pointer
	beq.s		1$			; skip close if DOS.lib not open
	movea.l		d0,a1			; move lib base into a1
	jsr		_LVOCloseLibrary(a6)	; close dos.library
1$
	move.l		IntBase,d0		; now grab intuition.library ptr
	beq.s		2$			; zero, so no need to close
	movea.l		d0,a1			; put it where we can use it
	jsr		_LVOCloseLibrary(a6)	; close intuition.library
2$
	move.l		returnMsg,d0		; grab returnMsg
	beq.s		3$			; if zero, no need to return msg
	jsr		_LVOForbid(a6)		; so WB won't UnloadSeg us
	movea.l		returnMsg,a1		; startup message
	jsr		_LVOReplyMsg(a6)	; many happy returns!
3$
	move.l		(sp)+,d0		; pop result code from stack
	rts					; this oughta take us home

*************************END OF NORMAL PROCESSING***************************
*
*			There be subroutines here! 
*
****************************************************************************
* This routine gets the message that Workbench will send to us
*	- Called with task id in a4
waitmsg
	lea		pr_MsgPort(a4),a0	; our process base
	jsr		_LVOWaitPort(a6)	; wait for a message
	lea		pr_MsgPort(a4),a0	; same old process base
	jsr		_LVOGetMsg(a6)		; get the message
	rts
****************************************************************************
* This routine draws the little monitor window.
*
DrawWind
	movea.l		IntBase,a6		; get Intuition base
	lea		NewWind,a0		; point to NewWindow struct
	jsr		_LVOOpenWindow(a6)	; open the puppy
	move.l		d0,windptr		; save the window pointer
	rts
****************************************************************************
* This routine opens the dos.library and saves its base pointer
*
openDOS
	lea		DOS_Lib,a1		; grab dos.library name
	move.l		#LIBRARY_VERSION,d0	; get library version
	jsr		_LVOOpenLibrary(a6)	; open dos.library
	move.l		d0,DOSBase		; save dos base
	beq		noDOS			; no dos.library, ALERT!
	rts					; everything's cool.
****************************************************************************
* Open the intuition.library and save its base pointer
*
openINT
	lea		INT_Lib,a1		; grab intuition.library name
	moveq.l		#0,d0			; version is irrelevant
	jsr		_LVOOpenLibrary(a6)	; open the library
	move.l		d0,IntBase		; save the base
	rts
****************************************************************************
* noDOS:  not no-DOZE, No-DOS!
*
noDOS:
	ALERT		(AG_OpenLib!AO_DOSLib)	; this wasn't my idea!
	move.l		#100,d0			; make like a hockey player &
	bra		exit			; get the puck out of here

****************************************************************************
*
*		Program's DATA area
*
****************************************************************************

		CNOP	0,2			; even-out to word boundary
	
ExecBase	DC.L	0
DOSBase		DC.L	0
IntBase		DC.L	0

initialSP	DC.L	0
returnMsg	DC.L	0

windptr		DC.L	0

NewWind		EQU	*
LeftEdge	DC.W	0
TopEdge		DC.W	0
Width		DC.W	276
Height		DC.W	10
DetailPen	DC.B	-1		; default forground
BlockPen	DC.B	-1		; default background
IDCMPFlags	DC.L	CLOSEWINDOW
Flags		DC.L	WINDOWCLOSE!SMART_REFRESH!WINDOWDRAG!WINDOWDEPTH
FirstGadget	DC.L	0
CheckMark	DC.L	0
Title		DC.L	wtitle
Scren		DC.L	0
BitMp		DC.L	0
MinWidth	DC.W	0
MinHeight	DC.W	0
MaxWidth	DC.W	0
MaxHeight	DC.W	0
Type		DC.W	WBENCHSCREEN
*	end of NewWindow structure

IText1		EQU	*			; IntuiText structure
		DC.B	3			; foreground pen
		DC.B	1			; background pen
		DC.B	RP_JAM2			; JAM2 drawing mode
		DC.W	30			; left edge offset
		DC.W	1			; top edge offset
		DC.L	0			; font structure pointer (def)
		DC.L	text1			; pointer to text
		DC.L	IText2			; pointer to next IntuiText

IText2		EQU	*			; IntuiText structure
		DC.B	2			; foreground pen
		DC.B	1			; background pen
		DC.B	RP_JAM2			; JAM2 drawing mode
		DC.W	70			; left edge offset
		DC.W	1			; top edge offset
		DC.L	0			; font structure pointer (def)
		DC.L	text2			; pointer to text
		DC.L	IText3			; pointer to next IntuiText

IText3		EQU	*			; IntuiText structure
		DC.B	2			; foreground pen
		DC.B	1			; background pen
		DC.B	RP_JAM2			; JAM2 drawing mode
		DC.W	110			; left edge offset
		DC.W	1			; top edge offset
		DC.L	0			; font structure pointer (def)
		DC.L	text3			; pointer to text
		DC.L	IText4			; pointer to next IntuiText

IText4		EQU	*			; IntuiText structure
		DC.B	2			; foreground pen
		DC.B	1			; background pen
		DC.B	RP_JAM2			; JAM2 drawing mode
		DC.W	140			; left edge offset
		DC.W	1			; top edge offset
		DC.L	0			; font structure pointer (def)
		DC.L	text4			; pointer to text
		DC.L	IText5			; pointer to next IntuiText

IText5		EQU	*			; IntuiText structure
		DC.B	2			; foreground pen
		DC.B	1			; background pen
		DC.B	RP_JAM2			; JAM2 drawing mode
		DC.W	180			; left edge offset
		DC.W	1			; top edge offset
		DC.L	0			; font structure pointer (def)
		DC.L	text5			; pointer to text
		DC.L	0			; pointer to next IntuiText

wtitle		DC.B	'Breakout Box V1.0',0
text1		DC.B	' DTR ',0
text2		DC.B	' RTS ',0
text3		DC.B	' CD ',0
text4		DC.B	' CTS ',0
text5		DC.B	' DSR ',0
INT_Lib		DC.B	'intuition.library',0
DOS_Lib		DC.B	'dos.library',0

		END
