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

; Paul Overaa's Amiga Computing Assembler Series - code for instalment 2

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

NULL			EQU	   0

TRUE			EQU	   1

TAG_DONE		EQU	   0
WA_BASE			EQU 	$80000063
WA_Left			EQU	WA_BASE+$01
WA_Top			EQU	WA_BASE+$02
WA_Width		EQU	WA_BASE+$03
WA_Height		EQU	WA_BASE+$04
WA_Title		EQU	WA_BASE+$0B
WA_DragBar		EQU	WA_BASE+$1F
WA_PubScreen		EQU	WA_BASE+$16

_AbsExecBase		EQU	   4

_LVOOpenLibrary		EQU	-552

_LVOCloseLibrary	EQU	-414

_LVODisplayBeep		EQU	 -96

_LVOLockPubScreen	EQU	-510

_LVOUnlockPubScreen	EQU	-516

_LVOOpenWindowTagList	EQU	-606

_LVOCloseWindow		EQU	 -72

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

LINKLIB		MACRO
		move.l	a6,-(a7)
		movea.l	\2,a6
		jsr	\1(a6)
		move.l	(a7)+,a6
		ENDM

CALLSYS		MACRO
		LINKLIB	_LVO\1,\2
		ENDM

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

_main		lea	function_stack,a5	for alloc/dealloc operations
		lea 	lib_names,a2
		lea 	_DOSBase,a3
		move.w	#(5-1),d3		loop counter
.loop		movea.l	(a2)+,a1		library name pointer
		moveq	#0,d0			any version will do
		CALLSYS	OpenLibrary,_AbsExecBase
		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	OpenWindow
		beq.s	closedown
		
		; window is now open so we could do something!
		; all I'm doing at the moment is...
		
delay		move.l	#10000000,d0		temporarily wasting some time
.loop		subq.l	#1,d0			so window appears for long
		bne.s	.loop			enough to be visible!
				
		
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		revised label - see text
		moveq	#5,d2			library count
		jsr	CloseLibs		close libraries
		moveq	#0,d0			clear d0 for O/S
		rts				and terminate program

lib_error_exit	moveq	#(5-1),d2		see part 1 mag text
		sub	d3,d2
		jsr	CloseLibs		close libraries
		moveq	#0,d0			clear d0 for O/S
		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,_AbsExecBase
		subq.b	#1,d2
		bra.s	CloseLibs
loop_end	rts

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

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


LockScreen	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		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		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

UnlkScreen	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		movea.w	#NULL,a0		screen name not needed
		movea.l	workbench_p,a1		screen to unlock
		CALLSYS	UnlockPubScreen,_IntuitionBase
		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

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

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


OpenWindow	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		movea.w	#NULL,a0
		lea	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
.error		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

ShutWindow	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		movea.l	window_p,a0		window to close
		CALLSYS	CloseWindow,_IntuitionBase
		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

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

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

window_p	ds.l 1
tags		dc.l	WA_PubScreen
workbench_p	ds.l	1
		dc.l	WA_Left,0
		dc.l	WA_Top,0
		dc.l	WA_Width,640
		dc.l	WA_Height,200
		dc.l	WA_DragBar,TRUE
		dc.l	WA_Title,window_name
		dc.l	TAG_DONE,NULL

stack_space	ds.l	2			space will grow as required
function_stack	dc.l	NULL			top of function stack


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

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

workbench_name	dc.b 'Workbench',NULL

window_name	dc.b 'Amiga Computing Assembler Series by Paul Overaa',NULL

		END

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


		