; ; subroutines wcom and w_com_a ; Writes a byte to the LCD command register after checking the busy flag first ; Assumes the external memory interface is configured for split mode with bank ; select. ; inputs: ; wcom: r0 = byte to write to command register ; wcom_a: acc = byte to write to command register ; outputs: none ; destroys: ; wcom: EMI0CN ; wcom_a: EMI0CN, r0 wcom_a: mov r0,a ; save acc in R0 while we check BUSY wcom: mov EMI0CN,#HIGH LCD_CMD ; command/status register wcom1: movx a,@r0 ; r0 has no relevance here jb acc.7,wcom1 ; wait for not BUSY mov a,r0 ; get the actual data to write movx @r0,a ; write the command, r0 is irrelevant here ret ; ; subroutines wdat and w_dat_a and w_datc ; Writes a byte to the LCD data register after checking the busy flag first ; Assumes the external memory interface is configured for split mode with bank ; select. ; inputs: ; wdat: r0 = byte to write to data register ; wdat_a: acc = byte to write to data register ; wdat_c: acc = dptr-relative index (dptr[acc]) of byte to write to data register ; outputs: none ; destroys: ; wdat: EMI0CN ; wdat_a: EMI0CN, r0 ; wdat_c: EMI0CN, r0 wdat_c: movc a,@a+dptr ; lookup byte to write (handy for fonts) wdat_a: mov r0,a ; save it in R0 while we check BUSY wdat: mov EMI0CN,#HIGH LCD_CMD ; command/status register wdat1: movx a,@r0 ; r0 has no relevance here jb acc.7,wdat1 ; wait for not BUSY mov EMI0CN,#HIGH LCD_DAT ; data register mov a,r0 ; actual data to write movx @r0,a ; write the data, r0 is irrelevant here ret ; ; Initialize controller for S64128N LCD module ; inputs: none ; outputs: none ; destroys: r0, r2, r3, dptr ; init_lcd: mov p4,#not LCD_RESET mov emi0cf,#28H ; B5: P4-7, B4: non-muxed, B3-2 split bank mov emi0tc,#0CH ; pulse width 4 sysclock cycles mov p74out,#0FFH ; push-pull orl p4,#LCD_RESET ; assert then deassert reset mov R0,#02FH ; Boost on, voltage Reg and follower on call wcom mov R0,#0A2H; ; 1/9bias selected call wcom mov R0,#0A1H ; reverse segment driver output seg131-seg0 call wcom mov R0,#0C0H ; common output mode com0 to com63 call wcom mov R0,#024H ; Ra/Rb ratio call wcom mov R0,#081H ; electronic vloume mode set call wcom mov R0,#026H ; contrast call wcom mov R0,#040H ; display line address = 0 call wcom mov R0,#0A6H ; normal video call wcom mov R0,#0AFH ; display on call wcom call blank_screen ; fall through to refresh_screen ; ; subroutine refresh_screen ; Copies 1k bytes of data from external address 0 to the LCD. Bytes 0-7F go ; into page 0, bytes 80-FF go to page 1 etc. ; inputs: none ; outputs: none ; destroys: r0, r2, r3, dptr, EMI0CN ; refresh_screen: mov dptr,#0 ; start of 1k block of memory mov r2,#0B0H ; command to set page number to 0 page_loop: mov a,r2 ; set page number n, n = 0, 1, 2...7 call wcom_a mov a,#04H ; set column number to 4. If LCD is not call wcom_a ; inverted, you will want to set column mov a,#10H ; number to 0. call wcom_a mov r3,#128 ; copy 128 bytes byte_loop: movx a,@dptr ; get byte from memory call wdat_a ; and write it to the LCD inc dptr djnz r3,byte_loop inc r2 ; advance to next page, but bail if it is 8 (B8) cjne r2,#0B8H,page_loop ret