EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    " Y! P6 C) @6 m/ O
  2. ;FlameCyclone 20230710% t+ k0 G. Q; m  ~! {2 Z
  3. 6 q/ l0 w( g6 ]6 ?
  4. ;文件头
    1 F/ A# b) S  a* U
  5. ;======================================================================9 W7 b% V% Z6 y; ?5 r* h- |
  6. .INESPRG 4                                              ;16KB PRG 数量
    ) ^  b6 m. z& I
  7. .INESCHR 1                                               ;8KB CHR 数量  y, `% p( W' u% v8 j' r
  8. .INESMAP 19                                                 ;mapper 19
    + L7 Z! z+ Y) m3 k; j) }
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    ( i& w7 I, b2 V, ]/ y7 L
  10. : Q( `% V8 Z  U0 f+ G; G
  11. ;必要条件- X* U' h! K  W% j4 D; d( b; b
  12. ;1.持有CHR ROM- x; P4 e2 d7 g( V1 `
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000. K' u3 l, e/ l7 m( p/ m7 E4 @
  14. ;3.精灵内存(OAM)不为空  I1 i: P7 l3 Q9 k& g9 c. S

  15. 3 R/ f7 b0 r% [* ?; t) y
  16. ;==================================================
    ) W' T, n: u8 _$ [7 l* ?% [/ J0 ]
  17. ;NES端口常量! G. l% w# C( R- b4 o  [
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器! L& \. V# u7 N9 J& |8 W* U' s: Q% Z
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    # m) q/ \# h/ m# O7 d& ?
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    / n( x% X1 T- m) J3 ~* ~3 A" d
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    : h2 {7 l! B; L/ T
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1% T3 c' s* o7 ~2 s1 R
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    - d& _; j9 G. v
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加, L4 g3 J/ a' L  N( t* p
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    4 a- P' G% w3 K$ j: l/ m; ?5 v; G
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存, v" R) P- Y* P7 b
  27. APU_STATUS              =   $4015   ;声音通道切换
    , g4 i7 d" c2 u% ]; J; g5 o
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通8 K% D# e% u9 {* {8 x  z- p* e
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    " h7 Q9 v# e% q( p8 G
  30.   d% ~; `7 Q. G/ g5 r* f6 v  O
  31. ;==================================================
    % `5 u* X0 x6 X- T0 z5 ?5 s
  32. ;MAPPER 19端口常量' e9 j7 q5 ~" F" `
  33. M19_CHR_0000    =   $8000: E9 K0 o7 K; J* z
  34. M19_CHR_0400    =   $8800
    * X6 ]  J% D: i7 `# }1 Y9 W( {
  35. M19_CHR_0800    =   $9000  [* w0 O9 g) {* s* \+ u" m
  36. M19_CHR_0C00    =   $9800( ^3 F  i: a+ F& ]3 L' Y. C
  37. M19_CHR_1000    =   $A000. Z  r3 g2 L- Z5 B" Y+ q) r
  38. M19_CHR_1400    =   $A800
    / ?5 O  Z8 ~3 O) F3 t
  39. M19_CHR_1800    =   $B000
    / v- f5 h9 z8 K1 H1 w: {
  40. M19_CHR_1C00    =   $B800. \% o7 N, s6 A
  41. M19_NT_2000     =   $C0005 k+ i' T6 B0 b  o' l8 j2 `- I
  42. M19_NT_2400     =   $C800+ h5 c3 G6 B$ s
  43. M19_NT_2800     =   $D000: O2 ~& t6 h- A- R, O1 a
  44. M19_NT_2C00     =   $D800
    . s: G8 X' [$ f1 e' w
  45. M19_PRG_8000    =   $E000* X# B8 N$ m% f5 ^
  46. M19_PRG_A000    =   $E800) |9 H. O8 c5 d0 t3 j' T0 w
  47. M19_PRG_C000    =   $F000
    - _5 p. _( `, H. T, e. P
  48. M19_IRQ_COUNT_L =   $5000( s; P$ N+ @) }3 T5 E2 ]4 v
  49. M19_IRQ_COUNT_H =   $5800
    8 P: [+ j  P& P$ L( H
  50. - L- n. N9 B9 M# [* i5 C( W
  51. ;==================================================
    ! X# K. U9 C7 R: r" e
  52. ;程序块配置
    3 U2 Q$ S2 a# v$ B( C" s: r
  53. BANK_DATA_MASK          = $07
    4 l/ H& m" g2 C9 s' r, ]
  54. ;--------------------------------------------------$ C: j2 |7 y# S4 L
  55. RESET_BANK              = $07
    + j* G- Z0 X- j- {* i) {
  56. RESET_ADDR              = $FC00
    5 t2 ~  k+ z8 o3 }. O' i, J% J

  57. + g3 s! s8 @! q
  58. ;==================================================
    : D1 x* j! @. z! G1 d8 k. I
  59. ;图像块配置# M5 D2 r3 A5 U7 {4 h$ C
  60. CHR_DATA_BANK           = $08
    % v- S  }7 u% S* t
  61. " d4 Z7 i; }" e; n' E
  62. ;==================================================/ g5 g+ N& C) u) m; j# I
  63. ;零页内存地址配置- u% y: n6 w. q
  64. Use_Ram_Addr            = $80& u$ t# N' t* k0 i* h8 Z: x0 H
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    + d3 m, \% l/ s+ T: ~
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01( f' I3 r# }4 k: L/ ^3 t/ V- n
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    " L# d. a; y# v- G) k4 ?( R1 i5 ?9 |
  68. PPU_Scroll_V            = PPU_Scroll_H + $012 B5 P9 C7 k& s2 E+ ^" P
  69. FC_Data_L               = PPU_Scroll_V + $01
    " ?5 G$ r( F+ @" b
  70. FC_Data_H               = FC_Data_L + $01( x$ y) u/ _, `1 s
  71. FC_Data_Buf             = FC_Data_H + $01
    % v1 p' |& |6 m7 m: M( b. w
  72. ;==================================================; n# M8 g3 E! \3 S0 Y5 S" e/ v; D
  73. ! T, J) F5 c5 Q6 N1 v
  74. GAMEPAD_MERGE_FLAG = $04
      L2 ~5 S6 _# @4 W( s5 J% Y. d% T+ X

  75. . x! G% Y/ c4 h: c6 {5 A
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    & U- @. g8 ~8 z. z
  77. Gamepad_Once            =       Gamepad_Keep + 2+ g( b0 q( J+ v/ p8 P$ e
  78. Gamepad_Temp            =       Gamepad_Once + 24 c1 q- O% z( c
  79.                                 & W& a# m7 V' A" }5 p0 X' @' M
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    % S- {+ A6 h/ m# R) ?. ^
  81. Gamepad_1_State         =       Gamepad_0_State + 1) m+ j: R7 N% J) H9 A
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    * X& z3 {  r+ ]( o
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    5 u/ a5 M. k% M8 N9 }& H( N0 b  P
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
      e: |( n% F; Q  K9 K9 S# s( Q
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    : u, B, I4 T9 Y9 x3 I

  86. $ Y! G! U" _$ C: Z6 m# }# j
  87. ;==================================================, m; F7 U5 x9 v
  88. IRQ_Index               =       Gamepad_Merge + $01
    + d+ q1 F* V: ^7 u6 R3 H0 |
  89. ;==================================================1 a) ^& M% V( y3 H, X! }
  90. 9 ^( A( d2 j2 b) O& t$ i/ ]
  91. ;CHR图形数据
    ; E+ e4 e9 H  Z" U/ }0 a0 ~
  92. ;==================================================- @# e8 u5 N% G6 F7 J" S
  93. .BANK CHR_DATA_BANK
    ; W) x1 Q* e( h/ h/ o
  94. .INCBIN "chr_bank/chr_data.chr", r6 `& }' e, e5 ?0 Q! ]+ m
  95. , L  m4 u0 u+ }  [- a5 X
  96. .BANK RESET_BANK & BANK_DATA_MASK
    * E9 d/ r) g0 W& p7 D7 [3 L
  97. .ORG RESET_ADDR
    6 o* L  A/ E7 m$ R" `$ ~  y
  98. ) g- y( U+ ?- k3 l& {# u4 Q- F
  99. ;--------------------------------------------------( l6 ^0 C2 [3 v  d- f
  100. Attributes_Data
    5 M) A9 f6 Y; Q6 x/ r# N; Z, D
  101. ;命名表属性3 u% n7 H! p6 h+ e
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      {, t. }. D- w) u
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA* P$ m2 N* x, i2 j9 r2 j
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    . h, q5 b! ]1 T  F9 i3 G( ]. N/ L
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    : T. o! U& ~% D( U; H1 T. I
  106. ;--------------------------------------------------) S+ O  `0 X$ q
  107. ;调色板数据( |% f# U0 R: @5 W/ w- y  g% R
  108. Palette_Data
    2 X- r" r& U7 I' p+ ~
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F  p, }% S# V  k, N7 q2 W8 y
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F. K& g7 [3 X+ \
  111. 5 R& z! w" k4 @) ?8 Q
  112. ;==================================================# d, K' }: ^$ K) Z
  113. ;命名表初始化
    / y, n2 S: n( t& h9 k9 Z9 {) }
  114. Init_Name_Table
    ) i8 N! j. f( H3 a! i2 t( e% A) M- f
  115. LDA #$20
    " L  G4 A; A* E9 @+ I  v9 z
  116. STA PPU_ADDRESS+ G9 s* T8 J. Z: |- ^$ {) o
  117. LDA #$00
    0 g, o! ?+ Y, u3 _& v1 b
  118. STA PPU_ADDRESS' }5 s9 }% a3 b
  119. LDA #$00
    7 v  o& v4 K' ?2 L
  120. LDY #$00
    8 z, r9 ~, ]' z' c
  121. LDX #$105 _: G. u& s) o9 o
  122. Init_Name_Table_Write& a/ t* ^* g) w! B2 p5 R  X( v
  123. STA PPU_DATA
    * [- K; J. _3 [! z; W
  124. INY
    0 ]' j# t! S4 u. y6 v! `' k
  125. BNE Init_Name_Table_Write
    ; `, j8 m# h! x5 D% I; c% w
  126. DEX! c+ q. Q  v* _# I  D
  127. BNE Init_Name_Table_Write& @' R: N1 Q. j
  128. RTS
    / G! @/ b0 }  c4 ?6 k
  129. 9 G& ?1 G' Z8 H
  130. ;==================================================
    - u/ p. W8 O! |  ?- @* U0 v+ v
  131. ;调色板初始化
    ) l  R# p9 n/ z. W+ x6 p3 \
  132. Init_Palette
    . v3 B" }; Q/ a. }
  133. BIT PPU_STATUS8 F4 [5 r6 n3 v2 p
  134. LDA #$3F  k$ Z( a# Z+ E+ P  R! p& b
  135. STA PPU_ADDRESS
    , a  N  u; a& H) S6 U& e
  136. LDA #$00( h1 `: n. T+ I: J- l2 |1 j2 }" f
  137. STA PPU_ADDRESS0 _3 J8 x& ]  C
  138. LDX #$00
    + K  Z. ?8 M$ O' b0 Q( x( n' C& l
  139. Init_Palette_Write
    * s* O: J0 }( C( n4 a) ]+ w
  140. LDA Palette_Data,X  H2 \' m4 m( w1 X$ Z
  141. STA PPU_DATA. }, B2 Y; T- m- D) I+ {
  142. INX' [0 k% d7 z/ N6 Q1 J. d2 q% f0 ?
  143. CPX #$20
    ! z0 Y+ a: k# Y8 Q7 g6 F
  144. BCC Init_Palette_Write
    7 O8 z6 y4 F0 P4 [
  145. RTS
    1 q2 |& Y1 d9 [% t1 m: o* \

  146. 0 I6 a" Y: U; E( R' M
  147. ;==================================================
    - S5 K  U: E# Q
  148. ;设置命名表属性: q, G* U$ ?+ y8 R( _
  149. Init_NameTable_Attributes
    5 e2 U, ]9 Y2 F% L6 F; H# V
  150. BIT PPU_STATUS
    ( E$ \1 A8 @" O1 K1 V
  151. LDA #$23* c- y$ M, L3 V1 Z2 F8 p
  152. STA PPU_ADDRESS
    ( [  i6 @, p! m' K7 e
  153. LDA #$C0
      T% T5 u0 ?& d' n  M7 [4 M% J
  154. STA PPU_ADDRESS! p7 R$ i2 n2 l' q7 s
  155. LDX #$000 q2 G  |, h* A- h5 d' d7 ^
  156. Init_NameTable_Attributes_Write
    % L" G0 A  p% V. ~9 P
  157. LDA Attributes_Data,X% x- j- u- f" @1 z
  158. STA PPU_DATA
    & c- [% a# E4 z7 `+ H
  159. INX; b6 t) F/ m" X0 v
  160. CPX #$404 Q, X# A( z- o+ ]+ M* B3 I
  161. BCC Init_NameTable_Attributes_Write, Z( D* x+ v$ N
  162. RTS' F  `& b( @! l( s' C! [  f7 F
  163. ! a1 {! q% H6 Q+ r
  164. ;==================================================; i2 A4 Q* M5 C5 T1 S" m. _
  165. ;初始化命名表文本
    ( n, J) N9 u6 {) ^' Y+ ]# C; L
  166. Init_Name_Table_Text( x; E+ w* b6 ~  A
  167. BIT PPU_STATUS3 k5 p4 A; x" j9 _* ]/ O3 Q
  168. LDA #$20
    , I3 I3 l4 |- ~0 a1 |) ]4 H# [3 Y0 X
  169. STA PPU_ADDRESS+ K, n. s/ a( @) }% o
  170. LDA #$003 K- V5 D" f; N8 M/ Z7 j/ ?# q: `6 }' d
  171. STA PPU_ADDRESS
    % D$ u2 v+ u5 z9 _( y
  172. LDA #$005 F! d, N' R% f- q$ ^
  173. STA FC_Data_Buf
    4 C; F0 O1 @9 ^
  174. LDY #30
    0 i% v( B1 t, d: m7 f3 |5 r
  175. Init_Name_Table_Text_Write
    ) S% ]; R: m* E+ h$ {
  176. LDX #32. ?7 e! m9 u0 k8 [/ d
  177. Init_Name_Table_Text_Write_Char* E4 _. v) Q4 E" J: I* H3 {, ~
  178. LDA #'0'
    1 l( r# O: \: w
  179. CLC
    / w3 r" N4 T+ l5 Q3 f% V8 ^
  180. ADC FC_Data_Buf. F4 E- l* U2 O2 j
  181. STA PPU_DATA
    % |3 _) u2 k. O9 x0 G5 y7 P8 A
  182. DEX5 x: v( M' }* H: Z6 G8 p" a
  183. LDA #$14, z, n0 V5 y% V3 v
  184. STA PPU_DATA0 I5 ]5 w. v' j# N6 z/ L
  185. DEX
    + m# ?; h) u* e/ S0 d" Y' N
  186. BNE Init_Name_Table_Text_Write_Char
    ( E2 a7 S  h2 f* o7 @
  187. INC FC_Data_Buf
      P2 e/ S% y" V: F; t8 |% [" Z
  188. DEY+ T  j" n# ]# R: v) Z9 ~" V# H
  189. BNE Init_Name_Table_Text_Write" R2 h0 q8 j9 H1 |- M0 l
  190. RTS- @( ^5 w; b# _6 F
  191. , ]: x4 }0 a; W4 x' S% M
  192. ;==============================
    ( `/ {$ c( @0 @( f
  193. Init_OAM_Ram;初始化精灵内存
    # o9 ~* c8 ~  j, G% P. E: r
  194. LDX #$00
    ( f/ G0 B: j4 S4 y
  195. LDA #$00# h4 p! K- m; H9 y' ^
  196. STA PPU_OAM_ADDR
    1 s3 K7 E& H& T; c  Q- [5 U; `; _
  197. LDA #$F80 @! |7 H4 b1 p
  198. Init_OAM_Ram_Write- Z; V% m# B9 }( G, b
  199. STA PPU_OAM_DATA
    # z7 G) I+ L6 l6 T% `
  200. INX; s* s7 I( }" O
  201. BNE Init_OAM_Ram_Write
    9 q" j; ?3 N7 @# ^( ~' y) G. G8 I
  202. RTS1 u5 ?8 U# j' z% E+ h
  203. * I5 Y/ E' S& Z3 s# Y  Z. p' s* A
  204. GamepadProcess;手柄处理* l# `. {. E3 d3 v4 L. x
  205. JSR GamepadDatacan
    % a' ]: U0 G4 T  \2 g
  206. LDA <Gamepad_0_Value7 C/ O% e5 D& C1 C6 H1 o+ f& S7 _
  207. STA <Gamepad_0_State
    # I# }$ o' u; P
  208. LDA <Gamepad_1_Value% k" \* v6 M  e4 D; N3 A
  209. STA <Gamepad_1_State' Z" U8 r! @1 M9 ~: _
  210. JSR GamepadDatacan
    2 v" x% A3 p  S: Q
  211. LDX #$01# e# X8 K; a( J7 ^: d) R# R
  212. GamepadMergeCheck;合并手柄输入检查
    1 P8 w! O7 L) Q- o
  213. LDA <Gamepad_0_Value,X
    1 i5 M* p; t. v! r, ], {# N
  214. CMP <Gamepad_0_State,X
    - p5 K* }, m! m$ f) F5 M& j
  215. BEQ GamepadMergeInput9 E. K& U% t" E/ m
  216. LDA <Gamepad_Temp,X) M/ |1 n* ^( R5 @6 I8 c% v
  217. STA <Gamepad_0_Value,X
    # B9 h0 g4 l4 ~2 V8 ]+ O
  218. GamepadMergeInput;合并手柄输入
    5 ^6 n! b% d) u
  219. DEX% T+ Y5 M2 p4 d$ e* j7 z
  220. BPL GamepadMergeCheck
    ; F# r6 P* Y7 B- m8 Q
  221. LDA <Gamepad_Merge
    + g' A  S- Z& s" U8 R9 u, B
  222. AND #GAMEPAD_MERGE_FLAG
    : y: k$ ?+ s, ]% ^8 h+ ]3 L2 x
  223. BNE GamepadStateProcess: k$ c  E# E) x0 e6 w, q
  224. LDA <Gamepad_0_Value
    0 b6 N! g' f; [- p2 J
  225. ORA <Gamepad_1_Value0 e0 r# ?" _2 \' a1 d4 @$ r+ ~2 A
  226. STA <Gamepad_0_Value
    5 \" b% `$ P6 [4 D$ h3 a5 `
  227. GamepadStateProcess;手柄状态处理
    3 Q4 v  f& I" y' s
  228. LDX #$01
    " F4 B8 Y  D8 [. Z3 a/ E" n  Z& }
  229. GamepadStateSave;手柄状态保存, n! d- C3 Q6 W4 F5 T" o
  230. LDA <Gamepad_0_Value,X, @" a) k/ k5 [; O- u
  231. TAY+ V) [1 Z0 R* u6 D0 Q. ]
  232. EOR <Gamepad_Temp,X; c% \  |/ d5 D7 n( }) W
  233. AND <Gamepad_0_Value,X
    + H% O" }! V9 R( J! p: D
  234. STA <Gamepad_Once,X! @5 A: B" T$ Z0 I; A2 S
  235. STY <Gamepad_Keep,X
    ; S! Z/ T4 E. w0 C! p2 N
  236. STY <Gamepad_Temp,X' T: O* b% W/ p; e# n9 T2 q# W
  237. DEX9 P% _, L2 q1 H0 d
  238. BPL GamepadStateSave
    " @( g4 z7 n+ i# }2 K/ m, T+ |
  239. RTS
    ; a% w0 Q$ b# t: H9 Q
  240. 4 O+ I$ h2 k5 s  M* R/ i2 w
  241. GamepadDatacan;手柄数据扫描
    9 z, a" E$ K: I) Z( Q9 m/ @! t
  242. LDX #$01
    2 E. X( ]9 h6 l0 v5 J" r
  243. STX $4016" V) D* T: u5 h8 w
  244. DEX6 O& F  q9 @- T5 e' C
  245. STX $4016- E1 C0 C9 n# q) Z' Z+ ?' V
  246. LDY #$08
    & J* X' F5 u0 D5 B0 s7 M. ~
  247. GamepadPortScan;手柄端口扫描& G. w% ]) S/ g/ l: {( t6 ^
  248. LDA $4016
    " [8 p0 b. C. Q& H8 s8 ~" a
  249. STA <Gamepad_Port_Value! k( J0 z; G( C& `  S
  250. LSR A6 x# |( e+ N! U/ ]2 @, k5 k
  251. ORA <Gamepad_Port_Value% e0 `+ q9 P" G8 x$ W
  252. LSR A
    1 O. T5 x# a3 Z, ^  K/ [$ f$ U
  253. ROL <Gamepad_0_Value
    ; \4 }" K" ^$ |. Q
  254. LDA $40176 I7 v3 ~; f# z4 w
  255. STA <Gamepad_Port_Value
    & R! ?* ]# ?4 @; M$ i& a
  256. LSR A
    3 w# h1 E+ P4 F1 f& R! }- m' B
  257. ORA <Gamepad_Port_Value0 I: `4 g! \% Y, o' I8 h
  258. LSR A: m7 _& A# J' h, K
  259. ROL <Gamepad_1_Value2 T9 l* d, W' }. x
  260. DEY9 d; c7 |/ t7 [/ j
  261. BNE GamepadPortScan
    % _& o6 s+ p6 w; T
  262. RTS
    3 \$ k* E0 L0 t' |! m1 M' a
  263. 3 h' K: q0 v* A" V& @( M* [/ M
  264. ;==================================================
    * R: p( y# L" n. I$ |: k7 n- Z
  265. ;PPU处理* G+ U4 d6 ^. C" ~0 l$ M; B8 ]
  266. PPU_Process
    % z$ h7 O, {6 o
  267. LDA #$004 x  K% c7 @- F5 H, Z0 _8 A  \
  268. STA PPU_MASK) Z/ E. H& X! [8 P4 w
  269. 2 t2 s' b  n% S1 X
  270. BIT PPU_STATUS# `: q6 G( s' E5 t
  271. LDA #$20
    0 A+ O- b, F' }4 I1 B+ c# m% Y
  272. STA PPU_ADDRESS5 E: y1 S. _$ b9 W, P# n
  273. LDA #$00
    # t( h5 m4 k/ A. n5 K
  274. STA PPU_ADDRESS
    9 b! I5 M4 H/ ]7 y9 g; H5 l

  275. 5 [1 j. e& B$ R
  276. STA PPU_SCROLL% C- z7 ~, \% X  `* K9 C
  277. STA PPU_SCROLL/ @. B8 h$ Y% [; t' [8 Z

  278. 7 r9 s; `3 _2 c# z( s  @5 \- c* ]
  279. LDA PPU_Msak_Buf
    " R2 K9 B9 Z: O) Z$ q; `9 W; u! F
  280. STA PPU_MASK
    5 t+ H+ }! V" F2 o% k6 L. z1 Y
  281. : n7 d- w; `; _% b4 I9 @
  282. RTS5 N3 H) {; r4 _6 @
  283. 1 f7 r2 l- \2 F7 c
  284. ;==============================/ J: ?1 f& e% _6 k# b- l  s8 Q
  285. Time_For_Vblank;延时等待* m  \$ H1 l' X( w9 u  M' l
  286. LDA PPU_STATUS
    ' V6 X& q( l' d5 O! ?2 Z0 X
  287. BPL Time_For_Vblank
    * J8 y& |3 J+ c% p
  288. RTS( {& S8 h1 D  z* X8 j: t

  289. 1 S- k% T9 v! ]! [# y) Z
  290. ;==============================% y+ M( h' N! G4 z
  291. ;初始化MAPPER19" t( j, ~/ Z* W! ~' w7 I
  292. Init_Mapper191 ^) B% z* v$ [$ f  O# j; Z7 q
  293. LDA #$00
    # ~% e. g- X# O7 D, S
  294. STA M19_CHR_0000' e! G+ x% J% D5 E6 B
  295. LDA #$01
    & I5 h" Q6 Q) k
  296. STA M19_CHR_0400
    / B7 Z6 [7 q, j
  297. LDA #$02
    / I5 b5 f  M0 M! ~4 Q% t9 N2 Z- e1 e
  298. STA M19_CHR_0800
    7 m5 Q! J, r8 f) I/ p: `
  299. LDA #$03/ V6 e, x0 w( L$ E+ s! I
  300. STA M19_CHR_0C00. u0 k" n$ e- b2 y! E2 L) r3 u
  301. LDA #$04# M: z: g; Y- Z) Y% O/ U. _- F! `
  302. STA M19_CHR_1000+ s! E3 h* J2 p
  303. LDA #$058 T. D: R- T: x" ~* w
  304. STA M19_CHR_14004 W3 k( p- l0 p. v7 q
  305. LDA #$06
    # H+ u0 |1 w' i1 s
  306. STA M19_CHR_18005 _# y" L+ ?: A. t
  307. LDA #$07' z+ V( R* s9 ]0 Y# e
  308. STA M19_CHR_1C007 E! `+ U( ^: d
  309. 3 Q/ R5 w' F5 }- i, V; G
  310. ;禁用IRQ' ^7 h5 I7 `3 ~; }
  311. LDA M19_IRQ_COUNT_H% G$ j  l  Z9 m1 H# v) ?$ o# L# F
  312. AND #$7F
    6 ^, y6 }* H  F6 J
  313. STA M19_IRQ_COUNT_H2 k! G( K) R9 Z/ v3 h  o( n
  314. ( J8 `; Y# J8 K
  315. ;命名表% l# V& o4 ]# P! M
  316. LDA #$E0& B7 J: j5 Z: y3 I; W' D. I
  317. STA M19_NT_2000
    * x9 B) }/ v# R- M1 X
  318. STA M19_NT_2400
    # I3 L* C: g0 W# V/ _

  319. 1 Y6 b/ D, f0 E) t/ c, F
  320. ;命名表
    / h8 ^" G1 D- L+ `6 @
  321. LDA #$E1
    7 t1 J1 M% r; L) @: f6 G' C( O. l8 Z. d# h
  322. STA M19_NT_28003 ^6 u* o, g% ^) ]# ?) v/ J
  323. STA M19_NT_2C00; Q7 ~' H* z2 E0 R

  324. 5 q# @3 @8 A2 r. {" X5 }0 x6 m6 G; \3 b
  325. RTS
    4 w9 u& ]" ?9 c6 U
  326. 4 B( v; H: [9 K: i* X2 e
  327. ;==================================================
    ; l! J7 e. _+ s$ A/ u; ?2 e# I
  328. ;重置中断处理
    ; q, Q0 V1 K; \6 r- q; |  g2 L# S
  329. ResetProgram' r8 Z7 A% a& @, V- `( f9 g
  330. SEI
    7 C  M5 s2 J2 k4 y9 a- {! T
  331. CLD
      X3 c) {3 h- }( w; s
  332. LDA #$00
    ; E% \2 `6 c# ^$ |; w- w6 R- Q, R
  333. STA PPU_CTRL
    : ]6 y8 _7 W% u! ?- l
  334. STA PPU_MASK
    ) \8 o/ S' a) Z7 Z) B, N7 H2 \
  335. STA PPU_STATUS
      ~+ R  e9 F0 \3 ?7 `
  336. STA JOY2_FRAME
    9 z- r$ J1 g; c; k' }) {8 w$ O
  337. STA APU_STATUS
    ; d" G" O# b- j7 @

  338. ) l3 @( D3 [4 C% N! @/ I7 t/ ~' s
  339. LDA #$C01 [* T  G$ O% b
  340. STA JOY2_FRAME+ g2 u+ _+ ]0 f+ i. s" X- _
  341. * s. e" S1 ~& D8 X. B& {
  342. ;等待vblank2 Z3 M; D2 |3 ]+ r
  343. LDX #$02
    * V. E  |8 Q# d# F' ~
  344. Vblank_Wait_1% H- x/ T) \6 M7 e- d7 Y# Y# J
  345. BIT PPU_STATUS; c/ ~) U4 K- d) ~8 o: x
  346. BPL Vblank_Wait_1
    ! J/ b8 _) b- n1 Y
  347. Vblank_Wait_2( Y2 Q2 [: ^  j' H) C  X: j" W) f5 [) C
  348. BIT PPU_STATUS  ~' b6 J7 C0 O. t1 L3 ]# C
  349. BMI Vblank_Wait_23 R6 s5 H8 {: u2 v8 Q. S7 Z& F
  350. DEX2 Y0 e* c9 b2 y. P# T' d
  351. BNE Vblank_Wait_1
    9 G0 Z- |/ P6 r. {

  352. 4 @: ^) n4 n% S2 r( B. F
  353. LDX #$FF
    3 Q: J$ d) O1 w3 n
  354. TXS
    & x% q7 ?$ }" b
  355. ) m; h. y* V% e* e: R8 K( }
  356. ;初始化MAPPER191 z' T, F" S  d
  357. JSR Init_Mapper19
    : t1 ~7 ]3 s5 ~: t0 F$ I

  358. " G2 D- P8 v  x
  359. ;==============================! V5 L" w' f+ Y$ t  n: {/ O% D
  360. ;RAM初始化( z: t/ c6 [2 i  I8 \# |4 A
  361. Nes_Ram_Init, [, K3 E' M9 r# Y* o+ _6 `
  362. LDY #$00
    " L9 Y, G+ O) L% {+ ?2 v
  363. LDX #$08
    * V0 V$ `7 b  A, @/ ~& _. U+ J
  364. LDA #$00& [( d: C! |$ w# z8 U: L3 @& ^# g
  365. STA <$00& i, {/ {5 a+ K& b" e: a+ k) P
  366. STA <$01
    # `! b) I' G; ^
  367. Nes_Ram_Init_Write1 ]; X3 s( R3 m
  368. STA [$00],Y
    : l5 @( j1 I/ @5 o. @. X- ^1 a* j
  369. INY
    " l6 ]. q9 I" v8 J, j1 d
  370. BNE Nes_Ram_Init_Write+ e: P. D6 \4 B, D
  371. INC <$01
    8 R  p% T* S0 ?8 C
  372. DEX/ |7 [* c" W9 J. m' C! B
  373. BNE Nes_Ram_Init_Write2 K! Y/ C) e( T  W- X
  374. ( w) r4 O  v/ @# x
  375. ;初始化命名表4 L- h  z5 |8 T" v' }( |1 F8 M& R
  376. JSR Init_Name_Table9 M# E) g, U3 j7 q$ v2 G. Q, r) |

  377. ; m: F0 n' `) l$ p# a! o* n' T
  378. ;初始化调色板
    & H* Q& o) @! T- {
  379. JSR Init_Palette
    / h3 O4 r9 S: E- o  l
  380. : i5 {$ k" `- d4 e0 E, j
  381. ;初始化命名表属性& n* _+ H) M- g5 G
  382. JSR Init_NameTable_Attributes
    $ N" z  j. K- v4 L+ ^9 a
  383. # }* O& J8 \9 g2 g
  384. ;初始化精灵内存
    ' Z- s2 P) P0 F& \" u6 l5 p' k
  385. JSR Init_OAM_Ram
    - }( `* V. g6 g9 E1 c3 m5 A

  386. # o3 z  L0 I( b8 Y4 ~) G+ V
  387. ;在屏幕上写点东西+ U+ h2 @6 U: Q* n% L1 r
  388. JSR Init_Name_Table_Text6 x, H! i) q7 q# o

  389. / _) `# r- l" j+ P- d7 e2 h8 c  P9 e
  390. JSR Time_For_Vblank
    7 r3 H+ J$ N+ Y
  391. ;开启PPU控制
    3 ^' _0 O$ b& |
  392. LDA #$A8& o, u1 R( y& U/ d( K
  393. STA PPU_Ctrl_Buf+ y) d: S; y+ O+ u" N
  394. STA PPU_CTRL9 s# v- e2 }1 p) u: C' U9 \

  395. 2 |7 o8 M# M1 H" |, B( ^3 g; F; ^: Z
  396. ;开启PPU显示
    0 X$ |4 V8 b" \6 A3 A( c! M8 P9 h. N$ A
  397. LDA #$1E
    3 m$ u$ n7 M! Y  l+ `2 o7 v; c7 w; Z) B
  398. STA PPU_Msak_Buf
    % q* u5 @! V  Z
  399. 0 n4 X: Q3 b5 c# l2 P( ]
  400. CLI
    $ a2 M0 f( [, E$ `* G+ {0 P1 x
  401. JMP Loop9 y8 f  Q. Z) T) c! z

  402. 6 O% Q8 Q3 S0 b: ^5 Z9 f8 T
  403. ;==============================, c3 @4 v0 F; g3 d/ w
  404. ;死循环, 等待NMI中断2 v- y+ _4 l/ k/ ]
  405. Loop5 U! B9 [9 G1 h8 k
  406. JMP Loop
    6 a2 u" ~" W: I/ ]6 O- ]2 X/ h

  407. + [+ {1 @/ P4 [, a) O! C
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    0 _2 L  a0 {: K& q5 m

  409. ; r5 d* J5 A) O/ d9 c+ O
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    3 ^" s: U# T1 t1 E
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    % t0 q# d1 ^' v3 V
  412. ;==================================================7 g( A1 f' x0 E
  413. ;NMI中断处理7 \1 k5 T) I% A9 e" S0 A! b, P% N
  414. NmiProgram
    : ~4 f. K+ z) @) p2 e9 n
  415. PHA
    ) H  \% g. W3 L9 r# c2 @
  416. TXA+ h8 Z  X; e9 K5 G4 Q$ X  C) o+ i
  417. PHA
    3 f  ]# _4 m# |$ S3 `- t
  418. TYA/ c# h, @% }, P0 M( N$ ^
  419. PHA
    / ?6 h8 ?- [. l
  420. * _- |$ l0 h6 K- J: [/ J  @0 L
  421. BIT PPU_STATUS
    % b  E3 V; P, p  A# _/ {

  422. 5 F( U* M+ d5 {3 d. L
  423. LDA #$007 R+ v7 |& j5 T. ^
  424. STA IRQ_Index
    ! w& J% F" ~) v1 w
  425. , v" E9 D4 o" t4 d# F( j
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    6 s% W7 ^- e* P7 m5 d8 j4 S  R
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    8 w. w( X1 O& r! G
  428. STA M19_IRQ_COUNT_L
    / L% }/ J# {7 d, L+ J
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ( O6 [3 T5 V% M1 x/ I
  430. ORA #$80, M% U$ g& w' T- [% }! `" b
  431. STA M19_IRQ_COUNT_H
      W) h- y2 \+ T
  432. CLI6 p3 u9 F: ~% s3 {
  433. ' X% J: M' P  |- D4 n! f6 V; y5 R! w
  434. ;关闭PPU控制/ ?. ^5 w; D; h7 B
  435. LDA #$00) j, l& a- \: ]8 h7 h  p
  436. STA PPU_CTRL% n" [8 ?- e; M8 n5 U: H+ l

  437. % s! n! t$ {0 Y4 n
  438. ;处理PPU
    6 Q6 p1 E$ Q% t, F: `9 C
  439. JSR PPU_Process# j4 f: o4 v, V

  440. $ Z; L/ p! L/ V0 [6 L6 d7 B
  441. ;开启PPU控制7 b* `7 l9 n) f9 j3 }( \' R* _
  442. LDA PPU_Ctrl_Buf* k$ i! v6 W, t7 T+ t
  443. STA PPU_CTRL
    6 ]* ]0 P% a6 C9 Z& K9 y
  444. * A1 E: }2 k3 h+ I7 `/ M& z
  445. ;手柄处理4 H9 k: A$ K: e. U
  446. JSR GamepadProcess" h. @! d3 p/ f
  447. * |9 Y2 W" O% P8 U6 z& ^
  448. LDA #$004 X: M. ~* m# T* X" M+ r
  449. STA IRQ_Index* k: r. }# E, J' y* S
  450.   K, r6 N- ~7 `% o: D3 x% V
  451. PLA" I9 Q' r: M" K5 O
  452. TAY, p1 P6 B. l/ i2 @; U
  453. PLA: l+ o2 i: ^- N& C; C- C
  454. TAX$ `8 g  q2 C( v0 @# l3 w$ @. W
  455. PLA3 y1 L# R8 A4 Z
  456. RTI
      d( a% |4 Z3 k& z1 M, @2 j
  457. ! ~& x: U/ o2 D2 ]: V; p
  458. ;每行扫描线113.67$ H/ l  F; Z1 n# I+ F  k6 ^
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)! C* K" x' ^9 j) E
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    , l8 l4 N3 F4 v1 J6 }
  461. ;==================================================
    6 x% \& f3 G5 S
  462. ;IRQ中断处理6 K, |9 {7 ?$ g) q/ A
  463. IrqProgram% [0 w! j6 n  ~% K
  464. PHA
    , g; R. _6 [" s5 [: u5 ]% ?+ B
  465. TXA
    ! o* f, G4 q/ y% p2 z/ }
  466. PHA
    : \3 P& a3 E( E5 q
  467. TYA
    + t* O& [. h; p1 ^% M  w$ Y6 Q0 u" S
  468. PHA4 Z  \0 L/ K' e0 S
  469. 3 w; h- {& Z+ p& L
  470. ;16条扫描线后触发IRQ
    1 U3 |4 W& ~8 E
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    % H' l% p  z; d8 t
  472. STA M19_IRQ_COUNT_L4 Q. r* Q" H5 W+ u( P' K
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    % _& B1 c# E+ X+ y) M+ G
  474. ORA #$805 H0 d& U4 J- S
  475. STA M19_IRQ_COUNT_H
    % @& L% z' I+ H( M6 s1 I  W

  476.   ?7 @7 X6 a3 o
  477. LDA <IRQ_Index: b' x- ?6 W( r  y5 Z
  478. BNE * + 4
    ) t! _/ |  K2 @* j* |! P
  479. INC <PPU_Scroll_H" J6 @# Z& d  p2 @

  480. $ Q; ^) [3 ?! c
  481. ;设置屏幕滚动$ I1 K: J4 d5 _2 n* v
  482. LDA <IRQ_Index. C1 Q3 L6 K* U$ a0 S3 Q
  483. AND #$01
    - p; G! X2 A* N7 Z( s9 |0 l. N
  484. BEQ Irq_Scroll_Right# k3 O) Z; L* O8 L
  485. 7 H. t( B9 X5 J8 A
  486. Irq_Scroll_Left# O/ d! t  o  l9 Z
  487. BIT PPU_STATUS
    , R" U. j) M" O" h" L" Y
  488. LDA <PPU_Scroll_H
    $ z$ s2 F+ Q4 M7 T: R
  489. STA PPU_SCROLL- k3 R1 O# b" o2 p5 G# R3 I
  490. STA PPU_SCROLL
    ) S. j/ s' `+ Z" O0 M
  491. JMP Irq_Scroll_Over( v( @4 r$ ?& j; {; ]/ Y2 x7 E
  492. ! D4 D3 e* I( b* v9 }! n3 z
  493. Irq_Scroll_Right& t) J& L1 g9 D$ ]3 W: Z1 Y' E. K9 U
  494. SEC, D+ G% M# o6 y7 o4 y6 s4 P! m/ j" `
  495. SBC <PPU_Scroll_H
    5 Y' h- l7 p* q7 K$ L* U) k$ a6 v
  496. STA PPU_SCROLL
    8 Q1 Z! o5 e; z
  497. STA PPU_SCROLL
    7 n  ]( x, M1 n8 O2 X3 [0 _
  498. Irq_Scroll_Over: W( s% w; [. s' l

  499. ; z+ k4 e0 S/ U; Y! N, l- E' |. c
  500. INC <IRQ_Index0 U/ C* s& V* q0 ?% H* S6 r
  501. - O1 q& ]; ?) m1 V
  502. LDA <IRQ_Index
    , s* g# g- T' \6 s9 K
  503. CMP #14+ I2 S3 d/ x& W, W9 T* z0 [
  504. BCC * + 10. F, F) x! q# x# W) w
  505. LDA #$00
    6 \6 v0 J% Z3 Z) X- ~. Q
  506. STA M19_IRQ_COUNT_L5 E5 u4 g( h0 n2 Y' s6 R
  507. STA M19_IRQ_COUNT_H, h7 A- f: p! F9 y, M& L. m

  508. ! j3 w1 R: ?8 H" ~4 \
  509. IrqProgramEnd2 q9 y& u( y5 n# \7 @
  510. PLA$ x8 U+ Q/ p" k" E( Y
  511. TAY
    # h* y5 o* P) j& @3 Q' v1 x1 w
  512. PLA
      L5 T( p* X3 L
  513. TAX: L' v4 s" Y- O
  514. PLA
    % ?& v; y' d1 w1 a, L% i8 `# y0 ?% R
  515. RTI
    ) l% T- ]( `3 p! R- T* Y; ]8 u
  516. ( K4 M4 C# y! t' ]. X1 J2 A' Q( W. W
  517. ;==================================================, j+ `4 L( I" Q9 C! z* }
  518. ;中断表* W7 f0 ^( f" W" X* X! @
  519. .ORG $FFFA; D: P# G! J) m/ H2 H
  520. .WORD NmiProgram: f1 t- n9 j2 q* S0 ]! _2 |
  521. .WORD ResetProgram
    ) h' c) O# U8 G9 G2 N1 ^& E
  522. .WORD IrqProgram
复制代码

7 e  G2 M( |3 q9 ~) r! p. J, |

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-11-5 14:03 , Processed in 1.063476 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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