EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2023-7-16 20:16:44 | 显示全部楼层 |阅读模式
  1. ;[FC][Mapper19 IRQ]
    4 @( {2 L0 `/ |! @* X
  2. ;FlameCyclone 202307107 s% b9 T3 l, q! |: y: C$ X
  3. 5 ?- T7 R$ x+ U. k
  4. ;文件头, m. W8 [! A/ r- o9 r# K
  5. ;======================================================================
    , W  q5 [* D# x% h3 H) P
  6. .INESPRG 4                                              ;16KB PRG 数量4 `% L9 M+ ~3 F
  7. .INESCHR 1                                               ;8KB CHR 数量
    ) d& r% v% q; H* i! s
  8. .INESMAP 19                                                 ;mapper 19
    & b( f+ X- n& `5 w: \0 I8 {1 Z1 V8 q
  9. .INESMIR 1                                   ;命名表镜像 0水平 1垂直6 c. z7 p0 a  h7 w! s
  10. ; o1 L2 v/ j1 l. s* d2 z: X
  11. ;必要条件) b) l( n$ b$ }# V7 o+ M) f& i
  12. ;1.持有CHR ROM
    1 f7 Q8 x/ R% M) t$ }
  13. ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
    ( b  y8 P( a# h% X& {. g
  14. ;3.精灵内存(OAM)不为空3 ?( ?- c2 K6 G& c, V$ D, R$ l
  15. ' `, U. n, C1 k4 k9 C6 g5 ?; t' k
  16. ;==================================================
    # w# `; Y4 l5 L5 l& J, {) k
  17. ;NES端口常量
    , t0 g/ I, a$ k% L7 n- D
  18. PPU_CTRL                =   $2000   ;PPU控制寄存器" B4 T% \- A7 R, {
  19. PPU_MASK                =   $2001   ;PPU掩码寄存器
    3 m5 P  n( c* }7 M, {: T) K
  20. PPU_STATUS              =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位- \+ X6 [/ M. D7 ]. R
  21. PPU_OAM_ADDR            =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1: V5 H7 B6 ?9 e8 a3 [3 `: t) D
  22. PPU_OAM_DATA            =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1% H0 u8 L# C6 R: a) {
  23. PPU_SCROLL              =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 " P7 s% ]  r! {: A3 N4 V; q
  24. PPU_ADDRESS             =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
    ' V9 q$ v8 M$ W0 P
  25. PPU_DATA                =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
    & b9 Z2 f, f, D: s. x1 `8 O+ d1 O
  26. OAM_DMA                 =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
    7 I. T9 r& a5 w& ]: G& G( Z) k- `
  27. APU_STATUS              =   $4015   ;声音通道切换9 m+ T( \$ }8 i: d+ m
  28. JOY1_FRAME              =   $4016   ;手柄1 + 选通$ z$ Q  [& F) F+ R$ u$ E
  29. JOY2_FRAME              =   $4017   ;手柄2 + 选通
    0 c- m! Z8 H( Z$ T5 A

  30. # f$ `% J8 d1 ]  ~9 _
  31. ;==================================================
    7 l$ l8 e. Y) ?* K
  32. ;MAPPER 19端口常量
    , D" y1 W, v; P4 i
  33. M19_CHR_0000    =   $8000
    0 r5 E* {6 X2 {$ P& {. C
  34. M19_CHR_0400    =   $8800
    ! [% Y4 z- B4 l
  35. M19_CHR_0800    =   $9000# r& \/ C+ Z4 F6 V  r
  36. M19_CHR_0C00    =   $9800
    * i2 C/ d5 [1 k7 c
  37. M19_CHR_1000    =   $A000+ S' Z& C& c- M1 g
  38. M19_CHR_1400    =   $A800
    " v/ z1 m- R8 g/ t+ y& {1 {
  39. M19_CHR_1800    =   $B000; s6 p3 E9 b" Y
  40. M19_CHR_1C00    =   $B800
    . M% i' X: }5 a" R5 x8 i4 \
  41. M19_NT_2000     =   $C000- X/ Y& Q0 S  Y0 t
  42. M19_NT_2400     =   $C800
    - Y3 ?1 q9 Y$ l! k# l
  43. M19_NT_2800     =   $D000' ]: W, W& q7 T" {6 c; h, i
  44. M19_NT_2C00     =   $D800
    , q2 F( ]4 C2 Z8 T- B/ g
  45. M19_PRG_8000    =   $E000. Q1 k: Z- M. p4 h4 ?: G. S
  46. M19_PRG_A000    =   $E800: d# P4 U- N! n/ z% s, T
  47. M19_PRG_C000    =   $F000% v5 h# j- D, `6 ^: Z0 C4 S* G
  48. M19_IRQ_COUNT_L =   $5000" q7 |4 X; _& K8 o6 G
  49. M19_IRQ_COUNT_H =   $5800. S8 I% W2 ?0 [
  50. $ M! \' i: A. n- E" x6 k+ t
  51. ;==================================================
    ( v# v( f- e1 M
  52. ;程序块配置
    2 q* _: Z( {) p' p2 ?. f
  53. BANK_DATA_MASK          = $07
    6 {) X& _" ]' G7 q2 Q6 ]
  54. ;--------------------------------------------------; E, D+ |5 X6 d; g" Q3 t
  55. RESET_BANK              = $07
    ; k* J1 g) U3 [* n1 \
  56. RESET_ADDR              = $FC00
    " h: v3 R6 Z: |) D

  57. 0 W" G8 B: Y7 i
  58. ;==================================================. S" I8 U+ `+ d/ M
  59. ;图像块配置4 ]# X! L" x) g. U
  60. CHR_DATA_BANK           = $08
    0 Q# j- x8 L9 {! ?

  61. & v! r5 x  n# g2 Q% F
  62. ;==================================================
    9 B* L4 X" V" n  k7 N6 S* `) D
  63. ;零页内存地址配置( v# r1 o1 R. m+ `7 W6 B
  64. Use_Ram_Addr            = $80
    & @) k' b6 U' ]6 T$ f7 y! F0 D
  65. PPU_Ctrl_Buf            = Use_Ram_Addr
    6 s9 z! |/ e* z3 `2 y
  66. PPU_Msak_Buf            = PPU_Ctrl_Buf + $01
    ; Z- \6 D1 u! a  C/ V
  67. PPU_Scroll_H            = PPU_Msak_Buf + $01; l- S! \' P# h0 {* N
  68. PPU_Scroll_V            = PPU_Scroll_H + $01. T# z1 t* \, W
  69. FC_Data_L               = PPU_Scroll_V + $013 u* t  `) U8 W0 w, P+ k$ j7 b
  70. FC_Data_H               = FC_Data_L + $012 L% A1 x- r1 y) F0 m: a
  71. FC_Data_Buf             = FC_Data_H + $01  c  F8 Z, B5 Z8 f8 C
  72. ;==================================================
    % g  f# j1 E& n1 k

  73. $ f6 F' s1 l7 U7 ?
  74. GAMEPAD_MERGE_FLAG = $04- J: \# J$ i% M$ R! S
  75. 5 c" l8 S5 P5 l) t  T
  76. Gamepad_Keep            =       FC_Data_Buf + 1
    # ~: u0 M$ p6 ?% H; S1 L  T4 t( e- `. r
  77. Gamepad_Once            =       Gamepad_Keep + 2, Q5 d( I1 h7 w9 B$ [1 F! J; M. n( h
  78. Gamepad_Temp            =       Gamepad_Once + 2
    + i$ x% F) C- }2 N) o
  79.                                 4 d, G/ }3 s7 u$ B7 H1 q7 H0 T6 @
  80. Gamepad_0_State         =       Gamepad_Temp + 29 G3 ^5 M3 U  C, J1 a
  81. Gamepad_1_State         =       Gamepad_0_State + 1; z% s* k7 y7 G! W+ d- F
  82. Gamepad_0_Value         =       Gamepad_1_State + 1
    " b( b2 ~( k  u! R7 `( K# j; V
  83. Gamepad_1_Value         =       Gamepad_0_Value + 1$ c. v& a% t# k: c
  84. Gamepad_Port_Value      =       Gamepad_1_Value + 18 G4 |7 P) {8 d  X7 R- R
  85. Gamepad_Merge           =       Gamepad_Port_Value + 1+ x# j! E! m9 f8 P" N$ {

  86. & j& v1 \$ b+ O( _
  87. ;==================================================
    7 m" I% [  @6 C0 I
  88. IRQ_Index               =       Gamepad_Merge + $01
    : y7 v$ |8 B8 n* F! A7 z
  89. ;==================================================# I5 @( j1 U" J* R: k) W; }5 \/ z, l3 @
  90. 3 s4 A7 P3 S0 @) |$ t, X
  91. ;CHR图形数据
    * k: {1 n( @0 |$ I8 }
  92. ;==================================================
    9 K5 P# _& P4 d* l+ V3 i: Z6 k' o; Z
  93. .BANK CHR_DATA_BANK7 ?) ^' \! @$ o2 |/ K6 O; f4 N5 q7 k
  94. .INCBIN "chr_bank/chr_data.chr"
    " f; p2 R- N0 ]0 X* A
  95. / ?0 g& ?2 n. H" o0 G) F
  96. .BANK RESET_BANK & BANK_DATA_MASK
    4 Z  M( r' P- B  q1 e: y0 t) D2 O3 |
  97. .ORG RESET_ADDR
    6 C$ e9 w  |& ]9 m0 \6 p

  98. 6 l' I; |& ^; E2 F2 i
  99. ;--------------------------------------------------; L. l& a6 T5 \2 a& c3 j
  100. Attributes_Data0 ~3 K; l/ C3 v4 L) J
  101. ;命名表属性  {9 q+ u. V/ i0 l, d$ b
  102. .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00) D# q( B) ]' ], O+ ?- W
  103. .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA. c  ]- R+ H- a; A& Y2 N
  104. .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA9 a7 ]) \, T* ]3 q$ P) X8 t, F! }
  105. .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55* \9 G  Y% b) X" g6 _$ M8 J7 G; M
  106. ;--------------------------------------------------! i5 i9 j* Z' N/ g# e  T& W* q6 u* ~7 k
  107. ;调色板数据
    8 g$ U8 {+ w3 X! T9 B1 Z3 u3 N
  108. Palette_Data) s/ M1 }/ }8 c" G  i4 Q) `- Q9 p; p7 [2 W
  109. .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
    / b9 @; k' k6 z/ I* [6 _, e5 u
  110. .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
    ; W! d5 |. r9 J0 L$ }: N

  111. 1 \4 b% @, C% K- ^, u1 r/ C
  112. ;==================================================
    / F6 u: M) E4 y* Q
  113. ;命名表初始化; L  F: ^9 @4 L7 Z0 P
  114. Init_Name_Table
    5 G3 V9 J7 L: o
  115. LDA #$20
    * x" z) x2 z" }  |8 Z& ~/ u- O
  116. STA PPU_ADDRESS4 b( s4 B& D% Z3 V  \
  117. LDA #$00
    8 l, r, y/ U, [2 C% k! [) _
  118. STA PPU_ADDRESS
    8 X/ i, }* B) R
  119. LDA #$00
    4 a) X0 E; o( c# J9 S
  120. LDY #$008 G; ], x. X) P( k7 |$ {# P
  121. LDX #$10: v7 X4 b6 h3 k# r( ?) z
  122. Init_Name_Table_Write2 f8 N5 N2 u! U3 l, k
  123. STA PPU_DATA( C$ c; @, R: ~1 Q1 F
  124. INY
    7 x) o# v1 h& I+ u; Z( f9 |7 X! n
  125. BNE Init_Name_Table_Write
    1 c6 n9 k: q. l& M* J. R$ q3 H
  126. DEX" H8 p& o8 f9 g$ G: F
  127. BNE Init_Name_Table_Write% _! D" z  ?: `1 t( d6 ~
  128. RTS: h6 W$ N% ^7 y$ Z/ L; C
  129. 9 D5 }' l( ]/ E# K
  130. ;==================================================
    3 g5 c1 F& z; L  O$ q1 [, A
  131. ;调色板初始化
    ) q4 Q3 o# w+ A% C% j
  132. Init_Palette
    + l# D5 q7 N; p' h' J
  133. BIT PPU_STATUS0 E" @* o# @1 r: v2 Z, @
  134. LDA #$3F
    - p& t& l, T. g: C" H
  135. STA PPU_ADDRESS1 W" q( O3 h" S9 p; Z! l2 ~7 v
  136. LDA #$00
    ! g. E/ W1 L  a' p0 F4 H
  137. STA PPU_ADDRESS
    + i, X  y) ?& R( P* Q( m7 J
  138. LDX #$00% k" F$ C- t. G' i
  139. Init_Palette_Write
    5 n3 O$ i; t+ u
  140. LDA Palette_Data,X6 U% s* K& G1 d( B% l8 Z+ {
  141. STA PPU_DATA
    * I5 `! \. ?& Q! @6 l3 I( d
  142. INX
    - o- v) `6 S/ V& p- k4 x
  143. CPX #$206 n. x0 }5 z4 r
  144. BCC Init_Palette_Write- i* O9 F* i( Z
  145. RTS
    " D# \1 d- V- ~! T- h

  146. # h# Y; c- a$ |! \1 V# N* [* C
  147. ;==================================================
    ' ?4 q: ?+ z$ G7 y* {
  148. ;设置命名表属性
    * _- o: D1 u) Y
  149. Init_NameTable_Attributes
    - |+ S# f& _1 X, X
  150. BIT PPU_STATUS" S' k! b) q0 @; L/ I" Q
  151. LDA #$23
    ! H  b6 k) s: k0 G  R5 R! }
  152. STA PPU_ADDRESS
    $ G6 G9 T7 X3 N4 |, ?
  153. LDA #$C0
    : J6 w+ S* t) X/ O; D
  154. STA PPU_ADDRESS
    7 o2 ~7 s; \; v! u# H$ W8 V
  155. LDX #$005 G. `! \! L* E
  156. Init_NameTable_Attributes_Write% I: S1 a2 p/ ?; [) ]" Y- t4 R1 p
  157. LDA Attributes_Data,X) ~7 L0 G6 w0 D9 I
  158. STA PPU_DATA# }  [: ~) N$ A& s- n/ w) D
  159. INX
      I3 ^8 }. J* w" u
  160. CPX #$40
    4 y! D+ W- H7 s0 j
  161. BCC Init_NameTable_Attributes_Write+ S! R, |3 I, x( [3 |3 M
  162. RTS- v2 t" u3 L# X' w

  163. ) d8 z, d- Z; u% I
  164. ;==================================================
    " h+ b- U6 \4 z, x- C! A5 M
  165. ;初始化命名表文本
    6 k3 f) j/ r) n" k0 v9 x: f
  166. Init_Name_Table_Text% q+ t6 j( Z$ r" [0 l
  167. BIT PPU_STATUS
    * k5 I! M5 C$ U
  168. LDA #$20
    , j( D* O3 E# Z: i
  169. STA PPU_ADDRESS  f4 I# c0 V: F8 s
  170. LDA #$00" n: B, U. d! r- Y4 Y0 Y% a( C* {
  171. STA PPU_ADDRESS
    # Q$ I- r( b( |
  172. LDA #$00
    5 {. B- Z$ H$ }& q+ G: @
  173. STA FC_Data_Buf+ i) X: [! i" e+ P. @) E0 G
  174. LDY #30
      G' G; l' ^/ x+ T
  175. Init_Name_Table_Text_Write
    + K' V/ k- T6 E2 p4 L; `
  176. LDX #32  s# B' d4 w- f$ H* K8 x6 j
  177. Init_Name_Table_Text_Write_Char7 D% ?/ I6 t7 W  I. l# W0 O6 u
  178. LDA #'0'
    " n" E# R: W4 A9 j5 N6 N
  179. CLC
    : s0 b* K- G" ?
  180. ADC FC_Data_Buf% v1 l6 H* S9 C1 W6 q8 Z
  181. STA PPU_DATA) |  \4 S! r7 p
  182. DEX7 n5 h; A0 z- y7 k8 L8 g
  183. LDA #$14
    ( d6 h& ?; i/ C; x- L3 G6 [% r7 Q
  184. STA PPU_DATA
    ) d) ?" r0 \% H! x
  185. DEX
    * w& u# U* g' ]3 Y' c+ Z  m
  186. BNE Init_Name_Table_Text_Write_Char' X+ C/ k+ m5 g
  187. INC FC_Data_Buf
    , g" W. F5 i; {( _1 C
  188. DEY
    ; J7 A' ?1 a# c! D# k' Y+ t
  189. BNE Init_Name_Table_Text_Write% ^) m' C" V9 X: W- z
  190. RTS& _3 h* J& i3 a) w' H

  191. / n, n' `$ v% ^
  192. ;==============================
    ; z9 ~" I) p( s( [  O( K
  193. Init_OAM_Ram;初始化精灵内存
    * n) A5 N2 J2 \  }- J% Q4 V0 H
  194. LDX #$00) G% k$ z0 }) [% E2 r2 ^5 I
  195. LDA #$00
    2 i* o9 L* Y( O2 B# R
  196. STA PPU_OAM_ADDR9 [( T( I0 w$ N
  197. LDA #$F8
    * F% b% g/ g" I- d- C; M6 _2 B6 J9 F6 M
  198. Init_OAM_Ram_Write' t5 Z5 j$ Y0 @. B0 M# b: y: x
  199. STA PPU_OAM_DATA
    ; m$ _$ T: H# U+ S2 g
  200. INX1 B8 G# |/ N: a5 U/ T
  201. BNE Init_OAM_Ram_Write8 m: \( B3 L* w+ ?
  202. RTS" O0 B  z7 w3 m- z8 U& M& W/ T0 M
  203. 1 B, W0 J. W! K6 j; E
  204. GamepadProcess;手柄处理
    : y( h- J/ h' ]
  205. JSR GamepadDatacan
    7 e( z$ G/ N; \: g+ q7 Q5 r5 v" B7 b
  206. LDA <Gamepad_0_Value
    6 m! ^0 K" C: }6 ]0 E; |8 c
  207. STA <Gamepad_0_State
    ; Z+ \" m2 {( \4 O) U. K. E/ v& S  s
  208. LDA <Gamepad_1_Value" \  [& p( t4 y
  209. STA <Gamepad_1_State" T/ z  i9 J, v7 e& ]5 M* C
  210. JSR GamepadDatacan' R. D3 N& f) `, {
  211. LDX #$01
    ' u" V* d: P8 e/ U& x5 X
  212. GamepadMergeCheck;合并手柄输入检查% y0 o$ w# ^9 u
  213. LDA <Gamepad_0_Value,X1 G/ E# _# v7 B' }7 V+ e% ~( \" `$ k
  214. CMP <Gamepad_0_State,X
    % _/ f8 e' k3 }9 d
  215. BEQ GamepadMergeInput1 ~0 J3 |. E" G1 S
  216. LDA <Gamepad_Temp,X
    & [! L7 J) y' ]
  217. STA <Gamepad_0_Value,X
    ' q1 w1 b* H& n. F  Y
  218. GamepadMergeInput;合并手柄输入
    9 @# K. C6 J% V/ x+ Q5 c% U
  219. DEX( Z% ^5 [( N) J/ t
  220. BPL GamepadMergeCheck
    ; D5 K8 b, H( ]; d; P
  221. LDA <Gamepad_Merge
    5 j, P$ f5 E3 Z: C5 V
  222. AND #GAMEPAD_MERGE_FLAG
    7 u" a$ V$ ]% l3 Y/ V
  223. BNE GamepadStateProcess' z5 j$ \! V* w% I- m& s
  224. LDA <Gamepad_0_Value
    ! y, p6 G0 i" b9 x2 I
  225. ORA <Gamepad_1_Value
    8 v& x; T1 N  Q# S
  226. STA <Gamepad_0_Value$ C( T$ K' w" P
  227. GamepadStateProcess;手柄状态处理
    % W, V1 K  ~8 J% p4 t  n
  228. LDX #$01) j& X1 f. E6 W1 h' E, H
  229. GamepadStateSave;手柄状态保存
    + Z$ e$ x3 G. I( ]  r* f
  230. LDA <Gamepad_0_Value,X
    / |5 b: Z7 o$ K: V1 Q
  231. TAY( j+ r% i% x& s+ M: W% ^5 \
  232. EOR <Gamepad_Temp,X
    2 y, B) x4 Q: O- ]5 c# S" P
  233. AND <Gamepad_0_Value,X
    2 j4 {& t+ E3 Z: I+ G; L$ `' l
  234. STA <Gamepad_Once,X5 C$ Y6 M" u( d8 p1 H* [/ T% [# D
  235. STY <Gamepad_Keep,X& F$ @, F+ C, t, S/ @
  236. STY <Gamepad_Temp,X
    : d5 v! _2 U5 |& F0 x6 j! E- t& ?
  237. DEX
    2 w9 t, L; U" Y7 k
  238. BPL GamepadStateSave
    ! H$ T8 F9 H$ Q* y. v
  239. RTS
    3 a2 O8 l# A( G

  240. * l% p8 h  C+ Y! `' m7 j
  241. GamepadDatacan;手柄数据扫描
    2 o. T* s& ?' m+ V8 t! c
  242. LDX #$011 k  J5 I; J( c6 O, R. d% l
  243. STX $4016& I- g+ y6 k: l
  244. DEX2 ?8 f! }3 w+ W% O
  245. STX $4016" e$ t5 e0 @; V! O
  246. LDY #$08; D! c8 Q* w' P  p" R
  247. GamepadPortScan;手柄端口扫描
    0 A$ v8 _/ Y9 P) X/ B6 g
  248. LDA $4016# I/ l' X! ^0 ]4 |
  249. STA <Gamepad_Port_Value
    & j0 U: {2 K% W) T
  250. LSR A
    8 U1 H% u+ T: r. e5 A2 _: v  A
  251. ORA <Gamepad_Port_Value7 `2 T, z' i) q9 o9 s  ]
  252. LSR A
    2 @/ N% a# U' D* i, V! Y4 o
  253. ROL <Gamepad_0_Value( V. M* W* @& x0 b
  254. LDA $4017) E' G' e: H9 V2 ~' t% K
  255. STA <Gamepad_Port_Value" A7 w; E8 r& }) E! s
  256. LSR A% Q8 z  X2 a  g, ^
  257. ORA <Gamepad_Port_Value
    ) W8 Y( i! d( D
  258. LSR A
    ( o+ A" g  x4 l; m9 }
  259. ROL <Gamepad_1_Value5 o: T7 A+ u5 k; Z* D, d
  260. DEY
    . M; K; X8 _# ~( y, |' F
  261. BNE GamepadPortScan
    ' e  G/ \% _3 a$ q
  262. RTS& W! Q" ~2 i/ P& s5 l3 L/ x

  263. 7 e( i% Y# {: l! ^8 Q0 p7 M2 O. ]6 ~
  264. ;==================================================. V1 o: ?4 s2 F: O# P8 E+ L
  265. ;PPU处理% S$ j. w8 K( s; E+ w
  266. PPU_Process3 f6 k1 f2 h# I, J' y" Y2 i$ C& q) T
  267. LDA #$00: C+ o) r4 F6 ^: f3 t) l* N
  268. STA PPU_MASK
    ' e8 @  A/ U' ?4 R

  269. , j6 K3 Q* K7 |  ~( v
  270. BIT PPU_STATUS' i  S' X# S) _8 U: z  i
  271. LDA #$20
    * K- G! R( B2 Z' h: Z* r
  272. STA PPU_ADDRESS$ Y- }; i+ q# K# Q7 ~
  273. LDA #$00
    9 t2 O9 \+ R) r4 P/ m
  274. STA PPU_ADDRESS
    ' J7 `$ n0 b0 e% j1 b

  275.   {$ p- a6 d9 U) `
  276. STA PPU_SCROLL
    1 O* `4 J) O( u& V" U
  277. STA PPU_SCROLL
    1 d9 q: v4 ^9 u* ]( X7 O% z: d
  278. 0 |" A* x9 ?. U! p5 R% Y
  279. LDA PPU_Msak_Buf5 k' {, N* m2 j6 k; Q
  280. STA PPU_MASK
    ! I5 s7 j4 s  i
  281. : n5 j; \0 B5 W( F# s, K$ ]
  282. RTS
    + [" K8 E" u) {9 K% G! h4 h
  283. * |9 p% M- s4 ^9 \
  284. ;==============================
    $ s& x9 U' w) m( b% u6 l* a
  285. Time_For_Vblank;延时等待5 D- P; ]  b: p/ N3 f
  286. LDA PPU_STATUS' a9 c* C# ~) l, U) r3 J
  287. BPL Time_For_Vblank
    & A8 F4 f9 l) L/ q& ^3 B
  288. RTS
      g7 s" {* Y% J$ A, @; u

  289. + I, g8 F; P$ V& g
  290. ;==============================  ?7 P# S/ F  b9 {+ n/ g+ p
  291. ;初始化MAPPER19" w0 E9 w$ `2 |0 h
  292. Init_Mapper19. n( W+ J  ]# G
  293. LDA #$00
    ; K. s3 D+ H7 ~- F! j
  294. STA M19_CHR_0000
    % G+ Q: ?8 @. e+ a9 e; z
  295. LDA #$01
    " p" g6 r* ]- N
  296. STA M19_CHR_0400
    5 l& P  l( {3 K% {  K! p
  297. LDA #$02. ?( Z/ B  @  F$ U! C1 a; h
  298. STA M19_CHR_0800; c) ?5 Q+ M/ a9 h: R4 K
  299. LDA #$03
    - q, }1 N1 u9 T5 X" G0 n7 ]
  300. STA M19_CHR_0C00
    % S8 S" ^2 s1 y3 x- m3 s* E5 b
  301. LDA #$04
    . @' _5 ?2 @, b" s) @1 h# R6 }2 N. W
  302. STA M19_CHR_1000# a, J: I. I1 N+ P1 d) [$ O
  303. LDA #$05# H5 A4 D; r( P" z
  304. STA M19_CHR_1400' d, X0 c$ r. Y  @  [
  305. LDA #$06
    % c+ l! i, J, L8 J
  306. STA M19_CHR_1800
    4 d6 F: l( m4 i! [
  307. LDA #$07
    * C2 c3 u9 ?7 b; G0 p% ~3 w
  308. STA M19_CHR_1C005 k  `7 J9 I+ V- H2 r
  309. . G8 x: |3 R# _5 |
  310. ;禁用IRQ0 `. \9 z, d6 X5 m
  311. LDA M19_IRQ_COUNT_H
    8 r: g' Q- R# x2 P& N4 p
  312. AND #$7F7 g4 w9 ^0 V. v" k, p
  313. STA M19_IRQ_COUNT_H
    - \& _7 Y/ Q! R# k" C

  314. # p# p2 x% }( Z# b( }0 V
  315. ;命名表; ^' s% n" Q" y. x" R
  316. LDA #$E0
    * i5 C2 F1 ^3 e$ ]; S
  317. STA M19_NT_2000' G7 B7 v* G/ k, s) d3 ~: {2 e' k
  318. STA M19_NT_2400
    & z9 R% t' |- Z# ~4 R9 _# B

  319. / a, [  j% u' D* t; w9 v+ t2 q$ U
  320. ;命名表
    * s- {: f" R# g' o+ x5 Z
  321. LDA #$E1$ q9 \4 \6 s( E8 ~
  322. STA M19_NT_2800$ I6 k3 m) z. Q; N; {  R- K( |
  323. STA M19_NT_2C00
    7 A! L# j; C7 b9 K; c) ~: h, l) P

  324. % W/ L8 V4 f) n4 n2 {
  325. RTS
    9 C# _" D% H# i; _/ y3 |$ \$ ]& F
  326. $ ?$ h) T4 L6 U
  327. ;==================================================
    / h, n' _+ V; S& x, T
  328. ;重置中断处理& n# b4 D- P3 x3 U& n' Y: u8 o4 l
  329. ResetProgram/ k, e: {" o' L
  330. SEI
    * l, l/ }( m2 T- H! I
  331. CLD
    ) r9 l5 a3 ?+ L: s* I$ z" L5 W: |& B
  332. LDA #$00% n5 r% d, ]7 k+ I
  333. STA PPU_CTRL- K0 L# K: F8 Z  G
  334. STA PPU_MASK
    4 K' _" Q  J& y, n% G% D7 ^4 v
  335. STA PPU_STATUS
    , R6 q" `1 p, ~! L4 a* p9 T
  336. STA JOY2_FRAME
    ; k6 L4 i( F0 A) z/ C
  337. STA APU_STATUS% @' g3 ]" K1 y. e  k

  338. . t/ w$ Z% X* Y6 `1 U3 h
  339. LDA #$C0$ P8 U0 w% s. l/ N+ g/ V
  340. STA JOY2_FRAME
    8 R) y; ?8 v! c: K. u% F+ Y

  341. 2 ^/ X% [; c9 [0 q5 R& H# m, T# }7 H
  342. ;等待vblank
    9 [5 E6 D6 [& {. F, N- N4 W8 E. b4 A
  343. LDX #$02
      d+ m- C# C/ Y1 b7 R
  344. Vblank_Wait_1
    ( p. q: q+ g  d! w0 p  Z7 Y
  345. BIT PPU_STATUS& x. q4 B) e8 }) f* q
  346. BPL Vblank_Wait_1
    , T" j3 f5 [4 p- t3 o
  347. Vblank_Wait_2  E8 f% F3 [) c7 I0 e$ z; r" H! j
  348. BIT PPU_STATUS
    8 [; [4 h/ T) c& H% U/ B9 w
  349. BMI Vblank_Wait_2
    # C- @4 D$ T& w7 Y
  350. DEX
    / s/ }, n0 g8 g3 J) W4 U! ?
  351. BNE Vblank_Wait_1* o# V4 P+ R- s3 u
  352. 4 K, e$ G& v6 A- _$ Z- w
  353. LDX #$FF6 {& Z( h7 s9 ?. j1 ^
  354. TXS
    , }$ n, v; V8 h3 q+ f9 u

  355. 0 z$ k# a+ {( ^$ [4 F) i
  356. ;初始化MAPPER19/ i$ h* o  {, l" U! ?( h, ^/ s2 ]
  357. JSR Init_Mapper193 w: r% e( m; m% j, ~
  358. 2 U9 W7 H/ M/ H# j  V
  359. ;==============================. q1 W7 \  `& A# s# S
  360. ;RAM初始化
    ' {  f# U  B1 T' M
  361. Nes_Ram_Init
    - {4 v# l" N, Z4 V" p
  362. LDY #$00/ L- S6 C4 g5 Z( P) ^
  363. LDX #$080 `! v& C) k  n+ l+ X
  364. LDA #$00
    ' W- I7 M* x! {) `5 y
  365. STA <$00
    , N' l6 O1 D) }) z6 T5 {
  366. STA <$01$ Z% z$ ^! J5 ]) {& w" J
  367. Nes_Ram_Init_Write
    7 N# Y0 }$ u% |
  368. STA [$00],Y. V- Z8 @" {8 {9 F* G4 t
  369. INY) s/ W8 Y. T9 H
  370. BNE Nes_Ram_Init_Write
    - g: N* ?: c3 J1 a) c/ x
  371. INC <$01
    ! n/ s. H' R: u& E& M8 C9 H
  372. DEX- y  h: n% V$ M2 ]6 h" A
  373. BNE Nes_Ram_Init_Write
    5 U1 x: z# G* u, k' C( A& e& z/ w

  374. 0 p% V2 \8 X3 r. x5 |  X
  375. ;初始化命名表! C3 W& I! U' ]2 W( H! g  q' L* |
  376. JSR Init_Name_Table
    ' Y! |0 @6 Y) Y7 e. s

  377. 7 a. q9 o( V. X+ n; ?' g, ?+ _6 s
  378. ;初始化调色板0 r+ e0 L* T1 X4 y, z9 [
  379. JSR Init_Palette
    & H; @+ l: j& y. K
  380.   k2 ^: v+ z0 @& S2 R
  381. ;初始化命名表属性9 A1 ^) Y. t5 b. r- m
  382. JSR Init_NameTable_Attributes
    ) m" G0 s) N& _$ a; u* C

  383. 5 ?( V; e( |1 _1 b  R3 O, `( d, P: y: ~
  384. ;初始化精灵内存
    % g/ B% W' v" M# c4 @9 {* Z
  385. JSR Init_OAM_Ram2 d' m* g* l) c) U- [: j

  386. 6 Y& p3 e- K5 M
  387. ;在屏幕上写点东西1 \8 A' V  k5 f3 C7 F0 @6 ^; n
  388. JSR Init_Name_Table_Text
    " V% Z* `/ U4 P9 H

  389. " b0 ~7 O+ g& N
  390. JSR Time_For_Vblank6 i7 L( q& c& O+ U& i/ E$ I. T
  391. ;开启PPU控制9 L7 V7 i6 `" q0 N+ f% D
  392. LDA #$A85 \# W8 U$ k: a; d( \+ Y5 j
  393. STA PPU_Ctrl_Buf9 ^7 J& W9 [" i1 I* ]9 P# ]3 p
  394. STA PPU_CTRL, F8 C/ W; u: u6 W0 F! ~, x

  395. 1 {2 l- j- v  Z9 }; ]  f+ A
  396. ;开启PPU显示% L, P2 D; ~  k/ l; m
  397. LDA #$1E
    / x+ I+ _1 h3 n; R& ?- f
  398. STA PPU_Msak_Buf
    : j. M" T0 F0 t) @/ v( `

  399. ; s5 v+ v. Z% |& Z4 J$ x6 x! d
  400. CLI
    4 z5 M, ~6 w% @6 O/ X+ J2 ~
  401. JMP Loop
    # h* ?1 M# |8 u# @2 A* R3 u

  402. ( d9 U/ e2 w- \6 K
  403. ;==============================$ g  [, Z' H; A) ^/ P9 \
  404. ;死循环, 等待NMI中断
    * _& w2 c' p  R0 V- R
  405. Loop
    ! t: i0 v/ L+ K7 j8 F+ {# F
  406. JMP Loop3 Y# M  @" k/ r! l# `8 `
  407. " v$ P5 P  {+ a8 T
  408. ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
    8 N2 v9 H* A2 o% {

  409. 1 _9 ?) g9 k( T, n
  410. ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
    , W- `! c& I5 ?& n8 p6 J
  411. BEGIN_LINE_CYCLES_START = 32768 - (4103)9 i" \9 Y; b+ T! f* t
  412. ;==================================================: u: W1 J( Z8 L& ?
  413. ;NMI中断处理
    , {3 E* M2 e/ R( m7 `7 A- C
  414. NmiProgram; T& @& M" K- L7 X0 E8 g5 |
  415. PHA
    ) }3 W6 P# C4 }6 H6 b9 X# s; M
  416. TXA- g, G- I9 i6 h( r& g& L. E
  417. PHA* Q/ g# f7 y  C$ @$ m* N) C
  418. TYA: \$ ?" W' |" ^$ d# }- k
  419. PHA$ d  W# M6 D/ f& \7 V, ?

  420. 4 ]" `- B$ u$ A) o" {* {7 J/ R' T
  421. BIT PPU_STATUS* _) ^3 _+ Z' G& }1 a8 h4 \! }
  422. % D5 i. a. e! ]% B& M
  423. LDA #$00
    ! z$ `7 x- f1 ?6 L: Q0 m; z8 k
  424. STA IRQ_Index
    7 v- E4 H3 M- E
  425. & j( M" W; u4 S  G/ C9 ^+ Q
  426. ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
    2 R5 A, I  x3 Q0 L
  427. LDA #LOW(BEGIN_LINE_CYCLES_START)  ]8 R& s* T8 G; u. J0 |
  428. STA M19_IRQ_COUNT_L
    ! A0 W: G9 P( c- f- s# V0 p6 F
  429. LDA #HIGH(BEGIN_LINE_CYCLES_START)& _  c# Z8 s( I  N# W5 e. V; U5 L3 N
  430. ORA #$80
    , ?& x: V& ^: h0 T& s
  431. STA M19_IRQ_COUNT_H/ ^3 Z2 |) {5 u1 S! d- U
  432. CLI9 G2 }# m: [# Z# A* K7 t

  433. # D$ S1 I5 W1 G- I  S/ y
  434. ;关闭PPU控制
    ( E; o6 }( l3 e2 h$ X
  435. LDA #$00
    $ }; w2 V- Z" j/ ~0 k% m! z7 Q, W
  436. STA PPU_CTRL% e( w* G8 c( G  N1 ^; F% I4 j7 a+ T

  437. , }& y) ~& i" A1 H9 G0 F5 _) ~
  438. ;处理PPU. t! ~0 y6 D2 x6 y- B
  439. JSR PPU_Process! f" {$ d4 B  e$ @/ o. S  |$ t

  440. # e; t$ F1 N) p( t
  441. ;开启PPU控制6 t' K8 E$ t3 D+ i+ T" k9 o
  442. LDA PPU_Ctrl_Buf
    # Y3 m5 H1 x) U- Y$ D
  443. STA PPU_CTRL
    2 \2 v; L" @3 c5 ]. s' I

  444. 4 J0 g3 w5 Z* |; n5 H/ H7 g
  445. ;手柄处理
    6 X& W+ u* x% n! S2 n5 Z- K
  446. JSR GamepadProcess
    9 ~' L, m. J$ G/ J. i3 m
  447. 9 S+ o7 P6 u9 Y8 N! {, d
  448. LDA #$00
    ! e- M. ^2 d% f# G
  449. STA IRQ_Index0 `3 s5 y* ^1 N+ t/ n  a
  450. 3 s7 L. W8 D' b3 [: ?
  451. PLA
    1 X$ C5 }! @: ]5 A: ?" q+ q6 C
  452. TAY
    / Q: O& y2 f) U0 a3 ]4 B& }9 u  X
  453. PLA
    8 t8 A4 z% {3 ~$ a+ z8 ^
  454. TAX
    " F" x. [6 o# b" x4 J! |3 R
  455. PLA
    , x: ]8 s4 b6 C4 u
  456. RTI/ p" K& ^7 c5 h$ [" c  A1 x

  457. ( }6 ]. ^! \. H! @# t* C, v7 k
  458. ;每行扫描线113.67
    / e  A$ u! A  n" B8 Y
  459. ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
    0 }& J2 f9 E; w/ [$ ~. _
  460. BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7' a8 q2 a  _- V, B! W. Y
  461. ;==================================================6 W, m: N) |4 t
  462. ;IRQ中断处理( a# f* e: h/ {& i; h
  463. IrqProgram/ K; T; v3 s# }, z4 x$ B- ?
  464. PHA
    8 k5 i' `- K- f, A3 |5 S
  465. TXA/ {* L) i0 @) b- H
  466. PHA
    3 e1 E! k# A9 ?4 v# c% Q% X5 j6 d* K
  467. TYA+ X" h% P1 _" ]8 T. ^; U
  468. PHA/ X7 Q$ J. ]5 W% e, y

  469. 5 `' G# d$ @8 P
  470. ;16条扫描线后触发IRQ. o2 m  d, Y' `8 [4 n9 ~
  471. LDA #LOW(BEGIN_LINE_CYCLES)
    / p0 @+ J$ E9 E: O
  472. STA M19_IRQ_COUNT_L
    0 i( t* c& a" F6 `3 C/ f
  473. LDA #HIGH(BEGIN_LINE_CYCLES)! ^) F& _+ \* X4 t
  474. ORA #$80
    0 D" @( W# p( h7 Z, `. Z
  475. STA M19_IRQ_COUNT_H
    " Y& L) q1 E  H! `

  476. " z& v: H7 X. C$ A, U
  477. LDA <IRQ_Index0 [! `: v; o& ?  z5 b2 C( q
  478. BNE * + 4
    1 k4 Y8 X$ C3 c- o, F$ I
  479. INC <PPU_Scroll_H( l8 @7 @$ R3 G" h: K3 H

  480. - ]$ R* |" x; q/ [
  481. ;设置屏幕滚动
    5 Z8 m. {; C7 T' u! G
  482. LDA <IRQ_Index
    # T7 }. r  s2 {: {; I4 f3 p( t
  483. AND #$01
    : z0 y$ b0 v0 t3 c# P
  484. BEQ Irq_Scroll_Right
    - x5 T8 x" L7 E7 Q4 S3 }2 T

  485. % c! e9 a1 X9 O
  486. Irq_Scroll_Left& G- o# I4 Z" N$ S" b
  487. BIT PPU_STATUS: e6 S5 ~; ~$ H7 _% q. T1 D) X+ K
  488. LDA <PPU_Scroll_H9 K$ V! b8 r! C9 O% l
  489. STA PPU_SCROLL
    . W9 j7 V1 f# o4 s" S/ \6 ?: K$ [
  490. STA PPU_SCROLL. {* V# e& x# q6 e' g
  491. JMP Irq_Scroll_Over& M8 n5 m# _4 K4 R  a9 b, C9 J
  492. 5 e1 `7 N9 i% x7 t
  493. Irq_Scroll_Right7 q: p! u5 e/ y/ r0 I! J  }2 u
  494. SEC
    ' z+ e7 s( R9 L! C, e
  495. SBC <PPU_Scroll_H$ ]1 u3 M, D0 }2 s+ b: F2 h9 A; e
  496. STA PPU_SCROLL1 [1 G. D6 X! ~' ^2 u
  497. STA PPU_SCROLL
    4 W! f$ ~$ X4 H! K" x
  498. Irq_Scroll_Over5 ~+ M8 d) X4 F9 @1 b; D; P

  499. ( G7 G& Z) f/ f9 C1 E
  500. INC <IRQ_Index
    9 m' y! q* ~* l) z( i/ o. U

  501. # p* h( J$ h+ _% F4 m! y' k, g) S$ s
  502. LDA <IRQ_Index$ j7 Y$ W/ F! p" R9 Q
  503. CMP #14
    0 G6 _4 U( P0 A/ z- S! e5 j8 S/ q0 k
  504. BCC * + 10' ?) j! f! l2 H0 G0 L
  505. LDA #$00, u% ~) r' @6 b! @6 K, H! g( {+ q
  506. STA M19_IRQ_COUNT_L
    - H) n( l; R; M. V4 d2 U8 h; Z' [6 [7 n% l
  507. STA M19_IRQ_COUNT_H; c; J( ?$ m2 _
  508.   l! S5 |) O0 m& B
  509. IrqProgramEnd
    * t# x4 a6 G( o9 q2 I+ _4 I' p
  510. PLA* \3 ]& T) ]  }# T7 ^
  511. TAY
    ' `; `  ^0 f* M5 J8 H3 T+ _$ d0 Z. y
  512. PLA
    / J) ~/ D' _% L) T6 D
  513. TAX
    6 p- g7 X1 I/ F8 J# T
  514. PLA1 u; r! x' M0 A* n% Y) S; X6 ?
  515. RTI
    ! i3 ?# p$ t5 }$ a$ O5 g

  516.   j3 S# o1 |* S7 t9 g! f, I" Z
  517. ;==================================================
    , i9 H( R1 x9 k! r
  518. ;中断表
    ) }, _! H  F- N, I0 z
  519. .ORG $FFFA
    9 |/ f* M8 t9 `, e
  520. .WORD NmiProgram4 \' S* o* x- {$ z4 z& w
  521. .WORD ResetProgram
    9 _+ e9 F6 @( q$ v, p( W" H
  522. .WORD IrqProgram
复制代码
' |$ E$ g$ Z7 M6 R; \6 A5 w6 x& y

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2025-1-20 07:20 , Processed in 1.083985 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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