EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    ; g9 B: y+ B; Z4 A3 b( r; Y% v
  2. ;FlameCyclone 20230710
    2 m( H0 A' I6 R( x9 h
  3. . m' P5 q% A. b, e/ m4 j
  4. ;文件头
    / Y8 O9 X7 J% M; X7 f7 a% M* l
  5. ;======================================================================
    ! A) q6 z6 D( i/ h! A
  6. .INESPRG 4                                              ;16KB PRG 数量
    + n( [0 c4 |. W6 V( W1 Z/ Q
  7. .INESCHR 1                                               ;8KB CHR 数量9 Q( i* |" F% e8 g2 e. G: m' y
  8. .INESMAP 19                                                 ;mapper 19) z4 D' Z+ L- ~; W
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    ' F3 s: L/ J3 g5 d# F; f3 s% k

  10. # a6 N& q& z' d% B; O4 y
  11. ;必要条件
    7 U/ M4 C' _0 ^3 R
  12. ;1.持有CHR ROM1 x0 C7 @/ a/ L4 s( l
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
      X! F; ?8 b& q" D
  14. ;3.精灵内存(OAM)不为空9 H& S) o& F5 Q* t- h2 s* u4 |) x
  15. 9 ~: `# N/ {+ k1 a- A  c
  16. ;==================================================
    5 `3 h+ w2 z) [; E7 D9 B
  17. ;NES端口常量5 k# K$ [( s9 n2 b& M& n) t2 V
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器% c$ J. b- D2 b! G1 K) r
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
      Q: S( G: O8 r: K/ P
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    ' X+ |; x- R9 p$ l/ ?
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ' w; a+ A6 t+ I% R
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1' I8 M9 u9 ^, c+ w, f2 z
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    4 p7 n7 G" r: V0 `1 ?& L
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    : y% O7 V8 H& U( s
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    , U% C! @' o) |/ P, |5 o7 ?  [3 r
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ( M8 G% s$ p; h( u
  27. APU_STATUS              =   $4015   ;声音通道切换
    & z3 {$ F, m; |6 x8 y, [7 ?
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通, I! J( H( a5 z. \: r/ W
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    $ r: g5 n# Q' D$ o  f  i. v  O9 ]( q
  30. - }3 V6 j6 o8 u
  31. ;==================================================
    5 p! r3 T5 Y) }8 R$ E) F. \
  32. ;MAPPER 19端口常量8 V$ M) u2 l  z4 n5 z
  33. M19_CHR_0000    =   $8000
    & \7 D# v( Z1 f) D: f% v' l
  34. M19_CHR_0400    =   $8800
    $ M9 ~" s1 W  W$ C, h. s
  35. M19_CHR_0800    =   $9000
      z7 p8 h: F# A5 H' a" K- Z3 G
  36. M19_CHR_0C00    =   $9800: H( }% M. b. c& I& b' B
  37. M19_CHR_1000    =   $A0008 L3 c- g$ k% Z" [/ B4 D
  38. M19_CHR_1400    =   $A800& H; L/ y( x9 b7 s  S- {
  39. M19_CHR_1800    =   $B000
    7 W' ~3 f1 W& G* f) H$ Q% ~6 [( z7 x
  40. M19_CHR_1C00    =   $B800
    " ^8 j! Y; @+ B6 ]" _( I
  41. M19_NT_2000     =   $C000# A' n6 ?! U. C7 R" D
  42. M19_NT_2400     =   $C8009 w5 I( E! O8 i, F& D$ g- W
  43. M19_NT_2800     =   $D0002 n: c9 H3 m  H% B3 w& U
  44. M19_NT_2C00     =   $D800
    ( S" m% d" R4 l8 t- H" G9 R, k
  45. M19_PRG_8000    =   $E000+ q! K" J, L* w! I2 P
  46. M19_PRG_A000    =   $E800
    : }; \9 q2 l! m
  47. M19_PRG_C000    =   $F0003 k* A/ k* e5 k) N4 Q( g& {5 V' z
  48. M19_IRQ_COUNT_L =   $5000
    " y' x, N2 [7 K) m' {& k
  49. M19_IRQ_COUNT_H =   $5800* Z- f/ U  O5 _) c

  50. 4 B# x! ^6 z, x  F
  51. ;==================================================
    ! d! H' V/ |3 R" N, D6 a
  52. ;程序块配置6 v4 }5 Q1 |) [! ]  e/ F
  53. BANK_DATA_MASK          = $07
    & s, y. J& a" x8 |1 N# J5 y7 o
  54. ;--------------------------------------------------# j" N: V. f' O& o2 E
  55. RESET_BANK              = $079 r+ n+ U1 F$ _
  56. RESET_ADDR              = $FC00# H. ]* q9 i# ?1 L% J# L9 \

  57. 6 D- e2 }6 M* ^
  58. ;==================================================7 }8 |4 W2 Z( j% u. M7 Y. Q7 j- m
  59. ;图像块配置
    * H2 q  W) Q, ?3 g) Z: v8 D
  60. CHR_DATA_BANK           = $080 e% S. G+ Y1 N8 H7 R1 X. m
  61. 3 w- F5 G# Q+ s) k7 n
  62. ;==================================================
    0 b& l( t& [& b4 W! x7 ^  ]
  63. ;零页内存地址配置
    ) z: k0 G( ^% x7 S
  64. Use_Ram_Addr            = $807 @# Q' d6 r, e1 W2 S& i# n
  65. PPU_Ctrl_Buf            = Use_Ram_Addr1 h3 f9 A" S8 P7 g  i( W
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    , q1 L/ ^5 }3 b; ~5 z
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    9 M9 Y8 d! F- {$ q4 U5 N
  68. PPU_Scroll_V            = PPU_Scroll_H + $016 {3 [$ u* D2 h" c  e6 k
  69. FC_Data_L               = PPU_Scroll_V + $01
    7 Y# o' V( r/ d; }: o; \/ \
  70. FC_Data_H               = FC_Data_L + $01( s! G( R4 B6 }$ [, q+ G  p6 j
  71. FC_Data_Buf             = FC_Data_H + $01  j# i$ ?* m; N. y2 a: l
  72. ;==================================================# b* i' e. j- s4 @/ n0 D

  73.   A4 g+ Q# d6 y' f
  74. GAMEPAD_MERGE_FLAG = $04
    3 C" G3 V; Q; {9 ]( y; m0 \

  75. 0 H3 Z+ ]& a* s  q# m( X
  76. Gamepad_Keep            =       FC_Data_Buf + 1) A9 C. X! w# y6 v1 _
  77. Gamepad_Once            =       Gamepad_Keep + 2
    2 l$ O# N/ Y# f2 L+ [" t3 @
  78. Gamepad_Temp            =       Gamepad_Once + 23 S: k. p2 l) \( W( H
  79.                                 
    7 e) E/ B7 y  }0 A4 [
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    ) e2 z1 ~& D1 d  G, l3 v7 G+ b
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ! n. [6 ]) \; Z( E6 F% N  }
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    / r% x5 H: a4 P! F( O  T+ o& o
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    1 H2 X0 W2 z3 |) Z
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    9 k: v; a& ]9 {8 M; N& c- A
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    % A5 @9 |8 B  D( H
  86. + j6 [- ^) Q- }0 q2 b. ?5 o/ ]3 \4 f
  87. ;==================================================
    4 D) r5 G; R5 K5 F# i. z
  88. IRQ_Index               =       Gamepad_Merge + $01
    7 n1 ?% D5 t! ?, K0 [# E1 m
  89. ;==================================================
    , l/ }3 y$ V+ z) R
  90. 3 }( P3 J* F9 d5 W  X2 n
  91. ;CHR图形数据, R* U; ]8 p' b5 o% l. a6 y% v
  92. ;==================================================( h) V8 C3 A9 R+ j0 d9 X
  93. .BANK CHR_DATA_BANK
    % K2 c7 K! x3 U# w
  94. .INCBIN "chr_bank/chr_data.chr"0 A- A/ D' }3 p" G- m& F! Z9 i
  95. + g1 x) L4 K! S5 N- ^
  96. .BANK RESET_BANK & BANK_DATA_MASK
    - G# z5 H8 {5 f7 I
  97. .ORG RESET_ADDR
    ) i0 i8 x7 G, y2 ]
  98. 3 F+ s( u: h5 y6 E. u+ ?1 o
  99. ;--------------------------------------------------
    " Q$ e1 |9 H9 ^; K2 V
  100. Attributes_Data
    * y3 k/ S( m2 ]* d! h+ W: G- l
  101. ;命名表属性9 O; ^: a/ [/ h/ g6 Z+ S. n. l$ W
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    3 G. [, _! ^; p4 n/ Z# u" X6 O/ a7 X
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA/ o5 Q. ^: V+ w7 ?& u) W7 B
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    , b, I7 A: w3 e5 O" W% ?7 C
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    * c# F' L# @9 f! ]7 r2 w
  106. ;--------------------------------------------------
    9 r8 {5 y2 |- o; i! V: {! @9 K
  107. ;调色板数据
    / U7 ]; v6 m( j& S( n9 d: D
  108. Palette_Data
    ' h" p, v2 d3 K  N7 P
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F5 d8 r# M+ x% ]: ?
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 Z) R% x& M8 u9 {% b* K- e% x

  111. ! U) e, n7 F1 o0 S8 K( |
  112. ;==================================================1 B" g  x+ U" Y( B- n% k
  113. ;命名表初始化7 w! d: i( `! p0 }9 W; |
  114. Init_Name_Table5 f5 d: f$ A7 N
  115. LDA #$202 Q5 k8 _. N+ [8 @4 ]9 S2 d/ e
  116. STA PPU_ADDRESS& U6 K4 \# x) N' }
  117. LDA #$00& k5 Z0 b8 F, c# }5 G
  118. STA PPU_ADDRESS
    6 w; Z3 ?4 f8 b" U
  119. LDA #$006 e3 K  l" t# ^3 E+ v
  120. LDY #$00" Q, r" l! T# Q- X4 b* o
  121. LDX #$10% u4 l* B6 L# j
  122. Init_Name_Table_Write
    # {( c9 D% k2 I- K
  123. STA PPU_DATA& `+ D$ c3 P- q/ x' j& ]
  124. INY! V: t4 I/ U8 j, a1 ^4 ^
  125. BNE Init_Name_Table_Write
    6 n$ i& h8 Q, Z8 L# S9 q  U
  126. DEX; H! y1 V7 ]3 t0 Q3 v; f9 M0 v
  127. BNE Init_Name_Table_Write
    5 m$ W1 n3 _4 J3 I1 q5 d, ?; n7 ~
  128. RTS, y. i0 n! y: K
  129. & u* M0 p/ F3 L
  130. ;==================================================
    # K8 l% C8 h$ h' W4 w$ Z
  131. ;调色板初始化$ K; d8 N; T) y3 g0 r2 `
  132. Init_Palette
    0 ~9 K3 f( `" M5 ?9 i' g
  133. BIT PPU_STATUS
    , ^$ O2 T" \$ W: d* i) A; t$ Y
  134. LDA #$3F6 G) N% o1 b& T5 H$ B1 R
  135. STA PPU_ADDRESS( u1 v$ z) C! a" \% U6 ]
  136. LDA #$00" z) u" j1 Q2 T0 p
  137. STA PPU_ADDRESS& R: X* z" g0 _
  138. LDX #$007 E& o$ L$ a$ }( X; [4 R  f5 F
  139. Init_Palette_Write# m8 V, K3 T( D; J
  140. LDA Palette_Data,X% n; {9 D% u7 o. W3 Y1 w; J
  141. STA PPU_DATA
    - E) }. x- U7 [1 _; x3 _+ a2 R
  142. INX3 V, m: _& V' V: x
  143. CPX #$20
    $ N4 \2 `( A3 Z1 q, ?, s: d; s
  144. BCC Init_Palette_Write
    - L, w9 w+ M9 g5 Y4 X3 Z" `1 @
  145. RTS
    & W' l7 J) M/ v, M

  146. 0 m& }7 ]& i! |/ B& W( @, D5 g1 s2 y
  147. ;==================================================
    * B' x/ s4 T# Y/ ?) i3 H2 v0 }
  148. ;设置命名表属性2 v3 |' T4 t- R) Z* U+ y6 z" i
  149. Init_NameTable_Attributes
    6 C" u4 k& P2 w6 O  H/ q
  150. BIT PPU_STATUS
    ( e1 ^/ O0 b, u/ }2 |
  151. LDA #$23
    0 ]7 b" N1 `# x% d, f2 W  J
  152. STA PPU_ADDRESS
    3 Z. H% K9 u6 z/ S8 S# a; u
  153. LDA #$C0
    4 j; e4 S7 G  Q. i
  154. STA PPU_ADDRESS
    & s5 _" {) u7 w
  155. LDX #$00& |! O! @6 @% ^
  156. Init_NameTable_Attributes_Write
    ; d. w" \5 |4 W8 C
  157. LDA Attributes_Data,X
    1 a8 z. j1 w9 x4 v- W( j, b
  158. STA PPU_DATA
      K1 M0 f" j8 L4 h! x5 r& v
  159. INX
    ) ?# I8 h0 g6 j7 @; `8 J1 E
  160. CPX #$40
    2 l- @( d) d& b7 B
  161. BCC Init_NameTable_Attributes_Write
      V7 B9 P9 ?8 L  A& k) q; A' @
  162. RTS4 S( y4 W3 e7 n! @! m( r3 d
  163. 2 Y' l; h( p" o, @2 L0 m" m9 g1 ]
  164. ;==================================================5 C) b+ a4 `& h' M& i6 {
  165. ;初始化命名表文本9 \; p7 E( B, y5 Q, u0 \, O8 l' [! ?
  166. Init_Name_Table_Text
    1 C2 x% @% m2 Q9 w% D
  167. BIT PPU_STATUS
    " E  S' l7 i0 l
  168. LDA #$203 }, l9 a' o: H. N0 N
  169. STA PPU_ADDRESS
    : @: j# w4 M% J* J( |
  170. LDA #$00- o, Y2 c  B9 s; Y9 T: J$ x
  171. STA PPU_ADDRESS) F: N* \6 }0 q8 [1 ~1 {
  172. LDA #$00; j& V' ]1 f- I
  173. STA FC_Data_Buf
    $ C) @* a  n: z3 f
  174. LDY #300 e' S& ?& r4 Q, R4 g2 d
  175. Init_Name_Table_Text_Write/ Z% g3 w* {% q. C; ]
  176. LDX #32
    : n- X& ]& [, @( P$ O
  177. Init_Name_Table_Text_Write_Char
    8 ~& P/ H( \- i5 L
  178. LDA #'0'3 |& z, J3 |4 K
  179. CLC% k( y- z2 G2 T: g/ S9 K0 n. |4 w% w
  180. ADC FC_Data_Buf
    ; `& O5 E% a8 `/ p
  181. STA PPU_DATA
    2 v+ x  v1 i! O6 P3 a6 z- Z) U
  182. DEX
    9 R. j: k5 P# n; I8 |
  183. LDA #$146 u' Z& X4 v; v0 N5 s
  184. STA PPU_DATA
    , Q: T& Y) I1 I5 L
  185. DEX! W9 u8 E! h- M" U6 ?
  186. BNE Init_Name_Table_Text_Write_Char
    # T! y/ E5 ?. P6 o7 W7 L2 }+ b
  187. INC FC_Data_Buf
    * s% b, K9 `3 `
  188. DEY/ \2 a1 \$ s0 L5 r7 _- z* P
  189. BNE Init_Name_Table_Text_Write, U  A- u5 M! c6 F
  190. RTS5 b7 ^9 }0 A0 P* T5 Z0 M  m' y( Q

  191. : |  m2 |" ~: J
  192. ;==============================5 g& [7 i) u* {' y
  193. Init_OAM_Ram;初始化精灵内存
    2 C/ c4 G6 g& h9 |6 J+ g
  194. LDX #$00$ f& y+ A; V% }/ f, P) m: }
  195. LDA #$00& I& }6 B) U  H" I/ y
  196. STA PPU_OAM_ADDR
    # a1 t9 M; N* v+ |! Q! L  D
  197. LDA #$F8/ g' Z$ z6 G: n5 W3 Y
  198. Init_OAM_Ram_Write& H2 P8 j; u) H9 t3 v
  199. STA PPU_OAM_DATA
    ' m) H3 t5 L$ Y, X0 `; r9 X! V
  200. INX
    3 J6 X/ f" s3 [8 h1 C, c
  201. BNE Init_OAM_Ram_Write
    1 g  I8 ^& b; B: w; G7 g( F( x% N
  202. RTS
    0 v0 n  G6 ^$ a; X

  203. 9 \7 `! \6 j1 N3 C5 V
  204. GamepadProcess;手柄处理
    - n) \1 E- G5 O$ [7 A( J6 F
  205. JSR GamepadDatacan+ m( `$ d9 Q6 Z, e' A, q% w6 h
  206. LDA <Gamepad_0_Value
    3 N5 U, u, f& b0 t, ~
  207. STA <Gamepad_0_State5 w$ w1 \' O4 z, ?
  208. LDA <Gamepad_1_Value
    6 l5 X; W8 d% S4 {8 d0 w
  209. STA <Gamepad_1_State
    8 X3 g% S2 U8 P4 }' }
  210. JSR GamepadDatacan
    0 b6 A: w/ p6 C( l
  211. LDX #$01% u8 r$ \7 [+ n, ~; D0 {
  212. GamepadMergeCheck;合并手柄输入检查
    9 B* v( e7 x1 A8 \0 R$ y5 Q
  213. LDA <Gamepad_0_Value,X2 Y0 }! S, Z6 O
  214. CMP <Gamepad_0_State,X9 d3 Q9 K/ t. R! H3 d# k
  215. BEQ GamepadMergeInput
    6 M! f' X& w# R0 I, z' ?: F0 @" s
  216. LDA <Gamepad_Temp,X
    & ^* H6 c, g5 {8 d# s3 [; G8 \
  217. STA <Gamepad_0_Value,X) z0 C; m3 @& s5 Y: b, Q
  218. GamepadMergeInput;合并手柄输入
    9 f. ^& \% B& X& o
  219. DEX
    # s& q& g; e; v/ ?  U$ r
  220. BPL GamepadMergeCheck9 t0 B4 U( E- b% m
  221. LDA <Gamepad_Merge
    ; X* c3 I5 g- o6 r$ a; }
  222. AND #GAMEPAD_MERGE_FLAG
    ( \9 j3 }' f9 m# [
  223. BNE GamepadStateProcess
    3 |) r: }( S* C9 ]4 i9 ^0 W
  224. LDA <Gamepad_0_Value
    , h1 ~% P& I' J2 k$ n# L: E
  225. ORA <Gamepad_1_Value+ \% Z1 ]  p3 X! C+ t  U( H$ E- r4 k- i
  226. STA <Gamepad_0_Value
    : [7 x' m- @7 L0 A4 \1 e5 P
  227. GamepadStateProcess;手柄状态处理
    3 H7 O5 o- v' t. t
  228. LDX #$01
    % K/ ]4 _* {+ C. r# e& G! t) x7 y; E
  229. GamepadStateSave;手柄状态保存; p: \: y) z$ I2 X( ]4 p
  230. LDA <Gamepad_0_Value,X
    ( k3 p/ \) A+ S* ~3 V2 T9 e
  231. TAY: ~/ k+ y/ g0 ^! m3 K1 @2 N
  232. EOR <Gamepad_Temp,X# V2 [* ?( o$ o
  233. AND <Gamepad_0_Value,X; f- }  K$ r  |7 w! z" q
  234. STA <Gamepad_Once,X8 Z/ e2 T) t8 A; N  ^  a+ d! n: Y
  235. STY <Gamepad_Keep,X% W+ l& W2 p. {, X3 N
  236. STY <Gamepad_Temp,X6 N. A! |, `/ M6 a4 n
  237. DEX
    % h2 g0 u+ l1 |2 X
  238. BPL GamepadStateSave3 ^0 G0 F1 Q2 r% ?) K
  239. RTS5 q) u: l  f% s" G* z9 x
  240. ! X9 m( Y8 }3 g: p) o! N. m  j4 R
  241. GamepadDatacan;手柄数据扫描
    ! |7 C! D: V9 q8 n; _% i: T3 ?$ w
  242. LDX #$010 f0 H! E, p; I3 L2 I
  243. STX $4016$ d3 p* g: {0 M/ A  ?3 L* q7 `1 q
  244. DEX
    1 P2 |+ d9 ], Z2 j. N
  245. STX $4016
    6 i  M" F) A- M8 Z! b
  246. LDY #$08
    . V1 \' J9 E  P  ]1 i$ X
  247. GamepadPortScan;手柄端口扫描3 o+ \0 u. o, J# f5 ]3 y. _6 A
  248. LDA $4016# I: R% H* d5 T  e: [' K; v
  249. STA <Gamepad_Port_Value
    1 |6 o0 a, s$ J8 D8 O/ X* F5 Y
  250. LSR A, l+ ~9 o" M" `
  251. ORA <Gamepad_Port_Value
    3 e7 s; k# H+ a% _( F
  252. LSR A" j) x2 }3 d* X6 i+ O8 ]0 ^4 l
  253. ROL <Gamepad_0_Value
    / j9 w8 c" @$ h) u# \; W
  254. LDA $4017/ U9 ]# ?7 ~3 H( ]' t
  255. STA <Gamepad_Port_Value
    + q! a) w7 u- v3 f# h
  256. LSR A
    3 k, s7 E5 A7 ~, S! Y$ V2 c
  257. ORA <Gamepad_Port_Value
    ; B/ n; s1 d, ^3 `
  258. LSR A  ^5 ~# ^2 d  D7 w9 b
  259. ROL <Gamepad_1_Value- F+ `7 L) I5 q7 }  h" G! L! R
  260. DEY
    + b+ p6 C, B( C3 ~' D
  261. BNE GamepadPortScan
    - A3 W2 M8 Z% J/ e. P2 R
  262. RTS
    2 u% w8 Z; `" f' c: A4 b# s% u

  263. $ D* b- C8 {; i1 l
  264. ;==================================================
    5 y* B, q8 T( |; _# ~: D
  265. ;PPU处理4 w/ o/ ^& v  g& u1 n6 t# G, j
  266. PPU_Process
    ! k- q' M, w! B0 \' }& k
  267. LDA #$009 U  A  w# n) z) O; e
  268. STA PPU_MASK
    9 C. @( b& W2 o5 e
  269. : `7 M2 Z$ d; _; o2 K9 u% H6 Z9 m7 g
  270. BIT PPU_STATUS
    . }9 W& P, K0 \6 z! r7 L: u
  271. LDA #$20
    1 B- |  [( H8 j0 E: N0 w8 x
  272. STA PPU_ADDRESS
    2 {+ W6 y/ L5 }
  273. LDA #$00
    6 M' y& `; G! ^" O6 M6 @
  274. STA PPU_ADDRESS  @% N. _5 u, J, w
  275. 7 ]: a5 n6 p' X3 [$ z$ X" J5 |
  276. STA PPU_SCROLL# @1 B. g. I5 B0 V0 H
  277. STA PPU_SCROLL7 P' k: n. I& S9 }

  278. % y, u5 e! [$ V# \7 x
  279. LDA PPU_Msak_Buf2 z4 k2 @& ~& p7 e
  280. STA PPU_MASK
      q- K  l! c1 e( A

  281. 0 z( d* O( `3 X4 W" {# j1 B
  282. RTS- Q$ B$ P" b5 u' {: U3 m2 M5 N! M
  283. " I. s+ ~) T1 Q- G& T
  284. ;==============================9 ?3 g& w, k; J9 m0 v
  285. Time_For_Vblank;延时等待
      ]* ]% M* h+ c; J: T8 F8 a
  286. LDA PPU_STATUS9 \" z1 {6 @7 P. x5 R; M
  287. BPL Time_For_Vblank3 o8 f4 e' q( z: f3 n( Y4 ?
  288. RTS
    & L2 u5 [% q# }" ~0 i) B; _7 L1 A

  289. . L# q0 }2 Q& P% H* k
  290. ;==============================1 x. d2 S# X: ~1 o
  291. ;初始化MAPPER19
    5 A. a2 I, x/ ]8 O9 p6 O4 @
  292. Init_Mapper19; Z$ @% {6 Y" X/ Q
  293. LDA #$00
    ( I5 m/ S+ V+ `  y
  294. STA M19_CHR_0000
    ; {9 S1 r  ^9 C# E6 E, ^
  295. LDA #$01
    : k! K! f% V. Q0 b4 m- v! Q! m$ r
  296. STA M19_CHR_0400/ z! O& q' X7 ^6 ]; l
  297. LDA #$027 E9 t# C, z$ k5 B% n' v; v
  298. STA M19_CHR_0800! i  I' p) f/ Q1 i
  299. LDA #$039 C8 N1 H* }5 Z% h" c; e8 X6 D! E
  300. STA M19_CHR_0C00
    $ m' q; F" A1 G' x' R
  301. LDA #$046 P* ~' a( G6 n. q- F& K7 ^* l: M
  302. STA M19_CHR_10007 ^& Q* |5 ], k# I% _% f2 X- B2 z
  303. LDA #$05
    ! I4 r: l6 l+ D8 [8 z3 S
  304. STA M19_CHR_1400
    , E, A: x( e$ a# Z, E+ ?
  305. LDA #$06
    ( U  @, B3 G) O8 X, Y
  306. STA M19_CHR_1800# H4 E( k2 `. J6 h
  307. LDA #$07% f2 S. Z! v9 D. @6 A' V. B
  308. STA M19_CHR_1C00* [5 B6 h& u( m; g9 W/ a

  309. - i+ m/ A- K# h+ Y! Z) p7 x
  310. ;禁用IRQ
    " {1 K1 v& g! K- A; \0 I
  311. LDA M19_IRQ_COUNT_H, `* T: O) G6 y0 A3 E, D2 N
  312. AND #$7F8 @# u# Y$ S+ x. \
  313. STA M19_IRQ_COUNT_H
    ! l! d0 `: B) h% v/ e+ j7 p1 ]" d

  314. 1 ]9 d# P8 p" a9 R( m
  315. ;命名表, z# a: \+ N( F8 J; t2 I
  316. LDA #$E0( w6 o' k6 U+ k* T9 }9 A
  317. STA M19_NT_20005 \# W" k' r* i  z/ [9 _
  318. STA M19_NT_24000 n4 l6 u0 n. B) Z% `* p) f
  319. 2 M3 d* k0 V/ E3 p$ w! [
  320. ;命名表
    % f1 C1 _! W8 M* ?0 x, ]$ |3 m
  321. LDA #$E1) Q; t8 [+ y, T# G& Y1 g& }
  322. STA M19_NT_2800
    0 W/ i, e- g" N9 w9 [
  323. STA M19_NT_2C00
    1 `5 m6 Q; _) Z6 A% S0 ^
  324. ( F( D, y2 T: U$ D& W" O
  325. RTS
    ' H% R) Y6 p  ^' F, r
  326. ! B& M. q# B4 y5 S: @  s
  327. ;==================================================) G  u- s9 y; q# Z8 c
  328. ;重置中断处理2 d9 O1 @' _" b
  329. ResetProgram
    ; v: W& r. D, F+ X1 G% S$ Q
  330. SEI
    " N8 W$ l+ D" c( r) S! o
  331. CLD, o3 x: w% _/ P" j  e
  332. LDA #$00; E( ^- H& o- I2 j" E- `
  333. STA PPU_CTRL
    ! [1 X& ?3 A3 V! P( V4 k2 r# u" U
  334. STA PPU_MASK1 N# [1 S& w2 c5 ^6 `4 R4 B1 l
  335. STA PPU_STATUS9 ^  N) x/ o( H
  336. STA JOY2_FRAME: U5 y  a4 F0 w2 n  _3 H" A# i
  337. STA APU_STATUS6 o  R/ ^3 L+ s+ F# L3 V
  338. ! M0 A: c- j# V: n8 ]& _" q2 q) i
  339. LDA #$C0
    " ?3 b5 v) m8 }
  340. STA JOY2_FRAME
    1 ^. @3 b9 h( I
  341. ' G7 N3 _* m/ |( T3 m
  342. ;等待vblank
    / M* t' i1 O7 l  A
  343. LDX #$022 Q2 y9 \+ P% D9 ], `+ j% D5 S
  344. Vblank_Wait_17 R# @  ^) N  q( b6 i7 k  ]
  345. BIT PPU_STATUS
    % ^; [& I+ R2 H/ p1 @2 o, X
  346. BPL Vblank_Wait_1
    " ~/ U+ a% E7 ^/ f8 g% `1 v! ]$ Y
  347. Vblank_Wait_2, ]- `% L9 _* W+ z7 F
  348. BIT PPU_STATUS
    ) X4 _9 V; @+ H6 \9 y4 C
  349. BMI Vblank_Wait_2
    : [- g# q* C) q' X  u& I. I' \4 o
  350. DEX
    4 @3 L7 q9 s; `
  351. BNE Vblank_Wait_1) v: Z& @. f6 ]% U5 e

  352. ; V& D1 b6 R" J/ t; R: d
  353. LDX #$FF
    0 Z0 m9 z8 k8 S: h' H( J! l5 F
  354. TXS2 O$ q& z3 w) P) F
  355. ; B. Q% L1 z% A
  356. ;初始化MAPPER19
    " c# J/ H; G5 J4 q' y
  357. JSR Init_Mapper19( w1 G% x* H6 p; l( Z

  358. 1 q# s8 W- X# h! g$ {! `
  359. ;==============================/ ?# S9 W/ G4 P  g
  360. ;RAM初始化
    0 l! `( C+ ]" o/ Y
  361. Nes_Ram_Init
    7 N3 U0 y! j3 y  [0 @0 j
  362. LDY #$00% p; i; g- }$ ?+ V$ E
  363. LDX #$085 l* ]  l$ @& z+ M5 z  a3 r
  364. LDA #$00( w5 v  R) _1 X/ q- _# J0 E0 y
  365. STA <$00
    8 w! _5 Q3 c0 a
  366. STA <$012 a. J% u  {4 \% S) V/ x
  367. Nes_Ram_Init_Write# N- r/ {- @" V2 y+ p
  368. STA [$00],Y3 a3 ?- t5 g8 ]5 k: N
  369. INY
    , Y, O# ^7 ]' R- C
  370. BNE Nes_Ram_Init_Write
    2 C0 P0 v4 }+ B7 M# T
  371. INC <$01
    - P( S! i! y. Z: S9 e& ~
  372. DEX
    # S- b5 b* e  ~: b+ o9 t
  373. BNE Nes_Ram_Init_Write
    " C+ d+ S2 Q) a) e( _% w

  374. ; f( v6 P3 ~* V# x8 a" w; s5 d
  375. ;初始化命名表( B& D2 O( [5 c8 }
  376. JSR Init_Name_Table- p% p+ N  l! ^3 {1 X

  377. % B2 p* ]' @& W1 L
  378. ;初始化调色板
    9 i! f' m+ @- m, B! Z, s, j
  379. JSR Init_Palette
    2 e1 h$ L  p& ^+ [: }5 E2 D: l

  380. 7 O  m! Q" A; J' j! T
  381. ;初始化命名表属性* _1 w/ I5 N! o  k# w9 B) R
  382. JSR Init_NameTable_Attributes
    8 J6 p3 T. O, G4 S$ @

  383. 6 ?9 {7 z, E7 w, @; ]
  384. ;初始化精灵内存& l6 T4 I7 r4 s3 E" d1 m7 F. @4 \0 y4 x
  385. JSR Init_OAM_Ram8 z  X% L! ~/ C# d2 t  @) [+ k7 A7 u( o6 C

  386. : P, p" E1 s2 [0 }2 `
  387. ;在屏幕上写点东西$ @/ s) Z" N8 M) j
  388. JSR Init_Name_Table_Text9 n9 j1 a4 V4 n6 v" r

  389. 6 b; G% v; P8 v+ Y4 n& b
  390. JSR Time_For_Vblank
    2 D2 }* y7 e/ Z4 b' i) v/ E
  391. ;开启PPU控制
    6 G; N# x3 l. V- _! @" v
  392. LDA #$A8
    7 n: m9 H- t- w- d
  393. STA PPU_Ctrl_Buf( ]3 H# L" O" U' a/ @* l1 i
  394. STA PPU_CTRL' f" r* R/ c( t0 b8 p% t

  395. 2 @0 G+ K5 F# E# I& w
  396. ;开启PPU显示  j; v  c7 u0 ]: P6 T9 v- q( Z
  397. LDA #$1E
    , w# N2 H5 w9 Z; o$ Z, Z
  398. STA PPU_Msak_Buf# r6 K, n: U8 O6 z( ~5 ^; R* j

  399. : w( E6 b/ _3 I) y! ?& ~
  400. CLI
    # f/ P9 z7 C; m# P- q( N
  401. JMP Loop( u2 F6 ?! @0 `8 Y
  402. 7 S4 ~: F0 S& x) Z. A
  403. ;==============================
    / S8 v; j7 E2 B# T
  404. ;死循环, 等待NMI中断
    5 ?8 q# \* e* a7 X  r: X
  405. Loop# X$ I, Q- o4 u3 ]
  406. JMP Loop' C4 s* K% q" N) ?% z& J
  407. ( M; l2 O) O5 d  p
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    5 Y& _6 o! ^& C" V' n. Y; }
  409. : S# L2 t$ g# u( Z, t0 R
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    4 [7 l! s) `1 g) X0 J) ?
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    1 f" @: F3 y! `. @. a- V
  412. ;==================================================
    2 c0 o* F8 d9 s
  413. ;NMI中断处理0 Z+ m" h& K. s( i# I/ d+ v  X
  414. NmiProgram
    7 r- k, Z' P  K$ m9 w$ q
  415. PHA
    ; l% {  @' I, f5 X, c
  416. TXA
    % x- e, K# g( M% [2 K- s
  417. PHA
    9 g7 ]% K; T! F
  418. TYA1 I5 U6 u9 T5 l- ^" ?& d9 n
  419. PHA
    + X! L  K! h) [6 x9 D  Z

  420. : ]3 |0 M, V0 t6 Z  v# M
  421. BIT PPU_STATUS
    : j$ ]' n! a# U0 ?! v7 {2 R% E

  422. 0 H6 C: R) C( L; X! F' Q8 ^
  423. LDA #$00+ w0 t9 ~# J8 H  d
  424. STA IRQ_Index
    " H' Y! h" _" |5 I2 {
  425. . u- z6 Q. T/ d2 }7 o; x4 ~
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    0 x( Y* |5 G9 p% T( x( x, }+ B
  427. LDA #LOW(BEGIN_LINE_CYCLES_START). T2 b5 Y: v. [. ]+ M
  428. STA M19_IRQ_COUNT_L: F- `: w6 g- N6 H- B4 i+ l
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)) J. O3 P% b) i5 a
  430. ORA #$80
    " z' O  _& f- x! ]  X
  431. STA M19_IRQ_COUNT_H
    & ]$ v1 E% P  n' Q2 E
  432. CLI/ ]8 K8 w% ?0 }
  433. 4 \% t% r2 l( r
  434. ;关闭PPU控制
    . }5 T3 O+ Q6 o% q/ S" I
  435. LDA #$00
    - F9 P" e. c/ p3 a/ f
  436. STA PPU_CTRL
    ! S! K8 J& Y' C' j; I7 Z9 A

  437. % v- q9 |% T/ S1 ]8 x2 ^9 L
  438. ;处理PPU% M% c' m7 k( }+ j. g
  439. JSR PPU_Process
    ' P* \8 x) n) B4 k! \
  440. 4 L! g$ Q5 r% z9 m7 V3 o
  441. ;开启PPU控制
    5 c/ Y% E- C% J  [
  442. LDA PPU_Ctrl_Buf1 ?* v( B7 E0 G
  443. STA PPU_CTRL" K' _# |/ e5 E9 R4 X: o" p

  444. 2 Y: z* X% O; B
  445. ;手柄处理: R5 n4 K4 X$ \% J
  446. JSR GamepadProcess
    * d# D; n% d( O" z5 j( E

  447. 7 H# }0 t7 b+ @( U2 L7 @/ `* c- R
  448. LDA #$00
    ! m& t+ J, z4 a" \$ {- W5 n
  449. STA IRQ_Index& |" K# y: i4 p$ T
  450. & v& x( |1 _/ W  q2 g+ W
  451. PLA
    - F6 l7 |9 F- p" k
  452. TAY; x! p2 s& a( _* j8 q; u$ d$ g9 l7 G
  453. PLA
    2 _- r1 }( `, @. f: m; m, f0 v7 d7 l
  454. TAX( M- v0 ~% F; J- `  _! s
  455. PLA
    ' m6 H0 Z. r; ^+ `
  456. RTI
    2 j+ E% X. T% D) p2 {
  457. ; E& \2 u/ d9 t/ D: D) k
  458. ;每行扫描线113.674 A" F+ D' @$ E6 W
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)5 T1 c2 }! _& Q8 f
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7! E# @4 q: U& h! v2 t4 b/ w
  461. ;==================================================. ~2 h" I; p3 o2 A9 V
  462. ;IRQ中断处理  _/ G- D- @: R2 b) w5 R
  463. IrqProgram, Q$ d' Q5 a3 B; ?2 C
  464. PHA
    7 Q  w; u9 G! Y, k: L5 ~8 E% ]  q
  465. TXA
    6 Q+ l" c& r9 L6 i4 A+ ?- b3 h1 I
  466. PHA
    3 K+ s' R; P( e. m2 F+ B" j* z) ]* s
  467. TYA& R8 K& R, C( i- S  `; m/ D
  468. PHA
    4 |9 ?- e1 |1 _6 O# [2 p0 D5 a0 ]

  469. 5 n; Z8 H) U4 N# z, K' ^9 C
  470. ;16条扫描线后触发IRQ
    7 X9 Z& }6 z! ^# h
  471. LDA #LOW(BEGIN_LINE_CYCLES)9 B7 L; f( h; b3 b+ P; x) G
  472. STA M19_IRQ_COUNT_L
    ; z9 ~7 b, f1 H2 B, [6 Q! J
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    . j  U2 T7 u+ E5 k( U; R
  474. ORA #$80: R) z6 v+ c0 P. P
  475. STA M19_IRQ_COUNT_H6 U9 f3 B0 F3 u; Q

  476. 5 U! a9 A4 e. f# B
  477. LDA <IRQ_Index
    # Z' y$ F& I- `/ {0 F& c' C2 @* [
  478. BNE * + 4, [) ~6 P& J, T* F  A  g9 {
  479. INC <PPU_Scroll_H
    / |- C& T' L5 t% Z. N) k
  480. % S* d& L( X8 x' Z: u, r; @
  481. ;设置屏幕滚动
    # N+ z2 G3 j: D& X3 K" C) ^
  482. LDA <IRQ_Index
    ' I* U' E) i( S8 v
  483. AND #$01
    . m: _4 P4 `9 i- ^
  484. BEQ Irq_Scroll_Right" A" R1 L3 c2 ^' M8 ]* `( y, U* ]: \

  485. 5 y! M' q$ I; q7 K6 C4 Q
  486. Irq_Scroll_Left
    ' v  G% c9 @1 |: z* t
  487. BIT PPU_STATUS
    & P" k% i( x+ G+ B) g/ h2 |
  488. LDA <PPU_Scroll_H# e8 w$ s2 T  h* E0 e0 Z
  489. STA PPU_SCROLL& W, b& X- j2 U5 k- @% z
  490. STA PPU_SCROLL
    $ D  {8 t- u- M# Z- p
  491. JMP Irq_Scroll_Over
    " ~2 P" _& T) i
  492. ' Y7 Y+ }/ H4 t* t
  493. Irq_Scroll_Right5 c! v" f, p, j8 u$ L* M3 C9 n! p' n
  494. SEC# x# B$ {8 A7 N. @% _
  495. SBC <PPU_Scroll_H" {  F4 `3 ?) l4 `! J
  496. STA PPU_SCROLL$ G0 i  o% o! o* i
  497. STA PPU_SCROLL! O3 S& t: T# U$ E! T9 w) S
  498. Irq_Scroll_Over
    ' C" U/ ?1 g, c$ m

  499. ( a& ^" g- |/ G0 w' d# L: R) \% n
  500. INC <IRQ_Index
    $ I2 V) h( [" i, C
  501. ! }  a% M2 Z5 l# c0 L- t* Z% B; h; s$ R
  502. LDA <IRQ_Index( A* u0 f1 `" q6 b: @5 |3 S5 v
  503. CMP #14
    : z1 l* @+ a& T9 G* Z8 I
  504. BCC * + 10
    % `. \7 u: @/ B2 E
  505. LDA #$00
    ; W( i" i7 H! [% a
  506. STA M19_IRQ_COUNT_L
    ; c8 j0 K# g. G; H$ P, H
  507. STA M19_IRQ_COUNT_H2 n% v1 ~4 A" k  |! E- p' U
  508. 3 Z- j. J, k& p% d/ i
  509. IrqProgramEnd
    4 U% W" \# ^& y* v
  510. PLA
      R* N1 Z# F) z3 f. e& i' o
  511. TAY; c4 w& o8 i2 w1 s
  512. PLA- m, Y/ a2 U8 f9 ^
  513. TAX
    $ F7 E7 w  u+ ?7 L: j& p  e8 [6 e# B9 W
  514. PLA
    ' T$ y9 W4 _9 v4 u3 |( J
  515. RTI* q2 D( V% B- @9 r
  516. ) ?3 C7 i3 R% L8 p% U
  517. ;==================================================
    . z) y5 Q; f" E; a( c* |
  518. ;中断表
    - K3 m) V' W- r0 k
  519. .ORG $FFFA+ ~" f9 b( F+ @$ E+ A
  520. .WORD NmiProgram
    6 G* Z2 S) [# l0 E. \% k
  521. .WORD ResetProgram. m4 v# t/ ^# K9 k
  522. .WORD IrqProgram
复制代码
4 H$ R) X1 m. u  x, C! T

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-2-19 05:54 , Processed in 1.101563 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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