|
|
- ;[FC][Mapper19 IRQ]
; p' S- p [8 ?( ^9 B: A - ;FlameCyclone 202307105 ?1 w5 a8 `3 p+ C
- - k5 `% T0 Y) K+ ]* Y; K3 S! u
- ;文件头( \$ ]( X* V' [
- ;======================================================================, `4 y- p# A% q( u5 f" x
- .INESPRG 4 ;16KB PRG 数量
* ?; E, N8 N) j3 g - .INESCHR 1 ;8KB CHR 数量
& [0 X# s9 |8 x - .INESMAP 19 ;mapper 19
) y- V3 g2 H; b/ n8 z' m - .INESMIR 1 ;命名表镜像 0水平 1垂直
* O9 x4 i' U- ~& \5 J, k3 X - 7 S3 @# s- ~( o8 o! g7 U
- ;必要条件( Z$ @" r$ h) V/ Y) a4 M, |2 i0 h
- ;1.持有CHR ROM5 T6 k' ]5 A# u+ E2 B
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000, {& _2 f- `! r. w( S+ i
- ;3.精灵内存(OAM)不为空
+ |9 g7 Y% M: C- `0 B1 ~" ~
# ?, W! v0 `% W8 ~$ p; n- ;==================================================% @) ^7 C/ |; ^/ E
- ;NES端口常量2 G) d0 ]$ Q& b6 Z
- PPU_CTRL = $2000 ;PPU控制寄存器
- V$ ]) n( G" R+ A# e8 f% ` - PPU_MASK = $2001 ;PPU掩码寄存器0 W/ m r( ?# F1 S" X
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位5 R7 A% x" O4 ^% p% m0 c5 n
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1. W# c: e* h) R* k2 s
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1% h+ t* @& A) ~4 W7 M: }( v# i
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 2 \* J. ?+ \, h
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
1 t1 J% H1 M! ]% v! q. g - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
0 Q/ u% \" _ s0 E9 Y2 G - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存4 p8 R0 U4 i: Q+ M
- APU_STATUS = $4015 ;声音通道切换2 R5 A8 D; F5 |! L6 B
- JOY1_FRAME = $4016 ;手柄1 + 选通
8 |- ?! _8 _# D/ j' ~ - JOY2_FRAME = $4017 ;手柄2 + 选通
* V+ t; L) ?" W- y - 2 I# K! k |( ~: V# l( g
- ;==================================================
% [! k6 t, H: H, Y+ }& V. _; F; i - ;MAPPER 19端口常量: u' I& u5 B* @" T7 w
- M19_CHR_0000 = $80008 S |: U6 B- F$ a2 x. r
- M19_CHR_0400 = $8800
' z' g, d) S0 k* } g3 q) d - M19_CHR_0800 = $90008 w' v( N& ]6 A6 W$ `; t$ e
- M19_CHR_0C00 = $9800
3 w; R# Z1 M. I/ x4 _! w7 @/ ] - M19_CHR_1000 = $A0008 m3 H+ I8 [6 \) L
- M19_CHR_1400 = $A8005 I& _' z8 P2 p. c% b
- M19_CHR_1800 = $B000* f7 A( R. R5 _; O8 Q e
- M19_CHR_1C00 = $B8007 ]2 S3 i" A! L: w0 g& a' l- W
- M19_NT_2000 = $C000/ ?, T/ o: y+ P: p( h; Y9 O1 c
- M19_NT_2400 = $C800
( i$ q/ j3 {7 g2 j( K! q4 K - M19_NT_2800 = $D0007 N6 Y: ]( X/ e1 e+ G- z
- M19_NT_2C00 = $D800
9 D$ X1 J" r7 f0 ~0 C5 N6 \1 Y# L9 D - M19_PRG_8000 = $E0009 V! g* b2 F | T2 F w8 ~6 f8 |
- M19_PRG_A000 = $E800/ ]* z$ {! k8 y% s
- M19_PRG_C000 = $F0008 R2 m+ j6 ^' r2 |0 A& o
- M19_IRQ_COUNT_L = $5000
, S' E# P2 Z4 m4 H5 c+ h, @ - M19_IRQ_COUNT_H = $5800 S& J$ y* `* b
- * {$ q8 O. l$ j+ f
- ;==================================================9 a& _& [# j8 [9 K
- ;程序块配置$ h: V( l: g! X7 B
- BANK_DATA_MASK = $076 s3 K8 o" O8 a7 Z2 p( y+ m
- ;--------------------------------------------------& x9 e F& G8 x# j1 v% ^+ ?- P( l
- RESET_BANK = $07- t! f. p# B7 \# m4 @. I! z/ w
- RESET_ADDR = $FC00
* ?6 v9 |& ~9 I L% f9 e8 q' D/ ] - ; S" i4 {3 }$ r: Z% I2 S
- ;==================================================
7 z2 h+ A5 o4 {- P' r+ J - ;图像块配置! |2 p# Y8 Y' }. c5 ]; N
- CHR_DATA_BANK = $08; o u0 U: j; v, Q; p
1 I8 ], v# W: c) g8 _/ F4 j- ;==================================================! P- E* _4 j7 U3 B y- r3 t2 N# v* G
- ;零页内存地址配置$ o/ H1 o& z. F8 f4 P6 c$ {
- Use_Ram_Addr = $80! P0 V) l! e* o+ l) h4 l
- PPU_Ctrl_Buf = Use_Ram_Addr
& \! ?6 e. N. w, w" b: Z; A# y - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
" g9 g/ g& E2 e" Q - PPU_Scroll_H = PPU_Msak_Buf + $015 r& ]8 E* _" l! O
- PPU_Scroll_V = PPU_Scroll_H + $01# B" y! N5 K( \
- FC_Data_L = PPU_Scroll_V + $01
8 d3 e! M$ ^; [ - FC_Data_H = FC_Data_L + $01 O' t' T. x5 ^' e9 W
- FC_Data_Buf = FC_Data_H + $012 a- N( P/ e+ X/ D
- ;==================================================
' T' P& E7 I9 J% n2 M- d2 j* r - & I$ T# b! N4 F6 E" ]( ~4 F
- GAMEPAD_MERGE_FLAG = $04
! J7 c: U! G& M- r1 ]! m% j/ u - 3 h' _4 x4 a* C: t7 _0 Q
- Gamepad_Keep = FC_Data_Buf + 17 ~2 q, m* ^, k6 W* h
- Gamepad_Once = Gamepad_Keep + 2. w& ]; }8 d1 _5 s( Z
- Gamepad_Temp = Gamepad_Once + 2
# R/ P( F* ]+ ~! n' J -
2 D" L: ^& ]( l9 H u4 b- r, y - Gamepad_0_State = Gamepad_Temp + 2
7 s. ^' O7 u: t$ Z* n% v - Gamepad_1_State = Gamepad_0_State + 1
" K$ a+ o Z7 O, f, Y/ ^6 p5 `/ [ - Gamepad_0_Value = Gamepad_1_State + 1
# t0 H! C* l1 ? - Gamepad_1_Value = Gamepad_0_Value + 1) i) x9 j4 x2 D5 g" T7 d
- Gamepad_Port_Value = Gamepad_1_Value + 1
9 |3 B7 g) d) e4 k a" g) D - Gamepad_Merge = Gamepad_Port_Value + 1, g1 M+ g l4 ~3 o6 a% D
- + d7 _4 j6 ?' K
- ;==================================================. B4 Y6 I0 L m4 ^
- IRQ_Index = Gamepad_Merge + $01
* k! o W9 Z/ o. {/ q. g - ;==================================================
2 g O- b Y/ e! O
; v: q; S5 r/ o K R! E- ;CHR图形数据1 g$ }" Y0 i8 d9 F X' x" w" ?7 j
- ;==================================================
& `* t# l' G2 Z' Q: M8 W- ?0 v - .BANK CHR_DATA_BANK
6 w1 {& U( ]8 z8 A8 h' T4 p$ e - .INCBIN "chr_bank/chr_data.chr"
* B) z; J* v& a0 ]* T: ?$ Q& T -
* ?/ M: F+ g1 R% Z' Z) g - .BANK RESET_BANK & BANK_DATA_MASK: b# G9 B$ S+ M9 j3 p+ ~
- .ORG RESET_ADDR
" e+ O" n# l8 i# ^- j -
% B4 Y- E. n3 } i! R - ;--------------------------------------------------
. j$ B- V5 H' `+ S# l* G" U - Attributes_Data$ a# I) F: W8 E5 n
- ;命名表属性# Q- Z5 {2 z( m8 ^+ C
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00. l0 e: ?1 j6 I$ t
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
: m% @# q8 k- _4 ?) L - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
k, o! g' x) [" E3 G - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55* K' h4 o$ B, k; H6 G F7 ]1 c+ Z9 C* A
- ;--------------------------------------------------
# j, A, A/ w# b/ j% |) c: _ - ;调色板数据% O3 S6 A' j' a) B9 I1 H S
- Palette_Data
3 f/ g" N4 {. c - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
6 l) T6 l1 R( Q' m5 h - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F+ `$ P* H3 j2 a. }
* i9 R: C( f+ g( k! v6 J- ;==================================================
7 |! Z, G* ?, o& y+ W$ D - ;命名表初始化
# s" i/ f& I$ M: q' O" a/ V- N - Init_Name_Table S5 Z6 P2 k( L" C( y% Z
- LDA #$200 M) d6 Q s- A- @
- STA PPU_ADDRESS
, h E- Z7 H! d% @: d' a - LDA #$00! l! d* O$ ?7 M' F
- STA PPU_ADDRESS3 |' |) A& o! _, V ?0 C, m
- LDA #$002 {3 O) }8 Q5 m
- LDY #$00+ V# L$ T5 T1 g7 y& l2 b/ r/ V
- LDX #$10
' H9 o4 p/ [& F3 O6 ? O - Init_Name_Table_Write
3 f/ ]& B; d e/ F# U' ? n - STA PPU_DATA! H4 ^& P/ j. W- X V$ x" Q8 l
- INY4 _ V4 A. [/ k) T
- BNE Init_Name_Table_Write
+ L$ M1 ]5 V) H! x- I& ? - DEX* }8 w+ e. J& R- f \3 b. Z; L
- BNE Init_Name_Table_Write
; F5 _, c# o7 N+ N* q - RTS; p- s/ h' y/ X* d5 J
- " K7 O) \ Q. r0 l
- ;==================================================& J6 t/ r, b5 q# A0 l
- ;调色板初始化
" t8 i% T) i- F4 d, U' l; L$ E - Init_Palette8 x* y i/ D% u4 s! y2 w
- BIT PPU_STATUS
5 }# T0 @- ~) q" S3 m' v - LDA #$3F
; a) }5 \( B4 Q* ?% w - STA PPU_ADDRESS' Y/ p7 n, Q6 }
- LDA #$003 X0 A; k( ]0 }/ K" J
- STA PPU_ADDRESS. r) r+ r5 K8 i% K8 s9 s# w: [7 M
- LDX #$00, m3 W4 V) _0 A5 j* S6 g
- Init_Palette_Write( N: ^1 b% I, A1 i6 z
- LDA Palette_Data,X
' w. J( ^) `/ g D4 v6 B( ^! U. [ - STA PPU_DATA
& e+ H8 X2 f; e; j) I - INX% d# W. P5 y4 E6 Q! c
- CPX #$20' _( }6 v1 t/ \/ J. q" S) p5 d0 m
- BCC Init_Palette_Write. O2 H ?( E2 W) p& D) ^+ S
- RTS( i5 n0 \+ p/ m
-
+ X: `! Z: p$ P4 l9 f - ;==================================================& B. D6 ?" x: I' J4 T6 _, w1 z4 Q
- ;设置命名表属性
! ?& ^( r. v* |. I0 {5 y. Q5 e - Init_NameTable_Attributes
* J Z6 Z J6 x0 u: ]# x - BIT PPU_STATUS& s- r% K' s D
- LDA #$23# q, L7 I0 s' c, r
- STA PPU_ADDRESS- W0 Y6 O1 e' o$ N1 U* N/ p: K, j
- LDA #$C09 i7 B4 V# ?4 W/ D+ {
- STA PPU_ADDRESS2 u ~3 o7 T6 P" d0 W' L( s
- LDX #$00; Q6 n: M0 }$ C" s" Q r
- Init_NameTable_Attributes_Write
8 J+ [% t5 i- F - LDA Attributes_Data,X* v8 O* B( m! r# s# M
- STA PPU_DATA* n9 }9 x# {0 ^% M, q& f
- INX9 ]( t; _7 Z$ Y' _$ J9 G8 b
- CPX #$408 v" \' f1 B8 k# q5 b
- BCC Init_NameTable_Attributes_Write
" r$ }. H+ b+ c9 b$ \ x - RTS6 a7 l" \6 ?# O0 R/ E$ {! v4 ~ u
- ; g( L4 o$ ]1 T/ b6 e
- ;==================================================. K& g* b" `* |! D; D
- ;初始化命名表文本1 ~6 W" S) y0 [- V& Z, }
- Init_Name_Table_Text( M: n% d6 P+ U, C: |6 H P5 h
- BIT PPU_STATUS
: c' {, U9 [/ |9 X! x - LDA #$201 U/ a- L E, j& V3 X2 I% \+ A
- STA PPU_ADDRESS
5 j w- T/ Q) E- a! `7 G+ B - LDA #$00% q6 j( ~2 n7 c/ V8 G$ P! n! {4 ]
- STA PPU_ADDRESS
; y' e) {6 K. T: A& S - LDA #$00
1 V6 i% T( L. h+ R+ u5 m5 `0 u - STA FC_Data_Buf0 i, F: z2 r. n$ [( h9 w
- LDY #30
6 Q) b* {7 _: p - Init_Name_Table_Text_Write4 U" g# W0 f, p# C
- LDX #32
/ H$ Q4 v+ L+ T; J - Init_Name_Table_Text_Write_Char2 g. C( I! w' Q$ e
- LDA #'0'
' \, Q5 h- f! A - CLC' ]0 r' r7 a2 S9 L7 {2 A
- ADC FC_Data_Buf
F( @+ J; Z, r1 j. F L3 C - STA PPU_DATA
: q4 Y" T/ `$ P8 ?! E* ?/ f - DEX+ B" }+ ~& B8 o
- LDA #$14: q7 z8 V8 h" a; c: S2 c. C
- STA PPU_DATA
* ~( D. |6 Z' Z% e - DEX
4 J$ Y' h" |% K: |( A: }) F - BNE Init_Name_Table_Text_Write_Char
1 M" L: P( [# [- P( k) J: Q0 `3 b - INC FC_Data_Buf |& B4 j2 ]+ e, G
- DEY
6 e; |8 d% \% J: w/ N. k. P4 w" \ - BNE Init_Name_Table_Text_Write
$ S, M2 E& p5 i9 F - RTS6 E7 ~. I& y- `1 X- H& {
- 0 Q# ]; A; k3 I& x
- ;==============================
# F3 d! f0 c7 [% K% A0 Q - Init_OAM_Ram;初始化精灵内存) F9 i2 M3 _' U* ^; q: [
- LDX #$00
$ L7 X* Z6 [3 \0 j5 P# A - LDA #$00
/ w8 F$ ?+ ]$ t2 @; b' ?$ A - STA PPU_OAM_ADDR
- G/ }9 b; }# N$ r/ v. j6 o - LDA #$F8
5 D& P! o2 K* h0 O3 N - Init_OAM_Ram_Write
% r2 ? C1 ]) I) [. D - STA PPU_OAM_DATA
5 I8 z" U' `& i: D$ [' A; ` - INX/ Z3 d- Z" O$ d/ n5 ~
- BNE Init_OAM_Ram_Write
$ f+ |+ L+ I0 Y3 I( b" U) ? - RTS9 e* g7 V* g8 x+ ^; \8 C/ p
- ! c; ]. a- O# \% f0 v& X
- GamepadProcess;手柄处理
4 x2 q% ~, R+ a: x/ y# D - JSR GamepadDatacan4 ~! U8 ], V1 h. b2 x. f
- LDA <Gamepad_0_Value4 [+ K- j V2 D9 `$ @, I
- STA <Gamepad_0_State
2 o( x, H+ ~/ E# m' G* r - LDA <Gamepad_1_Value
, g& e' X2 Z' L# O# y |0 k( m - STA <Gamepad_1_State7 r% r, F ~# c! L
- JSR GamepadDatacan, B' F( R2 g2 y% i! y/ a/ p7 n
- LDX #$016 z1 G4 T$ |, D; M
- GamepadMergeCheck;合并手柄输入检查
, ^5 `- @7 j6 @8 G6 { - LDA <Gamepad_0_Value,X
' o- F& P1 @, S2 X3 y. ~' ^ - CMP <Gamepad_0_State,X
; j+ K" _& b7 V1 D/ _! D9 O - BEQ GamepadMergeInput
9 k% y5 B6 c2 N5 `4 K - LDA <Gamepad_Temp,X
; Q* G! G* j) L* T: N7 G - STA <Gamepad_0_Value,X
7 k( }2 q+ ^* G* `1 i - GamepadMergeInput;合并手柄输入
! R2 }. l Y$ e, P9 @" D - DEX) L3 {2 R% F$ [9 q) q$ E' ~+ c
- BPL GamepadMergeCheck1 f4 q& L. i) i
- LDA <Gamepad_Merge
! x2 }+ \+ G& w, h/ i - AND #GAMEPAD_MERGE_FLAG
$ c& p$ R$ F; e$ S& x - BNE GamepadStateProcess+ f; i9 s0 l: T2 `: K, d
- LDA <Gamepad_0_Value
/ V: {) `6 o( A% h6 ^1 I - ORA <Gamepad_1_Value
C& ~8 Z! b9 p' }6 a" h, W# I; \ - STA <Gamepad_0_Value, ]( _! P8 T' g( d
- GamepadStateProcess;手柄状态处理
* A* p# s3 ^# Y/ j* n2 y - LDX #$01* Y; q8 z6 t+ T3 \7 k
- GamepadStateSave;手柄状态保存
- ]" S4 s1 ]2 r" i8 y* a2 v/ W. L - LDA <Gamepad_0_Value,X) _; {7 {; o" Y* s5 K7 _. A: b
- TAY
1 c6 F2 t0 S# Q - EOR <Gamepad_Temp,X* i" h k, s$ F" n& ~
- AND <Gamepad_0_Value,X) i* y& N! x* K0 l. R8 D
- STA <Gamepad_Once,X
9 ] h2 c+ n8 C) g# } - STY <Gamepad_Keep,X& B3 g$ ]+ d7 {
- STY <Gamepad_Temp,X
( v- D% h) O6 F% W* } - DEX
0 H4 h) M7 p+ v) R9 U& ~( G - BPL GamepadStateSave5 |2 G! ]" K# g+ j
- RTS& E9 d$ Y- H$ N- T+ z, O
6 U, N: w: k9 L- GamepadDatacan;手柄数据扫描
( D& ~& _, l' Y% e7 ~+ U6 J# h - LDX #$01& `2 p5 [+ j4 }. P
- STX $4016
( V6 X8 z( h+ R* k' K s8 \ - DEX3 i6 \2 a5 i1 S [* i( ]. ?
- STX $4016: {5 i# a1 J4 ]. @" N' p& q8 y
- LDY #$08
% O; @2 H2 q3 L) l+ `% h$ c - GamepadPortScan;手柄端口扫描
4 N2 o4 O) p2 o - LDA $4016
& F' c, I- Z& \0 I3 T - STA <Gamepad_Port_Value* w" o$ C5 H& b$ c. z8 D9 I; E
- LSR A7 v- ?8 `$ l, _3 B% v; C R& p
- ORA <Gamepad_Port_Value, D Y* ]2 t q- [
- LSR A# U% U. ?" }1 h1 O& [
- ROL <Gamepad_0_Value! f5 x( u7 c9 k/ [" O7 i
- LDA $4017; F+ m6 U, F ~( b9 G
- STA <Gamepad_Port_Value
2 j2 N3 e$ w# F - LSR A
7 J6 J9 l- |3 h( I% [ - ORA <Gamepad_Port_Value. m8 @ p% Y$ N8 @5 b" c# ^& ~4 S" c
- LSR A
) P3 n3 W* c3 w6 {" }- w& } - ROL <Gamepad_1_Value
- B' c B/ f1 ?4 F$ w! X - DEY
; q8 z4 t8 f f0 O4 H - BNE GamepadPortScan
+ N1 K" x4 a) \+ B- j' v - RTS
2 p ^9 g2 \% S$ p5 w -
8 k! S& t; }/ }' X0 V8 O - ;==================================================( _! d3 T# a3 m
- ;PPU处理
6 P1 S' }( e. N$ I. ~# y- U - PPU_Process
* x( i( @- i5 _; t9 x C& b - LDA #$00
; o: X' {0 A3 t# i; g5 u, ] - STA PPU_MASK1 g9 Q+ P) Q2 u4 x( E0 G
- 2 A$ \0 l$ b3 _( f- [$ l8 O1 D% I
- BIT PPU_STATUS. }: H5 @2 P* T/ X2 `1 P5 B
- LDA #$20( s6 Y$ f( E" Z( ?, ^6 |; e* t
- STA PPU_ADDRESS) S( H5 n; ]5 d3 z8 b
- LDA #$00* |# b, c+ q) V- W# [7 x2 Z
- STA PPU_ADDRESS
' C9 W4 V+ C* l8 ?1 d - 3 Y/ r( E4 r! z( L
- STA PPU_SCROLL. u; K3 b3 ~! q8 b8 e
- STA PPU_SCROLL/ a3 m: L8 U' a
- ( e" {- @% d+ l9 y7 F( o) E. A5 ^
- LDA PPU_Msak_Buf
' \4 W8 j' }9 i3 ?+ ]* Z! p' g - STA PPU_MASK/ [; R# c7 \7 x
4 D, k) [" d# T- RTS
& O' I" ]3 W* G( x! {- a1 g7 c! \ -
3 T ]& h# d. l, k3 n* j4 k$ `! x - ;==============================
( B1 t, Y& d% q8 f/ N5 ?0 O - Time_For_Vblank;延时等待
2 g. ?) U( j3 N" X E/ Y$ m - LDA PPU_STATUS
9 y: Y7 h+ V6 K" q& Y- | - BPL Time_For_Vblank
/ b# `3 l/ B" y9 I% b: ~ - RTS5 v. C# f+ B$ }& n; j
- I4 ]; Q2 C& @8 D
- ;==============================
, V- @; @% y& p6 @! m) F* y1 J - ;初始化MAPPER196 G# Y3 a9 J0 e" ~2 S7 y
- Init_Mapper191 g) R1 @- x+ Y4 \. y) t- W
- LDA #$00
+ _+ M3 h' q9 W, } - STA M19_CHR_0000% ?7 m. a, f) {2 N* B$ s- k
- LDA #$013 l7 g6 e. K! x: B. W; o
- STA M19_CHR_0400
5 Q: {" r2 G8 Y, v - LDA #$025 i K5 d" w& b6 c2 N* `
- STA M19_CHR_0800+ z2 d6 e: @. m4 D
- LDA #$03/ I1 c9 U" q% ?7 c( E Z, Q- h
- STA M19_CHR_0C00* \8 j8 S5 b1 U4 _: x; N( a
- LDA #$04) l$ @% a! M2 x8 E- n# _. n5 y
- STA M19_CHR_10000 j) e! w# ?! @ T( L( n0 @
- LDA #$05
# t; | z% L0 C# J7 f, y - STA M19_CHR_14003 {) d' O- f7 m. h0 K
- LDA #$06
& B2 l/ S1 n0 [ - STA M19_CHR_1800
# ~$ |$ S$ V$ y, g4 U - LDA #$079 @4 w- j. O4 ?& K" s
- STA M19_CHR_1C00! t, _# o9 U5 F) E
-
: A. `: e# m( G& s; |8 @ k - ;禁用IRQ
/ p( s, ]' R& W1 T+ j4 v, y+ @ - LDA M19_IRQ_COUNT_H& a. w. q+ Y; }" W
- AND #$7F! Q1 h! w6 g6 Q- R7 H _% R/ z) [& ?
- STA M19_IRQ_COUNT_H8 v$ e" g# C, S( H
-
5 ?+ x% D$ [6 ^ - ;命名表; k( x: V. ^; q1 W. [( k
- LDA #$E0/ }' q A' l! |6 L: }
- STA M19_NT_2000
2 l& R/ R, S r2 n - STA M19_NT_2400
1 N7 i* v* `+ t -
$ ^; Q7 u5 s* ~3 R8 ~; `( { B - ;命名表
6 ^4 Q5 a9 S3 e: U/ V+ N: d - LDA #$E1
* `. ^( O; J9 ]# s/ r; c% E - STA M19_NT_28008 @7 ?" O6 R1 O9 ]& P# a
- STA M19_NT_2C002 R: Z" z; h7 {
- * {. U- O8 G; _' V% e' y1 w( q p, P) Z
- RTS7 h, j! C, H; u
- 9 ?$ z% _# _( ~( g. E
- ;==================================================
$ v, g% l8 O! i+ K- M - ;重置中断处理
1 k* y4 c5 ?% f% X/ D+ a) R) O - ResetProgram$ b \: t" @! b2 O) \/ m& v
- SEI
; ?* @0 f& ^# Z, [$ y' B; p - CLD( G/ D& K/ \9 y. f ^- l- f
- LDA #$00+ M" z/ a5 C5 e3 M) U) d6 {
- STA PPU_CTRL; ]% Q) }6 L+ p/ N
- STA PPU_MASK; q5 N! v0 M- @3 z2 b5 g; d
- STA PPU_STATUS5 N! S5 m; s3 V2 r% U5 w4 K
- STA JOY2_FRAME9 K8 s$ d/ P( [! T3 u3 U
- STA APU_STATUS
! F$ L! o8 w. d+ s; } -
4 R( f7 g1 X. t; `" k I4 W - LDA #$C02 Q' l' Y% x4 s. { U. O8 K
- STA JOY2_FRAME
" [2 m9 M3 z6 q% l7 L -
: ^) x" b8 F3 w& q9 L5 W4 N - ;等待vblank
2 q! }% r7 q$ P% P8 D9 ^ - LDX #$02
! Z. O: y0 Y) { - Vblank_Wait_1; N) \$ h1 a8 P# ?" M+ X
- BIT PPU_STATUS- `/ E0 m L, _& G0 D
- BPL Vblank_Wait_15 y. E- z2 e F: I/ m; F+ x- K
- Vblank_Wait_2/ T" Y; c% K6 e/ c3 k+ O+ w
- BIT PPU_STATUS, D& B3 F8 E, p4 {
- BMI Vblank_Wait_2
* e& @7 G4 w; B# a, b - DEX
$ c2 Y8 d! A& C: E9 L2 e$ X - BNE Vblank_Wait_1! \& P- N2 u+ N- t8 g
- ! ~" m+ l/ e! r+ x$ j
- LDX #$FF
6 v2 D3 h; E# U0 |% M+ E - TXS1 U' v0 w9 J) ]% z. Y- S
- & G) H N' c% a# j
- ;初始化MAPPER19, g) \, {* M% f4 o$ P$ a6 k2 u; u
- JSR Init_Mapper19
+ P. L8 i" e2 ~) |6 ` -
* D& [) \/ j& I) u7 M% U - ;==============================$ L0 m3 y3 k m' E
- ;RAM初始化' ^" S6 d) i1 G/ g7 O! H
- Nes_Ram_Init) H: Q- j% q5 D2 m
- LDY #$00
0 c4 p! w6 u- I/ N7 w( S8 ` - LDX #$087 @1 Z A+ V& h w! @+ u- v, X' H
- LDA #$00
$ W3 L+ w/ Z4 R4 w K" F( T - STA <$009 b' b9 `' O0 p8 g6 e7 Z6 u7 r# o
- STA <$01
. ], e8 Z. I& M) l9 [# A - Nes_Ram_Init_Write
. k. c: L3 j) F& P0 p& p - STA [$00],Y
5 e" g$ o$ m" v p. I/ ?, O$ U$ G - INY/ l, [( ]* c. a2 g0 D
- BNE Nes_Ram_Init_Write
) O% G" t% J. o" a - INC <$01
- }. k# j/ n8 s. D$ Y% s - DEX
+ F# P" ]2 R" x8 g' a# o4 h - BNE Nes_Ram_Init_Write
- i" D6 J. q: J2 j% i -
7 a4 ]7 k! }0 v- ~& W - ;初始化命名表- `+ u3 x8 H' f/ x" H5 l0 X
- JSR Init_Name_Table+ ]% w" G' s, p. a" p/ N/ H
-
: N( x: V0 D' z - ;初始化调色板3 H: G' q4 B2 }7 r* }( P
- JSR Init_Palette2 c9 V/ `0 S' E6 d1 d
-
6 i9 R! o/ H2 f5 k0 c" } - ;初始化命名表属性
7 {8 U5 y. g& {5 V - JSR Init_NameTable_Attributes) F8 ~) _5 _+ r( y
-
$ n8 e$ [$ u: Q# _- w' t. U - ;初始化精灵内存
# S/ k4 t+ a. a( \ - JSR Init_OAM_Ram) k' P( [0 h R0 U r2 A8 o s
-
8 f5 _, }- M" @+ v( y5 e - ;在屏幕上写点东西4 _4 f1 h0 D% W
- JSR Init_Name_Table_Text0 I4 c" C! J; @6 ^0 d8 g3 M
- ' ]- t$ B, m( a& K. r$ R
- JSR Time_For_Vblank7 W; x! u, q' d: e
- ;开启PPU控制$ ]" q: v0 A) B9 n9 w, { m
- LDA #$A8. z) K- |/ A( s
- STA PPU_Ctrl_Buf1 b0 c. \# u, w$ k# B: k8 s
- STA PPU_CTRL; _6 ?7 I( v$ [5 O6 W$ @0 p2 _
-
* m& a3 J# p: U) w7 A" e1 J - ;开启PPU显示
/ Q* y8 n; N% E" V4 g2 v - LDA #$1E8 D9 z* n* F8 F1 n3 t8 k# y& I
- STA PPU_Msak_Buf3 C4 p1 V7 V _
-
9 B- k* d5 }5 a. l& O. F - CLI
7 s: d2 r& w+ y3 m& K. ~7 Z - JMP Loop
1 H* E( v, W S" x4 n w/ M -
* [3 a7 c% B! \& i - ;==============================
" u: f3 L6 M4 G" |0 `. n: c1 S - ;死循环, 等待NMI中断
1 Q; ^) w# z0 S- T% Z( V - Loop
2 U0 o6 [# A7 `: g& P$ A - JMP Loop0 V1 E$ ~# V l0 N) O( @# c
- 3 P o9 V) a2 T6 d# ~" @
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
9 F; D/ @9 v9 H& J- s9 P; ?: p/ t - , h$ ]+ l, T: x' c4 d# B" I
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
% D$ q: d; w$ X( Q - BEGIN_LINE_CYCLES_START = 32768 - (4103)
b" i3 a1 f5 @( v' ^2 t2 K - ;==================================================5 Y& Y- T7 ]1 e. d7 }
- ;NMI中断处理
# ~: |% X6 T& l$ \ - NmiProgram) w0 B$ {" A! A8 D! j4 Z
- PHA
) F3 u$ R! M( I( G' G! n+ D. a - TXA; c3 [# v2 }; t7 P: c! S: c; u9 P/ O
- PHA
% x* e5 I: s' a: v. l; s1 d8 a( } - TYA
M! C0 n: ~: f0 O6 | - PHA
$ ?# u1 o1 h+ ]+ F - ! I# E1 U4 l3 U9 D+ p# E
- BIT PPU_STATUS
& i7 z3 L Y" W. k2 z- T -
! g6 M, r6 H( z: m' f1 |7 v - LDA #$003 l9 h, J. i% r& d
- STA IRQ_Index; \) y; S7 {8 ~4 d0 ~2 m- s
- 2 b3 N- Q: y5 q0 k1 ~9 E- A- s
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动4 z6 r W& v( `/ {- Z( ~
- LDA #LOW(BEGIN_LINE_CYCLES_START)
, N6 m: {0 ?+ _* V - STA M19_IRQ_COUNT_L$ N! s8 l: U# o/ T. N' a- u8 ~4 Y
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
$ G, a/ t3 y5 h5 w( l - ORA #$80+ z0 R) K% O6 s% q' U E o
- STA M19_IRQ_COUNT_H) @5 @5 T# ?3 T+ R) B
- CLI
9 b3 e0 P( m9 b' m8 a$ d - 4 n8 B5 E' S/ W% @3 _8 Y* G
- ;关闭PPU控制
; Z/ B* j: h/ w2 Y9 ~. S% w - LDA #$00
9 A [5 s' ^% U H9 S - STA PPU_CTRL4 T+ \$ h) ]- M. C( ~+ } I
-
5 K P7 x9 u* n: \ - ;处理PPU( h5 s y/ [, v: D# ~, N
- JSR PPU_Process
% t% \9 \" }3 d -
# |+ {, v( c& k7 E" a o3 @3 T# Z - ;开启PPU控制( Y: T, q7 j0 z4 u4 I, I
- LDA PPU_Ctrl_Buf
$ i; O$ j0 p8 b9 e7 r; f/ ] - STA PPU_CTRL" m, z" I+ f4 H% G2 u! S) d. a0 g
-
2 M9 M* D, M2 { - ;手柄处理, @- W* c- {' T$ j; J- M
- JSR GamepadProcess
3 S7 F4 E: ^+ d. j3 t -
) G N. ^: \4 [" t' U- r R - LDA #$00
; b7 u$ }7 s% |& g% u! l - STA IRQ_Index
+ K F8 n# F& H( `1 \$ E9 } - % p7 n: S' Q! Y: J8 }: j+ L; X% s" ~7 e
- PLA
4 L8 k! V) I1 c, V \+ d* B5 s$ ? - TAY
1 k% ]% m4 o7 K" g$ { - PLA; C; ]+ o( `; v) U( B$ r; o: K
- TAX# R5 }7 k5 D! q( O' z8 |% H
- PLA: A; Q, a7 F- ], W* C) w
- RTI1 p- F# z# v8 @1 ~8 s* u
8 P) S! A, V5 e7 }- N- ;每行扫描线113.67
4 m0 l4 n) @" W! M. x3 v - ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
7 \. s7 k+ ]! n) U6 y* @% R - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7. E. V# N6 d% Y8 s' U( m+ u
- ;==================================================1 n2 k \0 J" U( s. _$ S0 r* E1 |# N, O& }
- ;IRQ中断处理
1 x9 Z( W. _) g! g3 Y - IrqProgram
. M2 O# s$ o. f: O - PHA# T0 U8 P$ U4 C
- TXA$ e7 Y! D1 M7 S* r1 w* D. I" [
- PHA
/ F2 Y6 b# \8 H& Z; i - TYA. E2 |+ Z& F$ x3 s& @3 a
- PHA/ T6 Z, I* _8 p1 N* z% K, A* E
-
! J: ]. f$ d& Z - ;16条扫描线后触发IRQ
( O+ h, @( I$ P d& s - LDA #LOW(BEGIN_LINE_CYCLES)( Z& T2 \# Z2 w
- STA M19_IRQ_COUNT_L% z q( c+ c& w8 c) f0 W6 }
- LDA #HIGH(BEGIN_LINE_CYCLES)
7 S3 S0 }# h3 u0 g9 O" L; w - ORA #$80( B' D% `1 |) r# A* o5 ~
- STA M19_IRQ_COUNT_H
9 Q5 y4 \' J* P1 d- \. Y -
* A0 U& q" m- O; n c; j - LDA <IRQ_Index5 D7 t1 Z6 o5 | U( ~
- BNE * + 4" i# U0 X- O8 P6 ^, D6 `
- INC <PPU_Scroll_H2 c" @# ^' e W6 u! C! k
- / u! r' p* n& M L
- ;设置屏幕滚动
9 ] m: w, }: O* e - LDA <IRQ_Index
4 c+ Q) S% e& ^' L* R/ O - AND #$01
; i$ X' G/ x0 f) [ m ~, S: W% V - BEQ Irq_Scroll_Right
% W0 C, L" p, u! `+ O( G - 7 V5 @! G3 k$ N8 [
- Irq_Scroll_Left
/ j- E$ n2 a* r% {7 H - BIT PPU_STATUS
& t, R4 j9 L; t: N/ b - LDA <PPU_Scroll_H
5 F: b1 d2 ^) M! L - STA PPU_SCROLL3 P+ V7 V& @/ g, [5 W( p9 w a
- STA PPU_SCROLL# M- Y- U0 l7 Q) C" M7 f
- JMP Irq_Scroll_Over4 _5 y8 n0 F8 r! K0 h/ i8 u
- # J6 @# R1 i6 G a& U
- Irq_Scroll_Right
9 s2 R: H& I) Q' X4 n' Y - SEC$ y y" s: Q0 m# U8 A; m
- SBC <PPU_Scroll_H( a, ]7 R- w7 x) _
- STA PPU_SCROLL6 i* i# Y" i7 B! Q
- STA PPU_SCROLL
9 D: F) ^' ` B& V - Irq_Scroll_Over* E( k1 p, Q2 s8 n8 k8 Z- j
-
' s# H$ ^2 g, s; X; R% x+ @ - INC <IRQ_Index; @+ `$ S# v0 }( I. Y2 u7 Z
- 4 W9 V6 p C9 A2 y3 M
- LDA <IRQ_Index; d* a- C' [6 {6 v F7 c* ]( `: l8 A% W! |
- CMP #14
$ U% K# Y3 Q! Q& U% [ - BCC * + 10
; N. u1 n E+ e8 z2 S" g - LDA #$00
3 Z7 \' G0 t2 [ j R* ] V( m8 t6 V - STA M19_IRQ_COUNT_L
) ]# u- U7 ?. _5 `$ P: F7 F - STA M19_IRQ_COUNT_H
. G2 ~8 z$ c% M8 ^0 g+ g' C T8 n -
2 F- j8 g0 I2 g4 E - IrqProgramEnd9 i2 @& N: J6 }$ q0 _
- PLA
: Q' [. m" C* M - TAY
; r- b. X! q2 S - PLA
- B m: B( o# f" ^, h - TAX) M0 ^* v' }- B0 @/ j! P" e8 d
- PLA! g. T9 g! H$ d! e! s
- RTI
- ~! n' F( ~; l, X! @ - ) ?$ }- a, `' `* Y+ r
- ;==================================================
: l3 U: W+ J" J& |, I/ A- @8 a3 Z1 O - ;中断表
* f1 T, e! l2 k: M - .ORG $FFFA% l: u0 ^" O* h. ?5 y& d' X
- .WORD NmiProgram. z1 X k% @/ {8 T, x; c& u3 }3 ]; W: J
- .WORD ResetProgram5 z9 `9 L" g% h( D9 ?& w
- .WORD IrqProgram
复制代码 ' f, K9 v+ O5 b! D) k* B
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|