EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]1 I$ J) n( ?0 R& H
  2. ;FlameCyclone 20230710- y3 [9 @1 Q3 ^) y$ c5 \0 a7 p

  3. % x5 T' Q4 F; [7 U3 ?
  4. ;文件头
    ; |8 M  m6 x+ e3 n( t# e
  5. ;======================================================================, z! o9 i" L7 k1 L* k- B
  6. .INESPRG 4                                              ;16KB PRG 数量) {" r. ], M) K& b
  7. .INESCHR 1                                               ;8KB CHR 数量
    3 h1 |. p2 I8 |! R' H! P
  8. .INESMAP 19                                                 ;mapper 19) [- r: w- ^( D# U0 B  B
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    0 y* \) h6 L! {/ N$ f* ?" g
  10. " u8 K2 `) E5 ]- x
  11. ;必要条件
    , u% X' l  f& w) i4 S2 @
  12. ;1.持有CHR ROM
    " t# x3 M5 B7 F" m9 R
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ! ^/ l# ^( V# |+ B# ^9 \
  14. ;3.精灵内存(OAM)不为空
    : C) Z. [9 _. w

  15. ' O- y- w% B; v5 |1 K  c( ]
  16. ;==================================================
    1 w+ P+ ^' s! g/ _- ?
  17. ;NES端口常量
    : |: l' ~! s+ L& V$ x2 _$ }5 ?
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    3 r, \# p2 }5 h# J
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器1 t' y  w* h3 i: I4 ]
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    6 D: i# j! \$ j8 f7 ~2 T- |* e
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加12 P5 ^/ e+ s9 `; y, E
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    - p# u! _- q# o! y  A
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ) d2 N+ U" R9 t0 K3 R0 E, J
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    5 ^; Q; e- M: G7 Z) V6 j7 P, t# W
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ! V3 a- F# h) j2 ^+ O
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存3 R" x0 b) [% E5 i4 G; I- u/ w7 A
  27. APU_STATUS              =   $4015   ;声音通道切换
    " E8 G3 Q/ @6 L
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通" A3 v2 y1 t" W" e
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
      x' {) j" Z* y( T, G* D- B

  30. ( o' m" g  i! T
  31. ;==================================================
    * ^+ Z6 E  Z6 t$ l$ Q+ V. u
  32. ;MAPPER 19端口常量
    & _9 u7 @. d( K) ^6 j, B
  33. M19_CHR_0000    =   $8000
    % M9 T+ `7 t$ J. J# h" f
  34. M19_CHR_0400    =   $88007 K/ t! V/ c; k# v' q/ S3 d
  35. M19_CHR_0800    =   $9000; M7 y7 s' }3 O$ y
  36. M19_CHR_0C00    =   $98007 \2 J& L# ~9 d, b4 D
  37. M19_CHR_1000    =   $A000
    ; D7 Z0 t( }& Z, s$ A
  38. M19_CHR_1400    =   $A800
    1 ~+ H6 J' f  t* l& E( y
  39. M19_CHR_1800    =   $B000
    * Y3 J* l1 e) }. S
  40. M19_CHR_1C00    =   $B800
    . \8 J6 c; Z1 f6 z/ \9 t
  41. M19_NT_2000     =   $C0008 y: V1 W6 _8 ?$ a: R
  42. M19_NT_2400     =   $C8008 n' s, [' G) i2 B/ H& x
  43. M19_NT_2800     =   $D000
    . \7 E) r) R9 L& Z# k; U9 M. h
  44. M19_NT_2C00     =   $D800; [* ]$ d5 p- a- {6 ]. M
  45. M19_PRG_8000    =   $E000, p5 S8 Q9 k. h3 Z
  46. M19_PRG_A000    =   $E800
    ' Q( j" b( M- v7 g9 P$ b# Y: k
  47. M19_PRG_C000    =   $F0005 h+ x' }) n" z- {* m
  48. M19_IRQ_COUNT_L =   $5000& ?2 n$ a" J4 _# Q1 q6 ]* F
  49. M19_IRQ_COUNT_H =   $58001 G# x$ I( F: }  v& E

  50. 8 d% V: c3 G7 l" L  G4 K- b! f/ |
  51. ;==================================================
    * d5 [3 W2 t3 x
  52. ;程序块配置" V- z9 `) d5 E2 n  s# ?3 m
  53. BANK_DATA_MASK          = $07
    ( V9 p9 ?' B$ b8 ~7 r
  54. ;--------------------------------------------------
    9 ^5 O$ a) @6 ^0 o2 t1 q
  55. RESET_BANK              = $07
    1 c6 d. l$ b, ~* w6 C) x# L
  56. RESET_ADDR              = $FC00* k- a# w" o. s& T, J; e: H
  57. 9 P8 v' k% o9 S$ ~3 D' w/ Q
  58. ;==================================================. n/ G5 j! Q4 h8 x' W) J
  59. ;图像块配置: S0 F6 O/ j4 m! n0 K' ]* b
  60. CHR_DATA_BANK           = $08
    / t2 g" Z3 J: d% ?$ _
  61. : Y+ ^9 @3 A. q. K" r7 l
  62. ;==================================================
    : e( T! g( @6 W$ v5 L: F
  63. ;零页内存地址配置! ?) N' R/ K/ ?7 r
  64. Use_Ram_Addr            = $80
    , I" I. c) {' t
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    ' ?8 ^/ z1 V6 F" @
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $016 H6 X; K1 D$ t! E) S+ g  V3 q' ^
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    , m# O7 }; R& `4 z# w, j
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    + g' h2 Y3 H* Q  }1 U1 L* x
  69. FC_Data_L               = PPU_Scroll_V + $01% D1 W( {) C) P# h1 s1 G8 W
  70. FC_Data_H               = FC_Data_L + $01
    : O, g  N  f% i) @! B; Y
  71. FC_Data_Buf             = FC_Data_H + $01& _- }5 Y* P6 G
  72. ;==================================================5 {0 B! _+ m' l1 {' l# p+ l
  73. ( x9 M" L- z' V6 O6 s5 {
  74. GAMEPAD_MERGE_FLAG = $04
    ; p* j+ N; q; o3 R7 O

  75. 0 J) n7 R+ p4 V; w9 V
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    " _: z, _* h' T* Y
  77. Gamepad_Once            =       Gamepad_Keep + 2* {- u4 |* u: z4 I; K8 L+ n/ y
  78. Gamepad_Temp            =       Gamepad_Once + 2' O- x2 F3 [6 h+ @: ]3 t
  79.                                 , B4 B: [8 p: d+ l  @' E* ~0 o2 n0 y- b
  80. Gamepad_0_State         =       Gamepad_Temp + 20 O7 t8 s+ @0 T) u
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    / V3 L. f# x6 }- F; `7 v/ N7 B6 w
  82. Gamepad_0_Value         =       Gamepad_1_State + 1. `3 o5 J( y' U$ A( p; E
  83. Gamepad_1_Value         =       Gamepad_0_Value + 11 b( Z& k& G- l' ~/ B& _5 n
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 10 G: D2 L0 u* C- K7 g' x8 ?. s1 U
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    " d) q- k- z. g, ~# Z( ~: Q) }& j

  86. ( ?. E' e+ Y, J4 P6 r5 H0 }# f# x
  87. ;==================================================
    / t/ o' h' n) g" v$ r+ g8 p
  88. IRQ_Index               =       Gamepad_Merge + $01* h4 O8 G! l% `+ b
  89. ;==================================================, [9 Y2 B- s  M# Z' e9 E% L

  90. - b2 ]) h, Z' }# g
  91. ;CHR图形数据
    - ]/ j4 |" d* M/ K, e0 v, \2 x0 |* Y
  92. ;==================================================
      v' l. U& _  B2 s4 l2 ]
  93. .BANK CHR_DATA_BANK. _6 b% u" U: Y1 ~) u7 M& j  W
  94. .INCBIN "chr_bank/chr_data.chr"5 V3 h, _. |$ G/ H1 q

  95. + S3 x/ e+ W. h: L8 N
  96. .BANK RESET_BANK & BANK_DATA_MASK
    5 B. \. C, w4 E8 W1 O" e* i% E
  97. .ORG RESET_ADDR
    ; Y" P# x, r7 o) ^( v# M$ D
  98. % D  @4 f9 [; k' |) [
  99. ;--------------------------------------------------
    0 {6 k6 X  }! g3 ^, m# ^
  100. Attributes_Data. @/ |/ h, c- T& h& G, M% N
  101. ;命名表属性
    9 i0 {+ H" ?! o! v
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$005 i+ ?8 r% G; t! [% D3 V
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    ; P9 i* s9 \! U9 H+ F
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    + ^( V, V! U+ ^7 h1 A' M+ {- k
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55) D2 V# f! H6 n0 k5 f
  106. ;--------------------------------------------------6 G) ]0 R  U7 N# p
  107. ;调色板数据
    , G$ K4 [2 e& W5 g4 r. w$ V
  108. Palette_Data
    ! P* W; |. Y3 a% }
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F6 g' c" t5 E; B0 J2 k1 [% F
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F( |" l4 k+ J" M' ?2 l7 D# q

  111. 9 I; h# Z: J  Q: m1 X) {) K4 a7 ^& M
  112. ;==================================================
    ! t4 Y8 i2 _% X" ]3 r5 o: N
  113. ;命名表初始化5 k- ?1 A! j2 ?/ d9 H+ D0 {1 @4 C
  114. Init_Name_Table
    ) U7 i3 J2 {7 S# ]
  115. LDA #$206 x9 E% S6 \, N3 W7 ?. _5 m6 x6 Q; I
  116. STA PPU_ADDRESS
    & U3 C5 h% O3 ^* ^; d: Q* v1 t( Y
  117. LDA #$00
    # O) k; q9 _5 }0 d# Y% X$ Z5 P) q
  118. STA PPU_ADDRESS
    2 t* e' r" R9 n  u
  119. LDA #$00) I1 L- B3 U# {# M
  120. LDY #$00& ~/ ~4 s$ m( O# y# c6 {
  121. LDX #$10
    3 d2 R& @$ B/ ?7 C3 D
  122. Init_Name_Table_Write
    % D8 q0 p) A; P, `
  123. STA PPU_DATA
    6 b; I# V" S- V' p' x; e, I7 n
  124. INY
    5 G5 M( |& z: o
  125. BNE Init_Name_Table_Write$ j: O) \5 ~7 s
  126. DEX
    " q$ n/ {! a. R- S
  127. BNE Init_Name_Table_Write7 S& C& P: r# f9 h5 h* \
  128. RTS
    9 c2 t4 U9 E/ x! d& E

  129. . ?" R3 o& A/ _9 L+ T+ e, }
  130. ;==================================================
    : P8 |$ F! C  n
  131. ;调色板初始化
    ) B, f/ H0 k9 N. n! r
  132. Init_Palette3 l9 S! V' U$ {* b; S
  133. BIT PPU_STATUS/ z% l8 \$ M4 [, R- X9 W! r
  134. LDA #$3F7 P4 J& x" t2 g; i) A$ z5 O! c
  135. STA PPU_ADDRESS4 y7 e4 e! s% v3 z% s; M8 h: a& F
  136. LDA #$00
    , G1 W  W5 K9 b, m$ }
  137. STA PPU_ADDRESS
    1 d3 k$ V- I: }# R, d
  138. LDX #$00
    0 W8 Y, c4 ^3 i+ g0 }+ l
  139. Init_Palette_Write
    3 m! r( o! f0 I' y) x" X2 j
  140. LDA Palette_Data,X  v- j7 z9 s6 x& K$ l+ H# B
  141. STA PPU_DATA
    ' f3 h& u! p+ f# N" Q
  142. INX
    ! @9 x2 \' N# a# D2 u
  143. CPX #$208 ^7 F1 p* E& X
  144. BCC Init_Palette_Write
    ! |& Z9 U/ t( {' l" F% D
  145. RTS
    ) J- Y  t' U, D
  146. & F( w* @1 N: u( z& ]
  147. ;==================================================1 D) V$ d( o8 [" k6 n0 \
  148. ;设置命名表属性
    ( j# [, M' V; U2 \
  149. Init_NameTable_Attributes9 ~( ~. w+ P8 t8 {7 Y
  150. BIT PPU_STATUS) ^9 b6 T1 b8 z) K4 N% i( b
  151. LDA #$23
    2 n' z- a* l/ J: e8 c9 q
  152. STA PPU_ADDRESS
    " G6 G+ @2 G6 ]8 T' K/ i
  153. LDA #$C0
    ; u( m* ?+ d: [" k9 @
  154. STA PPU_ADDRESS
    ( w7 |  `0 B* [4 I; \7 o
  155. LDX #$006 `# T" w  U, I
  156. Init_NameTable_Attributes_Write
    9 I: M# D1 ^3 T) y  c
  157. LDA Attributes_Data,X) ~6 P* t& m6 K4 ?6 y$ Y
  158. STA PPU_DATA% i+ u3 L# d/ w' {7 H+ g9 x5 i
  159. INX
      k0 b; z: @% }. L" Y
  160. CPX #$40. \  o3 v* I+ B2 e0 X
  161. BCC Init_NameTable_Attributes_Write
    : a$ j# L( G7 i  g% T
  162. RTS
    1 X  ]: e& S4 h6 y" d9 {1 H6 V

  163. ! w  }+ |, S( c2 z0 u; X& b$ H7 H
  164. ;==================================================6 M. e& _: F( m# p' c0 }
  165. ;初始化命名表文本
    ! l8 A- D  r9 b& E# ^- G$ J3 P
  166. Init_Name_Table_Text  w: }) N  p2 F+ i
  167. BIT PPU_STATUS
    $ L9 ^- R1 Z( |$ c5 l' `7 n
  168. LDA #$20
    " @$ k- i2 Q& h$ D4 [& x2 E) x
  169. STA PPU_ADDRESS
    * p. s1 X& n  n* |
  170. LDA #$008 w0 V: p+ ^8 x4 q4 @
  171. STA PPU_ADDRESS2 g0 Y( M& i- l, y
  172. LDA #$00! C# S3 h8 u2 W) i% u
  173. STA FC_Data_Buf
    # M% H0 {: A7 ~
  174. LDY #30/ x+ X/ R. l8 ?2 R: q; O6 q8 u
  175. Init_Name_Table_Text_Write/ ~- C$ P1 i" V# c
  176. LDX #326 x  l4 j  e: G9 e
  177. Init_Name_Table_Text_Write_Char
    4 X7 `; j& Y6 a
  178. LDA #'0'
    ) Q& M6 P! G8 c8 ~3 v# B
  179. CLC
    8 R& h5 Y: N6 T/ X. C+ T( r- D
  180. ADC FC_Data_Buf
    # v5 |! ?9 m7 D6 U5 T6 ~$ V
  181. STA PPU_DATA
    $ f' q0 s8 b( k9 y
  182. DEX
    6 l" Z4 O8 \1 e" ^  D
  183. LDA #$14+ k0 z) u, F; o' b3 f9 n2 h6 |
  184. STA PPU_DATA
    * s2 J# F2 ~7 W
  185. DEX7 \' w9 [3 y% h3 q
  186. BNE Init_Name_Table_Text_Write_Char
    : E* K' N. r* i/ E5 ]
  187. INC FC_Data_Buf
    1 W" R* _: J0 y
  188. DEY4 Y$ n% D/ k7 G2 |! h1 o, z9 W
  189. BNE Init_Name_Table_Text_Write
    0 R! c8 E5 k* W% u
  190. RTS
    " b* K: C0 B' g" `4 p
  191. , K+ _' w# k# t
  192. ;==============================
    : I4 [: u4 C0 l; L7 C5 X
  193. Init_OAM_Ram;初始化精灵内存3 p2 b/ L6 \6 k7 H4 C. b" y
  194. LDX #$00& \4 y" I5 H; X' b
  195. LDA #$00
    : j0 z. M6 }7 v; G
  196. STA PPU_OAM_ADDR! p! J- P) R8 N4 M. R7 R9 N3 q
  197. LDA #$F82 Q- g$ F2 \( n" x
  198. Init_OAM_Ram_Write
    # o0 Q$ |, D3 i
  199. STA PPU_OAM_DATA2 z& {3 z& E: ^2 E5 l; f2 E# o
  200. INX3 T- \; V& z/ @5 c: j
  201. BNE Init_OAM_Ram_Write1 W  l4 v, C+ i9 `1 T
  202. RTS
    . G2 H/ H9 s  |

  203. ' f1 o; `  T1 f. }! c
  204. GamepadProcess;手柄处理
    1 n6 N5 A. K1 t8 Q* H
  205. JSR GamepadDatacan
    # P) P0 |8 ?& a9 ?4 C
  206. LDA <Gamepad_0_Value
    # [$ w9 ?) H/ H9 y; r- {' r
  207. STA <Gamepad_0_State
    . i( J8 Q$ l( o: [3 r4 ~
  208. LDA <Gamepad_1_Value! {4 v* j, L. O6 W4 w0 g( ^& o9 B6 y
  209. STA <Gamepad_1_State& K  W& y; r, i/ I
  210. JSR GamepadDatacan
    0 H- E, I- O- t9 L
  211. LDX #$01' _3 U0 z2 a6 [* D3 M# H; y
  212. GamepadMergeCheck;合并手柄输入检查
    6 h4 G; w. b$ m& S  ^, d
  213. LDA <Gamepad_0_Value,X" R! B+ y6 {) h* N
  214. CMP <Gamepad_0_State,X8 s5 S( F% }5 k% ]
  215. BEQ GamepadMergeInput
    - {; {5 R* w3 q- g) B) [
  216. LDA <Gamepad_Temp,X) W+ g4 ?+ W) ]! t) w5 Q4 D
  217. STA <Gamepad_0_Value,X
    2 H/ G* |! M; G
  218. GamepadMergeInput;合并手柄输入
    " P5 `5 d* N1 b# ]. H% z
  219. DEX0 K# _# E5 e3 h6 W5 @3 y- v
  220. BPL GamepadMergeCheck; j* ]: W; O/ f" F% z- Y
  221. LDA <Gamepad_Merge
    9 F) x, e1 x3 ]9 E8 O4 e
  222. AND #GAMEPAD_MERGE_FLAG
    6 p# f6 R6 ?8 J/ E' @! i3 m
  223. BNE GamepadStateProcess
    - Q. }" ]' J$ |% A& A( ]
  224. LDA <Gamepad_0_Value4 \1 N: Q$ ~4 b: U+ e
  225. ORA <Gamepad_1_Value
    + e# F/ \% ~  X9 j+ C! C
  226. STA <Gamepad_0_Value
    5 j9 p) b( q! _& e" T3 w) u( ^
  227. GamepadStateProcess;手柄状态处理
    + }2 s' e5 l. N% K4 [
  228. LDX #$01
    8 f8 [! R+ \* Y& B) x
  229. GamepadStateSave;手柄状态保存
    0 ?" s. i+ ?4 Y
  230. LDA <Gamepad_0_Value,X
    8 T5 F) O1 j, m
  231. TAY
    2 q( Z0 i$ h1 G' E. ], w
  232. EOR <Gamepad_Temp,X1 P$ M' n! M- P2 t5 S
  233. AND <Gamepad_0_Value,X
    0 \9 O7 e9 e. l- @& J
  234. STA <Gamepad_Once,X
    ( D' ?; C# o( {+ I
  235. STY <Gamepad_Keep,X  b0 j$ ]) z' E, ?8 l
  236. STY <Gamepad_Temp,X
    4 }$ _# k6 k& V( o( T* q
  237. DEX  X* H. r' M8 n8 j& a, ]* q
  238. BPL GamepadStateSave$ `6 J- X% L0 N- H
  239. RTS9 ]0 T# F3 W; A9 Q# ]. V+ p

  240. " r8 b9 j# p0 W2 P5 K$ @" B
  241. GamepadDatacan;手柄数据扫描; ?% ~( t0 Z9 g4 q0 t
  242. LDX #$01
    # m/ i( K/ V6 ~0 ~
  243. STX $4016
      F' [# U9 `6 D& c+ ]1 D* @! L+ E
  244. DEX7 K7 t0 w, r/ X0 k! v
  245. STX $4016* p2 c3 f6 O$ m/ s" ]$ O
  246. LDY #$081 k" N1 v) G! u& e$ A# ]( t
  247. GamepadPortScan;手柄端口扫描1 i" m; h  v& H& p
  248. LDA $4016
    / S- E7 Q* u6 M: E8 R9 i
  249. STA <Gamepad_Port_Value: D! p+ r4 E5 U: D( k
  250. LSR A' N: O& g  b- n& c% r( s7 g2 c
  251. ORA <Gamepad_Port_Value
    3 k2 l$ R; b4 U* b  w7 |" V
  252. LSR A: ^3 a/ z+ T/ u" ~( j& `, p& [! N
  253. ROL <Gamepad_0_Value
    6 }0 \! g) f+ E" Y
  254. LDA $4017
    % K8 Q5 B7 w' i1 R7 l
  255. STA <Gamepad_Port_Value
    4 T$ H6 x3 _' l4 a
  256. LSR A4 L- R3 J8 v  ]" W
  257. ORA <Gamepad_Port_Value
    % @0 V. Q" d# Q7 U/ q/ Y
  258. LSR A7 d  u1 g: e9 H4 z% f$ P
  259. ROL <Gamepad_1_Value
    7 i& h, j; Y9 W9 t+ {5 `. n4 r. N  X
  260. DEY
    6 Y; C: Q! M( z+ N8 e
  261. BNE GamepadPortScan. O5 T/ r1 }( D
  262. RTS
    3 a7 G6 W2 d! G* g0 J4 L

  263.   M; H- w% q0 M1 Y$ C. s
  264. ;==================================================$ Q( a4 j1 L- K- Q: b3 N4 w" M
  265. ;PPU处理
    3 A. I% v& q/ w5 _) M* e! d6 F
  266. PPU_Process
    . q4 d- s8 w! j1 Q' A
  267. LDA #$00
    . _4 P+ M" v- c/ h$ K" I& x
  268. STA PPU_MASK# m- S% s' W+ ~1 Z. x6 K8 }
  269. # s' `: y  n1 Z5 O$ h
  270. BIT PPU_STATUS2 j% T5 v+ I% N$ T' i  D6 D
  271. LDA #$20
    ; O6 V! X- S  F  H
  272. STA PPU_ADDRESS* x3 s/ ~' X% o5 K7 t
  273. LDA #$00
    5 S3 r" g; ]/ C8 A% j
  274. STA PPU_ADDRESS
    3 _4 ^( W+ L4 I, |
  275. 0 |* ]! V( ?$ d3 P, }
  276. STA PPU_SCROLL
    ! b1 r8 K& k% a9 L9 {
  277. STA PPU_SCROLL
    0 i8 |4 [* A1 \3 l1 F2 g( Y. C
  278. 3 C. e0 S) v7 P2 q- X$ N7 ]
  279. LDA PPU_Msak_Buf2 ?! X' p* W( u% z7 S& S' Q7 _+ m% o
  280. STA PPU_MASK5 ?$ H2 ~) t3 z; ^  T
  281. ; O4 d# H1 p  b4 ^; N% ]: Z9 g, Q* x
  282. RTS8 j$ l. d0 ~+ C& u
  283. 4 a3 Z+ u: g+ s2 K  l2 E+ M0 o0 \
  284. ;==============================7 f3 b( s7 o# }1 n( k" K; M
  285. Time_For_Vblank;延时等待
    , B$ h3 |/ ?# ?  w
  286. LDA PPU_STATUS: t, Q2 c/ Q7 `+ C6 c- X9 J
  287. BPL Time_For_Vblank
    + g, a5 q3 }9 j/ ]
  288. RTS- X; ^# q- U' L& G( U

  289. 6 K. G/ c8 ?  w* [$ o
  290. ;==============================
    1 l. e7 n- ]6 y; z1 }* J
  291. ;初始化MAPPER194 Y3 X+ P" d' x' P$ i  l- Q" t
  292. Init_Mapper19
    % h# U6 k+ N9 ?. a- |+ d4 i* w
  293. LDA #$00& I# ~: B+ i8 w2 e! j  r. Q7 Y( R
  294. STA M19_CHR_0000# ?% A' q" Q) X1 l- i- D  F
  295. LDA #$01
    3 L" d& g# w+ `# U! d' E
  296. STA M19_CHR_0400' Q! K3 J& P- P1 o* O0 L- |4 ?
  297. LDA #$022 O1 s) |% o! r# E0 C$ o
  298. STA M19_CHR_0800
    " _7 N0 a7 K& Z0 ^0 L+ \
  299. LDA #$032 }# x' R" Q; F7 r, k9 c
  300. STA M19_CHR_0C00: m2 S( _6 ]% O. Q& X* R
  301. LDA #$04; ~: ?. o6 t1 o, o7 O# Z
  302. STA M19_CHR_1000
    % P( r2 ?. S+ y. k  o$ L3 a/ n
  303. LDA #$05# Z5 r* j: B; g# P1 b% c% i3 g
  304. STA M19_CHR_1400
    0 D% t  N: F& i# ]* [# l
  305. LDA #$06) d% q- Q/ m5 s; F% u( ]* _8 Q
  306. STA M19_CHR_1800
    ( \5 u/ N1 @3 ?' |4 C1 i) a
  307. LDA #$07
    : ]0 m# F( P9 A, m
  308. STA M19_CHR_1C00* L+ C+ j  r' a8 a, G# [
  309. 6 k9 Q) K+ b& k% A  H5 n# S8 ?6 _
  310. ;禁用IRQ2 a9 u0 L2 d" V7 c9 C- ?
  311. LDA M19_IRQ_COUNT_H
    6 }9 Q& a; ]/ [
  312. AND #$7F. P1 G* I* U7 y" }7 J& s
  313. STA M19_IRQ_COUNT_H& G; I' V0 C, W. d+ ^
  314. 8 f- r5 n5 R+ R& i; F
  315. ;命名表
    4 k% i( X8 w/ [0 C2 V
  316. LDA #$E0& r0 Q; X3 m% q$ U0 ~7 S3 W! E/ R  X
  317. STA M19_NT_2000% D' q2 v7 o4 V- o5 `7 |; f1 c: N
  318. STA M19_NT_2400
    ! }, B: L& k' ^1 T2 j

  319. 8 h, ~" x' l2 P
  320. ;命名表8 Y/ b( m  T& p0 p' M) Q- M6 |
  321. LDA #$E1
    & [9 D5 R5 e( m
  322. STA M19_NT_28000 j7 i* U8 c( |5 d! H+ _
  323. STA M19_NT_2C00, n+ K4 ^& f! C% x6 M/ s! I
  324. ) `/ i3 X, O8 n) \) @
  325. RTS6 P  B* _7 R( m. }5 J
  326.   n2 w& U- [/ p& k7 Y/ a0 F* S
  327. ;==================================================4 I- d) m* ]4 ?0 R2 F/ D
  328. ;重置中断处理9 \( m. z: m( E9 M4 w
  329. ResetProgram4 U% ?7 G2 e! T3 m4 L
  330. SEI( {+ {( w, b2 ]8 E8 [
  331. CLD) r) h! {4 [% O! |4 a) _+ V: V
  332. LDA #$00
    , A6 L1 M* L" W- Z% d
  333. STA PPU_CTRL
    2 W) k' k2 w! y3 T% g$ v
  334. STA PPU_MASK  V. v$ _' ?9 K* D9 o  }
  335. STA PPU_STATUS& i" Q( p* p; R
  336. STA JOY2_FRAME9 M) A3 j* i; E( j1 ?0 U
  337. STA APU_STATUS/ ^2 g, U4 ^# n8 w
  338. , U' {' e1 @" \8 v9 J2 S
  339. LDA #$C0
    - ]4 K3 `" q# c. _. x
  340. STA JOY2_FRAME  C1 P& x: h' y  v( g* n
  341. 6 k1 K6 D' F- F+ O: Z% ]% R
  342. ;等待vblank
    $ W$ L7 b" n2 Y4 r+ O* W
  343. LDX #$02
    * G( j$ U  y, g- [
  344. Vblank_Wait_1
    3 c2 k2 e# f$ H( ?& d, D  J0 ^
  345. BIT PPU_STATUS
    5 h, t5 x/ B7 h; m/ e( T& Z
  346. BPL Vblank_Wait_1
    ) w" L, T/ n% r) k8 J, O* w
  347. Vblank_Wait_24 M! D5 B( @1 b4 R, Y! h7 t9 r. {
  348. BIT PPU_STATUS# r! f* p9 j& a8 t9 F
  349. BMI Vblank_Wait_2
    - O' e% @, n, W% t5 W
  350. DEX
    $ j4 C7 ]/ Y( b0 `5 F8 q- V' ?
  351. BNE Vblank_Wait_1- l4 S, c) {1 L3 h1 o) W/ }' u3 R) W. c
  352. 2 `; ~+ w( L6 k( X9 _" I! |
  353. LDX #$FF
    & D/ I9 E% E/ Z& z
  354. TXS3 Y- ~! g, W  q

  355. & r: ?( C6 e5 u* O8 m! A* R
  356. ;初始化MAPPER198 T9 y4 v+ @' F  G* H, Z
  357. JSR Init_Mapper19
    4 N0 L  Q9 r! q  L: `  ^

  358. 4 ]% D( l5 w5 R; N6 @3 O- p# \# E
  359. ;==============================; K) F2 o; _+ ^, @7 [
  360. ;RAM初始化7 ~; o. Z3 U! ]0 X9 x: y, L( }
  361. Nes_Ram_Init0 |; ]8 t1 T1 ?( o
  362. LDY #$00) a! z$ D) J! Y# W
  363. LDX #$08( I. J, {; G. w/ s& m
  364. LDA #$005 m- P  A( a9 K2 K0 C6 S7 k. a4 k* y
  365. STA <$00/ A0 t7 ?9 D' J, d; y2 L  l+ W* r1 T  a
  366. STA <$01
    - O: |$ V# |! K
  367. Nes_Ram_Init_Write
    ; A2 P  E3 S  I- s
  368. STA [$00],Y
      m' A! J  `$ C% U! D
  369. INY& f+ m( r/ L0 j' u, o8 e7 ^
  370. BNE Nes_Ram_Init_Write% o: Z8 E% P- K- p; {. E6 L3 B/ k9 j
  371. INC <$015 @7 P% U. h" F# r& e
  372. DEX( L! F. y( B; E# R3 |
  373. BNE Nes_Ram_Init_Write0 P% N$ ^: C$ X8 q1 K

  374. 6 W* s5 P! j2 E; O
  375. ;初始化命名表
    % H9 G, C; J, k" P! v+ N+ l9 W
  376. JSR Init_Name_Table
    ( Q4 ~. I& N) N& p

  377. ' s: I5 Y0 K+ K
  378. ;初始化调色板
    $ Q" c+ X$ o% S/ Z( ~
  379. JSR Init_Palette
    0 f  {$ M  {4 `6 p

  380. * S8 p5 R, _: e9 @+ p) e7 S
  381. ;初始化命名表属性8 _  ?; W. j0 {( _- ^: i& a! w0 c
  382. JSR Init_NameTable_Attributes; v! Z& |* Y$ g$ D  S  i

  383. " q5 t! H: g& R0 [
  384. ;初始化精灵内存
    * P  \4 g5 t8 Y4 w6 i, F( A! p1 p
  385. JSR Init_OAM_Ram' |1 {. R+ q2 J8 N& N0 g$ ~
  386. $ q% @# v9 B, k; o8 M
  387. ;在屏幕上写点东西9 V- D: r, D, Z$ V) M& ~9 {
  388. JSR Init_Name_Table_Text( L! j3 U4 U2 W7 B. d% |3 l5 C
  389. $ U( q: ?* X5 J, Q. J
  390. JSR Time_For_Vblank* A7 c5 L0 M1 Y* K' o
  391. ;开启PPU控制
    . e4 E- s( e: |  ]( a- c2 M
  392. LDA #$A8* E0 l% B# ~2 {% n# o& g* g
  393. STA PPU_Ctrl_Buf
    $ x6 M2 E  n# {$ n; R6 m
  394. STA PPU_CTRL
    ; {+ h) |* |5 I; o' X: y

  395. % @& Y/ X) }* E9 Q8 |) B) Y
  396. ;开启PPU显示
    5 U4 r6 U. U( w4 p/ d$ |
  397. LDA #$1E8 U1 w0 U" ]! _7 h. {+ U& v( E
  398. STA PPU_Msak_Buf7 |2 a0 D0 Q# g7 r' z) s2 a
  399. # j5 n1 n0 W; i7 Y' E6 _2 k
  400. CLI$ v4 Q+ \: `9 Y) V8 q1 u
  401. JMP Loop
    / J! K9 j! ]0 F( }4 J
  402. 2 l& l) h( z+ {6 r! S) e' H
  403. ;==============================" Y, f1 V* i  X2 X" c7 A1 d/ S8 K
  404. ;死循环, 等待NMI中断1 d  u9 N* j8 C( s0 r% z
  405. Loop
    - T% X9 W; X+ V7 Q: @
  406. JMP Loop
    $ k: a' F: V  E& t3 w+ b" h9 {' F) M

  407. * M4 _5 Q- G5 G$ l! X) _+ z: }  B
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967- S2 N3 q2 O) r$ m* ?

  409. 6 E/ ?3 b$ E4 x. n4 u" Y* B
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    ! o0 F8 j( B! s( M2 ~, c3 D
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)( |& j  M4 y0 V7 d/ ]6 q
  412. ;==================================================2 V- w* u" K1 ~2 h2 e# X8 z( x& E4 B
  413. ;NMI中断处理; }0 L# V- M) S' q* h1 J
  414. NmiProgram
    # G. V. M2 x" I0 m; y4 b- u
  415. PHA  X" Z. y5 @8 B7 G
  416. TXA
    : ~5 t: C/ r9 {! ~2 W
  417. PHA6 A& O- I* B0 _
  418. TYA
    1 Q7 O0 ]) R; m5 o) |5 Z
  419. PHA9 x8 x5 G; i8 j8 n% w) J0 k
  420. + g; t# d+ o- j/ k2 o! z
  421. BIT PPU_STATUS) P7 a' m, y1 Q, r" {; w
  422. / G$ k1 ~+ `& y4 T$ M- f
  423. LDA #$00' f) ?# t2 {% W# x% r& U
  424. STA IRQ_Index4 n+ y5 h9 S2 r

  425. ! X6 W# S5 X2 p4 d* {. L, I
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    + G6 v; ^. p4 ^- T3 i, d( Z
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)) |# k) b: S  _  I" j# o5 j
  428. STA M19_IRQ_COUNT_L% R) k5 ]4 V/ F8 S# v
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ; [# t! w7 h  F; s' ]3 i
  430. ORA #$80
    7 E1 Z6 t' k+ n
  431. STA M19_IRQ_COUNT_H
    : P/ L6 B& e, N* s$ D7 k& S, q0 g
  432. CLI* d! o& ]: d3 p
  433. 9 v6 ]0 J8 b: ^8 G
  434. ;关闭PPU控制
    & c# `* {' I! ]$ E
  435. LDA #$00" B4 g, ]& U% V& c( a# s3 B$ ?
  436. STA PPU_CTRL; r: L+ n+ I9 s) ?4 Q# c4 l& x* \
  437. * X  |4 |- f: S+ M$ }2 R% R1 v) D
  438. ;处理PPU  d/ n. [) I: b3 g8 v
  439. JSR PPU_Process" N/ p0 w0 C9 ?0 \

  440.   C+ V" K8 [) E: q# ?
  441. ;开启PPU控制
    ) ~8 Q: E% s) D) h) z3 R1 ?
  442. LDA PPU_Ctrl_Buf
    % D4 ]1 P( t5 u  M3 V# x4 x6 P4 @" v4 Q
  443. STA PPU_CTRL$ e$ L0 |# |7 v' R1 N" s
  444. $ _: h  `- h: n' a' x- h7 Q9 g
  445. ;手柄处理
    3 s; X# n! ?3 i, D' I
  446. JSR GamepadProcess
    4 c8 Q) s! q5 [/ `

  447. $ R( a& O9 `3 d, s! Z( d
  448. LDA #$00
    , O9 G9 W: m" G5 `; K# k
  449. STA IRQ_Index) M- b! h  j6 r- `" Z4 z
  450. 0 q; y  s2 c- l1 B
  451. PLA0 e; W3 ^8 Z2 e
  452. TAY/ n  l: |! q- J, c  X
  453. PLA% P' U, t# ~5 I
  454. TAX
    - o! P9 W9 n* f) Z/ A
  455. PLA
    : p' n0 P- e4 e
  456. RTI
    8 H  r3 p) s1 ^4 K
  457. - @1 i8 H( H3 Q% U
  458. ;每行扫描线113.67# s2 i& S/ K" T/ {1 `- J
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    2 L5 a3 N7 K3 [5 V, n) D. }
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7' e+ \" j/ E& r4 O
  461. ;==================================================
    ( ~3 h) m+ o5 E- z9 P" O  X
  462. ;IRQ中断处理* |% d' |3 F2 Y; Q+ y' i
  463. IrqProgram
    ; O" W; f% {& U/ O; k) Y; F
  464. PHA
    4 Y. p' {- c7 G% t' w& t" C3 E
  465. TXA7 c' m6 D+ j& F
  466. PHA
    % Q+ G0 D2 d8 @
  467. TYA; v- e2 @! W$ P: v% x/ x( b
  468. PHA6 L3 ~0 s1 @- [( a  V( h$ `

  469.   R- P' H, J) T; y
  470. ;16条扫描线后触发IRQ
    9 l) C  B% v" ^& u
  471. LDA #LOW(BEGIN_LINE_CYCLES)* Y% ]5 d, {3 u* s# e2 |: `
  472. STA M19_IRQ_COUNT_L
    & Z, w2 \3 A/ o
  473. LDA #HIGH(BEGIN_LINE_CYCLES)* g' _) k4 m# B) D
  474. ORA #$801 L9 ^, T0 v  F1 K9 b% g
  475. STA M19_IRQ_COUNT_H
    3 ~! S- H; m1 x& S( u0 @. E
  476. 4 v$ |8 \/ A5 _. G8 u1 L
  477. LDA <IRQ_Index# i3 f) k/ h$ x( S5 M) \
  478. BNE * + 48 S: F( }$ v: z; X+ p" ^
  479. INC <PPU_Scroll_H
    # r$ Y' j6 ?1 s: x

  480. 7 Q* V4 U8 s: s
  481. ;设置屏幕滚动
    ( R( D) P0 v) }
  482. LDA <IRQ_Index
    & Q' P8 Q8 I6 e  e& y; _) v
  483. AND #$01
    5 I$ ~5 y& b$ B3 A/ H
  484. BEQ Irq_Scroll_Right
    * h5 S$ Q4 x2 O4 S. x

  485. 6 E" M2 ?) \+ X4 C- W0 R. u+ O9 B
  486. Irq_Scroll_Left
    ; V# y* {' j8 ]8 F: {7 E, z7 f
  487. BIT PPU_STATUS
    . H9 t3 u' K$ e* G$ v2 C! v9 x
  488. LDA <PPU_Scroll_H& D- A, {% Z( G- g# O8 {
  489. STA PPU_SCROLL" Q( X9 a  y) C' S- E
  490. STA PPU_SCROLL- e6 W/ O2 o! A; h' l
  491. JMP Irq_Scroll_Over$ {5 Z) a, j. R2 d
  492. * M6 q# L  o2 d" V
  493. Irq_Scroll_Right+ o* k$ F- }% c! e# \" f! q/ Z
  494. SEC5 B7 ?; w! z% l+ ]4 Z
  495. SBC <PPU_Scroll_H
    " Y: R0 Q( A" ~# @3 C
  496. STA PPU_SCROLL6 H+ f% k) ~. v* A! \- p
  497. STA PPU_SCROLL
    . k/ \* m- b% C6 V8 K& l
  498. Irq_Scroll_Over+ N! ?$ F% u1 a; g

  499. 6 ~- q3 q6 x, _& |' j- E' z# c
  500. INC <IRQ_Index5 \- B( v( p- D4 A& X9 \  U  Y

  501. ' N0 T& ]: p& C6 T6 w7 J
  502. LDA <IRQ_Index" l: o* |- n1 t, B
  503. CMP #14
    8 `  j3 j. Q3 w
  504. BCC * + 10& X; E: h) c2 j# j
  505. LDA #$00
    4 D% P3 h8 e( _7 u& z  T! y1 ~) i
  506. STA M19_IRQ_COUNT_L& a3 @! @" g9 q
  507. STA M19_IRQ_COUNT_H: U2 w. c, ~/ `  `. ?# q( X$ V9 e  f* e
  508. + N) N: m, m( H# U+ {
  509. IrqProgramEnd$ D3 o7 I* A+ [3 A1 T
  510. PLA) @  Y' F! M; D! c% o: ]
  511. TAY
    , {: k+ F8 E& U, [( A9 n
  512. PLA  j% Q, e8 Z9 r: A0 |6 Y9 o
  513. TAX
    0 L8 q/ v! k8 X$ B& H8 x% S
  514. PLA
    4 L6 c" q( `/ Y9 D4 Z4 u2 u
  515. RTI
    : c) M8 R4 s6 `  i0 u
  516. 0 d5 e) g/ u5 D, E( h: O4 S$ s
  517. ;==================================================
    3 r7 V  e7 F, b1 }. b
  518. ;中断表  Z! m0 E: |, ^) x1 f9 k0 o7 P
  519. .ORG $FFFA2 Z! g1 |* n; @
  520. .WORD NmiProgram
    + ^& O# V" \- v; Y
  521. .WORD ResetProgram
    ( z! {% S" {" r5 p3 {1 ]. r* x. ?
  522. .WORD IrqProgram
复制代码
1 h, h' X* r; K6 h7 M

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-10-7 15:49 , Processed in 1.068360 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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