Skip to main content.

LPTTCL ver. 3.0

To overcome some of the limitations of LPTTCL v.1.0, a new wrapper has been added to the Inpout32.dll available at Logix4U [4].

This new low-level access library allows you to avoid any installation and uninstall (a great advantage!!) and offers better compatibility on WinXP and on all machines (as we were reported that some desktops did not work properly with rev 1.0). In addition:

Please notice that the new LPT selection mode and the removed requirement for installation allow you to simply copy a few files with a wrapped executable, and you have a perfectly transportable Tcl application with LPT access. We do this with TclKit and Freewrap all the time.

Installation can be as follows: keep both DLLs in your working directory, or copy them on the system32 folder.

Consider that the extension is just released, so please report any issues you may find. In particular, we could not verify proper access with a PCI card; these LPT cards typically require a high base address ( > 1024).

LPTTCL ver. 1.0

There are still reasons to keep the old LPTTCL around: access is a faster, and may be interesting for slower hosts; also for Windows 98 it does not require installation.

A brief summary of its characteristics:

Users have reported that it works correctly under Windows XP, but on some hosts it fails; we could not identify the reason, but in any case the new 3.0 version works fine for the same users.

Commands summary

both versions

lpt_getbareturns base address of selected LPT
lpt_setba <addr>selects LPT at base address <addr>
lpt_rddatareturns LPT data register value
lpt_rdstatreturns LPT status register value
lpt_rdctrlreturns LPT control register value
lpt_wrdata <val>writes <val> to LPT data register
lpt_wrstat <val>writes <val> to LPT status register
lpt_wrctrl <val>writes <val> to LPT control register

only in version 3.0

lpt_rdreg <offset>generic register read at (base_address + offset)
lpt_wrreg <offset> <val>generic register write at (base_address + offset)
lpt_setport <id>selects LPT<id>, where <id> = 1,2,3,...;
lpt_getportreturns 1,2,....

Notes:

Basic startup code

 console show
 wm withdraw .
 load lpttcl

 set ver [package require lpttcl]

 puts [format "LPTTCL, version %s" $ver]
 puts         "---------------------"
 puts [format "Current port: LPT%d" [lpt_getport]]
 puts [format "Base address: 0x%08X" [lpt_getba]]
 puts " "

 puts [format "Data    register:          0x%02X" [lpt_rdreg 0]]
 puts [format "Status  register:          0x%02X" [lpt_rdreg 1]]
 puts [format "Control register:          0x%02X" [lpt_rdreg 2]]
 puts [format "Extended control register: 0x%02X" [lpt_rdreg 0x402]]

and its output on a console:

 
 LPTTCL, version 3.0
 ---------------------
 Current port: LPT1
 Base address: 0x00000378

 Data    register:          0xAA
 Status  register:          0x78
 Control register:          0x0C
 Extended control register: 0x15

Utilities

Note that in ver. 3.0 you can now perform a quick autoscan of available LPT ports:

   proc LPTscan {{nmax 8}} {
    for {set i 1} {$i < $nmax} {incr i} {
      lpt_setport $i
      if {[lpt_getba] == -1} {
         puts "LPT$i absent"
         } else {
         puts "LPT$i present"
         }
    }
  }

We made some profiling of access speed (when you insert real code in the loop, it goes slower); note that the test is compatible with both versions.

  proc toggle {num} {
  for {set i 0} {$i < $num} {incr i} {
      lpt_wrdata 0x55
      lpt_wrdata 0xAA
      }
  }

  proc getmaxfreq {{ntimes 10000}} {
    set tt [time {toggle $ntimes}]
    scan $tt %i tt
    set mf [expr (2000 * $ntimes / $tt)] ;# 2 writes, expressed in kHz
    puts "Max frequency is $mf kHz"
  }

Some results (using freewrap 5.4, based on Tcl/tk 8.3.5) using getmaxfreq:

The old version runs faster (around 2,5 times faster on some PCs!!); furthermore, newer tcl versions are slower. As an example, we measured that 8.3.5 (freewrap) is about 20% faster than 8.4.7 (activestate).