aboutsummaryrefslogtreecommitdiff
path: root/src/interrupts.s
blob: 8c53af7973b4171ad8ed3192db9ad2e3e769b704 (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
.segment "CODE"

.proc nmi
    ;; Should we skip it?
    bit Globals::zp_flags

    ;; If we are on a dev environment, account for any frame drops.
    .ifdef PARTIAL
        bpl @account_for_frame_drop
    .else
        bpl @end
    .endif

    ;; Save registers.
    pha
    txa
    pha
    tya
    pha

    ;; Sprite DMA.
    lda #$00
    sta OAM::m_address
    lda #$02
    sta OAM::m_dma

    ;; Are we paused? If so skip timers, PAL handler and the likes.
    lda #%00001000
    and Globals::zp_flags
    bne @ppu_registers

    ;; PAL-specific code
    .ifdef PAL
        jsr Driver::pal_handler
    .endif

    ;; TODO: some actions here will depend on the status of the game...
    lda Globals::zp_flags
    and #%00000001
    bne @ppu_registers

    ;; Increase the random seed.
    inc Prng::zp_rand

    ;; Decrease title timer.
    lda Title::zp_title_timer
    beq @ppu_registers
    dec Title::zp_title_timer

@ppu_registers:
    ;; Should we update PPU registers?
    bit Globals::zp_flags
    bvc @scroll

    ;; Zero out the `ppu` flag.
    lda #%10111111
    and Globals::zp_flags
    sta Globals::zp_flags

    bit PPU::m_status

    ;; Update the PPU control/mask registers with shadowed values.
    lda PPU::zp_mask
    sta PPU::m_mask
    lda PPU::zp_control
    sta PPU::m_control

@scroll:
    ;; Always reset the scroll just in case.
    bit PPU::m_status
    lda #$00
    sta PPU::m_scroll
    sta PPU::m_scroll

    ;; Unblock the main code.
    lda #%01111111
    and Globals::zp_flags
    sta Globals::zp_flags

    ;; Restore registers.
    pla
    tay
    pla
    tax
    pla

@end:
    rti

    ;; If we are on a dev environment, account for any frame drops.
.ifdef PARTIAL
@account_for_frame_drop:
    inc Debug::zp_frame_drops
    rti
.endif
.endproc

;; Unused.
.proc irq
    rti
.endproc