A system extension (INIT) for 68k Macs that fixes desktop pattern corruption at 32bpp
(Millions of Colors) on Mac OS 7.6 through 8.1. QuickDraw's FillCRgn and
EraseRect traps produce garbled rainbow pixels behind desktop icon labels,
masks, and text editing areas. DesktopFix tail-patches both traps, reading the
PixPat tile data directly and rendering correct 32bpp pixels to the
framebuffer — bypassing the broken code path entirely.
At Millions of Colors (32bpp), QuickDraw's FillCRgn and
EraseRect traps fail to properly tile the desktop PixPat
pattern. Instead of the familiar Mac OS watermark background, you get corrupted
rainbow garbage pixels behind icon labels, masks, and text editing areas.
The bug was first discovered on a real Quadra 700 running Mac OS 8.1 at Millions of Colors, and later confirmed on QEMU Quadra 800 emulation. Any 68k Mac capable of 32bpp output can hit this bug.
It went unnoticed for decades because 32bpp was uncommon on 68k Macs — most machines like the Quadra 800 only have 1MB of onboard VRAM, not enough for Millions of Colors at usable resolutions. You needed a NuBus video card or expanded VRAM. QEMU provides 4MB, making the bug trivially reproducible.
Finding the right trap to patch took extensive diagnostic work — injecting bright colored fills into different QuickDraw traps to see which one actually draws behind desktop icons. The answer wasn't obvious.
EraseRect (trap $A8A3) — wrong trap entirely.
EraseRect handles menus and titlebars, not icon backgrounds. Nine versions chasing the
wrong QuickDraw call.
FillCRgn (trap $AA12) with solid color fill. Right trap!
But the fix painted a solid purple bar over the icon column — the desktop is a tiled
pattern, not a solid color.
PtInRgn region-accurate fill with corruption detection. But rainbow corruption
defies simple heuristics — false positives during icon drags, false negatives on
actual corruption. Color distance sampling, local variance, uniform-far-from-desktop checks
— nothing worked reliably.
PixPat tile data directly, render
pattern ourselves at 32bpp. Bypass QuickDraw entirely. Don't detect corruption — just
always render it correctly.
EraseRect patch for text rename corruption. Both bugs
fixed. Key discovery: Finder does text editing in its own CGrafPort,
not WMgrCPort — so the EraseRect patch reads bkPixPat from
whatever color port is current.
DesktopFix installs as a standard INIT at boot (shows a wrench icon in the startup parade). It tail-patches two QuickDraw traps — after the originals run and produce corruption, DesktopFix overwrites with correct pixels:
FillCRgn runs (produces corruption at 32bpp)PixPat's tile bitmap (patData — raw 8bpp pixel indices)pmTable->ctTable[pixVal])RGBColor to 32bpp framebuffer formatGDevice PixMapPtInRgn respects the exact region shape (not just bounding box)Same rendering approach, but for rectangles. When you rename a desktop icon, the Finder erases the text editing area and its surroundings. At 32bpp, this produces the same corruption.
Key difference: the Finder does text editing in its own port,
not WMgrCPort. So this patch reads the background PixPat from whatever
CGrafPort is current (checking portVersion & $C000 to confirm
it's a color port).
The Mac OS desktop background is drawn using a PixPat (pixel pattern) —
typically the Mac OS watermark pattern stored at 8bpp with a CLUT (Color Lookup Table). When
QuickDraw needs to fill a region with this pattern at 32bpp, it must convert 8bpp indexed
pixels to 32bpp direct color. This conversion path is broken. It likely saw minimal testing
because 32bpp was uncommon on 68k Macs.
For each pixel in the region or rectangle:
Requires the Retro68 cross-compiler toolchain for 68k Macs.
Produces DesktopFix.dsk (HFS disk image) and DesktopFix.bin (MacBinary).
Using hfsutils:
Copy DesktopFix to your System Folder:Extensions folder and restart.
A pre-built DesktopFix.sit (StuffIt archive) is available in the
GitHub repository.
Reference QEMU command for Quadra 800 at 32bpp:
Note: -g 800x600x24 requests 32bpp (the 24 refers to 24 bits of
color data, stored in 32-bit pixels). This is what triggers the bug. At 256 Colors or
Thousands of Colors, the desktop renders fine.