设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:13:54 | 显示全部楼层 |阅读模式
  1. ;[FC音乐][MMC5 IRQ]
    : A0 i: W! S& v5 F0 U. ?
  2. ;FlameCyclone 20230710/ X* Y/ p) j" `8 c+ ?
  3. 7 R7 @0 ]6 o2 Y9 W) H  F5 Q
  4. ;文件头) z) o6 [- c% n' Y& H  x( H
  5. ;======================================================================/ z2 G9 R- |- f* P
  6. .INESPRG 4                                              ;16KB PRG 数量
    * U0 c$ x3 h0 o: P$ A1 p) T
  7. .INESCHR 1                                               ;8KB CHR 数量
    1 ^( Y' i1 u  h) A5 }# J# ]
  8. .INESMAP 5                                                   ;mapper 5. L: i2 m# \8 o
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    # }. V2 t) V. G# m" p) e: O

  10. ! {! a: O, s0 g, ~% g& a; p
  11. ;必要条件
    2 J$ r; l* v; y) j8 \( j' X- T
  12. ;1.持有CHR ROM
    2 P. v8 j8 _& o- i
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    % b4 i4 ?$ T. W" z9 y! y
  14. ;3.精灵内存(OAM)不为空
    7 n+ J! P# e, k8 _, P
  15. ' s8 g; f! G+ j4 _- A$ }3 y# V
  16. ;==================================================0 D" G) [1 c, `3 R& v
  17. ;NES端口常量
    % L: [0 G6 m5 @. F  v( b
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    2 W7 K0 v  g7 A
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ' r- S" R( ^' Y3 R6 ^4 S
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    * Z+ W$ W3 m! O- D- V) S  z
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加12 x  q8 m$ Q' G8 E$ t
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    1 m1 m! H9 j4 k, a
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 2 G- \: j2 [6 {- z1 a
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    % G) f$ o3 Z; }4 _7 \
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 . Y$ O" G. f' [
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    $ }, k# }+ i+ i6 J: I& K! N
  27. APU_STATUS              =   $4015   ;声音通道切换5 k9 `/ [% @3 I# ]0 s' c" L' x7 A
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    6 M6 @* Z0 ^9 M4 G$ p
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    ) v" |( ~3 @9 `7 ]! c% p
  30. 3 M4 F+ c+ J1 ~" ?- T
  31. ;==================================================' e$ t7 e" C3 s8 o/ f
  32. ;MMC5端口常量! t% A0 U8 u4 ]( G8 ]- P- ^
  33. MMC5_PRG_MODE               =   $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4, S. o9 L& j5 M
  34. MMC5_CHR_MODE               =   $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8" q  ^# k& u; r+ Y
  35. MMC5_PRG_RAM_PROTECT_1      =   $5102;
    * a8 e8 s: U1 Z6 R, c: l  i1 k
  36. MMC5_PRG_RAM_PROTECT_2      =   $5103;
    ; W3 O% S$ R+ j9 j
  37. MMC5_EX_RAM_MODE            =   $5104; 0: Write Only 1: Write Only 2: RW 3:R
    1 e8 |' M' ]2 w1 {+ s& K! p) ?' r
  38. MMC5_NT_MAPPING             =   $5105;
    / w  l# L) {* K" h3 O# K% S$ ^! c& O
  39. MMC5_FILL_MODE_TILE         =   $51069 g0 g, ^5 u- t# y! [! Z
  40. MMC5_FILL_MODE_COLOR        =   $5107! Y% j4 u" ^' ^2 w4 \4 v
  41. 6 W  z$ ^3 m) P; U( A: O+ K
  42. MMC5_PRG_BANK_6000          =   $5113+ t/ d& Z! Z% c9 d: j( B. L
  43. MMC5_PRG_BANK_8000          =   $51140 o) p1 ]: l2 b4 X+ M* h0 U
  44. MMC5_PRG_BANK_A000          =   $5115
    # g- f8 u) g* e7 e6 |$ |  a$ V
  45. MMC5_PRG_BANK_C000          =   $51164 M7 V0 B! j* {! s8 V3 X  Q' j- {! }
  46. MMC5_PRG_BANK_E000          =   $5117
    + t7 p1 K0 f7 a8 N
  47.     7 Y+ o& w: j6 }  ^0 u. R/ b
  48. MMC5_CHR_BANK_0000          =   $5120
    & j2 Y( ~5 X& J! Y. s: K! W$ N8 I$ s
  49. MMC5_CHR_BANK_0400          =   $51215 E9 l/ V) g4 c8 J' D- R) W
  50. MMC5_CHR_BANK_0800          =   $5122, E7 h/ T$ u) _
  51. MMC5_CHR_BANK_0C00          =   $5123+ _1 Z0 J# j: j
  52. MMC5_CHR_BANK_1000          =   $5124
    / h8 O  `+ V) w/ s/ D
  53. MMC5_CHR_BANK_1400          =   $5125" t: B1 [$ Y5 g: U
  54. MMC5_CHR_BANK_1800          =   $5126! n0 k! J; J/ {/ b2 p. |
  55. MMC5_CHR_BANK_1C00          =   $51275 c0 I' x$ i1 ]
  56. 8 n, S6 S) Z( |2 k
  57. MMC5_CHR_BANK_0000_1000     =   $5128
    " @% B2 c( P% B3 v* X3 H' `7 @9 w, _
  58. MMC5_CHR_BANK_0400_1400     =   $5129. I) C4 w& H& \2 k
  59. MMC5_CHR_BANK_0800_1800     =   $512A& K2 s0 b. `1 m9 s5 I6 b2 q
  60. MMC5_CHR_BANK_0C00_1C00     =   $512B
    # F, F" e- G; e' x- [9 D+ u, G4 b1 h" N
  61.     / P% `3 h9 p* t" Y8 y( o. j% R
  62. MMC5_CHR_BANK_UPPER         =   $51301 s. C6 O9 c% E% i8 `5 }
  63. MMC5_V_SPLIT_MODE           =   $52002 O8 S! M/ A; }% m
  64. MMC5_V_SPLIT_SCROLL         =   $52011 R0 T6 y4 X: F5 N0 g
  65. MMC5_V_SPLIT_BANK           =   $5202/ T7 W- V, m: X1 p
  66.     8 j8 w0 S$ O! ~0 q
  67. MMC5_IRQ_SCAN_CMP           =   $5203" b5 T* E! h( F' C6 R- a: A
  68. MMC5_IRQ_STATUS             =   $5204
    ; h3 ?$ r8 r* Q1 v! R( A7 Q; V( i6 H
  69. MMC5_MULTIPLIER_A           =   $5205) w8 E- [) p9 f6 {) [: ^
  70. MMC5_MULTIPLIER_B           =   $5206" r$ u0 k) C* R7 C) ?7 e4 z9 J
  71.     + x) F" }. P  e7 J3 N, r8 i
  72. MMC5A_CL3_SL3_DATA          =   $5207( z/ P* Y- I) _. p
  73. MMC5A_CL3_SL3_STATUS        =   $5208& i% C& r- S9 R, d& e  R  o
  74. MMC5A_IRQ_TIMER_LSB         =   $5209
    & z9 n9 o0 M6 P
  75. MMC5A_IRQ_TIMER_MSB         =   $520A+ e% z$ r" t' J* q

  76. & I# A) `$ S  w9 Z# a$ e# x
  77. ;==================================================& {% p/ B# p; a0 a3 a, G
  78. ;程序块配置. w" g* h. m% V% L; i
  79. BANK_DATA_MASK          = $07# N& i+ v7 f: @
  80. ;--------------------------------------------------
    8 R' u) a7 ?. e) F) q
  81. RESET_BANK              = $07+ Y) l- K: x1 a
  82. RESET_ADDR              = $FC00- ]  f0 }! L* R7 p8 {1 D
  83. ) M, V/ z8 k' h( a; `5 O  ~
  84. ;==================================================
    6 R# Q; ]* l/ z; J, L) T' o
  85. ;图像块配置/ J, R% ?; c1 Y( L1 o% O4 R
  86. CHR_DATA_BANK           = $08% ?5 q1 l" Z5 r) Q* [) K1 N

  87. $ @5 m; Q" s4 o: |* e* q  S
  88. ;==================================================
    0 M$ W5 K/ V1 Y  E- L9 m
  89. ;零页内存地址配置
    9 y( X* [) T; F) ^, m, y# ]
  90. Use_Ram_Addr            = $80
    9 v: h+ v0 k& g* Z! W8 o2 h
  91. PPU_Ctrl_Buf            = Use_Ram_Addr# y) a* Z; I0 `  H; i: k- E2 x
  92. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01( o" U; _) k! M
  93. PPU_Scroll_H            = PPU_Msak_Buf + $01! v! i, O, \8 a; @8 z/ Z# r2 {
  94. PPU_Scroll_V            = PPU_Scroll_H + $01! X% _8 x0 N$ b8 w( s7 e
  95. FC_Data_L               = PPU_Scroll_V + $012 e& g- Y' n1 l. `  j- E3 ?
  96. FC_Data_H               = FC_Data_L + $01
    + R* e# a0 n8 A5 W+ y
  97. FC_Data_Buf             = FC_Data_H + $01
    7 v- ^7 s3 X# e5 S& ^7 ~! P8 o
  98. ;==================================================
    % m& h  z# B) `, ?
  99. 7 K. v3 `* c4 y
  100. GAMEPAD_MERGE_FLAG = $04! V: w) m$ A' Y# U8 G. A' x

  101. ( l2 Q& P9 X( f$ X; c
  102. Gamepad_Keep            =       FC_Data_Buf + 1
    ) M3 [! ?8 l7 i/ R+ N3 x
  103. Gamepad_Once            =       Gamepad_Keep + 2
    , [! [) E1 F& T! Q. A
  104. Gamepad_Temp            =       Gamepad_Once + 2
    ) k7 n) \! f' p. \2 l8 V
  105.                                 # C5 G1 s, l. Q/ S6 R2 P! b
  106. Gamepad_0_State         =       Gamepad_Temp + 2
      t* N- l7 |9 H: n. t+ q" f0 r' \
  107. Gamepad_1_State         =       Gamepad_0_State + 1
    % O9 E/ l3 B( Y: _$ B0 ]; L
  108. Gamepad_0_Value         =       Gamepad_1_State + 15 D5 t8 C' F6 S) y1 A8 C# E) K7 }
  109. Gamepad_1_Value         =       Gamepad_0_Value + 1$ X2 [, s$ _; J/ H9 P
  110. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    " n& w) w3 {# @0 Z6 k
  111. Gamepad_Merge           =       Gamepad_Port_Value + 1
    9 u. A! z$ J% y; s! A* K9 |

  112. ; d' F4 M, W6 l& h/ K- D' F5 n
  113. ;==================================================# M, H/ G& m8 p+ m" s1 k
  114. IRQ_Index               =       Gamepad_Merge + $012 h* a1 g  w% [& I# f& y
  115. ;==================================================4 @1 F& ?6 @% V4 \* v

  116. ! a: F. T* ]# M" h8 X8 ]- u& Z
  117. ;CHR图形数据1 ~$ R) |$ q! |% Q' X
  118. ;==================================================9 ^1 k1 s, }3 |  t5 c' Y
  119. .BANK CHR_DATA_BANK
    & r( Y3 B. m5 a# m! ^
  120. .INCBIN "chr_bank/chr_data.chr"& M7 ^* \' w8 P5 S8 F% d7 m& ^+ D

  121. 2 d# }3 F% D: ?. i; R( c
  122. .BANK RESET_BANK & BANK_DATA_MASK7 a7 G6 p& g- p7 p8 W
  123. .ORG RESET_ADDR
    + K, \, X* T: P" ?) y
  124. ( e- A1 m% ~, B/ `. m4 a' _- E
  125. ;--------------------------------------------------
    6 d* ~8 {7 {' I9 K5 ^
  126. Attributes_Data- C3 `  i3 H2 Y
  127. ;命名表属性, L& \. _! u2 i2 S/ Q0 S% d
  128. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    2 A1 H6 T( {$ W5 w# ^
  129. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA, u* b4 @) q( z* l  Y9 o' V/ s* U
  130. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    / O! r& ]' Q; m
  131. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    1 K9 h8 O0 c* g9 R$ [. Y
  132. ;--------------------------------------------------) M) G1 |" j1 u4 h: u" ^: u1 v
  133. ;调色板数据
    9 {& \$ m: g2 Y2 G2 G( m9 C
  134. Palette_Data+ Y, K4 r2 Q- K$ G8 T4 ~% j
  135. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F' \( E, d8 c' y6 h* `- G  c
  136. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    + N8 E# c$ z5 h) {3 k4 J! L
  137. 1 v9 w% ~' r; j- ^& t( u
  138. ;==================================================
    / A3 B* k( |/ n* D& @7 ?" a
  139. ;命名表初始化
    ! ~9 R  X* I) r8 K( r! h! ?
  140. Init_Name_Table2 N& e' t; C4 c/ S# d- ^* k' |
  141. LDA #$20
    ) J" `' J) D  e$ v9 @- a
  142. STA PPU_ADDRESS
    9 O3 R. S) E# I1 r8 G! G( G
  143. LDA #$00( P% [7 X* k5 L. I, [9 E! I
  144. STA PPU_ADDRESS3 [6 ?+ A3 {1 G9 z
  145. LDA #$00
    . u9 T9 W- P" |- ?2 z* B6 y
  146. LDY #$008 b9 U9 G3 ~& E: r' V6 [
  147. LDX #$10
    / x/ o5 X5 L- ^1 y5 o  C
  148. Init_Name_Table_Write
    6 @8 I" i& W& J5 o% m/ ]& V
  149. STA PPU_DATA+ o0 t+ j* N# e& U$ O; A! Z
  150. INY
    - @8 d. }* q' A2 j# _
  151. BNE Init_Name_Table_Write7 Q/ c1 u8 X& V% W
  152. DEX
    4 Z: K7 k$ w# P: o
  153. BNE Init_Name_Table_Write
    + W, x# i* D" ^# Y, {' d6 d
  154. RTS
    ) B, q+ t% [5 ~# ?: J* a
  155. 9 F; F; g) W3 N
  156. ;==================================================
    2 o* ^' X5 `/ N3 r) u7 p
  157. ;调色板初始化* G4 l- O' S  L
  158. Init_Palette+ u, E( o0 Q3 ]8 c0 N) K
  159. BIT PPU_STATUS% u0 w! v, l& }' `/ k8 V8 n
  160. LDA #$3F
    # A  f: Y+ z9 C( p5 \* v
  161. STA PPU_ADDRESS0 l  N  u0 d1 A4 W2 G6 _% b) ?7 e
  162. LDA #$00& R2 c- q+ d! a
  163. STA PPU_ADDRESS) q4 D3 |- q) W# v
  164. LDX #$00! \+ A! L, M, B$ |
  165. Init_Palette_Write2 k/ P3 C$ T# L+ z
  166. LDA Palette_Data,X
    9 [2 J) @& H' y% E9 t% i
  167. STA PPU_DATA3 C* B* a. N. X& i. X+ X
  168. INX
    : E% Y( e/ O$ L, [' B- X7 l1 x
  169. CPX #$20
    / X! P- D9 G1 H- O% a
  170. BCC Init_Palette_Write
    4 A0 _; ^6 F$ d
  171. RTS
    7 M5 u  r: {% Z0 b
  172. # X* X% a' V5 J- F6 O7 m7 K* ?2 B
  173. ;==================================================4 E3 j* Q; D' U( I5 L, Z( |7 b0 X
  174. ;设置命名表属性
    " W$ |" [+ b" q$ P& L- T5 u% @
  175. Init_NameTable_Attributes5 a" `5 d9 E. e+ r& F' O
  176. BIT PPU_STATUS
      w2 N0 H  s1 l  `0 V* D
  177. LDA #$23
    % B! P& o! {$ g# Y  ?! [  l9 M
  178. STA PPU_ADDRESS
    " B+ r3 M* O2 J6 [4 o
  179. LDA #$C06 q8 z/ Y5 `+ o! R
  180. STA PPU_ADDRESS& D( I8 ^; m7 S
  181. LDX #$007 o. f/ b: {4 p. P
  182. Init_NameTable_Attributes_Write0 ]( z2 p7 F# `6 {
  183. LDA Attributes_Data,X3 c" \7 ?9 |5 k4 T2 A+ a  e  Z
  184. STA PPU_DATA
    % ?3 x1 k: b! q
  185. INX0 u% _7 K* s/ t- e' Y
  186. CPX #$401 g8 _& g" K5 U$ Q6 ]6 t, L
  187. BCC Init_NameTable_Attributes_Write
    ( R( Q7 g" N" A" Z3 T
  188. RTS- H$ l0 D  V* _

  189. * y# ^& O  _, f& F" \
  190. ;==================================================/ y4 g; G" I6 Y7 m, v
  191. ;初始化命名表文本
      h: X8 P# c# K& J8 J
  192. Init_Name_Table_Text1 \8 w% p3 X: k/ n9 R- R! {/ H7 x# p* \  R
  193. BIT PPU_STATUS- ^& x. a8 i! B
  194. LDA #$20
    ; e) @6 }3 m$ a1 t1 M
  195. STA PPU_ADDRESS
    , b; A" f% D( }) H; x2 F0 ?5 w
  196. LDA #$005 `$ K( {) Z% B( [2 _
  197. STA PPU_ADDRESS, q7 F& D6 k" ^& Z+ N& G1 g0 V0 N
  198. LDA #$00# r! K$ @" j) C+ F: _7 W
  199. STA FC_Data_Buf" f+ F/ A0 O! p5 d! @
  200. LDY #30' X4 v4 M+ T) e$ U! }& h2 w' N: m
  201. Init_Name_Table_Text_Write6 ]2 r' }8 c6 _8 c3 p  ^' Q
  202. LDX #32
    $ g) x  M( Z7 |  P" ?# m4 k
  203. Init_Name_Table_Text_Write_Char
    ( k# ~4 D% ~# V- {; T- ~8 [
  204. LDA #'0'6 V$ B$ X9 V0 C/ E
  205. CLC5 y' x( i8 ]% y# [! z
  206. ADC FC_Data_Buf# {+ E+ N9 p2 `
  207. STA PPU_DATA
    ' R! K0 \0 q0 }
  208. DEX3 [. j7 m, c9 N1 |" d1 |
  209. LDA #$14. k1 H: d( ~  I  U  l& `
  210. STA PPU_DATA
    1 {  |* V" g, f: i9 ^
  211. DEX- K; X7 V" H3 l" J+ R4 I6 ~
  212. BNE Init_Name_Table_Text_Write_Char* _2 m7 I* U% ~$ f: [! b
  213. INC FC_Data_Buf
      K- S% b, S2 w+ u
  214. DEY
    . t7 f7 {' o6 B1 A* p+ Y4 D0 J
  215. BNE Init_Name_Table_Text_Write
    , _- L9 \; _8 d7 N; d4 _
  216. RTS1 X1 D, I" D2 t7 y

  217. % V  u& |+ V7 v5 p, y# E) J( g
  218. ;==============================
    % G' h, l6 r9 l! d& V
  219. Init_OAM_Ram;初始化精灵内存. s' |2 H2 j9 H6 t5 l
  220. LDX #$00
    $ q, {8 i0 G; [' ]/ H7 y/ k
  221. LDA #$00
    / w( K8 E7 M; I: s' B
  222. STA PPU_OAM_ADDR
    ; O5 o% P5 y  o' t- O: l' z( {
  223. LDA #$F8! ]! Y6 z- I3 O7 n
  224. Init_OAM_Ram_Write
    & m- B) w: `! R5 m1 d6 G
  225. STA PPU_OAM_DATA
    " D" v! g) p* n: t
  226. INX- [+ `6 h/ a2 f( [
  227. BNE Init_OAM_Ram_Write& Z* ?* Z) }0 n& r  a
  228. RTS
    4 P/ m- ~1 A# h! Z

  229. 6 X1 D7 A1 S0 j1 y! N6 s
  230. GamepadProcess;手柄处理7 H; s3 B' `* O5 |/ H! B
  231. JSR GamepadDatacan
    0 O+ f) ?  ~) G( {1 ^
  232. LDA <Gamepad_0_Value
    / z( Q# X: ?7 [4 U8 @6 v# c+ N
  233. STA <Gamepad_0_State
    ! T9 Z& {2 m$ J; ?, N: i
  234. LDA <Gamepad_1_Value' r) t: c; N8 ^! {" E- G+ w
  235. STA <Gamepad_1_State* C  i7 t" O4 ^
  236. JSR GamepadDatacan6 A4 o9 O& v' j" _4 ^7 C
  237. LDX #$01* V4 |" n! w1 R; [  M* f. l
  238. GamepadMergeCheck;合并手柄输入检查  ]/ T( S1 {$ ]) t" \3 x7 B7 R: d' J
  239. LDA <Gamepad_0_Value,X
    8 z# j" d+ t  B+ X' R) C$ z0 y
  240. CMP <Gamepad_0_State,X
    ! T7 B( S; Y$ f- Z
  241. BEQ GamepadMergeInput
    % l$ }0 |+ q. L9 }. e# i
  242. LDA <Gamepad_Temp,X! \- `9 h1 |' \
  243. STA <Gamepad_0_Value,X
    & s1 `6 i* ]( M1 e" |  M% Q5 c4 N
  244. GamepadMergeInput;合并手柄输入
    " D8 c1 m/ k6 h# ~5 M
  245. DEX1 g, c9 L( L1 j! ^
  246. BPL GamepadMergeCheck6 J! r6 i) T" E/ X$ r& N
  247. LDA <Gamepad_Merge
      h2 {* W$ d& w' _) l
  248. AND #GAMEPAD_MERGE_FLAG
    , p( v9 f4 O/ H6 [8 p8 V1 u
  249. BNE GamepadStateProcess
    & Q$ n9 a. x2 \
  250. LDA <Gamepad_0_Value5 c  T8 B; ^/ }8 J3 q2 J1 a3 W/ S
  251. ORA <Gamepad_1_Value6 w: C0 ~, ]2 {+ L& _& t/ _
  252. STA <Gamepad_0_Value1 C6 B* k! E9 j( w( ~1 G
  253. GamepadStateProcess;手柄状态处理! X3 f- @. A+ v' s
  254. LDX #$01
    0 _5 K( Z# R* `" `3 L& S+ q
  255. GamepadStateSave;手柄状态保存
    6 d7 q7 {9 V5 o5 p
  256. LDA <Gamepad_0_Value,X/ z" z9 n# e- m1 w
  257. TAY/ q* Z( e: a4 v+ [
  258. EOR <Gamepad_Temp,X3 U, z" P4 {1 j$ X! ]
  259. AND <Gamepad_0_Value,X
    6 P2 w; g# t4 l  J
  260. STA <Gamepad_Once,X, C8 g, v+ Y; C6 c- T: A
  261. STY <Gamepad_Keep,X9 a7 h0 s7 A$ i/ m0 Y- i
  262. STY <Gamepad_Temp,X9 [+ q( y0 i. q( E0 }9 {8 l- B
  263. DEX' z( ^. E9 f) C, d9 L
  264. BPL GamepadStateSave9 P7 s7 b8 G$ k, Y7 `# Z
  265. RTS
    ) N/ k$ b$ R" ?# |: @
  266. : _" R. a& e8 [. @8 v/ t" C5 G
  267. GamepadDatacan;手柄数据扫描( N5 x- z  `9 o1 W3 y- D) }
  268. LDX #$01/ A$ b# d- g" j; A7 t/ n! b
  269. STX $4016; n  f0 m0 R+ E  K" c* }
  270. DEX3 c- Y1 d1 ]8 w8 ^, S
  271. STX $4016: Q* Z% g9 B" V
  272. LDY #$08
    ' \) P( ~" S1 B& K0 E
  273. GamepadPortScan;手柄端口扫描1 Y% Z5 Z& `) V
  274. LDA $4016. b/ @" n& m- b- m/ x* x
  275. STA <Gamepad_Port_Value( l/ W7 d2 b/ l
  276. LSR A
    % V6 [: }8 t6 X" N# w
  277. ORA <Gamepad_Port_Value
    " ^' J( p7 k* L% b$ D
  278. LSR A& q% n& C9 Y1 [$ K  L$ A
  279. ROL <Gamepad_0_Value6 q1 ^' ^& ^# k9 c* |9 }4 T
  280. LDA $4017
    7 ~. T# S/ B' J6 y( \& k
  281. STA <Gamepad_Port_Value
    # I, g6 l0 r4 J
  282. LSR A* E$ p9 V+ f0 z# k
  283. ORA <Gamepad_Port_Value
    " K1 y9 z; o' O7 S
  284. LSR A0 S- V! G4 P( c+ \$ s4 G4 y7 N2 _+ T
  285. ROL <Gamepad_1_Value& w' I7 k- D) O3 [. B6 F0 Z+ i
  286. DEY2 ~( ]& M# n7 a1 P/ T
  287. BNE GamepadPortScan
    ) ]2 U( b/ R0 u/ g
  288. RTS
    # m- \8 B, T* O: |$ m
  289. - k; L( Q! j1 r8 _
  290. ;==================================================& B. X1 X7 e# s5 H5 K/ s2 Z, i6 L- y
  291. ;PPU处理" y( {! f' W$ l5 G
  292. PPU_Process
    7 p, W8 l/ k! Q8 |$ O  Q0 F8 V  H
  293. LDA #$006 k  H/ a3 c: n8 r6 e
  294. STA PPU_MASK
    7 p9 l3 v" d+ M% u- N1 D9 @
  295. ) Z4 {: U- j4 y5 T" t% L& p) a
  296. BIT PPU_STATUS
    . ?, d, T! o0 V0 P$ H( S" y
  297. LDA #$20
    ) }9 B3 P0 k: _6 L1 `7 {  m5 P
  298. STA PPU_ADDRESS
    " m& i' E( ?; T; R
  299. LDA #$00, M* X  L) f* c6 F7 `( p
  300. STA PPU_ADDRESS. d, S- t2 J2 y: b

  301. ) U9 U  K2 W* ]& l+ Q: ]) R# Y% b) E
  302. STA PPU_SCROLL8 s- p4 Q7 g/ A! u! E% V/ N
  303. STA PPU_SCROLL
    - y8 J  P% {3 i" t+ L1 E. k

  304. & X/ U+ A7 F3 Q; d& `; F
  305. LDA PPU_Msak_Buf6 M9 o- l( y0 w2 e
  306. STA PPU_MASK
    ; B2 S& Q1 S  l

  307. 0 ?5 Y3 |3 P" `/ t7 |4 W% G( `
  308. RTS
    ( e' F4 T. T, G; }* \) E
  309. ) v2 k6 M+ K2 X$ \
  310. ;==============================3 A0 S+ N: Y+ K% W0 g# E/ e
  311. Time_For_Vblank;延时等待0 ]6 h: J: o+ p4 {8 E5 g
  312. LDA PPU_STATUS3 L* [. ?4 M7 r
  313. BPL Time_For_Vblank! y- j7 D4 ^8 X- ^
  314. RTS
      ~2 A% E% \1 h1 Z9 M4 t0 B5 v$ j' h
  315. 4 F" s9 U" l1 g( y
  316. ;==================================================- g9 l8 `9 S- s* [, I* i% l3 I
  317. ;初始化MMC5
    % E$ N$ n# F5 L' T1 F- [4 M9 A; {# Q0 S# j
  318. Init_MMC5* M7 L4 ~6 E2 _7 }

  319. - Y# z9 w4 f% O3 h
  320. ;设置一下6000-7FFF的RAM/ X, `9 U, E' ?
  321. LDA #$002 |% j% v1 A! `
  322. STA MMC5_PRG_BANK_6000
    % k# g1 ?: Y6 a7 U+ D
  323. : L, g: e0 B: \1 R6 F
  324. ;开启 PRG RAM 写入
    1 X; u. Y" ]+ p2 B4 S7 U- _# F
  325. LDA #$02
    ' j" h$ N# K; X
  326. STA MMC5_PRG_RAM_PROTECT_1, `; X5 y3 Z. U8 D) \, y/ p
  327. LDA #$01; |$ x; x0 Q' K5 W
  328. STA MMC5_PRG_RAM_PROTECT_25 T/ w  ^3 G, q+ H3 }
  329. " O! k% A5 ]7 i) S" e* Y
  330. ;启用 1KB 扩展RAM ($5C00-$5FFF)
    6 O' ~8 R( c% d" D5 I
  331. LDA #$02
    / Q3 B6 {+ i) d! R2 S
  332. STA MMC5_EX_RAM_MODE. h& @: m# `- U- E: G6 z  R

  333. 3 n$ r4 z4 G  t$ y6 v1 m$ Y
  334. ;设置 CHR( b- B3 H' t4 R1 h* K9 @! ?* I8 x) b
  335. LDA #$00& r6 R# C' Q9 B3 \
  336. STA MMC5_CHR_BANK_0000
    1 K' Z( M. G; T/ L) a
  337. LDA #$01; C- z  b. w. f4 P
  338. STA MMC5_CHR_BANK_0400
    % D9 S2 ?* s+ A' t
  339. LDA #$02+ ^8 j9 {1 J" I7 b; I5 ?# ?# U
  340. STA MMC5_CHR_BANK_0800
    $ J0 i) T/ v: I3 N
  341. LDA #$03
    % }9 t& D3 b0 @" r6 ?" {9 }  B- P
  342. STA MMC5_CHR_BANK_0C00
    + [1 Y6 j# m" y/ R# K3 e5 k, ?. p
  343. LDA #$04
    ' H5 {* }7 Z, @. O+ [2 t
  344. STA MMC5_CHR_BANK_1000
    0 C! q7 P1 Q0 f4 E
  345. LDA #$05
    & ]+ i; L- @, B) V" b8 t
  346. STA MMC5_CHR_BANK_1400
    2 {$ [! m  _& f+ {
  347. LDA #$069 s# K5 R2 j9 ~# ^3 ]
  348. STA MMC5_CHR_BANK_18001 Z( j* R4 C8 X$ N+ t0 ^. w
  349. LDA #$075 W' U! ]0 I& S( o" X
  350. STA MMC5_CHR_BANK_1C00
    2 {: u; W0 W0 v% @9 E

  351.   a3 H9 G, V. b: i: i
  352. ;设置屏幕镜像/ Z! Q, ^' S6 g6 `
  353. LDA #$50
    6 J# M3 M% _9 h* `& T
  354. STA MMC5_NT_MAPPING, G# \5 F3 M1 r! D& S1 N, k
  355. 2 b0 N/ m% r0 ^; z: b
  356. ;禁用IRQ3 a, i  w# j: Q' K9 l- q
  357. LDA #$00  _' x. \( n; ]! M; g/ M- p
  358. STA MMC5_IRQ_SCAN_CMP
    ( Z9 Q9 ?! }4 X9 h* p* I1 e
  359. STA MMC5_IRQ_STATUS
    ( T4 g" R- m% u0 I3 h; k( W
  360. + G/ K' O6 }5 \9 W- w8 _( l
  361. RTS
      m( \5 }( w; V

  362. # Y5 `; g& _3 N8 V1 {* q
  363. ;==================================================
    ' |  M. E  J- g& A/ A# T! `6 U& F( A
  364. ;重置中断处理6 _5 h0 e( [. V
  365. ResetProgram4 n! l4 _$ |* u& ]3 z; d) x
  366. SEI
    * d' n* f& y( B
  367. CLD: W2 N: i$ j/ I
  368. LDA #$00/ ?7 ~1 `( n- Y; ]" r
  369. STA PPU_CTRL8 j, V7 ^6 j1 J+ I- `  t
  370. STA PPU_MASK# e- _5 e3 n$ F: E5 E: u
  371. STA PPU_STATUS
    ( s. P( ]3 M% y; f5 l/ \9 A4 f
  372. STA JOY2_FRAME. F" s2 `/ o, ?4 q
  373. STA APU_STATUS
    $ j# A3 q! z0 `+ |, j

  374. ! p* }  _" P( {" t0 L4 g1 {; i
  375. LDA #$C07 N* s% Y5 E1 t& c
  376. STA JOY2_FRAME
    2 `6 o$ r# ~# y: O) v4 y

  377. . k; y) \: p+ r. z4 [; I
  378. ;等待vblank4 G4 r, G( F1 I
  379. LDX #$02
    2 r1 b7 l; U% x: j" ~
  380. Vblank_Wait_1
    1 L# r& v0 M3 v
  381. BIT PPU_STATUS% \6 f4 ~) Q& F4 j7 N3 _2 k
  382. BPL Vblank_Wait_1/ v! a) o9 w" b- y( a2 ^2 D7 k
  383. Vblank_Wait_2( e( ?: l  |( Z3 s+ i3 G' X0 _
  384. BIT PPU_STATUS; u6 A3 T/ ]$ `
  385. BMI Vblank_Wait_28 A. S- J& O; Y4 H& L& D
  386. DEX
    & _; p2 g* |  Y  f) H3 a+ p
  387. BNE Vblank_Wait_1
    ; h1 l3 {7 p5 i( D- X; G

  388. 4 L1 [; d& y, N5 t; n: n
  389. LDX #$FF4 T* Z" `. R$ W% ]
  390. TXS
    7 ]( W) M$ K, `3 A# z! L- ]

  391. ) G; b2 A: S- i6 R
  392. ;初始化MMC5
    2 a+ d+ X& q4 T- w& f1 ~
  393. JSR Init_MMC59 |3 H6 Q4 I. K" w  F1 h

  394. 3 F6 J7 g5 Q  u; t  ?
  395. ;==============================% Z& D$ c" C6 [8 ]8 ]
  396. ;RAM初始化9 ^7 I- ]6 i* t( S
  397. Nes_Ram_Init* L9 b: ?; j% M( R" i) M4 s
  398. LDY #$00
    8 G( H7 `$ v" O% O9 B8 T: \
  399. LDX #$08) L' c# B% L( Y, A
  400. LDA #$00; E, U$ J7 T5 W6 t- m
  401. STA <$00
    + H( r3 ^4 Z+ X
  402. STA <$01
    ' h8 [5 i# Q- f. l# Y/ \: L8 U( I4 ~
  403. Nes_Ram_Init_Write
    7 U+ }! e2 U  r! I4 e; V5 u7 @2 [
  404. STA [$00],Y/ F  Y3 C% F( q
  405. INY
    2 K" H5 h6 x$ P5 T
  406. BNE Nes_Ram_Init_Write
    / ~# u+ ?4 f7 @. r% ^4 U8 R
  407. INC <$01
    3 t9 s( `1 P$ w$ ^( h+ {
  408. DEX
    - t6 g2 w/ Z: Y" G2 B
  409. BNE Nes_Ram_Init_Write
    # K3 \* J+ s  U/ A; n2 d) N" X
  410.   
    4 ?! V2 G3 r0 f' w+ j; x$ h
  411. ;初始化命名表
    & J, _5 G: E$ |; L( n' v
  412. JSR Init_Name_Table+ U: v. s2 Y3 G, @0 y+ k

  413. ( X# K' n; l+ i: F# A
  414. ;初始化调色板2 U1 ^) F: p. y& w9 B' _$ H
  415. JSR Init_Palette& e# y7 |: S* F4 {
  416. 8 ]; b/ |, H( G1 ~3 i
  417. ;初始化命名表属性0 y5 P* k% y2 G( L7 q4 T
  418. JSR Init_NameTable_Attributes, K) Y3 E1 Y7 v, U' k) D
  419. " r( z  G- N( w/ p4 e
  420. ;初始化精灵内存2 H- h9 U6 V) Y: |
  421. JSR Init_OAM_Ram. s) S/ H- K  q, l3 A9 N  j

  422. 3 K2 s! r* k& k, z" Z
  423. ;在屏幕上写点东西
    ' |- h2 }9 G3 ^
  424. JSR Init_Name_Table_Text
    % ~5 t: x3 T& g) E
  425. & _+ p( h& I3 Q( o6 Y1 A5 |
  426. JSR Time_For_Vblank
    9 t& @2 D* a; s5 E; U+ a
  427. ;开启PPU控制
    , p1 b; j) ?- q
  428. LDA #$88* {& t9 J% r- c  x; r0 j- n
  429. STA PPU_Ctrl_Buf8 e: z" _! R% @6 }6 U1 ~8 R9 U
  430. STA PPU_CTRL& X$ o% C9 a# B* K) Z5 ?
  431. ! a8 s8 R% c# V
  432. ;开启PPU显示+ o* Y" M0 `% ~. K+ S; o5 d% S- k& ]; h
  433. LDA #$1E* K! ?, C" h5 l1 f' x
  434. STA PPU_Msak_Buf
    / p" d* p+ N6 X9 v, e( h
  435. ) i3 R+ K0 p8 q
  436. CLI) |9 h. g, e; r# y, L& J
  437. JMP Loop
    9 E& U$ E1 T5 P$ }; M

  438. - V" j% B% C5 I1 p0 ~
  439. ;==============================( r: q4 v( N; |' }' `  o0 g( \
  440. ;死循环, 等待NMI中断
    ) c! g8 W1 g, l: x& `
  441. Loop
    * [2 I' B- s9 Y6 g8 A; i9 t
  442. JMP Loop
    ' y  T2 G0 E" a* O! u3 O6 F" u
  443. 9 S) b4 q% G1 Y1 _
  444. ;==================================================
    9 I; _: s6 A" g) W5 a) d6 Z. f1 F
  445. ;NMI中断处理
    ! d- h- M& p! K/ I5 a
  446. NmiProgram
      S" A3 P9 m% q' a
  447. PHA
    7 B9 R/ A( k& ~+ U+ V8 J
  448. TXA8 r, K% e) v/ Q8 v& }
  449. PHA
    # x0 ~% m9 F5 E! d$ o
  450. TYA3 a2 N# |% `0 E% c
  451. PHA; i, y* [8 K- W3 {/ D. _5 ?' K

  452. # x# c! W( N! d& J
  453. BIT PPU_STATUS
    + Y2 `8 Y' W/ z% K$ I& A0 ]% o
  454. : }0 X4 Z! [# X6 r) i
  455. ;启动IRQ中断, 第16条扫描线触发
    ) n1 Z% m$ ^' ^/ v
  456. LDA #16
    6 _: a3 r) q( v0 t% ]# N
  457. STA MMC5_IRQ_SCAN_CMP; H1 k" b: K3 k
  458. LDA #$80
    . z8 v& V: ~0 X2 l
  459. STA MMC5_IRQ_STATUS
    ' r# J* u2 Q0 s$ R& }5 S
  460. CLI" X8 ^( {  L  ]: C

  461. , ~+ U5 v; c( g9 T
  462. ;关闭PPU控制
    * j% _/ @. l' d; i: ~2 f# T# [
  463. LDA #$005 ^+ Z; c, B. e5 ~3 ?) J
  464. STA PPU_CTRL+ A7 n+ v. v' V) q; @# `# C
  465. $ g* D9 y3 p  d0 O0 W
  466. ;处理PPU7 `; w& i$ P9 O" [8 s* p6 h
  467. JSR PPU_Process- d9 K8 x9 c3 `( C. w4 E$ o5 h
  468. ' V; R- X; B  H% ?2 o, ?
  469. ;开启PPU控制
    + r! L& w) ^; F+ h2 K2 Q! ^) k
  470. LDA PPU_Ctrl_Buf
    8 q6 g0 a. V! M: L" W
  471. STA PPU_CTRL( w8 \9 ~5 r; v0 Y0 S3 A

  472. 9 `# M4 O: J8 K
  473. ;手柄处理
    9 w/ z  R2 L( Z& @' Y
  474. JSR GamepadProcess  t0 Y& a3 X8 ?2 B9 q  p) L
  475. * q- {3 P, B% I8 q# P; h
  476. LDA #$00
    5 t5 u; a0 |$ t" ^& b0 N8 d; C
  477. STA IRQ_Index7 `6 R) i% [& B0 E3 \
  478. * b. O7 W% Y# t/ F
  479. PLA7 O1 c+ T+ {$ ]! d8 n6 v; `8 ^
  480. TAY4 A  R4 e% A& }! j9 n
  481. PLA$ ~% X+ _$ [6 L! t1 r
  482. TAX
    ! E) O- H8 {( X( u# [
  483. PLA: `, u+ P# J$ G1 {" N, c& {
  484. RTI
    ; Y! l- p8 \( L" P

  485. # n+ [" I' T& S: M
  486. ;==================================================' U$ Q/ d# m6 ^. U! ]' v
  487. ;IRQ中断处理* i5 c8 e( ^' l4 }2 A
  488. IrqProgram
    " k; H$ C, \! \: h. `" Y7 q& ^
  489. PHA
    6 X: d8 H7 P! y6 L& ]
  490. TXA" X$ g+ `4 B1 @' R
  491. PHA
    0 z1 @; `0 c7 t' h, }1 n
  492. TYA
    1 p- ^1 q( C8 q$ K. v; T" X
  493. PHA# Q# V) C( v- K& n

  494. 7 @$ p4 q9 s. L# b: [6 t6 ?
  495. ;确认IRQ
    9 N5 `, l7 C* C4 a3 m$ ~5 q$ I
  496. LDA MMC5_IRQ_STATUS
    3 Z1 t& O2 k$ d/ J

  497.   m/ G$ U: v8 o/ J7 M9 x
  498. ;允许下个IRQ触发9 h0 [+ O* Y8 M+ X; ~8 d( `( {
  499. LDA #$80
    : u9 S9 _3 W9 S' |
  500. STA MMC5_IRQ_STATUS# k, F2 S1 P) t7 I: \7 W  x5 Q

  501. 7 Z. }2 S2 B/ }; @: ~% T
  502. ;IRQ处理, 每隔16条扫描线触发
    & o3 _+ C! [$ I( Y9 c. `
  503. LDA <IRQ_Index6 V/ i( ]9 W8 {8 v6 S- }
  504. CLC" s2 q5 |" C3 T7 G% ^7 u  ]
  505. ADC #$02
    ! p5 v& u5 `6 @: b- {) M: b, V
  506. ASL A4 z( W( J1 y. T  A0 |/ E0 V8 Q
  507. ASL A
    ; Z3 T  c/ K! Q% v
  508. ASL A
    - x' p- R* c) i! M
  509. ASL A) l) Z0 q) T1 {
  510. STA MMC5_IRQ_SCAN_CMP, x4 O1 Q7 o: U& S
  511. " K; k; I2 P" W1 [
  512. LDA <IRQ_Index: i5 e* ~! E, `) o8 x' |
  513. BNE * + 4; ^/ b) t4 U9 J8 F
  514. INC <PPU_Scroll_H
    ; X% b& m; X* i* `
  515. 3 B& U. A0 |" W0 o
  516. ;设置屏幕滚动
    & y! d+ q* }, R- e' N/ [3 D% A1 ~
  517. LDA <IRQ_Index
    - o. z( l2 x! V8 H* f9 n2 q- H
  518. AND #$01
    " m; y4 V: V( T8 x. _& |
  519. BEQ Irq_Scroll_Right  B$ j- V% N1 F8 H5 M

  520. & S9 I3 a, H& C5 P; D5 M
  521. Irq_Scroll_Left, P7 ^- {/ X  F( b7 u
  522. BIT PPU_STATUS
    " `& j* k+ f9 t! Y; T
  523. LDA <PPU_Scroll_H
    ) {- k% d; @' H( ~
  524. STA PPU_SCROLL8 c! z, f3 o7 H8 i
  525. STA PPU_SCROLL
    / p6 ]$ |9 q/ b7 I
  526. JMP Irq_Scroll_Over
    : B7 S# r4 l. S& w

  527. & Y& x' m+ N: h- N
  528. Irq_Scroll_Right
    7 p: e3 T4 g- I5 g* F+ f$ X
  529. SEC
    % i, m; B6 [) F. \0 H
  530. SBC <PPU_Scroll_H1 \9 Z8 J- p& n) ~0 V
  531. STA PPU_SCROLL
    & I0 {& e: V+ g* `
  532. STA PPU_SCROLL+ d. Y3 q# E2 f- [) Q9 u
  533. Irq_Scroll_Over
    8 V. s; I, K4 k! I& V; W' z
  534. - U. {! G% h0 O; B* G. A; O
  535. INC <IRQ_Index
    ! @; t" d% r: n* s$ N2 {+ r% {

  536. $ l8 v2 j) \( `/ Q+ K
  537. LDA <IRQ_Index# v1 a& L+ ~0 t' [' E0 j9 W: e
  538. CMP #148 B( P% @. a/ A4 R4 A
  539. BCC * + 52 N) z3 K0 G: G
  540. ;关闭IRQ
    5 [8 P' |) F5 S" x- F
  541. LDA #$00
    9 X$ C$ p5 @1 n2 O9 W  Z- y
  542. STA MMC5_IRQ_STATUS! R1 J* K, z8 F; i  Z' |

  543. ! x% N% R9 H1 _, H4 X0 A2 ^
  544. IrqProgramEnd; E- h2 T1 F" ^5 n- @9 l" h$ `$ [
  545. PLA
    / W; Q! j) O$ S- C) h3 q6 h
  546. TAY
    * v% ~3 e% o+ o: i: ?: I
  547. PLA! t7 S0 Z; w; Q3 q2 C& X
  548. TAX
    ! O) J. m+ L2 E8 m4 X; u1 l. `
  549. PLA& v* j+ o0 i8 b, k$ w
  550. RTI
      C1 }$ ]6 L9 @4 q" T* @) {
  551. 0 x2 `+ ~9 T. u. d) n; W7 X' A
  552. ;==================================================' u+ s. W- z# Y! m5 g. y
  553. ;中断表
    4 z. k1 A$ b: a& [# h( R
  554. .ORG $FFFA
    0 p+ z& Q2 a) T. M5 I
  555. .WORD NmiProgram
    4 R. e' k/ [) a: }4 W
  556. .WORD ResetProgram' f9 F2 T) T' b) U: j7 A- N3 Z6 _- |% S! ~
  557. .WORD IrqProgram
复制代码
! f( Q5 g5 ~+ ]( n

本帖子中包含更多资源

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

×
[发帖际遇]: yandagui扶老大爷过马路,警察叔叔奖励yandagui 3 个 柠檬. 幸运榜 / 衰神榜
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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