EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]( }4 j. C0 P4 J- o
  2. ;FlameCyclone 20230710  H! X) H" Z" F" k: v

  3. $ Y9 s& P1 ~) B0 d8 A
  4. ;文件头
    % p6 [0 [% g' _1 H% T3 e
  5. ;======================================================================8 ]! h4 b0 }2 O2 w
  6. .INESPRG 4                                              ;16KB PRG 数量
    " E, L1 t; l9 k0 g2 u2 X! t* p
  7. .INESCHR 1                                               ;8KB CHR 数量
      N+ u5 a2 q( V7 T
  8. .INESMAP 19                                                 ;mapper 19$ a% l) d2 Z$ R$ D& n' l4 h- P- q' a
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直5 \# W- {+ g6 p+ c7 j% V1 u
  10. 6 B: l9 j2 z) c5 T
  11. ;必要条件' p8 b7 M# `6 A" C
  12. ;1.持有CHR ROM" \$ D, \7 D3 u  W8 W4 i1 L
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    2 w% ^$ d# S6 u, d( n
  14. ;3.精灵内存(OAM)不为空
    ( N: G3 v; i* s' A# l

  15. 6 [1 t- K8 B4 k% S9 ~
  16. ;==================================================
      q, ^, [' A( h5 @0 D9 q; ^' M
  17. ;NES端口常量
      G5 Z; [& n" I, A7 G9 F6 F% c+ y) j
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    % x% x6 z" k4 \+ S3 ~
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器. m. d1 e: Y9 g. ?$ B! s5 ~
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    - i. t/ ~7 K4 q! V
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    + y* e  r% f$ {  o' M
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1& [$ Z; k$ U0 z6 a1 }; S1 x2 m% U- W
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    ; u7 x8 D7 Y! B) X2 M/ \
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    % G5 v: ^- c0 S% V  M- ]
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ! s' s/ j# z  g! L
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ) j+ W) j0 `% ?) ]* q% A+ j2 c2 n
  27. APU_STATUS              =   $4015   ;声音通道切换
    3 t% A$ f  ^5 U! N- v
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
      H3 }* ]& R# R9 F) {
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    % C7 `+ l1 e# e5 u2 W/ L

  30. 3 W4 k, W) a) S2 t/ D) i3 Z
  31. ;==================================================
    . _; C: e5 G+ [/ U! e
  32. ;MAPPER 19端口常量
    ( ^$ L  F6 E) b" Y
  33. M19_CHR_0000    =   $8000
    . [9 h& E5 I7 j" e7 }+ c- F
  34. M19_CHR_0400    =   $8800- V1 n% {" v# M& B$ v5 t* T8 c+ S1 _
  35. M19_CHR_0800    =   $9000' k% t7 c# k; U$ S0 ~9 G  N
  36. M19_CHR_0C00    =   $9800" G3 Q/ d4 W8 z! c
  37. M19_CHR_1000    =   $A000
    2 O2 ^6 c: b+ e
  38. M19_CHR_1400    =   $A800
    " @& d( q0 X# Z5 }9 B; X/ W4 D8 E
  39. M19_CHR_1800    =   $B000' v: M5 O+ y0 G5 e8 A2 Q
  40. M19_CHR_1C00    =   $B800  a1 R6 @- U# M) C
  41. M19_NT_2000     =   $C0006 k2 e* S! x( ]
  42. M19_NT_2400     =   $C800
    + p. S7 g! v( P; _( }$ j' M, E
  43. M19_NT_2800     =   $D000
    & m# q! N5 k. |. B" V
  44. M19_NT_2C00     =   $D800
    $ P5 [+ S( k! L* I" M( s! U2 W
  45. M19_PRG_8000    =   $E0000 p  m# z+ x1 @) h& Q) H0 `
  46. M19_PRG_A000    =   $E800. x% M3 g7 j4 r; F9 V6 K2 g
  47. M19_PRG_C000    =   $F000
    % Z3 w4 F! l  {
  48. M19_IRQ_COUNT_L =   $50000 W' W0 M$ Z' s, W, Y  n4 M0 [
  49. M19_IRQ_COUNT_H =   $5800( t; `) L4 d- o& E" z: l! E; p

  50.   q2 h7 x  G  ^: w6 F" }5 R' ?2 N0 C
  51. ;==================================================
    , t6 a2 ^; f$ u4 y! `9 }' w/ i
  52. ;程序块配置# Z+ n( @9 J& _+ W( \1 V% o
  53. BANK_DATA_MASK          = $07) S) y! R3 q- ~1 c$ W7 x
  54. ;--------------------------------------------------
    / Z. t3 M, k5 K5 _  B  p
  55. RESET_BANK              = $07
    1 R+ q0 h# W; _/ h
  56. RESET_ADDR              = $FC00
    7 }& T" r' r/ \! v

  57. * D4 |; x% H/ H+ B* ~
  58. ;==================================================
    ! [7 `! S- d. n6 K
  59. ;图像块配置
    5 }  ^% p8 _- p0 ~0 \
  60. CHR_DATA_BANK           = $08
      O0 w) T( _! h" V5 d" m4 y3 ]
  61. 7 F0 O( {9 B; ~, T- F" W6 S
  62. ;==================================================
    ) h2 g8 [$ s/ s
  63. ;零页内存地址配置
    * C3 i$ k1 V- H/ q, i
  64. Use_Ram_Addr            = $80- e. Y4 W" i" u4 A2 A& {1 V
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    ! f1 g$ X3 f! Y* N4 ]/ T$ \
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
      ]0 k; o& E, ^% D
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01# Q" b. p) H6 [+ J4 i! `$ P7 ]" h
  68. PPU_Scroll_V            = PPU_Scroll_H + $01' g- b8 T- r7 }/ }. u/ A
  69. FC_Data_L               = PPU_Scroll_V + $01
    . w$ h, V: M3 l
  70. FC_Data_H               = FC_Data_L + $014 J+ V2 H6 k5 P# F7 O1 p
  71. FC_Data_Buf             = FC_Data_H + $011 C# P0 H" s0 r/ M* h2 D5 l
  72. ;==================================================$ x. y# R, y- e( p

  73. ! y3 }1 ?- ?- u9 J: W% F
  74. GAMEPAD_MERGE_FLAG = $04' e1 l2 I: c7 x; x
  75. . W2 A" d4 T$ D3 s
  76. Gamepad_Keep            =       FC_Data_Buf + 1) R* [; s3 J4 a# X9 C8 x
  77. Gamepad_Once            =       Gamepad_Keep + 2: s; a7 Z- \( H% r5 R$ g: X
  78. Gamepad_Temp            =       Gamepad_Once + 24 ]+ C# M6 u, a3 y
  79.                                 ) \8 ?3 v# P( r$ L
  80. Gamepad_0_State         =       Gamepad_Temp + 23 ]+ I* N+ O" w) r2 a
  81. Gamepad_1_State         =       Gamepad_0_State + 1
      E8 V" W2 p% Q* Z$ o+ s
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    9 w9 s' ~. W7 u# y' a
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1/ k5 m3 g  J+ T( p$ F& b. @. }
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 13 r( K3 j# Z6 ]& k
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ) v: D# c1 p# P3 X& i' c  h
  86. , Z3 O; g( P  i/ W) H
  87. ;==================================================
    3 w) w) E8 ~8 U. c
  88. IRQ_Index               =       Gamepad_Merge + $01
    ; \0 M- j: d% s' v6 v8 a+ p$ b
  89. ;==================================================
    ' g  N: j* @. U! Y' ?

  90. 1 a& M, U& J* U% F
  91. ;CHR图形数据8 Q4 ]2 A9 X# P/ \0 |
  92. ;==================================================
    * R+ M3 U/ s' P, R
  93. .BANK CHR_DATA_BANK
    ; h, ~, d% t( ?8 v& ^- U
  94. .INCBIN "chr_bank/chr_data.chr"1 u6 K( [: [0 G- v- r# o% i5 ]/ G$ @

  95. & D% D$ t' o4 }- B
  96. .BANK RESET_BANK & BANK_DATA_MASK1 a4 g; z8 b3 f3 D8 }# q
  97. .ORG RESET_ADDR& B) e. L9 e7 t0 N0 `* G
  98. ; }+ v0 V) j$ q; ?* e& C% D' f
  99. ;--------------------------------------------------) a" G8 f) r$ ]8 u9 ~
  100. Attributes_Data, d2 i; E$ c: ~# ^3 S6 R* a
  101. ;命名表属性* G) [  N! ^$ E, A( v5 D
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    : l* ?# E; F) k/ c$ E% X- J. \
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA  l+ Z6 M& _$ ?: K
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA- P& b' p* D6 P% E
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    8 y* z% B" G6 P, J% q  V7 t" z
  106. ;--------------------------------------------------- V+ r- j% F* h9 H' s5 A8 J* C! U
  107. ;调色板数据
    + K" @4 D7 U$ ]6 k, V5 b
  108. Palette_Data$ \1 s7 i1 {  X5 i1 T$ g" B
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
      Z  V  [- X- h* x2 [! A( ^% V
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F3 b; v( D( @/ [3 i8 O5 p$ M4 X7 }5 @
  111. ( w' B+ V& W; R
  112. ;==================================================
    $ N2 J+ r! I7 G3 v" R) t. e
  113. ;命名表初始化
    " h" \5 @0 L1 U$ y( @
  114. Init_Name_Table$ q+ d7 P$ ~% Y+ h: o8 |8 a, ]
  115. LDA #$20  p+ M. L6 T  h, z- l) n; W# R, o
  116. STA PPU_ADDRESS
    5 S# K: q* Y/ G1 D9 r( S
  117. LDA #$00( d6 F- r% w- M- O4 l3 Q
  118. STA PPU_ADDRESS# \, ^7 I  t% b1 p
  119. LDA #$00
    ! {+ x* y* n" a  L# U0 T' i$ M2 O
  120. LDY #$00
    ! z2 x$ m* Q- z: X
  121. LDX #$101 [: }" Q/ z/ L1 v
  122. Init_Name_Table_Write
    7 u$ ?5 b7 F4 J1 ~, \9 A$ T
  123. STA PPU_DATA
    , O. t" k' v% T5 T, W
  124. INY
    - f7 j  B  E8 i6 A- a1 W
  125. BNE Init_Name_Table_Write6 @, r5 Y& I9 L$ W2 L6 j+ U# T
  126. DEX
    ! E: ~6 z1 Y4 r! n. }# ~1 u
  127. BNE Init_Name_Table_Write$ I/ s/ O# Q2 T% {
  128. RTS
    3 ~- `# G0 Q8 d# o2 j. B" @: M

  129. - E& [( D* C' y
  130. ;==================================================
      B; Q5 r9 I4 S0 F$ T! i8 y& o4 k/ w, t
  131. ;调色板初始化2 [4 _& }) Q, @) I  Z; n) y
  132. Init_Palette
    : E( n& P: c; y. }
  133. BIT PPU_STATUS
    % e) d, n; ?" `+ g4 A+ q$ L
  134. LDA #$3F) b# ?/ o2 `$ w
  135. STA PPU_ADDRESS: k. ]& u3 }7 G5 n' N  d+ ^
  136. LDA #$00
    : v+ `2 H5 u9 E" L- x
  137. STA PPU_ADDRESS
    % X) l" a; F+ D2 q& f4 N
  138. LDX #$00
    4 }" V, |$ V% z8 U# C, }& W8 i
  139. Init_Palette_Write2 b6 E) }4 @% A: s6 A( X
  140. LDA Palette_Data,X$ f  S' T1 }1 }$ G5 {- \# A
  141. STA PPU_DATA% S! Y" W2 t) u' W; i$ ~3 q6 O- t
  142. INX( e0 m3 q: y' d6 E9 ^! b
  143. CPX #$20
    , M: K! }6 n2 }% y/ l7 F
  144. BCC Init_Palette_Write* N, T0 D$ L, K0 ^4 v, V: v4 j
  145. RTS
    8 I& r) u; {2 W* D

  146. ! f' \% J' b8 L2 y. f7 X
  147. ;==================================================
    5 }  y% a- p. ?
  148. ;设置命名表属性0 u# y0 g" F1 G* Y' ~7 Q  k
  149. Init_NameTable_Attributes7 ]/ [& w( W1 w3 d* d6 ~9 o
  150. BIT PPU_STATUS
    7 l! s# s% e: D
  151. LDA #$231 Y0 Z, s/ O9 u- `9 _, Z
  152. STA PPU_ADDRESS" W1 n. A' ?$ {; z2 W- z
  153. LDA #$C0
    ' M9 l0 }- K* [' B, R
  154. STA PPU_ADDRESS6 v3 X3 e# j7 T$ d0 Q
  155. LDX #$00
    1 ^. f3 v) b" j9 @) W
  156. Init_NameTable_Attributes_Write" C+ p3 n- V7 `0 D, V
  157. LDA Attributes_Data,X5 g2 K" _( v9 t
  158. STA PPU_DATA
    8 C# @) |# b- I
  159. INX' q/ I$ q, E' y! H# i! T
  160. CPX #$40
    % |5 r. d  R! `0 X
  161. BCC Init_NameTable_Attributes_Write
    9 V! n3 A: `) P' j
  162. RTS
    5 t9 s5 ]# X, P  j' F2 o# V

  163. 6 n( G% C0 h6 |4 h& y
  164. ;==================================================
    - Q, E' J: d1 v- T
  165. ;初始化命名表文本
    6 p) o2 M2 l6 }, M( Q5 W7 [. e
  166. Init_Name_Table_Text6 L- S4 Z; T. e3 r/ R
  167. BIT PPU_STATUS' J% Z3 b; E- D' z' T$ K
  168. LDA #$20
    ) j- S( s: Z' v7 B; s
  169. STA PPU_ADDRESS
    2 |$ G6 [, w' ^9 a5 E/ j0 d
  170. LDA #$00( T$ o" \" }( r8 q; H# f% m2 O
  171. STA PPU_ADDRESS6 a* w$ D) N  r$ F& ~( c* K
  172. LDA #$00
    : g  P. ^* k5 G
  173. STA FC_Data_Buf
    $ \+ @2 J! `* w- k3 L" X7 q9 v2 Z  g
  174. LDY #30# s8 n7 u+ |2 _9 |  S5 J
  175. Init_Name_Table_Text_Write
    ' Q( o& K6 Z0 W$ K( a5 ]& d; B1 v, y
  176. LDX #32
    " j+ I+ q! ^( g3 ]
  177. Init_Name_Table_Text_Write_Char
    % s# x7 j0 i6 U" I- U
  178. LDA #'0') |# E) [, X3 t9 \6 j
  179. CLC
    . W2 L/ J* t' L. G9 d& w/ R/ I1 S
  180. ADC FC_Data_Buf! c3 E4 k+ l$ [: @1 Y
  181. STA PPU_DATA+ a5 ~/ P* K0 [) v
  182. DEX+ W2 X9 P, S+ v" o- b
  183. LDA #$14
    ( ~9 W9 T; I+ j* F6 ]
  184. STA PPU_DATA' y0 ?% L1 q: [; X0 }, a* r$ N8 v, j6 f
  185. DEX
    & c( ~9 E* m7 ~/ F5 g; d3 b
  186. BNE Init_Name_Table_Text_Write_Char
    0 b& Q5 ^% R9 N# s, g5 Z; r3 O8 j( e
  187. INC FC_Data_Buf4 m! E" f9 i6 j
  188. DEY
    6 a4 W, H' ]4 J4 j! g
  189. BNE Init_Name_Table_Text_Write' K& m9 k5 c( \; S9 }
  190. RTS
    $ @( g/ t; `" ]  A+ H

  191. 5 |8 X  O3 o/ \5 N
  192. ;==============================, Q: z0 g" \: k# t
  193. Init_OAM_Ram;初始化精灵内存
    + ~9 J$ k, z6 W9 M
  194. LDX #$00
    0 p. q+ H! l- B1 W1 c2 z9 B' k
  195. LDA #$00
    , k3 [, l7 t6 ?* l) `6 F& J! r
  196. STA PPU_OAM_ADDR7 ^- U2 F# s: o: w/ @3 J
  197. LDA #$F8
    * f+ F5 G+ n8 U9 j1 h1 I
  198. Init_OAM_Ram_Write
    % p& l* X- v- b. W
  199. STA PPU_OAM_DATA
    3 E8 |; E4 e2 ?" G0 A# j
  200. INX
    ' `  ^+ z5 v/ w  [9 U5 l
  201. BNE Init_OAM_Ram_Write
    - D2 ?! g( }; D3 f. O  Q0 h
  202. RTS% A! N. b! A! \/ E

  203. 2 R( L+ c% J7 _' i2 L. f
  204. GamepadProcess;手柄处理4 U5 J6 L/ i5 i: E' S
  205. JSR GamepadDatacan! j# g! |9 s( P; N5 @+ D# X
  206. LDA <Gamepad_0_Value
    : O0 P% s, f' J# b. L
  207. STA <Gamepad_0_State
    0 k7 z+ c4 }8 Z/ D/ m( I
  208. LDA <Gamepad_1_Value) l( Q, p% u* _& f0 n/ C) q0 ~# P- I
  209. STA <Gamepad_1_State
    - j4 G5 D  k# ^' F
  210. JSR GamepadDatacan
    8 f" Y: Q( r. o( D0 f* W
  211. LDX #$01+ P- o/ [1 q% [5 m: I: v+ p/ M
  212. GamepadMergeCheck;合并手柄输入检查* E$ l2 @' y- ?! g8 g$ b! u
  213. LDA <Gamepad_0_Value,X
    * v! e6 `  [$ S6 l) O
  214. CMP <Gamepad_0_State,X
    4 o0 P9 O5 V$ y% `7 @
  215. BEQ GamepadMergeInput
    " U8 m' a5 w9 z  C( {% I
  216. LDA <Gamepad_Temp,X
    % [8 T* Y% r* C( M- k/ t
  217. STA <Gamepad_0_Value,X
    % e' g" p* D% L- N2 \6 W
  218. GamepadMergeInput;合并手柄输入
    7 m# t3 p4 @4 e
  219. DEX; n$ c/ `$ V. K+ a& D8 C! a1 L
  220. BPL GamepadMergeCheck% B& f1 E; M8 W, F) I. m* s
  221. LDA <Gamepad_Merge5 l4 o& L3 V5 g' i# g/ _
  222. AND #GAMEPAD_MERGE_FLAG
    ) a! r/ t) O- {0 A+ x0 s  Y
  223. BNE GamepadStateProcess
    : n- t+ d9 f9 J0 J1 ]! m
  224. LDA <Gamepad_0_Value
    8 A& N; k3 G, u8 C- F! L$ _2 O; X
  225. ORA <Gamepad_1_Value
    4 a/ w9 g: N% b$ m% u
  226. STA <Gamepad_0_Value& G, a5 p, q3 x$ p/ Y
  227. GamepadStateProcess;手柄状态处理
      [% E2 n) _+ _+ q; c/ D2 H( A; s/ }' G
  228. LDX #$01
    $ a. ~4 f* l8 x
  229. GamepadStateSave;手柄状态保存' h' K1 B; r* [1 V7 Z
  230. LDA <Gamepad_0_Value,X
    0 Q* R0 t6 h1 w/ x& c8 C
  231. TAY5 p8 @3 S4 P* Y! N* _# q/ Z
  232. EOR <Gamepad_Temp,X: Q# R( R, P5 Y9 T6 J
  233. AND <Gamepad_0_Value,X
    * J& F; z. W, Z) t. h3 N
  234. STA <Gamepad_Once,X$ z6 v+ t' \0 @
  235. STY <Gamepad_Keep,X
      ~+ {3 }* e1 F" \. B
  236. STY <Gamepad_Temp,X
    7 D, l9 b8 s; T2 g/ N8 A
  237. DEX2 H2 t" \" p. Z4 j) w8 G
  238. BPL GamepadStateSave
    - D* s! r5 N4 {; }2 `# {& B
  239. RTS
    7 U0 q; C8 Q; K: T. ?+ R* d7 t

  240. 1 j3 n% y- u3 t/ S0 ^; U& b
  241. GamepadDatacan;手柄数据扫描
    6 y, S: [4 @  |) U6 g
  242. LDX #$01
    7 h" @4 c- a" I; ^1 L. d. X9 f
  243. STX $4016& F  @0 M% L. `6 o; X
  244. DEX
    # U1 N/ \  J4 S& l
  245. STX $4016/ T" ?1 @9 T6 E5 Z0 [
  246. LDY #$08
    5 h# A) o5 K$ m. c7 s' X
  247. GamepadPortScan;手柄端口扫描
    % T8 m' I3 y2 }
  248. LDA $4016! X! p" n' [/ Q
  249. STA <Gamepad_Port_Value
    + L# m6 B, ~* r2 J) U: O5 o* H; o
  250. LSR A
    ( \: g! J# y7 A0 u2 J4 H
  251. ORA <Gamepad_Port_Value
    " }% H$ o6 f0 o! ?5 r; ?1 H; T6 [
  252. LSR A
    . ?7 M  z( _  q& q5 I
  253. ROL <Gamepad_0_Value
    2 w& c4 N( |1 K6 a  a* d/ E
  254. LDA $4017
    7 [% o* z( H8 h3 R- k7 u; ^
  255. STA <Gamepad_Port_Value; f* w  E2 U) \$ Z% D% \  T
  256. LSR A# C6 ?/ X- U, [. J% z
  257. ORA <Gamepad_Port_Value
    , q, A% F% L- U5 L
  258. LSR A
    1 \, P% j/ o$ K, a  Y: O  Q( Q
  259. ROL <Gamepad_1_Value
      u7 b; N8 q0 \' f
  260. DEY
    9 v8 c% f- Q$ I0 ]7 e- e' I
  261. BNE GamepadPortScan
    7 i+ h( Q1 f! ]( t3 s" F
  262. RTS) v' r8 W* E2 T3 C* Z' E
  263. / B  ~& Q1 V8 G# E7 I/ D
  264. ;==================================================
    ' n$ c8 a8 a/ I& @
  265. ;PPU处理4 \8 f7 v7 \$ z' \5 ?
  266. PPU_Process
    ; \/ Q. |5 s  i7 S. b" C. o
  267. LDA #$00! ^2 s: b- R& K& A5 Q
  268. STA PPU_MASK9 V  x0 ^' W; T( d; a* f; q
  269. 7 ]" K5 n) i! `+ ^6 N
  270. BIT PPU_STATUS
    8 i' K9 a' @, p, Q' k. Y- |
  271. LDA #$20
      }% Q$ U4 P, b0 g0 V" X, S
  272. STA PPU_ADDRESS
    ' k0 F2 ~- O7 z
  273. LDA #$00" c# X3 H" x/ A  \3 P+ \
  274. STA PPU_ADDRESS
    " a% }! c& L. W8 n

  275. ) \7 t8 |7 g  B& C. u. n
  276. STA PPU_SCROLL" n+ ^) z! m9 [" C& A3 A. N
  277. STA PPU_SCROLL
    % b$ W. ]/ b7 ]! n# h

  278. ( E: T( ?& p$ i- S1 I/ }' p+ k
  279. LDA PPU_Msak_Buf
    8 U5 g# E8 a, S
  280. STA PPU_MASK
      P( ^# L  ]' u  D
  281. * [* F! H; J8 j" h' W: I
  282. RTS
    . K0 h0 ?) R) a/ E

  283. + U; P$ x4 {( W8 C
  284. ;==============================5 b+ z& U: V* R, x5 ~% {9 J* L% Y
  285. Time_For_Vblank;延时等待
      G, G9 t- \4 E. K  `! G- f
  286. LDA PPU_STATUS
    4 A, \6 D5 B( E
  287. BPL Time_For_Vblank* u6 L- {3 i# f; o: m0 a
  288. RTS$ u! k' ^$ k9 P2 U" |1 }6 f

  289. 6 w3 [. P7 U' T) B
  290. ;==============================" z3 o: ?/ @. z( ^1 @, {7 \
  291. ;初始化MAPPER19# q5 ^+ z9 d. j4 X2 l% e
  292. Init_Mapper19
    3 T) r# L. ]' x  V
  293. LDA #$008 ^" w; q; G) f9 X! Z- y2 B" ]
  294. STA M19_CHR_00006 ]$ a$ x% \) t, c
  295. LDA #$01+ [8 E5 D: e! j) @& I4 H1 Q
  296. STA M19_CHR_0400
      Q% j$ f* ]# c7 `7 }
  297. LDA #$02
    & N2 g) Z- r, V0 C* A4 v" p. s
  298. STA M19_CHR_0800
    " Z2 `, A& |9 v+ H8 ?# i1 K$ H
  299. LDA #$03
    0 S3 b8 ^' S+ }: Y8 Q7 ]& H5 h
  300. STA M19_CHR_0C002 x% ~4 Q3 S9 ?7 A: P
  301. LDA #$04
    1 C# W# r( p, X2 A3 j
  302. STA M19_CHR_1000' ?4 m7 n/ {  I5 G
  303. LDA #$05
    ( @2 i" a7 k2 u: G
  304. STA M19_CHR_1400' U, R9 `& q: K) w5 u0 [
  305. LDA #$06, p/ G! g) W( y
  306. STA M19_CHR_1800
    4 g# W! h% h  W) I
  307. LDA #$07
    % g) `% ~6 N1 p' D
  308. STA M19_CHR_1C007 ~5 j2 u  P' J! k

  309.   Y* z6 ~' G$ o' Z
  310. ;禁用IRQ! e3 ]1 E' u  d) H3 k- m
  311. LDA M19_IRQ_COUNT_H4 F. C3 D  r# M' n
  312. AND #$7F
    8 k7 l, b) `6 X( q; h4 k% r( G
  313. STA M19_IRQ_COUNT_H
    6 }8 U) c% T* K% P/ u( S
  314. $ `% H5 W9 Z1 D1 L
  315. ;命名表: U: v/ ?% I1 Q
  316. LDA #$E0
    9 y1 _' j# {7 i/ d; W, ]# N
  317. STA M19_NT_2000
    $ T$ Y% c5 z3 ?% ?" P! }
  318. STA M19_NT_2400" _+ O1 Z9 R% R4 K# M0 @
  319. $ ~" c3 R' F0 ^0 u- b* I$ T
  320. ;命名表
    " I# g: j" |- v# d5 `6 \8 e; v% {3 \
  321. LDA #$E1
    " M% g, [5 W# J- L: S
  322. STA M19_NT_2800
    1 L! b2 t1 {& C% m& f7 _& W
  323. STA M19_NT_2C00
    . W+ e9 f0 u) t0 |

  324. $ h5 d0 E4 x. [% ]
  325. RTS) ~7 p* J# f) p$ K% h
  326. ( t/ J0 b" i, }8 r' _6 H
  327. ;==================================================
    2 p( v& O# I7 Q. h, L
  328. ;重置中断处理
    4 D/ q9 r) b) {, a2 |; v
  329. ResetProgram
    % n" E+ ^6 p! j2 x' Z8 p, \6 Z
  330. SEI
    1 d1 U1 T/ A' |( v& a: {
  331. CLD
    " _! o) Y" U( D8 N
  332. LDA #$00
    : p* X  m$ o" U4 F/ j& h" g/ \$ w
  333. STA PPU_CTRL
    6 d8 C4 C/ e2 l: H$ K
  334. STA PPU_MASK" v- [7 y1 O5 {4 I6 J
  335. STA PPU_STATUS
      n" d+ V. U3 ]1 ]0 c$ q
  336. STA JOY2_FRAME  Z& C1 f( U& }! a
  337. STA APU_STATUS3 h5 K6 C* G' r1 w

  338. , w5 f+ ^; r, \) a, ]' V( Q) _5 \
  339. LDA #$C0& q/ n2 [* D2 S& V% S2 B( h
  340. STA JOY2_FRAME
    - l" [" C2 c* J+ p
  341.   Y4 [5 @+ D: Q1 q' r+ a8 h
  342. ;等待vblank2 ]) k6 N/ }& e2 L6 R6 N7 p3 B1 L0 i  [
  343. LDX #$02, ?$ \2 g& M5 A
  344. Vblank_Wait_1
    " [( y2 f3 l* u0 B
  345. BIT PPU_STATUS
    3 u7 x" c( b0 J7 F
  346. BPL Vblank_Wait_16 f& A& ^7 w3 m8 o
  347. Vblank_Wait_2
    % F4 y$ v) K1 ~: G" \& j4 `
  348. BIT PPU_STATUS
    ; L1 h: g  G, x4 `! }
  349. BMI Vblank_Wait_2
    1 X( h' t* j4 G3 e( o2 d5 `
  350. DEX
    ; a' ]- B) O+ j* d5 \0 N
  351. BNE Vblank_Wait_1) N( B" B" ?" m* d- E0 |% ^

  352. * R! a1 L$ P3 W# {; X4 }
  353. LDX #$FF
    % j  Y! s4 g1 T4 b
  354. TXS
    8 f- {+ c) A: n7 M) p0 T
  355. , Z4 J4 ^- f* q' G8 p
  356. ;初始化MAPPER19
    . F6 a9 E' e+ H. J9 W; X  ?$ z0 A6 A6 M
  357. JSR Init_Mapper19
    / ]) Q1 s1 q8 R

  358. 5 z. w: d! P% Q0 R) e
  359. ;==============================
    / Z" L8 V. d. `4 j
  360. ;RAM初始化3 j6 T; Z6 _# s$ X4 r$ _0 y4 v. i: ~
  361. Nes_Ram_Init7 W" {) Y5 z- x, _$ E
  362. LDY #$005 @" A/ E; N9 |+ @# E$ I, F5 J
  363. LDX #$08' y; o- Y7 w, A/ t8 h: z/ z
  364. LDA #$00
    6 F" {( z- B  \( v7 u0 |
  365. STA <$00* U! N  B( U2 U1 ]: Z4 k! A
  366. STA <$010 L% P4 `; {5 D: `! x  ~
  367. Nes_Ram_Init_Write+ n& t/ t  r2 N  s- y' J
  368. STA [$00],Y% s* n0 l# p9 p
  369. INY
    6 t+ g8 J8 O( Z) L
  370. BNE Nes_Ram_Init_Write, a+ Z- {8 m3 L  q
  371. INC <$015 I; [3 O7 R& d8 M
  372. DEX
    / J# n* k1 ~( V$ L5 _
  373. BNE Nes_Ram_Init_Write" O% A. a- a/ d! @& B& _  V
  374. ( x2 r( o( O  S: S
  375. ;初始化命名表
    ; _3 @. X0 L$ J' J0 ~" W
  376. JSR Init_Name_Table" _! c( z0 O2 V1 a2 K( m$ H6 W

  377. & b3 T% f4 c2 q* u8 [" f1 E
  378. ;初始化调色板
    ; z  _3 ]! a. v. y) B3 J2 }
  379. JSR Init_Palette
    8 |  u. Q9 Q# b. _# K& L4 U

  380. 1 v0 ?2 E9 a* r% Z. i; _& I+ O5 ]
  381. ;初始化命名表属性
    + R2 z( E2 d, ]! Z1 W9 i8 p
  382. JSR Init_NameTable_Attributes
    4 f# c3 s% g$ t6 h

  383. ; R' W+ [* |, d6 C. E6 V
  384. ;初始化精灵内存3 f; x& J+ ?6 q% s
  385. JSR Init_OAM_Ram" g' S7 z3 j" O: v, ~: Q. |

  386. " s+ D& a. J% b$ }
  387. ;在屏幕上写点东西: W( D& }6 l( E- l4 W9 {) S
  388. JSR Init_Name_Table_Text
    0 _; S- t6 ?3 R8 |

  389. 2 L+ D% c) a# h# |( ?
  390. JSR Time_For_Vblank9 n% c" E6 D  H9 q3 j2 j1 e  a
  391. ;开启PPU控制: b1 {9 ~7 M# a# G. @  F% m
  392. LDA #$A8$ E( N9 f5 n1 N( [' n& H" }1 h- n0 p0 y; n
  393. STA PPU_Ctrl_Buf
    7 ^  ]. b% {9 Z2 G! ~% b3 N  z8 F
  394. STA PPU_CTRL/ Q8 \( X+ B2 r7 N9 S; k
  395. / ~& ^0 i4 r) Y) J* e% m
  396. ;开启PPU显示
    / J6 v4 E$ q! M0 P. F
  397. LDA #$1E/ T6 A' F) N. P4 w* n# h* N
  398. STA PPU_Msak_Buf
    # a; Y# c$ E' p% a  ~

  399. . P! B- l4 f! A# n0 Q4 ]) B
  400. CLI6 H/ {5 L, B* R2 ?
  401. JMP Loop! @1 C# a7 `/ u+ P

  402. 3 n% n' Q: U& B* L
  403. ;==============================3 e' f9 H" J7 ~1 Z
  404. ;死循环, 等待NMI中断% E! ?, h  _! _7 v* [
  405. Loop
    0 s$ Q( _" Y( a, {# g
  406. JMP Loop
    0 L+ N0 b( L  O0 Z/ o8 @

  407. % _' Z" ]' [+ p
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967# `4 L9 Q0 r9 R

  409. ; ?, V' p9 A1 R
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)( U6 q3 r: a8 l" y
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    # u; Z) @7 F' m( C) F- r
  412. ;==================================================5 z& a* X, O, D# `/ @
  413. ;NMI中断处理; s- D$ p+ u2 m1 O% O- f6 @
  414. NmiProgram
    + n! d$ y6 d4 P
  415. PHA( c# J; F; |6 U5 D) W8 G
  416. TXA
    1 t/ a, l" D4 W
  417. PHA6 L5 H  \! q0 y% b* U+ m) ?3 }6 n
  418. TYA
    1 a( b4 M) u6 C% r
  419. PHA0 p" m: G) [* ?$ o1 u
  420. ( y: h# p! t/ ^
  421. BIT PPU_STATUS
    ) F5 f; V" G4 r- F) N
  422. 9 C, h7 l9 T( P/ Y' K$ g2 F
  423. LDA #$00
    * _: l! q. y# `# H; {* ?
  424. STA IRQ_Index
    4 S. C5 z  X8 W# e2 J% j

  425. ( N) R$ ]% m$ a
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    , ~+ I7 e9 [7 k( f: j
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    % N+ ?  q8 D, Y& J1 ]$ P
  428. STA M19_IRQ_COUNT_L
    + H' S& {! U$ [1 K0 p5 h, g
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START). `" U; R) a2 z
  430. ORA #$80
    ' \( x7 j! Z% g2 X
  431. STA M19_IRQ_COUNT_H
    # w3 B" R1 K5 I5 N
  432. CLI
    + X) H; k" T, L8 H0 T: ]/ ^
  433. 9 |0 v! Y7 u* I5 ^5 f. T
  434. ;关闭PPU控制
    8 T4 I- t  I- _- }8 |
  435. LDA #$00
    $ T- G. l0 ?& c* n4 p) h
  436. STA PPU_CTRL" V" X' h  i- d/ M# v
  437. # I8 C" a. }, e+ W
  438. ;处理PPU0 D/ [4 E: C  e& U6 R
  439. JSR PPU_Process5 V% a4 u" f) E1 L( c* g

  440. % C7 q2 Z- z5 |% c( b
  441. ;开启PPU控制
    8 N; }, h$ z! O% j- v2 y. x- n1 W
  442. LDA PPU_Ctrl_Buf
    & s5 Q7 W# [: o) O
  443. STA PPU_CTRL
    5 u9 _/ F' z& O

  444. - C- `( c; n! T) _& T) s1 {
  445. ;手柄处理, k' M* [) _5 Y7 V- N, v
  446. JSR GamepadProcess
    $ }; ~0 y& Q% S9 n
  447. # P' I2 ^, o8 J5 _4 x9 r
  448. LDA #$001 O( K$ k" X$ W% Z
  449. STA IRQ_Index
    5 a: h5 Y0 ^* l' |5 F4 L
  450. ) x" ]; @- s9 S- N
  451. PLA
    ) X  V$ ^8 u. v2 e  L- b% d
  452. TAY
    5 ^) N, u5 w( {! n- r9 M
  453. PLA. o$ y. i& b" w7 a. C  C5 v
  454. TAX
    * @3 n) |/ M. S5 B  N; `
  455. PLA
    $ W! n5 v5 N  Y
  456. RTI
    : O$ q1 i) E. u1 X; s

  457. , b  v+ x4 }% c
  458. ;每行扫描线113.67/ K4 v4 ~  J' ~+ U2 A! K" f* k) t
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    7 H% Z: ]# b2 x5 y4 _( c, j) C
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    0 h) v" ~3 H0 b. C) J
  461. ;==================================================- f) ?, I2 ]! E% G: V& i- c* y
  462. ;IRQ中断处理5 N8 ~( o0 c, [  D, r5 i5 N
  463. IrqProgram
    8 F# I6 E1 S/ l! h) c
  464. PHA
    ; K! V9 i( K, o- T' b' Q+ @8 M
  465. TXA1 |! r) Z  {/ d, g/ l
  466. PHA
    ; z! i1 v! W* Z( Q4 i# w2 x
  467. TYA
    - Z% q5 b" R+ L/ I! I* Q
  468. PHA+ Z3 Q5 p1 m! z! h! A7 x
  469. ( \8 N* s/ A" k5 Y; G5 g
  470. ;16条扫描线后触发IRQ
    2 `/ h& v! @! j3 v. M
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    * @1 g; q4 I9 k* U
  472. STA M19_IRQ_COUNT_L
    , X# }& {9 `3 {4 h) m& |" F) }9 l
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ( Q, ]% b' q( T/ _2 Z
  474. ORA #$801 D1 w; ~& c3 F" s
  475. STA M19_IRQ_COUNT_H; _! N- s. Q5 d2 |
  476. ; x- U. G1 p' w* W# {
  477. LDA <IRQ_Index: p" L6 F  k( j, N8 S
  478. BNE * + 4- F/ S, f5 {$ M* a- b
  479. INC <PPU_Scroll_H
    # ^1 _4 Y  F* C- X* V
  480. 9 y8 R# t8 v# |6 Z! T
  481. ;设置屏幕滚动
    / X2 Y4 D2 p; b# O4 B' s7 d/ i! N
  482. LDA <IRQ_Index
    ( }7 h7 y- E5 E& s% O* P
  483. AND #$017 I' v$ m2 y! j/ d7 f1 ~7 N( J! O* Y
  484. BEQ Irq_Scroll_Right, ~0 Y, }9 @4 T
  485. 9 g* P$ i2 F. K% J
  486. Irq_Scroll_Left$ ~) x, g7 b8 o+ o: @* i9 l
  487. BIT PPU_STATUS
    " C" Z, s& |+ J" l* t
  488. LDA <PPU_Scroll_H& y2 F* K* Z% ~3 d' F
  489. STA PPU_SCROLL; b- Y' W9 Y3 y' \! [- r( V
  490. STA PPU_SCROLL
    ) i& w5 U; V) J- f" ]# L1 W
  491. JMP Irq_Scroll_Over
    + G7 t; M9 Q. m0 U
  492. 4 Z0 N0 s; R  O: Y: V8 Q2 l
  493. Irq_Scroll_Right0 u( Q  J: Y* o  V6 w
  494. SEC  f$ e& B; y2 J; R2 g* m% o
  495. SBC <PPU_Scroll_H
    6 S1 Y+ a8 y5 f' O: j4 P# H; ^6 s, y
  496. STA PPU_SCROLL4 o. ^1 S2 g3 `7 k, v
  497. STA PPU_SCROLL: W3 W$ C; n/ A* {7 X$ U/ t/ U+ O
  498. Irq_Scroll_Over
    & j' T  t- y% I9 F3 ~
  499. $ e# m: o2 k5 V6 K
  500. INC <IRQ_Index- D5 B1 r; b) e0 ~4 }
  501. % F$ }$ x' N2 w* G% ]* m4 t! f
  502. LDA <IRQ_Index
    ( U  W3 x( n9 y# E* w; G2 Y9 f* W
  503. CMP #146 n; `" d# R) p+ v. G
  504. BCC * + 10; P4 ?2 f: N1 `$ r
  505. LDA #$00! d4 i% Y5 Y# p4 w2 S+ N4 E0 S5 q
  506. STA M19_IRQ_COUNT_L
    8 r7 w% }9 S9 Q' P9 {# m% j
  507. STA M19_IRQ_COUNT_H2 L+ h% ]; \1 ~* V
  508.   z6 n3 V; ?% ?( ^9 b+ V$ Z* X
  509. IrqProgramEnd
    . k' R7 X5 d1 [
  510. PLA
    # u2 K: ^5 B4 j. T. y# X/ {. v0 u
  511. TAY
    . z+ e# ]$ G4 K, L, Q
  512. PLA
    8 J; R$ s/ c! t1 W' |
  513. TAX
    3 x" z5 W- U; L/ D/ L! E
  514. PLA, ]! V5 |# L) U" Q3 G
  515. RTI
      _8 c0 |& z+ Y" f, R- G
  516. $ D7 W2 c0 z* W
  517. ;==================================================. w1 P  M; {' Q  d
  518. ;中断表
    " \+ s( s7 h. ?% Z4 h  P- a
  519. .ORG $FFFA
    # Q& a8 f% C/ ]+ ]7 k+ x
  520. .WORD NmiProgram
    6 u: K2 g2 m' T+ T, n
  521. .WORD ResetProgram
    ) L+ m( `9 M7 S  b
  522. .WORD IrqProgram
复制代码

5 N2 ~4 i3 H" _" y8 c

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-7-20 06:00 , Processed in 1.091797 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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