Muy buenas family. Por favor no quiero que lo lean todo, solo un paseo por encima. 
1- Yo programo en CC5, nunca he hecho nada en asm para pics, por lo que no tengo ni la menor idea de como compilar este codigo, o sea, con que programa.
2- El otro lio, y el mas grave, es que este codigo esta escrito para un PIC16F628, y necesito imperiosamente modificarlo para un PIC16F877, debe poderse hacer porque el 16f628 no tiene nada que no tenga el 16f877.
Yo tengo el .hex del codigo que pondre a continuacion, cuando lo puse en proteus con el PIC16F628 como es logico funciona, pero cuando lo pongo con el PIC16F877, da errores de acceso a memoria que no existe, se pude modificar?, es solo cambiar las referencias distintas a los pines, ayuda por favor. Gracias
	
	
	
		
				
			1- Yo programo en CC5, nunca he hecho nada en asm para pics, por lo que no tengo ni la menor idea de como compilar este codigo, o sea, con que programa.
2- El otro lio, y el mas grave, es que este codigo esta escrito para un PIC16F628, y necesito imperiosamente modificarlo para un PIC16F877, debe poderse hacer porque el 16f628 no tiene nada que no tenga el 16f877.
Yo tengo el .hex del codigo que pondre a continuacion, cuando lo puse en proteus con el PIC16F628 como es logico funciona, pero cuando lo pongo con el PIC16F877, da errores de acceso a memoria que no existe, se pude modificar?, es solo cambiar las referencias distintas a los pines, ayuda por favor. Gracias
		Código:
	
	---------------------------------------------------------------------------------------------------------------
;CAPMET737.ASM 21AUG03 - COPYRIGHT JOHN BECKER - EPE IND/CAP/FREQ METER
;PIC16F628, 3.2768MHz, WDT OFF, POR ON, XTAL XS
;Config register bits
; CP1 CP0 CP1 CP0 NIL CPD LVP BOR MCL OS2 POR WDT OS1 OS0
;  1   1   1   1   1   1   0   0   1   0   0   0   0   1
;N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off
;respectively - refer to PIC '627/8 data sheet
#DEFINE BANK0 BCF $03,5
#DEFINE BANK1 BSF $03,5
        List P = PIC16F628, R=DEC; 
        __CONFIG   h'3F21'
        include P16F628.inc
        CBLOCK
REGA0				;lsb
REGA1
REGA2
REGA3				;msb
REGB0				;lsb
REGB1
REGB2
REGB3				;msb
REGC0				;lsb
REGC1
REGC2
REGC3				;msb
DSIGN				;Digit Sign. 0=positive,FF(or non zero)=negative
DIGIT1				;MSD
DIGIT2
DIGIT3
DIGIT4
DIGIT5				;Decimal digits
DIGIT6
DIGIT7
DIGIT8
DIGIT9
DIGIT10				;LSD
MTEMP
MCOUNT
DCOUNT
LOOP
LOOPA
RSLINE
STORE
SLOWIT
POINT
TIMEMSB
OVERFLOW
STORE2
LARGE
NANO
CAPREF3
CAPREF2
CAPREF1
CAPREF0
INDREF3
INDREF2
INDREF1
INDREF0
TIMEOUT
SWITCH
ZERO
INDCORRECT
CAPCORRECT
CORRECTLOC
        ENDC
PROMVAL  EQU $70   ; accessed via both BANKS
               ; locations up to $7F are available
; **************
        .ORG 0
        goto GIEOFF
        .ORG 4          ; Interrupt vector address
        goto GIEOFF
        .ORG 5          ; Start of program memory
GIEOFF: BCF INTCON,GIE  ; turn off global interrupts
        BTFSC INTCON,GIE
        goto GIEOFF
        goto START
TABLCD: addwf PCL,F     ;LCD initialisation table
        retlw %00110011 ;initialise lcd - first byte
        retlw %00110011 ;2nd byte (repeat of first)
        retlw %00110010 ;set for 4-bit operation
        retlw %00101100 ;set for 2 lines
        retlw %00000110 ;set entry mode to increment each address
        retlw %00001100 ;set display on, cursor off, blink off
        retlw %00000001 ;clear display
        retlw %00000010 ;return home, cursor & RAM to zero
                        ;end inititalisation table
TITLE:  addwf PCL,F
        retlw ' '
        retlw 'E'
        retlw 'P'
        retlw 'E'
        retlw ' '
        retlw 'L'
        retlw 'C'
        retlw 'F'
        retlw ' '
        retlw 'M'
        retlw 'E'
        retlw 'T'
        retlw 'E'
        retlw 'R'
        retlw ' '
        retlw ' '
        retlw ' '
TITLEB: addwf PCL,F
        retlw ' '
        retlw 'W'
        retlw 'A'
        retlw 'I'
        retlw 'T'
        retlw 'I'
        retlw 'N'
        retlw 'G'
        retlw ' '
        retlw 'T'
        retlw 'I'
        retlw 'M'
        retlw 'I'
        retlw 'N'
        retlw 'G'
        retlw ' '
OVERFLOWED:  addwf PCL,F
        retlw 'O'
        retlw 'V'
        retlw 'E'
        retlw 'R'
        retlw 'F'
        retlw 'L'
        retlw 'O'
        retlw 'W'
CALIB:  addwf PCL,F
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw 'N'
        retlw 'U'
        retlw 'L'
        retlw 'L'
        retlw 'E'
        retlw 'D'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
TIMEDOUT: addwf PCL,F
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw 'T'
        retlw 'I'
        retlw 'M'
        retlw 'E'
        retlw ' '
        retlw 'O'
        retlw 'U'
        retlw 'T'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
CAPTIME: addwf PCL,F
        retlw ' '
        retlw ' '
        retlw ' '
        retlw 'C'
        retlw 'A'
        retlw 'P'
        retlw 'A'
        retlw 'C'
        retlw 'I'
        retlw 'T'
        retlw 'O'
        retlw 'R'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
INDTIME: addwf PCL,F
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw 'I'
        retlw 'N'
        retlw 'D'
        retlw 'U'
        retlw 'C'
        retlw 'T'
        retlw 'O'
        retlw 'R'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
CORRECTMSG: addwf PCL,F
        retlw ' '
        retlw 'C'
        retlw 'O'
        retlw 'R'
        retlw 'R'
        retlw 'E'
        retlw 'C'
        retlw 'T'
        retlw 'I'
        retlw 'O'
        retlw 'N'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
;*******************
START:  clrf PORTA
        clrf PORTB
        movlw $07
        movwf CMCON
        BANK1
        movlw %11000000
        movwf TRISB
        movlw %00011100     ; RA0,RA1 as output
        movwf TRISA
        movlw %10000110     ; timer 1:128, pull-ups off
        movwf OPTION_REG
        BANK0
        clrf INTCON
        call PAUSIT
        call LCDSET
        call PAUSIT
        movlw %00000000     ; T1 ext osc disable (bit3=0), T1 stopped (bit0=0), internal clock (bit1=0), bit2 dont care
        movwf T1CON
        btfsc PORTA,2       ; is S3 (RA2) pressed?
        goto CORRECTIT
        call LCD1
        bsf RSLINE,4
        clrf LOOP
TITLE2: movf LOOP,W
        call TITLE
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TITLE2
        clrf INTCON
        clrf POINT
        clrf CAPREF3
        clrf CAPREF2
        clrf CAPREF1
        clrf CAPREF0
        clrf INDREF3
        clrf INDREF2
        clrf INDREF1
        clrf INDREF0
        movlw 0
        call PRMGET
        movwf INDCORRECT
        movlw 1
        call PRMGET
        movwf CAPCORRECT
        call PAUSIT         ; delay
        call PAUSIT         ; delay
        clrf INTCON
        movlw 255
        movwf SWITCH
;****************** START OF MAIN
MAIN:   clrf TIMEOUT
        movf PORTA,W
        andlw %00010000
        xorwf SWITCH,W
        btfsc STATUS,Z
        goto MAIN2
        movf PORTA,W
        andlw %00010000
        movwf SWITCH
        call LCD21
        bsf RSLINE,4
        clrf LOOP
TITLE3: movf LOOP,W
        call TITLEB
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TITLE3
        call LCD1
        bsf RSLINE,4
        clrf LOOP
        btfsc PORTA,4
        goto TIMOUT4
MAIN3:  movf LOOP,W
        call CAPTIME
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto MAIN3
        goto MAIN2
MAIN4:  movf LOOP,W
        call INDTIME
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TIMOUT4
        goto MAIN4
MAIN2:  btfsc SWITCH,4
        goto INDUCT
        goto CAPACITOR
; *****************
; QBASIC ROUTINE ILLUSTRATING INDUCTANCE FORMULA
;CLS
;DEFDBL A-Z
;PRINT "Formula:  L = ((1000000000 / (2 * PI * F) ^ 2)) / C"
;PRINT
;PI = 22 / 7
;F = 389305: PRINT "Frequency = "; F
;C = 200: C = (C * C) / (C + C): PRINT "Capacitance = "; C
;Process:
;L = F * 44: PRINT L
;L = INT(L / 7): PRINT L
;L = INT(1000000000 / L): PRINT L
;L = L * L: PRINT L
;L = INT(L / 10):
;L = L / 1000
;PRINT "Inductance = "; L; "uH"
; **************
INDUCT: movlw %00000001     ; set for correct osc
        movwf PORTA
        call INDTIMER       ; get osc frequency
        call COPY_TIME_REGA
        clrf POINT
        clrf LARGE
        movf TMR1H,W
        andlw %11000000
        iorwf TIMEMSB,W     ; is timing value less than 16384?
        btfsc STATUS,Z
        call LARGEVALUE     ; yes
        btfsc TIMEOUT,0
        goto TIMEEND
        call LCD1           ; set address
        bsf RSLINE,4        ; set RS for data send
        call BIN2DEC
        call SHOWITALL
        movlw 'H'
        call LCDOUT
        movlw 'z'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        call COPY_TIME_REGA
        movlw 44            ; multiply freq x 44 (22 x 2) (2 x PI = 44/7)
        call MULTIPLYSMALL  ; REGA * 44 -> REGA        
        movlw 7             ; divide by 7
        call DIVIDESMALL    ; REGA / 7 -> REGA
        call COPY_REGA_REGB ; copy answer into REGB
        call DIVIDEBILLION  ; 1,000,000,000 / REGB -> REGA
        call COPY_REGA_REGB ; copy answer into REGB
        call MULTIPLY       ; REGA * REGB -> REGA (squaring REGA)
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        movlw '2'
        movf OVERFLOW,F
        btfss STATUS,Z
        goto SHOWOVERFLOW
        movlw 10            ; divide by 10
        call DIVIDESMALL    ; REGA / 100 -> REGA
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        movlw 'C'
        movf OVERFLOW,F
        btfss STATUS,Z
        goto SHOWOVERFLOW
        movf INDCORRECT,W   ; multiply by correction factor
        call MULTIPLYSMALL  ; REGA * REGB -> REGA
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        movlw 'A'
        movf OVERFLOW,F
        btfss STATUS,Z
        goto SHOWOVERFLOW
        movlw 100           ; divide by 100
        call DIVIDESMALL    ; REGA / 100 -> REGA
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        movlw 'B'
        movf OVERFLOW,F
        btfss STATUS,Z
        goto SHOWOVERFLOW
        btfsc PORTA,2       ; is S3 (RA2) pressed?
        call CALIBIND
        movf LARGE,F
        btfsc STATUS,Z
        call SUBTRACTINDREF
        movlw 4
        movwf POINT
        call LCD21          ; set address
        bsf RSLINE,4        ; set RS for data send
        call BIN2DEC        ; converts binary in REGA to decimal in DIGIT
        movf LARGE,F
        btfsc STATUS,Z
        call CHECKMILLI
        call SHOWITALL
        movf LARGE,F
        btfss STATUS,Z
        goto IND2
        movlw 'u'
        movf NANO,F
        btfss STATUS,Z
        movlw 'm'
        call LCDOUT
IND2:   movlw 'H'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        goto MAIN
; ***************
CAPACITOR: movlw %00000010  ; set for correct osc
        movwf PORTA
        clrf TIMEMSB
        call INDTIMER
        call COPY_TIME_REGA
        clrf POINT
        clrf LARGE
        movf TMR1H,W
        andlw %11111110
        iorwf TIMEMSB,W     ; is timing value less than 512?
        btfsc STATUS,Z
        call LARGEVALUE     ; yes
        btfsc ZERO,0
        goto TIMEEND
        call LCD1           ; set address
        bsf RSLINE,4        ; set RS for data send
        call BIN2DEC
        call SHOWITALL
        movlw 'H'
        call LCDOUT
        movlw 'z'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        call COPY_TIME_REGA
        movlw 22             ; multiply freq x PI (R = 1k) (ignoring 3 zeros)
        call MULTIPLYSMALL
        movlw 7
        call DIVIDESMALL
        call COPY_REGA_REGB ; copy answer into REGB
        call DIVIDEBILLION  ; REGA / REGB -> REGA
        movf CAPCORRECT,W   ; multiply by correction factor
        call MULTIPLYSMALL  ; REGA / REGB -> REGA
        movlw 100           ; divide by 100
        call DIVIDESMALL    ; REGA / 100 -> REGA
        btfsc PORTA,2       ; is S3 (RA2) pressed?
        call CALIBCAP
        movf LARGE,F
        btfsc STATUS,Z
        call SUBTRACTCAPREF
        call LCD21          ; set address
        bsf RSLINE,4        ; set RS for data send
        call BIN2DEC
        call CHECKNANO
        call SHOWITALL
        movlw 'u'
        movf LARGE,F
        btfss STATUS,Z
        goto CAP2
        movlw 'n'
        movf NANO,F
        btfsc STATUS,Z
        movlw 'p'
CAP2:   call LCDOUT
        movlw 'F'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        goto MAIN
; **************
LARGEVALUE:
        clrf TIMEOUT
        incf LARGE,F
        movlw %00000000     ; stop timer 1
        movwf T1CON
        clrf TMR1L          ; reset timer 1
        clrf TMR1H
        bcf PIR1,0          ; clear timer rollover flag
        movf PORTB,W        ; get current status of RB6
        andlw %01000000
        movwf STORE         ; store it
        clrf SLOWIT
        bsf T1CON,0         ; start timer 1
WAITB1:
        movf PORTA,W
        andlw %00010000
        xorwf SWITCH,W
        btfss STATUS,Z
        return
WAITB2: movf PORTB,W        ; get current status of RB6
        andlw %01000000
        movwf STORE2        ; temp store it
        xorwf STORE,W       ; compare with prev val of RB6
        btfsc STATUS,Z      ; is it equal?
        goto WAITB1         ; yes
        movf STORE2,W       ; no, different, so store val
        movwf STORE
        call OSCILLATE      ; get timing between two changes of RB6 (1 full cycle)
        btfsc TIMEOUT,0
        return
        call COPY_TIME_REGA
        movlw 122
        call MULTIPLYSMALL  ; REGA * 122 -> REGA multiply freq x 122 to get time re 3.2768MHz xtal (1000000/819200 =1.22)
        movlw 100           ; divide by 100
        call DIVIDESMALL    ; REGA / 100 -> REGA
        call COPY_REGA_REGB ; copy answer into REGB
        call DIVIDEBILLION  ; 1,000,000,000 / REGB -> REGA 
        movf REGA0,W        ; copy answer back into TIMER
        movwf TMR1L
        movf REGA1,W
        movwf TMR1H
        movf REGA2,W
        movwf TIMEMSB
        movlw 4
        movwf POINT
        return
; ***********
CHECKNANO: clrf NANO
        movf DIGIT1,W
        iorwf DIGIT2,W
        iorwf DIGIT3,W
        iorwf DIGIT4,W
        iorwf DIGIT5,W
        iorwf DIGIT6,W
        andlw %00001111
        btfsc STATUS,Z
        return
        bsf NANO,0
        movlw 4
        movwf POINT
        return
; ***********
CHECKMILLI: clrf NANO
        movf DIGIT1,W
        iorwf DIGIT2,W
        iorwf DIGIT3,W
        iorwf DIGIT4,W
        iorwf DIGIT5,W
        andlw %00001111
        btfsc STATUS,Z
        return
        bsf NANO,0
        movlw 7
        movwf POINT
        return
; *************
CALIBCAP: movf REGA0,W
        movwf CAPREF0
        movf REGA1,W
        movwf CAPREF1
        movf REGA2,W
        movwf CAPREF2
        movf REGA3,W
        movwf CAPREF3
        call SHOWCALIB
        return
CALIBIND: movf REGA0,W
        movwf INDREF0
        movf REGA1,W
        movwf INDREF1
        movf REGA2,W
        movwf INDREF2
        movf REGA3,W
        movwf INDREF3
        call SHOWCALIB
        return
; **************
SHOWCALIB: call LCD1
        bsf RSLINE,4
        clrf LOOP
CALIB2: movf LOOP,W
        call CALIB
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto CALIB2
        call PAUSIT
        return
; **************
SUBTRACTCAPREF: ; subtract ref from current val
                ; REGA - REGB -> REGA ;Return carry set if overflow
        movf CAPREF3,W
        movwf REGB3
        movf CAPREF2,W
        movwf REGB2
        movf CAPREF1,W
        movwf REGB1
        movf CAPREF0,W
        movwf REGB0
        call SUBTRACT
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        return
SUBTRACTINDREF: ; subtract ref from current val
                ; REGA - REGB -> REGA ;Return carry set if overflow
        movf INDREF3,W
        movwf REGB3
        movf INDREF2,W
        movwf REGB2
        movf INDREF1,W
        movwf REGB1
        movf INDREF0,W
        movwf REGB0
        call SUBTRACT
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        return
; **************
INDTIMER: movlw %00000110   ; T1 ext osc sync off (bit 2) timer1 off
        movwf T1CON         ; uses T1 ext clock input via RB6 and measures
                            ; number of clock pulses during 25 cycles of TMR0
        BANK1
        movlw %10000110     ; timer 1:128, pullups off
        movwf OPTION_REG
        BANK0
        clrf TMR1L          ; reset timer 1
        clrf TMR1H
        clrf TIMEMSB
        bcf PIR1,0          ; clr timer rollover flag
        movlw %00000111     ; T1 ext osc sync off (bit 2) timer1 on
        movwf T1CON
        movlw 25            
        movwf SLOWIT
        clrf TMR0
        bcf INTCON,2
TIMEIT: btfss PIR1,0        ; has timer 1 overflowed?
        goto TIMIT2
        bcf PIR1,0
        incf TIMEMSB,F
TIMIT2: btfss INTCON,2      ; has timer 0 overflowed?
        goto TIMEIT
        bcf INTCON,2
        decfsz SLOWIT,F
        goto TIMEIT
        movlw %00000000
        movwf T1CON
        return
; ****************
OSCILLATE:   clrf ZERO
        clrf T1CON
        clrf TMR1H
        clrf TMR1L
        bcf PIR1,0
        bsf T1CON,0         ; start timer 1
        clrf TIMEMSB
        bsf T1CON,0         ; start timer 1
OSCA1:
        movf PORTA,W
        andlw %00010000
        xorwf SWITCH,W
        btfss STATUS,Z
        return
        btfsc PIR1,0        ; has timer 1 overflowed?
        call INCMSB         ; yes
OSCA1A: movf PORTB,W        ; is RB6 same as before?
        andlw %01000000
        movwf STORE2
        xorwf STORE,W
        btfsc STATUS,Z
        goto OSCA1          ; yes
        movf STORE2,W       ; no, so continue for next cycle
        movwf STORE
OSCA2:
        movf PORTA,W
        andlw %00010000
        xorwf SWITCH,W
        btfss STATUS,Z
        return
        btfsc PIR1,0        ; has timer 1 overflowed?
        call INCMSB         ; yes
OSCA2A: movf PORTB,W        ; is RB6 same as before?
        andlw %01000000
        movwf STORE2
        xorwf STORE,W
        btfsc STATUS,Z
        goto OSCA2          ; yes
        movlw %00000000     ; no, stop timer 1
        movwf T1CON
        return
INCMSB: incf TIMEMSB,F
        decf SLOWIT,F
        bcf PIR1,0
        clrf TMR1H
        clrf TMR1L
        movf SLOWIT,F
        btfsc STATUS,Z
        bsf ZERO,0
        return
;******** LCD ROUTINES **********
LCD1:   movlw %10000000
        goto LCDLIN
LCD5:   movlw %10000101
        goto LCDLIN
LCD6:   movlw %10000110
        goto LCDLIN
LCD8:   movlw %10001000
        goto LCDLIN
LCD9:   movlw %10001001
        goto LCDLIN
LCD13:  movlw %10001101
        goto LCDLIN
LCD15:  movlw %10001111
        goto LCDLIN
LCD21:  movlw %11000000
        goto LCDLIN
LCD25:  movlw %11000101
        goto LCDLIN
LCD26:  movlw %11000110
        goto LCDLIN
LCD28:  movlw %11001000
LCDLIN: BCF RSLINE,4
LCDOUT: movwf STORE
        movlw 50
        movwf LOOPA
DELAYIT: decfsz LOOPA,F
        goto DELAYIT
        call SENDIT
SENDIT: swapf STORE,F
        movf STORE,W
        andlw 15
        iorwf RSLINE,W
        movwf PORTB
        BSF PORTB,5
        nop 
        nop
        BCF PORTB,5
        RETURN
; *************
PAUSIT: movlw 25
        movwf SLOWIT
        bcf INTCON,2
PAUSE:  btfss INTCON,2
        goto PAUSE
        bcf INTCON,2
        decfsz SLOWIT,F
        goto PAUSE
        return
PAUSIT2: clrf TMR0
        movlw 10
        movwf SLOWIT
        bcf INTCON,2
PAUSE2: btfss INTCON,2
        goto PAUSE2
        bcf INTCON,2
        decfsz SLOWIT,F
        goto PAUSE2
        return
;..............
LCDSET: clrf LOOP       ;clr LCD set-up loop
        clrf RSLINE     ;clear RS line for instruction send
LCDST2: movf LOOP,W     ;get table address
        call TABLCD     ;get set-up instruction
        call LCDOUT     ;perform it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD set-up instruction now been done?
        goto LCDST2     ;no
        return
CLRLINE1: call LCD1     ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;
CLRL1:  movlw ' '       ;clear cell
        call LCDOUT     ;
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto CLRL1      ;no
        return
CLRLINE2: call LCD21
        bsf RSLINE,4
        movlw 16
        movwf LOOP
CL2:    movlw ' '
        call LCDOUT
        decfsz LOOP,F
        goto CL2
        return
; ***********
SHOWITALL: movlw DIGIT1
        movwf FSR
        movlw 10
        movwf LOOP
SHOW2:  movf INDF,W
        call LCDOUT
        movf LOOP,W
        xorwf POINT,W
        btfss STATUS,Z
        goto SHOW3
        movlw '.'
        call LCDOUT
SHOW3:  incf FSR,F
        decfsz LOOP,F
        goto SHOW2
        return
; ***********
COPY_TIME_REGA:
        movf TIMEMSB,W
        movwf REGA2
        movf TMR1H,W
        movwf REGA1
        movf TMR1L,W
        movwf REGA0
        clrf REGA3
        return
; *********
MULTIPLYSMALL:
        movwf REGB0
        clrf REGB1
        clrf REGB2
        clrf REGB3
        call MULTIPLY
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        return
; *************
DIVIDESMALL:
        movwf REGB0
        clrf REGB1
        clrf REGB2
        clrf REGB3
        call DIVIDE
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        return
; ***********
DIVIDEBILLION:
        movlw $3B      ; divide 1,000,000,000 ($3B9ACA00) by the answer
        movwf REGA3
        movlw $9A
        movwf REGA2
        movlw $CA
        movwf REGA1
        movlw $00
        movwf REGA0
        call DIVIDE
        movf STATUS,W
        andlw 1
        movwf OVERFLOW
        return
; ***********
COPY_REGA_REGB:
        movf REGA0,W    
        movwf REGB0
        movf REGA1,W
        movwf REGB1
        movf REGA2,W
        movwf REGB2
        movf REGA3,W
        movwf REGB3
        return
; *********** PETER HEMSLEY'S 32-BIT MATHS ROUTINES *******
;*** SIGNED MULTIPLY ***
;REGA * REGB -> REGA
;Return carry set if overflow
multiply
	clrf	MTEMP		;Reset sign flag
	call	chksgna		;Make REGA positive
	skpc
	call	chksgnb		;Make REGB positive
	skpnc
	return			;Overflow
	call	movac		;Move REGA to REGC
	call	clra		;Clear product
	movlw	D'31'		;Loop counter
	movwf	MCOUNT
muloop	call	slac		;Shift left product and multiplicand
	
	rlf	REGC3,w		;Test MSB of multiplicand
	skpnc			;If multiplicand bit is a 1 then
	call	addba		;add multiplier to product
	skpc			;Check for overflow
	rlf	REGA3,w
	skpnc
	return
	decfsz	MCOUNT,f	;Next
	goto	muloop
	btfsc	MTEMP,0		;Check result sign
	call	negatea		;Negative
	return
; *************
;*** SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
divide	clrf	MTEMP		;Reset sign flag
	movf	REGB0,w		;Trap division by zero
	iorwf	REGB1,w
	iorwf	REGB2,w
	iorwf	REGB3,w
	sublw	0
	skpc
	call	chksgna		;Make dividend (REGA) positive
	skpc
	call	chksgnb		;Make divisor (REGB) positive
	skpnc
	return			;Overflow
	clrf	REGC0		;Clear remainder
	clrf	REGC1
	clrf	REGC2
	clrf	REGC3
	movlw	D'32'		;Loop counter
	movwf	MCOUNT
dvloop	call	slac		;Shift dividend (REGA) msb into remainder (REGC)
	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
	subwf	REGC3,w
	skpz
	goto	dtstgt
	movf	REGB2,w
	subwf	REGC2,w
	skpz
	goto	dtstgt
	movf	REGB1,w
	subwf	REGC1,w
	skpz
	goto	dtstgt
	movf	REGB0,w
	subwf	REGC0,w
dtstgt	skpc			;Carry set if remainder >= divisor
	goto	dremlt
	movf	REGB0,w		;Subtract divisor (REGB) from remainder (REGC)
	subwf	REGC0,f
	movf	REGB1,w
	skpc
	incfsz	REGB1,w
	subwf	REGC1,f
	movf	REGB2,w
	skpc
	incfsz	REGB2,w
	subwf	REGC2,f
	movf	REGB3,w
	skpc
	incfsz	REGB3,w
	subwf	REGC3,f
	clrc
	bsf	REGA0,0		;Set quotient bit
dremlt	decfsz	MCOUNT,f	;Next
	goto	dvloop
	btfsc	MTEMP,0		;Check result sign
	call	negatea		;Negative
	return
;*** SQUARE ROOT ***
;sqrt(REGA) -> REGA
;Return carry set if negative
sqrt	rlf	REGA3,w		;Trap negative values
	skpnc
	return
	call	movac		;Move REGA to REGC
	call	clrba		;Clear remainder (REGB) and root (REGA)
	movlw	D'16'		;Loop counter
	movwf	MCOUNT
sqloop	rlf	REGC0,f		;Shift two msb's
	rlf	REGC1,f		;into remainder
	rlf	REGC2,f
	rlf	REGC3,f
	rlf	REGB0,f
	rlf	REGB1,f
	rlf	REGB2,f
	rlf	REGC0,f
	rlf	REGC1,f
	rlf	REGC2,f
	rlf	REGC3,f
	rlf	REGB0,f
	rlf	REGB1,f
	rlf	REGB2,f
	setc			;Add 1 to root
	rlf	REGA0,f		;Align root
	rlf	REGA1,f
	rlf	REGA2,f
	movf	REGA2,w		;Test if remdr (REGB) >= root (REGA)
	subwf	REGB2,w
	skpz
	goto	ststgt
	movf	REGA1,w
	subwf	REGB1,w
	skpz
	goto	ststgt
	movf	REGA0,w
	subwf	REGB0,w
ststgt	skpc			;Carry set if remdr >= root
	goto	sremlt
	movf	REGA0,w		;Subtract root (REGA) from remdr (REGB)
	subwf	REGB0,f
	movf	REGA1,w
	skpc
	incfsz	REGA1,w
	subwf	REGB1,f
	movf	REGA2,w
	skpc
	incfsz	REGA2,w
	subwf	REGB2,f
	bsf	REGA0,1		;Set current root bit
sremlt	bcf	REGA0,0		;Clear test bit
	decfsz	MCOUNT,f	;Next
	goto	sqloop
	clrc
	rrf	REGA2,f		;Adjust root alignment
	rrf	REGA1,f
	rrf	REGA0,f
	return
;*** SIGNED BINARY TO DECIMAL ***
;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN
;DSIGN = 0 if REGA is positive, FF if negative
;Return carry set if overflow
;Uses FSR register
bin2dec
        call    clrdig          ;Clear all digits
        clrf    MTEMP           ;Reset sign flag
	call	chksgna		;Make REGA positive
	skpnc
        goto BLANKIT            ;Overflow
	movlw	D'32'		;Loop counter
	movwf	MCOUNT
b2dloop	rlf	REGA0,f		;Shift msb into carry
	rlf	REGA1,f
	rlf	REGA2,f
	rlf	REGA3,f
	movlw	DIGIT10
	movwf	FSR		;Pointer to digits
	movlw	D'10'		;10 digits to do
	movwf	DCOUNT
adjlp	rlf	INDF,f		;Shift digit and carry 1 bit left
        movlw   -D'10'
	addwf	INDF,w		;Check and adjust for decimal overflow
	skpnc
	movwf	INDF
	decf	FSR,f		;Next digit
	decfsz	DCOUNT,f
	goto	adjlp
	decfsz	MCOUNT,f	;Next bit
	goto	b2dloop
	btfsc	MTEMP,0		;Check sign
	comf	DSIGN,f		;Negative
	clrc
BLANKIT: movlw 48
        iorwf DIGIT1,F
        iorwf DIGIT2,F
        iorwf DIGIT3,F
        iorwf DIGIT4,F
        iorwf DIGIT5,F
        iorwf DIGIT6,F
        iorwf DIGIT7,F
        iorwf DIGIT8,F
        iorwf DIGIT9,F
        iorwf DIGIT10,F
        movlw 10          ; blank leading zeros
        movwf LOOP
        movlw DIGIT1
        movwf FSR
BLANK:  movf LOOP,W
        xorwf POINT,W
        btfsc STATUS,Z
        return
        movf INDF,W
        andlw 15
        btfss STATUS,Z
        return
        bcf INDF,4
        incf FSR,F
        decfsz LOOP,F
        goto BLANK
        movlw 48
        iorwf DIGIT10,F
        return
; **************
;Negate REGA
;Used by chksgna, multiply, divide, mod, bin2dec, dec2bin
negatea	movf	REGA3,w		;Save sign in w
	andlw	0x80
	comf	REGA0,f		;2's complement
	comf	REGA1,f
	comf	REGA2,f
	comf	REGA3,f
	incfsz	REGA0,f
	goto	nega1
	incfsz	REGA1,f
	goto	nega1
	incfsz	REGA2,f
	goto	nega1
	incf	REGA3,f
nega1
	incf	MTEMP,f		;flip sign flag
	addwf	REGA3,w		;Return carry set if -2147483648
	return
;Check sign of REGA and convert negative to positive
;Used by multiply, divide, bin2dec
chksgna	rlf	REGA3,w
	skpc
	return			;Positive
;Set all digits to 0
;Used by bin2dec
clrdig	clrf	DSIGN
	clrf	DIGIT1
	clrf	DIGIT2
	clrf	DIGIT3
	clrf	DIGIT4
	clrf	DIGIT5
	clrf	DIGIT6
	clrf	DIGIT7
	clrf	DIGIT8
	clrf	DIGIT9
	clrf	DIGIT10
	return
;Shift left REGA and REGC
;Used by multiply, divide
slac	rlf	REGA0,f
	rlf	REGA1,f
	rlf	REGA2,f
	rlf	REGA3,f
	rlf	REGC0,f
	rlf	REGC1,f
	rlf	REGC2,f
	rlf	REGC3,f
	return
;Check sign of REGB and negative convert to positive
;Used by multiply, divide, mod
chksgnb	rlf	REGB3,w
	skpc
	return			;Positive
;Negate REGB
;Used by chksgnb, subtract, multiply, divide, mod
negateb	movf	REGB3,w		;Save sign in w
	andlw	0x80
	comf	REGB0,f		;2's complement
	comf	REGB1,f
	comf	REGB2,f
	comf	REGB3,f
	incfsz	REGB0,f
	goto	negb1
	incfsz	REGB1,f
	goto	negb1
	incfsz	REGB2,f
	goto	negb1
	incf	REGB3,f
negb1
	incf	MTEMP,f		;flip sign flag
	addwf	REGB3,w		;Return carry set if -2147483648
	return
movac	movf	REGA0,w
	movwf	REGC0
	movf	REGA1,w
	movwf	REGC1
	movf	REGA2,w
	movwf	REGC2
	movf	REGA3,w
	movwf	REGC3
	return
;Clear REGB and REGA
;Used by sqrt
clrba	clrf	REGB0
	clrf	REGB1
	clrf	REGB2
	clrf	REGB3
;Clear REGA
;Used by multiply, sqrt
clra	clrf	REGA0
	clrf	REGA1
	clrf	REGA2
	clrf	REGA3
	return
;Add REGB to REGA (Unsigned)
;Used by add, multiply,
addba	movf	REGB0,w		;Add lo byte
	addwf	REGA0,f
	movf	REGB1,w		;Add mid-lo byte
	skpnc			;No carry_in, so just add
	incfsz	REGB1,w		;Add carry_in to REGB
	addwf	REGA1,f		;Add and propagate carry_out
	movf	REGB2,w		;Add mid-hi byte
	skpnc
	incfsz	REGB2,w
	addwf	REGA2,f
	movf	REGB3,w		;Add hi byte
	skpnc
	incfsz	REGB3,w
	addwf	REGA3,f
	return
;*** SIGNED SUBTRACT ***
;REGA - REGB -> REGA
;Return carry set if overflow
subtract
	call	negateb		;Negate and add
	skpnc
	return			;Overflow
;*** SIGNED ADD ***
;REGA + REGB -> REGA
;Return carry set if overflow
add	movf	REGA3,w		;Compare signs
	xorwf	REGB3,w
	movwf	MTEMP
	call	addba		;Add REGB to REGA
	clrc			;Check signs
	movf	REGB3,w		;If signs are same
	xorwf	REGA3,w		;so must result sign
	btfss	MTEMP,7		;else overflow
	addlw	0x80
	return
; *************
SHOWOVERFLOW: movwf OVERFLOW
        call CLRLINE2
        call LCD21
        bsf RSLINE,4
;        movf INDCORRECT,W      ; author's test section
;        movwf REGA0
;        movf LARGE,W
;        movwf REGA0
;        clrf REGA1
;        clrf REGA2
;        clrf REGA3
;        call BIN2DEC
;        call SHOWITALL
        clrf LOOP
OVER2:  movf LOOP,W
        call OVERFLOWED
        call LCDOUT
        incf LOOP,F
        btfss LOOP,3
        goto OVER2
        movlw ' '
        call LCDOUT
        movf OVERFLOW,W
        call LCDOUT
        goto MAIN
; ***********
CHECKZERO:
        movf TMR1H,W
        iorwf TMR1L,W
        iorwf TIMEMSB,W
        movf STATUS,Z
        andlw $00000100
        movwf OVERFLOW
TIMEEND: movlw %00000000      ; stop timer 1
        movwf T1CON
        clrf TMR1H
        clrf TMR1L
        clrf TIMEMSB
        call LCD21
        bsf RSLINE,4
        clrf LOOP
TIMOUT2: movf LOOP,W
        call TIMEDOUT
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TIMOUT2
        call LCD1
        bsf RSLINE,4
        clrf LOOP
        btfsc PORTA,4
        goto TIMOUT4
TIMOUT3: movf LOOP,W
        call CAPTIME
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TIMOUT3
        goto MAIN
TIMOUT4: movf LOOP,W
        call INDTIME
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto TIMOUT4
        goto MAIN
; ******* WRITE DATA TO EEPROM ROUTINE modified for PIC16F62x devices ********
          ;according to data sheet page 93 (is the same as for 16F87x devices
	  ; except that PIR2 of '87x has become PIR1 for '62x and page 2/3 not used)
	
                        ;This routine is entered with W holding
                        ;the eeprom byte address at which data
                        ;is to be stored. The data to be stored
                        ;is held in PROMVAL, which is located in both pages at or above $70
SETPRM: 
        BANK1
        movwf EEADR     ;copy W into EEADR to set eeprom address
        movf PROMVAL,W  ;get data value from PROMVAL and hold in W
        movwf EEDATA    ;copy W into eeprom data byte register
        bsf EECON1,WREN ;enable write flag
MANUAL: movlw $55       ;these lines cause the action required by
        movwf EECON2    ;by the eeprom to store the data in EEDATA
        movlw $AA       ;at the address held by EEADR.
        movwf EECON2
        bsf EECON1,WR   ;set the ``perform write'' flag
        BANK0
CHKWRT: btfss PIR1,EEIF ;wait until bit 4 of PIR2 is set
        goto CHKWRT
        bcf PIR1,EEIF   ;clear bit 4 of PIR2
        return
;******** READ DATA FROM EEPROM ROUTINE modified for PIC16F62x devices ****
;         the data sheet page 93 is wrong!  This routine here works!
                        ;This routine is entered with W holding
                        ;the eeprom byte address to be read.
PRMGET: BANK1
        movwf EEADR     ;copy W into EEADR to set eeprom address
        bsf EECON1,RD   ;enable read flag
        movf EEDATA,W   ;read eeprom data now in EEDATA into W
        BANK0
        return
; ***********
CORRECTIT:
        call LCD1
        bsf RSLINE,4
        btfss PORTA,4
        goto CAPCRT
        
INDCRT: movlw 'I'
        call LCDOUT
        movlw 'N'
        call LCDOUT
        movlw 'D'
        call LCDOUT
        clrf CORRECTLOC
        goto CORRECT2
CAPCRT: movlw 'C'
        call LCDOUT
        movlw 'A'
        call LCDOUT
        movlw 'P'
        call LCDOUT
        movlw 1 
        movwf CORRECTLOC
CORRECT2: clrf LOOP
CORRECT3: movf LOOP,W
        call CORRECTMSG
        call LCDOUT
        incf LOOP,F
        btfss LOOP,4
        goto CORRECT3
COR3:   call SHOWCORRECT
    
COR4:   btfsc PORTA,2       ; is S3 (RA2) still pressed?
        goto COR4           ; yes
        call PAUSIT
COR5:   btfss PORTA,2       ; is S3 (RA2) pressed?
        goto COR5           ; no
        btfsc PORTA,4
        goto COR7
COR6:   call INCIT
        call SHOWCORRECT
        call PAUSIT2
        call PAUSIT2
        goto COR5
COR7:   call DECIT
        call SHOWCORRECT
        call PAUSIT2
        call PAUSIT2
        goto COR5
INCIT:  movf CORRECTLOC,W
        call PRMGET
        movwf PROMVAL
        addlw 1
        movwf PROMVAL
        xorlw 200
        btfsc STATUS,Z
        decf PROMVAL,F
        movf CORRECTLOC,W
        call SETPRM
        return
DECIT:  movf CORRECTLOC,W
        call PRMGET
        movwf PROMVAL
        decf PROMVAL,F
        btfsc STATUS,Z
        incf PROMVAL,F
        movf CORRECTLOC,W
        call SETPRM
        return
; **********
SHOWCORRECT:
        movf CORRECTLOC,W
        call PRMGET
        movwf REGA0
        clrf REGA1
        clrf REGA2
        clrf REGA3
        call LCD21
        bsf RSLINE,4
        call BIN2DEC
        movf DIGIT8,W
        call LCDOUT
        movf DIGIT9,W
        call LCDOUT
        movf DIGIT10,W
        call LCDOUT
        return
; **************
        .org $2100             ; data eeprom values
        DE 100,100,0,0,0,0
        END
			
				Última edición por un moderador: 
			
		
	
								
								
									
	
								
							
							 
   
				 
						 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		