EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]0 D; F: e2 @9 {2 U' R# E
  2. ;FlameCyclone 20230710% k1 k; r' l; }- n

  3. 2 L6 R! \" a. v; b- x* s
  4. ;文件头
    * D1 B/ v2 I# N2 J- U8 X4 P
  5. ;======================================================================
    ) I; Z" G. N/ j0 i# ?! m
  6. .INESPRG 4                                              ;16KB PRG 数量
    # Z; }; A# F5 R6 t' U
  7. .INESCHR 1                                               ;8KB CHR 数量
    / T6 s0 H8 K0 I/ {& n
  8. .INESMAP 19                                                 ;mapper 195 \. k$ |2 N" H; p' W  a9 N
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直& }1 t+ G2 }4 ~  h' f  z
  10. 1 ^1 W) k  u% O
  11. ;必要条件
    % C/ R: F4 T$ T: Y9 [! T/ {
  12. ;1.持有CHR ROM
    / J* c; \6 l6 B0 v" p% z
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ' n! s  C4 y( m3 d
  14. ;3.精灵内存(OAM)不为空
    " g0 M% n5 M& m

  15. & [3 m$ T8 j0 o: W/ C! F. @* D
  16. ;==================================================
    # x7 f+ s) V3 z+ i' b3 I
  17. ;NES端口常量  H0 n1 C5 ], }) y
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    / F( ~. W, t6 }/ ?  o8 Y2 P7 p
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    & k) k3 y, q2 z2 K+ @
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    " ]0 B: _2 G" Z% M* r  r7 H$ J: W
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    5 K. V( y0 V' u# g
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1, l& m2 j* j/ f/ a  O' M
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 + `/ B( l4 b+ |2 _% |8 U' N" t
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    0 A. d0 D3 Q" O7 u8 L
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    2 x7 N1 F4 s8 v3 p
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    3 _- ^1 R: k4 N( Y3 t8 i9 U/ A
  27. APU_STATUS              =   $4015   ;声音通道切换& |9 \$ b' `+ S: ~& A$ U
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    6 d, t. R# l% _
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通9 K0 |$ b$ T  h1 l
  30. # r# k( k; o  f( {2 q7 R- B! D3 g5 S
  31. ;==================================================0 S) r$ E! ^, Y- D( F3 W7 J
  32. ;MAPPER 19端口常量
    # \8 B2 u& }5 S! f1 r# O( ]4 C
  33. M19_CHR_0000    =   $8000
    ( i8 z9 W2 o; T4 e# ^1 _$ \1 `
  34. M19_CHR_0400    =   $8800: Z7 }4 b% t% i. p
  35. M19_CHR_0800    =   $90008 @& g0 i! g3 |. f/ `& e& [
  36. M19_CHR_0C00    =   $9800
    , S, p5 G/ a. p: u
  37. M19_CHR_1000    =   $A000
    : P+ S! L0 W+ O+ a% O5 j
  38. M19_CHR_1400    =   $A8005 B+ p- t2 l7 Q5 b# y3 v
  39. M19_CHR_1800    =   $B000  |' M3 u6 g6 O# b3 }- k3 `
  40. M19_CHR_1C00    =   $B800" Y8 J5 @5 P9 M( f7 U. s
  41. M19_NT_2000     =   $C000
    , x, P! w0 k$ E/ K  \+ L
  42. M19_NT_2400     =   $C800
    8 X; e  ]5 W1 B4 P9 J+ |( _
  43. M19_NT_2800     =   $D0004 {! T3 _! t) z- I
  44. M19_NT_2C00     =   $D800" j8 @- @+ G3 |
  45. M19_PRG_8000    =   $E000
    5 }. C, ~; |* K2 s9 K$ H8 v
  46. M19_PRG_A000    =   $E800
    2 m- v3 J4 t+ c3 U
  47. M19_PRG_C000    =   $F0004 p4 O9 ?. E8 R2 j* a
  48. M19_IRQ_COUNT_L =   $5000+ I4 |, X6 h$ G; C+ M+ F
  49. M19_IRQ_COUNT_H =   $58002 O% \5 s. m" o7 t+ @. s# G& j

  50. ( D  j( J. C& [* g* {5 ~  }/ }
  51. ;==================================================/ `$ w0 e2 a7 N1 [  a' y; @
  52. ;程序块配置
    8 k* F0 [6 X) F
  53. BANK_DATA_MASK          = $075 J# E3 g; G  ~3 a7 a: ]
  54. ;--------------------------------------------------
    1 {3 D2 ?- h3 ~+ R$ N2 `+ L
  55. RESET_BANK              = $07
    & a; i* l9 D0 t. ]) n7 M
  56. RESET_ADDR              = $FC00
    9 G, _/ n$ C6 m- T% A% i$ r# U
  57. 2 y# q# A: p; f; B
  58. ;==================================================
    7 o; o) {' _9 w1 L, v" z2 v
  59. ;图像块配置
    ; S! _9 Y) x! _
  60. CHR_DATA_BANK           = $08
    : d  Q1 D, c4 g' G/ p
  61. 1 l0 X, [% r) j# H! l
  62. ;==================================================! c3 `: l- A5 i8 A3 h
  63. ;零页内存地址配置
    " ?" B& H9 _: ?6 B, N
  64. Use_Ram_Addr            = $80
    : t+ b; T3 s2 ?6 a! F( }1 I
  65. PPU_Ctrl_Buf            = Use_Ram_Addr. Z- z- Z& e- N  L1 }4 Q1 C
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01) b  R; c1 J& n0 n
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    3 c! s9 S( Y5 J
  68. PPU_Scroll_V            = PPU_Scroll_H + $01! p7 z" M, e0 u) F" y+ C; p
  69. FC_Data_L               = PPU_Scroll_V + $01; D4 s' x* l% b  Z. [
  70. FC_Data_H               = FC_Data_L + $01
    + \0 a/ l9 T* o% X
  71. FC_Data_Buf             = FC_Data_H + $01! }1 K! P% B' I2 K6 a
  72. ;==================================================5 E$ v( A( D/ f3 f! H; Q
  73. , h: N* m) V! ?
  74. GAMEPAD_MERGE_FLAG = $04
    " [% j! [3 F2 I: @

  75. ( ^& c: J4 f8 e! B( s/ |
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    2 G* Y4 N+ i, Y" t% w& ^
  77. Gamepad_Once            =       Gamepad_Keep + 2
      a8 _' m+ Q, O5 ^# M% {( B" s! b
  78. Gamepad_Temp            =       Gamepad_Once + 2
    3 n- p2 O1 T$ j: r
  79.                                 
    * A# |: ]( m4 }* I
  80. Gamepad_0_State         =       Gamepad_Temp + 2/ k1 m8 `. v2 Q" J* G1 G$ Y& L
  81. Gamepad_1_State         =       Gamepad_0_State + 10 }5 r' d7 f1 `& c, V/ H% W$ a. y
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    ! k0 o* Y" _; ]8 N8 Z3 ^7 g: @4 T9 F3 I$ s
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    , J7 X7 D; ~, P1 \8 U  _
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    2 i& C# X& d) ]& I
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1* ?5 A% e4 @4 s9 r9 p/ e) c
  86. * y& ]% Z4 k2 X( \
  87. ;==================================================
    * O4 w" P, {6 j2 y
  88. IRQ_Index               =       Gamepad_Merge + $01  w$ o/ u" W0 M" {  k
  89. ;==================================================0 x3 X1 |* `' z

  90. 5 `( X$ ?# |! ^6 R! H2 d, y
  91. ;CHR图形数据
    8 y+ @) H) J- j4 d/ \5 z$ i$ Q
  92. ;==================================================% y# {& b  k" U7 `' T0 a
  93. .BANK CHR_DATA_BANK
    , X, I2 g8 `3 x* K
  94. .INCBIN "chr_bank/chr_data.chr"( g9 z4 k7 n$ \: t/ e  ~

  95. ; c+ B$ ~5 z' x, v3 F
  96. .BANK RESET_BANK & BANK_DATA_MASK
    4 d+ X- n7 M, N8 M
  97. .ORG RESET_ADDR4 d( y1 r& G. i$ [! b0 l5 C

  98.   i% G1 ~. j* c; q
  99. ;--------------------------------------------------
    0 w; ~9 ^  A. q( U' Y) f' ~6 Z
  100. Attributes_Data3 l- F1 V# a$ u( V: R5 f8 t
  101. ;命名表属性" q: ?% |9 F$ N0 c3 N* d6 w- Q$ I/ V
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00! B: a& \' V6 T; @+ d
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    ; ]; k9 I" y, H: h! j" z
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    . K9 @* l9 j0 m/ }
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    # }  d- A' s1 v& R0 A8 y& b6 A: X
  106. ;--------------------------------------------------
    ; k% L" B* w7 f& M' p% @
  107. ;调色板数据0 J6 m6 p7 T# b) ?) a' `
  108. Palette_Data
    0 X7 Y7 @. U$ X) q% I
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    / c, Z. c7 d, u8 x, ^/ U+ Q
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    & b* Q9 [8 T1 ?2 q

  111. 8 W+ t9 l0 W9 ]2 \1 x+ K3 Z
  112. ;==================================================
    ; x/ H& ]; d5 h; Y' m
  113. ;命名表初始化7 o7 Q1 m& O5 F+ m. Y
  114. Init_Name_Table- O" e! s% \, ]) O4 L
  115. LDA #$20$ O: c% \; A5 n- g
  116. STA PPU_ADDRESS
    ( t1 o" F: d- [/ I: y& m3 d' I
  117. LDA #$00( ]: ]3 Z( m2 A+ q0 a9 ?7 X0 j
  118. STA PPU_ADDRESS
    0 b( I. X& p+ J, D( g
  119. LDA #$00* q; |7 J5 J* R5 r% d7 H
  120. LDY #$00+ V4 |# j! l3 \' i9 K3 E; y) M
  121. LDX #$10& \% P+ Z! P% [/ `" P1 `- N
  122. Init_Name_Table_Write
    + d1 y( P7 _& G' M: G1 W7 T
  123. STA PPU_DATA/ r0 f' Y5 F% {: ], Q
  124. INY* N9 S- l  g4 S8 d
  125. BNE Init_Name_Table_Write
    ( K7 P; T$ Y8 X$ w
  126. DEX
    . Z9 S; g: E6 `# P
  127. BNE Init_Name_Table_Write
    ' r9 |, |+ J- j7 Y( g4 F9 y
  128. RTS& g$ Y$ `4 S4 A0 M% M/ `& f! a
  129. " ^! Q# Q, Y. j% y3 e- c( ]
  130. ;==================================================
    + X* d+ T) o& \" |
  131. ;调色板初始化, g, G8 u0 m* K" E6 Q
  132. Init_Palette
    " _# d6 r' X& [, u; i+ ?
  133. BIT PPU_STATUS
    9 \5 \+ S/ M! {: L( z# S
  134. LDA #$3F
    , ^6 g) [/ U3 M1 d2 _; ~
  135. STA PPU_ADDRESS
    ( Q/ ^( i! p. @( L( _! @
  136. LDA #$00
    ; h4 W. O1 v; Y6 E& F( |; f/ F
  137. STA PPU_ADDRESS* `' d. P' m6 Z1 \( i& b4 t3 B
  138. LDX #$00
    ! c4 F' l2 X; X* r* }: a
  139. Init_Palette_Write
    % e4 q1 `7 V4 O/ w
  140. LDA Palette_Data,X
    & {; Y* f' E% T2 W$ o+ o! |
  141. STA PPU_DATA
    6 p9 R2 G3 o' U
  142. INX- H# v. V) a; T- N$ G# Q
  143. CPX #$203 Y' ]+ k6 t6 |1 `' R& C
  144. BCC Init_Palette_Write
    & L  e; j( X5 ?9 m- L
  145. RTS8 E& Q2 V% C$ R4 R" i

  146. 2 h; |) B% w& k1 N  R) W% W4 k9 c
  147. ;==================================================
    0 V2 h5 ~* K0 h; K# R* P
  148. ;设置命名表属性
    " X0 g1 _$ f- z
  149. Init_NameTable_Attributes) \" r8 d' K& k2 {- v$ \
  150. BIT PPU_STATUS: n% t1 J% C* C: v% N+ q2 x6 g- \0 F
  151. LDA #$230 j2 x4 h4 a2 `+ O4 k/ ]" t' h$ J  ~7 G3 S
  152. STA PPU_ADDRESS+ ^8 V; K: f8 Y
  153. LDA #$C0/ r+ j  S! O: F; A
  154. STA PPU_ADDRESS
    2 o3 s$ z0 u, a) r0 e& ~, w
  155. LDX #$00" o0 ]6 I& t6 b4 d
  156. Init_NameTable_Attributes_Write
    ; O% A5 \% f" @  i6 e
  157. LDA Attributes_Data,X6 n& C0 F; a3 f1 g, W. Q. P  v+ p
  158. STA PPU_DATA. n7 E( Q9 _1 ^1 b5 r
  159. INX
    1 J: a6 z& P6 h8 a4 ~: J' f
  160. CPX #$40
    % T! ]/ a3 _: x5 _
  161. BCC Init_NameTable_Attributes_Write
    . d4 S4 M, }% f9 k
  162. RTS
    ! j) n, v. y$ B( ]0 f8 E

  163. " U7 m* i" j! n2 O+ a& O# y
  164. ;==================================================
    9 u' L$ o" M5 j8 z# Q- ]* F
  165. ;初始化命名表文本
    3 D( y& P4 B9 y+ Q1 m& ~! Q
  166. Init_Name_Table_Text$ @' E# E; [& X2 T1 `
  167. BIT PPU_STATUS
    ! ?- y# O" ^# r8 _% L& F. l8 B
  168. LDA #$20
    + F+ l; Q1 }* ?7 I) }# a7 E3 g
  169. STA PPU_ADDRESS
    ) J" a& O2 E# b: @
  170. LDA #$006 o5 H) |& F# R' _/ ]( |; b
  171. STA PPU_ADDRESS
    $ ~/ ^, u7 v1 E/ x0 l3 O! p
  172. LDA #$00
    8 L& }- G' K* I' A5 M! v
  173. STA FC_Data_Buf
    9 U8 e. o( B- O; o
  174. LDY #30
    ( u" M4 E5 ]+ |; i' t
  175. Init_Name_Table_Text_Write0 I. s2 f: |& V- S0 f
  176. LDX #32
    $ j- Y) s4 J$ r
  177. Init_Name_Table_Text_Write_Char$ i% A3 ?& c( @) U# G. \
  178. LDA #'0'
    * \) t6 T- }+ v
  179. CLC3 e& W- o- o6 K8 J( K
  180. ADC FC_Data_Buf) }7 C3 I4 `' b5 U! y+ O
  181. STA PPU_DATA1 f' N+ D' f- l# o2 E5 S
  182. DEX
    8 _+ W$ P- ^' {9 X1 P; ?
  183. LDA #$14; ]6 N8 o/ u7 y' N: m7 E- n
  184. STA PPU_DATA: B4 F0 n# q( A5 g2 T+ N3 ^. c) L
  185. DEX$ c5 c) D' k; Z9 x/ d+ c  S
  186. BNE Init_Name_Table_Text_Write_Char
    / m( z5 l# _% G# M
  187. INC FC_Data_Buf
    1 m# }' [8 M, _0 p  |
  188. DEY
    & W" @- F- ~0 R( g" E) ~0 x
  189. BNE Init_Name_Table_Text_Write
    1 H5 s+ h  d8 X' A1 J6 R5 Z
  190. RTS9 j) N" e7 m* \' L# T

  191. 9 [5 H  S* V- t) [
  192. ;==============================; ]. G2 f$ _4 i. x/ a4 d2 i/ c  N. H
  193. Init_OAM_Ram;初始化精灵内存
    ' e( W+ `: q: F
  194. LDX #$00
    $ S5 f4 ]. x' z( h/ F4 H/ k; o  o
  195. LDA #$00
    " x1 z, e: u2 x% @- S
  196. STA PPU_OAM_ADDR! U5 D6 y& Q; T- Z
  197. LDA #$F82 b" i+ B; ^/ M6 S, b0 t
  198. Init_OAM_Ram_Write
    6 K1 T1 _) O  U
  199. STA PPU_OAM_DATA* e) P; Y% R7 E$ l
  200. INX7 i- o  ]5 |1 l& D
  201. BNE Init_OAM_Ram_Write/ `( c7 J! \  S% H; e  R
  202. RTS
    3 k% y; }- S0 E/ K! n0 H, `
  203. 1 m. \" T1 }: _. U' i
  204. GamepadProcess;手柄处理
    ' g9 v9 C! S' B, u8 h' l
  205. JSR GamepadDatacan% S7 r! e' ?" A* G1 u, I2 |. i' X4 `
  206. LDA <Gamepad_0_Value
    8 N! ~) H$ Y/ N
  207. STA <Gamepad_0_State
    * L8 R2 d% r5 g8 a1 a
  208. LDA <Gamepad_1_Value
    ; ~' f# @( g) n; i
  209. STA <Gamepad_1_State
    ' R( u5 m5 k+ o. z) ^
  210. JSR GamepadDatacan, y( a: b5 w! v5 }9 v% A5 k5 D/ G  n
  211. LDX #$01
    ' M! _; [& e) v6 A9 o/ h$ s9 N5 @* R+ O
  212. GamepadMergeCheck;合并手柄输入检查, \. h2 n$ `+ }$ g7 T
  213. LDA <Gamepad_0_Value,X" x# g- B; A" v
  214. CMP <Gamepad_0_State,X
    + N6 a% W* `/ y1 B
  215. BEQ GamepadMergeInput
    5 P& S# |- l, a2 O! B4 p
  216. LDA <Gamepad_Temp,X
    % G# F2 @& J' ?' v
  217. STA <Gamepad_0_Value,X
    3 w7 P6 n+ L# f& _/ I9 H, y
  218. GamepadMergeInput;合并手柄输入
    8 W8 _* {8 N; F
  219. DEX
    ! L; e- _6 P' C
  220. BPL GamepadMergeCheck1 I) ?" Y7 x; ~
  221. LDA <Gamepad_Merge, @1 c: H1 A! G# b
  222. AND #GAMEPAD_MERGE_FLAG
    % x/ B+ c+ W% V$ ~8 S/ O
  223. BNE GamepadStateProcess0 [0 ^6 G$ C" H* R1 p1 F
  224. LDA <Gamepad_0_Value
    : C8 H# p% Z; C. Z" D: r# y; C
  225. ORA <Gamepad_1_Value) H8 q3 K5 n6 |- V8 U
  226. STA <Gamepad_0_Value! p, C3 j- H  v& e! J- |
  227. GamepadStateProcess;手柄状态处理" [- f+ z  h# L5 s& r% b
  228. LDX #$014 b4 e. e" H0 X$ S  \: E
  229. GamepadStateSave;手柄状态保存6 B0 [2 @- c" `" \
  230. LDA <Gamepad_0_Value,X
    . [0 S/ k3 }" r% D) ~- p- q2 [2 B
  231. TAY
    & e- }1 k, u! Z: H! @: L% E( d. R
  232. EOR <Gamepad_Temp,X& l: ?; i7 p+ _' r
  233. AND <Gamepad_0_Value,X
    # X1 m: C* f; o* E# G  L9 O
  234. STA <Gamepad_Once,X
    4 D# O* H; t1 Y; }
  235. STY <Gamepad_Keep,X) x1 n6 a$ ]! M, A
  236. STY <Gamepad_Temp,X
    3 o# r, b+ d. h- _: f% n( c
  237. DEX$ F6 R0 H0 @4 M3 N
  238. BPL GamepadStateSave
    6 k4 c! M) h. i/ C
  239. RTS
    ' C  `  `* o7 |' D* `2 Y4 k
  240. ) ~  V, l" f( J. e* e3 r
  241. GamepadDatacan;手柄数据扫描
    ' ?: ^0 L3 Z; G7 \* E: O
  242. LDX #$01" ?$ U. K# @9 N$ P  m4 ?. f: K
  243. STX $4016
    / x" g: c# _; ^  F- d
  244. DEX- ~- I0 N9 Y; m( {! o
  245. STX $40163 O( [4 a' U8 n& [* G6 {
  246. LDY #$08
    3 z3 _  L0 T8 }; [( o9 k+ E9 K
  247. GamepadPortScan;手柄端口扫描9 ~0 U, l4 C# s& W1 O4 `/ c/ C& Z
  248. LDA $4016
      ~5 c* e9 a0 \# O0 I5 F
  249. STA <Gamepad_Port_Value
    : s. ~1 {; u2 T
  250. LSR A/ e, {0 x6 D+ E0 P7 p# o. Y1 g
  251. ORA <Gamepad_Port_Value
    - m" R' }, k3 w
  252. LSR A
    % a/ U; ~6 x2 l" P( m7 N
  253. ROL <Gamepad_0_Value7 m3 Z  S/ \9 v* _! G$ k
  254. LDA $4017
    0 m' K5 v) S) \, E5 a6 N' M
  255. STA <Gamepad_Port_Value
    , ^7 Z' z7 L0 m/ a
  256. LSR A
    7 p( O  @" h6 x4 ]- |' o$ q( U
  257. ORA <Gamepad_Port_Value
    9 L; Z% k+ F# x0 m" {
  258. LSR A; ~% ~! t$ O7 P
  259. ROL <Gamepad_1_Value0 [; y0 f/ P7 G1 i0 F, m6 s
  260. DEY
    ; O9 |- z* f5 D* V) s$ Y5 r, F# [+ L
  261. BNE GamepadPortScan  S! U: \  C$ y4 S# b, b( i
  262. RTS5 I6 y8 ^0 d8 E$ W7 U; H
  263. , t4 P7 S4 E: J4 D1 ?6 k
  264. ;==================================================0 J+ ?, G0 r: n7 F/ i
  265. ;PPU处理9 U+ L9 \& m  z" H* I5 g% Y  g& R" T
  266. PPU_Process
    ) b1 \! D+ I. P- }  U& s
  267. LDA #$00$ [: G8 {+ R6 d) {
  268. STA PPU_MASK- h. {' ?" n1 P# }4 v" G3 i

  269. 3 z+ @4 s# u2 Z* q5 Y: }
  270. BIT PPU_STATUS$ y  p7 a7 |3 i& X
  271. LDA #$20
    / V, Y; X# u' X3 Q' i
  272. STA PPU_ADDRESS. ^3 j" e' g6 F  K
  273. LDA #$00! ?8 g; k0 G. W9 K2 v
  274. STA PPU_ADDRESS/ X9 W, J& P: P0 Y3 ~, [& h3 p
  275. 7 p4 Z2 S2 v/ k
  276. STA PPU_SCROLL2 x' K: r; h3 R$ W+ B5 Z3 L/ u
  277. STA PPU_SCROLL) i# B! l5 K( ~1 G' f1 s
  278. / T# {9 f0 I% ~+ I8 v" b
  279. LDA PPU_Msak_Buf
    & j9 w  ~8 a5 Q( h. Y
  280. STA PPU_MASK
    ( p% q7 _' W6 w5 a4 S$ y. x- V

  281. ! G3 X9 d5 J  ~5 a: p8 k2 c
  282. RTS
    ( X$ c2 `$ N6 \

  283. # ]6 A& @" I, a% g/ a3 [3 A
  284. ;==============================
    * O& Y8 u3 i/ u& A
  285. Time_For_Vblank;延时等待6 n! C! K) p- e
  286. LDA PPU_STATUS0 F3 C2 y  }* N# D: q1 L
  287. BPL Time_For_Vblank
    ( y/ \) @+ B% e$ O
  288. RTS
    8 A. o' {: a) R* j

  289. $ V# j9 `/ O8 y  e) J0 t
  290. ;==============================
    # ?2 p) f3 ?  }- a
  291. ;初始化MAPPER191 ^* U! a3 y$ j6 t* W+ S2 y
  292. Init_Mapper19$ a& H4 r5 w8 v& ]5 c( B4 ~. z  D) D4 {
  293. LDA #$00
    3 N3 F4 `+ g( v
  294. STA M19_CHR_0000& @- O3 T8 Y$ k
  295. LDA #$01
    8 D# x9 Z- o& Y, l# |6 _
  296. STA M19_CHR_0400
    5 j- t  N/ e" r5 f0 x8 d
  297. LDA #$02
    $ N% Q3 f. S, c! w! q- z
  298. STA M19_CHR_0800
    4 a1 C$ C( s9 d5 r2 u9 x- \4 c
  299. LDA #$03' n2 t+ H5 h2 {  d- V
  300. STA M19_CHR_0C00& A8 l( e$ P# G" G
  301. LDA #$048 t+ |5 `2 @9 R/ V
  302. STA M19_CHR_1000
    7 t& q. M: w( z! A. d
  303. LDA #$058 a: z( ~0 R# n3 O6 S! s, e. D. a
  304. STA M19_CHR_1400
    2 @  r) N' Z; K
  305. LDA #$06
    % n- x$ {  F( Q: [! K
  306. STA M19_CHR_1800
    ' H7 ~  i8 A7 o. @/ n; P3 A
  307. LDA #$07
    % I0 Q& a9 X, E. C
  308. STA M19_CHR_1C003 W7 t! h  h0 s: w

  309. / c- q) d/ g( B( L
  310. ;禁用IRQ
    - V3 T1 g, `% S4 |# Y
  311. LDA M19_IRQ_COUNT_H
    5 \0 T2 J/ h, T& v3 U
  312. AND #$7F& X& u, N: s$ f' }2 W2 {
  313. STA M19_IRQ_COUNT_H, _3 V  B: ^4 l  O  |3 T

  314. : w$ J! v" U- m  n
  315. ;命名表" e9 {8 n' _  g0 _  |" A
  316. LDA #$E01 c. }- w: T5 x/ z/ a* f
  317. STA M19_NT_2000! O7 t$ o! ^$ b7 r7 C8 }
  318. STA M19_NT_2400
    $ e2 ^" _" O" _

  319. - h7 T# h# l' j1 S* T
  320. ;命名表9 q" H  a* Y0 j0 D9 ~1 Z
  321. LDA #$E1
    3 |+ \) ]- _2 p, j6 V# o8 f6 `
  322. STA M19_NT_2800
    9 t5 \4 ?* b/ b" P
  323. STA M19_NT_2C005 R! \5 K8 M4 T% q/ H+ p3 F: [6 ^
  324. ; ?1 f1 L. \% z7 t
  325. RTS
    5 S1 K" C8 p0 \
  326.   Y7 l2 `; R1 u  |3 g% e
  327. ;==================================================: k& B# u% o0 O3 q0 h
  328. ;重置中断处理
    6 U" B+ j7 J# J# C* `/ g
  329. ResetProgram
    . N" ?6 V4 D: P8 P$ Y, \
  330. SEI% n  B! W; K2 @" m! u( ?- B
  331. CLD
    8 X. z7 N4 Y& t* K: {
  332. LDA #$00- Y& u3 U  @+ z' e& e* C' S  }1 u
  333. STA PPU_CTRL9 @9 g6 m$ m- p: f. r
  334. STA PPU_MASK8 W, {) A% M1 i9 F( S% L  l) x
  335. STA PPU_STATUS- R6 _& q" A' A" }! f& t. p- j
  336. STA JOY2_FRAME; n+ h1 X$ w) u; G
  337. STA APU_STATUS
    ; ^6 N! p* N" k# n* R6 X
  338. . J) v7 m7 E# R% R; @( L1 W. d3 Y
  339. LDA #$C08 J; Q* l# i, ~
  340. STA JOY2_FRAME
    " B: h. q  w6 V. G

  341. ( K, j# N/ d( U, ^& P" S+ o
  342. ;等待vblank
    , J  g5 B3 s" d; F$ E4 k
  343. LDX #$02
    0 a# U+ G0 t# A
  344. Vblank_Wait_1
    . i3 F9 D9 ^, t4 k1 v* h6 ]% e# M
  345. BIT PPU_STATUS
    ( o$ y7 c* c8 y8 G
  346. BPL Vblank_Wait_1
    ( }& Z( M; p% ~7 k! O! @6 G
  347. Vblank_Wait_2
    : J: @) w3 J' P( x  ^
  348. BIT PPU_STATUS; s& A7 J( ^) k# t) G; d
  349. BMI Vblank_Wait_2
    $ i- E% Q+ f! N5 }+ }
  350. DEX# G6 b* y5 [( ^- M+ }0 H" ^
  351. BNE Vblank_Wait_16 _: N: X: s# i7 m

  352. 6 @3 W+ [, }# Y: p9 c
  353. LDX #$FF; H, O0 g# `* |# s
  354. TXS
    # ?8 `' Z# a* c  \7 Z' s

  355.   S2 x* A: a# p; R6 Z! G9 _
  356. ;初始化MAPPER19& j6 {, R: Q1 Z/ q5 ]6 l
  357. JSR Init_Mapper19
    8 a6 ^3 |' {0 c1 m& h/ S
  358.   U$ @3 k) j3 x
  359. ;==============================
    1 D. k+ |' I  x( N  \. y. j
  360. ;RAM初始化+ S' ]  \( k& T& Z3 f
  361. Nes_Ram_Init2 W* ?: j$ {  ~" F6 r8 {1 L
  362. LDY #$00
    + z+ _; D- O1 g
  363. LDX #$08
    . r7 Y; l% y  M5 ]$ j
  364. LDA #$00
    ) r( e3 I+ U# m- f6 T' Z5 Z
  365. STA <$00
    ) h, W2 _* K& {) G
  366. STA <$01$ g/ y' k8 a. B8 U
  367. Nes_Ram_Init_Write
    8 A( W; c4 R7 n: _" ]
  368. STA [$00],Y1 F- @/ V8 J6 ]; {
  369. INY
    1 ~: A' S5 }, f: a
  370. BNE Nes_Ram_Init_Write5 {# z1 o( H$ }! s6 I! ^
  371. INC <$01. i" @& k( w6 M( g/ M
  372. DEX
    9 K' ~! \& c* `" H4 u. y) O; ]$ j
  373. BNE Nes_Ram_Init_Write
    3 S* n/ U- C4 s

  374. & z; q+ X) U+ f1 i4 j' m
  375. ;初始化命名表
    / t, _0 S& o* E; `  {. v
  376. JSR Init_Name_Table9 |8 Z; C% p, R& w. I% w& m

  377. . ]! \. V+ d& @) O$ f* [* W: }
  378. ;初始化调色板
    ' Y/ s" W) C. O) @$ S5 m5 [
  379. JSR Init_Palette, M+ J3 S0 j) Z& E' E" \9 n

  380. - P$ D1 l/ r; C- j# [& i
  381. ;初始化命名表属性
    0 A8 t4 g6 u4 l$ y0 w4 L3 C" r1 B! @
  382. JSR Init_NameTable_Attributes+ h0 X" a) y3 x9 @5 o

  383. # k* \* f5 b: n; U' _
  384. ;初始化精灵内存
    3 i2 h, D* H4 L# G
  385. JSR Init_OAM_Ram. \, D5 ?2 [( t" h  x9 _! K

  386. ( e' E$ c) W* u) k* O6 g* d. m, \
  387. ;在屏幕上写点东西
    ( e% l: M: |$ M0 r/ q1 i8 k
  388. JSR Init_Name_Table_Text
    / T6 A0 e8 ]1 P8 |- l

  389. : {& ~; T3 W9 q6 z
  390. JSR Time_For_Vblank, a5 t: r. ]4 Q- |6 Z& l9 i
  391. ;开启PPU控制
    / Y6 x0 }$ ~  W% s' c
  392. LDA #$A8
    # G: T" P3 A+ x. q6 y& A! v2 _7 X
  393. STA PPU_Ctrl_Buf. O6 \0 t% \2 Q. y! e7 Y6 m2 r
  394. STA PPU_CTRL* V# Y4 |- N; O1 B! O
  395. ' f/ _4 M. c9 e9 q2 M/ j
  396. ;开启PPU显示
    , g* ~2 f5 ]7 W: [; d
  397. LDA #$1E
    . {3 a& d0 {4 @3 g9 i: }
  398. STA PPU_Msak_Buf' Q) {9 d. A7 A$ t) a$ J

  399. 6 P2 o+ h' J) x+ v: X) P
  400. CLI
    + [! O. n  S/ p8 U' M( D4 T% X4 m4 W) t
  401. JMP Loop
    ; Q, O) q: l$ ]8 \, X" ~1 [, p8 P9 y8 N
  402. . ]4 G* w& H: b. [7 u/ e4 L( a
  403. ;==============================% F$ r9 e. B# g# h
  404. ;死循环, 等待NMI中断. [9 e1 w7 p% D9 O2 I! T0 G
  405. Loop0 i$ s0 i% g; f- q, y
  406. JMP Loop2 S9 G8 W. n! k* f) j# K
  407. 7 T2 r' D& G0 o1 [% J
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    0 n6 C) L3 e: r& a2 ?4 O
  409. " E$ Z1 j0 y: C( J
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    , o9 D0 G6 L. R7 X2 J8 t' y
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)" z/ M+ c, s5 C, `  u& M) n
  412. ;==================================================7 T3 y- l/ k) z% L+ I5 k
  413. ;NMI中断处理6 {. o2 [3 S$ H4 w) q
  414. NmiProgram. S7 Z3 ]- {7 L4 i3 k+ N
  415. PHA
    % J% }# B  y  u- [9 @
  416. TXA
    9 v7 a' A2 c* |% {, Z" ]
  417. PHA
    3 H) O1 Z0 J# z- \' ~, U" c( i
  418. TYA+ q  f( m" d: k! h. G
  419. PHA
    5 S- K  F8 e; Y5 L' k( ~* s9 h0 V4 W

  420. + ~* _$ X& Y1 \& E) p: P+ u. s9 J
  421. BIT PPU_STATUS- e5 v1 S8 }! o( \' f/ N8 Q+ {! X

  422.   f- \$ ]  T! L) Z7 V3 Z& Q
  423. LDA #$00
    9 u4 \! d1 {9 l! C- H" l/ j
  424. STA IRQ_Index4 U5 N! Y9 q( D8 x

  425. 9 c2 _! F4 Q8 ?' X/ ^( ~. J4 n0 k" i
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    % m3 ]7 \$ o) \6 N( P1 ?" `
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    . R( e9 q% U% U' j; E$ B# D& D& o
  428. STA M19_IRQ_COUNT_L0 o1 i5 W" \( k/ I, D2 U3 j
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    + ^9 Q7 [- i( \2 o9 \" A
  430. ORA #$80
    1 J0 b  C2 U4 [
  431. STA M19_IRQ_COUNT_H  v( r" t6 A- p. t0 R
  432. CLI% ~% o7 G$ Q2 K# r) V

  433. + B$ A8 p% p3 E# b! C
  434. ;关闭PPU控制6 N6 v. O( n: a# Z, l
  435. LDA #$00
    % d' Z0 x0 F+ b' e
  436. STA PPU_CTRL/ w* k3 a; X4 n, ~
  437.   R6 W" Z7 O3 Z& I. l+ U
  438. ;处理PPU9 H! x! F5 r4 o! p7 a" Y) u
  439. JSR PPU_Process
    * f, ^- y; p2 f

  440. 6 c7 G/ x* I# B
  441. ;开启PPU控制
    ) D( l) C" N( e$ j
  442. LDA PPU_Ctrl_Buf
    / Y6 q( W  s3 m1 k3 @* z  a1 `
  443. STA PPU_CTRL
      |! u. P% T3 q
  444.   f( g6 V/ Q1 \' S
  445. ;手柄处理
    - I6 B1 [  b6 g4 q/ @  \
  446. JSR GamepadProcess
    - F  r. R, c% I, `

  447. ! h) Q6 ?  F. G
  448. LDA #$00
    ) K6 ?8 m+ F" b7 U
  449. STA IRQ_Index
    . \* ?" Q1 |! J
  450. 8 Q* V( R$ z, y. f8 k1 \6 b
  451. PLA- q6 Y+ d# ?9 d% q  T8 V% d
  452. TAY
    5 d$ m( U0 W$ @- H2 W6 V
  453. PLA5 l- V' P! |: j/ |+ h
  454. TAX; P" l0 t7 u; h
  455. PLA# _( M2 ~- U  R
  456. RTI6 G  R  N& K2 F" b, K# m  x$ y" s( L
  457. / p7 H8 g; `- {1 e2 m
  458. ;每行扫描线113.67
    " c9 g+ X- K9 u6 c
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    + q7 u% k3 s! a8 X" q
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7+ K* L8 w0 \& Y1 y5 e8 L
  461. ;==================================================
    9 u  {- v( M& C" Q+ }
  462. ;IRQ中断处理
    , k  a& c0 h0 t8 a0 k: c9 R) p' h
  463. IrqProgram
      _8 Q/ N# E  C# Q2 B: l
  464. PHA  J7 m4 H! U* V$ ~) f6 @8 @
  465. TXA
    # F; A( j$ t: z5 G6 `
  466. PHA0 i* X) D3 t  A- t3 c6 Q  m
  467. TYA
    ! f0 g& X+ r+ V2 I' {: [' q
  468. PHA  F6 ^% A5 J# N; H  R/ f* v
  469. ) d) H: t  K- J8 ?) [
  470. ;16条扫描线后触发IRQ# z( ^$ j, u2 N1 J8 F8 x" c
  471. LDA #LOW(BEGIN_LINE_CYCLES)  @0 T. F; l% l$ |0 V5 o9 q. e$ q+ w
  472. STA M19_IRQ_COUNT_L/ t7 W  S6 m4 B2 P
  473. LDA #HIGH(BEGIN_LINE_CYCLES)- v  N7 e9 [% y$ {
  474. ORA #$80
      y( B+ I' e. V3 s
  475. STA M19_IRQ_COUNT_H7 d+ Q- n2 C9 m- {" N+ m5 @
  476. ! c6 R0 G4 z! Q) ?9 z- g
  477. LDA <IRQ_Index9 R! K6 m. [0 z' o4 R2 |* A: T
  478. BNE * + 4+ S5 u$ a! c1 Q, o3 r4 y
  479. INC <PPU_Scroll_H
    * ^5 r- F, u: u- \5 h

  480. ) j8 k! J& S1 C3 b+ r; s- r( \
  481. ;设置屏幕滚动, D! r3 `) [  k% f5 A
  482. LDA <IRQ_Index
    , o' T$ F# c, ]' K
  483. AND #$01
    ' w& e8 _$ F' f
  484. BEQ Irq_Scroll_Right8 D" B' n. x9 _/ o& L$ a9 V5 N# h
  485. ) }; s" q5 J2 o; L
  486. Irq_Scroll_Left7 v# K- U2 [. O
  487. BIT PPU_STATUS
    # g2 N) m4 b" ~4 v3 [/ g$ [0 z
  488. LDA <PPU_Scroll_H! T5 f/ j$ D: _
  489. STA PPU_SCROLL& Q( O6 f) F% K' ^$ @) N
  490. STA PPU_SCROLL
    7 Q/ i) u1 ~; I% o
  491. JMP Irq_Scroll_Over2 p5 H& z' U; J

  492. + j: D4 \, P1 w* U: v
  493. Irq_Scroll_Right
    5 N. L" u4 k- w- l0 b; s
  494. SEC
    8 S- a$ L7 {3 v; j0 `
  495. SBC <PPU_Scroll_H% [$ l7 m+ Z0 [) `" F
  496. STA PPU_SCROLL0 v: Y! C. C9 B
  497. STA PPU_SCROLL
    6 r2 e* p; t. L, S1 u4 D
  498. Irq_Scroll_Over( ^) f; v  d8 l  Q

  499.   t7 p% i+ I* k# c7 u1 I/ W
  500. INC <IRQ_Index
    & Z  ?; {- M- G
  501. - n% {# }* J: S* V
  502. LDA <IRQ_Index! C9 ~" R: P5 O8 F2 J- ?& @4 c8 G
  503. CMP #14
    $ n' J% \# }% ^
  504. BCC * + 10. E+ Y* O/ I* G! x- Y$ W
  505. LDA #$00( _$ n) Y5 |3 }" j, X/ N' x
  506. STA M19_IRQ_COUNT_L
    2 v& a8 n( c$ n! t
  507. STA M19_IRQ_COUNT_H: E  B  Y. o( H! P
  508. , X, n+ p, M+ J
  509. IrqProgramEnd
    ( t$ G+ _" f2 e- Y9 S) E1 i  n
  510. PLA2 }5 g% ^2 d- A! r7 S
  511. TAY
    9 @+ ?2 B7 x: m* F- d( `' t/ b
  512. PLA  Y2 j) |. L5 ~0 E# R
  513. TAX
    : G- m4 y- P( h6 Q
  514. PLA' W3 Y* L( k2 ~. s0 I# T
  515. RTI
    ( g  B7 c5 u+ c; t& J9 _! ?1 n
  516. 6 n: q. R* P& l( O
  517. ;==================================================
    ) j5 y" v: C( w1 k: l
  518. ;中断表
    " @  c1 \3 S6 t0 p0 E9 S2 W% K
  519. .ORG $FFFA( n# H6 J6 Y; P% U
  520. .WORD NmiProgram/ |% y9 R; p* Z! k- j
  521. .WORD ResetProgram
    / m, S0 ^/ z4 t% g# }
  522. .WORD IrqProgram
复制代码
' W" K! P; v% X

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-11-5 13:59 , Processed in 1.072266 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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