; SPECIAL NOTE: This code module is a direct copy of the routine supplied
;               with PopCLI (Fred Fish #35) which is in turn a version of
;               the code published in the 1.1 Rom Kernel Manuals.
;
;               PopCLI is copyrighted to the Software Distillery
;
	section	text,CODE
*
* C initial startup procedure under AmigaDOS
* 
* Requirements:

	INCLUDE	"exec/types.i"
	INCLUDE "exec/alerts.i"
	INCLUDE "exec/nodes.i"
	INCLUDE "exec/lists.i"
	INCLUDE "exec/ports.i"
	INCLUDE "exec/libraries.i"
	INCLUDE "exec/tasks.i"
	INCLUDE "libraries/dos.i"
	INCLUDE "libraries/dosextens.i"

; some usefull macros:
xlib	macro
	xref	_LVO\1
	endm

callsys	macro
	CALLLIB	_LVO\1
	endm
	

	xdef	_XCEXIT			* exit(code) is standard way to leave C.
	xdef	_HandlerInterface

	xref	_myhandler
	xref	__main			* Name of C program to start with.
	xref	_AbsExecBase
	xref	_FindTask
	xref	_DOSBase

	xlib	Alert
	xlib	FindTask
	xlib	Forbid
	xlib	GetMsg
	xlib	OpenLibrary
	xlib	CloseLibrary
	xlib	ReplyMsg
	xlib	Wait
	xlib	WaitPort
	xlib	Open
	xlib	Close
	xlib	CurrentDir

start:
	move.l	d0,dosCmdLen
	move.l	a0,dosCmdBuf
	move.l	a7,d0			; save old stack ptr
	movem.l	d1-d6/a0-a6,-(a7)
	move.l	d0,a5
	move.l	_AbsExecBase,a6
	move.l	a6,_SysBase
	move.l	a7,__StackPtr		* Save stack ptr

;------ get the address of our task
	suba.l	a1,a1
	callsys	FindTask
	move.l	d0,a4

;------ are we running as a son of Workbench?
	move.l	pr_CurrentDir(A4),_curdir
	tst.l	pr_CLI(A4)
	beq	exit2

;=======================================================================
;====== CLI Startup Code ===============================================
;=======================================================================

fromCLI:
	move.l	a5,D0		; get top of stack
	sub.l	4(a5),D0	; compute bottom 
	move.l	D0,__base	; save for stack checking
;------	attempt to open DOS library:
	lea	DOSName,A1
	moveq.l	#0,D0
	callsys OpenLibrary
	move.l	D0,_DOSBase
	beq	noDOS

;------ find command name:
	move.l	#start,a0
	clr.l	-(sp)
	jsr	_FindTask
	addq.l	#4,sp
	move.l	d0,a0
	move.l	pr_CLI(a0),a0
	add.l   a0,a0		; bcpl pointer conversion
	add.l   a0,a0
	move.l	cli_CommandName(a0),a1
	add.l   a1,a1		; bcpl pointer conversion
	add.l   a1,a1

;------	collect parameters:
	move.l	dosCmdLen,d0		; get command line length
	move.l	a1,__ProgramName
	addq.l	#1,d0			; allow for space after command	

	clr.w	-(A7)			; set null terminator for command line
	addq.l	#1,D0			; force to even number of bytes
	andi.w	#$fffe,D0		;(round up)
	sub.l	D0,A7			; make room on stack for command line
	subq.l	#2,D0
	clr.w	0(A7,D0)

;------ copy command line onto stack
	move.l	dosCmdLen,d0		; get command line length
	move.l	dosCmdBuf,a0
	move.l	d0,d2
	subq.l	#1,d0

copy_line:
	move.b	0(A0,D0.W),0(A7,D2.W)	; copy command line to stack
	subq.l	#1,d2
	dbf	d0,copy_line
	move.b	#' ',0(a7,d2.w)		; add space between command and parms
	subq.l	#1,d2

	move.l	A7,A1
	move.l	A1,-(A7)		; push command line address
	jsr	__main		        * call C entrypoint
	moveq.l	#0,d0			; set successful status
	bra.l	exit2

_XCEXIT:
	move.l	4(SP),d0	; extract return code
exit2:
	move.l	d0,-(a7)
	move.l	_SysBase,a6
	move.l	_DOSBase,a1
	callsys	CloseLibrary		; close Dos library

;------ this rts sends us back to DOS:
exitToDOS:
	MOVE.L	(A7)+,D0
	movea.l  __StackPtr,SP		* restore stack ptr
	movem.l	(a7)+,d1-d6/a0-a6
	rts				* and exit

;-----------------------------------------------------------------------
noDOS:
		ALERT	(AG_OpenLib!AO_DOSLib)
		moveq.l	#100,d0
		bra	exit2

*************************************************************************
*   HandlerInterface()
*
*   This code is needed to convert the calling sequence performed by
*   the input.task for the input stream management into something
*   that a C program can understand.
*
*   This routine expects a pointer to an InputEvent in A0, a pointer
*   to a data area in A1.  These values are transferred to the stack
*   in the order that a C program would need to find them.  Since the
*   actual handler is written in C, this works out fine. 
*
*   Author: Rob Peck, 12/1/85
*

_HandlerInterface:
	movem.L	A0/A1,-(A7)
	jsr	_myhandler
	addq.L	#8,A7
	rts

	section	data,DATA
;
	XDEF	_NULL,_SysBase,_LoadAddress,_console_dev,_WBenchMsg
	XDEF	_curdir,__mbase,__mnext,__msize,__tsize
	XDEF	__oserr,__OSERR,__FPERR,__SIGFPE,__ONERR,__ONEXIT,__ONBREAK
	XDEF	__SIGINT
	XDEF	_errno,_stdin,_stdout,_stderr
	XDEF	__ProgramName,__StackPtr,__base
;
_errno		dc.l	0
_stdin		dc.l	0
_stdout		dc.l	0
_stderr		dc.l	0
_NULL		dc.l	0		;
__base		dc.l	0		; base of stack
__mbase		dc.l	0		; base of memory pool
__mnext		dc.l	0		; next available memory location
__msize		dc.l	0		; size of memory pool
__tsize		dc.l	0		; total size?
__oserr		equ	*
__OSERR		dc.l	0
__FPERR		dc.l	0
__SIGFPE	dc.l	0
__SIGINT	dc.l	0
__ONERR		dc.l	0
__ONEXIT	dc.l	0
__ONBREAK	dc.l	0
_curdir		dc.l	0
_console_dev	dc.l	0
_SysBase	dc.l	0
_LoadAddress	dc.l	0			; program load address
_WBenchMsg	dc.l	0
__StackPtr	dc.l	0
dosCmdLen	dc.l	0
dosCmdBuf	dc.l	0
stdin		dc.l	0
__ProgramName	dc.l	0
DOSName 	DOSNAME

	END
