mirror of
https://github.com/kwsch/pkNX.git
synced 2026-09-08 02:25:15 -05:00
Update script documentation
all opcode names present in enum; I found src for the version 10 engine from 2008
This commit is contained in:
35
pkNX.Structures/Scripts/AmxError.cs
Normal file
35
pkNX.Structures/Scripts/AmxError.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
public enum AmxError
|
||||
{
|
||||
AMX_ERR_NONE,
|
||||
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
||||
EXIT, /* forced exit */
|
||||
ASSERT, /* assertion failed */
|
||||
STACKERR, /* stack/heap collision */
|
||||
BOUNDS, /* index out of bounds */
|
||||
MEMACCESS, /* invalid memory access */
|
||||
INVINSTR, /* invalid instruction */
|
||||
STACKLOW, /* stack underflow */
|
||||
HEAPLOW, /* heap underflow */
|
||||
CALLBACK, /* no callback, or invalid callback */
|
||||
NATIVE, /* native function failed */
|
||||
DIVIDE, /* divide by zero */
|
||||
SLEEP, /* go into sleepmode - code can be restarted */
|
||||
INVSTATE, /* no implementation for this state, no fall-back */
|
||||
|
||||
MEMORY = 16, /* out of memory */
|
||||
FORMAT, /* invalid file format */
|
||||
VERSION, /* file is for a newer version of the AMX */
|
||||
NOTFOUND, /* function not found */
|
||||
INDEX, /* invalid index parameter (bad entry point) */
|
||||
DEBUG, /* debugger cannot run */
|
||||
INIT, /* AMX not initialized (or doubly initialized) */
|
||||
USERDATA, /* unable to set user data field (table full) */
|
||||
INIT_JIT, /* cannot initialize the JIT */
|
||||
PARAMS, /* parameter error */
|
||||
DOMAIN, /* domain error, expression result does not fit in range */
|
||||
GENERAL, /* general error (unknown or unspecific error) */
|
||||
OVERLAY, /* overlays are unsupported (JIT) or uninitialized */
|
||||
}
|
||||
}
|
||||
57
pkNX.Structures/Scripts/AmxFlags.cs
Normal file
57
pkNX.Structures/Scripts/AmxFlags.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
/// <summary>
|
||||
/// Feature flags for the <see cref="AmxHeader"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Flag version listed here is for CUR_FILE_VERSION = 10, circa 2008
|
||||
/// </remarks>
|
||||
[Flags]
|
||||
public enum AmxFlags : short
|
||||
{
|
||||
NONE,
|
||||
|
||||
/// <summary> All function calls use overlays </summary>
|
||||
OVERLAY = 0x01,
|
||||
|
||||
/// <summary> Symbolic info is available </summary>
|
||||
DEBUG = 0x02,
|
||||
|
||||
/// <summary> Compact encoding </summary>
|
||||
COMPACT = 0x04,
|
||||
|
||||
/// <summary> Script uses the sleep instruction (possible re-entry or power-down mode) </summary>
|
||||
SLEEP = 0x08,
|
||||
|
||||
/// <summary> No array bounds checking; no BREAK opcodes </summary>
|
||||
NOCHECKS = 0x10,
|
||||
|
||||
/// <summary> Data section is explicitly initialized </summary>
|
||||
DSEG_INIT = 0x20,
|
||||
|
||||
/// <summary> Script new (optimized) version of SYSREQ opcode </summary>
|
||||
SYSREQN = 0x800,
|
||||
|
||||
/// <summary> All native functions are registered </summary>
|
||||
NTVREG = 0x1000,
|
||||
|
||||
/// <summary> Abstract machine is JIT compiled </summary>
|
||||
JITC = 0x2000,
|
||||
|
||||
/// <summary> Busy verifying P-code </summary>
|
||||
VERIFY = 0x4000,
|
||||
|
||||
/// <summary> AMX has been initialized </summary>
|
||||
INIT = 8000
|
||||
}
|
||||
|
||||
public static class AmxFlagsExtensions
|
||||
{
|
||||
public static bool HasFlagFast(this AmxFlags value, AmxFlags flag)
|
||||
{
|
||||
return (value & flag) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
pkNX.Structures/Scripts/AmxHeader.cs
Normal file
82
pkNX.Structures/Scripts/AmxHeader.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class AmxHeader
|
||||
{
|
||||
// Cell Size magic verification
|
||||
public const ushort MAGIC_32 = 0xf1e0;
|
||||
public const ushort MAGIC_64 = 0xf1e1;
|
||||
public const ushort MAGIC_16 = 0xf1e2;
|
||||
|
||||
/// <summary> Size of the "file" </summary>
|
||||
public int Size; // 0x00
|
||||
|
||||
/// <summary> Signature </summary>
|
||||
public ushort Magic; // 0x04
|
||||
|
||||
/// <summary> File format version </summary>
|
||||
public byte FileVersion; // 0x06
|
||||
|
||||
/// <summary> Required version of the AMX </summary>
|
||||
public byte AMXVersion; // 0x07
|
||||
|
||||
/// <summary> Feature flags </summary>
|
||||
public AmxFlags Flags; // 0x08
|
||||
|
||||
/// <summary> Size of a definition record </summary>
|
||||
public short DefinitionSize; // 0x0A
|
||||
|
||||
/// <summary> Initial value of COD - code block </summary>
|
||||
public int COD; // 0x0C
|
||||
|
||||
/// <summary> initial value of DAT - data block </summary>
|
||||
public int Data; // 0x10
|
||||
|
||||
/// <summary> Initial value of HEA - start of the heap </summary>
|
||||
public int Heap; // 0x14
|
||||
|
||||
/// <summary> Initial value of STP - stack top </summary>
|
||||
public int StackTop; // 0x18
|
||||
|
||||
/// <summary> Initial value of CIP - the instruction pointer </summary>
|
||||
public int CurrentInstructionPointer; // 0x20
|
||||
|
||||
/// <summary> Offset to the "public functions" table </summary>
|
||||
public int Publics; // 0x24
|
||||
|
||||
/// <summary> Offset to the "native functions" table </summary>
|
||||
public int Natives; // 0x28
|
||||
|
||||
/// <summary> Offset to the table of libraries </summary>
|
||||
public int Libraries; // 0x2C
|
||||
|
||||
/// <summary> Offset to the "public variables" table </summary>
|
||||
public int PublicVars; // 0x30
|
||||
|
||||
/// <summary> Offset to the "public tagnames" table </summary>
|
||||
public int Tags; // 0x34
|
||||
|
||||
/// <summary> Offset to the name table </summary>
|
||||
public int NameTable; // 0x38
|
||||
|
||||
/// <summary> Offset to the overlay table </summary>
|
||||
public int Overlays; // 0x3C
|
||||
}
|
||||
|
||||
/* File format version
|
||||
* 0 original version
|
||||
* 1 opcodes JUMP.pri, SWITCH and CASETBL
|
||||
* 2 compressed files
|
||||
* 3 public variables
|
||||
* 4 opcodes SWAP.pri/alt and PUSHADDR
|
||||
* 5 tagnames table
|
||||
* 6 reformatted header
|
||||
* 7 name table, opcodes SYMTAG & SYSREQ.D
|
||||
* 8 opcode BREAK, renewed debug interface
|
||||
* 9 macro opcodes
|
||||
* 10 position-independent code, overlays, packed instructions
|
||||
* 11 relocating instructions for the native interface, reorganized instruction set
|
||||
*/
|
||||
}
|
||||
226
pkNX.Structures/Scripts/AmxOpCode.cs
Normal file
226
pkNX.Structures/Scripts/AmxOpCode.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
// https://github.com/gameswop/mtasa-resources/blob/d557a72fefef57ac34780a76edf16383d3dff0e8/%5Bgamemodes%5D/%5Bamx%5D/amx-deps/src/amx/amx.c#L143
|
||||
public enum AmxOpCode
|
||||
{
|
||||
NONE, /* invalid opcode */
|
||||
LOAD_PRI,
|
||||
LOAD_ALT,
|
||||
LOAD_S_PRI,
|
||||
LOAD_S_ALT,
|
||||
LREF_PRI,
|
||||
LREF_ALT,
|
||||
LREF_S_PRI,
|
||||
LREF_S_ALT,
|
||||
LOAD_I,
|
||||
LODB_I,
|
||||
CONST_PRI,
|
||||
CONST_ALT,
|
||||
ADDR_PRI,
|
||||
ADDR_ALT,
|
||||
STOR_PRI,
|
||||
STOR_ALT,
|
||||
STOR_S_PRI,
|
||||
STOR_S_ALT,
|
||||
SREF_PRI,
|
||||
SREF_ALT,
|
||||
SREF_S_PRI,
|
||||
SREF_S_ALT,
|
||||
STOR_I,
|
||||
STRB_I,
|
||||
LIDX,
|
||||
LIDX_B,
|
||||
IDXADDR,
|
||||
IDXADDR_B,
|
||||
ALIGN_PRI,
|
||||
ALIGN_ALT,
|
||||
LCTRL,
|
||||
SCTRL,
|
||||
MOVE_PRI,
|
||||
MOVE_ALT,
|
||||
XCHG,
|
||||
PUSH_PRI,
|
||||
PUSH_ALT,
|
||||
PICK,
|
||||
PUSH_C,
|
||||
PUSH,
|
||||
PUSH_S,
|
||||
PPRI,
|
||||
PALT,
|
||||
STACK,
|
||||
HEAP,
|
||||
PROC,
|
||||
RET,
|
||||
RETN,
|
||||
CALL,
|
||||
CALL_PRI,
|
||||
JUMP,
|
||||
JREL, /* obsolete */
|
||||
JZER,
|
||||
JNZ,
|
||||
JEQ,
|
||||
JNEQ,
|
||||
JLESS,
|
||||
JLEQ,
|
||||
JGRTR,
|
||||
JGEQ,
|
||||
JSLESS,
|
||||
JSLEQ,
|
||||
JSGRTR,
|
||||
JSGEQ,
|
||||
SHL,
|
||||
SHR,
|
||||
SSHR,
|
||||
SHL_C_PRI,
|
||||
SHL_C_ALT,
|
||||
SHR_C_PRI,
|
||||
SHR_C_ALT,
|
||||
SMUL,
|
||||
SDIV,
|
||||
SDIV_ALT,
|
||||
UMUL,
|
||||
UDIV,
|
||||
UDIV_ALT,
|
||||
ADD,
|
||||
SUB,
|
||||
SUB_ALT,
|
||||
AND,
|
||||
OR,
|
||||
XOR,
|
||||
NOT,
|
||||
NEG,
|
||||
INVERT,
|
||||
ADD_C,
|
||||
SMUL_C,
|
||||
ZERO_PRI,
|
||||
ZERO_ALT,
|
||||
ZERO,
|
||||
ZERO_S,
|
||||
SIGN_PRI,
|
||||
SIGN_ALT,
|
||||
EQ,
|
||||
NEQ,
|
||||
LESS,
|
||||
LEQ,
|
||||
GRTR,
|
||||
GEQ,
|
||||
SLESS,
|
||||
SLEQ,
|
||||
SGRTR,
|
||||
SGEQ,
|
||||
EQ_C_PRI,
|
||||
EQ_C_ALT,
|
||||
INC_PRI,
|
||||
INC_ALT,
|
||||
INC,
|
||||
INC_S,
|
||||
INC_I,
|
||||
DEC_PRI,
|
||||
DEC_ALT,
|
||||
DEC,
|
||||
DEC_S,
|
||||
DEC_I,
|
||||
MOVS,
|
||||
CMPS,
|
||||
FILL,
|
||||
HALT,
|
||||
BOUNDS,
|
||||
SYSREQ_PRI,
|
||||
SYSREQ_C,
|
||||
FILE, /* obsolete */
|
||||
LINE, /* obsolete */
|
||||
SYMBOL, /* obsolete */
|
||||
SRANGE, /* obsolete */
|
||||
JUMP_PRI,
|
||||
SWITCH,
|
||||
CASETBL,
|
||||
SWAP_PRI,
|
||||
SWAP_ALT,
|
||||
PUSH_ADR,
|
||||
NOP,
|
||||
SYSREQ_N,
|
||||
SYMTAG, /* obsolete */
|
||||
BREAK, /* macro instructions */
|
||||
PUSH2_C,
|
||||
PUSH2,
|
||||
PUSH2_S,
|
||||
PUSH2_ADR,
|
||||
PUSH3_C,
|
||||
PUSH3,
|
||||
PUSH3_S,
|
||||
PUSH3_ADR,
|
||||
PUSH4_C,
|
||||
PUSH4,
|
||||
PUSH4_S,
|
||||
PUSH4_ADR,
|
||||
PUSH5_C,
|
||||
PUSH5,
|
||||
PUSH5_S,
|
||||
PUSH5_ADR,
|
||||
LOAD_BOTH,
|
||||
LOAD_S_BOTH,
|
||||
CONST,
|
||||
CONST_S, /* overlay instructions */
|
||||
ICALL,
|
||||
IRETN,
|
||||
ISWITCH,
|
||||
ICASETBL, /* packed instructions */
|
||||
#if !AMX_NO_PACKED_OPC
|
||||
LOAD_P_PRI,
|
||||
LOAD_P_ALT,
|
||||
LOAD_P_S_PRI,
|
||||
LOAD_P_S_ALT,
|
||||
LREF_P_PRI,
|
||||
LREF_P_ALT,
|
||||
LREF_P_S_PRI,
|
||||
LREF_P_S_ALT,
|
||||
LODB_P_I,
|
||||
CONST_P_PRI,
|
||||
CONST_P_ALT,
|
||||
ADDR_P_PRI,
|
||||
ADDR_P_ALT,
|
||||
STOR_P_PRI,
|
||||
STOR_P_ALT,
|
||||
STOR_P_S_PRI,
|
||||
STOR_P_S_ALT,
|
||||
SREF_P_PRI,
|
||||
SREF_P_ALT,
|
||||
SREF_P_S_PRI,
|
||||
SREF_P_S_ALT,
|
||||
STRB_P_I,
|
||||
LIDX_P_B,
|
||||
IDXADDR_P_B,
|
||||
ALIGN_P_PRI,
|
||||
ALIGN_P_ALT,
|
||||
PUSH_P_C,
|
||||
PUSH_P,
|
||||
PUSH_P_S,
|
||||
STACK_P,
|
||||
HEAP_P,
|
||||
SHL_P_C_PRI,
|
||||
SHL_P_C_ALT,
|
||||
SHR_P_C_PRI,
|
||||
SHR_P_C_ALT,
|
||||
ADD_P_C,
|
||||
SMUL_P_C,
|
||||
ZERO_P,
|
||||
ZERO_P_S,
|
||||
EQ_P_C_PRI,
|
||||
EQ_P_C_ALT,
|
||||
INC_P,
|
||||
INC_P_S,
|
||||
DEC_P,
|
||||
DEC_P_S,
|
||||
MOVS_P,
|
||||
CMPS_P,
|
||||
FILL_P,
|
||||
HALT_P,
|
||||
BOUNDS_P,
|
||||
PUSH_P_ADR,
|
||||
#endif
|
||||
/* ----- */
|
||||
SYSREQ_D,
|
||||
SYSREQ_ND, /* ----- */
|
||||
NUM_OPCODES
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,12 @@ namespace pkNX.Structures
|
||||
/// <remarks>https://github.com/compuphase/pawn</remarks>
|
||||
public class Script
|
||||
{
|
||||
public int Length => BitConverter.ToInt32(Raw, 0x00);
|
||||
public uint Magic => BitConverter.ToUInt32(Raw, 0x04);
|
||||
public AmxHeader Header;
|
||||
public int Length => Header.Size;
|
||||
public uint Magic => Header.Magic;
|
||||
// case 0x0A0AF1E0: code = read_code_block(f); break;
|
||||
// case 0x0A0AF1EF: debug = read_debug_block(f); break;
|
||||
public bool Debug => Magic == 0x0A0AF1EF;
|
||||
public bool Debug => Header.Flags.HasFlagFast(AmxFlags.DEBUG);
|
||||
|
||||
public ushort PtrOffset => BitConverter.ToUInt16(Raw, 0x08);
|
||||
public ushort PtrCount => BitConverter.ToUInt16(Raw, 0x0A);
|
||||
@@ -48,9 +49,10 @@ public class Script
|
||||
public Script(byte[] data = null)
|
||||
{
|
||||
Raw = data ?? Array.Empty<byte>();
|
||||
Header = data.ToClass<AmxHeader>();
|
||||
|
||||
// sub_51AAFC
|
||||
if ((Raw[8] & 1) != 0)
|
||||
if (Header.Flags.HasFlagFast(AmxFlags.OVERLAY))
|
||||
throw new ArgumentException("Multi-environment script!?");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user