segunda-feira, 14 de outubro de 2024

Webex com LXC

O Webex parou de funcionar no Ubuntu 22.04 quando eu atualizei o kernel e continuou dando problema quando fiz o upgrade para 24.04.

Ele inicia e até chega a rodar por uns minutos, mas acaba por encerrar sem dar nenhuma explicação. A comunicação não é mesmo o forte dele, porque ele não funciona no root, mas não indica nenhum motivo.

Sem muita esperança, resolvi experimentar rodar dentro de um contêiner LXC.

Vamos ao básico: instalar o LXD.


sudo snap install lxd
sudp lxd init

O init vai fazer um monte de perguntas. As respostas default servem.

Como vai ser preciso usar o X11 do hospedeiro, é preciso criar um profile. Primeiro, cria-se um arquivo gui.txt com essas configurações:


config:
  environment.DISPLAY: :0
  environment.PULSE_SERVER: unix:/home/ubuntu/pulse-native
  nvidia.driver.capabilities: all
  nvidia.runtime: "true"
  user.user-data: |
    #cloud-config
    runcmd: 
      - 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
    packages:
      - x11-apps
      - mesa-utils
      - pulseaudio
    write_files:
      - owner: root:root
        permissions: '0644'
        append: true
        content: |
          PULSE_SERVER=unix:/home/ubuntu/pulse-native
        path: /etc/environment
description: GUI LXD profile
devices:
  PASocket1:
    bind: container
    connect: unix:/run/user/1000/pulse/native
    listen: unix:/home/ubuntu/pulse-native
    security.gid: "1000"
    security.uid: "1000"
    uid: "1000"
    gid: "1000"
    mode: "0777"
    type: proxy
  X0:
    bind: container
    connect: unix:@/tmp/.X11-unix/X1
    listen: unix:@/tmp/.X11-unix/X0
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
  mygpu:
    type: gpu
name: x11
used_by: []

Com isso, podemos criar um profile e, finalmente, um contêiner (como root):


lxc profile create gui
cat gui.txt | lxc profile edit gui
lxc launch --profile default --profile gui ubuntu:22.04 jammy

Jammy vai ser o nome do nosso contêiner. Pode ser que o launch falhe inicialmente, mas o start o coloca de pé novamente:


lxc start jammy

Agora temos que criar um user, copiar o Webex.deb para dentro do contêiner, instalar e, finalmente, rodar:


xhost +
sudo lxc file push Webex.deb jammy/
sudo lxc exec jammy bash
# dentro do contêiner
cd /
apt install /Webex.deb
adduser armando
su armando
# como armando
export DISPLAY=:0
/opt/Webex/bin/CiscoCollabHost %U

Como o usuário armando foi criado depois, precisamos pegar o seu id e editar algumas linhas no profile para que o áudio funcione. Como é o primeiro usuário criado, ele ficou com o id 1001.


name: gui
description: GUI LXD profile
config:
  environment.DISPLAY: :0
  environment.PULSE_SERVER: unix:/home/armando/pulse-native
  nvidia.driver.capabilities: all
  nvidia.runtime: "true"
  user.user-data: |
    #cloud-config
    runcmd:
      - 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
    packages:
      - x11-apps
      - mesa-utils
      - pulseaudio
    write_files:
      - owner: root:root
        permissions: '0644'
        append: true
        content: |
          PULSE_SERVER=unix:/home/armando/pulse-native
        path: /etc/environment
devices:
  PASocket1:
    bind: container
    connect: unix:/run/user/1000/pulse/native
    gid: "1001"
    listen: unix:/home/armando/pulse-native
    mode: "0777"
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
    uid: "1001"
  X0:
    bind: container
    connect: unix:@/tmp/.X11-unix/X1
    listen: unix:@/tmp/.X11-unix/X0
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
  mygpu:
    type: gpu
used_by:
- /1.0/instances/jammy


Após editar o profile, é preciso parar e iniciar novamente o contêiner.


sudo lxc profile edit gui
sudo lxc stop jammy
sudo lxc start jammy

E com isso pode-se quebrar um galho enquanto a Cisco não atualiza o software.

segunda-feira, 7 de outubro de 2024

Migração de uma Instância de Oracle Apex

O Apex é uma ferramenta low-code muito interessante e conveniente. Infelizmente, é oferecida pela Oracle.

Como tudo é que é produzido pela empresa, ela oferece muitas facilidades para os programadores, mas é deficiente na administração.

Por algum motivo misterioso, ou talvez simplesmente fruto da complexidade desnecessária que a Oracle julga interessante aplicar a tudo, não é possível usar o Data Pump para exportar e importar os schemas do Apex.

O zip de instalação oferece um par de classes para exportar partes do Apex: oracle.apex.APEXExport.class e oracle.apex.APEXExportSplitter.class

Ele oferece várias opções, mas não uma maneira de exportar tudo de uma vez e, o mais curioso, não oferece uma maneira de exportar as configurações da instância. É preciso exportar primeiro os workspaces e então as aplicações:


java -cp .:ojdbc8.jar oracle.apex.APEXExport  \
  -db mydb.mycompany.com:1521/apex.mydb.mycompany.com \
  -user system \
  -password hard2crack \
  -expWorkspace

java -cp .:ojdbc8.jar oracle.apex.APEXExport  \
  -db mydb.mycompany.com:1521/apex.mydb.mycompany.com \
  -user system \
  -password hard2crack \
  -instance
  

Isso vai gerar um arquivo w123.sql para cada workspace e um arquivo f123.sql para cada aplicação.

Enquanto isso, recomendo guardar cópias das páginas de configuração da instância.

Então, no servidor destino, é preciso rodar uns comandos.

Em primeiro lugar, se já existe uma instância do Apex, é preciso remover todos os workspaces antes de carregar os novos:


begin
  -- Verifique os ids das aplicações a serem exportadas
  for w in (select * from  apex_workspaces where workspace_id>1000) loop
    APEX_INSTANCE_ADMIN.REMOVE_WORKSPACE(p_workspace=>w.workspace);  
  end loop;
end;

Depois, pode-se carregar os workspaces e as aplicações:


. ./mynewdb.env

ls -1a  w*sql | xargs -I{} sqlplus / as sysdba @{}
ls -1a  f*sql | xargs -I{} sqlplus / as sysdba @{}

Conforme o tamanho de sua instância, isso pode demorar.

Como nem as menores coisas da Oracle estão livre de bugs, problemas, e poréns, a configuração de autenticações com Web Credentials, não funciona e o campo client-id não foi copiado.


update wwv_credentials
set client_id='my-id'
where client_id is null

Como prêmio final, os nomes das aplicações saíram com erro de codificação e precisaram ser corrigidos manualmente.

quinta-feira, 6 de junho de 2024

Cisco Secure Client sobre ARM com QEMU

Eu vinha trabalhando remotamente de maneira ecologica quando a firma decidiu implementar 2FA com o Cisco Secure Client e o Duo.

Minha opção ecológica era usar pequenos SBCs ARM, que utilizam quantidades irrisórias de energia. Dá para deixá-las ligadas o ano todo com R$10.

Infelizmente a Cisco não compartilha do meu entusiasmo com o ARM e não oferece binários compatíveis.

Como o Linux é um Sistema Operacional de verdade, eu tinha certeza que com um pouco de teimosia encontraria uma solução prática.

A solução veio na forma do QEMU.

É preciso instalar o qemu-user-static, o suporte multi-plataformas (binfmt), e algumas bibliotecas que o Secure Client necessita.


  # Como root ou com sudo

  # QEMU e binfmt
  apt install binfmt-support qemu-user-static
  update-binfmts --display
  dpkg --add-architecture amd64
  
  # libs necessárias para o Secure Client
  apt install libc6:amd64
  apt install libgtk-3-0:amd64
  apt install libxml2:amd64
  apt install libwebkit2gtk-4.0-37:amd64
  
  # instalar o secure-client
  ./cisco-secure-client-linux64-5.0.05040-core-vpn-webdeploy-k9.sh
  

E agora posso trabalhar gastando ínfimo 1,1W de CPU.

Espero que, com a chegada dos laptops com Snapdragon X Elite, a Cisco ofereça os binários para Linux/ARM.

sexta-feira, 19 de abril de 2024

Dias Perfeitos

O novo filme de Wim Wenders me agradou por alguns motivos distintos.

Em primeiro lugar, as cidades japonesas me atraem por toda a infraestrutura que oferecem. Tenho a impressão de que deve ser possível morar dentro de uma loja de conveniência japonesa (recomendo o livro Uma Questão de Conveniência de Sayaka Murata). Algumas pessoas são atraídas pelas tradições japonesas, eu curto mais são as modernidades.

Em segundo lugar, os banheiros. Eles foram projetados por grandes arquitetos e demonstram que a infraestrutura das cidades também pode ser interessante. E que, sendo interessante, a cidade fica mais rica.

Em último lugar, a ideia do filme.

Algumas empresas japonesas fabricam produtos que considero melhores por serem mais conservadores. Em especial, os carros da Toyota e as impressoras Brother têm menos novidades supérfluas e são bastante confiáveis. A confiabilidade é o que me interessa.

O consumismo ocidental é confundido com materialismo, mas a busca por novidades e marcas não é materialismo. Certos objetos eu desejo pela função apenas; a marca, a cor, ou os acessórios não são importantes.

Os carros Kei nunca seriam aceitos no Brasil (eu adoraria ter um para andar na cidade). As pessoas buscam atributos irrelevantes para a utilidade do carro: querem se sentir mais ricas, ou mais másculas, ou mais poderosas. O carro Kei é essencialmente um carro para locomoção e nada mais.

O herói desse filme parece ter encontrado uma maneira bem simples de viver. Ele lê um livro por vez, toma banho numa casa de banhos, lava as roupas numa lavanderia, come no mesmo restaurante todos os dias. As coisas interessantes da vida dele chegam sem serem convidadas.

Num ponto o filme falha: as fitas cassetes não duram tanto tempo. Eu sei porque tenho algumas ainda. Depois de uns 20 anos, elas começam a estragar. E mesmo que sobrevivam, está quase impossível achar onde tocá-las.

Então, as minhas ressalvas à ideia do filme são duas:

Primeiro, manter o status quo exige energia. As mudanças vão nos empurrando de tal sorte que nem sempre vale a pena manter tudo parado.

Em segundo lugar, nem tudo merece ser preservado. As fitas cassetes serviram seu papel, mas hoje em dia elas são, junto com os LPs, lixo plástico. Um único pen-drive armazena milhares de discos e consome menos recursos por isso.

Então, o filme está a nos mostrar uma noção de vida mais simples, mas usa uma artimanha que esconde um desperdício bárbaro. A ideia é o que conta, eu sei, mas este é um blog sobre tecnologia. Continuar a usar fitas cassete em 2024 é como ter uma Mercedes de 1950: é muito bonito, mas exige tempo e recursos que não valem realmente a pena (para a maior parte das pessoas).

Hirayama, o personagem central do filme, usa câmeras com filme. Talvez em Tóquio ainda exista onde revelar filme, mas em cidades com menos de 30 milhões de habitantes, talvez seja difícil.

Em resumo, eu gostei da noção do filme de que devemos procurar uma maneira mais simples de viver. Vejo muitas pessoas sofrendo por quererem ter tudo ao mesmo tempo. Por outro lado, acho que o filme errou nos detalhes, porque usou artefatos que, embora nos remetam a tempos mais simples (ou seria apenas uma ilusão da nossa memória?), na realidade complicariam bastante a vida de quem quer usá-los ainda hoje. Eis a magia do cinema, sempre a nos iludir.

sábado, 24 de fevereiro de 2024

O que o IBM PC já fez por nós?

O primeiro PC da IBM (modelo 5150) foi lançado no fim de 1981. A revista Byte o avaliou no início de 1982. Comparados aos micros de 8 bits, ele não tinha muito a oferecer.

Temos que considerar que memória era muito cara nessa época. 64KB de RAM custavam centenas de dólares. Então, não é surpreendente que o modelo básico tivesse apenas 16KB. A placa mãe poderia ser expandida até 64KB e depois disso, a máquina poderia ser levada até 256KB via uma placa num dos 5 slots.

5 slots até parecem bastantes, porque os micros de 8 bits em geral não tinham nenhum. Por outro lado, um deles já tinha que ser ocupado pela placa de vídeo. Então, eram 4 slots livres, na melhor das hipóteses. Instalar um drive de disquetes implicava instalar uma placa noutro slot.

O processador 8088 não era muito melhor que um Z80 ou um 6502. Apesar das CPUs de 8 bits só suportarem apenas 64KB de RAM, pouca gente tinha orçamento para mais que isso mesmo.

A configuração original não tinha drives de disquetes. Estes também eram muito caros nessa época, custando de US$300 até U$600. Então, o PC original, assim como os micros de 8 bits, tinha uma interface para fita cassete.

E também como os micros de 8 bits, o 5150 tinha um BASIC em ROM. Apenas uma vez testemunhei um PC com BASIC em ROM. Se o sistema não encontrasse um disco com sistema operacional, ele caía no BASIC. Era um BASIC da Microsoft. Até agora, o PC original não se distingue em nada dos micros de 8 bits, tanto que o BASIC era mais lento que um BASIC num Z80 a 4Mhz e muito mais lento que o BBC Basic rodando a 2MHz num 6502.

Duas características importantes eram evidentes: um teclado de qualidade (que poucos micros de 8 bits tinham) e 80 colunas já na configuração mais básica.

O preço de um PC completo, com drive de disquetes, 64KB de RAM e vídeo com 80 colunas, era muito parecido ao de um Apple II Plus com as mesmas características (~US$2.700).

Pode-se argumentar que o BBC B, lançado em dezembro de 1981 era melhor e até um pouco mais barato, mas ele estava restrito a 32KB de RAM e versões com 64KB ou mais só surgiram em 1985 (placas de expansão de memória eram oferecidas antes desse ano).

Em 1982, uma libra comprava ~US$1,66 e um BBC B, com monitor colorido, e um drive de disquetes custava cerca de £900, ou uns US$1500. Era um bom negócio, desde que se estivesse do lado certo do Atlântico. O BBC B já vinha de fábrica com suporte a 80 colunas e também tinha um modo texto (40x25) muito prático que só consumia 1KB da memória.

As comparações de memória RAM costumam esquecer que o PC precisava carregar o DOS na RAM, enquanto em micros de 8 bits a ROM podia habitar um espaço de endereços diferente da RAM. Mas vamos ignorar isso, porque cada máquina tinha uma arquitetura diferente.

O som do PC era pífio: apenas um canal que emitia uns ruídos irritantes.

Então o que tornava o PC 5150 interessante? Temos que pensar como um comprador comercial, não como um adolescente ávido por jogos. O PC oferecia as facilidades importantes para trabalhar com produtividade, num pacote completo. A quantidade de cores e o som não eram importantes para esse comprador, mas as 80 colunas, o teclado de qualidade, a possibilidade de expansão fácil, e a possibilidade de ir até 256KB de RAM eram importantes. Os usuários comerciais estavam acostumados ao sistema operacional CP/M (parecido com DOS) e 80 colunas eram comuns nessa plataforma.

Ele também oferecia a segurança de que não haveria qualquer possibilidade do seu filho se interessar por ele e tomar como refém o micro da firma.

Naquele tempo, a IBM não publicava informações sobre produtos que não estivessem prontos para serem vendidos. Logo, ninguém sabia se haveria outros modelos mais adiante. Comparando friamente as características do PC original com alguns micros da época, não era uma escolha óbvia, embora tampouco fosse uma escolha ruim.

O que o PC de 1981 oferecia eram algumas características importantes para aplicações comerciais. O que o PC de hoje oferece é uma plataforma aberta com grande concorrência de fornecedores. Essa possibilidade não demorou muito a aparecer e, dados os preços da IBM, era inevitável.

A minha teoria é a de que o PC só se tornou a escolha técnica indiscutível (não vamos considerar tamanho do mercado ou outros fatores) quando apareceu o 386, em 1985 (as coisas andavam muito rapidamente nos anos 1980). O primeiro PC com 386 foi lançado em 1986 pela Compaq; a IBM em 5 anos já tinha perdido a liderança da plataforma que ela mesma tinha criado. Nesse ponto, não havia mais computador doméstico que oferecesse negócio melhor.

quinta-feira, 1 de fevereiro de 2024

Experimentos com Compressão de Textos

Inspirado num artigo no Hacker News, resolvi fazer uns experimentos com textos.

Baixei o livro Amor de Perdição (Camilo Castelo Branco) do Projeto Gutenberg. Dizem que minha avó lia escondida esta lasciva obra quando ainda andava de pés descalços pelos campos de Alquerubim.

O arquivo está codificado em UTF-8 e ocupa 310KB. Usarei números aproximados apenas.

O gzip reduz o arquivo a 121KB. Com minúsculas apenas, o gzip o reduz a 118KB. Miseros 3KB que representam uma pífia economia de 2,5%.

E se eu quiser guardar as maiúsculas para restaurar o arquivo? O problema é que só as maiúsculas ocupam quase 7KB.

Mesmo ante o fracasso iminente, prossegui com meu plano insensato e pouco elaborado: troquei todas as maiúsculas por traços baixos e coloquei todas as maísculas no início do arquivo. O plano era trocar um a um os traços baixos pelas letras do cabeçalho após a descompressão.

O resultado final comprimido ocupa 124KB. Logo, não há vantagem nenhuma nesse tipo de codificação.

Usar apenas uma caixa (alta ou baixa, tanto faz) realmente economiza espaço, embora não seja surpreendente. Encontrar uma maneira de restaurar o texto original é um pouco mais complicado.

Experimentei também colocar as maiúsculas no fim, mas como minúsculas; afinal, terei a certeza de que tudo o que estiver na última linha tem que ser caixa alta. O resultado supreendeu: 122KB compactados. O arquivo ficou apenas 1KB maior que o original compactado.

Talvez ainda haja algo a fazer com os espaços.

terça-feira, 30 de janeiro de 2024

Limpando o postgresql.conf

O Postgresql é relativamente simples de entender e configurar. Mesmo compilá-lo não é complicado.

Entretanto, o principal arquivo de configuração tem um excesso de documentação. Uma solução simples é guardar o arquivo original e limpar tudo o que não for essencial.

O que precisamos limpar são todas as linhas que começam com # ou estão em branco.


 cp postgresql.conf postgresql.conf.original
 grep -Pv "^\s*#" postgresql.conf | grep "\S" > postgresql.conf


O primeiro grep elimina todas as linhas que começam com um # e que talvez tenham espaços antes desse caracter. O segundo limpa todas as linhas em branco.

No meu caso, um arquivo com 979 linhas ficou reduzido a 18.

sexta-feira, 26 de janeiro de 2024

Grep com Contexto

O grep geralmente é usado em arquivos orientados a linhas. De quando em vez aparece algo mais complicado.

Se precisamos de mais contexto, podemos usar -B (before) e -A (after) para indicar quantas linhas queremos de antes e depois do que for encontrado:


  grep -B 4 -A 3 ERROR log.txt
  

E assim podemos ver 3 linhas para frente e 4 para trás.

Se o arquivo tiver delimitadores, podemos usar uma mágica do Perl. Considere o arquivo abaixo:


Registro 1
Nome: Fulano
Endereço: Rua Torta, 1
Sexo: M
Fim
Registro 2
Nome: Beltrana
Endereço: Rua Reta, 12
Sexo: F
Fim

Se eu quiser filtrar todos os registros com "Sexo: F", posso usar a variável $/, que indica o que é um separador de linha.


$ perl -ne "BEGIN{$/='Fim'} print if /Sexo: F/" pessoas.txt

Registro 2
Nome: Beltrana
Endereço: Rua Reta, 12
Sexo: F
$ perl -ne "BEGIN{$/='Fim'} print if /Sexo: M/" pessoas.txt
Registro 1
Nome: Fulano
Endereço: Rua Torta, 1
Sexo: M

O BEGIN serve para executarmos a atribuição apenas uma vez, porque a opção -n coloca tudo dentro de um "while(<>) {}". Mas se não nos importamos com isso, podemos simplificar com:


 perl -ne "$/='Fim'; print if /Sexo: M/" pessoas.txt
 

Podemos até incluir o \n no valor de $/ para não surgirem linhas vazias nos resultados. Para isso, também temos usar o qq() (quoted string) para não termos problemas com as aspas duplas:


 perl -ne "$/=qq(Fim\n); print if /Sexo: M/" pessoas.txt
 

Se os registros não tiverem os mesmos terminadores ou se o arquivo contiver outras estruturas que não nos interessam, podemos usar o operador flip-flop:


#!/usr/bin/perl
open(my $file, '<', $ARGV[0]);

my ($block, $found);
while(<$file>) {
    if(/^Registro/ .. /^Fim/) {
        $found=1 if /Sexo: M/;
        $block.=$_;
    } else {
        print $block if $found;
        undef $block;
        $found=0;
    }
}
print $block if $found;
  

Esse script recebe o nome do arquivo como parâmetro. A mágica acontece no "if(/^Registro/ .. /^Fim/)". O operador começa a retornar verdadeiro quando encontra Registro e passa a retornar falso quando encontra Fim. O resto do arquivo cai no else. O resto do script é óbvio.

Então, temos 3 opções para buscas progressivamente complexas em arquivos. Perl, como de costume, salva o dia.

segunda-feira, 22 de janeiro de 2024

Complicando o Problema dos Pintores

Um pintor pinta um quarto em 3h e o outro completa o serviço em 5h. Quanto tempo os dois juntos levam para pintar o quarto?

A gente poderia calcular o progresso por unidade de tempo, mas é melhor trabalhar com inteiros até onde der. Então, precisamos de um valor que os dois dividam. O mais óbvio é 3*5=15

Nesse tempo, o primeiro pinta 5 quartos (15/3) e o segundo pinta 3 quartos. Portanto, o tempo para os dois juntos pintarem um quarto será 15/(3+5): um pouco menos de 2h.

Os números 3 e 5 são primos, então o MMC deles só pode ser 3*5. Se os tempos forem 4 e 8, podemos usar 8 e a conta será 8/(1+0,5) ou 16/3.

Se usarmos 4 e 6, o MMC será 12 e a conta será 12/(3+2)=12/5.

O legal desse problema é que podemos usar qualquer quantidade de pintores. Se tivermos dois pintores lentos que levam 5h e um apressadinho que leva 3, a conta será 15/(5+3+3)=15/11.

Qual terá sido a contribuição de cada um?

Para calcular a contribução de cada um, basta multiplicar o recíproco do tempo de cada pintor pelo tempo total do serviço. Então, nosso amigo que leva 3h, terá contribuído com 15/8 * 1/3 = 15/24. O colega folgado contribuirá com 15/8*5 = 15/40. Com base nisso, podemos dividir o pagamento.

O MMC de 24 e 40 é 120 e então podemos confirmar que 15*5 + 15*3 = 120 e a nossa conta fecha 100%.

A conta fecha também com os três pintores: (15/(13*5))+(15/(13*3))+(15/(13*3))=5/13+3/13+3/13=1.

Se usarmos 3, 5, e 7, o produto será 105 e a soma 71 (105/3 + 105/5 + 105/7). É preciso ter cuidado para não esquecer que a soma é das divisões dos produtos por cada tempo, não os tempos em si.

Outra forma de ver a conta, é que é a soma dos produtos 2 a 2 (no caso de termos 3 pintores. Ou seja: 3*5 + 3*7 + 5*7.

Claro que só posso pensar numa solução n a n se o nominador for o produto de todos os tempos. Por exemplo, com os tempos 3, 5, e 5, seria preciso usar 3*5*5 para então calcular o denominador com 3*5 + 3*5 + 5*5. Note que 75/55=15/11. Usar o 15 seria um equivoco. Então o mais fácil é não misturar a combinatórica com o MMC. Use um ou outro, conforme o gosto pessoal.

Acho que basta deste assunto. Os pintores nunca vêm no horário combinado mesmo.

quinta-feira, 4 de janeiro de 2024

Niklaus Wirth (1934-2024)

O ano de 2024 começou com o falecimento do pai do Pascal, Niklaus Wirth.

Pascal foi a minha segunda linguagem de programação, depois do BASIC. Primeiro, tive que sofrer um pouco por não ter linhas numeradas; uma vez superada essa barreira, sofri um com ponteiros.

A linguagem, entretanto, ensinou-me bons hábitos e o esforço valeu a pena.

O ambiente em que eu aprendi a usar o Pascal merece uma nota: ISO Pascal da Acornsoft.

Para entender esse ambiente, é preciso entender um pouco sobre a máquina no qual ele rodava: o BBC Micro da Acorn.

Esse micro usava um 6502 e, portanto, só podia endereçar 64KB. Para contornar essa limitação, ele alternava um bloco de 16KB dentre os ROMs disponíveis. Esses ROMs podiam conter linguagens ou simplemente comandos para o Sistema Operacional; quando um comando era digitado na linha de comando, o SO procurava o código nos ROMs instalados. Havia também ROMs para Lisp, Forth, BCPL, Prolog, Logo, e COMAL.

Dentre os ROMs podia haver também chips de RAM! No caso do meu micro, havia 4x16KB. Essa memória podia se comportar como ROMs comuns (era possível carregar uma imagem de ROM a partir de um disquete, por exemplo), ou o programador podia usar como bem entendesse, uma vez que bastava colocar um valor num certo endereço de memória para trocar o ROM ou RAM visível para a CPU.

Havia mais algumas complicações, como 20KB de Shadow Memory que ficavam "atrás" da memória de vídeo e que podiam ser usadas para gráficos, desde que o programador usasse apenas as rotinas do SO. Havia também mais 12KB que o SO usava para não roubar mais RAM do usuário.

O Pascal vinha em 2 ROMs: um para o compilador e outro para o editor, as bibliotecas, e o interpretador de BL-code (um tipo de p-code). Esse BL-code foi inventado para contornar as limitações da máquina: simplesmente compilar para código de máquina era inviável, porque os binários ficariam muito grandes.

Como o compilador também estava em BL-code, para poder compilar um programa, o interpretador se copiava para a memória principal. Para rodar um programa já compilado, o interpretador podia ficar na área de ROM.

O editor ocupava apenas 4KB, mas tinha pesquisa com expressões regulares. É difícil acreditar nisso hoje em dia. Ele rodava no modo texto (40x25) e, portanto, gastava apenas 1KB de memória de vídeo. Os programas, entretanto, podiam ser rodados em qualquer modo.

Este foi o primeiro Pascal fiel à norma que rodou numa máquina sem disco. Ele recebeu elogios até da Primeira Ministra Margaret Thatcher; não que ela entendesse exatamente o que estava elogiando, mas elogiou.

A caixa incluía, além do software em ROM, um disquete (dava para rodar com disquete também), um manual, um cartão de referência, e um excelente livro entitulado: Pascal from BASIC. Afinal, os autores conheciam bem seu público.

E com essas boas lembranças, nos despedimos do grande Niklaus Wirth.