Writing A Human68k Tool To Export VRAM Contents As Image Files
The Sharp X68000 remains unusually rewarding to document because its hardware sits between a home computer and a compact workstation. Its graphics system gives software direct access to several VRAM planes, flexible screen modes and palette registers, yet the machine still expects tools to fit comfortably within a Human68k command-line workflow. A small exporter can therefore become a useful bridge between live hardware, emulator snapshots and long-term preservation.
The practical goal is simple: read the contents of graphics VRAM, reconstruct indexed pixels, apply the correct palette and save an image that modern computers can open. The difficult part is deciding what those bytes mean. Screen width, bitplane arrangement, colour depth, scrolling registers and the selected display page all affect the result, so a reliable utility needs a clearly defined capture contract rather than a single hard-coded memory dump.
Define The Capture Contract
Start by deciding exactly what the program exports. A useful first version can target a single 16-colour graphics mode, such as a 512-pixel-wide screen, with a fixed height and four bitplanes. Later versions can add 256-colour and 65,536-colour modes. Keeping the first target narrow makes it much easier to compare the output against a known test screen.
The command line should make assumptions visible. A command such as VRAM2IMG -w 512 -h 512 -p 4 -o SCREEN.BMP tells the operator which geometry and plane count the tool will use. If the utility can detect mode registers, it should still offer explicit overrides. Screens captured during demos, games or hardware tests may use unusual settings that automatic detection does not interpret correctly.
A raw dump and a rendered image are different products. The raw dump preserves the original bytes and should be available as an optional output, while the image is a decoded interpretation. Saving both is valuable for emulation research because a later decoder can revisit the original data without asking the physical machine to reproduce the screen.
Understand The X68000 VRAM Layout
The graphics VRAM commonly used by X68000 software is organised as bitplanes rather than a modern packed pixel buffer. In a four-plane mode, each pixel receives one bit from each plane. Those four bits form a palette index from 0 to 15. The plane data therefore has to be read in parallel: taking an entire plane first and then writing it directly as pixels will produce a striped or apparently scrambled picture.
A typical decoder processes one 16-bit word at a time. For each word position, it reads the corresponding word from plane zero, plane one, plane two and plane three. Bit 15, or whichever end the hardware specification confirms as the leftmost pixel, contributes one pixel position; the next bit contributes the next position. The output index can be assembled with a small expression such as:
index = ((p0 >> bit) & 1)
| (((p1 >> bit) & 1) << 1)
| (((p2 >> bit) & 1) << 2)
| (((p3 >> bit) & 1) << 3);
The exact plane offsets and row stride must be verified against the selected mode. Do not assume that a 512-pixel row occupies the same number of bytes as a 256-pixel row, or that every screen page starts where a convenient constant suggests. A test image containing vertical one-pixel lines, alternating colours and a numbered border quickly reveals reversed bit order, incorrect stride and swapped planes.
Display-page selection deserves separate attention. Some programs draw into an off-screen page and switch the visible page during vertical blanking. A capture taken while the back page is active may be perfectly valid but different from what the operator sees. The utility can document whether it reads a fixed page, the current display page or a caller-supplied page address.
Choose A Human68k Interface
A resident Human68k utility can access memory-mapped hardware directly, which is one of the platform’s great advantages. In C, the VRAM region can be represented through volatile pointers, with reads performed as 16-bit values when the layout is word-oriented. Volatile prevents the compiler from caching a value or removing a read that appears unused. It also communicates the important fact that the address refers to hardware, not ordinary RAM.
Assembly remains useful for the inner loop, especially when exporting a full screen on an original 68000. A C implementation is easier to maintain, though, and is generally fast enough if it reads words sequentially and converts a row into an output buffer before writing it. Avoid per-pixel system calls, repeated file seeks and unnecessary address calculations inside the hottest loop.
The program should leave the machine in a safe state. If it changes palette registers, screen mode or display-page registers, it needs to restore them before exiting. The least intrusive design reads the current palette and mode, performs the capture without changing video state, then closes the file cleanly even when an error occurs. A keyboard abort path is sensible for a utility that may be run from a floppy or a slow hard disk.
| Capture target | Typical pixel data | Decoder requirement | Suitable first output |
|---|---|---|---|
| 16-colour graphics mode | Four one-bit planes | Combine four bits into a palette index | Indexed BMP or PPM |
| 256-colour graphics mode | Eight one-bit planes or mode-specific arrangement | Confirm plane order and address stride | Indexed BMP |
| 65,536-colour mode | Packed or paired colour data | Follow the exact hardware format | 24-bit BMP |
| Raw VRAM archive | Original bytes | No decoding | Binary dump |
| Palette archive | Hardware colour register values | Convert colour encoding | Text or binary palette file |
Convert Bitplanes Into Pixels
The cleanest architecture separates memory reading, pixel decoding and file writing. First, a capture routine reads the required VRAM words into a buffer or passes them to a decoder. Second, the decoder produces one scanline of palette indices. Third, the image writer stores that scanline in the format’s required orientation. This separation makes it possible to test the decoder with an ordinary binary file on a modern development machine.
Palette handling is essential. A four-bit pixel index is not an image colour until the corresponding hardware palette entry has been captured. X68000 colour registers use a hardware-specific colour encoding, so the exporter should convert each component into the output format’s usual eight-bit range. If the register stores a smaller number of bits per channel, scaling can use a direct shift or a lookup table rather than assuming the value is already a full 0–255 component.
A palette dump should be saved beside the image when practical. It helps explain why a perfectly decoded screen appears too dark, has unusual blues or contains transparent-looking backgrounds in an image viewer. It also supports preservation: an artist’s original palette and the pixels that reference it are separate pieces of information.
For debugging, add a mode that ignores the palette and emits each bitplane as a monochrome image. Plane visualisation immediately exposes an incorrect base address, a wrong word order or a missing plane. Another useful option writes the numeric palette index rather than the final colour, allowing the operator to distinguish a decoding error from a palette-register error.
Select A Portable Image Format
An indexed BMP is a strong first target for a Human68k exporter. Its structure is documented, it supports a palette, and modern Windows, Linux and macOS applications can open it without a special plugin. The writer needs to produce a file header, information header, palette entries and padded scanlines. BMP traditionally stores rows from the bottom upward, so the program can either write rows in reverse order or set the appropriate header orientation where supported.
PPM is even easier to implement and is excellent for early testing. The plain or binary PPM variants require little code and can store fully expanded RGB pixels. The drawback is file size, especially on floppy disks or compact hard-disk partitions. PPM also does not preserve an indexed palette as naturally as an indexed BMP.
PNG is attractive for archival work, but implementing compression on the X68000 adds code, memory use and testing overhead. A sensible workflow is to create BMP or PPM on the X68000, then convert it to PNG on a modern computer. That preserves a simple, inspectable source format while allowing the final archive to use lossless compression and metadata.
Human68k filenames and paths should be treated conservatively. Short names such as CAP0001.BMP avoid surprises on older DOS-compatible tools. The program should reject an existing file unless an overwrite switch is supplied, report free-space failures clearly and close the file after every completed scanline or controlled block. A partially written image is much easier to diagnose when the error message includes the output path and row number.
Validate With Test Patterns And Real Hardware
Validation should begin with a synthetic screen rather than a favourite game. Create a pattern with one colour per palette index, alternating vertical and horizontal lines, a checkerboard and text showing the current mode. This gives every part of the decoder something measurable. If the checkerboard is shifted by one pixel, the bit order is suspect; if horizontal bands repeat at the wrong interval, the row stride is probably wrong.
Run the same capture through an emulator and an original machine where possible. Emulator settings can reveal whether the program depends on undocumented behaviour, while physical hardware exposes timing and bus-access assumptions. A modern Australian enthusiast may test on a compact setup in Melbourne, a workshop in Brisbane or a retrocomputing meet in Sydney, then compare the resulting files with an emulator running on a current laptop.
Hardware condition matters during testing. A failing floppy eject mechanism can turn a sound graphics experiment into a misleading file-read problem, so documenting floppy drive repairs is part of the wider preservation picture. Keep the executable on a hard disk, SCSI2SD device or network transfer where possible, and use floppy media only as an additional compatibility test.
Australia also adds electrical and logistical considerations. Many imported X68000 units are Japanese 100-volt machines, while household power is nominally 230–240 volts, so a suitable step-down transformer and a properly repaired power supply are essential before long test sessions. Replacement parts may arrive from Japan with international postage and GST folded into the real cost, making a software-only diagnostic workflow especially useful before ordering hardware.
Handle Performance And Memory Limits
A full-colour framebuffer can consume a substantial portion of an older machine’s available memory. Avoid allocating several complete copies when a scanline buffer is sufficient. For a four-plane screen, read the corresponding words, produce one output row and write it immediately. This keeps RAM usage predictable and allows the program to run on configurations with limited expansion memory.
Disk throughput may dominate the runtime. Sequential writes are preferable to seeking back and forth, and a moderate output buffer reduces the number of DOS calls. If the tool exports a raw capture as well as a rendered image, write the raw planes in large contiguous blocks. A progress counter displayed on the text screen is helpful, although it should not alter the graphics state being captured.
Do not chase speed until correctness is established. A slower decoder that produces a verified image is more valuable than an optimised routine with an undocumented assumption about bus access. Once the reference implementation works, profile the inner loop and consider unrolling the sixteen-pixel word conversion or using a small lookup table for byte pairs. Keep the clear version in the source tree as a test oracle.
For operators in Australia, transfer time can influence the design. A capture made at a Perth workshop may be moved through a modest local network or copied onto removable media before being archived elsewhere, while a collector in regional New South Wales may rely on a compact SCSI emulator rather than a fast network card. Small indexed BMP files are practical in both cases and are easier to verify than a proprietary compressed stream.
Package The Tool For Preservation
A useful release should include the executable, source code, build notes, a short mode reference and sample captures. State the compiler and linker versions used for Human68k, the expected memory model and whether the binary requires a particular DOS extension or library. Future users should be able to rebuild the utility rather than treating one floppy copy as the only surviving version.
Record capture metadata in a companion text file. Include the machine model, emulator or physical hardware, screen mode, width, height, plane count, VRAM base, palette source and date. A naming scheme such as X68K_MVI_512X512_0001.BMP is more informative than IMAGE.BMP, especially when files are later gathered from disks, SCSI images and online repositories.
The project can also serve the wider local community. Australian collectors often trade through specialist forums, retrocomputer groups and weekend markets, where a small utility that proves a graphics board or repaired machine is working has immediate value. A documented exporter makes demonstrations at a Canberra or Adelaide meetup reproducible and gives preservationists a common format for comparing screens.
Publish known limitations honestly. If the first release supports only one four-plane mode, say so. Include a raw-dump option, a plane-test command and a sample pattern image so another operator can identify a mismatch without guessing. Clear boundaries build trust and make later additions—256-colour modes, palette animation capture or emulator automation—far easier to review.
Build the smallest working version first: one known mode, one verified test pattern, one indexed output format and a raw-dump switch. Then compile it for Human68k, run it on an emulator, test it on a correctly powered X68000 and archive the source beside the captures. With that foundation in place, develop the additional mode decoders and modern conversion scripts as separate, testable pieces rather than turning the exporter into an opaque all-in-one program.
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.