Saturday, October 17, 2026

The Battle Chess Disk That Was Full, Empty, and Absolutely Fine

There is a particular kind of debugging problem that only old computers can provide.

The software is nearly forty years old. The media is magnetic. The operating system lives partly in ROM. The documentation assumes you remember what a key is. And somewhere along the way somebody installed an antivirus written when “computer virus” was still a sufficiently new concept that people were not always entirely sure how one moved from machine to machine.

This investigation started with an old Amiga copy of Battle Chess.

Which is appropriate, because Battle Chess gave software development one of its better debugging metaphors: the duck.

Battle Chess and the duck

According to a piece of Interplay lore, the artist responsible for the queen’s animations knew that the producer had a tendency to request some change during every review.

So he prepared the queen exactly as he wanted her, and added one deliberately unnecessary feature.

A pet duck.

The duck was carefully animated alongside the queen, but kept separate from the actual animation. When the producer reviewed the work, everything important survived untouched. There was just one requested change:

lose the duck.

The trick was not that the duck hid a defect. Quite the opposite: it provided an obvious, harmless target for scrutiny so that the thing the artist actually cared about could pass through review unchanged.

Years later, Battle Chess provided me with another duck.

This one lived in its boot block.

And I fell for it completely.

Enter Greaseweazle

The whole investigation started because I was preserving old Amiga floppies.

For that, I was using a Greaseweazle.

This is particularly interesting with Amiga disks because the Amiga and the PC approached floppy disks almost from opposite directions.

A traditional PC floppy controller is heavily format-aware. Software normally asks the controller for a particular cylinder, head and sector, and the controller takes care of finding the sector, decoding the MFM data, checking the CRC and returning the contents.

That works very well as long as the disk looks like something the controller understands.

If it does not, software has very little room to negotiate.

The Amiga floppy subsystem was deliberately much less opinionated.

The hardware can DMA the encoded track data into memory and leave interpretation to software. Normal AmigaDOS tracks have a defined format, of course, but software is not limited to that format.

That freedom is one reason Amiga software accumulated such an impressive collection of custom track layouts, unusual sync words, protections and other creative abuses of magnetic media.

Very approximately:

PC: software: give me sector 7 controller: certainly I know what a sector is

while the Amiga is closer to:

hardware: here is the encoded track data software: excellent I'll decide what it means

Greaseweazle goes lower still for preservation purposes.

Instead of returning decoded sectors, it records the timing of the magnetic flux transitions coming from the drive.

For a normal AmigaDOS disk, it can decode directly into an ADF:

gw read --format=amiga.amigados disk.adf

For preservation, however, I also like keeping a flux-level image:

gw read --revs 5 disk.scp

That records several revolutions of the disk.

Those transitions can later be decoded again, compared between revolutions, interpreted by other software, or written back to a floppy.

So, roughly:

PC floppy controller: sectors Amiga floppy subsystem: encoded track data Greaseweazle: flux-transition timing

For old-media archaeology, that lowest layer is extremely useful.

Battle Chess, however, did not initially look like a magnetic-media problem.

The disk read cleanly.

The filesystem was there.

The strange part came afterward.

The original mystery

Opening the Battle Chess disk window in Workbench produced:

Guru Meditation #87000008

The timing was interesting.

Workbench opened the window.

The icons appeared.

Then, just before it seemed to finish opening the drawer:

Guru.

My first thought was damaged media.

So I found another Battle Chess image online.

It crashed in exactly the same way.

That was the first major clue.

And the beginning of several excellent wrong ideas.

Comparing the two disks

The next tool entering the story was amitools, particularly xdftool.

If Greaseweazle lets me ask what was physically recorded on the floppy, xdftool lets me ask what the Amiga filesystem structures say about it.

It understands OFS and FFS volumes and can inspect directories, files, root blocks, allocation bitmaps and other filesystem structures directly from an image.

For example:

xdftool battle_chess.adf list / detail

showed:

Battlechess BattleChess.info Chesstodh0 ChessToDH0.info Disk.info EndCLI Icon.Library LoadWB s System-Configuration

Nothing obviously missing.

Then I compared my image against the one found online.

They were remarkably similar.

The actual game and filesystem contents were essentially the same. Apart from a few administrative differences in the root block, the significant difference was at the beginning of the disk.

My copy contained a custom boot block:

This disk was installed with TRISTAR-Viruskiller V1.1 Written 1988 by Transformer (Disk is protected against the SCA-Virus)

The online image did not.

There were also a few differences in the root-block metadata around block 880.

But the content of the disk was, for practical purposes, the same.

That made the boot block extremely difficult to ignore.

The virus hypothesis — and my own bias

The antivirus explanation was especially attractive to me because I grew up in exactly that period.

Computer viruses in the late 1980s and early 1990s occupied a peculiar place in popular computing culture.

They were very real.

But the understanding of how they propagated was not always equally real.

I still remember a computer-science teacher in high school, around 1992, asking us to unplug the PCs from the mains because a virus had been discovered and there was concern that it might propagate through the electrical wiring.

That memory matters because it explains my own bias here.

When I found:

TRISTAR-Viruskiller SCA-Virus

inside the boot block of a disk producing a mysterious Guru, my brain immediately assembled a satisfying story:

The disk had a virus.
Somebody tried to clean it.
Something survived.
Now that something is upsetting the system.

It was plausible.

It fit the period.

And it was dramatically better than “some filesystem bit is wrong.”

That should probably have been a warning.

All the boot block actually proved was:

Someone, at some point, was concerned enough about viruses to install TRISTAR-Viruskiller.

It did not prove that this particular disk had been infected.

It did not prove what the owner understood about boot-block viruses.

And it certainly did not prove that the present failure had anything to do with malware.

Still, it was difficult to resist.

It was our first duck.

Another suspicious character: chesstodh0

The disk startup sequence was very short:

chesstodh0 LoadWB endcli > nil:

LoadWB and EndCLI are ordinary enough.

chesstodh0 was more interesting.

Looking into the executable revealed:

UNIT A && World of Wonder presents NR. 47: BATTLECHESS Thanx to Blackie for the original ...

It also contained references to graphics.library, dos.library and icon.library.

A crack-group executable.

Running before Workbench.

On a disk that crashes Workbench.

This was an exceptionally good duck.

Perhaps it installed something resident.

Perhaps it changed DOS state.

Perhaps it left something behind that later failed.

So I removed it from startup-sequence.

Its messages disappeared.

The crash did not.

Remove the whole Battle Chess boot environment

There was an even cleaner way to eliminate that branch.

I booted a known Workbench 1.3.2 disk instead.

Once Workbench was running, I removed that disk, inserted Battle Chess and opened its drawer.

Now none of the Battle Chess boot-time software had run:

no Battle Chess boot block no TRISTAR code no chesstodh0 no Battle Chess startup-sequence no Battle Chess LoadWB no Battle Chess EndCLI

And yet:

87000008

So whatever the problem was, simply mounting and opening the Battle Chess disk was enough.

The surprisingly important write-protect tab

Then came the observation that changed the investigation.

Make the ADF write-protected:

works.

Make exactly the same image writable:

Guru.

That was much more interesting than another ROM revision or another executable.

Nothing about the visible contents had changed.

Workbench could clearly read the disk.

It could find the directory.

It could load the .info files.

It could draw the icons.

But whether the disk was allowed to be written determined whether the system survived opening the drawer.

At this point there were two facts:

same disk same Workbench operation write-protected -> works writable -> crashes

The obvious next question was no longer “what strange thing is the emulator doing?”

It was:

Does the real Amiga do the same thing?

Ask the Amiga

My first physical-hardware test had been misleading for a wonderfully mundane reason:

the disk had been write-protected.

So I returned to the physical Amiga.

Same disk.

Same operation.

But this time I opened the write-protect tab.

Workbench opened the drawer.

The icons appeared.

Then:

Guru Meditation.

Exactly the same behaviour.

That result was decisive.

There was no longer an emulator versus hardware problem to explain.

The real machine and the emulator agreed.

More importantly, they agreed on the one variable that mattered:

write-protected -> works writable -> fails

Only now did it make sense to stop looking at execution environment and start asking what the Amiga itself was complaining about.

What does 87000008 mean?

The Guru was not a random CPU exception.

87000008 is a DOS alert corresponding to:

key already free

Now the investigation had moved decisively into filesystem territory.

Classic Amiga filesystems use block numbers as keys.

They also maintain an allocation bitmap recording which blocks are occupied and which are available.

So “key already free” can be read fairly literally:

DOS is trying to release or manipulate a block which its allocation data already says is free.

That was a remarkably specific clue.

Especially given the previous experiment.

A read-only disk worked.

A writable disk did not.

Time to ask the filesystem what it believed.

Asking the filesystem

The volume is an Amiga OFS filesystem: DOS\0.

An Amiga double-density floppy contains 1760 blocks of 512 bytes.

The root block is conventionally placed in the middle:

1760 / 2 = 880

So block 880 is the volume root.

Among other things, the filesystem root leads us to the allocation bitmap: the structure responsible for recording which disk blocks are free.

xdftool can look at the same filesystem from two useful directions.

First, which blocks are actually referenced by files and directories?

$ xdftool battle_chess.adf bitmap node / all entries brief 0: .........D. ........... 880: V.......... ........... 1408: ........... .....HdHdHd 1430: dHdEEdddddd ddddddddddd 1452: ddddddddddd ddddddddddd ...

Here:

V = volume/root D = directory H = file header d = file data E = extension block

Clearly the disk contains a filesystem.

Clearly many blocks are occupied by files.

Then I asked the allocation bitmap which blocks were free:

$ xdftool battle_chess.adf bitmap free brief 0: ..FFFFFFFFF FFFFFFFFFFF 22: FFFFFFFFFFF FFFFFFFFFFF 44: FFFFFFFFFFF FFFFFFFFFFF ... 880: FFFFFFFFFFF FFFFFFFFFFF ... 1430: FFFFFFFFFFF FFFFFFFFFFF ...

Almost the whole disk was marked free.

Including blocks that the filesystem tree was actively using.

There it was.

A full disk convinced that it was empty

The filesystem said:

these blocks contain my files

The allocation bitmap said:

never heard of them

That contradiction explains the strange behaviour remarkably well.

Reading the disk did not require repairing the inconsistency.

The directory structure existed.

The file headers pointed to the correct data.

The icon files were readable.

Workbench could populate the window.

As long as the disk remained read-only, nobody had to reconcile the filesystem tree with the allocator’s version of reality.

But once writes were permitted, AmigaDOS eventually entered a path involving allocation bookkeeping.

At that point it encountered a block that the filesystem considered occupied while the bitmap already called it free.

And DOS complained, rather accurately:

KEY ALREADY FREE

Now all the experiments lined up:

Amiberry + write-protected disk -> works Amiberry + writable disk -> Guru real Amiga + write-protected disk -> works real Amiga + writable disk -> Guru

The machine did exactly what its metadata told it to do.

The metadata simply happened to contradict itself.

Greaseweazle and amitools: two layers of archaeology

One thing I particularly like about this case is how well the tools complemented each other.

Greaseweazle answers questions about the physical recording:

Can I read the disk reliably? What flux transitions are actually present? Can I preserve several revolutions? Can I return to the raw evidence later?

amitools answers questions about the filesystem constructed from that evidence:

What does AmigaDOS think this block is? Which blocks belong to a file? Where is the root block? Which blocks does the allocation bitmap call free?

Those are very different layers.

And keeping them separate is useful.

In this case the magnetic media was readable.

The logical file structures were readable.

The allocation metadata was wrong.

Greaseweazle gave confidence that the image represented the physical disk.

xdftool made it possible to interrogate what the filesystem itself believed.

Together they turned a thirty-something-year-old floppy into something surprisingly close to a modern forensic exercise.

What broke the bitmap?

That part remains archaeology.

Possible explanations include:

  • a badly mastered crack release;
  • a copying tool that reproduced the filesystem contents without correctly rebuilding the allocation bitmap;
  • an interrupted filesystem operation;
  • virus activity;
  • antivirus activity;
  • deliberate construction of a disk expected always to remain write-protected;
  • or some forgotten utility doing something perfectly reasonable by the standards of 1989.

The comparison with the online image is particularly interesting here.

My physical image and the online copy were almost identical in their actual filesystem contents.

The conspicuous difference was the boot block: mine contained the TRISTAR Viruskiller installation.

Yet both copies exhibited the same writable-disk failure.

That makes the antivirus boot block very poor evidence for the cause of the problem.

But excellent evidence for how easily an investigation can be distracted.

It was the duck.

Looks great. Lose the duck.

This investigation had no shortage of attractive suspects:

  • old magnetic media,
  • an emulator,
  • different Kickstart revisions,
  • cracked software,
  • a strange startup utility,
  • an antivirus boot block,
  • the SCA virus,
  • possible resident malware.

Some were reasonable hypotheses.

Some were historically fascinating.

One of them literally contained the word:

VIRUS

And none was responsible for the crash.

The actual problem was much quieter:

filesystem tree: these blocks contain my files allocation bitmap: those blocks are free

For decades that contradiction could remain harmless as long as the disk stayed write-protected.

Nobody asked the filesystem to reconcile the two stories.

The moment we did, AmigaDOS answered with surprising precision:

KEY ALREADY FREE

Battle Chess had already provided the appropriate debugging lesson.

When something conspicuous is absorbing all the attention:

Looks great. Lose the duck. Check the bitmap.

No comments:

Post a Comment