设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    3 ^' o9 G# h$ d; l; b, @( R
  2. ;FlameCyclone 20230710. ?' L$ B' r2 h% R

  3. ! L1 T; [9 k/ Q0 ?
  4. ;文件头
    ; `! F6 @) Y7 z: O
  5. ;======================================================================% o' e5 ], j; P; \: l0 F1 Q
  6. .INESPRG 4                                              ;16KB PRG 数量
    # ]" ]* @& U8 ?9 f
  7. .INESCHR 1                                               ;8KB CHR 数量
    0 h; R: W: u( B; \" e6 x
  8. .INESMAP 19                                                 ;mapper 19
    3 r, G; j4 k3 K0 h) u! ?& d
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    5 l# j0 H; n# K# t5 ^8 T9 C4 m4 D
  10. 6 F4 F6 A9 T5 t" u6 y7 u) ~) m
  11. ;必要条件
    * N9 g8 [- y) r' f7 z0 N- {. F9 M- L/ O
  12. ;1.持有CHR ROM
    4 j1 |) d5 p$ |( o
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ) p% E+ j  M6 V4 [; P
  14. ;3.精灵内存(OAM)不为空8 N8 H  [  Y; B0 j$ u( ]3 L/ o. u
  15. / {3 f" H4 B( a% w  y( a6 J
  16. ;==================================================
    * H* V: f% C% O0 L& Q2 j. l
  17. ;NES端口常量* D$ C2 g( i+ n  A$ [$ F
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器/ z5 r/ b7 K0 k8 U; J6 Z; r+ A. w
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    7 a- l) R" _) L% H6 r( s
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位- I, p& v7 q& m% j  y
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
      T7 y  L0 V& h0 M* X2 h$ e
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1& a2 f' A8 P5 E! D, S5 r
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    * A" V& u8 E+ i1 E
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加6 b: Z9 U2 a2 K! z, n# p/ j
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 - ^) q: U) _" G, [
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    3 ?9 [+ C" g; e4 E# \
  27. APU_STATUS              =   $4015   ;声音通道切换
    ' x2 F. T2 V% N, F0 A3 ?  Q
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通7 D. R) w, m2 e  d: C
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    * R# e4 t$ m# E3 a7 k; m- h
  30. * U, U: \6 P, ~+ s- g- T$ }
  31. ;==================================================
      z( u! l8 r2 x! k, B5 x
  32. ;MAPPER 19端口常量
    # L3 X1 b  _7 b# U* O- L. Q; f  M
  33. M19_CHR_0000    =   $8000
    " i8 u. F: o/ o# z& A6 a! ^) d
  34. M19_CHR_0400    =   $8800
    2 C+ I* L3 q$ S0 w) N+ r5 A
  35. M19_CHR_0800    =   $9000
    6 E. y! D2 b+ g6 k& e9 H6 I' a6 i
  36. M19_CHR_0C00    =   $9800' C3 G' r2 M8 s
  37. M19_CHR_1000    =   $A000
    6 B9 O1 E8 m' a  J2 j' p; k# S9 o
  38. M19_CHR_1400    =   $A800
    3 w1 \" \: H9 ?7 T: e
  39. M19_CHR_1800    =   $B000# h/ z8 [' Z/ p( O0 Z4 V& {1 C
  40. M19_CHR_1C00    =   $B800
    0 ^' B1 C( ^* `
  41. M19_NT_2000     =   $C000
    + e3 x0 K" z; e; I: p2 o
  42. M19_NT_2400     =   $C8004 S5 ]) \* V2 E" u8 B
  43. M19_NT_2800     =   $D000
    9 S$ F+ @: t& K6 ^
  44. M19_NT_2C00     =   $D800
    , J) O3 {7 E$ n& E. [: l0 b
  45. M19_PRG_8000    =   $E0009 z; y5 c4 X: J9 Y# `4 t, s- L2 P
  46. M19_PRG_A000    =   $E800( J( V  r  j+ X3 ?! F) V. E
  47. M19_PRG_C000    =   $F0002 K6 a1 r1 Q; ^
  48. M19_IRQ_COUNT_L =   $5000- b( x& B) c3 d& B: i" a
  49. M19_IRQ_COUNT_H =   $58008 S# N) v2 b' R

  50. $ S; N6 n+ m+ U# v
  51. ;==================================================2 T3 g0 l% o% B& `9 H
  52. ;程序块配置
    2 }! U2 |/ |) o& V, \4 N
  53. BANK_DATA_MASK          = $071 ~) b8 G8 J' s/ n4 G) g
  54. ;--------------------------------------------------
    + {- m. r$ v/ p4 u
  55. RESET_BANK              = $07
    + y8 C& Z; C; C; j# f
  56. RESET_ADDR              = $FC00/ N  V4 \4 r7 F, v5 f0 n
  57. ! C. }/ q5 c9 d  z: T# u
  58. ;==================================================. Q% u% O) w, t! x1 Y
  59. ;图像块配置) Y6 g6 q+ T5 ]3 Z! N8 S. o& B
  60. CHR_DATA_BANK           = $086 @! {+ C3 c. [0 u
  61. ) l! [% Z: u# J+ D
  62. ;==================================================7 K1 v9 a$ \6 T; i# v+ L: R6 O
  63. ;零页内存地址配置
    . w9 C$ l2 Z7 Q2 {9 @) T. v+ w% f5 O
  64. Use_Ram_Addr            = $80
    & |. A* y! ]( h, w) z
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    3 G, `$ O, d5 E0 a7 Y: C
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01% d( E( F+ Q: g2 c* r- d
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    5 ]5 M9 @; V+ k5 z% Y
  68. PPU_Scroll_V            = PPU_Scroll_H + $013 Q" A2 Z8 I( B/ o1 j! U8 ~
  69. FC_Data_L               = PPU_Scroll_V + $01
    8 E$ e! Q" E- Q$ K: O
  70. FC_Data_H               = FC_Data_L + $01- r6 |8 ~" \5 q+ |) w( h7 K: ?
  71. FC_Data_Buf             = FC_Data_H + $01
    ! K) P; j. n2 L4 I
  72. ;==================================================9 U" Y6 ]- o; q( c3 q

  73. 6 }) O: V$ V" Z
  74. GAMEPAD_MERGE_FLAG = $04
    5 w! {5 Q; t$ _+ D
  75. ; F6 ?( X3 d" m0 I% p& [
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    / e: m9 h* k5 ?' B+ \! @) j
  77. Gamepad_Once            =       Gamepad_Keep + 2) f4 c- z+ l: e! j
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ' B4 _; Q; u, U* X' D
  79.                                 " l+ X) k2 l* O$ \* f
  80. Gamepad_0_State         =       Gamepad_Temp + 27 G+ v. |; s; ^  A2 U: k, u* v
  81. Gamepad_1_State         =       Gamepad_0_State + 18 r4 t8 z9 G9 t: \& l8 F8 P
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    2 K' z" f$ |* U( f" B3 p/ n
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    0 @* z" F0 t6 r. J
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    6 z8 E5 N3 L1 T8 r- m7 n
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ' Q6 T8 s: D; v. A$ e" v
  86. 0 {  p$ C$ [. s9 o0 n
  87. ;==================================================
    9 C0 [- T3 J( B& H4 i! x3 x
  88. IRQ_Index               =       Gamepad_Merge + $01
    ( s# \( U3 {1 s  i; r* ]
  89. ;==================================================
      W( e2 ^$ w0 @& p) V' B5 \
  90. , n6 G* ?) ^; t* x* B  F
  91. ;CHR图形数据
    ( Z: ?* h: @& S* G* @# {
  92. ;==================================================; B* f" i; d+ T: l5 T+ v& y3 X
  93. .BANK CHR_DATA_BANK# A2 o- I" ^6 k& Y1 B8 S# p
  94. .INCBIN "chr_bank/chr_data.chr"
    8 c+ F' \6 y* x! H; y
  95. 9 T4 _) U. N) U! J) ~! ?
  96. .BANK RESET_BANK & BANK_DATA_MASK
    + q/ @' F- s- g0 Z; F) L! U$ G
  97. .ORG RESET_ADDR
    : b% H6 b* M7 U( X
  98. 3 g: d& p( L+ y  P, [" y
  99. ;--------------------------------------------------
    : s5 z$ E0 u  X0 n8 U
  100. Attributes_Data
    / E. K1 \- y% \2 D* l) S
  101. ;命名表属性
    + [7 I; T  F5 y' d7 g
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    6 a6 q! L' J4 J, k. N
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    8 s7 f* v0 U: [
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    , q, b; Y/ W. N/ x( U# {$ K6 H
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$551 N. P1 a. I7 I4 W
  106. ;--------------------------------------------------
    $ s8 s; d$ ]/ }) k0 x' u
  107. ;调色板数据2 M0 Q; i  W3 b# Y& o
  108. Palette_Data
    7 T4 R1 p3 k  h' Z6 }  @; q% I
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F5 [# P. d7 f+ ~: e7 d1 p
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    3 i( E: u3 S0 D  \5 P# T: B: N- k
  111. 2 K" `+ n: L+ t
  112. ;==================================================5 a0 u! u/ D8 B0 V. `  y
  113. ;命名表初始化
    ' ^5 a9 ?) C  x1 b7 L
  114. Init_Name_Table1 e9 c: {9 \* U* F- J2 Y6 E
  115. LDA #$20
    & W' y  Y4 z0 q0 v
  116. STA PPU_ADDRESS
    ( s, h3 p" ^9 _; c2 O+ u- R; O0 o2 L
  117. LDA #$00" Z% k& I0 k) y5 I3 p
  118. STA PPU_ADDRESS
    ' e% `, P3 d& M( x$ Y7 l6 U( t
  119. LDA #$00$ ^; R) q- T8 H6 ^! E- X  `
  120. LDY #$00
    ) B' P/ U- l# {) }% ^4 |
  121. LDX #$101 Z- {- y) p9 y: p2 k
  122. Init_Name_Table_Write' N. l: T, A8 I  P$ P" i) _
  123. STA PPU_DATA
    1 g$ i' w4 S5 h3 ]
  124. INY& j# Y) y: `  n1 g
  125. BNE Init_Name_Table_Write
    ( a0 N0 m& U0 u: H' A
  126. DEX
    ' N# [$ t; {  V" u
  127. BNE Init_Name_Table_Write; I9 b  {% V$ ]4 x" }" R, ~7 @. B
  128. RTS
    7 W- r  K  }2 X4 t3 A

  129. . g& l2 w: F0 G2 j5 H  ^9 l
  130. ;==================================================
    9 o) S3 j: a8 Y! X
  131. ;调色板初始化3 p4 f: B+ P; Q/ ?3 e* e1 ?9 D
  132. Init_Palette
    - O& B! K& t) Y' c7 y
  133. BIT PPU_STATUS
    " ^7 N8 j# |. C9 F
  134. LDA #$3F2 O5 l9 A: k0 v# ]1 L# V
  135. STA PPU_ADDRESS5 B* F+ _) l5 k+ r% }% ?! E# q" t3 u
  136. LDA #$00
      l, b1 Q; g; }) J' P. ?( L
  137. STA PPU_ADDRESS
    4 W5 _, d: E1 M  l4 ~
  138. LDX #$00
    ) d! q. c) `; v, p) E1 ~
  139. Init_Palette_Write. d/ A& B2 A7 r3 D
  140. LDA Palette_Data,X' D( {) T( Q+ Q! D& P" V7 K
  141. STA PPU_DATA4 ^8 Q9 h9 {. W2 O5 Q8 H
  142. INX
      w/ C9 ?0 \! }0 Z" O3 X4 `
  143. CPX #$20
    - F7 D9 r* M( a, F+ g
  144. BCC Init_Palette_Write
    # O, R3 n/ L! T9 J, {' ^
  145. RTS
    9 m8 N- q; R: l3 }2 w) u

  146. 3 l3 S( z7 [/ L; c3 n
  147. ;==================================================4 b1 D" Q( N' r3 ^9 s
  148. ;设置命名表属性8 P2 Z( z! l' g/ L, d4 w
  149. Init_NameTable_Attributes
      x8 `  y) C, Z) f  S
  150. BIT PPU_STATUS
    : y" u; i# L& m) K9 r0 B
  151. LDA #$23: E7 n1 q: s  Z0 m
  152. STA PPU_ADDRESS! G# M0 j# r- X" C; P3 w
  153. LDA #$C0$ P+ [' z  z5 i
  154. STA PPU_ADDRESS  G$ a3 u" @+ c
  155. LDX #$006 O" ]1 ^1 a/ z/ F8 P
  156. Init_NameTable_Attributes_Write9 d( e1 u% ?$ l0 f. R* U8 t+ G
  157. LDA Attributes_Data,X0 ~) S3 f  A9 X+ G8 m$ N. L+ c
  158. STA PPU_DATA
    ' [6 T5 ]7 h  R  G& P0 ^
  159. INX# T3 r1 E7 k3 ^7 @
  160. CPX #$40
    9 g6 K0 y4 z1 R2 b
  161. BCC Init_NameTable_Attributes_Write
    ) G) ^) q" X& {3 R  U. t
  162. RTS1 B4 r7 o+ s1 b
  163. & ^: C  u2 q. |
  164. ;==================================================( k. `8 n1 r8 S2 r, a) o
  165. ;初始化命名表文本1 H; }9 D5 D3 \! v
  166. Init_Name_Table_Text
    ( G5 s' B$ D% ?) A# R4 c3 ~1 {
  167. BIT PPU_STATUS
    8 b0 H9 ?" x8 z  @
  168. LDA #$208 v( e) b* @# ?; ~
  169. STA PPU_ADDRESS
    & I4 L; |8 Y+ B' l: k# t5 H
  170. LDA #$002 Y  M: a% ]. I7 p6 S! o
  171. STA PPU_ADDRESS; R  [0 A0 @4 U6 M" |
  172. LDA #$00
    ) B0 S  Q# |% E/ u
  173. STA FC_Data_Buf
    - B" O- d3 x; C, N' m3 N) D  c& w
  174. LDY #303 H5 @. ^  t" ?! N0 {
  175. Init_Name_Table_Text_Write/ L6 u6 |0 a1 }* Q
  176. LDX #32
    * `1 p+ R5 w% a. ~7 f! _
  177. Init_Name_Table_Text_Write_Char: M7 q0 B7 V: J+ N7 o
  178. LDA #'0'1 G) |1 k% m4 n/ s& |  V$ b
  179. CLC
    2 y! Y! W$ P* n" }) @, L
  180. ADC FC_Data_Buf
    : @2 v2 w. D( m' ^9 m5 u+ s
  181. STA PPU_DATA$ r5 `% l- r' Z
  182. DEX, T5 G0 s* Z% Q& `
  183. LDA #$14
    8 q5 v% ?% \) P' G, [
  184. STA PPU_DATA8 q: r) R$ Y0 q, s
  185. DEX: D8 Q, f4 ~( G
  186. BNE Init_Name_Table_Text_Write_Char& T; _& X6 j+ e4 f& W: L
  187. INC FC_Data_Buf  L9 B! u/ T4 U: ~3 _* G. b
  188. DEY
    ! q2 J; f- f, k6 X
  189. BNE Init_Name_Table_Text_Write8 }; B4 I+ q/ `
  190. RTS
    + m2 P; W3 P; ~, R, h

  191. ! Y& ]1 f# d" [; u. ?
  192. ;==============================5 }. j! f9 B4 s% A! L
  193. Init_OAM_Ram;初始化精灵内存
    - Q( R# M1 `/ f( c
  194. LDX #$00
    + P" L& k, a: R1 V0 D/ g
  195. LDA #$00
    ( L! P; S% v. [, r1 W7 N
  196. STA PPU_OAM_ADDR
    ! p& ?" C1 t( N) J9 _; J; U
  197. LDA #$F8
    ; b; l; x+ R; @( K+ h* A+ c, p- K1 t7 h
  198. Init_OAM_Ram_Write0 J/ u$ }: @" w& k  u  O; \
  199. STA PPU_OAM_DATA( r  Z, @. a' y0 j0 U
  200. INX& X0 q3 [3 a3 I& F) p! ?) u; l7 Q- Z
  201. BNE Init_OAM_Ram_Write9 i1 Z) e1 t5 w, i0 V
  202. RTS4 z8 ~" [$ t3 F( U5 y! [1 X

  203.   ~6 o/ M$ ?! M4 j1 N
  204. GamepadProcess;手柄处理+ B* k& {  P6 `9 d3 O3 L
  205. JSR GamepadDatacan
    ! P4 H& ^  u& X& |# ?
  206. LDA <Gamepad_0_Value
    8 i' `* `0 c( h; _4 l
  207. STA <Gamepad_0_State4 {* ]2 A7 |" J3 p- B) @) t
  208. LDA <Gamepad_1_Value; b1 U( Y/ e* B8 C2 V  n
  209. STA <Gamepad_1_State- \2 i, z. |- {( g
  210. JSR GamepadDatacan
    / ?) G- z$ Q% n% j+ f* a# A! Q
  211. LDX #$013 y# i% {1 j/ X2 U& ?
  212. GamepadMergeCheck;合并手柄输入检查
    3 X6 z. z1 y, X2 H. R" h- _) N
  213. LDA <Gamepad_0_Value,X
    ( a" S- O( ^& G. f4 r/ E# Q
  214. CMP <Gamepad_0_State,X
    $ {5 w0 s  h; t; @# f  X
  215. BEQ GamepadMergeInput
    % B3 p0 |, ~0 [% H4 f: ^
  216. LDA <Gamepad_Temp,X6 `7 ^% o5 q% b$ |8 l
  217. STA <Gamepad_0_Value,X6 W, N  v! C6 `  s, I1 x
  218. GamepadMergeInput;合并手柄输入* c% v2 X" B8 n
  219. DEX5 x5 j& @5 e. p3 `% y
  220. BPL GamepadMergeCheck
    5 a' L% n: _9 D1 b
  221. LDA <Gamepad_Merge
      N6 d6 r$ X$ }7 ?
  222. AND #GAMEPAD_MERGE_FLAG
    ! W+ C6 Y1 ], ~4 d: F* G- ]* l
  223. BNE GamepadStateProcess
    / @% I; v+ Y6 \" y- e/ @
  224. LDA <Gamepad_0_Value
    & ]/ ?8 ~& b3 L' P
  225. ORA <Gamepad_1_Value5 i4 g% x3 w2 d/ L; C1 S. O* I6 p2 ~$ x
  226. STA <Gamepad_0_Value
    ; D' b3 P. V# [! l# r* u
  227. GamepadStateProcess;手柄状态处理
    8 C* ]; d1 a' b" V# l- a
  228. LDX #$01
    8 n( J5 W' o+ I& L6 A$ D% @1 p! [
  229. GamepadStateSave;手柄状态保存
    # C8 [# }2 ]" F" Z7 v# U) Q
  230. LDA <Gamepad_0_Value,X
    2 s! [: p' N6 E+ a+ _
  231. TAY# C- W+ }4 ?& N9 y9 U
  232. EOR <Gamepad_Temp,X( L6 r+ G+ m& B8 G- j& w9 P
  233. AND <Gamepad_0_Value,X
    + K" y8 y/ C8 k' m2 i4 _
  234. STA <Gamepad_Once,X5 J2 }, K& b5 D; [% x2 W7 i
  235. STY <Gamepad_Keep,X8 J$ A$ S5 r# U  {: E
  236. STY <Gamepad_Temp,X; k# q: Z* f: Q+ I
  237. DEX7 B* ~: ]: ?% p: u2 [) C
  238. BPL GamepadStateSave3 i- O8 @/ o) Y( I3 R: X( P
  239. RTS
    . t% X8 H6 D+ ~4 I+ f6 Y
  240.   ?+ Q  c' ?* n+ D9 f) z
  241. GamepadDatacan;手柄数据扫描
    " f. E* Z4 B- U" L
  242. LDX #$01
    ' U4 z' T" p4 }' w5 d- Z! N4 U. M
  243. STX $4016  o, c8 k# i7 K1 s% r
  244. DEX5 E2 `; V8 a3 L; e1 T2 f
  245. STX $4016
    ! E5 N, R" m, s* l$ e4 [
  246. LDY #$08# y4 t$ m. f9 n% u& C
  247. GamepadPortScan;手柄端口扫描& ?$ }6 A, P3 T1 a- Z( u
  248. LDA $4016" ^- ^, ~. f+ N) h0 d
  249. STA <Gamepad_Port_Value4 z0 ]9 Y  Y2 _5 T
  250. LSR A+ k( g, t, y# q2 w/ e$ M! A
  251. ORA <Gamepad_Port_Value) W$ B. Z. d& H* Q" S8 s/ F
  252. LSR A
    8 O4 z. k! Q* }5 k/ Z+ j/ g
  253. ROL <Gamepad_0_Value2 \8 t% z% E' L% c7 v  p
  254. LDA $40170 R9 m7 U3 y* M1 Y
  255. STA <Gamepad_Port_Value7 b/ X% _! u& O2 `- x  I
  256. LSR A
    ) X! z# [/ E; ^
  257. ORA <Gamepad_Port_Value
    7 L5 N" \* q3 N4 N* m; u
  258. LSR A- b! x. t6 ]! V& F% r* T* n
  259. ROL <Gamepad_1_Value& t( J# V9 h: R3 o/ K  g! N) k2 b
  260. DEY6 q& ^: `+ a' `0 s
  261. BNE GamepadPortScan
    : ~' k( T: L; |! l$ s* c
  262. RTS
    2 Q( T  g( f  ~8 f1 f- `
  263. ! F* m: p! w. o" ^( ~0 f
  264. ;==================================================( p- P# p( c/ `- k: T0 ?/ B' e
  265. ;PPU处理
    & Q9 s9 L! W+ o& g. i$ G: f! C
  266. PPU_Process+ ~/ `% [( G+ X' L
  267. LDA #$00
      P$ [7 P/ F: [7 x. a" a
  268. STA PPU_MASK$ [5 F3 ^9 R/ n& l

  269. ; C' V/ o3 F+ Q1 E! m7 u# P
  270. BIT PPU_STATUS
    / g* M) N1 i$ J4 h
  271. LDA #$20
    , L: R* ?! y6 U$ H( ]
  272. STA PPU_ADDRESS
    - {0 ]9 f) b! f5 L1 m2 Z8 }1 b
  273. LDA #$001 p/ ^. |- ^6 h5 L' x
  274. STA PPU_ADDRESS
    7 c& x' w1 T, g
  275. % \. T. @& g) A
  276. STA PPU_SCROLL. b' B) C2 G5 e* z4 k: y* Y& Q) v! h" W
  277. STA PPU_SCROLL6 {3 C) f. ]; a+ H' A# K) ]- K, h

  278. 5 V: d9 x% M7 P' j! E& e
  279. LDA PPU_Msak_Buf2 h& U9 N) y2 Q/ l% z4 ]
  280. STA PPU_MASK
    . \( J& d! J! i( I

  281. $ }, t, y' G6 E3 ~5 Y
  282. RTS
    " K3 u9 k% U. O5 C
  283. ! ^+ ]- E! v, B% m0 F
  284. ;==============================
    : y9 Y" H3 L& l3 c
  285. Time_For_Vblank;延时等待
      W' i4 |4 |5 W
  286. LDA PPU_STATUS
    " t& F4 e/ i+ Q- j5 t
  287. BPL Time_For_Vblank
    9 ]0 i7 R5 ^) p! T6 m/ Y4 f6 x3 a
  288. RTS5 T; ]9 O% B, S$ m& T* N) j

  289. + o+ L- i4 H8 A9 K! X# G* F9 j7 j% y
  290. ;==============================
    ; }: k: ?: x4 C4 e' Y2 x" x) k* J
  291. ;初始化MAPPER19
    ; V  a, p% U% u5 G7 k6 d& a* g
  292. Init_Mapper19
    ! c' j) Z7 x" Z8 t) K' ~2 v- r
  293. LDA #$00- q$ J, ]$ }7 z2 g, _
  294. STA M19_CHR_0000$ f. B4 k1 @! S9 _7 Z3 b' |
  295. LDA #$01. L! a0 M6 }: v$ c6 _8 m% x
  296. STA M19_CHR_0400
    # H& `+ r  p5 j3 l, j  H+ n. D, A; u
  297. LDA #$02/ i1 n2 A3 l  q/ L" s
  298. STA M19_CHR_0800! g1 O9 A' F6 a( {
  299. LDA #$036 p  D0 B8 h, q8 O1 _) e7 C
  300. STA M19_CHR_0C00* l& g: n8 H0 t2 r  f
  301. LDA #$04
    7 N* Q9 W7 ]3 U& Y! X% \5 J+ Q: V
  302. STA M19_CHR_10006 o: _8 o, \3 i  N) D- @5 V
  303. LDA #$05
    . U' m' _3 H) W' S
  304. STA M19_CHR_14008 q0 l; z& O# a
  305. LDA #$06
    $ N/ Y3 o7 i: c) p) o" M" C. b
  306. STA M19_CHR_1800
    5 q. P% O# h8 u5 {2 y* c
  307. LDA #$07: j6 r! v$ F; Y' R" |. F
  308. STA M19_CHR_1C005 `8 J, _7 l3 D

  309. - T" \( A( m0 S$ U8 L8 s; X
  310. ;禁用IRQ
    0 S, A; j  x$ R& c7 v# ?& O
  311. LDA M19_IRQ_COUNT_H, L1 s* h3 D/ K( X' S' u. P
  312. AND #$7F
    , j  N. Z$ G! S! n* a% ^3 g# H
  313. STA M19_IRQ_COUNT_H
    $ w% ]  E9 G& X! ~6 D1 v6 }- m) h! q
  314. : j2 U. A( I5 x! C
  315. ;命名表
    ( ~' m9 q0 j4 M; d) U; d, A
  316. LDA #$E04 j* f$ e4 q' I' S: g
  317. STA M19_NT_2000
    3 P2 {& L; Z' S% F  S: J( S
  318. STA M19_NT_2400
    : g% f) p' i& a7 B+ e
  319. # y! S% M. k; W1 k5 n
  320. ;命名表3 K: h  B  D( ]3 u/ g! P0 }- K* N# z
  321. LDA #$E1) ^& r( B7 k) p6 p9 W+ H6 X
  322. STA M19_NT_2800
    4 b8 y; z, ]6 [8 m4 C
  323. STA M19_NT_2C00( t4 p, o8 i& u* M  n
  324. / P4 Q% Y) N. a0 a5 a) w
  325. RTS" X) Q# U2 _+ N3 p
  326. ; R/ e& v/ B6 H  P
  327. ;==================================================
    3 O9 ~  V  S/ |
  328. ;重置中断处理
    & ~9 L' `% k3 y6 {
  329. ResetProgram
    0 f. `- C# s; ?* p
  330. SEI
    - R6 v2 k) @6 }; g, O! W
  331. CLD3 ~2 a2 S* U' U( I% _1 d
  332. LDA #$002 O; @- H. w0 E# X2 W! Y' g$ _
  333. STA PPU_CTRL
    $ w) U% @0 L* x( T
  334. STA PPU_MASK( ?1 Y, L: r: [: ~2 F
  335. STA PPU_STATUS; e( y9 M3 ]* w$ y7 D8 r' O$ Q+ ~
  336. STA JOY2_FRAME
    ! I! H( d' G9 w' S
  337. STA APU_STATUS
    # V- q8 R, ~/ j4 k/ g
  338. 9 o7 q8 m! f  G  z% B! U2 E$ P
  339. LDA #$C0
    / N0 u! h1 z8 c! i1 K$ u, ~" J5 c
  340. STA JOY2_FRAME
    1 L5 Z# i, [6 v( m) c. R

  341. " a8 L2 O1 e5 p' H; W4 L
  342. ;等待vblank, ^* A0 Z7 ^; R6 U
  343. LDX #$02) ~; z/ t& W. [' H$ J/ [) x% W
  344. Vblank_Wait_14 x3 \; U4 p1 C. G
  345. BIT PPU_STATUS( L# y3 d/ @, _) Q2 @3 n, @
  346. BPL Vblank_Wait_1
    ; Q+ N- Z/ M) [! R# ~( ?2 B
  347. Vblank_Wait_2
    / @; l& m+ o; O+ Y* q
  348. BIT PPU_STATUS
    5 e: I! i% ?# U7 e
  349. BMI Vblank_Wait_26 h" t8 w9 L! h  H8 n
  350. DEX
    ! j# m- W) j! `" \+ v
  351. BNE Vblank_Wait_1
    : f6 z- U! G5 w# I8 a" v2 S

  352. & j1 e* s* `7 P4 a
  353. LDX #$FF& d" w  x; j9 [3 n- d) U
  354. TXS( ^1 ~7 F0 }. Q
  355. - K+ K  y/ j% W
  356. ;初始化MAPPER19
    + b5 A( }; G6 h+ }4 K( T
  357. JSR Init_Mapper19* w2 v* w9 L6 I' U( X* s' X
  358. : y; X& _. o3 W3 j  t
  359. ;==============================1 ?' T. {& ?# ]' d4 P
  360. ;RAM初始化
    3 w# ?9 Q# G  o7 v2 Y+ t. b
  361. Nes_Ram_Init
    1 d2 d8 @3 ?  g) G! h
  362. LDY #$00
    : d/ Y$ B  i* {+ ~( w/ d
  363. LDX #$08
    4 W) |  @% U( u1 h% W/ w
  364. LDA #$00: z& G0 z+ R" M1 m; N4 H
  365. STA <$00% ], f2 G9 _1 Q
  366. STA <$01+ w( x" \$ O8 l8 e4 a
  367. Nes_Ram_Init_Write6 o- s0 D; ?/ p
  368. STA [$00],Y
    3 C( r1 j; j2 C1 E# @; b: Y3 X
  369. INY
    , D  G8 H! X6 j: a
  370. BNE Nes_Ram_Init_Write
    % M7 }2 q$ J* z1 N  V4 m3 d
  371. INC <$01% I8 K1 }6 `% L, B6 B; j2 R  V
  372. DEX9 e( E$ A5 }" j5 s
  373. BNE Nes_Ram_Init_Write' v. C$ ^# D$ j$ ]* s0 j+ F
  374. 7 s" `- r0 T. }9 O
  375. ;初始化命名表
    4 T0 o! w3 \& a7 O9 V* w7 M! o
  376. JSR Init_Name_Table- f  J. ~5 U( j1 K9 B

  377. 4 I2 b% z( z5 Y& t: f: c
  378. ;初始化调色板
    ; w' f# v" G' y0 N- ]" o' x& o
  379. JSR Init_Palette
    % ^( h* c6 a6 q! _6 V# ?0 t

  380. 7 f- |8 b; ]3 U6 j
  381. ;初始化命名表属性8 b* r4 K- y( k3 C
  382. JSR Init_NameTable_Attributes
    * O9 x' w! r# [! G- S

  383. 6 c. p: w+ U4 A' C
  384. ;初始化精灵内存) Q7 ^  S3 k- P- D8 j
  385. JSR Init_OAM_Ram
    / G2 w6 J, t2 G# O

  386. / `# Q3 C  t, C+ o
  387. ;在屏幕上写点东西) M! b) l% n  X& i
  388. JSR Init_Name_Table_Text$ L; x$ b! w6 T. y; n0 Y
  389. " r4 |7 O9 U) R) ?
  390. JSR Time_For_Vblank
    / f2 x6 h4 e& {; j9 X
  391. ;开启PPU控制) O# Z/ J$ i. E# B* C4 t4 V
  392. LDA #$A8
    , |. Z9 w2 B+ H) {) }3 D* u- H
  393. STA PPU_Ctrl_Buf
    , k- Z4 h* @  W0 a( ~
  394. STA PPU_CTRL
    . a  S8 ^; |8 X& {
  395. % X- a* a' g% x
  396. ;开启PPU显示
    + d$ D1 `) z) M6 W  y
  397. LDA #$1E
    . m' T, r% S$ i( {
  398. STA PPU_Msak_Buf
    $ E. Q5 c, t& J7 ?/ h$ J
  399. ( ^; S! B3 X7 F0 n7 H
  400. CLI( `- j# ?" N+ U3 U: L! P
  401. JMP Loop
    , ~6 G3 i, j3 G

  402. + h. v2 n+ _0 ]: v
  403. ;==============================! g. a  z1 I, p7 R4 {
  404. ;死循环, 等待NMI中断5 r6 H' Q' R8 A3 W( i
  405. Loop
    2 o2 }, e6 y, r& c
  406. JMP Loop3 a5 B2 i+ W( M2 w
  407. - n8 I4 z, |' E
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    # f; h4 x+ D3 l! a2 }# m. S: w
  409. 6 J, ~4 @( |3 n0 A$ K, Z! ?4 H
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    9 M  ?8 V9 t( i
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)6 q) R9 l6 j& c: ]
  412. ;==================================================% g" d* y- G) `0 I( _
  413. ;NMI中断处理% \; T9 V% m3 x' r0 C7 Q5 }! t
  414. NmiProgram
    + ~! o- H- T: P4 t( p  N# [
  415. PHA6 w* S. Q- `: ^
  416. TXA
    ; P; ?# Z; r- k! D# g3 W
  417. PHA. [* U7 s2 G8 d- c
  418. TYA
    & y( w+ u; @- T  w3 {/ `
  419. PHA' k& ?+ j3 h4 N5 h( J; A: e

  420. ' \" u! Z( `8 P& v
  421. BIT PPU_STATUS
    6 O1 V# a% j& A: q; a6 K4 s
  422. 7 X% E  M3 o) o- M$ C
  423. LDA #$00
    3 q2 U3 |  ?- `
  424. STA IRQ_Index% o; j6 [" s- D
  425. 7 a3 s( e4 q3 Q' \& s4 y
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动" w' F  g5 s8 L5 ?: Z+ t
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    % f" C& w% Q& ^
  428. STA M19_IRQ_COUNT_L
    3 _/ Z& `- T" {, z" S/ C* y
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)) N. d/ s' G9 z4 y
  430. ORA #$80
    2 ^" ^& V3 L6 R2 ^- Y' X/ u1 q
  431. STA M19_IRQ_COUNT_H
    * O( D7 |2 d7 q1 `$ K% ]8 o9 W
  432. CLI; s  G% W$ ?8 H1 V* _
  433.   U. }! I; y: V9 ?6 }
  434. ;关闭PPU控制" Y0 W+ V4 }! i
  435. LDA #$00
    5 P6 n# p  W) Z$ @  P+ H
  436. STA PPU_CTRL
    4 |" G5 F9 x5 D/ t2 E

  437. ; d3 J, T% Y* t! b2 a
  438. ;处理PPU% X3 A! F! O. c2 H) b  z4 g
  439. JSR PPU_Process
    0 }5 k9 S8 x2 U
  440. & Z9 p) U/ @( k1 V6 Q
  441. ;开启PPU控制! C2 S; t5 d" c) m+ i" ?2 j
  442. LDA PPU_Ctrl_Buf6 q  ?: T0 i7 O( k% [! F+ O
  443. STA PPU_CTRL
      S9 K2 Q3 J& O3 ^. ^
  444. , n+ y. T' L  ]% F
  445. ;手柄处理
    ; Q6 [. X1 a5 E) {5 g) d
  446. JSR GamepadProcess
    * m+ ^& @7 v, \3 F6 o2 {' n9 v
  447. 6 i' P& A3 R' C9 D
  448. LDA #$00
    ! B  j; u. Q0 ?6 \
  449. STA IRQ_Index  h' ?* c2 A1 ?
  450. ) ~# \. \3 g( h8 q/ D1 v9 x
  451. PLA2 l6 Q5 m. v2 w8 M1 I: N/ ]
  452. TAY
    & {7 Z+ c# N* z  Z2 \* a
  453. PLA
    0 h: o. b' D4 R# ^
  454. TAX& Z( v% D3 `9 O# h  l  [
  455. PLA
    0 ~3 E# o( F& T
  456. RTI  J9 c, Q  M9 V' L

  457. & @) }: l* n  [/ ?" C  T
  458. ;每行扫描线113.67
    9 m% k4 J; y) }" }
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)9 ~7 p* O2 i3 `% o
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ( }% K) A. r2 O& [
  461. ;==================================================" X1 X: X/ Y" ]* O2 Z, L% w; B
  462. ;IRQ中断处理( s% e4 v- A# z- ~. o4 y
  463. IrqProgram" {2 Y8 Y. E" H2 C& X
  464. PHA
    & S. I2 O  w6 q7 r7 ?8 ?( V2 L0 Z
  465. TXA
    , Z- m- g3 {2 W5 O4 {  B
  466. PHA
    ; ~7 i! `& z3 g9 i) M1 s
  467. TYA! C" E1 w) M, H; a0 v9 l4 }' ~
  468. PHA
    6 k6 A6 u8 T- f, u1 v; `5 k' e

  469. 3 D; J5 h) K- _" M6 }, |# ~' n6 U
  470. ;16条扫描线后触发IRQ8 j  F/ ^2 C% h
  471. LDA #LOW(BEGIN_LINE_CYCLES)1 v+ I. S9 T( N; g# v* B
  472. STA M19_IRQ_COUNT_L
    9 W7 t" c' Z! w5 t3 k
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ( \2 c5 |5 s1 C4 M" K
  474. ORA #$80
    - \& k5 Y  x% T% ]8 B# R% ]) k
  475. STA M19_IRQ_COUNT_H) Y2 ]3 F8 e2 t1 o/ Z4 S
  476. - f+ S4 |( T$ ~* Z
  477. LDA <IRQ_Index, s' F) ]0 f8 L( h: j2 H) T" R  f& g
  478. BNE * + 4
    6 W  l# R: P- V0 E0 D$ P2 L
  479. INC <PPU_Scroll_H
    * _" I9 ]: c) v+ e
  480. / d  K! r# g: F$ m3 Y! u
  481. ;设置屏幕滚动
    ! X  S( M7 A3 A. o3 I- }6 Z
  482. LDA <IRQ_Index9 ?/ p5 C" U( z% u4 L2 N) }, ^$ Z
  483. AND #$01. k" F+ u' O! H) X' E% p
  484. BEQ Irq_Scroll_Right
    1 ~$ Z3 a! n" ~+ q, F

  485. ) R2 R  ?8 V5 L  q
  486. Irq_Scroll_Left8 U; B9 F4 W+ @. P/ m: B! H* x
  487. BIT PPU_STATUS% T5 b/ F" z: k* E* i
  488. LDA <PPU_Scroll_H, y9 W/ D4 V% W5 b. W- J9 H! W. Q
  489. STA PPU_SCROLL
    ) y7 S9 F, X+ K9 m
  490. STA PPU_SCROLL; l$ h7 s' z$ e: R
  491. JMP Irq_Scroll_Over9 i& |+ Y/ S1 K. R5 k& @
  492. : N4 Z& H$ j- g# F) ^. }
  493. Irq_Scroll_Right6 s) U+ \" v. U8 e) Z5 p4 ]
  494. SEC
    % k6 P# e' k9 j0 t
  495. SBC <PPU_Scroll_H
    8 [$ X0 W& G0 B0 w+ y8 B7 T4 M. w
  496. STA PPU_SCROLL
    % x5 z- v$ `/ r  n" d  l1 l8 x+ o$ C4 l& p
  497. STA PPU_SCROLL
    + v6 p$ y; O9 E4 G) X0 z: k
  498. Irq_Scroll_Over  h% B7 _# ^4 X6 [. D  [( k% J

  499. & Y+ |; Q: V  ?0 X4 z: |
  500. INC <IRQ_Index
    4 r3 [+ |: I2 H$ S; V

  501. 5 l1 J$ U  M5 L8 r' I
  502. LDA <IRQ_Index8 z0 {& e; B$ `9 G  B! v' G# U7 w
  503. CMP #14: L: z/ Z0 d* d5 G4 f1 Z# e/ G
  504. BCC * + 10
    ) [$ V! E# p. g" V- {
  505. LDA #$00
    " ^1 }* ^# Q& k& T5 j- }( C7 k
  506. STA M19_IRQ_COUNT_L" F( I  c& K  k9 C& d+ A1 x( U, U4 ?
  507. STA M19_IRQ_COUNT_H
    ( \3 a- F/ w5 s9 L% Z4 B
  508. & p# I) @! |* |
  509. IrqProgramEnd
    + x/ J$ W  t. a! _- h4 Z9 w3 c6 a( ]
  510. PLA/ J: o  K# [/ g3 t5 ?
  511. TAY
      W. k! a) U# o( V; T, h( K
  512. PLA9 c% S8 C) j% d
  513. TAX
    * J9 h5 Z& M3 R( x! b
  514. PLA5 V1 b+ p" u; E
  515. RTI
    4 C! k; q3 b3 }
  516. 2 c0 }% @% I8 [8 g) X1 t
  517. ;==================================================
    / _6 R6 m: z2 I) _1 T1 P  B
  518. ;中断表
    5 ~5 y( i: S% c& Z) ]
  519. .ORG $FFFA
    ; @4 Q  J, l; b& }; X# }+ U4 H
  520. .WORD NmiProgram
    + y! r! y% ?3 b5 Z  q. \
  521. .WORD ResetProgram
      `3 `6 p2 Z$ `. P
  522. .WORD IrqProgram
复制代码
( V7 w) ]; ^6 |. U  h  C+ n% z

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-6-26 02:33

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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