;************************************************************************
;                                                                       *
;   Filename:      BA_L8-Count_7seg_x1.asm                              *
;   Date:          8/11/09                                              *
;   File Version:  1.4                                                  *
;                                                                       *
;   Author:        David Meiklejohn                                     *
;   Company:       Gooligum Electronics                                 *
;                                                                       *
;************************************************************************
;                                                                       *
;   Architecture:  Baseline PIC                                         *
;   Processor:     16F505                                               *
;                                                                       *
;************************************************************************
;                                                                       *
;   Files required: delay10.asm         (provides W x 10ms delay)       *
;                   stdmacros-base.inc  (provides DelayMS macro)        *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 8, example 1a                                *
;                                                                       *
;   Demonstrates use of lookup tables to drive 7-segment display        *
;                                                                       *
;   Single digit 7-segment LED display counts repeating 0 -> 9          *
;   1 second per count, with timing derived from int 4MHz oscillator    *
;                                                                       *
;************************************************************************
;                                                                       *
;   Pin assignments:                                                    *
;       RB2, RC0-5 - 7-segment display (common cathode)                 *
;                                                                       *
;************************************************************************

    list        p=16F505 
    #include    <p16F505.inc>
    #include    <stdmacros-base.inc> ; DelayMS - delay in milliseconds

    radix       dec


;***** EXTERNAL LABELS
    EXTERN      delay10_R       ; W x 10ms delay


;***** CONFIGURATION
                ; ext reset, no code protect, no watchdog, 4MHz int clock
    __CONFIG    _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC_RB4EN


;***** VARIABLE DEFINITIONS
        UDATA_SHR
digit   res 1                   ; digit to be displayed


;***** RESET VECTOR *****************************************************
RESET   CODE    0x000           ; effective reset vector
        movwf   OSCCAL          ; update OSCCAL with factory cal value 
        pagesel start
        goto    start           ; jump to main program

;***** Subroutine vectors
delay10                         ; delay W x 10ms
        pagesel delay10_R
        goto    delay10_R       
set7seg                         ; display digit on 7-segment display
        pagesel set7seg_R       
        goto    set7seg_R


;***** MAIN PROGRAM *****************************************************
MAIN    CODE

;***** Initialisation
start  
        clrw                    ; configure PORTB and PORTC as all outputs
        tris    PORTB
        tris    PORTC
        movlw   ~(1<<T0CS)      ; disable T0CKI input
        option                  ;   -> RC5 usable

        clrf    digit           ; start with digit = 0

;***** Main loop
count
        pagesel set7seg         ; display digit
        call    set7seg
 
        DelayMS 1000            ; delay 1s

        incf    digit,f         ; increment digit
        movlw   .10
        xorwf   digit,w         ; if digit = 10
        btfsc   STATUS,Z
        clrf    digit           ;   reset it to 0

        pagesel count           ; repeat forever
        goto    count 


;***** LOOKUP TABLES ****************************************************
TABLES  CODE    0x200           ; locate at beginning of a page

; Lookup pattern for 7 segment display on port B
get7sB  addwf   PCL,f
        retlw   b'000000'       ; 0
        retlw   b'000000'       ; 1
        retlw   b'000100'       ; 2
        retlw   b'000100'       ; 3
        retlw   b'000100'       ; 4
        retlw   b'000100'       ; 5
        retlw   b'000100'       ; 6
        retlw   b'000000'       ; 7
        retlw   b'000100'       ; 8
        retlw   b'000100'       ; 9

; Lookup pattern for 7 segment display on port C
get7sC  addwf   PCL,f
        retlw   b'111111'       ; 0
        retlw   b'011000'       ; 1
        retlw   b'110110'       ; 2
        retlw   b'111100'       ; 3
        retlw   b'011001'       ; 4
        retlw   b'101101'       ; 5
        retlw   b'101111'       ; 6
        retlw   b'111000'       ; 7
        retlw   b'111111'       ; 8
        retlw   b'111101'       ; 9

; Display digit passed in 'digit' variable on 7-segment display
set7seg_R
        movf    digit,w         ; get digit to display
        call    get7sB          ; lookup pattern for port B
        movwf   PORTB           ;   then output it
        movf    digit,w         ; repeat for port C
        call    get7sC
        movwf   PORTC
        retlw   0


        END

