设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:17:53 | 显示全部楼层 |阅读模式
  1. ;[FC][MMC3 精灵碰撞], K! w0 K* u9 ~% ~5 H
  2. ;FlameCyclone 20230710/ |+ X: t6 r8 c4 S# y9 w

  3. 3 b; _" r% U- C, v# q
  4. ;文件头
    7 ~. v. J+ B& d
  5. ;======================================================================4 t5 ?" e2 a. V  Q! R. b$ m% w
  6. .INESPRG 4                                              ;16KB PRG 数量; c6 Z! z6 |: M2 ~" x. J
  7. .INESCHR 1                                               ;8KB CHR 数量: A% m# C4 k" A0 g: P
  8. .INESMAP 4                                                   ;mapper 4% C4 W; X9 F9 r! s
  9. .INESMIR 1                                     ;命名表镜像 0水平 1垂直
    ' L4 h! E. S8 A( M
  10. 2 p1 i, K/ a+ Z0 Z! ~/ C
  11. ;必要条件0 y- f" ~: t( i5 c& O9 s
  12. ;1.持有CHR ROM2 y$ i4 z! X9 D' E+ ^: q
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000) ~2 l4 a6 f# ]  `; n$ n' K  b
  14. ;3.精灵内存(OAM)不为空% P. @: r' R# P: Y1 O& H  ^9 N

  15. 0 K( c! h9 v2 E* v' E1 Y( Q( M+ W
  16. ;==================================================7 j% w0 B9 L. ]% v3 Q
  17. ;NES端口常量
    9 i% P6 Q$ A0 r5 M# u/ H+ R: ~4 K
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
      F. G" F4 l& u* z% Q
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器+ \3 z% P. P! K" v( F! R
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    % ~; Z5 c1 o: \; e
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    $ K9 y) \7 i" s7 W8 J; w
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    * k% t8 A* ?9 z2 E: {6 D4 _" t
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    8 O; o( y* f& s! K
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加# W- f: D0 j4 @% d
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 3 V" L% P3 w3 M: S' S
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    $ k, P4 {' m8 ~" _
  27. APU_STATUS              =   $4015   ;声音通道切换4 `3 X5 ?/ I$ l8 j4 W
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通" `9 ~% w7 I' `! r+ W7 H
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    / K' ]# |9 z6 x7 W: F
  30. $ s1 S2 ^9 \& d. C4 V
  31. ;==================================================0 ?9 x+ t! I$ y7 V1 b! A
  32. ;MMC3端口常量& V, l9 {) ?6 b: k/ i. e. I; |: Q
  33. MMC3_BANK_CTRL          =   $8000% p2 L7 y& T' n/ ]7 S  j
  34. MMC3_BANK_DATA          =   $80013 E9 X  |7 O$ a6 X
  35. MMC3_MIRRORING          =   $A000& j  S; Q- H7 ]
  36. MMC3_PRG_RAM_PROTECT    =   $A001
    ! E9 k4 M% o! u: M; W- ]
  37. MMC3_IRQ_LATCH          =   $C0001 L- g. D  ]$ c0 M; G" a, h, d2 V9 S  b
  38. MMC3_IRQ_RELOAD         =   $C001  ^8 J1 G9 s7 _' T4 V
  39. MMC3_IRQ_DISABLE        =   $E000+ ~# p# a0 q$ x
  40. MMC3_IRQ_ENABLE         =   $E001
    ) C  B8 |" ]) c4 h* `
  41. 6 Y$ U0 Z2 x, `$ G; O
  42. ;==================================================. `2 A, K; A; s% d) h6 Z/ ?
  43. ;程序块配置
    $ ~" a6 B' o1 C. n8 w; |+ B
  44. BANK_DATA_MASK          = $07% J5 z1 s. w8 f! v! F0 W4 Z1 p
  45. ;--------------------------------------------------# J5 `# P* @/ Y; c
  46. RESET_BANK              = $07
    , o5 l0 c( X8 N3 R3 G! ?# W5 m
  47. RESET_ADDR              = $FC00
    / z8 Z. n$ F0 _( y) W% r' w) |

  48. 9 q9 v) k& C# W0 M1 H9 f
  49. ;==================================================
    ; q1 z. B+ S: a1 n8 W
  50. ;图像块配置
    . W" \, H8 a( r
  51. CHR_DATA_BANK           = $08
      G6 {2 [! ~0 x' I3 \
  52. 7 K2 q; J9 d/ u7 J, v/ n3 l& a
  53. ;==================================================
    ) W+ p4 R+ I; c  W3 W
  54. ;零页内存地址配置6 u( L$ {  q5 z/ I
  55. Use_Ram_Addr            = $80
    ) }: ?9 e6 n1 }5 e4 q5 \6 Z
  56. PPU_Ctrl_Buf            = Use_Ram_Addr
    % ?+ l8 {8 M' w% C: k. _
  57. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01& ^  O5 N; G8 M! ^* V0 X
  58. PPU_Scroll_H            = PPU_Msak_Buf + $01
    9 J8 f2 y2 Z8 H2 y
  59. PPU_Scroll_V            = PPU_Scroll_H + $01
    ' g/ A0 K( J; Z+ F. e
  60. FC_Data_L               = PPU_Scroll_V + $01# q% t- M9 l6 L3 r0 P
  61. FC_Data_H               = FC_Data_L + $01
    ) |. Q- a4 S+ P" ~
  62. FC_Data_Buf             = FC_Data_H + $01
    : A' ~9 S* U9 |
  63. ;==================================================
    : U- C& b9 F; B+ t) Y& F7 s

  64. : F5 p! Q5 h6 I: N9 E
  65. GAMEPAD_MERGE_FLAG = $04
    : l2 c7 O( ?7 W

  66. * {0 ~5 d: U  m7 t" T; v" ?( S! G
  67. Gamepad_Keep            =       FC_Data_Buf + 1+ I2 `; `5 W2 Y9 u6 _
  68. Gamepad_Once            =       Gamepad_Keep + 24 L' h. b9 H& V, Y2 G4 k
  69. Gamepad_Temp            =       Gamepad_Once + 2! L7 h7 F" ~0 Q3 k
  70.                                 
    ! Z: I# i- `/ }" z0 d  v8 j
  71. Gamepad_0_State         =       Gamepad_Temp + 2, X1 y; r. q+ g) ]! i* E
  72. Gamepad_1_State         =       Gamepad_0_State + 1
    0 R6 e( n7 D: \$ U7 a
  73. Gamepad_0_Value         =       Gamepad_1_State + 1
    2 a$ N5 \6 h% X. N; ~. |
  74. Gamepad_1_Value         =       Gamepad_0_Value + 1) \) S& W/ q7 b- t( S& N7 h* o
  75. Gamepad_Port_Value      =       Gamepad_1_Value + 17 S! o" F  Z# C8 t( e; N
  76. Gamepad_Merge           =       Gamepad_Port_Value + 15 B/ ~/ f0 R5 g. E1 F2 H6 |
  77. . s' k0 Q0 p3 P0 O, B1 a$ \
  78. ;==================================================4 O5 ^' y( g0 g. \1 W8 E
  79. IRQ_Index               =       Gamepad_Merge + $01
    ( S) d, l6 G, O1 h! H/ M
  80. Sprite_0_Y              =       IRQ_Index + $011 p- P% C" K! \: S' g
  81. Sprite_0_Tile           =       Sprite_0_Y + $01
    " _% U* n0 E4 ]. P, q
  82. Sprite_0_Mode           =       Sprite_0_Tile + $01
    0 ]6 \0 \: w) D/ z( d
  83. Sprite_0_X              =       Sprite_0_Mode + $01# Z! _; ^" A. }+ V8 |3 `! I7 P9 c1 w* s
  84. Sprite_0_Hit_Move_Direction           =       Sprite_0_X + $01
    7 H" \' }) X: c' K- X
  85. ;==================================================
    % ]4 \: s) p5 y% K
  86. 9 A8 L% w5 z4 ?$ t2 O3 Q
  87. ;CHR图形数据
    & D  F0 k0 l' I: O/ m6 L0 C
  88. ;==================================================% Z& m/ k# e$ m! G. H: N( e7 L0 z7 A8 Q
  89. .BANK CHR_DATA_BANK+ K9 e( G6 h, A3 O" y) x6 A
  90. .INCBIN "chr_bank/chr_data.chr"
    7 t8 O0 E2 q/ t$ y; K9 z# e

  91. 4 Q3 H+ o* I7 P: t) x0 n1 x" H
  92. .BANK RESET_BANK & BANK_DATA_MASK
    3 g6 {0 A! ~* o  P
  93. .ORG RESET_ADDR
    . m/ o! i) n( G( L
  94. " |9 U- L1 F4 I7 i. l% Y1 f2 `
  95. ;--------------------------------------------------+ u; E" Y/ U+ m9 ^
  96. Attributes_Data
    9 P9 t% b0 _9 K# g' D; h7 k2 z. ], E. \
  97. ;命名表属性0 l. G# N0 @( j8 Q( X& g5 I
  98. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$009 g( t' `/ @0 y8 J; b1 w2 M4 @
  99. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA* o6 G; X, Z; ?) A4 T. O' w: |
  100. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    + I0 Q! ]; q9 Y3 x; y) Z3 h" m/ I
  101. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$558 {' m" c& {/ `* p& ^9 Q! P
  102. ;--------------------------------------------------
    $ N1 p7 |& H# N% N  n0 N( N
  103. ;调色板数据
      o" N8 i; K2 k3 l- m
  104. Palette_Data
    ! `* r7 J2 c( Z! ]" G: y
  105. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F  M# ~! I: k3 R% V  L
  106. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F7 t2 ?  _, H5 w8 m4 ]
  107. ! O- s) B! x( J* m
  108. ;==================================================
    0 e6 c3 l1 k6 Q0 x" ?' c0 `) O
  109. ;命名表初始化9 i$ i2 y6 e4 }- F
  110. Init_Name_Table
    ( U. X4 k$ \, p, e
  111. LDA #$20
    ) l; ]$ }1 A: B  l! g2 [6 I3 Q( H
  112. STA PPU_ADDRESS
    ( H% K/ i. G  r# Y7 V$ @
  113. LDA #$00
    2 d8 ^; W! T% V; e' I. @, z
  114. STA PPU_ADDRESS/ B0 h5 c# N& N- A6 R, }
  115. LDA #$00
    % s9 w' t9 T4 {7 u5 i
  116. LDY #$00
    - I5 u% t3 T' b3 y
  117. LDX #$10
    7 R* K5 w7 X1 v' B, A1 Z% D- v. Q
  118. Init_Name_Table_Write  `5 \9 s4 g5 N; Z" e6 T0 A* h: _
  119. STA PPU_DATA" U' K5 G% Y/ `; _: H/ Q1 Q! D* M
  120. INY
    2 I9 g. A6 l& [. A
  121. BNE Init_Name_Table_Write1 s- Z( U2 Z- ]) F
  122. DEX
    3 M4 r- h- _" S" B6 `5 t' h
  123. BNE Init_Name_Table_Write  x" \2 H. w4 ]* J0 z5 c
  124. RTS* i3 g' u" k3 z$ @
  125. , ~) T( g, i0 e& O* O3 J# d9 x
  126. ;==================================================: I+ q3 S* X; r
  127. ;调色板初始化) H4 i; z; q9 i; U0 G. c
  128. Init_Palette
    * m! f& u- r. d7 f3 O, c& [5 `! R
  129. BIT PPU_STATUS
    3 \; B4 w+ n- U! x; |; u+ ^* ^
  130. LDA #$3F
    1 m+ ^# f9 q+ I: O& ^: ^; N
  131. STA PPU_ADDRESS
    * K+ S) n9 H3 V: j# ]
  132. LDA #$00
    ; |+ J; P  B& C6 a/ R" @$ W
  133. STA PPU_ADDRESS; p% m% I' R- A3 ~7 K. W" N
  134. LDX #$00
    : k. b1 ^$ f4 d: ]( D+ C
  135. Init_Palette_Write
    / b! h8 t  ^6 x/ h4 z# x
  136. LDA Palette_Data,X$ K' U5 \/ b7 v
  137. STA PPU_DATA% o% P" I3 P" H) i- u8 ~
  138. INX
    % J+ H3 F5 V" d1 u, z
  139. CPX #$20! h/ k1 x( o% D3 J, {
  140. BCC Init_Palette_Write
    ! H/ E, |6 P. ~
  141. RTS
    4 Z3 r( R+ V4 }* N+ p( x
  142. 8 F; w# S$ x/ k1 b
  143. ;==================================================
    1 K1 k4 P9 ~3 m7 b; l& ]
  144. ;设置命名表属性" r4 M: M* M) v3 q$ j' i: a% M
  145. Init_NameTable_Attributes$ h# Y. n3 g8 h
  146. BIT PPU_STATUS) s; H. m5 ^: D( w% ~! c
  147. LDA #$23
    7 C: f8 a; {* v6 H
  148. STA PPU_ADDRESS
    . h' _. Z; x7 C  ~1 q  _! u
  149. LDA #$C03 [- C" f0 w1 @9 Q8 B1 X  E- T* u
  150. STA PPU_ADDRESS
    8 X: a% G" y+ H+ ^3 o0 D6 y2 X
  151. LDX #$006 v. H- x- w: k! ]; i+ W
  152. Init_NameTable_Attributes_Write
    & k0 O( }: X8 ?) A& N+ }6 p' y
  153. LDA Attributes_Data,X* Q+ z# v$ E8 W, }
  154. STA PPU_DATA2 s! v0 a, W' q! u5 R6 d
  155. INX
    5 B. G1 a* \: f: o% N
  156. CPX #$40
    ' {$ z$ r3 x) p7 q8 c6 s6 Y
  157. BCC Init_NameTable_Attributes_Write: P2 V  g; R5 B7 G" P
  158. RTS: h6 z; ?: J4 {: ^
  159. 7 _" }% r1 H/ f% b# U
  160. ;==================================================" g3 W9 E4 u% S# J- B. p% u4 W% h3 Y
  161. ;初始化命名表文本6 \' U! S, @$ I- ^* Y) G
  162. Init_Name_Table_Text; |, L7 J$ W% H/ |5 s
  163. BIT PPU_STATUS, o1 I5 l# w; m
  164. LDA #$20( Q9 {3 O& z: T6 z! n9 I# E0 ?
  165. STA PPU_ADDRESS
    7 w& ?- f* G' o* J3 K1 U2 e
  166. LDA #$00
    * v( {8 A" s- l( M' y/ t
  167. STA PPU_ADDRESS- t4 _% R- i% B8 z) W2 _
  168. LDA #$00. }! g! v' N1 y$ |2 o
  169. STA FC_Data_Buf
    . Z2 N7 v: Z% R* L% y
  170. LDY #30
    9 ?) Z" ]  _0 r( C3 g. N' `- W
  171. Init_Name_Table_Text_Write3 u; f6 `5 j* J+ c
  172. LDX #32; Z& E! ^+ l! K- L6 w' \' ]  R4 @
  173. Init_Name_Table_Text_Write_Char
    9 l3 L* @5 {6 `* E% S' ~2 ]
  174. LDA #'0'
    4 E! i2 T9 y2 y) v7 L
  175. CLC
    - m% ~( f1 S% Y: c5 V' `. I' j
  176. ADC FC_Data_Buf
    ! D  q  B9 h1 `- x
  177. STA PPU_DATA* `& T. r' u9 S8 p
  178. DEX) I2 g" Z6 j0 l$ Y% u+ R- J0 \
  179. LDA #$14" j  D  x1 }+ x9 _) X
  180. STA PPU_DATA
    + T% V1 n0 {+ d4 t' V$ T
  181. DEX! \7 i0 l- t* k7 K( }/ D
  182. BNE Init_Name_Table_Text_Write_Char. k. f# R3 `" o! f
  183. INC FC_Data_Buf' Q) o5 E  n/ ^3 ?# ^* N& b
  184. DEY
    - l6 q) u4 w9 j* R$ R" o
  185. BNE Init_Name_Table_Text_Write4 M9 V' o% H/ C' ?- J1 H7 k3 X) T5 P
  186. RTS) W& S; e' c; m; Q* m$ m

  187. & m1 G8 A$ i/ J( Y6 `' n
  188. ;==============================. ]' u3 ~; R+ J* X! }8 ?" m7 {6 l/ i
  189. Init_OAM_Ram;初始化精灵内存
    + ^1 `, K% \, K  O" o3 B
  190. LDX #$00# n$ X- R, B2 n* B% T. ]2 P
  191. LDA #$00  O& Q' z" T" Y1 R: O5 f
  192. STA PPU_OAM_ADDR
    ' r9 B, z: P, k6 U
  193. LDA #$F8
    ( |: M" \7 ?; b
  194. Init_OAM_Ram_Write- y: o" D( \' V1 ^& f7 e
  195. STA PPU_OAM_DATA  I0 G: R2 P& z% h' o
  196. INX
    3 t# l0 p0 r0 i+ g! r5 J
  197. BNE Init_OAM_Ram_Write
    8 C( ?: t2 l: i1 ?
  198. RTS. Z  A, A& h) C% v7 M0 n* y, W# i
  199. ; V6 t; X& e1 d9 K
  200. GamepadProcess;手柄处理
    ! x4 R& n  a! v/ B/ `
  201. JSR GamepadDatacan
    0 U3 w( e# J. g$ L% X. j8 @
  202. LDA <Gamepad_0_Value' ]- }. z" o$ m/ _$ A0 s7 c
  203. STA <Gamepad_0_State
    3 c6 A" G7 R% T8 W. _& @
  204. LDA <Gamepad_1_Value5 K8 F& m! T' n9 z( u3 j( n
  205. STA <Gamepad_1_State4 f$ Z# j. U) R9 z! X
  206. JSR GamepadDatacan
    ) B" f1 l3 I& z: h" e7 K+ m2 R
  207. LDX #$01
    4 p6 J# ^1 p) ~, G7 B  w  {
  208. GamepadMergeCheck;合并手柄输入检查
    + v) @1 l0 a/ {. q
  209. LDA <Gamepad_0_Value,X
    6 d) c9 s! `. [' Z5 T7 N" |
  210. CMP <Gamepad_0_State,X
    $ V8 j9 h! D5 q" r: [6 O9 l: e
  211. BEQ GamepadMergeInput# @( V2 N0 W2 ~7 m
  212. LDA <Gamepad_Temp,X7 s3 Q6 A2 w; h$ @- q/ g
  213. STA <Gamepad_0_Value,X: V7 L5 ]9 ?0 W
  214. GamepadMergeInput;合并手柄输入
    0 d8 h" i- C4 N8 k( i) O0 S9 y, A5 \
  215. DEX
    8 `% p* r, U0 N+ R! S
  216. BPL GamepadMergeCheck
    , {) L1 F- [) t2 ?, y
  217. LDA <Gamepad_Merge
    1 ~7 }* o) o( h
  218. AND #GAMEPAD_MERGE_FLAG( I7 {1 s2 ^; O# N0 y
  219. BNE GamepadStateProcess
    - N2 I6 [8 h+ B6 ^
  220. LDA <Gamepad_0_Value
    * Z; z: w0 d( x
  221. ORA <Gamepad_1_Value" t5 s# V: I5 Q0 O5 M
  222. STA <Gamepad_0_Value
    # q7 m; p- Y9 G# n1 V
  223. GamepadStateProcess;手柄状态处理
    ) f7 T; Z( ^- R& W5 }
  224. LDX #$01
    6 C9 c" l2 t9 k! s, F4 }: B
  225. GamepadStateSave;手柄状态保存- G: L1 K3 K  P' G
  226. LDA <Gamepad_0_Value,X
    , ?! V) G4 K* T& i8 [* @$ }
  227. TAY
    + Y$ q4 d! E2 `; G4 H
  228. EOR <Gamepad_Temp,X
    $ y# V4 u" A; C8 S8 W
  229. AND <Gamepad_0_Value,X+ W& s! V, n0 y; Z, g2 b
  230. STA <Gamepad_Once,X, Z( G% p; R& u9 Q. q  s* i5 @
  231. STY <Gamepad_Keep,X
    ( u% g+ J! E6 c1 K% ?3 |
  232. STY <Gamepad_Temp,X
    ' r5 w6 q8 c# o) x
  233. DEX
    , ^8 J' N/ s1 G
  234. BPL GamepadStateSave
    2 m8 v  o" Z" V+ }- _) v% w
  235. RTS- S* p) |9 @9 q

  236. 2 b1 N8 h2 ~: y- o* w; x
  237. GamepadDatacan;手柄数据扫描
    $ L) r2 T/ c. a+ H2 K
  238. LDX #$01
    4 {$ F+ K; V7 w2 t8 o
  239. STX $4016: o1 u/ X0 E8 V4 E1 d# H% J
  240. DEX- ?- n  q9 [5 c/ K
  241. STX $40166 T. d/ @" `* H. [6 i# ?
  242. LDY #$08
    % F! V; y% k1 v- \
  243. GamepadPortScan;手柄端口扫描
    & \9 ?' k: g; P. c9 A1 A
  244. LDA $4016  x$ y1 Y# ?: [% N/ Q  M
  245. STA <Gamepad_Port_Value5 B. I  P5 g# o+ i' t, K
  246. LSR A* D, x& o& E, e6 S7 |* w
  247. ORA <Gamepad_Port_Value4 _( f" C1 y. k0 I0 O
  248. LSR A
    1 C1 G5 p1 T. {) s1 ]  V+ I
  249. ROL <Gamepad_0_Value( E9 ]  d$ S( y' n% `
  250. LDA $4017
    ; X6 D  q6 I  G+ ~
  251. STA <Gamepad_Port_Value! ?7 r  }) s2 \
  252. LSR A
    ! x! a* C/ q+ w
  253. ORA <Gamepad_Port_Value
    . ?1 d( l8 z7 j7 r# z0 P5 E$ Y
  254. LSR A
    3 f" N+ I- C9 ?
  255. ROL <Gamepad_1_Value
    " T2 F) h5 Y2 t: Y: j! P
  256. DEY
    % n# U2 A, @& i7 @
  257. BNE GamepadPortScan
    2 u, e7 j" j! `- g
  258. RTS; D3 R1 |! ]( b$ F, D+ A: C$ F
  259. , G3 O1 n: N3 m
  260. ;==================================================
    : l( a8 X4 u; z
  261. ;PPU处理; y% B$ `* i& q6 ?; M
  262. PPU_Process
    $ m- R9 ^* [% p: d' i
  263. LDA #$00- E2 Z! h5 D$ K' X3 {7 ?
  264. STA PPU_MASK
      v6 l0 B( a% M* Y2 Z
  265. + v8 C; t/ B( i! j
  266. BIT PPU_STATUS
    1 ^+ I( c6 x2 O
  267. LDA #$20$ B) ~3 I* Y& F, o0 D0 E
  268. STA PPU_ADDRESS8 y1 Y, o& x- A$ j
  269. LDA #$00
      A9 g! _6 H: ]
  270. STA PPU_ADDRESS
      w$ e, x5 a$ {! H. a

  271. ! Q; L9 [% u$ i5 A7 K
  272. STA PPU_SCROLL2 q' T: p$ X1 ]: z* J( A4 I, X
  273. STA PPU_SCROLL+ I9 T# Z$ L% r

  274. 6 {. M, k( m7 Y9 a! f) f+ m3 E
  275. LDA PPU_Msak_Buf8 S1 i' V1 ^! K8 z0 |
  276. STA PPU_MASK
    # f7 h( D$ A( Y

  277. ) u- U9 j' u, N& E
  278. RTS% m# S( Z4 V* `. B- ^% m2 t
  279. % i3 {/ @4 y0 A# ]) R! }
  280. ;==============================
    / p# n( d1 k8 {1 o
  281. Time_For_Vblank;延时等待
    & r: E7 f$ L1 D/ ?4 {$ a$ J0 Y6 y
  282. LDA PPU_STATUS; i" n2 V) z' g+ _
  283. BPL Time_For_Vblank- c( I+ s) v) T1 ~% V4 j! f) H" B
  284. RTS
    ( M2 i! g# Y/ J7 k9 A/ P
  285. & S  C* L- x0 H( q
  286. ;==================================================
    # U. s+ {0 b8 d: ?1 s0 i4 i0 h
  287. ;初始化MMC3
    " L" n7 Y7 M7 B
  288. Init_MMC3) o) o: T5 \" o8 |( O
  289. STA MMC3_IRQ_DISABLE* U" V: Y/ Q  Q) e. }2 f
  290. . R1 ?2 |# ]* _/ [" F/ r6 g
  291. ;设置MMC3水平镜像. C6 ?; b) y* Z. K1 j. s1 ~
  292. LDA #$01* @1 V4 Z; ^/ u" z0 I# k
  293. STA MMC3_MIRRORING( e  X1 X8 @# k% \
  294. , |- v: a4 _  {2 k+ {% g1 k
  295. LDX #$05, V- c* \3 w6 \
  296. Init_MMC3_Chr_Bank_Write; T7 i2 G" e& v
  297. STX MMC3_BANK_CTRL" U7 Q9 ^# j9 c; m
  298. LDA MMC3_Chr_Bank_Data,X: j( H, H! y% l( m6 J$ v: g
  299. STA MMC3_BANK_DATA
    - s- f( E: {1 A" Y, G, t8 X
  300. DEX' @( H9 k6 D' O% a* S5 J
  301. BPL Init_MMC3_Chr_Bank_Write
    + e; q: B% X9 c" q3 Q' [* m% U
  302. RTS
    ' X" l/ g  k0 g$ R# ]' {0 ]
  303. ;--------------------------------------------------8 j) l; z3 h" b
  304. MMC3_Chr_Bank_Data8 G2 u! M" Q9 ?
  305. .DB $00,$02,$04,$05,$06,$07
    5 N1 y: a; F+ Z/ ^
  306. - e$ S* Q9 L: t% W: w$ [( X
  307. ;==================================================
    ' j! e1 k$ y% x0 D: i1 v  g2 s; E
  308. ;重置中断处理- t; y0 w: i) h/ h7 s+ J
  309. ResetProgram4 H; K, ~* g6 i( t# c! D
  310. SEI5 R3 H, p( }3 }( y( D: z
  311. CLD
    % h5 J" o) s4 G9 n: ?
  312. LDA #$00& @2 f2 H2 h1 _6 X6 w. `# k
  313. STA PPU_CTRL& d! E8 [( z' M
  314. STA PPU_MASK
    ( J3 G* C0 @! H; v5 C- r
  315. STA PPU_STATUS
    7 P% P; I0 ^1 ?3 a5 h, o
  316. STA JOY2_FRAME2 u9 R9 b& Z9 T  N( S
  317. STA APU_STATUS
    : I( D9 v* c+ G* T2 C! F6 |
  318. 8 l* ?6 n( s5 w$ y: l7 o
  319. LDA #$C0
    2 @3 I6 ?) B' M4 a3 `7 f5 X
  320. STA JOY2_FRAME
    7 M/ ^9 l. f8 K8 E/ Q8 o

  321. " M2 f- m+ t0 R3 c* [- T& G
  322. ;等待vblank
      W5 X* D5 S6 N
  323. LDX #$02+ f; v% l+ a- U* R
  324. Vblank_Wait_12 @* M$ k1 m* A! g! G
  325. BIT PPU_STATUS
    5 M% G" }8 u9 k$ M
  326. BPL Vblank_Wait_11 c& s' `. P2 q# q
  327. Vblank_Wait_2
    ; h( U1 z0 [$ M: D( r! _0 @9 y. w
  328. BIT PPU_STATUS
    ' h! H* I) X% m
  329. BMI Vblank_Wait_2' A+ Q# O( _& m8 V
  330. DEX. A4 _# m# I6 {; C5 Y; y; A; l
  331. BNE Vblank_Wait_1, n# F7 ^/ X( y7 a. r. e) z3 [
  332. * |6 J$ v4 Q5 s' R
  333. LDX #$FF, I* [7 x3 c- @- b  C
  334. TXS
    8 J" X) x6 v  l0 p+ ^

  335. 5 N0 z. }  Y# r! g, N6 |, I
  336. ;初始化MMC3# v& U# ], U/ T0 V
  337. JSR Init_MMC3- f$ r6 H# ~8 |4 _, m& j" A
  338. 9 K, m6 Q# \2 @; t5 j9 H0 p, o
  339. ;==============================
    9 ^2 Q2 @* e. I6 U( e  {
  340. ;RAM初始化1 |! h+ v3 u1 S0 u5 A3 [
  341. Nes_Ram_Init: G8 N. h: l& |) y
  342. LDY #$004 F. a* D) C. U# m" N
  343. LDX #$08) ~3 f; i: x, Y4 D7 E& f3 }& H3 C
  344. LDA #$00
    , |/ ?2 `- L% q6 x3 o: P) t0 ?
  345. STA <$003 K. @8 |$ H6 v! g
  346. STA <$010 x' F7 H* V  I& h* D. R$ N
  347. Nes_Ram_Init_Write' S9 X, i3 _* |2 t9 K
  348. STA [$00],Y9 H9 ^3 e- ~9 [. D
  349. INY
    0 ^* N+ C6 `1 p3 i+ \  i7 F
  350. BNE Nes_Ram_Init_Write+ J7 O! S8 I: N  U$ _% Q
  351. INC <$01
    ; v: |- \: ^* ]4 G1 U
  352. DEX
    3 w# v2 h; x% \% z) M  W
  353. BNE Nes_Ram_Init_Write1 P" k9 B, v- a9 u  u

  354. % }5 F3 {9 S% C' s
  355. ;初始化命名表3 z! x& q7 q5 Q# ?
  356. JSR Init_Name_Table' Y9 i9 C1 |" ]9 a5 q$ A% j
  357. . ]4 g8 H. q* ?) ?# H4 t  `
  358. ;初始化调色板
    ; ~4 d7 [+ ?- L( U& |6 W9 D: t
  359. JSR Init_Palette+ D- C# r6 e/ m4 x
  360. 6 _5 Z/ b5 G! S5 Z
  361. ;初始化命名表属性
    : p1 B. t2 M' Q  W
  362. JSR Init_NameTable_Attributes
    % @; H) Q' ~8 p0 x3 T% j3 I3 H
  363. ) g: G1 K, R& V" h5 Q, z2 t! y
  364. ;初始化精灵内存
    / Z; R: S- ^- |' z, w2 c
  365. JSR Init_OAM_Ram  z, _2 l% u6 |9 C

  366. / e$ N( {* U& c. u7 u4 j/ A3 k* y
  367. ;在屏幕上写点东西
    & L( l' B4 t2 V" S9 I% y& i
  368. JSR Init_Name_Table_Text
    ( t( m5 k1 n/ \0 l6 n7 b

  369. . p% a1 ~! @0 _) S) Z8 t0 w8 R# Q3 I
  370. JSR Time_For_Vblank
    / {9 a7 e2 ^$ v+ |  {! }. L
  371. ;开启PPU控制
    / w/ V7 A- s: s' a, H
  372. LDA #$80& q: t  r, Z. |& E
  373. STA PPU_Ctrl_Buf5 C! b# O( H1 o1 B7 q' t3 F( D" q% T
  374. STA PPU_CTRL4 @% _8 o: O& E+ t, s! T: Q

  375. 2 p1 }& I# N: o, v8 E- W1 M
  376. ;开启PPU显示
    # |3 b' f; Z, ?8 T' V: H8 T
  377. LDA #$1E
    ( W/ f; Q2 U2 m4 E0 @; ]3 o. H4 ]
  378. STA PPU_Msak_Buf
    * a! ]* L. X: Y& o, w
  379. : G9 m& D: v+ E4 a" t: j/ F9 i
  380. LDA #77
    7 r/ r: T& {! u5 K
  381. STA Sprite_0_Y
    - t: t" I6 H  _4 y0 W
  382. LDA #$1E) W. f% V2 q9 f; L+ k4 X  Z
  383. STA Sprite_0_Tile
    / \- @% f/ M5 S8 I+ w) ~( h' L1 O
  384. LDA #$20
    ! ]7 T% A4 s  X# O; G; z
  385. STA Sprite_0_Mode
    + ?% U7 N& x. H- p+ x
  386. LDA #$00
    / P( R( {5 N; S! e( j7 i! E
  387. STA Sprite_0_X' d* A; L, A' C' b" H% Z

  388. ) ]! _3 M, Y$ y. J3 ^
  389. CLI
    ! Z) ^! Y2 Y% P; H* H1 S9 d
  390. JMP Loop
      [$ v7 K5 l& y7 N* |9 n0 Y( a  d+ P

  391. . }; X& v: C  U; C7 y7 f
  392. ;==============================
    . t# t2 W6 d  l2 F& }8 P. |
  393. ;死循环, 等待NMI中断$ Q! X' q" I$ S+ L
  394. Loop
    ) @( y) O0 d5 `7 m# `
  395. JMP Loop( O& O# C- F8 E" ~! }
  396. + B* r0 D/ c, }1 v% p0 P2 T
  397. ;==================================================- X5 B- L( ]0 p- r. Z% h9 W9 U
  398. ;NMI中断处理0 W$ S+ i) Z) B4 t: W, L6 r/ k
  399. NmiProgram7 {, u/ O8 O3 e
  400. PHA" \* V; K6 o, {' V9 |
  401. TXA
    ' L6 {/ I' z1 e: e; x
  402. PHA
    3 t! C: P! |5 m9 f% F- Y
  403. TYA. L1 Y: L% _- i0 T% k- n: h
  404. PHA
    * m. j: [. \# e/ S' e
  405. ' }& m, o( J& U+ ?3 d3 m2 d
  406. BIT PPU_STATUS3 _: l. t9 F; I% V1 a
  407. 1 o4 b. Z  _9 C. s, l  C
  408. ;关闭PPU控制
    5 T" Z3 m% t8 U* x4 Z. L- Z
  409. LDA #$00
    : a2 u5 K9 _6 F. g8 R# V! G" u  V
  410. STA PPU_CTRL
    ; t  [$ y, x& g2 @

  411. # ^$ i+ h1 d3 T
  412. ;处理PPU
    $ S! ?3 s" \( I: r5 n5 M
  413. JSR PPU_Process
    8 K$ H8 c7 J5 O/ @0 v0 s

  414. $ s' R( \# j& F( Q, l1 S
  415. LDA #$00
    " W, c4 r! |4 Z% m  f0 y( T4 j
  416. STA PPU_OAM_ADDR
    : p+ \& v2 y: ?( }
  417. LDA <Sprite_0_Y8 m: u" L5 N% O- W/ y0 L2 r3 j
  418. STA PPU_OAM_DATA* W- Q/ H+ X; u* N$ T9 S* m
  419. LDA <Sprite_0_Tile
    + i  u) T6 S1 x, h$ n
  420. STA PPU_OAM_DATA
    * L; T" O5 C1 \5 s
  421. LDA <Sprite_0_Mode
    / r3 N! \9 ]( z
  422. STA PPU_OAM_DATA
    % Q3 n) u- h  l6 f8 w3 `
  423. LDA <Sprite_0_X/ m- s* p& V* g" F" H
  424. STA PPU_OAM_DATA, G% X' O7 ?) D& V0 D) z5 {
  425. / I% j. A7 u6 V4 l* Z" ]  s$ R# [
  426. ;开启PPU控制
    5 Z: Z+ ~% Y7 ]6 W  @1 y
  427. LDA PPU_Ctrl_Buf4 B: |9 `; Q5 o  ~+ }
  428. STA PPU_CTRL
    $ V! i/ N# n& H/ n+ g* }: e6 ]8 ~
  429. & X  p( ~0 ?1 v: Q0 U5 t+ c7 ]' j2 p  Z
  430. ;屏幕滚动
    6 _3 d  |& ?  L  i. H3 ?9 I
  431. LDA <PPU_Scroll_H
    / X* @: X1 A, s. Y1 x1 k/ p/ @
  432. STA PPU_SCROLL, B. W" K8 c! ^
  433. LDA #$00, [" u5 W- P6 p+ L
  434. STA PPU_SCROLL* ^/ j# c/ s, ?% s

  435. * ^0 w7 o% r/ @1 o# w& R( A
  436. ;手柄处理
    2 N7 ~  B* @3 @( V8 \: V$ c
  437. JSR GamepadProcess# `/ E# j4 j; t9 J& p
  438. 5 Y# T% x" e7 y! H& K& h$ R1 F# E
  439. INC <PPU_Scroll_H& c& I# q5 O' Y! ^: M. p0 v. j! |
  440. / u, x, Z4 q$ p5 a
  441. ;启动0号精灵碰撞检测: W  K3 d" ]: y& d
  442. LDA #$01
    0 `# L8 k7 Y, R$ A
  443. STA Sprite_0_Hit_Move_Direction
    9 i# x2 E9 X/ {% x+ F3 C
  444. JSR Sprite_Hit_Test% n0 |. k! E. A: p
  445. 8 L; u* e, \7 x4 d. f8 W' T
  446. PLA
    0 h4 v5 `4 k8 x9 P: z  U/ N
  447. TAY' ^& F* F! Y" k  T! ~. j0 s8 _
  448. PLA
    / k- U2 B. l( s8 H- r
  449. TAX
    3 y) |- Z; H9 W3 F* V
  450. PLA* I0 \: ?; i7 u6 U8 Q* Z- m4 I: B2 B
  451. RTI
    / Z1 ~3 Z  ]& }9 o0 ~4 ]8 n

  452. - |3 j2 G1 v) o) ^4 n. C
  453. ;==============================6 H8 s/ m0 C0 M
  454. ;0号精灵碰撞测试
    : S3 X2 I( {+ @6 E) _" u
  455. Sprite_Hit_Test( m! k; p& h- v" T+ A
  456. & n& h- a1 Z2 Z  ~6 X1 _
  457. ;------------------------------8 J7 D8 d+ }+ k4 C' D
  458. ;等待0号精灵碰撞状态取消
    $ g: f6 T' o. U; b8 S: a) u1 U
  459. LDA PPU_STATUS7 f! a" A9 R) Z
  460. ASL A
      [2 M( Y5 C: ]
  461. BMI * - 42 V/ ?1 S, u# K+ h. N$ |& y
  462. - P+ p) U* X) d: h
  463. ;------------------------------: f, Q1 E( a' p2 E# j, O
  464. ;等待0号精灵碰撞发生) J& _$ V) k6 F4 x
  465. LDA PPU_STATUS) Q7 O# Z1 P0 {$ ]# _6 f1 ~* ~% @
  466. ASl A
    # y- n0 [) e2 i  `
  467. BPL * - 4
    - t$ v7 u1 e  H1 k1 z: t
  468. : N0 w" K' k7 W/ ~& ~3 C
  469. ;------------------------------
    4 g3 A  v, V' R; |# S
  470. ;行消隐等待3 r/ B- V" @* h0 X4 w! k
  471. Sprite_Hit_Scroll_Wait
    6 o- {1 {- E2 u
  472. LDX #$28' i, M6 D( f! j" N2 y- S! y
  473. DEX
    ! W, I- m1 s, c, n/ M9 H
  474. BNE * - 1) p& @7 a0 |" p2 q7 d$ o; k; I
  475. 6 A9 G/ X; t, Z- P1 W! q4 u
  476. LDA Sprite_0_Hit_Move_Direction0 Q3 P1 x8 B* b5 _+ Y
  477. AND #$01
    3 Z6 g0 R  O" ^3 A' M
  478. BNE Sprite_Hit_Scroll_Set_Right* c/ c" S, h2 |" m

  479. , h# o- A( K' S3 p
  480. ;------------------------------* `+ Z7 ?2 d/ ?  C; G8 A* E
  481. ;分割画面向左滚动
    ! a* }2 Y: ?" R" o; Q: b
  482. Sprite_Hit_Scroll_Set_Left* S; u, y! v  j( C1 b
  483. LDA PPU_STATUS. M/ i0 |4 m* ?. I
  484. LDA <PPU_Scroll_H+ f+ M' t/ r% _+ C
  485. STA PPU_SCROLL
    . ?. n3 o8 e, G1 _; q
  486. LDA #$00; b2 @: e$ z' m0 X5 a3 N9 d
  487. STA PPU_SCROLL* ~. U' o5 h# k, [: _+ r. X6 g
  488. RTS
    0 }3 r. t8 s3 D
  489. ! v+ A6 O) T* W+ ~
  490. ;------------------------------+ H: {6 ~8 f6 ?& \% ]7 W3 [4 e1 y+ |
  491. ;分割画面向右滚动
    " S  ~0 k8 @$ i& k4 f
  492. Sprite_Hit_Scroll_Set_Right
    % _0 \) c. n- L# g) z
  493. LDA PPU_STATUS
    $ o: L2 {" e4 M% l
  494. LDA #$00- I6 T- w" R6 U8 k& _- h
  495. SEC$ ~4 n  D3 d  u5 Z7 p* }4 w
  496. SBC <PPU_Scroll_H
    $ a1 a0 A  g8 \' }; p5 h
  497. STA PPU_SCROLL% I  \' u' o7 P, p
  498. LDA #$00
    - {! A2 l; @3 [) ^
  499. STA PPU_SCROLL" O; Y# S# A. d  A# t
  500. RTS
    # F/ j, I0 r; S7 \
  501. 6 h& V* L0 _6 L: S( A$ |3 D
  502. ;==================================================
      o1 \& h% X- m$ X! w- o, H
  503. ;IRQ中断处理: p5 k, I# k; h8 z) l3 s
  504. IrqProgram2 ]6 @* V- L9 [" U. a* r
  505. PHA
    ; y$ w3 s* u8 S' u, U8 @5 X
  506. TXA3 n& Q- o& k, {2 ?! ^
  507. PHA2 Y2 T4 o* Y+ k9 }3 D, W9 ~+ [
  508. TYA
    8 X4 ^; _' C1 w7 u2 r0 T
  509. PHA
    , p) V' s0 x" s/ x* j/ B8 q

  510. 1 S. V6 E$ ^+ w: q' M0 t" _
  511. ;关闭IRQ
    0 K7 P  r0 z9 p+ Q3 e! z
  512. STA MMC3_IRQ_DISABLE3 M# k; m+ [& T5 R, W7 z+ g
  513. ! ]" Y2 s/ f7 A. {* m9 U. u
  514. ;允许下个IRQ触发
    4 ?0 H9 R: q2 [. I+ t8 E
  515. STA MMC3_IRQ_ENABLE
    ( C6 e+ s, c! r- a/ d
  516. , R/ x* ~3 X3 ^+ M$ M
  517. ;IRQ处理, 15线后继续触发/ H' s/ K/ k: B# B, a
  518. LDA #156 R& f3 ^3 p3 U# R5 c3 t
  519. STA MMC3_IRQ_LATCH5 S% }& [, o, w  d
  520. 4 h8 F4 h' Y2 S5 G7 i
  521. LDA <IRQ_Index
    , O$ G3 _/ O; g. F( v, _
  522. BNE * + 4/ c" O# H* ^! H% j& k
  523. INC <PPU_Scroll_H" b$ p8 t& q  c
  524. 4 j& x. K; M) k) Y
  525. ;设置屏幕滚动) u5 [* X- b: [8 H' B$ r, X
  526. LDA <IRQ_Index
    " M9 @5 d4 v2 R6 U& o1 o
  527. AND #$01
    9 m+ |- W, O3 D0 Q) L9 @
  528. BEQ Irq_Scroll_Right6 O% i3 x- v! g; [* V" \
  529. ; G5 U/ t5 r2 M( N1 a
  530. Irq_Scroll_Left
    ; s! {/ ]& Q4 X' G
  531. BIT PPU_STATUS, i$ ?. P5 ?$ a; n0 t3 @
  532. LDA <PPU_Scroll_H
    0 J+ ~8 \. v3 t! r
  533. STA PPU_SCROLL
    2 m- d2 ]: D' |) ]6 M8 W& R
  534. STA PPU_SCROLL
    , c7 O- |1 `1 L5 N5 e7 U4 C+ m
  535. JMP Irq_Scroll_Over
    / T2 Y$ S# ?& q3 m
  536. ' k+ d0 y% B. A0 T, E  E% i' ]
  537. Irq_Scroll_Right+ r5 g% c9 `9 B) I
  538. SEC4 f; P5 T' [8 n( i" W- X
  539. SBC <PPU_Scroll_H. G: b1 B+ o: Y$ \
  540. STA PPU_SCROLL# _+ n8 _  b; }! Y- ~( j* \1 G' I
  541. STA PPU_SCROLL8 C! P/ i0 u0 R$ O2 g4 z. O
  542. Irq_Scroll_Over
    5 ~+ B( J7 b8 Y" |/ [
  543. ( Q, Z* R. I+ N% ^9 H3 p
  544. INC <IRQ_Index" @- |2 v% H0 ^

  545. - h! {/ p4 j+ ^# c8 C  s
  546. LDA <IRQ_Index* L1 K! o7 \/ g" j
  547. CMP #14
    # u5 \& b2 y$ |1 m
  548. BCC * + 5% q+ \. T9 x+ r8 |7 W
  549. ;关闭IRQ
    + h0 M& `4 `# x6 r# @- v: q" T
  550. STA MMC3_IRQ_DISABLE
    ' }; U9 Z) l, t+ @4 X4 _- O

  551. - B6 ^. T! b, }& l6 z8 C9 @+ E
  552. IrqProgramEnd
    3 r" Z# k. W. }5 d8 T
  553. PLA! }9 c  y: _  W. c
  554. TAY, e4 \; U0 k" o2 k; O
  555. PLA3 l$ ?! Q' d& v$ e! a1 @! Z
  556. TAX" C; D. W8 U. D7 h  ?2 s4 w# {# v
  557. PLA
    ) W) i* j; y( Q5 _  C6 `! w
  558. RTI0 ^; ^% Z# \: g3 x) L% }3 I" ]& O
  559. 5 w3 d- S9 Z/ ~3 ?/ y- P
  560. ;==================================================
    ( n  @  P5 t7 N% d" P; u; |, ~) j
  561. ;中断表' b7 z, G- P$ c3 E( i+ [4 q
  562. .ORG $FFFA* ^6 e$ v; w1 @. E' @* c
  563. .WORD NmiProgram
    3 E5 I. S3 D# \  B6 Q; N* q0 S/ l
  564. .WORD ResetProgram+ f6 P% a# P! T+ A, C, e4 T
  565. .WORD IrqProgram
复制代码
' A/ l+ r4 l* J8 I  o

评分

1

查看全部评分

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

本版积分规则

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

GMT+8, 2026-3-17 04:03

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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