The plague of bad Amiga programmers

Having seen how (differently) good Commodore managers and engineers have been at making our beloved platform evolve, it is time to also talk about another source of huge problems that has caused so many bloodbaths: incompetent programmers.

I’m referring to those who, by definition, have been unable to learn the rudiments of (correct, of course) programming and develop software capable of running on any configuration, both hardware and software, of the parent company’s family of machines, despite the latter being very generous in providing all the necessary documentation (with the well-known Amiga Kernel Manual book series in pomp).

Let’s be clear that the Amiga is not the only system where inept programmers have done damages, as that of people who went too quickly from hoe to keyboard is a general problem, but having been my computer habitat for several years (and still being a fan of it today) it is the one that made me feel the most at first hand and take note of the tragic situation.

Being ignorant does not necessarily have a negative connotation: it indicates the state of those who ignore, precisely: of those who lack adequate knowledge in a particular field (whatever that may be). But it is not a permanent condition, since it can be remedied by adequate study.

It is not, however, nor should it be an excuse, precisely because it is possible to “iron out the differences” and put oneself in a position to be able to chew a subject correctly. Especially in the age of the information boom and, above all, in the boom of the Net first (BBS) and the Internet later, ignorance is not an extenuating circumstance, but an aggravating circumstance when mistakes are made as a result of it.

All this is net of errors that can happen and that in computing have a precise name: bugs. Of which, no programmer can consider himself exempt, no matter how presumptuous and boastful developers may say. In short, bugs do happen (“shit happens“, say our English-speaking friends), although this must not give rise to ignoring the good practices that should be put in place to reduce or eliminate them: here, too, it becomes a question of ignorance (lack of tools in one’s mental “toolbox”).

Living within one’s own four walls

Unfortunately, and as I had anticipated, Amiga was a platform literally infested with software developed on the feet of incompetents, without adequate knowledge and without putting in place measures to ensure that it could run on systems other than its own.

A blind and solipsistic development, in which the only point of reference remains the backyard, ignoring the rest of the world. It is the classic case of “it works on my computer!”, in front of which one can only snicker pitilessly, just for laughs.

Because that’s exactly what used to happen: you’d slip in the floppy disk of a game or a demo and it wouldn’t show any signs of life, it wouldn’t work properly, or the classic screen so “dear” and so well known to amigans would appear:

Or you would realise it the moment you had upgraded your wonderful machine: the coveted 512kB additional memory expansion, or the ROM with the new version of Kickstart (the most important part of the OS, which served at boot time and contained much of the main code), or the accelerator card you had dreamt of next to the Samantha Fox poster:

Sometimes all it took was the addition of a second disk drive to find that some application no longer worked, due to the slight memory consumption associated with it.

Men with skills best suited for farm work

These were all ominous and, unfortunately, common scenarios that related to the absurd light-heartedness and recklessness with which those products were developed, and which unfortunately are still surprisingly fashionable today, as I was recently able to discover in the largest amateur forum (EAB), which prompted me to write this article, the contents of which I quote from the latest relevant comments on the subject:

I have a small bonus question: Is there an official mention that forbids writing 8-bit (byte) to a custom register?
Taking for example AUDxVOL, where only the 7 low bits are used, with the other bits being marked as “not used” in the doc, which means must be set to zero.
I wondered how the hardware reacted to a byte write in that scenario? (from testing at least in WinUAE, it appears to work fine.)

and the subsequent response:

Upper byte (bits 8-15) = lower byte (might be different on some 020+, e.g 060, but in this case it doesn’t matter), because audio volume only uses bits 0-6, so it works fine. You can also have any value in bit7 (I’m doing that in my 4kb intro PT player, no problems).

Needless to say, the answer should have been quite different, considering that yes: there is an official mention of this, which can be found in the first introductory chapter of the Amiga Hardware Reference Manual, and of which I quote the relevant part:

Do not write spurious data to, or interpret undefined data from currently unused bits or addresses in the custom chip space. All undefined bits must be set to zero for writes, and ignored on reads.

The meaning of which should already be intelligible in itself, but reading the description of the audio channel volume register certainly helps to dispel any remaining doubts:

Bits 15-07Not used
Bit 06Forces volume to max (64 ones, no zeros)
Bits 05-00Sets one of 64 levels (000000=no output (111111=63 1s, one 0)
Audio Channel Volume (AUDxVOL)

The last comment, therefore, where the budding programmer (who knows which “grass”) candidly, and perhaps proudly, states that he uses bit 7 in his (audio) player of only 4kB of space…

The gallery of horrors

If all this is recent stuff, where time and experience should have brought advice as to how best to act (and, above all, study), one can imagine what the situation was like at the time, with programmers who indulged in all kinds of filth in order to make the game or demo run faster… or simply (!) out of sheer ignorance.

One could even turn a blind eye on this, remaining within the sphere of demos: it is difficult to expect professionalism from someone who may have read or plagiarised some bits of other people’s code and then decided to mess something up by seeing that, in the end, it “worked” (!).

What is unacceptable, however, is that poor quality code was produced for products that were marketed and ended up in the hands of users, because in this case, yes: professionalism is certainly demanded and reading the parent company’s documentation and applying its guidelines would have been the bare minimum.

Unfortunately, several of the thousands of “slaves” (a sort of interface between the game/demo and the main framework) of WHDLoad (a project initially created to be able to install games on a hard disk, later expanded to fixing bugs and adding new features such as, for example, support for joysticks/joypads with multiple keys and more) list modifications in their documentation, which make us realise how many games are affected by bad programming practices: a veritable gallery of horrors!

Let us take a few examples to show what kind of problems they were suffering from and which the programmers of the slaves had to fix. For Impossible Mission II:

we read:

The game requires an installed A500 Kickstart 1.3 image.
The kickstart image must be located in the directory “Devs:Kickstarts” and must be named “kick34005.A500”.

The game probably jumped on some routine that is specifically found in some address of Kickstart version 1.3, which is therefore necessary for it to work. Obviously, not only should no assumption be made as to which version of the OS is present on the system (unless it is a real requirement: e.g. for AGA machines, at least version 3.0 is assumed), but it is absolutely forbidden to jump to certain addresses in the ROM because it is easy for them to change from one version to another!

Instead Fright Night:

shows us a couple of quite common bugbears:

  • Memory ($C00000) redirected in expmem
  • Blitwaits inserted

The first could be called textbook (as it is not rare, unfortunately): the game assumes that there is always the infamous “Slow” RAM at the usual $C00000 address to which it is normally mapped. Too bad this is not always true, because this special type of memory is only present in the early Amiga 500 and 2000 models, while in the others you can find 1MB of Chip RAM, for example, or expansions with Fast RAM (which is obviously mapped to a different place!). The game will therefore never work in any other configuration that does not include Slow RAM.

The second is much more common (!), but should be taken with a grain of salt. Meanwhile and to clarify, the inclusion of so-called Blitwaits means that there are no checks that the Blitter has completed its last operation it is working on before it can be reprogrammed for the next one. Programming its registers while it is working can lead to disasters, which is why it is necessary for the processor to execute instructions to check that the Blitter is free before reprogramming it.

The code may even work without problems because by a series of coincidences everything always runs smoothly in the configuration used to test the game. But of course in another it can fail miserably, which is why you always have to put in Blitwaits. Granted, if the parent company’s guidelines state that you must check the status of the Blitter before reprogramming it, you must do so regardless!

Now, it may very well happen that the programmers have forgotten to do this. This is human and, as already mentioned, bugs exist for this reason. Nothing to say in this case: Errare humanum est, said the ancient Latins.

It is quite a different matter if, on the other hand, the programmers purposely avoided putting in Blitwaits to save memory space for the required instructions, as well as several clock cycles needed by the CPU to execute them. So in order to optimise space and performance. This is also because the programmers probably thought: “the Blitter will have finished the job for sure before we come back to programme it again“. In any case, the omission would clearly be malicious and deserving of flogging in the public square.

Distinguishing between bugs and intentionality is difficult, but whoever made the slave will have disassembled the game’s code and seen all the instances where the Blitter is programmed, so they can probably tell whether it is the implementation of a specific criminal scheme (life sentence deserved) or some occasional omission due to the developer’s forgetfulness.

Another game that presents itself as a patchwork of abominable practices is, on the other hand, Space Harrier II:

I dare not imagine the hard work that was required for developer of the slave, who was lavish with details in explaining the hell he found in the code of this case to be studied at university regarding the practices one should always abstain from:

  • Blitter waits added x47
  • Invalid memory accesses fixed x7
  • Screen clear routine rewritten to improve speed
  • Player avatar blit out of bounds blit fixed
  • Keyboard routine replaced to fix handshake
  • Timer subroutines fixed to avoid stack frame issues on 68010+
  • Frame delay/speed regulation added for very fast machines
  • Set CUSTOM2=0-5 to specify many frames to wait (minimum)
    (0 is off, 1 is draw every frame, 2 is every other frame, etc.)
  • Graphics fixed on fast machines due to copperlist not running in time
    (Mantis issue #4560)

I also quote parts of the slave author’s comment:

WORDS FROM THE AUTHOR

Access faults persisted with bosses and bonus levels, that should be fixed.
There were also some blits that addressed memory above the 512k chip limit.

It also turns out there are two revisions of the game. The latter release is
the same box art and only distinguished by a different disk label, so my
guess is Grandslam did a second production run and let the developer do some
bug fixes. There is an attempt to make the keyboard handshake actually work
(using a succession of divu instructions!) but not much else different.
[…]

The game has an incredibly expensive approach to rendering – clearing the
entire screen buffer each frame and redrawing everything! I’ve rewritten
the clearing code as the blitter was used with src A activated, meaning the
blitter was reading memory for no reason. Doing this meant I could use the
CPU in parallel to clear the screen a bit faster. The game starts drawing
immediately after so it is not possible to have the blitter run while the
game gets on with something else.

Ironically, despite running at about 15fps on a stock A500, this game runs
too fast on very modern accelerators/emulators, so I’ve added a frame delay
to clamp this. I recommend a setting of 2, i.e. 25fps, which is still a bit
faster than A500, but you can vary it if you wish (up to 5, which is 10fps).

Apart from the impressive mountain of Blitwait that had to be added (for which I highly doubt it could be programmer forgetfulness. No bugs, in other words: it’s a systemic problem!), there’s everything from various illegal memory accesses (beyond the available addresses) to the drawing of characters outside the boundaries of the screen, from the incorrect use of the Blitter to clear the screen (enabling a useless DMA channel, which is not used, but which obviously negatively affects performance) to Copperlists (programs executed by the other coprocessor, the Copper) that are not set correctly and create problems with systems equipped with faster hardware.

In this regard, the game is so poorly written that the creator of the slave was forced to add code to properly adjust the execution speed on faster systems, where it otherwise becomes unplayable. This, unfortunately, has been a plague of several games that were obviously written with their feet by inept programmers who did not take due account of the more advanced systems (accelerator cards have existed since the days of the Amiga 1000!).

This also has repercussions in the management of the keyboard, which in the Amiga needs a communication protocol that takes into account precise timings in order to function correctly, but which Space Harrier II got wrong from the very first version of the game, most probably by implementing a software wait cycle, through the execution of a certain number of instructions. A cycle that in faster systems was evidently executed very quickly, greatly anticipating the time needed to communicate with the keyboard controller and, therefore, not making it work properly.

The problem was so obvious that even the second version of the game tried to remedy it, but once again with a completely wrong “solution”, because it used division instructions (which are very slow in the first 68000 processors, but decidedly faster in more modern ones) to try to lengthen the execution time of the cycle, when instead the correct way should have been to use the timers in the system to schedule the appropriate amount of time to elapse, or to check the position of the electron beam by waiting for the right line to be passed (which equates to a certain amount of time having elapsed for the purpose).

I don’t know if there are any games that have done worse (I’d have to work my way through the thousands of slaves; which of course I have no intention of doing), but it seems fair to me that in addition to life imprisonment, the programmers should also have been given hard labour and 47 lashes (one for each missing Blitwait) for the string of disasters they managed to cause with just one game (the stuff of amateurs on the loose: people who would have been better off doing something else entirely, and staying away from programming).

Conclusions

I’ll stop here, because the examples I have cited cover the most important as well as common cases with which we have had to deal with games (and not only: the demos are authentic mines of similar “pearls”) badly written, not following Commodore’s guidelines regarding the correct programming of the Amiga.

For better or for worse, the ease of programming on these machines, combined with their greater accessibility (compared to PC et similia), has ushered in a horde of improvised programmers who have infested our beloved computers with products containing all sorts of dirty tricks or simply (!) making waste paper of rules created to guarantee the usability of software on all kinds of machines.

It is no coincidence that there are thousands of slaves (and others still in the works) trying to remedy this, but you can imagine for yourself the situation at the time, where all this was unfortunately not available, leading to despair many users “guilty” only of having had a different computer from those used to develop and/or test the game (or the demo).

Only Amiga developers made it possible!

Press ESC to close