EMU618社区

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

[原创] [FC][精灵碰撞学习源码]

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:17:53 | 显示全部楼层 |阅读模式
  1. ;[FC][MMC3 精灵碰撞]# m- _9 {: s! x+ }9 v1 M5 v
  2. ;FlameCyclone 20230710& S  s6 Q7 V, w4 f! F" x  `% `* @

  3. 3 G# z& `( C3 P9 u4 g' v
  4. ;文件头3 I8 }  Y" R5 F: D
  5. ;======================================================================
    8 g, I/ e: p- ~
  6. .INESPRG 4                                              ;16KB PRG 数量: F9 J% O6 }3 j1 d- ~& T; c1 W4 v
  7. .INESCHR 1                                               ;8KB CHR 数量8 k: Z9 ]1 P6 M* m
  8. .INESMAP 4                                                   ;mapper 4
    " `; h% }/ S* h  O1 [  L; o
  9. .INESMIR 1                                     ;命名表镜像 0水平 1垂直# @/ ?; }# k) Q2 b8 ?

  10. ! I2 i6 ]% l% n
  11. ;必要条件$ T: S8 m5 I# A) _
  12. ;1.持有CHR ROM
    . X# T" g" x9 U3 ^0 l: E8 R2 y5 a3 ?
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000: U' |0 o  H) W3 g
  14. ;3.精灵内存(OAM)不为空
    1 F/ P2 o4 m% J
  15. 2 G9 z& S. t1 G
  16. ;==================================================$ V8 N# m7 e- F7 o; d
  17. ;NES端口常量7 j) u7 J. V3 b# @2 \: G+ S
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    # L" y/ N5 \( Y* K+ b, q
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    2 X5 H# s& Q1 E" T
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位3 N; ~8 E; H1 U$ p$ M5 H: R2 X
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加11 @" _! S- j; J! ^% ^$ S
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1, {! k, \! P' _6 d
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    # e5 ~* B2 q; F) H( S
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加# ?/ v# g3 j: U1 c/ u* K0 a
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 3 h9 i4 @3 h2 \7 v, ~+ `5 T
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ; x% V8 ^4 x2 n" D5 d/ p8 @0 Y
  27. APU_STATUS              =   $4015   ;声音通道切换0 C# J4 ]$ g5 \6 x1 J! D: }. w1 m1 H9 F
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通( D( r7 U2 `; g2 u- o" ^! ^( ]
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    0 o: n# ]/ Z0 g  M1 q( p

  30. % x: P6 ~! K9 S% F
  31. ;==================================================
    - |* C( p) j3 E5 X
  32. ;MMC3端口常量2 o8 I- A! N" ^# L, I& j6 A2 P, J4 E
  33. MMC3_BANK_CTRL          =   $8000
    / Z; c. S' k7 @9 L+ |3 I! G
  34. MMC3_BANK_DATA          =   $8001
    8 j" V5 J2 w/ e0 C# L; D
  35. MMC3_MIRRORING          =   $A000
    . W# M9 X: s/ u4 @# X+ k/ C" U
  36. MMC3_PRG_RAM_PROTECT    =   $A001
    : r8 P! o: O6 ~2 M8 B% `
  37. MMC3_IRQ_LATCH          =   $C000, ?6 o( ]: l7 w0 M
  38. MMC3_IRQ_RELOAD         =   $C001$ |1 p# y3 s8 Y) t0 O
  39. MMC3_IRQ_DISABLE        =   $E000
    ; Y6 f  U7 T7 w; l8 S) T. g3 b" B
  40. MMC3_IRQ_ENABLE         =   $E001
    7 @0 `) A( o8 U( v5 ?

  41. 1 B: L3 A9 e4 U% J( w
  42. ;==================================================+ N8 d% i, E' m3 C1 a
  43. ;程序块配置. \# \+ [4 P" O  b
  44. BANK_DATA_MASK          = $07: ?5 w, p/ r; M! O& |! h' [- ~( a8 x
  45. ;--------------------------------------------------4 Y& c6 O0 {+ w8 |; [) t& q/ k
  46. RESET_BANK              = $07
    % L& q, K' O' C. U  ~5 X
  47. RESET_ADDR              = $FC00
    % h* I0 K, `/ k0 E4 L2 d. r

  48. , N4 H5 `/ s! g3 g, ?) p( a
  49. ;==================================================
    & x9 n0 f5 L# l* {& X
  50. ;图像块配置0 v6 ?$ u2 `$ @  {9 X  x: ^
  51. CHR_DATA_BANK           = $08+ K, ]- {2 V$ C, x5 W
  52. 2 X) U& ^* Z+ O+ M
  53. ;==================================================
    ! q) W: R0 b( O8 D8 X- z9 z- ^
  54. ;零页内存地址配置
    8 t9 f" W# A( b5 _3 u4 ]
  55. Use_Ram_Addr            = $80
    ) k( l9 P% G% H1 a
  56. PPU_Ctrl_Buf            = Use_Ram_Addr
    + P4 a# p9 \+ F9 j3 r+ m
  57. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01& ]: B( m7 e1 a# h% L2 Z
  58. PPU_Scroll_H            = PPU_Msak_Buf + $01
    7 W4 q9 r3 q( t" ^3 a7 _6 M) u
  59. PPU_Scroll_V            = PPU_Scroll_H + $01
    ( q" F9 `" C. M. q( Q$ V
  60. FC_Data_L               = PPU_Scroll_V + $01  s' E2 ^2 v- O6 a% L, h  D
  61. FC_Data_H               = FC_Data_L + $01/ W1 V& c3 D. a: w3 F
  62. FC_Data_Buf             = FC_Data_H + $01
    ! i) w# c) a$ S' N% w
  63. ;==================================================+ `# M4 {, Q# M  V" e0 c5 w

  64. # S/ b6 K' E) v6 N' \( r8 [
  65. GAMEPAD_MERGE_FLAG = $04! p! B5 y) u1 h" v7 O" H2 c6 R
  66. 1 u; t+ q) J# _0 k  {! u( u1 L: A
  67. Gamepad_Keep            =       FC_Data_Buf + 1
    2 a* M5 Q  r# w2 A+ U, E. ^/ _
  68. Gamepad_Once            =       Gamepad_Keep + 29 g% y& o6 w$ n2 A9 S; d
  69. Gamepad_Temp            =       Gamepad_Once + 2
    ; u4 m' j; c! }. ^: }. v8 |2 T) J
  70.                                 
    & I1 y0 S. P& z: O/ A% V+ [) m7 f
  71. Gamepad_0_State         =       Gamepad_Temp + 2& k1 U4 O; j& d& [5 b& D- n
  72. Gamepad_1_State         =       Gamepad_0_State + 1
    , B6 k, j& }+ ~8 f6 t- _
  73. Gamepad_0_Value         =       Gamepad_1_State + 1
    0 }' O% N0 [) l# x1 ]
  74. Gamepad_1_Value         =       Gamepad_0_Value + 14 e- x9 x! q2 Z, w( E
  75. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    . J( H* B  ^! h2 k; S
  76. Gamepad_Merge           =       Gamepad_Port_Value + 1' J/ B" z( C" Q) U  w
  77. 1 z. M- ~  c$ J. b
  78. ;==================================================
    : H  M0 I( j$ }6 E8 A, S) o
  79. IRQ_Index               =       Gamepad_Merge + $01
      d2 k- Z0 P, P5 Q; V
  80. Sprite_0_Y              =       IRQ_Index + $01: O/ T! J) X* ^
  81. Sprite_0_Tile           =       Sprite_0_Y + $01
    , E& e+ p) w! y$ s
  82. Sprite_0_Mode           =       Sprite_0_Tile + $01
    3 B0 g% W  H1 w2 x% O, e0 k
  83. Sprite_0_X              =       Sprite_0_Mode + $01
    7 k, D" H; q/ y, m- E: Z; v
  84. Sprite_0_Hit_Move_Direction           =       Sprite_0_X + $01# O/ G  \1 X: K0 @& e
  85. ;==================================================9 ?+ n9 }* A6 f; e+ O1 H8 N( m
  86.   Q. y2 ?/ k# c* D5 @
  87. ;CHR图形数据
    % A+ ~) P+ U% t; x
  88. ;==================================================2 K, ]* Z6 R/ }6 N% u
  89. .BANK CHR_DATA_BANK
    5 B- m4 S5 x0 F# \0 q3 ~
  90. .INCBIN "chr_bank/chr_data.chr"9 ^, j1 ?( h1 w2 H. h
  91. " y. O( W0 d- B( c, }
  92. .BANK RESET_BANK & BANK_DATA_MASK
    # c+ T3 ?1 g. _
  93. .ORG RESET_ADDR) K5 K5 Q5 y; u! P
  94. 8 Q' D( q/ f9 @& R
  95. ;--------------------------------------------------6 ^- L$ w% Y6 m% W2 E- g  C( C
  96. Attributes_Data$ X6 c' r* V% c2 G: s% f. `& I) j1 {
  97. ;命名表属性" O; q( W. @$ r  ^: j, m3 r
  98. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    6 v0 F, `: [4 C& N
  99. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA! I7 v- P& W' Q. q. A
  100. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    8 I: \; r/ X& e8 d, a( ~) S1 q
  101. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55' V# s7 U' Y$ R
  102. ;--------------------------------------------------
    & H: |* ]1 r  P2 t3 G$ j; @
  103. ;调色板数据# A- C4 m4 x$ {* v8 J
  104. Palette_Data4 h/ L$ F5 j) m: I, K" ~
  105. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    : w9 Q# e* J' H
  106. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    / _. i0 z. ^' ~' r
  107. # N0 U  a, w- o" E& i& U4 |4 w
  108. ;==================================================
    % F2 N2 _; f3 ?  |) f1 w
  109. ;命名表初始化" F7 @- p  }& _; n2 N% [
  110. Init_Name_Table
    9 B6 v; x5 l4 ?! V2 F
  111. LDA #$20
    + H" }/ V: g' S- d% l) h* \, k
  112. STA PPU_ADDRESS5 I8 V$ [3 ?; y$ m1 A
  113. LDA #$00
    3 x( d1 u# d/ i5 [0 H: N- F7 s  [
  114. STA PPU_ADDRESS0 e# a. f3 F4 f, f: V
  115. LDA #$00
    # k% Z  f7 V: W/ [6 s1 v
  116. LDY #$00. M- r5 a. T* v
  117. LDX #$10# q/ l5 f( d9 k) y
  118. Init_Name_Table_Write
    + B4 ~! K# I: e% Y0 e2 X8 g! m
  119. STA PPU_DATA
    / v, s( h6 @# O2 Y5 L( U
  120. INY' Z+ O$ a" n- O4 e- z& {
  121. BNE Init_Name_Table_Write6 V1 E& n' Y) y2 W+ Z6 }
  122. DEX
    1 o( Y/ V. z7 a7 f( E8 v
  123. BNE Init_Name_Table_Write: K+ n& c; Y" ^; X4 y
  124. RTS
    8 i4 s' E" i  D7 |& g
  125. 8 B5 @* B# g$ {% X4 P' @. p" Z% {5 M8 d
  126. ;==================================================
    9 {) @7 o0 |8 E
  127. ;调色板初始化
    ) `) l$ M& T( d9 i
  128. Init_Palette2 z( p  u% `) ^  V
  129. BIT PPU_STATUS' D/ ~. J8 \* ]5 Q
  130. LDA #$3F1 M7 U& o/ Z- x! s6 \$ U
  131. STA PPU_ADDRESS
    3 Z& s5 d7 x$ t  O" w7 g$ B7 e2 D
  132. LDA #$00* G" u2 S5 w9 h: [+ a" u) `
  133. STA PPU_ADDRESS
    + e1 A) i3 ~* C1 G/ x0 G
  134. LDX #$00; _2 M) D* X1 {: e  J; b8 x. K7 P+ E
  135. Init_Palette_Write
    5 F/ V+ A: Z2 n9 t5 R
  136. LDA Palette_Data,X
      Z& o! I) B. v9 ^6 J- S: p' A
  137. STA PPU_DATA) f  l$ |6 g' V6 u# j: d
  138. INX7 g* `- W0 ?  P6 ?0 A7 n$ N6 ]2 k# _
  139. CPX #$20
    ) D% o) [0 j8 f! X
  140. BCC Init_Palette_Write
    " C9 z5 R# N0 n
  141. RTS
    + o) K( R/ n0 z3 v% f

  142. $ {6 v& |+ n4 q% s# {* s
  143. ;==================================================
    7 E: Z0 j6 N! p! h, Y
  144. ;设置命名表属性
    9 _; A+ Q+ _( Z, z& h
  145. Init_NameTable_Attributes0 v1 L& G( Z. p- A( D
  146. BIT PPU_STATUS! P# M3 a4 |/ Z( }6 z: s- [2 g
  147. LDA #$23
    $ y( X7 Z0 q  ~
  148. STA PPU_ADDRESS6 c1 s& M: g, m) m' `2 m& a# s1 h
  149. LDA #$C0& g7 `0 d. B; v5 M1 q
  150. STA PPU_ADDRESS
    3 o$ X$ y% h/ o9 F3 C  r6 \* e: l2 }
  151. LDX #$00+ G& S9 [6 V3 X. J4 c- |$ S! A
  152. Init_NameTable_Attributes_Write) h% [) _4 f, V0 R: I0 {7 s3 R) w
  153. LDA Attributes_Data,X
    : e( Z' S. I1 F4 D) q, @
  154. STA PPU_DATA
      f2 N- g& J; f0 u
  155. INX4 o5 L2 U7 e8 k2 P
  156. CPX #$40
    + V$ u! d/ q! W3 d
  157. BCC Init_NameTable_Attributes_Write" c, n+ x3 C$ p5 _: Z
  158. RTS4 n" ~6 w5 |% c+ Q/ w
  159.   X4 {3 j  O' I0 |% C* `
  160. ;==================================================/ Z, ~, A! Z' }8 N
  161. ;初始化命名表文本* a" P7 G" U. R6 T8 J8 M
  162. Init_Name_Table_Text% y3 R1 O  t4 y
  163. BIT PPU_STATUS1 O! N" t8 w- P( s( z' U
  164. LDA #$20
    1 {& u. ~/ g$ t+ |' F0 b
  165. STA PPU_ADDRESS
    # ^& N; V" @# _+ z3 K
  166. LDA #$00
    0 t0 k( e! q2 L/ m& Y/ g
  167. STA PPU_ADDRESS
    2 q, r6 v' I4 ]4 o# z- g
  168. LDA #$002 V3 O# u; i+ ?: I- [5 a: i  m
  169. STA FC_Data_Buf; ?9 D# ]! N: H4 @
  170. LDY #30
    6 T: x7 `& t/ M+ o3 L; O& {
  171. Init_Name_Table_Text_Write% i0 T' H5 V8 j  y  \
  172. LDX #32! w' z! V; P  c, v
  173. Init_Name_Table_Text_Write_Char
    : W/ S( R- Y+ T1 E( I3 V  ~
  174. LDA #'0'# f6 ^- m2 s/ P
  175. CLC5 ]; f( P& C( C3 W% r! @
  176. ADC FC_Data_Buf
    ' V. r( o) N  h0 e8 c
  177. STA PPU_DATA
    6 E  R$ R$ C* S) x
  178. DEX
    % u8 r1 I; ^. `% }$ Z
  179. LDA #$14
    5 W% E: y& g9 q9 ^! i9 P) E  ^; j
  180. STA PPU_DATA
      E& E4 c8 K' w* o4 w  s& x  v3 n, h
  181. DEX
    $ R# l6 K  P* J. B8 l6 l$ g# n3 [
  182. BNE Init_Name_Table_Text_Write_Char8 L  m0 p1 Y5 `# s5 L
  183. INC FC_Data_Buf# ~" x) T) b% c5 V7 h1 P* s5 U
  184. DEY
    * m  C3 C. W$ Z2 ]
  185. BNE Init_Name_Table_Text_Write8 f! I9 H: ^" N, K& r
  186. RTS+ d! {) i, E1 y! a6 R, s
  187. - Y' h& l( i+ D! w; y
  188. ;==============================
    5 g% n9 n# `) O/ }
  189. Init_OAM_Ram;初始化精灵内存
    9 `9 g: I# u% a  Q+ B
  190. LDX #$00& D/ L9 @' D' T7 H9 d
  191. LDA #$00
    " e( f+ S  N: k- }) x
  192. STA PPU_OAM_ADDR0 S: ?/ J# e+ h% @
  193. LDA #$F8
    3 }* t8 |: N% I  B( r
  194. Init_OAM_Ram_Write
    & t" Z9 e2 C0 z$ h6 ?* |/ A& j; s
  195. STA PPU_OAM_DATA
    " B" x. l1 ^8 O4 B0 U6 y
  196. INX
    8 u& Q& y$ s% M5 k  g( T9 ~
  197. BNE Init_OAM_Ram_Write4 M/ t' s* ^# E: p: z
  198. RTS
    / g9 R7 o( A2 U# S( C

  199. ( z, ]2 A0 ]& I8 u0 z: d- I4 N
  200. GamepadProcess;手柄处理6 |* s6 y. U. j
  201. JSR GamepadDatacan
    + a) y( _# \* l& ]3 e) b. K% D0 @
  202. LDA <Gamepad_0_Value
    : J% ?! T  w* t) A0 h7 ?3 d4 E
  203. STA <Gamepad_0_State
    " ~  x0 H! D1 j% A/ `
  204. LDA <Gamepad_1_Value- J9 J7 T6 o8 R' D2 p
  205. STA <Gamepad_1_State  f( h& `9 G9 ~* D; P, m3 f
  206. JSR GamepadDatacan$ v( f( N# P; Y9 c4 @! E, r
  207. LDX #$01; ]/ {0 S% T# I: H
  208. GamepadMergeCheck;合并手柄输入检查) C0 Q+ w  P5 q
  209. LDA <Gamepad_0_Value,X( |9 V9 \0 i. {% |
  210. CMP <Gamepad_0_State,X# |! R9 m- q! w+ g
  211. BEQ GamepadMergeInput+ |: V4 h+ l! K( B* U6 O: w; u
  212. LDA <Gamepad_Temp,X" q" Y; \% }! A. n# B
  213. STA <Gamepad_0_Value,X) M& G6 C: {- {. I7 |  b$ W
  214. GamepadMergeInput;合并手柄输入
    ; P4 g" H6 A7 y$ |( m* K
  215. DEX
    % |' h5 P- {, U- q4 A
  216. BPL GamepadMergeCheck
    * d# a) G) }; G
  217. LDA <Gamepad_Merge, _9 d( o0 f" r+ b# x4 n! h; L$ D
  218. AND #GAMEPAD_MERGE_FLAG7 [) J" x! L* L+ N' d3 w
  219. BNE GamepadStateProcess& i7 k  i2 X! _* b, l
  220. LDA <Gamepad_0_Value. c. w: j8 o, X  w. g: S% {
  221. ORA <Gamepad_1_Value+ Z" y8 g; v% z% }- y' y
  222. STA <Gamepad_0_Value
    8 c+ ]' {  Z* t; F3 x: Q5 v
  223. GamepadStateProcess;手柄状态处理. ?$ O& G9 O/ R& B9 S. M) a
  224. LDX #$01$ l8 {, [; d7 F" i5 f
  225. GamepadStateSave;手柄状态保存
    . Z+ j9 c. O$ ?7 d4 V
  226. LDA <Gamepad_0_Value,X, S" i* K, @5 @
  227. TAY
    2 ~5 H( }/ K- B7 d$ Q
  228. EOR <Gamepad_Temp,X
    ( @0 T/ W- U0 I$ ]8 T7 R
  229. AND <Gamepad_0_Value,X- j% K% r# t5 g# M' W# i  L
  230. STA <Gamepad_Once,X
    , Q# e4 @) d# |8 G$ X  c! j6 M
  231. STY <Gamepad_Keep,X
    2 J% z$ z7 K) N7 u* Z; i
  232. STY <Gamepad_Temp,X- Z& G+ }5 ]; ?4 ], s4 ?0 k& O4 k
  233. DEX
    : ~/ O) U) b0 p. |7 i( @: l; U
  234. BPL GamepadStateSave
    : J6 e2 F6 h- @2 o9 S$ _
  235. RTS
      V: A% _8 Y" U7 z3 q. p* a
  236. . \6 x, H: z! Q6 l+ h
  237. GamepadDatacan;手柄数据扫描
    1 a" ]% I  w: T% ]
  238. LDX #$01
    + \" X# ^/ W, S. b" u- {4 j& U/ D- f
  239. STX $4016! `0 g# B: K7 F3 z
  240. DEX) h! A5 |# Y0 O) C, k# u. c
  241. STX $4016
      U5 D. d: u( ]
  242. LDY #$08- p3 {. C# a& F3 v5 q! ~
  243. GamepadPortScan;手柄端口扫描& Z9 Q* A0 w: d1 l- N! O
  244. LDA $40160 k( K/ @3 c# K! q$ [" T- r
  245. STA <Gamepad_Port_Value
    , b2 L0 I# T3 [- y
  246. LSR A+ Z# T- t) I! i: [, H
  247. ORA <Gamepad_Port_Value% M: y& O" w9 g) [7 Q
  248. LSR A
    , p4 h/ a2 {5 n4 l# ~, Z% R0 j. |
  249. ROL <Gamepad_0_Value, {$ O: @( G! a0 r( ]
  250. LDA $4017( q+ J) o& V8 |( f0 ^
  251. STA <Gamepad_Port_Value
    $ S/ g  l0 q' D8 n9 w9 i5 {
  252. LSR A; c* _% `9 {: F' |0 Z& s5 i: A
  253. ORA <Gamepad_Port_Value6 O& R( K( h7 a% ]* b, t% ?
  254. LSR A
    6 [- Q" p+ G5 s' p& k" K4 O" a
  255. ROL <Gamepad_1_Value7 C  l  \% D+ d
  256. DEY
    . V* Q4 {) ]7 G/ G" i9 I1 L
  257. BNE GamepadPortScan% H1 l; f. z" ]/ C. K2 V7 H
  258. RTS
    3 t/ `3 e% d( E1 E& [) j3 ^
  259. % C* S' b3 {+ A9 n& F8 M7 S
  260. ;==================================================% `( m8 V5 k! v$ s
  261. ;PPU处理: ?  j7 j6 q: I* u0 Q  B7 W
  262. PPU_Process1 O9 P9 |# x% G- a
  263. LDA #$001 R3 @& N9 A" K- J% V7 J+ g; ?
  264. STA PPU_MASK( S: o  `5 c6 a. _5 J4 ^2 c

  265. " b9 e5 A7 E6 G4 h7 }/ n& y+ v8 A0 ?
  266. BIT PPU_STATUS2 F2 X# f  K+ x+ ?
  267. LDA #$20
    / V( |( U" x6 [8 B/ u8 ?- a2 ^
  268. STA PPU_ADDRESS
    5 u' _7 I3 ?: ~" v" u
  269. LDA #$00, m6 D2 w- g, }
  270. STA PPU_ADDRESS
    : H2 Q1 X" i7 z8 V" R7 l
  271. % H( @1 F( q* i+ f3 m
  272. STA PPU_SCROLL( b$ r% y) z3 `' [% t) \  z
  273. STA PPU_SCROLL5 O% E7 |$ d6 m. M

  274. ) c) u. a" f7 l/ |
  275. LDA PPU_Msak_Buf2 w& W8 s& R' w
  276. STA PPU_MASK
    9 W+ X4 C" W! q4 e. g2 |* Y

  277. ) i5 v/ @2 K" ?- p3 u
  278. RTS
    * N; N2 d2 z2 @/ r1 W1 |& r) H
  279. , e1 ]2 W$ d( m6 m# z
  280. ;==============================' s" Q( o% b$ t! N2 N
  281. Time_For_Vblank;延时等待
    3 W0 I& q: P) s/ P2 s
  282. LDA PPU_STATUS
    ( h9 U, t. |  @: w! g
  283. BPL Time_For_Vblank, w3 w4 [- E& [' H3 p# ?1 ?8 U/ T
  284. RTS
    - N5 j8 p3 o+ w3 B

  285. 9 n, D  _  J0 A3 s+ f- u0 I% x
  286. ;==================================================: I+ K* b% z: q! @- k: q
  287. ;初始化MMC3
    . k; j3 `/ Y! Q8 c
  288. Init_MMC3; q, a4 ?, c& {! o0 H
  289. STA MMC3_IRQ_DISABLE' ?8 r+ }( v( Q' S! M% Y

  290. 5 @8 W, Y& d4 W* i2 ^
  291. ;设置MMC3水平镜像
    0 ?- ]3 [  \4 R" C
  292. LDA #$01
    9 L- X' N' F7 N
  293. STA MMC3_MIRRORING4 J  {7 n$ |0 Z
  294. 4 X+ Y# _# Y& M- \3 e; d: i
  295. LDX #$05
    ( F# L" F( H! m- ]% U. z
  296. Init_MMC3_Chr_Bank_Write) ^! P* O' T+ f. s% X+ _3 P2 l( c
  297. STX MMC3_BANK_CTRL7 |- f6 F' V5 ]& R: O: t
  298. LDA MMC3_Chr_Bank_Data,X
    + G7 e) t0 d3 e; C4 k# T- o, _" H
  299. STA MMC3_BANK_DATA! ?" }& L. f; N% h2 m! n
  300. DEX- m, `6 ^2 G$ E: C2 v0 s, b
  301. BPL Init_MMC3_Chr_Bank_Write
    5 q  y/ \1 ~* \- v
  302. RTS
    " P* ~  f8 X9 f- m7 p
  303. ;--------------------------------------------------
    - ?. o# G) C/ Y% B  z1 n. C  N
  304. MMC3_Chr_Bank_Data9 L  Q' I% h9 ]1 p6 g
  305. .DB $00,$02,$04,$05,$06,$07
    9 }  |, w. T+ ^/ p8 {- B
  306. 5 w3 B0 D4 M  b" J7 c/ w' t
  307. ;==================================================
    ( J/ K' t( H: S6 {
  308. ;重置中断处理
    + k( |4 \" {/ n6 ~# q7 d- R2 o
  309. ResetProgram& i: t  A9 |3 {. B
  310. SEI3 K* k0 p* X3 `; u+ r; o$ l
  311. CLD
      @! Y" o! w8 s9 |4 C# M
  312. LDA #$00) j5 @4 U' D: [" z, N5 X* O7 m
  313. STA PPU_CTRL! q+ S8 o7 d; q- G. `  G; c* v
  314. STA PPU_MASK( @, Q$ y3 [7 r9 v" R2 z- u
  315. STA PPU_STATUS6 _3 j. K* z+ p2 T
  316. STA JOY2_FRAME" a+ o( z6 V; U6 G$ i+ D
  317. STA APU_STATUS+ ~4 d, v( x% l, j" ^: n2 v. r

  318. ; m/ ~/ F$ m1 W& ?6 ~2 N
  319. LDA #$C0
    $ Q/ x0 B: A5 v7 K
  320. STA JOY2_FRAME0 ~6 z" W/ G3 [/ l5 v5 z

  321. ( Z  R' [" k) f/ |6 Q* S2 v' X3 C1 L1 C
  322. ;等待vblank6 H* M% W( |  L  P7 g
  323. LDX #$027 c: ]/ U" F7 _
  324. Vblank_Wait_1
    # u9 \4 t1 S$ J" ^
  325. BIT PPU_STATUS
    # O! ^* s& t) A, X/ P
  326. BPL Vblank_Wait_1  Z5 e& f9 E8 u5 X2 K7 y; k
  327. Vblank_Wait_29 Z/ }5 t0 Q" V  J8 I
  328. BIT PPU_STATUS
    ; H8 m, X( G& q# B: p( `1 K- t
  329. BMI Vblank_Wait_2
    6 ~2 w- D9 E+ S2 @
  330. DEX
    " {5 E( m! E. F
  331. BNE Vblank_Wait_15 M( U4 ~1 e5 W

  332. " [+ o* j7 y. f* y
  333. LDX #$FF6 n6 {7 O4 C9 i2 z  V
  334. TXS1 b( @  u$ G# v1 T

  335. 3 x- p# B/ N6 s/ I- v4 o6 F
  336. ;初始化MMC3
    ) f, f2 G" \1 o) T8 d* K
  337. JSR Init_MMC3
    . M3 E8 W9 B# N, \4 F1 W, Q5 G* G

  338. # h9 P! ~% q" |8 P% }9 G
  339. ;==============================  x2 D! |3 Q7 `4 d
  340. ;RAM初始化
    9 Q! f: B2 d7 P& y: Z% M
  341. Nes_Ram_Init: n9 u; ]3 ^9 @
  342. LDY #$00
    ) w8 p; K$ D* M( q6 G: ~$ Z" N
  343. LDX #$08. w# q6 G0 _5 V" L  [! y
  344. LDA #$00
    3 _% j- D" ^  H/ o  N8 Z
  345. STA <$005 j( e, ?$ M6 ^& C- Y$ z
  346. STA <$01$ z" i- H; a4 F- W( }5 H
  347. Nes_Ram_Init_Write4 o0 Z2 q7 F: X( ~2 w9 R5 n
  348. STA [$00],Y
      g; l8 J2 p3 w# z# l5 T
  349. INY
    8 d- ]) f3 {1 L$ V) w
  350. BNE Nes_Ram_Init_Write
    / f. D. B& _  i9 B9 e9 O1 h
  351. INC <$013 n, Y# p' j" F# g, F$ }( R) w
  352. DEX
    # [; r! j$ f2 t; q4 y7 ]
  353. BNE Nes_Ram_Init_Write) r2 W! w  Q# j5 _) f

  354. . `/ A& Y3 a% K9 B
  355. ;初始化命名表
    / ?. q3 q) f: _8 e% x* f
  356. JSR Init_Name_Table
    . s- I0 Q3 X- C% D3 L1 f6 O0 H

  357. 2 O. O* ^9 j+ N0 g) e. k
  358. ;初始化调色板$ t! b8 C/ c% z0 Q. c
  359. JSR Init_Palette: `: u% _! a7 \9 e  R2 O( D
  360. 3 x3 L6 D8 m8 F! t. S, F+ f0 V0 D
  361. ;初始化命名表属性" M1 h) F7 ~% t
  362. JSR Init_NameTable_Attributes
    ) m, v( y: Z# i

  363.   i" S) G( B; I9 R4 j2 X
  364. ;初始化精灵内存9 g1 t/ c) ?! U& z8 A2 t
  365. JSR Init_OAM_Ram
    3 T$ t6 m) Y; y8 M8 L. Z

  366. # ?% U  S  d7 c7 Z/ K& K) z
  367. ;在屏幕上写点东西! x" H, B6 o& g/ s+ o
  368. JSR Init_Name_Table_Text3 o2 w6 y, J# L# B

  369. ; b5 H! }0 u# X, L* Z) M3 S& [- ]4 G
  370. JSR Time_For_Vblank
    / ]2 D" V1 S. |- ~7 j  k
  371. ;开启PPU控制0 ~8 T! e7 h& f" @) W  Z6 s$ O. |
  372. LDA #$804 H" U& o) h# m( P- M. `
  373. STA PPU_Ctrl_Buf! H8 W& ^4 g) K. r' R
  374. STA PPU_CTRL, M8 O4 \2 e. l/ w

  375. 9 Y& b# ?0 Y0 @; O
  376. ;开启PPU显示
    / _7 S* F' ?* [8 J
  377. LDA #$1E4 E4 q1 @5 V4 a8 V/ M
  378. STA PPU_Msak_Buf; L0 [5 b) |/ E, W
  379. + g/ @. {& V- s9 w( e
  380. LDA #77
    + w$ o5 N* A; c- o
  381. STA Sprite_0_Y: \# H% m( k% t8 Q% X" T
  382. LDA #$1E9 h( O5 d$ R* I
  383. STA Sprite_0_Tile
    8 m6 b+ ]0 ]% O
  384. LDA #$20
    " D; n0 z6 w8 n' n9 c5 c
  385. STA Sprite_0_Mode3 @1 E4 [6 L2 j- f
  386. LDA #$00
    8 g0 ]- x2 u4 x& u6 _
  387. STA Sprite_0_X6 C4 H+ u3 Q8 V, n) N0 [

  388. & n  U4 i0 C9 Z, t/ r2 j" z- Z
  389. CLI7 A5 i0 t- d* ~4 D! F" `  Q# S1 P
  390. JMP Loop9 k% d0 ?: O9 p% }, R; N8 {/ ?9 ?" D5 F

  391. 1 x2 E. \2 B1 f, r+ w5 K
  392. ;==============================. a1 W# w) M, {7 S  H' Q8 i
  393. ;死循环, 等待NMI中断5 ~  Q6 t# G, @
  394. Loop
    % V. A8 `( N! _/ G$ T( |% T
  395. JMP Loop; _* Z* V) ~0 y" S: L& _0 o% R' C

  396. " A) d7 Y& e! J/ a
  397. ;==================================================
    - s/ Q( `/ y- K  D! i' `8 B
  398. ;NMI中断处理  e6 W5 L! K! t; k
  399. NmiProgram) u8 H8 m0 P/ o7 g7 z$ e3 H) ?
  400. PHA
    . \$ E( v% E$ H! k
  401. TXA
    + {. f, f+ d4 l" T) _4 i9 p. ^
  402. PHA* U' c0 a/ l" @9 w4 X( K! g2 e# @: p
  403. TYA
    $ O6 P9 m0 m9 P- O2 Z
  404. PHA6 I; ]& `- d5 H* ^

  405. ; B7 }+ C) ]+ f0 V3 [
  406. BIT PPU_STATUS/ d8 M3 d1 Z; I" i: r1 [

  407. 5 j) n3 V; j7 }4 t7 J- J
  408. ;关闭PPU控制
    / Z( M& s" X7 m: S: e
  409. LDA #$00
    3 s2 R: b) {" N
  410. STA PPU_CTRL2 n5 K: u9 I3 J  w( D

  411. " f$ R/ }: V+ V6 k  [0 N- {# r
  412. ;处理PPU3 [. F$ v+ g$ H7 ]* i0 X
  413. JSR PPU_Process
    + f2 R0 X1 |- Z+ A1 i% w

  414. : L- \, k+ x8 G. \6 R
  415. LDA #$00# m% _' z' _+ ?
  416. STA PPU_OAM_ADDR
    % `5 \1 }- X) ?1 [) M3 a2 f: i! g
  417. LDA <Sprite_0_Y1 M* ]4 X- e6 X2 N6 ^* M
  418. STA PPU_OAM_DATA
      w1 H" C: H' D. {, }
  419. LDA <Sprite_0_Tile
    0 J. D" C) K; Q
  420. STA PPU_OAM_DATA9 C/ g7 [. G' M+ K
  421. LDA <Sprite_0_Mode
    ' P8 x6 f$ I5 A4 ]- H: i
  422. STA PPU_OAM_DATA2 U' g+ s2 B0 _
  423. LDA <Sprite_0_X7 |$ }- \. u2 F$ T5 h. _
  424. STA PPU_OAM_DATA/ K: _( _- S+ {3 w; R8 ?; A8 j4 s3 G

  425. 6 c0 }; J6 k' y* I" A
  426. ;开启PPU控制
    8 R" @* Z6 f  S9 p
  427. LDA PPU_Ctrl_Buf
    . Z& h7 ]* z8 t3 W' u
  428. STA PPU_CTRL
    6 A6 V- c7 i/ k# \
  429. $ h$ R$ `2 `; V" {+ C) V8 B; b
  430. ;屏幕滚动0 t9 j, S; S+ M- J: G2 d, S- S
  431. LDA <PPU_Scroll_H4 b4 i$ |5 y: f5 ~% W! U2 Y
  432. STA PPU_SCROLL1 N" v2 U( E* f' K
  433. LDA #$00
    1 @; I  f% z( H! T0 J
  434. STA PPU_SCROLL
    & m% B) G5 H5 `0 Z" J- X2 W+ I7 H. Q

  435. : ~" v- o( K8 U, H+ E( G
  436. ;手柄处理% R! n  q$ ~$ K/ J9 M
  437. JSR GamepadProcess
    3 a; M& X% x# N8 a: t: S  l
  438. 9 o. \# R4 T: V7 C
  439. INC <PPU_Scroll_H
      m$ K: C' W# a8 C1 L
  440. + t$ P3 P+ g& b% C
  441. ;启动0号精灵碰撞检测) ^5 \, I2 _- g1 Z$ Z" b
  442. LDA #$01
    ! q5 k, S3 W7 |' E% R; h9 U
  443. STA Sprite_0_Hit_Move_Direction: C2 m1 V7 z& W  u. W# [: s
  444. JSR Sprite_Hit_Test+ Q9 [1 Q, `9 ?2 O5 Z! [
  445. , h2 G' I- P& u: |. g
  446. PLA' \* n4 t! q$ v$ V3 H
  447. TAY
    7 W4 m' U0 N5 c# o9 \4 z
  448. PLA
    " U; z5 [7 `% F2 ~% W
  449. TAX
    $ p* D' M8 ]& r8 Y8 b8 Q
  450. PLA
    6 Q% E3 K7 D7 h, g: G2 A4 [
  451. RTI
    6 f1 A& d: [" F7 M, |0 O0 y

  452. + V- ?! w2 E: K5 q* P& X) B
  453. ;==============================9 Z, z( }3 b! ]+ f
  454. ;0号精灵碰撞测试
    ' p! `. j1 U8 ^. d' w( b- Z; E( |
  455. Sprite_Hit_Test
    $ v) s& b4 {( M3 Y: b1 G
  456. " V8 M) c4 A+ F2 p; I
  457. ;------------------------------9 ~, M3 _% P2 x( P- P
  458. ;等待0号精灵碰撞状态取消
    $ D) X/ U9 m) k7 H# E7 I
  459. LDA PPU_STATUS
    6 j5 ^" D* ?* e% G# P
  460. ASL A1 _, C! H2 A* O7 D* V7 n- i
  461. BMI * - 4$ K- x& d8 E' F" l' |

  462. 0 e7 P" b7 k) L6 J) l
  463. ;------------------------------& c1 O6 [! t2 S+ F( {  |  B
  464. ;等待0号精灵碰撞发生* n! t: v. R  k  }/ A- d% S" u! U
  465. LDA PPU_STATUS3 N* i5 j/ y, X9 {2 |: l1 i
  466. ASl A
    ) S% m/ S5 W1 O' j2 }
  467. BPL * - 4
    . Y2 V3 H1 @- T) Y

  468. ) x& x: b% [  H
  469. ;------------------------------' t! r8 z- I8 `6 k- Z% ]- q1 n
  470. ;行消隐等待) q  }* K/ |- e+ k! F4 h
  471. Sprite_Hit_Scroll_Wait7 I8 [. L; i; [5 Y; P
  472. LDX #$28
    6 y, b8 z+ s1 x" c* w" _
  473. DEX, Q$ M2 Y2 a: e* Q
  474. BNE * - 1/ g- e: r% J6 q% d) R# e  b

  475. , v' m) f! `% u# x' W& n$ ]& _
  476. LDA Sprite_0_Hit_Move_Direction
    ; R2 Q7 T+ a( K5 t$ Z+ g- ~
  477. AND #$015 ]/ }  {6 b& _9 h7 E
  478. BNE Sprite_Hit_Scroll_Set_Right  ], [' k. V8 q5 d; a0 a9 `
  479. 7 P; b6 b0 W: f- G! Q0 J! @
  480. ;------------------------------$ d, z4 I$ z. ?) e! _9 ?" H+ X$ [
  481. ;分割画面向左滚动
      s+ X+ \7 e6 o$ _% b8 N+ @) \' K
  482. Sprite_Hit_Scroll_Set_Left
    . ]5 a, Z4 N9 H* H
  483. LDA PPU_STATUS
    8 ?  Y* P5 s! w! {) _( L; K
  484. LDA <PPU_Scroll_H
    + F; P) H8 K7 w+ Y% |
  485. STA PPU_SCROLL
    ' H5 @" \, f3 W( ~: X, r, _4 F
  486. LDA #$00' y' a- J$ a; g% v, k) f
  487. STA PPU_SCROLL
    * I$ r+ r2 r4 I0 S3 K# k
  488. RTS
    " L0 J& S7 S8 G$ l

  489. / B$ B' v$ [/ N% q
  490. ;------------------------------# D4 I2 c  j4 g5 m! s. E/ p
  491. ;分割画面向右滚动) D9 |* E7 G+ c* T% _% e. m; O
  492. Sprite_Hit_Scroll_Set_Right* }9 G7 l% r/ |
  493. LDA PPU_STATUS
    4 c+ D; n% l3 B% `# c
  494. LDA #$004 `( u( A" b- j# `2 d1 z1 w+ C
  495. SEC/ L/ V/ n2 L' T) T) ]
  496. SBC <PPU_Scroll_H
      p- H% ?; |2 g" ^  y, U! a) S
  497. STA PPU_SCROLL
    # ?' E4 D& F/ U: [2 V
  498. LDA #$00
    4 L: |  H4 o6 _
  499. STA PPU_SCROLL# n9 t1 \3 R- L; s, ]
  500. RTS
    ! b9 O3 F: a& Y3 g

  501. ! J0 D0 P- N& S) V
  502. ;==================================================
    ; H% \9 m2 L1 g$ G2 q5 Z
  503. ;IRQ中断处理1 [" m* o2 r. G
  504. IrqProgram! q2 M& E! T0 V$ i8 m9 [
  505. PHA* w( s1 J% n1 J# d
  506. TXA5 C6 I4 C' q9 k6 ~* Z) `
  507. PHA
    5 Z. f% u, l0 i' A, J0 p+ }& k
  508. TYA
    ( p+ T* K9 x. z. ]# M8 S& {1 a
  509. PHA
    3 y: {# ~+ K8 h7 i

  510. 1 s7 o( R8 U! o/ p/ d. I
  511. ;关闭IRQ" Y6 Y2 C( A" p3 _! Q9 ?! I8 N7 X. t
  512. STA MMC3_IRQ_DISABLE; I+ x2 B1 y( P4 e* [4 H
  513. 6 @" e/ f1 G- t' @9 e- t
  514. ;允许下个IRQ触发$ M& m% u) U3 q# h8 S7 }
  515. STA MMC3_IRQ_ENABLE
    + ?0 o$ @& X1 i
  516. , d0 r' c7 L  b+ G( M9 o
  517. ;IRQ处理, 15线后继续触发2 [! {8 D" U6 K0 A: `) o
  518. LDA #15
    2 ~3 V/ L; g+ O# a2 s" s5 F( p# \5 ~
  519. STA MMC3_IRQ_LATCH; s$ @. k% |. ?" V  E+ E! y4 k

  520. . h  }) B+ H# {
  521. LDA <IRQ_Index
      D2 E2 f! f# T- P" ]
  522. BNE * + 4& d/ x7 }9 u) |; d9 d) v
  523. INC <PPU_Scroll_H3 t$ N' w+ Z* D( Z! C" S" `: Y
  524. 8 W+ e: B$ N2 R+ L0 i! D- V
  525. ;设置屏幕滚动
    ) z4 ^1 w* [5 e5 W
  526. LDA <IRQ_Index5 _5 ^) e# r7 @: C" G1 S
  527. AND #$01  ^  k0 a& H8 Z) T' j2 l
  528. BEQ Irq_Scroll_Right9 P; x4 d! c: M% U
  529. 3 \8 {' q* g  ]' G
  530. Irq_Scroll_Left. y/ a# t: @/ J3 L1 Y, u
  531. BIT PPU_STATUS
    & p! Y7 b+ u% r& P8 V% f. V
  532. LDA <PPU_Scroll_H
    ) U2 t. E2 j2 l8 e) F/ J
  533. STA PPU_SCROLL
    6 K/ B; L! n3 w
  534. STA PPU_SCROLL
    8 ]( ]- Q, ]% D( J
  535. JMP Irq_Scroll_Over
    ! ^$ N, h( }8 A  H( [; Y
  536. ' t6 J) f3 R1 l" Z% ~  ~
  537. Irq_Scroll_Right7 q# t+ V, y4 t% h5 f% d( U' b# u
  538. SEC
    # O4 s6 w4 ]: @/ L  h
  539. SBC <PPU_Scroll_H- w1 ?3 p) D. s5 L2 {+ R7 h8 l# _
  540. STA PPU_SCROLL9 A. B2 V/ R7 c  t& G. W# I
  541. STA PPU_SCROLL
    + [9 t8 Q$ m5 \" i9 J: @3 N. D! o% C
  542. Irq_Scroll_Over2 Q: z) B' W( H9 p7 j

  543.   I8 y8 Q4 D! d( r
  544. INC <IRQ_Index
    . P% m* ]7 |8 g3 L" L! ]

  545. 7 F6 z( G& U6 F, P
  546. LDA <IRQ_Index
    7 |& }0 m6 g" G
  547. CMP #14* G$ e+ ^( I; C3 u- _
  548. BCC * + 5
    + Z. ^, x. B0 S$ f0 F( |
  549. ;关闭IRQ
    ! \$ R( F; Y6 Z  ]& w
  550. STA MMC3_IRQ_DISABLE
    % b  G" F1 s$ }% S$ O+ i! ?
  551. / `3 U  Q2 {% x1 h3 \
  552. IrqProgramEnd$ ]' a3 {0 o5 G6 u% a, l1 N  q! M
  553. PLA
    $ Y4 t9 ~; y% |# D+ M& r; w
  554. TAY" b& m; l5 F1 K- x0 p5 O
  555. PLA7 \5 n2 |, c% }+ G# \4 A
  556. TAX
    9 X6 Y/ E8 R3 Z) b6 p0 }
  557. PLA
    - q9 X( H' h/ u: k* @
  558. RTI* }  f; U  i% j& w0 r  `& i
  559. : z+ I- k5 N: R- _: _7 J- @; j" K
  560. ;==================================================
    $ [7 R8 o9 t/ e8 Q) ^9 u  f# w
  561. ;中断表
    ' o+ h7 Y' S) [. T
  562. .ORG $FFFA
    0 O% u: Z4 l1 d9 F
  563. .WORD NmiProgram
    - `( F7 K( O) @& ]/ E5 a
  564. .WORD ResetProgram
    1 h. k+ I( c. [' p4 B6 J2 l
  565. .WORD IrqProgram
复制代码

; o  |; w+ T6 j0 O3 e

评分

1

查看全部评分

[发帖际遇]: yandagui 在论坛发帖时没有注意,被小偷偷去了 3 个 柠檬. 幸运榜 / 衰神榜
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-5 14:02 , Processed in 1.086914 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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