117 lines
3.8 KiB
NASM
Raw Normal View History

jp main ; Startup vector: DO NOT MOVE! Must be the first instruction
; Tests TM404A, on ports 2 and 3
IO_2: EQU 0x40
IO_3: EQU 0x60
LCD_TOP_INSTR_REG: EQU IO_2
LCD_TOP_DATA_REG: EQU IO_2 + 1
LCD_BOTTOM_INSTR_REG: EQU IO_3
LCD_BOTTOM_DATA_REG: EQU IO_3 + 1
; Inits the lcd display
LCD4004_init:
; --- Init first controller ---
; The following are documented as in the datasheet: RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
; Function set: 0 0 0 0 1 DL N F 0 0 (DL: 8-bit/4-bit, N: number of display lines 2/1, F: Font type 11dots/8dots)
; 0000111000 (8 bit, 2 lines)
ld a,0x38
out (LCD_TOP_INSTR_REG),a
call LCD4004_wait_busy_clear
; Display ON/OFF Control: 0 0 0 0 0 0 1 D C B (D: display on/off, C: cursor on/off, B: blinking cursor on/off)
; 0000001111 (display on, blinking cursor)
ld a,0x0F
out (LCD_TOP_INSTR_REG),a
call LCD4004_wait_busy_clear
; Clear display
; 0000000001
ld a,0x01
out (LCD_TOP_INSTR_REG),a
call LCD4004_wait_busy_clear
; --- Init second controller ---
; The following are documented as in the datasheet: RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
; Function set: 0 0 0 0 1 DL N F 0 0 (DL: 8-bit/4-bit, N: number of display lines 2/1, F: Font type 11dots/8dots)
; 0000111000 (8 bit, 2 lines)
ld a,0x38
out (LCD_BOTTOM_INSTR_REG),a
call LCD4004_wait_busy_clear
; Display ON/OFF Control: 0 0 0 0 0 0 1 D C B (D: display on/off, C: cursor on/off, B: blinking cursor on/off)
; 0000001111 (display on, blinking cursor)
ld a,0x0F
out (LCD_BOTTOM_INSTR_REG),a
call LCD4004_wait_busy_clear
; Clear display
; 0000000001
ld a,0x01
out (LCD_BOTTOM_INSTR_REG),a
call LCD4004_wait_busy_clear
ret
; Prints string
; @param BC Pointer to a null-terminated string first character
LCD4004_TOP_print:
ld a, (bc) ; bc is the pointer to passed string's first char
cp 0 ; compare A content with 0 (subtract 0 from value and set zero flag Z if result is 0)
ret z ; if prev compare is true (Z flag set), string is finished, return
out (LCD_TOP_DATA_REG),a ; output char
call LCD4004_wait_busy_clear ; wait for the lcd to execute (busy signal check)
inc bc ; increment bc to move to next char
jp LCD4004_TOP_print
; Prints string
; @param BC Pointer to a null-terminated string first character
LCD4004_BOTTOM_print:
ld a, (bc) ; bc is the pointer to passed string's first char
cp 0 ; compare A content with 0 (subtract 0 from value and set zero flag Z if result is 0)
ret z ; if prev compare is true (Z flag set), string is finished, return
out (LCD_BOTTOM_DATA_REG),a ; output char
call LCD4004_wait_busy_clear ; wait for the lcd to execute (busy signal check)
inc bc ; increment bc to move to next char
jp LCD4004_BOTTOM_print
; Waits for the busy flag to be clear, indicating the LCD controllers to have finished their work
LCD4004_wait_busy_clear:
ret
in a, (LCD_TOP_INSTR_REG) ; reads the status
rla ; busy flag is DB7, so we shift it into carry to check it
jp c, LCD4004_wait_busy_clear ; if carry is set, lcd is busy
in a, (LCD_BOTTOM_INSTR_REG) ; reads the status
rla ; busy flag is DB7, so we shift it into carry to check it
jp c, LCD4004_wait_busy_clear ; if carry is set, lcd is busy
ret
; --- TEST CODE ---
main:
TEST_STR_80: DB "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam augue tortor sed.",0 ; null terminated string
TEST_STR_85: DB "2Lorem ipsum dolor sit amet, consectetur adipiscing elit praesent pellentesque nisi.",0 ; null terminated string
; Init display
call LCD4004_init
; Write string on first 2 lines
ld bc, TEST_STR_80
call LCD4004_TOP_print
; Write long string on last 2 lines (to see how it wraps)
ld bc, TEST_STR_85
call LCD4004_BOTTOM_print
halt