Diary of an Amiga fanatic

Category Archives: Amiga OS4.x

In our previous tutorial in the “File Attributes” series we opened a file and printed if we managed to open it or not. In this tutorial we are going to obtain some information of a certain file. We will obtain it’s name, comment info and the file size.

Comment example

If you are not familiar with the comment part you just have a look at the above picture. For this example I created a file called “example.txt” for which I added a comment as well. Make sure you have this file in the same folder in which you would run the example.

Click here to download the (fileinfo.c) source code file.

In order for us to get this info we will use the function “ExamineObject” from the DOS Library. As you know we don’t have to open the DOS Library but we also don’t have to open our file to get the info we want. On to the show!

File Attributes - File info

Line 8 is setting up our ExamineData structure called “data”. In here all the info of our file will be stored if we succeed to get this. And as you might have guessed we will also use this to check if we managed to get all the file info.

Line 13 will try to get all the info of our file. IDOS->ExamineObjectTags is the function that will obtain this. It will require us to tell it a few things. EX_StringNameInput is telling it that the file we want to use is not open and will be given in a text string which we will provide in the next part. I don’t want to make it to complicated but we can also tell it to use a file that is already open and if we would we would use for example EX_FileHandleInput. Next up is indeed the name of our file in a text string. TAG_END will tell it that we have reached the end of our instructions. So what we are doing is get the info from a file called “example.txt” which is not currently open and store it in a box called data.

Line 15 will check if we succeeded in doing this. Our pointer (or box if you like) called data will be empty if we failed and full if we succeeded. Line 22 till 28 will take care of the part if it failed. If you want to see if this part actually works if it does fail try to change the name of the file (in the source code or the actual file) and you will be greeted by the failure message.

Line 18 till 20 will get the info we want. As you might have guess line 18 will get the name, line 19 the comment info and line 20 the files size. This will be printed on the screen and in my case I will be greeted with the below info.

File Attributes - Outcome

There is one more part left which is what we are doing on line 30. We need to cleanup and on line 30 we are freeing up what we have used using the IDOS->FreeDosObject function. We are telling it that we have DOS info in our data box which we no longer need so dispose of it. That’s it! Please let me know if something is not clear, you can’t get it to work or you have any other questions. I hope you learned something and until next time; Happy coding!


In this series called File attributes we will do some C programming related to files. In our first article we will open a file, check if we succeeded and close it again. Really basic stuff but also really cool to learn. When I say really basic stuff I mean in the eyes of experienced programmers. I talked about this before but I will bring it up again. Doing simple examples might seem silly. Why is this useful to me? It’s just opening a file and not programming some really cool demo effects. Remember The Karate Kid? Pointless exercises leading to nothing only to realize they do teach you and make you understand. It is the same with these simple examples. After doing so many you start to see the bigger picture at a certain moment.

We are going to use the Dos library to open our file. Just like the Exec library the Dos library is also already open when OS4.x is booted up. So there is no need for us to open it up and to close it when we are done.

Example text fileI created a file called “example.txt” containing one line of text in it that I use in our example. I place it in the same folder in which we will execute our example code.

One of the problems is to get the source code displayed in such a way that it is readable. To overcome this problem I have the source code file available for download and use screen shots showing parts of the code to explain it. Click here to download the (openfile.c) source code file.

File Attributes - Open File IncludesThe above lines of code are called includes. They include other files with code into our program. For example <stdio.h> includes code that will allow us to use the printf() statement in our program. The <dos/dos.h> include will allow us to use the dos functions to open and close files in our program. Normally I have a lot more in there even if I don’t use them. You might get some errors during the compiling of your code which is caused by not having a certain include file in there that provides the code for a function that you use. You will end up, like me, having a certain set of includes in your code even if you don’t use them. But I did not want to make it difficult by including a lot of includes.

File Attributes - Open File BPTR and startNow we are getting to the start of our program. The line “BPTR fh;” is setting up our file handle. What this means is that once we open our file we will store all the info in “fh”.

The line “int main(void)” plus the open curly bracket is the start of our program.

File Attributes - Open file FH statementNow we are getting to the main part of our program that will open our file. As you can see we will store all our info in “fh”. The statement “IDOS->FOpen” will open our file of choice. As you might have guessed the “example.txt” is the file we are trying to open here. The “MOD_OLDFILE” part indicates we want to open an existing file. There are other access modes but for now we will leave it at this. The last “0” bit has to do with the buffer size. The buffer size will determine how many bytes the stream buffer will have. What? Let’s say you want to move stuff from your house to the car and you have the choice of several boxes each having a different size. Will you pick a small box which can hold just a few items or a really big box that can hold a lot more items? Each has pros and cons. In our example we set it to 0 which means the default value. We won’t do anything with our file like reading or writing to it so it has no influence on our example.

File Attributes - Open File Checking the FileNext up we will have to check if the successfully opened our file. As you can see we use “fh” which will hold all the info including if we managed to open it or not. Actually it will be empty when we failed to open it. So if the value is anything but 0 we managed to open it. The statement “if (fh != 0)” will check if our file handle “fh” is not 0. The “!=” means NOT. If it is NOT 0 we managed to open the file and we will print that we managed to open the file. If we failed the “else” statement will print that we failed to open the file. Sounds rather easy doesn’t?

File Attributes - Open File Closing upWhat’s left to do is to close our file if we managed to open it. The statement “IDOS->FClose” will close our file. Again we use “fh” which is our file handle containing everything regarding our file. It makes sense to close whatever we have opened. The “return 0;” will end the program and let the system know we are done.

If you successfully compiled the program you will get the below output.

File Attributes - Open File OutputThat’s it for the first article regarding files. Next time we will do something else with our file. I hope you enjoyed it and more important learned something. Please let me know if something is not clear or if you have any other questions.

It was going to be a series of 4 articles explaining how to open a ReAction window in C on OS4.x. I had 3 released already with the fourth on pending. Instead of writing the fourth article I decided to take the three articles off-line and use them in my new Amiga Editor project.

I know you are thinking what is he on about this time? Why bring Mr. Miyagi in to this? Remember Daniel question having to do these chores? Why waste his time on this while he wanted to learn karate? If you are like me you must have wondered at some stage if you would ever get to be any better at programming. Sure after trying really hard we understand all these small examples of source code but how would that ever turn us in to real programmers? Understanding and manage to open a window is nice but how would that ever make me create a full blown program? The beauty of it is that you can and will. Why? Because at some stage you understand that all those small examples made you realize you understand how it all works. All those small examples gave you a complete understanding on how you program. Let me give you a small example. You come across some source code plus information on a subject you never dealt with and you might not understand that new subject yet you do understand the source code. You understand what the source code is doing and at that moment you realize you actually have learned the art of programming. I call this the “Wax On, Wax Off” moment. Of course you still have a lot to learn but you have made a major break through.

One of the next big moments is that you actually will come up with your own routine(s). You want to do something and you start thinking what if I would do it like this? These are great moments because you finally have moved beyond the simple example stuff in to the big league. Mark my words when I say you will get there. Happy coding!

I have not been this excited about a Basic language since Amos. The strange thing is that this Basic version has been around for a long time already and I just re-discovered it. What basic version I am talking about? Well ACE Basic Compiler of course. The big difference, and one to win you over, is the GUI support it has. Without having played a lot with it I already decided I should start a series of tutorials about ACE Basic. I believe this to be the perfect language for beginners to start programming on the Amiga.

The begin with I would really recommend you subscribe to the Amiga ACE mailing list. Once you are subscribed you can also download the latest version of ACE Basic Compiler from the Files section. The latest version can also be downloaded from Aminet. The installation instructions are pretty easy to follow. Everything is well documented so you won’t have any problems and if you do there is the ACE Basic mailing list and me of course.

The ACE Basic Compiler packages comes with the  AIDE (ACE Integrated Development Environment) which is a graphical front-end for the development of ACE programs. This makes it easy to compile your code compared to the more crude way of doing it from the shell. In this first tutorial I am going to show you how to compile ACE code both ways. First we need a very simple example that we can use for this.

print “Trying out ACE Basic Compiler”;
print “I like ACE Basic Compiler”;

Above you see our very simple example we are going to use in our compiling sessions. The command PRINT will print our sentence on the screen and the LOCATE command moves our cursor to the next line so that our two lines will not end up next to each other.

If you start AIDE and it is up and running you can select “Set” to get the file requester to open the source code file you want to run.

AIDE - Open source code file

If you select “Run” in the “Program” section it will run our example code.

AIDE - Running our code

Of course we want to create an executable file. You can set the folder in which the executable file can be placed. In Project you can select AIDE setup in which we will be able to set our folder. In “Temp Dir” you can select the folder which I have set to “Applications:ACEBASIC”.

AIDE - Setting the folder for our executable files

Once you click on “Executable” in the “Make” section our code will be compiled and the executable file will be placed in the “Applications:ACEBASIC” folder. Let’s move on to compiling from the shell. Let’s say our source code file is called “howtocompile.b” we would need to execute the below two commands.

ace howtocompile.b
bas howtocompile

The problem I ran in to is that “bas” would not run saying it is not executable. What you need to do is set the “script” option for the “bas” file. The “bas” file is located in the “bin” folder of “ACE:”.

Setting the script option for the BAS file

By default the “bas” script is looking for your file in the “RAM:T” folder. You can change the location by editing the “bas” script file in the editor of your choice. I am not sure if it can be set somewhere else like for example in the AIDE set up. For now I just moved my file to the location the “bas” script file is looking for. The ACE package comes with a lot of documentation which I would recommend you read. That’s it for starters. Next time we will dive deeper in to basic programming.

Working with screens using the C programming language on the Amiga is a first for me. Remember how easy it was in Amos? I had seen some C code using screens before and frankly it scared me. Actually it is not really difficult to open a screen on the Amiga using C. As with all my articles I will try to take all the difficult information that is out there on a particular subject and make it understandable. The same goes for the example source code that is out there. I come across so many examples that even make me scratch my head. Especially when you can write in a much better and understandable way.

What steps do we need to take in order to open a screen?

Step 1 – Declare a pointer that will hold our screen structure (Line 10)
Step 2 – Setting up our screen’s parameters (Line 12 till 27)
Step 3 – Open the Intuition Library and Interface (Line 33 till 44)
Step 4 – Opening our screen and check if we managed to open it (Line 45 till 48)
Step 5 – Cleaning up by closing our screen, Intuition Library and it’s Interface (Line 50 till 79)

00 #include <stdio.h>
01 #include <exec/types.h>
02 #include <intuition/intuition.h>
04 #include <proto/exec.h>
05 #include <proto/intuition.h>
07 struct Library *IntuitionBase = NULL;
08 struct IntuitionIFace *IIntuition = NULL;
10 struct Screen *my_screen = NULL;
12 /* Declare and initialize our screen structure */
13 struct NewScreen my_new_screen=
14 {
15 0, /* LeftEdge */
16 0, /* TopEdge */
17 320, /* Width */
18 200, /* Height */
19 3, /* Depth */
20 0, /* DetailPen */
21 1, /* BlockPen */ 
22 CUSTOMSCREEN, /* Type of screen */
23 SPRITES, /* ViewModes option */
24 NULL, /* Font option */
25 NULL, /* Title of the screen */
26 NULL /* Gadgets option */
27 };
29 int main (void)
30 {
32 /* Opening the Intuition Library */
33 IntuitionBase = IExec->OpenLibrary("intuition.library", 50L);
35 /* Could we open the Intuition Library? */
36 if (IntuitionBase != NULL)
37 {
39 /* Open the Intuition Interface */
40 IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase, "main", 1, NULL);
42 /* Did we get the Intuition Interface? */
43 if (IIntuition != NULL)
44 {
45 my_screen = IIntuition->OpenScreen(&my_new_screen);
47 if (my_screen !=NULL)
48 {
50 /* If the screen is still open we need to close it */
51 IIntuition->CloseScreen(my_screen);
52 }
54 /* We could not open our screen */
56 else
57 {
58 printf ("Unable to open our screen!\n");
59 }
61 /* If the Intuition Library Interface is open, close it */
62 IExec->DropInterface((struct Interface *)IIntuition);
63 }
65 /* We could not open the Intuition Library Interface */
66 else
67 {
68 printf ("Unable to open the Intuition Library Interface!\n");
69 }
71 /* If the Intuition Library is open, close it */
72 IExec->CloseLibrary(IntuitionBase);
73 }
75 /* We could not open the Intuition Library */
76 else
77 {
78 printf ("Unable to open the Intuition Library!\n");
79 }
81 return 0;
82 }

When you compile the code and run it you will see it flashes a black screen for just a second. This is because we have not instruct our little example to do anything with our screen. We will do a lot more in the coming articles regarding screens.

Let’s analyse the source code.

10 struct Screen *my_screen = NULL;

Line 10 will set up a pointer called “my_screen” which will hold our screen structure. In other words if we open our screen successfully we will store the screens info in the “my_screen” pointer. We are going to use this to make our screen do things. To put it simple; every time we want to do things with our screen we need to refer to which screen we would like to use which means we will refer to “my_screen”. If my wife asks me to get a certain pair of shoes she will always refer to one of the 200 boxes she has. Without this info I would not be able to know what to do and shout some error codes.

12 struct NewScreen my_new_screen =
14 {
15 0, /* LeftEdge */
16 0, /* TopEdge */
17 320, /* Width */
18 200, /* Height */
19 3, /* Depth */
20 0, /* DetailPen */
21 1, /* BlockPen */
22 CUSTOMSCREEN, /* Type of screen */
23 SPRITES, /* ViewModes option */
24 NULL, /* Font option */
25 NULL, /* Title of the screen */
26 NULL /* Gadgets option */
27 };

Line 12 till 27 will define our screens parameters. Here we will define for example the width and height of our screen. For the moment we will not pay much attention to this. Going in to depth on this might just scare you away. Our screen will be of the type CUSTOMSCREEN and the width is 320 and the height is 200 is all you need to know at this stage. The width and height speaks for itself and a CUSTOMSCREEN means that we control how it looks, talks and breaths. In order words we decide the width, hight, colours etc.

45 my_screen = IIntuition->OpenScreen(&my_new_screen);

Line 45 will open our screen and store the info in our “my_screen” pointer. The part “(&my_new_screen)” tells the system how our screen should look like.

47 if (my_screen !=NULL)
48 {

Line 47-48 will check if we managed to open the screen. If not the program will jump to line 55-58 and display the message that the screen could not be opened.

51 IIntuition->CloseScreen(my_screen);

Line 51 will close our screen once we are done. Remember I was talking about the fact that we would use our “my_screen” pointer every time we would do something with our screen? Here we are closing our screen and referring to which screen we would like to close. In other words my wife asked me to put her pair of shoes back in box number 145. Next time we will actually keep our screen open until we decide it should be closed. Happy coding!

The idea for this article came from a posting from Hans de Ruiter over at OS4Coding.net in which he wanted to know how you could identify your machine. He talked about the function GetMachineInfo() from the expansion library that could do this. With that info I set out to create some code that would do exactly that; identifying our machine. Unfortunately the GetMachineInfo() function is not that detailed when it comes to identifying your machine. It can identify the below machines:

MACHINETYPE_UNKNOWN – Unknown hardware
MACHINETYPE_AMIGAONE – any AmigaOne model (including XE, SE, MicroA1 or XC).

The problem lies in the AmigaOne identifier since it will only report back “AmigaOne” and not if it is a XE, SE, MicroA1 or XC. I will do some more digging into this to see if there is  way to determine what exact model of AmigaOne it is. For now this example will demonstrate some new programming code and get you to extend your knowledge. Let’s have a look at the code.  

01 #include <stdio.h>
02 #include <expansion/expansion.h>
04 #include <proto/exec.h>
05 #include <proto/expansion.h>
07 struct Library *ExpansionBase = NULL;
09 struct ExpansionIFace *IExpansion = NULL;
11 int main (void)
13 {
15  /* Opening the Expansion Library */
16  ExpansionBase = IExec->OpenLibrary(“expansion.library“, 50L);
18   /* Did we manage to open the Expansion Library? */
19   if (ExpansionBase != NULL)
20  {
22     printf (“We opened the Expansion Library!!\n”);
24     /* Open the Expansion Interface */
25     IExpansion = (struct ExpansionIFace *) IExec->GetInterface (ExpansionBase, “main“, 1, NULL);
27      /* Did we get the Expansion Interface? */
28      if (IExpansion != NULL)
29     {
31       printf (“We did get the Expansion Interface!!\n”);
33        STRPTR machine;
35        IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
37        printf(“Blimey! Your model = ‘%s’\n”, machine);
39        /* If the Expansion Library Interface is open, close it */
40        IExec->DropInterface((struct Interface *)IExpansion);
41         }
43     /* We could not open the Expension Library Interface */
44     else
45     {
47    printf (“Unable to open the Expansion Library Interface!\n”);
48    }
50   /* If the Expansion Library is open, close it */
51   IExec->CloseLibrary(ExpansionBase);
52   }
54   /* We could not open the Expansion Library */
55   else
56  {
58   printf (“Unable to open the Expansion Library!\n”);
59  }
61 return 0;
62 }

If we compile our program and run it from the shell we will get the below output.

Running the ID machine program

As you can see I still add the code of printing if you managed to open a library or get the interface. You can leave that out if you wish.

The only strange piece of code on the block is:

02       #include <expansion/expansion.h>

05       #include <proto/expansion.h>

33        STRPTR machine;
35        IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
37        printf(“Blimey! Your model = ‘%s’\n”, machine);

Line 02 and 05 will add some includes so that we can use the Expansion base library functions in our program. Line 33 till 37 is the code that will actually perform our little magic trick.

The AutoDocs from the SDK describe GMIT_MachineString as:

GMIT_MachineString (STRPTR *) — Machine model as a human-readable string.

GMIT_MachineString is part of the GetMachineInfoTags function. We use IExpansion-> to call upon GetMachineInfoTags. The value returned by GMIT_MachineString is stored in “machine”. We have set-up “machine” on line 33 which sets up “machine” as a string pointer. In line 35 the & sign will store the value as a string pointer. And at line 37 we are printing the value of “machine” which is in this case AmigaOne.

This example also shows one of the difficult parts of programming on the Amiga OS; trying to understand the AutoDocs which describes all the functions. At least for me this is the case. It does describe all the functions but not really how to use them. Well in some cases they do provide some examples but mostly it just mentions all the functions which make almost no sense. It certainly would scare some new programmers away since they might become frustrated in not understanding it. I will try to address the AutoDocs in some future articles to make it easier to understand and at some point make it possible to actually read and understand them yourself. Till next time and happy coding!