;******************************************************************** ;==================================================================== ; 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): paadr equ 00h ; Address of PortA pbadr equ 01h ; Address of PortB pcadr equ 02h ; Address of PortC 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 allpsin equ 9bh ; set all ports to input mode paincout equ 90h ; A input,C output,B output pandcout equ 80h ; set all ports to output mode pacoutbin equ 82h ; A output,C output,B input ;bit set/reset commands.These bits are the control signals for the LCD enable equ 0fh ; set portC bit #6 disable equ 0eh ; reset portC bit #6 read equ 0dh ; set portC bit #5 write equ 0ch ; reset portC bit #5 command equ 0ah ; reset portC bit #4 data equ 0bh ; set portC bit #4 ; Define number of commands and length of string data numofc equ 4h ; number of commands numofd equ 10h ; number of string bytes ; initialization: ld sp,200h ; Set stack pointer ld c,cwadr ld a,pacoutbin ; Ports A&C output,B input out (c),a ; *********It all begins here**********: ; This part sends commands to initialize the LCD call delay ld a,38h ; function set command ld b,4 again: ld c,cwadr ld d,command out (c),d ; select the instruction register ld d,write out (c),d ; reset RW pin for writing to LCD out (paadr),a ; place the command into portA ld d,enable out (c),d ; enable the LCD ld d,disable out (c),d ; disable the LCD call delay ; wait for a while djnz again ; loop till the command is sent 4 times ; send commands to set input mode, cursor,number of lines ,and etc. ld hl,combegadr ; set HL to point the first command ld b,numofc ; put the number of commands to be sent in B nextcom: call sendcom ; send (HL) as a command inc hl ; point the next command 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 ld hl,databegadr ; set HL to point the first string byte ld b,numofd ; put the number of string bytes to be sent in B nextdata: call sendchar ; send (HL) as string data inc hl ; point the next string byte 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. cycle: ld e,4h ; use E to count the frames (4 frames in this case) ld hl,anim_data ; make (HL) point custom character data next_frame: ld b,8h ; each frame has 8 bytes of data ld a,40h call sendcomA ; Set CG RAM address to 00h by sendind 40h as a command next_byte: call sendchar ; write (HL) to CG RAM inc hl ; point the next byte to be written to CG RAM djnz next_byte ; loop till 8 bytes (1 frame/custom character) are sent push hl ; save HL ld hl,4040h ; put delay parameter for "pdealy" routine into HL call pdelay ; A frame was sent. Wait for while so that it can be seen. pop hl ; restore HL dec e ; decrease frame counter jp nz,next_frame ; loop till all frames are sent 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 ; ==================================================================== sendchar: ld a,(hl) ; put the data to be sent to the LCD in A sendcharA: push bc ; save BC push de ; save DE ld e,data ; jp common sendcom: ld a,(hl) sendcomA: push bc ; save BC push de ; save DE ld e,command common: call bfcheck ; See if the LCD is busy. If it is busy wait,till it is not. out (c),e ; Set/reset RS accoring to the content of register E ld d,write out (c),d ; reset RW pin for writing to LCD out (paadr),a ; place data/instrucrtion to be written into portA ld d,enable out (c),d ; enable the LCD ld d,disable out (c),d ; disable the LCD pop de ; restore DE pop bc ; restore BC 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 ; ==================================================================== bfcheck: push af ; save AF ld c,cwadr ld d,paincout out (c),d ; make A input,C output,B output ld d,read out (c),d ; set RW pin for reading from LCD ld d,command out (c),d ; select the instruction register check_again: ld d,enable out (c),d ; enable the LCD in a,(paadr) ; read from LCD ld d,disable out (c),d ; disable the LCD rlca ; rotate A left through C flag to see if the busy flag is set jp c,check_again ; if busy check it again,else continue ld d,pandcout out (c),d ; set all ports to output mode pop af ; restore AF 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 ;==================================================================== delay: ld hl,1010h pdelay: dec l jp nz,pdelay dec h jp nz,pdelay ret ;==================================================================== ; commands and strings combegadr: db 01h,80h,0ch,06h ; clear display,set DD RAM adress, ; turn on display with cursor hidden,set entry mode databegadr: ; Custom character 0 "IT IS EASY" Custom character 0 db 20h,00h,20h,49h,54h,20h,49h,53h,20h,45h,41h,53h,59h,20h,00h,20h anim_data: db 4,4,4,4,4,0,0,0 ; | db 16,8,4,2,1,0,0,0 ; \ db 0,0,31,0,0,0,0,0 ; - db 1,2,4,8,16,0,0,0 ; /