EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ], t  O% i( z0 B( R+ O4 ]  `
  2. ;FlameCyclone 20230710! e# {! ?2 w, d5 G# s
  3. ' o4 f1 X* x( N6 v# b% e
  4. ;文件头
    6 A( Z: E) W) Q7 c
  5. ;======================================================================
    % i/ O6 Y4 Y% _# w) X# u
  6. .INESPRG 4                                              ;16KB PRG 数量
    % O- A$ a7 t# e6 S: W, P, R: U
  7. .INESCHR 1                                               ;8KB CHR 数量
    1 H7 O+ z; B! H. m6 m( r
  8. .INESMAP 19                                                 ;mapper 19
    3 p4 w" s8 D' i9 P/ r' S+ p) G7 U) V
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    1 b- a7 S  r8 k4 m

  10. 5 H* Y) H0 \2 I, {$ g' \2 C
  11. ;必要条件4 l7 {9 ?- \0 U
  12. ;1.持有CHR ROM9 y; K' n* {1 [% ]8 Q! ?+ O
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10002 n9 N; |3 G1 V6 h$ E1 O
  14. ;3.精灵内存(OAM)不为空6 m/ E& I/ f' {9 s

  15. ) ~8 E) U! S+ m1 R# c
  16. ;==================================================% \* t' B5 j. i) E7 n  \
  17. ;NES端口常量
    + n& ?$ u' Q+ j3 S
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    . `% B1 c3 K7 K$ D9 f0 B# u
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器6 O6 ?# p; `- g. d' x0 X$ f
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位& r, d6 d" O8 O- C0 H  `
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加15 C2 S9 Y, C/ A
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1  u) R5 T- Z. I2 T) Q4 [
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    / `; Q6 V/ Q. C% m4 ?& n8 u" o
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    ' V  S! P: S- N; t; _# [
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 4 {8 g: H7 c( [, d  p
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ( s. K% N/ z7 }2 ^0 J
  27. APU_STATUS              =   $4015   ;声音通道切换
      b5 i$ Q: E/ v& l+ e% S* P
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    9 ^+ d  i# U1 H$ r6 K
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    : ~) H, T" P' ^

  30. , ?/ c. v8 y+ Z& u# u4 K2 F; S
  31. ;==================================================( B6 p  o7 G! V( t/ u# I
  32. ;MAPPER 19端口常量
    + j6 W/ a/ c6 V
  33. M19_CHR_0000    =   $8000
    & Y$ _' ?6 O( F( T+ b! @
  34. M19_CHR_0400    =   $8800) D- F9 ^( V1 ~9 o
  35. M19_CHR_0800    =   $9000
    - h: o3 ]9 W8 g8 [
  36. M19_CHR_0C00    =   $9800
    7 L3 B. \0 [3 ?5 T
  37. M19_CHR_1000    =   $A0001 }; b! O) H9 P
  38. M19_CHR_1400    =   $A800
    ( k% G6 q; n3 {
  39. M19_CHR_1800    =   $B000
    % Z1 m, j! w/ I0 @% a
  40. M19_CHR_1C00    =   $B8007 a. t4 p% R. [* S1 }" O
  41. M19_NT_2000     =   $C000/ C# J0 O# {. |, g+ U5 S) Q1 y% d
  42. M19_NT_2400     =   $C800
    / q  J8 x% ?) l( R2 |) N- v
  43. M19_NT_2800     =   $D000
    , l5 A, \) C& s* t" Z& v
  44. M19_NT_2C00     =   $D800
    6 W. R+ o5 T# ?2 T
  45. M19_PRG_8000    =   $E000
    9 K$ H6 `0 y4 O' J, h6 \% t8 g  f
  46. M19_PRG_A000    =   $E800) L5 p7 `, c+ Q& R  D4 X, X% X
  47. M19_PRG_C000    =   $F000; `" f) U# ]% a+ q0 M/ n9 Z
  48. M19_IRQ_COUNT_L =   $5000
    $ z$ c* y8 S$ i& F; m. X# v
  49. M19_IRQ_COUNT_H =   $5800
    " N( e/ O- D" H# g1 D& Y

  50. - F/ @; a: c: c# w9 v
  51. ;==================================================5 Z  N9 Y( F- W" b
  52. ;程序块配置
    & e$ r3 l) [( S% A& W9 C$ |. x9 z
  53. BANK_DATA_MASK          = $07  w' ]; N' t# i: c9 Q
  54. ;--------------------------------------------------; l3 ]. {+ x* D' g% B/ e
  55. RESET_BANK              = $071 u. i# z2 H9 M1 ~4 @% w0 ^
  56. RESET_ADDR              = $FC003 k+ G% R" R  I- f# U2 u2 y" V. I
  57. ; V* Z  M: y2 b0 v1 e8 s
  58. ;==================================================) O" w* X1 [# Q6 {  ~2 v
  59. ;图像块配置
    8 l/ _; K' O, }0 Q! @7 _9 t: n
  60. CHR_DATA_BANK           = $08
    * g1 K0 s5 G" N( B' I& F
  61. ; G( ^& Z) R% d, ?
  62. ;==================================================; a+ Y+ U7 [& T! ]
  63. ;零页内存地址配置$ G% n7 l8 u: u* n4 W' w1 E
  64. Use_Ram_Addr            = $80' C4 U$ W  ^, \9 X1 e1 s8 M
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    3 T, Z$ a' a+ Z5 F  a8 ?. E
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01- G3 e- y6 g. z$ p
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01) p. ?: \( m. W$ J' ]7 P6 c
  68. PPU_Scroll_V            = PPU_Scroll_H + $010 _3 p; \* W/ ?
  69. FC_Data_L               = PPU_Scroll_V + $01
    5 s( R$ Z$ r: p) T/ U" g
  70. FC_Data_H               = FC_Data_L + $01
    ! l- g+ A  p( r8 n# W
  71. FC_Data_Buf             = FC_Data_H + $01; d$ I6 ~1 ~- M8 s% ^% f+ S6 |
  72. ;==================================================8 \/ p4 |% I2 n) D) k5 J4 |  J
  73. : c. ^) n3 x* f7 L. t& i
  74. GAMEPAD_MERGE_FLAG = $04
    % r/ A( b' Q6 {* n! Y6 R# K

  75. 2 v& t8 Q$ r3 n* ?# S! ^& i
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    ! Y( f# T' l: ~
  77. Gamepad_Once            =       Gamepad_Keep + 2
    # N3 n; a5 e' F# l. q9 P) G, d* z
  78. Gamepad_Temp            =       Gamepad_Once + 2( y! D; f$ N9 ^" X/ _
  79.                                 - g( |$ v+ n# c& }
  80. Gamepad_0_State         =       Gamepad_Temp + 2) a/ k9 z1 \9 A' t- j  {; O
  81. Gamepad_1_State         =       Gamepad_0_State + 10 R4 H' R1 Q8 P; k
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    0 h" W9 z) N( y
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1( Q% T  D, X! H/ w, B
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    # c  A8 k$ ^! ^( X8 V: G
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
      m" I1 p4 ]! L$ n8 ?
  86. 4 h* N' F" k/ r: Y8 ?9 F0 Q0 y
  87. ;==================================================6 G3 x& |/ }3 [' N
  88. IRQ_Index               =       Gamepad_Merge + $01
    2 k6 m- W$ X* s
  89. ;==================================================6 M) i1 ^; W% y! o: z! N! G) N  A2 o

  90. ( p" N1 j' B1 S- ~+ k
  91. ;CHR图形数据
    - n2 \: Z5 |* Q% m1 V  s/ f( u' |
  92. ;==================================================
    - b* i+ E* d' u- Q) c& k" [
  93. .BANK CHR_DATA_BANK
    6 k, k$ S6 p, y+ b' Y# c" h
  94. .INCBIN "chr_bank/chr_data.chr"
    . Q; ^: s! K$ J) Z6 v6 ~
  95. , v! `+ ]6 _6 V2 B& R: T
  96. .BANK RESET_BANK & BANK_DATA_MASK9 g) F  g. H2 ^& y3 P/ {; I& Z
  97. .ORG RESET_ADDR
    ' Y# v6 A3 C) E  z% f2 N, ^0 o6 s

  98. 6 h; l2 K5 e: h3 x; _
  99. ;--------------------------------------------------; w6 Y; M. W) l8 u+ }( |0 g/ _
  100. Attributes_Data
    2 F$ `0 U- J- y# i/ _
  101. ;命名表属性
    , k# B/ w2 [/ D, w: v% K3 F+ B4 O
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    , U4 C9 b3 l+ L+ }
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    $ S# B5 I. D) h5 H* p) u/ a! ?0 P
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    5 g9 i, y: C# z6 |3 `
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
      ^: G4 ^2 l: l1 z* z, ?
  106. ;--------------------------------------------------
    ( ?4 o6 T% `  \# h: Z* U
  107. ;调色板数据
    8 v5 c& ?& B1 N& N4 R
  108. Palette_Data- }9 ~- g& `" G" d+ ]
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    $ V3 t9 T2 O/ K$ `
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 H& C5 f, I6 t2 B8 `( N9 F8 T

  111. ) R! a. z! j3 I& P
  112. ;==================================================7 t& a9 R, H: |2 \- R* N* D( T: _1 ]
  113. ;命名表初始化* }# L$ l$ x) V
  114. Init_Name_Table( ?* N3 w9 k5 ~6 w' G4 P
  115. LDA #$20# d1 J' K: K+ \4 P6 w. w1 ^
  116. STA PPU_ADDRESS
    ( e% h9 q/ R7 V1 w7 q5 J
  117. LDA #$00# Z/ c' G( P3 c# X" z
  118. STA PPU_ADDRESS
    , B* h0 U7 q, b" j: w- z$ e6 N4 C
  119. LDA #$00
    ) e$ u5 ^0 A8 |  E; R
  120. LDY #$00- B. ]2 h) i; K4 T8 {4 n
  121. LDX #$10
    * x3 e1 j0 @. t) o, H: X
  122. Init_Name_Table_Write
    ' @! c) f7 ]! V& k) H( x
  123. STA PPU_DATA) i( I5 v1 k% r6 T7 q$ `, |
  124. INY
    ' B" r  @# k! V( \' q4 s
  125. BNE Init_Name_Table_Write
    : A% v2 v% k# ]
  126. DEX) ^& d. p9 r6 q0 O2 H. _0 S
  127. BNE Init_Name_Table_Write
    - U# H' _- Z1 B1 M9 {0 X% Y
  128. RTS
    4 J. `' m- z- a. {
  129. 4 j9 b/ k8 A) }* M5 ?  r
  130. ;==================================================
    4 F1 K9 g2 C9 K; W3 p6 `
  131. ;调色板初始化
    ) `) D5 l5 ^1 O9 H1 K
  132. Init_Palette
    ' t* t1 x8 J- C2 _8 T3 y- O; G
  133. BIT PPU_STATUS
    6 n- h8 D2 s; ~$ Q5 b- e* I4 t& O! M
  134. LDA #$3F
    2 c  F' J( m1 D, ~; b& r
  135. STA PPU_ADDRESS
    ' G' v+ l( @% d2 ~2 f8 t6 `0 q- _
  136. LDA #$00. s' n$ z) b+ ^5 L9 q; W- r2 b
  137. STA PPU_ADDRESS
    / t% X- p! J; e5 f  Y
  138. LDX #$00
      [3 }6 z5 Z) R, C
  139. Init_Palette_Write8 L3 h, m! @! g6 H) l
  140. LDA Palette_Data,X
    - d1 D# W+ d. f( a+ k% L$ {, u
  141. STA PPU_DATA' a6 z" V3 T" d( C, ^
  142. INX0 f9 I3 ~9 j' \; R
  143. CPX #$20
    4 b( S0 L  x# g
  144. BCC Init_Palette_Write
    & ~- H7 }5 s) r3 |; Y8 u
  145. RTS% K$ s3 X" k7 q6 B4 w6 D; S
  146. 0 M) T. [1 k( F8 P7 R9 A, O$ X
  147. ;==================================================0 O' _5 x& E; g
  148. ;设置命名表属性: {, L) s3 Z1 o/ Y3 o5 j; ^
  149. Init_NameTable_Attributes
    5 n/ W2 P3 J1 j1 b  M% I  x+ p
  150. BIT PPU_STATUS8 `! ], s6 u& }' A' Y
  151. LDA #$23
    5 w9 k6 O: k2 i7 |' ~$ c' P
  152. STA PPU_ADDRESS
    0 s- W1 O# J3 Z" @
  153. LDA #$C09 H1 n7 |+ c/ A% i3 i. [& \5 ?
  154. STA PPU_ADDRESS9 G1 x: U: u7 t; Z; H
  155. LDX #$00) P0 j6 n! d4 `
  156. Init_NameTable_Attributes_Write- [+ g" d5 i- K! \/ L4 I- p& \
  157. LDA Attributes_Data,X
      z9 Q8 W: |  D' Z+ @9 C) f. n
  158. STA PPU_DATA
    6 J3 Y# s' M% M; Q" _
  159. INX
    3 m# R0 M5 T. U, k8 }9 i$ g
  160. CPX #$40
    5 m' _7 A& {+ j
  161. BCC Init_NameTable_Attributes_Write
    - U5 K8 ?% n6 Y' p& o9 Z$ u
  162. RTS
    ) x" F  T9 i, [& n" i

  163. 9 P+ W0 T7 ]  G9 T+ h4 j
  164. ;==================================================
    & Q# Q  B/ H2 m! r
  165. ;初始化命名表文本
    : h0 t& p$ M; p. \+ c6 t" p) k
  166. Init_Name_Table_Text
    - r* T* {* _4 p2 s( {
  167. BIT PPU_STATUS/ P9 `9 H3 }; y
  168. LDA #$20- B2 ~0 }3 G1 E4 f/ t4 U
  169. STA PPU_ADDRESS
    4 J3 Y- F7 r$ {7 \' B* F
  170. LDA #$00
    0 [5 V" `( M9 y7 R) q1 ?# v4 I9 k
  171. STA PPU_ADDRESS
    & s* t4 Y/ t0 ^. \
  172. LDA #$007 z( m7 m: y( W& @
  173. STA FC_Data_Buf
    : c4 y9 P* L9 U" ]
  174. LDY #30
      D+ T) [. ^4 t# O) D( v
  175. Init_Name_Table_Text_Write
    5 F, f  o8 ^# a
  176. LDX #32$ ^7 M+ h9 Q1 u. c3 h0 L
  177. Init_Name_Table_Text_Write_Char
    2 r+ Z3 n* q5 [8 c) b
  178. LDA #'0'& S' R8 ^0 _" W. [! r
  179. CLC; D1 V$ Y/ Z; c* k, ?% ^/ |
  180. ADC FC_Data_Buf
    / d( j: \* V6 Z  {8 @; l6 N
  181. STA PPU_DATA5 I3 B2 p- \1 r" c# x+ {/ U
  182. DEX3 h3 T# `7 ?: \, ?, f& h! n
  183. LDA #$14; U, {# A, H; Y: _) _
  184. STA PPU_DATA  Z# n6 v# J7 D% A: w7 {
  185. DEX
    1 _6 u' M' S1 X( [
  186. BNE Init_Name_Table_Text_Write_Char
    1 v2 T. e7 A3 f: w5 ~/ S
  187. INC FC_Data_Buf
    / ]: K* l" A& i% f5 F
  188. DEY
    * o) a9 o/ y" w8 |
  189. BNE Init_Name_Table_Text_Write5 @, |' z1 V+ f0 o; Z. I
  190. RTS
    9 V8 C- @" k" O; x3 v

  191. 0 @5 U% P% |" S0 L5 F: X% v8 q
  192. ;==============================
    9 d: L" Q* Q$ s7 p. Y7 E
  193. Init_OAM_Ram;初始化精灵内存
    8 t6 d1 r! f5 b+ S0 A2 E0 H
  194. LDX #$00
    ! h- A7 K, C& o5 Y
  195. LDA #$00
    ( p( V' U( Z7 A  \7 r) C
  196. STA PPU_OAM_ADDR
    7 T7 J; a- c2 L" Q
  197. LDA #$F8/ V! r6 L8 ]+ o( k
  198. Init_OAM_Ram_Write; E& R$ w; d2 t1 Z: L+ V& z( l
  199. STA PPU_OAM_DATA# R# }& F- ]; D4 o% i8 d) e* t; t
  200. INX
    1 O% W- b2 X0 e" J/ U" B
  201. BNE Init_OAM_Ram_Write& {5 a# q8 I! R
  202. RTS* k: u& a5 Y4 n8 c4 G+ V! g7 e
  203. 2 Z5 P' R0 W- t5 h3 v% V# B5 O& f
  204. GamepadProcess;手柄处理8 {6 c( [0 j# D. u0 p8 l6 p
  205. JSR GamepadDatacan$ P3 h; [5 n* E7 w8 G/ j% {- [7 F
  206. LDA <Gamepad_0_Value
    3 Z7 R, i* R. E
  207. STA <Gamepad_0_State, H0 @. i+ I4 k8 i/ W0 n" X' d( y% a
  208. LDA <Gamepad_1_Value3 w1 P: Z, U/ Y1 F7 }
  209. STA <Gamepad_1_State
    2 ^! A' Z5 M7 u
  210. JSR GamepadDatacan* `! n% _- M! D' f# Z7 T/ U# z
  211. LDX #$01
    5 T' s4 \# T  X( a2 O. b
  212. GamepadMergeCheck;合并手柄输入检查* t( u$ [  R2 ^: C4 c: k% k
  213. LDA <Gamepad_0_Value,X
    / r9 p, |2 w: f# O) P9 f% w
  214. CMP <Gamepad_0_State,X" @" t, t2 o8 ~$ a$ b1 c* j% `1 A
  215. BEQ GamepadMergeInput9 k- P0 v' K) ?
  216. LDA <Gamepad_Temp,X' e" N& b/ d& J; J. P* k  G" ~0 z3 Z
  217. STA <Gamepad_0_Value,X
    9 u- h+ l/ A# I& z) s2 W5 Y
  218. GamepadMergeInput;合并手柄输入! S; b) p/ k. p  J; Z
  219. DEX2 _+ {/ A( d0 Q# K7 F  ^5 c4 E9 g
  220. BPL GamepadMergeCheck
    + Q  O8 V  F7 H% Y4 w/ @. R
  221. LDA <Gamepad_Merge; R% S( }; X" X0 u
  222. AND #GAMEPAD_MERGE_FLAG8 Y6 _) \4 G/ u% F. I. a+ R) M, i
  223. BNE GamepadStateProcess
    # I- c3 _- f2 d- d  Y4 z" i1 r5 h
  224. LDA <Gamepad_0_Value
      ~+ x& y, a' Y2 w. \
  225. ORA <Gamepad_1_Value* R7 p" f3 o9 Q# W2 ~
  226. STA <Gamepad_0_Value! q4 g0 d" Q$ H4 {: ~+ j6 _8 a
  227. GamepadStateProcess;手柄状态处理: }6 e6 o' r- @8 O6 E
  228. LDX #$01
    ! ^* m1 T' B; [. \
  229. GamepadStateSave;手柄状态保存
    5 {7 j- h! b6 x! x- z7 H- @( {
  230. LDA <Gamepad_0_Value,X
    " `4 ?- X! z/ M! N5 Y3 U: Z
  231. TAY
    9 Q+ d% ^5 W. b; A( k) w$ l6 d
  232. EOR <Gamepad_Temp,X  d/ P% X; c8 x/ N0 y- a/ X7 ?
  233. AND <Gamepad_0_Value,X4 D7 s5 u, l  @8 d( ]/ C" N
  234. STA <Gamepad_Once,X4 j, J* D, w1 ?  i6 B! y7 n$ n
  235. STY <Gamepad_Keep,X
    : z6 r8 ], Y" [
  236. STY <Gamepad_Temp,X* u% e+ Z; f7 U+ S- X
  237. DEX$ S( m- h3 ~8 V8 }! X: H
  238. BPL GamepadStateSave
    3 q9 |" m7 {$ s6 `( R* A2 @
  239. RTS1 L# g4 b& q3 Y5 y
  240. / G0 A& X) N; V
  241. GamepadDatacan;手柄数据扫描* g. P7 }7 I2 m! E/ V1 k
  242. LDX #$01
      p5 Q+ \5 R; x* b6 A+ g
  243. STX $4016
    3 Z: f2 {" A% X0 U" @/ z
  244. DEX) @0 c1 n) c' x- q( {
  245. STX $4016
    : a, l, {9 x8 ?+ e5 c
  246. LDY #$08
    9 e3 g2 }1 n4 l, K- i. b
  247. GamepadPortScan;手柄端口扫描
    $ c1 q/ v2 O9 \) k( V
  248. LDA $4016( ?7 |  E" H3 O' ~' U* g
  249. STA <Gamepad_Port_Value
    % \# w6 P9 A# P) z3 E& |* w
  250. LSR A
    6 t- [" E. n6 U  s; M& r
  251. ORA <Gamepad_Port_Value
    1 Q/ Q3 R) s8 o6 \4 S- w
  252. LSR A4 u6 ^  p+ @, ^# O1 b0 ]- E. [( E
  253. ROL <Gamepad_0_Value, i$ Z7 y$ u. T5 a# y0 Y, L
  254. LDA $4017
    5 o1 ^8 A- d1 C
  255. STA <Gamepad_Port_Value
    0 x6 E7 J3 K9 g- w
  256. LSR A8 O& L$ [# r7 K# ~, W
  257. ORA <Gamepad_Port_Value1 B, }& v: q0 r4 |4 g/ U; c2 R8 U- d% [6 J
  258. LSR A# J) d- I4 |+ p7 X0 Y# S
  259. ROL <Gamepad_1_Value
    " N* h7 u( f9 U0 }# u
  260. DEY
    - E. R$ M7 H$ B; P4 R9 C8 r
  261. BNE GamepadPortScan
    4 _. j! |8 h+ l8 t- J. F
  262. RTS* W$ m/ |3 }/ r
  263. 9 H3 r0 ~& u' q% B$ p% A3 `
  264. ;==================================================/ W8 @, r8 L7 `5 {/ w" L9 W" a
  265. ;PPU处理
    1 n) ^! V: a% t4 T1 y
  266. PPU_Process
    ( T$ d4 a: ^; Z4 @2 Q% \3 ]3 f
  267. LDA #$00+ ?0 N; c3 C+ h3 U- L! ?- f
  268. STA PPU_MASK
    & I) t% W# a' ~: ^& E" ~
  269. 3 Z! {9 |! A1 q) F
  270. BIT PPU_STATUS: s  a  b; u3 l! N4 I# l
  271. LDA #$20
    : Q! r& H, m7 C# O% W8 u
  272. STA PPU_ADDRESS. B% q+ i2 \' r0 D! m, Z  i
  273. LDA #$009 a2 W1 u7 q  }7 [: c0 j
  274. STA PPU_ADDRESS
    5 K9 X0 |& J7 @) ^

  275. 4 h% X0 y" T+ Y0 A4 O, w
  276. STA PPU_SCROLL9 B$ y3 M. @. a- T+ z
  277. STA PPU_SCROLL
    3 H1 M) S; C+ Y7 n: P' y6 }1 O

  278. 1 X/ n* P+ z0 L
  279. LDA PPU_Msak_Buf7 W3 s/ T2 D5 f3 l
  280. STA PPU_MASK; w) J; K& L( O$ `/ H: A

  281. . S' s3 K" s7 L
  282. RTS( i  G; U! S( Z- T! Y( i% T% l
  283. : z1 ?$ n9 y5 F
  284. ;==============================) b1 u8 B' f! |' j# T
  285. Time_For_Vblank;延时等待6 W& M5 A0 c" g: i% H* g3 _
  286. LDA PPU_STATUS
    - x9 o- r" E0 u7 F
  287. BPL Time_For_Vblank) n2 s2 G' s. e" M& C- I
  288. RTS$ o+ d% R4 B% H2 D6 J: }

  289. ( h; O4 b# [" P) _( J2 B" q9 J
  290. ;==============================* j5 e7 L7 @  W6 R9 ]- T& ?: q; C
  291. ;初始化MAPPER19
    9 p4 ~5 v1 I- ?$ \
  292. Init_Mapper19
    ) r7 ~5 Q  _0 h+ c% c8 ^
  293. LDA #$008 Q; g- o  w7 l
  294. STA M19_CHR_0000( d2 `- |6 g3 s+ G. M) s$ a  p& h
  295. LDA #$01
    & }" O  g/ \! R8 m1 G7 V2 c
  296. STA M19_CHR_0400) f, i* }7 \6 n2 S) I, U  F& d
  297. LDA #$025 ]; c$ b9 B7 F% v$ F
  298. STA M19_CHR_0800
    ( x8 z& B! z2 }
  299. LDA #$038 t; R% ~* q! m3 i6 h6 R
  300. STA M19_CHR_0C00
    : b6 m% ]: X2 p: X
  301. LDA #$04
    0 F( v/ i8 z; z0 `; f
  302. STA M19_CHR_10005 n2 b: x* F2 G4 s$ B0 G
  303. LDA #$05
    7 y' [7 D$ D7 }6 c# `6 z  V
  304. STA M19_CHR_1400
    8 B9 s. F' y6 D6 H
  305. LDA #$068 Q* L- {! i$ M: T2 ]
  306. STA M19_CHR_1800+ X# }  a# j; B/ e; @- K
  307. LDA #$07' M+ m- \0 E' w4 M1 ]/ n
  308. STA M19_CHR_1C00
    ' i/ |& a9 n4 g! `+ V
  309. ' v1 T( s) K1 F4 D3 e9 U
  310. ;禁用IRQ: X$ u" y' _# J! y
  311. LDA M19_IRQ_COUNT_H
    9 l  M- U2 [  l" R
  312. AND #$7F
    2 ?0 @. q2 q; ?3 Q& i
  313. STA M19_IRQ_COUNT_H' r. _8 R% W( C: ~2 k# B

  314. ; p! Y, D, A& s0 H' t0 m7 R1 I! ^
  315. ;命名表; a6 `3 o( |; x5 F
  316. LDA #$E0* ^0 Y( j: ~- H* }+ N3 q
  317. STA M19_NT_20005 J+ T3 G8 g0 D3 T6 Q' B) o" x
  318. STA M19_NT_2400$ I+ K3 m' u) i

  319. * p0 N3 w3 B1 s
  320. ;命名表
    7 q( l  m1 i! t- {3 P5 k7 i
  321. LDA #$E1# l( |9 F, I- Q7 \  T, C
  322. STA M19_NT_2800. j) _  t1 M6 r  R2 Z! T' ?2 g
  323. STA M19_NT_2C00
    ) m7 q9 S" y% D' F: s2 {% @, ]

  324. # V* @# R. J5 }
  325. RTS- |9 a. ^, @( M* n4 O
  326. ( G# V' d; }4 i9 L7 T1 {8 s
  327. ;==================================================, [9 x6 m- d) K. r) e! x+ V- Y; x
  328. ;重置中断处理
    . @* A) d: y. D7 \, l; f  \6 ]2 S: U
  329. ResetProgram, K. L" D% s) v7 W) I
  330. SEI
    : y2 E9 X  L- Y& K
  331. CLD" X4 Q& }+ D& x. X
  332. LDA #$00
    & T2 m* m, _! V, H1 O2 t: p' `# s
  333. STA PPU_CTRL
    ! B# T/ E7 l/ `0 `/ _
  334. STA PPU_MASK
    8 L- R7 S1 a( l, L; g! g" e
  335. STA PPU_STATUS& i5 Q7 \4 h5 N( h" X# \0 b
  336. STA JOY2_FRAME
    7 n( E/ ~8 B* S% k2 a
  337. STA APU_STATUS* g0 G9 ~# s6 k3 @2 u0 R+ j

  338. + t8 n$ ^1 j9 s
  339. LDA #$C0, I) {+ k. R% K8 {2 V
  340. STA JOY2_FRAME; n1 v4 v4 `+ @8 C1 c+ H
  341. ) |3 z- [5 v' Z5 [
  342. ;等待vblank: w% y- i% g0 ~8 W' a0 O
  343. LDX #$02) _. h4 b, \1 F' M4 ]/ }+ L
  344. Vblank_Wait_1
    % ]  O9 A4 P" q! t) S0 G" M
  345. BIT PPU_STATUS' h- Z9 E4 T5 S- r" U/ b
  346. BPL Vblank_Wait_13 }0 T' g1 C) F
  347. Vblank_Wait_2
    ) @. H8 L" R) `
  348. BIT PPU_STATUS
    ' O5 v* S* F4 M
  349. BMI Vblank_Wait_2
    : Y6 u1 X. G6 W
  350. DEX  V. R5 G5 N& K% f# _
  351. BNE Vblank_Wait_1
    + l) x! ^+ c; Y& j4 N+ d

  352. % x, M9 \0 j1 {# L
  353. LDX #$FF1 W$ B8 r( r& N3 I: t1 D9 I0 Q
  354. TXS/ L/ _: s* \, o; f

  355. / O  i' e2 e  h. H4 j: i2 \- A
  356. ;初始化MAPPER19
    ; ^+ y% j, o2 g) b2 X  q5 H6 q: E
  357. JSR Init_Mapper19
    # k; e9 d0 G- [4 R; R0 {; p% K1 z1 _

  358. 9 O+ z* k, ~% P
  359. ;==============================
    # G# H: d  ~  g( g1 |) a6 n( X
  360. ;RAM初始化
    7 O; a' O8 Z3 Q" [
  361. Nes_Ram_Init
    : L9 s1 L4 h) S
  362. LDY #$00! U# l- s1 w+ Q- [9 I* O  C
  363. LDX #$08& T$ p8 H1 ?  T6 W+ J
  364. LDA #$00
    1 Z6 l* k, C0 w6 k8 ]4 L: `' j/ ^$ ~
  365. STA <$00
    9 V  ~% ^1 T3 U. |4 v: H) l6 \
  366. STA <$01
    ( W8 E5 X  |0 X* b1 _. W  ?
  367. Nes_Ram_Init_Write& L( }/ e% q! T1 ?- r
  368. STA [$00],Y- @8 V  ~2 ]- v+ \& p
  369. INY
    , L- H3 F, P+ c! a
  370. BNE Nes_Ram_Init_Write
    " r# g7 j2 N( U3 C( ?. v( q
  371. INC <$01( L( V% v* n5 w7 V
  372. DEX, Y. Z9 X' o, z+ i
  373. BNE Nes_Ram_Init_Write
    . A/ \( P$ @6 `7 X- I
  374. & }! E$ @. H" P0 D
  375. ;初始化命名表8 O2 g6 e1 Y. t' K* m
  376. JSR Init_Name_Table; R% p. i1 B4 B, \. K

  377. . f3 H5 [2 r$ _
  378. ;初始化调色板( o) s0 q; N( d0 F, ]  Y$ Y
  379. JSR Init_Palette
    2 I" U+ E0 M6 w8 N8 k5 L
  380. ; S3 J8 K8 I& r- ~9 |
  381. ;初始化命名表属性5 i7 [2 A  `+ a6 Q
  382. JSR Init_NameTable_Attributes
    4 H' J$ z/ Q+ L$ b* n$ w! F% G

  383. 1 V1 U6 M$ s" X9 s* e
  384. ;初始化精灵内存
    $ I7 }( ?2 {" W5 e% `' ~6 Q7 h
  385. JSR Init_OAM_Ram
    : }/ o" V# Z# B
  386. + }/ Y2 J" R3 B
  387. ;在屏幕上写点东西% ]% R2 T. Y- Z4 I9 H" e
  388. JSR Init_Name_Table_Text0 Q( {; Z9 o5 B3 w$ s
  389. ! F, u8 A- N! F+ _2 f: P
  390. JSR Time_For_Vblank) b5 Z" ?6 J7 b* K' C0 N: i, m
  391. ;开启PPU控制" |! k. p1 d6 A! V: e
  392. LDA #$A86 }. _) c2 Y" Z
  393. STA PPU_Ctrl_Buf4 ]% f' L) @8 ^8 i2 i
  394. STA PPU_CTRL
    # P5 f1 n, ?6 H; I7 L  V" {
  395. ! Q5 x& Z8 i& K
  396. ;开启PPU显示
    2 M. {  A& t$ Q1 j8 X9 j6 N. X
  397. LDA #$1E! M: m0 B/ K; t  x* N+ v, [/ M
  398. STA PPU_Msak_Buf8 T9 r& E. L3 Z1 g+ c; ~9 j

  399. ) v" [/ x8 t% z# p6 P. p8 y0 ]3 }  w
  400. CLI  k% L- y: t$ k* o" K+ r4 W
  401. JMP Loop; l: b6 ]3 V4 {: X8 _2 J4 _

  402.   |& x+ j9 }- F' z1 F. B
  403. ;==============================
    % w2 k/ J, W) B' |4 _
  404. ;死循环, 等待NMI中断
    ( W  C, n/ u" j- c
  405. Loop
    : j% k- _+ a5 e& H5 w: {0 b5 @
  406. JMP Loop
    2 Z" d9 i/ r- _. ^  ?- c2 o

  407. / C3 A% ]5 {( f) N
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967+ b7 n0 Z: x5 D& [1 e. D3 {( I
  409. 2 w  ], Y/ ~" ]6 L) L! }
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967); b$ X+ w1 l& t9 w
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)8 z- @+ ^( B, N2 W* d" F
  412. ;==================================================
    / o) C7 X  y" @1 H6 ~
  413. ;NMI中断处理
    ! N9 Y, F! P3 Z" [
  414. NmiProgram: S" K5 v( C/ c' U; A
  415. PHA
    4 j0 U& S9 t# C
  416. TXA
    0 B; J- f8 C6 f
  417. PHA
    / p/ M' t5 a& L
  418. TYA
    $ J- n- n. A) h0 ^
  419. PHA
    7 i/ c2 U, n0 A9 M5 w; g: _5 W

  420. & W7 l" L2 b" x" S
  421. BIT PPU_STATUS
    & O: {0 Y' C  z( \

  422. 0 z' a& X/ u* k
  423. LDA #$00
    2 W" s5 n+ m0 K  Y
  424. STA IRQ_Index* f. L6 C, N; n) C

  425. 3 L) y# O3 m3 n9 J: F' q6 Q7 `  K
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动2 [# M+ L$ a& ^$ B  u
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)% {5 f! v8 B" M# M/ I. h
  428. STA M19_IRQ_COUNT_L$ V/ U+ A7 l. G; p* L
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)* L: w9 s9 k5 K. A1 O
  430. ORA #$804 V1 \. _- ?" l" s$ a' O
  431. STA M19_IRQ_COUNT_H
    / z4 u; I; Y5 s( ~3 S% T
  432. CLI) v( A! z/ l# I4 G4 b

  433. % U# i% U* O7 @/ o3 F) l& V7 v: y
  434. ;关闭PPU控制
    * k4 `* ?% a" r, z0 [/ r
  435. LDA #$00$ R# h- e4 b# D5 i8 K
  436. STA PPU_CTRL* |" \7 \! [9 M+ s7 Q2 r

  437. % H7 U4 y& {  a( U: j0 f4 A* ^
  438. ;处理PPU
    ' ^  _$ I& b; z* o9 E. S7 z
  439. JSR PPU_Process0 o! j4 ]- Z4 H3 l$ \. p& d
  440. ' h0 a" W( W) a  `9 Q
  441. ;开启PPU控制$ b  J2 p; k; K$ F
  442. LDA PPU_Ctrl_Buf8 q4 z' b" A9 \6 n" \
  443. STA PPU_CTRL
    ) ^6 a; b' L2 D

  444. 7 u% \- Z2 I( c' k; D
  445. ;手柄处理- O+ G" f" {" R+ {8 @1 j* L4 J
  446. JSR GamepadProcess
    / f# ~8 [3 u! @. \" g& `: r

  447. 8 A/ h' ^0 f9 X' ~
  448. LDA #$00, p+ v; ^% U4 {: W; }( L% j4 l* z0 F, o
  449. STA IRQ_Index1 y) g- N6 J/ M- d, l4 k% l

  450. * R* H( n0 ~* s* u2 W7 m6 b1 e, T9 P
  451. PLA
    & L$ G4 r# G+ T3 a- a( U
  452. TAY9 W, p) i, h! Q- l, x
  453. PLA7 r6 p) K% H) ~! Y) F- q5 w. O
  454. TAX& Q5 E4 x0 }$ G7 u- H% s
  455. PLA: f- \: K5 e- ]3 Q& i  Q
  456. RTI3 b6 @& B: H- c2 q

  457. # E. P- Y0 j( P8 j( g0 h+ C7 S5 s5 p2 E- r
  458. ;每行扫描线113.67- ?: e% ~* g& x% h) c0 r& z# o
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)( Q+ H* V, Z! b; p2 v
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ; t$ z8 ~% n/ A* U3 O: j
  461. ;==================================================3 }( b5 d3 b' w# S5 h
  462. ;IRQ中断处理/ _% N9 \4 _7 _* `' f& v7 q
  463. IrqProgram3 h0 ]- _4 S% T3 h% d5 L+ a* B7 U( n
  464. PHA% v5 u$ o  a7 _- K! Q. T: `% S7 u1 l
  465. TXA1 s; u: N! z( t  @, D- @. |; D6 O
  466. PHA
    4 I: _0 k6 F3 b! J
  467. TYA
    8 Z* L2 _1 u( O: u
  468. PHA. O/ @8 Q9 U3 j

  469. . m, l  _7 y4 z# W
  470. ;16条扫描线后触发IRQ8 c6 B7 C! k7 A! a1 M
  471. LDA #LOW(BEGIN_LINE_CYCLES)3 ~' {6 {; L9 ~/ h) c2 H& d+ ~
  472. STA M19_IRQ_COUNT_L0 x% F" w! S2 g& i
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    0 Q4 u! x5 O) f, [' J- R9 C
  474. ORA #$805 @7 U! }5 i6 d4 |% x5 S0 Q
  475. STA M19_IRQ_COUNT_H
    ; t( U  p6 Z* m0 Z2 q& Z2 c$ a
  476. # b" \6 q5 s- }
  477. LDA <IRQ_Index
      n3 O; a0 \9 }4 C/ J, o
  478. BNE * + 4
    : P. R/ J% I+ ]$ N2 g
  479. INC <PPU_Scroll_H4 I" F- G# \2 n$ O  d
  480. 5 F0 ?3 O/ F2 r7 t/ |* R
  481. ;设置屏幕滚动2 K8 j4 J; x2 o. K) E" R% I7 E
  482. LDA <IRQ_Index
    4 n# y5 v$ d/ ^' [& t
  483. AND #$01: f; h5 y1 @; f( h# W
  484. BEQ Irq_Scroll_Right6 I! x: Q+ U' W/ I( n6 j

  485. * j( I4 d6 s2 |8 G! w
  486. Irq_Scroll_Left
    8 b& r0 H7 \+ D0 ], C
  487. BIT PPU_STATUS  u) M* T) f! L0 A
  488. LDA <PPU_Scroll_H- }4 f$ z) Q$ q4 ]- G5 P
  489. STA PPU_SCROLL* u/ k8 i# K+ N- h: a4 H
  490. STA PPU_SCROLL
    : o5 t  o- _" K2 P4 v/ x
  491. JMP Irq_Scroll_Over
    % \3 {, Y3 k) f1 j' T
  492. ! Z% {) S# N9 r  F8 m
  493. Irq_Scroll_Right
    ( g& c+ W- o, p* d+ W
  494. SEC
    8 K5 ?$ Z  `) Z6 X( c0 S" k
  495. SBC <PPU_Scroll_H9 O# \7 d& o$ d8 B: {7 T: s
  496. STA PPU_SCROLL
    * A' g2 U9 I" w+ V# f  a: A' C
  497. STA PPU_SCROLL" F" b1 |, p" D' N4 L* Z/ l
  498. Irq_Scroll_Over
    % e% B, U* V' _$ J( Z' G
  499.   o: J9 t  w3 q: o! s
  500. INC <IRQ_Index
    : X3 f( M* b* t: Z! V* m# X0 M
  501. " W1 {  z' j$ t5 y8 [* c
  502. LDA <IRQ_Index5 v9 h+ S* S% V. g; S$ d9 L  G) o
  503. CMP #14/ D% J  J# c3 V  I" c; F+ \
  504. BCC * + 108 x! D4 n; s) r4 t" I
  505. LDA #$00
    ) K! e/ d7 c9 {( r8 ^& B0 Z  a
  506. STA M19_IRQ_COUNT_L
    1 I, C$ j  e8 W* N: o% J8 G. x- a
  507. STA M19_IRQ_COUNT_H/ K: w. C# r" Y7 {! Z
  508. 6 D+ [" B2 M2 q' o: U7 Q! C: g
  509. IrqProgramEnd8 K, w& D+ S9 W9 d( e
  510. PLA
    " S0 s( I/ c% k2 I& o7 I1 }
  511. TAY3 I8 x" r0 V. N' K9 C" ~2 f* A
  512. PLA
    ! j5 g/ ~1 e4 D: v4 i
  513. TAX
    3 y) v9 d: [! g2 i
  514. PLA- s% n' c) \/ k( o  i- e
  515. RTI9 |% w" N+ h! g; X9 l

  516. + r% C- A& P5 l. \8 G  B
  517. ;==================================================
    . _# U/ ?, ?' |% G& R8 V
  518. ;中断表& I! B' V& ?9 B, l# X; A- d
  519. .ORG $FFFA
    , A. t. w/ x& U. t
  520. .WORD NmiProgram/ [1 X! ^( G! u& y( F9 _
  521. .WORD ResetProgram6 p) n$ ?8 x2 J" m- V  _( j. Z+ v
  522. .WORD IrqProgram
复制代码
# Z  }2 A8 ~1 E/ S) F) a

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-5-14 10:46 , Processed in 1.099609 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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