设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]$ M# g/ Y+ P9 k- E/ n# k  Y
  2. ;FlameCyclone 20230710
      N! v4 Q5 ~  S3 H' B

  3. # H3 ?6 q+ t" A) w5 X
  4. ;文件头: ^( X7 i; @* h/ F0 Y, v
  5. ;======================================================================% L! z1 H  P, [% B5 L2 p1 F# [0 X
  6. .INESPRG 4                                              ;16KB PRG 数量
    & |2 R+ w% {+ _/ @
  7. .INESCHR 1                                               ;8KB CHR 数量
    0 l) x) |8 f3 i! T6 a4 v; i
  8. .INESMAP 19                                                 ;mapper 19; p& \' l3 r+ R+ n
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    ) a, x! K& C! ^# h4 }" c/ [+ T
  10. 2 S+ m' x# O7 G, H9 {- v4 g
  11. ;必要条件
    9 r5 _0 b9 n2 I9 F& m; z
  12. ;1.持有CHR ROM- O0 ~( e& T# M
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    9 d9 D& e) y7 H* f
  14. ;3.精灵内存(OAM)不为空- k6 Z/ j) G) H6 b+ T+ z

  15. 4 B* a/ ]$ N9 c
  16. ;==================================================
    6 A6 w$ E' i- d# S' A, `
  17. ;NES端口常量5 I  J. d: X3 Q* D1 W* R) g* E2 K
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器% ?& t& [# E5 G9 f# N' O  X
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器8 |% a$ U* b/ g$ v) N+ J
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    * f& i7 \6 _& A6 _7 K7 h
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ' s6 h9 R; u( t4 R+ k
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    * H$ V/ N- _! A! f
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 : j2 h1 X) \: w$ t4 }6 ^
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加( B8 o3 ?+ m1 P! V/ d
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    ! F5 I0 b/ K+ e& m) ?
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存) o5 B0 P+ M6 \" |; S) B; B
  27. APU_STATUS              =   $4015   ;声音通道切换/ n% t$ s0 m- }
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通: z3 `$ i6 l! u
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通: e2 S* d+ {( N
  30. & m8 A( _# D) }& U$ S0 m7 \# m' t
  31. ;==================================================; |5 g9 }% ~* v5 r+ O; w6 \: u: [. J
  32. ;MAPPER 19端口常量
    . O  p5 ^: v% ~! G5 E- a5 Q2 X
  33. M19_CHR_0000    =   $8000
    8 I9 z2 C3 D2 O4 k
  34. M19_CHR_0400    =   $8800
    7 a1 l  f9 l# V% Q3 }; x% Z" _( G
  35. M19_CHR_0800    =   $90002 f1 C7 |# V9 q# f0 _" D7 C
  36. M19_CHR_0C00    =   $9800. {6 `/ v5 }+ T& y+ s9 Y, {" l8 n
  37. M19_CHR_1000    =   $A000
    0 s" u8 C$ x; {: r& a4 L
  38. M19_CHR_1400    =   $A800* o& M  L4 L, _8 a9 p
  39. M19_CHR_1800    =   $B000
    / T" X5 m8 N' d7 D( C- Q
  40. M19_CHR_1C00    =   $B8005 ]" ^: s# H6 f* a6 J: G) f
  41. M19_NT_2000     =   $C000
    0 T- k" T3 J4 _& r0 m
  42. M19_NT_2400     =   $C800; E1 T. i' D  _; W
  43. M19_NT_2800     =   $D000
    7 `7 d6 F) z3 j7 x- ?
  44. M19_NT_2C00     =   $D800
    1 f7 }, ~1 r; }* K; O4 G% ~
  45. M19_PRG_8000    =   $E000! W. K0 U! H4 _: ~
  46. M19_PRG_A000    =   $E800) G; {2 e. }# v% {) R
  47. M19_PRG_C000    =   $F000
    4 C" k3 a2 g3 J$ q  n5 s/ \
  48. M19_IRQ_COUNT_L =   $5000
    * O& L& ^+ V4 p7 Q$ V6 e( c; p
  49. M19_IRQ_COUNT_H =   $5800# t. o/ o  }6 \5 Y. I" ^: e" P
  50. + d4 q; v4 o( r9 o  g
  51. ;==================================================1 w; [3 l2 C3 Q( p; T
  52. ;程序块配置
    4 _% ]" Y6 D5 D
  53. BANK_DATA_MASK          = $07
    1 V- N+ C- l2 \4 m1 A# ~$ r
  54. ;--------------------------------------------------6 F, R) d& D& t$ l. b8 O
  55. RESET_BANK              = $073 m8 l# z+ ?" M2 f7 J4 ^: U
  56. RESET_ADDR              = $FC006 ~0 [+ @: w1 J/ w* q& Y  q. [% f
  57. " L& I, j( P% r9 r5 c
  58. ;==================================================% u. x2 b& _9 j0 ~+ x% q0 e
  59. ;图像块配置% H" S% Y# d$ s2 y
  60. CHR_DATA_BANK           = $08
    0 U; {1 t& u: y2 D1 w

  61. % S6 e4 `# ?4 @" j0 e2 L
  62. ;==================================================
    - {. J& P, c) \% L
  63. ;零页内存地址配置
    " Y% {' k& r1 J; t
  64. Use_Ram_Addr            = $80
    : i' _- v! g% h' b
  65. PPU_Ctrl_Buf            = Use_Ram_Addr( ?: Q! l2 C$ l3 n! @6 c
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    ) E1 @# c' e- f' B) l
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01/ N# M3 F* O+ T" o  \7 e/ L8 I# q1 C
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    3 _3 P  s' M: `
  69. FC_Data_L               = PPU_Scroll_V + $01( I! p2 _6 A8 M( h! S" l- l3 T
  70. FC_Data_H               = FC_Data_L + $01
    / \7 G) t  _4 g, }
  71. FC_Data_Buf             = FC_Data_H + $01
    ' v2 M; T. P4 Q# `
  72. ;==================================================) J% j: R# Z* e

  73. 9 ^) E" `9 R9 f
  74. GAMEPAD_MERGE_FLAG = $04
    ) z3 ^1 o6 M6 S, p/ d7 O
  75. 9 n- c& l4 M+ m2 a
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    $ g, u5 D& K, m* o0 i9 d
  77. Gamepad_Once            =       Gamepad_Keep + 2* U" B! }7 b0 o. y1 D
  78. Gamepad_Temp            =       Gamepad_Once + 2$ ~$ D# s0 E1 t0 j- k. V
  79.                                 : ~2 b3 E3 x7 |2 D. P
  80. Gamepad_0_State         =       Gamepad_Temp + 21 U+ f  N$ N! Q6 @/ X9 k
  81. Gamepad_1_State         =       Gamepad_0_State + 18 y9 q5 g. m! [6 m* |
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    4 @+ i3 Q" n$ y
  83. Gamepad_1_Value         =       Gamepad_0_Value + 15 C  m* X- _' \: M( m/ s
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1/ P4 P/ ^" C* K; B( \
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    3 `, d0 P: {; D8 L) o8 m7 J

  86. $ s1 K) b$ j$ y
  87. ;==================================================
    + v9 f7 W, M8 x' ~
  88. IRQ_Index               =       Gamepad_Merge + $010 A5 B* n1 e. C( ~, i) o1 a
  89. ;==================================================) b) f, i6 e" O. i8 m

  90. , @! C' i+ [/ d6 \. _
  91. ;CHR图形数据
    2 L" P9 {0 H. i0 t9 K( m5 ^4 l
  92. ;==================================================" N" Z; C9 k0 T  X& v" _
  93. .BANK CHR_DATA_BANK! u3 o' L- |) H% o! }, ?, ]: k
  94. .INCBIN "chr_bank/chr_data.chr"
    ' M$ s" B0 |$ o7 E4 J  T
  95. 2 Q3 |% [0 J! Y0 \5 \
  96. .BANK RESET_BANK & BANK_DATA_MASK/ c& q2 Y% W8 R* s. T
  97. .ORG RESET_ADDR
    ( W! }) K8 W7 P: S/ k) t2 S
  98. ( l. k' Y, S! _% `5 T( F
  99. ;--------------------------------------------------
    5 E  L+ H1 b8 F- n; u0 w, z0 F
  100. Attributes_Data8 r: m0 u  l* F
  101. ;命名表属性
      L8 m7 ?" F( y' O3 p
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    5 u9 ]4 r+ \. n1 c! P4 s% L
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA) S$ a3 {8 B; m1 P
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    . j: N2 R$ H- I/ m% z" W3 x: J; ~
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    : F0 u; ^6 W- s1 d4 B
  106. ;--------------------------------------------------3 P# H" Q1 Q) {2 X9 f* l
  107. ;调色板数据4 T3 c3 V$ y3 I% g' G4 \% n
  108. Palette_Data
    , _2 [5 @) y; ^4 t, }. d
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    $ A$ ~% c$ c" F7 m4 ^& Q9 }* W
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F& j. f' J/ {0 |; o0 |

  111. - o# Z8 E8 K* |' o) |2 I! G
  112. ;==================================================% R! @6 V$ M2 @7 N. |. W4 Z. b! p
  113. ;命名表初始化
    " j, D' C  d9 k: `) F7 W1 [- K
  114. Init_Name_Table  B, u4 [$ x! G) {0 a* |) x
  115. LDA #$202 o3 z$ S% s, e3 ?) a8 P5 b9 z
  116. STA PPU_ADDRESS
    1 J6 M1 f. y: ]& Z1 s7 H0 Z
  117. LDA #$00
    . o2 O$ c, Q: n9 x
  118. STA PPU_ADDRESS
    # P& [2 H/ L9 q  `
  119. LDA #$00
    3 m7 B1 z7 {9 P7 x/ I' m3 J
  120. LDY #$00& B' j5 z% \9 d, V# F8 D
  121. LDX #$10. Z# ?* v6 g& T# C
  122. Init_Name_Table_Write& h& J7 r$ U- _6 `( [! W; L+ R; R& T0 o. `
  123. STA PPU_DATA+ x4 P1 _( r# l5 N* i
  124. INY
    ' \. X& j! [4 ]0 b0 Q9 Y
  125. BNE Init_Name_Table_Write6 M# O' w" D- z9 N; P5 R
  126. DEX" K& g& G. z! e
  127. BNE Init_Name_Table_Write! y# G; q" h: Q
  128. RTS. z" W9 \. B  `

  129. / ~) i' u) e, |
  130. ;==================================================1 k- \) p7 T7 O" c. g( H
  131. ;调色板初始化
    " {9 p  u  n& b& W8 Q4 @" j
  132. Init_Palette9 L$ H# u( w! z4 i. u1 o; k
  133. BIT PPU_STATUS& x! }4 ^9 }4 Z4 ?5 [4 }( S! e% \9 k
  134. LDA #$3F
    / R) B  e. |/ {5 O  l
  135. STA PPU_ADDRESS& n4 Q- J# U: m( Y* ?' ?
  136. LDA #$00
    5 [! U+ A. {. T
  137. STA PPU_ADDRESS! F- a+ J/ T: d+ G0 M/ O7 q( [
  138. LDX #$00
    0 g' s3 l* C% t
  139. Init_Palette_Write; t: @% H  p7 O9 Q& Q
  140. LDA Palette_Data,X
    $ H+ m/ E$ b9 ~# h2 [  K" W
  141. STA PPU_DATA
    0 i. R5 M6 L+ P
  142. INX
    6 Y, w% t8 y. Z1 O5 }
  143. CPX #$20* }4 r3 ]3 g3 |1 h/ d
  144. BCC Init_Palette_Write3 ^& I1 _: k2 y: P+ T3 t8 H
  145. RTS: U$ O9 t  X$ \( B

  146. 6 Q* I: A6 @# N1 {3 y9 R$ b
  147. ;==================================================/ X4 u! e1 m+ i9 k0 W  u/ ?
  148. ;设置命名表属性' U$ S8 v/ e5 Y2 \$ u
  149. Init_NameTable_Attributes
    8 S7 N! [! q3 ^! _  l
  150. BIT PPU_STATUS- b% G2 s8 p7 R& \
  151. LDA #$23
    : u% K2 x0 h0 i$ |6 x0 ?+ t% Z3 R. h8 }
  152. STA PPU_ADDRESS
    6 _: I& a7 Y; k
  153. LDA #$C0
    # F; |2 u) H% h/ s( Q4 z
  154. STA PPU_ADDRESS
    # W- F& M% u$ u/ P
  155. LDX #$00
    : N$ O& m8 N0 Q% Z
  156. Init_NameTable_Attributes_Write; t7 _" C8 P2 A% Z% J
  157. LDA Attributes_Data,X
    ; k9 [* t) l: Z2 K9 ]( t9 g
  158. STA PPU_DATA$ l0 e1 o- ~2 U
  159. INX
    & m% p% A& n$ k# E
  160. CPX #$40
    + T& R! T0 Y: R: @
  161. BCC Init_NameTable_Attributes_Write
    4 o. I; G; n+ J
  162. RTS* X9 D. x# A3 ]; B$ V2 c( Q; g
  163. % {  M! C" f! k$ }1 @$ K
  164. ;==================================================
    * B" n% m# V/ G: f$ l+ Y
  165. ;初始化命名表文本
    % Y" C7 _' q  m1 w% j- Q' e
  166. Init_Name_Table_Text
    0 h8 D- L: _0 \$ y$ M: N
  167. BIT PPU_STATUS
    4 ^$ w2 j5 N, d8 {
  168. LDA #$20
    5 G/ q& X" z  e- [
  169. STA PPU_ADDRESS
    - L1 R! y' d# n6 S( D
  170. LDA #$00: F5 A1 V% @0 B2 ~9 v) V
  171. STA PPU_ADDRESS
    # s) r9 ^/ V6 Z9 {' j0 P7 P
  172. LDA #$006 b+ A, N  X$ l8 Y
  173. STA FC_Data_Buf& L5 C% g- `1 x. c
  174. LDY #309 a9 b0 z# D5 G% |
  175. Init_Name_Table_Text_Write2 B9 |' S3 l' E  u3 [& p$ y5 X) G
  176. LDX #32# l6 r' E1 e1 }3 J3 l' X$ n0 R0 n
  177. Init_Name_Table_Text_Write_Char8 K+ e2 \+ j- a6 T+ b3 i5 J! A+ M
  178. LDA #'0'1 d2 J. A9 b( ?* J: S
  179. CLC* `6 E9 j5 E" b; ~, i- O# _
  180. ADC FC_Data_Buf
    - @+ |+ c  u' I7 k0 r6 `# i$ n
  181. STA PPU_DATA, z" L" \6 `3 b" E: w7 l# R* C
  182. DEX
    / R8 r9 |' p* O- g, P
  183. LDA #$14* B% ?9 U4 u1 k6 A0 v8 [
  184. STA PPU_DATA
    ' u( W, y' ~( O( v" i' n% `/ Q
  185. DEX1 w4 U+ U* g" c3 J0 y
  186. BNE Init_Name_Table_Text_Write_Char0 k# ]2 x  B7 Q" o
  187. INC FC_Data_Buf/ d( G; L# q4 a# `. J
  188. DEY1 f9 k) ?& S+ @! ?/ B
  189. BNE Init_Name_Table_Text_Write
    ; P: O. N6 Y9 q$ n9 x, _& E
  190. RTS
    4 ~. x6 T) t  g6 e

  191. / o, @* |$ Y# L# d$ ~# E
  192. ;==============================
    2 @: x1 \& j" O3 [. l  p
  193. Init_OAM_Ram;初始化精灵内存
    8 w4 T: Q6 O4 l. G' T/ ]! J! H$ ?
  194. LDX #$00( k7 E: ?" D  o+ g$ n
  195. LDA #$00
    4 r1 f1 [; x" ~9 b% H2 d" ]1 M
  196. STA PPU_OAM_ADDR
    " R' s. D2 `* b8 @, B$ i' Y7 l
  197. LDA #$F8
    . O' D4 n3 {* [5 s7 M- q$ y. \0 C
  198. Init_OAM_Ram_Write- c" Q, T! [. N$ K8 ^( j
  199. STA PPU_OAM_DATA
    ' V, G) g( h1 p6 M1 m
  200. INX$ m- D" l& T0 t. {5 |
  201. BNE Init_OAM_Ram_Write% H% v' Y/ t3 f, h' G0 C5 Z
  202. RTS- v+ U1 d8 l: R3 _- x
  203. " e* ^# U) ?3 N, W$ n9 u
  204. GamepadProcess;手柄处理
    8 ]. u/ e4 @: z' m6 z. I& L
  205. JSR GamepadDatacan# f6 W& b" q$ v, o8 b
  206. LDA <Gamepad_0_Value8 d/ c7 p1 Z; H$ q& h
  207. STA <Gamepad_0_State+ H- Q; h$ q% ~) [% o" s' A
  208. LDA <Gamepad_1_Value# b8 y$ r  g3 v
  209. STA <Gamepad_1_State
    9 c- Y  C5 L& R( ^
  210. JSR GamepadDatacan
    8 Z6 L& ^1 W) h3 G4 g6 U6 d# h
  211. LDX #$01
    # u! V7 i( p( y- u; b3 E
  212. GamepadMergeCheck;合并手柄输入检查; W: a  V4 o1 L4 ^2 |4 J
  213. LDA <Gamepad_0_Value,X
    0 Z& n1 Q  V, E' ]% t( l
  214. CMP <Gamepad_0_State,X4 g5 U. P7 c- p; p, F2 R8 }
  215. BEQ GamepadMergeInput, T" _8 i' g: ]" s, S, d# D3 @
  216. LDA <Gamepad_Temp,X
    2 R$ y2 ~! Q' c, E4 U- \
  217. STA <Gamepad_0_Value,X0 }1 x1 d) D* |( ?6 u5 Z
  218. GamepadMergeInput;合并手柄输入
    ( [* z$ ]5 \% L+ M& j9 a, \. Z3 ~& \. T7 h
  219. DEX
    ! T. v5 P# [! M# K/ j, ]6 m
  220. BPL GamepadMergeCheck; Q5 X1 E4 G( Q6 U
  221. LDA <Gamepad_Merge
    , }1 x- v. h! S$ U, g8 Q1 A1 |$ p
  222. AND #GAMEPAD_MERGE_FLAG
    ( d5 U  l7 r1 `& w
  223. BNE GamepadStateProcess7 R& a2 o# n; b9 {1 Y
  224. LDA <Gamepad_0_Value( E$ C8 v2 Q7 E/ W
  225. ORA <Gamepad_1_Value3 U. J: w6 [, [* Z
  226. STA <Gamepad_0_Value
    7 P- S9 k# s( j3 _1 j' R
  227. GamepadStateProcess;手柄状态处理
    $ s, p) b/ \# p
  228. LDX #$01( F3 h/ U$ O- l9 d3 I, r% D
  229. GamepadStateSave;手柄状态保存' G, D9 w. `3 v7 N4 J
  230. LDA <Gamepad_0_Value,X
    ) @6 F9 {9 x$ C$ p! P+ n8 a8 n( i
  231. TAY. E7 ?  C' W. a" d0 T/ R
  232. EOR <Gamepad_Temp,X
    + M" R( X) T. V; x' n
  233. AND <Gamepad_0_Value,X* m" @7 O. U) N' a, [& h
  234. STA <Gamepad_Once,X5 E( `8 R# }2 e1 H; v  J7 \9 u. Y
  235. STY <Gamepad_Keep,X( @$ W: @7 d9 H% l* L
  236. STY <Gamepad_Temp,X. c+ U9 R5 f6 L* D3 E6 P5 q% h
  237. DEX$ J+ \* V0 s; d0 z) Q8 Z2 L: q
  238. BPL GamepadStateSave
    8 W6 m2 [9 N! V% j4 g9 I
  239. RTS7 w1 M3 g( h# Y. j
  240. 6 T4 ~# M3 B3 I" Y0 T
  241. GamepadDatacan;手柄数据扫描6 t$ j- r8 b' h) R# H% e& z1 ^4 P  b
  242. LDX #$01* O( z% J& c, F: K2 y! @/ z- }
  243. STX $40161 ]: P& [( `; ~2 }7 C1 u7 |" _
  244. DEX8 z  ?$ s  ^7 T; f1 P6 F/ f
  245. STX $4016
    7 ^& }1 X, y8 J+ c) i  v, T- U
  246. LDY #$089 g0 ?# f! L( Y. w
  247. GamepadPortScan;手柄端口扫描. t/ }9 h$ {! s' d" t
  248. LDA $4016( r" k8 Q( C# f% e! V- ^/ G* ]! B
  249. STA <Gamepad_Port_Value: u( K5 y2 I% F7 K+ m
  250. LSR A. G0 J8 P" e3 N. J
  251. ORA <Gamepad_Port_Value
    0 J  Y. e# w5 x
  252. LSR A3 \# m) V9 P: `9 h( ~
  253. ROL <Gamepad_0_Value
    5 A- h' N' Y$ O. g1 V
  254. LDA $4017
    ' n2 T' B, Y5 M7 n
  255. STA <Gamepad_Port_Value
    ; d* D8 Q) @: |9 N+ `
  256. LSR A
    9 ?7 k; V0 x9 @& G
  257. ORA <Gamepad_Port_Value) S/ ?# `7 w. h/ ]  W
  258. LSR A
    4 s8 d; e/ U  ]
  259. ROL <Gamepad_1_Value
    3 F: }: x3 [! z# b$ E
  260. DEY2 i$ r5 o& v2 U
  261. BNE GamepadPortScan1 m$ |* _9 \& L* p
  262. RTS4 j: L; N3 e* P+ K7 r

  263. " T1 U$ m, {+ O6 J9 I
  264. ;==================================================/ S4 D' b- b& c
  265. ;PPU处理& Z" d1 H  h' r0 N1 C! ]
  266. PPU_Process" J' I, @( o% G9 i
  267. LDA #$00
    9 m. X) A; F8 K7 g2 ~; h
  268. STA PPU_MASK" X) E& g- }' D' T+ E; u# J
  269. , D! K+ J( ~) r/ T. `% o
  270. BIT PPU_STATUS
    7 Z! S0 U1 B- ~" T
  271. LDA #$201 a' I+ Z4 c/ u3 Q& i
  272. STA PPU_ADDRESS/ G+ U& c, ]% l+ ~8 a! {2 ?2 G2 T* c
  273. LDA #$00
    * ?5 g1 [6 [# m3 W# B+ a3 p) m7 p
  274. STA PPU_ADDRESS) g3 u4 a1 N, U' P8 Z
  275. 8 S2 A" k- B: t  C1 y
  276. STA PPU_SCROLL0 G- Z" e" c( ?5 ?1 H0 z/ y
  277. STA PPU_SCROLL% \5 o  w$ M/ s% f1 K6 O/ ]" ]

  278.   ?; K9 {  U8 [2 h0 ?$ [
  279. LDA PPU_Msak_Buf6 l  q5 w& ?( S7 t
  280. STA PPU_MASK9 a( H. P" s* J( a

  281. / E. R) |- n+ D( w5 K
  282. RTS2 L' q7 p- q, k! O- Q9 E) E
  283. 6 p) U% w& j4 @8 S: F. {
  284. ;==============================2 k! O# p* D, p. N2 B# a- C
  285. Time_For_Vblank;延时等待, [5 R% _8 l  |7 {# c
  286. LDA PPU_STATUS7 u* n" [1 I) t* W
  287. BPL Time_For_Vblank3 p+ I# y% m0 N" L( f6 D8 M; _
  288. RTS8 U% e5 |% F4 }  M; N7 `
  289. 9 Y+ F9 Y! T3 S4 {( q3 x0 ?4 v
  290. ;==============================
    ) M" |, Q5 i0 z  b- W
  291. ;初始化MAPPER19$ j/ y, U7 ~( @  t$ i3 g
  292. Init_Mapper195 A5 Y9 s& Z( k, {2 C; E7 F2 a+ ~
  293. LDA #$00
    + ~+ r/ d0 S6 l6 I0 K: q
  294. STA M19_CHR_0000
    & {9 J' G/ y  B; I( e
  295. LDA #$01
    / K% _  M3 P' z$ M! N- i
  296. STA M19_CHR_04003 M8 G  C7 M( V, P5 |! b
  297. LDA #$02
    / U- i4 h" m1 q
  298. STA M19_CHR_0800
    3 r, \7 `! u' l) w( a1 Q
  299. LDA #$037 T' C# g4 Q4 ]- c# J: s
  300. STA M19_CHR_0C003 |0 c: ?0 ?+ c
  301. LDA #$04" t+ U+ G! o9 e8 U
  302. STA M19_CHR_1000) u0 t6 a6 x, }( P
  303. LDA #$05
    7 d5 s! G: }( j% F2 a1 Z* I: i
  304. STA M19_CHR_1400# h3 g! x/ ~8 F  z9 v% \
  305. LDA #$067 K  G9 R% i# [( z4 g
  306. STA M19_CHR_1800# J$ X  q2 I! _- Z3 }" w
  307. LDA #$078 S5 v. P8 t) y- U" g
  308. STA M19_CHR_1C00
      \/ K8 T1 w) i$ N5 y& m

  309. 4 h( q9 {8 z  s! c0 Q
  310. ;禁用IRQ
    ; W: C2 D& X. n, |& B6 h$ f- X
  311. LDA M19_IRQ_COUNT_H
    0 v3 X7 l0 o1 b$ l
  312. AND #$7F
    : f+ v9 }5 k' K& F% Q/ v9 E$ k3 U7 a
  313. STA M19_IRQ_COUNT_H
    8 k) q. f2 M& c( R

  314. & P3 O3 d( g3 B# b
  315. ;命名表/ B1 W9 B9 _' f( S7 C4 l
  316. LDA #$E0* O; d% ^# k+ i3 V& w" {7 ?
  317. STA M19_NT_2000
    4 o& `9 R$ b  l, {
  318. STA M19_NT_2400
    * F2 T1 x% n" }
  319. 4 N& f2 g, N; \( f
  320. ;命名表
    6 E0 T" l2 u0 }/ j: x
  321. LDA #$E1
    & K; D! ]1 O  @* Q. J
  322. STA M19_NT_2800# \2 k0 ~( o8 ]: e
  323. STA M19_NT_2C00
    / T; r/ u- [( {+ I( V# C0 c' ^
  324. 0 g* t; z' q7 F4 D1 u7 ?1 s
  325. RTS
    2 D% z0 r. k( D6 ~# V' ?
  326. 4 r# l! ~/ n) q8 J( H, l: J
  327. ;==================================================
    1 p4 w  O: y8 A" `4 z
  328. ;重置中断处理( e% `7 J* H0 j
  329. ResetProgram
    3 [3 ]" a# v# j1 {" F
  330. SEI2 T8 D- L0 o; j  l5 ~# F  `
  331. CLD
    " @% S4 A# Q/ G2 Y8 X/ i
  332. LDA #$00, A9 Q! }& C) v9 u: [( h
  333. STA PPU_CTRL
      w+ r! w( e% h5 Z/ e
  334. STA PPU_MASK# U0 l  G3 v- {( c- J2 o* Y3 K) n
  335. STA PPU_STATUS
    . H" e) c3 T2 ]7 m8 q
  336. STA JOY2_FRAME
    ' V* L, y% N+ h" q1 g) Y
  337. STA APU_STATUS
    % v* m3 |" w$ k& L
  338. ) E7 K( i& \3 ~) T3 E" e
  339. LDA #$C0
    0 t* [3 V3 Z- l1 T: M! r  F& ?
  340. STA JOY2_FRAME
    # M& K6 `9 t: ]: ]' x" z

  341. ( j5 n% T  o( i: I$ }
  342. ;等待vblank) l) d9 }9 \( m) Y$ \1 l( Q7 w0 w+ F# n/ k
  343. LDX #$02* N3 v- F' E0 r6 F- R* O, m
  344. Vblank_Wait_1
    ) O" M' L% N2 M
  345. BIT PPU_STATUS
    ! Y0 A& ~8 X7 U9 {* K4 ?) v
  346. BPL Vblank_Wait_1: `# @' R; S& }2 V/ ?% `7 B$ O
  347. Vblank_Wait_2% |) g2 G4 z: b+ i$ j0 W
  348. BIT PPU_STATUS  e7 B7 O; Z2 i/ v! P8 D
  349. BMI Vblank_Wait_2
    3 r$ ]; d- _4 a0 D0 `. w2 N
  350. DEX
    : o9 K+ q: E$ F
  351. BNE Vblank_Wait_1
      a% \' {- \% |2 H

  352. % D4 N0 B% O" B! S4 ^' ^, d6 \
  353. LDX #$FF
    * d! g, o5 T& X. k
  354. TXS
    9 x; ^' y. p' ^  T' F

  355. 7 p1 d  s# e2 k3 b! \
  356. ;初始化MAPPER19# D$ Q' R! b. u9 ]+ S4 m- O( K
  357. JSR Init_Mapper19! y" A, v( h, |, c+ L# x

  358. 4 e( @4 Z- f, N; G) N8 \$ f3 M$ A
  359. ;==============================2 F: l" J4 `( g5 i
  360. ;RAM初始化
    + q" V5 _% P2 b8 ^, w8 m5 Q, L
  361. Nes_Ram_Init+ p3 p" v$ `/ y) W; h9 i# c
  362. LDY #$00
    . ]  x8 n2 V+ b% x# f
  363. LDX #$083 {: m. g; N6 y/ s  t/ k! W
  364. LDA #$00; y+ N: b9 K5 B
  365. STA <$00
    / C, E  J6 o& D9 h
  366. STA <$01
    : g$ a# \* l. i3 K, k8 I, b
  367. Nes_Ram_Init_Write/ h- Y) C/ K6 X& U3 P) H
  368. STA [$00],Y# Q' q% m- U) \& S, _
  369. INY; }  |5 E: ]7 h0 B
  370. BNE Nes_Ram_Init_Write
    9 [  Y. o, g" D  p  b8 a! P7 e
  371. INC <$01
    3 F4 u/ \4 @1 F  Y
  372. DEX
    ; w3 h/ Z% `0 A6 [
  373. BNE Nes_Ram_Init_Write
    5 g3 _' o% i0 m& h2 _' u5 g

  374. , ]+ m! y% m2 M' [4 V( i
  375. ;初始化命名表5 c# G, j  A' P- i
  376. JSR Init_Name_Table3 m) H4 n4 A' F! g! N

  377. 9 D% r& [" @$ n7 n5 }3 |
  378. ;初始化调色板# n8 o7 c  @2 N
  379. JSR Init_Palette9 N8 V  i* `& T+ ]1 p! p, G9 p

  380. : J- z0 M& `  R
  381. ;初始化命名表属性
    * @1 E4 [$ D7 p3 m5 H& `% _+ t% R8 ?
  382. JSR Init_NameTable_Attributes
    8 P6 F- p8 u1 C
  383. 9 f$ i3 V/ q$ v' v
  384. ;初始化精灵内存0 ]' f7 Y: l( O
  385. JSR Init_OAM_Ram. ]# W9 @2 [1 S5 ^/ c1 c
  386. 8 n; k7 s) Q2 N; L# Y
  387. ;在屏幕上写点东西4 z' G( k/ O/ ?' f+ {4 p, u
  388. JSR Init_Name_Table_Text
    $ r0 F- Y5 V* d4 r

  389. 3 U+ P3 `$ G# R0 q6 E
  390. JSR Time_For_Vblank% y' ?/ o  u& X! h" t" d% |
  391. ;开启PPU控制! L; u6 }! v$ v. ^8 h, [0 n
  392. LDA #$A87 r8 G' A: R8 `& |& ~- Y0 [5 U
  393. STA PPU_Ctrl_Buf
    5 v; r! \6 X/ }5 W( F" F5 d
  394. STA PPU_CTRL
    & ?3 L& b( O, |! {
  395.   J% O( v1 j1 `5 k! U/ _
  396. ;开启PPU显示
    4 A, J4 `6 F% \' O) W
  397. LDA #$1E3 A" p# R# Q$ C( U/ A$ c
  398. STA PPU_Msak_Buf
    ' q+ C+ s" t; w% j  `! z
  399. / J' x( w+ O: w; {
  400. CLI
    " [0 y' G/ o" l+ I8 ]/ x
  401. JMP Loop
    " z$ A" g4 ^% z( \5 h
  402. ' P& e7 [3 ~9 Q
  403. ;==============================6 k* @: R- G) [3 x: J6 h
  404. ;死循环, 等待NMI中断
    ' M+ O6 {8 U( g' M
  405. Loop
    : [% g/ F5 g' [7 n6 l
  406. JMP Loop# q5 J9 W; Q  l# Y  X' F0 o

  407. 2 q: \8 I, z$ Q4 m2 h& l$ [
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967& H# g- @# k: a8 v

  409. 8 o& \! ^. d0 n4 k8 S
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)& q2 @/ n! o) ~
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103): g# S) v! X' Y$ l5 z4 s
  412. ;==================================================1 [" a6 v0 e( ]% Z& K
  413. ;NMI中断处理$ q2 d) v2 g! Z/ @# K- ?* O0 Z" q
  414. NmiProgram: S  e6 ^' k$ L6 u' L7 y+ l
  415. PHA) U/ g0 A1 L, p+ R% [2 u3 o6 t
  416. TXA, I. o; I! O3 @2 o# _- J
  417. PHA
    . d7 n- T$ ~4 Z; K) O9 @3 _+ K' c
  418. TYA$ ?& o; ?1 ~, ~4 {) [/ W
  419. PHA
    $ p" L3 A7 F7 z; ~0 d, Q) ~

  420. 7 N- E# F# I5 h3 T! d& b4 s! j0 o' m
  421. BIT PPU_STATUS
    ( P1 d' b/ F* C- M
  422. 4 n3 j* B4 t: D
  423. LDA #$00
    6 C3 U6 L4 ^' J! f9 R4 {7 w* a: E
  424. STA IRQ_Index0 u1 e- ~2 T" d; M5 X7 H

  425. 6 i/ a: c3 ?6 J9 r5 J( L7 y/ ~
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动$ e  G7 v! ~" |
  427. LDA #LOW(BEGIN_LINE_CYCLES_START): B2 n* t) }; O! t) g
  428. STA M19_IRQ_COUNT_L
    * {# e% o* r6 i" g: A$ g
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    * V, `2 |; E+ ]! U3 e
  430. ORA #$80
    - d& }$ O( I& A7 N+ v4 O
  431. STA M19_IRQ_COUNT_H' C! M8 k8 O: x$ \- G3 I+ l
  432. CLI
    ! J! D" ?5 E: @2 q# L

  433. . v* s/ E  ~" D& N% F7 K
  434. ;关闭PPU控制# M7 C+ H6 n( \% t
  435. LDA #$00, |/ n3 X3 `5 ?
  436. STA PPU_CTRL
      Q5 @$ Q5 `" g1 P: r* n% F

  437. 3 G& o/ G/ \! ?6 L
  438. ;处理PPU. K$ N( O5 o1 A5 C# T* P7 B
  439. JSR PPU_Process# W) x  p2 r; E  \$ c) h) p- P
  440. # c# M& y% }2 S/ @% \6 D
  441. ;开启PPU控制
    9 m3 g6 y* [- I
  442. LDA PPU_Ctrl_Buf
    0 n: B  k, e. y- R5 l, K5 d, T
  443. STA PPU_CTRL9 Z3 G3 _+ `  ~2 f3 v3 a

  444. 6 t4 L* ]! O2 [
  445. ;手柄处理) n! x& m  E3 `% A9 P" v& I6 _
  446. JSR GamepadProcess
      F1 t: |+ w: j3 K' `* g* g, {) L

  447.   q5 _" X% `6 F' f
  448. LDA #$00! B8 ~8 [* y2 B, u9 c9 K
  449. STA IRQ_Index
    * W" d6 n; ]- O: X8 E" R! u* N

  450. , a) C: P/ e3 i. O
  451. PLA
    1 ~4 m. Q& a( @+ X, w- T
  452. TAY
    : N+ d' c+ {5 v% u
  453. PLA
    1 x+ J% }2 s* R) L  W. t/ M
  454. TAX
    9 ^1 _4 Q4 q0 f- m4 s# i
  455. PLA6 ?2 V$ v1 Y0 u0 ?
  456. RTI* S/ d4 @" C4 z7 [$ W: k, T& w
  457. % {2 L& T4 N. ?# a
  458. ;每行扫描线113.67
    ) l6 q$ ^! z0 W$ Z6 A  \
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
      S. y$ k7 C3 h% g! Q6 s
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    & L% [5 T+ a* f; G
  461. ;==================================================: l/ s9 `: B" p8 I+ w1 p2 j
  462. ;IRQ中断处理
    * }' ~; g- S% g0 s0 }
  463. IrqProgram
    " Y8 J  h/ ?7 {2 i; n3 S
  464. PHA: t% P# i' u& M
  465. TXA) n! i$ A. e: G& Q2 H0 V
  466. PHA
    & {, W' Y" b: l& y
  467. TYA& {3 t; B$ F7 I8 o! R" y
  468. PHA- B7 F  U; o/ {; [
  469. + v% r9 s5 |- c0 Z2 d- w6 a
  470. ;16条扫描线后触发IRQ4 W+ }* _' d  I6 q; \+ q& ?
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    8 [+ o1 D' s6 I8 [
  472. STA M19_IRQ_COUNT_L
    " O1 L% X0 D6 V& @/ s
  473. LDA #HIGH(BEGIN_LINE_CYCLES)9 h( J* ]* n& S! c
  474. ORA #$80
      ~7 [' A# {$ {
  475. STA M19_IRQ_COUNT_H
    ; ]6 x3 ~" P2 l7 J

  476. 3 z8 v$ u1 `  b- ~2 I% |  H. J
  477. LDA <IRQ_Index
    ' g4 B( }" E7 [, S
  478. BNE * + 4$ M9 J6 F" g3 s
  479. INC <PPU_Scroll_H2 a4 k- O( J* ]- D7 E5 F' ~7 F
  480. " Y( g9 D" i8 E& Q7 [
  481. ;设置屏幕滚动! z  B' s! E# q" c" S
  482. LDA <IRQ_Index3 |+ `4 D) p( L' ~- m
  483. AND #$01) H/ O* N$ R4 {/ J
  484. BEQ Irq_Scroll_Right& B2 C6 L7 V5 t' Y- m" z5 Z+ }" g

  485. $ j  U% s8 F* c3 {; ^! g
  486. Irq_Scroll_Left1 h; X$ T1 R1 j$ k9 ]8 b4 ?
  487. BIT PPU_STATUS
    ; k& u5 M# W* a$ Q! Q
  488. LDA <PPU_Scroll_H
    0 @; n2 e9 _* N% `  M1 w# u
  489. STA PPU_SCROLL
    ! ^8 U5 G! B7 g- G
  490. STA PPU_SCROLL) n+ r: Z+ C$ c& i4 l% O: j; D1 P- i. a
  491. JMP Irq_Scroll_Over
    8 L% h+ j! s: q
  492. $ P6 C. F2 t6 ^, z' W5 d5 Q. k
  493. Irq_Scroll_Right
    6 W7 B+ j- `: A5 S' z4 R: g
  494. SEC
    3 T1 C4 F# C0 ~( w; d( ?
  495. SBC <PPU_Scroll_H/ p5 I8 E( b, t: L
  496. STA PPU_SCROLL% ~+ r: a( T" E# S4 b
  497. STA PPU_SCROLL
    % B& i3 H1 y3 @$ F5 y
  498. Irq_Scroll_Over: N! j$ V1 h; [7 u
  499. , y4 E+ y) G# ]( Q; Q
  500. INC <IRQ_Index% |* M) S7 @  w, i& P' `

  501. % ~: M9 D4 J$ _6 b$ f# T
  502. LDA <IRQ_Index
    8 n" O+ [) m4 s8 q$ _; G$ W
  503. CMP #14
    # {$ ^- ?; C8 @: ?# ^
  504. BCC * + 10
    ; E: F% e) y9 W5 f, y
  505. LDA #$00
    3 z* _+ }* Q- S# [* }
  506. STA M19_IRQ_COUNT_L
    : ^9 s1 M$ n+ X1 D" z: V( }+ j; X
  507. STA M19_IRQ_COUNT_H8 _9 A! Y+ x7 y# z; F  z

  508. 7 X( Y. d' f; N4 V
  509. IrqProgramEnd
    & F, U7 t2 x- ^+ v
  510. PLA
    6 J$ S2 y8 n" e6 p9 i- z; B
  511. TAY
    % U0 s: J7 D' n+ b( f
  512. PLA5 ?: Q' Y: k- J) `9 Z. f; I# v- S! K3 q
  513. TAX9 s7 R/ }% k/ s% V
  514. PLA1 G3 k. t+ E6 o7 Z
  515. RTI
    2 \# z: }# S1 @, i; @

  516. 0 ]! V  _! k+ `5 L: x; o. v4 g: v5 w
  517. ;==================================================
    + _! J7 P/ ?5 c. z
  518. ;中断表1 H6 S4 o" W1 ?: b6 f( l$ B( o
  519. .ORG $FFFA
    + [2 v) S+ E6 [5 ?' Z/ c
  520. .WORD NmiProgram
    + i4 s( D) {- B" F1 u
  521. .WORD ResetProgram
    3 Z8 P3 N8 |# @
  522. .WORD IrqProgram
复制代码
  R) j# q' ~: `4 h5 k( o

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-4-6 10:01

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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