| |
Laxity
Registered: Aug 2005 Posts: 459 |
Saving from one memory location, loading to another!
Ok.. Maybe some'o you guys know how to do this:
I wan't to save a file, say from $c000 to $ce00. The file should however load to adress $1000 to $1e00 when loaded normally (like: load "foo",8,1). How am I going about this problem?
I was thinking that I could write each byte of the data to disk, and since the two first bytes of a file is the destination memory pointer I could start by writing $00 $10 in this case and then the data from $c000 to $ce00!.. Is this correct?
Cheers! |
|
| |
hollowman
Registered: Dec 2001 Posts: 474 |
this has been discussed before, unfortunately without any good answers, http://noname.c64.org/csdb/forums/?roomid=11&topicid=10710&show.. Saving files using Kernal |
| |
HCL
Registered: Feb 2003 Posts: 728 |
If you're using the kernal saver, it woun't work. I had the same idea in ByteBoozer, but then i ended up transfering all data (to where it should be when loading) before saving. Totally lame :/. |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Quote: Ok.. Maybe some'o you guys know how to do this:
I wan't to save a file, say from $c000 to $ce00. The file should however load to adress $1000 to $1e00 when loaded normally (like: load "foo",8,1). How am I going about this problem?
I was thinking that I could write each byte of the data to disk, and since the two first bytes of a file is the destination memory pointer I could start by writing $00 $10 in this case and then the data from $c000 to $ce00!.. Is this correct?
Cheers!
This is exactly correct!
example:
lda #$00
sta $90 ;status
lda #$61
sta $b9 ;secondary address
jsr $f3d5 ;iec-open
lda $ba ;device number
jsr $ffb1 ;LISTEN
lda $b9
jsr $ff93 ;SECOND
lda #<ADDRESS
jsr $ffa8 ;CIOUT
lda #>ADDRESS
jsr $ffa8 ;CIOUT
;* the main write loop
lp1:
lda (currzp),y
;* write byte to IEC-bus
jsr $ffa8 ;CIOUT
;* check status, exit if fail
lda $90
and #%10000011
bne fail1
;* increase address and check for end
inc currzp
bne skp1
inc currzp+1
skp1:
lda currzp
cmp endzp
bne lp1
lda currzp+1
cmp endzp+1
bne lp1
;* Normal exit, clean up and CLEAR carry.
jsr $ffae ;UNLSN
jsr $f642 ;iec-close
clc
rts
;* Failure exit, clean up and SET carry.
fail1:
jsr $ffae ;UNLSN
jsr $f642 ;iec-close
sec
rts
|
| |
Laxity
Registered: Aug 2005 Posts: 459 |
Oh.. Thanks a lot.. Example code even.. Makes it so easy I don't even have to think for myself ;) |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
I'm home with a cold, so I have nothing better to do. :)
Sorry for spoiling the fun... |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Using Action Replay or comparable,
s"file",8,c000,ce00,1000
will do the trick.
From within a program, what tlr said.
But if you want it faster than plain kernel, 1541/40/70/71-only and with playing a tune while saving,
check: Plushdos for the irq1bit saver. |
| |
TNT Account closed
Registered: Oct 2004 Posts: 189 |
It might be nicer for IDE64 & MMC64 folks if you used standard open/chkout/chrout/clrchn/close instead of IEC-specific routines. |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Quote: It might be nicer for IDE64 & MMC64 folks if you used standard open/chkout/chrout/clrchn/close instead of IEC-specific routines.
I always did this with straight IEC-stuff, but I kind of figured it could be a problem with stuff like IDE64, MMC64 and similar...
Could you post a version doing the same as my code, but with straight I/O?
|
| |
TNT Account closed
Registered: Oct 2004 Posts: 189 |
I will try to remember to do that tonight with IDE64. There is currently no device emulation for MMC64, but I'm writing one for MMC64+RR combo. If everything works as planned all IDE64 fixed programs should work with it (as long as they don't overwrite $DExx as I'm running code in Retro Replay RAM). |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Great!
A related question: doesn't the IDE64/MMC64 supply a patched kernal? I believe that a lot of (old) software does direct IEC-calls, but uses no turbo, or other stuff that will make it impossible to run without patching. |
| |
cadaver
Registered: Feb 2002 Posts: 1160 |
At least IDE64 doesn't. |
| |
TNT Account closed
Registered: Oct 2004 Posts: 189 |
Both IDE64 and my patch only touch vectors at $03xx. That's why you can't use direct calls which bypass these vectors. In the easiest case IDE64 fix only requires changing all those calls to their patchable versions. |
| |
TNT Account closed
Registered: Oct 2004 Posts: 189 |
This one works with 1541 and clones as well as with IDE64.
setlfs = $ffba
setnam = $ffbd
open = $ffc0
close = $ffc3
chkout = $ffc9
clrchn = $ffcc
chrout = $ffd2
; make some test data
ldx #0
init txa
sta buf,x
inx
bne init
; and save it
lda #1
ldx $ba ; use last accessed device
ldy #1
jsr setlfs
lda #4
ldx #<name
ldy #>name
jsr setnam
jsr open
ldx #1 ; make it default output
jsr chkout
lda #<address ; send wanted address
jsr chrout
lda #>address
jsr chrout
lda #<memstart ; set memory start and end addresses
sta $ac
lda #>memstart
sta $ad
lda #<memend
sta $ae
lda #>memend
sta $af
ldy #0
lp1:
lda ($ac),y ; write byte to device
jsr chrout
lda $90 ; check status, exit if fail
and #%10000011 ; you could use jsr $ffb7 instead
bne fail1 ; of directly reading $90, but it
; really doesn't matter
jsr $fcdb ; bump $ac.w
jsr $fcd1 ; compare it to $ae.w
bcc lp1 ; loop if not equal
clc ; successful return
dc.b $24 ; bit $nn, hides "sec" below
fail1 sec ; error flag
php ; remember status
jsr clrchn ; restore default output
lda #1
jsr close ; and close file
plp ; restore status
rts
name dc.b "DATA"
buf ; our data will be here
address = $c000 ; it will load into this address
memstart = buf ; and these are for readability
memend = buf+256
|
| |
tlr
Registered: Sep 2003 Posts: 1790 |
@TNT: Clean and compact, nice! :) |
| |
Wanderer Account closed
Registered: Apr 2003 Posts: 478 |
Why not just transfer the code?
T c000 ce00 1000
then save
s "filename" 1000 1e00
Your method of changing the first two bytes will work of course. I've used that myself since the emulator/monitor I use is very unfriendly. |
| |
Graham Account closed
Registered: Dec 2002 Posts: 990 |
Why that complicated? You can use the standard LOAD vector for loading to any adress, and it is compatible with all fastloaders too. |
| |
Laxity
Registered: Aug 2005 Posts: 459 |
Quote: Why not just transfer the code?
T c000 ce00 1000
then save
s "filename" 1000 1e00
Your method of changing the first two bytes will work of course. I've used that myself since the emulator/monitor I use is very unfriendly.
Sure that'll work, but would be unusable in a tool. "Press F1 for instructions on how to save"!.. Nah.. don't think so! ;) |
| |
Laxity
Registered: Aug 2005 Posts: 459 |
tlr & TNT, thanks for sharing. I appreciate it! |
| |
TNT Account closed
Registered: Oct 2004 Posts: 189 |
Quote: Why that complicated? You can use the standard LOAD vector for loading to any adress, and it is compatible with all fastloaders too.
Load instructions:
poke 43,0:poke 44,16:load"file",8:poke 43,1:poke44,8
?
Rather than have wrong load address I would rather have totally bogus one ($0000 anyone?) so it would be clear what's wrong if I don't jump through all the loops required to load file correctly. |
| |
hannenz Account closed
Registered: Nov 2002 Posts: 24 |
Quote: Why that complicated? You can use the standard LOAD vector for loading to any adress, and it is compatible with all fastloaders too.
yes. just load the file as follows, this method ignores the file's load adress and will uzse the given one. and it uses kernal i/o only.
;load to ANY adress...
load_adress = $xxxx
lda #1
ldx $ba ;last used device
ldy #0
jsr $ffba ;setlfn
lda #fn1-fn
ldx #<fn
ldy #>fn
jsr $ffbd ;setnam
lda #0
ldx #<load_adress
ldy #>load_adress
jsr $ffd5 ;load
fn .text "filename"
fn1
|