EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    , ^! k2 Q- ]* s* j" g
  2. ;FlameCyclone 20230710
    * l) n) _1 ]( R9 A7 v( t' a
  3. % u: t- z; Q& J3 n
  4. ;文件头
    3 G9 b4 M& A& w/ Y8 r
  5. ;======================================================================& W) L7 f/ {7 q0 ~
  6. .INESPRG 4                                              ;16KB PRG 数量$ @8 B& ~: o9 ?: |9 A, B5 J+ s
  7. .INESCHR 1                                               ;8KB CHR 数量
    8 {5 y  W: _; s
  8. .INESMAP 19                                                 ;mapper 19) N: u' z3 ~+ ^# ^7 ^: M
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直$ y* [+ Q$ E/ c$ y" m3 k
  10. 9 z% K5 |0 d. w9 I
  11. ;必要条件
    : C0 U9 B. K! W4 I' W
  12. ;1.持有CHR ROM+ \9 s3 f- }" C) [1 K
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000) O' H- f5 d# e- F) Q
  14. ;3.精灵内存(OAM)不为空
    7 ^, y6 b  j1 o8 w8 k) k/ _+ `
  15. . A2 h. N% s, y" Z
  16. ;==================================================- N' c! ^/ M% w; m  @% r$ b! |
  17. ;NES端口常量. T+ l) H0 }7 N8 ^# x* y
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    : [  M" U3 X# s' O: J9 a9 D' F
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器6 H' U, {9 K# m3 _8 c# c
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    $ d9 O/ v; ^  B1 X1 [- `1 t
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1, X% M, i9 A# H$ p
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    " L) l6 V& E$ ]6 s! _2 R9 W3 k
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    % W5 w8 {% U1 J9 ]8 B
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加0 ?. G. P3 I! H
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    3 M4 l0 O" E- ~5 P+ K
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存- L4 Y( c0 ~( {4 A
  27. APU_STATUS              =   $4015   ;声音通道切换2 e. U, f* i/ o5 x+ o
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通6 b4 c! g0 ~$ M5 }4 n
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通8 G* |; c$ Z; n: M2 V0 x. X  s
  30. : g' r0 S  b% x
  31. ;==================================================
    ! U0 @, k7 r$ X/ P$ A. L5 X5 J
  32. ;MAPPER 19端口常量
    1 t2 ?3 t1 [: d$ h
  33. M19_CHR_0000    =   $8000' ]7 w+ g* Z& @
  34. M19_CHR_0400    =   $88004 F& t! j5 p! D1 X% j7 |, r
  35. M19_CHR_0800    =   $9000% J5 v! Z2 Q0 ^2 _5 F' E: K
  36. M19_CHR_0C00    =   $9800
    + t$ l+ h: T: P1 U% z
  37. M19_CHR_1000    =   $A000
    # q4 N8 z* _- r) V8 G1 \% W( s* ~: |
  38. M19_CHR_1400    =   $A800
    - ~3 h' M/ a8 e+ T( [
  39. M19_CHR_1800    =   $B000& E% V9 v' r3 ?$ x/ U6 T* ?; h
  40. M19_CHR_1C00    =   $B800
    ; }& I: ~0 o$ c5 _3 R
  41. M19_NT_2000     =   $C000" }5 n( q! @. K* d  Z  s
  42. M19_NT_2400     =   $C800* n  L4 _4 c; U- Z9 M9 e: Q
  43. M19_NT_2800     =   $D000
    - O7 Z) n9 r2 e9 A' q
  44. M19_NT_2C00     =   $D800
    5 l2 v  ]3 e" d3 R  e
  45. M19_PRG_8000    =   $E000
    - k+ _: i3 C7 M, k! T! \/ C
  46. M19_PRG_A000    =   $E8009 o1 h" Q9 y7 E
  47. M19_PRG_C000    =   $F000
    + G1 }3 E! A; Y. j# Y  w0 N/ Q
  48. M19_IRQ_COUNT_L =   $5000- r' A! h1 x& k# a
  49. M19_IRQ_COUNT_H =   $5800" W" J0 L9 k( g+ l

  50. ) J7 i! {" q2 X" K* W
  51. ;==================================================( g# O) _1 x$ @2 A% T
  52. ;程序块配置+ N+ Q0 Z! |) C( ^7 o# T' c$ o
  53. BANK_DATA_MASK          = $07
    . J# f* }& F, k, |* Q+ k- S5 P
  54. ;--------------------------------------------------
    1 h) D3 }6 A% ^5 g. D. ~
  55. RESET_BANK              = $07! a2 E3 s( q" K% g( w* z1 j
  56. RESET_ADDR              = $FC00. p- W8 W0 A/ k  y* x

  57. ) q1 m8 I# i/ r0 ~& S" T$ j
  58. ;==================================================
    $ G) h9 T- y+ i8 q4 Q( N7 ]* O) Y  w
  59. ;图像块配置- u0 C5 K- K. v5 V6 B
  60. CHR_DATA_BANK           = $08( l% U/ v3 G4 Z( `' P/ h; r

  61. - j4 Q' g+ m8 I' {
  62. ;==================================================/ X3 O/ J1 }: M: }$ L& V
  63. ;零页内存地址配置& o0 f. y$ B- j  E# E
  64. Use_Ram_Addr            = $80
    2 _1 b) u* i& J. E
  65. PPU_Ctrl_Buf            = Use_Ram_Addr+ v2 t  K) p6 z5 a3 |' f
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $019 w2 n: c: l1 t& T3 p
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01  ?- r4 N( `7 {$ p% N; F& @
  68. PPU_Scroll_V            = PPU_Scroll_H + $01! o/ m. H9 C( G, [$ s
  69. FC_Data_L               = PPU_Scroll_V + $019 S+ K1 e5 y( i6 a: c  [
  70. FC_Data_H               = FC_Data_L + $01
    ( U' {; ^* P; h
  71. FC_Data_Buf             = FC_Data_H + $018 K6 e/ N$ y* V; B' B$ B1 a
  72. ;==================================================
    % E8 F: t+ y4 Y* U# ]  o* |' i2 M* h
  73. ( j( R& E  f  g- @
  74. GAMEPAD_MERGE_FLAG = $04
    8 g& x+ \. ~9 ^1 l3 B- |) |5 L
  75. 4 t8 Q! r. s8 E- a
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    + i6 f+ j: s) O
  77. Gamepad_Once            =       Gamepad_Keep + 2
    7 v7 U# c  ]9 G& A; y8 S7 b
  78. Gamepad_Temp            =       Gamepad_Once + 2
    7 w, i! }9 m7 ~
  79.                                 $ A( J7 o& e# W- w! Q! e
  80. Gamepad_0_State         =       Gamepad_Temp + 2  b+ l: h' l! x" o( d4 w! F
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ; C; }- ~8 a6 r' u8 g/ R
  82. Gamepad_0_Value         =       Gamepad_1_State + 13 l; W0 Q: T1 {) X7 E
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    7 `& W1 A+ @) p, R7 O
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    4 \: ]+ c; k$ z) j
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    % x' W7 r1 m8 }# n6 |0 |

  86. 7 F* N. b& F2 d& ^3 b9 u+ W
  87. ;==================================================
    / V8 N2 T9 U9 @! u% f% x$ L
  88. IRQ_Index               =       Gamepad_Merge + $01) `( {7 Q; H! x& V+ |; f8 H
  89. ;==================================================
    . L) d- A' V3 q5 {
  90. $ w# f+ G& @! `* `+ u3 S! b( n
  91. ;CHR图形数据& f; c! L; Q" S0 {' C8 E, w" V
  92. ;==================================================: T3 q: V1 B( g3 J1 L) {
  93. .BANK CHR_DATA_BANK$ [1 _' D, ]( m
  94. .INCBIN "chr_bank/chr_data.chr"* E1 O* O3 }# j$ h  P" d( T
  95. 1 [: s. B% A2 n/ B4 g
  96. .BANK RESET_BANK & BANK_DATA_MASK
      G) V& h( p2 f. }
  97. .ORG RESET_ADDR
      \  F8 t$ g" W" B5 S4 O" g/ Z
  98. & b3 j/ I) E! X* q( v) q5 f4 \* k& |
  99. ;--------------------------------------------------  t8 F( V; k9 k6 w2 x' B' G/ J
  100. Attributes_Data
    + u- z6 n  _! B3 h
  101. ;命名表属性
    8 i  t+ S5 a" r
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    7 U% k/ A5 o9 l9 S
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA; Y' [8 r- M( f$ n( `9 ^
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA( A5 {% R: p/ e2 X% @
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55& y8 h9 u. z1 [
  106. ;--------------------------------------------------
    . M' `% z& }2 C7 h. @4 l) h
  107. ;调色板数据" ]' L: y4 R6 d+ k/ {' M5 T
  108. Palette_Data
    2 M4 h3 g# `" ^: `0 k
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F* [4 G9 C3 h1 C( ^& m1 K1 f
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F: b! j& ~# p& D
  111. , w/ C- g' s" t8 ~; q# }# I# Q
  112. ;==================================================+ T& \% V3 e- f! F
  113. ;命名表初始化6 F% s$ L2 F0 f" n  V5 b' ^
  114. Init_Name_Table5 Z6 u  \) v/ g' ~! K
  115. LDA #$20
    8 q0 c8 B! _' F0 \& t5 E
  116. STA PPU_ADDRESS2 O, |' ?" p* y- S( u
  117. LDA #$00$ k* J4 T9 [9 x
  118. STA PPU_ADDRESS8 N0 U: x8 \& _( y" n+ R( @! n
  119. LDA #$00
    ; ~- b% \6 U) T/ e, @
  120. LDY #$00
    , d2 k1 R! _8 I. P% t/ e
  121. LDX #$10; t+ T9 H4 B. Y; k6 @
  122. Init_Name_Table_Write8 `9 _) J7 g0 Z1 C- `: O0 \
  123. STA PPU_DATA
    2 x8 y, I! `7 ~3 x
  124. INY
    & u# t. m- F, _7 }+ G8 ~4 H
  125. BNE Init_Name_Table_Write
    4 {  j2 @5 e+ E2 f6 _
  126. DEX( Z6 d' h' U; R
  127. BNE Init_Name_Table_Write0 p1 l8 Q$ y% O$ h  g
  128. RTS& b! k- `" I6 N1 {3 H- @
  129. # Q( R( ?) m1 ]% |& e# B
  130. ;==================================================6 R2 x: E: E. J. x, Q) L+ Q
  131. ;调色板初始化
    5 b2 \8 u0 H: S2 W
  132. Init_Palette7 V" X' v: Q; q  k0 A! R
  133. BIT PPU_STATUS
    $ c  p8 B* i$ F- B* T3 L. U; d
  134. LDA #$3F
    + X( V5 q, p3 T5 f
  135. STA PPU_ADDRESS4 r/ @0 @% E, p0 P  V" u
  136. LDA #$00) R% c+ d6 u  a1 u$ s2 T
  137. STA PPU_ADDRESS
    # ^4 n9 K( o$ ]9 U4 t
  138. LDX #$00* ~: J, `- s( \+ e4 E# e
  139. Init_Palette_Write
    $ f) a  h9 |# J' `% Z+ o* Q
  140. LDA Palette_Data,X9 z* j, r/ c: s
  141. STA PPU_DATA
    * K- t/ `; r) C6 }4 Y2 o8 R
  142. INX
    * U! U4 o* N% @/ Q- V
  143. CPX #$20. d2 K& A7 k* Y: I! c* n9 A
  144. BCC Init_Palette_Write" g9 j  F$ F& c# g8 O# t$ b
  145. RTS. m, W0 u5 `% s; p: Z# z

  146. ; W8 d$ o$ q: X
  147. ;==================================================
    6 s% F% `, m9 l8 \
  148. ;设置命名表属性  D9 @$ t, P4 W( b
  149. Init_NameTable_Attributes$ r  K0 V( j- _% H  y, H# q
  150. BIT PPU_STATUS+ U3 F! o: L: Q/ o- F* i
  151. LDA #$23
    + V) J" t9 _, k. P" L* D( s' ^
  152. STA PPU_ADDRESS
    5 @  R/ Y' _6 o& s' w/ I
  153. LDA #$C01 {6 b# q0 r2 C8 u. E
  154. STA PPU_ADDRESS1 H. f% Q, @! `% g7 V
  155. LDX #$00$ X5 I# s$ h4 f% |3 J* R6 a
  156. Init_NameTable_Attributes_Write$ h; ~4 Y% V: T5 q, K8 N' V5 {+ [- R
  157. LDA Attributes_Data,X
    8 m0 C5 @$ M! }
  158. STA PPU_DATA; T4 }. y0 _$ J( {! S# U
  159. INX0 U4 N! @$ x2 W7 B/ h5 f
  160. CPX #$409 {5 y5 e/ X+ c. O8 j8 ^
  161. BCC Init_NameTable_Attributes_Write
    & j! p, f7 E$ j7 }4 Q. H
  162. RTS
    & o" K1 a2 y! X6 z, T2 d

  163. $ D! g8 ~, V' E5 F
  164. ;==================================================
    9 g9 k' j, T9 g$ X) x1 H
  165. ;初始化命名表文本/ F. H7 u% N$ m) t9 c
  166. Init_Name_Table_Text
    $ R: ]8 c* N9 \% m1 y
  167. BIT PPU_STATUS
    3 V- E, H* [% B9 R  J: h* }) K. {; J: ~
  168. LDA #$20
    + t3 A- t4 }& Z. g
  169. STA PPU_ADDRESS
    6 _! r# R7 i5 o9 i
  170. LDA #$00
    + o4 V: s4 t1 f, G2 M
  171. STA PPU_ADDRESS
    ' j# X! R8 p9 p8 Y; |5 ~* g
  172. LDA #$00
    # s6 k7 q2 t, {4 `: Y( ~3 H
  173. STA FC_Data_Buf) {$ _) H: ?  v7 a+ I8 C
  174. LDY #309 W: J* g- }5 g! ?9 Z1 H
  175. Init_Name_Table_Text_Write$ x) t0 `/ o# e# E% e
  176. LDX #32% G9 y, f, O; Q  S
  177. Init_Name_Table_Text_Write_Char  F; `& D( w5 f- \- B4 I
  178. LDA #'0'
    ! u- m5 j  ~' r$ ^
  179. CLC) D5 b, T$ ^- W0 M: w8 f+ ~
  180. ADC FC_Data_Buf8 Q; q1 m8 l4 j" E3 G. }; ]
  181. STA PPU_DATA
      b2 `, J9 e- d4 _7 j; S, i% j
  182. DEX
      z, T& r7 Z' o; |/ P! v
  183. LDA #$14, d6 F# i5 u$ h+ r( R$ ]3 @" m8 p
  184. STA PPU_DATA1 Q) S/ k, N) g' n
  185. DEX
    $ \1 t) h- o3 w' S
  186. BNE Init_Name_Table_Text_Write_Char
    3 D5 q# Y& l. W) a
  187. INC FC_Data_Buf0 B8 J2 v7 c6 ]! B( d
  188. DEY
    & g# f4 S( p7 u# T
  189. BNE Init_Name_Table_Text_Write
    ( e* Q3 z+ G. i: [5 I- ^
  190. RTS
    7 P# ?6 u1 k+ k/ D' W

  191. 6 V$ s- F. ^3 Q! [1 S$ y% |
  192. ;==============================
    + j7 r' ]& }/ T) a
  193. Init_OAM_Ram;初始化精灵内存! c- H6 Y/ {. u+ t- W
  194. LDX #$00' `/ K- N4 H7 H* y' K7 ]) a9 V
  195. LDA #$00
    : N3 e$ d# k4 f
  196. STA PPU_OAM_ADDR
    - u+ Z$ Q4 K- x- r; S
  197. LDA #$F8
    ' M/ B2 b! \# J
  198. Init_OAM_Ram_Write
    6 O6 Z/ s: b( v) a3 ^
  199. STA PPU_OAM_DATA% s+ ]3 e9 E# @* L
  200. INX
    ( _  j  V2 ]/ L" S1 E
  201. BNE Init_OAM_Ram_Write4 U+ J' r) S& c6 |3 r+ ?
  202. RTS3 p2 ^, W+ ~- v0 w

  203. 5 u* ]9 w6 e: o  d
  204. GamepadProcess;手柄处理
    5 m0 Y" t$ p: g2 h, c/ n2 X
  205. JSR GamepadDatacan1 T0 U/ }# @! J
  206. LDA <Gamepad_0_Value1 t4 @% t4 p$ K' y* S" B( K& L
  207. STA <Gamepad_0_State; J; }4 \3 {: ]7 e
  208. LDA <Gamepad_1_Value5 h  Z7 ^1 D( V9 M; [4 v
  209. STA <Gamepad_1_State
    - e  T, U" ]& f$ x
  210. JSR GamepadDatacan- [, H8 E' }: V* [- [( }$ T' T
  211. LDX #$01
    ; ?% @. l3 c$ G  R- a
  212. GamepadMergeCheck;合并手柄输入检查
    ) M5 ~. G! B3 Z
  213. LDA <Gamepad_0_Value,X
    ! K( S* }+ N! F/ ^; d" ~
  214. CMP <Gamepad_0_State,X
    ' d% c' d( a: Q, M2 b0 m0 M
  215. BEQ GamepadMergeInput
    - h% c. ?6 C, x, U2 I4 S
  216. LDA <Gamepad_Temp,X
    7 Y$ q8 l0 `; }
  217. STA <Gamepad_0_Value,X1 e' c4 J- m5 \( _$ G
  218. GamepadMergeInput;合并手柄输入) G. n* o6 @  |  a1 o2 ~) G0 \
  219. DEX' R2 {5 g0 V3 W" t' r
  220. BPL GamepadMergeCheck
    4 q; C3 [# _9 `9 p# j
  221. LDA <Gamepad_Merge
    8 O( E# }4 Y' L6 t" n
  222. AND #GAMEPAD_MERGE_FLAG
    * I. ]& E  S- |" _" \5 c) x2 Q
  223. BNE GamepadStateProcess
    - s# n& }9 I" c4 K
  224. LDA <Gamepad_0_Value
    ) b8 S! z: r0 R- C
  225. ORA <Gamepad_1_Value# J$ f( Q" i6 l$ D( Q
  226. STA <Gamepad_0_Value
    7 A- _8 }$ L$ k+ n  g  V* `
  227. GamepadStateProcess;手柄状态处理1 C8 z3 ~' E7 T3 s  ~7 o7 m1 h
  228. LDX #$015 p: B# _( ?% w4 I, d. h
  229. GamepadStateSave;手柄状态保存
      e. ~! v$ m5 q5 L' R9 Q0 }% f7 ~; X' G
  230. LDA <Gamepad_0_Value,X* P7 R$ Q  j2 P
  231. TAY
    5 t& o. b8 F, A9 m/ `6 s5 u
  232. EOR <Gamepad_Temp,X7 q' C! d4 z7 T( W
  233. AND <Gamepad_0_Value,X
    9 d' N+ a1 \9 I0 g5 h& J% f1 u
  234. STA <Gamepad_Once,X" ?2 P+ R' ]" t! |
  235. STY <Gamepad_Keep,X+ p8 ^4 j7 y8 u$ B
  236. STY <Gamepad_Temp,X
    0 w2 t3 e/ \( y
  237. DEX
    6 V2 O+ k  C$ K2 F6 n4 Y; z9 Q! [/ o
  238. BPL GamepadStateSave
    3 t) W( |7 W* b4 B
  239. RTS
    2 W! W9 x! N# a. o  q- G8 \

  240. 0 M% S8 C7 W: D! o2 L
  241. GamepadDatacan;手柄数据扫描
    ) U7 L5 `% u- g9 n6 e- r
  242. LDX #$01. ^; t: w: |& d
  243. STX $40166 B: I+ u8 c  U2 Z1 r, E
  244. DEX
    ; ~% U, A" ~# e- Y2 l& m( O2 \* \. G
  245. STX $40162 {, j9 O. q6 f7 t0 B
  246. LDY #$080 L% k$ c/ X1 H( m6 I
  247. GamepadPortScan;手柄端口扫描* W3 w  u8 m: x/ n2 h( ~
  248. LDA $40164 O( C- u. L; L1 K
  249. STA <Gamepad_Port_Value. `7 _3 R) y( R2 U2 S3 J3 h4 [
  250. LSR A! h+ |+ h: T  J9 t) G( _
  251. ORA <Gamepad_Port_Value" S' x! ?" s6 j$ n
  252. LSR A% E2 X, r- M8 n
  253. ROL <Gamepad_0_Value) @  Y8 E1 K, C; t5 o
  254. LDA $4017& J: U" A6 ]7 T1 L8 Q) Z
  255. STA <Gamepad_Port_Value- _$ L* _, w' C' G. k
  256. LSR A
    8 j7 \' ]% P5 ~( D8 Y; k
  257. ORA <Gamepad_Port_Value4 m" E) z3 a6 P/ o6 ?8 e2 E
  258. LSR A
    , ^6 I1 j) ~5 d* T
  259. ROL <Gamepad_1_Value: [) Q; {/ |5 R& P
  260. DEY) I& n, m; C+ i6 B, F
  261. BNE GamepadPortScan
    * I" X0 S1 I' A- t
  262. RTS  f' O, e0 ^+ a) w9 h9 K+ @1 |
  263. 7 P2 S  i" s2 C) T" \5 F2 h- {1 U1 Y
  264. ;==================================================
    6 H1 v1 }# L$ M1 J
  265. ;PPU处理$ `* g9 {& J6 `  L4 [4 |
  266. PPU_Process
    7 L; C$ h2 m  q- ?% G: |6 A5 h
  267. LDA #$00
    ( C/ d# P' x! C$ [
  268. STA PPU_MASK
    & H* @) G  U8 z* O" t" ~

  269. + I# H6 y! m. _& \" D
  270. BIT PPU_STATUS
    / [# P* V5 }, |
  271. LDA #$202 Z/ T7 h4 J) Z. U
  272. STA PPU_ADDRESS- X+ a' C8 i, E. \" o+ F: n
  273. LDA #$00
    7 t* E/ L( G' J* ?% h8 l; U8 ~
  274. STA PPU_ADDRESS6 u* r+ f' @. n  ?* T' i

  275. " r8 h3 z* a, G; P1 _( Z( x
  276. STA PPU_SCROLL$ Z, S7 a) _, F# O
  277. STA PPU_SCROLL) O4 l0 R, O$ V+ E' M
  278. 6 G, k2 i; J5 _0 r. ?
  279. LDA PPU_Msak_Buf
    * F! z0 F; G! E+ m3 P' X$ G
  280. STA PPU_MASK  u2 k) y! T2 T9 q9 i/ _

  281. $ w8 B+ O+ q# I8 w. g
  282. RTS
    8 l3 z* b+ R4 C& F9 V" W# H

  283. 0 R" [& w8 Y4 A2 B
  284. ;==============================
    " F, e& A7 p  ]. N& f2 O
  285. Time_For_Vblank;延时等待1 U. `. e/ j7 J
  286. LDA PPU_STATUS
    1 C/ s$ `, I, G- F
  287. BPL Time_For_Vblank
    6 |# T8 o0 e+ o
  288. RTS- ^' K" \, U* O6 j; R' t7 |

  289. - H! f' w4 p- n0 p* R
  290. ;==============================8 J. R8 G  k( j0 }, f
  291. ;初始化MAPPER19
    . \1 P' H3 T8 k# n/ f9 _' {2 A
  292. Init_Mapper19
    ' t+ b* q: k" C, J
  293. LDA #$00
    0 z' y1 g6 t1 K3 L4 q
  294. STA M19_CHR_0000+ c4 N. j7 U' c, K: q
  295. LDA #$016 e( V4 _  j' N: |6 G7 e" L
  296. STA M19_CHR_0400( c) ?% [/ G5 S# M5 j* c5 n) v
  297. LDA #$02/ E) R# W1 g* p( e% F# s. W/ M
  298. STA M19_CHR_0800" m$ b; ?, X- ~/ _* H5 M) H
  299. LDA #$03
    5 I( w/ B  }' i
  300. STA M19_CHR_0C00
    : D6 g7 R3 S$ _$ F$ v
  301. LDA #$04
    & D) H! W! @3 a
  302. STA M19_CHR_1000( V5 g1 `. v# M- J% w* c% _. S( K
  303. LDA #$05
    5 J, P7 f7 b3 _( h4 |% x4 j1 ?
  304. STA M19_CHR_1400
    0 A. n: q  [1 z( |2 M. \3 S& W8 p( Z
  305. LDA #$06/ h3 j$ ~7 w: Z2 \
  306. STA M19_CHR_1800+ z8 j% ], V! m+ E( R5 {
  307. LDA #$07
    ) @. h! C' T& r, t
  308. STA M19_CHR_1C00
    2 J: V# I9 G0 A1 G" ?

  309. : b8 R- `, F8 f" Y0 q4 U( L0 s
  310. ;禁用IRQ
    8 s( L5 }7 O) t
  311. LDA M19_IRQ_COUNT_H4 F4 S) Z% c+ N  A2 [
  312. AND #$7F* U$ d9 ^7 V# Q7 X' Z
  313. STA M19_IRQ_COUNT_H; a" h3 e* }) j
  314. + n# x* @& m2 g; I( ]
  315. ;命名表" ^7 Q  ~6 f- [2 M5 ]3 K( b7 k
  316. LDA #$E0% D% {; b7 q" D; Y2 t
  317. STA M19_NT_2000
    ' L" j% H* Q+ z* H9 n2 t
  318. STA M19_NT_24001 \6 f- C  q7 l( y) Z$ p

  319. " `; u9 T6 _4 ]2 n
  320. ;命名表
    ; `/ _1 W3 [" n3 N
  321. LDA #$E1
    $ W0 z( N  Y& D
  322. STA M19_NT_2800) D" c4 v7 O& z) {. E
  323. STA M19_NT_2C00- ?, U* |, h7 N6 Y. Y1 F

  324. ' L3 S& g# }4 h  Z% B
  325. RTS  A: K: S/ Q4 u$ s
  326. % ~, N0 r/ K. s% i2 P
  327. ;==================================================
    * M8 u: k8 P2 y# Z7 P3 e, h6 s* H
  328. ;重置中断处理
    - b+ f8 d4 j+ f; S
  329. ResetProgram
    ) a. C2 n7 R' e8 ~% ?+ m
  330. SEI
    ( c% m( W" R) i( T. n# y
  331. CLD
    1 U0 ^7 c9 V& C1 ^, z& C* _
  332. LDA #$00& `$ B& c5 ^2 c; U3 U
  333. STA PPU_CTRL3 f# a% E" J% e! L* E& j
  334. STA PPU_MASK
    ) j; G! J, l8 U- S+ ^4 p3 _
  335. STA PPU_STATUS
    % J7 d; C% V% n% R. Q9 z* X
  336. STA JOY2_FRAME1 N& J5 v3 E) [  _* t
  337. STA APU_STATUS. Q* S4 k. u, u6 R9 `( q4 `7 v
  338. 5 j7 [) [' \. i9 G% n# a1 f5 `
  339. LDA #$C0# m' P' B- z4 j3 ?) ~* f( O
  340. STA JOY2_FRAME4 O' ]1 k3 y# p* a4 ?2 z
  341. 0 m( `4 i, A0 P7 A9 i+ v
  342. ;等待vblank+ P8 J8 S) C+ }* h* B, n
  343. LDX #$02& i2 v+ E5 m( J
  344. Vblank_Wait_1
    ) @5 r! l+ k9 e2 l& @4 g/ c
  345. BIT PPU_STATUS8 ?0 l1 ?3 \0 U8 R
  346. BPL Vblank_Wait_1! `- a, f4 O8 a) S8 ~
  347. Vblank_Wait_2$ s5 `4 m4 S; `" a7 J
  348. BIT PPU_STATUS
    . B. r$ j/ U/ {( i+ J0 l3 m
  349. BMI Vblank_Wait_2
    ( }- Y8 t# I2 ~7 s) j
  350. DEX2 J* m- }6 x) F- r- a" L/ Z+ s
  351. BNE Vblank_Wait_1
    : Y% M' \% |2 s7 h3 T
  352. 0 i) E5 c: i6 S; @( A$ E
  353. LDX #$FF
    - D/ E7 }9 _* U
  354. TXS
    ( E: u7 L( r% m0 z( A0 p" k+ Q' u

  355. % |: g; c, m% F7 Z9 Y0 Q
  356. ;初始化MAPPER19
    9 X( }( d! c' C5 {3 @2 X
  357. JSR Init_Mapper19
    9 j3 N, T: n6 d1 Q1 e0 p, B
  358. # @0 @& D& ?- k: E6 J% _5 w
  359. ;==============================! l) L3 C0 R6 z, V+ Q3 ]
  360. ;RAM初始化5 a# [9 u/ u/ g" @9 P
  361. Nes_Ram_Init$ J+ `  [9 o; ?+ q8 h
  362. LDY #$00: r; n* l# C3 n) l2 ]
  363. LDX #$08
    3 q9 N) s9 F% V  I' E
  364. LDA #$00$ y) O0 G9 `' t5 M( I
  365. STA <$00
    8 x. z( N5 m7 m/ B  ~
  366. STA <$01
    $ J0 N% H6 N$ x, A6 T( s$ N
  367. Nes_Ram_Init_Write  q  v1 }! v2 x# x
  368. STA [$00],Y. _. Q& f' h( Q) U
  369. INY2 ]1 B& e2 p7 R6 @  H5 z
  370. BNE Nes_Ram_Init_Write
    ) w) K0 F& M' ^* [. l& h
  371. INC <$01
    6 y/ u: n* v4 L( i" u: @
  372. DEX
    ' N) _" h) {! E5 M: [  l  r0 ~3 Z9 Q  R
  373. BNE Nes_Ram_Init_Write( H0 A0 e  i3 u
  374. 9 R- A$ Q2 X9 X4 G9 a
  375. ;初始化命名表: o9 N% o/ M1 |$ j8 y$ r7 M
  376. JSR Init_Name_Table9 h7 y3 ~% Z5 m+ W+ y

  377. , m5 I5 t* h9 Z* k5 h
  378. ;初始化调色板4 P) _  ]( s: C5 I6 O- r
  379. JSR Init_Palette
    % M$ p+ b( }) ]* E/ ^1 U, }

  380. 2 {  A6 h8 L% E1 l
  381. ;初始化命名表属性
    " D7 a1 w' [1 q" _) r! b  G
  382. JSR Init_NameTable_Attributes- c- o( p% t; s

  383. - g- q: M* T) d; j6 s* Q- O" o) K
  384. ;初始化精灵内存
    0 {4 x! S) o5 H: l% ^
  385. JSR Init_OAM_Ram' A# k8 T6 y  G
  386.   W( |- S$ F2 G5 P2 c. q6 }
  387. ;在屏幕上写点东西! R( s* t3 r3 Q; J* G
  388. JSR Init_Name_Table_Text
    5 F0 [& A* W2 J4 D, M3 _5 o
  389. & Q4 B' {+ B9 h; o9 m1 Z' J
  390. JSR Time_For_Vblank
    9 I1 ~; `/ Q% s5 E
  391. ;开启PPU控制
    * F2 L/ Z# a: d7 B6 d
  392. LDA #$A8" W5 S- q  o2 w7 E6 l% f
  393. STA PPU_Ctrl_Buf
    ) i4 ]; v' y( K, ~; |) R/ v
  394. STA PPU_CTRL
    6 _: |* f  y! o) K' j

  395. # ]/ [  t# `9 `, `- c) E
  396. ;开启PPU显示+ s+ \) A8 y# Q( q6 r: k/ F
  397. LDA #$1E; A3 d5 ?* E6 F: w0 s% D5 }9 f( ?
  398. STA PPU_Msak_Buf
    * I: L/ B: f" l' ~6 w
  399. 8 H" z& o9 T$ _& D
  400. CLI, [! j9 t3 p0 W: ?: m- E, N
  401. JMP Loop$ |) N0 c6 o; M0 _) R. |* G
  402. # x' `; v; W) x# r( v  [* w, H
  403. ;==============================
    ' o( h8 h( g+ Z: I* k8 y
  404. ;死循环, 等待NMI中断
    : p( H; ?3 w7 b5 O$ M! J
  405. Loop: c* l4 V  l, D" L  w3 b, V
  406. JMP Loop5 J: A& ?4 O; W+ z0 z+ b" B$ J

  407. ( \6 }, y  A7 b2 c
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    8 c( X7 a( |- b# q

  409. ' I: y, {0 C1 S2 i8 @* E
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    1 j" \" t- v# B5 l  z$ h
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)) @9 U+ x4 ]4 E* U3 D$ u
  412. ;==================================================
    3 y) K& f  s$ e+ i& M: {% L, A
  413. ;NMI中断处理, O0 \4 A# `% Q: \0 V
  414. NmiProgram
    $ P9 f1 i% O! z( o- T6 D' S
  415. PHA8 u' @& h8 ?1 M. k9 N7 ?
  416. TXA, V" M3 r/ N+ l# w
  417. PHA
    1 \' c3 N, i, \" S) z
  418. TYA
    : S1 E$ E' h) `( ?+ ?: j) Q$ d& H/ Y
  419. PHA
    0 _$ g, n. X% b1 D, j5 ]+ K  D7 q% V
  420. 1 K4 d7 D4 e# S2 u' V' s5 |3 k
  421. BIT PPU_STATUS. o8 @9 h/ e+ `9 [& T# @

  422. & ^# K3 ^& T  T: G, s4 e! w
  423. LDA #$006 F6 A* y+ J4 k0 }1 a$ z/ k
  424. STA IRQ_Index% w$ e' n: j; `$ q3 y2 ], p
  425. $ F: X/ d8 w+ E9 H4 M7 r" }, M+ [
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    , ?  M9 Z, u1 v
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    + y& w8 }" l6 ]% p
  428. STA M19_IRQ_COUNT_L
    0 X( H9 a% l, G3 p' e) {' f6 X
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
      b% b7 y3 d# v! a9 D9 Y+ g
  430. ORA #$80: m0 P7 [: F" Q' p
  431. STA M19_IRQ_COUNT_H& N8 W; F: P$ r* h* E
  432. CLI. k) x8 G& C8 ]4 A0 g0 C
  433. , U. q0 a  i) ?5 S1 Q
  434. ;关闭PPU控制
    + x- Z  R6 o7 M
  435. LDA #$004 A1 y1 Y- `$ D% ]. g
  436. STA PPU_CTRL4 Y3 {0 G; G6 u6 d  ^0 U4 o
  437. 8 E2 k4 {# J7 @! M4 P
  438. ;处理PPU& C3 n3 b( _; j) ?
  439. JSR PPU_Process
    - R3 ~1 Y4 T; F- Z

  440. * v& k. ^! b9 d  [; t
  441. ;开启PPU控制
    - W- p+ e5 j/ l( ]7 `
  442. LDA PPU_Ctrl_Buf
    4 o* ~' i$ f. L1 u
  443. STA PPU_CTRL0 \0 E7 `8 P  s$ b

  444. & A7 T6 P1 s6 q0 p. \
  445. ;手柄处理! u; s: c7 [/ b9 E
  446. JSR GamepadProcess
    & K4 c; t$ w* \2 L

  447. 6 g$ m% A" n8 ~& ?6 `
  448. LDA #$00* N7 O$ w  b  r
  449. STA IRQ_Index. X& m9 E: ]1 x0 S6 X. Z& j

  450. & T* I; ~: l% }. d# d2 H
  451. PLA8 e4 v$ |. n9 B
  452. TAY$ t4 W* ~9 r0 E7 x: T! C3 o! n: B  c
  453. PLA
    1 C( c/ w. Q, m" \3 t! x
  454. TAX
    # H! U3 ~& o# Z' L& h# f3 C
  455. PLA
    7 W8 a) c, z% s) q/ k# s
  456. RTI
    4 d5 q( U" S3 q; o

  457. + f( O9 G! H$ W% v; U
  458. ;每行扫描线113.67
    2 f! A1 o. L$ o1 n8 i7 t
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    2 I4 O, E" x/ W; r3 P  j
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7, v4 L9 _) X% O  v' a3 P
  461. ;==================================================+ f! T2 q6 G, Z( m- {, ]& `8 T
  462. ;IRQ中断处理
    / Z- d  N9 @1 ?9 Z
  463. IrqProgram
    ! ~4 u: Y  S5 x: M8 e4 \
  464. PHA
    6 `- w( E" h0 g% k$ }# x
  465. TXA) |* [5 h, [! J6 a2 K: u% P' D" r; S6 p
  466. PHA6 L6 @1 |; z' E& q# l. ^
  467. TYA8 s: F  O- Z$ t, m
  468. PHA/ r* R6 @& T+ q8 d3 {$ c
  469. , j# K! D- P' r% \, M1 g
  470. ;16条扫描线后触发IRQ5 |7 J! w1 F' _/ R. a; W* p4 \
  471. LDA #LOW(BEGIN_LINE_CYCLES)! r; n3 O% m1 @! E" g' g# U% m
  472. STA M19_IRQ_COUNT_L
    8 Q% w5 ?2 z1 x, T% q( ]
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    9 E& l# P' B# ~  z! _  C
  474. ORA #$80
    6 }* N9 L4 L% n1 ?
  475. STA M19_IRQ_COUNT_H
    ' s" t5 ~) b$ T: ?* x$ Q

  476. 8 @& Z7 Y- f$ C, j+ ^0 ]: U! Y
  477. LDA <IRQ_Index& ]5 M: E* x2 H& n( q/ e
  478. BNE * + 4
    * y* L& b# ^" o8 O  P9 V" B
  479. INC <PPU_Scroll_H
    . D; g* ?0 J2 Z

  480. 7 U$ |: o# N' ^, N$ G/ P  C. t
  481. ;设置屏幕滚动
    - C# B# g/ E/ g  d
  482. LDA <IRQ_Index
    , T% B) P0 Z7 K$ J6 f5 n
  483. AND #$01
    ( ?! r0 Z7 |, `7 R
  484. BEQ Irq_Scroll_Right. R3 @9 \7 p$ p. v5 w$ \) |6 U+ `
  485. : D- I( {9 d9 t) J# j
  486. Irq_Scroll_Left
    & w( n& P4 q* y' g% F
  487. BIT PPU_STATUS$ `! |# ^4 t) i! P+ E2 ]
  488. LDA <PPU_Scroll_H$ c* ~4 I5 Q% t& P- ]9 _* N
  489. STA PPU_SCROLL
    7 J# ~6 a) S  Q  c
  490. STA PPU_SCROLL- R9 Y4 S) G* x6 |2 A8 [
  491. JMP Irq_Scroll_Over
    . @  i; o5 |/ [1 o/ p

  492. " K  L1 b# b  J2 r2 ^
  493. Irq_Scroll_Right1 {* Z1 R2 U( S* w: @- z/ [; A
  494. SEC
    3 `, i0 f. i2 _# a  n
  495. SBC <PPU_Scroll_H  C' W2 _/ `5 E: t( D
  496. STA PPU_SCROLL& ~. i$ F1 u8 W
  497. STA PPU_SCROLL
    ' o& `) G: B, q' p: \1 E
  498. Irq_Scroll_Over
    - A0 p7 z3 r6 T& E. p* [
  499. ) p' _7 w7 z0 ~* b
  500. INC <IRQ_Index3 g0 F; R  a, m2 C7 g% R
  501. ! y' x1 N; E4 z
  502. LDA <IRQ_Index
    7 J: T' a' b+ F% m* {
  503. CMP #14
    ! K6 l* h+ j& `/ [$ ~5 i( S
  504. BCC * + 10
    " h+ ~2 `+ Z/ \1 o/ x- U
  505. LDA #$00# O" r5 s. q! B1 e) }: `. y) }
  506. STA M19_IRQ_COUNT_L
    " R: D' f. E  l3 E
  507. STA M19_IRQ_COUNT_H: A+ f8 q9 }: J6 i$ |) U
  508. $ |, q1 r: x7 @# t5 W' C7 J; j
  509. IrqProgramEnd! `4 b8 G' K# K
  510. PLA
    " F3 p2 L  T# P: e$ [: {) z) n6 h
  511. TAY1 i: T; e9 c5 o( i  F9 @
  512. PLA6 \( Q4 y, E7 a% ~/ }
  513. TAX5 H8 \6 w  g' \. Y. l1 e
  514. PLA: x4 _: g: \" ?2 ~
  515. RTI
    5 m+ E1 x2 a# F8 g4 ]8 @1 ^% J' e

  516. " M6 F3 J8 }7 T" i
  517. ;==================================================+ @: w: X. h9 y' K+ x: g. I2 P
  518. ;中断表" i9 E' C, m8 v  K+ d
  519. .ORG $FFFA6 I9 A! _! y" I! k
  520. .WORD NmiProgram! d7 q. [8 X/ g
  521. .WORD ResetProgram4 Z/ W2 Q! |% L/ d$ k* b
  522. .WORD IrqProgram
复制代码
1 `4 x6 q5 r/ X; v  [

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-1-9 01:10 , Processed in 1.055664 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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