Many devices use a control/status and a data register in tandem. The declarations for
such a pair might look like:
typedef short int control;
typedef short int data;
typedef struct port port;
struct port
{
control cr;
data dr;
};
port *const p = (port *)0xFF70;
The typedef:
typedef struct port port;
defines port as a type name that’s equivalent to struct port. This allows you to
refer to the structure type port without also writing the keyword struct in front of it.
In C++, a struct, union or enum name is automatically a type name, so you don’t need
the typedef in C++. But it doesn’t hurt. For the remainder of this paper, I will assume
for convenience that a struct, union or enum name is a type name, even in C.
A bi-directional device (supporting both input and output) may use a pair of registers for
input and another pair for output. The declaration for such a pair might look like:
struct ioport
{
port in, out;
};
Using the declaration above,
ioport *const piop = (ioport *)0xFF70;
declares piop to point to an ioport, and:
piop->out.cr &= ~ENABLE;
disables output interrupts for that port. An assignment such as:
piop->out.dr = c;