165 lines
5.1 KiB
Plaintext
165 lines
5.1 KiB
Plaintext
;;********************************************************************************
|
|
;; @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 ARG0
|
|
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 ARG0
|
|
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
|