[Compuware Corporation] [Compuware NuMega home page]                [NuMega Lab]
[teal]

 [DriverStudio]    [Image][Image]
   Home
 [Driver Products]        Driver Technical Tips
   DriverStudio          How To Access I/O Ports under Windows NT
   DriverBundle
   Previews              When an application is running on Windows NT, the operating
   Compatibility         system has set the processor to a mode in which the instructions
 [Downloads]             for accessing the I/O space cause protection faults. This means
                          that an application requires the assistance of a device driver to
 Wizards                  perform I/O. Device drivers run in kernel mode, which means
   Utilities             (among other things) that the processor is running in a state
   NT source             that allows execution of I/O instructions.
 examples
   VxD source            If your goal is to gain access to the I/O space for the purpose
 examples                 of a small number of dedicated applications, as opposed to
   WDM source            creating a driver that enables generalized access to your
 examples                 hardware, then you should consider DriverAgent. This product
 [Resources]             enables to you access I/O ports without having to write a device
 Technical papers         driver. It provides not only I/O access, but memory mapped device
   Useful links          access, interrupt management, DMA support, and a set of utility
   Technical tips        objects, such as timers, events, and FIFOs. DriverAgent works
 [Support]               with applications written in C/C++, VB, Delphi, and Java.
 Support                  If you are writing a device driver, you'll find that doing simple
   Knowledge base        I/O to ports under Windows NT is not quite as simple as it is
   Problem               under Windows 95. Under Windows 95, a driver simply called
 submission               functions _inp and _outp, or used assembler instructions IN and
   Product               OUT. Because Windows 95 is designed solely for Intel machines, no
 registration             additional abstraction of the I/O is required.
   Release notes
 [Shop NuMega]           Windows NT was designed to be portable to different machine
 Buy it!                  architectures. The system model requires the driver writer to
   Price list            take into account that a machine may have multiple buses, and
   How to buy            that it may be necessary to translate addresses between buses.
   Sales offices         Furthermore, the model distinguishes between I/O space and memory
                          space. In a machine with multiple buses, each bus may support
                          both memory and I/O cycles.
 [Y2K Compliance]
                          By definition, I/O registers, also called ports, are accessed
                          with I/O cycles. However, on some systems the I/O space of a
 [More information]       peripheral bus can be mapped to the processor memory space. The
                          HAL makes this determination. To access an I/O register, the
                          driver writer must know on which bus the register resides, and
                          its I/O space address on that bus. A bus is specified by its
                          interface type (ISA, PCI, etc.) and its number (starting with
                          zero).

                          Here is an example of I/O access for an imaginary device, which
                          resides at address 0xE700 of the ISA bus 0. The layout of the
                          device is as follows:

                           Offset   Size     Usage

                              0        1     Command register

                              1        1     Status register

                              2        2     Word data register

                              4        4     Dword data register

                          With DriverWorks, a tool kit for developing NT/WDM device
                          drivers, you use the following steps to access the device:

                          First, construct an instance of KIoRange to map the device
                          registers.

                                   KIoRange DeviceIos;

                          status = DeviceIos.Initialize(
                                  Isa,    // Bus type
                                  0,      // Bus number
                                  0xE700, // Bus address
                                  8,      // Device size
                                  TRUE    // Map to system space (if port is memory mapped)
                                  );
                          if (NT_SUCCESS(status)) // all ok


                          You can use member functions of KIoRange to access the registers:

                          // register offsets
                          #define COMMAND 0
                          #define STATUS  1
                          #define WDATA   2
                          #define DDATA   3

                          // read status register
                          UCHAR DeviceStatus = DeviceIos.inb (STATUS);

                          // Write to command register
                          DeviceIos.outb (COMMAND, CMD_RESET);

                          // Write 20 words the word data port
                          DeviceIos.outw (WDATA, buffer, 20);

                          Alternatively, you can create instances of KIoRegister, and use
                          them to access the device:

                          KIoRegister CommandReg = DeviceIos[COMMAND];
                          KIoRegister StatusReg = DeviceIos[STATUS];

                          CommandReg = (UCHAR)RESET;      // write RESET command
                          UCHAR status = StatusReg;       // read STATUS register

                          There is a small performance benefit to using KIoRegister as
                          opposed to member functions of KIoRange if a register is accessed
                          repeatedly in the same function. However, it is crucial to type
                          the data correctly (UCHAR, USHORT, ULONG), because this
                          determines the size of the access that actually goes out to the
                          bus.

                          Back to technical tip start page.

  DriverCentral  DriverStudio  Free downloads  Resources  Support and
                          Services  Shop NuMega
     Compuware NuMega  Tel: +1 603 578-8400  Updated: 9 August 1999 
                      Problems? Contact our webmaster.
