aboutsummaryrefslogtreecommitdiff
path: root/src/jetpac.s
blob: 10f6df3c31f3ed49a0e88cf2be3567fa0ed121f2 (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
129
130
131
132
133
134
;; NOTE: automatically generated by the build system.
.include "../config/generated.s"

.segment "HEADER"
    ;; Bytes 0-3: NES\0 magic header.
    .byte 'N', 'E', 'S', $1A

    ;; Standard 32KB + 8KB NROM cartridge.
    .byte $02, $01

    ;; Horizontal mirroring, no battery.
    .byte $00

    ;; We use the NES 2.0 header mainly to differentiate between NTSC vs PAL in
    ;; a way that emulators won't ignore it.
    .byte $08

    ;; Blanked out stuff.
    .res $04, $00

    ;; NTSC vs PAL
    .ifdef PAL
        .byte $01
    .else
        .byte $00
    .endif

    ;; Blanked out stuff.
    .res $03, $00

.segment "CODE"

.include "../include/apu.s"
.include "../include/oam.s"
.include "../include/ppu.s"
.include "../include/asm.s"
.include "../include/joypad.s"
.include "../include/globals.s"

.include "assets.s"
.include "background.s"
.include "player.s"
.include "title.s"
.include "driver.s"
.include "vectors.s"

.proc main
    ;; Disable the PPU and zero out variables which shadow PPU registers.
    lda #0
    sta PPU::MASK
    sta PPU::zp_mask
    sta PPU::zp_control

    ;; Initialize other global variables which the rest of the game assume to
    ;; have zero as their initial values.
    sta Globals::zp_flags
    sta Joypad::zp_buttons1
    sta Joypad::zp_buttons2

    ;; Initialize the assets for the game.
    jsr Assets::init

    ;; Initialize some PAL-specific constants.
    .ifdef PAL
        lda #0
        sta Driver::zp_pal_counter
    .endif

    ;; We shadow the PPU control register in memory. Depending on the `make`
    ;; target we might need to switch directly to the main game. Otherwise we go
    ;; into the title as expected.
    .ifdef PARTIAL
        jsr Driver::switch

        lda PPU::zp_control
        sta PPU::CONTROL
    .else
        jsr Title::init

        lda #%10001000
        sta PPU::zp_control
        sta PPU::CONTROL
    .endif

    cli

    ;; Enable back the PPU
    lda #%00011110
    sta PPU::zp_mask
    sta PPU::MASK

@main_game_loop:
    READ_JOYPAD1

    lda Globals::zp_flags
    and #%00000011
    beq @title_screen
    cmp #1
    beq @game_screen
    jmp @over

@title_screen:
    ;; If we are in a transitioning state, avoid the update from the title.
    lda Globals::zp_flags
    and #%00000100
    bne @do_switch

    jsr Title::update
    beq @set_flags

@do_switch:
    ;; Start was pressed by the player, switch to the main game.
    jsr Driver::switch
    jmp @set_flags

@game_screen:
    jsr Driver::update
    ;; NOTE: fallthrough

@set_flags:
    lda #%10000000
    ora Globals::zp_flags
    sta Globals::zp_flags
@wait_for_render:
    bit Globals::zp_flags
    bmi @wait_for_render

    ;; Rendering is done, we can perform another iteration of the loop!
    jmp @main_game_loop

@over:
    ;; TODO: allow to start over, reset flags, control register, etc.
    jmp @over
.endproc