EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
      O" w# A' E3 g! B. `
  2. ;FlameCyclone 20230710
    5 @  ], a( T) N& _

  3. ) D! @" `7 x% E8 V
  4. ;文件头, D5 ~% y+ G) w- }% J/ U
  5. ;======================================================================
      w' Z4 }$ B: |$ j$ k7 @: w
  6. .INESPRG 4                                              ;16KB PRG 数量
    + ~9 d. W$ S  o8 G$ k7 ?7 w8 ~2 ^
  7. .INESCHR 1                                               ;8KB CHR 数量
    ; x1 v- d' R- I
  8. .INESMAP 19                                                 ;mapper 19& R) ?4 I: |! ]3 H. _
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
      t/ b6 b3 |- s2 m5 \
  10. 0 M3 E; a9 I& A! t5 _$ [
  11. ;必要条件. t$ V+ h& Z. n5 v9 @) b
  12. ;1.持有CHR ROM
    : K1 l; {, U' y4 |* q* |2 n6 b; I
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    4 P1 U1 ?9 E% a
  14. ;3.精灵内存(OAM)不为空$ C$ G$ ~8 s6 C- G

  15. $ I% R/ N1 F/ u. ~
  16. ;==================================================
    7 Z+ i* f9 t6 b1 m
  17. ;NES端口常量6 k9 H; G9 l! u- ~
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器* n% a+ j4 q# F. J
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器+ K7 ^7 D) f# Y7 D
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    4 i3 {. C; @( y2 q
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
      h' u1 o8 O0 k9 N: F9 h
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 s4 ^$ F- {! h% a2 c
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 . _' t1 }8 h3 g/ g$ u' K
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加. S8 M) x6 z1 [2 ^. K1 y
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 8 x0 P  U+ ?8 B( h: i
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ( Y, E* Z2 y/ O6 h' y
  27. APU_STATUS              =   $4015   ;声音通道切换
    + N7 y9 n: x( A. i
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通1 y. ^( L) x% z
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    & s6 s- R# f3 {  k& `9 h
  30. / _  V" Y1 ^- L% B: s! L
  31. ;==================================================: o) Z$ F; u! C2 q; H* [* b% j
  32. ;MAPPER 19端口常量! v& ~3 k) ~) G& w: \; ]
  33. M19_CHR_0000    =   $8000
    3 c  A* b4 C2 u) n
  34. M19_CHR_0400    =   $8800, |5 e' Y2 R' l; `  \
  35. M19_CHR_0800    =   $9000
    ) C: X: n8 S, w4 Y/ [3 x
  36. M19_CHR_0C00    =   $9800- B, r1 Z4 K4 r, @! C/ S) M5 `- Y
  37. M19_CHR_1000    =   $A000
    9 s9 m( ~" \* M9 J  k
  38. M19_CHR_1400    =   $A800
    ) R2 C+ w' `" {3 c, \" J
  39. M19_CHR_1800    =   $B0005 n: z( M# |* q! y3 c6 N6 U
  40. M19_CHR_1C00    =   $B8007 H5 x/ ^0 E& d# H
  41. M19_NT_2000     =   $C000
    ( p4 c# C3 I% x" s6 ~  p
  42. M19_NT_2400     =   $C800
    . e! O/ ~7 l1 `. ^  Q' ?1 w& P
  43. M19_NT_2800     =   $D000
    0 e$ n- c1 A% z/ U) v0 k2 j% S$ G
  44. M19_NT_2C00     =   $D800
    4 E' o- o4 }) O( W6 w8 E7 v; l( [& I
  45. M19_PRG_8000    =   $E0001 k) q0 F2 u6 [4 y& ?
  46. M19_PRG_A000    =   $E800
    1 e8 u7 r/ V3 {
  47. M19_PRG_C000    =   $F000& I  S1 R8 x$ v; U- `1 x
  48. M19_IRQ_COUNT_L =   $5000
    3 w  o3 x; M/ W' V/ Y
  49. M19_IRQ_COUNT_H =   $5800: h. N, {0 j4 {1 a0 K: d3 I
  50. 8 }9 l' Q0 N7 M. A' T( ^
  51. ;==================================================/ J+ ^6 Q0 B3 k# ]7 J- O* L
  52. ;程序块配置. u3 ?8 i; K/ k! E9 c9 u& @* F9 u
  53. BANK_DATA_MASK          = $07% ?5 d) f+ F7 j/ r& W9 \
  54. ;--------------------------------------------------# r7 a% }+ I) g0 C! I7 i5 ]
  55. RESET_BANK              = $07  ]4 p+ h+ @3 t8 {  T& S# R& J
  56. RESET_ADDR              = $FC00
    & \' J/ @, v+ @, W5 c9 m

  57. # D$ N. K$ E# o& j- I, _8 v
  58. ;==================================================5 }( d% u7 P$ K) O$ Z* `
  59. ;图像块配置& J7 S$ @3 w* B9 M3 I' }
  60. CHR_DATA_BANK           = $08. f$ M4 t8 J9 J- L4 s2 n

  61. 8 v/ m# q4 B3 {% D
  62. ;==================================================* Q6 G7 l/ }2 S& }. b  n9 w
  63. ;零页内存地址配置! e' g1 V3 N0 d+ r- I7 Q/ j
  64. Use_Ram_Addr            = $80- O7 _5 c1 W( K# p
  65. PPU_Ctrl_Buf            = Use_Ram_Addr0 }1 F- l% b$ B; _" A2 ]
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01. q+ H2 b/ B+ J
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01/ O5 [* e9 c% D: I$ D1 k3 u
  68. PPU_Scroll_V            = PPU_Scroll_H + $01% N" L3 `9 V' E4 d6 @- x
  69. FC_Data_L               = PPU_Scroll_V + $01; `: @" D% \( N4 v1 B- |; j" `5 J
  70. FC_Data_H               = FC_Data_L + $017 E. Z1 q5 \& _! T! k; D
  71. FC_Data_Buf             = FC_Data_H + $01
    $ w$ V6 S* `* p
  72. ;==================================================* s2 d, V2 G- s* j; x; I
  73. 9 ?$ m: o6 c& s/ J( x
  74. GAMEPAD_MERGE_FLAG = $04
    - A8 `0 F" v6 h: z

  75. + b2 r% N9 Q7 h) X
  76. Gamepad_Keep            =       FC_Data_Buf + 1  ~" H: [* t9 O( R
  77. Gamepad_Once            =       Gamepad_Keep + 2
    7 A" A+ o* [' i8 s
  78. Gamepad_Temp            =       Gamepad_Once + 2
    6 a& L0 W$ r% e- D% E! b7 m4 C1 t: P1 b" {
  79.                                 
    * w5 N8 ]9 @1 k! [8 s" e
  80. Gamepad_0_State         =       Gamepad_Temp + 2; t  o* @' j. F( j% f
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ) U' t: s) a7 Y- n0 Z+ r
  82. Gamepad_0_Value         =       Gamepad_1_State + 11 R  j4 d. W5 `5 w% n
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    5 c- ~3 ^9 _' ~9 A
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1- M. U# q5 L, X" F1 K* G
  85. Gamepad_Merge           =       Gamepad_Port_Value + 19 @+ j! M+ S! ]  ?7 ~/ g% j6 u

  86. $ V5 v- r0 }3 T4 u
  87. ;==================================================+ K7 z( z% a3 f! {, J+ `( j/ c. ?
  88. IRQ_Index               =       Gamepad_Merge + $01
    0 G8 k$ i6 Q7 a. j
  89. ;==================================================
    + m: G! J4 q$ E
  90. 3 e# ~3 @9 L! b' ?9 N- k
  91. ;CHR图形数据9 j& v0 c3 f- W/ Q' c
  92. ;==================================================
    9 U4 y& L5 j- d7 }
  93. .BANK CHR_DATA_BANK# R) t, X- ^, p/ B5 t
  94. .INCBIN "chr_bank/chr_data.chr"
    5 A) P+ R2 b" o. z& Q, P
  95. ' p5 x* u. O% ^
  96. .BANK RESET_BANK & BANK_DATA_MASK7 B+ R' h3 o& |9 k. K
  97. .ORG RESET_ADDR, \8 d, r) T& M
  98. . T; M1 V  F* \2 N$ t* U0 {& z. i2 `
  99. ;--------------------------------------------------
    1 E# t8 g* h+ G' ?4 a
  100. Attributes_Data
    2 F6 `3 C# `5 ]5 q1 V) S
  101. ;命名表属性
    7 x% P6 K3 [) t
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00) o* `% C0 u: z  Z; U7 q* E  F1 t# m
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    ) \+ o) y" ]& R
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA) m) N1 y+ a: `8 f' f1 Z
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55+ A1 a9 P* v. f- _' @
  106. ;--------------------------------------------------
    - o+ v7 q3 u) c+ n& _1 }
  107. ;调色板数据! `. c9 S" m6 s
  108. Palette_Data6 s! c4 t. N: D: m2 r& F% `
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    , m5 o5 q% r; V( a
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F5 q4 v% {" ^  b2 ^  h/ `: x

  111. : K- t+ [7 w" l- K- S0 q4 Y
  112. ;==================================================# ~. I+ G$ o. D$ K5 D2 D
  113. ;命名表初始化
    6 q) a5 z1 z( ^3 @
  114. Init_Name_Table
    + w, z, s  D, P4 Y
  115. LDA #$20
    - ]5 e4 y. l* S5 l! R' T
  116. STA PPU_ADDRESS
    " ]# x: j* `2 s4 `8 N
  117. LDA #$00! \6 q) _0 k9 y! L
  118. STA PPU_ADDRESS
      H% ]6 o% Q: I' v& s3 e" j
  119. LDA #$00
    + d# [9 r. d( `# Q) O; G8 S+ s; }
  120. LDY #$00  m# Y# H/ o* O+ h& _
  121. LDX #$10
    2 i; Z6 a# t4 @- `! F+ w
  122. Init_Name_Table_Write! o' B% Z  z$ q# x1 p
  123. STA PPU_DATA
    $ g! P4 g0 ^0 n# [
  124. INY
    * [; W  U0 E3 Y) Z
  125. BNE Init_Name_Table_Write* {2 T6 g8 \6 E( d3 `
  126. DEX6 a2 I: P" b; E- A9 c
  127. BNE Init_Name_Table_Write1 x( n- s& q; \& J! [" H, S
  128. RTS
    + v& T% i( B4 Z
  129. & x+ F$ K: x5 L# J$ }4 r+ U
  130. ;==================================================4 Q4 V4 V; Y! G8 Q* b5 b& d& h9 C
  131. ;调色板初始化
    , {( u3 W1 Z0 q! I
  132. Init_Palette2 V1 H7 J- s- \* l( v+ r. n
  133. BIT PPU_STATUS
    / C) E. S4 ]/ w4 S* t
  134. LDA #$3F* B+ w- q& G2 B$ A9 x- y: F
  135. STA PPU_ADDRESS) f* ~$ g! I1 F  j% P2 U* I- p7 [
  136. LDA #$00
    ' }9 e3 H+ x/ a# F0 X7 }3 Y
  137. STA PPU_ADDRESS
    ) p: a; N7 ~- Y! ?! W, D* @
  138. LDX #$00# o" m; U( c) z' D- f
  139. Init_Palette_Write2 w  i' u1 r9 M
  140. LDA Palette_Data,X
    ! Y* ^- A/ J5 h  A* O
  141. STA PPU_DATA6 P- M5 H2 T/ c' C6 i
  142. INX
    / E& ~" {' Y2 w
  143. CPX #$20: K8 w7 v# [' n$ N2 q0 r
  144. BCC Init_Palette_Write
    % L0 x# W- V+ k; S3 w7 D! a
  145. RTS
    " K$ v$ V4 {1 W5 K4 f

  146. ) W5 U9 x% ~* s
  147. ;==================================================
      P0 Q3 S- m9 S; N, N- C* J; d0 z
  148. ;设置命名表属性2 E  [0 M- E+ W% n  f- N
  149. Init_NameTable_Attributes
    3 F' Q5 G" [$ o$ r
  150. BIT PPU_STATUS& F; k! h# l% g
  151. LDA #$23# i2 \$ g) L+ P- I$ J$ Q  c
  152. STA PPU_ADDRESS7 m9 B: @1 w" W! _. b
  153. LDA #$C0' b6 R0 {3 [$ ]
  154. STA PPU_ADDRESS8 u5 B& V  v7 G+ `/ Y1 y) H( V
  155. LDX #$00( e* k6 w6 r, `& b' ^
  156. Init_NameTable_Attributes_Write% E  @( h6 R8 p# W$ a. ^
  157. LDA Attributes_Data,X6 n% u, h  z  A8 n' j
  158. STA PPU_DATA
    2 c; a4 a: M# M1 G
  159. INX
    3 F4 S9 W, W, Q$ l8 D0 D" ?
  160. CPX #$40
    9 T# s, V0 K! }
  161. BCC Init_NameTable_Attributes_Write
    0 k( r+ r4 {3 _- m
  162. RTS% Y! X; `6 s& _1 y6 t  \9 b& q
  163. 6 ^+ D1 L% f" w( v+ w$ h9 a
  164. ;==================================================7 X( m" o5 F! z! E
  165. ;初始化命名表文本
    5 o( U. P' ?6 M! H. J/ d
  166. Init_Name_Table_Text* G% ?1 G6 C) l5 F6 E( v" R
  167. BIT PPU_STATUS/ X& m$ H+ a; ~/ {) f
  168. LDA #$20
    2 G2 Q2 S* h* s2 m
  169. STA PPU_ADDRESS' i- M- |% i/ D- g
  170. LDA #$00$ d$ x, l- T& J+ a  G
  171. STA PPU_ADDRESS
    1 s. H" M6 s& V& `6 y0 e2 }$ I0 }
  172. LDA #$00. I4 X1 D4 \& E1 N1 I( u4 ?+ \
  173. STA FC_Data_Buf* [9 w" |+ P8 w7 B( n; z8 j
  174. LDY #30; G) A0 m1 d7 f
  175. Init_Name_Table_Text_Write9 ?% ?  }  O: D7 W* l  j* j
  176. LDX #32/ v/ N' E0 m; I+ M* P/ L: Z1 h
  177. Init_Name_Table_Text_Write_Char( v1 ]; t. X8 }6 ^
  178. LDA #'0'7 p6 h- S; w- V: g9 r
  179. CLC
    " ?) Y8 c( o2 B. Y9 W2 q
  180. ADC FC_Data_Buf
    7 Z2 n$ d' w! e( E
  181. STA PPU_DATA9 k" _3 ~3 U1 C7 c- s
  182. DEX
    * B" `; [; ~2 s7 \" {
  183. LDA #$14
    # W. M6 p0 @; Y4 y/ z) j7 O* s2 o
  184. STA PPU_DATA
    ( v; x$ E$ z5 u; p2 n# F
  185. DEX: y$ y1 _% w" Y$ _: {
  186. BNE Init_Name_Table_Text_Write_Char
    2 |  X1 U4 A& Q) P& ]( G( F/ t, B
  187. INC FC_Data_Buf
    ! C! P+ v0 `- \0 v5 G( E/ q
  188. DEY0 y) O# N1 U, S3 i6 [' k0 l; Q8 J' m
  189. BNE Init_Name_Table_Text_Write4 u- p: @& E1 ~% m3 L
  190. RTS  O8 G+ P% x/ b# G* ~! ~
  191. ! \; Q9 ^0 _1 i  w
  192. ;==============================# e* z# \9 n" j- A  {
  193. Init_OAM_Ram;初始化精灵内存! S7 q5 ]0 C5 i" S3 z1 }
  194. LDX #$000 E0 p- P* Q) t) G
  195. LDA #$009 |8 {) ?* `# ]# s" V' O
  196. STA PPU_OAM_ADDR( i$ O5 }) U, O! G4 C4 u
  197. LDA #$F8
    " s, t. Z, y& C' {. Z
  198. Init_OAM_Ram_Write
    , J, G3 C8 q" I( ^8 ~; Y0 `) m& h$ A8 R6 m
  199. STA PPU_OAM_DATA$ W7 w2 u  H1 U- n9 I
  200. INX1 m4 _& P9 v: m2 g
  201. BNE Init_OAM_Ram_Write$ @3 ?1 ]* D0 X0 U) Z0 |
  202. RTS6 D7 @6 Z6 g, U+ o; t# \
  203. 5 p1 `7 Z7 x0 b' ~: o
  204. GamepadProcess;手柄处理
    + U' Y% ^/ m3 d) r$ z
  205. JSR GamepadDatacan
    / T/ B! v% P' a  m+ Q& [) D4 ~; e
  206. LDA <Gamepad_0_Value
    5 W6 ?6 ~4 ?; z3 k
  207. STA <Gamepad_0_State$ m6 u. t0 r; c9 s
  208. LDA <Gamepad_1_Value; \: o, Z6 ?) N  l. w
  209. STA <Gamepad_1_State. n4 \! b' h5 h
  210. JSR GamepadDatacan. V* W0 S( A. l: J& X3 p1 A
  211. LDX #$01
    + n5 K( g; f" O/ E- {% w
  212. GamepadMergeCheck;合并手柄输入检查0 Z2 v: b' n7 h+ l5 i* ^0 a( o
  213. LDA <Gamepad_0_Value,X2 F& z: R/ a  o; e  {
  214. CMP <Gamepad_0_State,X
    3 s- P: X9 t3 j; i, Y8 a* i
  215. BEQ GamepadMergeInput
    # R; n$ N( \0 Y" W
  216. LDA <Gamepad_Temp,X2 _5 O; t% w( z
  217. STA <Gamepad_0_Value,X
    8 \7 d/ t  x; P( V' N5 }% N( W) a2 a
  218. GamepadMergeInput;合并手柄输入
    4 K! Y- X8 t. P3 Q
  219. DEX
    6 n. Y( O7 M5 E+ y1 L8 f9 W+ M3 ^
  220. BPL GamepadMergeCheck+ M) ]; U' `# Q% Z3 f7 n
  221. LDA <Gamepad_Merge
    8 Z4 c4 E6 I1 F" y
  222. AND #GAMEPAD_MERGE_FLAG
    : N8 B9 w6 Q( m% O
  223. BNE GamepadStateProcess
    : T0 E) u9 U5 @% K
  224. LDA <Gamepad_0_Value
    5 l/ o  }: l% C4 w
  225. ORA <Gamepad_1_Value
    2 R2 d+ u6 X/ L+ Q' m/ u, l' O
  226. STA <Gamepad_0_Value( H5 l3 }8 f2 \3 a' b4 H' k; y
  227. GamepadStateProcess;手柄状态处理
    ' F& {; Z( l; r7 i/ s/ C+ y
  228. LDX #$01+ W5 ?! v% X/ V3 ^% e8 J: E% m
  229. GamepadStateSave;手柄状态保存" p: s4 t: x7 P% [# C2 s% v. \
  230. LDA <Gamepad_0_Value,X  P+ F& f( \% Z) G; D
  231. TAY) i1 i" w% C: T9 V: l  u# ~
  232. EOR <Gamepad_Temp,X- f, S) |& y! Z1 O! l5 c# ]
  233. AND <Gamepad_0_Value,X( }2 ^* E3 S6 {8 U- M
  234. STA <Gamepad_Once,X/ v8 b9 l& x# J; }
  235. STY <Gamepad_Keep,X# \  ?1 [! H- @0 L$ B4 l
  236. STY <Gamepad_Temp,X; G: n9 K7 d9 S6 u5 g# n5 s, g
  237. DEX! {3 V4 a  |& F" H
  238. BPL GamepadStateSave
    & s! s0 y3 I: O+ j+ i
  239. RTS
    5 j4 `+ f8 j  i2 g5 {
  240. : X4 m7 C& Z& c+ u* f$ c
  241. GamepadDatacan;手柄数据扫描( e3 A( p# Z& P! y, z- x
  242. LDX #$01
    5 }0 ?2 W+ O1 P* R4 |) Q: e
  243. STX $4016  r# g( I6 y4 t4 b. Z; }
  244. DEX, ?: g9 k- r3 X# m
  245. STX $4016
    $ W; c9 y( u# V+ E
  246. LDY #$08
    9 B) p. ?% _8 T2 F( v1 c9 V
  247. GamepadPortScan;手柄端口扫描5 c& S( t- L+ g8 n) E# d( j
  248. LDA $40169 l, z% g* Q7 L- o# u- ^
  249. STA <Gamepad_Port_Value9 z; m: w0 r7 y* ^# C9 d, s6 j: c! r/ H
  250. LSR A) Q1 b( ~0 w& Q
  251. ORA <Gamepad_Port_Value8 ~& p: n' I5 A- G, n. r# c" m
  252. LSR A3 d2 O) ~2 O5 |: I/ l
  253. ROL <Gamepad_0_Value" x% ?, E# {# ^! e* ?
  254. LDA $4017% i' c4 V4 V. {$ D0 u6 t
  255. STA <Gamepad_Port_Value
    1 a% O2 F8 w# U
  256. LSR A  f- Z+ F3 |: M# D' M9 L
  257. ORA <Gamepad_Port_Value
    ! l& V) ]# e; x, z& s+ T
  258. LSR A
    8 {% z, f, G7 t( p! _2 R
  259. ROL <Gamepad_1_Value/ b& x* G5 b9 m4 z/ C, z4 K
  260. DEY
    ! I4 F0 Z4 r$ i- h
  261. BNE GamepadPortScan
    / b8 I) M# z3 x  _
  262. RTS
    $ D" a4 K3 \3 ?( @

  263. 2 l8 o) f6 ?6 X
  264. ;==================================================! Y* S4 ^+ q3 V% g/ G
  265. ;PPU处理
    . r+ T  U/ M& \4 r3 |  o( n
  266. PPU_Process
    ' d, Y- @9 Y3 B" W! D& U5 a
  267. LDA #$00
    - v/ ^- R) l" I/ P! |6 X% M% T
  268. STA PPU_MASK
    ) A% g6 D3 G* ~( h0 L9 z

  269. 3 }7 Z1 @( t: W$ l8 ^
  270. BIT PPU_STATUS6 _" A4 r: U* @+ P
  271. LDA #$20: H+ D! |& \/ |* R+ i
  272. STA PPU_ADDRESS
      [3 b2 D- T3 Y" Z/ Z& l
  273. LDA #$00
    & c! Y" s. p2 r! Q
  274. STA PPU_ADDRESS
    ; @  J4 l3 r  J0 k2 u  m

  275. 9 j! L, |) J1 [- ^! n
  276. STA PPU_SCROLL
    0 P( [3 M0 N: |3 v  J
  277. STA PPU_SCROLL8 i  B, F( h: B, v9 r
  278. : b, Z( z" z/ h
  279. LDA PPU_Msak_Buf
    4 |1 ]: ?; f% n& E' a
  280. STA PPU_MASK) C& k/ g' y; b/ G' {( ~3 F/ i

  281. ; \8 v/ Q' I" p
  282. RTS8 Q) |) f6 ?  J! ?

  283. ( ]* ^) k5 i% A' r! m
  284. ;==============================) R: E* i/ E, F
  285. Time_For_Vblank;延时等待/ B9 l0 y" r' L  O- Q
  286. LDA PPU_STATUS
    0 f' ?) c* L9 y% ]* n9 I
  287. BPL Time_For_Vblank4 g$ Z$ k9 \7 c' N, W' u
  288. RTS9 U" _  Y5 ^3 A  X

  289. # U! A4 W0 v+ {+ x
  290. ;==============================
    3 T! L8 Q1 P1 K
  291. ;初始化MAPPER19
    # C! m6 q  a" _8 }2 c/ @
  292. Init_Mapper197 u! D2 G' T+ g; ?& e
  293. LDA #$00! L5 z$ U7 r: w" q2 n8 Q$ o4 ^
  294. STA M19_CHR_0000
    6 |' g8 {+ y/ o) X0 }' s, _
  295. LDA #$01
    7 T7 ^) u) }; [& |4 b: q' p5 F
  296. STA M19_CHR_0400% I/ o! }  i+ c0 j, O& K  R, X% i
  297. LDA #$02
    2 L6 L( ]" N9 h+ q# {7 l
  298. STA M19_CHR_0800
    / z& p6 N. y  O
  299. LDA #$03
    ! S( W0 |' A0 X/ ~  B. \# ?# O, I1 D
  300. STA M19_CHR_0C006 k  L6 |2 T! _: R# h# W
  301. LDA #$048 M5 P. d; R. r. O( e- t. H
  302. STA M19_CHR_1000
    8 a: a7 p( I' q+ ~: v
  303. LDA #$05
    1 a/ y4 d! E, u1 p
  304. STA M19_CHR_1400% R- z- l; P* _$ p! I
  305. LDA #$068 [- r7 [: q' }# N5 S) D
  306. STA M19_CHR_1800
    : j* f( Y7 E! w( {7 m; g% F& J; U7 L
  307. LDA #$071 x% K) G3 H* R1 B
  308. STA M19_CHR_1C007 @9 \: [9 M3 a/ D7 O7 s
  309. 9 `( S$ d& d; G+ p4 j. r" z
  310. ;禁用IRQ
    ! H( k7 W) C* X; y
  311. LDA M19_IRQ_COUNT_H
    9 P" j3 T' f) i0 a* ?! S3 W$ O
  312. AND #$7F
    4 |5 Y( L+ A! D6 C7 T2 n7 N4 q
  313. STA M19_IRQ_COUNT_H- f8 ~3 z$ c4 t
  314. + ]1 O/ }+ Y; ~0 X# e# ]& E
  315. ;命名表7 A& ~% P8 m; g2 t0 x
  316. LDA #$E08 x( y) Q7 y2 I" R/ j2 x8 U. I# r
  317. STA M19_NT_2000
    ! L- J; M$ w' D  S3 c
  318. STA M19_NT_2400
    8 Z$ J- |- I7 E7 I' L* q% R
  319. 0 R5 i6 h! D( H9 n! o+ y. B8 F
  320. ;命名表( j' R3 ~: @" o0 {0 S5 \5 }
  321. LDA #$E1
    4 w# _+ \' O8 ]6 i; l" m: q) G: V
  322. STA M19_NT_28004 `2 n9 p: f$ A' V' u
  323. STA M19_NT_2C00
    * K4 P4 b* Q6 M% j! K  }8 s

  324. - f& v- y" _4 G: f4 B
  325. RTS
    ! f6 U) o: S. }; A

  326. 5 }" l! z3 P$ f
  327. ;==================================================
    6 t4 C; }: `; Z
  328. ;重置中断处理0 H8 Q# F1 ?0 s: B
  329. ResetProgram; U8 D. U) U' ?( M
  330. SEI
    , \3 I$ d" ]- g# g9 P/ p9 t
  331. CLD
      h( e+ T- P3 M& x8 K2 L2 n/ G
  332. LDA #$00! F+ j9 P, _# q' _
  333. STA PPU_CTRL$ h, p9 j# J" j' ?
  334. STA PPU_MASK% O% d. e* \  T3 h& z  h! [
  335. STA PPU_STATUS
    . H8 V2 ^: }  U( f, L1 @
  336. STA JOY2_FRAME
      p; M. F) Y5 u. n5 g, y8 a
  337. STA APU_STATUS' j* S4 B8 i6 _! f( p

  338. 0 J8 W8 U* s: P% u, f) B2 p7 u2 A
  339. LDA #$C08 |/ i6 J- j* O- o8 I" f
  340. STA JOY2_FRAME# ^' U: u1 T) N4 X2 H

  341. / F& J" a  N, Q
  342. ;等待vblank& ?  j, e% b& o+ P
  343. LDX #$02
    5 ^3 n0 x; L* M
  344. Vblank_Wait_1
    2 Z2 x2 R! v6 P7 |0 Z
  345. BIT PPU_STATUS
    2 b; |) x$ o; n  @
  346. BPL Vblank_Wait_14 P) i: w: f6 U7 S* [; z" ~. A$ E
  347. Vblank_Wait_2
    - [3 R8 z9 i# x; W
  348. BIT PPU_STATUS1 X6 _7 N8 q/ Y) k  }4 f3 z( D7 s
  349. BMI Vblank_Wait_2' d8 E) ]$ ?% \8 U1 V
  350. DEX& Z/ m7 B1 R+ R1 w
  351. BNE Vblank_Wait_19 g! m. Q2 Z8 q2 O! R

  352. * q3 q- I% \- I: V
  353. LDX #$FF
    1 E  ^2 \2 X: u- G; o, _
  354. TXS8 P) m& p% i9 O( z; K) S' s) t4 l

  355. ! X9 y! @' t/ Z, r
  356. ;初始化MAPPER19
    - J2 q! K2 [. w# i3 t8 b5 R+ j
  357. JSR Init_Mapper19
    1 O% t% _' g% z4 |! C& l5 L0 P

  358. 2 r- M4 ~! A6 y0 a5 y3 r) P- N
  359. ;==============================& \+ j( ]% ~' r' }
  360. ;RAM初始化" H  l) z# b6 h8 j" \
  361. Nes_Ram_Init
    ! J9 y) \6 S! q& D% |4 L) r
  362. LDY #$00
    1 o  I' r2 |. S/ u$ K
  363. LDX #$088 F3 Z) U% v' C! |$ `8 B, G
  364. LDA #$00
    % R  E0 S% j8 C( [% F
  365. STA <$006 J+ L# w2 d, T. S' g& ^% Q
  366. STA <$01
    3 F2 P( J. V$ ^/ O" i
  367. Nes_Ram_Init_Write
    ' D% ]) L  s  }' U) o4 R
  368. STA [$00],Y
    ; a3 U2 C% @* K. ^0 I$ j+ j
  369. INY
    + Z  \6 q$ N8 @! Q1 ?4 Q1 ^+ f
  370. BNE Nes_Ram_Init_Write+ O. r7 {7 [( Q/ U( K  G( {1 s& ^; _
  371. INC <$01: d, L# o$ v5 K# {1 {" s3 w
  372. DEX
    : C& [7 v4 {! l6 w1 C+ K# M
  373. BNE Nes_Ram_Init_Write# I* v2 G& e0 w6 j: n0 A/ w3 U9 C

  374. % v# \% j9 V" T) G9 q$ q' |# ]1 W
  375. ;初始化命名表5 r- d3 R: a5 U: ~7 ]( m
  376. JSR Init_Name_Table
    # u! q. J/ K6 Y' y
  377. ' a: J) L8 j2 R0 x+ R6 r0 ^6 R
  378. ;初始化调色板
    ! u+ }# W5 p. g3 L" J# m2 _+ `
  379. JSR Init_Palette
    6 V8 b$ C, `* S% d7 s2 p5 ]

  380. 6 v# a- N$ t! C" |& E8 r
  381. ;初始化命名表属性$ B3 P5 t# v0 f. m* g* o
  382. JSR Init_NameTable_Attributes% y3 m1 P7 @# u3 Z: o
  383. & O* S! H$ i% J' P, }; q
  384. ;初始化精灵内存
    4 K1 A# Q  u7 J% E, w
  385. JSR Init_OAM_Ram# x  `9 L/ t3 G3 c, p# s- ^
  386. 2 U" J1 `2 V; _$ [) w7 n
  387. ;在屏幕上写点东西; M* h% U3 y7 m- G
  388. JSR Init_Name_Table_Text) U+ g% X( l- G  n' D, Y

  389. : ]6 S# X* ^: N) q; q6 s3 v9 ^
  390. JSR Time_For_Vblank/ Y3 ?+ F# `0 e" ]: _: G* u
  391. ;开启PPU控制
    ( O1 n( D) O! C  H
  392. LDA #$A8$ j( ^* l/ ]; {( m9 X4 h& P
  393. STA PPU_Ctrl_Buf/ V1 ]( Q" T. ?
  394. STA PPU_CTRL
    ' y: u: Y% w" N3 b2 |2 R

  395. 3 p1 C& v1 J, x" e5 m7 Q
  396. ;开启PPU显示
    ; s4 m5 [9 Z% r; x) v4 y9 C2 h
  397. LDA #$1E$ g$ f$ N4 c9 |' i4 y" v: a
  398. STA PPU_Msak_Buf
    % S4 Y& p" |) s- ]
  399. : d. H- C  K- Q7 l6 i
  400. CLI$ {+ i  R2 J7 f8 }
  401. JMP Loop7 E) k% C5 [9 ]# {( W

  402. , q1 _3 A/ R2 f% U* x7 n, W. Z
  403. ;==============================
    3 g) o9 T5 @0 ~# B5 r
  404. ;死循环, 等待NMI中断5 v% O5 v5 I: N$ r- S4 A
  405. Loop$ _4 W- \2 [9 W2 y7 w
  406. JMP Loop
    . s5 P  `( G$ Y* s
  407. 7 O& k/ W, @  f5 L0 p! |% w
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9676 H/ b' c" F7 U
  409. 4 C: H/ Z. C/ C/ \0 B0 z
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967), L5 u' L1 n% I' q8 p' \7 a: j
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    7 R) [3 _$ T$ t2 v
  412. ;==================================================
    0 l6 T" O8 u% w: D" m! Z. E
  413. ;NMI中断处理
    : ^5 n- x3 z7 F/ ~. d% P  r6 k
  414. NmiProgram
    ) c, X2 y0 d3 O6 N7 m6 O0 i( j8 [' y
  415. PHA9 S  j, z' U* N7 E' \
  416. TXA
    ' M2 L% }3 E: g, b$ I# E; ?
  417. PHA- s) e  m/ l6 P2 K9 T1 D
  418. TYA
    1 s# y' y+ G. V$ y
  419. PHA
    - {  P" o& Y: N- J- U1 k
  420. 4 a) A7 E4 Y, ], H, \3 A
  421. BIT PPU_STATUS7 ^* Z; l' @$ o
  422. 3 J0 K( k) r! V0 V+ h/ x! j
  423. LDA #$00
    & p0 d! H" h+ j: I% Q7 D' b: Z
  424. STA IRQ_Index0 Q7 D' K/ v! y3 U( }  o7 }

  425. / N2 o8 @- Z9 b5 k! M  u4 N+ e
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    " n( t" I; d7 a% k4 m
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)& b. }7 m) ]+ }3 H" d; |5 [
  428. STA M19_IRQ_COUNT_L/ M" W5 ]/ y9 q
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)7 Q! h; H. ]# L# M# U0 }$ G( B: c/ N! T
  430. ORA #$809 d3 d2 H# ?# [& R6 F  }8 {
  431. STA M19_IRQ_COUNT_H/ y7 y1 h5 V) d& g) x$ t2 A6 ~
  432. CLI1 A1 S3 P' A9 M" Q' ^  q' m

  433. 0 Z( N+ L9 D0 |5 N8 ?, L7 }
  434. ;关闭PPU控制
    5 K. U/ o  Y' H3 G, P, m7 [5 R
  435. LDA #$00: @9 Z+ m+ D* K( r/ |
  436. STA PPU_CTRL
    6 e/ h7 X  |' V: Q& S+ b

  437. 5 \5 {. a! p3 n8 Q# ?
  438. ;处理PPU5 N4 q; g7 s1 b" R6 X2 s! h  K
  439. JSR PPU_Process
    ! U+ Z3 Y7 c+ x) C' c; D% r' w" k
  440. 4 K3 s" P1 ]8 k+ g* p( h* ?
  441. ;开启PPU控制
    ( p  `3 |* h1 r& k0 m. H8 _
  442. LDA PPU_Ctrl_Buf7 Q6 b1 n, C: H4 T7 G
  443. STA PPU_CTRL
    ! ?. Q! B' m  J

  444. / p( h" O% @1 a  I9 E' \; A
  445. ;手柄处理$ i; i7 O5 z  L9 y3 X6 K# Z" i: f
  446. JSR GamepadProcess
    / \  C1 m, l0 ~' M) u- S

  447. 3 t( C7 t1 {: a9 N2 }
  448. LDA #$00( I$ K  J+ \1 J
  449. STA IRQ_Index* a* z* T/ K4 M2 a4 F8 d
  450. 1 z$ w  x6 P, j  U0 |/ C, E2 w
  451. PLA
    ; |: Q! g6 u+ @: g3 ?
  452. TAY
    3 D3 c8 ~4 ^' L8 f. G
  453. PLA
    & u; r: {  i: L4 B4 ~0 J
  454. TAX
    ) T" M1 Q3 a" B$ R
  455. PLA- |: s/ K6 z7 v: M; y
  456. RTI
    # Y0 \6 v( t! T7 R' ^

  457. ) d+ z0 }( k0 M6 u' _1 t( r
  458. ;每行扫描线113.67
    / U0 Y6 M# ]' q3 u" B2 Q
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)/ H4 b  U6 j- S8 k% J4 ?& }
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    + b7 `3 Y7 y! b6 O' T
  461. ;==================================================
    0 [$ Z5 t5 x6 I- b; ^$ d
  462. ;IRQ中断处理. ~+ f! }/ J5 v! F' t
  463. IrqProgram" Z; I6 y9 O- Q- t
  464. PHA
    % g! [, R) G/ F8 w, Q( K+ F0 ]
  465. TXA& E" |' m9 r5 v8 ]& o: Y
  466. PHA
    & y9 h; A0 L# X1 ^7 h, B* `& i
  467. TYA( z, W5 L. f- w0 \6 p
  468. PHA
    " J! p. o8 Y" G7 m2 g

  469. 4 r$ D9 f& N! \. ?; v( \, m% l
  470. ;16条扫描线后触发IRQ# x" R# q, n* [& d4 j$ k
  471. LDA #LOW(BEGIN_LINE_CYCLES)* V- X6 n2 P; t4 ~, Z: U
  472. STA M19_IRQ_COUNT_L3 ]2 |2 z' H8 ^( H
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ! P& u4 X6 ^. q( N9 Q6 M
  474. ORA #$80
    * C, J6 b1 W& T4 V' a. R6 D
  475. STA M19_IRQ_COUNT_H, h1 b  g! `( C9 y

  476. 5 r% j( ?/ W) `
  477. LDA <IRQ_Index
    " X( ~- f  D0 @
  478. BNE * + 49 l* J" n, u+ T
  479. INC <PPU_Scroll_H
    - H* u* E# P: [* M% y
  480. 9 Y* G' @: u$ Q. Z5 M6 }: T
  481. ;设置屏幕滚动
    : ~& ?- b- Y0 L/ T* p( U
  482. LDA <IRQ_Index9 d- k! y" p: |
  483. AND #$01" p/ M+ E; c4 \: O+ \0 h
  484. BEQ Irq_Scroll_Right
    ! m. Z! P# g& i

  485. : D0 g  Z; G) ^: z
  486. Irq_Scroll_Left8 ^  P# T$ U4 }# E. B
  487. BIT PPU_STATUS
    ) i0 s3 f2 ]5 V% P# ]
  488. LDA <PPU_Scroll_H
    & T6 E4 I, S3 K+ H5 c8 o, X2 K, y- `: ]
  489. STA PPU_SCROLL
    1 u& A$ b' _* H1 ~6 V
  490. STA PPU_SCROLL( T+ G) Z, M$ |% T- `$ W9 T2 W$ y1 E
  491. JMP Irq_Scroll_Over
    * f- O3 N% K7 b) Z( L
  492. 6 x' |2 H2 g! z: e
  493. Irq_Scroll_Right. a* R- Q8 P3 Y3 f
  494. SEC
    , H4 Z# k* y- M& s( g% A7 I
  495. SBC <PPU_Scroll_H6 [" H0 n6 e+ D5 k6 B" ]  X1 K
  496. STA PPU_SCROLL
    ( b1 ^( R$ e2 ?  B8 H9 J
  497. STA PPU_SCROLL
    / P6 D; m3 T. E- v: K/ m
  498. Irq_Scroll_Over8 O# k0 n+ M$ X7 {) k. |
  499. : g. A: Q5 t+ P/ x4 n" [
  500. INC <IRQ_Index6 Z' o. V# p  G* ^

  501. 6 S, g; b. P& j2 }2 Q( }7 ?. [
  502. LDA <IRQ_Index
    % |; q/ f4 r/ Y) ~2 ~! M
  503. CMP #14
    * z* z2 B, ^" o% F- f/ ?) s1 P
  504. BCC * + 107 _! a- ]1 p" h7 N0 o
  505. LDA #$00# {8 l$ f  R. H7 J" l0 N9 a# J5 x, |; O
  506. STA M19_IRQ_COUNT_L
    ) y; }8 `0 @# E6 @5 ~/ z
  507. STA M19_IRQ_COUNT_H, [, N3 P( S2 G& B' ?! `

  508. 1 c. h* K. Y! W" F# F8 `% ~
  509. IrqProgramEnd
      N2 U# w3 `- k
  510. PLA
    6 ~. \! T$ o$ H
  511. TAY
      }0 G  C4 ]3 x, a
  512. PLA
    : x$ g3 l7 @0 K! \' j" r
  513. TAX: H& k8 n, q$ k8 V6 s
  514. PLA
    / G, D1 t; U& J$ I$ b+ `) O
  515. RTI
    , I, G# |  N  H+ ?( o6 g3 D
  516. # O4 J3 p9 Y: q2 ]( R5 V
  517. ;==================================================
    $ }+ ?3 G7 t5 }% \+ c
  518. ;中断表
    ( c/ S' d: f; W4 d
  519. .ORG $FFFA* Y" x5 y' s6 ^0 p- K, K& D% G
  520. .WORD NmiProgram) J9 B( ~  V, y; e0 t
  521. .WORD ResetProgram
    . E6 g6 I# z0 G- `; F% `
  522. .WORD IrqProgram
复制代码

' S5 P, _" o9 j

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-1-12 19:01 , Processed in 1.118164 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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