设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    , i! T2 s& L( n1 S! s
  2. ;FlameCyclone 202307102 i- z7 q; u! I  X" A6 @
  3. + t, V/ q* h% W9 F/ t  D1 \! g
  4. ;文件头
    8 C& I1 a, K$ A6 m) {
  5. ;======================================================================
    2 d7 ^4 B8 V( [7 X
  6. .INESPRG 4                                              ;16KB PRG 数量
    $ q# d$ B+ h: `. N. }
  7. .INESCHR 1                                               ;8KB CHR 数量) ]( Z" x$ o/ O" H0 U! {
  8. .INESMAP 19                                                 ;mapper 19
    7 q8 r4 F1 K4 t1 X6 n
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
      n2 y% G' o- C4 ~% j2 j
  10. ) r+ V* i/ D! ], d1 E; z* d7 Y
  11. ;必要条件
    - i, i+ \* s! v* |3 e# @, q
  12. ;1.持有CHR ROM2 F) R/ n7 ^/ s- E6 V
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    & }4 s4 m6 X0 w& e' m, z+ j
  14. ;3.精灵内存(OAM)不为空
    " K( q& a5 G& w  f$ G9 h  x5 I

  15. & r% [, ~6 P6 t: U5 q
  16. ;==================================================
    / B9 O# c$ o4 v7 a2 J7 }& e' G
  17. ;NES端口常量
    & |3 V9 m( u! H2 M. K7 |' K7 r
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    - n/ |' {$ _, H  E4 h5 b3 Q! _
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    $ f( m4 z9 [, J9 N0 d1 k5 p: }
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位1 R2 B4 l& t2 U# C1 K+ j
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加10 d' v' ~4 ~* z# M/ z5 d
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    & i% R5 N% Q. q9 T  j
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    # u' P  g/ Z% ^* }
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加) O# Y3 ]5 w. ]8 W% j/ ~
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    6 z; w+ l1 C! K3 k' u
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存2 A2 b9 T# a+ m& i
  27. APU_STATUS              =   $4015   ;声音通道切换
    % E4 `, {) s. j7 T
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    0 }( `' T% S2 ]! B  U
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通0 M4 }  o' {- _% f  Z
  30. 2 x% j; r5 r, y6 R  r& j
  31. ;==================================================' B# k% e6 K' p! z" c% g
  32. ;MAPPER 19端口常量
    ( I9 }8 T9 h+ U" Z: z& r
  33. M19_CHR_0000    =   $8000! i) j% h5 h' y* _; R) N
  34. M19_CHR_0400    =   $8800# Q* m2 H8 f9 m. @
  35. M19_CHR_0800    =   $9000* R, b2 H2 s6 D
  36. M19_CHR_0C00    =   $98005 i6 W0 U8 u& X3 l2 H% m9 y, o
  37. M19_CHR_1000    =   $A000
    ' D' f% V; g3 l: S% D
  38. M19_CHR_1400    =   $A800
    " ^& ~  F* X3 ?1 Y- n& T
  39. M19_CHR_1800    =   $B0006 l' p' u9 @8 `4 p
  40. M19_CHR_1C00    =   $B800; b+ a6 J5 ]6 p9 O: R8 V
  41. M19_NT_2000     =   $C000
    6 W  _' W& y3 l5 j% W
  42. M19_NT_2400     =   $C800
    / U7 t  u( P# g% `; q
  43. M19_NT_2800     =   $D000! v/ `" B2 o! @  q/ A! y# U
  44. M19_NT_2C00     =   $D800+ S" j% @. k" ~: H) w7 B& [6 H4 U9 `/ N
  45. M19_PRG_8000    =   $E000  K- q! z! ]2 }# h
  46. M19_PRG_A000    =   $E800; u% z0 m# |& u" l1 H8 H5 j
  47. M19_PRG_C000    =   $F000
    & N9 x3 F8 a8 u" T* Z
  48. M19_IRQ_COUNT_L =   $50004 c5 N  d+ {, e! ~( l+ Z5 B; V4 B( ?3 s
  49. M19_IRQ_COUNT_H =   $5800! t0 J6 W' U% `3 T3 m0 x. A

  50. - T; J0 o+ \6 [
  51. ;==================================================! F' ?1 l! [5 D: [' K9 W6 ^- l
  52. ;程序块配置
    $ s& h0 w4 \+ |/ \
  53. BANK_DATA_MASK          = $07
    6 X/ t6 l' a9 p0 B( H
  54. ;--------------------------------------------------
    ( W! i6 |/ X0 d% H  w- M
  55. RESET_BANK              = $07
    ( h$ a0 L! T. Q1 I
  56. RESET_ADDR              = $FC00& a% M: ]4 F- i# v: n
  57. + J2 {! V$ e" O4 x2 g. Z
  58. ;==================================================
    % `& F/ h* g- [' _
  59. ;图像块配置3 y# ?8 Q1 x* `* Y# i' D0 C
  60. CHR_DATA_BANK           = $08) @- V/ u" _0 y( W) n. b1 m
  61. 3 J  L0 \1 e" D; s  v) f1 w- M
  62. ;==================================================0 ~2 x4 x9 b, s& I5 `6 X7 P
  63. ;零页内存地址配置
    + t, y9 Y4 u# g9 D% P+ i: c
  64. Use_Ram_Addr            = $80
    5 A  h! u! n% A( S3 p
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    " `5 ]: o7 h. |& l
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01  g8 e; }8 s$ g
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    0 L( B$ C# b2 F8 k' w3 ~
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    ; L) D% D4 Z) l8 a) W( K
  69. FC_Data_L               = PPU_Scroll_V + $01
    $ f; t2 @  o9 P/ g% P
  70. FC_Data_H               = FC_Data_L + $01+ u9 h8 J5 N5 B
  71. FC_Data_Buf             = FC_Data_H + $01
    ! G( \3 D, o4 R" w, y
  72. ;==================================================' s' T! D% K) C( V
  73. # O( `4 V; c/ k# W' C; _
  74. GAMEPAD_MERGE_FLAG = $044 Z4 R7 w1 f3 j5 h# |
  75. % n4 N, h6 P) f  [2 U
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    1 @! U' J( i% S, ?: v, x) h
  77. Gamepad_Once            =       Gamepad_Keep + 2
    * E( ]& q3 p8 z
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ! B9 R% j$ p' |: a5 c. [+ l. G
  79.                                 / s: @  ]- R. e; N- ^/ z* u* J8 Q
  80. Gamepad_0_State         =       Gamepad_Temp + 2, f4 J9 d! [8 s6 v) [
  81. Gamepad_1_State         =       Gamepad_0_State + 1  X# N3 _8 D6 R: M/ l9 Q+ H8 [, A
  82. Gamepad_0_Value         =       Gamepad_1_State + 1$ G5 G- d  V# L+ r* ~. T
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1  W, Z3 z5 \$ g4 L: q9 k* a. c7 P
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    $ z1 z* ]  A* z% f1 ~
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ! y) i+ Q' e( t: n

  86. ! b0 u5 m9 @: U; H' _! r; r
  87. ;==================================================
    , q( F0 h" O  q3 R/ P' t6 k
  88. IRQ_Index               =       Gamepad_Merge + $01$ S5 }& }) h0 ~! c% _: H' c, _
  89. ;==================================================: d  t* S. f: A% f3 J# O. i

  90. # f9 ]6 N- i8 q/ u
  91. ;CHR图形数据* a* v4 g+ h6 l8 p0 `+ E4 d
  92. ;==================================================
    . ?5 x: ?5 g# O7 V# f8 n) ~
  93. .BANK CHR_DATA_BANK
    4 S* s' n8 N0 s" ~
  94. .INCBIN "chr_bank/chr_data.chr"
    ' V$ f( y( `3 `) u) |) H4 X, v
  95. : A; T6 j# ^3 Q. J8 f
  96. .BANK RESET_BANK & BANK_DATA_MASK* ]8 `& e" {- Z( F. N
  97. .ORG RESET_ADDR
    ( e' ?" K3 i; h# Q5 P9 G
  98. & Q- n" w; K; s+ T
  99. ;--------------------------------------------------$ @, M" R8 K$ H+ `- [
  100. Attributes_Data
    7 R7 x5 Q1 Z- `+ S, i
  101. ;命名表属性
    0 a: s* z* ^/ M3 J5 c! D, [6 D
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$005 Y7 U2 L( ~% _: n! R, Y
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA& K0 o% s1 b& E$ T" f: }
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    9 |$ E" ]( T5 K4 |& ~
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    1 @: K/ r8 |7 m8 r& X  W
  106. ;--------------------------------------------------" _6 b0 O5 |; T+ |" X9 g
  107. ;调色板数据+ e! z1 u2 d! z( N) m% `
  108. Palette_Data1 A. ^  S* _" e3 g
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    6 h  b" p  Z$ ^3 c4 W
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
      \% ~+ K3 H0 Z$ J8 T& Z, ^, \

  111. 1 X: a- Z) K6 I
  112. ;==================================================+ Q; Q; m4 F) i" g& g6 x8 B, R
  113. ;命名表初始化1 j1 }5 U5 ~3 X: H7 u; R' {
  114. Init_Name_Table2 x6 `( l* S& ]5 b, X
  115. LDA #$20
    6 M" z# `/ t0 t- }$ v8 i5 _  J
  116. STA PPU_ADDRESS) I" m7 C( j" Z$ C4 y
  117. LDA #$00
    / F4 W) G9 e% k
  118. STA PPU_ADDRESS
    $ X1 j: {" h  R" i( A1 n" V
  119. LDA #$00
    + w! ?5 R/ h/ p+ _! ]* F. Q
  120. LDY #$009 i) h+ B# g2 i' o+ I# ]" `
  121. LDX #$10) U) R& F! }* e; W( A" }
  122. Init_Name_Table_Write; G- ?, R8 u! T5 g  ^/ N
  123. STA PPU_DATA
    ' `+ ?6 Y5 K1 m$ S5 g; `9 i
  124. INY
    * g- q& V( b8 ]
  125. BNE Init_Name_Table_Write
    7 W) G1 D; }( q1 I7 c% u, I( H' D, V
  126. DEX7 L9 a) d' e1 R; g7 z
  127. BNE Init_Name_Table_Write& x4 Q8 `' Z$ j2 h  Z  e5 ^$ f
  128. RTS
    3 r5 k% I; Y6 {7 x$ a

  129. 4 f3 u: I. u2 q5 X
  130. ;==================================================7 Q) B( ^/ A" Y8 o$ E3 l
  131. ;调色板初始化
    2 f8 ]/ w( a! ]' I/ q8 x0 c# C- z
  132. Init_Palette
    9 r7 w; i- G8 a& }4 H3 L
  133. BIT PPU_STATUS
    : {% p0 @/ v2 `+ H0 k9 y) }6 l6 v& x
  134. LDA #$3F5 Q; F; S9 {/ L6 X9 h) V7 W2 _
  135. STA PPU_ADDRESS7 Z  \2 o3 D- w+ }: D; d4 M! M
  136. LDA #$004 N" Z( b4 O% U
  137. STA PPU_ADDRESS
    ; |- L( R8 u' R
  138. LDX #$00) P# t, h& W/ s! [
  139. Init_Palette_Write
    8 }$ b8 P' d6 Z
  140. LDA Palette_Data,X# \  k# z9 Y2 K
  141. STA PPU_DATA
    4 t4 `2 z% g5 O: f3 H
  142. INX
    ! Y) _5 `: I3 h6 x
  143. CPX #$20
    , a. J- T% i6 L: r% V; `
  144. BCC Init_Palette_Write& j8 H) S, d. S: V0 R7 H" ]1 r
  145. RTS3 F2 I) j" I* \! t& }

  146. # K* S8 ]& g, j& \7 S
  147. ;==================================================0 ^) _2 y3 f0 k/ R6 Q$ b
  148. ;设置命名表属性3 K6 C6 ^* B5 O& @: [( o. J5 h
  149. Init_NameTable_Attributes
    : T. M! o  W+ `* V  e* d' K* ~
  150. BIT PPU_STATUS
    . b" ~1 [' K/ {$ ~
  151. LDA #$23
    2 u1 J- w1 l9 l
  152. STA PPU_ADDRESS
    4 c1 A2 |" m: g1 Z/ F, }
  153. LDA #$C0% p& f1 k7 ~. Y6 O
  154. STA PPU_ADDRESS# T$ H% @; q0 g/ t4 Y  D
  155. LDX #$00  ?$ d$ b5 W5 A
  156. Init_NameTable_Attributes_Write
    6 G% m4 g5 ^& t% B- [$ ]) s
  157. LDA Attributes_Data,X
    + M2 m& H' K/ K5 q
  158. STA PPU_DATA& b; w: H) [% l5 u$ y, _1 k
  159. INX
    1 v) [$ ]6 s/ q2 p- ]6 f7 I* c/ J% \
  160. CPX #$40% K& x. w' V0 `* c" e
  161. BCC Init_NameTable_Attributes_Write
    3 I3 K# G) `* O; r9 j
  162. RTS
    6 R" V( O, ^4 ]% Q
  163. 5 x2 V& F- _5 ?8 Z6 L
  164. ;==================================================" d8 x  f' I/ Z" i5 a
  165. ;初始化命名表文本
    / {0 V$ A, E7 M/ x. ~
  166. Init_Name_Table_Text; o- G  E9 Q" C) m+ r8 ]
  167. BIT PPU_STATUS
    # _. d' R% c. b8 O6 n: N
  168. LDA #$20
    # C( ~! o8 c  s9 u  d" x
  169. STA PPU_ADDRESS* a7 @" f& _+ S: _
  170. LDA #$00
    . w7 H6 g) N+ y( I
  171. STA PPU_ADDRESS
    5 d6 c/ {3 H) j; k8 ^: a
  172. LDA #$00: }. B. A7 Z0 V7 ^4 }- a+ V! o
  173. STA FC_Data_Buf
    5 T0 Y/ n6 Y1 a) I! g7 v
  174. LDY #30
    ) S- z' D; Q/ U; Y. `% n
  175. Init_Name_Table_Text_Write
    6 c6 M  B' u" E! w! u7 g) ]2 C0 q, K
  176. LDX #324 K0 A. l' A: d# l7 x- K4 T
  177. Init_Name_Table_Text_Write_Char% l) m7 T8 Z( ^4 x3 V) f
  178. LDA #'0'+ `( z" m8 S. `! w8 M) u7 D
  179. CLC
    - e7 {$ b; l& T# U* x% E# l. I+ x
  180. ADC FC_Data_Buf$ r& e4 C% ~3 ^8 H6 F7 E
  181. STA PPU_DATA
    2 ]' U" m1 Y' E, u
  182. DEX4 m! T! y! a! @: i% |
  183. LDA #$14
    ( f& V) u) S0 m/ g. V- b
  184. STA PPU_DATA% [8 Z0 V2 ]! i! |
  185. DEX/ F) V& P& x2 i" A& l7 X) A
  186. BNE Init_Name_Table_Text_Write_Char
    9 e. K" s# ^7 K
  187. INC FC_Data_Buf3 j' T# V$ e) }6 @. u, K. [5 Y& ]
  188. DEY
    $ L# \" \8 ^4 U; |
  189. BNE Init_Name_Table_Text_Write  J% W% E1 \, b! ?# i
  190. RTS
    $ r6 a1 n2 u+ @8 O

  191. * j3 x0 H" d" v% ~! i1 y( H4 x. n
  192. ;==============================2 `0 A( R' o  E# v
  193. Init_OAM_Ram;初始化精灵内存
    8 y8 r8 ~7 x3 M" z
  194. LDX #$00; U3 |: [+ `+ C
  195. LDA #$00" j, t/ ~. d: F- |  G
  196. STA PPU_OAM_ADDR
    $ O2 v" Y8 Q5 I- H' I: N, n
  197. LDA #$F8
    6 K0 N8 e7 a# |- v# J/ |6 f
  198. Init_OAM_Ram_Write
    ( |. h- E3 G2 Z7 b$ G3 z
  199. STA PPU_OAM_DATA6 s1 K9 S! L0 J' a5 c
  200. INX$ g1 K' x: F8 J' F3 R  W
  201. BNE Init_OAM_Ram_Write, `6 H9 E# b% ]# {
  202. RTS
    & x) r) h/ S9 F9 B* [
  203. 8 l8 ~; Y4 J. o
  204. GamepadProcess;手柄处理
    ' c5 D: P% s& i# ]
  205. JSR GamepadDatacan. D" k. X; V  Q
  206. LDA <Gamepad_0_Value
    0 H2 ^" m. n% g8 F: O
  207. STA <Gamepad_0_State6 j% @' W( Y& w; p+ C
  208. LDA <Gamepad_1_Value
      K/ s1 V6 t5 y8 E1 M6 P0 H
  209. STA <Gamepad_1_State
    * h4 I( J; i' E/ p4 v
  210. JSR GamepadDatacan
    : e) R6 C9 j3 f! H' V. Q+ E7 c
  211. LDX #$01
    ) Z% I% B. H3 d$ S/ L7 J4 w
  212. GamepadMergeCheck;合并手柄输入检查# ~; u3 J" I4 q+ Q- g0 d) z
  213. LDA <Gamepad_0_Value,X
    0 a2 ~. ], }* O4 N" f1 O
  214. CMP <Gamepad_0_State,X' f0 u5 P: t( B8 G: ]
  215. BEQ GamepadMergeInput
    6 J- f9 S' c1 K
  216. LDA <Gamepad_Temp,X
    : m5 I8 N9 h; H7 t
  217. STA <Gamepad_0_Value,X0 r8 `0 @7 j! @! y$ m; i* Y
  218. GamepadMergeInput;合并手柄输入$ H* a  i" ?  T$ s- ?
  219. DEX
    9 |& s; `- n1 c
  220. BPL GamepadMergeCheck8 q' t5 K3 B) I! B1 T& e. I
  221. LDA <Gamepad_Merge/ z2 O- _) z; J% x9 x, }& V' g
  222. AND #GAMEPAD_MERGE_FLAG" a1 D' c5 Z. @4 b3 k
  223. BNE GamepadStateProcess4 Z- @3 w' D$ T5 X
  224. LDA <Gamepad_0_Value2 s! E; s; c* F0 o0 \" t$ {1 _1 P
  225. ORA <Gamepad_1_Value
    $ m2 `0 `% d6 o4 v: r
  226. STA <Gamepad_0_Value+ G" l; g. Y4 X0 w4 N
  227. GamepadStateProcess;手柄状态处理, [! F0 n# G3 g5 F4 S
  228. LDX #$01" r3 M6 B: \! c- S" M
  229. GamepadStateSave;手柄状态保存) `# h0 c" _- i) f! d2 Z" a
  230. LDA <Gamepad_0_Value,X
    6 s1 B; r3 ^' i) R
  231. TAY
    / U& ^% H2 @! T
  232. EOR <Gamepad_Temp,X) u! E" y& c, \
  233. AND <Gamepad_0_Value,X  L2 ~  D' V9 L9 b1 u' O) {
  234. STA <Gamepad_Once,X
    * s! q3 y" V$ n0 H
  235. STY <Gamepad_Keep,X5 t& Z1 B+ B4 ^, ~
  236. STY <Gamepad_Temp,X3 N3 n- n& x2 p
  237. DEX
    ' T$ z$ l; ?  e
  238. BPL GamepadStateSave
    5 B, ?9 o" p3 i9 B8 A
  239. RTS; e+ `4 p2 i8 A2 N3 H+ G

  240. 4 z% F6 B; T) }* w) K$ q) T  `
  241. GamepadDatacan;手柄数据扫描
    7 U* L0 i3 h/ e4 ?& T
  242. LDX #$01
    ! ?' l+ `) z2 d( v
  243. STX $4016
    ; G+ Q' a) t" r8 j# c
  244. DEX( P* I+ t9 t7 x! Q6 N
  245. STX $4016
    6 r7 \) R5 I* `. U% T
  246. LDY #$08: Z1 D0 d& g7 }: x/ i0 e
  247. GamepadPortScan;手柄端口扫描" k8 b5 l1 T2 g
  248. LDA $4016
    2 `7 |& T: E; T. ]( R1 b8 y, ]9 C
  249. STA <Gamepad_Port_Value1 x- V' _0 n! C$ s  G2 S
  250. LSR A0 V* Z3 D% |* S$ \
  251. ORA <Gamepad_Port_Value% U7 T# u6 n3 Q9 E* j
  252. LSR A
    7 b) w7 e7 }0 G  z- ]. H1 ~% C7 D+ O
  253. ROL <Gamepad_0_Value
    ' B" r/ G# ]7 @; W9 T
  254. LDA $4017' q. Z% F$ {2 H( \( h1 w6 }
  255. STA <Gamepad_Port_Value
    6 j. X. P2 r- P9 i" H! k, m
  256. LSR A& P% p  k) F4 j  z9 C
  257. ORA <Gamepad_Port_Value
    * E  o  r; h7 ]! @' y0 Q
  258. LSR A
    3 R  ^  Q- b6 [; e
  259. ROL <Gamepad_1_Value0 [$ H5 K7 ?& R7 G8 ]& L: \7 p
  260. DEY
    ) P$ O$ h+ H. l2 |# O
  261. BNE GamepadPortScan
    ; Q$ w. a2 D5 \& J& @1 q
  262. RTS2 Q7 I4 Y& ~' q& K( Z* T$ [

  263. ) D! i! |* z$ A; s* x+ P( n+ v9 V8 [
  264. ;==================================================
    4 k4 e" [4 O: H  i5 s5 u
  265. ;PPU处理2 j$ D/ a% X$ f
  266. PPU_Process& n! z1 ]7 h3 j+ }5 O6 F$ m3 m
  267. LDA #$00
    ) D/ e# R% a4 }
  268. STA PPU_MASK' S$ C* [" b1 W
  269. 8 T. Q; e0 I% |" O3 H. G7 w4 n
  270. BIT PPU_STATUS2 W, N4 P4 D( C2 o1 Y$ Y# o$ s
  271. LDA #$20
    2 q5 `/ K9 k' d
  272. STA PPU_ADDRESS# `1 ?6 Q- u! ]& R
  273. LDA #$001 u; t  b3 q7 X+ \7 E+ l( k
  274. STA PPU_ADDRESS  K9 t# r( G- x3 W( G6 S
  275. - z5 f5 H; o" d; {2 W/ ?) D
  276. STA PPU_SCROLL/ y) T- ~2 y2 V7 ^/ d5 R
  277. STA PPU_SCROLL
    , N- l  O4 g! e3 V' _  \
  278. ; M5 {  |; ^) W
  279. LDA PPU_Msak_Buf
    # v; O0 o+ Z7 o& n1 Q0 i
  280. STA PPU_MASK
    2 U/ n. k) o2 O8 U* b2 o3 M
  281. 3 t  }5 Q7 W7 Z0 t
  282. RTS
    0 j1 Y8 g6 g. U

  283. 0 q5 O, ], e+ }$ E6 o/ ?! W# V- v
  284. ;==============================
    8 S- N  |* w# k3 E
  285. Time_For_Vblank;延时等待
    . V5 P5 I+ a" A$ e! Q) \- d; J! D
  286. LDA PPU_STATUS: ~; g/ j0 ?* V5 v, p, H
  287. BPL Time_For_Vblank
    / }1 ?8 ~  D) I; ?0 K6 f5 c; C4 r
  288. RTS
    $ l# H$ Y$ W. m

  289. 4 z2 c4 p: Q, o. ]( q3 H$ k1 l$ k' \7 D
  290. ;==============================0 q, M- c( W/ m# @. S, m3 \
  291. ;初始化MAPPER19
    : }. X: Z! ~9 e  S) K9 ?3 A
  292. Init_Mapper198 R( |! C0 H5 x3 a8 |/ D
  293. LDA #$001 K: h* e! |: D% ~) z  m
  294. STA M19_CHR_0000$ t0 g0 M+ K$ k; v- e4 `5 a
  295. LDA #$01
    ; X( b0 J. W/ y6 S& O" _
  296. STA M19_CHR_04004 b2 `- B! R0 q9 W2 V
  297. LDA #$02
    , L6 q6 P( l0 k" L/ P0 g2 x2 c
  298. STA M19_CHR_0800! I& x0 w( ]. N7 u
  299. LDA #$03
      |- V  F; _+ t& ]" H
  300. STA M19_CHR_0C00
    ! |/ B8 O$ N! ~3 Y7 j
  301. LDA #$04& t- Y2 e( }: f( Z9 D3 W
  302. STA M19_CHR_10002 l- u( e/ a" L% C. w7 M5 H  h
  303. LDA #$05& \' a& Y9 B' I$ _3 E" e. r) G+ @4 C
  304. STA M19_CHR_1400
    ; X8 N5 u( h" g+ ~: R: S# y' X
  305. LDA #$06) A+ f2 ^+ Y% p2 I1 E' l* h( \
  306. STA M19_CHR_1800
    # L  v+ o: s/ j
  307. LDA #$07  u0 q* k/ f! D/ Y
  308. STA M19_CHR_1C00$ i" E$ z: h% \6 K/ o4 I% T. H& b

  309. " T( u* k: M6 X1 v; j5 J" B2 e
  310. ;禁用IRQ/ Q( m$ j6 t9 p  `
  311. LDA M19_IRQ_COUNT_H% _6 ^* r3 `" p- n4 n* e
  312. AND #$7F
    ( E! I0 @+ z  ^, Y
  313. STA M19_IRQ_COUNT_H, _, u' A. t. ]

  314. , j5 m9 f& O2 C  y
  315. ;命名表
    $ Z1 N9 A4 i- a! g5 e; H- @
  316. LDA #$E04 L. R1 q+ V& T  v! c' O* H5 e
  317. STA M19_NT_2000
    ( n. K0 a; z( R, R& N0 b
  318. STA M19_NT_2400
    * @0 F+ X  J5 F- ]0 I
  319. 3 j7 ^2 J8 o; ]  p. T7 T
  320. ;命名表
    0 P3 _1 y  Z) O* e
  321. LDA #$E1# t& m6 r- v9 o4 @1 _
  322. STA M19_NT_28008 |) l1 R1 U% C* k. ^* [
  323. STA M19_NT_2C00% h$ {* \$ C, I! \- d+ l: x
  324. % E; W0 B* f+ s) s  O9 X- W* i" E7 E4 G
  325. RTS$ G* p, _: Z/ q2 p7 ]

  326. 7 @' n7 h8 v- u% G- r* i2 D
  327. ;==================================================3 V' S- c+ ~0 |% v6 f2 `; X+ ~5 u, m
  328. ;重置中断处理
      e) S, O5 _! x9 t& }% U
  329. ResetProgram# a% `& D+ k% R
  330. SEI
    1 K& P0 j6 K: s( x/ `
  331. CLD
    ; M" Q) U6 z3 [; e1 ]  n
  332. LDA #$00. @6 Y; z1 T0 T3 _  w7 y& {7 }/ H
  333. STA PPU_CTRL; b. ~& W. E+ r: G, \
  334. STA PPU_MASK- C: |9 p( C$ O
  335. STA PPU_STATUS" c6 o; Z5 v: m  r1 K
  336. STA JOY2_FRAME
    2 W% _8 J- C1 e8 _+ u
  337. STA APU_STATUS9 M$ p" Z9 q. n

  338. 9 J# i# [1 F- [7 }0 f) w7 R2 R% i
  339. LDA #$C0
    & z  \: O7 ~: W8 }
  340. STA JOY2_FRAME: K* M7 D9 U$ ~; e7 j. T3 o* ]% A

  341. , i/ a/ e+ }0 |, c* j
  342. ;等待vblank9 F" Z+ L0 _) P- D  l, [7 N$ Y* G
  343. LDX #$029 Z* v- r& G4 x. ^
  344. Vblank_Wait_15 i/ a" x( I( a4 P$ _* ^
  345. BIT PPU_STATUS
    9 o* I8 H# }: t$ Y. e
  346. BPL Vblank_Wait_1
    ( A! m% n4 ~. W! h. V
  347. Vblank_Wait_2- O' `+ l. \, |! k4 r" K
  348. BIT PPU_STATUS
    6 D# g- n3 U2 u' z( V9 {
  349. BMI Vblank_Wait_20 {, P8 W$ f# w6 ^9 t
  350. DEX! f; i7 p& @4 b; D" g. L
  351. BNE Vblank_Wait_1' [4 O) Y. [+ q# [5 r

  352. - m% l  m" H# N" w& ]: ?% K4 K1 v
  353. LDX #$FF
    * q8 {0 R7 m) x  w1 l$ g
  354. TXS
    8 ~6 x+ \% Z- {
  355. 5 r2 I5 \. y* Z
  356. ;初始化MAPPER19- P7 c* K' @6 V
  357. JSR Init_Mapper19
    1 M4 ?) I$ C3 d! }8 U
  358. . ~; Y8 }" [/ W/ C/ B$ a/ i
  359. ;==============================
    , m0 E7 f& |& h
  360. ;RAM初始化+ a: {( L! t/ c) o
  361. Nes_Ram_Init
    ! m2 k( K- j1 z
  362. LDY #$00
    & f* n& }/ p" x4 ~8 o, H
  363. LDX #$08& ]& s. a9 U* @: P
  364. LDA #$006 F: _7 M- G: Y# ?9 [7 b& a
  365. STA <$00
    ( k2 ?% B1 d4 n5 h: V1 e
  366. STA <$012 X! U4 A- i. x$ P
  367. Nes_Ram_Init_Write
    9 P  r- x1 K" e) M/ g; d! E
  368. STA [$00],Y/ z. W; g9 d/ ?, P& w. z: p
  369. INY" {: u+ W" @) R0 M: k$ ^
  370. BNE Nes_Ram_Init_Write
    3 p( b, m! }5 ?% P# O" s+ U1 y
  371. INC <$01, T) ~. d" r9 I$ Y3 q/ w  J  L
  372. DEX5 a% o. d6 x  U+ D+ e9 u# W  A
  373. BNE Nes_Ram_Init_Write1 v/ |0 n5 ]: i# m- `, L- y+ P
  374. % P$ q9 g0 x1 l- B+ _
  375. ;初始化命名表
    2 y  b9 C5 _+ w# P
  376. JSR Init_Name_Table, i0 Q, c: [* ?* L3 D* w

  377. " u4 s5 D: I8 z4 I  s
  378. ;初始化调色板# g+ i$ o" m1 D; N
  379. JSR Init_Palette
    1 L) @' D4 O9 ]' Y$ h2 C
  380. / ?. s! R6 U3 t5 N
  381. ;初始化命名表属性
    ( }  T- ?, D7 I! A' U1 T& d
  382. JSR Init_NameTable_Attributes
    & f1 `9 J; V: ^$ T, V

  383. ' w3 l1 B& ^, y! K% H) s
  384. ;初始化精灵内存
    ( H+ O  V/ x" ^: p) R0 c
  385. JSR Init_OAM_Ram9 W4 Z1 E. D* w& T4 x7 J
  386. & A- A1 |9 h  P
  387. ;在屏幕上写点东西0 H$ s5 Y. r) c5 |- O1 L
  388. JSR Init_Name_Table_Text
    " W4 `! e7 P3 o

  389. * P) a  s2 `" ?! t! y
  390. JSR Time_For_Vblank
    5 \% O; J+ R. I( C
  391. ;开启PPU控制9 Q6 ]; w8 a& R, i$ {4 W( }% i
  392. LDA #$A8* c+ J! y; X+ i  f6 }3 y
  393. STA PPU_Ctrl_Buf
    # v. U. g. x  a# v6 o) K6 E. |8 h- U
  394. STA PPU_CTRL
    4 r$ T( L2 S' g" V( D/ S
  395. 0 O) n- Y0 O" @+ U
  396. ;开启PPU显示9 h# Q0 Z9 }& l( K+ c8 m
  397. LDA #$1E
    4 Z  x& C; V* o; G* z# k& }
  398. STA PPU_Msak_Buf% h- |  S$ `4 N9 u- V
  399. 0 r. _% L; W; x
  400. CLI2 w9 N: {+ `2 z/ E6 e
  401. JMP Loop  I$ Q% x! _, S$ a
  402. % D9 p, q9 x% c4 s+ t- W$ \
  403. ;==============================
    # f7 v7 {* S& Y2 L2 T1 t
  404. ;死循环, 等待NMI中断
    & F0 I1 r( R- f4 `/ O: Q
  405. Loop
    ' j- D, X+ H+ G! X" ?
  406. JMP Loop
    & K  @! @1 k' b2 D8 J# t5 R
  407. 7 Y6 @* x1 T4 {+ o
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    0 _5 i' {* ?, j4 c

  409. ) Z* l4 [3 \! @1 b
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)7 T& \1 C; p/ }5 M# m, Z+ ^
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    - S: Y( B6 O8 i% p7 J
  412. ;==================================================
    + R7 `6 {0 L: o" w
  413. ;NMI中断处理! Z/ g2 D$ n! Y4 [- T0 [
  414. NmiProgram
    - n5 K& ~5 ~9 S. g; R) @% r
  415. PHA
    $ P' \% u3 {% W: G
  416. TXA( Z( u6 S5 n" b
  417. PHA& _6 d# p. g% p
  418. TYA
    ' _3 {5 ^0 C, b1 A% G' P! ?
  419. PHA' q3 g2 y, E- p* f* o
  420. # Q( V9 V1 p3 b; b
  421. BIT PPU_STATUS
    . d7 _8 D: @! k8 U. [
  422. ; z& Q+ [7 f0 M( @
  423. LDA #$00
    . |; Q& r0 ~* N) Z: @( L
  424. STA IRQ_Index5 {& f1 ?/ X* \/ D3 q
  425. # `  x2 G& J! U  O0 J# v
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    0 e' }0 |& S+ P5 I
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)! i. X' W% r( G4 J; V  `
  428. STA M19_IRQ_COUNT_L
    ! f5 D1 G  X* w; @  Q4 ?
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START): o- f/ }# `* r! |8 [+ k
  430. ORA #$80
    " g# k1 G1 M6 r- M
  431. STA M19_IRQ_COUNT_H
    6 a& v- D1 f8 r/ }: X- {! R
  432. CLI. l; n% T3 a  z: w: g$ l. L" G* f

  433. 3 h" v* s8 K' E
  434. ;关闭PPU控制
      P7 `0 N7 z* W9 X: c  j
  435. LDA #$003 u0 v4 o% M2 r" p) w* v
  436. STA PPU_CTRL' z& C3 W* _  w' j" Z0 [
  437. 3 {2 G4 P0 q6 `) T+ k. C
  438. ;处理PPU9 \/ r, z2 W( w5 L8 r
  439. JSR PPU_Process; T% C2 R9 k2 y& e, c/ J
  440. 0 z% O7 z! O* Z! \: L* W. M5 t
  441. ;开启PPU控制
    ! n2 K0 T5 O4 r
  442. LDA PPU_Ctrl_Buf5 ]8 a) A; \" |) d4 p- i5 A4 T  x
  443. STA PPU_CTRL7 n# Z. r& O* a0 T" ~3 z
  444. + m1 c8 R0 s! P. Q; ]
  445. ;手柄处理
    + W& a. v$ u* U) F  V+ b7 G7 `8 A
  446. JSR GamepadProcess& l0 J4 k/ p9 e4 K# F: G
  447. . ~5 K2 o# o0 }( ]& X1 b; \# E
  448. LDA #$00
    / T( \. x& n' J. i8 n' t
  449. STA IRQ_Index6 O) s( n; |0 Z: p) u2 t) ?9 l; ~
  450. 2 R- `1 w% [0 S$ N# x
  451. PLA  Q" C# b  y# H' n: F
  452. TAY
    : f( f, n9 J, S# }
  453. PLA
    5 T) D% e- K+ a( F8 f! I  j% G2 ~
  454. TAX) W3 ~' z/ S' w  o) d+ Z1 Z
  455. PLA
    ' v/ Q, b6 S+ ^# {' @1 j
  456. RTI
      K5 h  x- V% S: a( A: y
  457. $ K* ?4 |9 k$ j
  458. ;每行扫描线113.67
    * J( H8 M# \9 U" V% P. a  @/ L9 ~
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    5 x7 a$ O% C1 F" u) ?
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7, x$ B6 N' Z8 N$ f6 n/ g! Z
  461. ;==================================================
    % G2 A3 c2 M' b2 D0 ?
  462. ;IRQ中断处理
    0 {, J) e' Z. C$ F3 V7 [" C
  463. IrqProgram2 S2 S. ?$ N: R( U/ m
  464. PHA
    0 p1 l+ T% F* O! i& X# h6 k% f+ o
  465. TXA
    / A0 ]# O2 X# B5 O; J
  466. PHA
    / i6 F1 s) f8 Z# K, s
  467. TYA
    + q3 g4 z3 _! L
  468. PHA: R0 U  t! x: [. h. g+ p

  469. . x; v7 C7 [1 A: c; Z
  470. ;16条扫描线后触发IRQ' D: A9 c. h4 d, M
  471. LDA #LOW(BEGIN_LINE_CYCLES)2 w( I6 U# q/ c, N
  472. STA M19_IRQ_COUNT_L
    0 ?7 C% y7 R. `8 C+ W, t" G: ?) @
  473. LDA #HIGH(BEGIN_LINE_CYCLES)* I% a/ S# M$ d, R$ @/ h
  474. ORA #$80
    2 n8 h" P5 p# O- }. H3 b  e+ p
  475. STA M19_IRQ_COUNT_H: }6 _8 h1 ^. y6 W

  476. ( h- S4 B: i0 {4 k. K' a6 T& s
  477. LDA <IRQ_Index, N9 A1 w8 x0 `3 i9 q
  478. BNE * + 4
    ; H/ n$ W" {; S" I' H
  479. INC <PPU_Scroll_H
    / ~! x; I# |' Z3 J9 t  P
  480. 7 c: ^+ j" w* O3 ^, f% n
  481. ;设置屏幕滚动
    ! v& O- g. M0 r5 X
  482. LDA <IRQ_Index; i8 R9 ]& V4 w/ A
  483. AND #$01
    4 P2 r3 A& T+ k. n: N/ q: `
  484. BEQ Irq_Scroll_Right
    ' ]' f4 k# S0 |9 @- j$ P
  485. 4 C* w* p, T7 p9 B
  486. Irq_Scroll_Left8 ]% n* ?9 P) R9 m+ r( k8 j
  487. BIT PPU_STATUS
    5 I8 S6 V: [* z. b9 j% Z6 R' d
  488. LDA <PPU_Scroll_H0 K( |" Q: r/ ]0 ^) B
  489. STA PPU_SCROLL
    3 R" _1 ~1 J) d1 B, o  T. N* O! Q
  490. STA PPU_SCROLL
    2 n9 Y8 t3 ^1 Y9 c
  491. JMP Irq_Scroll_Over5 U9 X2 Y+ i  O' l- {; _. T$ ]
  492. ( f0 Y5 S) A2 m1 y2 w
  493. Irq_Scroll_Right( M# \! D1 k: k0 Q( C$ K
  494. SEC# Y3 v, p; d! ?
  495. SBC <PPU_Scroll_H( B2 x) u. d! [4 |/ t
  496. STA PPU_SCROLL
      B( q2 T# y5 |$ b/ `+ E  k
  497. STA PPU_SCROLL
    6 o  `% u; h% o) e9 M" Y
  498. Irq_Scroll_Over
    7 C3 B3 Q+ u1 }( A# U

  499. + R3 ?$ C! t$ L- k1 V/ Z! e1 a
  500. INC <IRQ_Index9 [4 A5 i$ _; F0 x- F  J; w8 b
  501. & D4 I/ ]9 J7 m3 R
  502. LDA <IRQ_Index* y# F( {" r) M- _
  503. CMP #14/ z* F% y0 @( U
  504. BCC * + 10
    - l" W) K$ w! _. Q7 ?0 I/ w4 M
  505. LDA #$00" d. L( y, h, r5 e- D
  506. STA M19_IRQ_COUNT_L! ~# S& K  y. T& `  ^
  507. STA M19_IRQ_COUNT_H- S1 y6 M+ o$ i+ y% D" z
  508. 8 a+ C  F3 ~; m* b2 F" M6 b* n
  509. IrqProgramEnd
    4 s8 f/ Y6 y3 K2 o0 Q
  510. PLA
    , `7 L- I9 S% b
  511. TAY9 M3 r# [* V) C( q4 `: e
  512. PLA
    9 T3 C5 H. ~% l, h) d7 `3 Y
  513. TAX
    " }: o( [# [- I; N
  514. PLA
    6 e$ k3 q* p+ A: l1 ^* u6 Y( r- w0 E
  515. RTI
    / j, F9 W8 k) A. ^; F, O
  516. / K' D& q: p- l: H* x
  517. ;==================================================
    * N( t& n! i2 k; o- F3 ~
  518. ;中断表1 N2 b1 \3 r) q/ t
  519. .ORG $FFFA
    % A: y" z2 ]( w5 @8 {
  520. .WORD NmiProgram% M( ^3 v0 m3 m% y% C
  521. .WORD ResetProgram
    & ]8 }6 j# r3 o/ n
  522. .WORD IrqProgram
复制代码
) |! L6 S1 V; n( H

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-6-26 03:46

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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