EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    0 p# v, V+ l! \! ^
  2. ;FlameCyclone 20230710$ I: X% I! \2 B$ p3 y, U

  3. ! g4 y7 S8 d; W1 p6 `0 ]& Y
  4. ;文件头& C  H: F( C0 W. E8 W
  5. ;======================================================================
    ' h* [# R4 F9 x- C" N8 G
  6. .INESPRG 4                                              ;16KB PRG 数量
    ; i! E6 }. Y0 B
  7. .INESCHR 1                                               ;8KB CHR 数量
    9 [& Q. B+ k4 m1 P
  8. .INESMAP 19                                                 ;mapper 19
    3 ^  G4 {3 Q0 ]+ x& k; y- q# [
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    + O! H0 [( ]# l  A' j5 h
  10. 2 y' P! ^8 n. T7 n; \7 `
  11. ;必要条件0 @2 M$ K8 e  g8 J$ Y2 Z
  12. ;1.持有CHR ROM9 k# F3 _7 ]' ^$ W1 _
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000% r# P$ }1 m8 i0 F2 o3 A
  14. ;3.精灵内存(OAM)不为空$ j; a/ F7 i# X+ Y4 {$ w
  15. 5 j5 J9 u; G" @% ]% s
  16. ;==================================================- }! w; o8 s- s$ y2 Q+ ^" o9 G
  17. ;NES端口常量1 m2 w0 p5 w0 |
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器* V( z; U$ f( Y. f/ K
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ' z( `9 g1 A' r/ S5 y- r/ X1 @
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
      t! r& h0 ^3 h: L& R* t( ]& h3 k
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    * O# E8 _3 B! z7 }( H) B; r4 V
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加10 Z2 B8 r. y! o, t
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ; x$ w" }4 }9 ]/ j0 K; j0 L1 [
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加1 s3 T4 K1 g/ {7 ^$ c. i1 d
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 3 [. |# R. y* Y" x
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    4 |' o/ M+ j  U
  27. APU_STATUS              =   $4015   ;声音通道切换
    6 q5 k; m6 @* k0 \& p9 M7 H
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    ; b' f# F' ^" G  R
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    & H7 l$ {: J# I" j+ w
  30. ' x. q( _3 O* A( K+ D5 X* f
  31. ;==================================================
    ! n, `; p7 F3 z- S2 A! q1 w
  32. ;MAPPER 19端口常量
    4 \7 ~5 N" e( ~
  33. M19_CHR_0000    =   $8000' Z3 V" C' }- h0 N* W! ~! P
  34. M19_CHR_0400    =   $8800
    1 @; R# \& S0 {( d# E/ n
  35. M19_CHR_0800    =   $9000
    1 r8 X, H/ y8 K- w7 X# i
  36. M19_CHR_0C00    =   $9800& g8 L4 T# D! ^0 U
  37. M19_CHR_1000    =   $A000
    ( f# W% w% Z) C( K
  38. M19_CHR_1400    =   $A800
    + C$ F+ R' l% m6 T* ^5 N
  39. M19_CHR_1800    =   $B000/ d& s# L' V, E, ?
  40. M19_CHR_1C00    =   $B800  M4 l- w$ |. g8 ^
  41. M19_NT_2000     =   $C000
    $ A* _* h7 b. X1 c, a( j7 ^
  42. M19_NT_2400     =   $C8000 f/ }4 v2 F" c! Y
  43. M19_NT_2800     =   $D000
    $ _% v8 ]1 u& F1 S
  44. M19_NT_2C00     =   $D800
    # i& e( y# c: y# {7 E
  45. M19_PRG_8000    =   $E0005 _) _- R& K# `* e% _: l
  46. M19_PRG_A000    =   $E800+ k0 u" _4 I9 M, M, f5 R& d5 A1 w
  47. M19_PRG_C000    =   $F0008 _; o* G1 s) O. a
  48. M19_IRQ_COUNT_L =   $50002 Z5 A: f$ B! M8 P5 w- Y/ z, b
  49. M19_IRQ_COUNT_H =   $5800) q. n0 \, B& Q
  50. ( |2 m* y4 \% P" x& a0 a
  51. ;==================================================
    ; m  ^, k% x1 L) n6 T) J
  52. ;程序块配置& V6 w: F+ F4 H
  53. BANK_DATA_MASK          = $07( E$ q* w  x, I' i, |2 ~; u! P
  54. ;--------------------------------------------------
    / a" l; j/ S, I5 N5 I0 f' u8 E/ u
  55. RESET_BANK              = $07
    / _% F% P" E7 w! h# L: L9 _3 F, f5 j
  56. RESET_ADDR              = $FC00" B" e* ^( B, |0 X8 O
  57. 0 ?0 r. j8 w5 b; a, W
  58. ;==================================================% B- ~; J% M( k
  59. ;图像块配置
    9 W" K7 e( E/ U! z* X' F, T
  60. CHR_DATA_BANK           = $08
    / R% s6 i1 h& V) [1 \
  61. " u8 N* t; {4 d5 k5 F- u- N& K
  62. ;==================================================/ n( k4 W, ^. _% O
  63. ;零页内存地址配置& M5 q( W. i5 K% I( `
  64. Use_Ram_Addr            = $809 l8 v. |/ ^; w: Q9 ]5 E
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    6 I' Y2 k9 ^/ H+ b% e
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01+ R/ J$ |! M$ }3 s1 }5 l
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    ( [: K- y9 u9 q0 Q. K' J& W: U( X
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    2 m) T" X" k2 g; \4 o; w
  69. FC_Data_L               = PPU_Scroll_V + $018 ?  V% S5 x+ q8 K
  70. FC_Data_H               = FC_Data_L + $01( \. W9 V, O) }% L+ z% _2 O5 m
  71. FC_Data_Buf             = FC_Data_H + $018 q. i' n$ s3 w3 T8 s& V6 U6 `
  72. ;==================================================
    ) [* x% p# c" z1 |7 ]7 E

  73. $ K1 {! p  y0 m0 R( w. O+ [; x. {% @
  74. GAMEPAD_MERGE_FLAG = $04
    8 E4 L2 d" T  Y3 _! T

  75. , j* @4 U1 t' B7 x3 y6 O
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    ) L2 f0 _9 |7 L- K  z1 s4 m
  77. Gamepad_Once            =       Gamepad_Keep + 2
    + y# \8 X( J9 R7 \5 x, X1 h, K* J5 l
  78. Gamepad_Temp            =       Gamepad_Once + 2* g# p4 k1 X8 B3 d8 v# ~; d# y
  79.                                 
    / Q% B" R7 i- J, d8 @
  80. Gamepad_0_State         =       Gamepad_Temp + 2- T; ]5 O" k1 C$ `6 ]8 |
  81. Gamepad_1_State         =       Gamepad_0_State + 1* @1 c6 W; a, n- L  _. j
  82. Gamepad_0_Value         =       Gamepad_1_State + 1& G" }2 ~( q. @5 d  {! d
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    ; `" n9 _  Q4 F3 j" A
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1) t; U% p. V- h4 j9 g( L
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    9 t, D% E% u3 p$ g  _: x
  86. - @3 _, ^7 F9 c% ~2 g$ ^" |/ C: a
  87. ;==================================================4 Z0 c( t+ T3 F# N
  88. IRQ_Index               =       Gamepad_Merge + $01
    ' T: `2 }1 f) e8 v' V' g( {
  89. ;==================================================
    7 A7 w. n# y/ F9 P& C; J

  90. 4 |- H; A, s" |# O) u* p$ v: {
  91. ;CHR图形数据4 q4 G5 z1 R! t) L& `
  92. ;==================================================0 H2 f$ ]8 G8 e5 t2 ~8 S* ^
  93. .BANK CHR_DATA_BANK" s$ H0 f# ?/ ^' Q
  94. .INCBIN "chr_bank/chr_data.chr"
    ( _0 G& q* D, w: A

  95. , W- [6 M! F& I% A: q# F( h
  96. .BANK RESET_BANK & BANK_DATA_MASK
    , Y) |3 U6 H# o/ U1 m% Y
  97. .ORG RESET_ADDR* C6 e$ s% P( [, f4 d" i! E' n
  98. ; F5 ?7 U9 }  m  K0 A$ o, c: H
  99. ;--------------------------------------------------$ F9 F5 w1 i- H  p" x
  100. Attributes_Data, Y0 B6 G" ?+ M* ?
  101. ;命名表属性
    8 x! w1 R; T  Y8 i0 J+ w, o
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    ) `! b% `6 g7 p+ \
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    ) Q9 K# s! o& A# X+ a1 X! N* V
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA: i/ l$ l' ?, j- P
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$552 E( p% ]7 z1 Q
  106. ;--------------------------------------------------
    , q" n, ~6 u0 w4 C0 Z& g6 V$ D
  107. ;调色板数据7 Y" w+ P) E/ j7 k
  108. Palette_Data9 g+ [+ g  j$ W
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    . p& O& w7 S6 X+ X$ a
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 Y( _0 B, ^& j
  111. 5 J: p5 d% A' G. b
  112. ;==================================================7 d; H( n7 a) N/ a
  113. ;命名表初始化
    & ~. m  H8 o" E* R
  114. Init_Name_Table- @+ V/ W: G9 Q2 j( f
  115. LDA #$20$ Y7 u  o# u; Y: w! i& a
  116. STA PPU_ADDRESS
    / O* j1 W7 t0 {- V
  117. LDA #$00; l* R9 c! s$ Z7 j1 T% S" l0 \
  118. STA PPU_ADDRESS
    * f5 ^5 A$ V' I# O
  119. LDA #$00
    - J, |  m  D8 v9 h7 |+ X5 k
  120. LDY #$00% ]) K3 Z# |) T* ?) W
  121. LDX #$10: s8 ]2 m2 P- f8 `
  122. Init_Name_Table_Write
    / E3 l2 V2 j) w/ U; A& W  U; v7 r
  123. STA PPU_DATA% x+ i2 o8 I# _) c
  124. INY
    " A4 F% S; |( B  b" P! s
  125. BNE Init_Name_Table_Write
    : |, z7 R* D7 q0 T- i7 v* L7 r
  126. DEX: x4 t; M; w# w- Z0 I, K
  127. BNE Init_Name_Table_Write
    3 M0 ~7 b, F7 M' [0 K- @
  128. RTS& l, j, ]" p: D
  129. . y+ E, G! I2 L! `5 q. u2 Q& X
  130. ;==================================================# y% m- a0 Y( p! w0 Z1 L: _
  131. ;调色板初始化
    ' w& ^+ j9 Y5 \$ ~8 |7 a
  132. Init_Palette
    8 S7 k0 y3 E7 J1 K2 Y
  133. BIT PPU_STATUS
    ( h8 P4 X9 E- G3 s) w+ W, q
  134. LDA #$3F
    ( a4 V! C7 \1 q1 _' W( ^3 C
  135. STA PPU_ADDRESS
    8 |6 J3 f1 s( z
  136. LDA #$00
    / f! i( m0 y# S" ]0 Z0 ~$ j
  137. STA PPU_ADDRESS
    9 Y  C5 v7 J0 r* P/ f
  138. LDX #$00, J( s8 }3 m. i% P0 P7 ~6 v: V
  139. Init_Palette_Write
    7 s* u6 }' x- c% s; i
  140. LDA Palette_Data,X4 v: G: H+ L' n- W. W# V" u
  141. STA PPU_DATA
    1 H4 y" n9 [+ n+ _- o4 {8 V
  142. INX
    , Z0 y+ F( a! n% @# h, Z
  143. CPX #$20/ c  Q; ~: \  v1 z9 \
  144. BCC Init_Palette_Write. P: I& Y8 l9 M# f
  145. RTS( n6 t9 P8 A5 w- L3 x% X
  146. * f# c% Y0 V: R/ e
  147. ;==================================================
    " E. K9 U) P& a) ?3 o9 h/ }
  148. ;设置命名表属性
    ( c, c3 S! m3 }3 O+ p- |/ a# `
  149. Init_NameTable_Attributes
    , c0 @8 `3 E8 C& b
  150. BIT PPU_STATUS
    . E8 T- P2 w  W4 U" _
  151. LDA #$23) G5 P7 n) E0 l/ W) ?: i: i2 S9 a9 X
  152. STA PPU_ADDRESS1 U. u5 t' I0 L: t
  153. LDA #$C0
    # o; U6 j* X1 {. {
  154. STA PPU_ADDRESS  Z0 m  n  ?8 q' w. u4 b
  155. LDX #$00
    0 G5 Y! K2 w/ |, s- @8 [
  156. Init_NameTable_Attributes_Write% T, {6 b$ T' e/ i# D
  157. LDA Attributes_Data,X1 K( v  k8 b4 g& {6 E! L
  158. STA PPU_DATA
    : q8 e5 G' P/ z3 Q6 W! m- E4 y7 T
  159. INX
    2 V  w1 Q; ^7 N0 x! A
  160. CPX #$40
    " Y$ H/ I# _  @6 n) a9 r8 ?/ h6 p
  161. BCC Init_NameTable_Attributes_Write% ~, c+ t: i; [/ _2 k7 v; _  v
  162. RTS. P0 D/ ^* g( i" ^# D2 F

  163. ) x3 f; k5 Z2 S1 K5 J- Q6 w
  164. ;==================================================
    - h& c. i" W% v" o
  165. ;初始化命名表文本7 z! U% ~- E) b
  166. Init_Name_Table_Text, K0 W8 S! V/ }, t3 d' R
  167. BIT PPU_STATUS. @. ^9 u! G3 J/ c
  168. LDA #$20% x5 c( m2 P' D+ ~+ G" W
  169. STA PPU_ADDRESS
    5 b6 g( _' j7 t
  170. LDA #$00, X0 l. V: G+ ?2 k* O0 o
  171. STA PPU_ADDRESS: i" `  `' y6 U- e: Y/ [% U+ P. |
  172. LDA #$00+ I/ _& Y  V+ l8 {' h
  173. STA FC_Data_Buf
    0 |* h, f; Q2 B9 u9 D
  174. LDY #30
    ( b8 F" F8 E0 ?: f% q& J7 z
  175. Init_Name_Table_Text_Write1 u: |8 C( V% W8 J* ~. n
  176. LDX #32: S+ j; d8 i1 K
  177. Init_Name_Table_Text_Write_Char1 f, e# {: F+ y& n
  178. LDA #'0'
    4 m7 \- d5 h- \9 R& ]6 o  N2 O
  179. CLC
    0 r* ]. C+ P1 V* \/ x* Y' o( ?
  180. ADC FC_Data_Buf
    ( _: a9 k3 b1 d' E. P/ J% H, ^
  181. STA PPU_DATA
    * h7 A' V! D, w
  182. DEX# n& Z4 [4 n9 M) `& `- f0 W
  183. LDA #$142 c* }! _1 G% p; R3 U$ [  p
  184. STA PPU_DATA- J% s% d+ x% w' q3 H! D" ?# J
  185. DEX& n, b/ m3 L! I* ?# P: q
  186. BNE Init_Name_Table_Text_Write_Char
      K4 j* Y, f- V" a( j; n% O/ P' E. g
  187. INC FC_Data_Buf2 z( f0 r: {, \5 q
  188. DEY
    " @1 s/ A7 o: N! s6 x
  189. BNE Init_Name_Table_Text_Write
    ) ?' {4 x2 M" ~! o; `* `# D  X- i' k
  190. RTS
    2 H- [) E  q0 J, R3 m* V) G
  191. # N# L2 @1 e# X7 S. }7 _
  192. ;==============================; Q9 {, f" }6 |0 I) L% r1 R; ]: o
  193. Init_OAM_Ram;初始化精灵内存
    + L% W! V  V" ~5 s' N2 m
  194. LDX #$003 g! Z5 _2 [! ^* [5 e  [
  195. LDA #$00
    1 X* w" h( J. q$ m  k! |
  196. STA PPU_OAM_ADDR* J  k; u2 U$ k8 L8 A/ b7 z4 ^
  197. LDA #$F8( y8 L4 N, e& U, m8 r7 H
  198. Init_OAM_Ram_Write; s! J' G6 Y+ S
  199. STA PPU_OAM_DATA
    ! x( g7 ~' z- Q3 q
  200. INX
    % m! N5 y9 u) Z1 k+ e1 u
  201. BNE Init_OAM_Ram_Write
    7 W6 f! F$ ?. z( y+ _
  202. RTS
    & M3 y& ]5 y) S( r

  203. ) p4 p! h; M1 B) I
  204. GamepadProcess;手柄处理, `7 w, l! Z$ A! W
  205. JSR GamepadDatacan
    8 O, S0 ?! L; `( R
  206. LDA <Gamepad_0_Value5 ^* q) m  e" f3 q+ }
  207. STA <Gamepad_0_State3 x$ B  W: j8 F- ?" V5 f
  208. LDA <Gamepad_1_Value
    ' x, q/ i% y5 |. N6 b7 c
  209. STA <Gamepad_1_State/ T  F/ Z. i) Z  e
  210. JSR GamepadDatacan, d1 j# m& z3 _  s" v3 k
  211. LDX #$015 v# P& N( C, F3 @% m
  212. GamepadMergeCheck;合并手柄输入检查( k8 y9 X" h7 C& ^/ k
  213. LDA <Gamepad_0_Value,X
    . A) ]. Q1 ?: f' D. z. N
  214. CMP <Gamepad_0_State,X, J  ?. G6 Y" A+ b( p. N% y$ k
  215. BEQ GamepadMergeInput, Y3 b) f5 |4 \( w9 n
  216. LDA <Gamepad_Temp,X
    : h) H" C3 W+ b( ~# F
  217. STA <Gamepad_0_Value,X
    - W/ z) g) {. D! y% \+ }- K) l
  218. GamepadMergeInput;合并手柄输入, I) Z' u2 ~( Z& R! m. H& T
  219. DEX( H1 z& \+ I& Z6 D
  220. BPL GamepadMergeCheck9 d) j5 f0 a9 K/ x: v+ z1 ]# p6 }& l
  221. LDA <Gamepad_Merge
    9 b3 u" v& _) t
  222. AND #GAMEPAD_MERGE_FLAG/ [% L2 n" Q6 c
  223. BNE GamepadStateProcess
    : u* z/ p* N; m8 N7 m$ V; o
  224. LDA <Gamepad_0_Value/ i5 e9 x# ]0 E+ e
  225. ORA <Gamepad_1_Value
    : C6 v9 X8 b9 {/ \
  226. STA <Gamepad_0_Value1 g5 u/ p/ Q% ?- D
  227. GamepadStateProcess;手柄状态处理
    5 g, `' M" G4 D# w( J
  228. LDX #$01
    $ H3 _0 j9 J+ `& g
  229. GamepadStateSave;手柄状态保存
    " _& I5 a% l. o
  230. LDA <Gamepad_0_Value,X8 r" X; y/ ?" R5 f* ]
  231. TAY4 I9 Q" o% x& q; |% g
  232. EOR <Gamepad_Temp,X
    . |) o. ^4 g) B( S
  233. AND <Gamepad_0_Value,X9 A% e; G6 P/ C
  234. STA <Gamepad_Once,X
    ! I7 g' m" {; ]8 P1 q
  235. STY <Gamepad_Keep,X/ j; m* e" Y) A
  236. STY <Gamepad_Temp,X, |+ ~1 F( @' L* n% J. t5 l) y0 V
  237. DEX
    ! J! K8 {7 P/ x% C
  238. BPL GamepadStateSave0 s: J0 @- C# D, E5 A2 s/ n! Q
  239. RTS
    / g' u- Z/ J  F& F- @8 Y

  240.   c8 L2 a, |3 ]
  241. GamepadDatacan;手柄数据扫描
    - c) P1 w& g! ]9 K4 `  _. z; }
  242. LDX #$01
    . S3 p2 L) V/ T' V
  243. STX $4016, s% C; v/ O7 C3 P( q) x- T+ `! T
  244. DEX
    " U( ^/ q4 @: s) N! C
  245. STX $4016
    1 b9 W$ U4 Q& w7 |  f6 B8 K' k
  246. LDY #$086 E1 |/ m9 x8 M" D; j! m  L0 D
  247. GamepadPortScan;手柄端口扫描& K8 D% ?0 d# J5 z
  248. LDA $40160 p4 t$ d7 q% E) I; x
  249. STA <Gamepad_Port_Value. D* e' p' R" k
  250. LSR A
    5 T8 j2 S$ X5 s. ]( @0 E8 h; v
  251. ORA <Gamepad_Port_Value3 S) `( R' \7 r; |3 o8 L+ h
  252. LSR A
    % V, A7 q& i: H9 t1 \; g2 w( v
  253. ROL <Gamepad_0_Value5 E0 f  |8 i+ Z+ c3 X4 @5 H' J/ N
  254. LDA $4017
    ; p1 r. e  j; c& q# L
  255. STA <Gamepad_Port_Value  q+ F3 G6 ^. ]; |% R
  256. LSR A
    3 q" l7 g2 U; j+ ~5 i
  257. ORA <Gamepad_Port_Value
    1 g! \! F  U3 \; X4 u, M! ~
  258. LSR A
    : ^# O) `6 G2 E0 ^
  259. ROL <Gamepad_1_Value
    $ T$ c  m/ r  I3 c' E% [
  260. DEY
    1 E# K% J% c& [
  261. BNE GamepadPortScan* I! s8 F0 i% ]% b* {% f6 x
  262. RTS
    . ~  S7 f$ u2 k) F. T: h; B, `

  263. 1 w# P& |8 `3 _: b' z
  264. ;==================================================
    + ~( W* ?" Q+ _, ^
  265. ;PPU处理! t2 N7 X: e2 ^
  266. PPU_Process
    5 M; @( U  |# T: U7 b
  267. LDA #$002 \6 r- A: H( q7 Q- c0 k
  268. STA PPU_MASK
    ! x7 g, i3 N, T9 }, H  H. x, \- e9 {3 u

  269. 2 G( i. P0 v- i! N
  270. BIT PPU_STATUS
    2 I1 a( `; x# q% K: t
  271. LDA #$20
      \: m+ i: |( N& X$ C+ _$ k; N
  272. STA PPU_ADDRESS/ V7 Z( m& I* u* a' S! W
  273. LDA #$00; `- n7 a4 u1 V$ ^2 s
  274. STA PPU_ADDRESS+ s0 X, n, W; r9 {" z- p2 w

  275. ( y7 v' J  i) y  j/ V
  276. STA PPU_SCROLL' z* c$ k; L+ ?! x, P( ^& Z
  277. STA PPU_SCROLL
    ' }: ?& I" O0 N" `

  278. 3 L) C# q* l- Y, u" D
  279. LDA PPU_Msak_Buf! h7 Z% n2 d( I- u* }
  280. STA PPU_MASK
    # z" c7 c0 N3 ?
  281. 1 u. @. o9 X- j. `
  282. RTS
    ' c4 _% s8 \/ \' u+ S5 O

  283. 0 X+ T# |  l; J' W3 v" P
  284. ;==============================* Z# I0 _) I& I' j) u
  285. Time_For_Vblank;延时等待
    8 ~& T+ T" l; B5 C% u$ I' B
  286. LDA PPU_STATUS1 s7 x( I0 t: d+ O2 m5 H" E! u
  287. BPL Time_For_Vblank
    9 J; n" |4 R) K4 p0 |
  288. RTS
    $ q+ t' h- R( c

  289. ' Z" u+ J" b1 p& ?8 m; b7 L
  290. ;==============================6 J  ^( x# R8 x7 p$ @2 s+ A
  291. ;初始化MAPPER196 p9 K9 k! }  \* x6 r
  292. Init_Mapper19
    4 ~' ?/ K5 @3 u$ {- c# q1 @8 U7 ~/ T
  293. LDA #$00
    1 A* x* j2 G$ r5 R, ~- x
  294. STA M19_CHR_0000
    , k- ^3 L6 T/ C( r6 r& x
  295. LDA #$01
    # n& F" ?, x3 y
  296. STA M19_CHR_04000 C  n. A- ^4 u
  297. LDA #$02$ b) F) T$ I: d& x" Q) f
  298. STA M19_CHR_0800" f: h: p4 R& |3 {
  299. LDA #$03' Q4 Q  g3 [  ^
  300. STA M19_CHR_0C00: s6 ^( H0 h: l3 R! f
  301. LDA #$04% r4 x: {$ m0 ]$ |
  302. STA M19_CHR_1000
    / \3 s: l, E2 b/ I, R* n
  303. LDA #$054 D9 E8 N) z0 E. S! t
  304. STA M19_CHR_1400( U# s  s; n& `/ Q* R* o; q
  305. LDA #$069 F& n2 m* R' y( V% V
  306. STA M19_CHR_1800
    , t9 x( h) d6 \6 J0 B: Q  G7 z
  307. LDA #$07
    ' G) g6 `: e. z  u8 [  ~) O2 K
  308. STA M19_CHR_1C00! d6 o1 Q8 ~; c0 b  k1 w9 b. o
  309. 8 `8 Y' X# B3 V" R+ }
  310. ;禁用IRQ" X) z; i# ^" q/ d
  311. LDA M19_IRQ_COUNT_H0 b6 l5 |# F$ ^2 b# N+ ~+ A/ u
  312. AND #$7F
    ' s7 D3 H- e, n( a+ l
  313. STA M19_IRQ_COUNT_H
    ; b, ]" N5 O& w* F) }! z! O; J
  314. ) a; E6 T; E) z/ N9 ^& ~1 Q. A
  315. ;命名表
    & ~2 a; g6 q- O$ U8 l, D7 K8 g( A  _
  316. LDA #$E0
    ) {% k" b/ ?2 s; b$ c  _* |
  317. STA M19_NT_20001 y) B( v" H1 ]( {; @3 {
  318. STA M19_NT_24000 m9 h* X2 @, K0 T0 B( h
  319. ; f5 v9 u9 N9 E7 W( Q1 ^' V
  320. ;命名表3 p  x- j: m/ J8 k( P
  321. LDA #$E18 q; G7 d# Q) Y$ T  R  ~
  322. STA M19_NT_2800
    7 ?+ \% _/ y! E& o/ {5 ?' l. ^$ t
  323. STA M19_NT_2C00- X5 Y1 g# n; F3 ~

  324. 4 L6 {, K/ k$ ?9 c9 S8 }- U- @5 A5 U
  325. RTS/ B6 ?0 R7 l2 ^; Z

  326. ) c# |# M2 ^4 w3 @% ?
  327. ;==================================================0 z8 n2 `+ r9 `% }) Q; G/ U) @+ ~
  328. ;重置中断处理; Q! j( f) F, r9 G% i8 L
  329. ResetProgram# C8 {& R7 m" b- o. u/ n
  330. SEI: H) r: i* K: U3 X/ _
  331. CLD
    6 y2 T! t: {( z3 ~2 j
  332. LDA #$008 G" {: `* r. i, ^
  333. STA PPU_CTRL
      j8 i! D  ]/ r9 T7 p3 s( R/ }  g
  334. STA PPU_MASK- k, b% }4 E4 o6 K5 _. h0 P
  335. STA PPU_STATUS
    : n7 |" p& g# o# p3 {4 u; D% M% w9 G
  336. STA JOY2_FRAME5 Q- Q) z* L% F9 u2 t
  337. STA APU_STATUS1 |' }$ U6 _$ q% ]. z

  338. 1 R& W! _, g  n) [1 c. ?+ `% {
  339. LDA #$C0
    4 l+ {$ C' s- j# M
  340. STA JOY2_FRAME
    / H- G9 N0 \6 t; \  T

  341. . n7 n- G3 P# L% ?; W
  342. ;等待vblank# I  P& m1 Q9 Z- W
  343. LDX #$02
    : N1 |" v& r9 M' D7 S
  344. Vblank_Wait_1+ \& S5 D9 `# S$ C  e# |4 Y! B
  345. BIT PPU_STATUS5 z! i. V* y+ `( O$ `, @
  346. BPL Vblank_Wait_1& m4 q% {0 e( V; Z# O+ G( Q
  347. Vblank_Wait_2
    ) M' f& x2 z: T+ b4 v
  348. BIT PPU_STATUS
    " s* Z3 F- x2 ~+ N
  349. BMI Vblank_Wait_2
      f- ]- v5 q" C1 o$ y
  350. DEX+ _  A/ g9 y  l! `( G8 c
  351. BNE Vblank_Wait_12 P: J- }( C) T+ `

  352. : F% J; W- G! u1 u- H6 ?: V( q* T; k, K; @
  353. LDX #$FF! ~% s& f+ o2 a% W
  354. TXS  d0 ]& S5 V% `; W$ _0 K% ^

  355. " Q9 k1 {; i, p2 X* v
  356. ;初始化MAPPER19
    0 j( R/ W/ j9 E" O  C6 L  O
  357. JSR Init_Mapper19
    $ c4 @0 v! S5 ~/ u5 e2 j
  358.   \1 d6 J+ g- M/ }1 k9 G) G
  359. ;==============================
    9 D9 A3 C% l3 V6 n( f
  360. ;RAM初始化. C0 X* ?5 X9 H: e% ?
  361. Nes_Ram_Init4 o2 {6 B1 L. d! ~" u; n' D' S
  362. LDY #$00$ ?: V# z% w. ^$ t, {3 b" R
  363. LDX #$08
    2 i. ^: o, o* p$ m: k( E
  364. LDA #$00
    5 A- S1 O. m2 N: W8 q  A5 _
  365. STA <$007 u) K. F0 V, h7 S6 C
  366. STA <$01. o/ H7 e& s  g) c0 J
  367. Nes_Ram_Init_Write. E# @3 C3 y/ R% g7 u, ]
  368. STA [$00],Y/ G0 F5 D' t6 B& w2 o* Z3 h- a) |
  369. INY
    ) z& o. C. n$ J# p
  370. BNE Nes_Ram_Init_Write
    * _: J7 H4 g+ t( m7 z# c
  371. INC <$01
    ' P, N" r2 L+ H
  372. DEX7 Q6 S" q9 C# f, J
  373. BNE Nes_Ram_Init_Write
    6 F: c6 q' H1 q  m9 A6 q
  374. + e, P4 {, ~" |3 W: H
  375. ;初始化命名表
    ( w, e% e' v( p4 ]# j* S
  376. JSR Init_Name_Table5 }% H0 U$ b) x

  377. : O& W/ L' W, Z- h5 C
  378. ;初始化调色板: k/ U8 s+ x+ W! E; U3 a
  379. JSR Init_Palette
    ' p( [7 }8 u) x' I1 S

  380. 8 f# @! [; P+ `# f  h$ i" A/ O
  381. ;初始化命名表属性8 \  D; D- [. |. y  _
  382. JSR Init_NameTable_Attributes
    0 G' G  R; H5 V* |6 d( j8 C* j2 t

  383. 3 O' x/ Z! p9 O
  384. ;初始化精灵内存
    - i  g* E0 g5 Y: }$ t( J4 P
  385. JSR Init_OAM_Ram
    9 n9 s/ }7 c! E' X1 \( A4 W

  386. 4 J6 p" J$ e& i/ z. m' Z
  387. ;在屏幕上写点东西( h# U4 g3 x/ O5 \
  388. JSR Init_Name_Table_Text2 Q! ?' q0 \" j' |6 ?7 c/ P8 R5 ?, ]

  389. , D! C7 i& J' l0 [0 l- O- A! ]
  390. JSR Time_For_Vblank
    & i( V5 @, P0 Q2 o) Q6 W% `1 x  e
  391. ;开启PPU控制
    ' k+ u# X4 j% }  i3 q5 C9 Y
  392. LDA #$A8
    , O: c6 W; h7 F- b) t% A
  393. STA PPU_Ctrl_Buf+ t& i" G8 Q9 ?1 P! _7 x
  394. STA PPU_CTRL
    8 g/ C  H1 e# J

  395. 0 F& [3 P+ ?* r8 H
  396. ;开启PPU显示6 O$ [0 F  }/ r9 M3 k
  397. LDA #$1E3 Q- x" w: |/ v9 Z# u  i
  398. STA PPU_Msak_Buf* K" @- W: P  s7 {4 X
  399. + P$ Y. \' `8 Y4 V8 e) O
  400. CLI. U; k' n- }& P) L: h
  401. JMP Loop# I5 y) ^+ o# b
  402. 9 G4 p: X4 d2 V7 d7 t
  403. ;==============================
    3 F3 A  n, L3 ?( }, }' D5 v7 ]/ X
  404. ;死循环, 等待NMI中断
    ( F  I3 u; i! j
  405. Loop
    1 X! w% {% E' {4 N2 Z* o, x
  406. JMP Loop5 J1 n, E1 Y3 ]' p3 T8 U/ ^

  407. 7 }9 K: s. q0 g+ U
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967( |, ?1 W( [5 N4 X
  409. & H/ I6 w% l  S' j9 `% C3 e. u
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    % v; @& H/ f2 ~5 @- j, h5 [2 S
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    - ~1 @- g) p4 n; u
  412. ;==================================================6 q$ A- l& V# c5 k/ U
  413. ;NMI中断处理* [" n" P& H4 H. [. L
  414. NmiProgram6 e- m9 v# R5 ~, f+ ]' `1 z* r5 M
  415. PHA" B8 l( p0 F" G
  416. TXA* A; m" H1 n) u4 C7 |2 h# G! X
  417. PHA
    * V0 y, P) V- ^$ Y
  418. TYA
    # y1 e3 c8 x: y" s9 |# s" @
  419. PHA
    4 ^% A! j3 w9 U: L2 G* W7 l
  420. - k# ^) t/ C' H) @1 p% u+ x
  421. BIT PPU_STATUS
    9 K; N$ @# u' e' M' [- T2 ^- ]( d: Z
  422. * M2 y* ?; G' }
  423. LDA #$00! {! S% ^" H: o* L0 T  t; Z
  424. STA IRQ_Index
    " U' a. j- P- e& w4 U

  425. $ U# B% K, S3 E
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
      Y0 U; c  }1 r1 C5 Z1 M, @% r* ]
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    : D: Y% X, @+ O# d4 U
  428. STA M19_IRQ_COUNT_L
    7 n) D2 Q7 ~3 ]* ]# e
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    + t2 j6 ]6 _! j
  430. ORA #$80
    $ j4 _, T* n4 H& E
  431. STA M19_IRQ_COUNT_H
    # |  x& E6 N* S) r6 T$ w7 }
  432. CLI" Q/ a. O. f3 d$ E5 V0 [% D) D. i
  433. ; u, H1 b, g! y' r' t
  434. ;关闭PPU控制
    5 \, M  ?  N0 d% K
  435. LDA #$00: E% h; j' C' e4 k: S$ p
  436. STA PPU_CTRL0 f4 ^# f2 g) [/ r$ G: J& F

  437. ) D! i' P% K. E/ U  `; N% @
  438. ;处理PPU. |8 Z. X* d% b
  439. JSR PPU_Process
    " N; z0 X3 o; D. b: @+ u
  440. 3 Z. n3 Z7 Y; h( v% n
  441. ;开启PPU控制
    0 P. m" t4 S7 w( k7 J" P
  442. LDA PPU_Ctrl_Buf
    - F& p3 Q. h. A9 b9 [, Q
  443. STA PPU_CTRL
    $ k1 q0 B1 f8 ?- }" f2 N" o* A
  444.   Q" b. k1 J6 `+ D! J0 \/ U5 P6 r
  445. ;手柄处理
    4 j, ^2 q# X3 P) t6 g2 F' D
  446. JSR GamepadProcess6 R7 B: y4 s( X. q( k; |' h
  447. 7 \; Y0 [; a/ V% [2 T- n; i
  448. LDA #$00$ L$ ~, `1 x; \; o. m# ^+ g  x, f
  449. STA IRQ_Index
    : O. B2 ^) b8 f$ I% ]4 W+ Q4 @% @" D1 `
  450. 0 A' T! O! X4 k. r" p
  451. PLA, }% B; R$ s8 x
  452. TAY+ s1 r: q% b7 ?2 o0 g6 U( b
  453. PLA, c0 O: O9 W% l" v
  454. TAX
    3 r, m9 F$ t& P. H
  455. PLA$ |3 Y, K. o9 y3 Z: U
  456. RTI& O1 y8 P5 U# G2 c$ ]

  457. / K8 f& w7 {# a7 A+ N# ?! F
  458. ;每行扫描线113.67, q& \* H7 _" y2 m% M
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)9 @( s9 X; r, D; E& `  ]0 Z
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7$ [1 B6 N$ s4 I& z" h  _
  461. ;==================================================
    8 ?# w8 r7 J' W. y$ r4 `+ y2 L
  462. ;IRQ中断处理
    0 R( [/ w  N' q! {  Z
  463. IrqProgram
    7 F' }, [9 L' _+ k8 S* U
  464. PHA" P" u; d8 t2 w7 I  Z
  465. TXA
    5 l% s0 q6 L4 s
  466. PHA
    / u# A# B( D; E5 A2 {9 A
  467. TYA
    . D6 h" U' I* A: |- `2 g! h
  468. PHA
    % B& Q) N: S9 E3 a, i5 k; i8 w

  469. 5 q4 {/ ]: `: T* M3 p: R# k
  470. ;16条扫描线后触发IRQ
    ( `& _9 Z/ P$ H, v, z& g8 U6 d
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    . h) g5 E. I  r: `% t
  472. STA M19_IRQ_COUNT_L5 a$ H0 e. `6 R  c% Z: b! K* }! I
  473. LDA #HIGH(BEGIN_LINE_CYCLES)& e) h/ B( S6 `4 l! J
  474. ORA #$80
    1 z/ Z% A8 @! Z; B# q
  475. STA M19_IRQ_COUNT_H
    2 Q; A2 J! U7 m+ R+ V

  476. 9 e4 M: ?' `( [+ g
  477. LDA <IRQ_Index# ~. Q3 y: q8 O! ^# k3 D# s
  478. BNE * + 4
    1 Q4 T, ~! H9 u
  479. INC <PPU_Scroll_H/ ^  `# h4 d8 H$ H

  480. / h: D- w, {! |) D1 x% J
  481. ;设置屏幕滚动; G2 v2 T* x5 s1 @+ f
  482. LDA <IRQ_Index: i! Y0 M9 M: G5 B3 G% I& E3 A
  483. AND #$01
    ) {, r- _" x6 v% _; z
  484. BEQ Irq_Scroll_Right
    1 L' N1 B$ c. J7 I7 W2 E  `& v  D: x

  485. # F4 J6 P, R, P% P; P( R; h
  486. Irq_Scroll_Left
    / q- W6 e: ~. A# h# n+ A
  487. BIT PPU_STATUS
    / {' t& c) r5 `4 {& d) X
  488. LDA <PPU_Scroll_H
    8 ?; B# g+ R3 C
  489. STA PPU_SCROLL9 G* F* K1 L/ S  m6 S% `
  490. STA PPU_SCROLL, s% N3 S  I" g2 \/ A3 j
  491. JMP Irq_Scroll_Over2 D* B. f0 m# z, s
  492. ) u0 G. X/ m6 {# _' i7 \2 J4 T
  493. Irq_Scroll_Right
    4 X: v& ]2 b3 Q# T; {
  494. SEC
    3 n8 O; f- i) A, D8 T/ w$ }
  495. SBC <PPU_Scroll_H
    # h% J# [8 d4 U: _* V% P1 [
  496. STA PPU_SCROLL3 s8 r8 t* X% A5 b' t
  497. STA PPU_SCROLL
    ' t) {  G$ f& o5 Z: J9 G
  498. Irq_Scroll_Over
    - ?7 ^, V  A5 X# E) n

  499. ) x0 D& ]. e6 v! k6 r9 y/ U
  500. INC <IRQ_Index$ z, }- O) u. K4 R, y" T/ `

  501. 9 P( R1 n. a1 t' b0 Q; C9 M' ~# M
  502. LDA <IRQ_Index! G$ n/ `% T5 B
  503. CMP #14
    % v; T8 o  R  ?- Q6 Z
  504. BCC * + 101 _; O5 P+ v$ v: ~
  505. LDA #$002 Y1 b+ X6 k/ c/ G  Q) a
  506. STA M19_IRQ_COUNT_L( w* M. n- x9 [. S" F# o
  507. STA M19_IRQ_COUNT_H+ n* b# e) u4 Y/ Z# }% s! t0 t) o1 D
  508. : m5 a* i& \4 e" X- g
  509. IrqProgramEnd
    / Q& B/ y( o1 o6 q7 v
  510. PLA1 l: Q% H- f* q0 d& l1 [
  511. TAY* N0 s8 a2 k8 j4 F
  512. PLA0 x1 V  s- k. ]% @) r5 N
  513. TAX
    + }  t# {) n- ~' f+ j( h8 b
  514. PLA9 M0 \! U. e3 o$ C  v
  515. RTI
    % ^- g( Q( a+ X0 a& e* G% X
  516. 2 {4 J; m% H& a) j
  517. ;==================================================
    8 f6 N7 X0 t) ~/ ~9 w
  518. ;中断表9 I" n# S9 l# x2 K) N/ L' |" t8 ^
  519. .ORG $FFFA( f, K' D( a8 ~9 e3 r) P. a0 R! `
  520. .WORD NmiProgram
    " R8 z# ^+ \# k( N7 d, E: d/ n
  521. .WORD ResetProgram  ]4 c- Q# V3 ]% w0 b3 `5 p
  522. .WORD IrqProgram
复制代码

8 Q0 v! O9 o9 s7 s3 p: {8 @

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-4-21 06:52 , Processed in 1.121094 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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