Metropoli BBS
VIEWER: chkrx.s MODE: TEXT (ASCII)
******************************************************************
** CHKRX  
**
** -Sample program that checks RX pin of serial port
**  I show all the UART status bits on these annunciators:
**
**  LowBat      bRX     ( rx pin high, i hope )
**  RightShift  bRBZ    ( receiver busy )
**  LeftShift   bRBF    ( receive buffer full )
**  Alpha       bRER    ( receive error??? )
**  IO                  ( last 0 was a one->zero transition )
**
** - press ON (ATTN) to exit
** 
**  INPUT:   none
**
**  OUTPUT:  1: zeroes%     ( number of zeroes on RX )
**      - this number refers to how many one->zero transitions occurred
**
**
** COMMENTS:  try typing quickly to watch the error (alpha) come on
**            is you run this with normal serial IO, the RX 
**            annunciator ((*)) never seems to go off. i don't
**            know much about serial IO, but that tells me that
**            RX=1 is an idle condition
**
** 10/9/92 - Robert Sanders
**           any questions, comments, etc. e-mail to
**   pshuprs@prism.gatech.edu      or   gt8134b@prism.gatech.edu
******************************************************************

ASSEMBLE
    NIBASC \HPHP48-E\

** misc UART addresses
CRER    EQU     #113    ( write here to clear RER )
RBF     EQU     #114    ( 2-nibble, receive buffer )

** STATUS SERVICE DELAY CONSTANTS
**
** these allow the RER and RBF annunciators and status bits to
** stay set for a while, then be cleared.  the numbers are
** #'s of iterations before clearing, and the translation of
** loops->clock cycles->milliseconds will vary slightly with
** your HP48, and also with which bits get set 
**
** there is no hardware reason to do this, but you need this
** to see any results.
** the side effect is, a character received isn't taken out of
** the receive buffer for 600 loop iterations (it can easily
** choke at 9600 baud.)

RERCOUNT EQU 600
RBFCOUNT EQU 600        

**  UART status bits (at addr #111)
bRBF    EQU     0       ( receive buffer full   )
bRBZ    EQU     1       ( receiver busy         )
bRER    EQU     2       ( receive error?        )
bRX     EQU     3       ( rx pin high????       )

** UART control bits
bERBZ   EQU     0       ( enable interrupt for RBZ?  )
bERBF   EQU     1       ( enable interrupt for RBF?  )
bETBE   EQU     2       ( I'd say TransmitBufferEmpty, but dunno )
bSON    EQU     3       ( enable UART I/O - SerialON )

** ST bits used
sRER    EQU     0
sRBF    EQU     1
RPL

*============================================================*
*                 RPL STARTS HERE                            *
*============================================================*
::
   CLEARVDISP
   $ "ALARM ------ RX"          DISPROW1
   $ "LS: RBF    RS: RBZ"       DISPROW3
   $ "A:  RER"                  DISPROW4 

   CODE
        gosbvl  =SAVPTR         * save regs
        d0=(5)  =DISABLE_KBD
        la(1)   #F
        dat0=a  1               * disable keyboard polling (flag)
        INTOFF                  * shut off keyboard interrupts

        la(2)   #80
        d0=(5)  =ATTNFLG
        dat0=a  1               * init to 0 ON key presses

************************************************************
***********************  ROM INFO  *************************
************************************************************
* here's what OpenUartClr at #3161e (PMC) does to setup
* it sets ERBF (enable receive buffer full interrupt?)
*         ERBZ (enable receiver busy interrupt?)
*         SON  (SerialON - enable UART I/O)
*
*       d1=(5)  #110
*       lc(1)   #b              * sets SON, ERBF, ERBZ 
*       dat1=c  4
************************************************************

* the following is iffy
        d1=(5)  =IOC            * IOControl register (UART control) 
        lc(1)   2^bSON          * set bSON bit
        dat1=c  1

        d1=d1+  1               * serial receive control/status at #111h

        d0=(5)  =ANNCTRL        * annunciator contol (bit 2=ALPHA)
        dat0=a  2               * turn all annunciators off, but leave
                                * enabled (a should be 80 here)

        st=0    sRER            * no RER condition yet
        st=0    sRBF            * no RBF condition yet

        lc(5)   0
        r0=c    a
        
** in this loop, D1 points to the RX status mibb6e
**               D0 points to the annunciator control nibble upon
**                  entry (and loop), but changes
**               R0 counts zeroes on RX
**               ST<0> indicates RER condition unserviced
**               ST<1> indicates RBF condition unserviced
**                B holds counter for clearing RER. at b=0, clears
**                D holds counter for clearing RBF. at b=0, clears
**

mloop   c=dat1  1               * get RX status nibble
        ?cbit=1 bRX
        goyes   postzero        * after zero processing

** this code does "zero processing"
**   if RX=0 last time, the IO annunciator is cleared
**   if RX=1 last time, the IO annunciator is set and the zero counter
**                      is incremented. this flags a one->zero transition
**
** the zero counter is kept in R0
**
        a=dat0  1               * get old annunciators
        ?abit=1 bRX             * RX ann was set, so transition occurred
        goyes   trans   
notrans                         * comes here if RX is zero,
                                * but RX was zero before
        d0=d0+  1               * point to ANN2
        la(1)   8               * ANN_ON=8, IO_ANN=2
        dat0=a  1
        d0=d0-  1               * point back to ANNCTRL (ANN1)
        goto    postzero

trans
        d0=d0+  1               * point to ANN2
        la(1)   10              * ANN_ON=8, IO_ANN=2
        dat0=a  1
        d0=d0-  1               * point back to ANNCTRL (ANN1)
        a=r0    a               * increment 0 counter
        a=a+1   a               * ..
        r0=a    a               * ..

** post "zero processing"
postzero                        
        dat0=c  1               * drive RX status onto annun.

        ?cbit#1 bRER            * if no RER condition, check RBF
        goyes   chkrbf

*************** service RER **************
chkrer  ?st=1   sRER
        goyes   cntrer
        st=1    sRER            * flag the new RER
        la(5)   RERCOUNT        * times to countdown before clearing
        b=a     a
        goto    chkrbf
cntrer  b=b-1   a               * service old RER
        ?b#0    a
        goyes   chkrbf          * not displayed long enough yet
        d0=(5)  CRER            * address to clear RER
        dat0=a  1               * any value will clear
        st=0    sRER            * mark old RER condition gone

*************** service RBF **************
chkrbf  ?cbit#1 bRBF            * no RBF condition
        goyes   chkattn 
        ?st=1   sRBF
        goyes   cntrbf
        st=1    sRBF            * flag the new RBF
        lc(5)   RBFCOUNT        * times to countdown before clearing
        d=c     a
        goto    chkattn
cntrbf  d=d-1   a               * service old RBF
        ?d#0    a
        goyes   chkattn         * not displayed long enough yet
        d0=(5)  RBF             * address of receive buffer
        a=dat0  2               * get buffered byte
        st=0    sRBF            * mark old RBF condition gone

chkattn
        d0=(5)  =ATTNFLG
        c=dat0  1               * get annctrl nibble
        ?c#0    p               * ON pressed yet?
        goyes   done            * exit program
        d0=(5)  =ANNCTRL
        goto    mloop

** get us back to the normal system state
done    d0=(5)  =DISABLE_KBD
        la(1)   0
        dat0=a  1               * enable keyboard polling
        INTON
        d1=(5)  =IOC            * IOControl register (UART control) 
        lc(1)   0               * clear all, especially bSON 
        dat1=c  1               * (turn serial I/O off)

        gosbvl  =GETPTR         * restore RPL registers
        govlng  =PUSH#LOOP      * pushes R0 as sysbin and reenter
                                * RPL main loop
   ENDCODE


   UNCOERCE                     ( turn # into real )
;
[ RETURN TO DIRECTORY ]