*** ASSEMBLY SUCCESSFUL *** 0010 AGAIN 009B ALLPSIN 00C6 ANIM_DATA 0083 BFCHECK 0092 CHECK_AGAIN 00B2 COMBEGADR 000A COMMAND 006D COMMON 0003 CWADR 003F CYCLE 000B DATA 00B6 DATABEGADR 00A6 DELAY 000E DISABLE 000F ENABLE 002E NEXTCOM 0039 NEXTDATA 004B NEXT_BYTE 0044 NEXT_FRAME 0004 NUMOFC 0010 NUMOFD 0000 PAADR 0082 PACOUTBIN 0090 PAINCOUT 0080 PANDCOUT 0001 PBADR 0002 PCADR 00A9 PDELAY 000D READ 0060 SENDCHAR 0061 SENDCHARA 0068 SENDCOM 0069 SENDCOMA 000C WRITE ;******************************************************************** ;==================================================================== ; Program: Anim_1 ; programmer(s): Dincer Aydin ; function:Demonstrates a simple animation on LCD. ; The animation is a rotating stick and displayed in multiple locations. ;==================================================================== ;******************************************************************** ; 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 0000 NUMOFD EQU 10H ; number of string bytes ; 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 A6 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 A6 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 B2 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 68 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 ; This part sends strings to the LCD: ; Two of the string bytes are ASCII Charater 0 ; This is the first custom character of LCD 0034 21 B6 00 LD HL,DATABEGADR ; set HL to point the first string byte 0037 06 10 LD B,NUMOFD ; put the number of string bytes to be sent in B 0039 CD 60 00 NEXTDATA: CALL SENDCHAR ; send (HL) as string data 003C 23 INC HL ; point the next string byte 003D 10 FA DJNZ NEXTDATA ; loop till all string bytes are sent ; The text and custom character #1 is displayed now ; The code below will modify CG RAM contents to create a simple 4-frame-animation ; This animation routine was tested with Z80 clocked at 2 MHz. For a different clock ; frequency it may be necessary to change the delay paramater. 003F 1E 04 CYCLE: LD E,4H ; use E to count the frames (4 frames in this case) 0041 21 C6 00 LD HL,ANIM_DATA ; make (HL) point custom character data 0044 06 08 NEXT_FRAME: LD B,8H ; each frame has 8 bytes of data 0046 3E 40 LD A,40H 0048 CD 69 00 CALL SENDCOMA ; Set CG RAM address to 00h by sendind 40h as a command 004B CD 60 00 NEXT_BYTE: CALL SENDCHAR ; write (HL) to CG RAM 004E 23 INC HL ; point the next byte to be written to CG RAM 004F 10 FA DJNZ NEXT_BYTE ; loop till 8 bytes (1 frame/custom character) are sent 0051 E5 PUSH HL ; save HL 0052 21 40 40 LD HL,4040H ; put delay parameter for "pdealy" routine into HL 0055 CD A9 00 CALL PDELAY ; A frame was sent. Wait for while so that it can be seen. 0058 E1 POP HL ; restore HL 0059 1D DEC E ; decrease frame counter 005A C2 44 00 JP NZ,NEXT_FRAME ; loop till all frames are sent 005D C3 3F 00 JP CYCLE ; if all frames are sent ,start the the animation again ; ==================================================================== ; 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 ; ==================================================================== 0060 7E SENDCHAR: LD A,(HL) ; put the data to be sent to the LCD in A 0061 C5 SENDCHARA: PUSH BC ; save BC 0062 D5 PUSH DE ; save DE 0063 1E 0B LD E,DATA ; 0065 C3 6D 00 JP COMMON 0068 7E SENDCOM: LD A,(HL) 0069 C5 SENDCOMA: PUSH BC ; save BC 006A D5 PUSH DE ; save DE 006B 1E 0A LD E,COMMAND 006D CD 83 00 COMMON: CALL BFCHECK ; See if the LCD is busy. If it is busy wait,till it is not. 0070 ED 59 OUT (C),E ; Set/reset RS accoring to the content of register E 0072 16 0C LD D,WRITE 0074 ED 51 OUT (C),D ; reset RW pin for writing to LCD 0076 D3 00 OUT (PAADR),A ; place data/instrucrtion to be written into portA 0078 16 0F LD D,ENABLE 007A ED 51 OUT (C),D ; enable the LCD 007C 16 0E LD D,DISABLE 007E ED 51 OUT (C),D ; disable the LCD 0080 D1 POP DE ; restore DE 0081 C1 POP BC ; restore BC 0082 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 ; ==================================================================== 0083 F5 BFCHECK: PUSH AF ; save AF 0084 0E 03 LD C,CWADR 0086 16 90 LD D,PAINCOUT 0088 ED 51 OUT (C),D ; make A input,C output,B output 008A 16 0D LD D,READ 008C ED 51 OUT (C),D ; set RW pin for reading from LCD 008E 16 0A LD D,COMMAND 0090 ED 51 OUT (C),D ; select the instruction register 0092 16 0F CHECK_AGAIN: LD D,ENABLE 0094 ED 51 OUT (C),D ; enable the LCD 0096 DB 00 IN A,(PAADR) ; read from LCD 0098 16 0E LD D,DISABLE 009A ED 51 OUT (C),D ; disable the LCD 009C 07 RLCA ; rotate A left through C flag to see if the busy flag is set 009D DA 92 00 JP C,CHECK_AGAIN ; if busy check it again,else continue 00A0 16 80 LD D,PANDCOUT 00A2 ED 51 OUT (C),D ; set all ports to output mode 00A4 F1 POP AF ; restore AF 00A5 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 ;==================================================================== 00A6 21 10 10 DELAY: LD HL,1010H 00A9 2D PDELAY: DEC L 00AA C2 A9 00 JP NZ,PDELAY 00AD 25 DEC H 00AE C2 A9 00 JP NZ,PDELAY 00B1 C9 RET ;==================================================================== ; commands and strings 00B2 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 ; Custom character 0 "IT IS EASY" Custom character 0 00B6 20 00 20 49 DATABEGADR: DB 20H,00H,20H,49H 00BA 54 20 49 53 DB 54H,20H,49H,53H 00BE 20 45 41 53 DB 20H,45H,41H,53H 00C2 59 20 00 20 DB 59H,20H,00H,20H 00C6 04 04 04 04 ANIM_DATA: DB 4,4,4,4 00CA 04 00 00 00 DB 4,0,0,0 ; | 00CE 10 08 04 02 DB 16,8,4,2 00D2 01 00 00 00 DB 1,0,0,0 ; \ 00D6 00 00 1F 00 DB 0,0,31,0 00DA 00 00 00 00 DB 0,0,0,0 ; - 00DE 01 02 04 08 DB 1,2,4,8 00E2 10 00 00 00 DB 16,0,0,0 ; /