pls i hve a source code for a digital alarm clock bt its for pic16c54a and i want to desiogn a digital alarm clock using pic 16f84a so here is my source code, i need an assembly language guru to help me do this pls. below is the source code
[; *********************************************
; * PIC Egg Timer Give-Away *
; * *
; * Author: John Day *
; * Sr. Field Applications Engineer *
; * Northeast Region *
; * *
; * Revision: 1.2 *
; * Date September 22, 1994 *
; * Part: PIC16C54-LP/P or PIC16LC54A/P *
; * Fuses: OSC: LP *
; * WDT: OFF *
; * PuT: OFF *
; * CP: OFF *
; *********************************************
;
; This program is intended to run on a 32 Khz watch crystal and connects
; to four multiplexed seven segment displays. It displays the current
; time, alarm time and egg count down timers. There are switches that
; allow the user to set the alarm, timer and clock functions.
LIST F=INHX8M,P=16C54
INCLUDE "c:\pictools\picstarc\p16C5X.inc"
__FUSES _CP_OFF&_WDT_OFF&_LP_OSC
ORG 07h
; ****************************************
; * Static RAM Register File Definitions *
; ****************************************
INDADDR EQU 0 ; Indirect address register
DISPSEGS_A EQU 07h ; Current Display A segment bit pattern
DISPSEGS_B EQU 08h ; Current Display B segment bit pattern
DISPSEGS_C EQU 09h ; Current Display C segment bit pattern
DISPSEGS_D EQU 0Ah ; Current Display D segment bit pattern
CLK_SEC EQU 0Bh ; Clock second counter (0-59)
CLK_MIN_LD EQU 0Ch ; Clock minute low digit counter (0-9)
CLK_MIN_HD EQU 0Dh ; Clock minute high digit counter (0-5)
CLK_HOUR_LD EQU 0Eh ; Clock hour low digit counter (0-9)
CLK_HOUR_HD EQU 0Fh ; Clock hour high digit counter (0-2)
ALM_MIN_LD EQU 10h ; Alarm minute low digit counter (0-9)
ALM_MIN_HD EQU 11h ; Alarm minute high digit counter (0-5)
ALM_HOUR_LD EQU 12h ; Alarm hour lor digit counter (0-9)
ALM_HOUR_HD EQU 13h ; Alarm hour high digit counter (0-2)
TMR_SEC_LD EQU 14h ; Timer second low digit counter (0-9)
TMR_SEC_HD EQU 15h ; Timer second high digit counter (0-5)
TMR_MIN_LD EQU 16h ; Timer hour low digit counter (0-9)
TMR_MIN_HD EQU 17h ; Timer hour high digit counter (0-2)
KEYPAT EQU 18h ; Currently pressed key bits
FLAGS EQU 19h ; Status of alarms, display on, etc.
PREVTMR0 EQU 1Ah ; Used to determine which TMR0 bits changed
PREVSCAN EQU 1Bh ; Store Common Cathode display scan state
TEMP EQU 1Ch ; Temporary storage
DISPONCNT EQU 1Dh ; Time the displays have been on
MODE_COUNT EQU 1Eh ; Current mode state
ALARMCNT EQU 1Fh ; Time the alarm has been sounding
; ****************************************
; * Flag and state bit definitions *
; ****************************************
#define SECBIT TEMP,7 ; Bit to spawn 1/4 second count
#define SCANBIT TMR0,0 ; Bit to spawn display MUX
#define MODEKEY KEYPAT,4 ; Bit for MODEKEY pressed
#define UPKEY KEYPAT,6 ; Bit for UPKEY pressed
#define DOWNKEY KEYPAT,5 ; Bit for DOWNKEY pressed
#define MODEKEYCHG TEMP,4 ; Bit for delta MODEKEY
#define TIMENOW FLAGS,7 ; Flag to indicate 1 second passed
#define ALARMNOW FLAGS,3 ; Flag to indicate wakeup alarm
#define EGGNOW FLAGS,4 ; Flag to indicate egg timer alarm
#define ALARMOK STATUS,PA0 ; Flag to enable wakeup alarm
#define EGGOK STATUS,PA1 ; Flag to enable timer alarm
#define BUZZEROUT PORTB,7 ; Pin for pulsing the buzzer
#define DISPON DISPONCNT,4 ; Bit to turn on LED displays
; *************************************************
; * Various Constants used throughout the program *
; *************************************************
TMR0 EQU 1 ; Location of the TMR0 register
SEC_MAX EQU .60 ; Maximum value for second counter
MIN_LD_MAX EQU .10 ; Maximum value for low digit of minute
MIN_HD_MAX EQU .6 ; Maximum value for high digit of minute
HOUR_LD_MAX EQU .4 ; Maximum value for low digit of hour
HOUR_HD_MAX EQU .2 ; Maximum value for high digit of hour
OPTION_SETUP EQU b'00000011' ; TMR0 - internal, /16 prescale
BUZINITVAL EQU 7 ;
INIT_MODE_COUNT EQU 8 ; Digit counts to move to hour digits
ALARMCYCCNT EQU .40 ; Alarm for 10 seconds (ALARMCYCCNT/4)
ORG 01FFh ; The PIC5X reset vector is at end of memory
reset_vector
GOTO init ; Jump to the initialization code

ORG 0
; ****************************************
; * Current mode look-up table *
; ****************************************
mode_timer
ANDLW 3 ; Mask off upper bits just in case..
ADDWF PC ; Jump to one of 4 look-up entries
RETLW TMR_SEC_LD ; Return the address of the 99 min timer RAM
RETLW ALM_MIN_LD ; Return the address of the alarm RAM
RETLW CLK_MIN_LD ; Return the address of the clock RAM
RETLW CLK_MIN_LD ; Return the address of the clock RAM
; ****************************************
; * Buzz the buzzer for 1/8 second *
; ****************************************
buzz_now
CLRF PORTB ; Shut off the segments
buzz_now_dispon
CLRF TEMP ; Buzz for 256 pulses
loop_buz
BSF BUZZEROUT ; Send out pulse
BCF BUZZEROUT ; Clear out the pulse
DECFSZ TEMP ; Decriment counter and skip when done
GOTO loop_buz ; Go back and send another pulse
RETLW 0 ; We are done so come back!
; ****************************************
; * Mux drive the next LED display digit *
; ****************************************
task_scan ; (19 (next_scan) + 2 = 21 cycles - must be called every 11 cy)
BTFSC SCANBIT ; Synch up with 3.9 mS timer bit
GOTO task_scan ; Jump back until bit is clear
next_scan ; (15 + 2 call + 2 return = 19 cycles)
RLF PREVSCAN,W ; Move to the next digit select into C
BTFSS PREVSCAN,1 ; 0 Check if display A was on before
MOVF DISPSEGS_C,W ; Place display B value into W
BTFSS PREVSCAN,0 ; 1 Check if display B was on before
MOVF DISPSEGS_B,W ; Place display C value into W
BTFSS PREVSCAN,3 ; 2 Check if display C was on before
MOVF DISPSEGS_A,W ; Place display D value into W
BTFSS PREVSCAN,2 ; 3 Check if display D was on before
MOVF DISPSEGS_D,W ; Place display A value into W
CLRF PORTB ; Turn off all segments
RLF PREVSCAN ; Move to the next digit
RLF PORTA ; Move port to the next digit
MOVWF PORTB ; Place next segment value on PORTB
MOVF PREVSCAN,W ; Restore the port in case it is wrong
MOVWF PORTA ; Restore the port
RETLW 0 ; Display is updated - now return

; **********************************************
; * Move new digit display info out to display *
; **********************************************
disp_value
MOVWF FSR ; Place W into FSR for indirect addressing
CALL task_scan ; Scan the next LED digit.
MOVF INDADDR,W ; Place display value into W
CALL led_lookup ; Look up seven segment value
MOVWF DISPSEGS_A ; Move value out to display register A
INCF FSR ; Go to next display value
CALL task_scan ; Scan the next LED digit.
MOVF INDADDR,W ; Place display value into W
CALL led_lookup ; Look up seven segment value
MOVWF DISPSEGS_B ; Move value out to display register B
INCF FSR ; Go to next display value
CALL task_scan ; Scan the next LED digit.
MOVF INDADDR,W ; Place display value into W
CALL led_lookup ; Look up seven segment value
MOVWF DISPSEGS_C ; Move value out to display register C
INCF FSR ; Go to next display value
CALL task_scan ; Scan the next LED digit.
MOVF INDADDR,W ; Place display value into W
BTFSC STATUS,Z ; ZBLANK - Check for a zero
COMF INDADDR,W ; ZBLANK - Clear digit with FF if leading 0
CALL led_lookup ; Look up seven segment value
MOVWF DISPSEGS_D ; Move value out to display register D
CALL task_scan ; Scan the next LED digit.
RETLW 0
; ****************************************
; * Convert display value into segments *
; ****************************************
led_lookup
ANDLW 0Fh ; Strip off upper digits
ADDWF PC ; Jump into the correct location
RETLW b'00111111' ; Bit pattern for a Zero
RETLW b'00000110' ; Bit pattern for a One
RETLW b'01011011' ; Bit pattern for a Two
RETLW b'01001111' ; Bit pattern for a Three
RETLW b'01100110' ; Bit pattern for a Four
RETLW b'01101101' ; Bit pattern for a Five
RETLW b'01111101' ; Bit pattern for a Six
RETLW b'00000111' ; Bit pattern for a Seven
RETLW b'01111111' ; Bit pattern for a Eight
RETLW b'01101111' ; Bit pattern for a Nine
RETLW 0 ; Turn display off - ILLEGAL VALUE
RETLW 0 ; Turn display off - ILLEGAL VALUE
RETLW 0 ; Turn display off - ILLEGAL VALUE
RETLW 0 ; Turn display off - ILLEGAL VALUE
RETLW 0 ; Turn display off - ILLEGAL VALUE
RETLW 0 ; Turn display off - ILLEGAL VALUE
; ************************************************************************
; * Convert display value into single segment ON for manufacturing diags *
; ************************************************************************
mfg_led_lookup
ANDLW 07h ; Strip off upper digits
ADDWF PC ; Jump into the correct location
RETLW b'00000001' ; Bit pattern for segment A on only
RETLW b'00000010' ; Bit pattern for segment B on only
RETLW b'00000100' ; Bit pattern for segment C on only
RETLW b'00001000' ; Bit pattern for segment D on only
RETLW b'00010000' ; Bit pattern for segment E on only
RETLW b'00100000' ; Bit pattern for segment F on only
RETLW b'01000000' ; Bit pattern for segment G on only
RETLW b'01111111' ; Bit pattern for all segments on
; ***********************************************************
; * Wake-up and turn on the displays *
; ***********************************************************
turnon_scan
BSF DISPON ; Set display ON bit
MOVLW b'11101110' ; Place digit 0 scan pattern in W
XORWF PREVSCAN,W ; See if this is the current scan
BTFSC STATUS,Z ; Skip if this is not the current scan
RETLW 0 ; Legal scan value - we are done!
MOVLW b'11011101' ; Place digit 1 scan pattern in W
XORWF PREVSCAN,W ; See if this is the current scan
BTFSC STATUS,Z ; Skip if this is not the current scan
RETLW 0 ; Legal scan value - we are done!
MOVLW b'10111011' ; Place digit 2 scan pattern in W
XORWF PREVSCAN,W ; See if this is the current scan
BTFSC STATUS,Z ; Skip if this is not the current scan
RETLW 0 ; Legal scan value - we are done!
MOVLW b'01110111' ; Place digit 3 scan pattern in W
XORWF PREVSCAN,W ; See if this is the current scan
BTFSC STATUS,Z ; Skip if this is not the current scan
RETLW 0 ; Legal scan value - we are done!
MOVLW 0EEh ; Move digit 0 scan value into W
MOVWF PREVSCAN ; Move it into scan pattern register

; ****************************************
; * Scan for pressed keys *
; ****************************************
scan_keys
CLRF PORTB ; Turn off all of the segments
MOVLW 0FFh ; Place FF into W
MOVWF PORTA ; Make PORT A all ones
MOVLW b'01110000' ; Place 70 into W
TRIS PORTB ; Make RB4,5,6 inputs others outputs
MOVF PORTB,W ; Place keyscan value into W
XORWF KEYPAT,W ; Place Delta key press into W
MOVWF TEMP ; Place Delta key press into TEMP
XORWF KEYPAT,F ; Update KEYPAT reg to buttons pressed
CLRW ; Place 0 into W
TRIS PORTB ; Make PORT B outputs
MOVF PREVSCAN,W ; Place previous scan value into W
MOVWF PORTA ; Turn on the scan
RETLW 0
; ****************************************
; * Check if alarm or timer is expired *
; ****************************************
check_time
CALL task_scan ; Scan the next LED digit.
BSF ALARMNOW ; Set the alarm bit
BSF EGGNOW ; Set the Egg timer alarm bit
MOVF ALM_MIN_LD,W ; Place alarm minute counter into W
SUBWF CLK_MIN_LD,W ; CLK_MIN_LD - W -> W
BTFSS STATUS,Z ; Skip if they are equal
BCF ALARMNOW ; They are not equal so clear alarm bit
MOVF ALM_MIN_HD,W ; Place alarm minute counter into W
SUBWF CLK_MIN_HD,W ; CLK_MIN_HD - W -> W
BTFSS STATUS,Z ; Skip if they are equal
BCF ALARMNOW ; They are not equal so clear alarm bit
CALL task_scan ; Scan the next LED digit.
MOVF ALM_HOUR_LD,W ; Place alarm hour counter into W
SUBWF CLK_HOUR_LD,W ; CLK_HOUR_LD - W -> W
BTFSS STATUS,Z ; Skip if they are equal
BCF ALARMNOW ; They are not equal so clear alarm bit
MOVF ALM_HOUR_HD,W ; Place alarm hour counter into W
SUBWF CLK_HOUR_HD,W ; CLK_HOUR_LD - W -> W
BTFSS STATUS,Z ; Skip if they are equal
BCF ALARMNOW ; They are not equal so clear alarm bit
CALL task_scan ; Scan the next LED digit.
MOVF TMR_SEC_LD,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if this digit is zero
BCF EGGNOW ; Timer is not zero so clear egg alarm bit
MOVF TMR_SEC_HD,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if this digit is zero
BCF EGGNOW ; Timer is not zero so clear egg alarm bit
MOVF TMR_MIN_LD,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if this digit is zero
BCF EGGNOW ; Timer is not zero so clear egg alarm bit
CALL task_scan ; Scan the next LED digit.
MOVF TMR_MIN_HD,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if this digit is zero
BCF EGGNOW ; Timer is not zero so clear egg alarm bit
BTFSS EGGNOW ; Skip if we are still at EGG Time
BSF EGGOK ; If we are not at EGG time, re-set egg alarm
BTFSS ALARMNOW ; Skip if we are still at Alarm time
BSF ALARMOK ; If we are not at Alarm time, re-set alarm
CALL task_scan ; Scan the next LED digit.
RETLW 0
; ****************************************
; * Incriment the clock, timer or alarm *
; ****************************************
inc_time
MOVWF FSR ; Add one to clock second counter
CALL task_scan ; Scan the next LED digit.
INCF INDADDR ; Add one to minute lower digit
MOVLW SEC_MAX ; Place second max value into w
SUBWF INDADDR,W ; CLOCK_SEC - SEC_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
RETLW 0 ; We are done so let's get out of here!
CLRF CLK_SEC ; Clear CLK_second counter
INCF FSR ; Move to the next digit
INCF INDADDR ; Add 1 to minute LOW digit
GOTO skip_min_fsr ; Jump to the next digit
inc_min_ld
MOVWF FSR
INCF INDADDR ; Add 1 to minute LOW digit
skip_min_fsr
CALL task_scan ; Scan the next LED digit.
MOVLW MIN_LD_MAX ; Place minute lower digit max value into W
SUBWF INDADDR,W ; CLK_MIN_LD - MIN_LD_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
RETLW 0 ; We are done so let's get out of here!
CLRF INDADDR ; Clear CLK minute low digit
INCF FSR ; Move to the minute high digit
INCF INDADDR ; Add one to minute high digit
inc_min_hd
CALL task_scan ; Scan the next LED digit.
MOVLW MIN_HD_MAX ; Place minute high digit max value into W
SUBWF INDADDR,W ; CLK_MIN_HD - MIN_HD_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
RETLW 0 ; We are done so let's get out of here!
CLRF INDADDR ; Clear CLK minute high digit
INCF FSR ; Move to the hour low digit
INCF INDADDR ; Add one to hour low digit
GOTO skip_hour_fsr ; Jump to the next digit
inc_hour_ld
MOVWF FSR
INCF FSR
INCF FSR
INCF INDADDR ; Add 1 to minute LOW digit
skip_hour_fsr
CALL task_scan ; Scan the next LED digit.
MOVLW MIN_LD_MAX ; Place hour lower digit max value into W
SUBWF INDADDR,W ; CLK_HOUR_LD - HOUR_LD_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
GOTO check_inc ; We need to check for overflow
CLRF INDADDR ; Clear CLK hour low digit
INCF FSR ; Move to the hour high digit
INCF INDADDR ; Add one to hour high digit
GOTO inc_hour_hd
check_inc
INCF FSR ; Move to hour high digit
inc_hour_hd
CALL task_scan ; Scan the next LED digit.
MOVLW HOUR_HD_MAX ; Place hour high digit max value into W
BTFSC FLAGS,1
GOTO off_mode1
BTFSC FLAGS,0
MOVLW MIN_LD_MAX-1
off_mode1
SUBWF INDADDR,W ; CLK_HOUR_HD - HOUR_HD_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
RETLW 0 ; We are done so let's get out of here!
DECF FSR ; Move to the hour low digit
CALL task_scan ; Scan the next LED digit.
MOVLW HOUR_LD_MAX ; Place hour high digit max value into W
BTFSC FLAGS,1
GOTO off_mode2
BTFSC FLAGS,0
MOVLW 0 ; Clear W
off_mode2
SUBWF INDADDR,W ; CLK_HOUR_HD - HOUR_HD_MAX -> W
BTFSS STATUS,C ; Skip if there is an overflow
RETLW 0 ; We are done so let's get out of here!
CALL task_scan ; Scan the next LED digit.
CLRF INDADDR ; Clear hour high digit
BTFSC FLAGS,1
GOTO off_mode3
BTFSS FLAGS,0
off_mode3
NOP
INCF FSR ; Move to the hour high digit
CLRF INDADDR ; Clear one hour low digit
CALL task_scan
RETLW 0 ; We are done so let's get out of here!
dec_hour_ld
GOTO dec_hour_ld_vect ; ran out of CALL space....
; ****************************************
; * Decriment the clock, alarm or timer *
; ****************************************
dec_time
dec_min_ld
MOVWF FSR ; Set up pointer for indirect address
CALL task_scan ; Scan the next LED digit.
DECF INDADDR,F ; Subtract one from CLK_MIN_LD
COMF INDADDR,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if CLK_MIN_LD is zero
RETLW 0 ; We are done... Let's get out of here
MOVLW MIN_LD_MAX - 1 ; Place minute lower digit max value into W
MOVWF INDADDR ; MIN_LD_MAX -> CLK_MIN_LD
dec_min_hd
CALL task_scan ; Scan the next LED digit.
INCF FSR ; Move the pointer to Min HIGH DIGIT
DECF INDADDR,F ; Subtract one from CLK_MIN_HD
COMF INDADDR,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if CLK_MIN_LD is zero
RETLW 0 ; We are done... Let's get out of here
MOVLW MIN_HD_MAX - 1 ; Place minute lower digit max value into W
MOVWF INDADDR ; MIN_HD_MAX -> CLK_MIN_HD
CALL task_scan ; Scan the next LED digit.
INCF FSR ; Move the pointer to Hour LOW DIGIT
GOTO skip_dhour_fsr ; Jump to the next digit
dec_hour_ld_vect
MOVWF FSR
INCF FSR
INCF FSR
CALL task_scan ; Scan the next LED digit.
skip_dhour_fsr
DECF INDADDR,F ; Subtract one from CLK_HOUR_LD
COMF INDADDR,W ; Set the Z bit to check for zero
BTFSS STATUS,Z ; Skip if CLK_MIN_LD is zero
GOTO check_hour
MOVLW MIN_LD_MAX - 1 ; Place minute lower digit max value into W
MOVWF INDADDR ; MIN_LD_MAX -> CLK_HOUR_LD
INCF FSR ; Move the pointer to Hour HIGH DIGIT
DECF INDADDR,F ; Subtract one from CLK_HOUR_HD
GOTO dec_hour_hd
check_hour
INCF FSR ; Point to hour high digit
dec_hour_hd
CALL task_scan ; Scan the next LED digit.
COMF INDADDR,W
BTFSS STATUS,Z
RETLW 0
CALL task_scan ; Scan the next LED digit.
DECF FSR
MOVLW .9 ; Reset digit to 9
SUBWF INDADDR,W
BTFSS STATUS,Z ; Skip if CLK_MIN_LD is zero
RETLW 0 ; We are done... Let's get out of here
CALL task_scan ; Scan the next LED digit.
INCF FSR
MOVLW HOUR_HD_MAX ; Place minute lower digit max value into W
BTFSS FLAGS,1 ; Skip if CLOCK or ALARM mode
MOVLW .9 ; Reset digit to 9
MOVWF INDADDR ; HOUR_HD_MAX -> CLK_HOUR_HD
MOVLW HOUR_LD_MAX - 1 ; Place minute lower digit max value into W
BTFSS FLAGS,1 ; Skip if CLOCK or ALARM mode
MOVLW .9 ; Reset digit to 9
DECF FSR ; Move the pointer to Min LOW DIGIT
MOVWF INDADDR ; HOUR_LD_MAX -> CLK_HOUR_LD
CALL task_scan ; Scan the next LED digit.
RETLW 0 ; We are done... Let's get out of here
; ****************************************
; * Main loop calls all tasks as needed *
; ****************************************
main_loop
CALL task_scan ; Scan the next LED digit.
MOVF TMR0,W ; Place current TMR0 value into W
XORWF PREVTMR0,W ; Lets see which bits have changed...
MOVWF TEMP ; All changed bits are placed in temp for test
XORWF PREVTMR0,F ; Update Previous TMR0 value.
BTFSS SECBIT ; Skip if it is not time to increment second
GOTO main_loop ; Go back to main loop if 250 mS not passed
MOVLW b'00100000' ; Bits 6 and 5 of FLAGS used as divide by 4
ADDWF FLAGS,F ; Add one to bit 5
BTFSS TIMENOW ; Check bit 7 - if four adds occur, skip
GOTO skip_timer ; One second has not passed - skip timers
CALL task_scan ; Scan the next LED digit.
BCF TIMENOW ; Clear out second passed flag
MOVLW CLK_SEC ; Place pointer to increment clock
CALL inc_time ; Increment the clock
CALL check_time ; Check for alarm or timer conditions
BTFSC EGGNOW ; Do NOT decrease timer if zero
GOTO skip_timer ; Jump out if egg timer is zero
BTFSC UPKEY ; Skip if UP key is NOT pressed
GOTO skip_timer ; Jump out if UP key is pressed
BTFSC DOWNKEY ; Skip if DOWN key is NOT pressed
GOTO skip_timer ; Jump out if DOWN key is pressed
MOVLW TMR_SEC_LD ; Place pointer to decrement timer
CALL dec_time ; Decrement countdown timer
MOVLW ALARMCYCCNT ; Place the number of alarm beeps into W
MOVWF ALARMCNT ; Move beep count to ALARMCNT
skip_timer
BTFSS ALARMOK ; Skip if this is the first pass into alarm
GOTO skip_wakeup ; Second pass - do not re-init ALARMCNT
BTFSS ALARMNOW ; Skip if this is alarm pass
GOTO skip_wakeup ; Countdown timer - do not re-init ALARMCNT
MOVLW ALARMCYCCNT ; Place the number of alarm beeps into W
MOVWF ALARMCNT ; Move beep count to ALARMCNT
BCF ALARMOK ; Clear flag for second pass
skip_wakeup
CALL task_scan ; Scan the next LED digit.
BTFSC ALARMNOW ; Skip if alarm clock is not set
GOTO send_alarm ; Blast out a beep
BTFSC EGGNOW ; Skip if countdown timer is not alarming
GOTO send_alarm ; Blast out a beep
GOTO skip_alarm ; Skip beeping and continue
send_alarm
MOVF ALARMCNT,W ; Place ALARMCNT into W
BTFSC STATUS,Z ; Skip if not zero
GOTO skip_alarm ; We are done beeping - skip and continue
DECFSZ ALARMCNT,F ; Decriment beep count and skip when zero
CALL buzz_now ; Blast out the beep!!!
skip_alarm
BTFSS FLAGS,5 ; Skip if it is time to scan the keys 1/2 sec
goto finish_update ; Jump to finish updates - don't scan
CALL scan_keys ; Scan the keys and load value into KEYPAT
CALL task_scan ; Scan the next LED digit.
BTFSS MODEKEY ; Skip if the MODEKEY is pressed
GOTO same_mode ; Not pressed so it is the same mode...
BTFSS MODEKEYCHG ; Skip if the is pressing edge
GOTO same_mode ; Button is held so it is the same mode...
INCF FLAGS ; Advance the mode by incrimenting bits 0,1
BCF FLAGS,2 ; Force mode to wrap-around by clearing bit 2
CALL turnon_scan ; Mode button pressed - must turn on LEDs
same_mode
call task_scan ; Scan the next LED digit.
BTFSC UPKEY ; Skip if the UP key is not pressed
GOTO serve_up_key ; UP key is pressed - jump to serve it!
BTFSC DOWNKEY ; Skip if the DOWN key is not pressed
GOTO serve_down_key ; DOWN key is pressed - jump to serve it!
MOVLW INIT_MODE_COUNT ; UP and DOWN not pressed - re-init mode count
MOVWF MODE_COUNT ; Change back to lower digits for setting
MOVF DISPONCNT,F ; Update Z bit in STATUS reg display on time
BTFSS STATUS,Z ; Skip if displays should be OFF
DECF DISPONCNT ; Decriment display ON counter
BTFSS STATUS,Z ; Skip if displays should be OFF
GOTO finish_update ; Displays are ON - jump to finish updates
BCF FLAGS,0 ; Restore the mode to displays OFF
BCF FLAGS,1 ; Restore the mode to displays OFF
CLRF PORTB ; Clear out segment drives on PORTB
CLRF PORTA ; Clear out common digit drives on PORTA
GOTO finish_update ; Jump to finish updates
serve_up_key
call task_scan ; Scan the next LED digit.
BTFSC FLAGS,0 ; Skip if not in TIMER or CLOCK mode
GOTO no_up_display ; Currently in TIMER or CLOCK - keep mode
BTFSC FLAGS,1 ; Skip if not in ALARM mode
GOTO no_up_display ; Currently in ALARM - keep mode
BSF FLAGS,0 ; Set to CLOCK mode
BSF FLAGS,1 ; Set to CLOCK mode
no_up_display
CLRF ALARMCNT ; A key was pressed, so turn off alarm
call turnon_scan ; Turn on the LEDs
BTFSS MODEKEY ; Skip if MODE is pressed as well
GOTO finish_update ; MODE is not pressed - jump to finish update
MOVF MODE_COUNT,W ; Update STATUS Z bit for mode count
BTFSS STATUS,Z ; Skip if we have counted down to zero
DECF MODE_COUNT ; Decriment the mode count
call task_scan ; Scan the next LED digit.
MOVF MODE_COUNT,W ; Update the Z bit to check for zero
BTFSS STATUS,Z ; Skip if we have incrimented for 7 times
GOTO serve_min_up ; Incriment the minutes digits
DECF FLAGS,W ; Place current mode into W
CALL mode_timer ; Look-up register RAM address for current mode
CALL inc_hour_ld ; Add one hour to the current display
GOTO finish_update ; Jump to finish updates
serve_min_up
call task_scan ; Scan the next LED digit.
DECF FLAGS,W ; Place current mode into W
CALL mode_timer ; Look-up register RAM address for current mode
CALL inc_min_ld ; Add one minute to the current display
GOTO finish_update ; Jump to finish updates
serve_down_key
call task_scan ; Scan the next LED digit.
BTFSC FLAGS,0 ; Skip if not in TIMER or CLOCK mode
GOTO no_dn_display ; Currently in TIMER or CLOCK - keep mode
BTFSC FLAGS,1 ; Skip if not in ALARM mode
GOTO no_dn_display ; Currently in ALARM - keep mode
BSF FLAGS,0 ; Set to CLOCK mode
BSF FLAGS,1 ; Set to CLOCK mode
no_dn_display
CLRF ALARMCNT ; A key was pressed, so turn off alarm
CALL turnon_scan ; Turn on the LEDs
BTFSS MODEKEY ; Skip if MODE is pressed as well
GOTO finish_update ; MODE is not pressed - jump to finish update
MOVF MODE_COUNT,W ; Update STATUS Z bit for mode count
BTFSS STATUS,Z ; Skip if we have counted down to zero
DECF MODE_COUNT ; Decriment the mode count

call task_scan ; Scan the next LED digit.
MOVF MODE_COUNT,W ; Update the Z bit to check for zero
BTFSS STATUS,Z ; Skip if we have incrimented for 7 times
GOTO serve_min_down ; Decriment the minutes digits
DECF FLAGS,W ; Place current mode into W
CALL mode_timer ; Look-up register RAM address for current mode
CALL dec_hour_ld ; Subtract one hour from the current display
GOTO finish_update ; Jump to finish updates
serve_min_down
DECF FLAGS,W ; Place current mode into W
CALL mode_timer ; Look-up register RAM address for current mode
CALL dec_min_ld ; Subtract one minute from the current display
finish_update
call task_scan ; Scan the next LED digit.
BTFSC FLAGS,0 ; Skip if in mode OFF or ALARM
GOTO new_display ; Jump to update LED display registers
BTFSC FLAGS,1 ; Skip if in mode OFF
GOTO new_display ; Jump to update LED display registers
CLRF DISPSEGS_A ; Clear display regs to Shut off LED display
CLRF DISPSEGS_B ; Clear display regs to Shut off LED display
CLRF DISPSEGS_C ; Clear display regs to Shut off LED display
CLRF DISPSEGS_D ; Clear display regs to Shut off LED display
GOTO main_loop ; We are done - go back and do it again!
new_display
DECF FLAGS,W ; Move current mode state into W
CALL mode_timer ; Look-up register address of value to display
CALL disp_value ; Update display registers with new values
GOTO main_loop ; We are done - go back and do it again!

; ****************************************
; * Set up and initialize the processor *
; ****************************************
init
MOVLW OPTION_SETUP ; Place option reg setup into W
OPTION ; Set up OPTION register
MOVLW PORTA ; Place beginning of RAM/Port location into W
MOVWF FSR ; Now initialize FSR with this location
clear_mem
CLRF INDADDR ; Clear the FSR pointed memory location
INCFSZ FSR ; Point to the next location
GOTO clear_mem ; Jump back to clear memory routine
BSF ALM_HOUR_LD,3 ; Place 8:00 into alarm register
INCF CLK_HOUR_LD ; Place 1:00 into clock register
MOVLW 0EEh ; Turn on display A scan line, others off
MOVWF PREVSCAN ;
CLRW
TRIS PORTB ; Make all Port B pins outputs.
TRIS PORTA ; Make all Port A pins outputs.
BSF FLAGS,1 ; Set up current mode to CLOCK, display ON
BSF FLAGS,0
BCF ALARMOK ; Don't want to trigger alarms
BCF EGGOK
BSF DISPON ; Turn on the displays
mfg_checkkey
CALL scan_keys ; Lets see what is pressed
BTFSS UPKEY ; Goto self-test if UP key is pressed at pwr up
GOTO main_loop ; Normal operation - Jump to the main loop
; *****************************************************************
; * Self-test code for manufacturing only - test buttons and LEDs *
; *****************************************************************
mfg_selftest
MOVLW b'01110000' ; Place all key on pattern into W
MOVWF CLK_MIN_HD ; Use CLK_MIN_HD for keystuck ON test
CLRF CLK_HOUR_HD ; Use CLK_HOUR_HD for keystuck OFF test
mfg_display
MOVF CLK_SEC,W ; Current segment display count -> W
CALL mfg_led_lookup ; Look-up the next segment pattern to display
MOVWF PORTB ; Move the pattern to PORT B to display it
mfg_timer
MOVF TMR0,W ; Place current TMR0 value into W
XORWF PREVTMR0,W ; Lets see which bits have changed...
MOVWF TEMP ; All changed bits are placed in temp for test
XORWF PREVTMR0,F ; Update Previous TMR0 value.
BTFSS TEMP,7 ; Skip if it is not time to increment second
GOTO mfg_timer ; It is not time to move to next digit - go back
INCF CLK_SEC ; Move to the next display pattern
mfg_check_digit
BTFSS CLK_SEC,5 ; Skip if we have timed out waiting for button
GOTO mfg_doneclk ; Jump to check for the next button press
mfg_nextdigit
CLRF CLK_SEC ; Clear out timer
CALL buzz_now ; Send out a buzzer beep!
BTFSS PREVSCAN,3 ; Skip if we have NOT tested the last digit
GOTO finish_mfg_test ; Jump to the end after last digit tested
RLF PREVSCAN,W ; Select the next digit through a rotate..
RLF PREVSCAN
MOVF PREVSCAN,W ; Place next digit select into W
MOVWF PORTA ; Update port A to select next digit
mfg_doneclk
CALL scan_keys ; Scan the keys to see what is pressed...
MOVF KEYPAT,W ; Place pattern into W
ANDWF CLK_MIN_HD ; Make shure keys are not stuck ON
IORWF CLK_HOUR_HD ; Make shure each key is pressed at least once
BTFSS PREVSCAN,3 ; Skip if we are NOT at the last digit
BSF KEYPAT,7 ; Set flag bit to indicate we are done!
MOVLW .8 ; Place 8 into W
SUBWF CLK_SEC,W ; CLK_SEC - W => W
BTFSS STATUS,C
CLRF KEYPAT
SWAPF KEYPAT
COMF PREVSCAN,W
ANDWF KEYPAT,W
BTFSS STATUS,Z
GOTO mfg_nextdigit
GOTO mfg_display
finish_mfg_test
MOVF CLK_MIN_HD,F
BTFSS STATUS,Z
GOTO bad_switch
MOVF CLK_HOUR_HD,W
XORLW 070h
BTFSS STATUS,Z
GOTO bad_switch
mfg_cleanup
CLRF CLK_HOUR_HD ; Restore temp registers to zero
CLRF CLK_MIN_HD ; Restore temp registers to zero
GOTO main_loop ; Jump to main loop
bad_switch
COMF CLK_MIN_HD,F
SWAPF CLK_MIN_HD,W
MOVWF KEYPAT
BSF CLK_HOUR_HD,7
SWAPF CLK_HOUR_HD,W
ANDWF KEYPAT
MOVLW 07Fh
MOVWF PORTB
CLRF CLK_MIN_LD
BSF CLK_MIN_LD,5
loop_bad_sw
CALL buzz_now_dispon ; Beep the buzzer constantly for a few secs
DECFSZ CLK_MIN_LD ; Decriment counter and skip when done
GOTO loop_bad_sw ; Not done buzzing - go back and do it again
GOTO mfg_cleanup ; Done buzzing - clean-up and run clock
END
]
thanks alot:sad:

i'll be expecting a rply asap pls

Hi there,

Im also tryng to convert the same code but not for 16f84 but 16F628A wich is a better choice. First of all, are you interestet yet? You need a pic simulator, and in the code, you must redirect ram adress, next maybe the PC were not working, or may give you an error, the vectors may be changed, STATUS,PA0 & PA1 must be changed by STATUS, RP0 and STATUS, RP1. etc etc, so Im doing it also... just have to compare de datasheets... and some code that is not in the x14 pics like the TRIS command.

CesarIII

This article has been dead for over six months. Start a new discussion instead.