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