Flow-control structures: Difference between revisions

Content added Content deleted
m (→‎{{header|Z80 Assembly}}: minor clarification)
m (→‎{{header|Z80 Assembly}}: added JR and interrupts.)
Line 3,018: Line 3,018:
=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
<lang z80>JP &XXXX ; jump to an absolute address.
<lang z80>JP &XXXX ; jump to an absolute address.
JR &XX ; jump XX bytes forward or backward (this is a signed offset)
JR z,&XX ; conditionally jump forward or backward (JR cannot use parity, overflow, or sign flags to jump. JP, CALL, and RET can.
JP (HL) ; copy the value in HL to the program counter
JP (HL) ; copy the value in HL to the program counter
PUSH rr RET ; fake a return address and "return" to that address
PUSH rr RET ; fake a return address and "return" to that address
Line 3,032: Line 3,034:
OTDR ; out, decrement, repeat until BC = 0
OTDR ; out, decrement, repeat until BC = 0
INIR ; in, increment, repeat until BC = 0
INIR ; in, increment, repeat until BC = 0
INDR ; in, decrement, repeat until BC = 0</lang>
INDR ; in, decrement, repeat until BC = 0
RST # ; call a subroutine in low memory. This only takes 1 byte to encode (a CALL takes three.)</lang>

In addition, there are multiple hardware interrupt modes. These are not directly controlled by the programmer, but the programmer needs to be aware of them so that they do not destroy the flow control of the program. At a minimum they should push all registers they use as soon as possible and pop them before returning (or alternatively use the exchange commands <code>EX AF,AF'</code> and <code>EXX</code> at the beginning and end.) What they do and which ones are used will vary depending on the hardware.


* <code>NMI</code> executes the instruction <code>CALL &0066</code> and is returned from with <code>RETN</code>. Unlike other interrupt modes, the <code>DI</code> instruction will not prevent it.
* Interrupt mode 0 is selected with <code>IM 0</code>. The external hardware that generates the interrupt will do so by feeding the CPU the <code>CALL</code> instruction to the interrupt handler's memory location. This interrupt, and the other two below, should be returned from with <code>RETI</code>.
* Interrupt mode 1 is selected with <code>IM 1</code>. The external hardware that generates the interrupt will do so by feeding the CPU the instruction <code>RST 38</code>. This means that the interrupt handler (or a jump to it) will need to be located at memory address 0x0038.
* Interrupt mode 2 is selected with <code>IM 2</code>. This one is a bit weird. It uses the 8-bit value in the I register as well as am 8-bit value provided by whatever hardware is generating the interrupt, and will concatenate them into a memory address which will then be <code>CALL</code>ed. Generally, this interrupt mode is best handled by filling 257 bytes of memory with the same value, so that all interrupts addresses generated by this method are the same. Whatever address that will be is where the interrupt handler will go.


(Side note: The Game Boy uses none of the above, its interrupts are handled differently. The only thing the Game Boy has in common with the Zilog Z80 is that interrupts will not occur if they were disabled with <code>DI</code>. The Game Boy has no NMI.)


=={{header|zkl}}==
=={{header|zkl}}==