;  EXAMPLE.ASM written 09/15/86 by Martin Murray
;		modified 10/01/87 by Martin Murray for PW2

;*******************************************************************************
;*      THIS CODE IS IN NO WAY COPYRIGHT BY INOVATRONICS, INC.  IN FACT, YOU   *
;*      CAN DO ANYTHING WITH IT THAT YOU WANT TO DO.  JUST REMEMBER,           *
;*      INOVATRONICS, INC. WILL BEAR ABSOLUTELY NO RESPONSIBILITY FOR THE USE, *
;*      MISUSE, INABILITY TO USE OR INABLITY TO UNDERSTAND ANY OR ALL PARTS OF *
;*      THIS CODE.  ENJOY IT IN GOOD HEALTH.                                   *
;*******************************************************************************
;*******************************************************************************
;*      THE PURPOSE OF THE CODE IS TO LET YOU SEE WHAT YOUR PowerWindows2      *
;*      GENERATED SOURCE CODE WILL LOOK LIKE IN A PROGRAM.  IN MOST CASES, ALL *
;*      YOU SHOULD HAVE TO DO IS ASSEMBLE THIS FILE.  IT WILL  AUTOMATICALLY   *
;*      INCLUDE YOUR SOURCE FILE, PROVIDED IT IS IN THE DEFAULT DIRECTORY, AND *
;*      IS NAMED "example.i".  JUST ASSEMBLE IT, LINK IT AND RUN IT.  IT       *
;*      DEFAULTS TO TERMINATING WHEN THE CLOSE GADGET IS HIT, BUT IF YOU LOOK  *
;*      BELOW YOU'LL SEE HOW TO MAKE IT TERMINATE ON ANY EVENT AT ALL.         *
;*      PLEASE NOTE: IT IS DESIGNED FOR ONLY 1 WINDOW.  IT WILL LOAD A SCREEN  *
;*      AND A PALETTE IF THEY ARE PRESENT, BUT ONLY WINDOW NUMBER 1 AND ITS    *
;*      PROGENY.                                                               *
;*******************************************************************************

	include	"exec/types.i"
	include	"exec/io.i"
	include	"exec/strings.i"
	include	"libraries/dosextens.i"
	include	"intuition/intuition.i"

	xref	_AbsExecBase

;************   EQUATES
NULL	equ	0

;************   MACROS
xlib	macro
	xref	_LVO\1
	endm

callsys   macro   (routine name to call, A6 must have base pointer of library)
	xlib	\1
	CALLLIB	_LVO\1
	endm

call	macro	(address to call)
	bsr	\1
	endm

push	macro	(long ea to push)
	move.l	\1,-(sp)
	endm

pull	macro	(long ea to fetch without popping)
	move.l	(sp),\1
	endm

pop	macro	(long ea to pop into)
	move.l	(sp)+,\1
	endm


;*********   DATA AREA
	DATA
	include "example.i"		;include the PowerWindows code
Intuitionname:	string <'intuition.library'>
InitialSP:	dc.l	0
MeMyselfandI:	dc.l	0
ReturnMsg:	dc.l	0
_IntuitionBase:	dc.l	0
CurrentWindow:	dc.l	0
	ifd NewScreenStructure
CurrentScreen:	dc.l	0
	ifd Palette
_GFXBase:	dc.l	0
Graphicsname:	string <'graphics.library'>
	endc
	endc

;************   PROGRAM START
	CODE
;Intitialize by saving the stack pointer and finding our own task.
	move.l	sp,InitialSP		;save the stack pointer
	move.l	_AbsExecBase,a6		;get the system library address
	sub.l	a1,a1
	callsys	FindTask		;please, I must find myself
	move.l	d0,MeMyselfandI		;save the address of the TCB list node
	move.l	d0,a0			;  in case we need it for some reason
	tst.l	PR_CLI(a0)		;were we run by Workbench?
	bne.s	1$			;no-jump
	lea	PR_MSGPORT(a0),a0	;wait for the startup message
	push	a0
	callsys	WaitPort
	pop	a0			;get it
	callsys	GetMsg
	move.l	d0,ReturnMsg		;save the message
1$:
	moveq	#0,d0			;open intuition.library
	lea	Intuitionname,a1
	callsys	OpenLibrary
	move.l	d0,_IntuitionBase	;save her address
	beq	FatalExit		;quit NOW if no Intuition
;open Graphics Library if anything wants it
	ifd _GFXBase
	moveq	#0,d0			;open the Graphics Library
	lea	Graphicsname,a1
	callsys	OpenLibrary
	move.l	d0,_GFXBase		;save the base pointer
	beq	GraphicsError		;leave if library not opened
	endc

main:
	move.l	_IntuitionBase,a6	;A6 gets the pointer to Intuition

;open the screen and load the palette, if appropriate
	ifd NewScreenStructure
	lea	NewScreenStructure,a0	;try to open the screen
	callsys	OpenScreen
	move.l	d0,CurrentScreen	;save the Screen structure address
	beq	BigProblem		;woops! if screen didn't open, leave NOW
	ifd Palette
	move.l	d0,a0			;give the Screen pointer to A0
	lea	SC_VIEWPORT(a0),a0	;point to the ViewPort structure INSIDE
					;  the Screen structure
	lea	Palette,a1		;point to the Palette and get the color
	moveq	#PaletteColorCount,d0	;  count in D0
	move.l	_GFXBase,a6		;this next call goes through Graphics
	callsys	LoadRGB4
	move.l	_IntuitionBase,a6	;A6 gets the pointer to Intuition again
	endc
	endc

;do the opening of the window, et all.
	lea	NewWindowStructure1,a0	;point to the NewWindow structure
	ifd NewScreenStructure
	move.l	CurrentScreen,NW_SCREEN(a0)	;save the screen pointer
	endc
	callsys	OpenWindow		;open the window (gadgets will come up
	move.l	d0,CurrentWindow	;  too.)
	beq	Exit			;leave if couldn't open window

;attach the menu if present
	ifd MenuList1
	move.l	d0,a0			;window address to A0
	lea	MenuList1,a1		;menustrip pointed to by A1
	callsys	SetMenuStrip
	endc

;draw the IntuiText only if there is some
	ifd IntuiTextList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	WD_RPORT(a0),a0
	lea	IntuiTextList1,a1	;print this list of IText structures
	moveq	#0,d0			;let the text position itself
	move.l	d0,d1
	callsys	PrintIText
	endc

;draw the Borders only if there are some of them
	ifd BorderList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	WD_RPORT(a0),a0
	lea	BorderList1,a1		;draw this list of Border structures
	moveq	#0,d0			;let the borders position themselves
	move.l	d0,d1
	callsys	DrawBorder
	endc

;draw the Images only if there are some of them
	ifd ImageList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	WD_RPORT(a0),a0
	lea	ImageList1,a1		;draw this list of Image structures
	moveq	#0,d0			;let the images position themselves
	move.l	d0,d1
	callsys	DrawImage
	endc

;do the Requester if Required
	ifd RequesterStructure2
	lea	RequesterStructure2,a0	;point to the Requester structure
	move.l	CurrentWindow,a1	;put it in this window
	callsys	Request
	endc

;now wait for the event we should terminate at.
Execloop:
	move.l	_AbsExecBase,a6		;point to the system again
loop:
	move.l	CurrentWindow,a0	;get the IDCMP port address and Wait on
	move.l	WD_USERPORT(a0),a0	;  it
	push	a0			;save the port address
	callsys	WaitPort
	pop	a0			;get the message
	callsys	GetMsg
	move.l	d0,a1			;message address to A1
	ifd HandleEvent
	move.w	IM_CODE(a1),d2		;grab the potential MENUNUM
	move.l	IM_IADDRESS(a1),d3	;grab the potential Gadget address
	endc
	move.l	IM_CLASS(a1),d4		;save the event class in D4
	callsys	ReplyMsg		;reply the message

	ifd HandleEvent
	cmp.l	#GADGETUP,d4		;let the event handler do any special
	beq	DoGadgetEvent		;  code
	cmp.l	#GADGETDOWN,d4
	beq	DoGadgetEvent
	ifd MenuList1
	cmp.l	#MENUPICK,d4		;if menu, let that code work
	beq	DoMenuEvent
	endc
	endc

;termination test -- change it to any other IDCMP event, just be sure that your
;  IDCMP flags are set properly
	cmp.l	#CLOSEWINDOW,d4		;should we terminate now?
	bne	loop			;loop if not

quit:
	move.l	_IntuitionBase,a6	;be sure to do next through Intuition

;detach the menu if present
	ifd MenuList1
	move.l	CurrentWindow,a0	;window address to A0
	callsys	ClearMenuStrip
	endc

	move.l	CurrentWindow,a0	;close the window
	callsys	CloseWindow

;************   PROGRAM EXIT
Exit:
	ifd NewScreenStructure
	move.l	CurrentScreen,a0	;close the screen
	callsys	CloseScreen
	endc
BigProblem:
	move.l	_AbsExecBase,a6
	ifd _GFXBase
	move.l	_GFXBase,a1		;close Graphics if it is real
	callsys	CloseLibrary
	endc
GraphicsError:
	move.l	_IntuitionBase,a1	;close Intuition
	callsys	CloseLibrary
FatalExit:
	move.l	ReturnMsg,d0		;reply to any WorkBench message
	beq.s	1$			;jump if none
	move.l	a1,d0			;point with this here register
	callsys	ReplyMsg		;Reply the message
1$:
	moveq	#0,d0			;no error code returned
	move.l	InitialSP,sp		;return to the caller
	rts


;******************************	 SUBROUTINES   ******************************
	ifd HandleEvent

DoGadgetEvent:
	move.l	_IntuitionBase,a6	;be sure to do next through Intuition
	move.l	d3,d0			;send the gadget address in D0
	jsr	HandleEvent		;it comes back in D0, so just go!
	bra	Execloop		;go back to get ExecBase again

	ifd MenuList1
DoMenuEvent:
	move.l	_IntuitionBase,a6	;be sure to do next through Intuition
	moveq	#0,d0			;ask Intuition for the MenuItem address
	move.w	d2,d0			;send the MENUNUM
	lea	MenuList1,a0		;send the menu address
	callsys	ItemAddress
	jsr	HandleEvent		;it comes back in D0, so just go!
	bra	Execloop		;go back to get ExecBase again
	endc

	endc

	end
