\ BUTTONAPI.TXT - Improved button processing API

HEX

\ Typical ring buffer implementation. If empty, head
\ is equal to tail. If full, head is one less than
\ tail. Modulo araithmetic is used.

8 CONSTANT b_size \ Size of buffer in cells
0 VALUE    b_head \ Next index to store to
0 VALUE    b_tail \ Next index to read from

\ The switch buffer holds both the switch state and which
\ switches actually changed in the event.

CREATE b_buf
  b_size CELLS 2* ALLOT

\ RCX_BUTTON holds the current switch sample

0 VALUE b_prev    \ Holds the previous switch sample
0 VALUE b_old     \ Holds the oldest stable switch state

: b_put ( state chg -- )
  b_head DUP 1+ 8 MOD DUP
  b_tail =                         \ Check if full...
  IF   2DROP 2DROP                 \ If yes, ignore the event
  ELSE TO b_head CELLS 2* b_buf +  \ If not, store it
       SWAP OVER ! 1 CELLS + !
  THEN ;
  
: BUTTON_SCAN ( -- )
  b_prev DUP RCX_BUTTON
  DUP BUTTON_GET @
  DUP TO b_prev            \ Save the newest sample 
  INVERT XOR 7 AND 7 =     \ Check if all buttons are stable
  IF   DUP b_old XOR ?DUP  \ Check if any buttons changed
       IF   OVER TO b_old  \ Save the stable changed state
            b_put          \ And save the event too
       ELSE DROP
       THEN
  ELSE DROP
  THEN ;

: BUTTON_EVENT? ( -- state chg )
  b_tail DUP b_head =           \ Check if empty
  IF   DROP 0 0                 \ If yes, return 0
  ELSE DUP 1+ 8 MOD TO b_tail   \ Else return event
       CELLS 2* b_buf + DUP
       1 CELLS + @ SWAP @
  THEN ;

\ Improved button processing program

: BUTTON_RUN? ( -- f )
  BUTTON_EVENT? AND 1 AND ;

: BUTTON_VIEW? ( -- f )
  BUTTON_EVENT? AND 2 AND ;

: BUTTON_PRGM? ( -- f )
  BUTTON_EVENT? AND 4 AND ;
