I/O Access using Inline Assembly
The basis for this guide was sent to me by Armin Bauer(thanks!). It shows the basics on accessing hardware I/O ports using inline asm with GCC based compilers. The code in this guide requires:
This guide show how, using inline assembly, to preform hardware I/O access from within a single C source file. If the assembly syntax looks strange to you, it's because it's in AT&T syntax. GCC's built in assebler, GAS, uses AT&T syntax assembly. Take a look at Related Sites if you'd like to learn more about using inline assemble with GCC/DJGPP. The following code is the basis of all our C based I/O access: // -------------------------------------------------------------------------- // From NOPE-OS // -------------------------------------------------------------------------- // [email protected] // -------------------------------------------------------------------------- /* Input a byte from a port */ inline unsigned char inportb(unsigned int port) { unsigned char ret; asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port)); return ret; } /* Output a byte to a port */ /* July 6, 2001 added space between :: to make code compatible with gpp */ inline void outportb(unsigned int port,unsigned char value) { asm volatile ("outb %%al,%%dx": :"d" (port), "a" (value)); }First this is the Sourcecode to acces I/O-Ports. You'll need this Routines to acces I/O Ports, but not to access Memory (like Screen Memory). If you don't know, what inline means: Inline make's your compiler not to create a function. this let's the compiler insert the code in the line where the inline function is called. -Armin Bauer The above code only reads and write bytes. If you need to read or write words or double word, all you have to do is change the function names, the size of the accumlative register (al, ax, eax), and the return and argument types for each function. Also remember that some hardware devices must have interrupts disabled while accessing them. The following example shows how to read the CMOS's extended memory count value. It's meant to be run under DOS/Win(because of the printf). If you want to try this example out under DOS, don't forget a DPMI extender that's required for all DJGPP apps. #include <stdio.h> /* Input a byte from a port */ inline unsigned char inportb(unsigned int port) { unsigned char ret; asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port)); return ret; } /* Output a byte to a port */ /* July 6, 2001 added space between :: to make code compatible with gpp */ inline void outportb(unsigned int port,unsigned char value) { asm volatile ("outb %%al,%%dx": :"d" (port), "a" (value)); } /* Stop Interrupts */ inline void stopints() { asm ("cli"); } unsigned char highmem, lowmem; unsigned int mem; int main() { /* need to stop ints before accessing the CMOS chip */ stopints(); /* write to port 0x70 with the CMOS register we want to read */ /* 0x30 is the CMOS reg that hold the low byte of the mem count */ outportb(0x70,0x30); /* read CMOS values from port 0x71 */ lowmem = inportb(0x71); /* write to port 0x70 with the CMOS register we want to read */ /* 0x31 is the CMOS reg that hold the high byte of the mem count */ outportb(0x70,0x31); /* read CMOS values from port 0x71 */ highmem = inportb(0x71); /* fix the low and high bytes into one value */ mem = highmem; mem = mem<<8; mem += lowmem; printf("\nOld style CMOS extended memory count is %uk.\n", mem); }Source code is here and a precompiled binary is here. DJGPP QuickAsm Programming Guide Inline Assembler in DJGPP |