English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 14 March 2016, 22:44   #1
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
AmiDevCpp asm - undefined reference

Hi again,
further to my post a few days ago I have been dipping my toe in the water here and trying to find a working environment to code C and ASM for amiga in. Hannibals toolchain seemed perfect when I compiled the examples because I really want to use visual studio but it fell apart a bit when I tried to change the project structure (mostly because it relies on a .bat rather than giving visual studio references to the alternative compilers and intelligent command lines) and then I found most of the c standard library was missing (stdio, etc) and shoehorning it in didnt work so well. Basically it's great but very much designed for writing demos and in pretty much pure assembler.

That aside I decided to try amidevcpp as a "should just work" solution. Again, I'd much rather visual studio but right now i'll take anything that'll compile. I wrote a simple hello world in pure C - it compiled. I put the exec on a virtual hdd in winuae and ran it and it worked - joy

Then I added test_asm.s to my project. I've been following the amiga hardware programming asm tutorials on youtube so I decided to simply try compiling the mouse wait loop from tutorial 1. It looks like:

Code:
waitmouse:
        btst #6,$bfe001
        bne waitmouse
        rts
The compiler knows it's asm but throws the error:
[Linker Error] undefined reference to `$bfe001'

if I comment out the btst line the rest compiles fine :/ Is there some other syntax for btst in amidev or some such?

Thanks for your time
Sephnroth is offline  
Old 15 March 2016, 08:29   #2
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by Sephnroth View Post
The compiler knows it's asm but throws the error:
[Linker Error] undefined reference to `$bfe001'

if I comment out the btst line the rest compiles fine :/ Is there some other syntax for btst in amidev or some such?
GAS stinks. It uses MIT format instead of Motorola for the assembler. Many things need a '%' before them which is annoying. I don't know the best way to deal with it. I use vbcc mostly as it uses the legendary vasm assembler .
matthey is offline  
Old 15 March 2016, 16:56   #3
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by Sephnroth View Post
....

Code:
waitmouse:
        btst #6,$bfe001
        bne waitmouse
        rts
The compiler knows it's asm but throws the error:
[Linker Error] undefined reference to `$bfe001'

if I comment out the btst line the rest compiles fine :/ Is there some other syntax for btst in amidev or some such?

Thanks for your time
Try 0xbfe001
alkis is offline  
Old 15 March 2016, 19:48   #4
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by alkis View Post
Try 0xbfe001
That's too simple and logical to work .

@Sephnroth
You can use another assembler with Motorola format (like vasm) if you are assembling the files separately and linking the .o files. This is only possible with unofficial older versions of GCC which output Amiga HUNK format executables (I believe this includes default AmiDevCpp GCC). Your hardware banging and polling is not multitasking or C friendly which you probably already know .
matthey is offline  
Old 15 March 2016, 23:03   #5
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
It certainly isnt friendly, at the moment I'm stuck having hung the system and failing to restore it :P I was just coming in to post to ask about it!

My goal here is to be able to create full screen games, multitasking can go do one BUT my hope is to use C for the bulk of any game's engine (the state machine, logic, etc) and bang the hardware for the bits that need the speed - ie, rendering bitmaps etc.

Currently I successfully start my program, print some text to console window (not at the full screen game graphics stage yet! :P), disable "the system", start a loop, wait for a mouse click and then exit my loop and in theory my program. Sadly the "restore the system" part is NOT working. I'm probably doing something stupid - I havnt programmed ASM since 2005 and that was for ARM9 and minimal (similar situation to this, C programming for GP2X handheld with some ASM hardware access for co-processor) - also having nearly every tutorial in the world assume ASM-ONE syntax and being stuck with GAS isnt helping.

Anyway! My C code:

Code:
#include <stdio.h>
#include <stdlib.h>

int mouseclick(void);
void init(void);
void killsystem(void);
void restoresystem(int inter);
int getinterrupt();

int main(int argc, char *argv[])
{
    init();

    int INTERA = 0;
    printf("INTERA: %x\n", INTERA);

    INTERA = getinterrupt();
    printf("INTERA: %x\n", INTERA);

    killsystem();
    printf("Testing for mouse click..\n");

    while (1 == 1)
    {

        if (mouseclick() == 1)
        {
            printf("Mouse Clicked! Bye!\n");
            break;
        }
    }

    printf("Program has detected click and exited!\n");
    printf("Press any key to close.\n");
    getchar();

    restoresystem(INTERA);
    return 0;
}
and my asm:

Code:
|gas uses a pipe as a comment symbol? really?

.global _mouseclick
.global _init
.global _killsystem
.global _restoresystem
.global _getinterrupt

_init:
    move 0xdff01c, d5   |Save INTERA (read only ver) to d5 - but whats chance of d5 being safe for exec of whole program?
    rts

_killsystem:
    |interupt enable register: 0xdff09a
    move #0x7fff, 0xdff09a
    rts;

_getinterrupt:
    move 0xdff01c, d0
    rts;

_restoresystem:
    |method 1: restore INTERA from d5 which it was saved to at start of program (but could of been overwritten by C shennigans during program exec?)
    |or #0xc000, d5   |or this in because.. photon told us to.
    |move d5, 0xdff09a

    |method 2: restore INTERA from parameter (stored off in C code by calling getintterupt())
    or #0xc000, d0   |or this in because.. photon told us to.
    move d0, 0xdff09a
    rts;

_mouseclick:
    btst #6,0xbfe001
    bne no_click
    move.b #1, d0
    br done
no_click:
    move.b #0, d0
    br done
done:
    rts
as you can see I originally copied the exact method as photon's tutorial series on hardware programming and stored the INTERA into reg d5 and restored at the end. But when the restore wasnt working I thought I would try saving off the data into a C var instead and restoring at at the end - but it's still not releasing the mouse or allowing my program to close :/

no idea where I'm messing up now XD
Sephnroth is offline  
Old 16 March 2016, 08:39   #6
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
I'm knowledgeable about 68k assembler but not the Amiga hardware so no comment about what you are trying to do there. I do see 2 major problems though. You can not assume a register (D5) is preserved from one function to the next. You should change the 2x "move.b" in mouseclick() to "moveq" so the whole 32 bit int return value is affected. You can and should remove the second "br done". Many assembler programmers on here don't know or like the MIT format and are unlikely to help because of it.
matthey is offline  
Old 16 March 2016, 09:06   #7
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
Oh dear, guess I'm on the wrong side of the fence! I'll try and get a workflow with vasm working

Really appreciate the advice thou! I will remove the br and swap to moveq for the click test I had same thought about the d5 reg (even commented it :P) and so added the getinterrupt function so I could save it off in a c variable instead of a register and modified restoresystem to take a parameter (d0) instead. Still didn't fix it thou :/
Sephnroth is offline  
Old 16 March 2016, 11:51   #8
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
Ah! I'm at work and looking over this code during a break and I think I've spotted my problem! I dont specify a register for the parameter in my c code so I suspect my parameter is only present on the stack. I guess the stack is the proper place to read params from anyway... I'll investigate after work xD
Sephnroth is offline  
Old 16 March 2016, 17:31   #9
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by Sephnroth View Post
Ah! I'm at work and looking over this code during a break and I think I've spotted my problem! I dont specify a register for the parameter in my c code so I suspect my parameter is only present on the stack. I guess the stack is the proper place to read params from anyway... I'll investigate after work xD
Yes. The parameter is on the stack by default (68k ABI used by most compilers) but it is possible to specify registers in the function declaration (format varies from compiler to compiler).
matthey is offline  
Old 16 March 2016, 18:40   #10
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Ok, example for calling from to C to asm and parameters passing.

main.c
Code:
#include <stdio.h>

int regadd(register int a __asm("d0"),register int b __asm("d1"));
int stackadd(int a, int b);

int main(int argc, char **argv)
{
  printf("Parameters on stack: %d\n", stackadd(100,25));
  printf("Parameters on registers: %d\n", regadd(100,25));
  return 0;
}
funcs.s
Code:
  .global _regadd
_regadd:
    add.l	d1,d0
    rts
    
   .global _stackadd
_stackadd:
    move.l	4(sp),d0
    add.l	8(sp),d0
    rts
(compile example: m68k-amigaos-gcc -noixemul -o foo funcs.s main.c)

It's all in the prototyping in the C code.

Also, be carefull when you hit the hardware for the "width". If the hardware manual says the register is byte, specify .b. .w for word. Don't use generic move 0xhardware,d0 like that. You have to specify the length of the move.
alkis is offline  
Old 16 March 2016, 18:54   #11
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
matthey and alkis - thankyou both very much My program now works!

I store INTERA in an int at the start of the program and then disable the system. I start my loop, poll the hardware for a mouse click and when detected I end the loop, restore the INTERA value and end the program. It sounds so feable but I'm genuinely super excited I got my own code including asm hardware access compiling and working XD

I've used a register for restoring INTERA atm but I may switch to the stack to try and make that a habbit for compiler independence.

Incidently the true cause of my hang/failing to restore was actually in the C code, the getchar() call. If you try to getchar() whilst the sytem is disabled you get stuck forever XD moving getchar() to under restoresystem(INTERA); brought everything to life

Now to see if I can take over the display and start doing something graphical full screen.. watch this space for more of me crying into my beer begging for help from someone who knows what they are doing :P
Sephnroth is offline  
Old 16 March 2016, 19:07   #12
Sephnroth
Registered User
 
Join Date: Oct 2014
Location: England
Posts: 77
and I already have a question haha.. I actually ran into this last night but forgot until now. Alkis you wrote perfect GAS compliant asm for amiga just then so maybe you know the answer to this one :P

how can I declare hunk type's using gas? I need to position my copper list in chip ram. In the hardware programming guide on youtube I was following it was:

SECTION some_name,DATA_CHIP (or DATA_FAST, DATA_PUBLIC, etc). Looking online for the GAS documentation I've discovered I can declare sections with .section and set a name and a type like d for data or c for code but i have NO clue how to cause the equivalent of _CHIP or _FAST with their syntax :/
Sephnroth is offline  
Old 16 March 2016, 20:48   #13
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
I don't think that's supported in the later versions of gcc.

As you can read here http://cahirwpz.users.sourceforge.ne...gaos/chip.html it should be .datachip but I get:

funcs.s:12: Error: unknown pseudo-op: `.datachip'

(from m68k-amigaos-gcc (GCC) 3.4.0 / GNU assembler 2.14)

If you are gonna play more with assembly and less with C you should really switch to vasm as Matthey already suggested.

If however you insist on C/asm, have a look and steal a technique or two from here f.ex.
https://github.com/astrofra/amiga-ex.../fx_routines.c
alkis is offline  
Old 19 May 2016, 07:09   #14
NovaCoder
Registered User
 
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,400
Quote:
Originally Posted by alkis View Post
Ok, example for calling from to C to asm and parameters passing.

main.c
Code:
#include <stdio.h>

int regadd(register int a __asm("d0"),register int b __asm("d1"));
int stackadd(int a, int b);

int main(int argc, char **argv)
{
  printf("Parameters on stack: %d\n", stackadd(100,25));
  printf("Parameters on registers: %d\n", regadd(100,25));
  return 0;
}
funcs.s
Code:
  .global _regadd
_regadd:
    add.l	d1,d0
    rts
    
   .global _stackadd
_stackadd:
    move.l	4(sp),d0
    add.l	8(sp),d0
    rts
(compile example: m68k-amigaos-gcc -noixemul -o foo funcs.s main.c)

It's all in the prototyping in the C code.

Also, be carefull when you hit the hardware for the "width". If the hardware manual says the register is byte, specify .b. .w for word. Don't use generic move 0xhardware,d0 like that. You have to specify the length of the move.
This is the only way I could get ASM to work with C/C++ when using AmiDevCpp.

I'd use VASM to compile the ASM and then link it to the AmiDevCpp project as an include (object).
NovaCoder is offline  
Old 27 December 2022, 16:51   #15
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,160
Quote:
Originally Posted by alkis View Post
I don't think that's supported in the later versions of gcc.

As you can read here http://cahirwpz.users.sourceforge.ne...gaos/chip.html it should be .datachip but I get:

funcs.s:12: Error: unknown pseudo-op: `.datachip'

(from m68k-amigaos-gcc (GCC) 3.4.0 / GNU assembler 2.14)

If you are gonna play more with assembly and less with C you should really switch to vasm as Matthey already suggested.

If however you insist on C/asm, have a look and steal a technique or two from here f.ex.
https://github.com/astrofra/amiga-ex.../fx_routines.c

Bebbo's version allows and supports ".datachip" (v6)


Code:
GNU assembler version 2.35.2 (m68k-amigaos) using BFD version (GNU Binutils) 2.35.2.220518-152237
gcc version 6.5.0b 220509171442 (GCC)

Code:
        .datachip
        dc.w    1000,2000

_end_of_ng_data:
disassembles (IRA) into
Code:
    SECTION S_2,DATA,CHIP

__end:
    DC.W    $03e8            ;10a88
    DC.B    $07            ;10a8a
_end_of_ng_data:
    DC.B    $d0            ;10a8b

which is buggy (the label is shifted by 1 byte...) so maybe there are some issues but at least the data is in chipmem all right. Note: using ".word" syntax or 1 "dc" per data doesn't fix the bug.
jotd is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Tool to convert asm to gnu asm (gas) Asman Coders. Asm / Hardware 13 30 December 2020 11:57
AmiDevCpp AF2013 Coders. C/C++ 0 14 March 2014 00:23
SAS/C: Undefined symbols Yesideez Coders. C/C++ 14 13 February 2014 16:36
AsmOne: Undefined symbol copse Coders. Asm / Hardware 2 02 April 2012 01:41
Undefined symbol bsr.b init_bitmaps VoltureX Coders. General 12 13 November 2011 16:11

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 11:12.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08814 seconds with 13 queries