Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .segment "HEADER"
- .byte "NES", $1A ; iNES header identifier
- .byte 8 ; UNROM has 8 16k banks
- .byte 0 ; UNROM uses CHR-RAM, so no CHR-ROM
- .byte $20, $00 ; UNROM is Mapper 2
- .byte $00 ; UNROM has no PRG RAM
- .segment "CODE"
- reset:
- sei ; Ignore 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
- ; Clear the VBLANK flag so we know that we are waiting for the
- ; start of a vertical blank and not powering on with the
- ; VBLANK flag spuriously set
- bit $2002
- ; First of two waits for vertical blank to make sure that the
- ; PPU has stabilized
- @vblankwait1:
- bit $2002
- bpl @vblankwait1
- ; We now have about 30,000 cycles to burn before the PPU stabilizes.
- ; One thing we can do with this time is put RAM in a known state.
- ; Here we fill it with $00, which matches what (say) a C compiler
- ; expects for BSS. Conveniently, X is still 0.
- txa
- @clrmem:
- sta $0000, x
- sta $0100, x
- sta $0300, x
- sta $0400, x
- sta $0500, x
- sta $0600, x
- sta $0700, x ; Remove this if you're storing reset
- ; persistent data
- lda #$FE
- sta $0200, x
- inx
- bne @clrmem
- @vblankwait2:
- bit $2002
- bpl @vblankwait2
- start:
- jsr initgraphics ; Jump to the routine which initializes
- ; graphics
- forever:
- jmp forever ; Jump back to forever, infinite loop
- initgraphics:
- jsr loadchrram ; Load CHR-RAM from PRG-ROM
- jsr loadpalettes ; Jump to palette loading routine
- jsr initsprites ; Next, jump to sprites loading routine
- rts
- loadchrram:
- src = 0
- lda #<mario_chr ; Load the source address into a pointer
- ; in zeropage
- sta src
- lda #>mario_chr
- sta src+1
- ldy #0 ; Starting index into the first page
- sty $2006 ; Load the destination address into the PPU
- sty $2006
- ldx #32 ; Number of 256-byte pages to copy
- @loop:
- lda (src),y ; Copy one byte
- sta $2007
- iny
- bne @loop ; repeat until we finish the page
- inc src+1 ; go to the next page
- dex
- bne @loop ; repeat until we've copied enough pages
- rts
- 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 out at 0
- @loop:
- lda palette, x ; Load data from address
- ; (palette + the value in x)
- sta $2007 ; Write to PPU
- inx ; X = X + 1
- cpx #$20 ; Compare to hex $20, decimal 32
- bne @loop ; Branch to palette loading loop
- ; if compare was not equal to zero
- rts
- palette:
- ; Background palette
- .byte $0F, $31, $32, $33
- .byte $0F, $35, $36, $37
- .byte $0F, $39, $3A, $3B
- .byte $0F, $3D, $3E, $0F
- ; Sprite palette
- .byte $0F, $16, $27, $18
- .byte $0F, $02, $38, $3C
- .byte $0F, $1C, $15, $14
- .byte $0F, $02, $38, $3C
- initsprites:
- ldx #$00 ; Start at 0
- @loop:
- lda sprites, x ; Load data from address (sprites + x)
- sta $0200, x ; Store into RAM address ($0200 + x)
- inx ; X = X + 1
- cpx #$20 ; Compare X to hex $20, decimal 32
- bne @loop ; Branch to loading sprites loop if compare
- ; was not Equal to zero
- lda #%10000000
- sta $2000 ; Enable NMI, sprites from Pattern Table 1
- lda #%00010000
- sta $2001 ; Enable sprites
- rts
- sprites:
- ;; vert tile attr horiz
- .byte $80, $32, $00, $80 ; sprite 0
- .byte $80, $33, $00, $88 ; sprite 1
- .byte $88, $34, $00, $80 ; sprite 2
- .byte $88, $35, $00, $88 ; sprite 3
- nmi:
- 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
- latchcontroller:
- lda #$01
- sta $4016
- lda #$00
- sta $4016 ; Tell both the controllers to latch buttons
- read_a:
- lda $4016 ; Player 1 - A
- and #%00000001 ; Only look at bit 0
- beq @done ; Branch to @done if button is NOT pressed (0)
- lda $0203 ; Load sprite X position
- clc ; Make sure the carry flag is clear
- adc #$01 ; A = A + 1
- sta $0203 ; save sprite X position
- @done: ; handling this button is done
- read_b:
- lda $4016 ; Player 1 - B
- and #%00000001 ; Only look at bit 0
- beq @done ; Branch to @done if button is NOT pressed (0)
- lda $0203 ; Load sprite X position
- sec ; Make sure the carry flag is set
- sbc #$01 ; A = A - 1
- sta $0203 ; save sprite X position
- @done: ; handling this button is done
- rti
- .segment "VECTORS"
- ; When an NMI happens (once per frame if enabled) the label nmi:
- .word nmi
- ; When the processor first turns on or is reset, it will jump to the
- ; label reset:
- .word reset
- ; External interrupt IRQ is not used in this tutorial
- .word 0
- .segment "RODATA"
- mario_chr:
- .incbin "mario.chr"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement