设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]/ P  X& k# z! c8 S  R6 k, d
  2. ;FlameCyclone 20230710" s* t/ `5 D8 a  y$ v- q* A3 O

  3. 4 l) G2 ]) v  g- @* M0 y2 q+ F
  4. ;文件头
    # ^) @$ l5 o* {& X
  5. ;======================================================================
    0 d; M; Y8 N: a5 w* T, y
  6. .INESPRG 4                                              ;16KB PRG 数量0 w7 g6 @+ _8 f& m
  7. .INESCHR 1                                               ;8KB CHR 数量+ k7 u: \6 d4 r# n3 A4 d
  8. .INESMAP 19                                                 ;mapper 19
    : }2 ?( H/ o" Q7 o+ _0 N
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直1 ^  G- L' ~. Q, I; W
  10. " p( I/ e! m( r( T' k
  11. ;必要条件! t6 i  Y3 v4 R0 E6 Z! Z1 {
  12. ;1.持有CHR ROM: P9 `, v! x( B0 b" f+ u0 D
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    % ]1 v( h3 W# W
  14. ;3.精灵内存(OAM)不为空2 y$ s7 I! Q: r/ E5 a- U
  15. 1 N; L; w% y$ f5 l( ~
  16. ;==================================================
    0 q3 H4 R! N; k2 I9 y; i1 I
  17. ;NES端口常量" }7 v6 a2 K2 a
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器0 E$ Q8 F; N' }& K
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ; ?# d/ C8 ]" b0 s
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    * X, l6 j4 r( s. {" U) M! H
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ' H: _" t, y( U7 `# R+ L3 B
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 N, I& B8 d% D* S/ r2 d, g
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 5 d. }7 k* I. p- T8 Q& ~
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加+ d; j- X5 @' o! @# h6 f  E
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    % H# P# p& j- W+ S) U8 y
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存3 q! ~- G; W& N1 h9 [  a. |3 ~
  27. APU_STATUS              =   $4015   ;声音通道切换2 t  z0 d5 `- O
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    + S) b/ D3 K( |9 l( C& _6 p
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通2 c( h' y8 i) s8 J- C

  30. ) V2 t! u, e, t
  31. ;==================================================
    4 i) D3 }2 {2 r
  32. ;MAPPER 19端口常量+ n: _: s8 w. C1 A7 Y
  33. M19_CHR_0000    =   $80002 T* X$ T" I0 U' O- B' t+ R3 V
  34. M19_CHR_0400    =   $8800( d7 g* Z- v2 ^- L$ |0 _
  35. M19_CHR_0800    =   $9000
    ( G- a. }3 ], w( m$ |
  36. M19_CHR_0C00    =   $9800
    $ `- G. I5 H# f  b% J1 W
  37. M19_CHR_1000    =   $A000
    9 Q* F1 W% f6 I* v
  38. M19_CHR_1400    =   $A800
    4 O- j" S* R/ _5 U) b1 n5 D$ \
  39. M19_CHR_1800    =   $B000
    9 H8 U6 j+ x: u. L3 D3 n, I
  40. M19_CHR_1C00    =   $B800
    / B, j5 @" B8 j0 f. t- y* |
  41. M19_NT_2000     =   $C000& u; U3 u* U- G, q' [3 o
  42. M19_NT_2400     =   $C800
    # }( ]  k+ c; z" f2 B2 _
  43. M19_NT_2800     =   $D0001 \0 G$ O3 ]2 o+ Q$ c) }( z
  44. M19_NT_2C00     =   $D800
    ' G' r' p3 F: v' S
  45. M19_PRG_8000    =   $E000
    / j1 s5 ~+ y  }6 ~' c+ U" @
  46. M19_PRG_A000    =   $E800
    5 g+ l7 v' n* n; k( Z& ]6 n
  47. M19_PRG_C000    =   $F000& I' F- p+ u% k6 p2 }
  48. M19_IRQ_COUNT_L =   $50004 q* k& s  j2 d- F% j2 u1 x
  49. M19_IRQ_COUNT_H =   $58009 ^/ e" J2 F3 f) v

  50. 5 z8 T4 N# m" `7 F$ R
  51. ;==================================================5 [/ w9 w' Q9 c" ^
  52. ;程序块配置1 l/ r# G! B& V& k% g& d) G
  53. BANK_DATA_MASK          = $07) _% H9 O# n; F& z5 G, M
  54. ;--------------------------------------------------
    - E6 J! f3 \! H- C# g, |5 |9 s
  55. RESET_BANK              = $07& b; S2 Y1 L) k% n2 F4 y( i  |
  56. RESET_ADDR              = $FC00. d( E2 v/ \$ d$ M6 x0 w0 U; S
  57. - ?: _" s/ t5 R9 }* J/ Z* `
  58. ;==================================================
    5 V  v' C/ M% i" }
  59. ;图像块配置7 p/ `- N) z2 n, m* E& o/ g/ Q* N7 [
  60. CHR_DATA_BANK           = $08! B+ o, h+ v& c
  61. * r8 H/ c5 H( k0 y, a( v; y& A
  62. ;==================================================( y& I( [7 F. z; j! j
  63. ;零页内存地址配置
    7 {- o; J' [9 k6 j* P
  64. Use_Ram_Addr            = $80
    - d' u, A9 E8 _
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    , _; B  X6 y. ]/ y+ m; k
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    1 B, `# G: z5 F5 ~1 J( q
  67. PPU_Scroll_H            = PPU_Msak_Buf + $010 f! p4 t$ d" Z- R8 }& ?* b: f
  68. PPU_Scroll_V            = PPU_Scroll_H + $01) n# L+ G1 N8 z
  69. FC_Data_L               = PPU_Scroll_V + $017 m2 S$ @) W3 S3 p9 P! W
  70. FC_Data_H               = FC_Data_L + $01( G7 s% C0 Z; }( s. q- g
  71. FC_Data_Buf             = FC_Data_H + $011 I8 p, [2 l+ O% Y7 n
  72. ;==================================================
    % U3 C9 }, R# h0 T% q4 r) N& t0 a4 k; K- J
  73. 1 Z8 y/ h; w4 `
  74. GAMEPAD_MERGE_FLAG = $040 N' L/ |5 a$ D4 [

  75. 8 E% k5 r8 U; Z
  76. Gamepad_Keep            =       FC_Data_Buf + 1- q9 a* m, j( E3 ]
  77. Gamepad_Once            =       Gamepad_Keep + 2
    " t4 W  D  Q9 E  A8 V' q9 W! t% t
  78. Gamepad_Temp            =       Gamepad_Once + 2
    * \( [, h& \5 v' t- A  K
  79.                                 
    / s, \. K1 ?8 [
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    / q5 w. r- ~9 X% E  `
  81. Gamepad_1_State         =       Gamepad_0_State + 18 u' t% B1 u! _1 `% }  R+ b- C
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    + x5 c, Q# i4 S& ^) Y
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    0 |/ w& G% L1 r! {5 }
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 15 S6 O) r: A  f$ _% `
  85. Gamepad_Merge           =       Gamepad_Port_Value + 15 e- e8 ^, H/ g7 q5 |/ P* X

  86. 9 n, x9 j, C. q8 g% Z* @! S
  87. ;==================================================: x* z, q. n% c$ H5 Z3 Y1 C
  88. IRQ_Index               =       Gamepad_Merge + $01
    % R5 a6 ^8 L$ V
  89. ;==================================================; {/ K7 i: G3 }, ?- p" k6 W$ O/ s
  90. 9 c% {. F7 F2 \0 Y/ C- f/ o
  91. ;CHR图形数据; c+ g, N0 V5 r. A; ~
  92. ;==================================================
    " {: i0 g% ]+ y7 u
  93. .BANK CHR_DATA_BANK
    ( I; N. L/ e" J* _0 O
  94. .INCBIN "chr_bank/chr_data.chr"+ F( b5 m! w& U- _+ X7 ~0 m1 n

  95. ; W- s) P- O3 Q2 z8 V$ {6 c6 c% J
  96. .BANK RESET_BANK & BANK_DATA_MASK2 G8 M4 {4 Z- Q9 ]( s
  97. .ORG RESET_ADDR7 w# ~; f7 I$ ?2 _1 i$ R# N6 l

  98. : [7 w$ S- s/ _$ P6 F& T
  99. ;--------------------------------------------------; ]' v  ]9 A2 V) ^$ t" C$ B, N
  100. Attributes_Data
    5 ?# N& E, R: T; |: l
  101. ;命名表属性
    6 s6 E4 a" }7 x1 `6 s
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    + R0 l+ {* H( X# j, x& u, X
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA6 V) M9 g8 @3 j- L* S/ @
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
      I$ S+ }# t9 L, m: v! K
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    + w% y) ^' N5 t! a
  106. ;--------------------------------------------------
    * D* A3 f( U: Z& {! d4 i  H) s4 D
  107. ;调色板数据2 F# s4 U3 C2 a5 y; B2 K) b
  108. Palette_Data( w( M( l0 n" ~% }+ p4 v# s
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F. P& K5 \( e- [. r& f
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    , F4 O, K9 r& X# E( B+ z9 v6 \

  111. 3 F. ?' G$ x, d1 S" O+ g9 M2 w
  112. ;==================================================
    ; h7 M& S$ H9 k& s
  113. ;命名表初始化$ P" {. ~8 D7 b/ H: ]* N
  114. Init_Name_Table( Z0 T" R# o/ k: w
  115. LDA #$20
    ( j; F& G/ f: ~" q
  116. STA PPU_ADDRESS6 ^% ~2 b( h9 k- T% |
  117. LDA #$00
    ' B8 j( y! r2 w
  118. STA PPU_ADDRESS
    0 `7 s$ B; B: u; H
  119. LDA #$00
    ' h) W6 V7 Y3 K. r. h
  120. LDY #$00
      t2 S# d1 }) k$ K) L- H5 i8 v
  121. LDX #$10
    " G; ~4 R0 g) Z/ G+ ?% l$ l
  122. Init_Name_Table_Write
    " a' _0 s" ?& E+ E
  123. STA PPU_DATA
    $ t  H& j5 n  C
  124. INY4 H  c4 v) o6 A1 ]
  125. BNE Init_Name_Table_Write
    ! Q. G) l9 d+ `4 f7 Q
  126. DEX6 s" r/ k5 P  t0 |! _7 Q
  127. BNE Init_Name_Table_Write
    8 a; r. z" v0 c* B
  128. RTS
    ( `& L- m* z) B% H  Q# [. u
  129. # e% B; k$ V3 t) {1 Z" }( v; L
  130. ;==================================================3 B$ y: t( J! {+ ]% |: f) t: ?
  131. ;调色板初始化
    : ]5 q$ f) x9 r$ \0 P6 ^6 [4 A
  132. Init_Palette0 x9 G7 r5 \' e* S; S
  133. BIT PPU_STATUS
      P3 d1 V/ T! O$ d3 H2 a* ^& i" y
  134. LDA #$3F
    0 H& W! {1 M! v$ o0 `
  135. STA PPU_ADDRESS" M7 v' P% G7 t
  136. LDA #$00/ M$ a' |! O( S
  137. STA PPU_ADDRESS
      |; S5 X- h2 s7 u& b# T% r0 L# h
  138. LDX #$00: y8 a, [; {& v5 s- ~) s
  139. Init_Palette_Write
    / P$ D8 [" h6 `
  140. LDA Palette_Data,X" ~- x" l& I2 f' t4 i! Y6 D. p. ?
  141. STA PPU_DATA
    ; c$ C2 Y9 Q. w9 U$ p/ |
  142. INX
    * [% g% i( _7 F% s6 e1 n& u3 V
  143. CPX #$203 q2 H# @: X0 a/ ~
  144. BCC Init_Palette_Write  y% q: p( f( S' X
  145. RTS
    & j/ J, S" a8 K( u( |
  146. " L5 @* w8 U8 ~$ z
  147. ;==================================================
    ! y( B, K: V0 Q
  148. ;设置命名表属性+ P' y. F8 W* @
  149. Init_NameTable_Attributes
    % O: y8 Y, h* A+ z& [
  150. BIT PPU_STATUS6 U  ]1 B6 @5 Q9 Y$ Y0 b
  151. LDA #$23
    : I) D- w1 r7 G8 R, A
  152. STA PPU_ADDRESS, _4 a1 |$ y, Z/ S! G, U
  153. LDA #$C0
    # n* p' D: Q+ p  M
  154. STA PPU_ADDRESS) }/ }& v  F! h; d
  155. LDX #$00/ y' l" V% u7 f6 c5 l, F+ D3 f! a
  156. Init_NameTable_Attributes_Write
    + i4 a% y0 V* z) F9 T  ~8 `% T
  157. LDA Attributes_Data,X
    + d- E) p+ s& n0 F9 j  q) @7 C
  158. STA PPU_DATA: h2 ^" C) o  y2 }: j8 C, E$ T
  159. INX: Q2 u  ?6 i6 m+ E( E
  160. CPX #$40
    2 D. R' q/ Y6 E% s
  161. BCC Init_NameTable_Attributes_Write! `% a9 H6 P" Y; v0 S8 M6 |
  162. RTS
    5 s" t9 d& @2 A7 k* x3 t
  163. 3 w$ e0 o9 E4 I6 X; F
  164. ;==================================================
    ; U- d$ P4 v% [  G5 ~/ Z  _) k- K
  165. ;初始化命名表文本
    7 S' j9 O) a! F; s4 V5 a
  166. Init_Name_Table_Text
    8 p" W3 ?( w  u+ V. G6 U; O' L
  167. BIT PPU_STATUS  \* _4 {! x3 a( L/ z
  168. LDA #$20: B; U9 _' d+ @
  169. STA PPU_ADDRESS
    1 K7 X: I) a& q) H: f! _0 j
  170. LDA #$00
    % I  v/ z& b# N9 F: ]2 C
  171. STA PPU_ADDRESS
    # d3 L1 a2 l' j! E( `5 D
  172. LDA #$00
    0 D% V) s3 h: {9 H/ v* h
  173. STA FC_Data_Buf
    9 @  s! t( m( `7 Q
  174. LDY #30
    5 j3 w( n- T! t/ }" ]
  175. Init_Name_Table_Text_Write4 @* r+ p+ u" I- z
  176. LDX #32
    # B! l, @# p  P) Y
  177. Init_Name_Table_Text_Write_Char" l  X7 k3 ^6 j" C; t
  178. LDA #'0': x& }4 w; g) O4 h+ W
  179. CLC+ C5 u4 F! }" F- s
  180. ADC FC_Data_Buf) o% e: g7 }/ C  D; q2 T* A0 ]
  181. STA PPU_DATA
    9 W5 O3 D; b4 |# n; t) B
  182. DEX
    * z/ X) P3 e# Q
  183. LDA #$14
    5 Z/ y" w3 ~1 X% \( \# @
  184. STA PPU_DATA
    , b4 c+ M/ c7 ?# [& U
  185. DEX1 |7 ~" L7 L4 I/ g# b8 {' ~2 m
  186. BNE Init_Name_Table_Text_Write_Char1 `9 N& T+ a4 @/ o/ S# {7 o; J. q! r
  187. INC FC_Data_Buf
    " D3 I# `! }# [8 ~$ D
  188. DEY
    ) G3 h+ V- S% L4 f
  189. BNE Init_Name_Table_Text_Write
    # X9 O+ P9 n9 ]3 x( Z3 B( i/ y, `. z
  190. RTS4 |* _+ ^* H% r( _
  191. : F* b* H/ o* U; w: h! C) P
  192. ;==============================
    : g) a" B0 Y& G- a* C/ F
  193. Init_OAM_Ram;初始化精灵内存
    7 S, y6 J" x: @
  194. LDX #$00; E$ c  ~& R. `
  195. LDA #$00$ J) v  k  }1 }* z) u
  196. STA PPU_OAM_ADDR& T3 l/ y( z1 g9 X+ R% @
  197. LDA #$F8
    ) v1 {# y+ ^. [+ ]+ c! _/ E
  198. Init_OAM_Ram_Write
    * E9 G* y) B3 m' m
  199. STA PPU_OAM_DATA
    ; c: u; Y0 L! u# a  o6 V$ w  i
  200. INX
    # A7 I2 Q& T8 C  W" q2 b
  201. BNE Init_OAM_Ram_Write
    4 B0 j; e1 C: w) z' w- M0 t
  202. RTS
    5 z8 `! o  S, x

  203. 1 \$ M; n9 L( `6 S& x) }. O$ n
  204. GamepadProcess;手柄处理7 F: O: |  n$ q3 o0 F
  205. JSR GamepadDatacan# o) b3 `5 e6 R: n% i
  206. LDA <Gamepad_0_Value
    - {5 l0 `/ f7 \, z( F
  207. STA <Gamepad_0_State
    ! @% X) K" I4 y, K; N5 q* c% g
  208. LDA <Gamepad_1_Value' C1 ]! O8 O7 y( g/ a6 k+ L+ }
  209. STA <Gamepad_1_State
    - a1 i& L7 }1 Q0 R1 C$ f* Q; v  d
  210. JSR GamepadDatacan  E9 \1 W: j1 L: |# ^4 L( M
  211. LDX #$01
    ; G* D/ N) H2 ?8 z  D" Z
  212. GamepadMergeCheck;合并手柄输入检查
    8 _# `" N' f& _5 M( j" Z) A, U; A' E
  213. LDA <Gamepad_0_Value,X9 `. X! N4 n* f5 u, U; _5 r
  214. CMP <Gamepad_0_State,X  J1 c# {6 g; G2 W! q
  215. BEQ GamepadMergeInput0 M8 T5 m1 H" c/ G* |7 l4 ?
  216. LDA <Gamepad_Temp,X
    7 J5 i- o" g8 @2 |) X
  217. STA <Gamepad_0_Value,X9 w, C; |: D+ n/ }" Z
  218. GamepadMergeInput;合并手柄输入& b- Z* q" r. P0 F" }9 [
  219. DEX
    7 ?5 r& l0 Y6 R
  220. BPL GamepadMergeCheck7 R. G* H; w# }8 y5 }/ i
  221. LDA <Gamepad_Merge# ]% Y" U5 A% @. n- t9 M# c
  222. AND #GAMEPAD_MERGE_FLAG& M2 J2 [5 }' d& D4 |7 w  k
  223. BNE GamepadStateProcess3 Q/ `' P6 _% `- o0 c' W
  224. LDA <Gamepad_0_Value
    ) b% o+ m% Y' f% K/ e0 I0 x6 S6 B" [1 i
  225. ORA <Gamepad_1_Value# Z6 n2 B# J% Z( F/ t2 E$ R
  226. STA <Gamepad_0_Value
    * V, @5 [  S; v7 [' L; C
  227. GamepadStateProcess;手柄状态处理3 o3 [7 }" j! T6 t7 v% v$ T% l/ v
  228. LDX #$01
    - i1 z: X/ o% N6 j
  229. GamepadStateSave;手柄状态保存
    7 |" w# p, y7 v2 v: M
  230. LDA <Gamepad_0_Value,X
    % F5 B9 `+ d$ j0 C+ d4 t" Q" k: b
  231. TAY% F" C  ~- x* k3 x7 y- j4 _
  232. EOR <Gamepad_Temp,X$ A; c% O. }: j: y) ~- W
  233. AND <Gamepad_0_Value,X7 I/ O" ], i1 U& r
  234. STA <Gamepad_Once,X* q0 o1 g  H" n) c
  235. STY <Gamepad_Keep,X
    " |& g6 [* z0 L( R  f- L
  236. STY <Gamepad_Temp,X8 u3 c- ?% g$ q* G
  237. DEX
    : C! V$ a$ A# Q0 R$ f
  238. BPL GamepadStateSave* o6 W, S- p! f: B" L  X) F4 y
  239. RTS
    - d. O8 W5 }" }# ^3 Y

  240. 5 w8 a1 G, Z. R" W, n8 w0 ~1 r
  241. GamepadDatacan;手柄数据扫描
    0 l; m" `" T- c, ^8 J
  242. LDX #$01
    % B& ]( n  m/ y, P+ U! z7 H
  243. STX $4016- r" E" p( n+ ^. z3 m4 Z
  244. DEX
    , ~7 r; k& I0 R$ f
  245. STX $4016
    % |2 X. `) J: t# W
  246. LDY #$08
    9 ?2 t$ }/ ~* u; x1 X4 O/ k+ `
  247. GamepadPortScan;手柄端口扫描
    0 k+ {2 u' `+ s( m- M2 g* k& A
  248. LDA $4016
    6 u& `: Y  D- ?1 d; e( s
  249. STA <Gamepad_Port_Value
    - t4 e4 a9 z$ Z# \4 r" I1 J
  250. LSR A
    7 G' l6 M- L! ~8 q" j
  251. ORA <Gamepad_Port_Value- ]. L8 T$ C4 t5 }3 \  \
  252. LSR A
    5 j* {" Q4 z% a* _" c
  253. ROL <Gamepad_0_Value
    4 [: r. }1 Q* `; X0 f% T7 S
  254. LDA $4017! X# ?2 i6 B, M) E+ S
  255. STA <Gamepad_Port_Value
    % U2 \5 U+ {$ t; I$ j5 Z2 b
  256. LSR A) q9 R& \3 u9 Q1 a- e- _
  257. ORA <Gamepad_Port_Value
    + Y) ]  P# D$ _& `5 H
  258. LSR A
    $ Y; H: B4 b; I: N
  259. ROL <Gamepad_1_Value6 O. X5 K- l1 u
  260. DEY; \1 Y8 X8 h( b/ [8 E
  261. BNE GamepadPortScan
    : M' r# I5 f& s* m% `  e/ H8 o3 Q
  262. RTS
    3 T( ~* O5 S; l. ~  g
  263. ; d6 x% ?: j( I; K2 Z/ \
  264. ;==================================================
    - A0 e1 N+ x; N4 h5 A8 `8 D& E% A! s5 ~
  265. ;PPU处理
    & D! p. y/ _- W2 M" U; \
  266. PPU_Process
    ( ]! D& H  x/ o/ u
  267. LDA #$00
    - o& M% F& o- D* L' M$ J2 H* p
  268. STA PPU_MASK
    2 @7 ^# ]/ {; g3 n
  269. / ~  ~3 J3 P/ ~- d* }
  270. BIT PPU_STATUS
    * h7 F# y# t7 J6 |# v! ]  e9 {
  271. LDA #$20
    + ?& C9 e( h$ ]! F7 `4 E9 B
  272. STA PPU_ADDRESS
    * ^- a) b4 ?! f# z
  273. LDA #$00
    , u6 V) k# q% ]# D
  274. STA PPU_ADDRESS* Y6 B1 r8 p' L" B/ \" L7 \; g5 L' ]
  275. 0 }3 Q; P  e9 T
  276. STA PPU_SCROLL! v4 O+ n. J2 R2 R7 X0 [2 y6 s
  277. STA PPU_SCROLL' ]+ {) V  o: Q8 P

  278. ' \( u) D) I1 ?; [, u
  279. LDA PPU_Msak_Buf5 c8 Q! P* n( V8 P; @- t
  280. STA PPU_MASK
    # B" m* z* I* y0 P9 h  w1 X4 U
  281. " e! P, ~( R5 b- a$ \' M5 c" O! N
  282. RTS
    & u/ G' T5 C. P4 w  F
  283. . M, |$ e% k1 b- z: E) P
  284. ;==============================
    # Q. q) r9 ]3 W4 N; e7 @
  285. Time_For_Vblank;延时等待
    ) E! i( |6 o5 T4 _* r
  286. LDA PPU_STATUS
    5 e( s- h1 X6 p+ }
  287. BPL Time_For_Vblank( K# T  j( s0 f$ ?5 F
  288. RTS9 ^4 g* w( ]' A/ r. q+ {

  289. ' E. K1 o. o$ t3 q# E
  290. ;==============================
    8 b3 K$ m, k3 r
  291. ;初始化MAPPER19* z; P, y6 v: {# k
  292. Init_Mapper19- J- I; l7 b3 `8 N8 D/ D
  293. LDA #$00
    ! o- I% w5 I  x6 X0 G9 r
  294. STA M19_CHR_0000
    1 k- G+ o* g7 s6 K1 S
  295. LDA #$01+ [  d$ m/ B0 j- D5 ?
  296. STA M19_CHR_0400
    6 H+ e' k" I; D
  297. LDA #$027 B; K1 ]: ?" s7 E6 v
  298. STA M19_CHR_0800
    , e# k* p( u  h, v
  299. LDA #$030 u7 E2 ~; q6 d2 }7 B) W- f: h
  300. STA M19_CHR_0C00+ n8 h# ]$ R& ^9 e) R1 s, Q. T( Q
  301. LDA #$04
    ( R5 k- T; V. n3 ]3 E' s
  302. STA M19_CHR_1000
    ; K. L! A5 n1 D# g# [
  303. LDA #$05
    8 }. V: a- r5 ]4 ?
  304. STA M19_CHR_14007 c1 w; P5 [, T! P3 o, a# F/ o
  305. LDA #$061 s3 D( i& {% z3 H! S
  306. STA M19_CHR_18007 p& W# _; \; s. l
  307. LDA #$07* Q& N, M5 s- D% S* u8 K
  308. STA M19_CHR_1C00
    * B& B5 w, d. F1 p- |  |* Z: J

  309. & V+ s) v) D- o9 q. p( [
  310. ;禁用IRQ& Q8 m1 t4 `, L7 x" B8 l9 q3 E
  311. LDA M19_IRQ_COUNT_H
    1 y1 O5 y# {  \* X! _
  312. AND #$7F
    $ `1 x' K% i. F$ }& a- V
  313. STA M19_IRQ_COUNT_H* W8 |5 W' x" z) H
  314. 9 I+ A$ [$ S3 U- k$ [: k# X* F
  315. ;命名表% f" X- i0 a! O& A- F. N
  316. LDA #$E07 h  ], A6 [, J
  317. STA M19_NT_2000
    * s) y- n) @% u/ {2 b+ h8 i- i
  318. STA M19_NT_2400
    ) R% b% a, j1 Z9 ^: K
  319. . A2 ^4 n1 h0 F+ h8 C4 U
  320. ;命名表; A8 `/ f& O- \# o
  321. LDA #$E13 y& @, w5 c; ~- f" Z
  322. STA M19_NT_28007 V. \. f* R, z, v. j$ `
  323. STA M19_NT_2C00) p% b" D1 ]$ {! A

  324. & b5 s! T7 {" X# {) o
  325. RTS
      X  u8 m5 b0 W: ^6 |' j

  326. 6 i4 b, z  \+ A
  327. ;==================================================
    + i0 [, ^9 t: ^4 K" b
  328. ;重置中断处理5 {. j: Q8 w* ^+ L# o, \
  329. ResetProgram( X$ O& K# X3 P. v/ o
  330. SEI
    6 P, E- Z+ C& m7 p! k8 k9 Z
  331. CLD
    ' b# D6 |' i! M# X- j' R/ e
  332. LDA #$00
    ; S. n  a# T1 t5 L4 n
  333. STA PPU_CTRL
    3 F/ S/ y+ K7 R$ A5 i  G$ W
  334. STA PPU_MASK- W4 b. V2 ?6 v6 E! P, s" o
  335. STA PPU_STATUS# r4 x1 ]6 ~: I5 f, S1 ]3 A; H
  336. STA JOY2_FRAME
    # k! Y6 Q* M( l2 i4 A/ Y8 r6 V
  337. STA APU_STATUS+ Z; d/ _( ^2 ]# `$ j: C8 S: i' J

  338. 8 V. J$ \+ m. _8 i
  339. LDA #$C0+ k8 {+ Q/ g/ M- }' \2 n* Y
  340. STA JOY2_FRAME) B5 r$ y# b) `: z7 b7 }& X$ b
  341. ; I4 h6 I4 N; H5 ]  _4 ]! q
  342. ;等待vblank
    " _# c6 K% a& C# t4 `/ X0 f
  343. LDX #$02
    1 q) @# w/ x$ z% n7 }2 v0 }  m8 o2 n
  344. Vblank_Wait_1
    6 L, t, N$ f: v
  345. BIT PPU_STATUS1 t3 t9 o4 b3 D% l  `
  346. BPL Vblank_Wait_1
    8 V' {. e0 q9 `# U. j- V9 z
  347. Vblank_Wait_2
    7 c) T* n: i, m
  348. BIT PPU_STATUS' Q7 U  i/ `; m7 o( N1 L, B
  349. BMI Vblank_Wait_2* X! l1 Y# m8 P7 Z7 {' n
  350. DEX# _" O, S$ C  [0 p/ D% S# W
  351. BNE Vblank_Wait_19 k' x+ n- W$ z" J0 s/ S
  352. ' ^+ F& y2 T/ X
  353. LDX #$FF3 c5 [; f0 X8 N$ S: Q
  354. TXS
    # a6 F$ l1 {# Z9 S

  355. ! A# l& A/ k3 R! V$ U' t, t- v- Q" R
  356. ;初始化MAPPER19
    ( w) l) A/ u' u8 }8 N
  357. JSR Init_Mapper19
    2 Z, f9 S( I2 f: J4 J3 v
  358. 9 {+ ~" d3 G/ Z2 T- V# t, F& u; E
  359. ;==============================
    , I! c  @1 U- g
  360. ;RAM初始化
    2 l& N( ?5 t5 z" C
  361. Nes_Ram_Init
    6 ?0 l- ?/ N+ j/ ~" M5 q+ K, c' l' `
  362. LDY #$00% ]3 C7 e* ]9 P- A6 I' |! C9 T
  363. LDX #$08
    " ^# ]% j" {$ O
  364. LDA #$00* `8 ]& e* o  q: m3 `! Q, F8 ]
  365. STA <$00
    9 j* V7 b* {1 n/ S( E' L8 T8 P
  366. STA <$01( h! _% b9 K6 b+ B$ _# ?
  367. Nes_Ram_Init_Write
    2 i# u  T( u. P
  368. STA [$00],Y
    % h' f/ s( U: f! p9 w
  369. INY
    ) m) O* C% d0 ^) l
  370. BNE Nes_Ram_Init_Write# K3 o" _* ~; e( m+ ^0 n9 f  J
  371. INC <$016 `: i+ f/ ~- s4 I2 }4 M
  372. DEX
    ' m/ w/ c, {! Z7 a  T
  373. BNE Nes_Ram_Init_Write- [; c) X6 b% j4 B8 \' b2 z
  374. 3 a& f! q, k) {: D- [& i
  375. ;初始化命名表- u  T) D; t9 Q; L6 `9 v
  376. JSR Init_Name_Table5 v0 H, r# Q+ K5 k* z' o' w
  377. ; Y1 x( X8 J! H- n
  378. ;初始化调色板
    " |+ s' h4 ?9 S0 b
  379. JSR Init_Palette/ _" H, J1 w& R# i( u8 E' h' x
  380. ' H1 V/ n* g9 _( p# p  m' {9 ~
  381. ;初始化命名表属性
    1 A6 C& o" V; Y0 G8 B( C' g. Q4 `6 f
  382. JSR Init_NameTable_Attributes
    7 g2 V' r3 F( ^- M3 P

  383. + q9 e8 Z+ D5 V6 I2 U0 x! P
  384. ;初始化精灵内存7 m3 g$ m0 @$ B3 W9 ?1 Q3 K1 N" m0 G
  385. JSR Init_OAM_Ram! e# r% f, |6 I$ b: e

  386. 3 S& g5 w) P3 N& }1 E1 g9 f
  387. ;在屏幕上写点东西
    & P* T/ P( {2 j
  388. JSR Init_Name_Table_Text' o1 e; I) p$ o0 d  z

  389. 1 A3 Q; J* L9 w0 Q
  390. JSR Time_For_Vblank+ m/ _0 [) B7 b
  391. ;开启PPU控制
    8 c, X( B" y  P* {: L
  392. LDA #$A8
    , t+ q! j9 f: J6 u. b& o
  393. STA PPU_Ctrl_Buf) ~8 Q1 ?7 n+ e: s/ q
  394. STA PPU_CTRL* `4 l0 N/ h  f, Q
  395. 1 @$ l4 ]- ^4 p: Z) s" e1 V
  396. ;开启PPU显示
    0 Z2 m, F! R. P! E/ X
  397. LDA #$1E! p! R% R, l9 W. z3 a
  398. STA PPU_Msak_Buf$ P4 \( i2 R$ Q1 i2 `6 W

  399. , b- O# O# V  W3 @2 H/ A; f6 d
  400. CLI
    & B: o0 [, z0 o! _. f. O
  401. JMP Loop
    4 c# S# C; |, A( k4 X. x! [
  402. ' d. E0 D! ^% G1 z( f/ }# E# B
  403. ;==============================- M) v4 I# I; |
  404. ;死循环, 等待NMI中断0 n% ~6 j4 p2 Q5 |' S, d
  405. Loop+ T- U: c, K# _: M* N( S
  406. JMP Loop! ?2 ~! ?" i7 y$ T; J

  407. 5 _5 n- ^5 H$ |8 O' r3 B
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967) b% V' a& g# o/ j% t& E. {/ U: H

  409.   ?3 }/ {9 l3 Z( e7 A
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)/ o" V/ \: f9 t3 i* M+ s8 V
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103). b" |7 s& w5 W; o! p; }, z
  412. ;==================================================
    ( j$ `) [" k" M" m2 Y2 T' N2 i6 J. n
  413. ;NMI中断处理
    # n) d/ t6 u/ K
  414. NmiProgram% E# @% E* N4 F* |
  415. PHA* |9 h5 T  W$ o2 N# f5 @
  416. TXA  W8 Q! r' `6 D% u9 R
  417. PHA
    5 q! X5 Y) g" O, n: @6 u7 |
  418. TYA
    8 S6 f# G4 I8 _9 ~) Y9 F
  419. PHA5 ~; M% {; K& h2 f* e3 w

  420. 2 o% }% O4 A" o; V! `' \
  421. BIT PPU_STATUS
    . |9 m. m. c6 M  [, _

  422. " R" ~5 u% o9 M; u4 v1 ?, f5 N
  423. LDA #$00
    1 f: v4 o$ r; F8 t6 ~& i
  424. STA IRQ_Index
    8 x3 e% z8 ^; k( f% k* i( X+ W  Y

  425. % Z: h& S. y3 J
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    : q+ G0 H* }% i2 L0 s, `  y% Z
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    3 M8 v' y  k7 _/ e  W
  428. STA M19_IRQ_COUNT_L& u* v3 g- l, [# ~8 }- J9 o0 z' |
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ( Y3 r* ^2 N2 y5 N9 Z* Y3 ?
  430. ORA #$80
    7 D$ |# y9 b, A6 ?* z/ b) d9 G
  431. STA M19_IRQ_COUNT_H
    0 L9 E7 Y1 X' S9 Q" M
  432. CLI
    . ?4 T' e, h5 `' L- }+ x

  433. ' O& ?6 N9 w7 L9 B9 ~1 ~
  434. ;关闭PPU控制
    % X: i. w' l. P
  435. LDA #$00' D' @, t- y; m! R, i  B
  436. STA PPU_CTRL
    5 X  c% L7 c& W
  437. * I  p8 V* t( f2 A, K
  438. ;处理PPU7 _. U( l5 s! {  t  d* Q+ p) a
  439. JSR PPU_Process
    $ l/ j0 r% _9 i* H4 v. {- C0 W

  440. + s  B0 j: g* T' X9 ~
  441. ;开启PPU控制
    . w7 X9 A$ G; A" B/ g: |/ d' r
  442. LDA PPU_Ctrl_Buf
    ( u4 [8 v  A' P7 f# C( l) f
  443. STA PPU_CTRL
    0 s+ u8 k5 w) y7 C; n. R
  444. ' N' y9 o) ]4 a. F/ T
  445. ;手柄处理
    7 N# f3 p+ W( h
  446. JSR GamepadProcess# s( {* ?3 X& U9 r+ J* ?
  447. 0 I, Y) Y4 p5 s
  448. LDA #$00
    # j* k. N0 t  A1 }7 J" J+ p. j8 S
  449. STA IRQ_Index# p$ p. t" r2 T, H# A

  450. , L8 U' k2 }8 C$ p+ H
  451. PLA
    ; ^' ?8 @# X' h* U& a
  452. TAY
    3 R+ y4 k1 a8 v! N
  453. PLA
    % t0 V8 f' ?; b/ c
  454. TAX
    . A  o) B9 W; F/ }
  455. PLA
    5 Q* n$ }$ J: n  E
  456. RTI  F! K2 C! t' u% h
  457. & u0 y2 W. L9 C& y! V1 R
  458. ;每行扫描线113.670 _' S9 S) f9 Y3 g/ a
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)( \% B+ I4 S% p+ p; V
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7. |' J- B. i7 i- E# x
  461. ;==================================================1 ^2 [  R1 n0 o- k! f
  462. ;IRQ中断处理
    ( f& H6 y6 c% \/ C
  463. IrqProgram, X  V8 r1 C5 L# H) A' \8 r/ l
  464. PHA
    7 s$ K$ f5 b6 r) S9 x2 Y  d
  465. TXA
    9 h  B/ e. u7 z# Y: @
  466. PHA6 b( k! H7 a/ e; Q& m
  467. TYA/ {1 ?+ x4 b; x, k5 A1 F% R  m
  468. PHA
    6 q0 }( R3 d2 a& `- W( }( L" F
  469. : a1 `  \  U! P" }8 S. N2 o! N& j# R
  470. ;16条扫描线后触发IRQ, m+ O; w  c' D4 @1 V
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    - L$ d% @, A1 Z4 E* ^/ y) u0 a
  472. STA M19_IRQ_COUNT_L1 U: [8 }  ?6 Y. V; T; I2 ]
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    " w( n% g7 q& e: P. q7 q
  474. ORA #$802 _+ b  r: S: A, @" s
  475. STA M19_IRQ_COUNT_H
      a* q1 _8 R" _' t

  476. + U6 a8 q+ v% x9 e: H$ p
  477. LDA <IRQ_Index
    - \( r7 d7 L% P. O1 f8 b8 E# o
  478. BNE * + 4( O3 ?: F' x% C% ]
  479. INC <PPU_Scroll_H4 i% M% e2 p: [! O0 |8 f% m

  480. + l2 I0 z* p  M7 L+ U  V
  481. ;设置屏幕滚动$ [" j% h# V4 L( _- E# n
  482. LDA <IRQ_Index
    % P  X% N2 B# z# H! d& ^7 Y5 K" O
  483. AND #$01/ d9 m. F$ g) ]
  484. BEQ Irq_Scroll_Right3 U! O3 S9 X6 U, R/ u# n, {" @
  485. 1 r# x! q3 ]3 f$ `
  486. Irq_Scroll_Left+ [8 Q% n5 F2 h
  487. BIT PPU_STATUS; r, `) i0 C0 L, O% D
  488. LDA <PPU_Scroll_H
    % A  M4 g7 R1 U  ^; ^! K
  489. STA PPU_SCROLL9 J( z* X. o" p( _8 t  P
  490. STA PPU_SCROLL' y5 D8 C8 T: j' D
  491. JMP Irq_Scroll_Over4 W1 B, B% `* w2 p; |

  492. - V9 z4 E; V3 S, ~1 W1 t
  493. Irq_Scroll_Right
    1 B' }; Z8 R) j* B! m" t3 g
  494. SEC' B* g: c4 {& B: P6 r
  495. SBC <PPU_Scroll_H' z. c: R' c* J" F
  496. STA PPU_SCROLL( b6 z+ H" y0 r  Y
  497. STA PPU_SCROLL
    , ]  I. s% s% }: @* ]
  498. Irq_Scroll_Over
    " `) r! _% n/ _& d
  499. 3 s0 F' g6 i: W' A( |" @" |8 m3 y
  500. INC <IRQ_Index) m5 a* ~; B* D* ~6 R3 W7 Z# |
  501. 0 o' B& k" y4 }4 s* W! u  G: Q  u
  502. LDA <IRQ_Index
    - q& e9 N5 X. i! G
  503. CMP #14' B" h0 x0 A) R/ i1 Z/ {5 p# J8 {
  504. BCC * + 10
    # R9 w( C. X5 W! {2 `, A+ ~& i
  505. LDA #$00$ N& x+ G9 _& x. g% |9 o
  506. STA M19_IRQ_COUNT_L
    - `* T$ b# @! I0 X* R. m
  507. STA M19_IRQ_COUNT_H7 D: m: L6 u; x# w* i; a

  508. 1 g: G1 i( T& d8 K) K5 H
  509. IrqProgramEnd
    6 M' K" [' s- }: e; T
  510. PLA- M7 Z$ _- r- s6 \) [
  511. TAY
    : e9 q) J5 z, x- M7 O
  512. PLA; v: ~! s- v2 T
  513. TAX
    ) C! B1 o! Q! n* k  C, B1 m
  514. PLA4 M- y; p5 p* |5 V, \
  515. RTI
    ; K. R: o' F6 Y1 C. {

  516. " e& _$ G3 o+ p: u* y" h  \7 P/ k
  517. ;==================================================$ B& x9 ]& c" q% u: y6 ~
  518. ;中断表) j2 O  Y3 x5 I, h+ Y, F4 m9 g
  519. .ORG $FFFA
    ; e5 v4 W" O; F1 `
  520. .WORD NmiProgram  M, {3 h9 K& |2 q( u
  521. .WORD ResetProgram/ {! u, |/ Q4 ?( V
  522. .WORD IrqProgram
复制代码
9 Y% @1 N8 v0 S: |

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-8-5 10:25

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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