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