;;******************************************************************************** ;; @file ;; @brief LCD-W164B driver ;; @ingroup drivers ;; @device ELECTRONIC ASSEMBLY - W164B-NLW ;; @details ;; The LCD must be connected to a W65C22N Interface Chip: ;; - IO.RB0-7 -> LCD.D0-7 data lines ;; - IO.RA5 -> LCD.RS register select ;; - IO.RA6 -> LCD.R/W read/write ;; - IO.RA7 -> LCD.E enable ;; @requires IO: Base Address of IO Chip ;; @depends IO-W65C22N ;;******************************************************************************** .ifndef INCLUDE_LCD INCLUDE_LCD = 1 .include "system/system.h65" ;;******************************************************************************** ;; @brief LCD character display ;; @ingroup drivers ;;******************************************************************************** .scope lcd LCD_IO = IO1 Import lcd,init,clear,print,print_char,set_position,set_custom_char Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_set_dd_ram_addr_from_charcount Import lcd,_charcount ; PIN MASKS E = %10000000 RW = %01000000 RS = %00100000 RA_MASK = %11100000 ;;******************************************************************************** ;; LCD Instructions ;; @details See LCD-W164B datasheet for a complete list ;;******************************************************************************** .enum CMD CLEAR = %00000001 ;; clear display ENTRY_MODE = %00000110 ;; auto-shift cursor DISPLAY_ON = %00001111 ;; everything on, with blinking cursor SHIFT_CUR_LEFT = %00101000 ;; shift the cursor to the left SHIFT_DIS_LEFT = %00111000 ;; shift the display to the left SHIFT_DIS_RIGHT = %00110000 ;; shift the display to the right SHIFT_CUR_RIGHT = %00100000 ;; shift the cursor to the right FUNCTION_SET = %00111000 ;; 8-bit, 4 lines, 5x7 font SET_CG_ADDRESS = %01000000 ;; or this with the address SET_ADDRESS = %10000000 ;; or this with the address .endenum ; LCD Constants LINE1 = $00 LINE2 = $40 LINE3 = $10 LINE4 = $50 .endscope ;;******************************************************************************** ;; @macro Clear the screen and print a null-terminated string ;; @param message: Address of the message or string literal ;; @details ;; If message is a string literal, it will be stored in rodata ;; and the address of this segment will be used ;;******************************************************************************** .macro Print message jsr lcd::clear .if .match(message, "") ; message is a string literal -> store in rodata .pushseg .rodata : .asciiz message .popseg lda #<:- sta ARG0 lda #>:- sta ARG1 .else ; message is not a string lda #message sta ARG1 .endif jsr lcd::print .endmacro ;;******************************************************************************** ;; @macro Print a null-terminated string ;; @param message: Address of the message or string literal ;;******************************************************************************** .macro PrintNC message .if .match(message, "") ; message is a string literal -> store in rodata .pushseg .rodata : .asciiz message .popseg lda #<:- sta ARG0 lda #>:- sta ARG1 .else ; message is not a string lda #message sta ARG1 .endif jsr lcd::print .endmacro ;;******************************************************************************** ;; @macro Set the cursor to the n-th position ;; @param n: Position [0,$40) or a register ;;******************************************************************************** .macro lcd_SetCursorPos n .if .match (n, a) .elseif .match (n, x) txa .elseif .match (n, y) tya .else lda #n .endif sta lcd::_charcount jsr lcd::_set_dd_ram_addr_from_charcount .endmacro ;;******************************************************************************** ;; @macro Move the cursor to the right ;; @param n: Number of characters to move n. Defaults to 1 if not provided ;;******************************************************************************** .macro lcd_IncrementCursor n .ifblank n inc lcd::_charcount .elseif n = 1 inc lcd::_charcount .else lda lcd::_charcount add #n sta lcd::_charcount .endif jsr lcd::_set_dd_ram_addr_from_charcount .endmacro ;;******************************************************************************** ;; @macro Move the cursor to the left ;; @param n: Number of characters to move n. Defaults to 1 if not provided ;;******************************************************************************** .macro lcd_DecrementCursor n .ifblank n dec lcd::_charcount .elseif n = 1 dec lcd::_charcount .else lda lcd::_charcount sub #n sta lcd::_charcount .endif jsr lcd::_set_dd_ram_addr_from_charcount .endmacro .endif ; guard