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

; stamponit.s code example 

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

		include exec/memory.i
		include intuition/intuition.i
		include	libraries/dos.i
		include	libraries/asl.i
		include	libraries/gadtools.i
		include graphics/rastport.i
		include graphics/graphics_lib.i
		include	exec/exec_lib.i
		include	intuition/intuition_lib.i
		include	libraries/dos_lib.i
		include	libraries/asl_lib.i
		include	libraries/gadtools_lib.i

		XDEF	_main
	
		XREF	image	
		
NULL		EQU	   0

TRUE		EQU	   1

FALSE		EQU 	   0

PENCOLOUR	EQU	   1

SCREENCOLOUR	EQU	   2

SPECIFY		EQU	   0

DOSOMETHING	EQU	   1

QUIT		EQU	   2		

_AbsExecBase	EQU	   4

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

CALLSYS	MACRO
		LINKLIB	_LVO\1,\2
		ENDM

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

_main		movem.l	d3/a2-a3/a5,-(sp)		preserve registers
		move.l	_AbsExecBase,_SysBase		copy of exec library base
		lea	function_stack1,a5		for alloc/dealloc operations
		lea 	lib_names,a2
		lea 	lib_base_start,a3
		move.w	#LIBRARY_COUNT-1,d3		loop counter
.loop		movea.l	(a2)+,a1			library name pointer
		moveq	#0,d0				any version will do
		CALLSYS	OpenLibrary,_SysBase
		move.l	d0,(a3)+			store returned base
		dbeq	d3,.loop

		beq.s	lib_error_exit				
		
		; all libraries are open and available for use.
						
		jsr	LockScreen
		beq.s	closedown

		jsr	GetVisInfo
		beq.s	closedown	
		
		jsr	OpenWindow
		beq.s	closedown
		
		jsr	CreateMenu
		beq.s	closedown
		
		jsr	LayoutMenu
		beq.s	closedown

		jsr	InstallMenu
		beq.s	closedown		

		jsr	AllocFileReq
		beq.s	closedown

		; now everything is set up we call the event handler!

		movea.l	window_p,a1
		movea.l	wd_UserPort(a1),a2		user port address
		jsr	EventHandler			handle user actions

closedown	move.l	(a5)+,d0			retrieve function pointer
		beq.s	lib_normal_exit
		move.l	d0,a0
		jsr	(a0)				and execute routine if it exists!
		bra.s	closedown


lib_normal_exit	lea	lib_base_end,a3		
		moveq	#LIBRARY_COUNT,d2		library count
		jsr	CloseLibs			close libraries
		moveq	#0,d0				clear d0 for O/S
		movem.l	(sp)+,d3/a2-a3/a5		restore registers
		rts					and terminate program

lib_error_exit	moveq	#LIBRARY_COUNT-1,d2		
		sub	d3,d2
		jsr	CloseLibs			close libraries
		moveq	#0,d0				clear d0 for O/S
		movem.l	(sp)+,d3/a2-a3/a5		restore registers		
		rts					and terminate program

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

; CloseLibs() On entry...

; 	a3 should hold address of the longword location just past 
; 	   that of the first library to close (this is because the 
;	   routine uses a backward reading loop).

; 	d2 should hold count of the number of libraries to close

CloseLibs	tst.b	d2				test counter
		beq.s	.loop_end		
		movea.l	-(a3),a1			get library base
		CALLSYS	CloseLibrary,_SysBase
		subq.b	#1,d2
		bra.s	CloseLibs
.loop_end	rts

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

; LockScreen() and UnlkScreen() on entry... need no register parameters!


LockScreen	lea	workbench_name,a0		pointer to screen name
		CALLSYS	LockPubScreen,_IntuitionBase
		move.l	d0,workbench_p			save returned pointer
		beq.s	.error
		move.l	#UnlkScreen,-(a5)		push deallocation routine address
.error		rts

UnlkScreen	movea.w	#NULL,a0			screen name not needed
		movea.l	workbench_p,a1			screen to unlock
		CALLSYS	UnlockPubScreen,_IntuitionBase
		rts

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

; OpenWindow() and ShutWindow() on entry... need no register parameters!


OpenWindow	movea.w	#NULL,a0
		lea	window_tags,a1			start of tag list
		CALLSYS	OpenWindowTagList,_IntuitionBase
		move.l	d0,window_p			save returned pointer
		beq.s	.error
		move.l	#ShutWindow,-(a5)		push deallocation routine address

 		moveq	#SCREENCOLOUR,d0
		move.l	window_p,a1
		move.l	wd_RPort(a1),a1			window's rastport
		CALLSYS	SetRast,_GfxBase

		move.l	window_p,a0
		move.l	wd_RPort(a0),a0			window's rastport
		lea	image,a1
		moveq	#15,d0
		moveq	#20,d1
		CALLSYS DrawImage,_IntuitionBase

		move.l	window_p,a0		
		CALLSYS RefreshWindowFrame,_IntuitionBase			
		moveq	#1,d0				signify 'no error'
		
.error		rts

ShutWindow	movea.l	window_p,a0			window to close
		CALLSYS	CloseWindow,_IntuitionBase
		rts

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

; GetVisInfo() and FreeVisInfo() on entry... need no register parameters!


GetVisInfo	movea.l	workbench_p,a0		
		movea.w	#TAG_END,a1			no tags
		CALLSYS	GetVisualInfoA,_GadToolsBase
		move.l	d0,visual_info_p		save returned pointer
		beq.s	.error
		move.l	#FreeVisInfo,-(a5)		push deallocation routine address
.error		rts

FreeVisInfo	movea.l	visual_info_p,a0	
		CALLSYS	FreeVisualInfo,_GadToolsBase
		rts

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

; CreateMenu() and FreeMenu() on entry... need no register parameters!


CreateMenu	lea	menu,a0
		movea.w	#TAG_END,a1			no tags
		CALLSYS	CreateMenusA,_GadToolsBase
		move.l	d0,menu_p			save returned pointer
		beq.s	.error
		move.l	#FreeMenu,-(a5)			push deallocation routine address
.error		rts

FreeMenu	movea.l	menu_p,a0			menu to free
		CALLSYS	FreeMenus,_GadToolsBase
		rts

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

; LayoutMenu() on entry... needs no register parameters!


LayoutMenu	movea.l	menu_p,a0
		movea.l	visual_info_p,a1
		movea.w	#TAG_END,a2			no tags
		CALLSYS	LayoutMenusA,_GadToolsBase
		tst.l	d0				nothing to deallocate
		rts

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

; InstallMenu() and RemoveMenu() on entry... need no register parameters!


InstallMenu	movea.l	window_p,a0
		movea.l	menu_p,a1
		CALLSYS	SetMenuStrip,_IntuitionBase
		tst.l	d0
		beq.s	.error
		move.l	#RemoveMenu,-(a5)		push deallocation routine address
.error		rts

RemoveMenu	movea.l	window_p,a0			target window
		CALLSYS	ClearMenuStrip,_IntuitionBase
		rts
; ---------------------------------------------------------------------	

; AllocFileReq() and FreeFileReq() on entry... need no register parameters!


AllocFileReq	CALLSYS	AllocFileRequest,_AslBase
		move.l	d0,dir_request_p		save returned pointer
		beq.s	.error
		move.l	d0,a0
		lea	itext1,a1			install text pointer
		move.l	fr_Drawer(a0),it_IText(a1)		in itext1 structure
		lea	itext2,a1			install text pointer
		move.l	fr_Drawer(a0),it_IText(a1)		in itext2 structure
		move.l	#FreeFileReq,-(a5)		push deallocation routine address
.error		rts

FreeFileReq 	movea.l	dir_request_p,a0		requester to close
		CALLSYS	FreeFileRequest,_AslBase
		rts

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

; Function name:     EventHandler()

; Purpose:           Handles Intuition events

; Input Parameters:  Address of IDCMP user-port should be in a2. 

; Output parameters: None

; Register Usage:    a0: Used by WaitPort() and GetMsg()  
                     
;                    a1: Used by ReplyMsg()
                     
;                    a2: Holds user-port address

;                    d0: Used by WaitPort() and GetMsg()
                     
;                    d1: Unused but possibly altered by system functions

;                    d2: Used as an exit flag (quit when non-zero)

;		     d3: Used to hold message class field

;		     d4: Used to hold message code field


; Other Notes:       Within EventHandler() all registers are preserved

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

EventHandler	movem.l	d0-d4/a0-a2,-(a7)		preserve registers
		clr.l	d2				clear exit flag
EventHandler2	movea.l	a2,a0				port address  
		CALLSYS	WaitPort,_SysBase  
		jsr	GetMessage           
		cmpi.l	#TRUE,d2			exit flag set?
		bne.s	EventHandler2
		movem.l	(a7)+,d0-d4/a0-a2		restore registers
		rts					logical end of routine

; ---------------------------------------------------------------------
                     
GetMessage	movea.l	a2,a0				get port address in a0
		CALLSYS	GetMsg,_SysBase			get the message
		tst.l	d0
		beq.s	GetMessageExit			did it exist?
		movea.l	d0,a1				copy pointer to a1
		move.l	im_Class(a1),d3			copy message class
		move.w	im_Code(a1),d4			copy message code
		CALLSYS	ReplyMsg,_SysBase		then send message back

		cmpi.l	#IDCMP_CLOSEWINDOW,d3
		bne.s	MenuMessage
		moveq	#TRUE,d2			set QUIT signal to exit routine 
		bra.s	GetMessage
		
MenuMessage	cmpi.l	#IDCMP_MENUPICK,d3 		check message class
		bne.s	NotMenuMessage			some other message types

		cmpi.w	#MENUNULL,d4
		beq.s	GetMessage			ignore if MENUNULL
		lsr.w	#5,d4				extract menu item number
		andi.b	#$3F,d4				
		
		cmpi.b	#SPECIFY,d4
		beq.s	SpecifyDir
		
		cmpi.b	#QUIT,d4
		bne.s	GetMessage
		moveq	#TRUE,d2			set QUIT signal to exit routine 		
		bra.s	GetMessage			keep going
		
SpecifyDir	; jsr	DirHandler

		bra.s	GetMessage			check for more messages!

GetMessageExit	rts					d2 holds exit flag

NotMenuMessage	jsr SetDisplay				assume refresh

		bra.s	GetMessage
		
; ---------------------------------------------------------------------
; Function name:     DirHandler()

; Purpose:           Handles directory alterations

; Input Parameters:  None

; Output parameters: None

; Register Usage:    d0-d2/a0-a1/a5: Used by various system calls
  		     
; Other Notes:       All registers are preserved

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

DirHandler	movem.l	d0-d2/a0-a2/a5,-(a7)		preserve registers
;		lea	function_stack2,a5		for alloc/dealloc operations		
;		jsr	ClearName			removes if present
		movea.l	dir_request_p,a0		asl requester address
		lea	asl_tags,a1		
		CALLSYS	AslRequest,_AslBase		bring up the requester


;               jsr	PrintName

; 		jsr	LockDir
;		beq.s	.deallocate
;		jsr	AllocFib
;		beq.s   .deallocate
;		jsr	ExamineDir
;		beq.s	.deallocate
;		jsr	ExamineNext
				
;.deallocate	move.l	(a5)+,d0			retrieve function pointer
;		beq.s	.exit
;		move.l	d0,a0
;		jsr	(a0)				and execute routine if it exists!
;		bra.s	.deallocate
		           		
.exit		movem.l	(a7)+,d0-d2/a0-a2/a5		restore registers

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

LockDir		move.l	dir_request_p,a0
		move.l	fr_Drawer(a0),d1
		moveq	#ACCESS_READ,d2
		CALLSYS	Lock,_DOSBase
		move.l	d0,dirlock_p
		beq.s	.error
		move.l	#UnlockDir,-(a5)
.error		rts

UnlockDir	move.l	dirlock_p,d1
		CALLSYS	UnLock,_DOSBase
		rts		
; ---------------------------------------------------------------------

AllocFib	moveq	#DOS_FIB,d1			object type
		moveq	#NULL,d2			no tags
		CALLSYS	AllocDosObject,_DOSBase
		move.l	d0,fib_p			save pointer to fib
		beq.s	.error
		move.l	#FreeFib,-(a5)
.error		rts	
		
FreeFib		moveq	#DOS_FIB,d1			object type
		move.l	fib_p,d2		
		CALLSYS	FreeDosObject,_DOSBase
		rts
; ---------------------------------------------------------------------

ExamineDir	move.l	dirlock_p,d1
		move.l	fib_p,d2
		CALLSYS	Examine,_DOSBase
		tst.l	d0				zero if fails
		rts	
; ---------------------------------------------------------------------

ExamineNext	move.l	fib_p,d2
		move.l	d2,a2				copy in address reg
.loop		move.l	dirlock_p,d1
		CALLSYS	ExNext,_DOSBase			get details of this entry
		tst.l	d0
		beq.s	.exit				no more entries ?
		tst.l	fib_DirEntryType(a0)
		bpl.s	.loop				directory - so ignore
		
		;PROCESS THIS FILE
		
		bra.s	.loop				check for next
.exit		rts
; ---------------------------------------------------------------------

; THESE ARE JUST SOME TEMPORARY HAK ROUTINES THAT 
; ALLOW ME TO PRINT SOMETHING VISIBLE ON THE SCREEN...
		
		
PrintName	moveq	#0,d0
		moveq	#0,d1
		move.l	window_p,a0
		move.l	wd_RPort(a0),a0			window's rastport
		lea	itext1,a1
		CALLSYS PrintIText,_IntuitionBase
		rts	
		
ClearName	move.l	dir_request_p,a0
		cmpi.b	#NULL,fr_Drawer(a0)
		beq.s	.exit
		moveq	#0,d0
		moveq	#0,d1
		move.l	window_p,a0
		move.l	wd_RPort(a0),a0			window's rastport
		lea	itext2,a1
		CALLSYS PrintIText,_IntuitionBase
.exit		rts	


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

SetDisplay	move.l	window_p,a0
		CALLSYS	BeginRefresh,_IntuitionBase
		moveq	#SCREENCOLOUR,d0
		move.l	window_p,a1
		move.l	wd_RPort(a1),a1			window's rastport
		CALLSYS	SetRast,_GfxBase

		move.l	window_p,a0
		move.l	wd_RPort(a0),a0			window's rastport
		lea	image,a1
		moveq	#15,d0
		moveq	#20,d1
		CALLSYS DrawImage,_IntuitionBase

                jsr	PrintName
		move.l	window_p,a0
		CALLSYS RefreshWindowFrame,_IntuitionBase			
		move.l	window_p,a0
		moveq	#TRUE,d0
		CALLSYS	EndRefresh,_IntuitionBase
		rts

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


LIBRARY_COUNT	EQU  	5

lib_base_start
_DOSBase	ds.l	1
_IntuitionBase	ds.l 	1
_GadToolsBase 	ds.l 	1
_AslBase	ds.l	1
_GfxBase	ds.l	1
lib_base_end						;end of library base variables

_SysBase	ds.l	1
visual_info_p	ds.l	1	
window_p	ds.l 	1
menu_p		ds.l 	1
dir_request_p	ds.l 	1
dirlock_p	ds.l	1
fib_p		ds.l	1

stack_space1	ds.l	8				space set as required
function_stack1	dc.l	NULL				top of function stack

stack_space2	ds.l	8				space set as required
function_stack2	dc.l	NULL				top of function stack


asl_tags	dc.l	ASLFR_DrawersOnly,TRUE
		dc.l	ASLFR_TitleText,asl_text
		dc.l	TAG_DONE,NULL

window_tags	dc.l	WA_PubScreen
workbench_p	ds.l	1
		dc.l	WA_SmartRefresh,TRUE
		dc.l	WA_Left,10
		dc.l	WA_Top,10
		dc.l	WA_Width,375
		dc.l	WA_Height,240
		dc.l	WA_DragBar,TRUE
		dc.l	WA_DepthGadget,TRUE
		dc.l	WA_CloseGadget,TRUE
		dc.l	WA_SizeGadget,FALSE
		dc.l	WA_Zoom,zoom_data
		dc.l	WA_IDCMP,IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW
		dc.l	WA_Title,window_name
		dc.l	TAG_DONE,NULL

zoom_data	dc.w	300,0,340,10

itext1          dc.b    PENCOLOUR,0,RP_JAM1,0  	 	pens/drawmode/fill				
		dc.w	20,200				left/top edge
		dc.l	NULL				default font
		dc.l	NULL				text pointer set at run time
		dc.l	NULL				next intuitext

itext2          dc.b    SCREENCOLOUR,0,RP_JAM1,0 	pens/drawmode/fill				
		dc.w	20,200				left/top edge
		dc.l	NULL				default font
		dc.l	NULL				text pointer set at run time
		dc.l	NULL				next intuitext

menu		dc.b	NM_TITLE,0
		dc.l	menu_title,NULL
		dc.w	0
		dc.l	0,NULL
			
		dc.b	NM_ITEM,0
		dc.l	item0,commkey0
		dc.w	0
		dc.l	0,NULL
		
		dc.b	NM_ITEM,0
		dc.l	item1,commkey1
		dc.w	0
		dc.l	0,NULL
		
		dc.b	NM_ITEM,0
		dc.l	item2,commkey2
		dc.w	0
		dc.l	0,NULL

		dc.b	NM_END,0
		dc.l	NULL,NULL
		dc.w	0
		dc.l	0,NULL

			
lib_names	dc.l lib1,lib2,lib3,lib4,lib5

lib1		dc.b 'dos.library',NULL
lib2		dc.b 'intuition.library',NULL
lib3		dc.b 'gadtools.library',NULL
lib4		dc.b 'asl.library',NULL
lib5		dc.b 'graphics.library',NULL
		
workbench_name	dc.b 'Workbench',NULL

window_name	dc.b 'StampOnIT! - datestamp utility',NULL

menu_title	dc.b 'PROJECT',NULL

item0		dc.b 'Choose drawer to datestamp...',NULL

commkey0	dc.b 'L',NULL

item1		dc.b 'Currently unused option!',NULL

commkey1	dc.b 'S',NULL

item2		dc.b 'Quit!',NULL

commkey2	dc.b 'Q',NULL

asl_text	dc.b 'SELECT DRAWER TO MODIFY',NULL
	
		END

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




