Subversion Repositories MB01 Project

Rev

Blame | Last modification | View Log | Download | RSS feed

; LCD.ASM
; PROGETTO: B1601
; Compilatore Avocet X6502

; Gestione LCD


_CHIP_INC_      .SET    1
_KEYB_INC_      .SET    1


        .INCLUDE inc\global.inc
        .INCLUDE inc\dirp01.inc

        
; BIT di LCDFlag
; maschera 0 0 0 0 1 D C B
LCDFB_B         .EQU    0        ; BLINK cursore
LCDFB_C         .EQU    1       ; Cursore ON/OFF
LCDFB_D         .EQU    2       ; Display ON/OFF
; maschera 0 0 0 1 SC RL X X
LCDFB_RL        .EQU    3       ; Shift Destra/Sinistra
LCDFB_SC        .EQU    4       ; Shift Cursore/Display
; maschera 0 0 0 0 0 1 I/D SH
LCDFB_SH        .EQU    5       ; Shift completo
LCDFB_ID        .EQU    6       ; Incremento/Decremento
LCDFB_R         .EQU    7       ; LCD Ready

LCDMAXCOL       .EQU    20
LCDMAXROW       .EQU    4


;----------------------------------------------------------------------------
; SEGMENTO CODEF8
;----------------------------------------------------------------------------

        .CODEF8
        
        .GLOBAL _LCDFlag, LCDSetup, _LCDAtXY, LCDHex

_LCDFlag        .EQU    (DP01ADDR + LCDFlag)

; NOTA - le funzioni seguenti vanno chiamate in modo 8 bit

        .LONGA  off
        .LONGI  off

; valore T2 VIA per ritardo 2ms
D2MSCNT         .EQU    (2 * 1000 * PHI2)
; valore T2 VIA per ritardo 45us
D45USCNT        .EQU    (45 * PHI2)

; out LCD carattere A at riga X e colonna Y
_LCDAtXY:
        php     
        phd                     ; salva DP
        pea     #DP01ADDR       ; imposta DB
        pld
        CPU08
        jsr     SendLCDAt
        pld                     ; ripristina DP
        plp
        rts

HexDigit:
        and     #$0F
        cmp     #10
        bcc     ?01
        adc     #('A'-11)
        rts
?01:    adc     #'0'
        rts
        
Byte2Hex:
        pha
        lsr     a
        lsr     a
        lsr     a
        lsr     a
        jsr     HexDigit
        tax
        pla
        bra     HexDigit
        
LCDHex:
        php     
        phd                     ; salva DP
        pea     #DP01ADDR       ; imposta DB
        pld
        CPU08
        phx
        phy
        stx     LCDTmp
        jsr     Byte2Hex
        sta     LCDVal
        stx     LCDVal+1
        lda     LCDTmp
        ply
        jsr     SetLCDAddr
        lda     LCDVal+1
        jsr     SendLCDData
        lda     LCDVal
        jsr     SendLCDData
        lda     #' '
        jsr     SendLCDData
        plx
        pld                     ; ripristina DP
        plp
        rts
        
        .GLOBAL LCDHexL, LCDClrXL
        
LCDHexL:
        jsr     LCDHex
        rtl

LCDClrXL:
        jsr     ClearLCDRow
        rtl
        
;----------------------------------------------------------
; LCDSetup - chiamata da IOInit
;----------------------------------------------------------     
; LCDSetup      - Inizializza LCD dopo reset
; In            - A -> flag
; Out           - imposta LCDFlag
; Registri      - A
LCDSetup:
        php     
        phd                     ; salva DP
        pea     #DP01ADDR       ; imposta DB
        pld
        CPU08
        jsr     InitLCD
        pld                     ; ripristina DP
        plp
        rts


; NOTA - le funzioni locali seguenti vanno chiamate con DP = DP01ADDR
; e in modo 8 bit

;----------------------------------------------------------
; ClearLCDRow
;----------------------------------------------------------     
; ClearLCDRow   - Cancella una riga del display
; In            - X = riga da cancellare
; Out           - X = riga da cancellare
; Registri      - nessuno

ClearLCDRow:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     ?03
        cpx     #LCDMAXROW
        bcc     ?01
        ldx     #LCDMAXROW
?01:    pha
        phy
        txa                     ; A = row
        ldy     #0              ; Y = col
        jsr     SetLCDAddr
        ldy     #LCDMAXCOL
?02:    lda     #' '
        jsr     SendLCDData
        dey
        bne     ?02
        txa
        jsr     SetLCDAddr
        ply
        pla
?03:    rts
        

Delay45us:
        ldx     #(.LOW.D45USCNT)
        lda     #(.HIGH.D45USCNT)
        bra     DoDelay
        
Delay2ms:
        ldx     #(.LOW.D2MSCNT)
        lda     #(.HIGH.D2MSCNT)
        
DoDelay:
        stx     VIA0+VIAT2CL
        sta     VIA0+VIAT2CH
        lda     #T2IFRB
?01:    bit     VIA0+VIAIFR             ; test T2 flag
        beq     ?01                     ; attende timeout
        rts

;----------------------------------------------------------
; InitLCD
;----------------------------------------------------------     
; InitLCD       - Inizializza LCD dopo reset
; In            - nessuno
; Out           - imposta LCDFlag
; Registri      - A

InitLCD:
        sta     LCDFlag
        cmp     #0
        beq     ?98
        ;lda    #$80            ; imposta flag LCD presente
        ;tsb    LCDFlag
        ;;bra   ?99
        
        lda     #$38
        clc
        jsr     WriteLCD2
        jsr     Delay45us
        lda     #$0C
        clc
        jsr     WriteLCD2
        jsr     Delay45us

        lda     #$01
        clc
        jsr     WriteLCD2
        jsr     Delay2ms

        lda     #00111000B      ; 8 bit - 4 righe - font 5 x 8
        ;lda    #00110000B      ; 8 bit - 4 righe - font 5 x 8

                lda     #00000010B              ; Incremento - no shift
                ;jsr    SendLCDCmd
                jsr     SetLCDMode
?98:    rts
        
        
?99:
        jsr     OffLCD          ; LCD OFF
        lda     #00111100B      ; 8 bit - 4 righe - font 5 x 8  
        jsr     SendLCDCmd
        jsr     OnLCD           ; LCD ON
        lda     #00000010B      ; Incremento - no shift
        ;jsr    SendLCDCmd
        jsr     SetLCDMode
        bra     ClearLCD        ; cancella display

;----------------------------------------------------------
; SetLCDAddr
;----------------------------------------------------------     
; SetLCDAddr    - Imposta indirizzo DD RAM LCD
; In            - A = riga LCD
;                 Y = colonna LCD
; Out           - DD-RAM LCD impostata
; Registri      - A

SetLCDAddr:
        sty     LCDTmp          ; salva colonna
        clc
        ror     a               ; Bit0 e Bit1 in Bit6 e Bit7
        ror     a
        ror     a
        and     #$C0            ; maschera on bit6 e bit7
        bpl     ?01             ; riga = 0, 1
        ora     #$14            ; riga 2,3 - somma offset
?01:    clc
        adc     LCDTmp          ; somma colonna
        ora     #$80            ; Bit7 = 1 - setta DD RAM
        brl     SendLCDCmd      ; invia comando a LCD
        

;----------------------------------------------------------
; ClearLCD
;----------------------------------------------------------     
; ClearLCD      - cancella LCD
; In            - nessuno
; Out           - nessuno
; Registri      - A

ClearLCD:
        lda     #$01
        brl     SendLCDCmd
        
        
;----------------------------------------------------------
; HomeLCD
;----------------------------------------------------------     
; HomeLCD       - posiziona cursore a 0,0
; In            - nessuno
; Out           - nessuno
; Registri      - A

HomeLCD:
        lda     #$02
        brl     SendLCDCmd


;----------------------------------------------------------
; OnLCD
;----------------------------------------------------------     
; OnLCD         - LCD ON
; In            - nessuno
; Out           - LCDFlag
; Registri      - A
        
OnLCD:
        lda     #LCDFB_D
        tsb     LCDFlag         ; LCDFlag<2>->1 LCD ON
        bra     SetLCDCurs2
        

;----------------------------------------------------------
; CursLCDOn
;----------------------------------------------------------     
; CursLCDOn     - Cursore LCD ON
; In            - nessuno
; Out           - LCDFlag
; Registri      - A
        
CursLCDOn:
        lda     #LCDFB_C
        tsb     LCDFlag         ; LCDFlag<1>->1 CURSORE LCD ON
        bra     SetLCDCurs2
        

;----------------------------------------------------------
; BlinkLCDOn
;----------------------------------------------------------     
; BlinkLCDOn    - Blink Cursore LCD ON
; In            - nessuno
; Out           - LCDFlag
; Registri      - A

BlinkLCDOn:
        lda     #LCDFB_B
        tsb     LCDFlag         ; LCDFlag<0>->1 BLINK CURSORE LCD ON
        bra     SetLCDCurs2

;----------------------------------------------------------
; OffLCD
;----------------------------------------------------------     
; OffLCD        - LCD OFF
; In            - nessuno
; Out           - LCDFlag
; Registri      - A
        
OffLCD:
        lda     #LCDFB_D
        trb     LCDFlag         ; LCDFlag<2>->0 LCD OFF
        bra     SetLCDCurs2


;----------------------------------------------------------
; CursLCDOff
;----------------------------------------------------------     
; CursLCDOff    - Cursore LCD OFF
; In            - nessuno
; Out           - LCDFlag
; Registri      - A
        
CursLCDOff:
        lda     #LCDFB_C
        trb     LCDFlag         ; LCDFlag<1>->0 CURSORE LCD OFF
        bra     SetLCDCurs2

        
;----------------------------------------------------------
; BlinkLCDOff
;----------------------------------------------------------     
; BlinkLCDOff   - Blink Cursore LCD OFF
; In            - nessuno
; Out           - LCDFlag
; Registri      - A
        
BlinkLCDOff:
        lda     #LCDFB_B
        trb     LCDFlag         ; LCDFlag<0>->0 BLINK CURSORE LCD OFF
        bra     SetLCDCurs2


;----------------------------------------------------------
; SetLCDCurs
;----------------------------------------------------------     
; SetLCDCurs    - Imposta cursore e stato on/off LCD
; In            - A: flag -> 0 0 0 0 0 D C B
; Out           - LCDFlag
; Registri      - A
        
SetLCDCurs:
        and     #00000111B      ; maschera on D C B
        sta     LCDTmp          ; salva flag
        lda     LCDFlag
        and     #11111000B      ; maschera off D C B
        ora     LCDTmp          ; nuovo flag
        sta     LCDFlag

        
;----------------------------------------------------------
; SetLCDCurs2 - interna
;----------------------------------------------------------     
; SetLCDCurs2   - Imposta cursore e stato on/off LCD
; In            - nessuno
; Out           - imposta LCD in base ai bit D C B di LCDFlag
; Registri      - A

SetLCDCurs2:
        lda     LCDFlag
        and     #00000111B      ; maschera on D C B
        ora     #00001000B      ; comando cursore
        bra     SendLCDCmd
        
        
;----------------------------------------------------------
; ShiftLCDCursL
;----------------------------------------------------------     
; ShiftLCDCursL - Shifta cursore LCD a sinistra
; In            - nessuno
; Out           - imposta LCDFlag
; Registri      - A
        
ShiftLCDCursL:
        lda     #(LCDFB_SC.OR.LCDFB_RL) ; LCDFlag<4>->0 - Shift Cursore
        trb     LCDFlag                 ; LCDFlag<3>->0 - Shift sinistra
        bra     SetLCDShift2
        

;----------------------------------------------------------
; ShiftLCDCursR
;----------------------------------------------------------     
; ShiftLCDCursR - Shifta cursore LCD a destra
; In            - nessuno
; Out           - imposta LCDFlag
; Registri      - A
        
ShiftLCDCursR:
        lda     #LCDFB_SC
        trb     LCDFlag                 ; LCDFlag<4>->0 - Shift Cursore
        lda     #LCDFB_RL       
        tsb     LCDFlag                 ; LCDFlag<3>->1 - Shift destra
        bra     SetLCDShift2


;----------------------------------------------------------
; ShiftLCDLeft
;----------------------------------------------------------     
; ShiftLCDLeft  - Shifta LCD a sinistra
; In            - nessuno
; Out           - imposta LCDFlag
; Registri      - A
        
ShiftLCDLeft:
        lda     #LCDFB_SC
        tsb     LCDFlag                 ; LCDFlag<4>->1 - Shift Display
        lda     #LCDFB_RL
        trb     LCDFlag                 ; LCDFlag<3>->0 - Shift sinistra
        bra     SetLCDShift2


;----------------------------------------------------------
; ShiftLCDRight
;----------------------------------------------------------     
; ShiftLCDRight - Shifta LCD a destra
; In            - nessuno
; Out           - imposta LCDFlag
; Registri      - A
        
ShiftLCDRight:
        lda     #(LCDFB_SC.OR.LCDFB_RL) ; LCDFlag<4>->1 - Shift Display
        tsb     LCDFlag                 ; LCDFlag<3>->1 - Shift destra
        bra     SetLCDShift2


;----------------------------------------------------------
; ShiftLCD
;----------------------------------------------------------     
; ShiftLCD      - Shifta display e/o cursore
; In            - A: 0 0 0 0 0 0 SC RL
; Out           - imposta LCDFlag
; Registri      - A
        
ShiftLCD:
        and     #00000011B              ; maschera bit SC RL
        asl     a                       ; sposta SC ed RL in Bit4 e Bit3
        asl     a
        asl     a
        sta     LCDTmp
        lda     LCDFlag
        and     #11100111B              ; maschera off SC ed RL del flag
        ora     LCDTmp                  ; imposta nuovo flag
        sta     LCDFlag


;----------------------------------------------------------
; SetLCDShift2 - interna
;----------------------------------------------------------     
; SetLCDShift2  - Shifta display e/o cursore in base a LCDFlag
; In            - nessuno
; Out           - nessuno
; Registri      - A

SetLCDShift2:
        lda     LCDFlag
        and     #00011000B      ; maschera SC ed RL
        lsr     a               ; shifta 1 bit a destra
        ora     #00010000B      ; imposta comando shift
        bra     SendLCDCmd
        
        
;----------------------------------------------------------
; SetLCDMode
;----------------------------------------------------------     
; SetLCDMode    - imposta entry mode LCD
; In            - A: 0 0 0 0 0 0 ID SH
; Out           - imposta LCDFlag
; Registri      - A

SetLCDMode:
        and     #00000011B      ; maschera on bit ID e SH
        pha                     ; salva
        asl     a               ; sposta ID in Bit6
        asl     a
        asl     a
        asl     a
        asl     a
        sta     LCDTmp          
        lda     LCDFlag
        and     #10011111B      ; maschera off bit ID e SH
        ora     LCDTmp          ; imposta nuovo flag
        sta     LCDFlag
        pla                     ; ripristina A
        ora     #00000100b      ; IMPOSTA COMANDO
        
        
;----------------------------------------------------------
; SendLCDCmd - interna
;----------------------------------------------------------     
; SendLCDCmd    - Invia comando a LCD
; In            - A = comando
; Out           - nessuno
; Registri      - A

SendLCDCmd:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     _90
        clc                     ; invia comando

                
;----------------------------------------------------------
; WriteLCD - interna
;----------------------------------------------------------     
; WriteLCD      - Invia comando/data a LCD
; In            - C = 0 -> invia comando
;                 C = 1 -> invia data
;               - A = dato/comando
; Out           - nessuno
; Registri      - A

WriteLCD:
        jsr     WaitLCD         ; attende LCD pronto
WriteLCD2:
        php
        sei
        phx                     ; salva X
        phb                     ; salva DBR
        ldx     #0              ; imposta DBR = 0
        phx
        plb
        ldx     #00000010B      ; E->0, RW->1, RS->0
        stx     PIA1+PIAPRA
        stz     PIA1+PIACRB     ; accesso a DDRB
        ldx     #11111111B      ; pota B in uscita
        stx     PIA1+PIADDRB
        ldx     #00000100B
        stx     PIA1+PIACRB     ; accesso a PRB
        sta     PIA1+PIAPRB     ; dato
        lda     #00000000B      ; E->0, RW->0, RS->0
        bcc     ?01             ; comando - RS = 0
        ora     #00000001B      ; dato - RS = 1
?01:    sta     PIA1+PIAPRA
        ora     #00000100B      ; E->1
        sta     PIA1+PIAPRA
        nop
        nop
        nop
        nop
        and     #11111011B      ; E->0
        sta     PIA1+PIAPRA
        ora     #00000010B      ; RW->1
        sta     PIA1+PIAPRA
        stz     PIA1+PIADDRB    ; porta B in input
        ldx     #00000100B
        stx     PIA1+PIACRB     ; accesso a PRB
        plb                     ; ripristina DBR
        plx
        plp
_90:    rts


;----------------------------------------------------------
; SendLCDData 
;----------------------------------------------------------     
; SendLCDData   - Invia dato a LCD
; In            - A = dato
; Out           - nessuno
; Registri      - A

SendLCDData:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     _90
        sec
        bcs     WriteLCD
        

;----------------------------------------------------------
; SendLCDAt
;----------------------------------------------------------     
; SendLCDAt     - Invia dato a riga/colonna
; In            - A = dato
;                 X = riga
;                 Y = colonna
; Out           - X, Y
; Registri      - A

SendLCDAt:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     _90
        cpx     #LCDMAXROW
        bcc     ?01
        ldx     #LCDMAXROW-1
?01:    cpy     #LCDMAXCOL
        bcc     ?02
        ldy     #LCDMAXCOL-1
?02:    pha                     ; salva dato
        txa                     ; A = row
        jsr     SetLCDAddr
        pla                     ; A = dato
        sec
        bra     WriteLCD
        
        
;----------------------------------------------------------
; WaitLCD - interna
;----------------------------------------------------------     
; WaitLCD       - Attende Busy Flag LCD = 0
; In            - nessuno
; Out           - nessuno
; Registri      - nessuno - P salvato

WaitLCD:
        php                     ; salva P
        pha                     ; salva A
?01:    clc                     ; legge status
        jsr     ReadLCD
        and     #$80            ; test Busy Flag (bit 7)
        bne     ?01             ; attende LCD pronto
        pla                     ; ripristina A
        plp                     ; ripristina P
        rts
        

;----------------------------------------------------------
; GetLCDData
;----------------------------------------------------------     
; GetLCDData    - Legge dato da  LCD
; In            - nessuno
; Out           - A = dato
; Registri      - A

GetLCDData:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     _90
        sec
        
                
;----------------------------------------------------------
; ReadLCD - interna
;----------------------------------------------------------     
; ReadLCD       - Legge status/data da LCD
; In            - C = 0 -> legge status
;                 C = 1 -> legge data
; Out           - A = status/data
; Registri      - A

ReadLCD:
        php
        sei
        phb                     ; salva DBR
        phx                     ; salva X
        ldx     #0              ; imposta DBR = 0
        phx
        plb
        
        stz     PIA1+PIACRB
        stz     PIA1+PIADDRB
        
        ldx     #00000100B
        stx     PIA1+PIACRB     ; accesso a PRB

        lda     #00000010B      ; E->0, RW->1, RS->0
        bcc     ?01             ; legge status
        ora     #00000001B      ; legge dato - RS->1
?01:    sta     PIA1+PIAPRA
        nop
        nop
        nop
        nop
        ora     #00000100B      ; E->1
        sta     PIA1+PIAPRA
        nop
        nop
        nop
        nop
        nop
        nop
?02:    ldx     PIA1+PIAPRB     ; legge bus LCD
        cpx     PIA1+PIAPRB     ; attende lettura stabile
        bne     ?02
        and     #11111011B      ; E->0
        sta     PIA1+PIAPRA
        txa
        plx                     ; ripristina X
        plb                     ; ripristina DBR
        plp
        rts
        
        
;----------------------------------------------------------
; GetLCDAddr
;----------------------------------------------------------     
; GetLCDAddr    - Legge indirizzo corrente da  LCD
; In            - nessuno
; Out           - A = indirizzo
; Registri      - A

GetLCDAddr:
        bit     LCDFlag         ; esce se LCD non presente
        bpl     ?01
        clc                     ; legge status
        jsr     ReadLCD
        and     #01111111B      ; maschera busy flag
?01:    rts