;=======================================================
; Проект 39. Программный SPI: сдвиговый регистр 74HC595
; PIC16F84A, 4 МГц
; RB0 — DATA (DS), RB1 — CLOCK (SHCP), RB2 — LATCH (STCP)
; Восемь светодиодов подключены к выходам регистра
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

#define DAT     PORTB,0
#define CLK     PORTB,1
#define LAT     PORTB,2

        cblock  0x0C
        d1, d2, bitcnt, obyte, pattern
        endc

        ORG     0x000
        goto    Start

Start
        bsf     STATUS,RP0
        clrf    TRISB           ; все три линии — выходы
        bcf     STATUS,RP0
        clrf    PORTB
        movlw   b'00000001'
        movwf   pattern

Main
        movf    pattern,w
        call    SpiSend         ; выдвигаем байт в регистр
        call    Delay200ms
        bcf     STATUS,C
        rlf     pattern,f       ; бегущий огонь
        movf    pattern,w
        btfsc   STATUS,Z        ; вышли за край?
        goto    Restart
        goto    Main
Restart
        movlw   b'00000001'
        movwf   pattern
        goto    Main

;--- выдвинуть байт из W, старший бит вперёд ---
SpiSend
        movwf   obyte
        movlw   .8
        movwf   bitcnt
SBit
        btfss   obyte,7         ; готовим бит на линии данных
        goto    S0
        bsf     DAT
        goto    SClock
S0
        bcf     DAT
SClock
        bsf     CLK             ; фронт защёлкивает бит в регистре
        nop
        bcf     CLK
        rlf     obyte,f
        decfsz  bitcnt,f
        goto    SBit
        bsf     LAT             ; переносим данные на выходы
        nop
        bcf     LAT
        return

Delay200ms
        movlw   .150
        movwf   d1
DL1     movlw   .250
        movwf   d2
DL2     nop
        decfsz  d2,f
        goto    DL2
        decfsz  d1,f
        goto    DL1
        return

        END
