EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]: e" O# x% e- o% W
  2. ;FlameCyclone 202307106 I' [! N. R3 u
  3. ( K% m& Y9 N) s9 e1 E! K: M
  4. ;文件头
    ( n- J7 F; i7 p8 D& Q
  5. ;======================================================================- y, ?; Z! k: A4 l$ x( \( y7 q# f
  6. .INESPRG 4                                              ;16KB PRG 数量3 h# v8 Y0 w7 j7 ?, S
  7. .INESCHR 1                                               ;8KB CHR 数量3 K4 a8 P3 ^) S* O" [, \4 z3 o# p
  8. .INESMAP 19                                                 ;mapper 19! e0 J. {8 J' H$ \
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    6 g7 R. ?  x) B' k. [9 z
  10. " e3 j2 m! ]3 D7 j* K- `+ P  K
  11. ;必要条件  u: _$ c& Y% s/ e4 ]  k4 L
  12. ;1.持有CHR ROM. `& }1 D. f* d  N: |# j
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10000 |7 z# p! c! F% h/ d& G6 c' I
  14. ;3.精灵内存(OAM)不为空
    1 ~$ n0 R/ S- k* Q2 s( N
  15. 5 Q1 t) w* R: v* A  _- N) w
  16. ;==================================================; y# U/ K6 K  d# J9 u. C8 b6 A
  17. ;NES端口常量
    : p. @' Y) |9 \2 P: u0 f4 Q9 y6 _0 {
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器0 Y0 b1 n. u* ]- O
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器' U  {% C0 ?/ A! `$ ]. p
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
    3 E+ o8 L/ P! c, s# a) j( C  n
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
    ! O% p( V4 E& |% n& I
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    3 w- v2 Q7 o1 I0 A; E, R
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
    4 ^& @$ g' E+ q3 n5 ^
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    & y% p: o5 U* |! L3 A* F* N. J0 _
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 6 J, R- ?, Q" `% F4 `+ w7 e
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    ( R- G0 q6 Z6 n- E
  27. APU_STATUS              =   $4015   ;声音通道切换
    0 t3 `5 P" F% f. ?  v' i% [
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通# f: }* w* t; p4 ]( z% `
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    + J7 r/ h- |0 |! \: V: S* w
  30. . Z* G( C: I. [& A( }6 k
  31. ;==================================================
    ! u( V- K+ Z0 [  I1 Y* _
  32. ;MAPPER 19端口常量
    * d0 {: z4 m4 N- j$ {5 L" y: y
  33. M19_CHR_0000    =   $8000* ^  w( W& l5 ^% ~  r
  34. M19_CHR_0400    =   $8800  T" [/ S- ^3 h* ?6 A9 D
  35. M19_CHR_0800    =   $9000
    9 n/ o2 }! a! s5 N2 Q4 n) j
  36. M19_CHR_0C00    =   $9800
    1 ^1 r9 C) h' u$ P
  37. M19_CHR_1000    =   $A000  X  \! g- q* K. V2 g- j2 P5 c
  38. M19_CHR_1400    =   $A800
    7 t$ Z- N' F, f# ^# v
  39. M19_CHR_1800    =   $B000/ h( q# J8 f% N# a( C! A( C  l
  40. M19_CHR_1C00    =   $B800
    ' y  E2 w8 D8 H. y5 M7 N2 J: B2 w
  41. M19_NT_2000     =   $C000
    1 W6 I4 x- @  ?8 L. `/ S
  42. M19_NT_2400     =   $C800% _' E' J  c% W; \) Z9 Z5 A
  43. M19_NT_2800     =   $D000; t% q+ n/ h0 d" C( d
  44. M19_NT_2C00     =   $D800
    5 J3 B" A* J1 [, q0 f% s
  45. M19_PRG_8000    =   $E000
    2 I1 o9 G/ O' B3 f4 S+ N
  46. M19_PRG_A000    =   $E8003 W$ @+ @, Z+ ?9 z' ?- v7 z
  47. M19_PRG_C000    =   $F000  |4 J  d, d$ S* n& ~/ S+ R
  48. M19_IRQ_COUNT_L =   $5000
    5 H3 ^' }1 l& Y5 R$ w. |' [* W$ Y
  49. M19_IRQ_COUNT_H =   $5800" P# l+ G' Y' s. S' Z  G0 i; W

  50.   M# K" @$ h2 I0 @5 e5 _
  51. ;==================================================: D0 ~3 w5 e, v* i4 u6 m4 W" s
  52. ;程序块配置8 f4 H: B! ]5 n( T! c, z
  53. BANK_DATA_MASK          = $07
    $ X+ Y: [2 Y& R( n% X6 |
  54. ;--------------------------------------------------
    * r/ I* c) s9 l# J; b3 F1 o
  55. RESET_BANK              = $07
    + `; {" j7 M+ |7 C7 T
  56. RESET_ADDR              = $FC00& ^; ~- f$ w8 r
  57. 5 J* I! g: i( r, e. ?
  58. ;==================================================
    8 `2 P" h( Z; L8 K
  59. ;图像块配置- i2 a; H" v4 G/ d+ T, u
  60. CHR_DATA_BANK           = $08
    0 [# g& }! K4 `1 k/ [& b
  61. 1 Y& v8 {2 x: P# d5 w8 ^/ h
  62. ;==================================================
    - d5 i8 @: \9 k9 L: g0 U
  63. ;零页内存地址配置
    3 L4 R1 }" P* ^* Q0 C
  64. Use_Ram_Addr            = $80
    % F* L9 v+ V- p& J
  65. PPU_Ctrl_Buf            = Use_Ram_Addr7 e  c( `3 |& H, f& {
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    6 @7 M. e, W$ d8 ]  u6 F
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01! {) B; Q# K" X2 {0 R# Y/ D
  68. PPU_Scroll_V            = PPU_Scroll_H + $01! n) g' b9 e5 s- c9 O9 V. W
  69. FC_Data_L               = PPU_Scroll_V + $01
    ' @, I& G8 a/ z7 U4 o" I
  70. FC_Data_H               = FC_Data_L + $010 D8 m% f5 W( n
  71. FC_Data_Buf             = FC_Data_H + $01
    + {# w& ~7 B1 w
  72. ;==================================================
    6 r6 v( Q9 K1 F5 {" N+ D

  73. # `6 ]$ O8 j( I. M
  74. GAMEPAD_MERGE_FLAG = $04" P9 G) s, ?: }$ p( {' Z4 W6 x  s
  75. + H2 A" o/ g& V: w  N
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    ( s( H, J' u" o1 `; \1 A( ^- j
  77. Gamepad_Once            =       Gamepad_Keep + 2( a( n4 q! z4 U$ R1 Y
  78. Gamepad_Temp            =       Gamepad_Once + 2
    9 j9 i/ D( _. Q9 f. j
  79.                                 ) ?$ Q; @, W9 M! E8 i% c
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    & Y7 y) l$ m  U3 j- i
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    . l- n  f, N$ G9 k
  82. Gamepad_0_Value         =       Gamepad_1_State + 13 O% U- w( J  o. E4 e9 l
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    , I' B- b% ?0 z+ E, W/ D+ }$ \
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    # I+ b# ]! W6 F, J0 P
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1* a* g( _) e: J5 b) c0 i# c

  86. 0 n  A% \6 x9 F, ^
  87. ;==================================================
    2 x' `8 U5 G: K( C% R( G
  88. IRQ_Index               =       Gamepad_Merge + $018 `( D' |% g) b- Y, ?$ c" t
  89. ;==================================================& w+ H3 r/ N$ R. w9 X1 V
  90.   Y! _& O% C$ j: _  ]
  91. ;CHR图形数据
    9 J# S6 O$ w; \6 d) W  i
  92. ;==================================================! b/ ^2 R: w/ A; D/ b9 Y$ O
  93. .BANK CHR_DATA_BANK
    5 h9 l6 Z2 g& y7 x, \# T$ I1 G
  94. .INCBIN "chr_bank/chr_data.chr"* _: `- u* f" @5 e2 u6 N0 R8 Q; B* I

  95. : |! Y, W8 A; z- \- q
  96. .BANK RESET_BANK & BANK_DATA_MASK
    9 s, o- H0 j+ p8 B, j& U5 s% Z7 k
  97. .ORG RESET_ADDR; b) ?) K% h, M# h# D( S
  98. ) d3 q# [2 z6 i, [5 V& y/ x7 k
  99. ;--------------------------------------------------
    4 U9 V4 v0 Y* ]% ]  S( L& P& [% \
  100. Attributes_Data- P2 Y  s1 p( V5 a" N, {' c
  101. ;命名表属性" q- C+ N& h# [- z( B6 y5 t) p
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    % A( i7 l0 U$ O! @7 p  d* L
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    & i5 ?7 T+ ^! d1 q2 M% |5 T
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA! Z. W3 ]% |/ R3 |
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
    ) T" w. ^4 g: S$ ?1 V( N6 R
  106. ;--------------------------------------------------
    + M$ y5 O, J" {% I$ x! a
  107. ;调色板数据
    # r5 d1 ~! c5 b  Q1 t1 Y
  108. Palette_Data
    % A) D3 V+ r  ^6 Z- b9 y0 g: N
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F$ y0 ^) p' I! s' k7 ~( C/ V
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F8 i9 o0 s% k$ j0 Z* K5 m

  111. . x" b, e1 e; q; u) C$ d
  112. ;==================================================
    . O# L* e" k1 W( ^+ i% e
  113. ;命名表初始化
    $ `+ {$ c2 y; M- s8 E6 ?: w
  114. Init_Name_Table
    3 K1 j9 _4 T2 A& ?1 ]/ E. k
  115. LDA #$20- ]2 q, f. {- |' o: s5 [) K+ l
  116. STA PPU_ADDRESS6 q( E! @2 b6 S# U4 ~  c& |
  117. LDA #$00
    4 M/ A6 F, X6 |( p5 P/ M0 O6 K
  118. STA PPU_ADDRESS% v' N- J/ ^# Z0 I$ o
  119. LDA #$00
    ( e/ G- V+ b' G  y
  120. LDY #$002 B$ ?2 s4 A* F! U! E
  121. LDX #$10
    0 g& [5 [( e" y+ g5 H' p8 `
  122. Init_Name_Table_Write3 N; O$ r1 b; }; O" ~, P. A
  123. STA PPU_DATA4 j! F' L6 Y0 m' ]5 t7 o, g
  124. INY
    + v& o7 ?% M' ^5 x- ?6 Q7 S
  125. BNE Init_Name_Table_Write
    ) s: [4 S5 b) {
  126. DEX. U& X* i6 [8 o( d9 I
  127. BNE Init_Name_Table_Write7 ^% d. ^6 W9 Y' Y
  128. RTS
    3 [) ^: F$ |- h- o3 y% \8 ?

  129. # n6 l6 H7 _9 U: u+ e
  130. ;==================================================
      ~0 c5 v# b7 V$ E5 l( H: V
  131. ;调色板初始化* @0 b5 X3 D2 r  O3 H  l9 p
  132. Init_Palette9 h  w7 N# R! A3 L1 k0 j
  133. BIT PPU_STATUS
    6 d" J3 U' r- A+ C8 \) e' L. M
  134. LDA #$3F* O% Y) k8 x! |
  135. STA PPU_ADDRESS( u9 ~1 z8 [( p  B8 R4 q
  136. LDA #$00
    & z% y, F7 }+ k6 S, J! h
  137. STA PPU_ADDRESS6 y( \: p3 ?  p: E
  138. LDX #$00% b& a: `5 I: Z( u1 `4 d8 u
  139. Init_Palette_Write: j, t8 G/ x0 S$ A$ J5 z
  140. LDA Palette_Data,X2 M0 i" i! O. S0 ?; _
  141. STA PPU_DATA
    ' S: W+ E5 E$ m) f  \& {! i" ~1 P3 c
  142. INX
    9 h, d* r% E7 ~. v, f
  143. CPX #$20
    5 ~: X, J0 F8 B
  144. BCC Init_Palette_Write$ T9 v8 J' d# A
  145. RTS
    ) p1 |( H; O- M# z+ {  a, W

  146. 9 p1 h/ y! t! f( j: m
  147. ;==================================================  ?) O3 s5 N5 \" d( I8 N3 x
  148. ;设置命名表属性
    : J5 e! D9 F) r  f
  149. Init_NameTable_Attributes9 x& _. O0 v0 [3 C
  150. BIT PPU_STATUS
    2 B% |1 ?, i& N
  151. LDA #$23
    7 ^7 R/ B+ r7 ?' |8 H" Z
  152. STA PPU_ADDRESS, I; u3 \) I$ R! i  A- |: l
  153. LDA #$C0/ p0 }! _& {/ a0 E7 h4 I" K
  154. STA PPU_ADDRESS1 A. i6 x( J- W6 T
  155. LDX #$00! ^- C5 |$ N1 Q0 f1 u+ b
  156. Init_NameTable_Attributes_Write
    1 `% ]& V* f* ]  P) J; r) k- U' Z
  157. LDA Attributes_Data,X
    $ {0 P7 R# G/ V5 o: i
  158. STA PPU_DATA/ a1 [3 y6 {& O2 X' `" T+ s+ P$ y
  159. INX
    8 z$ |3 g9 R! {* x! k; X. n5 _, P% Q
  160. CPX #$40
    ; b- ~5 f( y% f/ z" k  x+ `
  161. BCC Init_NameTable_Attributes_Write
    . ~* ~# S- \! b9 H' G0 x
  162. RTS
    ! H8 k# U2 ~4 m

  163. " M# c5 e: G# b7 G# a& V/ m" P8 Y
  164. ;==================================================
    + z+ X1 ]8 _8 v( _6 P4 j6 |3 u
  165. ;初始化命名表文本+ R. Z9 B4 o. T) K0 m
  166. Init_Name_Table_Text
    * `, ]- O- b0 @7 @
  167. BIT PPU_STATUS
    ) {2 P  h8 X6 i8 \, o+ ~
  168. LDA #$20
    3 l& `, u% G' Y
  169. STA PPU_ADDRESS0 u# I4 z2 |" T7 G0 G- n
  170. LDA #$00
    ! ~5 W( f4 E3 v* l
  171. STA PPU_ADDRESS) h, m  L6 c# j
  172. LDA #$00
    . r% M; @9 I) \* }3 i( H. c
  173. STA FC_Data_Buf
    % [' R- N. c& r
  174. LDY #30$ w& |# Q/ v$ k( l& R& \* b: n/ u( x# P
  175. Init_Name_Table_Text_Write
    2 z+ |& m% G' p
  176. LDX #32
    $ }5 _! o9 R" e+ C
  177. Init_Name_Table_Text_Write_Char
    % f( r4 q4 z0 I6 p3 l- Q
  178. LDA #'0'" ]9 i1 b' D7 ^
  179. CLC
    1 r3 D5 r! m. o: r
  180. ADC FC_Data_Buf. x5 O1 P- S# e' E: h# I2 ^; |" N
  181. STA PPU_DATA( u+ @, F, m+ ~- ^: k
  182. DEX
    4 e9 d2 y5 ?3 V7 O4 i
  183. LDA #$14/ ?; @# ?2 j- R( i6 L* L6 p
  184. STA PPU_DATA7 s- _- y) o  y: O3 {  o
  185. DEX8 b4 `7 g* A5 e; ]& V/ ]
  186. BNE Init_Name_Table_Text_Write_Char
    9 W; W" Z9 z3 x- o4 X
  187. INC FC_Data_Buf7 x( H9 w% L5 z
  188. DEY( a/ v! {% X2 c
  189. BNE Init_Name_Table_Text_Write
    " G. ^& j3 y# |+ B; R9 W0 l
  190. RTS
    * H( G7 ^8 r# V  d: X/ n: r: j( d
  191. 8 d1 U7 g# _/ ]6 Q5 E) M
  192. ;==============================
      U* H; [3 p5 k7 W2 A5 x2 N
  193. Init_OAM_Ram;初始化精灵内存; c, w. [7 ?, R* ?
  194. LDX #$00
    2 K( n- [3 c% f. j
  195. LDA #$00# F# z  Q8 V: o# }4 j6 m
  196. STA PPU_OAM_ADDR2 A6 _- i; r/ x% {. W$ J
  197. LDA #$F8
    . E7 v& H1 m6 K& l  z' o! [
  198. Init_OAM_Ram_Write
    . L$ M. h) E0 F
  199. STA PPU_OAM_DATA& n3 Z6 v7 V: Q2 w5 J; O' N# n: x! w* x
  200. INX
    0 P2 I7 ~; k. W4 r7 ?; `4 {6 D& q: I
  201. BNE Init_OAM_Ram_Write+ C0 J2 }/ G/ T; X9 B4 Q
  202. RTS, ~& T' A5 q/ M, p  a

  203. * E6 P9 A: a" o9 u1 I  W  i7 ~
  204. GamepadProcess;手柄处理: ]8 |4 J: V+ X  u
  205. JSR GamepadDatacan' j3 o9 q1 _/ W% y6 U, _# }8 t2 _& d
  206. LDA <Gamepad_0_Value
    : @/ u& g0 z, V, k
  207. STA <Gamepad_0_State6 {  _# {9 F; C
  208. LDA <Gamepad_1_Value
    7 y* ~9 z0 s: ~* H% ?, L, Y
  209. STA <Gamepad_1_State
    : O5 z( P1 b$ ~
  210. JSR GamepadDatacan* e/ E! A0 t# \% ~4 t
  211. LDX #$01, f* c( H. R5 m: v
  212. GamepadMergeCheck;合并手柄输入检查
    0 Z/ Q: V$ |0 \8 B9 o9 N5 p$ h
  213. LDA <Gamepad_0_Value,X
    # a1 z: P: o/ Z; s# J3 t# D
  214. CMP <Gamepad_0_State,X
    , ^2 F6 @7 s8 j3 F) h( u/ c4 d6 s$ B9 r
  215. BEQ GamepadMergeInput
    6 S' Q& {& e, i
  216. LDA <Gamepad_Temp,X3 c/ W9 G4 E3 u7 U( _8 K
  217. STA <Gamepad_0_Value,X* ]& q' [9 a+ z; v8 Y* x
  218. GamepadMergeInput;合并手柄输入
    / L; X6 R, s  C& \. O
  219. DEX2 h* ~, T# T9 Y  T6 p
  220. BPL GamepadMergeCheck
    ( N* t) [! S( o/ C
  221. LDA <Gamepad_Merge' p8 o5 f* Z: K5 p! q  L4 O
  222. AND #GAMEPAD_MERGE_FLAG
    ' w" T4 T  @) G- ?8 Z
  223. BNE GamepadStateProcess
    . w2 a" `; J; s( I8 k
  224. LDA <Gamepad_0_Value7 f  f  L9 ~3 ?; U3 \" H. W: D
  225. ORA <Gamepad_1_Value
    % V* H9 w# \  m  o3 q% G
  226. STA <Gamepad_0_Value" O0 q" f7 M% q3 b8 e+ H4 O' ?
  227. GamepadStateProcess;手柄状态处理
    * o1 E1 F6 R. ~$ ^. O$ A! t
  228. LDX #$01
    ) y9 ~5 p4 R% r% y
  229. GamepadStateSave;手柄状态保存* n- v" G' S) X2 s2 V1 P
  230. LDA <Gamepad_0_Value,X
    5 P2 ~7 q% k) T& P) g1 a
  231. TAY
    . v$ V$ G9 \+ e# S7 C
  232. EOR <Gamepad_Temp,X
    / M- @2 V9 k3 h1 e9 r4 {- o
  233. AND <Gamepad_0_Value,X5 j0 ~' e& \; H/ `  Z+ n
  234. STA <Gamepad_Once,X
    . r& }9 b/ L# U' G. C
  235. STY <Gamepad_Keep,X  L1 F1 w& g( M; r: j9 }
  236. STY <Gamepad_Temp,X5 B' z% K0 `7 Q  D9 ]
  237. DEX7 c' n; |" C" b# b
  238. BPL GamepadStateSave
    " w1 e- E& g  y, g3 n) D! Y0 i
  239. RTS' R, x/ V) |+ f, H$ M7 Y  }( q
  240. : Z3 @/ d+ y) B- U! v0 p3 L
  241. GamepadDatacan;手柄数据扫描2 ?7 z0 c( _/ A3 O: q. |* m+ c( w, k
  242. LDX #$01
    $ `7 i0 L& Z6 d4 H' [+ L) M
  243. STX $4016
    / s$ @0 a0 c" Z) O+ J7 W5 O
  244. DEX6 C5 O( E6 ~, D' Z3 W3 W( C& X; W
  245. STX $4016
    * n* T, t* @6 c! ~
  246. LDY #$08% T7 ~) X7 O$ @2 S4 Z2 \
  247. GamepadPortScan;手柄端口扫描
    * g+ g. S; p+ f+ L0 g/ \
  248. LDA $4016# N+ r5 F6 w; ^
  249. STA <Gamepad_Port_Value
    8 W% q+ B# B! i4 U( ]
  250. LSR A' w' `# a6 w1 X2 P7 F" N* \( o
  251. ORA <Gamepad_Port_Value
    " U, w5 ]! @% _0 H( p
  252. LSR A& F& ^' [9 C1 W9 s& a- v
  253. ROL <Gamepad_0_Value
    ; L  A. n" h, r5 l' d4 W6 O, a4 R3 Y
  254. LDA $4017
    8 E" j% u3 N2 K" t; @% v+ @& L- d2 b3 L
  255. STA <Gamepad_Port_Value$ ?- i. N7 z2 X$ O$ s+ f- u
  256. LSR A
      V, Z4 R! E  t9 ^) M+ O4 M
  257. ORA <Gamepad_Port_Value) h+ y- \( z* Z# T3 k+ @
  258. LSR A
    " r. c  T+ y1 i1 q$ i- H/ B
  259. ROL <Gamepad_1_Value
    : y. s& c8 m! o- e. A9 d
  260. DEY+ e+ x- J" B6 x1 o
  261. BNE GamepadPortScan
    + B, g3 k# H$ L' l$ n2 q
  262. RTS. {) ?; a9 p/ j6 u; p
  263. 6 P5 B7 A0 h* [( s
  264. ;==================================================
    " ~. _5 K3 f  M0 X
  265. ;PPU处理6 v) b( V. b/ ]4 H9 I
  266. PPU_Process$ L7 ?5 i. m# U8 i
  267. LDA #$00
    & G7 k' ~9 }4 g' J6 V: `# [7 ?
  268. STA PPU_MASK
    # n7 l" C. W: ^7 I4 |6 U* g. N. u

  269. ) E; p3 N& g8 H6 V' h( r
  270. BIT PPU_STATUS
    - D5 B" o" [" X7 v* I0 o! l( y% Q3 I* e
  271. LDA #$20- I6 ?7 e  R% T0 Y7 C
  272. STA PPU_ADDRESS: R% Z, X) a/ d
  273. LDA #$00
    $ q3 |: p; v( p+ Y3 h2 j( |9 N
  274. STA PPU_ADDRESS
    # A- g: p8 ]! x: d$ _/ y# C
  275. ( I1 M: [& |$ N, n
  276. STA PPU_SCROLL
    " c) S( n, r" w* j. v
  277. STA PPU_SCROLL
    0 T; T  g* a8 t! R

  278. " e: v& y. `$ ]; {  Y4 d& x
  279. LDA PPU_Msak_Buf  N" t# t; }8 U9 L1 h) s  ?
  280. STA PPU_MASK; ?* K0 s& M& l" D# S
  281. 9 ^7 ^* }  u, m
  282. RTS
    ) G0 b' o% L  K4 |/ @7 w
  283. 8 E7 t7 `0 |/ B" B1 s4 X4 x
  284. ;==============================
    ( A6 }/ O, ]+ G1 Z& ]
  285. Time_For_Vblank;延时等待
    ) E" `8 C' ?4 K- I1 j9 e' |
  286. LDA PPU_STATUS) M% ~  w# L/ c; b
  287. BPL Time_For_Vblank1 `+ f9 f" l7 R
  288. RTS% s  Q/ n( w( Z/ I( w  Z/ X# V

  289. . c  _1 l! }* u9 P; I6 b! V
  290. ;==============================7 q; ~1 h. U  y1 R* T
  291. ;初始化MAPPER190 z/ ~& W% t/ J
  292. Init_Mapper195 ?0 ?* d% \8 D4 C/ T0 t" B7 F1 u
  293. LDA #$00
    # k' C) ]8 K$ m2 N$ R
  294. STA M19_CHR_0000
    # x4 ?" [+ p$ R8 t
  295. LDA #$01
    " B# o* K# n+ Z
  296. STA M19_CHR_04002 [5 K( Q# Y8 s* x( Q3 \% f
  297. LDA #$02( f! f/ E. k% c- T4 j. n. M
  298. STA M19_CHR_0800  {- G2 B, `7 W+ k; U
  299. LDA #$039 k% s1 V. l# N" D% o
  300. STA M19_CHR_0C00) A% d9 \$ V1 G2 k9 ^# c% C9 @( n
  301. LDA #$04
    1 D9 X) _: Z, o6 b& p+ u
  302. STA M19_CHR_1000
    ) i; l3 B% i" x) U
  303. LDA #$05# d9 z' [) i9 n- D
  304. STA M19_CHR_1400
    4 E" |: l  N. W, [0 \7 c* C" f+ c
  305. LDA #$06
    ! b1 s: O4 C" \& t. T
  306. STA M19_CHR_1800
    5 }: G4 a) d- L
  307. LDA #$075 g9 p9 P: X2 c1 G# c
  308. STA M19_CHR_1C00
    * n! P; G5 X/ s! z5 d5 ]% d

  309. " ]1 a4 ]4 t  ^% @8 N
  310. ;禁用IRQ' o8 s5 K5 k6 t
  311. LDA M19_IRQ_COUNT_H
    9 f# D' d, H/ H& q& G8 i: l
  312. AND #$7F( B# c8 l! ^( p* ?$ ?
  313. STA M19_IRQ_COUNT_H7 Q& }3 [- R" h# w

  314. & k/ r4 b* V8 v
  315. ;命名表' \. r. ~7 _1 G/ y! A. D1 h2 H
  316. LDA #$E0
    + `1 o8 H) [4 J2 _5 ^+ `
  317. STA M19_NT_2000
    ; j0 i) i9 M: u, a
  318. STA M19_NT_24007 ]! ^* l0 Q0 @9 f

  319. 6 t: I8 K/ q& ~0 V
  320. ;命名表
    5 f% g' x/ w6 F
  321. LDA #$E1
    ; r" l  w$ w! ~3 A
  322. STA M19_NT_2800
    5 _$ ^9 \- i- M9 z0 [
  323. STA M19_NT_2C00: s- B" Z& A5 Z' b2 z) w

  324. 7 Z! U4 `0 z9 m; Z" J+ t9 ]0 W
  325. RTS' y3 {2 P: z- N( h: N
  326. 7 P' ^) p8 P1 L) W9 X
  327. ;==================================================
    # P2 l! ~: H6 S& c& @  I
  328. ;重置中断处理
    1 s, Y2 {7 h- G; G; _# G. x$ o# r2 a* B
  329. ResetProgram
    . T  x5 S  C- x( y" U
  330. SEI# c2 b# [7 S; s# X
  331. CLD8 e9 a6 b8 ?  c& {# h/ x9 X
  332. LDA #$00
    % ]# W# A" m  Q8 U. o. b, ^
  333. STA PPU_CTRL
    . N5 s, a2 u, o* [0 l5 l
  334. STA PPU_MASK
    : J. T. d! _: c5 {! c% m
  335. STA PPU_STATUS
    ! U" ]- u! h( m2 U
  336. STA JOY2_FRAME
    3 l+ u5 R5 j) i
  337. STA APU_STATUS
    7 Z9 O& ^8 T+ X' |) [- W
  338. : V2 D0 l3 R1 o% h& A" Q
  339. LDA #$C0
    1 O$ w. z, N! a( S. |' J- ^
  340. STA JOY2_FRAME
    4 {+ [$ S% V3 p) }

  341.   u: h' v3 H) i4 W
  342. ;等待vblank
    & {6 ?7 }) E' F( J$ J5 @
  343. LDX #$02
    * Z9 w' n% L0 r1 _# {
  344. Vblank_Wait_1" |. D+ F8 ^. V
  345. BIT PPU_STATUS5 e5 Z$ V3 D& ~" r+ t3 K
  346. BPL Vblank_Wait_1
    ( }5 F3 \& N2 G6 ^4 j# I  Y
  347. Vblank_Wait_2
    ' g6 j; t" x: I, ]
  348. BIT PPU_STATUS
    " f8 z; V0 `8 C; z( ]/ Y5 Y# b7 w
  349. BMI Vblank_Wait_2; Q: _/ x; `! U, M5 F  ^! d
  350. DEX! T4 @# D0 X) ^; @
  351. BNE Vblank_Wait_1( T/ @9 N, b. R
  352. # F6 U4 p; T" J  Z$ T  L
  353. LDX #$FF
    . d  e. V" T8 i& w
  354. TXS+ C8 G' ]0 i' }
  355. 9 b0 T  d+ W9 B
  356. ;初始化MAPPER19
    4 f8 j, ^- K% p* ?  ]
  357. JSR Init_Mapper19
    + ^8 Z' Q  C1 {) [( p

  358. " p- l7 ]- j) ?/ n0 Q
  359. ;==============================
    # f5 ?/ f2 i2 V, V$ P* |* k8 n
  360. ;RAM初始化
    3 `. t) W% s2 Y" B
  361. Nes_Ram_Init1 p1 \6 V6 S+ }
  362. LDY #$001 {% X* C! g5 l& t
  363. LDX #$08# k, ]3 H3 A5 l, \  }  b+ @
  364. LDA #$000 a5 n) d$ R* n7 Q: E4 P
  365. STA <$00
    / Z0 [9 R* q0 y/ g2 I; F$ \
  366. STA <$01
    8 v$ r2 @2 Z. B: q" }/ V# z
  367. Nes_Ram_Init_Write
    6 g+ O4 L' Z0 d  k
  368. STA [$00],Y
    4 L3 I1 g/ Q) w4 Y8 u
  369. INY) E7 ^* z( D3 |6 ^
  370. BNE Nes_Ram_Init_Write
    ( |3 |! Q* d. {
  371. INC <$017 B# d$ B7 Q% T4 ]9 F& l9 ]
  372. DEX
    ) I' ~  u  e2 E: c1 R0 b7 I
  373. BNE Nes_Ram_Init_Write8 j. n) m, e" `
  374. + R4 T" d& R0 _. [6 V5 y
  375. ;初始化命名表, G6 s2 |2 T4 [  I, U$ V3 J: k
  376. JSR Init_Name_Table
    2 \+ U( k7 J* P
  377. * E" O" c! E/ W8 V) ]# \
  378. ;初始化调色板* E" |' P) y/ Y3 H8 s% v3 L
  379. JSR Init_Palette- U" }& i2 K: f9 c: [! V! O

  380. 3 A5 Q+ A  K7 t, q, A9 l$ |  H
  381. ;初始化命名表属性, w9 e+ Q$ u/ E0 j: r2 C
  382. JSR Init_NameTable_Attributes
    - m3 Z9 B" A) W, ]9 X* d

  383. ; R1 a. m4 P' |/ T2 p) p
  384. ;初始化精灵内存
    - Z+ J$ T7 v- R1 |+ M. F& N2 t, I& d
  385. JSR Init_OAM_Ram
    ; t- }' f. F0 Y+ r  j# y# D0 N
  386. 3 D+ p& I1 {( p' B6 [% O
  387. ;在屏幕上写点东西$ a' o0 G8 i( l4 I6 _
  388. JSR Init_Name_Table_Text' }) I: \( J/ W0 x" g/ `
  389. ! _  k1 T' g4 E0 [, p
  390. JSR Time_For_Vblank2 ?. [; t9 A3 N4 d% e. E1 N7 I
  391. ;开启PPU控制5 X/ `1 T% w1 S7 X
  392. LDA #$A8
    ; O! o8 D/ f# C$ `( }
  393. STA PPU_Ctrl_Buf9 J1 `$ R% ^: r. V, b+ j% @+ r
  394. STA PPU_CTRL
    $ V' x- O' L$ `! S) i

  395. 3 u7 ?+ c$ _( J1 |3 V
  396. ;开启PPU显示
    # \: \2 F' l- L3 `, Q
  397. LDA #$1E; e1 j6 q2 d5 n" j+ d
  398. STA PPU_Msak_Buf" W. l: e* c6 M/ L" ?$ s
  399. 1 B. `- ^7 ?) \7 d0 _% v( \/ j; O) X
  400. CLI  Z% E( X& W& j5 _1 Y: O
  401. JMP Loop
      l3 g# j; H% ~& z
  402. 6 F! R1 w8 [. A& @' V. R4 u: X
  403. ;==============================" F9 ]) D8 `) Q, @, h8 F
  404. ;死循环, 等待NMI中断! `* S. s8 w6 b- ^
  405. Loop
    % Z& m) o3 i3 X- _: H! C3 |
  406. JMP Loop
    5 Q- H' A5 h6 x+ c$ Q  K* ^, f- f

  407. 7 j0 l, E2 \+ b- `" a5 K, d. {
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9673 k' a/ ^5 q0 f6 t/ w& @- q
  409. 1 v: b) @, I# C) M, f5 ]. A
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)( O3 X3 x2 D' |( s7 }/ z4 r- \1 \
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)
    ; C$ Y5 }1 q1 Z, G( V; k- {5 d
  412. ;==================================================, L, [+ y* X. d9 W3 @  j; r. c
  413. ;NMI中断处理
    # q/ h# \0 p  q7 I/ b; Z
  414. NmiProgram3 ]8 Y8 l0 X! j$ Y. p3 \$ y% p4 }
  415. PHA
    6 O! O* K  k7 @; D9 I) @: Y; g. {
  416. TXA% A. H, i0 [9 q8 T$ {
  417. PHA
    : A! B5 ?- |9 I8 }4 Y3 T
  418. TYA" U( c) \4 p! @4 E; m
  419. PHA
    3 ^' q$ g6 t/ W5 H9 }

  420. ( `, _: |" I/ _9 C2 `
  421. BIT PPU_STATUS7 s2 @8 v( v( u: Y/ }9 X3 Q/ c% X8 z

  422. ' p# ]7 T! [- E% {
  423. LDA #$00' s" F, l( N; _7 {% f
  424. STA IRQ_Index4 P+ Z2 U5 A% E( K' v
  425. 5 c7 D6 e+ U8 B" D' O1 V/ I
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动; ~3 g0 u% G7 \/ Y; s, ~
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)
    + ?# J1 Q! v: k1 W5 }+ F+ i, ~" _6 [
  428. STA M19_IRQ_COUNT_L+ N/ Y7 @0 z# V, L- m8 `
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)
    8 H1 d; u1 |+ `. T
  430. ORA #$80
    ; {5 q' Z) J  p/ a! q  b; |
  431. STA M19_IRQ_COUNT_H
    / C" \, v/ t2 R* }
  432. CLI
    ; @8 o! c- [6 |& t' n! ^5 f
  433. % _+ E7 E, t" {0 @- M
  434. ;关闭PPU控制
    & N" T8 l6 [1 ]6 X/ ^6 D: J
  435. LDA #$00
    3 |1 D2 V* S" P
  436. STA PPU_CTRL
    2 a0 ^: q) S- [
  437. % W% P7 W! k5 n  l2 G' R
  438. ;处理PPU/ O# C3 u. V. w
  439. JSR PPU_Process
    - y$ I1 }$ R1 X: P, @

  440. ' V/ m' C2 [! `: _3 Q; ~- V3 y
  441. ;开启PPU控制/ u- w- `, C# D: @3 H' U$ D! O7 A
  442. LDA PPU_Ctrl_Buf
    ' Y7 w9 R7 M: X
  443. STA PPU_CTRL
    ) e* d/ [8 T) U/ }8 d
  444. 7 S5 i. I; G- j3 M
  445. ;手柄处理
    ! q0 G, ]4 d+ ]3 d2 t% c
  446. JSR GamepadProcess7 B! {) J! E: G* V' Q9 V4 ~8 v

  447. / O) }+ j+ U( U. j& n
  448. LDA #$00
    6 b( ?) \7 F& |
  449. STA IRQ_Index
    1 s- @2 M: {& b" x; f
  450. + [' ^. `8 _- n  M
  451. PLA' l2 S6 O- H: Z9 t0 }) Q8 i
  452. TAY
    - H" y, s7 x8 L! c
  453. PLA! x& s, r! W. {; @; G
  454. TAX
    : D% d4 F1 `; V3 L) V7 f
  455. PLA! H9 Y, N( Q( t8 U' O
  456. RTI' J( |# ?6 ?: J, g
  457. 6 L$ U1 ~0 u# V  b: t
  458. ;每行扫描线113.676 R8 b+ ~2 x( \( T2 B
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
      K+ E2 _/ E# z0 @  L" M
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7* o% \+ [; K6 X: P- l, @
  461. ;==================================================4 z, c2 \4 x% ~. E3 }& {
  462. ;IRQ中断处理
    ; n( j& i( b9 i- O+ y. @6 O9 L4 A
  463. IrqProgram8 L9 S1 Z8 T. P$ B; g, n- _
  464. PHA, q  C9 ~/ _0 |9 |  t; l4 I
  465. TXA# O2 b. d2 ?) q- |0 g$ ~3 ?1 J8 i
  466. PHA
    0 x# m3 Y5 a' k0 `! A5 f& y  A! @$ y
  467. TYA
    , a% X  K+ i- N" N
  468. PHA0 l; C7 W' k+ x  l6 q
  469. - f$ _/ ^- L$ h, w  K4 \
  470. ;16条扫描线后触发IRQ0 c" Q6 T3 o0 i1 o$ Z2 {' [$ _
  471. LDA #LOW(BEGIN_LINE_CYCLES)6 ^% s8 y% b5 o! F
  472. STA M19_IRQ_COUNT_L
    1 V1 ^# S8 K/ H: j3 ]. F" Y
  473. LDA #HIGH(BEGIN_LINE_CYCLES)5 V4 x: z0 x) ^* N5 x- }
  474. ORA #$80& G7 B  t( M; L" h3 I
  475. STA M19_IRQ_COUNT_H" t; o$ F6 A3 f* b+ M
  476.   f3 m3 Q2 J' q' i
  477. LDA <IRQ_Index( V  V2 L3 v( ?5 g0 `, x5 k
  478. BNE * + 4) S+ p. Z' D6 r" \+ q5 N
  479. INC <PPU_Scroll_H; V. Y5 K# K$ v! a2 t
  480. $ \9 K: F' P% |7 m( z
  481. ;设置屏幕滚动
    $ J. j1 _/ G" ?, r
  482. LDA <IRQ_Index
    7 Y  R( `: E1 B4 t2 O, T
  483. AND #$01/ R" J% u  O2 G5 {' y
  484. BEQ Irq_Scroll_Right1 w3 g% v! Q' V; q  g+ a8 w

  485. 1 Y0 C* G1 }% N7 `' q
  486. Irq_Scroll_Left4 s6 J6 V" \; l+ u5 H9 c
  487. BIT PPU_STATUS. U/ _) m6 v5 b3 m
  488. LDA <PPU_Scroll_H
    9 D$ \8 e! G, D0 F+ q
  489. STA PPU_SCROLL$ h- J4 r$ u( [7 {! V$ k
  490. STA PPU_SCROLL) u9 m; F( [- E2 j- h
  491. JMP Irq_Scroll_Over
    ; I/ E1 E3 L. O, T

  492. " x# l. \3 i+ s4 q6 n0 _
  493. Irq_Scroll_Right1 U$ v' B% n3 H; w- P5 }
  494. SEC9 D3 s6 e. G% l; h% T) E; n0 c
  495. SBC <PPU_Scroll_H
    - Y! u4 Y( T/ o
  496. STA PPU_SCROLL4 w: A: h5 h* a; k$ [0 R
  497. STA PPU_SCROLL
    ! L  z- R/ h) F  c, p: A5 u
  498. Irq_Scroll_Over
    % V; A' a0 I6 {, Z  Q6 J2 K
  499. ! s, E6 a+ k( H& P. c$ K! E
  500. INC <IRQ_Index
    ; S, l0 X/ d( d8 ^2 y
  501. 9 c/ S' {/ @! r6 |4 b# A
  502. LDA <IRQ_Index; h* ]9 @6 l9 f% c3 i
  503. CMP #14  X3 h0 R% e# I6 |" I. i  j
  504. BCC * + 10  ^+ ]* g3 }( e0 y) l6 u
  505. LDA #$00
    ) E% P' Q9 U; n. ?2 u/ U% u- i. _3 y4 P
  506. STA M19_IRQ_COUNT_L. |" L/ |' X; [
  507. STA M19_IRQ_COUNT_H3 u& M. B! }9 _
  508. $ O* ?  R! T1 x
  509. IrqProgramEnd
    ( ^# M/ D% Z" ]
  510. PLA  u* B4 z1 P; h8 V( |5 S) P, v
  511. TAY- s8 U* ~6 R# f) C
  512. PLA
    % o( r1 v2 f, c2 \
  513. TAX6 Z% @5 @* V  Q2 b
  514. PLA& {3 a0 q. j; p+ `0 x
  515. RTI
    3 H' \- ~4 [, w& G1 ]0 a( d9 c, a

  516. : s+ T2 u5 T) N: ~! j, w
  517. ;==================================================9 Y7 d9 m' y) _& H! d2 k, J: d4 R
  518. ;中断表, P) R1 `* I6 m2 W3 R7 s1 y$ O
  519. .ORG $FFFA  K+ K# r. g; ?8 s! L
  520. .WORD NmiProgram
    2 a- y% @8 g! i
  521. .WORD ResetProgram2 Z, [) |+ Y* G9 y) ^+ P& N
  522. .WORD IrqProgram
复制代码

8 a9 {+ D1 c  o

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-11-19 01:41 , Processed in 1.093750 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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