The <peekpoke.h> Header File

Routines for easier access to the memory and to I/O ports

Functions

peek_bit
Fetches a bit from the memory.
peek_l
Fetches a double word from the memory.
peek_w
Fetches a word from the memory.
peek
Fetches a byte from the memory.
peekIO_bit
Reads a bit from an I/O port.
peekIO_w
Reads a word from an I/O port.
peekIO
Reads a byte from an I/O port.
poke_bchg
Inverts a bit at a memory address.
poke_bclr
Clears a bit at a memory address.
poke_bset
Sets a bit at a memory address.
poke_l
Stores a double word in memory.
poke_w
Stores a word in memory.
poke
Stores a byte in memory.
pokeIO_bchg
Inverts a bit in an I/O port.
pokeIO_bclr
Clears a bit in an I/O port.
pokeIO_bset
Sets a bit in an I/O port.
pokeIO_w
Sends a word to an I/O port.
pokeIO
Sends a byte to an I/O port.
speek_l
Fetches a signed double word from the memory.
speek_w
Fetches a signed word from the memory.
speek
Fetches a signed byte from the memory.

peek_bit

short peek_bit (unsigned char *addr, short bit);

Fetches a bit from the memory.

peek_bit is a macro which fetches bit bit from the memory address addr. For example, to read the first bit from the video memory (the pixel in the upper left corner), do this:

byte = peek_bit (0x4C00, 7);

Note that it is better to use LCD_MEM in this case.

Note: Do not use peek_bit for reading I/O ports! Use peekIO_bit instead.


peek_l

#define peek_l(addr) (*((unsigned long*)(long)(addr)))

Fetches a double word from the memory.

peek_l is like peek, but fetches a double word from the memory instead of a byte.


peek_w

#define peek_w(addr) (*((unsigned short*)(long)(addr)))

Fetches a word from the memory.

peek_w is like peek, but fetches a word from the memory instead of a byte.

Note: Do not use peek_w for reading I/O ports! Use peekIO_w instead.


peek

#define peek(addr) (*((unsigned char*)(long)(addr)))

Fetches a byte from the memory.

peek is a macro which fetches a byte from the memory address addr, where addr does not necessarily need to be a pointer. Instead, it can be of any type (usually an integer) which may represent a memory address in a way which makes sense. This way it allows for fetching bytes from memory using the style which is common in most dialects of the BASIC language. For example, to read a first byte from the video memory, do this:

byte = peek (0x4C00);

Note that it is better to use LCD_MEM in this case.

Note: Do not use peek for reading I/O ports! Use peekIO instead.


peekIO_bit

short peekIO_bit (unsigned char *port, short bit);

Reads a bit from an I/O port.

This macro exists because peek_bit is not reliable when reading data from memory-mapped I/O ports. See the notes about peekIO if you want to know why.


peekIO_w

#define peekIO_w(port) (*((volatile unsigned short*)(long)(port)))

Reads a word from an I/O port.

peekIO_w is like peekIO, but reads a word from the I/O port instead of a byte.


peekIO

#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).


poke_bchg

void poke_bchg (unsigned char *addr, short bit);

Inverts a bit at a memory address.

This macro inverts bit bit at memory address addr. It is useful if you do not want to store a whole byte at this address, but only need to invert the state of a single bit. As usual, the rightmost bit of a value is numbered 0, and the leftmost bit is 7 in this case. For example, let's assume the address addr contains the value 0b10011010, and you call this macro like this:

poke_bchg (addr, 3);

Then the value will be 0b10010010 afterwards. Making the same call again will restore the previous value 0b10011010,

Note: Do not use poke_bchg for sending bits to I/O ports! Use pokeIO_bchg instead.


poke_bclr

void poke_bclr (unsigned char *addr, short bit);

Clears a bit at a memory address.

This macro clears bit bit at memory address addr. It is useful if you do not want to store a whole byte at this address, but only need to set a single bit to 0. As usual, the rightmost bit of a value is numbered 0, and the leftmost bit is 7 in this case. For example, let's assume the address addr contains the value 0b10011010, and you call this macro like this:

poke_bclr (addr, 3);

Then the value will be 0b10010010 afterwards.

Note: Do not use poke_bclr for sending bits to I/O ports! Use pokeIO_bclr instead.


poke_bset

void poke_bset (unsigned char *addr, short bit);

Sets a bit at a memory address.

This macro sets bit bit at memory address addr, which can be any which which may be cast to unsigned char *. It is useful if you do not want to store a whole byte at this address, but only need to set a single bit to 1. As usual, the rightmost bit of a value is numbered 0, and the leftmost bit is 7 in this case. For example, let's assume the address addr contains the value 0b10010010, and you call this macro like this:

poke_bset (addr, 3);

Then the value will be 0b10011010 afterwards.

Note: Do not use poke_bset for sending bits to I/O ports! Use pokeIO_bset instead.


poke_l

#define poke_l(addr,val) (void)(*((unsigned long*)(long)(addr)) = (val))

Stores a double word in memory.

poke_l is like poke, but stores a double word in memory instead of a byte.


poke_w

#define poke_w(addr,val) (void)(*((unsigned short*)(long)(addr)) = (val))

Stores a word in memory.

poke_w is like poke, but stores a word in memory instead of a byte.


poke

#define poke(addr,val) (void)(*((unsigned char*)(long)(addr)) = (val))

Stores a byte in memory.

poke is a macro which stores a byte val at the memory address addr, where addr does not necessarily need to be a pointer. Instead, it can be of any type (usually an integer) which may represent a memory address in a way which makes sense. This way it allows for storing bytes in memory using the style which is common in most dialects of the BASIC language. For example, to store a byte 255 at the first byte of the video memory, do this:

poke (0x4C00, 255);

Note: Do not use poke for sending bytes to I/O ports! Use pokeIO instead.


pokeIO_bchg

void pokeIO_bchg (unsigned char *port, short bit);

Inverts a bit in an I/O port.

This macro exists because poke_bchg is not reliable when sending data to memory-mapped I/O ports. See the notes about pokeIO if you want to know why.


pokeIO_bclr

void pokeIO_bclr (unsigned char *port, short bit);

Clears a bit in an I/O port.

This macro exists because poke_bclr is not reliable when sending data to memory-mapped I/O ports. See the notes about pokeIO if you want to know why.


pokeIO_bset

void pokeIO_bset (unsigned char *port, short bit);

Sets a bit in an I/O port.

This macro exists because poke_bset is not reliable when sending data to memory-mapped I/O ports. See the notes about pokeIO if you want to know why.


pokeIO_w

#define pokeIO_w(port,val) (void)(*((volatile unsigned short*)(long)(port)) = (val))

Sends a word to an I/O port.

pokeIO_w is like pokeIO, but sends a word to the I/O port instead of a byte.


pokeIO

#define pokeIO(port,val) (void)(*((volatile unsigned char*)(long)(port)) = (val))

Sends a byte to an I/O port.

poke is not reliable when sending data to memory-mapped I/O ports. Suppose that you have a device mapped to the address port, 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

poke (port, 127);
poke (port, 0);
poke (port, 255);
poke (port, 0);

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 port is a normal memory address, but it may be fatal if port is an address of a memory-mapped I/O port. To prevent such behaviour, use pokeIO instead of poke, i.e. write

pokeIO (port, 127);
pokeIO (port, 0);
pokeIO (port, 255);
pokeIO (port, 0);

Basically, pokeIO works exactly like poke, but prevents any unwanted optimizations generated by the compiler. It may be used even for storing bytes in memory, but poke will generate better code when working with memory.


speek_l

#define speek_l(addr) (*((signed long*)(long)(addr)))

Fetches a signed double word from the memory.

speek_l is like peek_l, but the result is interpreted as a signed double word.


speek_w

#define speek_w(addr) (*((signed short*)(long)(addr)))

Fetches a signed word from the memory.

speek_w is like peek_w, but the result is interpreted as a signed word.


speek

#define speek(addr) (*((signed char*)(long)(addr)))

Fetches a signed byte from the memory.

speek is like peek, but the result is interpreted as a signed byte.


Return to the main index