/// Enumeration of all System Calls (Syscalls) available in the Prometeu environment. /// /// Syscalls are the primary mechanism for a program running in the Virtual Machine /// to interact with the outside world (Hardware, OS, Filesystem). /// /// Each Syscall has a unique 32-bit ID. The IDs are grouped by category: /// - **0x0xxx**: System & OS Control /// - **0x1xxx**: Graphics (GFX) /// - **0x2xxx**: Input (Gamepad & Touch) /// - **0x3xxx**: Audio (PCM & Mixing) /// - **0x4xxx**: Filesystem (Sandboxed I/O) /// - **0x5xxx**: Logging & Debugging /// - **0x6xxx**: Asset Loading & Memory Banks #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u32)] pub enum Syscall { // --- System --- /// Checks if a cartridge is currently inserted in the virtual slot. SystemHasCart = 0x0001, /// Requests the OS to launch a specific cartridge. SystemRunCart = 0x0002, // --- GFX (Graphics) --- /// Fills the entire back buffer with a single color. GfxClear = 0x1001, /// Draws a solid rectangle. GfxFillRect = 0x1002, /// Draws a 1-pixel wide line. GfxDrawLine = 0x1003, /// Draws a circle outline. GfxDrawCircle = 0x1004, /// Draws a filled circle (disc). GfxDrawDisc = 0x1005, /// Draws a rectangle outline. GfxDrawSquare = 0x1006, /// Configures one of the 512 hardware sprites. GfxSetSprite = 0x1007, /// Draws a text string at the specified coordinates. GfxDrawText = 0x1008, /// Fills the entire back buffer with a single RGB565 color (flattened). GfxClear565 = 0x1010, // --- Input --- /// Returns the current raw state of the digital gamepad (bitmask). InputGetPad = 0x2001, /// Returns buttons that were pressed exactly in this frame. InputGetPadPressed = 0x2002, /// Returns buttons that were released exactly in this frame. InputGetPadReleased = 0x2003, /// Returns how many frames a button has been held down. InputGetPadHold = 0x2004, /// Returns the full snapshot of the gamepad state (48 slots). InputPadSnapshot = 0x2010, /// Returns the full snapshot of the touch state (6 slots). InputTouchSnapshot = 0x2011, /// Returns the X coordinate of the touch/mouse pointer. TouchGetX = 0x2101, /// Returns the Y coordinate of the touch/mouse pointer. TouchGetY = 0x2102, /// Returns true if the pointer is currently touching the screen. TouchIsDown = 0x2103, /// Returns true if the touch started in this frame. TouchIsPressed = 0x2104, /// Returns true if the touch ended in this frame. TouchIsReleased = 0x2105, /// Returns how many frames the pointer has been held down. TouchGetHold = 0x2106, /// Returns the full Button struct (6 bytes) for the touch finger state. TouchGetFinger = 0x2107, // --- Input (Pad service-based) --- /// Returns the full Button struct (6 bytes) for each gamepad button PadGetUp = 0x2200, PadGetDown = 0x2201, PadGetLeft = 0x2202, PadGetRight = 0x2203, PadGetA = 0x2204, PadGetB = 0x2205, PadGetX = 0x2206, PadGetY = 0x2207, PadGetL = 0x2208, PadGetR = 0x2209, PadGetStart = 0x220A, PadGetSelect = 0x220B, // --- Audio --- /// Starts playback of a sound sample by its Bank and ID. AudioPlaySample = 0x3001, /// Low-level audio play command. AudioPlay = 0x3002, // --- FS (Filesystem) --- /// Opens a file for reading or writing. Returns a File Handle (u32). FsOpen = 0x4001, /// Reads data from an open file handle into the VM heap. FsRead = 0x4002, /// Writes data from the VM heap into an open file handle. FsWrite = 0x4003, /// Closes an open file handle. FsClose = 0x4004, /// Lists entries in a directory. FsListDir = 0x4005, /// Checks if a file or directory exists. FsExists = 0x4006, /// Deletes a file or empty directory. FsDelete = 0x4007, // --- Log --- /// Writes a generic string to the system log. LogWrite = 0x5001, /// Writes a string to the system log with a specific numerical tag. LogWriteTag = 0x5002, // --- Asset (DMA) --- /// Starts an asynchronous load of a file into a memory bank. AssetLoad = 0x6001, /// Returns the status of a pending asset load (0=Loading, 1=Ready, 2=Error). AssetStatus = 0x6002, /// Finalizes the asset loading, making it available for GFX/Audio. AssetCommit = 0x6003, /// Cancels a pending asset load. AssetCancel = 0x6004, // --- Bank (Memory) --- /// Returns information about a specific Memory Bank. BankInfo = 0x6101, /// Returns information about a slot within a Memory Bank. BankSlotInfo = 0x6102, } impl Syscall { pub fn from_u32(id: u32) -> Option { 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), 0x1007 => Some(Self::GfxSetSprite), 0x1008 => Some(Self::GfxDrawText), 0x1010 => Some(Self::GfxClear565), 0x2001 => Some(Self::InputGetPad), 0x2002 => Some(Self::InputGetPadPressed), 0x2003 => Some(Self::InputGetPadReleased), 0x2004 => Some(Self::InputGetPadHold), 0x2010 => Some(Self::InputPadSnapshot), 0x2011 => Some(Self::InputTouchSnapshot), 0x2101 => Some(Self::TouchGetX), 0x2102 => Some(Self::TouchGetY), 0x2103 => Some(Self::TouchIsDown), 0x2104 => Some(Self::TouchIsPressed), 0x2105 => Some(Self::TouchIsReleased), 0x2106 => Some(Self::TouchGetHold), 0x2107 => Some(Self::TouchGetFinger), 0x2200 => Some(Self::PadGetUp), 0x2201 => Some(Self::PadGetDown), 0x2202 => Some(Self::PadGetLeft), 0x2203 => Some(Self::PadGetRight), 0x2204 => Some(Self::PadGetA), 0x2205 => Some(Self::PadGetB), 0x2206 => Some(Self::PadGetX), 0x2207 => Some(Self::PadGetY), 0x2208 => Some(Self::PadGetL), 0x2209 => Some(Self::PadGetR), 0x220A => Some(Self::PadGetStart), 0x220B => Some(Self::PadGetSelect), 0x3001 => Some(Self::AudioPlaySample), 0x3002 => Some(Self::AudioPlay), 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), 0x6001 => Some(Self::AssetLoad), 0x6002 => Some(Self::AssetStatus), 0x6003 => Some(Self::AssetCommit), 0x6004 => Some(Self::AssetCancel), 0x6101 => Some(Self::BankInfo), 0x6102 => Some(Self::BankSlotInfo), _ => None, } } pub fn args_count(&self) -> usize { match self { Self::SystemHasCart => 0, Self::SystemRunCart => 0, Self::GfxClear => 1, Self::GfxFillRect => 5, Self::GfxDrawLine => 5, Self::GfxDrawCircle => 4, Self::GfxDrawDisc => 5, Self::GfxDrawSquare => 6, Self::GfxSetSprite => 10, Self::GfxDrawText => 4, Self::GfxClear565 => 1, Self::InputGetPad => 1, Self::InputGetPadPressed => 1, Self::InputGetPadReleased => 1, Self::InputGetPadHold => 1, Self::InputPadSnapshot => 0, Self::InputTouchSnapshot => 0, Self::TouchGetX => 0, Self::TouchGetY => 0, Self::TouchIsDown => 0, Self::TouchIsPressed => 0, Self::TouchIsReleased => 0, Self::TouchGetHold => 0, Self::TouchGetFinger => 0, Self::PadGetUp => 0, Self::PadGetDown => 0, Self::PadGetLeft => 0, Self::PadGetRight => 0, Self::PadGetA => 0, Self::PadGetB => 0, Self::PadGetX => 0, Self::PadGetY => 0, Self::PadGetL => 0, Self::PadGetR => 0, Self::PadGetStart => 0, Self::PadGetSelect => 0, Self::AudioPlaySample => 5, Self::AudioPlay => 7, Self::FsOpen => 1, Self::FsRead => 1, Self::FsWrite => 2, Self::FsClose => 1, Self::FsListDir => 1, Self::FsExists => 1, Self::FsDelete => 1, Self::LogWrite => 2, Self::LogWriteTag => 3, Self::AssetLoad => 3, Self::AssetStatus => 1, Self::AssetCommit => 1, Self::AssetCancel => 1, Self::BankInfo => 1, Self::BankSlotInfo => 2, } } pub fn results_count(&self) -> usize { match self { // --- System --- Self::SystemHasCart => 1, Self::SystemRunCart => 0, // --- GFX (void) --- Self::GfxClear => 0, Self::GfxFillRect => 0, Self::GfxDrawLine => 0, Self::GfxDrawCircle => 0, Self::GfxDrawDisc => 0, Self::GfxDrawSquare => 0, Self::GfxSetSprite => 0, Self::GfxDrawText => 0, Self::GfxClear565 => 0, // --- Input (scalar/snapshots) --- Self::InputGetPad => 1, Self::InputGetPadPressed => 1, Self::InputGetPadReleased => 1, Self::InputGetPadHold => 1, Self::InputPadSnapshot => 48, Self::InputTouchSnapshot => 6, // --- Touch (scalars/struct) --- Self::TouchGetX => 1, Self::TouchGetY => 1, Self::TouchIsDown => 1, Self::TouchIsPressed => 1, Self::TouchIsReleased => 1, Self::TouchGetHold => 1, Self::TouchGetFinger => 4, // Button struct (4 slots) // --- Pad (per-button struct: 4 slots) --- Self::PadGetUp | Self::PadGetDown | Self::PadGetLeft | Self::PadGetRight | Self::PadGetA | Self::PadGetB | Self::PadGetX | Self::PadGetY | Self::PadGetL | Self::PadGetR | Self::PadGetStart | Self::PadGetSelect => 4, // --- Audio (void) --- Self::AudioPlaySample => 0, Self::AudioPlay => 0, // --- FS --- Self::FsOpen => 1, Self::FsRead => 1, // bytes read Self::FsWrite => 1, // bytes written Self::FsClose => 0, Self::FsListDir => 1, // entries count/handle (TBD) Self::FsExists => 1, Self::FsDelete => 0, // --- Log (void) --- Self::LogWrite | Self::LogWriteTag => 0, // --- Asset/Bank (conservador) --- Self::AssetLoad => 1, Self::AssetStatus => 1, Self::AssetCommit => 0, Self::AssetCancel => 0, Self::BankInfo => 1, Self::BankSlotInfo => 1, } } pub fn name(&self) -> &'static str { match self { Self::SystemHasCart => "SystemHasCart", Self::SystemRunCart => "SystemRunCart", Self::GfxClear => "GfxClear", Self::GfxFillRect => "GfxFillRect", Self::GfxDrawLine => "GfxDrawLine", Self::GfxDrawCircle => "GfxDrawCircle", Self::GfxDrawDisc => "GfxDrawDisc", Self::GfxDrawSquare => "GfxDrawSquare", Self::GfxSetSprite => "GfxSetSprite", Self::GfxDrawText => "GfxDrawText", Self::GfxClear565 => "GfxClear565", Self::InputGetPad => "InputGetPad", Self::InputGetPadPressed => "InputGetPadPressed", Self::InputGetPadReleased => "InputGetPadReleased", Self::InputGetPadHold => "InputGetPadHold", Self::InputPadSnapshot => "InputPadSnapshot", Self::InputTouchSnapshot => "InputTouchSnapshot", Self::TouchGetX => "TouchGetX", Self::TouchGetY => "TouchGetY", Self::TouchIsDown => "TouchIsDown", Self::TouchIsPressed => "TouchIsPressed", Self::TouchIsReleased => "TouchIsReleased", Self::TouchGetHold => "TouchGetHold", Self::TouchGetFinger => "TouchGetFinger", Self::PadGetUp => "PadGetUp", Self::PadGetDown => "PadGetDown", Self::PadGetLeft => "PadGetLeft", Self::PadGetRight => "PadGetRight", Self::PadGetA => "PadGetA", Self::PadGetB => "PadGetB", Self::PadGetX => "PadGetX", Self::PadGetY => "PadGetY", Self::PadGetL => "PadGetL", Self::PadGetR => "PadGetR", Self::PadGetStart => "PadGetStart", Self::PadGetSelect => "PadGetSelect", Self::AudioPlaySample => "AudioPlaySample", Self::AudioPlay => "AudioPlay", Self::FsOpen => "FsOpen", Self::FsRead => "FsRead", Self::FsWrite => "FsWrite", Self::FsClose => "FsClose", Self::FsListDir => "FsListDir", Self::FsExists => "FsExists", Self::FsDelete => "FsDelete", Self::LogWrite => "LogWrite", Self::LogWriteTag => "LogWriteTag", Self::AssetLoad => "AssetLoad", Self::AssetStatus => "AssetStatus", Self::AssetCommit => "AssetCommit", Self::AssetCancel => "AssetCancel", Self::BankInfo => "BankInfo", Self::BankSlotInfo => "BankSlotInfo", } } }