;; ****************************************************************************
;; LCD module for PIC12/16 Pseudo Operating System
;; ****************************************************************************

	LIST	P=PIC16F88
	INCLUDE	"P16F88.INC"
	INCLUDE	"MACRO.INC"

; *** Define constant ***
	IFNDEF	LCD_PORT
#DEFINE		LCD_PORT			;define LCD net list
#DEFINE		LCD_DB4		PORTA,D'3'
#DEFINE		LCD_DB5		PORTA,D'2'
#DEFINE		LCD_DB6		PORTA,D'1'
#DEFINE		LCD_DB7		PORTA,D'0'
#DEFINE		LCD_RS		PORTB,D'1'
#DEFINE		LCD_RW		PORTB,D'0'
#DEFINE		LCD_E		PORTB,D'2'
	ENDIF

; *** Request register/routine ***
	EXTERN	ARGUMENT0
	EXTERN	ARGUMENT1
	EXTERN	TEMP0
	IFNDEF	SP
	EXTERN	SP
	ENDIF

; *** Provide register/routine ***
	GLOBAL	LCD_INITIALIZE			;Initialize
	GLOBAL	LCD_COMMAND			;Command output
	GLOBAL	LCD_DATAOUT			;Data output
	GLOBAL	LCD_MOVE			;Cursor move

;;  ______________________________________________
;; |                                              |
;; | ** +-------------------------------------+   |
;; | ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | * |
;; | ** | | |L|C|D| |M|o|d| |u|l|e| |f|o|r| | | * |
;; | ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |   |
;; | ** | |P|I|C|1|2|/|1|6| |F| |S|e|r|i|e|s| | * |
;; | ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | * |
;; | ** +------------------------------------ +   |
;; |______________________________________________|

; *** Program area ***
	CODE

; *** LCD driver macro ***
;;; LCD Output High
OUTHIGH	MACRO	_ARG
	IF	_ARG>=H'0080'
	ERROR	"_ARG must in bank0"
	ENDIF
	BANKSEL(PORTA)
	;DB7 output
	BCF	LCD_DB7
	BTFSC	_ARG,D'7'
	BSF	LCD_DB7
	;DB6 output
	BCF	LCD_DB6
	BTFSC	_ARG,D'6'
	BSF	LCD_DB6
	;DB5 output
	BCF	LCD_DB5
	BTFSC	_ARG,D'5'
	BSF	LCD_DB5
	;DB4 output
	BCF	LCD_DB4
	BTFSC	_ARG,D'4'
	BSF	LCD_DB4
	ENDM
;;; LCD Output Low
OUTLOW	MACRO	_ARG
	IF	_ARG>=H'0080'
	ERROR	"_ARG must in bank0"
	ENDIF
	BANKSEL(PORTA)
	;DB7 output
	BCF	LCD_DB7
	BTFSC	_ARG,D'3'
	BSF	LCD_DB7
	;DB6 output
	BCF	LCD_DB6
	BTFSC	_ARG,D'2'
	BSF	LCD_DB6
	;DB5 output
	BCF	LCD_DB5
	BTFSC	_ARG,D'1'
	BSF	LCD_DB5
	;DB4 output
	BCF	LCD_DB4
	BTFSC	_ARG,D'0'
	BSF	LCD_DB4
	ENDM
;;; LCD Busycheck
CHECK	MACRO
	LOCAL	READY,BUSY
	BANKSEL(TRISA)
	BSF	LCD_DB4
	BSF	LCD_DB5
	BSF	LCD_DB6
	BSF	LCD_DB7
	BANKSEL(PORTA)
BUSY
	;LCD Busy
	BCF	LCD_RS				;Command
	BSF	LCD_RW				;Write
	BSF	LCD_E
	FILL	(NOP),D'4'
	BTFSS	LCD_DB7				;Busycheck
	GOTO	READY
	BCF	LCD_E
	FILL	(NOP),D'4'
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	GOTO	BUSY
READY
	;LCD Ready
	BCF	LCD_E
	FILL	(NOP),D'4'
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	BANKSEL(TRISA)
	BCF	LCD_DB4
	BCF	LCD_DB5
	BCF	LCD_DB6
	BCF	LCD_DB7
	ENDM

; *** LCD Initialize ***
LCD_INITIALIZE
	;Port initialize
	BANKSEL(TRISA)
	BCF	LCD_DB4
	BCF	LCD_DB5
	BCF	LCD_DB6
	BCF	LCD_DB7
	BCF	LCD_RS
	BCF	LCD_RW
	BCF	LCD_E
	;LCD initialize sequence
	;Wait for 15ms
	WAIT_MS	TEMP0,D'15'
	;Set 8bit mode
	PUSH	ARGUMENT0
	MOVLW	B'00110000'
	MOVWF	ARGUMENT0
	OUTHIGH	ARGUMENT0			;Data High half Byte
	POP	ARGUMENT0
	BANKSEL(PORTA)
	BCF	LCD_RW				;Write
	BCF	LCD_RS				;Command
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	;Wait for 5ms
	WAIT_MS	TEMP0,D'5'
	;Set 8bit mode
	PUSH	ARGUMENT0
	MOVLW	B'00110000'
	MOVWF	ARGUMENT0
	OUTHIGH	ARGUMENT0
	POP	ARGUMENT0
	BCF	LCD_RW				;Write
	BCF	LCD_RS				;Command
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	;Wait for 100us
	WAIT_US	TEMP0,D'100'
	;Set 8bit mode
	PUSH	ARGUMENT0
	MOVLW	B'00110000'
	MOVWF	ARGUMENT0
	OUTHIGH	ARGUMENT0
	POP	ARGUMENT0
	BCF	LCD_RW				;Write
	BCF	LCD_RS				;Command
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	;Wait for 100us
	WAIT_US	TEMP0,D'100'
	;Set 4bit mode
	PUSH	ARGUMENT0
	MOVLW	B'00100000'
	MOVWF	ARGUMENT0
	OUTHIGH	ARGUMENT0
	POP	ARGUMENT0
	BCF	LCD_RW				;Write
	BCF	LCD_RS				;Command
	BSF	LCD_E
	FILL	(NOP),D'4'
	BCF	LCD_E
	;Wait for 100us
	WAIT_US	TEMP0,D'100'
	;Function set
	PUSH	ARGUMENT0
	MOVLW	B'00101100'
	MOVWF	ARGUMENT0
	JUMP	LCD_COMMAND
	;Display OFF
	MOVLW	B'00001000'
	MOVWF	ARGUMENT0
	JUMP	LCD_COMMAND
	;Display ON
	MOVLW	B'00001100'
	MOVWF	ARGUMENT0
	JUMP	LCD_COMMAND
	;Clear all and cursor home
	MOVLW	B'00000001'
	MOVWF	ARGUMENT0
	JUMP	LCD_COMMAND
	;Entry mode set
	MOVLW	B'00000110'
	MOVWF	ARGUMENT0
	JUMP	LCD_COMMAND
	POP	ARGUMENT0
	BACK

; *** LCD Command ***
LCD_COMMAND
	CHECK				;Busy Check
	;       Output high 4bit       Output low 4bit
	;       ___ ______________ ___ ___ ______________ ___
	;DB4-7  ___X______________X___ ___X______________X___
	;  _    _____
	;R/W         \________________ ______________________
	;       _______
	;RS            \______________ ______________________
	;                 __                     __
	;E(STB) _________/  \_________ _________/  \_________
	;              ->|  |<- more than 220ns
	OUTHIGH	ARGUMENT0
	BCF	LCD_RW				;Write
	BCF	LCD_RS				;Command
	BSF	LCD_E				;Enable
	FILL	(NOP),D'4'
	BCF	LCD_E
	OUTLOW	ARGUMENT0
	BSF	LCD_E				;Enable
	FILL	(NOP),D'4'
	BCF	LCD_E
	BACK

; *** LCD Data output ***
LCD_DATAOUT
	CHECK				;Busy Check
	;       Output high 4bit       Output low 4bit
	;       ___ ______________ ___ ___ ______________ ___
	;DB4-7  ___X______________X___ ___X______________X___
	;  _    _____
	;R/W         \________________ ______________________
	;               ______________ ______________________
	;RS     _______/
	;                 __                     __
	;E(STB) _________/  \_________ _________/  \_________
	;              ->|  |<- more than 220ns
	OUTHIGH	ARGUMENT0
	BCF	LCD_RW				;Write
	BSF	LCD_RS				;Data
	BSF	LCD_E				;Enable
	FILL	(NOP),D'4'
	BCF	LCD_E
	OUTLOW	ARGUMENT0
	BSF	LCD_E				;Enable
	FILL	(NOP),D'4'
	BCF	LCD_E
	BACK

; *** LCD Cursor Move ***
LCD_MOVE
	MOVF	ARGUMENT0,W			;Load LCD clumn
	BANKSEL(ARGUMENT1)
	BTFSC	ARGUMENT1,D'0'			;Check LCD line
	ADDLW	H'40'
	BTFSC	ARGUMENT1,D'1'			;Check LCD line
	ADDLW	H'14'
	IORLW	B'10000000'
	MOVWF	ARGUMENT0
	GOTO	LCD_COMMAND

	END

; ______________________________________________
;|                                              |
;| ** +-------------------------------------+   |
;| ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | * |
;| ** | | | | | | | | | | | | | | | | | | | | * |
;| ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |   |
;| ** | | | | | | | | | | | | | | | | | | | | * |
;| ** | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | * |
;| ** +------------------------------------ +   |
;|______________________________________________|

; ______________________________________________________
;|                                                      |
;|    +---------------------------------------------+   |
;|    | +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ |   |
;| ** | | | | | | | | | | | | | | | | | | | | | | | |   |
;| ** | +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ | * |
;| ** | | | | | | | | | | | | | | | | | | | | | | | | * |
;| ** | +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ |   |
;| ** | | | | | | | | | | | | | | | | | | | | | | | | * |
;| ** | +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ | * |
;| ** | | | | | | | | | | | | | | | | | | | | | | | |   |
;|    | +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ |   |
;|    +-------------------------------------------- +   |
;|______________________________________________________|

;; ****************************************************************************
;;
;;  Copyright (c) Hitoshi Gomi
;;  All rights reserved.
;;
;;  Redistribution and use in source and binary forms, with or without
;;  modification, are permitted provided that the following conditions are met:
;;
;;  1.Redistributions of source code must retain the above copyright notice,
;;    this list of conditions and the following disclaimer.
;;  2.Redistributions in binary form must reproduce the above copyright notice,
;;    this list of conditions and the following disclaimer in the documentation
;;    and/or other materials provided with the distribution.
;;  3.The names of the author may not be used to endorse or promote products
;;    derived from this software without specific prior written permission.
;;
;;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;;  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;;  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;;  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
;;  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;;  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;;  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;;  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;;  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;;  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;;  POSSIBILITY OF SUCH DAMAGE.
;;
;; ****************************************************************************