<!-- PDF page 277 -->

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.

