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).
Syntax: 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.
Syntax: 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.
Syntax: 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.
Syntax: 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.
This is 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.
This is 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 (add
, sub
, 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 set
instructions!
The in (c)
/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/set
/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 sla
, sra
, sll
, srl
, rl
, rr
, rlc
, rrc
, set
or res
and ops denotes its operands), the resulting instruction is: ins reg8,ops
, 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.