Additionally, the type of the expected result is indicated by the carry flag: if set, the expected result is a number (in BC); if clear, the expected result is a string (in DE,BC).

All further parameters are left on the calculator stack for the machine-code routine to use with calculator operations or retrieve using standard ROM routines such as FIND-INT1, FIND-INT2, STK-FETCH. On entry, A contains the number of additional parameters on the calculator stack (0-16) and HL contains a bitmask indicating the type of each parameter. Bit 15, indicates the type of the final parameter (and will be the first to be retrieved from the calculator stack), so types can be read by shifting each bit in turn to the carry flag with ADD HL,HL. Type bits are 0 for string, 1 for numeric.

Routines must remove all additional parameters from the calculator stack, otherwise it will be unbalanced and the expression may be calculated incorrectly.

If you are writing a program to run with the 48K or 128K ROM, you should not load I with values between 40h and 7Fh (even if you never use IM 2). When using one of the 128K ROMs, values between C0h and FFh for I should also be avoided if you plan on enabling contention for your target machine / personality and contended memory (i.e. RAM 4 to 7) is to be paged in between C000h and FFFFh. This is due to an interaction between the ULA and the Z80 refresh mechanism, which can cause apparently inexplicable crashes, screen corruption or other undesirable effects. Thus, you should only use vector IM 2 interrupts between 8000h and BFFFh unless you are very confident of your memory mapping (or you are only going to run your program on the +2A, +3e or Next personalities where this problem does not exist).

There are a number of standard pitfalls when programming a banked system such as the ZX Spectrum Next from machine code. If you are experiencing problems, check that your stack is not being paged out during interrupts, and that your interrupt routine is always where you expect it to be (it is advisable to disable interrupts during paging operations). It is also recommended that you keep a copy of the current bank register setting in unpaged RAM somewhere as the ports are write-only. NextBASIC and the editor use the system variables BANKM and BANK678 for 7FFDh and 1FFDh respectively.

If you call NextZXOS routines, remember that interrupts should be enabled upon entry to the routines. Remember also that the stack must be below 49120 (BFE0h) and above 16384 (4000h), and that there must be at least 50 words of stack space available.

You can save your machine code program easily enough with, for example:

SAVE "name" CODE 65268,4

or, in case you used the BANK variant

SAVE "name" BANK %b, 0, 4

There is no way of saving the program such that when loaded it automatically runs itself; however, you can get round this by using the short NextBASIC program:

10 LOAD "name" CODE 65268,4
20 PRINT USR 65268

Which should also be saved as a separate program, using a command of the following form:

SAVE "loader" LINE 10

You may run the machine code from NextBASIC using the single command:

LOAD "loader"

This then loads and automatically runs the NextBASIC program, which in turn loads and runs the machine code. You can try and make a version with the BANK variant as well as that's safer and always preferred.


ZX Spectrum Next User Manual, 3rd Edition (ISBN 978-1-5272-5496-1), written and illustrated by Phoebus R. Dokos. Copyright © 2020-2024 Phoebus Dokos / SpecNext Ltd. Licensed under CC BY-NC-SA 4.0. This is a transcription and can contain errors; check any doubt against the printed page.