Dissecando a ULA do TK90X - Parte 4



O contador vertical e o VSync





Apesar da largura da tela do TK ser sempre fixa, a altura pode variar de tamanho, de acordo com o pino de seleção de 50 ou 60Hz, chamado aqui de modo 0 (50Hz) e modo 1 (60Hz). Em modo 0 temos um total de 312 linhas, enquanto em modo 1 apenas 262 linhas. Note que o tamanho do "miolo", a parte interna da tela não muda, tendo sempre 192 pixels de altura, apenas a borda sofre com a alteração.


HBlank como falamos, marca o fim da linha horizontal, então pode ser usado para incrementar U15, um contador de 12 bits 74hc4040. Já o 74hc157 em U16 funciona como um seletor da frequência lendo um jumper e resistor externos que definirão o modo de operação.

A lógica aqui é um pouco complicada porque novamente é preciso selecionar faixas de valores para o inicio e fim dos sinais. Vamos considerar primeiramente o sinal VSync, quando em modo 0: o terceiro e quarto bits do contador vertical são combinados na porta D do AND 74hc08 em U14 e com a seleção de U16, a porta C de U14 combina o resultado com o bit 5 do contador, e a porta D do NAND U11 combina ainda os bits 6 e 7 para formar o VSyncEn. Este sinal fica ativo sempre por 8 ciclos de clock, a partir do inicio do VSync. Num rápido cálculo 11111000b = 248, marcando o início do VSync. Note que o OR U17 combina o VSyncEn com o bit 2 do contador, logo, 11111100b = 252. Logo, a saída C de U17 é o nosso sinal VSync, na faixa entre 248 e 252, enquanto no VSyncEn fica entre 248 e 255.

Em modo 1, os bits 3 e 4 do contador são combinados na porta A do OR em U17 e invertido pelo XOR em U18 (note que uma das portas está sempre em nível alto, logo a saída vai ser sempre o inverso da entrada. Com a seleção de U16, a porta C de U14 combina o resultado com o bit 5 e a porta D do NAND U11 combina com os bits 6 e 7, portanto, 11100000b = 224. Seguindo o mesmo critério do modo 0, o bit 2 marca o final, em U17, logo, 11100100b = 228. Resumo, em modo 1, VSync entre 224 e 228 pulsos de clock e o VSyncEn entre 224 e 231.

Agora, vamos ao reset do contador, em modo 0 temos os ANDs U4, U31 e U26 combinando os bits 0 a 2, 4 e 5 do contador vertical. Com a seleção de U16 e é combinando na porta B de U14 com o bit 8, fazendo o número final para o reset, 100110111b = 311.

Em modo 1, apenas os bits 0 e 2 são combinados e depois de U18, combinados com o bit 8, então 100000101 = 261.

No VDHL está implementado ligeiramente diferente, usando a variável do próprio contador horizontal no lugar do HBlank, mas na prática o efeito é igual.

     
    -- contador Vertical
    process( clk7 )
    begin
        if falling_edge( clk7 ) then

            VCrst <= '0';                                       -- variável de status do reset do contador o contador. 
                                                                -- Quando em 1, o contador está zerado.

            if ( hc = 455 ) then                                -- testa se o contador horizontal chegou ao fim
                if ( ( vc = 261 and VERT50_60 = '1' ) or        -- se for a hora de incrementar o contador vertical, 
                     ( vc = 311 and VERT50_60 = '0' ) ) then
                      
                    vc <= ( OTHERS => '0' );                    -- zera o contador
                    VCrst <= '1';                               -- informa que o contador esta zerado
                    
                else
                
                    vc <= vc + 1;                               -- incrementamos o contador vertical
                    
                end if;
            end if;

        end if;
    end process;
	
    -- VSync - Pulso que indica um novo quadro de imagem
    -- O pino de selecao de frequencia da ULA e levado em conta para acertar a temporizacao
    process( clk7 )
    begin
        if falling_edge( clk7 ) then
            
            if ( ( vc = 224 and VERT50_60 = '1' ) or
                 ( vc = 248 and VERT50_60 = '0' )) then
                 
                VSync_n <= '0';
                
            elsif ( ( vc = 228 and VERT50_60 = '1' ) or
                    ( vc = 252 and VERT50_60 = '0' )) then
                     
                VSync_n <= '1';
                
            end if;
            
        end if;
    end process;
	
	-- VBlank - Nas TVs antigas, periodo que o feixe de eletrons era reposicionado no comeco da tela para um novo quadro da imagem
	-- O pino de selecao de frequencia da ULA e levado em conta para acertar a temporizacao
    process( clk7 )
    begin
        if falling_edge( clk7 ) then

            if ( ( vc = 224 and VERT50_60 = '1' ) or
                 ( vc = 248 and VERT50_60 = '0' )) then
                 
                VBlank_n <= '0';
                
            elsif ( ( vc = 232 and VERT50_60 = '1' ) or
                    ( vc = 256 and VERT50_60 = '0' )) then
                     
                VBlank_n <= '1';
                
            end if;

        end if;
    end process;
	

Beeeeeeemmmm mais simples, não?



Voltar para o índice




Dúvidas, sugestões? Use o espaço abaixo.


Voltar - Home


Comente



COMENTÁRIOS DESABILITADOS NO MOMENTO! RETORNAM EM BREVE
É expressamente proibido a reprodução total ou parcial deste texto sem a minha devida autorização por escrito.