EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]5 e. Y, {0 e; e/ U( G
  2. ;FlameCyclone 20230710
    5 w' N+ }; J) I

  3. # w3 v& l+ \, m
  4. ;文件头
    # w5 y. }; c* l+ u: ]
  5. ;======================================================================/ K, o  N) B5 q% L9 i" l, F
  6. .INESPRG 4                                              ;16KB PRG 数量
    6 i  b  w* T! F$ m! d7 \
  7. .INESCHR 1                                               ;8KB CHR 数量" E# W; o4 H& J/ p# g* \" y: I
  8. .INESMAP 19                                                 ;mapper 19
    4 t  X/ h3 \/ b. J' a0 ^1 @2 h
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直, |# h% u0 q, g  u, q8 c8 I

  10. 7 ^# Q; D5 ^' N7 u
  11. ;必要条件" S/ `* T% H( R# v' k! P+ a
  12. ;1.持有CHR ROM2 g$ e' H7 g5 d% o7 e  v" d" u
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    4 p, @8 ~2 Z4 `
  14. ;3.精灵内存(OAM)不为空
    + Q/ d6 x, z0 u$ h1 t. B. n9 t& {& h

  15. ) v7 f; s  l* b7 _
  16. ;==================================================
    2 T4 _9 @* A6 j" H
  17. ;NES端口常量
    % {1 z# _# ]5 }* I' q( ?
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    9 j+ A- F5 \# L! J! F
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器& O0 n& _( G1 J9 ?5 `5 M
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位2 u9 w0 ~( b/ K
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1* f3 R0 t' L% M. t) C+ }) D& T, T
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加17 `5 U) ~" {+ J2 Q( B' {
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 . p" Z4 r# V+ Y. U% K$ Y+ c- K
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加1 H7 C$ T" W5 L0 ?+ h( T
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 5 E1 q+ a6 V8 \5 V1 a
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    3 S& S3 f* |1 o
  27. APU_STATUS              =   $4015   ;声音通道切换6 y: \: u* \  r4 K9 N
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通2 i  k; X, B% b4 A9 j
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通* s6 {" C, }" Z

  30. 4 X6 }: `8 ^1 |( [: p" k6 v* z( B
  31. ;==================================================4 E- }/ g+ N) G6 Y
  32. ;MAPPER 19端口常量: p% Y  z5 K7 }
  33. M19_CHR_0000    =   $8000( v7 N! \# n$ ?
  34. M19_CHR_0400    =   $88000 q5 p$ _; f/ u, V+ s* F1 e& u
  35. M19_CHR_0800    =   $9000* X5 R9 ]" Z9 M, z2 }
  36. M19_CHR_0C00    =   $9800- |* ?* c$ Z. g
  37. M19_CHR_1000    =   $A0009 z' K1 t# M" V
  38. M19_CHR_1400    =   $A800
    6 D% u' V! b, q- i# G& d
  39. M19_CHR_1800    =   $B0002 u& [( W- S; M
  40. M19_CHR_1C00    =   $B800
    4 A! i- J  b/ |, |
  41. M19_NT_2000     =   $C000  S! G; X; B9 I3 @$ }/ @
  42. M19_NT_2400     =   $C800& I% b! t8 g+ f
  43. M19_NT_2800     =   $D0003 [+ p0 _, D# m5 [& r0 J( W  ^
  44. M19_NT_2C00     =   $D8006 W" `7 O8 ?% V6 W  ]
  45. M19_PRG_8000    =   $E000
    & N6 t$ ]  x4 c( ~# x& i
  46. M19_PRG_A000    =   $E8003 f  c) \' U( o0 L
  47. M19_PRG_C000    =   $F0001 N% T3 I9 j' q, ?. C) J! v9 ?' n
  48. M19_IRQ_COUNT_L =   $50009 N( B8 C. W, g, ^
  49. M19_IRQ_COUNT_H =   $5800: x2 L* c8 {# A# J

  50. , n% u: I! A* q0 c5 ~! {
  51. ;==================================================
    - ]0 ]1 t2 g8 y9 d* c" Y% [
  52. ;程序块配置
    & O( C0 M1 E3 |/ _4 C2 j
  53. BANK_DATA_MASK          = $071 N2 F  m3 M% }' j
  54. ;--------------------------------------------------& y% ~/ j! C# A3 M
  55. RESET_BANK              = $07; q! S- b* j4 {2 P. T
  56. RESET_ADDR              = $FC001 |3 K+ {0 C9 |0 i) A0 ~

  57. " q* H) j' b: e6 J6 q/ ~
  58. ;==================================================
    # x2 H5 M) T4 [- |
  59. ;图像块配置! b' n/ Z+ Q6 j) ]( i5 e
  60. CHR_DATA_BANK           = $08# C6 ]3 d7 S) |* I- t% N

  61. ) O! Q; S* V1 ?0 C& H
  62. ;==================================================/ l, [" K$ p- {- a6 E! h
  63. ;零页内存地址配置/ V9 \* X, F, o7 J: o5 `
  64. Use_Ram_Addr            = $80
    * y' s7 M; t% t( M
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    9 s- X; `1 v/ ~7 C6 H  ~
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01) \$ j! M' z4 @1 G
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    , x. D8 k" S, b5 P
  68. PPU_Scroll_V            = PPU_Scroll_H + $01$ {; p2 C' h& o+ y7 R
  69. FC_Data_L               = PPU_Scroll_V + $01) r6 K8 N% p8 v' l
  70. FC_Data_H               = FC_Data_L + $01
      B6 ~6 T6 W; x
  71. FC_Data_Buf             = FC_Data_H + $01
    4 p+ b9 h0 Y+ |( k! v
  72. ;==================================================/ S; l+ p3 s7 `, J2 Y5 q

  73. 8 O, D/ S+ L8 _2 S; c) m
  74. GAMEPAD_MERGE_FLAG = $04: S5 b( a6 d$ q9 l

  75. " N3 k; U7 g% a/ |, }
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    1 l! s3 _! p. @$ {+ A2 R
  77. Gamepad_Once            =       Gamepad_Keep + 2. ?  Z  Z- |+ f4 u7 G
  78. Gamepad_Temp            =       Gamepad_Once + 2# N& B& ~) W3 A; }
  79.                                 . p& T; I( q3 d
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    / T% f/ O. k. M; ?, c$ n' `  D
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    2 @; C) t* [5 V0 u( c
  82. Gamepad_0_Value         =       Gamepad_1_State + 19 p- z* y0 X  s: @: y
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    4 r) D" Q& C" v  k  U1 O7 n
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1/ E* i# k! ]5 P2 `: g
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    3 ^7 b6 C; b) X  \4 X: X8 w

  86. 2 i: E; C3 |3 Q5 c) [2 k8 X
  87. ;==================================================
    & w9 K2 Q7 N# E0 Y" ]. e" R1 d
  88. IRQ_Index               =       Gamepad_Merge + $01: P( H% T1 h% L, ^* ?
  89. ;==================================================
    + u! p9 I1 E8 [/ ^0 k/ ]* N

  90.   b% ?# Z$ I& U
  91. ;CHR图形数据. Z8 O: ^1 E  L, n0 E, z
  92. ;==================================================
    1 f0 E1 L5 D9 M, J* x6 T9 R  |
  93. .BANK CHR_DATA_BANK. U2 U9 K; G% K0 {2 m$ Z
  94. .INCBIN "chr_bank/chr_data.chr"( C+ W" Q' o! v; T" P* _' [
  95. $ T2 n# y# B1 g+ a' i1 u& y5 A$ Z
  96. .BANK RESET_BANK & BANK_DATA_MASK: e2 \- s  T, r) j) S5 q7 L  d- W! `
  97. .ORG RESET_ADDR6 b  T, _" ~1 E9 l; G/ H; _0 W
  98. $ I) c+ G  f% `% Q
  99. ;--------------------------------------------------
    ( Q- n0 X- Z  P8 J
  100. Attributes_Data3 p0 R. a+ k, B' g5 \
  101. ;命名表属性* A% _0 V3 Z, }) h& F
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    $ g/ i' u% A1 g7 C+ A: O- t; ]3 h7 W* G
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA$ S& Q+ f. k& o3 ?- [, Q) o
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    0 m8 L+ @' `7 C) z6 q" m; _
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$555 ]# R5 I( A, l% k
  106. ;--------------------------------------------------  x) V+ j" |1 s
  107. ;调色板数据
    7 g4 j; q' m# G5 L, v
  108. Palette_Data$ H# ~8 ^  x5 m( e1 N0 [/ W
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F7 Q) }* V* `! R/ ^- C# o
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 k5 a0 x' ~/ O0 M$ ^) U( F1 Z
  111. / R. o9 i8 D/ H
  112. ;==================================================: x" ?: q8 w( p' P
  113. ;命名表初始化
    6 o3 ?$ t8 {& P5 e
  114. Init_Name_Table) e( s3 G" F, @- h% Q
  115. LDA #$20
    ! h7 r! j. i" b# G# N& m8 _# T
  116. STA PPU_ADDRESS
    9 v* u. t) P* t+ k5 W
  117. LDA #$00
    1 T3 j2 |1 }! e; Y' a
  118. STA PPU_ADDRESS, y  [: k9 h7 `2 R- k1 w
  119. LDA #$00
    , ~1 I: [0 U) P+ y" E) P6 s
  120. LDY #$00
    " n* S0 p- b! `
  121. LDX #$10/ Y1 w9 x# C* ~1 j3 Z+ a2 e
  122. Init_Name_Table_Write* u$ `1 [5 J3 N
  123. STA PPU_DATA
    ) v) C- f8 P  A% j0 X' n
  124. INY) j5 N+ L& r1 E
  125. BNE Init_Name_Table_Write7 F7 N, f9 N( ?: k5 s1 K: A1 v
  126. DEX* d% m9 m. p9 B8 v8 d
  127. BNE Init_Name_Table_Write! ~9 E6 B$ N2 O3 w; p0 n+ {" p
  128. RTS
    6 l2 V% b3 \1 q6 {
  129. / s" U* W6 H2 w! f; u( [, o; o4 B( a
  130. ;==================================================
    % G( @5 [% a- t; j1 x
  131. ;调色板初始化
    + l6 ~& R" S/ ^# E& ^
  132. Init_Palette
    ; j& |- N" J7 D6 w
  133. BIT PPU_STATUS7 n7 v7 y% Z7 ?# t
  134. LDA #$3F2 [' S: a! g  A$ i
  135. STA PPU_ADDRESS
    ) A7 Y5 A) v3 C! |7 f; ?" N. `
  136. LDA #$00
    ! n- J. L7 }: n4 B
  137. STA PPU_ADDRESS0 ^0 P- g9 o/ i0 _1 ?, q/ ]* l; C
  138. LDX #$00& m/ e4 S7 S; ]& y
  139. Init_Palette_Write
    $ _$ A! t1 v  E) P& T: B
  140. LDA Palette_Data,X- O% I# e2 ]1 b' Y+ D5 v) B8 {
  141. STA PPU_DATA2 t7 \" n5 x* b% n, m
  142. INX# T: m3 H- t6 k# X
  143. CPX #$20
    & J8 v9 |  L6 e# b' a( ~
  144. BCC Init_Palette_Write
    9 u$ E1 {) |5 e/ \$ V, n
  145. RTS
    " y; g  Q) o5 L. G6 G
  146. " e( d6 [! H1 O  [
  147. ;==================================================
    + Y. l; E& @2 M1 g0 T8 P
  148. ;设置命名表属性( I# |; }# W' {7 e* J! t: L
  149. Init_NameTable_Attributes
    ( r9 k; M5 O/ y8 S  m9 v
  150. BIT PPU_STATUS5 S) v0 S7 p+ z
  151. LDA #$23
    ) m8 J# C' q) l& D, c
  152. STA PPU_ADDRESS3 N5 d/ @  i5 @- V  ?  E
  153. LDA #$C0& k3 H' t4 ^/ y. A# k" H" ]  I
  154. STA PPU_ADDRESS) G7 y! y  {$ y7 E0 ]! O) Z# J" E
  155. LDX #$00# T! y' F; H0 j6 u, e2 D% }+ g
  156. Init_NameTable_Attributes_Write
    ; Y! [9 d1 m0 `& `$ d
  157. LDA Attributes_Data,X- N+ m' I3 n0 W  C
  158. STA PPU_DATA6 C: j$ z$ G2 O5 X# E
  159. INX9 c: J) V/ W5 r  o
  160. CPX #$402 ?' L  ~. q: c9 n& u( ?" W
  161. BCC Init_NameTable_Attributes_Write) `& Q7 E* p) P: t4 U( }, P
  162. RTS4 W6 N5 w# x' x2 r0 V& r6 l. c2 L" D
  163. 5 U1 K" w/ A' K8 p- C% V
  164. ;==================================================
    & T, ~$ S1 `3 C; c0 Q
  165. ;初始化命名表文本- d; N* \1 G0 E9 V. {; r
  166. Init_Name_Table_Text7 w- e4 k- F% L! A1 e4 U2 K
  167. BIT PPU_STATUS' b6 B  l. W, ]1 I. V- `' {
  168. LDA #$201 y  A  r) d4 M2 _
  169. STA PPU_ADDRESS
    % x* A5 o" D) d# i
  170. LDA #$00/ C& N" ?4 s. C& I0 [
  171. STA PPU_ADDRESS0 h- ~8 \4 C& `  S( ^" I
  172. LDA #$00; T8 i5 ^( F1 R; h
  173. STA FC_Data_Buf3 B) l6 i( W0 e  M2 P$ g
  174. LDY #30
    ( ^+ G# ~5 y) F2 e4 E
  175. Init_Name_Table_Text_Write) x+ D0 `" h" O: m! G. M
  176. LDX #32
    $ r5 Y: k/ U3 z; j& P! R. u3 `
  177. Init_Name_Table_Text_Write_Char- R. _# h/ B" S6 f4 p1 V
  178. LDA #'0'
    8 j" C+ B6 P/ J
  179. CLC
    ; P2 d0 L5 g& i; V
  180. ADC FC_Data_Buf) Z/ E5 M. D* C9 V& Y
  181. STA PPU_DATA
    2 S, h1 h5 N8 ]+ u# V7 V% o* ]! q
  182. DEX  d/ k3 d6 H& b) ^% _9 `4 ~3 V
  183. LDA #$143 o' ]( U$ R$ ~8 M9 B% ~5 `
  184. STA PPU_DATA
    1 C' t6 G  \- x# g; @+ ]
  185. DEX
    + t* \4 f4 k* D& v) I4 Q  r* g
  186. BNE Init_Name_Table_Text_Write_Char
    # d3 Y/ \. X0 ~, m' T) i+ X
  187. INC FC_Data_Buf/ ^9 _+ ?# u* ?
  188. DEY" B9 V5 b$ q# t8 B$ r
  189. BNE Init_Name_Table_Text_Write0 y* i6 \* J1 K9 P* y& n
  190. RTS& b4 v) P6 L2 M/ j- R& w1 _" {3 H5 i

  191. 2 L: H1 e) V' m" H1 S
  192. ;==============================
    7 m3 q0 k4 ~* G* q! y/ T$ j4 }
  193. Init_OAM_Ram;初始化精灵内存  ?: _( r' t* |* J* C* o! Y2 f
  194. LDX #$00
    5 x& n% b" b5 \
  195. LDA #$00
    - l3 e4 v# t- M7 j6 P2 m- U( n9 q& {2 k
  196. STA PPU_OAM_ADDR
    ! [9 N% Q$ g, d! t
  197. LDA #$F8
    ) n7 F* ^5 j$ \+ G! t0 t0 a0 O
  198. Init_OAM_Ram_Write6 s: z3 k4 l- `, G/ p* l1 z  r" _
  199. STA PPU_OAM_DATA
    ! o1 o0 C! w5 l
  200. INX
    $ n% D4 {. c: c/ `% E1 M
  201. BNE Init_OAM_Ram_Write
    * g/ P" s* R. p( N( I
  202. RTS6 Y$ Y6 _; M0 [* \0 ~9 U

  203. * A% P( s6 L; C+ h1 N
  204. GamepadProcess;手柄处理/ O$ P- O  t5 U$ f
  205. JSR GamepadDatacan
    $ a2 a4 f7 J3 g( {
  206. LDA <Gamepad_0_Value
    5 \! \% g) ?% t5 P; ]
  207. STA <Gamepad_0_State
    8 R- M  V; L. W% d/ @8 f4 f
  208. LDA <Gamepad_1_Value
    2 A9 }- F7 u# n; D5 T) @
  209. STA <Gamepad_1_State
    ' B; J3 A( B7 {" w3 P
  210. JSR GamepadDatacan
    * l; t  T; B/ d3 ]  H
  211. LDX #$01
    6 D3 m( ~$ ?3 `4 t  o
  212. GamepadMergeCheck;合并手柄输入检查
    9 _  R8 O& |* ]) |" V
  213. LDA <Gamepad_0_Value,X7 B; x' `. i. v9 }& z" w" z
  214. CMP <Gamepad_0_State,X4 N" z0 I. C+ f5 z$ f1 L+ x' J1 D
  215. BEQ GamepadMergeInput1 ?5 O! B" `% U7 W% V
  216. LDA <Gamepad_Temp,X: f  B* R! E+ E1 i
  217. STA <Gamepad_0_Value,X
    - S/ w4 Y$ H6 z# U4 J+ X, n4 m
  218. GamepadMergeInput;合并手柄输入& r! n+ z* C% U3 |4 U+ K
  219. DEX
    7 q/ x5 }" }* b8 J0 _
  220. BPL GamepadMergeCheck, w, S+ n9 c  M( p2 }+ U/ f
  221. LDA <Gamepad_Merge0 \+ @$ d/ j7 A0 H! W
  222. AND #GAMEPAD_MERGE_FLAG- G4 i; Z1 Z1 P) Z3 X5 C
  223. BNE GamepadStateProcess
    4 x3 x% ^5 m8 X  y3 E! e$ H
  224. LDA <Gamepad_0_Value
    5 S: `" Y: g* E. c* a2 V! b3 j* ~
  225. ORA <Gamepad_1_Value
    2 N! G$ I9 a& W6 E$ r7 L% x
  226. STA <Gamepad_0_Value! p& H1 X+ j$ s/ j( }
  227. GamepadStateProcess;手柄状态处理
      Y4 e0 F3 K/ l& x, t: c
  228. LDX #$01
    # i8 J! G% w0 G4 V7 H: E
  229. GamepadStateSave;手柄状态保存& B; z' }. ~6 S8 T4 ]6 O
  230. LDA <Gamepad_0_Value,X
    6 w5 ]+ M$ {* ?% N( s
  231. TAY4 F, ^8 Z* J  G# B4 L4 n7 C
  232. EOR <Gamepad_Temp,X
    ' M3 K! ?, U$ [$ {. q7 m
  233. AND <Gamepad_0_Value,X' d: N0 z* ]! x0 f" x
  234. STA <Gamepad_Once,X
    * j. l# o5 j: ?- C; d" N
  235. STY <Gamepad_Keep,X/ F2 }' ?3 @- h+ @
  236. STY <Gamepad_Temp,X
    ' o1 N+ Z( b1 f" x: S- m
  237. DEX
    , q7 M, V/ L' t0 T0 c- L: P
  238. BPL GamepadStateSave
    / d- E' I% o' ^
  239. RTS- _* K  a3 s$ U& z

  240. 0 g! A0 j1 ~% v' A9 E6 H* U% n. }
  241. GamepadDatacan;手柄数据扫描# W# r8 q7 C- H
  242. LDX #$01
    8 s% w! r% J  s8 I  k/ S% a
  243. STX $4016* M( e7 L' V0 Q+ E  J! d
  244. DEX- u6 P; d. c8 c' [, z( e1 y
  245. STX $4016( ]1 }5 j5 M, L6 b  i
  246. LDY #$08
    0 w+ ?4 S4 V% h; _1 X0 q
  247. GamepadPortScan;手柄端口扫描, Y; d8 w8 S5 n4 ]0 ~; K
  248. LDA $4016
      h; \- C  u! F  G6 ]
  249. STA <Gamepad_Port_Value
    ; j# m. i9 F# V1 ~2 J  ^# q7 r
  250. LSR A$ d; Y" l$ e& e$ M
  251. ORA <Gamepad_Port_Value
    " C; Q- v+ }7 i' L0 W1 ]' z( ?
  252. LSR A
    & P- o# r( _# H* {9 ?
  253. ROL <Gamepad_0_Value+ P" l% T' {* a6 a4 K5 w
  254. LDA $4017! d( N, r6 t. B# \
  255. STA <Gamepad_Port_Value
    ) @$ C/ u! c7 |" ?5 y8 P
  256. LSR A* m5 u8 k5 Y% f& z5 N$ e1 {
  257. ORA <Gamepad_Port_Value4 ~! j% \& w1 R- g4 e" H5 ^
  258. LSR A& W7 z7 q) i" O- l1 D
  259. ROL <Gamepad_1_Value$ v- f: N/ Y3 a3 f0 F4 H+ |! u5 B  U
  260. DEY" s( i) I8 X+ E! R" Q7 R0 I, ?0 Y
  261. BNE GamepadPortScan
      l, K) R3 {4 p* T0 E  y2 D0 E
  262. RTS
    3 K: t0 I& D2 ~$ x

  263. $ J4 D  k) p3 m2 ]  S
  264. ;==================================================# E9 T! Z4 u# g
  265. ;PPU处理4 c2 s5 w6 y! z: z$ }2 K' {
  266. PPU_Process
    3 m" S* K8 q# z$ J+ G5 c
  267. LDA #$001 k0 T( Y4 c& u' G7 O! Q6 l
  268. STA PPU_MASK
    , n5 N& Z. H  E. x  X. A/ G
  269. % h( s; ?6 \( e$ }  H4 s" c
  270. BIT PPU_STATUS
    7 l* C8 Z) }7 s2 B/ A: r; Y* }9 G8 O
  271. LDA #$209 [( W/ @8 I8 j6 p. ~2 Q  M1 j
  272. STA PPU_ADDRESS# w6 R' G9 a, `" z0 _0 |1 f6 M
  273. LDA #$006 @7 U9 u/ r& l! D5 ?
  274. STA PPU_ADDRESS# j6 N5 n7 C( }$ {) ]! J
  275. " _+ p2 d, F( z$ v) I; p$ _
  276. STA PPU_SCROLL
    ' y: M: l$ _  O0 N( S/ O1 P5 @1 q
  277. STA PPU_SCROLL: j9 F2 J9 Q/ u1 F: f
  278. ) p/ h' L, d$ A- M
  279. LDA PPU_Msak_Buf9 C/ z, \4 {3 y6 y' |' z) B
  280. STA PPU_MASK
    / q7 E+ \) i: q) ^/ ^" l$ F
  281. ; _& b6 V6 p& W
  282. RTS4 ^! Z0 U9 E# s
  283. + t0 s3 F/ o5 T
  284. ;==============================* J+ O/ F. @  `# m4 l& s
  285. Time_For_Vblank;延时等待: @" k, N2 F8 D% v0 ?1 @" ]" q1 D& ^
  286. LDA PPU_STATUS
    6 a( X: _! o0 T& ?3 `) Q1 Z$ K) p
  287. BPL Time_For_Vblank
    8 o3 T! Y# ^8 f8 I4 m# d
  288. RTS( a$ b2 @3 a& T! A
  289. / W+ s) ], C/ o+ r
  290. ;==============================
    % y  ?( F4 r- |# G. F
  291. ;初始化MAPPER197 v% P. G& a) S2 c% e
  292. Init_Mapper19$ y  o: y, r8 T4 i$ ~2 |* q
  293. LDA #$001 s# ?4 U) {( O6 J; S
  294. STA M19_CHR_0000
    , n( J1 h/ v8 r2 \% i1 d/ E
  295. LDA #$01# B6 R$ v8 n1 j) g# \/ a
  296. STA M19_CHR_0400
      Z. j3 z* K* }5 w2 J. p& l
  297. LDA #$02
    : B. H2 b7 I! f$ b5 u
  298. STA M19_CHR_08003 w9 k/ j- T) X/ D1 L, @% Z
  299. LDA #$03
    ) T/ B) l& J3 v8 n: V# `& Z6 w
  300. STA M19_CHR_0C00
    ; v5 j; Q" Q/ a# r! t
  301. LDA #$04
    0 \9 c2 l( M- U1 y9 a  x) K
  302. STA M19_CHR_1000$ S7 _# Q- D' [( F* q6 S6 ]* x
  303. LDA #$05
    / Q6 Q+ i( n: J! O
  304. STA M19_CHR_1400
    ' Y* E2 x9 |5 m- j+ B
  305. LDA #$06
    + ?2 D5 g; ~3 g% |$ d
  306. STA M19_CHR_1800
    8 ^! Y- E2 I% [! ~6 e" t: i
  307. LDA #$07
    ! k4 G- H$ E( Y* F) t: m) d: A
  308. STA M19_CHR_1C00
    3 M2 W, w$ J9 T5 n4 R5 w4 @7 ?

  309. 3 H( E" d! z) B' b+ X" H! v! W
  310. ;禁用IRQ
    7 Y0 a; [7 r# X) F8 f
  311. LDA M19_IRQ_COUNT_H$ V$ z6 r' O: d
  312. AND #$7F( M- j/ H2 T" U# |$ k
  313. STA M19_IRQ_COUNT_H8 S3 n( m" ~- T: Q( U# t; L* \

  314. # i5 c6 x4 G# D: _
  315. ;命名表
    0 U( d9 E& r: d- S: X3 w: V
  316. LDA #$E02 V) d6 D* P7 |3 E) J
  317. STA M19_NT_2000
    5 E: J1 _) y% U% |/ Y" U
  318. STA M19_NT_2400
    / [. n. |$ N" }4 `; k% N2 W# ^
  319. 6 N. C* Z9 h0 [% `
  320. ;命名表6 b/ T8 Q6 H# D4 u& c1 r
  321. LDA #$E1
    - Y2 f4 v2 ?/ H2 k
  322. STA M19_NT_2800- Y( \! r1 a' ?
  323. STA M19_NT_2C00
    4 C2 t5 C) Z* U" S* r* \

  324. 8 Y+ ~/ B+ \0 b' c" M: l: `( O
  325. RTS
    2 w: M+ d7 o# s& Z) @- y' L5 t

  326. 2 [1 `1 |4 _6 d! c; ]$ f; ^
  327. ;==================================================0 j2 H) o) c% G; q& R4 q8 e. m
  328. ;重置中断处理
    1 |2 ^8 f0 Y' r# Z5 z8 P( e' z3 Q
  329. ResetProgram2 {8 `8 s. D# l) t
  330. SEI7 H" e7 R+ h+ U) ]
  331. CLD
    5 x& G6 E! e* b. T0 u
  332. LDA #$00
    ) o9 o# y' H- t. g: J
  333. STA PPU_CTRL
    & }9 J3 U3 G7 g. W& J
  334. STA PPU_MASK* E3 s# g, X9 v! J1 @3 t3 d; W: e
  335. STA PPU_STATUS$ ~% O- J; W, ?
  336. STA JOY2_FRAME- c, L& G0 w9 W5 z' _
  337. STA APU_STATUS; l0 r, q9 L, B" x. v
  338. $ h2 ?5 t5 l" X8 |
  339. LDA #$C0
    9 n$ _/ s, S$ `8 f
  340. STA JOY2_FRAME7 @* C' g' s) w7 V

  341. & h4 k" p4 [! ?( ~" O) x( D% y: Y
  342. ;等待vblank
    4 k0 ]* W; V1 w1 A( I& ?" a  ]
  343. LDX #$02
    0 X. X  C( q7 y( d, s& |0 g
  344. Vblank_Wait_14 x0 o2 f' {3 O7 ^
  345. BIT PPU_STATUS) U, Y+ a( ?7 D1 X/ w( y
  346. BPL Vblank_Wait_1
    * C. X/ S, ]2 X+ v0 X
  347. Vblank_Wait_2, n1 Z/ a5 h: F7 m! y
  348. BIT PPU_STATUS
    2 q% z5 F4 a6 q* r5 x; e
  349. BMI Vblank_Wait_2* |2 J6 Q8 Y5 i, ~( j
  350. DEX, b# l2 @5 p7 ~4 r
  351. BNE Vblank_Wait_12 i1 u- \4 h- D+ _. T+ B

  352. ) w3 V+ w1 N1 Z$ l4 L; @
  353. LDX #$FF
    " b& q! L* c" F, f" Z7 j
  354. TXS
    " G' f% p, ^: s; w9 _8 L

  355. # F- K9 d5 ]6 r3 _& p+ P/ d
  356. ;初始化MAPPER19
    ) S" Q! l! E, S# y
  357. JSR Init_Mapper19
    . ]' ~0 H  m3 j) ]# c( M

  358. - u) a% h4 T3 W
  359. ;==============================2 S- {% d0 q/ t+ H5 {& F- t) F2 `
  360. ;RAM初始化! {7 |" y9 R/ r- C9 E7 c
  361. Nes_Ram_Init% b; {8 ^2 P# h  i) f4 y1 }
  362. LDY #$00, t& a% c: L# H/ m( O8 x
  363. LDX #$08
    . o" n0 w3 \4 Y" h2 H
  364. LDA #$00* r3 o( j3 q! S
  365. STA <$00& {; T- \# M# O  Q6 A
  366. STA <$01) A/ g+ x1 m' `7 L; t' n1 p
  367. Nes_Ram_Init_Write! T7 L5 E, P& H0 Z2 p# H' O
  368. STA [$00],Y
    % j( ~# ^, r, _% z. N7 f
  369. INY
    9 y( w! m4 R5 k3 e- f) ]# f
  370. BNE Nes_Ram_Init_Write
    4 ], H! u% N6 L5 s
  371. INC <$011 \+ X+ u. \2 J! S
  372. DEX* o! M% v& F) P/ g# C
  373. BNE Nes_Ram_Init_Write
    ( z0 J! [7 @$ k2 R# {
  374.   b( Q" R8 _: H( e7 z# g2 o
  375. ;初始化命名表  m) B1 m9 u0 n
  376. JSR Init_Name_Table
    ! B' C( v2 ^' j5 e: |% X8 G
  377. % j' k( p+ O* r
  378. ;初始化调色板4 v8 w/ N! O8 e! k  P
  379. JSR Init_Palette% ^: q2 g  j  E+ y
  380. & n6 d. G# }# i
  381. ;初始化命名表属性
    5 U! n3 @4 T' r' v
  382. JSR Init_NameTable_Attributes
    % u7 y/ V' g' I4 D

  383. . i$ x0 N: B3 i) l9 N
  384. ;初始化精灵内存
    5 n% b# R  W$ n/ _
  385. JSR Init_OAM_Ram
    % F( z8 X+ K5 i# s

  386. . g9 r, x% Q& r' y9 @  J
  387. ;在屏幕上写点东西1 N( ?% U3 `$ z- V+ D
  388. JSR Init_Name_Table_Text
    5 W+ ^  \4 a: q" x8 W
  389. ) S" H0 c# T# t% g3 {2 ^
  390. JSR Time_For_Vblank9 J5 h7 W& A( b% y2 A! |. b2 Y" N
  391. ;开启PPU控制9 y" ^; e( i4 {" w
  392. LDA #$A81 i$ c; }0 F- B3 _9 |! j
  393. STA PPU_Ctrl_Buf" ^* k8 F- Y  M/ u3 `; {5 O( a
  394. STA PPU_CTRL
    / o* T) `7 f1 D. n- b2 @, M

  395. # i( N( ]9 Z( n, q2 w; P
  396. ;开启PPU显示
    0 u: u# `) c4 c9 N
  397. LDA #$1E
    ) k, a( l9 M/ o8 e  q
  398. STA PPU_Msak_Buf, f7 P$ `2 u2 y8 t# z# E4 k. q0 ?

  399. 5 F9 H. R2 p& t2 e1 C, `
  400. CLI7 ]/ Q8 w( j0 O4 o
  401. JMP Loop" [; X) ?! _+ K

  402. 0 z! J  l: ?/ }( c2 f0 b
  403. ;==============================
    . U3 [+ v/ [- g) q* W
  404. ;死循环, 等待NMI中断
    & f: p% T+ E% ?" N* T
  405. Loop! l9 U0 p  E$ b* m+ C2 k- c, l
  406. JMP Loop
    " e8 B/ c8 N, z$ W4 m
  407. 5 V: E& a" T5 r/ a
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967" [1 K9 A) j5 |# c( l: c2 P# R

  409. 3 n8 j! X4 }! b$ M. }
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    $ b' }: D' U: d/ J. d
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)% n. _5 U3 q4 p) _7 M8 h" J
  412. ;==================================================1 I0 B$ e" W! U8 o2 m  U' t' d
  413. ;NMI中断处理4 U; S! p" Z9 Q" O2 i8 T4 i6 m
  414. NmiProgram4 U5 g( V& G/ _+ h' l
  415. PHA0 k; v* t& i- e; X! T) b1 v
  416. TXA
    ! n! q( n& \" q$ X1 Y, _
  417. PHA
      L1 p9 ?# _0 |
  418. TYA0 j" j9 O1 r* H1 ?# x& N
  419. PHA# K0 h8 g7 {2 Q

  420. % A* X- Y0 f' S
  421. BIT PPU_STATUS
    ; d2 D0 E) x# H0 z2 J
  422. $ J) R4 `0 I! b. u% P$ Q
  423. LDA #$00
    $ G7 r2 |/ P/ u/ M: P
  424. STA IRQ_Index
    / e- V! B+ ~; H1 P2 ?( B; a
  425. $ g: T- R4 T+ w5 ]0 t/ J
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动* @  m( I+ v+ F$ K3 c4 L7 Q) H
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    9 n/ l- c- [! h9 O1 Y5 Q
  428. STA M19_IRQ_COUNT_L
    * {4 [% o3 q: d6 b8 ]
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)" h6 C5 }8 A/ g( b; O
  430. ORA #$80
    ) X0 \2 d+ M( k  e+ ~! q! @
  431. STA M19_IRQ_COUNT_H* b3 n& G" M' D- x
  432. CLI
    " r  T1 P, L. D
  433. - ^$ ~6 K! U7 y0 b' q1 p
  434. ;关闭PPU控制
    - T5 y+ w6 j! s, L
  435. LDA #$004 e5 q# f! S; `5 }" w
  436. STA PPU_CTRL: g! `% C1 n/ s2 D# N& z6 w

  437. % @: Q# B* N4 q9 U# @' I( K
  438. ;处理PPU% _  D. `4 A% K
  439. JSR PPU_Process
    " Z" p5 s# `- H/ R9 P

  440. ' s& j% }! H1 x& g
  441. ;开启PPU控制
    ; ]7 U1 }$ v/ p; Z
  442. LDA PPU_Ctrl_Buf
    . ?/ L! I- d; I  K# Z# L. m+ i' g
  443. STA PPU_CTRL
    9 x+ S. A1 S2 x! r7 E4 u; C3 t6 V
  444. ' m8 o4 X/ P, ~* Y9 c! z
  445. ;手柄处理
    & L- h7 R5 ]' s7 f4 q
  446. JSR GamepadProcess
    ( U2 L8 J8 t) T. c7 s5 g

  447. ) Z0 b" V2 ^$ H2 v
  448. LDA #$006 C5 N. q0 Z4 ?5 V" H, n2 m3 A
  449. STA IRQ_Index* E  g9 A8 ]( Q& e9 v) c% ~

  450.   A. J  C, M! b& k
  451. PLA
    2 }8 s2 ]' a2 U. S6 X! k: x; k
  452. TAY
    3 j( f" ?! G+ X7 S# |
  453. PLA+ I3 t: ?" H9 J( A- l  A
  454. TAX
    , N1 \6 G) q. q1 o# x* J* K
  455. PLA( @0 t. F1 I, h
  456. RTI0 Z. u5 @8 B9 y/ s* `, A

  457. 7 d( @! A' H! \( q3 [/ v
  458. ;每行扫描线113.679 p% y, I' L# g. _5 l
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)+ ~8 @3 A* T' y' Y' h+ H3 p
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ( G* }4 n) i" B* r7 p5 D0 A
  461. ;==================================================; L* U7 b8 ~0 B0 ]: L
  462. ;IRQ中断处理
    ' n7 X( q6 ^4 e5 w" F
  463. IrqProgram
    " y* A8 k- i. T
  464. PHA
    & n6 j" n! z1 |
  465. TXA0 l; x" |1 M$ M/ [
  466. PHA, \9 o3 B" @- d3 e/ W  x& _5 Z2 p
  467. TYA
    ( k5 w' K/ `  m/ N5 M. @$ o6 o" d
  468. PHA
    0 n) r1 t6 g+ V# i% V
  469. ' x$ V% ~, `6 u4 P5 F; b
  470. ;16条扫描线后触发IRQ
    1 H& ~# p: ]! T; W$ M
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    ) V8 {( H. z" i
  472. STA M19_IRQ_COUNT_L2 z0 R( \. J( B2 Y0 a$ b, J5 q' [
  473. LDA #HIGH(BEGIN_LINE_CYCLES)0 \" N; l' `3 T' K8 h/ f- F8 a) ?
  474. ORA #$80; R4 x5 |' }! S- k: D
  475. STA M19_IRQ_COUNT_H& e+ i5 T% ~& P) R* y1 \5 T( q

  476. 3 e$ M: m) u0 i
  477. LDA <IRQ_Index
    ) q9 C5 t; ~' ~* g5 G3 H% A0 T
  478. BNE * + 48 e2 f5 E1 ~/ N/ T
  479. INC <PPU_Scroll_H
    # d1 f. o  t) z' ?% d  _

  480. ; a+ L  J6 F0 T. ]3 L5 P7 W% ?8 _
  481. ;设置屏幕滚动
    3 n# ~  I0 w* p* H. a  C& q6 k) C
  482. LDA <IRQ_Index
    . O; y0 O1 b4 _" R4 m- K* Y
  483. AND #$016 ~( b: Q* \1 S4 _  `# j  b
  484. BEQ Irq_Scroll_Right
    6 X7 H) P: B, P6 Z) b$ `0 R$ l

  485. 0 c% c9 C) k/ r4 c6 h8 g
  486. Irq_Scroll_Left
    4 _$ I1 H* r' x
  487. BIT PPU_STATUS  u; ]: z6 R4 Z
  488. LDA <PPU_Scroll_H! ~! F" i! N+ o4 x' X: |, n: e
  489. STA PPU_SCROLL. m0 q; J  W, k2 U5 [
  490. STA PPU_SCROLL/ t$ a  h9 o9 z5 ?
  491. JMP Irq_Scroll_Over
    % j' r, n% f2 B+ p2 e/ e7 }

  492. - \3 Q) b$ v, j  i) x
  493. Irq_Scroll_Right# c) L5 o$ n& [' R9 {4 t
  494. SEC+ d+ W. p0 w- G# O# c5 e2 h
  495. SBC <PPU_Scroll_H
    * s# r7 c; A3 b1 D
  496. STA PPU_SCROLL1 d/ j  k( C$ F7 e
  497. STA PPU_SCROLL& l9 l6 [+ `: F  m
  498. Irq_Scroll_Over: W* h  I" f5 r
  499. 5 ~7 t% A6 V2 l2 _$ {: ~
  500. INC <IRQ_Index( ]0 m) }9 ~0 `2 @( l% Q- I% Z: P/ V7 R& A
  501. 8 g+ C8 g; _) a- i+ }
  502. LDA <IRQ_Index
    4 K# b- S0 M6 {% Q, S
  503. CMP #14
    " S: o- c1 ^. V
  504. BCC * + 10$ [9 Q% O% v# b- f/ [0 X% h
  505. LDA #$00
    3 V' h1 e5 j& e- t1 _
  506. STA M19_IRQ_COUNT_L
    : C# h, c9 b1 _9 g6 {- P9 j
  507. STA M19_IRQ_COUNT_H, h0 ~6 o  {) `) }

  508. & z) F% N4 i- t: X' {) E$ @
  509. IrqProgramEnd8 k6 m( I& a1 ]  E: [. D9 Y
  510. PLA
    # Z' O4 l5 w, z4 }7 ~: f: e3 k
  511. TAY
    4 g6 g3 r2 r3 g# C/ ~
  512. PLA  }2 {8 J8 @. H2 z5 x; D
  513. TAX0 t. }6 ?, f7 j$ ]- ]! z8 `
  514. PLA
    ) A3 D( y) p1 I1 [& u8 M9 B
  515. RTI
    2 t. L. w6 ]7 B* X0 Z6 f: P- v, Z
  516. ) Z  R4 u; X! c  e+ R4 u- q
  517. ;==================================================
    & a+ S) b% @; f
  518. ;中断表0 c: Y/ k* n0 Q2 C4 {9 n
  519. .ORG $FFFA
    * O5 w& B1 ~1 e- J! v- [  i- w
  520. .WORD NmiProgram, `7 s0 _$ K8 z6 I; S
  521. .WORD ResetProgram* L, ~8 z" Z* z, `9 N; X! `, H
  522. .WORD IrqProgram
复制代码

& i" V+ K6 G" t% i. z

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-2-19 06:47 , Processed in 1.106446 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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