Windows NT 3.1 – A génese do Windows moderno

Sempre que leio um artigo ou vejo um vídeo sobre a história ou evolução do Windows observo quase sempre a mesma estrutura de conteúdo:

  1. A primeira versão do Windows saiu em 1985;
  2. O SO só ganhou popularidade com o Windows 3.1;
  3. Saltou para a estratosfera em termos de utilizadores com o Windows 95;
  4. O Windows XP trouxe o kernel NT para os consumidores com maior estabilidade;
  5. O Windows Vista redesenhou grandes partes do SO para ter em conta segurança;

Entre o segundo e a quarto acontecimento noto sempre uma falta de esclarecimento sobre o kernel NT. De onde originou? Quem é que usava NT antes do Windows XP? Neste artigo pretendo elucidar um pouco sobre as origens do kernel NT, analisando o primeiro lançamento comercial com a sua implementação, o Windows NT 3.1.

O SO saiu em 1993. Na altura, os requisitos necessários para correr eram altos. É estranho considerar que 12MB de RAM era uma quantidade astronómica de memória para o comum utilizador, mas este fator contribuiu para a sua falta de adesão num espaço dominado pelo MS-DOS e pelo seu irmão mais mainstream, o Windows 3.1. Importante realçar que o Windows 3.1 é mais uma extensão gráfica para o MS-DOS do que propriamente um SO completo e de raíz como o NT 3.1. Enquanto que o Windows 3.1 era direcionado para o mercado do consumidor, o NT 3.1 pretendia preencher uma lacuna no mercado que a Microsoft previamente não ocupava significativamente: o mercado profissional e o de servidor. Daí existirem duas edições: “Workstation” e “Advanced Server”.

Origens

Abordar o desenvolvimento do Windows NT 3.1 é também falar de um pedaço importante de história da Microsoft. Para dar algum contexto, nos finais dos anos 80/inícios dos anos 90 a relação entre a Microsoft e a IBM, que previamente tinha levado ambas para a ribalta do mercado dos computadores pessoais, já tinha agoirado. A IBM considerava que a Microsoft já estava a competir demasiado num mercado que eles pretendiam controlar de cima a baixo, e a Microsoft considerava que a IBM era um gigante antiquada que não era compatível com a cultura de inovação que tentavam fomentar. O desenvolvimento do Windows NT 3.1 remota a 1988, quando a Microsoft decidiu contratar Dave Cutler, famigerado engenheiro de software que liderou a criação um conjunto de SO inovadores para a sua empresa anterior, a Digital Equipment Corporation (DEC). Começou como uma nova iteração do OS/2, um SO desenvolvido em conjunto com a Microsoft e a IBM, mas prontamente tomou uma identidade mais Windows à medida que as duas empresas se foram afastando (importante relembrar que antes dos anos 90 a Microsoft ainda era vista como uma empresa de porte médio). Um dos principais motivadores para Dave Cutler ter movido para a Microsoft é que lhe foi prometida liberdade total no desenho e implementação do SO. Com uma equipa inteiramente construída por ele e liberdade orçamental e temporal, tinha apenas como guia a construção de um SO de próxima geração. Microkernel, portabilidade, preempção, separação entre espaço de sistema e espaço de utilizador, … Todos os chavões da inovação da altura foram implementados. Mas como sabemos, a inovação não fica barata, motivo pelo qual o desenvolvimento durou uns 5 anos com o lançamento de versões beta regularmente a partir de 1991. Finalmente, em Julho de 1993 o Windows NT 3.1 apareceu nas lojas.

Caixa do Windows NT 3.1 vendida em lojas de retalho. A versão Workstation custava $495 e a versão Advanced Server 1495$

Instalação Obtusa

Embora seja um SO de próxima geração desenhado para o futuro, neste momento vivemos no futuro e temos de lidar com alguns pontos inerentes a um software concebido para correr em sistemas de 1993.

  • Processador – seria de pensar que qualquer processador lançado após 1993 conseguiria executar o SO sem grandes problemas, se descartarmos todos os componentes à volta, mas a verdade é que há uma verificação estrita nos ficheiros que configuram a instalação (ou isso ou um bug no código de deteção de processadores). Resultado: erro na fase gráfica da instalação com qualquer processador posterior à primeira série de Pentiums. É possível editar estes ficheiros para remover esta restrição – ou antes de gravar o disco ou utilizando uma disquete de MS-DOS para editar os ficheiros de instalação após o primeiro reinício.
Erro de instalação com um processador não suportado
  • Memória RAM – em 1993 MS-DOS era rei, e muitas das limitações de memória do standard IBM original ainda se encontravam presentes. Múltiplas empresas ainda não se tinham decidido sobre como endereçar memória acima dos 16MB (standard definido pelo processador 286 introduzido pela Intel). O Windows NT 3.1 utiliza um método obsoleto de detetar memória definido pela IBM, que já não se utiliza em sistemas modernos. Resultado: caso o BIOS não dê a opção para endereçar a memória de maneira diferente, o Windows NT irá apenas reconhecer no máximo 64MB. Claro que num sistema como este, 64MB de RAM já dá para bastante, mas é uma limitação peculiar para ter em conta. Há um artigo excelente que explica em pormenor este fenómeno, caso esteja interessado em saber mais.
  • Input/Output – até recentemente, conectar um leitor de discos ao computador passava por colocar o dispositivo na caixa e ligar à motherboard por SATA ou até mesmo IDE. Em 1993 a típica conexão IDE ainda só suportava discos rígidos. Só em 1994 é que o standard EIDE seria introduzido, permitindo a conexão de outros dispositivos. Como tal, um leitor de CDs teria de usar um outro standard de conexão que permitisse maior flexibilidade: SCSI. A instalação do Windows NT foi distribuída num CD-ROM, o que impõe o uso de um leitor de CDs. Juntando dois com dois é possível verificar o seguinte: o Windows NT apenas suporta de raíz a instalação em discos e unidades conectadas por SCSI. Se na altura esta conexão era maioritariamente utilizada pelo segmento profissional, hoje praticamente toda a gente a desconhece e nenhum computador moderno a suporta.
  • Inicialização – o standard para inicializar o computador através de um CD só foi publicado em 1995. Para efetuar a instalação do Windows NT é necessário tanto o CD-ROM com todos os dados do SO como a disquete para inicializar a configuração e carregar os controladores de disco, teclado, vídeo, …

Nem o VirtualBox ou VMware e muito menos o Hyper-V conseguem simular uma máquina com todas as peculiaridades da altura. O 86Box é uma solução de virtualização especializada em hardware mais antigo, cobrindo uma grande seleção desde o início dos anos 80 até finais dos anos 90. Permite selecionar a motherboard, CPU, RAM, placa de vídeo, áudio, etc.

Heis a configuração que gosto de usar no 86Box para instalar e utilizar o Windows NT 3.1:

  • Plataforma: Socket 7
  • Motherboard: ASUS P/I-P65UP5
  • CPU: Intel Pentium 150Mhz
  • RAM: 256MiB
  • Gráficos: ATI Mach64 GX 4MiB [PCI]
  • Som: Sound Blaster 16 [ISA16]
  • Rede: AMD PCnet-ISA
  • Controlador SCSI: Adaptec AHA-154xC
  • HDD: 3788MiB a 4500RPM ligado no canal SCSI 0:01
  • Leitor CD: Sony CD-ROM CDU-541 (velocidade 4x) ligado no canal SCSI 0:00
  • Rato: Normal PS/2
  • Impressora genérica PostScript ligada na porta LPT1

O computador simulado apresenta componentes que saíram depois do lançamento do NT 3.1, mas todas as peças são compatíveis, e assim garantimos a melhor velocidade possível quando estivermos a interagir com o sistema. Por exemplo, nem a placa de vídeo nem a de som são reconhecidas pelo SO à partida, mas existem drivers compatíveis. A totalidade dos 256MiB de RAM especificados também não serão reconhecidos com as definições predefinidas no BIOS, mas é possível mudar isso.

nt_31_bios

Definição do BIOS que tem de ser habilitada para que o Windows NT 3.1 reconheça mais do que 64MiB de RAM

A ATI Mach64 GX também precisa de ser inicializada com um disco especial da ATI em DOS para especificar as resoluções e quantidade de cores suportadas pelo monitor. Como vivemos no futuro, podemos essencialmente ativar todas as opções que o programa de configuração suporta.

ATI Mach 64 Config Disc

Programa de configurações da ATI Mach 64 GX

Após toda esta configuração, basta inserir a disquete de arranque e o CD de instalação e seguir os passos indicados. Um par de olhos funcional e compreensão da língua inglesa são as únicas ferramentas necessárias. Só recomendo na fase inicial de texto – antes do primeiro reinicio para a parte gráfica – mudar o tipo do teclado para português e mudar o adaptador gráfico para o ATI Mach 64 GX, inserindo a disquete com os drivers. No final do artigo terei uns links com todos estes dados, pois são algo raros e difíceis de encontrar na Internet.

Interface antiquada

Windows NT 3.1 UI

Interface do Windows NT 3.1 com alguns programas abertos

O Windows NT 3.1 herda a interface do seu irmão mais primitivo, o Windows 3.1. Há algumas decisões de Interface do Utilizador (IU) que me deixam a coçar a cabeça. Para mudar a resolução é preciso chamar o programa “Windows Setup” para mudar os drivers. Aos olhos do sistema, mudar a resolução do monitor é equivalente a mudar o driver gráfico. Um painel para ajuste do monitor só seria introduzido com a versão subsequente do SO, o Windows NT 3.5. O típico CTRL+C e CTRL+V para copiar e colar só funciona em caixas de texto. No Gestor de Ficheiros, é necessário usar o F8 para copiar, e não existe uma caixa de diálogo simplicada para efetuar muitas dessas operações. É necessário introduzir manualmente o caminho para copiar ou mover. Também temos de ser justos, muitas destas críticas de usabilidade também se aplicariam ao Windows 3.1.

Estranhamente, nem todos os programas incluídos com o NT 3.1 são verdadeiramente de 32 bits. O programa de tutorial do sistema e o WordPad ainda são de 16 bits. Em termos de funcionamento, existe um processo chamado NTVDM que traduz chamadas de programas de 16 bits para as equivalentes de 32 bits, simulando algum do ambiente original de execução. Infelizmente, este processo é usado por todos os programas de 16 bits que estiverem a correr, portanto se um deles falhar catastroficamente, deita abaixo todos os outros, e só com um reinicio do sistema é possível voltar a executar programas nesta arquitetura mais antiga. Este comportamento seria remediado no Windows NT 3.5, que permite correr estes programas em espaços de memória distintos.

Outra particularidade do ambiente de 16 bits é que só simula o nível de API do Windows 3.1 e não do 3.11. Isto significa que programas de 16 bits mais avançados desenvolvidos a partir a segunda metade dos anos 90 dificilmente correm. De facto, nem há suporte para OLE 2.0 (Object Linking and Embedding).

Portanto o Windows NT 3.1 está neste meio termo estranho em que não tem grande suporte para aplicações de 32 bits, que apareceriam em maiores números a partir de 1994 e especialmente em 1995, devido ao lançamento rápido de sucessivas iterações, nem tem grande suporte para aplicações de 16 bits. De tudo o que consegui encontrar na Internet, só consegui instalar o Visual C++ 1.1 e o Resource Kit como aplicações verdadeiramente nativas de 32 bits. Para instalar o Office 4.2 – que inclui o Word, Excel e PowerPoint – já tive de recorrer ao ambiente de 16 bits.

Em termos de jogos, quase nada consegui instalar. SimCity 2000 não abre pois necessita da biblioteca de Video For Windows (VFW) e qualquer jogo dependente da biblioteca WinG é também um não. Só consegui mesmo pôr a correr o primeiro Civilization, pois foi desenhado para correr no Windows 3.0 com extensões de multimédia.

Mas nem tudo são más notícias. Note-se que o Windows mantém compatibilidade de API desde os seus primórdios, e isso significa que qualquer aplicação desenvolvida para esta versão do Windows ainda corre sem problemas no Windows 11.

PaintBrush Windows 11

Paintbrush, o antecessor do Paint, a correr no Windows 11

Mas será que podemos puxar o panorama das aplicações disponíveis mais longe?

Jogar em 32 bits

Graças aos esforços de preservação da Internet, as bibliotecas de desenvolvimento para o Windows NT 3.1, juntamente com a documentação, estão facilmente acessíveis. Desenvolver, ou no mínimo adaptar código fonte existente para um sistema tão primordial de certeza que nos dará alguma visão sobre as realidades de desenvolvimento da altura. Tanto quanto sei, nenhum jogo de 32 bits saiu na altura com compatibilidade com o SO, portanto adaptando algum código fonte existente seria possível ganhar a distinção de primeiro jogo compatível com o NT 3.1.

Após alguma pesquisa na internet, descobri o website de um programador chamado Philip John Vaz e a sua empresa de jogos, VazGames. O website entretanto desapareceu, e a própria empresa de jogos parece que nunca mais publicou nada, mas ainda existe uma cópia dele no Web Archive. Neste site que parece vindo dos anos 90, há um sítio repleto de recursos para desenvolvimento de jogos em Windows, incluindo referências de programação. Se quiserem visitar, basta abrir este link. Foi um milagre ter tropeçado neste sítio tão remoto da Internet que teria caído no esquecimento, se não fosse por esta minha curiosidade em sistemas obsoletos.

Mas enfim, neste website encontrei o código fonte para uma versão do PacMan, denominada de VazPac, desenvolvida inteiramente em Win32 – com a ajuda de outras bibliotecas que iremos ver a seguir. Os principais desafios seriam:

  • Adaptar chamadas de Win32 que não existem no Windows NT 3.1 para equivalentes, muito provavelmente com funcionalidade reduzida;
  • O desempenho ser reduzido. Em todas as versões do Windows NT 3.x, o GDI – Graphics Device Interface – responsável por renderizar todos os gráficos, corre na camada de utilizador e não de kernel. Em sistemas antigos como o que temos de usar para correr o Windows NT 3.1, isto significa que o desempenho poderá não ser o ideal.
  • O comportamento das funções pode ter sofrido alterações entre antes e agora. A Microsoft pode ter feito alterações por motivos de segurança ou compatibilidade. Nunca se sabe.

Configuração e desafios técnicos

Há duas abordagens possíveis: utilizar o SDK original de julho de 1993 que contém não só todas as bibliotecas e ficheiros de header necessários para configurar o ambiente de desenvolvimento, ou utilizar o Visual C++ 1.1 para NT que contém não só tudo o que mencionei anteriormente, mais o IDE original. Ambos estão disponíveis aqui e aqui. Optei por utilizar o primeiro, pois a configuração é mais portátil e não modifica o sistema. Assim posso utilizar um ambiente de desenvolvimento mais moderno, como o Visual Studio Code no Windows 11.

O código e os recursos como se encontram originalmente não estão muito organizados. Toda a lógica está contida num único ficheiro VazPac.cpp com um ficheiro header apenas para definir o nome dos bitmaps que compõem os gráficos. Os mencionados bitmaps juntamente com os ficheiros de som encontram-se espalhados na mesma pasta que o código. Primeira ordem do dia era organizar os ficheiros. Movi os bitmaps e os sons para pastas separadas, dentro duma pasta denominada “ASSETS”. Depois mudei o nome dos ficheiros de código para “main”. Ultrapassadas as formalidades, passámos à análise pura e dura do código. Heis as seguintes áreas em que foi preciso alterar:

  1. Utilização da biblioteca DirectSound do DirectX para gestão do aúdio. O Windows NT 3.1 não suporta DirectX, portanto tive de escrever o código de gestão do som de raiz para utilizar as chamadas de baixo nível do waveOut.
  2. Função de inicialização dos bitmaps teve de ser mudada da inexistente LoadImage para a mais compatível e existente LoadBitMap, com a necessária reestruturação dos dados.
  3. Otimização do loop principal do jogo. O criador original optou por utilizar um simples loop infinito para controlar a execução do jogo, mas sendo o Windows um SO avançado com um sistema de comunicação por mensagens robusto, mudei para utilizar o temporizador do sistema. Isto permitiu diminuir o uso do processador e conseguir ganhos modestos de desempenho no Windows NT 3.1. O dissipador de calor Noctua do meu processador Ryzen 7 7700X fazia barulho quando tentava executar o jogo!
  4. Reestruturação do código, incluindo mudar todas as inicializações de variáveis e funções para ficheiros header apropriados. Não sendo um passo estritamente necessário para correr o programa, ajuda no mínimo à análise do código.

O resultado deste trabalho encontra-se neste repositório do GitHub que criei com todas as alterações.

https://github.com/jdev15/vazPac-winnt31

Também incluí um executável compilado com as ferramentas originais de 1993 que corre em todas as versões do Windows NT. Até é possível compilar o código no Visual C++ 1.1 sem quaisquer alterações. Admito que não testei a execução no Windows 3.11 com as extensões Win32s, mas deixo esse exercício para o leitor curioso.

Código do VazPac compilado no Visual C++ 1.1

O resultado demonstro nesta captura do ecrã: exatamente o mesmo executável a correr em sistemas com 30 anos de diferenças de avanços tecnológicos:

vazPac a correr no Windows 11 24H2 e no Windows NT 3.1 lado a lado.

Conclusões

Comecei o artigo com uma descrição do Windows NT 3.1, da sua história e funcionalidades e acabei por adaptar o código de um jogo conhecido desenvolvido por alguém que ninguém conhece. Foi um exercício lúdico interessante. Permitiu-me demonstrar a versatilidade do Windows e também aprofundar os meus conhecimentos no desenvolvimento de programas Win32. O executável em si tem alguns problemas ao executar em sistemas antigos. Ao iniciar dá uns erros de inicialização dos sons e corre extraordinariamente lento. Em vez de contar a velocidade em FPS é em SPF ou Segundos Por Frame. No mínimo, espero ter elucidado um pouco sobre a história do SO mais popular da história e das suas origens.

Estive a escrever este artigo há já algum tempo, maioritariamente atrasado pelos meus avanços lentos na adaptação do programa que apresentei na parte final. Considerei que não seria uma visão completa se também não incluísse um pouco as lutas do desenvolvimento na altura. Espero que o artigo seja no mínimo interessante.

Esta entrada foi publicada em Tecnologia com as tags , , . ligação permanente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *