Closed nyteshade closed 3 years ago
So this compiles without error
#include "support/gcc8_c_support.h"
#include <exec/exec.h>
#include <dos/dos.h>
#include <dos/stdio.h>
#include <proto/dos.h>
#include <proto/exec.h>
volatile struct Custom *custom;
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
int main(int argc, char **argv) {
STRPTR message = "Hello World\n";
SysBase = *((struct ExecBase**)4UL);
custom = (struct Custom*)0xdff000;
FPrintf(Output(), message);
return 0;
}
But still GURUs upon running. However, this program builds and runs fine on an Amiga using GCC 2.95.3. What am I missing here?
#include <exec/exec.h>
#include <dos/dos.h>
#include <dos/stdio.h>
#include <proto/dos.h>
#include <proto/exec.h>
int main(int argc, char **argv) {
STRPTR message = "Hello World\n";
FPrintf(Output(), message);
return 0;
}
As an aside, if support/gcc8_c_support.h
is required and we have to define
volatile struct Custom *custom;
struct ExecBase *SysBase;
...and we have to place this at the top of main in all our applications...
SysBase = *((struct ExecBase**)4UL);
custom = (struct Custom*)0xdff000;
Then it might make sense to have something like the following
#include "support/gcc8_c_support.h"
// your includes
/* Required definitions */
GCC8_C_DEFINITIONS // <- A bit that defines custom and SysBase
// your code
int main(int argc, char **argv) {
InitializeGCC8Support(); // Assign constant values to SysBase and custom for those who can't remember
// your code
}
With these snippets in comments in the default gcc8_c_support.h file. Thoughts?
Hi, I do not know where you get FPrintF
from.
Take a look at this minimal code that works to print out text.
SysBase
is required for OpenLibrary
to work (that's from exec.library
)
DOSBase
is required for Write
, Output
(they're from dos.library
)
Technically, you could reduce gcc8_c_support.h
to only memcpy
, memset
, memmove
, as these are sometimes used by the C compiler even if you don't call them explicitly. Everything else in there is just convenience.
Also, please do remember that this extension does not support the C standard library, so you don't get argc
, argv
into your main
, also you can't use stuff like printf
, std::cout
, etc.
#include "support/gcc8_c_support.h"
#include <proto/exec.h>
#include <proto/dos.h>
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
int main() {
SysBase = *((struct ExecBase**)4UL);
DOSBase = (struct DosLibrary*)OpenLibrary((CONST_STRPTR)"dos.library", 0);
if (!DOSBase)
Exit(0);
Write(Output(), (APTR)"Hello console!\n", 15);
Delay(50);
CloseLibrary((struct Library*)DOSBase);
return 0;
}
The include #include <dos/stdio.h>
is an Amiga header that uses Amiga library calls to simulate things like printf
. The call FPrintf()
, lowercase f on the end, relies on BPTR
and STRPTR
style exec types and is entirely Amiga.
@BartmanAbyss
Also, please do remember that this extension does not support the C standard library, so you don't get argc, argv into your main, also you can't use stuff like printf, std::cout, etc.
This raises so many questions. So how does one get input from the user with program written here? I don't know assembly, but I assume there is a way to get those values using assembly.
Also, how do I prevent the emulation environment from force quitting after the application ends? I want to play around with the environment there a bit?
Also shouldn't this program work without the inline versions of the functions present? I notice that if I define _NO_INLINE
at the top, even your base example fails. The <proto/dos.h>
and <proto/exec.h>
should include <clib/dos_protos.h>
and <dos/exec_protos.h>
by default but even with those the program fails to link. Is this because of not being in an Amiga environment?
Compiling main.c
Linking a.mingw.elf
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: obj/main.o: in function `main':
C:/Users/nytes/Desktop/t/main.c:31: undefined reference to `OpenLibrary'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:35: undefined reference to `Output'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:35: undefined reference to `Write'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:41: undefined reference to `Delay'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:50: undefined reference to `CloseLibrary'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:33: undefined reference to `Exit'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:35: undefined reference to `Output'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:35: undefined reference to `Write'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:41: undefined reference to `Delay'
c:/users/nytes/.vscode/extensions/bartmanabyss.amiga-debug-1.1.0-preview32/bin/opt/bin/../lib/gcc/m68k-amiga-elf/10.1.0/../../../../m68k-amiga-elf/bin/ld.exe: C:/Users/nytes/Desktop/t/main.c:50: undefined reference to `CloseLibrary'
collect2.exe: error: ld returned 1 exit status
In fact I've always wondered how the Amiga shared libraries (*.library) work for linking. With something like StormC, SAS/C, GCC 2.95.3 or other native Amiga C compilers, how do they link the binary when there isn't a fixed library file there to reference?
The include
#include <dos/stdio.h>
is an Amiga header that uses Amiga library calls to simulate things likeprintf
. The callFPrintf()
, lowercase f on the end, relies onBPTR
andSTRPTR
style exec types and is entirely Amiga.
Ah ok, I see it's defined in inline/dos.h
, however it may be because this is a function that uses vargs
that it itsn't supported. I will test and let you know.
Also shouldn't this program work without the inline versions of the functions present? I notice that if I define
_NO_INLINE
at the top, even your base example fails. The<proto/dos.h>
and<proto/exec.h>
should include<clib/dos_protos.h>
and<dos/exec_protos.h>
by default but even with those the program fails to link. Is this because of not being in an Amiga environment?
_NO_INLINE
is supported with gcc (it only works with linker libraries from old amiga compilers). The amiga system includes come with support for various compilers, and gcc only supports the inline/*
variant.
In fact I've always wondered how the Amiga shared libraries (*.library) work for linking. With something like StormC, SAS/C, GCC 2.95.3 or other native Amiga C compilers, how do they link the binary when there isn't a fixed library file there to reference?
The .library
file is loaded when you execute a LoadLibrary
call. Amiga libraries are a bit different than what you're probably used to on Linux or Windows. Essentially LoadLibrary
just returns a pointer (like a vtbl), and all functions you call on the loaded library just call into an offset of that pointer. So there's no C-style .lib
file involved during linking.
This raises so many questions. So how does one get input from the user with program written here? I don't know assembly, but I assume there is a way to get those values using assembly.
No need to do assembly. You can call all AmigaOS functions from C. See here
Also, how do I prevent the emulation environment from force quitting after the application ends? I want to play around with the environment there a bit?
I'm not sure, I tried that minimal sample I posted above, and it just returned to the CLI and sat there. Nothing crashed.
The include
#include <dos/stdio.h>
is an Amiga header that uses Amiga library calls to simulate things likeprintf
. The callFPrintf()
, lowercase f on the end, relies onBPTR
andSTRPTR
style exec types and is entirely Amiga.Ah ok, I see it's defined in
inline/dos.h
, however it may be because this is a function that usesvargs
that it itsn't supported. I will test and let you know.
So, I just tried it and it turns out that VPrintf is not supported on Kickstart 1.3, see the (V36)
in the link above? V36 is Kickstart 2.0 (see here. It works fine with an A1200-config and Kick 3.1
How can I add references to the math library etc to the linker?
I keep getting undefined reference to `__mulsf3' in the Linking a/mingw.elf stage, have tried adding -lm almost wherever I can?
Math library is not supported. Also, 68000 has no FPU. But you can use amiga IEEE libraries (they emulate float)
So I am trying to pare down the minimal required code for an application to work well with the system. The supplied
main.c
is impressive but it's also got a lot going on. If I wanted to be a good Amiga citizen and follow the rules, and print hello world in the console, I was thinking it would look something like this.From what I can tell we need to have the gcc8_c_support stuff, but what else is required? What is the
struct Custom *custom
bit? I haven't seen that before. This program, by the way, crashes when run in the emulator. Do you know why?