EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]5 @) h4 o, x. y
  2. ;FlameCyclone 20230710) L# E9 X/ e3 ]9 p- o/ f

  3. # j' L0 D, ]5 L+ c1 g& H& E4 _& C$ r
  4. ;文件头
    0 _, O9 W% u4 u9 ~& ]3 j5 Q
  5. ;======================================================================
    ( o# \% R) t' A6 r5 u5 N
  6. .INESPRG 4                                              ;16KB PRG 数量6 u$ ]' _% E# W; y' V1 M
  7. .INESCHR 1                                               ;8KB CHR 数量
    / O% A: M6 e3 o! j. F
  8. .INESMAP 19                                                 ;mapper 19
    . ^) A. F1 h; ~; `3 O. {. s( l; s
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直( X2 K3 |( y! p4 C9 L% U6 g, p4 A  X
  10. & U  v- l  e' b. R3 W  A1 i- O
  11. ;必要条件
    ) W3 g/ q- p+ ^0 N4 H7 @: p% K
  12. ;1.持有CHR ROM
    ' `# e( Z( |0 X5 {+ G5 g8 J' z
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    1 n, k5 H8 B6 d) C' {9 W* y
  14. ;3.精灵内存(OAM)不为空
    $ R6 P6 N% k! V$ X9 \& |# Q

  15.   U. n2 E7 v" U0 j0 V
  16. ;==================================================9 Y9 X" h) p+ k  I+ t; h
  17. ;NES端口常量
    ( a. y! s! W# f0 N
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    # ^  S7 F- l0 H0 ]
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    5 m- P* y+ x& n+ q2 @
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位4 z/ n  d& M1 |. l% M8 c
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1, r* x1 L, V% {) x% A# p6 @/ @, C
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 P; z% \! I" n2 L& N* U) d# b
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    9 f: R, T# P7 c" v$ E9 ]* B
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加$ B+ X' n/ @- k
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    ' H  h6 O8 U/ E3 V) o5 Z
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存/ p5 z# c9 y2 Y. c
  27. APU_STATUS              =   $4015   ;声音通道切换
    " P: a1 V' @2 [+ J4 m9 U2 E
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    , o/ z- _, F+ o" k& m0 j
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    2 k6 t& Z/ {& l. l4 H% W. v" G

  30. : t  w; U: U- r8 y$ m
  31. ;==================================================% Q' i( m- I0 O
  32. ;MAPPER 19端口常量; X% f3 n+ i- y  o0 Z
  33. M19_CHR_0000    =   $8000
    : F7 w3 Z+ g* Q) j: H
  34. M19_CHR_0400    =   $88000 X$ `, w6 D) R- r% t3 m! v
  35. M19_CHR_0800    =   $9000
    8 m% y, f( r: ]+ v6 u
  36. M19_CHR_0C00    =   $9800
    4 W# F: }( S" L$ y2 f+ {
  37. M19_CHR_1000    =   $A000& A9 t  m9 M2 Z' W# |9 a5 n# d
  38. M19_CHR_1400    =   $A800
    ( y/ D( G4 t1 G) p# a- O5 g
  39. M19_CHR_1800    =   $B000
    $ w! D) |* L* g$ m: D& h% L; P$ O
  40. M19_CHR_1C00    =   $B8000 {+ w5 z) u2 v8 ^5 `! ~- W) o9 q
  41. M19_NT_2000     =   $C000+ C6 p, [" G2 \0 J7 Y
  42. M19_NT_2400     =   $C800
    ) ?' n: W6 N7 e9 E
  43. M19_NT_2800     =   $D0003 N( u- k9 z. G* a: n+ z. V
  44. M19_NT_2C00     =   $D800
    / Z0 h4 I' q) m
  45. M19_PRG_8000    =   $E0003 u" a) s. b1 m
  46. M19_PRG_A000    =   $E800: T# ]% F7 v- [* b- M9 r
  47. M19_PRG_C000    =   $F0004 y9 k9 Q2 |+ y; a
  48. M19_IRQ_COUNT_L =   $50003 o9 l: r0 L6 {, @# t- N% T9 e! t* C0 w/ y
  49. M19_IRQ_COUNT_H =   $5800
    , f- a) Z; D; z! M
  50. 5 X# S. _0 A+ _2 u3 D. b' p' k
  51. ;==================================================
    1 G/ ?/ ]2 {9 O
  52. ;程序块配置) d$ o) j) }0 F! d/ n0 n
  53. BANK_DATA_MASK          = $07
    " q/ E5 }) m$ P2 Z; G; Z
  54. ;--------------------------------------------------7 R  f+ y4 B6 ^
  55. RESET_BANK              = $076 f- o* K, y) I6 g- u9 x: Z; v
  56. RESET_ADDR              = $FC00
    ( Y2 b" Y# W, n1 b& b$ w1 R

  57. 5 C/ q$ P4 ~( v" D  g
  58. ;==================================================, I7 C/ l! B) r- |7 ?4 w
  59. ;图像块配置' t- j+ e: c6 q3 f( p* ?
  60. CHR_DATA_BANK           = $087 d! X8 S9 m0 w# q& d
  61. ! ^/ F3 E! J  `* e/ V% s+ a( T
  62. ;==================================================
    3 \3 e% Z' O/ a+ r
  63. ;零页内存地址配置
    , b. ?& ]7 w  y! j# C3 T
  64. Use_Ram_Addr            = $80
    , H8 P. q& @" M0 g7 h
  65. PPU_Ctrl_Buf            = Use_Ram_Addr/ K& _3 T1 Q& k4 ~/ y/ R
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01: V. Z$ T9 Y& s! Y, t% i
  67. PPU_Scroll_H            = PPU_Msak_Buf + $019 H( b- a1 R/ E5 @) D
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    8 ^. I: N) W# K7 u, f1 J% a
  69. FC_Data_L               = PPU_Scroll_V + $01
    5 \1 C' r4 c- A  {* J
  70. FC_Data_H               = FC_Data_L + $01! a" ]  a! R9 @' Y
  71. FC_Data_Buf             = FC_Data_H + $01, S5 S* k; `: h1 s
  72. ;==================================================
    # {; A; R1 i3 ?2 u0 F

  73. + g: l; f) D5 L7 P9 x) m1 h
  74. GAMEPAD_MERGE_FLAG = $043 M* X2 v; [/ [, f/ I
  75. 2 T' N) ^( n- I3 l/ @
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    , a7 S/ B9 g4 R3 D/ M0 x
  77. Gamepad_Once            =       Gamepad_Keep + 2
    ' a( S7 [0 I5 Z( F
  78. Gamepad_Temp            =       Gamepad_Once + 2
    7 O, x9 ~5 {2 ~
  79.                                 7 ~4 `' J! B; g; U: b. k5 p
  80. Gamepad_0_State         =       Gamepad_Temp + 2
      a- d5 B" r3 x. v( Z' i0 W
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    . T7 ?; D. g/ s' w  r
  82. Gamepad_0_Value         =       Gamepad_1_State + 1  D1 i9 \# P0 ~  ~& M
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1" L- [3 q6 F. T5 Z( ^
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    $ h5 Z. |! Z: [9 ?2 z  B3 z- Q1 f
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1* |8 e: P$ J8 `# a6 B; @

  86. " f/ N. E7 M4 Q% P
  87. ;==================================================. V6 u7 P9 J" G6 L& U
  88. IRQ_Index               =       Gamepad_Merge + $01
    4 n0 z7 S2 D. @
  89. ;==================================================
      s% J. ^/ y. q2 b& c' _( |, ?

  90. + y0 |& w6 g: I' |2 l
  91. ;CHR图形数据  N/ U  c3 D# t! \2 q. `
  92. ;==================================================
    ; @  ]$ l& `6 }) w2 M: W0 y5 z
  93. .BANK CHR_DATA_BANK5 e8 }1 G6 [4 g4 O/ [9 X
  94. .INCBIN "chr_bank/chr_data.chr"
    ) j  P! O, V/ U" e
  95. 2 K5 @& ~& ?2 {$ x/ S8 ?
  96. .BANK RESET_BANK & BANK_DATA_MASK5 |. u+ u. e" ~2 ^! d( S
  97. .ORG RESET_ADDR
    $ F/ ]& D) U( r$ E

  98. ! Q  R8 t8 i1 k) I! k! b7 \+ r0 J, q
  99. ;--------------------------------------------------
    + s8 G3 O' R' O7 S# u
  100. Attributes_Data' y8 J+ a0 B1 h
  101. ;命名表属性# V, i) y$ e; ]) {$ Q' G
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    . ~. [0 {/ q) S# Q8 O4 d- L9 i
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    2 r- z0 d7 Z" z  b& `  |% J9 \
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA5 H2 h* h% Z( V, Y1 J* P
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
      k' j$ U  M( L% m1 B5 {
  106. ;--------------------------------------------------" P$ I  y; ]- h% B* E
  107. ;调色板数据
    9 U+ H; H' |& x; E3 S9 {8 W4 G
  108. Palette_Data
    ) V( D, w! G) v3 ?: L" |
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    1 k) K8 `5 C9 B7 ~
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F8 p. ~1 o5 r1 d) @; Y5 H# r: Z  L+ V& K

  111. ' q* W# b2 p6 m+ ]9 e, X: o
  112. ;==================================================! u& B' W' A0 h$ J$ A
  113. ;命名表初始化# u) I1 l2 g) k
  114. Init_Name_Table7 l, O7 J) g) \, z
  115. LDA #$209 m8 ~8 r4 @, o! N0 M# `
  116. STA PPU_ADDRESS
    # _# u5 l  a9 U0 _" e" m
  117. LDA #$00
    + a: s" A7 Q2 I: `7 i8 H
  118. STA PPU_ADDRESS
    7 _) _/ z. `) I; }- f3 O" `
  119. LDA #$002 @8 ~- F" R# r4 _( S6 |
  120. LDY #$00
    * |( Y* M$ j3 H. P# _
  121. LDX #$10
    % i0 M, W$ \- Q! ~- n0 \
  122. Init_Name_Table_Write" Z: F1 s- n) I( `
  123. STA PPU_DATA  r* A9 Q8 K- }& Q7 C
  124. INY, b: k! P- M( X
  125. BNE Init_Name_Table_Write
    2 p$ n' j) ?. a4 I1 ]; B
  126. DEX& w# n3 h( y' C
  127. BNE Init_Name_Table_Write
    0 y  l! M, W1 u! N* R
  128. RTS
      M7 f# M, p& H4 F- \

  129. 1 A- J3 P0 S$ ?0 z0 G, ?& w5 E
  130. ;==================================================9 n# A7 C; V  o' Y! H
  131. ;调色板初始化8 g: Q! I. z& l& L
  132. Init_Palette' Q: Q2 O% G8 d. S2 T( w6 T
  133. BIT PPU_STATUS; u) O# l. C6 P# |
  134. LDA #$3F$ m! s0 T/ ]3 J" O
  135. STA PPU_ADDRESS
    4 Q# [" ^1 H" e+ z1 f/ v. P# }% A9 F
  136. LDA #$00
    + i5 [( ]( G3 T! L
  137. STA PPU_ADDRESS
    . d1 u' d" w; `& n+ O
  138. LDX #$002 M3 w+ q# n2 ]
  139. Init_Palette_Write
    * v8 R$ R5 v- N' |
  140. LDA Palette_Data,X4 k: p+ u& A# g( m4 k$ [( f5 k
  141. STA PPU_DATA/ j1 z0 u1 T9 X) i& P9 d+ |
  142. INX2 b# j  ]. Y) ]
  143. CPX #$20
    * S, U2 }# n2 S  {' U5 a
  144. BCC Init_Palette_Write6 h6 e  C1 K3 x. M2 |, s
  145. RTS
      k7 c" y0 a8 `5 l6 d; X, v' W8 Q
  146. : W$ l( l5 ?9 ~
  147. ;==================================================
      A4 @" G& h$ O5 w$ b& S6 W3 L
  148. ;设置命名表属性/ h$ h& n! a7 C5 ?0 t
  149. Init_NameTable_Attributes. N  H( O( V& x$ E
  150. BIT PPU_STATUS
    % x9 p* A  W; T# M& q
  151. LDA #$23& K2 U$ ?" P( T# V. c1 q5 g
  152. STA PPU_ADDRESS6 r5 g' W! O9 m  D$ K3 p
  153. LDA #$C0- F' ?/ k& x9 D$ o/ {
  154. STA PPU_ADDRESS
    - [9 ]& {+ c* U  P
  155. LDX #$00
    ) [' s7 }6 Z2 X3 e
  156. Init_NameTable_Attributes_Write
    5 \$ C2 s- ~% e- c
  157. LDA Attributes_Data,X$ j7 L$ d2 x, a9 L! z5 L. y6 |5 e3 t
  158. STA PPU_DATA
    ' N% ]4 D( x5 v( Y5 Z! d
  159. INX, c+ D, E* p, `9 q
  160. CPX #$408 U; K+ y: n9 u, r; J5 G' L
  161. BCC Init_NameTable_Attributes_Write1 [  [2 R! e) J: [2 i5 G4 H
  162. RTS. ^" W5 B6 R* _$ o
  163. + ^( F# A9 _5 J' a
  164. ;==================================================: Y) W% ]& T) I  ^* V4 A/ |% ~
  165. ;初始化命名表文本# [$ C1 a& H5 N+ `2 Q
  166. Init_Name_Table_Text
    3 r4 s; ]9 [" F6 n  \7 X$ x* f4 j# H
  167. BIT PPU_STATUS
    # w4 G0 m8 U6 B4 f
  168. LDA #$20# e5 M/ r: d, d" Y# Y: d! u: i
  169. STA PPU_ADDRESS; [, y' [  C  v' H
  170. LDA #$00) D% j6 p" W6 ^! k$ B
  171. STA PPU_ADDRESS4 ]. W# ?/ A4 T, q6 D/ w" q
  172. LDA #$00/ w# `( M* B  I
  173. STA FC_Data_Buf
    0 p8 f0 n) e# N1 v
  174. LDY #30
    2 [+ i, w% g0 Q2 h( i- k3 I1 T
  175. Init_Name_Table_Text_Write
    ' V' b) N5 }$ \7 o* |# X' T
  176. LDX #32
    ! n1 M& j8 c1 h: R4 ^7 [( m/ [
  177. Init_Name_Table_Text_Write_Char
    & J8 s6 G$ C, R! G  I% y
  178. LDA #'0': U) m* l/ m" i* p; ?9 @- S2 l
  179. CLC
    1 Q9 ^9 F) P- D" d7 a; m4 P1 G0 b6 y
  180. ADC FC_Data_Buf
    * Z3 Z- k. t+ y9 i
  181. STA PPU_DATA
    0 b- H/ M  ^. V' O( v: u3 y9 Z
  182. DEX
    : ]; O  Z% N; a) Q4 W
  183. LDA #$14  G2 z9 F* Q  U: }
  184. STA PPU_DATA
    1 Y2 p6 M- o% [( y
  185. DEX
    $ v" D! }& E+ m
  186. BNE Init_Name_Table_Text_Write_Char( T8 g) D! z" @) l# x, Q
  187. INC FC_Data_Buf2 o5 H) N& z7 {1 t" `  l: U: Z* f* e
  188. DEY
    0 Q- s: I/ ]$ Q9 @  u( ?
  189. BNE Init_Name_Table_Text_Write
    9 L; b* X0 q& r' Z
  190. RTS
    - v9 D0 i' T& t  y! N
  191. + o+ g, J3 r* A2 E
  192. ;==============================
    ) L# l8 l* j% T
  193. Init_OAM_Ram;初始化精灵内存
    % ]1 E+ @  `( C2 w9 T
  194. LDX #$00% V0 z& i6 E7 F, ~
  195. LDA #$00) a- R1 g! H! V$ ~5 W$ I
  196. STA PPU_OAM_ADDR
    0 @; H1 v! w. O# q: ]2 ^
  197. LDA #$F8
    5 h1 v- |& r0 t2 x  u8 j7 Z
  198. Init_OAM_Ram_Write: M0 y7 P2 j* `4 b
  199. STA PPU_OAM_DATA3 ^& d- _* k  k9 c
  200. INX
    2 k! p5 ^( l! Y+ W  w9 e
  201. BNE Init_OAM_Ram_Write9 e# f9 r$ g8 O- H$ n5 Y
  202. RTS
    1 ?8 G5 B/ W; k. M
  203. $ {% z9 r+ ~& Q& H" j6 V
  204. GamepadProcess;手柄处理$ L" r# X: M3 Y# R
  205. JSR GamepadDatacan2 L+ D/ W% J9 h, S8 X: g% {
  206. LDA <Gamepad_0_Value$ f+ v/ `5 a5 m. ^* p
  207. STA <Gamepad_0_State7 N8 y$ ]' |1 s7 z# r  Q  _3 \. k; o1 e9 [
  208. LDA <Gamepad_1_Value, C; Q- e. l6 u, |! j8 b3 n9 b
  209. STA <Gamepad_1_State2 q, O# h9 d6 X8 ^. u
  210. JSR GamepadDatacan
    8 I; l( `" b; L7 W/ L" }7 w
  211. LDX #$01
    ' E9 X6 e& E2 p# G$ C0 N' I: }
  212. GamepadMergeCheck;合并手柄输入检查# B4 h- O# N3 E& C& z# U
  213. LDA <Gamepad_0_Value,X
    1 ~1 J! k5 g" t* ^7 `$ S
  214. CMP <Gamepad_0_State,X1 `1 I% j1 e  t' O" F9 l7 S- A
  215. BEQ GamepadMergeInput9 \/ v* X" T  R8 Z0 p
  216. LDA <Gamepad_Temp,X
    ( u" s/ z: e9 e1 u! Y+ P; O$ T
  217. STA <Gamepad_0_Value,X
    4 Z+ d; H2 j( R3 {( `# X- ^
  218. GamepadMergeInput;合并手柄输入8 f: b0 t2 @0 x: ?$ }
  219. DEX; }# r" q0 [/ c
  220. BPL GamepadMergeCheck
    - h3 w8 t4 S) z+ a4 K3 v* \4 w
  221. LDA <Gamepad_Merge
    8 t  v! G( _5 ]" g
  222. AND #GAMEPAD_MERGE_FLAG0 i6 |5 `. h1 f- T& n
  223. BNE GamepadStateProcess" @0 G/ m: P% U$ S  M) v
  224. LDA <Gamepad_0_Value
    0 n! d( X* G# D1 B3 |) e/ _
  225. ORA <Gamepad_1_Value
      n' e0 D% N6 F* @6 d( c+ E4 a
  226. STA <Gamepad_0_Value
    5 m7 L5 x8 X. S! K' W
  227. GamepadStateProcess;手柄状态处理- P) j% C1 [8 a+ {0 n
  228. LDX #$014 V% X1 U4 Q6 Y" K0 w$ J
  229. GamepadStateSave;手柄状态保存9 G/ V0 R$ v! o- G, N, J- P
  230. LDA <Gamepad_0_Value,X( \4 u7 q$ C; W( c
  231. TAY, A: S% \) N, e  E( Y$ y( G
  232. EOR <Gamepad_Temp,X, q$ S: |1 A2 y6 k7 m. R2 A
  233. AND <Gamepad_0_Value,X4 W, G# ~3 J8 O% r
  234. STA <Gamepad_Once,X
    7 I# A9 j3 ]7 J3 {
  235. STY <Gamepad_Keep,X7 K' S& R' p6 o2 E3 C
  236. STY <Gamepad_Temp,X
    % z  t/ ]8 h1 b- B" ^" W9 G
  237. DEX3 G8 E3 V7 I- `, C" R) {' u$ j
  238. BPL GamepadStateSave2 m6 t$ ]% E. u  m. T
  239. RTS; x9 w0 A' [8 n) G2 c
  240. 3 O0 o  c8 l. [! t- N
  241. GamepadDatacan;手柄数据扫描# D4 L! v+ M# P- @1 p6 Z! T/ ~
  242. LDX #$01
    3 R, {2 e: P. j/ j
  243. STX $4016
    7 g. q. Y2 |/ f; l, u0 j1 y+ T
  244. DEX
    # V  `; \( k; P
  245. STX $4016; I' `' f7 B$ B3 D
  246. LDY #$08, f9 q* R4 I" D: F9 V* E( e" g
  247. GamepadPortScan;手柄端口扫描
    2 u6 w# \3 _2 M# }7 W$ |& w
  248. LDA $4016, }. R* ~4 u; G& i, A1 T; r
  249. STA <Gamepad_Port_Value- T9 ^* A: M: h+ Z& `
  250. LSR A
    . `, R7 S% h7 j% A1 |; f
  251. ORA <Gamepad_Port_Value
    ' v3 V& H7 Q  ^& L1 }: S
  252. LSR A
    . U  w% X$ ?" z0 f6 v
  253. ROL <Gamepad_0_Value* t$ e( t# \' O8 I
  254. LDA $40179 L6 C1 c% e0 [4 w
  255. STA <Gamepad_Port_Value
    0 o" E" [3 k+ E, r
  256. LSR A
    + E* f6 Q4 z8 C+ I. {! B% V) m
  257. ORA <Gamepad_Port_Value  m' F( s8 ~2 E
  258. LSR A+ h$ P  D3 c! r1 ^% Z6 v* M( T1 [2 c
  259. ROL <Gamepad_1_Value  h3 ?& C7 `. z( i9 Y0 l" p
  260. DEY
      O& f8 ^, r( p: B3 r
  261. BNE GamepadPortScan
    ' ]) \9 D# T" V& c" \
  262. RTS
    1 W! q9 }! ?6 A" l) X- I

  263. 6 Z9 l- r' P( h
  264. ;==================================================
    $ O* G0 T- t* ~" K8 e0 o9 x/ W% G9 h) o
  265. ;PPU处理
    # C6 L7 |  u+ o
  266. PPU_Process
    - o3 o# y1 D, U* s3 h3 [
  267. LDA #$00
    - w% g* ~8 D/ O( Y
  268. STA PPU_MASK2 L* m6 z/ h6 F- W9 b% w

  269. % o8 K: Z. E+ \0 T, t
  270. BIT PPU_STATUS
    + [, Z1 X  y& ?7 s0 O0 t
  271. LDA #$201 J( F% s( i% l4 R; c
  272. STA PPU_ADDRESS; V1 |) n, `! R" z, S; ]) |
  273. LDA #$00( ^3 l8 o4 j" P6 q, F- a
  274. STA PPU_ADDRESS
    , ^+ C/ N2 N' j: g
  275. 3 ~8 p% f& }- S) c' A
  276. STA PPU_SCROLL
    $ J0 m$ _9 ~% ]8 d9 B8 j
  277. STA PPU_SCROLL2 ~) X* |. ^: D, m
  278. 0 c* ?' U$ h* b7 A
  279. LDA PPU_Msak_Buf
    * _  O5 A/ R  g( g! R
  280. STA PPU_MASK9 d2 ]" w/ p6 p' s/ M
  281. 3 D8 [/ w# v% k3 W! _
  282. RTS& h4 @5 j- d# m7 y# D/ T& {

  283. 3 |' @2 |! b/ L
  284. ;==============================+ R' B" c! {3 n8 h6 H
  285. Time_For_Vblank;延时等待
    / C3 o! \# u2 t( J  g
  286. LDA PPU_STATUS
    ; F& Q' I/ K5 b8 `) K6 G; A: F
  287. BPL Time_For_Vblank5 u3 z  u/ H8 d5 u! r& B: Y
  288. RTS. R6 ?) V8 n9 T, m. w

  289. 6 {4 v; [$ L4 v6 `
  290. ;==============================: k" F( C4 o. `' k6 f
  291. ;初始化MAPPER19
    1 E% t5 n# o- Z* y. S" E
  292. Init_Mapper19
    6 X$ W  ?- y- r* V
  293. LDA #$00
    6 }4 L: I$ u' _, M
  294. STA M19_CHR_0000
    % z7 H* g" Q, {  w
  295. LDA #$01
    5 v7 a6 N) t, `9 K- H
  296. STA M19_CHR_0400( S  ^( f: n: r
  297. LDA #$022 w: z/ B/ L* u  C1 `/ ]5 s  @
  298. STA M19_CHR_0800
    ( E& a/ R0 ^+ K; A) r8 D  n
  299. LDA #$03
    % u8 V9 i- C9 k( ]
  300. STA M19_CHR_0C00
    , F% t- w3 _, s
  301. LDA #$04* Y7 B1 a6 K- O1 b8 f; U. s
  302. STA M19_CHR_10000 h+ o7 r1 [+ `8 N
  303. LDA #$05
    0 z* h7 e6 W5 S2 k
  304. STA M19_CHR_1400
    0 k! G2 B; g4 h( A6 f, v
  305. LDA #$066 a( G8 [# [6 d# [
  306. STA M19_CHR_1800
    5 Q7 \" l+ e. P' u' y( \7 q9 i3 x9 y
  307. LDA #$07
    : `  e3 K5 n/ {8 w4 R: k
  308. STA M19_CHR_1C00# {0 L- C. \3 |

  309. : l- M" t* D6 Y2 \0 D3 d5 D) L; }1 H
  310. ;禁用IRQ
    1 s$ F- `: T1 _
  311. LDA M19_IRQ_COUNT_H& f1 C# }& Y6 P
  312. AND #$7F
      i0 x: }% m% n; Q4 ?0 ]
  313. STA M19_IRQ_COUNT_H  x0 }. Z) A9 x( ]3 m
  314. & S+ v' Q1 i" ^+ T0 Q" f: x  ^
  315. ;命名表  G; m  v6 r" H' @* v4 g
  316. LDA #$E0! U% {2 n4 I! J9 ?
  317. STA M19_NT_2000- q  q. a- e+ {
  318. STA M19_NT_2400) u9 o) A! L6 h
  319. 6 ?# Z5 W- b0 }$ N* E
  320. ;命名表1 X2 }( U' F% U& ^3 E
  321. LDA #$E1
    ! v9 ?, }5 s2 |) E: a) H
  322. STA M19_NT_2800
    # j# g8 B6 H* _: M% d5 ]
  323. STA M19_NT_2C00
    , E: x" A6 E  T; Y$ f+ i

  324. ! [5 o1 x" e4 U: i5 W$ z
  325. RTS/ q% T# c$ w! N; }3 B! g
  326. - v7 W2 a9 V, E( l- @
  327. ;==================================================
    # V' Z! Z  r6 k* d  H9 T* G8 O
  328. ;重置中断处理
    6 {% U8 n- i! j8 I  g
  329. ResetProgram2 a/ S+ M* {  E, [8 R, G8 c1 i
  330. SEI
    9 C& S- V% Q6 @% D) o
  331. CLD
    5 I+ H# v1 r+ V2 \2 T1 |
  332. LDA #$00
    % c  R9 q) y$ n0 g0 V+ s8 n% P( a
  333. STA PPU_CTRL* l6 v9 N# W7 z* w
  334. STA PPU_MASK
    . h$ Q. H1 }1 {5 C8 M! z' w7 u
  335. STA PPU_STATUS' c. D6 m1 }. y: ~, i7 `7 f6 N
  336. STA JOY2_FRAME& @6 y) h# ?9 f$ @
  337. STA APU_STATUS
    4 @/ k- k. N' k) k9 u- m4 v; W

  338. 0 b8 ^0 A& \6 \1 X7 H  ~
  339. LDA #$C0
    8 E* R# _6 M* U  Q. F8 }
  340. STA JOY2_FRAME
    ( D$ Z% z/ k1 s1 t- a$ m
  341. / E" Z9 o1 ~0 Z. L
  342. ;等待vblank
    6 p5 s0 f5 q2 P; [0 l
  343. LDX #$02
    # C5 _" E3 `# C( _+ Q$ N0 H
  344. Vblank_Wait_1
    " F" |/ c( u9 S4 E* o' @
  345. BIT PPU_STATUS
    ! E9 D7 q  O. ~* M+ P
  346. BPL Vblank_Wait_1/ P4 a" X/ ~' A1 `# t# @
  347. Vblank_Wait_2/ O. ^$ R% o4 x/ o$ P, r
  348. BIT PPU_STATUS
    2 C7 \2 d. a9 v* x$ N! {
  349. BMI Vblank_Wait_2
    * c3 f+ u7 d7 t) _; u& \+ [8 n
  350. DEX
    . `& w! D$ o1 ~$ w0 S
  351. BNE Vblank_Wait_1+ f- S, t; ?; }) F( `
  352. 2 I% f- ^' @% L6 @, {4 A) }
  353. LDX #$FF
    " ^8 I! I7 x# ]8 f. _. c, X
  354. TXS4 b6 b7 c0 T* a  q/ j# P, G

  355. & l- ~8 {1 e- u
  356. ;初始化MAPPER197 B, B4 v; l0 p0 u
  357. JSR Init_Mapper191 C/ n6 P3 c+ _" t& g+ S
  358. - ?  v# Q; r+ V5 g( w. [
  359. ;==============================
    & ^6 _$ K6 W, n% Z
  360. ;RAM初始化
    4 [. _0 @0 L% E8 R, j6 z
  361. Nes_Ram_Init/ ^4 c$ J; B) j2 {
  362. LDY #$002 N. Y0 e/ }" G# J1 M) H' H
  363. LDX #$08
    * x7 R) ~" H  s+ J& S
  364. LDA #$001 J% W. \. X3 B; |9 K8 ?
  365. STA <$00
    7 q2 E9 g& y2 R) M
  366. STA <$01# A$ R6 f8 m% ]
  367. Nes_Ram_Init_Write
    + n( m0 z) V$ l! W1 n+ P
  368. STA [$00],Y
    1 ~; j& J/ ~& g; f" t4 E" h
  369. INY
    4 e7 x0 o4 m' |# R) `
  370. BNE Nes_Ram_Init_Write  J1 t, R/ |7 ]
  371. INC <$01: v) d% W! X, y& F. j0 i* o
  372. DEX
    1 g% R2 e9 X. _9 o& ^
  373. BNE Nes_Ram_Init_Write
    + a: D6 i! I9 b

  374. 8 V) d! O$ y( E% u0 G* W  N
  375. ;初始化命名表
    ; f2 e- M6 I3 ?$ a/ J. u$ w* t* N
  376. JSR Init_Name_Table
    / K. q" a2 L2 M1 _8 _
  377. % @( c$ q) w% T, b; |; m
  378. ;初始化调色板
    & G+ k/ v- D& \  R
  379. JSR Init_Palette# d& X* i  O& {0 N8 k4 T7 V

  380. 4 j" D- T3 f' Q5 v6 O5 j
  381. ;初始化命名表属性
    ; a) a% h( A" Z6 `+ A
  382. JSR Init_NameTable_Attributes
    ! O0 {# s+ w! x- F

  383.   [" k! K: q% }' G8 v* R; p
  384. ;初始化精灵内存
    ( D4 ^, e) j/ q
  385. JSR Init_OAM_Ram% @; J; w3 E  K' n/ l' O
  386. 7 i1 g& t. Q# l
  387. ;在屏幕上写点东西
    2 ?  ~: n( l* b4 s( `
  388. JSR Init_Name_Table_Text
    ! w0 F2 |$ V1 x: b( a3 s0 s( `3 _
  389. $ m. [  Z' l+ n1 h! t( e
  390. JSR Time_For_Vblank
    3 u" X/ y9 F2 V) ~2 l8 M
  391. ;开启PPU控制
    6 E1 y" i0 r. C
  392. LDA #$A8) _& V6 z! V8 ^+ |
  393. STA PPU_Ctrl_Buf- i, A# ^) Z: U6 p+ G5 T
  394. STA PPU_CTRL
    , N! h7 y$ i8 Z; C# Z/ C, p- k
  395. . D/ [# l$ G$ |( }2 B- ]3 n
  396. ;开启PPU显示
    ( G2 {, w! p8 T$ o: Q7 X1 U
  397. LDA #$1E/ b- L! k( W' u  b  _, M
  398. STA PPU_Msak_Buf" t% G7 R& _  `7 a& m. `

  399. + g+ z: V' T" H0 Q: m) i& ?
  400. CLI
    - s* x* }7 B9 I/ O! m2 _  J8 y
  401. JMP Loop6 @+ Y4 ^( N% J0 o* v

  402. 1 X9 _0 M4 ^2 K! r
  403. ;==============================2 z" r0 i/ {  P; b$ ^
  404. ;死循环, 等待NMI中断
    8 i( \" n4 b  F0 g) y7 `
  405. Loop6 _& M, w% F% _9 v0 t. @
  406. JMP Loop8 W0 @. @- J3 ~" T2 h  [' ]7 w

  407. + x7 h2 C6 a/ p) Z: U' D4 }
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967. [/ D; Z# h# N1 R# v

  409. . m; |' y1 {. }
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    ( |* `+ k: [* e% L" T# a
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)/ d0 ?$ y% j6 E
  412. ;==================================================& H3 b& T& {, r2 e2 C
  413. ;NMI中断处理" d# X# f3 c' h+ B
  414. NmiProgram/ [! }, d& I, r9 [
  415. PHA, d5 `( E! Y, G' E% X
  416. TXA2 Z5 [: S8 {3 {$ x
  417. PHA
    1 r$ H4 d# j1 u4 v/ w" A
  418. TYA+ j. ?) y4 @$ a& U% l6 \1 @
  419. PHA
    8 J. [% a1 h: y' M

  420. ! M, S8 `& |; z* K# ]
  421. BIT PPU_STATUS
    : |7 b6 q  m. O% A
  422. - ]+ Q0 h6 L3 M' T7 v3 _4 c
  423. LDA #$00
    - _6 d  R6 b* r6 Q# e# J. t
  424. STA IRQ_Index
    & ~- @* r. {5 @: v9 j5 d) R
  425. 7 t7 d. u- k- G( r/ [3 v3 I( Q: L
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    2 D8 c8 g! M' t; i4 P5 p- u
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)5 Q. o) q+ a2 I
  428. STA M19_IRQ_COUNT_L
    ; u7 W( Q5 E( J; h/ S! h! v5 b
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ' F5 v: c8 O) X6 @' s- z
  430. ORA #$80! |8 v5 e% z$ D  l8 `# w. ~$ H
  431. STA M19_IRQ_COUNT_H  D0 p: ?' J/ E5 j& A
  432. CLI" {2 V5 U" V( r: \/ O2 S9 e/ x( v
  433. ; W( e# d4 R+ _9 p
  434. ;关闭PPU控制
    1 t% R9 ?7 k7 K7 w+ b
  435. LDA #$00
    ( j( l  }9 d" P3 z* N( A
  436. STA PPU_CTRL) {- `, y% |6 S* |( F

  437. , b0 _$ a: V& w6 `1 Y
  438. ;处理PPU
    3 o8 ~+ l" d% J$ h( `- b  Y2 z- V) G4 [
  439. JSR PPU_Process$ A4 z1 C, ^0 X, R
  440. + |+ f1 c, l. ~' k. a
  441. ;开启PPU控制3 j# j) {7 B+ f2 e3 ?/ n6 |
  442. LDA PPU_Ctrl_Buf
      ^/ G3 M$ B& l* V/ E1 |# y
  443. STA PPU_CTRL2 P3 k4 J  v6 t
  444. & y4 {5 w% M2 [2 U) F0 S% h6 f
  445. ;手柄处理
      j" T3 H: x" R  |3 i. T5 W1 m4 E
  446. JSR GamepadProcess
    2 l# G8 r+ S& r: |' c- J% f
  447. 0 i0 `- Z/ h" G6 V* m4 [4 s
  448. LDA #$00
    & q; Y( ~9 f1 p
  449. STA IRQ_Index9 g7 B( I& K* p9 m% L1 B
  450. 8 ?2 `, ~9 {, X9 K5 e$ W; b
  451. PLA: x- e. c* e( U% u. j0 j. X
  452. TAY
    0 Z% Y' L% i. P6 }
  453. PLA
    + y& O) y6 r$ Z: i! B4 \# C
  454. TAX
    - b' l: N; S0 s% X4 Z$ t3 @; C
  455. PLA
    ! c* W* I2 S( h& ]2 b3 }
  456. RTI' v. |* }7 g! d) @5 Q

  457. 3 w  L& R4 P" x" K/ ?7 G
  458. ;每行扫描线113.67
    % s1 u: ~9 X- D2 K5 v
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    * @  t% u+ [, W8 C* u" o- v$ r! Z
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    + r. X  `5 }' f" v. x
  461. ;==================================================
    0 I9 ~% q) H& O4 z8 |& @2 ]; r  y
  462. ;IRQ中断处理
      `% [5 V6 k- p9 u8 m' Y
  463. IrqProgram
    2 E7 j# I" b" t0 \5 B
  464. PHA3 W0 \* Y1 H! h  |$ Y- Z: I! m& u
  465. TXA7 r2 Y0 O, h9 k1 Q# S! b
  466. PHA
    1 y5 T( C- Z3 B$ a8 _: {; ?
  467. TYA6 l3 T+ c0 n" f$ X3 \; }: F
  468. PHA$ e- i/ G$ T: w- ?+ }4 ]
  469. ' }* Y8 |  Z9 J/ {& ~5 s
  470. ;16条扫描线后触发IRQ
    7 }- {8 M( T+ J
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    / ^( m6 N5 t8 n. V6 |# }0 f3 y
  472. STA M19_IRQ_COUNT_L
    * v0 S& `4 h" ]; D) E" g
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    9 X  V, i2 [# H- W
  474. ORA #$80
    $ `, T2 O( N- v! @( E
  475. STA M19_IRQ_COUNT_H
    2 T9 m2 v, A: r, S  S1 \6 ^: R1 K

  476. 1 T6 O  T! u6 e6 j  s
  477. LDA <IRQ_Index
    - b4 I9 Y- m( s, }: R
  478. BNE * + 46 U( v; t6 _+ E( E! D9 X! N
  479. INC <PPU_Scroll_H
      e  l) s7 i+ f4 \+ I- b# ~* {
  480. 2 I. I2 n, `* q( W. B
  481. ;设置屏幕滚动  y. z7 @4 e# N- ?
  482. LDA <IRQ_Index$ J5 |) s6 s  y- W& K
  483. AND #$015 T- B( V9 q( @" K- l: L* x! X& e3 A
  484. BEQ Irq_Scroll_Right+ S; H; ^2 e; N0 F- Q" y' A

  485. " l9 z$ I8 b- o
  486. Irq_Scroll_Left- f! e& [: z! t' [$ Y( J
  487. BIT PPU_STATUS
    ; N8 c" j! `% H1 i
  488. LDA <PPU_Scroll_H9 U2 n8 k% h  s% c
  489. STA PPU_SCROLL
    & m* \% \0 J) F: J
  490. STA PPU_SCROLL
    7 D. \8 h+ |$ x& G
  491. JMP Irq_Scroll_Over
    # o. ^# M. O) y, s

  492. ; |4 Z+ ]/ `  p1 F% S% z3 Q
  493. Irq_Scroll_Right
    2 P# P% q- D% o; h- m
  494. SEC! ?/ Z$ o% d7 x9 V' M2 F; J. Y
  495. SBC <PPU_Scroll_H3 K" h% A5 B9 L+ K" N) \
  496. STA PPU_SCROLL+ b8 I/ I# k/ [! |* ]# w8 E
  497. STA PPU_SCROLL. r" [; @; ?' y: v: i8 G9 x
  498. Irq_Scroll_Over
    ( v8 @  E9 D" ]( _3 l& i8 V

  499. 0 N0 l3 z& |# ]
  500. INC <IRQ_Index
    7 ?& l2 L0 V7 I: X) y) ]

  501. / Y! F# f; Q# a* U: h0 M/ v3 X& @3 }
  502. LDA <IRQ_Index
      n% U( Q! G) E4 {( |, c  V
  503. CMP #14& g6 L0 G9 b, @8 ?' v
  504. BCC * + 10
    6 w3 ]( e7 Y' H  B( V
  505. LDA #$00
    % z0 A6 a. o( G5 w9 X
  506. STA M19_IRQ_COUNT_L
    7 r4 f* ]5 ^9 g5 i  r
  507. STA M19_IRQ_COUNT_H1 I$ u; K. O0 ~: n2 _" E4 k8 q6 {
  508. 3 I6 y8 l' `' z4 k: P
  509. IrqProgramEnd
    - q8 d0 q' V' m  w7 z; U
  510. PLA
    5 Q  Z% n- G# q- ?
  511. TAY7 T% W2 p  Z2 @
  512. PLA# R# I1 V: H8 c6 N; G
  513. TAX
    ! S' F7 @: [7 m: v
  514. PLA" ?: a  Z2 `  m  u/ R
  515. RTI
    8 h/ d8 D" v! n2 G. \
  516.   f! R. Q- U( @# [0 {& P8 `
  517. ;==================================================
    - l- d4 W' f. Q9 p9 K* f
  518. ;中断表
    4 Q" M3 B/ i% ~/ x- @
  519. .ORG $FFFA
    & h1 U6 |3 q# F1 ~( H8 g
  520. .WORD NmiProgram/ P# Q6 S) f: l* F2 q: q6 j$ c& A
  521. .WORD ResetProgram
    + D* i- P* l5 u/ c0 H  h, E7 _! |
  522. .WORD IrqProgram
复制代码
- O% I$ e, E8 Z9 s& k- [) U* x* o

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-11-18 22:23 , Processed in 1.075196 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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