aboutsummaryrefslogtreecommitdiff
path: root/shared/joypad.s
blob: 2abf9592504588857bc5bb3da273f3df7f0b277c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
;;; TODO: safe read

.scope Joypad
    ;; Button masks.
    BUTTON_A      = 1 << 7
    BUTTON_B      = 1 << 6
    BUTTON_SELECT = 1 << 5
    BUTTON_START  = 1 << 4
    BUTTON_UP     = 1 << 3
    BUTTON_DOWN   = 1 << 2
    BUTTON_LEFT   = 1 << 1
    BUTTON_RIGHT  = 1 << 0

    ;; Port addresses for controllers.
    JOYPAD1 = $4016
    JOYPAD2 = $4017

    ;; We keep all the information from controller from mainly two variables:
    ;; m_buttons1 and m_buttons2; containing respectively the buttons pressed
    ;; for this frame for both controllers. The m_inv_buttons ($21) is an
    ;; internal variable and should not be used for anything outside of this
    ;; usage.
    m_inv_buttons = $21
    m_buttons1    = $22
    m_buttons2    = $23

    ;; READ_CONTROLLER reads the input from the controller mapped into the given
    ;; port, and saves the state into the given `buttons` address.
    ;; Implementation taken from NESHacker's example of smb3-like movement.
    .macro READ_CONTROLLER port, buttons
        lda m_inv_buttons
        tay
        lda #1
        sta port
        sta m_inv_buttons
        lsr
        sta port
    :
        lda port
        lsr
        rol m_inv_buttons
        bcc :-
        tya
        eor m_inv_buttons
        and m_inv_buttons
        sta buttons
    .endmacro

    ;; read sets the values for m_buttons1 and m_buttons2 as read from both
    ;; controllers.
    .proc read
        READ_CONTROLLER JOYPAD1, m_buttons1
        READ_CONTROLLER JOYPAD2, m_buttons2
        rts
    .endproc
.endscope