EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ], x, f! L( i9 h5 B; Q+ J
  2. ;FlameCyclone 20230710% z" j+ n9 y2 G" z& g3 L& E+ f* J

  3. $ R# m) q9 I6 v" G% N
  4. ;文件头
    / o( V' s- \. ]4 f# a
  5. ;======================================================================
    ' b8 u6 Y2 B+ a. S" [- A( w$ n5 z% B
  6. .INESPRG 4                                              ;16KB PRG 数量* y( I7 q$ Z7 P& a9 n
  7. .INESCHR 1                                               ;8KB CHR 数量
    " Z- V4 Q7 s5 ~0 h3 l( e0 E
  8. .INESMAP 19                                                 ;mapper 19
    8 ?; I4 i* c# f) t( y4 C
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    3 j2 N1 Z/ a8 ]& W, t
  10. 5 q2 ^5 o9 N! U8 y7 B: O3 u6 d
  11. ;必要条件4 I% v" G) P6 s! g
  12. ;1.持有CHR ROM
    4 ]+ e. \* L' T5 p; C
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000. P1 m: K+ b3 ]+ `! z
  14. ;3.精灵内存(OAM)不为空
    6 Y3 D+ p3 S. z. m
  15. 6 W9 a1 \* u6 I' h2 J& x9 k6 C
  16. ;==================================================
    ; d  M+ Q& T' p1 T% u5 U/ s5 V7 k
  17. ;NES端口常量
    ' B* ^( e0 n) d: a4 j
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    - s6 r1 ]$ u9 M9 k0 {+ W7 G
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ! O% w# u8 x2 P
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位3 O9 A- l9 |  v7 l
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    * t1 I0 N3 r! I9 f
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1: J6 t+ y* S3 a2 R8 m. u! q
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    % s3 [9 r: A. u- G1 U/ C) [+ c
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    5 U4 c# x; o+ b9 P, N4 ^5 \
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
      h3 V. k# g/ i7 ?
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    # `" U6 N3 E% h( X1 P! L
  27. APU_STATUS              =   $4015   ;声音通道切换6 ]' n7 f' P& }% v9 F% V* U
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    ! @. ~6 p5 s6 z6 d" |
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通  P' e# g# t$ W" H
  30. 3 h$ F4 h* F. z% j  O" U
  31. ;==================================================
    & h; U9 M6 `% }2 v, g
  32. ;MAPPER 19端口常量- c  {* d) L- {8 r
  33. M19_CHR_0000    =   $8000- ^+ v" \) \/ B! S1 j4 N
  34. M19_CHR_0400    =   $8800, V% V" Y3 L. d& W+ n
  35. M19_CHR_0800    =   $9000
    / x" R+ B: _+ F6 a' u" g
  36. M19_CHR_0C00    =   $9800
    ! G: F, L2 V* d4 _1 }9 T" t# G8 y
  37. M19_CHR_1000    =   $A000' L* e7 V* ~, G! ~0 \% w
  38. M19_CHR_1400    =   $A8007 b! _- W: o, I! N) Y* @! }$ ?) ?
  39. M19_CHR_1800    =   $B000# Z/ Q; ^6 [2 F7 b% h
  40. M19_CHR_1C00    =   $B800
      q: x8 _: q$ {' |1 k
  41. M19_NT_2000     =   $C000
    * g6 \) g- c0 @5 k; [: ^7 d
  42. M19_NT_2400     =   $C800
    - Y2 y& {7 w4 o
  43. M19_NT_2800     =   $D000
    ; L9 i) m$ j, g5 n; r! Y; C
  44. M19_NT_2C00     =   $D800# z# _; {$ z, |+ ^
  45. M19_PRG_8000    =   $E000
    8 k$ s; h) W( ~3 n" M
  46. M19_PRG_A000    =   $E800
    8 y4 ]5 a0 i  ~$ \  d
  47. M19_PRG_C000    =   $F000
    % X, `) a# T- k
  48. M19_IRQ_COUNT_L =   $50008 T. q. X& G+ |" {
  49. M19_IRQ_COUNT_H =   $5800
    + @. K$ ]  o, i# z" d/ ?+ S
  50. ; s* O- w( G' C' a! y; i
  51. ;==================================================' y9 {) U$ k2 P: c; T8 y
  52. ;程序块配置9 [- }9 T4 h7 l
  53. BANK_DATA_MASK          = $07; E$ M: Q; B8 G7 M, P. v
  54. ;--------------------------------------------------6 Q3 I8 U  R. q/ {
  55. RESET_BANK              = $072 \, X/ l; q2 [
  56. RESET_ADDR              = $FC00
    3 g) S% }; p' A6 R( a% i! F

  57. / z4 C2 [% G; n2 W& @  |# Q
  58. ;==================================================
    8 j* o. ?: t* G% F* U
  59. ;图像块配置1 T  ~8 h0 X: j) Z
  60. CHR_DATA_BANK           = $08; |2 y! |' ^% W2 n
  61. $ H9 h5 z; V) I/ @
  62. ;==================================================
    / o0 G* B1 p3 l) ~# C5 P; z0 F% e! V
  63. ;零页内存地址配置
      Y6 z( a7 S1 Y
  64. Use_Ram_Addr            = $80. _& R) w8 S$ ^: n: v7 s
  65. PPU_Ctrl_Buf            = Use_Ram_Addr* |) T8 E8 B8 {2 F
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01- _# e6 Y+ U9 Q& U
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    5 ^% O3 R; j8 B, I: g1 m
  68. PPU_Scroll_V            = PPU_Scroll_H + $014 a5 W/ D% ~. V. [/ p1 L
  69. FC_Data_L               = PPU_Scroll_V + $012 t9 j. }1 I0 w  o2 }( G5 O9 x: q
  70. FC_Data_H               = FC_Data_L + $01* X7 R# w: g1 c5 N* [8 {) W
  71. FC_Data_Buf             = FC_Data_H + $01% F9 J( L, H3 K
  72. ;==================================================
    5 D) q9 d1 F" v  _4 D( U

  73. - ^! @% g5 V# t% L# {& C/ V
  74. GAMEPAD_MERGE_FLAG = $04
    / n9 ^3 A0 t9 r% N' ]
  75. 0 G7 R, x1 Z1 K: u; |/ K
  76. Gamepad_Keep            =       FC_Data_Buf + 1, a7 x# @! H5 K0 m3 E
  77. Gamepad_Once            =       Gamepad_Keep + 2( m, @. x% u- J
  78. Gamepad_Temp            =       Gamepad_Once + 2( F/ c" q7 v4 M, p/ z
  79.                                 % K# b$ ?  d8 Z  D
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    5 r$ W$ `: |% q2 f
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    & S; L' m6 z* @, P0 N( H& M
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    ' u1 a  Q7 o- w
  83. Gamepad_1_Value         =       Gamepad_0_Value + 13 P1 n$ M& Q2 ^+ ]: z# r
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1/ v/ [3 |  g( a' D( f4 D
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1( s2 O$ M1 J1 B* ~; z

  86. * J- u; i1 S( t) J7 k
  87. ;==================================================
    0 j) `: F- T% _: `; v9 K# `( g3 J+ C
  88. IRQ_Index               =       Gamepad_Merge + $01
    $ s6 C) f% d3 a% d  f
  89. ;==================================================6 Y: w6 N6 u5 T, D. X2 E

  90. 1 `% O* }2 O) Z2 J- F# x
  91. ;CHR图形数据7 ]) i# I) \) d
  92. ;==================================================
    . M3 H' `/ i. ?3 `$ V5 V
  93. .BANK CHR_DATA_BANK. S* l1 s% X! y- T
  94. .INCBIN "chr_bank/chr_data.chr"* Z+ Q1 M% N2 [

  95. # r3 \- V& k+ W
  96. .BANK RESET_BANK & BANK_DATA_MASK
    ( X" J1 G$ s+ l+ k- K
  97. .ORG RESET_ADDR" n% b" Z7 f6 W% F/ X9 x& y
  98. 5 Q# l; {! z; K7 C
  99. ;--------------------------------------------------' y2 o5 C' Q2 g/ F) o
  100. Attributes_Data
    ' w- _4 b7 n* d4 i. D; ?
  101. ;命名表属性
    ; u; P& W' P1 z* `! P+ E
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    , F! M# R+ d% K1 U
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA8 B& `: T7 E; g: b: m
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA* T# u; T0 Q# l! L. l* m5 `5 _
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    % w0 u$ j3 M% n) A) }7 D6 A
  106. ;--------------------------------------------------
    6 t- o8 X6 b  K# M6 l3 r7 p
  107. ;调色板数据
    + I5 c" k1 z) @1 r9 k* P$ z
  108. Palette_Data
    . `) p( ^" Q) g' i
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    2 J5 j# Z$ D* l% u
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    5 q$ f( e+ N: @. s  e% m. {
  111. 3 O% S- f+ z  u7 e
  112. ;==================================================) ~4 j* z( G/ I6 {* q
  113. ;命名表初始化
    3 q" K" _! I# J- E, ^
  114. Init_Name_Table
    * Q: s0 N4 v: }6 q4 r# H. N7 Z
  115. LDA #$20
    - A% c& x$ x7 Z! g# O
  116. STA PPU_ADDRESS6 ~) ]2 M$ N5 y: l) D; m
  117. LDA #$00% g& g- Z0 `) f
  118. STA PPU_ADDRESS
    % g  Q/ L0 M5 j/ ?
  119. LDA #$00. B' [( ~) @$ `+ p
  120. LDY #$00
    5 U( i9 ?: m; A/ q7 C: I
  121. LDX #$105 `7 ~% S0 d% m+ Q
  122. Init_Name_Table_Write
    + {7 W4 F3 J% N$ d9 R0 S
  123. STA PPU_DATA
    6 u1 O+ P* m, K
  124. INY- F3 t; [% t: M7 s5 s6 l- P
  125. BNE Init_Name_Table_Write6 A+ }  d6 e+ C1 @% l0 I2 v* \
  126. DEX
    9 Q4 T, Z- m, I3 o1 q
  127. BNE Init_Name_Table_Write: K1 u) ~; I; u7 X
  128. RTS
    ) r# Z( t& I+ w! M9 ?, D& d
  129. 7 [( f' _4 V+ U) |
  130. ;==================================================
    8 ?7 }) a9 G0 h# \! H3 S# k( G
  131. ;调色板初始化- m/ A( X9 h3 z4 I3 q! w- }' ]
  132. Init_Palette
    5 V' v' o1 {  k  y* N
  133. BIT PPU_STATUS
    2 P* V, Y% O1 F- v
  134. LDA #$3F* ]" P$ ?' _- ~; o) o5 N+ a
  135. STA PPU_ADDRESS% t9 ]4 j1 g/ q' v6 ~1 j
  136. LDA #$006 ~0 U# ^$ ?3 O5 `! {, X' f
  137. STA PPU_ADDRESS- L+ X2 U* l; d$ O+ x% S
  138. LDX #$000 X& b* x* e6 f
  139. Init_Palette_Write
    1 Q9 N$ z1 u# A$ b0 ~  B
  140. LDA Palette_Data,X
    4 W$ ~5 i7 @& G; A& Q
  141. STA PPU_DATA
    5 I* A3 f; p8 z) x
  142. INX
    4 _( ~& U9 C' \, h  w* P
  143. CPX #$20" m" R& M) B( k3 [
  144. BCC Init_Palette_Write
    2 N+ R( M% C4 v" W: D
  145. RTS
    , V4 h- W9 |8 c! E/ v, f
  146. ! i1 Y# I" `4 \
  147. ;==================================================, j; N: S3 R2 [
  148. ;设置命名表属性3 ^/ x$ G7 ~6 y$ r
  149. Init_NameTable_Attributes4 A. ]& r# o: I+ w* q/ c
  150. BIT PPU_STATUS
    8 n9 g& x3 F1 y' N5 V
  151. LDA #$23
    3 n6 Y8 r( x  w$ ]3 w; @- z  C
  152. STA PPU_ADDRESS
    ; M* R1 b* x+ f. F' ?7 _  m. B
  153. LDA #$C0- [0 z! K( T! l2 {
  154. STA PPU_ADDRESS
    2 \" V, K2 m7 q( F& @
  155. LDX #$00
    : l0 z/ S6 w7 V! h6 x0 u
  156. Init_NameTable_Attributes_Write
    & |3 @# y2 f# _& U5 N1 {
  157. LDA Attributes_Data,X
    ) U; i9 \$ H& J& ]
  158. STA PPU_DATA
    : C9 L: V. m$ e/ v
  159. INX
    : O* P5 p3 N, Y' v. p; {, e2 T
  160. CPX #$40; u3 Z. k  U( P. H$ `
  161. BCC Init_NameTable_Attributes_Write
    ; J8 A( @% L3 V/ D1 ^# [
  162. RTS9 l; f0 {; d% z( R" E

  163. $ w/ h! k3 G% S8 A# _
  164. ;==================================================; b; J( G' {9 ~5 \2 e7 P( P8 x
  165. ;初始化命名表文本8 n2 V9 T" G$ \
  166. Init_Name_Table_Text
    / [: p# @2 o3 ~" j% i0 E
  167. BIT PPU_STATUS
    3 Q9 Q; S- G. d2 o
  168. LDA #$20
    / I0 O  z7 n) @: O5 h: w
  169. STA PPU_ADDRESS
    ) m, V4 B' l! ]8 ]3 n9 q
  170. LDA #$00
    0 Y6 p0 j, O/ {
  171. STA PPU_ADDRESS
      l# C2 j# J6 G- E% R
  172. LDA #$00# M! i/ ]3 M1 ^* J" _
  173. STA FC_Data_Buf- Z# j) e2 [3 }- R
  174. LDY #30
    , ]+ ^/ Q& d, j3 @& w
  175. Init_Name_Table_Text_Write4 s- w4 l& _( L$ F$ H
  176. LDX #32
    $ j2 C; N9 Q. S8 t
  177. Init_Name_Table_Text_Write_Char
    6 \/ t) |/ g. I7 N' o8 z
  178. LDA #'0'% T8 L- m! k% _  F; K" W: ~
  179. CLC
    ! G& ~3 `: m! }
  180. ADC FC_Data_Buf
    . Z5 d. W2 {9 M; g) s8 H0 ]9 v
  181. STA PPU_DATA
    : c/ X% u2 C9 a2 l3 B: v' T
  182. DEX+ M' ?, X- ~6 j
  183. LDA #$14+ C2 Z+ a9 |" Y7 a: j
  184. STA PPU_DATA3 m: y4 [  {2 v6 a+ t7 B& Z1 \
  185. DEX7 k0 H9 K$ i$ f
  186. BNE Init_Name_Table_Text_Write_Char0 L' t( C! V; m! `, c* q, w* l
  187. INC FC_Data_Buf
    ' j5 T- p7 l/ n$ a# E6 ?& s
  188. DEY& B0 ]* r, F3 g" P& i, r" R4 w# ~% D* v
  189. BNE Init_Name_Table_Text_Write
    9 Q' f4 D6 |! U; L$ m( C
  190. RTS8 N% A3 T% y; O3 p/ e6 o
  191. 6 V2 g1 C9 C. D& T0 M" E. M$ v
  192. ;==============================: z$ u7 R5 G" Q! K& p
  193. Init_OAM_Ram;初始化精灵内存) T5 _8 T8 \" W8 ]+ {3 `$ A
  194. LDX #$002 S! F9 ?& k( M
  195. LDA #$00
    7 A3 o  o; u# n
  196. STA PPU_OAM_ADDR
    6 X. j% s, \. u$ z4 X
  197. LDA #$F8/ D7 b( h1 ]' @& F/ W
  198. Init_OAM_Ram_Write! M: V2 i& k; P6 P
  199. STA PPU_OAM_DATA0 `7 u5 r( d) h
  200. INX
    6 m; \1 f& J  a, V( f  L! Y
  201. BNE Init_OAM_Ram_Write  F% c9 Q. j5 `- Z2 [
  202. RTS
    . S4 L6 ~& ?+ X$ p0 r
  203. ) O, R0 ]# i( n+ @1 [
  204. GamepadProcess;手柄处理
    : A# q: h/ g% }
  205. JSR GamepadDatacan
    ' P, P3 H: B7 Z% S/ W
  206. LDA <Gamepad_0_Value
    5 U- H0 y6 o4 j6 L! W/ z6 ^: R
  207. STA <Gamepad_0_State( m: x# _$ `. C( {
  208. LDA <Gamepad_1_Value
    4 _2 k! \! s1 ]+ E) a
  209. STA <Gamepad_1_State
    " G! {8 V! }" k8 W2 M: F
  210. JSR GamepadDatacan
    : I* f; w- a& ^
  211. LDX #$01
    * H; x9 V9 i  A0 a- U$ p
  212. GamepadMergeCheck;合并手柄输入检查
    " ~, u, U6 q9 |
  213. LDA <Gamepad_0_Value,X9 E- U2 p+ M7 z: |& @8 C. Z: O
  214. CMP <Gamepad_0_State,X" b/ d4 x8 R) F7 ^- E, O
  215. BEQ GamepadMergeInput. i* L6 d7 j6 t9 Y. @* o
  216. LDA <Gamepad_Temp,X
    & e) y" X/ y3 U4 ~6 C
  217. STA <Gamepad_0_Value,X: w; H0 y6 `  p  E% M  q
  218. GamepadMergeInput;合并手柄输入
    9 L* a$ ~: }  B5 c4 j' k) A' h
  219. DEX- j% C& ]; T% U' i
  220. BPL GamepadMergeCheck3 o9 R: F! G0 r9 d: v+ v, R7 B( L
  221. LDA <Gamepad_Merge
    . H; p9 {: k$ i- \% s& ^1 Q
  222. AND #GAMEPAD_MERGE_FLAG
    / N8 y  P/ i) S- i+ v. o
  223. BNE GamepadStateProcess  O! I/ x" D+ P7 E  y
  224. LDA <Gamepad_0_Value  r+ m8 B0 b$ }# J$ f# t
  225. ORA <Gamepad_1_Value1 ]7 r: r! b% v
  226. STA <Gamepad_0_Value$ O% b5 k' }/ z$ L
  227. GamepadStateProcess;手柄状态处理
    $ z3 K: j. x# H: M
  228. LDX #$01
    6 r. T9 V) c$ ]" j4 `) m& E
  229. GamepadStateSave;手柄状态保存6 E- H0 S+ l7 S% @, m
  230. LDA <Gamepad_0_Value,X
    ! p( A( ^: ^' a0 t
  231. TAY
    ; h" X4 W$ a4 ?7 i: o1 ?9 `  Z6 j
  232. EOR <Gamepad_Temp,X
    ' \' {. r( }! g5 ~
  233. AND <Gamepad_0_Value,X
    ! \4 C! d. U" }2 p; q' Z: Q
  234. STA <Gamepad_Once,X/ N) b: G5 K; {
  235. STY <Gamepad_Keep,X
    ' G  V/ q, D% U
  236. STY <Gamepad_Temp,X! i; l# W" O. S5 ]- G
  237. DEX* u# K0 \2 B4 t9 r
  238. BPL GamepadStateSave7 U$ q2 Z) E1 [! g5 v& x
  239. RTS
    * W: j+ s1 f' U/ `7 U8 R# w, [) O
  240.   O8 M# q/ |" h/ L) D
  241. GamepadDatacan;手柄数据扫描( P6 r! K! W6 M. M; d  J  ^
  242. LDX #$01
    8 b8 ]) D3 v/ h" z2 G( q0 V' u3 H
  243. STX $4016
    " e! i+ h! U9 E4 t4 I8 S( V
  244. DEX4 ~" t4 H# }* M5 F2 U0 j1 K% j
  245. STX $4016& S$ T( @9 H1 b# G
  246. LDY #$08
    % X% p% ~! x& O* C" q4 D# }
  247. GamepadPortScan;手柄端口扫描
    1 M  X$ a; J8 Q  j$ m& {4 z
  248. LDA $4016
    & Q# O+ S1 D) n  O
  249. STA <Gamepad_Port_Value
      m* k+ L! E5 X5 x
  250. LSR A2 \, u6 V3 f* x# Q0 N9 x' f" o! H
  251. ORA <Gamepad_Port_Value
    # F# G) r; d2 u9 M
  252. LSR A% X1 B2 X. r( |7 {7 q6 ~8 Z
  253. ROL <Gamepad_0_Value6 |' Y" v* }( Q; l+ n
  254. LDA $4017
    8 ?- z- ?9 t5 n0 p; T; g( X3 U" d
  255. STA <Gamepad_Port_Value: o& W; Z+ O8 O$ p
  256. LSR A
    : w0 V( T# K/ M. H
  257. ORA <Gamepad_Port_Value! z( W( o9 A9 f! {! Z: d! ?
  258. LSR A
    0 _6 t/ S$ M1 a6 ?
  259. ROL <Gamepad_1_Value
    ! C/ o' T7 u' k4 \
  260. DEY
    : w/ T( K3 r1 Y+ V
  261. BNE GamepadPortScan7 ^) ^8 M7 [. ?
  262. RTS: M* z7 x) V0 g$ z

  263.   ^2 j" w6 a. A! J2 f( X4 U7 A
  264. ;==================================================( Y: h; p$ K- f, A
  265. ;PPU处理* B2 w% N4 f1 F5 [3 g  p
  266. PPU_Process4 `- k: J! T- H8 E& m
  267. LDA #$00- I# i$ M3 Z7 @$ B
  268. STA PPU_MASK: X+ m; |. X$ O5 R$ M. e5 V5 W6 Q

  269. : \) N' k$ ~1 j  T
  270. BIT PPU_STATUS  t! L! Z# P+ l  X  e0 K- F) J/ n
  271. LDA #$20% L$ D8 R* A. L7 @
  272. STA PPU_ADDRESS
    $ a% J$ ~8 ^2 x8 u" T5 E
  273. LDA #$00
    ( {/ C8 V. h+ |: z
  274. STA PPU_ADDRESS0 O% \) ]! X5 c+ {/ M4 p2 D- J& \- g

  275. ' a0 y  q/ A: k1 J' |9 Y+ R$ `
  276. STA PPU_SCROLL" e" y9 ^& z2 S/ S7 ~4 U7 ^
  277. STA PPU_SCROLL
    5 S8 V1 }8 _6 V
  278. ; t- _) E9 c( [7 T
  279. LDA PPU_Msak_Buf
    4 P7 g1 Q3 R6 k2 O$ i% _2 w
  280. STA PPU_MASK$ m" u& p& v) W- S# c% V+ C3 P
  281. . z" v/ i8 f4 ~: u4 D# e3 A
  282. RTS
    6 p- P" W2 y7 B

  283. . v& A- `2 }4 N/ N& g! e
  284. ;==============================9 E$ _  L5 o  u6 W/ ~5 v/ q
  285. Time_For_Vblank;延时等待9 B* R* q7 d4 `1 P. y. c* a; I1 V9 i
  286. LDA PPU_STATUS) G5 w& \7 _7 T" d+ j
  287. BPL Time_For_Vblank
    . L2 Y) w) S8 k$ }+ l9 x
  288. RTS
    9 y. ^5 a: P9 c) w. ~" J

  289. : X8 \# C$ ^/ ^# B  M' v. |4 q
  290. ;==============================
      s" V' W# |3 K0 A. r/ c
  291. ;初始化MAPPER19* ^1 ]" L" N" U; K
  292. Init_Mapper19
    2 \9 s( {8 K# P
  293. LDA #$00- _) S) v% X" W5 g8 ~/ T
  294. STA M19_CHR_0000# j  z, ?/ D3 y0 D' A# ~! ~  @- L
  295. LDA #$01  L( y, J7 y) k2 m. _& N
  296. STA M19_CHR_0400( T8 i4 \- s( a* F
  297. LDA #$02
    % N- L0 `& b* @6 Q
  298. STA M19_CHR_0800
    8 s5 Q" w$ I5 z; }9 D4 n. x
  299. LDA #$038 N% I6 ~5 ^$ o! c
  300. STA M19_CHR_0C001 `0 n/ f9 x- s" R% R! c) `7 \
  301. LDA #$048 E4 E, ?3 x" I! V% Y- p+ {  R
  302. STA M19_CHR_1000
    7 p* H0 ?8 j1 V) i+ \
  303. LDA #$052 `- ^, K9 I9 c# R! _
  304. STA M19_CHR_1400
    1 h  S1 u( \/ u( ]+ V4 U& A  ]/ J
  305. LDA #$06) }" |0 ]: o4 @* ~
  306. STA M19_CHR_1800. A0 E/ p) z* g5 i
  307. LDA #$079 \4 K/ l9 P% L& S# x& h
  308. STA M19_CHR_1C00
      a/ B' U8 V( Y$ y% ]8 p

  309. ! [* @2 u% F- O, a) _. N
  310. ;禁用IRQ
    9 h: q# a4 d$ \0 C
  311. LDA M19_IRQ_COUNT_H
    % t! @* D: n  r4 |. a6 T
  312. AND #$7F
    % x1 t' U1 w( m, K
  313. STA M19_IRQ_COUNT_H
    : c" w( ^: N7 }  R
  314.   |& I8 O2 Y  a1 w' ?
  315. ;命名表
    1 q4 W) {$ P, `1 ^% |# L
  316. LDA #$E0
    0 _6 s- u! B8 |& o2 n+ O/ o2 W
  317. STA M19_NT_2000! s" G6 M: o& M" }8 O& j
  318. STA M19_NT_2400
      Q+ n6 J: I8 M, f

  319. - O: r9 ]( E3 g- p& Y8 q- @/ q
  320. ;命名表
      X% C- }  d! B. Q2 t
  321. LDA #$E1
    ' Y$ O* i1 t* B3 L
  322. STA M19_NT_2800+ r. h) r: z& U/ x# k; ~
  323. STA M19_NT_2C00$ g/ n" m/ q2 ~# G$ G7 }/ U

  324. 9 _5 Q% ^5 k0 t' U
  325. RTS
    - U! e; a# p+ Y9 p5 l

  326. + C! u+ E2 d+ r' x
  327. ;==================================================
    8 L/ |5 R* F2 t$ l
  328. ;重置中断处理2 w7 U# @+ A+ l9 Q; Y$ z
  329. ResetProgram+ G* j/ s6 P' {; e
  330. SEI
    3 D( t/ v) E. g- P
  331. CLD
    % s! M9 s  @+ A* e" f! `& _
  332. LDA #$00
    , }6 Z0 |3 Z+ y8 ~4 Q! G( T: V
  333. STA PPU_CTRL& ?) x4 O$ k1 y
  334. STA PPU_MASK
    ) F3 M" e" i0 ~% Y. m+ A
  335. STA PPU_STATUS
    , n6 V% _4 `" _/ @+ r+ B
  336. STA JOY2_FRAME( j! s& f: `5 l+ @( r+ v: e5 D) ~
  337. STA APU_STATUS6 t+ Q* C/ W4 }  Q: W2 d0 Z% _
  338. 1 o+ J% c, }% n/ w# X( _
  339. LDA #$C0
    5 F5 Z" ?7 x, C! Z- Z) }
  340. STA JOY2_FRAME# D4 a0 g- Z4 k0 y0 w
  341. % _. l, X  S( o1 A( Z# g
  342. ;等待vblank
    : ]/ s$ K' C* w$ T& v$ x
  343. LDX #$02
    8 y! _+ Q) B' D9 i
  344. Vblank_Wait_19 w: C; s0 w8 X, A. D" K- C6 [
  345. BIT PPU_STATUS: F; @0 {8 z# B
  346. BPL Vblank_Wait_16 S, n5 p6 j+ l/ w; v# |
  347. Vblank_Wait_2- s% T" q8 D, k$ P( K" t3 r
  348. BIT PPU_STATUS; t* ]( c" S3 D, _% h
  349. BMI Vblank_Wait_21 v( l6 e+ ^  T" `$ e% _( v
  350. DEX
    0 M6 j/ S& m& B6 x
  351. BNE Vblank_Wait_1) B" A* U/ S3 H6 d+ b1 z
  352. 2 g" i) u# Q/ P- C. ^
  353. LDX #$FF
    4 b, `- a; Y2 L8 ]! A
  354. TXS/ O1 P# `3 B$ k3 T- t

  355. . L% Y, ]+ ^) L% Z2 g
  356. ;初始化MAPPER19
    % q; A! E7 |' Z6 l4 g
  357. JSR Init_Mapper19; S/ v, I& a  {! F
  358. : L' b* r% k1 c8 a) m
  359. ;==============================+ _. o1 a% A0 ^$ H- x2 F
  360. ;RAM初始化3 |$ r! u: W" g$ p
  361. Nes_Ram_Init
    ; o. Q8 j" e5 M, }. u
  362. LDY #$00% c6 @& W% H: t+ O
  363. LDX #$08
    ) x8 K0 u% J1 N
  364. LDA #$00  q1 O; u& z  ~9 v; E/ H) ~; \* n
  365. STA <$00
    + E! {! P5 d# K
  366. STA <$01
    / p! R, c; a# r& ?, D# b; B/ T
  367. Nes_Ram_Init_Write( J* G3 m9 |" J
  368. STA [$00],Y
    % A2 Z3 K) @/ P% U# ]
  369. INY( `6 C. q" `( G  k
  370. BNE Nes_Ram_Init_Write+ _" y6 z' A: q" T# r3 k+ Y9 l% Q2 V
  371. INC <$01
      r7 y. h! j9 C5 [" n
  372. DEX
    4 w& I5 @2 E% C2 P' j& b
  373. BNE Nes_Ram_Init_Write
    - C/ D; z( |- i7 s4 \/ }) z
  374. : ?" U! x3 o6 Z
  375. ;初始化命名表
    " {% j. F4 z1 b  O( B3 C; h" G: K
  376. JSR Init_Name_Table6 n2 k2 m- o4 X" Q
  377. 6 S% G+ n2 @- J4 P( a
  378. ;初始化调色板* W  }( r' \6 b' D( M% H! p; z
  379. JSR Init_Palette
    , j4 d, L+ {5 D- R0 D# F: z
  380. 6 t+ b+ {& u, Q, `( o. M! o
  381. ;初始化命名表属性
    2 ]! A" y- C# j3 v7 a& g- u* h7 A
  382. JSR Init_NameTable_Attributes
    ! j: b( \& \% \" D

  383. " `% Q5 B+ Y  O% g
  384. ;初始化精灵内存$ }. @+ ?, Q% |: }; d  N* D$ J
  385. JSR Init_OAM_Ram. ~, o8 Q8 Q5 F

  386. 0 [! k: w2 @6 Q
  387. ;在屏幕上写点东西
    " b; Z4 g# G  ?+ j4 E
  388. JSR Init_Name_Table_Text2 v2 I$ S- k$ r, B5 j& G
  389. & F; q) U& b+ K$ b
  390. JSR Time_For_Vblank' J1 ~/ H. ]+ v& d
  391. ;开启PPU控制
    0 s$ f' }1 j3 {
  392. LDA #$A8
      {, G+ O. r" C
  393. STA PPU_Ctrl_Buf" K; Z6 {1 h8 E7 `* ?0 @, i! S
  394. STA PPU_CTRL0 d# e) h; C5 r4 U2 d5 A7 v

  395. 5 Q1 A0 |- w8 u4 h
  396. ;开启PPU显示9 ~+ `$ h) m  j. _1 ~2 M
  397. LDA #$1E
    $ Q' g/ v1 C' x4 e) [- }1 p
  398. STA PPU_Msak_Buf$ I9 i% E: b/ Y3 S/ A9 D
  399. ) u/ C5 q4 }  X+ G
  400. CLI# K& I/ `$ H; `7 e; u
  401. JMP Loop
    & d0 p9 b. t4 I. H5 o! T8 H
  402. : Q3 Z9 D! W& ^
  403. ;==============================
    & d6 S5 l, p9 t$ g
  404. ;死循环, 等待NMI中断
    3 X' N" ?2 ~; R9 E) P( r
  405. Loop
    4 m( [5 f+ E0 v! v; @: _  v) r/ @
  406. JMP Loop
    % K( [2 Z( |& X

  407. , Y' U! z5 H  Z: I- G$ L
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967. _( q* l# U9 r) R
  409. 1 e) _! d1 l% Q9 v+ x$ [
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)& d* m4 s" f/ i: g7 L
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    * I" h; m& K* M: y" k3 A7 w
  412. ;==================================================+ Q, G1 P$ ?/ g+ s9 p) ~1 a
  413. ;NMI中断处理4 w3 U( {8 \) J" `& F
  414. NmiProgram7 x( [. K1 c$ n9 u
  415. PHA. W7 b2 b. V: o6 x  j2 V. p7 E. x
  416. TXA" y) w! r2 m% t* T4 h! Q  t5 o
  417. PHA
    1 u- p$ k# {1 o  p5 b0 D9 B
  418. TYA
    + H. N4 L. W/ S6 ^7 Y1 }
  419. PHA2 O/ q, [9 H+ Y- G
  420. ' w( e+ U. _$ E& V% _
  421. BIT PPU_STATUS
    4 d3 c7 y9 r0 k3 o& g! ^4 t

  422.   f9 A- n% s7 p; t# r# }
  423. LDA #$00
      w+ a+ e" _+ m( m1 [, ]
  424. STA IRQ_Index- ]6 M9 ^7 e) g, V. l/ p: ]

  425. 5 Z- L7 u- F2 }. E* c1 `0 e
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    2 s* _6 u" l0 y  u1 o2 ~
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    . m2 S: z" ~( m5 a9 ], v+ {9 p& A
  428. STA M19_IRQ_COUNT_L
    3 d( e9 I) w* Z
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ) R  r$ ~& ~7 I
  430. ORA #$80
    8 ]& [( g. A" M  J% D
  431. STA M19_IRQ_COUNT_H
      N2 z' g3 D8 J. D: Y, O8 ~  ~
  432. CLI
    3 J5 g4 s5 l- @5 W/ Q0 h( c$ T3 X
  433. 1 i; `9 m) A9 K8 Q) b) D# |$ J$ Q" @
  434. ;关闭PPU控制
    7 h+ k- V6 P* |
  435. LDA #$00- H0 Q! R3 [) D- q9 K
  436. STA PPU_CTRL6 w' n* F/ i, u- D5 P: m' B2 y

  437. % [2 N6 ^0 V- i- e7 L) T
  438. ;处理PPU
    ! T3 O; T+ i- R1 D* j6 A! s# E/ I
  439. JSR PPU_Process, }4 {/ x' T( F! d. G

  440. 8 x* q) B3 X. W! ]" _
  441. ;开启PPU控制8 r/ x( A" `; `$ E3 a2 K
  442. LDA PPU_Ctrl_Buf
    " T4 h) b% }: K! m
  443. STA PPU_CTRL
    , a% _, t( C$ L! f" q# y

  444. ! g- U7 l) {- V. D2 v
  445. ;手柄处理
    ; T6 F! e+ L  ^& N
  446. JSR GamepadProcess
    6 c* m% k% d0 A& j# ?. H% J

  447. , f% J* i& C8 I8 ~
  448. LDA #$00
    1 x9 X, S9 R3 _+ U' D% J
  449. STA IRQ_Index
    & T7 u6 \& O. f! m
  450. 0 J) g/ T$ t  j8 ?
  451. PLA
    3 P, J; Y8 G; F* e, b9 w
  452. TAY  z- e* w: @7 D! w2 m: ?1 {& l3 @
  453. PLA' R* h" p1 |9 \8 B
  454. TAX
    # O8 W- g) ^' ~' _
  455. PLA
    ) `6 H$ F  c5 c8 I4 J; S* B
  456. RTI# j  u6 Q7 x4 k5 P( ^' N4 F
  457. 8 F' d: K! d3 o
  458. ;每行扫描线113.67( m1 c+ x& h. [1 a, E6 y5 o
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)) M& B% N7 U5 E. M1 D
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    8 B% v. y7 q" D1 T) x
  461. ;==================================================
    : l) Q" r4 P6 L# u% g* l8 l! l3 K8 s
  462. ;IRQ中断处理
    * }% P! _( M+ ^( z; Q
  463. IrqProgram
    8 Z+ Y& M( q5 `3 c3 H1 V# r$ K8 P
  464. PHA
    , _5 [  {2 ]. ^0 `! K6 T. Z, g
  465. TXA
    & ^# z1 P: G$ T+ t$ `4 s
  466. PHA
    ) E6 C; P: H  K8 t# S* r- M
  467. TYA# Z/ x2 o: W/ X3 x2 u. J" Q
  468. PHA1 k6 K- [. u, B, e! o$ l  }

  469. 7 w' q2 G; l$ ]3 |- @, ]6 T
  470. ;16条扫描线后触发IRQ
    ) l4 r0 J, o% k, L, u3 K
  471. LDA #LOW(BEGIN_LINE_CYCLES)" t# P3 X! E. ]  I! @
  472. STA M19_IRQ_COUNT_L3 Q- d/ }5 d3 s0 J/ a
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ) R/ E) A5 t/ g( I
  474. ORA #$805 a0 N: @6 s' N* ^7 O) A
  475. STA M19_IRQ_COUNT_H2 |5 |2 A' [4 ~, X7 T" g

  476. ! v1 F6 M' y& S  d8 Y5 x4 A6 Y! b
  477. LDA <IRQ_Index
    $ u" e3 S8 M2 j. k" K9 z
  478. BNE * + 43 @# @; k& \4 y) T; y7 n3 l
  479. INC <PPU_Scroll_H5 O# Q: P# v" O1 \  v3 j
  480. 3 j5 j  Y) M0 u
  481. ;设置屏幕滚动& |* _2 K" @' R5 |
  482. LDA <IRQ_Index
    * [! A% X( _* q* K
  483. AND #$01; [1 J' V/ V5 O+ O5 ~
  484. BEQ Irq_Scroll_Right
    % K- ^7 G/ r" i! P- c) N

  485. + A0 B. w4 _2 N% V1 o  `
  486. Irq_Scroll_Left7 l9 e- p( F4 `' b. z$ w* [
  487. BIT PPU_STATUS
    5 A6 a& b$ T' a; Y) f& S1 s4 t
  488. LDA <PPU_Scroll_H
    6 ~3 S/ t' H! s. @. R2 a
  489. STA PPU_SCROLL
    ) _; ?7 T& x% g$ b9 t2 `
  490. STA PPU_SCROLL5 p/ ]1 |: @! ^# H1 N- f& {" J
  491. JMP Irq_Scroll_Over0 {1 j+ `) Z$ t

  492. ; T) W! a" C! q/ F: @/ K# W* B
  493. Irq_Scroll_Right
    . E+ y2 U- X/ \* u
  494. SEC
    3 \0 J* q! ?/ M$ p. ~8 p! n
  495. SBC <PPU_Scroll_H
    " S, l& m' C+ T( \5 j
  496. STA PPU_SCROLL/ l+ d, @( I& u( h
  497. STA PPU_SCROLL4 U1 ]  Q4 H; \5 t# ]0 j/ Q. L
  498. Irq_Scroll_Over
    ) q- \+ I, P" N$ }$ J$ A3 B9 L
  499. : n+ t' d+ x+ J  k3 `7 K
  500. INC <IRQ_Index5 G- [/ V8 B4 C

  501. ) i) ?5 ~5 z5 C3 j* ]
  502. LDA <IRQ_Index, J$ ^& o2 I4 f, Z+ Q9 n
  503. CMP #14# }& D: [% p( u4 M4 k
  504. BCC * + 10
    . V4 z! O) j. V* `
  505. LDA #$00, _; U; w. |5 u+ Q- _
  506. STA M19_IRQ_COUNT_L
    ) U+ b0 q9 |/ @6 y1 \5 b
  507. STA M19_IRQ_COUNT_H0 y2 y8 M  f7 R, M1 a) s
  508. % F# y. j, O& p- ?9 f' t" `& g: K
  509. IrqProgramEnd
    + Z& ?: p6 C! l, k* Z
  510. PLA$ a8 a9 b% p! e1 L
  511. TAY2 L. r0 ~" X- ]6 U" k+ _
  512. PLA
    + X/ O; P% f: d* [" a
  513. TAX# B3 Y, {, y/ ?  W
  514. PLA
    + ^% d; z/ L, B9 o
  515. RTI  p1 K# \0 U9 |# Z3 F

  516. # d- V$ S7 E! I/ ~6 |
  517. ;==================================================0 ^" w. c3 H  ~
  518. ;中断表
    5 P4 _( a5 w# y0 _+ V
  519. .ORG $FFFA- m  U  _' ^3 ~; E2 X* `
  520. .WORD NmiProgram! M& x) w  c, n& u
  521. .WORD ResetProgram
    2 B9 ~8 q* f5 W% x
  522. .WORD IrqProgram
复制代码

9 v" n7 N. C) w; }8 F

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-6-8 17:36 , Processed in 1.110352 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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