Skip to content

EDIABAS BEST2 Interpreter & Bytecode Reference

This document describes the BEST2 bytecode interpreter implementation in TypeScript. It covers the PRG/GRB file format, register architecture, addressing modes, instruction set, and runtime behavior. All information is derived from the actual source code in packages/interpreter and packages/best-parser.


Table of Contents

  1. PRG/GRB File Structure
  2. Registers and Addressing Modes
  3. CPU Flags
  4. Bytecode Instruction Set
  5. Stack Operations
  6. String and Binary Handling
  7. Result Collection
  8. Error Handling and Trap Bits
  9. Job Execution Flow
  10. Communication Interface
  11. File System Operations
  12. Table Operations

1. PRG/GRB File Structure

EDIABAS programs are stored in two main formats: legacy binary PRG/GRP and EDIABAS OBJECT format. The parser in packages/best-parser supports both formats.

1.1 Legacy Binary PRG/GRP Format

The legacy format uses a 32-byte header with the magic number 0x00475250 ("PRG\0").

Header Layout

All fields are little-endian uint32 unless otherwise noted:

OffsetFieldDescription
0x00magic0x00475250 ("PRG\0")
0x04version0 = GRP (group), 1 = PRG (program)
0x08stringTableOffsetStart of string table
0x0CstringTableSizeSize of string table in bytes
0x10jobTableOffsetStart of job table
0x14jobCountNumber of job entries
0x18codeOffsetStart of bytecode section
0x1CcodeSizeSize of bytecode section in bytes

Derived Boundaries

stringTableEnd = stringTableOffset + stringTableSize
jobTableEnd = jobTableOffset + (jobCount * 12)
codeEnd = codeOffset + codeSize

String Table

The string table contains null-terminated CP1252-encoded strings. Strings are referenced by offset from the start of the table.

Job Table

Each job entry is 12 bytes:

FieldTypeDescription
nameOffsetuint32Offset into string table
offsetuint32Bytecode offset (start of job code)
argCountuint16Number of arguments expected
resultCountuint16Number of results produced

1.2 EDIABAS OBJECT Format

The EDIABAS OBJECT format is identified by the ASCII string "@EDIABAS OBJECT" (16 bytes, NUL-padded).

Header Layout

OffsetFieldDescription
0x00magic"@EDIABAS OBJECT" (16 bytes, ASCII/NUL-padded)
0x10version0 = GRP, 1 = PRG
0x84tableListOffsetOffset to table list (uint32, not XOR)
0x88jobListOffsetOffset to job list (uint32, not XOR)
0xA0dataOffsetStart of XOR-encoded data

XOR Encoding

All data from offset 0xA0 onwards is XOR-encoded with the key 0xF7. This includes:

  • Job metadata (text format)
  • Binary job list entries
  • Table data
  • Bytecode (if embedded)

To decode: decodedByte = encodedByte ^ 0xF7

Text Metadata Section

The decoded data area contains human-readable metadata in text format:

JOBNAME:<jobname>
JOBCOMMENT:<comment>
RESULT:<name>
RESULTTYPE:<type>
RESULTCOMMENT:<comment>
ARG:<name>
ARGTYPE:<type>
ARGCOMMENT:<comment>

Binary Job List

The jobListOffset points to a structure containing:

  • Job count (int32, NOT XOR-encoded)
  • Job entries (size 0x44 each, XOR-encoded)

Each job entry (XOR-encoded):

OffsetFieldTypeDescription
0x00–0x3Fnamechar[64]Job name (CP1252, XOR-encoded, NUL-terminated)
0x40–0x43offsetuint32Bytecode offset (XOR-encoded)

Binary Table List

The tableListOffset points to:

  • Table count (int32, encoding inconsistent — parser tries raw then XOR-decoded)
  • Table entries (size 0x50 each, XOR-encoded)

Each table entry (XOR-encoded):

OffsetFieldTypeDescription
0x00–0x3Fnamechar[64]Table name (CP1252, XOR-encoded)
0x40–0x43columnOffsetuint32Column data offset (XOR-encoded)
0x48–0x4Bcolumnsuint32Number of columns (XOR-encoded)
0x4C–0x4Frowsuint32Number of data rows (XOR-encoded)

Table data consists of XOR-encoded, NUL-terminated CP1252 strings. The first row contains column headers, followed by rows data rows.


2. Registers and Addressing Modes

The BEST2 interpreter implements a register-based virtual machine with six register types.

2.1 Register Set

Register TypeCountWidthDescription
B0–BF168-bitUnsigned byte registers
A0–AF168-bitUnsigned byte registers (alternate set)
I0–IF1616-bitUnsigned word registers
L0–L7832-bitUnsigned double-word registers
S0–SF16StringString/binary data (default max 255 bytes)
F0–F7864-bitIEEE-754 double-precision floating-point

Total: 32 × 8-bit, 16 × 16-bit, 8 × 32-bit, 16 × string, 8 × float

2.2 Internal CPU State

The interpreter maintains additional state not directly addressable as registers:

ComponentDescription
PCProgram counter (bytecode offset)
FlagsZ (zero), C (carry), V (overflow), S (sign)
Call StackReturn addresses for jtsr/ret
Data StackByte stack for push/pop/pushf/popf
Procedure StackProcedure parameter stack (ppush/ppop)
Error TrapMask and bit number for error handling
ProgressText, range, position for UI updates
Token StateSeparator and index for stoken
Table StateActive table reference and current row
Float PrecisionDecimal places for flt2a (default 4)

2.3 Register Encoding

Registers are encoded in operands as a single byte:

Byte RangeRegistersMapping
0x00–0x0FB0–BFB[byte - 0x00]
0x10–0x17I0–I7I[byte - 0x10]
0x18–0x1BL0–L3L[byte - 0x18]
0x1C–0x23S0–S7S[byte - 0x1C]
0x24–0x2BF0–F7F[byte - 0x24]
0x2C–0x33S8–SFS[byte - 0x2C + 8]
0x80–0x8FA0–AFA[byte - 0x80]
0x90–0x97I8–IFI[byte - 0x90 + 8]
0x98–0x9BL4–L7L[byte - 0x98 + 4]

Examples:

  • 0x00 → B0
  • 0x10 → I0
  • 0x1C → S0
  • 0x80 → A0
  • 0x90 → I8
  • 0x98 → L4

2.4 Addressing Modes

Every instruction is encoded as:

[opcode:1][addrMode:1][arg0...][arg1...]

The addressing mode byte encodes two 4-bit nibbles:

  • High nibble (bits 7–4): Mode for arg0
  • Low nibble (bits 3–0): Mode for arg1

Addressing Mode Table

ModeNameEncodingDescription
0x0NONENo operand (omitted)
0x1REG_S1 byte registerAny register (B/A/I/L/S/F)
0x2REG_AB1 byte registerSame as REG_S (legacy distinction)
0x3REG_I1 byte registerSame as REG_S (legacy distinction)
0x4REG_L1 byte registerSame as REG_S (legacy distinction)
0x5IMM81 byte immediateUnsigned 8-bit immediate value
0x6IMM162 bytes immediate (LE)Signed 16-bit immediate value
0x7IMM324 bytes immediate (LE)Signed 32-bit immediate value
0x8IMM_STR2-byte length + dataString immediate (length includes NUL in many files)
0x9IDX_IMMreg + i16 indexSx[#imm]
0xAIDX_REGreg + regSx[reg]
0xBIDX_REG_IMMreg + reg + i16 offsetSx[reg,#imm]
0xCIDX_IMM_LEN_IMMreg + i16 index + i16 lengthSx[#idx]#len
0xDIDX_IMM_LEN_REGreg + i16 index + reg lengthSx[#idx]reg
0xEIDX_REG_LEN_IMMreg + reg index + i16 lengthSx[reg]#len
0xFIDX_REG_LEN_REGreg + reg index + reg lengthSx[reg]reg

Indexed operands always use S registers as the base. The index and length can be immediate values or register references.

Example Instruction Encoding

move I0, #$1234

Encoded as:

[0x00]  [0x61]  [0x10]  [0x34] [0x12]
  ↑       ↑       ↑       ↑      ↑
opcode  mode   arg0    imm16 (little-endian)
       (6:REG, 1:IMM16)
  • Opcode: 0x00 (move)
  • Addressing mode: 0x61 (arg0=REG_S, arg1=IMM16)
  • Arg0: 0x10 (I0)
  • Arg1: 0x3412 (little-endian 0x1234)

2.5 Jump Offsets

Jump instructions accept a relative offset applied to the PC after decoding the instruction. Some jump opcodes also accept a register containing an absolute target address, which the interpreter converts to a relative offset internally.


3. CPU Flags

The interpreter maintains four CPU flags that are updated by arithmetic and comparison operations and tested by conditional jump instructions.

3.1 Flag Descriptions

FlagNameDescription
ZZeroSet when the result of an operation is zero
CCarrySet on unsigned overflow (result exceeds bit width)
VOverflowSet on signed overflow (sign bit changes unexpectedly)
SSignSet when the result is negative (MSB = 1)

3.2 Flag Update Operations

Flags are updated by:

  • Arithmetic: adds, subb, mult, divs, addc, subc
  • Bitwise: and, or, xor, not, test
  • Shift: asr, asl, lsr, lsl
  • Comparison: comp (integer), fcomp (float), strcmp (string)
  • Explicit: clrc, setc, clrv

3.3 Flag Test Operations (Conditional Jumps)

InstructionConditionFlags Tested
jzZeroZ = 1
jnzNot zeroZ = 0
jcCarryC = 1
jae/jncNo carry (above/equal)C = 0
jmiMinus (negative)S = 1
jplPlus (positive)S = 0
jvOverflowV = 1
jnvNo overflowV = 0
jgGreater (signed)Z=0 AND S=V
jge/jnlGreater/equal (signed)S = V
jlLess (signed)S ≠ V
jle/jngLess/equal (signed)Z=1 OR S≠V
jaAbove (unsigned)C=0 AND Z=0
jbe/jnaBelow/equal (unsigned)C=1 OR Z=1

3.4 Flag Stack Operations

Flags can be saved and restored using the data stack:

  • pushf: Push flags to data stack (stored as 32-bit bitfield: C=1, Z=2, S=4, V=8)
  • popf: Pop flags from data stack

4. Bytecode Instruction Set

The BEST2 interpreter implements 184 opcodes. Below is a comprehensive reference table for all opcodes.

4.1 Legend

  • int reg = B/A/I/L (integer register)
  • float reg = F (float register)
  • string reg = S (string register)
  • idx = indexed string operand (Sx[...])
  • imm = immediate value (8/16/32-bit)

4.2 Complete Opcode Table

OpcodeMnemonicDescriptionRegisters/StateOperand FormatExample
0x00moveMove/copy value between registers or memoryany reg, idxdest, srcmove I0, #$10
0x01clearClear register (set to 0 or empty string)any regdestclear S0
0x02compCompare integers (sets flags)int regs, flagsleft, rightcomp I0, I1
0x03subbSubtract integers (sets flags)int regs, flagsdest, srcsubb I0, #1
0x04addsAdd integers (sets flags)int regs, flagsdest, srcadds B0, B1
0x05multMultiply integers (high part → src if reg)int regs, flagsdest, srcmult I0, I1
0x06divsDivide integers (quotient → dest, remainder → src if reg)int regs, flagsdest, srcdivs L0, L1
0x07andBitwise ANDint regs, flagsdest, srcand B0, #$0F
0x08orBitwise ORint regs, flagsdest, srcor B0, B1
0x09xorBitwise XORint regs, flagsdest, srcxor I0, I1
0x0AnotBitwise NOTint reg, flagsdestnot A0
0x0BjumpUnconditional relative jumpPCoffsetjump #$10
0x0CjtsrJump to subroutine (call)call stack, PCoffsetjtsr #$FFF0
0x0DretReturn from subroutinecall stack, PCret
0x0EjcJump if carryflags, PCoffsetjc #$20
0x0FjaeJump if above/equal (no carry)flags, PCoffsetjae #$20
0x10jzJump if zeroflags, PCoffsetjz #$20
0x11jnzJump if not zeroflags, PCoffsetjnz #$20
0x12jvJump if overflowflags, PCoffsetjv #$20
0x13jnvJump if no overflowflags, PCoffsetjnv #$20
0x14jmiJump if minus/signflags, PCoffsetjmi #$FFF0
0x15jplJump if plus/no signflags, PCoffsetjpl #$08
0x16clrcClear carry flagflagsclrc
0x17setcSet carry flagflagssetc
0x18asrArithmetic shift right (impl: logical shift right)int regs, flagsdest, countasr I0, #1
0x19lslLogical shift leftint regs, flagsdest, countlsl I0, #1
0x1AlsrLogical shift rightint regs, flagsdest, countlsr I0, #1
0x1BaslArithmetic shift left (impl: same as lsl)int regs, flagsdest, countasl I0, #1
0x1CnopNo operationnop
0x1DeojEnd of job (halt execution)haltedeoj
0x1EpushPush integer or immediate to data stackstack, int regsrcpush I0
0x1FpopPop integer from data stackstack, int regdestpop I0
0x20scmpCompare binary/string values (Z=1 if equal)string regs, flagsleft, rightscmp S0, S1
0x21scatConcatenate binary/string data (append)string regsdest, srcscat S0, S1
0x22scutCut N bytes from end of stringstring reg, intdest, lenscut S0, I0
0x23slenStore byte length of binary/stringint reg, string regdest, srcslen I0, S0
0x24spasteInsert binary/string into indexed targetidx, string regdestIdx, srcspaste S0[#2], S1
0x25seraseRemove bytes from indexed rangeidx, intdestIdx, lenserase S0[#2], I0
0x26xconnectOpen communication interfacecommxconnect
0x27xhangupClose communication interfacecommxhangup
0x28xsetparSet communication parameters from buffercomm, string regsrcxsetpar S0
0x29xawlenSet answer lengths from buffercomm, string regsrcxawlen S0
0x2AxsendSend request and receive responsecomm, string regsresp, reqxsend S0, S1
0x2BxsendfSend frequent datacomm, string regpayloadxsendf S0
0x2CxrequfReceive frequent datacomm, string regdestxrequf S0
0x2DxstopfStop frequent modecommxstopf
0x2ExkeybRead key bytescomm, string regdestxkeyb S0
0x2FxstateRead interface statecomm, string regdestxstate S0
0x30xbootBoot/reset interface (if supported)commxboot
0x31xresetReset interfacecommxreset
0x32xtypeGet interface type stringcomm, string regdestxtype S0
0x33xversGet interface versioncomm, int regdestxvers I0
0x34ergbEmit byte result (unsigned 8-bit)results, intname, valueergb "RPM", I0
0x35ergwEmit word result (unsigned 16-bit)results, intname, valueergw "RPM", I0
0x36ergdEmit dword result (unsigned 32-bit)results, intname, valueergd "RPM", L0
0x37ergiEmit int result (signed 16-bit)results, intname, valueergi "TEMP", I0
0x38ergrEmit real (float) resultresults, float regname, valueergr "LAMBDA", F0
0x39ergsEmit string resultresults, string regname, valueergs "VIN", S0
0x3Aa2fltParse string to floatfloat reg, stringdest, srca2flt F0, S0
0x3BfaddFloat addfloat regs, flagsdest, srcfadd F0, F1
0x3CfsubFloat subtractfloat regs, flagsdest, srcfsub F0, F1
0x3DfmulFloat multiplyfloat regs, flagsdest, srcfmul F0, F1
0x3EfdivFloat dividefloat regs, flagsdest, srcfdiv F0, F1
0x3FergyEmit binary resultresults, string regname, valueergy "RAW", S0
0x40enewsetClear result setresultsenewset
0x41etagConditional result skip based on requested setresults, PCjumpTarget, nameetag #$10, S0
0x42xrepsSet repeat countercomm, intcountxreps I0
0x43gettmrRead error trap maskint reg, trapdestgettmr I0
0x44settmrSet error trap masktrap, intvaluesettmr I0
0x45settSet error trap bittrap, intbitsett I0
0x46clrtClear error trap bittrapclrt
0x47jtJump if trap/error detectedflags, trap, PCoffset, testBit?jt #$20, I0
0x48jntJump if no trap/errorflags, trap, PCoffset, testBit?jnt #$20, I0
0x49addcAdd with carryint regs, flagsdest, srcaddc I0, I1
0x4AsubcSubtract with carry/borrowint regs, flagsdest, srcsubc I0, I1
0x4BbreakRaise user break error (EDIABAS_BIP_0008)break
0x4CclrvClear overflow flagflagsclrv
0x4DeerrThrow error for current trap bittrapeerr
0x4EpopfPop flags from data stackstack, flagspopf
0x4FpushfPush flags to data stackstack, flagspushf
0x50atspRead value at stack offset (without popping)stack, int regdest, offsetatsp I0, #4
0x51swapReverse bytes in string or slicestring reg, idxdest/idxswap S0[#0]#4
0x52setspcSet token separator/index for stokenstring/intseparator, index?setspc S0, I0
0x53srevrsReverse stringstring regdestsrevrs S0
0x54stokenExtract token from stringstring regsdest, srcstoken S0, S1
0x55parbRead parameter byteint reg, paramsdest, indexparb B0, #1
0x56parwRead parameter wordint reg, paramsdest, indexparw I0, #1
0x57parlRead parameter dwordint reg, paramsdest, indexparl L0, #1
0x58parsRead parameter stringstring reg, paramsdest, indexpars S0, #1
0x59fcloseClose file handlefile, int reghandlefclose I0
0x5AjgJump if greater (signed)flags, PCoffsetjg #$10
0x5BjgeJump if greater/equal (signed)flags, PCoffsetjge #$10
0x5CjlJump if less (signed)flags, PCoffsetjl #$10
0x5DjleJump if less/equal (signed)flags, PCoffsetjle #$10
0x5EjaJump if above (unsigned)flags, PCoffsetja #$10
0x5FjbeJump if below/equal (unsigned)flags, PCoffsetjbe #$10
0x60fopenOpen filefile, int/stringhandle, pathfopen I0, S0
0x61freadRead one byte from filefile, int regsdest, handlefread I0, I1
0x62freadlnRead line from file into stringfile, string/intdest, handlefreadln S0, I0
0x63fseekSeek file positionfile, int regshandle, offsetfseek I0, I1
0x64fseeklnSeek file line numberfile, int regshandle, linefseekln I0, I1
0x65ftellGet file positionfile, int regsdest, handleftell I0, I1
0x66ftelllnGet file line numberfile, int regsdest, handleftellln I0, I1
0x67a2fixParse string to intint reg, stringdest, srca2fix I0, S0
0x68fix2fltConvert int to floatfloat reg, intdest, srcfix2flt F0, I0
0x69parrRead parameter floatfloat reg, paramsdest, indexparr F0, #1
0x6AtestBitwise TEST (AND without storing result)int regs, flagsleft, righttest I0, #1
0x6BwaitDelay in secondsdurationwait I0
0x6CdateGet date (string or int)string/int regdestdate S0
0x6DtimeGet time (string or int)string/int regdesttime S0
0x6ExbattGet battery voltagecomm, int regdestxbatt I0
0x6FtospLegacy/unused (no-op)tosp
0x70xdownlLegacy/unused (no-op)xdownl
0x71xgetportRead interface port valuecomm, int regsdest, portxgetport I0, #1
0x72xignitGet ignition voltagecomm, int regdestxignit I0
0x73xlooptLoop testcomm, int regdestxloopt I0
0x74xprogSet program voltagecomm, intvaluexprog I0
0x75xrawRaw send/receivecomm, string regsresp, reqxraw S0, S1
0x76xsetportSet interface port valuecomm, string/intportIndex, valuexsetport S0, I0
0x77xsiresetService interval resetcomm, intvaluexsireset I0
0x78xstoptrLegacy/unused (no-op)xstoptr
0x79fix2hexInt to hex stringstring reg, intdest, srcfix2hex S0, I0
0x7Afix2dezInt to decimal stringstring reg, intdest, srcfix2dez S0, I0
0x7BtabsetSelect active table by nametable, stringnametabset S0
0x7CtabseekSeek row by string valuetable, string regscolumn, valuetabseek S0, S1
0x7DtabgetRead table cell into stringtable, string regsdest, columntabget S0, S1
0x7EstrcatConcatenate strings (alias for SCAT; accepts imm/indexed)string regsdest, srcstrcat S0, "OK"
0x7FparyRead binary parameterstring reg, paramsdestpary S0
0x80parnRead parameter countint reg, paramsdestparn I0
0x81ergcEmit char result (signed 8-bit)results, intname, valueergc "C", B0
0x82erglEmit long result (signed 32-bit)results, intname, valueergl "VAL", L0
0x83tablineSet current table row by indextable, introwtabline I0
0x84xsendrLegacy stub (clears destination)string regdestxsendr S0
0x85xrecvLegacy stub (clears destination)string regdestxrecv S0
0x86xinfoLegacy stub (empty string)string regdestxinfo S0
0x87flt2aFloat to stringstring reg, floatdest, srcflt2a S0, F0
0x88setfltSet float precision (for flt2a)precisionsetflt I0
0x89cfgigConfig get intint reg, stringdest, keycfgig I0, "PORT"
0x8AcfgsgConfig get stringstring regsdest, keycfgsg S0, "DEVICE"
0x8BcfgisConfig set intstring, intkey, valuecfgis "TIMEOUT", I0
0x8Ca2yASCII string to Y (binary)string regsdest, srca2y S0, S1
0x8DxparrawLegacy/unused (no-op)xparraw
0x8Ehex2yHex string to Y (binary)string regsdest, srchex2y S0, S1
0x8FstrcmpString compare (sets flags)string regs, flagsleft, rightstrcmp S0, S1
0x90strlenString length (bytes)int reg, stringdest, srcstrlen I0, S0
0x91y2bcdBinary Y to BCD stringstring regsdest, srcy2bcd S0, S1
0x92y2hexBinary Y to hex stringstring regsdest, srcy2hex S0, S1
0x93shmsetSet shared memory valuestring regs, shmemkey, valueshmset "K", S0
0x94shmgetGet shared memory valuestring regs, shmemdest, keyshmget S0, "K"
0x95ergsysiSystem info result / init requestresults, intname, valueergsysi "!INITIALISIERUNG", I0
0x96flt2fixFloat to intint reg, floatdest, srcflt2fix I0, F0
0x97iupdateUpdate progress textprogresstextiupdate S0
0x98irangeSet progress rangeprogressrangeirange I0
0x99iincposIncrement progress positionprogressdeltaiincpos I0
0x9AtabseekuSeek row by numeric valuetable, string/intcolumn, valuetabseeku S0, I0
0x9Bflt2y4Float to 4-byte Y (IEEE 754 single, LE)string reg, floatdest, srcflt2y4 S0, F0
0x9Cflt2y8Float to 8-byte Y (IEEE 754 double, LE)string reg, floatdest, srcflt2y8 S0, F0
0x9Dy42flt4-byte Y to floatfloat reg, stringdest, srcy42flt F0, S0
0x9Ey82flt8-byte Y to floatfloat reg, stringdest, srcy82flt F0, S0
0x9FplinkLink procedure handlerproc registry, intidplink I0
0xA0pcallLegacy stub (no-op)pcall
0xA1fcompFloat compare (sets flags)float regs, flagsleft, rightfcomp F0, F1
0xA2plinkvLink procedure with validation (stub)proc registry, intidplinkv I0
0xA3ppushPush int to procedure stackproc stack, intsrcppush I0
0xA4ppopPop int from procedure stackproc stack, intdestppop I0
0xA5ppushfltPush float to procedure stackproc stack, floatsrcppushflt F0
0xA6ppopfltPop float from procedure stackproc stack, floatdestppopflt F0
0xA7ppushyPush binary/string to procedure stackproc stack, stringsrcppushy S0
0xA8ppopyPop binary/string from procedure stackproc stack, stringdestppopy S0
0xA9pjtsrProcedure jump to subroutine (stub)pjtsr
0xAAtabsetexTable set (extended alias, same as tabset)table, stringnametabsetex S0
0xABufix2dezUnsigned int to decimal stringstring reg, intdest, srcufix2dez S0, I0
0xACgenerrGenerate error (throws EdiabasError)codegenerr I0
0xADticksGet system ticks (ms since epoch, truncated to 32-bit)int regdestticks I0
0xAEwaitexDelay in millisecondsdurationwaitex I0
0xAFxopenLegacy stub (no-op)xopen
0xB0xcloseLegacy stub (no-op)xclose
0xB1xcloseexLegacy stub (no-op)xcloseex
0xB2xswitchLegacy stub (no-op)xswitch
0xB3xsendexLegacy stub (no-op)xsendex
0xB4xrecvexLegacy stub (clears destination)string regdestxrecvex S0
0xB5ssizeString byte length (cp1252)int reg, stringdest, srcssize I0, S0
0xB6tabcolsGet table column counttable, int regdesttabcols I0
0xB7tabrowsGet table row counttable, int regdesttabrows I0

4.3 Notes on Legacy/Stubbed Opcodes

The following opcodes are no-ops or stubs in the TypeScript interpreter (EdiabasLib compatibility):

  • 0x6F (tosp), 0x70 (xdownl), 0x78 (xstoptr), 0x8D (xparraw)
  • 0x84 (xsendr), 0x85 (xrecv), 0x86 (xinfo)
  • 0xA0 (pcall), 0xA9 (pjtsr)
  • 0xAF (xopen), 0xB0 (xclose), 0xB1 (xcloseex), 0xB2 (xswitch), 0xB3 (xsendex), 0xB4 (xrecvex)

These opcodes either clear their destination register or perform no action. They exist for backward compatibility with legacy EDIABAS programs.


5. Stack Operations

The interpreter maintains two separate stacks:

5.1 Data Stack

The data stack is a byte-addressable stack used for:

  • Pushing/popping integer register values (push, pop)
  • Saving/restoring CPU flags (pushf, popf)
  • Reading stack values at an offset (atsp)

Data Stack Operations

OpcodeMnemonicDescription
0x1EpushPush integer register or immediate value (LE byte order)
0x1FpopPop bytes into integer register (BE reconstruction)
0x4FpushfPush flags as 32-bit value (C=1, Z=2, S=4, V=8)
0x4EpopfPop 32-bit value and restore flags
0x50atspRead value at stack offset (relative to top, no pop)

Push/Pop Byte Order

  • push: Stores bytes in little-endian order (LSB first)
  • pop: Reconstructs value in big-endian order (MSB first) — this is an implementation quirk

Example:

assembly
push I0      ; I0=0x1234 → stack: [0x34, 0x12]
pop I1       ; I1 ← 0x1234 (reconstructed)

5.2 Procedure Stack

The procedure stack is used by procedure-related opcodes for passing parameters to external procedures:

OpcodeMnemonicDescription
0xA3ppushPush integer to procedure stack
0xA4ppopPop integer from procedure stack
0xA5ppushfltPush float to procedure stack
0xA6ppopfltPop float from procedure stack
0xA7ppushyPush binary/string to procedure stack
0xA8ppopyPop binary/string from procedure stack

The procedure stack is separate from the data stack and is only used for external procedure calls (via plink).

5.3 Call Stack

The call stack stores return addresses for subroutine calls:

  • jtsr (0x0C): Push current PC to call stack, jump to offset
  • ret (0x0D): Pop return address from call stack, jump to it

6. String and Binary Handling

String registers (S0–SF) store binary data internally, encoded as CP1252 bytes but represented as UTF-8 strings in the TypeScript implementation.

6.1 String Encoding

  • Storage: Internally stored as UTF-8 strings (converted from CP1252 bytes)
  • Operations: Binary operations use utf8ToCp1252() to convert back to bytes
  • Max length: Default 255 bytes (configurable via RegisterSetOptions.maxStringSize)

6.2 String Operations

OperationOpcodeDescription
move0x00Copy string or indexed slice
clear0x01Clear string (set to empty)
scmp0x20Binary compare (sets Z flag if equal)
scat0x21Concatenate (append src to dest)
scut0x22Cut N bytes from end
slen0x23Get byte length
spaste0x24Insert bytes at indexed position
serase0x25Remove bytes from indexed range
swap0x51Reverse byte order (entire string or slice)
srevrs0x53Reverse entire string
stoken0x54Extract token by separator
strcmp0x8FString compare (sets flags)
strlen0x90String length (bytes)
ssize0xB5String size in bytes (CP1252)

6.3 Indexed String Operands

Indexed operands allow operations on string slices:

Sx[index]          — slice starting at index
Sx[index]#length   — slice with fixed length
Sx[reg]            — slice with register index
Sx[reg,#offset]    — slice with register index + offset

Examples:

assembly
move I0, S0[#2]#4    ; Read 4 bytes from S0 starting at offset 2
spaste S1[#0], S2    ; Insert S2 at the start of S1
swap S0[#0]#4        ; Reverse first 4 bytes of S0

6.4 Binary Conversion Operations

OperationOpcodeDescription
a2y0x8CASCII string to binary (Y-register)
hex2y0x8EHex string to binary (e.g., "48656C6C6F" → bytes)
y2bcd0x91Binary to BCD string
y2hex0x92Binary to hex string (uppercase)

7. Result Collection

Results are collected using erg* opcodes and returned to the caller after job execution.

7.1 Result Types

OpcodeMnemonicTypeSizeDescription
0x34ergbbyte8-bitUnsigned byte (0–255)
0x35ergwword16-bitUnsigned word (0–65535)
0x36ergddword32-bitUnsigned dword (0–4294967295)
0x81ergcchar8-bitSigned byte (-128 to 127)
0x37ergiint16-bitSigned word (-32768 to 32767)
0x82ergllong32-bitSigned dword (-2147483648 to ...)
0x38ergrreal64-bitIEEE-754 double-precision float
0x39ergsstringVariableString (CP1252)
0x3FergybinaryVariableBinary data

7.2 Result Management

  • enewset (0x40): Clear all results (start new result set)
  • etag (0x41): Conditional result skip — if a "results request" set is provided and the result name is not in it, jump to the specified offset

7.3 System Results

  • ergsysi (0x95): Emit system info result or set initialization request flag
    • If name is "!INITIALISIERUNG" and value is non-zero, sets the requestInit flag

7.4 Result Naming

Result names are case-insensitive (converted to uppercase internally). The result name can be:

  • An immediate string (e.g., ergs "VIN", S0)
  • A string register (e.g., ergs S1, S0)

8. Error Handling and Trap Bits

The interpreter supports error trapping via trap bits, allowing programs to handle specific error conditions.

8.1 Trap Bit System

Error trapping uses:

  • Error trap mask (errorTrapMask): 32-bit bitmask indicating which errors should be trapped
  • Error trap bit number (errorTrapBitNr): The last trap bit that was set

8.2 Trap Bit Operations

OpcodeMnemonicDescription
0x43gettmrRead error trap mask into integer register
0x44settmrSet error trap mask from integer register
0x45settSet error trap bit (store bit number)
0x46clrtClear error trap bit
0x47jtJump if trap detected (optionally test bit)
0x48jntJump if no trap detected (optionally test bit)
0x4DeerrThrow error for current trap bit

8.3 Trap Bit to Error Code Mapping

The TrapBitDict maps error codes to trap bit numbers:

Error CodeTrap Bit
EDIABAS_BIP_00022
EDIABAS_BIP_00066
EDIABAS_BIP_00118
EDIABAS_BIP_00099
EDIABAS_BIP_001010
EDIABAS_IFH_000111
EDIABAS_IFH_000212
EDIABAS_IFH_000313
EDIABAS_IFH_000414
EDIABAS_IFH_000515
EDIABAS_IFH_000616
EDIABAS_IFH_000717
EDIABAS_IFH_000818
EDIABAS_IFH_000919
EDIABAS_IFH_001020
EDIABAS_IFH_001121
EDIABAS_IFH_001222
EDIABAS_IFH_001323
EDIABAS_IFH_001424
EDIABAS_IFH_001525
EDIABAS_IFH_001626
EDIABAS_IFH_006928
EDIABAS_IFH_007429

8.4 Error Handling Example

assembly
settmr #$0800     ; Enable trap for bit 11 (EDIABAS_IFH_0001)
xconnect          ; Try to connect (may fail)
jt error_handler  ; Jump if error trapped
; ... success path ...
error_handler:
  eerr            ; Re-throw the error

9. Job Execution Flow

9.1 Execution Model

The interpreter executes jobs using a fetch-decode-execute cycle:

  1. Fetch: Read opcode byte at PC
  2. Decode: Read addressing mode byte, decode operands
  3. Execute: Call opcode handler, update PC
  4. Repeat: Until eoj (0x1D) or error

9.2 Job Initialization

To execute a job:

  1. Call Interpreter.start(jobName, parameters)
  2. Interpreter resolves job name to bytecode offset
  3. Registers, flags, stacks, and state are initialized
  4. Parameters are loaded into ParameterSet

9.3 Job Termination

A job terminates when:

  • eoj (0x1D): Normal completion (sets halted = true)
  • Error thrown: Exception propagates to caller
  • break (0x4B): User break (throws EDIABAS_BIP_0008)

9.4 Return Value

Interpreter.execute() returns a ResultCollector containing all results emitted by erg* opcodes.


10. Communication Interface

Communication opcodes (x* opcodes) interact with an external CommunicationInterface (e.g., OBD-II, K-line, ENET).

10.1 Communication Lifecycle

OpcodeMnemonicDescription
0x26xconnectOpen/connect interface
0x27xhangupClose/disconnect interface
0x31xresetReset interface
0x30xbootBoot/reset interface (if supported)

10.2 Configuration

OpcodeMnemonicDescription
0x28xsetparSet communication parameters (from buffer)
0x29xawlenSet answer lengths (from buffer)
0x42xrepsSet repeat counter

10.3 Data Transfer

OpcodeMnemonicDescription
0x2AxsendSend request, receive response
0x75xrawRaw send/receive (no protocol processing)
0x2BxsendfSend frequent data (continuous transmission)
0x2CxrequfReceive frequent data
0x2DxstopfStop frequent mode

10.4 Interface Information

OpcodeMnemonicDescription
0x32xtypeGet interface type string
0x33xversGet interface version
0x2FxstateGet interface state
0x2ExkeybRead key bytes

10.5 Hardware Control

OpcodeMnemonicDescription
0x6ExbattGet battery voltage (mV)
0x72xignitGet ignition voltage (mV)
0x74xprogSet programming voltage (mV)
0x71xgetportRead interface port value
0x76xsetportSet interface port value
0x73xlooptLoop test
0x77xsiresetService interval reset

11. File System Operations

File opcodes provide access to the host file system (if a FileSystem implementation is provided).

11.1 File Operations

OpcodeMnemonicDescription
0x60fopenOpen file (handle ← int, path ← string)
0x59fcloseClose file handle
0x61freadRead one byte from file
0x62freadlnRead line from file (into string register)
0x63fseekSeek file position (byte offset)
0x64fseeklnSeek file line number
0x65ftellGet current file position (bytes)
0x66ftelllnGet current file line number

11.2 File Operations Example

assembly
fopen I0, S0      ; Open file at path in S0, store handle in I0
freadln S1, I0    ; Read line from file I0 into S1
fclose I0         ; Close file I0

12. Table Operations

Table opcodes provide access to embedded lookup tables (parsed from EDIABAS OBJECT files).

12.1 Table Management

OpcodeMnemonicDescription
0x7BtabsetSelect active table by name
0xAAtabsetexSelect active table (alias for tabset)
0x83tablineSet current row by index
0xB6tabcolsGet column count
0xB7tabrowsGet row count (excluding header)

12.2 Table Data Access

OpcodeMnemonicDescription
0x7CtabseekSeek row by string value (column, value)
0x9AtabseekuSeek row by numeric value (column, value)
0x7DtabgetRead cell value into string register

12.3 Table Operations Example

assembly
tabset S0         ; Select table by name in S0
tabseek S1, S2    ; Find row where column S1 equals value S2
tabget S3, S4     ; Read value from column S4 into S3

Appendix A: Operand Encoding Examples

Example 1: Register to Register

move I0, I1

Encoding:

[0x00][0x11][0x10][0x11]
  ^     ^    ^     ^
opcode mode  I0    I1
      (REG,REG)

Example 2: Immediate to Register

adds B0, #$42

Encoding:

[0x04][0x15][0x00][0x42]
  ^     ^    ^     ^
opcode mode  B0   imm8
      (REG,IMM8)

Example 3: Indexed String Operand

move I0, S0[#2]#4

Encoding:

[0x00][0xC1][0x10][0x1C][0x02][0x00][0x04][0x00]
  ^     ^    ^     ^     ^-------^   ^-------^
opcode mode  I0    S0    index(LE)   length(LE)
      (IDX_IMM_LEN_IMM, REG)

Example 4: String Immediate

ergs "VIN", S0

Encoding:

[0x39][0x81][0x04][0x00]['V']['I']['N'][0x00][0x1C]
  ^     ^    ^-------^   ^-----------------^   ^
opcode mode  str_len     string_data(CP1252)  S0
      (IMM_STR, REG_S)

Appendix B: Implementation Notes

B.1 Byte Order

  • File headers: Little-endian
  • Immediates: Little-endian (IMM16, IMM32)
  • Stack push: Little-endian byte order
  • Stack pop: Big-endian reconstruction (implementation quirk)

B.2 Type Enforcement

The interpreter strictly enforces operand types:

  • Integer opcodes (adds, subb, etc.) reject float or string registers
  • Float opcodes (fadd, fsub, etc.) require float registers
  • String opcodes (scat, slen, etc.) require string registers

Violating type constraints throws EdiabasError with code REGISTER_ERROR.

B.3 String Encoding

  • Storage: Strings are stored as UTF-8 in JavaScript/TypeScript
  • Operations: Binary operations convert to CP1252 bytes via utf8ToCp1252()
  • Indexed access: Operates on CP1252 byte offsets, not UTF-8 character offsets

B.4 Progress Reporting

The interpreter supports progress reporting for long-running jobs:

  • iupdate (0x97): Update progress text
  • irange (0x98): Set progress range (total steps)
  • iincpos (0x99): Increment progress position

External code can poll progressText, progressRange, and progressPos from the interpreter state.


Appendix C: Disassembler

The @ediabasx/best-parser package includes a disassembler that converts bytecode to human-readable assembly:

typescript
import { disassemble } from "@ediabasx/best-parser";

const instructions = disassemble(code, offset);
for (const instr of instructions) {
  console.log(`${instr.offset.toString(16)}: ${instr.mnemonic} ${instr.operands.join(", ")}`);
}

Example output:

0: move I0, #$0010
5: adds B0, B1
7: jz #$0020
c: jtsr #$0100
11: eoj

Document Metadata

  • Generated from: packages/interpreter/src/ and packages/best-parser/src/
  • Interpreter version: As of commit 0e3ebe8 (2026-02-07)
  • Opcode count: 184 (0x00–0xB7)
  • Register types: 6 (B, A, I, L, S, F)
  • Addressing modes: 16 (0x0–0xF)

For implementation details, refer to the source code in the emdzej/ediabasx repository.