From: smuegge@netcom.com (Shad Muegge)
Subject: Com Fix on HP95LX
Summary: Explaination of the bug in HP95LX serial port.
Keywords: HP95LX COM UART
Organization: Netcom - Online Communication Services  (408 241-9760 guest) 
Date: Tue, 6 Oct 1992 13:27:04 GMT

 
        USING THE HP 95LX WITH SERIAL PORT INTERRUPTS
 
                     October 1, 1992
 
Introduction
------------
 
Use of this document requires working knowledge of the 8250 family
of UART chips as well as knowledge of IBM PC assembly language
programmming.  8250 abbreviations used are:
 
        THRE    transmitter holding register empty
        LSR     line status register
        IER     interrupt enable register
        IIR     interrupt identification register
 
Background
----------
 
The HP 95LX contains a chip called the "Hopper" chip which
integrates numerous PC functions, one of which is an 8250 compatible
serial port (UART).  The 8250 function has two known flaws:
 
1) If the THRE interrupt is continuously enabled (in the IER), the
   95LX will hang as soon as the first interrupt occurs following
   transmission of a character.  Even if the interrupt is not
   continuously enabled, transmitted characters may be lost due to
   false THRE indications in the IIR.
 
2) Received characters may be duplicated when using the data
   available interrupt, especially at slow data rates (<2400).  This
   is also due to false indications in the IIR.
 
Note that programs that do not use interrupts are not affected by
these flaws.
 
Workarounds
-----------
 
There are simple software workarounds for these problems.  These
will be described at the assembly language communications driver
level.  The assembly language examples use A86 notation where a hex
operand is preceded by a zero.
 
Transmit Fix
------------
 
The transmit problem is overcome by enabling the THRE interrupt at
the time a character is sent, then disabling it as soon as the
interrupt occurs.  However, the LSR must first be checked to ensure
presence of the THRE condition, since false indications are
possible.  Here are the code fragments:
 
        ; send character in al (THRE interrupt is initially disabled)
 
                push    ax              ; save the character
                mov     dx,03f9         ; IER port
                mov     al,0f           ; enable all UART interrupts
                out     dx,al
                mov     dx,03f8         ; data port
                pop     ax
                out     dx,al           ; send the character
 
        ; interrupt service routine (after the IIR has indicated a
        ; THRE interrupt)
 
                mov     dx,03fd         ; LSR port
                in      al,dx           ; read line status
                test    al,020          ; if really THRE
                jz      read_iir_again  ; no, false indication
                mov     dx,03f9         ; IER port
                mov     al,0d           ; disable THRE interrupt
                out     dx,al
 
Receive fix
-----------
 
The duplicated character problem is solved by simply checking the
LSR to ensure that a character has actually been received:
 
                mov     dx,03fd         ; LSR port
                in      al,dx           ; read line status
                test    al,1            ; if data really available
                jz      read_id_again   ; no, false indication
                mov     dx,03f8         ; data port
                in      al,dx           ; read the character
 
One More Problem
----------------
 
There is an additional problem involving the 95LX serial port.  At
the time of this writing, the cause is not known (whether hardware
or software):
 
If an external program that uses the THRE interrupt is run while
FILER is open, the serial port will be unusable by internal
applications (FILER, COMM) after the program exits.
 
The only known workaround to this is to close and reopen FILER
before running an internal application that uses the serial port.
 
 
Fred P. Brucker
Author of {COMMO}
CompuServe ID: 71021,356
 

Newsgroups: comp.sys.palmtops