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

; Amiga Computing's assembler code tutorial - scroll1.s
; This source has really only been provided so that you can see the 
; changes that have been so far. It is possible to assemble and run 
; the program although don't expect anything startling - at the moment 
; all you will see is a blank screen for a few seconds!

; All the visible 'scroll code' stuff comes next month!


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

NULL			EQU	0
TRUE			EQU	1
FALSE			EQU   	0
TIME_DELAY		EQU	4*50

SCREEN_HEIGHT		EQU	600
SCREEN_WIDTH		EQU 	640
SCREEN_DEPTH		EQU	3

WINDOW_HEIGHT		EQU	600
WINDOW_WIDTH		EQU	640

TAG_DONE		EQU	0
SA_BASE			EQU 	$80000020 
SA_Left			EQU	SA_BASE+$01
SA_Top			EQU	SA_BASE+$02
SA_Width		EQU	SA_BASE+$02
SA_Height		EQU	SA_BASE+$04
SA_Depth		EQU	SA_BASE+$05
SA_DisplayID		EQU	SA_BASE+$12
SA_Quiet		EQU	SA_BASE+$18
SA_Pens			EQU	SA_BASE+$1A

HIRES_KEY		EQU	$008000

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_CustomScreen		EQU	WA_BASE+$0D
WA_DragBar		EQU	WA_BASE+$1F
WA_DepthGadget		EQU	WA_BASE+$20
WA_CloseGadget		EQU	WA_BASE+$21
WA_Backdrop		EQU	WA_BASE+$22
WA_Borderless		EQU	WA_BASE+$25
WA_SimpleRefresh	EQU	WA_BASE+$29

v_LOFCprList		EQU	4
crl_start		EQU	4


_AbsExecBase		EQU	   4

_LVOOpenLibrary		EQU	-552

_LVOCloseLibrary	EQU	-414

_LVOOpenScreenTagList	EQU	-612

_LVOCloseScreen		EQU	 -66

_LVOOpenWindowTagList	EQU	-606

_LVOCloseWindow		EQU	 -72

_LVODelay		EQU	-198

_LVOViewAddress		EQU	-294

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

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

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

		XDEF	_main
		
_main		lea	function_stack,a5	for alloc/dealloc operations
		lea 	lib_names,a2
		lea 	_DOSBase,a3
		move.w	#(LIBRARY_COUNT-1),d3	loop counter
.loop		movea.l	(a2)+,a1		library name pointer
		moveq	#36,d0			minimum library versions
		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	OpenScreen
		beq.s	closedown

		jsr	OpenWindow
		beq.s	closedown
		

		; Display is now up and running so now we
		; can get the address of the Intuition View 
		; structure, find the hardware copper list 
		; and locate the copper list instructions
		; related to the bitplane pointers... 

		CALLSYS	ViewAddress,_IntuitionBase
		move.l	d0,a0			copy to an address register
		move.l	v_LOFCprList(a0),a0
		move.l	crl_start(a0),a0	start of copper list
.search		cmpi.w	#$e0,(a0)		look at instruction
		beq.s	.searchend		found e0 instruction 
		addq.l	#4,a0			move to next instruction
		bra.s	.search			and keep searching
.searchend	addq.l	#2,a0			move to second word
		move.l	a0,copperlist_p		and store this pointer
		

		; all I'm doing at this stage is waiting for 
		; a few seconds so that the display can
		; be seen...

  		jsr 	TimeDelay
  		
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
		rts				and terminate program

lib_error_exit	moveq	#(LIBRARY_COUNT-1),d2	count	
		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

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

; OpenScreen() and CloseScreen() on entry... need no register parameters!


OpenScreen	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		movea.w	#NULL,a0
		lea	screen_tags,a1		start of  tag list
		CALLSYS	OpenScreenTagList,_IntuitionBase
		move.l	d0,screen_p		save returned pointer
		beq.s	.error
		move.l	#CloseScreen,-(a5)	push deallocation routine address
.error		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

CloseScreen	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		movea.l	screen_p,a0		screen to close
		CALLSYS	CloseScreen,_IntuitionBase
		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

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

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


OpenWindow	movem.l	a0-a1/d0-d1,-(a7)	preserve regs
		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	#CloseWindow,-(a5)	push deallocation routine address
.error		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

CloseWindow	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

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

TimeDelay	
		movem.l	a0-a1/d0-d1,-(a7)	preserve regs
                move.l	#TIME_DELAY,d1	 	load time delay value
		CALLSYS	Delay,_DOSBase
		movem.l	(a7)+,a0-a1/d0-d1	restore regs
		rts

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

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

window_p	ds.l 	1
copperlist_p	ds.l	1

screen_pens	dc.l	$FFFFFFFF

screen_tags     dc.l	SA_DisplayID,HIRES_KEY
		dc.l	SA_Quiet,TRUE
		dc.l	SA_Left,0
		dc.l	SA_Top,0
		dc.l	SA_Width,SCREEN_WIDTH
		dc.l	SA_Height,SCREEN_HEIGHT
		dc.l	SA_Depth,SCREEN_DEPTH
		dc.l	SA_Pens,screen_pens
		dc.l	TAG_DONE,NULL


window_tags	dc.l	WA_CustomScreen
screen_p	ds.l	1
		dc.l	WA_Left,0
		dc.l	WA_Top,0
		dc.l	WA_Width,WINDOW_WIDTH
		dc.l	WA_Height,WINDOW_HEIGHT
		dc.l	WA_SimpleRefresh,TRUE
		dc.l	WA_DragBar,FALSE
		dc.l	WA_Title,NULL
		dc.l 	WA_Borderless,TRUE
		dc.l	WA_Backdrop,TRUE
		dc.l    WA_DepthGadget,FALSE
		dc.l	WA_CloseGadget,FALSE
		dc.l	TAG_DONE,NULL

stack_space	ds.l	2			
function_stack	dc.l	NULL			top of function stack

LIBRARY_COUNT	EQU	3
lib_names	dc.l lib1,lib2,lib3

lib1		dc.b 'dos.library',NULL
lib2		dc.b 'graphics.library',NULL
lib3		dc.b 'intuition.library',NULL

		END

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


		