|
- ;[FC][Mapper19 IRQ]3 b4 K, L6 O8 {% G2 ` P
- ;FlameCyclone 202307109 q, [# w$ j" d6 S# ]* ?) ?" H
- 5 D+ W: ?' n/ Y% O: q/ ^0 _ @" J
- ;文件头0 {2 D, K: u) n- s# x0 E" q
- ;======================================================================9 y' O }6 R! W0 D1 d. N
- .INESPRG 4 ;16KB PRG 数量0 L5 Y( t* @3 U% D- W c
- .INESCHR 1 ;8KB CHR 数量
; ?9 A7 `5 \6 S: }. x0 y" x+ r, Y - .INESMAP 19 ;mapper 19% q6 I1 U' P6 _/ t; p2 e
- .INESMIR 1 ;命名表镜像 0水平 1垂直
4 X/ v' E/ B4 `4 a; W* S
2 j- ]2 ]& a( y- ;必要条件
( Z, H$ A" U% _$ L, V4 t( E - ;1.持有CHR ROM
2 k( p* L% n9 q0 {# j, u* m- ` - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
& e- p- l# r7 ?4 K/ a3 N0 ^2 Y - ;3.精灵内存(OAM)不为空
+ W! D# J# |# j% w# g) S( M
2 ?, S. y0 C. c' V- \( ]" L5 ^- ;==================================================" G G" \7 G4 Y! Z7 Q; i$ X
- ;NES端口常量# Z( D' H0 X6 z4 T$ F5 g3 ?; b
- PPU_CTRL = $2000 ;PPU控制寄存器
0 v6 h5 J- T9 k2 \8 l5 z* ^0 d - PPU_MASK = $2001 ;PPU掩码寄存器
" k( M( d# @0 k - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
- D- V1 @6 q9 ?4 R- U x* t0 u - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
6 m1 {" x* f& G' M - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
+ T( x8 B, b. z( V - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
1 C% K: @* C& ] - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加* j' [8 k+ B6 G, F+ p2 m
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 3 L0 J% q; Y. U( E( E
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存7 n7 G+ E# g" W* t% k, r% M: v
- APU_STATUS = $4015 ;声音通道切换' A) ^! S; ^7 ]! O9 W% r6 Q
- JOY1_FRAME = $4016 ;手柄1 + 选通- s5 e: u6 B/ h' [7 W& P+ X+ d
- JOY2_FRAME = $4017 ;手柄2 + 选通9 J8 \5 k j: H3 t* k+ D0 J
8 R' }% X+ C# a! x ^- ;==================================================1 n3 N( }- ^7 r: s8 j
- ;MAPPER 19端口常量
; e1 j' y: {. s8 P/ h& O5 ` - M19_CHR_0000 = $80003 M e( P- u Q$ v" d" v
- M19_CHR_0400 = $8800
+ ^+ x+ k) O3 @4 K H - M19_CHR_0800 = $90001 J& n k0 v% v2 J8 A% A6 M6 r
- M19_CHR_0C00 = $9800, j' ~0 `2 X, ]& M. c% C; p# p2 p$ j
- M19_CHR_1000 = $A000
' w' r! D( q/ [1 l$ Z) h - M19_CHR_1400 = $A8000 Y: v) _2 }: T# s
- M19_CHR_1800 = $B0004 w( x. s, G6 ~
- M19_CHR_1C00 = $B800
' X, M( C: t! `, p' N - M19_NT_2000 = $C0004 H- w% S! k2 P. ?* Z0 A- s
- M19_NT_2400 = $C8008 @2 q' ^: ]/ C0 b; ^$ y( {
- M19_NT_2800 = $D000' N% M6 l% ~" S @( @6 }% D3 B. p
- M19_NT_2C00 = $D8007 o l4 B) f) U, @7 |8 e! L0 }4 g
- M19_PRG_8000 = $E0008 V. U, S. t* l7 D
- M19_PRG_A000 = $E800
% i2 b8 r3 x2 f3 F8 A: \; c5 E4 ] - M19_PRG_C000 = $F000
: i/ s. @* }7 s4 J( g - M19_IRQ_COUNT_L = $5000: o) s9 h& F8 h" |. o# W' v
- M19_IRQ_COUNT_H = $5800) s4 J1 Y: @* N: C
- X+ u/ u6 [1 v& x
- ;==================================================
0 o1 O0 R9 Q# j' t$ d8 }$ v0 H% O - ;程序块配置
% B+ ?( @* U& H) I - BANK_DATA_MASK = $07: D* h3 m8 k# W2 p
- ;--------------------------------------------------* o+ \ R8 o2 P& [' `3 r" k- {% s1 n1 G
- RESET_BANK = $07
7 l* _ p/ [, A7 J - RESET_ADDR = $FC005 V5 B! K6 d9 n9 i7 F, P
- {7 b3 p. I: d' l: I- ;==================================================
' v1 ~& L6 i) O - ;图像块配置! r& Z' R/ s9 L# x
- CHR_DATA_BANK = $08
4 Q5 v$ k9 M- c8 T: y" u - + G+ n. }+ D" M) T! e: H9 P4 B
- ;==================================================
3 n' P/ o+ X! ?7 _3 k2 z# p' X - ;零页内存地址配置
1 x/ S0 s" p" _. G - Use_Ram_Addr = $80, A& ]8 h: ?# J
- PPU_Ctrl_Buf = Use_Ram_Addr1 k: M% T* Q7 [+ D5 M9 }
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
) z; {2 t; J; i, X H7 h2 e - PPU_Scroll_H = PPU_Msak_Buf + $014 I) h0 C/ H2 {3 ]# w6 U
- PPU_Scroll_V = PPU_Scroll_H + $01
- {* V$ p$ |9 W2 Z! _& u1 |" F: H - FC_Data_L = PPU_Scroll_V + $01
8 q. n6 a$ D7 l# d0 m - FC_Data_H = FC_Data_L + $015 t1 k% D, L9 ? I
- FC_Data_Buf = FC_Data_H + $01* p. v7 n+ Y9 {' { M5 k: ]( z' |5 r
- ;==================================================
+ `0 K, q3 g8 H2 F: o0 ]) K4 H - ( |/ z4 H7 f% k/ m+ e. r
- GAMEPAD_MERGE_FLAG = $04/ O N' c9 z% A6 P" j9 w* V) O# I
- - O4 B$ Q; P$ B! Q% [
- Gamepad_Keep = FC_Data_Buf + 11 x6 g! E! J& O
- Gamepad_Once = Gamepad_Keep + 2
' E0 s) {7 s" g% @0 X* | - Gamepad_Temp = Gamepad_Once + 2" L3 U% N, F: a c: f5 c
-
* f' ]) t! ]. |( U4 G" p - Gamepad_0_State = Gamepad_Temp + 2" j5 b4 ]& G0 S
- Gamepad_1_State = Gamepad_0_State + 1
# L. ]6 s6 a6 s' i" n5 M$ \( V - Gamepad_0_Value = Gamepad_1_State + 1, g% W! n* \. { K
- Gamepad_1_Value = Gamepad_0_Value + 1$ U7 K* n, \5 P7 N
- Gamepad_Port_Value = Gamepad_1_Value + 1% v5 E1 A5 J- q- n7 o% L; _$ [
- Gamepad_Merge = Gamepad_Port_Value + 1
) D, M1 N* L5 I7 z
0 T0 ^& s$ p3 y2 G- ;==================================================" t z5 S. y3 D. T4 C' f* W
- IRQ_Index = Gamepad_Merge + $01. N! G$ { @: M9 K1 H2 |6 A2 F# r
- ;==================================================
4 q- I, F$ Q h - ! x D& J7 h0 q% ~" e$ N$ J2 {
- ;CHR图形数据
. I) R6 R5 `: b - ;==================================================& c% j3 K. W$ m) A* _/ l3 c7 d
- .BANK CHR_DATA_BANK
8 N0 z5 V7 C! m+ E - .INCBIN "chr_bank/chr_data.chr"
+ w$ x P& {8 h6 y$ y -
# o7 f+ r3 U! [6 k" ~ - .BANK RESET_BANK & BANK_DATA_MASK* c- B5 L' i/ N- B3 C
- .ORG RESET_ADDR
9 ~$ @( ^' k/ g! p8 | - + [+ q; j# C; ` [* H9 |$ j# d* t% A
- ;--------------------------------------------------6 F, p. q- p- C7 v/ X
- Attributes_Data
% i7 K; q9 G8 l- R8 ^" | - ;命名表属性
( d" e) V' `6 x* v/ N& M - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$007 m% F% r5 v& W5 `- N. x [7 p$ |
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA( {* r% ~( [/ C' a5 u( X( |
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA' `# x: C/ |0 Y3 ~+ k
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$555 D' V$ o, p1 F# s# f* s$ {
- ;--------------------------------------------------, C, U- s. O7 ?1 U' P
- ;调色板数据. k9 J2 H0 n9 |* k8 T& J
- Palette_Data( d' g! `4 V5 _1 H5 L
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F8 G2 Q* g. L8 W A* l5 j% v
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F# i' i/ e3 U! e! o* W
- ' B; g1 n6 W7 f8 X
- ;==================================================+ Q. Y6 ]0 `+ T/ M) Q; ^
- ;命名表初始化
, S3 h4 n7 l" C: n ^4 V, G - Init_Name_Table; ]9 {$ n7 y5 d- v+ X* w
- LDA #$20* h; D2 ~& ?: [& C/ V, b
- STA PPU_ADDRESS
5 L/ T3 R, Q& a* T9 S - LDA #$00
9 k9 o5 I0 ]' m9 C- j - STA PPU_ADDRESS
' u! `* l+ E6 v$ [ - LDA #$009 ^# v% Q* b# s# `( [& o
- LDY #$00
! l' X F* [: M" H3 v - LDX #$10( H) d# _9 T1 t* e l, I( V1 p
- Init_Name_Table_Write
) ^6 T* K+ [0 b5 {% f# c - STA PPU_DATA: J$ ~- B/ j; H: j. w! R* X. O# P
- INY
. M$ m/ [ @ T: I$ k% w - BNE Init_Name_Table_Write
+ \, y( w' R3 P+ I - DEX; n D& u6 o# z! g: o
- BNE Init_Name_Table_Write
* r% G) ^5 j% b4 Z+ i/ F - RTS9 S" C- X! Q+ H9 j/ t' [
- 7 J3 w. b8 l" ]* d0 V$ b
- ;==================================================* m1 _& [2 I8 ^! l; s Q* A0 F
- ;调色板初始化/ `7 W0 J: F" \
- Init_Palette
0 f; u3 v: G& W$ k - BIT PPU_STATUS
& n" [. z, R: i/ I - LDA #$3F
- W! j! E7 ]5 n - STA PPU_ADDRESS- ]5 J1 y* V3 g
- LDA #$00
# a/ H( e6 }/ G; o1 C$ {6 Z - STA PPU_ADDRESS
1 H" Z, N8 `, X3 w8 s" i P - LDX #$00
, J$ U+ A y5 J, r, X5 z# C4 }4 P - Init_Palette_Write
' X/ @2 a2 a4 U0 N - LDA Palette_Data,X
8 S# C. Y$ l$ x+ G5 ^9 [: a - STA PPU_DATA
* j5 @& E6 }, I7 ? - INX
& e& H" ~9 P# b8 r. \ - CPX #$205 K. s" p. l& d9 L/ l0 g5 V4 V
- BCC Init_Palette_Write% w# V; ^% Q7 ~' H9 s1 Y$ o
- RTS \. {% J9 Q! Q, b- V
-
8 I! V' |8 n) V1 ?2 O - ;==================================================
% b# ^; E! V$ i. u - ;设置命名表属性
9 K- I& {4 |% E! ^* w. D# V6 C - Init_NameTable_Attributes
# p; C/ Y' T/ f& ~ - BIT PPU_STATUS
. f6 h4 M. p, D( z4 S% _2 ~ - LDA #$23
A# u7 J! T" e5 J! W - STA PPU_ADDRESS5 ?' R4 P# A' v- x
- LDA #$C0
% o, [% H: B2 L2 q0 ^ ~ - STA PPU_ADDRESS
0 W# X. G& } |+ B9 q) @# f3 y - LDX #$00
7 F& B* |. K0 q: C8 ~, G - Init_NameTable_Attributes_Write! `1 U* a# P; Y9 r$ E+ O
- LDA Attributes_Data,X% f8 h: A; ^: H% d
- STA PPU_DATA1 P& ?# E4 v+ H
- INX
C5 t1 v2 I: x. Y. B2 e - CPX #$40
$ A6 M6 C, r6 b7 z - BCC Init_NameTable_Attributes_Write, O; F) O$ ]3 q2 }3 C; l
- RTS
) G" U$ W8 M+ `5 L - : ~+ m- j R! a* m
- ;==================================================3 `9 P- k; R. W3 U/ Y1 Y- ^ H
- ;初始化命名表文本
1 M8 W6 {: A7 L% s2 q: d - Init_Name_Table_Text
6 }2 ~) I+ L% n. b4 @ - BIT PPU_STATUS* h) n, Z2 s/ Q+ n* J, a' k
- LDA #$20
; X9 Q% ^& X# n& ?: N" } - STA PPU_ADDRESS
* T' n; W3 W+ u5 E, I) u9 H - LDA #$00
8 b' Z( I6 A) k) U3 y: N$ q - STA PPU_ADDRESS) P, o3 |! z% K" L/ N$ f( `
- LDA #$00
% H6 t6 \, O( j' Z - STA FC_Data_Buf
- o& f v9 `0 R, h( D) E( J - LDY #30: {0 n: S& m- X$ ?
- Init_Name_Table_Text_Write
8 G5 ^. n/ V8 }2 @# g/ B5 v - LDX #32
3 ~1 @* J g" H% l. ~+ T! \ - Init_Name_Table_Text_Write_Char* c: p6 u* _; O0 g: x
- LDA #'0'
/ i1 \( J2 [! _, \$ k - CLC1 c2 m0 I$ A2 F7 e: u+ P$ z. l" D
- ADC FC_Data_Buf
: ~- J; V- q) J, S2 r: C - STA PPU_DATA
( u) V2 X0 v0 U: x* a# o4 R7 ` - DEX
4 n0 a6 l) {4 m) Y+ ?1 A) L+ h - LDA #$14
. \, U% R, K+ t2 E. w( G - STA PPU_DATA
4 O# g1 _4 @ k - DEX& ]2 x4 |8 j7 p" r6 P4 B) w
- BNE Init_Name_Table_Text_Write_Char
' |% |. `. S; V( x - INC FC_Data_Buf3 {: _5 h) S# r: A9 _/ o. X7 G
- DEY
0 m. c% c, |! s; N3 [ g - BNE Init_Name_Table_Text_Write e+ x; T' V7 T" p6 Y: | t
- RTS" D" }# X- c/ O9 S3 ^. ^5 n
% X, m% ?# y/ x" x% t- ;==============================0 u" ^ i* ~3 y
- Init_OAM_Ram;初始化精灵内存, V. _0 U T9 z) [* o
- LDX #$00
: P7 a% v' W/ C, r3 q. u5 g - LDA #$009 R9 O- o+ _2 r! b4 J0 b2 M+ N3 d& F
- STA PPU_OAM_ADDR
8 r0 K& u/ t' p0 s0 \" N2 c" b - LDA #$F81 m- f3 P n) }
- Init_OAM_Ram_Write
/ u+ x* d! |1 u, K7 w - STA PPU_OAM_DATA
: W1 ?- a0 j8 A. M; d+ I - INX7 @7 ^0 s& s, m, u4 f: S1 d) R
- BNE Init_OAM_Ram_Write
: P( J9 t0 W7 c - RTS
5 @# K; D( t" O; g! ~ -
0 ` _# E" x0 `. R3 T. e - GamepadProcess;手柄处理8 E! z* m' k4 I9 N
- JSR GamepadDatacan) ? m+ Y0 F% m& ^9 m a0 r
- LDA <Gamepad_0_Value
: |- P" b( S/ S0 R - STA <Gamepad_0_State
, Y) ^3 r$ l; K" E - LDA <Gamepad_1_Value8 q0 j% \) R! Q* L
- STA <Gamepad_1_State
! g0 k1 q p6 y1 o& t$ w - JSR GamepadDatacan
+ O& t3 r r/ D8 |* \; z - LDX #$01
' F+ |$ H5 F% @$ p - GamepadMergeCheck;合并手柄输入检查
4 M! V5 g3 o2 ~ - LDA <Gamepad_0_Value,X
7 q: l7 h* {4 F; x1 v( Z% ~! Z - CMP <Gamepad_0_State,X! z3 f+ }) ]" c& w
- BEQ GamepadMergeInput3 _1 a) `8 t5 y( ]7 d. \5 f" l3 j( x
- LDA <Gamepad_Temp,X
. z. a9 {: H) Y' A& |) ?: T - STA <Gamepad_0_Value,X
) r! _; O" q3 W# u4 A9 _$ I - GamepadMergeInput;合并手柄输入9 x. b* l* A0 [4 [6 g# s) G
- DEX: [. o0 }- N* s) t: c, F- J
- BPL GamepadMergeCheck
/ q% e2 l) F7 C6 U* Q3 g# P - LDA <Gamepad_Merge( ~# n, x# O7 M, X F! r8 S
- AND #GAMEPAD_MERGE_FLAG2 U$ A# w: E7 \% o9 T' d9 w& O. {
- BNE GamepadStateProcess* {2 p0 H* t& o4 E: M) V
- LDA <Gamepad_0_Value
2 F+ h' K* ~- N4 l# p - ORA <Gamepad_1_Value6 D4 N' z. ]" n$ i
- STA <Gamepad_0_Value" ~0 U# h' V* y( J/ n
- GamepadStateProcess;手柄状态处理
2 a2 a/ F9 n0 u, U - LDX #$01
" r8 ]: d R7 B: ~5 H+ ^/ Z' b8 O1 } - GamepadStateSave;手柄状态保存
) p9 L8 Y/ D5 T2 Z2 v. O P5 _* q - LDA <Gamepad_0_Value,X; A; n% d7 s: N& v
- TAY
5 v2 V2 W1 w0 [4 y% ? - EOR <Gamepad_Temp,X
6 M9 \/ A5 @' b! {1 Z' B - AND <Gamepad_0_Value,X
5 D& c, ?% }- t - STA <Gamepad_Once,X4 l% x5 P+ n- I' [; H6 ?
- STY <Gamepad_Keep,X
# g- R; p8 _) o+ i5 L - STY <Gamepad_Temp,X1 s: a* ?7 I) d/ q- S$ r: u
- DEX
( _- d. ^( t# [7 f8 V# H+ x - BPL GamepadStateSave+ V1 K% J8 m& n+ F( P
- RTS- d6 b7 \+ ?* W' U+ b; W% q
- 3 w* F4 X% N8 u, j4 O/ r
- GamepadDatacan;手柄数据扫描
- T% p- e2 G3 F- @8 l; s8 T! j - LDX #$01) `. Z4 \7 l! K( d+ p
- STX $4016+ {: E, \- O: N% G3 L3 { ~" o
- DEX& x8 H8 X0 u0 z* O k7 K! Q. z$ V/ t4 D
- STX $4016$ v* X T1 n* h5 d2 M" Z
- LDY #$08
! C2 X; y( w8 \ - GamepadPortScan;手柄端口扫描
& p: J8 O' G& Q1 @3 a8 u - LDA $4016; u! c8 D, a, Q* {9 ` [) H' C
- STA <Gamepad_Port_Value( `2 h- {7 u' N1 d% X" N
- LSR A
7 Y) K8 {9 y' l! |" I - ORA <Gamepad_Port_Value
1 W& A$ W R D( i( `. W: M4 p - LSR A
/ j0 h! Q/ h. ~. [$ y8 H - ROL <Gamepad_0_Value
1 _* C8 C7 ?& H5 {8 H J B. ~ y* r - LDA $40176 l9 u# G* _, X, ]% j
- STA <Gamepad_Port_Value
5 O0 n" U! u1 y9 Q - LSR A
% G4 _0 g/ O0 @" J; J - ORA <Gamepad_Port_Value
0 L7 {9 r7 |4 S8 D$ e - LSR A
' A9 b( ~9 H( H - ROL <Gamepad_1_Value) I1 a3 @0 n# ^; J0 S
- DEY0 `( Q7 Q0 t v6 H
- BNE GamepadPortScan% l B+ t3 D5 g2 ^; o( f" U
- RTS, i! `) \4 a2 u! Q+ S
- ! k+ `! V4 v) R5 f8 a4 I4 f3 r) {$ N
- ;==================================================
" ^, D* P8 {; ~, z! c7 ?- J - ;PPU处理! z/ A* t. g$ \8 \
- PPU_Process# r8 k- X, r* v) l/ Z1 w/ J
- LDA #$00
2 y! d# N s: I4 y - STA PPU_MASK
7 l/ m: f2 k' C$ o$ p* A' o# C - . D. f: {2 Q0 w, R% i7 @' C
- BIT PPU_STATUS
7 J ?4 R5 F0 K5 v6 x n6 S( r$ j$ T - LDA #$204 l+ t/ X& i8 @# z5 Z
- STA PPU_ADDRESS3 y9 g- n" W3 _/ Q6 O4 k
- LDA #$00
5 o7 F( S! K& r8 }6 H - STA PPU_ADDRESS
" ]+ C3 d# Z1 N. q4 C% e U; _& u -
6 F2 O+ N' g1 s0 | - STA PPU_SCROLL4 }5 N# | ]5 M! b5 A+ n4 \$ m& N, x- D
- STA PPU_SCROLL7 Y# Q/ S( d) c5 H* B n
- . g9 U. s2 F7 c' f3 S2 O) y1 a
- LDA PPU_Msak_Buf# V' ?" t0 K2 u' k( k
- STA PPU_MASK
7 A" }: `! Y: M; X H7 { - ' S, I7 U k6 ]7 e# f
- RTS; N1 `, m3 b I, w
-
6 \4 |7 \) N3 g' B3 N- T - ;==============================* [- `7 N, o7 z7 Z# }* U7 j7 M! Q
- Time_For_Vblank;延时等待$ h( p; b) f `7 C* d# O+ Q
- LDA PPU_STATUS9 x0 d# [2 \9 A" ?/ Y
- BPL Time_For_Vblank4 ]& A) v# \) n5 Z
- RTS
1 H7 x/ {! ~* v# Q -
/ e5 T ^: Q, v - ;==============================9 ^5 y, G, d9 d+ E$ N1 {. }- Z3 V
- ;初始化MAPPER199 v8 l9 E2 s4 U1 I
- Init_Mapper19
( R2 _! M8 H+ w2 }3 m6 V8 T - LDA #$00+ c& m; Q& W0 Y' V& C
- STA M19_CHR_0000
& \1 |. D, H8 |+ R - LDA #$01$ {. R* H+ I3 e, {) `6 E4 N$ Z
- STA M19_CHR_0400
m) [2 C5 i: X- A - LDA #$02$ E6 l7 r! q7 K: j9 \7 R
- STA M19_CHR_0800: {: ^7 B) W+ S4 j0 o6 u: o( F) E
- LDA #$03
) o& Y! w1 R& o - STA M19_CHR_0C00/ F- c# ~) m" M7 X6 ~
- LDA #$04
$ O+ `. a# [ K6 {; a3 e* ~: g9 S - STA M19_CHR_10005 e3 P8 e8 {6 N9 [0 j1 U
- LDA #$05
1 ]9 X; P4 Q5 c" }) d% Y& G - STA M19_CHR_1400' b7 M3 u/ \( A' _% A% \+ ~" n
- LDA #$06
/ ]' l, w4 `( U! {, G. z - STA M19_CHR_18003 u6 Z" T. v7 q& D
- LDA #$07
, V0 t; u. i! V8 L4 e* o' Z - STA M19_CHR_1C00
6 ?1 m& ^2 c9 K& {7 ] -
( P4 E/ H% p/ Y/ o - ;禁用IRQ4 j( t, h9 S1 l' M
- LDA M19_IRQ_COUNT_H
* Y' Q1 Z1 U2 k" D - AND #$7F
8 N5 u* Q8 y0 r/ t - STA M19_IRQ_COUNT_H; q; k0 u: \1 e, R
-
: j X9 c2 U0 i' `0 N1 j7 c - ;命名表" h1 p8 F ^/ J, t# w% N
- LDA #$E0: i" u1 Y3 m; z: \* c0 Q! q
- STA M19_NT_20006 J) C4 I# I. r) d
- STA M19_NT_2400! p/ ~: j, p1 i2 u* o7 K
-
7 [) ^- t" d* |5 v8 s, f0 u0 G: s - ;命名表
2 [9 c3 N( g7 |# n. b3 L) \ - LDA #$E1
4 E# l- t, A5 N' i+ j7 T1 @# Q - STA M19_NT_2800
9 W' k- ?6 r! t, W3 d' n5 ` - STA M19_NT_2C00
& L) u% w- I D" ^8 X# M( x, s - 3 [9 ^9 b5 U% R4 O& ~- w
- RTS9 Y# p& h. H O# b( \2 G
- 4 X4 }9 O0 t0 o. s4 P4 W
- ;==================================================' ?; `7 a0 D4 d: S4 o* V
- ;重置中断处理
# W! I4 f5 R8 A, o- A9 C - ResetProgram% E- ^6 Y9 ~* B3 Y7 u
- SEI3 [/ n/ r* C" t
- CLD, r( [8 k9 N* a5 V2 L9 ^, U6 g& ?
- LDA #$00
) q6 |9 T! }: _3 M6 l: d; c - STA PPU_CTRL1 @$ h) Q' x2 P
- STA PPU_MASK
G4 y7 P! W6 r, [. `( c$ }& b% E - STA PPU_STATUS
7 a, K q% [3 o$ | N - STA JOY2_FRAME5 Q1 d% c7 p! S/ t2 ?/ s6 s
- STA APU_STATUS8 H% I3 U( W" w; w
-
$ B' U& ^. s a$ Z - LDA #$C0& C0 X* w3 T5 J6 o# g4 u+ F
- STA JOY2_FRAME
5 a. v. g0 u: b - / j; ]+ k7 N# u8 t% G
- ;等待vblank
# n: l7 p3 a {( a) s+ y/ R& `1 W$ ^ - LDX #$02
! e" S; _$ S# S7 h( r5 W1 A. A - Vblank_Wait_1
2 L T- z; Y0 q; v- }0 b p/ ^ - BIT PPU_STATUS5 V0 p! N N$ y* y2 P% b' H0 Y
- BPL Vblank_Wait_1
J7 I$ Z) g9 o% l' Y" l( c* E, t - Vblank_Wait_2
, D" Q2 U# Q# c - BIT PPU_STATUS
- Z9 g$ T* C7 {1 l8 Z+ B+ v - BMI Vblank_Wait_2
8 O! v' O" N+ p# M5 _ - DEX
( p8 p7 {: y4 g% |% D k - BNE Vblank_Wait_1
# N% | l4 ~% s5 Y: G; Q @- K6 Q - 7 m. o. c6 L. \
- LDX #$FF- a7 g( N0 u% K$ c& O
- TXS
6 d% L# m% H3 t6 t- q. D - 3 z# `9 ^% I. e$ a6 I+ W
- ;初始化MAPPER19! p% D3 p1 v" x
- JSR Init_Mapper19, _- O+ \, }7 E I( z; s
-
% z0 A( u* ?: }0 n( K0 `; ` - ;==============================
- r4 T6 O0 {6 X* Z - ;RAM初始化
' x V1 t. x Q. ?4 N( Z. e9 z - Nes_Ram_Init3 x- m9 ~6 s9 w5 N+ P
- LDY #$00
6 }2 Y2 `+ z F- x7 i/ Z' F - LDX #$08; }( E& M+ v! D7 A# u" o& ]
- LDA #$008 T& I. \# i- ~" ]0 ?" W0 t: `
- STA <$00* h0 S' s% e4 E8 ~, T
- STA <$01
' k9 n n* p$ U! _4 _ - Nes_Ram_Init_Write
4 Y) t$ j7 F; w; L - STA [$00],Y' _3 p* H1 v+ o2 m
- INY$ e. [6 i3 h: M$ _
- BNE Nes_Ram_Init_Write
. A3 P0 Z6 b' t! w - INC <$01
8 J- N5 b8 b# o5 W! B - DEX
9 M: m7 H4 s- N- {+ u1 c - BNE Nes_Ram_Init_Write
O6 Y$ [. L6 c8 ?" U: u8 W - 3 f3 U2 J- t2 c* h
- ;初始化命名表
: d4 V1 P# H7 q# h& ` - JSR Init_Name_Table
, |" B; \# @4 Q3 R, d# D7 F# O - 5 M- ?- P) p* E! c3 R
- ;初始化调色板& r# J& a1 r0 F* A
- JSR Init_Palette
( q& R9 |7 h o( M3 n; P6 a - & w* H& q; a$ R# X1 @
- ;初始化命名表属性
4 J. j" ` K: d# |2 W: u - JSR Init_NameTable_Attributes
! X% B( z1 X) e, z5 b -
0 @; y* k/ r( F - ;初始化精灵内存8 ~: }! ^- F% U+ C w2 n( B
- JSR Init_OAM_Ram4 z% x6 e/ [/ w
- , E/ `) U, m: O5 t/ u. v
- ;在屏幕上写点东西
; \6 i' X! N9 N+ q - JSR Init_Name_Table_Text/ q9 ]- d# {) O* A) {. z, q5 J
-
& P5 X* |0 e: ? - JSR Time_For_Vblank1 o( A+ ^" m9 n1 |! D
- ;开启PPU控制
3 m0 t1 H6 M9 i( L1 e1 S - LDA #$A8; O# ?+ u8 D% ]& I$ y
- STA PPU_Ctrl_Buf T3 e/ T( { K5 u' X$ m
- STA PPU_CTRL$ `: b) z0 u4 H) I& V: s$ B
-
; K& }8 H% v5 x, o( W - ;开启PPU显示2 \! A- V+ f- B. n+ p: Z+ U% y
- LDA #$1E
0 E0 \ s, n z+ J - STA PPU_Msak_Buf
, z) [/ W8 V* ^; L1 m x - 2 y# a7 T$ c- b, c+ q
- CLI
. y w( M4 f, C+ F, e - JMP Loop
" h/ [5 {0 Z* \ - % x7 x- X/ e7 T1 W
- ;==============================
+ f% n1 M$ x: |/ {8 u& v - ;死循环, 等待NMI中断! E* N7 Q1 \5 o+ Q
- Loop
2 S& @& m2 _6 Y* i - JMP Loop* p7 o2 E# J1 s' K
- 1 z8 y9 S2 B1 k3 t7 q* e, ]& O- m
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
0 l1 T- _# y: A, P- e
; H5 e( f8 d4 f o6 K9 I- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)1 [/ v. K+ b0 c ]( @* c
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
+ |: B- `: c# }8 B4 v8 E# b - ;==================================================
8 S0 q: C3 p. I' F - ;NMI中断处理
: v4 c* f- Y! ?* `2 w. v - NmiProgram
# j# r0 j% _( Q4 C3 O$ B - PHA
# L# S0 C0 t9 S6 ` u - TXA
( P. L$ v) J8 `% a4 x1 i4 ` - PHA
) E2 B. x7 R1 Z( E- e - TYA1 k/ @4 ~8 p- r, ~
- PHA' G! ], m. H/ k1 `
- , x1 l4 q' b6 O g3 Y
- BIT PPU_STATUS
' x# V; T# c6 e6 o - . y& p/ D, ^, t( j0 C y
- LDA #$00/ ~% D* X. q& S1 Z& w* I- {
- STA IRQ_Index
) {8 m2 ~, b. n -
/ C3 o/ |3 x: k+ k+ l+ n - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
/ `( R, L/ v+ U {9 @ - LDA #LOW(BEGIN_LINE_CYCLES_START)
$ }. F$ p% q( G( \0 q - STA M19_IRQ_COUNT_L a( n9 ~7 {7 W( Q
- LDA #HIGH(BEGIN_LINE_CYCLES_START): [8 R" u% t: T, r |" r
- ORA #$801 U2 ~0 Q# X. p: u" U
- STA M19_IRQ_COUNT_H2 m2 s' F' M/ u9 v. Q) M; g+ f/ m
- CLI
) a b9 \6 R2 y7 k$ m; Q -
4 z6 P1 _7 ~3 s5 E/ i% M# q K - ;关闭PPU控制
' C( q" T! A7 Y/ J - LDA #$00
3 M7 a4 J+ c; b" } - STA PPU_CTRL6 H% |* D7 j. X: j+ n+ O
- 1 ]3 [% b) ~$ B% F! U1 K
- ;处理PPU5 k# A0 J4 w) D9 G! ^# r0 p
- JSR PPU_Process
. u- F5 i0 {! f$ r" M - 0 ~- G& b: ^+ ^5 q* ~+ I* J `
- ;开启PPU控制: Y2 ]4 \, l+ X+ `
- LDA PPU_Ctrl_Buf
) {$ N& }- h# O$ F, b - STA PPU_CTRL6 ]7 I9 V, D8 i# @+ S& }) x
-
' a9 i) I: u+ V. ]- k: i* O - ;手柄处理
6 k- c1 H* Z, _. Y. x( {$ { B - JSR GamepadProcess6 }+ i6 k" I$ I- A7 ]
- / ~; @( Q1 m$ p% C# u
- LDA #$00
3 q4 t# o$ c" H: g5 L - STA IRQ_Index5 h5 J/ @$ ]+ s+ V& i* S! L
- 0 X; l9 v7 h8 d
- PLA; T& y/ t. |, d7 I
- TAY
) |3 g! f( m8 _5 r; B8 U - PLA
/ h0 H6 F- U! L3 A8 n - TAX
6 e0 `( u+ }1 u7 k3 g - PLA
) @; ]! \8 t9 j5 O - RTI. @( ]$ j9 c7 \7 y C# Q3 G. y! z
" o# x3 j6 |* b$ ]: O- ;每行扫描线113.673 g, ~: | e; H0 P
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
- w+ h; z0 b' q/ }- M - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 78 U) z: A5 f9 F9 e; i3 z1 j* U
- ;==================================================
7 B0 f: A% A8 a+ g; R - ;IRQ中断处理
: A9 {' B6 g1 m( u8 I! T - IrqProgram4 X2 x6 s1 v2 j* V9 N7 ?
- PHA7 w' g; [9 |: y$ ?
- TXA
% y S _6 R1 H. f: k; b# a( R - PHA
a" J: V. v. T! q7 L* a - TYA6 o# N' L5 c; ]3 s* [5 Q( a
- PHA
, u0 K+ Q5 k/ c -
! P: Q5 }, o: S' G2 ^" x - ;16条扫描线后触发IRQ
9 r. n0 ^) g8 h# W* o i! W( A - LDA #LOW(BEGIN_LINE_CYCLES) c$ C) Z' R# _1 F4 |' G
- STA M19_IRQ_COUNT_L
! T1 Q, Q7 h/ p: O+ W( ?2 ~/ k - LDA #HIGH(BEGIN_LINE_CYCLES)) M. _2 Q( j- k1 s8 E
- ORA #$80! R) B5 H) t5 }# A y
- STA M19_IRQ_COUNT_H2 o# S! F. c' t1 n5 D Q
- d5 ~5 t5 j; }$ z9 f
- LDA <IRQ_Index
^/ e! w0 d; s) w' g2 h8 u - BNE * + 4
( c# T$ E1 y! t) @! ~ - INC <PPU_Scroll_H! B0 q& z9 f" T5 W! b
-
- p' D+ V; y5 @% c/ Q8 z# e1 n - ;设置屏幕滚动
2 H" ~! g: p6 z7 p - LDA <IRQ_Index$ s! V; e F' O) C, D1 ?4 j
- AND #$01, O/ J- Z3 `2 M. n+ q6 \& J
- BEQ Irq_Scroll_Right3 N1 l9 J5 W9 a9 O' [4 z4 ]2 b( [
5 Y) p% w" c5 H0 }* c- Irq_Scroll_Left
$ [4 b; \6 y' m( Z - BIT PPU_STATUS% H8 C. ?! ]; L0 G" m
- LDA <PPU_Scroll_H
, @& a* J$ t v9 J - STA PPU_SCROLL
: @/ J( X) X4 d7 Z7 E - STA PPU_SCROLL; y" }- p2 V2 d1 }+ m1 _
- JMP Irq_Scroll_Over0 t! Q4 a# @1 }' b- W2 d6 \
-
; |( B v2 L9 a6 n& \ - Irq_Scroll_Right
+ v0 I1 U: t' {: t- T - SEC
) }. v# h5 p5 U - SBC <PPU_Scroll_H; v& K% K* ]: F4 d
- STA PPU_SCROLL
( [! E9 ^6 e5 ^6 y" E; r - STA PPU_SCROLL
" R- d l: t) T1 s7 O% l - Irq_Scroll_Over
2 U4 n, F h6 K4 O - - d" g4 ^& o( B; L z& t% ~( D
- INC <IRQ_Index
7 P5 Y5 W1 X5 s - 9 C! t/ N8 u! @
- LDA <IRQ_Index4 z. n+ u( ~" X, I; p5 g3 x; L
- CMP #14
' _$ V; }& }0 V8 F - BCC * + 10
: P3 I. V/ V D1 C0 [ - LDA #$00
7 j7 N2 }) g8 h- x. K, |8 _; D% p2 ` - STA M19_IRQ_COUNT_L
6 t& V7 W7 k. Y" M - STA M19_IRQ_COUNT_H# q1 C' N8 D$ ?5 r8 V r
- + `0 Q/ j+ ?. k: U6 r( _
- IrqProgramEnd: D) N) o8 U+ `# @1 V9 A* _- u* ~8 a
- PLA
( g! J4 A! I m- d0 P1 { - TAY
% T7 ~5 V6 |# i3 S4 S - PLA8 k. C( \9 m' L! }
- TAX, o# r' K/ B+ n
- PLA
, u6 M# M; H; D! m9 h - RTI1 V1 T6 J# w* S- f) j
- 3 D+ u+ i- E* {- t/ `+ s, A* U2 I
- ;==================================================6 B! z( G4 x ~! V* y6 g
- ;中断表2 S; i% h( m# Y5 g8 H( |' Y
- .ORG $FFFA
9 ]# M* |, g9 ]+ C( w7 m! b9 u* Z - .WORD NmiProgram0 F Y/ r9 k) O) {
- .WORD ResetProgram W5 c: F0 E4 r
- .WORD IrqProgram
复制代码
U& b- T& \8 c' n% @5 B |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|