Simple SNES shoot-'em-up game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

819 lines
18 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. .INCLUDE "header.asm"
  2. .INCLUDE "init.asm"
  3. .INCLUDE "registers.asm"
  4. ; Memory layout:
  5. ; 0000-000F: scratch space for functions.
  6. ; 0010-0011: controller state of joypad #1.
  7. ; 0012-0013: controller state of joypad #2.
  8. ; 0014-0016: 24-bit counter of vblanks.
  9. ; 0017-0019: RGB color values to use for background color, from [0-31].
  10. ; 001A-001B: 16-bit pointer to next random byte.
  11. ; [gap]
  12. ; 0020-0021: (x, y) coordinates of player.
  13. ; 0022: shot cooldown timer.
  14. ; 0023: next-shot state.
  15. ; [gap]
  16. ; 0030-008F: {sprite, x, y, x-velocity, y-velocity, unused} per shot.
  17. ; If sprite is 0, the shot is disabled.
  18. ; [gap]
  19. ; Sprite table buffers -- copied each frame to OAM during VBlank, using DMA.
  20. ; 1000-11FF: table 1 (4 bytes each: x/y coord, tile #, flip/priority/palette)
  21. ; 1200-121F: table 2 (2 bits each: high x-coord bit, size)
  22. ; 1220-12A0: scratch table. One byte per sprite for high x-coord & size.
  23. .define joy1 $10
  24. .define joy2 $12
  25. .define vBlankCounter $14
  26. .define backgroundRed $17
  27. .define backgroundGreen $18
  28. .define backgroundBlue $19
  29. .define randomBytePtr $1A
  30. .define playerX $20
  31. .define playerY $21
  32. .define shotCooldown $22
  33. .define nextShotState $23
  34. .define shotArray $30
  35. .define shotArrayLength 16
  36. .define shotSize 6
  37. .define numSprites 128
  38. .define spriteTableStart $1000
  39. .define spriteTable1Size $200
  40. .define spriteTable2Start $1200
  41. .define spriteTableSize $220
  42. .define spriteTableScratchStart $1220
  43. ; Sets A to 8-bit (& enables 8-bit "B" register).
  44. .MACRO SetA8Bit
  45. sep #%00100000 ; 8-bit A/B.
  46. .ENDM
  47. ; Sets A to 16-bit.
  48. .MACRO SetA16Bit
  49. rep #%00100000 ; 16-bit A.
  50. .ENDM
  51. ; Sets X/Y to 16-bit.
  52. .MACRO SetXY16Bit
  53. rep #%00010000 ; 16-bit X/Y.
  54. .ENDM
  55. ; Stores result to A.
  56. ; Assumes 16-bit X & 8-bit A.
  57. ; Modifies X.
  58. ; Updates randomBytePtr.
  59. .MACRO GetRandomByte
  60. ldx randomBytePtr
  61. lda $028000, X ; $028000: beginning of ROM bank 2.
  62. inx
  63. cpx #$8000 ; This is the size of the entire ROM bank.
  64. bne +++
  65. ldx #0
  66. +++
  67. stx randomBytePtr
  68. .ENDM
  69. .BANK 0 SLOT 0
  70. .ORG 0
  71. .SECTION "MainCode"
  72. Start:
  73. InitializeSNES
  74. ; By default we assume 16-bit X/Y and 8-bit A.
  75. ; If any code wants to change this, it's expected to do so itself,
  76. ; and to change them back to the defaults before returning.
  77. SetXY16Bit
  78. SetA8Bit
  79. jsr LoadPaletteAndTileData
  80. jsr InitializeSpriteTables
  81. jsr InitializeWorld
  82. ; Set screen mode: 16x16 tiles for backgrounds, mode 1.
  83. lda #%11000001
  84. sta BGMODE
  85. ; Set sprite size to 16x16 (small) and 32x32 (large).
  86. lda #%01100000
  87. sta OAMSIZE
  88. ; Main screen: enable sprites & BG3.
  89. lda #%00010100
  90. sta MSENABLE
  91. ; Turn on the screen.
  92. ; Format: x000bbbb
  93. ; x: 0 = screen on, 1 = screen off, bbbb: Brightness ($0-$F)
  94. lda #%00001111
  95. sta INIDISP
  96. jmp MainLoop
  97. LoadPaletteAndTileData:
  98. ; For more details on DMA, see:
  99. ; http://wiki.superfamicom.org/snes/show/Grog%27s+Guide+to+DMA+and+HDMA+on+the+SNES
  100. ; http://wiki.superfamicom.org/snes/show/Making+a+Small+Game+-+Tic-Tac-Toe
  101. ;
  102. ; A lot of the graphics-related registers are explained in Qwertie's doc:
  103. ; http://emu-docs.org/Super%20NES/General/snesdoc.html
  104. ; ... but be careful, because there are some errors in this doc.
  105. ;
  106. ; bazz's tutorial (available from http://wiki.superfamicom.org/snes/) is
  107. ; quite helpful with palette / sprites / DMA, especially starting at
  108. ; http://wiki.superfamicom.org/snes/show/Working+with+VRAM+-+Loading+the+Palette
  109. ; Initialize the palette memory in a loop.
  110. ; We could also do this with a DMA transfer (like we do with the tile data
  111. ; below), but it seems overkill for just a few bytes. :)
  112. ; TODO(mcmillen): do it with a DMA transfer.
  113. ; First, sprite palette data:
  114. ldx #0
  115. lda #128 ; Palette entries for sprites start at 128.
  116. sta CGADDR
  117. -
  118. lda.l SpritePalette, X
  119. sta CGDATA
  120. inx
  121. cpx #32 ; 32 bytes of palette data.
  122. bne -
  123. ; Now, BG3 palette data.
  124. ; Palette entries for BG3 start at 0.
  125. ldx #0
  126. lda #0
  127. sta CGADDR
  128. -
  129. lda.l TilePalette, X
  130. sta CGDATA
  131. inx
  132. cpx #8 ; 8 bytes of palette data.
  133. bne -
  134. ; TODO(mcmillen): make the "DMA stuff into VRAM" a macro or function.
  135. ; Set VMADDR to where we want the DMA to start. We'll store sprite data
  136. ; at the beginning of VRAM.
  137. ldx #$0000
  138. stx VMADDR
  139. ; DMA 0 source address & bank.
  140. ldx #SpriteData
  141. stx DMA0SRC
  142. lda #:SpriteData
  143. sta DMA0SRCBANK
  144. ; DMA 0 transfer size. Equal to the size of sprites32.pic.
  145. ldx #2048
  146. stx DMA0SIZE
  147. ; DMA 0 control register.
  148. ; Transfer type 001 = 2 addresses, LH.
  149. lda #%00000001
  150. sta DMA0CTRL
  151. ; DMA 0 destination.
  152. lda #$18 ; The upper byte is assumed to be $21, so this is $2118 & $2119.
  153. sta DMA0DST
  154. ; Enable DMA channel 0.
  155. lda #%00000001
  156. sta DMAENABLE
  157. ; Store background tile data at byte $2000 of VRAM.
  158. ; (VMADDR is a word address, so multiply by 2 to get the byte address.)
  159. ldx #$1000
  160. stx VMADDR
  161. ; DMA 0 source address & bank.
  162. ldx #TileData
  163. stx DMA0SRC
  164. lda #:TileData
  165. sta DMA0SRCBANK
  166. ; DMA 0 transfer size. Equal to the size of tiles.pic.
  167. ldx #512
  168. stx DMA0SIZE
  169. ; DMA 0 control register.
  170. ; Transfer type 001 = 2 addresses, LH.
  171. lda #%00000001
  172. sta DMA0CTRL
  173. ; DMA 0 destination.
  174. lda #$18 ; The upper byte is assumed to be $21, so this is $2118 & $2119.
  175. sta DMA0DST
  176. ; Enable DMA channel 0.
  177. lda #%00000001
  178. sta DMAENABLE
  179. ; Tell the system that the BG3 tilemap starts at $4000.
  180. lda #%00100000
  181. sta BG3TILEMAP
  182. ; ... and that the background tile data for BG3 starts at $2000.
  183. lda #%00000001
  184. sta BG34NBA
  185. ; Set up the BG3 tilemap.
  186. ; VRAM write mode: increments the address every time we write a word.
  187. lda #%10000000
  188. sta VMAIN
  189. ; Set word address for accessing VRAM.
  190. ldx #$2000 ; BG 3 tilemap starts here. (Byte address $4000.)
  191. stx VMADDR
  192. ; Now write entries into the tile map.
  193. ldy #0
  194. -
  195. GetRandomByte
  196. sta $00
  197. ldx #$0000 ; This is a blank tile.
  198. ; 1 in 8 chance that we choose a non-blank tile.
  199. bit #%00000111
  200. bne +
  201. ldx #$0002
  202. bit #%10000000
  203. bne +
  204. ldx #$8002 ; Flip vertically.
  205. +
  206. stx VMDATA
  207. iny
  208. ; The tile map is 32x32 (1024 entries).
  209. cpy #1024
  210. bne -
  211. rts
  212. InitializeSpriteTables:
  213. ; This page is a good reference on SNES sprite formats:
  214. ; http://wiki.superfamicom.org/snes/show/SNES+Sprites
  215. ; It uses the same approach we're using, in which we keep a buffer of the
  216. ; sprite tables in RAM, and DMA the sprite tables to the system's OAM
  217. ; during VBlank.
  218. SetA16Bit
  219. ldx #$0000
  220. ; Fill sprite table 1. 4 bytes per sprite, laid out as follows:
  221. ; Byte 1: xxxxxxxx x: X coordinate
  222. ; Byte 2: yyyyyyyy y: Y coordinate
  223. ; Byte 3: cccccccc c: Starting tile #
  224. ; Byte 4: vhoopppc v: vertical flip h: horizontal flip o: priority bits
  225. ; p: palette #
  226. lda #$01
  227. -
  228. sta spriteTableStart, X
  229. .rept 4
  230. inx
  231. .endr
  232. cpx #spriteTable1Size
  233. bne -
  234. ; Fill sprite table 2. 2 bits per sprite, like so:
  235. ; bits 0,2,4,6 - High bit of the sprite's x-coordinate.
  236. ; bits 1,3,5,7 - Toggle Sprite size: 0 - small size 1 - large size
  237. ; Setting all the high bits keeps the sprites offscreen.
  238. lda #$FFFF
  239. -
  240. sta spriteTableStart, X
  241. inx
  242. inx
  243. cpx #spriteTableSize
  244. bne -
  245. SetA8Bit
  246. rts
  247. InitializeWorld:
  248. ; Start the background color as a dark blue.
  249. lda #4
  250. sta backgroundBlue
  251. ; Player's initial starting location.
  252. lda #(256 / 4)
  253. sta playerX
  254. lda #((224 - 32) / 2)
  255. sta playerY
  256. rts
  257. MainLoop:
  258. lda #%10000001 ; Enable NMI interrupt & auto joypad read.
  259. sta NMITIMEN
  260. wai ; Wait for interrupt.
  261. lda #%00000001 ; Disable NMI interrupt while processing.
  262. sta NMITIMEN
  263. jsr JoypadRead
  264. jsr JoypadHandler
  265. jsr UpdateWorld
  266. jsr UpdateSprites
  267. jsr FillSecondarySpriteTable
  268. jsr SetBackgroundColor
  269. jmp MainLoop
  270. JoypadRead:
  271. ; Load joypad registers into RAM for easy inspection & manipulation.
  272. -
  273. lda HVBJOY
  274. bit #$01 ; If auto-joypad read is happening, loop.
  275. bne -
  276. ldx JOY1L
  277. stx joy1
  278. ldx JOY2L
  279. stx joy2
  280. rts
  281. JoypadHandler:
  282. JoypadUp:
  283. lda joy1 + 1
  284. bit #$08 ; Up
  285. beq JoypadDown ; Button not pressed.
  286. lda playerY
  287. cmp #0
  288. beq JoypadDown ; Value saturated.
  289. dec playerY
  290. dec playerY
  291. JoypadDown:
  292. lda joy1 + 1
  293. bit #$04 ; Down
  294. beq JoypadLeft ; Button not pressed.
  295. lda playerY
  296. cmp #(224 - 32)
  297. beq JoypadLeft ; Value saturated.
  298. inc playerY
  299. inc playerY
  300. JoypadLeft:
  301. lda joy1 + 1
  302. bit #$02 ; Left
  303. beq JoypadRight ; Button not pressed.
  304. lda playerX
  305. cmp #0
  306. beq JoypadRight ; Value saturated.
  307. dec playerX
  308. dec playerX
  309. JoypadRight:
  310. lda joy1 + 1
  311. bit #$01 ; Right
  312. beq JoypadStart ; Button not pressed.
  313. lda playerX
  314. cmp #(256 - 32)
  315. beq JoypadStart ; Value saturated.
  316. inc playerX
  317. inc playerX
  318. JoypadStart:
  319. lda joy1 + 1
  320. bit #$10 ; Start
  321. beq JoypadSelect ; Button not pressed.
  322. lda backgroundRed
  323. cmp #31
  324. beq JoypadSelect ; Value saturated.
  325. inc backgroundRed
  326. JoypadSelect:
  327. lda joy1 + 1
  328. bit #$20 ; Select
  329. beq JoypadY ; Button not pressed.
  330. lda backgroundRed
  331. cmp #0
  332. beq JoypadY ; Value saturated.
  333. dec backgroundRed
  334. JoypadY:
  335. lda joy1 + 1
  336. bit #$40 ; Y
  337. beq JoypadX ; Button not pressed.
  338. lda backgroundGreen
  339. cmp #0
  340. beq JoypadX ; Value saturated.
  341. dec backgroundGreen
  342. JoypadX:
  343. lda joy1
  344. bit #$40 ; X
  345. beq JoypadL ; Button not pressed.
  346. lda backgroundGreen
  347. cmp #31
  348. beq JoypadL ; Value saturated.
  349. inc backgroundGreen
  350. JoypadL:
  351. lda joy1
  352. bit #$20 ; L
  353. beq JoypadR ; Button not pressed.
  354. lda backgroundBlue
  355. cmp #0
  356. beq JoypadR ; Value saturated.
  357. dec backgroundBlue
  358. JoypadR:
  359. lda joy1
  360. bit #$10 ; R
  361. beq JoypadB ; Button not pressed.
  362. lda backgroundBlue
  363. cmp #31
  364. beq JoypadB ; Value saturated.
  365. inc backgroundBlue
  366. JoypadB:
  367. lda joy1 + 1
  368. bit #$80 ; B
  369. beq JoypadDone
  370. jsr MaybeShoot
  371. JoypadDone:
  372. rts
  373. MaybeShoot:
  374. ; If the cooldown timer is non-zero, don't shoot.
  375. lda shotCooldown
  376. cmp #0
  377. bne MaybeShootDone
  378. ; Find the first empty spot in the shots array.
  379. ldx #shotArray
  380. -
  381. lda 0, X
  382. cmp #0
  383. beq +
  384. .rept shotSize
  385. inx
  386. .endr
  387. ; If we went all the way to the end, bail out.
  388. cpx #(shotArray + shotArrayLength * shotSize)
  389. beq MaybeShootDone
  390. jmp -
  391. +
  392. ; Enable shot; set its position based on player position.
  393. ; TODO(mcmillen): it might be easier/faster to keep N arrays: one for each
  394. ; field of shot (shotSpriteArray, shotXArray, shotYArray, ...)
  395. lda #8 ; Sprite number.
  396. sta 0, X
  397. lda playerX
  398. adc #20
  399. sta 1, X
  400. lda playerY
  401. sta 2, X
  402. ; x-velocity.
  403. lda #6
  404. sta 3, X
  405. ; y-velocity.
  406. lda nextShotState
  407. cmp #1
  408. beq +
  409. lda #2
  410. sta 4, X
  411. inc nextShotState
  412. jmp ++
  413. +
  414. lda #-2
  415. sta 4, X
  416. dec nextShotState
  417. ++
  418. ; Set cooldown timer.
  419. lda #10
  420. sta shotCooldown
  421. MaybeShootDone:
  422. rts
  423. UpdateWorld:
  424. ; Update shot cooldown.
  425. lda shotCooldown
  426. cmp #0
  427. beq +
  428. dec A
  429. sta shotCooldown
  430. +
  431. ldx #0
  432. ; Update shot position.
  433. UpdateShot:
  434. lda shotArray, X
  435. cmp #0
  436. beq ShotDone
  437. ; Add to the x-coordinate. If the carry bit is set, we went off the edge
  438. ; of the screen, so disable the shot.
  439. lda shotArray + 3, X ; x-velocity.
  440. sta $00
  441. bit #%10000000 ; Check whether the velocity is negative.
  442. bne UpdateShotWithNegativeXVelocity
  443. lda shotArray + 1, X
  444. clc
  445. adc $00
  446. bcs DisableShot
  447. sta shotArray + 1, X ; Store new x-coord.
  448. jmp UpdateShotY
  449. UpdateShotWithNegativeXVelocity:
  450. ; TODO(mcmillen): wrap sprites when they go negative here, like we do
  451. ; with y-velocities.
  452. lda shotArray + 1, X ; Current x.
  453. clc
  454. adc $00
  455. bcc DisableShot
  456. sta shotArray + 1, X
  457. jmp UpdateShotY
  458. UpdateShotY:
  459. ; Add to the y-coordinate.
  460. lda shotArray + 4, X ; y-velocity.
  461. sta $00
  462. bit #%10000000 ; Check whether the velocity is negative.
  463. bne UpdateShotWithNegativeYVelocity
  464. lda shotArray + 2, X
  465. adc $00
  466. cmp #224
  467. bcs DisableShot
  468. sta shotArray + 2, X ; Store new y-coord.
  469. jmp ShotDone
  470. UpdateShotWithNegativeYVelocity:
  471. lda shotArray + 2, X ; Current y.
  472. cmp #224
  473. bcs + ; If the shot was "off the top" before moving, maybe we'll reap it.
  474. adc $00 ; Otherwise, just update it,
  475. sta shotArray + 2, X ; save the result,
  476. jmp ShotDone ; and we know it shouldn't be reaped.
  477. +
  478. adc $00
  479. dec A ; Two's complement means that we need to -1 again in this case.
  480. cmp #224
  481. bcc DisableShot ; If it's now wrapped around, reap it.
  482. sta shotArray + 2, X
  483. jmp ShotDone
  484. DisableShot:
  485. stz shotArray, X
  486. ShotDone:
  487. ; TODO(mcmillen): in places where we .rept inx (etc), is it faster to use
  488. ; actual addition?
  489. .rept shotSize
  490. inx
  491. .endr
  492. cpx #(shotArrayLength * shotSize)
  493. bne UpdateShot
  494. ; Make the background scroll. Horizontal over time; vertical depending on
  495. ; player's y-coordinate.
  496. lda vBlankCounter
  497. sta BG3HOFS
  498. lda vBlankCounter + 1
  499. sta BG3HOFS
  500. lda playerY
  501. .rept 3
  502. lsr
  503. .endr
  504. sta BG3VOFS
  505. stz BG3VOFS
  506. rts
  507. UpdateSprites:
  508. ; Zero out the scratch space for the secondary sprite table.
  509. ldx #0
  510. -
  511. stz spriteTableScratchStart, X
  512. inx
  513. cpx #numSprites
  514. bne -
  515. ldx #0 ; Index into sprite table 1.
  516. ldy #0 ; Index into sprite table 2.
  517. ; Copy player coords into sprite table.
  518. lda playerX
  519. sta spriteTableStart, X
  520. lda playerY
  521. sta spriteTableStart + 1, X
  522. lda #0
  523. sta spriteTableStart + 2, X
  524. ; Set priority bits so that the sprite is drawn in front.
  525. lda #%00110000
  526. sta spriteTableStart + 3, X
  527. lda #%11000000 ; Enable large sprite.
  528. sta spriteTableScratchStart, Y
  529. .rept 4
  530. inx
  531. .endr
  532. iny
  533. ; Now add shots.
  534. sty $00 ; Save sprite table 2 index.
  535. ldy #0 ; Index into shotArray.
  536. -
  537. lda shotArray, Y
  538. cmp #0
  539. beq + ; If not enabled, skip to next shot.
  540. ; Update sprite table 1.
  541. sta spriteTableStart + 2, X ; sprite number
  542. lda shotArray + 1, Y
  543. sta spriteTableStart, X ; x
  544. lda shotArray + 2, Y
  545. sta spriteTableStart + 1, X ; y
  546. ; Update secondary sprite table.
  547. phy ; Save shotArray index.
  548. ldy $00
  549. lda #%11000000
  550. sta spriteTableScratchStart, Y
  551. iny
  552. sty $00
  553. ply ; Restore shotArrayIndex.
  554. .rept 4
  555. inx
  556. .endr
  557. +
  558. .rept shotSize
  559. iny
  560. .endr
  561. cpy #(shotArrayLength * shotSize)
  562. bne -
  563. ; Now clear out the unused entries in the sprite table.
  564. -
  565. cpx #spriteTable1Size
  566. beq +
  567. lda #1
  568. sta spriteTableStart, X
  569. .rept 4
  570. inx
  571. .endr
  572. +
  573. rts
  574. FillSecondarySpriteTable:
  575. ; The secondary sprite table wants 2 bits for each sprite: one to set the
  576. ; sprite's size, and one that's the high bit of the sprite's x-coordinate.
  577. ; It's annoying to deal with bitfields when thinking about business logic,
  578. ; so the spriteTableScratch array contains one byte for each sprite, in
  579. ; which the two most significant bits are the "size" and "upper x" bits.
  580. ; This function is meant to be called after UpdateWorld, and packs those
  581. ; bytes into the actual bitfield that the OAM wants for the secondary
  582. ; sprite table.
  583. ;
  584. ; The expected format of every byte in the scratch sprite table is:
  585. ; sx------ s = size (0 = small, 1 = large)
  586. ; x = flipped high x-coordinate (so 1 behaves like "enable").
  587. ldx #0 ; Index into input table.
  588. ldy #0 ; Index into output table.
  589. -
  590. stz $00 ; Current byte; filled out by a set of 4 input table entries.
  591. .rept 4
  592. ; For each byte, the lower-order bits correspond to the lower-numbered
  593. ; sprites; therefore we insert the current sprite's bits "at the top"
  594. ; and shift them right for each successive sprite.
  595. lsr $00
  596. lsr $00
  597. lda spriteTableScratchStart, X
  598. ora $00
  599. sta $00
  600. inx
  601. .endr
  602. lda $00
  603. eor #%01010101
  604. sta spriteTable2Start, Y
  605. iny
  606. cpx #numSprites
  607. bne -
  608. rts
  609. SetBackgroundColor:
  610. ; The background-color bytes are (R, G, B), each ranging from [0-31].
  611. ; The palette color format is 15-bit: [0bbbbbgg][gggrrrrr]
  612. ; Set the background color.
  613. ; Entry 0 corresponds to the SNES background color.
  614. stz CGADDR
  615. ; Compute and the low-order byte and store it in CGDATA.
  616. lda backgroundGreen
  617. .rept 5
  618. asl
  619. .endr
  620. ora backgroundRed
  621. sta CGDATA
  622. ; Compute the high-order byte and store it in CGDATA.
  623. lda backgroundBlue
  624. .rept 2
  625. asl
  626. .endr
  627. sta $00
  628. lda backgroundGreen
  629. .rept 3
  630. lsr
  631. .endr
  632. ora $00
  633. sta CGDATA
  634. rts
  635. VBlankHandler:
  636. jsr VBlankCounter
  637. jsr DMASpriteTables
  638. rti
  639. VBlankCounter:
  640. ; Increment a counter of how many VBlanks we've done.
  641. ; This is a 24-bit counter. At 60 vblanks/second, this will take
  642. ; 77 hours to wrap around; that's good enough for me :)
  643. inc vBlankCounter
  644. bne +
  645. inc vBlankCounter + 1
  646. bne +
  647. inc vBlankCounter + 2
  648. +
  649. rts
  650. DMASpriteTables:
  651. ; Store at the base OAM address.
  652. ldx #$0000
  653. stx OAMADDR
  654. ; Default DMA control; destination $2104 (OAM data register).
  655. stz DMA0CTRL
  656. lda #$04
  657. sta DMA0DST
  658. ; Our sprites start at $0100 in bank 0 and are #$220 bytes long.
  659. ldx #spriteTableStart
  660. stx DMA0SRC
  661. stz DMA0SRCBANK
  662. ldx #spriteTableSize
  663. stx DMA0SIZE
  664. ; Kick off the DMA transfer.
  665. lda #%00000001
  666. sta DMAENABLE
  667. rts
  668. .ENDS
  669. ; Bank 1 is used for our graphics assets.
  670. .BANK 1 SLOT 0
  671. .ORG 0
  672. .SECTION "GraphicsData"
  673. SpriteData:
  674. .INCBIN "sprites32.pic"
  675. SpritePalette:
  676. .INCBIN "sprites32.clr"
  677. TileData:
  678. .INCBIN "tiles.pic"
  679. TilePalette:
  680. .INCBIN "tiles.clr"
  681. .ENDS
  682. ; Fill an entire bank with random numbers.
  683. .SEED 1
  684. .BANK 2 SLOT 0
  685. .ORG 0
  686. .SECTION "RandomBytes"
  687. .DBRND 32 * 1024, 0, 255
  688. .ENDS