		include     "all.i"
		include     "exec/types.i"

AbsExecBase	equ	    4
KICK12		equ	    33

;	Call a library function (Base in A6)
libcall 	macro
		jsr	_LVO\1(A6)
		endm

;	Call a c (or assembler function)
call		macro
		bsr	@\1
		endm

;    Imports
		xref	    _LinkerDB
		xref	    @NewSetFunction
		xref	    @MakeHead
		xref	    @FindPatches

		section     Startup,code
Startup:	move.l	    (AbsExecBase).W,A6
		moveq.l     #0,D4

;	Get pointer to our Process.
		move.l	    ThisTask(A6),A4

;	Run from Workbench ?
		tst.l	    pr_CLI(A4)
		bne	    FromCLI	       ; No

;	Wait for Workbench startup-message.
		lea	    pr_MsgPort(A4),A0
		libcall     WaitPort
		lea	    pr_MsgPort(A4),A0
		libcall     GetMsg
		move.l	    D0,D4

;	Open dos. (Will not be closed, our function uses it)
FromCLI:	lea	    _LinkerDB,A4
		lea	    DOSNAME(PC),A1
		moveq.l     #KICK12,D0
		libcall     OpenLibrary
		move.l	    D0,(A4)          ; _DOSBase

		beq	    NoDos

;	Are we already installed ?
		jsr	    @FindPatches      ; cant use pc-rel
		tst.l	    D0
		beq	    FirstTime
		lea	    INSTALLED(PC),A0
		moveq.l     #INSTALL_sizeof,D3
		call	    PrintMes
		bra	    NoHead

;	Init Semaphore
FirstTime:	lea	    _SetFuncSemaphore-DT(A4),A0
		libcall     InitSemaphore

;	Create the list header
		sub.l	    A0,A0
		jsr	    @MakeHead	     ; can't use pc-rel here
		move.l	    D0,_MainHeader-DT(A4)
		beq	    NoHead

;	Patch SetFunction
		move.l	    #_LVOSetFunction,A0
		move.l	    A6,A1
		move.l	    #@NewSetFunction,D0
		jsr	    0(A6,A0.W)            ; SetFunction
		move.l	    D0,_OldSetFuncPtr-DT(A4)
		beq	    NoPatch	       ; oops !

;	Output message
		lea	    MESSAGE(PC),A0
		moveq.l     #MESSAGE_sizeof,D3
		call	    PrintMes

;	Remove segments from list.
		lea	    Startup-4(PC),A0
		clr.l	    (A0)
		bra	    Started

NoPatch:	move.l	    _MainHeader-DT(A4),A1
		moveq.l     #12,D0	       ; Header size
		libcall     FreeMem

NoHead: 	move.l	    (A4),A1            ; _DOSBase
		libcall     CloseLibrary

;	Started from WB ?
Started:	tst.l	    D4
		beq.b	    Done	       ; No

;	Forbid so Workbench can't unload us before we are done.
		move.l	    (AbsExecBase).W,A6
		libcall     Forbid
		move.l	    D4,A1
		libcall     ReplyMsg
Done:
NoDos:		moveq.l     #0,D0
		rts

;	Output a message.
@PrintMes:	move.l	    A0,D2
		move.l	    (A4),A6            ; DOSBase
		libcall     Output
		move.l	    D0,D1
		beq	    NoStdout

;	Output message
		libcall     Write
NoStdout:	rts

		dc.b	    '$VER: SaferPatches 2.0 (3-Oct-92)',$0
DOSNAME:	dc.b	    'dos.library',0
MESSAGE:	dc.b	    $9b,'0;33m','Saferpatches',$9b,'0m installed',$a
		dc.b	    '© Martin Adrian 1992',$a
MESSAGE_sizeof	equ	    *-MESSAGE
INSTALLED:	dc.b	    $9b,'0;33m','SaferPatches',$9b,'0m already installed.',$a
INSTALL_sizeof	equ	    *-INSTALLED


		section     text,code
		xdef	    @OldSetFunction

@OldSetFunction:
		move.l	    A2,-(SP)
		move.l	    A6,-(SP)
		move.l	    (AbsExecBase).W,A6
		move.l	    _OldSetFuncPtr-DT(A4),A2   ; its safe to use A4 here
		jsr	    (A2)
		move.l	    (SP)+,A6
		move.l	    (SP)+,A2
		rts

		section     __MERGED,bss
		xdef	    _DOSBase
		xdef	    _MainHeader
		xdef	    _OldSetFuncPtr
		xdef	    _SetFuncSemaphore
DT		equ	    *
_DOSBase	ds.l	    1
_MainHeader	ds.l	    1
_OldSetFuncPtr	ds.l	    1
_SetFuncSemaphore: ds.b      SS_SIZE
		end

;		 xref	     _OldSetFuncPtr
;		 xref	     _DOSBase
;		 xref	     _SetFuncSemaphore
;		 xref	     _MainHeader
;		 end

