Advertisement
Sarm_8

Display Mario with Comments

Dec 6th, 2021
1,915
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; reference: https://www.kibrit.tech/en/blog/nes-game-development-part-1
  2.  
  3. ; -----------------------------------------------------
  4. ; Header
  5. ; -----------------------------------------------------
  6.  
  7. ; These 16 bytes let nes know how banks are organised
  8. ; and how to run code
  9.  
  10. .segment "HEADER"
  11. .byte "NES" ; Name of Game (Maybe?)                        
  12. .byte $1a ; Indicates to nes that this is a game file that can be loaded
  13.  
  14. .byte $02 ; 2 * 16KB PRG ROM for code  
  15. .byte $01 ; 1 * 8KB CHR ROM for sprites
  16.  
  17. .byte %00000001 ; mapper and mirroring
  18. .byte $00
  19. .byte $00
  20. .byte $00
  21. .byte $00
  22.  
  23. .byte $00, $00, $00, $00, $00 ; filler bytes
  24.  
  25. .segment "ZEROPAGE" ; $0 - $FF
  26.  
  27. ; -----------------------------------------------------
  28. ; Startup
  29. ; -----------------------------------------------------
  30. .segment "STARTUP"
  31.  
  32. ; Interrupts
  33.  
  34. ; some things must be disabled or initalised for reset
  35. ; process
  36.  
  37. Reset:
  38.     sei ; disable interrupts
  39.     cld ; disable decimal mode
  40.  
  41.     ldx #$40
  42.     stx $4017 ;disable APU interrupts
  43.  
  44.     ldx #$FF
  45.     txs ; (copy x to s) Initialise stack
  46.  
  47.     inx ; set x to $00
  48.  
  49.     ; Zero out PPU
  50.     stx $2000
  51.     stx $2001
  52.  
  53.     stx $4010 ; disable APU DMC channel
  54.  
  55. ; We need to wait for VBlank before doing anything
  56. ; Waits until VBlank period
  57. ; bit $2002 sets negative flag to match the 7th(last) bit
  58. ; this is the bit that indicates we are in a VBlank
  59. ; if vblank = 0, negative = 0
  60. ; bpl will brach if posotive, aka if negative flag = 0
  61.  
  62. VBlankWait1:
  63.     bit $2002
  64.     bpl VBlankWait1
  65.  
  66. ; Clearing Memory
  67. ; When console starts RAM is initalised with random/garbage values
  68. ; NES RAM = 2KB or $0000 to $0800
  69. ; We need to init these all to #$00
  70.  
  71. ; First, set a to zero, then store in registers seen below
  72. ; with offset of x. Then increment x every cycle
  73. ; if x = 0, branch out
  74.  
  75. ClearMem:
  76.     lda #$00
  77.     sta $0000, x ; 0 - 255
  78.     sta $0100, x ; 256 - 511
  79.     ; $0200 - $02FF designated for sprite storage
  80.     sta $0300, x ; etc
  81.     sta $0400, x
  82.     sta $0500, x
  83.     sta $0600, x
  84.     sta $0700, x
  85.  
  86.     ; put all sprites off-screen. PPU will ignore them
  87.     lda #$FE
  88.     sta $0200, x
  89.  
  90.     inx
  91.     cpx #$00
  92.     bne ClearMem
  93.  
  94. ; wait for another VBlank to make sure NES is totally ready
  95.  
  96. VBlankWait2:
  97.     bit $2002
  98.     bpl VBlankWait2
  99.  
  100. ; PPU Palettes and init
  101. ; PPU needs to know where sprites are located($0200 - $02FF)
  102.  
  103. lda #$02 ; load most significant byte of $0200 into A
  104. sta $4014 ; tells PPU where sprites start will assume next 256 bytes are sprites too
  105. nop ; (no operation) Give time for the PPU to load
  106.  
  107. ; Palette Init
  108.  
  109. ; Total of 8 palettes. 4 for background and 4 for sprites
  110. ; 32 bytes all together
  111. ; Each palette consists of 4 colors, where the first one
  112. ; is always the same
  113.  
  114. ; PPU has own internal RAM.
  115. ; Palettes are stored in range $3F00 -$3F1F
  116. ; PPU first needs to know what we want ot write
  117. ; to this range of memory
  118. ; We do this by giving the address to $2006 which will send that
  119. ; to the PPU RAM, since the CPU and PPU are on different buses
  120.  
  121. lda #$3F ; load most significant bit to A
  122. sta $2006 ; sends to PPU
  123. lda #$00 ; load least significant bit to A
  124. sta $2006 ; sends to PPU
  125.  
  126. ; Next we need to load the palettes by iterating
  127. ; through PaletteData(which stores each palette in groups of 4 bytes)
  128. ; and adding each to $2007
  129. ; PPU will then read the color from that port and write to $3F00,
  130. ; then increment by itself and write the next color to $3F01, etc.
  131.  
  132. ldx #$00 ; init x for indexing PaletteData
  133.  
  134. LoadPalettes:
  135.     lda PaletteData, x ; load color from PaletteData at index X
  136.     sta $2007 ; $3F00 - $3F1F
  137.     inx
  138.     cpx #$20
  139.     bne LoadPalettes ; if x != 32, loop
  140.  
  141. ; Now, all of the palettes are loaded into the PPU
  142.  
  143. ; Loading Sprites
  144.  
  145. ; Memory Range $0200 - $02FF
  146. ; Sprites are stored in a different file, in this case, "hellomario.chr"
  147. ; We iterate through the sprites and store them in $0200 - $02FF
  148.  
  149. ldx #$00
  150.  
  151. LoadSprites:
  152.     lda SpriteData, x
  153.     sta $0200, x
  154.     inx
  155.     cpx #$20
  156.     bne LoadSprites
  157.  
  158. ; NMI(Non-Maskable Interrupts)
  159. ; NMIs happen every frame. This is a good place to do
  160. ; graphical updates
  161. ; The PPUs RAM is dynamic(values will degrade over time) so we will
  162. ; use the NMI to update that memory every frame
  163. ; We also need to re-enable all the interrupts from earlier in the HEADER
  164.  
  165. cli ; re-enable interrupts
  166.  
  167. ; Re-enables PPU drawing
  168. lda #%10010000
  169. sta $2000
  170. lda #%00011110
  171. sta $2001
  172.  
  173. ; AAAAAALLLLLL of that was part of the reset process
  174. ; Now, we define the behaviour of the NMI interrupt, which is much simpler
  175. ; Here we tell the PPU from where to take the spprites for
  176. ; an update by providing the most significant bit of $0200
  177.  
  178. NMI:
  179.     lda #$02
  180.     sta $4014 ; send to PPU memory for display
  181.     rti ; return form interrupt
  182.  
  183.  
  184.  
  185.  
  186. ; Palette Data and Sprite Data
  187.  
  188. ; Each palette starts with the same number
  189.  
  190. PaletteData:
  191.     .byte $22,$29,$1A,$0F,$22,$36,$17,$0f,$22,$30,$21,$0f,$22,$27,$17,$0F  ;background palette data
  192.     .byte $22,$16,$27,$18,$22,$1A,$30,$27,$22,$16,$30,$27,$22,$0F,$36,$17  ;sprite palette data
  193.  
  194. ; Byte 0 = Y position
  195. ; Byte 1 = Tile Index
  196. ; Byte 2 = Attributes - sprite flipping, z depth and palette
  197. ; Byte 3 = X position of sprite
  198.  
  199. SpriteData:
  200.   .byte $08, $00, $00, $08
  201.   .byte $08, $01, $00, $10
  202.   .byte $10, $02, $00, $08
  203.   .byte $10, $03, $00, $10
  204.   .byte $18, $04, $00, $08
  205.   .byte $18, $05, $00, $10
  206.   .byte $20, $06, $00, $08
  207.   .byte $20, $07, $00, $10 
  208.  
  209. ; -----------------------------------------------------
  210. ; Vectors
  211. ; -----------------------------------------------------
  212.  
  213. ; Sometimes interrupts are called vectors, these will just
  214. ; connect the labels to the actual interrupts
  215.  
  216. .segment "VECTORS"
  217.     .word NMI
  218.     .word Reset
  219.  
  220. ; -----------------------------------------------------
  221. ; Chars
  222. ; -----------------------------------------------------
  223.  
  224. ; Lastly, we need to include a tile map where the
  225. ; actual sprites are stored
  226. ; I'm using a mario .chr with marios sprites in it
  227.  
  228. .segment "CHARS"
  229.     .incbin "hellomario.chr"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement