What's new?
Top Next

What's new in 6.0 version?

There are no changes in TVicHW32 if you are still working under 32-bit Windows versions only. But you need this new version if you want to run your 32-bit application under Windows XP 64-bit. In this case, you must take into consideration a few following things:

· You can use OpenTVicHW function instead of OpenTVicHW32.
· You can not use RunRing0Function to run your code in ring 0 CPU.
· You can handle single interruption only.
· No keyboard hook is supported

This version includes TVicHW32 component for Borland Kylix (Linux) as a free gift for our customers (not supported!).

What's new in 5.0 version?

First, TVicHW32 5.0 allows to execute the user code which contains the privileged CPU instructions. Through the new RunRing0Function routine you can run your
procedure into Ring 0 CPU. In this case your code will have a maximal privilege level which was available before in the drivers only. Inside of this procedure you can access all ports directly with the IN/OUT assembler instructions or with _inp() _outp() "C" functions. Also you can enable/disable the hardware interruptions, get an access to the CPU special registers and so on. See "Running of the user level code in Ring 0 CPU" topic for more details.
Second, TVicHW32 5.0 allows to handle by correct way the "Level sensitive" interruptions usually generated by PCI devices. See UnmaskIRQEx function and Hardware interrupts topic for more details.
Third, with TVicHW32 5.0 you can read IDE HDD Serial Number as well as another disk geometry information for four IDE channels instead of two in previous version. See "HDD hardware manufacturer info" topic.
At last, TVicHW32 5.0 includes more full documentation package include F.A.Q

.


Contact Info
Previous Top Next

TVicHW32 is maintained at the following internet address:

http://www.entechtaiwan.com/tools.htm

where you can find the latest release and links to support and on-line ordering sites. Comments, questions and suggestions regarding TVicHW32 can
be directed by e-mail to tools@entechtaiwan.com.


Introduction

TVicHW32 6.0
Help File

Copyright(c) Victor Ishikeev 1997-2004
http://www.entechtaiwan.com/tools.htm
tools@entechtaiwan.com
card


What is TVicHW32?

You've just written an application to control a custom or system hardware device under DOS or Win16. Now comes the task of porting your software to Win32. You know this is a major undertaking because no one programming language contains the constructions or functions for Win32 hardware access, i.e. port I/O operations, physical memory accessing, hardware interrupt handling or DMA functions. Up to now, your only choice was to write your own device driver. You also know this means:you must have the Microsoft Driver Development Kit (DDK )installed on your PC, you must examine the driver structures - which are quite different for Windows 95/98/ME (VxD) and for Windows NT/2000 /XP(kernel-mode driver), if you don't know C then you'll have to learn this programming language and very likely the assembler instructions, you'll need to learn driver debugging methods and probably have to purchase a high-cost debugging tool, be prepared to lose data from your hard drive because even small driver bug produce the Blue Screen of Death (BSOD).
Fortunately, you now have a much simpler choice. TVicHW32 is a general purpose device driver that can be used by practically any programming language. It lets you access and control hardware directly from any Win32 application under Windows 95/98/ME/NT/2000/XP/XP64 without having to use the Windows DDK.

"The core" of TVicHW32 is composed by following files:

File | Description
tvichw32.vxd | The virtual device driver supported by Windows 95/98/ME. Must be located under \<windows>\system;
tvichw32.sys | The kernel-mode driver supported by Windows NT/2000/XP. Must be located under \<windows>\system32\drivers;
tvichw64.sys | The kernel-mode driver supported by Windows XP 64-bit. Must be located under \<windows>\system32\drivers;
tvichw32.dll | The library providing driver function call for almost all programming languages under 32-bit Windows versions. Must be located under \<windows>\system or any other directory available for the running application
tvichw32.h | header file providing a C/C++ interface to tvichw32.dll
tviclib.pas | provides a Delphi interface to tvichw32.dll and TVicHW32.dll
tviclib.bas | provides a Visual Basic interface to tvichw32.dll and TVicHW32.dll


TVicHW32 Main Capabilities

TVicHW32 main capabilities are:

· direct port I/O access,
· obtains pointers to the physical memory by directly mapping it to the user process's address space,
· simultaneous handling of multiple hardware interrupts,
· advanced LPT support including access to any pin on any LPT port,
· access to IDE HDDs hardware manufacturer information (HD serial number, geometry, etc.) for IDE1-IDE4,
· keyboard hooks and scan-code messaging,
· access to PCI configuration space allowing enumeration of all PCI devices,
· memory buffers allocation for the system and bus master DMA operations,
· execution of the user's functions at high-privileged CPU level (Ring 0).


Programming Languages Support

TVicHW32 provides an interface to drivers for:

· Microsoft Visual C/C++ 6.0 and 7.0
· Borland Delphi (versions 2-7)
· Borland C++ Builder (versions 1, 3-6)
· Microsoft Visual Basic 6.0
· Microsoft Visual Basic .Net
· Microsoft Visual C#
· Other programming systems that access functions in DLL's

We also provide TVicHW32 component for Borland Kylix (Linux) as a free gift for our customers (not supported!).


Licensing and Registration

TVicHW32 version 6.0 License Agreement

You should carefully read the following terms and conditions before using this software. Your use of this software indicates your acceptance of this license agreement and warranty.

TVicHW32 Shareware License (Unregistered)
TVicHW32 Single License
TVicHW32 Commercial License
Legal Disclaimer


Shareware (Unregistered) License

TVicHW32 Shareware License Agreement (Unregistered)
Previous Top Next

You may use a Shareware Copy of this Software for an evaluation period of up to 30 days, in order to determine whether the Software meets your needs before purchasing it. Once the evaluation period ends, you agree to either purchase a Registered Copy of the Software, or to stop using it and remove it from your computer system. If you have ordered a Registered Copy of the Software, you may continue to use your Shareware Copy until your Registered Copy arrives.

You must:

· not defeat, or try to defeat, messages in the Software which encourage users to register;
· modify or prepare derivative works of the Software;
· reverse engineer, decompile or disassemble the Software.

You are hereby granted the righto make as many copies of this software and its documentation as you wish;give exact copies (including all files) of the original version to anyone;and distribute the software and documentation in its unmodified form via electronic means. There is no charge for any of the above.
You are specifically prohibited from charging, or requesting donations, for any such copies (a small handling fee is acceptable). You are further prohibited from distributing the software and/or documentation with other products (commercial or otherwise) without prior written permission.


Single License

TVicHW32 Single License

Once registered, you are granted a non-exclusive license to use TVicHW32 on one computer at a time, for any legal purpose. The registration fee is $99
U.S. You have not rights to distribute TVicHW32 core files as part of your software.


Commercial License

TVicHW32 Commercial (World Wide) License

This license grants you the right to distribute TVicHW32 drivers and DLL's as part of your software without having to pay royalties. This license gives you the option of e-mailing us with a new name for the drivers and DLL so it appears you wrote these yourself. The commercial license also lets you e-mail us for a time-critical function or interrupt handler to be added to the drivers for better hardware access performance.


Legal Disclaimer

Legal Disclaimer

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

IN NO EVENT WILL THE AUTHOR OR ANY OTHER PARTY WHO MAY HAVE DISTRIBUTED THE
SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR ONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR
A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


How to order

To evaluate TVicHW32's functionality, simply download and install the demo version of TVicHW32 6.0 (300 KB). This demo includes many test examples showing how to use TVicHW32 with each programming language listed above. The TVicHW32 demo version is fully functional so you can write and debug your application before you buy one of the following licenses to use or distribute the driver.

Single License is $99 U.S. Purchase online.

Commercial License is $297 U.S. Purchase online.

Phone Orders - available 24/7:

· U.S. and Canada : 1-877-REGSOFT (1-877-734-7638)
· International : 1-770-319-2718

Fax Orders - available 24/7 :

· US Toll-Free Fax Number : 1-800-886-6030
· International Fax Number : 1-208-279-3837 (UK Customers can fax to (0870)132-2485)

When placing your order, please refer to the following product IDs:

· Single License Product ID#: 3137
· Commercial License Product ID#: 35047

Upgrade from TVicHW32 previous versions 6.0 also available for $50 US only for
the single license and for $150 for the commercial license (ordering of 3 units
of "TVicHW32 Upgrade to 6.0" product means commercial license upgrade).

Note! Tell us your registration name and order Id *before* you pay!

Thank you for your order.

Victor Ishikeev,
---------------


Programmer's Guide

TVicHW32 6.0
Programmer's Guide

Copyright(c) Victor Ishikeev 1997-2004
http://www.entechtaiwan.com/tools.htm
tools@entechtaiwan.com


TVicHW32 Overview

What is TVicHW32?
Basic functions of TVicHW32


Basic functions of TVicHW32

TVicHW32 Common Functions

Before using any of the functions of TVicHW32, the driver must be loaded and initialized with the help of the function OpenTVicHW32 . It must be done once after starting the application. Also resources used by the driver should be cleaned up (driver closed) before the application is closed.

Attention! - do not open and close the driver multiple times while application is running!

Schematic session of using TVicHW32:

// initialize (open)the driver
HW32 =  OpenTVicHW();

// Check if the driver initialized successfully
if ( GetActiveHW ( HW32 ) ) {

     ...  TVcHW32 session...

     // Free resources used by the driver (close the driver)

     HW32 = CloseTVicHW32(HW32);
}
else  // An error happened while starting the driver
   MessageBox("Cannot open the driver","Attention!", MB_OK | MB_ICONWARNING);

Driver can be initialized by up to 16 applications simultaneously.


Accessing physical memory addresses

Memory Mapping
Additional functions


Memory Mapping

To access specified physical memory address you have to map this physical address to a linear memory of the current process' address space. TVicHW32 includes the function MapPhysToLinear, which performs the above task and returns the pointer to the above linear memory defined by it's physical address and size. When the pointer is not needed by application any more, this physical memory area can and must be unmapped with the function UnmapMemory.

The following is an example how to get a pointer to the ROM BIOS area:

char *pBios;
HANDLE HW32 = NULL;

HW32 = OpenTVicHW32( HW32, "TVICHW32","TVicDevice0");

if (GetActiveHW(HW32)) {

     pBios = (char*)MapPhysToLinear(HW32,0xF8000,256); //256 bytes, starting from 0xF8000

     //...pBIOS session...

     UnmapMemory(HW32, 0xF8000,256); // undo mapping

     HW32 = CloseTVicHW32(HW32);     //  close the driver
  }
  else ... // failed


Additional Functions

As it was mentioned, the MapPhysToLinear function returns the pointer to the linear memory defined by it's physical address and size. You can work with a returned pointer directly or by means of additional functions set which provides physical memory access by bytes, by words or by double words. It's especially useful for Visual Basic programmers as Visual Basic has some limitations on working with a pointer directly.

Below is the list of the above mentioned functions:

UCHAR  GetMem  (HANDLE HW32, ULONG LinAddr, ULONG Offset);
USHORT GetMemW (HANDLE HW32, ULONG LinAddr, ULONG Offset);
ULONG  GetMemL (HANDLE HW32, ULONG LinAddr, ULONG Offset);
void   SetMem  (HANDLE HW32, ULONG LinAddr, ULONG Offset, UCHAR bValue);
void   SetMemW (HANDLE HW32, ULONG LinAddr, ULONG Offset, USHORT wValue);
void   SetMemL (HANDLE HW32, ULONG LinAddr, ULONG Offset, ULONG dValue);


I/O Ports control

General information on I/O ports control
Single read/write operations
Data array read/write operations


General information on I/O ports control

Basic port I\O overview

I/O ports control function set includes two major groups of functions: - single input/output by byte (word, double word) and data array input/output. Direct input/output is also possible by running RunRing0Function with the help of built-in Assembler commands or a function like inp()/outp().

There are two modes of controlling I/O ports - "Soft Mode" and "Hard Mode". "Soft Mode" provides better speed, but can produce false result if the port is already used by other driver. "Hard Mode" is slower but provides a very reliable ports access even if they are used by other drivers. Please refer to FAQ devoted to this topic.

The function SetHardAccess is used for switching between the above two modes. To verify the current port I/O mode, please use the function GetHardAccess.


Single read/write operations

Single port I\O operations

The following set of functions is used to read/write single values through port. Their assignment is evident from names and requires no comments.

GetPortByte - read a byte from a port
GetPortWord - read a word from a port
GetPortLong - read a double word from a port
SetPortByte - write a byte to a port
SetPortWord - write a word to a port
SetPortLong - write a double word to a port


Data array read/write operations

TVicHW32 also contains a set of functions for read/write data arrays from/to a single port. These functions are based on INSB/INSW/INSD assembly input commands and OUTSB/OUTSW/OUTSD output commands. You can use these functions, for example, to perform the LPT operations in EPP mode.

List of functions:

ReadPortFIFO   - read an array of bytes
ReadPortWFIFO  - read an array of words
ReadPortLFIFO  - read an array of double words
WritePortFIFO  - write an array of bytes
WritePortWFIFO - write an array of words
WritePortLFIFO - write an array of double words

In pPortRec structure you should indicate port address, quantity of data elements which you want to read or write, and an array of values to write to port. Remember, these functions don't provide another exchange algorithm ("handshaking"). They are used only for devices with hardware support of group input/output operations.


Handling hardware interrupts

Standard handling hardware interrupts
Extended options of hardware interrupt handling
Performance Issues


Standard handling hardware interrupts

Attention! - we only deal with hardware interrupts! TVicHW32 does not support DOS/BIOS functions call. It is assumed that a user is well familiar with hardware interrupts and has some relevant experience in DOS or 16-bit Windows.

Function UnmaskIRQ installs a hardware interrupt handler. You can specify IRQ number and unmasks this IRQ at hardware level. It works as follows:

  USHORT IrqNumber = 10;
  ULONG IrqCounter = 0;

  // The interrupt handler
  void __stdcall MyInterruptHandler( USHORT IrqNumber )
  {
      ++ IrqCounter;
  }

  ...

  // Main program
  HW32 = OpenTVicHW32( HW32, "TVICHW32","TVicDevice0" );
  if (GetActiveHW(HW32)) {
    UnmaskIRQ( HW32, IrqNumber, MyInterruptHandler );
  }
  else ... // failed

Calling the function MaskIrq stops hardware interrupt processing:

  MaskIrq( HW32, IrqNumber );

TVicHW32 has a capability to install several interrupt handlers or use one interrupt handler for several IRQs.

Important!:

· IRQ0 (system timer) cannot be used with any versions of Windows;
· RTC (Real Time Clock) cannot be used with Windows NT/2000.

Function IsIrqMasked checks if the specified IRQ number is masked or not. Counter value for the number of handled interrupts is returned by function GetIRQCounter. The interrupts from the ACK line (pin 10) of LPT port should be additionally enabled by the ForceLPTIrq function.


Extended options of hardware interrupt handling

As it was mentioned earlier, it's very important for level sensitive interrupts to inactivate bus interrupt level soon after it's activation. New function UnmaskIRQEx lets you to specify a register to read/write for interrupt acknowledge. Format of this function is the following:

  void UnmaskIRQEx  (
         HANDLE HW32,
         USHORT IRQNumber,
         ULONG IrqShared,
         TOnHWInterrupt HWHandler,
         pIrqClearRec IrqRec
  );

Let's assume that we have to write 0x0F0F to some register for interrupt acknowledge. Register is a word displacement 0x320 in the memory area with the physical address 0x3C000:

   IrqClearRec IrqRec;               // control structure
   ULONG IrqShared = FALSE;          // interrupt is acquired
   memset(&IrqRec,0,sizeof(IrqRec)); // clean structure fields
   IrqRec.ClearIrq = 1;              // Interrupt acknowledge needed
   IrqRec.TypeOfRegister = 1;        // Register type - memory-mapped
   IrqRec.WideOfRegister =    2;     // Register size - 2 bytes (a word)
   IrqRec.ReadOrWrite = 1;           // acknowledge means write to a register
   IrqRec.RegBaseAddress = 0x3C000;  // base physical memory address
   IrqRec.RegOffset = 0x320;         // register first byte displacement in memory
   IrqRec.ValueToWrite = 0x0F0F;     // A value to write to a register for interrupt acknowledge

   UnmaskIRQEx(HwCtrl,IRQ,IrqShared, MyInterruptHandler,&IrqRec);

Interrupt handler is the same as used in the basic option.


Performance Issues

TVicHW32 runs no problem for all the interrupt frequencies no more then 10 kHz. But there might be a delay that occurs when interrupts are delivered to the application level because interrupt handler is not called directly from the driver. The delay might be as big as number of milliseconds and it depends on CPU usage. What to do if such a delay is critical for the task? The following solutions are possible:

· if possible to change a hardware design in order to get the most from the hardware;
· to buy TVicHW32 Commercial License; in this case interrupt handler will be a part of the driver itself;
· to order custom device driver.

It's important to always remember that Windows is not a real time system! That's why if response time should be satisfactory and guaranteed, you have either order a custom device driver or switch an operating system to a real time one like QNX.


Specific work with LPT ports

Introductory notes
Basic functions to handle LPT ports
Handling different connector pins of LPT port
Working with Centronix signals


Introductory notes

General theory and scheme on LPT ports handling are not provided in this manual because it's assumed that a user is already familiar with LPT port architecture, functionality and pin descriptions. This information is available from a variety books and manuals as well as on the Internet. I can recommend the following excellent book: Jan Axelson "Parallel Port Complete", available for purchase at www.amazon.com or at the author's website: www.lvr.com/parport.htm
The website www.lvr.com/parport.htm itself is an excellent source of information on the subject as well.

TVicHW32 includes a set of the functions to handle LPT ports at a hardware level. At the same time TVicHW32 does not offer any procedures to provide some exchange protocols for LPT. If necessary these procedures can be implemented by a user with a help of basic functions provided with TVicHW32. Soon we are planning to release a new product TVicLPT which will be fully devoted to LPT ports handling.


Basic functions to handle LPT ports

Here I give some short description only. For more information please follow the links.

GetLPTNumPorts  - returns a number of LPT ports detected on the system
GetLPTNumber    - returns a number of current LPT
SetLPTNumber    - allows to change current LPT port number
GetLPTBasePort  - returns base address of current LPT port number(data register address)
AddNewLPT       - allows to enter an address of a user "non-standard" port.
SetLPTReadMode  - switches mode of current LPT port to "read" because normally data register is "read only"
SetLPTWriteMode - switches mode of current LPT port back to "write"
ForceIrqLPT     - allows to switch on and off receiving hardware interrupts by a system due to electric level change at ACK line (pin 10)
AcquireLPT      - acquire current LPT port
ReleaseLPT      - release acquired LPT port
IsLPTAcquired   - check if LPT port is acquired.


Handling different connector pins of LPT port

TVicHW32 allows to read/write operations for different pins of the D25 LPT connector. Pin numbers start from 1. For writing an electrical level to the selected pin of current LPT port use the function SetPin, and for reading use GetPin. It's also possible to control these pins by direct port access or LPT bit access, so these functions added to TVicHW32 for convenience.
Remember that not all the pins are available to read/write. See LPTTest example provided with deliverable TVicHW32 for more information. Pins 2-8 (data register) are available for reading only after the port was switched to read mode with the function SetLPTReadMode.


Working with Centronix signals

Here you can find a list of the functions to work with Centronix interface signal. Like in the above mentioned situation it's possible to work with Centronix over LPT port or by controlling pins directly. Basically this is what's called operations with LPT connector pins but they have a different names. Besides most of Centronix signals are inverted at reading.
Below is the list of the functions. You can get more information by clicking on function name. You should also remember that many Centronix signals are shown
inverted. You can get detailed information by clicking on the function name.

GetLPTAckwl
GetLPTBusy
GetLPTPaperEnd
GetLPTSlct
GetLPTError
LPTInit
LPTSlctIn
LPTAutofd
LPTStrobe


Getting a manufacture information on IDE disks including serial number.


Hardware Manufacturer Information

TVicHW32 allows to read a manufacture information on IDE hard drives including model, serial number, geometry and other. Please note that there is a difference between a serial number of the disk and a serial number of disk partition which was created during formatting and can be read by function GetVolumeInformation! A manufacture information retrieved by TVicHW32, is permanent and cannot be change by disk formatting.
The following function helps to retrieve a manufacture information:

void GetHDDInfo( HANDLE HW32, USHORT IdeNumber, USHORT Master, pHDDInfo Info);

Input parameters for this function are IDE (1-4) channel number and "Master" or "Slave" depending on how disk was configured. The result returns in the structure HDDInfo.

You can read about how this information can be used for your software copyright protection in the following FAQ section


Access to PCI devices information

PCI Bus Configuration Info

Basic functions
How to enumerate all PCI devices


PCI Basic Functions

PCI bus control function set includes the following items:

GetLasPciBus         - returns the last PCI bus number begin from 0 value.
GetHardwareMechanism - returns the hardware PCI mechanism used on your PC, 1 or 2.
GetPciHeader         - reads data from the header of the device's PCI configuration space for present Vendor Id and Device Id.
SetPciHeader         - writes data to the header of the device's PCI configuration space.
GetPciDeviceInfo     - returns a PCI device info for given bus number, device number and function number.


How to enumerate all PCI devices

Function GetPciDeviceInfo can be used to get an information on all the devices installed on PCI bus (including AGP and PCMCIA). The following is an example of how to do it:

int buses;
WORD n,bus,dev,func;
PCI_COMMON_CONFIG Info;

buses = GetLastPciBus(HW32); // Last PCI bus number(first - 0)

n = 0; // 0 devices was detected

for (bus = 0; bus<=buses; bus++) { // soft out all the buses
  for (dev = 0; dev<32; dev++)   { // sort out all the devices
    for (func= 0; func<8; func++) { // sort out all the functions

      if ( GetPciDeviceInfo(HwCtrl,bus,dev,func,&Info) &&
           (Info.VendorID != 0xFFFF) &&
           (Info.DeviceID != 0xFFFF ) ) {

               n++; // device is found!
              .. get device info from the Info structure..
      }
    }
  }
}


Keyboard Access

Sending a scan-code to a keyboard controller
Keystroke intercept (keyboard hook)


Sending a scan-code to a keyboard controller

Direct keyboard controller access

Note: does not work under Windows XP 64-bit!

TVicHW32 is capable of sending scan-code directly to keyboard controller which simulates real keystroke. Since this simulation is happening at the hardware level, those signals are sent "world wide", i.å. at a system level. The correspondence between scan-code and a real key is available in almost any reference or manual on IBM PC. It's important to remember that after sending a code imitating a keystroke, there should be key release code sent. This is the same code as keystroke but having "1" in the most significant bit :

BYTE KeyDownCode = 31; // keystroke code "s"
PutScanCode( HW32, KeyDownCode); // send a keystroke code
PutScanCode( HW32, KeyDownCode | 0x80); // send a key release code


Keystroke intercept (keyboard hook)

Note: does not work under Windows XP 64-bit!

void HookKeyboard( HANDLE HW32, TKbHookHandler HWHandler);

This function allows you to install a keyboard hook to intercept a keystroke.

The following procedure will remove this feature:

void UnhookKeyboard( HANDLE HW32).

The following is an example of how to set up a keyboard hook:

ULONG HookCounter = 0;

// Simple keyboard hook
void __stdcall KeyboardHookHandler(BYTE scan_code)
{
   HookCounter++;// hook counter
}

// Keyboard hook setup
HookKeyboard ( HW32, KeyboardHookHandler);

..... process ....

// Disabling keyboard hook
UnhookKeyboard ( HW32 );


DMA buffer allocation

DMA buffer overview
How to allocate


DMA Buffers overview

Important! TVicHW32 is not a replacement for DMA functions, because a user can do it independently using other available functions. However TVicHW32 allows
you to solve a major problem on DMA buffer allocation. As you probably know this memory should meet the following requirements:

· memory range should be physically contiguous (scatter-gather operations are not considered for the system DMA);
· physical address of the beginning of this range should be aligned at a specified boundary
· memory range should be fixed;
· memory must be page-locked;
· for system DMA operations (thorough DMA controller) physical addresses should be less than 16 MBytes.

Last requirement is not mandatory if memory is allocated for Bus-Master DMA operations which are specific for PCI bus when DMA operation is performed by adapter but not DMA controller. For System DMA this requirement is essential but unfortunately it's not always possible to meet it. For example if all the memory below 16 Mb is already used by the system and there is no possibility to allocate memory of required size. In this case it's recommended to include the option "Memory Hole: 15-16 Mb" into BIOS Setup Program. This option is available with some BIOS versions especially for DMA memory allocation.Bytes


How to allocate

Below is an example of using GetSysDmaBuffer function:

DMA_BUFFER_REQUEST DmaBuffer;

DmaBuffer.LengthOfBuffer = 16*1024; // 16 K in our case
DmaBuffer.AlignMask = 0x00;         // aligning to 4K
if (GetSysDmaBuffer(HwCtrl,&DmaBuffer)){ // memory distribution System (Slave) DMA
     ... buffer is distributed successfully...
     ... process ...
     FreeDmaBuffer(HwCtrl,&DmaBuffer);   // freeing the buffer
}

Memory block for Bus Master DMA can be allocated with the help of the following function:

GetBusmasterDmaBuffer(HwCtrl,&DmaBuffer);// Bus master DMA Buffer Request;


Executing a user's function at high-privileged CPU level (Ring 0)

What is this?
How to work with RunRing0Function


What it this?

What is this?
Previous Top Next

Note: does not work under Windows XP 64-bit!

It is possible that you are not satisfied with the set of the functions provided with TVicHW32 and you would like to extend it. Of course you can order additional 1-2 functions for the drivers but it's not always convenient and not free. Starting from the current version 5 you can add almost anything to the drivers without changing them. New function RunRing0Functionallows you to execute your procedure at Ring 0. It means that you can use this function to run any privileged CPU instructions which were previously available only for drivers!


How to work with RunRing0Function

Note: does not work under Windows XP 64-bit!

For example now you can directly access I/O ports under Windows NT/2000:

// =====================================================
// This function is containing direct port access operation
// and we want execute it at Ring 0.
// The function returns main memory size read from CMOS
//=====================================================

ULONG __stdcall Ring0Proc(PULONG pBaseMem)
{
   USHORT BaseMem;
   __asm {

        cli // disables interrupts while interacting with CMOS
        mov dx,70h // reads least significant byte
        mov al,15h
        out dx,al
        mov dx,71h
        in  al,dx
        mov byte ptr BaseMem,al
        mov dx,70h // reads most significant byte
        mov al,16h
        out dx,al
        mov dx,71h
        in  al,dx
        mov byte ptr BaseMem+1,al
        sti   // enable interrupts
   }

  *pBaseMem = BaseMem;
  return 1; // success
}

If you try to call this function directly under Windows NT/2000 you'll get a message "Privileged instruction", but calling RunRing0Function gives you the right result:

ULONG BaseMemorySize;
RunRing0Function ( HW32, Ring0Proc, &BaseMemorySize);

We intentionally used built-in Assembler to illustrate that any CPU command can be executed. And of course we could just use _inp() and _outp() for port access.


TVicHW32 Support Routines And Structures

TVicHW32 6.0
Support Routines And Structures

Copyright(c) Victor Ishikeev 1997-2004
http://www.entechtaiwan.com/tools.htm
tools@entechtaiwan.com


OpenTVicHW32

You can use OpenTVicHW function instead of OpenTVicHW32

Loads the tvichw32.vxd virtual device driver under Windows 95/98/ME or tvichw32.sys kernel mode device driver under Windows NT/2000/XP, providing direct access to the hardware.

HANDLE OpenTVicHW32(
         HANDLE  HW32,
         char *  DriverName,
         char *  EntryPoint
       );

Parameters:

HW32 - the TVicHW32 handle, must be NULL before first call
DriverName - the driver name, must be "TVICHW32"
EntryPoint - the driver's entry point, must be "TVicDevice0" or "TVicDevice1".

Return Value:

The new TVicHW32 handle value or NULL if fails. Keep this handle opened all time when you are working with TVicHW32 functions and close by CloseTVicHW32() at end of application.

Comments:

If the driver was successfully opened, the GetActiveHW() returns True; if the function fails, the GetActiveHW() returns False.
TVicHW32 now can be used by two applications at same time. For the first application use

HW32 = OpenTVicHW32(HW32, "TVICHW32","TVicDevice0");

For second:

HW32 = OpenTVicHW32(HW32, "TVICHW32","TVicDevice1");

See also:


CloseTVicHW32

Closes the kernel-mode driver and releases memory allocated to it. If a hardware interruptions was "unmasked", the "mask" is restored.

HANDLE CloseTVicHW32 ( HANDLE HW32 );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32

Return Value :
NULL.

See also:


OpenTVicHW (new)

OpenTVicHW

Loads the TVicHW32.sys kernel mode device driver under all Windows versions, providing direct access to the hardware. You can use this function instead of OpenTVicHW32 which is more complicated.

HANDLE OpenTVicHW();

Parameters: None

Return Value:

The new TVicHW32 handle value or NULL if fails. Keep this handle opened all time when you are working with TVicHW32 functions and close by CloseTVicHW32 at end of application.

Comments:

If the driver was successfully opened, the GetActiveHW() returns True; if the function fails, the GetActiveHW() returns False.

See also:


GetActiveHW

This boolean function specifies whether the mode driver is open.

  BOOL GetActiveHW ( HANDLE HW32 );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32

Return Value :
TRUE if the driver is already open by OpenTVicHW32(), or FALSE if it is not.

Comments:
Use immediately after OpenTVicHW32() call.

See also:


MapPhysToLinear

Maps a specific physical address to a pointer in linear memory for the current process' address space. This function is intended to be used to access device-specific physical memory (for the memory-mapped devices).

ULONG MapPhysToLinear (
         HANDLE HW32,
         ULONG  PhysAddr,
         ULONG  MappedSize
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32
PhysAddr - 32-bit physical address of the start of the region to examine
MappedSize - length in bytes of the physical region. The function uses this parameter to verify that the entire range is addressable.

Return Value :
The linear address of the first byte in the specified range of physical addresses.

Comments:
1. Returns type ULONG, should be converted to pointer before using.
2. Do not forget to unmap this physical memory area by UnmapMemory when your application not need it anymore.
3. No information can be concluded about the linear addresses for physical addresses if they lie outside the range requested.

See also :
UnmapMemory


UnmapMemory

Unmaps a specific physical address previously mapped with MapPhysToLinear.

void UnmapMemory (
          HANDLE HW32,
          ULONG  PhysAddr,
          ULONG  MappedSize
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32
PhysAddr - 32-bit physical address of the start of the region previously mapped
MappedSize - length in bytes of the mapped region

Return Value :
None.

See also :
MapPhysToLinear


GetMem

Reads one byte from the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

BYTE GetMem(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.

Return Value :
One byte value from the region.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:


GetMemW

Reads two bytes (16-bit word value) from the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

BYTE GetMemW(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.

Return Value :
16-bit word value from the region.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:


GetMemL

Reads four bytes (32-bit double word value) from the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

BYTE GetMemL(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.

Return Value :
32-bit double word value from the region.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:
MapPhysToLinear UnmapMemory GetMem GetMemW SetMem SetMemW SetMemL


SetMem

Write one byte to the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

void SetMem(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset,
        BYTE   bValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.
bValue - value to write.

Return Value :
None.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:


SetMemW

Write two bytes (16-bit word value) to the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

void SetMemW(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset,
        USHORT wValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.
wValue - 16-bit word value to write.

Return Value :
None.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:


SetMemL

Write four bytes (32-bit double word value) to the memory region. Mainly is intended for using in the Visual Basic applications where the direct manipulations with the pointers is difficult.

void SetMemL(
        HANDLE HW32,
        ULONG  MappedAddress,
        ULONG  MemOffset,
        ULONG  dwValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
MappedAddress - the linear address returned by MapPhysToLinear
MemOffset - the offset value, should begin from the "0" value.
dwValue - 32-bit word value to write.

Return Value :
None.

Comments:
In general, "MappedAddress" can be any valid linear pointer to the memory. But if this pointer was received from the MapPhysToLinear function then you can access physical memory also.

See also:
MapPhysToLinear UnmapMemory GetMem GetMemW GetMemL SetMem SetMemW


SetHardAccess

Determines whether the kernel-mode driver should use "hard" or "soft" access to the I/O ports.

void SetHardAccess(
        HANDLE  HW32,
        BOOL    AccessMode
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
AcessMode - if set to TRUE "hard" access is employed; if set to FALSE "soft" access is employed.

Return Value :
None.

Comments:
"Soft" access provides higher performance access to ports, but may fail if the port(s) addressed are already in use by another kernel-mode driver. While slower, "Hard" access provides more reliable access to ports which have already been opened by another kernel-mode driver.

See also:
GetHardAccess


GetHardAccess

Check the current port I/O access mode.

BOOL GetHardAccess(
          HANDLE  HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if "Hard Mode" enabled;
FALSE - if "Soft Mode" enabled.

Comments:
"Soft" access provides higher performance access to ports, but may fail if the port(s) addressed are already in use by another kernel-mode driver. While slower, "Hard" access provides more reliable access to ports which have already been opened by another kernel-mode driver.

See also:
SetHardAccess


GetPortByte

Reads a byte from the specified port address.

BYTE GetPortByte(
        HANDLE HW32,
        ULONG  PortAddress
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space

Return Value :
The byte read from the specified port address.

See also:


GetPortWord

Reads a 16-bit word value from the specified port address.

USHORT GetPortWord(
        HANDLE HW32,
        ULONG  PortAddress
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space

Return Value :
The 16-bit word value read from the specified port address.

See also:


GetPortLong

Reads a 32-bit double word value from the specified port address.

ULONG GetPortLong(
         HANDLE HW32,
         ULONG  PortAddress
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space

Return Value :
The 32-bit double word value read from the specified port address.

See also:


SetPortByte

Writes a byte to the specified port address.

void SetPortByte(
        HANDLE  HW32,
        ULONG   PortAddress,
        UCHAR   bValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space
bValue - specifies a byte to be written to the port.

Return value :
None.

See also:
GetPortByte GetPortWord GetPortLong SetPortWord SetPortLong


SetPortWord

Writes a 16-bit word value to the specified port address.

void SetPortWord(
        HANDLE  HW32,
        ULONG   PortAddress,
        USHORT  wValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space
wValue - specifies a 16-bit word value to be written to the port.

Return value :
None.

See also:
GetPortByte GetPortWord GetPortLong SetPortByte SetPortLong


SetPortLong

Writes a 32-bit double word value to the specified port address.

void SetPortLong(
        HANDLE  HW32,
        ULONG   PortAddress,
        ULONG   dwValue
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortAddress - the port address in I/O space
dwValue - specifies a 32-bit double word value to be written to the port.

Return value :
None.

See also:


ReadPortFIFO

Reads a number of bytes from the specified port address into a buffer.

void ReadPortFIFO(
         HANDLE       HW32,
         PFIFO_RECORD pPortRec
);

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORD, which contains the specified port address, a buffer into which an array of byte values is read, and the number of bytes to be read into the buffer.

Return Value :
None.

See also:


ReadPortWFIFO

Reads a number of 16-bit words from the specified port address into a buffer.

void ReadPortWFIFO(
         HANDLE        HW32,
         PFIFO_RECORDW pPortRec
);

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORDW, which contains the specified port address, a buffer into which an array of word values is read, and the number of words to be read into the buffer.

Return Value :
None.

See also:


ReadPortLFIFO

Reads a number of 32-bit double words from the specified port address into a buffer.

void ReadPortLFIFO(
         HANDLE        HW32,
         PFIFO_RECORDL pPortRec
);

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORDL, which contains the specified port address, a buffer into which an array of double word values is read, and the number of double words to be read into the buffer.

Return Value :
None.

See also:


WritePortFIFO

Writes a number of bytes from a buffer to the specified port.

void WritePortFIFO(
          HANDLE       HW32,
          PFIFO_RECORD pPortRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORD, which contains the specified port address, a buffer from which an array of byte values is to be written, and the number of bytes to be written to the port.

Return Value :
None.

See also:


WritePortWFIFO

Writes a number of 16-bit words from a buffer to the specified port.

void WritePortWFIFO(
          HANDLE        HW32,
          PFIFO_RECORDW pPortRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORDW, which contains the specified port address, a buffer from which an array of 16-bit word values is to be written, and the number of words to be written to the port.

Return Value :
None.

See also:


WritePortLFIFO

Writes a number of 32-bit words from a buffer to the specified port.

void WritePortLFIFO(
          HANDLE        HW32,
          PFIFO_RECORDL pPortRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
pPortRec - points to the structure type of FIFO_RECORDL, which contains the specified port address, a buffer from which an array of 32-bit double word values is to be written, and the number of double words to be written to the port.

Return Value :
None.

See also:


UnmaskIRQ

Installs a hardware interrupt handler for the specified IRQ number and unmasks this IRQ at hardware level.

void UnmaskIRQ(
       HANDLE         HW32,
       USHORT         IrqNumber,
       TOnHWInterrupt InterruptHandler
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqNumber - number of the IRQ to handle (1-15);
InterruptHandler - address of the callback procedure that handles hardware interrupts for this IRQ.

Return Value :
None.

Comments:

1. The interrupt handler function must be declared as:

typedef void (__stdcall * TOnHWInterrupt)(USHORT IRQNumber);

2. This function is a subcase of more common UnmaskIRQEx.

3. TVicHW32 can not handle RTC timer (IRQ8) under Windows NT/2000/XP

4. TVicHW32 can not handle IRQ0 (system timer) under all Windows platforms.

5. TVicHW32 can not handle serial port interruptions under Windows NT/2000/XP.

See also:


UnmaskIRQEx

Installs a hardware interrupt handler for the specified IRQ number and unmasks this IRQ at hardware level. UnmaskIRQEx allows to handle the "shared" and then "level sensitive" interrupts as well as the "edge triggered".

void UnmaskIRQ(
       HANDLE         HW32,
       USHORT         IrqNumber,
       ULONG          IsIrqShared,
       TOnHWInterrupt InterruptHandler,
       pIrqClearRec   IrqRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqNumber - number of the IRQ to handle (1-15);
IsIrqShared - specifies if this IRQ shared (1) or not (0);
InterruptHandler - address of the callback procedure that handles hardware interrupts for this IRQ
IrqRec - points to the structure of type IrqClearRec , which describes how to process an interruption inside of the driver.

Return Value :
None.

Comments:
1. The interrupt handler function must be declared as:

typedef void (__stdcall * TOnHWInterrupt)(USHORT IRQNumber);

2. This function helps to handle the "level sensitive" interrupts rather than "edge triggered" ones. If the interrupt level at the bus is not dropped at the end of an interrupt handling, the system calls the interrupt handler again and again and this will cause the system to hang. By calling the UnmaskIRQEx() function you can provide the
information for how the TVicHW32 driver should clear an interruption inside of the primary interrupt handler. Note : You do not need to clear the interrupt level in your user-level interrupt handler since this was already done by the TVicHW32 driver!

See also:


MaskIRQ

Stops the interrupt processing started by UnmaskIRQ or UnmaskIRQEx by masking the specified IRQ number at hardware level.

void MaskIRQ(
       HANDLE HW32,
       USHORT IrqNumber
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqNumber - number of the IRQ (1-15);

Return Value :
None.

See also:


IsIRQMasked

Checks if the specified IRQ number is currently masked or not.

BOOL IsIRQMasked(
       HANDLE HW32,
       USHORT IrqNumber
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqNumber - number of the IRQ.

Return Value :
TRUE if masked and FALSE if not masked.

See also:


GetIRQCounter

Returns how many interruptions was processed inside of the driver.

ULONG GetIRQCounter(
         HANDLE HW32,
         USHORT IrqNumber
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqNumber - number of the IRQ (1-15);

Return Value :
Number of the interruptions processed by the driver for the specified IRQ number.

See also:


GetLPTNumPorts

Returns the number of LPT ports installed on the PC.

UCHAR GetLPTNumPorts(
         HANDLE  HW32
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
Number of the LPT ports found on the PC.

Comments:
This functions extracts all base addresses of LPTs from the BIOS memory area (0408:0000). Some new ports like PCI LPTs does not report about its resources so you should add this kind of ports to TVicHW32 manually with the help of AddNewLPT function.

See also:


GetLPTNumber

Returns the current LPT port number.

UCHAR GetLPTNumber(
         HANDLE HW32
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32.

Return Value :
Current LPT port number (1 - LPT1, 2 - LPT2 and so on).

Comments:
Almost all LPT specific TVicHW32 functions are applicable for the LPT number which is "current". So it is necessary to select a current LPT number before call any LPT specific function.

See also:


SetLPTNumber

Set the specified LPT port number as a "current".

void SetLPTNumber(
        HANDLE  HW32,
        UCHAR   LptNumber
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
LptNumber - LPT port number (1 - LPT1, 2 - LPT2 and so on) to set as a "current"

Return Value :
None.

Comments:
Almost all LPT specific functions are applicable for the LPT number which is "current". So it is necessary to set a current LPT number before call any LPT specific function.

See also:


GetLPTBasePort

Returns the base port address of current LPT port.

ULONG GetLPTBasePort(
         HANDLE HW32
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32

Return Value :
The base port address (data reg) of current LPT port.

See also:


Add New LPT

Allows to enter an address of a user "non-standard" port.

UCHAR AddNewLPT(
         HANDLE HW32,
         USHORT PortBaseAddress
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PortBaseAddress - single-precision integer value (word) indicating the base address of custom LPT port.

Return Value :
Number of added LPT port

Comments:

See also:


AcquireLPT

Allows to prevent other applications (include printing system) to use selected LPT port.

USHORT AcquireLPT(
              HANDLE  HW32,
              USHORT  LPTNumber
       );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
LPTNumber - LPT port number (1,2,...).

Return Value :
LPT_ACQUIRE_SUCCESS - the port is locked successfully;
LPT_ACQUIRE_NOT_OPENED - the TVicHW32 driver was not opened;
LPT_ACQUIRE_BAD_PORT - bad LPT number;
LPT_ACQUIRE_REFUSED - the port is already locked by another process.

Comments:
This function is applicable under Windows 95/98/ME only.

See also:


ReleaseLPT

Unlocks the specified LPT port previously locked by AcquireLPT function

void ReleaseLPT(
            HANDLE HW32,
            USHORT LPTNumber
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
LPTNumber - LPT port number (1,2,...).

Return Value :
None.

Comments:
This function is applicable under Windows 95/98/ME only.

See also:


IsLPTAcquired

Checks if the specified LPT port was locked.

USHORT IsLPTAcquired(
         HANDLE HW32,
         USHORT LPTNumber
       );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
LPTNumber - LPT port number (1,2,...).

Return Value :
LPT_ACQUIRE_SUCCESS - the port is locked successfully by our application;
LPT_ACQUIRE_NOT_OPENED - the TVicHW32 driver was not opened;
LPT_ACQUIRE_BAD_PORT - bad LPT port number;
LPT_NOT_ACQUIRED - the port was not locked.

Comments:
This function is applicable under Windows 95/98/ME only.

See also:


GetPin

Allows read an electrical level from the selected pin of current LPT port.

BOOL GetPin(
        HANDLE HW32,
        UCHAR  PinNumber
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PinNumber - the selected pin number (1...25).

Return Value :
TRUE - high electrical level detected;
FALSE - low electrical level detected.

Comments:
Not all pins are accessible for this operation. Read LPT docs or run LPT test example for more info.

See also:
SetPin


SetPin

Allows write an electrical level to the selected pin of current LPT port.

void SetPin(
        HANDLE HW32,
        UCHAR  PinNumber,
BOOL PinLevel
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
PinNumber - the selected pin number (1...25).
PinLevel - the electrical level to be set (TRUE - high level, FALSE - low level).

Return Value :
None.

Comments:
Not all pins are accessible for this operation. Read LPT docs or run LPT test example for more info.

See also:
GetPin


GetLPTAckwl

Returns the Acknowledge state of current LPT port.

BOOL GetLPTAckwl(
        HANDLE   HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if ACTIVE or FALSE - if not.

Comments:


GetLPTBusy

Returns the BUSY state of current LPT port.

BOOL GetLPTBusy(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if ACTIVE or FALSE - if not


GetLPTPaperEnd

Returns the Paper End state of current LPT port.

BOOL GetLPTPaperEnd(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if ACTIVE or FALSE - if not


GetLPTSlct

Returns the Select state of current LPT port.

BOOL GetLPTSlct(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if ACTIVE or FALSE - if not


GetLPTError

Returns the Error state of current LPT port.

BOOL GetLPTError(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
TRUE - if ACTIVE or FALSE - if not


LPTStrobe

Make the short impulse (strobe) at pin 1 of the current LPT port.

void LPTStrobe(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32

Return Value:
None


LPTAutofd

Sets current AUTOFD state of the current LPT port.

void LPTAutofd(
        HANDLE HW32,
        BOOL   Flag
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
Flag - TRUE, if ACTIVE or FALSE, if not.

Return Value :
None.


LPTInit

Make the short impulse at INIT line of the current LPT port.

void LPTInit(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
None.


LPTSlctIn

Sets SLCTIN signal to the current LPT port.

void LPTSlctIn(
        HANDLE HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
None.


LPTPrintChar

Sends one symbol to the printer using the LPT "Compatible Mode".

BOOL LPTPrintChar(
        HANDLE HW32,
        UCHAR  ch
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
ch - symbol to print.

Return Value :
TRUE if succeed. Otherwise you need repeat this operation

Comments:
This function is not for the real using, but for the illustration only.


ForceLPTIrq

Forces a LPT device to generate an interruptions when ACK line (Pin 10) has been triggered by an external electrical level. The application must call this function to handle the LPT IRQ after using the UnmaskIRQ or UnmaskIRQEx.

void ForceLPTIrq(
          HANDLE HW32,
          BOOL   IrqEnable
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IrqEnable - TRUE to enable LPT IRQ or FALSE to disable.

Return Value :
None.

See also:


SetLPTReadMode

Switches current LPT port to "Read" mode to read the data from pin 2-9 through the data register.

void SetLPTReadMode(
        HANDLE HW32
       );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32.

Return Value :
None.

Comments:
1. The current LPT port should be "bi-directional" and configured as PS/2 compatible or as ECP.
2. You must switch the port back to "Write" mode before write the data.

See also:
SetLPTWriteMode


SetLPTWriteMode

Switches current LPT port back to the standard "Write" mode to write data to the pins 2-9 through the data register.

void SetLPTWriteMode(
        HANDLE  HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
None.

Comments:
You must switch the port to "Read" mode before read the data.

See also:
SetLPTReadMode


GetHDDInfo

Allows access to IDE HDDs hardware manufacturer information (HD serial number, geometry, etc.)

void GetHDDInfo(
        HANDLE    HW32,
        USHORT    IdeNumber,
        USHORT    Master,
        HDDInfo * Info
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
IdeNumber - the selected IDE controller, should be 1..4;
Master - should be 1 for "Master disk" or "0" for the "Slave disk";
Info - points to the structure of type HDDInfo, which contains a requested information.

Return Value :
None.


GetLastPciBus

Returns the last PCI bus number on your PC.

USHORT GetLastPciBus(
          HANDLE HW32
       );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value:
Last PCI bus number begin from 0 value.

See also:


GetHardwareMechanism

Returns a hardware PCI mechanism used on your PC.

USHORT GetHardwareMechanism(
          HANDLE HW32
       );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;

Return Value :
The hardware PCI mechanism, 1 or 2.

See also:


GetPciDeviceInfo

Returns a PCI device info for given bus number, device number and function number.

BOOL GetPciDeviceInfo(
        HANDLE HW32,
        USHORT BusNum,
        USHORT DeviceNum,
        USHORT FuncNum,
        PCI_COMMON_CONFIG * PciConfig
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
BusNum - PCI bus number (0..GetLastPciBus);
Device - PCI device on bus (0..31);
FuncNum - function number of device (0..7);
PciConfig - points to the requested information

Return Value :
TRUE, if the device exists or FALSE if not.

See also:


GetPciHeader

Reads data from the header of the device's PCI configuration space into the supplied PciConfig structure.

BOOL GetPciHeader(
        HANDLE      HW32,
        USHORT      VendorId,
        USHORT      DeviceId,
        USHORT      StartOffset,
        USHORT      Count,
        PCI_COMMON_CONFIG * PciConfig
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32
DeviceId - PCI device ID of the device
StartOffset - zero based offset, in bytes, from the start of the configuration space where the read operation is to begin; applicable for both device configuration space and for PciConfig structure.
Count - number of bytes to transfer.
PciConfig - points to the requested information

Return Value :
TRUE, if the device exists or FALSE if not.

See also:
SetPciHeader, GetPciDeviceInfo


SetPciHeader

GetPciHeader

Writes data to the header of the device's PCI configuration space from the supplied buffer.

BOOL GetPciHeader(
        HANDLE   HW32,
        USHORT   VendorId,
        USHORT   DeviceId,
        USHORT   StartOffset,
        USHORT   Count,
        PCI_COMMON_CONFIG * PciConfig
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32
VendorId - PCI vendor ID of the device
DeviceId - PCI device ID of the device
StartOffset - zero based offset, in bytes, from the start of the configuration space where the read operation is to begin; applicable for both device configuration space and for PciConfig structure.
Count - number of bytes to transfer.
PciConfig - points to the source information

Return Value :
TRUE, if the device exists or FALSE if not.

See also:
GetPciHeader, GetPciDeviceInfo


PutScanCode

Not supported for Windows XP 64-bit!

Sends one keyboard scan code directly to the keyboard controller.

void PutScanCode(
        HANDLE HW32,
        UCHAR  scode
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
scode - scan code to send.

Return Value :
None.

Comments:
Do not forget to send a "Key Up code" after sending the "Key Down code"!
KeyUpCode = KeyDownCode | 0x80;


HookKeyboard

Not supported for Windows XP 64-bit!

This functions allows to install a "system wide" keyboard hook procedure and to catch all keystrokes. See keyboard test example for more info.

void HookKeyboard(
         HANDLE HW32,
         TKbHookHandler KbdHandler
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
KbdHandler - keyboard hook procedure.

Return Value :
None.

Comments:

1. The keyboard hook procedure must be declared as:

typedef void (__stdcall * TKbHookHandler)(UCHAR ScanCode);

2. Only one hook can be installed with TVicHW32.

See also:
UnhookKeyboard


UnhookKeyboard

Not supported for Windows XP 64-bit!

Uninstalls a keyboard hook procedure installed by HookKeyboard().

void UnhookKeyboard(
           HANDLE  HW32
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32.

Return Value :
None.

See also:
HookKeyboard


RunRing0Function

Not supported for Windows XP 64-bit!

Allows to execute the user-level function at high-privileged CPU level (Ring 0). The user-level function can perform direct port I/O operations, read the contents of CPU control registers such as CR0,CR2 and more.

ULONG RunRing0Function(
         HANDLE         HW32,
         TRing0Function R0Func,
         PVOID          pParm
      );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
R0Func - points to the user-level function to be executed at Ring 0 CPU;
pParm - pointer passed to R0Func as a parameter.

Return Value :
The ULONG value returned by R0Func.

Comments:
The R0Func must be declared as:

typedef ULONG (__stdcall * TKbHookHandler)(PVOID pParm);

See R0Test example for more details.


GetSysDmaBuffer

Allows to allocate buffer for system (slave) DMA operation inside of first 16 MegaBytes area.

BOOL GetSysDmaBuffer(
        HANDLE HW32,
        DMA_BUFFER_REQUEST * DmaRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
DmaRec - points to the structure of type DMA_BUFFER_REQUEST.

Return Value:
TRUE, if succeed, FALSE - if not.

Comments:
Enable "15-16 Mb Memory Hole" in BIOS Setup program.
Do not forget free DMA buffer later! Keep and do not change DmaReq structure for the FreeDmaBuffer!

See also:


GetBusmasterDmaBuffer

Allows to allocate buffer for bus master DMA (usually for PCI devices).

BOOL GetBusmasterDmaBuffer (
        HANDLE HW32,
        DMA_BUFFER_REQUEST * DmaRec
     );

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
DmaRec - points to the structure of type DMA_BUFFER_REQUEST.

Return Value:
TRUE, if succeed, FALSE - if not.

Comments:
Do not forget free DMA buffer later! Keep and do not change DmaRec structure for the FreeDmaBuffer!

See also:


FreeDmaBuffer

Free a DMA buffer previously allocated by the GetSysDmaBuffer or GetBusmasterDmaBuffer functions.

void GetBusmasterDmaBuffer (
        HANDLE HW32,
        DMA_BUFFER_REQUEST * DmaRec
);

Parameters:
HW32 - the handle returned by a successful call to OpenTVicHW32 ;
DmaRec - points to the structure of type DMA_BUFFER_REQUEST.

Return Value:
None.

See also:


FIFO_RECORD

typedef struct _FIFO_RECORD {

  ULONG PortAddr; // the specified port address
  ULONG NumPorts; // number of bytes to be read into the buffer from
                  // or to be written to the specified port address
  UCHAR Buf[1];   // the buffer

} FIFO_RECORD, * PFIFO_RECORD;


FIFO_RECORDW

typedef struct _FIFO_RECORDW {

  ULONG PortAddr;   // the specified port address
  ULONG NumPorts;   // number of words to be read into the buffer from
                    // or to be written to the specified port address
  WORD  Buf[1];     // the buffer

} FIFO_RECORDW, *PFIFO_RECORDW;


FIFO_RECORDL

typedef struct _FIFO_RECORDL {

  ULONG  PortAddr; // the specified port address
  ULONG  NumPorts; // number of double words to be read into the buffer from
                   // or to be written to the specified port address
  ULONG  Buf[1];   // the buffer

} FIFO_RECORDL, *PFIFO_RECORDL;


IrqClearRec

typedef struct _IrqClearRec {

  UCHAR ClearIrq;        // 1 - Irq must be cleared, 0 - not
  UCHAR TypeOfRegister;  // 0 - memory-mapped register, 1 - port
  UCHAR WideOfRegister;  // wide of register: 1-Byte,2-Word,4-Double Word
  UCHAR ReadOrWrite;     // 0 - read register to clear Irq, 1 - write
  ULONG RegBaseAddress;  // register base address
  ULONG RegOffset;       // register offset
  ULONG ValueToWrite;    // value to write (if ReadOrWrite=1)

} IrqClearRec, * pIrqClearRec;


PCI_COMMON_CONFIG

This structure describes the PCI configuration space for PCI devices. All PCI devices have a common set of registers that include VendorID, DeviceID, and so on. This structure differs for PCI devices of header type 0 for devices, of header type 1 for PCI-PCI bridges, and of header type 2 for PCI-CardBus bridges. For more information, see the PCI Local Bus Specification, revision 2.1 or 2.2.

typedef struct _PCI_COMMON_CONFIG {
    USHORT  VendorID;
    USHORT  DeviceID;
    USHORT  Command;
    USHORT  Status;
    UCHAR   RevisionID;
    UCHAR   ProgIf;
    UCHAR   SubClass;
    UCHAR   BaseClass;
    UCHAR   CacheLineSize;
    UCHAR   LatencyTimer;
    UCHAR   HeaderType;
    UCHAR   BIST;

    union {
        struct _PCI_HEADER_TYPE_0 {
            ULONG   BaseAddresses[PCI_TYPE0_ADDRESSES];
            ULONG   CIS;
            USHORT  SubVendorID;
            USHORT  SubSystemID;
            ULONG   ROMBaseAddress;
            ULONG   Reserved2[2];

            UCHAR   InterruptLine;
            UCHAR   InterruptPin;
            UCHAR   MinimumGrant;
            UCHAR   MaximumLatency;
        } type0;

        struct _PCI_HEADER_TYPE_1 {
            ULONG   BaseAddresses[PCI_TYPE1_ADDRESSES];
            UCHAR   PrimaryBusNumber;
            UCHAR   SecondaryBusNumber;
            UCHAR   SubordinateBusNumber;
            UCHAR   SecondaryLatencyTimer;
            UCHAR   IOBase;
            UCHAR   IOLimit;
            USHORT  SecondaryStatus;
            USHORT  MemoryBase;
            USHORT  MemoryLimit;
            USHORT  PrefetchableMemoryBase;
            USHORT  PrefetchableMemoryLimit;
            ULONG   PrefetchableMemoryBaseUpper32;
            ULONG   PrefetchableMemoryLimitUpper32;
            USHORT  IOBaseUpper;
            USHORT  IOLimitUpper;
            ULONG   Reserved2;
            ULONG   ExpansionROMBase;
            UCHAR   InterruptLine;
            UCHAR   InterruptPin;
            USHORT  BridgeControl;
        } type1;

        struct _PCI_HEADER_TYPE_2 {
            ULONG   BaseAddress;
            UCHAR   CapabilitiesPtr;
            UCHAR   Reserved2;
            USHORT  SecondaryStatus;
            UCHAR   PrimaryBusNumber;
            UCHAR   CardbusBusNumber;
            UCHAR   SubordinateBusNumber;
            UCHAR   CardbusLatencyTimer;
            ULONG   MemoryBase0;
            ULONG   MemoryLimit0;
            ULONG   MemoryBase1;
            ULONG   MemoryLimit1;
            USHORT  IOBase0_LO;
            USHORT  IOBase0_HI;
            USHORT  IOLimit0_LO;
            USHORT  IOLimit0_HI;
            USHORT  IOBase1_LO;
            USHORT  IOBase1_HI;
            USHORT  IOLimit1_LO;
            USHORT  IOLimit1_HI;
            UCHAR   InterruptLine;
            UCHAR   InterruptPin;
            USHORT  BridgeControl;
            USHORT  SubVendorID;
            USHORT  SubSystemID;
            ULONG   LegacyBaseAddress;
            UCHAR   Reserved3[56];
            ULONG   SystemControl;
            UCHAR   MultiMediaControl;
            UCHAR   GeneralStatus;
            UCHAR   Reserved4[2];
            UCHAR   GPIO0Control;
            UCHAR   GPIO1Control;
            UCHAR   GPIO2Control;
            UCHAR   GPIO3Control;
            ULONG   IRQMuxRouting;
            UCHAR   RetryStatus;
            UCHAR   CardControl;
            UCHAR   DeviceControl;
            UCHAR   Diagnostic;
        } type2;

    } u;

    UCHAR   DeviceSpecific[108];

} PCI_COMMON_CONFIG , *PPCI_COMMON_CONFIG;

Members

VendorID
PCI vendor identifier register.
DeviceID
PCI device identifier register.
Command
PCI command register.
Status
PCI status register.
RevisionID
PCI revision identifier register.
ProgIf
PCI programming interface register.
SubClass
PCI device sub-class register.
BaseClass
PCI device base-class register.
CacheLineSize
PCI cache line size register.
LatencyTimer
PCI latency timer register.
HeaderType
PCI header type register. 0 indicates a normal PCI device, 1 indicates a PCI-PCI bridge, and 2 indicates a PCI-CardBus bridge.
BIST
PCI built-in self test register.
BaseAddresses
Array of PCI base address registers. Normal PCI devices have 6 base address registers, while PCI-PCI bridges have 2 and PCI-CardBus bridges have 1.
CIS
CardBus CIS pointer register.
SubVendorID
PCI subsystem vendor identifier register.
SubSystemID
PCI subsystem identifier register.
ROMBaseAddress
PCI ROM base address register.
Reserved2, Reserved3, Reserved4
Reserved.
InterruptLine
PCI interrupt line register.
InterruptPin
PCI interrupt pin register.
MinimumGrant
PCI minimum grant register.
MaximumLatency
PCI maximum latency register.
BaseAddress
PCI base address register.
PrimaryBusNumber
PCI primary bus number register.
SecondaryBusNumber
PCI secondary bus number register.
SubordinateBusNumber
PCI subordinate bus number.
SecondaryLatencyTimer
PCI secondary latency timer.
IOBase
Lower 8 bits of PCI I/O base address register.
IOLimit
Lower 8 bits of PCI I/O limit address register.
SecondaryStatus
PCI secondary status register.
MemoryBase
PCI memory base address register.
MemoryLimit
PCI memory limit address register
PrefetchableMemoryBase
Lower 16 bits of PCI prefetchable memory base address register.
PrefetchableMemoryLimit
Lower 16 bits of PCI prefetchable memory limit address register.
PrefetchableMemoryBaseUpper32
Upper 32 bits of PCI prefetchable memory base address register.
PrefetchableMemoryLimitUpper32
Upper 32 bits of PCI prefetchable memory limit address register.
IOBaseUpper
Upper 16 bits of PCI I/O base address register.
IOLimitUpper
Upper 16 bits of PCI I/O limit address register.
ExpansionROMBase
PCI expansion ROM base address register.
BridgeControl
PCI bridge control register.
CapabilitiesPtr
PCI capabilities pointer register.
SecondaryStatus
PCI secondary status register.
CardbusBusNumber
CardBus bus number register.
CardbusLatencyTimer
CardBus latency timer register.
MemoryBase0
CardBus memory base address register 0.
MemoryLimit0
CardBus memory limit address register 0.
MemoryBase1
CardBus memory base address register 1.
MemoryLimit1
CardBus memory limit address register 1.
IOBase0_LO
Lower 16 bits of CardBus I/O base address register 0.
IOBase0_HI
Upper 16 bits of CardBus I/O base address register 0.
IOLimit0_LO
Lower 16 bits of CardBus I/O limit address register 0.
IOLimit0_HI
Upper 16 bits of CardBus I/O limit address register 0.
IOBase1_LO
Lower 16 bits of CardBus I/O base address register 1.
IOBase1_HI
Upper 16 bits of CardBus I/O base address register 1.
IOLimit1_LO
Lower 16 bits of CardBus I/O limit address register 1.
IOLimit1_HI
Upper 16 bits of CardBus I/O limit address register 1.
LegacyBaseAddress
CardBus legacy base address register.
SystemControl
CardBus system control register.
MultiMediaControl
CardBus multimedia control register.
GeneralStatus
CardBus general status register.
GPIO0Control, GPIO1Control, GPIO2Control, GPIO3Control
CardBus GPIO control registers
IRQMuxRouting
CardBus IRQ multiplexer routing register.
RetryStatus
CardBus retry status register.
CardControl
CardBus card control register.
DeviceControl
CardBus device control register.
Diagnostic
CardBus diagnostic register.
DeviceSpecific
Device specific registers in the PCI configuration space, varies by device.


HDDInfo

All fields of this structure is self-documented and not need to be described.

typedef struct _HDDInfo {

  DWORD BufferSize;
  DWORD DoubleTransfer;
  DWORD ControllerType;
  DWORD ECCMode;
  DWORD SectorsPerInterrupt;
  DWORD Cylinders;
  DWORD Heads;
  DWORD SectorsPerTrack;
  char  Model[41];
  char  SerialNumber[21];
  char  Revision[9];

} HDDInfo, * pHDDInfo;


DMA_BUFFER_REQUEST

typedef struct _DMA_BUFFER_REQUEST {

  ULONG LengthOfBuffer;   // legth of the buffer in bytes
  ULONG AlignMask;        // alignment boundary:
                          // 0x00 - 4K
                          // 0x01 - 8K
                          // 0x03 - 16K
                          // 0x07 - 32K
                          // 0x0F - 64K
                          // 0x1F - 128K
  ULONG PhysDmaAddress;   // returned physical address of the buffer
  PVOID LinDmaAddress;    // returned linear address of the buffer
  ULONG PMemHandle;       // driver's internal value - keep it!
  ULONG KernelDmaAddress; // driver's internal value - keep it!

} DMA_BUFFER_REQUEST, * PDMA_BUFFER_REQUEST;


TVicHW32 F.A.Q.

TVicHW32 Frequently Asked Questions (F.A.Q)
Previous Top Next

NOTE: Please check this FAQ and the TVicHW32 Home Page, before requesting support by email. If you don't find an answer here or on the Home Page, then by all means send me your question(s). I add the interesting or frequently asked to this document.

What is included in the TVicHW32 package?

What is the difference between the various licenses?

Is my TVicHW32-based application limited to my current operating system?

My application cannot open TVicHW32 on Windows NT/2000/XP if the user is not an administrator. What's the solution?

What programming languages does TVicHW32 support?

I'm a Delphi programmer. Which is better to use in my application -TVicHW32.DLL or TVicHW32 VCL component?

I need TVicHW32 or a similar device driver to work with I/O ports under Windows NT. What advantage is TVicHW32 under Windows 95/98/ME where I can reach all ports directly from my application?

What's the difference between the "hard" and "soft" port I/O access modes?

How fast is access to the hardware registers with TVicHW32?

What's the maximum interrupt frequency handled by TVicHW32?

How do I increase the interrupt frequency?

Is it possible to handle interrupts from the system or from the RTC timer?

When do I need to write a custom device driver instead of using TVicHW32?

How do I use TVicHW32 for serial communications through the COM port?

Why does my PC hang when I try to unmask interrupts from my PCI card?

How do I protect my software against illegal copying with GetHDDInfo() function?

How do I make calls to the DOS/BIOS functions?

How do I control hardware connected to LPT?

I've purchased TVicHW32 but my application and/or device still does not work! What do I do?

My application does not work with TVicHW32. Can I send you my project to find where is my mistake?


What is included in the TVicHW32 package?

TVicHW32 demo version is fully functional so you can write and debug your application before you buy a license to use or distribute the driver.

TVicHW32 licensed version has only one difference: it includes the drivers tvichw32.vxd for Windows 95/98/ME and tvichw32.sys for Windows NT/2000 without nag screens.

Users who have purchased the TVicHW32 Commercial License in additional receive the TVicHW32.DLL source code written in MSVC++ 6.0.

Driver source code is not available for any kind of license!


What is the difference between the various licenses?

Single License: Once registered, you are granted a non-exclusive license to use TVicHW32 on one computer at a time, for any legal purpose. The registration fee is $99 U.S. Purchase online.

Commercial License: You are granted the license to distribute TVicHW32 drivers and DLL's as part of your software without having to pay royalties. Optionally
includes your own custom driver/dll names. In additional we can include the "time critical" code to the driver's body (one additional function or an interrupt handler). The registration fee is $297 U.S. Purchase online.

Site License: For teams of developers. The cost of this license depends on how many are using the software. Please contact us for the specific price.


Is my TVicHW32-based application limited to my current operating system?

No. With TVicHW32, the application you write works on all versions of Windows (95/98/ME/NT/2000/XP) without modification


My application cannot open TVicHW32 on Windows NT/2000 if the user is not an administrator. What's the solution?

My application cannot open TVicHW32 on Windows NT/2000/XP if the user is not an administrator. What's the solution?
Previous Top Next

After registration we provide special *.inf files to reinstall TVicHW32. After rebooting your PC you can log on to NT/2000/XP as a user without any privileges.

Note: you must be logged on as an Administrator to install TVicHW32!


What programming languages does TVicHW32 support?

We have tested TVicHW32 with the following programming systems:

· Microsoft Visual C++ 6.0, 7.0
· Microsoft Visual Basic 6.0
· Borland Delphi versions 2 to 7
· Borland C++ Builder versions 1, 3..6
· Microsoft Visual C#
· Microsoft Visual Basic .Net

In general, you can use TVicHW32 with any programming language if it allows calls to DLL functions. I know that TVicHW32 can be used with Borland Power Builder and with Forth but please don't ask me how! :-)


I'm a Delphi programmer. Which is better to use in my application-TVicHW32.DLL or TVicHW32.VCL?

The VCL component is just a convenient wrapper around a DLL so using the DLL directly achieves a little better performance. It's mainly a matter of your convenience or habit as a programmer.


I need TVicHW32 or a similar device driver to work with I/O ports under Windows NT. What advantage is TVicHW32 under Windows 95/98/ME where I can reach all ports directly from my application?

I need TVicHW32 or a similar device driver to work with I\O ports under Windows NT. What advantage is TVicHW32 under Windows 95\98\ME where I can reach all ports directly from my application?
Previous Top Next

It is almost true that you can reach all ports under Windows 95/98/ME. Windows is a multitasking system where any device can be used by more than one device concurrently, so Windows has a way to protect devices from getting more than one instruction at the same time. To control access to I/O addresses Windows 9X uses a bit-mapped list of ports called an I/O Permission Map (IOPM). A 1 bit on this list means "access denied" and a 0 bit means "access granted". It is no problem to access a port from a Win32 application if an access is granted in the IOPM, but it is not simple if access is denied.

The drivers (VxD's) call a system service to trap a particular port and register a callback function, called a "port trap handler". The system responds by setting the port's byte in the IOPM. When a Win32 application accesses that port and causes a fault, the system fault handler calls the VxD's registered port trap handler. This port trap handler can do anything in response to the I/O access from a Win32 application: the VxD may ignore the instruction, may execute the instruction or may substitute a value instead of the one you are sending!

Windows 9x and its component VxD's trap almost all standard PC I/O addresses but never traps non-standard I/O addresses. So it is necessary to be careful if you are working with the standard system devices. On other hand, the system cannot trap the I/O access from another VxD and this is why you need a device driver for reliable access to the ports under Windows 95/98/ME.


What's the difference between the <hard> and <soft> port I/O access modes?

What's the difference between the "hard" and "soft" port I\O access modes?
Previous Top Next

"Soft" mode provides a higher performance access to ports, but the access may fail if the ports addressed are already in use by another driver (see preceding). "Hard" access provides a more reliable access to ports but it is slower due to its increased overhead for the DeviceIoControl() API calls.


How fast is access to the hardware registers with TVicHW32?

Access to the memory-mapped registers is as fast as possible because it works with memory via Windows' usual pointers directly.

For port I/O access I recorded the following results on a P II 450MHz system:

· single port read operation in Hard mode - 5.85 µsec
· single port read operation in Soft mode - 2.04 µsec
· direct port access called through the RunRing0Function - 1.51 µsec
· reading of array of values from a port with ReadPortFIFO - 1.22 µsec


What's the maximum interrupt frequency handled by TVicHW32?

TVicHW32 runs perfectly up to 10 KHz on a 450 MHz Pentium II. For very stable results we recommend TVicHW32 be used with interrupt periods not less than 10 milliseconds. TVicHW32 handles all interrupts at higher frequencies, but it starts to influence the delays that occur when interrupts are delivered to the application level. This is possible only when Windows makes TVicHW32's thread active. For TVicHW32 to have this indirect delay effect its priority class must be REALTIME_PRIORITY_CLASS and its thread priority set at THREAD_PRIORITY_TIME_CRITICAL. In this extreme case we start to have problems with the keyboard and mouse which can even be blocked.


How do I increase the interrupt frequency?

The only reliable way is to move your interrupt handler to the driver. I can do this for you if you have purchased the TVicHW32 Commercial License. This license also lets you order a custom device driver.


Is it possible to handle interrupts from the system or from the RTC timer?

No, this is not possible. The system timer (IRQ 0) is used by the system for system scheduling and cannot be used for any other purpose. Also, under Windows NT/2000 we cannot use the RTC timer (IRQ 9).
In general, precision timing under Windows is an unsolvable problem because Windows was not developed as a real-time system. Developers requiring high precision timers can call the Win32 API function timeSetEvent() , which is accurate to 1 milliseconds (ms).
However, in Windows' multi-threaded environment, this accuracy is not reliable when other high-priority threads are demanding processor time.
If you need to measure a time-critical algorithm then do not use the GetTickCount() function. Instead, use the Win32 API functions QueryPerformanceCounter() and QueryPerformanceFrequency() .


When do I need to write a custom device driver instead of using TVicHW32?

If TVicHW32 cannot help you solve your problem, I can write a driver for you and send you its source code. E-mail me to get the price which depends on your
particular needs and delivery time.


How do I use TVicHW32 for serial communications through the COM port?

TVicHW32 is not recommend for serial communications. There are much easier and cheaper ways to do the same job with the standard API calls. Just open the Win32 help file and search for "communications".
You can also use MSCOMM32 OCX or you can find many shareware or even freeware libraries and components on the Internet.

Note: TVicHW32 can not handle serial port interruptions under Windows NT/2000/XP!


Why does my PC hang when I try to unmask interrupts from my PCI card?

There are two possible reasons:

The interrupt frequency is set too high. You can reduce this frequency or tweak your interrupt handler to work faster. Also see above.

Your device generates "level sensitive" interrupts rather than "edge triggered" ones. If the interrupt level at the bus is not dropped at the end of an interrupt handling, the system calls the interrupt handler again and again and this will cause the system to hang. To prevent this situation use the UnmaskIRQEx() function to install an interrupt handler instead of UnmaskIrq() . By calling this new function you can provide the information for how the TVicHW32 driver should clear an interruption inside of the primary interrupt handler.

Note : You do not need to clear the interrupt level in your interrupt handler since this was already done by the TVicHW32 driver!


How do I protect my software against illegal copying with GetHDDInfo() function?

We do not recommend this because it causes problems for the end user:

· users can not upgrade their PC hardware.
· users can not move your program to another PC owned by the same user (home/office/notebook).
· These methods work for IDE HDD only and do not work for SCSI disks
· protection methods are very easily cracked.


How do I make calls to the DOS/BIOS functions?

How do I make calls to the DOS\BIOS functions?
Previous Top Next

Unfortunately TVicHW32 cannot help you. The problem is that Windows NT/2000/XP has no kernel or user level functions to do this in any documented way. Windows NT was initially developed for many types of CPUs, not just Intel's, so we cannot make any recommendations about the BIOS or DOS.


How do I control hardware connected to LPT?

TVicHW32 includes a lot of standard functions to work with the LPT port.
Visit www.lvr.com/parport.htm for their very useful tips and information, books, FAQs, links, software tools, etc.
Also take a look at our new TVicLPT tool at our web site.


I've purchased TVicHW32 but my application and/or device still does not work! What do I do?

I've purchased TVicHW32 but my application and\or device still does not work! What do I do?
Previous Top Next

TVicHW32 is a tool for accessing hardware and, like any tool, it does not do the job for one. One does the job with the help of the tool. In other words, to use any tool expertly, one needs to know what he or she is doing with it. It is possible that we can suggest something to help you but in most cases the solution is really that you learn more about the hardware you are accessing, especially if you are working with "non-standard" devices.


My application does not work with TVicHW32. Can I send you my project to find where is my mistake?
Previous Top

No! Please do not.
We don't have enough free time even to become acquainted with your project before attempting to debug it. See if you can narrow down the exact area that's causing the problem and include several source code lines in an e-mail and we'll try to help if possible.