Building a Human68k sprite extraction utility for game ROMs

The Sharp X68000 is an excellent platform for studying how arcade-style graphics were stored, decoded and displayed. Its Human68k operating system gives a developer a practical DOS-like environment, while the machine’s Motorola 68000 processor, custom graphics hardware and Japanese game library provide plenty of interesting binary formats to investigate. A small command-line program can turn an obscure ROM dump into usable sprite sheets, raw tile files and palette data.

Creating a Human68k Utility to Extract Sprite Data from Game ROMs involves more than copying rectangular blocks from a file. The utility needs to identify graphics boundaries, account for 68000 byte order, understand packed or bit-plane pixel layouts, and produce files that can be checked on modern computers without losing information. The best design keeps the extractor conservative: read bytes exactly, make assumptions visible, and let the operator adjust offsets and dimensions.

For Australian enthusiasts, this is a realistic weekend preservation project rather than an exercise limited to a university lab. An X68000 may arrive from a Japanese auction with tired capacitors, a missing terminator or a power supply that needs attention before serious testing. Local collectors in Sydney, Melbourne, Brisbane and Adelaide often rely on imported hardware, eBay Australia listings and Japanese proxy services, where GST, postage and exchange rates can quickly affect the budget.

Approach Strengths Limitations Suitable output
Fixed-offset raw dump Simple and predictable Requires known offsets and dimensions Tiles, icons and test assets
Pattern scanning Finds repeated graphic structures Can produce false positives Unknown ROM investigations
Format-aware decoder Preserves palettes and metadata Needs reverse-engineering work Complete sprite resources
Emulator-assisted extraction Confirms what the game uses More setup and debugging Animated or compressed graphics

Defining the utility’s job

The first version should have a narrow responsibility: open a ROM image, seek to a user-supplied address, decode a specified number of sprites, and write an output format that another tool can inspect. Avoid trying to identify every game automatically. A reliable extractor with explicit options is far more valuable than a clever program that silently guesses incorrectly.

A useful command line might look like this:

SPRITEX GAME.ROM -o HERO.BMP -a 0x1A4000 -w 16 -h 16 -n 64 -b 4 -p palette.bin

Here, -a selects the source offset, -w and -h describe the tile dimensions, -n sets the number of sprites, and -b selects the bits per pixel. A separate palette option allows the same graphics data to be viewed with different colour assignments. Human68k command-line conventions are familiar to anyone who has used COMMAND.X, so short switches and clear error messages suit the platform.

The utility should also support a raw binary output. Bitmap or PNG export is convenient, but an unmodified decoded stream is essential when comparing results with an emulator, a disassembly or a later conversion tool. Include a small header or sidecar text file containing the source filename, offset, dimensions, pixel format and palette mode. That metadata prevents a successful extraction from becoming an unexplained image months later.

Reading ROM data safely on a 68000

The Motorola 68000 is big-endian, meaning a 16-bit value such as $1234 is stored as $12 $34. Sprite graphics are often byte-oriented, so byte order may appear irrelevant at first. It becomes important when the ROM contains tile pointers, compressed stream lengths, palette entries or lookup tables. Implement explicit functions such as read_be16() and read_be32() rather than casting a byte buffer to a structure.

Human68k software also needs to be careful with memory allocation. A modern desktop program can casually load a large ROM image into memory, but an X68000 utility should work comfortably with smaller machines and expanded-memory configurations. Reading the file in blocks, checking fread() results and rejecting offsets beyond the end of the image will make failures predictable. A corrupt or truncated dump should generate a useful message instead of a partially written sprite sheet.

Use fixed-width assumptions in the source code, even if the compiler’s standard library is old. Unsigned byte values must remain in the range 0 to 255 when bit masks are applied. Signed char behaviour can otherwise turn a pixel nibble into a negative index, leading to damaged palettes or writes outside an output buffer.

A practical implementation can be written in C for Human68k, with a second build for a modern host compiler. The shared decoder source should contain the format logic, while the platform layer handles file paths, console output and output-image writing. Testing the same input on an X68000 emulator and on a Linux, Windows or macOS build gives quick evidence that the code is portable rather than accidentally relying on a host compiler.

Recognising tile and sprite layouts

Many game ROMs store graphics as small tiles rather than complete sprites. A 16-by-16 sprite may consist of four 8-by-8 tiles, and the game’s object code may assemble those pieces with position, flip and palette attributes. The extractor therefore needs to distinguish between a linear bitmap, a tile stream and a set of bit planes.

In a packed four-bit format, each byte can represent two pixels, with the high nibble preceding the low nibble. In a planar format, separate blocks may contain one bit from every pixel. To decode a four-bit planar tile, read the corresponding bit from four plane addresses and combine them into a colour index:

pixel = bit(plane0) | bit(plane1) << 1
      | bit(plane2) << 2 | bit(plane3) << 3

The exact bit order varies. Some formats place the leftmost pixel in the high bit, while others begin with the low bit. A decoder should expose this as an option rather than burying it in a constant. Add switches for plane stride, row stride, tile interleave and bit direction. Those options are particularly useful when a ROM contains several graphics systems from different developers.

Pattern scanning can help when documentation is unavailable. Search for repeated runs whose byte distribution resembles graphics, then render candidate blocks at several widths and heights. Human figures, fonts and interface icons usually reveal themselves quickly as repeated edges and empty background areas. This is a discovery aid, not proof of a format; executable code and compressed data can produce equally convincing noise at one particular width.

Handling palettes, transparency and animation

A sprite extractor should preserve palette indexes before applying colours. The index zero value may mean transparent background, black, or an ordinary colour depending on the game. Converting immediately to a modern image can hide that distinction and make later palette research harder. Store indexed pixels first, then allow the user to select a transparent index during export.

X68000 palette entries may be stored in a compact format rather than standard 24-bit RGB. The game may also maintain several palette banks for enemies, player characters or flashing effects. Decode palette data separately from sprite pixels and provide a way to export a palette file. A visualiser can then render the same sprite repeatedly with different banks, which is useful when examining character states.

Animation frames often sit beside one another in ROM order, but the game may use a pointer table to arrange them. A useful enhancement is a manifest file listing frame offsets, widths, heights and palette selections. The extractor can read that manifest and produce numbered files or a contact sheet. This keeps the command line simple for routine work while allowing detailed research into complex objects.

For preservation, retain the original ROM dump and record its checksum. Never overwrite it with a “fixed” version after removing headers or swapping byte pairs. Keep transformations as separate files, with names that identify the operation. This makes it possible to reproduce an image months later and compare a community dump against another copy.

Building a useful Human68k workflow

Human68k output should be easy to move between the original machine and a modern workstation. A compact .X executable can scan the ROM and write raw or indexed files, while a desktop companion converts those files into PNG sheets and previews. Transfer can happen through a SCSI2SD device, CompactFlash adapter, serial link or a shared emulator directory. Keep filenames short and avoid characters that behave differently between Japanese DOS conventions and modern shells.

A good working record might include the ROM checksum, extraction command, suspected graphics address, tile geometry, palette source and a small preview. The project diary at X68K.NET offers the kind of practical documentation that makes this habit worthwhile: observations made during repair or testing can be as important as the finished program.

When a transfer fails, separate the network problem from the graphics problem. Check file size, checksum and timestamps before investigating a decoder. Basic connection diagnostics, including the connection troubleshooting notes, can help when a modern server, an old client and an intermediate network device disagree about authentication or transport settings.

Australian users may need to plan around hardware availability. A collector in Perth or Hobart could wait several weeks for a Japanese expansion board, while a local electronics supplier may have the capacitors and connectors needed for immediate bench work. It is sensible to test the extractor under emulation before connecting a valuable imported machine, especially when the ROM board or power supply has an uncertain history.

Testing results against real hardware

Visual inspection is valuable, but repeatable tests are better. Create small synthetic graphics with known pixel patterns: alternating bits, diagonal lines, numbered colour indexes and a one-pixel border. Encode those patterns using the suspected format and verify that the decoder reconstructs them exactly. These fixtures expose swapped planes, reversed bit order and incorrect row strides without relying on a commercial game.

Compare extracted frames with emulator screenshots and, where appropriate, the output from the X68000 itself. A mismatch may come from the decoder, a palette register, a sprite priority rule or a hardware display mode. Record each possibility rather than adjusting the image until it looks right. A sprite can appear correct while still having an incorrect transparent colour or a reversed animation sequence.

Stable video hardware matters during physical checks. If an X68000 has unstable analogue output, colours and sync may be misleading even when the extracted data is perfect. The guide to recapping the analogue board is relevant before using a real display as the final authority. Capture the same test image after the repair and keep the photographs with the extraction notes.

Once the decoder is trusted, add regression tests for every format discovered. Each test should specify the input bytes, expected dimensions, pixel indexes and palette interpretation. A future optimisation, compiler change or port to another Human68k environment should then fail loudly if it alters the result. This is especially helpful when sharing the source with preservation groups, where contributors may use different compilers and emulators.

A small, transparent utility can become part of a much larger preservation workflow. Release the source, example commands and format notes alongside extracted samples that can legally be shared. Document uncertainty, mark guessed offsets as provisional and avoid distributing copyrighted ROM images. The value lies in explaining the method so another enthusiast can apply it to a dump they own.

For an X68000 project, start with one known tile set, implement explicit big-endian reads, preserve indexed pixels and test every assumption against a synthetic pattern. Then build the Human68k executable, run it on an emulator or real hardware, and archive the command line with the resulting files. That measured approach turns an unknown game ROM into evidence that can be examined, corrected and reused by the wider retrocomputing community.

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.