Skip to the content.

ZZ9000 SDK mailbox, images, audio, and video

The emulated ZZ9000 exposes the SDK v2 mailbox discovery registers and a polling completion ring at board offset 0xD000. The protocol follows the ZZ9000 firmware’s SDK (zz9000-firmware master, which now advertises WebP, FLAC, Vorbis, WebM and MPEG-2). Amiberry advertises a capability bit or service flag only when the host code behind it is compiled in, so the guest clients fall back exactly as they would on older firmware.

Build options

Feature Needs
MP3 audio streams (MHI, MPEGA, ZZPlay MP3) mpg123 and AHI support
FLAC and Ogg Vorbis audio streams FFmpeg (USE_FFMPEG, default on)
MPEG-2, WebM and Matroska media sessions FFmpeg, Zorro III
WebP stills and animations libwebp with libwebpdemux (USE_WEBP, default on)
JPEG/PNG, MPEG-1 media, surfaces, console encoder always built

FFmpeg 5.1 or newer is required. It is no longer tied to USE_VIDEOGRAB; genlock video input still uses it when both are enabled. Android, iOS and the libretro core build without FFmpeg and libwebp. Windows ARM64 builds include libwebp but not FFmpeg, because vcpkg’s FFmpeg port does not build for arm64-mingw-dynamic.

Discovery and memory

Discovery, service queries, and bounded shared-buffer allocation work on both board models. Zorro II additionally answers the aperture-info handshake (0x111C/0x111E) and the aperture layout query that current zz9k.library builds use. The codec, crypto and diagnostics services are not advertised; current clients treat them as optional.

The Zorro III model reserves a shared-buffer heap near the top of its 128 MB board memory and also accepts card-only media allocations of up to 64 MiB (ZZ9K_ALLOC_MEDIA), which ZZPlay’s --preload option copies the file into with MEM_COPY before playback. The Zorro II model provides a 64 KiB host-visible staging window plus card-only buffers for the compressed and PCM rings. Both models reset the mailbox and release every session, worker thread and buffer on board reset or removal.

Audio streams

The audio-stream service implements begin, codec-aware begin (BeginEx), feed, read, play, stop, close and per-stream gain, and keeps up to four concurrent sessions like the card’s four stream slots; a begin against a full table answers NO_MEMORY. MP3 sessions use mpg123; the legacy begin opcode and BeginEx with the MP3 codec produce identical PCM. FLAC (8 to 192 kHz, up to 24 bits, mono or stereo) and Ogg Vorbis (8 to 96 kHz, mono or stereo) are decoded incrementally with FFmpeg as the guest feeds them, so large files are never held in host memory. As on the card, input waits in the session’s input ring until PCM space lets the decoder take it: a feed is refused only when it does not fit that ring (still OK, with the BACKPRESSURE result flag), and bytes_consumed counts decoded input. Undecodable MP3 data never faults a session — the card’s minimp3 consumes nothing and waits — and the input ring of any open session can be freed, because the session keeps the ring it resolved at begin. FLAC sessions can return S16LE, S16BE or S32BE; Vorbis sessions return S16LE or S16BE. Playback (Play) binds one session at a time; a Play for a different session while one is bound answers BUSY, exactly as the card’s single output pump does.

MHI’s S16LE stream plays through the selected Amiberry playback device on a host output stream separate from the board’s AHI path; the per-stream gain applies to that output. The SDK audio fabric is not emulated, so the installed guest drivers do not run AHI and MHI at the same time. mpega.library keeps the MP3’s sample rate and channel count for its S16BE reads.

Images

The image service decodes JPEG, PNG and WebP streams into RGB or 32-bit tiles for the installed picture DataTypes, or into an ARM-local surface for SDK viewers. Surface mapping, fill, and clipped bilinear scaling target the live 32-bit or 16-bit RTG framebuffer. WebP inputs follow the firmware limits: 8 MiB of input, 8192 pixels per side, 6 megapixels per canvas, and for animations 256 frames. Animated WebP sessions step frames with next, present, retire and restart, report frame durations and loop counts, and present YUV422CGX frames to the Picasso96 video window. CPU-visible SDK surface allocations still return UNSUPPORTED.

Media sessions

On Zorro III the video service plays:

Everything except MPEG-1 is decoded by FFmpeg on one worker thread per session. ZZPlay streams the file through a bounded input queue; the media write reply reports the cumulative number of accepted bytes, and decoding begins as soon as the stream headers arrive rather than at end of file. Like the card’s video FIFO, the worker demuxes up to 1 MiB of video ahead of the decoded-frame queue, so audio that a Program Stream carries behind its pictures keeps decoding while the guest holds a frame. Once all input and EOF have arrived, DECODE answers BUSY rather than NEED_INPUT until the worker has caught up. Decoded frames are packed to YUY2 for the Picasso96 video window. Interlaced frames are blended, and frames too large for the window are packed at half size. Audio goes to the session’s S16BE PCM ring. Card-local AX media binding is not advertised, so ZZPlay plays the sound through guest AHI. Zorro II video sessions remain unadvertised because its video window aperture is not mapped for this path.

The media status op (0x0b0a) answers all six card pages: timing (with the timeline origin), audio, counters (decoded, presented and discarded frames counted separately), audio output (zero underruns — there is no card-side DMA pump here to starve), the overlay presentation path, and per-stage profiling. The presentation page reports the PIP’s flags and source, destination and screen geometry packed into 16-bit pairs; because the emulated PIP is the FPGA overlay plane, an active overlay always reports the native path, and ZZPlay names it “native 1:1” or “native scaled” rather than “card-local compositor”. Profiling packs each stage as (microseconds << 32) | calls measured around the real FFmpeg/pl_mpeg decode, YUY2 pack, present copy and audio decode work; the NEON flag never appears because the host packs in scalar C++. Pages above five and nonzero flags are rejected exactly as on the card.

Console encoder

The console service (0x8200) encodes the live RTG framebuffer into RFB tile updates for remote-console clients. It converts BGRA8888 or RGB565 framebuffers to big-endian RGB565 tiles, encodes 8-bit screens (reported as INDEX8 surfaces) as CLUT8 tiles, refuses RGB555, and compresses tiles with zlib when that makes them smaller. Tiles are always raw; the card’s optional XOR and copy-rectangle layers are not produced.

Not emulated

The SDK’s archive, crypto, module, and physical-card operations remain unadvertised and return UNSUPPORTED.

Tests

tests/test_zz9000_sdk.sh, tests/test_zz9000_sdk_audio.sh, tests/test_zz9000_sdk_image.sh, tests/test_zz9000_sdk_media.sh and tests/test_zz9000_sdk_console.sh build the SDK against whichever optional libraries pkg-config finds and generate their fixtures with the ffmpeg command-line tool. They cover mailbox completion, allocation, reset and preload buffers; MP3, FLAC and Vorbis PCM against FFmpeg-decoded references and chunked feeding; JPEG, PNG and WebP pixels, limits and animation stepping; streaming playback of every supported container and codec pair, truncated input, and close/reopen; and console tile output.

Guest qualification

On the user’s A4000 system drive, ZZPlay and AmigaAMP MHI playback, MPEGA decoding, the JPEG and PNG picture DataTypes, the SDK viewer, and ZZPlay MPEG-1/MP2 playback (pause, resume, resize, loop, longer clips) work with the installed libraries. ZZPlay also played MPEG-2 Program Stream and VOB files with MP2, AC-3 and LPCM audio (up to 1280x720), WebM VP8/Vorbis and VP9/Opus, Matroska with MPEG-1, MPEG-2 and VP8 video, a 1920x1080 VP9 clip, FLAC and Ogg Vorbis through AHI and through on-card output, animated WebP, and preloaded playback; zz9k-view showed lossy, lossless and animated WebP. A later run on a disposable copy of the same system, with drivers master (zz9k.library 2.33, ZZPlay 0.6), passed the remaining checks: the WebP picture DataType and the FLAC and Ogg Vorbis sound DataType decode correctly, the console encoder’s decoded tiles match the screen pixel for pixel, ZZPlay reports the presentation path and card profile from status pages 4 and 5, and a warm reset during media, audio and network sessions recovers all of them. On a 4 MB Zorro II board with a 1024x768 16-bit Workbench, zz9k-archive, zz9k-view, MHI, AHI and on-card audio work, and ZZPlay refuses video files because Zorro II video sessions are not advertised.