Jump to content
  • 0
JohnGill

saving memory to a file?

Question

Hi all,

sorry to keep bugging you guys!

Next issue on my to-do: I'm writing myself a tool to convert lots of .bmp images into a single binary file that I can load into VRAM as a tileset.

On the C64, there was a great little trick where you could SAVE arbitrary blocks of memory to a file by poking 43-44 with the start address and 45-46 with the end address of the block you wanted to save.
eg, if I wanted to save memory locations 5000 to 6000. I could write:-

POKE 44,5000/256:POKE 43,5000-256*PEEK(44)
POKE 46,6000/256:POKE 45,6000-256*PEEK(46)
SAVE "DATA",1,1

I'm assuming the zero page values on the CX16 are not compatible with the C64 - does anyone know if there's a similar trick to the above that I can use on the CX16 to save off a block of memory?

 

thanks in advance

John 

  • Like 2

Share this post


Link to post
Share on other sites

16 answers to this question

Recommended Posts

  • 0
Posted (edited)

Apparently load and save routines are still in their infancy within the X16 roms.

I’m really just learning this myself. Here is how I tackle such problems:

By looking at the source of X16-Columns I’ve found a library called libx16 that has load and save functions.
https://github.com/CJLove/libX16/blob/29bf20c869c56eef51b5984cbe03b9e7fb12a2dd/src/save.c

Compiling save.c with cc65, I can get the assembly of those functions that are a good starting point for writing my own routines.
Compiling to assembly works like this:

cl65 -t cx16 -S save.c

I’ve attached the assembler output to this post.

I hope this helps.

 

save.s

Edited by Sandmage
  • Like 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Also, to add to your initial question. I didn't know about this C64 trick, but what it probably does is bend the address of the save routines to point to something else than the start of the basic ram. It should be possible to do this on the X16 as somewhere that save routine has to get those adresses too. The actual locations will definitely be different. Also, I don't understand why this should work as the SAVE function should overwrite those memory locations.

I've looked at the kernal-rom. In kernal/cbm/channel/channel.s are two defines that look to me like they could be the starting and end adresses:

sal .res 1           ;$AC
sah .res 1           ;$AD
eal .res 1           ;$AE
eah .res 1           ;$AF

If this is correct starting address might be be in $AC (172) and end address in $AE (174).

POKE 173,5000/256:POKE 172,5000-256*PEEK(173)
POKE 175,6000/256:POKE 174,6000-256*PEEK(175)
SAVE "DATA",1,1

Or, I could be totaly wrong.

There is also a disclaimer that no zeropage adress is fixed as the kernal is still in development.

 

Edited by Sandmage
  • Like 1

Share this post


Link to post
Share on other sites
  • 0
2 minutes ago, Sandmage said:

Also, to add to your initial question. I didn't know about this C64 trick, but what it probably does is bend the address of the save routines to point to something else than the start of the basic ram. It should be possible to do this on the X16 as somewhere that save routine has to get those adresses too. The actual locations will definitely be different. Also, I don't understand why this should work as the SAVE adress should overwrite those memory locations.

I've looked at the kernal-rom. In kernal/cbm/channel/channel.s are to defines that look to me like they could be the starting and end adresses:

sal .res 1           ;$AC
sah .res 1           ;$AD
eal .res 1           ;$AE
eah .res 1           ;$AF

If this is correct starting address might be be in $AC (172) and end address in $AE (174).

POKE 173,5000/256:POKE 172,5000-256*PEEK(173)
POKE 175,6000/256:POKE 174,6000-256*PEEK(175)
SAVE "DATA",1,1

Or, I could be totaly wrong.

 

some great investigations there, thanks so much sandmage - will try this out! 

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

It's very like wrong.

The C64 KERNAL ROM has those same declarations at $AC and $AE. So those are not the right numbers. And 43/44 is a pointer to the start of basic-ram on the C64.

Now it depends on whether the basic ram start and end adresses are hardcoded on the X16. Basic RAM starts at $0800 on the X16, so if there is apointer to the start of basic on the zeropage, it should be initialized with $00 and $08. This appears to not be the case.

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Actually, wrong again. Since the pointer to basic ram on the C64 points to $0801 not $0800, I was looking for the wrong numbers. On the x16 223/224 ($DF/$E0) read 1 and 8, so that should be the pointer. Also,  writing to these adresses changes the basic programm in memory. However, the two bytes following both read 0. Changing 224 to 9 clears the basic programm, however, entering a basic line locks up the emulator.

 

Edited by Sandmage

Share this post


Link to post
Share on other sites
  • 0
16 hours ago, Sandmage said:

Actually, wrong again. Since the pointer to basic ram on the C64 points to $0801 not $0800, I was looking for the wrong numbers. On the x16 223/224 ($DF/$E0) read 1 and 8, so that should be the pointer. Also,  writing to these adresses changes the basic programm in memory. However, the two bytes following both read 0. Changing 224 to 9 clears the basic programm, however, entering a basic line locks up the emulator.

 

thanks so much for looking into this sandmage. it seems this C64 trick isn't going to work on the CX16. I've asked on the facebook CX16 also, and the consensus of opinion is that it can't be done in basic. Seems I need to learn some kernal assembly chops to do this!

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

Your welcome. It was interesting for me too. Doing this in assembler shouldn't be difficult. Look at my first post. Using a trick like this wouldn't be the recommended way anyhow.

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Hi all, I've had a crack at writing some assembly to write a 4096 byte block of data to a file using the kernal.

My BASIC program pokes the start address of the block to be written to ZP $00 (LSB) and $01 (MSB) - the assembly should do everything else. I've written this in CBM PRG studio - it compiles fine, and I can run it with SYS $2000, and it RTS's back to BASIC without crashing. But no file is written. I thought this should be within my (very limited!) assembly prowess but I'm guessing I've made a glaring noob assembly foul up. Can anyone identify what I've done wrong? Please and thank you!

*=$2000
target TGT_C64
; this routine saves the
4096 byte block of memory, with a start address
; pointed to by the two ZP bytes: ; #$00 ; #$01 ;
; filename is the label to the memory address holding the actual filename


filename
byte "tilemap.prg"


; set up parameters for SETLFS
lda #$01
ldx #$08
ldy #$00
; call SETLFS

jsr $FFBA


; set up parameters for SETNAM
lda #$0B ; length of the filename "tilemap.prg"
ldx #<filename ; low byte of address of filename
ldy #>filename ; high byte of address of filename
; call SETNAM

jsr $FFBD


; set up parameters for SAVE
lda #$00 ; points to memory address ZP $00, data already poked in basic
ldx #$01 ; x/y points to end of 4096 byte block to be saved
ldy #$10 ; x = LSB, y = MSB ; $1001 for 4096 block + 1 bytes
; call save

jsr $FFD8

rts

Edited by JohnGill
  • Like 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Unless you explicitly read somewhere that you should add 1 to the end adress, I would guess that's wrong. End adresses are usually inclusive. But that's not the mistake. You cannot use Zeropage $00 and $01, because that's the CPU Port. I would try $70/$71. According to documentation everything untul $7F is free. But to be save, use something at the end of BASIC RAM.

Edited by Sandmage
  • Like 1

Share this post


Link to post
Share on other sites
  • 0
13 minutes ago, Sandmage said:

Unless you explicitly read somewhere that you should add 1 to the end adress, I would guess that's wrong. End adresses are usually inclusive. But that's not the mistake. You cannot use Zeropage $00 and $01, because that's the CPU Port. I would try $70/$71. According to documentation everything untul $7F is free. But to be save, use something at the end of BASIC RAM.

aah, thanks. I must have mis-read the latest version of the programming guide, I thought $00-$01 were free to use.   According to this: https://sta.c64.org/cbm64krnfunc.html I must add 1 to the end address, so I'm guessing that's right

 

Share this post


Link to post
Share on other sites
  • 0

Bah. Just recoded it with $70 / $71 instead of $00 / $01 and still no file written. Hmm. More head-scratching...!

Share this post


Link to post
Share on other sites
  • 0

Yeah, my mistake. And also, unlike the 6510 the 65C02 does not have a CPU port, so that's not what is wrong either. I cannot spot the mistake. Maybe try device 1 instad of 8. I think 8 is the SDcard, while 1 is the host filesystem, but I could be mistaken.

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)
20 hours ago, Sandmage said:

I think I've found the answer: According to this thread, the arguments for SETLFS are wrong:https://www.lemon64.com/forum/viewtopic.php?t=59083&sid=427e03cdae2d9890966ee5ebe2e74b81

lda #$00
ldx #$08
ldy #$01

 

Thanks for this sandmage. I've been told the SETLFS for the CX16 are different to the C64 - apparently 1,8,0 are in fact correct. Matt Heffernan on the facebook CX16 page has cracked it - in the 'SAVE' setup, I was setting X and Y to the *block size* +1 (ie, 4096 bytes, $1000) whereas I should have been setting x and y to the *absolute* address +1 of the end of the block to be written ($6000) . It was trying to save a block of data that runs backwards from $5000 to $1000! no wonder it couldn't write anything! Just as I thought - noob foul up on my behalf! Many thanks for all your work on this one.

Edited by JohnGill
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use