; coded by:
; Gozalo, Conrad Miguel E.
; Lauw, Boon Kristoffer P.
; Rodriguez, Tomas Miguel P.

; LCD program taken from edsim51.com
; works on EdSim51

; FREE FALL MOTION TIMER PROGRAM

ORG 000h	;initializes 8051 to start at program code 0 (start)

FIRST EQU R7	;declaration of place values
SECOND EQU R6		;”first” place value is the 0.0001’s place,
THIRD EQU R5		;”second place” value is the 0.001’s place,
FOURTH EQU R4		;up to “fifth” place which is the 1’s place
FIFTH EQU R3

start:		;start subroutine

MOV TMOD, #00000010b	;initializes timer to work on 8-bit auto-reload
mov th0,#156		;initializes reload value to 156
mov tl0,#156		;initializes the timer’s initial value to 156 

;156 was derived from (256-100) so that each timer overflow will
;result to 100 nanoseconds

JB P2.0, $			;jump to same command until the ball is
;detected

SETB TR0			;start timer0 (TR0 means timer run 0)

MOV IE,#88h

loop:
	JNB TF0, $		;wait until timer 0 overflows

	;the following code will be on incrementing place value

	CJNE FIRST, #9, incrementfirst
	MOV FIRST, #0
	CJNE SECOND, #9, incrementsecond
	MOV SECOND, #0
	CJNE THIRD, #9, incrementthird
	MOV THIRD, #0
	CJNE FOURTH, #9, incrementfourth
	MOV FOURTH, #0
	CJNE FIFTH, #9, incrementfifth
	MOV FIFTH, #0

checkstop:
	CLR TF0		;clear overflow flag
	JNB P2.1, stop		;if ball reaches ground
					;	then stop timer
					;else continue counting and continue loop
	JMP loop

;the next codes will be for carrying in addition (for place values)

incrementfirst: INC FIRST
			JMP checkstop
incrementsecond: INC SECOND
			JMP checkstop
incrementthird: INC THIRD
			JMP checkstop
incrementfourth: INC FOURTH
			JMP checkstop
incrementfifth: INC FIFTH
			JMP checkstop

stop:				;stop timer and display
	CLR TR0


; put data in RAM
	MOV A, FIFTH
	MOV DIVIFIFTH, A
	CALL lookup
	MOV 30h, A
	MOV 31h, #'.'
	MOV A, FOURTH
	MOV DIVIFOURTH, A
	CALL lookup
	MOV 32h, A
	MOV A, THIRD
	MOV DIVITHIRD, A
	CALL lookup
	MOV 33h, A
	MOV A, SECOND
	MOV DIVISECOND, A
	CALL lookup
	MOV 34h, A
	MOV A, FIRST
	MOV DIVIFIRST, A
	CALL lookup
	MOV 35h, A



; initialise the display
; see instruction set for details


	CLR P1.3		; clear RS - indicates that instructions are being sent to the module

; function set	
	CLR P1.7		; |
	CLR P1.6		; |
	SETB P1.5		; |
	CLR P1.4		; | high nibble set

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E

	CALL delay		; wait for BF to clear	
				; function set sent for first time - tells module to go into 4-bit mode
; Why is function set high nibble sent twice? See 4-bit operation on pages 39 and 42 of HD44780.pdf.

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E
				; same function set high nibble sent a second time

	SETB P1.7		; low nibble set (only P1.7 needed to be changed)

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E
				; function set low nibble sent

	CALL delay		; wait for BF to clear


; entry mode set
; set to increment with no shift
	CLR P1.7		; |
	CLR P1.6		; |
	CLR P1.5		; |
	CLR P1.4		; | high nibble set

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E

	SETB P1.6		; |
	SETB P1.5		; |low nibble set

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E
	CALL delay		; wait for BF to clear


; display on/off control
; the display is turned on, the cursor is turned on and blinking is turned on
	CLR P1.7
	CLR P1.6
	CLR P1.5
	CLR P1.4
				; high nibble set
	SETB P1.2		; |
	CLR P1.2		; | negative edge on E
	SETB P1.7
	SETB P1.6
	SETB P1.5
	SETB P1.4
				; low nibble set
	SETB P1.2		; |
	CLR P1.2		; | negative edge on E
	CALL delay		; wait for BF to clear


; send data
	SETB P1.3		; clear RS - indicates that data is being sent to module
	MOV R1, #30H
loop:
	MOV A, @R1
	JZ finish
	CALL sendCharacter
	INC R1
	JMP loop

finish:
	MOV A, #' '
	CALL sendCharacter
	MOV A, #'F'
	CALL sendCharacter
	MOV A, #'F'
	CALL sendCharacter
	MOV A, #'M'
	CALL sendCharacter
	MOV A, #'T'
	CALL sendCharacter
	JMP $

sendCharacter:
	MOV C, ACC.7		; |
	MOV P1.7, C		; |
	MOV C, ACC.6		; |
	MOV P1.6, C		; |
	MOV C, ACC.5		; |
	MOV P1.5, C		; |
	MOV C, ACC.4		; |
	MOV P1.4, C		; | high nibble set

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E

	MOV C, ACC.3		; |
	MOV P1.7, C		; |
	MOV C, ACC.2		; |
	MOV P1.6, C		; |
	MOV C, ACC.1		; |
	MOV P1.5, C		; |
	MOV C, ACC.0		; |
	MOV P1.4, C		; | low nibble set

	SETB P1.2		; |
	CLR P1.2		; | negative edge on E

	CALL delay		; wait for BF to clear

delay:
	MOV R0, #50
	DJNZ R0, $
	RET

