

 ; Read the Proportional valve feedback and update display with current value.
        ;  RD_FDBK is to read the analog channel '0' and return the 12 bit value in
        ;  ADC buffer locations in RAM, after right justifying the result.

        RD_FDBK:        CLR     P1.0
                        CLR     P1.1
                        CLR     P1.2

        GET_ANA:        CLR     P1.3                    ; R/C  low for coversion start
                        CLR     P1.4                    ; AO low for 12 bit mode
                        MOV     DPTR, #ADC_IN
                        MOVX    A,  @DPTR               ; to pull CE of ADC high..
                        MOV     R6,  #25
        ADC_DLY:        NOP
                        DJNZ    R6,  ADC_DLY            ; 25 X 2 = 50 microsecond delay
                        SETB    P1.3                    ; R/C  high for read
                        MOV     DPTR, #ADC_IN
                        MOVX    A,  @DPTR
                        MOV     ADC_HI,  A              ; Save high byte
                        SETB    P1.4                    ; AO high for second byte
                        MOVX    A,  @DPTR   <b><i>; BUG was here </b></i>
                        MOV     ADC_LO,  A              ; Save low byte
        RE_ORG:         NOP                             ; RE_ORG is for right justifying ADC result
                        SWAP    A

                        MOV     ADC_LO,  A              ; ADC_LO now has zeroes in high nibble
                        MOV     A,  ADC_HI
                        SWAP    A
                        ANL     A,  #0F0H
                        ADD     A,  ADC_LO              ; Mask low nibble of ADC_HI, add to ADC_LO
                        MOV     ADC_LO,  A              ; ADC_LO is now right justified.
                        MOV     A,  ADC_HI
                        SWAP    A

                        ANL     A,  #0FH                ; Mask original high nibble of ADC_HI
                        MOV     ADC_HI,  A              ; ADC_HI is now right justified.
                        CLR     P1.3
                        CLR     P1.4


        CHKPOLRTY:      MOV     OPERAND+0, #00H         ;
                        MOV     OPERAND+1, #08H         ; 800H = 0.0 V dc
                        MOV     R0, #ADC_LO
                        MOV     R1, #OPERAND+0
                        CALL    COMPARE
                        JC      NEGFBK
                        JZ      ZEROVAL

        POSCHK:         MOV     OPERAND+0, #00H
                        MOV     OPERAND+1, #08H
                        MOV     R0, #ADC_LO
                        MOV     R1, #OPERAND+0
                        CALL    COMPARE
                        JNC     POSFBK

        ZEROVAL:        MOV     ADC_LO, #00H
                        MOV     ADC_HI, #00H
                        MOV     DPTR, #POSFVAL
                        JMP     SHOADC                  ; Display zero if ADCvalue in the mid band (7FFH - 800H)

        NEGFBK:         MOV     R1, #ADC_LO             ; R0 holds 800H and R1 holds ADCvalue
                        MOV     R0, #OPERAND+0
                        CALL    COMPUTE                 ; Count value for -10V to 0V is to be converted to -9.99 to 0.00
                        MOV     DPTR, #NEGFVAL          ; count value for -10V is 0. and 0V is 800H
                        JMP     SHOADC                  ; Counts to convert = (800H-adc value)


        POSFBK:         MOV     R0, #ADC_LO             ; R0 holds ADCvalue and R1 holds 800H
                        MOV     R1, #OPERAND+0
                        CALL    COMPUTE                 ; Count value for 0V to +10V is to be converted to 0.00 to +9.99
                        MOV     DPTR, #POSFVAL          ; count value for 0V is 800H. and +10V is FFFH
                                                        ; Counts to convert = (adc value-800H)

        SHOADC:         CALL    FBKDISP                 ; Adjust decimals and display in VFD
                        RET

 ;=============================================

        ; Following algorithm used for compute. Call this routine with R0 and R1 suitably pointing
        ; to the ADC_LO and OPERAND(loaded with 800H). The count is first computed by subtraction
        ; and then the result mutiplied by 488 ( each bit = 4.88mV and 100 is used as a multiplier
        ; to increase precision. Thus 2048 x 488 = 999424. Now divide the answer by 1000 to restore
        ; result. (999424/1000 = 999.424) Display the integer as 9.99

        COMPUTE:        CALL    SUB16

                        MOV     R0, #ANSWER+0
                        MOV     OPERAND+0, #0E8H        ; = 488
                        MOV     OPERAND+1, #01H
                        MOV     R1, #OPERAND+0
                        CALL    MUL16

                        MOV     R0, #PROD+0
                        MOV     OPERAND+0, #0E8H
                        MOV     OPERAND+1, #03H         ; = 1000
                        MOV     R1, #OPERAND+0
                        CALL    rDIV16
                        MOV     ADC_LO, QUOT+0
                        MOV     ADC_HI, QUOT+1
                        RET
