Writing a Human68k Archive Tool for X68000 Games
An X68000 game archive tool needs to do more than unpack files from a disk image. It must respect Human68k’s DOS conventions, preserve Japanese filenames, handle media limitations, and produce archives that can be copied back to a real machine without surprises. A useful utility should also make the process repeatable for preservation work.
The practical target is a small command-line program that can extract an archive, inspect its contents, and repack those files into a compatible image or distribution bundle. Common cases include LZH archives found on game disks, installer packages, save-data collections, and project-specific containers created by a publisher or hobbyist developer.
For an Australian owner, this can be especially valuable. Original disks often arrive through Japanese sellers on eBay, while replacement media and accessories can cost a fair bit after postage to Melbourne, Brisbane, Perth, or Adelaide. A reliable tool lets you work from disk images and modern backups rather than repeatedly handling ageing media.
The best approach is conservative: identify the archive format first, preserve metadata where it matters, validate every extracted file, and make repacking deterministic. That gives enthusiasts a tool suited to restoration, translation patches, homebrew development, and long-term storage.
Define the Archive’s Real Requirements
Start by deciding whether the program is handling a known format or an unknown game-specific container. LZH is a strong candidate for many Human68k software collections because it was widely used in Japanese PC environments, but a file called DATA.DAT may contain anything from a simple concatenation of files to a compressed resource table. Guessing from the filename is unsafe.
Use signatures, structure checks, and failure messages to classify input. An LZH member commonly begins with a level marker and method information, while a proprietary archive may have a magic value, a file count, offsets, lengths, and a table of names. The tool should expose an info or list command before attempting extraction, showing the detected format, number of entries, compressed size, and uncompressed size.
A useful first command set might look like this:
xarc list GAME.LZH
xarc extract GAME.LZH --out game_files
xarc create GAME.LZH game_files
xarc test GAME.LZH
Keep format detection separate from extraction. That makes it possible to add a new game archive handler without changing directory traversal, filename conversion, error reporting, or checksum verification.
Respect Human68k File Semantics
Human68k uses conventions inherited from DOS, including drive letters, backslash-separated paths, eight-dot-three filenames in many older programs, and Japanese text encoded for the platform. A modern host may accept long Unicode names that cannot be represented on an X68000 disk. The tool therefore needs a clear policy instead of silently changing names.
For native execution, use the compiler and C library available in the target environment, then keep the archive logic independent of platform-specific file calls. On Human68k, standard functions such as fopen, fread, fwrite, fseek, and stat may be available through the chosen development kit, but exact structures and DOS extensions vary. Isolate those calls in a small compatibility layer.
Path sanitisation is essential. Reject absolute paths, drive prefixes, .. components, and names that become empty after conversion. Otherwise, an archive could overwrite files outside its destination directory. Convert forward slashes and backslashes consistently, and decide how to handle duplicate names after case folding. A collision should stop extraction or receive a clearly reported renamed path.
Japanese filenames deserve special attention. Store the original byte sequence whenever possible, and offer an explicit conversion option for modern systems. If a host terminal cannot display Shift JIS correctly, that is a display problem, not a reason to corrupt the archive’s name. Logging both hexadecimal bytes and a readable fallback can help diagnose troublesome disks.
Choose Compression and Container Boundaries
If the objective is compatibility with existing software, use an established LZH implementation rather than inventing a new compression method. The archive writer must emit the exact method, header level, length fields, and checksum expected by the decoder. A technically valid stream is not enough if the game’s loader only recognises a narrow subset.
When licensing or portability makes an embedded LZH library inconvenient, the program can support a two-stage workflow: extract with a trusted library and invoke a compatible compressor for repacking. That is less elegant for a single binary, yet it can be practical on a development workstation. For a self-contained Human68k utility, an embedded decoder and a deliberately limited encoder are easier for users to understand.
Separate the container layer from the compression layer. The container knows about filenames, timestamps, attributes, and member boundaries; the compressor only receives bytes and returns compressed data. This design also supports uncompressed members where speed or compatibility matters.
A game archive may use a proprietary format with no compression at all. In that case, document the byte layout and write a parser that checks every offset against the file size. Never trust an entry count or length field without bounds checking. One malformed value should produce an error, not a large allocation or a write beyond the destination buffer.
Build a Safe Extraction Pipeline
Extraction should proceed through a temporary file or memory buffer, then rename the completed output into place. This prevents a power interruption or damaged archive from leaving a file that looks valid but is incomplete. It matters on original hardware, where floppy drives, ageing hard disks, and compact flash adapters can all fail at inconvenient times.
For each member, validate the compressed length, decompressed length, checksum, and end-of-stream marker. Compare the number of bytes produced with the advertised size. If a checksum is unavailable, still report that the member was structurally checked but not cryptographically verified. A test command should perform these checks without writing output.
| Operation | Required checks | Useful output |
|---|---|---|
| List | Header, names, sizes, offsets | One line per member |
| Extract | Bounds, path safety, decompression, checksum | Written path and status |
| Create | Readability, name encoding, size limits | Archive summary |
| Test | All structural and data checks | Pass, warning, or failure |
| Convert | Encoding and collision rules | Changed-name report |
Keep memory use modest. A 68000-based system may have far less free RAM than a modern PC, and some games are distributed on several floppy disks. Stream compressed input where the format permits it, and avoid loading every member into a single in-memory buffer. A fixed-size read buffer, such as 8 or 16 KiB, is usually more practical than allocating based on untrusted archive fields.
Error messages should identify the member and operation: DATA/SPRITE.BIN: checksum mismatch is far more useful than bad archive. Return distinct exit codes for invalid input, an output collision, an encoding failure, and an I/O error so scripts can respond correctly.
Make Repacking Reproducible
Repacking is where preservation tools often become unreliable. A directory can contain files in different orders depending on the host operating system, and timestamps may change every time the archive is created. Sort members using a defined bytewise order, record a stable timestamp policy, and make compression settings explicit.
For archival work, a --deterministic option should set timestamps to a chosen value, normalise attributes, and use a stable file order. For a patching workflow, a --preserve-metadata option may be preferable. Do not mix these behaviours invisibly; users need to know whether a changed archive differs because its contents changed or because its headers received new dates.
On an Australian workstation, this is useful when keeping a master image on an NBN-connected NAS, a second copy on an external drive, and a working copy for a real X68000. A deterministic archive can be compared with hashes rather than manually inspected. It also reduces confusion when a Japanese download is mirrored between machines running different operating systems.
Use a manifest beside the archive. It can list each member, original size, extracted size, checksum, filename bytes, and tool version. A plain text manifest remains readable decades later and provides evidence of what was repacked. Include the source disk image hash when the archive came from a preservation project.
Test Against Real Hardware and Images
Testing only on Linux or Windows is insufficient. A host implementation may accept names, file sizes, and path syntax that Human68k software rejects. Test the utility with an emulator first, then copy a small archive to the actual target using the transfer method available to the owner: SCSI2SD, compact flash, a network adapter, or a floppy image.
Create a test corpus with ordinary files, empty files, Japanese names, duplicate case variants, long names, nested directories, maximum-size members, truncated headers, bad checksums, and extra bytes after the final member. Keep known-good archives from several sources. A regression test should compare extracted bytes, not just the displayed filenames.
On a real X68000, verify that a repacked archive can be read by the game or installer that originally used it. Some software assumes a particular member order, uppercase names, or a specific archive method. If a general-purpose extractor succeeds but the game fails, add a compatibility profile rather than weakening validation globally.
Power stability deserves consideration during these tests. A machine being used for repeated disk writes should have a healthy supply and sensible startup protection; the practical power-on delay notes are relevant before making a restoration workstation do hours of transfers. Australia’s 240-volt mains and summer heat make electrical and cooling checks worthwhile, particularly for hardware brought into a shed or spare room.
Package the Tool for Preservation Work
A command-line binary is valuable, but documentation determines whether others can use it safely. Include examples for extracting into a new directory, testing without writing, converting filename encodings, and creating a deterministic archive. State which formats are supported and identify limitations such as maximum member size or unavailable timestamps.
Distribute source code with a build file, a licence, and a small test corpus that can be legally shared. Provide binaries for the platforms most likely to be used by the community: modern Windows, Linux, and macOS for preparation work, plus a Human68k build if the program is intended to run on the original computer. Cross-compilation notes are particularly helpful because toolchains can be harder to locate than the archive format documentation.
Avoid making the utility dependent on a live internet service. A preservation workflow should still operate when a download disappears or a hobbyist’s server goes offline. Record the archive format description in the repository and include version information in --help output. If a format is reverse-engineered, separate confirmed observations from assumptions.
The Australian second-hand market adds another reason to keep the workflow self-contained. A disk bought through Gumtree or an imported auction listing may have unclear provenance, and returning to the seller is rarely practical after international postage. A tool that makes a verified image, manifest, and extracted copy on the first attempt protects the software even when the original disk later becomes unreadable.
Extend the Utility Without Losing Trust
Once extraction and repacking are stable, useful extensions can be added carefully. A diff command could compare two archives by member name and checksum. A repair mode might rebuild a damaged directory table when enough data remains, but it should write to a new file and preserve the original unchanged. A batch mode can process a directory of disk images while recording failures in a log.
Support for patch workflows is another sensible addition. The tool could extract a game, apply a binary or translation patch, rebuild the archive, and emit a manifest describing every changed member. It should never pretend that a rebuilt archive is identical to the publisher’s original. Clearly label it as a derived version and retain the original hash.
Do not add features that make validation weaker. Automatic filename guessing, silent truncation, and “best effort” decompression may appear friendly, yet they are dangerous in preservation work. Warnings should be visible, and a successful exit status should mean that the requested operation completed according to documented rules.
A strong first release can therefore remain small: reliable format detection, safe extraction, compatible creation, deterministic output, checksums, and readable diagnostics. That is enough to support game archiving, translation projects, emulator testing, and transfers back to an original X68000.
Build the tool around a known archive corpus, test it in an emulator and on real hardware, and publish the format notes with the source. Every verified disk image and reproducible archive adds another dependable copy of X68000 software to the community’s long-term record.
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.
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.