EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]+ K9 m' b' t! ?5 n) Q
  2. ;FlameCyclone 20230710& j* x8 I, Y! v4 X/ V

  3. , w/ P  W  L" @0 p" d( C
  4. ;文件头1 A" k' x2 ~! {; v# n/ d
  5. ;======================================================================
    1 j5 F# h: `- `3 n5 `
  6. .INESPRG 4                                              ;16KB PRG 数量' N# h+ m, M! d' n; `- L
  7. .INESCHR 1                                               ;8KB CHR 数量
      g  t! Q" u( O
  8. .INESMAP 19                                                 ;mapper 19
    0 l* \# p5 E6 O7 ~9 ^' t
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    ' P/ T+ S& w, j4 W; @
  10. ; i% T7 ?2 r1 X
  11. ;必要条件
    5 w( d4 H" V( q6 B8 g* Q
  12. ;1.持有CHR ROM
    7 A) i" l' i; s" `) w
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ; L& E' `4 p3 k
  14. ;3.精灵内存(OAM)不为空; j; T% Z/ y/ q5 x- @' v
  15. ! ]. C7 u- |# x) Q8 l7 [
  16. ;==================================================& y1 K* F' q' M
  17. ;NES端口常量) D5 j  l& L9 X/ c- S7 Q$ X
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    7 T3 d+ K1 g0 S! @& l
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器; C- V: y, w# V
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    4 c: m% h5 y6 ^' ]
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    # M; B: o7 F) f
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加11 z4 f- K, H7 y. T! |5 S
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    / T' a' K6 X. h9 R1 }) d
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加$ x, Y, K# }7 U1 g
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ' D/ g0 g4 {5 c: ?( o
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存/ |+ S! u% r1 R4 V5 w
  27. APU_STATUS              =   $4015   ;声音通道切换8 z9 B7 ^7 ?3 D3 Z
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    5 \, Z% W+ e8 q3 n1 P2 Z
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    : T" `( O7 O- e) a8 R
  30. + v- O3 `8 H' {* H: j! O
  31. ;==================================================3 B" c9 k. j) r
  32. ;MAPPER 19端口常量
    , i5 e* P) \9 k% A' l8 I
  33. M19_CHR_0000    =   $8000
    ( M/ ^, B( t$ W6 w9 `$ V0 w
  34. M19_CHR_0400    =   $8800' k4 e; a7 q6 d2 O7 y- a
  35. M19_CHR_0800    =   $9000
    % i1 ^! Z/ ~  _1 M2 I
  36. M19_CHR_0C00    =   $9800
    / R  g- e+ s# c
  37. M19_CHR_1000    =   $A0001 J& R6 J) F( x  Z3 I! [+ O% L
  38. M19_CHR_1400    =   $A800( W2 o2 S% @$ E) ]
  39. M19_CHR_1800    =   $B0001 w1 K# f" ~. ~0 A! P
  40. M19_CHR_1C00    =   $B800
    ( p' z" B8 ^, s' V
  41. M19_NT_2000     =   $C000
    ' F. w+ E3 F7 }9 e  ]+ B1 I( i2 N
  42. M19_NT_2400     =   $C800
    1 i  K$ g1 |. M; B8 s
  43. M19_NT_2800     =   $D000
    ! g7 J& N9 o5 C* U) V
  44. M19_NT_2C00     =   $D800! u7 n, O  \: k0 b: ~/ l
  45. M19_PRG_8000    =   $E0002 a. `2 Z) j* b. Y% ]
  46. M19_PRG_A000    =   $E800
    $ S8 f& _' c4 E6 v) [' |" C
  47. M19_PRG_C000    =   $F000
    : S% ^) K! Q5 S8 u" s
  48. M19_IRQ_COUNT_L =   $5000# ~# k, U) d% u1 l; \0 |( N6 h
  49. M19_IRQ_COUNT_H =   $5800
    ( m. Z; ~5 I) t9 [4 z$ Q* i
  50. ' ?; }) O+ F* e/ I/ n' v) a
  51. ;==================================================
    ( h$ U0 D. d) T
  52. ;程序块配置
    1 l/ f9 e; p% R1 }2 }' F
  53. BANK_DATA_MASK          = $07% S5 D& |# s0 o: m
  54. ;--------------------------------------------------
    . l4 J2 o5 N4 h/ |
  55. RESET_BANK              = $075 A2 U1 `7 {1 t/ v7 F- s
  56. RESET_ADDR              = $FC00% ^+ C. t7 l  J$ Y5 \. D* |! k
  57. ' f$ u: N' o4 S  ]
  58. ;==================================================9 p' D6 l1 g! @6 ?7 r
  59. ;图像块配置
    + O; M; S/ H7 J! b- a/ p
  60. CHR_DATA_BANK           = $08
    - _, a" c4 W. E
  61. ( v2 s1 v+ ^( F( U
  62. ;==================================================. @: |2 {) x* F8 A8 Q/ S, l! B
  63. ;零页内存地址配置
    , z; Q3 Y  g/ l$ m* o& c
  64. Use_Ram_Addr            = $807 l3 j  k! ~+ N" L: |
  65. PPU_Ctrl_Buf            = Use_Ram_Addr0 z! r$ t  @7 v$ ^# o! w% ~
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    1 d) H3 L5 h1 ^' E' ^/ M
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01- \- a7 F9 X8 H: V
  68. PPU_Scroll_V            = PPU_Scroll_H + $010 P/ x9 E: j& S/ |
  69. FC_Data_L               = PPU_Scroll_V + $015 Q9 D0 t8 s9 n8 x4 ^
  70. FC_Data_H               = FC_Data_L + $01
    : U5 X0 o! {; ^+ F8 `  H
  71. FC_Data_Buf             = FC_Data_H + $01
    1 A. l; M! r) W' v
  72. ;==================================================* J& a  D9 L! ]7 ]! N/ ~

  73. 2 x% y% |. j8 {4 S+ l8 U7 }  D6 k7 T
  74. GAMEPAD_MERGE_FLAG = $04
    ' Y4 r+ R" [) k; ^

  75. 5 K! ~4 S; I4 G) F2 v7 t* C
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    0 D+ T: N) {  _
  77. Gamepad_Once            =       Gamepad_Keep + 2
    8 f8 A" W0 V. ?4 F) R9 w
  78. Gamepad_Temp            =       Gamepad_Once + 2
    9 u, J1 O' }& k9 y% t
  79.                                 
    3 |! o' i- x1 }* w& {2 h2 F# {
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    / e8 z7 k5 X( {8 F, n6 X) a7 p3 d
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    " ]% D" h- U. b
  82. Gamepad_0_Value         =       Gamepad_1_State + 1) Y8 O" |+ V* Q, m& E- W
  83. Gamepad_1_Value         =       Gamepad_0_Value + 10 A) u! r+ M  \% b0 i$ z, A8 ^
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    " v* L; B8 o" b. d5 o% j
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ; S; ?; x" u, U% J2 o" k0 t

  86. $ ?8 p5 T4 Z( k% e1 ^0 S
  87. ;==================================================) s0 c! B$ ~0 z6 L$ W7 ]4 T" P- ^5 @
  88. IRQ_Index               =       Gamepad_Merge + $01' i% R! O1 Q, D( B
  89. ;==================================================9 T1 r" E6 |; H8 f" E

  90. 0 w# c, N4 W9 G4 d
  91. ;CHR图形数据
    ; V/ b* [* V) ^& H( P* T
  92. ;==================================================" K9 {5 o- L0 _  [! c% C
  93. .BANK CHR_DATA_BANK
    ' D: d: o' `( w
  94. .INCBIN "chr_bank/chr_data.chr"
    2 [9 j/ S# w$ ?' Z7 F: @4 b* L# I7 _

  95. - ?% Y6 m4 P; A$ d" W/ g: y
  96. .BANK RESET_BANK & BANK_DATA_MASK
    + j3 s* r4 Y- ?  y. E6 t. f  P  ]/ T
  97. .ORG RESET_ADDR
    , r' p! {6 r1 p& {7 A1 Y
  98. 2 D6 q6 S/ b& @; M2 |
  99. ;--------------------------------------------------
    / f1 }: |6 C7 t! e3 l
  100. Attributes_Data/ P2 N3 `* N' J9 ~
  101. ;命名表属性( q% G( g" H, f$ ~4 X) I2 A
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$008 s1 u" P0 N) k+ d; K- S
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA2 N$ u6 X* s  c5 {/ \6 Z% J
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    4 }3 k4 k; _# f
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$552 C, ^6 y2 T- n" Y/ D2 \! U  t8 {
  106. ;--------------------------------------------------1 ?+ H  ]( E, H4 x" O; G  B
  107. ;调色板数据: I8 N& L+ |/ V& j" \
  108. Palette_Data/ Q2 T# i& d1 G0 A. H/ K/ i
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    # H1 p  m" ]. H5 d5 t1 A7 [/ a
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F' o6 ?. _1 q  m/ j& `/ l7 ~

  111. ! t) l, F% ~" S4 F
  112. ;==================================================
    ( @- w# x* Y4 W  t% ~0 K& n
  113. ;命名表初始化& @4 P  ^! \4 y  b
  114. Init_Name_Table' N0 E+ l- I  f6 b1 G+ l
  115. LDA #$20: ?/ c4 P, G1 v1 w6 c
  116. STA PPU_ADDRESS
    8 l1 F& u, \/ g6 D
  117. LDA #$00
    7 f6 W0 j7 q; h% z. D. `3 [
  118. STA PPU_ADDRESS& H9 D; A- P0 g; S2 r
  119. LDA #$00
    # V# x* {) T& F1 F1 f* I/ B
  120. LDY #$008 D$ M: d/ w# K" ]- k
  121. LDX #$10/ L8 d1 K4 m" g3 p
  122. Init_Name_Table_Write
    ( \7 D; Q5 J1 M. R+ I. X; j. d3 f# t
  123. STA PPU_DATA% Z- F/ @. g" i9 O, R; \; \
  124. INY
    3 n* K& c9 \$ A# ~+ E) @3 A) i2 L
  125. BNE Init_Name_Table_Write
    : }7 F7 o# b1 ^# R' B
  126. DEX
      _6 K, `+ i6 C: j
  127. BNE Init_Name_Table_Write
    3 e7 {7 ]* Y. I; `+ ]" y# y4 j
  128. RTS9 k0 m( v/ x* L0 U0 Y2 j# ^6 \8 {
  129. / Y9 H, \2 A6 ?1 y# L% l
  130. ;==================================================* W2 h" q- X8 ]6 E# \$ P
  131. ;调色板初始化
    % ], v! H- \% @3 ]9 D6 d7 J
  132. Init_Palette
    : M. H/ e- a9 G3 V( N3 }3 u
  133. BIT PPU_STATUS2 l) U4 D, |1 s$ o! t
  134. LDA #$3F/ d  g8 B& R( X' s4 C
  135. STA PPU_ADDRESS
    0 f" B/ Q) o: w- R
  136. LDA #$00) D) [$ {6 T& {% L3 b9 L% {
  137. STA PPU_ADDRESS9 p( G$ w- i/ j* N) ^  |! g% `
  138. LDX #$004 i) W# @# u0 h8 q& q2 s
  139. Init_Palette_Write! s9 @0 e% u8 |: |
  140. LDA Palette_Data,X, L1 O8 H$ L0 }7 r" _
  141. STA PPU_DATA5 N+ r' W5 l% h
  142. INX' `& {5 J+ g" l( M6 a. v. W# o9 h2 N' k
  143. CPX #$205 o9 `+ Y7 u! i) h  ?
  144. BCC Init_Palette_Write
    + i3 g3 q+ t- {$ z$ h. B
  145. RTS
    7 @0 s8 s& k4 l) i
  146. 4 `( a5 T3 n9 N* w
  147. ;==================================================
    8 @; |1 `* ?# w3 q/ d% j8 m0 q
  148. ;设置命名表属性8 y1 i$ d- C5 [( M  A
  149. Init_NameTable_Attributes; E1 D) A6 L7 p! U0 Y9 \
  150. BIT PPU_STATUS5 O* {/ x( I0 r2 K& L
  151. LDA #$237 W/ C+ u/ F) [, K/ T
  152. STA PPU_ADDRESS
    ' k# v  M* _6 N& [
  153. LDA #$C0
    ; n, R& z5 m* F9 M
  154. STA PPU_ADDRESS9 Y- C# ?/ v* ~0 s
  155. LDX #$00
    9 Z+ o3 h1 S7 U; b- |( w, r" q
  156. Init_NameTable_Attributes_Write' f7 d- e' h: q* o
  157. LDA Attributes_Data,X3 B! o0 d! x0 G3 r) r
  158. STA PPU_DATA
    % h" U: u) O  W
  159. INX
    4 D" e+ K6 a+ S
  160. CPX #$40; ^1 B  b5 j% ]3 r  {! }
  161. BCC Init_NameTable_Attributes_Write) [& V# U5 p- X, I, u+ \8 S
  162. RTS! B8 `" R" w3 l% M
  163. 9 {% I) R# w0 C8 m8 Q
  164. ;==================================================
    ( i0 m3 d8 ~2 q
  165. ;初始化命名表文本
    & i3 i; |& G" S0 w/ x- e
  166. Init_Name_Table_Text
    ) v2 J; H) V5 t& Z  h2 \% }. V4 D
  167. BIT PPU_STATUS4 B+ f. u0 Q" ]8 E& `' d2 u
  168. LDA #$20+ e) f! d1 t. W, E# X( j0 j
  169. STA PPU_ADDRESS+ p3 c6 B/ }6 U
  170. LDA #$00
    6 p8 G4 C6 k# _0 T0 @9 J2 A
  171. STA PPU_ADDRESS
    0 X7 t9 j. @: Z* y) L8 B6 {
  172. LDA #$00
    . T$ r0 d7 S' M# w+ D, R6 v
  173. STA FC_Data_Buf
    / Q9 o& m% b" ^+ z
  174. LDY #30
    8 p5 J1 X3 J! W8 r1 c
  175. Init_Name_Table_Text_Write9 L* m4 U4 Z9 K. i  i; Y
  176. LDX #32
    $ @) l& L  O0 {
  177. Init_Name_Table_Text_Write_Char
    2 p) T7 ]$ [" n$ Z. q% i- N. O
  178. LDA #'0'9 H+ }; F8 x6 G. N9 _
  179. CLC
    + y; R. [: G2 j/ n) K+ c% }
  180. ADC FC_Data_Buf% d! f' r7 M  d3 W
  181. STA PPU_DATA
    , j2 R  `3 W( e2 l4 t8 f$ H) P! J' c; p
  182. DEX
    4 U8 ^2 x$ F0 i! p: O9 Q
  183. LDA #$14
    3 _% [, |& ~8 f, c( y
  184. STA PPU_DATA
    . n% P# l/ I7 _
  185. DEX' H/ b' `  U+ l/ Y) U
  186. BNE Init_Name_Table_Text_Write_Char
      K+ `; ~7 {$ \! v% q
  187. INC FC_Data_Buf5 m* E# v* L5 J2 [7 S( q
  188. DEY+ r) g. g! i1 {2 c; _
  189. BNE Init_Name_Table_Text_Write* {* ~* G" b" h% I4 O$ x
  190. RTS% L% F8 f- |- J; M

  191. 4 B, ^0 B7 g6 z3 U" I) f: J
  192. ;==============================
    1 ~& L0 U% X1 B) A, Y. Q* E' G
  193. Init_OAM_Ram;初始化精灵内存
    & u+ y, C& n4 U5 x7 G
  194. LDX #$00( P0 G6 z( x: W/ H9 e  ]' v
  195. LDA #$00
    % M* B4 `1 B8 N( @& Y3 A
  196. STA PPU_OAM_ADDR
      S6 _) `; \6 m% s( c0 q
  197. LDA #$F8% E, J8 M9 `1 R1 e" S
  198. Init_OAM_Ram_Write
    1 m  k6 T$ x! Y  V# f
  199. STA PPU_OAM_DATA/ e3 ^% J; |$ Y+ Q: i8 R' ?/ N
  200. INX+ _' a/ \5 }) m. P
  201. BNE Init_OAM_Ram_Write3 L9 @( H5 z& {
  202. RTS
    * j! T% l! z+ B" U" {

  203. 5 o. @& j8 U. y5 K+ Z& R+ z
  204. GamepadProcess;手柄处理
    ' q% w8 c2 j2 d9 D1 y
  205. JSR GamepadDatacan8 t+ c0 f6 a3 }. s7 X
  206. LDA <Gamepad_0_Value6 C8 @4 k! y+ o" w0 B3 }* w
  207. STA <Gamepad_0_State
    ( c1 U! ^& w  {" A- A
  208. LDA <Gamepad_1_Value
    9 t3 L6 I5 b6 f' ^, P
  209. STA <Gamepad_1_State& Y' i3 w0 U9 |7 X0 O; U
  210. JSR GamepadDatacan6 c& C4 [3 x8 n
  211. LDX #$01
    9 L# e. D  }/ x# k  Z
  212. GamepadMergeCheck;合并手柄输入检查
    ) [/ w. M9 e9 s4 J$ [" X3 ]
  213. LDA <Gamepad_0_Value,X
    * z2 ?0 O: a& H, i5 Q
  214. CMP <Gamepad_0_State,X
    % B# V$ x0 `; F2 |1 w' Y3 O7 l
  215. BEQ GamepadMergeInput* w) [, O0 S7 E7 V# Q' F
  216. LDA <Gamepad_Temp,X
    " T; A0 }* _$ x  q9 `9 G& x
  217. STA <Gamepad_0_Value,X
    3 V1 j& ^, U( Z* g& B( X' @
  218. GamepadMergeInput;合并手柄输入
    ) Y  ^/ v# ~1 ?
  219. DEX
    & Z9 O" s: }7 s
  220. BPL GamepadMergeCheck
    2 t2 G5 l  \5 L2 F( [# X" p
  221. LDA <Gamepad_Merge
    4 a( L. Y0 ]5 v( h2 o2 _
  222. AND #GAMEPAD_MERGE_FLAG- f, e4 S: A' @* a, f
  223. BNE GamepadStateProcess+ [# J1 J% A4 J6 a& v* m) F
  224. LDA <Gamepad_0_Value
    7 e6 e6 d" V1 }6 ]! f5 l
  225. ORA <Gamepad_1_Value
    : C, Y( `/ W; S  l" l' S# _) T
  226. STA <Gamepad_0_Value
    ) z' _+ w- u4 j! D9 J! n8 P2 S# P
  227. GamepadStateProcess;手柄状态处理
    # T  r7 L6 n" r0 _* H4 J- _% ?
  228. LDX #$013 A; A4 M9 E- `9 N' A! V
  229. GamepadStateSave;手柄状态保存4 P5 @4 S- q, @2 E
  230. LDA <Gamepad_0_Value,X$ K/ c7 e, X( ]+ J
  231. TAY
    ) N2 b" q& B! t' D. ~, `0 x3 D
  232. EOR <Gamepad_Temp,X
    % @; D/ }$ M: @. j( _; ]$ ~
  233. AND <Gamepad_0_Value,X
    4 c: Y) I' m- r' Y$ x5 T
  234. STA <Gamepad_Once,X9 A0 G( S1 C7 i( S! J+ A
  235. STY <Gamepad_Keep,X
    3 @- H0 n. U4 `4 M4 O9 N  I
  236. STY <Gamepad_Temp,X% i* y, U0 n* i, g0 C+ K
  237. DEX
    8 x! z6 M! ]9 F
  238. BPL GamepadStateSave
    9 I+ Y: E0 t7 q! M
  239. RTS
    " F! ?2 F& T6 l( ^/ i* N
  240. & E2 ^8 E7 h  ~+ g
  241. GamepadDatacan;手柄数据扫描: b+ w7 }" m5 F; c
  242. LDX #$01% N# C, t1 N9 i' ?6 V1 K
  243. STX $4016
    2 q* W) e  X/ B5 d  n/ S/ i( `9 n8 Q; I
  244. DEX5 m) _+ O9 l5 W1 W3 d" m
  245. STX $4016: n6 h5 E0 x9 K7 P
  246. LDY #$08
    , j; r  {$ ]* S# n1 V; h( ^6 a8 J
  247. GamepadPortScan;手柄端口扫描
    ! @8 T5 k$ d0 t0 y. T: I; O
  248. LDA $4016! N! F- |- F% b8 z
  249. STA <Gamepad_Port_Value$ Y0 {! x2 C! D* X: l% `; t
  250. LSR A, D' T  O; }  d- q& q$ o
  251. ORA <Gamepad_Port_Value
    - y% ^- m: X/ z* G" c3 C
  252. LSR A. N9 [) p$ a/ `* B$ c/ P1 Q
  253. ROL <Gamepad_0_Value
    0 [0 `1 S" R, Y
  254. LDA $4017
    9 [8 M# g" c0 e7 v+ m
  255. STA <Gamepad_Port_Value/ U3 n7 [" E; q
  256. LSR A
    + `8 ]8 Z6 U( r8 n7 d' k9 ~& A
  257. ORA <Gamepad_Port_Value4 w& T0 B; e. K- ^0 ?
  258. LSR A
    " }- l9 |1 y5 Y2 b6 _; _% V
  259. ROL <Gamepad_1_Value! U* g- G! |( |* o" O" w
  260. DEY% H% U! r2 e1 H+ e, Y
  261. BNE GamepadPortScan$ g. ?4 e, @( j( x# G) i' |3 L$ _% k
  262. RTS# S9 d' N& F4 o; D5 F, e+ E+ N0 E
  263. 2 N% V% B8 H* M* s6 T% Q+ J
  264. ;==================================================' T! R0 E) d5 j6 N1 v+ \# J" K
  265. ;PPU处理
    : u# J/ w, K% V; V) q) X0 b
  266. PPU_Process
    " r) l. N. K1 N  D$ w
  267. LDA #$00
    ' ]; U. I2 L, o+ Q2 N) m9 Y
  268. STA PPU_MASK5 R4 h, R5 A. k( m9 C( W" i
  269. 4 `& L' @1 V4 e8 r/ `
  270. BIT PPU_STATUS
    ; B; x. C4 D) c: s8 S" A
  271. LDA #$200 q9 b3 ?6 A) \: k7 K
  272. STA PPU_ADDRESS  y; S. T' g8 g& V3 X
  273. LDA #$008 E. i0 \  |; T; F; l9 ^" L$ ?( ]
  274. STA PPU_ADDRESS: T' n: j; c: |3 q* P0 F4 d" \

  275. 1 b5 Z* g# h; d
  276. STA PPU_SCROLL
    - {/ H: P5 z: {
  277. STA PPU_SCROLL& J( C/ L3 Z9 h( Z

  278. ' h7 B0 O+ f3 @  @
  279. LDA PPU_Msak_Buf( d7 e4 @9 u2 }
  280. STA PPU_MASK
    6 Y# p6 Z: R$ B8 h) F; O
  281. & j' n+ y- y# @3 A- T. ]
  282. RTS6 q8 t6 Z2 M4 p& h! }4 w
  283. . z; `* C' Z) I- R/ r3 l
  284. ;==============================
    1 Y/ Y7 A, A$ }& N4 v7 P" H. p2 m% U
  285. Time_For_Vblank;延时等待
    7 R' G! H$ g. _$ J- S! v' S7 R5 O# ], }
  286. LDA PPU_STATUS
    , B* ~, C5 Q. B1 p( i2 }7 M
  287. BPL Time_For_Vblank& P; u* r/ E1 L% P
  288. RTS  }2 r2 u0 ~8 B. F8 x
  289. 7 \9 u- D! j  i
  290. ;==============================& m, Z8 Q5 J- ?" H- J/ I. w
  291. ;初始化MAPPER19
    & r+ o7 ]4 v! U! M: _8 x
  292. Init_Mapper19
    4 ]3 u0 N: x# T
  293. LDA #$00
    + l) |' U0 Z, s. y+ s
  294. STA M19_CHR_0000
    8 r4 b, @/ }  X9 _9 i- ]1 s. m
  295. LDA #$01+ `4 r) {' m& M" P) y; B
  296. STA M19_CHR_0400
    8 G! j2 w6 [2 {* ~# [
  297. LDA #$02
    9 o" T2 i: N& ?+ C# m) V- U
  298. STA M19_CHR_0800
    * n9 \+ X$ _2 y- l  }
  299. LDA #$03
    % N, Q! R- H- @( B
  300. STA M19_CHR_0C004 F8 O7 {, z# Z8 c% t. t
  301. LDA #$047 C. D6 v( _+ v" W/ ~1 z6 n  }8 b
  302. STA M19_CHR_1000
    5 E% G  M* \" K* ^
  303. LDA #$05+ T/ _  g) j1 E+ p
  304. STA M19_CHR_1400
    1 N% Y5 a6 }! t8 V* R
  305. LDA #$06% l0 F2 E+ |& U, k* V2 `0 D
  306. STA M19_CHR_1800
    * @! F; |  k! D$ L
  307. LDA #$07
      U5 x+ a1 R: b" ^
  308. STA M19_CHR_1C00  I$ L' c3 ]# B& T. e; v3 ]. K
  309. 3 r0 c  p' G4 V/ u: T
  310. ;禁用IRQ
    1 R& f+ L: r3 u4 P7 x' b9 J
  311. LDA M19_IRQ_COUNT_H
    " }. b  j3 \. m; I: {+ S
  312. AND #$7F
    ' ]3 Y4 |7 R6 x  S
  313. STA M19_IRQ_COUNT_H
    ; ~( L$ v5 Z# y
  314. ( b- a: Y3 T$ B  m8 O7 D" `: K
  315. ;命名表
    . W! a: z* x! R) G& L' q
  316. LDA #$E0, J8 v% t! S9 ~8 w
  317. STA M19_NT_2000; M: R! v# |4 y" [& F; |" Y
  318. STA M19_NT_2400
    & \/ J! O* e* P. u/ a$ V

  319. ' }) P- Q6 |" Z; f
  320. ;命名表
    * q. j0 j  O! s* j9 v+ S
  321. LDA #$E1* O# r$ j& J; _! c$ l! t3 `
  322. STA M19_NT_2800
    + P6 w+ J8 G8 n* F3 @: \
  323. STA M19_NT_2C00
    7 P3 a1 q! N, u4 W1 ~

  324. 3 Z+ B$ a& O* q8 S0 c' |* C
  325. RTS* Z1 @7 a: I0 N% l& H% R
  326. 1 }* K9 {; h8 U* s  z
  327. ;==================================================( C( c; P' s9 R$ M6 ]
  328. ;重置中断处理
    6 Q: r5 h2 u' F/ ]4 T
  329. ResetProgram
    ( z$ H9 v! Z7 L7 \' K& ~( |& S
  330. SEI
    6 Y2 s" G. U# i4 s' @7 X
  331. CLD+ Y5 B; N6 }% H5 e5 A  ^% P4 D
  332. LDA #$002 i+ t/ Z1 P# m3 C6 {
  333. STA PPU_CTRL  o# Q% E" i" M: N% A  Y
  334. STA PPU_MASK
    6 o4 i+ q+ z. f
  335. STA PPU_STATUS
    2 c! e& s9 B& l- @  O9 t; Q9 B
  336. STA JOY2_FRAME( x( t8 a, g+ s/ M. y* b
  337. STA APU_STATUS8 `* }9 B  _1 Z+ K* d0 D7 }, a. E
  338. . O. u+ v2 A  D3 z" {# H, n& T4 r
  339. LDA #$C0) Q$ z: V* E$ h5 r9 B% m! K, z
  340. STA JOY2_FRAME6 O6 E6 v6 C  R! _

  341. 8 o* ]* C8 a  O' C1 q- T; F: d/ z5 D6 t
  342. ;等待vblank! t4 t6 U" \( T$ _: a
  343. LDX #$027 J% @% l7 }, z: P1 j8 O; Q; E! {/ z
  344. Vblank_Wait_1
    ! _8 ?+ K8 }0 f" ?
  345. BIT PPU_STATUS
    + ?/ x3 Q" Z, }% M- M
  346. BPL Vblank_Wait_11 x# R6 U2 ~! ]% y7 o  ^# n: N
  347. Vblank_Wait_2+ `3 N2 d2 F0 }4 l: o7 ~3 S* ?9 O
  348. BIT PPU_STATUS
    2 O% |2 Y' b. W+ S, P4 Y& ]* \' _
  349. BMI Vblank_Wait_2' p: ]3 ^- W) v1 l/ @* w
  350. DEX+ }4 g/ h) P9 F9 ^: ?0 c* R
  351. BNE Vblank_Wait_1
    3 c- L9 w0 C$ I( K! J( l
  352. 7 c% Q' N$ t( V4 R1 j9 G! B
  353. LDX #$FF2 U9 ~; ^2 k2 O7 P& ?3 Z
  354. TXS
    7 Y, W7 N* d5 P( ^

  355. * M1 @. x: p* H6 `: k# B
  356. ;初始化MAPPER19" ^. o. C9 @$ e# c( Q7 v
  357. JSR Init_Mapper19
    + j: k$ O" l$ j0 C0 _4 f3 n

  358. 6 M/ J8 C0 J" ^( d. n% }; A. w
  359. ;==============================
    6 M" S8 M3 K  c% c1 j8 X* _
  360. ;RAM初始化
    0 @! {6 y# k! H" o8 A
  361. Nes_Ram_Init9 O, H8 E- n" [; {: G
  362. LDY #$00: v$ J1 o+ T2 Q7 \0 h9 N2 H5 o9 y, }
  363. LDX #$08
    . G) y4 @4 q9 y  c' Y2 D/ z/ _
  364. LDA #$00- n% {0 o% @* @9 \, n5 e; r
  365. STA <$00
    % U5 B$ W: }8 L+ c+ p
  366. STA <$01
    % l. b+ N1 n8 ?/ k! A6 K1 v
  367. Nes_Ram_Init_Write# U# f& q( }" ^$ J
  368. STA [$00],Y9 V0 W$ F( r& }4 i
  369. INY
    3 H/ @7 a7 w7 W- F5 K2 {8 q
  370. BNE Nes_Ram_Init_Write
    . Q0 ?, o. E) U! k/ i& h2 z
  371. INC <$01+ D5 _  V8 ^5 R, o6 `2 q( }$ M0 V
  372. DEX& M# V* \) R! T. q, y6 O& k
  373. BNE Nes_Ram_Init_Write
    $ v& W& }9 H; z1 I. u
  374. . ~& x: L9 D9 V, b
  375. ;初始化命名表4 {' c" p4 v) w  w
  376. JSR Init_Name_Table1 U; A8 C! w: I3 [6 [
  377. . h( K1 [# {3 z! t9 ?
  378. ;初始化调色板
    ( n' q  H/ E4 A3 m! o1 X
  379. JSR Init_Palette0 y9 M- y& ]! E. E/ l
  380. : e, q% r! J9 d! u7 z# q3 m, H
  381. ;初始化命名表属性
    5 m4 b' N: U4 F0 {( m
  382. JSR Init_NameTable_Attributes# B$ H1 `( f' `9 a: L
  383. ( J9 G2 f& @3 r
  384. ;初始化精灵内存
    3 H2 R5 j! R; T* R- Y% ~" ^( W
  385. JSR Init_OAM_Ram1 }- |/ u: A, Z/ @& R5 _. U
  386. & t* P4 }+ Z5 f' i/ b' Q
  387. ;在屏幕上写点东西
    # H) D8 U, N2 x
  388. JSR Init_Name_Table_Text' m% j; f, ~: [4 f' `: B0 D+ t7 k5 _
  389. ) I/ Y/ M- g( Q* y" T2 X
  390. JSR Time_For_Vblank
    7 M6 j( n6 d4 ~
  391. ;开启PPU控制
    7 ^5 x* p, v3 f: S8 Z
  392. LDA #$A82 F4 X* W( ]$ b" j; q9 L
  393. STA PPU_Ctrl_Buf
    8 `/ w- [6 w3 r' L3 R- R+ v
  394. STA PPU_CTRL  T# o& u: E& U, S1 y' ^
  395. ( T0 f: m4 Q5 j- m; J( V
  396. ;开启PPU显示$ V! i' |) p/ D, X/ j
  397. LDA #$1E; T% ~, `2 h0 B& k" r; S
  398. STA PPU_Msak_Buf, g/ g1 r" U/ D. b7 E
  399. 8 M5 ^; q+ t) k/ j; B
  400. CLI9 Y% j: |% [/ L' J2 b+ B4 p
  401. JMP Loop6 n* \+ b% z9 t* Y
  402. 9 c' p( E- r7 w9 `- C
  403. ;==============================
    ) B7 l& n' E7 t* L3 D( m1 J8 W
  404. ;死循环, 等待NMI中断
    3 L# k( C6 u3 ^" _
  405. Loop9 S9 j, i. t1 b* }' i
  406. JMP Loop. E: t, c& S2 N8 {9 o! o/ S
  407. ' S) F- e* s; R! a
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    5 @& n  ]& c8 ?# _  A
  409. + j+ z' E) N! y$ q1 f" K8 V
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)( t' o- l0 C5 \% m8 f
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)8 O% X- y: r" E8 u% R, l' H
  412. ;==================================================* S& g6 E. d" a4 x, E' b1 p* V
  413. ;NMI中断处理* b: o& v( Q/ _: \! Q  Z1 r1 n# \5 X
  414. NmiProgram  |+ Z0 c6 L/ q
  415. PHA! `1 x& _: X8 f7 \8 o; S* L
  416. TXA
    " C# w9 c) r( J
  417. PHA1 _, Q5 V7 s  O/ s2 {0 o7 Q, q7 x
  418. TYA
    7 {7 |4 l) D6 w
  419. PHA- [. H$ `! Z0 n8 G0 j2 q) q
  420. 7 j+ j7 s4 |% X) ^5 `, ?
  421. BIT PPU_STATUS
    ; |8 u, X- v4 I6 N# S' J
  422. 5 E$ q8 a6 n3 o% S* L
  423. LDA #$00
    ; F/ A9 m" T9 o; R6 d1 H
  424. STA IRQ_Index
    * o( v8 M2 F; h/ X: U  Z

  425. 5 ~8 e9 I# q% a* q' ^! n
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    3 \" A1 x  J8 h, @6 e- i5 q
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    7 C7 V" n' D: @6 {5 ?5 j
  428. STA M19_IRQ_COUNT_L
    * w2 Y" L* f# w4 f1 `! Z8 W1 Q
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    % m% t" I3 d& v" P- d
  430. ORA #$80
    " Y( K% R( B. Z, ~* E. `! M2 F
  431. STA M19_IRQ_COUNT_H
    , X8 @2 B& j' n
  432. CLI
    0 K9 J' a& L; v; p& K1 J
  433. $ k+ J$ \* F/ m* m
  434. ;关闭PPU控制
    6 [& Q% @, g7 Z: A2 l+ G
  435. LDA #$00# r' t, O3 j* x* D* j
  436. STA PPU_CTRL
    0 W  @7 h- s& O

  437. 7 \$ D% {4 b( t( F
  438. ;处理PPU: W; i4 b! {! s4 D  w
  439. JSR PPU_Process
    $ @3 H2 |& W% }& G
  440. . E5 M1 A9 r; A$ \2 b  M4 |
  441. ;开启PPU控制" @/ n/ X' d$ F, H& |: U2 G6 L
  442. LDA PPU_Ctrl_Buf/ m; ?7 a, s5 M/ M" e, K  I4 |
  443. STA PPU_CTRL7 c+ o2 U. e) M( J4 U

  444. : u. h; @4 h0 `5 y2 _
  445. ;手柄处理
    " F, O+ P4 e8 J: B& g8 b
  446. JSR GamepadProcess% L( H9 d: D! P( C- e

  447. ' x+ U) S: D' A2 z! \
  448. LDA #$00
    0 W$ K' F  S3 Q7 d
  449. STA IRQ_Index1 K3 E7 o( {+ Y

  450. ; E& i2 _  V$ i  J
  451. PLA7 h% G4 F0 Y% l# }! W* c- U2 h
  452. TAY
    1 I5 W/ U" {3 ~& z1 l
  453. PLA
    ( S/ I$ C+ ?, x: B* d' w" o
  454. TAX
    4 i9 y3 N* X: m. g1 t7 ?- ~# I3 t
  455. PLA. m# D+ |6 B- k5 X: m
  456. RTI
    * x2 S! C# ^& ~4 @3 c

  457. 2 Y- y4 J6 u: r3 x1 o+ h
  458. ;每行扫描线113.679 q9 q  W/ ]. Z" S
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)3 M6 f7 O, O$ J
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    ; f) {. Y) h& o% V& L
  461. ;==================================================: k, U0 {- `5 r% ~0 a, y
  462. ;IRQ中断处理6 B8 C# o2 \9 ^% p
  463. IrqProgram) s7 t' V, d* M" Z6 [; S
  464. PHA
    ! j7 x, b# {# ~
  465. TXA, \% v6 q7 O. G/ u* Q' r
  466. PHA- J6 x6 ]8 Y* A
  467. TYA
    5 H) k+ l+ J* a0 R* |' q6 Q  z
  468. PHA
    5 A  |- `6 s3 I: N% H" s
  469. * ]8 p- g8 v$ ]7 K- G  ~
  470. ;16条扫描线后触发IRQ
    3 n: I( B: d- o. k
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    - s& @4 D$ X0 t- q0 \9 T! X
  472. STA M19_IRQ_COUNT_L' R( d! I' `' s
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    - {, E% ^5 i/ r( m
  474. ORA #$80
    ( l/ H0 l  C& x, Q/ s
  475. STA M19_IRQ_COUNT_H
    , m4 f4 {8 z8 q' I5 _- E
  476. " m: ~" Q" N6 R1 m5 X& P. F0 b
  477. LDA <IRQ_Index
    ) k" `, K* N. e9 L$ P' |$ s
  478. BNE * + 4) G4 }: G( t9 `
  479. INC <PPU_Scroll_H! M' b6 c# s! T! Y# A. F

  480. 3 O( M7 q, |$ f! L2 \
  481. ;设置屏幕滚动
    & M7 z% ?7 c; N" z
  482. LDA <IRQ_Index
    , }- e, ]3 w9 K& f
  483. AND #$016 n8 s! a" Y! L  x3 g
  484. BEQ Irq_Scroll_Right* Q- i  D& @* X- Y- N2 D% z# L
  485. ; ?4 ?& I; {+ L$ h7 `/ t. R) z
  486. Irq_Scroll_Left3 H' g9 C4 h9 K0 W, m5 R# p2 u" j
  487. BIT PPU_STATUS$ }/ l6 }2 f5 c9 m, W& R' W* y% V" X
  488. LDA <PPU_Scroll_H! U. v: v8 d* {* S, `- D1 ^" R
  489. STA PPU_SCROLL0 M5 C) E, Z" W  Y0 H
  490. STA PPU_SCROLL
    1 ^3 @' p# x0 N# u  I" v3 L
  491. JMP Irq_Scroll_Over
    % v9 V+ q8 {6 W9 Z/ B3 g7 K
  492. 0 x6 L( Z0 u! ^2 l
  493. Irq_Scroll_Right" \; t# i7 Q8 ^0 c
  494. SEC
    1 q/ E" y0 H8 Z  I3 m
  495. SBC <PPU_Scroll_H
    : N# ]* L# D4 H& I
  496. STA PPU_SCROLL
    . s- S! z+ |; [, E, W0 ]9 T3 t( ~
  497. STA PPU_SCROLL3 G6 I& i7 r& u8 s* p6 h
  498. Irq_Scroll_Over" l$ p/ l+ C& P

  499. ) ~$ A9 Q" E8 s5 \& C7 c# C
  500. INC <IRQ_Index4 x3 C6 _5 x( T6 x' ^
  501. / Z2 K. h; a/ H: W
  502. LDA <IRQ_Index
    8 Q8 f$ H- l" [7 C. m
  503. CMP #14+ F  Y# @3 c/ G& z
  504. BCC * + 10
    4 T) P# p; b2 \, ^9 _/ t/ \
  505. LDA #$00
    ! z: p7 S" c- B8 |& E( j. ?- a; b
  506. STA M19_IRQ_COUNT_L
    8 l! R. e% o: a' _! _: {
  507. STA M19_IRQ_COUNT_H
    . t7 i. V" o/ V9 R4 H) A) I
  508. * }9 I9 I' ^- x! x) Z3 f
  509. IrqProgramEnd7 i& Q$ V: U: p6 O! O0 N6 C
  510. PLA) `! c% ^. {, u
  511. TAY
    * \9 J5 W- N5 N: D
  512. PLA
    * |7 j% t% U/ R/ J
  513. TAX2 g* e4 z- ]+ v4 ^) `
  514. PLA
    2 y9 H( {& s. y$ V
  515. RTI' k& F4 j- g; v" m0 w

  516. . j5 o8 d& b3 e7 m) P
  517. ;==================================================
    ' G- Z, X. S- R$ v/ E$ w
  518. ;中断表' P2 _; V, c! t% P8 k2 a
  519. .ORG $FFFA
    5 k8 _8 f! o# G- c
  520. .WORD NmiProgram/ k3 b$ a3 R4 o$ T
  521. .WORD ResetProgram, ?3 q" j9 R9 F+ U; S: P$ T; M
  522. .WORD IrqProgram
复制代码
9 D: A* L+ R! I7 J# n, T

本帖子中包含更多资源

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

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

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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