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

snippet.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:

snippet.python
if has_prior_node:
  prior_node.next_node = current_node.next_node
else:
  root_node = current_node.next_node
snippet.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