359 lines
17 KiB
C
359 lines
17 KiB
C
// opcodes.h -- DVX BASIC bytecode instruction definitions
|
|
//
|
|
// Stack-based p-code for the DVX BASIC virtual machine.
|
|
// Embeddable: no DVX dependencies, pure C.
|
|
|
|
#ifndef DVXBASIC_OPCODES_H
|
|
#define DVXBASIC_OPCODES_H
|
|
|
|
// ============================================================
|
|
// Data type tags (used in Value representation)
|
|
// ============================================================
|
|
|
|
#define BAS_TYPE_INTEGER 0 // 16-bit signed
|
|
#define BAS_TYPE_LONG 1 // 32-bit signed
|
|
#define BAS_TYPE_SINGLE 2 // 32-bit float
|
|
#define BAS_TYPE_DOUBLE 3 // 64-bit float
|
|
#define BAS_TYPE_STRING 4 // ref-counted dynamic string
|
|
#define BAS_TYPE_BOOLEAN 5 // True (-1) or False (0)
|
|
#define BAS_TYPE_ARRAY 6 // ref-counted array
|
|
#define BAS_TYPE_UDT 7 // ref-counted user-defined type
|
|
#define BAS_TYPE_OBJECT 8 // opaque host object (form, control, etc.)
|
|
#define BAS_TYPE_REF 9 // ByRef pointer to a BasValueT slot
|
|
|
|
// ============================================================
|
|
// Stack operations
|
|
// ============================================================
|
|
|
|
#define OP_NOP 0x00
|
|
#define OP_PUSH_INT16 0x01 // [int16] push 16-bit integer
|
|
#define OP_PUSH_INT32 0x02 // [int32] push 32-bit integer
|
|
#define OP_PUSH_FLT32 0x03 // [float32] push 32-bit float
|
|
#define OP_PUSH_FLT64 0x04 // [float64] push 64-bit float
|
|
#define OP_PUSH_STR 0x05 // [uint16 idx] push string from constant pool
|
|
#define OP_PUSH_TRUE 0x06 // push boolean True (-1)
|
|
#define OP_PUSH_FALSE 0x07 // push boolean False (0)
|
|
#define OP_POP 0x08 // discard top of stack
|
|
#define OP_DUP 0x09 // duplicate top of stack
|
|
|
|
// ============================================================
|
|
// Variable access
|
|
// ============================================================
|
|
|
|
#define OP_LOAD_LOCAL 0x10 // [uint16 idx] push local variable
|
|
#define OP_STORE_LOCAL 0x11 // [uint16 idx] pop to local variable
|
|
#define OP_LOAD_GLOBAL 0x12 // [uint16 idx] push global variable
|
|
#define OP_STORE_GLOBAL 0x13 // [uint16 idx] pop to global variable
|
|
#define OP_LOAD_REF 0x14 // dereference top of stack (ByRef)
|
|
#define OP_STORE_REF 0x15 // store through reference on stack
|
|
#define OP_LOAD_ARRAY 0x16 // [uint8 dims] indices on stack, array ref below
|
|
#define OP_STORE_ARRAY 0x17 // [uint8 dims] value, indices, array ref on stack
|
|
#define OP_LOAD_FIELD 0x18 // [uint16 fieldIdx] load UDT field
|
|
#define OP_STORE_FIELD 0x19 // [uint16 fieldIdx] store UDT field
|
|
#define OP_PUSH_LOCAL_ADDR 0x1A // [uint16 idx] push address of local (for ByRef)
|
|
#define OP_PUSH_GLOBAL_ADDR 0x1B // [uint16 idx] push address of global (for ByRef)
|
|
#define OP_STORE_ARRAY_FIELD 0x1C // [uint8 dims, uint16 fieldIdx] value, indices, array on stack
|
|
|
|
// ============================================================
|
|
// Arithmetic (integer)
|
|
// ============================================================
|
|
|
|
#define OP_ADD_INT 0x20
|
|
#define OP_SUB_INT 0x21
|
|
#define OP_MUL_INT 0x22
|
|
#define OP_IDIV_INT 0x23 // integer divide (\)
|
|
#define OP_MOD_INT 0x24
|
|
#define OP_NEG_INT 0x25
|
|
|
|
// ============================================================
|
|
// Arithmetic (float)
|
|
// ============================================================
|
|
|
|
#define OP_ADD_FLT 0x26
|
|
#define OP_SUB_FLT 0x27
|
|
#define OP_MUL_FLT 0x28
|
|
#define OP_DIV_FLT 0x29 // float divide (/)
|
|
#define OP_NEG_FLT 0x2A
|
|
#define OP_POW 0x2B // exponentiation (^)
|
|
|
|
// ============================================================
|
|
// String operations
|
|
// ============================================================
|
|
|
|
#define OP_STR_CONCAT 0x30
|
|
#define OP_STR_LEFT 0x31
|
|
#define OP_STR_RIGHT 0x32
|
|
#define OP_STR_MID 0x33 // 3 args: str, start, len
|
|
#define OP_STR_MID2 0x34 // 2 args: str, start (to end)
|
|
#define OP_STR_LEN 0x35
|
|
#define OP_STR_INSTR 0x36 // 2 args: str, find
|
|
#define OP_STR_INSTR3 0x37 // 3 args: start, str, find
|
|
#define OP_STR_UCASE 0x38
|
|
#define OP_STR_LCASE 0x39
|
|
#define OP_STR_TRIM 0x3A
|
|
#define OP_STR_LTRIM 0x3B
|
|
#define OP_STR_RTRIM 0x3C
|
|
#define OP_STR_CHR 0x3D
|
|
#define OP_STR_ASC 0x3E
|
|
#define OP_STR_SPACE 0x3F
|
|
|
|
// ============================================================
|
|
// Comparison (push boolean result)
|
|
// ============================================================
|
|
|
|
#define OP_CMP_EQ 0x40
|
|
#define OP_CMP_NE 0x41
|
|
#define OP_CMP_LT 0x42
|
|
#define OP_CMP_GT 0x43
|
|
#define OP_CMP_LE 0x44
|
|
#define OP_CMP_GE 0x45
|
|
|
|
// ============================================================
|
|
// Logical / bitwise
|
|
// ============================================================
|
|
|
|
#define OP_AND 0x48
|
|
#define OP_OR 0x49
|
|
#define OP_NOT 0x4A
|
|
#define OP_XOR 0x4B
|
|
#define OP_EQV 0x4C
|
|
#define OP_IMP 0x4D
|
|
|
|
// ============================================================
|
|
// Control flow
|
|
// ============================================================
|
|
|
|
#define OP_JMP 0x50 // [int16 offset] unconditional jump
|
|
#define OP_JMP_TRUE 0x51 // [int16 offset] jump if TOS is true
|
|
#define OP_JMP_FALSE 0x52 // [int16 offset] jump if TOS is false
|
|
#define OP_CALL 0x53 // [uint16 addr] [uint8 argc] [uint8 baseSlot]
|
|
#define OP_GOSUB_RET 0x54 // pop PC from eval stack, jump (GOSUB return)
|
|
#define OP_RET 0x55 // return from subroutine
|
|
#define OP_RET_VAL 0x56 // return from function (value on stack)
|
|
#define OP_FOR_INIT 0x57 // [uint16 varIdx] [uint8 isLocal] init FOR
|
|
#define OP_FOR_NEXT 0x58 // [uint16 varIdx] [uint8 isLocal] [int16 loopTop]
|
|
#define OP_FOR_POP 0x59 // pop top FOR stack entry (for EXIT FOR)
|
|
|
|
// ============================================================
|
|
// Type conversion
|
|
// ============================================================
|
|
|
|
#define OP_CONV_INT_FLT 0x60 // int -> float
|
|
#define OP_CONV_FLT_INT 0x61 // float -> int (banker's rounding)
|
|
#define OP_CONV_INT_STR 0x62 // int -> string
|
|
#define OP_CONV_STR_INT 0x63 // string -> int (VAL)
|
|
#define OP_CONV_FLT_STR 0x64 // float -> string
|
|
#define OP_CONV_STR_FLT 0x65 // string -> float (VAL)
|
|
#define OP_CONV_INT_LONG 0x66 // int16 -> int32
|
|
#define OP_CONV_LONG_INT 0x67 // int32 -> int16
|
|
|
|
// ============================================================
|
|
// I/O
|
|
// ============================================================
|
|
|
|
#define OP_PRINT 0x70 // print TOS to current output
|
|
#define OP_PRINT_NL 0x71 // print newline
|
|
#define OP_PRINT_TAB 0x72 // print tab (14-column zones)
|
|
#define OP_PRINT_SPC 0x73 // [uint8 n] print n spaces
|
|
#define OP_INPUT 0x74 // read line into string on stack
|
|
#define OP_FILE_OPEN 0x75 // [uint8 mode] filename, channel# on stack
|
|
#define OP_FILE_CLOSE 0x76 // channel# on stack
|
|
#define OP_FILE_PRINT 0x77 // channel#, value on stack
|
|
#define OP_FILE_INPUT 0x78 // channel# on stack, push string
|
|
#define OP_FILE_EOF 0x79 // channel# on stack, push boolean
|
|
#define OP_FILE_LINE_INPUT 0x7A // channel# on stack, push string
|
|
|
|
// ============================================================
|
|
// UI / Event (used when form system is active)
|
|
// ============================================================
|
|
//
|
|
// All UI opcodes are name-based: control references, property names,
|
|
// method names, and form names are strings resolved at runtime.
|
|
// This allows third-party widget DXEs and new properties to work
|
|
// without recompiling the BASIC runtime.
|
|
//
|
|
// Stack convention:
|
|
// LOAD_PROP: ... controlRef propNameStr -> ... value
|
|
// STORE_PROP: ... controlRef propNameStr value -> ...
|
|
// CALL_METHOD: ... controlRef methodNameStr [args] -> ... [result]
|
|
// LOAD_FORM: ... formNameStr -> ... formRef
|
|
// CREATE_CTRL: ... formRef typeNameStr nameStr -> ... controlRef
|
|
|
|
#define OP_LOAD_PROP 0x80 // pop propName, pop ctrlRef, push property value
|
|
#define OP_STORE_PROP 0x81 // pop value, pop propName, pop ctrlRef, set property
|
|
#define OP_CALL_METHOD 0x82 // [uint8 argc] pop methodName, pop ctrlRef, pop args, push result
|
|
#define OP_LOAD_FORM 0x83 // pop formName string, push form reference
|
|
#define OP_UNLOAD_FORM 0x84 // pop formRef, unload it
|
|
#define OP_SHOW_FORM 0x85 // [uint8 modal] pop formRef, show it
|
|
#define OP_HIDE_FORM 0x86 // pop formRef, hide it
|
|
#define OP_DO_EVENTS 0x87
|
|
#define OP_MSGBOX 0x88 // pop flags, pop message string, push result
|
|
#define OP_INPUTBOX 0x89 // pop default, pop title, pop prompt, push result string
|
|
#define OP_ME_REF 0x8A // push current form reference
|
|
#define OP_CREATE_CTRL 0x8B // pop name, pop typeName, pop formRef, push controlRef
|
|
#define OP_FIND_CTRL 0x8C // pop ctrlName, pop formRef, push controlRef
|
|
#define OP_CTRL_REF 0x8D // [uint16 nameConstIdx] push named control on current form
|
|
#define OP_FIND_CTRL_IDX 0x8E // pop index, pop ctrlName, pop formRef, push ctrlRef
|
|
#define OP_LOAD_FORM_VAR 0x8F // [uint16 idx] push currentFormVars[idx]
|
|
#define OP_STORE_FORM_VAR 0x9B // [uint16 idx] pop, store to currentFormVars[idx]
|
|
#define OP_PUSH_FORM_ADDR 0x9C // [uint16 idx] push ¤tFormVars[idx] (ByRef)
|
|
#define OP_CREATE_CTRL_EX 0x9D // pop parentRef, pop name, pop type, pop formRef, push ctrlRef
|
|
#define OP_CREATE_FORM 0xF0 // pop height, pop width, pop nameStr, push formRef
|
|
#define OP_SET_EVENT 0xF1 // pop handlerNameStr, pop eventNameStr, pop ctrlRef
|
|
#define OP_REMOVE_CTRL 0xF2 // pop ctrlNameStr, pop formRef
|
|
|
|
// ============================================================
|
|
// Array / misc
|
|
// ============================================================
|
|
|
|
#define OP_DIM_ARRAY 0x90 // [uint8 dims] [uint8 type] bounds on stack
|
|
#define OP_REDIM 0x91 // [uint8 dims] [uint8 preserve] bounds on stack
|
|
#define OP_ERASE 0x92 // array ref on stack
|
|
#define OP_LBOUND 0x93 // [uint8 dim] array ref on stack
|
|
#define OP_UBOUND 0x94 // [uint8 dim] array ref on stack
|
|
#define OP_ON_ERROR 0x95 // [int16 handler] set error handler (0 = disable)
|
|
#define OP_RESUME 0x96 // resume after error
|
|
#define OP_RESUME_NEXT 0x97 // resume at next statement
|
|
#define OP_RAISE_ERR 0x98 // error number on stack
|
|
#define OP_ERR_NUM 0x99 // push current error number
|
|
#define OP_ERR_CLEAR 0x9A // clear error state
|
|
|
|
// ============================================================
|
|
// Math built-ins (single opcode each for common functions)
|
|
// ============================================================
|
|
|
|
#define OP_MATH_ABS 0xA0
|
|
#define OP_MATH_INT 0xA1 // floor
|
|
#define OP_MATH_FIX 0xA2 // truncate toward zero
|
|
#define OP_MATH_SGN 0xA3
|
|
#define OP_MATH_SQR 0xA4
|
|
#define OP_MATH_SIN 0xA5
|
|
#define OP_MATH_COS 0xA6
|
|
#define OP_MATH_TAN 0xA7
|
|
#define OP_MATH_ATN 0xA8
|
|
#define OP_MATH_LOG 0xA9
|
|
#define OP_MATH_EXP 0xAA
|
|
#define OP_MATH_RND 0xAB
|
|
#define OP_MATH_RANDOMIZE 0xAC // seed on stack (or TIMER if -1)
|
|
#define OP_RGB 0xAD // pop b, g, r; push LONG = (r<<16)|(g<<8)|b
|
|
#define OP_GET_RED 0xAE // pop LONG color; push (color>>16) & 0xFF
|
|
#define OP_GET_GREEN 0xAF // pop LONG color; push (color>>8) & 0xFF
|
|
|
|
// ============================================================
|
|
// Conversion built-ins
|
|
// ============================================================
|
|
|
|
#define OP_STR_VAL 0xB0 // VAL(s$) -> number
|
|
#define OP_STR_STRF 0xB1 // STR$(n) -> string
|
|
#define OP_STR_HEX 0xB2 // HEX$(n) -> string
|
|
#define OP_STR_STRING 0xB3 // STRING$(n, char) -> string
|
|
|
|
// ============================================================
|
|
// Extended built-ins
|
|
// ============================================================
|
|
|
|
#define OP_MATH_TIMER 0xB4 // push seconds since midnight as DOUBLE
|
|
#define OP_DATE_STR 0xB5 // push DATE$ string "MM-DD-YYYY"
|
|
#define OP_TIME_STR 0xB6 // push TIME$ string "HH:MM:SS"
|
|
#define OP_SLEEP 0xB7 // pop seconds, sleep
|
|
#define OP_ENVIRON 0xB8 // pop env var name, push value string
|
|
|
|
// ============================================================
|
|
// DATA/READ/RESTORE
|
|
// ============================================================
|
|
|
|
#define OP_READ_DATA 0xB9 // push next value from data pool
|
|
#define OP_RESTORE 0xBA // reset data pointer to 0
|
|
|
|
// ============================================================
|
|
// WRITE # (comma-delimited with quoted strings)
|
|
// ============================================================
|
|
|
|
#define OP_FILE_WRITE 0xBB // pop channel + value, write in WRITE format
|
|
#define OP_FILE_WRITE_SEP 0xBC // pop channel, write comma separator
|
|
#define OP_FILE_WRITE_NL 0xBD // pop channel, write newline
|
|
|
|
// ============================================================
|
|
// Random/Binary file I/O
|
|
// ============================================================
|
|
|
|
#define OP_FILE_GET 0xBE // pop channel + recno, read record, push value
|
|
#define OP_FILE_PUT 0xBF // pop channel + recno + value, write record
|
|
#define OP_FILE_SEEK 0xC0 // pop channel + position, seek
|
|
#define OP_FILE_LOF 0xC1 // pop channel, push file length
|
|
#define OP_FILE_LOC 0xC2 // pop channel, push current position
|
|
#define OP_FILE_FREEFILE 0xC3 // push next free channel number
|
|
#define OP_FILE_INPUT_N 0xC4 // pop channel + n, read n chars, push string
|
|
|
|
// ============================================================
|
|
// Fixed-length strings and MID$ assignment
|
|
// ============================================================
|
|
|
|
#define OP_STR_FIXLEN 0xC5 // [uint16 len] pop string, pad/truncate, push
|
|
#define OP_STR_MID_ASGN 0xC6 // pop replacement, len, start, str; push modified
|
|
|
|
// ============================================================
|
|
// PRINT USING
|
|
// ============================================================
|
|
|
|
#define OP_PRINT_USING 0xC7 // pop format + value, push formatted string
|
|
|
|
// ============================================================
|
|
// SPC(n) and TAB(n) with stack-based argument
|
|
// ============================================================
|
|
|
|
#define OP_PRINT_TAB_N 0xC8 // pop column count, print spaces to reach column
|
|
#define OP_PRINT_SPC_N 0xC9 // pop count, print that many spaces
|
|
#define OP_FORMAT 0xCA // pop format string + value, push formatted string
|
|
#define OP_SHELL 0xCB // pop command string, call system(), push return value
|
|
#define OP_COMPARE_MODE 0xCC // [uint8 mode] set string compare mode (0=binary, 1=text)
|
|
|
|
// ============================================================
|
|
// External library calls (DECLARE LIBRARY)
|
|
// ============================================================
|
|
//
|
|
// Calls native functions exported by dynamically loaded libraries.
|
|
// The VM resolves library + function name on first call via a host
|
|
// callback, caches the result, and marshals arguments through a
|
|
// second callback. This allows BASIC programs to use any library
|
|
// (serial, security, third-party) without recompiling the runtime.
|
|
|
|
#define OP_CALL_EXTERN 0xCD // [uint16 libNameIdx] [uint16 funcNameIdx] [uint8 argc] [uint8 retType]
|
|
|
|
#define OP_GET_BLUE 0xD0 // pop LONG color; push color & 0xFF
|
|
|
|
// App object
|
|
#define OP_APP_PATH 0xDD // push App.Path string
|
|
#define OP_APP_CONFIG 0xDE // push App.Config string
|
|
#define OP_APP_DATA 0xDF // push App.Data string
|
|
|
|
// INI file operations
|
|
#define OP_INI_READ 0xE0 // pop default, pop key, pop section, pop file, push string
|
|
#define OP_INI_WRITE 0xE1 // pop value, pop key, pop section, pop file
|
|
|
|
// Filesystem operations
|
|
#define OP_FS_KILL 0xE2 // pop filename, delete file
|
|
#define OP_FS_NAME 0xE3 // pop newname, pop oldname, rename
|
|
#define OP_FS_FILECOPY 0xE4 // pop dst, pop src, copy file
|
|
#define OP_FS_MKDIR 0xE5 // pop path, create directory
|
|
#define OP_FS_RMDIR 0xE6 // pop path, remove directory
|
|
#define OP_FS_CHDIR 0xE7 // pop path, change directory
|
|
#define OP_FS_CHDRIVE 0xE8 // pop drive, change drive
|
|
#define OP_FS_CURDIR 0xE9 // push current directory string
|
|
#define OP_FS_DIR 0xEA // pop pattern, push first matching filename
|
|
#define OP_FS_DIR_NEXT 0xEB // push next matching filename (no args)
|
|
#define OP_FS_FILELEN 0xEC // pop filename, push file length
|
|
#define OP_FS_GETATTR 0xED // pop filename, push attributes integer
|
|
#define OP_FS_SETATTR 0xEE // pop attrs, pop filename, set attributes
|
|
|
|
// Debug
|
|
#define OP_LINE 0xEF // [uint16 lineNum] set current source line for debugger
|
|
|
|
// ============================================================
|
|
// Halt
|
|
// ============================================================
|
|
|
|
#define OP_END 0xFE // explicit END statement -- terminates program
|
|
#define OP_HALT 0xFF // implicit end of module
|
|
|
|
#endif // DVXBASIC_OPCODES_H
|