# Input Handling ## The hardware direct way ### Wait for a mouse click Poll `CIAAPRA` bits 6 and 7. These bits go low when the button is down: http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node012E.html ```asm CIAAPRA EQU $BFE001 .loop: BTST #6,CIAAPRA BEQ .exitLoop BTST #7,CIAAPRA BNE .loop .exitLoop ; stuff ``` ## Using OS routines These are way less hacky, but do require that you allow `INTF_PORTS` interrupts, and also require a good bit more code. ### Wait for a key press or mouseclick This will also remove the key press or mouseclick from the event chain. The InputEvents into the interrupt handler are a linked list, so to remove a node, if `current_node.next_node` returns 0: ```python if has_prior_node: prior_node.next_node = current_node.next_node else: root_node = current_node.next_node ``` ```asm INCLUDE "exec/exec_lib.i" INCLUDE "exec/exec.i" INCLUDE "devices/input.i" INCLUDE "devices/inputevent.i" IECODE_DOWN_CHECK EQU $FF-IECODE_UP_PREFIX _main: BSR startInputHandler .loop TST KeyboardOrMouseButtonDown BEQ .loop BSR stopInputHandler MOVE.L #0,D0 RTS startInputHandler: ; http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_3._guide/node01FC.html MOVE.L 4,A6 CALLLLIB _LVOCreateMsgPort MOVE.L D0,MsgPort ; http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_3._guide/node01FB.html MOVE.L MsgPort.A0 ; http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node0098.html MOVE.L #IOSTD_SIZE,D0 MOVE.L 4,A6 CALLLIB _LVOCreateIORequest MOVE.L D0,InputIO ; http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node0366.html MOVE.L 4,A6 LEA InputDevice,A0 MOVEQ #0,D0 MOVE.L InputIO,D1 MOVEQ #0,D2 CALLLIB _LVOOpenDevice LEA Interrupt,A0 ; there's a Node at the root of the interrupt structure ; http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node0095.html MOVE.B #NT_INTERRUPT,LN_TYPE(A0) MOVE.B #100,LN_PRI(A0) LEA InterruptName,A2 MOVE.L A2,LN_NAME(A0) LEA inputInterruptHandler,A2 MOVE.L A2,IS_CODE(A0) MOVE.L #0,IS_DATA(A0) MOVE.L InputIO,A1 LEA Interrupt,A0 MOVE.L A0,IO_DATA(A1) MOVE.W #IND_ADDHANDLER,IO_COMMAND(A1) MOVE.L 4,A6 CALLLIB _LVODoIO stopInputHandler: MOVE.L InputIO,A1 LEA Interrupt,A0 MOVE.L A0,IO_DATA(A1) MOVE.W #IND_REMHANDLER,IO_COMMAND(A1) MOVE.L 4,A6 CALLLIB _LVODoIO MOVE.L InputIO,A1 MOVE.L 4,A6 CALLLIB _LVOCloseDevice MOVE.L InputIO,A0 MOVE.L 4,A6 CALLLIB _LVODeleteIORequest MOEV.L MsgPort,A0 MOVE.L 4,A6 CALLLIB _LVODeleteMsgPort RTS inputInterruptHandler: MOVEM.L A0-A1,-(SP) ; local storage SUB.L #12,SP MOVE.L A0,(SP) ; event chain start MOVE.L A0,4(SP) ; currentEvent MOVE.L #0,8(SP) ; priorEvent .checkLoop MOVE.L 4(SP),A0 CMP.B #IECLASS_RAWKEY,ie_Class(A0) BNE .checkMouseButton ; is a keyboard event MOVE.W ie_Code(A0),D0 AND.W #IECODE_UP_PREFIX,D0 ; expand zero register result SEQ KeyboardOrMouseButtonDown BRA .maybeRemoveEvent .checkMouseButton CMP.B #IECLASS_RAWMOUSE,ie_Class(A0) BNE .nextEvent MOVE.W ie_Code(A0),D0 AND.W #IECODE_DOWN_CHECK,D0 CMP.W #IECODE_LBUTTON,D0 SEQ KeyboardOrMouseButtonDown .maybeRemoveEvent TST.L 8(SP) BEQ .noPriorEvent ; remove this event from the chain MOVE.L 8(SP),A1 MOVE.L (A0),D0 MOVE.L D0,(A1) BRA .nextEvent .noPriorEvent MOVE.L (A0),D0 BNE .nextEvent ; no next events, we can exit early MOVE.L #0,0(SP) BRA .done .nextEvent MOVE.L A0,8(SP) MOVE.L (A0),A0 MOVE.L A0,4(SP) ; do we have a new current event? BNE .checkLoop .done MOVE.L 0(SP),D0 ADD.L #12,SP MOVEM.L (SP)+,A0-A1 RTS _data: KeyboardOrMouseButtonDown DC.L 0 MsgPort DC.L 0 InputIO DC.L 0 Interrupt DS.B IS_SIZE ```