Guest User

Untitled

a guest
Dec 14th, 2018
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.11 KB | None | 0 0
  1. .inesprg 1 ; 1x 16KB PRG code
  2. .ineschr 1 ; 1x 8KB CHR data
  3. .inesmap 0 ; mapper 0 = NROM, no bank swapping
  4. .inesmir 1 ; background mirroring
  5.  
  6. ;declare our variables
  7. .rsset 0 ;starting at address zero
  8. ballxspeed: .rs 1 ;pixels per frame x
  9. ballyspeed: .rs 1 ;pixels per frame y
  10. ballx: .rs 1 ;ball x pos
  11. bally: .rs 1 ;ball y pos
  12. ;balldir: .rs 1 ;ball direction: bit zero = up/down; bit one = left/right
  13. ballupdown: .rs 1 ;ball direction: 1 = down
  14. ballleftright: .rs 1 ;ball direction: 1 = right
  15. paddle1: .rs 1 ;top position for paddle 1
  16. paddle2: .rs 1 ;top position for paddle 2
  17. p1score: .rs 1 ;score for player 1
  18. p2score: .rs 1 ;score for player 2
  19. buttons1: .rs 1 ;buttons for player 1
  20. buttons2: .rs 1 ;buttons for player 2
  21. state: .rs 1 ;our current state
  22. arrowpos: .rs 1 ;current position of the arrow
  23. pressed: .rs 1 ;if the select button hasn't been released yet (used to avoid wild switching)
  24. ballmoving: .rs 1 ;if the ball is currently moving
  25. AIplayer: .rs 1 ;1 if AI is playing
  26. AIplayed: .rs 1 ;variable to keep AI's speed down
  27. cheatenabled: .rs 1 ;set to 1 if cheats are enabled
  28. cheatcounter: .rs 1 ;current button in the cheat code
  29. cheatpressed: .rs 1 ;set if a button hasn't been released yet
  30.  
  31. ;declare our constants
  32. ;paddle constants
  33. PADDLE1_X = $00
  34. PADDLE2_X = $F8
  35. PADDLE_HEIGHT = 32
  36. PADDLE_SEGMENT_HEIGHT = 8
  37.  
  38. ;ball bounds
  39. TOP = $08
  40. BOTTOM = $E0
  41. LEFT = $08
  42. RIGHT = $F0
  43.  
  44. PADDLE_BOTTOM = BOTTOM-PADDLE_HEIGHT
  45. PADDLE_TOP = $08
  46.  
  47. ;game speeds
  48. PADDLE_SPEED = 4
  49. BALL_SPEED = 2
  50.  
  51. ;text stuff
  52. PLAYER1TEXT_LOC = $2C
  53. PLAYER2TEXT_LOC = $3C
  54.  
  55. WINTEXT_HIGH = $21 ;nametable address to place the winner text
  56. WINTEXT_LOW = $48
  57.  
  58. WINNING_SCORE = 10
  59.  
  60. ;button constants
  61. BUTTON_A = $80
  62. BUTTON_B = $40
  63. BUTTON_SELECT = $20
  64. BUTTON_START = $10
  65. BUTTON_UP = $08
  66. BUTTON_DOWN = $04
  67. BUTTON_LEFT = $02
  68. BUTTON_RIGHT = $01
  69.  
  70. ;ppu constants
  71. PPUREG_1 = %10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  72. PPUREG_2 = %00011110 ; enable sprites, enable background, no clipping on left side
  73.  
  74. ;state defines
  75. STATE_TITLE = $00
  76. STATE_PLAYING = $01
  77. STATE_WIN = $02
  78.  
  79. ;positions
  80. ARROW_POS_HIGH = $22
  81. ARROW_POS_1 = $A9
  82. ARROW_POS_2 = $E9
  83.  
  84. .bank 0 ;program bank 0
  85. .org $C000
  86. RESET: ;NES init code stolen from Nerdy Nights, I was too lazy to write my own and didn't understand some of the stuff it did and why
  87. SEI ; disable IRQs
  88. CLD ; disable decimal mode
  89. LDX #$40
  90. STX $4017 ; disable APU frame IRQ
  91. LDX #$FF
  92. TXS ; Set up stack
  93. INX ; now X = 0
  94. STX $2000 ; disable NMI
  95. STX $2001 ; disable rendering
  96. STX $4010 ; disable DMC IRQs
  97.  
  98. vblankwait1: ; First wait for vblank to make sure PPU is ready
  99. BIT $2002
  100. BPL vblankwait1
  101.  
  102. clrmem:
  103. LDA #$00
  104. STA $0000, x
  105. STA $0100, x
  106. STA $0300, x
  107. STA $0400, x
  108. STA $0500, x
  109. STA $0600, x
  110. STA $0700, x
  111. LDA #$FE
  112. STA $0200, x
  113. INX
  114. BNE clrmem
  115.  
  116. vblankwait2: ; Second wait for vblank, PPU is ready after this
  117. BIT $2002
  118. BPL vblankwait2
  119.  
  120. ;stolen code ends here
  121.  
  122. ;initialize the PPU RAM and copy over our palettes and nametables and other fun stuff
  123. PaletteCopy: ;copy the palettes to the PPU
  124. LDA $2002 ;read the PPU status to reset the address
  125. LDA #$3F ;write out the palette address to the PPU ($3F00)
  126. STA $2006
  127. LDA #$00
  128. STA $2006
  129. LDX #0 ;reset X for the copy
  130. PaletteCopyLoop:
  131. LDA palettes,x ;load our palette byte
  132. STA $2007 ;store it to the magic address where it gets written to PPU RAM
  133. INX
  134. CPX #32 ;test if we're done (we need to copy 32 bytes of palette data)
  135. BNE PaletteCopyLoop
  136.  
  137. CopyNametable:
  138. LDA #LOW(titlenametable) ;set up addresses for indirect copying
  139. STA $30
  140. LDA #HIGH(titlenametable)
  141. STA $31
  142. JSR NametableCopy ;actually copy the nametable
  143.  
  144. AttributeCopy:
  145. LDA $2002 ;read the PPU status to reset the address
  146. LDA #$23 ;write out the nametable address to the PPU ($23C0)
  147. STA $2006
  148. LDA #$C0
  149. STA $2006
  150. LDX #0 ;reset X for the copy
  151. AttributeCopyLoop:
  152. LDA playfieldattributes,x ;load attribute byte
  153. STA $2007 ;write it to the PPU
  154. INX
  155. CPX #0 ;if we haven't copied all of it
  156. BNE AttributeCopyLoop ;copy more
  157.  
  158. JSR ClearSprites
  159. JSR UpdateSpritesTransfer
  160.  
  161. JSR TitleRamInit
  162.  
  163. ;JSR UpdateSpritesTransfer
  164.  
  165. PPUInit: ;set up the PPU registers
  166. LDA #PPUREG_1
  167. STA $2000
  168. LDA #PPUREG_2
  169. STA $2001
  170.  
  171. InfiniteLoop:
  172. JMP InfiniteLoop ;what could it be? I wonder...
  173.  
  174. NmiHandler:
  175. LDA state ;do different actions depending upon the current state
  176. CMP #STATE_TITLE ;if we're at the title screen
  177. BEQ DoTitle
  178. CMP #STATE_PLAYING ;or playing
  179. BEQ DoPlay
  180. CMP #STATE_WIN
  181. BEQ DoWin
  182. RTI ;huh, how could this have happened?
  183. DoPlay:
  184. JSR DrawScore
  185. JSR UpdateSprites
  186. JSR ReadControllers
  187. JSR HandleControllers
  188. JSR MovePaddles
  189. JSR BounceBall
  190. JSR MoveBall
  191. JMP NmiFinished
  192. DoTitle:
  193. JSR ReadControllers
  194. JSR HandleTitleButtons
  195. JMP NmiFinished
  196. DoWin:
  197. JSR ReadControllers
  198. JSR HandleWinButtons
  199. NmiFinished:
  200. LDA #0 ;reset the PPU for the next frame
  201. STA $2005
  202. STA $2005
  203. RTI
  204.  
  205. ClearSprites:
  206. LDX #$FF
  207. LDA #$FF
  208. ClearSpritesLoop:
  209. STA $200,x
  210. DEX
  211. BNE ClearSpritesLoop
  212.  
  213. UpdateSprites:
  214. LDA bally ;store the ball position to the sprite area
  215. STA $200
  216. LDA ballx
  217. STA $203
  218. CLC
  219. LDA paddle1 ;do the same with the paddles
  220. STA $204 ;it needs to be done 4 times for each paddle because each paddle is composed of 4 sprites
  221. ADC #8
  222. STA $204+4
  223. ADC #8
  224. STA $204+8
  225. ADC #8
  226. STA $204+12
  227. ADC #8
  228. LDA paddle2
  229. STA $204+16
  230. ADC #8
  231. STA $204+20
  232. ADC #8
  233. STA $204+24
  234. ADC #8
  235. STA $204+28
  236. UpdateSpritesTransfer:
  237. ;transfer the sprite data to the PPU via DMA
  238. LDA #0 ;set the low RAM address
  239. STA $2003
  240. LDA #2 ;set the high RAM address and start the dma
  241. STA $4014
  242. RTS
  243.  
  244. DrawScore:
  245. LDA $2002 ;read the PPU status to reset the address
  246. LDA #$20 ;write out the score location
  247. STA $2006
  248. LDA #PLAYER1TEXT_LOC
  249. STA $2006
  250. LDA p1score
  251. STA $2007
  252. LDA $2002 ;read the PPU status to reset the address
  253. LDA #$20 ;write out the score location
  254. STA $2006
  255. LDA #PLAYER2TEXT_LOC
  256. STA $2006
  257. LDA p2score
  258. STA $2007
  259. RTS
  260.  
  261. ReadControllers:
  262. LDA #1 ;latch the buttons
  263. STA $4016
  264. LDA #0
  265. STA $4016
  266. LDX #8 ;get ready for the loop
  267. ReadControllersLoop:
  268. LDA $4016 ;get button for controller 1
  269. LSR A ;put the button in carry
  270. ROL buttons1 ;and then put it in buttons
  271. LDA $4017 ;do the same for controller 2
  272. LSR A ;put the button in carry
  273. ROL buttons2 ;and then put it in buttons
  274. DEX ;check if we have any more buttons left
  275. BNE ReadControllersLoop
  276. RTS
  277.  
  278. HandleControllers:
  279. LDY buttons1
  280. TYA
  281. AND #BUTTON_START ;if start is pressed
  282. BNE StartBall ;start the ball moving
  283. RTS
  284.  
  285. StartBall:
  286. LDA ballmoving ;if the ball is already moving
  287. BNE RtsBranch1 ;no need to set it up again
  288. LDA #BALL_SPEED ;set up the speed
  289. STA ballxspeed
  290. STA ballyspeed
  291. LDA #1 ;and indicate that it's moving
  292. STA ballmoving
  293. RtsBranch1:
  294. RTS
  295.  
  296. MovePaddles:
  297. LDA ballmoving ;if the ball isn't moving
  298. BEQ MovePaddlesDone ;the paddles shouldn't either
  299. LDY buttons1 ;load the buttons and paddle position
  300. TYA
  301. LDX paddle1
  302. AND #BUTTON_UP ;if up is pressed
  303. BNE Player1Up ;move up
  304. TYA
  305. AND #BUTTON_DOWN
  306. BNE Player1Down ;and move down if down is pressed
  307. JMP MovePaddlesNext ;if neither is pressed, go check player 2
  308. Player1Down:
  309. CPX #PADDLE_BOTTOM ;if the paddle is as far down as it can go
  310. BEQ MovePaddlesNext ;ignore this and go test player 2
  311. TXA ;otherwise, add the paddle speed
  312. ADC #PADDLE_SPEED
  313. STA paddle1 ;and store it
  314. JMP MovePaddlesNext ;then go test player 2
  315. Player1Up:
  316. CPX #PADDLE_TOP ;if the paddle is as far up as it can go
  317. BEQ MovePaddlesNext ;ignore this and go test player 2
  318. TXA ;otherwise, subtract the paddle speed from the paddle position
  319. SBC #PADDLE_SPEED
  320. STA paddle1 ;and store it
  321. MovePaddlesNext: ;everything is the same for player 2
  322. LDA AIplayer ;however, if AI is playing
  323. BNE AIRun ;allow it to make its move
  324. AIRunDone:
  325. LDX paddle2
  326. LDY buttons2
  327. TYA
  328. AND #BUTTON_UP
  329. BNE Player2Up
  330. TYA
  331. AND #BUTTON_DOWN
  332. BNE Player2Down
  333. RTS
  334. Player2Down:
  335. CPX #PADDLE_BOTTOM
  336. BEQ MovePaddlesDone
  337. TXA
  338. ADC #PADDLE_SPEED
  339. STA paddle2
  340. JMP MovePaddlesDone
  341. Player2Up:
  342. CPX #PADDLE_TOP
  343. BEQ MovePaddlesDone
  344. TXA
  345. SBC #PADDLE_SPEED
  346. STA paddle2
  347. MovePaddlesDone:
  348. RTS
  349.  
  350. AIRun: ;basic philosophy is to get the paddle as close to the ball as possible
  351. LDA #0 ;clear out buttons
  352. STA buttons2
  353. LDA AIplayed
  354. BNE AIPlayedDone ;if we played last frame, don't this frame
  355. LDA #1 ;otherwise, indicate that we have
  356. STA AIplayed
  357. LDA paddle2 ;and begin AI logic
  358. CMP bally ;if the ball is above the paddle
  359. BCS AIMoveUp ;move the paddle up
  360. CLC
  361. ADC #PADDLE_HEIGHT
  362. CMP bally ;but if it is below the ball
  363. BCC AIMoveDown ;move the paddle down
  364. JMP AIRunDone
  365.  
  366. AIPlayedDone:
  367. LDA #0
  368. STA AIplayed
  369. JMP AIRunDone
  370.  
  371. AIMoveUp: ;I'm lazy so all it does is write to the button variables
  372. LDA #BUTTON_UP
  373. STA buttons2
  374. JMP AIRunDone
  375.  
  376. AIMoveDown:
  377. LDA #BUTTON_DOWN
  378. STA buttons2
  379. JMP AIRunDone
  380.  
  381. BounceBall:
  382. LDX ballx
  383. LDY bally
  384. CPX #LEFT ;if the ball X position is smaller than the left boundary
  385. BCC CollideLeft ;handle collisions
  386. CPX #RIGHT ;if the ball X is bigger than the right boundary
  387. BCS CollideRight ;do the same
  388. BounceNext:
  389. CPY #TOP ;if x < top
  390. BCC CollideTop
  391. CPY #BOTTOM ;if x > bottom
  392. BCS CollideBottom
  393. RTS
  394.  
  395. CollideTop:
  396. LDA #1 ;set the direction to down
  397. STA ballupdown
  398. RTS
  399.  
  400. CollideBottom:
  401. LDA #0 ;set the direction to up
  402. STA ballupdown
  403. RTS
  404.  
  405. CollideLeft:
  406. LDA paddle1 ;check if we're hitting the paddle
  407. SEC ;this checks if the bottom of the ball is touching the paddle
  408. SBC #PADDLE_SEGMENT_HEIGHT
  409. CMP bally ;check if we're above the paddle
  410. BCS ResetBall1 ;if so, change the score and reset everything
  411. ADC #PADDLE_HEIGHT+PADDLE_SEGMENT_HEIGHT ;check if we're below the paddle
  412. CMP bally
  413. BCC ResetBall1 ;if so, reset
  414. LDA #1 ;otherwise, set the direction to left
  415. STA ballleftright
  416. LDA paddle1 ;and perform angling
  417. ADC #PADDLE_SEGMENT_HEIGHT*3 ;check if we're below the third segment
  418. CMP bally
  419. BCC AngleBall ;if so, angle the ball
  420. LDA paddle1 ;or above the second segment
  421. ADC #PADDLE_SEGMENT_HEIGHT
  422. CMP bally
  423. BCS AngleBall
  424. LDA #BALL_SPEED ;otherwise, reset the default angle
  425. STA ballxspeed
  426. STA ballyspeed
  427. JMP BounceNext ;and go back to test up/down
  428.  
  429. AngleBall:
  430. LDA #BALL_SPEED+1 ;set the y speed 1 higher than the x speed
  431. STA ballyspeed
  432. LDA ballupdown ;and invert the up/down direction
  433. EOR #1
  434. STA ballupdown
  435. JMP BounceNext
  436.  
  437. CollideRight:
  438. LDA cheatenabled ;if cheats are enabled
  439. BNE ResetBall2 ;player 2 always dies
  440. LDA paddle2 ;check if we're hitting the paddle
  441. CMP bally ;check if we're above the paddle
  442. BCS ResetBall2 ;if so, change the score and reset everything
  443. ADC #PADDLE_HEIGHT ;check if we're below the paddle
  444. CMP bally
  445. BCC ResetBall2 ;if so, reset
  446. LDA #0 ;set the direction to right
  447. STA ballleftright
  448. LDA paddle2 ;and perform angling
  449. ADC #PADDLE_SEGMENT_HEIGHT*3 ;check if we're below the third segment
  450. CMP bally
  451. BCC AngleBall ;if so, angle the ball
  452. LDA paddle2 ;or above the second segment
  453. ADC #PADDLE_SEGMENT_HEIGHT
  454. CMP bally
  455. BCS AngleBall
  456. LDA #BALL_SPEED ;otherwise, reset the default angle
  457. STA ballxspeed
  458. STA ballyspeed
  459. JMP BounceNext ;and go back to test up/down
  460.  
  461. ResetBall1:
  462. INC p2score ;increment player 2's score
  463. LDA p2score ;check if player 2 wins
  464. CMP #WINNING_SCORE
  465. BEQ Player2Wins
  466. LDA #16 ;set up the ball position
  467. STA bally
  468. LDA #RIGHT-8
  469. STA ballx
  470. LDA #1 ;and direction
  471. STA ballupdown
  472. LDA #0 ;set up other variables
  473. STA ballleftright ;keep the ball from moving
  474. STA ballxspeed
  475. STA ballyspeed
  476. STA ballmoving
  477. LDA #PADDLE_TOP
  478. STA paddle1
  479. STA paddle2
  480. RTS
  481.  
  482. ResetBall2:
  483. INC p1score ;increment player 1's score
  484. LDA p1score ;check if player 1 wins
  485. CMP #WINNING_SCORE
  486. BEQ Player1Wins
  487. LDA #16 ;set up the ball position
  488. STA ballx
  489. STA bally
  490. LDA #1 ;and direction
  491. STA ballupdown
  492. STA ballleftright
  493. LDA #0 ;and speed
  494. STA ballxspeed
  495. STA ballyspeed
  496. STA ballmoving
  497. LDA #PADDLE_TOP
  498. STA paddle1
  499. STA paddle2
  500. RTS
  501.  
  502. Player1Wins:
  503. ;write out the player 1 wins text
  504. LDA $2002 ;read the PPU status to reset the address
  505. LDA #WINTEXT_HIGH ;write out the bottom address
  506. STA $2006
  507. LDA #WINTEXT_LOW
  508. STA $2006
  509. ;now copy the text over to the PPU RAM
  510. LDX #0
  511. Player1Loop:
  512. LDA p1wintext,x
  513. CMP #$FF ;check if this is the end
  514. BEQ HandleWinnage ;it is, so stop spitting out text
  515. STA $2007 ;otherwise write out the text
  516. INX
  517. JMP Player1Loop
  518.  
  519. Player2Wins:
  520. ;write out the player 2 wins text
  521. LDA $2002 ;read the PPU status to reset the address
  522. LDA #WINTEXT_HIGH ;write out the bottom address
  523. STA $2006
  524. LDA #WINTEXT_LOW
  525. STA $2006
  526. ;now copy the text over to the PPU RAM
  527. LDX #0
  528. Player2Loop:
  529. LDA p2wintext,x
  530. CMP #$FF ;check if this is the end
  531. BEQ HandleWinnage ;it is, so stop spitting out text
  532. STA $2007 ;otherwise write out the text
  533. INX
  534. JMP Player2Loop
  535.  
  536. HandleWinnage:
  537. LDA #STATE_WIN ;change the state to winning
  538. STA state
  539. LDA #0 ;set up the button state
  540. STA pressed
  541. RTS
  542.  
  543. MoveBall:
  544. LDA ballupdown ;if the ball is going up
  545. BEQ MoveUp ;move up
  546. LDA bally ;otherwise, it is going down
  547. CLC
  548. ADC ballyspeed ;so add the ball speed
  549. STA bally ;and store it
  550. JMP NextMove ;then calculate the horizontal ball position
  551. MoveUp:
  552. LDA bally ;move the ball up
  553. SEC
  554. SBC ballyspeed ;subtract the ball speed
  555. STA bally ;and store the ball position
  556. NextMove:
  557. LDA ballleftright
  558. BEQ MoveLeft ;branch to moveleft if the ball is doing so
  559. LDA ballx ;otherwise, it's going right
  560. CLC
  561. ADC ballxspeed ;so move it right
  562. STA ballx
  563. RTS ;and return
  564. MoveLeft:
  565. LDA ballx
  566. SEC
  567. SBC ballxspeed ;going left
  568. STA ballx
  569. RTS
  570.  
  571.  
  572. HandleTitleButtons:
  573. LDY buttons1 ;get player 1's buttons
  574. JSR PreHandleCheats ;handle the cheats
  575. TYA
  576. AND #BUTTON_SELECT ;if select pressed
  577. BNE MoveArrow ;move the arrow on the screen
  578. LDA #0 ;select has been released
  579. STA pressed
  580. TYA
  581. AND #BUTTON_START ;if start is pressed
  582. BNE StartPlay
  583. RTS
  584.  
  585. PreHandleCheats:
  586. LDA cheatenabled ;if cheats have already been enabled
  587. BNE RtsBranch ;return
  588. LDA cheatpressed ;if the previous button is still pressed
  589. BNE HandleCheatsPressed ;go deal with it
  590. TYA ;if no buttons are pressed
  591. BEQ RtsBranch ;return
  592. HandleCheats:
  593. LDA #1 ;indicate that a button has been pressed
  594. STA cheatpressed
  595. LDX cheatcounter ;load the next cheat byte
  596. LDA cheatcode,x
  597. INX ;and increment the counter
  598. STX cheatcounter
  599. CMP #$FF ;if this is the ending marker
  600. BEQ HandleCheatsSuccess ;the user entered the cheat successfully
  601. CMP buttons1 ;if the byte isn't equal to the buttons
  602. BNE HandleCheatsFail ;the user failed
  603. RTS
  604. HandleCheatsSuccess:
  605. LDA #1 ;enable cheats
  606. STA cheatenabled
  607. RTS
  608. HandleCheatsFail:
  609. LDX #0 ;reset the counter to 0
  610. STX cheatcounter
  611. RTS
  612. HandleCheatsPressed:
  613. TYA ;if the previous button hasn't been released
  614. BNE RtsBranch ;go return
  615. LDA #0 ;since it has been, indicate so
  616. STA cheatpressed
  617. JMP RtsBranch ;and return
  618.  
  619. MoveArrow:
  620. LDA pressed ;if it hasn't been released yet
  621. BNE RtsBranch ;don't do anything
  622. LDA #1 ;indicate that it has been pressed
  623. STA pressed
  624. LDA arrowpos
  625. AND #1 ;if it's at the top position
  626. BEQ HandleTop ;erase and redraw it
  627. BNE HandleBottom ;otherwise, it's at the bottom, so erase and redraw it there
  628. RtsBranch:
  629. RTS
  630.  
  631. StartPlay:
  632. LDA arrowpos ;set AI playing status
  633. EOR #1
  634. STA AIplayer
  635. LDA #STATE_PLAYING ;change the state to playing
  636. STA state
  637. LDA #0 ;turn off the PPU so things don't look funky while we copy over the new nametable
  638. STA $2001
  639. LDA #LOW(playfieldnametable) ;set up addresses for indirect copying
  640. STA $30
  641. LDA #HIGH(playfieldnametable)
  642. STA $31
  643. JSR NametableCopy ;actually copy the nametable
  644. JSR CopySprites ;copy the sprites to RAM as well
  645. LDA #PPUREG_2 ;and turn the PPU back on
  646. STA $2001
  647. RAMInit: ;set up the RAM variables
  648. LDA #0
  649. STA ballxspeed
  650. STA ballyspeed
  651. STA ballmoving
  652. STA p1score
  653. STA p2score
  654. STA AIplayed
  655. LDA #1
  656. STA ballupdown
  657. STA ballleftright
  658. LDA #16
  659. STA ballx
  660. STA bally
  661. LDA #PADDLE_TOP
  662. STA paddle1
  663. STA paddle2
  664. RTS
  665.  
  666. HandleTop:
  667. LDA $2002 ;read the PPU status to reset the address
  668. LDA #ARROW_POS_HIGH ;write out the top address
  669. STA $2006
  670. LDA #ARROW_POS_1
  671. STA $2006
  672. LDA #$24 ;and write a blank tile
  673. STA $2007
  674. ;now write the arrow at the new position
  675. LDA $2002 ;read the PPU status to reset the address
  676. LDA #ARROW_POS_HIGH ;write out the bottom address
  677. STA $2006
  678. LDA #ARROW_POS_2
  679. STA $2006
  680. LDA #$28 ;and write an arrow tile
  681. STA $2007
  682. LDA #1
  683. STA arrowpos
  684. RTS
  685.  
  686. HandleBottom:
  687. LDA $2002 ;read the PPU status to reset the address
  688. LDA #ARROW_POS_HIGH ;write out the bottom address
  689. STA $2006
  690. LDA #ARROW_POS_2
  691. STA $2006
  692. LDA #$24 ;and write a blank tile
  693. STA $2007
  694. ;now write the arrow at the new position
  695. LDA $2002 ;read the PPU status to reset the address
  696. LDA #ARROW_POS_HIGH ;write out the top address
  697. STA $2006
  698. LDA #ARROW_POS_1
  699. STA $2006
  700. LDA #$28 ;and write an arrow tile
  701. STA $2007
  702. LDA #0
  703. STA arrowpos
  704. RTS
  705.  
  706. NametableCopy:
  707. LDA $2002 ;read the PPU status to reset the address
  708. LDA #$20 ;write out the nametable address to the PPU ($2000)
  709. STA $2006
  710. LDA #$00
  711. STA $2006
  712. LDY #0 ;reset Y for the copy
  713. LDX #0
  714. NametableCopyLoop:
  715. LDA [$30],y ;load the byte
  716. STA $2007 ;store it at the magic address
  717. INY
  718. CPY #0 ;if we haven't yet copied 8 rows
  719. BNE NametableCopyLoop ;copy more
  720. NametableCopyNext: ;however, if we have, get ready for the next block of 8
  721. INC $31 ;increment the address
  722. INX ;check if we have any more blocks left
  723. CPX #4
  724. BNE NametableCopyLoop
  725. RTS
  726.  
  727. TitleRamInit:
  728. LDA #0
  729. STA arrowpos
  730. STA pressed
  731. STA cheatcounter
  732. STA cheatenabled
  733. STA cheatpressed
  734. RTS
  735.  
  736. HandleWinButtons:
  737. LDA buttons1
  738. AND #BUTTON_START ;check if start is pressed
  739. BEQ WinButtonsDone ;if it isn't, return
  740. LDA pressed ;if START hasn't already been pressed
  741. BEQ WinButtonsSetPressed ;indicate that it has, but don't return
  742. ActualWinButtons:
  743. ;otherwise, set everything up for the title screen
  744. JSR TitleRamInit
  745. JSR ClearSprites
  746. JSR UpdateSpritesTransfer
  747. LDA #0 ;turn off the PPU so things don't look funky while we copy over the new nametable
  748. STA $2001
  749. LDA #LOW(titlenametable) ;set up the nametable address
  750. STA $30
  751. LDA #HIGH(titlenametable)
  752. STA $31
  753. JSR NametableCopy ;actually copy over the nametable
  754. LDA #STATE_TITLE ;and update the state
  755. STA state
  756. LDA #PPUREG_2 ;and turn the PPU back on
  757. STA $2001
  758. WinButtonsDone:
  759. LDA pressed ;if it's been pressed
  760. BNE ActualWinButtons ;we can actually handle it now
  761. RTS
  762. WinButtonsSetPressed:
  763. LDA #1
  764. STA pressed
  765. RTS
  766.  
  767. CopySprites: ;copy the default sprite data to RAM
  768. LDX #0 ;reset X for the copy
  769. CopySpritesLoop:
  770. LDA defaultsprites,x
  771. STA $200,x
  772. INX
  773. CPX #4*9 ;check if we have copied everything
  774. BNE CopySpritesLoop
  775. RTS
  776.  
  777. .bank 1 ;program bank 1, used for data in this case
  778. .org $E000
  779.  
  780. palettes:
  781. ;.db $30,$0F,$10,$00, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F ;background palette data
  782. ;.db $30,$0F,$10,$00, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F ;sprite palette data
  783. .db $0F,$30,$10,$00, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F
  784. .db $0F,$30,$10,$00, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F, $3F,$3F,$3F,$3F
  785.  
  786. playfieldnametable:
  787. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  788. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  789. .db $24,$24,$24,$19,$15,$0A,$22,$0E,$1B,$24,$01,$24,$24,$24,$24,$25
  790. .db $25,$24,$24,$19,$15,$0A,$22,$0E,$1B,$24,$02,$24,$24,$24,$24,$24
  791. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  792. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  793. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  794. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  795. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  796. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  797. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  798. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  799. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  800. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  801. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  802. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  803. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  804. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  805. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  806. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  807. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  808. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  809. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  810. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  811. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  812. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  813. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  814. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  815. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  816. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  817. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  818. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  819. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  820. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  821. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  822. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  823. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  824. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  825. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  826. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  827. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  828. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  829. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  830. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  831. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  832. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  833. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  834. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  835. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  836. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  837. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  838. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  839. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  840. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  841. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  842. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  843. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  844. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  845. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$25
  846. .db $25,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
  847.  
  848. playfieldattributes:
  849. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  850. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  851. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  852. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  853. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  854. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  855. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  856. .db %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
  857.  
  858. p1wintext:
  859. .db $19,$15,$0A,$22,$0E,$1B,$24,$01,$24,$20,$12,$17,$1C,$2B,$01,$2B,$FF ; "PLAYER 1 WINS!1!"
  860.  
  861. p2wintext:
  862. .db $19,$15,$0A,$22,$0E,$1B,$24,$02,$24,$20,$12,$17,$1C,$2B,$01,$2B,$FF ; "PLAYER 2 WINS!1!"
  863.  
  864. cheatcode:
  865. .db BUTTON_UP,BUTTON_DOWN,BUTTON_RIGHT,BUTTON_A,BUTTON_LEFT,BUTTON_B,$FF ; the cheat code specified in a series of buttons terminated by $FF
  866.  
  867. titlenametable:
  868. .incbin "title.nam"
  869.  
  870. defaultsprites:
  871. .db $00,$01,$00,$00 ;ball
  872. .db $00,$02,$00,PADDLE1_X ;paddle 1 segment 1
  873. .db $08,$02,$00,PADDLE1_X ;paddle 1 segment 2
  874. .db $10,$02,$00,PADDLE1_X ;paddle 1 segment 3
  875. .db $18,$02,$00,PADDLE1_X ;paddle 1 segment 4
  876. .db $00,$02,$00,PADDLE2_X ;paddle 1 segment 1
  877. .db $08,$02,$00,PADDLE2_X ;paddle 1 segment 2
  878. .db $10,$02,$00,PADDLE2_X ;paddle 1 segment 3
  879. .db $18,$02,$00,PADDLE2_X ;paddle 1 segment 4
  880.  
  881.  
  882. .org $FFFA ;various vectors
  883. .dw NmiHandler ;NMI Handler routine vector
  884. .dw RESET ;reset vector
  885. .dw 0 ;external interrupt IRQ, not used yet
  886.  
  887. .bank 2 ;bank 2, used for chr data
  888. .org $0000
  889. .incbin "graphics.chr" ;8KB of chr data
Add Comment
Please, Sign In to add comment