
		STRUCTURE	ToolTypeHilfe,0
		ULONG	tth_Kennung		; MUSS mit "TTHi" gefüllt werden!
		APTR	tth_WBStartup		; WBStartup oder NULL
		APTR	tth_DirLock		; Lock auf Pfad des Programms (immer gefüllt)
		STRUCT	tth_FileName,32		; Dateiname (immer gefüllt)
		LABEL	tth_SIZEOF

;--------------	DUE TO POPULAR DEMAND: this is the listing of my world-famous
;--------------	"DETACHSTARTUPARGS" macro VERY loosely based upon the XOper
;--------------	startup code (that was years ago, pal, get real!) . However I
;--------------	really won't translate the comments for you, coz I really 
;--------------	got more important things to do. Don't mess around this macro,
;--------------	just use it if you want to...........

;--------------	Startet das Programm wie 'Runback'. 
;--------------	
;--------------	Folgende Daten müssen im Hauptprogramm definiert sein :
;--------------	
;--------------	dosName		dc.b	"dos.library",0
;--------------			even
;--------------	dosBase		dc.l	0
;--------------	
;--------------	Es wird die ToolTypeHilfs-Struktur in TC_Userdata übergeben.
;--------------	Die Einträge my.DirLock und my.FileName werden jetzt immer
;--------------	initialisiert.

DETACHSTARTUPARGS	MACRO	;\1=template,\2=storage,\3=Name des Hauptprogramms,[\4=Stackgröße]

		section	DetachStartupCode,code,chip

;--------------	DOS.Library öffnen
StartupCode	lea	(dosName),a1
		movea.l	(execBase).w,a6
		lea	(LibList,a6),a0
		CALL	FindName
		move.l	d0,(dosBase)

;--------------	Eventuell Message von der Workbench holen
		movea.l	(ThisTask,a6),a4
		tst.l	(pr_CLI,a4)
		bne.b	.notwb
		lea	(pr_MsgPort,a4),a0
		CALL	WaitPort
		lea	(pr_MsgPort,a4),a0
		CALL	GetMsg
		move.l	d0,(wb.msg)
		beq.b	.gomain
		movea.l	d0,a0
		movea.l	(sm_ArgList,a0),a0
		move.l	(wa_Lock,a0),(my.DirLock)	; DirLock
		movea.l	(wa_Name,a0),a0
		lea	(my.FileName),a1
..loop		move.b	(a0)+,(a1)+			; Dateiname kopieren
		bne.b	..loop
.gomain		jmp	MainStartCode

;--------------	NEU: Args vom CLI einlesen
.notwb		move.l	#\1,d1
		move.l	#\2,d2
		moveq	#0,d3
		CALL	ReadArgs,<(dosBase)>
		move.l	d0,(argRdargs)
		bne.b	.FAIL_ARGS
		moveq	#RETURN_ERROR,d0
		rts
.FAIL_ARGS
;--------------	
		link	a5,#-108		; Platz für Dateiname schaffen
		move.l	(pr_CurrentDir,a4),d1
		CALL	CurrentDir
		move.l	d0,d7			; D7: OldCurrentDir
		BMOVE	<(pr_CLI,a4)>,a4
		BMOVE	<(cli_CommandName,a4)>,a1
		movea.l	sp,a0
		moveq	#0,d0
		move.b	(a1)+,d0		; Länge des Namens
		subq.w	#1,d0
		bcs.b	.nullstring
		move.w	d0,d1
.copyname	move.b	(a1)+,(a0)+		; Dateiname kopieren
		dbf	d0,.copyname
.nullstring	clr.b	(a0)			; Nullbyte anhängen
		movea.l	sp,a0
..loop		cmpi.b	#"/",(a0,d1.W)		; Dateiname mit relativem Pfad?
		beq.b	.EinfachLock		; ja, dann gleich Lock()
		cmpi.b	#":",(a0,d1.W)
		beq.b	.EinfachLock		; ja, dann gleich Lock()
		dbf	d1,..loop
		moveq	#ACCESS_READ,d2
		move.l	sp,d1
		CALL	Lock
		move.l	d0,d5			; D5: FileLock
		bne.b	.LockGefunden
		BMOVE	<(cli_CommandDir,a4)>,a4	; Zeiger auf unsere Pfadliste
.PfadDurchgehen	move.l	(4,a4),d1			; d1=Unser Lock
		CALL	CurrentDir
		move.l	sp,d1
		CALL	Lock
		move.l	d0,d5				; D5: FileLock
		bne.b	.LockGefunden
		BMOVE	<(a4)>,a4			; Nächster Lock
 		tst.l	d0				; Gibt es noch einen Lock ?
		bne.b	.PfadDurchgehen			; Ja, weitermachen
		bra	.KeinLock
.LockGefunden	move.l	d0,d1
		CALL	CurrentDir
		move.l	d0,d1
		move.l	d0,d4
		CALL	DupLock				; DirLock duplizieren und
		move.l	d0,(my.DirLock)			; für Hauptprogramm retten
		move.l	d4,d1
		CALL	CurrentDir
		bra.b	.SpeicherFürFIB

;--------------	wenn Programm mit relativem Pfad aufgerufen wurde
.EinfachLock	move.l	d1,d3
		move.l	a0,d1
		moveq	#ACCESS_READ,d2
		CALL	Lock
		move.l	d0,d5				; D5: FileLock
		beq	.KeinLock
		movea.l	sp,a0
		cmp.b	#":",(a0,d3.W)
		bne.b	.pfad
		addq.w	#1,d3				; bei ":" erst dahinter Nullbyte
.pfad		clr.b	(a0,d3.W)
		move.l	a0,d1
		moveq	#ACCESS_READ,d2
		CALL	Lock
		move.l	d0,(my.DirLock)			; DirLock für Hauptprogramm retten
		beq.b	.KeinSpeicher
.SpeicherFürFIB	move.l	#fib_SIZEOF,d0
		move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
		CALL	AllocMem,<(execBase).w>	; RAM für FileInfoBlock
		move.l	d0,d6				; D6: FileInfoBlock
		beq.b	.KeinSpeicher
		move.l	d0,d2
		move.l	d5,d1				; D5: FileLock
		CALL	Examine,<(dosBase)>
		tst.l	d0
		beq.b	.KeinExamine
		move.l	d2,a0
		lea	(my.FileName),a1
		lea	(fib_FileName,a0),a0		; richtiger Dateiname
..loop		move.b	(a0)+,(a1)+			; Dateiname kopieren
		bne.b	..loop
.KeinExamine	move.l	d6,a1				; D6: FileInfoBlock
		move.l	#fib_SIZEOF,d0
		CALL	FreeMem,<(execBase).w>
.KeinSpeicher	move.l	d5,d1				; D5: FileLock
		CALL	UnLock,<(dosBase)>
.KeinLock	move.l	d7,d1				; D7: OldCurrentDir
		CALL	CurrentDir,<(dosBase)>
		unlk	a5

;--------------	SNOOPY addon: keep sticky if argument specified
		tst.l	(argSticky)
		beq.b	.RELEASEME
		jsr	\3	; must use JSR, because target will be another section
		movea.l	(execBase).w,a6
		lea	(dosName),a1
		lea	(LibList,a6),a0
		CALL	FindName
		movea.l	d0,a6
		move.l	(my.DirLock),d1
		beq.b	.NOUNLOCK
		CALL	UnLock
.NOUNLOCK	moveq	#0,d0
		rts
.RELEASEME

;--------------	Adresse dieses Segments holen
		lea	(StartupCode),a1
		move.l	-4(a1),d3
		move.l	d3,(my.seg)

;--------------	Segment des Hauptprogramms freigeben
		move.l	#MainStartCode,d3
		subq.l	#4,d3
		lsr.l	#2,d3
		clr.l	-4(a1)

;--------------	Eigenen Lock duplizieren
		movea.l	(execBase).w,a0
		movea.l	(ThisTask,a0),a0
		move.l	(pr_CurrentDir,a0),d1
		CALL	DupLock,<(dosBase)>
		move.l	d0,(my.currentdir)

;--------------	Neuen Prozess starten
		push	d0
		CALL	Forbid,<(execBase).w>
		move.l	#dummyName,d1
		moveq	#0,d2
		IFEQ	NARG-1
		move.l	#5000,d4
		ELSE
		move.l	#\4,d4
		ENDC
		CALL	CreateProc,<(dosBase)>
		movea.l	d0,a0				; A0 zeigt bereits auf pr_MsgPort
		pop	d0
		move.l	d0,(pr_CurrentDir-pr_MsgPort,a0)
		CALL	Permit,<(execBase).w>
		moveq	#0,d0
		rts

		section	main,code

dummyName	dc.b	"0",0
		even

MainStartCode	movea.l	(execBase).w,a0
		move.l	(ThisTask,a0),a0
		move.l	a0,(my.task)
		move.l	#TTHStruktur,(TC_Userdata,a0)	; Zeiger auf ToolTypeHilfe-Struktur übergeben
		bsr	\3	
		CALL	Forbid,<(execBase).w>
		move.l	(wb.msg),d0
		beq.b	.todos
		movea.l	d0,a1
		CALL	ReplyMsg
		moveq	#0,d0
		rts
.todos		movea.l	(execBase).w,a6
		lea	(dosName),a1
		lea	(LibList,a6),a0
		CALL	FindName
		movea.l	d0,a6
		move.l	(my.DirLock),d1
		CALL	UnLock
		move.l	(my.currentdir),d1
		CALL	UnLock
		move.l	(my.seg),d1
		CALL	UnLoadSeg
		moveq	#0,d0
		rts

my.seg		dc.l	0
my.task		dc.l	0
my.currentdir	dc.l	0
;--------------	Die Reihenfolge aller folgenden Zeiger MÜSSEN mit der
;-------------- oben definierten ToolTypeHilfe-Struktur übereinstimmen!!
TTHStruktur	dc.l	"TTHi"	; Kennung
wb.msg		dc.l	0	; WBStartup oder NULL
my.DirLock	dc.l	0	; Lock auf Pfad des Programms
my.FileName	ds.b	32	; Puffer für Dateiname
		ENDM
