14 dias programando em BASIC

Gabriel Ullmann
8 min readSep 2, 2024

--

Eu (esq.) e Dr. Yann-Gaël Guéhéneuc (dir.) acompanhando um participante durante um dos workshops de AMOS BASIC que conduzimos durante o ReAnimate 2024.

Quando penso em linguagens de programação modernas, várias características me vem a mente, tais como:

  • Orientação a objetos
  • Paradigma funcional (funções lambda, map, reduce, filter)
  • Gerenciamento de exceções (try/catch)
  • Vasta gama de bibliotecas (especialmente em JS e Python)
  • Existem no mercado várias boas IDEs e ferramentas para trabalhar com a linguagem

Mas nem sempre foi assim. Nos anos 60, a linguagem BASIC não tinha nenhuma dessas características, e ainda assim foi revolucionária. Criada por John Kemeny e Thomas Kurtz em 1963, a ideia era furar a “bolha” da programação, que era restrita a matemáticos e cientistas da época, e introduzí-la a estudantes de maneira simples. É daí que vem a sigla BASIC — Beginners’ All-purpose Symbolic Instruction Code (Código de Instruções Simbólicas de Propósito Geral para Iniciantes, em inglês).

Em comparação com outras linguagens como Assembly ou Fortran, a linguagem BASIC era mais alto-nível, de mais fácil leitura e compreensão e tinha um compilador pequeno o suficiente para caber na memória dos primeiros computadores pessoais. Dessa forma, a linguagem virou uma febre e deu origem a várias derivações. Empresas importantes da época como Sinclair, Atari e Commodore criaram suas próprias versões do BASIC. Microsoft e Apple, que nos anos 70 davam seus primeiros passos rumo ao sucesso mundial, também entraram na onda.

A popularidade da linguagem seguiu até a década de 80, quando a Commodore lançou o Amiga e também sua própria versão do BASIC para este computador, o AMOS BASIC. Como comentei em meus últimos posts, tive o privilégio de utilisar um computador Amiga 1000 e vários outros retrocomputadores durante o ReAnimate, uma summer school de retrocomputing da qual participei em Montreal, no Canadá. Foi este evento que me motivou a aprender BASIC, e também a escrever este post.

Uma de minhas missões durante o evento foi ministrar um workshop de programação em AMOS BASIC, e, portanto, tive que aprender a linguagem. Neste post, quero compartilhar um pouco com vocês como foi a experiência de aprender em 2024 uma linguagem que foi criada há mais de meio século. Como programador formado na segunda década do século XXI, penso que há um gap imenso não apenas na tecnologia, mas também na filosofia de programação quando comparamos os anos 60 com a atualidade. Vamos aos aspectos que mais me surpreenderam:

Ambiente de desenvolvimento

Código em BASIC para tocar “parabéns para você” que escrevi na IDE AMOS Pro.

Minha experiência com AMOS BASIC foi toda em máquina virtual, visto que não possuo um computador Amiga. Através do emulador Amiga Forever, rodei uma imagem de Amiga 4000 que inclui uma IDE chamada AMOS Pro, criada em 1993 por François Lionet.

O AMOS Pro é bastante simples de utilizar, mas tem algumas coisas que não são totalmente intuitivas para um dev moderno, a começar pelos atalhos de teclado. Em vez de utilizar a consagrada combinação CTRL + C, CTRL + V para copiar e colar, os comandos são CTRL + L (de Load, para copiar) e CTRL + P (de Paste, para colar). Antes de copiar, porém, lembre-se de pressionar CTRL + B para entrar em block mode (modo de seleção de texto em blocos) e então utilizar o mouse ou as flechas do teclado para selecionar o texto que você deseja copiar.

É preciso ficar atento também ao text buffer, que é a quantidade de RAM alocada pelo AMOS Pro para armazenar seu código durante sua execução. Em uma época na qual a memória RAM era artigo de luxo, o ambiente desenvolvimento alocava apenas a quantidade necessária de memória para abrir o arquivo, e nem um byte a mais. Caso o programador desejasse escrever mais código e salvá-lo, era preciso antes aumentar o text buffer.

Modularização e Funções

Em AMOS BASIC não há classes, namespaces ou pacotes. Também não é possível importar código de outros arquivos. Isso significa que uma aplicação BASIC é inevitavelmente monolítica e requer muito scrolling para cima e para baixo para navegar pelo código. Uma das poucas formas de modulizar o código é dividindo-o em subrotinas (também conhecidas como subs) ou procedures.

Tanto subs quanto procedures funcionam de forma similar a uma função, pois se localizam em um bloco bem definido dentro do código e possuem um nome através da qual podem ser “chamadas” pelo programador através do comando GOSUB. As procedures, contudo, tem uma funcionalidade a mais: receber parâmetros. Além disso, seu escopo de variáveis é isolado do resto do código. Em uma procedure, por exemplo, todas as variáveis globais declaradas fora da terão valor zero por padrão.

Embora um pouco mais poderosas do que as subs, as procedures são uma inovação do ambiente AMOS Pro e não existem em versões mais antigas do BASIC, como o ST BASIC, desenvolvido para o STOS da Atari. A própria documentação do AMOS Pro de 1993 recomenda o uso de procedures e menciona que o GOSUB está disponível apenas como suporte legado:

O comando GOSUB é outro comando antiquado, utilizado para realizar um salto para uma subrotina. Na verdade, o sistema de procedures do AMOS Professional torna o GOSUB redundante, embora ele possa ser útil para usuários de STOS que desejem converter seus programas.

No início de meu aprendizado em BASIC, achei mais simples utilizar as subs. Contudo, a medida que me familiarizei com a linguagem, passei a gostar mais das procedures por seu comportamento semelhante às funções que temos em linguagens modernas. Além disso, por possuírem um escopo estilo “closure”, as procedures dão mais segurança ao programador, impedindo referências ou alterações acidentais a variáveis globais.

Tratamento de exceções

O AMOS BASIC possui um comando chamado On Error, que é basicamente um precursor do Try/Catch. Através dele, você pode fazer a execução “saltar” para outro bloco de código caso algum erro ocorra dentro do bloco delimitado. No exemplo abaixo, que extraí da documentação do AMOS BASIC, qualquer erro dentro do bloco AGAIN fará o código dentro do bloco HELP ser executado. Dessa forma, podemos printar uma mensagem para explicar o erro em mais detalhes.

On Error Goto HELP
AGAIN:
Do
Input "Type in two numbers";A,B
Print A;" divided by ";B;" is ";A/B
Loop
Rem Error Handler
HELP:
Print
Print "Sorry, you have tried to divide"
Print "your number by zero."
Resume AGAIN : Rem Go back to input

Mostrar mensagens de erro em tempo de execução pode não parecer algo super importante para quem está acostumado a programar em linguagens modernas, mas é preciso lembrar que no tempo do BASIC as mensagens providas pelo compilador e o texto da documentação da linguagem eram muitas vezes incompletos ou um ambíguos, e não havia Google ou ChatGPT para tira-teima. Portanto, encontrar um comentário ou mensagem de erro deixada pelo criador original do código podia salvar horas de debugging de um programador que estivesse tentando entender aquele trecho.

Por exemplo, lembro que passei umas boas horas tentando entender por que o comando Bar estava parando subitamente a execução do meu código. O compilador retornava simplesmente uma mensagem de “ERROR” que me deixou completamente frustrado. Ao buscar mais detalhes sobre o comando Bar na documentação, cheguei a conclusão de que eu o estava utilizando corretamente. O comando recebe 2 parâmetros, um ponto de início e outro de final para desenhar um retângulo:

BAR
instrução: desenhar um retângulo preenchido
Bar x1,y1 To x2,y2

Este comando é utilizado para desenhar barras sólidas de cor única através do método familiar de definição de coordenadas gráficas do alto-esquerda [top left] e baixo-direita [bottom right].

O que eu não sabia é que a função simplesmente lança um erro quanto distância entre os pontos é igual a zero (por exemplo: Bar 1,1 To 1,1). Não há qualquer referência a isso na documentação, nem na mensagem provida pelo compilador, e acabei descobrindo o problema só após muita tentativa e erro. Para tornar as coisas ainda um pouco mais complicadas, o comando Bar estava dentro de um laço de repetição, e portanto o fato de as variáveis correspondentes aos pontos de início e final serem iguais não foi imediatamente evidente.

Limitações de hardware

Meu piano de 11 teclas para o ReAnimate 2024.

Para meu workshop durante o ReAnimate, minha intenção foi criar algo em AMOS BASIC que fosse interativo, divertido e que englobasse um pouco de tudo que o Amiga é capaz de fazer: exibir gráficos, reproduzir som e capturar inputs do usuário. Sendo assim, a primeira ideia que me veio à mente foi criar um pequeno jogo de plataforma no estilo Super Mario Bros ou Rick Dangerous, que fizeram muito sucesso na década de 80.

Porém, devido ao pouco tempo que consegui alocar para minha preparação — 14 dias, como menciono no título deste post — decidi pivotar para um projeto que julguei mais simples: um piano que o usuário pudesse tocar utilizando as teclas do computador. Após dois finais de semana de explorações, tentativas e erros, consegui criar um piano básico com 11 teclas no qual consegui tocar as primeiras notas de Für Elise de Beethoven. O código original está no GitHub, acompanhado de uma versão melhorada graças a contribuição do Dr. Yann-Gaël Guéhéneuc.

Embora tocar os sons e capturar os eventos de teclado não tenha sido muito difícil, o maior desafio ficou na parte visual, que embora simples exigiu um pouco de planejamento para que o código não ficasse muito longo ou confuso. Para desenhar as teclas, utilizei o comando Bar em um algoritmo que desenha primeiramente as teclas brancas, deixando espaços entre elas no quais, em seguida, as teclas pretas são desenhadas. A posição X das teclas é incrementada a cada iteração do loop. Toda essa lógica foi encapsulada na subrotina DRAW.

Em minha primeira versão do piano, utilizei busy waiting para verificar se alguma tecla estava sendo pressionada e, caso positivo, reproduzir o som e redesenhar o teclado de modo a destacar a tecla pressionada em verde. Porém, como a subrotina DRAW era chamada a cada iteração do loop, isso significa que o piano inteiro era continuamente redesenhado, independentemente de haver interação do usuário ou não. Isso acabava sobrecarregando um pouco o hardware de vídeo do Amiga, que não dava conta de atualizar a imagem com tanta frequência. Consequentemente, as teclas piscavam na tela (flickering) ou ficavam com “quebras” horizontais (tearing) — que são, inclusive, bem visíveis no screenshot acima.

Na versão de Yann, entretanto, esse problema é resolvido utilizando a função Wait Key, que literalmente espera por uma tecla ser pressionada e só então desenha na tela. Essa abordagem diminui o número de chamadas de atualizações de tela, e, portanto, elimina totalmente o flickering e tearing.

Considerações finais

Aceitei de braços abertos o desafio de criar uma pequena aplicação em AMOS BASIC para o ReAnimate 2024. Aprendi muito durante este processo, mas confesso que tenho muito a aprender. Sendo assim, minha inteção com este post não é explicar a linguagem AMOS BASIC e o ambiente de desenvolvimento do Amiga em detalhes, mas apenas compartilhar com vocês algumas das complexidades, curiosidades e belezas do mundo do retrocomputing. Ano que vem voltaremos com o ReAnimate 2025, e possivelmente novos projetos em AMOS BASIC. Até lá!

--

--

Gabriel Ullmann

Pesquisador de Engenharia de Software, sempre garimpando por coisas interessantes no código de video games e apps em geral. Atualmente em Montreal, Canada.