|
- ;[FC][Mapper19 IRQ], t O% i( z0 B( R+ O4 ] `
- ;FlameCyclone 20230710! e# {! ?2 w, d5 G# s
- ' o4 f1 X* x( N6 v# b% e
- ;文件头
6 A( Z: E) W) Q7 c - ;======================================================================
% i/ O6 Y4 Y% _# w) X# u - .INESPRG 4 ;16KB PRG 数量
% O- A$ a7 t# e6 S: W, P, R: U - .INESCHR 1 ;8KB CHR 数量
1 H7 O+ z; B! H. m6 m( r - .INESMAP 19 ;mapper 19
3 p4 w" s8 D' i9 P/ r' S+ p) G7 U) V - .INESMIR 1 ;命名表镜像 0水平 1垂直
1 b- a7 S r8 k4 m
5 H* Y) H0 \2 I, {$ g' \2 C- ;必要条件4 l7 {9 ?- \0 U
- ;1.持有CHR ROM9 y; K' n* {1 [% ]8 Q! ?+ O
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10002 n9 N; |3 G1 V6 h$ E1 O
- ;3.精灵内存(OAM)不为空6 m/ E& I/ f' {9 s
) ~8 E) U! S+ m1 R# c- ;==================================================% \* t' B5 j. i) E7 n \
- ;NES端口常量
+ n& ?$ u' Q+ j3 S - PPU_CTRL = $2000 ;PPU控制寄存器
. `% B1 c3 K7 K$ D9 f0 B# u - PPU_MASK = $2001 ;PPU掩码寄存器6 O6 ?# p; `- g. d' x0 X$ f
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位& r, d6 d" O8 O- C0 H `
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加15 C2 S9 Y, C/ A
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1 u) R5 T- Z. I2 T) Q4 [
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
/ `; Q6 V/ Q. C% m4 ?& n8 u" o - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
' V S! P: S- N; t; _# [ - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 4 {8 g: H7 c( [, d p
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
( s. K% N/ z7 }2 ^0 J - APU_STATUS = $4015 ;声音通道切换
b5 i$ Q: E/ v& l+ e% S* P - JOY1_FRAME = $4016 ;手柄1 + 选通
9 ^+ d i# U1 H$ r6 K - JOY2_FRAME = $4017 ;手柄2 + 选通
: ~) H, T" P' ^
, ?/ c. v8 y+ Z& u# u4 K2 F; S- ;==================================================( B6 p o7 G! V( t/ u# I
- ;MAPPER 19端口常量
+ j6 W/ a/ c6 V - M19_CHR_0000 = $8000
& Y$ _' ?6 O( F( T+ b! @ - M19_CHR_0400 = $8800) D- F9 ^( V1 ~9 o
- M19_CHR_0800 = $9000
- h: o3 ]9 W8 g8 [ - M19_CHR_0C00 = $9800
7 L3 B. \0 [3 ?5 T - M19_CHR_1000 = $A0001 }; b! O) H9 P
- M19_CHR_1400 = $A800
( k% G6 q; n3 { - M19_CHR_1800 = $B000
% Z1 m, j! w/ I0 @% a - M19_CHR_1C00 = $B8007 a. t4 p% R. [* S1 }" O
- M19_NT_2000 = $C000/ C# J0 O# {. |, g+ U5 S) Q1 y% d
- M19_NT_2400 = $C800
/ q J8 x% ?) l( R2 |) N- v - M19_NT_2800 = $D000
, l5 A, \) C& s* t" Z& v - M19_NT_2C00 = $D800
6 W. R+ o5 T# ?2 T - M19_PRG_8000 = $E000
9 K$ H6 `0 y4 O' J, h6 \% t8 g f - M19_PRG_A000 = $E800) L5 p7 `, c+ Q& R D4 X, X% X
- M19_PRG_C000 = $F000; `" f) U# ]% a+ q0 M/ n9 Z
- M19_IRQ_COUNT_L = $5000
$ z$ c* y8 S$ i& F; m. X# v - M19_IRQ_COUNT_H = $5800
" N( e/ O- D" H# g1 D& Y
- F/ @; a: c: c# w9 v- ;==================================================5 Z N9 Y( F- W" b
- ;程序块配置
& e$ r3 l) [( S% A& W9 C$ |. x9 z - BANK_DATA_MASK = $07 w' ]; N' t# i: c9 Q
- ;--------------------------------------------------; l3 ]. {+ x* D' g% B/ e
- RESET_BANK = $071 u. i# z2 H9 M1 ~4 @% w0 ^
- RESET_ADDR = $FC003 k+ G% R" R I- f# U2 u2 y" V. I
- ; V* Z M: y2 b0 v1 e8 s
- ;==================================================) O" w* X1 [# Q6 { ~2 v
- ;图像块配置
8 l/ _; K' O, }0 Q! @7 _9 t: n - CHR_DATA_BANK = $08
* g1 K0 s5 G" N( B' I& F - ; G( ^& Z) R% d, ?
- ;==================================================; a+ Y+ U7 [& T! ]
- ;零页内存地址配置$ G% n7 l8 u: u* n4 W' w1 E
- Use_Ram_Addr = $80' C4 U$ W ^, \9 X1 e1 s8 M
- PPU_Ctrl_Buf = Use_Ram_Addr
3 T, Z$ a' a+ Z5 F a8 ?. E - PPU_Msak_Buf = PPU_Ctrl_Buf + $01- G3 e- y6 g. z$ p
- PPU_Scroll_H = PPU_Msak_Buf + $01) p. ?: \( m. W$ J' ]7 P6 c
- PPU_Scroll_V = PPU_Scroll_H + $010 _3 p; \* W/ ?
- FC_Data_L = PPU_Scroll_V + $01
5 s( R$ Z$ r: p) T/ U" g - FC_Data_H = FC_Data_L + $01
! l- g+ A p( r8 n# W - FC_Data_Buf = FC_Data_H + $01; d$ I6 ~1 ~- M8 s% ^% f+ S6 |
- ;==================================================8 \/ p4 |% I2 n) D) k5 J4 | J
- : c. ^) n3 x* f7 L. t& i
- GAMEPAD_MERGE_FLAG = $04
% r/ A( b' Q6 {* n! Y6 R# K
2 v& t8 Q$ r3 n* ?# S! ^& i- Gamepad_Keep = FC_Data_Buf + 1
! Y( f# T' l: ~ - Gamepad_Once = Gamepad_Keep + 2
# N3 n; a5 e' F# l. q9 P) G, d* z - Gamepad_Temp = Gamepad_Once + 2( y! D; f$ N9 ^" X/ _
- - g( |$ v+ n# c& }
- Gamepad_0_State = Gamepad_Temp + 2) a/ k9 z1 \9 A' t- j {; O
- Gamepad_1_State = Gamepad_0_State + 10 R4 H' R1 Q8 P; k
- Gamepad_0_Value = Gamepad_1_State + 1
0 h" W9 z) N( y - Gamepad_1_Value = Gamepad_0_Value + 1( Q% T D, X! H/ w, B
- Gamepad_Port_Value = Gamepad_1_Value + 1
# c A8 k$ ^! ^( X8 V: G - Gamepad_Merge = Gamepad_Port_Value + 1
m" I1 p4 ]! L$ n8 ? - 4 h* N' F" k/ r: Y8 ?9 F0 Q0 y
- ;==================================================6 G3 x& |/ }3 [' N
- IRQ_Index = Gamepad_Merge + $01
2 k6 m- W$ X* s - ;==================================================6 M) i1 ^; W% y! o: z! N! G) N A2 o
( p" N1 j' B1 S- ~+ k- ;CHR图形数据
- n2 \: Z5 |* Q% m1 V s/ f( u' | - ;==================================================
- b* i+ E* d' u- Q) c& k" [ - .BANK CHR_DATA_BANK
6 k, k$ S6 p, y+ b' Y# c" h - .INCBIN "chr_bank/chr_data.chr"
. Q; ^: s! K$ J) Z6 v6 ~ - , v! `+ ]6 _6 V2 B& R: T
- .BANK RESET_BANK & BANK_DATA_MASK9 g) F g. H2 ^& y3 P/ {; I& Z
- .ORG RESET_ADDR
' Y# v6 A3 C) E z% f2 N, ^0 o6 s -
6 h; l2 K5 e: h3 x; _ - ;--------------------------------------------------; w6 Y; M. W) l8 u+ }( |0 g/ _
- Attributes_Data
2 F$ `0 U- J- y# i/ _ - ;命名表属性
, k# B/ w2 [/ D, w: v% K3 F+ B4 O - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
, U4 C9 b3 l+ L+ } - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
$ S# B5 I. D) h5 H* p) u/ a! ?0 P - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
5 g9 i, y: C# z6 |3 ` - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
^: G4 ^2 l: l1 z* z, ? - ;--------------------------------------------------
( ?4 o6 T% ` \# h: Z* U - ;调色板数据
8 v5 c& ?& B1 N& N4 R - Palette_Data- }9 ~- g& `" G" d+ ]
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
$ V3 t9 T2 O/ K$ ` - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 H& C5 f, I6 t2 B8 `( N9 F8 T
) R! a. z! j3 I& P- ;==================================================7 t& a9 R, H: |2 \- R* N* D( T: _1 ]
- ;命名表初始化* }# L$ l$ x) V
- Init_Name_Table( ?* N3 w9 k5 ~6 w' G4 P
- LDA #$20# d1 J' K: K+ \4 P6 w. w1 ^
- STA PPU_ADDRESS
( e% h9 q/ R7 V1 w7 q5 J - LDA #$00# Z/ c' G( P3 c# X" z
- STA PPU_ADDRESS
, B* h0 U7 q, b" j: w- z$ e6 N4 C - LDA #$00
) e$ u5 ^0 A8 | E; R - LDY #$00- B. ]2 h) i; K4 T8 {4 n
- LDX #$10
* x3 e1 j0 @. t) o, H: X - Init_Name_Table_Write
' @! c) f7 ]! V& k) H( x - STA PPU_DATA) i( I5 v1 k% r6 T7 q$ `, |
- INY
' B" r @# k! V( \' q4 s - BNE Init_Name_Table_Write
: A% v2 v% k# ] - DEX) ^& d. p9 r6 q0 O2 H. _0 S
- BNE Init_Name_Table_Write
- U# H' _- Z1 B1 M9 {0 X% Y - RTS
4 J. `' m- z- a. { - 4 j9 b/ k8 A) }* M5 ? r
- ;==================================================
4 F1 K9 g2 C9 K; W3 p6 ` - ;调色板初始化
) `) D5 l5 ^1 O9 H1 K - Init_Palette
' t* t1 x8 J- C2 _8 T3 y- O; G - BIT PPU_STATUS
6 n- h8 D2 s; ~$ Q5 b- e* I4 t& O! M - LDA #$3F
2 c F' J( m1 D, ~; b& r - STA PPU_ADDRESS
' G' v+ l( @% d2 ~2 f8 t6 `0 q- _ - LDA #$00. s' n$ z) b+ ^5 L9 q; W- r2 b
- STA PPU_ADDRESS
/ t% X- p! J; e5 f Y - LDX #$00
[3 }6 z5 Z) R, C - Init_Palette_Write8 L3 h, m! @! g6 H) l
- LDA Palette_Data,X
- d1 D# W+ d. f( a+ k% L$ {, u - STA PPU_DATA' a6 z" V3 T" d( C, ^
- INX0 f9 I3 ~9 j' \; R
- CPX #$20
4 b( S0 L x# g - BCC Init_Palette_Write
& ~- H7 }5 s) r3 |; Y8 u - RTS% K$ s3 X" k7 q6 B4 w6 D; S
- 0 M) T. [1 k( F8 P7 R9 A, O$ X
- ;==================================================0 O' _5 x& E; g
- ;设置命名表属性: {, L) s3 Z1 o/ Y3 o5 j; ^
- Init_NameTable_Attributes
5 n/ W2 P3 J1 j1 b M% I x+ p - BIT PPU_STATUS8 `! ], s6 u& }' A' Y
- LDA #$23
5 w9 k6 O: k2 i7 |' ~$ c' P - STA PPU_ADDRESS
0 s- W1 O# J3 Z" @ - LDA #$C09 H1 n7 |+ c/ A% i3 i. [& \5 ?
- STA PPU_ADDRESS9 G1 x: U: u7 t; Z; H
- LDX #$00) P0 j6 n! d4 `
- Init_NameTable_Attributes_Write- [+ g" d5 i- K! \/ L4 I- p& \
- LDA Attributes_Data,X
z9 Q8 W: | D' Z+ @9 C) f. n - STA PPU_DATA
6 J3 Y# s' M% M; Q" _ - INX
3 m# R0 M5 T. U, k8 }9 i$ g - CPX #$40
5 m' _7 A& {+ j - BCC Init_NameTable_Attributes_Write
- U5 K8 ?% n6 Y' p& o9 Z$ u - RTS
) x" F T9 i, [& n" i
9 P+ W0 T7 ] G9 T+ h4 j- ;==================================================
& Q# Q B/ H2 m! r - ;初始化命名表文本
: h0 t& p$ M; p. \+ c6 t" p) k - Init_Name_Table_Text
- r* T* {* _4 p2 s( { - BIT PPU_STATUS/ P9 `9 H3 }; y
- LDA #$20- B2 ~0 }3 G1 E4 f/ t4 U
- STA PPU_ADDRESS
4 J3 Y- F7 r$ {7 \' B* F - LDA #$00
0 [5 V" `( M9 y7 R) q1 ?# v4 I9 k - STA PPU_ADDRESS
& s* t4 Y/ t0 ^. \ - LDA #$007 z( m7 m: y( W& @
- STA FC_Data_Buf
: c4 y9 P* L9 U" ] - LDY #30
D+ T) [. ^4 t# O) D( v - Init_Name_Table_Text_Write
5 F, f o8 ^# a - LDX #32$ ^7 M+ h9 Q1 u. c3 h0 L
- Init_Name_Table_Text_Write_Char
2 r+ Z3 n* q5 [8 c) b - LDA #'0'& S' R8 ^0 _" W. [! r
- CLC; D1 V$ Y/ Z; c* k, ?% ^/ |
- ADC FC_Data_Buf
/ d( j: \* V6 Z {8 @; l6 N - STA PPU_DATA5 I3 B2 p- \1 r" c# x+ {/ U
- DEX3 h3 T# `7 ?: \, ?, f& h! n
- LDA #$14; U, {# A, H; Y: _) _
- STA PPU_DATA Z# n6 v# J7 D% A: w7 {
- DEX
1 _6 u' M' S1 X( [ - BNE Init_Name_Table_Text_Write_Char
1 v2 T. e7 A3 f: w5 ~/ S - INC FC_Data_Buf
/ ]: K* l" A& i% f5 F - DEY
* o) a9 o/ y" w8 | - BNE Init_Name_Table_Text_Write5 @, |' z1 V+ f0 o; Z. I
- RTS
9 V8 C- @" k" O; x3 v
0 @5 U% P% |" S0 L5 F: X% v8 q- ;==============================
9 d: L" Q* Q$ s7 p. Y7 E - Init_OAM_Ram;初始化精灵内存
8 t6 d1 r! f5 b+ S0 A2 E0 H - LDX #$00
! h- A7 K, C& o5 Y - LDA #$00
( p( V' U( Z7 A \7 r) C - STA PPU_OAM_ADDR
7 T7 J; a- c2 L" Q - LDA #$F8/ V! r6 L8 ]+ o( k
- Init_OAM_Ram_Write; E& R$ w; d2 t1 Z: L+ V& z( l
- STA PPU_OAM_DATA# R# }& F- ]; D4 o% i8 d) e* t; t
- INX
1 O% W- b2 X0 e" J/ U" B - BNE Init_OAM_Ram_Write& {5 a# q8 I! R
- RTS* k: u& a5 Y4 n8 c4 G+ V! g7 e
- 2 Z5 P' R0 W- t5 h3 v% V# B5 O& f
- GamepadProcess;手柄处理8 {6 c( [0 j# D. u0 p8 l6 p
- JSR GamepadDatacan$ P3 h; [5 n* E7 w8 G/ j% {- [7 F
- LDA <Gamepad_0_Value
3 Z7 R, i* R. E - STA <Gamepad_0_State, H0 @. i+ I4 k8 i/ W0 n" X' d( y% a
- LDA <Gamepad_1_Value3 w1 P: Z, U/ Y1 F7 }
- STA <Gamepad_1_State
2 ^! A' Z5 M7 u - JSR GamepadDatacan* `! n% _- M! D' f# Z7 T/ U# z
- LDX #$01
5 T' s4 \# T X( a2 O. b - GamepadMergeCheck;合并手柄输入检查* t( u$ [ R2 ^: C4 c: k% k
- LDA <Gamepad_0_Value,X
/ r9 p, |2 w: f# O) P9 f% w - CMP <Gamepad_0_State,X" @" t, t2 o8 ~$ a$ b1 c* j% `1 A
- BEQ GamepadMergeInput9 k- P0 v' K) ?
- LDA <Gamepad_Temp,X' e" N& b/ d& J; J. P* k G" ~0 z3 Z
- STA <Gamepad_0_Value,X
9 u- h+ l/ A# I& z) s2 W5 Y - GamepadMergeInput;合并手柄输入! S; b) p/ k. p J; Z
- DEX2 _+ {/ A( d0 Q# K7 F ^5 c4 E9 g
- BPL GamepadMergeCheck
+ Q O8 V F7 H% Y4 w/ @. R - LDA <Gamepad_Merge; R% S( }; X" X0 u
- AND #GAMEPAD_MERGE_FLAG8 Y6 _) \4 G/ u% F. I. a+ R) M, i
- BNE GamepadStateProcess
# I- c3 _- f2 d- d Y4 z" i1 r5 h - LDA <Gamepad_0_Value
~+ x& y, a' Y2 w. \ - ORA <Gamepad_1_Value* R7 p" f3 o9 Q# W2 ~
- STA <Gamepad_0_Value! q4 g0 d" Q$ H4 {: ~+ j6 _8 a
- GamepadStateProcess;手柄状态处理: }6 e6 o' r- @8 O6 E
- LDX #$01
! ^* m1 T' B; [. \ - GamepadStateSave;手柄状态保存
5 {7 j- h! b6 x! x- z7 H- @( { - LDA <Gamepad_0_Value,X
" `4 ?- X! z/ M! N5 Y3 U: Z - TAY
9 Q+ d% ^5 W. b; A( k) w$ l6 d - EOR <Gamepad_Temp,X d/ P% X; c8 x/ N0 y- a/ X7 ?
- AND <Gamepad_0_Value,X4 D7 s5 u, l @8 d( ]/ C" N
- STA <Gamepad_Once,X4 j, J* D, w1 ? i6 B! y7 n$ n
- STY <Gamepad_Keep,X
: z6 r8 ], Y" [ - STY <Gamepad_Temp,X* u% e+ Z; f7 U+ S- X
- DEX$ S( m- h3 ~8 V8 }! X: H
- BPL GamepadStateSave
3 q9 |" m7 {$ s6 `( R* A2 @ - RTS1 L# g4 b& q3 Y5 y
- / G0 A& X) N; V
- GamepadDatacan;手柄数据扫描* g. P7 }7 I2 m! E/ V1 k
- LDX #$01
p5 Q+ \5 R; x* b6 A+ g - STX $4016
3 Z: f2 {" A% X0 U" @/ z - DEX) @0 c1 n) c' x- q( {
- STX $4016
: a, l, {9 x8 ?+ e5 c - LDY #$08
9 e3 g2 }1 n4 l, K- i. b - GamepadPortScan;手柄端口扫描
$ c1 q/ v2 O9 \) k( V - LDA $4016( ?7 | E" H3 O' ~' U* g
- STA <Gamepad_Port_Value
% \# w6 P9 A# P) z3 E& |* w - LSR A
6 t- [" E. n6 U s; M& r - ORA <Gamepad_Port_Value
1 Q/ Q3 R) s8 o6 \4 S- w - LSR A4 u6 ^ p+ @, ^# O1 b0 ]- E. [( E
- ROL <Gamepad_0_Value, i$ Z7 y$ u. T5 a# y0 Y, L
- LDA $4017
5 o1 ^8 A- d1 C - STA <Gamepad_Port_Value
0 x6 E7 J3 K9 g- w - LSR A8 O& L$ [# r7 K# ~, W
- ORA <Gamepad_Port_Value1 B, }& v: q0 r4 |4 g/ U; c2 R8 U- d% [6 J
- LSR A# J) d- I4 |+ p7 X0 Y# S
- ROL <Gamepad_1_Value
" N* h7 u( f9 U0 }# u - DEY
- E. R$ M7 H$ B; P4 R9 C8 r - BNE GamepadPortScan
4 _. j! |8 h+ l8 t- J. F - RTS* W$ m/ |3 }/ r
- 9 H3 r0 ~& u' q% B$ p% A3 `
- ;==================================================/ W8 @, r8 L7 `5 {/ w" L9 W" a
- ;PPU处理
1 n) ^! V: a% t4 T1 y - PPU_Process
( T$ d4 a: ^; Z4 @2 Q% \3 ]3 f - LDA #$00+ ?0 N; c3 C+ h3 U- L! ?- f
- STA PPU_MASK
& I) t% W# a' ~: ^& E" ~ - 3 Z! {9 |! A1 q) F
- BIT PPU_STATUS: s a b; u3 l! N4 I# l
- LDA #$20
: Q! r& H, m7 C# O% W8 u - STA PPU_ADDRESS. B% q+ i2 \' r0 D! m, Z i
- LDA #$009 a2 W1 u7 q }7 [: c0 j
- STA PPU_ADDRESS
5 K9 X0 |& J7 @) ^ -
4 h% X0 y" T+ Y0 A4 O, w - STA PPU_SCROLL9 B$ y3 M. @. a- T+ z
- STA PPU_SCROLL
3 H1 M) S; C+ Y7 n: P' y6 }1 O -
1 X/ n* P+ z0 L - LDA PPU_Msak_Buf7 W3 s/ T2 D5 f3 l
- STA PPU_MASK; w) J; K& L( O$ `/ H: A
. S' s3 K" s7 L- RTS( i G; U! S( Z- T! Y( i% T% l
- : z1 ?$ n9 y5 F
- ;==============================) b1 u8 B' f! |' j# T
- Time_For_Vblank;延时等待6 W& M5 A0 c" g: i% H* g3 _
- LDA PPU_STATUS
- x9 o- r" E0 u7 F - BPL Time_For_Vblank) n2 s2 G' s. e" M& C- I
- RTS$ o+ d% R4 B% H2 D6 J: }
-
( h; O4 b# [" P) _( J2 B" q9 J - ;==============================* j5 e7 L7 @ W6 R9 ]- T& ?: q; C
- ;初始化MAPPER19
9 p4 ~5 v1 I- ?$ \ - Init_Mapper19
) r7 ~5 Q _0 h+ c% c8 ^ - LDA #$008 Q; g- o w7 l
- STA M19_CHR_0000( d2 `- |6 g3 s+ G. M) s$ a p& h
- LDA #$01
& }" O g/ \! R8 m1 G7 V2 c - STA M19_CHR_0400) f, i* }7 \6 n2 S) I, U F& d
- LDA #$025 ]; c$ b9 B7 F% v$ F
- STA M19_CHR_0800
( x8 z& B! z2 } - LDA #$038 t; R% ~* q! m3 i6 h6 R
- STA M19_CHR_0C00
: b6 m% ]: X2 p: X - LDA #$04
0 F( v/ i8 z; z0 `; f - STA M19_CHR_10005 n2 b: x* F2 G4 s$ B0 G
- LDA #$05
7 y' [7 D$ D7 }6 c# `6 z V - STA M19_CHR_1400
8 B9 s. F' y6 D6 H - LDA #$068 Q* L- {! i$ M: T2 ]
- STA M19_CHR_1800+ X# } a# j; B/ e; @- K
- LDA #$07' M+ m- \0 E' w4 M1 ]/ n
- STA M19_CHR_1C00
' i/ |& a9 n4 g! `+ V - ' v1 T( s) K1 F4 D3 e9 U
- ;禁用IRQ: X$ u" y' _# J! y
- LDA M19_IRQ_COUNT_H
9 l M- U2 [ l" R - AND #$7F
2 ?0 @. q2 q; ?3 Q& i - STA M19_IRQ_COUNT_H' r. _8 R% W( C: ~2 k# B
-
; p! Y, D, A& s0 H' t0 m7 R1 I! ^ - ;命名表; a6 `3 o( |; x5 F
- LDA #$E0* ^0 Y( j: ~- H* }+ N3 q
- STA M19_NT_20005 J+ T3 G8 g0 D3 T6 Q' B) o" x
- STA M19_NT_2400$ I+ K3 m' u) i
-
* p0 N3 w3 B1 s - ;命名表
7 q( l m1 i! t- {3 P5 k7 i - LDA #$E1# l( |9 F, I- Q7 \ T, C
- STA M19_NT_2800. j) _ t1 M6 r R2 Z! T' ?2 g
- STA M19_NT_2C00
) m7 q9 S" y% D' F: s2 {% @, ] -
# V* @# R. J5 } - RTS- |9 a. ^, @( M* n4 O
- ( G# V' d; }4 i9 L7 T1 {8 s
- ;==================================================, [9 x6 m- d) K. r) e! x+ V- Y; x
- ;重置中断处理
. @* A) d: y. D7 \, l; f \6 ]2 S: U - ResetProgram, K. L" D% s) v7 W) I
- SEI
: y2 E9 X L- Y& K - CLD" X4 Q& }+ D& x. X
- LDA #$00
& T2 m* m, _! V, H1 O2 t: p' `# s - STA PPU_CTRL
! B# T/ E7 l/ `0 `/ _ - STA PPU_MASK
8 L- R7 S1 a( l, L; g! g" e - STA PPU_STATUS& i5 Q7 \4 h5 N( h" X# \0 b
- STA JOY2_FRAME
7 n( E/ ~8 B* S% k2 a - STA APU_STATUS* g0 G9 ~# s6 k3 @2 u0 R+ j
-
+ t8 n$ ^1 j9 s - LDA #$C0, I) {+ k. R% K8 {2 V
- STA JOY2_FRAME; n1 v4 v4 `+ @8 C1 c+ H
- ) |3 z- [5 v' Z5 [
- ;等待vblank: w% y- i% g0 ~8 W' a0 O
- LDX #$02) _. h4 b, \1 F' M4 ]/ }+ L
- Vblank_Wait_1
% ] O9 A4 P" q! t) S0 G" M - BIT PPU_STATUS' h- Z9 E4 T5 S- r" U/ b
- BPL Vblank_Wait_13 }0 T' g1 C) F
- Vblank_Wait_2
) @. H8 L" R) ` - BIT PPU_STATUS
' O5 v* S* F4 M - BMI Vblank_Wait_2
: Y6 u1 X. G6 W - DEX V. R5 G5 N& K% f# _
- BNE Vblank_Wait_1
+ l) x! ^+ c; Y& j4 N+ d -
% x, M9 \0 j1 {# L - LDX #$FF1 W$ B8 r( r& N3 I: t1 D9 I0 Q
- TXS/ L/ _: s* \, o; f
-
/ O i' e2 e h. H4 j: i2 \- A - ;初始化MAPPER19
; ^+ y% j, o2 g) b2 X q5 H6 q: E - JSR Init_Mapper19
# k; e9 d0 G- [4 R; R0 {; p% K1 z1 _ -
9 O+ z* k, ~% P - ;==============================
# G# H: d ~ g( g1 |) a6 n( X - ;RAM初始化
7 O; a' O8 Z3 Q" [ - Nes_Ram_Init
: L9 s1 L4 h) S - LDY #$00! U# l- s1 w+ Q- [9 I* O C
- LDX #$08& T$ p8 H1 ? T6 W+ J
- LDA #$00
1 Z6 l* k, C0 w6 k8 ]4 L: `' j/ ^$ ~ - STA <$00
9 V ~% ^1 T3 U. |4 v: H) l6 \ - STA <$01
( W8 E5 X |0 X* b1 _. W ? - Nes_Ram_Init_Write& L( }/ e% q! T1 ?- r
- STA [$00],Y- @8 V ~2 ]- v+ \& p
- INY
, L- H3 F, P+ c! a - BNE Nes_Ram_Init_Write
" r# g7 j2 N( U3 C( ?. v( q - INC <$01( L( V% v* n5 w7 V
- DEX, Y. Z9 X' o, z+ i
- BNE Nes_Ram_Init_Write
. A/ \( P$ @6 `7 X- I - & }! E$ @. H" P0 D
- ;初始化命名表8 O2 g6 e1 Y. t' K* m
- JSR Init_Name_Table; R% p. i1 B4 B, \. K
-
. f3 H5 [2 r$ _ - ;初始化调色板( o) s0 q; N( d0 F, ] Y$ Y
- JSR Init_Palette
2 I" U+ E0 M6 w8 N8 k5 L - ; S3 J8 K8 I& r- ~9 |
- ;初始化命名表属性5 i7 [2 A `+ a6 Q
- JSR Init_NameTable_Attributes
4 H' J$ z/ Q+ L$ b* n$ w! F% G -
1 V1 U6 M$ s" X9 s* e - ;初始化精灵内存
$ I7 }( ?2 {" W5 e% `' ~6 Q7 h - JSR Init_OAM_Ram
: }/ o" V# Z# B - + }/ Y2 J" R3 B
- ;在屏幕上写点东西% ]% R2 T. Y- Z4 I9 H" e
- JSR Init_Name_Table_Text0 Q( {; Z9 o5 B3 w$ s
- ! F, u8 A- N! F+ _2 f: P
- JSR Time_For_Vblank) b5 Z" ?6 J7 b* K' C0 N: i, m
- ;开启PPU控制" |! k. p1 d6 A! V: e
- LDA #$A86 }. _) c2 Y" Z
- STA PPU_Ctrl_Buf4 ]% f' L) @8 ^8 i2 i
- STA PPU_CTRL
# P5 f1 n, ?6 H; I7 L V" { - ! Q5 x& Z8 i& K
- ;开启PPU显示
2 M. { A& t$ Q1 j8 X9 j6 N. X - LDA #$1E! M: m0 B/ K; t x* N+ v, [/ M
- STA PPU_Msak_Buf8 T9 r& E. L3 Z1 g+ c; ~9 j
-
) v" [/ x8 t% z# p6 P. p8 y0 ]3 } w - CLI k% L- y: t$ k* o" K+ r4 W
- JMP Loop; l: b6 ]3 V4 {: X8 _2 J4 _
-
|& x+ j9 }- F' z1 F. B - ;==============================
% w2 k/ J, W) B' |4 _ - ;死循环, 等待NMI中断
( W C, n/ u" j- c - Loop
: j% k- _+ a5 e& H5 w: {0 b5 @ - JMP Loop
2 Z" d9 i/ r- _. ^ ?- c2 o
/ C3 A% ]5 {( f) N- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967+ b7 n0 Z: x5 D& [1 e. D3 {( I
- 2 w ], Y/ ~" ]6 L) L! }
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967); b$ X+ w1 l& t9 w
- BEGIN_LINE_CYCLES_START = 32768 - (4103)8 z- @+ ^( B, N2 W* d" F
- ;==================================================
/ o) C7 X y" @1 H6 ~ - ;NMI中断处理
! N9 Y, F! P3 Z" [ - NmiProgram: S" K5 v( C/ c' U; A
- PHA
4 j0 U& S9 t# C - TXA
0 B; J- f8 C6 f - PHA
/ p/ M' t5 a& L - TYA
$ J- n- n. A) h0 ^ - PHA
7 i/ c2 U, n0 A9 M5 w; g: _5 W -
& W7 l" L2 b" x" S - BIT PPU_STATUS
& O: {0 Y' C z( \ -
0 z' a& X/ u* k - LDA #$00
2 W" s5 n+ m0 K Y - STA IRQ_Index* f. L6 C, N; n) C
-
3 L) y# O3 m3 n9 J: F' q6 Q7 ` K - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动2 [# M+ L$ a& ^$ B u
- LDA #LOW(BEGIN_LINE_CYCLES_START)% {5 f! v8 B" M# M/ I. h
- STA M19_IRQ_COUNT_L$ V/ U+ A7 l. G; p* L
- LDA #HIGH(BEGIN_LINE_CYCLES_START)* L: w9 s9 k5 K. A1 O
- ORA #$804 V1 \. _- ?" l" s$ a' O
- STA M19_IRQ_COUNT_H
/ z4 u; I; Y5 s( ~3 S% T - CLI) v( A! z/ l# I4 G4 b
-
% U# i% U* O7 @/ o3 F) l& V7 v: y - ;关闭PPU控制
* k4 `* ?% a" r, z0 [/ r - LDA #$00$ R# h- e4 b# D5 i8 K
- STA PPU_CTRL* |" \7 \! [9 M+ s7 Q2 r
-
% H7 U4 y& { a( U: j0 f4 A* ^ - ;处理PPU
' ^ _$ I& b; z* o9 E. S7 z - JSR PPU_Process0 o! j4 ]- Z4 H3 l$ \. p& d
- ' h0 a" W( W) a `9 Q
- ;开启PPU控制$ b J2 p; k; K$ F
- LDA PPU_Ctrl_Buf8 q4 z' b" A9 \6 n" \
- STA PPU_CTRL
) ^6 a; b' L2 D -
7 u% \- Z2 I( c' k; D - ;手柄处理- O+ G" f" {" R+ {8 @1 j* L4 J
- JSR GamepadProcess
/ f# ~8 [3 u! @. \" g& `: r -
8 A/ h' ^0 f9 X' ~ - LDA #$00, p+ v; ^% U4 {: W; }( L% j4 l* z0 F, o
- STA IRQ_Index1 y) g- N6 J/ M- d, l4 k% l
-
* R* H( n0 ~* s* u2 W7 m6 b1 e, T9 P - PLA
& L$ G4 r# G+ T3 a- a( U - TAY9 W, p) i, h! Q- l, x
- PLA7 r6 p) K% H) ~! Y) F- q5 w. O
- TAX& Q5 E4 x0 }$ G7 u- H% s
- PLA: f- \: K5 e- ]3 Q& i Q
- RTI3 b6 @& B: H- c2 q
# E. P- Y0 j( P8 j( g0 h+ C7 S5 s5 p2 E- r- ;每行扫描线113.67- ?: e% ~* g& x% h) c0 r& z# o
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)( Q+ H* V, Z! b; p2 v
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
; t$ z8 ~% n/ A* U3 O: j - ;==================================================3 }( b5 d3 b' w# S5 h
- ;IRQ中断处理/ _% N9 \4 _7 _* `' f& v7 q
- IrqProgram3 h0 ]- _4 S% T3 h% d5 L+ a* B7 U( n
- PHA% v5 u$ o a7 _- K! Q. T: `% S7 u1 l
- TXA1 s; u: N! z( t @, D- @. |; D6 O
- PHA
4 I: _0 k6 F3 b! J - TYA
8 Z* L2 _1 u( O: u - PHA. O/ @8 Q9 U3 j
-
. m, l _7 y4 z# W - ;16条扫描线后触发IRQ8 c6 B7 C! k7 A! a1 M
- LDA #LOW(BEGIN_LINE_CYCLES)3 ~' {6 {; L9 ~/ h) c2 H& d+ ~
- STA M19_IRQ_COUNT_L0 x% F" w! S2 g& i
- LDA #HIGH(BEGIN_LINE_CYCLES)
0 Q4 u! x5 O) f, [' J- R9 C - ORA #$805 @7 U! }5 i6 d4 |% x5 S0 Q
- STA M19_IRQ_COUNT_H
; t( U p6 Z* m0 Z2 q& Z2 c$ a - # b" \6 q5 s- }
- LDA <IRQ_Index
n3 O; a0 \9 }4 C/ J, o - BNE * + 4
: P. R/ J% I+ ]$ N2 g - INC <PPU_Scroll_H4 I" F- G# \2 n$ O d
- 5 F0 ?3 O/ F2 r7 t/ |* R
- ;设置屏幕滚动2 K8 j4 J; x2 o. K) E" R% I7 E
- LDA <IRQ_Index
4 n# y5 v$ d/ ^' [& t - AND #$01: f; h5 y1 @; f( h# W
- BEQ Irq_Scroll_Right6 I! x: Q+ U' W/ I( n6 j
* j( I4 d6 s2 |8 G! w- Irq_Scroll_Left
8 b& r0 H7 \+ D0 ], C - BIT PPU_STATUS u) M* T) f! L0 A
- LDA <PPU_Scroll_H- }4 f$ z) Q$ q4 ]- G5 P
- STA PPU_SCROLL* u/ k8 i# K+ N- h: a4 H
- STA PPU_SCROLL
: o5 t o- _" K2 P4 v/ x - JMP Irq_Scroll_Over
% \3 {, Y3 k) f1 j' T - ! Z% {) S# N9 r F8 m
- Irq_Scroll_Right
( g& c+ W- o, p* d+ W - SEC
8 K5 ?$ Z `) Z6 X( c0 S" k - SBC <PPU_Scroll_H9 O# \7 d& o$ d8 B: {7 T: s
- STA PPU_SCROLL
* A' g2 U9 I" w+ V# f a: A' C - STA PPU_SCROLL" F" b1 |, p" D' N4 L* Z/ l
- Irq_Scroll_Over
% e% B, U* V' _$ J( Z' G - o: J9 t w3 q: o! s
- INC <IRQ_Index
: X3 f( M* b* t: Z! V* m# X0 M - " W1 { z' j$ t5 y8 [* c
- LDA <IRQ_Index5 v9 h+ S* S% V. g; S$ d9 L G) o
- CMP #14/ D% J J# c3 V I" c; F+ \
- BCC * + 108 x! D4 n; s) r4 t" I
- LDA #$00
) K! e/ d7 c9 {( r8 ^& B0 Z a - STA M19_IRQ_COUNT_L
1 I, C$ j e8 W* N: o% J8 G. x- a - STA M19_IRQ_COUNT_H/ K: w. C# r" Y7 {! Z
- 6 D+ [" B2 M2 q' o: U7 Q! C: g
- IrqProgramEnd8 K, w& D+ S9 W9 d( e
- PLA
" S0 s( I/ c% k2 I& o7 I1 } - TAY3 I8 x" r0 V. N' K9 C" ~2 f* A
- PLA
! j5 g/ ~1 e4 D: v4 i - TAX
3 y) v9 d: [! g2 i - PLA- s% n' c) \/ k( o i- e
- RTI9 |% w" N+ h! g; X9 l
-
+ r% C- A& P5 l. \8 G B - ;==================================================
. _# U/ ?, ?' |% G& R8 V - ;中断表& I! B' V& ?9 B, l# X; A- d
- .ORG $FFFA
, A. t. w/ x& U. t - .WORD NmiProgram/ [1 X! ^( G! u& y( F9 _
- .WORD ResetProgram6 p) n$ ?8 x2 J" m- V _( j. Z+ v
- .WORD IrqProgram
复制代码 # Z }2 A8 ~1 E/ S) F) a
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|