Dados Gerais Nova
O Data General Nova é uma série de minicomputadores de 16 bits lançada pela empresa americana Data General. A família Nova era muito popular na década de 1970 e vendeu dezenas de milhares de unidades.
O primeiro modelo, conhecido simplesmente como "Nova", foi lançado em 1969. O Nova foi embalado em um único gabinete de montagem em rack 3U e tinha poder de computação suficiente para lidar com as tarefas mais simples. O Nova tornou-se popular em laboratórios de ciências em todo o mundo. Ele foi seguido no ano seguinte pelo SuperNOVA, que funcionou aproximadamente quatro vezes mais rápido.
Introduzida durante um período de rápido progresso no design de circuitos integrados (ou "microchips"), a linha passou por várias atualizações nos cinco anos seguintes, introduzindo o 800 e o 1200, o Nova 2, o Nova 3 e, finalmente, o Nova 4. Uma implementação de chip único também foi introduzida como microNOVA em 1977, mas não teve uso generalizado quando o mercado mudou para novos designs de microprocessador. A Fairchild Semiconductor também introduziu uma versão do microprocessador do Nova em 1977, o Fairchild 9440, mas também teve uso limitado no mercado.
A linha Nova foi sucedida pelo Data General Eclipse, que era semelhante em muitos aspectos, mas adicionava suporte à memória virtual e outros recursos exigidos pelos sistemas operacionais modernos. Uma atualização de 32 bits do Eclipse resultou na série Eclipse MV da década de 1980.
História
Edson de Castro e o PDP-X
Edson de Castro foi o Gerente de Produto da pioneira Digital Equipment Corporation (DEC) PDP-8, um computador de 12 bits amplamente referido como o primeiro verdadeiro minicomputador. Ele também liderou o projeto do PDP-8/I atualizado, que usava os primeiros circuitos integrados no lugar de transistores individuais.
Durante o processo PDP-8/I, de Castro visitou fabricantes de placas de circuito que estavam fazendo rápidos avanços na complexidade das placas que podiam montar. de Castro concluiu que o 8/I poderia ser produzido usando montagem totalmente automatizada em placas grandes, o que seria impossível apenas um ano antes. Outros dentro da DEC se acostumaram com as placas menores usadas em máquinas anteriores e estavam preocupados em rastrear problemas quando havia muitos componentes em uma única placa. Para o 8/I, optou-se por ficar com as pranchas pequenas, utilizando o novo "flip-chip" embalagem para uma melhoria modesta na densidade.
Durante o período em que o PDP-8 estava sendo desenvolvido, a introdução do ASCII e sua principal atualização em 1967 levaram a uma nova geração de designs com comprimentos de palavra que eram múltiplos de 8 bits em vez de múltiplos de 6 bits como na maioria desenhos anteriores. Isso levou a designs de médio alcance trabalhando com comprimentos de palavra de 16 bits em vez das atuais linhas de 12 e 18 bits da DEC. de Castro estava convencido de que era possível melhorar o PDP-8 construindo uma CPU de minicomputador de 16 bits em uma única placa quadrada de 15 polegadas.
Em 1967, de Castro iniciou um novo esforço de design conhecido como "PDP-X" que incluiu vários recursos avançados. Entre eles, havia um único design subjacente que poderia ser usado para construir plataformas de 8, 16 e 32 bits. Isso progrediu a ponto de produzir vários documentos detalhados de arquitetura. Ken Olsen não apoiou este projeto, sentindo que não oferecia vantagens suficientes sobre o PDP-8 de 12 bits e o PDP-9 de 18 bits. Ele acabou sendo cancelado na primavera de 1968.
Desenho do Nova
O cancelamento do PDP-X levou Castro a considerar deixar a DEC para construir um sistema por conta própria. Ele não estava sozinho; no final de 1967, um grupo de engenheiros com ideias semelhantes formou-se para considerar tal máquina. O grupo incluía Pat Green, um gerente de divisão; Richard Sogge, outro engenheiro de hardware; e Henry Burkhardt III, engenheiro de software. Em contraste com o PDP-X, o novo esforço se concentrou em uma única máquina que poderia ser lançada no mercado rapidamente, pois Castro sentiu que o conceito do PDP-X era ambicioso demais para uma pequena empresa iniciante.
Discutindo isso com os outros na DEC, o conceito inicial levou a uma máquina de 8 bits que seria menos dispendiosa de implementar. O grupo começou a conversar com Herbert Richman, um vendedor da Fairchild Semiconductor que conhecia os outros por meio de seus contatos com a DEC. Na época, a Fairchild estava lutando com a Texas Instruments e a Signetics no mercado de TTL em rápido crescimento e introduzindo novas fábricas que permitiam designs mais complexos. A mais recente série 9300 da Fairchild permitia até 96 portas por chip, e eles usaram isso para implementar vários chips de 4 bits, como contadores binários e registradores de deslocamento.
O uso desses ICs reduziu a contagem total de IC necessária para implementar uma unidade lógica aritmética completa (ALU), o principal componente matemático de uma CPU, permitindo a expansão de um design de 8 bits para 16 bits. Isso exigiu a expansão da CPU de uma única placa de circuito impresso de 15 por 15 polegadas (38 cm × 38 cm) para duas, mas tal projeto ainda seria significativamente mais barato de produzir do que o 8/I, embora ainda fosse mais poderoso e baseado em ASCII. Uma terceira placa continha os circuitos de entrada/saída e um sistema completo normalmente incluía outra placa com 4 kB de memória de acesso aleatório. Um sistema completo de quatro placas cabe em um único chassi de montagem em rack.
As placas foram projetadas para que possam ser conectadas entre si através de um backplane de circuito impresso, com o mínimo de fiação manual, permitindo que todas as placas sejam construídas de forma automatizada. Isso reduziu muito os custos em relação ao 8/I, que consistia em muitas placas menores que precisavam ser conectadas no backplane, que era conectado usando um envoltório de fio. A construção de placa maior também tornou o Nova mais confiável, o que o tornou especialmente atraente para ambientes industriais ou de laboratório.
O novo design usava uma arquitetura load-store simples que ressurgiria nos designs RISC na década de 1980. Como a complexidade de um flip-flop estava sendo rapidamente reduzida conforme eles eram implementados em chips, o projeto compensou a falta de modos de endereçamento do projeto load-store adicionando quatro acumuladores de uso geral, em vez do único registrador que seria encontrado. em ofertas similares de baixo custo como a série PDP.
Introdução do Nova
No final de 1967, Richman apresentou o grupo ao advogado de Nova York Fred Adler, que começou a sondar várias fontes de financiamento para capital inicial. Em 1968, Adler conseguiu um grande acordo de financiamento com um consórcio de fundos de capital de risco da área de Boston, que concordou em fornecer um investimento inicial de US$ 400.000 com um segundo US$ 400.000 disponíveis para aumento da produção. de Castro, Burkhart e Sogge saíram da DEC e começaram a Data General (DG) em 15 de abril de 1968. Green não se juntou a eles, considerando o empreendimento muito arriscado, e Richman não se juntou até que o produto estivesse funcionando no final do ano.
O trabalho no primeiro sistema levou cerca de nove meses, e os primeiros esforços de vendas começaram em novembro. Eles tiveram um pouco de sorte porque a Fall Joint Computer Conference foi adiada para dezembro daquele ano, então eles puderam trazer uma unidade de trabalho para o Moscone Center, onde executaram uma versão do Spacewar!. A DG lançou oficialmente o Nova em 1969 a um preço base de US$ 3.995 (equivalente a US$ 29.520 em 2021), anunciando-o como "o melhor computador pequeno do mercado". o mundo." O modelo básico não foi muito útil pronto para uso e adicionar 8 kW (16 kB) A RAM na forma de memória principal geralmente aumentava o preço para US$ 7.995. Por outro lado, um 8/I com 4 kW (6 kB) custava US$ 12.800.
A primeira venda foi para uma universidade no Texas, com a equipe construindo manualmente um exemplo que foi enviado em fevereiro. No entanto, isso ocorreu em meio a uma greve no setor aéreo e a máquina nunca chegou. Eles enviaram um segundo exemplo, que chegou prontamente porque a greve havia terminado naquele ponto, e em maio o original também foi finalmente entregue.
O sistema foi bem-sucedido desde o início, com o 100º sendo vendido após seis meses e o 500º após 15 meses. As vendas aceleraram com o lançamento de novas versões e, em 1975, a empresa tinha vendas anuais de US$ 100 milhões.
SuperNOVA
Ken Olsen previu publicamente que o DG falharia, mas com o lançamento do Nova ficou claro que isso não aconteceria. A essa altura, várias outras empresas também estavam falando sobre a introdução de designs de 16 bits. Olsen decidiu que isso representava uma ameaça para sua linha de 18 bits, bem como para 12 bits, e iniciou um novo esforço de design de 16 bits. Isso surgiu em 1970 como o PDP-11, um design muito mais complexo que era tão diferente do PDP-X quanto o Nova. Os dois projetos competiam fortemente no mercado.
Rumores sobre o novo sistema da DEC chegaram à DG logo depois que o Nova começou a ser enviado. Na primavera de 1970, eles contrataram um novo projetista, Larry Seligman, para ultrapassar qualquer possível máquina em construção. Duas grandes mudanças ocorreram desde que o Nova foi projetado; uma delas era que a Signetics havia introduzido o 8260, um IC de 4 bits que combinava um somador, XNOR e AND, significando que o número de chips necessários para implementar a lógica básica foi reduzido em cerca de três vezes. Outra era que a Intel estava falando agressivamente sobre memórias baseadas em semicondutores, prometendo 1024 bits em um único chip e rodando em velocidades muito mais altas do que a memória principal.
O novo design de Seligman aproveitou essas duas melhorias. Para começar, os novos ICs permitiram que a ALU fosse expandida para largura total de 16 bits nos mesmos dois cartões, permitindo realizar operações matemáticas e lógicas em um único ciclo e, assim, tornar o novo design quatro vezes mais rápido que o original. Além disso, foi usada uma nova memória de núcleo menor que melhorou o tempo de ciclo dos 1.200 ns originais para 800 ns, oferecendo mais 1/3 melhoria. O desempenho pode ser melhorado ainda mais substituindo o núcleo por memória somente leitura; sem o ciclo de leitura/gravação do núcleo, isso pode ser acessado em 300 ns para um aumento dramático no desempenho.
A máquina resultante, conhecida como SuperNOVA, foi lançada em 1970. Embora os modelos iniciais ainda usassem núcleo, todo o projeto foi baseado na premissa de que memórias semicondutoras mais rápidas seriam disponibilizadas e a plataforma poderia fazer pleno uso deles. Isso foi introduzido mais tarde no mesmo ano como o SuperNOVA SC, com memória de semicondutor (SC). A memória de desempenho muito maior permitiu que a CPU, que estava sincronizada com a memória, fosse aumentada ainda mais em velocidade para executar em um tempo de ciclo de 300 ns (3,3 MHz). Isso o tornou o minicomputador mais rápido disponível por muitos anos. Inicialmente, a nova memória também era muito cara e esquentava muito, por isso não era amplamente usada.
1200 e 800
Como uma demonstração do poder de sua tecnologia de matriz de portas Micromatrix, em 1968 Fairchild criou o protótipo do 4711, uma ALU de 4 bits de chip único. O design nunca foi planejado para produção em massa e era muito caro de produzir. A introdução do Signetics 8260 em 1969 forçou sua mão; tanto a Texas Instruments quanto a Fairchild introduziram suas próprias ALUs de 4 bits em 1970, a 74181 e a 9341, respectivamente. Em contraste com o 8260, os novos designs ofereciam todas as funções lógicas comuns e reduziam ainda mais a contagem de chips.
Isso levou a DG a considerar o projeto de uma nova CPU usando esses ICs mais integrados. No mínimo, isso reduziria a CPU a uma única placa para o Nova básico ou o SuperNOVA. Um novo conceito surgiu onde um único chassi seria capaz de hospedar qualquer uma das máquinas simplesmente trocando a placa de circuito da CPU. Isso permitiria que os clientes adquirissem o sistema de custo mais baixo e atualizassem a qualquer momento.
Enquanto Seligman trabalhava no SuperNOVA, a empresa recebeu uma carta de Ron Gruner declarando "Li sobre seu produto, li seus anúncios e vou para trabalhar para você. E estarei em seus escritórios em uma semana para conversar com você sobre isso." Ele foi contratado na hora. Gruner foi encarregado da máquina de baixo custo, enquanto Seligman projetou uma versão correspondente de alto desempenho.
O modelo de baixo custo do Gruner foi lançado em 1970 como o Nova 1200, o 1200 referindo-se ao uso da memória de núcleo 1.200 ns original do Nova. Apresentava uma ALU de 4 bits baseada em um único chip 74181 e, portanto, era essencialmente um Nova reembalado. O SuperNOVA de quatro ALU reembalado de Seligman foi lançado em 1971 como o Nova 800, resultando em uma nomenclatura um tanto confusa, onde o modelo de número inferior tem desempenho superior. Ambos os modelos foram oferecidos em uma variedade de casos, o 1200 com sete slots, o 1210 com quatro e o 1220 com quatorze.
Modelos posteriores
A essa altura, o PDP-11 estava finalmente sendo enviado. Ele oferecia uma arquitetura de conjunto de instruções muito mais rica do que a deliberadamente simples do Nova. A melhoria contínua nos projetos de IC e, especialmente, em sua relação preço-desempenho, estava corroendo o valor das instruções simplificadas originais. Seligman foi encarregado de projetar uma nova máquina que fosse compatível com o Nova, oferecendo um ambiente muito mais rico para quem o desejasse. Esse conceito foi enviado como a série Data General Eclipse, que oferecia a capacidade de adicionar circuitos adicionais para adaptar o conjunto de instruções para cargas de trabalho científicas ou de processamento de dados. O Eclipse teve sucesso em competir com o PDP-11 no segmento superior do mercado.
Na mesma época, começaram a surgir rumores de uma nova máquina de 32 bits da DEC. DG decidiu que eles tinham que ter um produto similar, e Gruner foi encarregado do que se tornou o Projeto Nascente. Dado o escopo do projeto, eles concordaram que todo o esforço deveria ser realizado fora do local, e Gruner selecionou um local no Research Triangle Park, na Carolina do Norte. Esse projeto tornou-se muito complexo e acabou sendo cancelado anos depois.
Enquanto esses esforços estavam em andamento, o trabalho na linha Nova continuou.
840
O 840, oferecido pela primeira vez em 1973, também incluía um novo sistema de memória paginada que permitia endereços de até 17 bits. Um índice compensa o endereço base na memória maior de 128 kword. Na verdade, a instalação de tanta memória exigia um espaço considerável; o 840 foi enviado em uma caixa grande de 14 slots.
Nova 2
A próxima versão foi a Nova 2, com as primeiras versões lançadas em 1973. A Nova 2 era essencialmente uma versão simplificada das máquinas anteriores, pois o aumento da densidade dos chips permitia que a CPU fosse reduzida em tamanho. Enquanto o SuperNOVA usou três 15×15" placas para implementar a CPU e sua memória, o Nova 2 encaixou tudo isso em uma única placa. A ROM foi usada para armazenar o código de inicialização, que foi então copiado para o núcleo quando o "carregamento do programa" interruptor foi acionado. As versões estavam disponíveis com quatro ("2/4"), sete e dez ("2/10") slots.
Nova 3
O Nova 3 de 1975 adicionou mais dois registradores, usados para controlar o acesso a uma pilha embutida. O processador também foi reimplementado usando componentes TTL, aumentando ainda mais o desempenho do sistema. O Nova 3 foi oferecido nas versões de quatro slots (o Nova 3/4) e de doze slots (o Nova 3/12).
Nova 4
Parece que a Data General originalmente pretendia que o Nova 3 fosse o último de sua linha, planejando substituir o Nova pelas máquinas Eclipse posteriores. No entanto, a demanda contínua levou a uma máquina Nova 4, desta vez baseada em quatro ALUs AMD Am2901 bit-slice. Esta máquina foi projetada desde o início para ser o Nova 4 e o Eclipse S/140, com microcódigos diferentes para cada um. Um coprocessador de ponto flutuante também estava disponível, ocupando um slot separado. Uma opção adicional permitiu o mapeamento de memória, permitindo que os programas acessem até 128 kwords de memória usando a troca de banco. Ao contrário das máquinas anteriores, o Nova 4 não incluía um console no painel frontal e, em vez disso, contava com o terminal para emular um console quando necessário.
Havia três versões diferentes do Nova 4, o Nova 4/C, o Nova 4/S e o Nova 4/X. O Nova 4/C era uma implementação de placa única que incluía toda a memória (16 ou 32 kwords). O Nova 4/S e 4/X usavam placas de memória separadas. O Nova 4/X tinha a unidade de gerenciamento de memória (MMU) integrada habilitada para permitir o uso de até 128 kwords de memória. A MMU também foi instalada no Nova 4/S, mas foi desativada pelo firmware. Tanto o 4/S quanto o 4/X incluíam um "pré-buscador" para aumentar o desempenho buscando até duas instruções da memória antes de serem necessárias.
MicroNOVA
AData General também produziu uma série de implementações de chip único microNOVA do processador Nova. Para permitir que ele se encaixe em um chip dual in-line package (DIP) de 40 pinos, o barramento de endereço e o barramento de dados compartilham um conjunto de 16 pinos. Isso significava que as leituras e gravações na memória exigiam dois ciclos e, como resultado, a máquina funcionava com cerca de metade da velocidade da Nova original.
O primeiro chip da série foi o mN601, de 1977. Este era vendido tanto como uma CPU para outros usuários, um chipset completo para quem queria implementar um computador, um computador completo em um placa única com 4 kB de RAM e como um modelo low-end completo do Nova. Uma versão atualizada do design, mN602 de 1979, reduziu todo o chipset a um único VLSI. Isso foi oferecido em duas máquinas, a microNOVA MP/100 e a microNOVA MP/200 maior.
O microNOVA foi posteriormente reembalado com um monitor em uma caixa estilo PC com dois disquetes como o Enterprise. O Enterprise foi lançado em 1981, rodando RDOS, mas a introdução do IBM PC no mesmo ano fez com que a maioria das outras máquinas desaparecessem do radar.
Legado de Nova
O Nova influenciou o design dos computadores Xerox Alto (1973) e Apple I (1976), e sua arquitetura foi a base para a série Computervision CGP (Computervision Graphics Processor). Seu design externo foi relatado como a inspiração direta para o painel frontal do microcomputador MITS Altair (1975).
A Data General acompanhou o sucesso do Nova original com uma série de designs mais rápidos. A família de sistemas Eclipse foi posteriormente introduzida com um conjunto de instruções compatível ascendente estendido, e a série MV estendeu ainda mais o Eclipse em uma arquitetura de 32 bits para competir com o DEC VAX. O desenvolvimento da série MV foi documentado no popular livro de Tracy Kidder de 1981, The Soul of a New Machine. A própria Data General evoluiria mais tarde para um fornecedor de servidores baseados em processador Intel e matrizes de armazenamento, eventualmente sendo comprada pela EMC.
A partir de 2004 ainda havia Novas e Eclipses de 16 bits rodando em uma variedade de aplicações em todo o mundo, incluindo controle de tráfego aéreo. Há um grupo diverso, mas fervoroso, de pessoas em todo o mundo que restauram e preservam os sistemas gerais de dados originais de 16 bits.
Descrição técnica
Desenho do processador
O Nova, ao contrário do PDP-8, era uma arquitetura load-store. Ele tinha quatro registradores de acumulador de 16 bits, dois dos quais (2 e 3) podiam ser usados como registradores de índice. Havia um contador de programa de 15 bits e um registrador de transporte de um bit. Como no PDP-8, o endereçamento de página atual + zero era central. Não havia registro de pilha, mas projetos posteriores do Eclipse utilizariam um endereço de memória de hardware dedicado para essa função.
Os primeiros modelos do Nova processavam matemática em série em pacotes de 4 bits, usando uma única ALU de 74181 bits. Um ano após sua introdução, esse projeto foi aprimorado para incluir uma unidade matemática paralela completa de 16 bits usando quatro 74181s, sendo esse projeto conhecido como SuperNova. Versões futuras do sistema adicionaram uma unidade de pilha e multiplicação/divisão de hardware.
O Nova 4 / Eclipse S/140 foi baseado em quatro ALUs AMD 2901 bit-slice, com microcódigo em memória somente leitura, e foi o primeiro Nova projetado apenas para memória principal DRAM, sem provisão para memória de núcleo magnético.
Memória e E/S
Os primeiros modelos estavam disponíveis com 8 K palavras de memória de núcleo magnético como opção, que praticamente todo mundo tinha que comprar, elevando o custo do sistema para $ 7.995.
Esta placa de memória central foi organizada de maneira planar como quatro grupos de quatro bancos, cada banco carregando dois conjuntos de núcleos em uma matriz de 64 por 64; assim, havia 64 x 64 = 4096 bits por conjunto, x 2 conjuntos dando 8.192 bits, x 4 bancos dando 32.768 bits, x 4 grupos dando um total de 131.072 bits, e isso dividido pelo tamanho da palavra da máquina de 16 bits deu 8.192 palavras de memória.
O núcleo desta placa de memória de palavras de 8K ocupou um "board-on-a-board", 5,25" de largura por 6,125" alto, e foi coberto por uma placa protetora. Ele estava cercado pelos circuitos de leitura-gravação-reescrita do driver de suporte necessário. Todo o núcleo e os componentes eletrônicos de suporte correspondentes se encaixam em uma única placa padrão de 15 x 15 polegadas (380 mm). Até 32K desse núcleo de RAM podem ser suportados em uma caixa de expansão externa. A ROM semicondutora já estava disponível na época, e os sistemas sem RAM (ou seja, apenas com ROM) tornaram-se populares em muitos ambientes industriais. As máquinas Nova originais funcionavam a aproximadamente 200 kHz, mas sua SuperNova foi projetada para funcionar a até 3 MHz quando usada com memória principal de semicondutor especial.
O backplane padronizado e os sinais de E/S criaram um projeto de E/S simples e eficiente que tornou a interface de dispositivos de E/S e canal de dados programados para o Nova simples em comparação com as máquinas concorrentes. Além de sua estrutura de barramento de E/S dedicada, o backplane Nova tinha pinos de enrolamento de fio que podiam ser usados para conectores não padronizados ou outras finalidades especiais.
Modelo de programação
O formato da instrução pode ser amplamente categorizado em uma das três funções: 1) manipulação de registrador para registrador, 2) referência de memória e 3) entrada/saída. Cada instrução estava contida em uma palavra. A manipulação de registro para registro era quase como RISC em sua eficiência de bits; e uma instrução que manipulasse os dados do registrador também poderia realizar testes, deslocamentos e até mesmo optar por descartar o resultado. As opções de hardware incluíam uma unidade de multiplicação e divisão inteira, uma unidade de ponto flutuante (precisão simples e dupla) e gerenciamento de memória.
O primeiro Nova veio com um interpretador BASIC em fita perfurada. À medida que o produto crescia, a Data General desenvolveu muitas linguagens para os computadores Nova, rodando em uma variedade de sistemas operacionais consistentes. FORTRAN IV, ALGOL, Extended BASIC, Data General Business Basic, Interactive COBOL e vários montadores estavam disponíveis na Data General. Fornecedores terceirizados e a comunidade de usuários expandiram as ofertas com Forth, Lisp, BCPL, C, ALGOL e outras versões proprietárias de COBOL e BASIC.
Conjunto de instruções
As instruções de máquina implementadas abaixo são o conjunto comum implementado por todos os processadores da série Nova. Modelos específicos geralmente implementavam instruções adicionais e algumas instruções eram fornecidas por hardware opcional.
Instruções aritméticas
Todas as instruções aritméticas operadas entre acumuladores. Para operações que requerem dois operandos, um foi retirado do acumulador de origem e outro do acumulador de destino, e o resultado foi depositado no acumulador de destino. Para operações de operando único, o operando foi retirado do registrador de origem e o resultado substituiu o registrador de destino. Para todos os opcodes de operando único, era permitido que os acumuladores de origem e destino fossem os mesmos e a operação funcionasse conforme o esperado.
Todas as instruções aritméticas incluíam um "sem carga" bit que, quando definido, suprime a transferência do resultado para o registrador de destino; isso foi usado em conjunto com as opções de teste para realizar um teste sem perder o conteúdo existente do registrador de destino. Em linguagem assembly, adicionar um '#' para o opcode definir o bit sem carga.
A CPU continha um registrador de bit único chamado carry bit, que após uma operação aritmética conteria o carry out do bit mais significativo. O bit de transporte pode ser definido para um valor desejado antes de executar a operação usando um campo de dois bits na instrução. O bit pode ser definido, limpo ou complementado antes de executar a instrução. Em linguagem assembly, essas opções foram especificadas adicionando uma letra ao opcode: 'O' — definir o bit de transporte; 'Z' — limpa o bit de transporte, 'C' — complemente o bit de transporte, nada — deixe o bit de transporte sozinho. Se o bit sem carga também for especificado, o valor de transporte especificado será usado para o cálculo, mas o registro de transporte real permanecerá inalterado.
Todas as instruções aritméticas incluíam um campo de dois bits que poderia ser usado para especificar uma opção de deslocamento, que seria aplicada ao resultado antes de ser carregado no registrador de destino. Um deslocamento de um único bit para a esquerda ou para a direita pode ser especificado, ou os dois bytes do resultado podem ser trocados. Os deslocamentos eram circulares de 17 bits, com o bit de transporte "para a esquerda" do bit mais significativo. Em outras palavras, quando um deslocamento à esquerda foi executado, o bit mais significativo do resultado foi deslocado para o bit de transporte e o conteúdo anterior do bit de transporte foi deslocado para o bit menos significativo do resultado. As trocas de bytes não afetaram o bit de transporte. Em linguagem assembly, essas opções foram especificadas adicionando uma letra ao opcode: 'L' — deslocar para a esquerda; 'R' — deslocar para a direita, 'S' — trocar bytes; nada — não execute uma mudança ou troca.
Todas as instruções aritméticas incluíam um campo de três bits que poderia especificar um teste a ser aplicado ao resultado da operação. Se o teste for avaliado como verdadeiro, a próxima instrução na linha será ignorada. Em linguagem assembly, a opção de teste foi especificada como um terceiro operando para a instrução. Os testes disponíveis eram:
- SZR — pular em resultado zero
- SNR — pular em resultado nonzero
- SZC — pular na carga zero
- SNC — pular nonzero carry
- SBN — pular se ambos carregam e resultam são nonzero
- SEZ — pular se carregar ou resultar, ou ambos, é zero
- SKP — sempre pular
- Nada — nunca saltar
As instruções aritméticas reais foram:
- MOVIMENTO — mover o conteúdo do acumulador de origem para o acumulador de destino
- COMUNICAÇÃO — mover o complemento bitwise do acumulador de origem para o acumulador de destino
- ADD — adicionar acumulador de origem ao acumulador de destino
- ADC — tomar o complemento bitwise do acumulador de origem e adicioná-lo ao acumulador de destino
- NEG — mover o negativo do acumulador de origem para o acumulador de destino
- ASSUNTO — subtrair o acumulador de fonte de conteúdo do acumulador de destino
- INC — adicionar 1 ao conteúdo do acumulador de origem e mover para o acumulador de destino
- E — executar o bitwise E dos dois acumuladores e colocar o resultado no acumulador de destino
Um exemplo de instruções aritméticas, com todas as opções utilizadas, é:
ADDZR 0,2,SNC
Isso é decodificado como: limpar o bit de transporte; adicione o conteúdo de AC2 (acumulador 2) a AC0; deslocar circularmente o resultado um bit para a direita; teste o resultado para ver se o bit de transporte está definido e pule a próxima instrução se estiver. Descarte o resultado após realizar o teste. Na verdade, isso adiciona dois números e testa para ver se o resultado é par ou ímpar.
Instruções de referência de memória
O conjunto de instruções Nova continha um par de instruções que transferiam o conteúdo da memória para acumuladores e vice-versa, duas instruções de transferência de controle e duas instruções que testavam o conteúdo de um local de memória. Todas as instruções de referência de memória continham um campo de endereço de oito bits e um campo de dois bits que especificava o modo de endereçamento de memória. Os quatro modos eram:
- Modo 0 — endereçamento absoluto. O conteúdo do campo de endereço da instrução é preenchido zero na esquerda e usado como endereço de destino.
- Modo 1 — endereço relativo. O conteúdo do campo de endereço da instrução é sinal estendido à esquerda e adicionado ao valor atual do contador do programa (que, no momento em que a instrução executa, aponta para a próxima instrução). O resultado é usado como endereço de destino.
- Modo 2 — endereçamento indexado. O conteúdo do campo de endereço da instrução é sinal estendido à esquerda e adicionado ao valor atual do acumulador 2. O resultado é usado como endereço de destino.
- Modo 3 — endereçamento indexado. O conteúdo do campo de endereço da instrução é sinal estendido à esquerda e adicionado ao valor atual do acumulador 3. O resultado é usado como endereço de destino.
Obviamente, o modo 0 só foi capaz de endereçar as primeiras 256 palavras de memória, dado o campo de endereço de oito bits. Essa parte da memória era chamada de "página zero". As palavras de memória de página zero eram consideradas preciosas para os programadores da linguagem assembly Nova devido ao pequeno número disponível; somente locais de página zero podiam ser endereçados de qualquer lugar no programa sem recorrer ao endereçamento indexado, o que exigia amarrar o acumulador 2 ou 3 para usar como um registrador de índice. Em linguagem assembly, um ".ZREL" a diretiva fazia com que o montador colocasse as instruções e as palavras de dados que a seguiam na página zero; um ".NREL" A diretiva colocou as seguintes instruções e palavras de dados em "normal" memória. Os modelos Nova posteriores adicionaram instruções com campos de endereçamento estendidos, que superaram essa dificuldade (com uma penalidade de desempenho).
O montador calculou deslocamentos relativos para o modo 1 automaticamente, embora também fosse possível escrevê-lo explicitamente na fonte. Se uma instrução de referência de memória referenciou um endereço de memória no espaço.NREL, mas nenhum especificador de modo, o modo 1 foi assumido e o montador calculou o deslocamento entre a instrução atual e o local referenciado e o colocou no campo de endereço da instrução (desde que o valor resultante caiba no campo de 8 bits).
As duas instruções de carregamento e armazenamento foram:
- LDA — carregar o conteúdo de um local de memória no acumulador especificado.
- STA — armazenar o conteúdo do acumulador especificado em um local de memória.
Ambas as instruções incluíam um "indireto" pedaço. Se esse bit foi definido (feito em linguagem assembly adicionando um '@' ao opcode), o conteúdo do endereço de destino foi considerado um endereço de memória em si e esse endereço seria referenciado para fazer a carga ou loja.
As duas instruções de transferência de controle foram:
- JMP — transfere o controlo para o local de memória especificado
- JSR ("subrotina de salto") — Faz o mesmo que a instrução JMP, mas também carrega o endereço de retorno (a instrução após a instrução JSR na linha) no acumulador 3 antes de saltar.
Assim como no caso das instruções load e store, as instruções jump continham um bit indireto, que também foi especificado em assembly usando o '@' personagem. No caso de um salto indireto, o processador recuperou o conteúdo do local de destino e usou o valor como endereço de memória para onde saltar. No entanto, ao contrário das instruções load e store, se o endereço indireto tivesse o bit mais significativo definido, ele realizaria um novo ciclo de indireção. Nos processadores da série Nova anteriores ao Nova 3, não havia limite no número de ciclos de indireção; um endereço indireto que referenciasse a si mesmo resultaria em um loop de endereçamento indireto infinito, com a instrução nunca sendo concluída. (Isto pode ser alarmante para os usuários, pois nesta condição, pressionar o botão STOP no painel frontal não fazia nada. Era necessário reiniciar a máquina para quebrar o loop.)
As duas instruções de teste de memória foram:
- ISZ — incrementar o local da memória e pular a próxima instrução se o resultado for zero.
- DSZ — decrement o local da memória, e pular a próxima instrução se o resultado for zero.
Como no caso das instruções load e store, havia um bit indireto que executaria um único nível de endereçamento indireto. Essas instruções eram estranhas porque, nos Novas com memória de núcleo magnético, a instrução era executada dentro da própria placa de memória. Como era comum na época, as placas de memória continham um "write-back" circuito para resolver o problema de leitura destrutiva inerente à memória de núcleo magnético. Mas o mecanismo de write-back também continha uma miniunidade aritmética, que o processador usava para diversos propósitos. Para as instruções ISZ e DSZ, o incremento ou decremento ocorreu entre o local de memória que está sendo lido e o write-back; a CPU simplesmente esperava saber se o resultado era zero ou diferente de zero. Essas instruções eram úteis porque permitiam que um local de memória fosse usado como um contador de loop sem ocupar um acumulador, mas eram mais lentas do que executar as instruções aritméticas equivalentes.
Alguns exemplos de instruções de referência de memória:
LDA 1,PAÍSES
Transfere o conteúdo do local de memória denominado COUNT para o acumulador 1. Assumindo que COUNT está no espaço.NREL, esta instrução é equivalente a: LDA 1,1,(COUNT-(.+1)) onde '.' representa a localização da instrução LDA.
JSR@ 0,17.
Salte indiretamente para o endereço de memória especificado pelo conteúdo da localização 17, no espaço zero da página, e deposite o endereço de retorno no acumulador 3. Este era o método padrão para fazer uma chamada de sistema RDOS nos primeiros modelos Nova; o mnemônico da linguagem assembly ".SYSTM" traduzido para isso.
JMP 0,3
Salta para o local da memória cujo endereço está contido no acumulador 3. Esse era um meio comum de retornar de uma chamada de função ou sub-rotina, pois a instrução JSR deixava o endereço de retorno no acumulador 3.
STA 0,3,- Não.1
Armazene o conteúdo do acumulador 0 no local que é um a menos que o endereço contido no acumulador 3.
DSZ PAÍSES
Decremente o valor no local rotulado COUNT e pule a próxima instrução se o resultado for zero. Como no caso acima, se COUNT for assumido como estando no espaço.NREL, isso é equivalente a: DSZ 1,(COUNT-(.+1))
Instruções de E/S
Os Novas implementaram um modelo canalizado para interface com dispositivos de I/O. No modelo, esperava-se que cada dispositivo de E/S implementasse dois sinalizadores, referidos como "Ocupado" e "Concluído", e três registros de dados e controle, referidos como A, B e C. Instruções de E/S estavam disponíveis para ler e gravar os registros e enviar um dos três sinais para o dispositivo, referido como "iniciar", "limpar" e "pulsar". Em geral, enviar um sinal de início iniciava uma operação de E/S que havia sido configurada carregando valores nos registradores A/B/C. O sinal claro interrompeu uma operação de E/S e limpou qualquer interrupção resultante. O sinal de pulso foi usado para iniciar operações auxiliares em subsistemas complexos, como operações de busca em unidades de disco. Dispositivos com polling geralmente movem dados diretamente entre o dispositivo e o registrador A. Dispositivos DMA geralmente usam o registrador A para especificar o endereço de memória, o registrador B para especificar o número de palavras a serem transferidas e o registrador C para flags de controle. O canal 63 referia-se à própria CPU e era usado para várias funções especiais.
Cada instrução de E/S continha um campo de número de canal de seis bits, um de quatro bits para especificar qual registro ler ou escrever e um campo de dois bits para especificar qual sinal deveria ser enviado. Em linguagem assembly, o sinal foi especificado adicionando uma letra ao opcode: 'S' para começar, 'C' para claro, 'P' para pulso e nada para nenhum sinal. Os opcodes foram:
- DIA — mova o conteúdo do registo A do dispositivo para o acumulador especificado
- DOA — enviar o conteúdo do acumulador especificado para o registo A do dispositivo no canal especificado
- DIBRO — mova o conteúdo do registo B do dispositivo para o acumulador especificado
- DOB — enviar o conteúdo do acumulador especificado para o registo B do dispositivo no canal especificado
- DIC — mover o conteúdo do registo C do dispositivo para o acumulador especificado
- DOC — enviar o conteúdo do acumulador especificado para o registo C do dispositivo no canal especificado
- Não. — "nenhum I/O", um misnomer. A instrução foi usada para enviar um sinal para um dispositivo sem fazer uma transferência de registro.
Além disso, quatro instruções estavam disponíveis para testar o status de um dispositivo:
- SKPBN — pular a próxima instrução se a bandeira ocupada do dispositivo estiver definida
- SKPBZ — pular a próxima instrução se a bandeira ocupada do dispositivo é clara
- SKPDN — pular a próxima instrução se a bandeira feita do dispositivo for definida
- SKPDZ — pule a próxima instrução se a bandeira feita do dispositivo estiver clara
Iniciar um dispositivo fez com que ele definisse seu sinalizador de ocupado. Quando a operação solicitada foi concluída, convencionalmente, o dispositivo limpou seu sinalizador de ocupado e definiu seu sinalizador concluído; a maioria dos dispositivos tinha seu mecanismo de solicitação de interrupção conectado ao sinalizador concluído, portanto, definir o sinalizador concluído causava uma interrupção (se as interrupções estivessem ativadas e o dispositivo não estivesse mascarado).
Instruções especiais
Estas instruções executam várias funções de status e controle da CPU. Todos eles eram, na verdade, mnemônicos abreviados para instruções de E/S no canal 63, o canal de E/S autorreferencial da CPU.
- INFORMAÇÃO — o reconhecimento de interrupção. Transferiu o número de canal do dispositivo de interrupção para o acumulador especificado.
- INTRODUÇÃO — desactivar todas as interrupções
- ÍNDICE — permitir todas as interrupções
- IORSTÃO — I/O reset. Enviado um sinal de reset no ônibus I/O, que parou todo o I/O, desativado interrompe e limpou todas as interrupções pendentes.
- MSKO — mascarar. Usado o conteúdo do acumulador especificado para configurar a máscara de interrupção. Como a máscara foi interpretada foi até a implementação de cada dispositivo de E/S. Alguns dispositivos não poderiam ser mascarados.
- READS — transferiu o conteúdo dos 16 interruptores de dados do painel frontal para o acumulador especificado.
- HALT — parou a CPU. Uma vez interrompido, a CPU poderia ser feita para começar novamente apenas por intervenção manual no painel frontal.
Interrupções e tratamento de interrupções
Do ponto de vista do hardware, o mecanismo de interrupção era relativamente simples, mas também menos flexível do que as atuais arquiteturas de CPU. O backplane suportava uma única linha de solicitação de interrupção, à qual todos os dispositivos capazes de interromper se conectavam. Quando um dispositivo precisava solicitar uma interrupção, ele levantava essa linha. A CPU pegou a interrupção assim que completou a instrução atual. Conforme declarado acima, esperava-se que um dispositivo aumentasse sua taxa de "concluído" sinalizador de I/O quando solicitou uma interrupção, e a convenção era que o dispositivo limparia sua solicitação de interrupção quando a CPU executasse uma instrução de limpeza de I/O no número do canal do dispositivo.
A CPU esperava que o sistema operacional colocasse o endereço de sua rotina de serviço de interrupção no endereço de memória 1. Quando um dispositivo interrompeu, a CPU fez um salto indireto pelo endereço 1, colocando o endereço de retorno no endereço de memória 0 e desativando mais interrupções. O manipulador de interrupção executaria então uma instrução INTA para descobrir o número do canal do dispositivo de interrupção. Isso funcionou levantando um "reconhecimento" sinal no backplane. O sinal de reconhecimento foi conectado em um formato de cadeia em série através do backplane, de modo que ele passasse por cada placa no barramento. Esperava-se que qualquer dispositivo solicitando uma interrupção bloqueasse a propagação posterior do sinal de reconhecimento no barramento, de modo que, se dois ou mais dispositivos tivessem interrupções pendentes simultaneamente, apenas o primeiro veria o sinal de reconhecimento. Esse dispositivo então respondeu colocando seu número de canal nas linhas de dados do barramento. Isso significava que, no caso de solicitações de interrupção simultâneas, o dispositivo que tinha prioridade era determinado por aquele que estava fisicamente mais próximo da CPU na gaiola do cartão.
Depois que a interrupção foi processada e a rotina de serviço enviou ao dispositivo uma limpeza de E/S, ela retomou o processamento normal ativando as interrupções e retornando por meio de um salto indireto através do endereço de memória 0. Para evitar que uma interrupção pendente ocorra interrompendo imediatamente antes do salto de retorno (o que faria com que o endereço de retorno fosse sobrescrito), a instrução INTEN tinha um atraso de um ciclo de instrução. Quando foi executada, as interrupções não seriam habilitadas até que a instrução seguinte, que era esperada ser a instrução JMP@0, fosse executada.
A rotina de serviço de interrupção do sistema operacional geralmente realizava um salto indexado usando o número do canal recebido, para pular para a rotina de tratamento de interrupção específica do dispositivo. Alguns dispositivos, principalmente o circuito de detecção de falha de energia da CPU, não responderam à instrução INTA. Se o INTA retornasse um resultado igual a zero, a rotina do serviço de interrupção tinha que pesquisar todos os dispositivos que não respondessem ao INTA usando as instruções SKPDZ/SKPDN para ver qual interrompeu.
O sistema operacional poderia gerenciar um pouco a ordem das interrupções definindo uma máscara de interrupção usando a instrução MSKO. O objetivo era permitir que o sistema operacional determinasse quais dispositivos tinham permissão para interromper em um determinado momento. Quando esta instrução foi emitida, uma máscara de interrupção de 16 bits foi transmitida para todos os dispositivos no backplane. Cabia ao dispositivo decidir o que a máscara realmente significava para ele; por convenção, um dispositivo mascarado não deveria aumentar a linha de interrupção, mas a CPU não tinha como impor isso. A maioria dos dispositivos mascaráveis permitia que o bit de máscara fosse selecionado por meio de um jumper na placa. Havia dispositivos que ignoravam completamente a máscara.
Nos sistemas com memória de núcleo magnético (que retinha seu conteúdo sem energia), a recuperação de uma falha de energia era possível. Um circuito de detecção de falha de energia na CPU emitiu uma interrupção quando foi detectada a perda da energia principal que entrava no computador; a partir deste ponto, a CPU teve um curto período de tempo até que um capacitor na fonte de alimentação perdesse sua carga e a alimentação da CPU falhasse. Este foi o tempo suficiente para interromper o I/O em andamento, emitindo uma instrução IORST e, em seguida, salvar o conteúdo dos quatro acumuladores e o bit de transporte na memória. Quando a energia retornasse, se a chave do painel frontal da CPU estivesse na posição LOCK, a CPU iniciaria e executaria um salto indireto através do endereço de memória 2. Esperava-se que este fosse o endereço de uma rotina de serviço do sistema operacional que recarregaria os acumuladores e carregaria o bit e, em seguida, retomaria o processamento normal. Cabia à rotina de serviço descobrir como reiniciar as operações de E/S que foram abortadas pela falha de energia.
Layout do painel frontal
Como era a convenção da época, a maioria dos modelos Nova fornecia um console de painel frontal para controlar e monitorar as funções da CPU. Todos os modelos anteriores ao Nova 3 dependiam de um layout de painel frontal canônico, conforme mostrado na foto do painel do Nova 840 acima. O layout continha um interruptor de energia com chave, duas fileiras de lâmpadas de exibição de endereço e dados, uma fileira de interruptores de entrada de dados e uma fileira de interruptores de função que ativavam várias funções da CPU quando pressionadas. As lâmpadas de endereço sempre exibiam o valor atual do contador de programa, em binário. As lâmpadas de dados exibiam vários valores, dependendo de qual função da CPU estava ativa no momento. À esquerda da lâmpada de dados mais à esquerda, uma lâmpada adicional exibia o valor atual do bit de transporte. Na maioria dos modelos, as lâmpadas eram lâmpadas incandescentes que eram soldadas na placa do painel; a substituição de lâmpadas queimadas era uma desgraça para os engenheiros de serviço de campo da Data General.
Cada um dos interruptores de dados controlava o valor de um bit em um valor de 16 bits e, de acordo com a convenção geral de dados, eles eram numerados de 0 a 15 da esquerda para a direita. Os interruptores de dados forneciam entrada para a CPU para várias funções e também podiam ser lidos por um programa em execução usando a instrução de linguagem assembly READS. Para reduzir a confusão do painel e economizar dinheiro, os interruptores de função foram implementados como interruptores momentâneos bidirecionais. Quando uma alavanca de chave de função era levantada, ela acionava a função cujo nome estava impresso acima da chave no painel; quando a alavanca era pressionada, ativava a função cujo nome aparecia abaixo do interruptor. A alavanca do interruptor voltou para a posição neutra quando liberada.
Referindo-se à foto do Nova 840, os primeiros quatro interruptores da esquerda executaram as funções EXAMINAR e DEPÓSITO para os quatro acumuladores. Pressionar EXAMINE em um deles fazia com que o valor atual do acumulador fosse exibido em binário pelas lâmpadas de dados. Pressionar DEPOSIT transfere o valor binário representado pelas configurações atuais das chaves de dados para o acumulador.
Indo para a direita, a próxima chave era a chave RESET/STOP. Pressionar STOP fez com que a CPU parasse após concluir a instrução atual. Pressionar RESET fez com que a CPU parasse imediatamente, limpou vários registros internos da CPU e enviou um sinal de reinicialização de E/S para todos os dispositivos conectados. O botão à direita era o botão INICIAR/CONTINUAR. Pressionar CONTINUE fazia com que a CPU retomasse a execução na instrução atualmente apontada pelo contador de programa. Pressionar START transfere o valor atualmente definido nas chaves de dados 1-15 para o contador de programa e, em seguida, inicia a execução a partir daí.
Os próximos dois interruptores forneciam acesso de leitura e gravação à memória no painel frontal. Pressionar EXAMINE transferiu o valor definido nas chaves de dados 1-15 para o contador de programa, buscou o valor no local de memória correspondente e exibiu seu valor nas lâmpadas de dados. Pressionar EXAMINE NEXT incrementa o contador do programa e executa uma operação de exame naquele local de memória, permitindo que o usuário percorra uma série de locais de memória. Pressionar DEPOSIT grava o valor contido nos interruptores de dados no local de memória apontado pelo contador de programa. Pressionar DEPOSIT NEXT primeiro incrementa o contador de programa e depois deposita no local de memória apontado.
A função INST STEP fazia com que a CPU executasse uma instrução, no local do contador de programa atual, e então parasse. Uma vez que o contador do programa seria incrementado como parte da execução da instrução, isso permitia ao usuário percorrer um programa em uma única etapa. MEMORY STEP, um nome impróprio, fazia com que a CPU executasse um único ciclo de clock e parasse. Isso era de pouca utilidade para os usuários e geralmente era usado apenas pelo pessoal de serviço de campo para diagnósticos.
PROGRAM LOAD era o mecanismo normalmente usado para inicializar um Nova. Quando esse switch foi acionado, ele fez com que a ROM de inicialização de 32 palavras fosse mapeada nas primeiras 32 palavras da memória, definisse o contador do programa como 0 e inicializasse a CPU. A ROM de inicialização continha um código que lia 256 palavras (512 bytes) de código de um dispositivo de E/S selecionado para a memória e então transferia o controle para o código de entrada. Os interruptores de dados 8-15 foram usados para informar à ROM de inicialização de qual canal de E/S inicializar. Se a chave 0 estivesse desligada, a ROM de inicialização assumiria que o dispositivo era um dispositivo de polling (por exemplo, o leitor de fita de papel) e executaria um loop de entrada de polling até que 512 bytes fossem lidos. Se a chave 0 estiver ligada, a ROM de inicialização assumirá que o dispositivo é compatível com DMA e iniciará uma transferência de dados DMA. A ROM de inicialização não era inteligente o suficiente para posicionar o dispositivo antes de iniciar a transferência. Isso foi um problema ao reiniciar após uma falha; se o dispositivo de inicialização fosse uma unidade de disco, suas cabeças provavelmente teriam sido deixadas em um cilindro aleatório. Eles tiveram que ser reposicionados no cilindro 0, onde o RDOS escreveu o bloco de inicialização de primeiro nível, para que a sequência de inicialização funcionasse. Convencionalmente, isso era feito alternando a unidade por meio de sua sequência de carregamento, mas os usuários que ficaram frustrados com o tempo de espera (até 5 minutos, dependendo do modelo da unidade) aprenderam como inserir no painel frontal uma unidade "recalibrar" código de E/S e passo único da CPU através dele, uma operação que levou apenas alguns segundos para um usuário experiente.
O interruptor de energia era um interruptor de 3 vias com as posições marcadas OFF, ON e LOCK. Na posição OFF, toda a energia foi removida da CPU. Girar a chave para ON aplicava energia à CPU. No entanto, ao contrário das CPUs atuais, a CPU não inicializou automaticamente quando a alimentação foi aplicada; o usuário tinha que usar PROGRAM LOAD ou algum outro método para iniciar a CPU e iniciar a sequência de inicialização. Girar a chave para LOCK desativou as chaves de função do painel frontal; girando a chave para LOCK e removendo a chave, o usuário pode tornar a CPU resistente a adulterações. Em sistemas com memória de núcleo magnético, a posição LOCK também habilitava a função de recuperação automática de falha de energia. A chave pode ser removida nas posições OFF ou LOCK.
Desempenho
O Nova 1200 executou as instruções de acesso à memória central (LDA e STA) em 2,55 microssegundos (μs). O uso de memória somente leitura economizou 0,4 μs. As instruções do acumulador (ADD, SUB, COM, NEG, etc.) levaram 1,55 μs, MUL 2,55 μs, DIV 3,75 μs, ISZ 3,15-4,5 μs. No Eclipse MV/6000 posterior, LDA e STA levavam 0,44 μs, ADD etc.
Exemplos de linguagem de montagem
Olá, programa mundial
Este é um exemplo mínimo de programação em linguagem assembly Nova. Ele é projetado para rodar em RDOS e imprime a string “Hello, world”. no console.
; um programa "olá, mundo" para Nova execução RDOS ; usa a chamada do sistema PCHAR Não. Olá. Não. . início início: Dochar: Ida. 0,@Pmsg ; carregar ac0 com o próximo caractere, Mov! 0,0,Snr ; teste ac0; pular se nonzero (não carregar resultado) O que foi? feito. .systm . ; imprimir primeiro O que foi? e ; pulou se OK Movs 0,0 ; bytes de swap .systm . ; imprimir segundo O que foi? e ; pulou se OK O que é? Pmsg ; apontar para o próximo personagem O que foi? do pomar ; ir ao redor novamente feito: .systm ; saída normal . er: .systm ; saída de erro Não. Parem! Pmsg: .+1 ; ponteiro para o primeiro caractere de string ; os bytes de nota são embalados direito à esquerda por padrão ; denota um par CR LF. Não. /Olá., mundo.<15> <12> 0 ; palavra da bandeira para terminar string .end início
Multiplicação de 16 bits
Os modelos básicos do Nova vieram sem capacidade de multiplicação e divisão de hardware integrado, para manter os preços competitivos. A rotina a seguir multiplica duas palavras de 16 bits para produzir um resultado de palavra de 16 bits (o estouro é ignorado). Ele demonstra o uso combinado de ALU op, shift e test (skip). Observe que quando esta rotina é chamada por jsr
, AC3 contém o endereço de retorno. Isso é usado pela instrução de retorno jmp 0,3
. Uma maneira idiomática de limpar um acumulador é sub 0,0
. Outras instruções únicas podem ser organizadas para carregar um conjunto específico de constantes úteis (por exemplo, -2, -1 ou +1).
Mpy:; multiplicar AC0 <- AC1 * AC2, por Toby Thain sub 0,0; resultado claro Mbit:Movz 1,1,- Sim.; multiplicador de turno, teste lsb Adicionar 2,0; 1: adicionar multiplicador Movzl 2,2,Szr; turno e teste para zero O que foi? Mbit; não zero, faça outro pouco O que foi? 0,3; retorno
Acumulador de impressão binário
A rotina a seguir imprime o valor de AC1 como um número binário de 16 dígitos no console RDOS. Ele revela mais peculiaridades do conjunto de instruções Nova. Por exemplo, não há nenhuma instrução para carregar um arquivo "imediato" valor em um acumulador (embora as instruções de referência de memória codifiquem tal valor para formar um endereço efetivo). Os acumuladores geralmente devem ser carregados de locais de memória inicializados (por exemplo, n16
). Outras máquinas contemporâneas, como o PDP-11, e praticamente todas as arquiteturas modernas, permitem cargas imediatas, embora muitas, como o ARM, restrinjam a faixa de valores que podem ser carregados imediatamente.
Como a macro de chamada .systm
do RDOS implementa um jsr
, o AC3 é substituído pelo endereço de retorno da função .pchar
. Portanto, um local temporário é necessário para preservar o endereço de retorno do chamador dessa função. Para uma rotina recursiva ou reentrante, uma pilha, hardware se disponível, software se não, deve ser usado em seu lugar. A instrução de retorno torna-se jmp @ retrn
que explora o modo de endereçamento indireto do Nova para carregar o PC de retorno.
As definições de constantes no final mostram dois recursos do montador: a raiz do montador é octal por padrão (20 = dezesseis) e as constantes de caracteres podem ser codificadas como, por exemplo, "0.
Pbin: ; imprimir AC1 no console como 16 dígitos binários, por Toby Thain Estatística 3,retificado ; salvar addr de retorno Ida. 2,n16 ; configurar o contador de bits loop: Ida. 0,O que foi? ; carga ASCII '0' Movzl 1,1,- Sim. ; get next bit in carry inc 0,0 ; esbarra para '1' .systm . ; AC0-2 preservado O que foi? Erro ; se erro inc 2,2,Szr ; contador de choque O que foi? loop ; loop novamente se não zero Ida. 0,- Sim. ; produzir um espaço .systm . O que foi? Erro ; se erro O que foi? @retificado - Sim. " É um espaço Não. "0" n16: -20 Retrn: 0
Aplicativos
A Canadian Broadcasting Corporation em Montreal usou o Nova 1200 para automação de reprodução de canais até o final dos anos 1980. Foi então substituído por unidades Nova 4 remodeladas e estas estiveram em uso até meados da década de 1990.
Contenido relacionado
Byte
KAB-500L
ESCALÃO