EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    , Z3 ~/ k9 a* k5 l& P
  2. ;FlameCyclone 202307105 @0 p0 i. z2 g

  3. / m0 L( J0 |0 m8 ~! a; K5 E" t7 q
  4. ;文件头9 \  L& d) G# @" R7 W
  5. ;======================================================================" X7 T' @% M' k) L2 [8 ~# s% u
  6. .INESPRG 4                                              ;16KB PRG 数量3 d" ?! @# B/ {$ @. n; n. e' O
  7. .INESCHR 1                                               ;8KB CHR 数量
    % C5 z8 Q$ _, B8 V# m
  8. .INESMAP 19                                                 ;mapper 19
    ; G! f! @! l3 a% G, g( ~
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直" `+ L- c; a; f/ g

  10. ! x. K% J5 l" p+ |
  11. ;必要条件/ _% Y* g& ?- x1 X3 _+ [* Y
  12. ;1.持有CHR ROM
    1 Y1 d3 v! a! h' B6 R5 L
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    7 L0 y: f9 @3 R* ~- f6 ~2 S
  14. ;3.精灵内存(OAM)不为空
    : L) [# C2 D7 t% s
  15. 3 v" h$ Z4 y* r* k
  16. ;==================================================
    8 {' C* C7 {4 v
  17. ;NES端口常量
    & _! ^+ K  O1 B1 v
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器1 |  f- `, i# i6 A  Y3 S
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器0 _  _0 k  D! g) ]3 u! W
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位3 h: J  K* I2 s: B4 l! l
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    0 W3 d, {4 ^" J8 N9 g* \0 g
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    % f. c9 [9 q/ U
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 0 c$ R; d- Q% s% E
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    : ]* l8 g6 E- T6 g7 p4 q3 F) E
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    3 d% y( z% N# M. H0 t
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存$ F/ Q& Q+ v* }5 a- s- p
  27. APU_STATUS              =   $4015   ;声音通道切换4 H7 f$ c( T! s" ]/ P9 u6 t
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    6 @5 W8 o& E1 j5 c6 H7 r
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    0 Q  j" k$ q" x  f+ Y

  30. . n: `: \  Q! l- R3 m: u) j
  31. ;==================================================
    % c$ {9 }0 R* B
  32. ;MAPPER 19端口常量4 o3 v& o3 Q1 A' E( b+ U3 s
  33. M19_CHR_0000    =   $8000
    1 B( _, H! m& a/ A3 |& h" p' q* B
  34. M19_CHR_0400    =   $8800. B2 B' }; V! Y" Y  Q
  35. M19_CHR_0800    =   $9000" J' A6 Y2 `7 y
  36. M19_CHR_0C00    =   $9800- d% [$ X0 k7 K! O$ Z  X4 H
  37. M19_CHR_1000    =   $A000) \, [! X9 y/ b
  38. M19_CHR_1400    =   $A800
    ) ?; _5 _% a) e- y
  39. M19_CHR_1800    =   $B000
    + u: V# [( a* h" O+ y6 f4 y
  40. M19_CHR_1C00    =   $B800
    + L: V# c( P$ C% X3 v* A
  41. M19_NT_2000     =   $C000
    1 d  Y  A9 o9 e0 Y
  42. M19_NT_2400     =   $C800
    2 L. l, k8 k% x  U. e9 Z( T
  43. M19_NT_2800     =   $D0002 j& P+ ~! H" E# J
  44. M19_NT_2C00     =   $D800* a1 t! A3 o4 s0 R6 P  s% E
  45. M19_PRG_8000    =   $E000# U2 X) v, V# q
  46. M19_PRG_A000    =   $E800. B. d2 Z4 `% u* o% m) z% h
  47. M19_PRG_C000    =   $F000
    * H8 r# t  T+ ^" t1 o" j! s) M+ j$ a
  48. M19_IRQ_COUNT_L =   $5000) R- {- M& E* M2 r
  49. M19_IRQ_COUNT_H =   $5800
    ; w1 L' }- H) ~- b% r" G
  50. 9 p$ p& X$ P- ^/ }5 j2 e( D$ W2 `# V
  51. ;==================================================/ W0 s* }  v" a; k1 X
  52. ;程序块配置/ Y+ F% r7 _. P6 E& x* _
  53. BANK_DATA_MASK          = $07$ Z* e  X( T1 f: {) s1 N1 u
  54. ;--------------------------------------------------# I4 R% X" c& v2 e
  55. RESET_BANK              = $070 F8 l1 x- p3 {$ i
  56. RESET_ADDR              = $FC00
    " W5 C/ f: m5 ]4 J( N: `

  57. # S( H, D% `0 x0 P3 d
  58. ;==================================================
    , u+ X. }# s. a1 J& }$ g; G
  59. ;图像块配置
    ( p+ \5 ]9 b  p: J
  60. CHR_DATA_BANK           = $08
    & [7 n9 R7 W- \0 K

  61. , R: \' b0 C1 ]$ P  [! Q! R( \, N
  62. ;==================================================
    5 V; t  j) e+ ^# S* M, V/ O. [
  63. ;零页内存地址配置
    ' ?/ m) v! w! w5 k
  64. Use_Ram_Addr            = $80. A4 ?0 G1 q4 g; O) ^
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    % D, \! U' F1 T! N2 s+ c
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    ' d# V9 o+ d7 ~! d8 A7 G
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01) R1 _( m4 i4 w7 j0 `" z. a2 h
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    0 A* ?+ j* |: |4 P3 `
  69. FC_Data_L               = PPU_Scroll_V + $01
    3 i7 c' i* |2 l
  70. FC_Data_H               = FC_Data_L + $015 w: B9 A, n; E. q
  71. FC_Data_Buf             = FC_Data_H + $01% h0 D) l% B: D9 w* s' S0 ]
  72. ;==================================================
    / h0 o2 L# [2 _9 @3 I

  73. ( }8 w8 ]# C# |5 `$ L( i* L9 {
  74. GAMEPAD_MERGE_FLAG = $042 ]8 N& W0 a  b( R1 R

  75. 1 C& R) V2 |0 n5 c& X; k, E! {
  76. Gamepad_Keep            =       FC_Data_Buf + 1( W8 j1 z( y- L8 \4 w& f" R+ E9 l
  77. Gamepad_Once            =       Gamepad_Keep + 2
    $ u4 `2 p2 A! t  h6 Y$ t* ~% X  R
  78. Gamepad_Temp            =       Gamepad_Once + 2
    7 a' H- T1 F  m3 K2 R2 l
  79.                                 
    . w( W0 D% O( G* }
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    + T8 o, A6 F- F2 ~+ {, m5 a
  81. Gamepad_1_State         =       Gamepad_0_State + 1& N% q1 T2 E, v* D0 y+ ?0 M
  82. Gamepad_0_Value         =       Gamepad_1_State + 13 `, l, U1 }3 D) t# {, \
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    $ H4 Y+ H: `' ]& B
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    2 q) [* g: u2 Y! J1 _* X/ T
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1* k3 A- c% W: V+ z

  86. % I; ^* [6 r$ [+ Z% A, y* |" F
  87. ;==================================================
    . _9 O# j3 Z9 r/ {9 P& b1 @( r  k6 g
  88. IRQ_Index               =       Gamepad_Merge + $018 J% I' W6 ]; e9 y
  89. ;==================================================5 V' y4 M6 e* D6 w

  90.   L, i* [3 |' T& A
  91. ;CHR图形数据
    5 N, O7 x7 z- L- Y) v' B
  92. ;==================================================
    5 w2 a! z6 Q6 v5 _5 x
  93. .BANK CHR_DATA_BANK; a" {0 C7 I% _  S( I7 v
  94. .INCBIN "chr_bank/chr_data.chr"! d& T  M  e! Q- B  x4 o
  95. 2 T+ b: B  _! L; q7 R, O
  96. .BANK RESET_BANK & BANK_DATA_MASK4 U! Z& N+ q& h  |2 x
  97. .ORG RESET_ADDR
    2 V  i. E. m( o& x0 j! q+ E. [6 R

  98. . D& J6 S  d$ L* y* d
  99. ;--------------------------------------------------
    1 u8 m4 U+ D3 L* O
  100. Attributes_Data7 M! D+ E6 F% d& q' c, r
  101. ;命名表属性
    1 R9 R7 G- B5 R6 a0 V
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00* i6 s% F* d; n" [7 C
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA( B& [# F) ^7 l3 v) H
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    " x* J8 O- Y, ], w
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    ( V# z2 U/ m) t8 w. o2 i6 g  l  z% C
  106. ;--------------------------------------------------
    ! T7 r0 Z7 N! H; u8 j6 f
  107. ;调色板数据
    ' j4 _  r  L9 t9 `* ]' S
  108. Palette_Data- y5 w1 ]4 {6 G; Q% ~: I
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F6 R2 S; e2 F+ a2 W2 I" G$ I1 v
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F) v& o$ G" Y3 ]1 R: H5 m
  111. 2 |+ S+ `+ {+ \9 }1 ^! g3 G
  112. ;==================================================8 D! d( O, q. r- i( a
  113. ;命名表初始化
    9 b  C7 W: n" u; _3 N) y1 F' y/ U
  114. Init_Name_Table6 `* T6 ]0 i7 b# [2 O, q- i
  115. LDA #$20' z" K2 B9 E/ g, j6 r% T: n" a
  116. STA PPU_ADDRESS/ U1 d$ W, f( X1 Z, }
  117. LDA #$00
    / {: h: u2 C2 X  C  F3 [- e7 P
  118. STA PPU_ADDRESS
    / |9 u( O. p, U7 Y; u8 h; u& v
  119. LDA #$001 ?" @' V2 K- q! P$ w* X
  120. LDY #$00
    + d  c; T4 a7 s$ Z7 S9 m3 ?
  121. LDX #$100 B6 g& D7 _$ h' W+ a! @
  122. Init_Name_Table_Write" H. k2 M/ x& w/ Z
  123. STA PPU_DATA: i* b8 K8 I  ^- u) D
  124. INY/ k8 S' i! L0 Z% `
  125. BNE Init_Name_Table_Write
    # }5 q2 B0 I6 R8 A) R- {3 Z/ n
  126. DEX7 Y" A: h2 f2 k% \4 I( ~% k9 `4 H! c' x
  127. BNE Init_Name_Table_Write
    ( m3 s  K, z. b# C
  128. RTS  S7 X* k  K) q5 X" x
  129. 2 h) A8 \7 B2 m0 o0 O  y
  130. ;==================================================
    3 I0 n+ I  t# H% F5 B! |
  131. ;调色板初始化. ~) @" G6 [' B0 ^1 N5 M2 C9 r4 q
  132. Init_Palette8 @" W8 T; p! M* ]
  133. BIT PPU_STATUS
    5 c" U) R$ C# `/ f8 w; l
  134. LDA #$3F
    : W4 X% ?/ {# O  k1 A+ k6 K
  135. STA PPU_ADDRESS4 @& T8 [0 ]8 g5 G+ Y2 s9 R( u
  136. LDA #$00, m0 `; s' T6 }9 D
  137. STA PPU_ADDRESS
    1 X2 G2 ?' @; z
  138. LDX #$00
    ' Y- V0 U( w7 K
  139. Init_Palette_Write
    6 a7 Q; K- j) {3 j* \; w, L' d9 O  G, @
  140. LDA Palette_Data,X
    7 N' v$ w' v) t- }. K- O
  141. STA PPU_DATA2 w% V) p, r* ?7 ?# `
  142. INX
    0 w6 t" W+ v% j" Z
  143. CPX #$20
    7 {% V  t0 f. f6 p' Q( i* N
  144. BCC Init_Palette_Write
    / W& D( v/ V  F- W7 J4 T  h# D; [
  145. RTS
    % Z1 P" }0 Y; l2 L

  146. : O! k+ `% @5 Z
  147. ;==================================================  E3 e, u0 |* S- J) ^/ a) Q4 B4 o3 J
  148. ;设置命名表属性
      x3 W( `+ I: z9 }1 J0 |
  149. Init_NameTable_Attributes. E- E0 O4 X& ^9 R0 d  ]' O" V
  150. BIT PPU_STATUS
    " y; Q8 ]! W8 J; K: m; N$ Q
  151. LDA #$23
    # ?1 g% x3 }( Y* e. }. _. e
  152. STA PPU_ADDRESS
    # a4 T3 J5 |% j- c7 J9 [0 U
  153. LDA #$C0
    + }0 a+ y5 m5 K5 P+ c
  154. STA PPU_ADDRESS
    & v% t$ T4 H; }$ h- F
  155. LDX #$00: u: e4 R7 y# I% k  B4 n
  156. Init_NameTable_Attributes_Write9 S5 ]6 g$ i7 t% x; ~; P& ?  L
  157. LDA Attributes_Data,X
    ; K5 t$ v2 j' ?" b% B7 ?7 O
  158. STA PPU_DATA; ~- X5 a  `' g4 }
  159. INX
    8 F, U/ T$ x  w
  160. CPX #$403 P& o6 z. l& U& W
  161. BCC Init_NameTable_Attributes_Write# Q9 U+ a3 e) x/ v; \  v
  162. RTS- A0 s2 w, x1 V+ c+ g' w( o: D, ~

  163. $ z  y# e9 ^8 N' O# e
  164. ;==================================================+ b4 @9 s1 x& i2 a$ K$ U9 u
  165. ;初始化命名表文本' R; F4 E1 `, F' g3 I9 T5 B
  166. Init_Name_Table_Text, p# T) L& J2 ~3 N1 L2 u
  167. BIT PPU_STATUS
      H4 Y- [& {- n* u
  168. LDA #$20
    & J' ~" n+ Q- z8 `" C4 W" A
  169. STA PPU_ADDRESS1 E. [' u/ M! b* e( x2 I
  170. LDA #$00$ b- l( [0 r2 v
  171. STA PPU_ADDRESS, W# L: N, p9 F' a0 w: S
  172. LDA #$00
    " Z  b2 [/ r: A6 t& y7 C
  173. STA FC_Data_Buf* D% q& O, Y0 Z$ @2 e# g6 Z+ w
  174. LDY #306 @' a- @6 B8 L$ {
  175. Init_Name_Table_Text_Write
    $ s- i( k% |# H$ S' }
  176. LDX #32
    * {& {) o$ B! i3 x+ f
  177. Init_Name_Table_Text_Write_Char
    4 ?% r- i% B& L; l8 |$ d
  178. LDA #'0'
    % T4 @# [3 ^4 h; Z, ?
  179. CLC7 W1 B  u$ e) M; D  \8 Y
  180. ADC FC_Data_Buf
    . V' {$ H4 k3 x
  181. STA PPU_DATA9 d$ a$ N, i1 W
  182. DEX) W. O* \" J) [* b4 B, [  u. ]
  183. LDA #$14
    % r5 q- f0 N: }6 `& i
  184. STA PPU_DATA: I. I1 H1 n9 O8 p' J. A
  185. DEX
    8 _8 ~/ a7 r5 x* \9 `
  186. BNE Init_Name_Table_Text_Write_Char8 w8 ?- m' ?$ A# e- U: N2 K5 _# n
  187. INC FC_Data_Buf
    + _  v1 x# i# Q1 U% A) u5 l
  188. DEY
    0 V/ y! b, v* Z& q+ w/ i
  189. BNE Init_Name_Table_Text_Write
    1 m* _7 N" I9 i, V/ j8 D
  190. RTS% i: U) h, l% @: w8 Z( }* a

  191. * i- \2 h) a2 {0 R( o
  192. ;==============================+ ~. Q8 r7 y. n9 q
  193. Init_OAM_Ram;初始化精灵内存' \9 O6 T% H! @/ y4 P1 Z" @& D
  194. LDX #$00- P2 [' }' P3 x! g' j1 v
  195. LDA #$00% Q/ j$ k. H/ [" A# a/ w6 m: R7 ]
  196. STA PPU_OAM_ADDR. j7 u* J% o. C3 S2 l
  197. LDA #$F8& k1 Q" C5 e, y
  198. Init_OAM_Ram_Write
    " }$ z) R: V2 U( M8 W7 w7 x" r
  199. STA PPU_OAM_DATA, @) A) ^9 @( ~# |5 T
  200. INX" p2 f$ l; r. L  |
  201. BNE Init_OAM_Ram_Write
    9 z$ Q$ H7 M/ p% V9 D3 V& H1 I0 K6 ^
  202. RTS0 i) M! J3 g! v. [
  203. 5 k& L3 V9 d5 W9 R/ z
  204. GamepadProcess;手柄处理8 Z6 N$ {4 U  o1 l+ U/ H# l
  205. JSR GamepadDatacan) F5 h$ m) _  F7 f+ Y
  206. LDA <Gamepad_0_Value
    7 v( s- _$ a$ `7 P, Q- h
  207. STA <Gamepad_0_State3 ]% {( B, e) Q8 v
  208. LDA <Gamepad_1_Value1 c- I/ k- _" x4 f5 @8 ?
  209. STA <Gamepad_1_State
    $ J# T1 C' e0 H* C8 H9 B+ N+ u
  210. JSR GamepadDatacan6 @* C! X: g+ I  \
  211. LDX #$01
    $ d9 e2 t/ `* q
  212. GamepadMergeCheck;合并手柄输入检查! {0 W: O) L; n. y2 m" I2 @
  213. LDA <Gamepad_0_Value,X
    , ^$ ^1 U8 a# r0 M5 W9 p6 k! Z! s
  214. CMP <Gamepad_0_State,X
    8 g+ Y1 r" d; E" z9 r
  215. BEQ GamepadMergeInput$ c* t& e- U; V3 w
  216. LDA <Gamepad_Temp,X7 c& l7 S# U* ^  T
  217. STA <Gamepad_0_Value,X! Q/ J9 O, ~4 t  C* d
  218. GamepadMergeInput;合并手柄输入; p! u2 ^3 `. D& p+ d6 g6 B" H
  219. DEX
      U2 s2 P, `2 s* j
  220. BPL GamepadMergeCheck7 t  u  b' h: z5 W
  221. LDA <Gamepad_Merge
    0 `! ~! [2 k( j% K5 A
  222. AND #GAMEPAD_MERGE_FLAG
    1 ~* S* H& R7 _( R# y3 {1 _
  223. BNE GamepadStateProcess5 P" [" x9 u9 c3 Y
  224. LDA <Gamepad_0_Value" h8 A! A- V# ~' o: h8 B6 S
  225. ORA <Gamepad_1_Value
    ( T: l/ g) I% d7 O% X) u; X
  226. STA <Gamepad_0_Value
    & I0 b" K+ ~( ^/ ^$ a  a
  227. GamepadStateProcess;手柄状态处理
    ( o# b* I- ?5 f! P! `
  228. LDX #$01
    0 v( f; ]; S9 r
  229. GamepadStateSave;手柄状态保存( z' P* C) l2 |1 B
  230. LDA <Gamepad_0_Value,X
    8 q! ~: Z. ~6 {) J3 a2 z* K, W$ K
  231. TAY
    * k8 n. R# K" q# Y* c! ~1 x+ ^
  232. EOR <Gamepad_Temp,X
    + k0 `+ _$ j; D: ^5 h! K! P
  233. AND <Gamepad_0_Value,X
    * j4 D7 L5 _7 k% _; ^( J
  234. STA <Gamepad_Once,X- v0 C7 p4 y" ^7 c
  235. STY <Gamepad_Keep,X
    5 u0 `/ L8 I5 O- C
  236. STY <Gamepad_Temp,X; ^) H3 M# y; A! T! ~
  237. DEX
    ' j: M7 S( Y3 S- }
  238. BPL GamepadStateSave
    / D3 r+ u: v; p7 M2 S1 N
  239. RTS
    5 [  Z2 E3 h7 e3 _6 U) v# I7 D; A
  240. , ?- f. @( r4 @1 _- U; v5 L
  241. GamepadDatacan;手柄数据扫描- @, s) |; _, S/ e2 _
  242. LDX #$01/ b' {; _* b. _- e" k5 F
  243. STX $4016+ r5 V9 V: w+ M0 l8 B4 i
  244. DEX$ T0 x# H& X% R# v6 K! r0 X# x
  245. STX $4016
    % x" B  I  o6 P3 Q
  246. LDY #$08* x- |0 z% u& i, Z
  247. GamepadPortScan;手柄端口扫描" _3 H0 p: B9 V
  248. LDA $4016
    & _# N* y& C- p0 U7 e0 ]
  249. STA <Gamepad_Port_Value
    ) }5 ]0 N9 ]/ s0 Y% w1 F/ a
  250. LSR A
    5 I7 F3 Q0 Q% R0 k
  251. ORA <Gamepad_Port_Value
    9 H2 i" w8 X/ K/ W# r+ \& n8 x
  252. LSR A: F! C% M) A# k9 ~7 ^! j$ Y: A
  253. ROL <Gamepad_0_Value/ j. |8 ]* Y% P- {  y$ {/ e+ b
  254. LDA $4017$ g  e+ G. [8 {) n) J' H1 U
  255. STA <Gamepad_Port_Value! r( k+ X" R7 g. C
  256. LSR A
    8 v. k. u& M1 N, {. \7 e. V! @
  257. ORA <Gamepad_Port_Value
    $ ]9 I  l& C& f7 C) C
  258. LSR A
    ; v- b( E$ Y! |8 D; v
  259. ROL <Gamepad_1_Value( D! \/ j6 g: j* N
  260. DEY( ?" [! J$ O. R& O/ f
  261. BNE GamepadPortScan
      y. o6 h" p  U( g9 p
  262. RTS5 P/ N& H$ z" K% L( {
  263. 4 q2 A9 [: ]# x& Q
  264. ;==================================================
    0 h) T- s7 w. x2 y& }$ L) O. `
  265. ;PPU处理
    5 a, `* _' d, ^4 B& m8 A
  266. PPU_Process
    . g. W8 m0 P$ H( Z, d9 ~, a! m7 f
  267. LDA #$00
    ) y8 s0 o& V% c7 M+ y
  268. STA PPU_MASK
    & t, w# ~  z: \
  269. & ^8 s9 W1 [: ~
  270. BIT PPU_STATUS$ ~* ^8 u: T8 A
  271. LDA #$20% X: j! Q/ L6 e/ h8 r$ h* V
  272. STA PPU_ADDRESS, B( W, O6 G( v# ]$ p) f3 K0 \; k) }
  273. LDA #$00! C) b3 m* A5 J+ q7 w
  274. STA PPU_ADDRESS
    4 V4 ^% u. p- H6 O8 s. l4 t. s- u- q
  275. 0 K* I, T3 J' ]3 I& o& }
  276. STA PPU_SCROLL
    9 i, O7 d7 ]8 |3 {7 v
  277. STA PPU_SCROLL& v7 d8 y* _4 v& F8 H

  278. ! _3 D- K& u  {4 _+ g
  279. LDA PPU_Msak_Buf7 q: \' x- [; S4 D- b' `
  280. STA PPU_MASK/ S) o) A& W& l
  281.   y3 l% G0 Y# y0 C0 X# I% m& b
  282. RTS# O( Z5 l% I, N0 `2 z; i

  283. " Z+ B# o( {( m5 H8 {- W
  284. ;==============================
    * R  _+ x' [1 T: ^1 j, l! [
  285. Time_For_Vblank;延时等待
    # t( l9 }9 {; b
  286. LDA PPU_STATUS
    7 B1 Y8 ]" N- X! [- V
  287. BPL Time_For_Vblank
    8 V$ B9 i* ?  `. [& n# D3 ~0 g
  288. RTS1 S! }% Q+ _! i4 N  o
  289. 4 T% E! ]: M' ?# r& O1 q
  290. ;==============================3 Y* ~4 d1 {& i/ s
  291. ;初始化MAPPER199 s: ]: X2 q: B- q0 z
  292. Init_Mapper19
    . h0 p7 O# ?" a* }' e
  293. LDA #$00
    6 q5 C+ J% Q/ ~& T4 E6 U
  294. STA M19_CHR_0000, m8 K  {  ~/ r5 |
  295. LDA #$01
      i# K3 @% s* p9 m. o3 r" r# I! e
  296. STA M19_CHR_0400# X  b) V) e( R* Q
  297. LDA #$02+ l0 i4 u$ t- _' I
  298. STA M19_CHR_0800
    6 h2 U# _% q" m& U
  299. LDA #$037 {- f/ f. R* o& e
  300. STA M19_CHR_0C00
    9 G) `0 E0 E7 }$ h; I4 U' b6 t
  301. LDA #$04' {& m0 T0 l* V2 w
  302. STA M19_CHR_10008 e- {9 e7 k1 `- F, n1 y/ P: V
  303. LDA #$05! {1 J) N0 }) F' W( i
  304. STA M19_CHR_1400
    3 @$ v7 \4 W, {9 P
  305. LDA #$061 c/ \. B. L4 Y! o
  306. STA M19_CHR_1800
    / _' {, E& S& p# S- V
  307. LDA #$07# s: I& U0 l1 X
  308. STA M19_CHR_1C00
    3 @, u9 {3 S$ @: ?

  309. 5 ]" T6 V$ ^2 E" e5 A. h
  310. ;禁用IRQ7 _& g; M, [- }' d, k
  311. LDA M19_IRQ_COUNT_H
    3 T- f# D, A) y9 A% l% b$ m0 `
  312. AND #$7F3 m; a! K8 h  ~& x1 E
  313. STA M19_IRQ_COUNT_H( ]/ N; A- U0 C

  314. # i: k! J+ D+ b0 J) S( v# T+ S
  315. ;命名表* v8 Z! g! ~" e9 F9 x9 h& N
  316. LDA #$E0. C3 q- e) l, P" n" v& i# M
  317. STA M19_NT_2000! w) O1 r* z# M3 X
  318. STA M19_NT_2400
    ( p( k/ a# p$ [) d
  319. 5 A7 W# P! Z7 T. @; ~
  320. ;命名表& b" F& W' ~$ t' p
  321. LDA #$E1  Q- ^' G1 R: F0 H
  322. STA M19_NT_2800
    1 `+ }8 V  B" x+ |3 R1 t
  323. STA M19_NT_2C00
    $ Z( w+ p% H3 d6 m! K

  324. 4 \1 L  D! n$ ~3 h" p
  325. RTS
    - c) H# Q: v; @
  326. # H  t7 `! @" N
  327. ;==================================================
    ) F2 k- F" E8 V7 d! v+ T' u
  328. ;重置中断处理) `) G3 c" h! Z+ r. j; f7 Z1 b
  329. ResetProgram
    ( X1 p5 i  a) T+ y" |; P
  330. SEI
    ) [* u2 _; j2 I: V. m& {9 D
  331. CLD# F1 D, x$ A9 E( v  Z9 w1 K8 I
  332. LDA #$00: c2 Q& c4 C# Z
  333. STA PPU_CTRL
    / L2 s5 _  b. D0 q2 A
  334. STA PPU_MASK$ w% }0 j) f' m1 T( f3 n6 h$ o+ j
  335. STA PPU_STATUS
    ! O# n/ {8 N+ P; w8 W/ I
  336. STA JOY2_FRAME7 n8 [( C/ Q9 ~! C- I9 s
  337. STA APU_STATUS
    - O1 Q5 ^4 Y' I' C

  338. ) S. t1 c: Z! m, V0 _/ u' ^
  339. LDA #$C0
    " P6 @0 l! W5 R% l5 Q! D
  340. STA JOY2_FRAME. I. F! w8 e5 h! q5 F, ?; W

  341. 6 ]1 o  a8 L2 h7 k# }! `/ R8 o
  342. ;等待vblank" m5 o) i1 n3 Y
  343. LDX #$02+ Y7 e4 A2 I7 @2 x# @9 t
  344. Vblank_Wait_1
    + ?, O+ P; o" H' X+ A
  345. BIT PPU_STATUS
    6 i/ N3 b% Z) }# f
  346. BPL Vblank_Wait_1' E* m( g9 {2 L! v. Z' w6 z# X  j
  347. Vblank_Wait_2" X* I, U9 S" d; c9 d
  348. BIT PPU_STATUS
    " S) r! L$ n: x
  349. BMI Vblank_Wait_2( i* h! T9 R/ u6 y+ d* `, V+ D3 n1 s; P
  350. DEX6 w! d. e. d6 Z. K9 a& ]
  351. BNE Vblank_Wait_1
    + t; A, I2 E# \4 e8 Q

  352. : x& k# d: J" e) \6 ^" M8 E
  353. LDX #$FF! s6 f! Y* Z8 q+ e6 c6 S# C
  354. TXS5 t% b; l( J/ O
  355. 3 R( D4 E4 p. `. r( r- S- b" U
  356. ;初始化MAPPER19
    + T8 h, C2 r3 e$ a
  357. JSR Init_Mapper198 M: Z- ~5 e) {; j% c' I

  358.   c9 W5 _; }% f
  359. ;==============================6 @# G% S, f3 m7 ~5 b& m6 l* W
  360. ;RAM初始化
    ) {  q% J2 J: `, s6 {" y
  361. Nes_Ram_Init8 J3 U- l8 w4 r4 N3 |4 ^
  362. LDY #$00- H& R0 V- B# k( T% a
  363. LDX #$08: i, _& n! \$ i# w9 V
  364. LDA #$00
    1 f4 `/ x9 @6 O  U7 h7 f1 n
  365. STA <$008 b, ^& v; o+ I/ {  W
  366. STA <$01
      V( m3 p$ l: P& g7 G
  367. Nes_Ram_Init_Write
    8 p: _& l' z5 W7 ]
  368. STA [$00],Y# [7 i  t9 ?2 t
  369. INY( }& g- \2 ~3 R/ d- J$ K
  370. BNE Nes_Ram_Init_Write7 D' C) x9 e" `' b. \9 f9 p
  371. INC <$01
    * t$ g) ]+ W: S. J
  372. DEX
    6 _; w3 f3 \( Y- a) l9 X
  373. BNE Nes_Ram_Init_Write; D$ G3 o3 ?( V; {  X! r9 E7 O

  374. 5 F. ?9 x6 S# C/ _
  375. ;初始化命名表
    - q1 L6 z8 d7 y1 E/ \
  376. JSR Init_Name_Table0 ~+ a# b% H* _( N5 Y

  377. & R/ }$ v* u" k
  378. ;初始化调色板( d' {. a0 V- {
  379. JSR Init_Palette& @" ?4 B2 @% F7 M+ B9 I
  380. * T; U+ n7 c0 h6 n7 @# k5 K. g
  381. ;初始化命名表属性/ t- p- O' k6 v% c& n% S0 [. t2 m
  382. JSR Init_NameTable_Attributes
    , O$ ^+ ?! W8 B  T8 T
  383. 1 M$ x1 n6 [7 h( _) `
  384. ;初始化精灵内存
    ( S7 J) ^* A+ d( [+ ^
  385. JSR Init_OAM_Ram
    " y+ D* k! K/ F5 u: Z
  386. 0 W# \8 \! K7 C# N* r
  387. ;在屏幕上写点东西
    0 a# S5 M; s+ ^5 M" C6 o2 x$ T& X
  388. JSR Init_Name_Table_Text4 m2 F% c. n8 ^) I% Z, o+ S
  389. % Q, C$ A: ~; H9 Y4 Q& e
  390. JSR Time_For_Vblank
    ' z# m8 T  i  G' G" c
  391. ;开启PPU控制
    * t' z/ D# L, o! ]  T: h) C& q4 K$ [
  392. LDA #$A8
    ! B% N& v$ W2 }9 a. I0 m, m( [
  393. STA PPU_Ctrl_Buf2 v4 d3 f$ ^6 _& u8 F  d
  394. STA PPU_CTRL* s0 g/ e/ p2 |9 ?# n, `% \$ v4 F- [
  395. - v( p4 R% }3 L
  396. ;开启PPU显示7 r: e1 `. Z$ W/ U7 g
  397. LDA #$1E
    ' y9 v+ a- ?  A: P
  398. STA PPU_Msak_Buf
    ) F* ~1 S" d5 s: y
  399. 5 H. Z4 \; |. y( {. `0 O
  400. CLI
    + f7 l% o8 {  w* B, [% J
  401. JMP Loop% p; F! w0 R$ i8 o/ z5 u

  402. ( y; a" t9 k) w! T5 h: h& D* v8 v
  403. ;==============================
    ( k( u, _; ?! H; |
  404. ;死循环, 等待NMI中断
    3 Y, u% T! i) J( B; S1 j& z. H
  405. Loop
      R5 D( }, E3 e1 s/ m
  406. JMP Loop
    - \. h& `* z% B0 `3 o' D' x' F6 _: }

  407. 0 M3 N. {2 E. R2 s6 V" {
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    + K, q1 x" x/ h, @, C  T
  409. 3 J0 |4 x8 y: j4 X! c2 u9 u
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)0 G6 i6 E: ^0 _) @
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)" q% i  O/ G. D. j& B2 [
  412. ;==================================================
    3 K7 B  S/ ?8 C# u% s9 R
  413. ;NMI中断处理  e3 c! N) {; }3 c( I
  414. NmiProgram
    ' s8 B; K& L" z
  415. PHA
    - a, F& v! e, o" p6 U1 `# J
  416. TXA
    8 z( Z5 L: h  g% d( c
  417. PHA8 c5 r7 p4 W3 C3 Z+ E
  418. TYA
    , F; k% F6 v" E4 R) Q
  419. PHA
    4 M8 ^8 d# ~) g$ S2 Y2 F4 g

  420. 0 }3 g( n0 P% P7 P" D
  421. BIT PPU_STATUS+ ?" O' m! u* i) @
  422. ; d) f0 W5 l4 C6 d, i6 A
  423. LDA #$005 C6 c- s% S6 s
  424. STA IRQ_Index
    + _; o0 \: h2 \# B, M3 e

  425.   ~) q2 |& l! @) `) d
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动- E. d( k  u0 o3 O9 C/ j4 K
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    2 ]  I* L1 ^8 j0 [0 D9 y
  428. STA M19_IRQ_COUNT_L' e# Z3 Q2 h9 r2 `
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    1 B- I! V$ @7 s5 q3 E: k
  430. ORA #$808 k5 R; @# q) K# T/ ~
  431. STA M19_IRQ_COUNT_H
      V, J- |" q1 j  x
  432. CLI
    / f' ^0 @: ~8 A* t+ v

  433. - M. m, }8 G4 I
  434. ;关闭PPU控制( o" d7 Q. `. ]$ r1 S" s
  435. LDA #$00% ~. W8 m" p) S
  436. STA PPU_CTRL
    6 G; t  u% Z/ l  x
  437. , ]9 X, t& w5 M5 U
  438. ;处理PPU
    & Q4 X, I; y% e1 \2 Z; v: s
  439. JSR PPU_Process) t# \' c4 @# g

  440. * }! V: a8 ?7 c8 X
  441. ;开启PPU控制, V( E, S- S, H' X! \! u
  442. LDA PPU_Ctrl_Buf
    + ?" t( K* `' A$ p* C. Y2 N
  443. STA PPU_CTRL& r' ^4 u+ W( j+ r- Y" \

  444. / r5 d5 _% [- F. G: H5 [  S
  445. ;手柄处理
    2 Q. e2 {- T- }# m
  446. JSR GamepadProcess& ^) Q& B. [+ D( @' Y1 {- H  C
  447.   L1 @7 K, j( ~& B4 b3 }
  448. LDA #$007 @' H, \% P! x8 ?; i' A
  449. STA IRQ_Index
    , p* C8 a4 w9 ]

  450. 6 P; R; e* c! ?- h
  451. PLA, x: x# k" q/ }% Y4 u! C
  452. TAY0 O$ F) E/ J* E  Y+ l( l7 l+ f7 x4 ?
  453. PLA& Q4 T+ Y2 x8 y$ r  h) A5 B
  454. TAX/ k. ~8 Q' ]5 Y/ z
  455. PLA
    : N7 ~% E# Z3 _3 i4 M6 }$ k
  456. RTI% A4 y( U3 s  j3 \- E
  457. # j: O0 d# `. l' A' l) I6 @: L4 q
  458. ;每行扫描线113.67
    6 D5 c) L2 ~0 j4 m! r  q
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    / M" g1 A, l; g) A3 S) \8 O  b
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    6 E/ U- K7 P( a% O) B' h; J( I! z% p
  461. ;==================================================, G% j* l3 q+ U$ n8 @; r' X
  462. ;IRQ中断处理
    : o- E7 d/ n& w3 }! b& H+ H, }
  463. IrqProgram( ^9 |) k! s, |% N( S0 K
  464. PHA
    8 D/ s" F; X2 O5 [- S& A1 N
  465. TXA  l2 ?9 K* ]3 C, N) E4 H
  466. PHA
    ' ]) M: s8 l) x* C1 l
  467. TYA: V4 F6 u& ?. v9 `
  468. PHA9 a/ N% O, N' i2 D) y4 [4 ?4 }6 l" B- t4 g
  469. - [$ u, W9 t0 V# N* l
  470. ;16条扫描线后触发IRQ7 d; i$ e) M1 C- {' I
  471. LDA #LOW(BEGIN_LINE_CYCLES)7 V, G, M/ i3 J! b2 x
  472. STA M19_IRQ_COUNT_L# L( b- E$ ~2 l% F0 ~
  473. LDA #HIGH(BEGIN_LINE_CYCLES)# Q' P8 B; R- W
  474. ORA #$80
    $ t8 w) j# b: i' q3 b
  475. STA M19_IRQ_COUNT_H
    0 @: ]% A- p' v7 E

  476. 9 D. S6 J: J( i1 i$ M
  477. LDA <IRQ_Index! I2 p% X+ N' s1 A
  478. BNE * + 46 {' Z* V% _0 q9 l  [
  479. INC <PPU_Scroll_H
    . o+ `- h& T1 x) g# d0 A0 ]

  480. & p6 ^6 J2 u2 A7 l7 @1 S
  481. ;设置屏幕滚动# |# B. K( H1 b& H9 U
  482. LDA <IRQ_Index
    - T3 s# z* [  G- _4 t4 y
  483. AND #$01
    ( o1 [+ U% ^; l) b7 t5 V
  484. BEQ Irq_Scroll_Right" ~) e* F6 A8 D/ M0 t0 R4 p
  485. ' [5 [4 c' g, [6 F0 ]$ s9 q
  486. Irq_Scroll_Left/ y  ~- ?! p# H  T2 l5 k, G5 Z0 p
  487. BIT PPU_STATUS
    " L2 u+ B  {" P" N7 F
  488. LDA <PPU_Scroll_H. ?3 \: X: p: c& B/ L* P
  489. STA PPU_SCROLL. S% p( n" ~* t+ l6 ~; b' B
  490. STA PPU_SCROLL5 e5 I* Q4 M1 |7 k; l# K
  491. JMP Irq_Scroll_Over$ i6 z% S( k, y2 z( w" c9 b0 t
  492. 7 i5 Y+ N9 R% r5 f
  493. Irq_Scroll_Right
    # X7 C# E' b! N" O0 j
  494. SEC
    5 d- V8 Y* v! Y* d1 Q* y
  495. SBC <PPU_Scroll_H3 z. t- P( X. W, q' N
  496. STA PPU_SCROLL
    7 V) H$ [. @3 T
  497. STA PPU_SCROLL1 e% m5 Y: w6 T6 w$ \3 L
  498. Irq_Scroll_Over5 l7 G" A# z: v: x
  499. , b; U/ w( w2 u3 ?1 W: A
  500. INC <IRQ_Index
    5 [$ f$ d$ M% @: V2 A$ a

  501. % u6 D/ n, T& Z# K" r& ?
  502. LDA <IRQ_Index/ y" u& X, \8 z( y2 Z/ u; k& @
  503. CMP #14
    ) B0 n6 r  I& \
  504. BCC * + 10$ ^5 I' F: Y! G: B4 S* y
  505. LDA #$00$ u4 L; B) H8 o7 v$ I) O/ @5 L
  506. STA M19_IRQ_COUNT_L' p5 j2 z7 ?* l+ I7 R3 C
  507. STA M19_IRQ_COUNT_H
    1 y( r3 r$ o6 N3 T4 @" o

  508. ( z) h- E: ~5 d- x
  509. IrqProgramEnd
      H. B, ^7 L* c7 t
  510. PLA. a8 f& i( j) J- a( Q
  511. TAY  k1 u* S) B4 x2 W6 {# P
  512. PLA# |5 m3 I3 V1 D# b% I$ f* {
  513. TAX/ P4 l; G3 R" `. a
  514. PLA
    * U3 N) L/ v' H5 T9 Q6 g
  515. RTI
    8 W: |; S4 o$ E8 D3 {1 |( Q0 `$ @

  516. 3 k; B" O2 l# y6 Q  A
  517. ;==================================================! ^  @/ {; v; E1 d5 O6 U
  518. ;中断表' @/ d& T3 `4 S
  519. .ORG $FFFA
    0 O. [% O) S( F9 j4 ^- f
  520. .WORD NmiProgram
    7 N- w6 i) x6 w  y! R) @$ j
  521. .WORD ResetProgram+ v6 \$ X* _$ g* ?
  522. .WORD IrqProgram
复制代码
- O  Z3 q3 X; A% `* f" r. s4 o, o

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-11-18 16:54 , Processed in 1.060547 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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