LIST		P=16F877A
			INCLUDE		<P16F877A.INC>
			__CONFIG	_CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
			CBLOCK		H'20'
			dem1
			dem2
			cursor
			curdisp
			poeslcd
			cuenta_tabla
			es_negativo
			centena						;millar por que llega hasta 1024
			decena						;centena idem anterior
			unidad						;decena idem anterior
			decimo						;unidad idem anterior
			ACCaHI						;2b
			ACCaLO						;2c
			ACCbHI						;2d
			ACCbLO						;2e
			ACCcHI						;2F
			ACCcLO						;30
			ACCdHI						;31
			ACCdLO						;31
			temp						;32
			sign						;33
			Flags						;34
			resAL						;35 RESTA 1 AUXILIAR
			resBA						;36 RESTA 2 AUXILIAR
;
			CARRY						;37
			DATO1						;38 dato 1 (8 bits + significativos)
			DATO2						;39
			DATO3						;3A
			DATO4						;3B dato 1 (8 bits - significativos)
			FUNC1						;3C dato 2 (8 bits + significativos)
			FUNC2						;3D
			FUNC3						;3E
			FUNC4						;3F dato 2 (8 bits - significativos)
			RES1						;40 resultado (8 bits + significativos)
			RES2						;41
			RES3						;42
			RES4						;43 resultado (8 bits - significativos)
			TEMP1						;44
			TEMP2						;45
			TEMP3						;46
			TEMP4						;47
;

			ENDC
;
RESET		ORG			H'00'
			GOTO		INICIO
			ORG			H'04'			;VECTOR INTERRUPCIÓN
INTERRUP
;
;
;
;
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Code Size : Looped Code )
;
;*******************************************************************;
; Multiplication: ACCb(16 bits)*ACCa(16 bits) -> ACCb,ACCc (32 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI (16 bits)
; (b) Load the 2nd operand in location ACCbLO & ACCbHI (16 bits)
; (c) CALL D_mpy
; (d) The 32 bit result is in location (ACCbHI,ACCbLO,ACCcHI,ACCcLO)
;
; Performance :
; Program Memory : 033
; Clock Cycles : 333
;
; Note : The above timing is the worst case timing, when the
; register ACCb = FFFF. The speed may be improved if
; the register ACCb contains a number ( out of the two
; numbers ) with less number of 1s.
; The performance specs are for Unsigned arithmetic (i.e,
; with “SIGNED equ FALSE“).
;
; The performance specs are for Unsigned arithmetic (i.e,
; with “SIGNED equ FALSE“).
;
;
; Program: DBL_MPYS.ASM
; Revision Date:
; 1-13-97 Compatibility with MPASMWIN 1.40
;
;*******************************************************************;
;ACCaLO equ 0x10
;ACCaHI equ 0x11
;ACCbLO equ 0x12
;ACCbHI equ 0x13
;ACCcLO equ 0x14
;ACCcHI equ 0x15
;ACCdLO equ 0x16
;ACCdHI equ 0x17
;temp   equ 0x18
;sign   equ 0x19
;Flags  equ 0x1F
;
TRUE   equ 1
FALSE  equ 0
MSB    equ 7
SIGNED equ TRUE ; Set This To ‘TRUE’ if the routines

; for Multiplication & Division needs
; to be assembled as Signed Integer
; Routines. If ‘FALSE’ the above two
; routines ( D_mpy & D_div ) use
; unsigned arithmetic.
;*******************************************************************
;
;RUTINA PARA MULTIPLICAR, SUMAR Y RESTAR.
;
;*******************************************************************
;-------------------------------------------------------------------
;SE NECESITA:
;
;11 POCICIONES DE RAM LIBRES PARA:
;                                   ACCaLO
;                                   ACCaHI
;                                   ACCbLO
;                                   ACCbHI
;                                   ACCcLO
;                                   ACCcHI
;                                   ACCdLO
;                                   ACCdHI
;                                   temp
;                                   sign
;                                   Flags
;
;NOTA: Si ACCb vale FFFF, hay que poner SIGNED equ FALSE (más arriba)
;      por defecto está seteado TRUE.
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para RESTAR llamar a RESTA y devuelve el resultado
;en ACCb. La resta es ACCb - ACCa = ACCb
;
;Para saber si es negativo chequear el bit C del STATUS.
;Si es 1, el resultado es positivo, si es 0 el resultado es negativo.
;
;PASOS A SEGUIR:
;
;1- CARGAR EL MINUENDO EN ACCbHI Y ACCbLO
;2- CARGAR EL SUSTRAENDO EN ACCaHI Y ACCaLO
;3- LLAMAR A LA SUBRUTINA RESTA1
;4- SE OBTUVO EL RESULTADO EN ACCbHI, ACCbLO
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para SUMAR llamar a D_add y devuelve el resultado
;en ACCb.
;
;PASOS A SEGUIR:
;
;1- CARGAR EL PRIMER NÚMERO EN ACCbHI Y ACCbLO
;2- CARGAR EL SEGUNDO NÚMERO EN ACCaHI Y ACCaLO
;3- LLAMAR A LA SUBRUTINA D_add
;4- SE OBTUVO EL RESULTADO EN ACCbHI, ACCbLO.
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para MULTIPLICAR llamar a la rutina D_mpyS y devuelve el resultado
;en ACCbHI,ACCbLO,ACCcHI,ACCcLO
;
;PASOS A SEGUIR:
;
;1- CARGAR EL PRIMER NÚMERO EN ACCaHI Y ACCaLO
;2- CARGAR EL SEGUNDO NÚMERO EN ACCbHI Y ACCbLO
;3- LLAMAR A LA SUBRUTINA D_mpyS
;4- SE OBTUVO EL RESULTADO EN ACCbHI,ACCbLO,ACCcHI,ACCcLO
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;*******************************************************************
;
RESTA1 CALL neg_A
;
;*******************************************************************
; Double Precision Addition ( ACCb + ACCa -> ACCb )
;
D_add bcf Flags,C ;Clear temp Carry bit
      movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
      addwf ACCbLO, F ;add lsb
      btfsc STATUS,C ;add in carry
      incf ACCbHI, F
      btfsc STATUS,C
      bsf Flags,C
      movf ACCaHI,W
      addwf ACCbHI, F ;add msb
      btfsc Flags,C
      bsf STATUS,C
      retlw 0
;*******************************************************************
; Double Precision Multiply ( 16x16 -> 32 )
; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyS ;results in ACCb(16 msb’s) and ACCc(16lsb’s)
;
      IF SIGNED
      CALL S_SIGN
      ENDIF
;
      call setup
mloop rrf ACCdHI, F ;rotate d right
      rrf ACCdLO, F
      btfsc STATUS,C ;need to add?
      call D_add
      rrf ACCbHI, F
      rrf ACCbLO, F
      rrf ACCcHI, F
      rrf ACCcLO, F
      decfsz temp, F ;loop until all bits checked
      goto mloop
;
      IF SIGNED
      btfss sign,MSB
      retlw 0
      comf ACCcLO, F ; negate ACCa ( -ACCa -> ACCa )
      incf ACCcLO, F
      btfsc STATUS,Z
      decf ACCcHI, F
      comf ACCcHI, F
      btfsc STATUS,Z
neg_B comf ACCbLO, F ; negate ACCb
      incf ACCbLO, F
      btfsc STATUS,Z
      decf ACCbHI, F
      comf ACCbHI, F
      retlw 0
      ELSE

      retlw 0
      ENDIF
;
;*******************************************************************
;
setup movlw .16 ; for 16 shifts
      movwf temp
      movf ACCbHI,W ; move ACCb to ACCd
      movwf ACCdHI
      movf ACCbLO,W
      movwf ACCdLO
      clrf ACCbHI
      clrf ACCbLO
      retlw 0
;
;*******************************************************************
;
neg_A comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa )
      incf ACCaLO, F
      btfsc STATUS,Z
      decf ACCaHI, F
      comf ACCaHI, F
      retlw 0
;
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
;
      IF SIGNED
;
S_SIGN movf ACCaHI,W
       xorwf ACCbHI,W
       movwf sign
       btfss ACCbHI,MSB ; if MSB set go & negate ACCb
       goto chek_A
;
       comf ACCbLO, F ; negate ACCb
       incf ACCbLO, F
       btfsc STATUS,Z
       decf ACCbHI, F
       comf ACCbHI, F
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
       retlw 0
       goto neg_A
;
       ENDIF
;
;
;
;
;------------------------------------------------------------
;UNA VEZ RESTADOS LAS DOS ADIQUICICIONES, MULTIPLICAMOS EL RESULTADO POR 244 ASÍ LO PASAMOS A VOLT.
;SE OBTIENE UN RESULTADO DE 32 BIT. LUEGO DESCOMPONEMOS EL RESULTADO EN:
;100.000, LUEGO EN 10.000, LUEGO EN 1.000 Y POR ÚLTIMO EN 100. ESTO NOS DA LA TEMPERATURA.
;------------------------------------------------------------
;
;MULTIPLICAMOS POR 244.
;
DESCOMPONER_NÚMERO
;
			MOVFW		resAL
			MOVWF		ACCaHI
			MOVFW		resBA
			MOVWF		ACCaLO
			CLRF		ACCbHI
			MOVLW		.244
			MOVWF		ACCbLO
			CALL		D_mpyS				;MULTIPLICAMOS Y OBTUVIMOS UN RESULTADO DE 32 BIT EN ACCbHI,ACCbLO,ACCcHI,ACCcLO

;
INICIO		BCF			STATUS,RP0
			BCF			STATUS,RP1
			CLRF		PORTA
			CLRF		PORTB
			CLRF		PORTC
			CLRF		PORTD
			CLRF		PORTC

;
			MOVLW		H'01'
			MOVWF		resAL
			MOVLW		H'99'
			MOVWF		resBA
			CALL		DESCOMPONER_NÚMERO
			GOTO		$

;
			END