;=======================================================
; Проект 20. Прерывание по переполнению TMR0
; PIC16F84A, 4 МГц. Светодиод RB0 мигает в обработчике,
; основная программа свободна (мигает вторым светодиодом RB1)
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

        cblock  0x0C
        w_temp, s_temp          ; сохранение контекста
        ovf, d1, d2
        endc

        ORG     0x000
        goto    Start

;--- вектор прерывания ---
        ORG     0x004
        movwf   w_temp          ; сохраняем W
        swapf   STATUS,w
        movwf   s_temp          ; сохраняем STATUS

        btfss   INTCON,T0IF     ; наше ли прерывание?
        goto    IsrEnd
        bcf     INTCON,T0IF
        decfsz  ovf,f
        goto    IsrEnd
        movlw   .8
        movwf   ovf             ; перезаряжаем счётчик
        movlw   b'00000001'
        xorwf   PORTB,f         ; мигаем светодиодом RB0
IsrEnd
        swapf   s_temp,w        ; восстанавливаем STATUS
        movwf   STATUS
        swapf   w_temp,f
        swapf   w_temp,w        ; восстанавливаем W
        retfie

Start
        bsf     STATUS,RP0
        clrf    TRISB
        movlw   b'00000111'     ; предделитель 1:256 на TMR0
        movwf   OPTION_REG
        bcf     STATUS,RP0
        clrf    PORTB
        movlw   .8
        movwf   ovf

        bcf     INTCON,T0IF
        bsf     INTCON,T0IE     ; разрешаем прерывание от TMR0
        bsf     INTCON,GIE      ; общее разрешение прерываний

Main                            ; фоновая задача идёт своим темпом
        movlw   b'00000010'
        xorwf   PORTB,f
        call    Delay
        goto    Main

Delay
        movlw   .200
        movwf   d1
DL1     movlw   .250
        movwf   d2
DL2     nop
        decfsz  d2,f
        goto    DL2
        decfsz  d1,f
        goto    DL1
        return

        END
