Introduction
A .sna file is the simplest snapshot of a ZX Spectrum: 27 bytes of CPU registers and then the RAM exactly as it was, with no
compression. It was introduced by the Spectrum emulator Z80's rival Spectrum emulators and is read by almost every one; the
Z80 format came later and adds compression, the hardware mode and the sound chip. An SNA
holds no hardware mode, so the size of the file says whether it is a 48K or a 128K snapshot.
The extension .sna is also used by Amstrad CPC emulators, whose snapshots start with the text MV - SNA
and have a different layout and size; those are not the format on this page.
A .sna file dropped on any page of this site opens in the explorer, which shows the header fields, the registers, the RAM
banks, the screen as a picture, the interrupt set-up and the Z80 disassembly of the RAM as the processor sees it with the
names of the ROM routines and system variables (names).
The header
Numbers are little-endian. The same 27 bytes begin both sizes of file.
| Offset | Size | Field |
|---|---|---|
0 | 1 | I |
1 | 2 | HL' |
3 | 2 | DE' |
5 | 2 | BC' |
7 | 1 | F' |
8 | 1 | A' |
9 | 2 | HL |
11 | 2 | DE |
13 | 2 | BC |
15 | 2 | IY |
17 | 2 | IX |
19 | 1 | Interrupt flip-flop: bit 2 holds IFF2 (and is read as IFF1 too); the other bits are not defined |
20 | 1 | R |
21 | 1 | F |
22 | 1 | A |
23 | 2 | SP |
25 | 1 | Interrupt mode (0, 1 or 2) |
26 | 1 | Border colour (0-7) |
These offsets are those libspectrum's sna.c reads. The program counter is not in the header.
The two layouts
48K: 49179 bytes
27 bytes of header, then 49152 bytes of RAM from $4000 to $FFFF. The program counter was pushed on the stack when the snapshot was taken, so it is
the word at the address in SP (offset SP − $4000 + 27 in the file), and the stack pointer after loading is SP + 2. This needs SP to be in RAM, from $4000 to
$FFFE; libspectrum refuses a file with an SP outside it, and so the explorer reports it as a problem (it still shows the RAM).
128K: 131103 or 147487 bytes
27 bytes of header, then 49152 bytes: RAM bank 5 ($4000), bank 2 ($8000) and the bank paged in at $C000. Then four bytes: the program counter (two bytes),
the last value written to port $7FFD (bits 0-2 the bank at $C000, bit 3 the screen, bit 4 the ROM, bit 5 the paging lock) and a flag that is 1 if the TR-DOS ROM is paged in.
Then the remaining banks, 16384 bytes each, in ascending order and skipping banks 2 and 5 and the paged-in bank, which were already written. That is five banks (131103 bytes) when
the paged-in bank is not 2 or 5, and six (147487 bytes) when it is, because the bank at $C000 is then also one of the first two.
0Header registers, interrupt mode, border27 bytes27RAM 48K:$4000-$FFFF. 128K: banks 5, 2 and the paged bank49152 bytes49179PC, port$7FFD, TR-DOS flag (128K only)4 bytes49183The other RAM banks (128K only)5 or 6 × 16384 bytes
Links
Software
Reference
- libspectrum – the library Fuse uses; its
sna.cwas read for this page
Not described
Known, not yet covered
- Reference: the Amstrad CPC snapshot that shares the extension has no page yet. Tools that write a 128K file whose size does not match the paged-in bank are not described (the explorer reports the mismatch).
- Viewer: every byte of RAM is decoded as Z80 code with nothing followed from the program counter; the ROM is not in a snapshot; flashing cells are drawn in their first phase. It has not been run in a browser by its author.
Checked
- No ZX .SNA file exists on the machine used to build the explorer. The reader was checked on 15 files written from real .Z80 snapshots and read by libspectrum and by the explorer (equal registers, border, port
$7FFDand bank hashes), on libspectrum's two test files with an invalid SP (refused by both), and on built files of each size.