Tamanho: 4KB
Alcance: 0x000 até 0xFFF
Bytes não utilizados: 0x000 até 0x1FF
Início dos programas: 0x200
O Chip-8 é capaz de acessar um alcance de 4KB (0x000 a 0xFFF) de memória. Os primeiros 512 bytes, de 0x000 até 0x1FF, são onde o interpretador era armazenado originalmente e não deve ser sobrescrito por programas.
A maioria dos programas começam na posição 0x200.
Registradores funcionam como "variáveis globais" do seu programa.
Registradores: V0 até VF, 16 registradores de 8-bit cada
Flag VF: O registrador VF é normalmente utilizado como uma flag para algumas das instruções.
Ponteiro de memória (I): Registrador de 16-bit utilizado como um ponteiro para um endereço da memória, como a memória do chip-8 vai de 0x000 até 0xFFF, o registrador I só utiliza 3 bytes.
Dois registradores de 8-bit também são utilizados para o uso de delay e som:
- Delay Timer (DT): Sempre que o valor de DT for diferente de zero, o timer subtrai "1" do próprio valor em uma velocidade de atualização de 60Hz. Quando DT chega a zero, ele desativa.
- Sound Timer (ST): O ST funciona da mesma forma que o DT, porém, enquanto o valor de ST for diferente de zero, será ativado um buzzer (ou um som qualquer). O som é definido pelo desenvolvedor do interpretador.
O Chip-8 tem também alguns registradores que não são acessíveis pelos programas, mas são importantes para o funcionamento do interpretador:
- Program Counter (PC): Armazena o endereço da instrução atual. Costuma ser 16-bit.
- Stack Pointer (SP): Armazena o valor do topo da pilha de execução. O SP armazena 16 valores de 16 bits que empilham os endereços gerados pelas subrotinas do interpretador. É capaz de armazenar até 16 níveis de subrotinas.
Originalmente, os computadores que utilizavam o interpretador Chip-8 tinham um teclado com o seguinte layout:
| 1 | 2 | 3 | c |
| 4 | 5 | 6 | d |
| 7 | 8 | 9 | e |
| a | 0 | b | f |
E estas teclas podem ser mapeadas para encaixar no seu teclado, por exemplo:
| 1 | 2 | 3 | 4 |
| q | w | e | r |
| a | s | d | f |
| z | x | c | v |
A implementação original do Chip-8 possui um display de 64x32 pixels monocromático.
A única forma de desenhar na tela do Chip-8 é através de sprites. Um sprite é composto por um grupo de bytes e podem ter um tamanho de 5x1 até 5x15.
O Chip-8 por padrão carrega no endereço 0x000 os sprites que representam os caracteres do 0 ao F.
Para saber mais:
Cowgod's Chip-8 Technical Reference
O Chip-8 possui um total de 36 instruções.
Todas as suas instruções possuem 2 bytes, onde o primeiro byte é o mais significante.
- nnn ou addr - Um valor entre 0x000 e 0xFFF indicando um endereço da memória.
- n ou nibble - Um valor entre 0x0 e 0xF.
- x - Um valor entre 0x0 e 0xF normalmente utilizado para indicar um registrador entre V0 e VF.
- y - Um valor entre 0x0 e 0xF também normalmente utilizado para indicar um registrador V0 e VF.
- kk ou byte - Um valor entre 0x00 e 0xFF.
Esta instrução era utilizada apenas nos computadores que originalmente implementavam o Chip-8, então você pode ignorar completamente.
Limpa a tela.
Volta de uma subrotina.
Atribui o valor do topo do Stack Pointer ao Program Counter e remove o mesmo da pilha.
Pula o programa para um endereço específico na memória.
Atribui o valor de nnn para o Program Counter.
Chama subrotina no endereço nnn.
Adiciona o endereço atual PC na Stack e atribui o valor de nnn ao PC.
Pula a próxima instrução se Vx for igual a kk.
Pula a próxima instrução se Vx for diferente de kk.
Pula a próxima instrução se Vx for igual a Vy*.*
Atribui o valor de kk no registrador Vx.
Adiciona o valor de kk ao valor já existente do registrador x.
Atribui o valor de Vy ao registrador Vx.
Realiza uma operação bitwise or no entre os registradores Vx e Vy e atribui o resultado no registrador Vx.
Realiza uma operação bitwise and no entre os registradores Vx e Vy e atribui o resultado no registrador Vx.
Realiza uma operação bitwise xor no entre os registradores Vx e Vy e atribui o resultado no registrador Vx.
Adiciona o valor de Vy ao valor já existente do registrador Vx.
Se o resultado da soma for maior que 255, atribui 1 ao registrador Vf e 0 caso não seja. O mesmo será utilizado como um carry flag.
Subtrai o valor de Vy ao valor já existente do registrador Vx.
Se Vx for maior que Vy, atribui 1 ao registrador Vf, utilizando como um no borrow flag.
Move os bits do registrador Vx para a direita.
Se o bit menos significante de Vx for igual a 1, atribui 1 ao registrador Vf, se não, 0.
Atribui ao registrador Vx o valor de Vy menos Vx.
Se Vy for maior que Vx, atribui 1 ao registrador Vf, utilizando como um no borrow flag.
Move os bits do registrador Vx para a esquerda.
Se o bit mais significante de Vx for igual a 1, atribui 1 ao registrador Vf, se não, 0.
Pula a próxima instrução se Vx for diferente de Vy.
Atribui o valor de nnn ao registrador I.
Pula o programa para a localização de nnn mais o valor do registrador V0 (nnn + V0).
O valor da soma entre o nnn e o V0 é atribuido ao PC.
Gera um valor randômico entre 0x00 e 0xFF e realiza uma operação binária bitwise and com o valor de kk.
Em seguida atribui este valor ao registrador Vx.
O interpretador pega todos os bytes contidos na memória entre o registrador I até I + nibble.
O nibble também pode ser visto como a altura do sprite, já que a largura sempre é 5.
Os bytes carregados são desenhados na tela.
Caso algum byte seja apagado no momento em que um pixel é desenhado, o registrador VF tem seu valor modificado para 1.
Pula a próxima instrução se a tecla com o valor Vx estiver pressionada.
Pula a próxima instrução se a tecla com o valor Vx não estiver pressionada.
Atribui o valor de DT ao registrador Vx.
Repete a instrução indefinidamente até o usuário pressionar algum botão, logo em seguida, o valor do botão é armazenado em Vx.
Atribui o valor do registrador Vx ao registrador DT.
Atribui o valor do registrador Vx ao registrador ST.
Soma e atribui o valor de Vx ao valor já existente do registrador I.
Atribui ao registrador I o endereço onde o sprite para o dígito de Vx se encontra.
Salva o digito da casa das centenas de Vx na memória no endereço de I
Salva o digito da casa das dezenas de Vx na memória no endereço de I + 1
Salva o último digito de Vx na memória no endereço de I + 2
Persiste os valores dos registradores de V0 até Vx na memória, começando pelo endereço do registrador I.
Lê valores na memória de os persiste nos registradores de V0 até Vx, começando pelo endereço do registrador I.
Todo este artigo foi baseado na documentação provida em: