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