EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]2 [4 ?8 p* U6 ^, z0 h& P8 K5 v
  2. ;FlameCyclone 20230710
    . b( U8 _/ u7 k: q
  3. / @# b, Z, a" e
  4. ;文件头3 G  u- @* k- m2 N, ]; s9 H$ ~0 e
  5. ;======================================================================+ {! D6 l" B' O2 {7 h; C
  6. .INESPRG 4                                              ;16KB PRG 数量
    ! o' O' z& z6 P6 J4 B
  7. .INESCHR 1                                               ;8KB CHR 数量
    * ?# R% R. T, V& o
  8. .INESMAP 19                                                 ;mapper 197 E  V# U2 Z2 W+ M1 J+ N
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    : ^' \6 ]" c2 z! I0 W, k
  10.   a: b  S: c. j# `0 c" b# z4 F! H
  11. ;必要条件! i8 Z; E2 G9 p: e3 |% b1 k/ L
  12. ;1.持有CHR ROM
    ) {4 f+ Z3 |  e" r# P0 x& p, @
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ) D7 i4 h; m' @# @8 ^; w  A$ v/ |
  14. ;3.精灵内存(OAM)不为空
    ' X5 b3 ]! e2 z4 O* s) p! u
  15. : @. z3 p6 ^8 }% Y& T- i( L
  16. ;==================================================4 L" }& n# l6 f! M$ q% P
  17. ;NES端口常量/ p) `0 |, F4 `" g0 k2 @
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    2 ~$ R. g% Z: ]; f  S' G
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
      X0 G' f. g9 h$ B2 S  m
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位" t8 G4 l' `. t8 z! d
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1- H: F3 n- L% P+ k5 M
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    5 @& S; i6 d& h6 w+ _9 G
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 8 v" a' [7 D: v5 o! e9 R
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加# |* _! ^( r* w" }0 ^- T8 ~( o" q1 E
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    2 q( F9 W" A( z, p0 u7 I2 t4 e8 n, L
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存/ z: Q8 m. F& x7 n
  27. APU_STATUS              =   $4015   ;声音通道切换
    7 e. S1 u4 R  H. v0 k& @+ ]; f) }$ [
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    % f/ x+ f- Q" L1 o
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    1 j" Y  O, }/ D
  30. ) ?5 x# J. X6 O9 X" P9 S9 g
  31. ;==================================================
    ; [# K% S, w3 W: o( K6 H! W" G( O  l
  32. ;MAPPER 19端口常量
    1 ^) N. w5 h$ t2 }% S
  33. M19_CHR_0000    =   $8000
    9 ~: F) ?4 l- ]- H' O
  34. M19_CHR_0400    =   $8800; b  m' I8 C" E/ G
  35. M19_CHR_0800    =   $9000
    7 b- l: A, C) n
  36. M19_CHR_0C00    =   $98007 m7 _- g- [, _1 z& @* e
  37. M19_CHR_1000    =   $A000
    $ M. X8 }# q- K8 v1 |, N1 l
  38. M19_CHR_1400    =   $A800) K) {) K; {; v* m( B# m- U
  39. M19_CHR_1800    =   $B000
    9 [! N1 q  e& K! G
  40. M19_CHR_1C00    =   $B800! i6 t' l7 z. N& D/ t* |) |0 \
  41. M19_NT_2000     =   $C000
    - a6 t6 ~1 \" {' b6 v6 @
  42. M19_NT_2400     =   $C800
    + q; A3 b5 P$ q
  43. M19_NT_2800     =   $D000# L' W2 D; n  O$ F* e
  44. M19_NT_2C00     =   $D800
    ) j1 {7 ^" p& l- d- U
  45. M19_PRG_8000    =   $E000# @8 V6 z" [  l5 Y+ M. I3 e
  46. M19_PRG_A000    =   $E800# `! e2 c, P! g" n. q
  47. M19_PRG_C000    =   $F000
    / n- _3 ~: q: D) C% Z, _7 |2 d( X
  48. M19_IRQ_COUNT_L =   $50003 t& M0 P7 j4 j( F: p/ |2 r0 Q) j
  49. M19_IRQ_COUNT_H =   $5800
    % q. ^  w, [9 T- a7 ?7 P. }
  50. & b9 N, m- M0 s) c* `# @) k0 J1 A
  51. ;==================================================
    ' `& q. U8 o# I' f4 E' v
  52. ;程序块配置% `& d: l  m7 a5 L, y
  53. BANK_DATA_MASK          = $079 F8 a9 X0 ~  v9 `
  54. ;--------------------------------------------------: L# O* Q7 F7 a8 H$ S, m& b* @
  55. RESET_BANK              = $07: k! N( d) b* v$ Y8 _3 A( z
  56. RESET_ADDR              = $FC00
    ! c: l) G8 e! ?% ?& n$ ^0 |
  57. % T, c  d6 h# v* J3 t: u; }) f
  58. ;==================================================7 T) c' Q& o1 V
  59. ;图像块配置9 O2 Z# a: E! g9 L" G
  60. CHR_DATA_BANK           = $08" [( N* c; J! ?# P( k

  61. ' T7 L' Q% p- a+ J8 S$ P
  62. ;==================================================
    % B, u& \; s: s/ `8 M+ O& o/ F
  63. ;零页内存地址配置
    1 \: `" f( u5 ?1 y$ M  [, j3 t  S
  64. Use_Ram_Addr            = $80
    6 a5 z- I: R4 Z
  65. PPU_Ctrl_Buf            = Use_Ram_Addr0 B; m) j3 f  b* u
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    : L9 }* e2 _1 Q2 [; `. ?
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01  ^. w8 @& D4 s* R
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    7 F7 ~) m8 `( `6 I
  69. FC_Data_L               = PPU_Scroll_V + $01$ G5 }8 U, Z+ S, ?
  70. FC_Data_H               = FC_Data_L + $01! ~7 W: N6 K; o7 g! a5 m
  71. FC_Data_Buf             = FC_Data_H + $01
    5 r  @$ C# p  q' X5 }, K' i. T" _
  72. ;==================================================
    # H- j& e2 e9 N/ P. m

  73. ) {8 l; o: Z8 f# H
  74. GAMEPAD_MERGE_FLAG = $04$ x& _/ n/ h) R* c3 P6 N3 `

  75. 0 j( U8 K, b  t
  76. Gamepad_Keep            =       FC_Data_Buf + 1" `* @$ }, n( C1 P7 K
  77. Gamepad_Once            =       Gamepad_Keep + 2
    5 f4 l: o  h2 a. s/ R
  78. Gamepad_Temp            =       Gamepad_Once + 2
    : t( N( e3 `# v4 ~
  79.                                 5 q5 S: q2 ~: ~2 l" T4 K' I9 h
  80. Gamepad_0_State         =       Gamepad_Temp + 2: B; w  B2 e/ @. n4 M. j
  81. Gamepad_1_State         =       Gamepad_0_State + 1( g" I5 d2 X- {% u5 K
  82. Gamepad_0_Value         =       Gamepad_1_State + 19 x8 t9 o4 M' |5 `1 t
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    / U3 v$ Z7 X3 U: E% F
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    ) S* G$ n) P, J$ T
  85. Gamepad_Merge           =       Gamepad_Port_Value + 12 p- E& p0 ^7 K4 y6 _

  86. / E0 @5 a+ N- P0 h! v3 Y
  87. ;==================================================
    , n- W, X; _' s) ^" f5 A5 i
  88. IRQ_Index               =       Gamepad_Merge + $01. Q4 u) m" c8 o5 o- c
  89. ;==================================================% p) d  m) i1 ?6 a8 M
  90. 3 _/ H  }3 p8 Q, Y! t
  91. ;CHR图形数据
    ' D1 p' I! v/ a* u2 e
  92. ;==================================================
    ( A! L; Z3 N) z  e* U
  93. .BANK CHR_DATA_BANK
    ; a6 z% ?1 r( @7 Y3 y
  94. .INCBIN "chr_bank/chr_data.chr"
    $ e$ d9 p( ^% N8 D
  95. + V+ i% Q7 J( s6 b2 T
  96. .BANK RESET_BANK & BANK_DATA_MASK! d0 T  r. Y+ I4 B& K
  97. .ORG RESET_ADDR
    8 u5 K/ x7 Z% r( N; W# ^
  98. 8 w: s; `6 G+ D- \6 U0 b
  99. ;--------------------------------------------------% S8 g" y1 }0 E$ ~6 o+ ^# W
  100. Attributes_Data* i. V& p1 r& T3 t
  101. ;命名表属性
    * r/ [- a2 b, w' M# d5 s" F" ?
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    % c# x& ^: H2 E/ x5 {
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    $ u. J( n  z4 z- ^: Y
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA: _- ?7 p1 Q$ M8 _
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$550 ^5 L& k/ a( U; [/ @9 C4 I
  106. ;--------------------------------------------------( u8 j3 w' ]8 k' E( I
  107. ;调色板数据
    / B5 M* t5 F: f5 }* i5 [
  108. Palette_Data  @  `, l2 y( @6 |
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    1 [3 {' G  @: o9 D* I1 c
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    . m* ?% M$ B9 c

  111. 7 K$ d/ G6 g3 f  ]4 Q
  112. ;==================================================
    5 O5 a8 {9 W9 }4 ^, w9 d/ f
  113. ;命名表初始化) P5 o9 `  o  e) h3 P. I
  114. Init_Name_Table
    8 N4 I7 R8 i4 u8 E! {# J
  115. LDA #$20
    4 S! d0 e; r; s( x* Y
  116. STA PPU_ADDRESS( @3 f6 q2 `- ?+ Z
  117. LDA #$00
    3 J, t! N' f3 o2 r( I7 O
  118. STA PPU_ADDRESS
    " u; H5 r4 ?% m; r
  119. LDA #$00
    : t- F% @2 Q- Q
  120. LDY #$00! H/ ~6 |4 d- w$ Y, g7 f* z
  121. LDX #$102 [0 p. `" {% ?5 C9 r
  122. Init_Name_Table_Write3 P9 p* L9 a  W4 ~+ _4 Q
  123. STA PPU_DATA. ]- L  J2 E# |+ @" a- \
  124. INY/ C0 s- q% F8 u, \% U! n
  125. BNE Init_Name_Table_Write
    ' A; U  ?: y2 j6 b3 N
  126. DEX
    9 |( i( {# E7 @! d4 ?& i+ i( _
  127. BNE Init_Name_Table_Write2 b  p+ d' ?9 Z
  128. RTS) O, R# u" B, P
  129. $ R: }7 ~- s& K& c2 X7 _/ C
  130. ;==================================================0 x9 a' T& d( S1 y/ u5 I
  131. ;调色板初始化( r( d; e: Z4 S( {. r7 p
  132. Init_Palette: ~# ^9 q6 v3 Y2 z/ p" j! B
  133. BIT PPU_STATUS
    , W7 J" F$ _2 j. x0 C9 R
  134. LDA #$3F
    ) t' H( M1 ~+ S: a3 V
  135. STA PPU_ADDRESS
    $ `% y2 l, F4 ~4 E* Q
  136. LDA #$00
    # j1 c" N  G' ]
  137. STA PPU_ADDRESS
    - `1 [' ^: O1 c% x2 x# _1 j( {
  138. LDX #$00* S% r5 j; v# Z8 O8 U
  139. Init_Palette_Write
    ; C  \( F: Y/ M: o% x
  140. LDA Palette_Data,X
    + e- J; L  `( j, ^& @" w
  141. STA PPU_DATA
    2 M+ M' t; E/ P/ m
  142. INX1 ^& X4 y; Z$ N. d( M6 x: [
  143. CPX #$20. n: T1 e0 K% H. P
  144. BCC Init_Palette_Write
    2 N! t( ?, q2 t* F6 r
  145. RTS
    ! p( F' q- I( t  _+ L' ]
  146. 9 a( v  K3 n! Q0 i0 W0 }- O. P8 _
  147. ;==================================================
    ) u! @9 W( v1 g# L( j( g2 h
  148. ;设置命名表属性
    6 l  z" D- E  H: t2 r
  149. Init_NameTable_Attributes. ~; Z! f2 E- v( u
  150. BIT PPU_STATUS
    1 {7 N" I7 s4 p% X6 L# @7 R
  151. LDA #$23
    ; H& q) C4 m, q1 d+ g/ z; z
  152. STA PPU_ADDRESS9 `5 e2 B2 L: i3 c/ f) v& r$ ~4 ]. Z& P
  153. LDA #$C0
    $ j; T7 i5 x- f  ]* ?! r& E
  154. STA PPU_ADDRESS. h2 ~$ ]' B  K- G* H8 `' C* C
  155. LDX #$00
    & i1 k5 H4 ^$ ?5 g" f) r
  156. Init_NameTable_Attributes_Write0 \) U$ z: t% Q! C( M
  157. LDA Attributes_Data,X
    1 \% n4 v' I0 o% o. _. H
  158. STA PPU_DATA
    $ y  r- L# e. Q- |+ i$ I  F5 p
  159. INX5 K. [; w2 H. t5 x
  160. CPX #$407 \1 H7 _# @& k
  161. BCC Init_NameTable_Attributes_Write4 K+ e3 N' V+ V2 j! u
  162. RTS
    / c8 Y* l; L# _4 o  D

  163. - x. B$ V5 _) f& z& K( Z5 Z
  164. ;==================================================+ d! q3 s; y! W: K# U$ `5 C
  165. ;初始化命名表文本  f0 G' O6 z/ y% b  W- r* u! K5 c
  166. Init_Name_Table_Text
    2 S# e7 S3 _$ `% b
  167. BIT PPU_STATUS
    8 p, C, K: U* `8 p5 A5 t* f' a
  168. LDA #$203 W8 j2 S2 u3 y; J! e3 Y9 G2 Y
  169. STA PPU_ADDRESS
    - C  E" M$ N7 V2 c- {' r) H
  170. LDA #$00
    . M- R4 K0 z5 X- {. B
  171. STA PPU_ADDRESS
    ' F7 I" W9 U0 B+ W9 p( Q
  172. LDA #$00' I( x2 B. J- m" p5 E
  173. STA FC_Data_Buf$ B/ E' N7 {0 `
  174. LDY #30
    + b1 p$ y1 l  M, a
  175. Init_Name_Table_Text_Write, x5 ~; x5 H- D$ @6 n
  176. LDX #32
    ! \3 |% G8 D2 V0 V6 e  A2 o5 ?
  177. Init_Name_Table_Text_Write_Char
    " p* Z! {* Y) s
  178. LDA #'0'3 M+ U5 a! o; r4 |9 U( ?
  179. CLC. G, ]$ S! o6 u+ A* W! `
  180. ADC FC_Data_Buf2 t" ]$ u. W8 v
  181. STA PPU_DATA
    4 p+ {- f. d/ ~. g
  182. DEX
    # n2 n2 T/ k- w% _' i/ s- ~' r
  183. LDA #$14+ Z3 n. _: |: \) l2 E
  184. STA PPU_DATA4 d4 m2 `# B4 c5 L2 p2 s
  185. DEX; Y6 b, p0 n4 r  ]+ @
  186. BNE Init_Name_Table_Text_Write_Char
    5 N0 h1 n* ?7 W- Y/ g: f
  187. INC FC_Data_Buf, P) h+ z% N  ?" A: Z" l9 M
  188. DEY
    & W1 t2 X5 T" u$ S
  189. BNE Init_Name_Table_Text_Write# Y$ ~' `+ Z: _# P, ]8 C
  190. RTS7 e4 B7 t: u3 P7 ^

  191. ' r- G& e) d$ m/ t# ?2 ]
  192. ;==============================
    9 C2 s( b2 n1 T( _6 e' U
  193. Init_OAM_Ram;初始化精灵内存: T% ?  a7 n  X
  194. LDX #$00
    - ~% }" |, q# A; N) h7 i  L
  195. LDA #$00( m5 H" o. M2 G8 m  N4 x
  196. STA PPU_OAM_ADDR
    8 r3 L4 B; a" M; h" ]
  197. LDA #$F8
      {2 v6 I. }$ c6 `! w% F$ x7 H
  198. Init_OAM_Ram_Write
    ) Q: I, @+ z# S9 K
  199. STA PPU_OAM_DATA$ l( t% e* e- {9 O9 K# V$ V
  200. INX6 x% o% u7 j$ E5 N: q
  201. BNE Init_OAM_Ram_Write
      v1 s- K2 ]2 F
  202. RTS
    6 m2 X6 v, d8 n7 j) G6 f7 e& {" c

  203. 9 s4 D$ v; t8 @/ h
  204. GamepadProcess;手柄处理
    2 f$ ?7 r  g5 M; F. p9 w
  205. JSR GamepadDatacan  |5 e. R7 N( U( R( p4 a
  206. LDA <Gamepad_0_Value  Q( |# v+ Z5 a* W
  207. STA <Gamepad_0_State7 B( e) A( T( P  W4 W
  208. LDA <Gamepad_1_Value: l  F& ~$ W; Q& w; B% e
  209. STA <Gamepad_1_State, E/ v' d" H( _
  210. JSR GamepadDatacan- W9 B( G! G# f! @) t
  211. LDX #$01+ t3 r. }, M. g* K% n4 Q2 T1 L; Z
  212. GamepadMergeCheck;合并手柄输入检查
    $ W' @$ ?; c" T. G/ `
  213. LDA <Gamepad_0_Value,X
    % c, a" t; Q* R3 w
  214. CMP <Gamepad_0_State,X
    " z4 M- E5 a: T
  215. BEQ GamepadMergeInput
    2 |% P  `" ?- q$ n0 E8 H
  216. LDA <Gamepad_Temp,X, }" S7 K$ ?) Z+ m+ p
  217. STA <Gamepad_0_Value,X( ~4 m9 \" S- e$ C
  218. GamepadMergeInput;合并手柄输入- Y9 M: t, \( ~/ q3 W( p9 J
  219. DEX" a0 I; J9 x% p  B" M7 c
  220. BPL GamepadMergeCheck
    ; o3 n8 q! B9 `& O% h
  221. LDA <Gamepad_Merge# Y) ^, b* H7 ]* ?
  222. AND #GAMEPAD_MERGE_FLAG2 Z: F4 y$ I# D" h
  223. BNE GamepadStateProcess
    ) v- i( z; l) t* f5 `, ~& N2 N
  224. LDA <Gamepad_0_Value" Z8 H* L; ^3 B6 m1 K
  225. ORA <Gamepad_1_Value
    7 T2 C/ n3 e" D! }
  226. STA <Gamepad_0_Value
    9 R- J1 C5 l* r* G7 P" l2 I
  227. GamepadStateProcess;手柄状态处理
    $ G0 h/ S2 m0 [' ]8 q! l+ O; e* D
  228. LDX #$01+ v( y" q! n' k! x  w
  229. GamepadStateSave;手柄状态保存
    8 u3 i3 |* ?( K9 W6 B: J
  230. LDA <Gamepad_0_Value,X
    : I- s- n% W$ `# R8 Y! w) U5 j# s
  231. TAY1 Q! s, X4 M6 N  S5 [; W5 V# q
  232. EOR <Gamepad_Temp,X
    & Z5 B/ E! B; i* D
  233. AND <Gamepad_0_Value,X
    . ?- Q' @0 G; C
  234. STA <Gamepad_Once,X: w* k' {* }0 ~- x7 s
  235. STY <Gamepad_Keep,X
    * x  M5 A0 p, m% D1 j" k
  236. STY <Gamepad_Temp,X2 y% _/ O, K; B: e" K" v" p1 r
  237. DEX
    % a" j4 R; ^; c+ D" e3 g
  238. BPL GamepadStateSave
    4 H9 B% x" ~5 O- `1 l
  239. RTS. T" ]  `8 V) H0 X1 n

  240. / _% O& F% l# Y0 O
  241. GamepadDatacan;手柄数据扫描# B' o! n1 s, F  D0 _
  242. LDX #$01
    # d' _% o' H5 D0 Q3 J* D# R( f' P
  243. STX $4016# ]. U( W' L2 u+ P4 h5 }* s
  244. DEX7 H* h; S: {) @
  245. STX $4016
    9 J+ s$ `" M* \& V. P
  246. LDY #$08* n0 G! U6 Y. F
  247. GamepadPortScan;手柄端口扫描+ l3 X' B# _$ k2 Z5 E$ T/ I2 V) k
  248. LDA $4016: L1 {. B4 R$ i; j' h- r
  249. STA <Gamepad_Port_Value
    5 O- I$ x! G* X) T2 x3 J9 _7 R: c
  250. LSR A
    ' o2 e! d, A; U6 O
  251. ORA <Gamepad_Port_Value8 v+ U8 i+ e) u! r2 |8 F8 g
  252. LSR A
    * |9 Z4 F' S) K- X% ^9 B/ e7 ^
  253. ROL <Gamepad_0_Value' O7 _' R" R6 ]2 q
  254. LDA $4017  E1 R4 R( M# s5 o" l8 M
  255. STA <Gamepad_Port_Value2 D/ t$ F! K- j; \; n$ @
  256. LSR A
    ! U( _% k9 S, ^3 |5 G
  257. ORA <Gamepad_Port_Value
    ( K' E5 U: g. H5 P) y" K
  258. LSR A
    1 [3 X$ ~9 Z! k
  259. ROL <Gamepad_1_Value
    * j/ m' w$ Z2 [; h( T
  260. DEY7 _5 Y4 S9 \0 O% I
  261. BNE GamepadPortScan$ T8 N/ U/ h6 ~. V4 C. X
  262. RTS
    4 n' D% ]  c: _9 Q1 `

  263. 9 C) a  T5 _- @+ R: {4 _, p' ~
  264. ;==================================================
    7 d% f' u  b) t. g
  265. ;PPU处理
    / u' Y8 E1 m+ P9 `% w. }
  266. PPU_Process
    # G2 M/ S5 ]0 F; O% p
  267. LDA #$00
    / f2 q7 C# f9 m; c1 Z" U! K
  268. STA PPU_MASK
    9 l  Y2 z& f* ^6 D( V2 c* V

  269. $ m. |' z" v" O9 A# h" L
  270. BIT PPU_STATUS8 Z4 r' C/ D& s% h4 ^2 H
  271. LDA #$20
    $ T" G/ Q+ c# v! {/ {1 B
  272. STA PPU_ADDRESS' \# z% j- P) ~; y! m3 ^
  273. LDA #$00
    7 [+ p! v% Y4 D5 H, L5 E
  274. STA PPU_ADDRESS% u) K$ {$ V9 H5 P4 {, Y

  275. & Q( l9 N- W8 |% i$ e
  276. STA PPU_SCROLL4 y$ ]! o* c2 ]% k) h) U( [6 H
  277. STA PPU_SCROLL
    4 {& I! ~* g2 a3 V% l4 S$ r
  278. . S- a' R8 Y  H3 M6 h8 `
  279. LDA PPU_Msak_Buf2 g2 c! \& D9 N$ y% `* h( P) x
  280. STA PPU_MASK
    3 G" B3 x# D4 ?2 N3 ^7 F7 k' N- S

  281. 2 `& d% d; x8 I
  282. RTS
    . e5 o) F) O  Y4 N1 R0 N
  283. 1 F, k0 c9 }6 r+ P3 U2 ^9 E
  284. ;==============================' @% s# {* Z8 w% Z9 `) h9 M
  285. Time_For_Vblank;延时等待
    2 V1 g! ]5 J& ]" C" B- [9 G
  286. LDA PPU_STATUS. s; r- G6 ?! Z6 V  s
  287. BPL Time_For_Vblank
    ' b5 E% J0 H& C/ ~) j
  288. RTS& t/ {+ g7 x4 \. `9 I
  289. ' u, z! E" s2 m. s7 ^. d% Y  i9 E
  290. ;==============================5 X3 @' S0 f6 D8 P3 l# B( j
  291. ;初始化MAPPER192 I8 F3 {3 ?. `* N" S) r  D: Y7 q
  292. Init_Mapper19
    ( A- w  |  A/ y; C
  293. LDA #$00
    ) U% g6 g) {( G% K6 t+ g! J! G
  294. STA M19_CHR_00005 X& h# U" J+ H
  295. LDA #$01
    ; C2 b( u' @6 E/ M3 @. Z/ I4 V
  296. STA M19_CHR_04003 r+ q3 l6 K; M5 o3 ^8 \8 O# ~8 y
  297. LDA #$02% J0 |8 Q& d" W1 U0 }
  298. STA M19_CHR_0800
    " T% h+ _. ?! M. Q+ s" X
  299. LDA #$03
    : K4 g: c2 z! f
  300. STA M19_CHR_0C008 _2 P- ~' r7 f& e1 m" b6 \
  301. LDA #$04
    # v+ R& |1 R& H' k
  302. STA M19_CHR_10001 f: t- X# J: f
  303. LDA #$05
    : Y; G1 s' B- P7 C' L6 j! Q
  304. STA M19_CHR_14008 ]0 P! g: N  V1 Q, o8 _
  305. LDA #$06
    ! F" L6 M3 F9 ^* P. }
  306. STA M19_CHR_1800
    2 \$ T( m, e- @) p/ M, a
  307. LDA #$07$ v% U- v8 Y: p5 y' S; v
  308. STA M19_CHR_1C00
    4 Z0 m1 g/ X: G+ e/ w- u
  309. 9 `/ W( M5 C) ?/ E* [9 P. F$ n
  310. ;禁用IRQ1 G; \8 V$ D% t. {2 H
  311. LDA M19_IRQ_COUNT_H
    0 o$ C% g4 _( Q6 ?: k+ {  i# n
  312. AND #$7F  [/ x6 l/ q$ q5 B3 @8 M: @' H
  313. STA M19_IRQ_COUNT_H4 N" m) R$ U( E
  314. ) o0 J4 c) a: H4 x( F+ T; ?
  315. ;命名表
    1 t6 b3 h5 I& T8 c# x7 g) {/ J
  316. LDA #$E01 X1 }3 S( p5 s$ n  \0 b
  317. STA M19_NT_2000
    % t4 ^, [; _. Z
  318. STA M19_NT_2400% E! V- i' ?' n' S0 a: Z& E

  319. 0 B8 a5 D6 ^# G3 d; Y6 H
  320. ;命名表6 t4 b2 {: v: p. ~
  321. LDA #$E1
    * B" Q$ }6 y& ]  V: J
  322. STA M19_NT_2800
    # O( ]9 h6 O0 m) N3 _+ u  }# N
  323. STA M19_NT_2C008 I2 G# t. F" h0 j
  324. & J& T2 B- I- I& v) _. w; c2 D
  325. RTS
    3 f# `5 D/ a7 ~5 C; G: R& e' k7 z

  326. # R: i1 E8 Y) m, f4 @
  327. ;==================================================  r7 D# Q9 |  y% C8 \7 @/ O. N
  328. ;重置中断处理/ E9 Y- L8 {( Z( X( w1 `. b
  329. ResetProgram
    # w$ O& m8 [" V  w- ?% g, t' m. W
  330. SEI0 X7 X& h* {4 H& _
  331. CLD6 {& y' g( E5 j9 A+ X3 A
  332. LDA #$00
    : d0 `8 c1 T% P8 y
  333. STA PPU_CTRL+ f4 v/ J3 u; H: _
  334. STA PPU_MASK  R4 e" Y/ l8 C
  335. STA PPU_STATUS
    9 t9 |+ W  ]7 H# g
  336. STA JOY2_FRAME
    9 [- u2 D0 Y6 ]" Y7 [
  337. STA APU_STATUS6 C! @1 ]8 u, J

  338. / m! i, {/ v* I" j) m) W
  339. LDA #$C0/ _. S' s, e( h9 p
  340. STA JOY2_FRAME  ]: U' N; |5 L" a; b2 \: @' B+ Q

  341. % O1 @3 j$ Y. t3 i
  342. ;等待vblank
    - V! D, J4 G8 e1 S: c- h
  343. LDX #$02
    7 t5 w- I# U5 D+ u7 T1 G7 S- v
  344. Vblank_Wait_1( W) _5 V7 E( C+ C6 I( J
  345. BIT PPU_STATUS* U( k7 j% x: m9 b: ?. {3 S1 z, @! Y
  346. BPL Vblank_Wait_1
    1 U' K, f3 R4 G8 h5 ?) f0 b. J2 r
  347. Vblank_Wait_23 k& d  \8 e7 F
  348. BIT PPU_STATUS
    ! ]$ M1 e6 \+ m5 `6 \$ L
  349. BMI Vblank_Wait_2, o6 I9 O7 C/ l! A# b0 i
  350. DEX
    + ]* e% O4 e- e- G2 g
  351. BNE Vblank_Wait_1: u  e+ t1 K* L' z2 @

  352. : b1 ^# g! y2 p) |1 w
  353. LDX #$FF
    5 e  J% V& e1 V) e. c7 ]  m1 c
  354. TXS
    5 q* a. D: ^. v- P% e4 D

  355. 9 [4 l. Z  f% ^& c
  356. ;初始化MAPPER19  p& x# k# D# w0 m$ ?6 j6 s6 Z
  357. JSR Init_Mapper19
    - W! {8 \' {6 H4 z3 K7 E. r
  358. $ m: r8 Z. t5 m4 t# i: S
  359. ;==============================
    / y# _  x; _/ E: t6 R- |5 `
  360. ;RAM初始化$ T) H) a, `0 b
  361. Nes_Ram_Init
    6 E, _% h) X& g. t8 Y9 V
  362. LDY #$00$ G2 e5 S; H+ l
  363. LDX #$08
    4 |" o$ m3 s) U" T0 ]
  364. LDA #$00
    & B( {- H0 J% S( R) \+ x
  365. STA <$00
    # w9 ?* p% H) o
  366. STA <$016 u* _( b7 G/ K$ ~) g, H
  367. Nes_Ram_Init_Write
    ) }" Y9 V7 o) c) w/ n& v* h
  368. STA [$00],Y- ^) q5 L, Y# W8 ~* Q- l
  369. INY
    5 o8 [- A! j9 K6 S& x5 d) ^
  370. BNE Nes_Ram_Init_Write$ d: s+ [5 \! \9 e7 Q
  371. INC <$01+ ?+ Y4 J, x' y3 j' i6 X& P
  372. DEX0 D3 \8 e& }3 E* O
  373. BNE Nes_Ram_Init_Write
    0 r8 y6 d/ _$ ~4 t( X& W/ x: L

  374. 7 A2 W6 b% W# c$ X) a* q0 W' Z
  375. ;初始化命名表1 C  u' f/ a; H4 h
  376. JSR Init_Name_Table
    , h! P; w  ]4 r
  377. ( D# `' _6 ]" u# E' H
  378. ;初始化调色板
    3 G8 j) ?, A1 J* c% B# ?) V
  379. JSR Init_Palette
    # z7 ?3 r2 ^& `* ~, ]$ g

  380. ! o, \; q  f. \# y  y
  381. ;初始化命名表属性
      H) g. o3 L: p' K0 h  Z
  382. JSR Init_NameTable_Attributes# P& W1 @* a; }# d

  383. " ?7 z5 i. T4 ^- f9 z
  384. ;初始化精灵内存4 ?! _( I5 w3 m# o$ g: s& L
  385. JSR Init_OAM_Ram8 V% A5 N0 p7 w% w
  386. ! Q4 T' X% _' S0 V; g
  387. ;在屏幕上写点东西
    / L1 R8 ~( i/ G9 _: d: @
  388. JSR Init_Name_Table_Text
    / n, m1 C! }4 j6 f- A4 r0 O
  389. 8 t( h/ ]9 o- N8 H" d+ Y
  390. JSR Time_For_Vblank* P. y( t: E+ v: V: O
  391. ;开启PPU控制
    4 l* m: A8 |% a
  392. LDA #$A81 V9 m* e. q  k$ F8 h8 P; B
  393. STA PPU_Ctrl_Buf
    * f$ N8 h3 A6 F- W2 O7 Q
  394. STA PPU_CTRL
    9 [& n- w, S0 M+ W1 B/ H9 N! h. ~
  395. ) v! f$ W: c  N& e% V" a2 r3 b
  396. ;开启PPU显示' o& t; n+ l" v/ k8 p8 B* w
  397. LDA #$1E
    * |! q: F$ m% C+ o* p
  398. STA PPU_Msak_Buf
      X& d5 ~  b% O
  399. 3 R9 V9 b) n. S7 Q( [
  400. CLI
    * A- ]3 g( g9 z' Q& V
  401. JMP Loop* |! b$ K4 Y" y. g/ K
  402. ' F9 W' _- _, b& Z- N8 K
  403. ;==============================
    6 \7 e- X6 }! r! i; b6 m4 a
  404. ;死循环, 等待NMI中断
    : ~. R4 e; V; `6 y+ ]/ E9 S% e
  405. Loop
    6 m+ D+ s$ ?  W# u" @
  406. JMP Loop. ~( Y3 V' I, y6 C0 Q& p; T
  407. ) O+ m6 R/ G2 v" K
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967  r, ^1 W; e: n: L
  409. 8 x0 @) ?  o' ^0 X' N
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)3 `9 C8 Z  W% O3 p5 B
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    , }2 e, M" p0 M: D
  412. ;==================================================) G7 H; _. {1 n3 S, G: H* A
  413. ;NMI中断处理
      b1 |! \* [" W
  414. NmiProgram
    : W$ f, `/ p) y- j
  415. PHA0 y  M7 i4 |/ ?/ x
  416. TXA& Y4 k+ }& \( o5 o
  417. PHA7 R! O" h! {1 Y5 Z7 I9 Y2 L
  418. TYA$ E) [* v6 @  E
  419. PHA
    $ @1 s6 s% ~! p
  420. ( I" A9 M  y- P% w4 _& ~
  421. BIT PPU_STATUS) |/ a  {* x8 v' v7 I' P
  422. / p7 K) E7 U& }/ r. g' V5 J$ l
  423. LDA #$00
    ( q2 G! S9 e  ?: O7 l1 \+ p
  424. STA IRQ_Index
    ) F, y3 X" U  R2 R

  425. + x4 E6 t' e1 k6 i! g
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动! p' k8 G$ [' a, P. f; R2 {
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)# C' k6 u0 i- N4 @, R9 Q& H5 p. X' `
  428. STA M19_IRQ_COUNT_L- |! A- o" a* h
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
      `' U0 f8 J6 w+ f! j
  430. ORA #$80
    3 N, r, H% J9 x" f
  431. STA M19_IRQ_COUNT_H. M2 |0 H2 u& m% {+ l8 H9 E5 E. B
  432. CLI
    , G8 ?; t3 `+ K, q( X4 Y
  433. ; a  X9 a8 x+ X/ d6 Y( m& K  P
  434. ;关闭PPU控制
    9 R" M2 B- v6 R( C3 d
  435. LDA #$00) Q# q! P2 L- _$ K, B$ y
  436. STA PPU_CTRL" Y8 ~( h/ n; C
  437. . v% G2 {" u. C  a" X, f2 `7 s
  438. ;处理PPU
    % Z! Q$ f# P$ m" v5 M4 M( r
  439. JSR PPU_Process' u$ E$ V3 t  H
  440. " p" ]/ M9 Z. S  ^% @
  441. ;开启PPU控制. H- t  y8 Z# I. n9 \- s
  442. LDA PPU_Ctrl_Buf0 y" m: C" l' A4 o" V4 W
  443. STA PPU_CTRL4 i. Y  I, M! Z# t
  444. 7 G" `9 O3 M. s% n
  445. ;手柄处理( r, m0 M( w7 r6 h4 A5 ~; Q
  446. JSR GamepadProcess3 `  D' s% o. y' Z8 x- X& Q1 w

  447. / O! z& E* M$ e3 {  U# R
  448. LDA #$00
    * i, `  J& R* P
  449. STA IRQ_Index
    9 {+ i' @4 o! Z: E6 i1 h2 o

  450. - M7 M; t6 l, p) i: ~& L
  451. PLA( l/ g+ ?% a, Y) W1 _8 L
  452. TAY
    . Y  R9 p2 Z$ |$ z
  453. PLA7 j0 H5 D; W0 N5 d: V: a, c
  454. TAX. Q  k" W4 z4 X& Y2 g0 d
  455. PLA
    % \" g. F7 h0 Y
  456. RTI* p4 |% u- t/ M( z9 z. t8 w

  457. : j7 o; u* l4 I8 k
  458. ;每行扫描线113.67
    : M# r! j1 @: ?7 p
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    & x& ^( T6 b, c
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 71 U9 t. r+ E& S5 s0 ^2 M) k# ?
  461. ;==================================================
    ( Z" A/ N" b8 u0 g6 n6 e
  462. ;IRQ中断处理8 ~. `1 V: W- b# b9 {: J
  463. IrqProgram
    * m  x+ \% h- Z* U
  464. PHA
    1 A+ f& D; X# V
  465. TXA  h5 ]: Y/ X$ C. y0 C
  466. PHA6 T6 J: t3 H  o+ a
  467. TYA9 E* i3 }( O6 E8 f) F) }
  468. PHA
    / y7 m/ n4 O" U6 {- s6 S

  469. 7 G" Z" G1 d; c6 P' [2 M
  470. ;16条扫描线后触发IRQ) K7 L$ x% n2 Y* e6 K( L  F( E
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    & y) N( `. E8 B7 l/ j. }
  472. STA M19_IRQ_COUNT_L
    8 R+ X! ]$ m9 m' B$ f6 n- u) ~
  473. LDA #HIGH(BEGIN_LINE_CYCLES)/ y1 K7 L  `+ E6 w$ \# l  ^/ j+ Q( q
  474. ORA #$80
    7 @8 T5 j0 J) e. e' F9 a' D6 m
  475. STA M19_IRQ_COUNT_H
    * t# l: ^: N5 V% p. ^( v

  476. 7 V8 D9 X+ Q+ j9 A
  477. LDA <IRQ_Index
    5 v5 C! h0 N" |! M9 X7 w
  478. BNE * + 4, ^3 Y# m9 i8 V" i+ A' g$ b. m$ X# E
  479. INC <PPU_Scroll_H
    : ~% R# p- j) d

  480. + V. ^' X! x7 J+ A3 G  }
  481. ;设置屏幕滚动& M  c! P! G6 I, @- T0 x
  482. LDA <IRQ_Index
    1 s4 ^2 D' Y( l  {' {5 p9 K
  483. AND #$01% ~/ Z; O- t8 ^& L' m
  484. BEQ Irq_Scroll_Right& J5 ^9 `1 w- b: F& Q; ^% u: ^  t
  485.   K2 c4 E' E/ P  a+ x5 H
  486. Irq_Scroll_Left
    ! u4 Q4 z( W# I7 g& \
  487. BIT PPU_STATUS8 z! W+ b6 t# m4 n- `4 W
  488. LDA <PPU_Scroll_H; M& A8 T* f9 E! C9 ~
  489. STA PPU_SCROLL
    9 b& i, A: y; g
  490. STA PPU_SCROLL6 V5 _/ s: c- Z' Z- g" k! @5 b" j
  491. JMP Irq_Scroll_Over
    ( N) q, u0 c/ q) {& G  I8 B
  492. - H8 ?7 H, v1 t3 N5 Y
  493. Irq_Scroll_Right
    * B% r# A' f* {! n/ z* z& q
  494. SEC
    1 t: W0 s, K2 s. W8 `. F
  495. SBC <PPU_Scroll_H, b5 P/ ?: r0 J/ @# }
  496. STA PPU_SCROLL
    ; P4 [* v  x6 C
  497. STA PPU_SCROLL$ }7 N# k* r5 H8 I9 I$ z
  498. Irq_Scroll_Over
    2 y" J; H. k3 J6 {( Z8 Y
  499. 4 O1 d" T, Y; ?: o
  500. INC <IRQ_Index1 {7 `+ k: A3 {. `% `5 e. F- @
  501. 9 R8 s. O$ {# H
  502. LDA <IRQ_Index
    ; S+ D% \( |0 ~3 {/ p# b* Y( e
  503. CMP #14& v& J) G4 y: V3 }  ^# _  F/ E, G' U
  504. BCC * + 10
    9 y  N; l* d# p; t8 ^
  505. LDA #$00
    5 E! F8 ~9 `1 t; i: x. l
  506. STA M19_IRQ_COUNT_L3 C  \6 H* F1 @- f2 ^+ `+ p% o
  507. STA M19_IRQ_COUNT_H# t% q5 w" ]& I& {  o" s
  508. ! t  `! E: R0 h* b
  509. IrqProgramEnd' a8 [1 p: o5 I2 [7 A
  510. PLA
    8 s" H+ }2 u5 g" q- Y+ }! J
  511. TAY
    5 e" M9 M) V$ P
  512. PLA
    ) j8 G5 N/ m6 V* h  B" w6 k7 H
  513. TAX
    # u3 A  @+ {+ W# t( }
  514. PLA
    # s5 g( B" v" P1 y: K/ ]1 U' W0 X
  515. RTI
    8 ]' a% n! W* t

  516. 7 g& f" d* s* J5 Q7 ?8 q9 l, X
  517. ;==================================================: V$ [) E# `5 S! |; c; D
  518. ;中断表
    9 ]- L& Y( Z! o' L# K% @* p, O
  519. .ORG $FFFA
    & q& l5 d! u8 Q% e- Y/ Y7 C
  520. .WORD NmiProgram
    1 d+ N; W% z4 Z5 @& z
  521. .WORD ResetProgram
    . w0 X6 Z* V- I8 G- J/ ~1 c
  522. .WORD IrqProgram
复制代码

0 p' d. C5 X3 M) a

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-2-19 06:48 , Processed in 1.112305 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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