decompiled_code:
int sxc_func_invoke(__int64 a1, int a2, unsigned int a3, ...)
{
char *v3; // r12
char *v4; // r13
__int64 v5; // rbx
__int64 v6; // rbx
unsigned int *v7; // rcx
int result; // eax
unsigned int v9; // er14
int v10; // ebx
__int64 v11; // [rsp-400h] [rbp-630h] BYREF
__va_list_tag *v12; // [rsp+0h] [rbp-230h]
unsigned int v13; // [rsp+8h] [rbp-228h]
int v14; // [rsp+Ch] [rbp-224h]
char v15[256]; // [rsp+10h] [rbp-220h] BYREF
__int64 v16; // [rsp+110h] [rbp-120h] BYREF
int v17; // [rsp+118h] [rbp-118h]
gcc_va_list va; // [rsp+138h] [rbp-F8h] BYREF

v14 = a2;
v13 = a3;
v3 = (char *)&v11;
puts("in sxc_function_invoke");
if ( v14 > 32 )
{
v6 = v14;
v4 = (char *)sxc_alloc(*(_QWORD *)(a1 + 16), (unsigned int)(40 * v14));
v3 = &v4[8 * v6];
v16 = *(_QWORD *)(a1 + 16);
v17 = 0;
va_start(va, a3);
sxc_value_getv(&v16, v13, va);
puts("done skipping dest");
}
else
{
v16 = *(_QWORD *)(a1 + 16);
v17 = 0;
va_start(va, a3);
sxc_value_getv(&v16, v13, va);
puts("done skipping dest");
if ( v14 <= 0 )
{
v4 = v15;
goto LABEL_11;
}
v4 = v15;
}
v5 = 0LL;
v12 = va;
do
{
*(_QWORD *)&v4[8 * v5] = v3;
*(_QWORD *)v3 = *(_QWORD *)(a1 + 16);
if ( va[0].gp_offset > 0x2F )
{
v7 = (unsigned int *)va[0].overflow_arg_area;
va[0].overflow_arg_area = (char *)va[0].overflow_arg_area + 8;
}
else
{
v7 = (unsigned int *)((char *)va[0].reg_save_area + va[0].gp_offset);
va[0].gp_offset += 8;
}
sxc_value_setv(*(_QWORD *)&v4[8 * v5], *v7, v12);
printf("done setting arg %d\n", (unsigned int)v5);
sxc_value_snormalize(*(_QWORD *)&v4[8 * v5]);
printf("done interning arg %d\n", (unsigned int)v5++);
v3 += 32;
}
while ( v14 > (int)v5 );
LABEL_11:
(**(void (__fastcall ***)(_QWORD, char *, _QWORD, __int64 *))(a1 + 8))(*(_QWORD *)a1, v4, (unsigned int)v14, &v16);
puts("done invoking func");
result = v13;
if ( v13 )
{
if ( v13 == -1 )
sxc_value_cnormalize(&v16);
va_end(va);
va_start(va, a3);
v9 = v13;
v10 = sxc_value_getv(&v16, v13, va);
result = puts("done extracting return_value");
if ( v10 != 1 )
result = sxc_typeerror(*(_QWORD *)(a1 + 16), "return value", v9, &v16);
}
return result;
}

canonical_decompiled_code:
int func0(__int64 a1, int a2, unsigned int a3, ...)
{
char *v3; // r12
char *v4; // r13
__int64 v5; // rbx
__int64 v6; // rbx
unsigned int *v7; // rcx
int result; // eax
unsigned int v9; // er14
int v10; // ebx
__int64 v11; // [rsp-400h] [rbp-630h] BYREF
__va_list_tag *v12; // [rsp+0h] [rbp-230h]
unsigned int v13; // [rsp+8h] [rbp-228h]
int v14; // [rsp+Ch] [rbp-224h]
char v15[256]; // [rsp+10h] [rbp-220h] BYREF
__int64 v16; // [rsp+110h] [rbp-120h] BYREF
int v17; // [rsp+118h] [rbp-118h]
gcc_va_list va; // [rsp+138h] [rbp-F8h] BYREF

v14 = a2;
v13 = a3;
v3 = (char *)&v11;
puts("in sxc_function_invoke");
if ( v14 > 32 )
{
v6 = v14;
v4 = (char *)sxc_alloc(*(_QWORD *)(a1 + 16), (unsigned int)(40 * v14));
v3 = &v4[8 * v6];
v16 = *(_QWORD *)(a1 + 16);
v17 = 0;
va_start(va, a3);
sxc_value_getv(&v16, v13, va);
puts("done skipping dest");
}
else
{
v16 = *(_QWORD *)(a1 + 16);
v17 = 0;
va_start(va, a3);
sxc_value_getv(&v16, v13, va);
puts("done skipping dest");
if ( v14 <= 0 )
{
v4 = v15;
goto LABEL_11;
}
v4 = v15;
}
v5 = 0LL;
v12 = va;
do
{
*(_QWORD *)&v4[8 * v5] = v3;
*(_QWORD *)v3 = *(_QWORD *)(a1 + 16);
if ( va[0].gp_offset > 0x2F )
{
v7 = (unsigned int *)va[0].overflow_arg_area;
va[0].overflow_arg_area = (char *)va[0].overflow_arg_area + 8;
}
else
{
v7 = (unsigned int *)((char *)va[0].reg_save_area + va[0].gp_offset);
va[0].gp_offset += 8;
}
sxc_value_setv(*(_QWORD *)&v4[8 * v5], *v7, v12);
printf("done setting arg %d\n", (unsigned int)v5);
sxc_value_snormalize(*(_QWORD *)&v4[8 * v5]);
printf("done interning arg %d\n", (unsigned int)v5++);
v3 += 32;
}
while ( v14 > (int)v5 );
LABEL_11:
(**(void (__fastcall ***)(_QWORD, char *, _QWORD, __int64 *))(a1 + 8))(*(_QWORD *)a1, v4, (unsigned int)v14, &v16);
puts("done invoking func");
result = v13;
if ( v13 )
{
if ( v13 == -1 )
sxc_value_cnormalize(&v16);
va_end(va);
va_start(va, a3);
v9 = v13;
v10 = sxc_value_getv(&v16, v13, va);
result = puts("done extracting return_value");
if ( v10 != 1 )
result = sxc_typeerror(*(_QWORD *)(a1 + 16), "return value", v9, &v16);
}
return result;
}

original_code:
void sxc_func_invoke(SxcFunc* func, int argcount, SxcDataType return_type, ...) {
  va_list varg;
  const int default_argcount = 32;
  SxcValue values[default_argcount];
  SxcValue* arg_values = values;
  SxcValue* valueptrs[default_argcount];
  SxcValue** arg_valueptrs = valueptrs;
  SxcValue return_value;
  int i;
  SxcDataType type;
  int has_return_value;
printf("in sxc_function_invoke\n");
  if (argcount > default_argcount) {
    arg_valueptrs = sxc_alloc(func->context, argcount * (sizeof(SxcValue*) + sizeof(SxcValue)));
    arg_values = (SxcValue*)(arg_valueptrs + argcount);
  }
  return_value.context = func->context;
  return_value.type = sxc_null;
  __builtin_va_start(varg,return_type);
  sxc_value_getv(&return_value, return_type, varg);
printf("done skipping dest\n");
  for (i = 0; i < argcount; i += 1) {
    arg_valueptrs[i] = &arg_values[i];
    arg_valueptrs[i]->context = func->context;
    type = __builtin_va_arg(varg,SxcDataType);
    sxc_value_setv(arg_valueptrs[i], type, varg);
printf("done setting arg %d\n", i);
    sxc_value_snormalize(arg_valueptrs[i]);
printf("done interning arg %d\n", i);
  }
  __builtin_va_end(varg);
  (func->binding->invoke)(func->underlying, arg_valueptrs, argcount, &return_value);
printf("done invoking func\n");
  if (return_type != sxc_null) {
    if (return_type == (-1)) {
      sxc_value_cnormalize(&return_value);
    }
    __builtin_va_start(varg,return_type);
    has_return_value = sxc_value_getv(&return_value, return_type, varg);
printf("done extracting return_value\n");
    __builtin_va_end(varg);
    if (has_return_value != (1)) {
      sxc_typeerror(func->context, "return value", return_type, &return_value);
    }
  }
}

canonical_original_code:
void sxc_func_invoke(struct _SxcFunc *func, int argcount, enum _SxcDataType return_type, ...) {
  __builtin_va_list varg;
  int default_argcount = 32;
  struct _SxcValue values[-1];
  struct _SxcValue *arg_values = values;
  struct _SxcValue *valueptrs[-1];
  struct _SxcValue **arg_valueptrs = valueptrs;
  struct _SxcValue return_value;
  int i;
  enum _SxcDataType type;
  int has_return_value;
printf("in sxc_function_invoke\n");
  if (argcount > default_argcount) {
    arg_valueptrs = sxc_alloc(func->context, argcount * (sizeof(struct _SxcValue *) + sizeof(SxcValue)));
    arg_values = (struct _SxcValue *)(arg_valueptrs + argcount);
  }
  return_value.context = func->context;
  return_value.type = sxc_null;
  __builtin_va_start(varg,return_type);
  sxc_value_getv(&return_value, return_type, varg);
printf("done skipping dest\n");
  for (i = 0; i < argcount; i += 1) {
    arg_valueptrs[i] = &arg_values[i];
    arg_valueptrs[i]->context = func->context;
    type = __builtin_va_arg(varg,SxcDataType);
    sxc_value_setv(arg_valueptrs[i], type, varg);
printf("done setting arg %d\n", i);
    sxc_value_snormalize(arg_valueptrs[i]);
printf("done interning arg %d\n", i);
  }
  __builtin_va_end(varg);
  (func->binding->invoke)(func->underlying, arg_valueptrs, argcount, &return_value);
printf("done invoking func\n");
  if (return_type != sxc_null) {
    if (return_type == (-1)) {
      sxc_value_cnormalize(&return_value);
    }
    __builtin_va_start(varg,return_type);
    has_return_value = sxc_value_getv(&return_value, return_type, varg);
printf("done extracting return_value\n");
    __builtin_va_end(varg);
    if (has_return_value != (1)) {
      sxc_typeerror(func->context, "return value", return_type, &return_value);
    }
  }
}

variable_types: struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *

variable_types: struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } [-1]

variable_types: struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } *[-1]

variable_types: struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } **

variable_types: i int


repo: jonathanhefner/sxc

decompiled_code:
__int64 __fastcall to_sfunc(__int64 a1, __int64 **a2)
{
__int64 v2; // rbp

v2 = **a2;
luaL_checkstack(v2, 4LL, &LC0);
lua_pushlightuserdata(v2, a1);
lua_pushcclosure(v2, &l_libfunc_invoke, 1LL);
return get_value(0xFFFFFFFFLL, a2);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 **a2)
{
__int64 v2; // rbp

v2 = **a2;
luaL_checkstack(v2, 4LL, &LC0);
lua_pushlightuserdata(v2, a1);
lua_pushcclosure(v2, &l_libfunc_invoke, 1LL);
return get_value(0xFFFFFFFFLL, a2);
}

original_code:
static int to_sfunc(SxcValue* value, void** dest, SxcFuncBinding** dest_binding) {
  SxcValue tmp_value;
  switch (value->type) {
    case sxc_sfunc:
      *dest = value->data.sfunc.underlying;
      *dest_binding = value->data.sfunc.binding;
      return (1);
    case sxc_func:
      *dest = value->data.func->underlying;
      *dest_binding = value->data.func->binding;
      return (1);
    case sxc_cfunc:
      tmp_value.context = value->context;
      (value->context->binding->to_sfunc)(value->data.cfunc, &tmp_value);
      *dest = tmp_value.data.sfunc.underlying;
      *dest_binding = tmp_value.data.sfunc.binding;
      return (1);
    default:
      return (0);
  }
}

canonical_original_code:
static int to_sfunc(struct _SxcValue *value, void **dest, struct _SxcFunctionBinding **dest_binding) {
  struct _SxcValue tmp_value;
  switch (value->type) {
    case sxc_sfunc:
      *dest = value->data.sfunc.underlying;
      *dest_binding = value->data.sfunc.binding;
      return (1);
    case sxc_func:
      *dest = value->data.func->underlying;
      *dest_binding = value->data.func->binding;
      return (1);
    case sxc_cfunc:
      tmp_value.context = value->context;
      (value->context->binding->to_sfunc)(value->data.cfunc, &tmp_value);
      *dest = tmp_value.data.sfunc.underlying;
      *dest_binding = tmp_value.data.sfunc.binding;
      return (1);
    default:
      return (0);
  }
}

variable_types: struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } *

variable_types:
dest
void **

return_type: int

user_defined_types: struct _SxcValue { struct _SxcContext *context; enum _SxcDataType type; union _SxcData data; }

user_defined_types: union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString *string; struct _SxcMap *map; struct _SxcFunc *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; }

user_defined_types: struct _SxcContext { void *underlying; struct _SxcContextBinding *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk _firstchunk; char _firstdata[-1]; }

user_defined_types: struct _SxcString { void *underlying; struct _SxcStringBinding *binding; struct _SxcContext *context; char *data; int length; }

user_defined_types: struct _SxcMap { void *underlying; struct _SxcMapBinding *binding; struct _SxcContext *context; }

user_defined_types: struct _SxcFunc { void *underlying; struct _SxcFunctionBinding *binding; struct _SxcContext *context; }

user_defined_types: struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod *methods, struct _SxcLibProperty *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); }


decompiled_code:
__int64 __fastcall get_arg(__int64 a1, int a2, __int64 a3)
{
return get_value((unsigned int)(a2 + 1), a3);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2, __int64 a3)
{
return get_value((unsigned int)(a2 + 1), a3);
}

original_code:
static void get_arg(void* underlying, int index, SxcValue* return_value) {
  get_value(index + 1, return_value);
}

canonical_original_code:
static void get_arg(void *underlying, int index, struct _SxcValue *return_value) {
  get_value(index + 1, return_value);
}

variable_types:
underlying
void *

variable_types: index int

return_type: void

user_defined_types: enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 }

user_defined_types: struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; }

user_defined_types: struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; }

user_defined_types: struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); }

user_defined_types: struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); }

user_defined_types: struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); }

user_defined_types: struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); }


decompiled_code:
__int64 __fastcall to_sstring(__int64 a1, int a2, __int64 **a3)
{
__int64 v4; // r13

v4 = **a3;
luaL_checkstack(v4, 3LL, &LC0);
lua_pushlstring(v4, a1, a2);
return get_value(0xFFFFFFFFLL, a3);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, int a2, __int64 **a3)
{
__int64 v4; // r13

v4 = **a3;
luaL_checkstack(v4, 3LL, &LC0);
lua_pushlstring(v4, a1, a2);
return get_value(0xFFFFFFFFLL, a3);
}

original_code:
static int to_sstring(SxcValue* value, void** dest, SxcStringBinding** dest_binding) {
  char* cchars;
  int length;
  char cpointer_bytes[sizeof(void*)];
  switch (value->type) {
    case sxc_sstring:
      *dest = value->data.sstring.underlying;
      *dest_binding = value->data.sstring.binding;
      return (1);
    case sxc_string:
      *dest = value->data.string->underlying;
      *dest_binding = value->data.string->binding;
      return (1);
    case sxc_cchars:
      return cchars_to_sstring(value->context, value->data.cchars.array,
              value->data.cchars.length, dest, dest_binding);
    case sxc_cstring:
      return cchars_to_sstring(value->context, value->data.cstring,
              strlen(value->data.cstring), dest, dest_binding);
    case sxc_cbool:
      return cbool_to_cchars(value->data.cbool, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cint:
      return cint_to_cchars(value->context, value->data.cint, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cdouble:
      return cdouble_to_cchars(value->context, value->data.cdouble, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cpointer:
      memcpy(cpointer_bytes, &(value->data.cpointer), sizeof(void*));
      return cchars_to_sstring(value->context, cpointer_bytes, sizeof(void*), dest, dest_binding);
    default:
      return (0);
  }
}

canonical_original_code:
static int to_sstring(struct _SxcValue *value, void **dest, struct _SxcStringBinding **dest_binding) {
  char *cchars;
  int length;
  char cpointer_bytes[-1];
  switch (value->type) {
    case sxc_sstring:
      *dest = value->data.sstring.underlying;
      *dest_binding = value->data.sstring.binding;
      return (1);
    case sxc_string:
      *dest = value->data.string->underlying;
      *dest_binding = value->data.string->binding;
      return (1);
    case sxc_cchars:
      return cchars_to_sstring(value->context, value->data.cchars.array,
              value->data.cchars.length, dest, dest_binding);
    case sxc_cstring:
      return cchars_to_sstring(value->context, value->data.cstring,
              strlen(value->data.cstring), dest, dest_binding);
    case sxc_cbool:
      return cbool_to_cchars(value->data.cbool, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cint:
      return cint_to_cchars(value->context, value->data.cint, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cdouble:
      return cdouble_to_cchars(value->context, value->data.cdouble, &cchars, &length)
          && cchars_to_sstring(value->context, cchars, length, dest, dest_binding);
    case sxc_cpointer:
      memcpy(cpointer_bytes, &(value->data.cpointer), sizeof(void *));
      return cchars_to_sstring(value->context, cpointer_bytes, sizeof(void *), dest, dest_binding);
    default:
      return (0);
  }
}

variable_types:
cchars
char *

variable_types: length int


decompiled_code:
void *__fastcall get_register_func(__int64 a1, const char *a2, int a3)
{
const char *v3; // r12
void *v4; // rax
void *result; // rax
char *v6; // rax

v3 = (const char *)fix_lib_name(a1, (__int64)a2, a3, "libsxc_%s.so", 47);
v4 = dlopen(v3, 2);
if ( !v4 || (result = dlsym(v4, "sxc_lib_register")) == 0LL )
{
v6 = dlerror();
result = (void *)sxc_error(a1, "Could not load library %s (%s): %s", a2, v3, v6);
}
return result;
}

canonical_decompiled_code:
void *__fastcall func1(__int64 a1, const char *a2, int a3)
{
const char *v3; // r12
void *v4; // rax
void *result; // rax
char *v6; // rax

v3 = (const char *)func0(a1, (__int64)a2, a3, "libsxc_%s.so", 47);
v4 = dlopen(v3, 2);
if ( !v4 || (result = dlsym(v4, "sxc_lib_register")) == 0LL )
{
v6 = dlerror();
result = (void *)sxc_error(a1, "Could not load library %s (%s): %s", a2, v3, v6);
}
return result;
}

original_code:
static SxcLibFunc* get_register_func(SxcContext* context, char* lib_name, int lib_name_len) {
    char* lib_name_fixed = fix_lib_name(context, lib_name, lib_name_len, "libsxc_%s.so", '/');
    void* library;
    void* func;
    library = dlopen(lib_name_fixed, 0x00002);
    if (library != ((void *)0)) {
      func = dlsym(library, "sxc_lib_register");
      if (func != ((void *)0)) {
        return (SxcLibFunc*)func;
      }
    }
    return sxc_error(context, "Could not load library %s (%s): %s", lib_name, lib_name_fixed, dlerror());
  }

canonical_original_code:
static void (*get_register_func(struct _SxcContext *context, char *lib_name, int lib_name_len))(struct _SxcContext *context) {
    char *lib_name_fixed = fix_lib_name(context, lib_name, lib_name_len, "libsxc_%s.so", '/');
    void *library;
    void *func;
    library = dlopen(lib_name_fixed, 0x00002);
    if (library != ((void *)0)) {
      func = dlsym(library, "sxc_lib_register");
      if (func != ((void *)0)) {
        return (void (*)(struct _SxcContext *context))func;
      }
    }
    return sxc_error(context, "Could not load library %s (%s): %s", lib_name, lib_name_fixed, dlerror());
  }

variable_types:
context
struct _SxcContext *

variable_types:
library
void *

variable_types:
func
void *

return_type: void (*)(struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue { struct _SxcContext *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context)


decompiled_code:
int __fastcall sxc_load(__int64 a1)
{
const char **v1; // rbx
size_t v2; // r12
const char *v3; // rbp
unsigned int v5; // ebp
_QWORD *v6; // rbx
unsigned int v7; // [rsp+4h] [rbp-34h] BYREF
char *s2[6]; // [rsp+8h] [rbp-30h] BYREF

printf("in sxc_load, lib_name:%p lib_name_len:%p\n", s2, &v7);
sxc_arg(a1, 0LL, 1LL, 13LL, s2, &v7);
printf("done extract lib_name from args, name:%s, len:%d\n", s2[0], v7);
v1 = (const char **)loaded_libs;
v2 = (int)v7;
v3 = s2[0];
while ( v1 )
{
if ( !strncmp(*v1, v3, v2) )
return puts("done find lib if it's already been loaded");
}
puts("done find lib if it's already been loaded");
v5 = v7;
v6 = malloc((int)v7 + 25LL);
printf("done alloc new lib struct, name_len: %d\n", v5);
*v6 = v6 + 3;
memcpy(v6 + 3, s2[0], (int)v7);
puts("done set new lib name");
*(_BYTE *)(*v6 + (int)v7) = 0;
puts("done terminate new lib name");
v6[1] = get_register_func(a1, s2[0], v7);
puts("get new lib register_func");
v6[2] = loaded_libs;
loaded_libs = v6;
((void (__fastcall *)(__int64))v6[1])(a1);
return puts("done register_func()");
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
const char **v1; // rbx
size_t v2; // r12
const char *v3; // rbp
unsigned int v5; // ebp
_QWORD *v6; // rbx
unsigned int v7; // [rsp+4h] [rbp-34h] BYREF
char *s2[6]; // [rsp+8h] [rbp-30h] BYREF

printf("in sxc_load, lib_name:%p lib_name_len:%p\n", s2, &v7);
sxc_arg(a1, 0LL, 1LL, 13LL, s2, &v7);
printf("done extract lib_name from args, name:%s, len:%d\n", s2[0], v7);
v1 = (const char **)loaded_libs;
v2 = (int)v7;
v3 = s2[0];
while ( v1 )
{
if ( !strncmp(*v1, v3, v2) )
return puts("done find lib if it's already been loaded");
}
puts("done find lib if it's already been loaded");
v5 = v7;
v6 = malloc((int)v7 + 25LL);
printf("done alloc new lib struct, name_len: %d\n", v5);
*v6 = v6 + 3;
memcpy(v6 + 3, s2[0], (int)v7);
puts("done set new lib name");
*(_BYTE *)(*v6 + (int)v7) = 0;
puts("done terminate new lib name");
v6[1] = func1(a1, s2[0], v7);
puts("get new lib register_func");
v6[2] = loaded_libs;
loaded_libs = v6;
((void (__fastcall *)(__int64))v6[1])(a1);
return puts("done register_func()");
}

original_code:
void sxc_load(SxcContext* context) {
  char* lib_name;
  int lib_name_len;
  LoadedLib* lib;
printf("in sxc_load, lib_name:%p lib_name_len:%p\n", &lib_name, &lib_name_len);
  sxc_arg(context, 0, 1, sxc_cchars, &lib_name, &lib_name_len);
printf("done extract lib_name from args, name:%s, len:%d\n", lib_name, lib_name_len);
  lib = loaded_libs;
  while (lib != ((void *)0) && strncmp(lib->name, lib_name, lib_name_len) != 0) ;
printf("done find lib if it's already been loaded\n");
  if (lib == ((void *)0)) {
    lib = malloc(sizeof(LoadedLib) + lib_name_len + 1);
printf("done alloc new lib struct, name_len: %d\n", lib_name_len);
    lib->name = (char*)(lib + 1);
    memcpy(lib->name, lib_name, lib_name_len);
printf("done set new lib name\n");
    lib->name[lib_name_len] = '\0';
printf("done terminate new lib name\n");
    lib->register_func = get_register_func(context, lib_name, lib_name_len);
printf("get new lib register_func\n");
    lib->next = loaded_libs;
    loaded_libs = lib;
    (lib->register_func)(context);
printf("done register_func()\n");
  }
}

canonical_original_code:
void sxc_load(struct _SxcContext *context) {
  char *lib_name;
  int lib_name_len;
  struct _LoadedLib *lib;
printf("in sxc_load, lib_name:%p lib_name_len:%p\n", &lib_name, &lib_name_len);
  sxc_arg(context, 0, 1, sxc_cchars, &lib_name, &lib_name_len);
printf("done extract lib_name from args, name:%s, len:%d\n", lib_name, lib_name_len);
  lib = loaded_libs;
  while (lib != ((void *)0) && strncmp(lib->name, lib_name, lib_name_len) != 0) ;
printf("done find lib if it's already been loaded\n");
  if (lib == ((void *)0)) {
    lib = malloc(sizeof(LoadedLib) + lib_name_len + 1);
printf("done alloc new lib struct, name_len: %d\n", lib_name_len);
    lib->name = (char *)(lib + 1);
    memcpy(lib->name, lib_name, lib_name_len);
printf("done set new lib name\n");
    lib->name[lib_name_len] = '\0';
printf("done terminate new lib name\n");
    lib->register_func = get_register_func(context, lib_name, lib_name_len);
printf("get new lib register_func\n");
    lib->next = loaded_libs;
    loaded_libs = lib;
    (lib->register_func)(context);
printf("done register_func()\n");
  }
}

variable_types: struct _LoadedLib { char *name; void (*register_func)(struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue { struct _SxcContext *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context); struct _LoadedLib *next; } *

user_defined_types: struct _LoadedLib { char *name; void (*register_func)(struct _SxcContext *context); struct _LoadedLib *next; }


decompiled_code:
__int64 __fastcall map_iter(unsigned int a1, __int64 a2, __int64 a3, __int64 **a4)
{
__int64 v6; // rbp
unsigned int v7; // eax
const char *v8; // rax
__int64 v9; // rbx
unsigned int v11; // er12
int v12; // eax

v6 = **a4;
v7 = lua_type(v6);
v8 = (const char *)lua_typename(v6, v7);
printf("in map_iter, mapindex: %d, state:%d, statetype:%s\n", a1, (unsigned int)a2, v8);
luaL_checkstack(v6, 4LL, &LC1);
if ( a2 )
{
if ( (int)lua_gettop(v6) > (int)a2 )
lua_pushvalue(v6, (unsigned int)a2);
}
else
{
lua_pushnil(v6);
}
v9 = 0LL;
if ( (unsigned int)lua_next(v6, a1) )
{
get_value(4294967294LL, a3);
v11 = lua_gettop(v6) - 1;
v9 = (int)v11;
v12 = *(_DWORD *)(a3 + 8);
if ( v12 == 2 )
{
--*(_DWORD *)(a3 + 16);
}
else if ( v12 != 7 )
{
sxc_value_set(a3, 0LL);
sxc_value_set(a4, 0LL);
lua_settop(v6, 4294967294LL);
printf("leaving map_iter nulled with new state:%d\n", v11);
return v9;
}
pop_value(a4);
printf("leaving map_iter with new state:%d\n", v11);
}
return v9;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, __int64 a2, __int64 a3, __int64 **a4)
{
__int64 v6; // rbp
unsigned int v7; // eax
const char *v8; // rax
__int64 v9; // rbx
unsigned int v11; // er12
int v12; // eax

v6 = **a4;
v7 = lua_type(v6);
v8 = (const char *)lua_typename(v6, v7);
printf("in map_iter, mapindex: %d, state:%d, statetype:%s\n", a1, (unsigned int)a2, v8);
luaL_checkstack(v6, 4LL, &LC1);
if ( a2 )
{
if ( (int)lua_gettop(v6) > (int)a2 )
lua_pushvalue(v6, (unsigned int)a2);
}
else
{
lua_pushnil(v6);
}
v9 = 0LL;
if ( (unsigned int)lua_next(v6, a1) )
{
get_value(4294967294LL, a3);
v11 = lua_gettop(v6) - 1;
v9 = (int)v11;
v12 = *(_DWORD *)(a3 + 8);
if ( v12 == 2 )
{
--*(_DWORD *)(a3 + 16);
}
else if ( v12 != 7 )
{
sxc_value_set(a3, 0LL);
sxc_value_set(a4, 0LL);
lua_settop(v6, 4294967294LL);
printf("leaving map_iter nulled with new state:%d\n", v11);
return v9;
}
pop_value(a4);
printf("leaving map_iter with new state:%d\n", v11);
}
return v9;
}

original_code:
static void* map_iter(SxcMap* map, void* state, SxcValue* return_key, SxcValue* return_value) {
  while ((state = (map->binding->iter)(map->underlying, state, return_key, return_value))) {
    switch (return_key->type) {
      case sxc_cint:
      case sxc_sstring:
        return state;
      case sxc_cdouble:
        if (return_key->data.cdouble == (double)(int)(return_key->data.cdouble)) {
          sxc_value_set(return_key, sxc_cint, (int)(return_key->data.cdouble));
          return state;
        }
      default:
        break;
    }
  }
  return ((void *)0);
}

canonical_original_code:
static void *map_iter(struct _SxcMap *map, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value) {
  while ((state = (map->binding->iter)(map->underlying, state, return_key, return_value))) {
    switch (return_key->type) {
      case sxc_cint:
      case sxc_sstring:
        return state;
      case sxc_cdouble:
        if (return_key->data.cdouble == (double)(int)(return_key->data.cdouble)) {
          sxc_value_set(return_key, sxc_cint, (int)(return_key->data.cdouble));
          return state;
        }
      default:
        break;
    }
  }
  return ((void *)0);
}

variable_types: struct _SxcMap { void *underlying; struct _SxcMapBinding { void (*intget)(void *underlying, int key, struct _SxcValue { struct _SxcContext { void *underlying; struct _SxcContextBinding { void (*get_arg)(void *underlying, int index, struct _SxcValue *return_value); void (*to_sstring)(char *data, int length, struct _SxcValue *return_value); void (*map_new)(void *map_type, struct _SxcValue *return_value); void *(*map_newtype)(struct _SxcContext *context, char *name, void (*initializer)(struct _SxcContext *context), struct _SxcLibMethod { char *name; int is_static; void (*func)(struct _SxcContext *context); } *methods, struct _SxcLibProperty { char *name; int is_static; void (*getter)(struct _SxcContext *context); void (*setter)(struct _SxcContext *context); } *properties); void (*to_sfunc)(void (*func)(struct _SxcContext *context), struct _SxcValue *return_value); } *binding; int argcount; struct _SxcValue return_value; int has_error; void *_jmpbuf; struct _SxcMemoryChunk { int free_space; struct _SxcMemoryChunk *next_chunk; int offset; char data; } _firstchunk; char _firstdata[-1]; } *context; enum _SxcDataType { sxc_null=0, sxc_cbool=1, sxc_cint=2, sxc_cdouble=3, sxc_string=4, sxc_map=5, sxc_func=6, sxc_sstring=7, sxc_smap=8, sxc_sfunc=9, sxc_cstring=10, sxc_cpointer=11, sxc_cfunc=12, sxc_cchars=13, sxc_cbools=14, sxc_cints=15, sxc_cdoubles=16, sxc_cstrings=17 } type; union _SxcData { _Bool cbool; int cint; double cdouble; void *_pointer_store; struct _SxcString { void *underlying; struct _SxcStringBinding { void (*to_cchars)(void *underlying, struct _SxcValue *return_value); int is_null_terminated; } *binding; struct _SxcContext *context; char *data; int length; } *string; struct _SxcMap *map; struct _SxcFunc { void *underlying; struct _SxcFunctionBinding { void (*invoke)(void *underlying, struct _SxcValue **args, int argcount, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *func; struct { void *underlying; void *binding; } _binding_store; struct { void *underlying; struct _SxcStringBinding *binding; } sstring; struct { void *underlying; struct _SxcMapBinding *binding; } smap; struct { void *underlying; struct _SxcFunctionBinding *binding; } sfunc; char *cstring; void (*cfunc)(struct _SxcContext *context); void *cpointer; struct { void *array; int length; } _array_store; struct { char *array; int length; } cchars; struct { _Bool *array; int length; } cbools; struct { int *array; int length; } cints; struct { double *array; int length; } cdoubles; struct { char **array; int length; } cstrings; } data; } *return_value); void (*intset)(void *underlying, int key, struct _SxcValue *value); void (*strget)(void *underlying, char *key, struct _SxcValue *return_value); void (*strset)(void *underlying, char *key, struct _SxcValue *value); int (*length)(void *underlying); void *(*iter)(void *underlying, void *state, struct _SxcValue *return_key, struct _SxcValue *return_value); } *binding; struct _SxcContext *context; } *

variable_types:
state
void *

return_type: void *


mount

decompiled_code:
__int64 __fastcall mount(const char *a1, int a2)
{
__int64 result; // rax

if ( drives[2 * a2] )
{
printf("Cannot use drive %d. Already in use. Please dismount or select another drive\n", (unsigned int)drive);
result = 0LL;
}
else
{
result = 0LL;
if ( a2 <= 7 )
{
drives[2 * a2] = (__int64)fopen(a1, "r+b");
if ( drives[2 * drive] )
{
LOWORD(drives[2 * drive + 1]) = 0;
WORD1(drives[2 * a2 + 1]) = 0;
result = 1LL;
}
else
{
printf("Unable to open file %s", a1);
result = 0LL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1, int a2)
{
__int64 result; // rax

if ( drives[2 * a2] )
{
printf("Cannot use drive %d. Already in use. Please dismount or select another drive\n", (unsigned int)drive);
result = 0LL;
}
else
{
result = 0LL;
if ( a2 <= 7 )
{
drives[2 * a2] = (__int64)fopen(a1, "r+b");
if ( drives[2 * drive] )
{
LOWORD(drives[2 * drive + 1]) = 0;
WORD1(drives[2 * a2 + 1]) = 0;
result = 1LL;
}
else
{
printf("Unable to open file %s", a1);
result = 0LL;
}
}
}
return result;
}

original_code:
int mount(char *f, int driveNo) {
 if (drives[driveNo].file) {
  printf ("Cannot use drive %d. Already in use. Please dismount or select another drive\n", drive);
  return 0;
 }
 if (driveNo >= DRIVES)
  return 0;
 drives[driveNo].file = fopen(f, "r+b");
 if (!drives[drive].file) {
  printf("Unable to open file %s", f);
  return 0;
 }
 drives[drive].busy = 0;
 drives[driveNo].WPS = 0;
 return 1;
}

variable_types:
f
char *

variable_types: driveNo int


decompiled_code:
int rk_read()
{
size_t v0; // rax
int v1; // er12
int v2; // er13
__int16 v3; // bx
void *v4; // rsp
_WORD *v5; // rdx
size_t v6; // rcx
__int64 v7; // rsi
unsigned __int16 *v8; // rbx
unsigned __int16 *v9; // r12
_WORD v11[24]; // [rsp+0h] [rbp-30h] BYREF

LODWORD(v0) = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = -(unsigned __int16)rkwc;
v2 = (__int16)-rkwc;
v3 = 2048 - position;
if ( position + v2 <= 1247231 )
v3 = -rkwc;
if ( v3 && !(_DWORD)v0 )
{
v4 = alloca(2LL * (__int16)v1);
v0 = fread(v11, 2uLL, v3, (FILE *)drives[2 * drive]);
v6 = v0;
if ( v2 > (int)v0 )
{
v7 = (int)v0;
v0 = (size_t)&v11[(int)v0];
v5 = &v11[v7 + 1 + (unsigned int)(v2 - 1 - v6)];
do
{
*(_WORD *)v0 = 0;
v0 += 2LL;
}
while ( (_WORD *)v0 != v5 );
}
if ( (*(&rkcs + 1) & 4) != 0 )
{
if ( BigEndian )
v11[v3 - 1] = __ROL2__(v11[v3 - 1], 8);
LODWORD(v0) = setWord((unsigned int)ba, (unsigned __int16)v11[v3 - 1], v5, v6);
}
else if ( v2 > 0 )
{
v8 = v11;
v9 = &v11[(__int16)v1 - 1 + 1];
do
{
if ( BigEndian )
*v8 = __ROL2__(*v8, 8);
LODWORD(v0) = setWord((unsigned int)ba, *v8, v5, v6);
ba += 2;
++v8;
}
while ( v8 != v9 );
}
}
return v0;
}

canonical_decompiled_code:
int func2()
{
size_t v0; // rax
int v1; // er12
int v2; // er13
__int16 v3; // bx
void *v4; // rsp
_WORD *v5; // rdx
size_t v6; // rcx
__int64 v7; // rsi
unsigned __int16 *v8; // rbx
unsigned __int16 *v9; // r12
_WORD v11[24]; // [rsp+0h] [rbp-30h] BYREF

LODWORD(v0) = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = -(unsigned __int16)rkwc;
v2 = (__int16)-rkwc;
v3 = 2048 - position;
if ( position + v2 <= 1247231 )
v3 = -rkwc;
if ( v3 && !(_DWORD)v0 )
{
v4 = alloca(2LL * (__int16)v1);
v0 = fread(v11, 2uLL, v3, (FILE *)drives[2 * drive]);
v6 = v0;
if ( v2 > (int)v0 )
{
v7 = (int)v0;
v0 = (size_t)&v11[(int)v0];
v5 = &v11[v7 + 1 + (unsigned int)(v2 - 1 - v6)];
do
{
*(_WORD *)v0 = 0;
v0 += 2LL;
}
while ( (_WORD *)v0 != v5 );
}
if ( (*(&rkcs + 1) & 4) != 0 )
{
if ( BigEndian )
v11[v3 - 1] = __ROL2__(v11[v3 - 1], 8);
LODWORD(v0) = setWord((unsigned int)ba, (unsigned __int16)v11[v3 - 1], v5, v6);
}
else if ( v2 > 0 )
{
v8 = v11;
v9 = &v11[(__int16)v1 - 1 + 1];
do
{
if ( BigEndian )
*v8 = __ROL2__(*v8, 8);
LODWORD(v0) = setWord((unsigned int)ba, *v8, v5, v6);
ba += 2;
++v8;
}
while ( v8 != v9 );
}
}
return v0;
}

original_code:
void rk_read() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc, buffSize;
 wc = buffSize = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[buffSize];
  int read = fread (buffer, sizeof(unsigned short), wc, drives[drive].file);
  for ( ; read < buffSize; read++)
   buffer[read] = 0;
  if (rkcs.INH_BA) {
   if (BigEndian)
    buffer[wc-1] = ((buffer[wc-1] & 255) << 8) | ((buffer[wc-1]>>8) & 255);
   setWord(ba, buffer[wc-1]);
   return;
  }
  for (i = 0; i < buffSize; i++) {
   if (BigEndian)
    buffer[i] = ((buffer[i] & 255) << 8) | ((buffer[i]>>8) & 255);
   setWord(ba, buffer[i]);
   ba += 2;
  }
 }
}

canonical_original_code:
void rk_read() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc; short buffSize;
 wc = buffSize = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[-1];
  int read = fread (buffer, sizeof(unsigned short), wc, drives[drive].file);
  for ( ; read < buffSize; read++)
   buffer[read] = 0;
  if (rkcs.INH_BA) {
   if (BigEndian)
    buffer[wc-1] = ((buffer[wc-1] & 255) << 8) | ((buffer[wc-1]>>8) & 255);
   setWord(ba, buffer[wc-1]);
   return;
  }
  for (i = 0; i < buffSize; i++) {
   if (BigEndian)
    buffer[i] = ((buffer[i] & 255) << 8) | ((buffer[i]>>8) & 255);
   setWord(ba, buffer[i]);
   ba += 2;
  }
 }
}

variable_types: seek int

variable_types: wc short

variable_types: buffSize short

variable_types:
buffer
unsigned short [-1]

variable_types: read int


decompiled_code:
size_t rk_write()
{
int v0; // ecx
__int16 v1; // r12
size_t result; // rax
void *v3; // rsp
__int64 *v4; // rbx
__int16 v5; // dx
__int16 v6; // ax
__int64 *v7; // [rsp+0h] [rbp-240h] BYREF
size_t n; // [rsp+8h] [rbp-238h]
char ptr[560]; // [rsp+10h] [rbp-230h] BYREF

v0 = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = 2048 - position;
result = (unsigned int)-(unsigned __int16)rkwc;
if ( position + (__int16)-rkwc < 1247232 )
v1 = -rkwc;
if ( v1 && !v0 )
{
v7 = (__int64 *)&v7;
n = v1;
v3 = alloca(2LL * v1);
if ( v1 > 0 )
{
v4 = (__int64 *)&v7;
do
{
v5 = getWord((unsigned int)ba);
v6 = __ROL2__(v5, 8);
if ( !BigEndian )
v6 = v5;
*(_WORD *)v4 = v6;
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
v4 = (__int64 *)((char *)v4 + 2);
}
while ( v4 != (__int64 *)((char *)&v7 + 2 * (unsigned int)v1) );
}
result = fwrite(&v7, 2uLL, n, (FILE *)drives[2 * drive]);
if ( v1 == (_DWORD)result )
{
if ( (_BYTE)v1 )
{
memset(ptr, 0, 0x200uLL);
result = fwrite(ptr, 2uLL, 256 - v1 % 256, (FILE *)drives[2 * drive]);
}
}
}
return result;
}

canonical_decompiled_code:
size_t func3()
{
int v0; // ecx
__int16 v1; // r12
size_t result; // rax
void *v3; // rsp
__int64 *v4; // rbx
__int16 v5; // dx
__int16 v6; // ax
__int64 *v7; // [rsp+0h] [rbp-240h] BYREF
size_t n; // [rsp+8h] [rbp-238h]
char ptr[560]; // [rsp+10h] [rbp-230h] BYREF

v0 = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = 2048 - position;
result = (unsigned int)-(unsigned __int16)rkwc;
if ( position + (__int16)-rkwc < 1247232 )
v1 = -rkwc;
if ( v1 && !v0 )
{
v7 = (__int64 *)&v7;
n = v1;
v3 = alloca(2LL * v1);
if ( v1 > 0 )
{
v4 = (__int64 *)&v7;
do
{
v5 = getWord((unsigned int)ba);
v6 = __ROL2__(v5, 8);
if ( !BigEndian )
v6 = v5;
*(_WORD *)v4 = v6;
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
v4 = (__int64 *)((char *)v4 + 2);
}
while ( v4 != (__int64 *)((char *)&v7 + 2 * (unsigned int)v1) );
}
result = fwrite(&v7, 2uLL, n, (FILE *)drives[2 * drive]);
if ( v1 == (_DWORD)result )
{
if ( (_BYTE)v1 )
{
memset(ptr, 0, 0x200uLL);
result = fwrite(ptr, 2uLL, 256 - v1 % 256, (FILE *)drives[2 * drive]);
}
}
}
return result;
}

original_code:
void rk_write() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[wc];
  for (i = 0; i < wc; i++) {
   unsigned short word = getWord(ba);
   if (BigEndian) {
    word = ((word & 255) << 8) | ((word>>8) & 255);
   }
   buffer[i] = word;
   if (!rkcs.INH_BA) {
    ba += 2;
   }
  }
  int wl = fwrite (buffer, sizeof(unsigned short), wc, drives[drive].file);
  if (wl != wc) {
   return;
  }
  if ((wc % WORDS) != 0) {
   int need = WORDS - (wc % WORDS);
   unsigned short fill[WORDS] = { 0 };
   wl = fwrite (fill, sizeof(unsigned short), need, drives[drive].file);
  }
 }
}

canonical_original_code:
void rk_write() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[-1];
  for (i = 0; i < wc; i++) {
   unsigned short word = getWord(ba);
   if (BigEndian) {
    word = ((word & 255) << 8) | ((word>>8) & 255);
   }
   buffer[i] = word;
   if (!rkcs.INH_BA) {
    ba += 2;
   }
  }
  int wl = fwrite (buffer, sizeof(unsigned short), wc, drives[drive].file);
  if (wl != wc) {
   return;
  }
  if ((wc % WORDS) != 0) {
   int need = WORDS - (wc % WORDS);
   unsigned short fill[-1] = { 0 };
   wl = fwrite (fill, sizeof(unsigned short), need, drives[drive].file);
  }
 }
}

variable_types: i int

variable_types:
word
unsigned short

variable_types: wl int

variable_types: need int

variable_types:
fill
unsigned short [-1]


writeCheck

decompiled_code:
__int64 writeCheck()
{
int v0; // ecx
__int16 v1; // bx
__int64 result; // rax
signed __int64 v3; // r12
void *v4; // rsp
_WORD *v5; // r12
_WORD *v6; // rbx
_WORD v7[16]; // [rsp+0h] [rbp-20h] BYREF

v0 = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = 2048 - position;
result = (unsigned int)-(unsigned __int16)rkwc;
if ( position + (__int16)-rkwc < 1247232 )
v1 = -rkwc;
if ( v1 )
{
if ( !v0 )
{
v3 = 2LL * v1;
v4 = alloca(v3);
result = (int)fread(v7, 2uLL, v1, (FILE *)drives[2 * drive]);
if ( (int)result == v3 && v1 > 0 )
{
v5 = v7;
v6 = &v7[v1];
do
{
if ( BigEndian )
*v5 = __ROL2__(*v5, 8);
result = getWord((unsigned int)ba);
if ( (_WORD)result == *v5 )
{
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
}
else
{
rker |= 1u;
if ( (*(&rkcs + 1) & 1) != 0 )
return result;
}
++v5;
}
while ( v5 != v6 );
}
}
}
return result;
}

canonical_decompiled_code:
__int64 func4()
{
int v0; // ecx
__int16 v1; // bx
__int64 result; // rax
signed __int64 v3; // r12
void *v4; // rsp
_WORD *v5; // r12
_WORD *v6; // rbx
_WORD v7[16]; // [rsp+0h] [rbp-20h] BYREF

v0 = fseek((FILE *)drives[2 * drive], 2LL * position, 0);
v1 = 2048 - position;
result = (unsigned int)-(unsigned __int16)rkwc;
if ( position + (__int16)-rkwc < 1247232 )
v1 = -rkwc;
if ( v1 )
{
if ( !v0 )
{
v3 = 2LL * v1;
v4 = alloca(v3);
result = (int)fread(v7, 2uLL, v1, (FILE *)drives[2 * drive]);
if ( (int)result == v3 && v1 > 0 )
{
v5 = v7;
v6 = &v7[v1];
do
{
if ( BigEndian )
*v5 = __ROL2__(*v5, 8);
result = getWord((unsigned int)ba);
if ( (_WORD)result == *v5 )
{
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
}
else
{
rker |= 1u;
if ( (*(&rkcs + 1) & 1) != 0 )
return result;
}
++v5;
}
while ( v5 != v6 );
}
}
}
return result;
}

original_code:
void writeCheck() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[wc];
  int re = fread (buffer, sizeof(unsigned short), wc, drives[drive].file);
  if (re != (wc * sizeof(unsigned short))) {
   return;
  }
  for (i = 0; i < wc; i++) {
   if (BigEndian) {
    buffer[i] = ((buffer[i] & 255) << 8) | ((buffer[i]>>8) & 255);
   }
   if (getWord(ba) == buffer[i]) {
    if (!rkcs.INH_BA)
     ba += 2;
   }
   else {
    rker.WCE = 1;
    if (rkcs.SSE)
     return;
   }
  }
 }
}

canonical_original_code:
void writeCheck() {
 int i;
 int seek = fseek (drives[drive].file, position * sizeof(unsigned short), 0);
 short wc = rkwc * -1;
 if ((position + wc) >= SIZE) {
  wc = SIZE - position;
 }
 if (wc && !seek) {
  unsigned short buffer[-1];
  int re = fread (buffer, sizeof(unsigned short), wc, drives[drive].file);
  if (re != (wc * sizeof(unsigned short))) {
   return;
  }
  for (i = 0; i < wc; i++) {
   if (BigEndian) {
    buffer[i] = ((buffer[i] & 255) << 8) | ((buffer[i]>>8) & 255);
   }
   if (getWord(ba) == buffer[i]) {
    if (!rkcs.INH_BA)
     ba += 2;
   }
   else {
    rker.WCE = 1;
    if (rkcs.SSE)
     return;
   }
  }
 }
}

variable_types: re int


readFMT

decompiled_code:
void __fastcall readFMT(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
int v4; // ebp
int i; // ebx

v4 = (__int16)-rkwc;
if ( v4 > 0 )
{
for ( i = 0; i != v4; ++i )
{
setWord((unsigned int)ba, (unsigned __int16)track, a3, a4);
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
if ( sector == 11 )
{
sector = 0;
if ( track == 202 )
{
a3 = (unsigned __int16)surface;
if ( !surface )
{
surface = 1;
track = 0;
continue;
}
if ( surface == 1 )
{
*(&rker + 1) |= 8u;
return;
}
}
++track;
}
else
{
++sector;
}
}
}
}

canonical_decompiled_code:
void __fastcall func5(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
int v4; // ebp
int i; // ebx

v4 = (__int16)-rkwc;
if ( v4 > 0 )
{
for ( i = 0; i != v4; ++i )
{
setWord((unsigned int)ba, (unsigned __int16)track, a3, a4);
if ( (*(&rkcs + 1) & 4) == 0 )
ba += 2;
if ( sector == 11 )
{
sector = 0;
if ( track == 202 )
{
a3 = (unsigned __int16)surface;
if ( !surface )
{
surface = 1;
track = 0;
continue;
}
if ( surface == 1 )
{
*(&rker + 1) |= 8u;
return;
}
}
++track;
}
else
{
++sector;
}
}
}
}

original_code:
void readFMT() {
 short wc = rkwc * -1;
 int i;
 for (i = 0; i < wc; i++) {
  setWord(ba, track);
  if (!rkcs.INH_BA)
   ba+=2;
  if (sector == (SECTORS-1)) {
   sector = 0;
   if (track == (TRACKSS-1) && surface == 0) {
    surface = 1;
    track = 0;
   }
   else if (track == (TRACKSS-1) && surface == 1) {
    rker.OVR = 1;
    return;
   }
   else {
    track++;
   }
   continue;
  }
  sector++;
 }
}


clearErrors

decompiled_code:
void clearErrors()
{
rker = 0;
*(&rker + 1) &= 0xE0u;
}

canonical_decompiled_code:
void func6()
{
rker = 0;
*(&rker + 1) &= 0xE0u;
}

original_code:
void clearErrors() {
 rker.WCE = 0;
 rker.CSE = 0;
 rker.NXS = 0;
 rker.NXC = 0;
 rker.NXD = 0;
 rker.TE = 0;
 rker.DLT = 0;
 rker.NXM = 0;
 rker.PGE = 0;
 rker.SKE = 0;
 rker.WLO = 0;
 rker.OVR = 0;
 rker.DRE = 0;
}


clearCont

decompiled_code:
void clearCont()
{
rkcs = 0;
*(&rkcs + 1) &= 0xC0u;
}

canonical_decompiled_code:
void func7()
{
rkcs = 0;
*(&rkcs + 1) &= 0xC0u;
}

original_code:
void clearCont() {
 rkcs.GO = 0;
 rkcs.FUN = 0;
 rkcs.MEX = 0;
 rkcs.IDE = 0;
 rkcs.RDY = 0;
 rkcs.SSE = 0;
 rkcs.FMT = 0;
 rkcs.INH_BA = 0;
 rkcs.SCP = 0;
 rkcs.HE = 0;
 rkcs.ERROR = 0;
}


rkdsReset

decompiled_code:
void rkdsReset()
{
rkds = 0;
*(&rkds + 1) &= 0xF0u;
}

canonical_decompiled_code:
void func8()
{
rkds = 0;
*(&rkds + 1) &= 0xF0u;
}

original_code:
void rkdsReset() {
 rkds.SC = 0;
 rkds.SCSA = 0;
 rkds.WPS = 0;
 rkds.RWSR = 0;
 rkds.DRY = 0;
 rkds.SOK = 0;
 rkds.SIN = 0;
 rkds.DRU = 0;
 rkds.RK05 = 0;
}


controlReset

decompiled_code:
void controlReset()
{
rkda = 0;
rkba = 0;
clearErrors();
clearCont();
rkdsReset();
rkcs |= 0x80u;
}

canonical_decompiled_code:
void func9()
{
rkda = 0;
rkba = 0;
func6();
func7();
func8();
rkcs |= 0x80u;
}

original_code:
void controlReset() {
 rkda = 0;
 rkba = 0;
 clearErrors();
 clearCont();
 rkdsReset();
 rkcs.RDY = 1;
}


readRKDS

original_code:
unsigned short readRKDS() {
 unsigned short tmp = 0;
 tmp |= rkds.SC;
 tmp |= (rkds.SCSA << 4);
 tmp |= (rkds.WPS << 5);
 tmp |= (rkds.RWSR << 6);
 tmp |= (rkds.DRY << 7);
 tmp |= (rkds.SOK << 8);
 tmp |= (rkds.SIN << 9);
 tmp |= (rkds.DRU << 10);
 tmp |= (rkds.RK05 << 11);
 tmp |= (rkds.DPL << 12);
 tmp |= (rkds.ID << 13);
 return tmp;
}

variable_types:
tmp
unsigned short

return_type: unsigned short


readRKER

original_code:
unsigned short readRKER() {
 unsigned short tmp = 0;
 tmp |= rker.WCE;
 tmp |= (rker.CSE << 1);
 tmp |= (rker.NXS << 5);
 tmp |= (rker.NXC << 6);
 tmp |= (rker.NXD << 7);
 tmp |= (rker.TE << 8);
 tmp |= (rker.DLT << 9);
 tmp |= (rker.NXM << 10);
 tmp |= (rker.PGE << 11);
 tmp |= (rker.SKE << 12);
 tmp |= (rker.WLO << 13);
 tmp |= (rker.OVR << 14);
 tmp |= (rker.DRE << 15);
 return tmp;
}


done

decompiled_code:
__int64 done()
{
__int64 result; // rax

rkcs |= 0x80u;
*(&rkcs + 1) |= 8u;
rkds = (HIBYTE(rkda) % 0xCBu) & 0xF | rkds & 0xF0 | 0xC0;
*(&rkds + 1) |= 1u;
result = readRKER();
if ( (_WORD)result )
{
*(&rkcs + 1) |= 0x20u;
result = readRKER();
if ( (result & 0xFFE0) != 0 )
*(&rkcs + 1) |= 0x10u;
}
if ( (rkcs & 0x40) != 0 )
{
if ( (func & 0xFFFFFFFB) == 0 )
*(&rkds + 1) = (32 * drive) | *(&rkds + 1) & 0x1F;
result = busRequest(&BR5, 220LL);
}
return result;
}

canonical_decompiled_code:
__int64 func12()
{
__int64 result; // rax

rkcs |= 0x80u;
*(&rkcs + 1) |= 8u;
rkds = (HIBYTE(rkda) % 0xCBu) & 0xF | rkds & 0xF0 | 0xC0;
*(&rkds + 1) |= 1u;
result = func11();
if ( (_WORD)result )
{
*(&rkcs + 1) |= 0x20u;
result = func11();
if ( (result & 0xFFE0) != 0 )
*(&rkcs + 1) |= 0x10u;
}
if ( (rkcs & 0x40) != 0 )
{
if ( (func & 0xFFFFFFFB) == 0 )
*(&rkds + 1) = (32 * drive) | *(&rkds + 1) & 0x1F;
result = busRequest(&BR5, 220LL);
}
return result;
}

original_code:
void done() {
 rkcs.RDY = 1;
 rkcs.SCP = 1;
 rkds.SC = ((rkda/WORDS) % TRACKSS);
 rkds.RWSR = 1;
 rkds.DRY = 1;
 rkds.SOK = 1;
 if (readRKER()) {
  rkcs.ERROR = 1;
 }
 if (readRKER() & 0177740) {
  rkcs.HE = 1;
 }
 if (rkcs.IDE) {
 if (func == SEEK || func == CONTROL_RESET) {
  rkcs.SCP = 1;
  rkds.ID = drive;
 }
   busRequest(&BR5, IntVector);
 }
}


go

decompiled_code:
void __fastcall go(__int64 a1, __int64 a2)
{
unsigned __int8 v2; // bl
char v3; // al
__int64 v4; // rcx
__int64 v5; // rdx
int v6; // eax

v2 = ((unsigned __int8)rkcs >> 1) & 7;
func = v2;
if ( !v2 )
{
controlReset();
return;
}
rker &= 0xFCu;
if ( !(unsigned __int16)readRKER() )
*(&rkcs + 1) &= 0xDFu;
v3 = *(&rkcs + 1) & 0xF7;
*(&rkcs + 1) = v3;
rkcs &= 0x7Fu;
if ( (v3 & 2) != 0 && ((v2 + 7) & 7u) > 1 )
{
*(&rker + 1) |= 1u;
done();
return;
}
drive = (unsigned __int16)rkda >> 13;
if ( !drives[2 * ((unsigned __int16)rkda >> 13)] )
{
rker |= 0x10u;
done();
return;
}
v4 = 2LL * ((unsigned __int16)rkda >> 13);
if ( LOWORD(drives[v4 + 1]) )
{
*(&rker + 1) |= 0x10u;
done();
return;
}
if ( v2 == 1 )
{
if ( WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) )
{
*(&rker + 1) |= 4u;
done();
return;
}
goto LABEL_26;
}
if ( v2 != 7 )
{
if ( v2 == 6 )
{
WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) = 0;
surface = 0;
sector = 0;
track = 0;
func = 4;
LABEL_12:
if ( func == 4 )
{
rkds |= 0x10u;
done();
}
ba = (unsigned __int16)rkba + ((((unsigned __int8)rkcs >> 4) & 3) << 16);
v5 = 3 * (unsigned int)(unsigned __int16)track;
if ( surface )
v6 = (unsigned __int16)sector + 12 * (unsigned __int16)track + 2436;
else
v6 = (unsigned __int16)sector + 12 * (unsigned __int16)track;
position = v6 << 8;
LOWORD(drives[2 * drive + 1]) = 1;
if ( func == 2 )
{
if ( (*(&rkcs + 1) & 2) != 0 )
readFMT(a1, a2, v5, v4 * 8);
else
rk_read();
}
else if ( func == 3 )
{
writeCheck();
}
else if ( func == 1 && (*(&rkcs + 1) & 2) == 0 )
{
rk_write();
}
rkba = ba;
rkwc = 0;
LOWORD(drives[2 * drive + 1]) = 0;
done();
return;
}
LABEL_26:
track = (unsigned __int8)((unsigned __int16)rkda >> 5);
sector = rkda & 0xF;
surface = ((unsigned __int16)rkda >> 4) & 1;
if ( (unsigned __int16)sector > 0xBu )
{
rker |= 4u;
done();
return;
}
if ( (unsigned __int16)track > 0xCAu )
{
rker |= 8u;
done();
return;
}
goto LABEL_12;
}
WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) = 1;
done();
if ( (rkcs & 0x40) != 0 )
busRequest(&BR5, 220LL);
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, __int64 a2)
{
unsigned __int8 v2; // bl
char v3; // al
__int64 v4; // rcx
__int64 v5; // rdx
int v6; // eax

v2 = ((unsigned __int8)rkcs >> 1) & 7;
func = v2;
if ( !v2 )
{
func9();
return;
}
rker &= 0xFCu;
if ( !(unsigned __int16)func11() )
*(&rkcs + 1) &= 0xDFu;
v3 = *(&rkcs + 1) & 0xF7;
*(&rkcs + 1) = v3;
rkcs &= 0x7Fu;
if ( (v3 & 2) != 0 && ((v2 + 7) & 7u) > 1 )
{
*(&rker + 1) |= 1u;
func12();
return;
}
drive = (unsigned __int16)rkda >> 13;
if ( !drives[2 * ((unsigned __int16)rkda >> 13)] )
{
rker |= 0x10u;
func12();
return;
}
v4 = 2LL * ((unsigned __int16)rkda >> 13);
if ( LOWORD(drives[v4 + 1]) )
{
*(&rker + 1) |= 0x10u;
func12();
return;
}
if ( v2 == 1 )
{
if ( WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) )
{
*(&rker + 1) |= 4u;
func12();
return;
}
goto LABEL_26;
}
if ( v2 != 7 )
{
if ( v2 == 6 )
{
WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) = 0;
surface = 0;
sector = 0;
track = 0;
func = 4;
LABEL_12:
if ( func == 4 )
{
rkds |= 0x10u;
func12();
}
ba = (unsigned __int16)rkba + ((((unsigned __int8)rkcs >> 4) & 3) << 16);
v5 = 3 * (unsigned int)(unsigned __int16)track;
if ( surface )
v6 = (unsigned __int16)sector + 12 * (unsigned __int16)track + 2436;
else
v6 = (unsigned __int16)sector + 12 * (unsigned __int16)track;
position = v6 << 8;
LOWORD(drives[2 * drive + 1]) = 1;
if ( func == 2 )
{
if ( (*(&rkcs + 1) & 2) != 0 )
func5(a1, a2, v5, v4 * 8);
else
func2();
}
else if ( func == 3 )
{
func4();
}
else if ( func == 1 && (*(&rkcs + 1) & 2) == 0 )
{
func3();
}
rkba = ba;
rkwc = 0;
LOWORD(drives[2 * drive + 1]) = 0;
func12();
return;
}
LABEL_26:
track = (unsigned __int8)((unsigned __int16)rkda >> 5);
sector = rkda & 0xF;
surface = ((unsigned __int16)rkda >> 4) & 1;
if ( (unsigned __int16)sector > 0xBu )
{
rker |= 4u;
func12();
return;
}
if ( (unsigned __int16)track > 0xCAu )
{
rker |= 8u;
func12();
return;
}
goto LABEL_12;
}
WORD1(drives[2 * ((unsigned __int16)rkda >> 13) + 1]) = 1;
func12();
if ( (rkcs & 0x40) != 0 )
busRequest(&BR5, 220LL);
}

original_code:
void go() {
 func = rkcs.FUN;
 if (func == CONTROL_RESET) {
  controlReset();
  return;
 }
 rker.WCE = rker.CSE = 0;
 if (readRKER() == 0)
  rkcs.ERROR = 0;
 rkcs.SCP = 0;
 rkcs.RDY = 0;
 if (rkcs.FMT && func != WRITE && func != READ) {
  rker.PGE = 1;
  done();
  return;
 }
 drive = (((rkda) >> RKDA_SDRV) & RKDA_ADRV);
 if (drives[drive].file == ((void *)0)) {
  rker.NXD = 1;
  done();
  return;
 }
 if (drives[drive].busy) {
  rker.DRE = 1;
  done();
  return;
 }
 if (func == WRITE && drives[drive].WPS) {
  rker.WLO = 1;
  done();
  return;
 }
 if (func == WRITE_LOCK) {
  drives[drive].WPS = 1;
  done();
  if (rkcs.IDE) {
   busRequest(&BR5, IntVector);
  }
  return;
 }
 if (func == DRIVE_RESET) {
  drives[drive].WPS = 0;
  track = sector = surface = 0;
  func = SEEK;
 }
 else {
  track = (((rkda) >> RKDA_STRAC) & RKDA_ATRAC);
  sector = (((rkda) >> RDKA_SSECT) & RKDA_ASECT);
  surface = (((rkda) >> RKDA_SSUR) & RKDA_ASUR);
 }
 if (sector >= SECTORS) {
  rker.NXS = 1;
  done();
  return;
 }
 if (track >= TRACKSS) {
  rker.NXC = 1;
  done();
  return;
 }
 if (func == SEEK) {
  rkds.SCSA = 1;
  done();
 }
 ba = (rkcs.MEX << sizeof(unsigned short)*8) + rkba;
 position = ((surface) == 0 ? (((track * SECTORS) + sector) * WORDS) : ((((track * SECTORS) + sector) * WORDS) + (TRACKSS * SECTORS * WORDS)));
 drives[drive].busy = 1;
 switch (func) {
  case WRITE:
   if (rkcs.FMT) {
   }
   else {
    rk_write();
   }
   break;
  case READ:
   if (rkcs.FMT) {
    readFMT();
   }
   else {
    rk_read();
   }
   break;
  case WRITE_CHECK:
   writeCheck();
   break;
  case READ_CHECK:
   break;
 }
 rkba = ba & 0177777;
 rkwc = 0;
 drives[drive].busy = 0;
 done();
}


readRKCS

original_code:
unsigned short readRKCS() {
 unsigned short tmp = 0;
 tmp |= rkcs.FUN << 1;
 tmp |= rkcs.MEX << 4;
 tmp |= rkcs.IDE << 6;
 tmp |= rkcs.RDY << 7;
 tmp |= rkcs.SSE << 8;
 tmp |= rkcs.FMT << 10;
 tmp |= rkcs.INH_BA << 11;
 tmp |= rkcs.SCP << 13;
 tmp |= rkcs.HE << 14;
 tmp |= rkcs.ERROR << 15;
 return tmp;
}


writeRKCS

original_code:
void writeRKCS(unsigned short value) {
 rkcs.GO = value & 1;
 rkcs.FUN = (value >> 1) & 7;
 rkcs.MEX = (value >> 4) & 3;
 rkcs.IDE = (value >> 6) & 1;
 rkcs.SSE = (value >> 8) & 1;
 rkcs.FMT = (value >> 10) & 1;
 rkcs.INH_BA = (value >> 11) & 1;
}

variable_types:
value
unsigned short


rkIO

decompiled_code:
__int64 __fastcall rkIO(const char *a1, __int64 a2, __int64 a3, __int64 a4)
{
bool v4; // cf
bool v5; // zf
__int64 result; // rax
const char *v8; // rdi
__int64 v9; // rcx
const char *v10; // rsi
char v11; // al
bool v12; // cf
bool v13; // zf
const char *v14; // rdi
__int64 v15; // rcx
const char *v16; // rsi
__int64 v17; // rdi
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

v4 = (unsigned __int64)&retaddr < 8;
v5 = &retaddr == 0LL;
switch ( (int)a2 )
{
case 261888:
result = readRKDS(a1, a2, a3, a4, a1);
break;
case 261889:
case 261891:
case 261893:
case 261895:
case 261897:
result = 0LL;
break;
case 261890:
result = readRKER(a1, a2, a3, a4, a1);
break;
case 261892:
v8 = "read";
v9 = 5LL;
v10 = a1;
do
{
if ( !v9 )
break;
v4 = *v10 < (unsigned int)*v8;
v5 = *v10++ == *v8++;
--v9;
}
while ( v5 );
v11 = (!v4 && !v5) - v4;
v12 = 0;
v13 = v11 == 0;
if ( v11 )
{
v14 = "write";
v15 = 6LL;
v16 = a1;
do
{
if ( !v15 )
break;
v12 = *v16 < (unsigned int)*v14;
v13 = *v16++ == *v14++;
--v15;
}
while ( v13 );
result = 0LL;
if ( (!v12 && !v13) == v12 )
{
v17 = a3 & 0x1FFF;
writeRKCS(v17);
result = 0LL;
if ( (rkcs & 1) != 0 )
{
go(v17, (__int64)v16);
result = 0LL;
}
}
}
else
{
result = readRKCS(v8, v10);
}
break;
case 261894:
result = (unsigned __int16)rkwc;
if ( !strcmp(a1, "write") )
{
rkwc = a3;
result = 0LL;
}
break;
case 261896:
result = (unsigned __int16)rkba;
if ( !strcmp(a1, "write") )
{
rkba = a3;
result = 0LL;
}
break;
case 261898:
rkda = a3;
result = 0LL;
break;
default:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(const char *a1, __int64 a2, __int64 a3, __int64 a4)
{
bool v4; // cf
bool v5; // zf
__int64 result; // rax
const char *v8; // rdi
__int64 v9; // rcx
const char *v10; // rsi
char v11; // al
bool v12; // cf
bool v13; // zf
const char *v14; // rdi
__int64 v15; // rcx
const char *v16; // rsi
__int64 v17; // rdi
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

v4 = (unsigned __int64)&retaddr < 8;
v5 = &retaddr == 0LL;
switch ( (int)a2 )
{
case 261888:
result = func10(a1, a2, a3, a4, a1);
break;
case 261889:
case 261891:
case 261893:
case 261895:
case 261897:
result = 0LL;
break;
case 261890:
result = func11(a1, a2, a3, a4, a1);
break;
case 261892:
v8 = "read";
v9 = 5LL;
v10 = a1;
do
{
if ( !v9 )
break;
v4 = *v10 < (unsigned int)*v8;
v5 = *v10++ == *v8++;
--v9;
}
while ( v5 );
v11 = (!v4 && !v5) - v4;
v12 = 0;
v13 = v11 == 0;
if ( v11 )
{
v14 = "write";
v15 = 6LL;
v16 = a1;
do
{
if ( !v15 )
break;
v12 = *v16 < (unsigned int)*v14;
v13 = *v16++ == *v14++;
--v15;
}
while ( v13 );
result = 0LL;
if ( (!v12 && !v13) == v12 )
{
v17 = a3 & 0x1FFF;
func15(v17);
result = 0LL;
if ( (rkcs & 1) != 0 )
{
func13(v17, (__int64)v16);
result = 0LL;
}
}
}
else
{
result = func14(v8, v10);
}
break;
case 261894:
result = (unsigned __int16)rkwc;
if ( !strcmp(a1, "write") )
{
rkwc = a3;
result = 0LL;
}
break;
case 261896:
result = (unsigned __int16)rkba;
if ( !strcmp(a1, "write") )
{
rkba = a3;
result = 0LL;
}
break;
case 261898:
rkda = a3;
result = 0LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
unsigned short rkIO(const char * command, unsigned int addr, unsigned short value) {
 switch (addr) {
  case RKDSA:
   return readRKDS();
  case RKERA:
   return readRKER();
  case RKCSA:
   if (strcmp(command, "read") == 0) {
    return readRKCS();
   }
   else if (strcmp(command, "write") == 0) {
    writeRKCS(value&017777);
     if (rkcs.GO) {
      go();
     }
   }
   break;
  case RKWCA:
   if (strcmp(command, "write") == 0) {
    rkwc = value;
   }
   else {
    return rkwc;
   }
   break;
  case RKBAA:
   if (strcmp(command, "write") == 0) {
    rkba = value;
   }
   else {
    return rkba;
   }
   break;
  case RKDAA:
   rkda = value;
   break;
 }
 return 0;
}

canonical_original_code:
unsigned short rkIO(char *command, unsigned int addr, unsigned short value) {
 switch (addr) {
  case RKDSA:
   return readRKDS();
  case RKERA:
   return readRKER();
  case RKCSA:
   if (strcmp(command, "read") == 0) {
    return readRKCS();
   }
   else if (strcmp(command, "write") == 0) {
    writeRKCS(value&017777);
     if (rkcs.GO) {
      go();
     }
   }
   break;
  case RKWCA:
   if (strcmp(command, "write") == 0) {
    rkwc = value;
   }
   else {
    return rkwc;
   }
   break;
  case RKBAA:
   if (strcmp(command, "write") == 0) {
    rkba = value;
   }
   else {
    return rkba;
   }
   break;
  case RKDAA:
   rkda = value;
   break;
 }
 return 0;
}

variable_types:
command
char *

variable_types:
addr
unsigned int


original_code:
void rk_boot_hello() {
 reg[7] = 01020;
 setWord (RKWCA, -25);
 setWord (RKBAA, 512);
 setWord (RKDAA, 0);
 setWord (RKCSA, 05);
}


bootStrap

original_code:
void bootStrap() {
 reg[7] = 000000;
 setWord (RKWCA, -256);
 setWord (RKCSA, 05);
}


isBigEndian

decompiled_code:
__int64 isBigEndian()
{
return 0LL;
}

canonical_decompiled_code:
__int64 func19()
{
return 0LL;
}

original_code:
int isBigEndian() {
 int no = 1;
 char *chk = (char *)&no;
 if (chk[0] == 1) {
  return 0;
 }
 else {
  return 1;
 }
}

variable_types: no int

variable_types:
chk
char *


decompiled_code:
__int64 rk_init()
{
__int64 result; // rax

configureDevice(rkIO, 261888LL, 261902LL);
result = isBigEndian();
BigEndian = result;
rkcs |= 0x80u;
return result;
}

canonical_decompiled_code:
__int64 func20()
{
__int64 result; // rax

configureDevice(rkIO, 261888LL, 261902LL);
result = func19();
BigEndian = result;
rkcs |= 0x80u;
return result;
}

original_code:
void rk_init() {
 configureDevice( rkIO, RKDSA, RKDBA);
 BigEndian = isBigEndian();
 rkcs.RDY = 1;
}


bin

decompiled_code:
int __fastcall bin(unsigned __int16 a1)
{
int v1; // ebp
unsigned int v2; // ebx
int result; // eax

v1 = 16;
v2 = 0x8000;
do
{
if ( ((unsigned __int16)v2 & a1) != 0 )
result = waddnstr(iface2, "1", -1);
else
result = waddnstr(iface2, "0", -1);
v2 >>= 1;
--v1;
}
while ( v1 );
return result;
}

canonical_decompiled_code:
int __fastcall func0(unsigned __int16 a1)
{
int v1; // ebp
unsigned int v2; // ebx
int result; // eax

v1 = 16;
v2 = 0x8000;
do
{
if ( ((unsigned __int16)v2 & a1) != 0 )
result = waddnstr(iface2, "1", -1);
else
result = waddnstr(iface2, "0", -1);
v2 >>= 1;
--v1;
}
while ( v1 );
return result;
}

original_code:
void bin(unsigned short n) {
 unsigned int i;
 i = 1<<(sizeof(n) * 8 - 1);
 while (i > 0) {
  if (n & i)
   waddnstr(iface2,"1",-1);
  else
   waddnstr(iface2,"0",-1);
  i >>= 1;
 }
}

variable_types:
n
unsigned short

variable_types:
i
unsigned int


updateregsdisplay

decompiled_code:
int updateregsdisplay()
{
unsigned __int16 v0; // ax
unsigned __int16 v1; // ax
unsigned __int16 v2; // ax
int result; // eax

werase(iface2);
waddnstr(iface2, "Addr reg:", -1);
v0 = getaddrreg();
bin(v0);
waddnstr(iface2, " Data reg:", -1);
v1 = getdatareg();
bin(v1);
waddnstr(iface2, " Switch reg:", -1);
v2 = getswitchreg();
result = bin(v2);
if ( currentwindow == 1 )
result = wrefresh(iface2);
return result;
}

canonical_decompiled_code:
int func1()
{
unsigned __int16 v0; // ax
unsigned __int16 v1; // ax
unsigned __int16 v2; // ax
int result; // eax

werase(iface2);
waddnstr(iface2, "Addr reg:", -1);
v0 = getaddrreg();
func0(v0);
waddnstr(iface2, " Data reg:", -1);
v1 = getdatareg();
func0(v1);
waddnstr(iface2, " Switch reg:", -1);
v2 = getswitchreg();
result = func0(v2);
if ( currentwindow == 1 )
result = wrefresh(iface2);
return result;
}

original_code:
void updateregsdisplay() {
 werase(iface2);
 waddnstr(iface2,"Addr reg:",-1);
 unsigned long addrreg = getaddrreg();
 bin(addrreg);
 waddnstr(iface2," Data reg:",-1);
 unsigned short datareg = getdatareg();
 bin(datareg);
 waddnstr(iface2," Switch reg:",-1);
 signed short switchreg = getswitchreg();
 bin(switchreg);
 if(currentwindow == 1)
  wrefresh(iface2);
}

canonical_original_code:
void updateregsdisplay() {
 werase(iface2);
 waddnstr(iface2,"Addr reg:",-1);
 unsigned long addrreg = getaddrreg();
 bin(addrreg);
 waddnstr(iface2," Data reg:",-1);
 unsigned short datareg = getdatareg();
 bin(datareg);
 waddnstr(iface2," Switch reg:",-1);
 short switchreg = getswitchreg();
 bin(switchreg);
 if(currentwindow == 1)
  wrefresh(iface2);
}

variable_types:
addrreg
unsigned long

variable_types:
datareg
unsigned short

variable_types: switchreg short


decompiled_code:
int iface_printmenu()
{
waddnstr(
iface,
"\n"
"Menu: \n"
" r: update address and data registers \n"
" s: modify switch register \n"
" d: press dep switch \n"
" e: press exam switch \n"
" l: press load switch \n"
" a: press enable switch \n"
" c: press cont switch",
-1);
return wrefresh(iface);
}

canonical_decompiled_code:
int func2()
{
waddnstr(
iface,
"\n"
"Menu: \n"
" r: update address and data registers \n"
" s: modify switch register \n"
" d: press dep switch \n"
" e: press exam switch \n"
" l: press load switch \n"
" a: press enable switch \n"
" c: press cont switch",
-1);
return wrefresh(iface);
}

original_code:
void iface_printmenu() {
 waddnstr(iface,"\nMenu: \n r: update address and data registers \n s: modify switch register" " \n d: press dep switch \n e: press exam switch \n l: press load switch" " \n a: press enable switch \n c: press cont switch",-1);
 wrefresh(iface);
}


decompiled_code:
int __fastcall iface_keypress(char a1)
{
char v2; // al

if ( ifstate )
{
if ( ifstate == 1 )
{
if ( (unsigned __int8)(a1 - 48) <= 1u )
{
if ( (unsigned __int8)switch_bitcount <= 0xFu )
{
waddch(iface, (unsigned int)a1);
v2 = ++switch_bitcount;
if ( a1 == 49 )
current_switch |= 1 << (16 - v2);
}
}
else if ( a1 == 10 )
{
setWord(262008LL, (unsigned __int16)current_switch);
ifstate = 0;
iface_printmenu();
}
}
}
else
{
switch ( a1 )
{
case 'a':
enable_switch();
waddnstr(iface, "\n enable switch pressed \n", -1);
break;
case 'c':
cont_switch();
waddnstr(iface, "\n cont switch pressed \n", -1);
break;
case 'd':
dep_switch();
waddnstr(iface, "\n dep switch pressed \n", -1);
break;
case 'e':
exam_switch();
waddnstr(iface, "\n exam switch pressed \n", -1);
break;
case 'l':
load_adrs_switch();
waddnstr(iface, "\n load switch pressed \n", -1);
break;
case 'r':
updateregsdisplay();
break;
case 's':
ifstate = 1;
waddnstr(iface, "\n Enter switch register in binary and press enter \n", -1);
switch_bitcount = 0;
current_switch = 0;
break;
default:
return wrefresh(iface);
}
}
return wrefresh(iface);
}

canonical_decompiled_code:
int __fastcall func3(char a1)
{
char v2; // al

if ( ifstate )
{
if ( ifstate == 1 )
{
if ( (unsigned __int8)(a1 - 48) <= 1u )
{
if ( (unsigned __int8)switch_bitcount <= 0xFu )
{
waddch(iface, (unsigned int)a1);
v2 = ++switch_bitcount;
if ( a1 == 49 )
current_switch |= 1 << (16 - v2);
}
}
else if ( a1 == 10 )
{
setWord(262008LL, (unsigned __int16)current_switch);
ifstate = 0;
func2();
}
}
}
else
{
switch ( a1 )
{
case 'a':
enable_switch();
waddnstr(iface, "\n enable switch pressed \n", -1);
break;
case 'c':
cont_switch();
waddnstr(iface, "\n cont switch pressed \n", -1);
break;
case 'd':
dep_switch();
waddnstr(iface, "\n dep switch pressed \n", -1);
break;
case 'e':
exam_switch();
waddnstr(iface, "\n exam switch pressed \n", -1);
break;
case 'l':
load_adrs_switch();
waddnstr(iface, "\n load switch pressed \n", -1);
break;
case 'r':
func1();
break;
case 's':
ifstate = 1;
waddnstr(iface, "\n Enter switch register in binary and press enter \n", -1);
switch_bitcount = 0;
current_switch = 0;
break;
default:
return wrefresh(iface);
}
}
return wrefresh(iface);
}

original_code:
void iface_keypress(char ch) {
 if(ifstate == 0) {
  switch(ch) {
   case 'r':
    updateregsdisplay();
   break;
   case 's':
    ifstate = 1;
    waddnstr(iface,"\n Enter switch register in binary and press enter \n",-1);
    switch_bitcount = 0;
    current_switch = 0;
   break;
   case 'd':
    dep_switch();
    waddnstr(iface,"\n dep switch pressed \n",-1);
   break;
   case 'e':
    exam_switch();
    waddnstr(iface,"\n exam switch pressed \n",-1);
   break;
   case 'l':
    load_adrs_switch();
    waddnstr(iface,"\n load switch pressed \n",-1);
   break;
   case 'a':
    enable_switch();
    waddnstr(iface,"\n enable switch pressed \n",-1);
   break;
   case 'c':
    cont_switch();
    waddnstr(iface,"\n cont switch pressed \n",-1);
   break;
  }
 }
 else if(ifstate == 1) {
  if((ch == '0' || ch == '1') && switch_bitcount < 16) {
   waddch(iface, ch);
   switch_bitcount++;
   if(ch == '1')
    current_switch |= 1 << (16 - switch_bitcount);
  }
  else if(ch == 10) {
   setWord(0777570, current_switch);
   ifstate = 0;
   iface_printmenu();
  }
 }
 wrefresh(iface);
}

variable_types: ch char


setupwindow

decompiled_code:
int setupwindow()
{
int v0; // edx

initscr();
noecho();
iface = newwin(0, 0, 1, 0);
tt = newwin(0, 0, 0, 0);
iface2 = newwin(1, 0, 0, 0);
scrollok(iface, 1);
scrollok(tt, 1);
waddnstr(stdscr, "PDP11 Emulator Started", -1);
waddnstr(tt, "tt window\n", -1);
waddnstr(iface, "iface window\n", -1);
waddnstr(iface2, "iface2 here\n", -1);
wrefresh(stdscr);
v0 = -1;
if ( tt )
v0 = tt->_maxy + 1;
wtouchln(tt, 0, v0, 1);
return wrefresh(tt);
}

canonical_decompiled_code:
int func4()
{
int v0; // edx

initscr();
noecho();
iface = newwin(0, 0, 1, 0);
tt = newwin(0, 0, 0, 0);
iface2 = newwin(1, 0, 0, 0);
scrollok(iface, 1);
scrollok(tt, 1);
waddnstr(stdscr, "PDP11 Emulator Started", -1);
waddnstr(tt, "tt window\n", -1);
waddnstr(iface, "iface window\n", -1);
waddnstr(iface2, "iface2 here\n", -1);
wrefresh(stdscr);
v0 = -1;
if ( tt )
v0 = tt->_maxy + 1;
wtouchln(tt, 0, v0, 1);
return wrefresh(tt);
}

original_code:
void setupwindow() {
        initscr();
        noecho();
        iface = newwin(0, 0, 1, 0);
        tt = newwin(0, 0, 0, 0);
 iface2 = newwin(1, 0, 0, 0);
        scrollok(iface, 1);
        scrollok(tt, 1);
        waddnstr(stdscr,("PDP11 Emulator Started"),-1);
        waddnstr(tt,"tt window\n",-1);
        waddnstr(iface,"iface window\n",-1);
 waddnstr(iface2,"iface2 here\n",-1);
        wrefresh(stdscr);
        wtouchln((tt), 0, ((0 != (const void *)((tt))) ? ((tt)->_maxy + 1) : (-1)), 1);
        wrefresh(tt);
}

canonical_original_code:
void setupwindow() {
        initscr();
        noecho();
        iface = newwin(0, 0, 1, 0);
        tt = newwin(0, 0, 0, 0);
 iface2 = newwin(1, 0, 0, 0);
        scrollok(iface, 1);
        scrollok(tt, 1);
        waddnstr(stdscr,("PDP11 Emulator Started"),-1);
        waddnstr(tt,"tt window\n",-1);
        waddnstr(iface,"iface window\n",-1);
 waddnstr(iface2,"iface2 here\n",-1);
        wrefresh(stdscr);
        wtouchln((tt), 0, ((0 != (void *)((tt))) ? ((tt)->_maxy + 1) : (-1)), 1);
        wrefresh(tt);
}


terminal

decompiled_code:
__int64 terminal()
{
int v0; // edx
int v1; // edx
int v2; // edx
unsigned __int8 v3; // al
unsigned __int8 v4; // bl

currentwindow = 0;
do
{
while ( 1 )
{
do
{
v3 = wgetch(stdscr);
v4 = v3;
}
while ( v3 == 0xFF );
if ( v3 != 14 )
break;
currentwindow = currentwindow == 0;
v0 = -1;
if ( iface )
v0 = iface->_maxy + 1;
wtouchln(iface, 0, v0, 1);
v1 = -1;
if ( iface2 )
v1 = iface2->_maxy + 1;
wtouchln(iface2, 0, v1, 1);
v2 = -1;
if ( tt )
v2 = tt->_maxy + 1;
wtouchln(tt, 0, v2, 1);
if ( currentwindow == 1 )
{
ifstate = 0;
iface_printmenu();
wrefresh(iface);
wrefresh(iface2);
}
else
{
wrefresh(tt);
}
}
if ( currentwindow )
{
if ( currentwindow == 1 )
iface_keypress(v3);
}
else
{
on_keypress(v3);
}
}
while ( v4 != 27 );
return 0LL;
}

canonical_decompiled_code:
__int64 func5()
{
int v0; // edx
int v1; // edx
int v2; // edx
unsigned __int8 v3; // al
unsigned __int8 v4; // bl

currentwindow = 0;
do
{
while ( 1 )
{
do
{
v3 = wgetch(stdscr);
v4 = v3;
}
while ( v3 == 0xFF );
if ( v3 != 14 )
break;
currentwindow = currentwindow == 0;
v0 = -1;
if ( iface )
v0 = iface->_maxy + 1;
wtouchln(iface, 0, v0, 1);
v1 = -1;
if ( iface2 )
v1 = iface2->_maxy + 1;
wtouchln(iface2, 0, v1, 1);
v2 = -1;
if ( tt )
v2 = tt->_maxy + 1;
wtouchln(tt, 0, v2, 1);
if ( currentwindow == 1 )
{
ifstate = 0;
func2();
wrefresh(iface);
wrefresh(iface2);
}
else
{
wrefresh(tt);
}
}
if ( currentwindow )
{
if ( currentwindow == 1 )
func3(v3);
}
else
{
on_keypress(v3);
}
}
while ( v4 != 27 );
return 0LL;
}

original_code:
void *terminal() {
        char ch;
 currentwindow = 0;
        while(ch != 27) {
                ch = wgetch(stdscr);
                if(ch == (-1))
   continue;
  if(ch == 14) {
   currentwindow = !currentwindow;
   wtouchln((iface), 0, ((0 != (const void *)((iface))) ? ((iface)->_maxy + 1) : (-1)), 1);
   wtouchln((iface2), 0, ((0 != (const void *)((iface2))) ? ((iface2)->_maxy + 1) : (-1)), 1);
   wtouchln((tt), 0, ((0 != (const void *)((tt))) ? ((tt)->_maxy + 1) : (-1)), 1);
   if(currentwindow == 1) {
    ifstate = 0;
    iface_printmenu();
    wrefresh(iface);
    wrefresh(iface2);
   }
   else {
    wrefresh(tt);
   }
  }
  else if(currentwindow == 0) {
                 on_keypress(ch);
  }
  else if(currentwindow == 1) {
   iface_keypress(ch);
  }
        }
 return 0;
}

canonical_original_code:
void *terminal() {
        char ch;
 currentwindow = 0;
        while(ch != 27) {
                ch = wgetch(stdscr);
                if(ch == (-1))
   continue;
  if(ch == 14) {
   currentwindow = !currentwindow;
   wtouchln((iface), 0, ((0 != (void *)((iface))) ? ((iface)->_maxy + 1) : (-1)), 1);
   wtouchln((iface2), 0, ((0 != (void *)((iface2))) ? ((iface2)->_maxy + 1) : (-1)), 1);
   wtouchln((tt), 0, ((0 != (void *)((tt))) ? ((tt)->_maxy + 1) : (-1)), 1);
   if(currentwindow == 1) {
    ifstate = 0;
    iface_printmenu();
    wrefresh(iface);
    wrefresh(iface2);
   }
   else {
    wrefresh(tt);
   }
  }
  else if(currentwindow == 0) {
                 on_keypress(ch);
  }
  else if(currentwindow == 1) {
   iface_keypress(ch);
  }
        }
 return 0;
}


consoleio

decompiled_code:
__int64 __fastcall consoleio(const char *a1, int a2, __int16 a3)
{
__int64 result; // rax

updateregsdisplay();
if ( strcmp(a1, "read") || (result = (unsigned __int16)switchreg, a2 != 262008) )
{
if ( !strcmp(a1, "write") && a2 == 262008 )
{
switchreg = a3;
result = 0LL;
}
else
{
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1, int a2, __int16 a3)
{
__int64 result; // rax

updateregsdisplay();
if ( strcmp(a1, "read") || (result = (unsigned __int16)switchreg, a2 != 262008) )
{
if ( !strcmp(a1, "write") && a2 == 262008 )
{
switchreg = a3;
result = 0LL;
}
else
{
result = 0LL;
}
}
return result;
}

original_code:
unsigned short consoleio(const char * command, unsigned int addr, unsigned short value) {
 updateregsdisplay();
 if(!strcmp(command, "read") && addr == 0777570) {
  return switchreg;
 }
 if(!strcmp(command, "write") && addr == 0777570) {
  switchreg = value;
 }
 return 0;
}

canonical_original_code:
unsigned short consoleio(char *command, unsigned int addr, unsigned short value) {
 updateregsdisplay();
 if(!strcmp(command, "read") && addr == 0777570) {
  return switchreg;
 }
 if(!strcmp(command, "write") && addr == 0777570) {
  switchreg = value;
 }
 return 0;
}


decompiled_code:
__int64 load_adrs_switch()
{
addrreg = (unsigned __int16)switchreg;
return updateregsdisplay();
}

canonical_decompiled_code:
__int64 func1()
{
addrreg = (unsigned __int16)switchreg;
return updateregsdisplay();
}

original_code:
void load_adrs_switch() {
 addrreg = switchreg;
 updateregsdisplay();
}


decompiled_code:
__int64 exam_switch()
{
datareg = getWord((unsigned int)addrreg);
++addrreg;
return updateregsdisplay();
}

canonical_decompiled_code:
__int64 func2()
{
datareg = getWord((unsigned int)addrreg);
++addrreg;
return updateregsdisplay();
}

original_code:
void exam_switch() {
 datareg = getWord(addrreg);
 addrreg++;
 updateregsdisplay();
}


decompiled_code:
int cont_switch()
{
int result; // eax

if ( halt )
{
fetchEx();
result = wprintw(tt, "c");
}
return result;
}

canonical_decompiled_code:
int func3()
{
int result; // eax

if ( halt )
{
fetchEx();
result = wprintw(tt, "c");
}
return result;
}

original_code:
void cont_switch() {
 if(halt) {
  fetchEx();
  wprintw(tt, "c");
 }
}


decompiled_code:
void enable_switch()
{
halt = halt == 0;
}

canonical_decompiled_code:
void func4()
{
halt = halt == 0;
}

original_code:
void enable_switch() {
 halt = !halt;
}

canonical_original_code:
void enable_switch() {
 halt = !halt;
}


decompiled_code:
void start_switch()
{
;
}

canonical_decompiled_code:
void func5()
{
;
}

original_code:
void start_switch() {
}

canonical_original_code:
void start_switch() {
}


decompiled_code:
__int64 dep_switch()
{
if ( (addrreg & 1) != 0 )
--addrreg;
setWord((unsigned int)addrreg, (unsigned __int16)switchreg);
addrreg += 2LL;
return updateregsdisplay();
}

canonical_decompiled_code:
__int64 func6()
{
if ( (addrreg & 1) != 0 )
--addrreg;
setWord((unsigned int)addrreg, (unsigned __int16)switchreg);
addrreg += 2LL;
return updateregsdisplay();
}

original_code:
void dep_switch() {
 if(addrreg % 2 != 0) {
  addrreg--;
 }
 setWord(addrreg, switchreg);
 addrreg += 2;
 updateregsdisplay();
}


gethalt

decompiled_code:
__int64 gethalt()
{
return (unsigned __int8)halt;
}

canonical_decompiled_code:
__int64 func7()
{
return (unsigned __int8)halt;
}

original_code:
char gethalt() {
 return halt;
}

canonical_original_code:
char gethalt() {
 return halt;
}

return_type: char


sethalt

decompiled_code:
void __fastcall sethalt(char a1)
{
halt = a1;
}

canonical_decompiled_code:
void __fastcall func8(char a1)
{
halt = a1;
}

original_code:
void sethalt(char hlt) {
 halt = hlt;
}

canonical_original_code:
void sethalt(char hlt) {
 halt = hlt;
}

variable_types: hlt char


getdatareg

decompiled_code:
__int64 getdatareg()
{
return (unsigned __int16)datareg;
}

canonical_decompiled_code:
__int64 func9()
{
return (unsigned __int16)datareg;
}

original_code:
unsigned short getdatareg() {
 return datareg;
}


getswitchreg

decompiled_code:
__int64 getswitchreg()
{
return (unsigned __int16)switchreg;
}

canonical_decompiled_code:
__int64 func10()
{
return (unsigned __int16)switchreg;
}

original_code:
unsigned short getswitchreg() {
 return switchreg;
}


getaddrreg

decompiled_code:
__int64 getaddrreg()
{
return addrreg;
}

canonical_decompiled_code:
__int64 func11()
{
return addrreg;
}

original_code:
unsigned long getaddrreg() {
 return addrreg;
}

return_type: unsigned long


lineclockio

decompiled_code:
__int64 lineclockio()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func0()
{
return 1LL;
}

original_code:
unsigned short lineclockio(const char * command, unsigned int addr, unsigned short value) {
 if(!strcmp(command, "read")) {
  return 1;
 }
 return 1;
}

canonical_original_code:
unsigned short lineclockio(char *command, unsigned int addr, unsigned short value) {
 if(!strcmp(command, "read")) {
  return 1;
 }
 return 1;
}


startlineclock

decompiled_code:
clock_t startlineclock()
{
clock_t result; // rax

result = clock() + 20000;
endclock = result;
return result;
}

canonical_decompiled_code:
clock_t func1()
{
clock_t result; // rax

result = clock() + 20000;
endclock = result;
return result;
}

original_code:
void startlineclock() {
 endclock = clock() + (((__clock_t) 1000000) / 50);
}

canonical_original_code:
void startlineclock() {
 endclock = clock() + (((long) 1000000) / 50);
}


lineclock

decompiled_code:
clock_t lineclock()
{
clock_t result; // rax

result = clock();
if ( result >= endclock )
{
endclock = clock() + 20000;
result = busRequest(&BR6, 64LL);
}
return result;
}

canonical_decompiled_code:
clock_t func2()
{
clock_t result; // rax

result = clock();
if ( result >= endclock )
{
endclock = clock() + 20000;
result = busRequest(&BR6, 64LL);
}
return result;
}

original_code:
void lineclock() {
 if(clock() >= endclock) {
  endclock = clock() + (((__clock_t) 1000000) / 50);
  busRequest(&BR6, 0100);
 }
}

canonical_original_code:
void lineclock() {
 if(clock() >= endclock) {
  endclock = clock() + (((long) 1000000) / 50);
  busRequest(&BR6, 0100);
 }
}