;=======================================================
; Проект 15. Вывод строк на LCD (две строки, таблица символов)
; PIC16F84A, 4 МГц. RB4..RB7 — D4..D7, RB0 — RS, RB1 — E
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

#define RS      PORTB,0
#define E       PORTB,1

        cblock  0x0C
        d1, d2, temp, chr, idx
        endc

        ORG     0x000
        goto    Start

;--- строка 1: "AFON radio" ---
Str1
        addwf   PCL,f
        retlw   'A'
        retlw   'F'
        retlw   'O'
        retlw   'N'
        retlw   ' '
        retlw   'r'
        retlw   'a'
        retlw   'd'
        retlw   'i'
        retlw   'o'
        retlw   0x00            ; признак конца

;--- строка 2: "PIC 16F84A" ---
Str2
        addwf   PCL,f
        retlw   'P'
        retlw   'I'
        retlw   'C'
        retlw   ' '
        retlw   '1'
        retlw   '6'
        retlw   'F'
        retlw   '8'
        retlw   '4'
        retlw   'A'
        retlw   0x00

Start
        bsf     STATUS,RP0
        clrf    TRISB
        bcf     STATUS,RP0
        clrf    PORTB
        call    Delay20ms
        call    LcdInit

        movlw   0x80            ; курсор в начало 1-й строки
        call    LcdCmd
        clrf    idx
Loop1
        movf    idx,w
        call    Str1
        movwf   chr
        movf    chr,w
        btfsc   STATUS,Z        ; конец строки?
        goto    Line2
        movf    chr,w
        call    LcdData
        incf    idx,f
        goto    Loop1

Line2
        movlw   0xC0            ; начало 2-й строки
        call    LcdCmd
        clrf    idx
Loop2
        movf    idx,w
        call    Str2
        movwf   chr
        movf    chr,w
        btfsc   STATUS,Z
        goto    Stop
        movf    chr,w
        call    LcdData
        incf    idx,f
        goto    Loop2
Stop
        goto    Stop

LcdInit
        movlw   0x30
        call    SendNibble
        call    Delay5ms
        movlw   0x30
        call    SendNibble
        call    Delay5ms
        movlw   0x30
        call    SendNibble
        call    Delay5ms
        movlw   0x20
        call    SendNibble
        call    Delay5ms
        movlw   0x28
        call    LcdCmd
        movlw   0x0C
        call    LcdCmd
        movlw   0x06
        call    LcdCmd
        movlw   0x01
        call    LcdCmd
        call    Delay5ms
        return

LcdCmd
        movwf   chr
        bcf     RS
        goto    SendByte
LcdData
        movwf   chr
        bsf     RS
SendByte
        movf    chr,w
        andlw   0xF0
        call    SendNibble
        swapf   chr,w
        andlw   0xF0
        call    SendNibble
        call    Delay5ms
        return

SendNibble
        movwf   temp
        movf    PORTB,w
        andlw   0x0F
        iorwf   temp,w
        movwf   PORTB
        bsf     E
        nop
        nop
        bcf     E
        return

Delay5ms
        movlw   .10
        movwf   d1
X1      movlw   .165
        movwf   d2
X2      nop
        decfsz  d2,f
        goto    X2
        decfsz  d1,f
        goto    X1
        return

Delay20ms
        call    Delay5ms
        call    Delay5ms
        call    Delay5ms
        call    Delay5ms
        return

        END
