ZX Spectrum Next Development
The ZX Spectrum Next assembler in Klive IDE provides a comprehensive development environment for the ZX Spectrum Next platform. This page covers all Next-specific features, including automatic conveniences, the .savenex pragma, and NEX file generation.
Quick Start
The simplest ZX Spectrum Next program in Klive IDE looks like this:
.model next
.savenex file "myapp.nex"
; Your code starts at $8000 automatically
main:
ld a, 4
out (0xFE), a ; Set border color to green
trap:
jr $When you use .model next, Klive automatically:
- Sets
.savenex ram 768(768K RAM) - Sets
.savenex border 7(white border) - Sets
.savenex entryaddr $8000(entry at $8000) - Maps unbanked code to bank 2 at address $8000
Automatic Conveniences for .model next
Default .savenex Values
When .model next is specified, these defaults are automatically applied:
| Parameter | Default Value | Description |
|---|---|---|
ram | 768 | 768K RAM configuration |
border | 7 | White border color |
entryaddr | $8000 | Entry point at $8000 |
You can override any default by explicitly specifying the .savenex pragma:
.model next
.savenex file "myapp.nex"
.savenex border 5 ; Override default (use cyan instead of white)
.savenex ram 1792 ; Override default (use 1792K instead of 768K)
; Code...Unbanked Code (Automatic Bank 2 Mapping)
When you write code without an explicit .bank pragma, it’s considered “unbanked” code and automatically:
- Starts at $8000 - The default assembly address is $8000
- Maps to Bank 2 - During NEX export, unbanked code is written to bank 2
- Uses the range $8000-$bfff - The standard 16KB bank 2 address range
Example - Simple unbanked program:
.model next
.savenex file "simple.nex"
; This code is unbanked - automatically starts at $8000 and maps to bank 2
main:
ld a, 3
call setborder
trap:
jr $
setborder:
out (0xFE), a
retAddress Range Warning (Z0904)
The assembler warns you if unbanked code exceeds the typical bank 2 range ($bfff):
.model next
.savenex file "test.nex"
.org $c000 ; ⚠️ Warning Z0904: Address $c000 exceeds $bfff
ld a, 7
trap:
jr $The warning message is:
Warning Z0904: Unbanked code address $c000 exceeds typical bank 2 range ($8000-$bfff).
Consider using .bank pragma for explicit memory layout.Note: This is a warning, not an error. Your code will still compile and the NEX file will be generated, but you should review whether you intended to extend beyond the standard bank 2 range.
Multiple Unbanked Sections
You can have multiple unbanked code sections at different addresses using .org:
.model next
.savenex file "multi.nex"
; First section at $8000
ld a, 1
call routine1
; Second section at $9000
.org $9000
routine1:
out (0xFE), a
ret
; Third section at $a000
.org $a000
routine2:
ld a, 2
retAll unbanked sections are collected and written to bank 2 in the NEX file at their respective addresses.
Multi-Bank Applications
For complex applications requiring multiple memory banks, use explicit .bank pragmas alongside unbanked code:
.model next
.savenex file "screen-tests.nex"
.savenex core "3.1.0"
; Unbanked code in bank 2 at $8000
main:
;
; Save the current MMU 5 value ($A000-$BFFF)
ld a,$55
ld bc,$243b
out (c),a
inc b
in a,(c)
push af
;
; Page in the first 8K of 16K Bank $20 to $A000-$BFFF
di
nextreg $55,$40
;
; Invoke the subrouting in Bank $20
call SetBorder
;
; Restore the old MMU 5 value
pop af
nextreg $55,a
ei
trap
jr $
; Explicit bank $20 code
.bank $20
.org $0000
.disp $a000
SetBorder
ld a,3
out ($fe),a
retHow Multi-Bank Code Works
- Unbanked code exports to bank 2 at the addresses where it’s assembled ($8000-$bfff typically)
.banksections export to their specified bank (e.g., bank 5) at the addresses defined by.organd.disp- Both can coexist in the same source file
- Each bank section is independent
SAVENEX Pragma Reference
The .savenex pragma provides a declarative way to configure ZX Spectrum Next NEX file generation parameters directly in your assembly source code. This pragma is only available when targeting the ZX Spectrum Next (Model 4).
Overview
The .savenex pragma uses a subcommand syntax where each subcommand configures a specific aspect of the NEX file. You can use multiple .savenex pragmas throughout your source code, and the compiler will collect and merge all declarations into a complete NEX file configuration.
Syntax:
.savenex <subcommand> <parameters>The pragma is case-insensitive, so .savenex, .SAVENEX, and .SaveNex are all valid.
Subcommands
FILE - Set Output Filename
Specifies the name of the NEX file to be generated.
Syntax:
.savenex file <filename>- filename: String literal or expression that evaluates to a string
Example:
.savenex file "myprogram.nex"RAM - Set RAM Configuration
Specifies the amount of RAM required by the program.
Syntax:
.savenex ram <size>- size: Must be either 768 (for 768K RAM) or 1792 (for 1792K RAM)
- Default when
.model nextis used: 768
Examples:
.savenex ram 768 ; 768K RAM (default for .model next)
.savenex ram 1792 ; 1792K RAMBORDER - Set Border Color
Specifies the border color to be set when the program loads.
Syntax:
.savenex border <color>- color: Integer value from 0 to 7
- Default when
.model nextis used: 7 (white)
Example:
.savenex border 5 ; Cyan borderBorder Colors:
| Value | Color |
|---|---|
| 0 | Black |
| 1 | Blue |
| 2 | Red |
| 3 | Magenta |
| 4 | Green |
| 5 | Cyan |
| 6 | Yellow |
| 7 | White |
CORE - Specify Required Core Version
Specifies the minimum ZX Spectrum Next core version required to run the program.
Syntax:
.savenex core <major>, <minor>, <subminor>
; or
.savenex core <version-string>- major: Integer value from 0 to 255
- minor: Integer value from 0 to 255
- subminor: Integer value from 0 to 255
- version-string: String literal in the format “major.minor.subminor”
Examples:
.savenex core 3, 1, 10 ; Requires core version 3.1.10 or higher
.savenex core "3.1.10" ; Alternative string formatNote: Both formats are supported. The string format is convenient when the version comes from a constant or macro, while the comma-separated format allows for calculated values.
STACKADDR - Set Stack Pointer Address
Specifies the initial stack pointer address.
Syntax:
.savenex stackaddr <address>- address: Integer value from 0 to 0xFFFF
Example:
.savenex stackaddr 0xFF00ENTRYADDR - Set Entry Point Address
Specifies the program’s entry point address.
Syntax:
.savenex entryaddr <address>- address: Integer value from 0 to 0xFFFF
- Default when
.model nextis used: $8000
Example:
.savenex entryaddr 0x8000 ; Entry at $8000 (default for .model next)ENTRYBANK - Set Entry Bank
Specifies the bank number to be paged in when the program starts.
Syntax:
.savenex entrybank <bank>- bank: Integer value from 0 to 111
Example:
.savenex entrybank 5FILEHANDLE - Set File Handle Mode
Specifies whether to close or keep open the NEX file handle after loading.
Syntax:
.savenex filehandle <mode>- mode: Either “close” (close file after loading) or “open” (keep file open, pass handle in BC register)
- Default: “close” (file is closed after loading)
Examples:
.savenex filehandle "close" ; Close file after loading (default)
.savenex filehandle "open" ; Keep file open, pass handle in BC registerNEX File Specification:
- “close” writes 0x0000 to offset 140 (file is closed by loader)
- “open” writes 0x0001 to offset 140 (file kept open, handle passed in BC register)
PRESERVE - Preserve Next Registers
Specifies whether to preserve the Next hardware registers after loading.
Syntax:
.savenex preserve <value>- value: “on”/“off” or 1/0
Examples:
.savenex preserve "on"
.savenex preserve 1
.savenex preserve "off"
.savenex preserve 0SCREEN - Configure Loading Screen
Specifies a loading screen to display while the program loads.
Syntax:
.savenex screen <type> [, <filename> [, <palette-offset>]]- type: Screen type - one of: “layer2”, “ula”, “lores”, “hires-color”, “hires-mono”
- filename: (Optional) Filename of the screen data
- palette-offset: (Optional) Offset in the palette file (0-255)
Examples:
.savenex screen "layer2"
.savenex screen "layer2", "loading.scr"
.savenex screen "layer2", "loading.scr", 0PALETTE - Set Palette File
Specifies a palette file to load.
Syntax:
.savenex palette <filename>- filename: String literal with the palette filename
Example:
.savenex palette "colors.nxp"COPPER - Set Copper Code File
Specifies a copper code file to load and execute.
Syntax:
.savenex copper <filename>- filename: String literal with the copper code filename
Example:
.savenex copper "effects.cu"BAR - Configure Loading Bar
Configures the loading bar display.
Syntax:
.savenex bar <enabled> [, <color> [, <delay> [, <start-delay>]]]- enabled: “on”/“off” or 1/0
- color: (Optional) Bar color (0-255)
- delay: (Optional) Delay per bar step (0-255)
- start-delay: (Optional) Delay before starting (0-255)
Examples:
.savenex bar "on"
.savenex bar "on", 2
.savenex bar "on", 2, 50
.savenex bar "on", 2, 50, 100NEX File Format
The NEX file format (see details here) is the native executable format for the ZX Spectrum Next. It’s a container format that includes:
- Header Information: File version, RAM requirements, entry points, etc.
- Screen Data: Optional loading screen in various formats
- Palette Data: Optional palette information
- Copper Code: Optional copper coprocessor code
- Loading Bar: Optional visual feedback during loading
- Program Banks: The actual program code and data organized in 16K banks
NEX File Version
The .savenex pragma targets NEX file format version 1.2, which is the current standard for ZX Spectrum Next executables.
Bank Organization
The NEX file organizes code and data into 16K banks that correspond to the Next’s memory management system:
- Banks 0-1: ROM (read-only, system)
- Bank 2: Default user code bank (unbanked code maps here automatically)
- Banks 3-4: Standard RAM banks
- Banks 5-111: Extended RAM banks available for paging
How Unbanked Code Maps to Bank 2
When you use .model next and write code without explicit .bank pragmas:
- Your code is assembled at addresses starting from $8000
- During NEX export, this “unbanked” code is written to bank 2
- The offset calculation is:
bank2_offset = address - $8000 - Code at $8000 goes to offset 0 in bank 2
- Code at $9000 goes to offset $1000 in bank 2
- And so on…
Example:
.model next
.savenex file "test.nex"
; Code at $8000 → bank 2, offset $0000
main:
ld a, 1
; Code at $9000 → bank 2, offset $1000
.org $9000
routine:
ld a, 2Loading Process
When a NEX file loads on the ZX Spectrum Next:
- The NEX loader reads the header to determine requirements
- If specified, the loading screen is displayed
- If enabled, the loading bar provides visual feedback
- Program banks are loaded into the specified memory locations
- Hardware registers are configured according to the NEX header
- Control is transferred to the entry point address with the entry bank paged in
Default Values
Default values for .savenex parameters depend on whether you’re using .model next:
With .model next (Automatic Conveniences)
| Parameter | Default Value | Description |
|---|---|---|
ram | 768 | 768K RAM |
border | 7 | White border |
entryaddr | $8000 | Entry point at $8000 |
entryBank | 0 | Bank 0 |
fileHandle | ”close” | Close NEX file after loading |
preserveRegs | false | Don’t preserve registers |
Without .model next (Traditional Mode)
| Parameter | Default Value | Description |
|---|---|---|
ram | (none) | Must be specified |
border | 0 | Black border |
entryaddr | (none) | Must be specified |
entryBank | 0 | Bank 0 |
fileHandle | ”close” | Close NEX file after loading |
preserveRegs | false | Don’t preserve registers |
Error Handling
The assembler will generate errors if:
- You use
.savenexwhen not targeting the ZX Spectrum Next (Model 4) - Invalid values are provided (e.g., border color > 7, bank > 111)
- Required parameters are missing
- Invalid screen types or modes are specified
- Version numbers exceed 255
The assembler will generate warnings if:
- Z0904: Unbanked code address exceeds $bfff (typical bank 2 range)
Notes
- The
.savenexpragma only configures the NEX file parameters; it doesn’t generate the actual NEX file. The file generation happens during the export process. - Multiple
.savenexpragmas with the same subcommand will use the last value specified. - Expression support allows you to use symbols, calculations, and other expressions for numeric parameters.
- String parameters can be string literals or expressions that evaluate to strings.
- Unbanked code is automatically tracked and exported to bank 2 during NEX file generation.
- You can mix unbanked code and explicit
.banksections in the same source file.
See Also
- Pragmas - Complete pragma reference
- Klive Z80 Assembler Overview - General assembler documentation
- ZX Spectrum Next Documentation - Official Next documentation