Building a Human68k FAT32 Driver for External Storage

The Sharp X68000 remains unusually approachable for serious hardware and software work. Its Motorola 68000 processor, documented interfaces and active enthusiast community make it possible to add modern storage without treating the original machine as a sealed museum piece. A FAT32 volume on an external drive can provide a practical bridge between contemporary computers and Human68k, provided the software respects the limits of the old operating environment.

Writing a Human68k patch to support FAT32 on external drives is therefore more involved than adding another file-extension handler. The project crosses several layers: physical media access, partition discovery, endian conversion, filesystem parsing, DOS-compatible file calls and safe write-back. A successful design must also account for removable media being disconnected, incorrectly formatted or attached through hardware with its own quirks.

For Australian owners, the project has a useful practical advantage. Second-hand IDE disks, CompactFlash adapters and small solid-state drives are often easier to source locally than original X68000 media, while modern PCs can prepare FAT32 volumes quickly. The challenge is creating a driver that behaves predictably on a 1980s computer rather than simply making a disk visible during one successful test.

Define the storage path first

Before writing filesystem code, identify how the X68000 will reach the external drive. A SCSI enclosure, IDE-to-CF adapter, removable cartridge or network-assisted storage arrangement may expose quite different device APIs. Human68k sees the result through a block-device layer, but the driver still needs to issue reads and writes using the protocol expected by that hardware.

This distinction matters because FAT32 is a filesystem, not a transport. A FAT32 parser cannot compensate for a SCSI command that reports the wrong sector size or an IDE adapter that mishandles multi-sector transfers. Begin with a small block test program that reads sector zero, displays the returned bytes and writes nothing. Confirm that logical block addresses, transfer lengths and error codes are reliable before adding directory support.

The Nereid-X expansion board is a useful example of why the boundary should remain clear. An expansion or network-oriented project may help move disk images and files between systems, but its available interfaces do not automatically provide a native FAT32 drive. Document whether the storage appears as a local block device, a remote service or a file-transfer endpoint, then choose the filesystem architecture accordingly.

Read the FAT32 structures safely

A FAT32 volume normally begins with a boot sector containing a BIOS Parameter Block. Important fields include bytes per sector, sectors per cluster, reserved sector count, number of FATs, sectors per FAT and the first cluster of the root directory. FAT32 also stores its larger filesystem fields at offsets beyond the traditional FAT12 and FAT16 area, including the 32-bit root cluster and total sectors per FAT.

All multibyte FAT32 values are little-endian. The 68000 is big-endian, so a direct cast from a byte buffer to a C structure is unsafe even when the compiler permits it. Read each field explicitly with helper functions such as get_le16() and get_le32(). These helpers should assemble bytes individually, avoid alignment faults and make the byte order obvious during debugging.

Do not trust the boot-sector signature alone. Validate that the sector size is one the block layer supports, the cluster size is a sensible power of two, reserved sectors are non-zero and the data region leaves enough space for the declared FAT. Reject a volume if its calculated cluster count falls outside the FAT32 range. Clear validation is preferable to mounting a corrupt disk and damaging it during the first write.

The FSInfo sector can accelerate free-space reporting, but it should be treated as a hint. Its lead, structure and trailing signatures must be checked, and its free-cluster count may be unknown or stale. The driver can scan the FAT when necessary, while preserving the value of 0xFFFFFFFF as “not available” rather than reporting an invented free-space figure.

Convert clusters into reliable block reads

FAT32 addresses file data through clusters. The first usable data cluster is generally cluster 2, and the sector containing a cluster can be calculated from the first data sector plus (cluster - 2) * sectors_per_cluster. Keep the calculation in a wide enough integer type and check for overflow before turning it into the block device’s sector address.

The FAT itself is an array of 32-bit entries, although only 28 bits are normally meaningful. To follow a file, calculate the FAT byte offset for the current cluster, read the containing sector, extract the little-endian entry and mask the high reserved bits. Values in the end-of-chain range must terminate the chain; bad-cluster markers and reserved values should produce an error rather than being followed as ordinary data.

A small sector cache will make a major difference on a 68000 system. Cache recently read FAT sectors and the directory sector currently being scanned, using a simple least-recently-used or two-slot policy. Keep cache memory modest because games, shell utilities and resident drivers may already compete for conventional RAM. A cache that can be invalidated after writes is safer than an ambitious cache with uncertain coherency.

Read-only support should come first. It allows testing against known-good disks, directory trees and large files without risking the original data. Once open, seek and read operations work consistently, add file creation and extension. This staged approach also makes it easier to determine whether a failure belongs to the filesystem, Human68k integration or the storage device.

Handle directories and long names

A FAT32 directory is a sequence of 32-byte entries. Standard entries contain an 8.3 short name, attributes, timestamps, starting-cluster fields and a 32-bit file size. The high word of the starting cluster is stored separately from the low word, which is an easy detail to miss when a file is located beyond the first part of a volume.

Long file names use preceding VFAT entries with an attribute combination that distinguishes them from ordinary directory records. These entries store UTF-16 code units in several fragmented ranges and include a checksum of the associated short name. A practical first release can expose short names only, but it should skip long-name records correctly rather than presenting fragments such as E5-marked or sequence-numbered entries as files.

Human68k software often expects conventions that differ from Windows. Decide how the driver maps lowercase names, Japanese characters, illegal DOS characters and path separators. A compatibility layer can accept case-insensitive lookups while returning a stable display name. If the target software mostly loads games and utilities, predictable 8.3 aliases may be more valuable than a partial character-set conversion.

Directory traversal needs cycle and bounds protection. A damaged directory chain can otherwise loop forever, locking the machine. Limit each scan to the number of clusters calculated from the volume, reject impossible cluster values and return a DOS-style error when a directory is malformed. The machine may be vintage, but it still benefits from defensive programming.

Fit the driver into Human68k

There are two broad integration strategies. A filesystem-aware utility can copy files between FAT32 and a native Human68k volume without pretending the external disk is a normal drive. This is the simplest path and is useful for backup, installation and data exchange. A resident device driver or DOS extension provides a better user experience by making the volume appear as an additional drive letter, but it requires deeper knowledge of Human68k’s device and file-operation conventions.

A resident driver should keep its public interface narrow. Translate open, close, read, write, seek, directory and status requests into internal filesystem operations, then translate failures into codes that existing applications understand. Avoid assuming that every caller uses the shell correctly; older software may issue unusual access patterns, request zero-length reads or depend on sequential reads being efficient.

Memory ownership needs particular care. Buffers supplied by an application may not remain valid across a blocking hardware operation, and the storage layer may require aligned memory. Copy request data into driver-owned buffers when necessary. Also decide whether interrupts can arrive during a device transfer and protect shared state accordingly. A short critical section is safer than disabling interrupts around an entire multi-sector copy.

The driver should report a volume label, capacity and read-only status through whatever Human68k mechanisms are available to the chosen integration method. If the machine cannot support a clean drive-letter implementation, a command-line tool with familiar operations such as DIR, COPY and TYPE can still be highly useful. A reliable utility is better preservation software than a nominal driver that crashes when a shell performs a wildcard expansion.

Treat partitioning and media as hostile inputs

Many modern computers initialise external disks with GPT, while older systems and small removable volumes commonly use an MBR partition table. Supporting MBR first keeps the implementation manageable. Read the partition entries, locate a FAT32 type or inspect candidate partitions, and translate the partition’s starting LBA into the filesystem’s relative sector addresses.

GPT support is possible but should be deliberate. It adds 64-bit LBAs, CRC checks and a larger header structure, all of which need careful handling on a 68000 platform. A practical compatibility rule is to prepare a dedicated MBR-partitioned FAT32 disk for the X68000 and document that requirement rather than silently guessing at GPT layouts.

Capacity can expose another trap. FAT32 metadata uses 32-bit sector-related fields in several places, but the surrounding block layer may have smaller address limits. Very large disks can also use sector sizes or cluster counts that the driver was never designed to handle. For an initial Australian workshop setup, a modest solid-state disk or CompactFlash card with a single MBR partition is easier to diagnose than a multi-terabyte archive disk.

Power deserves attention in Australia’s 240-volt environment. A bus-powered USB enclosure or adapter may draw more current at spin-up than an old expansion port can provide, even when the same arrangement works on a modern laptop. Use a properly regulated external supply, check connector polarity and avoid running an untested disk from a questionable plug-pack. A hot afternoon in a Brisbane shed is a poor time to discover that a marginal adapter overheats under sustained transfers.

Make writes conservative and recoverable

FAT32 writes can modify several structures for one logical operation. Creating a file may require a new directory entry, allocation of one or more clusters, updates to both FAT copies and a final file size. If power is removed between those actions, the volume can contain lost clusters or a directory entry pointing to incomplete data.

Start with a read-only mount and an explicit write-protection option. When writes are enabled, allocate clusters, write file data, update the directory entry and flush the storage device in a documented order. Keeping the old file size until all new data is safely written reduces the chance of exposing uninitialised content after a failed transfer.

Do not assume that a successful device write means data has reached non-volatile media. SCSI and IDE devices may cache writes, and an adapter may acknowledge a command before its flash translation layer has finished. If the protocol provides a cache-flush command, issue it when closing a file or unmounting. Provide a deliberate eject or sync command so users can finish a copy before unplugging a removable drive.

Test recovery with deliberately interrupted transfers on disposable media. Use a modern computer to run filesystem checks, then compare directory entries, file lengths and checksums. Keep original disks and rare software images read-only. In Australia, replacement media can often be ordered from Sydney or Melbourne suppliers, but a unique X68000 disk or custom partition image may be impossible to replace at any price.

Build a test bench that reflects real use

A sensible test set includes an empty FAT32 volume, a nearly full volume, files larger than 32 megabytes, fragmented files, nested directories and names containing spaces. Include files with zero length and sizes near cluster boundaries. Test both a disk prepared by the driver and one prepared by Windows or Linux, because formatting tools differ in FSInfo contents, alignment and reserved-sector choices.

Use checksums during every transfer. A small Human68k utility can calculate CRC32 or another compact digest while copying, and a PC can verify the same files afterward. Record the sector size, cluster size, partition start, transfer length and returned device status in a debug log. Serial output, a spare text console or a deliberately simple log file is more valuable than a large graphical diagnostic tool.

Performance should be measured without sacrificing correctness. Multi-sector reads, sequential cluster hints and a small FAT cache can make a large difference, but random access and directory scanning should remain bounded. An X68000 used in an Adelaide or Perth retrocomputing group may be connected to different adapters and cards than a machine in Sydney, so publish results with the hardware model, media type and cable arrangement.

Keep the source portable and the on-disk parser independent from the Human68k glue. A host-side test harness can feed captured sectors into the FAT32 code on a modern computer, where memory errors and boundary mistakes are easier to find. Then test the same parser on real hardware with read-only media. Release the driver with source, build instructions and a warning that users should back up before enabling writes.

A careful implementation can turn an external FAT32 disk into a practical part of an X68000 workstation without hiding the platform’s constraints. Begin with sector reads, validate every field, add read-only file access, and only then connect the code to Human68k’s write path. If you are developing this for your own machine, document the adapter, media and failure cases as you go, then share the tested driver and source with the X68000 community so the next arvo spent repairing vintage hardware starts with better tools.

Nereid-X Expansion Board

A personally-produced LAN+USB+Memory expansion board for Sharp X68000 series computers. Multiple production runs were offered, including a final batch and a later revival reproduction run.

Power Supply Repair

X68 power supply repair and modification services were offered by the site owner, with documentation shared through diary entries spanning 2001–2006.

Server & Networking

Notes on FreeBSD administration, ISP changes, server migration, and networking topics. The site itself ran on FreeBSD with the hns diary system and Namazu search integration.

A two-ink risograph print in muted slate-blue and charcoal on off-white paper, showing a stylized desktop computer monitor beside a circuit board with soft geometric trace lines, conveying a calm retro-computing workshop atmosphere. A two-ink risograph print in deep purple and dark grey on cream stock, depicting a compact expansion card with connector ports and subtle Japanese technical annotations, evoking a hobbyist electronics bench. A two-ink risograph print in teal and charcoal on warm white paper, showing a server rack silhouette with soft network-line motifs and a small weather icon, suggesting a personal server room corner.

Get in touch

X68K.NET connects Sharp X68000 enthusiasts through community links and shared projects. Reach out with questions about the Nereid project or X68 resources.