07 March 2017, 17:00 | #1 |
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Help please 1st c programme in decades, and it does not work....
Hi,
I used to write system software in C, many many years ago. I thought it would be interesting to see how much I had forgotten (most of it) by seeing if I could write a few simple Amiga progs. With this in mind I got the ade archive from the aminet and set up gcc. Then I went looking for a noddy programme to compile to check all was OK. I found this : https://github.com/cahirwpz/libnix/b...s/helloworld.c Code:
#include <dos/dos.h> #include <workbench/workbench.h> #include <inline/exec.h> #include <inline/dos.h> int __nocommandline=1; /* Disable commandline parsing */ int __initlibraries=0; /* Disable auto-library-opening */ struct DosLibrary *DOSBase=NULL; extern struct WBStartup *_WBenchMsg; int main(void) { if(_WBenchMsg==NULL) { if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",33))!=NULL) { Write(Output(),"Hello world\n",12); CloseLibrary((struct Library *)DOSBase); } } return 0; } but it won't compile, giving test2.c:16 'SysBase' undeclared (first use in this function) Given that SysBase is not used in the programme, I'm guessing it's a problem with one of the includes. Problem is I have no idea which. Having never developed for an Amiga before I'm a bit stuck. Im compilling with gcc -noixemul -lamiga -libnix test.c Can someone point me in the right direction? Thanks in advance. |
07 March 2017, 17:06 | #2 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,190
|
OpenLibrary() is called from Exec.library which is pointed to by SysBase.
|
07 March 2017, 20:37 | #3 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
if I add
Code:
struct ExecLibrary *SysBase; Code:
m68k-amigaos-gcc -noixemul -o helloworld helloworld.c |
08 March 2017, 17:26 | #4 |
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Hi
Many thanks for the replies, adding that declaration gets the prog to compile and it works. (though the executable is big for what it does...) Problem is, I don't really understand how it works. There are bits that make sense, the includes, int __somethings, structs etc. But when we get to the actual library calls I get lost. How, for example would I write a variable out using the Write(Output() call? say my variable was a long int with 2000000 in it?. Write looks like it needs a byte count (12 in the case of the prog I posted). Also why does *SysBase use a different structure to *DosBase if they are using the same library? I'm confused.... Is there a web page anywhere that can lead somone with c knowledge through programming for the Amiga? Thanks in advance. |
08 March 2017, 18:53 | #5 | |
Registered User
Join Date: Feb 2017
Location: Denmark
Posts: 1,174
|
Quote:
To output something you'd do something like: Code:
char message[] = "Hello world!\r\n"; Write(Output(), message, sizeof(message)-1); // -1 because we don't want to print the NUL char at the end of message Code:
sprintf(buffer, "%ld", my_long); Write(Output(), buffer, strlen(buffer)); Links: Amiga OS 3.5 Developer docs An amiga C tutorial - Note I only looked at a couple of the pages and they seemed reasonable, but I can't vouch for the rest. |
|
08 March 2017, 20:48 | #6 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
The easiest would be to use standard ansi c libraries. So, a normal printf would do all you want. I'd stay with normal C until there is a very good reason to go amiga-specific.
If you do want to go amiga-specific you need to tell us your constraints. What the minimum OS version your program should be able to run? (1.2? 1.3? 2.0? 3.x etc) What's your design-goal? Minimum executable size? Speed? |
09 March 2017, 17:39 | #7 |
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Hi,
Many thanks for the replies. Initially I want to re-learn c and at the same time get a handle on how the Amiga uses its libraries. So my first goal is to get a programme to compile using Amiga calls if possible, rather than c quick fixes (even though they are very nice quick fixes!) My next goal is to try and re-write the cli Info command so that it can handle large disks - my version of info is 38.2 and it says that the size of 2 of my partitions is negative (-638321k for one), neither is greater than 4gb. Finally, if I haven't gone mad trying this, I'd like to see if it is possible to patch/change or somehow fix workbench so that its windows also display the correct disk size info. As for base os etc, prob no earlier than 2.04 as there seem to be a lot of docs from around that time, and fewer for later versions. Currently though I am being hit by the Guru, #8000004, when I run my simple prog, below, and I don't know why. Code:
#include <dos/dos.h> #include <workbench/workbench.h> #include <inline/exec.h> #include <inline/dos.h> int __nocommandline=1; /* Disable commandline parsing */ int __initlibraries=0; /* Disable auto-library-opening */ struct DosLibrary *DOSBase=NULL; struct ExecLibrary *SysBase; extern struct WBStartup *_WBenchMsg; int main(void) { char buff[100]; unsigned long int big; big=1000000000; sprintf(buff,"hello world big number %ld",big); /* printf ("large number %d",big);*/ if(_WBenchMsg==NULL) { if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",33))!=NULL) { Write(Output(),buff,strlen(buff)); CloseLibrary((struct Library *)DOSBase); } } return 0; } Any ideas where I am going wrong? compile line is gcc -noixemul -lamiga -O2 test3.c I also tried gcc -noixemul -lamiga -lm -O2 test3.c but still guru. |
09 March 2017, 19:14 | #8 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
The reason it crashes is probably that you have disabled libraries autoinit and some code (either startup, or pulled from stdio) needs some library open.
In general, when you are in strict amiga-specific (you've disabled c-startup and/or libraries-init etc) you can't mix normal c libraries calls. If you have a full uncut C enviroment, you can mix amiga libraries calls. Anyways, solution is to roll your own sprintf Have a look here: http://amigadev.elowar.com/read/ADCD.../node036C.html Near the end you'll find an example. So, here is sprintf.s (for gcc assembler) Code:
_LVORawDoFmt = -522 .globl _mysprintf _mysprintf: |( ostring, format, {values} ) movem.l a2/a3/a6,-(sp) move.l 4*4(sp),a3 | Get the output string pointer move.l 5*4(sp),a0 | Get the FormatString pointer lea.l 6*4(sp),a1 | Get the pointer to the DataStream lea.l stuffChar(pc),a2 move.l _AbsExecBase,a6 jsr _LVORawDoFmt(a6) movem.l (sp)+,a2/a3/a6 rts | ;------ PutChProc function used by RawDoFmt ----------- stuffChar: move.b d0,(a3)+ | Put data to output string rts Code:
#include <dos/dos.h> #include <workbench/workbench.h> #include <inline/exec.h> #include <inline/dos.h> int __nocommandline=1; /* Disable commandline parsing */ int __initlibraries=0; /* Disable auto-library-opening */ struct DosLibrary *DOSBase=NULL; struct ExecLibrary *SysBase; extern struct WBStartup *_WBenchMsg; void mysprintf(char *, char *, ...); int main(void) { char buff[100]; unsigned int big; big=1000000000; mysprintf(buff,"hello world big number %ld\n",big); if(_WBenchMsg==NULL) { if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",33))!=NULL) { Write(Output(),buff,strlen(buff)); CloseLibrary((struct Library *)DOSBase); } } return 0; } Code:
m68k-amigaos-gcc -Wall -noixemul -o helloworld helloworld.c sprintf.s PS: Since you mentioned minimum target OS: 2.04, you could use Printf (note capital 'P') http://amigadev.elowar.com/read/ADCD.../node01CE.html If you go that way, pump the 33 in OpenLibrary to 36 |
10 March 2017, 02:07 | #9 | |
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Quote:
Im not sure that I have disabled autoinit and c-startup as to be honest I dont know how to. Perhaps it needs enabling in my version of gcc? Is there any way to check? Also how would I re-enable the full c environment if it is disabled? Is it through a compiler switch, or do I have to dive into an include? Hope you can suggest a way forward. |
|
10 March 2017, 18:27 | #10 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
What version of GCC are you using? If you're using Cahir's tool-chain from the link in your first post then the full C runtime, standard C library, and the Amiga NDK should always be available by default.
Just compile with m68k-amigaos-gcc -noixemul -o hello hello.c, and you shouldn't need all the extra stuff and declarations, just the call to Write(). |
10 March 2017, 19:44 | #11 | |
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Quote:
Which has gcc ver 2.95.3 in it so Im not sure if they are the same thing. Im developing on a real Amiga rather than uae or cross compiling. To be honest Im not sure if Ive set gcc up correctly yet due to the guru. |
|
10 March 2017, 22:40 | #12 | |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Quote:
Code:
int __nocommandline=1; /* Disable commandline parsing */ int __initlibraries=0; /* Disable auto-library-opening */ |
|
11 March 2017, 07:42 | #13 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
This version, helloworld2.c
Code:
#include <dos/dos.h> #include <workbench/workbench.h> #include <clib/dos_protos.h> #include <stdio.h> #include <string.h> extern struct WBStartup *_WBenchMsg; int main(void) { char buff[100]; unsigned int big; big=1000000000; sprintf(buff,"hello world big number %ld\n",big); if(_WBenchMsg==NULL) { Write(Output(), buff, strlen(buff)); } return 0; } Code:
m68k-amigaos-gcc -Wall -noixemul -o helloworld2 helloworld2.c Things to note:
|
11 March 2017, 14:18 | #14 |
Registered User
Join Date: Sep 2007
Location: Stockholm
Posts: 4,345
|
Look for the SAS/C archive in the EAB forum, it is arguably simpler to use for simple Amiga programs.
|
12 March 2017, 11:31 | #15 | |||
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Many thanks for the replies,
Quote:
Quote:
Do you know the differencies between clib/dosprotos.h and inline/dos.h? I have noticed the executable is big for such a simple prog, 22,980 bytes where as the original info command is only 1980, though I guessing that was written in assembler. Quote:
That said I cant find a way to get gcc to output long longs, long ints yes, long longs no. %ull just displays %ull while passing a long long to sprintf with a %u in it just gives 0, any ideas? While I wont need to output long longs in the final app I will need to for debugging. Anyway Ill download sas, but would like to tackle the gcc issues as well. While on the subject of gcc does anyone know the structure that holds the linked list of device names? I thought it was SYSBase, but cant find it in the incudes |
|||
12 March 2017, 12:57 | #16 | ||||||
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Quote:
Quote:
Quote:
Then, info was written in C. But its very amiga-c. (No standard IO, no standard C startup, no automatic opening/closing libraries...You do EVERYTHING by yourself) If you want to go that path. Get SAS/C, and look at examples in a folder 'no startup' or something similar for cat.c which implements the unix cat command. If I recall does so in 568 bytes of executable. Study cat.c. See how it is done. Quote:
Quote:
Quote:
SysBase->DeviceList Actually, you need http://amigadev.elowar.com/read/ADCD.../node0187.html Last edited by alkis; 12 March 2017 at 13:42. Reason: added LockDosList() |
||||||
12 March 2017, 19:55 | #17 | |||||
Registered User
Join Date: Dec 2016
Location: london
Posts: 178
|
Thanks for the reply,
Quote:
Quote:
Quote:
Quote:
It cant handle 64 bits.. Thanks for the suggestion, I've tried %llu on spritntf and the mysprintf asm you kindly posted a while back. sprint returns %llu, where as my sprint returns a number - but can't handle 64bits if I pass 32 hex fs to it it returns 16777215, which must be the result of overflows. The 68020 etc are 32 bit processors and from my 8 bit (yes I am that old) days I seem to remember that they had ways of combining registers to handle 16 bits. Do the 68020s etc have a similar feature? I don't really want to have to learn assembler just to output debug info, but would it be possible to change mysprintf to handle 64 bits? Oddly if I have both sprint and mysprintf in the same code the mysprintf fails to return anything. Incidentally what does the -Wall switch do in the compile string you posted with mysprintf? Code:
m68k-amigaos-gcc -Wall -noixemul -o helloworld2 helloworld2.c Quote:
|
|||||
12 March 2017, 23:42 | #18 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Get SAS/C just for the cat.c source code. Invaluable for seeing what you need to do for coding "system" command line applications.
The fact that SAS/C doesn't support 64bits doesn't mean you can't add the support. (it will be ugly function calls instead of a*b you'll use mul64(a, b) ) Gcc at least 3.4.0 that I have does have 64 bit support and %llu works in printf and sprintf. mysprintf.s that I posted was from the autodocs, which uses RawDoFmt() i.e. system-call. RawDoFmt() does not support 64bits. -Wall is a switch for gcc that enables all warnings. (helps you catch an extra error or two before actually running the program) Also note, that the partial source code of AmigaOS is leaked. If you happened to find it on the internets, and you proceed to illegaly download it, then you'll might get a glimpse of info.c If you proceed to make a few changes, it could compile with gcc. Code:
m68k-amigaos-gcc -s -nostdlib -noixemul -Os -o foo mystartup.s info.c Code:
-rwxrwxr-x 1 alex alex 2120 Mar 12 20:29 foo |
13 March 2017, 11:59 | #19 |
Unregistered User
Join Date: Sep 2012
Location: Copenhagen / DK
Age: 44
Posts: 4,190
|
Maybe I am damaged from mainly using C++, but can't you overload the + operator if you make your own 64 bit type?
|
13 March 2017, 12:01 | #20 |
Registered User
Join Date: Aug 2012
Location: RAM:
Posts: 83
|
No operator overloading in C.
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
This Amiga game was lost for two decades, and now it's out on Steam | Shoonay | Retrogaming General Discussion | 16 | 22 May 2019 12:07 |
English Amiga Board Joins Electronic Arts' Affiliate Programme | CodyJarrett | News | 14 | 07 April 2015 12:56 |
Falling at the 1st.... well last | Hockmiester | support.WinUAE | 2 | 26 March 2013 16:46 |
On the 1st day of January... | Fissuras | Retrogaming General Discussion | 1 | 12 January 2003 06:42 |
1st Sensible Soccer | Nico | request.Old Rare Games | 1 | 13 May 2002 15:37 |
|
|