*** ASSEMBLY SUCCESSFUL ***
0010 AGAIN 009B ALLPSIN 0076 BFCHECK 0085 CHECK_AGAIN
00A5 COMBEGADR 000A COMMAND 0060 COMMON 00A9 CUSTOM_DATA
0003 CWADR 000B DATA 0099 DELAY 000E DISABLE
000F ENABLE 002E NEXTCOM 003E NEXT_BYTE 004C NEXT_CHAR
0004 NUMOFC 0000 PAADR 0082 PACOUTBIN 0090 PAINCOUT
0080 PANDCOUT 0001 PBADR 0002 PCADR 009C PDELAY
000D READ 0053 SENDCHAR 0054 SENDCHARA 005B SENDCOM
005C SENDCOMA 000C WRITE
;********************************************************************
;====================================================================
; Program: custom.asm
; programmer(s): Dincer Aydin
; function:Demonstrates how custom characters are defined and used
;====================================================================
;********************************************************************
; This code requires a 2*16 LCD connected to a 8255 with base address of 00h
; routines sendcomA & sendcom & sendcharA & sendchar have been tested on
; >> 2*16 Hitachi LCD with HD44780 chip
; >> Samsung 1*16 LCD with a KS0062F00 chip
; >> 2*16 Epson LCD marked P300020400 SANTIS 1 ,and
; >> noname 1*16 HD44780 based LCD.
; The Z80 was clocked at 2 MHz and 4,9152 MHz for each display.This was done
; because the routines mentioned above take many t states and in most cases
; that will be longer that the time a HD44780 will need to execute a command.
;
; Connections:
; LCD data bus(pins #14-#7) connected to Port A of a 8255 with 00h 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 address(base 00h):
0000 PAADR EQU 00H ; Address of PortA
0000 PBADR EQU 01H ; Address of PortB
0000 PCADR EQU 02H ; Address of PortC
0000 CWADR EQU 03H ; Address of Control Word
;stuff to be written into the control word of the 8255:
;Some of the change the state of the ports and some manipulate
;bits on port C
0000 ALLPSIN EQU 9BH ; set all ports to input mode
0000 PAINCOUT EQU 90H ; A input,C output,B output
0000 PANDCOUT EQU 80H ; set all ports to output mode
0000 PACOUTBIN EQU 82H ; A output,C output,B input
;bit set/reset commands.These bits are the control signals for the LCD
0000 ENABLE EQU 0FH ; set portC bit #6
0000 DISABLE EQU 0EH ; reset portC bit #6
0000 READ EQU 0DH ; set portC bit #5
0000 WRITE EQU 0CH ; reset portC bit #5
0000 COMMAND EQU 0AH ; reset portC bit #4
0000 DATA EQU 0BH ; set portC bit #4
; Define number of commands and length of string data
0000 NUMOFC EQU 4H ; number of commands
; initialization:
0000 31 00 02 LD SP,200H ; Set stack pointer
0003 0E 03 LD C,CWADR
0005 3E 82 LD A,PACOUTBIN ; Ports A&C output,B input
0007 ED 79 OUT (C),A
; *********It all begins here**********:
; This part sends commands to initialize the LCD
0009 CD 99 00 CALL DELAY
000C 3E 38 LD A,38H ; function set command
000E 06 04 LD B,4
0010 0E 03 AGAIN: LD C,CWADR
0012 16 0A LD D,COMMAND
0014 ED 51 OUT (C),D ; select the instruction register
0016 16 0C LD D,WRITE
0018 ED 51 OUT (C),D ; reset RW pin for writing to LCD
001A D3 00 OUT (PAADR),A ; place the command into portA
001C 16 0F LD D,ENABLE
001E ED 51 OUT (C),D ; enable the LCD
0020 16 0E LD D,DISABLE
0022 ED 51 OUT (C),D ; disable the LCD
0024 CD 99 00 CALL DELAY ; wait for a while
0027 10 E7 DJNZ AGAIN ; loop till the command is sent 4 times
; send commands to set input mode, cursor,number of lines ,and etc.
0029 21 A5 00 LD HL,COMBEGADR ; set HL to point the first command
002C 06 04 LD B,NUMOFC ; put the number of commands to be sent in B
002E CD 5B 00 NEXTCOM: CALL SENDCOM ; send (HL) as a command
0031 23 INC HL ; point the next command
0032 10 FA DJNZ NEXTCOM ; loop till all commands are sent
; The code below will modify CG RAM contents to define 8 custom characters
0034 21 A9 00 LD HL,CUSTOM_DATA ; make (HL) point custom character data
0037 3E 40 LD A,40H
0039 CD 5C 00 CALL SENDCOMA ; Set CG RAM address to 00h by sendind 40h as a command
003C 06 40 LD B,40H ; use B to count number of bytes to be written to CG RAM
; 8 characters * 8 bytes = 64 bytes (40h) in this example
003E CD 53 00 NEXT_BYTE: CALL SENDCHAR ; write (HL) to CG RAM
0041 23 INC HL ; point the next byte to be written to CG RAM
0042 10 FA DJNZ NEXT_BYTE ; loop till all bytes are sent
; Now that custom characters are defined , let's see them on the LCD screen
; The code below will print characters 0-7 (the ones we defined) to LCD screen
0044 06 08 LD B,8H ; use B to count the number of bytes to be written to DD RAM
0046 3E 80 LD A,80H
0048 CD 5C 00 CALL SENDCOMA ; Set DD RAM adres to 00h by sending 80h as a command
004B AF XOR A ; clear a
004C CD 54 00 NEXT_CHAR: CALL SENDCHARA ; print ASCII character corresponding to the value in A
004F 3C INC A
0050 10 FA DJNZ NEXT_CHAR ; loop till ASCII characters 0-7 are sent to the LCD
0052 76 HALT
; ====================================================================
; Subroutine name:sendcomA & sendcom & sendcharA & sendchar
; programmer:Caner Buyuktuna & Dincer Aydin
; input:A or (HL)
; output:
; Registers altered:A
; function: sendcharA sends the data in A to the LCD
; sendchar sends the data in (HL) to the LCD
; sendcomA sends the command in A to the LCD
; sendcom sends the command in (HL) to the LCD
; ====================================================================
0053 7E SENDCHAR: LD A,(HL) ; put the data to be sent to the LCD in A
0054 C5 SENDCHARA: PUSH BC ; save BC
0055 D5 PUSH DE ; save DE
0056 1E 0B LD E,DATA ;
0058 C3 60 00 JP COMMON
005B 7E SENDCOM: LD A,(HL)
005C C5 SENDCOMA: PUSH BC ; save BC
005D D5 PUSH DE ; save DE
005E 1E 0A LD E,COMMAND
0060 CD 76 00 COMMON: CALL BFCHECK ; See if the LCD is busy. If it is busy wait,till it is not.
0063 ED 59 OUT (C),E ; Set/reset RS accoring to the content of register E
0065 16 0C LD D,WRITE
0067 ED 51 OUT (C),D ; reset RW pin for writing to LCD
0069 D3 00 OUT (PAADR),A ; place data/instrucrtion to be written into portA
006B 16 0F LD D,ENABLE
006D ED 51 OUT (C),D ; enable the LCD
006F 16 0E LD D,DISABLE
0071 ED 51 OUT (C),D ; disable the LCD
0073 D1 POP DE ; restore DE
0074 C1 POP BC ; restore BC
0075 C9 RET ; return
; ====================================================================
; Subroutine name:bfcheck
; programmer:Dincer Aydin
; input:
; output:
; Registers altered:D
; function:Checks if the LCD is busy and waits until it is not busy
; ====================================================================
0076 F5 BFCHECK: PUSH AF ; save AF
0077 0E 03 LD C,CWADR
0079 16 90 LD D,PAINCOUT
007B ED 51 OUT (C),D ; make A input,C output,B output
007D 16 0D LD D,READ
007F ED 51 OUT (C),D ; set RW pin for reading from LCD
0081 16 0A LD D,COMMAND
0083 ED 51 OUT (C),D ; select the instruction register
0085 16 0F CHECK_AGAIN: LD D,ENABLE
0087 ED 51 OUT (C),D ; enable the LCD
0089 DB 00 IN A,(PAADR) ; read from LCD
008B 16 0E LD D,DISABLE
008D ED 51 OUT (C),D ; disable the LCD
008F 07 RLCA ; rotate A left through C flag to see if the busy flag is set
0090 DA 85 00 JP C,CHECK_AGAIN ; if busy check it again,else continue
0093 16 80 LD D,PANDCOUT
0095 ED 51 OUT (C),D ; set all ports to output mode
0097 F1 POP AF ; restore AF
0098 C9 RET
;====================================================================
; Subroutine name:DELAY and PDELAY
; programmer(s):Dincer Aydin
; input:the value in HL (for PDELAY only)
; output:-
; Registers altered:H,L
; function:delay
; for more delay you can add a few nops or or some junk commands using the index
; registers
; pdelay uses what you put into HL before you called the PDELAY routine
;====================================================================
0099 21 10 10 DELAY: LD HL,1010H
009C 2D PDELAY: DEC L
009D C2 9C 00 JP NZ,PDELAY
00A0 25 DEC H
00A1 C2 9C 00 JP NZ,PDELAY
00A4 C9 RET
;====================================================================
; commands and strings
00A5 01 80 0C 06 COMBEGADR: DB 01H,80H,0CH,06H
; clear display,set DD RAM adress,
; turn on display with cursor hidden,set entry mode
; These are the values to create some custom characters
00A9 00 04 02 1F CUSTOM_DATA: DB 0,4,2,31
00AD 02 04 00 00 DB 2,4,0,0
; right arrow
00B1 00 04 08 1F DB 0,4,8,31
00B5 08 04 00 00 DB 8,4,0,0
; left arrow
00B9 04 0E 15 04 DB 4,14,21,4
00BD 04 00 00 00 DB 4,0,0,0
; up arrow
00C1 00 00 00 04 DB 0,0,0,4
00C5 04 15 0E 04 DB 4,21,14,4
; down arrow
00C9 08 14 14 08 DB 8,20,20,8
00CD 05 06 05 05 DB 5,6,5,5
; single-character "OK"
00D1 0E 11 11 1F DB 14,17,17,31
00D5 1B 1B 1F 00 DB 27,27,31,0
; locked (padlock closed)
00D9 0E 10 10 1F DB 14,16,16,31
00DD 1B 1B 1F 00 DB 27,27,31,0
; unlocked (padlock open)
00E1 11 12 17 09 DB 17,18,23,9
00E5 13 04 07 00 DB 19,4,7,0
; single-character "1/2"
; The custom character data above is taken from "LCD Serial Backpack App Note No. 2"
; from Scott Edwards Electronics Inc.
(
geocities.com/siliconvalley/circuit/8882) (
geocities.com/siliconvalley/circuit) (
geocities.com/siliconvalley)