שתשת                                        ***********************************************************
* $VER: StartUp_S 3.4
*
* This is my TakeSystem and RestoreSystem routines that I now use
* in all my demos.  I am spreading them in hopes to get rid of the
* crapy coding practices that people have had since the C64 days.
* I'd like to thank Comrade J for his excellent "howtocode" files.
* A lot of the stuff here is based on his words of wisdom. :^).  Anyway,
* these routines, as of version 3.4, handle the following:
*		Getting the VBR.
*		Saving DMACON.
*		Saving Intena.
*		Saving and reseting WB view modes.
*		Owning/Disowning the blitter.
*		Pal/Ntsc/AGA modes.
*		Killing multitasking.
*		Killing interrupts.
*		Fixed equates for case sensitive assemblers.
*		Easy to make 100% PC relative.
*
* Feel free to cut and paste to fit your code (i.e. put the data and bss in
* your data and bss sections.), but please leave the CODE intact!
* If you have any questions/comments/suggestions, PLEASE contact me at
* either:
*		idr@rigel.cs.pdx.edu		(internet)
*	- or -
*		Epsilon
*		P.O.B.	1914
*		Beaverton, OR  97075-1914
*		U.S.A.
*
* Many of you may not like the fact that I use includes and system calls,
* I know I don't :), but it is the ONLY SAFE WAY TO TAKE THE SYSTEM!  To
* insure that your demo will work on any system, it's what you have to do.
*
***********************************************************
* Includes
***********************************************************

		incdir	"DevpacAm:include/"
		include	"exec/exec_lib.i"
		include	"exec/execbase.i"
		include	"graphics/gfxbase.i"
		include	"graphics/graphics_lib.i"
		include	"hardware/custom.i"

***********************************************************
* Other Macros
***********************************************************

CALL		MACRO
		jsr	_LVO\1(a6)
		ENDM

***********************************************************
* Other Structs
***********************************************************

		rsreset
gfx_base	rs.l	1		; pointer to graphics base
OldView		rs.l    1		; old Work Bench view addr.
VectorBase:	rs.l	1		; pointer to the Vector Base
OldDMACon:	rs.w	1		; old dmacon bits
OldINTEna:	rs.w	1		; old intena bits
ntsc:		rs.b	1		; 0 = pal, 1 = ntsc
AGA:		rs.b	1		; 0 = ESC/standard, 1 = AGA
SYS_SIZE	rs.b	0		; size of the struct

***********************************************************

		section TheCode,code

TakeSystem:	movea.l	4.w,a6		; exec base
		lea	$dff002,a5	; custom chip base + 2
		lea	SystemSave,a4	; where to save everything

		lea	GraphicsName,a1	; "graphics.library"
		moveq	#0,d0		; any version
		CALL	OpenLibrary	; open it.
		move.l	d0,gfx_base(a4)	; save pointer to gfx base
		beq.b	.erexit		; if we got a NULL, then exit
		movea.l	d0,a6		; for later callls...

		move.l  gb_ActiView(a6),OldView(a4)	; save old view

		move.w	#0,a1		; clears full long-word
		CALL	LoadView	; Open a NULL view (resets display
					;   on any Amiga)

		CALL	WaitTOF		; Wait twice so that an interlace
		CALL	WaitTOF		;   display can reset.

		CALL	OwnBlitter	; take over the blitter and...
		CALL	WaitBlit	;   wait for it to finish so we
					;   safely use it as we please.

		movea.l	4.w,a6		; exec base
		CALL	Forbid		; kill multitasking

		cmpi.b	#50,VBlankFrequency(a6)	; is vblank rate pal?
		beq.b	.pal		; yup.
		st	ntsc(a4)	; set NTSC flag.

.pal:		move.w	$7c-2(a5),d0	; AGA register...
		cmpi.b	#$f8,d0		; are we AGA?
		bne.b	.not_aga	; nope.
		st	AGA(a4)		; set the AGA flag.
		move.w	#0,$1fc-2(a5)	; reset AGA sprites to normal mode

.not_aga:	bsr.b	GetVBR		; get the vector base pointer
		move.l	d0,VectorBase(a4)	; save it for later.

		move.w	dmaconr-2(a5),d0	; old DMACON bits
		ori.w	#$8000,d0	; or it set bit for restore
		move.w	d0,OldDMACon(a4); save it

		move.w	intenar-2(a5),d0	; old INTEna bits
		ori.w	#$c000,d0	; or it set bit for restore
		move.w	d0,OldINTEna(a4); save it

		move.l	#$7fff7fff,intena-2(a5)	; kill all ints
		move.w	#$7fff,dmacon-2(a5)	; kill all dma
		moveq	#0,d0		; return no error code
		rts

.erexit:	moveq	#-1,d0		; error, don't run demo.
		rts

***********************************************************

RestoreSystem:	lea	$dff002,a5	; custom chip base + 2
		lea	SystemSave,a4	; where it's all at

	; You must do these in this order or you're asking for trouble!
		move.l	#$7fff7fff,intena-2(a5)	; kill all ints
		move.w	#$7fff,dmacon-2(a5)	; kill all dma
		move.w	OldDMACon(a4),dmacon-2(a5)	; restore old dma bits
		move.w	OldINTEna(a4),intena-2(a5)	; restore old int bits

		movea.l	OldView(a4),a1	; old Work Bench view
		movea.l	gfx_base(a4),a6	; gfx base
		CALL	LoadView	; Restore the view
		CALL	DisownBlitter	; give blitter back to the system.

		move.l	gb_copinit(a6),$80-2(a5) ; restore system clist
		movea.l	a6,a1
		movea.l	4.w,a6		; exec base
		CALL	CloseLibrary

	; there is no call to Permit() because it is implied by the return
	; to AmigaDOS! :^)
		rts

***********************************************************
* This function provides a method of obtaining a pointer to the base of the
* interrupt vector table on all Amigas.  After getting this pointer, use
* the vector address as an offset.  For example, to install a level three
* interrupt you would do the following:
*
*		bsr	_GetVBR
*		move.l	d0,a0
*		move.l	$6c(a0),OldIntSave
*		move.l	#MyIntCode,$6c(a0)
*
***********************************************************
* Inputs: none
* Output: d0 contains vbr.

GetVBR:		move.l	a5,-(sp)		; save it.
		moveq	#0,d0			; clear
		movea.l	4.w,a6			; exec base
		btst.b	#AFB_68010,AttnFlags+1(a6); are we at least a 68010?
		beq.b	.1			; nope.
		lea.l	vbr_exception(pc),a5	; addr of function to get VBR
		CALL	Supervisor		; supervisor state
.1:		move.l	(sp)+,a5		; restore it.
		rts				; return

vbr_exception:
	; movec vbr,Xn is a priv. instr.  You must be supervisor to execute!
		movec   vbr,d0
	; many assemblers don't know the VBR, if yours doesn't, then use this
	; line instead.
;		dc.l	$4e7a0801
		rte				; back to user state code

***********************************************************

		section TheData,data

GraphicsName:	GRAFNAME		; name of gfx library
		EVEN

***********************************************************

		section	OldPointers_and_such,bss

SystemSave:	ds.b	SYS_SIZE
