EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    . N0 V4 d4 q/ A/ @
  2. ;FlameCyclone 20230710
    3 C" o/ S+ c( M/ J

  3. 5 [) o" ]7 c' s% I' h
  4. ;文件头: ^" r+ w- r% M' n
  5. ;======================================================================" e" \$ l: L& P' n& S' S. E
  6. .INESPRG 4                                              ;16KB PRG 数量' M" Q0 Z0 R% H! V: a+ Z6 H
  7. .INESCHR 1                                               ;8KB CHR 数量
    - }$ s3 @! P1 Y" j
  8. .INESMAP 19                                                 ;mapper 19
    : X5 E! i$ \1 {9 T% z/ X( x- P7 U
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    * R2 x# L: k7 J! B
  10. 8 c/ h6 e( d4 i7 \
  11. ;必要条件
    ' T) @, ~2 P/ w' a2 {( G
  12. ;1.持有CHR ROM
    * s$ @2 P6 k) S2 e' Z
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    # e. @' F$ a4 B1 Z& {; f. D
  14. ;3.精灵内存(OAM)不为空8 d) S" q$ E+ d1 d* v: G$ F4 E& G

  15. & f2 p2 ^. x  [5 O7 Q
  16. ;==================================================
    ( G  v+ i, f/ R, O
  17. ;NES端口常量
    3 p6 Q1 _7 E# P
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    1 _* n. O* a" ^$ [; H4 k
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    ) K) Y# Q: ]' x0 L9 s  `' c1 C1 r
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位" U( e% K7 K6 ^8 k2 Q
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ! l, o$ ~6 i" {
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    4 X+ T9 K, H, k9 R
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    " L2 f/ b' b( w7 {3 ~7 [/ ?
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    + ^/ r: C0 |) i$ ?6 \3 N% r
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    * h) K, H  X4 [: b+ z9 G: Q& b( j
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    " k  B5 n! s7 X, r% G8 u
  27. APU_STATUS              =   $4015   ;声音通道切换# [4 R9 e- ?3 y
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通3 w4 C; ]; |: @4 O7 ~7 a3 `: e
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通- v) S% s! \- o) ]/ E
  30. - R6 y7 k  y+ O/ `7 K# w; a2 m( g
  31. ;==================================================& j* l& O* T6 j* \
  32. ;MAPPER 19端口常量, ^) f3 {0 `0 K. m
  33. M19_CHR_0000    =   $8000$ q. f" L) b. A, A; Y! p
  34. M19_CHR_0400    =   $8800; @) }+ q: D: `" g3 J. Z. M
  35. M19_CHR_0800    =   $9000
    6 z0 G3 n) z, ?2 R+ U" f$ c
  36. M19_CHR_0C00    =   $9800
    , T  F5 C$ S' d: o
  37. M19_CHR_1000    =   $A0009 M1 Z5 u  m3 b/ z: q
  38. M19_CHR_1400    =   $A800; p. W  f$ L2 _
  39. M19_CHR_1800    =   $B000
    2 N6 F' G+ k3 i  t9 Q
  40. M19_CHR_1C00    =   $B800
    1 C- y6 w1 O  H1 s$ ^6 M
  41. M19_NT_2000     =   $C000* F+ z$ \1 e7 F9 u9 s$ Z; N
  42. M19_NT_2400     =   $C8003 G+ Q% Z1 g/ [' F* X+ p
  43. M19_NT_2800     =   $D000  }% k# i2 `1 h  k% J4 @9 H6 H
  44. M19_NT_2C00     =   $D800
    3 c9 U; j7 \7 n, N, a6 Y% S) r
  45. M19_PRG_8000    =   $E000
    ; z* s4 b8 v# [& [
  46. M19_PRG_A000    =   $E800$ f; x' \/ {9 ~/ {3 g8 U! z5 ]% ]7 C1 Z
  47. M19_PRG_C000    =   $F000
    2 K# F, y' W2 n) t7 Q  Y: l
  48. M19_IRQ_COUNT_L =   $5000
    + x1 v' ]- W$ j% k& D
  49. M19_IRQ_COUNT_H =   $5800' f+ f* v0 H/ H3 ]3 |

  50. 1 @7 T: ~; [* c0 m( b6 i+ l' t
  51. ;==================================================
    6 Y% I% w4 R4 k, W3 ?, p  B
  52. ;程序块配置5 v+ m) N8 F/ d4 E, T, t  A
  53. BANK_DATA_MASK          = $074 R9 O- l* h; \8 E: Z" y) J8 b
  54. ;--------------------------------------------------
    % S5 t0 ?. K3 T7 O- r
  55. RESET_BANK              = $07
    0 ?: U! g, A8 P
  56. RESET_ADDR              = $FC00
    ; v7 g: y+ ], f( c- r6 x
  57. ) l+ j. [& l; }# G' P
  58. ;==================================================% S) X6 N: }7 p2 c$ I! [* ^
  59. ;图像块配置
    % n! ~; f) {1 S* u# [
  60. CHR_DATA_BANK           = $08
      W2 U! D* g  T; k, H; x- i: _

  61. / ]8 b: }1 p/ b1 }- l! c
  62. ;==================================================  ]! l  V" [  Y
  63. ;零页内存地址配置
    7 q  l/ E# g( Y8 y2 X
  64. Use_Ram_Addr            = $806 a( S+ n6 S( f9 ?
  65. PPU_Ctrl_Buf            = Use_Ram_Addr$ S, g2 ]# f3 J) Z6 J) {
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01' J1 l3 v, G, k2 D) J
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    * Q& W3 ]3 I* h3 A
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    $ D% ?0 a# }3 @+ t  s& N! M
  69. FC_Data_L               = PPU_Scroll_V + $01
    ' C/ X. J, W0 r
  70. FC_Data_H               = FC_Data_L + $01% E- H9 _1 n% U. ?0 ?0 `
  71. FC_Data_Buf             = FC_Data_H + $015 `- i( s5 V  x. _3 `7 g% G
  72. ;==================================================
    / d$ G" V7 r! ]4 s3 b) Y

  73. 2 Q) y# `+ p2 n1 D; Q5 O
  74. GAMEPAD_MERGE_FLAG = $04
    : T. Y3 `  w1 o$ _
  75. ( Y$ k5 @0 w4 p; X* A) z3 U* I
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    ( f& D3 c5 r/ P% g
  77. Gamepad_Once            =       Gamepad_Keep + 2
    % W( }, F- U7 u: s) y: w# T
  78. Gamepad_Temp            =       Gamepad_Once + 2
    ( t$ e0 C2 W5 x/ u4 T
  79.                                 : q4 E; u& M4 G; A# k- W1 m
  80. Gamepad_0_State         =       Gamepad_Temp + 2- }) C3 O3 J9 @, S: N
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    + X7 x9 u% l- ~# L
  82. Gamepad_0_Value         =       Gamepad_1_State + 1, r  Q0 v6 h2 x- g$ S  q% o
  83. Gamepad_1_Value         =       Gamepad_0_Value + 12 M  M) G* C- W/ A( `
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1- A( G: B6 a# u* _& ^8 G
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    * R+ K5 a+ Z8 t3 K# r+ {2 y
  86. , v; Q' M$ {. S6 \5 \2 r; y
  87. ;==================================================
    ; U# Q( S9 m) |9 o: i; K0 [; ]
  88. IRQ_Index               =       Gamepad_Merge + $01; m4 X) B/ i! a; O# s  {
  89. ;==================================================& Y5 l; R8 U! P$ h! l. r, q

  90. 5 l0 Q; J( f1 F0 ]$ K9 v
  91. ;CHR图形数据
    / U0 I; H& J  _9 F" c! N6 P/ C! e- O
  92. ;==================================================" p3 p  v1 F* a. e5 ~& Q* ?* R( x
  93. .BANK CHR_DATA_BANK
    1 g# K# k. Q( b4 f8 x" z
  94. .INCBIN "chr_bank/chr_data.chr"
    & R) F% W' l$ m2 P1 a( @' t8 c# i
  95. 1 f7 d/ H0 Z6 n9 i
  96. .BANK RESET_BANK & BANK_DATA_MASK
    % ~* n, h' l9 {. _4 Y
  97. .ORG RESET_ADDR
    ( s% b4 ^: a& k+ E6 B( q2 n/ d- x
  98. 0 ~' T7 r3 X( \2 p& B$ p. I
  99. ;--------------------------------------------------
    8 W4 O) R7 z1 Y+ x+ b1 }! c1 b- [
  100. Attributes_Data
    , w3 r# D- i! R" }$ ^
  101. ;命名表属性+ l+ s9 B9 R) n2 _6 B$ o9 ]# J1 b
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$003 d4 A$ u* E" `. A+ u0 u6 T6 |
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA8 v; _' Q3 `5 S! B
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    % n. b6 K+ l" O/ G; G2 ?* O
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    / K8 P9 a# P) z+ a5 y
  106. ;--------------------------------------------------$ f" r1 M6 I( N! \6 v
  107. ;调色板数据9 P: R# ?, c: D- B
  108. Palette_Data! R; M: e4 P. e' a
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    1 c# K# L9 q2 [5 _  i7 n
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F6 [' o* Q/ y; ^0 T& z* m
  111. 9 S# d6 p3 l+ |1 C
  112. ;==================================================
    8 `+ Z) B; z0 ~  w! F5 u( m% Y
  113. ;命名表初始化
    9 j% j6 `4 f3 _3 {3 P0 `
  114. Init_Name_Table. \9 h& g  ~2 E
  115. LDA #$20
    * ^; T9 n0 a$ q1 J
  116. STA PPU_ADDRESS
    % }3 b1 c- E3 C1 Q
  117. LDA #$00* e1 b4 W2 {, W
  118. STA PPU_ADDRESS% D* m3 `* i$ D8 U; W, L. f
  119. LDA #$00. l' z! o. ~/ ~6 ]4 Z+ b
  120. LDY #$00- W: T- b: F. Y  q
  121. LDX #$10
    * K% H+ X5 A7 ~) l
  122. Init_Name_Table_Write
    0 ^- k+ ?- }" ]
  123. STA PPU_DATA9 }1 n! ~8 M# n1 ]- U
  124. INY6 p6 z  i: w$ X4 f
  125. BNE Init_Name_Table_Write
    # ~$ _. O' }8 \' r% n7 p
  126. DEX3 @( @% ~* Q& M3 f3 \0 N
  127. BNE Init_Name_Table_Write
    ! z$ i- `) `, E6 h6 h- m
  128. RTS" e% U  A. r8 T/ }+ t; f
  129. + B2 G( x! w! o
  130. ;==================================================
    1 U# U. p% l( {5 L  ~! m; r
  131. ;调色板初始化# a+ ]: x! y  q: T0 v% O0 J
  132. Init_Palette
    " I) I( q8 \: |4 |
  133. BIT PPU_STATUS9 }2 A: ?- c2 y3 o3 i
  134. LDA #$3F
    0 |# V/ ~6 O+ K& o0 B
  135. STA PPU_ADDRESS
    , r! M- U, I. y0 ]/ U
  136. LDA #$00  z9 R( d1 V5 m6 [/ p3 d0 |
  137. STA PPU_ADDRESS# \" l4 ~0 d& n6 l+ p# E! r* a) \
  138. LDX #$00* A! a) Z6 w8 u' D6 O) _5 ~% V3 F( B
  139. Init_Palette_Write
    % O5 X) K( D' n
  140. LDA Palette_Data,X9 S6 Z# p* _2 b, P, ~% D% }. y' u& `8 l
  141. STA PPU_DATA! ~1 A/ _0 ]$ k9 Y+ r6 W* J
  142. INX, J* E. ]$ [; R( q0 ~. m  t
  143. CPX #$20
    7 [* I- B( r0 t4 X6 c9 o& N8 f1 P2 C
  144. BCC Init_Palette_Write
    , S. [+ R& E/ s$ M! q
  145. RTS
    2 K0 {6 J  v. i2 `, B
  146. ; O) j8 s, W8 m* M
  147. ;==================================================! [% X8 O* z3 W& G# U
  148. ;设置命名表属性1 l& [% T8 w7 [1 S
  149. Init_NameTable_Attributes* |* k- A- C7 W1 b) D6 W
  150. BIT PPU_STATUS3 B; ~' q) `- a/ {
  151. LDA #$239 h4 V3 f8 l: ?3 ~& l$ W3 n
  152. STA PPU_ADDRESS
    4 i- B5 b1 _% L3 ^
  153. LDA #$C0
    . S' j- p0 m* p  U+ B2 O
  154. STA PPU_ADDRESS8 r2 ?; w2 n3 K8 t: r2 Z$ O2 m* C  q' E
  155. LDX #$00" l$ U; d0 r( a# K" ?3 |1 _
  156. Init_NameTable_Attributes_Write
      V# v" P- {# H/ q9 `/ L' @  w
  157. LDA Attributes_Data,X1 {. A3 V5 f( q) A3 a) w
  158. STA PPU_DATA
    6 `; i- @; x2 N" N
  159. INX
    4 j( n* C$ ~& V7 L+ u
  160. CPX #$40
    6 y  O# J6 }% }1 l4 }
  161. BCC Init_NameTable_Attributes_Write. t! i! x% W' k2 J. x& N" y
  162. RTS
    ' q) o: b( {& _" f( z

  163. # E2 H" G" A; @; b
  164. ;==================================================
    ) Q3 e( U, N) L6 `/ f2 i. n5 @- c
  165. ;初始化命名表文本
    : V3 [6 c1 C5 {& c9 B  Q
  166. Init_Name_Table_Text
    ; g- L- V% h- s1 `0 t1 j
  167. BIT PPU_STATUS4 q. V; n" Q  r1 }6 J# |* C
  168. LDA #$20
    . q- ?8 l' K4 K# C
  169. STA PPU_ADDRESS2 l9 ^0 W( w0 h* T4 s
  170. LDA #$00* n/ q, ]" [1 b/ Y$ X  K" n
  171. STA PPU_ADDRESS
    ' v+ q3 n: k, X
  172. LDA #$00
    ! [2 v. ~6 D; E; Y2 r5 `
  173. STA FC_Data_Buf
    . j  Q1 E% j5 H* }1 L" i/ G
  174. LDY #30* t2 K( d: C3 b: r  W4 \, H
  175. Init_Name_Table_Text_Write
    : N# N0 L3 r5 }5 C0 \$ S
  176. LDX #32) }; q  d2 J; h* M
  177. Init_Name_Table_Text_Write_Char
    0 U" O$ _2 a% E& J6 @
  178. LDA #'0'
    9 n, F4 N3 j+ {  U
  179. CLC2 o% Y( X* _! S4 R8 G# r
  180. ADC FC_Data_Buf2 E" Z) ^9 C  Y0 @$ U4 k8 [4 n% i( F
  181. STA PPU_DATA
    # F  _2 M& P9 @6 z
  182. DEX
    * t! X: n+ u9 v3 `5 g: z! C
  183. LDA #$14
    + M. q, Z8 u4 U# r4 ]9 C
  184. STA PPU_DATA
    ! R5 L( x. h. y$ y/ k
  185. DEX  t- f* I& a$ H' F( @! M; Q/ ?
  186. BNE Init_Name_Table_Text_Write_Char
    4 K. ~* O- |0 A& W
  187. INC FC_Data_Buf$ t( u+ n+ m5 Z$ Z: G$ x
  188. DEY% k: t! D" ^% @% O* i  ?
  189. BNE Init_Name_Table_Text_Write
    2 }$ d" L) h; m$ N- |# \$ U' W
  190. RTS* D0 t2 S: p3 A$ I9 y
  191.   x2 B6 B* r" ?) j; n
  192. ;==============================
    . ^4 x: e4 V; o; y
  193. Init_OAM_Ram;初始化精灵内存
    3 s* `6 u, r2 p6 w
  194. LDX #$004 V% R  ]  A( g
  195. LDA #$00# x% `& h& `: B
  196. STA PPU_OAM_ADDR
    * u( v1 _- o* P8 a7 A9 g8 U' @: c- n
  197. LDA #$F8
    ) R3 e& a& E' f) V9 O4 C4 |* l
  198. Init_OAM_Ram_Write
    7 I$ B/ `) K# m4 z
  199. STA PPU_OAM_DATA
    # y* B2 \* h( w: ^, P- E. I; b
  200. INX
    % i4 y" G* ~/ G  n; D
  201. BNE Init_OAM_Ram_Write
    9 m7 N9 q5 S5 v0 g- {6 j! C
  202. RTS# y& Q- {: p+ J2 ?( p$ T- E
  203. " h( H. F7 L: E
  204. GamepadProcess;手柄处理
    * V" I' m1 ~7 {+ J' B7 P9 M( W) P
  205. JSR GamepadDatacan
    7 M. h8 W4 {" P$ c2 h# i+ E' e
  206. LDA <Gamepad_0_Value
    ' I- }. l8 [( E& s
  207. STA <Gamepad_0_State* |$ O6 {+ ~! K8 f
  208. LDA <Gamepad_1_Value  R( `  [( r3 y: r
  209. STA <Gamepad_1_State" H) Z" f8 s- L) N' A+ p1 r
  210. JSR GamepadDatacan
    7 s( j5 y1 m# F/ r2 L& j  ]# _: n
  211. LDX #$01  J3 C# o6 Q; c& D; n
  212. GamepadMergeCheck;合并手柄输入检查
    $ Z- ]0 h& y3 W, P
  213. LDA <Gamepad_0_Value,X
    2 G) z4 T2 P4 O2 E+ i3 j1 c
  214. CMP <Gamepad_0_State,X
    - G& k$ l) c5 a" e& n/ |
  215. BEQ GamepadMergeInput8 x" s# _1 J  O; p0 }8 z* n' V% |
  216. LDA <Gamepad_Temp,X8 F, @. ~+ V- q! r: G/ z: p) l: g* E
  217. STA <Gamepad_0_Value,X; U% t0 L. `, z. e; b5 j  C
  218. GamepadMergeInput;合并手柄输入
    ( C; X8 v! |9 [6 {9 o4 W
  219. DEX; y( R% o2 @* N: S" L
  220. BPL GamepadMergeCheck7 g2 Z' w* p. ~) n" b
  221. LDA <Gamepad_Merge
    0 _: w& }5 {: z/ @! E6 T1 `% E
  222. AND #GAMEPAD_MERGE_FLAG
    6 e2 h  f/ {, F- I/ l, |: j- Z* Y6 d
  223. BNE GamepadStateProcess
    8 X3 q$ I& ]/ n+ r0 c: g
  224. LDA <Gamepad_0_Value
    2 ]  N* q9 e2 r
  225. ORA <Gamepad_1_Value7 k3 W* d  `, s
  226. STA <Gamepad_0_Value
    3 W, F' k0 }3 o% F* O
  227. GamepadStateProcess;手柄状态处理
    ( G: E  x1 ~% a
  228. LDX #$01% n" N# }$ H& M0 g
  229. GamepadStateSave;手柄状态保存$ }( T+ Q5 _! e3 x9 M
  230. LDA <Gamepad_0_Value,X( U8 Z( I8 u9 A0 L
  231. TAY8 m' f1 G; b9 @! w
  232. EOR <Gamepad_Temp,X
    ! i3 u. L1 S. v+ P' f% m( q
  233. AND <Gamepad_0_Value,X
    7 w  O9 P  l1 K- q* K
  234. STA <Gamepad_Once,X2 k$ D- o' S% q! N
  235. STY <Gamepad_Keep,X
    ! H- w, ?5 I: s
  236. STY <Gamepad_Temp,X& i) x9 F+ c  C9 I
  237. DEX; P: V: @9 f7 h% O1 l: Q
  238. BPL GamepadStateSave+ d& e' `, y% f0 b
  239. RTS
    , d- g. `# F1 ]+ f  z
  240. . z. a1 _+ j. v8 I4 d
  241. GamepadDatacan;手柄数据扫描3 `4 r6 I, h: _& I
  242. LDX #$01
    8 h9 E# `' Y' Q: V, b; j  n
  243. STX $4016
    ! _; t) M! t2 A! F) C- O
  244. DEX
    ! B3 [+ i* q# E7 L, a' p) k& u
  245. STX $40169 u* G7 J( ]6 e6 w# I
  246. LDY #$08- y$ r2 r8 ?! ?( ~
  247. GamepadPortScan;手柄端口扫描* @8 V! W  L% \  v
  248. LDA $40162 z2 w$ g% k  s/ \
  249. STA <Gamepad_Port_Value
    : A: f+ l1 C0 A1 ^' F1 S
  250. LSR A% O% B& z% f& K* g' ?! ?
  251. ORA <Gamepad_Port_Value, r0 `  K+ G5 e9 }6 B, Q/ p
  252. LSR A
    ; ~/ Q/ K! @5 ?2 u; b) n
  253. ROL <Gamepad_0_Value: s$ E1 Q/ _( R6 D
  254. LDA $40177 m1 E) z) Z2 U' z/ j0 B2 D
  255. STA <Gamepad_Port_Value
    ! m, Y1 N$ L* p2 L; }7 G
  256. LSR A2 G6 D5 M# p- K0 i7 M2 a
  257. ORA <Gamepad_Port_Value) @; u# k) t% G4 G+ f
  258. LSR A
    - h$ h8 o" ~' a$ J, r
  259. ROL <Gamepad_1_Value
    , b" r* N, ~5 |# t8 x& e+ {
  260. DEY, I- ^7 u+ Z- \/ c! e1 e: h8 d/ X
  261. BNE GamepadPortScan
    / U' D( w4 j0 y1 P+ M: t' x5 p
  262. RTS% v' S/ f! v8 \8 n9 y# ^

  263. 3 M% X  N! s; D. v  h  m$ z
  264. ;==================================================
    . l9 [1 O  V# b; U. R
  265. ;PPU处理
    " t& z8 \# N$ b
  266. PPU_Process
    ( x. H9 z$ g2 k  U3 R
  267. LDA #$00
    0 Q- f- `% {/ }; k. _
  268. STA PPU_MASK. ^5 W! W+ r/ H4 Z# q
  269. " G+ \6 D3 G: k' v( s
  270. BIT PPU_STATUS
    / \! {7 T' w* [6 L+ D$ I& P
  271. LDA #$20
    1 [, \0 z; I  B& w0 Z5 ]) s9 H
  272. STA PPU_ADDRESS
    # F* F4 h$ @: o; o6 B4 ~, }
  273. LDA #$00
    : P8 p% B' \+ I; s
  274. STA PPU_ADDRESS
    ' Y; }- @) \1 G  q* y4 S2 ~
  275. * P6 A- ?5 L4 s5 h
  276. STA PPU_SCROLL
    8 p& x1 W3 J4 F2 u+ }1 Y
  277. STA PPU_SCROLL0 B+ V  s7 T5 |" a/ C2 k

  278.   S# {) u7 v# L& z" @
  279. LDA PPU_Msak_Buf1 c5 g! d: u- i" s7 Y+ l" h5 Y
  280. STA PPU_MASK' K9 N6 ?$ X! q* n
  281. 1 \% f# Y0 H# `3 ^; m
  282. RTS% N& f; |0 |. n1 l7 Z! B  ]* T
  283. 8 N% N- ]. L7 \9 ]
  284. ;==============================  d" m  ]5 Z1 O3 C
  285. Time_For_Vblank;延时等待- H. j* J9 B0 t  `. \
  286. LDA PPU_STATUS3 C& H6 D: {) h6 _2 F: T, M
  287. BPL Time_For_Vblank1 n* _. S4 O& {, L
  288. RTS7 G9 s1 a& Z- H0 l6 X* ^

  289. 0 H% S3 _4 P* z5 r* ]  y2 M
  290. ;==============================
    * ^1 k. N" ?% N  N" i* o1 x
  291. ;初始化MAPPER19
    9 P* b9 I) A& [! F8 f
  292. Init_Mapper19% K, [; [3 Y! {0 H5 ?0 ]6 V1 y
  293. LDA #$004 O% u+ x( B1 w1 K) ]# c# W8 l$ [
  294. STA M19_CHR_0000
    , l9 _  O4 @; r5 L
  295. LDA #$01% q' d" P2 z0 e; V8 H6 a) N# _
  296. STA M19_CHR_0400( F9 k! K4 n/ r: z; q+ P8 P; x# h( D
  297. LDA #$02
    $ k, i) w' k' d0 w+ |* R
  298. STA M19_CHR_0800, h& R) l" c0 |  q
  299. LDA #$03+ O7 z# R$ s6 `' f
  300. STA M19_CHR_0C002 k! B: ]$ I: [  [& Q
  301. LDA #$04: x) G5 |& V' l
  302. STA M19_CHR_1000
    3 I4 [2 e! a8 x0 c# i1 ?0 P
  303. LDA #$052 w# ~! h5 `' r/ E: W
  304. STA M19_CHR_1400( H  d6 \( s3 j& }
  305. LDA #$06* n& [3 w- p; J! w* l
  306. STA M19_CHR_1800
    0 s' ?  L9 F4 p/ [! I
  307. LDA #$07
    / D3 t' [! r* t4 ]" c
  308. STA M19_CHR_1C00
    6 `$ Y) B3 Z- ~! O
  309. ' M! G$ ]- w" G  e% O
  310. ;禁用IRQ
    , l) C# k1 G# Q+ L! W1 a& i9 q/ ~
  311. LDA M19_IRQ_COUNT_H
    3 M! c, r  ~  i: U
  312. AND #$7F
    2 w) Z. W# q1 |. P- P
  313. STA M19_IRQ_COUNT_H9 T& d/ H" b  P0 ^
  314. . Z- [/ x! t! g* I1 f
  315. ;命名表* W4 k0 i0 X' ]& B7 |
  316. LDA #$E0
    0 U$ I% t  P0 P
  317. STA M19_NT_2000
      }3 S, n3 f5 y2 i
  318. STA M19_NT_2400
    3 {* \: a! a; M1 n) ^! `

  319. 8 Z) u7 J- }8 ~( G+ Y: j6 T
  320. ;命名表
    ' U; p1 ^. }; `: }+ I
  321. LDA #$E1
    ) E0 b% [5 H# T+ @! p/ x8 E7 k
  322. STA M19_NT_2800
    , R: @9 e0 v6 K! P8 v6 W
  323. STA M19_NT_2C00% ?# I1 Y* @* K3 a/ Z1 s6 F

  324. - B5 v  |2 d8 Q6 C1 I
  325. RTS2 y# \1 j1 o7 r4 ]% D. w# @

  326. 6 h. I, Q9 }# }- V3 ?3 ~1 _
  327. ;==================================================! Y2 y1 N# w5 y: f& s) T
  328. ;重置中断处理
    7 e( {5 x  x( j3 e1 Y
  329. ResetProgram
    , g3 l9 `& T+ w& O) E7 A, f
  330. SEI( h- P) j3 F4 S9 W% I
  331. CLD9 R6 M* I2 s# x/ o5 {$ t6 D
  332. LDA #$00
    ( {' n- a4 r: T
  333. STA PPU_CTRL5 j) Y. p% q2 ~# N* l4 `
  334. STA PPU_MASK' d9 J) b4 v- `, n+ w% i9 C: B  b
  335. STA PPU_STATUS
    * V) l: |1 z' r" y8 k
  336. STA JOY2_FRAME
    9 l: H3 G. ]( y* W( F8 a: z: I) q4 j
  337. STA APU_STATUS( y$ Q' c- d  y

  338. 3 l/ s8 E6 n4 Q- ?  ?3 l$ J* S, G" y9 S
  339. LDA #$C0. K" U$ q: D( h
  340. STA JOY2_FRAME; [0 ?% _; m% a

  341. 9 x7 F' ?/ k  |; [1 d' L  [
  342. ;等待vblank
    ' b5 }% K( ^( H1 F: q, c- X
  343. LDX #$02; c. O" [5 y8 C! Q' t0 K8 i3 M
  344. Vblank_Wait_1
    ( F# z/ Z& _$ b8 `8 m9 \9 w
  345. BIT PPU_STATUS/ _, r5 k# R+ h5 K% |5 g& Q
  346. BPL Vblank_Wait_1$ @& J4 |) E7 Q
  347. Vblank_Wait_2
    . W4 Z2 s0 h0 Y
  348. BIT PPU_STATUS8 Y6 [! d' q8 z% b( _
  349. BMI Vblank_Wait_2
    1 d& x# z8 [) U/ U2 a$ r+ D
  350. DEX
    8 o0 n6 {: J# [$ e! b" M& T. @4 R
  351. BNE Vblank_Wait_13 ^0 `9 ]4 L2 m! O2 Z
  352. 9 B0 }; a. P* p* ^; ^) ]! T
  353. LDX #$FF" l0 @8 }; c- l. f
  354. TXS
    ( |% Y( x7 _; M4 O! Y- m
  355. % Q4 L1 h, }. v% ?6 _
  356. ;初始化MAPPER198 j/ \$ C$ ]! O8 `2 d) j- C
  357. JSR Init_Mapper19- N$ ~5 p9 a6 @5 t
  358. . n7 ]( M; [0 Y/ o
  359. ;==============================
    8 C9 @# F# B$ ^( Y
  360. ;RAM初始化
    1 y4 H, H, E0 x8 p4 m9 a/ O# Y# r& u
  361. Nes_Ram_Init
    4 A1 t% A" z" {
  362. LDY #$00
    7 X4 _7 y& r) \3 ]% b
  363. LDX #$087 Q2 r2 m1 W% `
  364. LDA #$00
    ) \. l+ r3 j; z) q  U% r% x% [
  365. STA <$00  a( `& n: x6 N
  366. STA <$01
    & p" c' n6 U: n' C! X6 r
  367. Nes_Ram_Init_Write
    ( \4 F. ~. h# m9 |6 W
  368. STA [$00],Y: `) F( g  \$ f
  369. INY
    : y/ W" }- {! f; i: I
  370. BNE Nes_Ram_Init_Write
    4 V( ^9 d9 v0 A
  371. INC <$011 ]$ G: \8 j( {" k" ]/ C2 t6 \
  372. DEX* R, n' z  C4 ]: }
  373. BNE Nes_Ram_Init_Write
    1 e, t( G, f1 y3 x. ]( Z
  374. . y# i7 r: v4 D3 u; l* E! I1 ?
  375. ;初始化命名表+ v3 ^8 B1 t4 Q% m) h
  376. JSR Init_Name_Table+ X9 K* f; o( g8 M
  377. 0 n) J6 b2 u5 a( h5 H" v* q
  378. ;初始化调色板6 t! o1 ]/ z, M, c1 [' a5 w" p
  379. JSR Init_Palette6 j  i6 u* c; B4 M/ n  `

  380. 8 y6 s5 p9 o0 e
  381. ;初始化命名表属性. B3 Y+ K( y$ r% A. q
  382. JSR Init_NameTable_Attributes- F! l5 H" ]; Y, e

  383. 8 C3 X8 }3 U8 k3 e, I& R
  384. ;初始化精灵内存8 S( Y$ M' g4 G. C1 X1 ^
  385. JSR Init_OAM_Ram% R/ X8 c( K) d) {8 q1 P: A$ }6 A

  386. 8 p$ e) T3 c3 o
  387. ;在屏幕上写点东西7 ]2 F; R) \( A! r2 v. e6 @
  388. JSR Init_Name_Table_Text) l/ R; r& \/ t4 g0 o$ q
  389. 3 o4 u: b1 F( t3 B: Y; v( j
  390. JSR Time_For_Vblank
      `3 w7 t, n! E# ^
  391. ;开启PPU控制
    " S  Q7 _1 _! }
  392. LDA #$A8
    3 ?4 H1 C' R) m0 r
  393. STA PPU_Ctrl_Buf1 O+ t" P' g8 z, \( k# `' y( S( G8 B
  394. STA PPU_CTRL
      z' E3 b. d; f
  395. 5 z+ B& K% x$ m8 F# ^
  396. ;开启PPU显示
    1 K$ M3 T  W, P7 T' D; s
  397. LDA #$1E7 y/ e* a/ n% r) b' l  [$ T: o3 v
  398. STA PPU_Msak_Buf
    " h# C& }2 n+ W4 m6 B9 ]

  399. 6 \- ?% m: H9 ]* V( a0 N0 z
  400. CLI
    & E. v! t' E8 [; X8 p5 E
  401. JMP Loop1 z3 E/ D% P; n8 M* _
  402. ; s. F% y/ ]( x2 t* t0 k$ Z
  403. ;==============================
    $ s- v! q4 X# A1 V
  404. ;死循环, 等待NMI中断4 J! X8 l% v4 R
  405. Loop
      `' x- r, o. ^" N. P/ L
  406. JMP Loop/ e) \3 q- r3 \& T- y/ L7 _* Q
  407. ; r& _+ e6 w- w' e
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    5 B) n8 o2 n7 x, Q) W* m3 e

  409. $ s4 w) f( p4 S. {0 Q$ @/ \: f! z6 o( i
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967). O+ A" k% [1 }) l9 g+ ?( o
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    : g4 ~. {9 I# Z6 a$ H& E. ]
  412. ;==================================================; S( H4 P0 Z/ ~1 N. V
  413. ;NMI中断处理
    8 ^7 W  p% y7 W9 v
  414. NmiProgram
    $ Y6 t/ o" b+ g- C3 f2 L
  415. PHA) v/ ]2 r5 B+ k- C# V$ Q+ {+ T- T7 K
  416. TXA6 Y; K) ?- Q) [/ z9 Q
  417. PHA
    7 N: P" \) y2 A3 y: V
  418. TYA5 q# o& L6 I7 Z% x$ Y2 z3 A
  419. PHA9 S- P- L2 N7 t5 }- u4 |$ L, B% m

  420. * n3 q  ^2 r% ~/ ?1 h$ _0 A4 q
  421. BIT PPU_STATUS
    1 ~! [3 N4 e) }2 K7 V' @+ {
  422. 1 N( S6 I& }7 O0 ?
  423. LDA #$00
    6 O: |7 Z, r: O3 E
  424. STA IRQ_Index
    " P7 t+ Q; U' h5 V: E

  425. 3 d$ z0 s5 C, p, x. M4 d
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动" N: Z, G  F, `7 u& t( l
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    - v) E6 Z5 M/ E/ n4 W( [
  428. STA M19_IRQ_COUNT_L/ l& J& m% j# o  T" S2 M" R" D
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    ! s9 y1 V# C& V- {* t. L& l& l
  430. ORA #$80
    0 Z% ?( {1 |! Y& d# ?0 \2 ]1 g
  431. STA M19_IRQ_COUNT_H
    " F! N: j& ^  t) t6 J
  432. CLI% B  v% _( @, g6 L9 ?1 ^$ n/ _& o$ |

  433. - y) e# S. W5 \$ M! {5 {
  434. ;关闭PPU控制. t) x- S. }" W2 K: A; h% f  [8 H
  435. LDA #$001 ~/ K# v* C5 f% Z  x
  436. STA PPU_CTRL
    . W, o5 W% u! S
  437. ' j0 {: a' g' L7 h/ }
  438. ;处理PPU( R$ \7 N% ?" m6 s
  439. JSR PPU_Process+ n/ i, \6 k. U: w2 A

  440. : W; p- ]) ?; h: R3 b
  441. ;开启PPU控制
    ( I. |" a5 l; L/ A. U/ }+ e
  442. LDA PPU_Ctrl_Buf  p0 r: }% ^+ g+ W0 D
  443. STA PPU_CTRL
    ) ^5 J1 i% M+ g7 l

  444. % U# j" }+ o, y+ F* w4 W7 Y
  445. ;手柄处理
    % C2 n7 M3 f8 _( \
  446. JSR GamepadProcess! @9 H, u+ Y: E) N/ j9 Q
  447. * T, g" Y% \  E
  448. LDA #$00
    ( N( |* D2 |' ~9 P9 n0 r
  449. STA IRQ_Index
    $ Z% B+ f* T( z8 j/ x
  450. ; I. k4 b; A( e' N
  451. PLA
    2 z: s8 ^% w4 ~# g
  452. TAY9 A# x5 B$ D" Y5 |8 i3 [
  453. PLA8 k9 t' Y& ]& U3 K7 Y$ {9 e6 `* ~
  454. TAX/ C6 e; m2 w; |* P
  455. PLA4 S. s2 I5 ?2 _2 V. v
  456. RTI
    0 {6 V9 I8 w' z
  457. - [/ @$ ]7 C, I6 r
  458. ;每行扫描线113.67- w  ^; ~& o4 o
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    2 A# h; t& b6 c. B
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7  T8 W: p( g) i0 ~6 n. h5 w! V) {
  461. ;==================================================
    + B4 v/ j6 C' |8 b7 }
  462. ;IRQ中断处理3 e8 d. w% S0 e" j5 s
  463. IrqProgram" q1 n% G+ X" C7 e" r" g$ d9 d! T
  464. PHA
    ! J. N) Q5 s5 K2 s* U
  465. TXA
    * T8 d4 U; o5 |. u* G- K
  466. PHA
    $ |6 e. x! O0 A
  467. TYA/ \6 u+ i( A  }  r/ w
  468. PHA
    4 r: j4 V: `1 h5 A) F1 ^. H
  469. 5 N# J/ w8 u% a$ [
  470. ;16条扫描线后触发IRQ
    ! C2 y6 ?7 K/ F6 w- H- @
  471. LDA #LOW(BEGIN_LINE_CYCLES)( I) V4 e7 q5 h% w4 m
  472. STA M19_IRQ_COUNT_L
    ; T9 a# z5 `* H; p
  473. LDA #HIGH(BEGIN_LINE_CYCLES)- P* Y: Z. Q& H) \/ d
  474. ORA #$80
    ; i$ h( k$ |2 o. U5 k' [* T- a
  475. STA M19_IRQ_COUNT_H( f3 g3 u4 f: Q" |$ u6 @: N: L

  476. - l* P$ x! B/ N9 [
  477. LDA <IRQ_Index2 x% [( W- ?$ `2 V; D
  478. BNE * + 4
    1 W' B6 v9 ^$ L6 j* s4 C: e
  479. INC <PPU_Scroll_H: E# a' x: R/ g3 Z5 W! S
  480. , r+ T1 n: Z2 j* [: T. k
  481. ;设置屏幕滚动
    7 J2 c7 A3 \) Q( [2 }
  482. LDA <IRQ_Index' U; v$ ~* Y1 z& {7 }
  483. AND #$01/ J' H6 T4 s, O. X2 q% S, v. _* e- [
  484. BEQ Irq_Scroll_Right
    2 q0 p0 v( }3 b; u
  485. ) B# N7 J% f) S3 Y3 B: w5 ~. f
  486. Irq_Scroll_Left
    ) z* C: i4 b) y4 @5 v  @
  487. BIT PPU_STATUS
      f1 F/ P( ~- \# k
  488. LDA <PPU_Scroll_H7 m* S# F" y- q$ o9 j0 u
  489. STA PPU_SCROLL* ~4 R( r; O" T
  490. STA PPU_SCROLL
    , K( Q) c4 K* X' Z6 V
  491. JMP Irq_Scroll_Over1 R$ J# N7 P8 z7 K. p( p
  492. 7 p. x% ~8 r7 x: Q3 h2 Y" F
  493. Irq_Scroll_Right
    $ P/ [- t, ?' V: |* q
  494. SEC
    0 ~) s' `6 A3 `6 a
  495. SBC <PPU_Scroll_H
    # K  n+ h* T3 s: y0 u5 E7 X
  496. STA PPU_SCROLL5 M5 y1 {/ F4 d: d/ B$ v( f
  497. STA PPU_SCROLL
    + ^" l- r$ q. E( E7 S* n  u
  498. Irq_Scroll_Over9 f* ^: |) _# W" S2 n
  499. 3 }# a% n6 I) b- Z9 A
  500. INC <IRQ_Index  e' [9 X7 M6 q0 P9 R
  501. 0 t) T2 o" [6 q8 S2 S' f" h$ q
  502. LDA <IRQ_Index
    5 D8 d% _9 s# z
  503. CMP #143 d+ |' f  t% Z7 S' k: d
  504. BCC * + 10
    ; b+ \& J& t: M' l
  505. LDA #$00# m% O  x1 j( ]  f
  506. STA M19_IRQ_COUNT_L
      @) w6 K8 G4 n1 }5 t
  507. STA M19_IRQ_COUNT_H
    1 w$ D) I3 }1 C+ ]7 o
  508. 9 U0 P1 A- C* z. b' m% m
  509. IrqProgramEnd8 I" n, I' R9 M* [' |( z7 r9 H# ?! Z
  510. PLA# x! a* f# w' }" P, E: p  y
  511. TAY- a  U5 K0 |4 _6 Q: }/ ^" g
  512. PLA2 `. C" Y+ _/ y/ S
  513. TAX( }8 D6 O& U! P! j
  514. PLA* J0 D) Q/ Y9 W! ^" ]9 e
  515. RTI1 a  B4 b4 N. E$ p. x6 r  d. b4 K

  516. ' _* C7 N/ z5 U2 A+ ]! Q9 E
  517. ;==================================================2 V/ u7 P/ U/ ^. L, J
  518. ;中断表; i; p6 B4 x- A8 y% O
  519. .ORG $FFFA4 c  |. Y' D2 r" d+ t+ }" N, H" ]
  520. .WORD NmiProgram+ Z% B6 s  i9 Y# O7 Z& t5 i
  521. .WORD ResetProgram
    6 q& E( [2 ^6 u6 E+ }/ h
  522. .WORD IrqProgram
复制代码
6 I# `0 r7 z4 N6 D8 t

本帖子中包含更多资源

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

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

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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