EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]7 M! }1 o2 `2 C4 @; Q% x1 u
  2. ;FlameCyclone 20230710
    , `0 d5 L7 S( N3 F. [6 g

  3. 6 [4 s* w9 U, b5 r2 U" ~0 [
  4. ;文件头
    ; y* ?7 ]  F( I7 |2 o
  5. ;======================================================================" h2 ?& W( j) F2 z4 v- F! C
  6. .INESPRG 4                                              ;16KB PRG 数量
    1 n" R% |3 l$ q8 P- T5 n
  7. .INESCHR 1                                               ;8KB CHR 数量
    ' c: V% _( d# c+ `* r) J* r) l1 u% a3 H
  8. .INESMAP 19                                                 ;mapper 19
    , q; i7 U5 R$ e3 M
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直/ k, y3 `0 ?% C3 N

  10. " _8 ]! {: o! E  [& K
  11. ;必要条件
    % q* [% |! ^3 j( z
  12. ;1.持有CHR ROM$ C# o2 z# q  x3 |" k$ d0 ]
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    & {) ?9 l- ?3 D6 l# w# x
  14. ;3.精灵内存(OAM)不为空
    ( S7 X. o8 \% k0 a1 y4 z) ?
  15. ( [. G; O0 J6 P8 P& I! C
  16. ;==================================================" O& U4 l+ c( G+ m" E- U
  17. ;NES端口常量
    ) b2 s' [9 h1 f8 M
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器" I1 y: t+ _# A5 c' m" f
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器8 Q* f, G. O2 `0 r7 n
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    " T4 e& K# j/ _. ~. r
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1( d' e. J$ ^& S" g0 f/ _# Y
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1) p1 h$ F. y5 x4 m7 h
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    * Y5 |7 h+ x) Q2 D! B; |
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    9 K8 }$ B3 o. J8 d% I  F9 R
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    9 B* \: o# i: z; g& C3 |
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    - q  M2 T( y6 c$ r) C; c( t! c
  27. APU_STATUS              =   $4015   ;声音通道切换
    ! D* q# C* q8 \9 u) Q
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    / [$ I0 k8 Y/ ]3 v" b# c. F8 `- v
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    - w2 F; J  F6 q1 p
  30. & g. [, m5 m9 k* B% m' p9 \
  31. ;==================================================
    " n0 I- |, C5 N( {1 ?- y- a. [
  32. ;MAPPER 19端口常量  C5 G4 m+ q# @5 Z! [
  33. M19_CHR_0000    =   $80007 J  D/ Q6 D# B+ `! ~' \- H
  34. M19_CHR_0400    =   $8800
    5 x3 I4 `3 \# W2 |% O' R; U
  35. M19_CHR_0800    =   $9000; ?. u' b% `) w0 Y
  36. M19_CHR_0C00    =   $9800
    + q8 O, h* Y! m# G2 I' t: k
  37. M19_CHR_1000    =   $A000; k( l- r8 l. O8 q/ [3 B
  38. M19_CHR_1400    =   $A800+ W0 M, i6 u$ F2 r
  39. M19_CHR_1800    =   $B000
      `; P8 _* {5 u2 }# a9 T% d3 E
  40. M19_CHR_1C00    =   $B800
    " c3 q1 S# S5 F$ t
  41. M19_NT_2000     =   $C0003 |& \* S  @5 P
  42. M19_NT_2400     =   $C800: T3 c# W6 C' k) F
  43. M19_NT_2800     =   $D000+ n( x. D% Y, L8 X& `* p
  44. M19_NT_2C00     =   $D800/ e5 F; a- N) T3 T. I$ @
  45. M19_PRG_8000    =   $E0004 K0 L  n! @: K3 V" n' y! k/ V2 ]
  46. M19_PRG_A000    =   $E800
    ' m' a4 D2 C8 L
  47. M19_PRG_C000    =   $F000
    : J* ^# |! D9 d- t/ N
  48. M19_IRQ_COUNT_L =   $5000
    9 Y. I/ S! g& x# G% Y1 Y( e8 E
  49. M19_IRQ_COUNT_H =   $5800
    & o% Y1 v  S( `) f

  50. # A$ m1 w1 ^( j* Q. ^& X
  51. ;==================================================7 a. }* X& B; D+ ]4 m
  52. ;程序块配置
    + y& `/ B$ ?& }( ]$ E
  53. BANK_DATA_MASK          = $074 \- a: {% ?* {* }, C$ z
  54. ;--------------------------------------------------- d: D1 R7 b& M8 L: Y2 Z+ z5 B) Y
  55. RESET_BANK              = $07
    . B" ]+ i( U# Z( v) e8 Y; m$ j
  56. RESET_ADDR              = $FC001 `: L1 c9 o" z9 s+ Z
  57. ! k4 R* R6 P8 c. X0 e
  58. ;==================================================! Y% b/ G( W2 ]2 R! p1 ~1 C% d
  59. ;图像块配置
    $ `8 V. b% j' {  Y& B
  60. CHR_DATA_BANK           = $08
    5 m9 T4 k+ J' J" _% N" X5 X
  61. 5 f/ T0 _- y. T0 s" [
  62. ;==================================================  K& h7 h$ E0 x' E# _4 h6 m- k
  63. ;零页内存地址配置
    5 X' Z# a7 [& ]
  64. Use_Ram_Addr            = $80
    6 e6 b! j  z; L& o: _1 ]
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    6 A; m1 z6 ~3 _7 ^5 D: h5 w
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $012 z( r5 @4 Q# U5 x0 m6 Q* R
  67. PPU_Scroll_H            = PPU_Msak_Buf + $013 B# y6 Q: H5 D% T" P6 g
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    1 M. s- {" w; A- c( ~# V
  69. FC_Data_L               = PPU_Scroll_V + $01
      Z7 i  d1 p6 N- q9 H3 \
  70. FC_Data_H               = FC_Data_L + $01
    * s4 I, L) W6 Z* j- s5 Y
  71. FC_Data_Buf             = FC_Data_H + $016 G1 ~# K6 ~2 {$ G* T/ a
  72. ;==================================================
    " X; p7 @* Y7 }  U0 v3 X
  73. " g( U8 u# Z: R' f! c
  74. GAMEPAD_MERGE_FLAG = $04
    % B) N( w7 E* N* P+ o
  75. / U7 {# s! N5 L: Q, t2 k
  76. Gamepad_Keep            =       FC_Data_Buf + 1' S( h8 n& m: J
  77. Gamepad_Once            =       Gamepad_Keep + 2
    ' V/ O2 H! g( c
  78. Gamepad_Temp            =       Gamepad_Once + 2- {/ K, x2 c5 J+ f/ j. A! D
  79.                                 ! C# b0 z1 r& f5 G' d% K% n; E) M
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    * ]4 |/ r0 ?+ Z, I
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ; b% W6 J( E; i) `2 D8 M0 S6 l, [
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    # L" l( @7 C1 o9 h! {! q- o" e# l
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    8 x( A6 y% G. S. w" B" L8 R
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    6 B! b4 _0 {! t( t+ c
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    5 o. u: x) x, c4 ^& ]  e, [4 ]" F& i
  86. ( g/ n2 _: n6 w2 @
  87. ;==================================================
    / Q0 I/ Y& m3 c) e7 ~, A/ M0 j
  88. IRQ_Index               =       Gamepad_Merge + $014 [( E; |, k) l, d1 ^
  89. ;==================================================. j! [: S4 u/ Z9 O' u
  90. , k3 H+ B9 x0 e' u  C
  91. ;CHR图形数据  x" k: \# d0 l9 ?& a* H8 d( J
  92. ;==================================================
    % `9 Z7 A3 v5 o3 Z9 \3 z$ Y
  93. .BANK CHR_DATA_BANK) l& a9 B2 {& T& ]. R: v! f8 i) s
  94. .INCBIN "chr_bank/chr_data.chr"
    8 r1 ~/ I7 l3 ]7 o# U; I* }* ~/ z

  95. 2 |* Y# t7 v3 \& s  |) Y3 ^
  96. .BANK RESET_BANK & BANK_DATA_MASK
    9 y1 N5 |: K! d' ~
  97. .ORG RESET_ADDR' A! B1 [$ e* h0 x" T2 p
  98. % w- R! B4 t$ N1 [
  99. ;--------------------------------------------------) g; _0 p& j. V# H6 X. e2 V
  100. Attributes_Data# S8 @9 `. p+ B5 R  `- {7 y/ E
  101. ;命名表属性
    * T3 f: R/ M  E
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00/ f- i1 O/ p! i1 n$ ?" Z
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    % y. W9 o; B+ s2 Y4 ^& r1 u% P
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA; c7 \& k3 M, }7 J4 N. ?$ t
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    * e8 v" M# Y* m7 @3 y% v# u+ [
  106. ;--------------------------------------------------
    , s8 G1 Y; `& J& c9 M1 Y  K+ X: n
  107. ;调色板数据( ?4 W  N/ {; |; ~4 W
  108. Palette_Data9 j' y) Z- `6 k& w) {" A0 D
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    . m4 C. S4 R! g
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F' U3 B3 _. h/ i- f9 D( E/ O4 R

  111. 9 H8 C$ p. K7 k4 c
  112. ;==================================================# m3 F2 }3 I3 [* X: C2 f
  113. ;命名表初始化0 W; }  i7 e  E# _2 K9 ?% N3 p
  114. Init_Name_Table" h! b2 M: w6 Q) J9 @
  115. LDA #$20
    ) O! g. C$ z1 s2 n4 |
  116. STA PPU_ADDRESS5 o, ~, B) B" K  U( \+ ]! y9 f
  117. LDA #$00
    * M0 O' y) O8 ~: `7 |& g  d+ M# E
  118. STA PPU_ADDRESS0 q# ?- l  W% `) }- O3 m
  119. LDA #$00. r' s# J, R" s4 b% Y
  120. LDY #$00
    + I% ^% |: }2 |3 C( i
  121. LDX #$10/ n5 }$ C- Z8 r
  122. Init_Name_Table_Write
    ( l! L* `, x* y% ~8 h6 w: z
  123. STA PPU_DATA
    % k5 c) d. z  ^; Z; T
  124. INY
    ' C' M% l7 t& V
  125. BNE Init_Name_Table_Write& x+ E. k6 ^7 R6 S; S+ h3 T
  126. DEX2 w6 W- V( y% p  q8 [/ J( r
  127. BNE Init_Name_Table_Write0 r! F  E6 }+ ?- e( O8 H
  128. RTS
    / o# D1 R  T7 G
  129. ; {4 Y9 T6 c& d3 b/ i4 _2 W
  130. ;==================================================' B: U4 F" D" v8 E; `
  131. ;调色板初始化
    & S+ l8 A) A) R8 b, p
  132. Init_Palette5 V. F7 L- Z9 {9 ?# c1 P
  133. BIT PPU_STATUS9 c$ C. \" W0 r& O1 c
  134. LDA #$3F
    + ^- P3 \( n$ t: A! N) ~
  135. STA PPU_ADDRESS( e# x- V# g: h9 Z; C- D) H, K& P
  136. LDA #$00" o$ ?( \. R. h4 X; c/ F% p
  137. STA PPU_ADDRESS- R& f+ \) w0 G- I# M) U* _
  138. LDX #$00
    $ Z6 t2 U' J# c# `9 W9 k
  139. Init_Palette_Write
    & \1 z: A- s; p
  140. LDA Palette_Data,X8 K# @, M1 Q. r
  141. STA PPU_DATA  C! @9 U" A, F! O# ]2 g# I
  142. INX) r/ f  K3 e* }- ^+ M' K& P7 _
  143. CPX #$20
    + A5 z$ G( D' ]+ i! l
  144. BCC Init_Palette_Write  g  J2 X: X6 X% `
  145. RTS& K$ V! n: o8 i, ^1 z- c
  146. 3 ^- [$ S, w/ x3 a
  147. ;==================================================
    ' m* z; Q- v# o
  148. ;设置命名表属性
    : T' Y4 `" x2 ~6 o2 I
  149. Init_NameTable_Attributes
    7 W+ Q) P# P& b( O& x/ l
  150. BIT PPU_STATUS
      U3 B" E4 h" G/ q$ |+ x
  151. LDA #$23# Y( Y+ m2 U9 T" v! K
  152. STA PPU_ADDRESS
    4 j. s9 e. z6 Q/ J! t
  153. LDA #$C0/ W& R5 |* k1 D" T( o, m9 J
  154. STA PPU_ADDRESS
    5 z5 r  b" c$ N
  155. LDX #$00  D, y2 e4 |% _1 D' O* p! c
  156. Init_NameTable_Attributes_Write1 {/ \# @3 o$ X+ n
  157. LDA Attributes_Data,X
    1 V" R8 B7 ~+ Q1 n! j- h- M' w
  158. STA PPU_DATA$ u1 n6 S+ f6 H0 d) T. c
  159. INX
    8 _( U) @, x: B. t. o- v0 Z0 F
  160. CPX #$40
    - [9 I7 y  O% V+ j6 h0 U
  161. BCC Init_NameTable_Attributes_Write
    / [: ?! ]: @' u1 ]* G
  162. RTS
    " D) z  X1 F6 g: g. z% {

  163. ; ]$ D0 W- V, {' X7 X* D: C; q0 d6 l
  164. ;==================================================7 _+ x7 B6 f) K" b* i' f' n3 X
  165. ;初始化命名表文本
    - T9 h1 Y% [% s
  166. Init_Name_Table_Text
    $ P( f; w& S9 Q. y9 R! l9 {
  167. BIT PPU_STATUS
    , U& C$ L7 ^9 b- X; U
  168. LDA #$20, H% h1 X$ q8 m4 o+ B& K
  169. STA PPU_ADDRESS
    4 Z7 l* I0 f. k3 C
  170. LDA #$00
    4 H4 @4 g' R' X1 |) M4 D0 l6 A' F. Z; j
  171. STA PPU_ADDRESS% D8 ^9 |" j4 [3 I  l8 h! |
  172. LDA #$00
    7 H% l, v- c3 j
  173. STA FC_Data_Buf4 z* @7 J; \5 o4 L- \, X. v1 Y
  174. LDY #30
    * }& Y6 }: Q7 X! x) Z
  175. Init_Name_Table_Text_Write
    ' _2 |0 i6 s8 O+ \
  176. LDX #32
    # f- A9 m" I- A
  177. Init_Name_Table_Text_Write_Char2 W: x! s5 e  e6 B2 ~& u* @1 x
  178. LDA #'0'6 q: ]9 d2 ], n8 [& \% ~; z* [
  179. CLC
    8 d4 y/ k) V. R9 ?# J& ]2 {2 q9 i
  180. ADC FC_Data_Buf
    + z. _" k, L* ^) E( h9 C
  181. STA PPU_DATA! l# G$ r+ s& h& x% y
  182. DEX" B3 x' Z; F* A# Y/ q/ [) v" j! c9 y
  183. LDA #$14
    & ~# A; [8 y& ^: C
  184. STA PPU_DATA7 @2 E9 U. f! l& z
  185. DEX
      i7 v* T7 C# }/ |
  186. BNE Init_Name_Table_Text_Write_Char1 `% f. M0 H' p' O2 K" M# f; q
  187. INC FC_Data_Buf
    ; Z" b0 f0 [7 t+ R  A) N0 D
  188. DEY
    + F$ f7 Q8 G2 o$ t4 q
  189. BNE Init_Name_Table_Text_Write
    " Y9 b+ f/ l2 h# J  \$ @! v
  190. RTS& b+ i1 s2 n. s' _$ L$ e8 D

  191. 6 q+ w8 ^3 ]( H( O5 B
  192. ;==============================* ^5 M6 [, ~: R, w9 I  J9 I
  193. Init_OAM_Ram;初始化精灵内存8 V8 v( Q( J: ~/ B  M. y5 P% g5 d
  194. LDX #$00
    / d+ M6 x2 c  f( ^' F1 I
  195. LDA #$00* p, ?4 i6 X) c  x
  196. STA PPU_OAM_ADDR8 y' n  U- f. n5 q6 L, `1 n8 d
  197. LDA #$F8
    4 c! d2 @4 p& _: O
  198. Init_OAM_Ram_Write' T/ E9 h  {" q" x) B% d
  199. STA PPU_OAM_DATA; k. e* D8 h$ Q" w- g" a' z9 Y
  200. INX+ ^! j" f; d8 e
  201. BNE Init_OAM_Ram_Write
    , J: v. A0 _1 h
  202. RTS" _1 L" @; O$ _' h# [

  203.   c! ^: R  D0 o8 e
  204. GamepadProcess;手柄处理5 I0 S! s) G* ~; _+ @6 L& w
  205. JSR GamepadDatacan& c4 Z. [2 r" S
  206. LDA <Gamepad_0_Value
    9 A# p1 h0 F+ _9 q; N* o
  207. STA <Gamepad_0_State5 @5 d6 R  A2 }# X0 e% K, o/ \
  208. LDA <Gamepad_1_Value% P9 v% a% [# h- S1 F
  209. STA <Gamepad_1_State
    + \5 X! ~9 Z* U. k/ z: T
  210. JSR GamepadDatacan  A! n1 t8 I$ K  Z) O  \
  211. LDX #$01
    9 S) e% O/ C& o
  212. GamepadMergeCheck;合并手柄输入检查; X( T% F' @# J- y1 a7 M( ]) K1 v
  213. LDA <Gamepad_0_Value,X, f6 U: X; Y) m) }4 o6 i
  214. CMP <Gamepad_0_State,X" M; ?! a6 p4 G% U3 Y" J- x) U# g9 g
  215. BEQ GamepadMergeInput, y  }; U4 W" t0 t( p8 ?# N
  216. LDA <Gamepad_Temp,X
    % G# D- I+ Y5 h( V5 F' i
  217. STA <Gamepad_0_Value,X% P+ z2 b3 }4 }  [
  218. GamepadMergeInput;合并手柄输入% j5 `% h: y) L! N9 w2 K4 w+ z
  219. DEX2 |& S7 M+ r- o0 k) B1 l! f2 M' y
  220. BPL GamepadMergeCheck( b+ \! m2 [1 q
  221. LDA <Gamepad_Merge
    2 ~+ z' ^6 X% i( f9 o( j- s' D
  222. AND #GAMEPAD_MERGE_FLAG
    3 ~( M% T. e2 C* w! a1 |; R
  223. BNE GamepadStateProcess
    - ]3 d4 Z) \9 V' t" N: t) G, k
  224. LDA <Gamepad_0_Value
    . }2 ?2 l# L8 `& b
  225. ORA <Gamepad_1_Value% Z+ Z$ V& u/ B/ O8 G& M/ n' h
  226. STA <Gamepad_0_Value  \% }# {2 V4 Y" {6 R' ^: i
  227. GamepadStateProcess;手柄状态处理
    * D. l, J1 I5 H$ X
  228. LDX #$01
    / |- p3 e! h0 V; r( I- @2 P5 r+ S
  229. GamepadStateSave;手柄状态保存1 ]6 e5 a$ u- e4 x) u" t
  230. LDA <Gamepad_0_Value,X7 t  v+ h; |2 r+ r+ w, K" J
  231. TAY
    & f, [4 @+ z. D
  232. EOR <Gamepad_Temp,X
    , ^  ^; n' J6 M
  233. AND <Gamepad_0_Value,X
    6 X5 K+ j4 L& u% b% T
  234. STA <Gamepad_Once,X
    2 P6 F/ b9 U2 A% m/ S, `& a) V7 P
  235. STY <Gamepad_Keep,X6 P& n6 F9 b# q, J) n0 d
  236. STY <Gamepad_Temp,X
    , e. h4 d% m* n. @
  237. DEX5 C* \& v; Z: s" j, K& c
  238. BPL GamepadStateSave) c  ?- }4 {+ p
  239. RTS
    ) y3 Q+ ^# z1 W

  240. 5 c2 L5 G2 Q( M) ^. X
  241. GamepadDatacan;手柄数据扫描: v# N6 w; F) y) ~3 Q
  242. LDX #$01
    ' Q0 |$ W+ \5 s$ m: o; ^
  243. STX $4016
    1 N/ P4 j/ |4 b5 H- g
  244. DEX% T0 D% ~4 b3 Y+ X* j7 l; L
  245. STX $4016
    1 @& `* n+ t) A
  246. LDY #$08
    % u( }# G2 T2 t- _& o. l% B% O/ ?
  247. GamepadPortScan;手柄端口扫描
    ) k4 [) o( e9 m  g$ d1 D
  248. LDA $4016
    & a- K; p" n1 T( t& ^  d* r
  249. STA <Gamepad_Port_Value/ m  ~' L% l1 e1 R% ^
  250. LSR A9 K( K+ P9 r& l, @
  251. ORA <Gamepad_Port_Value
    . t9 s1 w2 e. C9 j6 U
  252. LSR A  K, ^( `. o! Z  t9 I# {& V
  253. ROL <Gamepad_0_Value" o8 p8 {% C: W! A+ e+ Q* M. u, ?! I
  254. LDA $4017
    : S5 S" Q6 e( i  j
  255. STA <Gamepad_Port_Value9 I8 c7 Y6 z" D. H5 u0 u
  256. LSR A
    - f0 G1 D  ^5 A0 P6 P
  257. ORA <Gamepad_Port_Value$ {5 \( s- P0 ^
  258. LSR A
    9 u5 z9 C) u$ Q1 H- I. w
  259. ROL <Gamepad_1_Value
    . a) [, k. C( ~$ [
  260. DEY
    , y1 X  \. {# R% r" L7 n
  261. BNE GamepadPortScan. Q* t, \7 F8 \- x% r  \6 w- T
  262. RTS% n9 k5 W: {2 |$ k

  263. % v8 ]$ u2 Y, H3 x6 J
  264. ;==================================================- E. ~% H9 n9 y! U9 m& g) ^
  265. ;PPU处理, V" n% u4 m2 T+ |4 ~+ x( u& z) k1 R
  266. PPU_Process
      b3 s/ @: {. \6 E
  267. LDA #$00
    5 T" Z. K+ w  f6 q& y
  268. STA PPU_MASK9 {1 q$ N" ^( c+ z* e& d9 J

  269. 0 ~, x! \& F0 r+ Z
  270. BIT PPU_STATUS
    + [$ w" A9 H8 b; A8 p9 \
  271. LDA #$206 k" V5 e2 |8 a) L
  272. STA PPU_ADDRESS
    ' [. J+ i7 B0 V4 D4 O7 u" R; L
  273. LDA #$005 e, N. N: z% h# l; d2 e
  274. STA PPU_ADDRESS' q4 y# u( S9 Z
  275. ) w' P9 J2 v( z2 T( w. U. H1 c
  276. STA PPU_SCROLL) b3 U$ n# D1 \4 B" b# L
  277. STA PPU_SCROLL
    ! O# e% E/ m9 f, B

  278. % q0 e( K* N/ }/ ]1 a! ^  ~4 f- T8 q4 R
  279. LDA PPU_Msak_Buf4 t# U- ]9 y! U# K; c4 g6 ~
  280. STA PPU_MASK
    * E; H" w; Z, \

  281. 3 p9 ?$ d+ x1 [
  282. RTS
    0 Z. n8 F: A* ^- l. a3 ]
  283. ' K  S% I- F% T0 i- P& y
  284. ;==============================
    5 m% J1 i! \3 F( o
  285. Time_For_Vblank;延时等待& L! W# D: y  b: |1 b. W/ v% J1 z% Z
  286. LDA PPU_STATUS
    ' @8 x) ~* i9 f6 p9 f7 s
  287. BPL Time_For_Vblank$ X7 {/ S$ b3 h  f5 o& \/ H
  288. RTS; @* v/ C/ z9 X& b- h( E

  289. - C7 S' E3 _( q
  290. ;==============================9 R* ~8 w6 T/ H, V7 L# p
  291. ;初始化MAPPER19
    # o0 e0 R# P+ ~4 `5 e) ^
  292. Init_Mapper19: |( s$ c( }# ~3 {* L
  293. LDA #$00
    ) a' c: n7 @5 c
  294. STA M19_CHR_0000! x' |3 B4 Q3 A) e  \5 ^3 d; r
  295. LDA #$01
    . A1 b5 \! ^& k1 T; H
  296. STA M19_CHR_0400
    2 [+ A, u" j7 \% W% W6 A: G0 ~
  297. LDA #$021 E' |8 [5 Y" d& \4 H0 ^
  298. STA M19_CHR_0800
    ) i5 `- x; D2 @/ ?0 {* @% n% d+ i
  299. LDA #$03
    ; u0 n; D( C3 m# o& k8 w* X
  300. STA M19_CHR_0C00  Z1 k$ N$ w  R; \# o* B
  301. LDA #$04
    - _" q% G& L  T$ L
  302. STA M19_CHR_1000. m1 y0 p' H7 |& y
  303. LDA #$05
    4 O7 j" m; V! h' m! G( ^! ~
  304. STA M19_CHR_1400  c4 I& D/ |! X
  305. LDA #$06) H2 u9 f7 M# i- K
  306. STA M19_CHR_1800
    ' [- Q8 J+ p% y5 U* O8 X
  307. LDA #$07
    & o) ^* z0 B6 `
  308. STA M19_CHR_1C00, a! M( A( n" v7 L
  309. / e. S) R( K/ o  J  B+ O
  310. ;禁用IRQ
    4 T& ]; C: F/ j, O" J
  311. LDA M19_IRQ_COUNT_H
    & H$ K5 R* Q5 |
  312. AND #$7F
    7 t2 b0 |1 _$ _' T2 V
  313. STA M19_IRQ_COUNT_H
    ' F" |. x; z1 U  G, d
  314. / ~2 P% \4 ]2 v; `8 r* t9 B
  315. ;命名表
    $ z/ o  C, m' L' t. S4 j* L: M+ W
  316. LDA #$E0! }+ A, `) \+ r$ f: V2 c
  317. STA M19_NT_20001 G' Q1 D' S* ]2 J- K
  318. STA M19_NT_24002 }4 a# ^4 C' B, y% A7 D
  319. " F/ Z2 }( ^8 f7 h( |7 h; x5 Z
  320. ;命名表
    % b; L+ }; M# L" q. {  k3 t
  321. LDA #$E1
    1 }0 E8 t; S' q% o, s
  322. STA M19_NT_2800
    , ~3 u! g. a, _6 b
  323. STA M19_NT_2C00
    # K+ z& g/ G+ h5 ~
  324.   y! z/ |8 x6 m8 {. d
  325. RTS' Q  }, |3 R$ m$ k3 J
  326. 7 t5 \" ~1 g) c2 k' m" d
  327. ;==================================================' x$ P" m& f9 s
  328. ;重置中断处理
    " ?2 M6 K* z2 q2 g
  329. ResetProgram" k" R0 E( A8 k
  330. SEI3 G6 @$ B; _: M) S
  331. CLD6 v( M% M! _0 X  F7 m/ N
  332. LDA #$007 Y- C2 W1 a% {
  333. STA PPU_CTRL
      ~9 v; U* _8 Y1 b, K  w* h0 a& A
  334. STA PPU_MASK
    1 Q2 A, U6 T& R0 ^# Q7 u+ n' X
  335. STA PPU_STATUS4 o3 P1 V# r6 M- @* z" y
  336. STA JOY2_FRAME
    ) _" ~$ i  R5 X( Y2 d  d0 W8 n" l6 ?
  337. STA APU_STATUS
    3 F! C+ B" j: @5 v% V6 |

  338. 3 S5 F" D0 W" p+ Z8 A  ~+ X" N
  339. LDA #$C0
    ! h$ O" ]* H, Y& l. O' A7 [
  340. STA JOY2_FRAME
    $ f) O; f- n# Q- e
  341. : e2 c7 B+ J) u  R
  342. ;等待vblank
    ; F) k' M/ k0 J( T$ i
  343. LDX #$02
    ) X/ G5 ^9 X: u- `( L% A
  344. Vblank_Wait_1
    9 D' d6 c% B" T8 F
  345. BIT PPU_STATUS* r; h# q6 _& G$ c0 v  E
  346. BPL Vblank_Wait_1) _- y, G# F( z8 V- y+ S
  347. Vblank_Wait_2
    * \; k5 @% h  c$ H0 |, j
  348. BIT PPU_STATUS
    . L" y* Z8 Z2 j( r' Y. H
  349. BMI Vblank_Wait_2
    ! x' t! Y$ p9 u# U2 Z$ ?. a
  350. DEX
    8 H6 y, P5 d+ M& }  D8 }" H
  351. BNE Vblank_Wait_1/ o" t4 V" K8 ?2 A

  352. ) o8 a- k9 Y& d+ H0 g
  353. LDX #$FF
    ! X1 ]/ Z+ S" O8 X8 `8 O
  354. TXS
    5 y0 V" u* T4 k' r$ o0 x* e

  355. 5 q8 Q# E! O8 s
  356. ;初始化MAPPER19
    6 x# t( H6 ]" z8 _8 K
  357. JSR Init_Mapper19
    8 ^& j$ Q- q$ U& N1 e7 K

  358. - }# K4 n3 \7 X1 F' S$ c
  359. ;==============================! u% F- D( K4 i, b
  360. ;RAM初始化
    ) J7 c4 m8 g2 _% k. }
  361. Nes_Ram_Init
    0 p  B' h7 O# R" u2 Q
  362. LDY #$001 ~8 {  ~- u$ [
  363. LDX #$08! {; ^. |4 F6 q7 J" Y
  364. LDA #$00
    4 K+ |. `( f6 B5 {: @
  365. STA <$00  a4 I9 |: ^" m5 @
  366. STA <$01/ ?9 H8 j! Y8 m( O
  367. Nes_Ram_Init_Write
    ( a+ T/ X; }/ L$ ]* h& }( M
  368. STA [$00],Y$ J5 a3 G5 D; o+ _% x0 {
  369. INY
    8 M+ ^5 G' e6 a' {1 A" {. `
  370. BNE Nes_Ram_Init_Write- i' Q, ~+ A$ p) k2 a5 U
  371. INC <$01# ^4 _1 b& V6 _+ P9 T5 K
  372. DEX0 N& F' N3 o# n( r5 h; Q/ o) ]
  373. BNE Nes_Ram_Init_Write
    ! m! T" G4 \2 v) ?$ o6 V7 X

  374. 9 Z* M+ a% \, x( z2 B6 F
  375. ;初始化命名表
    / l5 v' |2 G$ }) ?3 Z( U2 e
  376. JSR Init_Name_Table
    ( `6 Y! J! e' d  P# L& Y; y
  377. , C1 q* [4 X; ]4 I* {; h2 n
  378. ;初始化调色板
    ( O: K/ ~7 j7 c) u  ^% M1 S/ t
  379. JSR Init_Palette% W$ ]: I* n/ Z4 o! {0 n4 q

  380. # p( Y5 \6 q' N# r  q2 Y( F% f
  381. ;初始化命名表属性( u2 v) D3 u. s0 ~- z2 {' D9 m! a
  382. JSR Init_NameTable_Attributes
    6 {" K! a8 ~5 g* ~2 v3 J# F
  383. 1 ?: Z) C* U- c! E. r- r: C$ l
  384. ;初始化精灵内存1 L/ g( D% K2 ~# C% Y* ]
  385. JSR Init_OAM_Ram
    - u- I* O. h- V

  386. ; ^4 S4 y# i6 A* \5 X$ d
  387. ;在屏幕上写点东西+ p% ^* u1 Z: i; Z
  388. JSR Init_Name_Table_Text
    ( B3 C. h' M- ~$ Y( n, |9 o" r
  389. * [* U+ \- v& i& m' a
  390. JSR Time_For_Vblank6 ~8 Z9 W+ q7 Q) V6 P6 r: u
  391. ;开启PPU控制: ~- x0 r$ R. b: p8 H8 q
  392. LDA #$A8% Y$ y0 a) o; I3 p; c* }( L
  393. STA PPU_Ctrl_Buf
    7 u' @9 f; s3 J4 p. Y
  394. STA PPU_CTRL. s5 `* r! I# U3 U( i" `) P

  395. 1 o. ~4 B+ H$ }+ l
  396. ;开启PPU显示$ l% ?; x. Z, X; O3 ^
  397. LDA #$1E  `  y" r/ u8 v* P3 C+ _
  398. STA PPU_Msak_Buf
    4 Y" k! _) Y/ {$ N5 B) m$ z
  399. 2 L' O4 F5 I7 i2 }' x
  400. CLI) e  t9 H3 N4 ?# V- e( T, S
  401. JMP Loop4 v; Q7 W7 H! R5 b# f0 E, y

  402. ; w$ }) r2 `  i2 m- A: K
  403. ;==============================( N5 @4 u/ v( U: T
  404. ;死循环, 等待NMI中断& }0 n5 G+ a2 i0 ?1 g0 c0 R$ @
  405. Loop
    . j5 S  |7 m+ L  |4 F
  406. JMP Loop; R. a8 y8 C6 y, \
  407. 5 f* h# U7 Q, h3 `" h$ E
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    * k: ^8 v$ k3 X4 a7 K- r' D: r' Z
  409. : H7 V' y4 m9 G  _2 f
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)+ ~  a4 m% K& _5 m- {* }! Q8 o# z
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    7 ~6 K" D3 v* [. F$ B8 P2 j8 [6 {
  412. ;==================================================! |1 _$ n+ @: }! {
  413. ;NMI中断处理
    / t* L5 s% q; E# b9 l
  414. NmiProgram
    $ S+ F$ _. K! G$ ?- I  T0 K+ p
  415. PHA8 g$ a) [' C' D
  416. TXA
    ( @! I' ^0 S9 d' Z0 [- f
  417. PHA
    - T. A4 k& w! i* [( V0 u- u# n3 G; L
  418. TYA
    1 S' E9 c8 Q6 E% D
  419. PHA: _9 n9 j) \) V' L! Q) I8 \

  420. - ~& R, e6 N' n) B( L5 D
  421. BIT PPU_STATUS3 N7 x. L1 m1 z6 v9 @  I$ h

  422. . q# U7 Z: ^* Z1 `
  423. LDA #$00  b; x) X: O; y( B' I" R, P
  424. STA IRQ_Index
      p$ E9 V, ]( f
  425. % |  ^  i/ Y6 u# T6 A; ?7 B
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    7 R0 W- S: U) |3 |/ b  B( n2 b3 ^
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    + B$ I4 k2 a" e9 V* G
  428. STA M19_IRQ_COUNT_L  G) K8 T* Y; t1 o% D: z! Z3 F; w
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    8 {8 {, c9 m& ?" r; ~+ C! }. U/ A/ Q
  430. ORA #$80
    + H5 p& T; a: ?+ E8 ^. I5 ?7 a
  431. STA M19_IRQ_COUNT_H9 V2 ?  J3 K6 l8 ^
  432. CLI9 O0 C! v2 p5 V8 H; n
  433. 8 T% P0 u& }, M) E. ^3 l9 P4 S: F
  434. ;关闭PPU控制. l' N. f/ M1 J6 D
  435. LDA #$003 T5 {  O1 ]6 p3 P; A  Z# C; o% r3 L
  436. STA PPU_CTRL( j0 j5 ~  `7 @, e0 U& u4 e
  437. 6 j3 e9 {" ^/ n. C% h
  438. ;处理PPU
    9 X0 V% l6 p  w' @% q* c3 x( ~: Z6 H
  439. JSR PPU_Process
    / q: [1 A* E/ N) d& W8 [5 A' k

  440. 4 x. I, I, o" A9 g/ s1 \: G
  441. ;开启PPU控制
    7 J9 M9 Q2 j. `) y* K" W
  442. LDA PPU_Ctrl_Buf! @+ B& Z6 I4 Z5 X
  443. STA PPU_CTRL$ `, F+ Q% b2 h. w1 L# O: h, c( z. Q

  444. 9 F0 L- C6 b- W/ }/ ~) B
  445. ;手柄处理
    , A. Y8 W7 S) J; N
  446. JSR GamepadProcess
    ! u' i& y8 g$ t1 _' c
  447. : V7 h; X/ V6 R+ `* t6 w0 K1 A3 ]
  448. LDA #$00
    . [1 p5 p% \4 _
  449. STA IRQ_Index: w; w- j: p2 r; \1 B  C$ R' P/ d! l

  450. 1 G. i& q' g# T6 l  X7 A% p
  451. PLA; R& l& U: r9 S) n3 D
  452. TAY
    3 u5 z" B" i7 m  o) h
  453. PLA
    1 F( z7 Y; {# k) X' e( k
  454. TAX
    - H( k; D6 `; Z  g; X
  455. PLA
    9 L- j5 w7 d2 e
  456. RTI
    1 H, N/ n7 T) j1 a7 g
  457. ( n8 l% x  {& _7 E+ p% M+ }
  458. ;每行扫描线113.67+ z# a8 R; V. `
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)2 g5 l" q) z4 O9 U$ j' F! t5 ~
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ; G( x$ F/ f5 E: ^
  461. ;==================================================1 o! L8 z! j5 \  {6 X* Q/ U7 S
  462. ;IRQ中断处理- ?+ F2 e* {. g% A7 y1 e9 g
  463. IrqProgram# p& B, {1 K7 G2 v' p
  464. PHA
    : f9 c+ Y  L& s: L
  465. TXA4 S* ?, C( _1 ^8 @6 ?
  466. PHA
    ! l6 E+ p) M. l1 l
  467. TYA0 j- b7 K# U9 t+ n. Q2 r
  468. PHA4 w  u) x  Q# X) j
  469. 4 J4 j) V3 k2 z2 ?6 R; D
  470. ;16条扫描线后触发IRQ
    / \2 P. }! l( `$ r( M: i. Y* _
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    & _7 f4 P" N5 E! ]; C) |
  472. STA M19_IRQ_COUNT_L
    & a/ d- M7 d6 ?! R2 q
  473. LDA #HIGH(BEGIN_LINE_CYCLES)# I( o& F( I  O3 W( r; M) h
  474. ORA #$806 w# \! Y: A  ~
  475. STA M19_IRQ_COUNT_H
    ( p$ L  r" S% u. H5 @9 M5 V8 l

  476. % u: M2 K! p$ v  V+ B
  477. LDA <IRQ_Index
    ; ]0 H. N' l6 C- y" ], J( T
  478. BNE * + 4; G( {7 g6 v! u7 x: {. P
  479. INC <PPU_Scroll_H
    . ~/ ?6 X) O' Z) C* f

  480. . t8 ~# \" T+ @9 W' \
  481. ;设置屏幕滚动
    ' W) n: Y  S' u$ x, [& q% S
  482. LDA <IRQ_Index
    ' r# x* p7 o! B8 r6 C" M
  483. AND #$016 Y& [' }5 L- N, {# o$ j
  484. BEQ Irq_Scroll_Right! C; Y& O( W- g6 q6 B# @
  485. " v' B% a, Q. m/ C; u) R
  486. Irq_Scroll_Left
    1 ]8 l1 `7 h- Q+ J3 U3 ^! }/ z# H" F
  487. BIT PPU_STATUS
    , J" T3 k( H+ g8 ?5 a- H+ K6 d3 X* Q
  488. LDA <PPU_Scroll_H" L+ u+ [5 C! ^& M5 ~& z
  489. STA PPU_SCROLL- q7 A( n+ ]+ T% E! V- T$ [7 w
  490. STA PPU_SCROLL
    8 Z! u7 J7 \, F9 I
  491. JMP Irq_Scroll_Over5 p' x  ]9 T4 I2 u) @
  492. & }0 H( h, I( d8 d( Z% Q& R
  493. Irq_Scroll_Right
    ; t4 J$ l( g1 P7 Y0 Y/ h
  494. SEC
    - n0 y7 E+ d- _; L+ `  a% \* j
  495. SBC <PPU_Scroll_H1 e* o5 H/ L* a1 W4 A
  496. STA PPU_SCROLL
    3 Q: ?9 r! _% @
  497. STA PPU_SCROLL7 A( ]; I7 _; V; f$ N: T2 P: s' r
  498. Irq_Scroll_Over
    & t  w4 ]: l; T0 M

  499. - i7 T$ K3 Q+ H3 T" Y# e
  500. INC <IRQ_Index
    * I/ I- h. E& P! E6 c
  501. 1 y3 l0 ^$ e1 {1 e9 c& o4 g) S
  502. LDA <IRQ_Index
    % f' t0 \. A0 @$ P5 }
  503. CMP #14
    . }  M& M& z) Z% a1 u8 I
  504. BCC * + 10/ l7 K7 P' d$ i4 D& Q
  505. LDA #$00- X0 }) B; ]  k9 p
  506. STA M19_IRQ_COUNT_L5 X6 x0 H$ l3 R# n" Y
  507. STA M19_IRQ_COUNT_H
    ; |7 ^* D5 m  M6 }7 ~

  508. ( n1 x" J. ?  O/ U" F) z9 A/ M
  509. IrqProgramEnd( C9 C+ P# y+ T6 U2 C1 P
  510. PLA" d4 B3 }' E, Q5 }$ _' B, S- I$ h
  511. TAY/ j2 ^+ t/ s* v3 q. v5 X, h
  512. PLA
    9 n0 P! i2 q$ P% t5 ^# k# V
  513. TAX
    2 e- P4 }% C# k5 x+ A, ~
  514. PLA
    ; R$ t1 G( F, Y+ b$ E; {9 Q
  515. RTI
    $ R/ }$ M, E8 S. ~2 t
  516. & N! G3 P" X5 A" f
  517. ;==================================================, f2 t* \. Y' B8 D! T$ s
  518. ;中断表
    8 b2 D0 g3 b/ A% w2 F2 H
  519. .ORG $FFFA3 w$ w4 O% G- n( u& v. `1 T5 G( a
  520. .WORD NmiProgram
    + O/ P+ Q, ^/ m
  521. .WORD ResetProgram
    5 g% t: @; |+ ]6 J2 e
  522. .WORD IrqProgram
复制代码

, \) }: t$ Y" [( I6 E

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-9-17 04:32 , Processed in 1.093750 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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