当我为我在 6502 程序集中编写的 nes 运行这个 chrome 恐龙克隆时,由于某种原因,它会导致堆栈溢出。
这是代码:
1. isJumping = %00000001
2. isFalling = %00000010
3. isGameOver = %00000001
4.
5. collisionram = $700
6.
7.
8. .segment "HEADER"
9.
10. .byte "NES"
11. .byte $1A
12. .byte $02
13. .byte $01
14. .byte %00000000
15. .byte $00
16. .byte $00
17. .byte $00
18. .byte $00
19. .byte $00, $00, $00, $00, $00
20.
21. .segment "BSS"
22.
23.
24. .segment "ZEROPAGE"
25. gameState: .res 1
26. playerXPos: .res 1
27. playerYPos: .res 1
28. cactus1XPos: .res 1
29. cactus1YPos: .res 1
30. cactus2XPos: .res 1
31. cactus2YPos: .res 1
32. cactusTmpX: .res 1
33. cactusTmpY: .res 1
34. playerState: .res 1
35. playerJumpSpeed: .res 1
36. playerFallSpeed: .res 1
37. cactusMoveSpeed: .res 1
38. collisionHandler: .res 1
39. walkingAnimationState: .res 1
40. walkingAnimationDelay: .res 1
41. playerXCollisionIndex: .res 1
42. playerYCollisionIndex: .res 1
43. cactusXCollisionIndex: .res 1
44. cactusYCollisionIndex: .res 1
45.
46. .segment "STARTUP"
47.
48.
49. .segment "CODE"
50.
51.
52. Reset:
53. sei
54. cld
55. ldx #$40
56. stx $4017
57. ldx #$FF
58. txs
59. inx
60. stx $2000
61. stx $2001
62. stx $4010
63. :
64. bit $2002
65. bpl :-
66. txa
67.
68. clearmem:
69. sta $0000, x
70. sta $0100, x
71. sta $0300, x
72. sta $0400, x
73. sta $0500, x
74. sta $0600, x
75. sta $0700, x
76. lda #$FE
77. sta $0200, x
78. lda #$00
79. inx
80. bne clearmem
81. :
82. bit $2002
83. bpl :-
84. lda #$02
85. sta $4014
86. nop
87. lda #$3F
88. sta $2006
89. lda #$00
90. sta $2006
91. ldx #$00
92.
93. loadpalettes:
94. lda PaletteData, x
95. sta $2007
96. inx
97. cpx #$20
98. bne loadpalettes
99.
100. init:
101. ldx #$00
102. initCollisionRam:
103. lda CollisionMap, x
104. sta collisionram, x
105. inx
106. cpx #$78
107. bne initCollisionRam
108. lda #$04
109. sta cactusMoveSpeed
110. lda #$03
111. sta playerXPos
112. lda #$A2
113. sta playerYPos
114. lda #$A2
115. sta cactus1XPos
116. lda #$F1
117. sta cactus2XPos
118. lda #$AA
119. sta cactus1YPos
120. lda #$9F
121. sta cactus2YPos
122.
123. enableNMI:
124. cli
125. lda #%10010000
126. sta $2000
127. lda #%00011110
128. sta $2001
129.
130. Forever:
131. jmp Forever
132.
133. CheckBackgroundCollision:
134. txa
135. lsr
136. lsr
137. lsr
138. lsr
139. lsr
140. lsr
141. sta collisionHandler
142. tya
143. lsr
144. lsr
145. lsr
146. asl
147. asl
148. clc
149. adc collisionHandler
150. tay
151. txa
152. lsr
153. lsr
154. lsr
155. and #%00000111
156. tax
157. lda collisionram, y
158. and BitMask, x
159. rts
160.
161. checkCactusCollision:
162.
163. ldx #$00
164. stx playerXCollisionIndex
165. stx playerYCollisionIndex
166. stx cactusXCollisionIndex
167. stx cactusYCollisionIndex
168. ldy #$00
169. checkCollisionY:
170. ldx #$00
171. stx playerXCollisionIndex
172. checkCollisionX:
173.
174. lda playerXPos
175. clc
176. adc playerXCollisionIndex
177. pha
178. lda cactusTmpX
179. sta cactusXCollisionIndex
180. pla
181. cmp cactusXCollisionIndex
182. bne :+
183. lda playerYPos
184. clc
185. adc playerYCollisionIndex
186. pha
187. lda cactusTmpY
188. sta cactusYCollisionIndex
189. pla
190. cmp cactusYCollisionIndex
191. bne :+
192. lda gameState
193. ora #isGameOver
194. sta gameState
195. :
196. inx
197. inc playerXCollisionIndex
198. cpx #$18
199. bne checkCollisionX
200. iny
201. inc playerYCollisionIndex
202. cpy #$18
203. bne checkCollisionY
204. endCheckCollision:
205. rts
206.
207.
208. jump:
209. lda playerState
210. ora #isJumping
211. sta playerState
212. lda #$0B
213. sta playerJumpSpeed
214. rts
215.
216. adjustLegPosition:
217. lda #$08
218. clc
219. adc #$0C
220. clc
221. adc #$0D
222. rts
223.
224.
225.
226. update:
227. lda #$01
228. sta $4016
229. lda #$00
230. sta $4016
231. lda $4016
232. and #%00000001
233. cmp #%00000001
234. bne A_not_pressed
235. lda playerState
236. and #isJumping
237. cmp #$00
238. bne A_not_pressed
239. lda playerState
240. and #isFalling
241. cmp #$00
242. bne A_not_pressed
243. jsr jump
244. A_not_pressed:
245. lda $4016
246. and #%00000001
247. cmp #%00000001
248. bne B_not_pressed
249. B_not_pressed:
250. lda $4016
251. and #%00000001
252. cmp #%00000001
253. bne Select_not_pressed
254. Select_not_pressed:
255. lda $4016
256. and #%00000001
257. cmp #%00000001
258. bne Start_not_pressed
259. Start_not_pressed:
260. lda $4016
261. and #%00000001
262. cmp #%00000001
263. bne Up_not_pressed
264. lda playerState
265. and #isJumping
266. cmp #$00
267. bne Up_not_pressed
268. lda playerState
269. and #isFalling
270. cmp #$00
271. bne Up_not_pressed
272. jsr jump
273. Up_not_pressed:
274. lda $4016
275. and #%00000001
276. cmp #%00000001
277. bne Down_not_pressed
278. Down_not_pressed:
279. lda $4016
280. and #%00000001
281. cmp #%00000001
282. bne Left_not_pressed
283. Left_not_pressed:
284. lda $4016
285. and #%00000001
286. cmp #%00000001
287. bne Right_not_pressed
288. Right_not_pressed:
289. end_input:
290. lda cactus1XPos
291. sec
292. sbc cactusMoveSpeed
293. sta cactus1XPos
294. lda cactus2XPos
295. sec
296. sbc cactusMoveSpeed
297. sta cactus2XPos
298. inc walkingAnimationDelay
299. lda walkingAnimationDelay
300. cmp #$06
301. bne :+
302. lda #$00
303. sta walkingAnimationDelay
304. :
305. lda playerState
306. and #isJumping
307. cmp #$00
308. bne setWalkingStateToZero
309. lda playerState
310. and #isFalling
311. cmp #$00
312. bne setWalkingStateToZero
313. lda walkingAnimationDelay
314. cmp #$05
315. bne endWalkingAnimState
316. lda walkingAnimationState
317. cmp #$01
318. bne :+
319. lda #$02
320. sta walkingAnimationState
321. jmp endWalkingAnimState
322. :
323. lda #$01
324. sta walkingAnimationState
325. jmp endWalkingAnimState
326. setWalkingStateToZero:
327. lda #$00
328. sta walkingAnimationState
329. endWalkingAnimState:
330.
331. checkForJump:
332. lda playerState
333. and #isJumping
334. cmp #$00
335. beq :+
336. lda playerYPos
337. sec
338. sbc playerJumpSpeed
339. sta playerYPos
340. dec playerJumpSpeed
341. lda playerJumpSpeed
342. cmp #$00
343. bne :+
344. lda playerState
345. eor #isJumping
346. ora #isFalling
347. sta playerState
348. lda #$00
349. sta playerFallSpeed
350. :
351. checkForFall:
352. lda playerState
353. and #isFalling
354. cmp #$00
355. beq :+
356. lda playerYPos
357. clc
358. adc playerFallSpeed
359. sta playerYPos
360. inc playerFallSpeed
361. ldx playerXPos
362. ldy playerYPos
363. jsr CheckBackgroundCollision
364. beq :+
365. lda playerState
366. eor #isFalling
367. sta playerState
368. :
369. lda cactus1XPos
370. clc
371. adc #$08
372. sta cactusTmpX
373. lda cactus1YPos
374. clc
375. adc #$08
376. sta cactusTmpY
377. jsr checkCactusCollision
378. lda cactus2XPos
379. sec
380. sbc #$08
381. sta cactusTmpX
382. lda cactus2YPos
383. clc
384. adc #$08
385. sta cactusTmpY
386. jsr checkCactusCollision
387. rts
388.
389. draw:
390. lda #$08
391. clc
392. adc playerYPos
393. sta $200
394. lda #$00
395. sta $201
396. sta $202
397. lda #$08
398. clc
399. adc playerXPos
400. sta $203
401. lda #$08
402. clc
403. adc playerYPos
404. sta $204
405. lda #$01
406. sta $205
407. lda #$00
408. sta $206
409. lda #$10
410. clc
411. adc playerXPos
412. sta $207
413. lda #$08
414. clc
415. adc playerYPos
416. sta $208
417. lda #$02
418. sta $209
419. lda #$00
420. sta $20A
421. lda #$18
422. clc
423. adc playerXPos
424. sta $20B
425. lda #$08
426. clc
427. adc playerYPos
428. sta $20C
429. lda #$03
430. sta $20D
431. lda #$00
432. sta $20E
433. lda #$20
434. clc
435. adc playerXPos
436. sta $20F
437. lda #$10
438. clc
439. adc playerYPos
440. sta $210
441. lda #$04
442. clc
443. adc #$0C
444. sta $211
445. lda #$00
446. sta $212
447. lda #$08
448. clc
449. adc playerXPos
450. sta $213
451. lda #$10
452. clc
453. adc playerYPos
454. sta $214
455. lda #$05
456. clc
457. adc #$0C
458. sta $215
459. lda #$00
460. sta $216
461. lda #$10
462. clc
463. adc playerXPos
464. sta $217
465. lda #$10
466. clc
467. adc playerYPos
468. sta $218
469. lda #$06
470. clc
471. adc #$0C
472. sta $219
473. lda #$00
474. sta $21A
475. lda #$18
476. clc
477. adc playerXPos
478. sta $21B
479. lda #$18
480. clc
481. adc playerYPos
482. sta $21C
483. lda #$07
484. clc
485. adc #$0C
486. clc
487. adc #$0D
488. sta $21D
489. lda #$00
490. sta $21E
491. lda #$08
492. clc
493. adc playerXPos
494. sta $21F
495. lda #$18
496. clc
497. adc playerYPos
498. sta $220
499. lda walkingAnimationState
500. cmp #$01
501. beq setWalkingToWalking1
502. cmp #$02
503. beq setWalkingToWalking2
504. jsr adjustLegPosition
505. jmp :+
506. setWalkingToWalking1:
507. jsr adjustLegPosition
508. clc
509. adc #$02
510. jmp :+
511. setWalkingToWalking2:
512. jsr adjustLegPosition
513. clc
514. adc #$03
515. :
516. sta $221
517. lda #$00
518. sta $222
519. lda #$10
520. clc
521. adc playerXPos
522. sta $223
523. lda #$18
524. clc
525. adc playerYPos
526. sta $224
527. lda #$09
528. clc
529. adc #$0C
530. clc
531. adc #$0D
532. sta $225
533. lda #$00
534. sta $226
535. lda #$18
536. clc
537. adc playerXPos
538. sta $227
539. lda #$08
540. clc
541. adc cactus1YPos
542. sta $228
543. lda #$04
544. sta $229
545. lda #$00
546. sta $22A
547. lda #$08
548. clc
549. adc cactus1XPos
550. sta $22B
551. lda #$08
552. clc
553. adc cactus1YPos
554. sta $22C
555. lda #$05
556. sta $22D
557. lda #$00
558. sta $22E
559. lda #$10
560. clc
561. adc cactus1XPos
562. sta $22F
563. lda #$10
564. clc
565. adc cactus1YPos
566. sta $230
567. lda #$05
568. clc
569. adc #$0F
570. sta $231
571. lda #$00
572. sta $232
573. lda #$08
574. clc
575. adc cactus1XPos
576. sta $233
577. lda #$10
578. clc
579. adc cactus1YPos
580. sta $234
581. lda #$05
582. clc
583. adc #$10
584. sta $235
585. lda #$00
586. sta $236
587. lda #$10
588. clc
589. adc cactus1XPos
590. sta $237
591. lda #$08
592. clc
593. adc cactus2YPos
594. sta $238
595. lda #$16
596. sta $239
597. lda #$00
598. sta $23A
599. lda #$08
600. clc
601. adc cactus2XPos
602. sta $23B
603. lda #$08
604. clc
605. adc cactus2YPos
606. sta $23C
607. lda #$17
608. sta $23D
609. lda #$00
610. sta $23E
611. lda #$10
612. clc
613. adc cactus2XPos
614. sta $23F
615. lda #$10
616. clc
617. adc cactus2YPos
618. sta $240
619. lda #$26
620. sta $241
621. lda 00
622. sta $242
623. lda #$08
624. clc
625. adc cactus2XPos
626. sta $243
627. lda #$10
628. clc
629. adc cactus2YPos
630. sta $244
631. lda #$27
632. sta $245
633. lda #$00
634. sta $246
635. lda #$10
636. clc
637. adc cactus2XPos
638. sta $247
639. lda #$18
640. clc
641. adc cactus2YPos
642. sta $248
643. lda #$36
644. sta $249
645. lda #$00
646. sta $24A
647. lda #$08
648. clc
649. adc cactus2XPos
650. sta $24B
651. lda #$18
652. clc
653. adc cactus2YPos
654. sta $24C
655. lda #$37
656. sta $24D
657. lda #$00
658. sta $24E
659. lda #$10
660. clc
661. adc cactus2XPos
662. sta $24F
663. lda #$20
664. clc
665. adc cactus2YPos
666. sta $250
667. lda #$46
668. sta $251
669. lda #$00
670. sta $252
671. lda #$08
672. clc
673. adc cactus2XPos
674. sta $253
675. lda #$20
676. clc
677. adc cactus2YPos
678. sta $254
679. lda #$47
680. sta $255
681. lda #$00
682. sta $256
683. lda #$10
684. clc
685. adc cactus2XPos
686. sta $257
687. rts
688.
689. NMI:
690. lda #$00
691. sta $2003
692. lda #$02
693. sta $4014
694. lda gameState
695. and #isGameOver
696. cmp #$00
697. bne :+
698. jsr draw
699. jsr update
700. :
701. rti
702.
703. PaletteData:
704. .byte $30,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D
705. .byte $30,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D
706.
707. CollisionMap:
708. .byte %00000000, %00000000, %00000000, %00000000
709. .byte %00000000, %00000000, %00000000, %00000000
710. .byte %00000000, %00000000, %00000000, %00000000
711. .byte %00000000, %00000000, %00000000, %00000000
712. .byte %00000000, %00000000, %00000000, %00000000
713. .byte %00000000, %00000000, %00000000, %00000000
714. .byte %00000000, %00000000, %00000000, %00000000
715. .byte %00000000, %00000000, %00000000, %00000000
716. .byte %00000000, %00000000, %00000000, %00000000
717. .byte %00000000, %00000000, %00000000, %00000000
718. .byte %00000000, %00000000, %00000000, %00000000
719. .byte %00000000, %00000000, %00000000, %00000000
720. .byte %00000000, %00000000, %00000000, %00000000
721. .byte %00000000, %00000000, %00000000, %00000000
722. .byte %00000000, %00000000, %00000000, %00000000
723. .byte %00000000, %00000000, %00000000, %00000000
724. .byte %00000000, %00000000, %00000000, %00000000
725. .byte %00000000, %00000000, %00000000, %00000000
726. .byte %00000000, %00000000, %00000000, %00000000
727. .byte %11111111, %00000000, %00000000, %00000000
728. .byte %11111111, %00000000, %00000000, %00000000
729. .byte %00000000, %00000000, %00000000, %00000000
730. .byte %00000000, %00000000, %00000000, %00000000
731. .byte %00000000, %00000000, %00000000, %00000000
732. .byte %00000000, %00000000, %00000000, %00000000
733. .byte %00000000, %00000000, %00000000, %00000000
734. .byte %00000000, %00000000, %00000000, %00000000
735. .byte %00000000, %00000000, %00000000, %00000000
736. .byte %00000000, %00000000, %00000000, %00000000
737. .byte %00000000, %00000000, %00000000, %00000000
738.
739. BitMask:
740. .byte %10000000
741. .byte %01000000
742. .byte %00100000
743. .byte %00010000
744. .byte %00001000
745. .byte %00000100
746. .byte %00000010
747. .byte %00000001
748.
749. .segment "VECTORS"
750. .word NMI
751. .word Reset
752. .segment "CHARS"
753. .incbin "chrrom.chr"
(这与 checkBackgroundCollision 和 CollisionMap afaik 无关)
问题似乎出现在第 386 行,它第二次跳转到 checkCactusCollision 子例程(第 161 行),但是,上一次跳转它没有做任何事情。我已经尝试了很多事情,包括使代码更接近子程序,删除 checkCactusCollision 中的推送和拉取命令,并将它们替换为用于存储 A 寄存器的临时内存地址,甚至只是删除子程序跳转并重复代码checkCactusCollision 两次,但我仍然无法弄清楚。
帮助将不胜感激,谢谢。