	       opt	  l+,c+,d+,y+
	       opt	  ow1+,ow2+,ow3+,ow4+,ow5+,ow6+
	       INCDIR	  ":Pspråk/asm/include/"

	       INCLUDE	  "exec/types.i"
	       INCLUDE	  "PopUpMenu.i"

	       xref	 _LinkerDB

	       xref	 @PopUpHandler	    * Inputhandler

	       xref	 @SelectOptions     * Overlay (OldOptions)
					    *		  D2
	       xref	 @GetCommandLine    * Overlay (OldOptions,CommandLine,Length)
					    *		  D3	     A5        D2
	       xref	 @GetWBCommandLine  * Overlay (OldOptions)
					    *		  D3
	       xref	 @MyWrite	    * Overlay (TextNumber, Options)
					    *		  D2	      D3
	       xref	 @PopUpMenu	    * Overlay (MySignals)
					    *		  A3

	       xdef	 @FixDown
	       xdef	 @QueTimer
	       xdef	 @Mystrlen

	       xdef	 _PopUpSemaphore
	       xdef	 _IBase

INPHANDLPRI    EQU	 60	* Should be first in list
POPUPTASKPRI   EQU	 3

	       section	 text,code
Start:	       MOVEM.L	 D2-D7/A2-A6,-(SP)
	       MOVE.L	 A0,A5	       * A5 = Command Line
	       MOVE.L	 D0,D2	       * D2 = Command Length

* ------------ Make room for global data on stack
	       LEA	 -Globals_SIZEOF(SP),SP
	       MOVEA.L	 SP,A4

	       MOVE.L	 (AbsExecBase).W,A6
	       MOVE.L	 A6,(A4)             * Lets hope this is FAST RAM

	       CLR.L	 _WBenchMsg(A4)
	       MOVE.W	 #1,_Error(A4)

* ------------ Open Dos library
	       LEA	 DOSNAME(PC),A1
	       MOVEQ.L	 #LIBVERSION,D0
	       JSR	 _LVOOpenLibrary(A6)
	       MOVE.L	 D0,_DOSBase(A4)     * Checked later

*------------- Get the address of our task
	       MOVE.L	 eb_ThisTask(A6),A3

* ------------ Set task priority
	       MOVEA.L	 A3,A1
	       MOVEQ.L	 #POPUPTASKPRI,D0
	       JSR	 _LVOSetTaskPri(A6)

*------------- Started form CLI ?
	       TST.L   pr_CLI(A3)
	       BNE.B   FromCLI	       * Yes

* ------------ Workbench Startup
* ------------ Wait for startup message.
FromWorkbench: LEA	 pr_MsgPort(A3),A0
	       JSR	 _LVOWaitPort(A6)
	       LEA	 pr_MsgPort(A3),A0
	       JSR	 _LVOGetMsg(A6)
	       MOVE.L	 D0,_WBenchMsg(A4)

* ------------ Dos opened alright ?
FromCLI:       TST.L	 _DOSBase(A4)
	       BEQ.W	 NoDos	       * No

* ------------ See if we are already installed
* ------------ ReplyPort = FindPort(REPLYPORTNAME)
	       LEA	 REPLYPORTNAME(PC),A1
	       JSR	 _LVOFindPort(A6)
	       MOVE.L	 D0,_ReplyPort(A4)

* ------------ ReplyPort == NULL ? [ not installed ]
	       TST.L	 D0
	       BEQ.W	 NotInstalled	  * Yes

* ------------ PopUpMenues already installed, ask running task for options
* ------------ QuitPort = MyCreatePort(QUITPORTNAME)
Installed:     LEA	 QUITPORTNAME(PC),A0
	       JSR	 @MyCreatePort(PC)
	       MOVEA.L	 D0,A2

* ------------ QuitPort == NULL  ?
	       MOVE.L	 A2,D0
	       BEQ.W	 CleanUp13     * Yes

* ------------ Message = BuildIntuiMsg(QuitPort,GETOPTIONS,0)
	       MOVEQ.L	 #GETOPTIONS,D0
	       MOVEQ.L	 #0,D1
	       MOVEA.L	 A2,A0
	       JSR	 @BuildIntuiMsg(PC)
	       MOVEA.L	 D0,A3

* ------------ Message == NULL	?
	       MOVE.L	 A3,D0
	       BEQ.B	 4$

* ------------ PutMsg(ReplyPort,Message)  [ Send message ]
	       MOVEA.L	 _ReplyPort(A4),A0
	       MOVEA.L	 A3,A1
	       JSR	 _LVOPutMsg(A6)

* ------------ WaitPort(QuitPort)  [ Wait for reply ]
	       MOVEA.L	 A2,A0
	       JSR	 _LVOWaitPort(A6)

* ------------ GetMsg(QuitPort)  [ Get the reply ]
	       MOVEA.L	 A2,A0
	       JSR	 _LVOGetMsg(A6)
	       MOVE.W	 im_Code(A3),D0   * Current options

* ------------ Started from CLI ?
	       TST.L	 _WBenchMsg(A4)
	       BNE.B	 2$		  * No

* ------------ Get command line
	       MOVE.W	 D0,D3
	       JSR	 @GetCommandLine

* ------------ Wrong options ?
	       TST.W	 D0
	       BNE.B	 3$	      * No

	       BRA.B	 35$

* ------------ if started from WB just open window
2$	       BSET	 #OPENWINDOW+8,D0

* ------------ Store new option in message
3$	       MOVE.W	 D0,im_Code(A3)

* ------------ if user wants to open window don't output any text
	       BTST	 #OPENWINDOW+8,D0
	       BNE.B	 33$

* ------------ Output exit text ?
	       MOVEQ.L	 #2,D2	       * removed message
	       BTST	 #EXIT+8,D0
	       BNE.B	 32$

	       MOVEQ.L	 #1,D2	       * options message
	       MOVE.L	 D0,D3	       * options

32$	       JSR	 @MyWrite

* ------------ Prepare to send message
33$	       MOVEQ.L	 #NEWOPTIONS,D0
	       MOVE.L	 D0,im_Class(A3)

* ------------ PutMsg(ReplyPort,Message)  [ Send message ]
	       MOVEA.L	 _ReplyPort(A4),A0
	       MOVEA.L	 A3,A1
	       JSR	 _LVOPutMsg(A6)

* ------------ WaitPort(QuitPort)  [ Wait for reply ]
	       MOVEA.L	 A2,A0
	       JSR	 _LVOWaitPort(A6)

* ------------ GetMsg(QuitPort)  [ Get the reply ]
	       MOVEA.L	 A2,A0
	       JSR	 _LVOGetMsg(A6)

* ------------ FreeMem(Message,sizeof(struct IntuiMessage))
35$	       MOVEA.L	 A3,A1
	       MOVEQ.L	 #im_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)

* ------------ MyDeletePort(QuitPort);
4$	       MOVEA.L	 A2,A0
	       JSR	 @MyDeletePort(PC)

	       BRA.W	 NoError

****************************
* PopUpMenu not installed  *
* Start initialization.    *
****************************
* ------------ Default options
NotInstalled:  MOVE.W	 #DEFAULTOPTIONS*256+DEFAULTHOTKEY,D3

* ------------ Running from Workbench ?
	       TST.L	 _WBenchMsg(A4)
	       BEQ.B	 GetCLIArgs

	       JSR	 @GetWBCommandLine
	       BRA.B	 aaaa

* ------------ GetCommandLine(DEFAULT,CommandLine, CommandLength)
GetCLIArgs:    JSR	 @GetCommandLine
aaaa:	       MOVE.W	 D0,_Options(A4)

* ------------ Wrong or help options ?
	       BEQ.W	 NoError	* Yes

	       LEA	 DT,A5	       * Our BSS segment

************************ libraries  ***********************
* ------------ IntuitionBase = OpenLibrary("intuition.library", LIBVERSION)
	       LEA	 INTUITIONNAME(PC),A1
	       MOVEQ.L	 #LIBVERSION,D0
	       JSR	 _LVOOpenLibrary(A6)
	       MOVE.L	 D0,_IntuitionBase(A4)
	       MOVE.L	 D0,_IBase(A5)         * Global intuitionbase

* ------------ IntuitionBase == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp13     * Yes

* ------------ GfxBase = OpenLibrary("graphics.library", LIBVERSION)
	       LEA	 GFXNAME(PC),A1
	       MOVEQ.L	 #LIBVERSION,D0
	       JSR	 _LVOOpenLibrary(A6)
	       MOVE.L	 D0,_GfxBase(A4)

* ------------ GfxBase == NULL	?
	       TST.L	 D0
	       BEQ.W	 CleanUp11     * Yes

* ------------ LayersBase = OpenLibrary("layers.library", LIBVERSION)
	       LEA	 LAYERSNAME(PC),A1
	       MOVEQ	 #LIBVERSION,D0
	       JSR	 _LVOOpenLibrary(A6)
	       MOVE.L	 D0,_LayersBase(A4)

* ------------ LayersBase == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp10

************ Check if user wants to select options ****************
	       MOVE.W	 _Options(A4),D0
	       BTST	 #OPENWINDOW+8,D0
	       BEQ.B	 1$	       * No

	       MOVE.W	 D0,D2
	       JSR	 @SelectOptions
	       MOVE.W	 D0,_Options(A4)

1$	       BTST	 #EXIT+8,D0
	       BEQ.B	 2$

* ------------ Error = FALSE
	       CLR.W	 _Error(A4)
	       BRA.W	 CleanUp9

************************* Signals *******************************
* ------------ MenuUpSigNum = AllocSignal(-1)
2$	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)
	       MOVE.L	 D0,D7

* ------------ MenuUpSigNum < 0  ?
	       BMI.W	 CleanUp9      * Yes

* ------------ MenuDownSigNum = AllocSignal(-1)
	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)
	       MOVE.L	 D0,D6

* ------------ MenuDownSigNum < 0  ?
	       BMI.W	 CleanUp8      * Yes

* ------------ MouseMovedSigNum = AllocSignal(-1)
	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)
	       MOVE.L	 D0,D5

* ------------ MouseMovedSigNum < 0  ?
	       BMI.W	 CleanUp7      * Yes

* ------------ SelectDownSigNum = AllocSignal(-1)
	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)
	       MOVE.L	 D0,D4

* ------------ SelectDownSigNum < 0  ?
	       BMI.W	 CleanUp6      * Yes

* ------------ HotKeySigNum = AllocSignal(-1)
	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)
	       MOVE.L	 D0,D3

* ------------ HotKeySigNum < 0 ?
	       BMI.W	 CleanUp5x5    * Yes

*************** Build connection to the input.device ***************
* ------------ InputDevPort  = MyCreatePort(IMPDEVPORTNAME)
	       LEA	 INPDEVPORTNAME(PC),A0
	       JSR	 @MyCreatePort(PC)
	       MOVEA.L	 D0,A3

* ------------ InputDevPort == NULL  ?
	       MOVE.L	 A3,D0
	       BEQ.W	 CleanUp5      * Yes

* ------------ InputReqBlock = AllocMem(sizeof(struct IOStdReq),MEMF_CLEAR | MEMF_PUBLIC)
	       MOVEQ.L	 #io_SIZEOF,D0
	       MOVE.L	 #MEMF_PUBLIC!MEMF_CLEAR,D1
	       JSR	 _LVOAllocMem(A6)
	       MOVE.L	 D0,_InputReqBlock(A4)

* ------------ InputReqBlock == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp4

* ------------ InputReqBlock->io_Message.mn_Node.ln_Type = NT_MESSAGE;
	       MOVEA.L	 D0,A1
	       MOVE.B	 #NT_MESSAGE,io_Message+mn_Node+ln_Type(A1)

* ------------ InputReqBlock->io_Message.mn_Length = sizeof(struct IOStdReq);
	       MOVE.W	 #$30,io_Message+mn_Length(A1)

* ------------ InputReqBlock->io_Message.mn_ReplyPort = InputDevPort;
	       MOVE.L	 A3,io_Message+mn_ReplyPort(A1)

* ------------ OpenDevice("input.device",0,InputReqBlock,0)
	       LEA	 INPUTNAME(PC),A0
	       MOVEQ.L	 #0,D0
	       MOVEQ.L	 #0,D1
	       JSR	 _LVOOpenDevice(A6)

* ------------ OpenDevice failed  ?
	       TST.L	 D0
	       BNE.W	 CleanUp3      * Yes

****************** Bulid connection to the timer.device ****************
* ------------ TimerPort = MyCreatePort(TIMERPORTNAME)
	       LEA	 TIMERPORTNAME(PC),A0
	       JSR	 @MyCreatePort(PC)
	       MOVE.L	 D0,_TimerPort(A4)

* ------------ TimerPort == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp3x3    * Yes

* ------------ TimerSignal = 1L << TimerPort->mp_SigBit
	       MOVEA.L	 D0,A0
	       MOVEQ.L	 #0,D0
	       MOVE.B	 mp_SigBit(A0),D0
	       MOVEQ.L	 #1,D1
	       ASL.L	 D0,D1
	       MOVE.L	 D1,_TimerSignal(A4)

* ------------ TimerReqBlock = AllocMem(sizeof(struct timerequest),MEMF_CLEAR | MEMF_PUBLIC)
	       MOVEQ	 #tr_SIZEOF,D0
	       MOVE.L	 #MEMF_CLEAR!MEMF_PUBLIC,D1
	       JSR	 _LVOAllocMem(A6)
	       MOVE.L	 D0,_TimerReqBlock(A4)

* ------------ TimerReqBlock == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp3x2    * Yes

* ------------ TimerReqBlock->tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE
	       MOVEA.L	 D0,A1
	       MOVE.B	 #NT_MESSAGE,tr_Node+io_Message+mn_Node+ln_Type(A1)

* ------------ TimerReqBlock->tr_node.io_Message.mn_Length = sizeof(struct timerequest)
	       MOVE.W	 #tr_SIZEOF,tr_Node+io_Message+mn_Length(A1)

* ------------ TimerReqBlock->tr_node.io_Message.mn_ReplyPort = TimerPort;
	       MOVE.L	 _TimerPort(A4),tr_Node+io_Message+mn_ReplyPort(A1)

* ------------ OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerReqBlock,0)
	       LEA	 TIMERNAME(PC),A0
	       MOVEQ.L	 #UNIT_VBLANK,D0
	       MOVEQ.L	 #0,D1
	       JSR	 _LVOOpenDevice(A6)

* ------------ OpenDevice failed  ?
	       TST.L	 D0
	       BNE.W	 CleanUp3x1    * Yes

* ------------ QueTimer()  [ Start timer ]
	       JSR	 @QueTimer(PC)

********************** Make a semaphore for intuition patch ***********************
* ------------ PopUpSemaphore is located in this segment.
* ------------ PopUpSemaphore.ss_Link.ln_Name = /*SEMAPHORENAME*/ NULL
*	       CLR.L	 _PopUpSemaphore+ss_Link+ln_Name(PC)

* ------------ PopUpSemaphore.ss_Link.ln_Pri = 0
	       CLR.B	 _PopUpSemaphore+ss_Link+ln_Pri(A5)

* ------------ InitSemaphore(&PopUpSemaphore)
	       LEA	 _PopUpSemaphore(A5),A0
	       JSR	 _LVOInitSemaphore(A6)

********************** Patch intuition functions to use our semaphore *************
* ------------ OldSetMenuStrip = SetFunction(IntuitionBase,_LVOSetMenuStrip,MySetMenuStrip)
	       LEA	 @MySetMenuStrip(PC),A0
	       MOVE.L	 A0,D0
	       MOVEA.L	 _IntuitionBase(A4),A1
	       MOVEA.W	 #_LVOSetMenuStrip,A0
	       JSR	 _LVOSetFunction(A6)
	       MOVE.L	 D0,_OldSetMenuStrip(A5)

* ------------ OldSetMenuStrip == NULL	?
	       TST.L	 D0
	       BEQ.W	 CleanUp2x4

* ------------ OldClearMenuStrip = SetFunction(IntuitionBase,_LVOClearMenuStrip,MyClearMenuStrip)
	       LEA	 @MyClearMenuStrip(PC),A0
	       MOVE.L	 A0,D0
	       MOVEA.L	 _IntuitionBase(A4),A1
	       MOVEA.W	 #_LVOClearMenuStrip,A0
	       JSR	 _LVOSetFunction(A6)
	       MOVE.L	 D0,_OldClearMenuStrip(A5)

* ------------ OldClearMenuStrip == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp2x3    * Yes

* ------------ OldOnMenu = SetFunction(IntuitionBase,_LVOOnMenu,MyOnMenu)
	       LEA	 @MyOnMenu(PC),A0
	       MOVE.L	 A0,D0
	       MOVEA.L	 _IntuitionBase(A4),A1
	       MOVEA.W	 #_LVOOnMenu,A0
	       JSR	 _LVOSetFunction(A6)
	       MOVE.L	 D0,_OldOnMenu(A5)

* ------------ OldOnMenu == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp2x2    * Yes

* ------------ OldOffMenu = SetFunction(IntuitionBase,_LVOOffMenu,MyOffMenu)
	       LEA	 @MyOffMenu(PC),A0
	       MOVE.L	 A0,D0
	       MOVEA.L	 _IntuitionBase(A4),A1
	       MOVEA.W	 #_LVOOffMenu,A0
	       JSR	 _LVOSetFunction(A6)
	       MOVE.L	 D0,_OldOffMenu(A5)

* ------------ OldOffMenu == NULL  ?
	       TST.L	 D0
	       BEQ.W	 CleanUp2x1

*********************** Input handler *************************
* ------------ Init data for the inputhandler
	       LEA	 -sd_SIZEOF(SP),SP
	       MOVEA.L	 SP,A2

* ------------ InputSignals.Semaphore.ss_Link.ln_Name = NULL
*	       CLR.L	 sd_Semaphore+ss_Link+ln_Name(A2)

* ------------ InputSignals.Semaphore.ss_Link.ln_Pri = 0
	       CLR.B	 sd_Semaphore+ss_Link+ln_Pri(A2)

* ------------ InitSemaphore(&InputSignals.Semaphore)
	       LEA	 sd_Semaphore(A2),A0
	       JSR	 _LVOInitSemaphore(A6)

* ------------ InputSignals.PopUpMenuTask = ExecBase->ThisTask;
	       MOVE.L	 eb_ThisTask(A6),sd_PopUpMenuTask(A2)

* ------------ InputSignals.MenuUpSig = 1 << MenuUpSigNum
	       MOVEQ.L	 #1,D0
	       ASL.L	 D7,D0
	       MOVE.L	 D0,sd_MenuUpSig(A2)

* ------------ InputSignals.MenuDownSig = 1 << MenuDownSigNum
	       MOVEQ.L	 #1,D0
	       ASL.L	 D6,D0
	       MOVE.L	 D0,sd_MenuDownSig(A2)

* ------------ InputSignals.MouseMovedSig = 1 << MouseMovedSigNum
	       MOVEQ.L	 #1,D0
	       ASL.L	 D5,D0
	       MOVE.L	 D0,sd_MouseMovedSig(A2)

* ------------ InputSignals.SelectDownSig = 1 << SelectDownSigNum
	       MOVEQ.L	 #1,D0
	       ASL.L	 D4,D0
	       MOVE.L	 D0,sd_SelectDownSig(A2)

* ------------ InputSignals.HotKeySig = 1 << HotKeySigNum
	       MOVEQ.L	 #1,D0
	       ASL.L	 D3,D0
	       MOVE.L	 D0,sd_HotKeySig(A2)

* ------------ InputSignals.Down = FALSE   [ Menubutton is not down ]
	       CLR.W	 sd_Down(A2)

* ------------ InputSignals.Options = Options
	       MOVE.W	 _Options(A4),sd_Options(A2)

* ------------ Startup the inputhandler
* ------------ struct Interrupt InputReqData
	       LEA	 -is_SIZEOF(SP),SP

* ------------ InputReqData.is_Node.ln_Pri  = INPHANDLPRI [ Must come before intuition ]
	       MOVE.B	 #INPHANDLPRI,is_Node+ln_Pri(SP)

* ------------ InputReqData.is_Node.ln_Name = INPHANDLNAME
	       LEA	 INPHANDLNAME(PC),A1
	       MOVE.L	 A1,is_Node+ln_Name(SP)

* ------------ InputReqData.is_Data = (APTR)&InputSignals
	       MOVE.L	 A2,is_Data(SP)

* ------------ InputReqData.is_Code = PopUpHandler
	       LEA	 @PopUpHandler(PC),A1
	       MOVE.L	 A1,is_Code(SP)

* ------------ InputReqBlock->io_Command = IND_ADDHANDLER
	       MOVEA.L	 _InputReqBlock(A4),A1
	       MOVE.W	 #IND_ADDHANDLER,io_Command(A1)

* ------------ InputReqBlock->io_Data = &InputReqData
	       MOVE.L	 SP,io_Data(A1)

* ------------ DoIO(InputReqBlock)
	       JSR	 _LVODoIO(A6)

***************** Create a reply port for intuimessages *********
* ------------ ReplyPort = MyCreatePort(REPLYPORTNAME)
	       LEA	 REPLYPORTNAME(PC),A0
	       JSR	 @MyCreatePort(PC)
	       MOVE.L	 D0,_ReplyPort(A4)

* ------------ ReplyPort == NULL ?
	       TST.L	 D0
	       BEQ.W	 CleanUp1      * Yes

****************** Everything is OK ***************************
	       CLR.W	 _Error(A4)
	       MOVEQ.L	 #0,D2		 * Installed message
	       JSR	 @MyWrite

* ------------ PopUpMainLoop(&InputSignals)
	       MOVEA.L	 A2,A0
	       JSR	 @PopUpMainLoop(PC)

*********************** Remove Port *****************************
* this must be done first otherwise it is impossible to restart *
* popupmenu if the intuition functions can't be restored        *
*****************************************************************
* ------------ MyDeletePort(ReplyPort)
	       MOVEA.L	 _ReplyPort(A4),A0
	       JSR	 @MyDeletePort(PC)

*********************** Remove inputhandler *********************
* ------------ InputReqBlock->io_Command = IND_REMHANDLER
CleanUp1:      MOVEA.L	 _InputReqBlock(A4),A1
	       MOVE.W	 #IND_REMHANDLER,io_Command(A1)

* ------------ InputReqBlock->io_Data = &InputReqData
	       MOVE.L	 SP,io_Data(A1)

* ------------ DoIO(InputReqBlock)
	       JSR	 _LVODoIO(A6)

	       LEA	 is_SIZEOF+sd_SIZEOF(SP),SP

******************* Restore intuition functions ********************
* ------------ RestoreFunction(IntuitionBase, _LVOOffMenu, OldOffMenu, MyOffMenu)
	       MOVEA.L	 _IntuitionBase(A4),A0
	       MOVE.W	 #_LVOOffMenu,D0
	       MOVEA.L	 _OldOffMenu(A5),A1
	       LEA	 @MyOffMenu(PC),A2
	       JSR	 @RestoreFunction(PC)

* ------------ RestoreFunction(IntuitionBase, _LVOOnMenu, OldOnMenu, MyOnMenu)
CleanUp2x1:    MOVEA.L	 _IntuitionBase(A4),A0
	       MOVE.W	 #_LVOOnMenu,D0
	       MOVEA.L	 _OldOnMenu(A5),A1
	       LEA	 @MyOnMenu(PC),A2
	       JSR	 @RestoreFunction(PC)

* ------------ RestoreFunction(IntuitionBase, _LVOClearMenuStrip, OldClearMenuStrip, MyClearMenuStrip)
CleanUp2x2:    MOVEA.L	 _IntuitionBase(A4),A0
	       MOVE.W	 #_LVOClearMenuStrip,D0
	       MOVEA.L	 _OldClearMenuStrip(A5),A1
	       LEA	 @MyClearMenuStrip(PC),A2
	       JSR	 @RestoreFunction(PC)

* ------------ RestoreFunction(IntuitionBase, _LVOSetMenuStrip, OldSetMenuStrip, MySetMenuStrip)
CleanUp2x3:    MOVEA.L	 _IntuitionBase(A4),A0
	       MOVE.W	 #_LVOSetMenuStrip,D0
	       MOVEA.L	 _OldSetMenuStrip(A5),A1
	       LEA	 @MySetMenuStrip(PC),A2
	       JSR	 @RestoreFunction(PC)

********************* Close timer.device *********************
* ------------ CloseDevice(TimerReqBlock)
CleanUp2x4:    MOVEA.L	 _TimerReqBlock(A4),A1
	       JSR	 _LVOCloseDevice(A6)

* ------------ FreeMem(TimerReqBlock,sizeof(struct timerequest))
CleanUp3x1:    MOVEA.L	 _TimerReqBlock(A4),A1
	       MOVEQ.L	 #tr_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)

* ------------ MyDeletePort(TimerPort)
CleanUp3x2:    MOVEA.L	 _TimerPort(A4),A0
	       JSR	 @MyDeletePort(PC)

********************* Close input.device ***********************
* ------------ CloseDevice(InputReqBlock)
CleanUp3x3:    MOVEA.L	 _InputReqBlock(A4),A1
	       JSR	 _LVOCloseDevice(A6)

* ------------ DeleteStdIO(InputReqBlock)
CleanUp3:      MOVEA.L	 _InputReqBlock(A4),A1
	       MOVEQ	 #io_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)

* ------------ MyDeletePort(InputDevPort)
CleanUp4:      MOVEA.L	 A3,A0
	       JSR	 @MyDeletePort(PC)

*********************** Free allocated signals *************************
CleanUp5:      MOVE.L	 D3,D0
	       JSR	 _LVOFreeSignal(A6)

* ------------ FreeSignal(SelectDownSigNum)
CleanUp5x5:    MOVE.L	 D4,D0
	       JSR	 _LVOFreeSignal(A6)

* ------------ FreeSignal(MouseMovedSigNum)
CleanUp6:      MOVE.L	 D5,D0
	       JSR	 _LVOFreeSignal(A6)

* ------------ FreeSignal(MenuDownSigNum)
CleanUp7:      MOVE.L	 D6,D0
	       JSR	 _LVOFreeSignal(A6)

* ------------ FreeSignal(MenuUpSigNum)
CleanUp8:      MOVE.L	 D7,D0
	       JSR	 _LVOFreeSignal(A6)

********************* Close libraries **************************
* ------------ CloseLibrary(LayersBase)
CleanUp9:      MOVEA.L	 _LayersBase(A4),A1
	       JSR	 _LVOCloseLibrary(A6)

* ------------ CloseLibrary(GfxBase)
CleanUp10:     MOVEA.L	 _GfxBase(A4),A1
	       JSR	 _LVOCloseLibrary(A6)

* ------------ CloseLibrary(IntuitionBase)
CleanUp11:     MOVEA.L	 _IntuitionBase(A4),A1
	       JSR	 _LVOCloseLibrary(A6)

CleanUp13:     TST.W	 _Error(A4)
	       BEQ.B	 NoError
	       MOVEQ.L	 #3,D2		* Error message
	       JSR	 @MyWrite

*********************** Close Dos.library ********************
NoError:       MOVEA.L	 _DOSBase(A4),A1
	       JSR	 _LVOCloseLibrary(A6)

* ------------ Started from Workbench ?
NoDos:	       MOVE.L	  _WBenchMsg(A4),D2
	       BEQ.B	 1$	       * No

	       JSR	 _LVOForbid(A6)
	       MOVE.L	 D2,A1
	       JSR	 _LVOReplyMsg(A6)

* ------------ Remove our data area from stack
1$	       LEA	 Globals_SIZEOF(SP),SP

* ------------ return RETURN_OK
	       MOVEQ.L	 #0,D0

	       MOVEM.L	 (SP)+,D2-D7/A2-A6
	       RTS

INPDEVPORTNAME:  dc.b	  "InpDev",0
TIMERPORTNAME:	 dc.b	  "Timer",0
QUITPORTNAME:	 dc.b	  "Quit",0
REPLYPORTNAME:
INPHANDLNAME:	 dc.b	  "PopUpMenu",0
DOSNAME 	 dc.b	  "dos.library",0
INTUITIONNAME:	 dc.b	  "intuition.library",0
GFXNAME:	 dc.b	  "graphics.library",0
LAYERSNAME:	 dc.b	  "layers.library",0
INPUTNAME:	 dc.b	  "input.device",0
TIMERNAME:	 dc.b	  "timer.device",0

************************************************
* PopUpMainLoop(InputSignals)                  *
*					       *
* Input:				       *
*   InputSignals - Allocated signals.	       *
* Output:				       *
*   none				       *
************************************************
@PopUpMainLoop:
	       MOVEM.L	 D2-D7/A2-A3/A6,-(SP)
	       MOVEA.L	 A0,A3

* ------------ ReplySig = 1 << ReplyPort->mp_SigBit
	       MOVEQ.L	 #0,D0
	       MOVEA.L	 _ReplyPort(A4),A0
	       MOVE.B	 mp_SigBit(A0),D0
	       MOVEQ.L	 #1,D7
	       ASL.L	 D0,D7

* ------------ MenuUpSig = InputSignals->MenuUpSig
	       MOVE.L	 sd_MenuUpSig(A3),D3

* ------------ NrOfMessages = 0
	       MOVEQ.L	 #0,D6

* ------------ Quit = FALSE
	       MOVEQ.L	 #FALSE,D2

* ------------ VerifyOk = FALSE
	       MOVEQ.L	 #FALSE,D5

* ------------ SignalBits = Wait(ReplySig | MenuUpSig | MenuDownSig | HotKeySig)
LoopAgain:     MOVEA.L	 (A4),A6       * SysBase
	       MOVE.L	 D7,D0
	       OR.L	 D3,D0
	       OR.L	 sd_MenuDownSig(A3),D0
	       OR.L	 sd_HotKeySig(A3),D0
	       JSR	 _LVOWait(A6)
	       MOVE.L	 D0,D4

*******************************************
* D0   SignalBits      A3 InputSignals	  *
* D2   Quit	       A6 ExecBase	  *
* D3   MenuUpSig			  *
* D4   SignalBits			  *
* D5   VerifyOk 			  *
* D6.W NrOfMessages			  *
* D7   ReplySig 			  *
*******************************************
* ------------ SignalBits & InputSignals->MenuUpSig ?  [ Menubutton released ]
	       AND.L	 D3,D0
	       BEQ.B	 CheckReply    * No

* ------------ ActiveWindow = NULL  [ To be sure VERIFYOK can't be set ]
	       CLR.L	 _ActiveWindow(A4)

* ------------ VerifyOk = FALSE
	       MOVEQ.L	  #FALSE,D5

* ------------ SignalBits & ReplySig ?
CheckReply:    MOVE.L	 D4,D0
	       AND.L	 D7,D0
	       BEQ.W	 CheckMenuDown * No

* ------------ Message = GetMsg(ReplyPort)
	       MOVE.L	 D7,-(SP)
GetMessage:    MOVEA.L	 _ReplyPort(A4),A0
	       JSR	 _LVOGetMsg(A6)
	       MOVEA.L	 D0,A1

****************************************
* D2   Quit			       *
* D3   MenuUpSig		       *
* D4   SignalBits      A1 Message      *
* D5   VerifyOk        A3 InputSignals *
* D6.W NrOfMessages    A6 ExecBase     *
****************************************
* ------------ Message == NULL ?
	       MOVE.L	 A1,D0
	       BEQ.B	 NoMessages    * Yes

* ------------ New Option message ?
	       MOVE.L	 im_Class(A1),D0
	       BNE.B	 2$	       * No

* ------------ NewOptions = Message->Code
	       MOVE.W	 im_Code(A1),D7

* ------------ ReplyMsg(Message)
	       JSR	 _LVOReplyMsg(A6)

* ------------ HandleNewOpt(NewOptions)
	       MOVE.W	 D7,D0
	       JSR	 HandleNewOpt(PC)

* ------------ Exit ?
	       BTST	 #EXIT,_Options(A4)
	       BEQ.B	 GetMessage    * No

* ------------ Quit = TRUE
	       MOVEQ.L	 #TRUE,D2
	       BRA.B	 GetMessage

* ------------ Asking for options ?
2$	       BTST	 #0,D0
	       BEQ.B	 VerifyMsg	* No

* ------------ Reply current options.
	       MOVE.W	 _Options(A4),im_Code(A1)

* ------------ ReplyMsg(Message)  [Message does not belong to this task]
	       JSR	 _LVOReplyMsg(A6)
	       BRA.B	 GetMessage

* ------------ MENUVERIFY message ?  *************************
VerifyMsg:     BTST	 #13,D0
	       BEQ.B	 GetMessage    * No

* ------------ Message->IDCMPWindow == ActiveWindow ?  [ Only this window can cancel ]
	       MOVEA.L	 im_IDCMPWindow(A1),A0
	       CMP.L	 _ActiveWindow(A4),A0
	       BNE.B	 1$	       * No

* ------------ VerifyOk = TRUE
	       MOVEQ.L	 #TRUE,D5

* ------------ Message->Code == MENUCANCEL ?  [ Cancel menu-operation ]
	       MOVEQ.L	 #MENUCANCEL,D0
	       CMP.W	 im_Code(A1),D0
	       BNE.B	 1$	       * No

* ------------ VerifyOk = FALSE  [ Menues cancelled ]
	       MOVEQ.L	 #FALSE,D5

* ------------ NrOfMessages--
1$	       SUBQ.W	 #1,D6

* ------------ FreeMem(Message,sizeof(struct IntuiMessage))
	       MOVEQ.L	 #im_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)
	       BRA.W	 GetMessage

* ------------ NrOfMessages == 0 ?  [ All windows has replied ]
NoMessages:    MOVE.L	 (SP)+,D7
	       TST.W	 D6
	       BNE.B	 CheckMenuDown	* No

* ------------ Quit == TRUE ?
	       TST.L	 D2
	       BNE.W	 QuitLoop	* Yes

* ------------ VerifyOk == TRUE ?
	       TST.L	 D5
	       BEQ.B	 1$	       * No

* ------------ PopUpMenu(InputSignals)    * (A3)
	       JSR	 @PopUpMenu

* ------------ VerifyOk = FALSE
	       MOVEQ.L	 #FALSE,D5
	       BRA.B	 CheckMenuDown

1$	       MOVEA.L	 A3,A0
	       JSR	 @FixDown(PC)

*******************************************
* D2   Quit	       A3 InputSignals	  *
* D3   MenuUpSig			  *
* D4   SignalBits      A6 ExecBase	  *
* D5   VerifyOk 			  *
* D6.W NrOfMessages			  *
* D7   ReplySig 			  *
*******************************************
* ------------ SignalBits & (MenuUpSig | MenuDownSig) == MenuDownSig) ?
CheckMenuDown: MOVE.L	 sd_MenuDownSig(A3),D0
	       MOVE.L	 D3,D1
	       OR.L	 D0,D1
	       AND.L	 D4,D1
	       CMP.L	 D0,D1
	       BNE.B	 CheckHotKey

* ------------ Lock = LockIBase(0)
	       MOVEQ.L	 #0,D0
	       MOVEA.L	 _IntuitionBase(A4),A6
	       JSR	 _LVOLockIBase(A6)
	       MOVEA.L	 D0,A2

* ------------ ActiveWindow = IntuitionBase->ActiveWindow
	       MOVEA.L	 ib_ActiveWindow(A6),A0
	       MOVE.L	 A0,_ActiveWindow(A4)

* ------------ ActiveWindow == NULL ?  [ No Window is active ]
	       MOVE.L	 A0,D0
	       BEQ.B	 NoMenues1     * Yes

* ------------ ActiveWindow->Flags & RMBTRAP  ?  [ Window doesn't want menues ]
	       BTST	 #0,wd_Flags(A0)          **************************
	       BNE.B	 NoMenues1     * Yes

* ------------ ActiveWindow->MenuStrip == NULL ?  [ Window has no menues ]
	       TST.L	 wd_MenuStrip(A0)
	       BEQ.B	 NoMenues1	* Yes

* ------------ Screen = ActiveWindow->WScreen
	       MOVE.L	 wd_WScreen(A0),_Screen(A4)

* ------------ NrOfMessages = SendMessage()
	       JSR	 @SendMessage(PC)
	       MOVE.W	 D0,D6

* ------------ UnlockIBase(Lock)
	       MOVEA.L	 A2,A0
	       JSR	 _LVOUnlockIBase(A6)

* ------------ NrOfMessages != 0 ?  [ Wait for MENUVERIFY messages ]
	       TST.W	 D6
	       BNE.B	 1$	       * Yes

* ------------ PopUpMenu(InputSignals)    (A3)
	       JSR	 @PopUpMenu
	       BRA.B	 LoopEnd

* ------------ VerifyOk = TRUE
1$	       MOVEQ.L	 #TRUE,D5
	       BRA.B	 LoopEnd

* ------------ UnlockIBase(Lock)
NoMenues1:     MOVEA.L	  A2,A0
	       JSR	 _LVOUnlockIBase(A6)

* ------------ FixDown(InputSignals)    (A3)
	       JSR	 @FixDown(PC)

	       BRA.B	 LoopEnd

* ------------ SignalBits & HotKeySig ?
CheckHotKey:   MOVE.L	 sd_HotKeySig(A3),D0
	       AND.L	 D4,D0
	       BEQ.B	 LoopEnd

* ------------ HendleNewOptions(Options | OPENWINDOW)
	       MOVE.W	 _Options(A4),D0
	       BSET	 #OPENWINDOW+8,D0
	       JSR	 HandleNewOpt(PC)

* ------------ Options & EXIT ?
	       BTST	 #EXIT,_Options(A4)
	       BEQ.B	 LoopEnd       * No

* ------------ Quit = TRUE
	       MOVEQ.L	 #TRUE,D2

* ------------ NrOfMessages == 0 ?
	       TST.W	 D6
	       BEQ.B	 QuitLoop

LoopEnd:       BRA.W	 LoopAgain

QuitLoop:      MOVEM.L	 (SP)+,D2-D7/A2-A3/A6
	       RTS

***************************************
* HandleNewOpt(NewOptions)            *
*  Input			      *
*    NewOptions   Options to check    *
*				      *
* Warning! InputSignals must be in A3 *
*	   and ExecBase in A6	      *
***************************************
HandleNewOpt:  MOVE.W	 D2,-(SP)

* ------------ NewOptions & OPENWINDOW ?
	       BTST	 #OPENWINDOW+8,D0
	       BEQ.B	 1$	       * No

	       MOVE.W	 D0,D2

* ------------ Disable PopUpMenu by Clearing all options
* ------------ Get semaphore
	       LEA	 sd_Semaphore(A3),A0
	       JSR	 _LVOObtainSemaphore(A6)

	       CLR.W	 sd_Options(A3)

* ------------ release semaphore
	       LEA	 sd_Semaphore(A3),A0
	       JSR	 _LVOReleaseSemaphore(A6)

	       JSR	 @SelectOptions

* ------------ Save new options
1$	       MOVE.W	 D0,_Options(A4)

* ------------ Get semaphore
	       LEA	 sd_Semaphore(A3),A0
	       JSR	 _LVOObtainSemaphore(A6)

	       MOVE.W	 D0,sd_Options(A3)

* ------------ release semaphore
	       LEA	 sd_Semaphore(A3),A0
	       JSR	 _LVOReleaseSemaphore(A6)

	       MOVE.W	 (SP)+,D2
	       RTS

**********************************************************
* FixDown(InputSignals)                                  *
*  Stop inputhandler waiting for MENUBUTTON (LICKMENUES) *
**********************************************************
@FixDown:      MOVE.L	 A6,-(SP)
	       MOVE.L	 A2,-(SP)

	       MOVEA.L	 A0,A2
	       MOVEA.L	 (A4),A6       * SysBase

* ------------ Get semaphore
	       LEA	 sd_Semaphore(A2),A0
	       JSR	 _LVOObtainSemaphore(A6)

* ------------ InputSignals.Down &= 1
	       AND.W	 #1,sd_Down(A2)

* ------------ release semaphore
	       LEA	 sd_Semaphore(A2),A0
	       JSR	 _LVOReleaseSemaphore(A6)

	       MOVEA.L	 (SP)+,A2
	       MOVEA.L	 (SP)+,A6
	       RTS

*******************************************************
* SendMessage() - Send MENUVERIFY message             *
*  to all windows on screen with MENUVERIFY flag set. *
*  IBase must be locked!!			      *
* Input:					      *
*   none					      *
* Output:					      *
*   return    - Messages sent. (WORD)                 *
*******************************************************
@SendMessage:  MOVEM.L	 D7/A2-A3/A6,-(SP)

* ------------ NrOfMessages = 0
	       MOVEQ.L	 #0,D7

* ------------ Window = Screen->FirstWindow
	       MOVEA.L	 _Screen(A4),A0
	       MOVEA.L	 sc_FirstWindow(A0),A3

* ------------ Window->IDCMPFlags & MENUVERIFY	?
CheckWindow:   BTST	 #5,wd_IDCMPFlags+2(A3)
	       BEQ.B	 NoMessage     * No

* ------------ Code = (Window == ActiveWindow) ? MENUHOT : MENUWAITING
	       MOVEQ.L	 #MENUHOT,D1
	       CMPA.L	 _ActiveWindow(A4),A3
	       BEQ.B	 1$
	       MOVEQ.L	 #MENUWAITING,D1

* ------------ Message = BuildIntuiMsg(ReplyPort, MENUVERIFY, Code)
1$	       MOVE.L	 #$2000,D0
	       MOVEA.L	 _ReplyPort(A4),A0
	       JSR	 @BuildIntuiMsg(PC)
	       MOVEA.L	 D0,A2

* ------------ Message == NULL ?
	       MOVE.L	 A2,D0
	       BEQ.B	 NoMessage     * Yes

* ------------ CurrentTime(&Message->Seconds,&Message->Micros)
	       LEA	 im_Seconds(A2),A0
	       LEA	 im_Micros(A2),A1
	       MOVEA.L	 _IntuitionBase(A4),A6
	       JSR	 _LVOCurrentTime(A6)

* ------------ Message->IDCMPWindow = Window
	       MOVE.L	 A3,im_IDCMPWindow(A2)

* ------------ PutMsg(Window->UserPort,(struct Message *)Message);
	       MOVEA.L	 wd_UserPort(A3),A0
	       MOVEA.L	 A2,A1
	       MOVEA.L	 (A4),A6     * SysBase
	       JSR	 _LVOPutMsg(A6)

* ------------ NrOfMessages++
	       ADDQ.W	 #1,D7

* ------------ Window = Window->NextWindow
NoMessage:     MOVEA.L	 (A3),A3       * wd_NextWindow

* ------------ Window == NULL ?  [ No more windows to check]
	       MOVE.L	 A3,D0
	       BNE.B	 CheckWindow   * No

* ------------ return (NrOfMessages)
	       MOVE.W	 D7,D0

	       MOVEM.L	 (SP)+,D7/A2-A3/A6
	       RTS

***************************************
* BuildIntuiMsg(ReplyPort,Class,Code) *
*				      *
* Input:			      *
*   ReplyPort			      *
*   Class			      *
*   Code			      *
* Output:			      *
*   return    -  IntuiMessage	      *
***************************************
@BuildIntuiMsg:
	       MOVEM.L	 D6-D7/A2/A6,-(SP)
	       MOVEA.L	 A0,A2
	       MOVE.L	 D0,D7
	       MOVE.L	 D1,D6

	       MOVEA.L	 (A4),A6       * SysBase

* ------------ Message = AllocMem(sizeof(struct IntuiMessage),MEMF_PUBLIC | MEMF_CLEAR)
	       MOVEQ.L	 #im_SIZEOF,D0
	       MOVE.L	 #MEMF_PUBLIC!MEMF_CLEAR,D1
	       JSR	 _LVOAllocMem(A6)
	       MOVEA.L	 D0,A0

* ------------ Message == NULL	?
	       MOVE.L	 A0,D0
	       BEQ.B	 1$	       * Yes

* ------------ Message->ExecMessage.mn_Node.ln_Type = NT_MESSAGE
	       MOVE.B	 #NT_MESSAGE,im_ExecMessage+mn_Node+ln_Type(A0)

* ------------ Message->ExecMessage.mn_ReplyPort = ReplyPort
	       MOVE.L	 A2,im_ExecMessage+mn_ReplyPort(A0)

* ------------ Message->ExecMessage.mn_Length = sizeof(struct IntuiMessage) - sizeof(struct Message);
	       MOVE.W	 #$20,im_ExecMessage+mn_Length(A0)

* ------------ Message->Class = Class
	       MOVE.L	 D7,im_Class(A0)

* ------------ Message->Code  = Code
	       MOVE.W	 D6,im_Code(A0)

* ------------ return (Message)
1$	       MOVEM.L	 (SP)+,D6-D7/A2/A6
	       RTS

******************************************************
* QueTimer() - Queue the timer to go of after 0.2s   *
*						     *
* Input:					     *
*   none					     *
* Output:					     *
*   none:					     *
******************************************************/
@QueTimer:     MOVE.L	 A6,-(SP)

* ------------ TimerReqBlock->tr_node.io_Command = TR_ADDREQUEST
	       MOVEA.L	 _TimerReqBlock(A4),A1
	       MOVE.W	 #TR_ADDREQUEST,IO_COMMAND(A1)

* ------------ TimerReqBlock->tr_time.tv_secs = 0
	       CLR.L	 IOTV_TIME+TV_SECS(A1)

* ------------ TimerReqBlock->tr_time.tv_micro = 200000
	       MOVE.L	 #200000,IOTV_TIME+TV_MICRO(A1)

* ------------ SendIO(TimerReqBlock)
	       MOVEA.L	 (A4),A6       * SysBase
	       JSR	 _LVOSendIO(A6)

	       MOVEA.L	 (SP)+,A6
	       RTS

**************************************************************
* VOID RestoreFunction(Library, Offset,   OldFunc, NewFunc)  *
*			A0	 D0.W	    A1	      A2     *
* Try to restore a function in Library. 		     *
*  (If function can't be retored wait 5s and try again       *
* Input:						     *
*   Library   - Library to change.			     *
*   Offset    - Library function offset  (negative).         *
*   OldFunc   - Function to restore to. 		     *
*   NewFunc   - Function that should be in library.	     *
* Output:						     *
*   none						     *
* Globals used: 					     *
*   _DOSBase(A4)                                             *
**************************************************************
@RestoreFunction:
	       MOVEM.L	  D2-D4/A2/A6,-(SP)
	       MOVE.W	  D0,D2       * Offset
	       MOVE.L	  A1,D3       * OldFunc
	       MOVE.L	  A2,D4       * NewFunc
	       MOVE.L	  A0,A2       * Library

	       MOVEA.L	  _DOSBase(A4),A6

*************************************
* D2 = Offset	      A2 = Library  *
* D3 = OldFunc	      A6 = DOSBase  *
* D4 = NewFunc			    *
*************************************
* ------------ *(Library + Offset + 2) == NewFunc ?
1$	       MOVE.L	  2(A2,D2.W),D0
	       CMP.L	  D4,D0
	       BEQ.B	  2$	       * Yes

* ------------ Wait(256)   ~5s
	       MOVEQ.L	  #1,D1
	       SWAP.W	  D1
	       JSR	  _LVODelay(A6)
	       BRA.B	  1$

* ------------ SetFunction(Library, Offset, OldFunc)
2$	       MOVEA.L	  (A4),A6      * SysBase
	       MOVEA.L	  A2,A1
	       MOVE.W	  D2,A0
	       MOVE.L	  D3,D0
	       JSR	  _LVOSetFunction(A6)

	       MOVEM.L	  (SP)+,D2-D4/A2/A6
	       RTS

********************************************
* MySetMenuStrip, MyClearMenuStrip,	   *
* MyOnMenu, MyOffMenu			   *
*					   *
* My replacements for intuition functions. *
********************************************
@MySetMenuStrip:
	       MOVE.L	  A2,-(SP)
	       MOVEA.L	  _OldSetMenuStrip,A2
	       BRA.B	  CallOldFunction

@MyClearMenuStrip:
	       MOVE.L	  A2,-(SP)
	       MOVEA.L	  _OldClearMenuStrip,A2
	       BRA.B	  CallOldFunction

@MyOnMenu:     MOVE.L	  A2,-(SP)
	       MOVEA.L	  _OldOnMenu,A2
	       BRA.B	  CallOldFunction

@MyOffMenu:    MOVE.L	   A2,-(SP)
	       MOVEA.L	  _OldOffMenu,A2

* ------------ Obtain semaphore and then call the intuition function.
CallOldFunction:
	       MOVE.L	  A6,-(SP)
	       MOVEM.L	  D0/A0-A1/A6,-(SP)
	       LEA	  _PopUpSemaphore,A0
	       MOVE.L	  (AbsExecBase).W,A6
	       JSR	  _LVOObtainSemaphore(A6)
	       MOVEM.L	  (SP)+,D0/A0-A1/A6
	       JSR	  (A2)
	       LEA	  _PopUpSemaphore,A0
	       MOVE.L	  (AbsExecBase).W,A6
	       JSR	  _LVOReleaseSemaphore(A6)
	       MOVE.L	  (SP)+,A6
	       MOVE.L	  (SP)+,A2
	       RTS

*******************************
*  MyCreatePort(Name)         *
*  MyDeletePort(Port)         *
*			      *
*  Replacements for amiga.lib *
*******************************/
@MyCreatePort: MOVE.L	 A6,-(SP)
	       MOVE.L	 A2,-(SP)
	       MOVEA.L	 (A4),A6       * SysBase
	       MOVE.L	 A0,A2

* ------------ Port = AllocMem(sizeof(struct MsgPort),MEMF_CLEAR | MEMF_PUBLIC)
	       MOVEQ.L	 #mp_SIZEOF,D0
	       MOVE.L	 #MEMF_PUBLIC!MEMF_CLEAR,D1
	       JSR	 _LVOAllocMem(A6)
	       MOVE.L	 D0,A0

* ------------ Port == NULL  ?
	       MOVE.L	 A0,D0
	       BEQ.B	 NoPort        * Yes

* ------------ Init port  (Flags = PA_SIGNAL & Pri = 0 not needed -> MEMF_CLEAR)
* ------------ Port->mp_Node.ln_Name = Name
	       MOVE.L	 A2,mp_Node+ln_Name(A0)

* ------------ Port->mp_Node.ln_Type = NT_MSGPORT
	       MOVE.B	 #NT_MSGPORT,mp_Node+ln_Type(A0)

* ------------ Port->mp_SigTask = (struct Task *)FindTask(0)
	       MOVE.L	 eb_ThisTask(A6),mp_SigTask(A0)

* ------------ SigBit = AllocSignal(-1)
	       MOVE.L	 A0,A2
	       MOVEQ.L	 #-1,D0
	       JSR	 _LVOAllocSignal(A6)

* ------------ Port->mp_SigBit = SigBit
	       MOVE.B	 D0,mp_SigBit(A2)

* ------------ SigBit < 0  ?
	       BMI.B	 NoSignal      * Yes

* ------------ AddPort(Port)
	       MOVEA.L	 A2,A1
	       JSR	 _LVOAddPort(A6)

* ------------ return(Port)
	       MOVE.L	 A2,D0
	       BRA.B	 CreateEnd

* ------------ FreeMem(Port,sizeof(struct MsgPort))
NoSignal:      MOVE.L	 A2,A1
	       MOVEQ.L	 #mp_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)

* ------------ return(NULL)
	       MOVEQ.L	 #0,D0
NoPort:
CreateEnd:     MOVE.L	 (SP)+,A2
	       MOVE.L	 (SP)+,A6
	       RTS


@MyDeletePort: MOVE.L	 A3,-(SP)
	       MOVE.L	 A6,-(SP)
	       MOVEA.L	 A0,A3
	       MOVEA.L	 (A4),A6       * SysBase

* ------------ RemPort(Port)
	       MOVEA.L	 A3,A1
	       JSR	 _LVORemPort(A6)

* ------------ FreeSignal(Port->mp_SigBit)
	       MOVEQ.L	 #0,D0
	       MOVE.B	 mp_SigBit(A3),D0
	       JSR	 _LVOFreeSignal(A6)

* ------------ FreeMem(Port,sizeof(struct MsgPort))
	       MOVEA.L	 A3,A1
	       MOVEQ.L	 #mp_SIZEOF,D0
	       JSR	 _LVOFreeMem(A6)
	       MOVE.L	(SP)+,A6
	       MOVE.L	(SP)+,A3
	       RTS

*****************************************************
* ULONG Mystrlen(String) - A short strlen.          *
*						    *
* Input:					    *
*   String   - pointer to a null-terminated string. *
* Output:					    *
*   return   - length of string.		    *
*****************************************************
@Mystrlen:     MOVEQ.L	  #-1,D0
1$:	       ADDQ.L	  #1,D0
	       TST.B	  (A0)+
	       BNE.B	  1$
	       RTS

	       section	  __MERGED,bss
DT:	       EQU	*
_PopUpSemaphore:
	       ds.b	ss_SIZEOF
_OldSetMenuStrip:
	       ds.l	1
_OldClearMenuStrip:
	       ds.l	1
_OldOnMenu:    ds.l	1
_OldOffMenu:   ds.l	1
_IBase:        ds.l	1
	       END






