Jump to content
  • 0
Zakero

File is not loading to expected address

Question

Wrote a short assembly program to load a file into memory address $2000 but the file is not being placed in the expected address.  The file contains 256 bytes with a value of #$11.  All 256 bytes are #$11.  This was to make it easier to see where the file was loaded into RAM.

The expected address to find the data was $2000, however the file was loaded at $1111.

It was my understanding that when setting up the Logical File, I could set the Secondary Address to (LDY) #$00 for a relocated load.  When loading the file, I would then specified the $2000 address.

If I had set the Secondary Address to (LDY) #01, then I would expect the first two bytes of the file to be used the destination address.  This does work.

But hard-coding the destination address does not work.  Below is my code, if that would help clarify what I am talking about.

Can someone enlighten me as to what I am doing wrong or misunderstanding?

 

; ca65 formatted code
.pc02

load_file:
    ;---------------------------------------
    ; Set the file name
    lda    #(filename_end - filename)
    ldx    #<filename
    ldy    #>filename
    jsr    $ffbd    ; KERNAL::SETNAM

    ;---------------------------------------
    ; Setup the logical file to use
    lda    #$01    ; The File ID to use
    ldx    #$08    ; Device 8 = Disk Drive
    ldy    #$00    ; Secondary address of 0
    jsr    $ffba    ; KERNAL::SETLFS

    ;---------------------------------------
    ; Load the file
    lda    #$00    ; load to memory (1 = verify)
    ldx    #$00    ; at address $2000
    ldy    #$20
    jsr    $ffd5    ; KERNAL::LOAD

    ;---------------------------------------
    ; Did it work?
    bcc all_good
    stp    ; Break into the debugger
        ; Register A has the error code
all_good:
    stp    ; File loaded at $1111 instead of $2000

filename: .byte    $44,$41,$54,$41 ; DATA
filename_end:

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

You still need to have the 2-byte file header, you can just make it a couple of zero bytes, but it still has to be there. However, the code looks correct. I would expect it to load the last 254 bytes of $11 from the file at $2000. Is your filename really just "DATA", all caps?

Share this post


Link to post
Share on other sites
  • 0

Thank you clarifying that the 2-byte file header must be always present!  I am sure that knowledge just saved me from some future grief 🙂

Yes, my data file is really called "DATA", all caps.  You could probably guess that my program is called "LOADDATA"...

The data file was updated to have the 2-byte header with the address of $3000.  The code was not changed, so it is still hard-coded to use the $2000 address.  Upon re-running the data was loaded to $3000.  Not the $2000 specified in the program.

Share this post


Link to post
Share on other sites
  • 0

According to C64 Kernel documentation Secondary address 0 should load relative ...

Unfortunately I only have a german commented KERNAL at hand so trying to translate

This is in the middle of the load routine and in X we stored the original value of the secondary load address (in your case 0).

So transfer X to A and automatically set flags accordingly.

The next command is where the key is: 

Branch if Z=Flag is not set (bne) which mean : Branch if A is NOT 0. And the branch jumps then to absolute loading (e.g. the values that has been got from the file and stored in ($AE)  are beeing used, otherwise the paramterers you have given are being written to ($AE) first.

image.thumb.png.b690147b02306928cce950570f245625.png

Unfortunately I have no idea what the X16 rom will do, as I could not figure out to read it. The whole thing with includes and all the separated files in tiny bits makes it absolutely unreadable to me.

I could not figure out at all what the adress of bcc_16 load_iec would be ... So I could not find the corresponding section in the X16 ROM to identify what may be different. The f4a5.load.s does only contain the very beginning and the  rest of it is missing. Not sure where it is located in which file and how to find it.

Share this post


Link to post
Share on other sites
  • 0

There is a bug in the X16's Kernal ROM.  A relocatable load doesn't relocate!
This program works when it loads from the host file system (the emulator bypasses Kernal).  It fails when it loads from an SD-card.

; Assemble with:
;  cl65 -t cx16 loaddata.s

; These three lines let us test this program by typing:
;  LOAD "LOADDATA"
;  RUN
    .export  _main
    .forceimport  __STARTUP__
_main:

    .import  SETLFS, SETNAM, LOAD

load_file:
    ;---------------------------------------
    ; Set the file name.
    lda    #(filename_end - filename)
    ldx    #<filename
    ldy    #>filename
    jsr    SETNAM

    ;---------------------------------------
    ; Choose the device and the load method.
;    lda    #$01    ; LOAD doesn't need a file number
    ldx    #$08    ; Device 8 = Disk Drive
    ldy    #$00    ; Secondary address of 0
    jsr    SETLFS

    ;---------------------------------------
    ; Load the file
    lda    #$00    ; Load to memory (1 = verify)
    ldx    #<$2000 ; Desired destination
    ldy    #>$2000
    jsr    LOAD

    ;---------------------------------------
    ; Did it work?
    bcc all_good
    stp    ; Break into the debugger
           ; Register A has the error code

all_good:
    stp    ; File loaded at $1111 instead of $2000

.rodata
filename: .byte    "data"
filename_end:
Edited by Greg King

Share this post


Link to post
Share on other sites
  • 0

Looks like the code in kernal/cbm/channel/load.s saves the SA in to the X register, sets SA to something else for the serial routines, then tries restoring the old SA later on when it goes to check if it should load from the disk address, except that by that point X has been changed by the routines called in between and the old SA is lost.  Good catch! I just put in a PR for a fix for this.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

Thank you everyone for looking into and fixing the issue, I will be looking forward to the next release!

Also, thank you @Greg King for modifying the LOADDATA code!  I will be putting in some time to understand those changes and their effects.

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, Zakero said:

Also, thank you @Greg King for modifying the LOADDATA code!  I will be putting in some time to understand those changes and their effects.

There are three changes:

  • I showed an easy way to build the program.
  • I added some header lines that make it easy to create BASIC-like programs that you can use to test the Assembly code that you might want to put in your programs.  (It isn't good for your "final" programs, though.  It adds some start-up code that's used by C programs, but not Assembly programs.  "Production" programs would insert a BASIC stub in a different way.)
  • I used names for the Kernal functions.  We don't need to remember those hex address numbers.  (You can see the names that are available by looking at https://github.com/cc65/cc65/blob/master/asminc/cbm_kernal.inc)

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