EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    * _6 C: R' o& f) w4 c0 C
  2. ;FlameCyclone 20230710. D% a/ F( a7 K
  3. 0 z% H. s' h0 x3 E
  4. ;文件头! }+ y) r, |! Y4 |
  5. ;======================================================================
    5 ?& S! o2 m5 O2 |" G
  6. .INESPRG 4                                              ;16KB PRG 数量: ?' ?1 [  D% r, L# d7 K7 q
  7. .INESCHR 1                                               ;8KB CHR 数量
    8 d( |: q) O9 k- Y; {
  8. .INESMAP 19                                                 ;mapper 19
    ' r+ ^+ R1 J4 b4 s$ U7 P. L' ^& {+ F
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直7 `& E/ x( U3 W, Z
  10. ) P' }0 j# g' E# ?0 d& x9 p
  11. ;必要条件  L2 ~( V" L6 N2 r: i
  12. ;1.持有CHR ROM
    + X) j/ m$ O! \
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000$ Z8 F/ d5 R& r0 m$ X6 E
  14. ;3.精灵内存(OAM)不为空
    , u& h" ?& A9 k) y* b+ i7 O0 h
  15. + N  f" O3 S# m, N/ @6 h
  16. ;==================================================
      I& i, n3 q: w4 A* b9 v
  17. ;NES端口常量* @( K. {" `, K: m: [  y* ]
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    6 s( K- z9 b$ k- H9 [6 A$ h
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器& O  j3 Y: o! k3 v0 f$ o  i; Y
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位, {) G/ x# e$ ~3 g' j2 ~9 }
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1. x6 [. o2 M# p) h; O) W7 H' _
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加14 _; P6 Y6 C+ X+ x/ ]7 N
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ; V& X$ R( a7 ]" P) Q
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加0 V. l' |$ m; M: j* r/ X
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 / a+ B! Q  a/ S6 F4 R4 h
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存; x0 t+ ~! g7 s5 a/ ?8 E% r2 z
  27. APU_STATUS              =   $4015   ;声音通道切换
    . A% Z& |2 a& g' T# T6 j0 p
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通; ^! G4 d- }+ [& Q, m: ]
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通2 c7 V$ A1 u; g- m1 w

  30. - k5 y0 ]. E  O0 S+ o
  31. ;==================================================
    $ c: ~# _% Z* H3 m. [# I
  32. ;MAPPER 19端口常量9 h2 G, S4 Y; n
  33. M19_CHR_0000    =   $80000 [5 c# P$ {) X, O
  34. M19_CHR_0400    =   $88002 a) F; j( {5 I8 P5 E' f* r7 ^5 W
  35. M19_CHR_0800    =   $9000
    % f; Z& }1 w1 n
  36. M19_CHR_0C00    =   $98008 P; i3 y! v# P& Z0 e! v
  37. M19_CHR_1000    =   $A000- S; B# U7 d* g/ q  T0 h$ C' k( k
  38. M19_CHR_1400    =   $A800
    3 w' @( d5 Y8 R
  39. M19_CHR_1800    =   $B000- D; n+ j$ T% a- X8 t$ c' N
  40. M19_CHR_1C00    =   $B800
    $ }# ^  Z  p- G
  41. M19_NT_2000     =   $C000
    $ T, p1 b7 ^7 V2 q
  42. M19_NT_2400     =   $C8006 k. l8 n2 R/ r% z7 m- I- j" f
  43. M19_NT_2800     =   $D000# ]7 r8 Z) D4 F
  44. M19_NT_2C00     =   $D800' u/ S1 z: t, T7 @6 z  O( i
  45. M19_PRG_8000    =   $E000
    * w3 N0 ~: m/ k6 }
  46. M19_PRG_A000    =   $E800
    ; a( Q  }! U! z1 L/ a
  47. M19_PRG_C000    =   $F0009 H* v# Z3 K" B- W9 Z; B
  48. M19_IRQ_COUNT_L =   $5000% l# T* D9 m) Q
  49. M19_IRQ_COUNT_H =   $5800& o& ?5 u* F! B2 h2 b- D
  50. : a( a- m. h( U  r' m+ D, `' h3 r  z
  51. ;==================================================
    $ B5 u7 ^) R; p9 Q
  52. ;程序块配置
    ' [0 S: I3 x' W. c5 t+ r
  53. BANK_DATA_MASK          = $073 e# j) W, G2 U, {
  54. ;--------------------------------------------------
    : a  v& H! `( D4 J% R
  55. RESET_BANK              = $07* r/ S# L$ h: T# y+ n, d) x7 c
  56. RESET_ADDR              = $FC00! c. o) I. o$ e7 c" c! M

  57. 7 D8 o' J8 r2 u% I% x
  58. ;==================================================
    9 T! K# ?* C! v7 P
  59. ;图像块配置
    , m, ]) g$ |6 G& [6 G
  60. CHR_DATA_BANK           = $089 ~9 m8 i6 A/ G5 [+ }
  61. / D' w# K1 w; q1 L
  62. ;==================================================
      B: o8 e2 o6 }2 Q0 B: D! b. m
  63. ;零页内存地址配置
    9 @  f- E( w) D7 I9 m* C! ]3 n) K
  64. Use_Ram_Addr            = $80
    8 E5 U% ~4 |. J+ D5 y1 l3 H
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    % P* O# v3 h- W3 j7 s
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    + R* k3 G$ [% e1 A
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    1 K3 o2 K4 d& @$ l6 D
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    0 t) S$ R. Y& u9 \  i
  69. FC_Data_L               = PPU_Scroll_V + $01
    1 r3 u. m( _( ]. O1 }* i
  70. FC_Data_H               = FC_Data_L + $01- T6 E: X. `! B4 n& q) G, h
  71. FC_Data_Buf             = FC_Data_H + $01- ^# z  C+ u: b; s
  72. ;==================================================5 `* o3 G$ u& o7 ]8 [+ B$ U7 v
  73. 4 ~, ]( ^6 c. m3 [
  74. GAMEPAD_MERGE_FLAG = $04
    9 s9 A5 B8 p4 |9 Y, p. u3 ]( _

  75. - `6 s* T8 M$ ?
  76. Gamepad_Keep            =       FC_Data_Buf + 1
      ]9 c2 h" ^3 S' }2 ^0 P6 i% T; G
  77. Gamepad_Once            =       Gamepad_Keep + 2$ f' ?" p7 y' T) ~- X2 p  e
  78. Gamepad_Temp            =       Gamepad_Once + 2, x% j# q& V7 G$ i5 L
  79.                                 ) B  j& b8 O0 b6 `% p, g+ a
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    , z. i9 C. T$ F5 l7 F5 \7 P# I6 m
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    $ n* O) l" U1 s) ]5 F8 }
  82. Gamepad_0_Value         =       Gamepad_1_State + 1) J  j  M2 ]+ D
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    & W! u# I6 U: J9 j5 {
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1( X9 _/ y+ y9 O' p$ x0 D+ x
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    2 P/ _' G8 A: z5 ^! ~: \
  86. 4 r8 Y( R1 ?2 s  n8 E/ ~
  87. ;==================================================' l& U( _$ \/ ]; b, V: U# `
  88. IRQ_Index               =       Gamepad_Merge + $01
      b, o& R" ?: g2 w
  89. ;==================================================
    3 M: N0 `! [7 o. a6 C* }4 i2 E

  90. * y& S7 _0 z3 Y4 N
  91. ;CHR图形数据# I3 O1 D) x' h/ l! h& R' \+ T
  92. ;==================================================: p* _% w' c9 U
  93. .BANK CHR_DATA_BANK* Z9 l( S6 K& f- t- W7 F! |
  94. .INCBIN "chr_bank/chr_data.chr"  {8 ^, g! _" U( B% C5 j, b
  95. . ~# K. M& ^& C
  96. .BANK RESET_BANK & BANK_DATA_MASK
    9 R/ |" L3 {; o
  97. .ORG RESET_ADDR# a) z: Y7 S+ j' y' l2 C! }7 _, z
  98. : Y. o4 ?; c4 B8 ?1 C# d, |
  99. ;--------------------------------------------------
    $ z* |( t& A% C# T1 i) T2 a5 X
  100. Attributes_Data
    ( K7 ^" s8 d8 B" N0 P' D
  101. ;命名表属性
    ; n" B, @7 s+ @9 |: w  F6 j
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      L: Q: s# H! b8 S6 z0 l1 B9 m
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    % t% G) m6 S% i" D) w; f9 y
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA& \# I: ?' `; o2 T* _. x  @
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    3 @# n% v. s2 g' ?1 A' p
  106. ;--------------------------------------------------
    8 a& Q/ ^# [: q5 Y; x
  107. ;调色板数据/ {% `0 R7 f( l  @
  108. Palette_Data9 Y8 |0 w# q8 L
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    ' [0 O/ J0 |; s  j- H) s7 J3 W( j
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F, b1 x1 p# o  f; @% }: C) `, n

  111. 2 l" [# P4 W& ?( B6 Q* g
  112. ;==================================================
    ) l; u) R7 p" S9 h+ x  u
  113. ;命名表初始化
    0 h$ m+ Y, ?* z
  114. Init_Name_Table
    ' r, g! K% Y! i7 h" p  T+ J
  115. LDA #$20# x9 z+ Y5 T, l; f3 g( V  r
  116. STA PPU_ADDRESS
    ! Z1 T! t: A4 `& E6 }3 |
  117. LDA #$00
    , h7 t4 M9 S% t2 X, ~2 Z" b( G
  118. STA PPU_ADDRESS3 B9 g% h) w; [, f) ?5 d( W
  119. LDA #$00
    1 I% k+ Q& d8 \5 S! s) T; `
  120. LDY #$00
    0 C3 G! r  h, F1 j& f2 r
  121. LDX #$109 K' G$ |6 Z- R  }( S" o
  122. Init_Name_Table_Write
    2 y$ u" C% `/ k/ e$ [% I; B% c
  123. STA PPU_DATA
    ; h0 J% |- f! x$ n, w6 O3 W
  124. INY
    ' g# i, O- G  A& G7 ^$ a6 i
  125. BNE Init_Name_Table_Write
    3 [# c$ x. X9 X1 h, G4 t1 w0 S
  126. DEX
    7 [1 A0 L: v- |5 [( K  Y+ y
  127. BNE Init_Name_Table_Write( p/ r) n0 T2 Q, w& }+ l; q6 j
  128. RTS
    & q( d* r! n+ A3 Q! q$ C0 J

  129. & B8 H& B+ m7 R6 y4 q; s; q& {
  130. ;==================================================
    - D, l5 R" W3 W! `, ^! E
  131. ;调色板初始化
    , ~0 c& m; w& B" I3 E
  132. Init_Palette
    $ V' h7 u- D# |! K& P( `
  133. BIT PPU_STATUS
    5 S/ G- i6 _$ z# z6 J1 Y
  134. LDA #$3F  X6 i( ?# G  b: x
  135. STA PPU_ADDRESS
    $ l9 Z' x& Z2 O; o' f: i; P- O
  136. LDA #$00& ^+ i4 b. @7 j, |% W3 j6 G+ {
  137. STA PPU_ADDRESS
    + P! @. u' h* l" b& ?
  138. LDX #$00
    + y- r( j' {! a. a9 N$ ]
  139. Init_Palette_Write
    $ `3 b+ l3 R# A
  140. LDA Palette_Data,X! J+ [/ b- m3 ]
  141. STA PPU_DATA- _# |* U! ]! `  K2 @) A& C
  142. INX
      W) Q+ T/ U$ j3 g$ L: k+ O4 G5 [2 z
  143. CPX #$20
    ; o! |5 h1 h  |4 d
  144. BCC Init_Palette_Write# J' Z5 m0 ~2 s
  145. RTS2 F% z' _1 V9 h4 T
  146. & E: z4 x6 p' W4 @
  147. ;==================================================
    # x1 B1 P1 n5 Y( [  Y
  148. ;设置命名表属性
      y; G( f) V* k" R4 F" w
  149. Init_NameTable_Attributes! D3 h, N( L/ d/ \
  150. BIT PPU_STATUS
    ) j1 ]8 y* r; n) l7 O# r; \
  151. LDA #$23
    1 ]8 z" ^4 Z! c. v
  152. STA PPU_ADDRESS  k$ b, d4 R7 v
  153. LDA #$C0$ K# D+ c2 Z' i# x  s  v1 x1 i$ L
  154. STA PPU_ADDRESS
    # a1 C% X5 V2 N1 P: G
  155. LDX #$00
    & w' Q& T0 ^+ M0 U; X" D" H- q3 S
  156. Init_NameTable_Attributes_Write  d$ O# Q0 T5 ~& u1 L( q7 `5 N* g0 r/ c
  157. LDA Attributes_Data,X% M  X3 Y9 @/ G" ^. F3 l+ V& u
  158. STA PPU_DATA
    ; r8 h$ C$ ?/ i2 ]
  159. INX
    4 ]+ v. M, |1 i- D) [- G
  160. CPX #$40: L* [+ u- A7 X% n3 |' Y
  161. BCC Init_NameTable_Attributes_Write( N/ m5 a& T. n7 e
  162. RTS
    , g+ O2 f" [3 Q9 j6 [* E  r

  163. - _% y; j5 Q5 [8 n
  164. ;==================================================! Z# @* _3 s* P, }8 ^
  165. ;初始化命名表文本
    6 u& ?8 b* E$ J+ h6 D1 E  k
  166. Init_Name_Table_Text
    + N: \/ C, ]& z$ Z/ t1 F
  167. BIT PPU_STATUS
    , _5 ?/ e6 J6 G$ \# t; s) a# C
  168. LDA #$20
    4 i5 E( y: m6 d( I8 d. t; b8 m
  169. STA PPU_ADDRESS
    # L/ ?8 x* v" v8 ]9 x! {6 |& j( W( H
  170. LDA #$00
    3 \  X- ^3 e" _. v& J9 l
  171. STA PPU_ADDRESS
    1 p( ^  y: E% b- ]) U2 r7 V; A8 W
  172. LDA #$007 k: ^: {; H2 Q' N% l: t* ^* A; ]
  173. STA FC_Data_Buf5 ?/ U  A* d% A4 U1 u0 Q' |7 ?8 H
  174. LDY #30
    5 ~! S  D. P2 }! z6 y. B) V
  175. Init_Name_Table_Text_Write
    & d% e3 a, G$ p
  176. LDX #32
    / V* e) v( p0 X) y6 N. ]: A2 u+ x
  177. Init_Name_Table_Text_Write_Char
    9 V) y. T9 `0 r3 S5 v4 i$ P- ^: [
  178. LDA #'0'' c* \% i& q- U! R/ [% |# n
  179. CLC
    ' s9 s8 [6 b2 v7 g
  180. ADC FC_Data_Buf
    7 w8 j' ?6 R7 z0 p; R, S+ g6 s+ C; m
  181. STA PPU_DATA2 S5 g9 b: p. U) a! D
  182. DEX
    & e2 s8 L6 h+ p
  183. LDA #$14
    5 ^" f" M$ ?# u& `- z
  184. STA PPU_DATA4 A6 @8 ^# Q5 O  f" L+ _
  185. DEX
    7 V& x9 y2 W7 r/ m
  186. BNE Init_Name_Table_Text_Write_Char
    ( \  |! b( M% z7 V' F
  187. INC FC_Data_Buf8 L; }# t! P8 _: \" Q" o; R
  188. DEY
    - m1 j+ Q, w/ E2 `
  189. BNE Init_Name_Table_Text_Write
    ) N2 |9 j3 {  y% [4 ?4 \
  190. RTS
    6 Q: X& i8 {8 ?4 n4 R5 F- ?

  191. 4 E' j+ E: n2 [  F& v* |
  192. ;==============================1 B  c0 t, M- O6 R+ o3 i
  193. Init_OAM_Ram;初始化精灵内存
    ( @# J* w8 w$ N* \! q
  194. LDX #$00
    ( p6 r/ M. d) R% x2 w% n4 W% f
  195. LDA #$00
    " ~6 H0 ~- r! f& n& J6 X+ X
  196. STA PPU_OAM_ADDR3 {% y6 }' W! C$ q9 X8 m8 u: o
  197. LDA #$F8" n* g  z: ^6 K3 M! M
  198. Init_OAM_Ram_Write
    , `: |7 Z+ b3 ]% A5 q+ F* _1 S* }5 Y
  199. STA PPU_OAM_DATA
    0 `3 g: m6 l4 V+ }
  200. INX
    3 M6 S2 z# b6 b! U
  201. BNE Init_OAM_Ram_Write) X2 _8 [6 r6 k" u  D
  202. RTS
    ' Z) q& Z0 o" z7 G0 D* Y' |/ [8 q

  203. 0 E+ |6 U! T2 x
  204. GamepadProcess;手柄处理
    % t! M) p! B1 }0 i1 Q, g( e" x/ Q
  205. JSR GamepadDatacan. _, g  _1 X% U; @. N; b' `6 _1 @
  206. LDA <Gamepad_0_Value4 o2 ?1 `( {7 P$ s% c
  207. STA <Gamepad_0_State; C2 W8 ]  r0 n+ h
  208. LDA <Gamepad_1_Value3 P3 z" `2 X, J' h9 e5 ], h9 G$ G
  209. STA <Gamepad_1_State
    4 R1 I! p  T# R9 K  W+ U- N& l( n
  210. JSR GamepadDatacan
    - V  x4 j- Y% |1 a
  211. LDX #$01/ E/ \5 `% M" Z6 j, t
  212. GamepadMergeCheck;合并手柄输入检查" |2 ~& z5 d& {" b
  213. LDA <Gamepad_0_Value,X
    ! x% O( j9 J3 `, A8 `* h
  214. CMP <Gamepad_0_State,X
    5 T2 M( f/ v6 u6 m- p; M
  215. BEQ GamepadMergeInput: l* @0 a  j4 b9 [5 z& B
  216. LDA <Gamepad_Temp,X
    ( T3 Y) E( U9 b1 E" N  w
  217. STA <Gamepad_0_Value,X
    ; b& D$ ^) S3 y" g
  218. GamepadMergeInput;合并手柄输入
    " i  l6 C  I; H9 ?: d7 B0 v
  219. DEX
    0 H  v3 t  [( i; B/ X; w! F/ Z
  220. BPL GamepadMergeCheck
    & a& O( V7 n- A, G" A
  221. LDA <Gamepad_Merge
    0 J! |" I# ]! u7 M) M
  222. AND #GAMEPAD_MERGE_FLAG$ @0 _; Q6 F2 r3 b  l, K
  223. BNE GamepadStateProcess" T/ {# g$ S2 E" t
  224. LDA <Gamepad_0_Value
    ) T* B# V# o- v/ @& Q1 v* N
  225. ORA <Gamepad_1_Value
    # `2 x, ~1 f4 _, z/ S9 i
  226. STA <Gamepad_0_Value
    / S2 t. |3 t7 x# G' b
  227. GamepadStateProcess;手柄状态处理, k3 C+ F' F$ U* H2 a
  228. LDX #$01' o3 M8 Z3 k  I" f. z
  229. GamepadStateSave;手柄状态保存
    2 F; H! E. Q2 r7 _) @/ q
  230. LDA <Gamepad_0_Value,X
    ) F. z1 D( d/ O2 E6 ~. G
  231. TAY  Z6 W& v  R4 j
  232. EOR <Gamepad_Temp,X
    ! P; o8 i' j; O8 G, r% @
  233. AND <Gamepad_0_Value,X0 S8 j* r  }+ {+ S( s5 Y
  234. STA <Gamepad_Once,X0 n, r% B! I- [, Z" M
  235. STY <Gamepad_Keep,X
    8 O( n3 T6 ?, Y* F
  236. STY <Gamepad_Temp,X6 z  B0 H9 I$ S4 @# l$ w3 y, e9 U; Y
  237. DEX; d: \9 k/ ]  A1 n: w3 i" H' e* G
  238. BPL GamepadStateSave
    ) [2 S" ~9 K& H" }. B% y
  239. RTS2 r/ r2 _. K6 X7 l# O* E, o9 y5 W

  240. + i% F8 p5 f1 H# R9 Y0 E
  241. GamepadDatacan;手柄数据扫描
    + M, g- J, l; L- T3 G
  242. LDX #$01
    1 K5 k* b+ f: M- E4 G
  243. STX $4016
    % {5 _! `% F# t2 [- Y. a: O9 ~: Z
  244. DEX' @, }- x8 t% @; a% T, S' [
  245. STX $40160 ?6 g, B$ q: Z6 v' g/ M* w; y4 }2 s
  246. LDY #$087 q2 V* b5 L( g: C8 g. `" y, i' N
  247. GamepadPortScan;手柄端口扫描
    5 O! v& z1 @# `
  248. LDA $4016
    6 o" ?, q; {% u: |9 N0 P7 F
  249. STA <Gamepad_Port_Value
    ( r' K- B  o; S% }! t
  250. LSR A
    2 Z5 M& J5 b7 ?& S/ J" Y
  251. ORA <Gamepad_Port_Value
    ; W4 w( J& m. H* |  w7 ]: L# ^
  252. LSR A
    3 t. S" g: b1 `1 ^. s& S0 @7 v
  253. ROL <Gamepad_0_Value9 s7 q. [5 J* I7 [
  254. LDA $4017* b9 ~+ j( A, D9 @9 I7 q' n
  255. STA <Gamepad_Port_Value
    5 l3 ]5 r' R+ X4 h4 _& f
  256. LSR A
    / y8 w$ @0 D7 a+ O, f. \0 \& p' Z, H
  257. ORA <Gamepad_Port_Value
    . O6 Z$ p1 c" g6 |, T8 A
  258. LSR A) L& @3 k- G) W, S  q7 Z1 |6 w
  259. ROL <Gamepad_1_Value
    7 S( P; v& q& z; r
  260. DEY/ I6 T7 ^$ v6 Y' a
  261. BNE GamepadPortScan- \* ]$ t9 g8 y
  262. RTS- j$ B6 s4 ^* r# \1 K
  263. 3 K; @  D9 j0 L2 F: z; t! U% S
  264. ;==================================================# y1 ]8 K2 b/ v# B- V% a
  265. ;PPU处理
    7 d* R: }7 Y9 V& ~8 \
  266. PPU_Process. b- E2 t# a$ F% Z
  267. LDA #$00
    2 p1 J8 R8 C( W6 K0 d7 v" E
  268. STA PPU_MASK
    ! r5 G! l. b/ ?! z# |' j/ r' [
  269. # A' E; r& x/ c/ l" ]0 A" C
  270. BIT PPU_STATUS4 x* C; i/ o5 {# W8 m( u% x
  271. LDA #$20
    9 y& O  s  y: y6 y' F7 c/ v
  272. STA PPU_ADDRESS
    , _" Y: X; W6 H' N1 J! z% ?
  273. LDA #$00: C) i4 W( A- |8 i; r9 V
  274. STA PPU_ADDRESS
    + X+ Z! a1 i9 t4 T

  275. " E1 @' n! `8 ^: E3 _- V5 T+ O- h
  276. STA PPU_SCROLL: ]* g" s$ W/ r7 [/ `' n
  277. STA PPU_SCROLL6 x+ h+ M0 @4 R/ E; G- X

  278. . R# {9 ]& Z( g7 {3 F% [
  279. LDA PPU_Msak_Buf- O1 v9 `, N8 Z0 I  b: {! d
  280. STA PPU_MASK
    ! I  s8 z% y$ _
  281. 1 |: `8 P* H* m; o$ K; R" u
  282. RTS
    1 ^- I6 c6 c/ v
  283. . a1 c. h( H. G2 w
  284. ;==============================% j1 d* e/ M8 M, s
  285. Time_For_Vblank;延时等待
    ) A5 V- k  P( M9 Y% v6 T3 n
  286. LDA PPU_STATUS
    6 p2 m! S) F0 O) j
  287. BPL Time_For_Vblank
    8 P" \7 _: A2 G% {# l; ]+ v% `
  288. RTS
    + s% W& l: o4 F0 u7 N9 ]
  289. 1 M7 d" N3 C7 |- h  @/ O
  290. ;==============================, i) M: w) X9 ^! V! W
  291. ;初始化MAPPER19- R5 _, P) A9 V; S
  292. Init_Mapper19
    " J/ p' u1 I: F; c5 F0 w7 ]
  293. LDA #$00
    7 {8 }! T1 {5 d. I: v0 e& O7 n
  294. STA M19_CHR_0000$ M- e. \0 X% ]) H
  295. LDA #$01: J  A/ Y, \* }" q
  296. STA M19_CHR_0400
    4 _' Q$ h1 l* j
  297. LDA #$02  _4 z- I! ~# u' f$ \
  298. STA M19_CHR_0800( |3 @/ G1 j+ c) r" m; ]
  299. LDA #$03
    ) b9 U# h2 }$ g. d) v: B' o
  300. STA M19_CHR_0C008 w0 N" A1 q% E! L
  301. LDA #$04
    4 l: B6 F0 l8 T9 v; `
  302. STA M19_CHR_1000
    . j% V! d# x& W. G! \! s
  303. LDA #$05
    5 h( T* A0 l+ _- W/ K
  304. STA M19_CHR_1400
    * g7 \) s/ {9 _" v
  305. LDA #$06/ b, G0 Q$ e/ `8 o! g; `
  306. STA M19_CHR_18004 `% s9 _8 B+ J) I8 Q
  307. LDA #$07" |9 S/ L. L- u& ^% Z3 _: d
  308. STA M19_CHR_1C00' h, r3 W; g& x! w: g" n" p/ I. N
  309. ! G* k$ M/ B; u  F6 y
  310. ;禁用IRQ2 m, O5 B3 j0 x3 c2 q
  311. LDA M19_IRQ_COUNT_H
    & g& J- H1 z2 P6 J
  312. AND #$7F
    # y5 t6 q7 e) c
  313. STA M19_IRQ_COUNT_H. ]# k# c, w$ G: ^& v
  314. 4 R, w+ T6 r& K  }& q- p% w; E
  315. ;命名表+ }2 O0 x: d! }9 F$ s0 S
  316. LDA #$E0
    6 x+ G2 R! U. I& [( E- M" L
  317. STA M19_NT_2000
    6 V2 ^2 z- i% ]3 W+ P" Q5 r. G
  318. STA M19_NT_2400
    # f- f! f" F3 x# k8 }* N
  319. " @) v% y; `# @0 O" u
  320. ;命名表
    - t, ^% Y; N( m9 Z2 e1 P
  321. LDA #$E1. f4 R4 r, Y- W9 r; ^1 {; ]
  322. STA M19_NT_2800
    6 f: B: c$ L' \
  323. STA M19_NT_2C000 u6 \$ U! ~' j( V! f9 P  p
  324. 1 n% R0 I) q0 T4 [. t5 q5 |
  325. RTS
    ; y, [& `, E9 b& o0 Y' T

  326. + K0 p. [% \+ x6 _) S0 ^
  327. ;==================================================
    ( X( b% O7 H! t; p4 E0 y
  328. ;重置中断处理
    % g. R8 I2 D7 T  s! i3 W1 C
  329. ResetProgram  |- C6 P7 ]2 B; q7 f6 y- T& K
  330. SEI
    0 J) a( F) j# J5 L; v
  331. CLD
    0 `6 L5 a2 _. s0 E7 q
  332. LDA #$00$ C8 Y* C% A, @3 @0 F) g
  333. STA PPU_CTRL
    " ^# Z  u+ V, z# R: [- R$ P( S
  334. STA PPU_MASK- O# h# g3 Z/ E: w; V7 Q
  335. STA PPU_STATUS
    + ]0 e7 v) d8 T! w/ ~
  336. STA JOY2_FRAME
    8 `) Q. h' o) U, C" l
  337. STA APU_STATUS
    * l; ]# i6 N/ V1 c1 q

  338. 4 [2 R! H  T: m
  339. LDA #$C04 q/ m4 @; o; ]1 R7 `
  340. STA JOY2_FRAME
    0 V0 E% [9 d/ p" T! u8 T

  341. 4 K! ?6 d* C8 n' k
  342. ;等待vblank, [$ }  i; _1 Q; t  ]2 A& K
  343. LDX #$024 k# g& V* V5 X/ p) y+ C! p
  344. Vblank_Wait_1( y0 P" h" c$ h& y- F0 I
  345. BIT PPU_STATUS6 \" G& q9 e- r2 r
  346. BPL Vblank_Wait_1$ V( D& D& Y# ~4 Y  d
  347. Vblank_Wait_2/ j( F; _7 D) z' f8 ^2 K
  348. BIT PPU_STATUS
    4 j8 D+ g. {/ S% C
  349. BMI Vblank_Wait_2
    2 E- n8 [) X4 B
  350. DEX. f4 q* ^% q5 j
  351. BNE Vblank_Wait_1
    : q/ R$ K0 e' A4 A( _7 s9 T
  352. / j8 w7 i" p3 K0 A
  353. LDX #$FF2 \  D! W: N- O/ U
  354. TXS
    5 n3 g8 k# W2 f& Q1 Z
  355.   h, G% e3 v1 v6 B7 K4 V. `
  356. ;初始化MAPPER19
    # ]2 I0 Z2 @' b/ c) @4 q
  357. JSR Init_Mapper19
    6 l6 ]# s  _7 ~* h

  358. + ^( U5 D) E( b8 x5 [8 @$ o0 m' r
  359. ;==============================! s) c2 D* y8 z5 h  ~' v
  360. ;RAM初始化' |; n1 h0 N4 o3 m' V1 Z6 _
  361. Nes_Ram_Init% M0 H% [; ?6 p' W! K
  362. LDY #$00, h6 X, |8 I+ w) V: z; K  W
  363. LDX #$08
    " B. u  e' q& I3 g' ^, z( Y
  364. LDA #$004 W, ^6 L# r7 \+ V
  365. STA <$00! A. B8 J; y2 V4 `+ c
  366. STA <$01
    " a5 Z% d% a0 |' d7 g* F" [
  367. Nes_Ram_Init_Write# V) I% V: @; O" p
  368. STA [$00],Y
    " I. {3 F" [9 R$ B" T
  369. INY( \: C$ p' v) L) Y' A- Q
  370. BNE Nes_Ram_Init_Write2 U% B% h" G) _* S
  371. INC <$01' d4 W! y+ _; Q5 _
  372. DEX& h+ `6 M4 J5 ^, d7 S& B
  373. BNE Nes_Ram_Init_Write. i4 x0 `6 F+ I% k$ [# w, Y; O. U

  374. - h$ \2 v7 u8 K* Q, \$ r% z8 M+ y# t
  375. ;初始化命名表
    % h3 f- U# Z: p9 q* G/ E/ _
  376. JSR Init_Name_Table# M7 s7 F8 u0 q, F) \& _( o

  377. 4 v7 T5 M/ A- A% a' e& ^  {
  378. ;初始化调色板2 D) l& H& A1 w! }
  379. JSR Init_Palette  e3 s7 x% K( J4 {. ?
  380. 4 W3 O* z6 v+ X6 B+ ]( y
  381. ;初始化命名表属性
    + V: s( l0 \; J1 H
  382. JSR Init_NameTable_Attributes/ c: _& E3 l" @* b3 c

  383. 9 @0 |, F3 ?' `3 Y. u$ o0 ?
  384. ;初始化精灵内存5 ^+ I% ^, u, j2 \/ ?
  385. JSR Init_OAM_Ram5 M% L  s& \" c# _1 ^4 l

  386. 0 i. S0 b. l5 A# `+ {) I
  387. ;在屏幕上写点东西
    5 }/ @! {5 X. m7 I* v  \/ p. |
  388. JSR Init_Name_Table_Text! \, X, T2 Y" I" d9 c

  389. 2 J2 a3 c. X# |4 |9 ?
  390. JSR Time_For_Vblank
    % A7 F9 H( o& z
  391. ;开启PPU控制2 G# \; p; F4 E- C; e
  392. LDA #$A8
      {- ?: U0 I9 ~# l2 l
  393. STA PPU_Ctrl_Buf
    0 Q6 ^+ G0 ?, j) N7 X$ l" L
  394. STA PPU_CTRL
    + M- M4 P+ c2 N1 w8 f) }8 }- R
  395. + K  j* U7 G: Q2 \- f( h
  396. ;开启PPU显示
    , ~: g$ \) Y1 I2 q0 O( z
  397. LDA #$1E
    7 o; Z& }! {% C6 _
  398. STA PPU_Msak_Buf
    : q8 S% Z% Y7 ~* Q' d* L' R- F0 n

  399. , W6 ^5 e! y, r) B7 }* P( o
  400. CLI0 }; x+ t0 I8 w+ ^! `4 d* W
  401. JMP Loop
    2 {, r: `2 n- x7 q4 f( l2 {
  402. 6 O# [2 ]9 O/ T/ t8 a/ ^
  403. ;==============================
    4 p! s$ m2 r# c. y8 O( ^& p$ b
  404. ;死循环, 等待NMI中断
    ( L& M/ y+ R( O8 k0 U. c
  405. Loop5 V/ j8 }) v& _+ l# T" S$ C3 B
  406. JMP Loop! P/ F4 D# h  [, _4 p1 o1 J
  407. ' p) n; A: |% ~, g
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967( k! w5 B' z2 m7 R7 [. v
  409. - a4 K& l+ U1 X/ D/ M2 K; B0 x6 s
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)4 |. Y0 |: O: l  n2 V
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
      u/ B5 ^2 F9 \8 M9 Z$ B9 g5 g3 ^; |5 ^
  412. ;==================================================/ d1 b9 u, x4 \1 d
  413. ;NMI中断处理3 R* \; ^3 O* d& S
  414. NmiProgram
    $ w, K5 k$ J) x  ]$ r0 E" M! Z
  415. PHA6 ]" i8 I# z' D$ Y2 E" ]
  416. TXA" b. L! [3 U* _& q  K
  417. PHA% o/ B! i# _! C9 |
  418. TYA$ {9 O# U7 Q9 L# V. _
  419. PHA
    / }& ~1 u5 ?7 D/ S1 H
  420. " I" l9 J, ^3 F' w) V) n
  421. BIT PPU_STATUS
    . v  {6 y& U7 o  q+ m1 L5 g
  422. " w4 w8 G; I7 O# b5 }. Y! `' h! t
  423. LDA #$00
    * e5 \# L3 c& B2 k* j
  424. STA IRQ_Index8 ?5 H3 l3 H" N- {% a, V% j
  425. ; q" B: O% d% G( x7 Z2 i  M
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动3 I5 D$ U6 v' b1 c
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)4 @2 n0 i* M1 `2 q' @5 j
  428. STA M19_IRQ_COUNT_L
    + T( E1 P4 B, ^' N" ]
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)3 U9 ^7 y' |3 t! Y* _/ \+ y
  430. ORA #$80
    % k. L8 w3 \6 g) @, q3 A6 z/ }) K
  431. STA M19_IRQ_COUNT_H
    6 ^" B+ W/ ?5 ^2 f- i
  432. CLI
    * J2 d' R8 _1 B  r, U
  433.   G6 N, ]! a* K0 v' n
  434. ;关闭PPU控制
    2 {4 X" T7 L/ g3 u
  435. LDA #$00+ h" I, g, c- Z
  436. STA PPU_CTRL$ J" O0 Y# F, T* e5 C$ k
  437. % W3 b$ }8 o4 v
  438. ;处理PPU  c; ^% r+ ~: X5 J. q) U- n$ A1 j
  439. JSR PPU_Process
    ; ~  w! B1 e' r+ n
  440. / o3 H* V# T: Q( E
  441. ;开启PPU控制0 @7 g; U: H( l) ~
  442. LDA PPU_Ctrl_Buf9 a1 j9 c, K8 V: p% ?* K$ e
  443. STA PPU_CTRL
    0 G" {4 {$ p$ m2 P+ L* a
  444. $ j  c( s$ F8 g6 n7 a; m- r
  445. ;手柄处理
    $ N+ a/ v+ ^+ p; s
  446. JSR GamepadProcess% i( h4 n3 i0 L4 K3 I2 J7 E
  447. 0 n! |4 b- F1 ]
  448. LDA #$00
    4 q2 Z0 o0 F6 T* z( d
  449. STA IRQ_Index
    : @; w# c# O; G+ S8 E+ F
  450. % F! g2 |/ @& J: C2 g
  451. PLA& |8 O0 m! B. x0 j7 k
  452. TAY
    2 v) A+ |/ d- @; n( M- y( L
  453. PLA
    " n" m; Y" g9 W/ W
  454. TAX
    / V! ^( i4 b) P' n
  455. PLA
    : v0 g0 A) ?) A5 x
  456. RTI! k( e* I. p3 S
  457. / h; ]7 I6 d* @7 P' h# F" J
  458. ;每行扫描线113.678 b+ `2 v% R: E$ T' T
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    * `$ w! v  q- _- t; W' s& O
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 71 D! W) e( ?7 K
  461. ;==================================================% ~% ?7 Z$ }1 C* X% J: \; m# c& Z
  462. ;IRQ中断处理
    & E& R1 @1 d6 |; j' B( H' ~
  463. IrqProgram
    ' J3 }4 m6 X9 L, v* N5 q
  464. PHA
    + S. R1 E4 `! s2 D5 `9 {1 q# m5 u
  465. TXA
      z. H6 E& J4 o/ [7 f$ S9 B& g3 |
  466. PHA
    . A* l0 X6 J* U: ]) M2 _, ^% B! V. n
  467. TYA. \% m5 G0 e: D. ^. K8 w
  468. PHA+ g% d9 M2 r1 @. g

  469. * _9 X, f! X/ e: S
  470. ;16条扫描线后触发IRQ
    5 Y4 S. n+ Z9 J% ~( k6 D; I
  471. LDA #LOW(BEGIN_LINE_CYCLES)8 u- y* g! p! m9 O# l6 ~% Q
  472. STA M19_IRQ_COUNT_L7 T# d/ ?2 l: N+ y- R" r4 B
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    " A1 a! v' |: w9 K
  474. ORA #$80
    " L4 {( P  H8 N$ O; V1 p# ]
  475. STA M19_IRQ_COUNT_H7 G* y( l" I: p* I6 m6 p
  476. 1 E4 U) v  F0 e& u" g7 ?; V  T
  477. LDA <IRQ_Index
    - J# T1 H+ u# W* k9 ^
  478. BNE * + 4
    8 ~! f& x, e5 G* {6 M* s* N
  479. INC <PPU_Scroll_H& e: p  D1 ]: k2 t$ h6 z+ ^$ x
  480. 4 }; {3 ?4 f7 N, y5 _$ z
  481. ;设置屏幕滚动% y) C! j5 x& H
  482. LDA <IRQ_Index
    0 H, p3 M0 ^9 d1 Z, U
  483. AND #$01& H8 H5 O9 g. F) l& E# @: P
  484. BEQ Irq_Scroll_Right
    " H" l& s6 c& v+ x$ o/ [) i
  485. 3 m2 J1 J& C/ o) T1 j& A! u
  486. Irq_Scroll_Left# v$ R& s& Z6 I
  487. BIT PPU_STATUS+ v* [) w) {1 i, l* ]
  488. LDA <PPU_Scroll_H0 {+ |: H- r% z, }
  489. STA PPU_SCROLL9 F; ^6 O6 O! ^+ W7 g+ v3 w, e5 M
  490. STA PPU_SCROLL
    ' X# w/ M; {6 Y3 S# C0 \3 \
  491. JMP Irq_Scroll_Over, C' b2 j) J; _9 l
  492. 1 Q4 {" b* u0 Q' y& a: P% b
  493. Irq_Scroll_Right% a, w! i9 u4 C- N
  494. SEC
    3 y' P' Z. ~1 x/ O2 l, g* E: u
  495. SBC <PPU_Scroll_H; g. [. O5 a2 n* J) |. m( c
  496. STA PPU_SCROLL4 W% p" x1 s) X, z, b8 _: s/ U0 e, C4 e
  497. STA PPU_SCROLL6 a: c- m  O9 E3 P8 f
  498. Irq_Scroll_Over
    + ^' u- s+ \+ k" B2 ~# Q7 C

  499. 6 o/ }# `! W. a, W8 K' G
  500. INC <IRQ_Index
    ' ~0 C0 B- m' I8 G
  501. $ d  O; u( ]; W& U' u
  502. LDA <IRQ_Index
    . V9 ~! L( u# z9 C& ^4 X+ j" C( d
  503. CMP #14
    " t% {/ U0 w4 `6 f; M% b$ T* c
  504. BCC * + 10- L6 H* s$ ?/ X# j- `5 c" i9 ~: q, c
  505. LDA #$000 j# F5 g& _. k- d' r
  506. STA M19_IRQ_COUNT_L" _# w  W. s- d) s2 E+ ~* N# _: j9 ^
  507. STA M19_IRQ_COUNT_H
    " d. M. v0 Z( L) C

  508. % ~# L/ r6 H. J4 K! V/ `# M
  509. IrqProgramEnd+ q: w  A" t& C5 o2 t6 ^
  510. PLA
    6 T8 d) v) v/ Z: u* Y7 U7 a
  511. TAY
    - A2 n8 e1 ?1 i4 s; H' e
  512. PLA9 i: Y) ~4 v. N& J8 o9 v' Z' Z
  513. TAX9 m2 x9 F' N  b5 J
  514. PLA
      j- s6 o) T! r" F0 ]
  515. RTI5 S  V6 p( \* m' x

  516. ) _: Q5 |7 H* m% r3 D& }) w
  517. ;==================================================
    $ {; [1 p+ m" S  y2 u9 |" {$ m' W) d
  518. ;中断表
    6 N% `2 N; A  G* ~
  519. .ORG $FFFA
    ' _2 q3 o! ~2 T6 R$ |: n( @" ~$ _
  520. .WORD NmiProgram
    + d8 I* `  G# V" I% U/ }0 e$ K
  521. .WORD ResetProgram* J. i0 }, c0 }# t3 x8 M" ]6 i9 Y
  522. .WORD IrqProgram
复制代码

1 H5 w. k. C! t* q4 {# a

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-7-25 15:30 , Processed in 1.077149 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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