*******************************************************************************
* shl_strtup.i 3.4.2
*******************************************************************************
* INFO	shell startup code; operations performed:
*	  1. opens all needed libraries
*	  2. if required, parses the command line with ReadArgs(): the
*	     arguments pointers are stored in CmdLnArgs (a buffer in
*	     dat.i); the template must be specified in the custom code
*	     at the label tmplt; the number of arguments must be set
*	     by the custom code with the constant ARGSNO (leave it
*	     undefined if you don't need parsing)
*	  3. initializes a TCS display
*	  4. call the initialization routine of custom program
*	     (_PrgInit) which must return ccr=eq on error
*	  5. turns off the OS
*	  6. takes control of the hardware
*	  7. activates the TCS display
*	  8. calls the main routine of custom program (_PrgMain)
*	  9. hides the TCS display
*	 10. restores the hardware status
*	 11. re-activates the OS
*	 12. call the cleanup routine of custom program (_PrgClnUp)
*	     (this is called even if _PrgInit failed)
*	 13. frees all the resources allocated
* NOTE	- use the macro CALLTCS to call tcs.library functions
*	- no need of any include other than tcs.library's
*******************************************************************************

	macro	CALLTCS
	movea.l	_TCSBase,a6
	jsr	(_LVOTCS_\1,a6)
	endm



	code

*******************************************************************************
* open libs / command line parsing

	movea.l	4.w,a6
	lea.l	DOSNm,a1
	moveq.l	#37,d0
	jsr	(-552,a6)	;OpenLibrary(...)
	move.l	d0,_DOSBase
	beq	.exit
	lea.l	GfxNm,a1
	moveq.l	#37,d0
	jsr	(-552,a6)	;OpenLibrary(...)
	move.l	d0,_GfxBase
	beq	.ClsDOS
	lea.l	TCSNm,a1
	moveq.l	#1,d0
	jsr	(-552,a6)	;OpenLibrary(...)
	move.l	d0,_TCSBase
	beq.s	.ClsGfx

	ifd	ARGSNO
	move.l	#tmplt,d1
	move.l	#CmdLnArgs,d2
	moveq.l	#0,d3
	movea.l	_DOSBase,a6
	jsr	(-798,a6)	;ReadArgs(tmplt,CmdLnArgs,0)
	move.l	d0,_RDArgs
	beq	.ClsLibs
	endif

*******************************************************************************
* display/custom program initialization

	lea.l	DsplDef,a0	;our TCS display
	CALLTCS	InitDspl	;initialize it
	move.l	d0,DIAdr	;keep its structure address
	beq.s	.FreeArgs	;in case of error...

	bsr	_PrgInit	;custom init
	beq.s	.PrgClnUp	;if error...

*******************************************************************************
* OS/HW takeover

	movea.l	_DOSBase,a6
	moveq.l	#40,d1
	jsr	(-198,a6)	;Delay(40)

	bsr	TkSys	;get OS and HW control

*******************************************************************************
* start custom code

	movea.l	DIAdr,a0	;our display
	CALLTCS	ShwDspl	;activate it!
	beq	.RlsSys	;if failed to (never should)...
	jsr	_PrgMain	;call custom code

*******************************************************************************
* HW/OS restoration / custom program cleanup / resources release

	movea.l	DIAdr,a0	;our display
	CALLTCS	WtBltFRPass	;wait for blitter to finish
	movea.l	DIAdr,a0	;our display
	suba.l	a1,a1	;don't show anything after
	CALLTCS	HideDspl	;hiding it
.RlsSys	bsr	RlsSys	;restore HW and OS status

.PrgClnUp	bsr	_PrgClnUp	;custom cleanup

	movea.l	DIAdr,a0	;our display
	CALLTCS	FreeDspl	;free its resources

.FreeArgs
	ifd	ARGSNO
	move.l	_RDArgs,d1
	movea.l	_DOSBase,a6
	jsr	(-858,a6)	;FreeArgs(_RDArgs)
	endif

.ClsLibs	movea.l	4.w,a6
	movea.l	_TCSBase,a1
	jsr	(-414,a6)	;CloseLibrary(...)
.ClsGfx	movea.l	4.w,a6
	movea.l	_GfxBase,a1
	jsr	(-414,a6)	;CloseLibrary(...)
.ClsDOS	movea.l	4.w,a6
	movea.l	_DOSBase,a1
	jsr	(-414,a6)	;CloseLibrary(...)

.exit	moveq.l	#0,d0
	rts



*******************************************************************************
* TkSys 0.0.1
*******************************************************************************
* INFO	turns AmigaOS OFF and takes control of the hardware
*******************************************************************************

TkSys	movem.l	d0-d7/a0-a6,-(sp)
	movea.l	_GfxBase,a6
	move.l	($22,a6),_SysView	;gb_ActiView
	suba.l	a1,a1
	jsr	(-222,a6)	;LoadView(NULL)
	jsr	(-270,a6)	;WaitTOF()
	jsr	(-270,a6)	;WaitTOF()

	movea.l	_GfxBase,a6
	jsr	(-456,a6)	;OwnBlitter()
	jsr	(-228,a6)	;WaitBlit()

	movea.l	4.w,a6
	jsr	(-132,a6)	;Forbid()
	jsr	(-120,a6)	;Disable()

	move.w	$dff01c,_SysINTENA
	move.w	#$7fff,$dff09a	;clear INTENA.all
	move.w	#$7fff,$dff09c	;clear INTREQ.all
	move.w	$dff002,_SysDMACON
	move.w	#$7fff,$dff096	;clear DMACON.all

	bsr	GetVBR
	lea.l	([_VBR.l],$64.w),a0	;first autovector address
	movem.l	(a0),d1-d7	;get system autovectors 1-7
	lea.l	_SysVecs,a0
	movem.l	d1-d7,(a0)	;store them

	movem.l	(sp)+,d0-d7/a0-a6
	rts



*******************************************************************************
* RlsSys 0.0.2
*******************************************************************************
* INFO	releases the hardware and turns AmigaOS ON
*******************************************************************************

RlsSys	movem.l	d0-d7/a0-a6,-(sp)

	lea.l	_SysVecs,a0	;get system
	movem.l	(a0),d1-d7	;autovectors
	lea.l	([_VBR.l],$64.w),a0	;first autovector address
	movem.l	d1-d7,(a0)	;restore them

	move.w	#$7fff,$dff09a	;clear INTENA.all
	move.w	#$7fff,$dff09c	;clear INTREQ.all
	move.w	#$7fff,$dff096	;clear DMACON.all
	move.w	_SysDMACON,d0
	ori.w	#$8000,d0
	move.w	d0,$dff096	;restore system DMACON
	move.w	_SysINTENA,d0
	ori.w	#$c000,d0
	move.w	d0,$dff09a	;restore system INTENA

	movea.l	4.w,a6
	jsr	(-126,a6)	;Enable()
	jsr	(-138,a6)	;Permit()

	movea.l	_GfxBase,a6
	jsr	(-462,a6)	;DisownBlitter()

	movea.l	_GfxBase,a6
	movea.l	_SysView,a1
	jsr	(-222,a6)	;LoadView(_SysView)
	jsr	(-270,a6)	;WaitTOF()
	jsr	(-270,a6)	;WaitTOF()
	move.l	([_GfxBase.l],$26.w),$dff080 ;gb_copinit
	move.w	#1,$dff088	;restore system copperlist

	movem.l	(sp)+,d0-d7/a0-a6
	rts



*******************************************************************************
* GetVBR 0.0.0
*******************************************************************************
* INFO	retrieves the VBR
* OUT	_VBR.l	variable holding the VBR
*******************************************************************************

GetVBR	movem.l	a5-a6,-(sp)
	movea.l	4.w,a6
	btst.b	#0,($129,a6)
	beq.s	.exit	;if 68000...
	lea.l	(_GetVBR,pc),a5
	jsr	(-30,a6)	;Supervisor()
.exit	movem.l	(sp)+,a5-a6
	rts

_GetVBR	dc.l	$4e7ad801	;movec.l vbr,a5
	move.l	a5,_VBR
	rte
