Diagrama em blocos do Odyssey
O sistema gira em torno do microcontrolador 8048 (com 1K de ROM e 64 B de RAM internos), alimentado por um clock mestre de 7,151222 MHz. Três barramentos interligam os componentes principais: dados, endereços e controle.
O VDC recebe seu clock dividindo o clock mestre por 2 (3,575611 MHz). O sinal de vídeo passa pelo codificador de cor e pela chave PAL, sendo combinado com o som no modulador de RF.
# Processador
O Odyssey é baseado no microcontrolador 8048 da Intel. O 8048 funciona com um clock de aproximadamente 5,36 MHz, internamente dividido por 3 para gerar um "ciclo de estado" de 1,78 MHz, e depois por 5 para produzir um "ciclo de instrução" de 0,357 MHz. Isto não é tão lento quanto parece, pois cada instrução do 8048 consome apenas 1 ou 2 ciclos (veja o Apêndice A).
- 64 bytes de RAM interna
- 1K de ROM interna, contendo a rotina chamada de "Executivo" (veja a seção 7.0)
- 2 portas de E/S de 8 bits cada
- Um barramento de dados
- Um temporizador/contador interno
- Uma entrada de interrupção
- Duas entradas de um único bit que podem ser testadas (T0 e T1)
Ao ser ligado ou resetado, todas as portas de saída são colocadas em 1.
O 8048 usa a arquitetura Harvard modificada, com memória de dados separada da memória de instruções, embora a memória de programa possa ser acessada como dados.
Ele pode acessar diretamente até 4K de memória de programa através de 12 linhas de endereço. Durante operações com memória de programa externa, o 8048 coloca ALE em 1 e gera os 8 bits menos significativos no barramento de dados (DB0–DB7) e os 4 bits mais significativos em P20–P23. Dois latches de 8 bits (74LS175) guardam o endereço quando ALE passa para 0, e então o 8048 coloca ~PSEN em 0 para habilitar a memória externa no barramento de dados.
# Porta de E/S 1
Todos os pinos (P10–P17) desta porta são saídas. A função de cada pino segue:
| Pino | Função |
|---|---|
| P10 | Chave de seleção de banco 0. Seleciona entre os bancos de um cartucho com 2 bancos de 2K (4K); é o bit menos significativo para selecionar bancos num cartucho de 4 bancos de 2K (8K). |
| P11 | Chave de seleção de banco 1. Bit mais significativo para selecionar bancos num cartucho de 4 bancos. |
| P12 | Habilitar varredura do teclado. Colocar em 0 habilita a saída da varredura de teclado. |
| P13 | Habilitar controlador de vídeo (VDC). Em 0, habilita o VDC no barramento para operações com memória externa. |
| P14 | Habilitar RAM externa. Em 0, habilita a RAM externa no barramento para operações com memória externa. |
| P15 | Não conectado. |
| P16 | Habilitar modo de cópia. Em 0, habilita a cópia da RAM externa para o VDC (também exige P13 e P14 em 0). As leituras vêm da RAM externa e as escritas vão ao VDC, facilitando copiar dados. |
| P17 | Habilitar luminância. Em 1, habilita a saída de luminância do 8244 para a entrada do codificador de cor. |
# Porta de E/S 2
A segunda porta de E/S é usada para ler o teclado e o joystick. As portas P20…P23 também são usadas como os 4 bits superiores do barramento de endereço (os oito bits inferiores vão no barramento de dados). Esses 4 bits são mantidos mesmo depois que ALE vai para zero, então não é possível fazer varredura do teclado a partir de memória de programa externa.
| Pino | Direção | Função |
|---|---|---|
| P20…P22 | Saída | Selecionar a linha do teclado a varrer. Leva uma das linhas ao nível baixo (seção 5.0). Escrever 0 também habilita o joystick 2 no barramento de dados; escrever 1 habilita o joystick 1 (seção 6.0). |
| P23 | — | Não usado. |
| P24 | Entrada | Indicador de tecla pressionada. Um 0 indica que há uma tecla pressionada na linha selecionada. |
| P25…P27 | Entrada | Leitura de colunas do teclado. Se P24 for 0, esses 3 bits contêm o número da coluna da tecla pressionada. |
# Cartucho
O conector de cartucho do Odyssey possui 2 fileiras de 15 contatos cada, com distância de 150 milésimos de polegada. A especificação do conector é EDAC 307-030-520-208. A porta do cartucho também serve como porta de expansão para o módulo The Voice ou o cartucho de Xadrez, por exemplo.
Os pinos da fileira superior não usam as letras G, I, O e Q como identificação.
Conexão entre o 8048 e o conector do cartucho
| 8048 | Cartucho | Observação |
|---|---|---|
| DB0–DB7 | D0–D7 | Barramento de dados (direto) |
| ALE + latches 74I75 | A0–A7 | 8 bits inferiores travados pelos latches |
| P20–P23 | A8–A11 | 4 bits superiores do endereço |
| P10 / P11 / P14 | P10 / P11 / P14 | Seleção de banco / controle |
| P16 + ~WR/~RD (lógica) | ~CS / ~WR | Geração de chip-select e escrita |
| ~PSEN | ~PSEN | Program Store Enable |
| T0 | T0 | Entrada testável |
# Cartucho de 2K
O cartucho contém um chip de memória de 2K. Para aparecer ao processador a partir do endereço 400h, o A10 da memória é conectado ao sinal A11 do processador. Um efeito colateral disso é que o conteúdo de 800h–BFFh se repete em C00h–FFFh.
2.1.1 — Cartuchos Nacionais de 2K
# Cartucho de 4K
O cartucho é dividido em 2 páginas de 2K, totalizando 4K. O barramento de dados é conectado diretamente, e o de endereços utiliza A11 como A10, mapeando a ROM nos endereços 400h–BFFh. Ao acessar C00h–FFFh, aparece o mesmo conteúdo de 800h–BFFh. O pino P10 seleciona qual banco de 2K é usado:
2.2.1 — Cartuchos Nacionais de 4K
E os estratégicos:
# Cartucho de 8K
O cartucho é dividido em 4 páginas de 2K, totalizando 8K. O barramento de dados é direto e o de endereços usa A11 como A10, permitindo acesso a 4 páginas mapeadas entre 400h–BFFh. Os endereços C00h–FFFh são uma cópia de 800h–BFFh. Os pinos P10 e P11 selecionam a página (lembrando que ao inicializar o 8048, P10 = P11 = 1):
2.3.1 — Cartuchos Nacionais de 8K
# Cartucho de 12K
O cartucho na verdade possui 16K, mapeados em 4 páginas de 4K. Mas como o 8048 "bloqueia" o primeiro 1K de memória de programa, só podem ser usados 3K em cada página, totalizando 12K. O programa deve estar gravado nas páginas a partir de 400h, 1400h, 2400h e 3400h — os endereços 000h–400h não podem ser usados.
2.4.1 — Cartuchos de 12K
O único cartucho que utiliza este mapeamento é o Kill The Attacking Aliens, de Sören Gust.
# Cartucho de 3+1K
Este tipo de circuito é usado nos cartuchos europeus Videopac 31 (Musician) e Videopac 40 (4 in 1 Row). Possui 4K ao todo: 3K ficam mapeados nos endereços 400h–FFFh, e mais 1K que é acessado em blocos de 128 bytes como se fosse memória de dados, usando a instrução MOVX.
# Videopac+ e troca de bancos
Um cartucho geralmente usa: GND, +5V (energia), DB0…DB7 (dados), ~PSEN (em 0 indica leitura de memória de programa — habilita o cartucho), e A0…A9, A11 (endereço). Observe que A10 normalmente não é usado: a ROM interna ocupa $000–$3FF; como o primeiro byte do cartucho está em $400, desconectar A10 e usar A11 mapeia esse endereço para o primeiro byte do cartucho.
Para cartuchos de 4K, P10 seleciona entre os bancos; para 8K, P10 e P11 selecionam os 4 bancos. Existem rotinas na ROM interna que selecionam bancos e saltam automaticamente para $408 após alterar a porta 1:
| Endereço | Ação |
|---|---|
| $37F | Ajusta P10 em 0 |
| $383 | Ajusta P11 em 0 |
| $387 | Ajusta P10 e P11 em 0 |
| $38B | Ajusta P10 e P11 em 1 |
Ao alterar P10/P11 dentro do próprio cartucho com ORL P1 ou ANL P1, o Program Counter não muda, então a execução continua no endereço seguinte. É prática comum colocar um NOP após a instrução — tanto no banco de saída quanto no de chegada — para dar tempo da porta 1 estabilizar antes de buscar a próxima instrução.
# RAM Externa
Além da RAM interna do processador, existem 128 bytes de RAM externa. Para habilitá-la, ajuste P14 em 0 e P13 em 1. A memória pode ser lida e escrita usando a instrução MOVX do 8048.
# VDC — Controlador do Display de Vídeo
O chip VDC 8244 é exclusivo da Intel e gera todos os sinais de áudio e vídeo do Odyssey. Nos Videopacs europeus é usada a versão PAL, o 8245, que funciona de maneira semelhante mas com frequências ligeiramente diferentes.
O VDC recebe um clock obtido dividindo o clock mestre de 7,151222 MHz por 2, resultando em 3,575611 MHz. Diferente de outros chips da época, o 8244/8245 considera tanto a passagem do clock de 1→0 quanto de 0→1, trabalhando efetivamente ao dobro da velocidade do sinal de clock entregue.
O processador acessa o VDC como memória externa, colocando P13 em 0 e P14 em 1, usando a mesma instrução MOVX da RAM externa. O VDC ocupa os endereços externos $00–$FF.
Duas rotinas do Executivo ativam/desativam a saída de objetos gráficos:
- ENABLE — $127 — habilita os objetos e as interrupções externas do 8048.
- DISABL — $11C — desativa o display; também habilita as interrupções.
# A imagem de TV
Uma imagem de TV é gerada por um feixe de elétrons que atinge uma camada de fósforo dentro do tubo, produzindo brilho conforme a intensidade do feixe. O feixe é desviado magneticamente pelas bobinas de deflexão para iluminar pontos diferentes da tela, em varredura sequencial — de cima à esquerda até embaixo à direita.
Como as bobinas não conseguem mover o feixe instantaneamente, há os movimentos de "retorno" (com o feixe desligado): o intervalo horizontal (Horizontal Blanking) e o intervalo vertical (Vertical Blanking). A persistência da visão na retina faz o olho enxergar a imagem completa de uma vez.
A imagem foi especificada com 525 linhas, divididas em 2 campos de 262,5 linhas, transmitidos sequencialmente (entrelaçamento). As frequências:
| Parâmetro | Valor |
|---|---|
| Quadros por segundo | 30 Hz |
| Campos por segundo (varredura vertical) | 60 Hz |
| Linhas por campo (varredura horizontal) | 262,5 → 15,75 kHz |
| Duração de uma linha de varredura | 63,49 µs (10,9 µs de intervalo horizontal) |
No Odyssey, o processador demora 2,79 µs por ciclo de instrução, então executa no máximo 22,75 ciclos de instrução por linha (o intervalo horizontal dura ~4 ciclos). O intervalo vertical equivale a 22 linhas (1,396 ms), ou 500 ciclos de instrução.
Sistema europeu (PAL): 25 quadros / 50 campos, 312,5 linhas por campo e 25 linhas de intervalo vertical → 25,3 ciclos por linha e 632 ciclos no intervalo vertical.
O VDC gera todos os sinais de sincronismo para vídeo composto. O Odyssey² americano gera em NTSC, os europeus em PAL ou SECAM, e o brasileiro em PAL-M.
# Cor de fundo
O Odyssey permite selecionar a cor de fundo entre as 8 cores primárias, salvando o valor desejado no registrador de cor em $A3 (SVCOLR). Veja a tabela no Apêndice B.
A cor de fundo pode ser alterada durante a varredura, sem desativar o vídeo, desde que a alteração não ocorra no meio de uma linha (para evitar cintilação). Como o clock do processador não é múltiplo da frequência horizontal, a posição horizontal exata varia num ciclo que dura 4 campos. Vários jogos usam este recurso para mudar a cor de fundo no meio da tela durante o intervalo horizontal.
# Objetos gráficos
Além da cor de fundo, o VDC pode gerar 4 tipos de objetos gráficos:
| Tipo | Quantidade | Descrição |
|---|---|---|
| Grade de fundo | 1 | Grade de caixas com 8 linhas × 9 colunas |
| Caracteres individuais (objetos maiores) | 12 | Baseados em ROM de 64 caracteres |
| Caracteres quádruplos (objetos maiores quádruplos) | 4 | Grupos de 4 caracteres |
| Sprites (objetos menores) | 4 | Matriz de 8×8 pixels de uma cor |
Em condições normais, esses objetos só devem ser alterados durante o intervalo vertical, mas com cuidado podem ser alterados no meio da tela, aumentando a quantidade de objetos disponíveis.
4.2.1 — Grade de fundo
A grade de fundo é uma grade de caixas com 8 linhas e 9 colunas. Cada segmento de cada linha pode ser ligado/desligado individualmente. Os registradores de controle:
| Endereços | Nome | Função |
|---|---|---|
| $C0–$C8 | SVGRIH | Linhas horizontais da grade. Cada byte = uma coluna (da esquerda). O bit 0 corresponde à primeira linha de cima; o bit 7, à oitava. |
| $D0–$D8 | SVGRIB | Nona linha horizontal (a última de baixo). Cada byte = uma coluna; o bit 0 é o segmento, da esquerda à direita. Bits 1–7 ignorados. |
| $E0–$E9 | SVGRIV | Segmentos verticais. Cada posição = uma das dez linhas verticais; cada bit = um segmento (bit 0 em cima, bit 7 embaixo). |
A cor da grade é controlada por $A3 (SVCOLR), podendo ter luminância normal ou mais brilhante. A grade — assim como uma grade de pontos nas interseções — pode ser ativada por bits no registrador de controle $A0 (SVCTRL).
4.2.2 — Caracteres individuais (Objetos Maiores)
O VDC posiciona até 12 caracteres independentes, baseados no conjunto de 64 caracteres da ROM interna do VDC (veja o Apêndice D). As posições $10–$3F controlam posição e cor, em blocos de 4 bytes: o 1º caractere usa $10–$13, o 2º usa $14–$17, etc.
A ROM interna é chamada de LSS (Linear Select Store). O valor do ponteiro LSS = 8 × código do caractere + (Y / 2). Alterando-o, é possível exibir só as primeiras linhas de um caractere. A rotina LSSCAL do Executivo calcula esse ponteiro.
Bytes de controle de um caractere
O bit 0 é o nono bit do ponteiro LSS; os bits 1–3 (R/G/B) definem a cor do caractere.
4.2.3 — Caracteres quádruplos (Objetos Maiores Quádruplos)
Funcionam como os caracteres normais, mas são exibidos em grupos de 4. Usam a faixa $40–$7F, com 16 bytes para cada caractere quádruplo (4 bytes para cada um dos 4 caracteres, com as mesmas funções). A diferença: a posição X e Y do último caractere determina a posição do conjunto inteiro. Cada caractere é posicionado um após o outro, com um espaço em branco entre eles.
4.2.4 — Sprites (Objetos Menores)
O VDC desenha 4 sprites totalmente independentes. Cada um é uma matriz de 8×8 pixels de uma só cor, livremente posicionável. Os registradores de controle ficam em $00–$0E e o bitmap em $80–$9F.
Bytes de controle (3 bytes por sprite)
- Bit X9 (X8): em 1, desloca o sprite meio pixel para a direita. Se S também estiver em 1, desloca só nas linhas ímpares.
- Bit S (Smoothing): em 1, desloca meio pixel para a direita nas linhas pares.
- Bit D: dobra o tamanho do sprite.
- Bits R, G, B: especificam a cor do sprite.
- Os bits 6 e 7 não são usados.
Endereços dos registradores
| Sprite | Controle | Bitmap |
|---|---|---|
| 1 | $00–$02 SVMIN1 | $80–$87 SVMIP1 |
| 2 | $04–$06 SVMIN2 | $88–$8F SVMIP2 |
| 3 | $08–$0A SVMIN3 | $90–$97 SVMIP3 |
| 4 | $0C–$0E SVMIN4 | $98–$9F SVMIP4 |
Cada sprite tem 8 bytes de desenho: cada byte é uma linha, cada bit é uma coluna (1 = aceso, 0 = apagado). Devido à forma como o vídeo é gerado, os sprites são invertidos da esquerda para a direita. Exemplos de padrões aparecem em jogos como Conflito Cósmico, Come-Come e Senhor das Trevas.
Editor de sprite · do bitmap ao pixel
Os desenhos abaixo são reconstruções ilustrativas no formato de 8 bytes (SVMIP), feitas para demonstrar como o VDC interpreta o bitmap — não são os dados originais da ROM. Clique nos pixels para editar, escolha uma cor da paleta de sprites e observe os 8 bytes em $80–$87 mudarem em tempo real. O botão espelhar mostra a inversão horizontal que o hardware aplica na tela.
A ordem segue SVMIP: byte de $80 = linha de cima → $87 = linha de baixo. Cada bit, do 7 ao 0, é uma coluna da esquerda para a direita (antes do espelhamento).
# Registradores de controle e status do VDC
| Endereço | Nome | Função |
|---|---|---|
| $A0 | SVCTRL | Registrador de controle do VDC |
| $A1 | SVSTAT | Registrador de status do VDC |
| $A2 | SVOVST | Registrador de colisão do VDC |
| $A3 | SVCOLR | Registrador de cor do VDC |
| $A4 | SVYSTR | Posição vertical da varredura |
| $A5 | SVXSTR | Posição horizontal da varredura |
4.3.1 — SVCTRL · Controle $A0
- Bit 0: habilitar interrupções no blanking horizontal.
- Bit 1: em 1, aciona os latches de posição, travando SVYSTR e SVXSTR.
- Bit 2: habilitar interrupção de som (sinalizada no bit 2 do status).
- Bit 3: em 1, ativa a grade.
- Bit 4: permitir sobreposição externa (não usado no Odyssey).
- Bit 5: habilita os objetos maiores e menores. Os dados de objeto não podem ser alterados enquanto estiver em 1.
- Bit 6: habilita a grade de pontos.
- Bit 7: modo de preenchimento da grade (em 1, o quadrado à direita das linhas verticais ativas é preenchido).
4.3.2 — SVSTAT · Status $A1
- Bit 0: 0 = blanking horizontal ativo, 1 = varredura horizontal ativa.
- Bit 1: status dos latches de posição: 0 = acionando, 1 = seguir feixe.
- Bit 2: interrupção de som (fim dos dados do registrador de deslocamento).
- Bit 3: normalmente 0; fica em 1 nos primeiros 40 µs de VBLANK.
- Bits 4–5: não usados.
- Bit 6: sobreposição de VDC externo (não usado no Odyssey).
- Bit 7: sobreposição de objetos maiores. Fica em 1 quando um ou mais objetos maiores estão sobrepostos.
4.3.3 — SVOVST · Colisão $A2
| N1–N4 | Objetos menores 1 a 4 (sprites) |
| VG | Grade vertical |
| HG | Grade horizontal e grade de pontos |
| EX | Colisão externa (gráficos de fundo do Videopac G7400 — não lançado no Brasil) |
| MA | Objetos maiores |
Para verificar colisões com certos objetos, escreva 1 nos bits correspondentes no início do frame. Ao ler no intervalo vertical, as colisões aparecem como 1 no local correspondente. Exemplo: para checar colisões do sprite 1, escreva $01 em $A2; após gerar o vídeo, releia $A2 — retornará 1 para cada objeto que o sprite 1 atingiu.
4.3.4 — SVCOLR · Cor $A3
- Bits 0–2 (GB/GG/GR): cor da grade.
- Bits 3–5 (BB/BG/BR): cor de fundo.
- Bit 6 (GL): luminância de fundo (0 = normal, 1 = mais claro).
4.3.5 — SVYSTR / SVXSTR · Posição da varredura $A4 / $A5
Os registradores $A5 e $A4 são, respectivamente, as posições X e Y da varredura do VDC. Quando o bit 1 de $A0 é ajustado em 1, o conteúdo desses registradores é congelado.
# Interrupções de linha
Em operação normal, os registradores de vídeo só devem ser alterados durante o intervalo vertical, mas podem ser alterados durante o desenho da tela (com restrições) para criar efeitos. Para sincronizar essas mudanças, usam-se interrupções de linha.
O 8048 possui um contador interno conectado ao sinal de blanking do VDC. No fim de cada blanking horizontal, o contador é incrementado; quando passa de $FF e volta a $00, gera uma interrupção de temporizador/contador, desviando para o endereço $007.
# Som
O som é controlado pelos registradores $A7–$AA. O sistema consiste em um registrador de deslocamento de 24 bits e um registrador de controle.
SVSDCT · Controle do som $AA
- Bits 0–3 (V0–V3): volume do som.
- Bit 4 (N): habilitar geração de ruído.
- Bit 5 (F): frequência de deslocamento — 0 = 983 Hz, 1 = 3933 Hz.
- Bit 6: não usado.
- Bit 7 (EN): habilitar som — 0 = desligado, 1 = ligado.
Os endereços $A7–$A9 formam os 24 bits do registrador de deslocamento. A sequência de deslocamento vai da esquerda para a direita: do bit 0 de $A7 ao bit 7 de $A8, e finalmente para $A9.
Quando o bit de geração de ruído está habilitado, o registrador é encurtado para 16 bits ($A8 e $A9) e é feito um OU-exclusivo do último bit com o bit 5 de $A9, realimentado no bit 7 de $A8 e no bit 7 de $A7.
O bit 0 de $A9 é a saída do registrador: envia as sequências de 0s e 1s a um filtro passa-baixa que arredonda a forma de onda, antes de ir aos circuitos de vídeo composto. Esse mesmo bit 0 é reenviado ao bit 7 de $A7.
Tabela de formas de onda no Executivo
; DADOS DE FORMA DE ONDA (frequências dos tons) 0300 40.95 Hz 0310 245.75 Hz 0304 81.92 Hz 0312 327.75 Hz 0308 122.87 Hz 0318 491.63 Hz 030C 163.83 Hz 031C 655.50 Hz 0320 983.25 Hz 0324 1966.50 Hz 300 00 0F FF ; forma: ____________------------ · 983Hz vol 15 304 03 F0 3F ; forma: ______------______------ · 983Hz vol 15 308 0F 0F 0F ; forma: ____----____----____---- · 983Hz vol 15 30C 1C 71 C7 ; forma: ___---___---___---___--- · 983Hz vol 15 310 33 33 33 ; forma: __--__--__--__--__--__-- · 983Hz vol 15 314 03 F0 3F ; forma: ______------______------ · 3933Hz vol 15 318 0F 0F 0F ; forma: ____----____----____---- · 3933Hz vol 15 31C 1C 71 C7 ; forma: ___---___---___---___--- · 3933Hz vol 15 320 33 33 33 ; forma: __--__--__--__--__--__-- · 3933Hz vol 15 324 55 55 55 ; forma: _-_-_-_-_-_-_-_-_-_-_-_- · 3933Hz vol 15
# Teclado
O Odyssey tem a característica única, entre os consoles, de ter um teclado alfanumérico, usado para selecionar jogos, entrar nomes e programar labirintos.
A tecla RESET é conectada diretamente à entrada RESET do 8048, reiniciando o sistema instantaneamente. O resto do teclado é lido por varredura, testando cada linha em sequência. Duas rotinas do Executivo tratam o teclado:
- KEYBRD ($0B0) — varre o teclado. Se houver tecla pressionada, retorna o código em R7; $FF se nenhuma; $C0 se houver erro de leitura.
- KEYCHK ($13D) — suspende a execução e, a cada intervalo vertical, chama KEYBRD até uma tecla ser pressionada, emitindo o som de tecla. Como KEYBRD desativa as interrupções e é demorada, só deve ser chamada durante o intervalo vertical. Retorna o código no acumulador.
Nos primeiros consoles nacionais o teclado ainda era em inglês; depois alguns dizeres foram traduzidos para o português, mantendo os mesmos códigos de tecla.
Numérico
Funções / Entradas
Alfa
# Joysticks
Para ler os joysticks: primeiro desabilite o VDC e a RAM externa (1 em P13 e P14); depois habilite a entrada de teclado/joystick (P12 em 0). Para o joystick direito, P20…P21 devem estar todos em 0. Para o esquerdo, P20 em 1 e P21…P22 em 0. Em seguida, a instrução INS A,BUS recupera o valor no acumulador.
- RESLV ($38F) — lê o joystick. Seleciona o controle em R1 (0 = direito, 1 = esquerdo). Retorna delta-X em R2 ($00 sem movimento, $01 direita, $FF esquerda) e delta-Y em R3 ($00 sem movimento, $01 para baixo, $FF para cima). O botão de ação retorna no flag F0.
- CALHD ($3B1) — converte delta-X e delta-Y em um número de 0 a 7, retornando a direção no acumulador.
Roda de direções (CALHD)
0 = direita · 2 = cima · 4 = esquerda · 6 = baixo (e as diagonais entre eles)
# Executivo
A ROM interna de 1 Kbyte do 8048 fica nos endereços $000–$3FF. Esta ROM se chama Executivo e contém sub-rotinas para atualizar o VDC durante o intervalo vertical, comunicar com teclado e joysticks, exibir objetos na tela e fazer funções de temporização (contagem crescente e decrescente).
7.1 — Vetores do Cartucho
Ao ligar, a primeira instrução da ROM interna salta para $400, o primeiro byte do banco ativo da ROM do cartucho. As interrupções saltam para endereços na ROM interna, que por sua vez desviam para o cartucho — permitindo usar as rotinas padrão do Executivo ou rotinas próprias do usuário.
400 44 C3 JMP START ; 2C3 - rotina do select game 402 04 09 JMP INTSVC ; 009 - Interrupção externa (VDC) 404 x4 xx JMP INTTMR ; xxx - interrupção do timer ou RETR 406 04 1A JMP VRTETY ; 01A - rotina VBLANK 408 x4 xx JMP GSTART ; xxx - retorno do select game 40A 04 44 JMP INTSND ; 044 - Serviço de som
Como os vetores estão separados por 2 bytes, só há espaço para um JMP a outro endereço. Existem 3 situações de interrupção:
Interrupção de Reset
Ocorre ao ligar o console ou pressionar RESET. Força o contador de programa para $000.
000 84 00 JMP 400 ; salta para o início do cartucho
O endereço $400 geralmente salta para a rotina SELECT GAME ($2C3), mas há casos em que o cartucho não a usa. Como a interrupção externa aponta para $402, essa instrução precisa ser um JMP para não interferir.
Interrupção externa
Ocorre quando o VDC começa a gerar o blanking horizontal ou vertical. Salva o endereço da próxima instrução e o PSW na pilha, forçando o processamento para $003. Habilita-se com EN I e desabilita-se com DIS I. A rotina do Executivo começa em $009 e testa se está ocorrendo intervalo vertical.
003 84 02 JMP 402 ; rotina de interrupção do cartucho
Interrupção do temporizador/contador
O temporizador/contador é um registrador de 8 bits que conta até $FF; ao estourar, retorna a $00 e dispara a interrupção. Como temporizador, é incrementado a cada 32 ciclos de instrução; como contador, incrementa toda vez que a entrada T1 (ligada ao blanking do VDC) passa de 1→0, uma vez por linha. Assim, é possível disparar uma interrupção após N linhas (movendo $FF-N para o registrador).
007 84 04 JMP 404 ; rotina de temporizador do cartucho
Habilita-se com EN TCNTI / desabilita-se com DIS TCNTI. Além de habilitar, é preciso iniciar com START T (temporizador) ou START CNT (contador). Para parar: STOP TCNT.
7.2 — Rotinas do Executivo
| End. | Rótulo | Função |
|---|---|---|
| 000 | RESET | reset do 8048 |
| 003 | IRQ | interrupção externa (VBlank) |
| 007 | TMRIRQ | interrupção do temporizador/contador |
| 009 | INTSVC | interrupção de intervalo vertical |
| 01A | VRTETY | interrupção de intervalo vertical |
| 044 | INTSND | interrupção de som |
| 089 | OUTPUT | cópia da RAM externa para o VDC |
| 08B | OUTP1 | — |
| 0B0 | KEYBRD | varredura de teclado |
| 0E7 | SL8244 | configura acesso ao VDC |
| 0EC | SELRAM | configura acesso à RAM externa |
| 0F1 | CLEAR | inicialização das memórias externas |
| 11C | DISABL | desativa o display, liberando o VDC |
| 127 | ENABLE | habilita o display |
| 132 | OTFGST | habilita cópia de dados no próximo VBlank |
| 13D | KEYCHK | espera uma tecla ser pressionada |
| 14B | LSSCAL | calcula o ponteiro para LSS |
| 16B | CLRMAJ | limpa os objetos maiores |
| 176 | NXTINT | espera o próximo VBlank |
| 17C | SCORE | mostra 2 dígitos do placar |
| 197 | SCROUT | calcula LSS e salva objeto maior na RAM |
| 1A2 | SNDSET | toca um som |
| 1B0 | TIMER | contagem incremental/regressiva |
| 1FC | OUTP | exibe o tempo |
| 229 | GEN | — |
| 22C | GEN1 | — |
| 23A | INICLK | inicializa Quad 0 e 1 para exibir um relógio |
| 2A4 | RNDM | gerador de números aleatórios |
| 261 | LDMAJ | exibe um objeto maior na tela |
| 26A | TDBIT | testar um bit |
| 280 | RDBT | resetar um bit |
| 28A | SDBIT | setar um bit |
| 293 | RNDM2 | gerador de aleatórios usando o timer |
| 2C3 | START | rotina de Select Game |
| 37E | RP10 | reseta P10 |
| 383 | RP11 | reseta P11 |
| 387 | RP1 | reseta P10 e P11 |
| 38B | SP1 | seta P10 e P11 |
| 38F | RESLV | ler o joystick |
| 3B1 | CALHD | calcula a direção do joystick (0 a 8) |
| 3CF | DVDE | divisão |
| 3DD | MULT | multiplicação |
| 3EA | OPMJ | calcula LSS de um caractere e escreve no display |
# The Voice
The Voice é um módulo de expansão conectado à entrada de cartucho do Odyssey, adicionando síntese de voz. Usa o chip de processamento de fala SP0256B e possui várias ROMs internas de fala, que podem ser expandidas pelo conector do cartucho.
8.1 — Endereçamento
The Voice aparece na memória da mesma forma que a RAM externa (seção 3.0). Todas as escritas externas de $80–$FF são direcionadas a ele. Ajustar o bit 5 para 0 ao escrever nessa faixa mantém o SP0256B em reset; escrever 1 no bit 5 libera o RESET. Resetar o SP0256B desliga o som que está sendo reproduzido e seleciona o banco de vozes 0.
8.2 — Bancos de sons
Os bancos do SP0256B ficam armazenados em séries diferentes. O primeiro banco está dentro do SP0256B e é selecionado escrevendo em $E4. Três bancos adicionais ficam numa placa de ROMs externas dentro do The Voice, selecionados em $E8, $E9 e $EA. Escrever em $EB–$EF seleciona um banco externo contido em um cartucho. Após selecionar, o banco permanece ativo até outro ser selecionado ou o chip ser resetado.
8.3 — Disparando sons
Escrever 1 em qualquer endereço de $80–$DF ou $F0–$FF faz o SP0256B reproduzir um som do banco selecionado. Nem todos os bancos têm sons em todos os endereços (veja o Apêndice E). Uma vez disparado, o som toca até finalizar ou até o chip ser resetado.
8.4 — Status
A entrada T0 do processador está ligada ao pino ~LRQ do SP0256B. Quando ~LRQ está em 1, o buffer de entrada está cheio e nenhum comando adicional pode ser enviado. Quando passa para 0, o buffer está livre. Isso não indica que um som terminou — apenas que o chip está pronto para receber mais um comando. Novos comandos só são executados após os anteriores finalizarem.
# Mapa de instruções
O conjunto de instruções do 8048 (família MCS-48). O Apêndice A original organiza as instruções numa grade 16×16 pelos dois dígitos hexadecimais do opcode, indicando bytes e ciclos. Legenda do mapa:
- Instruções de 1 byte que consomem 1 ciclo de instrução
- Instruções de 1 byte que consomem 2 ciclos de instrução
- Instruções de 2 bytes que consomem 2 ciclos de instrução
- Instruções não definidas
- Instruções inválidas no Odyssey
| Categoria | Instruções |
|---|---|
| Aritmética / lógica (A) | ADD A,# · ADDC A,# · ADD/ADDC A,@Rr / Rr · ANL A,# · ORL A,# · XRL A,# · INC A · DEC A · CLR A · CPL A · DA A · SWAP A |
| Rotação | RL A · RLC A · RR A · RRC A |
| Transferência de dados | MOV A,# · MOV A,Rr/@Rr · MOV Rr,A/# · MOVP A,@A · MOVP3 A,@A · MOVX A,@Rr · MOVX @Rr,A · XCH A,Rr/@Rr · XCHD A,@Rr |
| E/S | IN A,Pp · INS A,BUS · OUTL BUS,A · OUTL Pp,A · ANL/ORL BUS,# · ANL/ORL Pp,# · MOVD A,Pp · MOVD Pp,A · ANLD/ORLD Pp,A |
| Desvio / chamada | JMP 0–7 · JMPP @A · CALL 0–7 · RET · RETR · DJNZ Rr,addr |
| Desvio condicional | JC/JNC · JZ/JNZ · JT0/JNT0 · JT1/JNT1 · JF0/JF1 · JTF · JNI · JB0…JB7 addr |
| Registradores | INC Rr/@Rr · DEC Rr · SEL RB0/RB1 · SEL MB0/MB1 |
| Flags / controle | CLR/CPL C · CLR/CPL F0 · CLR/CPL F1 · EN I · DIS I · EN TCNTI · DIS TCNTI · STRT T · STRT CNT · STOP TCNT · ENT0 CLK · NOP |
# Cores
Cores de objetos maiores e menores (sprites & caracteres)
Cores de grade / fundo
| Índice | Versão escura | Versão clara |
|---|---|---|
| 0 | Preto | Preto |
| 1 | Azul escuro | Azul |
| 2 | Verde escuro | Verde |
| 3 | Verde claro | Verde claro |
| 4 | Vermelho | Vermelho |
| 5 | Violeta | Violeta |
| 6 | Laranja | Laranja |
| 7 | Cinza claro | Cinza claro |
# Mapa de memória do VDC
| Faixa | Conteúdo |
|---|---|
| $00–$0E | Controle dos objetos menores — SVMIN1 ($00), SVMIN2 ($04), SVMIN3 ($08), SVMIN4 ($0B/$0C) |
| $10–$3F | Objetos maiores — SVMAJ1…SVMAJ12 (4 bytes cada) |
| $40–$7F | Caracteres quádruplos — GRP 1.1 a GRP 4.4 (16 bytes por grupo) |
| $80–$9F | Padrão (bitmap) dos objetos menores — SVMIP1…SVMIP4 (8 bytes cada) |
| $A0–$AA | Registradores (SVCTRL, SVSTAT, SVOVST, SVCOLR, SVYSTR, SVXSTR, registrador de deslocamento de som $A7–$A9, SVSDCT $AA) |
| $AB–$AF | Não usado |
| $B0–$BF | Espelho dos registradores / não usado |
| $C0–$C8 | Grade horizontal — SVGRIH |
| $C9–$CF | Não usado |
| $D0–$D8 | Grade horizontal, linha 9 — SVGRIB |
| $D9–$DF | Não usado |
| $E0–$E9 | Grade vertical — SVGRIV |
| $EA–$FF | Não usado |
Acesso de leitura/escrita aos registradores
| End. | Reg. | Função | Leitura | Escrita |
|---|---|---|---|---|
| A0 | SVCTRL | controle | ✕ | ✕ |
| A1 | SVSTAT | status | ✕ | |
| A2 | SVOVST | colisão | ✕ | ✕ |
| A3 | SVCOLR | cor | ✕ | |
| A4 | SVYSTR | pos Y | ✕ | |
| A5 | SVXSTR | pos X | ✕ | |
| A7–A9 | SVSDSR | registrador de deslocamento | ✕ | |
| AA | SVSDCT | controle de som | ✕ | ✕ |
# Conjunto de caracteres
O VDC armazena 64 caracteres (códigos $00–$3F) numa ROM interna, acessados pelo ponteiro LSS (seção 4.2.2). Os glifos são desenhos estilizados em grade. Mapeamento dos códigos conhecidos:
# Sons do The Voice
Bank $E4 — fonemas e palavras (interno ao SP0256B)
| 80–84 | Pausas: 10ms / 30ms / 50ms / 100ms / 200ms |
| 85–9F | Fonemas: b[OY], sk[Y], [E]nd, [C]OMB, [P]ow, dod[GE], thi[N], S[i]T, [T]o, [R]ural, [M]ilk, par[T], [TH]ey, s[EE], b[EI]ge, coul[D], t[OO], [AU]ght, h[O]t, [Y]es, h[A]t, [H]e, [B]usiness, [TH]in, b[OO]k, f[OO]d |
| A0–BF | Fonemas: [OU]t, [D]o, wi[G], [V]est, [G]ot, [SH]ip, a[Z]ure, b[R]ain, [F]ood, s[K]y, [C]an't, [Z]oo, a[NG]chor, [L]ake, [W]ool, [R]epair, [WH]ig, [Y]es, [CH]urch, f[IR], b[EAU], [TH]ey, ve[S]t, [N]o, [H]oe, st[ORE], al[AR]m, cl[EAR], [G]uest, sadd[EL], [B]usiness (long) |
| C0–CA | Palavras: "ENEMY", "ALL CLEAR", "PLEASE", "GET OFF", "OPEN FIRE", "WATCH OUT", "MERCY", "HIT IT", "YOU BLEW IT", "DO IT AGAIN", "INCREDIBLE" |
| FA–FB | "U.F.O." · "MONSTER!" |
Bank $E8 — palavras (ROM externa)
Bank $E9 — palavras e efeitos
Bank $EA — palavras e efeitos
# Jogos lançados para o Odyssey
O documento original cataloga as bibliotecas por região (com as artes de caixa). Abaixo, os títulos brasileiros e os mercados internacionais cobertos.
Brasil
Outras regiões
- Estados Unidos / Canadá — biblioteca Magnavox/Philips Odyssey².
- Europa (Videopac) — linha Philips Videopac numerada.
- Europa (Jopac) — versão francesa licenciada.
- Europa (Videopac+) — jogos adaptados com gráficos de fundo (G7400); alguns títulos exclusivos da plataforma.