EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    ) e! ~8 U5 w/ b4 P
  2. ;FlameCyclone 202307107 [8 b- Q0 L$ }" e2 r3 c2 r- P1 D. i
  3. . p, b. a! a1 [
  4. ;文件头4 n# e  |3 ]5 D% ?
  5. ;======================================================================' E. a) k" E& D
  6. .INESPRG 4                                              ;16KB PRG 数量  Y5 \! v4 |) r9 k2 N  Q" R6 X6 P
  7. .INESCHR 1                                               ;8KB CHR 数量
    ) `0 K; l: _5 i- g# \0 r  v
  8. .INESMAP 19                                                 ;mapper 19
    ) O3 G1 X: Q8 K* S" \2 k( Q
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直) s. _& b6 ]& y0 p. i/ Q! b) j( Q

  10. ( \* a4 e2 w- A' F( v
  11. ;必要条件% ]5 M) F- {" g( E# C, m' T9 \
  12. ;1.持有CHR ROM4 Z0 P2 X6 @* c) r, b8 e. t
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    & Y4 ?- J- E; u1 w2 t& S, [
  14. ;3.精灵内存(OAM)不为空
    3 D' p+ @# D3 k3 m

  15. % u0 m% V0 E. V" Y2 o# Z3 ]
  16. ;==================================================
    ! C7 g  Q, q/ V0 y( X$ T. `
  17. ;NES端口常量/ _. k" j9 i2 n
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器, e2 e: {( r/ z2 O  o
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ) a' P) z1 C5 o( O5 g% c
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位# ~+ e1 A9 ?' a+ e
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1! C" h& _+ e3 x
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    9 W. h7 i) q) @% `" U( v
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 6 u+ N" G+ z! U- A+ _
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    ( H7 C8 F3 q- h# g
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    ! @7 q, ~$ C, O# q7 K# `! P
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    . N3 D. @! W  K' L1 h% X
  27. APU_STATUS              =   $4015   ;声音通道切换( Z% b7 N2 f* g6 y: y$ s
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    7 O% s  Y, c9 p1 U% Y
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    # f' v2 {4 m. M/ \/ G0 `+ K- I

  30. + `$ j- e" c5 Q- K' y* Z& A# ^
  31. ;==================================================, g: ?0 c; E# y+ C
  32. ;MAPPER 19端口常量0 h$ A2 ~9 u, a: |
  33. M19_CHR_0000    =   $8000
      I# S2 q/ F0 _" _; [
  34. M19_CHR_0400    =   $8800: G8 T- X! j4 N
  35. M19_CHR_0800    =   $9000$ s- t3 x# i9 k) k# J. g* }) v( [9 y
  36. M19_CHR_0C00    =   $9800  M1 k, ?* T' M! {& F* M
  37. M19_CHR_1000    =   $A000' c( r* I2 H2 ^5 s( o$ y+ Y: Y
  38. M19_CHR_1400    =   $A800
    , z2 n$ N6 `  h( f5 l( L
  39. M19_CHR_1800    =   $B000" Y( g/ @3 }! u- Q5 r7 b4 W
  40. M19_CHR_1C00    =   $B800
    ; ]3 o2 v" z$ l* y" y8 k
  41. M19_NT_2000     =   $C0009 X/ \' e% d% e
  42. M19_NT_2400     =   $C800. d0 ~  }, Z/ C; J
  43. M19_NT_2800     =   $D000
    5 w% ?4 f: |9 }9 g* P- \; v5 A) I
  44. M19_NT_2C00     =   $D800+ P; p1 X' I, k8 S/ H( p# c" N
  45. M19_PRG_8000    =   $E000
    0 l' f4 b$ ?7 K/ c* B3 u
  46. M19_PRG_A000    =   $E800, F7 Y, N4 ^' Z3 p
  47. M19_PRG_C000    =   $F000
    3 I& e( a4 {1 }1 M4 }
  48. M19_IRQ_COUNT_L =   $5000
    ( ?! h& R/ x& a( L
  49. M19_IRQ_COUNT_H =   $5800
    " }- p3 Q6 n! d) N* f6 D+ Q2 ^
  50. 9 R9 l/ _. v; @1 E' B/ a* Q8 B
  51. ;==================================================  V2 q, ^, c5 w: ~1 V
  52. ;程序块配置
    ! d. r5 o# q- g5 R' K: A: C3 B
  53. BANK_DATA_MASK          = $07* P5 _3 U7 D: }' ~
  54. ;--------------------------------------------------/ x* n9 Q5 w4 T. L5 r9 A2 B) M4 u( |
  55. RESET_BANK              = $07
    1 ]+ A8 W/ l! h6 N4 t
  56. RESET_ADDR              = $FC000 O. `1 N# S3 L$ s3 e

  57. : s1 W4 a/ n& _( |
  58. ;==================================================
    - u* f% D, [5 |. m5 h$ e7 W1 R
  59. ;图像块配置
    6 L; f! t! E8 q% A' [2 A
  60. CHR_DATA_BANK           = $08
    6 ]; M! |& x* Q9 k
  61.   y; D. ?& u( q9 x2 ]4 M. ]
  62. ;==================================================
    : G/ C; n% [: k9 E5 N$ V6 z
  63. ;零页内存地址配置3 N5 W, j& o2 q' K) z
  64. Use_Ram_Addr            = $80
    - c1 g! u# i0 v. O+ k
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    1 ]" @1 Z; i% P
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    1 }# G$ n5 w- p. H- S) D0 c
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01) b( r( k/ l9 O5 d9 K- j3 ]
  68. PPU_Scroll_V            = PPU_Scroll_H + $015 L* b6 y3 d( [  L
  69. FC_Data_L               = PPU_Scroll_V + $01
    ( O- H$ a) m8 s
  70. FC_Data_H               = FC_Data_L + $015 y' `+ R+ l& i1 v% k9 f
  71. FC_Data_Buf             = FC_Data_H + $01" O. |) U. i) g# w2 B
  72. ;==================================================
    ' |$ K8 n' N0 ^6 R
  73. 1 ^4 f/ Z7 k# a( _, p
  74. GAMEPAD_MERGE_FLAG = $04
      c7 {! q8 [& C9 s

  75. 2 o' m' G& |, y2 j5 `; m" k
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    6 S8 G8 }6 @% b  m
  77. Gamepad_Once            =       Gamepad_Keep + 2
    3 T7 @0 y5 P/ J
  78. Gamepad_Temp            =       Gamepad_Once + 2
    2 ?4 a& B# I' c
  79.                                 , h" m+ F7 `; y& j  R  `! y- X
  80. Gamepad_0_State         =       Gamepad_Temp + 2! Z, h) s1 f% L. }" G- l! ~
  81. Gamepad_1_State         =       Gamepad_0_State + 1% f/ C1 i* `  d( W6 e
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    7 S4 v$ ^( l# z6 N0 K+ b2 C
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1- z/ U6 h& D" Q* D+ s0 `" u
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 10 ^6 H  P7 n* m' ^
  85. Gamepad_Merge           =       Gamepad_Port_Value + 12 C# l& X6 L! W

  86. ) F( o/ ^+ z8 [" [, e; v
  87. ;==================================================2 H! o4 }0 C' `+ {6 J
  88. IRQ_Index               =       Gamepad_Merge + $01
    6 R  n9 O1 Z4 M( `
  89. ;==================================================% @, o$ C  {! U9 y

  90. & |5 K7 w( M/ L* D) ]9 \% G
  91. ;CHR图形数据6 @$ v7 X& [3 g( u
  92. ;==================================================* h* {3 x7 o  k* p! v1 \( c9 T
  93. .BANK CHR_DATA_BANK0 L0 L: L1 B5 G9 `/ Y
  94. .INCBIN "chr_bank/chr_data.chr"
    0 r1 ]: o+ @, X9 |2 ]$ `. j" o8 L
  95. ) U, ?2 L0 v/ N9 z  v5 v2 s
  96. .BANK RESET_BANK & BANK_DATA_MASK
    ( v8 i# ]- p7 ^
  97. .ORG RESET_ADDR
    * b" f6 k! W5 x/ a& [) |  G. m

  98. * z% s/ p! ?" j# l7 m" ?5 A% `5 Z
  99. ;--------------------------------------------------
    9 |$ o  s) ~8 E' a
  100. Attributes_Data. P4 g  r- x1 ]! g
  101. ;命名表属性5 U3 p% e1 M! y, h: W8 b
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00" @+ s+ R5 R* c) K. b- Y
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA9 ?- }  d& H' q1 \, j7 t
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA& [6 L0 Q6 r/ g0 B
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    : u0 t( d( U! i/ \
  106. ;--------------------------------------------------
    : b; A* @1 r/ g% z
  107. ;调色板数据+ I" X. Q) J+ Q( [9 z" I
  108. Palette_Data
    2 b  I! Z8 f* o: {# r
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    6 G9 ]7 S# h7 C2 v
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    - f- ^- l, P( I* |+ i- \0 F

  111. / F/ W) z" w# K3 Y6 g
  112. ;==================================================# P0 A  }+ _) d/ X$ p2 B
  113. ;命名表初始化/ z" u+ _( a$ w, q7 w
  114. Init_Name_Table
    ! I. C) z1 j/ ?( t# J# |# S8 w
  115. LDA #$209 i0 |# R2 U3 n! O
  116. STA PPU_ADDRESS/ g: s1 c0 d2 h! D
  117. LDA #$000 K: g; r) v3 M. L; i7 Y
  118. STA PPU_ADDRESS+ I* b3 `; q+ A5 w
  119. LDA #$004 @, l6 Q4 D6 v8 R, L9 Z3 b
  120. LDY #$00
    1 u' c4 f* S0 h5 f
  121. LDX #$10
    . V0 _  V, P/ Q# P. C% Q9 ^8 ?
  122. Init_Name_Table_Write! K! ]- A$ r) R
  123. STA PPU_DATA. B- q1 e% Q2 ?: K4 c; m; T
  124. INY1 h% z2 \; }5 Q- z3 b7 P
  125. BNE Init_Name_Table_Write
      h; K2 |: R4 S3 t2 p' I
  126. DEX3 `3 S2 _: P3 h* }
  127. BNE Init_Name_Table_Write
    " e" s1 _, d; {3 H& P, w, o
  128. RTS
    1 U. d3 _9 b* U* i, S; Y6 C
  129. 5 s. V3 M6 O; v; I, C& A# W, [
  130. ;==================================================6 D- U4 T# a. x2 e4 q
  131. ;调色板初始化5 G4 a& |( r7 S( t1 l
  132. Init_Palette+ Z6 w9 Y: g' e9 B% _$ q# e: U8 x
  133. BIT PPU_STATUS
    6 k& t+ C/ Y0 T8 w* U; D
  134. LDA #$3F2 p. t7 t& x2 u) d: h$ N9 j
  135. STA PPU_ADDRESS
    - T0 s- g$ ~4 X# i+ B& Z
  136. LDA #$00) q/ R1 A8 `+ z( N5 R
  137. STA PPU_ADDRESS9 p  b9 |- x5 e4 [. t' k
  138. LDX #$00
      j$ i; H6 i7 W( ~+ e( K9 a$ y! u; k
  139. Init_Palette_Write2 u, ?9 Z: Q  ^6 n
  140. LDA Palette_Data,X6 G/ o3 E/ {* w" q. K# P
  141. STA PPU_DATA6 K3 _" S( n3 b( ?
  142. INX
    , r/ q. H/ {5 k; q( s% P
  143. CPX #$20$ V# x3 f# I" L' `! {2 d, K0 N
  144. BCC Init_Palette_Write  z& u6 h( r  t7 Q3 `% w6 U
  145. RTS
    " O1 |4 U+ [1 h: |6 G# F! T) I

  146.   k8 A' w, W" ~. ?! X; o
  147. ;==================================================7 ?9 a+ [3 K/ V6 Y' K# \
  148. ;设置命名表属性
    & ]' {$ W3 G  k# N# i7 ?1 R/ m% {
  149. Init_NameTable_Attributes
      B* X& C/ @# N7 s
  150. BIT PPU_STATUS
    0 e4 {6 G5 m8 J& j. B( Y
  151. LDA #$237 D: F# j0 I7 I2 G, P
  152. STA PPU_ADDRESS
    " Q: _: ~1 B( J+ W- D+ }5 R
  153. LDA #$C0% D7 E3 ~+ S+ ]4 d! I" H
  154. STA PPU_ADDRESS8 ]+ H4 z) P  G. S% f
  155. LDX #$00
    # c6 k8 b0 T9 c" T. U+ s6 C
  156. Init_NameTable_Attributes_Write
    - b' O) l3 m. k, O! v+ p
  157. LDA Attributes_Data,X# M% T) b' |. K1 R
  158. STA PPU_DATA4 h6 Z. M: `- l1 e9 ]
  159. INX0 U2 V9 T" c2 J
  160. CPX #$40- ~! H! R& R+ D( n3 w* z
  161. BCC Init_NameTable_Attributes_Write
    % u& K, K) M% }5 F. j
  162. RTS2 u1 i* o* p1 f7 a

  163. & ]9 P0 i3 ]% G; E7 [
  164. ;==================================================
    ' N. B! }' a- S. s7 C/ \7 v) N
  165. ;初始化命名表文本, j4 ~- X3 A/ |- D; v3 B7 F7 X
  166. Init_Name_Table_Text
    5 Y8 J2 f6 K  I% r
  167. BIT PPU_STATUS
    * l& S9 O- q1 n; s8 j& y, w
  168. LDA #$20. U5 l; W+ E# Y) f$ H7 j3 N0 y1 |
  169. STA PPU_ADDRESS
    ( E7 S, u9 l+ c3 Y9 m: J
  170. LDA #$004 x4 L% ?# z+ O# V; C
  171. STA PPU_ADDRESS- m9 P6 B- \' ?  [
  172. LDA #$00
    " u# q6 f/ \$ Y' u0 K
  173. STA FC_Data_Buf6 k# x. Z. D& G% O) r
  174. LDY #30
    & O9 F- P; Q8 f2 S, z
  175. Init_Name_Table_Text_Write( p6 o+ h5 x- n7 ]8 I! H
  176. LDX #32; i6 m' I0 H1 ~5 `  X" y
  177. Init_Name_Table_Text_Write_Char
    4 j: [. ~7 L  t2 i) U* q' C
  178. LDA #'0'
    ! z% H3 A, J& J. o( w
  179. CLC
    6 g4 e( d# W4 o& c7 C9 y
  180. ADC FC_Data_Buf
    ) x: E$ d0 f7 h+ I, W* z& `
  181. STA PPU_DATA5 h* A* X# F2 z/ l* l
  182. DEX
    . \) A2 v6 U$ k' V$ H% V
  183. LDA #$140 m5 A3 U0 F4 ]
  184. STA PPU_DATA
    3 X; a+ X' I0 l: K& }0 B$ {
  185. DEX
    * I1 O4 y! w2 E) ]
  186. BNE Init_Name_Table_Text_Write_Char( o! [/ s- w+ R6 G% B0 b+ W& `
  187. INC FC_Data_Buf
    # z, ~: Z5 Y* O# l0 |. G+ |0 \: @
  188. DEY
    : W5 F% L" Y' W% \3 j
  189. BNE Init_Name_Table_Text_Write
    ' a- A, I- d0 C4 W7 u2 `* k
  190. RTS6 M4 S+ k$ p- S/ i1 }) S
  191. ( k. ~) ^" X* T- b( n& {/ l8 F
  192. ;==============================
    3 ?7 U7 K5 H4 ^" }
  193. Init_OAM_Ram;初始化精灵内存5 K9 }) S6 Y: U6 A$ ?
  194. LDX #$007 I& L/ a/ B* Z4 ?; D$ Y/ ~
  195. LDA #$005 D: I2 j' E& Z$ x! ?/ N! Y
  196. STA PPU_OAM_ADDR8 L% u+ W% t  `* S# E& b1 D
  197. LDA #$F8: @1 `5 p2 J( W+ u2 W: V6 c
  198. Init_OAM_Ram_Write
    9 G% o( V$ n2 Z% ~( O! s6 s. }! D
  199. STA PPU_OAM_DATA
    6 ]; @/ b3 l6 h- h5 W8 j. U
  200. INX
    : O6 `3 s- L) v4 w0 T
  201. BNE Init_OAM_Ram_Write& B" }/ C0 m: h/ `) u4 \* B' b
  202. RTS- E0 j5 N. {( H! E" \$ g8 J6 x8 s4 A
  203. 7 C: u6 i7 N1 \3 o% A
  204. GamepadProcess;手柄处理
    , \$ t  `" ^$ X, K4 m& t1 x1 S  e
  205. JSR GamepadDatacan7 X" O' ^/ p9 K; S. L% F3 H6 h% x
  206. LDA <Gamepad_0_Value* q0 H1 O  r2 N1 Y1 F+ Y; g
  207. STA <Gamepad_0_State, f% c+ J1 [2 @2 A; }( \0 V
  208. LDA <Gamepad_1_Value
    " G0 w* t6 u  e
  209. STA <Gamepad_1_State. q. V; Q& Y( I
  210. JSR GamepadDatacan. q- l- C0 }% e, d& A2 E7 }" e( y
  211. LDX #$01
    ' B. h, `& h) o% i
  212. GamepadMergeCheck;合并手柄输入检查- M9 p8 w: d3 Y
  213. LDA <Gamepad_0_Value,X# j5 W5 `2 i9 {1 I( R6 V4 N7 C
  214. CMP <Gamepad_0_State,X
    $ n5 t* ^7 P# X, ?6 I
  215. BEQ GamepadMergeInput* g8 q: E  d% W5 V; a3 A4 C  Q
  216. LDA <Gamepad_Temp,X
    7 F9 V3 w( c. H& Y
  217. STA <Gamepad_0_Value,X
    $ R6 [) k( G9 q8 L
  218. GamepadMergeInput;合并手柄输入, C  o3 A' Z% H& u
  219. DEX
    0 \8 f  C7 o" d0 Y
  220. BPL GamepadMergeCheck
    + \0 [1 W  ^! p( D" N% S7 E
  221. LDA <Gamepad_Merge# H$ t' c' d7 Q* j" L9 {
  222. AND #GAMEPAD_MERGE_FLAG9 q4 g6 b/ y# t5 M% n3 X
  223. BNE GamepadStateProcess
    ) ~& d4 s  ]! X0 z; v) ?6 M+ }
  224. LDA <Gamepad_0_Value( O. `% w3 ~2 I% [
  225. ORA <Gamepad_1_Value/ x! U1 C7 x' c. e8 }* }) X
  226. STA <Gamepad_0_Value
    / d& U( R' R1 f
  227. GamepadStateProcess;手柄状态处理
    - l. A) T3 ]7 N6 N! q* z3 B
  228. LDX #$01/ b3 `$ ]" V( T( N
  229. GamepadStateSave;手柄状态保存6 t# k2 V3 X& ^5 ^+ ?9 n
  230. LDA <Gamepad_0_Value,X6 C. C' \* b& \% H; Y
  231. TAY
    + P) r, b4 K9 W  F& T
  232. EOR <Gamepad_Temp,X
    : h2 m! a: g/ ~; {+ y" J
  233. AND <Gamepad_0_Value,X4 ?" ]6 m: v' K. K$ B+ H
  234. STA <Gamepad_Once,X
      `# A; L( V8 X+ N9 c% I
  235. STY <Gamepad_Keep,X
    & [$ z0 s/ @, R7 J7 x; W/ M' S' `8 o! K
  236. STY <Gamepad_Temp,X' p/ M  l& ^3 Q( i& g
  237. DEX
    0 w9 w5 P6 s) J. J6 a
  238. BPL GamepadStateSave
    5 }) A% J1 ^  S; X4 L4 }
  239. RTS9 o/ L8 G- S3 C

  240. 5 _8 H. Y  s: D1 m+ T
  241. GamepadDatacan;手柄数据扫描
    9 {" `7 g5 f" L/ |8 ^1 @& Z
  242. LDX #$011 x" G6 M( F4 E) g- M
  243. STX $4016
    0 J5 N6 T, s4 Y; t2 O
  244. DEX* x$ L0 `% n& h$ K+ i2 j8 Q
  245. STX $4016- F! ?+ ^3 o5 z, a$ O. o' g
  246. LDY #$08
    0 E- u: z" ~; b2 h. Y$ U. u+ P. n
  247. GamepadPortScan;手柄端口扫描
    % Q* W8 B; I1 i; J) B/ n1 x
  248. LDA $4016
    6 h1 S: [  z' n9 y
  249. STA <Gamepad_Port_Value# b; ~# u7 g+ G( o' r' {
  250. LSR A
    3 l: Q/ y+ y4 j6 |
  251. ORA <Gamepad_Port_Value
    5 h" j8 ?6 r5 S3 W3 i& E
  252. LSR A
    ( j5 e3 d' N; a7 V4 K- D
  253. ROL <Gamepad_0_Value3 {  f* f& j  L/ u& U; ^
  254. LDA $4017( h0 y5 }5 y# S' I$ I) y. F* a
  255. STA <Gamepad_Port_Value
    * E7 f  s; c" m" Y7 E/ v) a# s
  256. LSR A+ f2 d: s. Z/ W  D
  257. ORA <Gamepad_Port_Value0 P# ?; p; ?, ?3 F% M
  258. LSR A
    . t8 p5 I# s$ Q- H3 U; X. @8 s
  259. ROL <Gamepad_1_Value
      E! L4 ?$ Z6 B# ^
  260. DEY, Z" }& y1 V' J( q. u% S1 I0 Y
  261. BNE GamepadPortScan
    3 i3 M7 s' d$ W# B# z( j2 V- B
  262. RTS* P( ^+ d* K! v! ^: }) d
  263. 5 @7 O3 Q: }$ R1 G; X& P
  264. ;==================================================
    & F+ F8 }" K2 f  e; U- @- }2 y0 l
  265. ;PPU处理( o( K) d6 Z  l% P5 f; t
  266. PPU_Process0 `2 U/ ^; s/ G/ g6 \
  267. LDA #$00
    7 M$ |+ @2 B9 W9 V6 B
  268. STA PPU_MASK
    + n# ^3 m+ h% n0 Z- D+ Q
  269. 8 B& a0 l, f4 Q7 `! i) X
  270. BIT PPU_STATUS, y4 o, Q% U2 H" O  ?
  271. LDA #$20  C0 t/ Q0 T6 @" z3 l
  272. STA PPU_ADDRESS. B4 h, L' c5 i# I
  273. LDA #$008 h+ E% x9 t& y, z) V
  274. STA PPU_ADDRESS+ E0 S. z# E' u8 ~/ ^+ c. o* j) y

  275. . z" V) O0 N4 r5 y4 H
  276. STA PPU_SCROLL  z3 ~3 w% G* _. ]0 g
  277. STA PPU_SCROLL1 T, e  l! H! d( c

  278. 3 w. \$ L" s& f. s  ]- n
  279. LDA PPU_Msak_Buf
    7 \& e8 M9 p/ e& o( ?0 q5 A, d7 E/ y( C
  280. STA PPU_MASK
    # v, ]3 @1 R1 F. U0 e
  281. * t1 y! p, Y* R4 D1 t; s
  282. RTS
    1 {. R4 i% p$ o0 U* _! N) y: _

  283. ) a' J$ R9 ~: \
  284. ;==============================
    : R; n1 V. M% |
  285. Time_For_Vblank;延时等待' A' F" U6 R2 x$ z3 \) A) ~
  286. LDA PPU_STATUS
    - f1 I( v* [! c) w4 b% t) J
  287. BPL Time_For_Vblank
    % c% l; {3 V7 l$ A8 R# l
  288. RTS
    / X; Y+ @7 \( d# R, t- l# Y

  289. : p8 j7 b& e5 F' N$ I  y
  290. ;==============================9 f& _6 U" z! \+ r0 j8 r3 F% K
  291. ;初始化MAPPER199 X: h: m/ I* ~% T4 s  x
  292. Init_Mapper19  V' O' e; ?! a; J8 A
  293. LDA #$00: j( S0 c5 @2 u; {% `/ f& j
  294. STA M19_CHR_0000. D+ m% Q+ t. j% ^- p& e$ i; J
  295. LDA #$01
    . y' ~9 y4 M# T0 _8 W! s
  296. STA M19_CHR_0400
    $ o+ R& i1 U2 d
  297. LDA #$02/ U+ y1 x3 W, P) T2 h3 n/ j% J
  298. STA M19_CHR_0800
    . p/ V- j9 i% i2 q, a9 {
  299. LDA #$03
    5 U8 a) _8 M5 n2 u" e
  300. STA M19_CHR_0C000 [9 T( L7 d8 W( x+ }- {2 }
  301. LDA #$04
    1 k* t7 ?$ |% E; c+ a
  302. STA M19_CHR_1000
    ' V0 B& m" X- C+ n3 Z2 E
  303. LDA #$05
    : ^: T2 u2 I$ w+ y
  304. STA M19_CHR_1400" m: |$ d2 O8 h1 @! M( y
  305. LDA #$06
    : B  c$ v  I1 l
  306. STA M19_CHR_1800
    * z$ d$ V' ]) V
  307. LDA #$07
    6 V* s( d6 i  q( E# V
  308. STA M19_CHR_1C00
    1 F  r2 ^( z# B( K9 N% e
  309. ! R1 V9 ?/ l! J* z- [
  310. ;禁用IRQ+ p7 q% e' I8 ^( J' C
  311. LDA M19_IRQ_COUNT_H; B4 F# W% g; B
  312. AND #$7F
    8 {! Y5 M& W( N* r# @
  313. STA M19_IRQ_COUNT_H
    ; |0 ^4 A3 r0 x/ e6 S
  314. * I+ e3 R* q! k  }; a* v5 Q# @& i. N
  315. ;命名表
    8 s2 I' O7 h0 ], o8 m
  316. LDA #$E0
    % _9 w, ^' n$ Z+ N, I8 Z" x
  317. STA M19_NT_2000  i0 M- g7 ]; K. S8 @0 k5 m
  318. STA M19_NT_2400* a" h4 o6 j1 V! ~: s1 P8 t: L" y; @

  319. 3 L. Y; m/ w+ a" B+ H
  320. ;命名表
    ' x' y1 M' W0 K1 p
  321. LDA #$E1
    6 ^0 J% f. ~; {( J) [
  322. STA M19_NT_28004 v/ E1 @1 o% j4 [3 ^
  323. STA M19_NT_2C009 D4 V, b3 m" W* Q; E# j

  324.   o: ^7 ~) k% `( V- h7 E
  325. RTS: F' w6 w2 P' X( F+ K
  326. 7 K  L# J. P. h- Z
  327. ;==================================================
    2 q6 W3 t( a: d/ }2 a# t
  328. ;重置中断处理* d3 t  x; Y; C  D
  329. ResetProgram% V! |# [7 Q% l3 q
  330. SEI: S& n0 d0 b; d7 t
  331. CLD$ R1 _+ D& `- z+ t5 u/ h' O* J
  332. LDA #$00
    & A( q7 |% n; k2 w: W
  333. STA PPU_CTRL
      d; M$ g# u3 ?, h% L
  334. STA PPU_MASK6 J' \- p3 w8 M5 @  {
  335. STA PPU_STATUS
    " _5 K9 t; c+ C
  336. STA JOY2_FRAME
    $ t7 b! j7 p4 J# x
  337. STA APU_STATUS- v, A7 [8 W' s

  338. 1 S: H' B( |% ~( q; A5 d
  339. LDA #$C09 z. j! {( ~5 v4 j& m2 _$ @
  340. STA JOY2_FRAME9 E- n0 S% y/ R! U

  341. ( v  }4 F  o" D3 X1 G
  342. ;等待vblank
    ; g' N' z- I  @
  343. LDX #$02
    " L9 I( }0 |; ^! t% g
  344. Vblank_Wait_1) P5 a! A) b5 ^; P. T8 h
  345. BIT PPU_STATUS1 O/ l( C9 B+ y
  346. BPL Vblank_Wait_13 o% `- B4 e" L2 c% g
  347. Vblank_Wait_2
      e' ?* O* W+ i2 t4 U7 c
  348. BIT PPU_STATUS4 H6 ?8 A5 m  A; Q" P
  349. BMI Vblank_Wait_22 X3 u8 _/ d1 @% o
  350. DEX
    8 P7 n1 W6 q: p& }
  351. BNE Vblank_Wait_1
    - \0 {3 f0 r$ }1 l+ \9 Q7 W3 @
  352. $ A% U, |* H1 s, y6 V
  353. LDX #$FF
    ( l+ A6 r6 f5 a+ b# k+ D1 Y, M
  354. TXS
    % b+ j4 c+ e  [& Z! ~2 {

  355. ; v! z' a9 w0 j' a  a( L% p
  356. ;初始化MAPPER193 R3 h% C6 p( p, p" x' ?
  357. JSR Init_Mapper19* n4 D2 Z1 T0 K

  358. & W7 L) D# j: D+ x3 q& ?
  359. ;==============================- n! z& J& W" w7 x8 o! t
  360. ;RAM初始化
    2 a1 [1 [0 D3 ^9 y* V" a
  361. Nes_Ram_Init( q- B; A, P+ y# e
  362. LDY #$00
    - L* T& P$ C' Y. C0 l0 m
  363. LDX #$08
    4 u4 d/ b+ t$ z0 n
  364. LDA #$00
    1 E/ p* P- d5 I) ]
  365. STA <$00
    0 b2 @# p$ a! \+ R' r
  366. STA <$01
    : u% D  D, Y8 ]' N7 }& s! |" d' h
  367. Nes_Ram_Init_Write, k% s* Y" N, r8 z
  368. STA [$00],Y* J2 P. K, J+ [6 [" M9 b
  369. INY/ u! S$ E  Q9 M3 N
  370. BNE Nes_Ram_Init_Write
    6 h$ H2 T$ U1 S( {1 `1 V  C
  371. INC <$01
    . x& m. h: D0 k; F
  372. DEX8 ~9 m9 u3 {" S. u' j8 B! P9 ]
  373. BNE Nes_Ram_Init_Write+ d! R3 k) n4 \- ^

  374. 5 }4 z: F# ]0 H- M6 r0 ~
  375. ;初始化命名表  D/ V( L! v: _
  376. JSR Init_Name_Table
    1 i) J. `9 t2 ^5 S0 M% T0 e

  377. . c& M! M& l: f( b- {8 c
  378. ;初始化调色板
    % K0 Z8 `! ^3 M
  379. JSR Init_Palette; t; e0 j4 B- V8 x# D4 t. k

  380. 9 u  t9 Y/ N, \, A) q" I; Z  |# A
  381. ;初始化命名表属性; v( h5 E4 w7 N& r
  382. JSR Init_NameTable_Attributes: n3 R; t0 }0 N5 A4 S9 a
  383. ; P4 i( G" B3 S5 j2 ?' p
  384. ;初始化精灵内存
    3 M' Y* g6 W5 \8 ~
  385. JSR Init_OAM_Ram
    3 d" u/ ?/ P2 n) c; V

  386. + S$ d  L0 R* B+ r' _- s& ?
  387. ;在屏幕上写点东西
    3 D) `8 h! b7 W5 V3 `" `2 w
  388. JSR Init_Name_Table_Text
      e; ?# h0 A0 M
  389. 1 V0 y/ F2 }- U2 N4 A# k5 y7 {
  390. JSR Time_For_Vblank
    - W- @% c3 x7 R  E/ H4 w( i
  391. ;开启PPU控制
    " s1 M3 q- n& O. W4 X7 W
  392. LDA #$A84 f  d9 }. L) @+ z' A3 O+ Q+ d
  393. STA PPU_Ctrl_Buf- r( k) C- d9 I8 y& E- ]0 u
  394. STA PPU_CTRL  w# B3 c9 x6 c3 Z& h* g- X& H
  395. * G/ f/ o9 O3 o3 w7 z6 Z. ]8 B
  396. ;开启PPU显示* T. @- J' s, A! \6 T% }
  397. LDA #$1E
    0 w6 _3 U% z& E6 ]- `# Y% c* S
  398. STA PPU_Msak_Buf
    9 D* _4 d& _1 p' E' q

  399. 9 N4 H0 c- Z: ]( \0 M
  400. CLI
    * X) W9 _6 ~8 x: M, Q+ Y
  401. JMP Loop4 V2 v6 M$ t9 V/ _

  402. $ V2 o4 H0 C! {: V) y, E% r
  403. ;==============================
    ) B% X8 B- p9 b8 R+ B  W
  404. ;死循环, 等待NMI中断
    1 a, _8 b7 ~- y9 i, d- U
  405. Loop
    $ g7 t( t2 o: y6 T
  406. JMP Loop) {3 A, i5 R6 N

  407. : A& y, S4 b) e# `0 ~- q- W7 F) d
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9672 ?4 I3 ^( }8 h" F; ^# k, I5 u5 Z3 B
  409. 5 X; j1 d5 u! j% T
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    2 ^3 y6 G4 E) e
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    , n1 ?/ B5 h6 e+ P6 q& B
  412. ;==================================================
    8 y3 L- N. H) P. Q
  413. ;NMI中断处理. B) G8 j. z( K2 i' G
  414. NmiProgram
    . }6 S1 B  B8 `3 r: m
  415. PHA
      r, X6 L1 |$ l
  416. TXA
    9 y% v# p( l  N# L
  417. PHA
    7 ^+ n9 W6 Q3 l! t# O
  418. TYA
    . F3 V; u/ Y- b
  419. PHA
    . d8 ]# q0 K  B$ |
  420. . n% X; p" L, v5 Z
  421. BIT PPU_STATUS
    ( F! B  _/ P: Y

  422. * q3 Z$ Y% h% W
  423. LDA #$00) I) C. H: r0 \/ x- N! B( ]
  424. STA IRQ_Index
    3 A' I2 y9 I9 C* Q2 s8 d, ?/ K

  425. 3 y/ K4 J6 [1 Q  W; Q4 u0 t$ {
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    " e4 w5 ~6 l% {
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)  \: o8 {9 y8 f& E/ n4 u" }
  428. STA M19_IRQ_COUNT_L' Y4 ]' c8 Z& ]; N5 `
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)0 h' e* Q: u& N" K* m$ v- D( y2 r
  430. ORA #$803 }  l; h5 ^( ?8 X6 q- T
  431. STA M19_IRQ_COUNT_H5 s; X. r9 f/ P. d
  432. CLI
    # q# c% Q6 A: j; r$ g$ z/ s: O2 c

  433. 3 n" Q  P! c! s# F2 t
  434. ;关闭PPU控制
    2 @& \% J+ z/ ]  t
  435. LDA #$00# {% r! m8 }+ J0 r+ D& t
  436. STA PPU_CTRL4 ^7 B( g% Q/ B( n
  437. 3 M1 I: D8 ~* }% S; e; ?8 P" P
  438. ;处理PPU  Q$ o3 U3 }# W
  439. JSR PPU_Process
    - ^4 B7 X7 _: R' U
  440. , s1 z: O: @) X) k
  441. ;开启PPU控制' u! u  v7 R: G1 \
  442. LDA PPU_Ctrl_Buf+ y# S' M: w7 K9 l# D  O
  443. STA PPU_CTRL; ~0 u4 \. f' K& p- f
  444. 7 V1 p! v& S, x  a0 f
  445. ;手柄处理6 W4 N0 s0 }2 d2 {' [) ^: W1 K
  446. JSR GamepadProcess; h8 d. J1 [' \  \3 A+ x! w
  447. + z, f; j# A2 M& w# p! Q
  448. LDA #$00  t' w3 r4 A1 e  @
  449. STA IRQ_Index
    7 p1 w4 d: f3 {6 [

  450. 7 W$ j6 V1 C9 M% A5 P6 q" R
  451. PLA
    % M# B1 Y. j; S
  452. TAY
    6 M9 b8 n7 ]7 z7 B" b
  453. PLA
    : p! h+ S/ R: u2 o( o: o
  454. TAX
    + z0 A+ {2 h4 \7 g7 v% z. _. Q8 G, s
  455. PLA
    9 z2 G! _. I% ], y4 V: q6 o
  456. RTI' x# f1 F" p; l0 u" m5 ~* @
  457. + U% p2 m1 U" p0 a" Q) V
  458. ;每行扫描线113.678 a6 f0 ^7 u3 b0 \% S. B& h
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)7 R1 ~) x' v$ L6 b3 K* l
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 76 K, }$ r/ ~4 a1 D6 x
  461. ;==================================================
    $ {9 _9 D$ a# R0 u/ J5 Z0 B. T# ]0 v
  462. ;IRQ中断处理
    . B1 C( M- L$ l6 X, j/ b: u+ F0 L
  463. IrqProgram5 Q7 c; U* z4 [! c3 T" }
  464. PHA
    % z( ^6 u* J4 ?  Q+ g
  465. TXA
    7 r8 W1 @" a# N, ~' O
  466. PHA# j- q3 S3 T$ I* B
  467. TYA
    " L* S3 w  ^2 O) j6 l
  468. PHA9 r( Z7 C0 G7 ]! L! B  c" z$ S

  469. 0 P9 Y$ Q6 D) a" ]# K
  470. ;16条扫描线后触发IRQ; f! I0 D9 q* _1 s
  471. LDA #LOW(BEGIN_LINE_CYCLES)* T) f7 }# f2 w7 c
  472. STA M19_IRQ_COUNT_L- W+ q. E# l9 H: H! j; n2 ^, l
  473. LDA #HIGH(BEGIN_LINE_CYCLES)( ^" W, \$ S0 B2 T$ q
  474. ORA #$80
    " T) p8 L: l3 b; b
  475. STA M19_IRQ_COUNT_H
    ) ]+ ]& D/ Z. G/ D9 t6 ]' v7 ]

  476. ' t% e" t7 A1 I; }9 N) k
  477. LDA <IRQ_Index
    . s- P. f; X4 e& k
  478. BNE * + 4
    6 ]$ {& n* h' S' a2 M3 L
  479. INC <PPU_Scroll_H8 E3 D' t- l7 J+ ?
  480. & J( i$ u* {7 e3 v2 c; a5 R) Z
  481. ;设置屏幕滚动
    # g3 {0 @5 c  x" G9 [" m. Q& A3 u; Q
  482. LDA <IRQ_Index
    / I8 u8 W8 u% `& X8 P
  483. AND #$011 P2 b, G. x! U8 r5 c! I
  484. BEQ Irq_Scroll_Right' ^- l5 e4 p. S% ^" q9 h4 H: C

  485. 6 n! y7 v. W2 u2 p
  486. Irq_Scroll_Left
    8 ?4 s- b6 f4 o  O9 N3 B$ F
  487. BIT PPU_STATUS+ n% D/ @7 F2 a& }
  488. LDA <PPU_Scroll_H4 k3 _' S) u1 U% Z0 ~
  489. STA PPU_SCROLL' A8 K0 M% c' B
  490. STA PPU_SCROLL* s7 G! `; E+ h1 p  t
  491. JMP Irq_Scroll_Over
    % `+ f7 n6 b7 b2 S" \! o' [3 m
  492. - s- m2 E; ?; _, |2 ^
  493. Irq_Scroll_Right
    * i& I0 \( m/ t
  494. SEC
    + ^) e( b5 I- G4 k1 w& l
  495. SBC <PPU_Scroll_H
    + z7 F) n3 L! m/ z+ t3 T2 z2 B
  496. STA PPU_SCROLL2 m* E/ p  |9 p/ r3 Y0 k
  497. STA PPU_SCROLL4 f' n) t, s" Q9 s
  498. Irq_Scroll_Over. F3 D2 B1 y8 e- s
  499. $ o1 V% B8 ^: Z
  500. INC <IRQ_Index% _+ V! U  j2 A" ^
  501. $ j1 T4 w4 D5 S
  502. LDA <IRQ_Index& K1 g4 i6 [: n* Z
  503. CMP #14
    ) N$ M4 {; \! ]& {% F3 M& h
  504. BCC * + 10
    5 [8 i* t9 e$ y
  505. LDA #$00
    7 M9 D& T/ A# q, a% [6 ^
  506. STA M19_IRQ_COUNT_L5 ^- i; T" |  z/ E- `4 l/ @3 m
  507. STA M19_IRQ_COUNT_H& h  t6 u* Z0 Z/ v* u

  508. ; e0 `/ n7 h( X! d! X( t
  509. IrqProgramEnd" k, D8 t* @% b1 i+ L; G
  510. PLA9 ^7 ]0 d; Y9 F  w1 G* M
  511. TAY
    & A# t0 T) f( _4 U& F
  512. PLA& H, W. X+ j* E9 G7 s) R* ^
  513. TAX. s0 l/ E5 S) I  F- C
  514. PLA4 i4 F0 G. V, V6 A' n
  515. RTI
    0 ~) T3 W! E9 U# J
  516. / F5 O1 [6 V) r$ d7 ?
  517. ;==================================================
    ; v) b' Q/ h- F& ?, n$ B7 }9 ?
  518. ;中断表& K2 |; u: ]. N3 K+ f# R0 r! Z
  519. .ORG $FFFA3 W! A2 |5 e# n# w1 m
  520. .WORD NmiProgram
      i) q& Q$ h; V# F4 y* {+ e
  521. .WORD ResetProgram; K& B% k+ q5 V2 J5 l; @
  522. .WORD IrqProgram
复制代码

" q5 E, A+ C3 H' B; k' a

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-12-26 19:36 , Processed in 1.089844 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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