|
|
本帖最后由 yandagui 于 2017-4-28 14:17 编辑
) ?7 p7 m2 \4 e, y2 B1 k1 W& i( e; i/ N& ]" ^
;[FC][任意数据搬移到$6000-$7FFF] BY FlameCyclone1 J& x, \* y/ R( U8 K9 b9 O, Z
;2017.4.28; y8 ^9 L! q- q) ~* w0 i4 }7 @
;例子:双截龙3
. r# Z+ _* l8 H' S3 a1 K1 V .ORG $8100 ;定义程序开始地址- Y# @$ Z- c6 ^ N4 [+ g% U
JMP Copy_Data_Start ;跳转到复制程序7 d9 y5 j6 y9 l/ Q4 Q @
* w+ P6 u0 Q$ J2 xAddr_To: ;目的写入地址3 |* J/ a+ ^% H L
.BYTE $00,$70 ;想要复制到的地方
3 p. }9 I! o. I, ~# KAdd_Begin: ;源开始数据地址
! l' V) Z* I0 V+ q .BYTE $00,$82 ;想要从何处开始复制3 e V1 Y) |: L2 z% D
Addr_End: ;源结束数据地址
; N# H, D. _9 y0 @( L .BYTE $EE,$91 ;想要从何处结束复制7 ]5 o V& L& X2 G, @8 |$ @
9 R9 i( G. k1 ^$ s& q% }& V0 ^; |
INT_Addr = $A0 ;中断地址
# a7 G% R, R1 N) UFlag_Over = $7FFF ;完成标志地址 P& D3 v" w1 \8 `/ ~+ \
Data_Over = $7F ;完成标志
& k, g* ]9 X4 P6 W- F
) I6 ~4 P, k+ b; p- _
/ ^2 z8 C1 U! @( V* o* ^! LAddr_Data_TO = $A0 ;目的写入地址. h/ A! g' ~& u
Addr_From_Start = $A2 ;源开始读取地址
, i3 b! T, K- m" i+ _1 I/ u* aAddr_From_End = $A4 ;源结束读取地址+ D$ S5 h# B6 c3 `) O0 @
7 M H9 `9 v& ?/ v( {) e: U. fCopy_Data_Start:
, @3 h( ~8 k" T6 ^& k7 `+ @3 d. J; fData_Copy_Protect: ;保护数据4 X6 m- e: F/ k: V: x8 N1 x
PHA( `' r# p/ K* ^9 ~9 w7 K
TXA
' x! X- P! O O- ^6 P PHA
2 _ u1 z V$ `2 b! h+ n I" n5 J TYA
5 H) p# T5 X% U! a; ?, \" l& _! b PHA
8 Y2 B# W* s3 [: i& p- c JSR Off_INT ;跳转到禁用软件中断
. m, N2 f- ~, C6 G& J1 g4 {0 x6 b LDA Addr_Data_TO9 U( v9 T& e) e+ t$ O6 K6 y
PHA
4 I: x" G0 X2 ?% {; R) F& j% {1 j LDA Addr_Data_TO+1
! q( {$ c& u$ B. f$ L1 [" {7 p PHA# B$ e9 k: _( h
LDA Addr_From_Start) k- r# A: ]# ~* |. _
PHA
% L3 t$ k$ P' u3 i. O2 R" l LDA Addr_From_Start+1
) i8 R1 w' B- x1 b. J7 T PHA1 ?1 o* Z9 M( u$ \
LDA Addr_From_End
9 ^8 J+ p$ W4 E* Z- X6 ] PHA5 B; M* j% C! ~# Q, T6 I
LDA Addr_From_End+1
6 N7 t5 m. O: K H. k. ~* K PHA
8 @! C+ p* a* Q2 Y! R7 @9 ]0 z* g
x9 M0 B* @9 o: w2 e& M6 n; P3 D8 xSet_Data_Addr_Start: ;设置复制起始地址) m7 j% U, I' R2 Q2 G! y
LDA Add_Begin- h( U$ K3 C" H* T* b$ o
STA Addr_From_Start ;设置复制起始地址低位2 s! x. { Z: }7 ]
LDA Add_Begin+1
) [+ i/ m3 s b% v0 w9 M( C STA Addr_From_Start+1 ;设置复制起始地址高位3 T+ m p2 v/ i# S
& s; S* v0 j5 rSet_Data_Addr_End: ;设置复制结束地址
$ \- l' J% J+ v* z LDA Addr_End
7 }# H; c& |* Y6 l4 z STA Addr_From_End ;设置复制结束地址低位; H% u% s7 b9 k. Z4 z( V
LDA Addr_End+1 t8 I. o2 ?, e7 s6 s
STA Addr_From_End+1 ;设置复制结束地址高位
( S+ e! V' c5 Z! m 5 _: }- k- N$ D
Set_Data_Copy_Start: ;设置目的起始地址
, E7 q6 X" U. k LDA Addr_To
+ Y% o4 h3 a4 a9 k6 A# ^9 q STA Addr_Data_TO ;设置目的起始地址低位
9 _! O% a0 S8 @* G LDA Addr_To+1
3 S8 _; { [1 e# ^ STA Addr_Data_TO+1 ;设置目的起始地址高位) I2 V5 L; Y9 t. w
0 l* |6 P- H8 U+ R+ sOver_Copy_Cmp: ;复制完成比较) F* V' @# p# X9 T5 j
LDA Flag_Over
+ Z/ [3 o% m- @% Z) Z CMP #Data_Over ;复制完成标志比较
1 d2 Z1 ^" P2 {1 ~* N9 O$ P BEQ Data_Copy_Exact( A0 i. p% C: K
. _, H2 X. p( e# d" l$ J0 C2 dINI_XY_Count: ;计数器初始化. f' Y+ R% Y+ g
LDX #$00
8 E k5 U1 L1 l* k% p4 H/ Y( z LDY #$00' }1 d6 g& r2 k# L2 z0 c
' j) @* O# P6 H0 ^ b
Copy_Over_Cmp: ;地址比较
! {: n3 A2 V K. F FCmp_Addr_Data_TO: ;写入目的地址越界判断(向$6000前写入)
# n1 }* S; ^8 F LDA Addr_Data_TO+1
, T/ e: F! ?$ U: D! n CMP #$600 A* `" } {9 }6 b& A4 g$ r
BCC Data_Copy_Exact ;写入目的地址小于$6000时结束复制
: `& i% A! a% q$ Z8 U2 o. F1 LCmp_Addr_Data_TO_H: ;写入目的地址越界判断(向$7FFF后写入)
0 s ?! m, s8 v# P% x. ], @, D% l- u* I LDA Addr_Data_TO+1
; b) y" f$ y, } CMP #$80
5 U, `! j2 T3 k8 f( }- O* y BEQ Data_Copy_Exact ;写入目的地址大于$7FFF时结束复制
; \: n0 r* z: M, f: t& @; r6 T
5 E+ Y+ F2 S9 w qCmp_Copy_FREE: ;源地址结束判断
0 F4 {8 |1 |* ]( _. N# w+ n# f$ E LDA Addr_From_Start8 f s( z4 k) Y. C: d) n
CMP Addr_From_End1 ?, Q1 S- n" k |! v$ v [ Z4 z; f
BNE Copy_Start
) U, q7 N7 J6 z7 {6 W LDA Addr_From_Start+12 a4 T: x G0 U7 ^' J; h
CMP Addr_From_End+1
6 Z7 H* V1 s" F' a% G7 z BEQ Copy_Over8 `1 {6 k$ T$ o/ P5 f
! T7 ^* D6 c x, T1 GCopy_Start: ;数据复制开始
. D. E r2 D4 u9 x+ E LDA (Addr_From_Start),Y ;读取源地址
! c" B/ q1 v2 y8 @# K STA (Addr_Data_TO),Y ;写入目的地址
% F' L0 a' a: E/ d% }- GCopy_INC_From: ;源地址低位递增
/ m! k I. y7 b [' M INC Addr_From_Start ;源地址低位递增! B' T, n8 \7 i3 b. v8 ]: \" k
BNE Copy_INC_TO; r" O1 I2 k- l$ o* S
INC Addr_From_Start+1 ;源地址高位递增9 u: w6 ]: o3 P1 `
Copy_INC_TO: ;源地址高位递增
) w* t. _- ]0 R INC Addr_Data_TO ;目的地址低位递增
' R/ b" P' |4 q) B BNE Recopy; p$ V. N( \9 `* L; q
INC Addr_Data_TO+1 ;目的地址高位递增
' L m& J4 N1 Z7 ?9 RRecopy:
- F; ~# F7 p- l: i2 p% [4 j JMP Copy_JMP
3 R# K" `, F9 X3 |/ \ 0 ?4 D6 z" N2 L1 ^ N! n
Copy_JMP: + g/ y5 q) u3 R( a
JMP Copy_Over_Cmp) {' Q. g) P# ]4 p& S/ k1 D
* {9 T6 U: t8 l( k& Q( M
Copy_Over: ;复制完成+ s1 b' d; I" c/ R: u
LDA #Data_Over
: Q7 Y0 b9 T9 |/ _* t$ R STA Flag_Over ;写入完成标志, |* p0 G+ f r6 k# q
FINAL_BYTE:% Z+ X6 j5 R4 P* r
LDA (Addr_From_Start),Y ;读取最后一个字节
' I) K! | R }$ N0 m ~ STA (Addr_Data_TO),Y ;写入最后一个字节" \" E/ y) ?9 E6 c; W8 P
6 x9 d K. \+ \0 p3 D* ], |0 V
Data_Copy_Exact: ;恢复数据4 w7 a1 b( Z( V( P; }, F3 F$ h U
PLA3 |# W3 S6 ^4 j
STA Addr_From_End+1% ^# ?. C. D8 s0 r; n9 M! x) w
PLA, Y2 g7 a+ _. X$ u3 S+ R% W5 {
STA Addr_From_End
$ z7 l6 f+ B/ ? PLA8 b; e2 q) r- V. ]/ @' R; T
STA Addr_From_Start+1
3 ]6 d/ U1 ` f4 q7 j: z0 d( a8 z PLA7 Z* L, o- C0 V5 ]$ {& L1 @0 m
STA Addr_From_Start
* j+ S! l* E, p' J+ v PLA* J4 {4 z* z2 q
STA Addr_Data_TO+16 @5 u- T1 L5 ]2 j* z) [8 ] \ f
PLA
) e1 L1 F/ d8 D* i STA Addr_Data_TO
, P& O4 ?+ W$ g: ^: [ PLA
* Q8 g! @8 }4 c; e/ b TAY
1 ] J; n1 y' e0 J, [ PLA
; {! K( z7 r5 V0 A( b TAX
f' `/ r% j3 I8 h PLA
: P1 V& ~3 P6 w- g- x% c 1 o* [: j' w9 X: q" ]( z; G, f' i
Data_Copy_Return:; n" r+ {7 }" k6 T, R3 O* O
JSR Rec_INT ;跳转到恢复软件中断数据
- Z% A9 O+ q3 D& C& P) t5 D RTS; B' _0 O: b0 N k
+ w K6 B% E- w& S0 FOff_INT: ;禁用软件中断6 m6 S8 n3 |. r+ }2 i% ~
LDA INT_Addr
5 e% j% y$ ]7 e2 N6 N AND #$7F+ y# u/ ]& O9 m) z+ [: [# ]
STA 20009 O' H! ~. ^8 i
RTS
0 i/ C* Q) d3 L9 g* @6 v
/ }. ]/ N: |$ p7 tRec_INT: ;恢复软件中断数据
( F4 n8 E! F! O LDA INT_Addr# ]! ^/ F! L6 B* B. |# ~
STA 2000
4 C* P7 \, x8 `. j RTS |
|