EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    # U" B; C/ V4 p( |+ E
  2. ;FlameCyclone 202307105 X* {$ U6 o% Q- ~6 l+ g
  3. 1 B& S) d0 t9 z/ T% @% Z  P' S2 x
  4. ;文件头
    3 `' c. v% q2 S' \9 r
  5. ;======================================================================1 ?$ `) y, q2 p% f
  6. .INESPRG 4                                              ;16KB PRG 数量- G# e8 ~+ L# D2 `; ~( a8 m
  7. .INESCHR 1                                               ;8KB CHR 数量
    ) g( V. D* f/ W$ r7 d9 ?) d
  8. .INESMAP 19                                                 ;mapper 192 H6 p7 Z& L5 O4 j. x" ~0 W
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    $ m( o3 n" Z/ n

  10. 4 S3 s0 C* ?$ Q2 v% O5 c
  11. ;必要条件
    ; `+ b$ }) i* R0 J) @  m
  12. ;1.持有CHR ROM
    ' j6 W8 `( n3 N" _
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000/ o# J9 W7 F2 C
  14. ;3.精灵内存(OAM)不为空6 N8 j8 w9 [3 L/ s7 s
  15. ! Q; f  i+ ]0 ~$ p  z9 Y
  16. ;==================================================; M" O4 `+ E2 U; y( Q5 s
  17. ;NES端口常量
    ' j! I# H5 x7 T
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    , g: ?) O1 k3 A
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    + K# k9 u8 l1 l
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    / X' ~5 D& T/ x1 F4 H+ u
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1% U4 z! ~" a3 W* N6 ~8 T5 C1 o
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1+ _. {  I; D1 V  \5 V8 d/ m4 M
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 . l. W& b: `& q' T7 G
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    $ C# m8 C6 M* w2 W  a4 P
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    7 S% q/ g  A0 l/ b
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存9 U1 @( J1 V+ @# Z( n
  27. APU_STATUS              =   $4015   ;声音通道切换
    - @' O( U7 T1 e# ~
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通9 r7 {8 C" G/ ~1 M! R  i
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    + r5 Y; b- o" _
  30. 3 ]3 _% Z4 [3 }, J- y2 e6 Q
  31. ;==================================================
    4 T" s5 g4 c. L: w# b  v
  32. ;MAPPER 19端口常量
    # ?8 d3 N8 P  H# @2 K( L0 \
  33. M19_CHR_0000    =   $8000
    ' E; @. o4 F: i6 m! N+ U$ Q- g
  34. M19_CHR_0400    =   $8800
    ( C; N! V1 ~5 G8 G9 w. S& n$ U
  35. M19_CHR_0800    =   $9000
    3 Y7 T$ Y! g$ t
  36. M19_CHR_0C00    =   $9800
    , z* w4 f, i3 B0 D+ i
  37. M19_CHR_1000    =   $A000
    - M$ l& H6 g- |9 M9 C! {
  38. M19_CHR_1400    =   $A800
    ' F  `* X7 A) K' j+ B
  39. M19_CHR_1800    =   $B0002 e* p5 T  D8 J4 }7 _7 K$ ]7 f
  40. M19_CHR_1C00    =   $B800
    8 g2 [  B. P* q
  41. M19_NT_2000     =   $C000
    7 L; j6 R" u" `% m; A
  42. M19_NT_2400     =   $C800
    0 S' d" f" c4 f1 w2 T
  43. M19_NT_2800     =   $D000
    - r- m$ c) c2 a  o
  44. M19_NT_2C00     =   $D800/ ^- U+ m' c3 G) a2 F
  45. M19_PRG_8000    =   $E000
    - ^9 _' i  }7 b" D9 p2 J. k
  46. M19_PRG_A000    =   $E800
    % U( K! s) p$ I4 l( j
  47. M19_PRG_C000    =   $F0006 s6 O9 `+ ?. A. ~) p9 ^+ p" }
  48. M19_IRQ_COUNT_L =   $5000' ~, r1 i! C8 p& E' a, G$ v
  49. M19_IRQ_COUNT_H =   $58000 {# X) y2 u% n7 b3 K
  50. 7 B6 Z  b8 b6 ?- D" h8 x
  51. ;==================================================
    # V+ m9 ?6 X4 r/ d) i# r/ |0 N3 ?
  52. ;程序块配置
      X  i: X+ z2 b
  53. BANK_DATA_MASK          = $07; z/ j- o% z+ E/ k9 c1 u) u* w
  54. ;--------------------------------------------------5 z" H/ Z7 }  H7 I
  55. RESET_BANK              = $07
    * |, g  W0 l0 `) }: J* P
  56. RESET_ADDR              = $FC00$ x" G5 Y' \8 ~9 o, R5 v% {8 U  M
  57. / w' C0 S7 z% z2 {  ?- i+ R- a* U
  58. ;==================================================. m0 Y4 Z7 A9 `$ O) ]
  59. ;图像块配置
    # ]* h  ]. O+ A/ k3 |
  60. CHR_DATA_BANK           = $087 b( H- S; M0 }, C4 m
  61. * g) o6 B9 _+ O8 }3 i: O" x
  62. ;==================================================
    , ^1 F6 P! s" J5 s! F0 t
  63. ;零页内存地址配置
      H- a* k7 H8 v# h9 }- N$ V
  64. Use_Ram_Addr            = $805 L0 X  n6 H- B2 w- h+ k2 L" `
  65. PPU_Ctrl_Buf            = Use_Ram_Addr; K: u( T- ]- x" G0 Z, S
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01, F5 F4 q5 j* W
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    ) S; Q0 @* k% k
  68. PPU_Scroll_V            = PPU_Scroll_H + $01+ [$ x- p8 [( k! d8 m
  69. FC_Data_L               = PPU_Scroll_V + $01
    # t( Q( B. f, |/ @/ z7 h3 ^
  70. FC_Data_H               = FC_Data_L + $014 N" J5 t6 w( ^# M
  71. FC_Data_Buf             = FC_Data_H + $01
    2 e# }9 O2 e7 N( i7 d
  72. ;==================================================  _$ j9 p; G1 j
  73. 0 f) |$ i$ m7 L8 q0 d
  74. GAMEPAD_MERGE_FLAG = $04( Q) f6 m8 H. y

  75.   @7 N1 ~& j9 f+ j3 E: w0 s
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    4 S4 \7 R; ~# v* |# K
  77. Gamepad_Once            =       Gamepad_Keep + 25 |# s1 ]( t( k, x; H9 H
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ) g. c1 B9 T5 F9 z0 p* \
  79.                                 
    " n- V( q9 R$ y% l6 x% a0 a' p
  80. Gamepad_0_State         =       Gamepad_Temp + 26 L# j( {5 w" P# R
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    ) p' I& n/ b4 A0 }; a" a# @
  82. Gamepad_0_Value         =       Gamepad_1_State + 1) [7 c* d* y8 [5 K2 Q
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    9 R2 g0 J9 a: [4 `/ J
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1. u6 l5 }" N( d0 a- H/ P
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1$ n+ S8 U0 h# \/ t- S
  86. 8 e. E: d: C3 s% F# \
  87. ;==================================================: c! E: V3 E* j6 C' G1 l! A
  88. IRQ_Index               =       Gamepad_Merge + $01
    / ?& O/ e. ^6 S$ G6 V0 C# w9 j. l* E! H
  89. ;==================================================
    # e1 ?* [' |6 L" F

  90. . m; m! I, R5 F7 H
  91. ;CHR图形数据: k! L6 E4 n! F4 B' B/ _" R) {
  92. ;==================================================& e  Y6 z7 e4 a' J4 U! b9 o
  93. .BANK CHR_DATA_BANK
    ) D6 B/ g8 h. r& e' ~( ^
  94. .INCBIN "chr_bank/chr_data.chr"' I: s1 a+ m) z0 H+ L
  95. 7 W3 U: a% ~2 \: P' f9 c0 x
  96. .BANK RESET_BANK & BANK_DATA_MASK+ T; D# [5 S8 Z1 u4 N
  97. .ORG RESET_ADDR
    ; \) S1 ~3 z" V% I, h
  98. " K) e* }: Q& c7 p: }9 G7 l0 }: J
  99. ;--------------------------------------------------5 _7 o$ b1 G  @
  100. Attributes_Data
    9 a" z' l' `2 j1 B1 ]+ k9 D
  101. ;命名表属性
    & P* D) R% d% W4 p7 J' c6 ^8 Z
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    , X' J, e: M5 g, }
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA. B, m9 A% R: m1 m9 n" L
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    - ]3 Q4 Z3 o9 r
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55) B4 {- L, g" F$ e
  106. ;--------------------------------------------------
    , t0 d! ]. S/ u% n# k
  107. ;调色板数据$ G; c* t/ ~& r
  108. Palette_Data- L/ a. t( v. o) V- k  P
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    1 A8 T4 ~. R/ h- a! V& E) o
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    % o: M  N2 s- E* x! J) \6 l3 f/ j
  111.   G% n: J; o% O* t0 I
  112. ;==================================================  v! I/ S( s/ Z* d3 `" \2 a
  113. ;命名表初始化
    0 T7 q7 R1 ~* P) ?* _, `
  114. Init_Name_Table
    $ J$ K$ e! {* ^
  115. LDA #$20- I  P& a2 ]2 u
  116. STA PPU_ADDRESS0 t; Y) t  d8 M: H6 ~
  117. LDA #$007 l3 I2 g6 [% c/ }
  118. STA PPU_ADDRESS6 t, }. O  t1 e9 P# ^- P6 ~
  119. LDA #$001 v  T. D- \6 a6 r8 y. w- g
  120. LDY #$00' r: `1 m" n3 @" L" U# M0 M  ]
  121. LDX #$109 w% t* d& P. R, X+ q7 |# N
  122. Init_Name_Table_Write1 l; r( p- I: b' o4 V! L9 L3 X; _
  123. STA PPU_DATA8 g; O: W- I, T+ C! e1 T( ^
  124. INY
    " ~+ `' }6 n. X- G1 m: \/ z+ r4 W  `
  125. BNE Init_Name_Table_Write( e9 w  A$ d: c' t5 ]
  126. DEX
    , X4 k% f0 Y+ R9 O; }8 Y2 a
  127. BNE Init_Name_Table_Write( E% @: [2 m& b- z  M4 `: d
  128. RTS% R- W  I. |9 O( ]

  129. 5 h7 ]0 N) T3 k
  130. ;==================================================  b/ O3 ]- j' L0 C6 ^
  131. ;调色板初始化3 F: |  Y$ A8 S" V
  132. Init_Palette
    # F9 j& x, ]* C4 }7 F2 ~+ S
  133. BIT PPU_STATUS
    6 h8 c, Y( X1 S1 O
  134. LDA #$3F7 J# X0 j# Z# W
  135. STA PPU_ADDRESS: P) \! B2 a) ~, i+ ?3 b3 q
  136. LDA #$00
    ! J/ m9 E* y9 I. `. C
  137. STA PPU_ADDRESS
    7 _- Z2 z4 U# B3 L8 o' l
  138. LDX #$006 h. ?! R7 ?" ]& Z% C# N* f
  139. Init_Palette_Write
      Z4 {& e9 ^5 a" E# O
  140. LDA Palette_Data,X
    $ P7 k5 N0 k# d9 Z6 p
  141. STA PPU_DATA
    ' o- p( g/ I  m7 v
  142. INX
    ' z/ L2 |& f5 {1 L( i& M7 L: R
  143. CPX #$20
    ( l+ ?" x, e$ H& |* `8 p
  144. BCC Init_Palette_Write
    - R3 l- e3 c$ b# _, {$ N
  145. RTS
    6 ^6 o7 q4 ^# Y7 j1 c( C
  146. 9 u- _2 I+ @, B, N& C
  147. ;==================================================. K7 q& \5 C6 R- R: b* U$ F, P6 K4 v
  148. ;设置命名表属性2 X5 Y1 }& }( g7 Y' b( z2 r
  149. Init_NameTable_Attributes
    8 ]; u0 K/ m* m
  150. BIT PPU_STATUS
      s# Q, c9 E% |1 |+ e  G# f" p
  151. LDA #$232 I4 T% I3 z7 c& Q5 v
  152. STA PPU_ADDRESS
    , q4 H3 a! ?" s8 c; b6 \& i
  153. LDA #$C0( V- B$ R( u# X; C9 ^, G  O
  154. STA PPU_ADDRESS
    + L# o+ j5 @' B2 Q" ^" {5 }
  155. LDX #$00
    . ]! }( L% c$ ^% W% q6 L
  156. Init_NameTable_Attributes_Write
    - U. y9 Q+ X! [8 g8 n0 d+ G9 V
  157. LDA Attributes_Data,X
    ' |- \, x! I' h/ x+ v
  158. STA PPU_DATA
    + a; ?2 Y( w4 `) W( W
  159. INX
    . P& ~: O1 t/ h, N
  160. CPX #$40
    : \, l% K- U$ }: t
  161. BCC Init_NameTable_Attributes_Write6 |% n% `9 x& I" k& q# ~
  162. RTS! V4 V, Q% D5 _6 ^  u8 l+ Y3 V! e: a9 B

  163. ' Y! f5 i' j9 z# ]
  164. ;==================================================9 O! K$ {+ e3 X+ i' e* I1 U% G
  165. ;初始化命名表文本& o. a* J( V; s5 b( D, v& c
  166. Init_Name_Table_Text
    1 J( A! i  |# A/ |
  167. BIT PPU_STATUS
    0 ^- I3 f3 ~) F9 n
  168. LDA #$20! w0 z+ p6 w* M' @$ c% k
  169. STA PPU_ADDRESS
    + ?! d- v6 C) `
  170. LDA #$00. L! w3 `: a; s2 L1 i' W
  171. STA PPU_ADDRESS' a) A/ h$ G$ S5 r$ s  Z
  172. LDA #$00- ]* k' ~1 {. }! j+ _5 ~" ~! y
  173. STA FC_Data_Buf1 s3 m4 V$ p9 O8 v1 t7 L* r
  174. LDY #30
    ( g$ X& @% H6 ~4 f- p7 V6 `; I
  175. Init_Name_Table_Text_Write
    ( N8 f- q8 b# n
  176. LDX #32
    - b* A' m# c* m* B  j
  177. Init_Name_Table_Text_Write_Char5 ^$ G* t0 v) ^3 o- ]" j7 K
  178. LDA #'0'
    % S8 O* a0 K3 r5 `) {. d7 b5 i
  179. CLC
    + x% K) |/ i7 H9 I5 ]) ^4 X
  180. ADC FC_Data_Buf8 K* c& X, f! G, w! s
  181. STA PPU_DATA! W1 A# _4 o% }$ S. P; ~
  182. DEX
    . L' m5 r+ ^; u7 C' H
  183. LDA #$14: a2 j) k% m2 O& I
  184. STA PPU_DATA# d" g  K8 U' F. n
  185. DEX
    " _/ R: k3 l* y9 U
  186. BNE Init_Name_Table_Text_Write_Char2 x2 V  N: H8 M
  187. INC FC_Data_Buf
    * S9 @- }: A; O" Y* d
  188. DEY
    & I/ S) L5 ~; b
  189. BNE Init_Name_Table_Text_Write
    ! F. N) w3 }2 O' a
  190. RTS5 k7 {& C: Z0 o. g

  191. * U) k) X2 p7 c- h- C2 h) ^! Y+ v
  192. ;==============================6 y- z# ?: \" q, W
  193. Init_OAM_Ram;初始化精灵内存
    1 `7 W0 F: f8 j) O+ |) g# ^# {; R
  194. LDX #$00/ e' l2 M$ ]& F& i: q' X' `
  195. LDA #$006 m1 x: k  k8 |6 y) b) h
  196. STA PPU_OAM_ADDR
    ( Y& ^& w& r# ~7 u8 W0 p( Y
  197. LDA #$F8
    ! u6 ?( q: e( y
  198. Init_OAM_Ram_Write
    5 e" |$ A' w+ m' _1 \
  199. STA PPU_OAM_DATA
    , H) [3 ?' N0 ~
  200. INX
    , o* ^7 O, v  a8 X7 B: t
  201. BNE Init_OAM_Ram_Write
    1 p9 K4 [1 Y" n
  202. RTS' j5 d4 U0 t) P- k! y/ q9 E6 t
  203. 9 Q) u$ F" w6 N: Q3 ^( {+ |
  204. GamepadProcess;手柄处理+ u( U1 Q% F" o
  205. JSR GamepadDatacan$ e& ?2 d0 w* ^, v/ M6 F
  206. LDA <Gamepad_0_Value
    8 b7 j! ?( s  v: ^+ U; W0 P8 U
  207. STA <Gamepad_0_State
    5 B) l( H& _) f& z% ]- {; m, B
  208. LDA <Gamepad_1_Value$ |- j0 Z3 P7 o4 n! `6 V
  209. STA <Gamepad_1_State
    / L: W4 @; z; V, |5 ~- x
  210. JSR GamepadDatacan1 I( u: y* g! f& ~1 y; C
  211. LDX #$01
    1 v: t: ]( W3 S: S
  212. GamepadMergeCheck;合并手柄输入检查. b: |) D8 w) }+ q9 a( u% `
  213. LDA <Gamepad_0_Value,X2 \, i% p+ |% B& Q3 f/ S
  214. CMP <Gamepad_0_State,X+ _. t5 n' F' T1 K
  215. BEQ GamepadMergeInput; }( K/ j; D( E
  216. LDA <Gamepad_Temp,X# a! z/ L. n& R& W. B
  217. STA <Gamepad_0_Value,X* B% z4 Q, H* E9 r' z" Q
  218. GamepadMergeInput;合并手柄输入
    9 m9 V7 k# L( f' w; b. k2 p
  219. DEX% V  r' G. R  U2 e
  220. BPL GamepadMergeCheck
    . Z& D- Y: `: D  X4 C
  221. LDA <Gamepad_Merge
    0 E. \5 y- u! E3 N9 u* v* ~# ]
  222. AND #GAMEPAD_MERGE_FLAG6 Y4 q! _) a0 E. Q- i
  223. BNE GamepadStateProcess2 ?1 `8 Y7 F% Q! V& K$ t3 O* y
  224. LDA <Gamepad_0_Value# x3 ~; G5 z: ?8 e, I& E
  225. ORA <Gamepad_1_Value3 k* x: v' t" P  T9 S1 n/ Z
  226. STA <Gamepad_0_Value  Z, ^& l. B! I
  227. GamepadStateProcess;手柄状态处理
    1 g* q- a* m9 z( f/ I1 Q7 K2 R
  228. LDX #$01
    ! c; r2 {. ^! E+ V7 J2 @* g
  229. GamepadStateSave;手柄状态保存
    6 l- T7 n( _  u) W6 U: Y
  230. LDA <Gamepad_0_Value,X
    ! y% }8 A+ \; \# ?
  231. TAY
    $ t1 Q& x2 [7 h- d, ]
  232. EOR <Gamepad_Temp,X
    3 m  ]! q6 h4 {$ \! s3 B! C* ?
  233. AND <Gamepad_0_Value,X
    # T- ?! ]/ n% Q" i. Y% r4 f
  234. STA <Gamepad_Once,X" J  F! N2 [# Z( z7 C2 l$ X  K' B
  235. STY <Gamepad_Keep,X
    0 _' e& X$ E& I0 a
  236. STY <Gamepad_Temp,X8 B& b/ C4 D3 H, R: \; g
  237. DEX
    : x1 W1 t; B% c2 K' y, t, C' R4 P
  238. BPL GamepadStateSave) b: o2 X% Z8 P& t9 B8 m
  239. RTS
    . u* ]* B9 h+ F2 j2 h/ V' U
  240. & }/ K  M, A" |( J* D* h2 A
  241. GamepadDatacan;手柄数据扫描6 N; F6 m1 Y0 x( I, P% f1 g
  242. LDX #$01
    0 X  B3 t. b4 B# ^) v
  243. STX $40169 {5 i7 H' z4 ^% f, {& W' M( S
  244. DEX% L8 o( m% R3 N6 T; _! _! r8 e
  245. STX $40162 O+ ?- Q& G" s( U$ m8 y8 _
  246. LDY #$08' x* i0 @# Z* G4 ]. F: F6 N
  247. GamepadPortScan;手柄端口扫描
    & M3 \1 S& Y# V" ?* q
  248. LDA $4016
    ) o+ S" s* p( X$ A
  249. STA <Gamepad_Port_Value
    & B7 v  w+ V: E
  250. LSR A
    ! U4 _3 h" ^' T/ H
  251. ORA <Gamepad_Port_Value) o0 J" C+ ?2 v* G
  252. LSR A
    : ]/ T+ \8 w3 J/ t7 K
  253. ROL <Gamepad_0_Value
    ' u+ T6 x8 P! I6 ~6 _3 G% o
  254. LDA $4017# B" S+ S, u/ G8 j) I
  255. STA <Gamepad_Port_Value  c) I# |3 P6 W8 ~2 o( x7 K
  256. LSR A) l5 Z$ C* L# g) \' T
  257. ORA <Gamepad_Port_Value, g4 m. T6 p1 M( J' [7 P! f1 T4 Y
  258. LSR A
    ; e# Z/ E" w; ^* ~  I
  259. ROL <Gamepad_1_Value$ L9 K! U" b" f% w" c3 g; _) [
  260. DEY" J' ~9 g) X/ L7 G' I7 x5 V% I
  261. BNE GamepadPortScan7 g3 M0 G8 G+ k7 `
  262. RTS" f; m" p( G# S, _& C5 A- `
  263. ; |& s' |* x6 L
  264. ;==================================================' e) w+ B8 Z4 L  X# b
  265. ;PPU处理
    0 w, T) f5 Z( P
  266. PPU_Process
    $ O% o- w0 E* Y! n6 C
  267. LDA #$00( @+ B* }+ e. Z9 o4 R0 A) C0 L, u
  268. STA PPU_MASK  A& r' c2 y0 w' [) |/ X! @; H

  269. " N( t* ?5 N& _8 l$ n# K8 J/ J
  270. BIT PPU_STATUS
    % f2 [7 h) h* k9 r8 K2 w
  271. LDA #$201 J% [% s4 q, {3 y7 w& G3 |
  272. STA PPU_ADDRESS
    ( ]- n# s+ d: o  f6 [
  273. LDA #$00
    % z2 p6 U& N; T7 W9 }
  274. STA PPU_ADDRESS
    2 v) g! L  w, I0 l) I
  275. " K/ X6 _. c& I+ G
  276. STA PPU_SCROLL8 L1 }, O1 O6 p  }0 N
  277. STA PPU_SCROLL
    : [7 ]& X. [! d  Q6 E* w# w
  278.   |9 S' W, U! y# h0 Z8 |' @; t
  279. LDA PPU_Msak_Buf
    1 R' _2 `6 n- U# ]" X7 E
  280. STA PPU_MASK
    ( |9 `+ N: M% Q) r( x6 J
  281. * A! l8 G0 \- ^0 r8 v$ g
  282. RTS
    ; X' `- I3 F6 m& y) y

  283. 7 g$ p4 z2 Z" E6 Y1 m8 `- P+ H
  284. ;==============================
      _7 ]% G$ D& t
  285. Time_For_Vblank;延时等待2 i, e. T3 j( H& C
  286. LDA PPU_STATUS
    / x. q' F3 l7 W1 N  P! x
  287. BPL Time_For_Vblank) Y- U; X% D3 u+ P$ S. b% L
  288. RTS* I# a0 p7 x8 n
  289. " Z9 u6 d# a% G: \0 x0 k$ f
  290. ;==============================5 Z! P6 e, W8 J+ ~0 D
  291. ;初始化MAPPER19
    9 H$ ?' K+ O4 u
  292. Init_Mapper194 i6 d) c9 P: z* X
  293. LDA #$00
    # k9 a& C1 L3 k3 l. d
  294. STA M19_CHR_0000
    + L8 d, ?) L; n* l) F# A# a
  295. LDA #$017 d( k: h& u2 G5 P
  296. STA M19_CHR_0400
    ) Y8 N1 m3 G- P; B/ O7 p
  297. LDA #$02
    $ |) a3 {4 e3 c- X
  298. STA M19_CHR_08003 u# t5 b, r/ z1 V$ D/ h+ \) |
  299. LDA #$03  S% N. Q3 [' W4 U
  300. STA M19_CHR_0C00# a4 e5 _4 y0 g9 U) v
  301. LDA #$04
    3 u7 {- N6 t. c( K' J8 U8 W: @6 q
  302. STA M19_CHR_1000
    . @4 R( e! I- _7 v1 Y: h
  303. LDA #$052 n. Z  h! h4 H$ ~# `
  304. STA M19_CHR_1400, G7 A+ s$ j5 X, p4 b
  305. LDA #$064 r# t1 V% ]) r
  306. STA M19_CHR_1800# [( m, o2 u0 R! a3 P
  307. LDA #$07  |3 Y' g: _( k7 a5 ]' D8 Z
  308. STA M19_CHR_1C00
      x  I2 {. |4 |- m

  309. ! `. f, l5 L" a
  310. ;禁用IRQ! w0 Y2 q% e5 l; K. |9 s: G; x
  311. LDA M19_IRQ_COUNT_H1 e) R9 O7 B0 N; n2 z
  312. AND #$7F% O7 C$ F0 S* X
  313. STA M19_IRQ_COUNT_H
    ! H2 r- q; V" S* O1 P' `
  314. * v& O# K* K$ [
  315. ;命名表2 r$ D2 b. p) C1 u# ~& b' |! n
  316. LDA #$E0$ h6 h7 I: c- m
  317. STA M19_NT_2000& F9 C; l) K7 _
  318. STA M19_NT_2400
    ; \) r4 R* @) d( y
  319. ! `) u5 J0 e! l5 _$ R3 F
  320. ;命名表
    # L# J1 s4 i+ q4 B$ u# `/ a" Z% W+ Z" j
  321. LDA #$E1
    ( L3 ~( R1 L& R$ H6 F; @
  322. STA M19_NT_2800" c, Z2 O# `% T
  323. STA M19_NT_2C00
    5 J8 s5 K& ~, l6 ?( E" l8 j% ~
  324. # k# O: i" q* i: z5 ^  H
  325. RTS
    8 h  M2 G" P" D0 P( e& O( G" V

  326. 7 |( g, E. ~. D2 B
  327. ;==================================================
    9 o1 [, L# ]! R) P0 J, J- _
  328. ;重置中断处理9 d, _- [+ V+ p" k; i# P. U% N/ [/ u
  329. ResetProgram
    8 r) m) `) Y4 T! u
  330. SEI# ~8 k- a+ g1 H4 E4 A* r# V
  331. CLD5 u: D6 G5 S, \; S+ J* k2 Z
  332. LDA #$00- w( q, `" ~9 Y, Y7 x3 y0 O
  333. STA PPU_CTRL
    7 _. m8 Y' a5 x& \+ w1 s
  334. STA PPU_MASK
    " o  o% G/ o7 w$ ^5 O2 ]- G
  335. STA PPU_STATUS* P3 V# k9 W7 R+ W1 d: I" j
  336. STA JOY2_FRAME8 q8 \% W' f/ H: K9 x
  337. STA APU_STATUS  E9 E& ]8 f+ R' H

  338. 0 I8 B# R3 Y- z7 H# l
  339. LDA #$C0" M- w/ C) k8 m
  340. STA JOY2_FRAME( K/ ^9 W7 d, Z& N9 I
  341. 4 M$ {2 G1 q% z7 D) m  S; f
  342. ;等待vblank
    $ D# _. u+ [4 W& k2 `! {
  343. LDX #$02
    ) B# f+ V7 G8 h, _% Z. @* a4 C$ n( P
  344. Vblank_Wait_1
    ( i; D) T; A) q" K+ f
  345. BIT PPU_STATUS
    / |3 I& M; Y2 x1 `9 G* }2 N
  346. BPL Vblank_Wait_13 o% d) }2 j0 J/ N
  347. Vblank_Wait_2! t0 g& o  m+ {5 j) d4 j& J0 t
  348. BIT PPU_STATUS
    3 T. ]1 g# K* E- c+ T
  349. BMI Vblank_Wait_27 S3 G0 B7 Y; [4 R; l: n1 P
  350. DEX" x  r0 A. m7 C; k5 G4 G3 |
  351. BNE Vblank_Wait_1
    % K1 u, d, A9 U1 H0 Y
  352. 3 n$ w  A5 q0 O6 p2 f' c
  353. LDX #$FF
    + k* P7 k/ r) G9 h  P
  354. TXS
    % ^4 I0 D( P- Y3 e  o+ i1 k; p: e

  355. 9 t( B0 x4 E8 @/ F0 _- V7 c
  356. ;初始化MAPPER19
    / O7 y; a/ `2 `: P* x1 ^) I
  357. JSR Init_Mapper19: }6 z# R5 s$ x3 W

  358. 5 s+ M; r- Z5 l
  359. ;==============================
    6 m$ o7 \0 k& F) |, ?* M4 G
  360. ;RAM初始化/ c" I) I+ W8 G. i
  361. Nes_Ram_Init3 z' t6 \4 P% U& c( D$ v3 o; ~
  362. LDY #$00
    6 U" ]9 K* E% V
  363. LDX #$08/ ?6 m4 |0 ^! g+ A
  364. LDA #$00
    * n* z& v4 c: O. o! Q+ A
  365. STA <$00
    6 e. b$ O6 c+ R1 u- m
  366. STA <$01
    9 H. N0 I% k) t9 K' \8 @
  367. Nes_Ram_Init_Write; m4 z+ Q" w2 T0 D: E
  368. STA [$00],Y7 @' x6 f% |7 x- X
  369. INY" N8 H) F4 d" j1 ^" z- s
  370. BNE Nes_Ram_Init_Write
    . V6 j) ]; m4 l+ b
  371. INC <$01
    * k5 Q& O$ P% K3 Y$ ^- Q
  372. DEX0 Z/ |% \. ~3 b7 _. t/ P* p  l
  373. BNE Nes_Ram_Init_Write
    ; A7 V; f$ l% {

  374. . f* _+ ^5 c: ]/ q6 G. W9 y0 T2 a
  375. ;初始化命名表# B7 x. c( a3 a$ @
  376. JSR Init_Name_Table
    , R% J* m9 W! T3 `7 r$ J9 Y1 i
  377. 6 B; u% v& D6 A: _6 L2 b( n1 b
  378. ;初始化调色板) v" W5 P! e' O& V! [0 H+ s6 v$ W
  379. JSR Init_Palette
    . c6 W3 B+ g$ |0 w

  380. ( C3 p3 \* _4 N
  381. ;初始化命名表属性
    + e: R# H# |+ m8 [" [! C
  382. JSR Init_NameTable_Attributes
    ; l: X9 f/ N3 j2 I" x

  383. 2 P' J6 J/ z6 Y! S
  384. ;初始化精灵内存
    - A* d7 q9 I; F: C+ m
  385. JSR Init_OAM_Ram
    2 G; S0 H6 Q6 F- G
  386. # N$ L; q% {' y4 y; v$ S
  387. ;在屏幕上写点东西
    3 i  H0 _( ?9 ?( G
  388. JSR Init_Name_Table_Text+ W1 z: R9 W3 |% n
  389. 0 H% [/ L! I: O+ ~
  390. JSR Time_For_Vblank0 l. L) J+ Q# c. K* a- v1 A4 P
  391. ;开启PPU控制
    $ K6 R) v9 [( f7 Q0 }8 t
  392. LDA #$A8
    - p' W, H# u8 M9 ^4 [# C$ d3 H
  393. STA PPU_Ctrl_Buf" O9 G1 T; h9 J! {; P3 D
  394. STA PPU_CTRL
    3 _  d, y  _( x# M# e! P

  395. # s: ]: W( ?9 P$ v  J0 K8 ?$ k" i8 m
  396. ;开启PPU显示) p, R  I) d- f
  397. LDA #$1E5 m6 H8 S. q; _0 v- N% d+ J0 ~- a/ Y
  398. STA PPU_Msak_Buf
    8 R6 l8 f8 j! a; d0 O
  399. " J6 V! u2 A, ?3 Q
  400. CLI
    9 O2 A* z" t  i$ n( A* K; m$ N. q1 p
  401. JMP Loop4 v* n- q' G7 B5 m/ y
  402. ' G1 H3 F  `4 v3 Y6 c3 |
  403. ;==============================% B' k5 m  C9 f5 c( H
  404. ;死循环, 等待NMI中断) A' H3 U1 [1 m
  405. Loop9 S! s3 n' P' c0 P( l2 {
  406. JMP Loop% V! |8 W3 ?) k; q0 @

  407. * e0 i' e2 t" C
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    1 A: t, g5 C/ k* W8 G

  409. - }5 c0 F$ O" L* ]- j* g
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    1 Q: h) C4 A4 @) V; r" Y- v" T
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    ; [$ {6 N( `* I2 Z. W9 k- u( a; c# A
  412. ;==================================================
    ) F3 L0 G5 l: I: C: X
  413. ;NMI中断处理. A8 s( Y3 x7 o8 S% o
  414. NmiProgram3 z3 f' c0 R2 I6 o- Z' h( m
  415. PHA, h, t2 \6 W1 n( v% o  H  f
  416. TXA2 R/ I7 f+ s- }# ~1 l0 G6 K  ]/ R
  417. PHA( O, K( [( m. N" i- v3 w0 a' ~5 B1 C
  418. TYA; {( \4 k5 G5 ~2 V+ R8 L$ k8 G
  419. PHA
    % r: p2 G0 J# _; |% _% _

  420. 6 I3 m) ]. O4 f& }$ r  D7 T8 l3 K
  421. BIT PPU_STATUS
    0 T9 E1 }3 `/ q- E; W7 F) [
  422. # i- b2 J$ W, X( d3 t
  423. LDA #$004 _* Q! f) F1 P0 V6 {
  424. STA IRQ_Index# x6 U) `- O" j+ ?# w# o0 ]0 M/ ?
  425. + o9 L$ z1 Q( G6 t! T) ]: D6 F4 T
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动1 f. _; b3 R9 l' @1 _0 b9 X, S" [
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    % s+ y* ]! S: L7 R2 I' T+ L
  428. STA M19_IRQ_COUNT_L7 o  G; i4 R% P5 Y9 k
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START): |2 ?7 u) ?) `+ m( s: Q
  430. ORA #$804 M! f  E/ u- s( b3 Q$ v
  431. STA M19_IRQ_COUNT_H
    + ]! ?* @! T2 t  N- D$ ~
  432. CLI
    / P+ ^5 N/ b% `8 k- y
  433. ) [  K# ^. `  o6 I
  434. ;关闭PPU控制
    . ]1 u8 f8 \& ]- A& `
  435. LDA #$005 z" k/ |; `$ k/ @+ S9 ^4 B
  436. STA PPU_CTRL& f/ M6 Z5 |& X$ I1 G3 ]& N
  437. 8 r$ L0 N# S1 p1 i: Y
  438. ;处理PPU4 v8 R' K6 o& B0 `6 G- e
  439. JSR PPU_Process
    * V# _5 ^% U( B8 E2 G

  440. 7 O" E$ P* v; [- N, K& f( ^
  441. ;开启PPU控制9 L% Y  |% p* [( a8 q/ u0 c8 w
  442. LDA PPU_Ctrl_Buf$ O$ K! X  }1 i+ e9 Y# T# R9 |
  443. STA PPU_CTRL) A0 j- H' q6 |5 T* a
  444. : `! f9 V' F( k3 r: X/ H* k
  445. ;手柄处理
    5 W0 s3 }0 Q+ `. m
  446. JSR GamepadProcess
    / F3 M) Z: q2 |

  447. $ p( _1 f5 D$ v3 k5 c
  448. LDA #$00
    : r; g5 e+ {0 @  \0 S
  449. STA IRQ_Index
    3 H" U: q7 Y: K5 N  Q) k" ?2 |
  450. * T3 H9 g+ n# H) {5 o) f) I+ B8 B
  451. PLA
    0 m! L0 b% \9 G! |+ b7 c* o$ V
  452. TAY: @8 E7 w/ R) O8 a# e
  453. PLA
    % Q" A1 `" h. l) n
  454. TAX6 [3 u2 _9 y! f
  455. PLA  Q* M2 F; w* k) ]
  456. RTI4 a9 t" k" M/ X. C5 \: s5 W, t

  457. ! Q+ l) g- n+ u( e
  458. ;每行扫描线113.67: i. U2 u: T$ m, B6 O* V$ w
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967). q: d0 X  }! v# K7 Y+ u3 G
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7+ l2 I; w  w: ^" S/ ~8 N
  461. ;==================================================& h! z- ^" Y0 r6 O0 W# A  {
  462. ;IRQ中断处理
    6 S) D- `$ U+ Q$ w; ~
  463. IrqProgram
    . `0 S& b3 j# y
  464. PHA
    7 D2 m  z, r, y$ P% ?4 y4 A
  465. TXA7 f& u0 o  H& K2 [; E% M, h
  466. PHA
    & S2 ?: ^! t) s" @! i5 n3 z
  467. TYA  p9 \1 n% @0 P, E+ O
  468. PHA
    2 j! n1 x  m  O  p$ a

  469. $ v8 E3 M' M/ C- |- `* c
  470. ;16条扫描线后触发IRQ: f" \& B- V9 T. w/ R
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    % _, h! U" h5 Q/ i+ \
  472. STA M19_IRQ_COUNT_L
    * t3 [( C+ g7 A9 r! S& o
  473. LDA #HIGH(BEGIN_LINE_CYCLES)
    * h2 P* z8 }; y  j$ r; n5 }' K
  474. ORA #$809 s* B3 i' s, f  W
  475. STA M19_IRQ_COUNT_H
    8 i0 ?; B; ]- H2 g- K
  476. 2 H& u  z: H! [: |
  477. LDA <IRQ_Index
    , D$ a& M  B9 W* Q
  478. BNE * + 4
    1 [- l" H- z: d9 f. u
  479. INC <PPU_Scroll_H
    2 R( G+ b! ^# b1 ^& a3 b
  480. " b+ C( g1 ]" Z5 `. H; R
  481. ;设置屏幕滚动
    6 Z, L) e% c9 Q6 C4 q8 L' h1 }; `
  482. LDA <IRQ_Index1 J/ [1 I! Z  O! r3 a; D8 p
  483. AND #$01
    2 k7 E& }" R2 K- b& A* F
  484. BEQ Irq_Scroll_Right6 Z0 B6 J" O, Z- G
  485. ( K4 ^' ^! W: F
  486. Irq_Scroll_Left# Q2 t% `4 ]" Z3 M9 L  d  t6 \
  487. BIT PPU_STATUS
    0 Z! y2 J: E! X, W2 f- T
  488. LDA <PPU_Scroll_H' v  t, ?+ H6 T7 h5 I7 z
  489. STA PPU_SCROLL
    4 R  P, c& _0 m! R; `
  490. STA PPU_SCROLL$ Y, P- K7 j- V: M# X0 T
  491. JMP Irq_Scroll_Over* f; z) e" W+ }: Y, ]

  492. 0 ?. V/ B7 ]5 Y; }; s2 ?8 L
  493. Irq_Scroll_Right* g/ o  T, e6 ?4 c
  494. SEC
    / W; Y1 H8 V* H% J6 x
  495. SBC <PPU_Scroll_H
    " Q7 ?$ k2 N! X/ y' Y
  496. STA PPU_SCROLL  T9 u/ `7 D4 g3 k3 W( L
  497. STA PPU_SCROLL3 [# w4 u, g( k; e( j
  498. Irq_Scroll_Over8 T7 D% h) ^# {& c
  499. 0 C& e# P6 X0 G% a3 P  J3 s% X
  500. INC <IRQ_Index' G6 O& c& v1 N2 y
  501. 0 p; T0 V8 V" o$ q& x
  502. LDA <IRQ_Index
    3 [* n9 E7 M7 N( }- B* E
  503. CMP #14
    ; b! b1 h  `& r
  504. BCC * + 10
    - W) S1 q7 P; V
  505. LDA #$00) b4 K5 {% c. }" W' T; X" e  s
  506. STA M19_IRQ_COUNT_L
    4 g0 h& j) N. v8 D% [; S
  507. STA M19_IRQ_COUNT_H1 s: y' }9 U4 o* N. \
  508. 9 b( k$ Z- Y5 D# O5 T
  509. IrqProgramEnd
    : q4 v, W9 j4 |/ k$ k, T2 |
  510. PLA- t( t: U! q/ k+ B6 ~- v( V
  511. TAY
    7 d$ a& `4 N$ d2 t" n# b2 O6 H8 ]
  512. PLA0 X3 m' D0 Y! g9 s; k2 D
  513. TAX
    0 e. A9 L: w, W9 e
  514. PLA
    7 h& b2 y3 B3 f5 M- v
  515. RTI
    ' {7 y, l8 w3 l7 m

  516. - q$ v- _4 \; c
  517. ;==================================================- l6 i0 ~  R' G1 a
  518. ;中断表. p; ^) O, F! ~/ K2 Z2 l4 y
  519. .ORG $FFFA. ^) W# |7 h7 B, R! M$ y6 W
  520. .WORD NmiProgram6 d- _+ S7 d3 o
  521. .WORD ResetProgram" u0 ^4 T9 ?* {+ i
  522. .WORD IrqProgram
复制代码
9 z2 p& z& L* R

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-12-6 05:42 , Processed in 1.087891 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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