EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]$ M) c% z& a& L5 @9 p2 P
  2. ;FlameCyclone 20230710
    8 i/ z+ {  G/ o' j) W

  3. 8 T; Y% x/ c3 A4 U8 u: X2 N; I
  4. ;文件头3 u. E; O3 F  O, t* s
  5. ;======================================================================
    6 W. h) F  Z1 d5 d- p
  6. .INESPRG 4                                              ;16KB PRG 数量
    , V8 a' {5 |& H6 f
  7. .INESCHR 1                                               ;8KB CHR 数量* ]1 P& O  `$ _+ J
  8. .INESMAP 19                                                 ;mapper 19
    % ~* }( A1 Y; x# t; h9 N, N
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    1 o' C: `1 l1 V* _

  10. , _  y& @+ {* F9 j/ \4 r2 Y2 l
  11. ;必要条件
    8 Y; X8 S8 e1 w9 j7 A
  12. ;1.持有CHR ROM4 d& E1 x5 I$ h0 Z1 D4 e' g3 l
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    2 Y! j1 b: o$ R! ?1 C' I
  14. ;3.精灵内存(OAM)不为空8 K- _. z! T- v- y* S& I4 w

  15. 5 b; H* X5 ?" A& V
  16. ;==================================================
    3 y  M' r% H' X. F6 e
  17. ;NES端口常量
    5 Q! U- Y$ r5 V* i" N8 g
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器8 ]2 G2 I6 J0 T
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器! k6 w  n1 [! z  ~
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位2 `8 s4 m9 A0 @0 j% m8 \
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ' L' X; }# S- I& o+ ^2 V1 s
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1( c% c: [% K9 L* K" |! V. w
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    5 ^0 A( i- m1 q, F1 X. u, M
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加) f9 c/ g. R: M2 d8 z0 N# r
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    2 z8 y. D: |6 x9 L7 [
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存+ E' y/ s( w! W. v. ~4 g' Y
  27. APU_STATUS              =   $4015   ;声音通道切换8 i  J: D0 Y# B/ D% l
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通8 D' G' l0 W& [
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    & G1 V: w9 p9 I7 ]# Z  S1 n

  30. / V# ~( w5 N: d( S
  31. ;==================================================
    8 p1 p6 H2 ~# n5 c" I
  32. ;MAPPER 19端口常量
    2 c% X2 F! P& l) G7 M: h4 e
  33. M19_CHR_0000    =   $8000
    9 C9 O* x0 ^$ x! u) }+ {0 g  }
  34. M19_CHR_0400    =   $8800
    7 y; Y& j" k5 K( e$ @1 ?4 i
  35. M19_CHR_0800    =   $9000
    & p7 k: K9 F* V# W  T
  36. M19_CHR_0C00    =   $9800
    & C/ x+ }+ \, }
  37. M19_CHR_1000    =   $A000; E% H" g1 N$ B# j; r, n
  38. M19_CHR_1400    =   $A8001 H+ D) Q3 h  B0 O+ E
  39. M19_CHR_1800    =   $B000
    6 O  P6 V1 B2 _8 I" L
  40. M19_CHR_1C00    =   $B8004 a( z; i$ C: a
  41. M19_NT_2000     =   $C000  V0 B) s3 U5 _) o/ F- j
  42. M19_NT_2400     =   $C800
    0 M; R% g% n+ ~; ]/ h. w
  43. M19_NT_2800     =   $D000
    % B% J9 _% J0 K7 V* u) t# e
  44. M19_NT_2C00     =   $D800
    / y' X, M6 B5 ]0 U* I3 j
  45. M19_PRG_8000    =   $E000; x; n+ ?* s- j
  46. M19_PRG_A000    =   $E800
    ; f& O+ a) m0 N6 }% q; W3 {
  47. M19_PRG_C000    =   $F000: p' ]. r4 ?9 t8 B) `
  48. M19_IRQ_COUNT_L =   $5000% t7 }5 J' i, o: y. {* w
  49. M19_IRQ_COUNT_H =   $5800$ g  r6 e2 n% b

  50. ! ^% G) y) Y/ o$ c0 T5 l
  51. ;==================================================% Q- v9 s# g! C; _9 n; y
  52. ;程序块配置
    / {' E' m$ i5 u  i+ C
  53. BANK_DATA_MASK          = $071 z! W8 J& I+ F& b: y$ F. h
  54. ;--------------------------------------------------
    ' e/ Y9 c6 w, |: [7 D5 b, w( G
  55. RESET_BANK              = $07& [$ y" b  S. F( C6 ?  ]
  56. RESET_ADDR              = $FC00
    5 N9 w8 k3 F/ u  X* Q

  57. ) t, P( M+ l8 y; d
  58. ;==================================================0 u9 e/ M. U: L7 `4 v& c
  59. ;图像块配置
    5 t8 S# H* a2 d) N! D8 F& g6 H
  60. CHR_DATA_BANK           = $08
    * s) }) I9 X% D. [' Y" P

  61. . {5 s; T& m& l* q
  62. ;==================================================$ ?6 @! w, b, C
  63. ;零页内存地址配置
    6 O2 W, l7 S3 H' `& d
  64. Use_Ram_Addr            = $80% q. r  |: H9 @- y9 ^
  65. PPU_Ctrl_Buf            = Use_Ram_Addr, u- E# K: S6 }& l6 |% e
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01! u: }. j6 t) ~6 s" _
  67. PPU_Scroll_H            = PPU_Msak_Buf + $012 Z: Q/ c* Z2 S. D
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    7 [( |* T, Z* f# d1 V& u
  69. FC_Data_L               = PPU_Scroll_V + $01' n+ b* Q( s1 `5 l3 t
  70. FC_Data_H               = FC_Data_L + $019 [7 @2 r5 Z4 y6 u2 L9 H5 |
  71. FC_Data_Buf             = FC_Data_H + $01
    ) O: {+ `( G5 Q3 R* c/ l. L2 n
  72. ;==================================================
    : x* m! Q) `" I/ \& Q; \, I

  73. 9 ]% {0 @9 {  C5 l( T9 [
  74. GAMEPAD_MERGE_FLAG = $04- w* F, m; Q  L: n+ e5 V
  75. ! v" I1 O1 q  T" X
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    , g+ H  P: e% V
  77. Gamepad_Once            =       Gamepad_Keep + 2
    ( E; p& `3 o+ b3 L" w1 N7 }0 D
  78. Gamepad_Temp            =       Gamepad_Once + 29 e) ^7 E$ u; ?6 X  {
  79.                                 8 z- o# @* ?' }7 K) X7 w
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    ! r6 c3 |1 n% F& j
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    " j! U$ @' u1 G! a* l+ F
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    0 a- r+ ~( G, q6 _5 H" [& x  q* @5 J
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
      ]1 O# K4 w$ q9 C; p9 _3 ~0 Q; J8 C
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    4 o: ^' z2 ~5 K3 P$ h+ f
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    0 l: V" e% b) [" @' C

  86. $ x0 F& ]  T. C3 Q) j5 A
  87. ;==================================================) Z+ t0 S) ]! m2 G
  88. IRQ_Index               =       Gamepad_Merge + $014 N+ g  ?0 F9 @
  89. ;==================================================& w' ?3 t$ v4 f& b
  90. 9 x; y3 v* W6 L  P5 ]0 x
  91. ;CHR图形数据! c5 V: `; c" ?8 M& U/ p
  92. ;==================================================0 J+ O% z, Z& U8 F& G
  93. .BANK CHR_DATA_BANK/ S3 ^8 v9 P) v  [; v; E7 _
  94. .INCBIN "chr_bank/chr_data.chr"
    / z  K8 O; H- R7 G1 b

  95. . B5 W7 m( o0 l$ f
  96. .BANK RESET_BANK & BANK_DATA_MASK$ u' S! i0 X5 a( `0 ~3 F8 k
  97. .ORG RESET_ADDR4 G( C7 y* V" @7 q' N0 I8 ~

  98. : x. V' q, b( Y- `2 O
  99. ;--------------------------------------------------
    ( V/ S5 S1 X; Z/ ]
  100. Attributes_Data6 m( u; Q8 \/ o# W/ a' O  m9 B
  101. ;命名表属性. K+ Z1 ?+ u% W/ y
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    4 k+ \% P  s  U! w  R
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA6 @- A1 Z+ j, F- {3 {9 K
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA2 l! v+ v$ x2 R3 t2 W
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55- ?8 F2 _2 g" o5 I) K; L
  106. ;--------------------------------------------------+ H+ i. G% L, M) d6 x3 l$ p5 F
  107. ;调色板数据
    7 o3 V1 |1 P5 x. ]
  108. Palette_Data
    # F" K! o# }4 A' |7 ~
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    6 R0 S/ p# t% {# `- X/ o: U) T
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    ; i% w( @  O4 G- \: |5 a( ~
  111. 4 k% b/ d/ s* a) Z( F7 _
  112. ;==================================================" ]' }+ y% v# g
  113. ;命名表初始化
    & o' E5 h* D. c; `& J& E
  114. Init_Name_Table
    ) L9 C4 K2 K( X, T+ U
  115. LDA #$20
    $ \. K  A- g! h) d8 v: h7 X( _& F
  116. STA PPU_ADDRESS
    6 c0 }, c8 \- ?7 Y6 y5 H2 k
  117. LDA #$00
    8 J/ A7 I+ C$ R* K2 e, r* ?
  118. STA PPU_ADDRESS
    ) Z! z/ p, i# M2 f# [, B0 {
  119. LDA #$00
    ; ~( R/ i9 X. V7 d: U6 {3 X3 f' x8 M0 [
  120. LDY #$00
    + s+ v5 h5 T; l% A  a% n
  121. LDX #$10* w2 j7 o1 \$ h! _5 s; A# G
  122. Init_Name_Table_Write' y6 G. L2 j0 L$ O. u. K
  123. STA PPU_DATA
    ( C" A0 Y1 n) a' n: `, Y) F
  124. INY2 a5 p; v  ^: T. o- m9 W' h
  125. BNE Init_Name_Table_Write+ ~9 C: o9 Z. v! k+ p" R9 _
  126. DEX
    2 R' g9 C/ |7 x
  127. BNE Init_Name_Table_Write1 Y  A1 z6 z$ j- h* Q
  128. RTS
    9 s4 [5 b+ l) o) `3 B

  129. " ~2 Q; T' F/ x* J! I0 k7 q# k
  130. ;==================================================
    * r  D7 e5 ^# Z* q
  131. ;调色板初始化' P# u  D# `6 o
  132. Init_Palette
    3 U' a7 l, ?5 _6 r( X$ U
  133. BIT PPU_STATUS
    ' y. N0 g$ D" Y( v0 C
  134. LDA #$3F/ j! S4 L+ |/ O: S$ E' v
  135. STA PPU_ADDRESS# {! k* H; M# D# L' z
  136. LDA #$00
    . S2 L, a# f! ^: N( [
  137. STA PPU_ADDRESS
    4 U$ o7 U7 z6 I9 G8 d' W0 ~& Q
  138. LDX #$007 `0 U1 M* d  ^* }  L
  139. Init_Palette_Write' _2 f- `' b4 x0 U0 k1 M
  140. LDA Palette_Data,X
    ' k* p7 {# a; F
  141. STA PPU_DATA
    ( R3 }" ~( ]# Q  f- ^
  142. INX
    9 F3 @( O4 e( B) m9 F
  143. CPX #$20! r8 C+ m& J. m1 a2 x0 e* o
  144. BCC Init_Palette_Write" x. T! m5 c( ]4 e
  145. RTS
    3 a' `6 b. Y& y, s

  146. 2 r& v5 _* K0 p* F, K8 x
  147. ;==================================================
    % s, y1 R1 u) T( S/ t
  148. ;设置命名表属性
    3 ?9 m3 j7 e. K0 }( Q/ ~' y+ E+ V, r
  149. Init_NameTable_Attributes5 I. `3 u- U* K+ f
  150. BIT PPU_STATUS9 s! L9 R! r; ?! N% W# l, o( Q
  151. LDA #$23
    ! n2 C- s: _: [: y/ F% Y1 P8 A2 Y
  152. STA PPU_ADDRESS
      j, S9 L" H' y0 S3 }8 ?
  153. LDA #$C0
    7 {% r3 Y4 Z+ z% T, d
  154. STA PPU_ADDRESS$ [8 Q4 p; |# \5 e
  155. LDX #$00
    8 `. [, J  V; V' T
  156. Init_NameTable_Attributes_Write
    % U& y) a2 e0 g$ i
  157. LDA Attributes_Data,X
    0 A2 e# j: x, c, @/ i2 y
  158. STA PPU_DATA
    ( L1 A' g( ^) w; |" ]& R: [
  159. INX
    8 r- C& o7 e8 d4 j0 C9 z  E
  160. CPX #$40% U3 E: ?( T9 H
  161. BCC Init_NameTable_Attributes_Write+ X* Z8 g. x$ ~4 p* M9 E
  162. RTS
    / R: q- n5 q( g) m

  163. 7 E% B; a3 e3 r- ^( ?# A
  164. ;==================================================/ k4 W5 j/ a6 H2 p6 y6 T& e8 k
  165. ;初始化命名表文本* H1 g$ _, D( I/ Y3 d' _6 q" I
  166. Init_Name_Table_Text
    4 s. b3 P0 u: n+ K2 H
  167. BIT PPU_STATUS
    , Y' i' j; B( ~$ Y
  168. LDA #$20/ B- y# g% t! d+ m, ~6 f
  169. STA PPU_ADDRESS
    ' W. z$ v" d# m$ A
  170. LDA #$00
    $ W2 b  d' \( V1 V1 I3 i
  171. STA PPU_ADDRESS
    / |5 i4 ^/ ?+ s, U
  172. LDA #$00, M  v3 p1 H5 o. \4 \8 x8 U/ y$ z
  173. STA FC_Data_Buf6 i6 C3 `) h( ^8 D) X6 c+ L& }/ |
  174. LDY #30
    ! Q" E) z# D9 \
  175. Init_Name_Table_Text_Write
    5 e2 j* [; X; k6 n' x# r
  176. LDX #32
    8 i1 X: n. o0 o$ `7 W
  177. Init_Name_Table_Text_Write_Char: x. J8 a# \( p8 }
  178. LDA #'0') D! g' S( l. K: h  @
  179. CLC
    5 _* j0 S4 _! I9 w6 e
  180. ADC FC_Data_Buf
    - A" d  y, X' B* o
  181. STA PPU_DATA
    7 x2 M. b2 ?  H; T( |
  182. DEX
    ; T4 J; J) d$ S& _$ \: J  J8 D
  183. LDA #$14& F/ {9 _4 W5 e6 \% X
  184. STA PPU_DATA8 t. ^' ^# c& V
  185. DEX  t" I6 i( a2 m) V
  186. BNE Init_Name_Table_Text_Write_Char
    0 d2 ^: Q" j3 k# |0 P1 f) C
  187. INC FC_Data_Buf
    4 \9 c: x- Q9 |, y/ W( p
  188. DEY
    - p+ v( Y1 J& U; a& u; {9 ]
  189. BNE Init_Name_Table_Text_Write  @0 i; R) w. A1 q* E$ M& O
  190. RTS
    ( m, i6 i& @6 a# e! G
  191. ! F; z. {4 X, z8 H
  192. ;==============================) p  q, L5 X' F% P7 V
  193. Init_OAM_Ram;初始化精灵内存
    / c7 m9 T) i2 R( e, ^6 \  ?6 M, e
  194. LDX #$00- O2 w$ x0 W. |; Y, V
  195. LDA #$00
    ' j$ o. ?) s) |
  196. STA PPU_OAM_ADDR
    3 \3 _( w# v& W' ]! j* o
  197. LDA #$F8
    6 k  N$ a$ V. S; ~% N6 M+ k
  198. Init_OAM_Ram_Write
    / s1 Y) a: p$ {# H) `: k' p1 _& E
  199. STA PPU_OAM_DATA0 V0 X, L: J3 p
  200. INX
    + N6 t  j0 b8 ?+ y3 A5 G* y
  201. BNE Init_OAM_Ram_Write
    ( v1 b! F0 y7 b. H+ F
  202. RTS) n# D. Z5 g# `& K; Y
  203. 4 j3 j" z; F9 p0 H+ [0 D
  204. GamepadProcess;手柄处理
    ; N) }4 z) U; G# B
  205. JSR GamepadDatacan
    1 z1 [8 s" B" k
  206. LDA <Gamepad_0_Value, t; Y& c! }9 x- v0 v
  207. STA <Gamepad_0_State
    6 o* e0 L2 f. ], h5 \( C
  208. LDA <Gamepad_1_Value
    8 [$ k% N/ w( C  k0 @7 L/ E
  209. STA <Gamepad_1_State' w8 Q9 B* x- L. ~
  210. JSR GamepadDatacan; f" i' W; N1 ?) g" g3 F
  211. LDX #$01$ B# s4 x  P% R9 C# a
  212. GamepadMergeCheck;合并手柄输入检查0 c; I  _' t8 N  E) F. @
  213. LDA <Gamepad_0_Value,X0 K8 H( O% u2 ~6 s
  214. CMP <Gamepad_0_State,X
    4 |: P7 q. C. x: u; A7 i
  215. BEQ GamepadMergeInput; r; N6 i4 ~0 E! Y( i$ P
  216. LDA <Gamepad_Temp,X6 |: w$ \3 p" Y( Q" q4 `! H" {
  217. STA <Gamepad_0_Value,X
    # p9 D# D& h0 S9 p
  218. GamepadMergeInput;合并手柄输入
    1 y5 P. F( F2 \! {1 B
  219. DEX# I0 l% e) E- {- I& w( B: r% Z
  220. BPL GamepadMergeCheck
    0 s, }& ^  |5 k8 {9 v* l* V
  221. LDA <Gamepad_Merge( B9 T4 X. }3 V# N6 I' W% }
  222. AND #GAMEPAD_MERGE_FLAG
    . W, k- Z3 M) ~9 M
  223. BNE GamepadStateProcess
    ) X8 r4 m# [; k- E3 V6 F" t$ J8 \
  224. LDA <Gamepad_0_Value# v* y! d2 x4 j1 S  `8 i6 x
  225. ORA <Gamepad_1_Value+ j: w/ j! H1 g2 M
  226. STA <Gamepad_0_Value3 ^/ ]. v  _/ X0 _: Z2 a
  227. GamepadStateProcess;手柄状态处理9 M# l8 M, q; p/ n1 U% F5 z7 e! Y. A
  228. LDX #$01
    ! w3 F8 f4 N5 P
  229. GamepadStateSave;手柄状态保存
    0 m/ V% _' u& s1 @
  230. LDA <Gamepad_0_Value,X% E  [( J5 W: _7 G4 G4 X
  231. TAY
    ( @  Y, u4 n; J$ M  D& L+ h
  232. EOR <Gamepad_Temp,X1 Y5 V) V9 v& R7 X9 s
  233. AND <Gamepad_0_Value,X
    & B! |' h, g0 z! O- }
  234. STA <Gamepad_Once,X
    " A9 w5 c/ u* W; {. y  n* U7 a4 q! }
  235. STY <Gamepad_Keep,X
    ! D7 ^, ^( I: a8 C
  236. STY <Gamepad_Temp,X8 K% {8 F1 W; j$ C! a1 ^3 }4 w
  237. DEX. Q! U- t. s* ^: k8 Z8 v
  238. BPL GamepadStateSave
    + b, A- |. q7 x8 W
  239. RTS
    9 t5 y2 r! s- q% Z2 m. {
  240. ( U# U5 E* f2 |! G# W- Q( q
  241. GamepadDatacan;手柄数据扫描: V+ }6 h. s8 A6 n& @
  242. LDX #$01$ e- ?6 z( t/ D' @% B' B
  243. STX $4016, R0 ]9 C" H' ?' h0 W! O! V& y0 T, R0 J
  244. DEX) j# {2 s! b: R6 O; e
  245. STX $4016
    - z- ~- B# y+ }$ d  A
  246. LDY #$08
    & I+ \" n( g. V+ U6 S5 K
  247. GamepadPortScan;手柄端口扫描
    ! y7 G' }- g' {( z: S
  248. LDA $4016
    " h9 {+ n/ _7 {8 h' N
  249. STA <Gamepad_Port_Value
    2 ]( g6 J- K) d: n/ U5 f8 Z; Q
  250. LSR A
    % _( t( R( X) X
  251. ORA <Gamepad_Port_Value, D9 @, s  V  {( I9 I
  252. LSR A
    - p+ [" ^; d$ N* S1 l
  253. ROL <Gamepad_0_Value4 s! \/ ~. r9 n0 q& \0 n: q8 |7 ^
  254. LDA $4017
    & E+ i& M, t" _, A( `: Q4 j  l; V
  255. STA <Gamepad_Port_Value  `( B1 t2 O! v( {: M2 N
  256. LSR A
    ! m$ q9 y( o8 B* L
  257. ORA <Gamepad_Port_Value& Y1 M# f# b' e
  258. LSR A2 w+ {) y# K3 e: _
  259. ROL <Gamepad_1_Value
    0 [; Q, W' j5 E( y) ~4 Y
  260. DEY% ~. |3 ]1 O  M1 N4 t3 w, l
  261. BNE GamepadPortScan
    6 Y4 r3 b% d2 G& u
  262. RTS
    * Q1 E- A# D9 s7 D
  263. 8 P9 H  w. \# |9 y0 q4 z; V+ u" a
  264. ;==================================================
    - G4 w) p2 k  U  P- F. ]. Y( \0 o
  265. ;PPU处理8 M* m* k, m0 N$ }7 f
  266. PPU_Process. w" u0 n' w1 e* @
  267. LDA #$00: Y2 q( x- M* a  i2 B
  268. STA PPU_MASK
    - H; Q! `' y" l3 s

  269. ; f. d$ R8 H3 a1 N' j
  270. BIT PPU_STATUS# P' ~/ y0 p% C& `! G: b. I
  271. LDA #$20
    . a# Y( y, u8 ]  \
  272. STA PPU_ADDRESS
    7 ~# P+ f& C! d- s% w0 O- R- J! W
  273. LDA #$000 @, P% A6 H/ Q' P$ p' _
  274. STA PPU_ADDRESS6 I9 ~+ B; S) Z+ u

  275. / H- v3 o7 [, g) q' [, z
  276. STA PPU_SCROLL
    # |1 ]+ y& z4 @6 n/ Z
  277. STA PPU_SCROLL
    % c4 N" j" ]0 X' B+ B

  278. * i. t( c8 a, m$ U1 A. B3 Q
  279. LDA PPU_Msak_Buf  T" O  j$ F. j* W
  280. STA PPU_MASK
    1 B: |) {6 g+ \) \% o

  281. ! h" `- C" u3 u" W
  282. RTS
    * h: K; n0 D2 S4 T4 u' o5 d
  283. ! }: G7 ^0 p  X, K7 V$ y; {
  284. ;==============================
    + s/ {" m; n, G  ]# k
  285. Time_For_Vblank;延时等待: t0 U0 Z$ l! s' d# {% g5 Z0 _
  286. LDA PPU_STATUS
    3 g0 Q8 r! C% O4 z( V5 d9 ^
  287. BPL Time_For_Vblank4 W+ X' [, k; ~6 C( R: c
  288. RTS
      T5 ?+ L  _7 a

  289. * _. U. K$ Q8 ~8 B4 L4 h
  290. ;==============================
    , X( P& q& V- o1 V
  291. ;初始化MAPPER19
    4 l  P4 f& D% Q
  292. Init_Mapper19% @  U, i7 H/ ?$ D8 J) W: |# |- ?
  293. LDA #$00
    ) H6 T; ~0 i$ Y8 T
  294. STA M19_CHR_0000% ^" x1 U7 e* J- \: q
  295. LDA #$01
    ; C/ U1 v3 M2 y5 x& W
  296. STA M19_CHR_0400
    " r6 i, Z2 r6 T9 j
  297. LDA #$02
    * c# m. ^' x/ E. ^1 ?6 S& x# W
  298. STA M19_CHR_0800
    " I# f8 L4 Y* \  I; t  d( [- L5 q6 K
  299. LDA #$03
    6 N9 Z' {2 j5 \9 X
  300. STA M19_CHR_0C00
    , {# p$ D9 k8 x; j0 ]* w1 x( j! D; e
  301. LDA #$04$ H. C+ m0 p1 w2 t8 f, r9 ?5 S% A, \
  302. STA M19_CHR_1000
    9 b$ n8 o" Y; z% v8 G
  303. LDA #$05
    " ^$ A9 f: J6 |/ I4 O" _& i8 R
  304. STA M19_CHR_1400
    ( g: f5 J4 u9 ~6 V
  305. LDA #$069 U/ `  H( u. F' `  E( A
  306. STA M19_CHR_1800
    # M+ R) u: b. [% A0 [8 a0 v
  307. LDA #$07% T9 t; w# S% r  ?6 a+ R8 D
  308. STA M19_CHR_1C00# [% W; p/ Z$ B4 q  ~

  309. - o# ~! F0 {" M5 @
  310. ;禁用IRQ3 m) ]& U2 S4 W: k9 v. l
  311. LDA M19_IRQ_COUNT_H, g. N' M* _+ U3 ^
  312. AND #$7F% M( Z: D0 x0 d3 `; u
  313. STA M19_IRQ_COUNT_H
    ' R8 m% [; z3 X+ C( W
  314. : i8 p) M0 Q% J' D& B( {, h+ Z
  315. ;命名表8 p$ `: r  ~, V
  316. LDA #$E0
    9 ^% ?/ t/ I( e1 Y( F, d  y$ g
  317. STA M19_NT_20009 n* h, R9 I  u4 c$ Q
  318. STA M19_NT_2400
    2 @$ ], b2 R( G; v. E3 J
  319. 0 ]" p3 j3 K1 f
  320. ;命名表
    % C2 g8 C  Y$ a; r. K
  321. LDA #$E1
    1 k0 {  z3 K$ g' m1 t' [
  322. STA M19_NT_28004 a( j. j  \) b$ v  f6 v
  323. STA M19_NT_2C00
    % O; P$ K8 l8 Q- A$ c% h0 }

  324. $ i' B; x& g! K
  325. RTS
    ( |/ q5 {2 U+ L& {3 A. T1 _( \; J

  326. 5 I6 ]5 z8 {3 v4 W$ A
  327. ;==================================================* G( _2 c- x8 x3 t0 f" S
  328. ;重置中断处理
    5 O2 j, y. R* c* O/ w
  329. ResetProgram
    - T5 \3 d0 w. U/ v( L2 y. m* A$ C
  330. SEI
    ! a8 C# Q5 ?% d/ ~3 a3 A
  331. CLD
    2 j! g9 F$ k  d! q2 g
  332. LDA #$00
    % V; v3 F, S9 n+ p( m
  333. STA PPU_CTRL; e; P" T  g+ i
  334. STA PPU_MASK. m0 B4 Z2 o8 K3 C9 M
  335. STA PPU_STATUS
    % W4 U4 A1 \' [. @. H/ M
  336. STA JOY2_FRAME
    + |1 {" A' I. V! |* ~8 y
  337. STA APU_STATUS0 v9 {0 W0 ?% u

  338. 3 G) Y% M# g+ M* }: C
  339. LDA #$C0
    ' N$ Y5 s$ b: E
  340. STA JOY2_FRAME
    ( d5 {4 G% q/ E6 s$ D/ I. l

  341. 2 d/ P( o4 ~/ ]& u/ X$ D0 X3 m
  342. ;等待vblank
    2 Q3 b  L+ c( U: r6 B6 p2 H2 ]
  343. LDX #$023 y* ^% K( o/ P$ z
  344. Vblank_Wait_1' j2 b1 t  U- O5 F' F; R
  345. BIT PPU_STATUS: |0 e/ U3 M9 G' e, y9 s5 [
  346. BPL Vblank_Wait_15 P" }0 K+ X# u( b1 S, w+ P' O
  347. Vblank_Wait_2# n3 S+ J: j( c
  348. BIT PPU_STATUS
    3 w/ ^. D+ J+ a7 l/ y6 a
  349. BMI Vblank_Wait_2  H. p4 u5 Q; G9 r( r& \
  350. DEX5 u- O+ C9 [$ b. {( \; o
  351. BNE Vblank_Wait_1# M2 f# s' \' \4 ~( d  ~2 E6 C

  352. & O8 c+ |' N: `+ L' B
  353. LDX #$FF
    . L& I# T& d. W* F* W
  354. TXS: u8 h3 i4 r2 Z) Y7 v
  355. ; B0 j1 F, Q5 g0 M
  356. ;初始化MAPPER19' p, o/ p" r* R2 t2 d! M. Z/ k
  357. JSR Init_Mapper19
    & F: |/ \; M  v, `4 z# [* O
  358. ! i: O( I/ q. ^2 A% Y# D
  359. ;==============================4 A' u8 X" O$ c) E! k
  360. ;RAM初始化
    4 M; M& V, ?/ J0 w; x+ {% s
  361. Nes_Ram_Init+ ^/ d. k9 D" _& |* L
  362. LDY #$00: I" O, ?9 N& Q1 J+ E
  363. LDX #$08( W( p3 L! b2 S% L2 A/ n4 X- p
  364. LDA #$00* K, U$ _; J0 k
  365. STA <$00- @) ?! I- \2 z- B, H. g) _2 s
  366. STA <$016 {" \  p% \+ G$ `
  367. Nes_Ram_Init_Write
    . L3 G! J$ f5 w. F5 n
  368. STA [$00],Y
    % K9 d, J! l3 q/ ^, ~8 m* C
  369. INY
    8 b6 O) V) Q( O. T! ?+ T' S5 C
  370. BNE Nes_Ram_Init_Write* u6 y9 X9 G) p
  371. INC <$013 s( z* K! C# F; z8 X: }4 J
  372. DEX+ L. K, z" n8 C: H- M$ E# ^
  373. BNE Nes_Ram_Init_Write
    - u! \2 q  A. i% \# v4 s9 y+ @
  374. ! M" y3 Z( g& R8 Z% X
  375. ;初始化命名表0 N' [! ^/ r0 C: }* ]; V% I. d" Y
  376. JSR Init_Name_Table- r; R4 K% ]4 X
  377. : M0 }+ j* D: f1 J0 Q/ U" q% y
  378. ;初始化调色板
    ; U  Z3 }. U' A8 z0 ^* s
  379. JSR Init_Palette+ _# P4 u/ o5 `" c) O1 A2 S+ t
  380. - v3 v5 P6 N$ [
  381. ;初始化命名表属性
    + i! }- n1 j% e9 L7 L% p5 h2 o
  382. JSR Init_NameTable_Attributes
    7 X  H4 ]. V: T6 |: J
  383. 0 Y' R+ g2 ^$ ~( u* q/ y& B9 u6 m
  384. ;初始化精灵内存
    4 K0 R% ~2 u% w- k
  385. JSR Init_OAM_Ram& w+ y* k+ B& f: v0 t
  386. # u. v9 N+ Q# D+ e: o
  387. ;在屏幕上写点东西
    . B& `% m7 m7 t1 v3 f* T' e' j2 s$ J
  388. JSR Init_Name_Table_Text3 r, ]. L% V4 ]2 O/ s0 L8 F

  389. 8 F9 V5 o1 e4 O
  390. JSR Time_For_Vblank# |6 @; M0 A. X! @; h0 B
  391. ;开启PPU控制
      ~# S2 e. V/ D, x
  392. LDA #$A8
    * C8 e% }: T* P. u) }* u/ d4 ^* i( j
  393. STA PPU_Ctrl_Buf
    ; ~, \7 B' i# T$ R$ B# u/ U
  394. STA PPU_CTRL
    : \' |9 X  N2 a+ y" r

  395. " W- D# D1 ?5 P. M% U
  396. ;开启PPU显示8 n$ E) H' Y/ A3 u, {  r6 H
  397. LDA #$1E& d$ M1 d! M# I& o2 D9 y1 {- d/ E
  398. STA PPU_Msak_Buf5 r: }9 E: C# S+ D
  399. 7 D. C5 Z4 [6 ]3 S; {7 f0 I: n# Z
  400. CLI
    " N5 I8 Q, m3 _+ n
  401. JMP Loop/ ^. E; i0 t# d" t1 `
  402. 8 u# v% h9 g# }2 s
  403. ;==============================
    ; [" M( r( S" ^, f! N( n
  404. ;死循环, 等待NMI中断, p0 Z9 q8 Y9 o
  405. Loop
    2 y4 s1 t: V& J) t
  406. JMP Loop
    9 x' `0 c. N: A3 v& w1 g, L

  407. + H5 d( u9 D% n( u: ^3 s0 I% B- D
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967( y4 w- p; W( a3 w) p- }3 z  ?

  409. 8 h: P7 Z5 m: t
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
      g. f# ^! B5 M( m4 g4 c2 G
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)* Q' g) u$ _+ z3 U1 T9 N
  412. ;==================================================; I; @0 J& v6 z2 [8 N
  413. ;NMI中断处理
    + D' P) {# j5 U3 S
  414. NmiProgram
    7 l& R+ ^' C5 \' F6 M4 V3 _$ j% m
  415. PHA
    & L" C  ~* c/ Z( e4 n, F$ I
  416. TXA: V3 g' H- X5 a5 J* G' ]
  417. PHA1 h( ?, a6 o) n" p7 F8 `# w& U
  418. TYA& p, v/ [6 Y, F4 T# n3 ?$ a
  419. PHA
    1 f& W, O7 \. `4 }9 h/ c' N

  420. * K1 f& R" k& I
  421. BIT PPU_STATUS& g, x8 q+ R$ f2 J4 \! f8 X
  422. # _2 k# x4 c6 Y- O3 `! N
  423. LDA #$00% r2 k# G1 ?4 W, f/ o7 C9 i& X
  424. STA IRQ_Index
    . G( u% u6 ?/ }6 h3 \7 a

  425. 9 m+ {: ]' x; A% x  o# T) i4 q% n
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    ! o/ b: |: v, O4 ?$ v3 e
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    * N. y' o1 K6 J+ \/ Q
  428. STA M19_IRQ_COUNT_L
    # g6 G$ R2 h' B! u5 R  W2 ]5 t' V) X
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    7 d9 b7 F- |) b! r/ r! ]$ j
  430. ORA #$804 m& K/ k$ P) i1 _% ^: D  d: E6 t
  431. STA M19_IRQ_COUNT_H2 X) k3 `: N' P" B& M: O. N- n
  432. CLI
    ( i1 l. {! y1 u" r6 S; V8 z
  433. 8 V7 d2 t* @: D. U6 R& z* m! O
  434. ;关闭PPU控制" ^: h- j: V) ]) X
  435. LDA #$00
    8 q+ ]. S1 l: d0 Z
  436. STA PPU_CTRL7 H2 H4 B3 E7 _$ O
  437. 2 Y/ a! H: N8 X$ F( Q
  438. ;处理PPU
    + K* y$ w. W9 ?) `7 f
  439. JSR PPU_Process/ ?8 I9 W4 T  q! z* X

  440. / i: F* \0 T. [
  441. ;开启PPU控制
    ' A2 R& ^/ f& r) g5 ]9 d( d
  442. LDA PPU_Ctrl_Buf
    , X3 l) C/ j1 }' g( w( I- e* p; M9 O
  443. STA PPU_CTRL
    0 q; y& a0 N7 r0 }3 _( A$ J
  444. " L$ F1 C, i5 t. g7 h) ]
  445. ;手柄处理* o, b/ R! z% E6 L
  446. JSR GamepadProcess
    ( D/ d- l9 z6 z# \7 w
  447. 6 c$ M2 t9 W# C1 w' _
  448. LDA #$008 k6 `9 ^- A" o' _
  449. STA IRQ_Index
    / ]5 X- w# ?# o( |' h1 X4 L$ O
  450. + ?, R" u( g0 X( n; t& R: p- ?1 d
  451. PLA0 Z2 u5 V; M) R2 `) w) l7 }1 v
  452. TAY6 {4 e# a; G# z& j3 x( a
  453. PLA
    % I/ g0 ]) o0 [  \
  454. TAX
    8 \( _$ ]- H- j+ n) K0 {' _
  455. PLA
    6 l5 k0 h7 [, u$ {# A
  456. RTI
    5 v- j9 O" S9 \+ }  u* `, K

  457. " V# q" D1 k# ~' v
  458. ;每行扫描线113.67
    $ O/ I9 n4 Y: \1 ^0 U
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)+ r; H% l6 M# ~8 `
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ' v# {, }' C9 y0 \6 j" U. b
  461. ;==================================================
    ( D& R4 E8 ~  e, e
  462. ;IRQ中断处理: R$ m' A3 E8 z. F/ i9 z' g) W
  463. IrqProgram" I$ I2 v, @4 h
  464. PHA
    & c( Q& X, p$ t
  465. TXA3 {! f! m5 q9 ?! [) Y: H$ B4 m
  466. PHA' T" i9 p/ K6 z- E$ Y
  467. TYA
    " L( X" |# _4 ^: C  ?4 m7 r
  468. PHA
    ; K+ _; \6 k# ^; f7 m, y9 e

  469. , B$ y. F  d% D: B
  470. ;16条扫描线后触发IRQ
    9 h3 }" R  W& Y9 @) P
  471. LDA #LOW(BEGIN_LINE_CYCLES)4 T- p# b; _) a2 E
  472. STA M19_IRQ_COUNT_L" V: o: }' A  b
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    8 U* W$ o3 \# N
  474. ORA #$80
    4 ?/ r0 ?4 ^# ?
  475. STA M19_IRQ_COUNT_H
      v3 x- g9 c' I0 F, R5 z% Z% a. i. \4 L6 k
  476. ) F* _, p4 X. a2 K  ?
  477. LDA <IRQ_Index
    : g0 a0 ]; }' [* G
  478. BNE * + 48 t( ^  _. |) l5 A2 c
  479. INC <PPU_Scroll_H
    % `8 M! Q' C3 @: F6 k: y9 x6 z/ U
  480. + a) a0 `9 {6 f2 l( k
  481. ;设置屏幕滚动
    8 r. u. m. X! E
  482. LDA <IRQ_Index
    4 }1 [4 }) \, ]" \
  483. AND #$015 s* G8 V# G7 D- ?& i# z* O
  484. BEQ Irq_Scroll_Right
    & h& P9 @4 K5 q

  485. " ^" _: P* N" l1 Y: o7 B2 e7 R# w
  486. Irq_Scroll_Left& R  _6 y' k& f: u+ C# D
  487. BIT PPU_STATUS2 W: c6 o! D$ w; \
  488. LDA <PPU_Scroll_H
    : ^: F- |" G5 @. G( _
  489. STA PPU_SCROLL
    $ Y2 d  l, u% M
  490. STA PPU_SCROLL& K, H+ p1 n& v/ G" x
  491. JMP Irq_Scroll_Over
    6 _6 F9 u# K$ v# @, ^/ I9 P

  492. " n' l  c6 B- k
  493. Irq_Scroll_Right. e5 d  e+ u# V
  494. SEC
    4 a; B2 @; m' f% i
  495. SBC <PPU_Scroll_H% Q4 b0 R4 F, Z  J
  496. STA PPU_SCROLL0 M: R# d7 _8 G* Q& B/ @
  497. STA PPU_SCROLL; U/ [8 S+ Y* s' f2 t) l; N
  498. Irq_Scroll_Over: m0 ]1 d+ C/ g

  499. & @# F" i- r! j, S& _$ r2 E- I4 R
  500. INC <IRQ_Index  J; G) U1 ]: R+ [+ c% b( D0 y- g
  501. / z1 G) P5 E/ P8 V. t& f+ M
  502. LDA <IRQ_Index, v+ `/ _- z, b$ X' }  k5 L
  503. CMP #14
    3 z, k: Q1 q. L# U" p0 p
  504. BCC * + 10
      F" @, x6 W+ q9 z& w# _2 ^
  505. LDA #$005 F2 U6 @2 O2 s# q
  506. STA M19_IRQ_COUNT_L
    . R" J# p9 k* S
  507. STA M19_IRQ_COUNT_H
    ) I0 f8 i/ ]9 p: Z. J6 w8 [
  508. ; }. u6 t- `) f1 \
  509. IrqProgramEnd
    3 B) e! V( w5 A. \
  510. PLA3 i( f+ z! }: ~7 b
  511. TAY
    ! Z0 b" v, o( |
  512. PLA
    : S% O: P  E* U) f' u( O. Z- ]
  513. TAX, O  b" ^- s" ?- B" t4 `
  514. PLA- j, m5 q. o' Q8 z3 ~
  515. RTI% P! W7 R8 x) l( r7 q0 [
  516. " f* n6 C2 ~- ]1 ~6 ^
  517. ;==================================================
    / J" r0 o7 o5 D+ c! Y0 u" L0 `  c
  518. ;中断表
    + V8 q1 i) @- k+ ]! p2 G
  519. .ORG $FFFA# Z7 U! }4 q) S2 O4 E+ M  D( }
  520. .WORD NmiProgram3 N0 v  M4 Z) ?  ]  H1 `8 o' d% Q) _/ p5 `
  521. .WORD ResetProgram% q8 x) g  \- c
  522. .WORD IrqProgram
复制代码

8 ~- B5 j% C! F# z( s* m& Z/ p

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-11-18 16:24 , Processed in 1.084961 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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