EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]6 h6 o/ r$ D' r: e) Q1 G
  2. ;FlameCyclone 20230710
    8 E& R" P/ k5 {" T) X3 L7 T7 {5 H: P
  3. 8 ^: Q% g, D, @
  4. ;文件头
    ; I$ A5 `" T$ k, G
  5. ;======================================================================
      n: W- U( J6 p; [
  6. .INESPRG 4                                              ;16KB PRG 数量7 q" I. N# M. T
  7. .INESCHR 1                                               ;8KB CHR 数量- u" ^9 T+ _, S' e5 ?/ u
  8. .INESMAP 19                                                 ;mapper 190 u$ D# Q! w; E. n
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直* o! w! ?9 T* @' |3 i

  10. : g9 b* O4 H+ G" {2 d
  11. ;必要条件
    6 m9 {8 ?% W! u* X/ k
  12. ;1.持有CHR ROM
    9 ~( \* `8 T8 V
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ' c  j( V7 Y9 M% h
  14. ;3.精灵内存(OAM)不为空
    $ a8 U+ U. k3 Z8 g; ]6 |) K; Q' a

  15. ) `* u2 o- {# f" A
  16. ;==================================================
    3 J; Q# B* D" q' M( I- @! ]1 M7 D
  17. ;NES端口常量
    ; R& p! u7 p! D" D1 z
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器3 F! B4 [1 i  J! G+ p2 P: Z- X
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    & v8 @9 i6 u- V; R
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位/ e6 K4 O! d7 n/ D! `, a2 d
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1& i, @* F6 g- ^! ^+ V% r6 T
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
      V# {0 r* x8 ]+ ?8 g
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 / h& S- o2 ^* q6 N* u1 u
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加6 H9 S% ^- o$ Q, K- n$ Q
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32   D  c! O( O1 [* m: O2 k) i6 ~2 \: k
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存8 y! k* e: K; j9 w4 W/ C7 a
  27. APU_STATUS              =   $4015   ;声音通道切换
    * m% T6 O0 A$ C1 Y0 g
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通5 l& @$ j3 p7 B; t2 T$ `; X) q. l
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    # t. ]+ E0 _3 n

  30. $ ?0 I/ i3 y( i% O. w/ g
  31. ;==================================================
      ~9 @' G" d1 E! }) i: T" _& i
  32. ;MAPPER 19端口常量
    % k& }, ^+ b) M# T
  33. M19_CHR_0000    =   $8000
      W- k, s, ~0 h, D3 _* g; ~/ E: U
  34. M19_CHR_0400    =   $8800
      A3 W' b/ _# c% _( t
  35. M19_CHR_0800    =   $9000
    1 f" X. _* ]" g% r# {7 a: s: b
  36. M19_CHR_0C00    =   $9800& L) s0 z1 V, ?
  37. M19_CHR_1000    =   $A0009 w2 q1 }! l, a5 R
  38. M19_CHR_1400    =   $A800
    ! ~& a* O5 r/ V3 C# [
  39. M19_CHR_1800    =   $B000
    . g1 X) ]+ {0 Z* D$ v+ o6 E
  40. M19_CHR_1C00    =   $B800
      q4 c9 o3 s2 N$ k4 {/ i" s2 c  n& H
  41. M19_NT_2000     =   $C000
    % `, S9 d0 |# P- v4 J
  42. M19_NT_2400     =   $C800
    ; C; K5 T! d, l) R1 j
  43. M19_NT_2800     =   $D0000 E: H7 g- K& a2 Z2 E& l$ T
  44. M19_NT_2C00     =   $D8005 \- x5 t5 y- ]% W! i" C* {0 @
  45. M19_PRG_8000    =   $E000
      O" u  B1 n8 N' n3 R+ i0 {
  46. M19_PRG_A000    =   $E800- l9 Z7 e% x; ], ]" n
  47. M19_PRG_C000    =   $F0006 V! w& d8 C7 h0 f7 _0 X
  48. M19_IRQ_COUNT_L =   $5000
    ! M' j$ ]0 Z9 M6 n' M( d1 g4 G
  49. M19_IRQ_COUNT_H =   $58003 H0 F3 W/ r# q' Y! G6 |! t4 S

  50. , V# w# ~% a) d: v9 L% [
  51. ;==================================================6 N5 M+ f3 y! ]
  52. ;程序块配置+ w: n2 d  ?% I. p) i) C
  53. BANK_DATA_MASK          = $07, ^9 Y& F6 Y/ D5 N! H
  54. ;--------------------------------------------------3 a" N! V' V+ l8 y6 t
  55. RESET_BANK              = $07; \" B' t7 _9 J3 e0 M9 e% Z
  56. RESET_ADDR              = $FC00% P0 n, j* w- ^

  57. 1 e3 X- n3 U/ o- K( Q2 \  T( Q+ ~
  58. ;==================================================0 s* F& u" i/ s
  59. ;图像块配置7 `4 X. F5 _# ]- Y4 M9 x& V1 q
  60. CHR_DATA_BANK           = $08
    4 a. ]2 Q  B6 C( M( Z

  61. / i5 m  |( r! k7 A1 ~( F/ L9 j
  62. ;==================================================6 W5 b0 F* I7 Q/ h& m: z
  63. ;零页内存地址配置
    8 ?$ p# j/ Q' E% H. q* T7 J$ a
  64. Use_Ram_Addr            = $802 f' H5 w( M# p1 E$ N# D& f/ s
  65. PPU_Ctrl_Buf            = Use_Ram_Addr/ E: m1 e8 S0 @" V" ~* ~0 ~( a
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $015 b' z( [& Y8 q3 x; m# }& I3 u
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01/ p) R# b2 T2 k8 A: `7 G! G9 s  e
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    ; j+ u" c) O  b' X3 K1 K! s
  69. FC_Data_L               = PPU_Scroll_V + $01( r0 Q. H. t1 ^" Q+ v
  70. FC_Data_H               = FC_Data_L + $01
      [! t5 i! `; U4 D- J
  71. FC_Data_Buf             = FC_Data_H + $01
    1 |  m" n, d% m5 Y( r
  72. ;==================================================
    1 ~; ?; M& @" j$ b$ q! U$ J
  73. 7 Y/ q: T0 y) i; i. x" `8 U) g& s
  74. GAMEPAD_MERGE_FLAG = $04
    8 {% t+ o% l2 d3 x/ n9 t& E% v

  75. ! ?! x: B" C/ i( s0 A
  76. Gamepad_Keep            =       FC_Data_Buf + 12 [& q, x, H" o7 O+ R$ x- O
  77. Gamepad_Once            =       Gamepad_Keep + 2
      C' A, g/ \5 w! T5 x! Z
  78. Gamepad_Temp            =       Gamepad_Once + 2
    : O- k" W# @& o8 ~6 K8 i9 H
  79.                                 
    2 v5 A2 p5 b2 I: S/ C4 T( X# Q
  80. Gamepad_0_State         =       Gamepad_Temp + 26 Y0 D2 Z+ s: k5 S
  81. Gamepad_1_State         =       Gamepad_0_State + 18 \& n. o+ r0 t" L
  82. Gamepad_0_Value         =       Gamepad_1_State + 13 ], d5 w. t8 z2 \: a7 R
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    7 e3 X. F* }6 c# C% G# l7 }5 u  k
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1+ u% b' V# s) \
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1: G. L% \, l- J  u' |
  86. 9 x# r! ?' ?# F6 E0 P% s
  87. ;==================================================
    1 n6 [0 L* V. O1 s: g6 {2 L
  88. IRQ_Index               =       Gamepad_Merge + $01" ]5 w: D, S4 k- ^
  89. ;==================================================+ T# i. V7 U  N5 q# `) n
  90. ! Y9 P9 E9 L2 Z( l  L
  91. ;CHR图形数据
    0 W9 x( |9 A- N2 h- T
  92. ;==================================================
    5 i+ a- {( D+ t# X! v: V
  93. .BANK CHR_DATA_BANK$ J$ V& w' u( v3 U, G
  94. .INCBIN "chr_bank/chr_data.chr") }2 X; W0 k! `, x" M! G/ k
  95.   l% G8 i* x0 G9 c0 e# l8 U, c
  96. .BANK RESET_BANK & BANK_DATA_MASK
    6 `) P4 f! M6 O# u4 v( }6 @
  97. .ORG RESET_ADDR
    / Z; \3 z. O+ e" M  o) \. N; t% U
  98. 2 c$ u5 F! a# u. O
  99. ;--------------------------------------------------: P( z" o& {6 Z) y+ s; L
  100. Attributes_Data
    2 F0 e. l+ C* k# `/ w& j; p& E/ G6 P
  101. ;命名表属性+ f5 S4 t6 n4 h0 ^( g- ~
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00# G  ~6 o7 n1 Q5 r8 K% X
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    - K& g, U: W+ o+ o* ?
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    ' s7 D5 {1 g4 t
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55# Y& i5 |8 P" ^3 N
  106. ;--------------------------------------------------: F$ r3 X' g1 I5 f2 p: |! Z+ `& J
  107. ;调色板数据
    ! _$ }' D3 |% |& p- `1 _& O  n
  108. Palette_Data" C8 @) M$ j0 X4 H- H
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    % j/ p7 j" ]1 G4 R
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F7 A( L3 ^8 F0 _4 _7 T- A
  111. 0 L$ ~3 ]3 j0 b# T
  112. ;==================================================
    8 B0 ^+ R3 j) V) [, {
  113. ;命名表初始化
    7 z0 k, R% \. e# q' b
  114. Init_Name_Table( c. _+ T' Q  a: B" `/ [0 z: S
  115. LDA #$20
    7 a& J3 f" c$ D4 |' b: T: m# I
  116. STA PPU_ADDRESS
    1 h& X& a4 j: ]+ }4 Z! @
  117. LDA #$00
    8 c! P0 P0 H3 y
  118. STA PPU_ADDRESS% B+ O8 D# T& H' X6 x! ?
  119. LDA #$002 _- N/ X5 p& p% b: E$ ], g
  120. LDY #$00
    ) |2 [/ T7 E. y) x6 p. r
  121. LDX #$10
    - F0 e' W+ U6 x8 U) ~
  122. Init_Name_Table_Write" M0 \  Q: Z7 Q) I4 _
  123. STA PPU_DATA
      {1 e. K. }- k* p0 S" F3 O
  124. INY. L7 w  o: j/ z" V
  125. BNE Init_Name_Table_Write' u  Z1 g4 r( D; ^- `8 |" @
  126. DEX4 C* M( a! c  J1 Q  y$ ^# t( k
  127. BNE Init_Name_Table_Write9 \9 b3 b3 f3 P+ }( M6 |9 ]7 C
  128. RTS3 `: h8 T4 u- q4 Z2 N, K
  129. " a( |. T+ Y% z/ N0 R
  130. ;==================================================
    0 y$ V0 x/ i. D, ^5 O; p
  131. ;调色板初始化
    * t, X4 U2 L- _! ^: M
  132. Init_Palette& S$ m$ t" U# L3 t$ t3 n
  133. BIT PPU_STATUS
    8 c6 O7 l! k& {, f& z
  134. LDA #$3F7 ?" h( J9 T1 S- v  c; I
  135. STA PPU_ADDRESS
    4 q* `9 ^  t& [0 B2 h5 ~
  136. LDA #$00, c5 x) j+ B: L: W& U2 ~! ~
  137. STA PPU_ADDRESS
    6 R! p0 g0 [+ }# D. e3 Y( T- K" v4 t
  138. LDX #$00. J# Y- @0 j! ~( c4 o% ?/ I  Z3 Z- F$ |
  139. Init_Palette_Write
    ( U0 Y3 I' X# W) W5 V, t  V' L
  140. LDA Palette_Data,X
    0 ]0 L* u, ?, Z
  141. STA PPU_DATA+ }: r% V* W5 v$ p
  142. INX  V& w3 H7 ?. e7 C( S0 S' n+ o; ^
  143. CPX #$20  [2 x6 u7 @9 u* a3 _+ E
  144. BCC Init_Palette_Write
    % O3 _$ E" V0 m% U* `: c
  145. RTS3 a: y8 u6 L  F0 F7 R6 n+ G
  146. $ U5 L$ v0 Q1 N9 U: i1 X/ h) `
  147. ;==================================================4 O" x( K$ ^" _5 z, p
  148. ;设置命名表属性4 Z' }: ^" [' @" ]# g" N% @
  149. Init_NameTable_Attributes; ?1 w% F0 B, {3 @3 ?: J
  150. BIT PPU_STATUS
    ' k6 ]# P/ G! K+ U7 @, o
  151. LDA #$23
    & b8 I- ~1 q, I: y
  152. STA PPU_ADDRESS
    ' `- T( @$ g3 P& Q
  153. LDA #$C0
    ( L8 W0 |! x/ d& Y: N3 m! Q
  154. STA PPU_ADDRESS
    % [9 _7 N& d  o0 h2 s: \
  155. LDX #$00
    ; _. [$ F5 a8 F5 o+ c. L5 z
  156. Init_NameTable_Attributes_Write
    . _/ r% i4 z% j$ U; d, y
  157. LDA Attributes_Data,X
    ' |3 U: z) A4 a
  158. STA PPU_DATA
    " D/ A# I7 T/ W  [
  159. INX
    3 R0 t1 G; P/ p; V$ r
  160. CPX #$40* E( O& V, P; ~+ s  C) Q3 g
  161. BCC Init_NameTable_Attributes_Write
    7 K# S1 O5 _& g+ f) x# A& M
  162. RTS
    + T; {0 U5 _! o$ S

  163. & h5 V  S: J! X% _5 l! b5 m: ]. N
  164. ;==================================================
    ; G" o3 _, i! D
  165. ;初始化命名表文本% g: Y% \% T7 S
  166. Init_Name_Table_Text
    + i6 I7 Z, Y& }
  167. BIT PPU_STATUS0 ]7 d; E5 M0 V: U4 q6 |) r
  168. LDA #$201 p& \0 P/ W* V" a+ s
  169. STA PPU_ADDRESS' N" ?( F: N% c
  170. LDA #$00: m" x, a6 {8 z& m+ D
  171. STA PPU_ADDRESS
    1 [# J* A. I0 u+ m1 @9 b6 I; Q
  172. LDA #$006 }: q4 q$ w1 y6 s7 i" C% o
  173. STA FC_Data_Buf8 c3 u/ _3 y9 Y* o
  174. LDY #30
    * h/ e% v9 r3 ^( K
  175. Init_Name_Table_Text_Write
    8 O5 G& L; P. o9 H9 m* M. T+ l( v
  176. LDX #32: X% i8 s* t7 d# z# o9 d
  177. Init_Name_Table_Text_Write_Char
    , O- t& K5 m9 |( I
  178. LDA #'0'
    ( g5 n  _  Y5 Z" W$ U% e
  179. CLC
    ! C7 I$ d  U6 l; l% [, }
  180. ADC FC_Data_Buf4 U" y! S, o# H4 L4 N- o# ]
  181. STA PPU_DATA
    : S; {6 P/ x0 Q3 V. _2 S1 [
  182. DEX
    . n: ]- K, o8 h8 W2 u4 y* k
  183. LDA #$14
    ' I" M4 L% ?1 B! \( t) V% C
  184. STA PPU_DATA
    7 p( j# f; b) e. N7 |- B
  185. DEX
    ( F3 n, ?8 U9 O( r. |3 L
  186. BNE Init_Name_Table_Text_Write_Char) j, J6 }- Q- F/ |
  187. INC FC_Data_Buf
    6 n7 v& }3 C/ u0 @! n) a( h, t
  188. DEY
    : T) u) i. ]) n9 J! y' G. w" ?
  189. BNE Init_Name_Table_Text_Write
    ' O/ w$ i1 u7 `1 ]
  190. RTS
    ( J8 O1 D# K0 @
  191. 4 ]' j" L+ ]. I6 ^+ x
  192. ;==============================
    $ {3 G- h, S/ f, P
  193. Init_OAM_Ram;初始化精灵内存
    ' U/ X& G( D1 G* n$ ?8 r
  194. LDX #$000 I) ^7 Z2 o* i( z3 M, u' H# m
  195. LDA #$004 L0 l( t' H- v# {
  196. STA PPU_OAM_ADDR
    ; o' E3 B, F# y. l1 ^- |/ x
  197. LDA #$F8
    ) p1 V2 {5 L6 M6 P$ l
  198. Init_OAM_Ram_Write4 e, ~+ q& [: @5 ]4 D1 L
  199. STA PPU_OAM_DATA$ N$ u' L3 t+ |; r; N
  200. INX$ f/ l% l4 P/ f2 M* X3 E9 O" ~
  201. BNE Init_OAM_Ram_Write
    ; }, L# p5 t" C; Q# w. x
  202. RTS/ ]/ {4 j$ b% [2 p
  203. ; O2 P/ ^: H! y5 e
  204. GamepadProcess;手柄处理: O6 a3 p. ^( A$ A( T/ J
  205. JSR GamepadDatacan
    + |* ?  D$ m  `/ \0 a  `
  206. LDA <Gamepad_0_Value
    5 r! Y+ w1 P( B* F2 m
  207. STA <Gamepad_0_State5 U" q% A0 l" q3 j: v) G
  208. LDA <Gamepad_1_Value
    ; c! [( A0 z8 q+ n) S! K0 E
  209. STA <Gamepad_1_State+ L4 }) Y# G& S' e
  210. JSR GamepadDatacan
    . \3 U0 F/ U5 p
  211. LDX #$01
    2 B! `  h1 q& m8 M1 U
  212. GamepadMergeCheck;合并手柄输入检查- Y! a! X9 U6 X6 b6 ~
  213. LDA <Gamepad_0_Value,X- S5 P4 \7 m' C/ H6 S" d
  214. CMP <Gamepad_0_State,X
    , L1 c) d( p  S( J& s) B
  215. BEQ GamepadMergeInput
    " ^- s4 `5 V2 L9 ^- |/ F( P- ?
  216. LDA <Gamepad_Temp,X, g2 @. i- A' u, d- P1 b2 d; Z
  217. STA <Gamepad_0_Value,X# {+ I% e* M* C! h' t. n
  218. GamepadMergeInput;合并手柄输入
    6 n; z6 Z9 l/ O# q  z) A
  219. DEX
    8 w6 M; D' C! L- Q/ \1 a
  220. BPL GamepadMergeCheck( f, H  B* Q' B  U
  221. LDA <Gamepad_Merge0 ~0 f: R) X) V; Q4 m: I! Y4 n( J
  222. AND #GAMEPAD_MERGE_FLAG
    + ]/ ~" F# t; p. b8 J
  223. BNE GamepadStateProcess+ t: W% h8 a2 [, K
  224. LDA <Gamepad_0_Value1 H3 B1 Y$ K/ U9 l+ b2 m% }9 s7 M
  225. ORA <Gamepad_1_Value6 P3 ^$ K$ }9 y7 }1 f; K& u
  226. STA <Gamepad_0_Value
      u" _; w9 u& M2 D# ~, @
  227. GamepadStateProcess;手柄状态处理" I7 `- Z& h( n- Z
  228. LDX #$012 O3 B  s: p, Q4 _' r
  229. GamepadStateSave;手柄状态保存
    ; t9 t8 p% v8 ]2 _
  230. LDA <Gamepad_0_Value,X) d( l, t4 j1 B) {$ v$ l" }
  231. TAY
    " Z9 K- y4 `. r1 Z8 D
  232. EOR <Gamepad_Temp,X3 N8 g+ v% a( U( V5 J
  233. AND <Gamepad_0_Value,X
    + _' h0 t. H6 B# ^: P) T
  234. STA <Gamepad_Once,X
    9 x( P  |1 E2 ^4 y0 P! R
  235. STY <Gamepad_Keep,X, ~# G0 g# S# C, `- l
  236. STY <Gamepad_Temp,X
    6 y$ Y7 a9 @* e8 V- V6 A4 y4 m  N
  237. DEX( S9 j% s" C+ g0 x0 T9 `
  238. BPL GamepadStateSave! J+ P  V1 U0 M2 F( l! }
  239. RTS! }0 _8 ^6 x% z8 ?
  240. . h' S: w0 }8 I: Y* c% ^! q
  241. GamepadDatacan;手柄数据扫描
    * ]0 J( c7 _* G
  242. LDX #$01
    6 n1 A+ {* |) P. Y" |
  243. STX $4016
    8 {, f: e' L0 ]5 L& @+ Q% P
  244. DEX3 G  w0 L" v+ c% t6 C
  245. STX $4016/ y6 ~6 {9 q8 s: q
  246. LDY #$08% [; g4 |3 U2 w
  247. GamepadPortScan;手柄端口扫描! W% A9 C( k6 q3 }- C
  248. LDA $40165 P9 n3 |  F. f4 D6 L; H
  249. STA <Gamepad_Port_Value
    ' H0 D0 Z  f. o
  250. LSR A
    . g, ^1 I- R8 ?: r
  251. ORA <Gamepad_Port_Value
    # d8 q7 O! ]3 m2 s7 s& z
  252. LSR A
    0 j  u: C3 ?# _+ ?7 p/ s# D: Q
  253. ROL <Gamepad_0_Value# v" T- Y) _6 w, }" ]* r1 H$ G- [
  254. LDA $4017! t0 D4 s1 W+ W5 K  j% b
  255. STA <Gamepad_Port_Value4 \$ S- O! j( k0 d7 }1 s3 q
  256. LSR A2 |2 C, S* g5 U; z
  257. ORA <Gamepad_Port_Value
      w4 T1 y5 }3 ~6 b9 y0 D4 V% \% v
  258. LSR A
    ' T" l. a+ l. B- i' c
  259. ROL <Gamepad_1_Value  x' f6 B/ j4 Z+ o: j7 j8 {+ W, {
  260. DEY  d+ t9 e/ r$ D4 B+ |
  261. BNE GamepadPortScan
    0 e6 H$ z& y& \- ]5 W0 z7 m8 N/ z# ?
  262. RTS2 p- d0 K3 p2 V) [4 a" j% `; f
  263. 6 i* X: q) @7 b; r$ n
  264. ;==================================================: r/ }$ h8 v: O2 a0 s2 S- ?
  265. ;PPU处理7 V6 C# I7 X0 K+ l+ s: L& y! i7 V' F
  266. PPU_Process9 S# D8 ^2 K& [5 D9 c
  267. LDA #$000 `$ a* _9 O! ^( n$ J
  268. STA PPU_MASK
    1 g) i: W% g9 K

  269. 6 `8 e% d0 q4 \) B
  270. BIT PPU_STATUS
    " o9 K- w$ x' D  i
  271. LDA #$20* i( _( v8 Q6 F) {& L% S* Y0 j
  272. STA PPU_ADDRESS. Z# J" A+ }' A' _$ |) L+ z
  273. LDA #$00$ S9 L) D0 T  Y0 B+ F# f  n
  274. STA PPU_ADDRESS$ R% q2 v9 G9 R( E/ r
  275. , ?1 p1 {! |/ w/ U; ]
  276. STA PPU_SCROLL* F7 q8 N7 g9 Y
  277. STA PPU_SCROLL: y1 S0 W& o$ @5 \' l% ~5 e1 F
  278. : r" E/ q" j1 s# m0 m  ~2 P
  279. LDA PPU_Msak_Buf
    8 s) R; i4 ^- J5 M. i
  280. STA PPU_MASK, X" B4 r- S& i5 N8 |" }$ f
  281. / T1 n' U0 O( P2 A: r
  282. RTS& N) ]$ j; p. a5 K* w

  283. $ ?5 x8 h( a$ ?; i% @" N
  284. ;==============================
    * m$ O) j1 p$ z' G6 I$ F& j; Y
  285. Time_For_Vblank;延时等待
    + \9 A' C2 }5 e) b
  286. LDA PPU_STATUS) V+ Q; H% \& |0 c; n4 J. \5 }
  287. BPL Time_For_Vblank  [/ {% U1 ^1 C1 N- [* P
  288. RTS6 t3 F2 U2 f! q; X8 P
  289. : Z3 {$ b7 D" X% ~
  290. ;==============================: L9 h% j* r% h9 s1 m
  291. ;初始化MAPPER19
    1 Y! w+ ?1 p2 Z- o- z! f) I' x
  292. Init_Mapper19
    1 ^* p8 b+ W- k$ Z' f& ?0 s/ Z
  293. LDA #$002 P* M: n7 R) [! z* H* y) D
  294. STA M19_CHR_0000
    + ~; s; s# |) w8 `, A; [  y  x
  295. LDA #$01
    1 `3 [' J7 B1 X' g" Y5 z
  296. STA M19_CHR_0400* Z8 Y1 w8 V7 U* T
  297. LDA #$02& C$ X% M. n) [5 F' g2 \3 d3 a
  298. STA M19_CHR_08009 E  {3 A/ l, B( U. U& j& E
  299. LDA #$03. c% G9 o# h6 ?9 R, w7 n2 @+ k4 ?
  300. STA M19_CHR_0C00
    3 i0 m2 E% n& h% D5 ~
  301. LDA #$049 n) b, P. o  c7 q. q$ H+ c, W' _! f
  302. STA M19_CHR_1000, o6 |5 x8 O+ i7 m1 ^. q5 S
  303. LDA #$058 {# u/ R+ a. G3 A! a1 S+ D
  304. STA M19_CHR_1400! x0 Q4 U2 z. r2 l3 [1 [, B
  305. LDA #$062 V4 Q# B- }" Q+ a* F
  306. STA M19_CHR_18006 M0 j" B. H+ K8 I
  307. LDA #$07
    & _0 U  ~  s9 P9 S0 Z
  308. STA M19_CHR_1C00. f0 O$ g' D0 f$ m) v$ L# I
  309. . ~# ?: k+ r( D6 S5 g7 H
  310. ;禁用IRQ8 `. D& R' p0 X' c* t  j
  311. LDA M19_IRQ_COUNT_H1 i& i5 ^; ]3 k, l. Z7 H
  312. AND #$7F$ I) w$ y* t9 W3 q, e- _  d
  313. STA M19_IRQ_COUNT_H7 |5 c& g+ n2 I  y* G

  314. ( G' V. b: K9 @4 j. X, r  n. D6 l
  315. ;命名表! N$ r  D4 F* n; {
  316. LDA #$E05 x" N' F% }2 K; {8 ~, g! \' \
  317. STA M19_NT_2000
    $ ?0 ]. S3 s6 C6 C/ L  j0 `# B/ p
  318. STA M19_NT_2400
    , j3 e% P% c2 U0 l1 z# f6 H# E

  319. 2 i$ R! C1 `# z9 h
  320. ;命名表
    8 H+ ]) m8 Q, e" q2 c" J0 _
  321. LDA #$E1
    3 N. b. D" p8 M0 \& Q( U6 C
  322. STA M19_NT_2800; d5 m2 S8 p4 }( Y7 |! w" J; P1 s& ^
  323. STA M19_NT_2C00" U. `$ ^4 C, }1 _2 B
  324.   X) q3 X; @) {9 {# O; m8 v
  325. RTS
    ! g2 [  z0 t- D6 y! U* I
  326. ; i2 C8 W, i% l" f0 ^& V0 m
  327. ;==================================================# e) e0 }+ P0 S# {0 p
  328. ;重置中断处理
    % A9 s$ B2 k1 K0 U/ t# Z
  329. ResetProgram
    2 }0 G8 z, w# ^" j
  330. SEI9 M% E) b0 \! e; J" Q+ O/ r7 D
  331. CLD
    ' G; g6 [2 I/ L$ Y2 |. Y! J, Y  M
  332. LDA #$00$ I" Y2 U& H! x
  333. STA PPU_CTRL
    ) t) i, C$ r- J4 f, N* n/ d$ o+ l' |
  334. STA PPU_MASK
    2 n! K( Y7 `$ y# ]( `6 t$ a4 [+ x
  335. STA PPU_STATUS
    4 f8 N# t& E5 W% L+ G% e0 R
  336. STA JOY2_FRAME
    8 m3 h& J! A" D6 W# @7 B
  337. STA APU_STATUS
    8 J+ j8 u8 o0 \; o' D4 i3 ]* y
  338. 9 b# p: G6 v* `# W
  339. LDA #$C00 e4 W3 |: n$ Z
  340. STA JOY2_FRAME
    0 ^' J* e& e6 x" c0 R

  341. + E4 C& L& y0 C, d
  342. ;等待vblank4 y2 C( \5 M) J  w
  343. LDX #$023 q  T9 ]$ N9 T! @+ L( |
  344. Vblank_Wait_1( Q  \& ^6 O0 y# s9 C! \: F( a! k4 ?4 \
  345. BIT PPU_STATUS
    1 L+ x0 J9 s4 Z8 T* I! r
  346. BPL Vblank_Wait_1) Z, a. B2 e5 B* H/ H' X
  347. Vblank_Wait_2
    & {: S" [8 s8 _: d2 m
  348. BIT PPU_STATUS
    , v) E" l( P( z7 ^
  349. BMI Vblank_Wait_2
    0 W& `5 f4 ~9 I; R
  350. DEX
    " A8 V, k3 C7 D3 T& `! ]& M# F
  351. BNE Vblank_Wait_1$ |1 e$ ?! L' t) T/ s5 _& q
  352. 5 A' _! T! g, F4 Y. R  t- d9 N
  353. LDX #$FF0 J8 C0 v$ ]0 h
  354. TXS
    ) [) M+ ?  _2 e' v

  355. $ b7 _4 ~- E) W3 o, l* }
  356. ;初始化MAPPER193 s7 F& v5 I3 ^9 F, W+ K* ?' O4 l
  357. JSR Init_Mapper19
    + l5 a2 ~( i  Z

  358. - P4 e3 v) B& R) w3 a4 _# `- O
  359. ;==============================' P8 x7 m, B1 C6 M8 W, e
  360. ;RAM初始化
    : h3 V7 z- h  N! N
  361. Nes_Ram_Init5 q# X3 x- _# Y" h/ y& I2 k
  362. LDY #$00. |7 l, J$ d' w2 ]* b3 R
  363. LDX #$08
    ( A: C' B' d/ c2 A) K* B) s
  364. LDA #$00
    . u2 p! Z5 t  c! b
  365. STA <$00( l- N6 v+ l  f  _( |! B1 x& j
  366. STA <$018 o- P6 b  w& k" g  c% M0 `# r
  367. Nes_Ram_Init_Write
    6 M6 A7 W& P7 x# a2 x* f
  368. STA [$00],Y. P3 p4 Z% G  ]; Q6 s# w: `' J
  369. INY
    0 s; R: T' T9 B/ p* B6 `, A% X
  370. BNE Nes_Ram_Init_Write: {& B7 D/ T( U# @! a. ^3 @6 q
  371. INC <$01
    + ~; V4 k( E" c: n
  372. DEX
    + \) Q+ v' z6 R
  373. BNE Nes_Ram_Init_Write! h( Y! J7 q4 {; x

  374. - T) M2 }: C4 [) W
  375. ;初始化命名表
    / W: A/ N4 ?9 }5 g9 a! m% o
  376. JSR Init_Name_Table$ k! N3 |5 j* y3 r/ r( ~. h
  377. . l' D0 t" I+ z, ~" a6 o5 Z
  378. ;初始化调色板
    , M8 q, P7 J; _2 K6 i3 X0 v7 H
  379. JSR Init_Palette
    ' ^4 B; n: k$ t' u( ?$ p7 M, y% o! D
  380. . P2 \+ v& Y) n) I0 n- H' B, q9 s9 P/ B
  381. ;初始化命名表属性' `$ n4 D$ \  v/ D2 o/ y" Q
  382. JSR Init_NameTable_Attributes
    4 O* }, F; \& r, M( }

  383. 4 s8 q% c6 F2 ^, k5 Z: I
  384. ;初始化精灵内存
    ( H3 p" S6 H0 U$ O2 H  D
  385. JSR Init_OAM_Ram$ K2 t6 [1 h1 n( b# v

  386. ) p3 [$ W/ c+ R0 e5 O* ^8 \) ?, J% U- T
  387. ;在屏幕上写点东西) _5 S) m  f0 c. r. }0 K8 t" w2 K
  388. JSR Init_Name_Table_Text/ g$ Z0 `: k; q) D
  389. $ l& G0 j( O! i: X  ]9 a, `( ]
  390. JSR Time_For_Vblank
    ' o3 i1 t5 ?4 O2 A9 r3 y
  391. ;开启PPU控制
    2 P$ V4 S. g( z( z4 r1 i9 h# T: T
  392. LDA #$A8
    7 O6 ^4 }1 v& N' G/ x+ j
  393. STA PPU_Ctrl_Buf
    6 e0 u% o/ A9 u% ~& k
  394. STA PPU_CTRL% j8 g* G% [0 z: K( G
  395. # ]4 \% v9 t- j& W
  396. ;开启PPU显示( M2 ], Y8 D8 i2 U
  397. LDA #$1E
    ( S9 b1 \1 U4 ^' I( U
  398. STA PPU_Msak_Buf3 [' q' k2 R4 u. }( \1 }

  399. ' c. O" {% M  a+ y3 l/ [5 W
  400. CLI* x( ^% h" \0 p0 d7 C0 F: x9 k
  401. JMP Loop
    % w& E6 H# G! E4 ^

  402. " t# F' t4 ?, ^$ {
  403. ;==============================; ]+ N) t. z' G, w
  404. ;死循环, 等待NMI中断4 r" j- m: ?. V- _. n6 J
  405. Loop' ?) h# e4 u7 m3 `$ u  i
  406. JMP Loop+ G  v( r: f( u; L2 R

  407. / F" U5 E# K; l! X+ Y8 ^4 y
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    ; {  D( i9 \+ }9 k/ Z' z) |6 f

  409. 3 z; l3 B% c& d' o4 X
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)% i7 q, ^0 g* Q7 X' c4 e# u9 e0 o, `
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103), f0 H+ w' a, V' ]! n2 L2 J. \
  412. ;==================================================* X( u& T* g( |" Q( D% D+ B
  413. ;NMI中断处理1 M& Z# i6 G1 B. W& S; L. ]& ?
  414. NmiProgram
    ! U! U  o% Q4 j6 b* j9 l
  415. PHA
    - z+ J7 ?, W7 z- Z+ J3 m
  416. TXA+ L0 Z8 ^1 X$ {* {$ D% t
  417. PHA: D# B5 f5 M+ [- K8 r
  418. TYA
    , D$ l; E/ F/ C- L' w: z' }4 n
  419. PHA" v5 B. ]! \) d7 a2 d

  420. , b6 W3 w* _) d
  421. BIT PPU_STATUS
    6 p: F2 D4 @  V2 [
  422. ) t6 E  ~  u8 o8 m. U; p
  423. LDA #$00
    . E, p- [$ ^6 q9 v; @7 B
  424. STA IRQ_Index% V$ n  \( m! B% [& z7 y; ~0 h5 |

  425. 0 c; C: z0 C7 }. D! K8 `% U
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    + b. l3 m/ m0 L0 Z% q- _
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)% Y8 C; n1 R$ f* R8 _2 a
  428. STA M19_IRQ_COUNT_L
    # A0 r8 ]9 @0 ^! o) H; j
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    & z5 H: v( L7 f  R
  430. ORA #$80! m' J! v0 T& |3 D8 `; M
  431. STA M19_IRQ_COUNT_H
    " o9 o) a5 O6 B' R" R+ a" e" L/ }
  432. CLI
    , q; \1 m! t; D6 s. Z$ p

  433. 6 D/ n; e6 ^, u% x1 Y' ]8 i
  434. ;关闭PPU控制, a8 e1 ?2 O2 z) ?6 A; O  X
  435. LDA #$009 X: G7 i2 E2 e3 L, K
  436. STA PPU_CTRL
    # V9 K- g1 L  k: E/ t
  437. 9 }+ t+ g  [4 E( p
  438. ;处理PPU( X4 x: d# T5 s  p& S4 _
  439. JSR PPU_Process' a& ^0 @$ ^1 \

  440. & z$ d* X. x/ [8 a
  441. ;开启PPU控制! J% M; S; ~* b
  442. LDA PPU_Ctrl_Buf
    3 L4 G7 T. e0 q
  443. STA PPU_CTRL
      T# ?* z& S. f$ a4 A! U- x5 ^

  444. ) u' l, c) J5 j
  445. ;手柄处理
    4 U: {; |$ t6 t- |
  446. JSR GamepadProcess
    5 c9 x  E& j5 x1 R, [+ A
  447. . H8 F6 ^0 ^# `2 ?6 }/ l2 n  n( }0 x
  448. LDA #$00. p: ^5 t' V0 G; y+ V1 a% s
  449. STA IRQ_Index
    7 S( ^, H7 n$ r6 x% Y' Q( X% n6 \

  450. ' L/ x# t: L$ H4 Z
  451. PLA  U& y+ n& u' @( a1 k! g1 s: i) G1 y
  452. TAY1 T( u! }0 |: P1 _
  453. PLA
    & f  g7 |; @! @
  454. TAX
    , i5 \2 S3 M, r
  455. PLA
    2 u! p6 T) C2 R  L# }  ]' ^
  456. RTI
    $ Q5 j  C; t8 f& l

  457. 8 I% v7 K/ z+ ]5 w- Y
  458. ;每行扫描线113.67! P8 b  O5 e- d" s5 p
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)1 y1 s  ], v1 @+ ]1 V- P
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    & S1 q2 @1 Q: F; B) K$ g
  461. ;==================================================/ ^3 q# x" e7 x  i
  462. ;IRQ中断处理
    ; Y4 U2 Y: B0 }2 P
  463. IrqProgram
    % a% ~4 F* K9 ?6 [& v7 {/ ^( x! @
  464. PHA1 W: O& j* l" z. Q. I
  465. TXA
    ( p5 I) ~2 b6 W) ?" D
  466. PHA
    - s- Y+ K1 Q* X. d4 E, n, d
  467. TYA
    : l# S: Z: w) B
  468. PHA
    2 a+ O/ Y( J. y$ B
  469. ' |1 ^+ a; n4 D6 A) a2 B
  470. ;16条扫描线后触发IRQ+ u" K, X/ y  P6 U* u( ]0 \
  471. LDA #LOW(BEGIN_LINE_CYCLES)3 x( A  h- \" b! D: H3 n2 e
  472. STA M19_IRQ_COUNT_L
    . T. f, @8 t% [* E1 @7 ~. k( b
  473. LDA #HIGH(BEGIN_LINE_CYCLES)4 o9 ^9 f! v7 ^& m
  474. ORA #$80* }. |& W/ t9 l+ J1 B5 @5 m
  475. STA M19_IRQ_COUNT_H
    9 Y; ?/ n) }0 E2 {+ b* B0 z' a
  476. ) Y7 u, t: ?& d# @* W0 q! q
  477. LDA <IRQ_Index
    0 t" x! O7 \1 x: d% Y
  478. BNE * + 4
    & N- Z( Z$ k1 F  o
  479. INC <PPU_Scroll_H' d0 g: w  D$ R9 d8 i# B
  480. 3 t: u) d' e; j( T
  481. ;设置屏幕滚动: e- Q* \4 w( A' G7 V
  482. LDA <IRQ_Index0 I: X5 L$ I" _+ S2 q5 V5 L- \
  483. AND #$01
    + z$ u: g  N7 [# ^3 K% m3 l1 c7 O
  484. BEQ Irq_Scroll_Right* M! j5 _2 Y* q9 f. D3 U
  485. ) I' w1 E: C4 d( e- ?* q
  486. Irq_Scroll_Left, }* y. X6 ~: `8 x
  487. BIT PPU_STATUS. K/ P3 \# Z: a9 O  q
  488. LDA <PPU_Scroll_H
    ! P9 R9 p* f! R3 E8 w' h
  489. STA PPU_SCROLL
    ; H9 G+ A: p4 R9 W/ s& y# o
  490. STA PPU_SCROLL
    " i4 t+ E* F4 ~* G) G  o) _) {! G
  491. JMP Irq_Scroll_Over
    # ^& {+ x0 N. Z( a* L

  492. 9 {* g  y6 x. Y, _, G; c( p
  493. Irq_Scroll_Right
    2 F5 {# y" }4 ]6 L( c& F6 m
  494. SEC7 n6 i; U" ]5 `! X7 }5 W
  495. SBC <PPU_Scroll_H
    ) k. k( Q; I* v* C, F
  496. STA PPU_SCROLL( @% r: ^. [* R: }/ @) q( l
  497. STA PPU_SCROLL" A+ r/ D5 v* v
  498. Irq_Scroll_Over
    ; b- p% y' u0 e' a4 @

  499. * Z% M. V1 N4 b7 ?  m
  500. INC <IRQ_Index
    9 @0 }5 c3 w& @- a$ U2 B& P
  501. , }3 w6 R* R# b9 n3 A
  502. LDA <IRQ_Index1 G. G. m* N2 C( K
  503. CMP #14
    5 G+ z! v, M9 K8 _% D+ D
  504. BCC * + 10
      F* T% t- n9 c9 o9 O4 G! n. |
  505. LDA #$008 y# d- B- d$ K. }/ ^! l0 z9 s1 o
  506. STA M19_IRQ_COUNT_L
    . l7 E" I& m! l, Z* {* [
  507. STA M19_IRQ_COUNT_H
    * i/ h1 D" P# s% h5 M3 z. y( b3 V; `% k6 C
  508. 6 v# f3 Y2 f9 U
  509. IrqProgramEnd
    ( H' s2 t# _- l
  510. PLA! X% U0 R+ j- ~
  511. TAY
    ) X9 L9 [# w! r) t" F6 x
  512. PLA0 g/ D/ S. H9 P: ?6 g+ I
  513. TAX
    : Y6 m! R5 M$ F3 s* m) ]8 c% k
  514. PLA" W+ b- b/ I% {* y. A5 [, c
  515. RTI
    , l  P# h9 _; i; x' b2 q+ K
  516. % d4 M4 n; V* S+ P
  517. ;==================================================% l3 l) S. c8 j
  518. ;中断表
    ) Q- p. H' H" m) ~1 i1 }5 h
  519. .ORG $FFFA
    ( Y5 }/ e  Z% p* D& p6 I
  520. .WORD NmiProgram
    " U+ H. P  f3 u+ {4 k. Z$ D
  521. .WORD ResetProgram
    7 U# R/ r' M+ m/ F9 L
  522. .WORD IrqProgram
复制代码

4 ^" E3 @& u/ c+ x2 w- ]

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-1-12 07:42 , Processed in 1.085937 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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