; This here code is for a process started up by CLImax which has the job of
; actually carrying out the creation of the new CLI process and then waiting
; for it to finish and then closing the screen it used.
;
; Written for the Manx assembler, hopefully portable.
; Use the -n flag for one-pass assembly.  Link with the +a flag.
;
; This code is incorporated into the program CLImax, which then copies it into
; an allocated block of public memory.  It copies everything found between
; the two symbols _beginning and _ending.  The new process adds this area of
; memory into its tc_MemEntry list for automatic cleanup.


		xdef		_beginning
		xdef		_ending
		xdef		_StuffOffs
		xdef		_CommandOffs
		xdef		_CloseStuff
		xdef		_NameOffs
		xdef		_FakeOffs

		nolist
		  include 	"exec/types.i"  	; nobody pulls this in!
		  include 	"exec/memory.i"
		  include 	"exec/tasks.i"
		  include 	"exec/execbase.i"
		  include 	"intuition/intuition.i"
		  include	"dos/dosextens.i"
		  include	"libraries/dos_lib.i"
		list

		STRUCTURE	stufff,0
		  CPTR		ibase
		  CPTR		gbase
		  CPTR		dosbase
		  CPTR		fawnt
		  CPTR		scr
		  CPTR		win
		  BPTR		wandle
		  BPTR		ceedee
		  CPTR		wdef
		  CPTR		oldOpenWindow
		  CPTR		wfargs
		  LONG		waitret
		  BOOL		onecmd
		  BOOL		dos2
		LABEL		stuffsize

		STRUCTURE	wfargss,0
		  CPTR		handler
		  WORD		left
		  WORD		top
		  WORD		width
		  WORD		height
		  CPTR		title
		  CPTR		windowptr
		LABEL		wfargsize


stuf		equr		a5		; the stuff struct
clap		equr		a4		; our struct CLI
me		equr		a3		; FindTask(null)
mist		equr		a2		; tc_MemEntry addition
pathlist	equr		d7		; the command path bptr-list

memlistsize	equ		ML_SIZE+ME_SIZE		; size of MemList
							;   with one MemEntry
codesize	equ		8+_ending-_beginning	; size of our "seglist"


lcall:  macro					; call whatever library is in a6
		ifnd		_LVO\1
		  xref		_LVO\1  	; (few dublications)
		endc
		jsr		_LVO\1(a6)
	endm


xcall:  macro					; make an exec library call
		move.l 		4,a6
		lcall		\1
	endm

	cseg
	cnop		0,4		; USE LN'S +A OPTION to make this work


; ============================ The first word copied is also the entry point:

_beginning:	lea		stuff(pc),stuf
		sub.l		a1,a1
		xcall		FindTask
		move.l		d0,me
		move.l  	#MEMF_PUBLIC|MEMF_CLEAR,d1
		move.l  	#memlistsize,d0
		xcall		AllocMem	; make a MemList with one entry
		move.l  	d0,mist
		tst.l		d0
		beq		DOit(pc)	; low ram? then we'll lose more!
						; (this code won't deallocate)
		  move.l  	#codesize,ML_ME+ME_LENGTH(mist)
		  lea		_beginning(pc),a0
		  moveq		#8,d0
		  sub.l		d0,a0
		  move.l  	a0,ML_ME+ME_ADDR(mist)
		  move.w  	#1,ML_NUMENTRIES(mist)  ; the memlist points
		  lea		TC_MEMENTRY(me),a0	;   to our code
		  move.l  	mist,a1
		  lcall		AddTail 	; plug in where RemTask looks.

DOit:		move.l		wandle(stuf),d0
		move.l		d0,pr_COS(me)
		asl.l		#2,d0
		move.l		d0,a0
		move.l		fh_Type(a0),pr_ConsoleTask(me)
		move.l		#MODE_OLDFILE,d2
		lea		starname(pc),a0
		move.l		a0,d1
		move.l		dosbase(stuf),a6
		lcall		Open
		lea		extraFH(pc),a0
		move.l		d0,(a0)
		move.l		d0,pr_COS(me)
		move.l		win(stuf),pr_WindowPtr(me)
		move.l		ceedee(stuf),pr_CurrentDir(me)
		lea		fakli(pc),a0
		move.l		a0,d0
		asr.l		#2,d0
		move.l		d0,pr_CLI(me)

		move.l		wandle(stuf),d0
		move.l		d0,pr_CIS(me)
		move.l		pr_COS(me),cli_StandardOutput(a0)
		move.l		pr_COS(me),cli_CurrentOutput(a0)
		move.l		pr_CIS(me),cli_StandardInput(a0)
		move.l		pr_CIS(me),cli_CurrentInput(a0)

		lea		command(pc),a0
		move.l		a0,d1
		move.w		onecmd(stuf),d0
		and.w		dos2(stuf),d0
		bne		systemt
		  move.l	wandle(stuf),d2
		  move.l	extraFH(pc),d3
		  lcall		Execute				; TA DA!
		  moveq		#-1,d5
		bra		nair
systemt:	  lea		taglist,a0
		  move.l	a0,d2
		  lcall		SystemTagList			; another TA DA!
		  move.l	d0,d5

nair:		move.l		waitret(stuf),d0
		not.l		d0
		beq		kerflush
		  cmp.l		waitret(stuf),d5
		  blo		kerflush
		    move.l	wandle(stuf),d1
		    lea		waitmsg(pc),a0
		    move.l	a0,d2
		    moveq	#27,d3			; CAREFUL OF THIS ...
		    lcall	Write
		    move.l	wandle(stuf),d1
		    lea		spoog(pc),a0
		    move.l	a0,d2
		    moveq	#1,d3
		    lcall	Read			; wait for any input
kerflush:	move.l		wandle(stuf),d1
		lcall		Close

		clr.l		pr_CLI(me)
		lea		fakli(pc),clap
		move.l		pr_CurrentDir(me),d1
		beq		nounlock(pc)
		  lcall		UnLock
		  clr.l		pr_CurrentDir(me)
nounlock:	move.l		cli_CommandDir(clap),pathlist
		asl.l		#2,pathlist
		beq		die(pc)

getapode:	  move.l	pathlist,a2
		  move.l	(a2),pathlist		; bptr to next
		  move.l	4(a2),d1		; lock
		  beq		nounlick(pc)
		    move.l	dosbase(stuf),a6
		    lcall	UnLock
nounlick:	  move.l	a2,a1
		  moveq		#8,d0
		  xcall		FreeMem
		  asl.l		#2,pathlist
		  bne		getapode(pc)

die:		move.l		stuf,-(sp)		; C style parm
		bsr		_CloseStuff
		addq		#4,sp
		moveq		#0,d1
		move.l		dosbase(stuf),a6
		lcall		Exit			; bye bye


; this routine can be called both from the main program and from the bud
; process.  In the former case the copy of stuff that we need to use is not
; the one we can find at stuff(pc).  So we pass the stuff pointer as a C arg.

_CloseStuff:	movem.l		stuf/a6,-(sp)
		move.l		12(sp),stuf
		move.l		extraFH(pc),d1
		beq		noxtra
		  move.l	dosbase(stuf),a6
		  lcall		Close
noxtra		tst.l		scr(stuf)
		beq		nocloseS(pc)
		  xcall		Forbid

wait:		    tst.l	win(stuf)
		    beq		nocloseW(pc)
		      move.l	scr(stuf),a0
		      move.l	sc_FirstWindow(a0),d1
		      cmp.l	win(stuf),d1
		      bne	nocloseW(pc)
		        move.l	ibase(stuf),a6
		        move.l	win(stuf),a0
		        lcall	CloseWindow

nocloseW:	    move.l	scr(stuf),a0
		    tst.l	sc_FirstWindow(a0)
		    beq		closeS(pc)
		      move.l	dosbase(stuf),a6
		      moveq	#50,d1
		      lcall	Delay
		      bra	wait(pc)
closeS:		  move.l	ibase(stuf),a6
		  lcall		CloseScreen	; stuff->scr already in a0
		  xcall		Permit

nocloseS:	tst.l		fawnt(stuf)
		beq		nocloseF(pc)
		  move.l	fawnt(stuf),a1
		  move.l	gbase(stuf),a6
		  lcall		CloseFont
nocloseF:	move.l  	ibase(stuf),a1
		xcall		CloseLibrary
		move.l		gbase(stuf),a1
		lcall		CloseLibrary
		movem.l		(sp)+,stuf/a6
		rts


command:	ds.b		88
_CommandOffs:	dc.w		command-_beginning
stuff:		ds.b		stuffsize
_StuffOffs:	dc.w		stuff-_beginning
procname:	dc.b		"CLImax",0,0
_NameOffs:	dc.w		procname-_beginning

	 cnop		0,4
fakli:		ds.b		cli_SIZEOF
prompt:		dc.b		4,"%N> ",0,0,0
		ds.b		56
setname:	dc.b		4,"SYS:",0,0,0
		ds.b		80
_FakeOffs:	dc.w		fakli-_beginning

extraFH:	dc.l		0
starname:	dc.b		"*",0
waitmsg:	dc.b		10," -- Press return to exit: "
spoog:		ds.b		2
taglist:	dc.l		TAG_DONE


		public		_WedgeOffs,_strncmp

OWwedge:	movem.l		a2/stuf,-(sp)     ; struct NewWindow *  is in a0
		lea		stuff(pc),stuf
		move.l		wfargs(stuf),a1
		move.w		left(a1),d0
		cmp.w		nw_LeftEdge(a0),d0
		bne		around
		move.w		top(a1),d0
		cmp.w		nw_TopEdge(a0),d0
		bne		around
		move.w		width(a1),d0
		cmp.w		nw_Width(a0),d0
		bne		around
		move.w		height(a1),d0
		cmp.w		nw_Height(a0),d0
		bne		around
		  move.l	title(a1),a1
		  move.l	nw_Title(a0),a2
		  moveq		#29,d0			; !strncmp
zoop:		    cmp.b	(a1)+,(a2)+
		    bne		around
		   dbra		d0,zoop
		      move.l	a0,a2
		      move.l	win(stuf),a0
		      lcall	CloseWindow		; ibase already in a6
		      move.l	wdef(stuf),a0
		      move.l	oldOpenWindow(stuf),a1
		      jsr	(a1)
		      move.l	d0,win(stuf)
		      bne	outwego
		        move.l	a2,a0
around:		  move.l	oldOpenWindow(stuf),a1
		  jsr		(a1)
outwego:	movem.l		(sp)+,a2/stuf
		rts

_WedgeOffs:	dc.w		OWwedge-_beginning


	cnop		0,4
_ending:	dc.l		0		; safety pad

		public		_RDF_MoveByte

_RDF_MoveByte:	move.b		d0,(a3)+	; used with RawDoFmt
		rts

		end
