设为首页收藏本站

 找回密码
 立即注册
搜索
查看: 186|回复: 0

[原创] [FC][Mapper19][IRQ学习源码]

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    ( c5 j& a. e2 o" F: A+ Y
  2. ;FlameCyclone 202307105 i6 u" N' R/ z

  3. & N- H8 C; f- G. ]
  4. ;文件头  x7 y' a: q# ]+ h) H- _4 d: k
  5. ;======================================================================
    3 i& M! [5 Q$ n) e& @+ N
  6. .INESPRG 4                                              ;16KB PRG 数量
    ; i0 t* g4 }7 i( y( D2 k; d; E
  7. .INESCHR 1                                               ;8KB CHR 数量
    8 x% [: J/ N& \9 q9 W
  8. .INESMAP 19                                                 ;mapper 19
    7 r2 C  w/ m1 P- q
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    3 x$ W! k( q( ~% S+ M
  10. 6 ?* m3 R9 E$ R# L
  11. ;必要条件
    3 b+ P$ c$ I% I: n5 f7 f2 C8 z" g
  12. ;1.持有CHR ROM
    . L9 ]- q7 S( q% [
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
      W2 |% u& Z9 m( z+ J4 a
  14. ;3.精灵内存(OAM)不为空5 l  n' Z7 u% N4 R8 C' s

  15. 2 X4 W+ N1 t' O
  16. ;==================================================( }; ~' W) S  }% O
  17. ;NES端口常量
    9 c( x* s4 ]- v% `8 i2 q; L  l" B
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    : y; O4 i" R! i- F2 p
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    + L; Y& ?7 d& o
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位; d3 Y; o4 ^/ E& o' p
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    5 J, I- W/ v) H# O4 w( M
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    + k/ S$ t3 W+ H  \
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 9 b6 f( ]9 g4 A+ D+ \5 s
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加/ [+ h: V. L5 U
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 1 G. |5 M; Z* ]& `: }- ]1 L
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存9 O% v! j8 \& g% r
  27. APU_STATUS              =   $4015   ;声音通道切换; ^/ s. T2 ?8 n: y& t' a
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    9 P# P, I( F; y6 L/ ^" a
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    & s4 t4 D: H! I9 f" `# `" i

  30. - u- K7 Z1 G+ S, U; ~' L: _
  31. ;==================================================
    2 v' K( x$ g2 C
  32. ;MAPPER 19端口常量% Z+ j" q0 }: a0 ~2 t% \! w
  33. M19_CHR_0000    =   $8000
    ; `  U! Y0 D* t% }
  34. M19_CHR_0400    =   $8800" K" j- @+ t# t- \1 O" Q9 ^
  35. M19_CHR_0800    =   $9000
    - O8 {# _% H( g
  36. M19_CHR_0C00    =   $9800+ t+ C3 I: i9 [# ^9 v
  37. M19_CHR_1000    =   $A000
    1 e: F+ G3 X) |1 S  ]  D! ?# [5 P
  38. M19_CHR_1400    =   $A8007 t! ~3 q: d- ]/ \1 D2 N' j* Q3 F
  39. M19_CHR_1800    =   $B000
    " Q2 B0 `. ]8 g1 N
  40. M19_CHR_1C00    =   $B8005 r6 M9 W1 N0 v+ t- W& N9 h
  41. M19_NT_2000     =   $C000
    0 w4 ~; v: M/ V4 r/ z& {
  42. M19_NT_2400     =   $C800( O* [9 G& F4 O. D9 Z  d
  43. M19_NT_2800     =   $D000
    9 p: D7 J0 I6 |) X5 L
  44. M19_NT_2C00     =   $D800" e  _, }! _# y  ^+ }
  45. M19_PRG_8000    =   $E0001 n; v2 U- J+ Z' _+ `2 Q/ O9 W! w! {3 [
  46. M19_PRG_A000    =   $E8009 i4 o/ o4 s7 R
  47. M19_PRG_C000    =   $F000
    1 b2 r: }; S, L7 S+ h4 Q# b( k" V
  48. M19_IRQ_COUNT_L =   $5000# ]" v* A5 u4 I& |! s
  49. M19_IRQ_COUNT_H =   $5800
    , ~/ x4 R5 s0 R2 ~. C
  50. , {7 p$ W3 s$ M3 C% ?8 ?1 ?. ^
  51. ;==================================================
    : {( Y- U) |' i
  52. ;程序块配置
    4 x8 z4 |9 U' Z( A6 e2 _3 B5 [
  53. BANK_DATA_MASK          = $07
    ' I# G! ~( c4 z( {, L- I8 e  X
  54. ;--------------------------------------------------! T, Q+ T1 r* B; K& s! a3 |
  55. RESET_BANK              = $07
    , R- y3 Z8 z4 Z; X2 H# y+ m! }2 C* q0 h
  56. RESET_ADDR              = $FC00
    8 |; k* a( F6 J; d; Z; G( ^1 `! }

  57. 9 N5 w7 o" E. H
  58. ;==================================================
    % M+ y+ W+ A  B- [# T
  59. ;图像块配置( v0 X$ @3 [$ V6 g% F" A! ?
  60. CHR_DATA_BANK           = $08
    / z/ Z" M6 s2 D
  61. 5 l7 V* G+ F# j* U2 w5 }- ?' u
  62. ;==================================================% O- s# g9 d- E6 H; z
  63. ;零页内存地址配置
    8 B/ b0 A% V9 S7 c' F; w+ H1 _* ~
  64. Use_Ram_Addr            = $80
    0 Q. G- `# P# T7 }5 ~6 O. o/ m
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    " x  K6 W3 ]" ~; N: S  e0 Z4 u
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $010 o8 d( W. b- z. |- Z8 @6 F
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    & A4 k& r8 t& Q* |
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    / _8 Q* Y6 ~+ V; _: s9 a, U1 |: \
  69. FC_Data_L               = PPU_Scroll_V + $01
    : g' T) |7 |% G) ~) ]2 j
  70. FC_Data_H               = FC_Data_L + $01
    . s8 y5 T" R  J4 ^. }
  71. FC_Data_Buf             = FC_Data_H + $01' ^6 l( |6 {1 e' u$ u
  72. ;==================================================. T$ d+ X4 B, ~3 M2 ?' @
  73. # c9 Z! k, n( j7 s) D
  74. GAMEPAD_MERGE_FLAG = $04
      E9 ~0 S3 [& n/ R

  75. 5 m. x' u5 k: t) p* `& B
  76. Gamepad_Keep            =       FC_Data_Buf + 1; K# y3 H: l& c  W1 U' O
  77. Gamepad_Once            =       Gamepad_Keep + 27 i- V( u$ Q. R
  78. Gamepad_Temp            =       Gamepad_Once + 2( z( Z" l6 O* u+ p2 {2 `' P) Q& u
  79.                                 
    & m, e3 x3 j1 {! y% c
  80. Gamepad_0_State         =       Gamepad_Temp + 2% v8 k0 i- a3 x. |
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    6 k& u# A8 L' `9 [3 X& p3 t
  82. Gamepad_0_Value         =       Gamepad_1_State + 11 f' T; k1 R+ r* d/ }
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    6 M8 q& v! x+ e; p
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    9 y9 {7 l/ B- N5 X$ {4 O0 L
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ) b8 N4 H8 p, q7 }6 j. t
  86. 6 G1 z  C" {6 D' X$ d, R& z
  87. ;==================================================; I  ]* O! F2 }. H( W% b( l  U
  88. IRQ_Index               =       Gamepad_Merge + $01) g& L$ p4 f9 x. N3 M; l
  89. ;==================================================  ^5 t+ l9 l( H2 A+ ]

  90. + J# F( Z1 p, q% f; z
  91. ;CHR图形数据/ R7 j; m$ f4 B
  92. ;==================================================
    * Z7 T3 A# {1 W- T9 ]) a
  93. .BANK CHR_DATA_BANK2 Y8 u- N( K4 d) z5 {- R) M2 j
  94. .INCBIN "chr_bank/chr_data.chr"5 Q  y' @" V+ D' N; Z
  95. 8 M0 x8 R, p5 X) R
  96. .BANK RESET_BANK & BANK_DATA_MASK
    * f  V& B( \, b# c( \% u4 y8 Z
  97. .ORG RESET_ADDR# q/ K4 {" [* m, T& B/ I! [
  98. 2 w3 B) A% e& {1 `
  99. ;--------------------------------------------------& G9 X- Z* u  ~6 u5 z
  100. Attributes_Data3 k2 @. p+ ^/ X" X. n
  101. ;命名表属性" Q; S, K! p5 a4 I
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$007 K1 c( R& v! g  j
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    # F% O% j2 ~) k0 ]
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA* j1 D& T8 S* ?" Y9 c/ ^
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    2 A% f5 h. ]$ `/ R: a$ t: |
  106. ;--------------------------------------------------, D) u: I3 n6 S. W& O4 H( n
  107. ;调色板数据
    ; z5 l5 }" G8 [, J1 x5 A5 S( m6 e
  108. Palette_Data
      \; V0 D0 j: `  {1 |
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
      h8 P3 J; N/ |) v: }6 m, k
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    1 S5 B$ Z. u8 ^
  111. 4 O3 T' m. a& `% \/ V
  112. ;==================================================* t& T7 G3 [% K
  113. ;命名表初始化
    % [; I( t1 b# w, D, L
  114. Init_Name_Table
    8 U9 N3 q, S0 M$ o
  115. LDA #$20% u( p8 k  W/ }
  116. STA PPU_ADDRESS
    2 J) `5 t4 L7 k, S) y$ Z! B) O4 h2 g1 V, e
  117. LDA #$00  y. l7 s% W) P: h4 D: J, {$ O
  118. STA PPU_ADDRESS
    2 ~, e/ b0 v; b) ?- f' ]) m  v; d
  119. LDA #$00
    1 `8 ?2 l0 Z2 ?" ~3 `) W# Q
  120. LDY #$00
    - V# A; ~4 W; l- ^$ T5 L6 s8 i8 H6 c
  121. LDX #$10% N! t/ g0 O* l  \/ S
  122. Init_Name_Table_Write8 @  `4 F. f9 t: V  O
  123. STA PPU_DATA- K3 `( e# l6 G. @3 [! R
  124. INY5 T. V/ y  U4 B& P1 o5 p
  125. BNE Init_Name_Table_Write# q8 U6 ^0 H  d2 X" W) |* b8 H+ `
  126. DEX; C0 r# w) Z- ?+ o/ O, }6 Z- |. ?
  127. BNE Init_Name_Table_Write; z, g$ q  C( S
  128. RTS& `0 z# g8 x" }7 W3 r5 ?# O
  129. 3 T% M& q4 H1 N9 G
  130. ;==================================================
    7 r  `9 c! }$ o
  131. ;调色板初始化% _* l6 \/ a7 F: Z( {* \5 e- G% R7 Q. o
  132. Init_Palette2 N. L4 O2 W+ J. `6 B! `; Z$ j
  133. BIT PPU_STATUS
    - M, v- s6 N. J2 C
  134. LDA #$3F
    % z- S: `8 I4 X& V$ w9 _( q8 f" \
  135. STA PPU_ADDRESS, D0 `  {( m% z& A2 ]
  136. LDA #$00  j4 B6 X- p; ?% a7 e, n5 t7 V
  137. STA PPU_ADDRESS0 c3 J) v& t# W9 h5 d
  138. LDX #$00
    $ {$ ~8 Z% c* n/ N7 r3 [
  139. Init_Palette_Write9 L. S+ V% B) g! B$ s8 `% |2 n- F
  140. LDA Palette_Data,X# O1 D$ O: b9 ^( R! F  s( o7 q
  141. STA PPU_DATA0 c1 p- m. ~! S
  142. INX
    - C# @0 Y& R* ^8 G1 `
  143. CPX #$20
    $ H$ l; V6 O4 B- N# }6 D, M
  144. BCC Init_Palette_Write8 d. w7 q. b/ R2 f, ^
  145. RTS
    " O) T7 k1 @% o8 z8 d

  146. . i6 Y% A7 P$ }4 c; {# D0 S% h& M
  147. ;==================================================+ o2 T4 Y% H, w1 A1 G
  148. ;设置命名表属性
    7 M: f0 _: z; p) ]
  149. Init_NameTable_Attributes
    , q# s" t; B+ a1 r' S9 ?3 e
  150. BIT PPU_STATUS( L4 j, w4 x" @7 v) f  o9 Z2 X
  151. LDA #$23
    3 O3 N0 \% v8 y0 k. I
  152. STA PPU_ADDRESS
    4 b1 v& {3 a4 ]5 p8 d' e7 T
  153. LDA #$C0
    + T8 g6 f$ v% w0 R
  154. STA PPU_ADDRESS" i1 l3 n5 h0 |9 _# ?
  155. LDX #$00
    % b3 U, U) l+ m9 T. H/ p7 K) B
  156. Init_NameTable_Attributes_Write1 J) Z/ g/ i0 h
  157. LDA Attributes_Data,X
    ! T9 f, l4 T1 j# A
  158. STA PPU_DATA
    " M: y7 p+ {2 o# Y! Z
  159. INX! Y2 p5 N/ `5 A. @
  160. CPX #$40
    ! T* [* F3 s- _. c
  161. BCC Init_NameTable_Attributes_Write
    + Y$ t3 o7 J2 i3 e6 }+ G. v
  162. RTS
    " p2 h6 ]3 H; H) E3 o- N0 F

  163. 8 V) l* m' F. ]4 |" j, A% K2 t
  164. ;==================================================
    0 B! f0 u; l' B& D0 w" E
  165. ;初始化命名表文本# q" y6 o1 \5 c/ U
  166. Init_Name_Table_Text
    : |! b0 b" t- F# m
  167. BIT PPU_STATUS- M5 \0 T! f7 Q# u
  168. LDA #$20# u% I0 C( Z2 \+ q. `( h+ Z
  169. STA PPU_ADDRESS7 [- c' H/ q0 M# e" C% `9 k
  170. LDA #$007 v& B7 V6 m. L8 b
  171. STA PPU_ADDRESS4 J$ @) B% }: S6 N. M
  172. LDA #$00$ D, P5 f5 o/ b
  173. STA FC_Data_Buf
    $ v8 I/ ]8 v# O0 W& Q% [9 C4 W! l
  174. LDY #30
    4 d6 x. W9 k/ W$ f
  175. Init_Name_Table_Text_Write
    3 C  y+ P3 F  M7 d- K& b
  176. LDX #32
    . M  O) ^7 l6 H% Z! D0 g' T
  177. Init_Name_Table_Text_Write_Char* K$ m! V' o* L0 L; w
  178. LDA #'0'. y! \2 [( e) l! N" y
  179. CLC3 ^6 K6 d5 [! f
  180. ADC FC_Data_Buf
    ! t+ _) U8 i# v: v2 T
  181. STA PPU_DATA
    * M/ _! T: m/ d) n
  182. DEX
    : j1 P6 D% G% m2 C
  183. LDA #$14
    , Q" A8 `& b# J/ i1 z! m
  184. STA PPU_DATA
    / [& A% U3 L  u7 N" F+ T
  185. DEX+ P0 y; a5 U* H2 o  R8 L
  186. BNE Init_Name_Table_Text_Write_Char3 t( Y8 F( b: i% Q
  187. INC FC_Data_Buf
    - J! ]# ~" N" k6 ?4 z, b; d
  188. DEY
    - Q! I) _/ M9 f" Y5 I; r) i
  189. BNE Init_Name_Table_Text_Write
    1 S3 Q- G% h- e7 z0 }" P3 O( d# S- [
  190. RTS3 ]& {0 D' j" _4 I% ?% i
  191. / D; [8 X+ Q7 W
  192. ;==============================; N2 B# p1 x3 S2 a( R; f2 [2 Z
  193. Init_OAM_Ram;初始化精灵内存
    1 S2 U/ r1 m5 t6 \
  194. LDX #$003 X+ E8 N1 y0 Z6 c. K) y
  195. LDA #$00
    & F9 x' V: {! k8 Q0 K, n4 P
  196. STA PPU_OAM_ADDR
    / h# Q2 {  t; ?/ u
  197. LDA #$F8
    & C$ ]9 W. j$ Y+ x4 \! G8 [, v/ Z
  198. Init_OAM_Ram_Write
    & L, Q, K0 K, `4 n
  199. STA PPU_OAM_DATA
    4 i4 Z9 G- w  R( V
  200. INX
    5 F  [  T6 ]( Y- Q
  201. BNE Init_OAM_Ram_Write
    6 K/ A* p3 z& V6 @8 ~. [1 q
  202. RTS$ r6 `+ D' i" s: w* y/ D

  203. ) s7 `, Z1 z% L" I1 Y
  204. GamepadProcess;手柄处理
    0 m" G& z+ I5 |9 \
  205. JSR GamepadDatacan
    : i: c; z8 A0 O7 D# U
  206. LDA <Gamepad_0_Value- Y/ o5 S0 ^* m
  207. STA <Gamepad_0_State+ c3 i- V+ v7 @
  208. LDA <Gamepad_1_Value( [) h9 }7 X, P9 G+ X4 q2 O; c1 }
  209. STA <Gamepad_1_State2 j6 N7 w5 h3 @! G' c% J, i  F
  210. JSR GamepadDatacan3 [9 j, k9 E3 V1 s
  211. LDX #$01
    8 |0 m9 N. E! ]4 s5 V
  212. GamepadMergeCheck;合并手柄输入检查
    ! z, {5 |8 O4 b8 h6 h! O
  213. LDA <Gamepad_0_Value,X
    0 ^. Q. L' c- X7 I$ T, S
  214. CMP <Gamepad_0_State,X% ?( A% u6 t: \( F
  215. BEQ GamepadMergeInput! z. P5 V9 ^+ Q5 @
  216. LDA <Gamepad_Temp,X
    9 u* D" f4 s" I3 f, h7 y  z
  217. STA <Gamepad_0_Value,X6 F: X9 m9 Q2 J1 z1 p; Y3 K* ]
  218. GamepadMergeInput;合并手柄输入
    ' e  T5 n3 W6 V0 x$ B
  219. DEX
    7 Y/ g$ U7 j5 Z+ W, s4 H2 v
  220. BPL GamepadMergeCheck& u. r, J7 x- p$ @6 k6 Z) f! |, S4 @& {
  221. LDA <Gamepad_Merge* t* A7 S/ v# ?. T: q+ R
  222. AND #GAMEPAD_MERGE_FLAG/ F" S' N0 j8 b& O
  223. BNE GamepadStateProcess
    . c- w4 d0 x  K) i) M
  224. LDA <Gamepad_0_Value. _( i1 l0 d: l
  225. ORA <Gamepad_1_Value( L  P/ @3 {) L( K8 ?
  226. STA <Gamepad_0_Value# o0 n% l$ Q3 Q
  227. GamepadStateProcess;手柄状态处理
      |8 }8 W+ s5 E- Q1 Z' ~: }
  228. LDX #$01& L: n9 J+ Y+ y
  229. GamepadStateSave;手柄状态保存
    6 g; w- V3 W5 [) B  Y5 }
  230. LDA <Gamepad_0_Value,X
    8 ~0 Y6 I$ ^- P
  231. TAY
    : @3 w' j1 Q  b/ p% s) T0 V
  232. EOR <Gamepad_Temp,X8 S& y( `0 d, S# o5 U/ L0 @
  233. AND <Gamepad_0_Value,X
    ; p6 l; K, c, \
  234. STA <Gamepad_Once,X
    ) S, n. O& S$ S3 A7 J3 G+ k, W
  235. STY <Gamepad_Keep,X
    , z( V) l. h, N8 H) T2 t+ ?1 t
  236. STY <Gamepad_Temp,X
    7 h  H" r) l7 e% G. f. s
  237. DEX
    % C  h+ [/ G- W
  238. BPL GamepadStateSave% \9 r' f& [" S$ U8 i
  239. RTS7 N+ X' n6 M: N- }9 {/ [  `

  240. " y5 e) \4 b& b5 Q( Y% \, U
  241. GamepadDatacan;手柄数据扫描
    & u) b- Z. C, F* o" {
  242. LDX #$01" j5 _2 g1 s3 ?
  243. STX $4016- v) t$ Q6 L  R$ R! D3 y+ g2 F
  244. DEX
    8 e! n! X; P2 T# W
  245. STX $40167 J# A& ^( N4 o0 o; b5 T, X
  246. LDY #$089 \3 ?7 `6 S+ |7 l. D, y
  247. GamepadPortScan;手柄端口扫描" z" V/ j) A: V) K+ _
  248. LDA $4016( q2 @) {' m( l1 ~9 G
  249. STA <Gamepad_Port_Value
    " K; [( _; ?2 ]& C0 f: l5 N
  250. LSR A
    " l' L# |+ H$ i( n" H& {
  251. ORA <Gamepad_Port_Value) g$ g! v$ O+ U; A& |% k2 s
  252. LSR A
    $ g8 C( E0 S/ ~4 X7 w* x5 T
  253. ROL <Gamepad_0_Value& J7 \4 W9 }7 r3 o; h' O: W+ v
  254. LDA $4017
    3 ^" r# d4 J3 o7 A8 Q& E
  255. STA <Gamepad_Port_Value8 [/ r% J8 U% Z8 W" R1 ^7 R/ K. o
  256. LSR A9 q8 X7 m" \9 z; d* F' O* Z/ K7 O
  257. ORA <Gamepad_Port_Value9 a  z9 M4 p' D/ T
  258. LSR A& T  A0 q! M2 _8 C3 M
  259. ROL <Gamepad_1_Value
    0 Q5 Z" J$ }0 A2 v, u/ g2 @: x
  260. DEY' E! L0 l4 l, h1 r  i7 [6 A/ y
  261. BNE GamepadPortScan1 a" n& c) N, h4 I4 B* e
  262. RTS
    6 u  E7 B4 `( E) \& q+ r: |, N5 C
  263. 9 B7 V8 ~1 C. `% ]" J
  264. ;==================================================
    6 j8 Z$ y9 T) m, N  K- D
  265. ;PPU处理
    ( l& q( W- K# d, [0 |; A+ G- g4 [
  266. PPU_Process
    - O* Z" ^3 ^, d
  267. LDA #$00
    4 g$ T: o, p0 ]3 j
  268. STA PPU_MASK
    3 |& u1 o; a" t" n" C) H9 V

  269. 0 L* [$ b6 @" l; T  l7 z
  270. BIT PPU_STATUS
    0 A3 O+ N% z& B* J+ s4 o& O
  271. LDA #$20' s6 S+ t; k% d& h& K5 n
  272. STA PPU_ADDRESS
    * @# T/ b  z- ^2 r+ T9 \: a0 i3 W5 t
  273. LDA #$00
    / I# E! Q$ J+ ]9 a4 j) k8 S- g) B+ ]' {
  274. STA PPU_ADDRESS0 |( `  G( h% r- b" Q1 }

  275. / Y4 N0 P' [7 c5 h, b; H
  276. STA PPU_SCROLL
    2 ^- `- Y+ E2 b: B$ ^
  277. STA PPU_SCROLL
    / g! ]3 J: K: q+ ?: ^5 o5 |; p

  278. & y7 K9 r0 X2 b% ]: z6 B- n. x- `4 M
  279. LDA PPU_Msak_Buf; G, C! m% P. V( X; z
  280. STA PPU_MASK$ ?+ E7 c0 V" K: v1 |3 i; |5 W
  281. ) W" ~" ~+ B7 s; V; V
  282. RTS& `( }: |- P( \0 V& N

  283. 4 C% W" {! R6 o3 E1 e/ E
  284. ;==============================
    $ O; G% u* S( \  G/ W* Q2 C
  285. Time_For_Vblank;延时等待1 [1 f$ a, {. }: X2 e6 a# g. v: i
  286. LDA PPU_STATUS' \) v, D  H) l& V/ s
  287. BPL Time_For_Vblank
    0 e6 W* z1 S. i. x0 S
  288. RTS
    9 ^4 d* B3 w3 w+ z% a
  289. , ]- O5 D* Z5 \
  290. ;==============================
    . f- B! F3 a8 g. {7 `/ t
  291. ;初始化MAPPER19: }5 t2 G, H2 w* y# U
  292. Init_Mapper19
    $ O# Q; Z0 E. S
  293. LDA #$00# U2 d1 `: j8 @1 _
  294. STA M19_CHR_00002 e+ C1 r2 ]0 V5 t1 i
  295. LDA #$01
    6 N3 B) @$ M) u+ B& l8 R
  296. STA M19_CHR_0400
    3 m# _% w1 ^( o# s  b
  297. LDA #$020 X' U$ \8 D- `& |% ?0 @
  298. STA M19_CHR_0800
    5 z+ C" C% p- J& S: C
  299. LDA #$03( ?& M* H2 Q  U" P. x( r
  300. STA M19_CHR_0C00
    # [; b3 [+ D) p0 M% n. s6 k& [
  301. LDA #$04
    $ ]+ N. p; e. X- t; ?0 u. k3 S
  302. STA M19_CHR_1000
    * O: R% ~# Q" G7 a
  303. LDA #$05
      b/ E( g0 I4 g  K
  304. STA M19_CHR_1400
    7 U. K) z" x$ ?7 f9 h1 j
  305. LDA #$06
    ! N: U9 z# T" \
  306. STA M19_CHR_1800
    2 m) F+ X) I* L
  307. LDA #$07  h+ ~' S) a/ }! j" G; D
  308. STA M19_CHR_1C00
    . G0 _( y) S! S) z
  309. ) m0 Q- F: p8 [( x
  310. ;禁用IRQ* C5 s9 u0 d" Z
  311. LDA M19_IRQ_COUNT_H! i* D* Z: `; ?
  312. AND #$7F1 r. d' r7 v: r3 V' ]3 P. g7 ^
  313. STA M19_IRQ_COUNT_H7 r. U. E' s! B& t) `, V

  314. 8 Z( E5 U# A: e0 }1 K
  315. ;命名表% P. I) m: B7 n6 w  L9 m
  316. LDA #$E0/ v( e. t# h# u9 q: H% y- F0 z
  317. STA M19_NT_2000
    " f& N8 [# K# b" X4 l2 x0 F
  318. STA M19_NT_2400; }) g& }$ K! w" e4 ?9 L) @

  319. 5 c( a! E0 L* a- I+ A- N/ g( `
  320. ;命名表/ A# w& c% a% g4 N
  321. LDA #$E1
    , S6 Y1 g  H/ ~) x6 Q
  322. STA M19_NT_2800
    ; n9 \0 L. v9 A4 Q6 @
  323. STA M19_NT_2C007 g- A$ ~4 g. u$ b, i6 N

  324. ! t: O2 {$ @' p+ U& N5 |
  325. RTS
    . f! M! k, v' V
  326. . |* r, W8 \5 w7 y  y7 U1 C/ t3 x
  327. ;==================================================9 H+ @2 ~" X# s; e! h. o
  328. ;重置中断处理
    9 L2 s) u5 }) c2 R
  329. ResetProgram
    - w: X! l8 l" }
  330. SEI
    8 x; [9 @) T% U/ F1 K* T* n
  331. CLD
    " L3 g; K5 l* D
  332. LDA #$00
    ' \0 `$ T% s/ Y' }
  333. STA PPU_CTRL
    ( b+ R0 O- _1 k' d5 ^2 l2 n
  334. STA PPU_MASK; x- K2 ~3 K/ ~" g+ W. T
  335. STA PPU_STATUS% G9 u% A& B2 \/ ^3 D
  336. STA JOY2_FRAME5 ^6 d: y& j8 V  u5 @
  337. STA APU_STATUS& Z3 @; ]: ?; N. E3 Q+ a

  338. 2 Q" C. U% l0 W8 m1 o- x
  339. LDA #$C0
    % u! @! W5 S3 }% `5 s  F/ t
  340. STA JOY2_FRAME
    # I$ O  r1 f, M

  341. 2 I& E: H0 e3 P/ Z' R
  342. ;等待vblank. E" s- n& r3 w; ~9 A$ L1 P! _1 J* ]
  343. LDX #$02
    ) W$ q8 w( M+ |: W7 Y( i( n
  344. Vblank_Wait_1, h6 E/ f3 K; b. n9 F/ G
  345. BIT PPU_STATUS5 F- Y+ P7 \4 ]! V! D
  346. BPL Vblank_Wait_1
    2 a: q0 @' S* j- @
  347. Vblank_Wait_2
    . F4 Y5 w+ V( u) L; I) o8 u" u
  348. BIT PPU_STATUS
    5 F/ e* L" H; k0 t. i  t; c
  349. BMI Vblank_Wait_2
    1 L9 m' n" t* N0 `. j$ ^
  350. DEX7 n$ h% R: d# g5 g5 Y8 i# x, j9 [
  351. BNE Vblank_Wait_1
    3 ]6 X0 {: `, o, b" f/ D
  352. 6 v; A3 p. D3 o4 A% l
  353. LDX #$FF
    2 ^! |$ D7 l1 E  e* ^$ O1 o  `
  354. TXS
    ( a! l# ?  q# L! S  u- L
  355. 9 N& |/ O' B9 }3 X
  356. ;初始化MAPPER19
    1 x# g6 L* D9 O) E
  357. JSR Init_Mapper19
    0 k3 S7 Y$ X1 [
  358. % V2 E# o2 i) g
  359. ;==============================
      Z# ]9 z7 j8 P  D1 S
  360. ;RAM初始化, q4 A( Y9 a' [. R3 l% s
  361. Nes_Ram_Init( \* |/ K$ k; @% z8 Q" y
  362. LDY #$00
    4 j  X; M( y2 j5 O3 y7 o. T
  363. LDX #$08
    , y  K& Y9 l% I
  364. LDA #$00' F+ w8 C+ n) f$ B& h
  365. STA <$006 ?9 y8 ~. X. q: j5 m
  366. STA <$01
    ' O. r# }4 t! w% L
  367. Nes_Ram_Init_Write+ `. x- e$ S" F, c; q) k4 Y$ O$ C
  368. STA [$00],Y
    ( D3 |$ C* h8 o! z# ^* t
  369. INY) s7 E& f' O7 {8 Y, ]0 Y
  370. BNE Nes_Ram_Init_Write
    0 h6 F) ]0 u2 I% h0 S
  371. INC <$01# s  i5 H& t  b1 C
  372. DEX9 h$ y$ S; ?  R+ ^# d9 n" Y
  373. BNE Nes_Ram_Init_Write) t9 e8 E% @7 j9 H; }* D6 C) l
  374. 7 A& O7 A% N* ~, _( S
  375. ;初始化命名表: J2 N" o7 X* ~# `3 B" w/ ^
  376. JSR Init_Name_Table
    + z& `" [, H( g. V

  377. 9 v; @9 q$ m& n/ U! `/ I; d; X
  378. ;初始化调色板* L  Q# M. Y3 ~$ x7 B
  379. JSR Init_Palette
    " N% I; r1 T5 P9 t
  380. ' r0 S2 X9 |' e8 i+ d6 u
  381. ;初始化命名表属性+ h' j; `* V1 ?8 F
  382. JSR Init_NameTable_Attributes) a4 U, J3 D* H% F
  383. 0 y9 p* [  }6 q9 y: y
  384. ;初始化精灵内存
    , V6 {* O9 M4 ?  l6 M. k0 g% O
  385. JSR Init_OAM_Ram7 _2 C3 M+ U3 @* W  |9 K
  386. 6 r- D4 s) F5 Z, {" l# e6 ?
  387. ;在屏幕上写点东西! E7 d  X( e1 V  @0 i1 i0 f
  388. JSR Init_Name_Table_Text/ g3 ?1 k! ?5 j- r3 I, k3 j
  389. 0 L. }* m8 Z! W/ v" v0 R
  390. JSR Time_For_Vblank: [8 W3 g& `( b: T
  391. ;开启PPU控制4 [8 s, [" ^" \9 h! @) Z% R4 b
  392. LDA #$A8
    , X" f  M. v7 s3 `
  393. STA PPU_Ctrl_Buf
    " [. U. y& q. k( w
  394. STA PPU_CTRL8 d' n  I8 [& w$ T% r2 n! ?

  395. 2 D. `! U# Z5 G4 j
  396. ;开启PPU显示
    ) ]+ [7 {# s' k( r. l
  397. LDA #$1E
    ! \" m1 X; a2 i6 j/ |* h
  398. STA PPU_Msak_Buf! o1 j2 M, [7 P! Y$ g0 U

  399. % N6 V( Q3 K1 {
  400. CLI
    6 r7 @% f, s/ Z8 b# e$ w$ u
  401. JMP Loop& l1 U1 s% c8 U( H0 B
  402. 7 Z! l: F" k1 ]) L1 I4 E
  403. ;==============================+ w0 v" b* s( O* d+ t' \$ w1 P
  404. ;死循环, 等待NMI中断
    & ]2 \% ^0 x  C# J0 ?9 K$ u
  405. Loop
    - @( ?- R7 B+ S9 o5 q
  406. JMP Loop4 z  ^& s! ]+ F8 j* I! `" u  r
  407. * x4 h0 d7 {5 j
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    ) ^- H: @6 l8 g/ ]$ C
  409. ; v) |9 N1 G9 v( t
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)% ?; ?: t6 @, w$ C, D
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103), W: s. j& Z: T6 \* p
  412. ;==================================================$ S9 i# l3 z5 m/ ?6 I
  413. ;NMI中断处理- E$ z$ \& [2 X$ U
  414. NmiProgram" J- v5 g( _8 H
  415. PHA
    1 K, G" q, L% O. e' c
  416. TXA
      ]$ P( Q1 Q. r) H! l) d& d
  417. PHA
    3 f* W$ m' W7 V8 y
  418. TYA
    ( v' J# w% v$ ~9 b0 v
  419. PHA
    ) |! s* {6 o3 `

  420. 1 Z0 n9 l$ m3 X- W% ^
  421. BIT PPU_STATUS) |0 Z# q- Q; C3 _

  422. 7 z7 w$ G  R9 x/ _
  423. LDA #$00
      u. J0 O# H8 f2 f1 ^
  424. STA IRQ_Index2 }4 K! U% d/ q$ V$ u/ [

  425. . a9 ~# r* g- n
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    / h& ]' z. ^' o4 ^
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    & Z4 Y+ }8 k" [# b- j' _
  428. STA M19_IRQ_COUNT_L; b! f8 U* _4 l2 x! W" I
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)4 e% B  t/ f: V
  430. ORA #$80- k* E& e$ \# B$ S/ o& p' ]
  431. STA M19_IRQ_COUNT_H
    2 h. S- a! V* Z4 G+ v
  432. CLI
    4 D+ z! t8 i. i$ k+ d! o
  433. 1 ^8 _5 P: s# x1 E) n9 A! }
  434. ;关闭PPU控制  E  C! ?4 [2 ?2 o
  435. LDA #$00
    , F6 p1 K3 G) l& o* ]8 Y
  436. STA PPU_CTRL
    6 b6 `4 P4 ]% f2 u
  437. ) D9 ^9 h) j0 f
  438. ;处理PPU
    " J, P* h4 }" q% h' `
  439. JSR PPU_Process) y3 w3 z: o" N) Z

  440. : P& Q5 N, L: Y
  441. ;开启PPU控制
    * a7 _' e) @: V! U0 ?$ h5 X
  442. LDA PPU_Ctrl_Buf
    # \- `, e1 V* o- ]# ?' B, l7 u
  443. STA PPU_CTRL
    ( f6 w+ y7 Q. R- C7 q

  444. ; c: y+ }% r6 j; o
  445. ;手柄处理5 l0 P7 y% M5 c3 A
  446. JSR GamepadProcess
    $ }# P' R$ f4 v" s" c
  447. / x7 k0 Y. w  I! R1 B- e
  448. LDA #$00
    , m! b/ _3 Z3 U" A9 p
  449. STA IRQ_Index3 a2 p2 s" S7 U3 N, G+ ~
  450. . i+ A! b+ c; [" `) L; V
  451. PLA0 G& D3 B& l# U& b) q9 z
  452. TAY
    3 G, S; Y; g  t( B/ a
  453. PLA" E& z* ~/ Y9 i0 e; M; v
  454. TAX" f3 E, ]  ?6 c, d3 P
  455. PLA9 \4 a* p5 m( `  p( g9 J
  456. RTI
    ( ~+ f0 ?! _" O2 f2 s# S: b0 I/ k
  457. - E# l8 G4 I1 H: p& Y
  458. ;每行扫描线113.67/ w2 M0 [' \! Q* [  F7 f% Y
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    ) A- N) g5 l  z2 c
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7, R! t; J+ X1 F6 {3 t
  461. ;==================================================
    5 x8 p% y9 U* e+ B0 X4 |2 c: a
  462. ;IRQ中断处理- v9 O6 Z5 d% r6 H7 F
  463. IrqProgram, F$ V& y: M* k: ~$ ~4 e0 ]9 q2 U  h
  464. PHA6 l# |2 W6 E  g& P/ W
  465. TXA
    3 p1 c7 |" i$ p, c- S) s6 E
  466. PHA) \: G& k- ^% R4 ]" }
  467. TYA4 a% F" b3 |4 s: U& v
  468. PHA) w( T& V  Y& v: r+ P9 |

  469. 1 e  S2 {5 H# f5 h
  470. ;16条扫描线后触发IRQ
    # g% j) o( k& q; N9 C  }- j
  471. LDA #LOW(BEGIN_LINE_CYCLES)$ c& {2 J' L) c1 Q, Q8 n
  472. STA M19_IRQ_COUNT_L
    / `- @" c8 O. s; `% R# s
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    % n5 [; T. `% Z$ w+ w1 \1 N" y( q
  474. ORA #$80! G4 J8 w3 l4 T" ^
  475. STA M19_IRQ_COUNT_H
    , i, I0 F6 K) D

  476. $ [8 W) y) I: X2 h' Y
  477. LDA <IRQ_Index0 q+ Z' g# U( ]. j' ~8 o
  478. BNE * + 4
    * r" U& a1 @* I
  479. INC <PPU_Scroll_H, h( y6 a' x4 T2 _0 |! \5 T- j

  480. 3 z! ^& w$ I" e% d3 P7 w( z- o8 A
  481. ;设置屏幕滚动% {/ X/ ]$ n8 T! d5 w
  482. LDA <IRQ_Index
    4 `( i' Q" a2 q6 A% M
  483. AND #$01& D: ]3 J9 c8 s0 p4 a
  484. BEQ Irq_Scroll_Right
    2 O6 ?4 D3 C7 B. X4 b# J0 ]( D

  485. 0 H& p( v+ S( A
  486. Irq_Scroll_Left5 P$ z/ F8 z, {. F
  487. BIT PPU_STATUS; G5 c9 u. c, z
  488. LDA <PPU_Scroll_H+ }$ F" o) t5 E- y9 A( Z8 U
  489. STA PPU_SCROLL
    3 e( z2 y5 G( v/ K+ J
  490. STA PPU_SCROLL( W0 \0 x/ R) o8 ?
  491. JMP Irq_Scroll_Over
    : l" S8 R' @" K, N; W; [
  492. % Y' {6 y3 Z* ^; ?
  493. Irq_Scroll_Right
    2 i4 d7 `! x0 ]! ]$ x/ j
  494. SEC$ l: v' ~3 a7 X3 j. r
  495. SBC <PPU_Scroll_H
    $ \: L4 _5 `5 V8 O# [' {$ q* u
  496. STA PPU_SCROLL* n: S9 y/ }- h# J  o
  497. STA PPU_SCROLL
    ) @0 W, T) Q# x/ B; J: M, S- ^
  498. Irq_Scroll_Over" D5 B" O/ I  n' Q1 f+ `1 ?7 S
  499. , [- p  ~5 L# Y* y# ]/ [4 X
  500. INC <IRQ_Index( n; j# l  r3 h+ G- y

  501. ( a( O! R" p. x3 D. v/ b
  502. LDA <IRQ_Index; S4 S$ h: m# D1 K* E
  503. CMP #14
    6 c1 H7 K. a1 u/ ^9 \1 z$ |
  504. BCC * + 10. _3 w: c0 ^: r) e- e/ c- f
  505. LDA #$00
    & p* c. ^$ n- ?
  506. STA M19_IRQ_COUNT_L  j2 f# X, A5 W% O, _
  507. STA M19_IRQ_COUNT_H$ k1 x) s8 V3 X9 ?2 j- W( ^$ E& t

  508.   j6 p2 V, s" M/ X0 P
  509. IrqProgramEnd
    ( [' \* U, H) Q  Y5 Q6 Q% S
  510. PLA+ [: {1 J* A: w8 T8 V/ p
  511. TAY
    $ [4 T( w, B8 A) c# Q5 }/ q
  512. PLA* ~+ A) t8 f0 S: P3 S- @
  513. TAX5 p  D7 j4 m+ r: z9 r# x* t
  514. PLA
    6 F+ H1 E$ v& r: B3 V  h! Q4 L
  515. RTI
    : z, O6 \2 L$ Z5 I: o* D
  516. ; P0 o& u; f. {7 [0 A$ _, \* N0 r
  517. ;==================================================
    - |5 Q$ B- o: v4 y5 |
  518. ;中断表7 _$ w3 @5 H- D9 P* b# M* d. q
  519. .ORG $FFFA' u% \' l; E, O
  520. .WORD NmiProgram1 g7 A( _$ f7 b, H' Q
  521. .WORD ResetProgram
    3 r7 h5 A# h6 ^) ~8 l- k% x  ^
  522. .WORD IrqProgram
复制代码

5 [, C! h/ Q" _; n# }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|国治模拟精品屋 ( 沪ICP备15012945号-1 )

GMT+8, 2026-3-17 04:06

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表