.inesprg 1 ; 1x 16KB bank of PRG code .ineschr 1 ; 1x 8KB bank of CHR data .inesmap 0 ; mapper 0 = NROM, no bank swapping .inesmir 1 ; background mirroring (ignore for now) 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 ButtonsHeldLastFrame: = $0000 ButtonsHeldNow: = $0001 MovementDir: = $0002 PlayerYPos: = $0003 PlayerYSubpixelPos: = $0004 PlayerYVel: = $0005 PlayerYSubpixelVel: = $0006 PlayerYAcceleration: = $0D ;;;;;;;;;;;;;; .bank 0 .org $C000 RESET: SEI ; disable IRQs CLD ; disable decimal mode LDX #$40 STX $4017 ; disable APU frame IRQ LDX #$FF TXS ; Set up stack INX ; now X = 0 STX $2000 ; disable NMI STX $2001 ; disable rendering STX $4010 ; disable DMC IRQs vblankwait1: ; First wait for vblank to make sure PPU is ready BIT $2002 BPL vblankwait1 clrmem: LDA #$00 STA $0000, x STA $0100, x STA $0300, x STA $0400, x STA $0500, x STA $0600, x STA $0700, x LDA #$FE STA $0200, x INX BNE clrmem vblankwait2: ; Second wait for vblank, PPU is ready after this BIT $2002 BPL vblankwait2 LoadPalettes: LDA $2002 ; read PPU status to reset the high/low latch LDA #$3F STA $2006 ; write the high byte of $3F00 address LDA #$00 STA $2006 ; write the low byte of $3F00 address LDX #$00 ; start palette address at 0 LoadPalettesLoop: LDA palette, x STA $2007 ; write palette address to PPU INX ; X = X + 1 CPX #$20 ; If X != $20 (decimal 32)... BNE LoadPalettesLoop ; ...loop back to LoadPalettesLoop LoadSprites: LDX #$00 ; start sprite address at 0 LoadSpritesLoop: LDA sprites, x STA $0200, x ; write sprite address into RAM address ($0200 + x) INX ; X = X + 1 CPX #$10 ; If X != $10 (decimal 16)... BNE LoadSpritesLoop ; ...loop back to LoadSpritesLoop LoadBackground: LDA $2002 ; read PPU status to reset the high/low latch LDA #$20 STA $2006 ; write the high byte of $2000 address LDA #$00 STA $2006 ; write the low byte of $2000 address ; Load the empty space on the top 8 rows of the background LDA #$00 ; load tile 0 (blank) LDX #$00 ; start current background tile at 0 LoadEmptySpaceLoop: STA $2007 ; write to PPU INX ; X = X + 1 CPX #$E0 ; If X != $E0 (decimal 240, or 8 rows)... BNE LoadEmptySpaceLoop ; ...loop back to LoadEmptySpaceLoop ; Load the top row of the diagonal square tiles LDX #$00 ; start current background tile at 0 LoadTopRowLoop: LDA bg_top_row, x ; load tile data for top row STA $2007 ; write to PPU INX ; X = X + 1 CPX #$20 ; If X != $20 (decimal 32, or 1 row)... BNE LoadTopRowLoop ; ...loop back to LoadTopRowLoop ; Load the rows of tiling for the diagonal square tiles LDY #$00 ; start at the 0th "row" of tiling ; really, 1 "row" is 2 rows of background LoadTilingRows: LDX #$00 ; start current background tile at 0 LoadTilingLoop: LDA bg_tiling, x ; load tile data for tiling row STA $2007 ; write to PPU INX ; X = X + 1 CPX #$40 ; If X != $40 (decimal 64, or 2 rows) BNE LoadTilingLoop ; ...loop back to LoadTilingLoop ; One "row" of tiling is done being drawn INY ; Y = Y + 1 CPY #$0A ; If Y != $0A (decimal 10, which will draw 10 "rows" of tiling) BNE LoadTilingRows ; ...loop back to LoadTilingRows LoadAttribute: LDA $2002 ; read PPU status to reset the high/low latch LDA #$23 STA $2006 ; write the high byte of $23C0 address LDA #$C0 STA $2006 ; write the low byte of $23C0 address LDA #$00 ; every square in the background will use palette 0 LDX #$00 ; start current attribute byte at 0 LoadAttributeLoop: STA $2007 ; write to PPU INX ; X = X + 1 CPX #$00 ; If X != $00 (decimal 0; done to copy 256 bytes)... BNE LoadAttributeLoop ; ...loop back to LoadAttributeLoop LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1 STA $2000 LDA #%00011110 ; enable sprites, enable background, no clipping on left side STA $2001 MainGameLoop: JMP MainGameLoop ; jump back to MainGameLoop NMI: PHA TXA PHA TYA PHA LDA #$00 STA $2003 ; set the low byte (00) of the RAM address LDA #$02 STA $4014 ; set the high byte (02) of the RAM address, start the transfer JSR ReadJoypad ; read the controller LDA