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

AbsExecBase	equ	 4
TRUE		equ	 1
FALSE		equ	 0
KICK204 	equ	 37

;	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

;	Exports
		xdef	    @OpenWindowWithGad
		xdef	    @CloseWindowWithGad
		xdef	    @NewList
		xdef	    @Bin2Hex
		xdef	    @Mystrncpy
		xdef	    _LISTTEXT
		xdef	    _StdFunctions

;	Imports
		xref	    @MainLoop
		xref	    _LinkerDB

		section     text,code
;************************
;* Program entry point	*
;************************
ProgStart:	move.l	    (AbsExecBase).w,A6
		lea	    _LinkerDB,A4

;	Get the address of our task
		move.l	    ThisTask(A6),A5  ; A5 = ThisTask

;	Started form CLI ?
		moveq.l     #0,D0
		tst.l	    pr_CLI(A5)
		bne	    FromCLI	    ; Yes

;	Wait for startup message.
		lea	    pr_MsgPort(A5),A0
		libcall     WaitPort		; (A0=port)

		lea	    pr_MsgPort(A5),A0
		libcall     GetMsg		; (A0=port)

FromCLI:	move.l	    D0,_WBenchMsg-DT(A4)

;	Open Dos library
		lea	    DOSNAME(PC),A1
		moveq.l     #KICK204,D0        ; Need version 2.04
		libcall     OpenLibrary 	; (A1=libname,D0=version)

		move.l	    D0,_DOSBase-DT(A4)
		beq	    NoDos	       ; No dos !!!?

;	Parse arguments
		call	    ParseArgs		; ()

		call	    MainLoop

;	Load A6 since Lattice may destroy it.
		move.l	    (AbsExecBase).W,A6

;	Close dos.library
		move.l	    _DOSBase-DT(A4),A1
		libcall     CloseLibrary

;	 If started from workbench we must reply the message
NoDos:		move.l	    _WBenchMsg-DT(A4),D3
		beq	    NoDos1

		libcall     Forbid		; ()

		move.l	    D3,A1
		libcall     ReplyMsg		; (A1=message)

NoDos1: 	moveq.l     #0,D0
		rts

;************************************************************
;* ParseArgs(VOID)   get user arguments both CLI & WB       *
;*   return    D0 = NOFD, D1 = USEWINDOW		    *
;************************************************************
		STRUCTURE   Args,0
		ULONG	    arg_UseWindow
		ULONG	    arg_NoFD
		LABEL	    arg_SIZEOF

@ParseArgs:	movem.l     D2-D5/A2-A3/A6,-(SP)

;    Workbench or cli arguments ?
		lea	    DefaultArgs(PC),A2
		tst.l	    _WBenchMsg-DT(A4)
		bne	    GetWBArgs

;    Rda = ReadArgs(Template,&DefaultArgs,NULL)
GetCLIArgs:	move.l	    _DOSBase-DT(A4),A6
		lea	    TEMPLATETEXT(PC),A0
		move.l	    A0,D1
		move.l	    A2,D2
		moveq.l     #0,D3
		libcall     ReadArgs

;   FreeArgs(Rda)
		move.l	    D0,D1
		beq	    ArgOK
		libcall     FreeArgs

		bra	    ArgOK

;   Open icon library, any version will do
GetWBArgs:	move.l	    (AbsExecBase).W,A6
		lea	    ICONNAME(PC),A1
		moveq.l     #0,D0
		libcall     OpenLibrary 	; (A1=libName,D0=version)

		move.l	    D0,D3
		beq	    NoIconLib

;    OldCD = CurrentDir(WBenchMsg->sm_ArgList->wa_Lock)
		move.l	    _DOSBase-DT(A4),A6
		move.l	    _WBenchMsg-DT(A4),A3
		move.l	    sm_ArgList(A3),A3
		move.l	    wa_Lock(A3),D1
		libcall     CurrentDir		; (D1=lock)

		move.l	    D0,D4

;    DiskObj = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)
		move.l	    D3,A6	    ; IconBase
		move.l	    wa_Name(A3),A0
		libcall     GetDiskObject	; (a0=name)

		move.l	    D0,D5
		beq	    NoDiskObj

;    ToolTypes = Dobj->do_ToolTypes
		move.l	    D0,A0
		move.l	    do_ToolTypes(A0),A3

;  D3 = IconBase     A2 = DefaultArgs
;  D4 = OldCD	     A3 = ToolTypes
;  D5 = DiskObject   A6 = IconBase

;  Look for Tooltype NOFD
;  DefaultArgs.NoFD = FindToolType(ToolTypes,"NOFD")
		move.l	    A3,A0
		lea	    ARG_NOFD(PC),A1
		libcall     FindToolType

		move.l	    D0,arg_NoFD(A2)

;  Workbench must use own screen.
;  DefaultArgs.UseWindow = TRUE;
		moveq.l     #TRUE,D0
		move.l	    D0,arg_UseWindow(A2)

;  FreeDiskObject(DiskObj)
		move.l	    D5,A0
		libcall     FreeDiskObject

;  if (OldCD)  CurrentDir(OldCD)
NoDiskObj:	move.l	    _DOSBase-DT(A4),A6
		move.l	    D4,D1
		beq	    CloseLib

		libcall     CurrentDir	     ; (D1=lock)

;  CloseLibrary(IconBase)
CloseLib:	move.l	    (AbsExecBase).W,A6
		move.l	    D3,A1
		libcall     CloseLibrary     ; (A1=library)

;  return arguments
ArgOK:
NoIconLib:	move.l	    arg_NoFD(A2),D0
		move.l	    arg_UseWindow(A2),D1

		movem.l     (SP)+,D2-D5/A2-A3/A6
		rts

;********************************************************************
;* OpenWindowWithGad()  - Create gadgets and open the window we use *
;*   return   - Pointer to window structure if everything is OK     *
;********************************************************************
@OpenWindowWithGad:
		movem.l     D2-D3/A2-A3/A5-A6,-(SP)

;   Create local variables
		lea	    -gng_SIZEOF(SP),SP

;   Find the default screen
		move.l	    _IntuitionBase-DT(A4),A6
		lea	    WindowTags(PC),A3     ; A3 = Windowtags
		suba.l	    A0,A0
		libcall     LockPubScreen	  ; (A0=name)

		move.l	    D0,wtag_PubScreen(A3)
		beq	    NoPubScreen

;   Find size of window title bar
		move.l	    D0,A0
		moveq.l     #0,D0
		move.b	    sc_WBorTop(A0),D0
		move.l	    sc_Font(A0),A1
		add.w	    ta_YSize(A1),D0
		addq.w	    #1,D0
		move.w	    D0,gng_TopEdge(SP)

;   Get visual info
		move.l	    _GadToolsBase-DT(A4),A6
		lea	    TagDone(PC),A1
		libcall     GetVisualInfoA	; (A0=screen,A1=taglist)

;   Fill in common stuff into the NewGad structure
		move.l	    D0,gng_VisualInfo(SP)
		move.l	    D0,_VisualInfo-DT(A4)
		beq	    NoVisualInfo

;   Set font = Topaz 8
		lea	    Topaz8Font(PC),A0
		move.l	    A0,gng_TextAttr(SP)

;   ID = 0  [never used]
		clr.w	    gng_GadgetID(SP)

;   TopEdge
		add.w	    #15,gng_TopEdge(SP)

;   Create a context to use
		lea	    wtag_Gadgets(A3),A0
		clr.l	    (A0)
		libcall     CreateContext	; (A0=glistptr)

		move.l	    D0,A0

; First gadget (LISTVIEW)
;   LeftEdge
		move.w	    #7,gng_LeftEdge(SP)

;   Width and height
		move.l	    #$01900090,gng_Width(SP)  ; Both width and height

;   Tags to use
		lea	    ListViewTags(PC),A2

;   Gadget text
		lea	    _LISTTEXT(PC),A1
		move.l	    A1,gng_GadgetText(SP)

		move.l	    SP,A1	       ; A1 = NewGadget

;   Gadget Flags
		moveq.l     #NG_HIGHLABEL,D0
		move.l	    D0,gng_Flags(A1)

;   Create gadget
		moveq.l     #LISTVIEW_KIND,D0
		libcall     CreateGadgetA	; (D0=kind,A0=gad,A1=ng,A2=taglist)

; Second gadget (BUTTON)
;   Gadget Text
		lea	    EXITTEXT(PC),A0
		move.l	    A0,gng_GadgetText(SP)

		move.l	    D0,A0		; Context

;   Left and top
		add.w	    #144,gng_TopEdge(SP)
		move.w	    #168,gng_LeftEdge(SP)

;   Width and height
		move.l	    #$004c000e,gng_Width(SP)

;   Tags
		lea	    ButtonTags(PC),A2

		move.l	    SP,A1	       ; A1 = NewGadget

; Flags
		moveq.l     #PLACETEXT_IN,D0
		move.l	    D0,gng_Flags(A1)

		moveq.l     #BUTTON_KIND,D0
		libcall     CreateGadgetA	; (D0=kind,A0=gad,A1=ng,A2=taglist)

		tst.l	    D0
		beq	    NoGad

;   open window
		move.l	    _IntuitionBase-DT(A4),A6
		suba.l	    A0,A0
		move.l	    A3,A1		; WindowTags
		libcall     OpenWindowTagList	; (A0=newWindow,A1=tagList)

		move.l	    D0,D2

		beq	    NoWindow

;   Draw the gadgets
		move.l	    _GadToolsBase-DT(A4),A6
		move.l	    D0,A0		; Window
		sub.l	    A1,A1
		libcall     GT_RefreshWindow	; (A0=win,A1=req)

		bra	    OpenOk

NoWindow:	move.l	    _GadToolsBase-DT(A4),A6
NoGad:		move.l	    wtag_Gadgets(A3),A0
		libcall     FreeGadgets 	; (A0=gad)

		move.l	    _VisualInfo-DT(A4),A0
		libcall     FreeVisualInfo	; (A0=vi)

NoVisualInfo:	move.l	    wtag_PubScreen(A3),A1
		sub.l	    A0,A0
		move.l	    _IntuitionBase-DT(A4),A6
		libcall     UnlockPubScreen	    ; (A0=name,A1=screen)

NoPubScreen:	moveq.l     #0,D2

OpenOk: 	lea	    gng_SIZEOF(SP),SP

		move.l	    D2,D0
		movem.l     (SP)+,D2-D3/A2-A3/A5-A6
		rts

;*************************************************************************
;* VOID CloseWindowWithGad(Window) - close the window and remove gadgets *
;*************************************************************************
@CloseWindowWithGad:
		move.l	    A2,-(SP)
		move.l	    A6,-(SP)

		move.l	    _IntuitionBase-DT(A4),A6

		lea	    WindowTags(PC),A2

;	Remove the window from the screen
		libcall     CloseWindow 	; (A0=window)

;	Clean up the gadgets
		move.l	    _GadToolsBase-DT(A4),A6
		move.l	    wtag_Gadgets(A2),A0
		libcall     FreeGadgets 	; (A0=gad)

;	No need for the Visual info anymore
		move.l	    _VisualInfo-DT(A4),A0
		libcall     FreeVisualInfo	; (A0=vi)

;	Release the screen
		move.l	    _IntuitionBase-DT(A4),A6
		move.l	    wtag_PubScreen(A2),A1
		sub.l	    A0,A0
		libcall     UnlockPubScreen	; (A0=name,A1=screen)

		move.l	    (SP)+,A6
		move.l	    (SP)+,A2
		rts

;*******************************************************
;* NewList(List)  - replacement for amiga.lib version. *
;*		  - uses register parameters.	       *
;*******************************************************
@NewList:	move.l	    A0,LH_HEAD(A0)
		addq.l	    #4,LH_HEAD(A0)
		clr.l	    LH_TAIL(A0)
		move.l	    A0,LH_TAILPRED(A0)
		rts

;***********************************************************************
;* Bin2Hex(Buffer,Value, Length) - Converts a long to ascii hex string *
;*   Buffer - where to store result.				       *
;*   Value  - Value to convert. 				       *
;*   Length - No of hex digits to use. (max 8)                         *
;*								       *
;* Does not print anything if value == 0			       *
;***********************************************************************
@Bin2Hex:	move.l	    D2,-(SP)
		move.l	    D3,-(SP)

; skip first digits if length < 8
		moveq.l     #8,D2
1$		cmp.w	    D2,D1
		beq.b	    2$

		lsl.l	    #4,D0
		subq.w	    #1,D2
		bra	    1$

; Start with blanks
2$		moveq.l     #FALSE,D2

NextChar:	move.l	    D0,D3
		lsl.l	    #4,D0
		lsr.l	    #8,D3	 ; There must be an
		lsr.l	    #8,D3	 ; easier way to do this
		lsr.l	    #8,D3
		lsr.l	    #4,D3
		bne	    CharFound

;  Have we printed anything yet ?
		tst.w	    D2
		bne	    CharFound

		moveq.l     #' ',D3
		bra	    WriteChar

;  Convert to ASCII
CharFound:	lea	    HEXCHARS(PC),A1
		move.b	    0(A1,D3.W),D3
		moveq.l     #TRUE,D2

WriteChar:	move.b	    D3,(A0)+
		subq.w	    #1,D1
		bne	    NextChar

;  End the string
		move.b	    D1,(A0)
		move.l	    (SP)+,D3
		move.l	    (SP)+,D2
		rts

;*******************************************************
;* ULONG Mystrlen(String) - A short (and fast) strlen. *
;*						       *
;*   String   - pointer to a null-terminated string.   *
;*   return   - length of string. max 32767 chars      *
;*******************************************************
;@Mystrlen:	 moveq.l     #-1,D0
;1$		 tst.b	     (A0)+
;		 dbeq	     D0,1$
;		 neg.l	     D0
;		 subq.l      #1,D0
;		 rts

;**************************************************************
;* Mystrncpy(Dest,Source,Count) - A short (and fast) strncpy  *
;*							      *
;*   Source,Dest  - strings to copy.			      *
;*   Count	  - max length of destination		      *
;**************************************************************
@Mystrncpy:	move.b	    (A1)+,(A0)+
		dbeq	    D0,@Mystrncpy
		rts

;*****************************************************************
;*			   Data area				 *
;*****************************************************************

;    Default arguments (used by ReadArgs)
DefaultArgs:	dc.l	    FALSE	; arg_UseWindow
		dc.l	    FALSE	; arg_NoFD
ICONNAME:	dc.b	    'icon.library',0
		cnop	    0,2
DOSNAME:	dc.b	    'dos.library',0
		cnop	    0,2
TOPAZNAME:	dc.b	    'topaz.font',0
		cnop	    0,2
ARG_NOFD:	dc.b	    'NOFD',0
		cnop	    0,2
TEMPLATETEXT:	dc.b	    'USEWINDOW/S,NOFD/S',0
		cnop	    0,2
HEXCHARS:	dc.b	    '0123456789abcdef'
		cnop	    0,2
_LISTTEXT:	dc.b	    'Offset    Old       New   Name                  ',0
		cnop	    0,2
_StdFunctions:	dc.b	    'Lib_Open',0,0,0,0
		dc.b	    'Lib_Close',0,0,0
		dc.b	    'Lib_Expunge',0
		dc.b	    'Lib_Reserved',0
		cnop	    0,2
EXITTEXT:	dc.b	    'E_xit',0
		cnop	    0,2
WINDOWTITLE:	dc.b	    'ShowPatches 2.0 ',$a9,' 1992 Martin Adrian',0
		cnop	    0,2
		dc.b	    '$VER: ShowPatch 2.0 (3-Oct-92)',0
		cnop	    0,2

WindowIDCMP:	set	    LISTVIEWIDCMP!BUTTONIDCMP!IDCMP_GADGETUP
WindowIDCMP:	set	    WindowIDCMP!IDCMP_CLOSEWINDOW!IDCMP_VANILLAKEY
WindowIDCMP:	set	    WindowIDCMP!IDCMP_REFRESHWINDOW

WindowFlags:	set	    WFLG_DRAGBAR!WFLG_DEPTHGADGET!WFLG_CLOSEGADGET
WindowFlags:	set	    WindowFlags!WFLG_SIMPLE_REFRESH!WFLG_ACTIVATE
WindowFlags:	set	    WindowFlags!WFLG_RMBTRAP

WindowTags:	dc.l	    WA_Left,0
		dc.l	    WA_Top,0
		dc.l	    WA_InnerWidth,405
		dc.l	    WA_InnerHeight,174
		dc.l	    WA_AutoAdjust,TRUE
		dc.l	    WA_IDCMP,WindowIDCMP
		dc.l	    WA_Flags,WindowFlags
		dc.l	    WA_Title,WINDOWTITLE
WPub:		dc.l	    WA_PubScreen,0	; filled in
WGad:		dc.l	    WA_Gadgets,0	; filled in
		dc.l	    TAG_DONE

wtag_Gadgets:	equ	    (WGad-WindowTags)+4
wtag_PubScreen: equ	    (WPub-WindowTags)+4

ListViewTags:	dc.l	     GTLV_Labels,_List
		dc.l	     GTLV_ReadOnly,TRUE
ButtonTags:	dc.l	     GT_Underscore,'_'
TagDone:	dc.l	     TAG_DONE

Topaz8Font:	dc.l	    TOPAZNAME		; ta_Name
		dc.w	    8			; ta_YSize
		dc.b	    FS_NORMAL		; ta_Style
		dc.b	    FPF_ROMFONT 	; ta_Flags

		section     __MERGED,bss
DT		equ	    *

		xdef	    _DOSBase
		xdef	    _Fh
		xdef	    _FDOffset
		xdef	    _GadToolsBase
		xdef	    _IntuitionBase
		xdef	    _List

_DOSBase	ds.l	    1
_Fh		ds.l	    1
_FDOffset	ds.l	    1
_GadToolsBase	ds.l	    1
_IntuitionBase	ds.l	    1
_List		ds.b	    LH_SIZE
_WBenchMsg	ds.l	    1
_VisualInfo	ds.l	    1

		end
