EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    6 A7 Q9 A- {; g" W
  2. ;FlameCyclone 202307109 u% D# w6 i5 W4 |
  3. - a6 G* ^- C. K! K6 d! k
  4. ;文件头1 T" G- o7 C! e% X, T8 Q
  5. ;======================================================================7 Y0 L0 M" X& E/ n
  6. .INESPRG 4                                              ;16KB PRG 数量) |! r( ^- y) J. C; M( B$ z5 \& [
  7. .INESCHR 1                                               ;8KB CHR 数量
    * Z8 d' Q0 t/ B$ e: E
  8. .INESMAP 19                                                 ;mapper 19! L; P9 e3 \( n+ ^! r
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直
    ( ^% q1 e, m# h* i; y8 \

  10. + ^# E4 ~$ u1 o: \9 Z0 S5 E! g
  11. ;必要条件
    + J, U$ A( G( p
  12. ;1.持有CHR ROM
    6 b0 W9 E7 S% b+ @( h
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000% u+ w5 P$ t$ i
  14. ;3.精灵内存(OAM)不为空$ e) ?) u; k4 ^# ^8 ~

  15. # }1 v; H4 R1 j
  16. ;==================================================
    " Y% M# p: J3 ^
  17. ;NES端口常量
    & l8 K7 r1 K5 }. ?: A* f. n" L
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器% m, `; g3 }% M  t- b" r4 n2 d
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器& L9 ~- X' R% X1 U. w, q, @" O
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
      o* \3 M/ b1 M$ o+ \7 T
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1* {" V9 K  y& _( W/ Z5 F
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
    ( u: n8 U# g; y2 {$ Q- `& v
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 6 z1 c1 I+ }/ V. C; c
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加& @) Z9 K% R/ \4 _
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ! G- L0 K. r6 N' D2 T( p8 a% @& E
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存% F8 U$ e3 F- n$ b8 }* _' U' D" x
  27. APU_STATUS              =   $4015   ;声音通道切换, _" r' C- O. ^; ^! J) p
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通7 \6 s1 k3 A$ m- e6 m
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    3 c% \0 p3 h5 T' ]! \; U5 o# H
  30. . P8 R  h3 p& |  P9 O: B+ w
  31. ;==================================================/ [" l7 q" m" @5 L
  32. ;MAPPER 19端口常量/ ]8 ?: F, Y/ w. g. ]1 t4 |5 z) g
  33. M19_CHR_0000    =   $80004 H2 n* u1 f6 e2 M& a
  34. M19_CHR_0400    =   $8800
    7 [1 r' T) {5 u) i/ c, {
  35. M19_CHR_0800    =   $90008 R* q0 |' x  Z4 z
  36. M19_CHR_0C00    =   $98009 y5 x+ c, Q% O" |. K% l
  37. M19_CHR_1000    =   $A000, ?& o0 p/ C$ M. c7 l
  38. M19_CHR_1400    =   $A800; b7 f' D) H6 ~: o% K
  39. M19_CHR_1800    =   $B0009 ?0 S: I# j& v7 D3 s% |2 }
  40. M19_CHR_1C00    =   $B800! v5 E# h  t( [
  41. M19_NT_2000     =   $C000; `+ e  N8 `* D. X+ D
  42. M19_NT_2400     =   $C800
    ) v: V& e/ R- ]( E/ k/ I) N
  43. M19_NT_2800     =   $D000
    / _6 x  U# f# S# i( [8 T1 C- z9 j  p
  44. M19_NT_2C00     =   $D800: Y- [$ _- g# R# k1 ~# ~
  45. M19_PRG_8000    =   $E000
    ; l" z3 G1 R0 ^! Z, t! e. W
  46. M19_PRG_A000    =   $E800
    8 r+ S% o$ O5 V
  47. M19_PRG_C000    =   $F000
    * j' E9 a- R4 b* J1 L
  48. M19_IRQ_COUNT_L =   $50001 b" k2 n" M9 y* d( C6 D+ I( e( s
  49. M19_IRQ_COUNT_H =   $5800
    ( y6 [0 z  K# p, @. X% e. _- Y- V
  50. 2 t% u8 z* o# ?$ }' I: E0 ~
  51. ;==================================================
    " |* \( c  x2 ]2 y
  52. ;程序块配置
    & a. N$ N/ ?8 n& A, ^: y  f
  53. BANK_DATA_MASK          = $07( q- ?3 d7 N: P! K- _! V
  54. ;--------------------------------------------------. z8 n0 M) o, N# l9 I8 r& r% E
  55. RESET_BANK              = $07
    # ~: R1 [+ o; J- s& ?
  56. RESET_ADDR              = $FC00
    9 i& d: S  ]/ j  T( H5 i

  57. & y, ^3 V0 t, _5 z& u8 F
  58. ;==================================================
    / |0 f2 J  N3 y1 S% r$ ^' u
  59. ;图像块配置
    9 O5 ~  E" N, u' Q( c8 t
  60. CHR_DATA_BANK           = $08
    + B. }3 p# Q8 B0 z6 J5 P
  61. ) R! s7 G- C) c
  62. ;==================================================
    ' Y# |4 G$ |# R, j/ [
  63. ;零页内存地址配置/ G9 u! W. g9 e8 O
  64. Use_Ram_Addr            = $80' b" W$ I3 V7 l& y
  65. PPU_Ctrl_Buf            = Use_Ram_Addr5 b; P0 F+ ]. u' b* c  ?, c# X
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $018 e" f( y& ~3 u- j. `
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01
    ' V& c* O7 z* v6 q$ O# J# b
  68. PPU_Scroll_V            = PPU_Scroll_H + $01
    ! z- [7 D* r0 d! L" q0 V0 X+ k2 ?
  69. FC_Data_L               = PPU_Scroll_V + $01# k$ t. r  j/ b; D3 Z+ r# r9 }& e
  70. FC_Data_H               = FC_Data_L + $01
    # N+ K5 M+ o% a3 P
  71. FC_Data_Buf             = FC_Data_H + $01
    ) E* n% U9 J$ h
  72. ;==================================================
    # c2 Y8 [2 \: X
  73. 3 Q! k0 H! E! Q$ y! E' D
  74. GAMEPAD_MERGE_FLAG = $043 j( N* {9 J3 ~* h) J2 S

  75. 8 D5 b" J2 \9 ~* c6 z4 D
  76. Gamepad_Keep            =       FC_Data_Buf + 1
      g4 t$ S- j/ u! Z* X) S
  77. Gamepad_Once            =       Gamepad_Keep + 28 D! ^$ Q5 h3 l
  78. Gamepad_Temp            =       Gamepad_Once + 2
    & m5 v& c; z& {7 g
  79.                                 
    * ?+ z6 C1 d7 x. a+ F
  80. Gamepad_0_State         =       Gamepad_Temp + 2
    0 P* R* P# `3 e% U4 P
  81. Gamepad_1_State         =       Gamepad_0_State + 1
    $ q. x: J( d" a4 V- f9 _% l0 O
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    ' A2 v  J2 G* h8 E2 R! v& q
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1
    9 }" j# j6 a  @, }9 A- I
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 1
    5 r( `  R+ D4 p" a3 q
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1
    1 t0 O* _% D' E: n+ ]: b

  86. 2 r: n) j1 J5 k# V
  87. ;==================================================
    0 z/ ^8 G* e8 y" a5 B$ D% q8 p8 ^
  88. IRQ_Index               =       Gamepad_Merge + $01- t) ^9 U" [+ k0 I! G) g& y- j
  89. ;==================================================9 ]$ U3 M8 S& s) R

  90. + `) V9 r6 _/ S
  91. ;CHR图形数据& B9 n/ e& y( a8 v
  92. ;==================================================
    5 l" `  I, u8 c) U
  93. .BANK CHR_DATA_BANK
    . [+ J0 y, w  T" o3 P- \4 Q7 A& I
  94. .INCBIN "chr_bank/chr_data.chr"
    % G; E0 w! S2 v' E" h/ C
  95. # |0 ~6 W& B1 v, J* Q* d
  96. .BANK RESET_BANK & BANK_DATA_MASK* l% M# \5 `3 o6 C) r
  97. .ORG RESET_ADDR# J6 h7 h) p! p
  98. 3 c) q8 |- C2 Z
  99. ;--------------------------------------------------
    8 M* M: _. y3 G" n7 c" G
  100. Attributes_Data* y$ H- o2 n, |; q! a
  101. ;命名表属性) h. N+ o. r' ?/ A# {* I
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00  w& p6 X" w3 [, [. c, g8 n$ }
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
    & A) a4 k) z" X' b& O0 k
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA( d  ~/ k; ]4 D5 X5 ]1 T
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55% J* |& K: a' u) i& \" _
  106. ;--------------------------------------------------
      O$ H$ u, C; @
  107. ;调色板数据
    0 m& p  M" w* Y: H6 }" \7 |
  108. Palette_Data
    + q' P, E4 a9 V+ T: s
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F, Y" ~+ V7 x' f1 a7 R( n
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F. j. P* j6 u0 t0 j- |+ k3 u
  111. 7 D: {! c% J1 I& B9 m5 b$ H
  112. ;==================================================
    ( Z! f$ B5 D0 G# N& M/ E3 M
  113. ;命名表初始化
    ( r1 F% O+ [* @8 S; D
  114. Init_Name_Table! l2 K9 X" k' N
  115. LDA #$20
    ( g, H' @5 n1 D5 X- h  s/ `
  116. STA PPU_ADDRESS
    ! A7 V; l1 Q! b2 \
  117. LDA #$00
    $ l" A" J. I  }% o6 U1 t# ~
  118. STA PPU_ADDRESS- D8 D! G% E$ C* }; S! x+ v
  119. LDA #$009 Q4 Y: k, {4 W
  120. LDY #$00
    : E7 Q# N$ z: }& R* D* n: t+ R
  121. LDX #$10
    7 l2 T$ T3 e# `( A) D
  122. Init_Name_Table_Write
    , A4 y/ f. }# v/ ~1 H2 t! v6 j
  123. STA PPU_DATA4 z) D% i% z3 x0 g9 z5 E( u/ a
  124. INY
    + O5 Y* q. z) @2 W0 d( D$ |
  125. BNE Init_Name_Table_Write- T! O( b2 ?4 Z
  126. DEX
    % n3 s  ]1 h1 o, g- Q
  127. BNE Init_Name_Table_Write
    & G2 v+ l8 p  R" Y5 i
  128. RTS% m- ^/ v* m8 S. g
  129. " E) {3 C; y. f/ t
  130. ;==================================================/ Y0 k) {9 _1 I8 K  b& U1 y3 Y; @  D
  131. ;调色板初始化
    7 f3 r1 [0 V, o- C4 C$ J
  132. Init_Palette
    : c- i" V6 G2 X' X" I
  133. BIT PPU_STATUS8 s* Y, ^8 e& e1 ?% r0 x
  134. LDA #$3F
    ) ~0 k: w# V; }6 g* P$ a
  135. STA PPU_ADDRESS
    " W7 R3 k; b  m* q! u# d  l; c
  136. LDA #$00; Z' G7 o& x8 R9 p
  137. STA PPU_ADDRESS  U5 e( S% A1 ]3 ~- w
  138. LDX #$00; d2 e) h6 g. P5 K6 n5 ~7 r( s
  139. Init_Palette_Write: x7 x( i+ }! Z7 {3 Z7 l; R  d) j
  140. LDA Palette_Data,X
    ) ]% P6 p) V% s7 d- `) W
  141. STA PPU_DATA9 F9 t& Y9 w& {% I: j& L
  142. INX
    ! M7 }( F( N6 j8 o. s& C
  143. CPX #$20# O0 {1 z! w" j& e( _1 \
  144. BCC Init_Palette_Write
    % U4 d9 J, T5 N" s5 ]6 j
  145. RTS7 F- L9 J! U/ x8 b) W+ d6 g1 R

  146. + j% B" S& _. T$ b# S/ k7 c7 [2 o7 Q
  147. ;==================================================
    # `' [8 m: `+ m
  148. ;设置命名表属性5 ?8 a7 K" K8 X( j8 ]
  149. Init_NameTable_Attributes3 h5 B) _' ~2 \
  150. BIT PPU_STATUS% L2 O2 @- l' `) ^6 g6 R
  151. LDA #$23
    % f2 o# D9 [" s  k; @& S; s
  152. STA PPU_ADDRESS4 R' B/ r/ }4 @& \
  153. LDA #$C0
    # _" j# |2 j7 W( @& w/ d
  154. STA PPU_ADDRESS* c+ Y/ n% T3 f8 A) B, j' p
  155. LDX #$00
    6 T; D! C: x9 ^6 w$ J
  156. Init_NameTable_Attributes_Write# b& |' O" h9 R) c. W; o+ A
  157. LDA Attributes_Data,X0 U& h  V4 X( e/ T  H* L
  158. STA PPU_DATA/ p9 t' \0 ^" {) |# j; X
  159. INX
    2 ?( `0 _3 p* ?# c. K
  160. CPX #$40% q# n: D. V0 m+ f
  161. BCC Init_NameTable_Attributes_Write
    7 e2 Y  ~  |; D9 n  L  I, y
  162. RTS
    # ?! F: K: r' j/ X6 \* P8 c
  163. " M- N( X. }0 T, i) A" ~, \+ t
  164. ;==================================================- E. a7 {" A; X- G
  165. ;初始化命名表文本
    : }1 t' j1 _: ?( C" w: l! H- B) k1 n$ H' A
  166. Init_Name_Table_Text
    % {! h$ O8 {+ E4 y6 l. s" Z: f2 Z
  167. BIT PPU_STATUS6 y- Y. x7 S9 S  s/ T
  168. LDA #$20
    8 _4 O5 ^+ q( L4 ]/ d0 X5 w. p2 J
  169. STA PPU_ADDRESS
    6 I* x: G+ P6 x& K  Q  N9 T" ^
  170. LDA #$00/ o3 m, i6 Y& r- S  t
  171. STA PPU_ADDRESS' ^! ~; B! M) c" [$ f0 E
  172. LDA #$00
    5 @% h& Y* k* @3 ^& C+ I
  173. STA FC_Data_Buf
    ' m+ C* p- }8 Y5 L
  174. LDY #309 l' U/ q( {) f. A5 Y* i# |# M
  175. Init_Name_Table_Text_Write: t' F/ L% X% _' K- G/ B
  176. LDX #32) Q, d- d4 C- W4 I0 z  Q& p( K  i- P* s% N
  177. Init_Name_Table_Text_Write_Char
    5 d# Q: q1 {! W5 U2 s; H
  178. LDA #'0'
    8 l% b% Q$ K8 ]; p' L: q: v3 K- H
  179. CLC
    3 c* E! B2 X8 R$ j+ w4 @
  180. ADC FC_Data_Buf# I+ {$ z. V: E" i6 G5 y
  181. STA PPU_DATA7 E: H  X9 z; w( P, G+ M
  182. DEX
    9 P+ P+ E* K2 s4 M7 f
  183. LDA #$149 C% n* |: j" J/ T# r" V4 \
  184. STA PPU_DATA* S$ k1 M, F' v/ ^! [% }8 u
  185. DEX
    3 f9 d% \5 U& s% j2 r1 b
  186. BNE Init_Name_Table_Text_Write_Char
    , u8 Y! E$ x# C0 N; O; f
  187. INC FC_Data_Buf
    ' d5 ?6 x' c/ L
  188. DEY7 }  G5 s' a# G( \/ O* [- }2 ]; K0 ~
  189. BNE Init_Name_Table_Text_Write2 h3 ?+ l; g, y9 n3 m+ g( T
  190. RTS
    8 L4 }& K  d! k  b
  191. 3 \1 f. y' F% e' v: w' X5 N$ S
  192. ;==============================% Q! N, ~* d: L* h  z( a) S
  193. Init_OAM_Ram;初始化精灵内存$ O# Z# x0 ^$ k7 q
  194. LDX #$00
    ; G( h5 `4 |% ~
  195. LDA #$00) f# j# |9 J, ?' V0 I" x0 Z5 P/ L
  196. STA PPU_OAM_ADDR
    5 m& X$ M: K) |) Q' J5 f
  197. LDA #$F8
    9 j  D' J" H2 `" ]! P! z
  198. Init_OAM_Ram_Write% ~+ _. y4 ]4 r- Q
  199. STA PPU_OAM_DATA
    2 r( q, l- |6 `9 R$ O0 \
  200. INX
    / r9 m, Z/ x; w7 Q
  201. BNE Init_OAM_Ram_Write
      \* v: H3 B7 s& w3 O
  202. RTS2 |! [/ l, n+ H$ Q3 u# c( Y' M
  203. & v2 D3 t1 A3 h4 `7 W
  204. GamepadProcess;手柄处理, r4 z5 V8 |( p& x
  205. JSR GamepadDatacan
    6 m  m, R& w" T* d
  206. LDA <Gamepad_0_Value) ?* ^9 I2 n+ E+ c8 A4 j# j
  207. STA <Gamepad_0_State
    6 ?: k2 Z, P6 c) w+ R
  208. LDA <Gamepad_1_Value6 |# w" n1 S+ V  m# J! W% H6 b" M
  209. STA <Gamepad_1_State* N$ Q/ h. [& Z# o) H5 M
  210. JSR GamepadDatacan
    $ c5 e* m- r. ^) g; j4 J- f% P' _
  211. LDX #$01) a8 ]2 X, O* ^( k* N
  212. GamepadMergeCheck;合并手柄输入检查
    - I: y- v  U' \
  213. LDA <Gamepad_0_Value,X
    7 g" o3 H. B/ T" ?2 Q" D1 e
  214. CMP <Gamepad_0_State,X
    3 _. C3 i& T; p. o- E/ J
  215. BEQ GamepadMergeInput
    + `# C" j! U" W# U, F+ j
  216. LDA <Gamepad_Temp,X
    . A' W& E0 s: J9 r0 F( O
  217. STA <Gamepad_0_Value,X
    % o2 S- Y# Z; H' S$ Z! X* `
  218. GamepadMergeInput;合并手柄输入
      e1 j& o( z. K# A; }' i
  219. DEX; [8 p4 z! \- Q- }$ `. B
  220. BPL GamepadMergeCheck
      F" K  z% n8 Y% R  d% }" x) q
  221. LDA <Gamepad_Merge( M/ Y$ `; @* ^
  222. AND #GAMEPAD_MERGE_FLAG* M+ i% V, W- M; K& m  n0 d) h
  223. BNE GamepadStateProcess4 ^' X  p! ~3 y+ N- t
  224. LDA <Gamepad_0_Value% }6 I+ _3 q* B7 a; p: k
  225. ORA <Gamepad_1_Value
    # C$ X! c( ?! w+ |
  226. STA <Gamepad_0_Value) I8 [$ D- _$ n5 Z" S" Q
  227. GamepadStateProcess;手柄状态处理2 K7 n. J9 |: C% d
  228. LDX #$01
    - Z  ~" d! h& O+ Z7 I+ F& z7 [% w
  229. GamepadStateSave;手柄状态保存
    6 u1 N4 D! b: i* q) v
  230. LDA <Gamepad_0_Value,X+ p4 z% }% _0 Z/ \# g/ t  J6 U
  231. TAY
    0 {8 d: s  p5 D* Z
  232. EOR <Gamepad_Temp,X: A. w$ S& K! C+ V6 m6 i' V" N7 I- l
  233. AND <Gamepad_0_Value,X/ j4 S% p  V* J" D3 T
  234. STA <Gamepad_Once,X% S$ T1 z+ g9 d  F& I% v$ D
  235. STY <Gamepad_Keep,X) n# X& P* J& d1 k. e1 p# R! [1 W7 o0 r
  236. STY <Gamepad_Temp,X
    % `/ t9 b) ~  c# i; i
  237. DEX
    ' Y8 E6 v9 a1 s
  238. BPL GamepadStateSave
    ; D1 J: K7 f0 f9 `
  239. RTS. A6 n. ~, p. w  c) @

  240.   n' H2 n9 q# T" \* z/ u, T
  241. GamepadDatacan;手柄数据扫描
    2 q* c4 b6 J1 ~, N
  242. LDX #$01$ \& E, w, K+ p3 ~4 _
  243. STX $4016* {8 A! J+ t4 T; s, D0 {/ k
  244. DEX
    6 t4 M% O; V* s% A1 c$ x' J
  245. STX $4016
    ( X, L/ F" G# R+ j& _
  246. LDY #$084 T# f  _- E$ b. Z
  247. GamepadPortScan;手柄端口扫描
    * M  D: v; _: Z! M: \
  248. LDA $4016: o: m% J( k) ^: Q6 O( d- n
  249. STA <Gamepad_Port_Value- W- {8 i3 S/ a; _5 F  c
  250. LSR A: B$ |% V. f1 m3 W2 {; o
  251. ORA <Gamepad_Port_Value' p3 R9 [; P& l+ H8 L
  252. LSR A
    1 J) z& y8 n' L$ e$ r2 [
  253. ROL <Gamepad_0_Value" D" P" D# ]! v
  254. LDA $4017% x" y; s0 M4 y1 V' m- I5 }$ E
  255. STA <Gamepad_Port_Value
    3 K9 r4 v( j: {: W4 c) S, W
  256. LSR A
    . j) }2 T0 h- r% L& A" W$ E
  257. ORA <Gamepad_Port_Value+ w' B0 i0 z- c$ @  k7 `
  258. LSR A
    - j7 }6 u  N) @9 g4 a9 V3 z
  259. ROL <Gamepad_1_Value
    " k' J8 G0 m7 O! n- U, ?
  260. DEY
    $ ], d/ l" J( }) o8 x# z
  261. BNE GamepadPortScan* k1 x) ^* b; f$ G5 a: K& U
  262. RTS4 v, f2 [. Q0 }" U$ m
  263. : D- W: ^( t, m; z
  264. ;==================================================
    " W; ~0 [. K7 n& E" k: f  ?6 U
  265. ;PPU处理
    2 ?5 n( _; ~7 e3 J' T* M0 h
  266. PPU_Process
    + m8 n; t: {. O: n' B) v- B' M5 Z1 F9 m
  267. LDA #$00) @1 Y. P9 i! ]  ^' m: `
  268. STA PPU_MASK* A, U7 H# E% `" u
  269. 8 d- u0 \. ]; C) \' B; a
  270. BIT PPU_STATUS" m/ x  A! \: @2 W% N
  271. LDA #$20# W3 {1 v( U# C
  272. STA PPU_ADDRESS8 I- }# z" U0 j$ G, s; i2 W1 U
  273. LDA #$000 K+ `  Z! @- d- h
  274. STA PPU_ADDRESS
    0 z& }9 C2 s0 E+ _9 G1 c) N
  275. ( v9 U+ Q: p" ^+ R( B8 M
  276. STA PPU_SCROLL
    8 V' [# D# I) [$ |- o% v
  277. STA PPU_SCROLL
    0 z( ~" l8 l6 E+ f6 q

  278. - v) e6 X6 t0 l3 m
  279. LDA PPU_Msak_Buf8 _% G4 a# G- n* _* X
  280. STA PPU_MASK
    ; U' |! D) c! i; F# T4 a3 d
  281. ) T6 _  h7 b# q- ]% @4 z
  282. RTS; `6 G6 b' J: _: M+ v$ c
  283. 3 w) i; N* }- u
  284. ;==============================, S( E9 P; q4 U" v) C
  285. Time_For_Vblank;延时等待
    / |0 L  V! b6 Z- f( m% y  L
  286. LDA PPU_STATUS; a* m+ D; s3 b2 `; X
  287. BPL Time_For_Vblank; ]! C/ J. w; M; L0 h5 U
  288. RTS- V2 B& ?: `6 ]1 M, z

  289. % f, x: w$ R# u- I
  290. ;==============================
    ) y) W' D2 m6 W5 S; V
  291. ;初始化MAPPER19
    4 L# `8 W  h1 n; V0 |( ?7 H6 z
  292. Init_Mapper19
    3 r# U& ^5 ]- F$ J2 \2 X/ L
  293. LDA #$009 i7 W  W# U% L+ i
  294. STA M19_CHR_0000
    / l0 U  I% n+ J5 b# Y* j
  295. LDA #$01
    5 ^+ _7 L! A6 F7 n9 J( o
  296. STA M19_CHR_04005 u' O6 a4 P4 q5 I7 G8 t7 L( T
  297. LDA #$02
    " `4 }1 c$ g7 X( M5 [7 b' s: U
  298. STA M19_CHR_08008 j$ e; T' M1 K: _8 \6 k
  299. LDA #$03
    * W( _' m/ s- a
  300. STA M19_CHR_0C004 i- ^' x# I% \5 m& l/ y/ g
  301. LDA #$04
    , s  M3 X; }$ b  e6 e
  302. STA M19_CHR_1000
    1 B) ?; v: m* a+ d  y% W
  303. LDA #$05. {+ @/ L9 r& |' h& K3 X
  304. STA M19_CHR_1400
    ; ~! ?: e6 Y  S; ]" d; I+ f
  305. LDA #$06
    3 p! b% j$ ]& ^! e2 J4 `$ q
  306. STA M19_CHR_18005 U. ]9 ~5 Q4 A# D! E
  307. LDA #$07; A! Z7 e( ?' Y9 r
  308. STA M19_CHR_1C00
    " u8 V$ ^) D0 j3 p* Y  ?
  309. 0 K+ E# z( @; U1 X7 O
  310. ;禁用IRQ6 b  r/ ?5 p- e; r; Z- ~+ Y% @8 Y
  311. LDA M19_IRQ_COUNT_H
    ' m% n; Y5 ]' b$ m: M
  312. AND #$7F2 @. f, m7 d) V6 \% L
  313. STA M19_IRQ_COUNT_H
    0 Y0 ~1 u6 Z. s4 y
  314. & n$ R4 }5 |1 e: }# T" G9 H
  315. ;命名表
    7 |1 d* Z4 g3 p+ l
  316. LDA #$E0
    4 Y$ R& J* z8 f: l
  317. STA M19_NT_2000' n, B3 w3 A" U' Q! K
  318. STA M19_NT_2400, A' j% A* v" s0 |8 z

  319. 9 B) `8 h7 H  U$ @
  320. ;命名表
    # \- N: O7 E6 a  V( J( J' K
  321. LDA #$E16 X) O- b, A% k" U; D
  322. STA M19_NT_2800
    7 d+ g) x2 K+ X7 Z6 L7 f5 H
  323. STA M19_NT_2C00! r; J3 g- l1 F
  324. * c- R+ {1 a+ X* R
  325. RTS- S; G# h' I( t' i$ E( r- F" m7 y

  326. 9 P) `& f3 E* E/ B4 x  \+ B, ]9 F
  327. ;==================================================
    4 ~/ \  P3 j$ y" }
  328. ;重置中断处理. l$ `; f8 I1 k+ @) X9 B! p
  329. ResetProgram* Q5 s% ~) ^, L  ]! e
  330. SEI( i# q) Q2 K$ a: j6 S7 j
  331. CLD
    % n" s9 f. `( x& H8 N0 }! \
  332. LDA #$00
    0 t9 P* C; J/ K* X" L
  333. STA PPU_CTRL
    1 @% H2 m+ N9 {- j* U$ f& ~
  334. STA PPU_MASK/ l3 K; |8 y5 K5 o6 W
  335. STA PPU_STATUS" v! p" Z; P, ]
  336. STA JOY2_FRAME+ ~% [/ Z5 }+ K  ~% T
  337. STA APU_STATUS! H1 q# p* M( G( f+ y
  338. ; U8 L6 ~6 [, H# Q' D. ]1 b
  339. LDA #$C0- c: T& w4 y7 F/ I
  340. STA JOY2_FRAME  G" g% Q/ E. d5 z. ?9 \
  341. 2 G" w5 m: u' J
  342. ;等待vblank/ m4 S% ^- [" g! v. y
  343. LDX #$02( _: ?* x! i. L# G9 t# P2 t# H
  344. Vblank_Wait_1
    * T& x8 K* M) u5 H" F3 I; L; R
  345. BIT PPU_STATUS
    + z  q7 _1 s: a2 Z+ s
  346. BPL Vblank_Wait_1
    8 G  ^- ?# M- i/ k
  347. Vblank_Wait_2
      H; M) ~6 O: U( Q, l* D
  348. BIT PPU_STATUS
    9 W4 X8 F! Q* V7 Q/ U4 k4 f  X: m& U
  349. BMI Vblank_Wait_2$ [* I/ T! R  S% n! e5 [: J2 J! O! h+ g
  350. DEX
    , M" J. p- ?0 f: q
  351. BNE Vblank_Wait_10 D2 }4 y3 H9 M! [2 }+ R/ K. q) L

  352. # f( H0 N1 n' ?3 V! E& q- T6 b
  353. LDX #$FF
    9 D, ~4 d+ Y1 H
  354. TXS  B; U' E* a1 P$ ~6 L" I

  355. ; I6 z/ ^" h1 O$ h, V0 Q
  356. ;初始化MAPPER19
    & i  q  v' q9 h
  357. JSR Init_Mapper199 w7 c  r7 p; f2 A
  358. " T. g" ^: h: o
  359. ;==============================
    . d2 [5 E- O0 y  m) c/ B+ p
  360. ;RAM初始化" k1 b1 Q* u" I
  361. Nes_Ram_Init6 e- N; P# t0 ^* z" O$ J0 l# X+ X: X
  362. LDY #$00
    6 }: C+ `9 S9 W; x+ e
  363. LDX #$08
    ; W9 W+ @3 R" L
  364. LDA #$00
    % Y9 v. @2 }. {: M0 V! i; W: Y5 z
  365. STA <$00
    ' g! T! a( ~( _! N0 I# x
  366. STA <$01
    2 D5 p4 O4 r4 G
  367. Nes_Ram_Init_Write, W8 S9 g/ B" a1 Q. V- B5 [- i
  368. STA [$00],Y
    6 [( _+ @$ V. a8 l
  369. INY
    7 W! ~- z+ s8 s# S7 S  A* {
  370. BNE Nes_Ram_Init_Write
    + F& X  r9 f0 d7 M( P" ], {* ^
  371. INC <$01
    2 Q2 D0 o6 o2 }5 A- J8 m4 F, I
  372. DEX
    : u# z: K& L% F4 [' Q% p2 d
  373. BNE Nes_Ram_Init_Write
    ( P  x$ E' i& H4 b3 [8 L8 h

  374. . D# v; @8 y  n
  375. ;初始化命名表9 D. Q7 q' m. K1 ?9 s5 `$ @5 _/ q
  376. JSR Init_Name_Table
    ' G; x& L$ M) T
  377. ( W, h# w: l) Q/ z# ~
  378. ;初始化调色板( s7 a5 B+ _! x1 }
  379. JSR Init_Palette
    9 n3 c* D, M9 |1 s+ N; E: H4 }
  380. # w5 I* a4 j4 q
  381. ;初始化命名表属性$ H% J5 Z% U0 _
  382. JSR Init_NameTable_Attributes
    & M, i, c- p/ h; W% V. e/ P( R" G
  383. : @0 A! `; S+ M/ q6 @9 e
  384. ;初始化精灵内存* @5 J5 D: F  ^7 V1 Z. B
  385. JSR Init_OAM_Ram
    / `7 Z2 Z8 W9 I1 I; N
  386. / q$ p, H% f2 C$ E6 m; h% J+ m# X1 _
  387. ;在屏幕上写点东西
      u4 ]1 q/ o% Y5 m0 U+ z( V  [7 Y
  388. JSR Init_Name_Table_Text
    " W+ }6 X% O* C- q
  389. 0 K4 ^! ?- ~: v  x" _0 Y: G: S" G
  390. JSR Time_For_Vblank
    ( n: O: y. M$ v8 }4 E& o- W
  391. ;开启PPU控制: H  f5 J, ?% n" S& v9 ~. [3 o. H
  392. LDA #$A83 K8 x7 u' D/ u" a" F* ?
  393. STA PPU_Ctrl_Buf
    % {1 t7 V$ C. N/ {, P& ]# C
  394. STA PPU_CTRL/ ~2 G1 g4 v% ^# c
  395. , w/ }3 N1 [, I+ Z) u! a
  396. ;开启PPU显示
    3 n3 ?" g6 J+ N- V( x2 Q" A  y' Q
  397. LDA #$1E
    & i; F2 s& e8 x+ z( H: w
  398. STA PPU_Msak_Buf
    " U- Y' p4 b# h0 @" m( O: r) g8 k

  399. / i  n% ?8 ^4 F: B% }
  400. CLI
    : Q! _8 u8 E9 H6 H3 S2 H! u  M, c
  401. JMP Loop" C( r' j$ \6 e

  402. # B! u* l- W- m4 B# Z1 t0 a% Q
  403. ;==============================
    % t4 {! l7 D. X- v( Z# w
  404. ;死循环, 等待NMI中断
    8 u8 @* O9 K6 n/ N
  405. Loop0 r% D" d$ Y8 Q' ]2 @3 f
  406. JMP Loop
    4 A5 E: h$ k; u8 }6 c( O/ g

  407. ( G2 j8 |2 y  v! w4 q5 r
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    ' H* X9 y2 p& Q1 b
  409. : `: @% w5 X! b" g5 k2 Z4 d* K% p
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    9 _7 S5 M1 w$ w$ i! R5 B2 p
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)# Q  M. V, X0 ^7 B5 \! K; K2 x) E
  412. ;==================================================
    - u- @1 E6 R% i7 W) x+ J
  413. ;NMI中断处理- F1 W: `# b4 P
  414. NmiProgram$ Q" H4 _+ l. P$ [6 R8 y
  415. PHA& \+ w% i+ P, O4 g$ d" m6 }" |
  416. TXA4 O( _  u$ i, O2 `- E8 P3 l! \* P# u
  417. PHA4 O! ], Y. m+ r! g4 z( s
  418. TYA
    3 @$ G/ ?2 V* ~( q+ E, ^; _) _# x
  419. PHA/ q' }6 k4 a+ @7 K0 X2 p, ]

  420. 2 h7 A1 f  I# t, Q
  421. BIT PPU_STATUS
    . u! O( l8 u* ^  @* T2 E: D0 b0 S

  422.   m( N7 t" u: x3 y& s
  423. LDA #$00
    2 y6 ?' A% ]' w: e; W9 @) `
  424. STA IRQ_Index
    9 s! J/ a0 U0 O& k0 q: K" h

  425. 2 P5 p: Y$ T' P2 S& }% r# G
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    ' y& m) l& j. l3 b) [
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)0 z! m7 q, D3 B1 P8 q* b& s
  428. STA M19_IRQ_COUNT_L3 t8 T: x. ?; N0 g8 F9 t
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)  G% H) B" v0 k
  430. ORA #$80! f+ P# r2 ~: G; f; l4 o8 U
  431. STA M19_IRQ_COUNT_H
    9 F- `& _' l% ~: W4 m- C
  432. CLI/ q, F8 W" w# ^' k/ f

  433. : Y6 ]( V2 M: q8 ], l
  434. ;关闭PPU控制
    / m" }7 J* r* {+ J1 K$ U
  435. LDA #$00
    - ?4 @' W" M6 X
  436. STA PPU_CTRL
    & {9 n; A. F4 Z: n& E3 [

  437. 0 E9 K( }6 H. t
  438. ;处理PPU
    ( X% x! R+ ]! S& U, K# K/ B
  439. JSR PPU_Process  ?& S$ e; k) N% T6 s$ d, H6 n

  440. 2 \' k+ N" D; `0 \3 |  A
  441. ;开启PPU控制( c/ F, r2 O/ ?
  442. LDA PPU_Ctrl_Buf
    2 E/ }3 q! N5 s) _1 D* v
  443. STA PPU_CTRL- y3 b# I1 \/ Z
  444. $ K( \3 }6 ~% J" v
  445. ;手柄处理$ o& O' g% B& L& r( ^' ?$ x
  446. JSR GamepadProcess0 m2 A" U4 d9 G. y% ?

  447. ! x/ N& f7 M" c; o2 g0 L- S
  448. LDA #$00
    4 Y; F4 Y8 }7 B/ U, i/ [
  449. STA IRQ_Index
    6 A& K) U" B- f  m: z/ {' y- O

  450. 6 F6 y1 I) z: G- O2 M
  451. PLA0 R8 s; ~$ s/ [, y
  452. TAY
    * F6 y6 W3 j$ y0 C" K
  453. PLA( g. s4 V9 ^9 e, ~
  454. TAX. @$ p; Y9 Y! q2 ~' ]: T' M
  455. PLA" P# H/ X9 |; P; A
  456. RTI
    4 D9 ]$ E9 Y6 m8 o

  457. + X2 W2 z2 q) r( g0 F, I; Y
  458. ;每行扫描线113.676 P; H. v6 `1 m1 Q2 t- Q
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)5 r8 ]2 m# g% M5 d
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
    3 F+ Z# p! y$ f* }6 f4 d
  461. ;==================================================# \. O5 A3 v3 x8 r
  462. ;IRQ中断处理  H; C8 D. m3 _, B$ l+ e
  463. IrqProgram
    % t- A: u$ ]. @+ B8 R7 Y+ f
  464. PHA
    / C; k6 F6 m  u9 c; M, j+ X
  465. TXA2 h3 u3 p- u- T
  466. PHA: `1 C- \8 \  j
  467. TYA
    2 |9 }9 p& J. U. p8 u) s9 A
  468. PHA" O1 A( r5 \: x; Z( r$ {
  469. ( S) h1 l: |- Z- |* t' C
  470. ;16条扫描线后触发IRQ
    * N6 ~: E* l$ B4 ]& U
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    - {( G6 S6 ^3 G( ]# r* v8 D; g2 Z* ]
  472. STA M19_IRQ_COUNT_L+ Q9 r& M- ^8 R9 P2 j. H6 T
  473. LDA #HIGH(BEGIN_LINE_CYCLES)" q0 Q5 d/ h9 f
  474. ORA #$80
    + U0 G! k- b$ W( J$ p3 ^# L
  475. STA M19_IRQ_COUNT_H
    % ^( T' p- K$ N1 J6 ]) N# |

  476. / J) m: y4 g) U- I9 u; Z. _  w
  477. LDA <IRQ_Index
    ; W. }. U" a) q7 b/ l1 e
  478. BNE * + 4
    6 m+ C' D# V. e2 J
  479. INC <PPU_Scroll_H" H3 j, j. I3 z  e% f4 K, {. H* V

  480. " R2 v4 O1 c* @# g! e& Z
  481. ;设置屏幕滚动
    . R( A6 X) T  L2 ^9 H4 O8 m6 l
  482. LDA <IRQ_Index
    ) J. C' J' t4 [% \
  483. AND #$01& Z! [& d& t8 k, d6 ~$ s% O$ U, [9 n) E
  484. BEQ Irq_Scroll_Right" p2 s( y. }. m

  485. ) D$ f" m1 p& T* R3 F
  486. Irq_Scroll_Left
    / b: _% ]) p: X$ o( x7 X
  487. BIT PPU_STATUS$ F. F& ]7 Q5 Y( N! B9 u; Y
  488. LDA <PPU_Scroll_H
    : E) {$ T3 U+ @( ^+ n# O. X% Q# H
  489. STA PPU_SCROLL- P# G8 k& d9 U8 E- {  Y5 m
  490. STA PPU_SCROLL5 l! B5 [5 Q1 |9 F: z# E& J
  491. JMP Irq_Scroll_Over
    $ ?" Q4 F" i& U* g' u

  492. " A  A) L1 M3 w0 F' u+ G9 e
  493. Irq_Scroll_Right
    9 R; q$ G2 n% M- Q  Q+ ^' \
  494. SEC/ N, ~# l: g; ?4 _1 R# G  ~+ o
  495. SBC <PPU_Scroll_H3 q' f) |1 _! u3 a
  496. STA PPU_SCROLL
    2 y6 Q4 E7 r/ [9 u, J
  497. STA PPU_SCROLL
    - ~6 C2 r9 M& v  P) S7 S
  498. Irq_Scroll_Over4 v% x0 k4 x* b3 M! }6 X2 E% W

  499. 7 O  W" G' c# m4 _  P1 q9 [
  500. INC <IRQ_Index
    1 g  [0 C3 c/ y1 ?+ {7 X' L
  501. ' `% r' `" ]+ i4 w. C. ^+ I! f$ Z
  502. LDA <IRQ_Index
    4 f. ^+ f8 ~; d3 q- @( ?" S" E$ r
  503. CMP #14
    ' E: I( o% F2 W0 @4 ^  D8 s
  504. BCC * + 10" A! f! K# m) n9 L6 W
  505. LDA #$009 m' m) A! N( \/ f  {
  506. STA M19_IRQ_COUNT_L
    - k" L9 c, q3 z1 k# V% N
  507. STA M19_IRQ_COUNT_H
    ( o) x+ y6 R) a
  508. / W- s3 r3 T* w
  509. IrqProgramEnd: H* ^2 Y+ G# l/ X3 ^
  510. PLA8 D& D, Y! L# g& o2 @; l: H
  511. TAY
    3 b4 ~, D* G+ B+ r' e1 R, t
  512. PLA  _) y- ?. V/ _7 O5 ^) q- q8 `; X
  513. TAX
    # d1 B( }' Z9 {; \; n9 C
  514. PLA( r3 g& k' g& b) ]
  515. RTI9 j$ X2 o! l4 @/ ?

  516. 8 |) N' H  y4 C) X6 W  O0 f  O; v6 o7 I
  517. ;==================================================
    9 S1 Z, V3 g! N: j) z) x' P
  518. ;中断表
    / \" M" v: |4 `0 M; ~
  519. .ORG $FFFA3 \! F1 g9 v' m# Y5 Y
  520. .WORD NmiProgram; u# v  W+ N1 h/ U
  521. .WORD ResetProgram. [& b* Q( y2 @2 B* ^) B& L6 ]
  522. .WORD IrqProgram
复制代码
- B% Z( z8 f7 V" B9 \. v8 q

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-6-10 02:55 , Processed in 1.082031 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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