;lcd.asm ******************************************************************************* *REVISION HISTORY: * *DATE REV. NO. DESCRIPTION * *March 3, 2000 V1.00 *Written by Exequiel Rarama for the ADAPT 912 ******************************************************************************** ; Memory Allocation are define in the main program ;disp_buffer ds 80 ;display buffer (4 lines of 20 chars) ;disp_ptr ds 2 ;pointer to display buffer ;disp_flag ds 1 ;1 = update; 0 = home; -1 = done ;drow_var ds 1 ;temp ds 1 ;lcd_state ds 2 ;temp_h ds 1 ;TEMP1 ds 1 ;TEMP2 ds 1 ;lcd_timer ds 2 ;dcol_var ds 1 ;dig_lenght ds 1 ;l_flag ds 1 ; Local Constants lcd_ctrl equ %01000000 ;Port A bit 6 = 0 - Instruction in lcd_data equ %01000000 ;Port A bit 6 = 0 - Data in lcd_enable equ %10000000 ;Port A bit 7 - enable BL EQU $20 EOT EQU $04 ;end of text/table ; ;Spi initialization variables spi_mask1 equ %01010000 ;SPE,MSTR=1, SWOM,CPOL,CPHA=0 spi_mask2 equ %11100000 ;Bit 7,6,5=1 the rest=0 spi_baud1 equ %00000000 ;4.0 Mhz spi_baud2 equ %00000001 ;2.0 Mhz spi_baud3 equ %00000010 ;1.0 Mhz spi_baud4 equ %00000011 ;0.5 Mhz spi_baud5 equ %00000100 ;250 kHz spi_baud6 equ %00000101 ;125 kHz spi_baud7 equ %00000110 ;62.5 kHz spi_baud8 equ %00000111 ;31.3 kHz SPIF equ %10000000 ;flag after the 8th clock SPIE equ %10000000 ;Spi interrupt enable LSBF equ %00000001 ;SPI LSB First enable ;slave_select equ %10000000 ;Chip select for the sound chip SSPIN equ %10000000 ;Chip select for the sound chip TEN equ $80 us2 equ 8 ;----------------------------------------------------------------------------- ; Display Initialization ; ---------------------- disp_init ;Initialize LCD display bset DDRP,%11000000 ;Initialize Port J bclr PORTS,SSPIN ;inititalize port to 0 movb #spi_mask2,DDRS movb #spi_mask1,SP0CR1 ;SPE,MSTR=1, CPOL,SWOM,CPHA=0 bclr SP0CR2,%01 ;SPC0=0, Normal mode movb #spi_baud3,SP0BR ;set clock to 1 Mhz ldaa SP0SR ;clear flag and buffer ldaa SP0DR clr spi_int_flag clr drow_var clr disp_flag jsr delay jsr delay ;Initialize jsr small_delay ldaa #%00110000 jsr toggle_lcd_ctrl ;8 data bits, 4 display lines, 0 jsr small_delay ldaa #%00111000 jsr toggle_lcd_ctrl ;8 data bits, 4 display lines, 0 jsr small_delay ldaa #%00001100 jsr toggle_lcd_ctrl ;display on, cursor off, blink off jsr small_delay ldaa #%00000001 jsr toggle_lcd_ctrl ;Clear display and return cursor to home jsr small_delay ldaa #%01000000 jsr toggle_lcd_ctrl jsr small_delay ldaa #%10000000 jsr toggle_lcd_ctrl ldx #cgram_table ldab #CGRAM_LEN jsr line_update ldx #disp_menu1 stx lcd_state ldx #0 stx lcd_timer jsr disp_clear rts toggle_lcd_ctrl jsr dump_spi_data bset PORTS,SSPIN ;DRIVE SELECT OF 74HC595 HI nop nop bclr PORTS,SSPIN ;DRIVE SELECT OF 74HC595 LO bclr PORTP,lcd_ctrl nop bset PORTP,lcd_enable ;Pulse lcd enable nop nop bclr PORTP,lcd_enable rts toggle_lcd_data jsr dump_spi_data bset PORTS,SSPIN ;DRIVE SELECT OF 74HC595 HI nop nop bclr PORTS,SSPIN ;DRIVE SELECT OF 74HC595 LO bset PORTP,lcd_data nop bset PORTP,lcd_enable ;Pulse lcd enable nop nop bclr PORTP,lcd_enable rts dump_spi_data pshb ldab SP0SR ;clear flag and buffer ldab SP0DR clr spi_int_flag ;clear for next spi dump bset SP0CR1,SPIE ;Enable spi interrupt staa SP0DR ;dump to spi to start playback brclr spi_int_flag,$01,* ;wait here for spi int bclr SP0CR1,SPIE ;Disable spi interrutp clr spi_int_flag ;clear for next spi dump pulb rts us_delay bclr TSCR,TEN ;stop the timer so we can produce accurate time ;delays ldd u_delay_var ;get constant for 2us delay addd TCNT std TC0 bset TSCR,TEN ;turn on the timer brclr TFLG1,$01,* ;wait here for 8us bclr TSCR,TEN ;turn offn the timer rts ;spi_int ; bset spi_int_flag,%00000001 ; ldaa SP0SR ; ldaa SP0DR ; rti ;============================================================================= ;These subroutine displays the various messages in 2 second interval and are ; called in the main loop. ; disp_menu0 ;dummy display ldx lcd_timer bne lcd_ex0 ldaa #0 staa drow_var jsr drow ldx #MSG8 jsr dstr ldaa #1 staa drow_var jsr drow ldx #MSG1 jsr dstr ldaa #2 staa drow_var jsr drow ldx #MSG2 jsr dstr ldaa #3 staa drow_var jsr drow ldx #MSG3 jsr dstr ldx #disp_menu1 stx lcd_state ldx #61 stx lcd_timer lcd_ex0 rts disp_menu1 ldx lcd_timer bne lcd_ex1 ldaa #0 staa drow_var jsr drow ldx #MSG1 jsr dstr ldaa #1 staa drow_var jsr drow ldx #MSG2 jsr dstr ldaa #2 staa drow_var jsr drow ldx #MSG3 jsr dstr ldaa #3 staa drow_var jsr drow ldx #MSG9 jsr dstr ldx #disp_menu2 stx lcd_state ldx #61 stx lcd_timer lcd_ex1 rts disp_menu2 ldx lcd_timer bne lcd_ex2 ldaa #0 staa drow_var jsr drow ldx #MSG2 jsr dstr ldaa #1 staa drow_var jsr drow ldx #MSG3 jsr dstr ldaa #2 staa drow_var jsr drow ldx #MSG9 jsr dstr ldaa #3 staa drow_var jsr drow ldx #MSG9 jsr dstr ldx #disp_menu3 stx lcd_state ldx #61 stx lcd_timer lcd_ex2 rts disp_menu3 ldx lcd_timer bne lcd_ex3 ldaa #0 staa drow_var jsr drow ldx #MSG3 jsr dstr ldaa #1 staa drow_var jsr drow ldx #MSG9 jsr dstr ldaa #2 staa drow_var jsr drow ldx #MSG9 jsr dstr ldaa #3 staa drow_var jsr drow ldx #MSG9 jsr dstr ldx #disp_menu0 stx lcd_state ldx #61 stx lcd_timer lcd_ex3 rts disp_menu4 rts ;----------------------------------------------------------------------------- ; Clear Display ; ------------- disp_clear ldx #disp_buffer ;starting address of display buffer stx disp_ptr ;home cursor ldab #80 ;number of characters ldaa #BL dcl10 staa 0,x ;fill buffer with spaces inx decb bne dcl10 ldaa #1 ;set flag for immediate display staa disp_flag ; update rts ;----------------------------------------------------------------------------- ; Set Display Position ; -------------------- ; This routine sets the display buffer pointer to the selected row ; and column position. Values are assumed to be valid: no range checking ; is performed. ; Entry: A contains row number (0 - 3) ; B contains column number (0 - 19) disp_pos ldx #disp_buffer ;starting address of display buffer abx ;add column number ldab #20 mul abx ;add 20 x row number stx disp_ptr rts ;----------------------------------------------------------------------------- ; Display Character ; ----------------- ; Entry: A contains character to be displayed ; B contains number of occurences (DISP_REP only) disp_chr ldy disp_ptr ;store character in display buffer cmpa #$a6 bne dsc10 ldaa #4 dsc10 staa 0,y iny bra dispex disp_rep ldy disp_ptr cmpa #$a6 bne drp10 ldaa #4 drp10 staa 0,y ;store character, decrement counter iny ; and loop until done decb bne drp10 dispex cpy #disp_buffer+80 blo dsp10 ldy #disp_buffer dsp10 sty disp_ptr ldaa #1 ;set flag for immediate display staa disp_flag ; update rts ;----------------------------------------------------------------------------- ; Display String ; -------------- disp_str ldy disp_ptr dst10 ldaa 0,x beq dst20 cmpa #$a6 bne dst15 ldaa #4 dst15 staa 0,y inx iny bra dst10 dst20 inx bra dispex ;-------- disp_strn ldy disp_ptr dsn10 ldaa 0,x cmpa #$a6 bne dsn15 ldaa #4 dsn15 staa 0,y inx iny decb bne dsn10 bra dispex ;----------------------------------------------------------------------------- ; Update Display ; -------------- ; This routine updates the LCD display from the display image in ; memory whenever the update flag is set. disp_update ldaa disp_flag ;exit if display update flag is clr bmi dupex ; dec disp_flag beq dup10 ldaa #%00000010 jsr toggle_lcd_ctrl ;home cursor bra dupex dup10 ldab #20 ;number of characters per line ldx #disp_buffer ;display 1st line jsr line_update ldx #disp_buffer+40 ;display 3rd line jsr line_update ldx #disp_buffer+20 ;display 2nd line jsr line_update ldx #disp_buffer+60 ;display 4th line jsr line_update ldaa #%1100 jsr toggle_lcd_ctrl ;display on, cursor off, blink off dupex rts ;---------------------------------------------------------------------------- line_update pshb ;save character count lup10 ldaa 0,x ;write character to display cmpa #'0' ; (substitue O for 0) bne lup15 ldaa #'O' lup15 ;Display Char to LCD jsr toggle_lcd_data jsr small_delay inx ;advance to next character, decrement decb ; count & loop if not done bne lup10 pulb ;restore character count rts ;============================================================================== ; Set Cursor Position ; ------------------- ; A contains row number ; B contains column number drow ldaa drow_var ;drow_var = 0 =>1st line ; ;drow_var = 1 =>2nd line ; ;drow_var = 2 =>3rd line ; ;drow_var = 3 =>4th line ldab #0 jsr disp_pos rts dpos ldaa drow_var ;drow_var = 0 =>1st line ; ;drow_var = 1 =>2nd line ; ;drow_var = 2 =>3rd line ; ;drow_var = 3 =>4th line ldab dcol_var ;dcol_var = 0 => 20 1st line ; ;dcol_var = 1 => 20 2nd line ; ;dcol_var = 2 => 20 3nd line ; ;dcol_var = 3 => 20 4nd line jsr disp_pos rts ; Display String ; -------------- ; X contains address of string to be displayed ; B contains length of string (if absent: nul terminates string) dstr jsr disp_str rts dstrn jsr disp_strn rts dvalx ldab #5 ;will display 5 digit value ; subb #3 ;lenght of value subb dig_lenght ;lenght of value to be displayed abx ;Reg X contain the address to be displayed jsr disp_strn rts ;----------------------------------------------------------------------------- cgram_table db %00000 db %00000 db %00000 db %00000 db %00000 db %00000 db %00000 db %00000 CGRAM_LEN EQU $-cgram_table ;----------------------------------------------------------------------------- ;Lcd Messages MSG1 fcc 'LCD Routine Program.' fcb 0 MSG2 fcc 'This is a TEST......' fcb 0 MSG3 fcc '--------------------' fcb 0 MSG4 fcc 'Msg4................' fcb 0 MSG5 fcc 'Msg5................' fcb 0 MSG6 fcc 'Msg6................' fcb 0 MSG7 fcc 'Msg7................' fcb 0 MSG8 fcc 'Technological Arts ' fcb 0 MSG9 fcc ' ' fcb 0 MSG10 fcc 'Keyboard Test.......' fcb 0 MSG11 fcc 'Msg11...............'