When programming memory mapped I/O devices, the addresses of relevant device registers are needed. These are typically set up as compiler/assembler preprocessor directives, and may be stored in a seperate include file, or simply declared in the source file.
The following code from HLAB6 illustrates the assembly language programming of the parallel port:
/* porta1s.s test of port a parallel i/o */ .text .even .global main main: move.b #0xff,%d1 /* set port A */ move.b %d1,PADDR /* for output */ move.b #0b10101011,%d1 move.b %d1,PADAT /* write something to port A*/ rts MBARx = 0x10000000 /* Module Base Address value */ PADDR = MBARx+0x01C5 /* Port A Data Direction Register; 8-bit, R/W */ PADAT = MBARx+0x01C9 /* Port A Data Register, 8-bit, R/W */
The following C program from HLAB6 performs the same function:
/* porta1c.c test of sbc port a */ #define MBARx 0x10000000 /* Module Base Address value */ #define PADDR (* (char *) (MBARx+0x01C5)) /* Port A Data Direction Register; 8-bit, R/W */ #define PADAT (* (char *) (MBARx+0x01C9)) /* Port A Data Register, 8-bit, R/W */ int main() { PADDR = 0xff; /* set port A for output */ PADAT = 0xaa; /* output something */ return 0; }
Observe carefully how the port addresses are setup in each case, and in particular, the type casting used in the C code (see Clements, Chapter 3, page 176).
ANU Engineering - ENGN3213