;**********************************************************************
;                                                                     *
;    Filename:	    TVSyncGen.asm                                     *
;    Date:          13/07/2008                                        *
;    File Version:  0.1                                               *
;                                                                     *
;    Author:        Rubén Arranz                                      *
;    Company:       Electronics Design                                *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files required:                                                  *
;                    16F648A.lkr                                      *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;                                                                     *
;                                                                     *
;                                                                     *
;**********************************************************************

	list      p=16F648A           ; list directive to define processor
	#include <p16F648A.inc>       ; processor specific variable definitions

	errorlevel  -302              ; suppress message 302 from list file

	__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC 

;Variables Tenemos disponibles desde 0x20 hasta 0x7F en el Banco 0
;Mirar Datasheet para los otros bancos de memoria.

SYNCSTAT	equ		0x20	;Controla el Status del Sincronismo
LINEA		equ		0x21	;Contador de línea interlazada como son 253 líneas nos alcanza con 1 byte
d1			equ		0x22	;Variable para delay



;*** Constantes
SINC		equ		H'0000'	;Señal de Sincronismo
LUMI		equ		H'0001'	;Señal de Luminancia
;Por ahora solo será pixel encendido o apagado


;**********************************************************************
RESET_VECTOR	CODE	0x000			;Vector de Reset del Procesador

		goto	Rst

VECT_INT		CODE	0x004			;Vector de Interrupción del Procesador
		goto	Rst

MAIN			CODE	0x005			;Sector de Inicio del Block de Programa
Rst
		movlw	0x07
		movwf	CMCON					;Desactivamos los comparadores del Puerto A
		clrf	PORTA					;Ponemos las salidas del Puerto A en 0
		bsf		STATUS,RP0				;Me cambio al Banco de memoria 1
		clrf 	TRISA					;Todo el puert A como salidas
		clrf	TRISB					;Todo el puert B como salidas
		bcf		STATUS,RP0				;Vuelvo al Banco 0
;---------------------------------------------------------------------------------

;*** Rutina principal
Inicio

; Tenemos entoces que hacer lo siguiente:
; 6 Pulsos de Pre-ecualización
; 6 Pulsos de Sincronismo
; 6 Pulsos de Post-ecualización
; Todo esto lo realiza la Rutina VSincro

		call	VSincro
		
; Luego hacemos
; 252 Cuadros Normales
		movlw	0xFC
        movwf	LINEA			;Cargo la Variable línea con 252 (Que son los cuadros normales)

;*** Cuadros Normales
;*************************************************************************************************************************************
;*** La rutina deberá ser capáz de generar una señal de la forma siguiente
;***
;*** 100%                                                   _
;***                                _                      / \
;***       |                       / \      __   /\___/\  /   \/\
;***       |                    /\/   \  __/  \_/       \/      |
;***       |                   |       \/                       |
;***  30%  |_____         _____|                                |_____         _____
;***             |       |                                            |       |
;***             |       |                                            |       |
;***   0%        |_______|                                            |_______|
;***
;***       |<-A->|<--B-->|<-C->|<--------------E--------------->|<-A->|<--B-->|
;***       |<--------------------- 63.5 us -------------------->|
;***
;*** A:  1.5 us Llamado Portal Anterior (Front Porsh) previo a la Señal de Sincronismo vertical
;*** B:  4.7 us Sincronismo vertical
;*** C:  4.7 us Portal Posterior (Back Porsh) Posterior a la Señal de Sincronismo
;*** E: 52.6 us Que corresponden al tiempo donde se envía la señal de video propiamente
;*** La señal de sincronismo entonces ocupa los tiempos A+B+C y representan un total de 10.9 us
;*************************************************************************************************************************************

Campo_0
;Se genera ahora la imagen de Video
;*** Portal Anterior, Parte A de la Señal
		bsf		PORTB,SINC
		call	Wait_A			;(1.4 us) Uso 1.4 en lugar de 1.5 ya que otras demoras lograrán el tiempo adecuado
;*** Sincronismo Vertical propiamente, parte B de la Señal
		bcf		PORTB,SINC
		call	Wait_B			;(4.6 us) Uso 4.6 en lugar de 4.7 ya que otras demoras lograrán el tiempo adecuado
;*** portal posterior, Parte C de la Señal
		bsf		PORTB,SINC
		call	Wait_B			;(4.6 us) Uso 4.6 en lugar de 4.7 ya que otras demoras lograrán el tiempo adecuado
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla (Parte E de la Señal)
;*** por ahora solo esperaremos el tiempo de imagen (52.6 us)
		call	Wait_E			;(52.6 us)
		decfsz	LINEA,f			;Me fijo si se completaron las 252 líneas...
		goto	Campo_0			;Aún no, repetimos esta parte
		
; 1/2 Cuadro Correspondiente a la línea 253
;*************************************************************************************************************************************
;*** La rutina deberá ser capáz de generar una señal de la forma siguiente
;***
;*** 100%                                      
;***                                _          
;***       |                       / \      __ 
;***       |                    /\/   \  __/  \
;***       |                   |       \/      |
;***  30%  |_____         _____|               |_____
;***             |       |                           |       |
;***             |       |                           |       |
;***   0%        |_______|                           |_______|
;***
;***       |<-A->|<--B-->|<-C->|<--- 1/2 E --->|<-A->|<--B-->|
;***       |<--------------- 37.9 us --------------->|
;***
;*** A:  1.5 us Llamado Portal Anterior (Front Porsh) previo a la Señal de Sincronismo vertical
;*** B:  4.7 us Sincronismo vertical
;*** C:  4.7 us Portal Posterior (Back Porsh) Posterior a la Señal de Sincronismo
;*** 1/2 E: 27 us Que corresponden al tiempo donde se envía la señal de video propiamente
;*** La señal de sincronismo entonces ocupa los tiempos A+B+C y representan un total de 10.9 us
;*************************************************************************************************************************************

;*** Ahora debo generar el sincronismo horizontal y media línea, correspondiente a la 253
;*** Portal Anterior, Parte A de la Señal
		bsf		PORTB,SINC
		call	Wait_A			;(1.4 us) Uso 1.4 en lugar de 1.5 ya que otras demoras lograrán el tiempo adecuado
;*** Sincronismo Vertical propiamente, parte B de la Señal
		bcf		PORTB,SINC
		call	Wait_B			;(4.6 us) Uso 4.6 en lugar de 4.7 ya que otras demoras lograrán el tiempo adecuado
;*** portal posterior, Parte C de la Señal
		bsf		PORTB,SINC
		call	Wait_B			;(4.6 us) Uso 4.6 en lugar de 4.7 ya que otras demoras lograrán el tiempo adecuado
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla (Parte E de la Señal)
;*** por ahora solo esperaremos el tiempo de imagen (27 us)
		call	Wait_E2			;(27 us)

;*** De ahora en más entramos en el segundo campo, de las líneas pares
; Debemos hacer:
; 6 Pulsos de Pre-ecualización
; 6 Pulsos de Sincronismo
; 6 Pulsos de Post-ecualización
; esto lo realiza la rutina VSincro

		call	VSincro
;*** Ahora debo esperar el tiempo faltante correspondiente a 1/2 línea
		call	Wait_E2			;(27 us)

;*** Finalmente dibujo las 252 Líneas del Campo 1
;*** Cuadros Normales
		movlw	0xFC
        movwf	LINEA			;Cargo la Variable línea con 252 (Que son los cuadros normales)

Campo_1
;*** Portal Anterior
		bsf		PORTB,SINC
		call	Wait_A			;(1.4 us)
		bcf		PORTB,SINC
		call	Wait_B			;(4.6 us)
		bsf		PORTB,SINC
		call	Wait_B			;(4.6 us)
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla
;*** por ahora solo esperaremos el tiempo de imagen (52.6 us)
		call	Wait_E			;(52.6 us)
		decfsz	LINEA,f
		goto	Campo_1
		goto	Inicio			;Finalmente Repetimos la rutina


VSincro
;*** Sincronismo Vertical
;*** La parte dificil viene en los sincronismos verticales
;*** La "National Television Systems Committee" describe la señal de video textualmente así:
;*************************************************************************************************************************************
;*** Field 0 contains 262.5 lines, as follows. 
;***
;***   3 lines: 6 pre-eq pulses 
;***   3 lines: 6 vertical sync pulses 
;***   3 lines: 6 post-eq pulses 
;*** 253 lines: normal scan lines (many of these are invisible and some are reserved
;***            for closed-caption data, cable tv scrambler data, etc...
;***            but so far as sync is concerned, these lines are all "normal" scan lines) 
;*** 0.5 lines: the last line of the field quits right in the middle! 
;***
;*** Field 1 contains 262.5 lines, as follows. 
;***
;*** 3 lines: 6 pre-eq pulses 
;*** 3 lines: 6 vertical sync pulses 
;*** 3.5 lines: 7 post-eq pulses 
;*** 253 lines: normal scan lines 
;***
;*** Con esta información el sincronismo vertical del Campo 1 correspondiente a las líneas Pares puede verse así:
;***
;*** 100%
;***      
;***                
;***           |\  /|
;***           | \| |
;***  30%    _/     |_   ___   ___   ___   ___   ___   ___     _     _     _     _     _     _   ___   ___   ___   ___   ___   ___
;***      | |         | |   | |   | |   | |   | |   | |   |   | |   | |   | |   | |   | |   | | |   | |   | |   | |   | |   | |   |
;***      | |         | |   | |   | |   | |   | |   | |   |   | |   | |   | |   | |   | |   | | |   | |   | |   | |   | |   | |   |
;***   0% |_|         |_|   |_|   |_|   |_|   |_|   |_|   |___| |___| |___| |___| |___| |___| |_|   |_|   |_|   |_|   |_|   |_|   |
;***        
;***                  <1>   <2>   <3>   <4>   <5>   <6>   <1->  <2->  <3->  <4->  <5->  <6->  <1>   <2>   <3>   <4>   <5>   <6>
;***      |<Línea 253>|<-Línea 1->|<-Línea 2->|<-Línea 3->|<-Línea 4->|<-Línea 5->|<-Línea 6->|<-Línea 7->|<-Línea 8->|<-Línea 9->|
;***                  |<------- Pre  Ecualización ------->|<------ Sincronismo Vertical------>|<------- Post Ecualización ------->|
;***                  |       Tiempo en Bajo 2.5 us       |       Tiempo en Bajo 27 us        |       Tiempo en Bajo 2.5 us
;***                  |       Tiempo en Alto 29 us        |       Tiempo en Alto 5 us         |       Tiempo en Alto 29 us
;***
;*** Mientras que el sincronismo del Campo 0 correspondiente a las líneas Pares puede verse así:
;***
;*** 100%
;***      
;***                
;***           |\ 
;***           | \
;***  30%    _/  |  ___   ___   ___   ___   ___   ___     _     _     _     _     _     _   ___   ___   ___   ___   ___   ________
;***      | |    | |   | |   | |   | |   | |   | |   |   | |   | |   | |   | |   | |   | | |   | |   | |   | |   | |   | |        |
;***      | |    | |   | |   | |   | |   | |   | |   |   | |   | |   | |   | |   | |   | | |   | |   | |   | |   | |   | |        |
;***   0% |_|    |_|   |_|   |_|   |_|   |_|   |_|   |___| |___| |___| |___| |___| |___| |_|   |_|   |_|   |_|   |_|   |_|        |
;***        
;***             <1>   <2>   <3>   <4>   <5>   <6>   <1->  <2->  <3->  <4->  <5->  <6->  <1>   <2>   <3>   <4>   <5>   <6>
;***      |<-M1->|<-Línea 1->|<-Línea 2->|<-Línea 3->|<-Línea 4->|<-Línea 5->|<-Línea 6->|<-Línea 7->|<-Línea 8->|<-Línea 9->|<M2>|
;***             |<------- Pre  Ecualización ------->|<------ Sincronismo Vertical------>|<------- Post Ecualización ------->|
;***             |       Tiempo en Bajo 2.5 us       |       Tiempo en Bajo 27 us        |       Tiempo en Bajo 2.5 us
;***             |       Tiempo en Alto 29 us        |       Tiempo en Alto 5 us         |       Tiempo en Alto 29 us
;***
;***  Siendo M1: La línea 253 (Media Línea) y M2: La línea 10 de las Pares (Media Línea)
;*************************************************************************************************************************************

;*** Pre Ecualización
		movlw	0x06
        movwf	LINEA			;Cargo la Variable línea con 6
		bcf		PORTB,LUMI
Pre_EQ
		bcf		PORTB,SINC
		call	Wait_C			;(2.4 us)
		bsf		PORTB,SINC
		call	Wait_D			;(29 us)
		decfsz	LINEA,f
		goto	Pre_EQ


		movlw	0x06
        movwf	LINEA			;Cargo la Variable línea con 6
Vert_Sinc
		bcf		PORTB,SINC
		call	Wait_E2			;(27 us)
		bsf		PORTB,SINC
		call	Wait_B			;(4.6 us) Casi los 5 us que necesitamos
		nop						; Agregamos un par de nop para completar el tiempo
		nop
		decfsz	LINEA,f
		goto	Vert_Sinc

;*** Post Ecualización
		movlw	0x06
        movwf	LINEA			;Cargo la Variable línea con 6
Post_EQ
		bcf		PORTB,SINC
		call	Wait_C			;(2.4 us)
		bsf		PORTB,SINC
		call	Wait_D			;(29 us)
		decfsz	LINEA,f
		goto	Post_EQ
		return


;Esta Rutina efectua una demora de 1.4 us (7 Ciclos del PIC a 20 Mhz)
Wait_A
		goto $+1
		nop
		return

;Esta Rutina efectua una demora de 4.6 us (23 Ciclos del PIC a 20 Mhz)
Wait_B
				;19 cycles
		movlw	0x06
		movwf	d1
Delay_B
		decfsz	d1, f
		goto	Delay_B
				;4 cycles (including call)
		return

;Esta Rutina efectua una demora de 2.4 us (12 Ciclos del PIC a 20 Mhz)
Wait_C
		goto $+1
		goto $+1
		goto $+1
		goto $+1
		return

;Esta Rutina efectua una demora de 29 us (145 Ciclos del PIC a 20 Mhz)
Wait_D
				;145 cycles
		movlw	0x30
		movwf	d1
Delay_D
		decfsz	d1, f
		goto	Delay_D
		return
	
;Esta Rutina efectua una demora de 52.6 us (263 Ciclos del PIC a 20 Mhz)
Wait_E
			;262 cycles
		movlw	0x57
		movwf	d1
Delay_E
		decfsz	d1, f
		goto	Delay_E

			;1 cycle
		nop
		return


;Esta Rutina efectua una demora de 27 us (135 Ciclos del PIC a 20 Mhz)
Wait_E2

				;133 cycles
		movlw	0x2C
		movwf	d1
Delay_E2
		decfsz	d1, f
		goto	Delay_E2

				;2 cycles
		goto	$+1
		return


		
		end						;Fin del Programa

