EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:17:53 | 显示全部楼层 |阅读模式
  1. ;[FC][MMC3 精灵碰撞]/ K  b" H$ X9 ]" \
  2. ;FlameCyclone 20230710
    5 m2 l3 \, K9 N0 ^

  3. 4 e! o/ B* e* G, l' C0 V. X! t; l
  4. ;文件头
    & b1 Q7 n: H# \  a& ]# c
  5. ;======================================================================
    8 Y8 \2 ~# q0 m+ i7 N
  6. .INESPRG 4                                              ;16KB PRG 数量  c1 ]) ^: v9 [6 b0 r' Q! `
  7. .INESCHR 1                                               ;8KB CHR 数量
    " g4 v0 s) S# L1 u# U
  8. .INESMAP 4                                                   ;mapper 4
    6 X4 f; |+ {1 o6 q# a
  9. .INESMIR 1                                     ;命名表镜像 0水平 1垂直
    * m2 N1 q* e& h! q7 I
  10. 7 J. ~3 s; I; D+ O6 F7 F7 P" Q8 M
  11. ;必要条件/ o. o% v# |& ^' [
  12. ;1.持有CHR ROM
    4 O* ]4 N5 Q% F
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
      {, c# F" r6 Q5 t! W' l
  14. ;3.精灵内存(OAM)不为空
    + }* s" B2 N! Y. y- A) f9 `

  15. . y- M! O6 a: g
  16. ;==================================================0 D1 T) x2 ]2 _% l
  17. ;NES端口常量
    . n1 D% M  ?" I& l8 [, ^
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    " C: i0 Z; k' ]+ D# a- R
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器4 C3 d) o' V7 T+ u" h
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
      }8 u! j, {$ _
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1% p! S# A2 d3 b/ N# y
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    8 w! a: K) v5 U3 I& \. m: i5 b' k/ d3 C
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ! K9 K1 S* G" w0 c9 w
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加+ P  K' Z" M2 k
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    : I( ?3 O) N, \  [- t
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存+ F1 n6 Q6 G$ m1 R
  27. APU_STATUS              =   $4015   ;声音通道切换* }1 X8 Y, R- h* \
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通3 K) n. M% j2 g! p6 @2 P6 ?* H6 C0 }
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通8 N$ X! j. x4 `8 s1 i  K
  30. / n* L- y& Y% i
  31. ;==================================================, w1 ~$ ^3 C* I: r* s' a
  32. ;MMC3端口常量# A" s. d! [, x. t* h) W9 R2 R; y
  33. MMC3_BANK_CTRL          =   $80006 p1 e/ i# O0 n+ z
  34. MMC3_BANK_DATA          =   $80017 f4 S# W, s5 b9 |3 O, j
  35. MMC3_MIRRORING          =   $A0000 l' {% i, D5 Q! y$ {: O' D$ i4 S  K
  36. MMC3_PRG_RAM_PROTECT    =   $A001
    6 v* D8 }6 y& C$ f7 z+ \6 W
  37. MMC3_IRQ_LATCH          =   $C000- `2 y2 V( V6 s
  38. MMC3_IRQ_RELOAD         =   $C001# |% l! h* Q' t0 \/ @
  39. MMC3_IRQ_DISABLE        =   $E000
    ) M+ A2 `) ?9 \/ Y* }
  40. MMC3_IRQ_ENABLE         =   $E001
    % V" Z& v6 H# [% N! ]7 X
  41. 8 n! ]- W) q0 A7 i- W. \* L& g
  42. ;==================================================& ~5 Z, H3 s# G3 V4 ~/ ~5 `$ i
  43. ;程序块配置
    ! O& w# b# T) H; M5 M0 ?: d
  44. BANK_DATA_MASK          = $07
    * J% ?' D$ w. f* z% {; C" R6 j
  45. ;--------------------------------------------------
    . E( t4 q- d3 F: P7 P, a% K( @' |
  46. RESET_BANK              = $07
    2 r' c! C) X- V5 ~
  47. RESET_ADDR              = $FC00: x5 G& ?2 v: ?- H3 u

  48. ; f6 {1 R7 B2 \+ R* H" P- F8 c
  49. ;==================================================
    + o- u7 E- D$ X6 \0 x- k+ n
  50. ;图像块配置
    ) ]+ k4 [& K! d# I
  51. CHR_DATA_BANK           = $087 r8 [4 M  e3 A/ C: ]5 g
  52. 3 V* H/ x# F' |; p/ q
  53. ;==================================================5 h5 W/ I! |- }# p% b! }
  54. ;零页内存地址配置7 V0 b" R* w3 B, i2 s. P
  55. Use_Ram_Addr            = $80! ^* F  T5 g" ?+ a) P
  56. PPU_Ctrl_Buf            = Use_Ram_Addr$ q- q' }4 c; k
  57. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01: A; y9 ~  p) \0 A9 Z
  58. PPU_Scroll_H            = PPU_Msak_Buf + $01! X) E- F* q/ r- X  O
  59. PPU_Scroll_V            = PPU_Scroll_H + $01- R5 S9 l; S9 w/ V" w0 r
  60. FC_Data_L               = PPU_Scroll_V + $019 k& j1 K' t% Z! s0 y
  61. FC_Data_H               = FC_Data_L + $01
    3 w0 W6 P  L. t! x
  62. FC_Data_Buf             = FC_Data_H + $012 s/ e/ M% \* V) G
  63. ;==================================================
    . h* `3 g/ {9 V: P( H8 u. Q
  64. ) G) M6 o  {, ?. f# b0 c$ m2 L
  65. GAMEPAD_MERGE_FLAG = $047 J# L; B2 `9 _3 @  ~
  66. $ x6 h- u. v; a5 k* y
  67. Gamepad_Keep            =       FC_Data_Buf + 1
    ! U1 U' i0 m2 s$ I
  68. Gamepad_Once            =       Gamepad_Keep + 2: Q8 h; B$ j9 |7 O. c/ h" ^
  69. Gamepad_Temp            =       Gamepad_Once + 2% w2 l  T* e: v/ R; {
  70.                                 3 Q" p( G$ O# Q6 P6 a. R
  71. Gamepad_0_State         =       Gamepad_Temp + 2
    9 r1 K) J( s& @/ X$ ~2 r
  72. Gamepad_1_State         =       Gamepad_0_State + 1' z4 a$ Z9 c4 h  C  q0 A& Q4 K
  73. Gamepad_0_Value         =       Gamepad_1_State + 1
    & W, T3 z; {, f5 n
  74. Gamepad_1_Value         =       Gamepad_0_Value + 1
    ( R  S! a. k" C5 G
  75. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    + K! x0 q& r0 E) a* d
  76. Gamepad_Merge           =       Gamepad_Port_Value + 1
    + `7 U8 k1 q$ P( e0 M

  77. + T) z* w  u1 y7 _
  78. ;==================================================& ?7 Q' _0 D" K  k* |% l) U6 H
  79. IRQ_Index               =       Gamepad_Merge + $01
    6 m! V- }/ S) v" O
  80. Sprite_0_Y              =       IRQ_Index + $01
    4 \8 `1 D  o# G
  81. Sprite_0_Tile           =       Sprite_0_Y + $01
    * e1 Q5 ^. _) r8 p0 @
  82. Sprite_0_Mode           =       Sprite_0_Tile + $01
    / I0 T4 J" E1 ?6 D4 Y9 S, k
  83. Sprite_0_X              =       Sprite_0_Mode + $01
    6 s! i, w4 i, i/ Z# s4 O& Z
  84. Sprite_0_Hit_Move_Direction           =       Sprite_0_X + $01& G$ _8 d) ^  e3 R
  85. ;==================================================
    , w4 _' [. e. X5 q% A; ~* r

  86. " v8 I8 i7 z' I# u0 L+ @# H/ p/ K
  87. ;CHR图形数据/ U: f& P! j8 i& W" M3 d
  88. ;==================================================! {) n/ W  U; [9 ~( C% B( n) l
  89. .BANK CHR_DATA_BANK
    " r$ L: [. X8 M$ `& w
  90. .INCBIN "chr_bank/chr_data.chr"7 D/ t% z1 O* W1 M

  91. $ u" H3 F" \$ k$ b7 O4 {8 F$ b& q
  92. .BANK RESET_BANK & BANK_DATA_MASK
    ( Q7 Y! ?: b/ Q1 Q* Y8 C9 J
  93. .ORG RESET_ADDR- n' i5 K0 i" i( p
  94. % }. i( ~: w3 _. H' Z
  95. ;--------------------------------------------------
    ( y7 P2 C  f- ]/ @/ h9 f5 h
  96. Attributes_Data
      T5 z% N% a5 o7 n2 f
  97. ;命名表属性; F4 ^3 t- R! p8 n" s% c7 K2 `
  98. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00! I' z( ^& U# p5 M9 _
  99. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    8 n' n, H) L, F0 M% F1 S; a
  100. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA. w' `% p. ]4 U/ G
  101. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$559 q  D! ^$ T- w8 y2 E- _: M
  102. ;--------------------------------------------------
    0 B3 r5 x' l7 o' u
  103. ;调色板数据: ^+ \' j' f0 E7 s! m
  104. Palette_Data
    9 b4 F/ v9 ?' q* Q' K
  105. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F9 e& \* X4 B5 x9 a
  106. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    ! \+ v" i  x, u! ]3 C
  107. 4 B% V4 w( c5 w/ l8 E
  108. ;==================================================
    , i# L, @, e' X5 n* |$ o2 @- q- ]
  109. ;命名表初始化
    / U5 D, Y' N  R9 E1 I% u; b
  110. Init_Name_Table
    6 L- q) ~9 C5 b
  111. LDA #$20
    2 F$ i2 n$ `$ R  ]1 H; F' K- h
  112. STA PPU_ADDRESS1 {+ D1 L$ g3 t! b
  113. LDA #$00
      V( x1 |" m% \' h; h; m
  114. STA PPU_ADDRESS
    ; j1 D8 @) S+ v9 D$ @0 s- ]3 N
  115. LDA #$00
    ! {0 l2 o6 w% M
  116. LDY #$00
      K! \' }- [7 t; ^  ]) k
  117. LDX #$10
    . x3 u0 s, f* f: q; K$ s
  118. Init_Name_Table_Write
    ( M+ W. B' o% e1 U- \" `! L
  119. STA PPU_DATA$ D! d( q3 O( w( K* `
  120. INY! Q. ~6 q$ G! L4 h6 U
  121. BNE Init_Name_Table_Write1 z" I9 F+ P% S) w5 B- q
  122. DEX
    3 m% g0 b$ @) L( L
  123. BNE Init_Name_Table_Write" K7 ~, l) ~7 `( m* I8 E
  124. RTS1 G; V' V& N9 I: y4 p) X6 o

  125. 6 p9 z8 P- w3 t* M5 `6 b' o  j
  126. ;==================================================
    4 S2 J& f! _" G$ Q
  127. ;调色板初始化; X/ s4 {- A; l: N; ]
  128. Init_Palette8 j3 Q0 z! A3 c* K4 k& p
  129. BIT PPU_STATUS3 k7 a  [: @0 g( W
  130. LDA #$3F0 }" v# y& m8 j( D
  131. STA PPU_ADDRESS7 s, K6 P8 ?9 X+ |4 T
  132. LDA #$00
    : I6 W7 |% s+ ]
  133. STA PPU_ADDRESS
    6 W/ ^0 `, g- Q+ f2 A  [6 D! H
  134. LDX #$00
    0 K- ?, K$ b$ Z, ^
  135. Init_Palette_Write1 z) j" ^: {- h0 Z, e0 X
  136. LDA Palette_Data,X
    7 \* D) v/ s4 ~2 ~! f( B' ^
  137. STA PPU_DATA
    3 w; u2 m5 G* S0 q2 P- G3 u% f
  138. INX
    . X0 t0 T4 p( ^' V& c. e9 X. }, t% x
  139. CPX #$200 n2 B1 j$ R) N+ I# g
  140. BCC Init_Palette_Write& ~3 U* c$ E- L; ]8 J# R7 R3 I
  141. RTS
    2 G0 ]# q$ a; ]! c9 O% j

  142. , v: j* s% U  F4 G8 J5 I1 h( E
  143. ;==================================================. _: k5 o# D( F3 N% n2 j
  144. ;设置命名表属性. Z# D8 i" u: \$ d6 h6 M0 @" F. s
  145. Init_NameTable_Attributes: V- a; Y9 ]/ b
  146. BIT PPU_STATUS
    1 ]# E8 j9 x; i+ X
  147. LDA #$23+ t1 K1 c) y( P' t
  148. STA PPU_ADDRESS9 u! M- K5 N/ \) j' I* N! e
  149. LDA #$C0
    3 ^9 Y' I0 d  p6 }1 c1 i( N
  150. STA PPU_ADDRESS" ~  C* t; i4 Z9 I
  151. LDX #$00
    % }% A5 I% r7 T0 M
  152. Init_NameTable_Attributes_Write
    / z' M  E4 A9 K7 O7 Y
  153. LDA Attributes_Data,X
    & D  L* ~) L$ x+ ]' F
  154. STA PPU_DATA
    $ F& [/ O1 g4 p* }0 f2 Z/ Q
  155. INX/ @  [# H) Y- ?' d# K5 {$ S# B
  156. CPX #$40! K, t. k1 v) z9 K( N
  157. BCC Init_NameTable_Attributes_Write
    & }. P0 |. y8 d! A
  158. RTS
    4 C# L( `9 h7 `" d. k5 s6 i
  159. , M: w  m$ w  c' l
  160. ;==================================================
      Y3 a1 x; c+ f3 f
  161. ;初始化命名表文本: o# H* k# ~# X: s
  162. Init_Name_Table_Text# M# C8 B" n8 r8 h1 ]. g
  163. BIT PPU_STATUS- O. D# b. ^5 G8 {
  164. LDA #$20- e! D4 f. `0 U& ^, S! U
  165. STA PPU_ADDRESS3 F+ Y4 `% [5 n1 f- K6 {" n1 y
  166. LDA #$00
    9 c- |& }+ f% H# d( U1 Z
  167. STA PPU_ADDRESS
    ' D% H6 D& x% z8 H- Y
  168. LDA #$00
    7 k2 ~; K( f( V( Q0 B7 J/ a
  169. STA FC_Data_Buf/ @6 y; r4 @1 u
  170. LDY #30
    ; |0 E! K; \1 F
  171. Init_Name_Table_Text_Write
    , X" g* d9 P; B7 L+ |' l
  172. LDX #320 L# v! K4 i# {) L- K* D
  173. Init_Name_Table_Text_Write_Char
    - H8 ^5 s' H1 R% |
  174. LDA #'0'
    1 Z" k  h9 V6 c, ?9 D' j: k; K
  175. CLC- @% C4 m) j: x$ T
  176. ADC FC_Data_Buf
    ' V. F7 @9 [- M3 q: B) a
  177. STA PPU_DATA# X* v# ?5 Z: \. W( P- b# w
  178. DEX6 P* ]2 h; k7 {3 k* ^! ^) s
  179. LDA #$140 P3 n6 i) [0 P9 r! ]
  180. STA PPU_DATA  C% Z4 @' f1 k: _. N3 d1 {
  181. DEX
    8 h/ Y$ A8 I' L
  182. BNE Init_Name_Table_Text_Write_Char: {. k* ?9 O6 A. U" K8 u
  183. INC FC_Data_Buf
    9 b4 N" }1 T+ H* m+ F
  184. DEY( K; e' R/ e/ |8 m
  185. BNE Init_Name_Table_Text_Write7 P) ]7 Q9 r* g- X
  186. RTS
    + J' D/ {( W/ {: \/ |, @

  187. + e5 a# ]" o% |% \& c
  188. ;==============================
    5 h! }3 E2 o/ t* ~- d, [, }
  189. Init_OAM_Ram;初始化精灵内存
    0 U0 U  D3 {, j, U5 R) Q
  190. LDX #$00; p% Y- p4 h* o5 q5 r2 I
  191. LDA #$00
    # R0 [. C3 z3 [* T, P$ E: r9 y. E
  192. STA PPU_OAM_ADDR
    + ^/ X- d* _$ }. {% N6 x
  193. LDA #$F8
    - l) {7 H! o5 A7 q8 G) @
  194. Init_OAM_Ram_Write
    / |" m1 y  A1 P& i1 T
  195. STA PPU_OAM_DATA
    6 z: M" f9 [+ g; O# N( J
  196. INX6 u& g. g5 I7 i  p5 k+ |: ~* v
  197. BNE Init_OAM_Ram_Write4 J$ f' k! ?, @2 C- f/ H4 R
  198. RTS
    ! A  D1 o3 m& v& {6 n

  199. 1 w& Y* o: c& l/ x( P# P
  200. GamepadProcess;手柄处理" e* F$ D7 h, Z" c$ R/ K( E: k* U2 @5 m
  201. JSR GamepadDatacan
    ) V0 D$ M# S0 \5 s/ [
  202. LDA <Gamepad_0_Value
    2 f& K1 ]. O4 [% d6 k6 y
  203. STA <Gamepad_0_State$ S4 n) t; ~+ g$ S3 m. i. J4 V9 p" ]/ V9 s
  204. LDA <Gamepad_1_Value0 L% c+ f7 ]. g3 G) S
  205. STA <Gamepad_1_State
    ' X0 W- g" B8 n' {0 ?; L
  206. JSR GamepadDatacan
    # J$ I  q. K+ O; B" V- c& L
  207. LDX #$01
    3 ~* h# y. [' g* A5 V& {
  208. GamepadMergeCheck;合并手柄输入检查
    9 u1 u9 a- v! {0 B, v
  209. LDA <Gamepad_0_Value,X
      U' z2 q% K0 T, t
  210. CMP <Gamepad_0_State,X
    # w1 a* {: H0 q6 _7 y
  211. BEQ GamepadMergeInput; D* N4 @+ t1 ]6 x" y4 q" z
  212. LDA <Gamepad_Temp,X% F& A6 ]  K7 I4 K  Z) y* @2 K7 Q5 C! @
  213. STA <Gamepad_0_Value,X# ?1 e* u8 v# l) @: C
  214. GamepadMergeInput;合并手柄输入/ Y! Z( s' I) I0 F
  215. DEX- e# m$ X1 y1 Q, ]
  216. BPL GamepadMergeCheck
    - P7 W1 e2 }$ p% R; P
  217. LDA <Gamepad_Merge$ {! q: @' M' G# L# M
  218. AND #GAMEPAD_MERGE_FLAG
    # n( r6 X% b6 D0 F1 Z- b# x
  219. BNE GamepadStateProcess
    6 p+ Z- R2 C2 Z/ v. m$ e5 I2 L4 j5 J
  220. LDA <Gamepad_0_Value2 j0 B0 t% {1 f' B6 i
  221. ORA <Gamepad_1_Value0 A' [6 M# H+ q; p6 i" c
  222. STA <Gamepad_0_Value+ t9 Y, M% }+ R) B% }$ }; Q: ]5 x+ D
  223. GamepadStateProcess;手柄状态处理9 q/ L& B! ~: P3 p5 G7 J! i
  224. LDX #$010 R# o8 ^) e' @3 S! B7 |$ N3 v) ~
  225. GamepadStateSave;手柄状态保存' ?, b% X) E' x4 _5 G2 G
  226. LDA <Gamepad_0_Value,X
    4 F4 i. S  E( {6 @, q3 w
  227. TAY" n. x9 f: u1 P( G& n' [" h7 D
  228. EOR <Gamepad_Temp,X
    ; o& U, ^2 z) t# U
  229. AND <Gamepad_0_Value,X- S. O: q" V* }- l1 z# h9 {4 S! w
  230. STA <Gamepad_Once,X
    ' G/ ?! }$ d3 I! P% t$ Y
  231. STY <Gamepad_Keep,X
    " @/ m  C% G0 {5 Y  W# y; L
  232. STY <Gamepad_Temp,X
    + |0 U% _# \1 u$ b
  233. DEX
    # c5 W' P% ?# `. c  h
  234. BPL GamepadStateSave
    1 r6 D9 C8 E$ w- U+ B
  235. RTS
    . a& b( M( _3 ?6 r
  236. % m, p7 g1 z$ g1 \; u4 Z
  237. GamepadDatacan;手柄数据扫描
    ! j/ i7 ^  o2 k4 z8 E
  238. LDX #$01+ h. V2 H2 v. l& t7 e  J
  239. STX $4016, ^3 o. d: l* ?) e9 y% a& J* ^
  240. DEX
    : P/ e9 g* u( w# L: w
  241. STX $4016, i2 G7 I, I- Y! l) j3 }3 W5 t
  242. LDY #$084 t5 }* \% I* X( w
  243. GamepadPortScan;手柄端口扫描: h! N- J2 I: S0 q! f" r! s
  244. LDA $4016' b- X$ }* ^/ b+ J0 y  _# E
  245. STA <Gamepad_Port_Value
      X- H% l% p* G- y9 Y/ c' T
  246. LSR A+ B" d0 K- X# `  V, F( h" W
  247. ORA <Gamepad_Port_Value) e8 d& @. S4 }9 ~
  248. LSR A6 v" p$ c7 G, o+ [3 Q1 A% C9 m3 }( {
  249. ROL <Gamepad_0_Value! B7 x, l8 l* j7 r5 _$ ]
  250. LDA $4017
    + I2 C3 n& ^8 l5 h- g6 U- U2 Q1 r
  251. STA <Gamepad_Port_Value
    ) ]1 _2 s, ^, x" `; g2 Z& i- [
  252. LSR A1 ^- S1 z9 \! m( r! @$ G& W, z
  253. ORA <Gamepad_Port_Value; J- \1 ]8 \! o6 c8 D
  254. LSR A
    2 D* Y, X  u  O$ s
  255. ROL <Gamepad_1_Value8 n. j. l% K, X. P- m
  256. DEY- ^2 b8 N1 q% n0 a
  257. BNE GamepadPortScan9 k9 C' S' \" b: I
  258. RTS
    7 l  e$ U; `$ T- ]3 i
  259. % S) v6 D8 v- i. E5 u. l" o
  260. ;==================================================1 b( w- g5 |( U6 }' ^
  261. ;PPU处理
    5 Q  g$ v- K# n
  262. PPU_Process8 C: H% ^) X0 w/ O5 m
  263. LDA #$00- m% O0 [  X; r
  264. STA PPU_MASK
      l& [" E, u+ m, ^/ f, j: o! L9 g
  265. * [3 ~% K4 j7 N% K
  266. BIT PPU_STATUS
    , U4 K2 R- y4 q5 m1 [7 D
  267. LDA #$20. P, t. \* E7 |. @3 R, s
  268. STA PPU_ADDRESS4 C2 S: L' n8 I: G
  269. LDA #$00
    ' R8 ]2 e! x6 K' e# L
  270. STA PPU_ADDRESS
      C8 R2 e5 R6 p4 i% _

  271. 1 ]2 {) k1 p. G' s4 v8 e
  272. STA PPU_SCROLL
    - q/ Q" t9 k7 O
  273. STA PPU_SCROLL
    # l6 g5 V+ _3 K& _' {. x2 Z
  274. # K! o. ]8 ?' v' S' ]: {
  275. LDA PPU_Msak_Buf
    + Z0 \1 p3 m6 J+ @2 j% [
  276. STA PPU_MASK
    # {+ X+ ?' s5 j+ B4 g/ ]5 f
  277. ; ~- `1 x; H# \: {2 z
  278. RTS
    & M# o* A, z* Z1 U* Y: v' |0 \

  279.   d" n" D( n1 p
  280. ;==============================) ?) |3 u! d6 q+ a" T8 [
  281. Time_For_Vblank;延时等待. ]7 Z# v3 @! b; u7 m
  282. LDA PPU_STATUS
    5 {! d; j* k: j2 j! h% z* N- c
  283. BPL Time_For_Vblank0 A4 _0 @* d# P: C. @9 {# m% z
  284. RTS
    ! k0 s/ L0 J6 ~0 x4 U5 J& T# C
  285. 7 U! C1 B6 M1 i; H- R# h
  286. ;==================================================% R  q0 m7 w$ }0 r
  287. ;初始化MMC3
    , r, q& T# b$ B* Y0 h5 v5 Y
  288. Init_MMC3. s: Q0 r2 d/ c+ D0 }& p" |& f
  289. STA MMC3_IRQ_DISABLE
    7 t- A3 Q6 v- k- }  E

  290. - O$ J& B  {: d8 C2 \  @8 h& }- ~
  291. ;设置MMC3水平镜像* f+ Z( y: m& q: i
  292. LDA #$01
    5 L! }$ Z# L- \. N
  293. STA MMC3_MIRRORING
    7 A& h  R. \6 J) C& K# s
  294. 8 p( f# ~' p) x
  295. LDX #$05
    : [+ B) o) ~* X4 h$ c5 P, }
  296. Init_MMC3_Chr_Bank_Write: D: u" z  ^& r6 q" ?8 V/ I5 `
  297. STX MMC3_BANK_CTRL
    ( |5 ~" x& F5 \. i1 O7 ~
  298. LDA MMC3_Chr_Bank_Data,X6 W- J9 ^+ {' s
  299. STA MMC3_BANK_DATA
    ( y! k( A2 }7 }# g
  300. DEX
    , B* i4 ^( _! [# S* j9 d. W7 D% a3 B
  301. BPL Init_MMC3_Chr_Bank_Write
      @" h& E3 D/ A
  302. RTS6 Q7 R8 b: c2 x
  303. ;--------------------------------------------------' J- Q. ]% q) U- P  B
  304. MMC3_Chr_Bank_Data5 j4 R6 \& u0 J) a- m* a( l; y6 X
  305. .DB $00,$02,$04,$05,$06,$073 ]  u! V5 _" w5 {
  306. ! N( w3 R) l0 [8 [1 a; v
  307. ;==================================================
    / d7 Y$ L3 n) L7 Z0 A' a6 |
  308. ;重置中断处理
      M+ e  `& g& R1 h2 k
  309. ResetProgram
    % T% R& x$ H8 \2 R2 g& S  U" y
  310. SEI' G5 W' `1 B) g2 @- b' z' e; h
  311. CLD
    1 e, O/ p. c$ F5 \" o
  312. LDA #$00$ G  d4 @& A% U; f% N4 f8 I
  313. STA PPU_CTRL& s1 K$ O) x' n$ |0 Y
  314. STA PPU_MASK
    1 Y; d* d" z8 C
  315. STA PPU_STATUS
    9 G6 ]0 O* g7 C6 E5 b& x. c
  316. STA JOY2_FRAME7 e/ }/ [" t3 G: `$ ?' ]
  317. STA APU_STATUS' h. S, |5 b1 o
  318. - ?" v  z  R$ |1 d
  319. LDA #$C0
      _4 x3 I% J, Q9 p6 ~
  320. STA JOY2_FRAME
    * t4 k" p4 G7 c
  321. - s5 r/ }3 {' R; R
  322. ;等待vblank( H8 Z, T, n* u6 b$ o- p- M
  323. LDX #$02
    & x/ v. m7 S+ \" z5 ]8 d+ u- A
  324. Vblank_Wait_1
    + J: b  U0 F+ V. |
  325. BIT PPU_STATUS. C6 `( V: X+ j
  326. BPL Vblank_Wait_1
    5 h3 j9 s- q1 b7 B
  327. Vblank_Wait_2
    % k) x1 X4 h! C8 K  f: h7 `! h
  328. BIT PPU_STATUS
    , ^8 L- ]: J4 V! C) R' c, P
  329. BMI Vblank_Wait_2
    6 J9 h% h) }$ @% l, |. p
  330. DEX1 n" ?  d3 h% e
  331. BNE Vblank_Wait_1
    0 h1 l- D/ c% s

  332. 8 E* d0 A5 h8 {. ]$ o
  333. LDX #$FF6 W1 j' q% V* z2 ]
  334. TXS( `% |. ~' D# h% G& {5 g9 W/ n
  335. 5 F! @, Z1 z9 C5 a
  336. ;初始化MMC3
      P! w& b! r3 P  L9 Y* z" w& y
  337. JSR Init_MMC3
    : W9 d1 \+ Q3 w4 |" P2 [: i, L4 P0 B* l

  338. , F  F7 I; r: Y. Q' i) ^/ ^  B
  339. ;==============================
    : R; D& x% V4 t. Q" L$ a2 x
  340. ;RAM初始化
    + [' H! X: \8 H, A  W/ `
  341. Nes_Ram_Init
    ( f8 D+ I# J: t$ D6 i' o6 S' H
  342. LDY #$000 ~3 ~9 }1 ?0 K: {
  343. LDX #$08; f6 g* i7 E' g! x. r8 e1 g3 f
  344. LDA #$00
    # Y: j: a' @3 i4 O7 p( L' ~
  345. STA <$00. i% U3 j8 T# |# j. o' u
  346. STA <$015 F7 m6 I  K! [$ k# m9 q# v
  347. Nes_Ram_Init_Write
    : f8 C# e/ V! C+ j  h8 Q' B
  348. STA [$00],Y
    ! \8 B  Y3 r% Q4 \7 c9 r. k
  349. INY
    & j& i+ Z0 y7 w5 A5 v* t9 z
  350. BNE Nes_Ram_Init_Write
    2 w. z, B4 H  f! I6 M4 |3 ?% y6 B
  351. INC <$01
    5 B' x5 W8 Q  W
  352. DEX
    5 G. _1 ~8 ^3 v! Q
  353. BNE Nes_Ram_Init_Write" x/ {8 ^- H1 J9 u
  354. 7 {: `( m6 X( H+ c$ T( i
  355. ;初始化命名表$ |- s# L) g. P5 x9 o9 e5 ~1 U
  356. JSR Init_Name_Table
    5 {+ v+ n3 C) n2 I# E7 D

  357. 0 m$ A) y2 o" Q5 M/ x0 {2 c
  358. ;初始化调色板
    " H. c) g* G8 c5 L5 B' T! U6 H
  359. JSR Init_Palette0 k0 o: U4 n3 |* b
  360. ! `/ r4 x3 l" [- o
  361. ;初始化命名表属性: H" j" v2 J/ n: y. u
  362. JSR Init_NameTable_Attributes
    0 }( z; g4 Z  Z$ L
  363. 6 b& @( j& n* ]" O
  364. ;初始化精灵内存% P8 O$ c1 S$ \# a5 B5 O
  365. JSR Init_OAM_Ram" W& i( `2 Y: |( _0 u! a! ?6 m
  366. 6 \6 r+ @3 {/ t, ?& e5 c0 W" j$ {
  367. ;在屏幕上写点东西
    $ Z( K' J; t; f7 g/ G3 D% x" V. K$ H
  368. JSR Init_Name_Table_Text9 n3 P. Q* M( b& d
  369. $ i& q9 C1 Q  ?4 j
  370. JSR Time_For_Vblank
    % Q$ ]: |: K5 H% e/ ]7 I
  371. ;开启PPU控制2 ^- O* b/ K% I6 S0 J
  372. LDA #$807 b+ _  N( c7 {! w) ]
  373. STA PPU_Ctrl_Buf4 i7 o/ F( {$ D9 u5 J: f3 j5 i& P
  374. STA PPU_CTRL
      _) Z  x. c4 _/ q) f
  375. $ y. W* U$ x& J% J/ V
  376. ;开启PPU显示
    5 P1 {% j, ?& q# Y$ j
  377. LDA #$1E
    , N: T2 i7 A4 I
  378. STA PPU_Msak_Buf
    ) J, E& u' u9 _3 }  M- T0 G

  379. + g5 D7 c8 }6 {
  380. LDA #77
    / w4 T4 P- w9 v% L$ Y/ E) I+ k, r) v* w
  381. STA Sprite_0_Y) v; k* ]! i6 R, z/ H
  382. LDA #$1E
    ( a3 |8 ?  h3 U
  383. STA Sprite_0_Tile
    5 x+ e8 c: z3 T2 A+ D* `3 I. L' j2 `
  384. LDA #$20
    6 Z5 P* T# _$ X  ~2 @% Z8 m7 M
  385. STA Sprite_0_Mode2 K) H  o! U$ w; o* Z! X) @, m1 P
  386. LDA #$00
    - d' e" L7 X3 d' B3 I  m, h7 Q
  387. STA Sprite_0_X$ P* C% k* T( l# a1 s* V- E# m

  388. 9 {; o2 i( W0 M. Y# ^
  389. CLI- C1 k8 K, H- v* v: E. [
  390. JMP Loop1 q0 @5 U, T5 J3 _# s
  391. , s6 ]7 a6 M/ i2 c4 z5 _4 c
  392. ;==============================
    ( ]! e9 b" G( P% q
  393. ;死循环, 等待NMI中断- I, k" ^) b$ `0 o/ x
  394. Loop# P9 y( S; B5 r; |7 I5 t
  395. JMP Loop
    * h9 Z) l4 \3 j9 g. X
  396. ) p2 [3 B3 Z% ^+ ]0 i
  397. ;==================================================
    $ ]* a+ a  D; }+ _# U
  398. ;NMI中断处理
    * N4 \% H* t% C3 H, [' z6 L+ u
  399. NmiProgram: d9 H# M! U0 K6 h
  400. PHA3 @6 ]( t' g( s8 u. [8 j' l0 k5 E4 ?
  401. TXA9 S. Q: o" r& H- d( J
  402. PHA
    + x. h. u' d+ J- A8 D1 P
  403. TYA
    ' b1 ~2 X% a/ l4 C9 k
  404. PHA
    5 v1 F2 E% [4 w
  405.   F( p$ c. q8 c
  406. BIT PPU_STATUS2 y3 f2 W8 r3 R$ V/ |7 W/ ]/ B
  407. ( Q4 X7 t2 ~9 t
  408. ;关闭PPU控制
    " F' j$ Q+ H0 @) D( v  x" o. p
  409. LDA #$00
    + q* n1 `: N5 W* q* y: v# ?# `
  410. STA PPU_CTRL
    # S% B6 z* J; f6 R

  411. 3 g9 n' e; R# W, m3 V( B
  412. ;处理PPU
    $ h' f; j$ L, l% V
  413. JSR PPU_Process
    * s- C. r! s. [4 ]; L) a
  414. 7 R$ E7 q# y* `: Y
  415. LDA #$00+ w( W9 ?! v2 Y2 W/ m9 D% C
  416. STA PPU_OAM_ADDR# m, G* _0 s* r0 t% n' {3 \
  417. LDA <Sprite_0_Y- E$ d+ M9 C$ k" l
  418. STA PPU_OAM_DATA
    % d2 x& ~% C3 }/ H7 ^* _( P0 j
  419. LDA <Sprite_0_Tile
    7 `5 a0 V7 B9 ^2 G  [) w
  420. STA PPU_OAM_DATA$ W* a5 f% B6 [) _; y* S& K
  421. LDA <Sprite_0_Mode' w9 U8 q+ m8 S7 O) g" s9 C' T
  422. STA PPU_OAM_DATA
    - W' ~) l& b# g" a& ]* z
  423. LDA <Sprite_0_X0 a2 T, ^# y6 p" H
  424. STA PPU_OAM_DATA
    # t. m4 b( N2 k, _2 ^/ }3 Q

  425. 1 {' f( r& M+ |: Y$ b/ ~- n
  426. ;开启PPU控制
    . B  b( @) u( w8 I( A1 D: c) g( j& a
  427. LDA PPU_Ctrl_Buf
    ' h; V. j6 R+ \1 R5 h  }- X
  428. STA PPU_CTRL
    / s. a9 m$ C- b9 q% b
  429. , G* U+ Y4 D0 A6 O: M$ M! p
  430. ;屏幕滚动
    , N: i$ ]3 m" q/ W5 s) K
  431. LDA <PPU_Scroll_H3 r7 D( G6 _0 c2 L
  432. STA PPU_SCROLL9 O% T( O6 J1 V- {- ?
  433. LDA #$00+ L9 L) `$ m7 O5 V* Z2 J3 {
  434. STA PPU_SCROLL/ R0 g8 U& J; {! C* J

  435. / D. R  l+ d: m' E3 E( j
  436. ;手柄处理% e. F& @9 J% f% Y3 {* m
  437. JSR GamepadProcess7 B, M0 N- K8 G% p$ y

  438. 8 @/ _( m) t( {0 |1 @) ]! R( K
  439. INC <PPU_Scroll_H
    ) k  z: H( f  F
  440. 1 M( M% f; Q/ c
  441. ;启动0号精灵碰撞检测
    " o: @$ H/ h1 y
  442. LDA #$01
    # L- O' V+ q" r+ t
  443. STA Sprite_0_Hit_Move_Direction
    . G. m- X) {; L! `# L
  444. JSR Sprite_Hit_Test1 _( Q& z+ g: j5 |. w" R

  445. : K' t  b* G) V6 d8 _$ p
  446. PLA) z$ h7 {9 W) Y  U  n
  447. TAY
    - z( a! u: P; {* U9 C' A
  448. PLA0 O7 x1 J8 U$ `6 L  V( `$ o7 Y' x* t
  449. TAX
    " l" @( U; [. L. w
  450. PLA  B/ p0 }- A1 ^1 d
  451. RTI
    9 ^! }$ F: X1 e6 O4 ~& y2 Z6 h

  452. 7 W. B# l" G, L7 @& r0 s5 Y" k
  453. ;==============================; }" J/ z+ Z' P/ e
  454. ;0号精灵碰撞测试- z  r2 f$ @6 Q; T, ]
  455. Sprite_Hit_Test' w& B3 g( a0 v
  456. / F; Y% P! c' O+ a$ d' A2 ~) y
  457. ;------------------------------* b, G) b" l- _% _  S: A+ I
  458. ;等待0号精灵碰撞状态取消
    * w) F9 ^! X5 ~4 h1 N7 x
  459. LDA PPU_STATUS
    # t6 O5 A1 A8 R( y& a
  460. ASL A
    , M  i  Q. G) u" ^# B# n
  461. BMI * - 4$ W, A! {& U2 R! _

  462. / O6 X, W/ h- p  w! d- D- ^* f
  463. ;------------------------------
    1 p1 y7 i' S& O& s  Z+ Y$ S
  464. ;等待0号精灵碰撞发生
    2 e5 e& ^1 U, i$ f
  465. LDA PPU_STATUS
    & c2 w0 y( d0 d- X/ [; m  _8 P
  466. ASl A1 T+ E9 I8 c- w1 v" v# |1 S/ q8 f
  467. BPL * - 47 m8 X, {8 }/ w6 |: A
  468. * q# M3 W' }% x; _( u
  469. ;------------------------------
    5 X* A0 C& B& D6 e$ M) I' @
  470. ;行消隐等待; q: d) l4 p6 c
  471. Sprite_Hit_Scroll_Wait
    , V, k# ~- ^" Y/ }' X+ Z+ D8 X
  472. LDX #$28" p; K. v1 R( O; T$ n$ n, k" m
  473. DEX
    . A* z: ]: d1 I- }) g
  474. BNE * - 1
    4 J5 X$ i& q. {( @- t
  475. ( |* m9 U( g) F0 b
  476. LDA Sprite_0_Hit_Move_Direction
    , v1 Y! F7 f! O' k! M) q
  477. AND #$01) i' s$ N: x) W# n. z
  478. BNE Sprite_Hit_Scroll_Set_Right
    & R! D  i/ G& ?( K5 w# c
  479. / _3 E. i6 W" L2 y' t, h( ]* O2 z
  480. ;------------------------------% P9 q. U5 F" _+ n
  481. ;分割画面向左滚动
    8 Q/ W- p7 Y9 Z+ `- x
  482. Sprite_Hit_Scroll_Set_Left% M! k8 }8 D1 g  k3 J
  483. LDA PPU_STATUS; @9 i% D0 S8 h* B) _! C) z
  484. LDA <PPU_Scroll_H
    / x+ i9 M% X: \! u2 }
  485. STA PPU_SCROLL
    ! a* w, w2 z3 U6 j# G# h) r+ u
  486. LDA #$00$ C+ G6 ^/ ~( n% G& h
  487. STA PPU_SCROLL
    9 c2 i6 ]9 x% {1 a/ W: @$ i
  488. RTS
    1 w$ Y2 @, [! ^/ |5 X: ?! u* v( j
  489. 5 g! r% U( s6 f
  490. ;------------------------------% B5 G, K, x  v# @/ w$ Q$ K% L
  491. ;分割画面向右滚动3 w+ F! h0 w6 z) R4 l2 |
  492. Sprite_Hit_Scroll_Set_Right
    ) t" Q- u$ K: Q. q( L+ P; }
  493. LDA PPU_STATUS3 |* D- D7 W" n/ B% Y1 O) z
  494. LDA #$00/ z2 J2 Q6 I2 a& o. |7 m
  495. SEC9 l+ d# Z- t/ x, g/ U
  496. SBC <PPU_Scroll_H$ g- S$ @1 f; i- @& Y: n8 d
  497. STA PPU_SCROLL
    # A% ^6 Q) P' |: [
  498. LDA #$00: C& q0 p3 n7 v- T
  499. STA PPU_SCROLL
    0 J$ v" ?2 H  l3 A% i5 \
  500. RTS+ S6 a% n' Z5 A- H2 D

  501. ; c$ [9 v$ `, M* \' W# v3 \" t
  502. ;==================================================
    : A: Y  ^& u0 g' t
  503. ;IRQ中断处理
    . k& M" c" ]9 ~/ i& z6 y
  504. IrqProgram6 O4 q' U5 T2 N; k
  505. PHA
      Z/ Y. j& j5 A' g  z) n
  506. TXA  J  }) t, W# J( F# q0 Z" }7 _* f
  507. PHA
    2 l' D+ C/ N5 v. V+ Q, c: Q
  508. TYA* g& ?5 C. ?5 _* {5 e- w# `
  509. PHA
    $ U. v7 `. p) t

  510. , Y4 w6 q  O9 a8 a
  511. ;关闭IRQ4 N5 w' c4 w/ l0 u$ D
  512. STA MMC3_IRQ_DISABLE4 u3 K8 F5 o  C) n2 e; ~$ a
  513. 3 y/ ?& O6 r, x2 B# b5 M
  514. ;允许下个IRQ触发9 q4 M- n; \: F$ n
  515. STA MMC3_IRQ_ENABLE
    ; S" Y: y$ I- ~4 ]

  516. & g/ ~% m' R9 H
  517. ;IRQ处理, 15线后继续触发+ n% f8 c( |* \- x
  518. LDA #15: U3 c$ q9 @( S: i
  519. STA MMC3_IRQ_LATCH
    ' O0 C0 R: W$ ~" f, P

  520. 2 S) E" F5 y" X2 k8 F7 s
  521. LDA <IRQ_Index
    ' E8 v  \/ z1 @% a' B' N
  522. BNE * + 4/ y* J! W6 Y: ]1 c9 w8 |) Q* @
  523. INC <PPU_Scroll_H
    8 {0 K- B& K- V, g* [8 q

  524. ' n: W/ i, D7 W0 Q
  525. ;设置屏幕滚动
    / S& @# B* t  t3 J0 J5 e0 i
  526. LDA <IRQ_Index
    + o% ^! C( u$ Q
  527. AND #$01
    4 E* R, r( M* y3 s1 A/ k
  528. BEQ Irq_Scroll_Right
    + K  [/ z5 ]) }% X5 d/ x6 q. Z% e
  529. / J: Q0 i$ L9 }+ B/ z# q
  530. Irq_Scroll_Left6 h8 J6 W# Y" _8 b9 u' W% n3 `) Y
  531. BIT PPU_STATUS3 W6 j8 J5 R0 Y2 n% {) I. r3 A- G4 |7 d3 P
  532. LDA <PPU_Scroll_H
    " A) b, A: d) q2 _5 [
  533. STA PPU_SCROLL5 V8 Z6 O. t: g! y
  534. STA PPU_SCROLL
    " D5 C" f5 @# W8 ?8 B2 Z
  535. JMP Irq_Scroll_Over+ \: {6 I( a! X- q$ T8 `
  536. " |! P: z: X8 e9 c- B
  537. Irq_Scroll_Right0 {" E$ S9 l6 `9 ]0 l
  538. SEC
    6 @: p  z+ T7 X0 C. T3 Q2 ]
  539. SBC <PPU_Scroll_H
    ; P: x" }1 b. d& e( C- E
  540. STA PPU_SCROLL
    8 K: s; t5 q3 }
  541. STA PPU_SCROLL* z4 ]+ g" [; _
  542. Irq_Scroll_Over) J3 s& [) T6 T3 I  }% {

  543. . ~" a- b! _0 M5 N% B3 C" R
  544. INC <IRQ_Index. a1 X. k3 c6 p, w' P0 z: d/ g0 ^4 U
  545. - U- `( Y0 ~5 R' ~3 [
  546. LDA <IRQ_Index
    3 |0 b* C2 \6 k* @; M- c! I: Y5 g$ B
  547. CMP #14; v+ B& ]/ o/ Z3 O  b
  548. BCC * + 5" y1 L) j0 d6 d* }% a) v3 P$ }7 ~% P) h
  549. ;关闭IRQ
      k4 ]- W9 ]9 d4 j" q$ r% j
  550. STA MMC3_IRQ_DISABLE" ~& J$ D$ `# e% m9 f5 T
  551.   F4 L! T  q- P/ O8 ~
  552. IrqProgramEnd# F, |! j, l* G! `. B
  553. PLA
    ' \" t& g- {3 b* Z
  554. TAY: _: G2 }" R2 {3 ]5 |
  555. PLA
      w6 m* u1 S. U+ Q, \0 d* q" v
  556. TAX
    0 d' ^/ R3 R' \
  557. PLA# v% A" T. [  F$ I; G
  558. RTI
    6 o7 P- P4 [" T3 p0 I8 `" w

  559. 0 Y. E# t5 A5 n# F
  560. ;==================================================
    4 N& M. e2 b) `. x2 ], Z1 Y+ B& D
  561. ;中断表9 m$ `0 }) b& o9 j8 O5 D
  562. .ORG $FFFA
    % X$ m3 k+ E2 Z! {* {2 V
  563. .WORD NmiProgram
    1 H# n1 o$ ]# O6 w: U
  564. .WORD ResetProgram0 y9 j& T% `$ u
  565. .WORD IrqProgram
复制代码
5 ^# l5 T  C* K- T$ y5 @* v0 K4 O

评分

1

查看全部评分

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

本版积分规则

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

GMT+8, 2025-8-27 05:01 , Processed in 1.080079 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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