445 lines
10 KiB
Markdown
445 lines
10 KiB
Markdown
< [Voltar](chapter-1.md) | [Sumário](table-of-contens.md) | [Adiante](chapter-3.md) >
|
|
|
|
# ⚙️ ** PVM (PROMETEU VM) — Instruction Set**
|
|
|
|
## 1. Visão Geral
|
|
|
|
A **PROMETEU VM** é uma máquina virtual obrigatória e sempre presente no hardware lógico:
|
|
|
|
* **stack-based**
|
|
* determinística
|
|
* orientada a ciclos
|
|
* projetada para ensino e inspeção
|
|
|
|
Ela existe para:
|
|
|
|
* mapear conceitos de linguagens de alto nível
|
|
* tornar custo computacional visível
|
|
* permitir análise de execução
|
|
* servir como base do cartucho PROMETEU
|
|
|
|
> A PROMETEU VM é simples por escolha.
|
|
> Simplicidade é uma ferramenta pedagógica.
|
|
|
|
---
|
|
|
|
## 2. Modelo de Execução
|
|
|
|
### 2.1 Componentes Principais
|
|
|
|
A VM possui:
|
|
|
|
* **PC (Program Counter)** — próxima instrução
|
|
* **Operand Stack** — pilha de valores
|
|
* **Call Stack** — pilha de frames
|
|
* **Heap** — memória dinâmica
|
|
* **Globals** — variáveis globais
|
|
* **Constant Pool** — literais e referências
|
|
* **ROM** — bytecode do cartucho
|
|
* **RAM** — dados mutáveis
|
|
|
|
---
|
|
|
|
### 2.2 Ciclo de Execução
|
|
|
|
Cada instrução executa:
|
|
|
|
```
|
|
FETCH → DECODE → EXECUTE → ADVANCE PC
|
|
```
|
|
|
|
Propriedades:
|
|
|
|
* toda instrução tem custo fixo em ciclos
|
|
* não há trabalho implícito invisível
|
|
* execução é totalmente determinística
|
|
|
|
---
|
|
|
|
## 3. Tipos Fundamentais
|
|
|
|
| Tipo | Descrição |
|
|
| --------- | ----------------------- |
|
|
| `integer` | inteiro 64-bit (signed) |
|
|
| `float` | ponto flutuante 64-bit |
|
|
| `boolean` | verdadeiro/falso |
|
|
| `string` | UTF-8 imutável |
|
|
| `null` | ausência de valor |
|
|
| `ref` | referência ao heap |
|
|
|
|
Não existem:
|
|
|
|
* coerções mágicas
|
|
* casts implícitos
|
|
* overflows silenciosos
|
|
|
|
---
|
|
|
|
## 4. Convenções da Pilha
|
|
|
|
* Operações usam o topo da pilha
|
|
* Resultado sempre volta para a pilha
|
|
* Último empilhado = primeiro consumido
|
|
|
|
Exemplo:
|
|
|
|
```
|
|
PUSH_CONST 3
|
|
PUSH_CONST 4
|
|
ADD
|
|
```
|
|
|
|
Estado:
|
|
|
|
```
|
|
[3]
|
|
[3, 4]
|
|
[7]
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Categorias de Instruções
|
|
|
|
1. Controle de fluxo
|
|
2. Pilha
|
|
3. Aritmética e lógica
|
|
4. Variáveis
|
|
5. Funções
|
|
6. Heap e estruturas
|
|
7. Periféricos (syscalls)
|
|
8. Sistema
|
|
|
|
---
|
|
|
|
## 6. Instruções — VM Set 1
|
|
|
|
### 6.1 Controle de Execução
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
| ------------------- | ------ | ----------------------- |
|
|
| `NOP` | 1 | Não faz nada |
|
|
| `HALT` | 1 | Encerra execução |
|
|
| `JMP addr` | 2 | Salto incondicional |
|
|
| `JMP_IF_FALSE addr` | 3 | Salta se topo for falso |
|
|
|
|
---
|
|
|
|
### 6.2 Pilha
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
| -------------- | ------ | ----------------- |
|
|
| `PUSH_CONST k` | 2 | Empilha constante |
|
|
| `POP` | 1 | Remove topo |
|
|
| `DUP` | 1 | Duplica topo |
|
|
| `SWAP` | 1 | Troca dois topos |
|
|
|
|
---
|
|
|
|
### 6.3 Aritmética
|
|
|
|
| Instrução | Ciclos |
|
|
| --------- | ------ |
|
|
| `ADD` | 2 |
|
|
| `SUB` | 2 |
|
|
| `MUL` | 4 |
|
|
| `DIV` | 6 |
|
|
|
|
---
|
|
|
|
### 6.4 Comparação e Lógica
|
|
|
|
| Instrução | Ciclos |
|
|
| --------- | ------ |
|
|
| `EQ` | 2 |
|
|
| `NEQ` | 2 |
|
|
| `LT` | 2 |
|
|
| `GT` | 2 |
|
|
| `AND` | 2 |
|
|
| `OR` | 2 |
|
|
| `NOT` | 1 |
|
|
|
|
---
|
|
|
|
### 6.5 Variáveis
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
| -------------- | ------ | -------------- |
|
|
| `GET_GLOBAL i` | 3 | Lê global |
|
|
| `SET_GLOBAL i` | 3 | Escreve global |
|
|
| `GET_LOCAL i` | 2 | Lê local |
|
|
| `SET_LOCAL i` | 2 | Escreve local |
|
|
|
|
---
|
|
|
|
### 6.6 Funções
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
|----------------| ------ |---------------------------------|
|
|
| `CALL addr` | 5 | Chamada |
|
|
| `RET` | 4 | Retorno |
|
|
| `PUSH_SCOPE n` | 3 | Cria escopo (frame de execução) |
|
|
| `POP_SCOPE` | 3 | Remove escopo |
|
|
|
|
---
|
|
|
|
### 6.7 Heap
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
| --------------- | ------ | ------------- |
|
|
| `ALLOC size` | 10 | Aloca no heap |
|
|
| `LOAD_REF off` | 3 | Lê campo |
|
|
| `STORE_REF off` | 3 | Escreve campo |
|
|
|
|
Heap é:
|
|
|
|
* finito
|
|
* monitorado
|
|
* contabilizado no CAP
|
|
|
|
---
|
|
|
|
### 6.8 Periféricos (Syscalls)
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
|--------------| -------- | ------------------- |
|
|
| `SYSCALL id` | variável | Chamada ao hardware |
|
|
|
|
#### Syscalls Implementadas (v0.1)
|
|
|
|
| ID | Nome | Argumentos (Pilha) | Retorno |
|
|
| ---------- | ----------------- | ---------------------------- | ------- |
|
|
| `0x0001` | `system.has_cart` | - | `bool` |
|
|
| `0x0002` | `system.run_cart` | - | - |
|
|
| `0x1001` | `gfx.clear` | `color_idx` | - |
|
|
| `0x1002` | `gfx.draw_rect` | `x, y, w, h, color_idx` | - |
|
|
| `0x2001` | `input.get_pad` | `button_id` | `bool` |
|
|
| `0x3001` | `audio.play` | `s_id, v_id, vol, pan, pitch`| - |
|
|
|
|
**IDs de Botões:**
|
|
- `0`: Up, `1`: Down, `2`: Left, `3`: Right
|
|
- `4`: A, `5`: B, `6`: X, `7`: Y
|
|
- `8`: L, `9`: R
|
|
- `10`: Start, `11`: Select
|
|
|
|
---
|
|
|
|
## 7. Erros de Execução
|
|
|
|
Erros são:
|
|
|
|
* explícitos
|
|
* fatais
|
|
* nunca silenciosos
|
|
|
|
Tipos:
|
|
|
|
* stack underflow
|
|
* tipo inválido
|
|
* heap inválido
|
|
* frame inválido
|
|
|
|
Geram:
|
|
|
|
* mensagem clara
|
|
* dump de estado
|
|
* stack trace
|
|
|
|
---
|
|
|
|
## 8. Determinismo
|
|
|
|
Garantias:
|
|
|
|
* mesma entrada → mesmo resultado
|
|
* mesma sequência → mesmos ciclos
|
|
* sem execução especulativa
|
|
* sem otimizações invisíveis
|
|
|
|
> Se você vê a instrução, você paga por ela.
|
|
|
|
---
|
|
|
|
## 9. Relação com Linguagens
|
|
|
|
Java, TypeScript, Lua etc:
|
|
|
|
* são linguagens-fonte
|
|
* compiladas para esse bytecode
|
|
* nunca executadas diretamente
|
|
|
|
Todas rodam na **mesma VM**.
|
|
|
|
---
|
|
|
|
## 10. Exemplo
|
|
|
|
Fonte:
|
|
|
|
```java
|
|
x = 3 + 4;
|
|
```
|
|
|
|
Bytecode:
|
|
|
|
```
|
|
PUSH_CONST 3
|
|
PUSH_CONST 4
|
|
ADD
|
|
SET_GLOBAL 0
|
|
```
|
|
|
|
Custo:
|
|
|
|
```
|
|
2 + 2 + 2 + 3 = 9 ciclos
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Execução por Tick
|
|
|
|
A VM não roda infinitamente.
|
|
|
|
Ela executa:
|
|
|
|
* até consumir o budget do **frame lógico**
|
|
* ou até `HALT`
|
|
|
|
O budget é definido pelo hardware lógico do PROMETEU (ex.: `CYCLES_PER_FRAME`).
|
|
|
|
Exemplo:
|
|
|
|
```
|
|
vm.step_budget(10_000)
|
|
```
|
|
|
|
Isso alimenta:
|
|
|
|
* CAP
|
|
* profiling
|
|
* certificação
|
|
|
|
---
|
|
|
|
## 12. Frame Lógico e `FRAME_SYNC`
|
|
|
|
O PROMETEU define **frame lógico** como a unidade mínima de atualização consistente do jogo.
|
|
|
|
* **Input é latched por frame lógico** (não muda enquanto o frame lógico não for concluído).
|
|
* O **budget de ciclos** é aplicado ao frame lógico.
|
|
* Um novo frame lógico só começa quando o frame atual termina.
|
|
|
|
### 12.1 Instrução de Sistema: `FRAME_SYNC`
|
|
|
|
A instrução `FRAME_SYNC` marca o **fim do frame lógico**.
|
|
|
|
| Instrução | Ciclos | Descrição |
|
|
| ------------ | ------ | ----------------------------- |
|
|
| `FRAME_SYNC` | 1 | Finaliza o frame lógico atual |
|
|
|
|
Propriedades:
|
|
|
|
* `FRAME_SYNC` é uma **instrução do sistema**.
|
|
* Não deve ser exposta como API “manual” ao usuário.
|
|
* O tooling/compilador pode **injetar** `FRAME_SYNC` automaticamente ao final do loop principal.
|
|
|
|
### 12.2 Semântica (o que acontece quando executa)
|
|
|
|
Ao executar `FRAME_SYNC`, o core:
|
|
|
|
1. **Finaliza** o frame lógico atual.
|
|
2. **Apresenta** o frame (`gfx.present()` ou `gfx.compose_and_present()` conforme o modelo do GFX).
|
|
3. **Libera** o latch de input.
|
|
4. **Reseta** o budget para o próximo frame lógico.
|
|
|
|
### 12.3 Overbudget (quando o frame não termina a tempo)
|
|
|
|
Se o budget do frame lógico acabar **antes** da VM alcançar `FRAME_SYNC`:
|
|
|
|
* a VM **pausa** (PC e pilhas permanecem no ponto exato)
|
|
* **não há present**
|
|
* o latch de input é **mantido**
|
|
* no próximo tick do host, a VM **continua** de onde parou, ainda no mesmo frame lógico
|
|
|
|
Efeito prático:
|
|
|
|
* se o código precisa de 2 budgets para alcançar `FRAME_SYNC`, o jogo passa a atualizar a ~30 FPS (frame lógico leva 2 ticks)
|
|
* isso é determinístico e reportável no CAP
|
|
|
|
---
|
|
|
|
## 13. Boot ROM e Estado Inicial
|
|
|
|
A **PROMETEU VM** nunca inicia em um estado totalmente "vazio" ou inativo.
|
|
|
|
### 13.1 O Boot ROM (BIOS)
|
|
Se a máquina for inicializada sem um cartucho específico carregado, a VM executa um **Boot ROM padrão**. Este é um pequeno programa em bytecode embutido no core que gerencia o ciclo de vida inicial da máquina através de uma máquina de estados:
|
|
|
|
#### Fase 1: BOOT (Splash & Som)
|
|
1. **Som de Inicialização**: Emite um som de "plim" (`0x3001`) imediatamente ao ligar (frame 0).
|
|
2. **Splash Animation**: Exibe o logotipo (quadrado Índigo) crescendo suavemente (0-40 frames).
|
|
3. **Splash Estático**: O logotipo permanece na tela até o frame 180 (~3 segundos).
|
|
4. **Interrupção**: O usuário pode pular o Splash a qualquer momento pressionando **START**.
|
|
|
|
#### Fase 2: C_VALIDATION (Validação)
|
|
Ao fim do Splash ou interrupção, a BIOS verifica a presença de um cartucho:
|
|
- **Com Cartucho**: Chama `system.run_cart` (`0x0002`) para transferir o controle.
|
|
- **Sem Cartucho**: Transita para o **Estado de SO**.
|
|
|
|
#### Fase 3: RUN (Sistema Operacional / Fallback)
|
|
Se nenhum cartucho for detectado, a máquina entra em modo "SO":
|
|
1. **Interface**: Exibe um quadrado **Ciano** no centro da tela.
|
|
2. **Hot-plug**: Monitora em tempo real a inserção de cartuchos. Se um cartucho for inserido e o botão **START** for pressionado, o cartucho é iniciado.
|
|
|
|
### 13.2 Ciclo de Memória
|
|
A instrução `system.run_cart` garante um ambiente limpo para o novo programa:
|
|
1. Reseta o **PC** para 0.
|
|
2. Limpa as pilhas (**Operand Stack** e **Call Stack**).
|
|
3. Limpa a memória (**Globals** e **Heap**).
|
|
4. Carrega a nova **ROM** e **Constant Pool** do cartucho.
|
|
|
|
---
|
|
|
|
## 14. Boot e Cartucho
|
|
|
|
O core:
|
|
|
|
* valida cartucho
|
|
* carrega ROM e dados
|
|
* seta PC inicial
|
|
* entra em modo RUN
|
|
|
|
O cartucho:
|
|
|
|
* contém bytecode
|
|
* assets
|
|
* metadata
|
|
* entry point
|
|
|
|
---
|
|
|
|
## 15. Extensibilidade
|
|
|
|
O Instruction Set é versionado.
|
|
|
|
Futuro:
|
|
|
|
* DMA
|
|
* streaming
|
|
* vetores
|
|
* coprocessadores fictícios
|
|
|
|
Nenhuma instrução existente muda de significado.
|
|
|
|
---
|
|
|
|
## 16. Resumo
|
|
|
|
* VM stack-based
|
|
* custo explícito
|
|
* execução determinística
|
|
* integrada ao CAP
|
|
* base de todo cartucho PROMETEU
|
|
|
|
< [Voltar](chapter-1.md) | [Sumário](table-of-contens.md) | [Adiante](chapter-3.md) > |