home *** CD-ROM | disk | FTP | other *** search
- TTL MiddleButton
- *
- *******************************************************************************
- * *
- * MiddleButton *
- * *
- * Copyright (c) 1989 by Michael Sinz MKSoft Development *
- * *
- * AmigaDOS EXEC release 1.2 or greater... *
- * *
- *******************************************************************************
- * *
- * To assemble, I used the assembler that comes with MANX C68K *
- * *
- * It should assemble without any problems on most 680x0 assemblers *
- * The code is position independant and thus needs an assembler that *
- * can produce such files. *
- * *
- *******************************************************************************
- * *
- * This program installs a handler into the input food chain. *
- * The handler converts the middle mouse button (for those of you *
- * with such animals) into a shift key for all mouse events. *
- * *
- * Thus, when you hold the middle button down, you can "SHIFT-SELECT" *
- * using just the mouse. Some programs also give you an extended *
- * select mode when you click the mouse and push the shift key. *
- * Only mouse events are modified to have the shift key qualifier. *
- * *
- * When you run this program, it will take 80 bytes of system memory *
- * to install and link in the handler code. It then exits... *
- * *
- *******************************************************************************
- *
- * The following INCLUDE files are needed to make this program assemble.
- * They come with the Amiga Macro-Assembler Package.
- *
- NOMLIST ; No macro expansion list
- NOCLIST ; No conditional list
- NOLIST ; No need to list these
- INCLUDE "EXEC/Types.i"
- INCLUDE "EXEC/Libraries.i"
- INCLUDE "EXEC/Interrupts.i"
- INCLUDE "EXEC/Memory.i"
- INCLUDE "EXEC/IO.i"
- INCLUDE "EXEC/Ables.i"
- INCLUDE "Libraries/DOSextens.i"
- INCLUDE "Devices/Input.i"
- INCLUDE "Devices/InputEvent.i"
- LIST ; Ok, lets start the listing
- *
- *******************************************************************************
- *
- * This is the only fixed address in the system and it even "floats"...
- *
- xref _AbsExecBase
- *
- *******************************************************************************
- *
- * Some macros that make calling the system routines easier...
- *
- CALLSYS MACRO
- xref _LVO\1 ; Set the external reference
- CALLLIB _LVO\1 ; Call the EXEC definied macro
- ENDM
- *
- *******************************************************************************
- * *
- * Register usage through this system... *
- * *
- * a0 - Scrap *
- * a1 - Scrap *
- * a2 - IO Block *
- * a3 - MsgPort *
- * a4 - Task *
- * a5 - New Memory *
- * a6 - ExecBase pointer *
- * a7 - Stack pointer... What else? *
- * *
- * d0 - Scrap *
- * d1 - Scrap *
- * d2 - Scrap *
- * d3 - Scrap *
- * d4 - Scrap *
- * d5 - Scrap *
- * d6 - Scrap *
- * d7 - Zero... *
- * *
- *******************************************************************************
- *
- * Now, for the start of the code...
- *
- MiddleButton: move.l _AbsExecBase,a6 ; Get the EXEC library base
- *
- clr.l d7 ; Clear d7...
- *
- move.l d7,a1 ; Clear a1
- CALLSYS FindTask ; Get our task pointer...
- move.l d0,a4 ; Now, move it to a1 for addressing use
- lea pr_MsgPort(a4),a3
- tst.l pr_CLI(a4) ; Check if this is a CLI task...
- bne.s QuickCLI ; If so, skip the next section
- *
- *******************************************************************************
- *
- * This section deals with starting from the WorkBench...
- * It is just here for completeness...
- *
- QuickWorkBench: move.l a3,a0 ; Get message port
- CALLSYS WaitPort ; Wait for the WorkBench message...
- move.l a3,a0 ; ...it's here, so let's get it
- CALLSYS GetMsg ; off the message port...
- bra.s QuickCont ; ...and go to the continue routine
- *
- *******************************************************************************
- *
- * The routine was started from the CLI (prefered)
- * Let's store a NULL pointer so that there is no WB message...
- *
- QuickCLI: move.l d7,d0 ; No reply message...
- *
- *******************************************************************************
- *
- * Continue with the Quick initialization
- *
- QuickCont:
- move.l d0,-(sp) ; Save the message pointer...
- *
- lea InputBlock(pc),a2 ; Get the I/O block
- move.b #NT_MESSAGE,LN_TYPE(a2) ; initialize it...
- move.w #IOSTD_SIZE,MN_LENGTH(a2)
- move.l a3,MN_REPLYPORT(a2) ; Our reply port...
- *
- lea inputName(pc),a0 ; Get input.device name
- move.l d7,d0 ; Clear d0
- move.l d7,d1 ; and d1
- move.l a2,a1
- CALLSYS OpenDevice ; a1 is still set to the I/O block
- tst.l d0
- bne.s abortNoInput
- *
- *******************************************************************************
- *
- * We now allocate and copy the handler...
- *
- move.l #CodeSize,d0 ; Size of memory
- move.l d0,d6 ; Save it...
- move.l #MEMF_PUBLIC,d1 ; Type of memory
- CALLSYS AllocMem ; Get the memory
- move.l d0,a5 ; Save it...
- tst.l d0 ; Check it...
- beq.s NormalExit ; No memory, no copy...
- move.l d0,a1 ; Destination...
- lea StartOfCode(pc),a0 ; Source
- CopyLoop: move.b (a0)+,(a1)+ ; Copy it...
- dbra d6,CopyLoop ; All of it...
- *
- *******************************************************************************
- *
- * We also need to add our own input handler into the food chain...
- *
- move.l a5,a0 ; Start of new code...
- add.l #HandlerOffset,a0 ; Pointer to handler
- move.b #60,LN_PRI(a0) ; Handler priority
- move.l a5,IS_DATA(a0) ; Handler data
- addq.l #2,a5 ; Point to code...
- move.l a5,IS_CODE(a0) ; Handler code
- move.l a2,a1 ; Get i/o block
- move.l a0,IO_DATA(a1) ; Set the data address...
- move.w #IND_ADDHANDLER,IO_COMMAND(a1) ; the ADD command...
- CALLSYS DoIO ; All set, handler is running
- *
- *******************************************************************************
- *
- * The standard exit routines...
- * Close anything that we have opened...
- *
- NormalExit:
- move.l a2,a1 ; Get I/O block...
- CALLSYS CloseDevice ; Close the thing...
- abortNoInput:
- move.l (sp)+,d0 ; Get that message back
- beq.s abortNoWB ; If none, we are done
- move.l d0,a1 ; Get the pointer ready
- FORBID ; manual says we must forbid...
- CALLSYS ReplyMsg ; ...when returning WB message
- abortNoWB:
- rts ; RTS out of this task...
- *
- *******************************************************************************
- *
- * The input block...
- *
- InputBlock: ds.b IOSTD_SIZE
- *
- *******************************************************************************
- *
- * This is the mouse accel value...
- *
- StartOfCode: dc.w 0 ; Flag value for shift key...
- *
- *******************************************************************************
- *
- * This is the handler... It is the hardest working piece of code here...
- *
- MyHandler: move.l a0,-(sp) ; We MUST save what we play with...
- *
- *******************************************************************************
- *
- * Now, for the handler loop... We will look at every event that has been given
- * to us.
- *
- HandlerLoop: cmpi.b #IECLASS_RAWMOUSE,ie_Class(a0) ; Check for mouse...
- bne.s HandlerNext ; If skip it...
- *
- * if IECODE_MBUTTON... IECODE_UP_PREFIX...
- move.w ie_Code(a0),d0 ; Get code...
- cmpi.w #IECODE_MBUTTON,d0 ; Check if button is pushed...
- bne.s NotDown ; Middle button not down...
- *
- move.w #IEQUALIFIER_LSHIFT,(a1) ; Store the left shift
- bra.s HandlerCont ; and continue
- *
- NotDown: cmpi.w #(IECODE_MBUTTON+IECODE_UP_PREFIX),d0 ; Button up?
- bne.s HandlerCont ; If not, skip
- clr.w (a1) ; Clear code...
- *
- HandlerCont: move.w ie_Qualifier(a0),d0 ; Get qualifier...
- or.w (a1),d0 ; or in the shift value...
- move.w d0,ie_Qualifier(a0) ; Store it...
- *
- HandlerNext:
- move.l ie_NextEvent(a0),d0 ; Get next event...
- move.l d0,a0
- bne.s HandlerLoop ; Go back and do this one...
- *
- move.l (sp)+,d0 ; Restore our stuff... d0=a0...
- rts ; Done with handler...
- *
- *******************************************************************************
- *
- HandlerInfo: ds.b IS_SIZE ; The handler structure...
- EndOfCode:
- CodeSize EQU EndOfCode-StartOfCode
- HandlerOffset: EQU HandlerInfo-StartOfCode
- *
- *******************************************************************************
- *
- * The data section...
- *
- inputName dc.b 'input.device',0
- *
- *******************************************************************************
- *
- * And, with that we come to the end of another full-length feature staring
- * that wonderful MC680x0 and the Amiga system. Join us again next time
- * for more Wonderful World of Amiga... Until then, keep boinging...
- *
- end
-