terça-feira, 27 de maio de 2025

Matrix - Raining Code para o TRS-Color

Tempos atrás, depois de fazer o Raining Code para o MSX, portei para o ZX81 e para o TRS-80, o que ocorreu com certa facilidade, porque todos utilizam o Z80 como processador e, assim, só precisava fazer as devidas adaptações para o hardware de vídeo.

Aí pensei: fazer esse programa para o TRS-Color seria muito legal, porque ele tem um modo de alta resolução (256x192), como o MSX, em duas cores (verde e preto). Além disso, até onde eu sei, ninguém havia feito ainda, ao menos em alta resolução. 

Só que minha falta de intimidade com o assembly 6809 foi, há dois anos atrás, uma barreira insuperável e acabei engavetando o projeto. Na época tentei portar o código, traduzindo as instruções e endereços do Z80 para o 6809. Minha abordagem do problema não ajudou, pelo contrário, apenas complicou.

Recentemente, resolvi retomar e cheguei à conclusão que a única maneira de avançar com o programa era retroceder. Assim, em vez de tentar portar o código do Z80 para o 6809, resolvi recomeçar do zero, de maneira que ia escrevendo o código aos poucos, ao tempo que ia aprendendo melhor o assembly do 6809. Depois de uma certa relutância inicial, meu cérebro finalmente sintonizou comunicação com o 6809 e a partir daí a programação fluiu. Tomei como lição que tentar traduzir a implementação diretamente do Z80 para o 6809 é um equívoco e que o melhor é focar no algoritmo, ou seja, partir de um nível de abstração mais elevado, para daí iniciar a nova implementação. Isso permite o uso mais adequado das peculiaridades de uma linguagem sem a interferência das técnicas de implementação da outra.

O processo

Comecei "importando" os caracteres alfanuméricos e katakana de uma ROM japonesa do MSX. Infelizmente não arrumei uma maneira de fazer isso diretamente, porque não há compatibilidade de arquivos entre o MSX e o TRS-Color, tampouco encontrei maneira de importar os dados via emulador. O jeito foi fazer à mão. Janela do openMSX de um lado, com o meu editor (não publicado) fornecendo as informações byte a byte dos caracteres, janela do Xroar do outro, anotando os dados em linhas data no Color Basic. Com muita paciência fui fazendo aos poucos e até que finalmente tinha o resultado na tela:

 

Resultado do teste dos caracteres na tela do Color, no modo RG6.

  

Minha ferramenta de edição no MSX, de onde obtive os dados dos caracteres.

Dados dos caracteres em hexadecimal. 

Fiz ainda um pequeno ajuste, já que os caracteres do MSX são justificados do lado esquerdo e apareciam "colados" com a margem esquerda da tela do Color, o que me incomodou, esteticamente. A solução foi um deslocamento de bits para a direita. O BASIC não tem instrução de deslocamento de bits, é verdade, mas a matemática básica salva: para deslocar bits de um número binário para a direita é só tomar o valor inteiro do número dividido por dois. Uma pequena rotina deu conta fazer isso com os 736 bytes dos 92 caracteres que utilizei.

Depois foi questão de elaborar o programa em si para manipular os dados na tela. Fiz isso utilizando o Disk Edtasm 6309, ferramenta nativa do Color, como montador para o 6809.

Todos os efeitos das outras versões foram reproduzidos: cada coluna tem um delay para iniciar a descida dos caracteres e o seu apagamento; quatro velocidades diferentes para a escrita e apagamento dos caracteres, sorteadas a cada reinício de cada coluna; e finalmente, caracteres já escritos são sobrescritos por caracteres aleatórios (seriam "patches" na Matrix?). Para destacar o primeiro caractere que vai descendo pela tela em cada coluna, utilizei o velho truque deslocamento de bits para gerar o caractere bold. Poderia ter utilizado os caracteres bold pré-processados, mas acabei programando a geração dos mesmos on the fly.

Acredito que o resultado ficou muito bom, um pouco atrás apenas da versão para MSX, cuja coluna descendente tem 3 tons de verde além do caractere branco como destaque.

DownloadMatrix-TRS-Color.dsk

  



The Matrix has you.


quarta-feira, 7 de maio de 2025

Demo do Color Clube Brasil - TRS-Color

Fazia tempos que não fazia nada para o Color. Desde o Color Poker, mergulhei profundamente no universo do Z80 e fiz um bocado de coisas no MSX, algumas outras no TK-85 (ZX81) e ainda um par de coisas para o TRS-80.

Há alguns anos eu adquiri um CP-400, igual àquele que foi o primeiro computador que tive, lá em 1985. Mas acabei não usando muito, porque começou a apresentar um problema de vídeo. Até que esses dias resolvi finalmente arrumar e, ele novo de novo, de tão bom que ficou me animou a fazer alguma coisa para rodar nele.

Inspirado no efeito de abertura dos episódios do canal do 8-Bit Guy, resolvi fazer algo do gênero para o Color, que na realidade já tinha feito no MSX e depois para o TK 85 há algum tempo. 

Primeiro fiz uma tela em homenagem ao Clube Color Brasil (grupo do Facebook) utilizando o modo semigráfico (e bastante colorido) do Color para poder utilizar o efeito em cima dela. Ou melhor, na realidade, a tela vai surgindo a partir do efeito. Em seguida, joguei mais um efeito de troca de cores e finalmente um scroll up para recomeçar o efeito inicial. Olha aí:

 


 

O Assembly 6809

Apesar da minha experiência com o Color BASIC do TRS-Color, o assembly da CPU Motorola 6809 era para mim um mistério. Mas sempre tive muita curiosidade, até para conhecer as diferenças em relação ao assembly Z80. Então lá fui eu apreender "uma nova língua". O montador que uso é o Disk EDTASM++ (ferramenta nativa).  A vantagem de usar esse montador é que ele é muito similar ao EDTASM para o TRS-80, no qual já tenho alguma experiência, já que fiz versões do Matrix e do Doom Fire para TRS-80 (todos disponíveis aqui no blog).

Para o assembly, meu guia tem sido o didático TRS-80 Color Computer Assembly Language Programming, do Willian Barden Jr. Utilizei também outros materiais esparsos, de maior profundidade técnica, que me ajudaram a compreender como o SAM e o VDG interagem e, especificamente, como é feita a seleção dos modos gráficos em baixo nível. Se alguém for se aventurar, não se esqueça de que além de setar os registradores do modo gráfico escolhido, é preciso também definir o offset das páginas gráficas. De nada.

A diferença entre o assembly do 6809 para o do Z80 é substancial, tendo o 6809 mais recursos e flexibilidade. Para além do conjunto de instruções e sua sintaxe, levei um tempo para me acostumar com a notação que diferencia o endereçamento direto e indireto e com o prefixo obrigatório "$" para hexadecimal, que nunca utilizei com o Z80. Pode parecer bobagem, mas de início essa diferença de notação me dificultava bastante a leitura do que estava na tela. Meu cérebro, desde os 15 anos, estava acostumado com endereçamento indireto indicado de forma muito clara com parênteses, somado ao fato de que eu uso o sufixo "H", e não o prefixo "$", para notação de hexadecimais.

Mas enfim, o programinha simples serviu muito bem como iniciação. Logo faço algo um pouco mais complexo.

Download da imagem do disco: CCB-Demo.dsk

Para carregar: LOADM "CCBDEMO.BIN"

Para executar: EXEC

Para sair: segure a tecla BREAK 

terça-feira, 23 de maio de 2023

Relógio BCD para o TK85 no ZX Assembler da Artic

Um relógio BCD (binary-coded decimal) mostra os dígitos decimais em formato binário. Cada dígito decimal das horas, minutos e segundos está codificado em binário. Assim, cada coluna corresponde a um dígito do relógio (HH:MM:SS), mas em formato binário: quadrados preenchidos = 1, quadrados vazios = 0.

A leitura dos valores no caso do relógio que implementei se dá de baixo para cima. A primeira linha de bits tem valor 1, a segunda 2, a terceira 4 e a quarta 8. O valor resultante é a soma dos valores dos bits. Na figura abaixo, por exemplo, o bits da quinta coluna somam 5 e o da sexta coluna 9, indicando 59 segundos.

O relógio BCD com os valores de cada casa de bits e o horário: são 12h 46min e 59s.

Bom, foi isso que eu procurei implementar para a linha Sinclair ZX81. Já tinha feito um relógio BCD bem simples no BASIC do MSX numa manhã de domingo. Mas desta vez quis fazer algo na tela cheia, então fui de assembly para dar conta das limitações do TK85. Olha aí ele fornecendo as horas:



Para executar, digite RUN e entre com o horário. Confirme e pronto. Lá está o seu relógio BCD funcionado.

Durante o seu funcionamento, se você pressionar a tecla "D" (de decimal) as horas vão aparecer com dígitos normais no canto superior esquerdo da tecla. Tecle "D" novamente para que esse recurso desapareça. Pressionando a tecla "NEW LINE", o programa para e volta ao BASIC. É preciso de um pouco de paciência com esses comandos, já que a leitura do teclado só é feita na virada de cada segundo.

Segue o link para download do arquivo .p:

Download

Sobre o ZX Assembler da Artic

Para falar a verdade, a programação do relógio surgiu apenas como desculpa para  experimentar o ZX Assembler, da britânica Artic Computing Ltd. Queria ver como seria a programação em assembly utilizando uma ferramenta nativa. Eu procuro utilizar assemblers nativos em todas as máquinas que programo: GEN80 e Mega Assembler no MSX, Edtasm no TRS-80 e Edtasm+ para o TRS-Color. Mas no caso do ZX81, pensava que as limitações seriam torturantes demais e, por isso, estava utilizando o Pasmo para gerar o binário Z80 e o appmake (este do pacote z88dk) para gerar o arquivo ".p". Mais um pequeno bash script e o fluxo de trabalho fica simplesmente fantástico, gerando o arquivo .p no diretório do emulador e um arquivo texto (.lst) com a listagem dos endereços de montagem para referência, se necessário. E tudo no terminal, já que não uso ambiente gráfico para emulação no Raspberry Pi.

Mas sobre a impossibilidade prática de utilizar o micro real para programação assembly, eu estava enganado, pelo menos em parte. Para minha grata surpresa, depois de um "Hello World" no ZX Assembler, descobri que é sim possível trabalhar nativamente na máquina. Isto é, desde que não se utilize fita cassete como mídia (imagine carregar o ZX Assembler por 3:30 minutos, mais o  tempo de carregamento do programa fonte, toda vez que der um pau na execução do programa? Não dá). Então resolvi fazer algo para ver o quanto é viável utilizá-lo em projetos maiores. É verdade que, para isso, utilizei o emulador. Mas o fluxo de trabalho não seria muito diferente caso o usuário possua uma ZXpand ou um Blue Drive da vida. Eu aqui tenho um Blue Drive mas meu TK85, perfeitinho e original, não tem o mod de vídeo-composto que a ROM de 50Hz do Blue Drive exige, e a tela fica rolando no RF. Um dia eu resolvo essa história.

Obviamente, o ZX Assembler é bastante simples e limitado, mas ao mesmo tempo a forma que foi implementado é surpreendentemente inteligente. A primeira coisa que me chamou a atenção foi o editor: gostei muito por ser simples, limpo e direto. Diria é quase perfeito e que faltou apenas um par de comandos, page up e page down para navegar no texto mais rápido. Em lugar disso o programador pode lançar mão de uma busca por um rótulo para ir direto ao ponto do programa a ser editado. Mas no geral, excelente editor.

O montador em si é minimalista. Você dá o comando e se o montador não encontrar erros, não diz nada, apenas volta para o prompt. E como a montagem se dá na memória, é extremamente rápida. Se o programa encontrar um erro na montagem, sinaliza o tipo de erro e, se o usuário teclar "E" para voltar ao editor, a linha com erro já é mostrada. Simplicidade genial. 

A forma como o ZX Assembler contorna os problemas de design do ZX81 também é ótima. Pra quem não conhece, o código de máquina no ZX81 deve ficar guardado em uma linha REM, para poder ser salvo. Não há outra forma (simples) de salvar um programa em código de máquina. Assim, o ZX Assembler gera o código-objeto na linha 1 do BASIC, e o código-fonte assembly na linha 2. O programador pode então adicionar código em BASIC a partir da linha 3 em diante. Eventuais alterações nos códigos fonte e/ou objeto em assembly não afetam o conteúdo em BASIC já digitado, e vice-versa. E tudo pode ser salvo por um comando SAVE do BASIC. Ao finalizar, o código-fonte pode ser eliminado pela simples exclusão da linha 2, e lá vão estar a linha 1 REM com o código em linguagem de máquina e o código BASIC em seguida. Em compensação, por toda essa conveniência, não é possível montar o programa em endereço diferente de 16516.

Além do montador e do editor, há também algumas funções de monitor, como verificação e edição de endereços de memória, verificação e alteração de valores de registradores, cálculo de desvios relativos, etc; e a função de execução do programa com retorno ao monitor (o break-point é um JP específico que deve ser inserido manualmente no código-fonte).

Há ainda uma rotina utilitária de cópia de bloco de memória. Mas não há disassembler disponível no pacote. Sem problema. Seria exigir demais do programinha.

O montador é feito para ser minimista por boa razão:  a memória é um artigo de luxo para o ZX81. A configuração com expansão de memória mais comum, à época, era de 16kB. Assim, para deixar o maior espaço possível ao programador (códigos fonte e objeto + eventual código BASIC), o código do ZX Assembler deve ser o mais enxuto possível.

Isso reflete na falta de alguns recursos básicos que vemos em qualquer montador. Notadamente, o silêncio do montador ao gerar o código-objeto. Ele não lista o código-objeto com os respectivos endereços de montagem, não gera informações sobre o tamanho ocupado na memória nem sobre os endereços dos rótulos. Assim, o programador fica no escuro quanto a quantidade de memória utilizada e, principalmente, terá bastante dificuldade para calcular o endereço de uma eventual rotina no meio do código-objeto se quiser executá-la a partir do BASIC. O único endereço de execução fornecido é o do início do código-objeto, que consta no manual do ZX Assembler. Considero que o programa poderia pelo menos informar o endereço dos rótulos já que isso não demandaria grande espaço de memória.

Enfim, a conclusão é que o ZX Assembler pode ser usado tranquilamente para programas simples em lugar de ferramentas externas que estragam a experiência de imersão, ainda que seja por emulador. Mas como tudo está na memória (código-fonte, código-objeto, o assembler em si e mais, eventualmente, linhas em código BASIC), o espaço de memória fica bastante limitado.

Acrescento aqui informações que não constam do manual:

  • Os endereços 16514 e 16515 contêm o código 118 (76h), ou seja, NEW LINE. Provavelmente para evitar a listagem do código de máquina decodificado pelo comando LIST do BASIC, enchendo a tela com caracteres e comandos. É por isso que o programa em LM deve ser executado com RAND USR 16516;
  • O assembler reside acima da RAMTOP, setada em 25684. Em 30000 há um desvio (JP) para 30742, endereço efetivo do início de execução do programa. Mas o atalho RAND USR 3E4 (30000), fornecido no manual, é mais simples de lembrar e digitar;
  • Ao usuário fica disponível pouco menos de 9kB para código-objeto, código-fonte e linhas BASIC. O código-fonte é armazenado em modo texto, não há qualquer tipo de compressão ou pré-codificação dos mnemônicos.



segunda-feira, 5 de setembro de 2022

O Panfleto Pitfall! para Commodore64 no MSX

Inspirado por um colega do grupo MSX Brasil (Facebook), analisei com mais cuidado um vídeo postado no canal do Youtube "8-bit Show and Tell" sobre um panfleto publicado pela Actvision nos anos 80 contendo uma listagem de um programa para o Commodore 64. O programa é relativamente simples, mas como é assinado pelo próprio David Crane (autor de clássicos do Atari 2600 como Pitfall! e Decathlon), concordei com o colega que ele merecia uma versão para MSX.

 

Panfleto publicado pela Actvision em 1984

 

O programa do panfleto está em BASIC, mas tem uma certa quantidade de dados (linhas DATA) referentes à imagem do Harry na tela e também um pouco de código de máquina. Resulta na animação do personagem Pitfall Harry correndo olimpicamente pela tela, desparecendo no lado direito e reaparecendo no lado esquerdo. Ele para quando a tecla de espaço é pressionada.

A maior curiosidade talvez seja o fato de que mesmo que o programa BASIC seja parado ("break"), o personagem continua a correr pela tela. Isto porque existe uma rotina em linguagem de máquina ligada à interrupção do sistema.

 



Os sprites no MSX

Não foi muito difícil replicar o programa no MSX. Na realidade eu não desassemblei o programa original, apenas reproduzi seu comportamento no MSX. 

Entretanto, não sem algumas adaptações. O chip gráfico do Commodore 64 tem capacidade de produzir sprites multicoloridos, de até três cores, que é o caso daqueles usados no programa original. O MSX não tem essa capacidade, pois os sprites possuem apenas uma cor. A única maneira de contornar essa situação é sobrepondo sprites de cores variadas para obter o mesmo resultado.

Assim, os 6 sprites coloridos no Commodore 64 (5 representando a corrida e 1 do Harry parado) viraram 18 sprites no MSX. A tarefa de desenhá-los e de gerar os dados correspondentes foi bastante facilitada pelo aplicativo web chamado TinySprite, de autoria do Rafael Janone. Depois, no MSX, eu só tive o trabalho de converter os dados de hexadecimal para decimal e assim diminuir o tempo de carregamento dos dados.

Outro detalhe (que francamente não sei como funciona no Commodore 64) é que o Harry desaparece ao poucos do lado direito e reaparece, também aos poucos no lado esquerdo da tela. Ocorre que a resolução horizontal (eixo x) do MSX é de 256 pixels. No MSX-BASIC o efeito de um sprite aparecer gradualmente na margem esquerda da tela é obtido com valores negativos no eixo x do sprite, de modo que quando o valor 0 é atingido, o sprite já aparece por completo na margem esquerda. 

Entretanto, em linguagem de máquina o eixo x é representado por apenas um byte e, sendo assim, este pode assumir valores de 0 a 255, que são todos considerados como positivos pelo VDP. Para que o sprite inicie no eixo x antes do início da margem esquerda, é necessário setar o bit 7, chamado early clock, do quarto byte de atributos do sprite (que também contém sua cor). Isso irá localizar o sprite 32 pixels para dentro da margem esquerda. Não é o fim do mundo, mas esse procedimento demanda que o programador preveja manualmente quando o early clock deve ser setado ou zerado e, ainda, que se faça o devido ajuste no valor do eixo x no programa assembly.

A rotina de interrupção

Atrelei o programinha em assembly ao gancho do sistema (H.TIMI). Isso faz com que a animação do Harry seja atualizada 60 vezes por segundo no caso das máquinas PAL-M e NTSC (60Hz de frequência vertical) e 50 vezes por segundo no caso das máquinas PAL-G/PAL-N (50Hz). Como resultado, assim como no programa original, o personagem continua correndo pela tela mesmo com a interrupção do programa BASIC pelo usuário com um Control+Stop (break). 

Entretanto, uma diferença é que no caso do Commodore 64 o sprite pode ser programado para aparecer debaixo das letras que estão na tela. Já no MSX isso simplesmente não é possível, uma vez os planos dos sprites sempre sobrepõem o plano no qual os caracteres são impressos por definição do hardware (VDP). O Harry no MSX só pode correr por sobre o texto, nunca sob ele.

O que mais não ficou igual

Uma das coisas que mais me chamou atenção no vídeo do "8-bit Show and Tell" foi que o programa BASIC era interrompido e então o comando LIST era executado e o Harry continuava a correr sob a listagem do programa.

Infelizmente, não consegui fazer que esse efeito funcionasse a contento no MSX. No meu programa, tudo está bem quando comandos simples são executados, como um PRINT ou algo assim. Entretanto, se diversos comandos PRINT ou mesmo um único LIST é executado de modo que ocorra um scroll da tela, a memória de vídeo (VRAM) é afetada e coisas estranhas aparecem na tela. Os comandos CLS e SCREEN também não funcionam como deveriam, esculhambando a tela com lixo da VRAM.

Quebrei bastante a cabeça tentando evitar a corrupção da memória de vídeo na execução desses comandos enquanto o Harry corria pela tela e cheguei a conclusão que não há forma simples de evitar que as rotinas do BIOS utilizadas pelos comandos do MSX-BASIC conflitem com o programinha do Pitfall. É que essas rotinas acessam os registros do VDP de forma mais intensa e acabam colidindo como acesso do programa do Pitfall ao VDP e à VRAM (60 vezes por segundo) gerando lixo na memória de vídeo. 

Pela mesma razão, alterar as cores dos sprites do Harry enquanto ele está em movimento também acarretam a corrupção da memória de vídeo, estragando um pouco a brincadeira (update 20.09.22: modifiquei a rotina em linguagem de máquina e agora é muito raro que haja corrupção na memória de vídeo utilizando os pokes para alteração das cores do Harry).

Assim, eu me dei por satisfeito e deixei o programa como está (e no fim ponho a culpa no hardware... rs).

Para quem quiser tentar, as cores da roupa podem ser trocadas para azul, por exemplo, com POKE &HE0C9,4. É esse último valor "4" que contém o código da cor, que pode ser de 0 a 15. 

A cor do cabelo/cinto/sapatos e a cor da pele do Harry também podem ser mudados alterando-se o valor dos endereços &HE0C1 e &HE0C5 respectivamente, usando o mesmo critério descrito acima. Por exemplo, POKE &HE0C5,6:POKE &HEC1,10 deixa o Harry com pele "morena" e cabelos louros. 

O programa

Enquanto o programa BASIC estiver sendo executado, a tecla ESPAÇO (na realidade, qualquer tecla) faz com que o Harry pare por um instante. Esta é a única interação que o usuário pode ter com o personagem. Isto está no programa original, mas provavelmente minha implementação de como isso é feito é diferente (eu utilizei uma flag para que o BASIC indique ao programa assembly que uma tecla foi pressionada).

Após interromper o programa BASIC com Control+Stop, o Harry continua correndo até que o usuário comande GOTO 180, que irá desligar a rotina de interrupção, colocando um C9 (opcode RET) no início do gancho do sistema H.TIMI. O correto mesmo seria que a rotina original do gancho do sistema fosse salva e depois recuperada. Mas como isso não funcionaria se o programa fosse iniciado novamente com RUN (porque o gacho já alterado seria salvo), optei por uma solução menos elaborada (displicente, talvez, mas funcional).

Como explicado anteriormente, os endereços &HE0C1, &hE0C5 e &HE0C9 podem ser alterados com o comando POKE para mudar as cores do Harry.

Disponibilizo no link abaixo a imagem de disco contendo o programa BASIC para MSX, com comentários delimitando os blocos e, ainda, a rotina assembly responsável pela animação do Harry, no formato do MegaAssembler em que foi criado. Este está sem comentários, pelo que peço desculpas. Incluí ainda, no pacote zip, a listagem do programa assembly em formato texto.

Download (update 20.09.22)


domingo, 31 de outubro de 2021

Doom Fire para MSX, ZX81 e TRS-80

Após descobrir o tal "algoritmo do fogo do Doom", cuja existência até então ignorava por completo, resolvi brincar com ele. Desta vez, fiz logo três versões de uma vez. 

Primeiro para o ZX81, onde desenvolvi o mecanismo e fui otimizando o código. Depois disso, portar para o TRS-80 foi bem tranquilo. Na verdade colocar coisas na tela do TRS-80 é mais simples do que no ZX81, então foi só um pequeno trabalho de descomplicação. 

Já no MSX, tive que aprender como funciona a tela no modo 3 (multicolor), que nunca havia lidado a não ser no BASIC. A cada frame os dados são processados em três etapas. A primeira atualiza os valores dos 1536 bytes correspondentes, cada um, a uma célula do fogo. Como a Screen 3 não é um modo bitmap, os dados são organizados, na segunda etapa, para que fiquem dispostos num buffer da maneira que exige o processador gráfico. Só então os dados são impressos na tela, numa terceira etapa.

A versão do ZX81 desenvolvi na tabelinha nano/Pasmo, testando no emulador sz81. A do TRS-80, fiz no EDTASM, rodando no emulador SLDTRS. E a do MSX fiz no Mega Assembler, rodando no openMSX. 

Download: Doom Fire - MSX/ZX81/TRS-80

Versão MSX (a versão final tem a animação um pouco mais fluída do que a que aparece no vídeo):


Versão TRS-80:


Versão ZX81:








sábado, 30 de outubro de 2021

Matrix - Raining Code para TRS-80



Portar o código em si do ZX-81 para o TRS-80 foi bem simples. O que me deu um pouco mais de trabalho foi entrar no mundo do TRS-80. Como só uso ferramentas externas em último caso (em único caso, na verdade, do ZX-81, que uso cross-assembler), aprendi basicamente como funciona o emulador SDLTRS, o sistema operacional do TRS-80 e o assembler EDTASM. Levei um tempinho pra me acostumar com todas essas novidades, mas valeu a pena. Afinal eu me meto nessas velharias mesmo pra ter o prazer de aprender e lidar com elas.  E faz tempo que eu queria mexer com o TRS-80, porque o CP-500 foi um dos primeiros computadores que vi funcionar. E que impressão aquele monstrinho branco dava!

Bom, segue o download de uma imagem de disquete contendo o programa.

Download: Matrix - Raining Code - TRS-80




quinta-feira, 23 de julho de 2020

Matrix - Raining Code para o ZX81

Portei  para o ZX81(linha que no Brasil foi representada pelo TK-85, CP-200, etc) o programa que havia escrito para o MSX. Uma boa parte teve que ser reescrita, principalmente porque na versão para MSX eu utilizei o modo gráfico ("screen 2"). O algoritmo de animação, de um modo geral, é o mesmo, respeitadas as limitações da maquininha.

Para inciar o programa, digite RUN. Para interromper a execução, tecle NEW LINE.

Atualização em 20.07.2024: fiz uma versão para máquinas capazes de gerar vídeo reverso (fundo preto com caracteres em branco). Assim, no pacote ZIP há duas versões, a normal (matrix.p) e a para vídeo reverso (matrix-r.p). Eu aproveitei para fazer alguns ajustes, em especial, agora o programa irá rodar aproximadamente na mesma velocidade em computadores NTSC/PAL-M ou PAL europeu (60/50Hz de sincronismo vertical).

Download: Matrix-ZX81.zip





Matrix - Raining Code para o TRS-Color

Tempos atrás, depois de fazer o Raining Code para o MSX, portei para o ZX81 e para o TRS-80, o que ocorreu com certa facilidade, porque tod...