Assembly inline C - example

SGDK only sub forum

Moderator: Stef

Post Reply
Cristiano Sword
Interested
Posts: 19
Joined: Mon Jul 03, 2017 2:23 pm
Location: Sao Paulo -Sp
Contact:

Assembly inline C - example

Post by Cristiano Sword » Tue Jun 04, 2019 5:54 pm

Hello guys,

I have some code here in asm that I made in bex, and I'm trying to port them to sgdk, but I can not compile at all, if you can help me reu thanks, because I saw code I know the assembly is with the correct syntax, I already I looked for assemlby inline, but even so do not compile, who can help me, I put the most simple examples I have, I just need to understand how to write them for the compiler to run


code bex:

Code: Select all

 print "test asm68k"
  
  'write ram and register a3
  asm
  
     move.l  #$FF0010,a0
     move.l  #$CAFE,(a0)
     
     move.l  #$cafecafe,a3
  
  end asm
  
  'cls asm
   Asm
		
	  move.w #0x8F02,(a4) 
	  move.l #0x40000000,(a4) 
	  move.w #0x7FFF,d1 

    End Asm
Some ways you tried, unsuccessfully:

Code: Select all

#include <genesis.h>

void chamar1();

int main()
{

            asm("move.l #$cafecafe,%a3");
         
    while(1)
    {
            VDP_waitVSync();
            VDP_drawText("asm 68k",1,1);
    }
    return (0);
}

//asm

 void chamar1()  
  {
        __asm__(
    
       "move.l #$cafecafe,%a3\n"
       "move.l #$cafecafe,%a4\n"
   
  );
 //END
  }


The Mega Drive Will Never Die In Our Hearts.

Project Leyria RPG for Sega Mega Drive / Genesis
https://gendev.spritesmind.net/forum/vi ... php?t=2728

Stef
Very interested
Posts: 2994
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Assembly inline C - example

Post by Stef » Wed Jun 05, 2019 9:01 am

Did you had a look on this :
https://github.com/0xAX/linux-insides/b ... heory-3.md

Also what is the error message you got ?

Cristiano Sword
Interested
Posts: 19
Joined: Mon Jul 03, 2017 2:23 pm
Location: Sao Paulo -Sp
Contact:

Re: Assembly inline C - example

Post by Cristiano Sword » Wed Jun 05, 2019 2:52 pm

Stef wrote:
Wed Jun 05, 2019 9:01 am
Did you had a look on this :
https://github.com/0xAX/linux-insides/b ... heory-3.md

Also what is the error message you got ?
Hi stef,
follows the errors below, remembering that sgdk compiles normally when programmed only in C

Code:

Code: Select all

#include <genesis.h>

void chamar1();

int main()
{

           // asm("move.l #$cafecafe,%a3");
           chamar1();

    while(1)
    {
            VDP_waitVSync();
            VDP_drawText("asm 68k",1,1);
           
    }
    return (0);
}

//asm

 void chamar1()
  {
        __asm__(

       "move.l #$cafecafe,%a3\n"
       "move.l #$cafecafe,%a4\n"

  );
 //END
  }
Errors: :arrow:

BUild Messages

Code: Select all

||=== Build: default in Adress cafe ram asm68k (compiler: Sega Genesis Compiler) ===|

C:\Users\HPZ230\AppData\Local\Temp\ccgMYmBJ.ltrans3.ltrans.o||In function `main':|

(.text.startup+0xa6)||undefined reference to `$cafecafe'|
(.text.startup+0xac)||undefined reference to `$cafecafe'|
(.text.startup+0x124)||undefined reference to `$cafecafe'|
(.text.startup+0x12a)||undefined reference to `$cafecafe'|

||=== Build failed: 4 error(s), 0 warning(s) (0 minute(s), 3 second(s)) ===|

Build Log:

Code: Select all


-------------- Build: default in Adress cafe ram asm68k (compiler: Sega Genesis Compiler)---------------

Checking if target is up-to-date: make.exe -q -f c:\dev\sgdk\Makefile.gen default
Running command: make.exe -f c:\dev\sgdk\Makefile.gen default
C:/dev/sgdk/bin/mkdir -p src/boot
C:/dev/sgdk/bin/mkdir -p out
C:/dev/sgdk/bin/mkdir -p out/src
C:/dev/sgdk/bin/mkdir -p out/res
C:/dev/sgdk/bin/gcc -m68000 -Wall -fno-builtin -Iinc -Isrc -Ires -IC:/dev/sgdk/inc -IC:/dev/sgdk/res -BC:/dev/sgdk/bin -O3 -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer -flto -c main.c -o out/main.o
echo "out/main.o" > out/cmd_
C:/dev/sgdk/bin/gcc -BC:/dev/sgdk/bin -n -T C:/dev/sgdk/md.ld -nostdlib out/sega.o @out/cmd_ C:/dev/sgdk/lib/libmd.a C:/dev/sgdk/lib/libgcc.a -o out/rom.out
C:\Users\HPZ230\AppData\Local\Temp\ccgMYmBJ.ltrans3.ltrans.o: In function `main':
<artificial>:(.text.startup+0xa6): undefined reference to `$cafecafe'
<artificial>:(.text.startup+0xac): undefined reference to `$cafecafe'
<artificial>:(.text.startup+0x124): undefined reference to `$cafecafe'
<artificial>:(.text.startup+0x12a): undefined reference to `$cafecafe'
make.exe: *** [out/rom.out] Error 1
Process terminated with status 2 (0 minute(s), 3 second(s))
4 error(s), 0 warning(s) (0 minute(s), 3 second(s))
 
The Mega Drive Will Never Die In Our Hearts.

Project Leyria RPG for Sega Mega Drive / Genesis
https://gendev.spritesmind.net/forum/vi ... php?t=2728

Chilly Willy
Very interested
Posts: 2800
Joined: Fri Aug 17, 2007 9:33 pm

Re: Assembly inline C - example

Post by Chilly Willy » Wed Jun 05, 2019 2:57 pm

If you want an example of 68K inline assembly, here's a routine I did in a SCD demo.

Code: Select all

static fixed_t FIX_MUL( fixed_t a, fixed_t b )
{
    fixed_t res = 0, c = 0, d = 0, e = 0;
    asm volatile (
        "tst.l %1\n\t"
        "spl %5\n\t"
        "bpl.b 1f\n\t"
        "neg.l %1\n"
        "1:\n\t"
        "tst.l %2\n\t"
        "bpl.b 2f\n\t"
        "not.b %5\n\t"
        "neg.l %2\n"
        "2:\n\t"
        "move.w %1,%3\n\t"
        "swap %1\n\t"
        "move.w %2,%4\n\t"
        "move.w %2,%0\n\t"
        "swap %2\n\t"
        "mulu %3,%0\n\t"
        "mulu %1,%4\n\t"
        "mulu %2,%1\n\t"
        "mulu %3,%2\n\t"
        "swap %1\n\t"
        "move.w #0,%1\n\t"
        "move.w #0,%0\n\t"
        "swap %0\n\t"
        "add.l %4,%0\n\t"
        "addx.l %2,%0\n\t"
        "addx.l %1,%0\n\t"
        "tst.b %5\n\t"
        "bne.b 3f\n\t"
        "neg.l %0\n"
        "3:\n\t"
        : "=d" (res), "=d" (a), "=d" (b), "=d" (c), "=d" (d), "=d" (e)
        : "0" (res), "1" (a), "2" (b), "3" (c), "4" (d), "5" (e)
        : "cc"
    );
    return(res);
}

Miquel
Very interested
Posts: 478
Joined: Sat Jul 30, 2016 12:33 am

Re: Assembly inline C - example

Post by Miquel » Wed Jun 05, 2019 3:28 pm

In gcc you can write inline assembly or compose an assembly file, both ways works the same really.

Inline assembly:
+ fully interlockable with C
- more verbose
- you NEED to know the use of the key words “__asm volatile” and “__asm”
- you need to use implicit params (%), and how they work ("=>a", "=d", ...)
*+ it can be inlined, if performance heavily depends on inlining, that's the way to go

Assembly file:
+ more simple
- Intimidating at the start, since you have to learn a “new language”
+ you can use lifesaving macros
+ There are some parameters to avoid using % on registers and make it more like other assemblers
+ you can use maths on static data (another param to make it like C)

And now a very easy example, doing a byte copy, needed to copy data to the z80 ram; the idea is exactly the same:

Inline assembly:

Code: Select all

void memcpy8( void* destination, void const* source, u32 size )
{
	u32 altSize;
	u32 jmpSize;
	// Copy blocks of 16bytes and less
	altSize = size >> 4;
	// jmpSize mean: ( full jump(16 instructions+remaing one) - (size/4)%16 ) * (size of instruction:2)
	jmpSize = -((size << 1) & (0xF << 1));
	__asm volatile (
		"	jmp (2f,%%pc,%3)\n"
		"1:	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"	move.b (%0)+,(%1)+;"
		"2: dbra %2, 1b\n"
		: "=>a" (source), "=>a" (destination), "=d" (altSize)
		: "d" (jmpSize), "0" (source), "1" (destination), "2" (altSize) );
}
Assembly file:

Code: Select all

*************************************************************
* void* memcpy8( void* const destination, void const* const source, u32 size )
* Needed to copy to z80 memory
*------------------------------------------------------------
* 4(sp) destination.l
* 8(sp) source.l
* 12(sp) size.l
*------------------------------------------------------------
* memcpy8ASM
*------------------------------------------------------------
* a1 destination.l
* a0 source.l
* d0 size.l
*************************************************************

ROUTINE memcpy8
	movem.l	4(sp), d0/a0-a1
	exg		d0, a1
ROUTINE memcpy8ASM
* Backwards jump (d1)
	moveq.l	#(1 << 4) - 1, d1		/* And 15, because of unroll */
	and.l	d0, d1
	lsl.l	#1, d1					/* Mul by 2, because instruction size */
	neg.l	d1
* Number of loops (d0)
	lsr.l	#4, d0					/* Div by 16, because of unroll */
	jmp		2f(d1.l, pc)
3:		.rept 1 << 4
			move.b	(a0)+, (a1)+
		.endr
2:		dbra.w	d0, 3b
	move.l	4(sp), d0				/* return original destination */
	rts
Edit: * added
Last edited by Miquel on Thu Jun 06, 2019 6:00 pm, edited 1 time in total.
Help. Spanish TVs are brain washing people to be hostile to me.

Stef
Very interested
Posts: 2994
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Assembly inline C - example

Post by Stef » Thu Jun 06, 2019 7:31 am

Cristiano Sword wrote:
Wed Jun 05, 2019 2:52 pm

...
Build Log:

Code: Select all


...
<artificial>:(.text.startup+0xa6): undefined reference to `$cafecafe'
<artificial>:(.text.startup+0xac): undefined reference to `$cafecafe'
<artificial>:(.text.startup+0x124): undefined reference to `$cafecafe'
.... 
Ok so the problem is about the $ character, try to use #0xcafecafe instead :)

Cristiano Sword
Interested
Posts: 19
Joined: Mon Jul 03, 2017 2:23 pm
Location: Sao Paulo -Sp
Contact:

Re: Assembly inline C - example

Post by Cristiano Sword » Thu Jun 06, 2019 5:55 pm

I managed to compile stef ^^
Thanks to all who helped me, it was a great help to me. :D :mrgreen:
The Mega Drive Will Never Die In Our Hearts.

Project Leyria RPG for Sega Mega Drive / Genesis
https://gendev.spritesmind.net/forum/vi ... php?t=2728

Post Reply