;---------------------------------------------------------
; Programa: monitor.asm
; Data:17/10/2011 08:59:20
; Autor: prof Vargas
;
; Este programa serve a placa universal 8253.  Neste caso, 
; em particular, atenderá as aplicações de comunicação 
; serial, e auto-check.
; A placa deve funcionar com 4 opções de ação, selecioná-
; veis pelos bits P04 e P05 obtidos do dipswitch da
; seguinte forma:
; P04		P05		AÇÃO
;  0     	 0		 manutenção
;  0		 1		 Transmissor
;  1		 0		 Receptor
;  1		 1		 Transmissor e receptor (dual)
;
; A função MANUTENÇÃO:
; --------------------
; Neste modo podemos efetuar testes de hardware local, 
; testando os displays, os dipswitchs e os botões.
; Descrição do Display:
;       a
;      ---
;    f| g |b
;      ---
;    e| d |c
;      ---
;
; No Proteus:        No projeto:
;   --- a
;   --- b			7 6 5 4 3 2 1 0 (P2)
;   --- c			c g f e d p b a
;   --- d
;   --- e
;   --- f
;   --- g
; Daí:
; F = 10001110	  8Eh		7 = 01111100  7Ch 
; E = 10000110	  86h		6 = 00000110  06h
; D = 00100101	  25h		5 = 00010110  16h
; C = 11000110	  C6h		4 = 00011101  1Dh
; B = 00000111	  07h		3 = 00110100  34h
; A = 00001100	  0Ch		2 = 10100100  A4h
; 9 = 00011100  1Ch		1 = 01111101  7Dh
; 8 = 00000100	  04h		0 = 01001000  44h
;
; Descrição DipSwitch:
;
;    +------------> P0.0
;    |+-----------> P0.1   Bits de 0000 a 1111
;    ||+----------> P0.2
;    |||+---------> P0.3
;    |||| 
;    oooooooo
;
;    oooooooo
;          ||
;          |+-----> P0.4   Modo de funcionamento
;          +------> P0.5
;---------------------------------------------------------

	org	0000h
	jmp	inicio

	org	0030h			;inicio do programa principal
inicio:
	;carrega os códigos do display em RAM partindo de 30h
	mov	30h,#44h		;0100 0100  [0]
	mov	31h,#7Dh		;0111 1101  [1]
	mov	32h,#A4h		;1010 0100  [2]
	mov	33h,#34h		;0011 0100  [3]
	mov	34h,#1Dh		;0001 1101  [4]
	mov	35h,#16h		;0001 0110  [5]
	mov	36h,#06h		;0000 0110  [6]
	mov	37h,#7Ch		;0111 1100  [7]
	mov	38h,#04h		;0000 0100  [8]
	mov	39h,#1Ch		;0001 1100  [9]
	mov	3Ah,#0Ch		;0000 1100  [A]
	mov	3Bh,#07h		;0000 0011  [b]
	mov	3Ch,#C6h		;1100 0110  [C]
	mov	3Dh,#25h		;0010 0101  [d]
	mov	3Eh,#86h		;1000 0110  [E]
	mov	3Fh,#8Eh		;1000 1110  [F]
denovo:
	mov		ie,#00h		;não aceita interrupção
	mov		p2,#FFh		;inicializa o display
;================================
; Seleção do modo a ser executado
; 0 -> ativo   1-> inativo
;================================
again:
	mov		a,p0	;recolhe DipS
	anl		a,#30h	; --dd------ => 0011 0000 = 30h
	rr		a
	rr		a
	rr		a
	rr		a		; obtem ------dd
	cjne	a,#03,next1
	ljmp	dual			; é 3 ... é Dual
next1:
	cjne	a,#02,next2
	ljmp	recebe			; é 2 ... é Recepção
next2:
	cjne	a,#01,manut		; é 0 ... é Manutenção
	ljmp	transm			; é 1 ... é Transmissão

;+++++++++++++++++++++++++++++++++++
; Modo Transmissão/Recepção => Dual
;+++++++++++++++++++++++++++++++++++
dual:
	mov		p2,#FFh		;apaga o display
laco:	
	clr		p2.2
	lcall	tem_1s
	setb	p2.2
	lcall	tem_1s
	ljmp	laco

;+++++++++++++++++
; Modo Recepção
;+++++++++++++++++
recebe:
	clr		p2.5
	lcall	tem01s
	clr		p2.0
	lcall	tem01s
	clr		p2.1
	lcall	tem01s
	clr		p2.7
	lcall	tem01s
	clr		p2.3
	lcall	tem01s
	clr		p2.4
	lcall	tem01s
	clr		p2.6
	lcall	tem01s
	lcall	tem01s
	setb	p2.5
	lcall	tem01s
	setb	p2.0
	lcall	tem01s
	setb	p2.1
	lcall	tem01s
	setb	p2.7
	lcall	tem01s
	setb	p2.3
	lcall	tem01s
	setb	p2.4
	lcall	tem01s
	setb	p2.6
	lcall	tem01s
	lcall	tem01s
	ljmp	recebe

;++++++++++++++++++++++++++++++++++++++++
; Modo Transmissão
; Sinaliza piscando o valor do dipswitch
;++++++++++++++++++++++++++++++++++++++++
transm:
	call	 Le_dip		;converte o valor do Dip para 7 seg
	lcall	tem_1s
	mov		p2,#FFh		;apaga
	lcall	tem_1s
	mov		p2,b		;acende
	ljmp	transm

;+++++++++++++++++
; Modo Manutenção
;+++++++++++++++++
manut:
	lcall	Le_dip		; converte o valor do Dip para 7 seg
	mov		p2,b
;-------------------------------------
; Temporiza ~ 5 seg e apaga o display 
;-------------------------------------
	lcall	tem_1s
	lcall	tem_1s
	lcall	tem_1s
	mov		p2,#FFh		;apaga o display
;------------------------------------------
; Teste dos push botton
; Como o valor do display 7seg está preservado em B,
; os push boton em teste podem liberar a exibição desse
; valor quando pressionados.
;-------------------------------------------
loopkey:	
	jnb		p0.6,SW1		;SW1 foi apertado
	jnb		p0.7,SW2		;SW2 foi apertado			
	jmp	 	loopkey

SW1:
	jnb		p0.6,$		;espera usuário soltar a tecla
	mov		p2,b		;apresenta valor no display
	lcall	tem_1s
	lcall	tem_1s
	lcall	tem_1s
	mov		p2,#FFh		;apaga display
	ljmp	manut		;continua manutenção

SW2:
	jnb		p0.7,$		;espera usuário soltar a tecla
	mov		p2,b		;apresenta valor no display
	lcall	tem_1s
	lcall	tem_1s
	lcall	tem_1s
	mov		p2,#FFh		;apaga display
	ljmp	manut		;continua manutenção

final:
	ljmp	again
	
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Sub-rotina Le_dip
; Lê o valor em binário do DIP SW4 e o converte
; para 7 segmentos enviando o valor lido dos DIP
; para o display em P2 e o preserva em B
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Le_dip:
	mov		r0,#30h		; endereço inicial displays
	mov		a,p0		;recolhe o estado do dipswitch	
	anl		a,#0Fh		;elimina bits high desnecessários
	add		a,r0		;aponta para equivalencia 7seg
	mov		r0,a
	mov		b,@r0		;Obtêm o valor de 7 segmentos
	ret

;===================
; Subrotina tem_1s
;===================
tem_1s:
	mov		r5,#FFh		; 1µs
	mov		r6,#FFh		; 1µs
	mov		r7,#8		; 1µs
salto1: 
	djnz	r5,salto1	;2µs-(2µs x 255 x 255 x 7) = 0.91 seg
	mov		r5,#FFh		;1µs - (1µs x 255 x 7) = 1.7ms
	djnz	r6,salto1	;2µs - (2µs x 255 x 7) = 3.57ms
	mov		r6,#FFh		;1µs - (1µs x 7) = 7µs
	djnz	r7,salto1	;2µs - (2µs x 7) = 14µs
	ret					;2µs

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
; sub-rotina tem01s
; As instruções do 8051 levam ~ 1µs para serem
; executadas - desde que o cristal seja de 
; 12 MHz -, porém algumas instruções de desvio
; como a djnz são executadas em 2µs.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tem01s:  
	mov	r5,#255		; --------- (1µs)
	mov	r6,#255		;­ --------- (1µs)

salt: 
	djnz  r5,salt	;2µs => (2µs x 255 x 255) = 130 ms
	mov   r5,#255	;1µs =>       (1µs x 255) = 255 µs
	djnz  r6,salt	;2µs =>       (2µs x 255) = 500 µs
	mov   r6,#255	;1µs =>             (1µs) =   1 µs
	ret				;2µs
;------------------------------------- Total: 130 ms

	end

