
Emulador de PDP-11/34 a nível de circuito
O ll/34 é um emulador em nível de circuito para o PDP-11/34A (1976), executando uma CPU virtual com engenharia reversa a partir dos esquemas, microcódigo e capturas lógicas de um PDP-11/34A real.
Foi originalmente projetado como uma réplica digital da CPU real para auxiliar na solução de problemas a nível de sinal. A CPU virtual KD11-EA consiste essencialmente em uma tradução em C dos esquemas e consultas às tabelas ROM. Todos os ROMs combinacionais foram obtidos por engenharia reversa, e o gerador de clock é modelado com precisão.
O nível de circuito (tabelas verdade ROM + lógica combinacional) foi escolhido em vez do nível de portas (Verilog) porque é suficientemente de baixo nível para reproduzir bugs de hardware, mas rápido o suficiente para executar programas.
Todos os dispositivos são conectados ao backplane UNIBUS (unibus.c), que realiza decodificação de endereços, temporização e ciclos de barramento.
Internamente, a CPU é composta pelos seguintes componentes:
| Arquivo | Descrição |
|---|---|
ucode_rom.h | Armazenamento de microcódigo de 512x48 bits (PROMs bipolares), baseado no Verilog e dumps do Bitsavers. Cada micro-palavra controla a ULA, scratchpad, interface de barramento e ramificação para um micro-ciclo. |
combo_roms.h | ROMs combinacionais (E51-E83, E107), decodificação IR (E59/E60/E63/E69/E70/E71/E74), seleção de função da ULA (E61/E82/E83), prioridade de trap/serviço (E52/E53) e lógica de código de condição (E68/E107), todos reconstituídos a partir dos esquemas e capturas lógicas. ROMs de coletor aberto fazem OR com fio no barramento MPC. |
kd11ea.c | Mecanismo do caminho de dados. Percorre o microcódigo um micro-palavra por ciclo. Portas 74xx básicas são simuladas usando operadores lógicos C (!, &&, >> etc.). A ULA bit-slice 74S181 é totalmente modelada (4 fatias, 16 bits). |
mmu.c | Gerenciamento de memória. Espaços de endereço kernel/usuário, relocação de 18 bits (3 somadores 74S283), 16 pares PAR/PDR, registradores de aborto SR0/SR2 com lógica de congelamento. |
clockgen.c | Gerador de clock. Modela a linha de atraso E106 (feedback TAP 30/90/120, barramento TRAN INH). Ciclos curtos: 180 ns, ciclos longos: 240 ns, transferências de barramento se estendem até o retorno SSYN. |
clock.c | Controle em tempo real. Mantém o tempo simulado sincronizado com o tempo real. |
int.c | Árbitro de interrupção. Fila de prioridade BR4-BR7, aproxima a ordem de concessão da cadeia de margaridas UNIBUS. |
Emula os interruptores e indicadores do painel frontal do PDP-11/34A. Ativo quando a CPU está parada (inicialização, instrução HALT ou Ctrl-P).
Permite inicializar o barramento, inicializar a CPU, executar passo a passo o código, examinar e depositar dados em endereços arbitrários e sair do emulador.
O frontend é desacoplado do mecanismo, portanto uma GUI de painel frontal fotorrealista também é fornecida em WebAssembly.
O Console de Depuração fornece um depurador interativo para código tanto em nível de microcódigo quanto de instrução:
s [n]: executar passo a passo n micro-instruções com dump completo de estado (MPC, ULA, barramento, registradores)b addr: definir breakpoint de PC (octal), bl para listar, bd n para deletarg: retomar execuçãou [addr] [n]: desmontar instruçõesc [addr] [n]: dump de memória (octal)mmu: mostrar estado da MMU (PAR/PDR do kernel e usuário, modo atual marcado)r: dump de registradoresSolucionar problemas do ll-34 durante seu desenvolvimento mostrou-se tão semelhante a solucionar problemas do hardware real que um analisador lógico interno foi implementado para rastrear os sinais e sondar o caminho de dados. Isso foi fundamental para encontrar bugs sutis de ROM e temporização na CPU virtual. Também pode ser usado como referência para solucionar problemas do hardware real, assim como o hardware funcional ajudou a desenvolver o emulador.
O analisador lógico permite a sondagem de 102 pontos nos principais sinais da CPU, mapeados para pinos físicos do chip (notação KD1:Exx:pin correspondente aos esquemas DEC K1-5 a K2-9). Aliases lógicos (MPC, ALU_OUT, IR, PSW…) são fornecidos por conveniência.
A taxa de amostragem é o clock da CPU em tempo real (5.555.556 Hz) com resolução de 180 ns por amostra. Um divisor configurável reduz a taxa de amostragem para janelas de captura mais longas.
As capturas usam um buffer circular (até 64K amostras) com trigger configurável em qualquer sinal, posição do trigger ajustável (proporção pré/pós) e exportação CSV para análise offline.
Capturas lógicas foram amplamente utilizadas ao longo do projeto para mapear e depurar caminhos de multiplexação mal compreendidos.
O ll-34 vem com alguns programas e sistemas para testar: um Game of Life, V6 UNIX, RT-11 V4 com o jogo Tetris original e ATTN/11, um pequeno Transformer treinável com autoatenção.
./ll-34 --rk ./wasm/demos/rtv4_rk.dsk
A ROM de boot carregará automaticamente do RK11 e iniciará o sistema operacional. DIR listará arquivos, HELP imprimirá ajuda, RUN TETRIS iniciará a demo do Tetris (embora o $TERM provavelmente esteja errado?). RUN ADVENT iniciará o Colossal Cave Adventure, construído em um PDP-11/34 real.
./ll-34 --rk ./wasm/demos/v6bin.rk
O bootloader exibirá um prompt @ mínimo. Digite rkunix e pressione Enter; alguns segundos depois você deverá obter um prompt login:. Digite o nome de usuário root sem senha e pronto! Uma observação: cd se chama chdir no Unix antigo.
make + um compilador C11, não há outras dependências.
Verificado que compila sem avisos no Linux (x86_64 e aarch64) com musl e glibc, macOS aarch64 e NetBSD 10 aarch64.
Além da CLI, uma versão WebAssembly independente com uma GUI fotorrealista está disponível aqui: https://dbrll.github.io/ll-34.
Nota: o ll-34 é um emulador intensivo em recursos. Ao contrário de emuladores em nível de instrução, ele percorre o microcódigo um ciclo de cada vez e executa a ULA, ROMs combinacionais, scratchpad, gerador de clock e temporização do barramento a cada passo. O host deve sustentar a velocidade de 5,5 MHz do gerador de clock continuamente para permanecer preciso em termos de ciclo.
Na inicialização, o emulador fará um benchmark de si mesmo e reportará sua velocidade em relação a um KD11-EA real. Uma proporção abaixo de 1x significa que o host não consegue acompanhar e a precisão da temporização não é garantida. O benchmark não está disponível na versão WebAssembly, onde a resolução do timer do navegador o torna não confiável. Como a compilação WASM é mais lenta que a nativa, executá-la em um smartphone normalmente será muito lento.