EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]3 b4 K, L6 O8 {% G2 `  P
  2. ;FlameCyclone 202307109 q, [# w$ j" d6 S# ]* ?) ?" H
  3. 5 D+ W: ?' n/ Y% O: q/ ^0 _  @" J
  4. ;文件头0 {2 D, K: u) n- s# x0 E" q
  5. ;======================================================================9 y' O  }6 R! W0 D1 d. N
  6. .INESPRG 4                                              ;16KB PRG 数量0 L5 Y( t* @3 U% D- W  c
  7. .INESCHR 1                                               ;8KB CHR 数量
    ; ?9 A7 `5 \6 S: }. x0 y" x+ r, Y
  8. .INESMAP 19                                                 ;mapper 19% q6 I1 U' P6 _/ t; p2 e
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    4 X/ v' E/ B4 `4 a; W* S

  10. 2 j- ]2 ]& a( y
  11. ;必要条件
    ( Z, H$ A" U% _$ L, V4 t( E
  12. ;1.持有CHR ROM
    2 k( p* L% n9 q0 {# j, u* m- `
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    & e- p- l# r7 ?4 K/ a3 N0 ^2 Y
  14. ;3.精灵内存(OAM)不为空
    + W! D# J# |# j% w# g) S( M

  15. 2 ?, S. y0 C. c' V- \( ]" L5 ^
  16. ;==================================================" G  G" \7 G4 Y! Z7 Q; i$ X
  17. ;NES端口常量# Z( D' H0 X6 z4 T$ F5 g3 ?; b
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    0 v6 h5 J- T9 k2 \8 l5 z* ^0 d
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    " k( M( d# @0 k
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    - D- V1 @6 q9 ?4 R- U  x* t0 u
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    6 m1 {" x* f& G' M
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    + T( x8 B, b. z( V
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    1 C% K: @* C& ]
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加* j' [8 k+ B6 G, F+ p2 m
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 3 L0 J% q; Y. U( E( E
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存7 n7 G+ E# g" W* t% k, r% M: v
  27. APU_STATUS              =   $4015   ;声音通道切换' A) ^! S; ^7 ]! O9 W% r6 Q
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通- s5 e: u6 B/ h' [7 W& P+ X+ d
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通9 J8 \5 k  j: H3 t* k+ D0 J

  30. 8 R' }% X+ C# a! x  ^
  31. ;==================================================1 n3 N( }- ^7 r: s8 j
  32. ;MAPPER 19端口常量
    ; e1 j' y: {. s8 P/ h& O5 `
  33. M19_CHR_0000    =   $80003 M  e( P- u  Q$ v" d" v
  34. M19_CHR_0400    =   $8800
    + ^+ x+ k) O3 @4 K  H
  35. M19_CHR_0800    =   $90001 J& n  k0 v% v2 J8 A% A6 M6 r
  36. M19_CHR_0C00    =   $9800, j' ~0 `2 X, ]& M. c% C; p# p2 p$ j
  37. M19_CHR_1000    =   $A000
    ' w' r! D( q/ [1 l$ Z) h
  38. M19_CHR_1400    =   $A8000 Y: v) _2 }: T# s
  39. M19_CHR_1800    =   $B0004 w( x. s, G6 ~
  40. M19_CHR_1C00    =   $B800
    ' X, M( C: t! `, p' N
  41. M19_NT_2000     =   $C0004 H- w% S! k2 P. ?* Z0 A- s
  42. M19_NT_2400     =   $C8008 @2 q' ^: ]/ C0 b; ^$ y( {
  43. M19_NT_2800     =   $D000' N% M6 l% ~" S  @( @6 }% D3 B. p
  44. M19_NT_2C00     =   $D8007 o  l4 B) f) U, @7 |8 e! L0 }4 g
  45. M19_PRG_8000    =   $E0008 V. U, S. t* l7 D
  46. M19_PRG_A000    =   $E800
    % i2 b8 r3 x2 f3 F8 A: \; c5 E4 ]
  47. M19_PRG_C000    =   $F000
    : i/ s. @* }7 s4 J( g
  48. M19_IRQ_COUNT_L =   $5000: o) s9 h& F8 h" |. o# W' v
  49. M19_IRQ_COUNT_H =   $5800) s4 J1 Y: @* N: C
  50.   X+ u/ u6 [1 v& x
  51. ;==================================================
    0 o1 O0 R9 Q# j' t$ d8 }$ v0 H% O
  52. ;程序块配置
    % B+ ?( @* U& H) I
  53. BANK_DATA_MASK          = $07: D* h3 m8 k# W2 p
  54. ;--------------------------------------------------* o+ \  R8 o2 P& [' `3 r" k- {% s1 n1 G
  55. RESET_BANK              = $07
    7 l* _  p/ [, A7 J
  56. RESET_ADDR              = $FC005 V5 B! K6 d9 n9 i7 F, P

  57. - {7 b3 p. I: d' l: I
  58. ;==================================================
    ' v1 ~& L6 i) O
  59. ;图像块配置! r& Z' R/ s9 L# x
  60. CHR_DATA_BANK           = $08
    4 Q5 v$ k9 M- c8 T: y" u
  61. + G+ n. }+ D" M) T! e: H9 P4 B
  62. ;==================================================
    3 n' P/ o+ X! ?7 _3 k2 z# p' X
  63. ;零页内存地址配置
    1 x/ S0 s" p" _. G
  64. Use_Ram_Addr            = $80, A& ]8 h: ?# J
  65. PPU_Ctrl_Buf            = Use_Ram_Addr1 k: M% T* Q7 [+ D5 M9 }
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    ) z; {2 t; J; i, X  H7 h2 e
  67. PPU_Scroll_H            = PPU_Msak_Buf + $014 I) h0 C/ H2 {3 ]# w6 U
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    - {* V$ p$ |9 W2 Z! _& u1 |" F: H
  69. FC_Data_L               = PPU_Scroll_V + $01
    8 q. n6 a$ D7 l# d0 m
  70. FC_Data_H               = FC_Data_L + $015 t1 k% D, L9 ?  I
  71. FC_Data_Buf             = FC_Data_H + $01* p. v7 n+ Y9 {' {  M5 k: ]( z' |5 r
  72. ;==================================================
    + `0 K, q3 g8 H2 F: o0 ]) K4 H
  73. ( |/ z4 H7 f% k/ m+ e. r
  74. GAMEPAD_MERGE_FLAG = $04/ O  N' c9 z% A6 P" j9 w* V) O# I
  75. - O4 B$ Q; P$ B! Q% [
  76. Gamepad_Keep            =       FC_Data_Buf + 11 x6 g! E! J& O
  77. Gamepad_Once            =       Gamepad_Keep + 2
    ' E0 s) {7 s" g% @0 X* |
  78. Gamepad_Temp            =       Gamepad_Once + 2" L3 U% N, F: a  c: f5 c
  79.                                 
    * f' ]) t! ]. |( U4 G" p
  80. Gamepad_0_State         =       Gamepad_Temp + 2" j5 b4 ]& G0 S
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    # L. ]6 s6 a6 s' i" n5 M$ \( V
  82. Gamepad_0_Value         =       Gamepad_1_State + 1, g% W! n* \. {  K
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1$ U7 K* n, \5 P7 N
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1% v5 E1 A5 J- q- n7 o% L; _$ [
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    ) D, M1 N* L5 I7 z

  86. 0 T0 ^& s$ p3 y2 G
  87. ;==================================================" t  z5 S. y3 D. T4 C' f* W
  88. IRQ_Index               =       Gamepad_Merge + $01. N! G$ {  @: M9 K1 H2 |6 A2 F# r
  89. ;==================================================
    4 q- I, F$ Q  h
  90. ! x  D& J7 h0 q% ~" e$ N$ J2 {
  91. ;CHR图形数据
    . I) R6 R5 `: b
  92. ;==================================================& c% j3 K. W$ m) A* _/ l3 c7 d
  93. .BANK CHR_DATA_BANK
    8 N0 z5 V7 C! m+ E
  94. .INCBIN "chr_bank/chr_data.chr"
    + w$ x  P& {8 h6 y$ y

  95. # o7 f+ r3 U! [6 k" ~
  96. .BANK RESET_BANK & BANK_DATA_MASK* c- B5 L' i/ N- B3 C
  97. .ORG RESET_ADDR
    9 ~$ @( ^' k/ g! p8 |
  98. + [+ q; j# C; `  [* H9 |$ j# d* t% A
  99. ;--------------------------------------------------6 F, p. q- p- C7 v/ X
  100. Attributes_Data
    % i7 K; q9 G8 l- R8 ^" |
  101. ;命名表属性
    ( d" e) V' `6 x* v/ N& M
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$007 m% F% r5 v& W5 `- N. x  [7 p$ |
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA( {* r% ~( [/ C' a5 u( X( |
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA' `# x: C/ |0 Y3 ~+ k
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$555 D' V$ o, p1 F# s# f* s$ {
  106. ;--------------------------------------------------, C, U- s. O7 ?1 U' P
  107. ;调色板数据. k9 J2 H0 n9 |* k8 T& J
  108. Palette_Data( d' g! `4 V5 _1 H5 L
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F8 G2 Q* g. L8 W  A* l5 j% v
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F# i' i/ e3 U! e! o* W
  111. ' B; g1 n6 W7 f8 X
  112. ;==================================================+ Q. Y6 ]0 `+ T/ M) Q; ^
  113. ;命名表初始化
    , S3 h4 n7 l" C: n  ^4 V, G
  114. Init_Name_Table; ]9 {$ n7 y5 d- v+ X* w
  115. LDA #$20* h; D2 ~& ?: [& C/ V, b
  116. STA PPU_ADDRESS
    5 L/ T3 R, Q& a* T9 S
  117. LDA #$00
    9 k9 o5 I0 ]' m9 C- j
  118. STA PPU_ADDRESS
    ' u! `* l+ E6 v$ [
  119. LDA #$009 ^# v% Q* b# s# `( [& o
  120. LDY #$00
    ! l' X  F* [: M" H3 v
  121. LDX #$10( H) d# _9 T1 t* e  l, I( V1 p
  122. Init_Name_Table_Write
    ) ^6 T* K+ [0 b5 {% f# c
  123. STA PPU_DATA: J$ ~- B/ j; H: j. w! R* X. O# P
  124. INY
    . M$ m/ [  @  T: I$ k% w
  125. BNE Init_Name_Table_Write
    + \, y( w' R3 P+ I
  126. DEX; n  D& u6 o# z! g: o
  127. BNE Init_Name_Table_Write
    * r% G) ^5 j% b4 Z+ i/ F
  128. RTS9 S" C- X! Q+ H9 j/ t' [
  129. 7 J3 w. b8 l" ]* d0 V$ b
  130. ;==================================================* m1 _& [2 I8 ^! l; s  Q* A0 F
  131. ;调色板初始化/ `7 W0 J: F" \
  132. Init_Palette
    0 f; u3 v: G& W$ k
  133. BIT PPU_STATUS
    & n" [. z, R: i/ I
  134. LDA #$3F
    - W! j! E7 ]5 n
  135. STA PPU_ADDRESS- ]5 J1 y* V3 g
  136. LDA #$00
    # a/ H( e6 }/ G; o1 C$ {6 Z
  137. STA PPU_ADDRESS
    1 H" Z, N8 `, X3 w8 s" i  P
  138. LDX #$00
    , J$ U+ A  y5 J, r, X5 z# C4 }4 P
  139. Init_Palette_Write
    ' X/ @2 a2 a4 U0 N
  140. LDA Palette_Data,X
    8 S# C. Y$ l$ x+ G5 ^9 [: a
  141. STA PPU_DATA
    * j5 @& E6 }, I7 ?
  142. INX
    & e& H" ~9 P# b8 r. \
  143. CPX #$205 K. s" p. l& d9 L/ l0 g5 V4 V
  144. BCC Init_Palette_Write% w# V; ^% Q7 ~' H9 s1 Y$ o
  145. RTS  \. {% J9 Q! Q, b- V

  146. 8 I! V' |8 n) V1 ?2 O
  147. ;==================================================
    % b# ^; E! V$ i. u
  148. ;设置命名表属性
    9 K- I& {4 |% E! ^* w. D# V6 C
  149. Init_NameTable_Attributes
    # p; C/ Y' T/ f& ~
  150. BIT PPU_STATUS
    . f6 h4 M. p, D( z4 S% _2 ~
  151. LDA #$23
      A# u7 J! T" e5 J! W
  152. STA PPU_ADDRESS5 ?' R4 P# A' v- x
  153. LDA #$C0
    % o, [% H: B2 L2 q0 ^  ~
  154. STA PPU_ADDRESS
    0 W# X. G& }  |+ B9 q) @# f3 y
  155. LDX #$00
    7 F& B* |. K0 q: C8 ~, G
  156. Init_NameTable_Attributes_Write! `1 U* a# P; Y9 r$ E+ O
  157. LDA Attributes_Data,X% f8 h: A; ^: H% d
  158. STA PPU_DATA1 P& ?# E4 v+ H
  159. INX
      C5 t1 v2 I: x. Y. B2 e
  160. CPX #$40
    $ A6 M6 C, r6 b7 z
  161. BCC Init_NameTable_Attributes_Write, O; F) O$ ]3 q2 }3 C; l
  162. RTS
    ) G" U$ W8 M+ `5 L
  163. : ~+ m- j  R! a* m
  164. ;==================================================3 `9 P- k; R. W3 U/ Y1 Y- ^  H
  165. ;初始化命名表文本
    1 M8 W6 {: A7 L% s2 q: d
  166. Init_Name_Table_Text
    6 }2 ~) I+ L% n. b4 @
  167. BIT PPU_STATUS* h) n, Z2 s/ Q+ n* J, a' k
  168. LDA #$20
    ; X9 Q% ^& X# n& ?: N" }
  169. STA PPU_ADDRESS
    * T' n; W3 W+ u5 E, I) u9 H
  170. LDA #$00
    8 b' Z( I6 A) k) U3 y: N$ q
  171. STA PPU_ADDRESS) P, o3 |! z% K" L/ N$ f( `
  172. LDA #$00
    % H6 t6 \, O( j' Z
  173. STA FC_Data_Buf
    - o& f  v9 `0 R, h( D) E( J
  174. LDY #30: {0 n: S& m- X$ ?
  175. Init_Name_Table_Text_Write
    8 G5 ^. n/ V8 }2 @# g/ B5 v
  176. LDX #32
    3 ~1 @* J  g" H% l. ~+ T! \
  177. Init_Name_Table_Text_Write_Char* c: p6 u* _; O0 g: x
  178. LDA #'0'
    / i1 \( J2 [! _, \$ k
  179. CLC1 c2 m0 I$ A2 F7 e: u+ P$ z. l" D
  180. ADC FC_Data_Buf
    : ~- J; V- q) J, S2 r: C
  181. STA PPU_DATA
    ( u) V2 X0 v0 U: x* a# o4 R7 `
  182. DEX
    4 n0 a6 l) {4 m) Y+ ?1 A) L+ h
  183. LDA #$14
    . \, U% R, K+ t2 E. w( G
  184. STA PPU_DATA
    4 O# g1 _4 @  k
  185. DEX& ]2 x4 |8 j7 p" r6 P4 B) w
  186. BNE Init_Name_Table_Text_Write_Char
    ' |% |. `. S; V( x
  187. INC FC_Data_Buf3 {: _5 h) S# r: A9 _/ o. X7 G
  188. DEY
    0 m. c% c, |! s; N3 [  g
  189. BNE Init_Name_Table_Text_Write  e+ x; T' V7 T" p6 Y: |  t
  190. RTS" D" }# X- c/ O9 S3 ^. ^5 n

  191. % X, m% ?# y/ x" x% t
  192. ;==============================0 u" ^  i* ~3 y
  193. Init_OAM_Ram;初始化精灵内存, V. _0 U  T9 z) [* o
  194. LDX #$00
    : P7 a% v' W/ C, r3 q. u5 g
  195. LDA #$009 R9 O- o+ _2 r! b4 J0 b2 M+ N3 d& F
  196. STA PPU_OAM_ADDR
    8 r0 K& u/ t' p0 s0 \" N2 c" b
  197. LDA #$F81 m- f3 P  n) }
  198. Init_OAM_Ram_Write
    / u+ x* d! |1 u, K7 w
  199. STA PPU_OAM_DATA
    : W1 ?- a0 j8 A. M; d+ I
  200. INX7 @7 ^0 s& s, m, u4 f: S1 d) R
  201. BNE Init_OAM_Ram_Write
    : P( J9 t0 W7 c
  202. RTS
    5 @# K; D( t" O; g! ~

  203. 0 `  _# E" x0 `. R3 T. e
  204. GamepadProcess;手柄处理8 E! z* m' k4 I9 N
  205. JSR GamepadDatacan) ?  m+ Y0 F% m& ^9 m  a0 r
  206. LDA <Gamepad_0_Value
    : |- P" b( S/ S0 R
  207. STA <Gamepad_0_State
    , Y) ^3 r$ l; K" E
  208. LDA <Gamepad_1_Value8 q0 j% \) R! Q* L
  209. STA <Gamepad_1_State
    ! g0 k1 q  p6 y1 o& t$ w
  210. JSR GamepadDatacan
    + O& t3 r  r/ D8 |* \; z
  211. LDX #$01
    ' F+ |$ H5 F% @$ p
  212. GamepadMergeCheck;合并手柄输入检查
    4 M! V5 g3 o2 ~
  213. LDA <Gamepad_0_Value,X
    7 q: l7 h* {4 F; x1 v( Z% ~! Z
  214. CMP <Gamepad_0_State,X! z3 f+ }) ]" c& w
  215. BEQ GamepadMergeInput3 _1 a) `8 t5 y( ]7 d. \5 f" l3 j( x
  216. LDA <Gamepad_Temp,X
    . z. a9 {: H) Y' A& |) ?: T
  217. STA <Gamepad_0_Value,X
    ) r! _; O" q3 W# u4 A9 _$ I
  218. GamepadMergeInput;合并手柄输入9 x. b* l* A0 [4 [6 g# s) G
  219. DEX: [. o0 }- N* s) t: c, F- J
  220. BPL GamepadMergeCheck
    / q% e2 l) F7 C6 U* Q3 g# P
  221. LDA <Gamepad_Merge( ~# n, x# O7 M, X  F! r8 S
  222. AND #GAMEPAD_MERGE_FLAG2 U$ A# w: E7 \% o9 T' d9 w& O. {
  223. BNE GamepadStateProcess* {2 p0 H* t& o4 E: M) V
  224. LDA <Gamepad_0_Value
    2 F+ h' K* ~- N4 l# p
  225. ORA <Gamepad_1_Value6 D4 N' z. ]" n$ i
  226. STA <Gamepad_0_Value" ~0 U# h' V* y( J/ n
  227. GamepadStateProcess;手柄状态处理
    2 a2 a/ F9 n0 u, U
  228. LDX #$01
    " r8 ]: d  R7 B: ~5 H+ ^/ Z' b8 O1 }
  229. GamepadStateSave;手柄状态保存
    ) p9 L8 Y/ D5 T2 Z2 v. O  P5 _* q
  230. LDA <Gamepad_0_Value,X; A; n% d7 s: N& v
  231. TAY
    5 v2 V2 W1 w0 [4 y% ?
  232. EOR <Gamepad_Temp,X
    6 M9 \/ A5 @' b! {1 Z' B
  233. AND <Gamepad_0_Value,X
    5 D& c, ?% }- t
  234. STA <Gamepad_Once,X4 l% x5 P+ n- I' [; H6 ?
  235. STY <Gamepad_Keep,X
    # g- R; p8 _) o+ i5 L
  236. STY <Gamepad_Temp,X1 s: a* ?7 I) d/ q- S$ r: u
  237. DEX
    ( _- d. ^( t# [7 f8 V# H+ x
  238. BPL GamepadStateSave+ V1 K% J8 m& n+ F( P
  239. RTS- d6 b7 \+ ?* W' U+ b; W% q
  240. 3 w* F4 X% N8 u, j4 O/ r
  241. GamepadDatacan;手柄数据扫描
    - T% p- e2 G3 F- @8 l; s8 T! j
  242. LDX #$01) `. Z4 \7 l! K( d+ p
  243. STX $4016+ {: E, \- O: N% G3 L3 {  ~" o
  244. DEX& x8 H8 X0 u0 z* O  k7 K! Q. z$ V/ t4 D
  245. STX $4016$ v* X  T1 n* h5 d2 M" Z
  246. LDY #$08
    ! C2 X; y( w8 \
  247. GamepadPortScan;手柄端口扫描
    & p: J8 O' G& Q1 @3 a8 u
  248. LDA $4016; u! c8 D, a, Q* {9 `  [) H' C
  249. STA <Gamepad_Port_Value( `2 h- {7 u' N1 d% X" N
  250. LSR A
    7 Y) K8 {9 y' l! |" I
  251. ORA <Gamepad_Port_Value
    1 W& A$ W  R  D( i( `. W: M4 p
  252. LSR A
    / j0 h! Q/ h. ~. [$ y8 H
  253. ROL <Gamepad_0_Value
    1 _* C8 C7 ?& H5 {8 H  J  B. ~  y* r
  254. LDA $40176 l9 u# G* _, X, ]% j
  255. STA <Gamepad_Port_Value
    5 O0 n" U! u1 y9 Q
  256. LSR A
    % G4 _0 g/ O0 @" J; J
  257. ORA <Gamepad_Port_Value
    0 L7 {9 r7 |4 S8 D$ e
  258. LSR A
    ' A9 b( ~9 H( H
  259. ROL <Gamepad_1_Value) I1 a3 @0 n# ^; J0 S
  260. DEY0 `( Q7 Q0 t  v6 H
  261. BNE GamepadPortScan% l  B+ t3 D5 g2 ^; o( f" U
  262. RTS, i! `) \4 a2 u! Q+ S
  263. ! k+ `! V4 v) R5 f8 a4 I4 f3 r) {$ N
  264. ;==================================================
    " ^, D* P8 {; ~, z! c7 ?- J
  265. ;PPU处理! z/ A* t. g$ \8 \
  266. PPU_Process# r8 k- X, r* v) l/ Z1 w/ J
  267. LDA #$00
    2 y! d# N  s: I4 y
  268. STA PPU_MASK
    7 l/ m: f2 k' C$ o$ p* A' o# C
  269. . D. f: {2 Q0 w, R% i7 @' C
  270. BIT PPU_STATUS
    7 J  ?4 R5 F0 K5 v6 x  n6 S( r$ j$ T
  271. LDA #$204 l+ t/ X& i8 @# z5 Z
  272. STA PPU_ADDRESS3 y9 g- n" W3 _/ Q6 O4 k
  273. LDA #$00
    5 o7 F( S! K& r8 }6 H
  274. STA PPU_ADDRESS
    " ]+ C3 d# Z1 N. q4 C% e  U; _& u

  275. 6 F2 O+ N' g1 s0 |
  276. STA PPU_SCROLL4 }5 N# |  ]5 M! b5 A+ n4 \$ m& N, x- D
  277. STA PPU_SCROLL7 Y# Q/ S( d) c5 H* B  n
  278. . g9 U. s2 F7 c' f3 S2 O) y1 a
  279. LDA PPU_Msak_Buf# V' ?" t0 K2 u' k( k
  280. STA PPU_MASK
    7 A" }: `! Y: M; X  H7 {
  281. ' S, I7 U  k6 ]7 e# f
  282. RTS; N1 `, m3 b  I, w

  283. 6 \4 |7 \) N3 g' B3 N- T
  284. ;==============================* [- `7 N, o7 z7 Z# }* U7 j7 M! Q
  285. Time_For_Vblank;延时等待$ h( p; b) f  `7 C* d# O+ Q
  286. LDA PPU_STATUS9 x0 d# [2 \9 A" ?/ Y
  287. BPL Time_For_Vblank4 ]& A) v# \) n5 Z
  288. RTS
    1 H7 x/ {! ~* v# Q

  289. / e5 T  ^: Q, v
  290. ;==============================9 ^5 y, G, d9 d+ E$ N1 {. }- Z3 V
  291. ;初始化MAPPER199 v8 l9 E2 s4 U1 I
  292. Init_Mapper19
    ( R2 _! M8 H+ w2 }3 m6 V8 T
  293. LDA #$00+ c& m; Q& W0 Y' V& C
  294. STA M19_CHR_0000
    & \1 |. D, H8 |+ R
  295. LDA #$01$ {. R* H+ I3 e, {) `6 E4 N$ Z
  296. STA M19_CHR_0400
      m) [2 C5 i: X- A
  297. LDA #$02$ E6 l7 r! q7 K: j9 \7 R
  298. STA M19_CHR_0800: {: ^7 B) W+ S4 j0 o6 u: o( F) E
  299. LDA #$03
    ) o& Y! w1 R& o
  300. STA M19_CHR_0C00/ F- c# ~) m" M7 X6 ~
  301. LDA #$04
    $ O+ `. a# [  K6 {; a3 e* ~: g9 S
  302. STA M19_CHR_10005 e3 P8 e8 {6 N9 [0 j1 U
  303. LDA #$05
    1 ]9 X; P4 Q5 c" }) d% Y& G
  304. STA M19_CHR_1400' b7 M3 u/ \( A' _% A% \+ ~" n
  305. LDA #$06
    / ]' l, w4 `( U! {, G. z
  306. STA M19_CHR_18003 u6 Z" T. v7 q& D
  307. LDA #$07
    , V0 t; u. i! V8 L4 e* o' Z
  308. STA M19_CHR_1C00
    6 ?1 m& ^2 c9 K& {7 ]

  309. ( P4 E/ H% p/ Y/ o
  310. ;禁用IRQ4 j( t, h9 S1 l' M
  311. LDA M19_IRQ_COUNT_H
    * Y' Q1 Z1 U2 k" D
  312. AND #$7F
    8 N5 u* Q8 y0 r/ t
  313. STA M19_IRQ_COUNT_H; q; k0 u: \1 e, R

  314. : j  X9 c2 U0 i' `0 N1 j7 c
  315. ;命名表" h1 p8 F  ^/ J, t# w% N
  316. LDA #$E0: i" u1 Y3 m; z: \* c0 Q! q
  317. STA M19_NT_20006 J) C4 I# I. r) d
  318. STA M19_NT_2400! p/ ~: j, p1 i2 u* o7 K

  319. 7 [) ^- t" d* |5 v8 s, f0 u0 G: s
  320. ;命名表
    2 [9 c3 N( g7 |# n. b3 L) \
  321. LDA #$E1
    4 E# l- t, A5 N' i+ j7 T1 @# Q
  322. STA M19_NT_2800
    9 W' k- ?6 r! t, W3 d' n5 `
  323. STA M19_NT_2C00
    & L) u% w- I  D" ^8 X# M( x, s
  324. 3 [9 ^9 b5 U% R4 O& ~- w
  325. RTS9 Y# p& h. H  O# b( \2 G
  326. 4 X4 }9 O0 t0 o. s4 P4 W
  327. ;==================================================' ?; `7 a0 D4 d: S4 o* V
  328. ;重置中断处理
    # W! I4 f5 R8 A, o- A9 C
  329. ResetProgram% E- ^6 Y9 ~* B3 Y7 u
  330. SEI3 [/ n/ r* C" t
  331. CLD, r( [8 k9 N* a5 V2 L9 ^, U6 g& ?
  332. LDA #$00
    ) q6 |9 T! }: _3 M6 l: d; c
  333. STA PPU_CTRL1 @$ h) Q' x2 P
  334. STA PPU_MASK
      G4 y7 P! W6 r, [. `( c$ }& b% E
  335. STA PPU_STATUS
    7 a, K  q% [3 o$ |  N
  336. STA JOY2_FRAME5 Q1 d% c7 p! S/ t2 ?/ s6 s
  337. STA APU_STATUS8 H% I3 U( W" w; w

  338. $ B' U& ^. s  a$ Z
  339. LDA #$C0& C0 X* w3 T5 J6 o# g4 u+ F
  340. STA JOY2_FRAME
    5 a. v. g0 u: b
  341. / j; ]+ k7 N# u8 t% G
  342. ;等待vblank
    # n: l7 p3 a  {( a) s+ y/ R& `1 W$ ^
  343. LDX #$02
    ! e" S; _$ S# S7 h( r5 W1 A. A
  344. Vblank_Wait_1
    2 L  T- z; Y0 q; v- }0 b  p/ ^
  345. BIT PPU_STATUS5 V0 p! N  N$ y* y2 P% b' H0 Y
  346. BPL Vblank_Wait_1
      J7 I$ Z) g9 o% l' Y" l( c* E, t
  347. Vblank_Wait_2
    , D" Q2 U# Q# c
  348. BIT PPU_STATUS
    - Z9 g$ T* C7 {1 l8 Z+ B+ v
  349. BMI Vblank_Wait_2
    8 O! v' O" N+ p# M5 _
  350. DEX
    ( p8 p7 {: y4 g% |% D  k
  351. BNE Vblank_Wait_1
    # N% |  l4 ~% s5 Y: G; Q  @- K6 Q
  352. 7 m. o. c6 L. \
  353. LDX #$FF- a7 g( N0 u% K$ c& O
  354. TXS
    6 d% L# m% H3 t6 t- q. D
  355. 3 z# `9 ^% I. e$ a6 I+ W
  356. ;初始化MAPPER19! p% D3 p1 v" x
  357. JSR Init_Mapper19, _- O+ \, }7 E  I( z; s

  358. % z0 A( u* ?: }0 n( K0 `; `
  359. ;==============================
    - r4 T6 O0 {6 X* Z
  360. ;RAM初始化
    ' x  V1 t. x  Q. ?4 N( Z. e9 z
  361. Nes_Ram_Init3 x- m9 ~6 s9 w5 N+ P
  362. LDY #$00
    6 }2 Y2 `+ z  F- x7 i/ Z' F
  363. LDX #$08; }( E& M+ v! D7 A# u" o& ]
  364. LDA #$008 T& I. \# i- ~" ]0 ?" W0 t: `
  365. STA <$00* h0 S' s% e4 E8 ~, T
  366. STA <$01
    ' k9 n  n* p$ U! _4 _
  367. Nes_Ram_Init_Write
    4 Y) t$ j7 F; w; L
  368. STA [$00],Y' _3 p* H1 v+ o2 m
  369. INY$ e. [6 i3 h: M$ _
  370. BNE Nes_Ram_Init_Write
    . A3 P0 Z6 b' t! w
  371. INC <$01
    8 J- N5 b8 b# o5 W! B
  372. DEX
    9 M: m7 H4 s- N- {+ u1 c
  373. BNE Nes_Ram_Init_Write
      O6 Y$ [. L6 c8 ?" U: u8 W
  374. 3 f3 U2 J- t2 c* h
  375. ;初始化命名表
    : d4 V1 P# H7 q# h& `
  376. JSR Init_Name_Table
    , |" B; \# @4 Q3 R, d# D7 F# O
  377. 5 M- ?- P) p* E! c3 R
  378. ;初始化调色板& r# J& a1 r0 F* A
  379. JSR Init_Palette
    ( q& R9 |7 h  o( M3 n; P6 a
  380. & w* H& q; a$ R# X1 @
  381. ;初始化命名表属性
    4 J. j" `  K: d# |2 W: u
  382. JSR Init_NameTable_Attributes
    ! X% B( z1 X) e, z5 b

  383. 0 @; y* k/ r( F
  384. ;初始化精灵内存8 ~: }! ^- F% U+ C  w2 n( B
  385. JSR Init_OAM_Ram4 z% x6 e/ [/ w
  386. , E/ `) U, m: O5 t/ u. v
  387. ;在屏幕上写点东西
    ; \6 i' X! N9 N+ q
  388. JSR Init_Name_Table_Text/ q9 ]- d# {) O* A) {. z, q5 J

  389. & P5 X* |0 e: ?
  390. JSR Time_For_Vblank1 o( A+ ^" m9 n1 |! D
  391. ;开启PPU控制
    3 m0 t1 H6 M9 i( L1 e1 S
  392. LDA #$A8; O# ?+ u8 D% ]& I$ y
  393. STA PPU_Ctrl_Buf  T3 e/ T( {  K5 u' X$ m
  394. STA PPU_CTRL$ `: b) z0 u4 H) I& V: s$ B

  395. ; K& }8 H% v5 x, o( W
  396. ;开启PPU显示2 \! A- V+ f- B. n+ p: Z+ U% y
  397. LDA #$1E
    0 E0 \  s, n  z+ J
  398. STA PPU_Msak_Buf
    , z) [/ W8 V* ^; L1 m  x
  399. 2 y# a7 T$ c- b, c+ q
  400. CLI
    . y  w( M4 f, C+ F, e
  401. JMP Loop
    " h/ [5 {0 Z* \
  402. % x7 x- X/ e7 T1 W
  403. ;==============================
    + f% n1 M$ x: |/ {8 u& v
  404. ;死循环, 等待NMI中断! E* N7 Q1 \5 o+ Q
  405. Loop
    2 S& @& m2 _6 Y* i
  406. JMP Loop* p7 o2 E# J1 s' K
  407. 1 z8 y9 S2 B1 k3 t7 q* e, ]& O- m
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    0 l1 T- _# y: A, P- e

  409. ; H5 e( f8 d4 f  o6 K9 I
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)1 [/ v. K+ b0 c  ]( @* c
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    + |: B- `: c# }8 B4 v8 E# b
  412. ;==================================================
    8 S0 q: C3 p. I' F
  413. ;NMI中断处理
    : v4 c* f- Y! ?* `2 w. v
  414. NmiProgram
    # j# r0 j% _( Q4 C3 O$ B
  415. PHA
    # L# S0 C0 t9 S6 `  u
  416. TXA
    ( P. L$ v) J8 `% a4 x1 i4 `
  417. PHA
    ) E2 B. x7 R1 Z( E- e
  418. TYA1 k/ @4 ~8 p- r, ~
  419. PHA' G! ], m. H/ k1 `
  420. , x1 l4 q' b6 O  g3 Y
  421. BIT PPU_STATUS
    ' x# V; T# c6 e6 o
  422. . y& p/ D, ^, t( j0 C  y
  423. LDA #$00/ ~% D* X. q& S1 Z& w* I- {
  424. STA IRQ_Index
    ) {8 m2 ~, b. n

  425. / C3 o/ |3 x: k+ k+ l+ n
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    / `( R, L/ v+ U  {9 @
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    $ }. F$ p% q( G( \0 q
  428. STA M19_IRQ_COUNT_L  a( n9 ~7 {7 W( Q
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START): [8 R" u% t: T, r  |" r
  430. ORA #$801 U2 ~0 Q# X. p: u" U
  431. STA M19_IRQ_COUNT_H2 m2 s' F' M/ u9 v. Q) M; g+ f/ m
  432. CLI
    ) a  b9 \6 R2 y7 k$ m; Q

  433. 4 z6 P1 _7 ~3 s5 E/ i% M# q  K
  434. ;关闭PPU控制
    ' C( q" T! A7 Y/ J
  435. LDA #$00
    3 M7 a4 J+ c; b" }
  436. STA PPU_CTRL6 H% |* D7 j. X: j+ n+ O
  437. 1 ]3 [% b) ~$ B% F! U1 K
  438. ;处理PPU5 k# A0 J4 w) D9 G! ^# r0 p
  439. JSR PPU_Process
    . u- F5 i0 {! f$ r" M
  440. 0 ~- G& b: ^+ ^5 q* ~+ I* J  `
  441. ;开启PPU控制: Y2 ]4 \, l+ X+ `
  442. LDA PPU_Ctrl_Buf
    ) {$ N& }- h# O$ F, b
  443. STA PPU_CTRL6 ]7 I9 V, D8 i# @+ S& }) x

  444. ' a9 i) I: u+ V. ]- k: i* O
  445. ;手柄处理
    6 k- c1 H* Z, _. Y. x( {$ {  B
  446. JSR GamepadProcess6 }+ i6 k" I$ I- A7 ]
  447. / ~; @( Q1 m$ p% C# u
  448. LDA #$00
    3 q4 t# o$ c" H: g5 L
  449. STA IRQ_Index5 h5 J/ @$ ]+ s+ V& i* S! L
  450. 0 X; l9 v7 h8 d
  451. PLA; T& y/ t. |, d7 I
  452. TAY
    ) |3 g! f( m8 _5 r; B8 U
  453. PLA
    / h0 H6 F- U! L3 A8 n
  454. TAX
    6 e0 `( u+ }1 u7 k3 g
  455. PLA
    ) @; ]! \8 t9 j5 O
  456. RTI. @( ]$ j9 c7 \7 y  C# Q3 G. y! z

  457. " o# x3 j6 |* b$ ]: O
  458. ;每行扫描线113.673 g, ~: |  e; H0 P
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    - w+ h; z0 b' q/ }- M
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 78 U) z: A5 f9 F9 e; i3 z1 j* U
  461. ;==================================================
    7 B0 f: A% A8 a+ g; R
  462. ;IRQ中断处理
    : A9 {' B6 g1 m( u8 I! T
  463. IrqProgram4 X2 x6 s1 v2 j* V9 N7 ?
  464. PHA7 w' g; [9 |: y$ ?
  465. TXA
    % y  S  _6 R1 H. f: k; b# a( R
  466. PHA
      a" J: V. v. T! q7 L* a
  467. TYA6 o# N' L5 c; ]3 s* [5 Q( a
  468. PHA
    , u0 K+ Q5 k/ c

  469. ! P: Q5 }, o: S' G2 ^" x
  470. ;16条扫描线后触发IRQ
    9 r. n0 ^) g8 h# W* o  i! W( A
  471. LDA #LOW(BEGIN_LINE_CYCLES)  c$ C) Z' R# _1 F4 |' G
  472. STA M19_IRQ_COUNT_L
    ! T1 Q, Q7 h/ p: O+ W( ?2 ~/ k
  473. LDA #HIGH(BEGIN_LINE_CYCLES)) M. _2 Q( j- k1 s8 E
  474. ORA #$80! R) B5 H) t5 }# A  y
  475. STA M19_IRQ_COUNT_H2 o# S! F. c' t1 n5 D  Q
  476.   d5 ~5 t5 j; }$ z9 f
  477. LDA <IRQ_Index
      ^/ e! w0 d; s) w' g2 h8 u
  478. BNE * + 4
    ( c# T$ E1 y! t) @! ~
  479. INC <PPU_Scroll_H! B0 q& z9 f" T5 W! b

  480. - p' D+ V; y5 @% c/ Q8 z# e1 n
  481. ;设置屏幕滚动
    2 H" ~! g: p6 z7 p
  482. LDA <IRQ_Index$ s! V; e  F' O) C, D1 ?4 j
  483. AND #$01, O/ J- Z3 `2 M. n+ q6 \& J
  484. BEQ Irq_Scroll_Right3 N1 l9 J5 W9 a9 O' [4 z4 ]2 b( [

  485. 5 Y) p% w" c5 H0 }* c
  486. Irq_Scroll_Left
    $ [4 b; \6 y' m( Z
  487. BIT PPU_STATUS% H8 C. ?! ]; L0 G" m
  488. LDA <PPU_Scroll_H
    , @& a* J$ t  v9 J
  489. STA PPU_SCROLL
    : @/ J( X) X4 d7 Z7 E
  490. STA PPU_SCROLL; y" }- p2 V2 d1 }+ m1 _
  491. JMP Irq_Scroll_Over0 t! Q4 a# @1 }' b- W2 d6 \

  492. ; |( B  v2 L9 a6 n& \
  493. Irq_Scroll_Right
    + v0 I1 U: t' {: t- T
  494. SEC
    ) }. v# h5 p5 U
  495. SBC <PPU_Scroll_H; v& K% K* ]: F4 d
  496. STA PPU_SCROLL
    ( [! E9 ^6 e5 ^6 y" E; r
  497. STA PPU_SCROLL
    " R- d  l: t) T1 s7 O% l
  498. Irq_Scroll_Over
    2 U4 n, F  h6 K4 O
  499. - d" g4 ^& o( B; L  z& t% ~( D
  500. INC <IRQ_Index
    7 P5 Y5 W1 X5 s
  501. 9 C! t/ N8 u! @
  502. LDA <IRQ_Index4 z. n+ u( ~" X, I; p5 g3 x; L
  503. CMP #14
    ' _$ V; }& }0 V8 F
  504. BCC * + 10
    : P3 I. V/ V  D1 C0 [
  505. LDA #$00
    7 j7 N2 }) g8 h- x. K, |8 _; D% p2 `
  506. STA M19_IRQ_COUNT_L
    6 t& V7 W7 k. Y" M
  507. STA M19_IRQ_COUNT_H# q1 C' N8 D$ ?5 r8 V  r
  508. + `0 Q/ j+ ?. k: U6 r( _
  509. IrqProgramEnd: D) N) o8 U+ `# @1 V9 A* _- u* ~8 a
  510. PLA
    ( g! J4 A! I  m- d0 P1 {
  511. TAY
    % T7 ~5 V6 |# i3 S4 S
  512. PLA8 k. C( \9 m' L! }
  513. TAX, o# r' K/ B+ n
  514. PLA
    , u6 M# M; H; D! m9 h
  515. RTI1 V1 T6 J# w* S- f) j
  516. 3 D+ u+ i- E* {- t/ `+ s, A* U2 I
  517. ;==================================================6 B! z( G4 x  ~! V* y6 g
  518. ;中断表2 S; i% h( m# Y5 g8 H( |' Y
  519. .ORG $FFFA
    9 ]# M* |, g9 ]+ C( w7 m! b9 u* Z
  520. .WORD NmiProgram0 F  Y/ r9 k) O) {
  521. .WORD ResetProgram  W5 c: F0 E4 r
  522. .WORD IrqProgram
复制代码

  U& b- T& \8 c' n% @5 B

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-9-17 08:49 , Processed in 1.172851 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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