
RS	Bit	P0.0
RW	Bit	P0.1
E_Clock	Bit	P0.2
P13     Bit     7Eh

	CSEG
	Org	$

Init_LCD:
	Push	IE
	Clr	ET0
	Mov	R7,#10
	Lcall	Delayx10mS
	Clr	E_Clock			;E Clock diberi kondisi awal low
	Mov	A,#30H			;Kirim 30H
	Lcall	Kirim_Perintah		;
        Mov     R7,#10
	Lcall	Delayx10mS

	Mov	A,#30H			;Kirim 30H
	Lcall	Kirim_Perintah		;
        Mov     R7,#10
	Lcall	Delayx10mS

	Mov	A,#30H			;Kirim 30H
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy
	
	Mov	A,#20H			;Send Init
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy

	Mov	A,#2FH			;8x5 2lines
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy
	
	Mov	A,#08H			;
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy
	
	Mov	A,#01H			;
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy

	Mov	A,#07H			;
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy

	Mov	A,#0CH			;Display ON
        Lcall   Kirim_Perintah          ;Cursor OFF
;	Lcall	Tunggu_Busy

	Mov	A,#06H			;Mode Increment Address
	Lcall	Kirim_Perintah		;
;	Lcall	Tunggu_Busy
	Pop	IE
	Ret


ClearLCD:
	Mov	A,#01h

;*********************************************
;* Pengiriman data ke LCD ada 2 macam yaitu:
;* - Pengiriman perintah di mana data yang dikirim masuk ke Control Register
;*   RS = 0
;* - Pengiriman karakter di mana data yang dikirim masuk ke Data Register
;*   RS = 1
;*********************************************
Kirim_Perintah:
	Push	IE
	Clr	ET0
	Clr	RS
	Lcall	Kirim_DataLCD		;Kirim High Nibble ke LCD
	Swap	A			;
	Lcall	Kirim_DataLCD		;Kirim Low Nibble ke LCD
	Lcall	Tunggu_Busy
	Lcall	Tunggu_Busy
	Pop	IE
	Ret

Kirim_Karakter:
	Push	IE
	Clr	ET0
	Setb	RS	
	Lcall	Kirim_DataLCD		;Kirim High Nibble ke LCD
	Swap	A			;
	Lcall	Kirim_DataLCD		;Kirim Low Nibble ke LCD
	Lcall	Tunggu_Busy
	Pop	IE
	Ret

;*******************
;* Subroutine ini digunakan oleh subroutine kirim karakter ataupun
;* kirim perintah untuk mengirimkan data ke LCD dengan teknik 4 bit interface
;*******************
Kirim_DataLCD:
	Clr	RW			;LCD mode write
	Push	ACC			;Simpan data yang dikirim di Stack	
	Anl	A,#0F0H			;Hapus bit 3 ... bit 0 dari data
                                        ;yang dikirim
	Anl	P0,#0FH			;Hapus bit 4 ... bit 7 dari Port 1
	Orl	A,P0			;Pindahkan bit 4 .. bit 7 dari data
					;tanpa mengganggu bit 3 ... bit 0
        Push    PSW
        Mov     C,P13
        Mov     ACC.3,C
        Pop     PSW
	Mov	P0,A			;Port 1
	Setb	E_Clock			;Beri 1 pulsa clock
	Clr	E_Clock			;
	Pop	ACC			;Ambil data yang dikirim dari Stack
	ret



Baca_IR:
	Setb	RW			;LCD Mode Read
	Clr	RS			;Pembacaan Register Instruksi, RS = 0
	Lcall	BacaData_LCD		;Baca Data High Nibble
	Push	ACC			;
	Lcall	BacaData_LCD		;Baca Data Low Nibble
	Pop	B			;
	Swap	A			;Gabungkan High Nibble
	Add	A,B			;dan Low Nibble
	Ret


BacaData_LCD:
	Orl	P0,#0F0H		;Jadikan P1.4 .. P1.7 sebagai
					;input tanpa mengganggu P1.0 ... P1.3
	Setb	E_Clock			;Clock high
	Mov	A,P0			;Ambil data dari Port 1
	Clr	E_Clock			;Clock Low
	Anl	A,#0F0H			;Hapus bit 3 ... bit 0
	Ret

;Rutin-rutin perintah LCD
Baris2_LCD:
	Mov	A,#0C0H
	Lcall	Kirim_Perintah
;	Lcall	Tunggu_Busy
	Ret

Baris1_LCD:
	Mov	A,#02H
	Lcall	Kirim_Perintah
	Lcall	Tunggu_Busy

	Ret



;----------------------
;Geser Cursor ke kiri

GeserCursor_Kiri:
	Mov	A,#10H
	lcall	Kirim_Perintah
;	Lcall	Tunggu_Busy
	Ret

;----------------------
;Geser Cursor ke kanan

GeserCursor_Kanan:
	Mov	A,#14H
	lcall	Kirim_Perintah
;	Lcall	Tunggu_Busy
	Ret


Tunggu_Busy:
	Push	B
	Mov	B,#1
LoopDelayBusy:
	Push	B
	Mov	B,#0
	Djnz	B,$
	Pop	B

	Djnz	B,LoopDelayBusy
	Pop	B
	Ret



	Push	ACC
LoopTunggu_Busy:
	Lcall	Baca_IR
        Jb      ACC.7,LoopTunggu_Busy
	Pop	ACC
	Ret


KirimPesan_LCD:
LoopKirimPesan_LCD:
	Mov	A,#00H			;Ambil data dari memori yg ditunjuk
	Movc	A,@A+Dptr		;
	Cjne	A,#0FH,Kirim_LCD	;Kirim ke LCD selama belum ditemukan
	Ret				;0FH
	
Kirim_LCD:
	lcall	Kirim_Karakter
	Inc	Dptr			;Tunjuk ke memori selanjutnya
	Ljmp	LoopKirimPesan_LCD


;===================================
; MENAMPILKAN 2 BARIS LCD

LCD2Baris:
	Lcall	KirimPesan_LCD
	Lcall	Baris2_LCD
	Inc	DPTR
	Lcall	KirimPesan_LCD
	Ret


;===================================
; MENAMPILKAN 1 BYTE DATA BCD KE 2 BYTE ASCII DI LCD
OutLCD2B:
	Lcall	Hex_ASCII2
	Push	B
	Lcall	Kirim_Karakter
        Pop     ACC
	Lcall	Kirim_Karakter	
	Ret

OutLCDDesimal:
	Mov	R0,#TabelDesimal
	Mov	@R0,#00
	Inc	R0
	Mov	@R0,#00
	Inc	R0
	Mov	@R0,#00
	Mov	R0,#TabelDesimal
	lcall	konversi1bDesimal
	Mov	R0,#TabelDesimal+2
	Mov	A,@R0
	Add	A,#30h
	Lcall	Kirim_Karakter
	Dec	R0
	Mov	A,@R0
	Add	A,#30h
	Lcall	Kirim_Karakter
	Dec	R0
	Mov	A,@R0
	Add	A,#30h
	Lcall	Kirim_Karakter		
	Ret
