EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]: ~, Z0 U- F* @) Q% _( N4 q7 R
  2. ;FlameCyclone 202307103 s+ E9 X* ?; ]& a( a1 k

  3. 0 N, n  a- L0 x
  4. ;文件头; C2 \  V: L) q6 S* T
  5. ;======================================================================. Q6 l1 R( P4 B/ F3 A4 P  Q
  6. .INESPRG 4                                              ;16KB PRG 数量  S% [, o& n0 n! A0 e. A8 z
  7. .INESCHR 1                                               ;8KB CHR 数量
    0 C3 G& k. r+ H1 r
  8. .INESMAP 19                                                 ;mapper 19
    7 T: x' E! \0 b- s% l
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直1 C3 }' Y" f+ x. X9 |
  10. & |  \  j/ P" ?+ L4 f- J/ P
  11. ;必要条件
    " {8 ?" w& ?: O! `
  12. ;1.持有CHR ROM
    1 R8 @; r4 ?7 d% T
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    - t" m- a# p- [
  14. ;3.精灵内存(OAM)不为空
    & a" V1 N; ]) ?0 w) S; t
  15. 7 ^  ~& C5 l, k/ c
  16. ;==================================================
    1 b3 {  l, _9 _2 D' \8 U! i- I
  17. ;NES端口常量% D2 p6 @, K0 U* d& S- K" L
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器7 f; s5 Q6 \) m  R, c1 S
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ; x, X4 i' t) i7 j$ ^
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    $ W4 w- Q* g; a1 J9 R. S* `
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    + @. `- M4 W- _8 F" l" Q9 r
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1; e8 `6 H0 `4 U* f/ {& I
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    & B: |+ E0 A# R5 Z, H: s% F8 F
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    4 u" y: G0 m& {7 V4 H" G
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    1 r4 o3 Q5 ]8 }3 p2 n
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    8 Y; G/ {; c, F% T1 j4 h
  27. APU_STATUS              =   $4015   ;声音通道切换
    0 Q$ U4 e3 x4 e
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    7 m# V: }7 \6 c' y+ l
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    0 [% B5 o$ ?, R, l, M! L. ^
  30. ! {% ~/ G5 V: v9 h) H  M
  31. ;==================================================) W2 c8 @0 |  _: y8 `, s
  32. ;MAPPER 19端口常量
    " l3 T5 X8 X3 U
  33. M19_CHR_0000    =   $8000% e0 ?" r/ [9 t: s1 r2 |
  34. M19_CHR_0400    =   $8800- d: a" n: d* I( k
  35. M19_CHR_0800    =   $9000, U4 e+ @" x: s2 k7 }6 S5 J
  36. M19_CHR_0C00    =   $9800$ {$ Y! X- x7 T
  37. M19_CHR_1000    =   $A000) a" w: A# O) F, C  }; H
  38. M19_CHR_1400    =   $A800" l, A# i  J7 `" D0 t$ m
  39. M19_CHR_1800    =   $B000
    : m8 J, j; v  t7 C0 o: u# z! \
  40. M19_CHR_1C00    =   $B800
    7 s* [, ?7 x* f9 x2 g
  41. M19_NT_2000     =   $C000) k  @: y5 A) K: r/ s% l
  42. M19_NT_2400     =   $C800& c$ ~9 P0 R, g" @" ]! {& R
  43. M19_NT_2800     =   $D0008 X1 a, y% r1 y! B
  44. M19_NT_2C00     =   $D800/ f: y. [( R' C  M  X# X' B: y# _( G
  45. M19_PRG_8000    =   $E0009 B: G7 `  {) R4 l( H
  46. M19_PRG_A000    =   $E800
    ! i% ^& \& J* p
  47. M19_PRG_C000    =   $F000
    1 R& o, \# d0 z  K+ U" l
  48. M19_IRQ_COUNT_L =   $5000
    + C) A/ g3 B9 r) a
  49. M19_IRQ_COUNT_H =   $5800: ^3 H) _# k- Z7 U; }6 v8 d* w) y

  50. & j+ E; C  J- L& W
  51. ;==================================================
    ' T) r: a' n4 w$ \  n3 F
  52. ;程序块配置9 R- b1 N" G9 M7 {; |, ?
  53. BANK_DATA_MASK          = $07
    7 o% D, K2 l5 d5 ^% L5 G4 D# _
  54. ;--------------------------------------------------
    2 Q$ `4 Y* A6 e. W% ?7 {
  55. RESET_BANK              = $07
    % e7 G" v/ ^" G/ R7 Z. B; W
  56. RESET_ADDR              = $FC00
    ; b' j) b( X' i- ~
  57. 4 y. I4 G  |9 q3 M
  58. ;==================================================7 m1 w' H1 D3 b7 K$ J+ j5 H! r3 x
  59. ;图像块配置) U! ?$ [/ O; W" ~- T; f- _& P9 f
  60. CHR_DATA_BANK           = $08
    % u7 J& x# g1 g. S: [

  61. 1 m1 x- }8 X( r6 s
  62. ;==================================================
    ' D$ W4 Y3 e  x0 P+ H
  63. ;零页内存地址配置$ [$ w; _+ M, ^: T, n9 f9 F
  64. Use_Ram_Addr            = $80) u% J7 E+ _2 E4 l# c: ]
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    / \: f: h; k! l5 ~
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    " n3 G: H& T$ \. M: L+ _
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    ' j  n5 T- U/ m0 P( @7 M, x' B% h
  68. PPU_Scroll_V            = PPU_Scroll_H + $01) f1 X4 y) w& F) S/ |
  69. FC_Data_L               = PPU_Scroll_V + $01
    : Y# e4 a- |3 v' G2 b& i) p% \8 @; V
  70. FC_Data_H               = FC_Data_L + $01
    ) T% `8 p5 K% U. N) B: w: ]$ [. j
  71. FC_Data_Buf             = FC_Data_H + $013 \, r5 k4 k5 r8 O: r" q
  72. ;==================================================
    5 f* P  I7 K% I
  73. 3 \0 G! d* i( w& Y5 `
  74. GAMEPAD_MERGE_FLAG = $04. b. C; q+ n  I' G
  75. % b7 d, e* Y8 o8 v. X' L; L3 o1 p
  76. Gamepad_Keep            =       FC_Data_Buf + 1& j- o8 W. }, n( O
  77. Gamepad_Once            =       Gamepad_Keep + 2# ~# ?8 t5 `7 K+ w- c6 `5 z5 m
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ' A- s; |) W' ?* v0 a* G: {
  79.                                 ' i% @- W. Q6 v8 T, B
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    7 g: }+ h& O+ e2 q
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ( T' t7 c: Y6 Z6 w
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    3 x) j: G3 \* v  {5 d, n
  83. Gamepad_1_Value         =       Gamepad_0_Value + 14 B# K. U' U! w$ o
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    + v0 W" g* o9 |5 T4 n
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    / O! V6 ^5 f0 N0 n# u& P; P
  86. 9 G- m2 m1 C+ G7 B3 K( k
  87. ;==================================================% k# `  E) m7 d6 d% I5 U- C0 E
  88. IRQ_Index               =       Gamepad_Merge + $01
    1 _2 l$ Y2 |5 @9 U0 c7 J9 Y
  89. ;==================================================; X: k# s. j+ ^. p9 }' I

  90. , Y% S) x' v& @) L# i' a
  91. ;CHR图形数据
    ; E. p! b, d$ O
  92. ;==================================================. X8 N4 ?( F% |) L$ ]2 O
  93. .BANK CHR_DATA_BANK1 j% B3 h# e( r
  94. .INCBIN "chr_bank/chr_data.chr"
    4 W; h- q" ~) B+ u" ~

  95. 1 i7 x  r& M7 r8 }. W, d  X* q
  96. .BANK RESET_BANK & BANK_DATA_MASK& U; n3 g+ r5 G! b* _3 N2 v
  97. .ORG RESET_ADDR
    - ?7 @# g; ?; `, s& F1 P+ {
  98. $ N3 X9 S: i7 A4 Z1 f0 N7 [6 l$ l' [
  99. ;--------------------------------------------------1 c. j; ?/ q  H
  100. Attributes_Data3 ]8 ?( X1 [8 L$ c: @  r
  101. ;命名表属性5 s& }: |  Y" s
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00" w- K+ D5 |, s8 O
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    * ?( R4 b% W; }) w
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
      b, L( y$ p& ]
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    : J# U" ^2 P. a" Z% M& E
  106. ;--------------------------------------------------
    , Y: x- X8 T/ d7 Z1 b0 C
  107. ;调色板数据9 I. K7 O6 D. L: m
  108. Palette_Data
    0 I/ u9 p5 y" O2 T- a
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F2 t& B. v; r. `4 d' D' A3 n
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    1 v& ?( E+ U/ }3 y' t8 g  ]

  111. 1 A' G4 K% O5 }$ c' z& f
  112. ;==================================================/ k: Z2 a2 S: w2 p
  113. ;命名表初始化
    . z" w+ [$ v6 B9 n3 w3 }4 R
  114. Init_Name_Table% z, _; E' }& a$ p5 o# f
  115. LDA #$20
    . W7 x: v( H3 Z' \, Y% \
  116. STA PPU_ADDRESS
    8 x  C: i' a( L* V2 \% w) o1 T
  117. LDA #$007 H& X: P2 J' P
  118. STA PPU_ADDRESS6 `9 T9 U4 l# L) M, f* A
  119. LDA #$00$ N4 ~. p) D- K/ @3 c: G8 N9 {( V
  120. LDY #$00
    ( j1 q. ~2 J. y0 H) b) r: S% {7 F
  121. LDX #$10
    # T( H$ f* |5 F, A" |- h5 Y. G# X& T" B
  122. Init_Name_Table_Write
    * y/ O* n# Q2 h# G
  123. STA PPU_DATA
      ~% V9 M1 U% K% d
  124. INY
    / x% \) W& a0 v6 o; N9 {
  125. BNE Init_Name_Table_Write
    * v) l2 K" f2 C: W
  126. DEX
    ( s  _6 ^  }$ g7 y9 X
  127. BNE Init_Name_Table_Write1 b/ t8 G, e" _2 @; ^6 c9 C
  128. RTS( z* A2 U( Y& L3 T, o$ P+ ~
  129. % R5 {' g8 q7 ]  M* W- E
  130. ;==================================================7 W. d3 b) o+ C2 E4 Z+ f3 Z
  131. ;调色板初始化; P0 c% p% i- J1 f
  132. Init_Palette
    , O0 _( U4 f! R% k3 P# M4 G
  133. BIT PPU_STATUS
    . F: t6 V# f  X) B# |- k4 R) }
  134. LDA #$3F1 t$ ]9 z' f' s5 ~$ H- L
  135. STA PPU_ADDRESS" Y; b# e1 m0 h: s" E
  136. LDA #$000 l6 C3 w( G# m
  137. STA PPU_ADDRESS
    3 R- B( N: `( X) Q' x% Y
  138. LDX #$00
    ! ~7 A* i. F& o5 _- `1 s" i
  139. Init_Palette_Write
    ! q+ N$ Y6 ?7 U: F. K
  140. LDA Palette_Data,X7 V' k$ ?5 d9 a- d5 g+ T7 l
  141. STA PPU_DATA
    . E( a% p0 e  {9 r
  142. INX
    : M! Q  d6 g# L4 W& E1 ^
  143. CPX #$20
    % k, V% C- p* N+ {
  144. BCC Init_Palette_Write
    ; R! D5 t; t8 R1 r: V7 a  [5 ?
  145. RTS+ ~/ H2 p5 q$ E2 M$ N
  146. " J% L& C2 |! ?5 L! H' t
  147. ;==================================================7 s' n3 M  u$ A& y) L0 u
  148. ;设置命名表属性
    : x' a, v2 s8 y% i) e* q
  149. Init_NameTable_Attributes
    3 ]9 C! N3 k) U, U! p; T) ~
  150. BIT PPU_STATUS
    ! j6 n' X3 g. B' f- T5 A$ w. E
  151. LDA #$23
    - H" i9 `$ f7 D9 h$ w, O
  152. STA PPU_ADDRESS4 P3 l# b! n( ?; T/ C! c
  153. LDA #$C0, O7 p& I5 K/ j  X0 b( G+ R) g
  154. STA PPU_ADDRESS# z. n1 ~) ]6 k. c
  155. LDX #$00
    : R8 W5 ^$ G$ r5 n
  156. Init_NameTable_Attributes_Write
    " }# a0 y& H- s% z5 ^" Z! n; R- \
  157. LDA Attributes_Data,X2 n5 `: L8 O2 U
  158. STA PPU_DATA; s0 ^0 x% {- u
  159. INX3 }+ F' P! K0 i5 [; m& }
  160. CPX #$40
    - ?( o5 T9 r; R
  161. BCC Init_NameTable_Attributes_Write
    5 j# G  ~) A+ Q" y
  162. RTS& Q) m# x! A# a. I
  163. 6 q! g5 v4 A, c& T2 }2 w
  164. ;==================================================3 F9 B) B( F9 }0 t5 f3 Z4 q$ c
  165. ;初始化命名表文本
    & h. s7 c  l$ I1 N! v- H" ~
  166. Init_Name_Table_Text. n/ |+ l1 s8 B& X
  167. BIT PPU_STATUS
    5 P  E0 o* F( V
  168. LDA #$20& M7 ?+ j; h% w4 B
  169. STA PPU_ADDRESS
    ( ]' b' w" Y7 ]4 u
  170. LDA #$001 L5 h4 ~3 Z* V- M) [9 i8 X
  171. STA PPU_ADDRESS
    2 Y- N& A# V$ B* W
  172. LDA #$00$ u7 i6 u4 G! n, w) s, V% M$ ]3 e
  173. STA FC_Data_Buf
    + _! Z6 t  L  S0 j7 |+ V5 s
  174. LDY #30
    $ p8 P% h/ z( _- {; x8 ^
  175. Init_Name_Table_Text_Write
    / ~3 ~3 n3 |! H4 a, N3 g
  176. LDX #325 H* i8 K% h* O2 a# M
  177. Init_Name_Table_Text_Write_Char
    5 q: G  Y8 v, G6 h
  178. LDA #'0'
    - p9 D" ?3 {9 C4 K# j6 ]+ s( H7 _/ c% i
  179. CLC
    / c# k8 }4 V; k' r. F$ ^
  180. ADC FC_Data_Buf: D9 N( f1 d5 g5 Q8 F9 K2 v
  181. STA PPU_DATA
    ) l" f  a! ]: c6 @8 f& R  m
  182. DEX0 a- r8 Y% i- u& O8 `# h; G
  183. LDA #$145 Z5 ]; o% N( s6 {. T2 L" G
  184. STA PPU_DATA  H! @9 I0 F" J& r- f
  185. DEX9 m: d% `8 x9 \" p
  186. BNE Init_Name_Table_Text_Write_Char7 t$ p1 [! ^) E2 s' C  B1 z: {5 {
  187. INC FC_Data_Buf
    " U2 T; T) k; D3 ?' D% O: d! B! c0 @
  188. DEY% G- i# ]9 x( [
  189. BNE Init_Name_Table_Text_Write: @0 q) P1 {, ]* R7 s  J; y( B
  190. RTS
    # l+ o* N  ?" @4 |/ L7 E
  191. 5 o+ g6 m# v$ N
  192. ;==============================
    * s0 p( }* g. V8 J
  193. Init_OAM_Ram;初始化精灵内存/ ~$ }# a5 @9 ]  ~( R
  194. LDX #$007 X' q+ [0 b& z
  195. LDA #$00
    - n* R8 f) J; O, t1 N  D( w. u
  196. STA PPU_OAM_ADDR. D* D6 d( ^$ Q
  197. LDA #$F8
    & L* Z  Y+ O, a3 v7 w
  198. Init_OAM_Ram_Write$ g0 k0 g8 |# i9 ?1 S
  199. STA PPU_OAM_DATA* d( G7 b# d, M1 C. j+ F# G$ v* `
  200. INX
    0 i2 R3 T: a2 m) Z
  201. BNE Init_OAM_Ram_Write* h6 C/ s1 `* D! @0 k" Y
  202. RTS1 C) f9 M2 U6 h) z

  203. ! c9 R9 l6 e* ~# @; C& i
  204. GamepadProcess;手柄处理$ q+ v5 T" d( R, C  N( N' i( Q
  205. JSR GamepadDatacan
    8 c/ A3 s4 h* X1 \: t/ o/ u
  206. LDA <Gamepad_0_Value
    4 M; S1 E: X9 _; D3 l
  207. STA <Gamepad_0_State
    0 g2 v# Q. s. d) K( D+ \; w$ P6 Z
  208. LDA <Gamepad_1_Value* m; J" c( x5 j0 Z1 U$ P& }4 F
  209. STA <Gamepad_1_State9 h9 n* J3 Z& c4 `; v- Z
  210. JSR GamepadDatacan3 b& m( t" o8 l
  211. LDX #$01; k; u* y; e" F! W* Y/ V
  212. GamepadMergeCheck;合并手柄输入检查
    ! D* G+ ~) g7 `( A3 M
  213. LDA <Gamepad_0_Value,X* i9 L# O- F7 i& S( H( ~
  214. CMP <Gamepad_0_State,X/ `( s, ^0 |, f5 o4 k$ Y
  215. BEQ GamepadMergeInput
    - Q# ?. w7 N! B  v
  216. LDA <Gamepad_Temp,X
      e: l! N+ ?5 k# t$ \/ a$ N
  217. STA <Gamepad_0_Value,X9 y  W  J  B! |
  218. GamepadMergeInput;合并手柄输入+ [8 E! b. i! O
  219. DEX
    4 m4 C  {& a% L) u) K
  220. BPL GamepadMergeCheck
    $ Y. b' y1 S& V- h" W9 x# s3 M
  221. LDA <Gamepad_Merge
    7 a4 a/ t$ x) \
  222. AND #GAMEPAD_MERGE_FLAG: z- m- R8 x, t
  223. BNE GamepadStateProcess
      w( U6 w! n# a# D* O
  224. LDA <Gamepad_0_Value& x/ t  _5 q. j) M' K, ^
  225. ORA <Gamepad_1_Value
    2 F2 F% X8 P" G4 c3 Z
  226. STA <Gamepad_0_Value4 g/ m0 x( l* {4 r. y3 r' q) W- j
  227. GamepadStateProcess;手柄状态处理
    % ?+ U: y0 u3 L! ]- O7 @
  228. LDX #$01  l6 @; k  S9 B+ H$ h% U$ O
  229. GamepadStateSave;手柄状态保存* D# q2 J+ d, C8 m& r
  230. LDA <Gamepad_0_Value,X
    3 y7 Y+ N( i' s3 [) l9 T
  231. TAY) Z) e1 E5 \, S2 c7 z4 I0 i% G1 l
  232. EOR <Gamepad_Temp,X
    ' D0 A% L* L: Z3 R9 l% X
  233. AND <Gamepad_0_Value,X1 `' u8 }" e; U3 R: A2 t' I, B( Z9 k" s
  234. STA <Gamepad_Once,X7 [% J0 {7 d: T6 \: ?2 R. Q; z. Q8 H
  235. STY <Gamepad_Keep,X
    8 x! w; x3 v+ X7 _3 H
  236. STY <Gamepad_Temp,X5 B7 I' ^3 m2 V) h' ]% Q
  237. DEX9 ]" ]8 m, U" t% g' M; a
  238. BPL GamepadStateSave# X, s6 p. e6 a) }) z
  239. RTS
    " w5 h2 I; O- t& g
  240. * M8 R% \4 A$ E8 p& j
  241. GamepadDatacan;手柄数据扫描' s6 o7 E& x% A/ g& T- G: Y
  242. LDX #$01
    : {+ Q# m* n6 l1 S9 g( l5 t
  243. STX $4016) ~& z9 I" a. r' n% M) `
  244. DEX# r! t% Y  I4 d
  245. STX $4016) P: H; A. t0 m6 }: C, A7 L
  246. LDY #$08
    ! s7 @- V3 p% g+ @$ e
  247. GamepadPortScan;手柄端口扫描
    * u7 W9 N8 p2 g6 U4 S8 P
  248. LDA $4016
    + f; l- f& r  Z% C2 ?! b' L0 R
  249. STA <Gamepad_Port_Value
    : t. C9 p  H% t2 ~1 H
  250. LSR A4 m# Z5 p, ~$ j
  251. ORA <Gamepad_Port_Value
    , E5 d# H* P& t+ f
  252. LSR A
    3 \: F$ V4 `+ U/ L) m
  253. ROL <Gamepad_0_Value- o# t! ^4 R$ q, E9 Q1 i
  254. LDA $4017
    . R# e4 A' Z# w! ?7 [% g
  255. STA <Gamepad_Port_Value
    5 N7 k2 d' Y) N8 r
  256. LSR A
    8 D$ d. W/ `! }, B0 `# ?( p
  257. ORA <Gamepad_Port_Value
    # K$ `5 @. F' d6 O# a
  258. LSR A
    % t- Q# w/ I. v0 p
  259. ROL <Gamepad_1_Value2 a/ b7 Z. T& s$ E  X9 H" e
  260. DEY: t) @: Z* x4 f, x( g
  261. BNE GamepadPortScan
    4 ^* @+ n5 J$ @$ M0 H; s
  262. RTS4 i% v: O4 q! r

  263. # {8 G0 K! f4 C" n
  264. ;==================================================3 ~, j5 K) t7 t" h8 [
  265. ;PPU处理7 c0 }0 C- |+ x
  266. PPU_Process
    , s( X) y' S, K5 V0 [6 c8 w$ K" \! K, Q
  267. LDA #$00/ X+ X9 Z+ X1 d& E' n2 g
  268. STA PPU_MASK
    7 P7 N9 T( p5 @
  269. 8 H! E# I% R* @  [- Z
  270. BIT PPU_STATUS$ ]+ i9 ]) b4 |2 u: h
  271. LDA #$20
    $ F3 F/ l1 }# P
  272. STA PPU_ADDRESS3 \3 x0 S$ @* G
  273. LDA #$00) w2 v. z( d4 b, z& a, D% m
  274. STA PPU_ADDRESS. ]1 h8 @$ W2 b+ D$ u9 A% x# `. s, _

  275. , {& a  w& _/ s8 h
  276. STA PPU_SCROLL
    ' C  m- q- R3 d/ ^$ q
  277. STA PPU_SCROLL9 W' N2 Y, j" ~. U8 ~

  278. ' Z7 `" m, r9 a# O9 U
  279. LDA PPU_Msak_Buf
    $ H3 M1 \3 t) U$ A" v* }* Y
  280. STA PPU_MASK7 J) b" A1 F1 q+ }  x

  281. ! t7 x: Y. D+ b7 X
  282. RTS7 V5 m: V8 Y1 n+ d+ [

  283. " i" ?: H9 I# x- M
  284. ;==============================
    & D1 o7 l* R7 F- J, K  ?; e
  285. Time_For_Vblank;延时等待# @* F* W; x5 k8 k7 ?* ]
  286. LDA PPU_STATUS/ o/ P+ b& L; `  y* [, [
  287. BPL Time_For_Vblank: U, `% b& W8 L& s
  288. RTS
    ' ^" d1 {+ o! r1 ?

  289.   r. b5 E2 `5 V
  290. ;==============================; N0 q) A- t6 v' {* w& T
  291. ;初始化MAPPER19' A% ^7 t' R% c, X3 p, U0 V
  292. Init_Mapper19
    % D+ f$ f. d  [. z
  293. LDA #$00
    ( L( [5 C0 n- e
  294. STA M19_CHR_0000. E" d$ B! ]3 q# L) T# c! d' @
  295. LDA #$01) t( C0 k& V- `; i: F; ]
  296. STA M19_CHR_0400
    ( h! w/ }7 t6 n' u
  297. LDA #$02! O+ B# R7 t" J
  298. STA M19_CHR_0800( J# {+ X: i( Q+ O5 u
  299. LDA #$03. ~. l7 ^! p* J  j
  300. STA M19_CHR_0C00
    9 a/ e' v* |$ B
  301. LDA #$04
    " R' s2 s0 g$ T
  302. STA M19_CHR_1000
    ! Z5 ?  q! o, t+ k, q
  303. LDA #$05
    4 e* R6 |. G5 n- J" B. e
  304. STA M19_CHR_1400
    ) c0 s2 Q0 V: U# ^
  305. LDA #$06
    0 z4 G& Q' ?$ R) q5 \/ N
  306. STA M19_CHR_1800
    8 f$ k. W; i4 Y* g
  307. LDA #$07
    ' d8 r0 l) [. }  p% _0 o: H1 m
  308. STA M19_CHR_1C009 w9 U" y$ r( L% X+ Y8 @, B0 D! `
  309. 6 R' D, {5 C/ p; t* F( l4 C
  310. ;禁用IRQ  _( @" W/ N" h' J1 l5 m' [  K
  311. LDA M19_IRQ_COUNT_H, F. M4 Q/ v7 R
  312. AND #$7F
    * j, t/ Z3 S+ x- @8 M2 C
  313. STA M19_IRQ_COUNT_H, ]! `: z1 b( m& Y; C" e3 s
  314. 9 z! J0 M6 Y" ]$ s/ [: b5 [! S+ W. V
  315. ;命名表# M  W  j; G3 i9 z( c* K- y
  316. LDA #$E0
    / ~- Z* O7 V, ^9 Q
  317. STA M19_NT_20004 Q2 B! y9 i: m9 g# c: |& ?
  318. STA M19_NT_2400; `/ l' [) O$ z( i+ ^' \; l) i

  319.   [0 }  u" {; k. F
  320. ;命名表5 W( Z, @2 P8 `8 x: L/ `
  321. LDA #$E1
    " m& L' `* B4 \9 G7 v" E8 C
  322. STA M19_NT_2800; @! g7 ~  i% }
  323. STA M19_NT_2C00
    & \8 v! z' y0 ?3 }- I

  324. * v1 g( m: h+ H7 F; U
  325. RTS
    . s" P& g% U& ?4 P
  326. 3 f4 \# |  Q$ _5 E8 \
  327. ;==================================================
    * h& ~/ Y$ Z( \% C3 D/ E% g# X  \" ^
  328. ;重置中断处理
    $ M2 Q% l) ?0 P8 V. W" \" I
  329. ResetProgram
    & }' I' \9 W7 r0 e" D" m
  330. SEI- h+ |: N  l1 `8 T1 `
  331. CLD
    ) R: a, A1 f# E* p$ T
  332. LDA #$00% _$ K+ K9 g$ o
  333. STA PPU_CTRL$ S+ |# |1 G9 w" s0 _
  334. STA PPU_MASK  l3 R. L+ K2 e
  335. STA PPU_STATUS
    % l6 M& z% _4 X5 V; H
  336. STA JOY2_FRAME
      _" q& s. m. O. `' a' Y5 M# z. t% K
  337. STA APU_STATUS  f& ?! g" [9 a2 W9 W" L6 v
  338. 4 B. B$ X6 F3 k7 a4 k  ]( I! z
  339. LDA #$C0
    " n% M1 u8 \" B; P2 ?* |3 n
  340. STA JOY2_FRAME
    & X" Y7 q5 u. _( H; A4 i5 Q

  341. & b$ S# ]; u$ x0 L; j% e2 h
  342. ;等待vblank
    * B. v7 M% A. p7 h+ J
  343. LDX #$02
    * _  K" o: i8 u
  344. Vblank_Wait_1' _. G+ q% a6 ~0 y* f
  345. BIT PPU_STATUS
    ' Y" w* X* E& ^) \3 a) e+ G
  346. BPL Vblank_Wait_1
    ; u7 q2 ?/ P. C
  347. Vblank_Wait_2
    $ U: S  Z& z$ M8 c1 I7 J
  348. BIT PPU_STATUS
    / g/ r' F; o( q5 U8 p% `
  349. BMI Vblank_Wait_27 _2 W. V; d# I+ N5 c; t  |2 x
  350. DEX
    ' }6 w/ v7 I$ P: S, f
  351. BNE Vblank_Wait_1
    - _  X7 `  m1 \3 w  f
  352. ! e: V' x" g( y2 y% X9 E, O+ \4 g; o
  353. LDX #$FF! V& i: [& F( B( x) l3 [
  354. TXS5 a; _# |% M3 o1 Y/ s. a
  355. % j7 T/ J. A5 x8 v
  356. ;初始化MAPPER19
    - T3 u* E" S0 b; r6 S, N6 R
  357. JSR Init_Mapper19
    ( e( q' d- M  i; c6 q

  358. ( J. Z$ f' R, p. z
  359. ;==============================
    2 l# f4 u! s& W
  360. ;RAM初始化
    7 x( I* g$ N: m8 R& @
  361. Nes_Ram_Init
    ) e5 y' P8 b; F9 E3 B
  362. LDY #$00; q* `) ^3 v7 I9 T: ?, A8 Z' F" S
  363. LDX #$08
    , K( l2 I, n9 ~! ?$ J& z
  364. LDA #$00& }6 T0 C) w( O5 V7 h
  365. STA <$00
    9 @; m+ s1 l2 q- E& K
  366. STA <$01
    ! f3 W2 Z- I% n% A. |/ }
  367. Nes_Ram_Init_Write
    " l+ g( O$ Z8 s* U
  368. STA [$00],Y
    9 J6 K3 a# E4 |6 B) i, J
  369. INY2 C/ u" Y) M2 ~  }) n* P
  370. BNE Nes_Ram_Init_Write
    5 U- w0 X9 X' M  w4 z2 S
  371. INC <$01
    0 s$ M6 D7 H' \6 f4 ]
  372. DEX! X* G! F7 I  A
  373. BNE Nes_Ram_Init_Write8 g$ w! d  B. A: d, p

  374. " u) b$ o4 i; }) r- A
  375. ;初始化命名表+ N  m& v) W# u: |
  376. JSR Init_Name_Table
    5 ?+ K$ T0 |) F+ {( s, C% G/ k
  377. + x- X% f+ I0 }. V! N2 M" t" n
  378. ;初始化调色板! I6 r$ E) T, B; ]6 w
  379. JSR Init_Palette
    5 i; I* L7 }/ N% _2 t
  380. 7 h$ R- W/ \( z( y! @$ s
  381. ;初始化命名表属性9 U9 I" A/ o( T6 d; ]5 B0 ]
  382. JSR Init_NameTable_Attributes
    * J$ \. |& _  x( ?
  383. : ^+ p+ X$ _' h- O, V% l
  384. ;初始化精灵内存; ?/ `' ?9 m/ m( I& |, {. \
  385. JSR Init_OAM_Ram, v4 g2 Q. j1 `' q, Q8 ~: g0 k1 g
  386. $ V$ f$ d3 t6 L& u. ^5 a/ _
  387. ;在屏幕上写点东西
    0 U& ?% ^6 I( Q" ^8 j1 B6 t  `
  388. JSR Init_Name_Table_Text1 j) H+ S- N" E& T- \8 k; |
  389. 4 X1 J- L' G6 ?9 w/ O
  390. JSR Time_For_Vblank8 m# \& a7 D# B( D4 X* k
  391. ;开启PPU控制
    # Z# }5 k! d$ t4 f$ _9 u+ ?/ @
  392. LDA #$A8
    . @' \* y" ]0 z7 e
  393. STA PPU_Ctrl_Buf
    ( ~1 D) K6 E3 s3 F' S) A4 D* {
  394. STA PPU_CTRL
    ! g7 Z0 m' _5 ]

  395. - E, g' r$ G) K9 h1 Z
  396. ;开启PPU显示
    , U1 j; U' S4 F( C4 @3 H1 B  v# q
  397. LDA #$1E
    2 l. j, g( g1 `/ c/ v! o" X0 F
  398. STA PPU_Msak_Buf
    5 l' w- B" _0 W8 K$ W# j$ F" Q

  399. 6 x4 u, m0 i( d* P1 }4 M
  400. CLI, X+ G: h1 S( v
  401. JMP Loop
    5 ^9 L( ]6 W3 q1 j$ Z; L

  402. ) w& e( \+ E! M4 y! n
  403. ;==============================3 T1 {6 e: A0 D- \& o) S$ ^
  404. ;死循环, 等待NMI中断: _* C$ j6 H7 i2 a2 M) @
  405. Loop9 G0 J' \7 x# i6 |
  406. JMP Loop
    0 r, y) ~  M8 {- k, _0 q3 V  V

  407. 2 t( n3 J5 U4 {. V
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9679 x' j2 t7 m$ k( n' B7 Q
  409. 9 V; x( D# }) z. S9 t# _: a  A, `8 H3 k
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)  u& K  I: j1 l/ |$ o5 ]+ B, t
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    6 X* r9 l0 f- Q5 G! B" N
  412. ;==================================================
    : p/ h! }2 Q" G# }
  413. ;NMI中断处理& \$ [! }2 X$ j: l( U1 n7 C9 ^9 H
  414. NmiProgram
    ! b- v5 c7 h8 g: e+ {! B9 m
  415. PHA, a/ _% Z7 n. S! Q, F. c1 O, z
  416. TXA5 o2 _6 W- Q$ g. Q" _& {5 I( j
  417. PHA
    & S1 L/ v8 z5 c, O: A
  418. TYA6 w! A$ R. Y# U$ c  I- j
  419. PHA
    9 H/ Z5 Z+ d8 i% w, {

  420. 9 E+ I: P9 r6 z4 ~2 S9 O4 F
  421. BIT PPU_STATUS
    - r: G* u( i5 w" d; q

  422. 2 k! `; d  ~- D
  423. LDA #$00
    * {0 I4 `- `+ N2 b. |/ @7 n( o
  424. STA IRQ_Index
    ) i4 {! Y9 b! {& @

  425.   `9 Y8 l& O: Q5 F
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    ) t# s* D) V5 [* R
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    9 H# t. L+ x9 b2 K% g
  428. STA M19_IRQ_COUNT_L9 E: `! A2 _) a2 W
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    4 u' d6 i; }! M/ |8 D
  430. ORA #$80
    ; E, g( i8 \3 J9 h$ ]& l
  431. STA M19_IRQ_COUNT_H6 x! n* D( m; d8 ]% b
  432. CLI% v, T! L6 h" f5 p9 ~
  433.   m. j% m+ w  f: O% E& a
  434. ;关闭PPU控制7 @4 i. A. [) G. L! [
  435. LDA #$00
    2 S+ l3 C8 A' E. Y. L. V9 b
  436. STA PPU_CTRL
    / `. r3 q3 \: O% _; F2 ]; V

  437. 7 s% w$ O# P1 m' Q: i) L
  438. ;处理PPU
    : U9 _/ D/ R8 k! H* y) a' q
  439. JSR PPU_Process7 q0 b9 B. n# u1 `# [6 c

  440. 7 l4 J- a+ h; x% H) [
  441. ;开启PPU控制
    % f( t6 {, t8 c# p# l
  442. LDA PPU_Ctrl_Buf
    & P+ ]/ Z! r2 Q" ^2 U- r
  443. STA PPU_CTRL% R4 o- _" k& d# T! T
  444. - _5 l& ]0 V: Q
  445. ;手柄处理- i. p* a1 e( P3 I0 y
  446. JSR GamepadProcess
    " }5 \) G6 ]& o/ f
  447. 9 P( Q# t+ `9 X6 O
  448. LDA #$003 _( }0 {# C- F9 t" J! [, r. F
  449. STA IRQ_Index! ]. I- V6 x/ ]9 ?% q
  450. 6 i1 f0 ?* p0 |  J/ y0 `
  451. PLA
    ; ~" A, t* P3 Y& H
  452. TAY
    3 v. V4 T; D! c: q$ E- S4 n
  453. PLA& }, v2 B$ @1 \9 C8 E3 O
  454. TAX" ?$ Q& L2 v: \( M
  455. PLA
    & |, l$ D& q- N1 K1 M
  456. RTI
    6 B5 r8 I& D( p2 m) Y! I

  457. ( I( R8 q% x+ q$ K- s
  458. ;每行扫描线113.679 Q% v3 e) \" a* v3 M( p0 }8 D
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    4 e9 n! s5 r9 x& ~0 T( G5 U
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    4 ]5 @" P& F' p, d, C9 [" U3 O
  461. ;==================================================8 ?/ @6 V- B  A) \( K
  462. ;IRQ中断处理
    3 M. j0 Y; U2 w; h" e- p! ?. ^! v
  463. IrqProgram
    3 P: k# G4 v+ t6 p
  464. PHA3 \4 G& e3 e9 J: d% f; P0 H( V
  465. TXA/ p; d' X, c" W( G# h
  466. PHA" |3 q. e! N/ t8 j, }0 d% ^
  467. TYA
    & r- ]2 u, O7 C# G9 y
  468. PHA# f7 q5 h$ ^4 x
  469. $ b+ [1 |2 o! c9 T1 x# \! [5 F
  470. ;16条扫描线后触发IRQ: d2 @# u+ \* t. S# L8 g
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    " i+ s6 Y! ^( n
  472. STA M19_IRQ_COUNT_L+ m; G: M1 A! k
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    0 R$ ]- D3 @/ S9 F
  474. ORA #$80
    9 I0 a; l, O; i. d. z3 e2 F
  475. STA M19_IRQ_COUNT_H
    3 ^: s8 s8 D. \/ F- G  f" G. W0 G

  476. 0 W% I0 W4 L* \) n
  477. LDA <IRQ_Index0 V9 q2 o: c* T  n$ a/ v
  478. BNE * + 4  `8 {( g" B5 o! s
  479. INC <PPU_Scroll_H
    : R, U6 ?& C9 u& {/ a- F' L* L1 b

  480.   W2 x0 l8 @( Y8 p" @$ S
  481. ;设置屏幕滚动
    ) T( S0 O6 N! D# K
  482. LDA <IRQ_Index
    1 w1 a4 ~0 ^$ ~9 C- O5 W4 G, \/ M! S
  483. AND #$01" ?" d( z6 i' P0 y) a
  484. BEQ Irq_Scroll_Right
    1 O0 a' C6 e2 K% v

  485. ; S8 [$ O* z" L; m, A' I$ `* B$ b
  486. Irq_Scroll_Left
    - ]8 [- O) _& O% `
  487. BIT PPU_STATUS; m) Q6 z& E6 P1 W5 \0 L
  488. LDA <PPU_Scroll_H/ E8 F- q- `& z0 k6 f  t$ t8 L
  489. STA PPU_SCROLL
    - D. R* }* S5 ^# W
  490. STA PPU_SCROLL
    2 H9 S& h; `5 G& l4 [
  491. JMP Irq_Scroll_Over) c3 l, ~: @1 H/ o

  492. . h* Y1 ^  u' A$ e. g
  493. Irq_Scroll_Right
    . v' U1 }& E& n/ z3 ^
  494. SEC; X) _( w6 ]4 Q! L5 }4 T
  495. SBC <PPU_Scroll_H
    ' f: ~9 N# S; x) x" P; v* v# m
  496. STA PPU_SCROLL
    * w. h8 c) u6 ]9 W4 C
  497. STA PPU_SCROLL2 z2 m5 [- h" z0 p/ ^3 S
  498. Irq_Scroll_Over
    7 p( e# ~( F/ \9 d8 d! y* P3 l

  499. & l- w4 x- M1 q- L
  500. INC <IRQ_Index
    0 k; g0 H  s% z! _
  501. ) q7 ?8 T5 N, }5 e! x1 Z, Z! J
  502. LDA <IRQ_Index
    ! K4 s' `, x/ t
  503. CMP #149 X! _- a- |' q
  504. BCC * + 10
    / T+ {9 n- O, t. G0 p' A
  505. LDA #$00
    " c( x) k9 k, S
  506. STA M19_IRQ_COUNT_L2 T4 x1 K9 Y' b! L4 f/ z
  507. STA M19_IRQ_COUNT_H
    ( |$ b: M+ o& Y3 D8 `2 d

  508. ' S% `5 @" P% k0 O
  509. IrqProgramEnd" a, x0 K5 `0 B! p& ~# `. ^1 |5 ^
  510. PLA
    1 c  j) c! m. c) s1 p2 R7 V$ a
  511. TAY
    5 I+ k) I& l% n- Z8 T0 p' _
  512. PLA
    % L" W+ G* X. Z
  513. TAX
      S  \( a9 \1 V  i- [
  514. PLA
    7 O9 a% G) B* Y7 R4 T: u* M
  515. RTI
    8 y. n/ d. E/ x- B
  516. * C( _  S7 Q9 U
  517. ;==================================================+ ~: y0 u$ K7 x
  518. ;中断表( Y2 n+ M0 J5 |  V* [, Y; |: ?  a
  519. .ORG $FFFA8 L  r/ _6 U6 a( U" W, w4 x2 y
  520. .WORD NmiProgram
    ( b6 b6 Q4 V+ E! Y0 Q1 q
  521. .WORD ResetProgram
    + a4 y1 `$ \' g) W) E. u2 _  }& E0 l
  522. .WORD IrqProgram
复制代码

1 E: n3 T* u# ]; U  i

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-6-9 21:56 , Processed in 1.114258 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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