quinta-feira, 21 de maio de 2015

Ressuscitando um TK-85 (5)

Nos últimos dias não tenho conseguido mexer muito com a plaquinha "ressucitada", mas hoje consegui fazer umas poucas coisas:

Instalei duas barras de pinos. Uma com 5 pinos e outra com 8 pinos.

Barras de pinos para as conexões do teclado.
Com isso já deu para testar as combinações da matriz de teclado. Felizmente todas as teclas estão funcionando.

A imagem ficou muito nítida com o TK85AV Tetraloaded

Instalei também alguns componentes faltantes na placa para implementar o MOD do PSG. Ficou faltando o Jaque de saída (que não tenho no momento) e um capacitor de desacoplamento, este último só fui me dar conta agora. A lista completa dos componentes necessários é:
  • 1 AY3-8912 (IC29, PSG) 
  • 1 74LS00 (IC27)
  • 1 LM386 (IC 38)
  • 4 diodos 1N4148 (D6, D7, D8, D9)
  • 4 capacitores de 100nf (C15, C24, C31, C32)
  • 1 capacitor de 220uf (C16)
  • 1 resistor de 47K (R66)
  • 1 resistor de 100K (R65)
  • 1 soquete de 8 pinos (para IC38)
  • 1 soquete de 14 pinos (para IC27)
  • 1 soquete de 28 pinos (para IC29)
  • 1 Jaque de áudio P2
Como ainda falta testar algumas coisas não instalei os CIs, somente os soquetes.
Ficou faltando o capacitor C32 que serve para desacoplar a alimentação de IC27 (LS00)

Soquete e capacitores para o amplificador de áudio.
Por hoje é só...



domingo, 17 de maio de 2015

Caixa reciclada para o TK85

Aproveitando a onda da reciclagem salvei de ir pro lixo uma caixa de placa de vídeo que serviu perfeitamente para abrigar um TK85. Só precisei cortar um pouco a espuma para encaixar o TK, e ainda sobrou um compartimento onde cabe perfeitamente uma fonte chaveada e um cabo de vídeo.

O TK-85 há décadas não tinha uma casa própria.

Ressuscitando um TK-85 (4)

Continuando o post anterior...


Hoje eu peguei o TK-85 que está funcionando corretamente e capturei várias formas de onda, a fim de comparar com a placa que estou tentando restabelecer seu funcionamento.

Eu usei como trigger o sinal de base de tempo vertical presente no anodo de D22 e escorreguei a base de tempo para aproximadamente 2,5ms além. A razão disso é que intervalo vertical não há vídeo sendo gerado. Eu ajustei a posição vertical de forma que a borda de descida do ciclo M1 batesse com o centro da tela do osciloscópio, ou seja sobre o eixo vertical.

A razão de usar o ciclo M1 como referência é que o TK85 (ZX81) literalmente executa a memória para desenhar a tela, e o ciclo M1 vai a nível baixo no início do ciclo de busca (fetch) das instruções.
Quando o ZX81 executa instruções na região correspondente ao D-FILE, existe um circuito que gera 'NOPS' para o Z80 para cada caractere na tela. Sendo assim, este sinal é uma boa referência de tempo para se checar os outros sinais.

Com uma referência fixa foi possível combinar várias formas de onda e combina-las numa figura única de forma a facilitar o entendimento (ou futuras pesquisas de pane).

Formas de onda do TK85

Olhando a figura acima vemos de cara uma coisa estranha. O sinal presente no pino 9 de IC5 (LS373) varia entre 0 e 1,2Volts. Isso estava assim também na placa defeituosa e foi exatamente esse comportamento que ontem me fez suspeitar de IC17 (LS04) e de IC5 (LS373). Acabei trocando IC5 porque apesar de tudo a saída da porta E de  IC17 invertia o sinal. Depois de trocado IC5 o comportamento do circuito não havia se alterado.

Geração do sinal SHIFT/LOAD
Como última e desesperador medida acabei trocando também IC17, pois sua porta C estava ligada diretamente em DD6 que quando tocada com o dedo ou a ponta de prova mudava o sinal produzido na tela (vide post anterior).
A conclusão é que embora bizarro esse circuito funciona assim mesmo. O que acontece é que na fase alta do sinal de REFRESH, as saídas de IC5 estão em tristate, e isso equivale a deixar o pino 11 de IC17 em aberto. Com isso, os 1,25 Volts são enxergados como nível alto e a saída representa o inverso do sinal de entrada com um pequeno detalhe: Na falta de algo para puxar a entrada do inversor (IC17-11) para cima, o sinal sobe relativamente devagar, formando uma rampa que causa um delay de aproximadamente 200ns na borda de descida do sinal no pino 10 de IC17. Não sei dizer se este atraso é proposital, teria que analisar mais ou fazer mais experimentos.

Continuando, o sinal de NOP 'atrasado' junto com o sinal MREQ (também atrasado por uma rede RC) e mais o sinal de 3.25MHz são combinados numa porta NAND de forma que um pulso baixo só aparecerá no momento em que os três sinais estiverem em nível lógico alto. Isso acontece entre na fase alta de clock, no final do ciclo de 'refresh', logo antes do início do ciclo de 'fetch' seguinte (o sinal nop segue mais ou menos o inverso do sinal de refresh)

Formas de onda em IC18C (LS10, TK85 funcionando)
Na placa defeitosa, os sinais estavam um pouco diferentes: O sinal de clock era um pouco mais bem comportado, e o sinal de NOP 'atrasado' por IC5 (LS373) apresentava uns glitches que desapareciam quando tocava-se o dedo ou a ponta de prova na linha DD6. O sinal MREQ' era igual.

Já a saída era muito estranha, em vez dos pulsos curtos apareciam dois pulsos de SHIFT/LOAD e era isso que fazia o registrador de deslocamento apresentar aquele monte de lixo na tela.

Formas de onda em IC18C (LS10, TK85 defeituoso)

Abrindo-se a varredura da tela para conferir os estados lógicos apareceu um suspeito: IC18. Aparentemente a saída estava simplesmente invertendo o sinal MREQ'.

Forma de onda 'esperada' em IC18 (vermelho) versus sinal atual (azul)
Comparando o sinal observado com o sinal desejado tinha-se a impressão de que a porta NAND não estava funcionando corretamente. Daí, dá-lhe trocar o LS10, Aproveitei para colocar um soquete.

IC18 (LS10) removido

Soquete instalado para IC18 (LS10)
Estava fácil demais.... não precisa nem dizer que não funcionou...

Então, pausa pra tomar um café e brincar com o cachorro enquanto pensa no problema...
Brincando com o Otto para refrescar as idéias.

Alguns biscoitos depois comecei a investigar outra a diferença que observei nos sinais: O clock. Como eu ainda tinha na memória do osciloscópio o clock do TK funcionando, fiz uma nova captura e sobrepus os dois sinais:

Clock 3.25MHz'. Branco: TK funcionando / Azul: TK com defeito


 Daí apareceu uma coisa que não tinha notado de início. O Clock do TK com defeito estava sobreposto a um sinal de aproximadamente 1,2Volts. Isso me fez lembrar da saída do LS367 que era reconhecida como nível alto daí refiz a análise dos sinais na entrada de IC18 considerando que o clock estivesse sendo enxergado pelo CI como em nível alto o tempo inteiro:
Considerando o Clock em nível alto, explicava-se o comportamento da saída.

Bingo!!! Considerando-se o Clock em nível alto o tempo inteiro, o comportamento estranho do sinal SHIFT/LOAD estava explicado!

O problema agora havia se transformado em estudar porque o clock estava diferente do que deveria. Analisando o circuito do TK novamente, vemos que o sinal de clock/2 (3.25MHz) saindo do pino 9 de IC4 (LS74) passa por uma rede diferenciadora (C3-R5) e vai para o pino 9 de IC18. Como o sinal estava passando, o capacitor poderia estar em curto ou o resistor poderia estar aberto.
Derivador de clock.
Deu um pouco de trabalho encontrar estes dois componentes (C3, R5) que estavam ao lado do jack de 'EAR'. Quando os encontrei verifiquei que a conexão de GND do resistor estava aberta.  Observando do lado de baixo da placa vi o problema:
Trilha danificada quando a placa foi canibalizada.
A conexão entre o terminal negativo do resistor R5 (e sabe-se lá o que mais, já que a trilha é grossa) e a ilha do jack de EAR que vai ao GND estava aberta! Esta trilha deve ter-se rompido quando a placa foi canibalizada e passou batido quando eu soldei o Jack para substituir o que estava faltando.

Consertei a placa usando fio rígido. Cortes, trincas e demais interrupções sempre devem ser reparadas soldando fio entre ilhas, pois quando o fio é soldado nas trilhas elas aquecem e tendem a descolar e depois de algum tempo o reparo pode romper-se novamente.

Trilha reparada.

 Depois do conserto, verifiquei a forma de onda dos sinais de CLOCK e SHIFT/LOAD. Desta vez estava tudo certo!  Até os picos que apareciam no sinal de "NOP" e a sensibilidade quando se tocava a linha DD6 desapareceram.
Formas de onda como esperado agora!
Formas de onda boas, o próximo passo foi ligar o monitor. Agora sim... SUCESSO!!!



 

O próximo passo vai ser soldar os pinos para os conectores do teclado e testar se a leitura e escrita no cassete estão funcionando.





















sexta-feira, 15 de maio de 2015

Ressuscitando um TK85 (3)

Hoje não foi um dia muito frutífero, mas a pesquisa continua...

Em primeiro lugar tive que conectar a placa do TK a um monitor. Como a TV de 5" cabe melhor na bancada do que o monitor LCD eu montei num protoboard uma versão melhorada do A/V Treloaded que usa menos componentes e tem melhor desempenho. Por desempenho entenda-se que a saída tem impedância de 75Ohms e acoplamento DC.  Eu batizei o circuito de 'TK85 AV Tetraloaded'. Poderia também ser Treloaded Plus, mas como eu na realidade removi componentes também poderia ser Treloaded Minus. Enfim, segue anexo circuito.

TK85 A/V Tetraloaded
Diagrama do circuito.

Depois de ligado o circuito na TV a imagem que apareceu estava cheia de artefatos, o que confirmou as observações de anteontem no osciloscópio.

Artefatos na tela.

Nas minhas observações o que achei estranho é que o registrador de deslocamento IC9 (Ls165) está recebendo dois pulsos de load dentro de um mesmo ciclo M1. Não me lembro de ser assim no outro TK.

Azul: SH/LD de IC9. Barras verticais: Ciclo M1
Uma coisa que achei estranha é que quando a ponta de prova é colocada na linha DD6, a imagem fica praticamente sem artefatos, muito embora o K do cursor tabém não esteja OK nessa situação.

Ao se encostar na linha DD6 o padrão de artefatos muda.
Fiz alguns testes mas nada conclusivo. Cheguei a desconfiar de alguns sinais e troquei os circuitos integrados IC5 e IC15 porém a situação continuou a mesma.
IC5 e IC17 com soquetes.

Também troquei as memórias por outras que eu tinha aqui mas a situação continuou igual. Só mudou um pouco os padrões na tela.

Amanhã vou anotar algumas formas de onda do TK que está bom e usar como comparação.



quarta-feira, 13 de maio de 2015

Ressuscitando um TK85 (2)

Continuando com a pesquisa de defeitos do artigo de ontem...

O oscilador a cristal estava funcionando de forma aleatória e somente quando a ponta de prova estava em cima do cristal (eu monitorava ao mesmo tempo os sinais dos pinos 11 e 12).

Como o cristal é 'filho único' eu precisava verificar se ele estava bom. Então repliquei o oscilador do TK85 num proto-board e o circuito oscilou a 6,5MHz como esperado provando que o cristal estava em ordem.

Oscilador do TK85 replicado no proto-board e funcionandoa 6.5MHz

Oscilador do TK85
Restava testar as conexões da placa, coisa que fiz com o multímetro na escala de continuidade. Depois de constatar que estava tudo em ordem o jeito foi remover IC20 (LS86) e testar ele no oscilador do proto-board.

IC20 (LS86) removido. O cristal e o capacitor C1 estão fora da placa, montados no proto-board
Quando coloquei no proto-board o LS86 que estava na placa o oscilador não funcionou, comprovando que o CI estava com problemas. Reinstalei então o cristal e o capacitor C1 na placa e instalei um soquete para o LS86.

Soquete, cristal e capacitor reinstalados em seus devidos lugares.
 Após instalado o CI em seu soquete o oscilador passou a funcionar, e deu para partir para os testes seguintes.
Oscilador funcionando novamente.
A primeira coisa que fiz foi checar se os sinais de sincronismo e de vídeo para ver se o TK estava vivo. Havia um sinal instável no vídeo mas não havia sincronismo.

O primeiro lugar para checar é o gerador de base de tempo, composto por IC11, IC12 IC21 e IC23. Este gerador recebe o sinal de 3,25MHz e divide até chegar num tempo de aproximadamente uma linha (64us). Os pulsos podem ser vistos no pino 11 de IC23. Mas este circuito estava em ordem

Gerador de base de tempo horizontal.

Olhando um pouco à frente vi que os pulsos de sincronismo estavam ficando parados na porta D de IC24, uma vez que o sinal de /IOWR estava constantemente em nível zero (pino 13 de IC24) .
Gerador de base de tempo, sincronismo e sinais de escrita no cassete.
As linhas /IORQ e /WR estavam fixas em nível alto, e o flip flop formado pelas portas C e D de IC16 permanecia em sempre travado. em nível zero.

Agora que estou escrevendo este artigo começo a desconfiar que o diodo D22 está invertido no diagrama. Amanhã eu confirmo isso.


Pinos 13 de IC24 ficava fixo em nível zero, mantendo o pino 11 travado em nível alto.
Prosseguindo, como no padrão do ZX81 o vídeo é gerado parte por hardware parte por software nas interrupções não mascaráveis, desconfiei que o comportamento estranho talvez fosse devido a um problema com o Z80, ou a ROM ou a RAM, e deixei de lado por algum tempo os sinais de sincronismo.

Medindo as linhas de dados e de endereços no Z80 vi que algumas delas ficavam variando, outras não. Isso poderia ser um problema do Z80. Para verificar se era isso coloquei a ponta de prova numa linha das linhas que estava parada (no caso o A13) e observei o comportamento durante o RESET. A linha tinha sinal por um tempo depois sumia.  O mesmo padrão se repetia para outras linhas com sinal fixo, como IORQ e /WR. Esse comportamento indica que o Z80 está OK.

O próximo passo então foi checar se todas as linhas das SRAMs estavam recebendo alimentação e sinais corretamente, uma vez que os soquetes das SRAMs estavam meio oxidados. Comecei checando as alimentações de +5, -5 e -9 e estavam todas OK.

Daí fui checando as vias de dados se estavam coerentes com as linhas de dados do Z80. Para fazer esse check uma das pontas de prova do osciloscópio vai no pino do Z80 e a outra vai na memória. Os traços devem ser iguais. Se houver diferença de um pro outro alguma coisa pode estar errada.

Eu tive um pouco de sorte, pois ao chegar na linha DD4 vi que ela estava em nível alto o tempo inteiro nos pinos 2,14 de IC34 (4116) porém no Z80 esta linha ficava um 'sujinho' em nível baixo.

Checando no diagrama os outros pontos onde essa linha é conectada vi que o sinal estava OK nos pinos das EPROMs porém no pino 24 da furação destinada ao PSG o sinal não chegava.

Peguei então o multímetro para conferir mas nem precisava. Uma inspeção visual já deu para achar o problema ali dentro do soquete da ROM auxiliar. Uma trilha estava partida muito provavelmente pela ferramenta usada para remover a EPROM quendo a placa foi canibalizada.
Trilha do sinal DD4 interrompida por dano causado por ferramenta.

Reparo efetuado com fio esmaltado.

Remendada a placa, os sinais de /IOWR começaram a ser gerados e já era possível ver atividade em todas as linhas do Z80, porém ainda não tinha sincronismo presente no pino 2 de IC20 (LS86).

Seguindo a trilha do sinal de sincronismo cheguei ao pino 12 de IC22 (LS32) que estava fixo em 2,0Volts. Este pino é ligado ao pino 8 de IC24 (LS00) que tinha sinal.

Checando com o multímetro vi que não havia continuidade entre estes pinos. Porém dependendo de como eu pressionasse o pino 8 de IC24 o multímetro acusava continuidade.

O sinal não passava do pino 8 de IC24 para o pino 12 de IC22.

Olhando a placa por baixo deu para ver a razão. O pino estava sem solda!

O pino 8 do IC24 (LS32) estava sem solda.

Refeita a solda, o sinal de sincronismo passou a aparecer normal no pino 2 (e 3) de IC20 (LS86). Uma maneira bacana de ver ambos o sinais é sincronizar pelo sinal vertical presente no pino 4 de IC24 e colocar a outra ponta de prova no sinal de sincronismo (pino 8 de IC24 ou pino 11 de IC22).

Apesar do sincronismo estar normal, o vídeo está uma bagunça. Ainda não liguei a um monitor mas com a ponta de prova do osciloscópio já deu para ver a encrenca. Amanhã vou ligar o circuito do Kolour neste TK para dar uma olhada no aspecto da tela para ver se tenho alguma pista.










terça-feira, 12 de maio de 2015

Ressuscitando um TK85

Fiquei animado com a postagem do amigo Clóvis que deu um trato num TK85 dele e resolvi continuar o meu trabalho de ressucitação de um TK que achei na casa da minha mãe mas nem me lembro mais de onde ele veio nem como foi parar lá.

Esta placa estava em estado lastimável, faltando vários componentes, como o regulador de tensão, o dissipador de calor, o 555, os jaques, o modulador de RF o cristal, as memórias DRAM, os transistores, os conectores de teclado, a Eprom auxiliar, vários capacitores eletrolíticos. Além disso a placa tinha vários resistores quebrados.  


 Apesar disso tudo estar faltando, a placa estava em bom estado, e comecei a restaurá-la mais ou menos na época em que montei o Nestor, mas acabei deixando a restauração de lado por alguma razão (acho que foi esperando o cristal que comprei chegar) e acabei esquecendo dessa placa.

Só lembrei dela recentemente quando tive que pegar um TK-85 que estava guardado na mesma caixa que a placa para poder 'emprestar' o teclado ao TK90X.

Mas como disse, o post do Clóvis me animou e essa noite em vez de ir deitar resolvi mexer um pouco na plaquinha do TK.

No ponto onde parei a restauração eu já tinha colocado de volta os jaques (sobras do Nestor), o 555 e componentes associados, os transistores, os eletrolíticos e trocado uma porção de resistores quebrados.

Hoje instalei o 7805 e um dissipador de calor. Como não tinha um modelo nem de longe parecido coloquei um bonitinho que retirei de um conversor DC DC de placa mãe de PC, e isolei a placa com fita de Kapton para o dissipador não fechar nenhum curto.

Também achei mais um resistor quebrado (R74) e troquei o cristal. Ao energizar a placa infelizmente não tinha oscilação.

Durante o 'troubleshooting' acabei me deparando com um errinho no diagrama refeito do TK. Um dos lados do capacitor C1 estava ligado incorretamente (no diagrama) ao pino 8 de IC20 (LS86) em vez de estar ligado ao terra.

Engraçado é que coloquei um outro cristal em paralelo com o cristal de 6.5 e o circuito começou a oscilar.

Daí mexi um pouco no valor do capacitor de realimentação do oscilador, mas o circuito só oscilava, e de maneira bem instável, com a ponta de prova conectada a um pino do cristal.

Tirei o cristal e testei num oscilador que tenho aqui e para minha felicidade o cristal está normal, oscilando a 6,5 MHZ.

Daí refiz o circuito num protoboard e ele oscilou corretamente! Com isso desconfio que tenha algum problema nas conexões ou mesmo no LS86. Mas isso fica pro próximo post.

Seguem anexas algumas fotos.
Placa semi-restaurada. Foto do início de 2014

Cristal oscilador de 6,5MHz.

Foto de hoje, antes de eu começar a mexer novamente.

Dissipador de calor retirado de uma placa de PC. Fiz um furo na lateral para prender o regulador.

Regulador com pasta térmica já preso ao dissipador.


Regulador de tensão já soldado na placa. Detalhe do 555, capacitores e zeners novos.

Placa já com o regulador, o dissipador de calor, as memórias RAM e o cristal reinstalados.


Mais um resistor que estava quebrado foi substituído.



segunda-feira, 11 de maio de 2015

Temporização do código na geração de réplicas dos sinais de vídeo do TK90, MSX1 e MSX2


Este projeto começou há alguns meses atrás, precisamente em 31/12/2014, como um passatempo em meu último dia de férias.

Eu estava relendo o artigo do Victor sobre o Tic Tac Blue e em determinado momento ele comenta que o circuito dele gerava uns artefatos porque entre fechar um loop e abrir outro ele perdia alguns ciclos de clock.


O circuito é baseado num PIC16F688 rodando a 20MHz
 Fiquei encucado com aquilo e na falta do que fazer comecei a brincar com o MPLAB. Nas primeiras experiências descartei a possibilidade de gerar vídeo por interrupções, mesmo a 20MHz. Para gerar vídeo, ainda mais em VGA tem que ser realmente contando ciclo a ciclo.

Então imaginei gerar cada parte do vídeo (sincronismo, bordas e vídeo ativo) com alguns loops. Mais ou menos algo assim:

video:

...
        movlw N_LINHAS
        movwf CONTA
_loop1:
        call GERA_LINHA
        decfsz CONTA,F
        goto _loop1
        movlw N_LINHAS
        movwf CONTA
_loop2:
        call GERA_LINHA
        decfsz CONTA,F
        goto _loop2
...
...
        goto video 



De cara o problema já se apresentou: Entre o começo de um loop e o final do outro perdem-se 2 ciclos. Não sei se foi exatamente assim o problema que o Victor enfrentou, mas como havia dito eu queria alguma coisa para distrair a cabeça isso já serviu:

A primeira coisa quer fiz foi analisar o exato número de ciclos gastos.


video:

...
        movlw N_LINHAS     ; 1
        movwf CONTA        ; 1
_loop1:
        call GERA_LINHA    ; N  2 do call, x da linha, 2 do return
        decfsz CONTA,F     ; 1 o goto vira um nop quando pulado
        goto _loop1        ; 2 na iteração, 1 quando é pulado 
        movlw N_LINHAS     ; 1
        movwf CONTA        ; 1
_loop2:
        call GERA_LINHA    ; N
        decfsz CONTA,F     ; 1
        goto _loop2        ; 2
...
...
        goto video

daí considerando as iterações:

video:

loop 1:
CONTA=4->N+1+2 ciclos
CONTA=3  N+1+2
CONTA=2  N+1+2
CONTA=1  N+1+2
CONTA=0  N+1+1+1
movlw    1 ciclo
movwf    1

loop 2:
CONTA=N_LINHAS    N+1+2
CONTA=N_LINHAS-1  N+1+2
...
...
CONTA=1  N+1+2
CONTA=0  N+1+1+1

...
goto video

Assim entre cada iteração temos N+3 ciclos e entre a última iteração do loop1 para a primeira iteração do loop2 temos N+5 ciclos.

Eu gastei algum tempo pensando em como poderia fazer para fazer para gastar o mesmo tempo entre a iteração e a passagem de um loop para o outro. Depois de algumas tentativas frustradas de colocar NOPs antes e depois dos loops, cheguei a uma solução que é muito simples:

Colocar o movlw dentro do loop!


Dessa forma:


video:

...
        movlw N_LINHAS     ; 1
        movwf CONTA        ; 1
_loop1:
        call GERA_LINHA    ; N  2 do call, x da linha, 2 do return
        movlw N_LINHAS     ; 1
        decfsz CONTA,F     ; 1 o goto vira um nop quando pulado
        goto _loop1        ; 2 na iteração, 1 quando é pulado 

        movwf CONTA        ; 1
_loop2:
        call GERA_LINHA    ; N
        movlw N_LINHAS     ; 1

        decfsz CONTA,F     ; 1
        goto _loop2        ; 2 / 1
...
...
        goto video         ;2
 
Assim o tempo gasto nas iterações fica:

video:

loop 1:
...
CONTA=4  N+1+1+2
CONTA=3  N
+1+1+2
CONTA=2  N
+1+1+2
CONTA=1  N
+1+1+2
CONTA=0  N
+1+1+1
movwf    1

loop 2:
CONTA=N_LINHAS    N
+1+1+2
CONTA=N_LINHAS-1  N
+1+1+2
...
...
CONTA=1 
N+1+1+2
CONTA=0 
N+1+1+1
...
goto video 2


Daí temos um tempo entre cada iteração de  N+1+1+2 ciclos e entre a última iteração do loop1 para a primeira iteração do loop2 temos N+1+1+1+1 ciclos, ambos resultando em N+4 ciclos!

Mas a coisa não pára por aí.... Ainda faltava resolver um último detalhe... o GOTO VIDEO no final consome 2 ciclos.O que fazer nesse caso?

A resposta para esse problema exigiu pensar um pouco mais. Quando estava quase desistindo veio a inspiração.

A última linha da tela teria que ser colocada fora do loop.

do_video:
        movlw N_LINHAS     ; 1 - valor inicial do primeiro loop
frame:
        movwf CONTA        ; 1
_loop1:
        call GERA_LINHA    ; N  2 do call, x da linha, 2 do return
        movlw N_LINHAS     ; 1
        decfsz CONTA,F     ; 1 o goto vira um nop quando pulado
        goto _loop1        ; 2 na iteração, 1 quando é pulado

        movwf CONTA        ; 1
_loop2:
        call GERA_LINHA    ; N
        movlw N_LINHAS     ; 1
        decfsz CONTA,F     ; 1
        goto _loop2        ; 2
...
...

        movwf CONTA        ; 1
_last_loop:
        call GERA_LINHA    ; N
        nop                ; 1 dummy, pois segue trecho sem iteração
        decfsz CONTA,F     ; 1
        goto _last_loop    ; 2

       
        nop                ; 1 

_last_line:
        call GERA_LINHA    ; N   última linha
        movlw  N_LINHAS    ; 1  quant. de linhas para o primeiro loop       
        goto frame         ; 2


Desta forma, entre a última linha gerada e o retorno ao primeiro loop temos N+1+2+1 ou seja novamente N+4 ciclos.



Assim para gerar vídeo basta definir quantas linhas de de cada tipo serão geradas e criar as rotinas para preencer cada linha, lembrando de descontar 8 ciclos por linha equivalentes aos 4 gastos nas iterações mais 2 do CALL e mais 2 do RETURN.

A título de exemplo o frame para gerar o vídeo do TK90X, conforme as medições que eu descrevi num artigo anterior fica:

; TK90X ULA Frame                     
; N_LINHAS TIPO                       
;   1      Heq1                       
;   3      Vser                       
;   1      Heq2                       
;  20      Brancas                    
;  15(33)  Borda topo NTSC(PAL)      
;  92      Video ativo primeira metade (barras de cor)
;   8      texto
;  92      Video ativo segunda metade (barras de cor)
;  22(54)  Borda de baixo NTSC(PAL)   
;   7      Brancas                      
;   1      Branca, ultima linha        
;-----                                
; 262 (312) linhas