quinta-feira, julho 20, 2017

Piscando um LED com o CDP1802

A montagem do Cosmac ELF em protoboard segue lenta. São várias conexões, quase uma dezena de integrados e mais cabo e conector para o painel. Daí surgiu a ideia de fazer uma montagem bem minimalista mas com resultado mais imediato.


Hardware


Neste montagem não tem painel: o software está gravado em uma ROM e a saída se resume a um único LED. São apenas dois integrados: o 1802 e uma EEProm 28C16 (a mesma que usei com o Z80).

O clock é gerado ligando um cristal diretamente ao 1802. As entradas não usadas do 1802 são ligadas a pullups, uma precaução importante quando se trata de CMOS. As vias de endereço e dados são ligadas diretamente à memória, o sinal /MRD é usado para acionar a saída da EEProm.

Nesta configuração usamos somente os 8 bits menos significativos de endereço, que permitem selecionar 256 bytes. A 28C16 é de 2Kbytes, possuindo 11 bits de endereço; os três mais significativos ficam ligados ao terra. Como é a única memória, podemos deixá-la sempre selecionada ligando /CE direto ao terra. A memória será usada somente para leitura, portanto o sinal /WE é fixo em nível alto.

Completando o circuito, um transistor é usado para acionar o LED ligado ao pino Q do 1802.

Software

O software foi copiado da documentação do Membership Card (Program 2 -- Blink Q Slow):

ender código   instrução   comentário
0000  F8 49    LDI 73      coloca 73 no acumulador
0002  B2       PHI R2      copia o acumulador na parte alta de R2
0003  22       DEC R2      decrementa R2
0004  92       GHI R2      copia a parte alta de R2 para o acumulador
0005  3A 03    BNZ #0003   se acumulador diferente de zero volta ao endereço 0003
0007  CD       LSQ         avança p/ 000A se Q for 1
0008  7B       SEQ         coloca 1 em Q (acende o LED)
0009  38       SKP         avança para 000B
000A  7A       REQ         coloca 0 em Q (apaga o LED)
000B  30 00    BR #0000    volta ao endereço 0000

Este código se vale de algumas características do 1802:
  • Após o reset os registradores estão com 0 e R0 é o contador do programa
  • Os registradores são de 16 bits. DEC decrementa o registrador inteiro, porém PHI e GHI manipulam apenas os 8 bits mais significativos.
  • A instrução BNZ (e outras semelhantes) testam diretamente o valor no acumulador, não é necessário fazer uma operação aritmética ou lógica para acionar flags.
  • As instruções de branching (BNZ e BR no programa) afetam somente a parte baixa do contador de programa. Desta forma o código é mais curto (2 bytes) porém o destino deve ter a mesma parte alta da instrução seguinte (pois o contador de programa é avançado antes do desvio).
  • Existem duas variações de instruções skip,  a curta (como SKP) e a longa (como LSQ). Estas instruções são um desvio simplificado, pulando (respectivamente) um ou dois bytes.
  • O uso do SKP dentro dos dois bytes pulados por LSQ é ligeiramente diabólico.
Este código foi gravado na 28C16 usando um programador externo.

Resultado

Gravado o código e feita a montagem, tive a grata surpresa de ver funcionar de primeira. O vídeo abaixo mostra o LED piscando alegremente.


Nenhum comentário: