diff --git a/system/lcd.h65 b/system/lcd.h65 index 93ed1d8..b4dbad6 100644 --- a/system/lcd.h65 +++ b/system/lcd.h65 @@ -20,7 +20,32 @@ INCLUDE_LCD = 1 .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 +Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_charcount +; PIN MASKS +E = %10000000 +RW = %01000000 +RS = %00100000 + +RA_MASK = %11100000 + +; LCD Instructions (see datasheet for more) +CMD_CLEAR = %00000001 ; clear display +CMD_ENTRY_MODE = %00000110 ; auto-shift cursor +CMD_DISPLAY_ON = %00001111 ; everything on, with blinking cursor +CMD_SHIFT_CUR_LEFT = %00101000 ; shift the display to the left +CMD_SHIFT_DIS_LEFT = %00111000 ; shift the display to the left +CMD_SHIFT_DIS_RIGHT = %00110000 ; shift the display to the right +CMD_SHIFT_CUR_RIGHT = %00100000 ; shift the display to the right +CMD_FUNCTION_SET = %00111000 ; 8-bit, 4 lines, 5x7 font +CMD_SET_CG_ADDRESS = %01000000 ; or with the address +CMD_SET_ADDRESS = %10000000 ; or with the address +; LCD Constants +LINE1 = $00 +LINE2 = $40 +LINE3 = $10 +LINE4 = $50 + +.endscope ;;******************************************************************************** ;; @macro Clear the screen and print a null-terminated string @@ -73,29 +98,38 @@ Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram jsr lcd::print .endmacro -; PIN MASKS -E = %10000000 -RW = %01000000 -RS = %00100000 -RA_MASK = %11100000 +;;******************************************************************************** +;; @macro Print a null-terminated string +;; @param message: Address of the message or string literal +;;******************************************************************************** +.macro lcd_SetCursor pos + .if .match (pos, a) + .elseif .match (pos, x) + txa + .elseif .match (pos, y) + tya + .else + lda #pos + .endif + sta lcd::_charcount + jsr lcd::_set_dd_ram_addr_from__charcount +.endmacro + +;;******************************************************************************** +;; @macro Print a null-terminated string +;; @param message: Address of the message or string literal +;;******************************************************************************** +.macro lcd_AdvanceCursor n + .ifblank n + inc lcd::_charcount + .else + lda lcd::_charcount + add n + sta lcd::_charcount + .endif + jsr lcd::_set_dd_ram_addr_from__charcount +.endmacro -; LCD Instructions (see datasheet for more) -CMD_CLEAR = %00000001 ; clear display -CMD_ENTRY_MODE = %00000110 ; auto-shift cursor -CMD_DISPLAY_ON = %00001111 ; everything on, with blinking cursor -CMD_SHIFT_CUR_LEFT = %00101000 ; shift the display to the left -CMD_SHIFT_DIS_LEFT = %00111000 ; shift the display to the left -CMD_SHIFT_DIS_RIGHT = %00110000 ; shift the display to the right -CMD_SHIFT_CUR_RIGHT = %00100000 ; shift the display to the right -CMD_FUNCTION_SET = %00111000 ; 8-bit, 4 lines, 5x7 font -CMD_SET_CG_ADDRESS = %01000000 ; or with the address -CMD_SET_ADDRESS = %10000000 ; or with the address -; LCD Constants -LINE1 = $00 -LINE2 = $40 -LINE3 = $10 -LINE4 = $50 -.endscope .endif ; guard diff --git a/system/lcd.s65 b/system/lcd.s65 index b5222f5..09143aa 100644 --- a/system/lcd.s65 +++ b/system/lcd.s65 @@ -5,10 +5,10 @@ .endif Export lcd,init,clear,print,print_char,set_position,set_custom_char -Export lcd,_cmd,_wait_nbusy,_write_ram,_read_ram +Export lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_charcount ; RAM VARIABLES .bss -charcount: .res 1 +_charcount: .res 1 ; TODO when clockspeeds are more than 1MHz, _cmd, _write_ram and _read_ram might need to be adjusted .code @@ -36,7 +36,7 @@ charcount: .res 1 lda #lcd::CMD_ENTRY_MODE jsr _cmd - stz charcount + stz _charcount rts .endproc @@ -61,17 +61,17 @@ charcount: .res 1 cmp #$10 bge @line3 bra @set -; @line1: ; starts at $00, charcount at $00 -@line2: ; starts at $40, charcount at $10 +; @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 +@line3: ; starts at $10, _charcount at $20 add #$10 bra @set -@line4: ; starts at $50, charcount at $30 +@line4: ; starts at $50, _charcount at $30 sbc #$20 @set: - sta charcount + sta _charcount pla pha ora #lcd::CMD_SET_ADDRESS @@ -82,7 +82,7 @@ charcount: .res 1 @invalid: pla ; otherwise stack corruption lda #$13 - sta charcount + sta _charcount lda #(lcd::CMD_SET_ADDRESS | (lcd::LINE2 + 3)) jsr _cmd lda #(lcd::LINE2 + 3) @@ -99,7 +99,7 @@ charcount: .res 1 ;; @modifies A ;;******************************************************************************** .proc clear - stz charcount + stz _charcount lda #lcd::CMD_CLEAR jsr _cmd rts @@ -131,7 +131,7 @@ charcount: .res 1 .proc print_char pha jsr _write_ram - inc charcount + inc _charcount jsr _break_line pla ; put char back in a .endproc @@ -286,11 +286,53 @@ charcount: .res 1 ;;******************************************************************************** -;; @function Set the LCD DD-RAM Address so that text linebreaks after 16 chars +;; @function Set the LCD DD-RAM Address from the character count +;; @details +;; Sets the DD-RAM Address so that a line break occurs after 16 characters +;; If _charcount is more than $40, the position will be set to line 1. +;;******************************************************************************** +.proc _set_dd_ram_addr_from__charcount + cmp #$40 ; set to line1 when full + bcs @wrap_to_line1 + cmp #$10 + bcc @line1 + cmp #$20 + bcc @line3 + ; bra @line4 +@line4: + clc + adc #$20 ; _charcount $30-$3f -> $50 - $5f + bra @set_address +@wrap_to_line1: + sbc #$40 + and #%00001111 + ; now every _charcount is mapped between 0 and $3f + bra @set_address +@line2: + adc #$30 ; _charcount $10-$1f -> $40 - $4f + bra @set_address +@line3: + sec + sbc #$10 ; _charcount $20-$2f -> $10 - $1f + bra @set_address +@line1: ; _charcount $00-$1f -> $00 - $0f - nothing to do +@set_address: + ora #lcd::CMD_SET_ADDRESS + jsr _cmd + rts +.endproc + +;;******************************************************************************** +;; @function Set the LCD DD-RAM Address to te next line if the end of the line was reached +;; @details +;; If the cursor is past the end of a line, the DD-RAM Address is set to the next line. +;; If _charcount is more than $40, the position will be set to line 1. +;; This function is intended to be used with to set the correct address when +;; auto-shift is enabled ;;******************************************************************************** .proc _break_line ; check if checks are necessary - lda charcount + lda _charcount beq @line1 bit #%10001111 ; ($10 | $20 | $30 | $40) = %01110000 beq @check @@ -307,7 +349,7 @@ charcount: .res 1 bge @line1 rts @line1: - stz charcount + stz _charcount lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1) jsr _cmd rts