aboutsummaryrefslogtreecommitdiff
path: root/tests/runrom/branching.s
blob: a96888c49d0a02d218f2df20d987abac363db974 (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.segment "HEADER"
    .byte 'N', 'E', 'S', $1A
    .byte $02, $01
    .byte $00
    .byte $00

.segment "CHARS"
.byte 0

.segment "VECTORS"
    .addr reset, reset, reset

.segment "CODE"
;; asan:stack full

;; From: https://git.mssola.com/nes/jetpac.nes/.
.scope Globals
    ;; | Bit | Short name       | Meaning                  |
    ;; |-----+------------------+--------------------------|
    ;; |   7 | enabled          | Multiplayer enabled.     |
    ;; | 6-3 | -                | Unused.                  |
    ;; |   2 | player's 2 state | 0: over; 1: alive        |
    ;; |   1 | player's 1 state | 0: over; 1: alive        |
    ;; |   0 | active           | 0: player 1; 1: player 2 |
    zp_multiplayer = $27

    ;; Extra bitmap that was needed beyond the ones that we already have. Yeah,
    ;; I know, bad planning from my side, but now it's a bit complex to untangle
    ;; variables like 'Globals::zp_flags'.
    ;;
    ;; | Bit | Short name       | Meaning                          |
    ;; |-----+------------------+----------------------------------|
    ;; |   7 | score            | The score has been updated.      |
    ;; |   6 | high             | The high score has been updated. |
    ;; | 5-0 | -                | Unused.                          |
    zp_extra_flags = $28
.endscope

;; From: https://git.mssola.com/nes/jetpac.nes/.
.scope Score
    ;; Scores for both players are stored in a single buffer. Even indeces
    ;; contain digits for the first player, and odd indeces contain digits for
    ;; the second player. Digits are stored in little-endian format.
    ;;
    ;; Interweaving digits this way might seem weird, but it actually makes
    ;; indexing things super easy: the 'active' bit from
    ;; 'Globals::zp_multiplayer' can be used to index the first item, and then
    ;; it's a matter of advancing the 'x' register twice in order to get the
    ;; next digit.
    PLAYERS_BUFF_SIZE = $0C
    m_players = $300     ; asan:reserve PLAYERS_BUFF_SIZE

    ;; The high score for this session.
    m_hi = $30C           ; asan:reserve $06
.endscope

;; This is basically Score::save_hi_score() from
;; https://git.mssola.com/nes/jetpac.nes/.
.proc reset
    ;;;
    ;; Check player 1.

    ldx #(Score::PLAYERS_BUFF_SIZE - 2)
    ldy #5

@player1_loop:
    lda Score::m_hi, y
    cmp Score::m_players, x
    bcc @save_player1
    dex
    dex
    dey
    cpy #$FF
    bne @player1_loop

    ;; No dice! If we are in multiplayer mode, then check player 2,
    ;; otherwise just quit.
    bit Globals::zp_multiplayer
    bpl @end

    ;;;
    ;; Check player 2.

    ldx #(Score::PLAYERS_BUFF_SIZE - 1)
    ldy #5

@player2_loop:
    lda Score::m_hi, y
    cmp Score::m_players, x
    bcc @save_player2
    dex
    dex
    dey
    cpy #$FF
    bne @player2_loop

    ;; Not player 2 either. Just quit.
    rts

    ;;;
    ;; One of the players actually achieved a high score. Let's save it.

@save_player1:
    ldx #0
    beq @save
@save_player2:
    ldx #1

@save:
    ldy #0
@save_loop:
    lda Score::m_players, x
    sta Score::m_hi, y

    inx
    inx
    iny
    cpy #6
    bne @save_loop

    ;; And set the 'high' bit so this change is reflected on screen.
    lda Globals::zp_extra_flags
    ora #$40
    sta Globals::zp_extra_flags

@end:
    rts
.endproc