Design retro para o primeiro console portátil do distante 1979



Em 1974, a Texas Instruments lançou os primeiros microcontroladores de 4 bits da família TMS1000, e a Intel em 1976 iniciou a produção de microcontroladores de 8 bits de sua famosa série MCS-48. E então começou.

Devido ao baixo custo e à auto-suficiência dos microcontroladores (então eles eram chamados diretamente - um microcomputador de chip único), os dispositivos eletrônicos de consumo eram mais sábios e seu número aumentou mais do que nunca. Com o advento dos microcontroladores, surgiu uma classe de dispositivos como os jogos eletrônicos portáteis, a escala do "desastre" pode ser estimada neste link . Entre toda essa variedade de jogos antigos, um que discutirei neste post se destacou - este é Milton Bradley Microvision, o primeiro jogo eletrônico portátil com cartuchos substituíveis, que usou os dois microcontroladores acima. Também tentarei me debruçar sobre as especificidades do desenvolvimento para este console.

Descrição geral




A microvisão foi lançada nos Estados Unidos há quase quarenta anos, em 1979. No total, 12 cartuchos com jogos foram vendidos para ela, entre os quais - vem completo com o console Block Buster (analógico do Breakout ), esportes - Bowling e Baseball, uma versão eletrônica do famoso jogo de tabuleiro Connect Four , Pinball e outros. A maioria dos jogos pode ser avaliada no emulador MVEM , que foi feito com base em uma série interessante de publicações , das quais eu também aprendi muitas coisas úteis. Aqui não vou me debruçar em detalhes sobre a descrição dos jogos originais do console, mas voltarei imediatamente para o seu mundo interior.



Uma característica importante do console é um LCD de 2 polegadas com uma resolução de 16x16 pixels. Bastante primitivo para os padrões de hoje, mas comparado aos conjuntos de LEDs e indicadores luminescentes a vácuo usados ​​em jogos portáteis na época, a tela LCD da matriz era um passo bastante progressivo. Além da Microvision, no mesmo ano, uma série de jogos eletrônicos Mego Mini-Vid com tela semelhante apareceu à venda, embora 13x20. Aparentemente, naquela época, esses eram os únicos dispositivos à venda com LCDs matriciais de tal resolução.



O monitor é controlado pelo chip Hughes SCUS0488 - este é um driver de LCD de matriz. O driver é alimentado por um estabilizador de tensão negativa UA79MG com um par de capacitores e resistores, que é a base do elemento mais simples.


Na caixa do console também estão os controles - uma matriz de botão 4x3 e um resistor variável de 10k 10 como uma raquete. Para reprodução de som, existe um piezodinâmico.

O mais importante é o motivo pelo qual a Microvision fez história, e todos se esqueceram do Mini-Vid mencionado acima, usando cartuchos substituíveis.



Externamente, o cartucho era uma parte superior destacável da caixa. No centro do cartucho, havia uma janela de plástico cobrindo a tela, na qual eram aplicados elementos de jogo coloridos e inscrições individuais para cada jogo. Abaixo estavam os furos para os botões cobertos por um filme fino, no qual as assinaturas eram aplicadas, e para cada jogo, furos eram feitos apenas para os botões usados. Provavelmente, esse arranjo do cartucho, segundo os autores, possibilitou maximizar a adaptação do console a um jogo específico.


Tabuleiro de jogo Block Buster, no caso e nas costas

A parte eletrônica do cartucho foi construída em um dos dois microcontroladores - TMS1100 ou Intel 8021 com o chicote necessário. Colocar o "cérebro" de um console em um cartucho pode parecer uma decisão bastante estranha, mas só permite que você convide com dois chips por jogo. Além disso, também adicionou versatilidade. Ao mesmo tempo, o preço do cartucho, aparentemente devido à presença do microcontrolador, não aumentou muito (por exemplo, o custo de 8021 em grandes lotes em 1976 foi de cerca de US $ 3).

Tudo isso alimentava uma ou duas coroas conectadas em paralelo (8021 era bastante voraz). Além disso, nas versões posteriores, os contatos da segunda bateria foram removidos e o espaço restante foi recomendado para ser usado como uma bateria sobressalente. Aparentemente, isso se deve ao fato de os usuários frequentemente confundirem a polaridade, obtendo um curto-circuito bastante perigoso.

Gravata


Comprei esse console antigo para escrever algum tipo de jogo e fazer um cartucho e, se possível, copiar a base de elementos do original o máximo possível.
Mas há um problema significativo - que o TMS1100, que o Intel 8021 tinha uma ROM mascarada, ou seja, programado na fábrica durante o processo de fabricação. Existe uma saída para o microcontrolador da Intel: 8021 é uma versão simplificada do 8048, que também possui uma ROM mascarada, mas a Intel produziu um análogo de 8048 com uma ROM programável - 8748, ambos com apagamento ultravioleta e mais barato quando programável.

Infelizmente, a situação é muito pior para o TMS1100 - houve uma versão de depuração do chip que funciona com uma ROM externa - TMS1098, mas comprá-lo agora, se possível, é muito difícil. Além disso, o chip foi fabricado no pacote DIP-64, é enorme por si só e não cabe no cartucho, mas também é necessária uma ROM bastante grande.

Em geral, o 8748 apagável por UV é o que você precisa, e a versão final do cartucho pode ser fabricada em uma versão indelével.


Acima está um P8748H programável e abaixo está um D8748H apagável por UV

Intel 8021


Abaixo está uma breve descrição de 8021, não 8748, porque Usarei apenas os recursos truncados do 8021 para ter apenas os recursos originalmente estabelecidos pelos desenvolvedores do console.

O subsistema de memória, como toda a família MCS-48, é baseado em uma arquitetura modificada de Harvard. A memória do programa é uma ROM interna de 1024 bytes, a memória de dados é de 64 bytes de RAM dinâmica.

A organização da RAM é mostrada na figura a seguir:



As células 0–7 ocupam os registros de trabalho endereçados diretamente R0 - R7, com R0 e R1 sendo usados ​​como ponteiros para acesso indireto a todas as células RAM. As células 8-23 são usadas para a pilha de chamadas de 8 níveis, embora também possam ser usadas através de R0-R1.

O microcontrolador possui um gerador de relógio interno, a frequência de referência é definida por um quartzo externo, corrente RC ou corrente LC. Um ciclo de máquina dura 10 ciclos e cada ciclo leva 3 períodos da frequência de referência. A frequência máxima é de 3,58 MHz, enquanto o ciclo da máquina dura 8,38 μs. A frequência mínima é limitada pelas especificações da DRAM e é de 600 kHz.

O 8021 contém duas portas de 8 bits e uma de 4 bits, que também podem ser usadas para conectar um expansor de portas de E / S, chip 8243. Todas as portas são quase bidirecionais.

Além disso, o microcontrolador possui um timer / contador de oito dígitos embutido. No modo timer, o contador T é incrementado em 1 a cada 32 ciclos da máquina. No estouro T, o sinalizador TF está definido. No modo contador, os pulsos são contados na entrada de teste T1.

O sistema de comando contém 64 instruções, das quais 36 são executadas em um ciclo e 28 em dois. A maioria das instruções é de byte único.

Lista de instruções com breves descrições


Preparação


Não houve problemas com a compra do 8748, o principal é prestar atenção que os chips foram produzidos usando diferentes tecnologias. Os primeiros NMOPs exigiam tensão de 25V para o firmware, rotulado como D8748. No final dos anos 70, esses microcontroladores começaram a ser construídos usando a tecnologia HMOP-E (uma versão aprimorada do NMOP da Intel), foram rotulados como D8748H e já exigiam 21V. A mesma voltagem foi requerida por um clone posterior da NEC (mPD8748H). A versão programável única foi identificada como P8748H.

A borracha UV foi comprada no chinês mais simples e barato com um cronômetro mecânico, que, como a prática demonstrou, lida perfeitamente com sua tarefa (embora não haja precisão no cronômetro em intervalos curtos). Apaga de forma confiável a ROM dos chips em ~ 2,5 minutos. Mais tarde, comprei uma borracha ZAX Quick-EII por um preço simbólico das mãos japonesas, nem sei em que ano é, pela aparência do início dos anos 90. Ele usa um flash de xenônio e apaga 8748 em 3 (!) Segundos, literalmente. Um vídeo (não o meu) com uma demonstração do trabalho pode ser visto aqui .

O principal problema foi o programador. O suporte para essa família obsoleta da Intel em programadores modernos está disponível apenas a um custo de US $ 300. Embora exista um Willem amador relativamente barato que possa trabalhar com o MCS-48 através de um adaptador, mas ele precisa de LPT, o que não me agradou. Eu tive que me soldar. Sou, digamos, um amador de rádio novato, então passei cerca de uma semana com ele, abandonando um dos dois 8748 que haviam chegado até lá (embora eu goste do pensamento de que ela era originalmente assim). Tomei o circuito publicado aqui como base, apenas o adaptei para o Atmega e para uma potência de 24V mais conveniente. Tudo isso foi soldado em uma tábua de pão:



Acabou, é claro, muito feio, e um dos mosfets trabalha até o limite (até um pouco para), mas, no final, o programador lidou com sua tarefa e me serviu bem.

Então, está tudo pronto, o firmware de teste pisca alegremente com o LED, é hora de fazer um cartucho.

Cartucho


A maior parte dos cartuchos trabalhava no TMS1100, porque A Signetics, que lançou a licença Intel 8021 da Intel, não forneceu o suprimento necessário de chips MB. Até alguns jogos que já foram escritos para o 8021 tiveram que ser portados para o TMS1100. Isso, aliás, nos permitiu abandonar o pacote perigoso de duas baterias, porque o consumo do microcontrolador de TI era de apenas 0,1W versus 1W para a Intel. Eu tenho apenas um dos 6 cartuchos com 8021, este é o jogo Connect Four, e foi tomado como base.

Tentei tornar o quadro o mais parecido com o original possível, mas, é claro, tive que fazer alterações. Em primeiro lugar, o tamanho do chip (DIP-40 versus DIP-28) e uma pinagem diferente. Em segundo lugar, tivemos que mudar as denominações no circuito oscilatório que define a frequência do relógio, porque o ciclo da máquina para as versões HMOS dos microcircuitos é de 15 ciclos e, para as versões MOS usadas nos cartuchos originais, 30 ciclos. Portanto, para uma autenticidade completa, meu cartucho funcionará a 1,25 MHz contra os 2,5 MHz originais, garantindo o mesmo desempenho.



Na foto acima, as placas de circuito impresso acabadas encomendadas na China e, enquanto estavam ligadas, desenhei e gravei a placa de circuito e montei um "complexo de depuração":


Finalmente, a parte do hardware está pronta e você pode começar a programar.

Exibição




Primeiro de tudo, eu tive que lidar com a saída para o LCD. Como escrevi acima, ele era controlado pelo driver Hughes 0488 usando multiplexação (recentemente, um artigo interessante sobre esse modo de controle de LCD foi publicado na Habré). É um driver, não um controlador; portanto, você não pode simplesmente ativar um pixel e realizar seus negócios; é necessário atualizar constantemente o conteúdo da tela com uma frequência de 30 a 50 Hz com comandos de baixo nível.

O diagrama de conexão é o seguinte:



Pinagem H0488:

Vdd - Potência (3-8V)
R1-R16 - Saídas de controle de string
C1-C16 - Saídas de controle de coluna
DATA0-DATA3 - Barramento de Dados
! Data Clk - Entrada do relógio de gravação de dados
Pulso de trava - Sinal de status de pinagem R0-R15, C0-C15

O significado do chip é o seguinte:

Através de 4 linhas de informação, o estado necessário de todas as 32 saídas do microcircuito é definido sequencialmente (16 por linha e coluna). I.e. indicamos em partes de 4 bits o estado das saídas para as linhas 1-4, depois 5-8, 9-12 e finalmente para 13-16, e também 4 vezes em 4 bits, indicamos o estado das colunas. Cada novo dado é cronometrado por um pulso ao longo da linha! DATA CLK. Depois de enviarmos todos os 8 dados, um pulso na linha Latch Pulse define o estado indicado das saídas R1-R16, C1-C16 que serão mantidas até o próximo pulso nesta linha.

Naturalmente, em um desses ciclos, não podemos indicar o estado de cada pixel individual independentemente dos outros, podemos apenas 16 (pelo número de interseções de linhas com colunas). Portanto, para atualizar independentemente o estado de cada pixel, serão necessários 256/16 = 16 ciclos.

Além disso, temos a responsabilidade de alterar a polaridade para eliminar a tensão constante dos eletrodos do LCD, caso contrário, o display se degradará rapidamente. A troca de polaridade ocorre na extremidade posterior do sinal no Latch Pulse em uma entrada baixa! Data Clock. É recomendável mudar a polaridade com a taxa de atualização da tela.

O acima é ilustrado pelo seguinte gráfico de tempo de uma folha de dados:



Tudo isso, implementado no assembler 8021 (que, a propósito, é significativamente reduzido em comparação com o assembler do resto da família, tudo pela mesma autenticidade que usei apenas instruções suportadas pelo 8021), pode ser algo como isto:

mov R0, #32 ;    . mov r1, #10000000b ;    r1-r2 mov r2, #00000000b ;  . mov r4, #00000010b ;    !DATA CLK. mov r3, #11110000b clr c loop: ;   r1-r16   . mov a, r1 ;   r1 loadNibble ;    R1-R4. mov a, r1 ;  4   r1 rrc a ;      , xch a, r1 ;    . swap a loadNibble ;    R5-R8. mov a, r2 ;   r2 loadNibble ;    R9-R12. mov a, r2 ;  4   r2 rrc a ;      ,  xch a, r2 ;  C,     . swap a loadNibble ;    R13-R16 ;   C1-C16     . mov a, @R0 ;       loadNibble ;       C1-C4. mov a, @R0 swap a ;   4 . loadNibble ;     C4-C8. inc R0 ;     mov a, @R0 ;     , loadNibble ;      4 . mov a, @R0 swap a ;   4 . loadNibble ;     C9-C12. inc R0 ;    inc a ;   R0-R15  C0-C15, outl p1, a ;  Latch Pulse  1. jnc loop ;      . clr a ; outl p1, a ; . inc a ; outl p1, a ; loadNibble macro anl a, r3 ;    . outl p1, a ;   . orl a, r4 outl p1, a ; !DATA CLK. endm 

Esta é a minha versão mais rápida da sub-rotina que exibe a imagem armazenada na RAM. É realizado em 1152 ciclos de máquina (que no nosso caso é de ~ 12 μs).

A taxa máxima de atualização da tela é de cerca de 70 quadros por segundo (se o microcontrolador não fizer mais nada), o que é, em princípio, redundante, portanto, para salvar registros e ROMs, na prática eu usei outras sub-rotinas - mais lentas e mais adequadas para tarefas específicas. Porém, nessa frequência, levando em consideração a alta inércia dessa tela, é possível exibir fotos com 4 gradações de cinza (como um niblonog no KPDV), mudando rapidamente os quadros. Ou até curtas animações de quatro cores:


Como você pode ver, o contraste deixa muito a desejar, é especialmente impressionante quando todas as linhas e colunas estão envolvidas, mas não há nada a ser feito - os custos do controle multiplex.

Teclado




Tudo é muito mais simples aqui. Os botões são agrupados em uma matriz de 4 linhas e 3 colunas. As linhas são conectadas aos pinos P0.4-P0.7, as colunas são conectadas aos P0.0-P0.2.



Como observei acima, as portas do 8021 são quase bidirecionais; portanto, para conhecer o status dos terminais, você deve primeiro enviar unidades para eles. I.e. ao inserir dados, ocorre uma conjunção entre os sinais de entrada e o conteúdo do buffer, que corresponde aos dados mais recentes exibidos na porta. Uma pesquisa de teclado é mais ou menos assim:

  mov a, #01111111b ; 0        1, outl p0, a ; ,      . in a, p0 ; , 0       ;      

Paddle




Ou, em russo, a roda do manipulador instalada na parte inferior do console é um resistor variável de 10kΩ com uma alça decorativa, que pode ser girada para controlar algo no jogo. Obviamente, não havia ADC no 8021 ou no TMS1100. O ângulo de rotação foi determinado pela velocidade de carga do capacitor, que foi prudentemente soldado à placa do console.



Tudo funciona da seguinte maneira: enquanto os pinos P2.2-P2.3 estão altos, o capacitor é descarregado e a unidade lógica está na entrada de teste T1. Depois de definirmos P2.2 a P2.3 para um nível baixo, o capacitor começará a carregar e, após algum tempo, exponencialmente dependente da resistência do resistor variável, a queda de tensão passará a ser tal que T1 seja definido como 0. Resta apenas detectar o tempo até o aparecimento de zero em T1, que será proporcional ao ângulo de rotação da raquete (Mais detalhes e mais interessante sobre esses esquemas podem ser encontrados em DI HALT'a ). No código, isso pode ser assim:

  clr a mov r1, a outl p2, a ; 0  P2.2-P2.3 loop: inc r1 ; r1 jt1 loop ;  T1  mov a, #00110000b ; 1  P2.2-P2.3 outl p2, a ;     



Som


Aqui é bem simples: um piezodinâmico é conectado às duas linhas da porta P2.0 e P2.1, tudo o que precisamos fazer é alternar as pernas com a frequência certa.

O que aconteceu


Como resultado, escrevi dois jogos - Tetris e uma espécie de Flappy Bird. Para depuração, usei o Intel D8748H e um clone do NEC D8749HD, diferindo apenas no tamanho da ROM. Usei o ambiente de desenvolvimento integrado 8048 como montador e depurador. No processo, obtive uma experiência inesquecível - o fluxo constante de microcontroladores do console para o apagador, do apagador para o programador e de lá para o console, e tudo isso é acompanhado por um cheiro hospitalar de ar ultravioleta ionizado ...

Anotei os programas concluídos no Intel P8748H, que era programável, que soldava nas placas de circuito impresso que haviam chegado até então.


Comparação com as placas originais, da esquerda para a direita: Block Buster, Minha opção, Connect Four

Eu tive que usar o original como um caso; apenas um dos dois cartuchos disponíveis para o jogo Block Buster se mostrou inoperante.



O casco não foi suficiente para o segundo jogo:


Conclusão


O Microvision MB foi produzido antes de 1981 e, embora as vendas no início tenham sido bem-sucedidas, um pequeno número de jogos (13 cartuchos foram lançados no total) e problemas de qualidade são geralmente chamados de razões para o declínio nas vendas. Eu acrescentaria um tamanho excessivamente grande, especialmente se comparado à série Nintendo Game & Watch que apareceu na época e se tornou um sucesso.

Códigos e esquemas de fonte publicados no GitHub

Source: https://habr.com/ru/post/pt416865/


All Articles