peekIO Function (Macro)

peekpoke.h

#define peekIO(port) (*((volatile unsigned char*)(long)(port)))

Reads a byte from an I/O port.

peek is not reliable when reading data from memory-mapped I/O ports. For example, suppose that the user wants to wait until the programable timer on the TI-89 (its value may be read from the address 0x600017) reaches the value 255. The following construction seems quite good:

while (peek (0x600017) != 255);
However, it will cause an infinity loop. Namely, the compiler will notice that the same value is read in the loop. As a normal memory location can not be changed without explicitely writing to it, and there is nothing in the loop which changes the data at the address 0x600017, the optimizer will move memory reading out of the loop to make the code more efficient. Such behaviour is correct for ordinary memory locations. But the compiler does not know anything about the fact that 0x600017 is not an ordinary memory location but an I/O port, which may be changed unpredictably (purely by the hardware, without any program control). To prevent such behaviour, use peekIO instead of peek, i.e. write
while (peekIO (0x600017) != 255);
Basically, peekIO works exactly like peek, but prevents any unwanted optimizations generated by the compiler. Always use peekIO for reading memory-mapped I/O ports, else you may have trouble (especially in short loops). For example, to read the keyboard column mask on TI-89, do
key_mask = peekIO (0x60001B);
peekIO may be used even for reading bytes in memory, but peek will generate better code when working with memory. However, use peekIO to read any memory location which may change in a way which is unpredictable from the aspect of a normal program flow (for example, a memory location which is changed in the body of the interrupt handler).