organized syscall maps

This commit is contained in:
Nilton Constantino 2026-01-20 11:45:46 +00:00
parent 313480fec4
commit 1883ce8e37
No known key found for this signature in database
9 changed files with 175 additions and 41 deletions

1
Cargo.lock generated
View File

@ -1919,6 +1919,7 @@ dependencies = [
"oxc_parser",
"oxc_span",
"prometeu-bytecode",
"prometeu-core",
"serde",
"serde_json",
]

View File

@ -6,7 +6,7 @@ pub mod firmware;
pub mod fs;
pub mod telemetry;
pub mod debugger_protocol;
mod prometeu_os;
pub mod prometeu_os;
mod prometeu_hub;
pub use hardware::hardware::Hardware;

View File

@ -1,3 +1,20 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum ButtonId {
Up = 0,
Down = 1,
Left = 2,
Right = 3,
A = 4,
B = 5,
X = 6,
Y = 7,
L = 8,
R = 9,
Start = 10,
Select = 11,
}
#[derive(Default, Clone, Copy, Debug)]
pub struct Button {
pub pressed: bool,

View File

@ -9,7 +9,7 @@ mod cartridge;
mod cartridge_loader;
mod window;
pub use button::Button;
pub use button::{Button, ButtonId};
pub use cartridge::{AppMode, Cartridge, CartridgeDTO, CartridgeError};
pub use cartridge_loader::{CartridgeLoader, DirectoryCartridgeLoader, PackedCartridgeLoader};
pub use color::Color;

View File

@ -1,4 +1,6 @@
mod prometeu_os;
pub mod syscalls;
pub use prometeu_os::PrometeuOS;
pub use syscalls::Syscall;
pub use crate::virtual_machine::native_interface::NativeInterface;

View File

@ -2,7 +2,7 @@ use crate::fs::{FsBackend, FsState, VirtualFS};
use crate::hardware::{HardwareBridge, InputSignals};
use crate::log::{LogLevel, LogService, LogSource};
use crate::model::{Cartridge, Color, Sample};
use crate::prometeu_os::NativeInterface;
use crate::prometeu_os::{NativeInterface, Syscall};
use crate::telemetry::{CertificationConfig, Certifier, TelemetryFrame};
use crate::virtual_machine::{Value, VirtualMachine};
use std::collections::HashMap;
@ -554,17 +554,18 @@ impl NativeInterface for PrometeuOS {
/// Each syscall returns the number of virtual cycles it consumed.
fn syscall(&mut self, id: u32, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Result<u64, String> {
self.telemetry_current.syscalls += 1;
match id {
let syscall = Syscall::from_u32(id).ok_or_else(|| format!("Unknown syscall: 0x{:08X}", id))?;
match syscall {
// --- System Syscalls ---
// system.has_cart() -> bool
0x0001 => {
Syscall::SystemHasCart => {
// Returns true if a cartridge is available.
vm.push(Value::Boolean(true)); // For now, assume true or check state
Ok(10)
}
// system.run_cart() -> null
0x0002 => {
Syscall::SystemRunCart => {
// Triggers loading and execution of the current cartridge.
vm.push(Value::Null);
Ok(100)
@ -573,7 +574,7 @@ impl NativeInterface for PrometeuOS {
// --- GFX Syscalls ---
// gfx.clear(color_index) -> null
0x1001 => {
Syscall::GfxClear => {
let color_idx = vm.pop_integer()? as usize;
let color = self.get_color(color_idx, hw);
hw.gfx_mut().clear(color);
@ -581,7 +582,7 @@ impl NativeInterface for PrometeuOS {
Ok(100)
}
// gfx.draw_rect(x, y, w, h, color_index) -> null
0x1002 => {
Syscall::GfxFillRect => {
let color_idx = vm.pop_integer()? as usize;
let h = vm.pop_integer()? as i32;
let w = vm.pop_integer()? as i32;
@ -593,7 +594,7 @@ impl NativeInterface for PrometeuOS {
Ok(200)
}
// gfx.draw_line(x1, y1, x2, y2, color_index) -> null
0x1003 => {
Syscall::GfxDrawLine => {
let color_idx = vm.pop_integer()? as usize;
let y2 = vm.pop_integer()? as i32;
let x2 = vm.pop_integer()? as i32;
@ -605,7 +606,7 @@ impl NativeInterface for PrometeuOS {
Ok(200)
}
// gfx.draw_circle(x, y, r, color_index) -> null
0x1004 => {
Syscall::GfxDrawCircle => {
let color_idx = vm.pop_integer()? as usize;
let r = vm.pop_integer()? as i32;
let y = vm.pop_integer()? as i32;
@ -616,7 +617,7 @@ impl NativeInterface for PrometeuOS {
Ok(200)
}
// gfx.draw_disc(x, y, r, border_color_idx, fill_color_idx) -> null
0x1005 => {
Syscall::GfxDrawDisc => {
let fill_color_idx = vm.pop_integer()? as usize;
let border_color_idx = vm.pop_integer()? as usize;
let r = vm.pop_integer()? as i32;
@ -629,7 +630,7 @@ impl NativeInterface for PrometeuOS {
Ok(300)
}
// gfx.draw_square(x, y, w, h, border_color_idx, fill_color_idx) -> null
0x1006 => {
Syscall::GfxDrawSquare => {
let fill_color_idx = vm.pop_integer()? as usize;
let border_color_idx = vm.pop_integer()? as usize;
let h = vm.pop_integer()? as i32;
@ -646,7 +647,7 @@ impl NativeInterface for PrometeuOS {
// --- Input Syscalls ---
// input.get_pad(button_id) -> bool
0x2001 => {
Syscall::InputGetPad => {
let button_id = vm.pop_integer()? as u32;
let is_down = self.is_button_down(button_id, hw);
vm.push(Value::Boolean(is_down));
@ -656,7 +657,7 @@ impl NativeInterface for PrometeuOS {
// --- Audio Syscalls ---
// audio.play_sample(sample_id, voice_id, volume, pan, pitch)
0x3001 => {
Syscall::AudioPlaySample => {
let pitch = vm.pop_number()?;
let pan = vm.pop_integer()? as u8;
let volume = vm.pop_integer()? as u8;
@ -681,7 +682,7 @@ impl NativeInterface for PrometeuOS {
// FS_OPEN(path) -> handle
// Opens a file in the virtual sandbox and returns a numeric handle.
0x4001 => {
Syscall::FsOpen => {
let path = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string path".into()),
@ -697,7 +698,7 @@ impl NativeInterface for PrometeuOS {
Ok(200)
}
// FS_READ(handle) -> content
0x4002 => {
Syscall::FsRead => {
let handle = vm.pop_integer()? as u32;
let path = self.open_files.get(&handle).ok_or("Invalid handle")?;
match self.fs.read_file(path) {
@ -713,7 +714,7 @@ impl NativeInterface for PrometeuOS {
}
}
// FS_WRITE(handle, content)
0x4003 => {
Syscall::FsWrite => {
let content = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string content".into()),
@ -732,14 +733,14 @@ impl NativeInterface for PrometeuOS {
}
}
// FS_CLOSE(handle)
0x4004 => {
Syscall::FsClose => {
let handle = vm.pop_integer()? as u32;
self.open_files.remove(&handle);
vm.push(Value::Null);
Ok(100)
}
// FS_LISTDIR(path)
0x4005 => {
Syscall::FsListDir => {
let path = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string path".into()),
@ -758,7 +759,7 @@ impl NativeInterface for PrometeuOS {
}
}
// FS_EXISTS(path) -> bool
0x4006 => {
Syscall::FsExists => {
let path = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string path".into()),
@ -767,7 +768,7 @@ impl NativeInterface for PrometeuOS {
Ok(100)
}
// FS_DELETE(path)
0x4007 => {
Syscall::FsDelete => {
let path = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string path".into()),
@ -782,7 +783,7 @@ impl NativeInterface for PrometeuOS {
// --- Log Syscalls (0x5000) ---
// LOG_WRITE(level, msg)
0x5001 => {
Syscall::LogWrite => {
let msg = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string message".into()),
@ -791,7 +792,7 @@ impl NativeInterface for PrometeuOS {
self.syscall_log_write(vm, level, 0, msg)
}
// LOG_WRITE_TAG(level, tag, msg)
0x5002 => {
Syscall::LogWriteTag => {
let msg = match vm.pop()? {
Value::String(s) => s,
_ => return Err("Expected string message".into()),
@ -800,8 +801,6 @@ impl NativeInterface for PrometeuOS {
let level = vm.pop_integer()?;
self.syscall_log_write(vm, level, tag, msg)
}
_ => Err(format!("Unknown syscall: 0x{:08X}", id)),
}
}
}

View File

@ -0,0 +1,110 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Syscall {
// System
SystemHasCart = 0x0001,
SystemRunCart = 0x0002,
// GFX
GfxClear = 0x1001,
GfxFillRect = 0x1002,
GfxDrawLine = 0x1003,
GfxDrawCircle = 0x1004,
GfxDrawDisc = 0x1005,
GfxDrawSquare = 0x1006,
// Input
InputGetPad = 0x2001,
// Audio
AudioPlaySample = 0x3001,
// FS
FsOpen = 0x4001,
FsRead = 0x4002,
FsWrite = 0x4003,
FsClose = 0x4004,
FsListDir = 0x4005,
FsExists = 0x4006,
FsDelete = 0x4007,
// Log
LogWrite = 0x5001,
LogWriteTag = 0x5002,
}
impl Syscall {
pub fn from_u32(id: u32) -> Option<Self> {
match id {
0x0001 => Some(Self::SystemHasCart),
0x0002 => Some(Self::SystemRunCart),
0x1001 => Some(Self::GfxClear),
0x1002 => Some(Self::GfxFillRect),
0x1003 => Some(Self::GfxDrawLine),
0x1004 => Some(Self::GfxDrawCircle),
0x1005 => Some(Self::GfxDrawDisc),
0x1006 => Some(Self::GfxDrawSquare),
0x2001 => Some(Self::InputGetPad),
0x3001 => Some(Self::AudioPlaySample),
0x4001 => Some(Self::FsOpen),
0x4002 => Some(Self::FsRead),
0x4003 => Some(Self::FsWrite),
0x4004 => Some(Self::FsClose),
0x4005 => Some(Self::FsListDir),
0x4006 => Some(Self::FsExists),
0x4007 => Some(Self::FsDelete),
0x5001 => Some(Self::LogWrite),
0x5002 => Some(Self::LogWriteTag),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::SystemHasCart => "system.has_cart",
Self::SystemRunCart => "system.run_cart",
Self::GfxClear => "gfx.clear",
Self::GfxFillRect => "gfx.fillRect",
Self::GfxDrawLine => "gfx.drawLine",
Self::GfxDrawCircle => "gfx.drawCircle",
Self::GfxDrawDisc => "gfx.drawDisc",
Self::GfxDrawSquare => "gfx.drawSquare",
Self::InputGetPad => "input.get_pad",
Self::AudioPlaySample => "audio.playSample",
Self::FsOpen => "fs.open",
Self::FsRead => "fs.read",
Self::FsWrite => "fs.write",
Self::FsClose => "fs.close",
Self::FsListDir => "fs.listDir",
Self::FsExists => "fs.exists",
Self::FsDelete => "fs.delete",
Self::LogWrite => "log.write",
Self::LogWriteTag => "log.writeTag",
}
}
pub fn from_name(name: &str) -> Option<Self> {
match name {
"system.has_cart" => Some(Self::SystemHasCart),
"system.run_cart" => Some(Self::SystemRunCart),
"gfx.clear" => Some(Self::GfxClear),
"gfx.fillRect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
"gfx.drawLine" | "gfx.draw_line" => Some(Self::GfxDrawLine),
"gfx.drawCircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
"gfx.drawDisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
"gfx.drawSquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
"input.get_pad" => Some(Self::InputGetPad),
"audio.playSample" | "audio.play_sample" => Some(Self::AudioPlaySample),
"fs.open" => Some(Self::FsOpen),
"fs.read" => Some(Self::FsRead),
"fs.write" => Some(Self::FsWrite),
"fs.close" => Some(Self::FsClose),
"fs.listDir" => Some(Self::FsListDir),
"fs.exists" => Some(Self::FsExists),
"fs.delete" => Some(Self::FsDelete),
"log.write" => Some(Self::LogWrite),
"log.writeTag" => Some(Self::LogWriteTag),
_ => None,
}
}
}

View File

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
prometeu-bytecode = { path = "../prometeu-bytecode" }
prometeu-core = { path = "../prometeu-core" }
oxc_parser = "0.48.0"
oxc_allocator = "0.48.0"
oxc_ast = "0.48.0"

View File

@ -1,23 +1,27 @@
pub const SYS_GFX_FILL_RECT: u32 = 0x1002;
pub const SYS_INPUT_GET_PAD: u32 = 0x2001;
use prometeu_core::prometeu_os::Syscall;
use prometeu_core::model::ButtonId;
pub const BTN_UP: u32 = 0;
pub const BTN_DOWN: u32 = 1;
pub const BTN_LEFT: u32 = 2;
pub const BTN_RIGHT: u32 = 3;
pub const BTN_A: u32 = 4;
pub const BTN_B: u32 = 5;
pub const BTN_X: u32 = 6;
pub const BTN_Y: u32 = 7;
pub const BTN_L: u32 = 8;
pub const BTN_R: u32 = 9;
pub const BTN_START: u32 = 10;
pub const BTN_SELECT: u32 = 11;
pub const BTN_UP: u32 = ButtonId::Up as u32;
pub const BTN_DOWN: u32 = ButtonId::Down as u32;
pub const BTN_LEFT: u32 = ButtonId::Left as u32;
pub const BTN_RIGHT: u32 = ButtonId::Right as u32;
pub const BTN_A: u32 = ButtonId::A as u32;
pub const BTN_B: u32 = ButtonId::B as u32;
pub const BTN_X: u32 = ButtonId::X as u32;
pub const BTN_Y: u32 = ButtonId::Y as u32;
pub const BTN_L: u32 = ButtonId::L as u32;
pub const BTN_R: u32 = ButtonId::R as u32;
pub const BTN_START: u32 = ButtonId::Start as u32;
pub const BTN_SELECT: u32 = ButtonId::Select as u32;
pub fn map_syscall(name: &str) -> Option<u32> {
if let Some(syscall) = Syscall::from_name(name) {
return Some(syscall as u32);
}
// Fallback para nomes especiais do compilador
match name {
"gfx.fillRect" => Some(SYS_GFX_FILL_RECT),
"input.btnA" | "input.btnB" | "input.get_pad" => Some(SYS_INPUT_GET_PAD),
"input.btnA" | "input.btnB" => Some(Syscall::InputGetPad as u32),
_ => None,
}
}