;START GMS
;---------
;Usage:   StartGMS <TaskFile>
;Author:  Paul Manias
;Version: V0.2
;Date:    30/5/97
;Docs:    This program is intended to allow multi-platform capabilities by
;	  doing things like opening GMS for the task.  For example the
;	  following code would not work on a Mac even if it is 68000 code:
;
;	  move.l $4.w,a6
;	  ...
;	  CALL   OpenLibrary
;
;	  To fix this problem we put this machine-specific code in a task
;	  launcher (StartGMS) and pass the GMSBase onto the task.  Alakazam,
;	  multiple platform capabilities!
;
;PROBLEMS: Programs written in E cannot cope with this as far as I know :-(.

	INCDIR	"INCLUDES:"
	INCLUDE	"exec/exec_lib.i"
	INCLUDE	"dos/dos_lib.i"
	INCLUDE	"exec/libraries.i"
	INCLUDE	"games/games_lib.i"

CALL	MACRO
	jsr	_LVO\1(a6)
	ENDM

	SECTION	"StartGMS",CODE

;===================================================================================;
;                                INITIALISE PROGRAM
;===================================================================================;
;Requires: a0 = Pointer to file to load???

Start:	MOVEM.L	A0-A6/D0-D7,-(SP)
	move.l	a0,CommandLine
	move.l	d0,AmtCommands

	move.l	($4).w,a6
	lea	DOSName(pc),a1
	moveq	#$00,d0
	CALL	OpenLibrary
	move.l	d0,DOSBase
	beq.s	.Error_DOS

	lea	GMSName(pc),a1
	moveq	#$00,d0
	CALL	OpenLibrary
	move.l	d0,GMSBase
	beq.s	.Error_GMS

	cmp.l	#1,AmtCommands
	ble.s	.ReturnToDOS
	move.l	CommandLine(pc),a0
	cmp.b	#"?",(a0)
	bne.s	.go
	bsr.s	Usage
	bra.s	.ReturnToDOS

.go	bsr.s	ParseArguments
	tst.l	d0
	bne.s	.ReturnToDOS
	bsr	Launch
	bsr	FreeArguments

.ReturnToDOS
.Error_GMS
	move.l	($4).w,a6
	move.l	DOSBase(pc),a1
	CALL	CloseLibrary
.Error_DOS
	MOVEM.L	(SP)+,A0-A6/D0-D7
	moveq	#$00,d0
	rts

;===================================================================================;
;                             PRINT USAGE INFORMATION
;===================================================================================;

Usage:	move.l	DOSBase(pc),a6
	CALL	Output
	move.l	d0,d1	;d1 = File handle to write out to.
	move.l	#TXT_Usage,d2	;d2 = Pointer to buffered text.
	move.l	#TXT_UsageSize,d3	;d3 = Size of text.
	CALL	Write
	rts

;===================================================================================;
;                                 PARSE ARGUMENTS
;===================================================================================;
;Template is: StartGMS <TaskFile> [PREFS <Name>] <Arg1> <Arg2> ...

ParseArguments:
	move.l	CommandLine(pc),a0	;a0 = Pointer to first char of <TaskFile>.
	moveq	#$00,d0	;d0 = Byte count of file name.
.loop	cmp.b	#10,(a0)	;a0 = Check for return key.
	beq.s	.key_return	;>> = Return key found.
	cmp.b	#' ',(a0)	;a0 = Check for space key.
	beq.s	.key_space	;>> = Return key found.
	addq.l	#1,d0	;d0 = ++1
	addq.w	#1,a0	;a0 = ++1
	bra.s	.loop	;>> = Keep looping till we find the end.

.key_return
	move.b	#' ',(a0)	;a0 = Replace return key with a space.
.key_space
	addq.l	#1,a0	;a0 = ++1
	move.l	a0,TaskArgs	;MA = Save pointer to GMS task args.
	move.l	($4).w,a6	;a6 = ExecBase
	addq.l	#1,d0	;d0 = (MemSize)+1 [For null termination]
	move.l	d0,sizeTaskFile	;MA = Make a note of the size allocated.
	moveq	#$0,d1	;d1 = MemType
	CALL	AllocMem	;>> = AllocMem(Size:d0,Type:d1)
	move.l	d0,TaskFile	;MA = Pointer to file memory.
	beq.s	.Error_Memory	;>> = Memory error.

	move.l	CommandLine(pc),a0	;a0 = Command Line source.
	move.l	TaskFile(pc),a1	;a1 = FileName destination.
.cloop	cmp.b	#" ",(a0)	;a0 = Check for space.
	beq.s	.done	;>> = Got it.
	move.b	(a0)+,(a1)+	;a1 = Copy Character++
	bra.s	.cloop	;>> = Keep looping.

.done	clr.b	(a1)+
	moveq	#$00,d0	;d0 = No errors.
	rts

.Error_Memory
	moveq	#$01,d0	;d0 = Memory error.
	rts

FreeArguments:
	move.l	($4).w,a6	;a6 = ExecBase.
	move.l	TaskFile(pc),a1	;a1 = Pointer to allocated block.
	move.l	sizeTaskFile(pc),d0	;d0 = Size of allocated block.
	CALL	FreeMem	;>> = Free it.
	rts

;===================================================================================;
;                                LAUNCH GMS PROGRAM
;===================================================================================;
;Load the program in with LoadSeg() and then run it (remembering to pass the
;necessary variables).  On other machines this part will have to be modified to
;recognise and load in Amiga formatted file hunks.
;
;Sends: a0 = Command Line Parameters
;	a1 = GMSBase
;	a2 = Pointer to address of program.
;	d0 = "GMSP" Identification.
;	d1 = Amount of commands on line.
;	d2 = (Version<<16)|(Revision)

Launch:	move.l	DOSBase(pc),a6	;a6 = DOS Base.
	move.l	TaskFile(pc),d1	;d1 = Pointer to file name.
	CALL	LoadSeg	;>> = Go and load the executable.
	move.l	d0,Segment	;MA = Store pointer to segment.
	beq.s	.Error_Segment	;>> = Error loading file :-(

	;Initialise self-destruct sequence.

	move.l	GMSBase(pc),a6	;a6 = GMSBase.
	lea	.exit(pc),a0	;a0 = Pointer to SelfDestruct() cleanup.
	move.l	a7,a1	;a1 = Stack pointer.
	CALL	InitDestruct	;>> = Initialise the call.

	;Setup parameters here.

	move.l	Segment(pc),d0	;d0 = BCPL pointer to segment.
	add.l	d0,d0	;d0 = *2
	add.l	d0,d0	;d0 = *4
	move.l	d0,a2	;a2 = Pointer to start of seglist.
	move.l	GMSBase(pc),a1	;a1 = Pointer to GMSBase.
	move.l	#"GMSP",d0	;d0 = "GMSP"

	move.w	LIB_VERSION(a1),d2	;d2 = Version
	swap	d2	;d2 = (Version)<<16
	move.w	LIB_REVISION(a1),d2	;d2 = (Version<<16)|(Revision)

	sub.l	a3,a3	;Clear all other registers before
	sub.l	a4,a4	;launching the task.
	sub.l	a5,a5
	sub.l	a6,a6
	moveq	#$00,d2
	moveq	#$00,d3
	moveq	#$00,d4
	moveq	#$00,d5
	moveq	#$00,d6
	moveq	#$00,d7
	jsr	4(a2)	;>> = Start the GMS program.

.exit	move.l	GMSBase(pc),a6
	CALL	CloseGMS

	move.l	DOSBase(pc),a6	;a6 = DOS Base.
	move.l	Segment(pc),d1	;d1 = BCPL segment pointer.
	CALL	UnLoadSeg	;>> = Unload the program.
.Error_Segment
	rts

;===================================================================================;
;                                       DATA
;===================================================================================;

GMSName: dc.b	"GMS:libs/dpkernal.library",0
	 even
DOSName: dc.b	"dos.library",0
	 even

GMSBase:  dc.l	0	;Pointer to GMSBase.
DOSBase:  dc.l	0

TaskFile:    dc.l  0	;Name of file to load.
sizeTaskFile dc.l  0	;Size of allocated memory block.
Segment:     dc.l  0	;Pointer to segment of loaded file.
CommandLine  dc.l  0	;Pointer to first command line argument.
AmtCommands: dc.l  0	;Amount of arguments on command line.
TaskArgs:    dc.l  0	;Arguments for the GMS Task.

TXT_Usage:
 dc.b	10
 dc.b	"STARTGMS",10
 dc.b	"--------",10
 dc.b	"This program will launch GMS tasks for you, and in future will",10
 dc.b	"be required for setting up GMS games that have been compiled on other",10
 dc.b	"platforms.",10
 dc.b	10
 dc.b	"To use it, just type:",10
 dc.b	10
 dc.b	"  1> StartGMS <FileName> <Arg1> <Arg2> <Arg3> ...",10
 dc.b	10
 dc.b	"Example:",10
 dc.b	10
 dc.b	"  1> StartGMS GMS:demos/Redimension",10
 dc.b	10
 dc.b	0

TXT_UsageSize = *-TXT_Usage

