home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
600-699
/
ff667.lha
/
PopUpMenu
/
Source
/
NewStartUp.a
< prev
next >
Wrap
Text File
|
1992-05-21
|
39KB
|
1,374 lines
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