设为首页收藏本站

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    " D, i7 D3 l5 c. k6 a# Z; A
  2. ;FlameCyclone 20230710  h. l  L2 `. [6 K% y8 R. z: p

  3. * V# F8 F, U) i& _* M4 f2 ?
  4. ;文件头
    5 H' ~4 ]9 s; B: Z/ o0 g
  5. ;======================================================================" F! A5 N1 M* I+ T7 L
  6. .INESPRG 4                                              ;16KB PRG 数量) w- L# j& d! n9 v7 i9 R+ J2 k/ u
  7. .INESCHR 1                                               ;8KB CHR 数量- b' j4 |4 [4 C9 ]) [8 I
  8. .INESMAP 19                                                 ;mapper 194 p6 C: R4 I/ r( A5 ^. W% {# [
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    7 N" w8 Q2 _) c, H- N) G. f

  10. - F3 t% I4 @0 N2 s' [! }
  11. ;必要条件# `6 J* s+ N' A2 q
  12. ;1.持有CHR ROM) U: H+ ]  s. N7 _7 }
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000: L: ]* x6 T1 y
  14. ;3.精灵内存(OAM)不为空! ?9 e2 E8 {; x# ?

  15. + D2 D: o6 O# u- X
  16. ;==================================================
    9 k: W8 D- n& O0 M- _, z, S
  17. ;NES端口常量1 b" L. J3 i  ?* S( H! _* H
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器
    : W& ~. R+ {+ {( d
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    5 A; r: Z0 I* c8 X' A
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    - p' t) N* T8 H1 `' E$ L: I2 C) h
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加12 z: T# a" W7 g  t% k/ h4 t
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    % C! G# A3 W. b5 W9 b
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
      u1 H2 N2 V9 P: [( _) v7 I
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    0 q! X, o+ v9 `% {" I: Y  s
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    # D' M9 a6 h5 V; n7 Q8 m% Y
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存% B/ V. i8 n: Q
  27. APU_STATUS              =   $4015   ;声音通道切换
    / v& h5 ], K0 h9 f
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通
    # `+ G6 X/ `: O' k/ x( b  `: g  ]+ r
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    8 }; R# r& g* s! T

  30. " B4 T) [' [2 R2 ]
  31. ;==================================================
    ) t$ a; `; v1 k& U" M  l
  32. ;MAPPER 19端口常量. |$ @% S+ x* A9 ?# f5 p
  33. M19_CHR_0000    =   $8000$ a( W7 _& E$ m3 P3 K8 H' {
  34. M19_CHR_0400    =   $88006 M, }& l0 x) H- b; T( |
  35. M19_CHR_0800    =   $9000
    + A8 x6 j" g# d" Y; i* e3 F% G
  36. M19_CHR_0C00    =   $9800, o! n3 Y, O3 i
  37. M19_CHR_1000    =   $A000! }' d. v5 j- ?2 P
  38. M19_CHR_1400    =   $A800
    # \4 T/ X+ R, Y
  39. M19_CHR_1800    =   $B0007 W$ }; w' K- }) B" q4 l2 s
  40. M19_CHR_1C00    =   $B800
    & A' h8 L# G0 `' M5 n6 N
  41. M19_NT_2000     =   $C000# k; q7 ~$ \0 E7 a+ p
  42. M19_NT_2400     =   $C8009 Y3 o% D/ a3 K% q3 Z7 {, c
  43. M19_NT_2800     =   $D0006 a5 F8 E6 Z# Y" i+ G# W
  44. M19_NT_2C00     =   $D800& K0 M/ y9 C2 D
  45. M19_PRG_8000    =   $E000
    ; C$ L( v2 |  I9 T5 L! N) p; m$ A
  46. M19_PRG_A000    =   $E800
    / C# U* I, x3 @0 o5 ^/ H
  47. M19_PRG_C000    =   $F000
    ; w9 B/ P: x% X$ Z/ T# E
  48. M19_IRQ_COUNT_L =   $5000: ]6 F7 k+ \. h1 ^3 b$ M
  49. M19_IRQ_COUNT_H =   $5800; Z3 U. \; B* e/ {% v
  50. ) r( }3 A# D' Y" @
  51. ;==================================================
    8 X* C/ }8 n2 e/ I" B0 s0 G$ d
  52. ;程序块配置" R+ {( a1 p; w! h+ Y% i
  53. BANK_DATA_MASK          = $07
    ! |; l7 T8 M- U' _/ c, P
  54. ;--------------------------------------------------& ^# n8 p  _0 G3 v" |# o; C
  55. RESET_BANK              = $07* z- t5 K8 y- ]8 e( ]
  56. RESET_ADDR              = $FC00/ V6 H' B- u8 A; }6 d& Y

  57. - ], ~8 o9 W$ X4 r! Z  F
  58. ;==================================================$ ^4 J" V- w4 f/ s$ v, c" Z
  59. ;图像块配置. ]' l) r  ]+ q6 C/ Z3 }
  60. CHR_DATA_BANK           = $08
    4 p) P( I6 d0 G3 l$ g! s( \% M9 m

  61. 0 L6 \7 |) r+ F/ H' z7 t7 [! K' J
  62. ;==================================================
    / l9 u% t" c* i# q) c
  63. ;零页内存地址配置9 i8 X' ?' c  k( ~+ W" G/ g6 _3 s
  64. Use_Ram_Addr            = $80% F. c6 Q# G9 h: e2 T5 f* \
  65. PPU_Ctrl_Buf            = Use_Ram_Addr* S+ d: q& Y) b' O
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    & x( l9 Q, m, }9 x( \
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    / q+ V& Z0 r) m! }, }; ]
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    0 c) X* W, g7 n& `. n+ z
  69. FC_Data_L               = PPU_Scroll_V + $01
    & e6 R0 P3 [. z7 D1 c# Y0 D
  70. FC_Data_H               = FC_Data_L + $018 P/ `( W! n% z  O
  71. FC_Data_Buf             = FC_Data_H + $01' M; z- F0 V' u7 o9 k
  72. ;==================================================+ a3 L# v4 B5 w- h2 A" R

  73. ' P) ]7 F% H1 O) E7 v7 Y' x4 k
  74. GAMEPAD_MERGE_FLAG = $04
    ' x4 `. @$ V; \- K* t

  75. 4 y* M3 b' p9 Q% ?' X
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    # ?# C9 b% q6 j' ]6 [
  77. Gamepad_Once            =       Gamepad_Keep + 2
    + J1 V) Q' ^9 O  j8 d1 h; B. E
  78. Gamepad_Temp            =       Gamepad_Once + 2! d  d/ Y* W! I* b$ k5 p
  79.                                 4 j$ ]/ o8 W# }; c+ [
  80. Gamepad_0_State         =       Gamepad_Temp + 2. q8 s0 x' l* G: O* G
  81. Gamepad_1_State         =       Gamepad_0_State + 1; ]8 O0 b8 ~2 T: [9 D/ y; O( Z6 j
  82. Gamepad_0_Value         =       Gamepad_1_State + 1* h: @5 g8 E+ Z
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
      O! X) f3 J! B2 s5 c& ]# G
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    % Z9 U* p. A4 ^) A3 b6 o
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    , G) J: J5 U; J0 ?& O7 P

  86. $ H. s# X5 Z& Y1 H
  87. ;==================================================
    * f+ Y$ z) x+ `5 c* w) m* o
  88. IRQ_Index               =       Gamepad_Merge + $01# r3 U/ \4 c1 y
  89. ;==================================================$ g, S0 U1 ^" x

  90. 4 L3 I0 y. g, G0 D; t, {
  91. ;CHR图形数据
    ; U& q1 u) T- m8 Y* G# i3 Z
  92. ;==================================================
    ! A6 P7 {2 U* s4 g- y: @1 M9 P% Q
  93. .BANK CHR_DATA_BANK1 l& X$ w  d# x
  94. .INCBIN "chr_bank/chr_data.chr"2 P& U$ N0 e3 f* ~

  95. 7 B/ N8 z, G9 A! e0 f+ a% K
  96. .BANK RESET_BANK & BANK_DATA_MASK  g# e8 t, }% ]! L3 ?' S) Q- v1 z
  97. .ORG RESET_ADDR+ j  ~8 }, t; R1 A: i2 H2 F( a
  98. ; G' {3 w9 |9 H  D$ B; h
  99. ;--------------------------------------------------
    1 r7 E1 V/ K. s: m6 k5 N
  100. Attributes_Data4 h* K0 G! L. i# ^
  101. ;命名表属性7 L) q. a" o( L) l
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$006 c4 a  k# t4 R+ W  x
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    2 x1 m; W' k" _: L  L7 c  U+ j# e
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
    / i% ?# a! [0 @1 g* B
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$552 b7 ^/ ~! y' _8 q0 L! x% P
  106. ;--------------------------------------------------; w/ c1 V3 @  n
  107. ;调色板数据* u$ e1 }7 c/ v+ `$ w3 E
  108. Palette_Data( t2 ~- ]4 }0 a; K
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F$ y) a' K2 J* l6 ~; r
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F6 S2 d8 h+ }) h0 _% y. W

  111. 5 r, s, b% K- b2 H2 H
  112. ;==================================================
    # ~2 b9 f" v' _; t1 k) C6 x3 b
  113. ;命名表初始化8 |" k# G  n8 C1 _. e" ^" ^
  114. Init_Name_Table
    - t8 J% k# ?6 \, q
  115. LDA #$20
    5 E9 I. A# M3 K' ?& x2 O
  116. STA PPU_ADDRESS$ i0 h! F+ z* ?- `% K, o( F
  117. LDA #$003 T+ A9 Y; h; ~- c
  118. STA PPU_ADDRESS  U% N. I7 W% I8 k& U
  119. LDA #$00- c/ |( H8 x/ W0 @5 O1 C
  120. LDY #$00
    6 f4 h( ?  {0 V2 ]' R- p1 J
  121. LDX #$10
    : K7 |, r" z. `4 e" b" L6 B. \
  122. Init_Name_Table_Write
    ' @; x8 M* Z( G" I+ I
  123. STA PPU_DATA+ ]: [- Q; t# D* }3 h1 Y. J5 ?  h
  124. INY
    + Q6 I! B  P+ i6 P3 J5 p3 J7 G
  125. BNE Init_Name_Table_Write; X% |4 I. n3 h( R! h4 n* |
  126. DEX' G4 f3 g$ [$ Y' l! G
  127. BNE Init_Name_Table_Write1 ^3 m$ J, Y* A9 Y; m2 X! Z
  128. RTS9 k9 o' x: \2 r, Z8 p0 c7 N. R

  129. 1 D. _3 V9 L+ R
  130. ;==================================================
    $ I$ W; G/ v7 w
  131. ;调色板初始化; H) C$ k. U, C& C
  132. Init_Palette0 w7 V! ]; B( w
  133. BIT PPU_STATUS
    1 @" j% [5 D. ~1 H5 v8 c" {
  134. LDA #$3F' }% h: ], j- O7 Z% K0 V9 k/ Y
  135. STA PPU_ADDRESS
    $ R6 S) W) E1 D! y" K6 t  ]( Q8 Y
  136. LDA #$000 u7 y! s0 r: t; a) q7 X
  137. STA PPU_ADDRESS
    4 P  ?# ~8 G; A# e
  138. LDX #$00; z6 a/ z7 b4 ~6 N- M
  139. Init_Palette_Write
    ' e0 I$ U, A& g. b  ?, V
  140. LDA Palette_Data,X3 N6 q9 r1 M! ?
  141. STA PPU_DATA, y% m; y; ^* O  [+ ]
  142. INX
    / T# I7 x! K# Y$ q/ s' v& z
  143. CPX #$20
    , Z+ W' y0 [9 X! D
  144. BCC Init_Palette_Write
    6 z! ]- j3 r* ~9 a/ E- q/ S
  145. RTS5 P7 V/ a$ L) v4 O* h

  146. & b0 I+ F" P9 w5 V3 c; V3 W! ~
  147. ;==================================================% o1 A6 U: ~# _7 R) z
  148. ;设置命名表属性
    / g5 k+ W# A' i( H+ O6 W  I2 a
  149. Init_NameTable_Attributes* y& [; |5 j+ ^* o
  150. BIT PPU_STATUS0 K) I$ `; K4 z$ n, @" |: x  X1 r
  151. LDA #$233 B/ _" u+ ?, N0 F- ]: w5 [
  152. STA PPU_ADDRESS8 C. M6 d) y6 Y: c
  153. LDA #$C0
    ! N" X0 k* J8 Z( X  {
  154. STA PPU_ADDRESS- ^2 O, c( K9 X* c
  155. LDX #$00& _: D. N4 a0 r. R
  156. Init_NameTable_Attributes_Write
    2 v+ k1 t9 e  R
  157. LDA Attributes_Data,X
    2 `; F- l6 }) @' i& D
  158. STA PPU_DATA! h+ |% r6 j) l! x7 e1 m
  159. INX
    $ j4 y( b  d0 c- G, U% T
  160. CPX #$40: W, z* m7 Q' B0 M, T. d
  161. BCC Init_NameTable_Attributes_Write, N. H. r! ^* W$ V( a, c& h
  162. RTS0 G+ w" j: z6 n# B0 i) h
  163. ) b5 h7 D0 t3 b( a) F
  164. ;==================================================3 V$ S/ }7 W# F& |. I
  165. ;初始化命名表文本% L% ]4 G- p$ M! g7 X6 m
  166. Init_Name_Table_Text! X7 _' R: L) @3 \" F
  167. BIT PPU_STATUS
    / `9 m5 Y# F( s5 H0 \) s( N, v" R$ }. b8 r
  168. LDA #$205 g  p3 H9 R8 v: i
  169. STA PPU_ADDRESS
    - m- Q7 T( r( T/ Q! n
  170. LDA #$00
    2 ]; O7 Q- C5 t) A1 X' i, t- `! `( G  I
  171. STA PPU_ADDRESS
      ], z0 J8 Q* i# g
  172. LDA #$00
    & y  |6 k% a( H8 e+ n
  173. STA FC_Data_Buf# U# L( h5 q: j0 v3 d7 F
  174. LDY #30
    6 J' j% S0 y6 K: o# q
  175. Init_Name_Table_Text_Write+ L! p$ U& s: F8 X$ y) I" B
  176. LDX #32
    1 H6 w( m! u. f+ }7 [7 S' b; R/ F
  177. Init_Name_Table_Text_Write_Char, ^& {* A$ G1 W
  178. LDA #'0'
    8 K) l0 s. q, z+ F1 v
  179. CLC/ ]. K& _5 a( s) Y
  180. ADC FC_Data_Buf
    4 Y6 w0 E5 V/ _  D. u3 p3 I
  181. STA PPU_DATA- e# J8 W+ @3 u* `. B$ I# o8 d
  182. DEX% q/ b; P" l# v
  183. LDA #$14% i& R. B! A# @7 y' F
  184. STA PPU_DATA
    " F* l5 A- o/ |& t% |
  185. DEX
    8 X" g3 O8 e- m0 o! a) H2 I1 f
  186. BNE Init_Name_Table_Text_Write_Char" i5 w0 h. \. y* M
  187. INC FC_Data_Buf
    $ N/ Z( ]. U6 H' Y6 q$ e3 p
  188. DEY
    6 F" g7 a- v% n4 ]
  189. BNE Init_Name_Table_Text_Write
    3 V7 R. Q: [/ X& [! s7 Q: X
  190. RTS
    + H( ?; p% r+ T6 ~" j
  191. 7 b: u& R8 v* ?
  192. ;==============================
    9 x% U1 g$ \# j" s- n7 }
  193. Init_OAM_Ram;初始化精灵内存
    7 a; j1 E$ H7 {: d! E9 b
  194. LDX #$00
    8 t/ ~) z- z- x+ Y4 S& f' E
  195. LDA #$00
    . I" D+ X8 p1 p) ~. }5 Q. \1 r
  196. STA PPU_OAM_ADDR
    * a- H/ d* u( a! Z0 a9 K9 C) r' ^
  197. LDA #$F8
    . K1 E$ }3 o! w0 W5 |
  198. Init_OAM_Ram_Write
    $ J2 P5 h0 V. L8 a; Y
  199. STA PPU_OAM_DATA5 N( \1 s! C3 z# P3 u1 F8 j
  200. INX
    : W2 U) \8 _+ ^7 b/ b8 l
  201. BNE Init_OAM_Ram_Write
    3 M3 _' g$ Q9 S% s/ C
  202. RTS. A% a8 A( n0 |1 s! W
  203. 0 A7 U# O% q; D# E
  204. GamepadProcess;手柄处理+ ?+ C9 e6 c: V  q& a+ a; |! v
  205. JSR GamepadDatacan7 G+ g$ N, u& ~$ K- p& L4 I- d7 X
  206. LDA <Gamepad_0_Value' F) X; Z4 X% z, K; N
  207. STA <Gamepad_0_State
    ; Q7 d3 S7 \  v8 x
  208. LDA <Gamepad_1_Value. b8 _4 V6 B; w5 [
  209. STA <Gamepad_1_State
    $ s) V, ?  W0 |' w5 s
  210. JSR GamepadDatacan' P6 ]  |3 {6 E  g6 r
  211. LDX #$01- F% l" X' `! i; w( R5 n2 s" Z
  212. GamepadMergeCheck;合并手柄输入检查  R/ N0 C* r3 m; w: k3 f
  213. LDA <Gamepad_0_Value,X
    7 S3 t5 s9 k9 {; `" d3 j2 k% X
  214. CMP <Gamepad_0_State,X6 u- d' I0 n; S
  215. BEQ GamepadMergeInput
    % Z( t- ]% p( Q: ~# ?, e* a
  216. LDA <Gamepad_Temp,X
    . D/ P' u0 E) c7 I5 d  L- c
  217. STA <Gamepad_0_Value,X
      `& t9 m5 ]8 l/ ~* e1 q
  218. GamepadMergeInput;合并手柄输入- C$ u" D8 E! V, E  Y$ v' [( p
  219. DEX
    3 ?/ B! J3 p* M
  220. BPL GamepadMergeCheck2 e5 s' t9 T$ `  v) U5 ~- d; n5 }
  221. LDA <Gamepad_Merge5 J- {6 p" F* h  }
  222. AND #GAMEPAD_MERGE_FLAG
    3 E3 w. X& R0 U
  223. BNE GamepadStateProcess
    6 [) H7 v2 e2 I) |) l0 [, e3 a* |
  224. LDA <Gamepad_0_Value
    : f0 X# ?+ c# [5 Y
  225. ORA <Gamepad_1_Value
    , h5 e$ i; q# d, r% O& X
  226. STA <Gamepad_0_Value. V4 J( p" H9 m4 _9 s2 P
  227. GamepadStateProcess;手柄状态处理
    " {$ W, P+ t  X5 \$ y% d4 a
  228. LDX #$01
    8 I9 e. H; Q& C7 t# O1 L% e4 W
  229. GamepadStateSave;手柄状态保存
      F5 e/ s% o$ N$ b9 t
  230. LDA <Gamepad_0_Value,X- ^% X( @2 i6 D5 T( P
  231. TAY
    . r# a: E: Q4 v! |0 V4 u! x/ G) T
  232. EOR <Gamepad_Temp,X" B4 C/ o0 t4 N. p1 l* ~
  233. AND <Gamepad_0_Value,X
    , {+ P( U9 H! c3 G& C- d( d
  234. STA <Gamepad_Once,X: A3 k/ v! l% t3 w$ w3 [  c
  235. STY <Gamepad_Keep,X
    $ Z# O  z. t% m. I1 y
  236. STY <Gamepad_Temp,X
    ! h. B* k8 R. s+ K  B
  237. DEX
    2 k/ |' s/ `5 _- @4 R/ h0 q
  238. BPL GamepadStateSave
    5 k9 A. g# ?6 t, Z- z9 f8 R
  239. RTS
    * G! [( }; \+ L$ f8 H) P1 E, c/ K

  240. & B' Q2 d3 u' L! J
  241. GamepadDatacan;手柄数据扫描7 G5 U5 b( {  s" Y
  242. LDX #$01& D; b" D+ Q2 }* l7 M& p
  243. STX $40162 j+ s* A, k" k- M: n' \9 I4 p2 x8 G
  244. DEX
    8 Y# J3 v. E; c0 [- C. n! X. r
  245. STX $40167 [/ H% o4 Y- }( T& i
  246. LDY #$08
    / P% I* _9 a6 ?1 p. {5 R! Q
  247. GamepadPortScan;手柄端口扫描# v4 Y5 y8 R" D. A8 L; H5 ]( V
  248. LDA $4016
    9 Z: d1 m8 u5 X  {8 B
  249. STA <Gamepad_Port_Value
      x1 T. |% E* Q: P! p# b
  250. LSR A
    . L" g% }' h0 @$ p
  251. ORA <Gamepad_Port_Value
    6 {" d3 e* [( \8 T8 i/ z. q3 g
  252. LSR A
    ( E" ~* b2 Z  a( e9 I) w
  253. ROL <Gamepad_0_Value7 `8 l) w. ^+ ~. T4 o0 U' J7 o
  254. LDA $4017, G) L% p! D3 r/ X  y2 P
  255. STA <Gamepad_Port_Value% w2 P3 a& [7 O
  256. LSR A2 h; X% P% m9 E: j
  257. ORA <Gamepad_Port_Value3 L; t# t- B; v2 S; J$ V3 F
  258. LSR A2 B5 X/ V( `( c- r; U* v1 T7 s* V' C
  259. ROL <Gamepad_1_Value7 y' H' h! N* K; B! f3 \9 j
  260. DEY/ k/ Z( i1 {3 ]9 {) ^7 U
  261. BNE GamepadPortScan
    3 \" x# t9 w- e  Z2 O1 X
  262. RTS
    ( [4 {* N& l& q0 @* Y

  263.   u3 X7 W: Y0 [
  264. ;==================================================
    1 i$ h8 @1 @% c# [( H; L" n& U
  265. ;PPU处理
    5 x3 i. y7 v% Y0 l4 n% {
  266. PPU_Process
    + Y* v$ T5 w" R% T; f3 _- F) Y/ [9 A
  267. LDA #$00
    & _0 U. i' I( d/ `4 v! T6 K
  268. STA PPU_MASK1 A8 [( i& V, Q' U/ Y. Y! V2 ?) {- X) b

  269. 3 s- q* j5 J8 n! ?- l% O
  270. BIT PPU_STATUS" D( M5 ], M' D, S" b& ~
  271. LDA #$20" M0 N0 A( i# s1 I  F  C0 P2 e3 N: `9 P
  272. STA PPU_ADDRESS
    8 C1 R1 ~) c7 i# m1 O2 Q
  273. LDA #$002 I( |( Z% a+ T' \( q2 A. Z9 ~; M
  274. STA PPU_ADDRESS
    & l' @% V; t4 y$ L; A/ _+ l% T

  275. 2 y/ r6 ]% A( B) q& y
  276. STA PPU_SCROLL
    & h) R- v: u6 N
  277. STA PPU_SCROLL/ I1 ~) b$ _6 }' h! r- M

  278. ' j7 l  w4 q7 C  D' `
  279. LDA PPU_Msak_Buf$ U7 B& a& C% o$ N& M
  280. STA PPU_MASK1 a% S8 p3 U$ T1 R, O' K4 }# Z/ @

  281. " H. H3 j' @; S$ {9 r) t
  282. RTS$ q( C8 v* R+ t3 C; \7 P, r

  283. + E; Y5 J1 s+ x) Q: Z
  284. ;==============================
    ' \" f5 v6 W# f5 b$ i1 n
  285. Time_For_Vblank;延时等待9 K$ h; b/ n. |# ^( I3 `# ]
  286. LDA PPU_STATUS4 y9 w0 ^, H) }
  287. BPL Time_For_Vblank
    + P) R5 Y! [( x6 J+ i, |
  288. RTS$ I( M0 k, v! l. X7 t# I
  289. , N3 n& J2 I3 C5 E
  290. ;==============================
    3 [6 |- t$ j# l' f5 A, \
  291. ;初始化MAPPER19
    3 x- e+ i- T1 S
  292. Init_Mapper19
    - O# G0 }% f" P; t# o* r
  293. LDA #$00
    ( E' j1 {6 y: y: M; i! H. a
  294. STA M19_CHR_00001 u+ U2 ]( R; i
  295. LDA #$01
    * t- x- I0 x# o6 n7 e
  296. STA M19_CHR_0400
    1 [* A5 {; O, R0 c$ Q
  297. LDA #$02
    / ?$ [) v( U; }- H  a- b
  298. STA M19_CHR_0800' y" p9 ?4 t7 I- l* j$ @* N+ z8 Z
  299. LDA #$03
    6 ]' [3 e& G2 n: K9 m8 m# c
  300. STA M19_CHR_0C00
    - h2 }/ k8 J! k5 I- S; W
  301. LDA #$04# }3 E' c7 @" H' H
  302. STA M19_CHR_1000
    4 ]; j# R9 Z& S+ @0 y: z
  303. LDA #$05
    . ^4 I( b6 [8 F$ ~8 M4 K1 ?! K
  304. STA M19_CHR_1400
    / D/ }+ G+ m3 u7 ^
  305. LDA #$06
    2 M, ^# D% g& ^+ x- w
  306. STA M19_CHR_1800
    5 `0 k8 d8 F  A& q, H
  307. LDA #$07; V! D+ K( K+ O0 h# V0 P+ W
  308. STA M19_CHR_1C00% t* o) m' G# Q
  309. 5 |3 r) @$ z3 `  q8 v
  310. ;禁用IRQ
    2 w+ n: m! b7 n6 @3 I( [, ?7 ~
  311. LDA M19_IRQ_COUNT_H) P! a6 c! C  q% Z6 v
  312. AND #$7F* e, u6 f" `0 o6 I5 M% T
  313. STA M19_IRQ_COUNT_H
    ( Y9 L* Y/ s% u: f# W

  314. , n7 L4 _2 L2 {" i
  315. ;命名表
      j3 E) I1 v1 D# A# ^
  316. LDA #$E0
    5 }  p$ H* X7 v3 N. |; U) [. N6 D
  317. STA M19_NT_2000
    7 b4 C2 B4 p0 U8 k
  318. STA M19_NT_2400
    , |5 f+ F; |$ P# x

  319. & T5 |* k5 _8 a0 c
  320. ;命名表
    $ U2 k; q6 g/ F: o9 ~% M7 c
  321. LDA #$E1
    ; F8 v7 a* s  Q1 l, F' B0 Y8 D7 }
  322. STA M19_NT_2800$ L  `9 e. `9 L5 q
  323. STA M19_NT_2C00
    & a+ G* U2 Q- e" W

  324. 1 F% k8 z% G9 R* p7 m# ~' Z" }% A
  325. RTS
    ) y5 R( H5 ^: T5 Q3 a

  326. 8 q& u/ Y9 w( [% R$ O0 r
  327. ;==================================================
    8 B, {2 {; h$ g1 }, ~! ~
  328. ;重置中断处理
    - Z$ Y9 P% C5 j5 i
  329. ResetProgram  q5 R2 v. y& X: _& I
  330. SEI
    - H) n3 w7 T* C& X& P
  331. CLD# m& h' q" X1 g" |) U( U6 f
  332. LDA #$00
    : d& a+ l3 D# g. a
  333. STA PPU_CTRL& ~2 ~& ?( N! `6 P: Z7 r
  334. STA PPU_MASK9 v0 L" F& u: C4 Q& O- D* U
  335. STA PPU_STATUS) c1 l: D- u3 _) |( s3 s) n
  336. STA JOY2_FRAME
    " w! P; I! G4 x$ n9 ?
  337. STA APU_STATUS( V" ^$ Z, ?; @/ ~+ W' R
  338. / x0 i6 j( f7 s0 X* ~
  339. LDA #$C09 @+ g3 f& [' A  I- y' t) S" B6 _
  340. STA JOY2_FRAME
    3 B4 z  R0 Z- v2 D0 w
  341. 1 b5 p6 r- |, }
  342. ;等待vblank
    ; _) i8 h4 n5 ?& n5 z: p3 ^
  343. LDX #$02
    9 n$ |2 k) i( z
  344. Vblank_Wait_1
    ( D; ]7 c5 ^/ _5 [2 {
  345. BIT PPU_STATUS  x) T, V6 J8 K
  346. BPL Vblank_Wait_1# M8 \) T5 N6 q: d2 }
  347. Vblank_Wait_2" a& Q; I7 c# B+ s
  348. BIT PPU_STATUS
    , @2 k( T  Y/ i- u) O; X
  349. BMI Vblank_Wait_22 q' a- N4 l4 j9 p* A/ t% A. V
  350. DEX
    % e" Q3 h* g" \/ {  l; ]% p+ a0 b% b
  351. BNE Vblank_Wait_1
    4 }+ X" x" J5 c! {0 F

  352. & m) @  i1 K4 |4 I: \: d# E
  353. LDX #$FF
    1 C) t$ H3 ^6 {" z, ?
  354. TXS
    " z# L7 e/ d( J' }9 U/ F7 ~

  355. 1 U' I- e6 v) m2 A0 X/ G
  356. ;初始化MAPPER19( s8 {+ b; S) A% ~1 Z
  357. JSR Init_Mapper19
    0 A) T6 `7 I/ s. A, O" V7 U

  358.   G. h" A1 t; S5 @# V; w
  359. ;==============================2 ~" U+ `2 d4 v) a6 F7 s* B
  360. ;RAM初始化
    1 `! c/ U" F- A/ L
  361. Nes_Ram_Init' k# i# T! {  t: M7 m/ [, m  H& o  I
  362. LDY #$00) s0 ]3 F# A/ y# y2 M, @. w
  363. LDX #$084 Q! `4 N4 w. u8 l: f
  364. LDA #$008 s, R* W( ]4 z( d9 W' }
  365. STA <$005 g5 ~4 \% j7 ~3 o4 Z: G0 J( `  U
  366. STA <$01& S9 n& T, \4 ^$ R/ F/ t& C- g
  367. Nes_Ram_Init_Write
      j: ^9 `8 {. Q- f  K% I% V2 }
  368. STA [$00],Y
    5 {% Q  \3 Q5 l% u8 Y
  369. INY
    - a* \2 q6 R9 }
  370. BNE Nes_Ram_Init_Write4 x6 a& O- ^; T
  371. INC <$01! `4 a4 ^! U( ^  V8 v9 [0 p
  372. DEX7 \0 [! _7 h% b; ]( n6 ]
  373. BNE Nes_Ram_Init_Write: l9 H4 F7 w% ?" G/ T! }
  374. # |5 U  v  O3 d7 w- L+ y/ Q0 I. T
  375. ;初始化命名表
    : P' N9 S1 X! c! F
  376. JSR Init_Name_Table7 k- I; [  A$ `9 R) L
  377. 3 g7 ?( L7 L( H0 `
  378. ;初始化调色板
    ) c& P  }7 d4 ?; J3 n
  379. JSR Init_Palette
    8 c2 i% N  H- ~1 ^3 l" y+ g0 i

  380. & i& D6 c5 f" S
  381. ;初始化命名表属性; [! h  a" m/ F& l
  382. JSR Init_NameTable_Attributes, A$ n8 r* l3 D( }$ I; y
  383. 1 E% f4 B" C) `
  384. ;初始化精灵内存5 k0 A1 S7 {6 S
  385. JSR Init_OAM_Ram
    $ M$ ^) R9 W* H5 I/ Z
  386. ) s/ P" h0 ^5 }0 [7 P% e* d
  387. ;在屏幕上写点东西( J0 D3 A* Q) `) S. u: E( x9 x# G
  388. JSR Init_Name_Table_Text
    - i) V0 x6 y; ]4 |6 _  V
  389. - I- t8 D, L$ ]
  390. JSR Time_For_Vblank
    ( @+ E) s; K; }; e& l
  391. ;开启PPU控制. \( _8 B* y1 R
  392. LDA #$A8
    ( S/ y  F, z; H& j  }
  393. STA PPU_Ctrl_Buf
    4 C2 X5 m+ ]% E/ [0 {/ p( b+ I
  394. STA PPU_CTRL
    ! I' W0 t6 W+ I* b3 f, d

  395. ( S6 f7 b  C, l& W4 E1 j* K
  396. ;开启PPU显示3 ]7 p0 X$ _6 Z0 M
  397. LDA #$1E$ W" X) q% `* s/ }* w: r
  398. STA PPU_Msak_Buf
    : O0 O6 ]6 Z! j9 p) |8 t

  399. 7 {4 |2 p7 J( \4 Y
  400. CLI
    2 d, _$ R& H* v! b& S' I3 _
  401. JMP Loop
      g" V! L1 w" N: K
  402. 8 S& u, d  ^( {% S) W- R+ i9 [
  403. ;==============================
    3 o) l, }+ \+ D$ ^# p) E
  404. ;死循环, 等待NMI中断5 f  U- A3 W6 d% w& O: }: m! ^; a$ h
  405. Loop
    : i) [6 B6 u% U" s' T  B. Q
  406. JMP Loop
    . S) E$ y& T' z" f

  407. 8 o. Y' z& V7 ]+ T+ z5 V/ \' d$ F
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    1 _0 |1 x$ T4 x/ X8 G) l

  409. / [2 F% [% Q- \! C! E
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)1 i, ]5 @1 W& N/ _
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)9 C! f) r5 f5 W# ^! K8 N; n
  412. ;==================================================! a+ u; g$ a! j! s" S- _; @  T$ E' E, i5 h, a
  413. ;NMI中断处理
    ; A* Z5 C; k1 Y7 X
  414. NmiProgram
    - S( f) I: t% H. p4 A5 U2 k
  415. PHA$ \/ e$ ]" }6 ~! p' G
  416. TXA1 ~6 h% q/ X. O% u( s
  417. PHA
    6 A" g9 W' W0 @! R
  418. TYA$ Z: \# S! c4 F" p: f, ~9 J  R6 J
  419. PHA
    * P/ g8 r4 S9 h: J4 X3 u

  420. 9 v- o& H( X& H, T
  421. BIT PPU_STATUS. p/ c( T1 W& G+ }+ x

  422. 0 a% i' G. K& A8 |( y. i. h. ~! R
  423. LDA #$00% T7 L5 s/ p, ^. G) O$ \/ v1 Z
  424. STA IRQ_Index% q: m8 G+ |8 ^* h
  425. 6 R$ Q- m% J# x" S( q0 x
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    : y3 Q: g; s2 f( e; P" f0 M
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)6 {$ s2 P0 t! o! ]* H2 q! ~$ h# m
  428. STA M19_IRQ_COUNT_L
    7 r& K0 n2 a4 ]2 K# x# U$ o4 r* a
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    . @0 Z$ J" ?* S6 P# h+ l( ?& ?
  430. ORA #$80% M" P9 d4 p. z2 l
  431. STA M19_IRQ_COUNT_H
    6 N' q9 y/ i) S$ ?0 b$ `. n
  432. CLI+ J3 s( o! |% R3 _

  433. ! g2 F( t+ }2 R- u4 b! Q
  434. ;关闭PPU控制
    1 k  q: w' }; f. f2 n
  435. LDA #$00
      `0 P( \$ ?, ?0 t
  436. STA PPU_CTRL- y& v- r7 j% a8 W7 {6 s
  437. & L# `3 r! g1 f) w! o6 M
  438. ;处理PPU
    / {8 Z1 C+ H4 d1 ^; q
  439. JSR PPU_Process
    2 Q& i1 ~3 x2 W8 Q* k

  440. / E9 w* V( s$ Z* h6 ^% Y
  441. ;开启PPU控制
    . y( g+ @6 r4 y% M& t' z* d
  442. LDA PPU_Ctrl_Buf
    $ D; {/ G* y$ H1 c4 j+ [  J
  443. STA PPU_CTRL4 ]) n/ J8 p2 R: T

  444. 6 z7 F5 n: n- r; F# p, d3 Y$ b5 |% h
  445. ;手柄处理
    6 O3 [( \9 b0 D2 ~) i+ k$ B2 M
  446. JSR GamepadProcess$ f! O* B. v& y5 e3 K$ H  M4 r8 A
  447.   [- {% U" j" M* }0 D7 \
  448. LDA #$00
    2 s4 c# \: {/ e1 s: U3 X
  449. STA IRQ_Index
    ! {* u! L3 k7 K) b0 k- m. J9 U

  450. 9 }4 F1 w. a- ~8 Z3 z4 T0 B
  451. PLA2 Z5 h1 H' B! Z1 a
  452. TAY6 {4 B2 ^2 a4 y" F' I- O% z
  453. PLA
    / E9 R2 H  s" a
  454. TAX
    6 D) q& c* a; O% q: z0 T$ X7 x0 l# J
  455. PLA$ E3 |9 C9 _/ B4 z- @4 B
  456. RTI
    & w% _; S8 h2 t0 n6 @( A) P5 M
  457. 0 g2 h; Z0 b4 c0 o3 p" C7 o/ q  H
  458. ;每行扫描线113.67
    : F/ N: ~3 Y7 t! g
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    8 L. T4 j. ^( F1 L' }, d
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    7 }7 A4 X3 `" q) `0 W
  461. ;==================================================! K( ^* s# h7 f; o* r
  462. ;IRQ中断处理
    7 `" K7 X) v- W3 R4 z3 z
  463. IrqProgram! ~; A" k  H: a# A: Q' Y* J; ^
  464. PHA
      }8 D+ c  |+ {! ]$ J" G
  465. TXA( J7 ]* F; O5 _  ^+ I9 F4 P. n
  466. PHA0 D/ _. u9 x- A# C: w
  467. TYA
    7 v$ K; Q5 m# o. ^8 l
  468. PHA1 N# r- G. {0 S) V

  469. * Q) f6 Y9 v) ^, i' y9 J+ |* `3 S
  470. ;16条扫描线后触发IRQ
    * E$ B( F( A" g
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    + |" w5 w5 Q6 U. a0 m2 g3 m
  472. STA M19_IRQ_COUNT_L
    8 b0 E& k3 G6 {- n2 s. F. e
  473. LDA #HIGH(BEGIN_LINE_CYCLES)7 `5 n: v2 K# F: M% Q
  474. ORA #$80
    4 `1 E! X3 f3 V  ^- u, l3 O8 s
  475. STA M19_IRQ_COUNT_H
    4 p7 f/ N0 q% r

  476. 8 ~" \; K4 m% F
  477. LDA <IRQ_Index
    , o* I% J: ?; {0 L+ q
  478. BNE * + 40 C4 \+ E& _2 ?; M
  479. INC <PPU_Scroll_H
    # X+ v& D! D  \* \& N) H1 \3 m5 d
  480. # y5 t+ ^; C1 O0 L- J" K
  481. ;设置屏幕滚动. l0 X( y" e4 @
  482. LDA <IRQ_Index
    9 Z/ z# H/ o' j) S  p$ L
  483. AND #$01
    , `5 I: g- ^" G9 Z
  484. BEQ Irq_Scroll_Right0 N' M. _) O4 e' b6 q

  485. . J2 W& i7 x: L+ f, l2 L
  486. Irq_Scroll_Left" F, I/ T( c; p  x0 R1 o
  487. BIT PPU_STATUS+ d( \. N. e0 H& g) l( ]! u$ n
  488. LDA <PPU_Scroll_H2 ?- c( l* C/ r& Q/ a; ]& ]
  489. STA PPU_SCROLL
    : u; U% D" o# ]! u! ^5 \8 J2 r
  490. STA PPU_SCROLL
    - G+ Z  ?* }' O
  491. JMP Irq_Scroll_Over
    - r8 i' V% B. _+ W- U8 v! V
  492. / F4 l6 F# @9 c1 V( c7 I8 Q( ~
  493. Irq_Scroll_Right9 t5 ^6 M* @$ ^) w1 N6 h- U
  494. SEC2 R4 Q2 t( A) g
  495. SBC <PPU_Scroll_H$ ~/ M% E, @( b: z
  496. STA PPU_SCROLL
    2 \- O. |+ F+ R7 o& F9 D9 f
  497. STA PPU_SCROLL
    & q" ^% }* A4 Y0 v8 I
  498. Irq_Scroll_Over  V8 n& S* s) w. q
  499. * [& t1 t- \( X# H
  500. INC <IRQ_Index" P  U5 O9 N  t3 @- y$ V6 R

  501. $ H: i, s/ b; e
  502. LDA <IRQ_Index
    % u" H& ^) P+ G/ g+ j
  503. CMP #149 J6 T6 T& U$ h% \5 C6 o" H8 q
  504. BCC * + 10% B# l4 Q; t+ d  R  v1 g
  505. LDA #$00
    9 v4 f# C, {9 P- y# n; X
  506. STA M19_IRQ_COUNT_L
    ' U* |; s0 }" O- a% v+ E
  507. STA M19_IRQ_COUNT_H9 R0 V" q6 X" W# y7 c

  508. ( z% a& k, k4 C
  509. IrqProgramEnd; P* h' E7 h- K- W6 q
  510. PLA+ Z, ^2 q) R: w( F% I7 {4 s1 h
  511. TAY
    / r9 A8 P3 W* O! T/ F+ x
  512. PLA; X) q# Y" V# ?+ Q- Z! y
  513. TAX
    , O" G9 ?# \% M/ l
  514. PLA
    ( F7 C* y, d3 d0 Y9 ^
  515. RTI' _8 v, m4 O2 \  P3 k, c) k% n

  516.   V2 t( f- ?$ X& a) I
  517. ;==================================================
    0 v) G3 Z9 E" Z$ {) u0 d
  518. ;中断表
    1 W% U& Y, ]6 U
  519. .ORG $FFFA3 S$ S9 s7 m3 t5 b) u/ v
  520. .WORD NmiProgram
    # }& O! G' d5 u/ P1 ]. d3 h
  521. .WORD ResetProgram8 m4 r5 b6 a. c6 w# ]/ ~
  522. .WORD IrqProgram
复制代码

4 W9 J2 A5 Y2 t, \8 O& M, c

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2026-7-16 06:40

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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