EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    9 S. M* _- u+ j) I6 R3 V
  2. ;FlameCyclone 20230710
    % a1 j$ z2 ?1 ^4 }5 `
  3. & o* i+ p* h, E7 Y6 `& b1 f8 v5 c
  4. ;文件头
    4 P. ]; v- c! F& n
  5. ;======================================================================
    ! ^1 l/ x3 D: \, T  `
  6. .INESPRG 4                                              ;16KB PRG 数量
    3 D$ J0 D. G3 K1 O, x2 P- z
  7. .INESCHR 1                                               ;8KB CHR 数量5 e, O+ C/ x3 j
  8. .INESMAP 19                                                 ;mapper 19: c1 S" W3 F, }) V" F, @: S
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    % K, l. ?9 T& x$ }5 I

  10. + Q6 \- N: C: U$ K- s. n2 v
  11. ;必要条件
    5 A  C0 D* o. E" B$ g; C$ W# C
  12. ;1.持有CHR ROM
    + q% X9 B7 g, j
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    * Q* ~. c' t0 N1 [1 _* F  t& v$ I! w
  14. ;3.精灵内存(OAM)不为空
    # e' C- M7 @& u- G9 ?# ^: e
  15. + Y  ?6 P. S, d- k- j" f
  16. ;==================================================
    ) W3 j" t' `# X3 U/ o
  17. ;NES端口常量
    / S" V: c( ^+ o) P3 R. @) t' b1 K
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    " Z; o! \+ O( l+ |1 o
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ' o$ Y' G/ a$ X  o0 n
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位4 z" L) }: t; U7 X1 |
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加15 D) ?. R: {- V) H! b
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1$ `  Z: ?! A8 W. s7 D/ I5 z/ L
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ( _# _& F& @' `/ {# g# ~  p# T
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    0 [9 z% y+ d: y" k/ l  E
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    4 q/ _! x0 i4 Y& [( w/ |! L+ r
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存; u6 D. ?6 r7 Q1 D- K' j; k7 [
  27. APU_STATUS              =   $4015   ;声音通道切换1 G& `9 |2 c' B
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    " h! o+ d0 ^- ?+ _# ]: x8 {
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    0 H+ [7 [$ Z( }$ l; W1 C0 ^6 ~
  30. / d1 ]/ ~1 a! ]2 L
  31. ;==================================================+ F% S9 X" _3 F. f* e
  32. ;MAPPER 19端口常量
    # B' V: g/ }, y9 o0 U! q8 C
  33. M19_CHR_0000    =   $8000
    $ }; `% f! l, Z+ |0 o; R8 Z
  34. M19_CHR_0400    =   $88002 X+ c3 _' a' C9 o* A
  35. M19_CHR_0800    =   $9000
    . F- o+ B9 O9 l
  36. M19_CHR_0C00    =   $98008 }( d  _' V2 m% V, ?0 @& b
  37. M19_CHR_1000    =   $A000
    : @' p6 c* l! C1 q" P
  38. M19_CHR_1400    =   $A800
    / F0 y! p  K+ U0 R( R
  39. M19_CHR_1800    =   $B000' w/ A! U5 m+ ]& R7 K
  40. M19_CHR_1C00    =   $B8009 k% w& q' h  u4 f
  41. M19_NT_2000     =   $C000
      h( d2 N+ x; M9 O3 }; J
  42. M19_NT_2400     =   $C800
    + H  f- y! l6 B  F6 n9 v# e2 m
  43. M19_NT_2800     =   $D000+ j" W% ^3 x3 ?/ ^) V# P
  44. M19_NT_2C00     =   $D800$ E6 }) L+ r  G+ ^: g
  45. M19_PRG_8000    =   $E000
    - l! c' D( `, t2 b
  46. M19_PRG_A000    =   $E800# e1 u: [6 y1 R  M
  47. M19_PRG_C000    =   $F000+ e3 S7 I+ ?/ [. p
  48. M19_IRQ_COUNT_L =   $5000
    2 j6 }0 w5 t! _% d0 v+ ^3 x4 X
  49. M19_IRQ_COUNT_H =   $5800
    + S! ^( q0 z0 J8 U
  50. 5 ]' e, l, s& e+ J# x
  51. ;==================================================
    + {! X! E* q9 n& d$ _
  52. ;程序块配置' p* {# T% k& w6 R0 N9 c# J( J
  53. BANK_DATA_MASK          = $074 V6 q0 n1 H5 A( _/ f
  54. ;--------------------------------------------------
    ' F5 G& Y9 z& V: K+ b$ N
  55. RESET_BANK              = $07
    ( S/ h0 p+ f2 T* H4 J& z
  56. RESET_ADDR              = $FC00
    ) g% y: t: [' A; p7 _- c5 F$ J7 {

  57.   l/ f% ^7 Y& ]
  58. ;==================================================
    % S+ n: q, @! Y3 e) [
  59. ;图像块配置
    % ]5 a9 ~, R7 Z# M% E' R# O
  60. CHR_DATA_BANK           = $08" E& A8 B4 S. j$ u

  61. . }6 v9 K8 _0 r, l3 ?9 i
  62. ;==================================================
    " R1 u; M7 M% G
  63. ;零页内存地址配置5 t9 [) d  i0 m- C( C( d" t
  64. Use_Ram_Addr            = $80
    " P% V( @; l$ k  o) a* q) w
  65. PPU_Ctrl_Buf            = Use_Ram_Addr4 E( U8 x$ J: {
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01' \' C! D/ y( J2 V8 u5 @5 A: L
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01& `5 f" U; j. c0 _/ X1 ~4 n
  68. PPU_Scroll_V            = PPU_Scroll_H + $01! t: N4 B7 ~/ Y2 A+ K. r/ ^$ M
  69. FC_Data_L               = PPU_Scroll_V + $01# J2 n1 v7 u4 C$ E* D! \" \3 o
  70. FC_Data_H               = FC_Data_L + $014 P" f1 ]$ w$ }3 c: ]
  71. FC_Data_Buf             = FC_Data_H + $01
    % D! c9 g; Z0 N9 q
  72. ;==================================================
      l+ O0 P- r( t6 }# o

  73. 3 a2 K. o/ m2 F8 `  c7 f1 s2 ]
  74. GAMEPAD_MERGE_FLAG = $04& g! r0 j( Y3 k  ]
  75. ! d. H4 e! q: p; n5 h* G
  76. Gamepad_Keep            =       FC_Data_Buf + 14 F. L0 x: Q% y8 G- J
  77. Gamepad_Once            =       Gamepad_Keep + 2
    9 y4 m6 |8 L  L- c
  78. Gamepad_Temp            =       Gamepad_Once + 2
    * z  c9 V. s8 I! a6 ^
  79.                                 0 Z8 ?9 g1 z, d* t
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    0 T" I, b1 k+ \& G6 j( g# U
  81. Gamepad_1_State         =       Gamepad_0_State + 11 i8 B4 S3 W1 ^' t8 ]4 h
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    2 G$ O6 R5 A- q- D% g/ U' _/ C( G! F
  83. Gamepad_1_Value         =       Gamepad_0_Value + 13 Q% w5 q; z, K3 @) P) o' V/ ^
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    / @( g% s9 M. x3 Y( @2 N4 Y
  85. Gamepad_Merge           =       Gamepad_Port_Value + 19 I! T1 y4 H; g8 b0 A

  86. ! H3 m* y0 _0 u& f3 r
  87. ;==================================================5 s/ z9 t1 v( r7 b# D1 I
  88. IRQ_Index               =       Gamepad_Merge + $01
    ( H* K( s3 O1 M5 {( O1 e
  89. ;==================================================. j# t1 D4 F' w- h' E( X
  90. * E3 F) X2 f* j
  91. ;CHR图形数据' R% M( f) M1 i5 P$ Q. x& ~
  92. ;==================================================$ {2 w9 a2 Y8 y+ `/ H
  93. .BANK CHR_DATA_BANK
    . R( ^! T) G0 m5 ]
  94. .INCBIN "chr_bank/chr_data.chr"
    1 k( M/ `, A" ]6 @* x; g
  95. * ^) I: d5 y5 o) p, @
  96. .BANK RESET_BANK & BANK_DATA_MASK
    ( J9 W8 `! C( Q! d+ U
  97. .ORG RESET_ADDR
    % m0 p5 z: Z) j' T, G9 {0 F
  98. / s' \! s4 b+ x4 `- R8 {5 I
  99. ;--------------------------------------------------1 U& o! _0 Z  c( Q) N
  100. Attributes_Data; h) Y! f+ o' _" u% \
  101. ;命名表属性
    - D% @% f! Z" p- A$ N0 H  B) H
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00" H+ k3 E* G$ u" O
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    5 M( G, Z5 Z! m1 ^/ m- V
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA& G( U9 [7 R7 z4 ]6 u  f# h
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    7 Z; V: l  m( b& l) I
  106. ;--------------------------------------------------" W0 ]8 C1 y% h8 |7 S" x
  107. ;调色板数据" S5 y" j( @$ @) y7 _
  108. Palette_Data8 H5 w6 S% Z4 d
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    . [' z* z& U( `9 p' c9 S$ N
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    9 _, @$ O' p7 S

  111. " `' P5 ]% v3 @* o, M
  112. ;==================================================
    5 Z1 f& B$ A+ Z7 u
  113. ;命名表初始化
    1 \5 r$ h4 w1 }3 J
  114. Init_Name_Table, T/ n5 }& o# s2 m3 l  q
  115. LDA #$20$ ?2 z% I) |) I
  116. STA PPU_ADDRESS
      I  l# w0 D0 k# d6 O
  117. LDA #$00
    ( X) r1 }4 C0 J, z8 P3 d' |
  118. STA PPU_ADDRESS
    7 B% v) y$ U/ \- |
  119. LDA #$008 n0 n5 R! f  f; Z; U
  120. LDY #$00
    ! u/ w8 F) R* {2 H( E1 W( @
  121. LDX #$10
    " q: f# Q0 S" H0 I$ U* g
  122. Init_Name_Table_Write& C, }- t/ X; {, }* T
  123. STA PPU_DATA0 V! o/ ~7 {! o
  124. INY
    6 c) G5 @9 }0 S  k: Q" ^
  125. BNE Init_Name_Table_Write  R6 F9 W5 H; S
  126. DEX
    , \& X1 @3 f# b& g! R. }
  127. BNE Init_Name_Table_Write7 _& o9 p$ Q9 q: D2 P+ H
  128. RTS
    # d0 O5 J2 ?0 {! Q/ _! \* n, ]

  129. 1 u  \) w) V- B8 j
  130. ;==================================================2 d7 q2 A& |! u0 `: k9 A$ v# Z
  131. ;调色板初始化
    + k3 {& D+ ?0 c! g* _3 i
  132. Init_Palette
    % x0 R* Q. {8 X2 |% ?7 }
  133. BIT PPU_STATUS
    - a* M2 v( x: v8 v9 a
  134. LDA #$3F& S5 X9 ]& N+ |" X+ o4 w4 q. G
  135. STA PPU_ADDRESS( J: s/ c$ |2 w" X& {
  136. LDA #$00
    4 O0 J4 ]: G  O- F* h8 i1 Z$ l
  137. STA PPU_ADDRESS
    % t  H2 d8 E4 T) y' O% q
  138. LDX #$00
    + P5 M0 q4 f, w% n! O$ w
  139. Init_Palette_Write2 Z' v# c5 z/ e" F# [+ ?( T
  140. LDA Palette_Data,X
    ! D6 e- h3 H: R  V$ _
  141. STA PPU_DATA
    # Y) o/ j' o" a1 L  I
  142. INX
    9 M- W  s; C) B: T. L, K) ]
  143. CPX #$20
    $ d1 P8 b& C6 k
  144. BCC Init_Palette_Write/ B8 i+ ]- e9 F" f
  145. RTS% }& n) C8 T; M0 I8 ]! H6 D
  146. 8 z* q$ N3 e; V1 n1 g0 v
  147. ;==================================================& B7 K2 h2 X4 M$ K) @
  148. ;设置命名表属性7 B; s2 Y) a7 L
  149. Init_NameTable_Attributes
    " {. j, _4 T7 I! @8 x
  150. BIT PPU_STATUS1 h7 {9 N' ^) F4 e. P0 u2 m
  151. LDA #$23
    " A' F: M; C/ ^' P& r2 z
  152. STA PPU_ADDRESS
    : v6 n! d+ W* c* W; \' S
  153. LDA #$C0
    ! i+ Y& y" Y7 ]- g
  154. STA PPU_ADDRESS4 V; A5 U9 c: l6 f' h
  155. LDX #$00
    ' T8 D9 U6 u% W
  156. Init_NameTable_Attributes_Write
    - p' D! R: m, W% e5 @7 c+ a
  157. LDA Attributes_Data,X
    3 i" l: e  f; ^7 |9 b2 m7 `" H- u
  158. STA PPU_DATA
    ) R. H% N; G9 ]& j) S, X* n
  159. INX$ V3 ^3 |+ z3 G7 A: r
  160. CPX #$40
    0 @( q! w: ]9 s$ x# f. Q
  161. BCC Init_NameTable_Attributes_Write- f% m2 I# q( V8 Y& J( `
  162. RTS+ Q3 _, x, M, E- j" @
  163. ) t/ @' N& i8 \& P  v
  164. ;==================================================: v5 s; u4 s/ l7 X8 p( }% @
  165. ;初始化命名表文本
    ' Y% S6 _0 f0 R% Y; v- f
  166. Init_Name_Table_Text
    5 F! h% ~4 H7 g- S* ~& I
  167. BIT PPU_STATUS* V& ?; P# b3 Z1 e8 f) q
  168. LDA #$20# H+ P% P# i# o, A
  169. STA PPU_ADDRESS
    6 T) E# A% S  I. O8 Q
  170. LDA #$00% W$ R; d3 J; Z
  171. STA PPU_ADDRESS- K( ^. S! f! ~. e
  172. LDA #$00
    , t: ~" E: E; m
  173. STA FC_Data_Buf- ^* h' i$ V, l; k/ `
  174. LDY #30
    - b- n& U  v6 E+ [6 H& o1 U
  175. Init_Name_Table_Text_Write
    ) ?) g6 M: U& o. E: k
  176. LDX #32* N+ T7 ~8 r, Q- `1 r7 J, u
  177. Init_Name_Table_Text_Write_Char; v$ u3 }$ U6 R1 v  a3 K
  178. LDA #'0'% w4 }4 @- k, s5 g
  179. CLC
    * L, o. B6 `, F+ ?+ N
  180. ADC FC_Data_Buf& ~9 K2 M/ n+ S' H. d; @2 m1 w. E
  181. STA PPU_DATA* S: @: l3 }# E' {. a
  182. DEX
    * X1 O' \/ M9 m6 ]% H$ W$ T
  183. LDA #$14
    ! e# W# ?+ V' e  M1 x
  184. STA PPU_DATA
    % M; F; E- |( W
  185. DEX% M/ T' F) B* E0 C$ I
  186. BNE Init_Name_Table_Text_Write_Char3 K$ o+ ?4 Q  K+ w
  187. INC FC_Data_Buf
    ' P/ G+ _; `5 p" @/ v/ ^
  188. DEY( T7 l  l8 |  S- S& x% R
  189. BNE Init_Name_Table_Text_Write/ {6 T: X7 y- L; f  Y+ i
  190. RTS
    5 H/ }3 Y; n% B

  191. ' i- U% _( s: Q
  192. ;==============================9 e! b/ g9 o8 [
  193. Init_OAM_Ram;初始化精灵内存
    ( L1 |! Q7 `. t
  194. LDX #$00
    9 Q% o, o4 S+ z3 t: }  ?
  195. LDA #$00' B: v' V+ r  [
  196. STA PPU_OAM_ADDR+ C: h& \9 {+ E/ y$ C0 ?  u
  197. LDA #$F8
    ; z& H  s  n  [9 ]' v, M& l; C$ K
  198. Init_OAM_Ram_Write
    1 \" N/ R+ Z! ?* s+ V" @
  199. STA PPU_OAM_DATA8 }" Y# i# A4 f
  200. INX
    ' a+ [% a" e# A1 g, k) y
  201. BNE Init_OAM_Ram_Write
    3 V" D# ~# Q4 w* a4 q
  202. RTS2 E% i* q, w0 h
  203. ! X) p9 I! o5 z0 h8 ^  t
  204. GamepadProcess;手柄处理& u& I" K4 O: Z" ?) f
  205. JSR GamepadDatacan
    ' J+ H1 H! d6 l2 d$ `
  206. LDA <Gamepad_0_Value+ c7 g- B* P: H2 j' ]
  207. STA <Gamepad_0_State
    5 r! G: ]: V; z( Z+ ~# Q
  208. LDA <Gamepad_1_Value
    $ t1 {5 m+ u% D& ^0 W: Z
  209. STA <Gamepad_1_State
    ( Z8 R. Z  o) M
  210. JSR GamepadDatacan; Q- y$ i) w; L0 R0 o- |. ?- m
  211. LDX #$012 V/ n( ]  }$ {$ f! |7 }
  212. GamepadMergeCheck;合并手柄输入检查- A8 b" @& j! @; ~  ]6 `. D% c  M
  213. LDA <Gamepad_0_Value,X
    # F" M. c; `' m! a% V
  214. CMP <Gamepad_0_State,X
    . s9 B) F# k# t- M
  215. BEQ GamepadMergeInput
    4 U$ c4 ]& A% S/ Z" |: m  t* T# U
  216. LDA <Gamepad_Temp,X* U0 K# t1 `* M
  217. STA <Gamepad_0_Value,X$ E. ^1 m( w5 {& n5 g& m
  218. GamepadMergeInput;合并手柄输入
    $ x( N; x# v; j3 x+ \. d% D0 g
  219. DEX+ h& ]2 B' @" I: O
  220. BPL GamepadMergeCheck
    ) [, r! H7 e& G! {  X) |2 W! g
  221. LDA <Gamepad_Merge) v5 E" F9 _  m
  222. AND #GAMEPAD_MERGE_FLAG0 i: X  _& o! t, L8 ^
  223. BNE GamepadStateProcess3 g& y. ?) _$ {3 {
  224. LDA <Gamepad_0_Value5 D% w9 G9 L6 X6 p( {: V, s' e
  225. ORA <Gamepad_1_Value, y& m% }- u8 d+ u9 [
  226. STA <Gamepad_0_Value: ~: G, H' j- Z" J2 y- t
  227. GamepadStateProcess;手柄状态处理
    5 ~5 C/ y/ A4 {- a% ^) W
  228. LDX #$01- c! P. G' s5 p8 j8 U
  229. GamepadStateSave;手柄状态保存( u. t1 v( l6 H& t7 ]
  230. LDA <Gamepad_0_Value,X3 @9 o* s  Q! r0 Y4 q
  231. TAY
    5 t8 N4 y; E# M, J
  232. EOR <Gamepad_Temp,X7 J( N* v3 v2 Q  |* r2 U
  233. AND <Gamepad_0_Value,X$ _$ |6 l. J$ C: Z
  234. STA <Gamepad_Once,X" `. z7 `) e$ ?" D0 N
  235. STY <Gamepad_Keep,X6 v5 V) @0 Q6 z3 }
  236. STY <Gamepad_Temp,X1 o! c/ o. y, f- T, R
  237. DEX
    1 ]& l3 J( c+ B. j+ f4 ^
  238. BPL GamepadStateSave
    . r  }4 z5 s: {$ M+ A! {" X$ X
  239. RTS
    " ]- U* h$ M, _' |
  240. " ?8 d& T: m9 p* l: V1 M" u
  241. GamepadDatacan;手柄数据扫描& G* X1 y2 t; I, T% T7 J
  242. LDX #$01
    + N3 f. S* A& R4 l* C$ ]$ Y- J
  243. STX $4016
    : N. w3 ]% o, a3 R! Q% W
  244. DEX, C  T$ l+ E- U1 V% C
  245. STX $40165 E% G9 e# \5 e" M
  246. LDY #$08
    1 @( P' K. l0 p% Y! e9 f& u7 C
  247. GamepadPortScan;手柄端口扫描7 y* Z5 ]2 o+ |- s
  248. LDA $4016* L( n# `2 [/ ]. n! e+ r$ {, t
  249. STA <Gamepad_Port_Value5 b8 N8 G" O0 b& {! R5 u
  250. LSR A6 |. a3 e9 I1 R, t7 O& `3 S& G
  251. ORA <Gamepad_Port_Value
    " c5 [2 j4 d0 w, @" {% z% L
  252. LSR A7 W: S  r, ]! M! f" m7 G
  253. ROL <Gamepad_0_Value
    + U. s$ n4 P3 ]9 ~+ S
  254. LDA $4017
    ' _2 o, Y& Y1 `" i) i) _9 p- [
  255. STA <Gamepad_Port_Value
    $ K1 F$ p5 m( D, W$ D8 t/ K
  256. LSR A& I7 g; p( g; E3 L+ }
  257. ORA <Gamepad_Port_Value
    % P# A2 ]+ k% H. @
  258. LSR A
      [) T7 Y: S( `- b% t- @4 j8 t
  259. ROL <Gamepad_1_Value
    & M+ W. z7 h5 j
  260. DEY! v' g6 a# P+ ]  i1 `
  261. BNE GamepadPortScan
    2 Q2 \1 Q" j0 M8 {* Q& s
  262. RTS" _$ H4 T5 m6 [3 C2 B
  263. 4 S; g" W0 ^! D
  264. ;==================================================9 w+ d! h) ^( ?" K, O
  265. ;PPU处理
    " m5 ?: Y" u* W, z3 `+ d0 u& N
  266. PPU_Process
    - ^, _: R8 N$ e  c) z- e9 |
  267. LDA #$00
    8 W8 Z( _# U  ?; K/ p
  268. STA PPU_MASK
    ( i7 `  `! \, h( x8 W

  269. 8 f1 F/ I. S: a8 E& o
  270. BIT PPU_STATUS
    9 F+ r/ N, J1 J9 R* N& F' K. C1 ?
  271. LDA #$20
    6 j% [# z5 ^, [- F# ^' B- M$ X/ Y
  272. STA PPU_ADDRESS1 R7 d# n' y1 c
  273. LDA #$00
    * b% F( M5 w' K) n' P
  274. STA PPU_ADDRESS$ I+ x5 k7 O2 m7 d3 S+ l

  275. 4 r0 T( x3 K5 c6 c+ v  D
  276. STA PPU_SCROLL/ _8 C  e, J/ F0 E7 c4 v
  277. STA PPU_SCROLL
    3 W# s5 Y# R  b  z8 a% L  R  E

  278. 5 K8 N5 N, D" g/ J) {+ M# T1 A) |
  279. LDA PPU_Msak_Buf  e# P9 V( B! M! \2 c
  280. STA PPU_MASK
    " }2 m( Y) h7 c( t9 t8 ~& a$ f

  281. ; R7 z3 i5 i% y3 T1 I. @1 f
  282. RTS
    % R4 }# a! @9 m& \" x

  283. * H' b" I7 j/ d* a8 m, @1 Z
  284. ;==============================
    2 V# k3 H8 i6 ~8 W8 ]
  285. Time_For_Vblank;延时等待  J( U4 Z3 d( k  }5 H" ?0 k8 d( j
  286. LDA PPU_STATUS
    , q# r% w6 d- k
  287. BPL Time_For_Vblank
      d/ |, k! j( X4 i
  288. RTS( N, `1 k* ]: M0 ?* g" A# ?2 v2 ~8 B

  289. - {0 k. ~) ^2 l4 ^3 ?7 [
  290. ;==============================
    7 k! g7 k1 l/ o4 h! `' H" Y4 v
  291. ;初始化MAPPER19& x; R1 _& H' j( \* K
  292. Init_Mapper19# Q- e- N1 n6 F9 W( R
  293. LDA #$000 P5 u  N: d, M9 A. h9 S
  294. STA M19_CHR_0000
    " o% S8 |  j! _/ g. s
  295. LDA #$01  J& l) j" d$ ^
  296. STA M19_CHR_04003 m( L7 N. i9 x, g9 F1 U0 e. i
  297. LDA #$02* B3 @6 t9 g: G4 y' v/ b" x8 G
  298. STA M19_CHR_08004 D& q" F$ \$ ]9 e2 F* k- g* v  {
  299. LDA #$03
    % E" g' T8 A8 ]3 d7 j
  300. STA M19_CHR_0C00/ Y0 ^2 E4 R4 p# H( m' p9 j+ e
  301. LDA #$04
    & ~2 A& g) Y) |8 d. u
  302. STA M19_CHR_1000
    ( j2 F; {" l+ y: a1 n4 n
  303. LDA #$05
    / C+ N9 |& a# a( b9 k8 c. l
  304. STA M19_CHR_1400( _. t& K! N0 m, T% [5 J
  305. LDA #$06
    3 Z& l, b4 s1 |  r) z$ E
  306. STA M19_CHR_1800
    5 G9 l+ b1 }5 B
  307. LDA #$07( q; K0 |! a( t6 Z  J
  308. STA M19_CHR_1C00
    4 y' U# w4 m  e$ u, A3 z$ E
  309. - n& u0 k4 V' d" V& y. g7 q" b
  310. ;禁用IRQ$ E1 }6 L% U9 p6 U4 C4 E
  311. LDA M19_IRQ_COUNT_H7 u2 n. f( G4 G- H
  312. AND #$7F$ E+ c8 V+ r, p
  313. STA M19_IRQ_COUNT_H
    . ~/ A3 j- g3 b6 T$ j

  314. 4 _% G3 X% k- a# D
  315. ;命名表* ?" z, L1 t* D' p, h' r% S+ O
  316. LDA #$E0
    4 p; s6 `6 M+ f* C, J0 c; Z; S8 b* {
  317. STA M19_NT_2000! v6 y' g+ t& ^) J: t
  318. STA M19_NT_2400) o0 W2 e9 d, e; V# U, I3 W
  319. 3 O$ K+ D8 i# h" S1 K2 O
  320. ;命名表
    ) P5 R9 J8 D/ z  S/ p4 ^8 g
  321. LDA #$E1' C9 D4 P/ q6 C- K% y# H2 q
  322. STA M19_NT_2800
    9 T7 S# X: w* c7 x7 K* o1 E7 u# j
  323. STA M19_NT_2C00) _8 N5 y3 Z8 N7 e2 m0 n* }

  324. 7 d0 @: c+ i8 w- x2 l1 O6 Y! {; {
  325. RTS
    2 h$ P- U8 j7 X! i5 `

  326. * X% x* f+ f7 O/ B, s
  327. ;==================================================% x# z1 \/ e! B4 x
  328. ;重置中断处理
    / n8 {; g" y, A9 B2 a
  329. ResetProgram* k7 w! w5 O0 D1 m/ `
  330. SEI* M7 P* \! x3 @. P: G2 G6 f
  331. CLD
    : B. U4 f) I% i+ Z
  332. LDA #$00
    $ t2 r* t4 P$ }9 c! Z' Q' e
  333. STA PPU_CTRL
      F7 `2 T6 |$ T
  334. STA PPU_MASK
    0 m; O+ v1 E2 Q/ Y& ]% d" C6 W) w
  335. STA PPU_STATUS& b- Z8 }3 N5 l" \( m
  336. STA JOY2_FRAME
    , v$ v# l) ^2 c: W- r/ }9 m  _2 X4 O
  337. STA APU_STATUS
    ! F, ~  }2 G2 p3 v# T! `
  338. # m3 R; V: \. Q) P% J
  339. LDA #$C0
    + S- S; }! ~: v
  340. STA JOY2_FRAME
    2 r. e; b$ Q  D, M6 N/ T

  341. / s% G' r0 V, Z7 p& U8 j
  342. ;等待vblank
    9 ?, r% M( t& `/ s
  343. LDX #$021 d3 A8 H: |  X  `
  344. Vblank_Wait_18 z% Y/ \1 f: x
  345. BIT PPU_STATUS6 f% z4 y( f! {2 ^0 `3 |) v# N
  346. BPL Vblank_Wait_1
    6 ^9 }* d: Z0 ^# w5 G( l
  347. Vblank_Wait_2
    1 \" J+ x7 U. L3 V, k/ \
  348. BIT PPU_STATUS' ~: k6 j0 D6 p3 ?
  349. BMI Vblank_Wait_2% E9 {. e6 [4 x7 x
  350. DEX
    5 e, \- L+ l. W8 W8 b5 w  z
  351. BNE Vblank_Wait_1+ a5 t) f! q9 n; V$ i  Z+ L
  352. ' w( \3 z* r9 R2 `( h
  353. LDX #$FF
    ) c5 T" @3 N3 m5 c# S$ D1 V
  354. TXS
    # J. M3 D8 C0 {4 L+ {* M
  355. # b) I9 z6 ~4 n8 y
  356. ;初始化MAPPER191 ?* H/ I8 _5 Q, c
  357. JSR Init_Mapper19
    . A# R9 ?* \9 D4 A9 e1 w! _

  358. $ e# V9 [! `- S( r3 r: {5 Q5 E
  359. ;==============================, t7 y+ r6 R( t, A) z
  360. ;RAM初始化) q+ l1 }" {3 i0 J6 [
  361. Nes_Ram_Init$ n4 I- X! ~2 U% [7 m
  362. LDY #$00
    ' Y! X0 v  b5 d. j0 u; @
  363. LDX #$087 |  I  }4 l& }' |, U: C
  364. LDA #$00; p  U4 T! `. ?' T, x3 Y
  365. STA <$00
    2 s# z6 v: N2 I/ l/ _& l! w
  366. STA <$01  y8 v7 v1 N2 s+ _, [
  367. Nes_Ram_Init_Write* T9 t: M( L7 Q, }; E9 _
  368. STA [$00],Y
    # s& K2 t+ {# g+ Y& I- [. h8 u3 `, |
  369. INY' f( r4 q+ z$ b8 ?  _1 Q: T: Q
  370. BNE Nes_Ram_Init_Write
    6 S7 d' l7 B) V6 D  o
  371. INC <$01* f' O+ V8 [0 C( P
  372. DEX% E/ P! ^; V# v
  373. BNE Nes_Ram_Init_Write
    * T) d; d6 W2 M: A! M6 T3 f
  374. & `( @  V% l) m  N1 S
  375. ;初始化命名表
    9 x2 o" F$ ~  w$ t" k
  376. JSR Init_Name_Table
    $ [( _: w1 k: Z
  377. 8 ~( }1 b4 x/ ~8 o
  378. ;初始化调色板
    * a! P. |% D: J% M4 G
  379. JSR Init_Palette
    ! Y+ M8 p9 ^- R+ X

  380.   Q2 R% I# g7 \1 N
  381. ;初始化命名表属性
    9 P% R- v# K8 }
  382. JSR Init_NameTable_Attributes" U4 r$ @' d% ^9 [, ^  o

  383. 8 K9 X6 `- z6 ^6 Z
  384. ;初始化精灵内存  w. U! D5 B8 k- Z; y7 x- h
  385. JSR Init_OAM_Ram
    5 @2 t6 L9 j- q, |! Z+ }  G/ f

  386. # u5 j% p, o: G4 H
  387. ;在屏幕上写点东西( V* u* U/ q0 N+ y/ W  l% E6 [
  388. JSR Init_Name_Table_Text0 U9 F  M9 O" n% R4 f

  389. 7 i) Y! f3 P1 q' c8 x! K
  390. JSR Time_For_Vblank
    2 C% k5 y9 {% X( W. `
  391. ;开启PPU控制& }* }1 [' a: M* I
  392. LDA #$A8
    2 s8 X7 [9 w; C/ W! q9 ?( _- R
  393. STA PPU_Ctrl_Buf  Q. h* e4 F7 x1 z7 H* P/ X
  394. STA PPU_CTRL5 D0 z6 p5 N% J: Q1 x7 P
  395. 9 {/ b1 l1 ^/ V9 i
  396. ;开启PPU显示
    2 t+ \+ y* W9 B" k; c8 _/ Y
  397. LDA #$1E
    / s6 l, L, g: o* X1 G% {1 d; M" L/ \
  398. STA PPU_Msak_Buf
    ' }# a6 j0 r$ j! }; f3 Q

  399. " l# D# _9 \) M( V! Q- ]* x  ]
  400. CLI. }; y2 g: u8 j) D* E" g5 Y
  401. JMP Loop
    3 t- C' g3 v1 O/ e9 y' e9 W
  402. 7 W/ R4 L% o* l
  403. ;==============================
    . }: d, H. q) `# R& J( \& N) G6 }
  404. ;死循环, 等待NMI中断
    $ o4 t* v7 a# g; X8 a0 t
  405. Loop6 M( [9 }3 Q1 h/ O  m, X) E0 L
  406. JMP Loop
    - K/ |5 ~& X! a
  407.   I0 Y- M1 H9 J( ^
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9676 F; i# z7 o  n
  409. ' G* y7 }8 M8 D! @1 c
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)  w. x2 |  A6 x8 s% H" Z6 d
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    8 l  L1 @% q' H) _  s5 ?6 ~1 `
  412. ;==================================================3 H/ ^% [. Y: K4 S0 P
  413. ;NMI中断处理
    + e' o6 a; P6 Q6 F* k: v
  414. NmiProgram
    & b% |+ Z# O( W) \% S* C
  415. PHA# o! x$ c4 P: H4 @' X( v4 }) X
  416. TXA& p/ |, g2 G5 E0 V" K- h! b  e* c
  417. PHA
    6 m+ z5 B0 z$ c& M
  418. TYA* v# U% G* Y0 V1 e) e: a- z
  419. PHA! ^" Q! b1 l: S) v( q
  420. ; @: z7 b7 L5 ~3 z' @( j
  421. BIT PPU_STATUS( e5 ]. k; u, k/ k4 d* N+ E

  422. ) }% C. j0 W. T7 q! O
  423. LDA #$006 ~$ I0 V! |+ L# O1 t4 j! _) A. ?
  424. STA IRQ_Index
    2 Z/ X6 _9 \/ J9 n% J/ f

  425. . E  `9 z7 B' P6 o5 N1 O
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    8 K) \' u5 d( \- F
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)  g* ~. o$ s, ^1 _
  428. STA M19_IRQ_COUNT_L4 @* E' j" g* R
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)3 z7 c$ `2 }1 a8 z. p
  430. ORA #$803 h  |& a. x6 a. \# P2 c' w
  431. STA M19_IRQ_COUNT_H
    & ]$ ^! q1 y( L; e
  432. CLI" o0 D& q* F$ V1 O

  433. ( s* O) Z4 y6 _1 c
  434. ;关闭PPU控制
    0 t. ^5 e, c' c1 q% B4 W
  435. LDA #$001 j# r- ~; e& ?- X9 [
  436. STA PPU_CTRL
    . B* h7 L5 ?9 v. T' n
  437. ' A8 w& u0 Z2 I
  438. ;处理PPU
    5 j" Q6 b+ r* W  T/ y( ]5 z
  439. JSR PPU_Process; d  p* L* w. X# v" t" X; }9 D
  440. $ R( k8 C8 R) j
  441. ;开启PPU控制/ A) G$ a% _$ p& Q  ^
  442. LDA PPU_Ctrl_Buf
    3 u  C7 T) W$ G" H7 P
  443. STA PPU_CTRL
    1 ~) q9 _7 G8 H

  444. 3 r( E  L. D. U0 g% h, l
  445. ;手柄处理6 S+ Q; K; P5 l3 e! @
  446. JSR GamepadProcess
    % t. V4 f1 v- O, x! g! y' d
  447. % }& r1 O4 y* o
  448. LDA #$00
    . N! {: D9 c  [* {0 d+ p8 a
  449. STA IRQ_Index
    ( h/ {4 M0 G$ i$ F

  450. " t7 Y8 x$ F8 q' y5 g: n5 E( ^! @. n
  451. PLA, c! o  ^3 p2 \! W8 |3 V1 P
  452. TAY
    ( A; c# y$ P/ {# k9 R
  453. PLA% z/ o6 H! G* G5 i
  454. TAX
    9 R' w8 }8 T4 c  r, x5 M4 K6 R
  455. PLA- d: U$ B! V5 ], ^" x
  456. RTI
    / k- N. |& W6 ^9 {9 t" a

  457. $ Z* A0 C0 n" H/ `, y, |* ?& B
  458. ;每行扫描线113.67% a* `$ u% l; r% U3 o0 y
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    5 W2 [6 v1 Y  K; K
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7* z# V) V! i7 \, q) u3 F& A
  461. ;==================================================# ~( e- p# |- u9 e/ [2 `
  462. ;IRQ中断处理) I) U! t9 W, p5 L' ]: v* g
  463. IrqProgram
    $ J8 V* t" h$ @/ R  S  j
  464. PHA
    6 M* d/ T' q' y1 |
  465. TXA$ ]) |  S/ |# _0 ]! E; S
  466. PHA
    9 e* k$ s+ |% u% r6 h3 }
  467. TYA. b7 q  _! q/ h1 I# I4 Q7 A- T
  468. PHA
    2 d! y* R" a9 g" T0 {& Y+ y0 G

  469. / `, |% i. I5 `: K4 d) _" ?1 t
  470. ;16条扫描线后触发IRQ
    6 B  z  @8 E. S" c. ]3 j' e
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    7 s4 ?8 B& I4 W; s
  472. STA M19_IRQ_COUNT_L
    + v+ s( f. E# @, R0 {. W% H
  473. LDA #HIGH(BEGIN_LINE_CYCLES)  ^, T1 K0 L5 B' L1 T) m
  474. ORA #$80% x# Z+ o3 R* V* a, M# [
  475. STA M19_IRQ_COUNT_H
    3 b# Y0 @0 }" F8 ?  b

  476. : f% c# m3 s* |5 D' k
  477. LDA <IRQ_Index
    / q' O0 _# V" G
  478. BNE * + 4
    3 d7 B  V% N# `- ]7 I
  479. INC <PPU_Scroll_H9 @1 u: y- V7 J9 {3 j8 ]

  480. + p& e; |( r3 l% s
  481. ;设置屏幕滚动# a& c+ b1 @' W- D* O
  482. LDA <IRQ_Index
    : F$ Q" o  D, o6 R7 z
  483. AND #$01
    * q' a! R1 c5 h" Z7 J
  484. BEQ Irq_Scroll_Right
    ( D* i/ }/ J' E7 Q

  485. ) O/ X5 L; P8 A* t) Q; \6 L
  486. Irq_Scroll_Left& x0 j- q! w/ s5 y/ F$ i! j
  487. BIT PPU_STATUS  k: U8 Y& J. p9 l
  488. LDA <PPU_Scroll_H
    4 Y+ X8 e, c: V& y, p2 ]
  489. STA PPU_SCROLL. T2 |( \. G" A4 \, B
  490. STA PPU_SCROLL
    5 }% V% W! c, B- B1 e7 ?% {
  491. JMP Irq_Scroll_Over- \# |: g2 B, y! y; {. H
  492. $ c  r6 C& S9 {0 @2 A+ v6 V
  493. Irq_Scroll_Right7 o2 G8 @  L' E( j+ h# Y, y9 X
  494. SEC: [8 r3 Z) ~- F/ q, k3 \: \. W
  495. SBC <PPU_Scroll_H
    ) o7 y* q& E+ t1 {( S- S$ `9 [6 ^
  496. STA PPU_SCROLL
    ) D- q0 c! b9 Z' q
  497. STA PPU_SCROLL& l0 ]+ z, A& ]/ a6 ?
  498. Irq_Scroll_Over
    ; T0 t" v' C( a( A& I, m6 I5 E
  499. - ^  y% V/ l9 l) u0 D
  500. INC <IRQ_Index( G9 D1 }7 Q+ v- u( d1 B

  501. + L6 D0 y$ i$ K3 X! z, @8 c" V
  502. LDA <IRQ_Index
    9 j# s$ c+ V( N1 m9 R. p: W# G. }, t/ h
  503. CMP #144 ]6 x8 I0 v- f! h- V/ }, p+ {
  504. BCC * + 10, r  W& I% N+ i' i; B' }$ }
  505. LDA #$00
      J+ R# g7 A: `- S  G
  506. STA M19_IRQ_COUNT_L# Y9 J2 i! x; X8 `2 u
  507. STA M19_IRQ_COUNT_H
    5 B$ \& C0 Q, I' i6 }
  508. 3 Y! b: \/ S- I5 F$ q3 }
  509. IrqProgramEnd
    # ]8 E+ g2 i$ f9 }
  510. PLA
    : t/ R. y8 ^* a, d
  511. TAY
    9 h' A8 E, t8 z% F; R3 ?
  512. PLA& ?# V1 h  d0 s7 T2 [
  513. TAX5 B9 b2 B# p8 O: a4 b
  514. PLA* Q3 M# J$ a3 G+ ?2 X+ s/ p# t
  515. RTI1 l, D* }/ x; g4 i
  516. 7 m: k. E# Z, I0 h  C
  517. ;==================================================5 b& V9 B7 S/ [& o5 M
  518. ;中断表
    ( v* C- _1 g& t5 z
  519. .ORG $FFFA# V, O' n8 e& S' J- A! d( A
  520. .WORD NmiProgram
    . m$ i' o  D" J$ H+ e
  521. .WORD ResetProgram
    ! ]  E- n) @9 H4 A) R
  522. .WORD IrqProgram
复制代码
, w3 _+ d/ k3 d4 `2 d  W

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-4-21 12:30 , Processed in 1.165039 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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