[Main]
Name=pokeIO
Type=Function
Subtype=Macro
Header Files=peekpoke.h
Definition=#define pokeIO(port,val) (void)(*((volatile unsigned char*)(long)(port)) = (val))

[Description]
Sends a byte to an I/O port.

[Explanation]
<A HREF="$$LINK(peekpoke.h/poke)">poke</A> is not reliable when sending data to memory-mapped I/O ports.
Suppose that you have a device mapped to the address <I>port</I>, and that this device
requests sending a sequence ot bytes 127,0,255,0 to this address to be reset. If you
simply try to do
<PRE>poke (<I>port</I>, 127);
poke (<I>port</I>, 0);
poke (<I>port</I>, 255);
poke (<I>port</I>, 0);
</PRE>
the compiler will (incorrectly) conclude that sending a sequence of bytes to the same address is
nonsense, because new values will overwrite previous ones (assuming that the address
points to the memory), so the optimizer will
ignore all stores but the last one. Such behavior is correct if <I>port</I> is a
normal memory address, but it may be fatal if <I>port</I> is an address of a memory-mapped I/O
port. To prevent such behaviour, use pokeIO instead of <A HREF="$$LINK(peekpoke.h/poke)">poke</A>, i.e. write
<PRE>pokeIO (<I>port</I>, 127);
pokeIO (<I>port</I>, 0);
pokeIO (<I>port</I>, 255);
pokeIO (<I>port</I>, 0);
</PRE>
Basically, pokeIO works exactly like <A HREF="$$LINK(peekpoke.h/poke)">poke</A>, but prevents any unwanted optimizations
generated by the compiler. It may be used even for storing bytes in memory, but <A HREF="$$LINK(peekpoke.h/poke)">poke</A>
will generate better code when working with memory.
