EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]7 q0 t+ {0 P' E- H& X. C) K: }4 I" d
  2. ;FlameCyclone 20230710! V+ I" j$ k) `6 w& i

  3. 7 O  m* o' U) R5 H+ c! G6 D
  4. ;文件头1 Y1 u3 O: a+ v' J# E  O: N
  5. ;======================================================================
    2 ~6 l# B" S* ?
  6. .INESPRG 4                                              ;16KB PRG 数量. i3 d, ?* z. X4 {, k# O& n
  7. .INESCHR 1                                               ;8KB CHR 数量
    ) m! J  ]( E5 F7 |1 Z) _
  8. .INESMAP 19                                                 ;mapper 19
    4 X; r$ |* ?- X- q3 L; N. X8 S9 c
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直. w! y+ C7 z7 q
  10. & U$ n6 I3 F3 e$ k
  11. ;必要条件9 C3 y# R+ n6 ?+ s- [
  12. ;1.持有CHR ROM
    ' q6 m" @7 g. E9 U: n% ?5 Q! k  I) b1 z
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10001 d1 ~2 b7 L! d
  14. ;3.精灵内存(OAM)不为空
    $ L" l  d* P* u  R" M4 Z
  15. , B! ?  h6 |) V  T3 N
  16. ;==================================================. H# j" D, p$ {& j! U
  17. ;NES端口常量
    - ^* E$ g; H8 h* |, i
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器, K% d, h$ e+ U
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    $ N! }# ~* F+ F" g* U/ H6 _/ _
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位& z; N# C+ ^+ _9 p. O6 @& {
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    0 m) H3 W5 ?4 W: w
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1- m5 a7 N( V( I$ U7 ~
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    ) q" N* c( C2 T9 |6 `
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加5 f, E; m& t+ U% c+ b
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 & a: h0 A3 r3 y1 v
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存$ _( C& ?8 x! ?1 B! t" ]7 I0 E- h
  27. APU_STATUS              =   $4015   ;声音通道切换
    # y2 o/ l: W' v( Z$ ]
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通# R1 V0 r% ?5 w
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    % L0 @% e  G* F0 Y
  30.   M/ j+ ^3 `: A% s
  31. ;==================================================- S7 f7 H5 ^2 ^: j" ?( W0 z4 [5 `
  32. ;MAPPER 19端口常量
    % V; ]% j% i, [# i# W% _+ L
  33. M19_CHR_0000    =   $8000; I( l. w/ B2 ^" H6 N, _8 S
  34. M19_CHR_0400    =   $8800
    1 M) H" l5 P+ i0 P
  35. M19_CHR_0800    =   $9000
    / D+ l. Q6 M# J* B( z- W
  36. M19_CHR_0C00    =   $9800
    0 S6 F1 |% A9 C# J5 e
  37. M19_CHR_1000    =   $A000
    3 p2 ^4 v+ J! n" r1 Q2 y5 j& u/ @
  38. M19_CHR_1400    =   $A8009 _0 ?9 [9 j. I" ^/ w  A
  39. M19_CHR_1800    =   $B000  A1 S3 \  Y7 ]" g# i: J9 I0 P
  40. M19_CHR_1C00    =   $B8004 [. V; _/ ~, Q: q% ^
  41. M19_NT_2000     =   $C000
    # i5 T, T) s: p# V+ c7 ~6 }( L( N
  42. M19_NT_2400     =   $C800, u( ?: y1 t9 K: ^7 D
  43. M19_NT_2800     =   $D000( a$ w" Y7 G1 C! d
  44. M19_NT_2C00     =   $D800
    $ {& E; J+ D1 [4 Z- B- c! \5 ?
  45. M19_PRG_8000    =   $E000& E3 o% l1 F* j2 m$ g( G
  46. M19_PRG_A000    =   $E800  A4 o) ]! }) V* u, b, b+ W3 \
  47. M19_PRG_C000    =   $F000/ A8 x4 x! H0 d4 z% }  G
  48. M19_IRQ_COUNT_L =   $5000
    8 ~/ L/ {6 l5 x: u5 `
  49. M19_IRQ_COUNT_H =   $5800
    : Q0 W9 Z5 c  b5 O

  50. % g. v2 T3 Y1 m/ g6 ~
  51. ;==================================================
    5 @. s; r+ _8 @/ t* g% t7 ^
  52. ;程序块配置
    & v! E" M% w5 |! V0 \; d
  53. BANK_DATA_MASK          = $07: \$ u9 a! |; F6 N
  54. ;--------------------------------------------------( s+ S3 k, e. O+ Q0 ~! d) f
  55. RESET_BANK              = $07
    ) X$ y% c1 T8 g
  56. RESET_ADDR              = $FC00/ ~( k4 L" J4 i7 p
  57. 8 A9 M# |6 b0 h# O' P
  58. ;==================================================
    8 f- }3 D8 o* c8 P3 ~* F: U
  59. ;图像块配置
    9 I# i& ]. s; r4 Y; J/ ?
  60. CHR_DATA_BANK           = $089 G9 F  w4 j7 m- [

  61. % H5 B! v/ Y# a( X
  62. ;==================================================) O9 X4 T, q2 a/ Q) N
  63. ;零页内存地址配置
    ' j" k+ L! s; i9 K" \
  64. Use_Ram_Addr            = $80
    $ I  z& i6 F9 g; s8 g0 c# S
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
      P# P5 Z; [. t3 f& V9 Z
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    6 T1 K/ W3 ?. C; k0 _' W# h9 z8 Q
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01- \: y% V: v9 M- i1 ^; q1 U/ k
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    & K& N" {, b" Z% t$ {
  69. FC_Data_L               = PPU_Scroll_V + $01+ M/ b+ \  k5 w
  70. FC_Data_H               = FC_Data_L + $019 T7 g( a. e  }$ G: I
  71. FC_Data_Buf             = FC_Data_H + $01, _* C0 a5 p! a; v9 N% w
  72. ;==================================================" i( y4 K/ K" P! ^
  73. , n" S$ O5 |2 p9 O4 N
  74. GAMEPAD_MERGE_FLAG = $044 g: R0 \0 r! k% C; ]
  75. 7 h1 u! ^+ E! i
  76. Gamepad_Keep            =       FC_Data_Buf + 1  n3 o( W+ u6 r3 ]4 @
  77. Gamepad_Once            =       Gamepad_Keep + 2  j6 B: d/ ^" P# A6 `
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ' e7 Q& \3 T: Q3 G
  79.                                 . m- h9 E4 C8 s+ H- s% Z9 |0 \
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    1 M4 c( w/ v* ?! q3 k1 }1 Z( a9 \) A
  81. Gamepad_1_State         =       Gamepad_0_State + 16 }- x5 d# `1 r: B; x1 \/ q
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    6 @* l& u) J2 y- x8 _7 A) S9 @
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    7 l5 l; L: s) d' i2 j
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    $ J' m  r9 M+ P8 x% C" G
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ! y% G( r0 s: O
  86. 3 D- u9 w" o% P, l
  87. ;==================================================
    / Z9 j. d! P5 O3 x
  88. IRQ_Index               =       Gamepad_Merge + $014 b6 r' ^& U* k7 B" H* u% a3 g& u
  89. ;==================================================3 e* {. J) p" V! Z2 ]

  90. ! [3 z. a# B% q2 C
  91. ;CHR图形数据9 g9 q) f5 P4 j
  92. ;==================================================7 j2 [7 @+ s& X% }6 ]7 H
  93. .BANK CHR_DATA_BANK, `1 u0 A& I* ]) ]6 D
  94. .INCBIN "chr_bank/chr_data.chr"
    # h7 p) ~& q6 V; j1 o0 p. j

  95. 1 C4 f3 ?1 K% Z: W* u
  96. .BANK RESET_BANK & BANK_DATA_MASK: E! ?" q) }* F) N1 V( |: \
  97. .ORG RESET_ADDR
    6 |2 z3 Y, {" g- \( ]4 v# T

  98. + x$ S' k0 K: R
  99. ;--------------------------------------------------! `( a* D9 u& a, A4 `& t
  100. Attributes_Data* }6 x& J* D, [8 ]  b0 L1 r, h
  101. ;命名表属性! V% w" S  D7 X/ A; |* C# G
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00' K+ p. L2 D" Q* j
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    ; x, E4 L' T4 L" n, ^. P
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA4 O6 m5 _( g* C4 g2 [6 ^! A, ?
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    6 w2 L/ J5 ~4 Y1 [/ A
  106. ;--------------------------------------------------
    6 _/ m7 P2 w. t2 o$ s
  107. ;调色板数据6 Q" h( X1 {6 z7 s; W) b  |0 g
  108. Palette_Data/ S' x: |$ \; K# v2 j5 c8 O8 l
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F0 {0 t8 I# Q; X, s( S
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    - u; b5 ]4 c/ Q. w, S

  111. 6 z) i3 l; X: {8 _
  112. ;==================================================0 O5 t% T8 C0 |/ r/ M
  113. ;命名表初始化
    ! k( s9 \/ W6 D  `- o
  114. Init_Name_Table
    6 b$ C, R- G$ G& R' D
  115. LDA #$207 P/ v$ U8 K1 r# q2 y: ]
  116. STA PPU_ADDRESS  O: D  y( D0 f% I, w+ J
  117. LDA #$00
    / H/ v& }7 I1 F0 n  R1 a
  118. STA PPU_ADDRESS7 K' Z( l9 K1 y/ e/ z5 K" n
  119. LDA #$00: x8 Z3 D) C5 m# |- k
  120. LDY #$00. d  ~' f% ?5 E" j( U
  121. LDX #$10
    1 C& @+ ?; i" p7 N
  122. Init_Name_Table_Write, l: j+ S' ~2 @+ y' K: w) `
  123. STA PPU_DATA
    : l# c" x+ [, v. p
  124. INY
    ! ^9 [' }9 U% A% b" F  k
  125. BNE Init_Name_Table_Write
    4 U6 \8 z5 r* r" q5 ?
  126. DEX
    # y) k! d* Q* [/ w
  127. BNE Init_Name_Table_Write8 K: k- G3 J, ?$ G" [% ?
  128. RTS  z9 g8 P: q7 ^9 c. T0 Z' s$ y

  129. : b7 Q: q' E6 z: v
  130. ;==================================================
    ; Z7 I+ K- G( h! G0 x4 x
  131. ;调色板初始化
    - K3 A9 d1 G2 ^' j  U) }) J! y
  132. Init_Palette
    ; u+ A7 B& T" C' C
  133. BIT PPU_STATUS$ ?/ }$ k( O8 a
  134. LDA #$3F
    $ _) n5 \& k1 [% ~6 D8 W4 b' m2 p& c
  135. STA PPU_ADDRESS
    ! Y% \" m# R5 N0 r
  136. LDA #$00
    + _9 b% P' |7 o- o% a3 S' e
  137. STA PPU_ADDRESS! C3 q; l, p/ A! T# t0 T% U0 C
  138. LDX #$00
    7 [( Y3 L" k( W# P& I3 J
  139. Init_Palette_Write7 T4 I, P6 Z3 H
  140. LDA Palette_Data,X
    # U5 P; @0 y* S2 J
  141. STA PPU_DATA
    # B) |* R9 G$ M6 R: \* R4 B" z
  142. INX% H/ o9 ?+ S# a- r; ^# p* [; z& t1 O! i
  143. CPX #$20: b" q) g& H2 }
  144. BCC Init_Palette_Write
    7 a3 c  N$ i4 ?/ O: k1 Q! R5 P. x
  145. RTS& D5 F: U2 b1 d3 _2 X
  146. 8 e  y" s0 }9 K& C
  147. ;==================================================
    0 n9 W/ m4 ~0 c
  148. ;设置命名表属性
      c; g- ^1 V+ |+ b0 h& R
  149. Init_NameTable_Attributes' Z' S( H& o' }( W
  150. BIT PPU_STATUS
    ; G9 [. C7 N0 l" l& }4 q
  151. LDA #$23
    5 g( {2 [* h3 N3 j8 M
  152. STA PPU_ADDRESS
      @  B6 _( l; J8 z- C- ^
  153. LDA #$C0
    / b8 `/ j7 q- H1 z4 S5 A
  154. STA PPU_ADDRESS
    3 O9 C* Z8 ]# C0 k' ~. |- w
  155. LDX #$00
    + [# v3 I# b+ \+ @* ^$ K4 O
  156. Init_NameTable_Attributes_Write
    ' J+ ^, D, k5 u3 [% W
  157. LDA Attributes_Data,X
    8 W5 V& g8 O  z% g; r& N
  158. STA PPU_DATA
      K- Y- U# v2 t# S- E
  159. INX
    3 ?4 f0 ^2 V% u1 {& v, O
  160. CPX #$40
    8 _9 s  l- X* ~1 S/ d4 B9 [2 K
  161. BCC Init_NameTable_Attributes_Write
    , u4 N! J( J% _4 k' X
  162. RTS0 O& b$ E$ T7 {2 _, ?. z9 o

  163. / {8 ^' c# t9 V9 j
  164. ;==================================================# S- {- [9 N( [' F1 w. J# ~! Q1 l
  165. ;初始化命名表文本$ R) k' Y& D8 ^" @8 i3 ?+ K; @
  166. Init_Name_Table_Text& h6 }3 m3 _! w; j# ]
  167. BIT PPU_STATUS5 Z4 i' H' N2 t, Y; \9 [$ G
  168. LDA #$20/ R- Y9 v% J: Z$ R
  169. STA PPU_ADDRESS5 a4 K1 M2 t( j8 F1 p7 H
  170. LDA #$000 \' }) D1 O3 Y# s" x7 e& w' |" D
  171. STA PPU_ADDRESS) m5 }, [  h* l+ U9 j) G" G
  172. LDA #$002 t  m! k. y, u. Y  Z
  173. STA FC_Data_Buf2 [7 ]( }4 `* l+ E
  174. LDY #301 ~7 d% v4 ^( D! W9 [# x. @- i
  175. Init_Name_Table_Text_Write
    ! O! H6 C, M, E
  176. LDX #32
    1 N4 J( w$ {; v5 r7 i$ p/ q- Z" L
  177. Init_Name_Table_Text_Write_Char
    " Z' o' A% X3 }
  178. LDA #'0'0 F) w$ B0 d/ n. k) A/ d
  179. CLC
    2 G: M' f. G6 n
  180. ADC FC_Data_Buf  b8 h& @+ k& h5 R8 e( R+ `6 s/ E$ Z
  181. STA PPU_DATA
    - f, z- R! U$ H9 s
  182. DEX/ ?( {" T% ?: d, V+ i( _# V3 ~7 ?
  183. LDA #$14- [; ~9 O1 j' f' }% L
  184. STA PPU_DATA
    ' l' I3 Q% l( e/ s& U/ k) e
  185. DEX0 F! ^  t( u( v/ V8 I( F) h6 y1 Z
  186. BNE Init_Name_Table_Text_Write_Char
    ' X4 Y6 k6 M' N& [) v8 E) r( d
  187. INC FC_Data_Buf6 K: f$ V5 o" Y1 I1 V# v3 C: f
  188. DEY8 \* ~% \$ V- D: D
  189. BNE Init_Name_Table_Text_Write
    ; X& x7 J' v. F2 Z8 M9 m- V
  190. RTS+ X8 j1 D7 T' U# c- K  L9 ^5 p
  191. 9 g8 Y' a5 {$ |3 ~: {1 `5 D
  192. ;==============================/ g8 C% ]& h, U; r! ^6 E% d
  193. Init_OAM_Ram;初始化精灵内存
    ' _4 g" d- \% Z8 s3 m# Z
  194. LDX #$00
    : c; G( S3 t* ^8 x) S) c: c
  195. LDA #$00
    % ~& M; ?$ H, b
  196. STA PPU_OAM_ADDR
    0 x3 j% ~' n) n" [5 D
  197. LDA #$F8- A5 _  h$ j/ z. d. t
  198. Init_OAM_Ram_Write3 q3 J3 H4 P+ X# U- D
  199. STA PPU_OAM_DATA! y- P5 @9 J6 f! t6 X
  200. INX6 K5 N' I% T3 G* o/ `+ l
  201. BNE Init_OAM_Ram_Write
    0 b  _3 R8 f' D1 V/ `" C
  202. RTS
    ! j- k- n. d% S' l2 X1 D

  203. $ [, G) r- t( p8 J: s
  204. GamepadProcess;手柄处理
    % d" }4 L4 c% O& q  h7 q
  205. JSR GamepadDatacan, O# d) j$ x% t0 {. M7 w% q
  206. LDA <Gamepad_0_Value
    : q8 c" ^5 U; K4 i& B
  207. STA <Gamepad_0_State: a  W' ~- C. t
  208. LDA <Gamepad_1_Value
    $ Z: |# q2 }  J  Z$ _! a  g8 W
  209. STA <Gamepad_1_State$ Z, [+ S+ Y+ \. v/ @% u
  210. JSR GamepadDatacan
    / T8 R( Z; {' I( T) }% _& Y5 {$ W
  211. LDX #$01
    ! q. F. P5 N$ w$ t$ q! g5 b% K
  212. GamepadMergeCheck;合并手柄输入检查; H, e+ P+ P, M1 ?- G( `& K9 a
  213. LDA <Gamepad_0_Value,X7 g5 x9 u& V; D" g! l% m3 k$ d( |0 d6 z
  214. CMP <Gamepad_0_State,X
    8 C: U1 \7 Z# C4 n
  215. BEQ GamepadMergeInput
    6 |; w! {$ ~$ V5 S) O
  216. LDA <Gamepad_Temp,X; |2 u1 `+ D4 I4 K
  217. STA <Gamepad_0_Value,X5 A+ }5 L) [4 }1 Y; L' j3 Y
  218. GamepadMergeInput;合并手柄输入1 O; r  y2 u) N1 `8 s
  219. DEX
    / O) _4 J+ A" Q& A. }
  220. BPL GamepadMergeCheck# L2 i# B- e0 {6 I( v
  221. LDA <Gamepad_Merge
    ; q5 \  P* i9 p
  222. AND #GAMEPAD_MERGE_FLAG9 k3 B  r3 y3 I5 @/ \9 t$ n' L
  223. BNE GamepadStateProcess  Q$ Z+ W3 ~" z8 P, l
  224. LDA <Gamepad_0_Value% h) y+ I- L) ]" D
  225. ORA <Gamepad_1_Value, d) [0 R5 k( R
  226. STA <Gamepad_0_Value  [" [! O- B$ Q& }% f" l/ B, `% T+ {
  227. GamepadStateProcess;手柄状态处理9 d0 O9 k7 Q# u8 G
  228. LDX #$01- W# w. x5 i4 y! E2 j7 @
  229. GamepadStateSave;手柄状态保存
    / p$ o  ^0 C) J7 f
  230. LDA <Gamepad_0_Value,X# ~+ w" W  g" j2 y7 Q  d& x. f6 B
  231. TAY) {- G" R" p) B$ r
  232. EOR <Gamepad_Temp,X
    1 {% I! S7 r, f* a& b
  233. AND <Gamepad_0_Value,X
      W& G2 }" c4 m$ c
  234. STA <Gamepad_Once,X, N$ l/ L% a. N) _# z1 s6 z
  235. STY <Gamepad_Keep,X
    ( u! f/ v3 \& A9 g
  236. STY <Gamepad_Temp,X
    2 X8 j, D: i. u1 N0 B6 t6 \9 j
  237. DEX* R# |. R$ U; K/ D# [! k
  238. BPL GamepadStateSave; w" n  n8 _; E, f* s: ~4 N
  239. RTS2 K8 J! L1 p3 K! @$ \) `. X

  240. & k( Z  |, M9 {
  241. GamepadDatacan;手柄数据扫描2 |) O$ J# e( V7 p4 m* i
  242. LDX #$01
    . q0 u: p+ K6 |7 S7 P! h
  243. STX $4016
    - r7 u6 b. O& ^2 ]( d1 t; g
  244. DEX
    3 ^4 Q' h2 t: @6 d1 x, w" t7 |
  245. STX $4016  w# O. K; R7 z9 f  H- Z4 ~( x" ?
  246. LDY #$084 A6 E+ j3 I! e3 f) c- v
  247. GamepadPortScan;手柄端口扫描, n' E7 `- m8 u
  248. LDA $4016
    ; q( T' X3 j. I3 ?9 y1 y2 m7 d- r
  249. STA <Gamepad_Port_Value: l$ r4 V0 k3 N* s& f
  250. LSR A
    ) S2 t" ]6 ?+ l) f; e9 t
  251. ORA <Gamepad_Port_Value
    $ _5 d4 n0 Q# B# t1 ?
  252. LSR A4 t, [' k* C! ]. }+ {' Q6 P8 z
  253. ROL <Gamepad_0_Value
    3 ?2 I+ f( s4 i; p
  254. LDA $4017! D) ~2 ?1 \" R; [% a
  255. STA <Gamepad_Port_Value/ x! S/ t' q& d7 ~
  256. LSR A
    ) r6 ~2 t: u3 N/ D7 @. _( s+ P: S
  257. ORA <Gamepad_Port_Value
    4 ?& I; C  @0 ]- J, B
  258. LSR A
    0 U2 l3 I( q: m  J4 e1 Z
  259. ROL <Gamepad_1_Value
    & s$ B+ Y7 D- ?# D1 z5 x
  260. DEY
    ; K, q( Q* H, Y; r
  261. BNE GamepadPortScan" Y; B  c% }: E" }2 T# F
  262. RTS3 r; B- n1 G7 }6 Z" P. h  F  x

  263. : Z* A& H+ L1 R" [, m- ?7 q2 |1 Z
  264. ;==================================================8 @$ Z- M: |" s# H
  265. ;PPU处理
    ( p$ q# n9 j0 p" u
  266. PPU_Process
    6 E, S; T3 ]/ a: Z
  267. LDA #$00; s& v. u: r) {* {0 V
  268. STA PPU_MASK
    5 m$ j  |% Y& x2 M

  269.   ]. i. S# r1 N. V7 q
  270. BIT PPU_STATUS
    " z; B6 r3 v6 q+ h0 D% p' T
  271. LDA #$20
    % U8 _5 c( L) o: ~6 u# _: a. E! I
  272. STA PPU_ADDRESS
    8 E2 ^- W2 |0 `, I* _3 s
  273. LDA #$00. X/ c) Y$ [# @
  274. STA PPU_ADDRESS2 z( J# K+ N5 j/ Y: O

  275. 1 D% F/ H) v) l' z
  276. STA PPU_SCROLL, ]/ n8 B: z! C+ ~! z
  277. STA PPU_SCROLL" W3 V% y+ A% N* \
  278. / S  p- U% Z; i, J! y. e/ U5 S& o% M
  279. LDA PPU_Msak_Buf8 J; u% q5 s* a" h3 p% U% W/ T
  280. STA PPU_MASK7 Y7 a3 D/ e3 k0 V2 M

  281. - V3 n/ G7 ^$ v" J, a
  282. RTS
    3 n% Q. e; _0 i  {- b; I. M
  283. 9 ?; W$ w# K' Q% u! b" `. m
  284. ;==============================2 }+ B; k) ]1 ?7 r. ~/ n) v
  285. Time_For_Vblank;延时等待
    : ]3 `' r, Y0 w& a5 C8 X
  286. LDA PPU_STATUS
    , x3 j% ~" P7 F
  287. BPL Time_For_Vblank/ H8 p# D* j3 w. q4 l/ Q4 F
  288. RTS6 l! J& B2 [0 u* o  D' R# C$ M* W7 ~+ J
  289. : w8 `# {5 t4 i
  290. ;==============================8 H  Y" N; q5 w. f
  291. ;初始化MAPPER19
    5 O7 F% L" ^, g: \* ~3 n: F& U
  292. Init_Mapper19
    - {) K% k  D7 k* G  q, D) u
  293. LDA #$009 T( B6 @+ m; i3 u. E4 J. \
  294. STA M19_CHR_0000
    , N: w4 z; C. ?) ^5 V# S& t$ z
  295. LDA #$01
    - |; p+ T( W) \$ J# U
  296. STA M19_CHR_0400/ X2 I& w1 G& [0 H# n) H
  297. LDA #$02
    ( J3 _$ ]( S2 E% D, p9 n7 z8 J
  298. STA M19_CHR_0800
    + ?8 }* V1 g. a% E( \2 b
  299. LDA #$03
    # y+ R. K3 {, O2 q  y% B1 I8 b6 O
  300. STA M19_CHR_0C00
    * D) k3 s6 |6 Z! \
  301. LDA #$048 S9 U* M: Q2 L/ L4 o
  302. STA M19_CHR_1000
    # k  f+ O# q! r9 m
  303. LDA #$05
    5 Y3 `4 ]. u9 H0 E0 [# ]2 A
  304. STA M19_CHR_1400
    * K8 [- n# ^4 ~; m7 K4 j
  305. LDA #$06+ [" G) z: T1 b$ A1 h0 d5 _7 q
  306. STA M19_CHR_1800
    3 G7 |& T+ W  G, T
  307. LDA #$07
    ! G6 ~- B' d. ^6 }: u7 @
  308. STA M19_CHR_1C00' \' P" p; e& `6 R4 }

  309. ; y; V5 m4 d; v5 ~' y0 z
  310. ;禁用IRQ6 U2 q4 R' m6 G. ?
  311. LDA M19_IRQ_COUNT_H" s$ `! G6 X! `8 L
  312. AND #$7F
    9 f# n: D: B5 H* d7 z5 O+ C
  313. STA M19_IRQ_COUNT_H
    & Q* F+ m0 u5 i  |5 \
  314. 4 C* S. Y8 b/ t# h3 O$ h9 A( W
  315. ;命名表
    % X6 p5 \2 {  \% A' O4 \9 d
  316. LDA #$E0# N% B1 R3 [9 R4 J+ l" ?, \) a% f
  317. STA M19_NT_20001 D  K; Q0 B3 P: i
  318. STA M19_NT_2400$ v! S. [3 z, x, g

  319. & K# F; h$ ^6 O$ o& f) ^+ o5 A/ |
  320. ;命名表
    & [* u$ [8 b/ b. [5 o4 |' Y
  321. LDA #$E1$ A! V3 B! A. M
  322. STA M19_NT_2800
    + W  ^6 o% Z& X5 Y" W
  323. STA M19_NT_2C00
    $ G! [3 V1 b; k' T+ q+ N5 [1 X
  324. 8 w' ]& B: Q, [+ Y- k
  325. RTS! }7 l: T6 y. I9 `% ~
  326. ' R( v0 j: C% u* N6 [$ v' }2 [- _
  327. ;==================================================& b( p! p2 X' O. a
  328. ;重置中断处理
    . I; z8 g7 _) U
  329. ResetProgram  ?! ~5 ~" F  W" x
  330. SEI7 U8 P  r) U; H# X7 D. a
  331. CLD
    9 m3 [# i8 K2 @3 G' K  Q
  332. LDA #$00
    0 l: |& @# ~3 |6 d; G5 p! Z
  333. STA PPU_CTRL! z. H: _$ u3 g  X* v3 g
  334. STA PPU_MASK  Z, t) s; j- u/ |
  335. STA PPU_STATUS: i. ~: ^7 l( l1 |
  336. STA JOY2_FRAME: C$ T9 B* P$ q7 X0 a
  337. STA APU_STATUS
    ' k, ^& C) I/ f. n
  338. $ ^, F3 s* V% l# f0 L# s6 D  C* o
  339. LDA #$C0
    & F7 C- ~$ [4 _" F1 d
  340. STA JOY2_FRAME) c2 y+ d4 V: f$ K5 h3 F4 R  d1 g
  341. 3 W/ B. [  s, m( A% L5 O& L
  342. ;等待vblank
      a. s! Y: o. b3 N) z; W+ r+ P
  343. LDX #$020 W' \' g# D0 f4 M
  344. Vblank_Wait_1: j/ U. N5 f6 x. V5 w0 |
  345. BIT PPU_STATUS
    $ J" X. t% N0 j, X% P- a+ M9 |5 Q: g( s
  346. BPL Vblank_Wait_1
    - A1 g8 N. @, ^, P
  347. Vblank_Wait_2
    * V! W' {$ B- q# r% G. ~& a
  348. BIT PPU_STATUS0 j2 K; |/ N5 L- L- I$ L
  349. BMI Vblank_Wait_2
    + F4 c  F1 D3 X8 N% F
  350. DEX
    1 }% b3 s" u6 x" ~) o4 U& A
  351. BNE Vblank_Wait_1& a' d% X4 J: W. {% \
  352. ) e1 E, Q1 q2 h3 n7 f1 J
  353. LDX #$FF
    : K, ^( P! C% p# @3 ]
  354. TXS
    - J$ g) a5 B4 D7 O
  355. ! `( K2 g0 r) o8 C
  356. ;初始化MAPPER19/ h% d) c; `$ \  h% n/ M& g" ^
  357. JSR Init_Mapper19) J5 l: u$ I0 V0 N; h$ t7 r: S
  358. : K7 o% j8 w& B
  359. ;==============================
    * [+ T3 i! U7 k  b1 p/ X
  360. ;RAM初始化
    + k, Z& }; v& U$ A
  361. Nes_Ram_Init1 y( L$ _: X7 K3 J# s. ^/ N" k5 _
  362. LDY #$00
    ! P  Z; U% n: k
  363. LDX #$08' I- N. O( M7 a( N
  364. LDA #$00
    - ]* E  d" C+ G" q$ L4 r  q
  365. STA <$00  z8 l* X7 S' c) C/ l+ p) _: Z
  366. STA <$01
    ) u- o+ ^% b1 M& H; p9 p
  367. Nes_Ram_Init_Write
    5 n" ^6 \# s% x$ q
  368. STA [$00],Y+ Y5 ?" S" t# a$ _6 ^
  369. INY) m/ z6 X$ O7 l( U
  370. BNE Nes_Ram_Init_Write9 F# x8 n7 V1 L. m, L
  371. INC <$010 Z( F8 ~2 \; Z" Y
  372. DEX: \. Q1 }1 G0 `# `
  373. BNE Nes_Ram_Init_Write
    $ f' v9 T# |( g  c! N; C
  374. 8 r, a/ H) w. S3 y
  375. ;初始化命名表2 ?: s& p5 e7 @6 V1 u; `7 j
  376. JSR Init_Name_Table6 u2 C, p5 Y1 Y# V$ L7 _
  377. / V0 i5 T& z) y3 t; c
  378. ;初始化调色板
    ! T0 w. \. t2 X3 K
  379. JSR Init_Palette
    5 x; N) l. K, m
  380. 0 N/ D3 P2 x! `) k7 B7 Z. F
  381. ;初始化命名表属性5 \& `3 ^3 }* k, y( a( q
  382. JSR Init_NameTable_Attributes/ E# O% _; \7 m) ^9 h

  383. ' D6 ~' T+ P2 E
  384. ;初始化精灵内存2 `  X) G+ G, J2 H8 l
  385. JSR Init_OAM_Ram7 v% o  y2 ?# e' J

  386. " y# f0 U( i1 b8 Y; z0 _" g+ S2 w
  387. ;在屏幕上写点东西' i# b" W$ B+ j& F9 a8 H2 d
  388. JSR Init_Name_Table_Text0 t$ }; w5 w- R% M/ m8 j; T' b- w
  389. - ]* g5 A  i2 U. s+ F) n" a: b
  390. JSR Time_For_Vblank
    ( i% `2 ^# v. H; g, N8 }& ^. y2 v* I
  391. ;开启PPU控制
    & l$ z' V* j/ ?
  392. LDA #$A8
    : p  y( _. C4 m3 F$ S
  393. STA PPU_Ctrl_Buf8 X  A  l. N) ?& X+ b8 t. J
  394. STA PPU_CTRL
    + n: W" f. ^7 w2 {" q) N
  395. ( n1 c' f: `6 [# L% m" C" i( Z
  396. ;开启PPU显示
    8 n6 A# e  B  U6 S
  397. LDA #$1E: _9 y/ r, o  p" f6 l" s8 f
  398. STA PPU_Msak_Buf
    5 O' p/ U+ h+ k3 G% W

  399. 4 C: ^! z3 s' C% I' @
  400. CLI  v! R' G. V- {, j3 o5 B# c: x
  401. JMP Loop; D+ O, K4 |: D/ h

  402. 7 i5 q" x: }4 |* m' n: [$ Z& ^
  403. ;==============================7 G8 i( Y0 b4 [  y
  404. ;死循环, 等待NMI中断
    ' T& [% o" s! Q; F* e4 m/ r& Q, |( h
  405. Loop
    7 p3 _8 r' N0 Z* ]$ g
  406. JMP Loop
    ! Q; j$ B# b3 v: r1 y7 F
  407. ( B* f  q; j  @" W
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    " }7 h- T( S& b! c
  409. * W; o8 ?5 E+ {
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)% A/ n9 T6 A" q- |  r9 y5 x
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)" @4 l8 }: ]# q
  412. ;==================================================" X5 o2 b4 R7 r- \: G# Y  e
  413. ;NMI中断处理$ f6 E' j9 \% o+ l4 i2 T9 k
  414. NmiProgram2 @. i$ A+ e7 _
  415. PHA& H  ~, h( S  G" r0 S/ q
  416. TXA+ Q3 |/ p9 ]/ G/ \
  417. PHA
    , F) A; S( a7 y3 E- Q% W
  418. TYA1 H. u- O2 }: ^4 W$ z) {2 j( l
  419. PHA
    & h+ P: `% Y: M( g! |% V
  420. 3 V+ p% U6 @& s# f% s
  421. BIT PPU_STATUS
    4 k# e, |  T4 p8 _

  422. ' P' q9 P# q7 U# J
  423. LDA #$00- Z" @3 B8 a6 n4 C) S# m/ E7 C
  424. STA IRQ_Index
    ' C# d( g$ m7 w0 d
  425. ' V" l5 n% _) g3 r+ F# c
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动! Y% @. `1 @# k  s( B+ v1 D3 O
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    0 i1 q  W' Z" W! f3 E% X. v# b
  428. STA M19_IRQ_COUNT_L  z: l) P+ X  ^  Y* X
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)) i6 h1 r6 P: T+ P
  430. ORA #$80
    7 _* {7 Y7 |1 V6 l- q
  431. STA M19_IRQ_COUNT_H
    % V5 z) ^: H+ V! R5 g
  432. CLI
    8 [+ {; z( v& Y8 V0 p4 b
  433. : K1 V- T( F  ?6 u: k
  434. ;关闭PPU控制
    9 x5 V' x" n0 d/ _) L1 c* U$ S
  435. LDA #$00, _7 d( b% A9 c* U& m7 c2 R; ]
  436. STA PPU_CTRL0 o6 b/ D  i/ K- f2 A  q

  437. % g+ o) o- i1 a: w
  438. ;处理PPU
    ) a) k% U, j% K: P4 O1 ]3 j
  439. JSR PPU_Process$ }1 J0 T- u  N1 d. M+ q+ n3 I

  440. - S" J/ E4 ]: V" \, z; ]
  441. ;开启PPU控制) E- z' ^) Y1 m: y
  442. LDA PPU_Ctrl_Buf  |: a0 V" S% ]& O$ D" |
  443. STA PPU_CTRL9 \2 ^: `% Z! C, y* S3 V4 [
  444. / n- n2 b% e3 H+ q3 }' W' D  |
  445. ;手柄处理! `! M0 W5 `# B2 K, g
  446. JSR GamepadProcess8 R6 [) ?$ u: `; k# R
  447. % ]! d; u3 R6 a  ]( H& h
  448. LDA #$005 S; |- Z/ `* R, g& z) ?
  449. STA IRQ_Index
    ( B5 d1 J6 o! w& E, d
  450. 3 `* c. N9 W, Y4 c8 {5 B& [
  451. PLA
    7 {4 h! O6 W: J9 C9 K
  452. TAY
    ) x# S5 v. I, T3 F  z
  453. PLA; f4 \' ?1 R( h0 |& ]5 U, C( l
  454. TAX  ?( V. K/ H3 U' K8 [
  455. PLA
    - Q0 X) _/ F5 j$ |) R
  456. RTI
    ' D: Z  y- c3 n4 j  I2 H- y9 I- X
  457. ( {: o4 J8 X1 O1 A
  458. ;每行扫描线113.67# d, s6 P: b( }0 [: g. h
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)' \/ L0 R5 R8 r0 [) {8 z" u$ O- K4 f
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    , o# _% k& E; B+ u8 i" \! [' g* `/ X( ?
  461. ;==================================================4 m; \) l' W5 d# `" o! c2 |
  462. ;IRQ中断处理* n: J6 p/ O6 z* e. e
  463. IrqProgram8 W+ A% ?  B* J/ H# O- ]% ~
  464. PHA) F& X' s& k! V1 f& a
  465. TXA% m* C# g3 ~" }' k, }: ~. x! }
  466. PHA1 ^  [  T2 X& K( g$ K
  467. TYA
    ; M0 D5 W+ b, [
  468. PHA" P" i6 J( }9 d* K- J/ r- \

  469. % p& \; z# o# l& @. l; e$ v
  470. ;16条扫描线后触发IRQ
      T$ c$ O6 U1 G" Q, j
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    1 d: o/ W- D  u' E- w7 `$ x9 m% m
  472. STA M19_IRQ_COUNT_L
    4 Q& h& E5 f. k, N
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ! ~4 C# n( z  F
  474. ORA #$801 c) x9 g1 j/ f: W) w1 q& h, \& l
  475. STA M19_IRQ_COUNT_H. Q3 k" K) p/ v& N: S6 f2 i8 f
  476. * r  S5 S2 b: [9 q! X6 X9 |2 C. ~( Z
  477. LDA <IRQ_Index
    4 a/ A7 R  l* L( @' }4 g  M
  478. BNE * + 46 t2 d2 @+ u& s3 D+ L
  479. INC <PPU_Scroll_H- P# v8 d0 W: u
  480. + f" R6 x9 l" \5 H. D
  481. ;设置屏幕滚动8 U4 i' S5 R1 H1 m
  482. LDA <IRQ_Index0 |- P3 W  Z5 R0 C' t$ W
  483. AND #$01& O8 G: h% L" g6 x/ P0 l$ `
  484. BEQ Irq_Scroll_Right- \6 D9 _* g. K5 S
  485. " ]6 b0 }( s; g) d4 W
  486. Irq_Scroll_Left
    " g- [  y% B, s4 o8 @+ N5 U
  487. BIT PPU_STATUS/ ~1 a, ]' l, d8 C" j8 m
  488. LDA <PPU_Scroll_H
    8 ]( H$ `, ]5 C4 Y, u
  489. STA PPU_SCROLL
    6 d! h( v1 T0 d
  490. STA PPU_SCROLL+ D; I% i) S: e# M8 L' n
  491. JMP Irq_Scroll_Over' @9 F( x) h# \4 O

  492. 4 ~/ d$ ^0 M3 @, l# }
  493. Irq_Scroll_Right) f* m3 Y( V& t; ], X6 X
  494. SEC
    : T: M$ M1 `: ^
  495. SBC <PPU_Scroll_H- V; r5 v* w  S0 k
  496. STA PPU_SCROLL; Q1 A, g( b6 Q" E& w
  497. STA PPU_SCROLL
    . E" N* p2 p# K, L4 L+ ^
  498. Irq_Scroll_Over% L% H- p9 |* G, Y. e
  499. ; }2 }5 x& B2 \3 M% R7 H3 R+ z
  500. INC <IRQ_Index: u3 N& n& Q+ M' }% b4 D/ i
  501. 3 e! U8 k3 b7 p- `4 e0 o' h
  502. LDA <IRQ_Index
    ' \$ H! g4 N, i
  503. CMP #14; E* L+ G% j/ T: I; w+ D
  504. BCC * + 10
    6 D  \/ R9 b8 ?9 F
  505. LDA #$00
    " ?! r1 h% V0 A! s, U8 `
  506. STA M19_IRQ_COUNT_L
    9 w8 g3 U- C/ I% g/ ?6 k6 G( o
  507. STA M19_IRQ_COUNT_H2 h: L8 S2 ]$ h7 u& Z9 s3 {. ]8 Z

  508. 2 z6 `8 ^& P. \
  509. IrqProgramEnd9 t0 O( @& p" @6 }, U* x, k
  510. PLA8 @2 N7 c# g: \7 d7 p* F
  511. TAY
    . b; ]1 W+ X& T' V1 Z( `6 t+ a/ `
  512. PLA
    ; }( x+ o- w0 k( d2 |2 @
  513. TAX
    : Y* g. f" B! |6 T8 Y5 @
  514. PLA+ r/ R& o: K7 j; J7 b2 b& h
  515. RTI! Y3 a. l# p5 K9 T' |' y) R" }2 P

  516. / `$ r+ k; [+ a2 D) R- I
  517. ;==================================================/ ~+ j2 I7 k4 S
  518. ;中断表
    . O5 x6 M8 D6 f$ p7 q8 Y
  519. .ORG $FFFA+ O+ V3 B0 ~/ m1 _4 {# K
  520. .WORD NmiProgram
    1 N) ?7 R' d. \( h# J0 S) p) v* [
  521. .WORD ResetProgram9 j$ T  T7 L) B
  522. .WORD IrqProgram
复制代码
1 B& s2 R1 O+ y6 v$ H2 q" \

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-2-24 17:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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