The process mode set by the Windows NT operating system causes a protective failure of the instructions running the application in which it accesses the I/O address. This allows the application to attach a device driver for I/O operations. The device driver runs in kernel mode, which enables processes running in this state to perform I/O operations.
----Windows 95/98 is designed for Intel type machines only, with no additional complex I/O requirements, and Windows NT is designed to be ported on different machine mechanisms. This enables the Windows NT System mode to require the driver's creator to consider that a machine may have multiple types of buses, which may require the delivery of addresses between buses. This pattern also distinguishes between I/O space and memory space. Each bus in a multiple-bus machine can support both memory and I/O loops.
----by definition, I/O registers or port accesses are implemented through I/O loops. However, in some systems, the I/O space of the external bus can be imaged to the process memory space. The hardware abstraction layer (hardware abstract Layer) determines these. To access an I/O register, the driver writer must know the register is on that bus, and its I/O space address is on that bus. A bus is determined by its interface class rows (such as ISA, PCI, and so on) and numbering (zero-based).
----Below is an example of an illusion device access I/O, interface type: ISA number 0 address 0xe700. The device description is as follows: Offset Size Usage 0 1 Command Register 1 1 Status Register 2 2 Word data Register 4 4 Dword data register
----Using the toolkit Driverdorks to develop NT device drivers, you can access the device using the following steps:
----to establish a Kiorange object image device register.
Kiorange Deviceios; Status = Devceios.initialize (
ISA,//bus type
0,//bus number
0xe700,//bus address
8,//equipment number
TRUE//image to System space (if the port is a memory image)
);
if (nt_success (status))//established successfully
----can access registers using Kiorange member functions:
Register offset
#define COMMAND 0
#define STATUS 1
#define WDATA 2
#define DDATA 3
Read status Registers
Uchar Devicestatus = deviceios.inb (STATUS);
Write Command Registers
DEVICEIOS.OUTB (Command,cmd_reset);
Write 20 words to port
DEVICEIOS.OUTW (wdata,buffer,20);
----Alternatively, you can create Kioregister objects to access the device:
Kioregister Commandreg = Deviceios[command];
Kioregister Statusreg = Deviceios[status];
Commandrge= (Uchar) RESET; Write Reset Command
Uchar Status=statusreg; Read status Registers
If the register is frequently accessed in the same function, the performance of Kioregiser is better than that of a Kiorange member function. In any case, the data type must be correct (Uchar,ushort,ulong), which determines the actual size of the data on the bus.