Memory Architecture
Understanding how memory works in Spectranext is essential for developing programs that interact with the cartridge and manage resources efficiently.
Overview
Spectranext uses a banked memory system that maps cartridge memory into the ZX Spectrum's address space. The system manages multiple memory sections and provides ROM routines for memory management.
Memory Sections
Spectranext organizes memory into four main sections:
- Permanent Flash ROM (0x0000-0x0FFF): Always mapped, contains socket library, utility routines, buffer handlers
- Page A (0x1000-0x1FFF): Paged memory area A, can be mapped to any memory page
- Page B (0x2000-0x2FFF): Paged memory area B, can be mapped to any memory page
- Permanent RAM (0x3000-0x3FFF): Always mapped, contains temporary workspace and Spectranet system variables
Page A and Page B
The two paged memory areas (Page A and Page B) are the primary interface between your programs and the cartridge:
- Page A (0x1000-0x1FFF): Primary paged memory area, typically used for data memory
- Page B (0x2000-0x2FFF): Secondary paged memory area, typically used for program code
These pages can be mapped to different memory banks, allowing access to ROM routines, RAM buffers, and other cartridge resources. Note that if you call socket functions from code running in paging area A, you need to ensure the page is properly managed to avoid crashes.
Memory Mapping
When Spectranext is paged in, memory is mapped as follows:
0x0000-0x0FFF - Permanent Flash ROM (cartridge - always mapped)
0x1000-0x1FFF - Page A (cartridge memory - paged)
0x2000-0x2FFF - Page B (cartridge memory - paged)
0x3000-0x3FFF - Permanent RAM (cartridge - always mapped, workspace/system vars)
0x4000-0xFFFF - Spectrum RAM (normal)
According to the Spectranet documentation, the base Spectranet functions tend to page data memory into paging area A (for instance, the 42 column character set, or the W5100 register/buffer areas) and programs into area B - but there are no hard and fast rules.
Paging Mechanism
The cartridge uses hardware paging controlled by I/O port 0x033B:
- Writing to
0x033Bpages Spectranext in or out - Page A and Page B can be independently mapped to different memory banks
- The system automatically manages paging during ROM routine calls
Important: Do not use OUT instructions directly to page memory unless absolutely necessary, as the I/O ports may change in future CPLD revisions. Always use the provided ROM routines (SETPAGEA, SETPAGEB, PUSHPAGEA, etc.) which keep system variables up to date.
The current page in each paging area is stored in system variables v_pga and v_pgb (at addresses 0x3F05 and 0x3F06 in the Spectranet system variables area).
ROM Routines for Memory Management
Spectranext provides ROM routines for managing memory pages:
Setting Pages
SETPAGEA equ 0x3E33 ; Set page area A
SETPAGEB equ 0x3E36 ; Set page area B
SETPAGEA: Maps a memory bank into Page A (0x1000-0x1FFF)
- Input: A register = page number to map
- Output: Page A now contains the specified page
SETPAGEB: Maps a memory bank into Page B (0x2000-0x2FFF)
- Input: A register = page number to map
- Output: Page B now contains the specified page
Pushing and Popping Pages
PUSHPAGEA equ 0x3E81 ; Page into area A, pushing old one
POPPAGEA equ 0x3E84 ; Restore previous page in area A
PUSHPAGEB equ 0x3E87 ; Page into area B, pushing old one
POPPAGEB equ 0x3E8A ; Restore previous page in area B
These routines maintain a stack of page mappings, allowing you to temporarily change pages and restore them later.
PUSHPAGEA:
- Saves current Page A mapping
- Maps new page into Page A
- Use when you need temporary access to a different page
POPPAGEA:
- Restores previous Page A mapping
- Must be called after PUSHPAGEA to restore state
PUSHPAGEB / POPPAGEB: Same as Page A routines but for Page B
Page Reservation
RESERVEPAGE equ 0x3E9F ; Reserve a page of static RAM
FREEPAGE equ 0x3EA2 ; Free a page of static RAM
RESERVEPAGE: Allocates a page of static RAM
- Output: A register = page number (carry clear on success)
- Output: Carry set if no pages available
- Use for buffers, workspaces, or temporary storage
FREEPAGE: Releases a reserved page
- Input: A register = page number to free
- Must free pages when done to avoid memory leaks
Memory Access from Programs
Accessing ROM Routines
ROM routines are accessed via call tables in the paged memory areas. When Spectranext is paged in, you can call routines directly:
call SOCKET ; Allocate a socket
call CONNECT ; Connect to remote host
call SETPAGEA ; Set page A
Important: If your code is running from Spectrum's main RAM and needs to call Spectranet functions, you must page in the Spectranet memory first using CALL PAGEIN (at address 0x3FF9). This triggers the CPLD's CALL trap mechanism. The instruction at 0x3FF9 is just a RET, but the CPLD intercepts the CALL instruction to page in the Spectranet address space.
Similarly, when the CPLD sees the CPU fetch an instruction at address 0x007C, it causes the memory to be paged out. Again, this is a RET instruction.
Note: You must use CALL 0x3FF9 (not a conditional call or jump) for the pagein operation, as the CPLD decodes the CALL instruction specifically to avoid compatibility problems with ROMs that have code at this address.
Accessing Paged Memory
To access data in paged memory:
- Set the page: Use
SETPAGEAorSETPAGEBto map the desired page - Access memory: Read/write to addresses 0x1000-0x1FFF (Page A) or 0x2000-0x2FFF (Page B)
- Restore page: If you changed pages, restore the original mapping
Example - Accessing ROM page:
ld a, 0x05 ; ROM page 5 (0x05 = ROM chip, page 5)
call SETPAGEA ; Map ROM page 5 into Page A
ld hl, 0x1000 ; Start of Page A
ld a, (hl) ; Read byte from ROM page 5
; ... use the data ...
ld a, 0 ; Original page
call SETPAGEA ; Restore original page
Example - Accessing RAM page:
ld a, 0xC3 ; RAM page 3 (0xC0 = RAM chip base, +3 = page 3)
call SETPAGEA ; Map RAM page 3 into Page A
ld hl, 0x1000 ; Start of Page A
ld (hl), 0x42 ; Write byte to RAM page 3
; ... use the data ...
ld a, 0 ; Original page
call SETPAGEA ; Restore original page
Example - Accessing W5100 buffers:
ld a, 0x44 ; W5100 buffer page 0
call SETPAGEA ; Map W5100 buffer into Page A
ld hl, 0x1000 ; Start of Page A
ld a, (hl) ; Read byte from W5100 buffer
; ... use the data ...
ld a, 0 ; Original page
call SETPAGEA ; Restore original page
Example - Accessing WiFi configuration:
ld a, 0x48 ; WiFi configuration page
call SETPAGEA ; Map WiFi config into Page A
ld hl, 0x1000 ; Start of Page A (wifi_config_registers_t structure)
; ... access WiFi config registers ...
; Set command to scan
ld (hl), 1 ; WIFI_COMMAND_SCAN_ACCESS_POINTS
; ... wait for scan_status to update ...
ld a, 0 ; Original page
call SETPAGEA ; Restore original page
Example - Accessing XFS registers:
ld a, 0x49 ; XFS filesystem page
call SETPAGEA ; Map XFS registers into Page A
ld hl, 0x1000 ; Start of Page A (xfs_registers_t structure)
; ... access XFS command/status registers ...
ld a, 0 ; Original page
call SETPAGEA ; Restore original page
Workspace Areas
Spectranext provides workspace areas for temporary data:
- XFS Workspace: Used by filesystem operations (accessible via page 0x49)
- WiFi Workspace: Used by WiFi operations (accessible via page 0x48, see
wifi_config_registers_t.workspace) - Socket Workspace: Used by network operations
- General Workspace: Available for program use
Check ROM routine documentation for specific workspace locations.
Page Numbering and Available Pages
According to the Spectranet memory documentation, memory is arranged in 4K pages. The page register is 8 bits, allowing access to 256 4K pages (1MB total address space). Spectranext maintains backwards compatibility with Spectranet's page numbering scheme.
Available Page Ranges
| Page(s) | Description / Usage |
|---|---|
| 0x00-0x1F (32 pages, 128KB) | Flash ROM Pages. Contains ROM code, socket library, utility routines. 0x00: Permanently mapped to 0x0000-0x0FFF, socket library and utility functions. 0x01: Spectranet data. 0x02: Spectranet utility programs (configuration utility, DHCP client). 0x03: Reserved for future use. Last 256 bytes of 0x1F: Spectranet configuration storage. |
| 0x40 | W5100 registers (network hardware registers). |
| 0x44-0x47 | W5100 buffers (4 pages, network hardware buffers). |
| 0x48 | WiFi configuration registers (WIFI_CONFIG_SPECTRANET_PAGE). Contains wifi_config_registers_t structure (see api/wifi.h). Used for scanning, connecting, managing WiFi state. |
| 0x49 | XFS filesystem registers (XFS_SPECTRANET_PAGE). Contains XFS command and status registers. Used by Spectrum programs for XFS filesystem access. |
| 0xC0-0xDF (32 pages, 128KB) | Static RAM Pages. General-purpose RAM storage. 0xC0: Permanently mapped to 0x3000-0x3FFF, workspace, buffers, system variables. 0xC1-0xC2: Frame buffer copy during NMI events. 0xDC-0xDF: Used by configuration utility for flash rewrite. |
Page Number Examples
0x00= ROM page 0x00 (permanently mapped flash)0x1F= ROM page 0x1F (last ROM page)0x40= W5100 registers0x44= W5100 buffer page 00x48= WiFi configuration registers0x49= XFS filesystem registers0xC0= RAM page 0x00 (permanently mapped RAM)0xC3= RAM page 0x03 (available developer RAM)
I/O Ports for Paging
The following I/O ports are used for paging (important - these may change during prototyping):
- Port 0x003B: Memory page for area A (8 bits, write-only)
- Port 0x013B: Memory page for area B (8 bits, write-only)
The complete 16 bits of the port address is decoded, so only OUT instructions to these specific ports will work. However, you should not use OUT instructions directly - always use the ROM routines (SETPAGEA, SETPAGEB, etc.) which keep system variables updated.
Memory Constraints
Available Pages
- ROM Pages: 32 pages (0x00-0x1F) for ROM code
- Network/Hardware Pages:
- Page 0x40: W5100 registers
- Pages 0x44-0x47: W5100 buffers (4 pages)
- Page 0x48: WiFi configuration registers
- Page 0x49: XFS filesystem registers
- RAM Pages: 32 pages (0xC0-0xDF) for RAM storage
- Total: 1MB addressable space (256 pages × 4KB)
Note: Spectranext maintains backwards compatibility with Spectranet's page numbering scheme. The WiFi configuration (page 0x48) and XFS filesystem registers (page 0x49) are Spectranext-specific additions that extend the original Spectranet memory map.
Page Size
Each page is 4KB (4096 bytes):
- Page A: 0x1000-0x1FFF = 4KB (one page visible)
- Page B: 0x2000-0x2FFF = 4KB (one page visible)
Memory Limits
- Static RAM: Limited number of pages available
- Dynamic Buffers: Managed by the system
- Stack Space: Use carefully in interrupt handlers
Best Practices
Page Management
- Save/Restore Pages: Always restore pages after temporary changes
- Use PUSHPAGE/POPPAGE: Prefer these over SETPAGE when possible
- Free Reserved Pages: Always free pages allocated with RESERVEPAGE
- Check Errors: Verify page operations succeeded
Memory Access
- Keep Pages Mapped: Don't change pages unnecessarily
- Use Workspace: Use provided workspace areas when available
- Respect Boundaries: Don't access memory outside mapped pages
- Handle Errors: Check for memory allocation failures
Performance
- Minimize Page Changes: Page changes have overhead
- Cache Frequently Used Data: Copy to Spectrum RAM if needed repeatedly
- Batch Operations: Group memory operations together
- Use Appropriate Pages: Choose ROM vs RAM pages based on needs
Example: Reading from a Page
; Reserve a page for our workspace
call RESERVEPAGE
jr c, no_memory ; Check for error
ld (saved_page), a ; Save page number
; Map our page into Page A
call SETPAGEA
; Access data in Page A
ld hl, 0x1000 ; Start of Page A
ld de, buffer ; Destination in Spectrum RAM
ld bc, 256 ; Number of bytes
ldir ; Copy data
; Restore original page
ld a, 0
call SETPAGEA
; Free the reserved page
ld a, (saved_page)
call FREEPAGE
Debugging Memory Issues
Common Problems
- Page Not Mapped: Accessing unmapped memory returns garbage
- Page Changed: Memory contents change if page is remapped
- Memory Leaks: Forgetting to free reserved pages
- Stack Corruption: PUSHPAGE/POPPAGE misuse
Debugging Tools
- Memory Map Command: Use
memory-mapconsole command - Peek/Poke Commands: Use
peekandpoketo inspect memory - Debugger: Use breakpoints to inspect memory state
Next Steps
- Socket APIs - Network programming with sockets
- Debugging Spectrum - Debug your programs
- Check ROM routine documentation for specific memory operations