;; 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 "bullets.s" .include "enemies.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 level. We allow the build system to pass its own value for ;; this in `LEVEL`, just in case we want to debug the enemy of a specific ;; level. .ifdef LEVEL lda #LEVEL sta Globals::zp_level and #%00000111 sta Globals::zp_level_kind .else sta Globals::zp_level sta Globals::zp_level_kind .endif ;; 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