EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]/ c: K$ O- ~- }: k# E0 O
  2. ;FlameCyclone 20230710( C2 V8 q9 f3 J, j: g% x; A* M
  3. 8 X  l. r6 o: F6 m1 \" F2 o  d
  4. ;文件头
    * X/ ^" T6 J- U" j7 W0 k
  5. ;======================================================================
    + [) ~& I7 @; @
  6. .INESPRG 4                                              ;16KB PRG 数量
    0 S2 G0 ~2 e) J: x5 g/ {
  7. .INESCHR 1                                               ;8KB CHR 数量
    6 Z4 u: v- q0 h2 T% {* ~
  8. .INESMAP 19                                                 ;mapper 19
    : i( e  _, x2 ^
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直* f) t$ @; a# p+ E- @& O

  10. 8 z* h* X+ B7 T" H' ]
  11. ;必要条件; X. A8 G: z% |$ ?/ d3 A
  12. ;1.持有CHR ROM
    + `/ V7 g* l8 p4 ~4 B( `$ [
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    2 p; |- L& G( e4 e! r
  14. ;3.精灵内存(OAM)不为空
    9 z3 y% R  W7 _7 W4 i

  15. ! v) f4 v! H4 N8 _' l4 ~
  16. ;==================================================3 U: @" g+ \( h8 M" ]; i4 ]5 c
  17. ;NES端口常量
    3 R- J; U* E" i1 ]- ~
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器3 t' T+ a, F& o- F. h2 |" f6 ^
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器& U; t1 A2 Y1 V- }4 x5 Y1 f
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    7 e, c1 L2 j% Z9 |- }
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1; k7 w6 M2 f4 P$ l5 I+ e/ T) N
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    - E" g4 m7 D" l" R9 X6 @
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    - y) d: q! Z, r  K5 W
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加# k! S% I4 [7 ^' l, H
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    " P& f! r+ W1 b6 u- M
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存2 X' [+ b7 P8 {7 e- w6 p% `
  27. APU_STATUS              =   $4015   ;声音通道切换: w, Q& H3 V( M$ r1 j5 j* `' C+ f
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通) W$ K+ ~% ?1 S1 e1 t! E
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通8 \! I6 s) d$ N" _0 O3 R3 S

  30. ) o; d  t4 g+ I
  31. ;==================================================1 C% D2 r) `3 E& t- D4 K1 n
  32. ;MAPPER 19端口常量
    0 g- S% A+ ?9 i! B2 b5 S2 G
  33. M19_CHR_0000    =   $8000
    0 [6 M* ?4 r7 ]# `! B/ y
  34. M19_CHR_0400    =   $8800
    + [3 }5 C# |! h1 A
  35. M19_CHR_0800    =   $9000
    : `7 X) W6 B3 F6 u
  36. M19_CHR_0C00    =   $9800
    9 ~" g! ^/ `  u8 n4 S, {( d  A
  37. M19_CHR_1000    =   $A000/ G; E( Z6 u0 A2 R% P
  38. M19_CHR_1400    =   $A800
    " I) ~/ h: f; Q: |' ^, w2 M
  39. M19_CHR_1800    =   $B000
    7 @+ ^9 j" T2 W! V5 a4 q
  40. M19_CHR_1C00    =   $B800
    6 f6 e. Q( U6 z  u% h* \
  41. M19_NT_2000     =   $C000
    1 Y" s8 O8 t; g9 ~. v; d
  42. M19_NT_2400     =   $C800
    2 y; J; _: I6 [% u1 `
  43. M19_NT_2800     =   $D000. \, J' }9 z: c* b! p6 S+ |, R
  44. M19_NT_2C00     =   $D800
    + w% F7 _2 v' F) U# A) `* |# B1 m
  45. M19_PRG_8000    =   $E000/ T! q' h5 h) L+ \; \( t" ^
  46. M19_PRG_A000    =   $E800
      \& r- o1 Y4 J' T) s
  47. M19_PRG_C000    =   $F0008 k3 r$ x+ y/ w
  48. M19_IRQ_COUNT_L =   $5000
    8 x/ A9 N8 ?. i$ U. h! R
  49. M19_IRQ_COUNT_H =   $5800
    2 c- e8 Q5 Q# o8 y
  50. $ w% J0 g) G$ A1 s8 n
  51. ;==================================================* i; v4 u' q9 P, j4 Z( _' [2 f
  52. ;程序块配置2 l' u# n; d) q. R
  53. BANK_DATA_MASK          = $07- S9 N' v: R! o4 X) c
  54. ;--------------------------------------------------
    0 f: a% {% o8 u; N
  55. RESET_BANK              = $07
    + K# I! G0 f5 _
  56. RESET_ADDR              = $FC00" y+ l- k3 w' l2 r

  57. ' j/ g& A* H0 \0 q8 c9 r  T& m
  58. ;==================================================4 B: r9 \2 u  ~
  59. ;图像块配置! D" h' U/ V# z$ [
  60. CHR_DATA_BANK           = $08
    : {4 @# C0 e6 h" d8 s; B
  61. ' f+ z. S) o  F% b8 \2 o
  62. ;==================================================+ c9 ^5 C; b2 y2 H# c( J5 |
  63. ;零页内存地址配置% u8 z, s9 k0 O0 B
  64. Use_Ram_Addr            = $80
    % p( @; [  T2 X! F
  65. PPU_Ctrl_Buf            = Use_Ram_Addr& i0 e' F' v  R! m3 U6 H1 P& q' m
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    & @/ ?5 u+ F: M# H/ S+ S7 N  T+ S
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01  F( A" y" D4 \# G+ w7 ^
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    + O- D& Q$ c: s  ^/ s1 o4 X% q/ d) l- A
  69. FC_Data_L               = PPU_Scroll_V + $01
    & b, R7 n6 e. d/ `3 N% H$ ]
  70. FC_Data_H               = FC_Data_L + $01! A& t0 s) p- v+ G  v1 ]8 q. o- Z# t
  71. FC_Data_Buf             = FC_Data_H + $01
    + x# ]6 c, E) C. ^
  72. ;==================================================
    9 l* W( K% z2 T& b& l" V8 q, v

  73. ) m) R0 q0 R4 D! x) B
  74. GAMEPAD_MERGE_FLAG = $04
    % K8 k1 F: ]5 `4 {6 B4 i
  75. + I/ S. n' f4 r; T0 V: v0 N3 q
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    ( D+ t" G, h; N" R' S2 [
  77. Gamepad_Once            =       Gamepad_Keep + 2/ u9 N* b, U( I9 U. z7 v' v( y; c
  78. Gamepad_Temp            =       Gamepad_Once + 2, ~, _0 h4 q  @/ A6 h
  79.                                 / r: h' z* c2 C) g8 E
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    ) i- Y7 o/ F+ F% V$ f
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    1 z3 _  ^3 S$ ~
  82. Gamepad_0_Value         =       Gamepad_1_State + 11 |+ `: E# q' j9 E4 R
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
      S3 A" q8 C' y  e1 [  y+ Y
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    ! X2 L& D8 z$ [
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    3 e- j% ~4 l5 k- m% Z# n

  86. 1 M2 m" G7 n  a+ _' P! d/ p/ K0 v
  87. ;==================================================' g& \, ?7 D  `
  88. IRQ_Index               =       Gamepad_Merge + $01
    0 f/ W" ]5 _! [  P8 Q5 X
  89. ;==================================================9 {5 q& Y! y" `' ^" K" F! Z* C
  90. : _$ @  x& h3 [
  91. ;CHR图形数据
    ! W$ C- ~- {! C) a0 H
  92. ;==================================================
    8 q$ V' ]# n7 O4 N2 N
  93. .BANK CHR_DATA_BANK" B& @9 P, U5 S) [( ?
  94. .INCBIN "chr_bank/chr_data.chr": Z( e$ E: O& ~6 K* G+ `
  95. & d. o! z) _6 |: @( d, k, I
  96. .BANK RESET_BANK & BANK_DATA_MASK
    % i- ]! w$ h: [4 a0 O
  97. .ORG RESET_ADDR
    5 q! r! p# A4 x8 E
  98. $ t; _7 ]/ e# W4 |! p
  99. ;--------------------------------------------------
    4 \! ]' P3 [, T, f) f/ \
  100. Attributes_Data# E3 r3 [( j  }2 `
  101. ;命名表属性
    ) V9 ^/ g& Q0 c: }: X; _
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    1 _% O( H1 v, y. m! c1 W  m
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA: U2 [5 m) O' P+ G/ d8 ]
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    . a. y% ^! H4 V
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55! Z7 l) d; H5 s% s& x! G7 K- W# k
  106. ;--------------------------------------------------9 e" d& X7 A. I* e, s: J
  107. ;调色板数据
    , R+ |8 F% q: w
  108. Palette_Data
    % |' j9 G/ i! I7 Z  P* N
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    & s5 a; M1 l. A" ?2 ?& ]" O" w
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    3 ^* R+ r# k/ `' v9 b+ O! l

  111. 1 b4 W( z* Y$ X- I
  112. ;==================================================! H: d7 X; h5 o  n) u1 u! Z5 H* [: Q
  113. ;命名表初始化
    $ J1 G( j! D% ~* i- m# Y' r6 f
  114. Init_Name_Table
    3 N% h# ^. k# Z$ l% ~7 I; J& q
  115. LDA #$20
    ' _2 J' R, G+ @( e
  116. STA PPU_ADDRESS
    4 y6 v; `6 L% j- A. j
  117. LDA #$00
    , d' Y' O2 T$ h! k" c7 H$ O
  118. STA PPU_ADDRESS
    % l: s2 n' ^; N: M" H
  119. LDA #$00
    . \& r6 g7 k* h7 w
  120. LDY #$00  `: v$ g* d5 v5 z* ~8 k
  121. LDX #$10: `: ^: `4 S# |: s  |& b1 ?
  122. Init_Name_Table_Write
    & x$ M1 O2 I  X3 e0 D
  123. STA PPU_DATA& D1 T" L" x: t5 |# T
  124. INY9 N: y8 S8 z/ e7 P4 X
  125. BNE Init_Name_Table_Write# M' V$ v% s; d6 q$ S* p
  126. DEX
    4 u: A4 C( G+ o4 d6 U( j) \  ?9 `
  127. BNE Init_Name_Table_Write
      m) f  t! E& `. U
  128. RTS8 K0 I7 \6 U6 w. I
  129. ; q  q# ]% ]: E7 N, h* C" m
  130. ;==================================================
    8 r! v+ G* l4 |+ z/ j* g) h4 n
  131. ;调色板初始化
    ! B7 c. y, \8 b& c! }
  132. Init_Palette' J/ R' f( u8 e" K* Z3 [' i
  133. BIT PPU_STATUS2 q6 Q* l& T+ f1 H1 [
  134. LDA #$3F
    - F' s- ]7 I2 R. @2 {$ \
  135. STA PPU_ADDRESS0 S1 k. ]+ J1 @8 f
  136. LDA #$00
    8 O* L: ~% h1 ]8 y; P. R
  137. STA PPU_ADDRESS
    3 k) e/ C; {. [  K) w
  138. LDX #$00& f2 H3 a( x6 G: p. e
  139. Init_Palette_Write4 a. i) l% Z5 [  ~( e
  140. LDA Palette_Data,X+ t; e* T% b# G9 ]* n7 s. A
  141. STA PPU_DATA
    $ }: c: s; `- _4 Z7 h% L
  142. INX
    # i2 L9 ~* h: I8 [* z: F, @
  143. CPX #$20! M) p" h* q2 m' r
  144. BCC Init_Palette_Write
    % y. N, Q) ]  {' t2 z4 ~$ j1 H  w
  145. RTS
    / \; J% g, H; Q- M6 Y9 Y
  146. # r% ^2 y# m& d9 n/ r: w5 |3 R
  147. ;==================================================2 }% o5 e: E9 ]" d' Q
  148. ;设置命名表属性
    ( p: t! p2 J, s* q
  149. Init_NameTable_Attributes, z0 G/ O% _4 m7 G7 T! Q9 f
  150. BIT PPU_STATUS0 Y# d' w; i' ]) q3 n9 A( t
  151. LDA #$23
    ) K5 @# Z+ P3 r- }7 K; s& F6 [
  152. STA PPU_ADDRESS
    5 D: {# k# ?8 _+ |' |
  153. LDA #$C04 Q6 W9 U+ N* l$ n$ B
  154. STA PPU_ADDRESS1 F! Q! Q2 F$ `
  155. LDX #$00+ R  t6 b" I, ^+ Q# I* E
  156. Init_NameTable_Attributes_Write
    8 E9 |" `5 q% O1 H
  157. LDA Attributes_Data,X& M# n# M& \8 j; x9 i) O
  158. STA PPU_DATA
    ! x5 {" W* Z1 s
  159. INX. V) m; T1 Z1 b( T; o
  160. CPX #$40
    - t5 w% p, ]9 O* M7 {
  161. BCC Init_NameTable_Attributes_Write* u1 r! @* u' X9 F
  162. RTS
    9 P5 I# Q% p) j- O: t
  163. 3 K: I4 p. Q3 L& T" D
  164. ;==================================================
    % X! n4 K3 I/ |$ U$ S2 e/ M
  165. ;初始化命名表文本
    9 u3 y6 ^8 c) Q8 q+ u
  166. Init_Name_Table_Text+ v1 R& T5 B  s- \1 P) ?
  167. BIT PPU_STATUS
    1 c( d. P+ V8 x( G0 _* K
  168. LDA #$20/ \3 s, `" J  L6 T# e
  169. STA PPU_ADDRESS
    8 p+ ]. c$ A4 G3 z4 _1 g
  170. LDA #$00
    . i$ [* E# m0 h- e) J
  171. STA PPU_ADDRESS
    " ]2 r5 g; H' U  a- \
  172. LDA #$00
    0 W* p; b& v, K8 T
  173. STA FC_Data_Buf& x; @! T2 y# ]0 N: }. R, o
  174. LDY #30" L# K1 m0 l* d; p
  175. Init_Name_Table_Text_Write
    ) y. Q& K  _% f7 q2 Z& z+ S% K6 p
  176. LDX #32
    9 C9 ^5 G) k4 e* m4 i
  177. Init_Name_Table_Text_Write_Char
    ; N4 e5 ^7 b; z
  178. LDA #'0'
    7 s; a/ R  b$ ~- x1 {0 D  f9 W) `
  179. CLC, v! u/ W& ~* F" f0 N  B
  180. ADC FC_Data_Buf
    " T- X0 w: v2 c$ f7 j
  181. STA PPU_DATA
    ) s  u2 A  G$ Z+ p4 W
  182. DEX
    ! e3 h" F0 s8 L1 K3 f
  183. LDA #$14
    5 t% i- k% }/ {5 w. T
  184. STA PPU_DATA
    . E3 [2 B$ }8 t- W. [
  185. DEX
    6 E; Q( k# s2 i8 @2 _. S/ E2 D
  186. BNE Init_Name_Table_Text_Write_Char8 p9 V/ \% M% Q4 m9 m9 S
  187. INC FC_Data_Buf
    / L$ \; t! R' y3 q! W- k
  188. DEY
    % H9 t& u! f! N; ]
  189. BNE Init_Name_Table_Text_Write
    . b. g7 n8 {: S7 C
  190. RTS, Y2 O. `  b$ Q, X+ U* d; V* P5 T
  191. 3 s  ^% R: ?0 d4 M$ @1 V
  192. ;==============================- Q% [# Q4 a. y# ^
  193. Init_OAM_Ram;初始化精灵内存  r% D* F1 z: u+ C0 U$ V
  194. LDX #$00
    0 Q; Y. Z) q( G/ t* y4 s% U" i0 M
  195. LDA #$00
    2 j' s, k2 y0 N) @1 Q
  196. STA PPU_OAM_ADDR* ~6 w* y# b, r3 N. g9 v
  197. LDA #$F8
    * t* S! r' x8 h/ h3 X
  198. Init_OAM_Ram_Write1 F5 x/ M! T8 H
  199. STA PPU_OAM_DATA7 K6 N* z9 a+ n1 r: O6 i; R6 g
  200. INX
    9 D& _* A/ }, A0 w. h6 g* e
  201. BNE Init_OAM_Ram_Write
    ( y0 K7 ~. ]+ S9 v1 F+ e
  202. RTS2 J4 W$ ]( r  n$ \+ Q( e- n8 u

  203. 7 V+ q% {% Q0 j1 o
  204. GamepadProcess;手柄处理! o4 L' {: k5 r
  205. JSR GamepadDatacan& P# Y# t* M5 P9 J' S
  206. LDA <Gamepad_0_Value
    + [! N7 ]' v: g" @4 S% L
  207. STA <Gamepad_0_State
    6 F: K; z/ ~! B* \7 @$ x
  208. LDA <Gamepad_1_Value% L6 g  O: W  t. g$ z
  209. STA <Gamepad_1_State
    7 [7 l& d9 y, J- T+ b
  210. JSR GamepadDatacan
    % i* o' d2 k. u  T3 [% P: I! {6 F
  211. LDX #$01/ `8 ~, n1 ]9 S4 E
  212. GamepadMergeCheck;合并手柄输入检查
    # F3 Q8 t4 ^3 A4 s+ m  l7 b
  213. LDA <Gamepad_0_Value,X
    6 C, {9 Q/ F/ k6 n- I+ N  f* ?
  214. CMP <Gamepad_0_State,X3 E: C3 c: c0 X/ D6 |* _
  215. BEQ GamepadMergeInput. x) d: p9 x8 H- }5 n
  216. LDA <Gamepad_Temp,X
    ( o1 K! q* s) r+ ~6 g# _
  217. STA <Gamepad_0_Value,X$ @/ m/ r% R" I; N: D' o
  218. GamepadMergeInput;合并手柄输入
    7 H7 h$ Z& y  |- W
  219. DEX
    " Z' F; S0 @. @" v! b
  220. BPL GamepadMergeCheck4 o  y6 }! F, Y5 Y
  221. LDA <Gamepad_Merge
    ) }. N2 L3 ~1 ^6 K# L  e, o
  222. AND #GAMEPAD_MERGE_FLAG0 X$ |9 @8 X/ F* n- s
  223. BNE GamepadStateProcess
    8 v& ~5 o0 ~- L6 Q% e, T5 q- i
  224. LDA <Gamepad_0_Value* E( @" r: _$ o5 `. R
  225. ORA <Gamepad_1_Value
    # t6 S1 E  K4 g- F. z
  226. STA <Gamepad_0_Value+ X7 o& ~4 y( g/ l% Y1 l$ Y5 {
  227. GamepadStateProcess;手柄状态处理
    * f2 ]1 Y6 i3 w, M% w, C$ A
  228. LDX #$01
    8 \, f) }, {' p
  229. GamepadStateSave;手柄状态保存
    1 K: W0 q# @5 l2 E4 H% ]) d
  230. LDA <Gamepad_0_Value,X
    1 E& s7 J* \" W. v) F& _
  231. TAY
    # z& c8 `$ U+ `/ I- [3 D
  232. EOR <Gamepad_Temp,X; @1 n$ L2 `, r5 }
  233. AND <Gamepad_0_Value,X$ @4 G2 J8 c& c1 u' w0 o" q( r
  234. STA <Gamepad_Once,X
    2 Z' F  q5 ~' c
  235. STY <Gamepad_Keep,X/ l7 N/ X6 e" N
  236. STY <Gamepad_Temp,X
    9 @/ n8 W; h5 X) a! n* t  b
  237. DEX- |# ]  N5 T5 H, w: d
  238. BPL GamepadStateSave0 B2 d2 B* T: [5 g( r+ ^- m4 o
  239. RTS7 I5 k' k6 c; C" _7 p2 I" A( |; \
  240. 0 p2 u) p. ^9 I9 x
  241. GamepadDatacan;手柄数据扫描
    2 _5 y$ a, w  \
  242. LDX #$01
    . y, B! ?/ Z3 k( {( y- {
  243. STX $4016
    8 P8 Z' F: B* g0 Q
  244. DEX
    8 [' h3 B) y4 z0 C, b
  245. STX $4016
    / E. o2 W! y7 {! t! s+ a; s
  246. LDY #$08! ]/ m0 Y* U; f
  247. GamepadPortScan;手柄端口扫描0 P! w7 ?" F% I8 |. ~& i
  248. LDA $4016  }! I0 I! r! b& J* ]
  249. STA <Gamepad_Port_Value
    ( h7 \' i2 K$ }, g) {% Q4 x5 v5 H) e
  250. LSR A* @; G/ k, z( g$ v, d
  251. ORA <Gamepad_Port_Value
    5 G! h  J) G8 H! j% a; ~' v
  252. LSR A
    7 [4 M) {* U. A  B5 I
  253. ROL <Gamepad_0_Value
    , d* {$ m4 b* E; U4 N* a# g& }
  254. LDA $4017
    & I$ f' t4 H$ h0 `, J
  255. STA <Gamepad_Port_Value
    2 P" Z% _! Y5 o$ ~  C( x! h
  256. LSR A
    # R* k5 h1 K* O& i
  257. ORA <Gamepad_Port_Value- S& A* G4 o3 l2 H( _5 D
  258. LSR A
    % k- W6 E& _2 [1 `% R5 P7 o7 v
  259. ROL <Gamepad_1_Value( i2 ?: g3 U% o
  260. DEY
    " K, T% {  i" D7 l% U" i
  261. BNE GamepadPortScan
    0 c  s0 R+ f+ A6 g  K# O- [
  262. RTS
    6 h/ P- K% K: e

  263. 9 t1 A( O" ^$ g/ a9 @; Q
  264. ;==================================================
    ( C7 f( r! n# l  x. C) X4 \
  265. ;PPU处理
    ' A8 F+ R, u. r/ n, z- l
  266. PPU_Process
    " i5 D) a/ O! M% e0 V) B
  267. LDA #$00
      k7 f; J) B7 U
  268. STA PPU_MASK
    ( e$ j: L* o9 X( `: t4 Z' x$ H
  269. $ K; X% i  n9 l( P9 l
  270. BIT PPU_STATUS
    # p8 r# g. g) H: R0 K: p) W
  271. LDA #$20
    , \% O6 H' v7 F: e7 @! b
  272. STA PPU_ADDRESS
    9 F5 n) U+ Y* ^8 B4 u( Y' G
  273. LDA #$002 \8 g, |2 W; E
  274. STA PPU_ADDRESS1 Y, Q  G1 ~/ N0 U3 U
  275. 4 ^* D; W- a* R; R
  276. STA PPU_SCROLL
    5 [1 z6 k0 N% @" g
  277. STA PPU_SCROLL! O; m4 q1 g3 G5 n

  278. , B& P7 V: u$ i; h* k: M8 I
  279. LDA PPU_Msak_Buf: |( J$ T% L2 f, f+ c
  280. STA PPU_MASK
    $ r8 @/ [- t2 J
  281. : B+ e( _7 U/ J9 s3 ?: _6 }
  282. RTS
    7 n% Z8 |) |1 U/ ]: m
  283. 0 u0 g4 b2 [) O  `$ ~  j
  284. ;==============================
    + d" `9 y7 b& B. w
  285. Time_For_Vblank;延时等待, R/ K) O) k; P% e7 U' G: O
  286. LDA PPU_STATUS8 Z2 l4 G# p7 C: n" n, p0 h
  287. BPL Time_For_Vblank
    # Z2 @3 {# M7 E/ n% R* l8 r
  288. RTS
    3 s$ o3 q* N  k1 e, d
  289. + ]2 d6 a3 n; ]8 l  E
  290. ;==============================
    0 q$ b$ z% N, N
  291. ;初始化MAPPER19
    & G9 A8 k1 I9 d+ u5 I
  292. Init_Mapper19
    3 T" S4 j( }% g: h
  293. LDA #$00
    : v" U5 j; R" B. u- }; W
  294. STA M19_CHR_0000+ H$ r! M3 R7 [9 M1 @  L2 I
  295. LDA #$016 w$ M. a# c% P- l! H1 G1 c8 F
  296. STA M19_CHR_04007 ?* t1 r- X: ~2 Q( }( ]
  297. LDA #$02& K6 \) s' w) L9 B7 R; t
  298. STA M19_CHR_0800
    , K$ T% J, b7 V. y
  299. LDA #$039 K9 V# _  y) x3 ]7 S9 N  k) X6 j3 Q# Y
  300. STA M19_CHR_0C00
    ; k: _6 X. i1 J: N
  301. LDA #$04
    ) f0 I7 D0 b1 r' E5 L1 D
  302. STA M19_CHR_1000; Z9 D5 M3 r) o% L+ D- r( i* U
  303. LDA #$05
    3 h- u) {0 I2 o; o; }( J
  304. STA M19_CHR_1400; u: J2 M0 [7 t
  305. LDA #$06, v8 @0 M7 T$ B
  306. STA M19_CHR_1800
    + L* S. }& ~, y  w% v+ u" s; t$ I
  307. LDA #$07
    & O: K4 x7 S: n# f! u
  308. STA M19_CHR_1C00( m' ]: @8 S7 `
  309. 0 `3 g9 w# k5 [* ^! `" |, b
  310. ;禁用IRQ5 l3 Q) @- E1 ]
  311. LDA M19_IRQ_COUNT_H6 @- `0 Z$ {% H6 k, i( ~3 W- y! {
  312. AND #$7F
    3 u" n9 d. D: n( Z/ f
  313. STA M19_IRQ_COUNT_H( j8 C; \' W1 ]: e2 M! S5 I7 I

  314. 4 c" f  Q. B3 U7 e3 A5 H2 k: t5 U
  315. ;命名表5 z, W0 D6 V3 z; @
  316. LDA #$E02 Q6 u: I% C/ K0 P- Y2 ~
  317. STA M19_NT_20005 b' k( K- {, l! p" I
  318. STA M19_NT_2400
    ! p( D) ]$ U( @( I
  319. 0 g: |7 P. i9 u* ~+ w- x# z% \
  320. ;命名表
    4 F) z; {# V6 ]% }7 U9 b  }
  321. LDA #$E1
    8 n$ O" O$ ?) n5 q  E
  322. STA M19_NT_2800
    # z' f0 n. Z6 ~* I$ p( M7 `
  323. STA M19_NT_2C00) E, m! B4 ~+ b% v6 g2 o

  324. ; {1 z: t" q; f5 N3 h- `# J* I
  325. RTS
    ; G& z, E5 y5 U" Y& E2 q$ Z+ h
  326. 8 V. d& x# Z+ Z0 J
  327. ;==================================================% e- E8 r: @5 ~
  328. ;重置中断处理
    : z# Z9 u3 i+ g9 k' s- p2 `
  329. ResetProgram
    2 c1 a5 v& L( G+ e+ E1 K5 ~& _, L
  330. SEI$ K+ h0 n( u2 Q% C4 e
  331. CLD
    7 w# P) f  ^  o! l* Y  L
  332. LDA #$00
    1 T# i2 q# i6 B' J( W
  333. STA PPU_CTRL
    8 o* J4 P# \) k5 s+ R  J
  334. STA PPU_MASK
    ! ?2 c( S# G9 E/ H( L4 p
  335. STA PPU_STATUS" _' p/ e2 T* S: ]* Y
  336. STA JOY2_FRAME0 d+ Z  n4 v, V& _* B+ U5 ^
  337. STA APU_STATUS
    & Q% r$ ?9 I& T+ n4 I/ j

  338. ( i5 r( @6 p2 G2 b$ K0 J: n* t
  339. LDA #$C0* l" H4 w6 ^0 ~5 R5 }" h3 G2 @
  340. STA JOY2_FRAME+ E" H2 I( W9 c+ z  T" z/ B! h

  341. % z: c: P0 I9 m- W6 |% F
  342. ;等待vblank4 ^7 f1 z+ x8 G
  343. LDX #$029 k" Z" w  M; H9 d0 f! Y" O6 v; D
  344. Vblank_Wait_19 M6 J2 W' k5 x& {& U( D. G
  345. BIT PPU_STATUS
    / A9 W. d  M+ U
  346. BPL Vblank_Wait_1+ G/ q3 C+ g* C" }8 E0 I) }  b5 e
  347. Vblank_Wait_2  ?; o( R. a# ?) {) y& \
  348. BIT PPU_STATUS
    0 t8 O" r) o# R
  349. BMI Vblank_Wait_2' y. i- Y# S9 v8 T  `
  350. DEX
    8 B, f9 Y, |/ ~) F& ^
  351. BNE Vblank_Wait_12 d0 g& A. {: S" }1 v+ J
  352. ; U6 H# q; @) C$ V; h5 R/ c
  353. LDX #$FF
    8 P! _  b) w7 a* a4 q8 n
  354. TXS/ \9 h" `' Q# N2 D/ ]& F! @# y" s
  355. 3 q, [' z! _, u
  356. ;初始化MAPPER19& v- Q5 l- c0 U
  357. JSR Init_Mapper19
    8 J8 m6 X$ V1 r8 x1 M

  358. 1 ?4 q7 V2 V% s: W" ?6 s
  359. ;==============================2 z0 s+ e, X5 ?$ R
  360. ;RAM初始化
    & q0 P% G& X  c' n6 R+ p
  361. Nes_Ram_Init
    8 b$ P, L6 b3 c. I8 Z7 [
  362. LDY #$00  Z. e) u' N" z. A( m/ p
  363. LDX #$080 x9 Q$ g4 Z6 K3 t# r% y" \
  364. LDA #$00
    $ l% i8 \$ J- N% f3 K
  365. STA <$00
      h/ X5 g" x/ r/ s
  366. STA <$01
    * k6 V8 N  o* }% X2 N
  367. Nes_Ram_Init_Write* H# x# c3 a2 O6 r1 C* L& c
  368. STA [$00],Y% K. o0 t# u4 `
  369. INY# M8 x& }6 Q! @4 {2 e9 ?
  370. BNE Nes_Ram_Init_Write; ^* ]8 n+ J1 Q$ _* W6 ^, ^- X
  371. INC <$01. N+ y5 s* ]/ A, `5 h
  372. DEX* w" C( Q" F5 w7 v' E; J
  373. BNE Nes_Ram_Init_Write
    + H, G; j# t; B+ E

  374. . S9 t- ?6 v9 A: f6 f7 z
  375. ;初始化命名表' H: P) t+ D/ d" a/ O/ F
  376. JSR Init_Name_Table$ n. K6 _3 S# p6 K
  377. 2 T1 ?' ~( J6 }' K! {
  378. ;初始化调色板
    / e5 X& ~; N1 ?( _0 \
  379. JSR Init_Palette
    & _* E$ Z* M7 f) ~4 d0 w0 h
  380. ; N$ J1 k6 x. ?5 M4 X5 L
  381. ;初始化命名表属性
    . C) c- v! D/ [& g9 v7 ?
  382. JSR Init_NameTable_Attributes
    1 f5 {. m. u& w' z
  383. 7 ~9 L( o' L2 n7 g5 U5 T& Y, K8 ^
  384. ;初始化精灵内存
    # p1 A8 Q: n. o- H( c8 @& p; h) Y
  385. JSR Init_OAM_Ram9 L! S+ R$ N) B5 Q9 T
  386. ) V5 S- e3 t6 K4 |
  387. ;在屏幕上写点东西
    ( _4 M2 [& e5 b- @7 h
  388. JSR Init_Name_Table_Text
    % ^% }& q* y6 ]4 G+ o

  389. ) x2 i; Q; F6 v! k, @3 i* c
  390. JSR Time_For_Vblank7 Q% d+ B( d1 f9 o+ p  E( c/ f
  391. ;开启PPU控制& ?5 D, A2 B. S
  392. LDA #$A8, Y5 ]" |: V: r6 T+ g$ K* R
  393. STA PPU_Ctrl_Buf
    ( `  }- U" r% O/ t% M2 d' r
  394. STA PPU_CTRL' @/ L! m) |0 F1 H1 ]  Y
  395. - m$ V4 w5 B, _$ n; K# q
  396. ;开启PPU显示7 n1 _5 W: s/ b! P2 g& u
  397. LDA #$1E
    8 R5 Z9 C( o; s( j
  398. STA PPU_Msak_Buf
    7 M! y# h: t( Z4 l! g" p; q

  399. + N& o+ D- I) I1 N) F) ?: z
  400. CLI* P) V- e7 r4 l0 J. u
  401. JMP Loop! S, s6 X# X8 _/ K' S

  402. ' v0 E: {: \7 o6 U( u1 f
  403. ;==============================& n6 M+ o. A. g6 ]  D
  404. ;死循环, 等待NMI中断
    # ~- G4 t6 o: s- A8 J0 s. {
  405. Loop' L5 M1 a0 m9 _* y& @! _
  406. JMP Loop
    . X# N. d, C5 f# B: L% V
  407. - h3 m+ z/ Q+ b
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    8 c7 _* V6 {9 `9 x

  409. . U9 Y% X( b" J7 ^# J$ C
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    - b0 L/ }( [$ V! s9 F, B
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)' N  R1 l( d+ n; W1 D1 B% D
  412. ;==================================================
    " Q# R* V; F% h4 k
  413. ;NMI中断处理3 a7 r5 `0 @. w, G
  414. NmiProgram
    $ J5 _5 P1 c$ V% G0 c
  415. PHA
    1 \2 P, K2 U/ b& T
  416. TXA
    ) V' w* R6 ]+ {
  417. PHA
    ' _- ?, p  P: Z% I) ?
  418. TYA
    3 `- H6 W2 }- N1 b
  419. PHA* O+ I/ ~# h* o( c% b
  420. 8 J( p  E" V/ e9 u  Q" N
  421. BIT PPU_STATUS, x# ^% r/ g# p/ u. [

  422. , B# G: a; K; k( c
  423. LDA #$00
    ( P; g7 y& r* c* x, X7 f
  424. STA IRQ_Index! u5 N3 H) z" D$ f" L7 m
  425.   v, J- u. G8 [. h( o3 ^
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    / P" }& D# g, H
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)/ u2 f: N' {( m* ?3 J* O1 [: `7 C
  428. STA M19_IRQ_COUNT_L
    / C, {' a- {2 Z! @/ R! p
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)( z' ^& {0 L0 S. N
  430. ORA #$80/ t# h* |6 |1 L
  431. STA M19_IRQ_COUNT_H& C/ ^* ]" |& T" d# G
  432. CLI
    * I/ Z' t5 X, {( Q

  433. 0 ~" S/ }0 I6 g4 |) I1 h+ ]% s
  434. ;关闭PPU控制7 G! v6 g. h+ P2 a+ S' e& B  {
  435. LDA #$00, b5 @- ?' @# ^1 v1 a# T5 o+ C% z
  436. STA PPU_CTRL( h: W' i8 x) l8 ^# V* j& a" S# p
  437. : v% x( |2 n3 `4 ?- H6 L
  438. ;处理PPU
    & n+ M+ \5 i" u
  439. JSR PPU_Process$ @" ~9 ?0 h) ^. g% K  ]0 r, ?/ b

  440. " y0 X% a' w: @9 M& x9 `9 b! u/ K
  441. ;开启PPU控制
    8 _  ?* L; }, Q
  442. LDA PPU_Ctrl_Buf8 S: Z( ~3 b; [& [
  443. STA PPU_CTRL
    1 l( d- a; A4 L8 ?6 t& h9 J
  444. $ O0 y. v. C9 N5 I# j2 a) v/ y2 O
  445. ;手柄处理
    # J; B8 s% n* r6 N2 c! U. L; j
  446. JSR GamepadProcess
      g% `, K; T- C- i" m

  447. " W& C# o# N4 n' I- m
  448. LDA #$00
    8 C! k3 |) U3 e: k! e, B
  449. STA IRQ_Index$ [9 ]5 c' d- i/ G

  450. # c# k" ?7 }- Z; {! u" X
  451. PLA3 `' m& }/ a0 V  U* a% C
  452. TAY
    " n: T0 A6 S3 R" v
  453. PLA. s4 v% T& c" ]1 J/ Q- V
  454. TAX
    - d: e5 d6 I( g6 v2 I3 l5 f% [
  455. PLA( G2 p6 b! N; x$ e. u
  456. RTI
    2 X+ ?4 @! [* c3 F* a

  457. ; z8 p- h5 P, o) |6 [0 K
  458. ;每行扫描线113.67
    : E) P" ]6 R# z7 q* L3 y
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)9 W0 q+ A! I9 ]" I- N; s
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ; T- e1 y' K/ ~' {% S
  461. ;==================================================8 v( t/ L  c' p& O# a
  462. ;IRQ中断处理
    + o% J4 }+ h0 q& I! k  v& w
  463. IrqProgram
    : C. L6 U* H* Z2 m, f6 H' ]$ L
  464. PHA
      i/ T# J2 ], C; u0 L, j: y$ ?. _$ d4 O
  465. TXA
    ' d# H( v' e/ p+ z" ^
  466. PHA
    4 n9 R- D' ?, F( B$ E$ L+ E
  467. TYA9 Y% \: h# C" [% \$ h  {$ a
  468. PHA) `# G9 {6 k& a* C) }' h

  469. $ x; x$ O% B- v* w- Q. u
  470. ;16条扫描线后触发IRQ
    . ^4 ?8 ]$ O4 y0 i2 Y; H
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    4 H+ K: a! g+ {. w3 [4 v
  472. STA M19_IRQ_COUNT_L1 ^$ X3 s4 b: G8 S5 r
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    ! A, T7 n5 `/ {& @6 M
  474. ORA #$80+ M+ R" d. _4 K3 D  |. R
  475. STA M19_IRQ_COUNT_H$ r/ v: i5 b8 ?% C' f! i

  476. / k* @7 r% r9 {- j; u  H2 _
  477. LDA <IRQ_Index
    ! o8 R" j  R  a* ]( t! S
  478. BNE * + 4  ?4 Z7 ^. @5 K0 y
  479. INC <PPU_Scroll_H; K6 C. R7 R% _, u9 l! G1 t' H
  480. " s" h6 ]! `" S
  481. ;设置屏幕滚动
    % p- H: Y+ N2 r* h" c# C! s
  482. LDA <IRQ_Index
    + s+ I2 g7 J1 ]3 ?/ u
  483. AND #$01' G9 G- r" p- `. {1 x
  484. BEQ Irq_Scroll_Right7 r% n3 ^9 W1 P# D

  485. - }' O. P4 M0 a  w( H/ a
  486. Irq_Scroll_Left1 v' _. H/ e- K! A- b
  487. BIT PPU_STATUS
    2 {2 w! e* h1 E" \$ _6 P/ P
  488. LDA <PPU_Scroll_H0 C5 p. V; b0 Z& D& x) k
  489. STA PPU_SCROLL& p( k' f" K, y- I* Z5 x' M0 e% A
  490. STA PPU_SCROLL: ]& ?' ?: D" F% {& d+ ^
  491. JMP Irq_Scroll_Over
    7 E- Z, D' s, F7 ~- r/ g
  492. / |9 D) A; n/ e0 U
  493. Irq_Scroll_Right
    " b- y3 G- r& {8 R0 X: c2 C
  494. SEC
    # N& w4 g3 ~" c% F
  495. SBC <PPU_Scroll_H6 G; |) k: p" a% n! G: }& D1 g
  496. STA PPU_SCROLL" L* ^7 I# e% [* @% h
  497. STA PPU_SCROLL5 |) n( @- m& D3 K1 }: \6 @
  498. Irq_Scroll_Over
    8 P5 @- t9 k6 ^) v# w* W; H5 ~6 ^
  499. 9 S& k- w. O2 d  ?& Z
  500. INC <IRQ_Index; g2 @, L5 D8 V# @+ E3 V% i

  501. 3 Q: Q! |: j3 g' ?; w) F) Z( s7 g
  502. LDA <IRQ_Index
    / i' Q$ H* B7 Y) e/ s) e
  503. CMP #14
    1 b) X4 j' b4 P4 T8 J( _% B
  504. BCC * + 104 g. p) K2 k- ]  o6 k: o
  505. LDA #$00/ U& m. U6 y! A" ~; v! u) }$ g
  506. STA M19_IRQ_COUNT_L+ I3 q) f) r2 r. k/ H6 T
  507. STA M19_IRQ_COUNT_H
    7 `( n/ a" J" W% a* c

  508. 5 }* v. l( i. ^8 x7 I$ |2 h
  509. IrqProgramEnd# G4 H& R7 n4 b! t
  510. PLA2 W* }% r; H/ D2 \8 s- I$ ^+ [$ i; X+ X
  511. TAY) f. \" J6 F7 ?; f
  512. PLA
    . R5 ]6 }3 D7 v% G+ e: ~
  513. TAX
    ! v( b! u: P8 B" u0 r
  514. PLA3 @, U/ l, h0 X" T( r0 |& |$ |
  515. RTI+ ~$ z/ k" j- k7 o! Y1 D
  516.   k4 F/ ?1 |+ r6 m0 F$ m( e4 Z4 u
  517. ;==================================================% D5 G4 x0 v3 {! v" z# s/ ^
  518. ;中断表4 {4 b. F7 g; t/ |: F& L1 v
  519. .ORG $FFFA
    & \8 A3 H5 ^/ e- H6 |
  520. .WORD NmiProgram8 `4 B8 o" u4 v& y4 L6 |0 k
  521. .WORD ResetProgram0 C# d. @( ~+ p5 d+ @- ^
  522. .WORD IrqProgram
复制代码
( z, Y2 H4 ?& r; C

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-12-19 16:06 , Processed in 1.064453 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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