;******************************************************************************
;            (C) Copyright 1992-1995, Radius, Inc. and Atari Corp.
; Secret and confidential                                   All rights reserved
;******************************************************************************
; This source code and any compilation or derivative thereof is the joint
; property of Radius, Inc. and Atari Corp.  This code is provided pursuant
; to a Software License Agreement and/or Software Development Contract.  This
; code is the proprietary information of Radius, Inc. and Atari Corp. and is
; confidential in nature.  Its use and dissemination by any party other than
; Atari Corp. are strictly limited by the confidential information provisions
; of the Agreement or Contract referenced above.
;******************************************************************************
; 100 02 Oct 95 JPE     Initial revision.
; 101 24 Oct 95 JPE     Removed GetOption() function. CheckJoy() now aware
;                       of 'remind' flag. AutoJoy() and PathJoy() now work
;                       for all difficulty settings.
; 102 06 Nov 95 JPE     Eliminated GetJoy(), ReadJoy() and GetPause()
;                       functions. Added SampleJoy() routine.
; 103 21 Dec 95 JPE     Made joyTime global.
; 104 14 Feb 96 JPE     Stripped out autoPlay, CheckJoy(), etc.
;******************************************************************************

        .nlist
        .include    'jaguar.inc'
        .include    'params.inc'
        .list

;==============================================================================
;                              SampleJoy
;==============================================================================
;   Samples joypad at ~24 Hz and updates the following locations:
;
;       joySamp: Current encoded reading from joypad
;       joyFall: Mask of negative edges since previous reading
;       joyRise: Mask of positive edges since previous reading
;
;   Output: None.
;==============================================================================

SampleJoy::
        movem.l     d0-d2,-(sp)         ; Save registers

        move.l      time,d0             ; Get current time
        cmp.l       joyTime,d0          ; Time to take a sample?
        blt.s       ExitSample          ; No, bail out

        addi.l      #25,d0              ; Add 1/24 second
        move.l      d0,joyTime          ; Next sample time
        move.b      #$ff,joySemaphore   ; Set semaphore

        bsr         GetAny              ; Current sample in d0
        move.l      joySamp,d1          ; Previous sample in d1
        eor.l       d0,d1               ; Difference mask in d1
        move.l      d1,d2               ; Make a copy in d2
        and.l       d0,d1               ; Mask for rising edges
        eor.l       d1,d2               ; Mask for falling edges
        move.l      d0,joySamp          ; Save current sample
        move.l      d1,joyRise          ; Save rising mask
        move.l      d2,joyFall          ; Save falling mask

.if 0   ;----------------------------------------------------------------------
        .extern     RecordEvent
        move.l      d1,d2               ; d2 = joyRise
        move.l      d0,d1               ; d1 = joySamp
        move.l      #'JSMP',d0          ; Tag
        bsr         RecordEvent         ; Leave crumb
.endif  ;----------------------------------------------------------------------

ExitSample:
        movem.l     (sp)+,d0-d2         ; Restore regsiters
        rts

;==============================================================================
;                                GetAny
;==============================================================================
;   Returns composite reading of all keys on joypad.
;
;   Output:
;           (d0.l):23 = 1 if 'Right' key pressed
;           (d0.l):22 = 1 if 'Left' key pressed
;           (d0.l):21 = 1 if 'Down' key pressed
;           (d0.l):20 = 1 if 'Up' key pressed
;           (d0.l):19 = 1 if '1' key pressed
;           (d0.l):18 = 1 if '4' key pressed
;           (d0.l):17 = 1 if '7' key pressed
;           (d0.l):16 = 1 if '*' key pressed
;           (d0.l):15 = 1 if '2' key pressed
;           (d0.l):14 = 1 if '5' key pressed
;           (d0.l):13 = 1 if '8' key pressed
;           (d0.l):12 = 1 if '0' key pressed
;           (d0.l):11 = 1 if '3' key pressed
;           (d0.l):10 = 1 if '6' key pressed
;           (d0.l):9  = 1 if '9' key pressed
;           (d0.l):8  = 1 if '#' key pressed
;           (d0.l):7  = 1 if 'A' key pressed
;           (d0.l):6  = 1 if 'Pause' key pressed
;           (d0.l):5  = 1 if 'B' key pressed
;           (d0.l):3  = 1 if 'C' key pressed
;           (d0.l):1  = 1 if 'Option' key pressed
;==============================================================================

GetAny::
        movem.l d1-d3/a0-a1,-(sp)       ; Save used registers

        clr.l   d1                      ; Make all zeros
        clr.b   d2                      ; Make all zeros
        move    #4-1,d3                 ; Loop 4 times
        lea     codeTable,a1            ; Start of code table

RowLoop:
        lsl.l   #4,d1                   ; Make room for next data
        lsl.b   #2,d2                   ; Make room for next data

        movea.l #JOYSTICK,a0            ; Address joystick register
        move    (a1)+,(a0)              ; Read specified row
        move    (a0),d0                 ; Read key settings
        andi.l  #$f00,d0                ; Mask off unwanted bits
        eori.l  #$f00,d0                ; Invert bits of interest
        or.l    d0,d1                   ; Or into composite

        movea.l #JOYBUTS,a0             ; Address buttons register
        move    (a0),d0                 ; Read button settings
        andi.b  #3,d0                   ; Mask off unwanted bits
        eori.b  #3,d0                   ; Invert bits of interest
        or.b    d0,d2                   ; Or into composite

        dbra    d3,RowLoop              ; Loop until done

        clr.l   d0                      ; Clear all bits
        or.l    d1,d0                   ; Or in key bits
        or.b    d2,d0                   ; Or in button bits

        movem.l (sp)+,d1-d3/a0-a1       ; Restore used registers
        rts                             ; Exit

codeTable:
        dc.w    $810e                   ; Row 0
        dc.w    $810d                   ; Row 1
        dc.w    $810b                   ; Row 2
        dc.w    $8107                   ; Row 3

;==============================================================================
;                               ClearJoy
;==============================================================================
;   Waits for joypad to clear, with time allowance for key bounce.
;
;   Output: None
;==============================================================================

ClearJoy::
        move.l  d0,-(sp)                ; Save used register

WaitClear:
        bsr     GetAny                  ; Get code in d0
        tst.l   d0                      ; Key pressed?
        bne.s   WaitClear               ; Yes, wait to clear

        bsr     Debounce                ; Wait for key bounce

        move.l  (sp)+,d0                ; Restore used register
        rts                             ; Exit

;==============================================================================
;                              ClearPause
;==============================================================================
;   Waits for pause key to clear, with time allowance for key bounce.
;
;   Output: pauseClear = unmodified if key is not clear
;           pauseClear = 1 if key is clear
;==============================================================================

ClearPause::
        move.l  d0,-(sp)                ; Save used register

        bsr     GetAny                  ; Get code in d0
        btst.l  #bPAUSE,d0              ; Pause key pressed?
        bne.s   ClearExit               ; Yes, wait to clear

        bsr     Debounce                ; Wait for key bounce
        move    #1,pauseClear           ; Set flag

ClearExit:
        move.l  (sp)+,d0                ; Restore used register
        rts                             ; Exit

;==============================================================================
;                               Debounce
;==============================================================================
;   Key debounce routine: delays 0.1 second after key is first cleared.
;
;   Output: None
;==============================================================================

Debounce:
        move.l  d0,-(sp)                ; Save used register

        move.l  time,d0                 ; Get time
        addi.l  #60,d0                  ; Add 0.1 second

ShortWait:
        cmp.l   time,d0                 ; Compare current time
        bge.s   ShortWait               ; Wait for timeout

        move.l  (sp)+,d0                ; Restore used register
        rts

;------------------------------------------------------------------------------
;   Declare storage for flags and variables.
;------------------------------------------------------------------------------

joyTime::       dc.l    0
joySamp::       dc.l    0

        .bss

joyFall::       ds.l    1
joyRise::       ds.l    1

;------------------------------------------------------------------------------
;   Declare externals.
;------------------------------------------------------------------------------

        .extern pauseClear
        .extern time
        .extern joySemaphore

