Home > Mobile >  Passing memory address to subroutine in C64 Assembly?
Passing memory address to subroutine in C64 Assembly?

Time:09-30

param word 0

function
    ...
    lda param,x


scr1 byte "some text"
     byte 0

So how do I pass "scr1" to function as "param"? I know it's a memory address, so it doesn't fit into 1 byte registers. What's the best way to do this?

EDIT:

Thanks for the answers! The solution posted below works great, but this uses both X and Y registers. What if "function" calls KERNAL routines which rely on X or Y or my own code needs X for something etc? In these case this won't work as expected I guess?

I'm totally new to assembler, so I'm confused about many things.

Basically I wanted to pass the address, because I wanted to avoid code duplication. I have a simple function which prints a string to the screen like so:

        ldx #$00
copy_text
        lda scr1,x
        beq done
        sta screen_start,x
        inx
        bne copy_text
done
        rts

But this works only with scr1. If wanna print other stuff, I need to duplicate the code which seems to be wasteful.

Is that acceptable in assembler? I mean, in C or any other language you would just write a reusable function or method. But in assembler this seems to be very hard to do, because there are only 3 registers and they are used by many things.

What's the best way to overcome this limitation?

CodePudding user response:

There are a few ways to do this.

zpb = $fb

function = *
   stx zpb 0  
   sty zpb 1  ; note after you've stored .X and .Y in zero page they can be re-used for other purposes.
   ...
   ldy #$00
   lda (zpb),y
   ...

caller = *
    ldx #<scr1
    ldy #>scr1
    jsr function

Alternatively you can play with the stack

zpb = $fb

function = * 
   pla            ; save current stack pointers for later
   sta temp 0
   pla
   sta temp 1
   pla            ; pull low byte off first
   sta zpb 0
   pla            ; now pull off high byte
   sta zpb 1       
   lda temp 1     ; restore stack pointers so RTS works as expected
   pha
   lda temp 0
   pha
   ...
   ldy #$00
   lda (zpb),y
   ...
temp .byte 0,0

caller = *
    lda #>scr1   ; note we push high byte first since stack is FILO
    pha
    lda #<scr1
    pha
    jsr function

Machine language by its own on the 6502 only has the three registers, so your options are usually to pass values in those registers, or, use those registers to point to a larger set of data that you can then access elsewhere. The indirect zero page is your best friend in this regard since you can then store pointers in zero page and then access them indirectly.

  • Related