tebe6502/Mad-Assembler

Calling proc from proc not passing parameters

Closed this issue · 1 comments

As reported here: https://forums.atariage.com/topic/353109-mads-calling-proc-from-proc-with-parameter-problem-parameters-not-being-set/

I'm finding that when calling a proc from a proc, if there are any parameters involved, they don't get passed correctly.

I've got a minimal example showing the problem.

zp-p1.asm - a simple proc that takes an arg t1 as a var, which is externally defined in ZP $80/$81
zp-p2.asm - calls p1 but doesn't pass the parameters to the proc
zp-params.asm - the main method, calls both p1 and p2 correctly, setting parameters as needed

zp-p1.asm

    .extrn t1 .byte
    .public p1
    .reloc

.proc p1 ( .word t1 ) .var
    rts
.endp

zp-p2.asm

    .extrn t1 .byte
    .public p2
    .extrn p1 .proc
    .reloc

.proc p2 ( .word t1 ) .var
    ; PROBLEM HERE IN GENERATED CODE - NO SETUP OF PARAMETERS TO p1 FOR ARG s3
    p1 #s3
    rts
s3 dta c'ccc', 0
.endp

zp-params.asm

    .zpvar t1 .word = $80
    
    org $1000

    ; both of these work fine - parameters are set before jsr to each proc
    p1 #s1
    p2 #s2
    rts

    .link "zp-p1.obx"
    .link "zp-p2.obx"

s1  dta c'aa', 0
s2  dta c'bb', 0

I'm seeing that when the main method calls p1 and p2, the compiler correctly establishes the parameters by setting values in $80/81 prior to jsr call:

    ;-------------------------
    org f:$1000 ; start 1000 end 1025
    lda #$20            ; 1000: A9 20
    sta $80             ; 1002: 85 80
    lda #$10            ; 1004: A9 10
    sta $81             ; 1006: 85 81
    jsr p1              ; 1008: 20 17 10

    lda #$23            ; 100B: A9 23
    sta $80             ; 100D: 85 80
    lda #$10            ; 100F: A9 10
    sta $81             ; 1011: 85 81
    jsr p2              ; 1013: 20 18 10

    ; ...
	; data defined later at:
    dta $61             ; 1020: 61
    dta $61             ; 1021: 61
    dta $0              ; 1022: 00
    dta $62             ; 1023: 62
    dta $62             ; 1024: 62
    dta $0              ; 1025: 00

This all looks great, params are being passed nicely via $80/$81

But inside t2, it doesn't do the same:

    ; p2 generated code - NO SETUP OF PARAMS BEFORE CALLING p1 FOR ARG s3
    jsr p1           ; 1018: 20 17 10
    rts                 ; 101B: 60
    dta $63             ; 101C: 63
    dta $63             ; 101D: 63
    dta $63             ; 101E: 63
    dta $0              ; 101F: 00

Compiled with:

$ mads -o:zp-p2.obx -t -l zp-p2.asm && mads -o:zp-p1.obx -t -l zp-p1.asm && mads -i:. -t -l -o:zp-params.xex zp-params.asm

Am I missing anything in the definition of zp-p2.asm that will force it to correctly pass the parameters through to p1?

for .EXTRN (EXT) and .PROC, specify the parameters

    .extrn t1 .byte
    .public p2
    .extrn p1 .proc (.word t1) .var

    .reloc

.proc p2 ( .word t1 ) .var
    p1 #s3
    rts
s3 dta c'ccc', 0
.endp