Update script documentation

all opcode names present in enum; I found src for the version 10 engine
from 2008
This commit is contained in:
Kurt
2018-12-31 18:58:41 -08:00
parent 5fcc327d86
commit a94d63e615
5 changed files with 406 additions and 4 deletions

View 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 */
}
}

View 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;
}
}
}

View 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
*/
}

View 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
}
}

View File

@@ -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!?");
}