2023-12-08 22:56:35 +01:00
|
|
|
.include "system/lcd.h65"
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
.ifndef lcd::LCD_IO
|
|
|
|
.fatal "lcd::LCD_IO is not defined: set it to the base address of the IO chip of the LCD"
|
|
|
|
.endif
|
|
|
|
|
|
|
|
Export lcd,init,clear,print,print_char,set_position
|
2023-10-26 19:51:20 +02:00
|
|
|
|
|
|
|
; RAM VARIABLES
|
2023-12-08 22:56:35 +01:00
|
|
|
.bss
|
|
|
|
charcount: .res 1
|
|
|
|
|
|
|
|
.code
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Initialize the lcd module
|
|
|
|
;; @details call before doing anything else
|
|
|
|
;; @modifies A
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc init
|
2023-10-26 19:51:20 +02:00
|
|
|
; init IO
|
|
|
|
lda #$ff ; RB 0-7 output
|
2023-12-08 22:56:35 +01:00
|
|
|
sta lcd::LCD_IO+IO::DDRB
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
; UT_update_with_mask IO + IO::DDRA, (RS | LCD_RW | LCD_E), (LCD_RS | LCD_RW | LCD_E)
|
|
|
|
lda #(lcd::RS | lcd::RW | lcd::E) ; RA 5-7 output
|
|
|
|
sta lcd::LCD_IO+IO::DDRA
|
2023-10-26 19:51:20 +02:00
|
|
|
|
|
|
|
; init lcd
|
2023-12-08 22:56:35 +01:00
|
|
|
lda #lcd::CMD_FUNCTION_SET
|
|
|
|
jsr _cmd
|
|
|
|
lda #lcd::CMD_DISPLAY_ON
|
|
|
|
jsr _cmd
|
|
|
|
lda #lcd::CMD_CLEAR
|
|
|
|
jsr _cmd
|
|
|
|
lda #lcd::CMD_ENTRY_MODE
|
|
|
|
jsr _cmd
|
|
|
|
|
|
|
|
stz charcount
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; PRINTING TO LCD
|
|
|
|
;;********************************************************************************
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Clear the display
|
|
|
|
;; @see lcd_print
|
|
|
|
;; @modifies A
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc clear
|
|
|
|
stz charcount
|
|
|
|
lda #lcd::CLEAR
|
|
|
|
jsr _cmd
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
|
|
|
jsr _cmd
|
2023-10-28 03:48:27 +02:00
|
|
|
rts
|
|
|
|
.endproc
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Print a null-terminated string
|
|
|
|
;; @param ARG0-1 Address of the string to print
|
|
|
|
;; @modifies: A,Y
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc print
|
2023-10-28 03:48:27 +02:00
|
|
|
ldy #$00
|
|
|
|
@lcd_print_loop:
|
2023-10-30 22:14:08 +01:00
|
|
|
lda (ARG0),y
|
2023-10-28 03:48:27 +02:00
|
|
|
beq @lcd_print_end
|
2023-12-08 22:56:35 +01:00
|
|
|
jsr print_char
|
2023-10-28 03:48:27 +02:00
|
|
|
iny
|
|
|
|
bra @lcd_print_loop
|
|
|
|
@lcd_print_end:
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-10-28 03:48:27 +02:00
|
|
|
.endproc
|
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @macro Print a single character
|
|
|
|
;; @param A: Character to print
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc print_char
|
2023-11-01 13:13:23 +01:00
|
|
|
pha
|
|
|
|
pha
|
|
|
|
; TODO use UT_update_with_mask?
|
2023-12-08 22:56:35 +01:00
|
|
|
jsr _wait_nbusy
|
2023-11-01 13:13:23 +01:00
|
|
|
pla
|
2023-12-08 22:56:35 +01:00
|
|
|
sta lcd::LCD_IO + IO::RB
|
|
|
|
lda #lcd::RS
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #(lcd::RS | lcd::E)
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #lcd::RS
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
inc charcount
|
|
|
|
jsr _break_line
|
2023-11-01 13:13:23 +01:00
|
|
|
pla ; put char back in a
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; Internal LCD Commands
|
|
|
|
;;********************************************************************************
|
2023-10-26 19:51:20 +02:00
|
|
|
; read busy flag
|
2023-12-08 22:56:35 +01:00
|
|
|
.proc _wait_nbusy
|
|
|
|
stz lcd::LCD_IO + IO::DDRB ; set IO1-IO + IO::RB to input
|
2023-10-26 19:51:20 +02:00
|
|
|
@lcd_wait_nbusy_loop: ; read the busy flag
|
2023-12-08 22:56:35 +01:00
|
|
|
lda #lcd::RW
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #(lcd::RW | lcd::E)
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
lda lcd::LCD_IO + IO::RB
|
2023-10-26 19:51:20 +02:00
|
|
|
and #%10000000 ; and updates zero flag, if not set retry
|
|
|
|
bne @lcd_wait_nbusy_loop
|
|
|
|
|
|
|
|
lda #%00000000 ; TODO dont overwrite 0-4
|
2023-12-08 22:56:35 +01:00
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #%11111111 ; set IO1-IO + IO::RB to output
|
|
|
|
sta lcd::LCD_IO + IO::DDRB
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-11-01 13:13:23 +01:00
|
|
|
.endproc
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Send a command to the lcd
|
|
|
|
;; @param A: command
|
|
|
|
;; @modifies A
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc _cmd ; send cmd in acc
|
2023-10-26 19:51:20 +02:00
|
|
|
pha
|
2023-12-08 22:56:35 +01:00
|
|
|
jsr _wait_nbusy
|
2023-10-26 19:51:20 +02:00
|
|
|
pla
|
|
|
|
|
|
|
|
; TODO use UT_update_with_mask?
|
2023-12-08 22:56:35 +01:00
|
|
|
sta lcd::LCD_IO + IO::RB
|
|
|
|
lda #lcd::CLEAR
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #lcd::E
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
|
|
|
lda #lcd::CLEAR
|
|
|
|
sta lcd::LCD_IO + IO::RA
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-10-28 03:48:27 +02:00
|
|
|
.endproc
|
2023-10-26 19:51:20 +02:00
|
|
|
|
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Set the cursor to a position
|
|
|
|
;; @param A: cursor position: `(lcd::LINEX + offset)`, where offset € [$0, $f]
|
|
|
|
;; @details:
|
|
|
|
;; If the position is too large, it will be set to char 5 in line 2
|
|
|
|
;; @returns A: the cursor position
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc set_position
|
2023-12-09 23:33:15 +01:00
|
|
|
pha
|
|
|
|
cmp #$60
|
|
|
|
bge @invalid
|
|
|
|
cmp #$50
|
|
|
|
bge @line4
|
2023-12-08 22:56:35 +01:00
|
|
|
cmp #$40
|
2023-12-09 23:33:15 +01:00
|
|
|
bge @line2
|
|
|
|
cmp #$20
|
2023-12-08 22:56:35 +01:00
|
|
|
bge @invalid
|
2023-12-09 23:33:15 +01:00
|
|
|
cmp #$10
|
|
|
|
bge @line3
|
|
|
|
bra @set
|
|
|
|
; @line1: ; starts at $00, charcount at $00
|
|
|
|
@line2: ; starts at $40, charcount at $10
|
|
|
|
sbc #$30 ; carry is already set
|
|
|
|
bra @set
|
|
|
|
@line3: ; starts at $10, charcount at $20
|
|
|
|
add #$10
|
|
|
|
bra @set
|
|
|
|
@line4: ; starts at $50, charcount at $30
|
|
|
|
sbc #$20
|
|
|
|
@set:
|
2023-12-08 22:56:35 +01:00
|
|
|
sta charcount
|
2023-12-09 23:33:15 +01:00
|
|
|
pla
|
2023-12-08 22:56:35 +01:00
|
|
|
ora #lcd::CMD_SET_ADDRESS
|
|
|
|
jsr _cmd
|
2023-12-09 23:33:15 +01:00
|
|
|
and #(<~lcd::CMD_SET_ADDRESS) ; return original argument
|
2023-12-08 22:56:35 +01:00
|
|
|
rts
|
|
|
|
@invalid:
|
|
|
|
lda $14
|
|
|
|
sta charcount
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | (lcd::LINE2 + 4))
|
|
|
|
jsr _cmd
|
|
|
|
lda #(lcd::LINE2 + 4)
|
2023-12-09 23:33:15 +01:00
|
|
|
rts
|
2023-12-08 22:56:35 +01:00
|
|
|
.endproc
|
|
|
|
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Set the LCD DD-RAM Address so that text linebreaks after 16 chars
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc _break_line
|
2023-10-26 19:51:20 +02:00
|
|
|
; check if checks are necessary
|
2023-12-08 22:56:35 +01:00
|
|
|
lda charcount
|
|
|
|
beq @line1
|
2023-10-26 19:51:20 +02:00
|
|
|
and #%10001111 ; ($10 | $20 | $30 | $40) = %01110000
|
2023-12-08 22:56:35 +01:00
|
|
|
bne @rts
|
2023-10-26 19:51:20 +02:00
|
|
|
; checks necessary
|
2023-12-08 22:56:35 +01:00
|
|
|
lda charcount
|
|
|
|
beq @line1
|
2023-10-26 19:51:20 +02:00
|
|
|
cmp #$10
|
2023-12-08 22:56:35 +01:00
|
|
|
beq @line2
|
2023-10-26 19:51:20 +02:00
|
|
|
cmp #$20
|
2023-12-08 22:56:35 +01:00
|
|
|
beq @line3
|
2023-10-26 19:51:20 +02:00
|
|
|
cmp #$30
|
2023-12-08 22:56:35 +01:00
|
|
|
beq @line4
|
|
|
|
cmp #$40 ; set to line1 when full
|
|
|
|
bge @line1
|
|
|
|
@rts:
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-12-08 22:56:35 +01:00
|
|
|
@line1:
|
|
|
|
stz charcount
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
|
|
|
jsr _cmd
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-12-08 22:56:35 +01:00
|
|
|
@line2:
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE2)
|
|
|
|
jsr _cmd
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-12-08 22:56:35 +01:00
|
|
|
@line3:
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE3)
|
|
|
|
jsr _cmd
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-12-08 22:56:35 +01:00
|
|
|
@line4:
|
|
|
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
|
|
|
jsr _cmd
|
2023-10-26 19:51:20 +02:00
|
|
|
rts
|
2023-10-28 03:48:27 +02:00
|
|
|
.endproc
|
2023-12-08 22:56:35 +01:00
|
|
|
|