EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    2 E; F5 U$ E$ f$ j- r
  2. ;FlameCyclone 20230710
    % e3 o% R8 H: U6 V  m- R& M

  3. , T% F3 V: v+ p: \" G3 t
  4. ;文件头1 o  ]2 |( N0 G( O3 E# X
  5. ;======================================================================
    8 D. F, a4 ]% q1 T6 Y! q
  6. .INESPRG 4                                              ;16KB PRG 数量
    # C7 d2 v; H. i
  7. .INESCHR 1                                               ;8KB CHR 数量. D1 v2 L0 J- t* j; L
  8. .INESMAP 19                                                 ;mapper 191 R2 {4 h& G% M3 T. }
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
      m3 C6 W+ T" ^$ `6 {

  10. 9 q* Z. _; Z+ M: C: }& ]- k% c
  11. ;必要条件
    4 n' H7 y! b+ X3 \
  12. ;1.持有CHR ROM; D: E3 }) a( X  M
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    0 p$ ^: e1 A5 X' x
  14. ;3.精灵内存(OAM)不为空% n, T" H* p; A
  15.   j" G& F- o% w& |. P9 n
  16. ;==================================================
    3 o) j/ I1 Q+ \! i
  17. ;NES端口常量
    3 ^8 y. g+ a/ P8 u. ]
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器5 v$ K! E! ?7 P: I
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器2 `* a) @' M7 J& g4 B' d$ z' b( }
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    6 P: ]; g& v5 o2 @+ }: |% a
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    & j. X$ k2 D3 c( Z
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    ; t, I0 N! o6 J& x, d% \; k2 X5 O# p
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    / C( L; j' }3 {! e
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    . F# o2 N' g' S1 @6 ?
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 - e9 y3 w4 ?( g6 U
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    7 m. ~; Q4 y6 U+ m6 Y3 b
  27. APU_STATUS              =   $4015   ;声音通道切换, t9 H1 b- s' {
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通" l! o4 N( e" y5 R
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    9 ?+ C* M/ f8 T
  30. & \& w7 s4 m/ A& B
  31. ;==================================================
    & ~6 b4 o; T" @% ^7 B
  32. ;MAPPER 19端口常量* e, x* K/ T. l& T5 P' h
  33. M19_CHR_0000    =   $8000/ N, H9 I$ {4 M. c* J! F# R0 A
  34. M19_CHR_0400    =   $8800
    : ^5 @4 Y. p. w5 K5 J. z
  35. M19_CHR_0800    =   $9000
    + F: Q% ^  R8 F
  36. M19_CHR_0C00    =   $9800/ k" q0 H9 \' s0 d6 L1 v" d: {: h
  37. M19_CHR_1000    =   $A000
    % ~3 K' j" a7 k4 Y
  38. M19_CHR_1400    =   $A800' ~8 ^/ f; X9 W6 a- l
  39. M19_CHR_1800    =   $B000& [! {" g+ D5 i; S
  40. M19_CHR_1C00    =   $B800
    ' z( j' l2 o) e3 O( m' ]( V0 N7 Z' L" j
  41. M19_NT_2000     =   $C000
    + ~0 j3 q) w6 O$ X. v& A$ w9 b% z
  42. M19_NT_2400     =   $C800& m, S/ V( C2 b
  43. M19_NT_2800     =   $D000
    4 A" o% _" a8 Q
  44. M19_NT_2C00     =   $D800
    : O  r4 i4 {  m  N
  45. M19_PRG_8000    =   $E000
      U/ }2 o$ ]9 x8 g$ b. `
  46. M19_PRG_A000    =   $E800
    4 q+ ~9 x0 y. b8 @- L
  47. M19_PRG_C000    =   $F000$ c7 _7 Q$ `5 J  ~+ S8 {
  48. M19_IRQ_COUNT_L =   $50001 j2 t% m$ J$ W# F
  49. M19_IRQ_COUNT_H =   $5800
    . y" t/ f! e7 V6 G2 S. n
  50. 9 j5 s  ?6 \' x* l; S  p
  51. ;==================================================
    : e& Z" P9 Q# K$ x
  52. ;程序块配置$ m# T2 B; x4 V6 u" ~7 Q/ l; V# L
  53. BANK_DATA_MASK          = $07
    0 B. a- g  M7 X) h
  54. ;--------------------------------------------------+ Y' w8 _- X+ P, X
  55. RESET_BANK              = $07
    + s( y! G) [+ e- L* ^9 a
  56. RESET_ADDR              = $FC00/ s4 S. y6 }' V$ B5 o
  57. 7 S& C' q. b# U+ F6 T1 ~) X0 p
  58. ;==================================================) v* y# @# O; {7 u$ T
  59. ;图像块配置
    $ Y* y" I5 F+ `2 K
  60. CHR_DATA_BANK           = $08
    8 K8 f) G  K1 V5 S+ {

  61. $ O: z; y6 I( k$ \5 ~" H. P
  62. ;==================================================
    ' C% V" P2 H: Y3 M# ?
  63. ;零页内存地址配置; W* H9 d( `; U: d$ n& n
  64. Use_Ram_Addr            = $80
    ' }; Z2 ^1 ]! l
  65. PPU_Ctrl_Buf            = Use_Ram_Addr% C. ^9 t% ^: r$ t
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01- S" f1 ]9 m" v
  67. PPU_Scroll_H            = PPU_Msak_Buf + $011 r2 c! p: r2 s( k, T4 P( @5 z1 k+ Z
  68. PPU_Scroll_V            = PPU_Scroll_H + $016 ?) d" [# E4 s- _, `3 ?
  69. FC_Data_L               = PPU_Scroll_V + $01* j1 ?! }: h6 b1 P. r0 Q
  70. FC_Data_H               = FC_Data_L + $01. \6 q+ v: ?1 W
  71. FC_Data_Buf             = FC_Data_H + $017 V. e# U2 F# k3 O- M: n
  72. ;==================================================
    3 w" h) I5 I+ G3 F5 `( z% t

  73. 6 B$ S, X$ u9 \" L
  74. GAMEPAD_MERGE_FLAG = $040 x2 T) X, h8 |2 A7 O

  75. % C6 F+ Y4 u5 {# H
  76. Gamepad_Keep            =       FC_Data_Buf + 1" ?% U" s2 C! J
  77. Gamepad_Once            =       Gamepad_Keep + 2
    : ~! x3 i- U( v# V/ `1 M
  78. Gamepad_Temp            =       Gamepad_Once + 2/ y/ p6 N  D) W4 }0 J, x0 Q
  79.                                 8 I$ R2 E( h9 X* @9 E$ d3 q2 ]
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    4 r. u$ G' C. O& G7 R
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    . @* o- P( W: u1 o0 q6 a# M
  82. Gamepad_0_Value         =       Gamepad_1_State + 1! m& t9 t1 U# ^4 {. E8 r
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    8 s( Z! ^- |, M/ Q' |$ L6 Y2 v$ h
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
      ^+ w- m4 t- }
  85. Gamepad_Merge           =       Gamepad_Port_Value + 19 _0 k' _+ ^* F- E& Z. D
  86. 1 `2 y+ {& Y- t, R, L
  87. ;==================================================
    0 ]' a) d& p* F
  88. IRQ_Index               =       Gamepad_Merge + $01
    : m4 g7 L4 Q) C
  89. ;==================================================7 @9 N% i6 w0 x/ J+ M$ ?* f4 `

  90. & Y% R& }2 P$ J# G
  91. ;CHR图形数据
    # K0 K% @4 h$ `8 J3 y# x
  92. ;==================================================
    1 M* X+ P8 a* S' b3 E' v/ E- M
  93. .BANK CHR_DATA_BANK* M, x4 I5 V8 l" s5 ?' A
  94. .INCBIN "chr_bank/chr_data.chr", G4 R# L8 }& U3 j$ Z( D1 U

  95. : O5 Y; s3 p- c2 A1 l) T
  96. .BANK RESET_BANK & BANK_DATA_MASK
    0 k) K7 F+ J1 S% \7 N9 M
  97. .ORG RESET_ADDR) m' K. M7 l7 y1 U/ Z. u

  98. % O# z* A: P5 J' `$ l( ^' Q
  99. ;--------------------------------------------------
    8 N- k' j' B; E6 w/ r5 C3 c/ O
  100. Attributes_Data
    0 \# Z# B- S8 e6 D
  101. ;命名表属性5 f8 B% P% N+ p+ R; A
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$007 }" V: f" w$ y' [& X
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    7 d: z. g8 H3 F- t+ C$ O$ u$ |
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA0 ]" K# Y0 e. B8 c' e
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
      a- b) u' A9 u2 F
  106. ;--------------------------------------------------
    1 ?2 s3 N. A6 ?, A" c& ~
  107. ;调色板数据' a6 \* J8 L, P7 r/ s$ ]8 _
  108. Palette_Data
    ; D5 l9 q6 Z& v6 q! a
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F0 \- _) I; D. {/ M% ]! J
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    & |: {: w8 v8 Q6 T
  111. ( e( p8 g" g3 X% {
  112. ;==================================================
    3 @: C# _) ^- n! K# w* Z
  113. ;命名表初始化
    6 A2 Z- s/ {1 {
  114. Init_Name_Table
    ) R8 a* i7 d1 q" @6 o
  115. LDA #$20' D/ I+ G2 n7 I7 _, |
  116. STA PPU_ADDRESS
    # M6 j6 G+ D1 D, ^: e+ Y) x
  117. LDA #$00# ^0 V4 N: l  \  ]" F) ]1 Z5 O
  118. STA PPU_ADDRESS
    2 c8 i& b" z8 J7 S. w
  119. LDA #$00
    + H$ y5 W/ C! d! J7 s3 V1 D
  120. LDY #$00/ n* {3 F" x% a1 u. k/ u& O
  121. LDX #$10
    2 z$ r4 `) q( E7 ~. w
  122. Init_Name_Table_Write
    , s' l9 P0 C/ ^$ ^" L% a
  123. STA PPU_DATA
    0 Y: [, r2 B- o' Z  \7 z* [3 {
  124. INY
      C. T' L6 K, `+ {! Q6 W
  125. BNE Init_Name_Table_Write
    8 a/ t+ {( }% E
  126. DEX+ P$ t+ G5 z6 A+ p& ]
  127. BNE Init_Name_Table_Write
    $ V3 U( S1 `0 C, i5 J/ T
  128. RTS% X$ K( o* Z* F, b7 v$ H- _
  129. ' U* C4 N, [* e9 r9 F" b
  130. ;==================================================2 l( x  K' K# `9 M' A: _7 G' W
  131. ;调色板初始化* Z9 I5 Z/ y/ g& G% {
  132. Init_Palette/ {5 x& h: ?- l6 j% E
  133. BIT PPU_STATUS$ K- n. m9 M4 c* r$ [( J3 z
  134. LDA #$3F
    ' h. D, q0 i" w- F0 f
  135. STA PPU_ADDRESS) T) x9 P5 N1 J# N
  136. LDA #$00
      [) G! C6 f5 o- j+ Q) {
  137. STA PPU_ADDRESS
    , @7 h  s* D! E% \2 v
  138. LDX #$00& P: I4 y3 C; X2 r0 T7 s4 n
  139. Init_Palette_Write
    1 K3 Y  l2 H0 t8 \; U
  140. LDA Palette_Data,X
    ; E. O% W3 T' G3 c
  141. STA PPU_DATA
    4 T/ [  o9 ~  g1 o! T: d
  142. INX
    ; `' K  |! a; P! v) E$ x
  143. CPX #$20  C! p8 {' O, F- c+ M' P
  144. BCC Init_Palette_Write$ j7 l! |+ N) Q: w
  145. RTS: O) u& i/ D) W% f9 L- B# t
  146. 8 b0 Z; \  g+ z6 C5 [. ~/ @" ~
  147. ;==================================================
    * U2 s: ~( q& G4 g
  148. ;设置命名表属性% N# f! j4 U3 `( r9 r
  149. Init_NameTable_Attributes* g9 B1 U( c3 x0 w
  150. BIT PPU_STATUS
    & k5 L5 B. M2 m8 _6 i
  151. LDA #$23% Q4 x4 K6 P9 E8 C. e+ f- M
  152. STA PPU_ADDRESS
    0 c9 `; J5 |7 K$ C
  153. LDA #$C0
    9 U8 G9 [- B* v! B
  154. STA PPU_ADDRESS4 O, Y% m( G5 [, x1 r
  155. LDX #$007 I  K$ `! o5 U, I' g3 B
  156. Init_NameTable_Attributes_Write/ |! t6 K: W5 r/ y
  157. LDA Attributes_Data,X4 f! u/ h3 E2 D+ c
  158. STA PPU_DATA
    ' o0 N- x1 O% R* f6 K
  159. INX
    , g5 H6 s/ |- \# b5 X1 r' A
  160. CPX #$40
      y$ f# A  h5 l  _
  161. BCC Init_NameTable_Attributes_Write9 J9 j7 O( ]# x
  162. RTS
    8 [; f! O0 u, a( f

  163. . j& {& e/ S; Q! d. @" L
  164. ;==================================================$ @9 l# l2 w! g
  165. ;初始化命名表文本
    ; a2 V; k  o1 ?& x& b% |
  166. Init_Name_Table_Text
    - [" N/ z/ Y% g* J
  167. BIT PPU_STATUS2 p0 s! D7 H1 s) h+ q
  168. LDA #$20* q9 U  g0 A' m) A! F, K# R
  169. STA PPU_ADDRESS' Y. b' `! S& Z; Q
  170. LDA #$00% }) x) D. i5 Z1 D. g$ l4 ^3 c  ?
  171. STA PPU_ADDRESS5 n: T2 K! I/ w; |, ]6 s
  172. LDA #$00" [, b# X$ [) u& L4 V
  173. STA FC_Data_Buf  s8 y" n* |1 {6 c
  174. LDY #30- x' I8 S1 k+ w; t* n/ D
  175. Init_Name_Table_Text_Write; K0 ?5 \/ L2 {7 q
  176. LDX #32
    3 e4 j4 M1 @4 z* ?( U
  177. Init_Name_Table_Text_Write_Char7 }( D7 r7 V; u& T' }
  178. LDA #'0'
    7 c; `+ H0 P' T+ m& L+ s1 C8 }6 _
  179. CLC! d$ \& w# q2 i9 _5 _$ u
  180. ADC FC_Data_Buf" Y) Z0 ?7 _+ v* q; n* E5 G
  181. STA PPU_DATA5 M, C# x3 o/ v0 J+ P; c* g; o
  182. DEX8 P* s( ?: U8 k5 h  ]$ K( J* B- p
  183. LDA #$14. t5 ?1 P4 Z6 C8 H- i; {
  184. STA PPU_DATA
    $ a# v0 [( O6 k' d' b7 k
  185. DEX
      C' C8 I0 W  ^( h' S4 |& T
  186. BNE Init_Name_Table_Text_Write_Char
    & t' U; u# L/ t# v- a4 O* b  i
  187. INC FC_Data_Buf( ?3 W( z$ ?1 z( ]5 g. u
  188. DEY: ]9 R+ e* j7 Z9 X8 Z+ T* b
  189. BNE Init_Name_Table_Text_Write
    - e8 K( l/ }  o/ ]* r
  190. RTS
    4 j2 k8 `; T' e) F& k' q* u
  191. 1 _- w9 p/ O) Y! b2 q
  192. ;==============================5 |9 Y( x5 ^5 r
  193. Init_OAM_Ram;初始化精灵内存' ^6 t. {4 {5 ?2 S
  194. LDX #$00$ N+ d' f9 a/ Y6 L: H! p+ D
  195. LDA #$006 n; u2 c8 Z8 z' U4 h
  196. STA PPU_OAM_ADDR
    ; d5 g2 a5 S. I) g" P$ A* M* C* G
  197. LDA #$F8
    8 W0 v0 i; u- |( _; T- [, v
  198. Init_OAM_Ram_Write
    6 R) Y" R" C3 g; _# z, B$ Q
  199. STA PPU_OAM_DATA, u3 q! U' @  a) P5 B% c
  200. INX4 }2 R: I$ @* Z: l
  201. BNE Init_OAM_Ram_Write
    2 l' x/ ?- m7 J2 @3 L; x: e: U) z
  202. RTS
    5 G3 e# d# {3 W# n! y' [* n

  203. * t. E8 D, q. x6 a2 i
  204. GamepadProcess;手柄处理
      s, f: X+ V' c( g( I) \
  205. JSR GamepadDatacan# w. U& E0 s. m# e0 R
  206. LDA <Gamepad_0_Value* O" {2 ?1 E% p. G: P# p6 g8 i
  207. STA <Gamepad_0_State
    9 j# R, b0 K) y
  208. LDA <Gamepad_1_Value, }! _0 U7 l6 f+ Z9 \
  209. STA <Gamepad_1_State
    4 E- l( ]8 W- l* N0 s
  210. JSR GamepadDatacan
    + d& Z! q) u" t( c" D0 T0 W! {% q
  211. LDX #$01) i: p' q& J+ a% z8 `/ y: d
  212. GamepadMergeCheck;合并手柄输入检查
    . O+ B1 C  A) f* ^8 ^
  213. LDA <Gamepad_0_Value,X
    2 B3 S$ j# i7 J1 x$ {8 o7 T
  214. CMP <Gamepad_0_State,X
    " X1 \3 k& ?$ i8 ~7 g2 n. W* S
  215. BEQ GamepadMergeInput4 t8 ~3 ?$ f% X0 O( U" v6 o
  216. LDA <Gamepad_Temp,X+ ]# Q5 y  \0 H& ^9 [8 b
  217. STA <Gamepad_0_Value,X
    5 `. `. S( q% |: w% w
  218. GamepadMergeInput;合并手柄输入
    5 f1 w. W! K/ Q" `5 J: M
  219. DEX
    ) Y0 Z) y( @$ h' D- \1 e& U
  220. BPL GamepadMergeCheck
    . W" j2 Q' T( p% V6 p
  221. LDA <Gamepad_Merge) l3 e, M0 `# `' \" Z4 p
  222. AND #GAMEPAD_MERGE_FLAG! d/ n5 P; _8 E$ ?6 Z
  223. BNE GamepadStateProcess
    3 P- O* ^: s" N0 i. z
  224. LDA <Gamepad_0_Value3 g- o4 z1 n, o  f/ i
  225. ORA <Gamepad_1_Value) E+ m; w6 u* ~& C
  226. STA <Gamepad_0_Value
    % @4 Q9 A7 x4 X9 i! O% v' n
  227. GamepadStateProcess;手柄状态处理
    & w5 H. Q0 b8 g" g
  228. LDX #$016 n: p5 S" d$ V4 t% \. i2 d# }! R: W
  229. GamepadStateSave;手柄状态保存- H  i$ L( Y; D8 h; Z# _5 w- M: A2 ~
  230. LDA <Gamepad_0_Value,X) f) K) j* P0 a5 W
  231. TAY/ L9 K5 |4 @" X
  232. EOR <Gamepad_Temp,X
    . v9 \# n/ P3 J; w' [) N: m
  233. AND <Gamepad_0_Value,X& Y& l5 M% w, L4 ?
  234. STA <Gamepad_Once,X$ x  e9 w7 w5 b3 O+ a4 R
  235. STY <Gamepad_Keep,X
      B: e) Q9 a1 V4 v' w. I$ Y# D/ b
  236. STY <Gamepad_Temp,X6 x9 _2 w9 P  E8 L$ m% T
  237. DEX+ r! P2 T! _+ u, g6 a& G5 b
  238. BPL GamepadStateSave
    9 ~) H$ G2 M$ z* j2 N: ~
  239. RTS
    ! H, v, d% m  v, _& K; e" T

  240. & d6 Z% c; z) ]9 I$ m# _
  241. GamepadDatacan;手柄数据扫描
    ! x$ L# K+ r4 b
  242. LDX #$01+ Q6 ^/ |- N% H) b8 ~3 F
  243. STX $40160 D) W2 y, }, W# V* V9 m0 s
  244. DEX
    " s( f/ `  g, R% y6 O
  245. STX $40165 z9 p6 @# J! K2 ]% i
  246. LDY #$08) n! Q4 U- y! Y  ]/ W6 Y
  247. GamepadPortScan;手柄端口扫描
    1 o! ^( G% Y; p( r% K+ N. I2 g
  248. LDA $4016
    6 D7 e' B3 g9 e7 O4 e
  249. STA <Gamepad_Port_Value# v6 w* o" r1 @; g* D
  250. LSR A' j6 h' D7 ]) B" M, A% }1 h3 {( |
  251. ORA <Gamepad_Port_Value+ \+ Q  I# z  W3 [5 V6 G) y) `
  252. LSR A
    - g& G" s$ j# l" D6 S: T. I$ u6 k
  253. ROL <Gamepad_0_Value  R. w; ?# c( S* o
  254. LDA $40171 ~1 u" z5 p: o3 S# `( m: L
  255. STA <Gamepad_Port_Value9 Y% F( g6 H' |, s& r* I
  256. LSR A
    0 I! ~! L+ R6 l2 g, W
  257. ORA <Gamepad_Port_Value
    ; A! H4 J- o" F1 u9 ~
  258. LSR A+ U' E( l/ @5 o* v, @; J: I
  259. ROL <Gamepad_1_Value  n+ P/ }( |+ q( m/ ^+ B
  260. DEY
    + ?+ X0 u/ m8 a, ^! o) r! M* K0 S
  261. BNE GamepadPortScan$ g, y; \. `: l% X/ [8 R* E) V
  262. RTS
    , i% d7 ~3 i1 x: ^8 b
  263. $ c" A/ ^6 x! K" ]) l
  264. ;==================================================
    * {4 v, D2 |1 w" P' ?
  265. ;PPU处理
    2 V3 P5 }/ M; X1 m7 i% r
  266. PPU_Process, U  g, j% H. J  E9 W
  267. LDA #$006 K! D6 [$ w! X" O8 N* ^
  268. STA PPU_MASK
    " g& f3 {, o4 l. X9 ?

  269. 2 s  B8 f5 l/ l; l; q, E
  270. BIT PPU_STATUS
    9 Q3 b2 Y/ ~' s5 t  E
  271. LDA #$20( w* p0 ]; U7 h6 T8 X/ [' T; |
  272. STA PPU_ADDRESS
      B1 U! Q7 A" j/ a  [
  273. LDA #$00
    ! F! N& {" c! g, f$ }
  274. STA PPU_ADDRESS
    ; J5 P% }. a/ J
  275. 8 s& E3 i1 a& G  c
  276. STA PPU_SCROLL% X' n9 }* E: U) Q" r0 i
  277. STA PPU_SCROLL
    # i+ Z+ M" _& Z$ t
  278. 7 r; v3 F1 m' f( w
  279. LDA PPU_Msak_Buf
    ( r( D, }) L$ }$ {
  280. STA PPU_MASK
    0 g% a9 ?( R2 h0 {0 _; e2 n3 s+ u
  281. + [$ ?- _0 X) S- ]7 o* H) l: i2 K5 ~
  282. RTS4 f5 g! Q2 _' o3 K9 b8 T: G: ~
  283.   w" D7 H7 [7 K6 m
  284. ;==============================
    2 B" B) A' i) a% j. j
  285. Time_For_Vblank;延时等待
    ( B& {' t+ G! N( Y3 Q; S8 W
  286. LDA PPU_STATUS1 }, k* L; P+ c! D1 L* p
  287. BPL Time_For_Vblank
    ' x) n# ^% k6 c" n5 W
  288. RTS
    5 H; G- b1 ], s( X5 N
  289. ' Y& G; x' |& ~" l+ |- a
  290. ;==============================5 [6 b, Q3 m0 A- |$ w) c" N9 I
  291. ;初始化MAPPER19
    " y( F6 c' O9 y0 S/ ^1 q/ S
  292. Init_Mapper19' D+ E' b3 J! L  d+ n* G/ t+ O1 F1 c
  293. LDA #$00
    3 d0 P8 m, P: n7 Z; |8 v+ P
  294. STA M19_CHR_0000
    ; |/ J( x  V& L* n8 J+ b: A
  295. LDA #$01
    + R. ?/ U& o& f  k0 R
  296. STA M19_CHR_0400; O- e! G7 M1 u3 v
  297. LDA #$02
    ; ]+ ^& z8 w& k" {7 Q/ w
  298. STA M19_CHR_0800
    4 O. n1 I1 U! E: S. `- E
  299. LDA #$03
    5 w) h. g, F4 U' l$ R
  300. STA M19_CHR_0C00) |& b  ]0 ]  X- r
  301. LDA #$048 J: w4 s2 Q& }; h7 ~& V8 p2 B
  302. STA M19_CHR_1000: ?8 D6 w. y* t2 }( v* o
  303. LDA #$055 c* E  ~' |' U
  304. STA M19_CHR_14001 c: T! e5 o, U3 ]
  305. LDA #$06
    3 ^8 {4 p5 [  y; X$ i
  306. STA M19_CHR_1800
    ! e& ^3 w4 L3 H# z- Y
  307. LDA #$07) M2 K. ?0 {9 h1 W9 S; n+ V( m6 U
  308. STA M19_CHR_1C00+ u  @( j/ l( m& Y2 r
  309. 3 b3 n' o5 R7 m6 A+ T5 i
  310. ;禁用IRQ: q5 Z& Y3 ~) d3 Z7 t* [" p
  311. LDA M19_IRQ_COUNT_H4 R; k# u0 e" c% ^8 R1 n+ D
  312. AND #$7F
    , t! ?- n* Y4 `  L* B* T$ `
  313. STA M19_IRQ_COUNT_H4 a; L  u% F4 f, i# ~% J# R
  314. % X+ I* E3 @4 }6 f( o" k7 G
  315. ;命名表
    ' w  x: W1 Y' }& Z
  316. LDA #$E0
    9 X4 N( @" d" G4 ]
  317. STA M19_NT_2000
    : z0 K1 @/ W3 N( z2 V+ b
  318. STA M19_NT_2400, u, ^: [- u8 u0 X

  319. " L0 L3 j  B3 P6 b  v. D  a
  320. ;命名表+ q3 b! g% \7 _9 m1 a+ t
  321. LDA #$E1
    & x& U. X. c( G, x/ z
  322. STA M19_NT_28000 D3 M& B' u' S3 L- v3 L
  323. STA M19_NT_2C00: w% Z6 W& B( l

  324. 5 e8 B" p8 @. j& N+ u/ e
  325. RTS2 E- S8 v) T4 t- J
  326. 8 k- p9 g4 C8 z- t1 D
  327. ;==================================================
    * v* C; _  p8 F4 O4 D" {6 h
  328. ;重置中断处理
    + D6 ~2 G4 `2 }2 ?# N" k$ V+ s
  329. ResetProgram7 o7 r0 p2 a, d% q0 t
  330. SEI" W8 J! V8 x8 l: R0 W
  331. CLD1 P& X- K. J2 x' i, G1 y# S  \. _
  332. LDA #$00
    7 q: @; p% J2 V5 y! {
  333. STA PPU_CTRL
      c, t9 W* v, X) q
  334. STA PPU_MASK
    ( C( [  H* k* l
  335. STA PPU_STATUS6 c2 k9 U2 a- s- c. n- m
  336. STA JOY2_FRAME' E% c. ~3 a9 T4 ?8 Z
  337. STA APU_STATUS3 ^7 v2 V% Y5 K4 G" Z
  338. 0 `; U0 t8 F9 u" {( n, x
  339. LDA #$C0
    # D$ ~- G- r! n2 ]  `, Q
  340. STA JOY2_FRAME0 k' U) x4 X( V8 Y" N
  341. 0 d" H3 F  u& ?
  342. ;等待vblank6 y" g8 ]$ U" k3 G4 p- x
  343. LDX #$02
    ) G+ d1 d, c/ K: N+ s, l
  344. Vblank_Wait_15 L6 F5 K& |; F" k; K1 @; E
  345. BIT PPU_STATUS$ h2 q0 d/ U- M% g
  346. BPL Vblank_Wait_1  B: @4 z" p+ \* u
  347. Vblank_Wait_2& b# A  B' E" k( V- M. @
  348. BIT PPU_STATUS& u' p, y* B. G
  349. BMI Vblank_Wait_2
    3 h" K3 J3 h% n4 N; y$ i6 g
  350. DEX' [: u7 I& z/ T- Y0 F4 [3 ~& f
  351. BNE Vblank_Wait_1' X$ D% S) z1 `/ W+ Y4 ^0 T( K0 {1 [& p

  352. & o6 G/ A' B4 t7 E4 ^
  353. LDX #$FF
    1 Q* \2 J: G& ^% @
  354. TXS
    ) X1 b+ B3 r+ ^0 L5 v& T5 R* z
  355. / g% g. }8 g; f$ {5 Y0 Y
  356. ;初始化MAPPER19- l, e. K( n/ Z" ^! I
  357. JSR Init_Mapper19$ R7 F/ I  H& C7 B) J+ _2 |$ E8 o

  358. & L, g  W: e# W
  359. ;==============================" u) d' a& ]! f
  360. ;RAM初始化* ^. d+ \) }( f1 {1 z
  361. Nes_Ram_Init8 o! s- e3 {; f( @& x, F* b( d( r
  362. LDY #$00
    8 y) t* v7 |  |" j! K
  363. LDX #$08
    : D* |* b# {0 m7 `2 F8 b- h  d
  364. LDA #$00. I& n) u4 @& @* Z3 x
  365. STA <$00# x) o2 J5 j# G! E9 E
  366. STA <$01) S: a4 a0 N& p. L9 }/ m
  367. Nes_Ram_Init_Write
    , p* m3 `8 G: F3 v. s6 B' l$ D
  368. STA [$00],Y
    $ A# p6 T1 f! m! x( ~
  369. INY& s. \5 ?/ M6 S" L, K. H
  370. BNE Nes_Ram_Init_Write
    2 q$ m0 T0 v0 @: L4 U# c* s
  371. INC <$01
    - Z  `" U6 X$ y- m1 T
  372. DEX/ ^8 _7 B* T- J
  373. BNE Nes_Ram_Init_Write
    3 O! ~  u+ k; T

  374. - A8 Z8 ^0 U7 |. Z
  375. ;初始化命名表
    $ }( D: e$ u: g. _) R0 p
  376. JSR Init_Name_Table6 Q( C0 D1 U. n- a- [

  377. 9 V, W% V+ X* p: B
  378. ;初始化调色板
    + u; L9 g$ Q- [
  379. JSR Init_Palette
    1 a0 p  s+ h9 A# V8 g
  380. & Q: N. T# `# N. Q
  381. ;初始化命名表属性
    1 |7 S8 c7 K. |& ]
  382. JSR Init_NameTable_Attributes; o" _) ?, @% {0 o( Y

  383. " p5 T- `  E! e# y, J
  384. ;初始化精灵内存
    " R0 i% B9 ?, s6 p- M" ~
  385. JSR Init_OAM_Ram
    7 G+ [! G6 Z' o& m! h; O% S

  386. ! f* T/ l/ @! {4 T! C- e
  387. ;在屏幕上写点东西
    1 V6 t9 S# ~. d- t9 [
  388. JSR Init_Name_Table_Text
    ) E5 V/ F: L4 n5 A% i" a
  389. 9 h/ c9 `+ a6 Y& L# m
  390. JSR Time_For_Vblank
    : ]7 W3 X& }4 T
  391. ;开启PPU控制
    7 c  Y, O' }% A2 V4 l
  392. LDA #$A8
    / a) i, W" _* {
  393. STA PPU_Ctrl_Buf1 ^% K8 ^" [% n% f6 @& [
  394. STA PPU_CTRL  s: w: M4 [1 u$ T
  395. 6 z; N/ M" J* \; n
  396. ;开启PPU显示! r) z3 B+ b) d8 ^1 n
  397. LDA #$1E
    ( E2 E6 {! M8 g4 b6 v
  398. STA PPU_Msak_Buf
    $ O! _/ g, `9 G5 U" R

  399. % R5 p. @+ o. _4 ~; h; z
  400. CLI
    : V: _) F9 v1 h4 r, T9 x
  401. JMP Loop
    0 h) X2 f% E9 M! z. n

  402. ( [( A" d' e/ W) s
  403. ;==============================
    7 o: Q! F, [- u3 T
  404. ;死循环, 等待NMI中断6 F9 g; n$ v+ {) i2 w, F
  405. Loop
    3 T2 q) t$ D3 E7 V: e0 P2 f9 U
  406. JMP Loop
    8 k  ]. n2 n! J9 X) W8 e

  407. 5 X. ^% q% K5 z
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9677 X& D/ ?. X( v

  409. % v, F% `1 A3 ^& Q8 A& U; {! p
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    ' d/ O' L$ p  C& c
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    . Z8 h3 r$ j; F9 [" y( m5 s
  412. ;==================================================, ^+ A/ H7 Q$ s& v& x3 d
  413. ;NMI中断处理
    # B* h6 V5 x' F
  414. NmiProgram. |( `9 R; W8 g3 Z
  415. PHA
    : w- @$ I0 |- w$ Z- c
  416. TXA+ e( ^( l9 H( _! L  K
  417. PHA% }3 q9 S9 I- p' G
  418. TYA
    7 \, J3 C% V( N8 m( T6 o" f
  419. PHA! w, r, m) x* I% s* \
  420. # R; s$ v& `; Q* o
  421. BIT PPU_STATUS
    , @; O7 }/ b5 m$ v
  422. " t# R" V1 O# O
  423. LDA #$00
    # q8 B. C7 F7 g) \3 c  x( J
  424. STA IRQ_Index, i- ?# F$ B4 g8 J9 p( b$ t
  425. 3 s& ?$ {  }6 m3 O
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    3 t5 U5 }( V" h* ~
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)  Z' R# A( Q8 W" k1 `+ O3 u
  428. STA M19_IRQ_COUNT_L
    % ?6 ]" Z( R- F
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    0 P2 m- a/ f( l! Z
  430. ORA #$807 z, i# d( L. g! |8 D
  431. STA M19_IRQ_COUNT_H
    2 d: ?- Z5 E) n1 d( L+ [! t, V0 t
  432. CLI
    ' u+ Q( g0 V3 M3 c2 o& P0 U: F
  433. ; ?- o0 {& B- l; f& T9 Q4 \
  434. ;关闭PPU控制
    # X, ?& Z3 g4 V' g& w& `- z) S7 a5 p! Q# a
  435. LDA #$00
    ; f8 A% k. d) E- P
  436. STA PPU_CTRL
    4 }  A8 |% {* ~" C- V
  437. ; x* W! m% u0 }
  438. ;处理PPU
    8 E; ?, d% y  v4 C7 @
  439. JSR PPU_Process  y% R) b' b& L8 Z- J, Q) a

  440. $ \% T- [, g9 Z3 s; w# z1 y7 g
  441. ;开启PPU控制* ~. K& m) q2 W: [( v* a
  442. LDA PPU_Ctrl_Buf: Q! t% g: Q# z( t2 A% o0 n% c1 R
  443. STA PPU_CTRL
    ; @/ L9 w; v0 e9 }4 J

  444. 4 K3 n& s# q0 A5 W
  445. ;手柄处理" A9 P- D  p0 T: h* f7 b0 B
  446. JSR GamepadProcess
    2 H$ h7 [0 Z! j% Q+ ]& H
  447. 2 H& e& e9 m; a
  448. LDA #$001 A9 r; Y& D9 R1 g% V
  449. STA IRQ_Index: L: V! i; i5 V0 ?' n4 i% c6 a8 u" ~
  450. : @, O9 A/ T3 \- |
  451. PLA
    : c/ z% {, o% i7 b0 }4 _7 i
  452. TAY
      G# [/ [4 `, H
  453. PLA: e& C+ E% x& J. c$ [1 z
  454. TAX' j( D" [& R" a/ N+ t; W) v! l3 w% \
  455. PLA- ~) s3 ?* Z8 ?/ p
  456. RTI
    7 F) [3 P) \- X- o

  457. & j: f" j4 ~/ f3 c: P: E9 P. }
  458. ;每行扫描线113.67
    ' r+ j' x$ ~( E  Q
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967): K7 [1 p8 Q' _% q
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7' ]4 y! w( q; p) w- Z1 x& z
  461. ;==================================================* j7 b5 F' i; _+ S+ i& H
  462. ;IRQ中断处理* _( D7 f3 f0 u  @
  463. IrqProgram0 e- u7 Y3 ~1 V* Q, x* i0 v1 s; R
  464. PHA
    8 h( ?7 j) D( V7 j+ O8 k
  465. TXA
    # v7 z' l+ L# k/ W% |4 e
  466. PHA
    1 ]& h2 H8 @4 V
  467. TYA
    + n0 r8 C5 `# d, \" s6 l
  468. PHA. U. ]8 ~& C) C# n$ Y3 n* Z' Y
  469. + L, P5 W* j3 h
  470. ;16条扫描线后触发IRQ
    # V2 L( l9 S0 B( ?: b* g3 k: K) v
  471. LDA #LOW(BEGIN_LINE_CYCLES)
      Z& G( l6 |/ [& w0 c6 W3 b5 {( Z
  472. STA M19_IRQ_COUNT_L
    ( w. E$ U8 A4 m* I; \, g: [. ^
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    6 y2 ~1 x* O$ f4 V6 ?/ i
  474. ORA #$80
    ) }7 V" u' y3 ?! V0 D- X
  475. STA M19_IRQ_COUNT_H3 u1 `& K! K1 k5 _4 u

  476. 0 W' w4 k$ y5 J6 L5 i
  477. LDA <IRQ_Index
    3 m; a* h' S1 }' a0 i# K6 X
  478. BNE * + 4) ?  q$ P; U3 i3 V) G+ w
  479. INC <PPU_Scroll_H2 W1 d+ u* F) F) I: \5 M2 ~

  480. . A: V9 l0 y! @/ g$ W  o
  481. ;设置屏幕滚动
    1 h! }. h/ }) k9 F% d" W1 ?0 d
  482. LDA <IRQ_Index
    ) H' A3 Z; @; l' `2 d
  483. AND #$018 o2 S% W1 e7 N6 b9 S" E' X
  484. BEQ Irq_Scroll_Right
    2 ^6 \) l, v  r6 r7 n/ o$ K& n
  485. $ U: k  m8 A$ i
  486. Irq_Scroll_Left/ ?& X2 u% S9 j" f* L9 P8 h9 x
  487. BIT PPU_STATUS; O/ J$ \4 j. R% U9 n
  488. LDA <PPU_Scroll_H
    6 F% N6 n, ^, A( t
  489. STA PPU_SCROLL' L9 H, P9 x5 z2 k  e
  490. STA PPU_SCROLL
    # Z- }. b, [; _8 I: X
  491. JMP Irq_Scroll_Over. o' G7 L- k% E' s+ U

  492. 6 A2 i% C. `( e' o/ s2 [
  493. Irq_Scroll_Right
    : \  V+ t9 k# p  i. a/ r
  494. SEC
    5 K$ `- _, c+ m* f
  495. SBC <PPU_Scroll_H/ Z$ e1 V! y5 D. z4 ^* x, d, J
  496. STA PPU_SCROLL
    + U9 J9 F. `0 r+ R3 o7 X1 P
  497. STA PPU_SCROLL
    ; l/ ~8 }6 U' ?6 |4 N/ H  r6 Z
  498. Irq_Scroll_Over) |, b3 S0 X9 l6 H0 }( u9 g
  499. $ o: x% d# i% c; h: k
  500. INC <IRQ_Index
    6 H% j0 \% A$ `: u" ^7 Z

  501. , y# a% Z1 l7 H4 u
  502. LDA <IRQ_Index
    4 E" {+ i% m" }4 O6 n+ `5 c
  503. CMP #14# W3 {8 s. r2 w. I$ k/ g/ @
  504. BCC * + 10
    0 [# u- K! @# l* z7 e  G0 R
  505. LDA #$00
    $ m( m* O2 l" X0 K: K
  506. STA M19_IRQ_COUNT_L
      [, k* Z9 M7 d2 i! A# @5 c
  507. STA M19_IRQ_COUNT_H# J  h0 B# U" @: ]! V, \

  508. " g  [2 y8 K7 K- |% C$ W4 x, ]" y
  509. IrqProgramEnd
    1 c! Z  P6 K3 Z& Y% J. v7 w
  510. PLA* |! \7 M/ G" S  F& M
  511. TAY
    / O# A  s9 ]5 ~, C. m
  512. PLA9 _( ?, Y* @* A% h  L: ~
  513. TAX
    / y2 D# O+ ?9 l
  514. PLA
    . H# u# d6 i7 _+ f
  515. RTI
    - [2 G* B5 j; j3 e2 q# @2 E! r8 m" h

  516. 6 K2 e2 N) B/ z4 @, r
  517. ;==================================================
      z8 V- \- O! N! i5 m% x  \4 `* Z
  518. ;中断表7 a; o, P! E4 E) T# Q0 m
  519. .ORG $FFFA, G( W, G) J8 A' e+ k
  520. .WORD NmiProgram
    : ]/ x& L! y$ z- P
  521. .WORD ResetProgram. D2 A. I8 S& B+ J1 |  v. F6 c, R
  522. .WORD IrqProgram
复制代码
2 v3 T8 Z1 l* k# T9 V0 Z/ l. g

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-2-19 06:38 , Processed in 1.073242 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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