how pass a #define from c to asm? - newbie question

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
tomtom68
New member
Posts: 5
Joined: Mon Aug 23, 2021 9:55 am

how pass a #define from c to asm? - newbie question

Post by tomtom68 »

Hi guys,

I am new to z88dk and this forum and I already searched this forum for an answer for "my problem" - but I did not found any solution...

I use z88dk for RC2014 and compile c with asm together.

Everything works fine with inline asm, or external asm file with "export" and "public" ... so far so good...

BUT how do I pass "#define something 0x55" from C to asm file?

Any idea?

Thanks & cheers

Thomas
derekfountain
Member
Posts: 121
Joined: Mon Mar 26, 2018 1:49 pm

Re: how pass a #define from c to asm? - newbie question

Post by derekfountain »

#define creates a C preprocessor macro definition, and passing such a thing to the assembler doesn't make a lot of sense. That said, I did spent quite a while trying to find a way to share a simple numerical value between C and ASM files. There might be a way to do it with pragmas:

https://www.z88dk.org/wiki/doku.php?id=usage:pragmas

but I couldn't work it out.

I'm not sure if it's a particularly useful thing to be able to do, but I'd be interested if anyone knows the answer.
andydansby
Member
Posts: 51
Joined: Fri May 27, 2016 8:58 pm

Re: how pass a #define from c to asm? - newbie question

Post by andydansby »

derekfountain wrote: Tue Aug 24, 2021 9:26 am #define creates a C preprocessor macro definition, and passing such a thing to the assembler doesn't make a lot of sense. That said, I did spent quite a while trying to find a way to share a simple numerical value between C and ASM files. There might be a way to do it with pragmas:

https://www.z88dk.org/wiki/doku.php?id=usage:pragmas

but I couldn't work it out.

I'm not sure if it's a particularly useful thing to be able to do, but I'd be interested if anyone knows the answer.
Actually passing on assembler variables to C and back the other way is the subject of 128k Programming Lesson 2, part 2.
https://zxspectrumcoding.wordpress.com/ ... -2-part-2/. It's pretty easy once you have the syntax correct.

I'm hoping to release lesson 3 this Saturday which is calling assembler routines from C and using fastcall.

Andy Dansby
derekfountain
Member
Posts: 121
Joined: Mon Mar 26, 2018 1:49 pm

Re: how pass a #define from c to asm? - newbie question

Post by derekfountain »

The request, as I understood it, wasn't to pass a variable from C to ASM, but to pass a compile time constant from C to ASM.
tomtom68
New member
Posts: 5
Joined: Mon Aug 23, 2021 9:55 am

Re: how pass a #define from c to asm? - newbie question

Post by tomtom68 »

Hi guys,

thanks for your ideas.

passing vars or functions from c to asm with "export" and "public" (or from asm to c) is no problem, but I did not found any way to do this with c definitions.

For example I need to know an address in c and asm as well. I can't imagine that's best practice to #define in c and .equ in asm the same address again.

I also think that pragma will not help.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: how pass a #define from c to asm? - newbie question

Post by dom »

Briefly. Please take a look at the FOPEN_MAX (and other) handling in classic - that may do what you want (though on a reread it may be in reverse)
tomtom68
New member
Posts: 5
Joined: Mon Aug 23, 2021 9:55 am

Re: how pass a #define from c to asm? - newbie question

Post by tomtom68 »

dom wrote: Tue Aug 24, 2021 5:13 pm Briefly. Please take a look at the FOPEN_MAX (and other) handling in classic - that may do what you want (though on a reread it may be in reverse)
?? FOPEN ... I dont understand. I dont want to deal with streams and/or files - I just want to tell the compiler, that #define MY_IO_ADDR 0x88 in test.c should also be known in test.asm file. As I already mentioned, I use mixed c and asm files with:

zcc +rc2014 -subtype=basic -v --list -s -SO1 --c-code-in-asm -compiler=sdcc @sources.lst -o


sources.lst contains:
test.c
test.asm
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: how pass a #define from c to asm? - newbie question

Post by dom »

No worries. I just gave a pointer to an example of how to turn a pragma or an assembler variable into a value available in both C and assembler.

That’s not what you want and since I’m currently away I can’t assist further.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: how pass a #define from c to asm? - newbie question

Post by dom »

Now I'm back I can play around, I'm not sure if this is what you've done in the past, but seems to be the easiest way to do it:

Code: Select all

def1.c:

static void exportfunc() __naked
{
__asm
        GLOBAL ASM_MYVALUE
        defc    ASM_MYVALUE = MYVALUE
__endasm;
}


int main() {
}

asm.asm:

        EXTERN  ASM_MYVALUE
        SECTION code_user

myfunc:
        ld      hl,ASM_MYVALUE
I compiled with: zcc +test def1.c asm.asm -DMYVALUE=13 -m and then ran z88dk-dis -x a.map a.bin which yielded:

Code: Select all

myfunc:
                    ld      hl,$000d                        ;[0368] 21 0d 00


The ASM_MYVALUE label is resolved at linktime, so you'll need to get your dependency management right.

Alternatively you could:

1. Use -Ca-DMYVALUE=13 to pass the value through to the assembler on the command line
2. Rename the files to .c.m4 and .asm.m4 and use m4 pre-processing
tomtom68
New member
Posts: 5
Joined: Mon Aug 23, 2021 9:55 am

Re: how pass a #define from c to asm? - newbie question

Post by tomtom68 »

Hi dom,

thanks for your time and help - but it does not work :(

in myfile.c:

Code: Select all

#define MYVALUE 0x1234

static void exportfunc() __naked
{
	__asm
    	GLOBAL ASM_MYVALUE
    	defc ASM_MYVALUE = MYVALUE
	__endasm;
}
After compiling in myfile.c.sym the constant MYVALUE appears as public.

Code: Select all

ASM_MYVALUE                     = $1234 ; const, public, , , code_compiler, sandbox.c:1473

BUT in myfile.asm:

Code: Select all

SECTION code_user
EXTERN ASM_MYVALUE

myfunc:
    ld hl, ASM_MYVALUE

In myfile.asm.lis the ASM_MYVALUE is empty :(

Code: Select all


12    0000              SECTION code_user
13    0000              EXTERN ASM_MYVALUE
14    0000              
15    0000              myfunc:
16    0000  21 00 00        ld hl, ASM_MYVALUE
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: how pass a #define from c to asm? - newbie question

Post by dom »

I have a feeling that the .lis is generated from the assembly stage not from the link stage.

At assembly stage the value of ASM_MYVALUE is not known so in the .lis output it gets a placeholder of 0.

The .o file should contain a relocation entry which is resolved at link time.
tomtom68
New member
Posts: 5
Joined: Mon Aug 23, 2021 9:55 am

Re: how pass a #define from c to asm? - newbie question

Post by tomtom68 »

YES!! Thank you dom!! You are right, the asm listing was before linking. I made a test and defined a led test-pattern, passed it to asm file and it worked!

I also tried without m4 or any DMYVALUE param and it also worked well.

But, your solution is a smart workaround but is this really the final solution?

I mean - z88dk can do so many fancy things make z80 enthusiasms hearts beat faster (mixed c and asm) - maybe also cook coffee,

but is not able to export a definition in a simple way?

If I had 50 definitions I would need to put all these definitions in this exportfunc...or maybe then I had to use this m4 stuff...

BUT I am OK with this exportfunc - even with 50 definitions :)

Thank you.

Cheers Thomas
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: how pass a #define from c to asm? - newbie question

Post by dom »

tomtom68 wrote: Fri Aug 27, 2021 8:25 amBut, your solution is a smart workaround but is this really the final solution?

I mean - z88dk can do so many fancy things make z80 enthusiasms hearts beat faster (mixed c and asm) - maybe also cook coffee,

but is not able to export a definition in a simple way?
I think the correct way to do this would be:

Code: Select all

file.c:
#define VAR  0x4000

__at (VAR) void *p;

asm.asm:
GLOBAL _p
ld hl,_p
Which seems to work in sdcc. Unfortunately with sccz80 there's been some scoping changes over the years so this no longer works - I'll fix that up and I think we'll have the definitive way of doing it.

EDIT: Fixed the scoping in sccz80 so this method will work regardless of compiler.
Post Reply