EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    - ]% `+ x! H9 k  T5 H4 I
  2. ;FlameCyclone 20230710
    / k# f( i  H( F9 x0 N, B0 J7 c2 R

  3. + i* O* @, W/ h3 I+ m
  4. ;文件头
    5 z  @6 ^* H; N1 r/ h  o
  5. ;======================================================================
    # E% |$ p  B# R6 J# G8 o; @
  6. .INESPRG 4                                              ;16KB PRG 数量
    4 P% {5 ]: K; [$ P" d: }9 \$ [& \
  7. .INESCHR 1                                               ;8KB CHR 数量
      K0 H" [6 x8 _" w1 \% Q
  8. .INESMAP 19                                                 ;mapper 197 r- X9 t% A8 z7 w1 L2 Z. _  P: r
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直# G3 N3 ~+ K' c5 D4 J/ X0 N
  10. " S' W1 p/ @# B# S1 Q
  11. ;必要条件
    * {/ O8 \+ W5 W: q4 v+ W+ d
  12. ;1.持有CHR ROM
    $ I8 u8 P3 ]3 s. U+ E& i
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000% n9 ^6 m8 x/ k
  14. ;3.精灵内存(OAM)不为空
    : z1 @0 f( g# g; {
  15. 9 c# n2 `/ O- k: _7 `% L
  16. ;==================================================
    ) o9 T; q9 O! n8 e; ^
  17. ;NES端口常量' M6 l1 Q7 U6 E3 Y$ B$ v/ {) o9 t1 {
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    1 o" Q* Q; c1 i% W
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器: z+ ?) d) O4 a. `
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位$ J+ u- E" C4 t/ X
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    7 O* m1 I0 v2 c& {5 Q9 p
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    6 j- |/ }: z& r1 T2 \" w
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    8 K. b: R3 r9 Z! c% i5 O
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加/ j2 K' l4 X  l9 ^" h9 N- @" r+ \5 u" j
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 # A" k/ E3 p; g2 Z
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ' P- a% W, Y/ n- I, x
  27. APU_STATUS              =   $4015   ;声音通道切换1 Z# k0 O, k4 ^4 M
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通. N( Z( c# z; j/ S( l$ _. Q
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通1 m) E' q. w8 k! b: N* q$ {8 h

  30. + d% [# g! p7 t5 a6 h1 p' Y$ j
  31. ;==================================================
    2 P# {& u: U- o2 ~. P
  32. ;MAPPER 19端口常量
    ' |) v4 J" g( H5 V+ D
  33. M19_CHR_0000    =   $8000- V3 s* {: N) @" t
  34. M19_CHR_0400    =   $8800! w  A4 j2 g: I2 M: @! F0 \3 h* J
  35. M19_CHR_0800    =   $9000
    2 S' [* l3 y: |8 T
  36. M19_CHR_0C00    =   $9800  `- M  K6 r% Z4 r3 z4 f* c
  37. M19_CHR_1000    =   $A000! ~1 }1 e" U+ v3 [. @
  38. M19_CHR_1400    =   $A800
    ! F2 C8 B( w' H( C( d. x
  39. M19_CHR_1800    =   $B000! l# S6 E% H" h# e* @6 `* I# a' W
  40. M19_CHR_1C00    =   $B800) U! D, v9 I! N( b
  41. M19_NT_2000     =   $C000
    ; g( [% n! J7 t
  42. M19_NT_2400     =   $C8002 e2 n8 D8 l6 \7 {
  43. M19_NT_2800     =   $D000& F  M- u( O4 v% K
  44. M19_NT_2C00     =   $D800
    & y. T( g) @" v- D, G
  45. M19_PRG_8000    =   $E000
    5 S' r( G/ `) ~  x7 O
  46. M19_PRG_A000    =   $E800
    # v% |- v6 ]6 T! B* z3 T, I5 x
  47. M19_PRG_C000    =   $F000
    0 g7 q9 T7 V( l/ V9 P' \+ c
  48. M19_IRQ_COUNT_L =   $5000
    3 E$ }  V' q1 A1 G6 ?6 t, ~
  49. M19_IRQ_COUNT_H =   $5800
    * N1 G3 n. s, p: a

  50. 4 Z3 h* s* |1 q% N1 X2 g! A
  51. ;==================================================
    * k* r( k# B! y
  52. ;程序块配置5 D3 G% `& V' d9 x+ {
  53. BANK_DATA_MASK          = $079 J4 r; ^7 Q- o9 C
  54. ;--------------------------------------------------
    ! s2 T  T( U3 j. O: v' \* [' |0 \
  55. RESET_BANK              = $07
    + K2 O3 Q( _* P( p1 Q( O! a3 T) L
  56. RESET_ADDR              = $FC00
    5 k6 ~7 L* D$ A, i% }9 v
  57. . k* i2 b( I( ]6 m1 |6 W( F6 _
  58. ;==================================================2 D) f& k. }, {/ s
  59. ;图像块配置
    ' K9 i' B- z8 L2 S* M( J
  60. CHR_DATA_BANK           = $08
    4 q& R' T& L, O, G
  61. ! h5 E1 \# i2 `- z$ f
  62. ;==================================================! U# E+ o/ I: B* f5 u7 E- e% K7 L
  63. ;零页内存地址配置
    9 a5 B; V1 R) p! N& F/ l
  64. Use_Ram_Addr            = $80' ]! _! e5 m% }
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    5 o0 b3 w1 ]& @7 J& v- `; G* l3 Y  p7 [9 {
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    2 L8 l0 F0 V# X. S  W
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    9 H4 j) K; y- y7 P( I
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    : t0 h/ A+ X6 B
  69. FC_Data_L               = PPU_Scroll_V + $01$ g  F/ s; ^; A: f& E
  70. FC_Data_H               = FC_Data_L + $01" n- N, M8 Q7 J& B/ ?" ]/ }
  71. FC_Data_Buf             = FC_Data_H + $01& ^* J6 `9 \7 o; u" }; u8 k
  72. ;==================================================
    ; K4 [  y1 f$ ^

  73. ; y- t7 e8 @# H1 \& E2 z0 Z
  74. GAMEPAD_MERGE_FLAG = $04
    ) z: d9 d7 e9 P5 O7 r" r' e

  75. # H$ v$ c3 y' L
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    2 K# @1 n3 F3 r# z
  77. Gamepad_Once            =       Gamepad_Keep + 2* `/ D4 S; s2 F: A! l% Q
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ( A. U0 d6 N! K$ P" z
  79.                                 $ y# |. k+ f/ C+ Y
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    + y! v$ h9 _: H' m4 R# L1 k
  81. Gamepad_1_State         =       Gamepad_0_State + 12 g- v: ?% \  M$ K
  82. Gamepad_0_Value         =       Gamepad_1_State + 1' C$ u" q# L; Y" F1 e
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    : m5 e" g( L% b; P2 v5 Z8 d
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    3 _1 I7 b( {7 o
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1; n0 \; ?8 G  r& m+ _1 _/ M/ L
  86. * ^7 d( p+ h6 K* c+ y8 v) [
  87. ;==================================================
      u: y, q9 J+ o8 O" {: p( c4 V* `# L9 }
  88. IRQ_Index               =       Gamepad_Merge + $017 V; F. b6 C2 M
  89. ;==================================================" i% B# [+ |% a
  90. ) h2 C$ t$ K# j, J" z  \% u) a
  91. ;CHR图形数据; S  e$ N* ~9 L
  92. ;==================================================6 ^) X  ]' D6 Q9 u7 o- d
  93. .BANK CHR_DATA_BANK
    7 d9 {" g$ h( `* @
  94. .INCBIN "chr_bank/chr_data.chr"
    : `, T+ x( y5 U: r
  95. # @) ~" m5 B+ M& }, ^9 Q. A/ z
  96. .BANK RESET_BANK & BANK_DATA_MASK6 c/ [  L/ k) L5 B
  97. .ORG RESET_ADDR" W& {  M4 v6 y/ A4 R9 w

  98. 3 z! w6 u3 a: k; i; J) S* q
  99. ;--------------------------------------------------$ Z' S# F# h" W
  100. Attributes_Data2 ^: g& _) [0 d. n
  101. ;命名表属性6 F3 s! \3 j" j
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    # U% t* P2 L+ n, }7 P. D# M; S
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA" I/ _7 s' d/ V  _
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    + J- c6 T( c8 T
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55& L" e/ t; z$ E" T# l
  106. ;--------------------------------------------------
    5 T0 \" y9 S  j
  107. ;调色板数据. ]5 }4 j, M( `6 M* y9 a
  108. Palette_Data
    2 s1 P9 A+ {4 c- u7 ]+ V  Y; W0 R
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    4 ^: d" K  L  F
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F& B. d. Y. M" ^) c8 R3 H
  111. & K, t; n9 T7 K) a5 U, _# [0 H4 o
  112. ;==================================================- l/ m- i: |2 x8 S
  113. ;命名表初始化  `0 K/ ]) r+ J$ v4 D) F& g0 {
  114. Init_Name_Table
      r6 p7 C3 g: w7 V! L5 k
  115. LDA #$202 J) ?1 \3 E  @. E* s% u, y
  116. STA PPU_ADDRESS
    5 W/ l8 R5 W9 O* F6 G' K
  117. LDA #$00+ q; |* q( L% K7 n; O' W* G  b
  118. STA PPU_ADDRESS! Y4 C- N+ U% H9 h! A( N, g
  119. LDA #$00
    * \4 ]- e. _' T- U; ^# @; x! B. e
  120. LDY #$00
    0 S% J5 w8 ]! c' U+ i; @
  121. LDX #$10! h5 x4 C: ?# s  v  d
  122. Init_Name_Table_Write
    ( b4 Q- d1 \! w0 f
  123. STA PPU_DATA6 W& j  _. s3 q  w
  124. INY
    $ A; _  `6 f- |. G/ ^( a& G/ s
  125. BNE Init_Name_Table_Write
    9 G; f( s0 e( e
  126. DEX
    3 X  p2 B2 r; s, q  \) n1 _
  127. BNE Init_Name_Table_Write
    " [4 |8 k& Q+ m0 V: k
  128. RTS
    7 M2 C+ `" T: @- W/ o: L

  129. " E1 \) o3 @) ~
  130. ;==================================================# V# N3 _4 H/ ~2 v; m
  131. ;调色板初始化6 M4 A: s5 M+ D
  132. Init_Palette* T' S( U* r, O( k2 u) O
  133. BIT PPU_STATUS; I+ f. d- {1 Q6 w" q4 ?5 N* c
  134. LDA #$3F
    6 j/ R+ ?9 g* v3 ]  o
  135. STA PPU_ADDRESS$ I- V, m: b& s0 A- g
  136. LDA #$00
    5 D# S7 o: r/ _6 J! u3 R# l
  137. STA PPU_ADDRESS! N9 I) z! {$ v% x
  138. LDX #$00' y- b9 r- K: Y7 K
  139. Init_Palette_Write, P8 t* e% s" Y( K( s2 E. V( b
  140. LDA Palette_Data,X( M8 m. h0 r0 \" h6 d
  141. STA PPU_DATA
    : D4 I& _2 P% f
  142. INX' }. r$ J" O4 c
  143. CPX #$20
    # f* h1 s! K1 m  U. l
  144. BCC Init_Palette_Write
    $ L+ Y" G, B: q5 s+ I
  145. RTS3 J6 n! k1 x( r+ L

  146. : Q& b7 N( N# S  U1 J5 Z% y
  147. ;==================================================! x# |8 a6 E0 g9 Q% ?
  148. ;设置命名表属性
    # O# X, X8 b; @7 o
  149. Init_NameTable_Attributes# o9 q) ?4 J2 A: b0 p# e+ s
  150. BIT PPU_STATUS
    4 Z3 q' E+ q. s6 P- S- _( r4 @
  151. LDA #$23- p, M& {* q$ y: f' E. L0 G  M
  152. STA PPU_ADDRESS
    . x' P6 S; E2 q. {2 i8 S% g2 V# ^2 f
  153. LDA #$C0$ P3 c5 H: B% U: P
  154. STA PPU_ADDRESS  i7 B: N% [4 K& K/ `7 B
  155. LDX #$00
    3 K1 R; k% y- b
  156. Init_NameTable_Attributes_Write" M' i( b3 E9 L$ Q
  157. LDA Attributes_Data,X
    8 Z( x4 l7 }3 b; T3 H( `# U
  158. STA PPU_DATA
    7 X, b; q! z5 S( T3 L& G
  159. INX: ~. s! s- z3 s* Y9 b
  160. CPX #$40' D. g- O+ @$ X( b$ B
  161. BCC Init_NameTable_Attributes_Write3 [: w, v* k+ z$ E! R
  162. RTS4 m$ B& j2 s4 `* A- J5 M
  163. 6 v, i1 J3 H' h+ d6 w. M
  164. ;==================================================
    ) c6 D0 K" z% E+ K; M
  165. ;初始化命名表文本3 T  q  J9 m2 C4 a4 P4 y
  166. Init_Name_Table_Text
    ) v' M* f+ t0 k/ e
  167. BIT PPU_STATUS+ ~+ Q4 O+ _6 e# \' G0 x; J
  168. LDA #$203 ~5 I6 i) U: D% w! w8 M
  169. STA PPU_ADDRESS& x: y3 b/ E0 o! ~& c$ a, F, _% I
  170. LDA #$005 I% g1 S) Y1 e/ q6 I$ Q. }
  171. STA PPU_ADDRESS
    ; Y: ~4 z, Q% B0 E5 D- E6 Q
  172. LDA #$004 H1 u4 u+ R' d" t6 M2 [
  173. STA FC_Data_Buf0 X6 y- o( V8 u  w; m+ L
  174. LDY #30
    6 k) s. n8 X5 l# r$ y$ ^0 L) C
  175. Init_Name_Table_Text_Write
    5 A0 {/ s/ ~8 w4 P7 D: S6 U
  176. LDX #32
    ! ~/ _) n9 \9 C) U4 c7 b
  177. Init_Name_Table_Text_Write_Char
    2 r5 `! c0 Z5 d
  178. LDA #'0'
      o. ~1 i2 G/ f* C9 |, v
  179. CLC
    0 B9 p( A( J& L* a. m: W
  180. ADC FC_Data_Buf9 E& R0 S0 b" R$ g" g
  181. STA PPU_DATA% h! o" l2 ^; ^
  182. DEX
    5 z* |% }5 k* ?7 V$ G7 d+ O
  183. LDA #$145 |# n* {/ B3 E
  184. STA PPU_DATA
    $ D0 s3 o) p- [9 w( ]5 s9 x
  185. DEX
    * q- x8 f# }( H: O: X" R
  186. BNE Init_Name_Table_Text_Write_Char. |1 n% x; X7 Z
  187. INC FC_Data_Buf
    2 r2 d' _6 L3 }; _, u
  188. DEY: Q* e# J. Q( N# l3 i* o
  189. BNE Init_Name_Table_Text_Write1 h' ]) n( x# B% d; U* B8 `  r3 r# h
  190. RTS
    # }5 e% z: _( O( x' U4 t: ~& M/ Y9 c

  191. ( d" V/ ?6 {* r0 `) R7 B
  192. ;==============================' ~# A1 u* u0 F! C1 }' t$ }, a3 J- K& d
  193. Init_OAM_Ram;初始化精灵内存# j; u7 i$ B. }+ l+ t
  194. LDX #$00- n1 y! P' V6 W2 i2 d
  195. LDA #$007 `/ d+ r  Y' s# g/ x/ C
  196. STA PPU_OAM_ADDR' H7 F1 B. A* u  v
  197. LDA #$F87 ]# Q0 k: N- q" J6 d; g# s
  198. Init_OAM_Ram_Write
    ! q% \6 o6 M, n2 @- E
  199. STA PPU_OAM_DATA
    0 T" P+ z1 A3 a7 l" i! R" j
  200. INX
    3 x. I# y3 Q. v  Z* h
  201. BNE Init_OAM_Ram_Write
    9 W, O5 M8 E0 Z( S% x
  202. RTS
    " ^8 V. N+ k3 _  O: N: w. v: J

  203. % R5 o! T' ^5 b9 H, ?
  204. GamepadProcess;手柄处理
      e5 w0 @, s; m% W8 @
  205. JSR GamepadDatacan
    ; X. l0 Z, h; G5 _
  206. LDA <Gamepad_0_Value( W1 a, Y8 G& O! \
  207. STA <Gamepad_0_State& Q: T  \+ R$ H" j6 C. [
  208. LDA <Gamepad_1_Value
    ; R' N5 c1 i: l; |- i! L
  209. STA <Gamepad_1_State) @) {4 y- h# @0 q$ T7 R. t0 T
  210. JSR GamepadDatacan
    0 \7 i1 ^+ ^& _! w" R% M
  211. LDX #$01
    8 b6 N3 x6 G( M3 T! W$ ~0 t$ H
  212. GamepadMergeCheck;合并手柄输入检查
    # [9 v7 D9 e, s" K
  213. LDA <Gamepad_0_Value,X- y$ ]3 D! P) f! M0 N6 `, U7 Q
  214. CMP <Gamepad_0_State,X) J5 U$ x' e  `
  215. BEQ GamepadMergeInput: z: t! v2 N; f! z3 ?. W' h
  216. LDA <Gamepad_Temp,X* @/ q8 ~9 d0 p+ K; O6 e/ `9 K5 j
  217. STA <Gamepad_0_Value,X( F. l; L0 E$ y* K# d
  218. GamepadMergeInput;合并手柄输入* @; R9 z; }% G0 ?: ^+ Y
  219. DEX
    9 t. C7 W7 V9 ^: G2 y
  220. BPL GamepadMergeCheck
    / l% ?: }- k& K/ N8 _8 e3 [
  221. LDA <Gamepad_Merge
    ' `0 ]" `1 b$ ?( c& W- J* R
  222. AND #GAMEPAD_MERGE_FLAG
    # W2 i% Y' `# F: w. V4 ~0 X0 @
  223. BNE GamepadStateProcess5 V% \7 I1 ?7 g1 B6 u* P4 ?# K
  224. LDA <Gamepad_0_Value
      B& W* ?+ q# b, f  p; n0 S& y
  225. ORA <Gamepad_1_Value
    ) B1 W% |8 s: [+ L/ ~
  226. STA <Gamepad_0_Value, L8 x: l% d4 U/ ^% A* Z# H
  227. GamepadStateProcess;手柄状态处理
    & ?0 A3 [6 ?  x+ S% m6 \
  228. LDX #$01# M! k. F; L1 S, z7 E' Z7 k# V2 t
  229. GamepadStateSave;手柄状态保存
    ! g. r2 W) k( T. \) u; o
  230. LDA <Gamepad_0_Value,X
    4 v* {' Y7 x. |- F, Y- E  J
  231. TAY
    & {7 e8 }- y8 d9 t& g- X. y
  232. EOR <Gamepad_Temp,X$ P$ K/ y) L& J; M) [# j
  233. AND <Gamepad_0_Value,X
    % O. w* h& r/ ~9 A' ^2 U6 \2 v
  234. STA <Gamepad_Once,X0 D4 c$ @+ X3 y. N. H
  235. STY <Gamepad_Keep,X9 k4 O# k3 ?- I; O8 a
  236. STY <Gamepad_Temp,X
    * {: V+ i# H; g. o7 O) z
  237. DEX% d( I( v. J7 N( D
  238. BPL GamepadStateSave
    / X- h) [: A- U, b% j( [
  239. RTS
    4 \9 S! ^. l9 f1 a% x2 _# N& h) O
  240. ' \3 X3 J" C! `2 C. j
  241. GamepadDatacan;手柄数据扫描. T% K7 j" U7 t: D( g7 S
  242. LDX #$01" x* T* B2 a) E1 V+ c
  243. STX $4016/ t7 ^# w" q% O& L
  244. DEX3 @" K( f# w# _: _0 J; o' V9 h
  245. STX $4016, P8 `8 Q- U3 p5 @$ Z+ Y, s
  246. LDY #$08
    ; k! O$ }# L3 s. k2 L2 U  Y" f
  247. GamepadPortScan;手柄端口扫描
    ! z3 I4 `! R. p
  248. LDA $4016
    ) Q# K0 Q: R- q/ x! ^
  249. STA <Gamepad_Port_Value: h2 y1 t$ u6 y7 s' G
  250. LSR A
    7 N6 j6 ?9 P& x- Z+ |+ P: A
  251. ORA <Gamepad_Port_Value
    8 r2 M- s& e2 L8 z# k. e: L
  252. LSR A
    + K3 [% i9 D' m9 {* M& ]
  253. ROL <Gamepad_0_Value
    ' }( w. T- @3 I* \/ ^1 D
  254. LDA $4017
    8 i; [% _6 f3 V0 k7 Z  X4 t
  255. STA <Gamepad_Port_Value
    3 f& y, r; b( J, a& s6 O; K9 x$ z& [
  256. LSR A
    & i7 R% P/ t/ f3 v
  257. ORA <Gamepad_Port_Value5 ]5 ?& g! W5 L' S" e
  258. LSR A  C( t, l  V* u* s9 i; y
  259. ROL <Gamepad_1_Value
    # W& R7 J  H3 R
  260. DEY8 W: w7 U; I: A8 U
  261. BNE GamepadPortScan9 T( S# j- V& e/ K  Q
  262. RTS
    / A; M0 Y' S% I( T9 v
  263. % X: s4 M% j$ r+ _9 R
  264. ;==================================================
    7 l+ p) X3 W+ z
  265. ;PPU处理8 j! `/ Q! ^, _# N1 s
  266. PPU_Process6 C$ v, C1 Z  a! q# \2 c/ I* Y1 v
  267. LDA #$00
    + T4 M8 D5 F, A
  268. STA PPU_MASK+ P7 ^# I3 R& m7 I" J4 t
  269. * Z( u3 B& V, [( K$ o1 b" _
  270. BIT PPU_STATUS9 h& x8 C, k. X) G& ~3 ]
  271. LDA #$20
    , B" ]# w6 O# \8 C
  272. STA PPU_ADDRESS' Y, m9 w1 q9 y/ K* y
  273. LDA #$001 z- p4 v$ _4 S- F) q1 r  \
  274. STA PPU_ADDRESS) f9 o, h/ w' ^

  275. # q$ A( L* Z8 f  j! W
  276. STA PPU_SCROLL
    5 X* I7 `5 r+ o8 w: t
  277. STA PPU_SCROLL
    ! M# P) {) V, G, `; t+ ^3 Q; `, U5 t
  278. . s& w$ P( h* z+ D1 n8 _5 G5 b
  279. LDA PPU_Msak_Buf
    6 h' B$ Y. k- I& `, h/ V* c% F
  280. STA PPU_MASK
    5 P. A, s5 N- Y# q' m

  281. , g$ s; \  {2 ]
  282. RTS% Z" g' U7 I9 w: a' [$ T/ Z( n
  283. $ G* m* q" A6 T% V! \  F/ B& ~
  284. ;==============================7 A! q# k: y9 Q
  285. Time_For_Vblank;延时等待3 }- w- \8 q% V& q8 r5 E; p
  286. LDA PPU_STATUS* e' h. c6 ?- i9 _
  287. BPL Time_For_Vblank1 _6 n) r  I* z3 \% [( D
  288. RTS
    , Q* h: e' m: e5 u6 W7 Z
  289. 1 t/ g3 _& Q0 Z
  290. ;==============================' K; D1 C+ H4 y: p) E
  291. ;初始化MAPPER19
      M# E4 T5 C: V# w$ A3 K
  292. Init_Mapper199 D  e- t  W6 Q9 g% i7 k% u# @
  293. LDA #$00
      y5 S8 E$ e3 H9 R0 ^
  294. STA M19_CHR_0000
    2 A6 }* H- c6 R5 |6 o  }$ w
  295. LDA #$01
    * Q6 b; Q: Q$ e) `, j- `
  296. STA M19_CHR_0400
    , B& K6 N% X+ E; h
  297. LDA #$02
    $ [' m. y8 E9 z
  298. STA M19_CHR_0800" l: Z$ h* X" X9 g  q8 o# K0 U
  299. LDA #$03% V- x4 d+ N' }  ^: ]7 g/ o$ s( Z; I
  300. STA M19_CHR_0C00/ D& B  H. E- [$ T! h/ E
  301. LDA #$041 F% E, L- ^- \. o1 S0 g! V! L
  302. STA M19_CHR_1000
    - f9 i0 ?' |) b, ~2 D$ H! A- \
  303. LDA #$05
    " s7 B- z0 ]. U
  304. STA M19_CHR_1400! N7 z6 N' e' T  ~* a
  305. LDA #$06
    ; j, ~% M- H$ G( u
  306. STA M19_CHR_1800
    ) b9 x7 u9 a: x* t
  307. LDA #$07
    6 S9 ?% z) P/ w$ |" e4 _8 o
  308. STA M19_CHR_1C00
      _7 ^# S) ^& V4 |
  309. $ k' n# B/ g' A5 P- I+ o. Q
  310. ;禁用IRQ
    , a) T$ Q+ {: X0 {
  311. LDA M19_IRQ_COUNT_H' S9 N: L, H* c/ N0 ~8 W' a" T
  312. AND #$7F$ w5 H. }9 y2 Y* n
  313. STA M19_IRQ_COUNT_H
    & W( ]( L. a2 H2 \& r# s- d, [

  314. . Z8 e$ P- p& ?  N- ]% q
  315. ;命名表8 e% F7 l$ e0 y0 m' X: g+ _
  316. LDA #$E0/ Z% H# C2 t; ~6 U
  317. STA M19_NT_2000
    0 G% ^& x1 N( [" i4 Z/ T$ y
  318. STA M19_NT_2400
    ) m* _7 M; V1 t' w& J0 {/ E
  319. 9 l' v! ?. U% z8 i) U
  320. ;命名表% I1 u6 L# |1 \4 F
  321. LDA #$E1
    * j0 L7 {. z3 x* m" {
  322. STA M19_NT_28000 b7 Q( p- \% n# p
  323. STA M19_NT_2C00/ t9 o8 u6 _! ?* S, @# f

  324. 7 ~+ w4 k; ]9 W3 p1 \* E4 {2 t( Z
  325. RTS
    1 a0 J1 |0 z% {6 ~8 Y
  326. 7 [! r) S+ u" d1 W
  327. ;==================================================
    : `! z+ U8 n! [2 n( \; \3 {8 V6 R/ p* W
  328. ;重置中断处理. `) b8 T' L- g, B  `
  329. ResetProgram1 h" A2 k4 M$ w7 q$ i$ [/ }
  330. SEI
    : L7 r1 Y) H  ^* c; _4 o
  331. CLD
    ! ~$ m; Y' K' K- L: I: k+ P( u
  332. LDA #$00# K1 m/ A8 {7 J
  333. STA PPU_CTRL
    8 d1 v' }, B3 a
  334. STA PPU_MASK
      e! ?8 G  \" b# `# l# M
  335. STA PPU_STATUS
    ) K/ |; V5 @9 M" b: d' U+ Z
  336. STA JOY2_FRAME
    8 |9 L: P+ E8 `1 L$ W+ g% A& z/ x
  337. STA APU_STATUS
      C9 n6 w: A$ a' P" v/ W

  338. 7 {0 w( T2 s" m6 e4 U! |8 `
  339. LDA #$C0
    * _" F$ a) Z" I6 `$ L$ m! d' S
  340. STA JOY2_FRAME
    , E5 {: Z" D2 p7 I/ E
  341. ! ^6 ^- M! t1 U- v
  342. ;等待vblank
    # g( M# j& P3 F* l0 \2 c9 v
  343. LDX #$02* N% q9 e9 ?0 p4 M" e1 p6 @9 R! w5 c
  344. Vblank_Wait_1' I: Z0 {7 U2 l; ?/ C, E2 |1 N4 K
  345. BIT PPU_STATUS
    ' e4 J; u5 M7 y5 e
  346. BPL Vblank_Wait_1
    # d/ L8 g' q8 ~$ ^- S
  347. Vblank_Wait_20 k2 M% s9 p1 W" T' \, a* W
  348. BIT PPU_STATUS9 {* `6 E& a7 I6 i
  349. BMI Vblank_Wait_2; M4 Q- L- O- w- B7 x
  350. DEX
      b; \& R1 N! G) h9 S5 N4 C
  351. BNE Vblank_Wait_1
    4 Q$ V# a8 g' m1 T3 S% [5 S" B

  352. 8 p% v! f9 e( ?" ^) T
  353. LDX #$FF
    2 E, q) a5 |" H( r4 Z6 I
  354. TXS
    2 ^# W3 ^3 @2 Q& l9 j; o1 N1 `
  355. ) i( w8 m1 j( C
  356. ;初始化MAPPER19
    : ?9 v; h( b5 c' O9 v# e# r' e- n' f
  357. JSR Init_Mapper19
    / ]* e( u  M+ @6 ~3 z

  358. 6 @0 H& W0 }8 ]" a$ p7 ^
  359. ;==============================# h! }% y1 V1 H* e
  360. ;RAM初始化
    ( {  \& t  o' j; G4 a9 A
  361. Nes_Ram_Init
      p4 p9 g' p. T8 |2 Z+ \3 e5 R4 B
  362. LDY #$006 u. E7 r' }, E0 C/ i( R! l
  363. LDX #$08
    % W9 n" T2 H$ l. ?. M+ l! Y7 a- ~
  364. LDA #$00$ `* }7 B$ \6 }" y( j' V' j
  365. STA <$009 x1 [2 S7 i9 \3 w9 j1 |
  366. STA <$01
    ! ~# n$ H2 u1 s: z5 y( Z
  367. Nes_Ram_Init_Write
    9 G4 R$ n6 J# J% ^! x
  368. STA [$00],Y
      C' q5 y+ G& o8 A2 h
  369. INY
    % E( y/ l4 j" J  a* N5 T0 H, q
  370. BNE Nes_Ram_Init_Write* d) `$ R7 W7 e! @" Q  L- @8 `0 r
  371. INC <$01% [* {  i+ q$ t# a& _
  372. DEX
    * k: V/ _7 s1 V" w. T
  373. BNE Nes_Ram_Init_Write9 b5 Y' u, K" P/ J/ _4 f
  374. " s& k7 q; \6 }  X3 J
  375. ;初始化命名表' K5 ?5 S' @: @* |+ n
  376. JSR Init_Name_Table! u5 i0 x9 g& r9 l
  377. 8 `! z* y% ?! \
  378. ;初始化调色板+ c0 S( W# L' @- ?  ?. ?
  379. JSR Init_Palette
    " x1 `7 c8 z/ W) ^/ g2 a/ U: M% u

  380. 1 h) {1 R) p" U, m( X
  381. ;初始化命名表属性
    / l# m# Z4 q: ~: [5 ]0 D) z
  382. JSR Init_NameTable_Attributes* V7 k  U- x5 F# j. @" u

  383. # a+ a' }. j$ |. |
  384. ;初始化精灵内存$ z. A" [2 G  q
  385. JSR Init_OAM_Ram
      v6 q/ t  w- D( u( Y+ f& T

  386. * `5 R( O% E) w; U) _0 ^
  387. ;在屏幕上写点东西
    3 v& l8 L) h2 W8 j0 X% m, t
  388. JSR Init_Name_Table_Text
    4 R) n3 K* U6 z' h- w: I. u0 R
  389. & N/ {& t- r; s
  390. JSR Time_For_Vblank
    + \! L0 V& y. }
  391. ;开启PPU控制/ R" M9 e% F  X/ \; G+ b6 |
  392. LDA #$A8
    ( d+ r5 R& h3 ^3 R
  393. STA PPU_Ctrl_Buf2 s2 L4 a$ v! Z$ X
  394. STA PPU_CTRL, B7 D  _6 c5 |

  395. 0 }3 m& z8 y+ \# M, R
  396. ;开启PPU显示) s: a+ v  ^1 ^3 F% C- G
  397. LDA #$1E
    $ U8 `- ~6 C- D$ ^  f
  398. STA PPU_Msak_Buf
    ) U1 T0 `1 y4 j( `; B
  399. " V0 p8 {4 J4 d
  400. CLI
    ' N' G' z; u% t! R9 q/ Y
  401. JMP Loop$ e' s: F6 }+ ^- ], p( m

  402. & n" S0 g9 q  n! F& j7 F
  403. ;==============================3 X' L  @# b, M+ d, d4 I
  404. ;死循环, 等待NMI中断/ d. D: g4 [+ |" N. D
  405. Loop
    8 Y7 M& ?3 e/ x( X+ f, l1 U
  406. JMP Loop
    6 h, c) ~8 X1 ~& B* d9 B% _$ U
  407. . e2 Y1 }7 K5 {  Y+ Y
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9670 i! Z- o% _- ~: a7 @

  409. % s: J  D' i( c
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    : T1 x; ]( N" Z% \0 l
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    - {! q, W2 i8 k1 h& O, v- M, U
  412. ;==================================================
    : A# a8 G7 A5 \; Q
  413. ;NMI中断处理' I" V9 c/ g3 u
  414. NmiProgram7 z( I7 n" d3 d
  415. PHA3 ^) w8 V" W3 J- q
  416. TXA
    " r% Y+ E7 M% ?7 S' ~/ }  v& R
  417. PHA. @$ u: V1 u. f' d: k  |
  418. TYA: i! R" p$ ]2 z8 ?* p3 r5 E
  419. PHA- b) r8 J* \9 z4 |, g  O) V

  420. & A- m+ A, L0 K' t7 j
  421. BIT PPU_STATUS
    6 K1 l! ?; M; T6 E3 S
  422. / |5 |* `% Z0 ^; ^1 K
  423. LDA #$009 ^* j( m4 u4 b4 q0 |" ]& m
  424. STA IRQ_Index
    1 H$ ]5 A. u% T
  425. % T7 v4 m. v. M+ C- Y
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动& U% |6 W$ ^! `. M8 W. N( m
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)( p5 z7 J+ e) a( @: }% `0 {+ U$ U
  428. STA M19_IRQ_COUNT_L
    & _- c( R5 Q# x1 |+ @7 d& G9 q
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    + M0 e( d5 k3 Z) U6 m- U8 r
  430. ORA #$802 b2 k# d7 l( s4 e5 \) b( T
  431. STA M19_IRQ_COUNT_H
    6 Z% u" q/ V  |" E) J
  432. CLI, O; n" f' O7 o
  433. 0 S5 i/ ^0 ^& D* d* Y
  434. ;关闭PPU控制
    / A1 y, ~, {$ s. s
  435. LDA #$00
    ( L3 a; i/ M3 d7 v+ x0 ~
  436. STA PPU_CTRL# V' s4 _# T8 G2 z' r. }( G; l

  437. 6 ^& M1 N4 l6 k/ h" y: z8 N
  438. ;处理PPU
    . l5 i1 i2 o6 S8 o# `
  439. JSR PPU_Process8 e! b# U6 R, w4 s- k& g: K
  440. - N8 f; i! L8 a* G6 m+ Y( }
  441. ;开启PPU控制
    / n2 g; ~* w  C: q
  442. LDA PPU_Ctrl_Buf
    ) B0 D! b$ t- o0 f
  443. STA PPU_CTRL; X: N" S; D- B9 V0 J0 f) G

  444. $ D& G3 w$ h9 A' B  j5 m
  445. ;手柄处理2 M% J6 i  L3 O& `/ L0 N( ]
  446. JSR GamepadProcess" ~5 \4 J) ~( i. y. [9 U9 c) J

  447. / ?( E+ u. m7 X2 o/ `
  448. LDA #$00
    7 @; J' [* W( R1 n  O$ R; m
  449. STA IRQ_Index6 Y0 k0 ~7 W3 J. G, B# Q

  450. + \! Z+ Q% ]& Y* O
  451. PLA
    7 Y- l$ \. _! \
  452. TAY
    9 F9 _9 X' w& `, j$ p( n* e5 ?  T
  453. PLA, w$ |3 L' Z- D( \2 s& ~0 }7 }9 Y  m
  454. TAX
    6 o% q5 S/ w& p- s: y
  455. PLA
    ! P/ H4 {3 p3 [! A9 S$ [  `
  456. RTI) ], v+ }7 s1 U* j5 M: d% b! L
  457. 8 a6 W* [8 F: F8 `
  458. ;每行扫描线113.67+ @( ]; |1 [! D; c/ l( V; u
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)/ K* v& m, t  X& l) `0 l" ]  G6 M% O! p; ^9 @
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    2 _8 p* o9 T/ e5 x) g; r' f! M
  461. ;==================================================# M' u. d& ]& t; ]. P
  462. ;IRQ中断处理
    & L; i# P* ]- p
  463. IrqProgram
    6 W2 h1 ~0 q$ \
  464. PHA
    . m5 B/ Y" @( c6 E
  465. TXA. @$ ~& }3 U- y+ n9 ?- z' |: j
  466. PHA$ w% }/ G& _4 E/ d' c, g2 s9 E
  467. TYA
    0 e+ u2 I+ o5 `0 ~5 @" a5 `3 \/ g
  468. PHA+ @! t) ?; B& W; q- H7 ^

  469. 7 f* w" m) r* u7 P
  470. ;16条扫描线后触发IRQ
    / `$ g4 t! q& ?. E
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    . g, Y5 k+ G. G! |
  472. STA M19_IRQ_COUNT_L
    # c7 a7 f8 N; N
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    9 c7 D0 l; F0 C4 G: d4 s
  474. ORA #$80. A! s+ `! \) `3 e' d
  475. STA M19_IRQ_COUNT_H* K' h/ r( d- j! h0 E9 s2 d. n* Y
  476. . Q- m" {$ y* Q/ O7 p/ s$ E
  477. LDA <IRQ_Index# Q) l8 \; ?1 O8 u2 `
  478. BNE * + 4* r. l* x% i9 b$ E9 I- ?. K
  479. INC <PPU_Scroll_H
    / B9 A9 v; j% E* X" X" o
  480. ! G5 ^' N1 K: }$ U- a& I
  481. ;设置屏幕滚动/ g1 w1 u  \1 b+ e$ p% U2 u, F
  482. LDA <IRQ_Index/ |  f4 z+ v; q3 o( D6 u
  483. AND #$01" {: Y8 S- ]; |/ n, Y, }/ R8 n
  484. BEQ Irq_Scroll_Right
    8 j' w  l6 N- O7 U9 u" }- p7 Q
  485. % f9 N2 h) a$ Y
  486. Irq_Scroll_Left
    # n; Q0 ~: Z, V3 `, E$ H* K
  487. BIT PPU_STATUS
    2 l0 F+ s' j8 j; d; D: T
  488. LDA <PPU_Scroll_H5 _& p& A  [' s. b& {" |
  489. STA PPU_SCROLL2 V" y5 W. h  H% Y5 G1 o
  490. STA PPU_SCROLL/ L3 ~" [. S/ \" P$ J! k: |
  491. JMP Irq_Scroll_Over
    : Y, q5 y& V- h# e3 s+ [  q
  492. 7 G4 V6 A( l! D
  493. Irq_Scroll_Right
    9 H) I' X2 c, g1 x# o2 \
  494. SEC
    # I. d( [* n# Z: X2 G
  495. SBC <PPU_Scroll_H
    & [3 S1 _" u* U4 z$ p
  496. STA PPU_SCROLL
    8 i" a& L$ w8 X
  497. STA PPU_SCROLL! k. k, V$ G+ h
  498. Irq_Scroll_Over, b" B9 m  z# x: L1 }% N# f

  499. 9 w) `& j5 @' T9 O0 e5 L6 Y+ x* g# g; V, J
  500. INC <IRQ_Index
    4 f1 r" q9 N, {" X$ M! @

  501. # {6 Z1 `9 Z0 q& c
  502. LDA <IRQ_Index
    5 I$ B' d. L* V: ], Y
  503. CMP #14
    ! V# q* f% J6 y; \' t3 k* h. _
  504. BCC * + 10" f& m2 R5 z9 S+ T' ~: n. p0 r
  505. LDA #$000 e- O) E8 \; W- ]- Z
  506. STA M19_IRQ_COUNT_L
    3 z: O: Q  ]9 t
  507. STA M19_IRQ_COUNT_H/ s$ S3 P1 k1 R
  508. ; K6 n) k6 T  O. [
  509. IrqProgramEnd8 c) u1 J/ Z, N* [
  510. PLA7 t; y# b: b) R. s) q" K' d/ A1 Z. _0 W
  511. TAY, [# M: t3 ~# d7 D  S$ ~  ^
  512. PLA4 a: N) x. K- i! O
  513. TAX2 {! ]6 P) @3 ~' e8 F" W" i5 }; o
  514. PLA
    ! U4 X" d) `6 \2 C) H+ K5 v* N
  515. RTI+ H( I& Q4 B8 B( d& c
  516. 3 l/ Z/ L+ n9 Y& W4 `1 T
  517. ;==================================================3 m$ W# R4 R3 A% {
  518. ;中断表) w% t& B/ J* o; }5 f
  519. .ORG $FFFA
    # U( a* m& l% o0 C& d
  520. .WORD NmiProgram
    - n6 X4 l3 N* j! \/ ~, f
  521. .WORD ResetProgram
    / W  S7 X( d, r% x. H
  522. .WORD IrqProgram
复制代码
5 i  H8 v0 S5 p* r

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-8-27 05:03 , Processed in 1.063477 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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