These are the instructions that deal with controlling the interrupts.
There are no operands. When
di is executed, the (maskable) interrupts are disabled. The flags are preserved.
There are no operands. When
ei is executed, the (maskable) interrupts are enabled. The flags are preserved.
This instruction returns from the interrupt routine. From the programmer’s point of view it is no more than a simple
ret, but it has to be used to properly handle the interrupt. Note that you cannot use conditions with
reti. The flags are not affected.
Basically the same as
reti, but this one is used to return from the nonmaskable interrupt (NMI).
im mode where mode is 0, 1 or 2
Setting the interrupt mode. The flags are not affected. Mode 0 means that only external devices generate interrupts, and the devices send instructions (mostly
rst) to the CPU to execute. (this is not used in the TI calculators). When mode 1 is active, interrupts are generated by the internal circuitry of the processor, and each time this occurs,
rst $38 is executed. The frequency of these interrupts is 200 per second on a ZX Spectrum, but it depends on the state of the batteries in the case of TI calculators (probably varies between 100 and 150). Mode 2 causes the user interrupt to be executed instead of
rst $38. You can read more about this process in the Interrupts section.
rst address where address is $00, $08, $10, $18, $20, $28, $30 or $38
The long name of this instruction is Restart; it is basically a
call to the given address. The action taken by the
rst’s depends on what kind of hardware you have. On the TI calculators they are equivalent to some of the most important ROM calls. Another example from the Spectrum:
rst $28 activates the built-in floating point calculator. The
rst instruction does not affect the flags either.
With these instructions, the CPU can communicate with other pieces of hardware present in the computer. The functions of the ports again depend on the hardware itself.
in a,(n) (n is a byte) or
in reg8,(c) (where reg8 is A, B, C, D, E, H or L)
Reading from the port marked by the second operand, and storing the result into the first operand. The carry is preserved, N is cleared, P/V is parity and the other flags are affected by definition. There exists an undocumented version as well:
in (c) (or
in f,(c) depending on what you compile your programs with), which does not store the result anywhere, but still alters the flags.
out (n),a (n is a byte) or
out (c),reg8 (where reg8 is A, B, C, D, E, H or L)
Writing the value of the second operand to the port given in the first operand. The flags are preserved. Similarly to
in there is an undocumented combination:
out (c),0 can be used, too.
There are no operands. Reads the (C) port and writes the result to (HL), then increments HL and decrements B (not BC!). The carry is preserved, the N flag is reset, while S, H and P/V are undefined. Z is set if B becomes zero after decrementing, otherwise it is reset.
The same as
ini with the minor difference that HL is decremented.
ini repeated until B becomes zero. Therefore the Z flag is always set on leaving the instruction.
The same as
inir, but the memory is naturally filled backwards.
There are no operands. Reads the byte at (HL) and outputs it to the (C) port, then increments HL and decrements B. The carry is preserved, the N flag is reset, while S, H and P/V are undefined. Z is set if B becomes zero after decrementing, otherwise it is reset.
The same as
outi with the minor difference that HL is decremented.
outi repeated until B becomes zero. Therefore the Z flag is always set on leaving the instruction.
The same as
otir, but the memory is naturally filled backwards.
These are the two instructions that do almost nothing. Neither of them needs any operands, and they do not alter the flags either.
This instruction waits for an elementary amount of time: 4 clock cycles, and does nothing else.
The execution of instructions is suspended and the CPU enters the low power state until an interrupt occurs. Note: when the calculator is switched off, it is actually running a series of
halt’s while waiting for On to be pressed.
The reason why these instructions were put into the hardware section is that although they were not documented for a long time, they worked because their existence comes from the structure of the inner circuitry of the Z80 processor. Most of these instructions were already listed in the previous sections, but it is useful to see them listed together.
All the instructions that take advantage of these registers:
ld and the 8-bit arithmetic and logical operations (
xor etc.); these special registers are officially supported in later CPU generations, but you have to be aware that the instructions accessing them are slower than the normal ones. Do not forget that you cannot use them with the shifting, the
res and the
in f,(c) and
out (c),0 instructions.
It is important to mention again, that if you use
sll in your code, your program will behave unexpectedly on the next generations of the Z80 (e. g. they are redefined in the Z380). Of course, it must work on all the TI calculators and on the ZX Spectrum as well.
The instructions of this group were not yet mentioned. They are based on the shift/
res instructions. What they do is besides modifying the contents of (ix/iy+n), they copy the result into an 8-bit register (only into A, B, C, D, E, H or L). There exist various notations for these special instructions. If the base instruction was
ins ops (ins is
res and ops denotes its operands), the resulting instruction is:
ins reg8=ops or
ld reg8,ins ops depending on which assembler you use. So for example you can use
srl b,(ix+$48) (or
srl b=(ix+$48) or
ld b,srl (ix+$48)), which is
srl (ix+$48) followed by
ld b,(ix+$48). Another example:
res d,5,(iy-$12) which is
res 5,(iy-$12) followed by
ld d,(iy-$12). The time needed to execute these instructions is exactly the same as if there was no autocopy! The only drawback is that you can only use them with (ix/iy+n), as I mentioned above.
Back to the index