translate to english!

This commit is contained in:
Nilton Constantino 2026-01-19 07:28:14 +00:00
parent 38ec13b248
commit 0f3105d622
No known key found for this signature in database
49 changed files with 2488 additions and 2488 deletions

View File

@ -1,84 +1,84 @@
# PROMETEU # PROMETEU
PROMETEU é um **ecossistema educacional e experimental** inspirado em consoles clássicos, com foco em **ensinar programação, arquitetura de sistemas e conceitos de hardware através de software**. PROMETEU is an **educational and experimental ecosystem** inspired by classic consoles, focusing on **teaching programming, system architecture, and hardware concepts through software**.
> PROMETEU é uma máquina virtual simples, explícita e didática. > PROMETEU is a simple, explicit, and educational virtual machine.
--- ---
## 🎯 Objetivos do Projeto ## 🎯 Project Goals
- **Simular um “hardware lógico” simples**: Criar uma barreira de entrada baixa para entender como computadores funcionam. - **Simulate simple "logical hardware"**: Create a low entry barrier for understanding how computers work.
- **Loop Determinístico**: Garantir que o mesmo código produza o mesmo resultado em qualquer plataforma. - **Deterministic Loop**: Ensure the same code produces the same result on any platform.
- **Portabilidade Total**: O núcleo não depende de sistema operacional, permitindo rodar de computadores modernos a hardware dedicado. - **Total Portability**: The core does not depend on an operating system, allowing it to run from modern computers to dedicated hardware.
- **Ferramentas de Primeiro Nível**: Oferecer depuração e inspeção profunda como parte central da experiência. - **First-Class Tools**: Offer deep debugging and inspection as a central part of the experience.
--- ---
## 🧠 Filosofia de Design ## 🧠 Design Philosophy
- **Sem magia**: tudo é explícito. - **No magic**: everything is explicit.
- **Sem heurística implícita**: o sistema não “adivinha intenções”. - **No implicit heuristics**: the system doesn't "guess intentions".
- **Determinístico**: mesmo input → mesmo resultado. - **Deterministic**: same input → same result.
- **Hardware-first**: APIs modelam periféricos, não frameworks modernos. - **Hardware-first**: APIs model peripherals, not modern frameworks.
- **Portável por definição**: se não funciona em todas as plataformas, não existe. - **Portable by definition**: if it doesn't work on all platforms, it doesn't exist.
--- ---
## 📦 Estrutura do Monorepo ## 📦 Monorepo Structure
Este repositório é organizado como um workspace Rust e contém diversos componentes: This repository is organized as a Rust workspace and contains several components:
- **[crates/](./crates)**: Implementação do software em Rust. - **[crates/](./crates)**: Software implementation in Rust.
- **[prometeu](./crates/prometeu)**: Interface de linha de comando (CLI) unificada. - **[prometeu](./crates/prometeu)**: Unified command-line interface (CLI).
- **[prometeu-core](./crates/prometeu-core)**: O núcleo lógico, VM e SO interno. - **[prometeu-core](./crates/prometeu-core)**: The logical core, VM, and internal OS.
- **[prometeu-runtime-desktop](./crates/prometeu-runtime-desktop)**: Host para execução em sistemas Desktop. - **[prometeu-runtime-desktop](./crates/prometeu-runtime-desktop)**: Host for execution on Desktop systems.
- **[docs/](./docs)**: Documentação técnica e especificações do sistema. - **[docs/](./docs)**: Technical documentation and system specifications.
- **[devtools-protocol/](./devtools-protocol)**: Definição do protocolo de comunicação para ferramentas de desenvolvimento. - **[devtools-protocol/](./devtools-protocol)**: Definition of the communication protocol for development tools.
- **[test-cartridges/](./test-cartridges)**: Exemplos e suítes de teste de cartuchos. - **[test-cartridges/](./test-cartridges)**: Cartridge examples and test suites.
--- ---
## 🛠️ Requisitos ## 🛠️ Requirements
- **Rust**: Versão definida em `rust-toolchain.toml`. - **Rust**: Version defined in `rust-toolchain.toml`.
- **Instalação**: Use o [rustup](https://rustup.rs/) para instalar a toolchain necessária. - **Installation**: Use [rustup](https://rustup.rs/) to install the required toolchain.
--- ---
## ▶️ Início Rápido ## ▶️ Quick Start
Para compilar o projeto completo: To compile the full project:
```bash ```bash
cargo build cargo build
``` ```
Para rodar um cartucho de exemplo: To run an example cartridge:
```bash ```bash
./target/debug/prometeu run test-cartridges/color-square ./target/debug/prometeu run test-cartridges/color-square
``` ```
Para mais detalhes sobre como usar a CLI, veja o README de **[prometeu](./crates/prometeu)**. For more details on how to use the CLI, see the **[prometeu](./crates/prometeu)** README.
--- ---
## 🚧 Status do Projeto ## 🚧 Project Status
⚠️ **Em estágio inicial (bootstrap)** ⚠️ **Early stage (bootstrap)**
Atualmente o foco é na estabilização da arquitetura do core e do protocolo de depuração. Nada aqui deve ser considerado uma API estável ainda. Currently, the focus is on stabilizing the core architecture and debugging protocol. Nothing here should be considered a stable API yet.
--- ---
## 📜 Licença ## 📜 License
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes. This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
--- ---
## ✨ Nota Final ## ✨ Final Note
PROMETEU é tanto um projeto técnico quanto pedagógico. A ideia não é esconder complexidade, mas **expor a complexidade certa**, no nível certo, para que ela possa ser entendida, estudada e explorada. PROMETEU is both a technical and pedagogical project. The idea is not to hide complexity, but to **expose the right complexity**, at the right level, so it can be understood, studied, and explored.

View File

@ -1,14 +1,14 @@
# PROMETEU Core # PROMETEU Core
Este crate contém a biblioteca central que define o comportamento do hardware e software do PROMETEU. This crate contains the core library that defines the behavior of PROMETEU's hardware and software.
## Responsabilidades ## Responsibilities
- **Hardware Lógico**: Definição de GFX, Input, Audio e Touch. - **Logical Hardware**: Definition of GFX, Input, Audio, and Touch.
- **Máquina Virtual**: Execução de bytecode customizado (PBC - Prometeu Byte Code). - **Virtual Machine**: Execution of custom bytecode (PBC - Prometeu Byte Code).
- **Virtual FS**: Gerenciamento de arquivos e acesso ao "cartucho". - **Virtual FS**: File management and "cartridge" access.
- **Firmware/OS**: O sistema operacional interno que gerencia o ciclo de vida das aplicações, splash screens e o Hub Home. - **Firmware/OS**: The internal operating system that manages the application lifecycle, splash screens, and the Hub Home.
## Arquitetura ## Architecture
O core é projetado para ser determinístico e portátil. Ele não faz chamadas diretas ao sistema operacional do host; em vez disso, define traços (traits) que os hosts devem implementar (ex: `FsBackend`). The core is designed to be deterministic and portable. It does not make direct calls to the host operating system; instead, it defines traits that hosts must implement (e.g., `FsBackend`).

View File

@ -31,7 +31,7 @@ impl Firmware {
} }
pub fn step_frame(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) { pub fn step_frame(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
// Atualiza input uma vez por frame de host // Updates input once per host frame
hw.pad_mut().begin_frame(signals); hw.pad_mut().begin_frame(signals);
hw.touch_mut().begin_frame(signals); hw.touch_mut().begin_frame(signals);
@ -50,7 +50,7 @@ impl Firmware {
self.state = new_state; self.state = new_state;
self.state_initialized = false; self.state_initialized = false;
// Entra no novo estado imediatamente // Enters the new state immediately
self.on_enter(signals, hw); self.on_enter(signals, hw);
self.state_initialized = true; self.state_initialized = true;
} }

View File

@ -14,16 +14,16 @@ impl AppCrashesStep {
} }
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> { pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
// Atualiza periféricos para input na tela de crash // Update peripherals for input on the crash screen
ctx.hw.pad_mut().begin_frame(ctx.signals); ctx.hw.pad_mut().begin_frame(ctx.signals);
// Tela de erro: fundo vermelho, texto branco // Error screen: red background, white text
ctx.hw.gfx_mut().clear(Color::RED); ctx.hw.gfx_mut().clear(Color::RED);
// Por enquanto apenas logamos ou mostramos algo simples // For now we just log or show something simple
// No futuro, usar draw_text // In the future, use draw_text
ctx.hw.gfx_mut().present(); ctx.hw.gfx_mut().present();
// Se apertar START, volta pro Hub // If START is pressed, return to the Hub
if ctx.hw.pad().start.down { if ctx.hw.pad().start.down {
return Some(FirmwareState::LaunchHub(LaunchHubStep)); return Some(FirmwareState::LaunchHub(LaunchHubStep));
} }

View File

@ -13,19 +13,19 @@ impl HubHomeStep {
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> { pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
let mut error = None; let mut error = None;
// Sempre atualiza a GUI do Hub (limpa a tela e processa input se não houver foco) // Always updates the Hub GUI (clears screen and processes input if no focus)
ctx.hub.gui_update(ctx.os, ctx.hw); ctx.hub.gui_update(ctx.os, ctx.hw);
if let Some(focused_id) = ctx.hub.window_manager.focused { if let Some(focused_id) = ctx.hub.window_manager.focused {
if ctx.hw.pad().start.down { if ctx.hw.pad().start.down {
ctx.hub.window_manager.remove_window(focused_id); ctx.hub.window_manager.remove_window(focused_id);
} else { } else {
// System App roda aqui, desenhando sobre o fundo do Hub // System App runs here, drawing over the Hub background
error = ctx.os.step_frame(ctx.vm, ctx.signals, ctx.hw); error = ctx.os.step_frame(ctx.vm, ctx.signals, ctx.hw);
} }
} }
// Renderiza as bordas das janelas do System App // Renders the System App window borders
ctx.hub.render(ctx.os, ctx.hw); ctx.hub.render(ctx.os, ctx.hw);
ctx.hw.gfx_mut().present(); ctx.hw.gfx_mut().present();

View File

@ -17,8 +17,8 @@ impl LaunchHubStep {
if let BootTarget::Cartridge { path, .. } = ctx.boot_target { if let BootTarget::Cartridge { path, .. } = ctx.boot_target {
match CartridgeLoader::load(path) { match CartridgeLoader::load(path) {
Ok(cartridge) => { Ok(cartridge) => {
// No caso de debug, aqui poderíamos pausar, mas o requisito diz // In the case of debug, we could pause here, but the requirement says
// para o Runtime abrir o socket e aguardar. // for the Runtime to open the socket and wait.
return Some(FirmwareState::LoadCartridge(LoadCartridgeStep { cartridge })); return Some(FirmwareState::LoadCartridge(LoadCartridgeStep { cartridge }));
} }
Err(e) => { Err(e) => {

View File

@ -23,8 +23,8 @@ impl LoadCartridgeStep {
); );
ctx.hub.window_manager.set_focus(id); ctx.hub.window_manager.set_focus(id);
// Apps de sistema não mudam o estado do firmware para GameRunning. // System apps do not change the firmware state to GameRunning.
// Eles rodam em background ou via janelas no Hub. // They run in the background or via windows in the Hub.
return Some(FirmwareState::HubHome(HubHomeStep)); return Some(FirmwareState::HubHome(HubHomeStep));
} }

View File

@ -12,23 +12,23 @@ pub struct SplashScreenStep {
impl SplashScreenStep { impl SplashScreenStep {
pub fn on_enter(&mut self, ctx: &mut PrometeuContext) { pub fn on_enter(&mut self, ctx: &mut PrometeuContext) {
ctx.os.log(LogLevel::Info, LogSource::Pos, 0, "Showing SplashScreen".to_string()); ctx.os.log(LogLevel::Info, LogSource::Pos, 0, "Showing SplashScreen".to_string());
// Tocar som no enter // Play sound on enter
if let Some(sample) = ctx.os.sample_square.clone() { if let Some(sample) = ctx.os.sample_square.clone() {
ctx.hw.audio_mut().play(sample, 0, 255, 127, 1.0, 0, LoopMode::Off); ctx.hw.audio_mut().play(sample, 0, 255, 127, 1.0, 0, LoopMode::Off);
} }
} }
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> { pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
const ANIMATION_DURATION: u32 = 60; // 1 segundo a 60fps const ANIMATION_DURATION: u32 = 60; // 1 second at 60fps
const TOTAL_DURATION: u32 = 240; // 2 segundos totais (conforme ctxuisito anterior) const TOTAL_DURATION: u32 = 240; // 4 seconds total (updated from 2s based on total_duration logic)
// Atualiza periféricos para input // Update peripherals for input
ctx.hw.pad_mut().begin_frame(ctx.signals); ctx.hw.pad_mut().begin_frame(ctx.signals);
// Limpar tela // Clear screen
ctx.hw.gfx_mut().clear(Color::BLACK); ctx.hw.gfx_mut().clear(Color::BLACK);
// Desenhar quadrado aumentando // Draw expanding square
let (sw, sh) = ctx.hw.gfx().size(); let (sw, sh) = ctx.hw.gfx().size();
let max_size = (sw.min(sh) as i32 / 2).max(1); let max_size = (sw.min(sh) as i32 / 2).max(1);
@ -44,8 +44,8 @@ impl SplashScreenStep {
ctx.hw.gfx_mut().fill_rect(x, y, current_size, current_size, Color::WHITE); ctx.hw.gfx_mut().fill_rect(x, y, current_size, current_size, Color::WHITE);
ctx.hw.gfx_mut().present(); ctx.hw.gfx_mut().present();
// Lógica de transição // Transition logic
// Caso o botão start seja pressionado a qualquer momento depois da animação terminar // If any button is pressed at any time after the animation ends
if self.frame >= ANIMATION_DURATION && ctx.hw.pad().any() { if self.frame >= ANIMATION_DURATION && ctx.hw.pad().any() {
return Some(FirmwareState::LaunchHub(LaunchHubStep)); return Some(FirmwareState::LaunchHub(LaunchHubStep));
} }

View File

@ -120,7 +120,7 @@ impl Audio {
} }
} }
/// Limpa a fila de comandos. O Host deve consumir isso a cada frame. /// Clears the command queue. The Host should consume this every frame.
pub fn clear_commands(&mut self) { pub fn clear_commands(&mut self) {
self.commands.clear(); self.commands.clear();
} }

View File

@ -32,7 +32,7 @@ pub struct Gfx {
pub hud_fade_level: u8, // 0..31 pub hud_fade_level: u8, // 0..31
pub hud_fade_color: Color, pub hud_fade_color: Color,
// Cache de prioridades para evitar alocações por frame // Priority cache to avoid per-frame allocations
priority_buckets: [Vec<usize>; 5], priority_buckets: [Vec<usize>; 5],
} }
@ -51,17 +51,19 @@ impl Gfx {
}; };
let len = w * h; let len = w * h;
let mut layers = [
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
];
Self { Self {
w, w,
h, h,
front: vec![0; len], front: vec![0; len],
back: vec![0; len], back: vec![0; len],
layers: [ layers,
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
ScrollableTileLayer::new(64, 64, TileSize::Size16),
],
hud: HudTileLayer::new(64, 32), hud: HudTileLayer::new(64, 32),
banks: [EMPTY_BANK; 16], banks: [EMPTY_BANK; 16],
sprites: [EMPTY_SPRITE; 512], sprites: [EMPTY_SPRITE; 512],
@ -83,7 +85,7 @@ impl Gfx {
(self.w, self.h) (self.w, self.h)
} }
/// O buffer que o host deve exibir (RGB565). /// The buffer that the host should display (RGB565).
pub fn front_buffer(&self) -> &[u16] { pub fn front_buffer(&self) -> &[u16] {
&self.front &self.front
} }
@ -92,7 +94,7 @@ impl Gfx {
self.back.fill(color.0); self.back.fill(color.0);
} }
/// Retângulo com modo de blend. /// Rectangle with blend mode.
pub fn fill_rect_blend( pub fn fill_rect_blend(
&mut self, &mut self,
x: i32, x: i32,
@ -122,21 +124,21 @@ impl Gfx {
} }
} }
/// Conveniência: retângulo normal (sem blend). /// Convenience: normal rectangle (no blend).
pub fn fill_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) { pub fn fill_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) {
self.fill_rect_blend(x, y, w, h, color, BlendMode::None); self.fill_rect_blend(x, y, w, h, color, BlendMode::None);
} }
/// Double buffer swap (O(1), sem cópia de pixels). /// Double buffer swap (O(1), no pixel copying).
pub fn present(&mut self) { pub fn present(&mut self) {
std::mem::swap(&mut self.front, &mut self.back); std::mem::swap(&mut self.front, &mut self.back);
} }
/// Pipeline principal de renderização do frame. /// Main frame rendering pipeline.
/// Segue a ordem de prioridade do manual (Capítulo 4.11). /// Follows the priority order from the manual (Chapter 4.11).
pub fn render_all(&mut self) { pub fn render_all(&mut self) {
// 0. Fase de Preparação: Organiza quem deve ser desenhado em cada camada // 0. Preparation Phase: Organizes what should be drawn in each layer
// Limpa os buckets sem desalocar memória // Clears the buckets without deallocating memory
for bucket in self.priority_buckets.iter_mut() { for bucket in self.priority_buckets.iter_mut() {
bucket.clear(); bucket.clear();
} }
@ -147,27 +149,27 @@ impl Gfx {
} }
} }
// 1. Sprites de prioridade 0 (Atrás da Layer 0 - o fundo do fundo) // 1. Priority 0 sprites (Behind Layer 0 - the very back)
Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[0], &self.sprites, &self.banks); Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[0], &self.sprites, &self.banks);
for i in 0..self.layers.len() { for i in 0..self.layers.len() {
// 2. Layers de jogo (0 a 3) // 2. Game Layers (0 to 3)
let bank_id = self.layers[i].bank_id as usize; let bank_id = self.layers[i].bank_id as usize;
if let Some(Some(bank)) = self.banks.get(bank_id) { if let Some(Some(bank)) = self.banks.get(bank_id) {
Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[i].map, bank, self.layers[i].scroll_x, self.layers[i].scroll_y); Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[i].map, bank, self.layers[i].scroll_x, self.layers[i].scroll_y);
} }
// 3. Sprites de acordo com prioridade // 3. Sprites according to priority
Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[i + 1], &self.sprites, &self.banks); Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[i + 1], &self.sprites, &self.banks);
} }
// 4. Aplica Scene Fade (Afeta tudo desenhado até agora) // 4. Applies Scene Fade (Affects everything drawn so far)
Self::apply_fade_to_buffer(&mut self.back, self.scene_fade_level, self.scene_fade_color); Self::apply_fade_to_buffer(&mut self.back, self.scene_fade_level, self.scene_fade_color);
// 5. HUD (Sempre por cima) // 5. HUD (Always on top)
self.render_hud(); self.render_hud();
// 6. Aplica HUD Fade (Opcional, apenas para o HUD) // 6. Applies HUD Fade (Optional, HUD only)
Self::apply_fade_to_buffer(&mut self.back, self.hud_fade_level, self.hud_fade_color); Self::apply_fade_to_buffer(&mut self.back, self.hud_fade_level, self.hud_fade_color);
} }
@ -186,7 +188,7 @@ impl Gfx {
Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[layer_idx].map, bank, scroll_x, scroll_y); Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[layer_idx].map, bank, scroll_x, scroll_y);
} }
/// Renderiza o HUD (sem scroll). /// Renders the HUD (no scroll).
pub fn render_hud(&mut self) { pub fn render_hud(&mut self) {
let bank_id = self.hud.bank_id as usize; let bank_id = self.hud.bank_id as usize;
let bank = match self.banks.get(bank_id) { let bank = match self.banks.get(bank_id) {
@ -208,30 +210,30 @@ impl Gfx {
) { ) {
let tile_size = bank.tile_size as usize; let tile_size = bank.tile_size as usize;
// 1. Calcular quantos tiles cabem na tela (com margem de 1 para o scroll) // 1. Calculate how many tiles fit on the screen (with margin of 1 for scroll)
let visible_tiles_x = (screen_w / tile_size) + 1; let visible_tiles_x = (screen_w / tile_size) + 1;
let visible_tiles_y = (screen_h / tile_size) + 1; let visible_tiles_y = (screen_h / tile_size) + 1;
// 2. Calcular o offset inicial (onde o primeiro tile começa a ser desenhado) // 2. Calculate the initial offset (where the first tile starts being drawn)
let start_tile_x = scroll_x / tile_size as i32; let start_tile_x = scroll_x / tile_size as i32;
let start_tile_y = scroll_y / tile_size as i32; let start_tile_y = scroll_y / tile_size as i32;
let fine_scroll_x = scroll_x % tile_size as i32; let fine_scroll_x = scroll_x % tile_size as i32;
let fine_scroll_y = scroll_y % tile_size as i32; let fine_scroll_y = scroll_y % tile_size as i32;
// 3. Loop por Tile (Muito mais eficiente) // 3. Loop by Tile (Much more efficient)
for ty in 0..visible_tiles_y { for ty in 0..visible_tiles_y {
for tx in 0..visible_tiles_x { for tx in 0..visible_tiles_x {
let map_x = (start_tile_x + tx as i32) as usize; let map_x = (start_tile_x + tx as i32) as usize;
let map_y = (start_tile_y + ty as i32) as usize; let map_y = (start_tile_y + ty as i32) as usize;
// Skip se estiver fora dos limites do mapa // Skip if outside map bounds
if map_x >= map.width || map_y >= map.height { continue; } if map_x >= map.width || map_y >= map.height { continue; }
let tile = map.tiles[map_y * map.width + map_x]; let tile = map.tiles[map_y * map.width + map_x];
if tile.id == 0 { continue; } if tile.id == 0 { continue; }
// 4. Desenha o bloco do tile na tela // 4. Draws the tile block on the screen
let screen_tile_x = (tx as i32 * tile_size as i32) - fine_scroll_x; let screen_tile_x = (tx as i32 * tile_size as i32) - fine_scroll_x;
let screen_tile_y = (ty as i32 * tile_size as i32) - fine_scroll_y; let screen_tile_y = (ty as i32 * tile_size as i32) - fine_scroll_y;
@ -240,7 +242,7 @@ impl Gfx {
} }
} }
// Função auxiliar para desenhar um bloco de 8x8, 16x16 ou 32x32 pixels // Helper function to draw a block of 8x8, 16x16 or 32x32 pixels
fn draw_tile_pixels(back: &mut [u16], screen_w: usize, screen_h: usize, x: i32, y: i32, tile: crate::model::Tile, bank: &TileBank) { fn draw_tile_pixels(back: &mut [u16], screen_w: usize, screen_h: usize, x: i32, y: i32, tile: crate::model::Tile, bank: &TileBank) {
let size = bank.tile_size as usize; let size = bank.tile_size as usize;
@ -255,13 +257,13 @@ impl Gfx {
let fetch_x = if tile.flip_x { size - 1 - local_x } else { local_x }; let fetch_x = if tile.flip_x { size - 1 - local_x } else { local_x };
let fetch_y = if tile.flip_y { size - 1 - local_y } else { local_y }; let fetch_y = if tile.flip_y { size - 1 - local_y } else { local_y };
// 1. Pega o índice do pixel no banco // 1. Gets the pixel index in the bank
let px_index = bank.get_pixel_index(tile.id, fetch_x, fetch_y); let px_index = bank.get_pixel_index(tile.id, fetch_x, fetch_y);
// 2. Regra: Índice 0 é transparente // 2. Rule: Index 0 is transparent
if px_index == 0 { continue; } if px_index == 0 { continue; }
// 3. Resolve a cor usando a paleta do tile // 3. Resolves the color using the tile's palette
let color = bank.resolve_color(tile.palette_id, px_index); let color = bank.resolve_color(tile.palette_id, px_index);
back[world_y as usize * screen_w + world_x as usize] = color.raw(); back[world_y as usize * screen_w + world_x as usize] = color.raw();
@ -293,7 +295,7 @@ impl Gfx {
sprite: &Sprite, sprite: &Sprite,
bank: &TileBank bank: &TileBank
) { ) {
// ... (mesmo cálculo de bounds/clipping que já tínhamos) ... // ... (same bounds/clipping calculation we already had) ...
let size = bank.tile_size as usize; let size = bank.tile_size as usize;
let start_x = sprite.x.max(0); let start_x = sprite.x.max(0);
let start_y = sprite.y.max(0); let start_y = sprite.y.max(0);
@ -308,13 +310,13 @@ impl Gfx {
let fetch_x = if sprite.flip_x { size - 1 - local_x } else { local_x }; let fetch_x = if sprite.flip_x { size - 1 - local_x } else { local_x };
let fetch_y = if sprite.flip_y { size - 1 - local_y } else { local_y }; let fetch_y = if sprite.flip_y { size - 1 - local_y } else { local_y };
// 1. Pega o índice // 1. Get index
let px_index = bank.get_pixel_index(sprite.tile.id, fetch_x, fetch_y); let px_index = bank.get_pixel_index(sprite.tile.id, fetch_x, fetch_y);
// 2. Transparência // 2. Transparency
if px_index == 0 { continue; } if px_index == 0 { continue; }
// 3. Resolve cor via paleta (do tile dentro do sprite) // 3. Resolve color via palette (from the tile inside the sprite)
let color = bank.resolve_color(sprite.tile.palette_id, px_index); let color = bank.resolve_color(sprite.tile.palette_id, px_index);
back[world_y as usize * screen_w + world_x as usize] = color.raw(); back[world_y as usize * screen_w + world_x as usize] = color.raw();
@ -322,10 +324,10 @@ impl Gfx {
} }
} }
/// Aplica o efeito de fade em todo o back buffer. /// Applies the fade effect to the entire back buffer.
/// level: 0 (cor total) até 31 (visível) /// level: 0 (full color) to 31 (visible)
fn apply_fade_to_buffer(back: &mut [u16], level: u8, fade_color: Color) { fn apply_fade_to_buffer(back: &mut [u16], level: u8, fade_color: Color) {
if level >= 31 { return; } // Totalmente visível, pula processamento if level >= 31 { return; } // Fully visible, skip processing
let weight = level as u16; let weight = level as u16;
let inv_weight = 31 - weight; let inv_weight = 31 - weight;
@ -334,7 +336,7 @@ impl Gfx {
for px in back.iter_mut() { for px in back.iter_mut() {
let (sr, sg, sb) = Color::unpack_to_native(*px); let (sr, sg, sb) = Color::unpack_to_native(*px);
// Fórmula: (src * weight + fade * inv_weight) / 31 // Formula: (src * weight + fade * inv_weight) / 31
let r = ((sr as u16 * weight + fr as u16 * inv_weight) / 31) as u8; let r = ((sr as u16 * weight + fr as u16 * inv_weight) / 31) as u8;
let g = ((sg as u16 * weight + fg as u16 * inv_weight) / 31) as u8; let g = ((sg as u16 * weight + fg as u16 * inv_weight) / 31) as u8;
let b = ((sb as u16 * weight + fb as u16 * inv_weight) / 31) as u8; let b = ((sb as u16 * weight + fb as u16 * inv_weight) / 31) as u8;
@ -343,19 +345,19 @@ impl Gfx {
} }
} }
/// Retorna o uso real de memória das estruturas gráficas em bytes. /// Returns the actual memory usage of the graphics structures in bytes.
/// Reflete os buffers de índices, paletas e OAM conforme Capítulo 10.8. /// Reflects index buffers, palettes, and OAM as per Chapter 10.8.
pub fn memory_usage_bytes(&self) -> usize { pub fn memory_usage_bytes(&self) -> usize {
let mut total = 0; let mut total = 0;
// 1. Framebuffers (Front + Back) // 1. Framebuffers (Front + Back)
// Cada um é Vec<u16>, ocupando 2 bytes por pixel. // Each is Vec<u16>, occupying 2 bytes per pixel.
total += self.front.len() * 2; total += self.front.len() * 2;
total += self.back.len() * 2; total += self.back.len() * 2;
// 2. Tile Layers (4 Game Layers) // 2. Tile Layers (4 Game Layers)
for layer in &self.layers { for layer in &self.layers {
// Tamanho da struct + os dados do mapa (Vec<Tile>) // Struct size + map data (Vec<Tile>)
total += size_of::<ScrollableTileLayer>(); total += size_of::<ScrollableTileLayer>();
total += layer.map.tiles.len() * size_of::<crate::model::Tile>(); total += layer.map.tiles.len() * size_of::<crate::model::Tile>();
} }
@ -364,19 +366,19 @@ impl Gfx {
total += size_of::<HudTileLayer>(); total += size_of::<HudTileLayer>();
total += self.hud.map.tiles.len() * size_of::<crate::model::Tile>(); total += self.hud.map.tiles.len() * size_of::<crate::model::Tile>();
// 4. Tile Banks (Assets e Paletas) // 4. Tile Banks (Assets and Palettes)
for bank_opt in &self.banks { for bank_opt in &self.banks {
if let Some(bank) = bank_opt { if let Some(bank) = bank_opt {
total += size_of::<TileBank>(); total += size_of::<TileBank>();
total += bank.pixel_indices.len(); total += bank.pixel_indices.len();
// Tabela de Paletas: 256 paletas * 16 cores * tamanho da struct Color // Palette Table: 256 palettes * 16 colors * Color struct size
total += 256 * 16 * size_of::<Color>(); total += 256 * 16 * size_of::<Color>();
} }
} }
// 5. Sprites (OAM) // 5. Sprites (OAM)
// Array fixo de 512 Sprites. // Fixed array of 512 Sprites.
total += self.sprites.len() * size_of::<Sprite>(); total += self.sprites.len() * size_of::<Sprite>();
total total
@ -457,8 +459,8 @@ impl Gfx {
} }
} }
/// Faz blend em RGB565 por canal com saturação. /// Blends in RGB565 per channel with saturation.
/// `dst` e `src` são pixels RGB565 (u16). /// `dst` and `src` are RGB565 pixels (u16).
fn blend_rgb565(dst: u16, src: u16, mode: BlendMode) -> u16 { fn blend_rgb565(dst: u16, src: u16, mode: BlendMode) -> u16 {
match mode { match mode {
BlendMode::None => src, BlendMode::None => src,

View File

@ -9,7 +9,7 @@ pub struct Touch {
} }
impl Touch { impl Touch {
/// Flags transitórias devem durar apenas 1 frame. /// Transient flags should last only 1 frame.
pub fn begin_frame(&mut self, signals: &InputSignals) { pub fn begin_frame(&mut self, signals: &InputSignals) {
self.f.begin_frame(signals.f_signal); self.f.begin_frame(signals.f_signal);
self.x = signals.x_pos.clone(); self.x = signals.x_pos.clone();

View File

@ -85,7 +85,7 @@ mod tests {
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i)); service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
} }
let after = service.get_after(2); // seqs são 0, 1, 2, 3, 4. Deve retornar 3 e 4. let after = service.get_after(2); // seqs are 0, 1, 2, 3, 4. Should return 3 and 4.
assert_eq!(after.len(), 2); assert_eq!(after.len(), 2);
assert_eq!(after[0].msg, "Log 3"); assert_eq!(after[0].msg, "Log 3");
assert_eq!(after[1].msg, "Log 4"); assert_eq!(after[1].msg, "Log 4");

View File

@ -33,7 +33,7 @@ impl DirectoryCartridgeLoader {
let manifest_content = fs::read_to_string(manifest_path).map_err(|_| CartridgeError::IoError)?; let manifest_content = fs::read_to_string(manifest_path).map_err(|_| CartridgeError::IoError)?;
let manifest: CartridgeManifest = serde_json::from_str(&manifest_content).map_err(|_| CartridgeError::InvalidManifest)?; let manifest: CartridgeManifest = serde_json::from_str(&manifest_content).map_err(|_| CartridgeError::InvalidManifest)?;
// Validação adicional conforme requisitos // Additional validation as per requirements
if manifest.magic != "PMTU" { if manifest.magic != "PMTU" {
return Err(CartridgeError::InvalidManifest); return Err(CartridgeError::InvalidManifest);
} }
@ -73,7 +73,6 @@ pub struct PackedCartridgeLoader;
impl PackedCartridgeLoader { impl PackedCartridgeLoader {
pub fn load(_path: &Path) -> Result<Cartridge, CartridgeError> { pub fn load(_path: &Path) -> Result<Cartridge, CartridgeError> {
// Stub inicialmente, como solicitado
Err(CartridgeError::InvalidFormat) Err(CartridgeError::InvalidFormat)
} }
} }

View File

@ -1,10 +1,10 @@
/// Cor simples em RGB565 (0bRRRRRGGGGGGBBBBB). /// Simple RGB565 color (0bRRRRRGGGGGGBBBBB).
/// - 5 bits Red /// - 5 bits Red
/// - 6 bits Green /// - 6 bits Green
/// - 5 bits Blue /// - 5 bits Blue
/// ///
/// Não há canal alpha. /// There is no alpha channel.
/// Transparência é tratada via Color Key ou Blend Mode. /// Transparency is handled via Color Key or Blend Mode.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Color(pub u16); pub struct Color(pub u16);
@ -23,7 +23,7 @@ impl Color {
pub const COLOR_KEY: Self = Self::MAGENTA; pub const COLOR_KEY: Self = Self::MAGENTA;
pub const TRANSPARENT: Self = Self::MAGENTA; pub const TRANSPARENT: Self = Self::MAGENTA;
/// Extrai canais já na faixa nativa do RGB565: /// Extracts channels in the native RGB565 range:
/// R: 0..31, G: 0..63, B: 0..31 /// R: 0..31, G: 0..63, B: 0..31
#[inline(always)] #[inline(always)]
pub const fn unpack_to_native(px: u16) -> (u8, u8, u8) { pub const fn unpack_to_native(px: u16) -> (u8, u8, u8) {
@ -33,14 +33,14 @@ impl Color {
(r, g, b) (r, g, b)
} }
/// Incorpora canais já na faixa nativa do RGB565 em um pixel: /// Packs channels from the native RGB565 range into a pixel:
/// R: 0..31, G: 0..63, B: 0..31 /// R: 0..31, G: 0..63, B: 0..31
#[inline(always)] #[inline(always)]
pub const fn pack_from_native(r: u8, g: u8, b: u8) -> u16 { pub const fn pack_from_native(r: u8, g: u8, b: u8) -> u16 {
((r as u16 & 0x1F) << 11) | ((g as u16 & 0x3F) << 5) | (b as u16 & 0x1F) ((r as u16 & 0x1F) << 11) | ((g as u16 & 0x3F) << 5) | (b as u16 & 0x1F)
} }
/// Cria uma cor RGB565 a partir de componentes 8-bit (0..255). /// Creates an RGB565 color from 8-bit components (0..255).
pub const fn rgb(r: u8, g: u8, b: u8) -> Self { pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
let r5 = (r as u16 >> 3) & 0x1F; let r5 = (r as u16 >> 3) & 0x1F;
let g6 = (g as u16 >> 2) & 0x3F; let g6 = (g as u16 >> 2) & 0x3F;

View File

@ -9,13 +9,12 @@ pub enum TileSize {
pub struct TileBank { pub struct TileBank {
pub tile_size: TileSize, pub tile_size: TileSize,
pub width: usize, // em pixels pub width: usize, // in pixels
pub height: usize, // em pixels pub height: usize, // in pixels
// pub pixels: Vec<Color>,
/// Agora guardamos índices de 0 a 15 (4 bits por pixel simulados em 8 bits) /// Now we store indices from 0 to 15 (4 bits per pixel simulated in 8 bits)
pub pixel_indices: Vec<u8>, pub pixel_indices: Vec<u8>,
/// 256 paletas, cada uma com 16 cores (RGB565 como u16) /// 256 palettes, each with 16 colors (RGB565 as u16)
pub palettes: [[Color; 16]; 256], pub palettes: [[Color; 16]; 256],
} }
@ -25,14 +24,14 @@ impl TileBank {
tile_size, tile_size,
width, width,
height, height,
pixel_indices: vec![0; width * height], // Índice 0 = Transparente pixel_indices: vec![0; width * height], // Index 0 = Transparent
palettes: [[Color::BLACK; 16]; 256], palettes: [[Color::BLACK; 16]; 256],
} }
} }
/// Retorna a cor de um pixel específico dentro de um tile. /// Returns the color of a specific pixel inside a tile.
/// tile_id: o índice do tile no banco /// tile_id: the tile index in the bank
/// local_x, local_y: a posição do pixel dentro do tile (0 até tile_size-1) /// local_x, local_y: the pixel position inside the tile (0 to tile_size-1)
pub fn get_pixel_index(&self, tile_id: u16, local_x: usize, local_y: usize) -> u8 { pub fn get_pixel_index(&self, tile_id: u16, local_x: usize, local_y: usize) -> u8 {
let size = self.tile_size as usize; let size = self.tile_size as usize;
let tiles_per_row = self.width / size; let tiles_per_row = self.width / size;
@ -45,13 +44,13 @@ impl TileBank {
if pixel_x < self.width && pixel_y < self.height { if pixel_x < self.width && pixel_y < self.height {
self.pixel_indices[pixel_y * self.width + pixel_x] self.pixel_indices[pixel_y * self.width + pixel_x]
} else { } else {
0 // Fora do banco = Transparente 0 // Outside the bank = Transparent
} }
} }
/// Resolve um índice de pixel para uma Color real usando uma paleta. /// Resolves a pixel index to a real Color using a palette.
pub fn resolve_color(&self, palette_id: u8, pixel_index: u8) -> Color { pub fn resolve_color(&self, palette_id: u8, pixel_index: u8) -> Color {
// Regra: Índice 0 é sempre transparente (usamos MAGENTA/COLOR_KEY como vácuo) // Rule: Index 0 is always transparent (we use MAGENTA/COLOR_KEY as vacuum)
if pixel_index == 0 { if pixel_index == 0 {
return Color::COLOR_KEY; return Color::COLOR_KEY;
} }

View File

@ -3,7 +3,7 @@ use crate::log::{LogLevel, LogSource};
use crate::model::{Color, Rect, Window, WindowId}; use crate::model::{Color, Rect, Window, WindowId};
use crate::prometeu_os::PrometeuOS; use crate::prometeu_os::PrometeuOS;
/// Gerenciador de janelas do PROMETEU. /// PROMETEU Window Manager.
pub struct WindowManager { pub struct WindowManager {
pub windows: Vec<Window>, pub windows: Vec<Window>,
pub focused: Option<WindowId>, pub focused: Option<WindowId>,
@ -50,7 +50,7 @@ impl WindowManager {
} }
} }
/// PrometeuHub: Launcher e ambiente de UI do sistema. /// PrometeuHub: Launcher and system UI environment.
pub struct PrometeuHub { pub struct PrometeuHub {
pub window_manager: WindowManager, pub window_manager: WindowManager,
} }
@ -63,7 +63,7 @@ impl PrometeuHub {
} }
pub fn init(&mut self) { pub fn init(&mut self) {
// Inicializa o Window System e lista apps // Initializes the Window System and lists apps
} }
pub fn gui_update(&mut self, os: &mut PrometeuOS, hw: &mut dyn HardwareBridge) { pub fn gui_update(&mut self, os: &mut PrometeuOS, hw: &mut dyn HardwareBridge) {

View File

@ -9,8 +9,8 @@ use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant; use std::time::Instant;
/// PrometeuOS (POS): O firmware/base do sistema. /// PrometeuOS (POS): The system firmware/base.
/// Autoridade máxima do boot, periféricos, execução da PVM e tratamento de falhas. /// Maximum authority for boot, peripherals, PVM execution, and fault handling.
pub struct PrometeuOS { pub struct PrometeuOS {
pub tick_index: u64, pub tick_index: u64,
pub logical_frame_index: u64, pub logical_frame_index: u64,
@ -18,7 +18,7 @@ pub struct PrometeuOS {
pub logical_frame_remaining_cycles: u64, pub logical_frame_remaining_cycles: u64,
pub last_frame_cpu_time_us: u64, pub last_frame_cpu_time_us: u64,
// Assets de exemplo (mantidos para compatibilidade com syscalls de áudio v0) // Example assets (kept for compatibility with v0 audio syscalls)
pub sample_square: Option<Arc<Sample>>, pub sample_square: Option<Arc<Sample>>,
pub sample_kick: Option<Arc<Sample>>, pub sample_kick: Option<Arc<Sample>>,
pub sample_snare: Option<Arc<Sample>>, pub sample_snare: Option<Arc<Sample>>,
@ -37,7 +37,7 @@ pub struct PrometeuOS {
pub current_cartridge_app_mode: crate::model::AppMode, pub current_cartridge_app_mode: crate::model::AppMode,
pub logs_written_this_frame: HashMap<u32, u32>, pub logs_written_this_frame: HashMap<u32, u32>,
// Telemetria e Certificação // Telemetry and Certification
pub telemetry_current: TelemetryFrame, pub telemetry_current: TelemetryFrame,
pub telemetry_last: TelemetryFrame, pub telemetry_last: TelemetryFrame,
pub certifier: Certifier, pub certifier: Certifier,
@ -49,7 +49,7 @@ pub struct PrometeuOS {
impl PrometeuOS { impl PrometeuOS {
pub const CYCLES_PER_LOGICAL_FRAME: u64 = 100_000; pub const CYCLES_PER_LOGICAL_FRAME: u64 = 100_000;
pub const SLICE_PER_TICK: u64 = 100_000; // Por enquanto, o mesmo, mas permite granularidade diferente pub const SLICE_PER_TICK: u64 = 100_000; // For now the same, but allows different granularity
pub const MAX_LOG_LEN: usize = 256; pub const MAX_LOG_LEN: usize = 256;
pub const MAX_LOGS_PER_FRAME: u32 = 10; pub const MAX_LOGS_PER_FRAME: u32 = 10;
@ -83,7 +83,7 @@ impl PrometeuOS {
boot_time, boot_time,
}; };
// Inicializa samples básicos (mesma lógica do LogicalHardware) // Initializes basic samples (same logic as LogicalHardware)
os.sample_square = Some(Arc::new(Self::create_square_sample(440.0, 0.1))); os.sample_square = Some(Arc::new(Self::create_square_sample(440.0, 0.1)));
os.log(LogLevel::Info, LogSource::Pos, 0, "PrometeuOS starting...".to_string()); os.log(LogLevel::Info, LogSource::Pos, 0, "PrometeuOS starting...".to_string());
@ -135,18 +135,18 @@ impl PrometeuOS {
self.last_frame_cpu_time_us = 0; self.last_frame_cpu_time_us = 0;
} }
/// Carrega um cartucho na PVM e reseta o estado de execução. /// Loads a cartridge into the PVM and resets the execution state.
pub fn initialize_vm(&mut self, vm: &mut VirtualMachine, cartridge: &Cartridge) { pub fn initialize_vm(&mut self, vm: &mut VirtualMachine, cartridge: &Cartridge) {
vm.initialize(cartridge.program.clone(), &cartridge.entrypoint); vm.initialize(cartridge.program.clone(), &cartridge.entrypoint);
// Determina o app_id numérico // Determines the numeric app_id
self.current_app_id = cartridge.app_id; self.current_app_id = cartridge.app_id;
self.current_cartridge_title = cartridge.title.clone(); self.current_cartridge_title = cartridge.title.clone();
self.current_cartridge_app_version = cartridge.app_version.clone(); self.current_cartridge_app_version = cartridge.app_version.clone();
self.current_cartridge_app_mode = cartridge.app_mode; self.current_cartridge_app_mode = cartridge.app_mode;
} }
/// Executa uma única instrução da VM (Debug). /// Executes a single VM instruction (Debug).
pub fn debug_step_instruction(&mut self, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Option<String> { pub fn debug_step_instruction(&mut self, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Option<String> {
match vm.step(self, hw) { match vm.step(self, hw) {
Ok(_) => None, Ok(_) => None,
@ -158,7 +158,7 @@ impl PrometeuOS {
} }
} }
/// Executa um tick do host (60Hz). /// Executes a host tick (60Hz).
pub fn step_frame(&mut self, vm: &mut VirtualMachine, signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option<String> { pub fn step_frame(&mut self, vm: &mut VirtualMachine, signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option<String> {
let start = std::time::Instant::now(); let start = std::time::Instant::now();
self.tick_index += 1; self.tick_index += 1;
@ -174,25 +174,25 @@ impl PrometeuOS {
self.logical_frame_remaining_cycles = Self::CYCLES_PER_LOGICAL_FRAME; self.logical_frame_remaining_cycles = Self::CYCLES_PER_LOGICAL_FRAME;
self.begin_logical_frame(signals, hw); self.begin_logical_frame(signals, hw);
// Início do frame: resetar acumulador da telemetria (mas manter frame_index) // Beginning of frame: reset telemetry accumulator (but keep frame_index)
self.telemetry_current = TelemetryFrame { self.telemetry_current = TelemetryFrame {
frame_index: self.logical_frame_index, frame_index: self.logical_frame_index,
..Default::default() ..Default::default()
}; };
} }
// Budget para este tick: o mínimo entre a fatia do tick e o que resta no frame lógico // Budget for this tick: the minimum between the tick slice and what remains in the logical frame
let budget = std::cmp::min(Self::SLICE_PER_TICK, self.logical_frame_remaining_cycles); let budget = std::cmp::min(Self::SLICE_PER_TICK, self.logical_frame_remaining_cycles);
if budget > 0 { if budget > 0 {
// Executa budget // Execute budget
let run_result = vm.run_budget(budget, self, hw); let run_result = vm.run_budget(budget, self, hw);
match run_result { match run_result {
Ok(run) => { Ok(run) => {
self.logical_frame_remaining_cycles = self.logical_frame_remaining_cycles.saturating_sub(run.cycles_used); self.logical_frame_remaining_cycles = self.logical_frame_remaining_cycles.saturating_sub(run.cycles_used);
// Acumula métricas // Accumulates metrics
self.telemetry_current.cycles_used += run.cycles_used; self.telemetry_current.cycles_used += run.cycles_used;
self.telemetry_current.vm_steps += run.steps_executed; self.telemetry_current.vm_steps += run.steps_executed;
@ -205,14 +205,14 @@ impl PrometeuOS {
if run.reason == crate::virtual_machine::LogicalFrameEndingReason::FrameSync { if run.reason == crate::virtual_machine::LogicalFrameEndingReason::FrameSync {
hw.gfx_mut().render_all(); hw.gfx_mut().render_all();
// Finaliza telemetria do frame (host_cpu_time será refinado no final do tick) // Finalizes frame telemetry (host_cpu_time will be refined at the end of the tick)
self.telemetry_current.host_cpu_time_us = start.elapsed().as_micros() as u64; self.telemetry_current.host_cpu_time_us = start.elapsed().as_micros() as u64;
// Certificação (CAP) // Certification (CAP)
let ts_ms = self.boot_time.elapsed().as_millis() as u64; let ts_ms = self.boot_time.elapsed().as_millis() as u64;
self.telemetry_current.violations = self.certifier.evaluate(&self.telemetry_current, &mut self.log_service, ts_ms) as u32; self.telemetry_current.violations = self.certifier.evaluate(&self.telemetry_current, &mut self.log_service, ts_ms) as u32;
// Latch: o que o overlay lê // Latch: what the overlay reads
self.telemetry_last = self.telemetry_current; self.telemetry_last = self.telemetry_current;
self.logical_frame_index += 1; self.logical_frame_index += 1;
@ -235,7 +235,7 @@ impl PrometeuOS {
self.last_frame_cpu_time_us = start.elapsed().as_micros() as u64; self.last_frame_cpu_time_us = start.elapsed().as_micros() as u64;
// Se o frame acabou neste tick, atualizamos o tempo real final no latch // If the frame ended in this tick, we update the final real time in the latch
if !self.logical_frame_active && self.telemetry_last.frame_index == self.logical_frame_index.wrapping_sub(1) { if !self.logical_frame_active && self.telemetry_last.frame_index == self.logical_frame_index.wrapping_sub(1) {
self.telemetry_last.host_cpu_time_us = self.last_frame_cpu_time_us; self.telemetry_last.host_cpu_time_us = self.last_frame_cpu_time_us;
} }
@ -367,16 +367,16 @@ mod tests {
}; };
os.initialize_vm(&mut vm, &cartridge); os.initialize_vm(&mut vm, &cartridge);
// Primeiro tick // First tick
os.step_frame(&mut vm, &signals, &mut hw); os.step_frame(&mut vm, &signals, &mut hw);
let cycles_after_tick_1 = vm.cycles; let cycles_after_tick_1 = vm.cycles;
assert!(cycles_after_tick_1 >= PrometeuOS::CYCLES_PER_LOGICAL_FRAME); assert!(cycles_after_tick_1 >= PrometeuOS::CYCLES_PER_LOGICAL_FRAME);
// Segundo tick - Agora ele NÃO deve ganhar mais budget // Second tick - Now it SHOULD NOT gain more budget
os.step_frame(&mut vm, &signals, &mut hw); os.step_frame(&mut vm, &signals, &mut hw);
let cycles_after_tick_2 = vm.cycles; let cycles_after_tick_2 = vm.cycles;
// CORREÇÃO: Ele não deve ter consumido ciclos no segundo tick porque o budget do frame lógico acabou // FIX: It should not have consumed cycles in the second tick because the logical frame budget ended
println!("Cycles after tick 1: {}, tick 2: {}", cycles_after_tick_1, cycles_after_tick_2); println!("Cycles after tick 1: {}, tick 2: {}", cycles_after_tick_1, cycles_after_tick_2);
assert_eq!(cycles_after_tick_2, cycles_after_tick_1, "VM should NOT have consumed more cycles in the second tick because logical frame budget is exhausted"); assert_eq!(cycles_after_tick_2, cycles_after_tick_1, "VM should NOT have consumed more cycles in the second tick because logical frame budget is exhausted");
} }
@ -388,7 +388,7 @@ mod tests {
let mut hw = Hardware::new(); let mut hw = Hardware::new();
let signals = InputSignals::default(); let signals = InputSignals::default();
// Loop que chama FrameSync: // Loop that calls FrameSync:
// PUSH_CONST 0 (dummy) // PUSH_CONST 0 (dummy)
// FrameSync (0x80) // FrameSync (0x80)
// JMP 0 // JMP 0
@ -407,15 +407,15 @@ mod tests {
}; };
os.initialize_vm(&mut vm, &cartridge); os.initialize_vm(&mut vm, &cartridge);
// Primeiro tick // First tick
os.step_frame(&mut vm, &signals, &mut hw); os.step_frame(&mut vm, &signals, &mut hw);
let cycles_after_tick_1 = vm.cycles; let cycles_after_tick_1 = vm.cycles;
// Deve ter parado no FrameSync // Should have stopped at FrameSync
assert!(cycles_after_tick_1 > 0, "VM should have consumed some cycles"); assert!(cycles_after_tick_1 > 0, "VM should have consumed some cycles");
assert!(cycles_after_tick_1 < PrometeuOS::CYCLES_PER_LOGICAL_FRAME); assert!(cycles_after_tick_1 < PrometeuOS::CYCLES_PER_LOGICAL_FRAME);
// Segundo tick - Deve resetar o budget e rodar mais um pouco até o próximo FrameSync // Second tick - Should reset the budget and run a bit more until the next FrameSync
os.step_frame(&mut vm, &signals, &mut hw); os.step_frame(&mut vm, &signals, &mut hw);
let cycles_after_tick_2 = vm.cycles; let cycles_after_tick_2 = vm.cycles;
@ -430,7 +430,7 @@ mod tests {
os.current_app_id = 123; os.current_app_id = 123;
// 1. Teste de log normal // 1. Normal log test
vm.push(Value::Integer(2)); // Info vm.push(Value::Integer(2)); // Info
vm.push(Value::String("Hello Log".to_string())); vm.push(Value::String("Hello Log".to_string()));
let res = os.syscall(0x5001, &mut vm, &mut hw); let res = os.syscall(0x5001, &mut vm, &mut hw);
@ -441,7 +441,7 @@ mod tests {
assert_eq!(recent[0].level, LogLevel::Info); assert_eq!(recent[0].level, LogLevel::Info);
assert_eq!(recent[0].source, LogSource::App { app_id: 123 }); assert_eq!(recent[0].source, LogSource::App { app_id: 123 });
// 2. Teste de truncamento // 2. Truncation test
let long_msg = "A".repeat(300); let long_msg = "A".repeat(300);
vm.push(Value::Integer(3)); // Warn vm.push(Value::Integer(3)); // Warn
vm.push(Value::String(long_msg)); vm.push(Value::String(long_msg));
@ -451,27 +451,27 @@ mod tests {
assert_eq!(recent[0].msg.len(), 256); assert_eq!(recent[0].msg.len(), 256);
assert!(recent[0].msg.starts_with("AAAAA")); assert!(recent[0].msg.starts_with("AAAAA"));
// 3. Teste de Rate Limit // 3. Rate Limit Test
// Já fizemos 2 logs. O limite é 10. // We already made 2 logs. The limit is 10.
for i in 0..8 { for i in 0..8 {
vm.push(Value::Integer(2)); vm.push(Value::Integer(2));
vm.push(Value::String(format!("Log {}", i))); vm.push(Value::String(format!("Log {}", i)));
os.syscall(0x5001, &mut vm, &mut hw).unwrap(); os.syscall(0x5001, &mut vm, &mut hw).unwrap();
} }
// O 11º log deve ser ignorado (e deve gerar um aviso do sistema) // The 11th log should be ignored (and generate a system warning)
vm.push(Value::Integer(2)); vm.push(Value::Integer(2));
vm.push(Value::String("Eleventh log".to_string())); vm.push(Value::String("Eleventh log".to_string()));
os.syscall(0x5001, &mut vm, &mut hw).unwrap(); os.syscall(0x5001, &mut vm, &mut hw).unwrap();
let recent = os.log_service.get_recent(2); let recent = os.log_service.get_recent(2);
// O último log deve ser o aviso de rate limit (veio depois do 10º log tentado) // The last log should be the rate limit warning (came after the 10th log attempted)
assert_eq!(recent[1].msg, "App exceeded log limit per frame"); assert_eq!(recent[1].msg, "App exceeded log limit per frame");
assert_eq!(recent[1].level, LogLevel::Warn); assert_eq!(recent[1].level, LogLevel::Warn);
// O log "Eleventh log" não deve estar lá // The log "Eleventh log" should not be there
assert_ne!(recent[0].msg, "Eleventh log"); assert_ne!(recent[0].msg, "Eleventh log");
// 4. Teste de reset do rate limit no próximo frame // 4. Rate limit reset test in the next frame
os.begin_logical_frame(&InputSignals::default(), &mut hw); os.begin_logical_frame(&InputSignals::default(), &mut hw);
vm.push(Value::Integer(2)); vm.push(Value::Integer(2));
vm.push(Value::String("New frame log".to_string())); vm.push(Value::String("New frame log".to_string()));
@ -480,7 +480,7 @@ mod tests {
let recent = os.log_service.get_recent(1); let recent = os.log_service.get_recent(1);
assert_eq!(recent[0].msg, "New frame log"); assert_eq!(recent[0].msg, "New frame log");
// 5. Teste de LOG_WRITE_TAG // 5. LOG_WRITE_TAG test
vm.push(Value::Integer(2)); // Info vm.push(Value::Integer(2)); // Info
vm.push(Value::Integer(42)); // Tag vm.push(Value::Integer(42)); // Tag
vm.push(Value::String("Tagged Log".to_string())); vm.push(Value::String("Tagged Log".to_string()));
@ -623,7 +623,7 @@ impl NativeInterface for PrometeuOS {
}; };
match self.fs.list_dir(&path) { match self.fs.list_dir(&path) {
Ok(entries) => { Ok(entries) => {
// Por enquanto, retorna uma string separada por ';' // For now, returns a string separated by ';'
let names: Vec<String> = entries.into_iter().map(|e| e.name).collect(); let names: Vec<String> = entries.into_iter().map(|e| e.name).collect();
vm.push(Value::String(names.join(";"))); vm.push(Value::String(names.join(";")));
Ok(500) Ok(500)

View File

@ -2,25 +2,25 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)] #[repr(u16)]
pub enum OpCode { pub enum OpCode {
// 6.1 Controle de Execução // 6.1 Execution Control
Nop = 0x00, Nop = 0x00,
Halt = 0x01, Halt = 0x01,
Jmp = 0x02, Jmp = 0x02,
JmpIfFalse = 0x03, JmpIfFalse = 0x03,
// 6.2 Pilha // 6.2 Stack
PushConst = 0x10, PushConst = 0x10,
Pop = 0x11, Pop = 0x11,
Dup = 0x12, Dup = 0x12,
Swap = 0x13, Swap = 0x13,
// 6.3 Aritmética // 6.3 Arithmetic
Add = 0x20, Add = 0x20,
Sub = 0x21, Sub = 0x21,
Mul = 0x22, Mul = 0x22,
Div = 0x23, Div = 0x23,
// 6.4 Comparação e Lógica // 6.4 Comparison and Logic
Eq = 0x30, Eq = 0x30,
Neq = 0x31, Neq = 0x31,
Lt = 0x32, Lt = 0x32,
@ -29,13 +29,13 @@ pub enum OpCode {
Or = 0x35, Or = 0x35,
Not = 0x36, Not = 0x36,
// 6.5 Variáveis // 6.5 Variables
GetGlobal = 0x40, GetGlobal = 0x40,
SetGlobal = 0x41, SetGlobal = 0x41,
GetLocal = 0x42, GetLocal = 0x42,
SetLocal = 0x43, SetLocal = 0x43,
// 6.6 Funções // 6.6 Functions
Call = 0x50, Call = 0x50,
Ret = 0x51, Ret = 0x51,
PushScope = 0x52, PushScope = 0x52,
@ -46,7 +46,7 @@ pub enum OpCode {
LoadRef = 0x61, LoadRef = 0x61,
StoreRef = 0x62, StoreRef = 0x62,
// 6.8 Periféricos e Sistema // 6.8 Peripherals and System
Syscall = 0x70, Syscall = 0x70,
FrameSync = 0x80, FrameSync = 0x80,
} }
@ -126,7 +126,7 @@ impl OpCode {
OpCode::Alloc => 10, OpCode::Alloc => 10,
OpCode::LoadRef => 3, OpCode::LoadRef => 3,
OpCode::StoreRef => 3, OpCode::StoreRef => 3,
OpCode::Syscall => 1, // Variável, mas vamos usar 1 como base ou definir via ID OpCode::Syscall => 1, // Variable, but we'll use 1 as base or define via ID
OpCode::FrameSync => 1, OpCode::FrameSync => 1,
} }
} }

View File

@ -7,7 +7,7 @@ pub enum Value {
Float(f64), Float(f64),
Boolean(bool), Boolean(bool),
String(String), String(String),
Ref(usize), // Referência ao heap Ref(usize), // Heap reference
Null, Null,
} }

View File

@ -27,7 +27,7 @@ pub struct VirtualMachine {
pub call_stack: Vec<CallFrame>, pub call_stack: Vec<CallFrame>,
pub globals: Vec<Value>, pub globals: Vec<Value>,
pub program: Program, pub program: Program,
pub heap: Vec<Value>, // Simplificado para demo, futuramente RAM/Heap real pub heap: Vec<Value>, // Simplified for demo, future real RAM/Heap
pub cycles: u64, pub cycles: u64,
pub halted: bool, pub halted: bool,
pub breakpoints: std::collections::HashSet<usize>, pub breakpoints: std::collections::HashSet<usize>,
@ -56,12 +56,12 @@ impl VirtualMachine {
self.program = Program::new(program_bytes, vec![]); self.program = Program::new(program_bytes, vec![]);
} }
} else { } else {
// Por enquanto, tratamos os bytes como a ROM diretamente. // For now, we treat the bytes as the ROM directly.
self.program = Program::new(program_bytes, vec![]); self.program = Program::new(program_bytes, vec![]);
} }
// Se o entrypoint for numérico, podemos tentar usá-lo como PC inicial. // If the entrypoint is numeric, we can try to use it as the initial PC.
// Se não, por enquanto ignoramos ou começamos do 0. // If not, for now we ignore it or start from 0.
if let Ok(addr) = entrypoint.parse::<usize>() { if let Ok(addr) = entrypoint.parse::<usize>() {
self.pc = addr; self.pc = addr;
} else { } else {
@ -173,7 +173,7 @@ impl VirtualMachine {
let pc_before = self.pc; let pc_before = self.pc;
let cycles_before = self.cycles; let cycles_before = self.cycles;
// Fast-path: FRAME_SYNC encerra o frame lógico // Fast-path: FRAME_SYNC ends the logical frame
let opcode_val = self.peek_u16()?; let opcode_val = self.peek_u16()?;
let opcode = OpCode::try_from(opcode_val)?; let opcode = OpCode::try_from(opcode_val)?;
if opcode == OpCode::FrameSync { if opcode == OpCode::FrameSync {
@ -187,7 +187,7 @@ impl VirtualMachine {
self.step(native, hw)?; self.step(native, hw)?;
steps_executed += 1; steps_executed += 1;
// garante progresso real // ensures real progress
if self.pc == pc_before && self.cycles == cycles_before && !self.halted { if self.pc == pc_before && self.cycles == cycles_before && !self.halted {
return Err(format!("VM stuck at PC 0x{:08X}", self.pc)); return Err(format!("VM stuck at PC 0x{:08X}", self.pc));
} }

View File

@ -1,17 +1,17 @@
# PROMETEU Desktop Runtime # PROMETEU Desktop Runtime
Esta é a implementação de host para plataformas desktop, permitindo que o PROMETEU rode em Windows, Linux e macOS. This is the host implementation for desktop platforms, allowing PROMETEU to run on Windows, Linux, and macOS.
## Funcionalidades ## Features
- **Renderização**: Utiliza a GPU via biblioteca `pixels` para apresentar o framebuffer de baixa resolução. - **Rendering**: Uses the GPU via the `pixels` library to present the low-resolution framebuffer.
- **Input**: Traduz eventos de teclado e controle (via `winit`) para os sinais de hardware do PROMETEU. - **Input**: Translates keyboard and controller events (via `winit`) into PROMETEU hardware signals.
- **Áudio**: Interface com o sistema de som do host (via `cpal`). - **Audio**: Interfaces with the host's sound system (via `cpal`).
- **Debugging**: Hospeda um servidor TCP que implementa o **DevTools Protocol**, permitindo conexões de IDEs ou debuggers externos. - **Debugging**: Hosts a TCP server that implements the **DevTools Protocol**, allowing connections from external IDEs or debuggers.
## Como rodar ## How to run
Geralmente executado via CLI principal (`prometeu`), mas pode ser chamado diretamente para testes: Generally executed via the main CLI (`prometeu`), but can be called directly for testing:
```bash ```bash
cargo run -- --run path/to/cart cargo run -- --run path/to/cart

View File

@ -39,7 +39,7 @@ impl HostAudio {
let mut mixer = AudioMixer::new(); let mut mixer = AudioMixer::new();
// Para passar dados de performance da thread de áudio para a principal // To pass performance data from the audio thread to the main thread
let audio_perf_rb = HeapRb::<u64>::new(64); let audio_perf_rb = HeapRb::<u64>::new(64);
let (mut perf_prod, perf_cons) = audio_perf_rb.split(); let (mut perf_prod, perf_cons) = audio_perf_rb.split();
@ -47,13 +47,13 @@ impl HostAudio {
.build_output_stream( .build_output_stream(
&config, &config,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
// Consome comandos da ringbuffer // Consumes commands from ringbuffer
while let Some(cmd) = cons.try_pop() { while let Some(cmd) = cons.try_pop() {
mixer.process_command(cmd); mixer.process_command(cmd);
} }
// Mixa áudio // Mixes audio
mixer.fill_buffer(data); mixer.fill_buffer(data);
// Envia tempo de processamento em microssegundos // Sends processing time in microseconds
let _ = perf_prod.try_push(mixer.last_processing_time.as_micros() as u64); let _ = perf_prod.try_push(mixer.last_processing_time.as_micros() as u64);
}, },
|err| eprintln!("audio stream error: {}", err), |err| eprintln!("audio stream error: {}", err),
@ -144,7 +144,7 @@ impl AudioMixer {
pub fn fill_buffer(&mut self, buffer: &mut [f32]) { pub fn fill_buffer(&mut self, buffer: &mut [f32]) {
let start = std::time::Instant::now(); let start = std::time::Instant::now();
// Zera o buffer (estéreo) // Zeroes the buffer (stereo)
for sample in buffer.iter_mut() { for sample in buffer.iter_mut() {
*sample = 0.0; *sample = 0.0;
} }
@ -172,7 +172,7 @@ impl AudioMixer {
break; break;
} }
// Interpolação Linear // Linear Interpolation
let s1 = sample_data.data[pos_int] as f32 / 32768.0; let s1 = sample_data.data[pos_int] as f32 / 32768.0;
let s2 = if pos_int + 1 < sample_data.data.len() { let s2 = if pos_int + 1 < sample_data.data.len() {
sample_data.data[pos_int + 1] as f32 / 32768.0 sample_data.data[pos_int + 1] as f32 / 32768.0
@ -204,7 +204,7 @@ impl AudioMixer {
} }
} }
// Clamp final para evitar clipping (opcional se usarmos f32, mas bom para fidelidade) // Final clamp to avoid clipping (optional if using f32, but good for fidelity)
for sample in buffer.iter_mut() { for sample in buffer.iter_mut() {
*sample = sample.clamp(-1.0, 1.0); *sample = sample.clamp(-1.0, 1.0);
} }

View File

@ -28,7 +28,7 @@ impl HostDebugger {
if let BootTarget::Cartridge { path, debug: true, debug_port } = boot_target { if let BootTarget::Cartridge { path, debug: true, debug_port } = boot_target {
self.waiting_for_start = true; self.waiting_for_start = true;
// Pré-carrega informações do cartucho para o handshake // Pre-loads cartridge information for the handshake
if let Ok(cartridge) = CartridgeLoader::load(path) { if let Ok(cartridge) = CartridgeLoader::load(path) {
firmware.os.initialize_vm(&mut firmware.vm, &cartridge); firmware.os.initialize_vm(&mut firmware.vm, &cartridge);
} }
@ -75,7 +75,7 @@ impl HostDebugger {
self.stream = Some(stream); self.stream = Some(stream);
// Enviar Handshake // Send Handshake
let handshake = DebugResponse::Handshake { let handshake = DebugResponse::Handshake {
protocol_version: DEVTOOLS_PROTOCOL_VERSION, protocol_version: DEVTOOLS_PROTOCOL_VERSION,
runtime_version: "0.1".to_string(), runtime_version: "0.1".to_string(),
@ -104,10 +104,10 @@ impl HostDebugger {
} }
Ok(n) => { Ok(n) => {
let data = &buf[..n]; let data = &buf[..n];
// Processar múltiplos comandos se houver \n // Process multiple commands if there's \n
let msg = String::from_utf8_lossy(data); let msg = String::from_utf8_lossy(data);
self.stream = Some(stream); // Coloca de volta antes de processar comandos self.stream = Some(stream); // Put it back before processing commands
for line in msg.lines() { for line in msg.lines() {
let trimmed = line.trim(); let trimmed = line.trim();
@ -154,7 +154,7 @@ impl HostDebugger {
} }
DebugCommand::Step => { DebugCommand::Step => {
firmware.os.paused = true; firmware.os.paused = true;
// Executa uma instrução imediatamente // Executes an instruction immediately
let _ = firmware.os.debug_step_instruction(&mut firmware.vm, hardware); let _ = firmware.os.debug_step_instruction(&mut firmware.vm, hardware);
} }
DebugCommand::StepFrame => { DebugCommand::StepFrame => {
@ -192,7 +192,7 @@ impl HostDebugger {
for event in new_events { for event in new_events {
self.last_log_seq = event.seq; self.last_log_seq = event.seq;
// Verifica se é um breakpoint hit via tag // Check if it's a breakpoint hit via tag
if event.tag == 0xDEB1 { if event.tag == 0xDEB1 {
self.send_event(DebugEvent::BreakpointHit { self.send_event(DebugEvent::BreakpointHit {
pc: firmware.vm.pc, pc: firmware.vm.pc,
@ -200,7 +200,7 @@ impl HostDebugger {
}); });
} }
// Certificação via Tags 0xCA01-0xCA03 // Certification via Tags 0xCA01-0xCA03
if event.tag >= 0xCA01 && event.tag <= 0xCA03 { if event.tag >= 0xCA01 && event.tag <= 0xCA03 {
let rule = match event.tag { let rule = match event.tag {
0xCA01 => "cycles_budget", 0xCA01 => "cycles_budget",
@ -211,7 +211,7 @@ impl HostDebugger {
self.send_event(DebugEvent::Cert { self.send_event(DebugEvent::Cert {
rule, rule,
used: 0, // Simplificado, informações detalhadas estão na msg do log used: 0, // Simplified, detailed information is in the log message
limit: 0, limit: 0,
frame_index: firmware.os.logical_frame_index, frame_index: firmware.os.logical_frame_index,
}); });

View File

@ -21,7 +21,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut debug_mode = false; let mut debug_mode = false;
let mut debug_port = 7777; let mut debug_port = 7777;
let mut i = 1; // Pula o nome do executável let mut i = 1; // Skip the executable name
while i < args.len() { while i < args.len() {
match args[i].as_str() { match args[i].as_str() {
"--run" => { "--run" => {

View File

@ -95,7 +95,7 @@ impl HostRunner {
fn display_dbg_overlay(&mut self) { fn display_dbg_overlay(&mut self) {
let tel = &self.firmware.os.telemetry_last; let tel = &self.firmware.os.telemetry_last;
let color_text = prometeu_core::model::Color::WHITE; let color_text = prometeu_core::model::Color::WHITE;
let color_bg = prometeu_core::model::Color::INDIGO; // Azul escuro para destacar let color_bg = prometeu_core::model::Color::INDIGO; // Dark blue to stand out
let color_warn = prometeu_core::model::Color::RED; let color_warn = prometeu_core::model::Color::RED;
self.hardware.gfx.fill_rect(5, 5, 140, 65, color_bg); self.hardware.gfx.fill_rect(5, 5, 140, 65, color_bg);
@ -129,7 +129,7 @@ impl ApplicationHandler for HostRunner {
let window = event_loop.create_window(attrs).expect("failed to create window"); let window = event_loop.create_window(attrs).expect("failed to create window");
// 🔥 Leak: Window vira &'static Window (bootstrap) // 🔥 Leak: Window becomes &'static Window (bootstrap)
let window: &'static Window = Box::leak(Box::new(window)); let window: &'static Window = Box::leak(Box::new(window));
self.window = Some(window); self.window = Some(window);
@ -165,18 +165,18 @@ impl ApplicationHandler for HostRunner {
} }
WindowEvent::RedrawRequested => { WindowEvent::RedrawRequested => {
// Pegue o Pixels diretamente do campo (não via helper que pega &mut self inteiro) // Get Pixels directly from the field (not via helper that gets the entire &mut self)
let pixels = self.pixels.as_mut().expect("pixels not initialized"); let pixels = self.pixels.as_mut().expect("pixels not initialized");
{ {
// Borrow mutável do frame (dura só dentro deste bloco) // Mutable borrow of the frame (lasts only within this block)
let frame = pixels.frame_mut(); let frame = pixels.frame_mut();
// Borrow imutável do prometeu-core (campo diferente, ok) // Immutable borrow of prometeu-core (different field, ok)
let src = self.hardware.gfx.front_buffer(); let src = self.hardware.gfx.front_buffer();
draw_rgb565_to_rgba8(src, frame); draw_rgb565_to_rgba8(src, frame);
} // <- frame borrow termina aqui } // <- frame borrow ends here
if pixels.render().is_err() { if pixels.render().is_err() {
event_loop.exit(); event_loop.exit();
@ -206,7 +206,7 @@ impl ApplicationHandler for HostRunner {
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
self.debugger.check_commands(&mut self.firmware, &mut self.hardware); self.debugger.check_commands(&mut self.firmware, &mut self.hardware);
// Atualiza estado do Filesystem no OS (específico do prometeu-runtime-desktop) // Updates Filesystem state in OS (specific to prometeu-runtime-desktop)
if let Some(root) = &self.fs_root { if let Some(root) = &self.fs_root {
use prometeu_core::fs::FsState; use prometeu_core::fs::FsState;
if matches!(self.firmware.os.fs_state, FsState::Unmounted | FsState::Error(_)) { if matches!(self.firmware.os.fs_state, FsState::Unmounted | FsState::Error(_)) {
@ -220,7 +220,7 @@ impl ApplicationHandler for HostRunner {
let now = Instant::now(); let now = Instant::now();
let mut frame_delta = now.duration_since(self.last_frame_time); let mut frame_delta = now.duration_since(self.last_frame_time);
// Limitador para evitar a "espiral da morte" se o SO travar (máximo de 100ms por volta) // Limiter to avoid the "death spiral" if the OS freezes (max 100ms per loop)
if frame_delta > Duration::from_millis(100) { if frame_delta > Duration::from_millis(100) {
frame_delta = Duration::from_millis(100); frame_delta = Duration::from_millis(100);
} }
@ -228,7 +228,7 @@ impl ApplicationHandler for HostRunner {
self.last_frame_time = now; self.last_frame_time = now;
self.accumulator += frame_delta; self.accumulator += frame_delta;
// 🔥 O coração do determinismo: consome o tempo em fatias exatas de 60Hz // 🔥 The heart of determinism: consumes time in exact 60Hz slices
while self.accumulator >= self.frame_target_dt { while self.accumulator >= self.frame_target_dt {
if !self.debugger.waiting_for_start { if !self.debugger.waiting_for_start {
self.firmware.step_frame(&self.input.signals, &mut self.hardware); self.firmware.step_frame(&self.input.signals, &mut self.hardware);
@ -242,10 +242,10 @@ impl ApplicationHandler for HostRunner {
self.audio.update_stats(&mut self.stats); self.audio.update_stats(&mut self.stats);
// Atualiza estatísticas a cada 1 segundo real // Updates statistics every 1 real second
self.stats.update(now, self.window, &self.hardware, &self.firmware); self.stats.update(now, self.window, &self.hardware, &self.firmware);
// Processa logs do sistema // Process system logs
let last_seq = self.log_sink.last_seq().unwrap_or(u64::MAX); let last_seq = self.log_sink.last_seq().unwrap_or(u64::MAX);
let new_events = if last_seq == u64::MAX { let new_events = if last_seq == u64::MAX {
self.firmware.os.log_service.get_recent(4096) self.firmware.os.log_service.get_recent(4096)
@ -254,11 +254,11 @@ impl ApplicationHandler for HostRunner {
}; };
self.log_sink.process_events(new_events); self.log_sink.process_events(new_events);
// Overlay de Telemetria // Telemetry Overlay
if self.overlay_enabled { if self.overlay_enabled {
self.hardware.gfx.present(); // Traz o front para o back para desenhar por cima self.hardware.gfx.present(); // Bring front to back to draw over
self.display_dbg_overlay(); self.display_dbg_overlay();
self.hardware.gfx.present(); // Devolve para o front com o overlay aplicado self.hardware.gfx.present(); // Return to front with overlay applied
} }
self.request_redraw(); self.request_redraw();
@ -286,37 +286,37 @@ mod tests {
assert!(runner.debugger.waiting_for_start); assert!(runner.debugger.waiting_for_start);
assert!(runner.debugger.listener.is_some()); assert!(runner.debugger.listener.is_some());
// Verifica se conseguimos conectar // Check if we can connect
{ {
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar"); let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
// Pequeno sleep para garantir que o SO processe // Short sleep to ensure the OS processes
std::thread::sleep(std::time::Duration::from_millis(100)); std::thread::sleep(std::time::Duration::from_millis(100));
// Simula o loop para aceitar a conexão // Simulates the loop to accept the connection
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_some(), "Stream deve ter sido mantido aberto"); assert!(runner.debugger.stream.is_some(), "Stream should have been kept open");
// Verifica Handshake // Handshake Check
let mut buf = [0u8; 2048]; let mut buf = [0u8; 2048];
let n = stream.read(&mut buf).expect("Deve ler handshake"); let n = stream.read(&mut buf).expect("Should read handshake");
let resp: serde_json::Value = serde_json::from_slice(&buf[..n]).expect("Handshake deve ser JSON válido"); let resp: serde_json::Value = serde_json::from_slice(&buf[..n]).expect("Handshake should be valid JSON");
assert_eq!(resp["type"], "handshake"); assert_eq!(resp["type"], "handshake");
assert_eq!(resp["protocol_version"], DEVTOOLS_PROTOCOL_VERSION); assert_eq!(resp["protocol_version"], DEVTOOLS_PROTOCOL_VERSION);
// Envia start via JSON // Send start via JSON
stream.write_all(b"{\"type\":\"start\"}\n").expect("Conexão deve estar aberta para escrita"); stream.write_all(b"{\"type\":\"start\"}\n").expect("Connection should be open for writing");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
// Processa o comando recebido // Process the received command
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(!runner.debugger.waiting_for_start, "Execução deve ter iniciado após comando start"); assert!(!runner.debugger.waiting_for_start, "Execution should have started after start command");
assert!(runner.debugger.listener.is_some(), "Listener deve permanecer aberto para reconexões"); assert!(runner.debugger.listener.is_some(), "Listener should remain open for reconnections");
} }
// Agora que o stream saiu do escopo do teste, o runner deve detectar o fechamento no próximo check // Now that the stream is out of the test scope, the runner should detect closure on next check
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_none(), "Stream deve ter sido fechado após o cliente desconectar"); assert!(runner.debugger.stream.is_none(), "Stream should have been closed after client disconnected");
} }
#[test] #[test]
@ -329,32 +329,32 @@ mod tests {
debug_port: port, debug_port: port,
}); });
// 1. Conecta e inicia // 1. Connect and start
{ {
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 1"); let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 1");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_some()); assert!(runner.debugger.stream.is_some());
stream.write_all(b"{\"type\":\"start\"}\n").expect("Deve escrever start"); stream.write_all(b"{\"type\":\"start\"}\n").expect("Should write start");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(!runner.debugger.waiting_for_start); assert!(!runner.debugger.waiting_for_start);
// Atualmente o listener é fechado aqui. // Currently the listener is closed here.
} }
// 2. Desconecta (limpa o stream no runner) // 2. Disconnect (clears stream in runner)
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_none()); assert!(runner.debugger.stream.is_none());
// 3. Tenta reconectar - DEVE FALHAR atualmente, mas queremos que FUNCIONE // 3. Try to reconnect - SHOULD FAIL currently, but we want it to WORK
let stream2 = TcpStream::connect(format!("127.0.0.1:{}", port)); let stream2 = TcpStream::connect(format!("127.0.0.1:{}", port));
assert!(stream2.is_ok(), "Deve aceitar nova conexão mesmo após o start"); assert!(stream2.is_ok(), "Should accept new connection even after start");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_some(), "Stream deve ter sido aceito na reconexão"); assert!(runner.debugger.stream.is_some(), "Stream should have been accepted on reconnection");
} }
#[test] #[test]
@ -367,24 +367,24 @@ mod tests {
debug_port: port, debug_port: port,
}); });
// 1. Primeira conexão // 1. First connection
let mut _stream1 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 1"); let mut _stream1 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 1");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.debugger.stream.is_some()); assert!(runner.debugger.stream.is_some());
// 2. Segunda conexão // 2. Second connection
let mut stream2 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 2 (SO aceita)"); let mut stream2 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 2 (OS accepts)");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); // Deve aceitar e fechar stream2 runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); // Should accept and close stream2
// Verifica se stream2 foi fechado pelo servidor // Check if stream2 was closed by the server
let mut buf = [0u8; 10]; let mut buf = [0u8; 10];
stream2.set_read_timeout(Some(std::time::Duration::from_millis(100))).unwrap(); stream2.set_read_timeout(Some(std::time::Duration::from_millis(100))).unwrap();
let res = stream2.read(&mut buf); let res = stream2.read(&mut buf);
assert!(matches!(res, Ok(0)) || res.is_err(), "Segunda conexão deve ser fechada pelo servidor"); assert!(matches!(res, Ok(0)) || res.is_err(), "Second connection should be closed by server");
assert!(runner.debugger.stream.is_some(), "Primeira conexão deve continuar ativa"); assert!(runner.debugger.stream.is_some(), "First connection should continue active");
} }
#[test] #[test]
@ -397,7 +397,7 @@ mod tests {
debug_port: port, debug_port: port,
}); });
let stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar"); let stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
std::thread::sleep(std::time::Duration::from_millis(100)); std::thread::sleep(std::time::Duration::from_millis(100));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
@ -405,19 +405,19 @@ mod tests {
let mut reader = std::io::BufReader::new(stream); let mut reader = std::io::BufReader::new(stream);
let mut line = String::new(); let mut line = String::new();
reader.read_line(&mut line).expect("Deve ler handshake"); reader.read_line(&mut line).expect("Should read handshake");
assert!(line.contains("handshake")); assert!(line.contains("handshake"));
// Envia getState // Send getState
reader.get_mut().write_all(b"{\"type\":\"getState\"}\n").expect("Deve escrever getState"); reader.get_mut().write_all(b"{\"type\":\"getState\"}\n").expect("Should write getState");
std::thread::sleep(std::time::Duration::from_millis(100)); std::thread::sleep(std::time::Duration::from_millis(100));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
// Verifica se recebeu resposta (pode haver eventos/logs antes) // Check if response received (may have events/logs before)
loop { loop {
line.clear(); line.clear();
reader.read_line(&mut line).expect("Deve ler linha"); reader.read_line(&mut line).expect("Should read line");
if line.is_empty() { break; } if line.is_empty() { break; }
if let Ok(resp) = serde_json::from_str::<serde_json::Value>(&line) { if let Ok(resp) = serde_json::from_str::<serde_json::Value>(&line) {
@ -426,7 +426,7 @@ mod tests {
} }
} }
} }
panic!("Não recebeu resposta getState"); panic!("Did not receive getState response");
} }
#[test] #[test]
@ -439,24 +439,24 @@ mod tests {
debug_port: port, debug_port: port,
}); });
// 1. Conecta e pausa // 1. Connect and pause
{ {
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar"); let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
stream.write_all(b"{\"type\":\"pause\"}\n").expect("Deve escrever pause"); stream.write_all(b"{\"type\":\"pause\"}\n").expect("Should write pause");
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
assert!(runner.firmware.os.paused, "VM deve estar pausada"); assert!(runner.firmware.os.paused, "VM should be paused");
} }
// 2. Desconecta (stream sai de escopo) // 2. Disconnect (stream goes out of scope)
std::thread::sleep(std::time::Duration::from_millis(50)); std::thread::sleep(std::time::Duration::from_millis(50));
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
// 3. Verifica se despausou // 3. Check if unpaused
assert!(!runner.firmware.os.paused, "VM deve ter despausado após desconexão"); assert!(!runner.firmware.os.paused, "VM should have unpaused after disconnect");
assert!(!runner.debugger.waiting_for_start, "VM deve ter saído do estado waiting_for_start"); assert!(!runner.debugger.waiting_for_start, "VM should have left waiting_for_start state");
} }
} }

View File

@ -39,7 +39,7 @@ impl HostStats {
if let Some(window) = window { if let Some(window) = window {
let kb = hardware.gfx.memory_usage_bytes() as f64 / 1024.0; let kb = hardware.gfx.memory_usage_bytes() as f64 / 1024.0;
// comparação fixa sempre contra 60Hz, manter mesmo quando fazer teste de stress na CPU // Fixed comparison always against 60Hz, keep even when doing CPU stress tests
let frame_budget_us = 16666.0; let frame_budget_us = 16666.0;
let cpu_load_core = (firmware.os.last_frame_cpu_time_us as f64 / frame_budget_us) * 100.0; let cpu_load_core = (firmware.os.last_frame_cpu_time_us as f64 / frame_budget_us) * 100.0;

View File

@ -1,5 +1,5 @@
/// Copia RGB565 (u16) -> RGBA8888 (u8[4]) para o frame do pixels. /// Copies RGB565 (u16) -> RGBA8888 (u8[4]) to the pixels frame.
/// Formato do pixels: RGBA8. /// Pixels format: RGBA8.
pub fn draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8]) { pub fn draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8]) {
for (i, &px) in src.iter().enumerate() { for (i, &px) in src.iter().enumerate() {
let (r8, g8, b8) = rgb565_to_rgb888(px); let (r8, g8, b8) = rgb565_to_rgb888(px);
@ -11,7 +11,7 @@ pub fn draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8]) {
} }
} }
/// Expande RGB565 para RGB888 (replicação de bits altos). /// Expands RGB565 to RGB888 (high bit replication).
#[inline(always)] #[inline(always)]
pub fn rgb565_to_rgb888(px: u16) -> (u8, u8, u8) { pub fn rgb565_to_rgb888(px: u16) -> (u8, u8, u8) {
let r5 = ((px >> 11) & 0x1F) as u8; let r5 = ((px >> 11) & 0x1F) as u8;

View File

@ -1,14 +1,14 @@
# PROMETEU CLI (Dispatcher) # PROMETEU CLI (Dispatcher)
O binário `prometeu` atua como o front-end unificado para o ecossistema. Ele não implementa a lógica de execução ou compilação, mas sabe onde encontrar os binários que as implementam. The `prometeu` binary acts as the unified front-end for the ecosystem. It does not implement the execution or compilation logic but knows where to find the binaries that do.
## Comandos ## Commands
- `prometeu run <cart>`: Executa um cartucho usando o runtime disponível. - `prometeu run <cart>`: Runs a cartridge using the available runtime.
- `prometeu debug <cart> [--port <p>]`: Inicia a execução em modo de depuração. - `prometeu debug <cart> [--port <p>]`: Starts execution in debug mode.
- `prometeu build <projectDir>`: (Planejado) Chama o compilador `prometeuc`. - `prometeu build <projectDir>`: (Planned) Calls the `prometeuc` compiler.
- `prometeu pack <cartDir>`: (Planejado) Chama o empacotador `prometeup`. - `prometeu pack <cartDir>`: (Planned) Calls the `prometeup` packager.
## Funcionamento ## How it works
O dispatcher localiza os binários irmãos (`prometeu-runtime`, `prometeuc`, etc.) no mesmo diretório onde ele próprio está instalado. Ele herda `stdin`, `stdout` e `stderr`, e propaga o código de saída do processo chamado. The dispatcher locates sibling binaries (`prometeu-runtime`, `prometeuc`, etc.) in the same directory where it is installed. It inherits `stdin`, `stdout`, and `stderr`, and propagates the exit code of the called process.

View File

@ -5,7 +5,7 @@ use std::process::Command;
#[derive(Parser)] #[derive(Parser)]
#[command(name = "prometeu")] #[command(name = "prometeu")]
#[command(about = "Dispatcher para o ecossistema Prometeu", long_about = None)] #[command(about = "Dispatcher for the Prometeu ecosystem", long_about = None)]
struct Cli { struct Cli {
#[command(subcommand)] #[command(subcommand)]
command: Option<Commands>, command: Option<Commands>,
@ -13,30 +13,30 @@ struct Cli {
#[derive(Subcommand)] #[derive(Subcommand)]
enum Commands { enum Commands {
/// Executa um cartucho /// Executes a cartridge
Run { Run {
/// Caminho para o cartucho /// Path to the cartridge
cart: String, cart: String,
}, },
/// Debuga um cartucho /// Debugs a cartridge
Debug { Debug {
/// Caminho para o cartucho /// Path to the cartridge
cart: String, cart: String,
/// Porta para o debugger (padrão: 7777) /// Port for the debugger (default: 7777)
#[arg(long, default_value_t = 7777)] #[arg(long, default_value_t = 7777)]
port: u16, port: u16,
}, },
/// Compila um projeto /// Builds a project
Build { Build {
/// Diretório do projeto /// Project directory
project_dir: String, project_dir: String,
}, },
/// Empacota um cartucho /// Packages a cartridge
Pack { Pack {
/// Diretório do cartucho /// Cartridge directory
cart_dir: String, cart_dir: String,
}, },
/// Verifica integridade de um projeto ou cartucho /// Verifies the integrity of a project or cartridge
Verify { Verify {
#[command(subcommand)] #[command(subcommand)]
target: VerifyCommands, target: VerifyCommands,
@ -45,14 +45,14 @@ enum Commands {
#[derive(Subcommand)] #[derive(Subcommand)]
enum VerifyCommands { enum VerifyCommands {
/// Verifica um projeto /// Verifies a project
C { C {
/// Diretório do projeto /// Project directory
project_dir: String, project_dir: String,
}, },
/// Verifica um cartucho ou arquivo PMC /// Verifies a cartridge or PMC file
P { P {
/// Caminho para o cartucho ou PMC /// Path to the cartridge or PMC
cart_or_pmc: String, cart_or_pmc: String,
}, },
} }
@ -63,7 +63,7 @@ fn main() {
let exe_dir = match env::current_exe() { let exe_dir = match env::current_exe() {
Ok(exe_path) => exe_path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(), Ok(exe_path) => exe_path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(),
Err(e) => { Err(e) => {
eprintln!("Erro ao obter o caminho do executável: {}", e); eprintln!("Error obtaining executable path: {}", e);
std::process::exit(1); std::process::exit(1);
} }
}; };
@ -109,8 +109,8 @@ fn dispatch(exe_dir: &Path, bin_name: &str, args: &[&str]) {
let bin_path = get_binary_path(exe_dir, bin_name); let bin_path = get_binary_path(exe_dir, bin_name);
if !bin_path.exists() { if !bin_path.exists() {
// Tenta encontrar o runtime com o nome exato (prometeu-runtime-desktop) // Tries to find the runtime with the exact name (prometeu-runtime-desktop)
// caso prometeu-runtime seja apenas um alias ou link que ainda não existe // in case prometeu-runtime is just an alias or link that doesn't exist yet
let alt_bin_name = if bin_name == "prometeu-runtime" { let alt_bin_name = if bin_name == "prometeu-runtime" {
Some("prometeu-runtime-desktop") Some("prometeu-runtime-desktop")
} else { } else {
@ -130,7 +130,7 @@ fn dispatch(exe_dir: &Path, bin_name: &str, args: &[&str]) {
if !final_bin_path.exists() { if !final_bin_path.exists() {
eprintln!( eprintln!(
"prometeu: comando '{}' ainda não está disponível nesta distribuição", "prometeu: command '{}' is not yet available in this distribution",
match bin_name { match bin_name {
"prometeu-runtime" => "run/debug", "prometeu-runtime" => "run/debug",
"prometeuc" => "build/verify c", "prometeuc" => "build/verify c",
@ -159,7 +159,7 @@ fn execute_bin(bin_path: &Path, args: &[&str]) {
std::process::exit(status.code().unwrap_or(0)); std::process::exit(status.code().unwrap_or(0));
} }
Err(e) => { Err(e) => {
eprintln!("Erro ao executar {}: {}", bin_path.display(), e); eprintln!("Error executing {}: {}", bin_path.display(), e);
std::process::exit(1); std::process::exit(1);
} }
} }
@ -167,7 +167,7 @@ fn execute_bin(bin_path: &Path, args: &[&str]) {
fn not_implemented(cmd: &str, _bin_name: &str) { fn not_implemented(cmd: &str, _bin_name: &str) {
eprintln!( eprintln!(
"prometeu: comando '{}' ainda não está disponível nesta distribuição", "prometeu: command '{}' is not yet available in this distribution",
cmd cmd
); );
std::process::exit(1); std::process::exit(1);

View File

@ -1,31 +1,31 @@
# Prometeu DevTools Protocol # Prometeu DevTools Protocol
Este documento descreve o protocolo de comunicação entre o Runtime do Prometeu e ferramentas de desenvolvimento (como o Prometeu Debugger). This document describes the communication protocol between the Prometeu Runtime and development tools (such as the Prometeu Debugger).
## Visão Geral ## Overview
O protocolo é baseado em JSON, enviado via uma conexão de transporte (geralmente TCP). Cada mensagem é um objeto JSON em uma única linha (JSONL). The protocol is based on JSON, sent via a transport connection (usually TCP). Each message is a JSON object on a single line (JSONL).
## Estrutura ## Structure
- **[protocol.json](./protocol.json)**: Definição formal do protocolo em formato JSON. - **[protocol.json](./protocol.json)**: Formal definition of the protocol in JSON format.
- **[protocol.md](README.md)**: Documentação legível para humanos descrevendo os comandos, eventos e tipos. - **[protocol.md](README.md)**: Human-readable documentation describing commands, events, and types.
- **[examples/](./examples)**: Exemplos de fluxos de mensagens (handshake, breakpoints, etc.) em formato JSONL. - **[examples/](./examples)**: Examples of message flows (handshake, breakpoints, etc.) in JSONL format.
## Versionamento ## Versioning
O protocolo possui uma versão explícita definida no campo `protocol_version`. The protocol has an explicit version defined in the `protocol_version` field.
- Mudanças incompatíveis (breaking changes) incrementam a versão principal. - Incompatible changes (breaking changes) increment the major version.
- Novos campos em mensagens existentes devem ser opcionais sempre que possível para manter compatibilidade retroativa. - New fields in existing messages should be optional whenever possible to maintain backward compatibility.
A versão atual do protocolo é: **1** The current protocol version is: **1**
## Handshake ## Handshake
Ao conectar, o Runtime envia uma mensagem de handshake para o cliente. Upon connecting, the Runtime sends a handshake message to the client.
### Runtime -> Cliente ### Runtime -> Client
```json ```json
{ {
@ -41,43 +41,43 @@ Ao conectar, o Runtime envia uma mensagem de handshake para o cliente.
} }
``` ```
### Cliente -> Runtime ### Client -> Runtime
O cliente deve responder com `start` ou `ok` para iniciar a sessão. The client must respond with `start` or `ok` to start the session.
```json ```json
{ "type": "start" } { "type": "start" }
``` ```
## Requisições (Requests) ## Requests
O cliente pode enviar as seguintes requisições para controlar a execução: The client can send the following requests to control execution:
| Nome | Parâmetros | Descrição | | Name | Parameters | Description |
|------|------------|-----------| |------|------------|-----------|
| `pause` | `[]` | Pausa a execução da VM. | | `pause` | `[]` | Pauses VM execution. |
| `resume` | `[]` | Retoma a execução da VM. | | `resume` | `[]` | Resumes VM execution. |
| `step` | `[]` | Executa uma única instrução (PC). | | `step` | `[]` | Executes a single instruction (PC). |
| `stepFrame` | `[]` | Executa até o próximo frame. | | `stepFrame` | `[]` | Executes until the next frame. |
| `getState` | `[]` | Retorna o estado atual da VM (`pc`, `stack_top`, `frame_index`, `app_id`). | | `getState` | `[]` | Returns the current VM state (`pc`, `stack_top`, `frame_index`, `app_id`). |
| `setBreakpoint` | `{"pc": number}` | Define um breakpoint no endereço especificado. | | `setBreakpoint` | `{"pc": number}` | Sets a breakpoint at the specified address. |
| `clearBreakpoint` | `{"pc": number}` | Remove um breakpoint no endereço especificado. | | `clearBreakpoint` | `{"pc": number}` | Removes a breakpoint at the specified address. |
## Respostas (Responses) ## Responses
Algumas requisições geram respostas específicas. Por exemplo, `getState` retorna o estado da VM. Some requests generate specific responses. For example, `getState` returns the VM state.
## Eventos (Events) ## Events
O Runtime pode enviar eventos assíncronos para o cliente: The Runtime can send asynchronous events to the client:
| Nome | Campos | Descrição | | Name | Fields | Description |
|------|--------|-----------| |------|--------|-----------|
| `breakpointHit` | `pc`, `frame_index` | Emitido quando a execução atinge um breakpoint. | | `breakpointHit` | `pc`, `frame_index` | Emitted when execution hits a breakpoint. |
| `log` | `level`, `source`, `msg` | Emitido quando o código em execução gera um log. | | `log` | `level`, `source`, `msg` | Emitted when the running code generates a log. |
| `telemetry` | `frame_index`, `vm_steps`, `syscalls`, `cycles` | Estatísticas de execução enviadas periodicamente. | | `telemetry` | `frame_index`, `vm_steps`, `syscalls`, `cycles` | Execution statistics sent periodically. |
| `cert` | `rule`, `used`, `limit`, `frame_index` | Informações de certificação e limites de recursos. | | `cert` | `rule`, `used`, `limit`, `frame_index` | Certification information and resource limits. |
## Exemplos ## Examples
Veja a pasta `examples/` para fluxos de mensagens completos. See the `examples/` folder for complete message flows.

View File

@ -1,15 +1,15 @@
# PROMETEU Documentation # PROMETEU Documentation
Este diretório contém a documentação técnica e especificações do projeto PROMETEU. This directory contains the technical documentation and specifications for the PROMETEU project.
## Conteúdo ## Content
### 📜 [Especificações (Specs)](./specs) ### 📜 [Specifications (Specs)](./specs)
Documentação detalhada sobre a arquitetura do sistema, formato de cartuchos, conjunto de instruções da VM e muito mais. Detailed documentation on system architecture, cartridge format, VM instruction set, and more.
- [Índice de Tópicos](./specs/topics/table-of-contents.md) - [Topic Index](./specs/topics/table-of-contents.md)
### 🐞 [Debugger](./debugger) ### 🐞 [Debugger](./debugger)
Documentação sobre as ferramentas de depuração e como integrar novas ferramentas ao ecossistema. Documentation on debugging tools and how to integrate new tools into the ecosystem.
### 🔌 [DevTools Protocol](../devtools-protocol) ### 🔌 [DevTools Protocol](../devtools-protocol)
Definição do protocolo de comunicação utilizado para depuração e inspeção em tempo real. Definition of the communication protocol used for real-time debugging and inspection.

View File

@ -1,113 +1,113 @@
# Especificação — Ciclo de Desenvolvimento Prometeu # Specification — Prometeu Development Cycle
**Versão:** 0.1 **Version:** 0.1
**Status:** Conceitual / Filosófico **Status:** Conceptual / Philosophical
--- ---
## 1. Princípio Central ## 1. Central Principle
O Prometeu é uma plataforma didática de desenvolvimento de software interativo. Prometeu is a didactic platform for interactive software development.
Seu ciclo de desenvolvimento é projetado para separar claramente: Its development cycle is designed to clearly separate:
- Criação de código - Code creation
- Compilação - Compilation
- Execução - Execution
- Observação e explicação - Observation and explanation
Cada etapa possui uma ferramenta própria, especializada e não sobreposta. Each stage has its own specialized, non-overlapping tool.
--- ---
## 2. Ferramentas do Ciclo ## 2. Cycle Tools
O ciclo utiliza quatro pilares: The cycle uses four pillars:
1. **Editor de Código** 1. **Code Editor**
Ambiente livre (ex: WebStorm) onde o desenvolvedor escreve em TypeScript. Free environment (e.g., WebStorm) where the developer writes in TypeScript.
2. **Compilador Prometeu** 2. **Prometeu Compiler**
Converte código fonte em bytecode executável pela runtime Prometeu. Converts source code into executable bytecode for the Prometeu runtime.
3. **Runtime Prometeu** 3. **Prometeu Runtime**
Executa jogos e aplicações em seu próprio ambiente gráfico. Executes games and applications in its own graphical environment.
4. **Prometeu Debugger** 4. **Prometeu Debugger**
Ferramenta didática de observação, análise e explicação do comportamento interno do sistema. A didactic tool for observation, analysis, and explanation of the system's internal behavior.
Nenhuma dessas ferramentas tenta substituir a outra. None of these tools try to replace each other.
Elas cooperam através de contratos claros. They cooperate through clear contracts.
--- ---
## 3. Fluxo Geral ## 3. General Flow
O ciclo segue sempre a mesma sequência conceitual: The cycle always follows the same conceptual sequence:
1. O desenvolvedor escreve código em TypeScript. 1. The developer writes code in TypeScript.
2. O código é compilado para bytecode Prometeu. 2. The code is compiled to Prometeu bytecode.
3. O bytecode é empacotado como cartucho. 3. The bytecode is packaged as a cartridge.
4. O cartucho é executado pela runtime. 4. The cartridge is executed by the runtime.
5. O comportamento interno pode ser observado pelo Prometeu Debugger. 5. Internal behavior can be observed by the Prometeu Debugger.
--- ---
## 4. Modos de Execução ## 4. Execution Modes
O Prometeu possui dois modos conceituais de execução: Prometeu has two conceptual execution modes:
### Execução Normal (Run) ### Normal Execution (Run)
- O cartucho é empacotado e executado. - The cartridge is packaged and executed.
- A runtime funciona de forma autônoma. - The runtime operates autonomously.
- O Debugger atua apenas como observador. - The Debugger acts only as an observer.
### Execução Assistida (Debug) ### Assisted Execution (Debug)
- O cartucho é empacotado e executado. - The cartridge is packaged and executed.
- A runtime aguarda conexão do Prometeu Debugger. - The runtime waits for a connection from the Prometeu Debugger.
- O Debugger passa a controlar e observar a execução. - The Debugger begins to control and observe the execution.
--- ---
## 5. Separação de Papéis ## 5. Separation of Roles
Cada parte do ciclo tem responsabilidade única: Each part of the cycle has a unique responsibility:
| Etapa | Papel principal | | Stage | Main Role |
|-----------|--------------------------------------| |------------|------------------------------------|
| Editor | Criar código | | Editor | Create code |
| Compilador| Transformar código em bytecode | | Compiler | Transform code into bytecode |
| Runtime | Executar | | Runtime | Execute |
| Debugger | Observar, explicar e ensinar | | Debugger | Observe, explain, and teach |
Essa separação é intencional e parte da filosofia do Prometeu. This separation is intentional and part of the Prometeu philosophy.
--- ---
## 6. Filosofia Didática ## 6. Didactic Philosophy
O Prometeu não é apenas uma engine. Prometeu is not just an engine.
Ele é uma plataforma para aprender como software interativo funciona por dentro. It is a platform for learning how interactive software works from the inside.
O ciclo de desenvolvimento é pensado para: The development cycle is designed to:
- Tornar a execução visível - Make execution visible
- Tornar decisões técnicas observáveis - Make technical decisions observable
- Tornar erros explicáveis - Make errors explainable
- Tornar desempenho mensurável - Make performance measurable
O Debugger não é apenas uma ferramenta de correção, mas um instrumento pedagógico. The Debugger is not just a fix tool, but a pedagogical instrument.
--- ---
## 7. Síntese ## 7. Synthesis
O Ciclo de Desenvolvimento Prometeu é: The Prometeu Development Cycle is:
- Modular - Modular
- Observável - Observable
- Didático - Didactic
- Não acoplado a uma IDE específica - Not coupled to a specific IDE
- Orientado a aprendizado e compreensão profunda - Oriented towards learning and deep understanding
Ele existe para que o desenvolvedor não apenas escreva programas, mas entenda como eles vivem dentro da máquina. It exists so that the developer does not just write programs, but understands how they live inside the machine.

View File

@ -1,190 +1,190 @@
# 📜 Prometeu — O Fogo e a Promessa # 📜 Prometeu — The Fire and the Promise
**PROMETEU** é um console imaginário. **PROMETEU** is an imaginary console.
Mas não no sentido fraco de “imaginar”. But not in the weak sense of "imagining".
PROMETEU foi **deliberadamente projetado** para existir como um **modelo computacional completo**: simples o bastante para ser entendido, e poderoso o suficiente para criar jogos reais. PROMETEU was **deliberately designed** to exist as a **complete computational model**: simple enough to be understood, and powerful enough to create real games.
O nome PROMETEU carrega dois significados intencionais: The name PROMETEU carries two intentional meanings:
- **Prometeu, o titã**, que roubou o fogo dos deuses e entregou aos humanos - **Prometheus, the titan**, who stole fire from the gods and gave it to humans
- **“Prometeu” como verbo**, uma promessa feita - **“Prometeu” as a verb**, a promise made (in Portuguese)
Neste projeto: In this project:
- o *fogo* é o conhecimento de como computadores realmente funcionam - the *fire* is the knowledge of how computers really work
- a *promessa* é que nada é mágico, nada é escondido, e tudo pode ser compreendido - the *promise* is that nothing is magic, nothing is hidden, and everything can be understood
Este manual é essa promessa escrita. This manual is that written promise.
--- ---
## 🎯 O que é o PROMETEU ## 🎯 What is PROMETEU
PROMETEU é um **Virtual Microconsole** — um computador fictício, com regras claras, recursos limitados e comportamento determinístico. PROMETEU is a **Virtual Microconsole** — a fictitious computer, with clear rules, limited resources, and deterministic behavior.
Ele foi projetado para: It was designed to:
- ensinar fundamentos reais de computação - teach real computing fundamentals
- expor tempo, memória e execução - expose time, memory, and execution
- permitir jogos 2D completos (plataformers, metroidvanias, arcade) - allow full 2D games (platformers, metroidvanias, arcade)
- servir como ponte entre: - serve as a bridge between:
- microcontroladores - microcontrollers
- consoles clássicos - classic consoles
- máquinas virtuais - virtual machines
- engines modernas - modern engines
PROMETEU **não é**: PROMETEU **is not**:
- uma engine genérica - a generic engine
- um substituto de Unity ou Godot - a substitute for Unity or Godot
- um console comercial real - a real commercial console
PROMETEU **é**: PROMETEU **is**:
- um laboratório - a laboratory
- um instrumento didático - a didactic instrument
- um brinquedo sério - a serious toy
--- ---
## 🧠 Modelo Mental Fundamental ## 🧠 Fundamental Mental Model
> PROMETEU é um microcontrolador que desenha pixels, toca som e lida com inputs do jogador. > PROMETEU is a microcontroller that draws pixels, plays sound, and handles player input.
> >
Tudo no sistema deriva disso. Everything in the system derives from this.
### Equivalência conceitual ### Conceptual equivalence
| Microcontrolador real | PROMETEU | | Real microcontroller | PROMETEU |
| --- | --- | | --- | --- |
| Clock | Tick da VM | | Clock | VM Tick |
| Flash | Cartucho PROMETEU | | Flash | PROMETEU Cartridge |
| RAM | Heap + Stack | | RAM | Heap + Stack |
| GPIO | Input | | GPIO | Input |
| DMA | Transferência gráfica | | DMA | Graphics transfer |
| ISR | Eventos do sistema | | ISR | System events |
| Periféricos | GFX, AUDIO, INPUT, FS | | Peripherals | GFX, AUDIO, INPUT, FS |
Se você entende um MCU, você entende PROMETEU. If you understand an MCU, you understand PROMETEU.
--- ---
## 🧩 Filosofia de Design ## 🧩 Design Philosophy
### 1. Simplicidade visível ### 1. Visible Simplicity
- Cada operação tem custo - Every operation has a cost
- Cada frame tem orçamento - Every frame has a budget
- Cada erro tem causa observável - Every error has an observable cause
Nada acontece “porque sim”. Nothing happens "just because".
### 2. Determinismo ### 2. Determinism
- Mesmo cartucho - Same cartridge
- Mesma entrada - Same input
- Mesmo resultado - Same result
Independente da plataforma. Regardless of the platform.
### 3. Limitação como ferramenta pedagógica ### 3. Limitation as a pedagogical tool
PROMETEU impõe limites **intencionais**: PROMETEU imposes **intentional** limits:
- memória finita - finite memory
- tempo por frame - time per frame
- recursos gráficos limitados - limited graphics resources
Limites ensinam design. Limits teach design.
### 4. Profundidade progressiva ### 4. Progressive depth
PROMETEU pode ser explorado em camadas: PROMETEU can be explored in layers:
1. **Camada Jogo** — `update()` e `draw()` 1. **Game Layer** — `update()` and `draw()`
2. **Camada Sistema** — bytecode, stack, heap 2. **System Layer** — bytecode, stack, heap
3. **Camada Máquina** — ciclos, eventos, periféricos 3. **Machine Layer** — cycles, events, peripherals
O aluno decide até onde descer. The student decides how deep to go.
## 🏗️ Arquitetura Geral ## 🏗️ General Architecture
``` ```
+---------------------------+ +---------------------------+
| CARTUCHO | | CARTRIDGE |
| (bytecodeX + assets) | | (bytecodeX + assets) |
+-------------+-------------+ +-------------+-------------+
| |
+-------------v-------------+ +-------------v-------------+
| PROMETEU VM | | PROMETEU VM |
| (stack-based, | | (stack-based, |
| determinística) | | deterministic) |
+-------------+-------------+ +-------------+-------------+
| |
+-------------v-------------+ +-------------v-------------+
| PERIFÉRICOS VIRTUAIS | | VIRTUAL PERIPHERALS |
| GFX | AUDIO |INPUT | FS| | | GFX | AUDIO |INPUT | FS| |
+-------------+-------------+ +-------------+-------------+
| |
+-------------v-------------+ +-------------v-------------+
| CAMADA DE PLATAFORMA | | PLATFORM LAYER |
| PC | SteamOS | Android | | PC | SteamOS | Android |
| iOS | Consoles (futuro) | | iOS | Consoles (future) |
+---------------------------+ +---------------------------+
``` ```
Este manual descreve **a máquina PROMETEU**, não ferramentas externas. This manual describes **the PROMETEU machine**, not external tools.
--- ---
## 📦 O Cartucho PROMETEU ## 📦 The PROMETEU Cartridge
Um **cartucho PROMETEU** é um pacote imutável, equivalente a firmware. A **PROMETEU cartridge** is an immutable package, equivalent to firmware.
Conteúdo típico: Typical content:
- `program.pbx`bytecode PROMETEU (bytecodeX) - `program.pbx` — PROMETEU bytecode (bytecodeX)
- `assets/` — gráficos, áudio, mapas - `assets/` — graphics, audio, maps
- `manifest.json` — metadados e configuração - `manifest.json` — metadata and configuration
O cartucho: The cartridge:
- sempre pode ser executado - can always be executed
- sempre pode ser distribuído - can always be distributed
- nunca é bloqueado pelo sistema - is never blocked by the system
--- ---
## 🧪 Linguagens de Programação ## 🧪 Programming Languages
PROMETEU **não executa linguagens de alto nível diretamente**. PROMETEU **does not execute high-level languages directly**.
As linguagens são **fontes**, compiladas para bytecode PROMETEU. The languages are **sources**, compiled to PROMETEU bytecode.
### Linguagens planejadas ### Planned languages
- **Java (subset)** — arquitetura, ensino profundo - **Java (subset)** — architecture, deep teaching
- **TypeScript (subset)** — acessibilidade e mercado - **TypeScript (subset)** — accessibility and market
- **Lua (subset)**scripting clássico e leve - **Lua (subset)**classic and lightweight scripting
Todas convergem para: All converge to:
> O mesmo bytecode. A mesma VM. O mesmo comportamento. > The same bytecode. The same VM. The same behavior.
> >
--- ---
## 🔄 Modelo de Execução ## 🔄 Execution Model
PROMETEU executa em um loop fixo: PROMETEU executes in a fixed loop:
``` ```
BOOT BOOT
LOAD CARTUCHO LOAD CARTRIDGE
INIT INIT
@ -197,68 +197,68 @@ LOOP (60 Hz):
``` ```
- Frequência padrão: **60 Hz** - Default frequency: **60 Hz**
- Cada iteração corresponde a **um frame** - Each iteration corresponds to **one frame**
- O tempo de execução é **mensurável** - Execution time is **measurable**
--- ---
## ⏱️ CAP — Execution Cap (Orçamento de Execução) ## ⏱️ CAP — Execution Cap
### Definição ### Definition
O **CAP** define um orçamento de execução (tempo, memória e recursos) **em um contexto específico**, como uma Game Jam ou avaliação. The **CAP** defines an execution budget (time, memory, and resources) **in a specific context**, such as a Game Jam or evaluation.
> CAP nunca bloqueia execução. > CAP never blocks execution.
CAP nunca bloqueia empacotamento. > CAP never blocks packaging.
CAP nunca impede o jogo de ser jogado. > CAP never prevents the game from being played.
> >
--- ---
### Quando o CAP é usado ### When the CAP is used
- Game Jams PROMETEU - PROMETEU Game Jams
- Avaliações acadêmicas - Academic evaluations
- Desafios técnicos - Technical challenges
- Comparações entre soluções - Comparisons between solutions
Fora desses contextos, PROMETEU opera em **modo livre**. Outside of these contexts, PROMETEU operates in **free mode**.
--- ---
### O papel do CAP ### The role of the CAP
O CAP serve para: The CAP serves to:
- orientar decisões técnicas - guide technical decisions
- fornecer feedback mensurável - provide measurable feedback
- gerar **certificações técnicas** - generate **technical certifications**
- criar critérios objetivos de avaliação - create objective evaluation criteria
PROMETEU **ajuda durante o desenvolvimento**: PROMETEU **helps during development**:
- indicadores visuais - visual indicators
- alertas de custo - cost alerts
- profiling por frame - per-frame profiling
--- ---
## 📄 Certificação PROMETEU ## 📄 PROMETEU Certification
### O que é ### What it is
A **Certificação PROMETEU** é um relatório técnico gerado a partir da execução do jogo sob um CAP definido. The **PROMETEU Certification** is a technical report generated from the execution of the game under a defined CAP.
Ela: It:
- **não impede** o jogo - **does not prevent** the game from running
- **não invalida** a entrega - **does not invalidate** the delivery
- **registra evidências técnicas** - **records technical evidence**
--- ---
### Exemplo de relatório ### Report Example
``` ```
PROMETEUCERTIFICATIONREPORT PROMETEUCERTIFICATIONREPORT
@ -281,19 +281,19 @@ Notes:
-Heappressurecausedbyper-frameallocations -Heappressurecausedbyper-frameallocations
``` ```
O relatório **acompanha o jogo**. The report **accompanies the game**.
--- ---
## 🎓 Uso Educacional ## 🎓 Educational Use
A avaliação pode considerar: Evaluation may consider:
- Qualidade do jogo (criatividade, design) - Game quality (creativity, design)
- Qualidade técnica (certificação) - Technical quality (certification)
- Decisões arquiteturais justificadas - Justified architectural decisions
- Evolução entre versões - Evolution between versions
PROMETEU avalia **processo**, não apenas resultado. PROMETEU evaluates **process**, not just result.
< [Sumário](topics/table-of-contents.md) > < [Summary](topics/table-of-contents.md) >

View File

@ -1,45 +1,45 @@
< [Sumário](table-of-contents.md) | [Adiante](chapter-2.md) > < [Summary](table-of-contents.md) | [Next](chapter-2.md) >
# ⏱️ **Modelo de Tempo e Ciclos** # ⏱️ **Time Model and Cycles**
# 1. Visão Geral # 1. Overview
PROMETEU é um sistema **orientado a tempo**. PROMETEU is a **time-oriented** system.
Nada acontece “instantaneamente”. Nothing happens "instantly".
Toda ação consome **tempo mensurável**, expresso em **ciclos de execução**. Every action consumes **measurable time**, expressed in **execution cycles**.
Este capítulo define: This chapter defines:
- o **clock base** do sistema - the system's **base clock**
- o conceito de **ciclo PROMETEU** - the concept of a **PROMETEU cycle**
- como o tempo é distribuído ao longo dos frames - how time is distributed across frames
- como o **CAP (Execution Cap)** se relaciona com esse modelo - how the **CAP (Execution Cap)** relates to this model
--- ---
## 2. Clock Base do Sistema ## 2. System Base Clock
PROMETEU opera com um **clock fixo de 60 Hz**. PROMETEU operates with a **fixed clock of 60 Hz**.
Isso significa: This means:
- 60 iterações do loop principal por segundo - 60 iterations of the main loop per second
- cada iteração corresponde a **um frame** - each iteration corresponds to **one frame**
- o clock é **determinístico e estável**, independente da plataforma - the clock is **deterministic and stable**, regardless of the platform
> O clock define o ritmo da máquina, > The clock defines the machine's rhythm,
não a quantidade de trabalho obrigatório por frame. not the amount of mandatory work per frame.
> >
--- ---
## 3. O Frame PROMETEU ## 3. The PROMETEU Frame
Um **frame PROMETEU** representa uma unidade completa de execução. A **PROMETEU frame** represents a complete unit of execution.
Cada frame executa, conceitualmente, as seguintes etapas: Each frame conceptually executes the following stages:
``` ```
FRAME N FRAME N
@ -53,61 +53,61 @@ SYNC
``` ```
O sistema garante: The system guarantees:
- ordem fixa - fixed order
- repetição previsível - predictable repetition
- ausência de frames “fantasmas” - absence of "ghost" frames
--- ---
## 4. Ciclos PROMETEU ## 4. PROMETEU Cycles
### 4.1 Definição ### 4.1 Definition
Um **ciclo PROMETEU** é a menor unidade abstrata de tempo do sistema. A **PROMETEU cycle** is the smallest abstract unit of time in the system.
- cada instrução da VM consome um número fixo de ciclos - each VM instruction consumes a fixed number of cycles
- chamadas de periféricos também possuem custo - peripheral calls also have a cost
- o custo é **documentado e estável** - the cost is **documented and stable**
Ciclos são: Cycles are:
- **contáveis** - **countable**
- **comparáveis** - **comparable**
- **independentes de hardware real** - **independent of real hardware**
--- ---
### 4.2 Por que ciclos, e não milissegundos? ### 4.2 Why cycles, and not milliseconds?
PROMETEU não mede tempo em milissegundos porque: PROMETEU does not measure time in milliseconds because:
- milissegundos variam entre plataformas - milliseconds vary between platforms
- clocks reais diferem - real clocks differ
- jitter e latência escondem custo real - jitter and latency hide the real cost
Ciclos permitem afirmar: Cycles allow stating:
> “Este programa é mais caro que aquele, > "This program is more expensive than that one,
> >
> >
> independentemente de onde ele rode.” > regardless of where it runs."
> >
--- ---
## 5. Orçamento por Frame ## 5. Per-Frame Budget
Cada frame possui um **orçamento máximo de ciclos**. Each frame has a **maximum cycle budget**.
Esse orçamento: This budget:
- é resetado a cada frame - is reset every frame
- não acumula ciclos não utilizados - does not accumulate unused cycles
- representa a capacidade da “CPU virtual” - represents the capacity of the "virtual CPU"
### Exemplo conceitual ### Conceptual example
``` ```
Frame Budget:10,000cycles Frame Budget:10,000cycles
@ -124,107 +124,107 @@ Remaining:
--- ---
## 6. Separação entre Clock e Trabalho ## 6. Separation between Clock and Work
PROMETEU **não exige** que toda lógica rode a cada frame. PROMETEU **does not require** all logic to run every frame.
O programador é **explicitamente encorajado** a distribuir trabalho no tempo. The programmer is **explicitly encouraged** to distribute work over time.
### Exemplos comuns ### Common examples
- lógica de inimigos a cada 2 frames (30 Hz) - enemy logic every 2 frames (30 Hz)
- pathfinding a cada 4 frames (15 Hz) - pathfinding every 4 frames (15 Hz)
- animações independentes da AI - animations independent of AI
- timers baseados em contagem de frames - timers based on frame count
Isso reflete práticas reais de: This reflects real-world practices from:
- consoles clássicos - classic consoles
- sistemas embarcados - embedded systems
- firmware de microcontroladores - microcontroller firmware
> Nem tudo precisa acontecer agora. > Not everything needs to happen now.
> >
--- ---
## 7. Distribuição Temporal como Arquitetura ## 7. Temporal Distribution as Architecture
PROMETEU trata **distribuição de trabalho no tempo** como uma decisão arquitetural. PROMETEU treats **work distribution over time** as an architectural decision.
Isso significa que: This means that:
- código que roda todo frame é mais caro - code that runs every frame is more expensive
- código distribuído é mais eficiente - distributed code is more efficient
- otimização é, antes de tudo, **organização temporal** - optimization is, first and foremost, **temporal organization**
PROMETEU ensina: PROMETEU teaches:
> desempenho não vem só de “menos código”, > performance doesn't just come from "less code",
> >
> >
> mas de **quando** o código roda. > but from **when** the code runs.
> >
--- ---
## 8. Execution CAP (Orçamento Contextual) ## 8. Execution CAP (Contextual Budget)
### 8.1 O que é o CAP ### 8.1 What is the CAP
O **CAP** define um conjunto de limites técnicos associados a um **contexto específico**, como: The **CAP** defines a set of technical limits associated with a **specific context**, such as:
- Game Jams - Game Jams
- avaliações acadêmicas - academic evaluations
- desafios técnicos - technical challenges
O CAP pode definir: The CAP can define:
- orçamento máximo de ciclos por frame - maximum cycle budget per frame
- limite de memória - memory limit
- limites de chamadas de periféricos - peripheral call limits
--- ---
### 8.2 CAP não bloqueia execução ### 8.2 CAP does not block execution
Regras fundamentais: Fundamental rules:
- o jogo **sempre roda** - the game **always runs**
- o jogo **sempre pode ser empacotado** - the game **can always be packaged**
- o jogo **sempre pode ser jogado** - the game **can always be played**
O CAP **nunca impede** execução. The CAP **never prevents** execution.
--- ---
### 8.3 CAP gera evidência, não punição ### 8.3 CAP generates evidence, not punishment
Quando um CAP está ativo, PROMETEU: When a CAP is active, PROMETEU:
- mede execução - measures execution
- registra picos - records peaks
- identifica gargalos - identifies bottlenecks
- gera **relatório de certificação** - generates a **certification report**
Esse relatório: This report:
- não bloqueia o jogo - does not block the game
- não invalida a entrega - does not invalidate the delivery
- **documenta conformidade ou não conformidade** - **documents compliance or non-compliance**
--- ---
## 9. Certificação Baseada em Tempo ## 9. Time-Based Certification
A certificação PROMETEU analisa: PROMETEU certification analyzes:
- uso médio de ciclos por frame - average cycle usage per frame
- picos máximos - maximum peaks
- frames problemáticos - problematic frames
- distribuição de custo - cost distribution
Exemplo: Example:
``` ```
Target CAP:PROMETEU-LITE Target CAP:PROMETEU-LITE
@ -238,17 +238,17 @@ enemy.updateAI():1,012cycles
``` ```
Essa certificação acompanha o jogo como **artefato técnico**. This certification accompanies the game as a **technical artifact**.
--- ---
## 10. Implicações Pedagógicas ## 10. Pedagogical Implications
O modelo de tempo e ciclos permite ensinar: The time and cycles model allows teaching:
- planejamento de execução - execution planning
- arquitetura orientada a tempo - time-oriented architecture
- trade-offs técnicos - technical trade-offs
- leitura de perfis reais - reading real profiles
< [Sumário](table-of-contents.md) | [Adiante](chapter-2.md) > < [Summary](table-of-contents.md) | [Next](chapter-2.md) >

View File

@ -1,194 +1,194 @@
< [Voltar](chapter-9.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-11.md) > < [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >
# 🛠️ **Debug, Inspeção e Profiling** # 🛠️ **Debug, Inspection, and Profiling**
## 1. Visão Geral ## 1. Overview
PROMETEU foi projetado para **ser observado**. PROMETEU was designed to **be observed**.
Debug, inspeção e profiling **não são ferramentas externas opcionais** — Debug, inspection, and profiling **are not optional external tools** —
eles são **partes integrantes da máquina**. they are **integral parts of the machine**.
Nada acontece sem deixar rastros. Nothing happens without leaving traces.
Nada consome recursos sem ser medido. Nothing consumes resources without being measured.
Nada falha sem explicação. Nothing fails without explanation.
> PROMETEU não esconde estado. > PROMETEU does not hide state.
PROMETEU expõe comportamento. > PROMETEU exposes behavior.
> >
--- ---
## 2. Filosofia de Debug em PROMETEU ## 2. Debug Philosophy in PROMETEU
PROMETEU segue três princípios fundamentais de debug: PROMETEU follows three fundamental debug principles:
1. **Estado antes de abstração** 1. **State before abstraction**
O programador vê a máquina antes de ver “features”. The programmer sees the machine before seeing “features”.
2. **Tempo como primeira classe** 2. **Time as first class**
Cada ação é analisada no contexto do frame e dos ciclos. Every action is analyzed in the context of the frame and cycles.
3. **Observação não altera execução** 3. **Observation does not alter execution**
Debug nunca muda o comportamento do sistema. Debug never changes the behavior of the system.
--- ---
## 3. Modos de Execução ## 3. Execution Modes
PROMETEU opera em três modos principais: PROMETEU operates in three main modes:
### 3.1 Modo Normal ### 3.1 Normal Mode
- execução contínua - continuous execution
- sem inspeção detalhada - no detailed inspection
- foco em jogo e experiência - focus on game and experience
--- ---
### 3.2 Modo Debug ### 3.2 Debug Mode
- execução controlada - controlled execution
- acesso a estado interno - access to internal state
- pausas e stepping - pauses and stepping
Este modo é usado para: This mode is used for:
- aprendizado - learning
- investigação - investigation
- correção de erros - error correction
--- ---
### 3.3 Modo Certificação ### 3.3 Certification Mode
- execução determinística - deterministic execution
- métricas coletadas - collected metrics
- geração de relatório - report generation
Nenhum modo altera o resultado lógico do programa. No mode alters the logical result of the program.
--- ---
## 4. Debug de Execução ## 4. Execution Debug
### 4.1 Pausa e Continuação ### 4.1 Pause and Resume
O sistema pode ser pausado em pontos seguros: The system can be paused at safe points:
- início do frame - frame start
- antes de UPDATE - before UPDATE
- após DRAW - after DRAW
- antes do SYNC - before SYNC
Durante pausa: During pause:
- estado é congelado - state is frozen
- buffers não são trocados - buffers are not swapped
- tempo lógico não avança - logical time does not advance
--- ---
### 4.2 Step-by-Step ### 4.2 Step-by-Step
PROMETEU permite stepping em diferentes níveis: PROMETEU allows stepping at different levels:
- **por frame** - **by frame**
- **por função** - **by function**
- **por instrução da VM** - **by VM instruction**
Stepping por instrução revela: Stepping by instruction reveals:
- Program Counter (PC) - Program Counter (PC)
- instrução atual - current instruction
- pilha de operandos - operand stack
- call stack - call stack
--- ---
## 5. Inspeção de Estado ## 5. State Inspection
### 5.1 Pilhas ### 5.1 Stacks
PROMETEU permite inspecionar: PROMETEU allows inspecting:
- **Operand Stack** - **Operand Stack**
- **Call Stack** - **Call Stack**
Para cada frame: For each frame:
- conteúdo - content
- profundidade - depth
- crescimento e limpeza - growth and cleanup
Stack overflow e underflow são imediatamente visíveis. Stack overflow and underflow are immediately visible.
--- ---
### 5.2 Heap ### 5.2 Heap
O heap pode ser inspecionado em tempo real: The heap can be inspected in real time:
- tamanho total - total size
- uso atual - current usage
- pico de uso - peak usage
- objetos vivos - live objects
O programador pode observar: The programmer can observe:
- padrões de alocação - allocation patterns
- fragmentação - fragmentation
- pressão de GC - GC pressure
--- ---
### 5.3 Espaço Global ### 5.3 Global Space
Variáveis globais: Global variables:
- valores atuais - current values
- referências - references
- inicialização - initialization
Globais são visíveis como **RAM estática**. Globals are visible as **static RAM**.
--- ---
## 6. Debug Gráfico ## 6. Graphics Debug
PROMETEU permite inspecionar o sistema gráfico: PROMETEU allows inspecting the graphics system:
- front buffer - front buffer
- back buffer - back buffer
- estado da paleta - palette state
- sprites ativos - active sprites
É possível: It is possible to:
- congelar a imagem - freeze the image
- observar buffers separadamente - observe buffers separately
- identificar redraw excessivo - identify excessive redraw
--- ---
## 7. Profiling de Tempo (Ciclos) ## 7. Time Profiling (Cycles)
### 7.1 Medição por Frame ### 7.1 Per-Frame Measurement
Para cada frame, PROMETEU registra: For each frame, PROMETEU records:
- ciclos totais usados - total cycles used
- ciclos por subsistema - cycles per subsystem
- picos de execução - execution peaks
Exemplo conceitual: Conceptual example:
``` ```
Frame 18231: Frame 18231:
@ -201,47 +201,47 @@ SYSTEM:612
--- ---
### 7.2 Profiling por Função ### 7.2 Per-Function Profiling
PROMETEU pode associar ciclos a: PROMETEU can associate cycles with:
- funções - functions
- métodos - methods
- blocos lógicos - logical blocks
Isso permite responder: This allows answering:
> “onde o tempo está sendo gasto?” > “where is the time being spent?”
> >
--- ---
### 7.3 Profiling por Instrução ### 7.3 Per-Instruction Profiling
No nível mais baixo, o sistema pode exibir: At the lowest level, the system can display:
- instruções executadas - executed instructions
- custo individual - individual cost
- frequência - frequency
Esse nível é especialmente útil para: This level is especially useful for:
- ensino de VM - VM teaching
- otimização profunda - deep optimization
- análise de bytecode - bytecode analysis
--- ---
## 8. Profiling de Memória ## 8. Memory Profiling
PROMETEU registra: PROMETEU records:
- uso médio de heap - average heap usage
- pico de heap - heap peak
- alocações por frame - allocations per frame
- frequência de GC - GC frequency
Exemplo: Example:
``` ```
Heap: Heap:
@ -250,101 +250,101 @@ Peak:34KB❌
Limit:32KB Limit:32KB
``` ```
Esses dados alimentam diretamente a certificação. These data directly feed the certification.
--- ---
## 9. Breakpoints e Watchpoints ## 9. Breakpoints and Watchpoints
### 9.1 Breakpoints ### 9.1 Breakpoints
PROMETEU suporta breakpoints em: PROMETEU supports breakpoints in:
- frames específicos - specific frames
- funções - functions
- instruções da VM - VM instructions
Breakpoints: Breakpoints:
- pausam execução - pause execution
- preservam estado - preserve state
- não alteram comportamento - do not change behavior
--- ---
### 9.2 Watchpoints ### 9.2 Watchpoints
Watchpoints monitoram: Watchpoints monitor:
- variáveis - variables
- endereços de heap - heap addresses
- valores específicos - specific values
A execução pode pausar quando: Execution can pause when:
- um valor muda - a value changes
- um limite é ultrapassado - a limit is exceeded
--- ---
## 10. Debug de Eventos e Interrupções ## 10. Event and Interrupt Debugging
PROMETEU permite observar: PROMETEU allows observing:
- fila de eventos - event queue
- timers ativos - active timers
- interrupções ocorridas - occurred interrupts
Cada evento possui: Each event has:
- origem - origin
- frame - frame
- custo - cost
- consequência - consequence
Nada acontece “em silêncio”. Nothing happens “silently”.
--- ---
## 11. Integração com CAP e Certificação ## 11. Integration with CAP and Certification
Todos os dados de debug e profiling: All debug and profiling data:
- alimentam o relatório de certificação - feed the certification report
- são coletados de forma determinística - are collected deterministically
- não dependem de ferramentas externas - do not depend on external tools
O relatório final é: The final report is:
- reproduzível - reproducible
- auditável - auditable
- explicável - explainable
--- ---
## 12. Uso Pedagógico ## 12. Pedagogical Use
Este sistema permite ensinar: This system allows teaching:
- como debugar sistemas reais - how to debug real systems
- como ler métricas - how to read metrics
- como correlacionar tempo e memória - how to correlate time and memory
- como justificar decisões técnicas - how to justify technical decisions
O aluno aprende: The student learns:
> debug não é tentativa e erro, > debug is not trial and error,
é observação informada. > it is informed observation.
> >
--- ---
## 13. Resumo ## 13. Summary
- debug é parte do sistema - debug is part of the system
- inspeção é completa - inspection is complete
- profiling é determinístico - profiling is deterministic
- tempo e memória são visíveis - time and memory are visible
- certificação é baseada em evidência - certification is evidence-based
< [Voltar](chapter-9.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-11.md) > < [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >

View File

@ -1,258 +1,258 @@
< [Voltar](chapter-10.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-12.md) > < [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >
# 🌍 **Garantias de Portabilidade e Execução Multiplataforma** # 🌍 **Portability Guarantees and Cross-Platform Execution**
## 1. Visão Geral ## 1. Overview
PROMETEU foi projetado desde o início para ser **portável por construção**, não por adaptação posterior. PROMETEU was designed from the beginning to be **portable by construction**, not by later adaptation.
Um cartucho PROMETEU: A PROMETEU cartridge:
- executa da mesma forma em qualquer plataforma suportada - executes the same way on any supported platform
- produz os mesmos resultados para as mesmas entradas - produces the same results for the same inputs
- mantém comportamento técnico previsível - maintains predictable technical behavior
> PROMETEU não depende da plataforma. > PROMETEU does not depend on the platform.
A plataforma depende do PROMETEU. > The platform depends on PROMETEU.
> >
Este capítulo define **o contrato de portabilidade** do sistema. This chapter defines the system's **portability contract**.
--- ---
## 2. Princípio Fundamental da Portabilidade ## 2. Fundamental Principle of Portability
A portabilidade em PROMETEU se baseia em uma regra simples: Portability in PROMETEU is based on a simple rule:
> Somente a PROMETEU VM define o comportamento do programa. > Only the PROMETEU VM defines the program's behavior.
> >
Isso significa: This means:
- linguagens-fonte não importam após compilação - source languages do not matter after compilation
- hardware real não influencia lógica - real hardware does not influence logic
- sistema operacional não altera semântica - the operating system does not change semantics
Tudo que não pertence à VM é **adaptação**, não execução. Everything that does not belong to the VM is **adaptation**, not execution.
--- ---
## 3. Separação de Responsabilidades ## 3. Separation of Responsibilities
PROMETEU separa rigorosamente três camadas: PROMETEU strictly separates three layers:
``` ```
+----------------------------+ +----------------------------+
| CARTUCHO | | CARTRIDGE |
| (bytecode + assets) | | (bytecode + assets) |
+-------------+--------------+ +-------------+--------------+
| |
+-------------v--------------+ +-------------v--------------+
| PROMETEU VM | | PROMETEU VM |
| (lógica, tempo, memória) | | (logic, time, memory) |
+-------------+--------------+ +-------------+--------------+
| |
+-------------v--------------+ +-------------v--------------+
| CAMADA DE PLATAFORMA | | PLATFORM LAYER |
| janela, áudio,input, FS | | window, audio, input, FS |
+----------------------------+ +----------------------------+
``` ```
### O que a VM controla ### What the VM controls
- execução de bytecode - bytecode execution
- tempo lógico (frames, ciclos) - logical time (frames, cycles)
- memória (stack, heap) - memory (stack, heap)
- determinismo - determinism
- custos e métricas - costs and metrics
### O que a plataforma fornece ### What the platform provides
- exibição de pixels - pixel display
- saída de áudio - audio output
- coleta de input físico - physical input collection
- acesso ao sistema de arquivos sandbox - access to the sandbox file system
A plataforma **nunca decide comportamento**. The platform **never decides behavior**.
--- ---
## 4. Determinismo como Base da Portabilidade ## 4. Determinism as the Basis of Portability
PROMETEU garante determinismo por meio de: PROMETEU guarantees determinism through:
- clock lógico fixo (60 Hz) - fixed logical clock (60 Hz)
- ciclos abstratos, não tempo real - abstract cycles, not real time
- input amostrado por frame - input sampled per frame
- ausência de concorrência implícita - absence of implicit concurrency
- ausência de operações dependentes de sistema - absence of system-dependent operations
Isso permite afirmar: This allows stating:
> “Se o cartucho é o mesmo, o jogo é o mesmo.” > “If the cartridge is the same, the game is the same.”
> >
--- ---
## 5. Independência de Hardware Real ## 5. Independence from Real Hardware
PROMETEU **não utiliza**: PROMETEU **does not use**:
- timers do sistema operacional - operating system timers
- clocks de alta resolução - high-resolution clocks
- instruções específicas de CPU - CPU-specific instructions
- aceleração gráfica não controlada - uncontrolled graphics acceleration
Todo desempenho é medido em **ciclos PROMETEU**, não em milissegundos. All performance is measured in **PROMETEU cycles**, not in milliseconds.
O hardware real: The real hardware:
- apenas executa a VM - only executes the VM
- nunca interfere na semântica - never interferes with semantics
--- ---
## 6. Precisão de Ponto Flutuante ## 6. Floating Point Precision
Para garantir consistência numérica: To guarantee numerical consistency:
- PROMETEU define operações matemáticas explícitas - PROMETEU defines explicit mathematical operations
- evita dependência de FPU específica - avoids dependence on specific FPUs
- padroniza comportamento de `number` - standardizes `number` behavior
Isso evita: This avoids:
- divergências entre arquiteturas - divergences between architectures
- erros acumulativos imprevisíveis - unpredictable cumulative errors
- diferenças sutis entre plataformas - subtle differences between platforms
--- ---
## 7. Input Multiplataforma ## 7. Cross-Platform Input
PROMETEU abstrai input físico em **estado lógico**. PROMETEU abstracts physical input into **logical state**.
- teclado, gamepad e toque são mapeados externamente - keyboard, gamepad, and touch are mapped externally
- o cartucho só enxerga botões e eixos lógicos - the cartridge only sees logical buttons and axes
- o momento da leitura é fixo por frame - the reading moment is fixed per frame
O mesmo cartucho: The same cartridge:
- reage da mesma forma em PC, mobile ou console - reacts the same way on PC, mobile, or console
- não contém lógica dependente de dispositivo - does not contain device-dependent logic
--- ---
## 8. Áudio Multiplataforma ## 8. Cross-Platform Audio
O sistema de áudio: The audio system:
- define canais e mixagem logicamente - defines channels and mixing logically
- usa APIs nativas apenas como saída - uses native APIs only as output
- mantém sincronização por frame - maintains per-frame synchronization
Diferenças de hardware: Hardware differences:
- não alteram timing lógico - do not change logical timing
- não alteram sequência sonora - do not change sound sequence
- não afetam certificação - do not affect certification
--- ---
## 9. Gráficos Multiplataforma ## 9. Cross-Platform Graphics
O sistema gráfico: The graphics system:
- opera sobre framebuffer lógico - operates on a logical framebuffer
- usa paleta indexada - uses an indexed palette
- não depende de GPU específica - does not depend on a specific GPU
A camada de plataforma: The platform layer:
- apenas exibe o framebuffer - only displays the framebuffer
- não reinterpreta comandos gráficos - does not reinterpret graphics commands
PROMETEU **não delega decisões gráficas ao hardware**. PROMETEU **does not delegate graphics decisions to the hardware**.
--- ---
## 10. Sistema de Arquivos e Persistência ## 10. File System and Persistence
PROMETEU define um **filesystem lógico sandbox**: PROMETEU defines a **sandbox logical filesystem**:
- caminhos virtuais - virtual paths
- limites de tamanho - size limits
- comportamento determinístico - deterministic behavior
A plataforma mapeia esse filesystem para: The platform maps this filesystem to:
- disco - disk
- storage móvel - mobile storage
- memória persistente - persistent memory
Sem alterar semântica. Without changing semantics.
--- ---
## 11. Certificação e Portabilidade ## 11. Certification and Portability
A **Certificação PROMETEU** é válida para todas as plataformas. The **PROMETEU Certification** is valid for all platforms.
Se um cartucho: If a cartridge:
- passa em uma plataforma - passes on one platform
- com as mesmas entradas - with the same inputs
Ele: It:
- passará em todas - will pass on all
- produzirá os mesmos relatórios - will produce the same reports
Isso é possível porque: This is possible because:
> a certificação valida a VM, não o ambiente. > the certification validates the VM, not the environment.
> >
--- ---
## 12. O que PROMETEU NÃO garante ## 12. What PROMETEU DOES NOT guarantee
PROMETEU **não promete**: PROMETEU **does not promise**:
- desempenho absoluto igual (FPS real) - identical absolute performance (real FPS)
- latência física idêntica - identical physical latency
- consumo energético equivalente - equivalent energy consumption
PROMETEU promete: PROMETEU promises:
- **comportamento lógico idêntico** - **identical logical behavior**
- **decisões técnicas reproduzíveis** - **reproducible technical decisions**
--- ---
## 13. Implicações Pedagógicas ## 13. Pedagogical Implications
Este modelo permite ensinar: This model allows teaching:
- diferença entre lógica e apresentação - the difference between logic and presentation
- por que engines modernas quebram determinismo - why modern engines break determinism
- como isolar sistemas - how to isolate systems
- como projetar software portável - how to design portable software
O aluno aprende: The student learns:
> portabilidade não é sorte — é arquitetura. > portability is not luck — it is architecture.
> >
--- ---
## 14. Resumo ## 14. Summary
- PROMETEU define comportamento na VM - PROMETEU defines behavior in the VM
- plataformas apenas executam - platforms only execute
- tempo é lógico, não físico - time is logical, not physical
- input, áudio e gráficos são abstraídos - input, audio, and graphics are abstracted
- certificação é universal - certification is universal
- portabilidade é garantida por design - portability is guaranteed by design
< [Voltar](chapter-10.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-12.md) > < [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >

View File

@ -1,236 +1,236 @@
< [Voltar](chapter-11.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-13.md) > < [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >
# 🧠 Firmware — PrometeuOS (POS) + PrometeuHub # 🧠 Firmware — PrometeuOS (POS) + PrometeuHub
## 1. Visão Geral ## 1. Overview
O **Firmware do PROMETEU** é composto por duas camadas: The **PROMETEU Firmware** is composed of two layers:
- **PrometeuOS (POS)**: o firmware/base do sistema. É a autoridade máxima do boot, periféricos, execução da PVM e tratamento de falhas. - **PrometeuOS (POS)**: the system firmware/base. It is the maximum authority for boot, peripherals, PVM execution, and fault handling.
- **PrometeuHub**: o “launcher” e ambiente de UI do sistema, embutido no firmware, executado **sobre** o POS e usando o **PROMETEU Window System**. - **PrometeuHub**: the system launcher and UI environment, embedded in the firmware, executed **over** the POS and using the **PROMETEU Window System**.
> **Todo cartucho é um App**. > **Every cartridge is an App**.
> A diferença é o **modo do App** (Game ou System), informado no header do cartucho. > The difference is the **App mode** (Game or System), specified in the cartridge header.
--- ---
## 2. Termos e Definições ## 2. Terms and Definitions
- **Host**: plataforma real (desktop, mobile, console DIY, etc.) que chama o core em 60Hz e exibe o framebuffer. - **Host**: real platform (desktop, mobile, DIY console, etc.) that calls the core at 60Hz and displays the framebuffer.
- **POS (PrometeuOS)**: firmware (core de sistema). Controla boot, PVM, budget, latch de input, periféricos e crash. - **POS (PrometeuOS)**: firmware (system core). Controls boot, PVM, budget, input latch, peripherals, and crash.
- **PrometeuHub**: UI do sistema/launcher rodando sobre POS. - **PrometeuHub**: system UI / launcher running over POS.
- **PVM (PROMETEU Virtual Machine)**: VM que executa bytecode do App. - **PVM (PROMETEU Virtual Machine)**: VM that executes the App's bytecode.
- **App / Cartucho**: pacote executável PROMETEU (ex.: `.pbc`). - **App / Cartridge**: PROMETEU executable package (e.g., `.pbc`).
- **AppMode**: modo do App no header do cartucho: - **AppMode**: App mode in the cartridge header:
- `GAME`: assume tela cheia, UI própria - `GAME`: assumes full screen, own UI
- `SYSTEM`: app integrado ao sistema, deve rodar “em janela” no Hub - `SYSTEM`: app integrated into the system, should run "in a window" in the Hub
- **Frame lógico**: unidade de atualização do App, encerrada por `FRAME_SYNC`. - **Logical frame**: App update unit, terminated by `FRAME_SYNC`.
- **Tick do host**: chamada do host (60Hz real). - **Host tick**: call from the host (real 60Hz).
--- ---
## 3. Responsabilidades do POS (PrometeuOS) ## 3. Responsibilities of the POS (PrometeuOS)
O POS deve garantir: The POS must guarantee:
### 3.1 Boot e Estados de Sistema ### 3.1 Boot and System States
- RESET determinístico (estado conhecido) - Deterministic RESET (known state)
- SPLASH opcional (curto) - Optional SPLASH (short)
- inicialização do PrometeuHub e do Window System - initialization of the PrometeuHub and the Window System
- retorno ao Hub após saída/crash de app - return to the Hub after app exit/crash
### 3.2 Controle da PVM ### 3.2 PVM Control
- carregar cartucho na PVM - load cartridge into the PVM
- resetar PC/stack/heap ao iniciar app - reset PC/stack/heap upon app start
- executar budget por frame lógico - execute budget per logical frame
- respeitar `FRAME_SYNC` como boundary de frame lógico - respect `FRAME_SYNC` as logical frame boundary
- manter input latched por frame lógico - maintain input latched per logical frame
### 3.3 Controle de Periféricos ### 3.3 Peripheral Control
- inicialização e reset de: - initialization and reset of:
- GFX / buffers - GFX / buffers
- AUDIO (canais, fila de comandos) - AUDIO (channels, command queue)
- INPUT / TOUCH - INPUT / TOUCH
- política de “safe mode” (ignorar Hub/config se solicitado) - "safe mode" policy (ignore Hub/config if requested)
### 3.4 Falhas e Recuperação ### 3.4 Failures and Recovery
- capturar faults fatais da PVM - capture fatal PVM faults
- apresentar **POS_CRASH_SCREEN** (fora da PVM) - present **POS_CRASH_SCREEN** (outside the PVM)
- permitir: - allow:
- reiniciar app - app restart
- voltar ao Hub - return to Hub
- reset do sistema - system reset
--- ---
## 4. Responsabilidades do PrometeuHub ## 4. Responsibilities of the PrometeuHub
O PrometeuHub deve: The PrometeuHub must:
- listar Apps disponíveis no storage - list available Apps in storage
- ler metadata do header do cartucho (incluindo `AppMode`) - read metadata from the cartridge header (including `AppMode`)
- permitir seleção e launch - allow selection and launch
- aplicar tema/UI do sistema via Window System - apply system theme/UI via Window System
- decidir o “comportamento de execução” com base no `AppMode` - decide the "execution behavior" based on the `AppMode`
### 4.1 Decisão por `AppMode` ### 4.1 Decision by `AppMode`
Ao selecionar um App: When selecting an App:
- Se `AppMode = GAME`: - If `AppMode = GAME`:
- o Hub delega ao POS: **executar como jogo** (tela cheia) - the Hub delegates to the POS: **execute as a game** (full screen)
- Se `AppMode = SYSTEM`: - If `AppMode = SYSTEM`:
- o Hub delega ao POS: **carregar o App** - the Hub delegates to the POS: **load the App**
- e o Hub **abre uma janela** e roda o App “integrado ao sistema” - and the Hub **opens a window** and runs the App "integrated into the system"
> Observação: o Hub não executa bytecode diretamente; ele sempre delega ao POS. > Note: the Hub does not execute bytecode directly; it always delegates to the POS.
--- ---
## 5. PROMETEU Window System (UI do Sistema) ## 5. PROMETEU Window System (System UI)
O Window System é parte do firmware (POS + Hub) e oferece: The Window System is part of the firmware (POS + Hub) and offers:
- tema global (paleta, fontes, sons de UI) - global theme (palette, fonts, UI sounds)
- sistema de janelas (pelo menos: uma janela ativa + stack de dialogs) - window system (at least: one active window + dialog stack)
- roteamento de input: - input routing:
- foco, navegação, confirmação/cancelamento - focus, navigation, confirmation/cancellation
- touch como “tap” (single pointer) - touch as "tap" (single pointer)
### 5.1 Integração de System Apps ### 5.1 System App Integration
System Apps são executados em modo “janela” e devem: System Apps are executed in "window" mode and must:
- respeitar a área de viewport fornecida pela janela - respect the viewport area provided by the window
- cooperar com foco/inputs do Window System - cooperate with the Window System's focus/inputs
- aceitar ser suspensos/fechados pelo Hub - accept being suspended/closed by the Hub
O Hub pode oferecer “chrome” de janela: The Hub can offer window "chrome":
- título - title
- botão voltar/fechar - back/close button
- overlays (toast, dialogs) - overlays (toast, dialogs)
--- ---
## 6. Header do Cartucho (requisito mínimo para o firmware) ## 6. Cartridge Header (minimum requirement for the firmware)
O firmware exige que todo cartucho forneça no header, no mínimo: The firmware requires every cartridge to provide at least the following in the header:
- `magic` / `version` - `magic` / `version`
- `app_id` (string curta ou hash) - `app_id` (short string or hash)
- `title` (string) - `title` (string)
- `entrypoint` (endereço de PC) - `entrypoint` (PC address)
- `app_mode`: `GAME` ou `SYSTEM` - `app_mode`: `GAME` or `SYSTEM`
- (opcional) `icon_id` / `cover_id` - (optional) `icon_id` / `cover_id`
- (opcional) `requested_cap` / versão da VM - (optional) `requested_cap` / VM version
O POS/HUB devem usar `app_mode` para decidir execução. The POS/HUB must use `app_mode` to decide on execution.
--- ---
## 7. Estados Oficiais do Boot (Firmware) ## 7. Official Boot States (Firmware)
### 7.1 POS_RESET ### 7.1 POS_RESET
- inicializa periféricos - initializes peripherals
- prepara PVM - prepares PVM
- carrega config - loads config
- detecta safe mode - detects safe mode
Transição: `POS_SPLASH` ou `POS_LAUNCH_HUB` Transition: `POS_SPLASH` or `POS_LAUNCH_HUB`
### 7.2 POS_SPLASH (opcional) ### 7.2 POS_SPLASH (optional)
- exibe logo/versão - displays logo/version
- tempo fixo ou “skip” - fixed time or "skip"
Transição: `POS_LAUNCH_HUB` Transition: `POS_LAUNCH_HUB`
### 7.3 POS_LAUNCH_HUB ### 7.3 POS_LAUNCH_HUB
- inicia Window System - starts Window System
- entra no loop do Hub - enters the Hub loop
Transição: `HUB_HOME` Transition: `HUB_HOME`
### 7.4 HUB_HOME ### 7.4 HUB_HOME
- lista Apps - lists Apps
- permite seleção: - allows selection:
- `GAME``POS_RUN_GAME(app)` - `GAME``POS_RUN_GAME(app)`
- `SYSTEM``HUB_OPEN_WINDOW(app)` (que delega `POS_RUN_SYSTEM(app)`) - `SYSTEM``HUB_OPEN_WINDOW(app)` (which delegates `POS_RUN_SYSTEM(app)`)
### 7.5 POS_RUN_GAME(app) ### 7.5 POS_RUN_GAME(app)
- carrega cartucho na PVM - loads cartridge into the PVM
- executa frame lógico (budget + `FRAME_SYNC`) - executes logical frame (budget + `FRAME_SYNC`)
- apresenta frames - presents frames
- mantém latch por frame lógico - maintains latch per logical frame
Saídas: Exits:
- `APP_EXIT``POS_LAUNCH_HUB` - `APP_EXIT``POS_LAUNCH_HUB`
- `APP_FAULT``POS_CRASH_SCREEN` - `APP_FAULT``POS_CRASH_SCREEN`
### 7.6 POS_RUN_SYSTEM(app) ### 7.6 POS_RUN_SYSTEM(app)
- carrega cartucho na PVM (ou instância separada, se suportado no futuro) - loads cartridge into the PVM (or separate instance, if supported in the future)
- executa sob o ciclo do Hub/Window System - executes under the Hub/Window System cycle
- apresenta na área da janela (viewport) - presents in the window area (viewport)
Saídas: Exits:
- `APP_EXIT` → retorna ao Hub - `APP_EXIT` → returns to the Hub
- `APP_FAULT``POS_CRASH_SCREEN` (ou crash window + fallback) - `APP_FAULT``POS_CRASH_SCREEN` (or crash window + fallback)
### 7.7 POS_CRASH_SCREEN ### 7.7 POS_CRASH_SCREEN
- exibe erro (tipo, PC, stack trace) - displays error (type, PC, stack trace)
- ações: restart app / hub / reset - actions: restart app / hub / reset
Transição: conforme escolha. Transition: as chosen.
--- ---
## 8. Modelo de Execução (Budget, Latch e `FRAME_SYNC`) ## 8. Execution Model (Budget, Latch, and `FRAME_SYNC`)
O POS é responsável por garantir: The POS is responsible for guaranteeing:
- **Input latched por frame lógico** - **Input latched per logical frame**
- execução em fatias (ticks do host) até o app alcançar `FRAME_SYNC` - execution in slices (host ticks) until the app reaches `FRAME_SYNC`
- apenas em `FRAME_SYNC`: - only at `FRAME_SYNC`:
- `present()` (ou compose+present) - `present()` (or compose+present)
- avança `logical_frame_index` - advances `logical_frame_index`
- libera latch de input - releases input latch
- reseta budget do próximo frame lógico - resets the budget for the next logical frame
Se o budget acabar antes do `FRAME_SYNC`: If the budget runs out before `FRAME_SYNC`:
- não apresenta - does not present
- mantém latch - maintains latch
- continua a execução no próximo tick do host no mesmo frame lógico - execution continues in the next host tick within the same logical frame
--- ---
## 9. Regras de Retorno ao Hub ## 9. Rules for Returning to the Hub
O firmware deve oferecer um mecanismo de “voltar ao sistema”: The firmware must offer a "return to system" mechanism:
- atalho de botão (ex.: START+SELECT por X ticks) - button shortcut (e.g., START+SELECT for X ticks)
- ou syscall controlada (apenas System Apps) - or controlled syscall (System Apps only)
Ao retornar ao Hub: Upon returning to the Hub:
- o POS encerra ou suspende o App atual - the POS terminates or suspends the current App
- retorna ao Window System com estado consistente - returns to the Window System with a consistent state
--- ---
## 10. Objetivos Pedagógicos ## 10. Pedagogical Objectives
Este firmware permite ensinar: This firmware allows teaching:
- boot stages e firmware como autoridade - boot stages and firmware as an authority
- separação entre sistema e aplicação - separation between system and application
- execução determinística com budget e frame lógico - deterministic execution with budget and logical frame
- diferença entre apps (Game vs System) - difference between apps (Game vs System)
- tolerância a falhas e crash handling realista - fault tolerance and realistic crash handling
--- ---
## 11. Resumo ## 11. Summary
- POS é a camada base e controla PVM, budget, latch, periféricos e crash. - POS is the base layer and controls the PVM, budget, latch, peripherals, and crash.
- PrometeuHub é o launcher/UI embutido do firmware sobre o POS. - PrometeuHub is the embedded firmware launcher/UI over the POS.
- Todo cartucho é um App; o header define `app_mode` (GAME/SYSTEM). - Every cartridge is an App; the header defines the `app_mode` (GAME/SYSTEM).
- `GAME` roda tela cheia; `SYSTEM` roda integrado ao Hub em janela. - `GAME` runs in full screen; `SYSTEM` runs integrated into the Hub in a window.
- `FRAME_SYNC` é o boundary do frame lógico. - `FRAME_SYNC` is the logical frame boundary.
< [Voltar](chapter-11.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-13.md) > < [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >

View File

@ -1,35 +1,35 @@
< [Voltar](chapter-12.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-14.md) > < [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >
# Cartuchos # Cartridges
**Versão:** 1.0 (baseline estável) **Version:** 1.0 (stable baseline)
**Status:** Proposta **Status:** Proposal
--- ---
## 1. Objetivo ## 1. Objective
Definir um contrato mínimo e estável para cartuchos Prometeu, permitindo: Define a minimum and stable contract for Prometeu cartridges, allowing:
* Identificação do app * App identification
* Seleção de modo (Game/System) * Mode selection (Game/System)
* Resolução de entrypoint * Entrypoint resolution
* Carregamento previsível pelo runtime * Predictable loading by the runtime
--- ---
## 2. Conceito ## 2. Concept
Um cartucho é a unidade distribuível do Prometeu. Ele pode existir como: A cartridge is the distributable unit of Prometeu. It can exist as:
* **Diretório (dev)** — ideal para desenvolvimento e hot-reload * **Directory (dev)** — ideal for development and hot-reload
* **Arquivo empacotado (.pmc)** — ideal para distribuição * **Packaged file (.pmc)** — ideal for distribution
Ambos compartilham o mesmo layout lógico. Both share the same logical layout.
--- ---
## 3. Layout Lógico ## 3. Logical Layout
``` ```
<cartridge>/ <cartridge>/
@ -39,72 +39,72 @@ Ambos compartilham o mesmo layout lógico.
└── ... └── ...
``` ```
Campos obrigatórios: Required fields:
* `manifest.json` * `manifest.json`
* `program.pbc` (bytecode Prometeu) * `program.pbc` (Prometeu bytecode)
--- ---
## 4. manifest.json (Contrato v1) ## 4. manifest.json (Contract v1)
```json ```json
{ {
"magic": "PMTU", "magic": "PMTU",
"cartridge_version": 1, "cartridge_version": 1,
"app_id": 1234, "app_id": 1234,
"title": "Meu Jogo", "title": "My Game",
"app_version": "1.0.0", "app_version": "1.0.0",
"app_mode": "Game", // Game | System "app_mode": "Game",
"entrypoint": "main" "entrypoint": "main"
} }
``` ```
### Campos ### Fields
* `magic`: string fixa `PMTU` * `magic`: fixed string `PMTU`
* `cartridge_version`: versão do formato * `cartridge_version`: format version
* `app_id`: identificador numérico único * `app_id`: unique numerical identifier
* `title`: nome do app * `title`: name of the app
* `app_version`: versão do app * `app_version`: app version
* `app_mode`: `Game` ou `System` * `app_mode`: `Game` or `System`
* `entrypoint`: símbolo ou índice reconhecido pela VM * `entrypoint`: symbol or index recognized by the VM
--- ---
## 5. Regras do Runtime ## 5. Runtime Rules
* Validar `magic` e `cartridge_version` * Validate `magic` and `cartridge_version`
* Ler `app_mode` para decidir fluxo de execução * Read `app_mode` to decide execution flow
* Resolver `entrypoint` no `program.pbc` * Resolve `entrypoint` in `program.pbc`
* Ignorar `assets/` se não suportado ainda * Ignore `assets/` if not supported yet
--- ---
## 6. Modos de Uso ## 6. Usage Modes
### Diretório (desenvolvimento) ### Directory (development)
``` ```
prometeu --run ./mycart/ prometeu --run ./mycart/
``` ```
### Arquivo empacotado ### Packaged file
``` ```
prometeu --run mygame.pmc prometeu --run mygame.pmc
``` ```
Ambos devem se comportar de forma idêntica no runtime. Both must behave identically in the runtime.
--- ---
## 7. Estabilidade do Contrato ## 7. Contract Stability
A partir do v1: From v1 onwards:
* `manifest.json` é a fonte de verdade * `manifest.json` is the source of truth
* Campos só podem ser adicionados de forma backward-compatible * Fields can only be added in a backward-compatible manner
* Mudanças incompatíveis exigem `cartridge_version` novo * Incompatible changes require a new `cartridge_version`
< [Voltar](chapter-12.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-14.md) > < [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >

View File

@ -1,25 +1,25 @@
< [Voltar](chapter-13.md) | [Sumário](table-of-contents.md) > < [Back](chapter-13.md) | [Summary](table-of-contents.md) >
# Boot Profiles # Boot Profiles
**Versão:** 1.0 **Version:** 1.0
**Status:** Proposta **Status:** Proposal
--- ---
## 1. Objetivo ## 1. Objective
Definir como o Prometeu decide o que executar ao iniciar: Define how Prometeu decides what to execute at startup:
* Hub * Hub
* Cartucho automaticamente * Automatic cartridge
* Modo debug * Debug mode
--- ---
## 2. Conceito de BootTarget ## 2. BootTarget Concept
No início do boot, o POS resolve um alvo: At the beginning of boot, the POS resolves a target:
```rust ```rust
enum BootTarget { enum BootTarget {
@ -30,106 +30,106 @@ enum BootTarget {
--- ---
## 3. Regras Gerais ## 3. General Rules
### Se BootTarget == Hub ### If BootTarget == Hub
* Firmware entra em `HubHome` * Firmware enters `HubHome`
* Nenhum cartucho é carregado automaticamente * No cartridge is automatically loaded
### Se BootTarget == Cartridge ### If BootTarget == Cartridge
1. Carregar cartucho 1. Load cartridge
2. Ler `app_mode` no manifest 2. Read `app_mode` in the manifest
3. Aplicar regras: 3. Apply rules:
* `Game`: * `Game`:
* Entrar em `RunningGame` * Enter `RunningGame`
* `System`: * `System`:
* Permanecer em `HubHome` * Stay in `HubHome`
* Abrir o app como janela/system tool * Open the app as a window/system tool
--- ---
## 4. CLI do Host ## 4. Host CLI
### Boot padrão ### Default boot
``` ```
prometeu prometeu
``` ```
Resultado: entra no Hub Result: enters the Hub
### Executar cartucho ### Run cartridge
``` ```
prometeu run <cartucho> prometeu run <cartridge>
``` ```
Resultado: Result:
* Game → entra direto no jogo * Game → enters directly into the game
* System → abre como tool no Hub * System → opens as a tool in the Hub
### Executar com debugger ### Run with debugger
``` ```
prometeu debug <cartucho> prometeu debug <cartridge>
``` ```
Resultado: Result:
* Mesmo fluxo do `run` * Same flow as `run`
* Runtime inicia em modo debug * Runtime starts in debug mode
* Aguarda conexão do Debugger Java * Waits for connection from the Java Debugger
--- ---
## 5. Estados do Firmware ## 5. Firmware States
Firmware mantém apenas: Firmware maintains only:
* `Boot` * `Boot`
* `HubHome` * `HubHome`
* `RunningGame` * `RunningGame`
* `AppCrashed` * `AppCrashed`
System apps nunca mudam o estado do firmware. System apps never change the firmware state.
--- ---
## 6. Comportamento em Hardware Real (futuro) ## 6. Behavior on Real Hardware (future)
* Se miniSD/cartucho físico presente no boot: * If miniSD/physical cartridge is present at boot:
* POS pode: * POS can:
* sempre ir ao Hub, ou * always go to the Hub, or
* auto-executar conforme configuração do usuário * auto-execute according to user configuration
--- ---
## 7. Integração com Debugger ## 7. Integration with Debugger
Quando `debug == true`: When `debug == true`:
* Runtime: * Runtime:
* Inicializa * Initializes
* Abre socket DevTools * Opens DevTools socket
* Aguarda comando `start` * Waits for `start` command
* Somente após isso inicia execução do cartucho * Only after that does it start cartridge execution
--- ---
## 8. Estabilidade ## 8. Stability
* BootTarget é contrato interno do POS * BootTarget is an internal POS contract
* CLI do host deve respeitar essas regras * Host CLI must respect these rules
* Novos modos de boot devem ser extensões compatíveis * New boot modes must be compatible extensions
< [Voltar](chapter-13.md) | [Sumário](table-of-contents.md) > < [Back](chapter-13.md) | [Summary](table-of-contents.md) >

View File

@ -1,87 +1,87 @@
< [Voltar](chapter-1.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-3.md) > < [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >
# ⚙️ ** PVM (PROMETEU VM) — Instruction Set** # ⚙️ ** PVM (PROMETEU VM) — Instruction Set**
## 1. Visão Geral ## 1. Overview
A **PROMETEU VM** é uma máquina virtual obrigatória e sempre presente no hardware lógico: The **PROMETEU VM** is a mandatory virtual machine always present in the logical hardware:
* **stack-based** * **stack-based**
* determinística * deterministic
* orientada a ciclos * cycle-oriented
* projetada para ensino e inspeção * designed for teaching and inspection
Ela existe para: It exists to:
* mapear conceitos de linguagens de alto nível * map high-level language concepts
* tornar custo computacional visível * make computational cost visible
* permitir análise de execução * allow execution analysis
* servir como base do cartucho PROMETEU * serve as the foundation of the PROMETEU cartridge
> A PROMETEU VM é simples por escolha. > The PROMETEU VM is simple by choice.
> Simplicidade é uma ferramenta pedagógica. > Simplicity is a pedagogical tool.
--- ---
## 2. Modelo de Execução ## 2. Execution Model
### 2.1 Componentes Principais ### 2.1 Main Components
A VM possui: The VM has:
* **PC (Program Counter)**próxima instrução * **PC (Program Counter)**next instruction
* **Operand Stack**pilha de valores * **Operand Stack**value stack
* **Call Stack**pilha de frames * **Call Stack** — frame stack
* **Heap**memória dinâmica * **Heap**dynamic memory
* **Globals**variáveis globais * **Globals** — global variables
* **Constant Pool** — literais e referências * **Constant Pool** — literals and references
* **ROM** — bytecode do cartucho * **ROM**cartridge bytecode
* **RAM**dados mutáveis * **RAM**mutable data
--- ---
### 2.2 Ciclo de Execução ### 2.2 Execution Cycle
Cada instrução executa: Each instruction executes:
``` ```
FETCH → DECODE → EXECUTE → ADVANCE PC FETCH → DECODE → EXECUTE → ADVANCE PC
``` ```
Propriedades: Properties:
* toda instrução tem custo fixo em ciclos * every instruction has a fixed cost in cycles
* não há trabalho implícito invisível * there is no invisible implicit work
* execução é totalmente determinística * execution is fully deterministic
--- ---
## 3. Tipos Fundamentais ## 3. Fundamental Types
| Tipo | Descrição | | Type | Description |
| --------- | ----------------------- | | --------- | ------------------------- |
| `integer` | inteiro 64-bit (signed) | | `integer` | 64-bit signed integer |
| `float` | ponto flutuante 64-bit | | `float` | 64-bit floating point |
| `boolean` | verdadeiro/falso | | `boolean` | true/false |
| `string` | UTF-8 imutável | | `string` | immutable UTF-8 |
| `null` | ausência de valor | | `null` | absence of value |
| `ref` | referência ao heap | | `ref` | heap reference |
Não existem: Do not exist:
* coerções mágicas * magic coercions
* casts implícitos * implicit casts
* overflows silenciosos * silent overflows
--- ---
## 4. Convenções da Pilha ## 4. Stack Conventions
* Operações usam o topo da pilha * Operations use the top of the stack
* Resultado sempre volta para a pilha * Results always return to the stack
* Último empilhado = primeiro consumido * Last pushed = first consumed
Exemplo: Example:
``` ```
PUSH_CONST 3 PUSH_CONST 3
@ -89,7 +89,7 @@ PUSH_CONST 4
ADD ADD
``` ```
Estado: State:
``` ```
[3] [3]
@ -99,47 +99,47 @@ Estado:
--- ---
## 5. Categorias de Instruções ## 5. Instruction Categories
1. Controle de fluxo 1. Flow control
2. Pilha 2. Stack
3. Aritmética e lógica 3. Arithmetic and logic
4. Variáveis 4. Variables
5. Funções 5. Functions
6. Heap e estruturas 6. Heap and structures
7. Periféricos (syscalls) 7. Peripherals (syscalls)
8. Sistema 8. System
--- ---
## 6. Instruções — VM Set 1 ## 6. Instructions — VM Set 1
### 6.1 Controle de Execução ### 6.1 Execution Control
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
| ------------------- | ------ | ----------------------- | | ------------------- | ------ | ------------------------- |
| `NOP` | 1 | Não faz nada | | `NOP` | 1 | Does nothing |
| `HALT` | 1 | Encerra execução | | `HALT` | 1 | Terminates execution |
| `JMP addr` | 2 | Salto incondicional | | `JMP addr` | 2 | Unconditional jump |
| `JMP_IF_FALSE addr` | 3 | Salta se topo for falso | | `JMP_IF_FALSE addr` | 3 | Jumps if top is false |
--- ---
### 6.2 Pilha ### 6.2 Stack
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
| -------------- | ------ | ----------------- | | -------------- | ------ | ------------------- |
| `PUSH_CONST k` | 2 | Empilha constante | | `PUSH_CONST k` | 2 | Pushes constant |
| `POP` | 1 | Remove topo | | `POP` | 1 | Removes top |
| `DUP` | 1 | Duplica topo | | `DUP` | 1 | Duplicates top |
| `SWAP` | 1 | Troca dois topos | | `SWAP` | 1 | Swaps two tops |
--- ---
### 6.3 Aritmética ### 6.3 Arithmetic
| Instrução | Ciclos | | Instruction | Cycles |
| --------- | ------ | | ----------- | ------ |
| `ADD` | 2 | | `ADD` | 2 |
| `SUB` | 2 | | `SUB` | 2 |
| `MUL` | 4 | | `MUL` | 4 |
@ -147,10 +147,10 @@ Estado:
--- ---
### 6.4 Comparação e Lógica ### 6.4 Comparison and Logic
| Instrução | Ciclos | | Instruction | Cycles |
| --------- | ------ | | ----------- | ------ |
| `EQ` | 2 | | `EQ` | 2 |
| `NEQ` | 2 | | `NEQ` | 2 |
| `LT` | 2 | | `LT` | 2 |
@ -161,53 +161,53 @@ Estado:
--- ---
### 6.5 Variáveis ### 6.5 Variables
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
| -------------- | ------ | -------------- | | -------------- | ------ | ---------------- |
| `GET_GLOBAL i` | 3 | Lê global | | `GET_GLOBAL i` | 3 | Reads global |
| `SET_GLOBAL i` | 3 | Escreve global | | `SET_GLOBAL i` | 3 | Writes global |
| `GET_LOCAL i` | 2 | Lê local | | `GET_LOCAL i` | 2 | Reads local |
| `SET_LOCAL i` | 2 | Escreve local | | `SET_LOCAL i` | 2 | Writes local |
--- ---
### 6.6 Funções ### 6.6 Functions
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
|----------------| ------ |---------------------------------| |----------------| ------ |---------------------------------|
| `CALL addr` | 5 | Chamada | | `CALL addr` | 5 | Call |
| `RET` | 4 | Retorno | | `RET` | 4 | Return |
| `PUSH_SCOPE n` | 3 | Cria escopo (frame de execução) | | `PUSH_SCOPE n` | 3 | Creates scope (execution frame) |
| `POP_SCOPE` | 3 | Remove escopo | | `POP_SCOPE` | 3 | Removes scope |
--- ---
### 6.7 Heap ### 6.7 Heap
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
| --------------- | ------ | ------------- | | --------------- | ------ | --------------- |
| `ALLOC size` | 10 | Aloca no heap | | `ALLOC size` | 10 | Allocates on heap |
| `LOAD_REF off` | 3 | Lê campo | | `LOAD_REF off` | 3 | Reads field |
| `STORE_REF off` | 3 | Escreve campo | | `STORE_REF off` | 3 | Writes field |
Heap é: Heap is:
* finito * finite
* monitorado * monitored
* contabilizado no CAP * accounted for in the CAP
--- ---
### 6.8 Periféricos (Syscalls) ### 6.8 Peripherals (Syscalls)
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
|--------------| -------- | ------------------- | |--------------| -------- | --------------------- |
| `SYSCALL id` | variável | Chamada ao hardware | | `SYSCALL id` | variable | Call to hardware |
#### Syscalls Implementadas (v0.1) #### Implemented Syscalls (v0.1)
| ID | Nome | Argumentos (Pilha) | Retorno | | ID | Name | Arguments (Stack) | Return |
| ---------- | ----------------- | ---------------------------- | ------- | | ---------- | ----------------- | ---------------------------- | ------- |
| `0x0001` | `system.has_cart` | - | `bool` | | `0x0001` | `system.has_cart` | - | `bool` |
| `0x0002` | `system.run_cart` | - | - | | `0x0002` | `system.run_cart` | - | - |
@ -216,7 +216,7 @@ Heap é:
| `0x2001` | `input.get_pad` | `button_id` | `bool` | | `0x2001` | `input.get_pad` | `button_id` | `bool` |
| `0x3001` | `audio.play` | `s_id, v_id, vol, pan, pitch`| - | | `0x3001` | `audio.play` | `s_id, v_id, vol, pan, pitch`| - |
**IDs de Botões:** **Button IDs:**
- `0`: Up, `1`: Down, `2`: Left, `3`: Right - `0`: Up, `1`: Down, `2`: Left, `3`: Right
- `4`: A, `5`: B, `6`: X, `7`: Y - `4`: A, `5`: B, `6`: X, `7`: Y
- `8`: L, `9`: R - `8`: L, `9`: R
@ -224,57 +224,57 @@ Heap é:
--- ---
## 7. Erros de Execução ## 7. Execution Errors
Erros são: Errors are:
* explícitos * explicit
* fatais * fatal
* nunca silenciosos * never silent
Tipos: Types:
* stack underflow * stack underflow
* tipo inválido * invalid type
* heap inválido * invalid heap
* frame inválido * invalid frame
Geram: Generate:
* mensagem clara * clear message
* dump de estado * state dump
* stack trace * stack trace
--- ---
## 8. Determinismo ## 8. Determinism
Garantias: Guarantees:
* mesma entrada → mesmo resultado * same input → same result
* mesma sequência → mesmos ciclos * same sequence → same cycles
* sem execução especulativa * no speculative execution
* sem otimizações invisíveis * no invisible optimizations
> Se você vê a instrução, você paga por ela. > If you see the instruction, you pay for it.
--- ---
## 9. Relação com Linguagens ## 9. Relationship with Languages
Java, TypeScript, Lua etc: Java, TypeScript, Lua etc:
* são linguagens-fonte * are source languages
* compiladas para esse bytecode * compiled to this bytecode
* nunca executadas diretamente * never executed directly
Todas rodam na **mesma VM**. All run on the **same VM**.
--- ---
## 10. Exemplo ## 10. Example
Fonte: Source:
```java ```java
x = 3 + 4; x = 3 + 4;
@ -289,107 +289,107 @@ ADD
SET_GLOBAL 0 SET_GLOBAL 0
``` ```
Custo: Cost:
``` ```
2 + 2 + 2 + 3 = 9 ciclos 2 + 2 + 2 + 3 = 9 cycles
``` ```
--- ---
## 11. Execução por Tick ## 11. Execution per Tick
A VM não roda infinitamente. The VM does not run infinitely.
Ela executa: It executes:
* até consumir o budget do **frame lógico** * until consuming the **logical frame** budget
* ou até `HALT` * or until `HALT`
O budget é definido pelo hardware lógico do PROMETEU (ex.: `CYCLES_PER_FRAME`). The budget is defined by the PROMETEU logical hardware (e.g., `CYCLES_PER_FRAME`).
Exemplo: Example:
``` ```
vm.step_budget(10_000) vm.step_budget(10_000)
``` ```
Isso alimenta: This feeds:
* CAP * CAP
* profiling * profiling
* certificação * certification
--- ---
## 12. Frame Lógico e `FRAME_SYNC` ## 12. Logical Frame and `FRAME_SYNC`
O PROMETEU define **frame lógico** como a unidade mínima de atualização consistente do jogo. PROMETEU defines **logical frame** as the minimum unit of consistent game update.
* **Input é latched por frame lógico** (não muda enquanto o frame lógico não for concluído). * **Input is latched per logical frame** (does not change until the logical frame is completed).
* O **budget de ciclos** é aplicado ao frame lógico. * The **cycle budget** is applied to the logical frame.
* Um novo frame lógico só começa quando o frame atual termina. * A new logical frame only starts when the current frame ends.
### 12.1 Instrução de Sistema: `FRAME_SYNC` ### 12.1 System Instruction: `FRAME_SYNC`
A instrução `FRAME_SYNC` marca o **fim do frame lógico**. The `FRAME_SYNC` instruction marks the **end of the logical frame**.
| Instrução | Ciclos | Descrição | | Instruction | Cycles | Description |
| ------------ | ------ | ----------------------------- | | ------------ | ------ | ---------------------------------- |
| `FRAME_SYNC` | 1 | Finaliza o frame lógico atual | | `FRAME_SYNC` | 1 | Finalizes the current logical frame |
Propriedades: Properties:
* `FRAME_SYNC` é uma **instrução do sistema**. * `FRAME_SYNC` is a **system instruction**.
* Não deve ser exposta como API “manual” ao usuário. * It should not be exposed as a "manual" API to the user.
* O tooling/compilador pode **injetar** `FRAME_SYNC` automaticamente ao final do loop principal. * Tooling/compiler can **inject** `FRAME_SYNC` automatically at the end of the main loop.
### 12.2 Semântica (o que acontece quando executa) ### 12.2 Semantics (what happens when it executes)
Ao executar `FRAME_SYNC`, o core: When executing `FRAME_SYNC`, the core:
1. **Finaliza** o frame lógico atual. 1. **Finalizes** the current logical frame.
2. **Apresenta** o frame (`gfx.present()` ou `gfx.compose_and_present()` conforme o modelo do GFX). 2. **Presents** the frame (`gfx.present()` or `gfx.compose_and_present()` depending on the GFX model).
3. **Libera** o latch de input. 3. **Releases** the input latch.
4. **Reseta** o budget para o próximo frame lógico. 4. **Resets** the budget for the next logical frame.
### 12.3 Overbudget (quando o frame não termina a tempo) ### 12.3 Overbudget (when the frame doesn't finish on time)
Se o budget do frame lógico acabar **antes** da VM alcançar `FRAME_SYNC`: If the logical frame budget runs out **before** the VM reaches `FRAME_SYNC`:
* a VM **pausa** (PC e pilhas permanecem no ponto exato) * the VM **pauses** (PC and stacks remain at the exact point)
* **não present** * there is **no present**
* o latch de input é **mantido** * the input latch is **maintained**
* no próximo tick do host, a VM **continua** de onde parou, ainda no mesmo frame lógico * on the next host tick, the VM **continues** from where it left off, still in the same logical frame
Efeito prático: Practical effect:
* 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) * if the code needs 2 budgets to reach `FRAME_SYNC`, the game updates at ~30 FPS (logical frame takes 2 ticks)
* isso é determinístico e reportável no CAP * this is deterministic and reportable in the CAP
--- ---
## 15. Extensibilidade ## 15. Extensibility
O Instruction Set é versionado. The Instruction Set is versioned.
Futuro: Future:
* DMA * DMA
* streaming * streaming
* vetores * vectors
* coprocessadores fictícios * fictitious coprocessors
Nenhuma instrução existente muda de significado. No existing instruction changes its meaning.
--- ---
## 16. Resumo ## 16. Summary
* VM stack-based * stack-based VM
* custo explícito * explicit cost
* execução determinística * deterministic execution
* integrada ao CAP * integrated with CAP
* base de todo cartucho PROMETEU * foundation of every PROMETEU cartridge
< [Voltar](chapter-1.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-3.md) > < [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >

View File

@ -1,29 +1,29 @@
< [Voltar](chapter-2.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-4.md) > < [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
# 🧠 **Memória: Stack, Heap e Alocação** # 🧠 **Memory: Stack, Heap, and Allocation**
## 1. Visão Geral ## 1. Overview
PROMETEU trata **memória como um recurso explícito**. PROMETEU treats **memory as an explicit resource**.
Nada é alocado “por conveniência”. Nothing is allocated "for convenience".
Nada cresce “automaticamente”. Nothing grows "automatically".
Nada é invisível. Nothing is invisible.
Este capítulo define: This chapter defines:
- os **espaços de memória** da PROMETEU VM - the **memory spaces** of the PROMETEU VM
- como **Stack** e **Heap** funcionam - how **Stack** and **Heap** work
- o custo e as consequências da **alocação dinâmica** - the cost and consequences of **dynamic allocation**
- como a memória se relaciona com **CAP e certificação** - how memory relates to **CAP and certification**
--- ---
## 2. Espaços de Memória da PROMETEU VM ## 2. PROMETEU VM Memory Spaces
A memória da PROMETEU VM é dividida em regiões com responsabilidades claras: The PROMETEU VM memory is divided into regions with clear responsibilities:
``` ```
+---------------------------+ +---------------------------+
@ -41,61 +41,61 @@ A memória da PROMETEU VM é dividida em regiões com responsabilidades claras:
``` ```
Cada região: Each region:
- tem semântica própria - has its own semantics
- tem limites definidos - has defined limits
- tem impacto direto no custo de execução - has a direct impact on execution cost
--- ---
## 3. Operand Stack ## 3. Operand Stack
### 3.1 Definição ### 3.1 Definition
A **Operand Stack** é usada para: The **Operand Stack** is used for:
- passagem de operandos entre instruções - passing operands between instructions
- resultados intermediários - intermediate results
- avaliação de expressões - expression evaluation
Ela é: It is:
- **LIFO** - **LIFO**
- de crescimento automático dentro do frame - automatically growing within the frame
- **resetada** entre frames (exceto valores persistidos explicitamente) - **reset** between frames (except explicitly persisted values)
--- ---
### 3.2 Características ### 3.2 Characteristics
- não armazena estruturas complexas - does not store complex structures
- armazena valores primitivos ou referências - stores primitive values or references
- overflow ou underflow são **erros fatais** - overflow or underflow are **fatal errors**
> A pilha de operandos é barata, rápida e temporária. > The operand stack is cheap, fast, and temporary.
> >
--- ---
## 4. Call Stack (Stack de Chamadas) ## 4. Call Stack
### 4.1 Frames de Execução ### 4.1 Execution Frames
Cada chamada de função cria um **Call Frame**, contendo: Each function call creates a **Call Frame**, containing:
- variáveis locais - local variables
- parâmetros - parameters
- endereço de retorno - return address
- contexto de execução - execution context
Frames são criados com: Frames are created with:
``` ```
PUSH_FRAME n PUSH_FRAME n
``` ```
E destruídos com: And destroyed with:
``` ```
POP_FRAME POP_FRAME
@ -103,64 +103,64 @@ POP_FRAME
--- ---
### 4.2 Custos e Limites ### 4.2 Costs and Limits
- criação de frame tem custo explícito - frame creation has an explicit cost
- profundidade máxima de stack é limitada - maximum stack depth is limited
- recursão profunda é desencorajada - deep recursion is discouraged
PROMETEU favorece: PROMETEU favors:
- iteração - iteration
- estado explícito - explicit state
- controle consciente de profundidade - conscious depth control
--- ---
## 5. Global Space ## 5. Global Space
### 5.1 Definição ### 5.1 Definition
O **Global Space** armazena: The **Global Space** stores:
- variáveis globais - global variables
- estado persistente do jogo - persistent game state
- referências de longo prazo - long-term references
Globais: Globals:
- sobrevivem entre frames - survive between frames
- ocupam memória permanentemente - occupy memory permanently
- contam para o uso total de memória - count towards total memory usage
--- ---
### 5.2 Uso consciente ### 5.2 Conscious usage
PROMETEU incentiva: PROMETEU encourages:
- poucas globais - few globals
- estruturas compactas - compact structures
- inicialização explícita - explicit initialization
Globais são equivalentes a **RAM estática** em microcontroladores. Globals are equivalent to **static RAM** in microcontrollers.
--- ---
## 6. Heap ## 6. Heap
### 6.1 Definição ### 6.1 Definition
O **Heap** é a região de memória dinâmica da PROMETEU VM. The **Heap** is the dynamic memory region of the PROMETEU VM.
É usado para: It is used for:
- objetos - objects
- arrays - arrays
- tabelas - tables
- estruturas compostas - composite structures
Toda alocação no heap é feita explicitamente com: Every allocation on the heap is done explicitly with:
``` ```
ALLOC size ALLOC size
@ -168,142 +168,142 @@ ALLOC size
--- ---
### 6.2 Custos da Alocação ### 6.2 Allocation Costs
Alocar memória: Allocating memory:
- consome **ciclos** - consumes **cycles**
- consome **heap disponível** - consumes **available heap**
- aumenta pressão sobre o sistema - increases pressure on the system
PROMETEU trata alocação como uma operação **cara por definição**. PROMETEU treats allocation as an **expensive operation by definition**.
> Alocar é uma decisão arquitetural, não um detalhe. > Allocation is an architectural decision, not a detail.
> >
--- ---
## 7. Limites de Heap ## 7. Heap Limits
### 7.1 Heap Finito ### 7.1 Finite Heap
O heap: The heap:
- tem tamanho máximo definido - has a defined maximum size
- pode variar conforme o CAP ativo - can vary according to the active CAP
- nunca cresce dinamicamente - never grows dynamically
Exemplo: Example:
``` ```
Heap Limit:32KB Heap Limit:32KB
Heap Used:28KB Heap Used:28KB
``` ```
Ultrapassar o limite: Exceeding the limit:
- não trava o jogo - does not crash the game
- gera erro de execução - generates an execution error
- aparece no relatório de certificação - appears in the certification report
--- ---
### 7.2 Heap e CAP ### 7.2 Heap and CAP
Durante uma JAM ou avaliação: During a JAM or evaluation:
- o pico de heap é medido - heap peak is measured
- o valor é comparado ao limite do CAP - the value is compared to the CAP limit
- não conformidades são registradas - non-compliances are recorded
O jogo **continua rodando**, mas a evidência fica registrada. The game **continues running**, but the evidence is recorded.
--- ---
## 8. Garbage Collection (GC) ## 8. Garbage Collection (GC)
### 8.1 Existência do GC ### 8.1 Existence of GC
PROMETEU pode utilizar **Garbage Collection simples**, com as seguintes propriedades: PROMETEU may use **simple Garbage Collection**, with the following properties:
- não incremental (v0.1) - non-incremental (v0.1)
- custo explícito - explicit cost
- pausas observáveis - observable pauses
- comportamento documentado - documented behavior
GC **não é invisível**. GC **is not invisible**.
--- ---
### 8.2 Custo do GC ### 8.2 GC Cost
Quando o GC ocorre: When GC occurs:
- ciclos são consumidos - cycles are consumed
- o frame pode sofrer impacto - the frame may be impacted
- o evento é registrado - the event is recorded
PROMETEU ensina: PROMETEU teaches:
> “Criar lixo tem custo.” > "Creating garbage has a cost."
> >
--- ---
## 9. Boas Práticas de Memória ## 9. Memory Best Practices
PROMETEU encoraja explicitamente: PROMETEU explicitly encourages:
- reutilização de estruturas - structure reuse
- alocação fora do loop principal - allocation outside the main loop
- buffers persistentes - persistent buffers
- pooling manual - pooling manual
E desencoraja: And discourages:
- alocação por frame - per-frame allocation
- estruturas temporárias descartáveis - disposable temporary structures
- crescimento não planejado - unplanned growth
--- ---
## 10. Relação com Microcontroladores ## 10. Relationship with Microcontrollers
O modelo de memória PROMETEU é intencionalmente similar a MCUs reais: The PROMETEU memory model is intentionally similar to real MCUs:
| MCU | PROMETEU | | MCU | PROMETEU |
| --- | --- | | --- | --- |
| RAM estática | Global Space | | Static RAM | Global Space |
| Stack | Call Stack | | Stack | Call Stack |
| Heap | Heap | | Heap | Heap |
| Falha de alocação | Erro explícito | | Allocation failure | Explicit error |
| Fragmentação | Responsabilidade do dev | | Fragmentation | Dev's responsibility |
Isso cria transferência direta de aprendizado. This creates a direct transfer of learning.
--- ---
## 11. Implicações Pedagógicas ## 11. Pedagogical Implications
Este modelo permite ensinar: This model allows teaching:
- diferença entre stack e heap - the difference between stack and heap
- custo de alocação - allocation cost
- lifetime de dados - data lifetime
- impacto arquitetural de decisões simples - architectural impact of simple decisions
- relação entre memória e tempo - the relationship between memory and time
Tudo com **feedback imediato e visível**. Everything with **immediate and visible feedback**.
--- ---
## 12. Resumo ## 12. Summary
- PROMETEU possui espaços de memória bem definidos - PROMETEU has well-defined memory spaces
- stack é temporária e barata - stack is temporary and cheap
- heap é finita e cara - heap is finite and expensive
- alocação tem custo explícito - allocation has an explicit cost
- GC é visível e mensurável - GC is visible and measurable
- memória participa da certificação - memory participates in certification
< [Voltar](chapter-2.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-4.md) > < [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >

View File

@ -1,229 +1,229 @@
< [Voltar](chapter-3.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-5.md) > < [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >
# 🎨 **Periférico GFX (Sistema Gráfico)** # 🎨 **GFX Peripheral (Graphics System)**
## 1. Visão Geral ## 1. Overview
O periférico **GFX** é responsável pela geração de imagem no PROMETEU. The **GFX** peripheral is responsible for generating images in PROMETEU.
Ele modela um **hardware gráfico simples**, inspirado em consoles clássicos It models **simple graphics hardware**, inspired by classic consoles
(SNES, CPS-2, Neo-Geo), priorizando: (SNES, CPS-2, Neo-Geo), prioritizing:
- determinismo - determinism
- baixo custo computacional - low computational cost
- didática - didactics
- portabilidade - portability
O GFX **não é uma GPU moderna**. The GFX **is not a modern GPU**.
Ele é um dispositivo explícito, baseado em: It is an explicit device, based on:
- framebuffer - framebuffer
- tilemaps - tilemaps
- banks de tiles - tile banks
- sprites por prioridade - priority-based sprites
- composição por ordem de desenho - composition by drawing order
--- ---
## 2. Resolução e Framebuffer ## 2. Resolution and Framebuffer
### Resolução base ### Base resolution
- **320 × 180 pixels** - **320 × 180 pixels**
- proporção próxima de 16:9 - aspect ratio close to 16:9
- escalável pelo host (nearest-neighbor) - scalable by the host (nearest-neighbor)
### Formato de pixel ### Pixel format
- **RGB565** - **RGB565**
- 5 bits Red - 5 bits Red
- 6 bits Green - 6 bits Green
- 5 bits Blue - 5 bits Blue
- sem canal alpha - no alpha channel
Transparência é feita por **color key**. Transparency is handled via **color key**.
--- ---
## 3. Double Buffering ## 3. Double Buffering
O GFX mantém dois buffers: The GFX maintains two buffers:
- **Back Buffer**onde o frame é construído - **Back Buffer**where the frame is built
- **Front Buffer**onde o frame é exibido - **Front Buffer**where the frame is displayed
Fluxo por frame: Per-frame flow:
1. O sistema desenha no back buffer 1. The system draws to the back buffer
2. Chama `present()` 2. Calls `present()`
3. Buffers são trocados 3. Buffers are swapped
4. O host exibe o front buffer 4. The host displays the front buffer
Isso garante: This guarantees:
- ausência de tearing - no tearing
- sincronização clara por frame - clear per-frame synchronization
- comportamento determinístico - deterministic behavior
--- ---
## 4. Estrutura Gráfica do PROMETEU ## 4. PROMETEU Graphical Structure
O mundo gráfico é composto por: The graphical world is composed of:
- Até **16 Tile Banks** - Up to **16 Tile Banks**
- **4 Tile Layers** (scrolláveis) - **4 Tile Layers** (scrollable)
- **1 HUD Layer** (fixa, sempre por cima) - **1 HUD Layer** (fixed, always on top)
- Sprites com prioridade entre layers - Sprites with priority between layers
### 4.1 Tile Banks ### 4.1 Tile Banks
- Existem até **16 banks** - There are up to **16 banks**
- Cada bank tem tamanho fixo de tile: - Each bank has a fixed tile size:
- 8×8, 16×16 ou 32×32 - 8×8, 16×16, or 32×32
- Um bank é uma biblioteca de gráficos: - A bank is a graphics library:
- ambiente - environment
- personagens - characters
- UI - UI
- efeitos - effects
### 4.2 Layers ### 4.2 Layers
- Existem: - There are:
- 4 Tile Layers - 4 Tile Layers
- 1 HUD Layer - 1 HUD Layer
- Cada layer aponta para **um único bank** - Each layer points to **a single bank**
- Sprites podem usar **qualquer bank** - Sprites can use **any bank**
- HUD: - HUD:
- não scrolla - does not scroll
- prioridade máxima - maximum priority
- geralmente usa tiles 8×8 - generally uses 8×8 tiles
--- ---
## 5. Modelo Interno de uma Tile Layer ## 5. Internal Model of a Tile Layer
Uma Tile Layer **não é um bitmap de pixels**. A Tile Layer **is not a bitmap of pixels**.
Ela é composta por: It is composed of:
- Um **Tilemap lógico** (índices de tiles) - A **logical Tilemap** (tile indices)
- Um **Cache de Borda** (janela de tiles visíveis) - A **Border Cache** (window of visible tiles)
- Um **Offset de Scroll** - A **Scroll Offset**
### Estrutura: ### Structure:
- `bank_id` - `bank_id`
- `tile_size` - `tile_size`
- `tilemap` (matriz grande) - `tilemap` (large matrix)
- `scroll_x`, `scroll_y` - `scroll_x`, `scroll_y`
- `cache_origin_x`, `cache_origin_y` - `cache_origin_x`, `cache_origin_y`
- `cache_tiles[w][h]` - `cache_tiles[w][h]`
--- ---
## 6. Tilemap Lógico ## 6. Logical Tilemap
O tilemap representa o mundo: The tilemap represents the world:
Cada célula contém: Each cell contains:
- `tile_id` - `tile_id`
- `flip_x` - `flip_x`
- `flip_y` - `flip_y`
- `priority` (opcional) - `priority` (optional)
- `palette_id` (opcional) - `palette_id` (optional)
O tilemap pode ser muito maior que a tela. The tilemap can be much larger than the screen.
--- ---
## 7. Cache de Borda (Tile Cache) ## 7. Border Cache (Tile Cache)
O cache é uma janela de tiles ao redor da câmera. The cache is a window of tiles around the camera.
Exemplo: Example:
- Tela: 320×180 - Screen: 320×180
- Tiles 16×16 → 20×12 visíveis - 16×16 tiles → 20×12 visible
- Cache: 22×14 (margem de 1 tile) - Cache: 22×14 (1-tile margin)
Ele guarda os tiles já resolvidos a partir do tilemap. It stores tiles already resolved from the tilemap.
--- ---
## 8. Atualização do Cache ## 8. Cache Update
A cada frame: Every frame:
1. Calcular: 1. Calculate:
- `tile_x = scroll_x / tile_size` - `tile_x = scroll_x / tile_size`
- `tile_y = scroll_y / tile_size` - `tile_y = scroll_y / tile_size`
- `offset_x = scroll_x % tile_size` - `offset_x = scroll_x % tile_size`
- `offset_y = scroll_y % tile_size` - `offset_y = scroll_y % tile_size`
2. Se `tile_x` mudou: 2. If `tile_x` changed:
- Avança `cache_origin_x` - Advance `cache_origin_x`
- Recarrega apenas a nova coluna - Reload only the new column
3. Se `tile_y` mudou: 3. If `tile_y` changed:
- Avança `cache_origin_y` - Advance `cache_origin_y`
- Recarrega apenas a nova linha - Reload only the new line
Somente **uma linha e/ou coluna** é atualizada por frame. Only **one row and/or column** is updated per frame.
--- ---
## 9. Cache como Ring Buffer ## 9. Cache as Ring Buffer
O cache é circular: The cache is circular:
- Não move dados fisicamente - Does not physically move data
- Apenas move índices lógicos - Only moves logical indices
Acesso: Access:
- `real_x = (cache_origin_x + logical_x) % cache_width` - `real_x = (cache_origin_x + logical_x) % cache_width`
- `real_y = (cache_origin_y + logical_y) % cache_height` - `real_y = (cache_origin_y + logical_y) % cache_height`
--- ---
## 10. Projeção para o Back Buffer ## 10. Projection to the Back Buffer
Para cada frame: For each frame:
1. Para cada Tile Layer, em ordem: 1. For each Tile Layer, in order:
- Rasterizar tiles visíveis do cache - Rasterize visible tiles from the cache
- Aplicar scroll, flip e transparência - Apply scroll, flip, and transparency
- Escrever no back buffer - Write to the back buffer
2. Desenhar sprites: 2. Draw sprites:
- Com prioridade entre layers - With priority between layers
- Ordem de desenho define profundidade - Drawing order defines depth
3. Desenhar HUD layer por último 3. Draw HUD layer last
--- ---
## 11. Ordem de Desenho e Prioridade ## 11. Drawing Order and Priority
- Não existe Z-buffer - There is no Z-buffer
- Não existe sorting automático - There is no automatic sorting
- Quem desenha depois fica na frente - Whoever draws later is in front
Ordem base: Base order:
1. Tile Layer 0 1. Tile Layer 0
2. Tile Layer 1 2. Tile Layer 1
3. Tile Layer 2 3. Tile Layer 2
4. Tile Layer 3 4. Tile Layer 3
5. Sprites (por prioridade entre layers) 5. Sprites (by priority between layers)
6. HUD Layer 6. HUD Layer
--- ---
## 12. Transparência (Color Key) ## 12. Transparency (Color Key)
- Um valor RGB565 é reservado como TRANSPARENT_KEY - One RGB565 value is reserved as TRANSPARENT_KEY
- Pixels com essa cor não são desenhados - Pixels with this color are not drawn
``` ```
if src == TRANSPARENT_KEY: if src == TRANSPARENT_KEY:
@ -235,11 +235,11 @@ else:
--- ---
## 13. Color Math (Blending Discreto) ## 13. Color Math (Discrete Blending)
Inspirado no SNES. Inspired by the SNES.
Modos oficiais: Official modes:
- `BLEND_NONE` - `BLEND_NONE`
- `BLEND_HALF` - `BLEND_HALF`
@ -247,99 +247,99 @@ Modos oficiais:
- `BLEND_HALF_MINUS` - `BLEND_HALF_MINUS`
- `BLEND_FULL` - `BLEND_FULL`
Sem alpha contínuo. No continuous alpha.
Sem blending arbitrário. No arbitrary blending.
Tudo é: Everything is:
- inteiro - integer
- barato - cheap
- determinístico - deterministic
--- ---
## 14. Onde o Blend é Aplicado ## 14. Where Blend is Applied
- O blend ocorre durante o desenho - Blending occurs during drawing
- O resultado vai direto para o back buffer - The result goes directly to the back buffer
- Não existe composição posterior automática - There is no automatic post-composition
--- ---
## 15. O que o GFX NÃO suporta ## 15. What the GFX DOES NOT support
Por design: By design:
- Alpha contínuo - Continuous alpha
- RGBA framebuffer - RGBA framebuffer
- Shader - Shaders
- Pipeline moderno de GPU - Modern GPU pipeline
- HDR - HDR
- Gamma correction - Gamma correction
--- ---
## 16. Regra de Performance ## 16. Performance Rule
- Layers: - Layers:
- só atualizam borda ao cruzar tile - only update the border when crossing a tile
- nunca redesenham mundo inteiro - never redraw the entire world
- Rasterização: - Rasterization:
- sempre por frame, só área visível - always per frame, only the visible area
- Sprites: - Sprites:
- sempre redesenhados por frame - always redrawn per frame
--- ---
## 17. PostFX Especial — Fade (Scene e HUD) ## 17. Special PostFX — Fade (Scene and HUD)
O PROMETEU suporta **fade gradual** como um PostFX especial, com dois controles PROMETEU supports **gradual fade** as a special PostFX, with two independent
independentes: controls:
- **Scene Fade**: afeta toda a cena (Tile Layers 03 + Sprites) - **Scene Fade**: affects the entire scene (Tile Layers 03 + Sprites)
- **HUD Fade**: afeta apenas o HUD Layer (sempre composto por último) - **HUD Fade**: affects only the HUD Layer (always composed last)
O fade é implementado sem alpha contínuo por pixel e sem floats. The fade is implemented without continuous per-pixel alpha and without floats.
Ele usa um **nível inteiro discreto** (0..31), que na prática produz um resultado It uses a **discrete integer level** (0..31), which in practice produces an
visual “quase contínuo” em 320×180 pixel art. "almost continuous" visual result in 320×180 pixel art.
--- ---
### 17.1 Representação do Fade ### 17.1 Fade Representation
Cada fade é representado por: Each fade is represented by:
- `fade_level: u8` no intervalo **[0..31]** - `fade_level: u8` in the range **[0..31]**
- `0`totalmente substituído pela cor de fade - `0`fully replaced by the fade color
- `31`totalmente visível (sem fade) - `31`fully visible (no fade)
- `fade_color: RGB565` - `fade_color: RGB565`
- cor para a qual a imagem será misturada - color the image will be blended into
Registradores: Registers:
- `SCENE_FADE_LEVEL` (0..31) - `SCENE_FADE_LEVEL` (0..31)
- `SCENE_FADE_COLOR` (RGB565) - `SCENE_FADE_COLOR` (RGB565)
- `HUD_FADE_LEVEL` (0..31) - `HUD_FADE_LEVEL` (0..31)
- `HUD_FADE_COLOR` (RGB565) - `HUD_FADE_COLOR` (RGB565)
Casos comuns: Common cases:
- Fade-out: `fade_color = BLACK` - Fade-out: `fade_color = BLACK`
- Flash/teleporte: `fade_color = WHITE` - Flash/teleport: `fade_color = WHITE`
- Efeitos especiais: qualquer cor RGB565 - Special effects: any RGB565 color
--- ---
### 17.2 Operação de Fade (Mistura com Cor Arbitrária) ### 17.2 Fade Operation (Blending with Arbitrary Color)
Para cada pixel RGB565 `src` e cor de fade `fc`, o pixel final `dst` é calculado por canal. For each RGB565 pixel `src` and fade color `fc`, the final pixel `dst` is calculated per channel.
1) Extrair componentes: 1) Extract components:
- `src_r5`, `src_g6`, `src_b5` - `src_r5`, `src_g6`, `src_b5`
- `fc_r5`, `fc_g6`, `fc_b5` - `fc_r5`, `fc_g6`, `fc_b5`
2) Aplicar mistura inteira: 2) Apply integer blending:
``` ```
src_weight = fade_level // 0..31 src_weight = fade_level // 0..31
@ -352,127 +352,127 @@ b5 = (src_b5 * src_weight + fc_b5 * fc_weight) / 31
- `src_r5`, `src_g6`, `src_b5` - `src_r5`, `src_g6`, `src_b5`
- `fc_r5`, `fc_g6`, `fc_b5` - `fc_r5`, `fc_g6`, `fc_b5`
3) Reempacotar: 3) Repack:
``` ```
dst = pack_rgb565(r5, g6, b5) dst = pack_rgb565(r5, g6, b5)
``` ```
Observações: Notes:
- Operação determinística - Deterministic operation
- Somente inteiros - Integers only
- Pode ser otimizada via LUT - Can be optimized via LUT
--- ---
### 17.3 Ordem de Aplicação no Frame ### 17.3 Order of Application in the Frame
A composição do frame segue esta ordem: The frame composition follows this order:
1. Rasterizar **Tile Layers 03** → Back Buffer 1. Rasterize **Tile Layers 03** → Back Buffer
2. Rasterizar **Sprites** conforme prioridade 2. Rasterize **Sprites** according to priority
3. (Opcional) Pipeline extra (Emission/Light/Glow etc.) 3. (Optional) Extra pipeline (Emission/Light/Glow etc.)
4. Aplicar **Scene Fade** usando: 4. Apply **Scene Fade** using:
- `SCENE_FADE_LEVEL` - `SCENE_FADE_LEVEL`
- `SCENE_FADE_COLOR` - `SCENE_FADE_COLOR`
5. Rasterizar **HUD Layer** 5. Rasterize **HUD Layer**
6. Aplicar **HUD Fade** usando: 6. Apply **HUD Fade** using:
- `HUD_FADE_LEVEL` - `HUD_FADE_LEVEL`
- `HUD_FADE_COLOR` - `HUD_FADE_COLOR`
7. `present()` 7. `present()`
Regras: Rules:
- Scene Fade nunca afeta HUD - Scene Fade never affects the HUD
- HUD Fade nunca afeta a cena - HUD Fade never affects the scene
--- ---
### 17.4 Casos de Uso ### 17.4 Use Cases
- Troca de HUD: - HUD Switch:
- diminuir `HUD_FADE_LEVEL` até 0 - decrease `HUD_FADE_LEVEL` to 0
- trocar HUD/tilemap - switch HUD/tilemap
- aumentar `HUD_FADE_LEVEL` até 31 - increase `HUD_FADE_LEVEL` to 31
- Troca de área: - Area Switch:
- diminuir `SCENE_FADE_LEVEL` até 0 - decrease `SCENE_FADE_LEVEL` to 0
- trocar cenário - switch scenery
- aumentar `SCENE_FADE_LEVEL` até 31 - increase `SCENE_FADE_LEVEL` to 31
- Flash / dano / teleporte: - Flash / damage / teleport:
- usar `fade_color = WHITE` ou outra cor temática - use `fade_color = WHITE` or another thematic color
--- ---
## 18. Sistema de Paletas ## 18. Palette System
### 18.1. Visão Geral ### 18.1. Overview
O PROMETEU utiliza **exclusivamente** gráficos indexados por paleta. PROMETEU uses **exclusively** palette-indexed graphics.
Não existe modo RGB direto por pixel. There is no direct RGB-per-pixel mode.
Todo pixel gráfico é um **índice** que aponta para uma cor real em uma paleta. Every graphical pixel is an **index** pointing to a real color in a palette.
Objetivos: Objectives:
- reduzir uso de RAM e storage - reduce RAM and storage usage
- permitir troca de cores sem shader - allow color swapping without shaders
- manter identidade retrô - maintain retro identity
- facilitar efeitos como variação, dano, dia/noite - facilitate effects like variation, damage, day/night
--- ---
### 18.2. Formato de Pixel ### 18.2. Pixel Format
Cada pixel de um tile ou sprite é: Each pixel of a tile or sprite is:
- **4 bits por pixel (4bpp)** - **4 bits per pixel (4bpp)**
- valores: `0..15` - values: `0..15`
Regra fixa: Fixed rule:
- Índice `0` = TRANSPARENTE - Index `0` = TRANSPARENT
- Índices `1..15` = cores válidas da paleta - Indices `1..15` = valid palette colors
--- ---
### 18.3. Estrutura de Paletas ### 18.3. Palette Structure
Cada **Tile Bank** contém: Each **Tile Bank** contains:
- Até **256 paletas** - Up to **256 palettes**
- Cada paleta tem: - Each palette has:
- **16 cores** - **16 colors**
- cada cor em **RGB565 (u16)** - each color in **RGB565 (u16)**
Tamanho: Size:
- 1 paleta = 16 × 2 bytes = **32 bytes** - 1 palette = 16 × 2 bytes = **32 bytes**
- 256 paletas = **8 KB por bank** - 256 palettes = **8 KB per bank**
- 16 banks = **128 KB máximo de paletas** - 16 banks = **128 KB maximum palettes**
--- ---
### 18.4. Associação de Paleta ### 18.4. Palette Association
#### Regra Fundamental #### Fundamental Rule
- Cada **tile** usa **uma única paleta** - Each **tile** uses **a single palette**
- Cada **sprite** usa **uma única paleta** - Each **sprite** uses **a single palette**
- A paleta deve ser informada **explicitamente** em todo draw - The palette must be provided **explicitly** in every draw
Não existe troca de paleta dentro do mesmo tile ou sprite. There is no palette swap within the same tile or sprite.
--- ---
### 18.5. Onde a Paleta é Definida ### 18.5. Where the Palette is Defined
#### Tilemap #### Tilemap
Cada célula do tilemap contém: Each tilemap cell contains:
- `tile_id` - `tile_id`
- `palette_id (u8)` - `palette_id (u8)`
@ -481,7 +481,7 @@ Cada célula do tilemap contém:
#### Sprite #### Sprite
Cada sprite draw contém: Each sprite draw contains:
- `bank_id` - `bank_id`
- `tile_id` - `tile_id`
@ -492,20 +492,20 @@ Cada sprite draw contém:
--- ---
### 18.6. Resolução de Cor ### 18.6. Color Resolution
O pipeline funciona assim: The pipeline works like this:
1. Ler pixel indexado do tile (valor 0..15) 1. Read indexed pixel from tile (value 0..15)
2. Se índice == 0 → pixel transparente 2. If index == 0 → transparent pixel
3. Caso contrário: 3. Otherwise:
- cor_real = paleta[palette_id][indice] - real_color = palette[palette_id][index]
4. Aplicar: 4. Apply:
- flip - flip
- blend discreto - discrete blend
- escrita no back buffer - writing to back buffer
Ou seja: In other words:
``` ```
pixel_index = tile_pixel(x,y) pixel_index = tile_pixel(x,y)
if pixel_index == 0: if pixel_index == 0:
@ -517,84 +517,84 @@ else:
--- ---
### 18.7. Organização dos Tile Banks ### 18.7. Organization of Tile Banks
Os Tile Banks são “assets fortes”: Tile Banks are "strong assets":
- Tiles e paletas vivem juntos - Tiles and palettes live together
- Exportação/importação sempre leva: - Export/import always carries:
- tiles + paletas - tiles + palettes
- O hardware não impõe organização semântica: - The hardware does not impose semantic organization:
- o agrupamento é decisão do criador - grouping is the creator's decision
- Tooling e scripts podem criar convenções: - Tooling and scripts can create conventions:
- ex.: paletas 0..15 = inimigos - e.g.: palettes 0..15 = enemies
- 16..31 = cenário - 16..31 = scenery
- etc. - etc.
--- ---
### 18.8. Efeitos Possíveis com Paletas ### 18.8. Possible Effects with Palettes
Sem shader, é possível: Without shaders, it is possible to:
- Palette swap: - Palette swap:
- inimigos com variação de cor - enemies with color variation
- Estados: - States:
- dano, gelo, veneno, power-up - damage, ice, poison, power-up
- Dia / noite: - Day / night:
- trocar paletas globalmente - swap palettes globally
- Biomas: - Biomes:
- mesma arte, clima diferente - same art, different climate
- UI themes - UI themes
Tudo isso sem mudar os tiles. All this without changing tiles.
--- ---
### 18.9. Limitações Artísticas ### 18.9. Artistic Limitations
- Cada tile/sprite: - Each tile/sprite:
- máximo de 16 cores - maximum of 16 colors
- Gradientes suaves exigem: - Smooth gradients require:
- dithering - dithering
- blend discreto - discrete blend
- glow/emission - glow/emission
Essa limitação é intencional e faz parte da identidade do PROMETEU. This limitation is intentional and part of the PROMETEU identity.
--- ---
### 18.10. Métricas para Certificação (CAP) ### 18.10. Metrics for Certification (CAP)
O sistema pode medir: The system can measure:
- `palettes_loaded_total` - `palettes_loaded_total`
- `palettes_referenced_this_frame` - `palettes_referenced_this_frame`
- `tiles_drawn_by_palette_id` - `tiles_drawn_by_palette_id`
- `sprites_drawn_by_palette_id` - `sprites_drawn_by_palette_id`
Isso permite: This allows:
- analisar custo artístico - analyzing artistic cost
- ensinar impacto de variedade excessiva - teaching the impact of excessive variety
- sugerir boas práticas de coesão visual - suggesting best practices for visual cohesion
--- ---
## 19. Resumo ## 19. Summary
O GFX do PROMETEU é simples **por escolha**, não por limitação. PROMETEU's GFX is simple **by choice**, not by limitation.
- Framebuffer RGB565 com double buffer - RGB565 Framebuffer with double buffer
- Color key para transparência - Color key for transparency
- Blending discreto estilo SNES - SNES-style discrete blending
- Até 16 tile banks - Up to 16 tile banks
- 4 Tile Layers + 1 HUD - 4 Tile Layers + 1 HUD
- Layer = tilemap + cache + scroll - Layer = tilemap + cache + scroll
- Projeção rasterizada por frame - Rasterized projection per frame
- Profundidade definida por ordem de desenho - Depth defined by drawing order
< [Voltar](chapter-3.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-5.md) > < [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >

View File

@ -1,255 +1,255 @@
< [Voltar](chapter-4.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-6.md) > < [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
# 🔊 Periférico AUDIO (Sistema de Som) # 🔊 AUDIO Peripheral (Audio System)
## 1. Visão Geral ## 1. Overview
O **Periférico AUDIO** é responsável pela **geração e mistura de som** no PROMETEU. The **AUDIO Peripheral** is responsible for **sound generation and mixing** in PROMETEU.
Assim como os demais subsistemas: Just like the other subsystems:
- não é automático - it is not automatic
- não é gratuito - it is not free
- não é mágico - it is not magic
Cada som é resultado de **comandos explícitos**, executados sob **orçamento de tempo e recursos**. Each sound is the result of **explicit commands**, executed under a **time and resource budget**.
> Som consome tempo. > Sound consumes time.
> Som consome memória. > Sound consumes memory.
--- ---
## 2. Filosofia ## 2. Philosophy
PROMETEU trata áudio como: PROMETEU treats audio as:
- um **periférico ativo** - an **active peripheral**
- com **canais limitados** - with **limited channels**
- comportamento **determinístico** - **deterministic** behavior
- controle **explícito** - **explicit** control
Objetivo: clareza arquitetural e didática, não realismo absoluto. Objective: architectural and didactic clarity, not absolute realism.
--- ---
## 3. Arquitetura Geral ## 3. General Architecture
O sistema de áudio é composto por: The audio system is composed of:
- **Voices (canais)** — tocadores independentes - **Voices (channels)** — independent players
- **Samples**dados PCM - **Samples** — PCM data
- **Mixer** — soma das voices - **Mixer** — summation of voices
- **Saída** — buffer estéreo PCM - **Output** — PCM stereo buffer
Separação conceitual: Conceptual separation:
- Jogo envia **comandos a 60Hz** - Game sends **commands at 60Hz**
- Áudio é **gerado continuamente** em 48kHz - Audio is **generated continuously** at 48kHz
--- ---
## 4. Formato de Saída ## 4. Output Format
- Sample rate: **48.000 Hz** - Sample rate: **48,000 Hz**
- Formato: **PCM16 estéreo (signed i16)** - Format: **PCM16 stereo (signed i16)**
- Clipping: saturação/clamp - Clipping: saturation/clamp
Esse formato é compatível com: This format is compatible with:
- DACs I2S comuns - common I2S DACs
- HDMI áudio - HDMI audio
- USB áudio - USB audio
- SBCs DIY (Raspberry Pi, Orange Pi, etc.) - DIY SBCs (Raspberry Pi, Orange Pi, etc.)
--- ---
## 5. Voices (Canais) ## 5. Voices (Channels)
### 5.1 Quantidade ### 5.1 Quantity
``` ```
MAX_VOICES = 16 MAX_VOICES = 16
``` ```
Cada voice: Each voice:
- toca **1 sample por vez** - plays **1 sample at a time**
- é independente - is independent
- é misturada no output final - is mixed into the final output
--- ---
### 5.2 Estado de uma Voice ### 5.2 Voice State
Cada voice mantém: Each voice maintains:
- `sample_id` - `sample_id`
- `pos` (posição fracionária no sample) - `pos` (fractional position in the sample)
- `rate` (pitch) - `rate` (pitch)
- `volume` (0..255) - `volume` (0..255)
- `pan` (0..255, esquerda→direita) - `pan` (0..255, left→right)
- `loop_mode` (off / on) - `loop_mode` (off / on)
- `loop_start`, `loop_end` - `loop_start`, `loop_end`
- `priority` (opcional) - `priority` (optional)
--- ---
### 5.3 Conflito de Voices ### 5.3 Voice Conflict
Se todas as voices estiverem ocupadas: If all voices are occupied:
- aplica-se uma política explícita: - an explicit policy is applied:
- `STEAL_OLDEST` - `STEAL_OLDEST`
- `STEAL_QUIETEST` - `STEAL_QUIETEST`
- `STEAL_LOWEST_PRIORITY` - `STEAL_LOWEST_PRIORITY`
PROMETEU não resolve isso automaticamente sem regra definida. PROMETEU does not resolve this automatically without a defined rule.
--- ---
## 6. Modelo Conceitual: “CPU de Áudio ## 6. Conceptual Model: “Audio CPU
O AUDIO do PROMETEU é concebido como um **periférico independente**, assim como consoles clássicos tinham: The PROMETEU AUDIO is conceived as an **independent peripheral**, just as classic consoles had:
- CPU principal do jogo - Main game CPU
- CPU dedicada ao som - Dedicated sound CPU
No PROMETEU: In PROMETEU:
- O **core lógico** assume essa separação conceitual - The **logical core** assumes this conceptual separation
- O **host decide** como implementar: - The **host decides** how to implement it:
- mesma thread - same thread
- thread separada - separate thread
- core separado - separate core
### 6.1 Metáfora de Hardware ### 6.1 Hardware Metaphor
Conceitualmente: Conceptually:
``` ```
[CPU do Jogo] → envia comandos 60Hz → [Periférico AUDIO] [Game CPU] → sends 60Hz commands → [AUDIO Peripheral]
| |
v v
Voices + Mixer Voices + Mixer
| |
v v
Saída PCM PCM Output
``` ```
### 6.2 Implementação é Papel do Host ### 6.2 Implementation is the Host's Role
O core: The core:
- define o **modelo** - defines the **model**
- define os **comandos** - defines the **commands**
- define os **limites** - defines the **limits**
O host: The host:
- escolhe: - chooses:
- threads - threads
- afinidade de CPU - CPU affinity
- backend de áudio - audio backend
- garante entrega contínua dos buffers - guarantees continuous delivery of buffers
Assim: Thus:
> PROMETEU modela o hardware. > PROMETEU models the hardware.
> O host decide como realizá-lo fisicamente. > The host decides how to physically realize it.
--- ---
## 7. Samples ## 7. Samples
### 7.1 Formato ### 7.1 Format
Samples do PROMETEU: PROMETEU samples:
- **PCM16 mono** - **PCM16 mono**
- sample_rate próprio (ex.: 22050, 44100, 48000) - own sample_rate (e.g., 22050, 44100, 48000)
- dados imutáveis em runtime - immutable data at runtime
Campos: Fields:
- `sample_rate` - `sample_rate`
- `frames_len` - `frames_len`
- `loop_start`, `loop_end` (opcional) - `loop_start`, `loop_end` (optional)
--- ---
### 7.2 Uso ### 7.2 Usage
Exemplo: Example:
``` ```
audio.play(sample_id, voice_id, volume, pan, pitch, priority) audio.play(sample_id, voice_id, volume, pan, pitch, priority)
``` ```
Ou: Or:
``` ```
audio.playAuto(sample_id, volume, pan, pitch, priority) audio.playAuto(sample_id, volume, pan, pitch, priority)
``` ```
(usa política de stealing) (uses stealing policy)
--- ---
## 8. Pitch e Interpolação ## 8. Pitch and Interpolation
- `rate = 1.0`velocidade normal - `rate = 1.0` → normal speed
- `rate > 1.0`mais agudo - `rate > 1.0`higher pitch
- `rate < 1.0`mais grave - `rate < 1.0`lower pitch
Como posição vira fracionária: As position becomes fractional:
- usa-se **interpolação linear** entre dois samples vizinhos - **linear interpolation** is used between two neighboring samples
--- ---
## 9. Mixer ## 9. Mixer
Para cada frame de saída (48kHz): For each output frame (48kHz):
1. Para cada voice ativa: 1. For each active voice:
- ler sample na posição atual - read sample at current position
- aplicar pitch - apply pitch
- aplicar volume - apply volume
- aplicar pan → gera L/R - apply pan → generates L/R
2. Somar todas as voices 2. Sum all voices
3. Aplicar clamp 3. Apply clamp
4. Escrever no buffer estéreo 4. Write to the stereo buffer
Custo depende de: Cost depends on:
- número de voices ativas - number of active voices
- uso de interpolação - use of interpolation
--- ---
## 10. Sincronização com o Jogo ## 10. Synchronization with the Game
- Jogo roda a **60Hz** - Game runs at **60Hz**
- Áudio gera dados a **48kHz** - Audio generates data at **48kHz**
A cada frame (60Hz): Every frame (60Hz):
- jogo envia comandos: - game sends commands:
- play - play
- stop - stop
- set_volume - set_volume
- set_pan - set_pan
- set_pitch - set_pitch
O áudio aplica esses comandos e continua tocando. The audio applies these commands and continues playing.
--- ---
## 11. Comandos Básicos ## 11. Basic Commands
Exemplos conceituais: Conceptual examples:
``` ```
audio.play(sample, voice, volume, pan, pitch, priority) audio.play(sample, voice, volume, pan, pitch, priority)
@ -263,15 +263,15 @@ audio.isPlaying(voice)
--- ---
## 12. Áudio e CAP ## 12. Audio and CAP
O áudio participa do Execution CAP: Audio participates in the Execution CAP:
- custo de mixagem por frame - mixing cost per frame
- custo por voice ativa - cost per active voice
- custo de comandos - command cost
Exemplo: Example:
``` ```
Frame 1024: Frame 1024:
@ -283,49 +283,49 @@ audio_commands: 6
--- ---
## 13. Boas Práticas ## 13. Best Practices
Recomendado: Recommended:
- reutilizar samples - reuse samples
- limitar voices simultâneas - limit simultaneous voices
- tratar som como evento - treat sound as an event
- separar música e efeitos - separate music and effects
Evitar: Avoid:
- tocar som todo frame - playing sound every frame
- abusar de voices - abusing voices
- samples gigantes para efeitos simples - giant samples for simple effects
--- ---
## 14. Inspiração Histórica ## 14. Historical Inspiration
O modelo PROMETEU se inspira em: The PROMETEU model is inspired by:
- NES: canais fixos - NES: fixed channels
- SNES: sample playback + mixagem - SNES: sample playback + mixing
- CPS2: polifonia confortável - CPS2: comfortable polyphony
- Neo Geo: sample pesado (não copiado integralmente) - Neo Geo: heavy samples (not fully copied)
Mas abstraído para: But abstracted for:
- clareza - clarity
- simplicidade - simplicity
- ensino - teaching
--- ---
## 15. Resumo ## 15. Summary
- Output: PCM16 estéreo @ 48kHz - Output: stereo PCM16 @ 48kHz
- 16 voices - 16 voices
- Samples PCM16 mono - mono PCM16 samples
- Volume, pan, pitch - Volume, pan, pitch
- Interpolação linear - Linear interpolation
- Mixer explícito - Explicit mixer
- Conceito de “CPU de áudio” - "Audio CPU" concept
- Implementação é papel do host - Implementation is the host's role
< [Voltar](chapter-4.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-6.md) > < [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >

View File

@ -1,94 +1,94 @@
< [Voltar](chapter-5.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-7.md) > < [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >
# 🎮 **Periférico INPUT (Sistema de Entrada)** # 🎮 **INPUT Peripheral (Input System)**
## 1. Visão Geral ## 1. Overview
O **Periférico INPUT** é responsável por **coletar e disponibilizar o estado dos controles** ao programa PROMETEU. The **INPUT Peripheral** is responsible for **collecting and providing the state of controls** to the PROMETEU program.
Em PROMETEU: In PROMETEU:
- input é **estado**, não evento implícito - input is **state**, not an implicit event
- input é **amostrado no tempo**, não entregue assíncronamente - input is **sampled over time**, not delivered asynchronously
- input tem **ordem, custo e momento definidos** - input has a **defined order, cost, and moment**
> Botões não “disparam eventos”. > Buttons do not “trigger events”.
Eles mudam de estado. > They change state.
> >
--- ---
## 2. Filosofia do Sistema de Entrada ## 2. Philosophy of the Input System
PROMETEU modela input como hardware clássico: PROMETEU models input like classic hardware:
- o estado dos controles é lido **uma vez por frame** - the state of controls is read **once per frame**
- o programa consulta esse estado durante `UPDATE` - the program queries this state during `UPDATE`
- não existem callbacks assíncronos de input - there are no asynchronous input callbacks
Esse modelo: This model:
- é determinístico - is deterministic
- é simples de entender - is simple to understand
- reflete microcontroladores e consoles clássicos - reflects microcontrollers and classic consoles
--- ---
## 3. Dispositivos de Entrada ## 3. Input Devices
PROMETEU abstrai diferentes dispositivos em uma interface comum. PROMETEU abstracts different devices into a common interface.
Dispositivos típicos: Typical devices:
- controle digital (D-Pad + botões) - digital control (D-Pad + botões)
- teclado (mapeado para botões) - keyboard (mapped to buttons)
- gamepad - gamepad
- toque (mobile, mapeado) - touch (mobile, mapped)
Independentemente da origem, PROMETEU expõe **o mesmo modelo lógico**. Regardless of the origin, PROMETEU exposes **the same logical model**.
--- ---
## 4. Modelo de Estado ## 4. State Model
### 4.1 Estado por Frame ### 4.1 Per-Frame State
Para cada frame, o sistema mantém: For each frame, the system maintains:
- estado atual dos botões - current state of buttons
- estado do frame anterior - state from the previous frame
Isso permite consultar: This allows querying:
- botão pressionado - button pressed
- botão liberado - button released
- botão mantido pressionado - button held down
--- ---
### 4.2 Tipos de Consulta ### 4.2 Query Types
Operações típicas: Typical operations:
``` ```
input.btn(id)// botão está pressionado input.btn(id)// button is pressed
input.btnp(id)// botão foi pressionado neste frame input.btnp(id)// button was pressed this frame
input.btnr(id)// botão foi liberado neste frame input.btnr(id)// button was released this frame
``` ```
Essas funções: These functions:
- são puramente consultivas - are purely advisory
- não alteram estado - do not change state
- têm custo explícito - have an explicit cost
--- ---
## 5. Momento da Amostragem ## 5. Sampling Moment
O estado do input é capturado **no início de cada frame**, antes da fase `UPDATE`. The input state is captured **at the beginning of each frame**, before the `UPDATE` phase.
Fluxo conceitual: Conceptual flow:
``` ```
FRAME N: FRAME N:
@ -99,162 +99,162 @@ AUDIO
SYNC SYNC
``` ```
Durante todo o frame: Throughout the entire frame:
- o estado de input é imutável - the input state is immutable
- chamadas repetidas retornam o mesmo valor - repeated calls return the same value
> Input não muda no meio do frame. > Input does not change in the middle of the frame.
> >
--- ---
## 6. Determinismo e Reprodutibilidade ## 6. Determinism and Reproducibility
O modelo de input PROMETEU garante: The PROMETEU input model guarantees:
- mesma sequência de inputs - same sequence of inputs
- mesmos frames - same frames
- mesmos resultados - same results
Isso permite: This allows:
- reprodução de execuções - execution playback
- replays determinísticos - deterministic replays
- certificação confiável - reliable certification
Input pode ser: Input can be:
- gravado - recorded
- reproduzido - played back
- injetado artificialmente - artificially injected
--- ---
## 7. Input e CAP ## 7. Input and CAP
Operações de input: Input operations:
- consomem poucos ciclos - consume few cycles
- participam do orçamento por frame - participate in the per-frame budget
- aparecem em relatórios de certificação - appear in certification reports
Exemplo: Example:
``` ```
Frame 18231: Frame 18231:
input.btn():12cycles input.btn():12cycles
``` ```
Embora barato, input **não é gratuito**. Although cheap, input **is not free**.
--- ---
## 8. Mapeamento de Botões ## 8. Button Mapping
### 8.1 Identificadores Lógicos ### 8.1 Logical Identifiers
PROMETEU define identificadores lógicos de botões: PROMETEU defines logical button identifiers:
- `UP`, `DOWN`, `LEFT`, `RIGHT` - `UP`, `DOWN`, `LEFT`, `RIGHT`
- `A`, `B`, `X`, `Y` - `A`, `B`, `X`, `Y`
- `START`, `SELECT` - `START`, `SELECT`
O mapeamento físico: The physical mapping:
- depende da plataforma - depends on the platform
- é resolvido fora da VM - is resolved outside the VM
- é transparente ao programa - is transparent to the program
--- ---
### 8.2 Portabilidade ### 8.2 Portability
O mesmo cartucho PROMETEU: The same PROMETEU cartridge:
- roda em teclado - runs on a keyboard
- roda em gamepad - runs on a gamepad
- roda em touch - runs on touch
Sem alteração de código. Without any code changes.
--- ---
## 9. Input Analógico (Opcional) ## 9. Analog Input (Optional)
PROMETEU pode expor eixos analógicos de forma explícita: PROMETEU can expose analog axes explicitly:
``` ```
input.axis(id) input.axis(id)
``` ```
Características: Characteristics:
- valor normalizado (ex.: -1.0 a 1.0) - normalized value (e.g.: -1.0 to 1.0)
- custo explícito - explicit cost
- atualização por frame - per-frame update
Input analógico: Analog input:
- não é obrigatório - is not mandatory
- não substitui input digital - does not replace digital input
- deve ser usado conscientemente - must be used consciously
--- ---
## 10. Boas Práticas de Input ## 10. Input Best Practices
PROMETEU incentiva: PROMETEU encourages:
- tratar input como estado - treating input as state
- consultar input apenas em `UPDATE` - querying input only in `UPDATE`
- separar input de lógica pesada - separating input from heavy logic
- mapear ações, não teclas - mapping actions, not keys
E desencoraja: And discourages:
- lógica dependente de polling excessivo - logic dependent on excessive polling
- leitura de input em DRAW - reading input in DRAW
- acoplamento direto a hardware físico - direct coupling to physical hardware
--- ---
## 11. Relação com Consoles Clássicos ## 11. Relationship with Classic Consoles
O modelo PROMETEU reflete: The PROMETEU model reflects:
- leitura de registradores de input - reading input registers
- polling por frame - per-frame polling
- ausência de eventos assíncronos - absence of asynchronous events
Esse modelo: This model:
- simplifica raciocínio - simplifies reasoning
- aumenta previsibilidade - increases predictability
- facilita debugging - facilitates debugging
--- ---
## 12. Implicações Pedagógicas ## 12. Pedagogical Implications
O Periférico INPUT permite ensinar: The INPUT Peripheral allows teaching:
- diferença entre evento e estado - the difference between event and state
- amostragem temporal - temporal sampling
- determinismo em sistemas interativos - determinism in interactive systems
- sincronização entre input e lógica - synchronization between input and logic
Com feedback claro e reproduzível. With clear and reproducible feedback.
--- ---
## 13. Resumo ## 13. Summary
- input é estado, não evento - input is state, not an event
- amostrado uma vez por frame - sampled once per frame
- imutável durante o frame - immutable during the frame
- consultas têm custo explícito - queries have an explicit cost
- input participa do CAP - input participates in the CAP
- modelo é determinístico - model is deterministic
< [Voltar](chapter-5.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-7.md) > < [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >

View File

@ -1,72 +1,72 @@
< [Voltar](chapter-6.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-8.md) > < [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >
# 🖐️ Periférico TOUCH (Sistema de Entrada via ponteiro absoluto) # 🖐️ TOUCH Peripheral (Absolute Pointer Input System)
## 1. Visão Geral ## 1. Overview
O periférico **TOUCH** fornece ao PROMETEU um **ponteiro absoluto**, baseado em coordenadas de tela, destinado a: The **TOUCH** peripheral provides PROMETEU with an **absolute pointer**, based on screen coordinates, intended for:
- interação com UI - UI interaction
- seleção direta de elementos - direct element selection
- ações contextuais no cenário - contextual actions in the scenery
- mecânicas baseadas em arrasto (drag, slash, trail) - drag-based mechanics (drag, slash, trail)
O TOUCH é um **periférico de primeira classe**, tão válido quanto D-Pad e botões. The TOUCH is a **first-class peripheral**, as valid as D-Pad and buttons.
--- ---
## 2. Princípios de Design ## 2. Design Principles
O TOUCH no PROMETEU segue princípios rígidos: TOUCH in PROMETEU follows strict principles:
- ✅ **Single-touch universal** - ✅ **Universal single-touch**
- ✅ **Determinístico** - ✅ **Deterministic**
- ✅ **Estado por frame** - ✅ **Per-frame state**
- ✅ **Sem gestos** - ✅ **No gestures**
- ✅ **Sem aceleração** - ✅ **No acceleration**
- ✅ **Sem heurística** - ✅ **No heuristics**
- ✅ **Mesmo comportamento em todas as plataformas** - ✅ **Same behavior on all platforms**
> Se um comportamento não pode ser garantido em todas as plataformas, ele não existe no PROMETEU. > If a behavior cannot be guaranteed on all platforms, it does not exist in PROMETEU.
> >
--- ---
## 3. Modelo Conceitual ## 3. Conceptual Model
O PROMETEU expõe **apenas um ponteiro ativo por vez**, independentemente de quantos toques físicos o hardware reconheça. PROMETEU exposes **only one active pointer at a time**, regardless of how many physical touches the hardware recognizes.
- Hardware pode detectar multitouch - Hardware may detect multitouch
- Runtime seleciona **apenas um toque ativo** - Runtime selects **only one active touch**
- A API **nunca expõe multitouch** - The API **never exposes multitouch**
Esse modelo garante: This model guarantees:
- portabilidade total - total portability
- previsibilidade - predictability
- ausência de ambiguidades - absence of ambiguities
--- ---
## 4. Espaço de Coordenadas ## 4. Coordinate Space
- As coordenadas do TOUCH usam **o mesmo espaço do framebuffer** - TOUCH coordinates use **the same space as the framebuffer**
- Resolução: **320×180** - Resolution: **320×180**
- Origem: canto superior esquerdo `(0,0)` - Origin: top-left corner `(0,0)`
- Intervalos: - Ranges:
- `x ∈ [0, 319]` - `x ∈ [0, 319]`
- `y ∈ [0, 179]` - `y ∈ [0, 179]`
O TOUCH é **absoluto**: TOUCH is **absolute**:
> (x, y) representa a posição exata do contato, sem transformação dinâmica. > (x, y) represents the exact position of contact, without dynamic transformation.
> >
--- ---
## 5. API do Periférico TOUCH ## 5. TOUCH Peripheral API
### 5.1 Estrutura Exposta ### 5.1 Exposed Structure
``` ```
TOUCH: TOUCH:
@ -81,182 +81,182 @@ TOUCH:
--- ---
### 5.2 Semântica dos Campos ### 5.2 Field Semantics
- **present** - **present**
- `true` se o periférico TOUCH está disponível - `true` if the TOUCH peripheral is available
- `false` se não houver touch físico (desktop, hardware sem touch) - `false` if there is no physical touch (desktop, hardware without touch)
- **down** - **down**
- `true` enquanto o ponteiro ativo está pressionado - `true` while the active pointer is pressed
- **pressed** - **pressed**
- `true` apenas no frame em que o ponteiro ativo foi capturado - `true` only in the frame where the active pointer was captured
- **released** - **released**
- `true` apenas no frame em que o ponteiro ativo foi liberado - `true` only in the frame where the active pointer was released
- **x, y** - **x, y**
- posição atual do ponteiro ativo - current position of the active pointer
- válidas apenas quando `down == true` - valid only when `down == true`
--- ---
## 6. Política de Seleção do Ponteiro ## 6. Pointer Selection Policy
### *Single Pointer Capture Policy* ### *Single Pointer Capture Policy*
Quando múltiplos toques físicos ocorrem, o PROMETEU aplica a seguinte política: When multiple physical touches occur, PROMETEU applies the following policy:
--- ---
### 6.1 Captura Inicial ### 6.1 Initial Capture
1. Se **nenhum ponteiro está ativo** 1. If **no pointer is active**
2. E ocorre um **novo toque físico** 2. And a **new physical touch** occurs
3. O **primeiro toque detectado** é capturado 3. The **first detected touch** is captured
4. Esse toque se torna o **ponteiro ativo** 4. This touch becomes the **active pointer**
Esse frame gera: This frame generates:
- `pressed = true` - `pressed = true`
- `down = true` - `down = true`
--- ---
### 6.2 Manutenção da Captura ### 6.2 Capture Maintenance
Enquanto o ponteiro ativo estiver pressionado: While the active pointer is pressed:
- Apenas ele é rastreado - Only it is tracked
- Todos os outros toques físicos são ignorados - All other physical touches are ignored
- `x, y` seguem apenas o ponteiro ativo - `x, y` follow only the active pointer
--- ---
### 6.3 Liberação ### 6.3 Release
Quando o ponteiro ativo é solto: When the active pointer is released:
- `released = true` - `released = true`
- `down = false` - `down = false`
- O sistema entra em estado **sem ponteiro ativo** - The system enters a **no active pointer** state
--- ---
### 6.4 Recaptura (Regra Importante) ### 6.4 Recapture (Important Rule)
Após a liberação: After release:
- Toques que **já estavam presentes** são ignorados - Touches that **were already present** are ignored
- Um novo ponteiro só é capturado com um **novo evento de toque** - A new pointer is only captured with a **new touch event**
> Isso evita saltos inesperados do ponteiro e ações acidentais. > This avoids unexpected pointer jumps and accidental actions.
> >
--- ---
## 7. Comportamentos Deliberadamente NÃO Suportados ## 7. Deliberately NOT Supported Behaviors
O periférico TOUCH **não implementa**: The TOUCH peripheral **does not implement**:
❌ Multitouch ❌ Multitouch
❌ Gestos (swipe, pinch, rotate, long-press) ❌ Gestures (swipe, pinch, rotate, long-press)
❌ Aceleração ou suavização ❌ Acceleration or smoothing
Sensibilidade dinâmica Dynamic sensitivity
Histórico implícito Implicit history
❌ Interpretação de intenção ❌ Intent interpretation
Se um jogo quiser qualquer um desses comportamentos, ele deve: If a game wants any of these behaviors, it must:
- implementar explicitamente - implement them explicitly
- usando apenas estado por frame - using only per-frame state
- sem suporte implícito do hardware - without implicit hardware support
--- ---
## 8. “Sem Gesto” — Definição Formal ## 8. “No Gesture” — Formal Definition
O PROMETEU **não interpreta padrões temporais**. PROMETEU **does not interpret temporal patterns**.
O periférico TOUCH **não classifica ações** como: The TOUCH peripheral **does not classify actions** as:
- swipe - swipe
- drag - drag
- long press - long press
- double tap - double tap
Ele apenas informa: It only reports:
- posição atual - current position
- estado do contato - contact state
Toda semântica é responsabilidade do jogo. All semantics are the game's responsibility.
--- ---
## 9. “Sem Aceleração” — Definição Formal ## 9. “No Acceleration” — Formal Definition
O PROMETEU **não modifica** o input do TOUCH. PROMETEU **does not modify** the TOUCH input.
- Nenhuma curva de sensibilidade - No sensitivity curves
- Nenhuma amplificação por velocidade - No speed-based amplification
- Nenhuma suavização - No smoothing
A relação entre o toque físico e `(x, y)` é **1:1** após normalização. The relationship between the physical touch and `(x, y)` is **1:1** after normalization.
--- ---
## 10. Integração com Outras Formas de Input ## 10. Integration with Other Input Forms
- Desktop: - Desktop:
- mouse pode emular TOUCH - mouse can emulate TOUCH
- Mobile: - Mobile:
- touch físico direto - direct physical touch
- Steam Deck: - Steam Deck:
- touchscreen físico - physical touchscreen
- Hardware PROMETEU: - PROMETEU Hardware:
- touch opcional, mas suportado - optional touch, but supported
Do ponto de vista do PROMETEU: From PROMETEU's point of view:
> TOUCH é sempre TOUCH. > TOUCH is always TOUCH.
> >
--- ---
## 11. Usos Esperados ## 11. Expected Uses
O periférico TOUCH é adequado para: The TOUCH peripheral is suitable for:
- UI (menus, inventário, mapas) - UI (menus, inventory, maps)
- drag-and-drop - drag-and-drop
- seleção direta - direct selection
- “clicar para investigar - “click to investigate
- puzzles baseados em apontamento - pointing-based puzzles
- mecânicas de rastro (ex.: Fruit Ninja-like) - trail mechanics (e.g.: Fruit Ninja-like)
--- ---
## 12. Garantias de Portabilidade ## 12. Portability Guarantees
Todo jogo PROMETEU que utiliza TOUCH: Every PROMETEU game that uses TOUCH:
- comporta-se de forma idêntica em todas as plataformas - behaves identically on all platforms
- não depende de capacidades específicas do host - does not depend on host-specific capabilities
- não sofre variação semântica entre desktop, mobile e hardware dedicado - does not suffer semantic variation between desktop, mobile, and dedicated hardware
--- ---
## 13. Resumo ## 13. Summary
O TOUCH no PROMETEU é: The TOUCH in PROMETEU is:
- simples - simple
- explícito - explicit
- previsível - predictable
- universal - universal
- determinístico - deterministic
< [Voltar](chapter-6.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-8.md) > < [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >

View File

@ -1,80 +1,80 @@
< [Voltar](chapter-7.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-9.md) > < [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >
# 📀 Periférico MEMCARD (Sistema de save/load) # 📀 MEMCARD Peripheral (Save/Load System)
## 1. Visão Geral ## 1. Overview
O **MEMCARD** é o periférico responsável pela **persistência explícita de dados do jogo** no PROMETEU. The **MEMCARD** is the peripheral responsible for the **explicit persistence of game data** in PROMETEU.
Ele simula o comportamento de *memory cards* clássicos (PS1, GameCube), fornecendo: It simulates the behavior of classic *memory cards* (PS1, GameCube), providing:
- armazenamento limitado - limited storage
- custo explícito de I/O - explicit I/O cost
- controle total do jogo sobre quando salvar - full game control over when to save
- portabilidade entre plataformas - portability across platforms
O MEMCARD **não é um save state**. The MEMCARD **is not a save state**.
Ele representa **dados que o próprio jogo decide persistir**. It represents **data that the game itself decides to persist**.
--- ---
## 2. Princípios de Design ## 2. Design Principles
O periférico MEMCARD segue os seguintes princípios: The MEMCARD peripheral follows these principles:
- ✅ **Persistência explícita** (nada automático) - ✅ **Explicit persistence** (nothing automatic)
- ✅ **Tamanho limitado e conhecido** - ✅ **Limited and known size**
- ✅ **Commit obrigatório** - ✅ **Mandatory commit**
- ✅ **Custo de tempo (ciclos) mensurável** - ✅ **Measurable time cost (cycles)**
- ✅ **Formato estável e documentado** - ✅ **Stable and documented format**
- ✅ **Independente de plataforma** - ✅ **Platform independent**
- ❌ Sem sistema de arquivos complexo (no v0.1) - ❌ No complex file system (in v0.1)
- ❌ Sem múltiplos arquivos internos (no v0.1) - ❌ No multiple internal files (in v0.1)
--- ---
## 3. Modelo Conceitual ## 3. Conceptual Model
Cada cartucho PROMETEU pode acessar **um ou mais slots de MEMCARD**, sendo o modelo padrão: Each PROMETEU cartridge can access **one or more MEMCARD slots**, the default model being:
- **Slot A**principal - **Slot A**main
- **Slot B** — opcional (futuro) - **Slot B** — optional (future)
Cada slot corresponde a **um arquivo no host**: Each slot corresponds to **a file on the host**:
``` ```
MyGame_A.mem MyGame_A.mem
MyGame_B.mem MyGame_B.mem
``` ```
O runtime monta esse arquivo como um **dispositivo de armazenamento persistente**. The runtime mounts this file as a **persistent storage device**.
--- ---
## 4. Capacidade e CAP ## 4. Capacity and CAP
O tamanho do MEMCARD é **fixo**, definido pelo perfil de execução (CAP). The size of the MEMCARD is **fixed**, defined by the execution profile (CAP).
### Tamanhos sugeridos ### Suggested sizes
| Perfil | Tamanho | | Profile | Size |
| --- | --- | | --- | --- |
| JAM | 8 KB | | JAM | 8 KB |
| STANDARD | 32 KB | | STANDARD | 32 KB |
| ADVANCED | 128 KB | | ADVANCED | 128 KB |
O jogo **não pode exceder** esse tamanho. The game **cannot exceed** this size.
Tentativas de escrita acima do limite resultam em erro. Attempts to write above the limit result in an error.
--- ---
## 5. API do Periférico (v0.1) ## 5. Peripheral API (v0.1)
### 5.1 Interface Lógica ### 5.1 Logical Interface
O MEMCARD expõe uma API **simples de blob único**: The MEMCARD exposes a **simple single-blob API**:
``` ```
mem.read_all() -> byte[] mem.read_all() -> byte[]
@ -86,92 +86,92 @@ mem.size() -> int
--- ---
### 5.2 Semântica das Operações ### 5.2 Operation Semantics
### `read_all()` ### `read_all()`
- Retorna todo o conteúdo persistido - Returns all persisted content
- Se o cartão estiver vazio, retorna um buffer zerado - If the card is empty, returns a zeroed buffer
- Custo em ciclos proporcional ao tamanho - Cycle cost proportional to size
--- ---
### `write_all(bytes)` ### `write_all(bytes)`
- Escreve o buffer **em memória temporária** - Writes the buffer **to temporary memory**
- Não persiste imediatamente - Does not persist immediately
- Falha se `bytes.length > mem.size()` - Fails if `bytes.length > mem.size()`
--- ---
### `commit()` ### `commit()`
- Persiste os dados no dispositivo - Persists data to the device
- Operação **obrigatória** - **Mandatory** operation
- Simula flush de hardware - Simulates hardware flush
- Pode falhar (ex.: I/O, corrupção simulada) - May fail (e.g., I/O, simulated corruption)
--- ---
### `clear()` ### `clear()`
- Zera o conteúdo do cartão - Zeroes the card content
- Requer `commit()` para persistir - Requires `commit()` to persist
--- ---
### `size()` ### `size()`
- Retorna a capacidade total do cartão em bytes - Returns total card capacity in bytes
--- ---
## 6. Commit Explícito (Regra Fundamental) ## 6. Explicit Commit (Fundamental Rule)
O PROMETEU **não salva automaticamente**. PROMETEU **does not save automatically**.
Sem `commit()`: Without `commit()`:
- dados permanecem voláteis - data remains volatile
- podem ser perdidos ao encerrar o jogo - can be lost upon exiting the game
- simulam desligamento abrupto de hardware - simulates abrupt hardware shutdown
👉 Isso ensina: 👉 This teaches:
- flush de dados - data flushing
- atomicidade - atomicity
- risco de corrupção - risk of corruption
- custo real de persistência - real cost of persistence
--- ---
## 7. Custo de Execução (Ciclos) ## 7. Execution Cost (Cycles)
Todas as operações de MEMCARD têm custo explícito. All MEMCARD operations have an explicit cost.
### Exemplo (valores ilustrativos) ### Example (illustrative values)
| Operação | Custo | | Operation | Cost |
| --- | --- | | --- | --- |
| read_all | 1 ciclo / 256 bytes | | read_all | 1 cycle / 256 bytes |
| write_all | 1 ciclo / 256 bytes | | write_all | 1 cycle / 256 bytes |
| commit | custo fixo + proporcional | | commit | fixed + proportional cost |
Esses custos aparecem: These costs appear:
- no profiler - in the profiler
- na timeline de frame - in the frame timeline
- no relatório de CAP - in the CAP report
--- ---
## 8. Formato do Arquivo `.mem` ## 8. `.mem` File Format
O arquivo de MEMCARD possui um formato simples e robusto. The MEMCARD file has a simple and robust format.
### 8.1 Header ### 8.1 Header
| Campo | Tamanho | | Field | Size |
| --- | --- | | --- | --- |
| Magic (`PMEM`) | 4 bytes | | Magic (`PMEM`) | 4 bytes |
| Version | 1 byte | | Version | 1 byte |
@ -183,56 +183,56 @@ O arquivo de MEMCARD possui um formato simples e robusto.
### 8.2 Payload ### 8.2 Payload
- Buffer binário definido pelo jogo - Binary buffer defined by the game
- Tamanho fixo - Fixed size
- Conteúdo interpretado apenas pelo jogo - Content interpreted only by the game
--- ---
## 9. Integridade e Segurança ## 9. Integrity and Security
- CRC valida corrupção - CRC validates corruption
- Cart ID impede uso de save errado - Cart ID prevents using wrong save
- Versão permite evolução futura do formato - Version allows future format evolution
- Runtime pode: - Runtime can:
- avisar corrupção - warn of corruption
- permitir reset do cartão - allow card reset
--- ---
## 10. Integração com o Editor / GUI ## 10. Integration with the Editor / GUI
A ferramenta principal pode fornecer um **Memory Card Manager**: The main tool can provide a **Memory Card Manager**:
- criar/resetar cartão - create/reset card
- ver tamanho e uso - see size and usage
- importar/exportar `.mem` - import/export `.mem`
- visualizar últimos commits - visualize last commits
- associar cartões a projetos - associate cards with projects
Nenhuma dessas operações altera o runtime. None of these operations change the runtime.
--- ---
## 11. Evoluções Planejadas (fora do v0.1) ## 11. Planned Evolutions (outside v0.1)
- API de blocos (`read_block`, `write_block`) - Block API (`read_block`, `write_block`)
- múltiplos slots internos - multiple internal slots
- wear simulation - wear simulation
- versionamento de saves - save versioning
- criptografia opcional (educacional) - optional encryption (educational)
--- ---
## 12. Resumo ## 12. Summary
O periférico MEMCARD no PROMETEU: The MEMCARD peripheral in PROMETEU:
- simula hardware real - simulates real hardware
- força decisões de design - forces design decisions
- ensina persistência corretamente - teaches persistence correctly
- é simples de usar - is simple to use
- é difícil de abusar - is hard to abuse
- cresce sem quebrar compatibilidade - grows without breaking compatibility
< [Voltar](chapter-7.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-9.md) > < [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >

View File

@ -1,175 +1,175 @@
< [Voltar](chapter-8.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-10.md) > < [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >
# ⚡ **Eventos e Interrupções** # ⚡ **Events and Interrupts**
## 1. Visão Geral ## 1. Overview
PROMETEU distingue claramente **execução normal**, **eventos** e **interrupções**. PROMETEU clearly distinguishes between **normal execution**, **events**, and **interrupts**.
Nada ocorre “fora do tempo”. Nothing occurs "out of time".
Nada interrompe o sistema sem custo. Nothing interrupts the system without cost.
Nada acontece sem um ponto bem definido no ciclo de execução. Nothing happens without a well-defined point in the execution cycle.
> Eventos são sinais. > Events are signals.
Interrupções são decisões da máquina. > Interrupts are machine decisions.
> >
Este capítulo define: This chapter defines:
- o que PROMETEU considera um evento - what PROMETEU considers an event
- como interrupções são modeladas - how interrupts are modeled
- quando elas podem ocorrer - when they can occur
- como se relacionam com ciclos, CAP e determinismo - how they relate to cycles, CAP, and determinism
--- ---
## 2. Filosofia de Eventos em PROMETEU ## 2. Event Philosophy in PROMETEU
PROMETEU **não utiliza callbacks assíncronos invisíveis**. PROMETEU **does not use invisible asynchronous callbacks**.
Todo evento: Every event:
- é registrado - is registered
- é entregue em momento previsível - is delivered at a predictable moment
- é tratado dentro do loop principal - is handled within the main loop
Esse modelo evita: This model avoids:
- concorrência implícita - implicit concurrency
- race conditions ocultas - hidden race conditions
- efeitos colaterais não determinísticos - non-deterministic side effects
PROMETEU favorece: PROMETEU favors:
> controle explícito sobre reatividade. > explicit control over reactivity.
> >
--- ---
## 3. Eventos ## 3. Events
### 3.1 Definição ### 3.1 Definition
Um **evento** em PROMETEU é um **sinal lógico** gerado pelo sistema ou pelo programa, que indica que algo ocorreu. An **event** in PROMETEU is a **logical signal** generated by the system or the program, indicating that something has occurred.
Exemplos de eventos: Examples of events:
- fim de frame - end of frame
- timer expirado - timer expired
- troca de estado do sistema - system state change
- erro de execução - execution error
Eventos **não executam código automaticamente**. Events **do not execute code automatically**.
Eles apenas **informam**. They only **inform**.
--- ---
### 3.2 Fila de Eventos ### 3.2 Event Queue
PROMETEU mantém uma **fila de eventos**: PROMETEU maintains an **event queue**:
- eventos são enfileirados - events are queued
- a fila é processada em ordem - the queue is processed in order
- o processamento ocorre em pontos definidos do frame - processing occurs at defined points in the frame
Eventos: Events:
- não interrompem execução arbitrariamente - do not interrupt execution arbitrarily
- não executam fora do loop - do not execute outside the loop
--- ---
## 4. Interrupções ## 4. Interrupts
### 4.1 Definição ### 4.1 Definition
Uma **interrupção** é um evento especial, tratado pelo sistema como **prioritário**, que pode: An **interrupt** is a special event, treated by the system as **priority**, which can:
- alterar o fluxo normal de execução - change the normal flow of execution
- executar código específico do sistema - execute specific system code
- impactar ciclos e orçamento - impact cycles and budget
Interrupções são **raras e explícitas**. Interrupts are **rare and explicit**.
--- ---
### 4.2 O que NÃO é uma interrupção ### 4.2 What is NOT an interrupt
Em PROMETEU, **não são interrupções**: In PROMETEU, the following are **not interrupts**:
- input de botão - button input
- colisões - collisions
- timers comuns - common timers
- lógica de jogo - game logic
Esses são tratados como **estado ou eventos normais**. These are treated as **state or normal events**.
--- ---
## 5. Tipos de Interrupções em PROMETEU ## 5. Types of Interrupts in PROMETEU
PROMETEU define um conjunto pequeno e bem controlado de interrupções. PROMETEU defines a small and well-controlled set of interrupts.
### 5.1 Interrupção de Frame (VBlank Conceitual) ### 5.1 Frame Interrupt (Conceptual VBlank)
O final de cada frame gera uma **interrupção lógica de sincronização**, responsável por: The end of each frame generates a **logical synchronization interrupt**, responsible for:
- swap de framebuffer - framebuffer swap
- commit de áudio - audio commit
- sincronização de estado - state synchronization
Essa interrupção: This interrupt:
- ocorre no SYNC - occurs at SYNC
- tem custo fixo - has a fixed cost
- não executa código do usuário - does not execute user code
--- ---
### 5.2 Interrupção de Sistema ### 5.2 System Interrupt
Gerada por condições excepcionais: Generated by exceptional conditions:
- erro fatal de VM - fatal VM error
- violação de memória - memory violation
- instrução inválida - invalid instruction
Resultado: Result:
- execução é interrompida - execution is halted
- estado da VM é preservado - VM state is preserved
- relatório detalhado é gerado - detailed report is generated
--- ---
### 5.3 Interrupções Temporizadas (Timers) ### 5.3 Timed Interrupts (Timers)
PROMETEU pode oferecer **timers do sistema**, modelados como: PROMETEU can offer **system timers**, modeled as:
- contadores baseados em frames - counters based on frames
- sinais gerados ao atingir zero - signals generated upon reaching zero
Timers: Timers:
- não disparam código automaticamente - do not trigger code automatically
- geram eventos consultáveis - generate queryable events
Exemplo conceitual: Conceptual example:
``` ```
if (timer.expired(T1)) { if (timer.expired(T1)) {
// tratar evento // handle event
} }
``` ```
--- ---
## 6. Relação entre Eventos, Interrupções e o Loop ## 6. Relationship between Events, Interrupts, and the Loop
O fluxo completo pode ser representado assim: The complete flow can be represented as follows:
``` ```
FRAME N FRAME N
@ -184,23 +184,23 @@ SYNC
────────────── ──────────────
``` ```
Importante: Important:
- eventos são processados antes da lógica principal - events are processed before main logic
- interrupções ocorrem apenas em pontos seguros - interrupts occur only at safe points
- nenhuma interrupção ocorre “no meio” de uma instrução - no interrupt occurs "in the middle" of an instruction
--- ---
## 7. Custos e Orçamento ## 7. Costs and Budget
Eventos e interrupções: Events and interrupts:
- consomem ciclos - consume cycles
- participam do CAP - participate in the CAP
- aparecem na certificação - appear in certification
Exemplo de relatório: Example report:
``` ```
Frame 18231: Frame 18231:
@ -208,82 +208,82 @@ Event processing:120cycles
VBlank interrupt:80cycles VBlank interrupt:80cycles
``` ```
Nada é gratuito. Nothing is free.
--- ---
## 8. Determinismo e Reprodutibilidade ## 8. Determinism and Reproducibility
PROMETEU garante: PROMETEU guarantees:
- mesma sequência de eventos → mesmo comportamento - same sequence of events → same behavior
- interrupções sempre no mesmo ponto do frame - interrupts always at the same point in the frame
- timers baseados em frame count, não em tempo real - timers based on frame count, not real time
Isso permite: This allows:
- replays confiáveis - reliable replays
- debugging preciso - precise debugging
- certificação justa - fair certification
--- ---
## 9. Boas Práticas ## 9. Best Practices
PROMETEU incentiva: PROMETEU encourages:
- tratar eventos como dados - treating events as data
- consultar eventos explicitamente - querying events explicitly
- evitar lógica pesada em handlers - avoiding heavy logic in handlers
- usar timers em vez de polling excessivo - using timers instead of excessive polling
PROMETEU desencoraja: PROMETEU discourages:
- simular callbacks assíncronos - simulating asynchronous callbacks
- depender de ordem implícita - depending on implicit order
- usar eventos como “atalho” para lógica complexa - using events as a "shortcut" for complex logic
--- ---
## 10. Relação com Microcontroladores ## 10. Relationship with Microcontrollers
O modelo reflete MCUs reais: The model reflects real MCUs:
| MCU | PROMETEU | | MCU | PROMETEU |
| --- | --- | | --- | --- |
| ISR | Interrupção explícita | | ISR | Explicit interrupt |
| Loop principal | Loop PROMETEU | | Main Loop | PROMETEU Loop |
| Flags | Eventos | | Flags | Events |
| Timers | Timers por frame | | Timers | Per-frame timers |
Mas sem: But without:
- concorrência real - real concurrency
- interrupções imprevisíveis - unpredictable interrupts
PROMETEU **ensina o conceito**, não o caos. PROMETEU **teaches the concept**, not the chaos.
--- ---
## 11. Implicações Pedagógicas ## 11. Pedagogical Implications
Este modelo permite ensinar: This model allows teaching:
- diferença entre evento e interrupção - the difference between event and interrupt
- sincronização segura - safe synchronization
- controle de fluxo em sistemas reativos - flow control in reactive systems
- impacto de decisões temporais - the impact of temporal decisions
Tudo com **ordem, clareza e mensuração**. Everything with **order, clarity, and measurement**.
--- ---
## 12. Resumo ## 12. Summary
- eventos informam, não executam - events inform, they do not execute
- interrupções são raras e controladas - interrupts are rare and controlled
- nenhuma execução ocorre fora do loop - no execution occurs outside the loop
- custos são explícitos - costs are explicit
- comportamento é determinístico - behavior is deterministic
< [Voltar](chapter-8.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-10.md) > < [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >

View File

@ -1,19 +1,19 @@
# Table of Contents # Table of Contents
- [Capitulo 1: Modelo de Tempo e Ciclos](chapter-1.md) - [Chapter 1: Time Model and Cycles](chapter-1.md)
- [Capitulo 2: PROMETEU VM Instruction Set](chapter-2.md) - [Chapter 2: PROMETEU VM Instruction Set](chapter-2.md)
- [Capitulo 3: Memória: Stack, Heap e Alocação](chapter-3.md) - [Chapter 3: Memory: Stack, Heap, and Allocation](chapter-3.md)
- [Capitulo 4: Periférico GFX (Sistema Gráfico)](chapter-4.md) - [Chapter 4: GFX Peripheral (Graphics System)](chapter-4.md)
- [Capitulo 5: Periférico AUDIO (Sistema de Áudio)](chapter-5.md) - [Chapter 5: AUDIO Peripheral (Audio System)](chapter-5.md)
- [Capitulo 6: Periférico INPUT (Sistema de Entrada)](chapter-6.md) - [Chapter 6: INPUT Peripheral (Input System)](chapter-6.md)
- [Capitulo 7: Periférico TOUCH (Sistema de Entrada via ponteiro absoluto)](chapter-7.md) - [Chapter 7: TOUCH Peripheral (Absolute Pointer Input System)](chapter-7.md)
- [Capitulo 8: Periférico MEMCARD (Sistema de save/load)](chapter-8.md) - [Chapter 8: MEMCARD Peripheral (Save/Load System)](chapter-8.md)
- [Capitulo 9: Eventos e Interrupções](chapter-9.md) - [Chapter 9: Events and Interrupts](chapter-9.md)
- [Capitulo 10: Debug, Inspeção e Profiling](chapter-10.md) - [Chapter 10: Debug, Inspection, and Profiling](chapter-10.md)
- [Capitulo 11: Garantias de Portabilidade e Execução Multiplataforma](chapter-11.md) - [Chapter 11: Portability Guarantees and Cross-Platform Execution](chapter-11.md)
- [Capitulo 12: Firmware — PrometeuOS (POS) + PrometeuHub](chapter-12.md) - [Chapter 12: Firmware — PrometeuOS (POS) + PrometeuHub](chapter-12.md)
- [Capitulo 13: Cartucho](chapter-13.md) - [Chapter 13: Cartridge](chapter-13.md)
- [Capitulo 14: Boot Profiles](chapter-14.md) - [Chapter 14: Boot Profiles](chapter-14.md)
--- ---
[Voltar para o README](../README.md) [Back to README](../README.md)

View File

@ -1,26 +1,26 @@
# PROMETEU Test Cartridges # PROMETEU Test Cartridges
Este diretório contém cartuchos de exemplo e suítes de teste para validar o comportamento do runtime e das ferramentas de desenvolvimento do PROMETEU. This directory contains example cartridges and test suites to validate the behavior of the PROMETEU runtime and development tools.
## Cartuchos Disponíveis ## Available Cartridges
### 🟩 [color-square](./color-square) ### 🟩 [color-square](./color-square)
Um cartucho simples que demonstra: A simple cartridge that demonstrates:
- Inicialização do sistema. - System initialization.
- Renderização de um quadrado colorido no framebuffer. - Rendering a colored square in the framebuffer.
- Loop básico de execução. - Basic execution loop.
## Estrutura de um Cartucho ## Cartridge Structure
Um cartucho PROMETEU (em sua forma descompactada) geralmente consiste em: A PROMETEU cartridge (in its unpacked form) generally consists of:
- `manifest.json`: Metadados do aplicativo (ID, título, versão, modo). - `manifest.json`: Application metadata (ID, title, version, mode).
- `program.pbc`: O bytecode compilado para a VM do PROMETEU. - `program.pbc`: Compiled bytecode for the PROMETEU VM.
- `assets/`: Recursos como tiles, sprites e amostras de áudio. - `assets/`: Resources such as tiles, sprites, and audio samples.
## Como usar ## How to use
Você pode rodar qualquer um destes cartuchos usando a CLI principal: You can run any of these cartridges using the main CLI:
```bash ```bash
prometeu run test-cartridges/<nome_do_cartucho> prometeu run test-cartridges/<cartridge_name>
``` ```