Output Formats

The same source assembles to four different files. Which one you want depends on what is going to load it — an emulator, a real Next, a flashing tool, or something of your own.

FormatIsTypical use
binThe assembled bytes and nothing elseincbin into another build, a loader you wrote
hexIntel HEX, as textEPROM burners and flashing tools
snaA whole-machine snapshotEmulators, and the 48K/128K machines
nexThe Next executableA real Next, or an emulator of one

bin is the default.

Choosing one

Three places say which format you want, and they override each other in this order:

  1. -f/--format on the command line.
  2. format under [assembler] in fantasm.toml.
  3. format as a directive in the source: format nex.

If none of them says, the output filename’s extension decides — game.nex gets a NEX without being asked.

The chosen format renames the output. -f nex with an output called game.bin writes game.nex. Nothing is left at the name you gave, so a build script looking for it finds nothing.

bin — the bytes

fantasm build main.asm game.bin

No header, no padding, no record of where the code was meant to live. A program that orgs at $8000 and emits three bytes produces a three-byte file; whatever loads it has to know that $8000 is where those bytes belong.

That makes it the format to use when something else is doing the loading — a incbin in another target (Building Several Images), a custom loader, or a tape image built by another tool.

hex — Intel HEX

fantasm build main.asm game.hex -f hex

Text rather than binary, one record per line, each carrying its own load address and checksum:

:038000003E01C975

The same three bytes as above, with 8000 in the record so the address survives. Read by EPROM programmers and by most flashing tools.

sna — a snapshot

A .sna is a picture of the whole machine, not just your program: every byte of RAM, the registers, the interrupt mode and the border. An emulator loads one and is immediately in your program.

TargetSize
zx4849,179 bytes — a 27-byte header and 48 KiB of RAM
zx128131,103 bytes — the 128K variant, with its extra banks

Two directives set what the machine wakes up doing:

    org $8000
start:
    sna pc start        ; where execution begins
    sna sp $BFFF        ; the stack pointer
    ld  a,1
    ret

pc and sp are the only two !sna takes — anything else is E1052 Unknown SNA command.

Both have defaults, so neither is required. Execution begins at your ORG and the stack sits at $FFFE.

A 48K snapshot has no field for the program counter. The entry address is pushed onto the stack and the loader RETs to it, so sna sp moves the entry word with it. If you place the stack over memory you also want to use, the two bytes below SP are not yours.

nex — the Next executable

A NEX carries a 512-byte header and then whole 16 KiB banks, so a program larger than 64 KiB loads in one go without a loader of yours running first.

512 bytes of header  +  16384 bytes per bank

A single-bank program is 16,896 bytes. FantASM writes version 1.3.

The header

    org $8000
start:
    nex pc start        ; entry point
    nex sp $FF00        ; stack pointer
    nex border 3        ; border while loading
    nex core 2,0,28     ; minimum core version
    ld  a,1
    ret
DirectiveSets
nex pc <addr>Entry point. Defaults to your ORG.
nex sp <addr>Stack pointer. Defaults to $FFFE.
nex border <0-7>Border colour during loading.
nex screen <n>Loading-screen type.
nex bar <on>, <colour>, <startDelay>, <loadDelay>The loading bar; every argument after the first is optional.
nex core <major>, <minor>, <subminor>Minimum core version the program needs.
nex entry <bank>The 16 KiB bank mapped at $C000 on entry.
nex preserve <0|1>Keep most NextRegs rather than resetting them.
nex ram <0|1>RAM required: 0 = 768K, 1 = 1792K.
nex crc <0|1>Write a CRC-32C checksum into the header.
nex cfg <border>, <fileHandle>, <preserve>, <ram>Four of the above at once.

An unrecognised word is E1053 Unknown NEX command, so a typo is refused rather than ignored.

Getting code into a bank

The banks in the file are the banks your program actually filled. Select one with a slot, which is what moves assembly into it:

    org $8000
    ld  a,1
    ret

    bank 11,3           ; assembly continues at $6000
    db  $AA,$BB

    bank 12,4
    db  $CC

That produces a NEX of 49,664 bytes — the header plus banks 2, 11 and 12.

Bare bank 11 does not do this. It selects the bank but leaves the program counter alone, so the bytes carry on landing where they were going, the bank stays empty, and an empty bank is dropped from the file. See Memory and Banking.

nex bank <n> forces a bank into the file that holds no data, for a program that pages one in and fills it at runtime.

What next

Documentation