
#include "8051equ.inc"

.org	00h
	ajmp	start

.org	0bh
	reti

.org	13h
	reti

.org	1bh
	reti

.org	23h
	reti

.org	25h

initialize:
	; start timer 0 - 16 bit timer mode
	mov	TMOD, #01h
	setb	TR0

	mov	PSW, #00h
	mov	IE, #00h
	ret

; delay for 1 ms (11.0592 MHz crystal)
delay_ms:
	mov	r7, #00h
loop_1:
	inc	r7
	mov	a, r7
	cjne	a, #0ffh, loop_1
	ret

; 8-bit binary to bcd converter
; a  - input value
; r2 - output digit 1
; r3 - output digit 2
; r4 - output digit 3
bin_to_bcd:
	mov	r2, #00h
	mov	r3, #00h
	mov	r4, #00h

	mov	B, #010d
	div	ab
	mov	r4, B
	mov	B, #010d
	div	ab
	mov	r3, B
	mov	B, #010d
	div	ab
	mov	r2, B
	ret

display_0:
	mov	P1, #00001001b
	ret

display_1:
	mov	P1, #11101011b
	ret

display_2:
	mov	P1, #01000101b
	ret

display_3:
	mov	P1, #01100001b
	ret

display_4:
	mov	P1, #10100011b
	ret

display_5:
	mov	P1, #00110001b
	ret

display_6:
	mov	P1, #00010001b
	ret

display_7:
	mov	P1, #01101011b
	ret

display_8:
	mov	P1, #00000001b
	ret

display_9:
	mov	P1, #00100011b
	ret

; displays 3 digit BCD number in A register
display_bcd:
	cjne	a, #00h, check1
	acall	display_0
	ret
check1:
	cjne	a, #01h, check2
	acall	display_1
	ret
check2:
	cjne	a, #02h, check3
	acall	display_2
	ret
check3:
	cjne	a, #03h, check4
	acall	display_3
	ret
check4:
	cjne	a, #04h, check5
	acall	display_4
	ret
check5:
	cjne	a, #05h, check6
	acall	display_5
	ret
check6:
	cjne	a, #06h, check7
	acall	display_6
	ret
check7:
	cjne	a, #07h, check8
	acall	display_7
	ret
check8:
	cjne	a, #08h, disp9
	acall	display_8
	ret
disp9:
	acall	display_9
	ret
		
start:
	acall	initialize

	; set P3.0 to be used as an input
	setb	P3.0	

	; wait until switch is pressed
	jb	P3.0, $

random:
	mov	a, TL0

	; wait for switch to be released
	jnb	P3.0, $
	acall	bin_to_bcd

display_loop:
	mov	a, r2
	acall	display_bcd
        
        ; turn on 7-segment display 1
	setb	P3.3
	acall	delay_ms
	clr	P3.3

	mov	a, r3
	acall	display_bcd

        ; turn on 7-segment display 2
	setb	P3.4
	acall	delay_ms
	clr	P3.4

	mov	a, r4
	acall	display_bcd

        ; turn on 7-segment display 3
	setb	P3.5
	acall	delay_ms
	clr	P3.5

        ; display same number until switch is pressed
	jb	P3.0, display_loop
	ajmp	random
	
.end
