sexta-feira, 2 de maio de 2014

Como funciona um cartucho de Atari 2600 com menu.

Quero deixar a minha contribuição para quem esta pensando em montar um multicart e quer fazer bonito.

Vou explicar aqui a ideia de como funciona para ter um multicart com menu, como funciona o 'truque' da escolha etc.

Vamos la, essa explicação é destinada a quem entende um pouco da programação do Atari2600 E de um pouco de eletronica, precisamente portas lógicas, ou seja, não muito difícil de fazer.

Um bankswitch nada mais é que mudar um banco da ROM/EPROM durante o funcionamento, como ja devem saber o atari só endereça diretamente até 4kb, para ter jogos maiores existe um circuito que pula para os próximos 4kb da ROM e com isso seu código dobra de tamanho, existem vários BS por ai, mas não to aqui para falar de BS, porem o menu utiliza da mesma técnica.

O atari quando é ligado, SEMPRE acessa o endereço FFFC da ROM, neste endereço esta o ponto exato da rom onde o jogo começa, pois quando a gente programa, o inicio pode variar, isso faz com que seja normalizada, você acessa o endereço FFFC e o código do jogo indica o lugar certo para inicio.

Muito bem, sabendo disso, montamos um espécie de BS que na verdade é acessada apenas um vez (pelo menu) e depois não trabalha mais, ela retem o endereço do banco que queremos e fica la até você desligar o console.

Então vamos montar um cartucho com 15 jogos, como ficaria ? Mas porque 15 jogos se a lógica me diz que vão ser blocos múltiplos de 2 e nesse caso era para ser 16 (na eprom 27C512 cabem 16 blocos de 4kb) ? bom,  o menu já ocupa um bloco, sendo assim, sobram 15 blocos para os jogos.

No cartucho você inclui um registrador de 4bits, pode ser um 74ls173, atente para que o mesmo tenha um capacitor no reset para zerar efetivamente ao ser ligado, nas 4 saídas do mesmo, temos que ter o endereço 0000 .. esse será o banco que vamos colocar o menu, ou seja, o primeiro banco, o atari vai acessar o endereço FFFC do código do menu que la terá o endereço do inicio do seu código correto.

Muito bem, não entrando em como programar para o 2600, então os 15 jogos vão ter que acessar os bancos de 0001 até 1111 correto ? isso nos dá 15 combinações, você cria um menu, que inicia já no primeiro nome com valor 0001 e ao pressionar o controle abaixo ou acima, você aumenta ou diminui esse valor, acho que até aqui tranquilo certo ??

Essa contagem é em binário, então o segundo jogo será 0010, o terceiro será 0011 e assim por diante ...

Ok, já sabemos como atribuir um valor de banco para o jogo selecionado na tela, mas e para transferir isso para o registrador no cartucho ??

O 2600 endereça até 4kb diretamente, o que passar disso tem que ter um truque, o mais famoso BS acessa o endereço FFF9 para ir para seu segundo banco e FFF8 para voltar ao primeiro banco, na linha de endereço do slot, temos de A0 até A12, sendo este ultimo apenas um ativador da rom (ele manda sinal 1 para ativar a ROM e 0 para desativar) então o que interessa esta somente de A0 até A11, são com eles que vamos identificar o endereço enviado pelo atari.

Então veja, para o endereço FFF8, os pinos de address (A0 a A11) vão estar assim:

A A A A A A A A A A A A A < Pinos de endereços
1 1 1 9 8 7 6 5 4 3 2 1 0
2 1 0

1 1 1 1 1 1 1 1 1 1 0 0 0 < valores nos pinos

Agora veja a chamada para o FFF9:

A A A A A A A A A A A A A < Pinos de endereços
1 1 1 9 8 7 6 5 4 3 2 1 0
2 1 0

1 1 1 1 1 1 1 1 1 1 0 0 1 < valores nos pinos

Repare que somente o pino A0 muda seu valor, isso nos facilita muito na hora de montar o hardware.

Quando eu digo FFF8 considere que ele não 'entende' o primeiro F (em binário 1111) pois ele só endereça até o A11, então só cabe ali o 1 mais a direita do F .. então qualquer outro valor que tenha 1 no seu digito mais a direita vai funcionar na verdade, podendo ser 1FF8, 3FF8 e assim vai.

Então temos que designar um endereço que de preferência não entre em conflito com as chamadas, nem da ROM nem dos comandos internos, difícil ?? sim, apesar de regulamentado os endereços a usar, tem jogo (programador) que usam chamadas diferentes nos seus games, e isso acaba dando zica na pratica, imagine se o menu funcionar com FFF9 para escolher o jogo, e eu estou usando um jogo de 8KB que utiliza esse endereço ?? não vai dar certo, em anexo (me peçam por mensagem abaixo) uma lista com os endereços internos utilizados, pelo menos os mais utilizados, e seus mirrors.

Nos meus menus eu utilizo o endereço 03CX  (X = qualquer valor), se você procurar na tabela, vai ver que ele é um mirror de um endereço da RIOT ... então se os programadores utilizarem os endereços padrões nos seus códigos, nenhum problema acontecerá, já os que, por algum motivo, resolvem utilizar um endereço mirror, pode dar problema, e dá no 03CX (alguns jogos não funcionam com meu menu por isso)(OBS: como o exemplo que dei do BS F8 ele utiliza um endereço da ROM pois ativa o pino A12, o programador tem que  saber exatamente o que tem nesse endereço que não vá dar conflito com o resto do código, e eu estou pensando em mudar meu endereço de chamada para uma na ROM, acho que os jogos que não funcionam pela incompatibilidade possam voltar a funcionar, só testando)

X pode ser qualquer valor, não importa, visto que ali teremos a informação de qual banco acionar, já sabemos também que o endereço 03C0 nunca será chamado, pois o banco 0 é utilizado pelo próprio menu certo ??

Então no meu código fica assim, o jogador ao apertar o botão do controle ou acionar a chave RESET no console, retem o numero do jogo selecionado na lista, vamos supor que foi o décimo jogo, transformamos esse numero 10 em decimal para hexadecimal que fica A e adicionamos o endereço da chamada, no meu caso 03C, ficando 03CA.

Vamos ver como é a chamada do 03CX:

A A A A A A A A A A A A A < Pinos de endereços
1 1 1 9 8 7 6 5 4 3 2 1 0
2 1 0

0 0 0 1 1 1 1 0 0 X X X X < valores nos pinos

Sabendo o endereço que se quer usar, filtramos esse endereço na linha de endereços para acionar a função da troca de jogo (do menu para um jogo, isso no cartucho), ai entra a eletrônica, queremos registrar o endereço do banco, no exemplo o A, ou precisamente 1010 em binário.

Precisamos de um circuito que identifique que o endereço 03C foi chamado e ai sim pegar o A final e jogar no registrador.

03C em HEX fica 000111100 em binário, basta no cartucho, com auxilio de portas logicas verificar se é isso que esta chegando respectivamente de A12 a A4 (A3 a A0 não interessa, será jogado diretamente no registrador, não é necessário sua verificação) ... mas eu disse la traz que o A12 era somente para ativação da ROM certo ??? porque eu to verificando ele agora, e porque ele é um 0 e não um 1 para ativar a ROM ??? Porque agora não queremos ativar a rom, queremos apenas selecionar o banco certo na ROM do cartucho apenas, o endereço 13C com toda certeza é um endereço que a ROM do jogo utiliza, nenhum endereço referente a ROM do cartucho pode ser usado, então o 1 do começo não pode estar ali, vamos usar o 0 e temos que verificar se ele é um 0 mesmo, pois o menu e os jogos vão sempre utilizar o endereço 13CX, cagando o que o registrador faz no cartucho (trocando de banco durante o jogo).

Bom, se as portas lógicas determinarem que o endereço 03C realmente foi chamado, então basta pegar os valores dos pinos de A3 a A0 do jeito que vierem e colocar diretamente no registrador de 4bits, a saida do registrador estará ligado diretamente aos pinos da ROM/EPROM que mudam os bancos (no caso de 15 jogos no cartucho na eprom 27C512, serão os pinos A15 a A12, lembrando que o A12 da ROM não é o A12 do barramento, eles não se comunicam).

Legal, o meu código faz uma chamada 03CX e o banco é trocado, fantástico certo ??? errado, ainda temos um grave problema ai que precisa ser resolvido, já vi muitos errarem e abandonarem seus projetos justamente ai, explico.

O atari endereça 4kb, você já está careca de saber isso, legal .... quando usamos um sistema de BS ele troca de banco para ter mais informação no mesmo jogo, porém o jogo está preparado para isso, quando a chamada para troca de banco é feita, o código sabe o que vai ter no segundo banco na sequência de onde o primeiro banco parou, isso porque o atari não 'sabe' que o banco foi trocado, ele continua a acessar as informações da ROM achando que o mesmo banco de 4kb esta ativo, o programador tem que se preocupar que a sequência de informações no segundo banco seja precisa para o código não se perder.

Mas e o menu ?? como será que quando ele faz a chamada, ele vai saber que a ROM do jogo vai estar na posição certa ?? Já foi dito, basta, no código do menu, fazer uma chamada para o endereço FFFC, onde TODO jogo contém o inicio do seu próprio código, então , o menu esteja ele fazendo o que estiver, será desviado para FFFC ao passo que o banco na ROM é trocado.

Certo ?? ainda não, ainda falta uma coisa tão importante quanto a anterior, pense que o atari executa o código ininterruptamente assim que é ligado, ele não para, ele não pausa e tal ... seguindo a lógica vamos pensar como funciona até aqui, o que entendemos:

1. vc liga o cartucho, o registrador no cartucho é zerado escolhendo o banco 0000 da ROM
2. o menu é chamado pelo console pelo endereço FFFC que indica o início correto do código
3. o código fica esperando uma ação do jogador, escolher um dos itens e aguarda um comando de execução
4. ao chamar o código o hardware no cartucho vai trocar de banco
5. banco trocado o código faz a chamada ao FFFC do jogo escolhido para iniciar corretamente
6. todos ficam felizes para sempre ....

Não, ainda não ficam, porque se você trocou o banco no cartucho no passo 4, o endereço seguinte que o código que esta sendo executado pelo console, não será mais do código do menu e sim do código do novo banco, e o que vai conter la ?? ninguém sabe, você trocou de banco, o próximo passo seria uma chamada ao endereço FFFC que nunca será executado, pois o banco foi trocado e essa informação se perdeu, veja, você troca de banco e chama o FFFC, se trocou de banco, o que garante que a próxima instrução será uma chamada ao FFFC ?? Bom, como resolver isso ??

Veja que ao executar a chamada da troca de banco, eu preciso garantir que parte do meu código ainda esteja 'visível' pelo programa do menu para que a troca seja concluída com sucesso.

Então vamos detalhar mais um pouco o momento exato da troca:

jogo escolhido 10 (A como no exemplo)
adiciona o endereço 03C a chamada ficando 03CA
executa uma chamada nesse endereço (nessa hora o banco é trocado pelo cartucho)
agora teríamos que chamar o endereço FFFC, e que ficou de fora.

Então a solução é a seguinte:

jogo escolhido 10 (A)
adiciona o endereço 03C a chamada ficando 03CA
carregamos, ignorando ou não as informações da RAM, um código que vai terminar o processo
executamos o código da RAM
código da RAM faz a chamada 03CA
código da RAM faz a chamada FFFC
novo código do banco escolhido entra em ação e toda essa informação é perdida

Bom, como já trocamos o banco e a chamada de inicialização foi feita, não precisamos mais do menu agora certo ?? então perder a informação dele não causa problema algum.

O que ocorre na solução é que o atari precisa seguir instruções, não importa se é da ROM ou da RAM, o problema é que a RAM tem apenas 128b, muito pouco como você interessado nesse assunto já deve saber, mas na RAM precisamos de poucas instruções, apenas as de chamada, que no caso do exemplo é uma chamada, para 03CA e depois uma chamada para FFFC e pronto, isso ocupa poucos bites e da para ser colocado na RAM sem problemas.

Mas como fazer isso ?? oras, normalmente o código de qualquer jogo não começa limpando a RAM com 00 ? Basta fazer uma rotina que carregue o seu código na RAM em um endereço especifico (quando um jogo da lista for escolhido) e depois fazer uma chamada para ela, sabendo que a RAM esta alocada de 0080 a 00FF, seu código tem que estar dentro desses valores e você faz uma chamada para ele, por exemplo chamar, diretamente o endereço 0080 (ou 80) se você colocou ele no inicio da RAM ... como eu disse, depois que a chamada é feita, nada mais do menu importa, apenas que ele finalize a troca do banco, então o que tinha antes na RAM, que faz o menu funcionar, exibir as coisas certinhas, valor de cor do fundo, valor de cor das letras e tudo mais, não interessam mais agora, você ignora tudo tacando la seu novo código e executando de lá.

Bom, basicamente isso funciona ótemamente bem para um cartucho com 15 jogos de 4kb, o menu que programei tem 15 linhas (16 na verdade, a última eu utilizo para copyright).

E se for utilizar um BS com jogos 8kb com o menu ?? jogos de 8kb utilizam o A12 da ROM, suas chamadas vão ter que mudar para uma ROM maior ou vão caber metade dos jogos, ao invés de utilizar A15 a A12 da ROM, vamos utilizar A16 a A13 para os bancos e o A12 fica para o sistema de BS utilizado, mesma coisa para jogos de 16KB, sendo que esse utiliza A13 e A12 para o sistema de BS, os restantes da ROM podem ser usados para trocar seus bancos com outros jogos, no menu não é necessário mudar absolutamente nada para utilizar um jogo com BS.

Se for misturar jogos de diferentes BS fiquem espertos, jogos que não utilizam BS funcionam de boa (jogos até 4kb), jogos maiores tem que ter o sistema BS próprio para funcionar, mas jogos que não utilizam BS podem ser misturar com eles, mas cuide para que as ROMs dos jogos estejam do mesmo tamanho, dobrando ou quadruplicando as roms de 4kb para ficar do tamanho dos jogos que usam o BS.

Teoricamente, os BS mais utilizados são F8 e F6, com jogos de 8kb e 16kb respectivamente, e na teoria, um jogo dobrado de F8 TERIA que funcionar no BS F6, mas na pratica, metade dos jogos não funciona, então é melhor não misturar, ou se você tiver saco, ir testando quais vão funcionar e colocar uma lista aqui para gente consultar depois =-D

Bom, e se eu quiser um cartucho com mais que 15 jogos ?? Ai você vai ter que se virar =-)) eu desenvolvi algumas soluções, mas eu sou perfeccionista, tive que entrar em acordo comigo mesmo de qual utilizar, eu cheguei em 2 soluções plausíveis e tive que optar por uma delas.

Uma delas foi via código, você precisa de um registrador para cada tela cheia (até agora, expliquei como ter somente 1 tela cheia certo?), e um registrador para as páginas (que são bancos de 16 bancos, parece difícil né ? hehehe) para exemplificar novamente, imagine somente jogos de 4kb, os bancos que controlamos pelo menu são A15 a A12 .. se na ROM tiver o pino A16 moscando (27C010 por exemplo) ele pode controlar 2 páginas, cada página com um conjunto desse explicado (15 jogos). Então você pode controlar via código, que seria fazer uma chamada especifica que controle somente o registrador que cuida das páginas, nesse caso não fazendo nenhuma chamada ao FFFC pois você não quer trocar o jogo, quer continuar no menu, é mais simples que trocar de jogo, faz a chamada sem carregar código algum na RAM, sem fazer chamada nenhuma além da chamada que troca justamente a página (e obviamente é diferente da chamada que troca do menu para o jogo escolhido).

Essa solução é ótema, porém tem um efeito colateral que me irritava bastante, ao fazer a chamada da troca de páginas, funcionava, mas a tela dava uma piscada, e isso irritava, pois comecei a montar cartuchos com muitos jogos (cartucho de 240 jogos tem 16 páginas), mas tem a facilidade de fazer isso com o controle na mão, você coloca para direita, a pagina aumenta, coloca para esquerda, a pagina diminui e tal, comodidade 10.

A outra solução que tive e acabei usando pois não existe a piscada na tela, é de colocar um botão no cartucho, ele age diretamente no registrador (que agora não é mais um registrador, é um contador binário), existem vários tipos de contadores e usei o mais comum, que somente conta para cima (somando e não diminuindo) e para isso a parte chata é ter que adicionar um botão no cartucho que faz a contagem, foi uma escolha, como a pessoa escolhe o jogo e depois pode ficar horas jogando, achei que não seria tão ruim assim, o problema é alguém apertar o botão com o jogo já escolhido, entenderam que vai dar merda né ?? hehehe

Bom, é isso, tudo o que eu aprendi sozinho obviamente, apenas lendo uma coisa e outra por ai, fazendo engenharia reversa em alguns cartuchos e tals, foi o que passei para vocês ai.

Gostaria de ter contato de quem se meter a besta e montar o seu modelo, trocar ideias, de repente uma solução diferente para os problemas que enfrentei etc.

Dablio.

25 comentários:

  1. Olá, estava precisando trocar uma ideia contigo, sobre um Atari com AV que tenho, ele está com um chiado quando liga na tv, tipo interferência e quando mexo no controle e uso o botão de tiro dá contato na tela, deixando a imagem meio esbranquiçada. O que poderia ser? Grato.

    ResponderExcluir
    Respostas
    1. Eu ja tive esse problema e era o TIA.

      Excluir
    2. ola amigo é simples deve estar encostando em algo dentro abra é resolde é simples

      Excluir
    3. ola amigo é simples deve estar encostando em algo dentro abra é resolde é simples

      Excluir
  2. Hum, então pode ser. Fiz esse final de semana um teste na minha LED de 32" e o som ficou bom, não deu chiado, tipo interferência, mas a imagem ficou fora de foco, como se desse sobra "branca" ao invés da imagem limpa como no emulador. Ainda acha que pode ser o TIA? Se for você presta assistência? Grato.

    ResponderExcluir
    Respostas
    1. Pode mandar para mim que eu dou um jeito sim.

      Excluir
  3. Olá. Esse final de ano sai o flash card Atari? Eita vai ser top! Cara tu dá vida ao nosso bom e velho atari, não pare nunca com as novidades hein? No aguardo! Abraço.

    ResponderExcluir
    Respostas
    1. Sai não, vai sair é uma outra fornada de cartuchos personalizados ...

      Excluir
  4. Olá! É possível para um iniciante montar um cartucho em casa? Gostaria de fazer um pelo desafio. Qual o tipo de gravador de EEPROM que é utilizado? O kit de placa de circuito impresso vendido no mercado pode ser usado para isso? Gostaria de começar com um cartucho simples, depois vou complicando... valeu desde já.

    ResponderExcluir
    Respostas
    1. Para montar um cartucho simples, tem que ser um jogo de 4K ... vc usa uma eprom 27c32 e grava a rom do jogo nele, no pino OE da eprom, vc pega o sinal que vem do slot A12 e inverte, o resto dos pinos da eprom são ligados diretamente no slot, inverter o sinal do A12 pode ser com um transistor, 2 capacitores e um resistor, ou coloca um 74LS00 ou 74LS04 e uma uma porta inversora deles ... com isso vc pode gravar um river raid, seaquest, pitfall, enduro, forstibite etc ,, tem varios jogos legais em 4K .. mais facil que isso não tem rapaz.

      Excluir
  5. Fiz uma "listinha" não sei se é possível, mas não custa tentar!
    1 - River Raid
    2 - Enduro
    3 - Pac Man
    4 - Hero
    5 - Keystone Kapers
    6 - Bobby is Going Home
    7 - Tennis
    8 - Boliwg (Boliche)
    9 - Frostbite
    10 - Pitfall
    11 - Seaquest
    12 - Pressure Cooker
    13 - Sexta Feira 13
    14 - Oink
    15 - Megamania
    Fiz essa de 15 não sei se pode ser com 30, mas quanto ficaria essa, caso seja possível. Grato.

    ResponderExcluir
    Respostas
    1. Da para montar sim, com esses 15 jogos faço 100,00 + frete

      Excluir
    2. Opa! Blza! Me manda um e-mail depois: aurimar091@gmail.com

      Excluir
  6. Olá Boa noite.
    Me chamo Joselito. E Sou Tecnólogo em Telecomunicação, trabalho atualmente em Sistemas embarcado. Bem passando as formalidades, achei muito interessante esse seu artigo, sou saudosista, e quando era criança ficava babando com o Atari, e o Odisey, porem fui de família pobre, e não tive a oportunidade de desfrutar quando criança. Com o tempo aprendi também sozinho a programar no Z-80, para o ZX81(TK-82/85), TK90x, CP500, depois para Amiga500(MC6800), depois já adulto trabalho com os processadores ARM7/9, CortexA9, AVR32,, pic's, DSpic. Bem vamos ao que interessa, gostaria de saber se Você tem interesse em fazer comigo um cartucho usando qualquer um desses processadores que informei e uma memoria serial flash(mais circuito periférico), no qual colocaríamos todos os jogos possíveis e imagináveis de Atari? Minha ideia era pesquisar na net a arquitetura do Atari, mas vi que nisso você domina, e logo me pouparia algum tempo, quanto ao assembly do 2600 dei uma olhada nos mnemônicos e vi que são bem simples, mas como disse não conheço nada da Arquitetura do Atari, e nisso acredito que Você domine. Há esqueci de dizer que todo o Hardware deixa por minha conta, na empresa que trabalho faço todo o projeto, desde a escolha dos componentes (BOM) até a PCB, então nessa parte eu domino. Então caso tenha interesse meu email é Joselito_oliveira@outlook.com. Fique com Deus e Obrigado pelo Ótimo artigo

    ResponderExcluir
  7. Boa noite Dablio, estou com um Supergame da CCE, com problema ele não da imagem? Vc faz este tipo de reparo?
    Como faço pra te mandar?
    Uma abraço e parabéns pelo seus post´s

    ResponderExcluir
  8. Boa tarde amigo, teria como você disponibilizar um esquema para fazer um cartucho do river raid, obrigado desde já

    ResponderExcluir
  9. Amigo,tenho um atari 2600 com 32 (32 BUILT IN) jogos na memória é possivel modificar o integrado para outro com mais jogos? a referencia é:kc6208-019 svc32n1!Obrigado.

    ResponderExcluir
  10. Amigo,tenho um atari 2600 com 32 (32 BUILT IN) jogos na memória é possivel modificar o integrado para outro com mais jogos? a referencia é:kc6208-019 svc32n1!Obrigado.

    ResponderExcluir
    Respostas
    1. eu tenho diversos desse modelo aqui, com 32, 64, 128, 255, 320 jogos embutidos, mas o sistema que criaram, é bem estranho, a mudança para adicionar mais jogos não vale a pena, melhor vc comprar um multicart meu, que funciona com menu na tela bonitinho e 240 jogos sem repetir, mais barato e rapido.

      Excluir
  11. Amigo, gostaria de encomendar um cartucho de Atari, como faço? Qual seu email?

    ResponderExcluir
    Respostas
    1. Beleza, meu email é dabliobr @ yahoo . com . br

      Excluir
  12. boa noite, gostei muito do seu artigo, uma pergunta vc ainda esta fazendo cartucho?

    ResponderExcluir
    Respostas
    1. Estou sim, pode achar meus anuncio no mercadolivre direto no link: www.dabliogames.ml

      Excluir