Programando em C para o Atari ST

atari-st-c-1_abertura

Esta é a ducentésima quinquagésima sexta publicação deste blog e sabe o que isto significa? Significa que são necessários 16-bits para expressar o número de publicações deste blog, ou seja, não lá muita coisa… 😀

E para “comemorar” a publicação de número 0x100 resolvi juntar duas coisas:

  1. Escrever algo sobre um hardware de 16-bit (o que é legal) e
  2. Aproveitar para praticar um pouco de C, a  linguagem que resolvi aprender um pouco mais este ano.

O que é um Atari ST?

Para os que não conhecem, o Atari ST é um computador de 16-bit desenvolvido e comercializado pela Atari Corporation e que cujo o primeiro modelo foi o 520ST com 512KiB de RAM e lançado no ano de 1985 ao custo de USD$ 799,95.

Era baseado no processador Motorola 68000 rodando a 8MHz, com resoluções gráficas de 320×200 (16 cores¹), 640×200 (4 cores) e 640×400 (monocromático); o YM2149F da Yamaha para geração de som (sim, o mesmo PSG do MSX); até 2 unidades de disquetes de 3½” SD ou DD, interface ACSI para discos rígidos e conector para cartuchos. E também portas serial (MODEM), MIDI (teclados e sintetizadores), paralela (impressora) e conectores para joystick e mouse.

O sistema operacional, o TOS, embutido em ROM, foi baseado no CP/M da Digital Research e também incluía uma interface gráfica, a GEMGraphics Environment Manager.

Foram bastante populares na Europa, principalmente na Alemanha Ocidental, onde eram utilizados em pequenas empresas, por conta das portas MIDI acabaram populares entre os músicos e, claro, graças ao baixo custo e bons recursos de áudio e vídeo, uma máquina para jogos — junto com o Amiga o ST ele é a plataforma original do Another World.

E para terminar, o 1040ST, lançado em 1986, ao preço de USD$ 999,00 foi o primeiro computador doméstico com 1 MiB de RAM a ser vendido por menos de USD$ 1.000,00.

(¹) Paleta de cores de 9-bit (8×8×8 = 512 cores), igual ao dos MSX2 mas, infelizmente, sem um modo de 256 cores.

(²) Apesar do que falam por aí TOS é apenas o acrônimo de The Operating System.

Escolhendo o compilador C

(versão para lá de reduzida) Há diversos compiladores C disponíveis para a plataforma, dei uma olhada em alguns dos compiladores antigos, experimentei um pouco o AHCC³, mas no final acabei optando pela compilação cruzada mesmo utilizando o “bom e velho” GCC.

(³) O ANSI Home Cooked C, um compilador padrão ANSI C89  escrito por Henk Robbers e que inclui compilador, assembler e até mesmo um editor de programas; o AHCC é compilado a partir do próprio AHCC!

Instalando o GCC

Na verdade a minha objeção inicial em usar o GCC estava no fato de que não existe um tool chain para o TOS e sim para o MiNT (calma, já explico!) e versões antigas do GCC até suportam a geração de binários para o TOS mas eu não queria ficar limitado às versões 1.x ou 2.x do compilador. Mas então descobri que a parte em C do EmuTOS (já explico também) é compilada utilizando o GCC e usando esta mesma tool chain.

Assim criei um Vagrantfile para configurar uma máquina virtual para instalar a tool chain para compilação cruzada para o MiNT usando GCC 4.x que é mantida pelo Vincent Rivière e que está disponível para Linux, macOS X e Windows. E coloquei o que é necessário em um repositório no GitHub, daí é cloná-lo, usar “vagrant up” e aguardar o processo de configuração finalizar para começar a brincar. 🙂

Duas rápidas explicações agora:

  • MiNT³ já foi acrônimo para MiNT is Not TOS mas hoje significa MiNT is Now TOS, é uma alternativa em software livre ao TOS com suporte a multitarefa, camada de compatibilidade para chamadas UNIX e outras melhorias. É um projeto que iniciou em 1988, que chegou a ser usado pela própria Atari quando precisou adicionar multitarefa ao sistema operacional do Atari TT (MultiTOS) mas que hoje é um projeto independente, o FreeMiNT.
  • EmuTOS é uma reimplementação do firmware original do ST em software livre construído a partir do código fonte original da Digital Research — que foram liberados sob a GPL em abril de 1999 — e que funciona como um substituto ao TOS proprietário. E ele é escrito usando o GCC e doses generosas de assembly de 68000.

(³) Claro, MiNT não tem relação alguma com a distribuição Linux Mint!

Testando o compilador

Claro, que haveria um “hello world!” para testar se o compilador, senão isto aqui não teria graça…

...
int main(int argc, char* argv[]){
    puts("Hello, world !");
    return 0;
}

Aliás, o arquivo faz parte do pacote, é o “hello.c”, não precisa digitar.

Compilando o programa

E para compilar:

$ vagrant ssh
$ cd /vagrant/src
$ m68k-atari-mint-gcc hello.c -o hello.tos

Só verificando que tudo deu certo…

$ file hello.tos
hello.tos: Atari ST M68K contiguous executable (txt=114136, dat=1544,
bss=4260, sym=12992)

E agora é só testar!

Testando o programa

atari-st-c-1_hello-world

Existem duas opções para testar o programa, pode-se testar diretamente em um Atari ST, ou seja, copiando (ou transferindo) o programa para lá ou usando um emulador para a tarefa. Estou usando o Hatari para tal  e durante a inicialização da máquina virtual o Vagrant aproveitou para baixar a última versão do EmuTOS (mas você precisará instalar o emulador) então basta sair da máquina virtual do Vagrant e usar:

$ hatari -c hatari.conf

Dentro do “hatari.conf” está uma configuração básica para emular um 1040ST padrão, utilizando o EmuTOS e emulando um disco rígido a partir do diretório “./src”.

Quando o boot finalizar, você pode ir em “File” → “Execute EmuCON” ou simplesmente pressionar «Ctrl»+«Z» para abrir o EmuCON2. o console de comandos do EmuTOS, e digitar:

C:\> HELLO
Hello world !

Parabéns, está tudo funcionando como esperado, para sair do console use “EXIT”.

Algo mais sofisticado

Que tal algo além do simples programa de teste? Daí escrevi o “dumpfile.c” que lista na tela um arquivo passado como parâmetro e o exibe na tela com listagens em hexadecimal como também em ASCII.

$ vagrant ssh
$ cd /vagrant/src
$ m68k-atari-mint-gcc dumpfile.c -o dumpfile.tos

Levar para o emulador, se a barra de espaços não funcionar tente «Shift»+«Espaço», e:

atari-st-c-1_tos_dumpfile

A parte interessante é que, como não estou usando nada além da biblioteca padrão e estou usando uma versão relativamente nova do GCC, o mesmo programa escrito para rodar em uma arquitetura de 16-bit, pode se compilado e executado sem modificações em uma de 64-bit:

atari-st-c-1_linux_dumpfile

E obtendo o mesmo resultado (só que bem mais rápido).

Considerações finais

atari-st-c-1_tos_dumpfile_real

Claro que testaria o programa no hardware real, no caso em um 1040STFM (mesma coisa que o 1040ST mas como o drive de disquetes embutido).

A principal vantagem em usar o GCC é que algumas rotinas (ou partes delas) podem até mesmo ser testadas sem precisar recorrer ao emulador ou a máquina real. Quanto ao “problema” de trabalhar com uma tool chain de MiNT e não de TOS, resolvi estudar o código fonte do EmuTOS para entender como eles se resolveram. A ideia é pegar emprestado os headers que eles usam (e no meio do caminho aprender como ele acessa o hardware).

E fica a promessa de escrever um pouco sobre a arquitetura interna do TOS, comporta por BIOS, XBIOS, GEMDOS, AEI, LINE-A, VDI etc…

Até!