One of the things lacking with the Amiga 68000 Kickstart Relocator project is a GUI to manipulate the flash ROMs, the original project had one in a fork, but it was proprietary. It doesn’t support DiagROM at all and doesn’t support the dual-ROM firmware I wrote for version 3.0. So, I decided to spend some nights of free time developing a tool to do this, working out how to develop GUIs for Amiga OS as I go. Here is some of my findings.
I’ve been a C developer for a very long time, so I decided that C would be a good language for this. Especially since Amigas have very limited CPU and RAM by today’s standard so I didn’t want to go too high level. The tool needs to support Kickstart / Workbench 1.3 because some users will still have 1.3 as their main motherboard ROM. This is actually a big limiting factor because most of the toolkits to help you develop are based on Amiga OS 2.0 or higher.
I therefore decided to use pure Intuition which is the built-in GUI window management library. It has “windows” which are very much like you would expect and “gadgets” which are essentially basic widgets you can add to a window. For dialogs such as loading a file (called “requestors”), there are built-in toolkits in Amiga OS 2.0, but not 1.3. I therefore decided to use a library ReqTools 2.2 which supports 1.3 but also wraps around the 2.0 “requestors” if they exist.
There were a few resources I used as reference when developing. For a book I used the Amiga Intuition Reference Manual (I wish I could get a physical copy of this!). There is also a simple tool called PowerSource which lets you draw and configure windows and gadgets, it will then generate source code for this. I mostly used PowerSource as a reference for how to generate certain visual outputs based rather than designing my entire UI using the tool.
Everything is very struct heavy which I guess is to be expected. They are also typically chained. For example when you create a struct instance for a gadget you point to another gadget, and so on with
NULL as the final gadget. When you create a window you point to the first gadget and it iterates through the list. Borders can be added to gadgets which are based on relative coordinates and colour IDs, this can give a 3D-like effect.
The application then basically renders things and waits for events to fire to react. Since things are typically single-threaded you don’t have to worry too much about race conditions either (although there is co-operative yielding with some caveats).
One of the most difficult things I found was to make a text gadget that was read-only. Amiga OS 1.3 doesn’t have an easy way to say that a user cannot edit the text in it, you can “disable” a gadget, but this covers it in a chequer pattern. In the end I created a button gadget (known as a BOOL gadget) that doesn’t react when clicked, I think added two labels to it, the first outside it and actually a label, the second sitting on top with the contents. The colours for the border were inverted compared to the rest of the buttons to give it an indented look as compared to a raised look for the buttons. The underlying string buffer can be edited and then the gadget redrawn. The end results turns into these ROM detail boxes in the image below:
After a few days of tweaking positions and hooking things up I ended up with the first release version of the application. The only minor pain point is you need to copy a library to your
LIBS: directory first to support ReqTools. A few more images below:
You can see the source code for this in the
Software/gui.c file in the 68000 Flash Kickstart Relocator tree on GitHub.
There is still more work to do for another day, probably the two biggest things are:
- Erase at a block level to flash individual ROMs instead of the whole device.
- Flash using buffered blocks so that we don’t load the entire ROM into RAM first before flashing it (requires a RAM expansion for most Amiga 500s to actually flash a ROM right now).