Flow-control structures: Difference between revisions

Content added Content deleted
(→‎{{header|Z80 Assembly}}: added conditional jumps)
Line 3,038: Line 3,038:
INIR ; in, increment, repeat until BC = 0
INIR ; in, increment, repeat until BC = 0
INDR ; in, decrement, repeat until BC = 0
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>
RST # ; call a subroutine in low memory. This only takes 1 byte to encode (a CALL takes three.)
HALT ; the program counter won't move past this instruction until an interrupt occurs. (See below).</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.
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 the interrupts do, when they occur, and which interrupt modes 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.
* <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 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. Check the hardware documentation so that you know where to assemble the code for your interrupt handler. 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 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.
* Interrupt mode 2 is selected with <code>IM 2</code>. This one is a bit weird. It uses the 8-bit value in the <code>I</code> 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 interrupt addresses generated by this method are the same. Whatever address that will be is where the interrupt handler will go.