; *************************************************************************** ; copyright : (C) 2023 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** ; Some code in this module is based on C-code in Tiny4kOLED (https://github.com/datacute/Tiny4kOLED/tree/master/src) ; by Stephen Denne (MIT license), rewritten in AVR assembler ; ; - page 0 is top line, page 7 ist bottom line ; - column 0 is the leftmost colum, column 127 is the rightmost column ; - a page has a height of 8 (->8 bits) ; - when writing a byte to a position (e.g. page 0, column 0) ; - writing to chip RAM is done in columns ; ; text_xpos=(xpos*8), meaning max 16 chars per text line ; ; Page 0: col 0 col 1 ... col 127 ; Row 0(LSB) 0/0 1/0 ... 127/0 ; Row 1 0/1 1/1 ... 127/1 ; Row 2 0/2 1/2 ... 127/2 ; Row 3 0/3 1/3 ... 127/3 ; ... ; Row 7(MSB) 0/7 1/7 ... 127/7 ; and so one ; *************************************************************************** ; defines .equ LCD_WIDTH = 128 .equ LCD_HEIGHT = 64 .equ LCD_PAGE_COUNT = 8 .equ LCD_MODE_MULTICMD = 0x00 .equ LCD_MODE_SINGLECMD = 0x80 .equ LCD_MODE_DATA = 0x40 .equ LCD_MODE_SINGLEDATA = 0xc0 ; *************************************************************************** ; data .dseg lcdDataBegin: lcdDataEnd: ; *************************************************************************** ; code .cseg LCD_BEGIN: ; --------------------------------------------------------------------------- ; @routine LCD_Init @global ; ; @return CFLAG set if okay, cleared on error LCD_Init: ldi zl, LOW(lcdInitCommandsBegin) ldi zh, HIGH(lcdInitCommandsBegin) ldi r16, 28 rcall lcdWriteCommandsFromFlash ldi r16, 0 rcall LCD_Fill ldi r16, 255 rcall LCD_Fill ldi r16, 0 rcall LCD_Fill ldi r18, 0 ldi r19, 0 rcall LCD_SetCursor ldi zl, LOW(lcdHelloMsg) ldi zh, HIGH(lcdHelloMsg) rcall LCD_PrintFromFlash ; set cursor to next line here, sometimes this doesn't work correctly ; when called later. TODO: find out what goes wrong here... ldi r18, 0 ldi r19, 0 rcall LCD_SetCursor sec ret ; @end ; --------------------------------------------------------------------------- ; @routine LCD_Fini @global ; LCD_Fini: sec ret ; @end ; --------------------------------------------------------------------------- ; @routine LCD_Sleep @global ; ; @return nothing ; @param r16 1=sleep, 0=awake ; @clobbers r15, r16, r19 (R17, R18, R22) ; LCD_Sleep: ldi r16, 0xae ; set sleep tst r19 brne LCD_Sleep_send ldi r16, 0xaf ; set wake LCD_Sleep_send: rjmp lcdOneByteCommand ; @end ; --------------------------------------------------------------------------- ; @routine LCD_SetContrast @global ; ; @return nothing ; @param r16 1=sleep, 0=awake ; @clobbers r15, r16, r19 (R17, R18, R22) ; LCD_SetContrast: ldi r20, 0x81 mov r21, r16 rjmp lcdTwoByteCommand ; @end ; --------------------------------------------------------------------------- ; @routine lcdOneByteCommand ; Send a one byte command ; ; @return CFLAG set if okay, cleared on error ; @param r20 first byte of command ; @clobbers r15, r16, r19 (R17, R18, R22) lcdOneByteCommand: in r15, SREG push r15 cli rcall lcdBeginMultiCommand ; (r16, R17, R18, R22) brcc lcdOneByteCommand_error mov r16, r20 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdOneByteCommand_error rcall twiStop ; (R22) pop r15 out SREG, r15 sec ret lcdOneByteCommand_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine lcdTwoByteCommand ; Send a two byte command ; ; @return CFLAG set if okay, cleared on error ; @param r20 first byte of command ; @param r21 second byte of command ; @clobbers r15, r16, r19 (R17, R18, R22) ; lcdTwoByteCommand: in r15, SREG push r15 cli rcall lcdBeginMultiCommand ; (r16, R17, R18, R22) brcc lcdTwoByteCommand_error mov r16, r20 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdTwoByteCommand_error mov r16, r21 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdTwoByteCommand_error rcall twiStop ; (R22) pop r15 out SREG, r15 sec ret lcdTwoByteCommand_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine lcdBeginMultiCommand ; ; Set TWI start condition, send address and LCD_MODE_MULTICMD ; ; @return CFLAG set if okay, cleared on error ; @clobbers r16, (R17, R18, R22) lcdBeginMultiCommand: rcall twiStart ; (R22) ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdTwoByteCommand_error ldi r16, LCD_MODE_MULTICMD rjmp twiSendByteExpectAck ; (R16, R17, R18, R22) ; @end lcdTwiStopPopR15ClcRet: rcall twiStop ; (R22) pop r15 out SREG, r15 clc ret ; --------------------------------------------------------------------------- ; @routine LCD_SetCursor @global ; ; Set cursor. X is specified in pixels, Y is specified in character rows (8 pixels). ; Left upper corner is 0/0 (x/y), right lower corner is 127/7 ; ; @return CFLAG set if okay, cleared on error ; @param R18 X ; @param R19 Y ; @clobbers r1, r2, r15, r16 (R16, R17, R18, R22) LCD_SetCursor: in r15, SREG push r15 cli mov r1, r18 mov r2, r19 rcall twiStart ; (R22) ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error ldi r16, LCD_MODE_MULTICMD rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error mov r16, r2 ; Y andi r16, 0x07 ori r16, 0xb0 ; set page start address for page addressing mode rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error ldi r16, 0x21 ; set column start rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error mov r16, r1 ; X rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error ldi r16, LCD_WIDTH-1 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_SetCursor_error rcall twiStop ; (R22) pop r15 out SREG, r15 sec ret LCD_SetCursor_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine LCD_Fill @global ; ; Fill display RAM with the given value. ; ; @return CFLAG set if okay, cleared on error ; @param R16 data to write ; @clobbers r15, r16, r18, r19, r20, r21 (r17, r22) LCD_Fill: in r15, SREG push r15 cli mov r20, r16 ldi r21, 0 ; Y LCD_Fill_loopY: clr r18 mov r19, r21 rcall LCD_SetCursor brcc LCD_Fill_error rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error ldi r16, LCD_MODE_DATA rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error ldi r19, LCD_WIDTH ; count backwards to save one instruction LCD_Fill_loopX: mov r16, r20 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) rcall twiSendByte brcc LCD_Fill_error dec r19 brne LCD_Fill_loopX rcall twiStop inc r21 cpi r21, LCD_PAGE_COUNT brcs LCD_Fill_loopY pop r15 out SREG, r15 sec ret LCD_Fill_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine LCD_PrintFromFlash @global ; ; Print a string from flash at the current position. ; ; @return CFLAG set if okay, cleared on error ; @param Z position of string to print ; @clobbers r15, r16, Z (R17, R18, R22) LCD_PrintFromFlash: in r15, SREG push r15 cli lsl zl rol zh rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintFromFlash_error ldi r16, LCD_MODE_DATA rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintFromFlash_error LCD_PrintFromFlash_loop: lpm r16, z+ tst r16 breq LCD_PrintFromFlash_end push zh push zl rcall lcdPrintOneChar pop zl pop zh brcc LCD_PrintFromFlash_error rjmp LCD_PrintFromFlash_loop LCD_PrintFromFlash_end: rcall twiStop pop r15 out SREG, r15 sec ret LCD_PrintFromFlash_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine LCD_PrintChar @global ; ; Print a character at the current position. ; ; @return CFLAG set if okay, cleared on error ; @param R16 char ; @clobbers r15, r16, r17, Z LCD_PrintChar: in r15, SREG push r15 cli rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintChar_error ldi r16, LCD_MODE_DATA rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintChar_error rcall lcdPrintOneChar brcc LCD_PrintChar_error rcall twiStop pop r15 out SREG, r15 sec ret LCD_PrintChar_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine LCD_PrintHexByte @global ; ; Convert a given byte into HEX and write it to the current position. ; ; @return CFLAG set if okay, cleared on error ; @param R16 byte to convert to hex ; @clobbers r15, r16, r17, r20, Z LCD_PrintHexByte: in r15, SREG push r15 cli mov r20, r16 rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintHexByte_error ldi r16, LCD_MODE_DATA rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintHexByte_error mov r16, r20 rcall lcdPrintHexByte brcc LCD_PrintHexByte_error rcall twiStop pop r15 out SREG, r15 sec ret LCD_PrintHexByte_error: rjmp lcdTwiStopPopR15ClcRet ; (R22) ; @end ; --------------------------------------------------------------------------- ; @routine LCD_PrintHexWord @global ; ; Convert a give word into HEX and write it to the current position. ; ; @return CFLAG set if okay, cleared on error ; @param r18 low byte of the word ; @param r19 high byte of the word ; @clobbers r15, r16, r17, r22, Z LCD_PrintHexWord: in r15, SREG push r15 cli push r18 push r19 rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintHexWord_errorPop ldi r16, LCD_MODE_DATA rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_PrintHexWord_errorPop pop r19 pop r18 rcall lcdPrintHexWord brcc LCD_PrintHexWord_errorNoPop rcall twiStop pop r15 out SREG, r15 sec ret LCD_PrintHexWord_errorPop: rcall twiStop pop r19 pop r18 LCD_PrintHexWord_errorNoPop: pop r15 out SREG, r15 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdPrintHexWord ; ; Convert a given word into HEX and write it to the current position. ; ; @return CFLAG set if okay, cleared on error ; @param r18 low byte of the word ; @param r19 high byte of the word ; @clobbers r16, (r17, r20, Z) lcdPrintHexWord: mov r16, r19 push r18 rcall lcdPrintHexByte ; (r16, r17, r20, Z) pop r18 brcc lcdPrintHexWord_error mov r16, r18 rcall lcdPrintHexByte ; (r16, r17, r20, Z) brcc lcdPrintHexWord_error sec ret lcdPrintHexWord_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdPrintHexByte ; ; Convert a give byte into HEX and write it to the current position. ; ; @return CFLAG set if okay, cleared on error ; @param R16 byte to convert to hex ; @clobbers r16, r20 (r16, r17, Z) lcdPrintHexByte: mov r20, r16 swap r16 rcall lcdNibbleToAscii ; write high nibble (r16, r17) rcall lcdPrintOneChar ; (r16, r17, Z) brcc lcdPrintHexByte_error mov r16, r20 rcall lcdNibbleToAscii ; write low nibble rcall lcdPrintOneChar brcc lcdPrintHexByte_error sec ret lcdPrintHexByte_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdNibbleToAscii ; ; Convert a nibble to an ASCII char. ; @return R16 ASCII representation of that nibble (e.g. '0' for 0) ; @param R16 byte (in bits 0-3) ; @clobbers r16, r17 lcdNibbleToAscii: andi r16, 0xf cpi r16, 10 brcs lcdNibbleToAscii_l1 ldi r17, 7 add r16, r17 lcdNibbleToAscii_l1: ldi r17, '0' add r16, r17 ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdWriteCommandsFromFlash ; ; @return CFLAG set if okay, cleared on error ; @param R16 number of bytes to send ; @param Z pointer to data ; @clobbers r16, r20, Z (r17, r18, r22) lcdWriteCommandsFromFlash: rcall twiStart lsl zl rol zh mov r20, r16 ; number of bytes ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdWriteCommandsFromFlash_error ldi r16,LCD_MODE_MULTICMD rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdWriteCommandsFromFlash_error lcdWriteCommandsFromFlash_loop: lpm r16, z+ rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdWriteCommandsFromFlash_error dec r20 brne lcdWriteCommandsFromFlash_loop rcall twiStop ; (R22) sec ret lcdWriteCommandsFromFlash_error: rcall twiStop clc ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdPrintOneChar ; ; Print a character at the current position. ; ; @param R16 char ; @clobbers r16, r19, Z (R17, R18, R22) lcdPrintOneChar: rcall lcdGetCharMatrix ; (r16, r17, Z) ldi r16, 0 ; spacing between chars rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdPrintOneChar_error ldi r19, 6 lcdPrintOneChar_loop: lpm r16, z+ rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc lcdPrintOneChar_error dec r19 brne lcdPrintOneChar_loop sec ret lcdPrintOneChar_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine lcdGetCharMatrix ; ; Get pointer to matrix of given char. ; ; @return Z pos of character matrix (ready for LPM) ; @param R16 char to lookup ; @clobbers r16, r17, Z lcdGetCharMatrix: #ifdef LCD_MINIMAL_FONT rcall lcdUpcase cpi r16, 65+32 brcc lcdGetCharMatrix_l1 cpi r16, 32 brcc lcdGetCharMatrix_l2 lcdGetCharMatrix_l1: ldi r16, 32 lcdGetCharMatrix_l2: ldi r17, 32 sub r16, r17 mov zl, r16 clr zh clr r17 lsl zl ; *2 rol zh add zl, r16 ; *3 adc zh, r17 lsl zl ; *6 rol zh ldi r16, LOW(lcdFont6x8Minimal*2) ldi r17, HIGH(lcdFont6x8Minimal*2) add zl, r16 adc zh, r17 ret #else cpi r16, 95+32 brcc lcdGetCharMatrix_l1 cpi r16, 32 brcc lcdGetCharMatrix_l2 lcdGetCharMatrix_l1: ldi r16, 32 lcdGetCharMatrix_l2: ldi r17, 32 sub r16, r17 mov zl, r16 clr zh clr r17 lsl zl ; *2 rol zh add zl, r16 ; *3 adc zh, r17 lsl zl ; *6 rol zh ldi r16, LOW(lcdFont6x8*2) ldi r17, HIGH(lcdFont6x8*2) add zl, r16 adc zh, r17 ret #endif ; @end #ifdef LCD_MINIMAL_FONT ; --------------------------------------------------------------------------- ; @routine Uppercase the given character if it is lower case. ; ; @return R16 char ; @param R16 char ; @clobbers r16, r17 lcdUpcase: cpi r16, 'a' brcs lcdUpcase_done cpi r16, 'z'+1 brcc lcdUpcase_done ldi r17, 32 sub r16, r17 lcdUpcase_done: ret #endif ; @end lcdInitCommandsBegin: ; 28 bytes .db 0xae, 0x20, 0x00, 0xb0, 0xc8, 0x00, 0x10, 0x40 .db 0x81, 0x3f, 0xa1, 0xa6, 0xa8, LCD_HEIGHT-1, 0xa4, 0xd3 .db 0x00, 0xd5, 0xf0, 0xd9, 0x22, 0xda, 0x12, 0xdb .db 0x20, 0x8d, 0x14, 0xaf lcdInitCommandsEnd: lcdHelloMsg: .db "AqHOME 2024", 0 ; font taken from Tiny4kOLED (https://github.com/datacute/Tiny4kOLED/tree/master/src) by Stephen Denne (MIT license), ; original by Neven Boyanov #ifdef LCD_MINIMAL_FONT lcdFont6x8Minimal: .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0 .db 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 ; ! 1 .db 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 ; " 2 .db 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 ; # 3 .db 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 ; $ 4 .db 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 ; % 5 .db 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 ; & 6 .db 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 ; ' 7 .db 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 ; ( 8 .db 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 ; ) 9 .db 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 ; * 10 .db 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 ; + 11 .db 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 ; , 12 .db 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 ; - 13 .db 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 ; . 14 .db 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 ; / 15 .db 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E ; 0 16 .db 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 ; 1 17 .db 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 ; 2 18 .db 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 ; 3 19 .db 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 ; 4 20 .db 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 ; 5 21 .db 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 ; 6 22 .db 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 ; 7 23 .db 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 ; 8 24 .db 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E ; 9 25 .db 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 ; : 26 .db 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 ; ; 27 .db 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 ; < 28 .db 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 ; = 29 .db 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 ; > 30 .db 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 ; ? 31 .db 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E ; @ 32 .db 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C ; A 33 .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 ; B 34 .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 ; C 35 .db 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C ; D 36 .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 ; E 37 .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 ; F 38 .db 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A ; G 39 .db 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F ; H 40 .db 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 ; I 41 .db 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 ; J 42 .db 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 ; K 43 .db 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 ; L 44 .db 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F ; M 45 .db 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F ; N 46 .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E ; O 47 .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 ; P 48 .db 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E ; Q 49 .db 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 ; R 50 .db 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 ; S 51 .db 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 ; T 52 .db 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F ; U 53 .db 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F ; V 54 .db 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F ; W 55 .db 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 ; X 56 .db 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 ; Y 57 .db 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 ; Z 58 .db 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 ; [ 59 .db 0x00, 0x02, 0x04, 0x08, 0x10, 0x20 ; \ 60 .db 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 ; ] 61 .db 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 ; ^ 62 .db 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 ; _ 63 .db 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 ; ' 64 #else lcdFont6x8: .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0 .db 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 ; ! 1 .db 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 ; " 2 .db 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 ; # 3 .db 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 ; $ 4 .db 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 ; % 5 .db 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 ; & 6 .db 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 ; ' 7 .db 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 ; ( 8 .db 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 ; ) 9 .db 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 ; * 10 .db 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 ; + 11 .db 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 ; , 12 .db 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 ; - 13 .db 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 ; . 14 .db 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 ; / 15 .db 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E ; 0 16 .db 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 ; 1 17 .db 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 ; 2 18 .db 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 ; 3 19 .db 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 ; 4 20 .db 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 ; 5 21 .db 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 ; 6 22 .db 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 ; 7 23 .db 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 ; 8 24 .db 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E ; 9 25 .db 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 ; : 26 .db 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 ; ; 27 .db 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 ; < 28 .db 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 ; = 29 .db 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 ; > 30 .db 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 ; ? 31 .db 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E ; @ 32 .db 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C ; A 33 .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 ; B 34 .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 ; C 35 .db 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C ; D 36 .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 ; E 37 .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 ; F 38 .db 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A ; G 39 .db 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F ; H 40 .db 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 ; I 41 .db 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 ; J 42 .db 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 ; K 43 .db 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 ; L 44 .db 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F ; M 45 .db 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F ; N 46 .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E ; O 47 .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 ; P 48 .db 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E ; Q 49 .db 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 ; R 50 .db 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 ; S 51 .db 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 ; T 52 .db 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F ; U 53 .db 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F ; V 54 .db 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F ; W 55 .db 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 ; X 56 .db 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 ; Y 57 .db 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 ; Z 58 .db 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 ; [ 59 .db 0x00, 0x02, 0x04, 0x08, 0x10, 0x20 ; \ 60 .db 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 ; ] 61 .db 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 ; ^ 62 .db 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 ; _ 63 .db 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 ; ' 64 .db 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 ; a 65 .db 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 ; b 66 .db 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 ; c 67 .db 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F ; d 68 .db 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 ; e 69 .db 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 ; f 70 .db 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C ; g 71 .db 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 ; h 72 .db 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 ; i 73 .db 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 ; j 74 .db 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 ; k 75 .db 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 ; l 76 .db 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 ; m 77 .db 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 ; n 78 .db 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 ; o 79 .db 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 ; p 80 .db 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC ; q 81 .db 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 ; r 82 .db 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 ; s 83 .db 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 ; t 84 .db 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C ; u 85 .db 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C ; v 86 .db 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C ; w 87 .db 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 ; x 88 .db 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C ; y 89 .db 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 ; z 90 .db 0x00, 0x08, 0x36, 0x41, 0x41, 0x00 ; { 91 .db 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00 ; | 92 .db 0x00, 0x00, 0x41, 0x41, 0x36, 0x08 ; } 93 .db 0x00, 0x08, 0x04, 0x08, 0x10, 0x08 ; ~ 94 #endif LCD_END: .equ MODULE_SIZE_LCD = LCD_END-LCD_BEGIN