Z80 Build From Scratch

PAGE 18:  Coding for PPI LCD Panel

<< PREV

 

Assembly Code Overview: setup PPI

This first chunk of code of PPI.asm will setup the PPI.

We have skipped over the first 47 lines of background information.

 

; Connections
; LCD Data bus (pins #14-#7) connected to Port A of a 8255 with $08 base address
; LCD Enable pin (#6) connected to Port C bit #7
; LCD R/W pin (#5) connected to Port C bit #6
; LCD RS pin (#4) connected to Port C bit #5

 

; 8255 Port Addresses (base $08)

base .EQU $08               ; UART is at address $00 and PPI is at $08.

pAadr .EQU base + 0     ; Address of PortA.
pBadr .EQU base + 1     ; Address of PortB.
pCadr .EQU base + 2     ; Address of PortC.
CWRadr .EQU base + 3 ; Address of Control Word Register (CWR).

 

;8255 Port Configuration Mode
pAoChoCliBo .EQU $81   ; A out, C high out, C low in, B out.
pAiChoCliBo .EQU  $91    ; A in, C high out, C low in, B out. Used by busy-check function.
 

;8255 Bit Configuration Mode

; Bit set/reset Commands for the E, RW, RS LCD lines:
; NOTE: With bit 7 being 0 instead of 1, we are in Bit Config Mode and not Port Config Mode.
; These commands will apply to only Port C:
Command .EQU $0a   ; Reset LCD bit #4 portC bit #5 (RS)  0000 101-0
Data           .EQU $0b   ; Set LCD bit #4 portC bit #5 (RS)       0000 101-1
Write         .EQU $0c   ; Reset LCD bit #5 portC bit #6 (RW) 0000 110-0
Read          .EQU $0d   ; Set LCD bit #5 portC bit #6 (RW)     0000 110-1
Disable       .EQU $0e   ; Reset LCD bit #6 portC bit #7 (E)     0000 111-0
Enable        .EQU $0f     ; Set LCD bit #6 portC bit #7 (E)        0000 111-1

 

; Define number of Commands and length of string Data
numComm .EQU $4     ; Number of Commands.
numData    .EQU $10   ; Number of string bytes.

 

; Initialize RAM and 8255
    LD SP, $FFFF               ; Set stack pointer to top of RAM.
    LD C, CWRadr
    LD A, pAoChoCliBo   ; Port mode config cmd to 8255: A out, C high out, C low in, B out.
    OUT (C), A

 

REPEAT: CALL Delay

 

Assembly Code Overview: configure LCD

The next chunk of code will be LCD configuration.

 

; Config the LCD
    LD A, $38           ; Function set Command: 8-bit mode, AC=0, 2 lines, 5x7 characters.

 

initLCD:

    LD C, CWRadr
    LD D, Command  
    OUT (C), D           ; Set RS low for command (select the instruction register).
    LD D, Write
    OUT (C), D           ; Reset RW pin for writing to LCD.
    OUT (pAadr), A    ; Place the 38h Command into portA.
    LD D, Enable        ; Start LCD pulse.
    OUT (C), D           ; ......Enable the LCD.
    Call Delay            ; ......Slow the pulse.
    LD D, Disable       ; ......Disable the LCD.
    OUT (C), D           ; End LCD pulse.

 

 

 

 

 

 

 

 

 

 

NEXT >>

 

 

Assembly Code Overview: send commands and data

 

; This part sends 4 Commands to the LCD (clear display, set DD RAM address, turn on display with
; cursor hidden, and set entry mode 6):
    LD HL, CmndBeginAdr                  ; Set HL to point the first Command.
    LD B, numComm                           ; Put the number of Commands to be sent in B.
nextComm:

    CALL sendCommHL                       ; Send (HL) as a Command.
    INC HL                                           ; Point to the next Command.
    DJNZ nextComm                            ; Loop until all 4 Commands are sent.

 

; This part sends Data strings to the LCD
    LD HL, DataBegAdr    ; Set HL to point the first string byte.
    LD B, numData           ; Put the number of string Data bytes to be sent in B.
nextData:

    CALL sendDataHL       ; Send (HL) as string Data.
    INC HL                         ; Point to the next string byte.
    DJNZ nextData            ; Loop until all string bytes are sent.
    ;HALT
    JP REPEAT

 

; sendDataA sends the Data in A to the LCD.

; sendDataHL sends the Data in (HL) to the LCD.
; sendCommA sends the Command in A to the LCD.

; sendCommHL sends the Command in (HL) to the LCD.
sendDataHL:
                      LD A, (HL)    ; Put the Data to be sent to the LCD in A.
sendDataA:
                       PUSH BC     ; Save BC and DE on Stack.
                       PUSH DE
                       LD E, Data
                       JP Common

sendCommHL:
                       LD A,(HL)
sendCommA:
                       PUSH BC      ; Save BC & DE on Stack.
                       PUSH DE

 

Common:                ; Removed BusyCheck.
    OUT (C), E          ; Set/reset RS according to the content of register E (Command or Data).
    LD D, Write
    OUT (C), D          ; Reset RW pin (low) for writing to LCD.
    OUT (pAadr), A   ; Place Data/instruction to be written into portA.
    PUSH HL              ; ------------Save HL (HL is also used by Delay).
    CALL longDelay   ; ------------Delay added between character reads can create a scroll effect.
    POP HL                ; ------------Recover HL.
    LD D, Enable       ; Start LCD pulse.
    OUT (C), D           ; ......Enable the LCD.
    LD D, Disable       ; ......Disable the LCD.
    OUT (C), D           ; End LCD pulse.
    POP D                  ; Restore DE.
    POP BC                ; Restore BC.
    RET                      ; Return to CALLer.

; pDelay uses what you put in HL before you called the PDelay routine.
longDelay:
    LD HL, $3F3F
    JP pDelay
Delay:
    LD HL, $0200       ; Originally $1010. $0200 is adequate to avoid busy-check function.

                                ; $3F3F = slow scroll.

pDelay:
    DEC L
    JP NZ, pDelay
    DEC H
    JP NZ, pDelay
    RET                       ; Return to CALLer.

; 4 Commands and 16-character string
CmndBeginAdr:
    .db $01,$80,$0c,$06  ; Clear display, set DD RAM address, turn on display with cursor hidden,
                                       ; and set entry mode
DataBegAdr:
    .db $20h,$21,$21,$20,$5a,$65,$64,$38,$30,$2e,$63,$6F,$6D,$20,$21,$21 ; !! Zed80.com !!
                                       ; 0 1 2 3 4 5 6 7 8 9 a b c d e f

.END

 

 << PREVNEXT >>

 

TOP

 

HOME

 

Updated 2025-12-17