CHR$128
para o TK85
Por Kelly Abrantes Murta
- Zeddy-Br
11 de Agosto de 2010
Na
década de 80, no auge do boom dos microcomputadores de 8 bits, fez
muito sucesso aqui no Brasil uma pequena adaptação feita nos TKs que
possibilitava a redefinição dos 64 caracteres disponíveis no micro. Uma
dessas adaptações, de autoria de Bernhard Wolfgang Schön, foi
publicada na revista Micro Bits em uma série de três artigos e acho que
fez bastante sucesso entre aqueles usuários que tinham familiaridade
com o ferro-de-solda. A alguns anos
atrás, por ocasião do encontro do Canal 3 que aconteceu aqui em Belo
Horizonte, eu implementei essa modificação em meu TK85 mas acabei
retirando-a logo após o encontro pois, apesar de funcionar
perfeitamente,
a
montagem ficou muito tosca, com uma montoeira de fios dentro do TK.
Pois bem, após eu ter implementado o vídeo composto by Victor Trucco e com a
versatilidade e eficiência proporcionada pelo projeto O.T.L.A.
no carregamento de programas via porta cassete, deu uma
vontade danada de experimentar novamente a sensação de ver no TK85 os
joguinhos em alta-resolução por redefinição de caracteres e foi daí que
surgiu o material para este artigo e com uma funcionalidade extra,
inexistente no projeto original.
A geração de caracteres no
ZX81
Antes de passar à montagem, vamos rever então como são gerados os
caracteres que o ZX81 envia para tela durante a geração de vídeo.
Cada caracter é formado a partir de uma matriz de 8x8 pixels
armazenados na ROM a partir do endereço $1E00 (7680 em decimal). Assim,
cada caracter é definido por 8 bytes sucessivos, resultando em 512
bytes o total de memória necessário para definir todos os 64 caracteres
disponíveis. Tome como exemplo o caracter A:
O código deste caracter é 38 e sua matriz de definição está armazenada
a partir do endereço 7984 (7680+38*8). Examinando os oito bytes
subsequentes encontramos a seguinte sequencia:
hexadecimal binário
00
00000000
3C
00111100
42
01000010
42
01000010
7E
01111110
42
01000010
42
01000010
00
00000000
Pois bem, se quisermos redefinir este caracter precisaremos alterar os
oito
valores acima, mas como estão localizados em ROM isso não é possível.
Teríamos que transferir a tabela de caracteres para a RAM,
redefinir os caracteres e informar ao sistema operacional onde
localizar a nova tabela de caracteres, o que é feito através do
registrador
I do processador Z80. Durante o
boot, esse registrador é carregado com
o valor $1E indicando que a tabela está armazenada a partir do endereço
$1E00, no final da ROM de 8Kb. Se transferirmos a tabela de caracteres
para o endereço $6000 (24576) devemos alterar o registrador I para
apontar para a nova tabela, o que pode ser feito com o pequeno
código abaixo:
ld a,$60
ld i,a
ret
Mas
o que acontece quando executamos o código acima após transferir a
tabela de caracteres para o endereço $6000? Você vai
observar um efeito muito curioso: a tela ficará preenchida com padrões
de pixels totalmente estranhos, algo parecido com a figura ao lado.
A primeira vez em que eu fiz isso em meu TK82C, ficava imaginando o que
deu errado, afinal eu havia transferido a tabela para a RAM e alterado
o registrador I para a nova posição, então por que a bagaça não
funcionava?!
Para saber a razão, é necessário antes compreender como o TK envia
para a TV as informações do arquivo de tela (DFILE), o que tentarei
explicar a seguir.
O arquivo de tela do TK é armazenado em RAM e sua posição é
indicada
pela variável de sistema DFILE. Quando o circuito de geração de vídeo
interrompe o programa do usuário para rodar a rotina de interrupção
responsável pela geração da imagem na TV, em um dado momento é
executado a
instrução JP (HL), onde o par de registradores HL contém o valor
do DFILE+$8000. Nesse momento, o TK identifica a linha A15 do Z80 em
nível lógico 1 e a linha /M1 (opcode fetch) em nível lógico 0.
Imediatamente o TK
coloca as linhas D0 a D7 do barramento de dados do Z80 em nível lógico
0, forçando-o a
executar a instrução NOP para cada código de caracter no DFILE.
Paralelamente, os bits 0 a 5 do código do caracter que
está sendo processado naquele momento são capturados e armazenados em
um registrador de
6 bits e o bit 7 armazenado no INVERT register, tudo isso
ocorrendo durante os ciclos T1 e T2 da execução do NOP pelo Z80.
Nos ciclos seguintes (T3 e
T4), o Z80 ativa o sinal /RFSH e o TK passa a montar o endereço da
posição de memória onde será capturado o byte que formará cada linha do
caracter. Para isso existe um circuito contador de 0 a 7 (o LINECNTR),
que é incrementado a cada linha do caracter e cuja saída fornece os
bits A0 a A2 do endereço. Os bits A3 a A8 são fornecidos pelo seis bits
do código do caracter e os bits A9 a A15 correspondem ao conteúdo do
registrador I do Z80. Ou seja:
A15------A9
A8-----A3 A2-A0
<---reg I---> <--CHR-->
<-LINECNTR->
Com o endereço montado, os oito pixels correspondentes à linha do
caracter que está sendo processada é lido da ROM e enviado para o vídeo
shift register que por sua vez envia-o para a TV à taxa de 6.5MHz. Se
o bit armazenado no INVERT register for 1, o pixel é invertido
antes de ir para a TV.
Pois bem, se o endereço é formado pelo reg I+cód caracter+LINECNTR, por
que a
rotina acima não funcionou quando o registrador I foi alterado?
A resposta é simples! Todos os eventos relatados acima ocorrem durante
a execução da instrução NOP, quando o barramento de endereço do Z80
endereça o código do caracter no DFILE em RAM. Isso implica que o
barramento de endereços da tabela de caracteres deve ser isolado do
barramento do Z80. Isso é feito por resistores colocados entre as
linhas A0 a A8 do Z80 e as saídas de um circuito multiplexador de 16
para 8 linhas, que multiplexa as linhas A0 a A8 com os bits 0 a 8
(CHR+LINECNTR) do endereço da máscara de pixel do caracter durante o
ciclo de refresh gerado pela CPU. As saídas
desse multiplexador são identificadas no circuito do TK/ZX81 como A0' a
A8' e estão conectadas aos pinos A0 a A8 da ROM, enquanto que a RAM
está ligada diretamente ao barramento A0 a A8 do Z80. Por isso não
adianta apenas fazer o
registrador I apontar para a RAM, pois ela sempre estará sendo
endereçada pelo Z80, mesmo durante a geração de vídeo.
Diante do exposto, para possibilitar a redefinição de caracteres
precisamos implementar uma RAM cujos pinos A0 a A8 estejam
conectados às linhas A0' a A8' e a melhor maneira de fazer isso é
conectando-os diretamente aos pinos correspondentes da ROM. E é isso o
que se propõe o presente artigo, implementar um redefinidor de
caracteres montado em uma pequena placa que encaixe
diretamente no soquete da ROM do TK85. Isso minimizará a quantidade de
fios a serem ligados dentro do TK e tornará o MOD, digamos, menos
amador ;-)
O circuito do CHR$128
A figura abaixo mostra o esquema do nosso circuito, onde temos o chip
da ROM do sistema operacional e os dois chips de memória 2114, que
dispensam maiores explicações. O integrado 74LS138 é o responsável pelo
mapeamento das memórias nos primeiros 16Kb do sistema. Quando acessamos
os endereços entre 0 e 8191, a ROM do SO é selecionada; entre 8192 e
12287 seleciona-se a ROM do HISPEED e, por fim, entre 12288 e 16383 são
selecionadas as memórias 2114. O sinal /ROMCS foi usado para prevenir
que haja conflito caso se conecte algum periférico que também requisite
essa área de memória. Neste caso, o redefinidor de caracteres ficará
desabilitado.
A
grande novidade desse circuito em relação ao original é o uso do
multiplex 74LS157 para criar a linha A9', o que possibilitará o acesso
a um
banco extra de 64 caracteres de tal forma que o TK85 passará a dispor
de até 128 caracteres únicos em oposição aos 64 originais. Para ativar
esse banco extra de 64 caracteres é necessário setar o bit 0 do
registrador I, o qual normalmente é zero. Por exemplo, para ativarmos
um banco de 64 caracteres no endereço 12288 carregamos o registrador I
com o valor $30; se quisermos 128 caracteres, carregamos o valor $31 em
I. Neste caso, os 64 caracteres extras são acessados através do bit 7
do código do caracter setado. Dito isso, vamos ver como funciona essa
parte do circuito.
Quando o sinal /RFSH estiver em nível lógico 1, o 157 ligará a entrada
1B à saída 1Y e A9' = A9. Com o /RFSH ativo, ou seja em nível 0, a
saída 1Y (A9') será gerada pelas duas portas NAND na entrada 1A. Neste
caso, se A8 = 1 e INVERT = 1, então A9' = 1 e o acesso se dará no
segundo banco de caracteres. Caso contrário, A9' = 0 e o acesso será no
primeiro banco.
Vale lembrar que o código de caracter com o bit 7 setado força a
inversão dos pixels do caracter na saída do sinal de vídeo, portanto,
os caracteres do banco extra devem ser definidos em reverso.
Sabendo como o circuito funciona, vamos finalmente para a parte prática!
A montagem do CHR$128
A motagem, apesar de simples, é trabalhosa e requer um pouco mais de
atenção e
habilidade com o ferro-de-solda. Separe o seguinte
material:
- 1 CI 74LS138
- 1 CI 74LS157
- 1 CI 74LS00
- 2 CI's 2114 (SRAM 1Kx4)
- Soquetes para os CI's (opcionais, mas é desejável pelo menos 1
para a ROM)
- 1 barra de pinos 1x40 180º
- Placa de CI virgem ou placa perfurada (universal) com 18x18 furos
- Fios finos (wireup) para as interligações
- Solda e ferro de solda
A minha intenção era fazer a montagem em uma pci confeccionada
especialmente para o CHR$128 mas infelizmente minha impressora está uma
porcaria e não foi possível, ainda,
confeccionar a pci. Portanto, a seguir descrevo como fazer a montagem
em uma placa universal e quando eu conseguir confeccionar a minha pci,
atualizo o artigo. De qualquer modo, deixo a seguir o layout da pci
para que vocês mesmo possam confeccioná-la, já que assim a montagem é
bem mais fácil.
Montagem em Placa Universal
Com o material em mãos, comecem pelo soquete da ROM e pela barra de
pinos. Tome por referência a figura a seguir como uma
sugestão de layout para a disposição dos componetes. Tanto no esquema
do circuito como no layout abaixo a ROM está identificada como 2364
apenas como referência, pois provavelmente na maioria dos TK's ela pode
ter outra identificação. O meu por exemplo usa o SCM92879P, para a qual
não
encontrei
referência em nenhun lugar. As 3 próximas fotos são apenas para
ilustrar o procedimento de montagem das barras de pino e do soquete da
ROM, não é a montagem do MOD propriamente. Infelizmente eu esqueci de
documentar esta parte e tive que improvisar para as fotos, I'm sorry :(
Pegue a barra de pinos e separe dois pedaços com 12 pinos cada. Vamos
começar soldando a barra de pinos 1; insira os pinos mais curtos na
placa pelo lado cobreado mas não deixe os pinos vazarem do outro lado
pois é necessário deixar um espaçamento entre o suporte da barra e a
ilha na placa, para poder receber a solda. Para facilitar, coloque a
placa sobre a mesa e insira a barra, dessa maneira os pinos não
atravessarão do outro lado. Solde o primeiro ou o último pino e cuide
para que a barra fique em ângulo de 90º com a placa. O resultado
deve ficar como na foto a seguir:
Solde agora o pino da outra ponta para que a barra fique firme. Pegue o
soquete de 24 pinos para a ROM e posicione-o ao lado da barra, pelo
outro lado da placa:
Solde os pinos 1 e 24 do soquete, fixando-o em sua posição. O próximo
passo é conectar cada pino do soquete com o seu correspondente na barra
de pinos, o que pode ser feito apenas com solda ou, se acharem mais
fácil, com pedacinhos de fio. Esta parte é muito crítica (e chata) e
deve-se
tomar muito cuidado para não fechar curto com os pinos vizinhos. Comece
pelo pino 13 e siga da esquerda para a direita (a não ser que você seja
canhoto), solda na mão esquerda e ferro na direita, e não tenha dó de
gastar solda! A cada pino ligado, verifique a continuidade com um
multímetro para ter certeza da conexão e de que não há curto com os
pinos laterais. Veja o exemplo abaixo com os pinos 13, 14 e 15 já
interligados:
Terminando com a barra 1, repita todo o procedimento para a barra 2 e
depois fixe os soquetes para os demais CIs, exceto para as memórias
2114 que deverão ser soldadas direto na placa, como explicarei adiante.
Finalizada essa etapa, usando fios finos do tipo wireup ou parecidos,
proceda à interligação dos componentes conforme detalhado no
esquemático do circuito, imprima-o e tenha-o em mãos durante toda a
montagem. Uma dica: as linhas de endereçamento e dados entre a ROM e a
memória 2114 não precisam ser
ligadas sequencialmente, use a sequencia que achar mais conveniente,
isto não afetará o funcionamento do circuito. Os demais sinais devem
ser ligados rigorosamente conforme consta no esquemático, portanto,
bastante atenção nessa hora ;-)
As memórias 2114 deverão ser montadas uma sobre a outra, por isso não
será possível o uso de soquete para elas pois a montagem ficaria muito
alta e impediria o fechamento do TK. Oriente-se pela ilustração a
seguir para montar as 2114:
Veja como ficou a minha montagem, já com os fios para as conexões na
placa do TK85:
Finalizada a montagem da placa é hora de conectar o dispositivo,
então vamos identificar os pontos de conexão na placa do TK:
A linha A8 é extraída do terminal do resistor R33 e a /ROMCS do
terminal
do resistor R26 ou R27. /RFSH, /MREQ, A13 e A14 são extraídos dos furos
na placa indicados na foto acima. O sinal /WR, que não está mostrado,
deve ser extraído do barramento de expansão na sétima trilha contando
da direita para a esquerda, conforme pode ser visto nas
fotos seguintes. O sinal /HSROMCS deve ser ligado ao pino 18 da ROM do
hispeed. Extraia o chip do soquete, levante o pino 18, coloque a ROM de
volta ao soquete e ligue o fio do /HSROMCS no pino levantado. O sinal
INVERT deve ser extraído do pino 5 do IC16, solde o fio neste pino (é o
fio azul nas fotos abaixo).
A montagem finalizada, com o dispositivo já espetado no soquete da ROM:
Pronto, está finalizada a montagem! Primeiro vamos testar a nova RAM em
12288. Conecte o teclado e digite POKE 12288,37 / PRINT PEEK 12288. Se
tudo estiver bem, será impresso 37 na tela. Caso contrário, verifique
as ligações, veja se não tem nenhum CI com posição invertida e/ou
defeituoso. Com tudo OK, carregue alguns programas redefinidos e curta
seu novo MOD!