EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]3 Y& d' X2 R' z5 A3 y1 {$ Y
  2. ;FlameCyclone 20230710
    * O! K/ ^' L; I% m

  3. 8 R5 L! E" H  C8 d/ @$ i: I
  4. ;文件头& j! c) o- N/ E' c( M
  5. ;======================================================================7 A; X1 [) Q6 T$ {1 f  X8 P
  6. .INESPRG 4                                              ;16KB PRG 数量9 M; W8 c& y' ~/ f3 V/ ^
  7. .INESCHR 1                                               ;8KB CHR 数量
    7 b; [. p- T+ Z0 L5 H
  8. .INESMAP 19                                                 ;mapper 19
    * t2 }3 h# |8 A8 x& ~% Z' s8 F
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    4 [6 h" c5 w- z6 [/ q. t
  10. " i5 A- g# r* o& i6 v
  11. ;必要条件7 }5 C7 v# o* C& i, S; B. q7 @
  12. ;1.持有CHR ROM
    , E" z4 h1 j& m8 y
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    1 D! I( F! Y7 a. B/ G1 F
  14. ;3.精灵内存(OAM)不为空% C9 G0 n, z, U: t) ?9 e
  15. - r+ F/ K7 `7 E/ y0 y! t$ t# D
  16. ;==================================================
    1 I& @- Q) X3 k. O5 X4 W
  17. ;NES端口常量& v! D$ ~: I+ c5 m8 x" P0 Y
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器# r* u6 e. }$ c. _: @$ Y" G
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    % e! D$ K5 M0 M7 d+ E! P
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位% P- k$ ?( S5 l; G
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    & Q' ]# U0 \) C5 a: }5 S: x
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    ( k  N9 L" m# U1 p! H) c
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    6 b5 c. h8 g! i! A5 i. e7 E
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加/ K8 U$ n- N, K, L
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 # n' m) ?& F7 R* P
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存7 ?4 H: P7 k2 ^4 m
  27. APU_STATUS              =   $4015   ;声音通道切换
    9 V6 ~' J/ e) E
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    & V$ j. @/ e* ~
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通+ Z2 f( ?$ a; r  H7 z
  30. $ f; J/ j+ Y' z/ |$ X7 n* H7 `9 e
  31. ;==================================================# O/ n1 o/ u  p6 Z, e- j+ D
  32. ;MAPPER 19端口常量
    / p+ G9 _) x0 V1 E
  33. M19_CHR_0000    =   $8000, G0 d" o3 B" Z! ]3 @. b; G
  34. M19_CHR_0400    =   $8800& I4 S( ]/ O1 H
  35. M19_CHR_0800    =   $90005 C3 `( @* ?- J. b1 n8 v
  36. M19_CHR_0C00    =   $98001 T" P5 I, U; x" d4 P/ @; h
  37. M19_CHR_1000    =   $A0006 J, x1 P+ ]7 E' v' l
  38. M19_CHR_1400    =   $A800
    # V5 V: c% o: v/ h+ Y: c3 G# z
  39. M19_CHR_1800    =   $B000
    ( H3 [: |, m! @
  40. M19_CHR_1C00    =   $B8001 u/ R' Y5 U+ {* I% L8 T
  41. M19_NT_2000     =   $C0009 ^' t# O5 U0 _3 H" z) B/ ]( a  H
  42. M19_NT_2400     =   $C8008 ~/ |# S4 ]9 i
  43. M19_NT_2800     =   $D000, u+ O2 L. j$ l2 }" N/ B* {- C6 U
  44. M19_NT_2C00     =   $D800
    - C1 [5 o5 O' E. @/ [& q8 V
  45. M19_PRG_8000    =   $E000
    9 Y3 ^# [; t4 `+ M# S
  46. M19_PRG_A000    =   $E800
    * ?7 B: P. q0 s  b$ e1 `
  47. M19_PRG_C000    =   $F000
    ' {; J2 i* V( n8 n) Y+ {
  48. M19_IRQ_COUNT_L =   $5000
    3 P/ l$ d8 o( G- h) ~5 L8 @+ a) \
  49. M19_IRQ_COUNT_H =   $5800
    6 x# ~& {! I# U5 K7 o. j
  50. * g: u% V% e' w, |* m; _- C
  51. ;==================================================, D3 }5 R6 j9 I. P1 k4 l
  52. ;程序块配置/ F4 j! {+ O; ~+ f' Y. U5 \
  53. BANK_DATA_MASK          = $07
    % ~0 q$ w1 Q# G! W7 q+ s% f- z
  54. ;--------------------------------------------------
    . R& Y" n, @6 D. G
  55. RESET_BANK              = $075 v. g: `% f  t
  56. RESET_ADDR              = $FC00
    ; P3 v% A, P3 m; ^" a

  57. 7 Y7 d" p; ]. Q6 ^' G
  58. ;==================================================
    & W" }& K9 Y/ A; M$ r2 t
  59. ;图像块配置
    3 {7 u0 n+ G( m! z" p- E
  60. CHR_DATA_BANK           = $08
    , _  W. P# U6 h. p& N) R7 g
  61. / c4 \5 p! h0 h" I) c+ _0 c
  62. ;==================================================4 n# a$ }+ b1 l8 L5 d
  63. ;零页内存地址配置6 p- ~5 w& \  T0 D/ S& w! n
  64. Use_Ram_Addr            = $80
    ; D' P& L1 I8 }/ O* x1 P
  65. PPU_Ctrl_Buf            = Use_Ram_Addr  N# r2 \$ o/ ~6 G# M
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
      {5 t4 I4 S( x4 _6 X
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01: A. c, i6 c% j. n  x2 Q+ B% K( }
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    3 ?1 ]4 C' l& U2 c
  69. FC_Data_L               = PPU_Scroll_V + $01. H: t# d5 L/ b
  70. FC_Data_H               = FC_Data_L + $01
    & f3 @# u. W3 |8 P5 O% i
  71. FC_Data_Buf             = FC_Data_H + $01
    0 W( R* m$ a) R3 N
  72. ;==================================================
    3 X# j) X) Q" V$ E' D
  73. # n5 F/ a1 T4 S3 n+ Y9 t( K
  74. GAMEPAD_MERGE_FLAG = $04
    3 W4 I7 k! n. i3 a

  75. % I# N& N8 K1 m
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    % K$ G( ~/ d" j3 S: |
  77. Gamepad_Once            =       Gamepad_Keep + 2
    , i/ F3 G! y! r! y; O
  78. Gamepad_Temp            =       Gamepad_Once + 2
    8 T' L' F- c+ j" L- q
  79.                                 
      W& v/ \. t  Z  {) c. s. Z. j
  80. Gamepad_0_State         =       Gamepad_Temp + 2, b" z3 l5 h5 ~% r: ~
  81. Gamepad_1_State         =       Gamepad_0_State + 1
      z# h0 d4 G! E5 ?9 a
  82. Gamepad_0_Value         =       Gamepad_1_State + 18 r) N2 }# X( T' ]5 K1 N0 n5 T
  83. Gamepad_1_Value         =       Gamepad_0_Value + 11 p# M" W. Z# \1 z1 w
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1. z# b9 R- _3 L) `: }
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1. t4 E8 R* b: G0 }* a5 Q6 Z% a% G3 n4 l

  86. 3 U6 h: ]0 t: N, q+ o/ P8 o3 ~
  87. ;==================================================
    8 x* V" y2 @- H/ A8 t- i; Y1 d
  88. IRQ_Index               =       Gamepad_Merge + $01
    2 g0 s' m. O4 g9 A
  89. ;==================================================* z9 _4 R$ z" x! A

  90. + d# @  _5 j# H: w: e
  91. ;CHR图形数据
    - \3 O/ H8 Z- z
  92. ;==================================================4 M, P3 P: M" t" G# i4 k" o0 U
  93. .BANK CHR_DATA_BANK
    - [  D! Q9 b, y
  94. .INCBIN "chr_bank/chr_data.chr"
    , m" M, v2 Y* e% R5 q3 d3 ~- e
  95. 6 n1 s" O( N6 F; g' A! r" k4 C* F1 [
  96. .BANK RESET_BANK & BANK_DATA_MASK( b0 S9 j1 b+ K. Y0 o
  97. .ORG RESET_ADDR: Z4 D! H& I8 l1 h5 |1 D4 h
  98. . ~) R2 w# h& I% M% v6 P
  99. ;--------------------------------------------------
    & ^+ p+ O& S+ B  e" I
  100. Attributes_Data+ u' A$ t7 n: Q, \$ a. S
  101. ;命名表属性. I  a' H( Z! P' [* @6 ]7 \
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00! l% u6 {3 B) g- u+ K7 O
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA) f' C4 d& p( E3 _% {
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    ! X) U- K7 q$ P7 B
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55# l8 z+ K" h" q: L3 ~
  106. ;--------------------------------------------------: ]3 `2 O# U1 N0 M. k8 r+ ]8 W9 v
  107. ;调色板数据
      ?0 j* d) q2 t6 v  d0 i
  108. Palette_Data- m! |% ^# q/ I3 Z8 A* B$ ], p
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    " b3 m! @5 J. h$ n0 B
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F6 b; [6 X! G8 r* m3 F- a

  111. + o: m8 m; o  t0 B& W4 F
  112. ;==================================================8 m& o- Z( N# \- n, ?( j( o3 ]/ M
  113. ;命名表初始化
    8 \- [+ ~' a: N2 W
  114. Init_Name_Table
    " z" M* i8 w: s* m5 I# R
  115. LDA #$209 a0 U! }0 O- w( e
  116. STA PPU_ADDRESS
    , E9 n- G& G% s1 J: ?; i) i
  117. LDA #$00
    0 L  I2 Z6 ^; W  B1 w2 J
  118. STA PPU_ADDRESS
    . i' Q: U# `3 Q3 `1 g3 s
  119. LDA #$00  {1 p9 F* q& p& G% k
  120. LDY #$00$ S& \4 O0 v4 V% j6 Z& [6 ~$ p4 m! k
  121. LDX #$10
    ( `: |* \# D" y0 `5 N3 I
  122. Init_Name_Table_Write+ ]. }6 x* A: I' L2 V
  123. STA PPU_DATA8 [/ h" N( l- j% Q8 G: V
  124. INY' d) O5 p. }: ?$ d1 k
  125. BNE Init_Name_Table_Write! D$ R  l) N& [
  126. DEX# V. E6 S* \- x5 X, Q% l: G" ?
  127. BNE Init_Name_Table_Write
    ( `7 j" a/ n# B9 D
  128. RTS& W, X9 E5 f# E  n0 c3 @

  129. 1 a% B) P6 N4 X
  130. ;==================================================7 C# Y% R5 S0 b/ c$ C- a; M8 \2 i
  131. ;调色板初始化4 A7 v8 v5 e6 d4 o  V, ]4 T
  132. Init_Palette7 \+ j! m2 v) |, k6 T! d
  133. BIT PPU_STATUS
    7 q( B# j+ H0 k2 K* }0 p4 A4 ?  g  C& K! W
  134. LDA #$3F
    7 Y( }, Q7 i! c. R: v, k! [7 [1 j
  135. STA PPU_ADDRESS' h1 u& B2 }. @7 V8 r$ d( }: O: v
  136. LDA #$00$ k7 h$ N' Y! b, Z  F; {% g
  137. STA PPU_ADDRESS% P+ s0 d7 h  s5 p: S7 ~
  138. LDX #$00. w8 \# i- v) \3 t
  139. Init_Palette_Write
    # i3 H9 {; u9 q' b* W  \1 j
  140. LDA Palette_Data,X
    & ~0 Z6 d; r3 Y; D1 ^* H9 b4 C! I
  141. STA PPU_DATA) M* z6 @$ A) H, X$ c: B+ G) S* R
  142. INX& N, o& ^; ?# n6 ?
  143. CPX #$20
    ' V6 i+ x" q& [. s4 T  H0 U
  144. BCC Init_Palette_Write% i2 Z, }# K8 [! i7 n8 r
  145. RTS
    " l  U# T0 R0 f

  146. 6 Y* V& n" g! F( O5 J
  147. ;==================================================
    ; @% ]* q8 ^/ |& D4 Q
  148. ;设置命名表属性
    9 ?. n* F- K7 |" @9 _
  149. Init_NameTable_Attributes
    0 l! e2 @" b  Y7 Y) K# S
  150. BIT PPU_STATUS
    6 E! ?; B8 @0 o6 I$ X' L! B
  151. LDA #$23$ V  H$ G, q( i
  152. STA PPU_ADDRESS. f2 K: B3 ^. r. F
  153. LDA #$C0
    4 @: Y- T- |- o2 D
  154. STA PPU_ADDRESS$ W) T7 F7 d; U6 L
  155. LDX #$006 Y. H* d7 U6 \1 p' c0 X. A
  156. Init_NameTable_Attributes_Write$ l3 n5 b. R+ J6 u, Q+ s
  157. LDA Attributes_Data,X8 i  Z" F# N6 G* `; N4 u: B
  158. STA PPU_DATA
      d; ~& f6 ~8 c$ L5 o
  159. INX( v7 |) X2 Q% S! d
  160. CPX #$40
    4 g" B, P3 u5 b, f- N
  161. BCC Init_NameTable_Attributes_Write
    : i1 y, G+ g/ q& ^- }! o0 |3 h: ~
  162. RTS
    - A% R7 _2 h' }4 X/ t
  163. 2 c1 t( L; d5 M+ \1 b
  164. ;==================================================) G$ m; F7 c; O
  165. ;初始化命名表文本  u# L( O; {) p0 k: P0 }
  166. Init_Name_Table_Text
    $ \! ]7 u6 x0 d/ U5 f
  167. BIT PPU_STATUS% h( z7 P6 \% K/ p+ i7 C" K3 E
  168. LDA #$20: ^+ f8 g; x9 o& H) ]1 i$ t% T
  169. STA PPU_ADDRESS' a/ S/ O; z+ g  n0 U& `+ I
  170. LDA #$00
    " \/ S  P0 o: H9 e% P2 S2 D' I$ m6 m
  171. STA PPU_ADDRESS
    2 d) W1 E/ ]7 b- I" [1 z+ q
  172. LDA #$00
    4 l3 f5 A* S+ k
  173. STA FC_Data_Buf
    ; _% q( h* Y5 \6 E8 k' g( [
  174. LDY #30
    - I2 Z1 n' I" N' k2 [* h6 y7 T
  175. Init_Name_Table_Text_Write3 }0 U4 e, _, @4 h+ z5 Q0 ]  W
  176. LDX #32+ w# X  y3 `- Z! c
  177. Init_Name_Table_Text_Write_Char: W- Z: V) Y: _, e! K- Q
  178. LDA #'0'
    7 V  E7 m) m* I5 ?
  179. CLC
    . R) q* _" a/ ?" M
  180. ADC FC_Data_Buf
    5 v! S% h3 B1 E7 R! X# R: E
  181. STA PPU_DATA, `6 f  v1 y+ t' X) Y
  182. DEX
    ) i$ K% ?8 l: X/ g
  183. LDA #$14
    5 n& m8 y* `! k  R' ?# Z
  184. STA PPU_DATA
    : ~3 u7 E' j- D5 W( R; W2 u
  185. DEX0 M" k3 W! r. E6 m; M
  186. BNE Init_Name_Table_Text_Write_Char" l1 E; n9 r2 p4 l
  187. INC FC_Data_Buf
    6 z5 Q. U3 K, f5 X' {" k
  188. DEY
    , R8 i. \5 i( F* ]4 K! w# |
  189. BNE Init_Name_Table_Text_Write
    ! P9 x9 A* u* F# i5 C5 l
  190. RTS. L. l) j; _# V

  191. * N5 w- I* c+ k
  192. ;==============================
    / @, R6 k3 u& B& \. N& f$ |
  193. Init_OAM_Ram;初始化精灵内存: [; I9 E* {. n6 \8 z* O3 Y) f
  194. LDX #$00  X% H( C8 X% T2 {3 k# l- D# s6 S
  195. LDA #$00& E% w. u$ S6 Y" K. p& d, ^) f! Q# p7 x
  196. STA PPU_OAM_ADDR
    . d# l/ w- \8 S' x
  197. LDA #$F80 q2 C) r4 ^4 q/ w- \$ v1 c: k& c) i
  198. Init_OAM_Ram_Write) G% ?8 m5 z4 o/ T
  199. STA PPU_OAM_DATA
    # Y" B6 [9 o2 F
  200. INX
      l0 a9 N' C2 B! g9 [
  201. BNE Init_OAM_Ram_Write
    6 l5 y( I* f+ i9 d
  202. RTS
    - A; O  n3 \' E5 X) I( t6 Z

  203. 0 H4 `/ t* s/ U3 x! j9 }# L
  204. GamepadProcess;手柄处理
    - D) E2 c5 z& d2 ?2 c8 N
  205. JSR GamepadDatacan+ L  Z3 i: C6 l' d  f* H
  206. LDA <Gamepad_0_Value% F. t0 a# R: m" Y: n5 D' S
  207. STA <Gamepad_0_State
    , h! ~+ w; \( j( V5 G
  208. LDA <Gamepad_1_Value
    ( c( q4 Q7 F, X  f/ b4 D
  209. STA <Gamepad_1_State# Y; f; o7 V! x+ D
  210. JSR GamepadDatacan- q0 b' v: B. w- f3 @, _
  211. LDX #$01& P7 |/ ~" f" ^" M2 ?
  212. GamepadMergeCheck;合并手柄输入检查
    7 W: `2 `0 Y: Q3 ~. I1 V
  213. LDA <Gamepad_0_Value,X  J. T/ p) U. Z/ a
  214. CMP <Gamepad_0_State,X6 W( Q5 s7 L7 r* x+ `3 A
  215. BEQ GamepadMergeInput0 J# C. g& r% p# ^" S' i2 K# n
  216. LDA <Gamepad_Temp,X+ b  P  ~4 y+ j4 G- C
  217. STA <Gamepad_0_Value,X
    3 d3 Y+ R) Q* h& f7 @% W. [0 g2 f
  218. GamepadMergeInput;合并手柄输入
    # c4 N; W2 A& _* c
  219. DEX
    ; U9 b& m" `- _8 R& i3 q" y& n9 U
  220. BPL GamepadMergeCheck0 D! a3 N+ v  K: ~
  221. LDA <Gamepad_Merge4 Z- h! ?# Y# @: t4 c
  222. AND #GAMEPAD_MERGE_FLAG% K* o- S6 t) y8 A2 v0 F5 Q; k
  223. BNE GamepadStateProcess/ r* ^- ]4 u& B1 e6 |
  224. LDA <Gamepad_0_Value; B& @5 W: W; P
  225. ORA <Gamepad_1_Value
    1 M, h! {. L* E7 X
  226. STA <Gamepad_0_Value* E5 o  h  `2 @7 T' i% l2 s8 t
  227. GamepadStateProcess;手柄状态处理
    * {6 V; M$ \6 ^6 ]
  228. LDX #$01- `+ U9 ^7 F7 A7 e: K" E
  229. GamepadStateSave;手柄状态保存
    ( N) m6 h- `0 n1 }
  230. LDA <Gamepad_0_Value,X$ R& t& y* |& V, D- _3 X1 v
  231. TAY0 a8 A  \, S* O2 M4 W$ k6 [2 V
  232. EOR <Gamepad_Temp,X3 ~' }0 r+ y9 \
  233. AND <Gamepad_0_Value,X
    9 {5 X- W4 M4 Z" g! ^# A) r' S
  234. STA <Gamepad_Once,X
    6 c  g% A: L% f) X4 @6 k
  235. STY <Gamepad_Keep,X
    $ \. f+ g# C7 ]% C! o
  236. STY <Gamepad_Temp,X
    / n  v/ D6 J: I
  237. DEX
    + J9 _; ]( S( i, M
  238. BPL GamepadStateSave
    : J# O4 ]0 G& q4 R% A
  239. RTS4 M4 b" {, K7 {, ~

  240. 7 T) ]9 N' P$ d0 A0 M6 T
  241. GamepadDatacan;手柄数据扫描6 m& M- k$ q7 d$ ~
  242. LDX #$01
    $ U3 z. X, l3 l/ t: |
  243. STX $4016# q) C, R4 G) ~: n) g( L6 \/ G
  244. DEX
    + H, s: z( e; }" f& v
  245. STX $4016
    ! n6 M* _0 w+ s8 T
  246. LDY #$08
    3 C# L5 g- F4 [. ~. K- m) n
  247. GamepadPortScan;手柄端口扫描
    ) U5 S0 T) B. u" ]" D; ~/ J
  248. LDA $4016
    - ~+ d) E8 s. V0 @3 @2 O
  249. STA <Gamepad_Port_Value
    : v) j* T9 G1 y7 Y# A" {9 O
  250. LSR A; U% B6 \8 t7 E& [  _- L: @
  251. ORA <Gamepad_Port_Value
    ) l) M, @( v3 t7 c4 ~
  252. LSR A
    & S1 S" e2 X! T9 x- `
  253. ROL <Gamepad_0_Value8 ]+ c$ N- l# X
  254. LDA $40177 b2 j& f6 K& X4 G! Y
  255. STA <Gamepad_Port_Value, `7 y8 g7 f, ?! h
  256. LSR A
    ' @9 {6 C5 w9 o  w5 u5 d! w- _
  257. ORA <Gamepad_Port_Value6 ?; ~' ]" W" B( B
  258. LSR A
    $ C2 `( h) ?# C) ]' s4 F; F
  259. ROL <Gamepad_1_Value& U' t! y! u% z% U( w: L$ m+ ~, D' [6 k
  260. DEY
    . a6 M& n5 I9 i  \% G
  261. BNE GamepadPortScan
    - S- G' K/ l. |
  262. RTS1 _2 Z, j0 Q2 E! D

  263. . G+ B! g& t. Q
  264. ;==================================================
    9 l4 f1 s3 A8 G9 D; ?
  265. ;PPU处理
    " Y8 P! r" X5 F* Z2 l" J
  266. PPU_Process2 n8 |0 n, E1 y3 q( M; x) k: ]
  267. LDA #$00, l+ W8 h: t6 ]9 u/ x8 e
  268. STA PPU_MASK- H0 C9 M1 v5 o
  269. % }4 Z3 C1 b$ N  ~
  270. BIT PPU_STATUS
    6 T, L5 i) M0 d  m
  271. LDA #$20
    & D9 `  w. _) H: H. ^( W% d7 t
  272. STA PPU_ADDRESS
    9 a' s# M; f$ d( [+ L5 p
  273. LDA #$00
    1 [$ t) n: L7 t7 u& N
  274. STA PPU_ADDRESS
    ; z; J% K- O% |- T/ H  a

  275. ; u; ?, J8 U' G
  276. STA PPU_SCROLL
    % }2 v6 K! I- n( q9 o# d; W
  277. STA PPU_SCROLL
      c8 {% A1 ]: D; b# h8 p$ ~# J

  278. & H& S; R" B( o8 y
  279. LDA PPU_Msak_Buf  J, x3 u/ D7 s  q/ A
  280. STA PPU_MASK
    * F3 n  \+ W9 M+ }- q7 D2 Z; I! `
  281. / ]) a& K& k# `% G, g
  282. RTS
    $ @! _) C* }# m. h  A
  283. * Y6 X8 E) M7 ]7 X4 @; I6 E
  284. ;==============================
    ; K% g+ A8 Z9 Y* H# Y. S+ Q9 k
  285. Time_For_Vblank;延时等待
    # Q- F$ [9 e& a$ ^  c+ P+ U
  286. LDA PPU_STATUS
    , a  g) E$ I& S. t5 k3 w$ M: {. d
  287. BPL Time_For_Vblank
    * a' @* V- `# q2 B# c
  288. RTS
    ! ?& `: }, M! l$ Z* X
  289. ) h4 P* E7 d: r5 s2 s! J( r
  290. ;==============================$ k6 a2 E7 r1 V9 A" W% n
  291. ;初始化MAPPER19
      C$ a/ X( F% _* p8 J
  292. Init_Mapper19
    ( F7 ]4 M' T* U6 R' r
  293. LDA #$00
    : m) y1 M2 _$ e  S% N
  294. STA M19_CHR_0000, W: ~1 y1 ?( S& J1 q$ Q# {4 \, a- l
  295. LDA #$01
    . w: _4 @2 j  M. m6 t1 ]9 F) k
  296. STA M19_CHR_0400
    ( L% d7 W" G, Q: K' p
  297. LDA #$021 W- F" X  n: R+ E) w
  298. STA M19_CHR_0800
    2 f5 g! l3 f/ V, E  }
  299. LDA #$03
      @" S4 M9 I- ?- H8 ?5 n, x; v
  300. STA M19_CHR_0C00
    1 k: ^* @' N: u! I7 T0 _* s
  301. LDA #$04
      H  a9 a7 S* v7 [: H7 a, z1 X6 Y4 Z
  302. STA M19_CHR_1000
    8 h# T! R7 w- H" a) o% `7 C8 v
  303. LDA #$05
    0 T( T. Z% B' Y3 F. @1 ~
  304. STA M19_CHR_1400
    ' Z+ s5 N+ P  }7 t9 e6 o7 D( Z
  305. LDA #$06
    4 [6 i; @: Z. t: X
  306. STA M19_CHR_18004 `# N9 W" h4 p3 t/ {+ c5 ^2 r
  307. LDA #$073 A$ d4 @. p& {; ]
  308. STA M19_CHR_1C00
    : c+ b6 u4 y3 p& P9 e

  309. 0 P% U* Y! T# ?( e' u
  310. ;禁用IRQ  j. X1 I$ O0 D6 v4 e
  311. LDA M19_IRQ_COUNT_H) ?2 l5 g" A3 K! t& O& y
  312. AND #$7F% E2 a) M% k) ?3 A0 k0 e' ~
  313. STA M19_IRQ_COUNT_H
    $ Z8 a* [/ [# {9 v, E
  314. ' X2 T# x; K% Q. h% F
  315. ;命名表& D( o3 M+ R/ w; Z) Q2 Z
  316. LDA #$E02 U7 R8 n4 Q0 B$ |# K
  317. STA M19_NT_2000. z; Y& ^! m5 L7 B
  318. STA M19_NT_2400. m! q0 A5 @9 p7 W3 n0 T
  319. 4 I" Y2 C3 a4 \/ ~. x# ?& @# e4 x
  320. ;命名表# a" z5 K1 q2 M' ^9 C! h* Y  R6 I! r
  321. LDA #$E1
    : _; I! w- G8 g. ]
  322. STA M19_NT_28000 |' [7 D- @5 }5 d# ?% _
  323. STA M19_NT_2C00
    / q5 F% Z* s* a! r* S7 q
  324. " [3 `/ E' w# F$ G
  325. RTS0 s% l! o, [. q. n

  326. 5 M8 k% M- s" i
  327. ;==================================================
    ) l- m: H% e8 f( z# h
  328. ;重置中断处理
    ; l/ G* d( V  Q: D
  329. ResetProgram4 Q, s! J# z  j& j
  330. SEI' ~4 A7 r5 _' q1 H/ x3 _
  331. CLD' r- ^/ o8 W+ W( N4 Y0 L
  332. LDA #$00
    2 q% a7 T" |5 X! ^$ J9 a. j
  333. STA PPU_CTRL- D7 j; H/ x" u  f! I. j
  334. STA PPU_MASK
    : E) R# o1 w3 ~4 d& O+ N  V
  335. STA PPU_STATUS" `+ K# V1 @1 _# @9 B* |: M
  336. STA JOY2_FRAME
    ) c# P! D/ [! E  {  Y8 O4 u
  337. STA APU_STATUS( A5 K8 [( }1 v/ Z& \+ _/ C+ q
  338. : Y5 j; a& x5 l+ ^/ X
  339. LDA #$C0
    % j- D9 V$ y4 z5 T
  340. STA JOY2_FRAME+ _% g8 x2 i* C) h
  341. & [2 Z+ A6 ?# i1 z
  342. ;等待vblank
    0 G- q" t! B2 k. L- A
  343. LDX #$02# u- J2 m) T0 |5 W8 J! V( |
  344. Vblank_Wait_1: N0 D5 w1 P- G6 g7 v
  345. BIT PPU_STATUS
    7 F# l6 w6 [( P3 V4 N- M' m
  346. BPL Vblank_Wait_1
    , _9 \" E, u- d8 q, j* _) y/ a
  347. Vblank_Wait_2
    ; Z( }% _+ y6 T# X! Z, V7 ~
  348. BIT PPU_STATUS
    ' r2 X- _/ K$ @2 f. F& X$ f/ T
  349. BMI Vblank_Wait_2/ S" s( P4 j) V6 F, g
  350. DEX
    " @7 w# F/ |9 q+ q& T/ S
  351. BNE Vblank_Wait_1' t; h0 x" G- G3 d2 Z$ S6 y( I

  352. 8 t' q2 d: E( b  c- }9 p2 n  j9 [
  353. LDX #$FF" E; y1 q3 @6 Q9 M& \9 h, ]4 m
  354. TXS
    0 L4 A6 U+ p) s

  355. ' e4 c9 l, Y0 \. A
  356. ;初始化MAPPER19- n6 R9 E! O' t
  357. JSR Init_Mapper19  d# b0 W: h! {" }
  358. + ]) a& M. Y$ u: A7 W/ E
  359. ;==============================) I0 ?6 i# W4 `4 q) c" [* i
  360. ;RAM初始化' T7 E" l/ L5 T" u% k9 _$ c! S
  361. Nes_Ram_Init/ |- k0 W# O7 T- F
  362. LDY #$003 v5 \6 J& E4 `- v' v2 f
  363. LDX #$088 D. ~1 X# K% G! g/ w) u
  364. LDA #$00
    & [) |. D7 l0 t# n: T" w6 j
  365. STA <$006 [" Q( }, y: K# z0 r. P& H
  366. STA <$01
    0 d4 F+ Z, ^+ O7 m0 v. Y
  367. Nes_Ram_Init_Write
    - m+ c+ @( s: ~5 U% O
  368. STA [$00],Y: F; `3 q0 D) r7 j2 k
  369. INY# Z) f. N6 i, e) I9 C
  370. BNE Nes_Ram_Init_Write0 E* }3 g. r8 B3 a$ r8 M
  371. INC <$01
    ; n( l0 d6 [& G" @) W7 x2 U
  372. DEX# P$ a1 c. ?: X2 X, M
  373. BNE Nes_Ram_Init_Write
    1 v& \4 f/ C+ R3 P- j6 e9 C, f
  374. ) `1 P% F8 F2 {, p
  375. ;初始化命名表9 ^( ^! j' l$ O1 e1 @" f7 B8 X) B% H
  376. JSR Init_Name_Table
    + j7 A  s  e- k7 z( |
  377. 5 y' X- }8 v. s- p
  378. ;初始化调色板
    , d( H) y; M$ h5 {. D
  379. JSR Init_Palette
    3 T9 `  Q5 m" h% Y% `1 _4 Q' C
  380. ) }4 T) M2 H6 {% m8 m+ G5 K
  381. ;初始化命名表属性
    1 g& C7 [' p, L" C% c1 y" ?
  382. JSR Init_NameTable_Attributes
    , c3 d, r. N) O+ o( T
  383. + x/ d4 M9 p6 X" i
  384. ;初始化精灵内存9 b" L2 @5 t0 E* U8 O$ W. X
  385. JSR Init_OAM_Ram4 Y. f2 `! ]9 h0 Y

  386. 9 j4 ]. c: R  [4 f4 Q
  387. ;在屏幕上写点东西5 _. {% b$ R5 x/ a# Q
  388. JSR Init_Name_Table_Text
    4 K+ l- V5 i3 n0 p/ Q" ]! u
  389. & P& t7 e) t$ T' Y9 j
  390. JSR Time_For_Vblank; e( ?# {  C2 ?2 E! N) X5 t: o
  391. ;开启PPU控制
    1 r  Y( i3 v) T! g* o* O
  392. LDA #$A8
    ' b( |9 S, H+ }; z
  393. STA PPU_Ctrl_Buf' O' m, i8 }* ^8 Y
  394. STA PPU_CTRL; R/ @3 W& s: d8 H$ P, ~
  395. ) R, ~( B! v2 a1 |8 k4 s
  396. ;开启PPU显示
    + E, ^. I9 h% Q
  397. LDA #$1E
    ) P! ~6 w0 f' a+ X: j  x( L2 w1 S' V' d
  398. STA PPU_Msak_Buf, C# i) W/ R0 L, s2 J

  399. 7 Y; e9 d' ?6 }+ f
  400. CLI
    : B: j' _& `  N( O% z
  401. JMP Loop
    5 w1 I" s' S6 a

  402. # G0 u# S0 k, l: {) H  f0 y3 e
  403. ;==============================$ P# s7 ^9 m: K
  404. ;死循环, 等待NMI中断
    2 k: m: U8 m  A$ L$ g! W
  405. Loop# t8 t/ F5 q: s+ G8 I) U
  406. JMP Loop, P' j+ V! P, W, B3 V. N3 w
  407. " o' c! S+ {" ^4 N. |* t7 Z, n1 W
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    2 X* p5 t8 b" g5 _3 q0 b$ ]
  409. 5 O5 U' Z! K$ m! m9 E
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)9 J, h6 O9 M: N$ q5 N
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)+ t# P8 Z' T& q/ U: y) l
  412. ;==================================================
    % X8 O8 s3 w' w) g- ]0 @0 I! Q- P  ]. S
  413. ;NMI中断处理% p% G7 J2 g) q9 y" J( F$ k
  414. NmiProgram5 Y4 H. \5 l3 D% Y7 J9 o
  415. PHA# g9 ^# M- C, ^. D3 s
  416. TXA1 Q5 r0 `0 ]% R& F$ G
  417. PHA
    7 ?9 P+ f7 I/ @5 {5 i
  418. TYA( K2 b' V7 l' A5 @: N7 X
  419. PHA; `6 m, `0 |: D' J, `6 y8 |
  420. # I& x% I& \9 S
  421. BIT PPU_STATUS8 O# q" Y6 W: ]2 v% ~  h

  422. 5 u7 U3 j. Y- w  P' }* w
  423. LDA #$00
    2 ^% i) [6 r" i" V4 [$ T
  424. STA IRQ_Index
    8 H; S0 t. ~2 W! i  @% V

  425. 4 a/ x! n1 u1 W
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动6 a8 h: j8 F. k9 ^# u! Z4 e5 R
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)3 W' ?! O/ t! q; u
  428. STA M19_IRQ_COUNT_L
    + a1 V6 @; Q8 I# m3 a4 _4 A
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)0 M7 s9 x9 g+ n9 O! B: e) W) N
  430. ORA #$80) O$ \! C) C* \9 e0 d
  431. STA M19_IRQ_COUNT_H9 \: ^! X! o5 U" o- \
  432. CLI- E. T5 h* j' x6 X& {0 G4 c% J8 e2 b% ^
  433. 0 _% Q4 o$ j2 O# m
  434. ;关闭PPU控制6 ~- H8 ~5 s. E, C  S
  435. LDA #$00
    ; ^$ a' T5 Z1 _& W
  436. STA PPU_CTRL" T2 t0 E6 @& m  h; I

  437. , p' O9 i* Y" q# k, p3 A6 E
  438. ;处理PPU( a4 Z. @6 N6 Y2 v
  439. JSR PPU_Process
    . ~- i3 U% l0 y$ I4 f$ l/ r
  440. ! x0 Z/ t7 F, w
  441. ;开启PPU控制
    % Q" E$ H  p6 ^9 M
  442. LDA PPU_Ctrl_Buf
    1 g, `  u4 o, [' v
  443. STA PPU_CTRL
    6 P9 M7 b" E' K1 @) @
  444. + }' g- c6 H! ^9 M
  445. ;手柄处理
    ; k, Y. d+ Y0 z, `/ M2 `
  446. JSR GamepadProcess
    ( B9 E0 E: u) @4 [
  447. 9 Z" J* u: y/ s4 _, \: R% h; Z; a
  448. LDA #$00
    6 ~. j! y( I  A" c
  449. STA IRQ_Index
    7 f- C$ \3 R  c' |9 c

  450. - o  e7 K9 B6 B. q2 h9 p
  451. PLA) ^7 x! f0 D7 m6 B0 }
  452. TAY
    8 q3 w- M& K1 e# d
  453. PLA3 k: E: w9 M5 j6 i" R
  454. TAX
    * e8 B0 Z% b& C+ S
  455. PLA
    + g# G3 R! T0 Q  l2 r
  456. RTI
    ! {/ R* l& G9 g1 j# d

  457. 1 X) _% P. M; G9 n( P& }
  458. ;每行扫描线113.67. r. C4 N0 t! L% K" A5 k
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    5 z; H! t0 W/ K" G# P. L1 f
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ' Y: u( N9 Z1 F" C; l
  461. ;==================================================
    . L% ?* q( o# H( v& L
  462. ;IRQ中断处理5 B- }* ?% D9 q  l) J- N
  463. IrqProgram4 q- m1 p* ]# P+ D. t
  464. PHA% e3 c! I- m' z
  465. TXA
    ; ~+ l0 ]$ A# j1 k7 J, x
  466. PHA
    + R+ L0 L1 k" ?4 m
  467. TYA* W7 m, N+ y3 X( T
  468. PHA
    ( b% |2 \" v" H

  469. ) g; N" ]% K6 u- ~# {" ?
  470. ;16条扫描线后触发IRQ
    & I' g5 k4 f) B4 O
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    " @" h% K: V! [) M& }6 y: b# k
  472. STA M19_IRQ_COUNT_L- ^: u2 ^$ d* w( _5 e* Q
  473. LDA #HIGH(BEGIN_LINE_CYCLES)6 K! Y" i' t* M
  474. ORA #$80# G$ y( I( r8 U; W, b7 v
  475. STA M19_IRQ_COUNT_H) X. j. X5 {& ^: M5 @; Y) T
  476. : ^" M6 j& W' e5 M, Z4 |
  477. LDA <IRQ_Index
    5 M+ m4 H; v( a/ [5 ^+ {* ?3 T. a
  478. BNE * + 4
    $ V" r3 w1 O$ `$ _8 B1 G( _3 }6 T$ G& H
  479. INC <PPU_Scroll_H/ j) J! K. h$ t* ?" \
  480. 2 d$ H8 H' \- ]. ^: i
  481. ;设置屏幕滚动
    " \% t& r3 y" f# b
  482. LDA <IRQ_Index0 a+ h$ C+ s6 D! O
  483. AND #$010 [) Z0 g% u+ @4 b3 e0 O4 u  v
  484. BEQ Irq_Scroll_Right
    8 Q$ t; e! T+ ]8 z3 R8 t) p

  485. 7 H/ {' `* ?' z/ N$ @& G
  486. Irq_Scroll_Left6 ]" s: w9 R8 ^9 G1 E
  487. BIT PPU_STATUS
    - P5 C$ o5 k% @
  488. LDA <PPU_Scroll_H$ ]) }* z% n5 W! ~. X9 f: V
  489. STA PPU_SCROLL5 V" O* j. i# W+ E3 j# i
  490. STA PPU_SCROLL/ A( _+ Y" I7 K; x6 Q
  491. JMP Irq_Scroll_Over. }& f" Q8 [' G* {9 h" s& j. ?  i# x

  492. % A/ H" r$ o3 h2 d# T1 T% q# b
  493. Irq_Scroll_Right! _8 z: ^* A  g. A" ]. j
  494. SEC
    - \- |8 n/ @1 w9 T1 ^6 @$ H
  495. SBC <PPU_Scroll_H
    7 K8 d7 j! w7 _2 w* X
  496. STA PPU_SCROLL! p* t+ m' C* [" ^. L) N+ v
  497. STA PPU_SCROLL: D9 i$ O8 ^2 d! T; L) o
  498. Irq_Scroll_Over" T5 r! \8 E& z2 C3 d  }* z" C

  499. * {$ a3 d/ w$ o# [
  500. INC <IRQ_Index: J! b* A; y, Y( I
  501. 5 ^5 _6 K4 v: V8 N4 @) z- L
  502. LDA <IRQ_Index6 |' e; |" A$ |6 H( f
  503. CMP #141 b9 A1 `# Y4 Y
  504. BCC * + 10
    " K: a* W' b" O5 }' S
  505. LDA #$00
    & I1 [1 _# t, D
  506. STA M19_IRQ_COUNT_L
    + h/ ^# m5 r1 g/ U- W
  507. STA M19_IRQ_COUNT_H
      q" c5 r4 T' }3 m

  508. * q( `: }: `5 ?/ u; ]( O8 G
  509. IrqProgramEnd. e; Q: i9 ^6 k4 }
  510. PLA
    1 d$ Y4 Z" D" J8 q% _
  511. TAY0 Y: R2 H' q) x5 P. z' ?' o/ e
  512. PLA
    : B; @& P2 [9 r  T* o8 T
  513. TAX
    " M$ W( N$ i/ |* o* j
  514. PLA: X" L# A, T. K$ F* ?, z! w; T
  515. RTI8 S+ ^" F: g! Q6 F' O& M

  516. / o( ?. q; `" `) N
  517. ;==================================================
    / f' C9 ^# w! k8 J
  518. ;中断表% Y. b9 b# ~4 _. D
  519. .ORG $FFFA, o5 |4 `3 Z0 I0 J% k* x' N
  520. .WORD NmiProgram4 d8 x" e/ r) p' \7 I7 d
  521. .WORD ResetProgram
    / r0 ]/ s6 s- i3 X
  522. .WORD IrqProgram
复制代码

2 a# R  D6 F+ @1 T% Y+ H

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-5-11 12:53 , Processed in 1.078125 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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