设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    ' O3 C% r6 |: T! W( g7 Q
  2. ;FlameCyclone 20230710' q# E4 w0 K. h% o+ {

  3. ! x- f  ]7 p: i! X! A( z
  4. ;文件头
    8 O0 \5 o5 D1 h$ v
  5. ;======================================================================
    6 [1 g! k- p  ^
  6. .INESPRG 4                                              ;16KB PRG 数量5 d  x7 W2 w/ K" E% J) {7 O
  7. .INESCHR 1                                               ;8KB CHR 数量
    ; a/ J. M: Q! T1 K7 D0 g
  8. .INESMAP 19                                                 ;mapper 19; o( N( X: }7 v0 Z' t$ y
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    - s+ X9 X( x, s) X7 {
  10. ! G' A1 w. m3 k4 n1 j8 i, @+ k
  11. ;必要条件
    + K% Q5 @* X# D; V& z( [' k# Y
  12. ;1.持有CHR ROM0 i7 r! }- W9 c' Q( T/ X2 Q$ X
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000% ]) u) G, f! E# z( A% V
  14. ;3.精灵内存(OAM)不为空
    9 u) ]3 i4 {) G# [4 _1 J7 J1 N
  15. 6 @7 U! `1 Q, X) c$ m* U7 ~
  16. ;==================================================
      a0 J5 _( w' z
  17. ;NES端口常量
    9 p. @$ J+ n3 y0 s* B5 C. a
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器, T. {9 G2 Y  g9 y! [5 ^; X
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    , O: M! V5 W+ B1 U* L  }7 m. ]
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    0 i; e) O: Z0 ^8 M; A
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1; U. e, [+ v7 o
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    . ^- }9 Z- u' q, q1 G" s# W
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    2 v# z$ j* o9 r: ]4 d
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加* ~3 S/ x6 {. z9 T. u6 S$ O
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    . D& h, b+ M. ?
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    - x, w! i  }  O7 M- q: t
  27. APU_STATUS              =   $4015   ;声音通道切换
    . `: ?& t: f. Z; _8 v
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通8 l1 V3 u0 H5 H# k0 T* h" e% `
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通* x+ R8 R0 N6 V! [% U9 _; j
  30. ) U- ^* F: t* Y8 H/ d/ ^( J% Y2 X- q
  31. ;==================================================$ K- Q% P  q2 h( Z# r
  32. ;MAPPER 19端口常量
    ; e; r2 a- Z" n  S' {
  33. M19_CHR_0000    =   $8000
    2 r, O. t9 Y; k- Y. Y
  34. M19_CHR_0400    =   $8800% ?1 b4 y- s* r6 K3 x& S" I" i7 u
  35. M19_CHR_0800    =   $9000) E/ {- O8 b% z0 @' m! I
  36. M19_CHR_0C00    =   $9800  l8 Q7 `6 ]/ W1 w' w' ~+ `; c
  37. M19_CHR_1000    =   $A000$ L/ Z' m4 ?9 z1 M8 n
  38. M19_CHR_1400    =   $A800$ {2 G. q- L4 [& x
  39. M19_CHR_1800    =   $B0009 o$ A, K- `3 E" o: Y" y7 ^$ K% h% d# L
  40. M19_CHR_1C00    =   $B800
    . X6 I# K7 p& |: t% Y& c
  41. M19_NT_2000     =   $C0003 v7 P" M' x" C8 R. s3 k
  42. M19_NT_2400     =   $C800  S3 o8 G* @8 @0 g" [6 A6 ]
  43. M19_NT_2800     =   $D000
    5 v) R& ^) C, }1 H
  44. M19_NT_2C00     =   $D800
    8 b8 b! ^. M: D& x2 f
  45. M19_PRG_8000    =   $E000. q6 m, F. M2 ?' s. I
  46. M19_PRG_A000    =   $E800  i! v' _( z8 n. i& i1 v5 V
  47. M19_PRG_C000    =   $F000% c8 ?: f7 x+ P, {
  48. M19_IRQ_COUNT_L =   $5000
    % Q2 M( ]+ q3 O: w  g$ J! w
  49. M19_IRQ_COUNT_H =   $5800
    & F4 R/ l0 o" u2 ?" q

  50. / R2 M- q! u( ~& w$ p$ l5 w# n
  51. ;==================================================
    6 w# ^% [/ d$ ~
  52. ;程序块配置
    - s  `4 R2 Q2 p' }
  53. BANK_DATA_MASK          = $07
    + A2 C; y' B: b0 o
  54. ;--------------------------------------------------
    + o/ [. v& |6 ~
  55. RESET_BANK              = $078 I& W9 w5 ~+ \! D8 Y; L8 v
  56. RESET_ADDR              = $FC00% O1 |& g/ W; W: t/ ^3 P
  57. ( i& `4 ]- [4 H, h# u+ k
  58. ;==================================================
    5 g' ]% w" d% h* l. Z4 `# e
  59. ;图像块配置
    2 T$ d1 P$ U9 _; l, U( d
  60. CHR_DATA_BANK           = $08
    5 F, t5 n# E2 K4 J# n$ h* @

  61. 6 d# }% a& a5 y  [  w- L, w" ?+ D
  62. ;==================================================
    5 `, e: x) F  j$ D( h
  63. ;零页内存地址配置% l$ z: Y$ w. X- P
  64. Use_Ram_Addr            = $80
    7 G8 l( l1 u* ^! B7 `4 w; p/ o
  65. PPU_Ctrl_Buf            = Use_Ram_Addr+ N* K/ H7 Y+ T+ M7 z$ H
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    5 V% A$ P( A$ z) c" f
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01/ q* T8 g  O$ s* W: R. L
  68. PPU_Scroll_V            = PPU_Scroll_H + $018 l1 y) V0 c4 G1 }9 `3 l% y
  69. FC_Data_L               = PPU_Scroll_V + $01
    5 H7 ~( F- F, Y" b% ^! a
  70. FC_Data_H               = FC_Data_L + $01$ f  l% Z" }& W0 J
  71. FC_Data_Buf             = FC_Data_H + $01; k2 z. `9 o, L9 M, L3 x4 j1 M
  72. ;==================================================+ k, i! Y5 k4 P+ D/ q$ A
  73. 8 o/ q5 e8 s+ m) L; V* Q+ e
  74. GAMEPAD_MERGE_FLAG = $04
    8 _" U7 R& m8 ]+ f! N, ]3 P% l
  75.   m4 Z1 w4 n: X3 C6 T& W4 P9 G
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    : V6 T+ w" h' X. S5 \3 W
  77. Gamepad_Once            =       Gamepad_Keep + 20 e" _1 w3 y! g( |! F
  78. Gamepad_Temp            =       Gamepad_Once + 27 |' L9 U7 J% j/ K
  79.                                 7 d2 o, p6 x1 e
  80. Gamepad_0_State         =       Gamepad_Temp + 2% C$ v8 C* {( z
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    1 a( c: X! l+ G; P7 N$ L
  82. Gamepad_0_Value         =       Gamepad_1_State + 1/ @5 \2 [% I6 p8 }0 o7 F! k
  83. Gamepad_1_Value         =       Gamepad_0_Value + 10 l; y8 n6 l! ~- A1 s4 i* p
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    7 @8 H' i4 }% h7 O$ P$ e
  85. Gamepad_Merge           =       Gamepad_Port_Value + 16 Q! l; n8 A  _' u

  86. 6 T, s- n' N& P% g; U3 S
  87. ;==================================================
    & H! K( P, _  U3 l
  88. IRQ_Index               =       Gamepad_Merge + $01
    1 v2 b6 `+ G% a! y& N3 _  _
  89. ;==================================================
    0 H$ t1 W6 @: T& j6 @0 ~: A
  90. 1 J) ?9 x4 ~0 n: H, ^# X! o" L4 P
  91. ;CHR图形数据; @1 l$ j& W  K# I" ?
  92. ;==================================================
    0 O- ^5 O# X: Z0 o% h
  93. .BANK CHR_DATA_BANK0 H! U7 ]4 {. ^: a4 d
  94. .INCBIN "chr_bank/chr_data.chr"
    0 O) x. [$ M6 X3 \* H/ J
  95. 8 {7 {' f# e0 H
  96. .BANK RESET_BANK & BANK_DATA_MASK
    * P' N- A! a# Y' z
  97. .ORG RESET_ADDR
    " Y9 z3 e# w  q4 T

  98. " r. H, Z+ b3 x/ X/ L+ g
  99. ;--------------------------------------------------
    * p( w, ^6 H: f! G% c
  100. Attributes_Data/ i8 r" G0 V' K1 {% y: y( a! B
  101. ;命名表属性+ P/ m8 p- t) q( x  i; h
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00. W$ |) P3 Z, A9 W+ A
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    2 M5 j" t5 [5 O- T( y# N
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    ( G3 B8 P( i9 l$ F2 r+ J: t
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55  v0 ]! A8 X- {: d8 o
  106. ;--------------------------------------------------
    / s  B$ r) }$ U/ y; W  G8 _% R* _
  107. ;调色板数据
    , q6 m: r" U+ x' ?* _& a8 q
  108. Palette_Data( M/ z- N4 m( ~0 V' K
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F4 x2 s2 b0 ?* ^- _6 R9 ]
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    8 {5 y7 ~! J7 o3 u7 Y+ \9 |
  111. 2 W: K4 h6 _; j4 c9 m' y7 N
  112. ;==================================================
    ( M- q; `3 J' v% J' {# {* |; O/ {3 s
  113. ;命名表初始化7 d& m2 F& ]2 D$ A1 M# Z- y
  114. Init_Name_Table
    $ ^5 P( E2 w" ~) P' N
  115. LDA #$20" A; X) ?9 K; T
  116. STA PPU_ADDRESS
    0 t8 _- L: R) \6 }
  117. LDA #$00- V% f7 y6 o1 e% z& z1 @: t! r
  118. STA PPU_ADDRESS- _4 K7 C2 g8 C
  119. LDA #$00
    & e2 {0 q% e) K8 W
  120. LDY #$00! g# ~  H+ g" J* x9 v
  121. LDX #$106 d5 d4 @' T& p- Y# h# P; W3 |& g' N
  122. Init_Name_Table_Write: K* p6 T( E' x2 K
  123. STA PPU_DATA
    ; y6 A7 q% a2 r9 e
  124. INY
    4 S% K/ h, H: v& o3 T1 l
  125. BNE Init_Name_Table_Write+ u! g" o9 B& h3 s6 X2 |5 D4 `
  126. DEX2 ?: u% ?) Y9 ^1 k
  127. BNE Init_Name_Table_Write
    2 |8 c( U; `/ g- \; g
  128. RTS
    0 y0 G1 H9 F0 n8 z- {

  129. 1 [. L, X" |% m, X( `
  130. ;==================================================
    ) K# a: E' R; [
  131. ;调色板初始化
    / Y, b+ h2 E4 g& r  X4 l' T
  132. Init_Palette) }" T+ |4 b/ C* T# t
  133. BIT PPU_STATUS+ Y8 X, t& G; T) n4 X1 R' Y
  134. LDA #$3F
    - D# {# k6 [' T2 G6 o  k
  135. STA PPU_ADDRESS
    7 K" F& g# F4 k# `
  136. LDA #$00  S7 V3 B- P8 u  ]) \6 b3 V8 m0 o
  137. STA PPU_ADDRESS0 ~( k4 p4 A3 @. D) b8 w
  138. LDX #$00
    / h# R) P. y* i
  139. Init_Palette_Write) a9 U9 x" W& t# V& j5 i
  140. LDA Palette_Data,X
    * J' N3 W: J0 o+ O( L6 k) T% A
  141. STA PPU_DATA* l( p$ ~3 U1 y# x2 w3 Q% u4 o) ?
  142. INX$ z: O0 q. T9 Q! n; r1 ?
  143. CPX #$20
    ; E6 x" X0 O0 W6 O+ e
  144. BCC Init_Palette_Write" A; s, u: D% M. {! ^
  145. RTS
    ' e# P6 e' b+ t* N. |* u5 ?

  146. 0 q$ ]# K* z$ }' U
  147. ;==================================================
    5 D7 {7 K+ ?, i& ]' n; i- B* j* P
  148. ;设置命名表属性
    / ]: F7 p0 a, ~* W& n; ^
  149. Init_NameTable_Attributes' O' N/ p$ l% x) o# t7 e3 l
  150. BIT PPU_STATUS
    3 \. E" n+ e: o# b! Y
  151. LDA #$23
    : _4 K1 E. [% g% k( M- q3 y
  152. STA PPU_ADDRESS
    * W* Q+ ^4 g' E, `
  153. LDA #$C01 w& M  x# }' u9 n. ^' }
  154. STA PPU_ADDRESS
    6 K1 x3 T! d) A
  155. LDX #$00/ T2 \1 h" \( g9 K4 Y5 L
  156. Init_NameTable_Attributes_Write9 h6 \: q! e* G; @- ~
  157. LDA Attributes_Data,X0 i+ E/ l5 f/ S0 C. m3 {. g8 i
  158. STA PPU_DATA: h) N5 w$ y" F- o
  159. INX5 v) o  g- b1 ~. E# c8 w
  160. CPX #$40
    ( B1 M( V1 f6 P8 Z5 N- N- M
  161. BCC Init_NameTable_Attributes_Write& M" w# l: n/ n
  162. RTS
    , Y& U4 }0 s% S! K' X/ q2 u

  163. 0 Z+ W- U+ V* R
  164. ;==================================================2 m7 H- [; m8 ?* m; k+ Y
  165. ;初始化命名表文本
    , y3 H: K9 P7 r
  166. Init_Name_Table_Text( t% Q3 \: w9 T+ F7 {
  167. BIT PPU_STATUS7 [" y: i% M' L) K
  168. LDA #$20
      X1 O( L" U" A( [  t
  169. STA PPU_ADDRESS
    6 N/ P+ X; e, _5 R- s
  170. LDA #$00+ Y3 ?* }- ]$ d; Z
  171. STA PPU_ADDRESS
    5 B, w$ n6 q. G; e
  172. LDA #$00
    ) L  R; {, _/ v
  173. STA FC_Data_Buf( g  b- d$ ~* G& ^
  174. LDY #30! R/ l" @1 v) f, i7 N; N9 G
  175. Init_Name_Table_Text_Write
    / V2 c  }: K! }8 L
  176. LDX #32
    ! w( ~  R1 j8 X2 M# t2 {; p2 [
  177. Init_Name_Table_Text_Write_Char* }: E* q* B7 u5 v/ e- f
  178. LDA #'0'2 {' j8 t4 k; A1 Q( {8 U8 E: g
  179. CLC. Z% A3 K- j; Z* V" F' v
  180. ADC FC_Data_Buf% d7 f# F: }6 T. O* g* |( q
  181. STA PPU_DATA
    ) W) \  L+ ^3 R: b
  182. DEX3 \5 [) A4 H" z7 f, J1 p' `
  183. LDA #$14
    0 n* `; Y7 |5 v0 {2 v& v
  184. STA PPU_DATA
    : e4 Z- S6 h. V6 j$ B, h
  185. DEX" N( Y$ s% I9 I5 o  H; G+ s
  186. BNE Init_Name_Table_Text_Write_Char
    * P! T, s: ]% b) i
  187. INC FC_Data_Buf( S( h$ |7 r, C! E5 h' P
  188. DEY
    $ B* a3 o, ]! T% M7 n- n; J" }
  189. BNE Init_Name_Table_Text_Write  T5 w  F5 |& ?0 M9 F1 G
  190. RTS/ L8 U, C" ]. Y' ^. H! a/ K

  191. 9 V  F# z+ \2 C6 {  r$ X% {& A/ r
  192. ;==============================
    + U0 E" T! {' v% @& I6 @
  193. Init_OAM_Ram;初始化精灵内存
    3 ~. k0 P% f: h, Z) ~  O
  194. LDX #$00) Z6 x& o# I  O0 ^( s' b
  195. LDA #$00
    ' H, x1 c% n4 g1 E
  196. STA PPU_OAM_ADDR, Q9 C% A+ e" k* m
  197. LDA #$F8" `) m* D0 v7 U0 ~) h0 H
  198. Init_OAM_Ram_Write+ N) ~6 T5 l' ]" {
  199. STA PPU_OAM_DATA: e- u4 n3 T! Z' |% H# R; y. ?
  200. INX
    ! m7 ~# u: N( Q  ?
  201. BNE Init_OAM_Ram_Write: b8 Z0 a) j6 B0 [8 i
  202. RTS
    ; c- m& l4 d% t1 t
  203. ; b2 t' D8 Q: R4 U
  204. GamepadProcess;手柄处理
    ! Z( `7 \- T8 t, b( b2 h! w' n
  205. JSR GamepadDatacan) R9 J( {. S7 t- R& R; {! ]
  206. LDA <Gamepad_0_Value% Z; H  m6 s; j: k9 e( ^/ W
  207. STA <Gamepad_0_State; C4 Z% S5 C& J5 _
  208. LDA <Gamepad_1_Value
    : a0 E8 o( X. D9 _
  209. STA <Gamepad_1_State8 M! a- H6 n0 U* i$ H; Z  Z
  210. JSR GamepadDatacan
    ; Y( S( v3 l  ^5 ~+ u/ [: S
  211. LDX #$01* W0 w1 ~1 ^$ Q' W1 U: ~- E
  212. GamepadMergeCheck;合并手柄输入检查; q9 ]. u, T/ J; P: `
  213. LDA <Gamepad_0_Value,X
    ! Y7 X7 z. v5 I7 c, @2 a
  214. CMP <Gamepad_0_State,X2 E1 K+ D5 I2 s6 I+ e/ s
  215. BEQ GamepadMergeInput
    - C+ b3 M9 w0 Q" l1 e6 l2 F
  216. LDA <Gamepad_Temp,X
    ( w/ d. _- C4 `& z, j
  217. STA <Gamepad_0_Value,X
    . e2 z5 \( c# O. q
  218. GamepadMergeInput;合并手柄输入: l# ?4 s* c( L) O% o  G! _
  219. DEX/ d4 a3 N3 J* @7 L, O' z0 G% Y
  220. BPL GamepadMergeCheck8 v# j" V( R" C' P% u! d
  221. LDA <Gamepad_Merge/ G2 G/ s  \4 y5 M2 e& u  \: m2 f
  222. AND #GAMEPAD_MERGE_FLAG
      X( K  F+ Z6 n8 v
  223. BNE GamepadStateProcess
    % ]" r5 H  ^& \( a- @
  224. LDA <Gamepad_0_Value( ]1 G; n8 `5 O
  225. ORA <Gamepad_1_Value, Z- [9 v$ T& i$ z% \# o
  226. STA <Gamepad_0_Value& _' ~, b$ X; X
  227. GamepadStateProcess;手柄状态处理
    1 B: i8 C3 q, g+ A$ ?4 U2 i9 s
  228. LDX #$01( x2 p, ^7 A/ e& y4 q+ V6 H+ s, c
  229. GamepadStateSave;手柄状态保存
    7 k! S& C" n# S. C  h! K7 Y& ?: R
  230. LDA <Gamepad_0_Value,X1 D3 o! A5 j6 A  _
  231. TAY
    0 l3 B8 \+ c) [. v% g6 \. |1 I
  232. EOR <Gamepad_Temp,X
    6 W$ B; e( ^- z+ R6 ?" |! {
  233. AND <Gamepad_0_Value,X
    ' w6 Y2 J0 s6 u/ u! n$ }' F% y
  234. STA <Gamepad_Once,X7 D( y. c) _0 M) R$ F
  235. STY <Gamepad_Keep,X
    # h$ S3 P# a! M: ^$ u2 x
  236. STY <Gamepad_Temp,X
    % a# f% T: g& Q8 m( K+ k" O' |+ A
  237. DEX# j7 ~& D5 Z4 j9 A
  238. BPL GamepadStateSave
    0 \4 u" t7 ?7 Q' A: `. K5 M
  239. RTS0 N5 j% H  P: w# V
  240. $ h1 k! ]& R, U  {* t- Q( L
  241. GamepadDatacan;手柄数据扫描
    * l. q* D1 ~8 R
  242. LDX #$01- M# Y( ]# D0 }" C* A1 z3 r8 B
  243. STX $40168 U7 U2 l- B* v1 e7 D
  244. DEX
    * r! h. O7 b0 r1 w0 m
  245. STX $4016/ R$ c6 S$ i; o
  246. LDY #$08
    5 c# F6 g! o; [/ R: N7 k; d  o
  247. GamepadPortScan;手柄端口扫描
    $ h" F3 e8 Q) B& K( U9 p
  248. LDA $4016
    ( ^1 ?4 P5 }6 L/ E+ a
  249. STA <Gamepad_Port_Value# U+ |; @7 |' {3 ]1 ~! N% @
  250. LSR A  z* h5 |$ S+ c. ^$ r* l
  251. ORA <Gamepad_Port_Value: o7 [( P9 {0 s$ f' ]) y) N3 |
  252. LSR A
      s: \* I$ g. t" M- O- r8 `  @- s1 k
  253. ROL <Gamepad_0_Value3 u5 L5 W) [* O9 ~! k
  254. LDA $4017. O9 c$ K. |! L! M- r3 ]5 u
  255. STA <Gamepad_Port_Value$ Z! x, @8 ^2 s0 F, T
  256. LSR A. c$ N* E- \: ?; F* ?
  257. ORA <Gamepad_Port_Value* ^  U; l+ F) a# Q/ `2 K
  258. LSR A; V: L: I' {1 g" n- Q+ F1 M. \; a, c& |
  259. ROL <Gamepad_1_Value
    # |; M9 r" k1 i
  260. DEY# K; J; K* x7 T% W4 t
  261. BNE GamepadPortScan7 ^/ y7 t6 s1 s+ P
  262. RTS7 G; O8 z0 I$ Q  ?& T6 e

  263. $ G0 a' [3 k: \' `! v
  264. ;==================================================4 h. N  K( y  ?) Y
  265. ;PPU处理
    " `) S3 q3 W  D
  266. PPU_Process7 m- A% x- Y) H9 O  ^3 B  C, z
  267. LDA #$00
    & d3 H: o: S7 \* I: C% ?" ^0 H; @
  268. STA PPU_MASK
    2 q- S2 ^. d3 p2 f& P% ?2 a

  269. 7 C7 z5 h2 N/ [  m3 W+ Y+ Z; D
  270. BIT PPU_STATUS
    : v9 a8 B$ [/ @; m. r% @0 X2 m
  271. LDA #$208 r( R5 e6 t$ S* z8 F
  272. STA PPU_ADDRESS
    * {3 ^, M* W$ ?
  273. LDA #$00
    , s, ~/ U1 k5 ]8 G
  274. STA PPU_ADDRESS; o1 `' D6 }# _- K# F' A
  275.   d" l3 H/ T8 q# W
  276. STA PPU_SCROLL
      E' B  K3 W' c% w9 L7 a7 t
  277. STA PPU_SCROLL
    2 i" T9 y' J: K( g

  278.   L# [" j8 Z; O7 U6 t# @
  279. LDA PPU_Msak_Buf& E1 j) ~; ?! W  `4 ]
  280. STA PPU_MASK
    3 [2 }' v& C9 h
  281. ' S6 Y3 T3 u, b) U
  282. RTS5 U! _! c$ H' s4 j
  283. ' V) e# Z8 y  @& v, X& m1 ~0 G! V1 U" Y
  284. ;==============================( ]2 f% @) j. J1 c% m) w
  285. Time_For_Vblank;延时等待+ M  I( C7 W, K& K1 _
  286. LDA PPU_STATUS& T( o4 H- L5 R, V+ x/ `! O
  287. BPL Time_For_Vblank+ v4 l8 ]. ~" v; K+ M5 d& g% z9 b4 O
  288. RTS, |" w" v' a* ^! X: p6 a
  289. $ L7 O$ O! M! m& N: M7 ]4 f
  290. ;==============================. S2 _3 E+ U9 i" n# V
  291. ;初始化MAPPER19
    7 \" ~- X! K* M3 u9 `7 |
  292. Init_Mapper19
    ; P+ F$ K9 v  c* K- b2 @
  293. LDA #$00
    % w7 Y0 F8 E. E6 M- n# p' v' ~9 U
  294. STA M19_CHR_0000
    - X4 b8 k( ^) g  H* e
  295. LDA #$01
    : k/ B) K" j  Z
  296. STA M19_CHR_04004 B) X. p/ t& `. L$ w! U( a3 q2 g
  297. LDA #$02) U$ n: h2 W4 p& y; ?% B! F' O. @
  298. STA M19_CHR_0800& ?) ^' m9 }6 {4 b! M; k5 \
  299. LDA #$03# x' I/ e! Z0 r' t6 h' c7 D
  300. STA M19_CHR_0C00  w5 R8 T* [, c
  301. LDA #$04/ e" R. n% f8 b1 A: ^0 M
  302. STA M19_CHR_1000
    6 `# J& G& h* v" Y" g$ f
  303. LDA #$05) h9 \: N) Q/ s% D
  304. STA M19_CHR_1400# R! o& O9 F8 l( q2 a1 u
  305. LDA #$06
    . O. T9 g! w" M
  306. STA M19_CHR_1800: a4 H4 ]% m$ d7 E% q, U/ B" W
  307. LDA #$07$ N  l' E$ [) j
  308. STA M19_CHR_1C00. r' l' |( \, Y6 x: d5 X! S  ^% b

  309. ( _4 f) l7 a4 T9 h" L4 d
  310. ;禁用IRQ9 [6 d; ^% L0 c& ]  ~
  311. LDA M19_IRQ_COUNT_H
    5 M2 o+ k" n8 O* V' }
  312. AND #$7F/ l4 J. Q, ^9 t/ B$ L1 T1 z
  313. STA M19_IRQ_COUNT_H+ U6 b6 Z5 ~0 B

  314. & J3 X: y2 F" w: ], m7 ~
  315. ;命名表
    / P+ j8 J$ w' e5 A, q; a
  316. LDA #$E0
    & Y& A$ h: a( ?! s! H
  317. STA M19_NT_2000; ~' `+ P$ y4 J  h0 L4 L
  318. STA M19_NT_2400
    * J, B( _+ _- ~% D, F# T

  319. $ L7 |1 z5 J4 @
  320. ;命名表
      X5 ?2 _0 a6 Y) b) ^8 }5 S8 p
  321. LDA #$E1# i1 w& ?& e, C% y$ a
  322. STA M19_NT_2800
    0 \% Q4 y& K. ^$ k% E/ _( N+ s
  323. STA M19_NT_2C00
    % l: J- u6 H3 h3 P2 @/ ^
  324. ' H# w8 J1 C( l7 ]; R8 h
  325. RTS
    ) t" p. R' Y' ~+ O8 L+ r7 h

  326. 3 u* L/ G0 g6 I- p) }( l- {3 F
  327. ;==================================================
    5 T+ M0 F0 d( H
  328. ;重置中断处理( m- H) ]6 Y3 }/ a; G2 u
  329. ResetProgram
    " i0 W+ c* L8 U9 [7 }
  330. SEI
    - t* {- f3 I# z
  331. CLD# J; A+ i9 B% q  A) d
  332. LDA #$00# ?8 f2 R5 D1 D* W9 g2 N0 r
  333. STA PPU_CTRL2 S2 G" v2 c2 b- w- W8 u
  334. STA PPU_MASK
    ' o5 e# G' X+ k( O  X
  335. STA PPU_STATUS
    . S& z7 q0 W- z' I+ D
  336. STA JOY2_FRAME
    ' z, T8 w" T. H4 G& w7 a
  337. STA APU_STATUS( M8 R! }! L4 R; {, X1 N

  338. . p. |2 e) S/ V9 V6 S
  339. LDA #$C0* \9 K' e" j; y9 J
  340. STA JOY2_FRAME& b9 A4 g4 F( ?9 I3 }; r/ P
  341. 2 h( C  U4 ]# J3 e" z0 Q2 v
  342. ;等待vblank
    ' N' f* Y/ W% j8 f
  343. LDX #$02/ V; r+ K6 V, \& a9 p
  344. Vblank_Wait_19 y0 |; j6 {) O2 z- {- [$ E
  345. BIT PPU_STATUS
    " q' `6 p6 L  O5 T) w8 M
  346. BPL Vblank_Wait_1
    6 X! @; M3 |0 ~% h
  347. Vblank_Wait_2- Q" J& S& r, Z- g; b5 \
  348. BIT PPU_STATUS: ~! [# u3 [) M$ t
  349. BMI Vblank_Wait_2
    * q  t* r: o7 I4 p$ ], S
  350. DEX! n- B( `! {% q3 Y* c
  351. BNE Vblank_Wait_1
    # J- Y$ K+ P, k* o4 t/ {, U+ o3 l0 F

  352. ( D! @% K1 o% E' U
  353. LDX #$FF. b& ?' r* h) {) ^- p! d6 Z- a0 A
  354. TXS' C6 G% v$ P- w1 B

  355. / B6 l4 F7 \( [% i
  356. ;初始化MAPPER19
    ) v  S) s* N+ P
  357. JSR Init_Mapper196 Q- S. t0 N8 B4 K

  358. # `) U3 V: q$ y2 b4 h
  359. ;==============================
    " q. {2 f9 n" }2 t4 L0 D7 j% ~% y
  360. ;RAM初始化
    " c! w" K% O: f% Q1 V. h
  361. Nes_Ram_Init1 E  R: I" v; O, i
  362. LDY #$007 e6 ^; W) V8 C6 Y1 h& K2 l5 N
  363. LDX #$08
    # X% c* x3 j* S  `9 E/ L! y- K: K
  364. LDA #$00+ ^) j4 s, `- u% k
  365. STA <$008 X- H! B& d- e) U. l
  366. STA <$01+ k6 g3 Y9 b* ]; s
  367. Nes_Ram_Init_Write
    9 W9 x% H6 q5 o& j0 \' L  T
  368. STA [$00],Y- Z$ t. u( ]9 }  p
  369. INY" `9 W! X7 ]2 H, N, e& S3 ^% i
  370. BNE Nes_Ram_Init_Write
    7 W. i  }5 Y; Y9 N- P
  371. INC <$01, M0 F5 ]+ u7 r( P3 `
  372. DEX
    6 t3 J. _5 s+ D' i9 n% D: D
  373. BNE Nes_Ram_Init_Write  X/ u0 g9 b7 e
  374. % Q  _) _+ s# K2 T
  375. ;初始化命名表
    1 R' |# w* i1 z2 k1 }+ o6 P4 A
  376. JSR Init_Name_Table
    # J  Y8 E: [. B  F% S
  377. & ?/ _5 p2 ^3 J6 K3 a2 c
  378. ;初始化调色板
    $ j( y( M) G0 E3 r4 U, `' }8 R9 ]: H
  379. JSR Init_Palette
    " l( U3 m+ i: \% F
  380. + o! Z  m3 R6 H. m; \  v
  381. ;初始化命名表属性
    9 l4 I* i( K/ m9 G, S
  382. JSR Init_NameTable_Attributes
    0 v. S7 G* }$ ^- v

  383. " |; N) O0 g- ^$ x9 I4 e% F7 K
  384. ;初始化精灵内存
      I3 V5 Z  _0 ?' v
  385. JSR Init_OAM_Ram
    ( h& U$ Q7 D  d% ]

  386. . w8 J3 j- w1 ^6 L0 P, E
  387. ;在屏幕上写点东西* e! l: Q: ^# I" o: Q5 |
  388. JSR Init_Name_Table_Text0 W8 x, o8 G# E# U; X. a7 h: ]: V; |

  389. 0 Y, H; {) n( V
  390. JSR Time_For_Vblank
    1 l1 O8 D. I# S: G2 }
  391. ;开启PPU控制( n9 v0 o. f, Y
  392. LDA #$A8
    5 p+ x) n: c" L# M0 `. N/ w5 @
  393. STA PPU_Ctrl_Buf( l" K' k3 _: x# F
  394. STA PPU_CTRL
      W* V# A; b% T* }
  395.   s% I( `9 j+ w1 ~% ^! F. F: ?
  396. ;开启PPU显示: X* L- _9 h8 ]
  397. LDA #$1E
    # I' r" h$ ?2 n8 o
  398. STA PPU_Msak_Buf
    , l9 W( v  h8 R7 ]

  399. - C1 l" X9 n, o# w  j. a
  400. CLI" p  M. E+ @- B
  401. JMP Loop
    / l0 }- j7 E) s' D- T) d- j

  402. $ l9 E; A1 [$ v, L
  403. ;==============================. Y1 F: ^. g" B5 Z3 r- C" x) W
  404. ;死循环, 等待NMI中断/ j7 R% t* _( U( ]
  405. Loop
    5 X! U& I+ K5 y! f
  406. JMP Loop
    8 z. z" q4 C+ U! k
  407. 4 M& U' B8 a" l' G" h) _; K
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967) r; p/ w# r& R' V- b) F$ D

  409. ; J- ~* a: {6 d' @
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967), w+ c4 D+ B1 l2 |( X6 R
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    9 S2 ^5 Q. \% E! [8 t1 d
  412. ;==================================================5 |) x) E9 K6 V& B9 d( ]6 X- `
  413. ;NMI中断处理/ s7 w' H4 `6 q1 V
  414. NmiProgram
    3 R. ?3 o0 |. ]- b' A  {6 F
  415. PHA
    3 X9 R4 }; G0 }4 V. l
  416. TXA
    4 ~. e+ b' d6 g
  417. PHA
    - B# s! U0 D( J1 e* {# v
  418. TYA8 J, t' v- B6 |- a- f3 c9 i
  419. PHA; U5 p- T, P7 E& M) I

  420. - C$ b8 n/ ]6 ]9 @5 N
  421. BIT PPU_STATUS
    , H; I/ g' R( g( a
  422. 6 h5 I$ J: i; U. L$ M
  423. LDA #$002 |% W0 Q6 i, `( l6 {, w; I; O
  424. STA IRQ_Index
    4 b. S6 \& ~  S9 [+ H" @
  425. 2 k4 X- h( J  f, G% I
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    8 Z- F9 B6 D! P* |6 j
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)$ r8 y# D' }6 l! `7 X3 j5 i: L! k
  428. STA M19_IRQ_COUNT_L
    % f3 g  Q. a( `, _  C
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)6 t+ q5 f' t% e$ h
  430. ORA #$80
    4 R8 |1 t+ O; C
  431. STA M19_IRQ_COUNT_H
    & r  O0 k5 q# ~+ d  M
  432. CLI$ x2 ]/ a' o1 T2 R" J2 d8 X

  433. " Y/ c* E: y. `+ M
  434. ;关闭PPU控制+ W3 j" y, Q5 F; g% d
  435. LDA #$00& w+ x* e0 b+ {7 H# w
  436. STA PPU_CTRL
    4 F  u! C9 j1 P
  437. 7 g* M% V( ?! c7 K4 v+ P& }6 m
  438. ;处理PPU8 W' k8 z/ ^) Z3 y: k! b
  439. JSR PPU_Process
    * o" |$ ^. H$ g* E4 A# N( S& V
  440. $ H" _5 E; ]1 N
  441. ;开启PPU控制
    ( E2 R) ?1 o+ }' \
  442. LDA PPU_Ctrl_Buf0 P+ Z. I8 I9 _' \' V5 m4 W: {. e
  443. STA PPU_CTRL- M( s0 a2 _) m. f, F: p1 C

  444. 8 b1 ?* K) i6 i
  445. ;手柄处理6 Q; p/ ?: t: b# |, R# G
  446. JSR GamepadProcess1 H6 x5 K  c4 b7 w1 z, ]) ]

  447. " b! d/ g" s# T
  448. LDA #$00
    % H3 \3 g' m, ~: m% r
  449. STA IRQ_Index
    2 y0 o; E9 ~. t7 C
  450. 1 A. _) c7 S4 m, \; t: v
  451. PLA$ F/ V$ V: d5 U# o& H* Q0 P
  452. TAY. L, [+ _9 d) W+ m* N
  453. PLA2 j5 w; m7 [8 X, G2 w0 f3 x- H
  454. TAX4 E% y9 a2 u) R8 [
  455. PLA: d3 y* o: G  C
  456. RTI
    0 a1 V3 K& D1 I
  457. : K# l7 R  F7 o: |9 h- ?; p
  458. ;每行扫描线113.67
    # Q0 m! a0 v" f) K
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    8 n3 C" y! g( w/ [6 a
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    3 G* }. ?8 ~# m9 d
  461. ;==================================================* s9 h5 F* q0 a
  462. ;IRQ中断处理
    5 ^8 U+ \# I- D3 w
  463. IrqProgram' ^, q8 S! r1 S
  464. PHA, t3 A; Q8 `7 {
  465. TXA
      [$ |# m/ p3 a, W; a
  466. PHA2 I3 K( J3 Y* v
  467. TYA8 q' C3 o; K  ?! L* \8 A# n
  468. PHA. j1 k* i$ o4 Q$ A! [9 J

  469. . ^# F" T/ ^7 V0 x& q( X$ ^' \
  470. ;16条扫描线后触发IRQ
    8 s8 n! H* K/ ~/ Q
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    9 S" w8 }; J1 y# E
  472. STA M19_IRQ_COUNT_L# s7 a! X4 C' R: u) W0 s5 T4 T. C
  473. LDA #HIGH(BEGIN_LINE_CYCLES)! g0 e- D! N; o4 }. F
  474. ORA #$803 ~1 [+ t0 p7 s' d0 S
  475. STA M19_IRQ_COUNT_H
    : b. ~/ Q, K( l4 c/ Q' U: ^

  476. & l4 y- T9 S3 R1 }
  477. LDA <IRQ_Index
    9 T  Y. _7 L  K
  478. BNE * + 40 t5 z0 F7 }4 {. g
  479. INC <PPU_Scroll_H) [* i% P, L6 v

  480. $ \7 s& g6 U0 m5 c) }( [# n: b
  481. ;设置屏幕滚动
    ! D; I- j# k& \/ o$ w6 h
  482. LDA <IRQ_Index
    ' V) {- o4 `) [9 f
  483. AND #$01$ t) ]0 Y/ `. U$ r% M) U
  484. BEQ Irq_Scroll_Right
    9 h, ]( Q' X( l
  485. : f* T% E: u. [" a1 Q; l  P* n
  486. Irq_Scroll_Left. ^3 H' m5 i3 j" X; a
  487. BIT PPU_STATUS, ~3 _& }* S% W) x
  488. LDA <PPU_Scroll_H7 u" R% t1 O" F$ t2 s: \
  489. STA PPU_SCROLL
    / N3 F& u7 _& w5 u: I: q" q: g4 X
  490. STA PPU_SCROLL8 g; @  m8 R6 A# Z1 s
  491. JMP Irq_Scroll_Over
    5 v: I+ C7 r* h. H
  492. 0 j* t1 l0 a! A; y* P0 H) z# R
  493. Irq_Scroll_Right# [+ q5 r' e/ j; B9 o- n
  494. SEC7 m  P. G( q) l" y3 ]
  495. SBC <PPU_Scroll_H
    : c' d0 ?0 E* G0 h
  496. STA PPU_SCROLL+ T8 v9 K( [0 s) H& }
  497. STA PPU_SCROLL7 i( Z' O  w' e. ]2 W& i9 x
  498. Irq_Scroll_Over
    . ]% B+ l2 g8 Q1 q2 N
  499. ( G6 B  a* K7 R1 k7 D( o8 x7 o
  500. INC <IRQ_Index$ J$ a. f! ~  e3 |  V7 c8 T' @9 M8 A

  501. , V" P# @  j  A0 w* g
  502. LDA <IRQ_Index5 d0 N) r$ `) q) P# f  d
  503. CMP #14, y0 x$ L$ }+ N8 j+ C
  504. BCC * + 10
    8 g  d2 {, y! A
  505. LDA #$002 ?6 q! b/ r# m5 d! Q6 P- H" e
  506. STA M19_IRQ_COUNT_L
    4 k6 o, ?* b+ x
  507. STA M19_IRQ_COUNT_H5 j* f  h: D' c0 X
  508. ! t1 N* }' O+ |8 @1 C, D
  509. IrqProgramEnd5 B' s9 l* f$ ]7 I; r* m0 d4 K' H
  510. PLA
    " K: f( l- P$ X  U4 e$ @/ A
  511. TAY2 p' J1 `! }9 [0 t5 g
  512. PLA
    ! z0 f& w5 Z- ?9 o$ l, ?: u5 }
  513. TAX2 i+ E5 H. e9 @6 _. k6 Z
  514. PLA" [0 {( u4 u3 K) K% {& E# k
  515. RTI  h: N7 i+ Y( A' S* ~$ u& k

  516. 4 Q6 f1 e0 o; [* l
  517. ;==================================================
    : c. L0 [6 J/ v/ e
  518. ;中断表- a6 N/ J( Q' I3 U1 `% r8 ]
  519. .ORG $FFFA
    7 S- i% z" ^" K% L9 i
  520. .WORD NmiProgram
    ) Q# o* b$ e# S1 j; [
  521. .WORD ResetProgram
    8 l& H+ b- x7 b) U( F
  522. .WORD IrqProgram
复制代码
: I! i9 D8 T. F, Q3 q

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-4-26 19:22

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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