decompiled_code:
void __fastcall utils_store(__int64 a1, int a2, unsigned int a3, __int16 a4)
{
if ( a3 <= 0xFFFFF )
{
switch ( a4 )
{
case 16:
*(_BYTE *)(a1 + a3) = a2;
*(_BYTE *)(a1 + a3 + 1) = BYTE1(a2);
break;
case 32:
*(_BYTE *)(a1 + a3) = a2;
*(_BYTE *)(a1 + a3 + 1) = BYTE1(a2);
*(_BYTE *)(a1 + a3 + 2) = BYTE2(a2);
*(_BYTE *)(a1 + a3 + 3) = HIBYTE(a2);
break;
case 8:
*(_BYTE *)(a1 + a3) = a2;
break;
}
}
}

original_code:
void
utils_store(ram_t *ram, uint32_t word, uint32_t adr, uint16_t bits)
{
    if (adr >= (1024 * 1024))
        return;
    switch (bits)
    {
        case 32:
            ram->address [adr] = (uint8_t)(word) & 0xFF;
            ram->address [adr + 1] = (uint8_t)(word >> 8) & 0xFF;
            ram->address [adr + 2] = (uint8_t)(word >> 16) & 0xFF;
            ram->address [adr + 3] = (uint8_t)(word >> 24)& 0xFF;
            break;
        case 16:
            ram->address [adr] = (uint8_t)(word) & 0xFF;
            ram->address [adr + 1] = (uint8_t)(word >> 8) & 0xFF;
            break;
        case 8:
            ram->address [adr] = (uint8_t)(word) & 0xFF;
            break;
        default:
            return;
    }
}

canonical_original_code:
void utils_store(struct ram_s *ram, unsigned int word, unsigned int adr, unsigned short bits)
{
    if (adr >= (1024 * 1024))
        return;
    switch (bits)
    {
        case 32:
            ram->address [adr] = (unsigned char)(word) & 0xFF;
            ram->address [adr + 1] = (unsigned char)(word >> 8) & 0xFF;
            ram->address [adr + 2] = (unsigned char)(word >> 16) & 0xFF;
            ram->address [adr + 3] = (unsigned char)(word >> 24)& 0xFF;
            break;
        case 16:
            ram->address [adr] = (unsigned char)(word) & 0xFF;
            ram->address [adr + 1] = (unsigned char)(word >> 8) & 0xFF;
            break;
        case 8:
            ram->address [adr] = (unsigned char)(word) & 0xFF;
            break;
        default:
            return;
    }
}

variable_types:
word
unsigned int

variable_types:
adr
unsigned int

variable_types:
bits
unsigned short


decompiled_code:
__int64 __fastcall utils_load(__int64 a1, _DWORD *a2, unsigned int a3, __int16 a4)
{
__int64 result; // rax

if ( a3 <= 0xFFFFF )
{
switch ( a4 )
{
case 16:
result = *(unsigned __int8 *)(a1 + a3) | (*(unsigned __int8 *)(a1 + a3 + 1) << 8);
*a2 = result;
break;
case 32:
result = (*(unsigned __int8 *)(a1 + a3 + 3) << 24) | *(unsigned __int8 *)(a1 + a3) | (*(unsigned __int8 *)(a1 + a3 + 2) << 16) | (*(unsigned __int8 *)(a1 + a3 + 1) << 8);
*a2 = result;
break;
case 8:
result = *(unsigned __int8 *)(a1 + a3);
*a2 = result;
break;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, _DWORD *a2, unsigned int a3, __int16 a4)
{
__int64 result; // rax

if ( a3 <= 0xFFFFF )
{
switch ( a4 )
{
case 16:
result = *(unsigned __int8 *)(a1 + a3) | (*(unsigned __int8 *)(a1 + a3 + 1) << 8);
*a2 = result;
break;
case 32:
result = (*(unsigned __int8 *)(a1 + a3 + 3) << 24) | *(unsigned __int8 *)(a1 + a3) | (*(unsigned __int8 *)(a1 + a3 + 2) << 16) | (*(unsigned __int8 *)(a1 + a3 + 1) << 8);
*a2 = result;
break;
case 8:
result = *(unsigned __int8 *)(a1 + a3);
*a2 = result;
break;
}
}
return result;
}

original_code:
void
utils_load(ram_t *ram, uint32_t *dst, uint32_t adr, uint16_t bits)
{
    if(adr >= (1024 * 1024))
        return;
    switch (bits)
    {
        case 32:
            *dst = ram->address[adr] |
              (ram->address[adr+1] << 8) |
              (ram->address[adr+2] << 16) |
              (ram->address[adr+3] << 24);
            break;
        case 16:
            *dst = (ram->address [adr]) |
                   (ram->address [adr+1] << 8);
            break;
        case 8:
            *dst = ram->address[adr];
            break;
        default:
            return;
    }
}

canonical_original_code:
void utils_load(struct ram_s *ram, unsigned int *dst, unsigned int adr, unsigned short bits)
{
    if(adr >= (1024 * 1024))
        return;
    switch (bits)
    {
        case 32:
            *dst = ram->address[adr] |
              (ram->address[adr+1] << 8) |
              (ram->address[adr+2] << 16) |
              (ram->address[adr+3] << 24);
            break;
        case 16:
            *dst = (ram->address [adr]) |
                   (ram->address [adr+1] << 8);
            break;
        case 8:
            *dst = ram->address[adr];
            break;
        default:
            return;
    }
}

variable_types: struct ram_s { unsigned char address[-1]; struct instr_s { unsigned char opcode; unsigned char dst_src; unsigned short constant; } *instruction; } *

variable_types:
dst
unsigned int *

return_type: void

user_defined_types: struct ram_s { unsigned char address[-1]; struct instr_s *instruction; }


decompiled_code:
__int64 __fastcall utils_cpy_chunk(__int64 a1, int a2, unsigned int a3, int a4)
{
int v5; // esi
int v6; // er8
char v7; // cl
__int64 result; // rax

if ( a4 )
{
v5 = a4 + a3;
v6 = a2 - a3;
do
{
v7 = *(_BYTE *)(a1 + a3);
result = v6 + a3++;
*(_BYTE *)(a1 + result) = v7;
}
while ( v5 != a3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, int a2, unsigned int a3, int a4)
{
int v5; // esi
int v6; // er8
char v7; // cl
__int64 result; // rax

if ( a4 )
{
v5 = a4 + a3;
v6 = a2 - a3;
do
{
v7 = *(_BYTE *)(a1 + a3);
result = v6 + a3++;
*(_BYTE *)(a1 + result) = v7;
}
while ( v5 != a3 );
}
return result;
}

original_code:
void
utils_cpy_chunk(ram_t *ram, uint32_t dst, uint32_t src, uint32_t bytes)
{
    unsigned int i;
    for (i = 0; i < bytes; i++)
    {
        ram->address [dst + i] = ram->address [src + i];
    }
}

canonical_original_code:
void utils_cpy_chunk(struct ram_s *ram, unsigned int dst, unsigned int src, unsigned int bytes)
{
    unsigned int i;
    for (i = 0; i < bytes; i++)
    {
        ram->address [dst + i] = ram->address [src + i];
    }
}

variable_types:
dst
unsigned int

variable_types:
src
unsigned int

variable_types:
bytes
unsigned int

variable_types:
i
unsigned int

user_defined_types: struct instr_s { unsigned char opcode; unsigned char dst_src; unsigned short constant; }


decompiled_code:
void __fastcall utils_compare(_DWORD *a1, int a2, int a3)
{
unsigned int v3; // esi

v3 = a2 - a3;
if ( v3 )
*a1 = 2 * (v3 >> 31);
else
*a1 = 1;
}

canonical_decompiled_code:
void __fastcall func4(_DWORD *a1, int a2, int a3)
{
unsigned int v3; // esi

v3 = a2 - a3;
if ( v3 )
*a1 = 2 * (v3 >> 31);
else
*a1 = 1;
}

original_code:
void
utils_compare(uint32_t *reg_cmp, uint32_t w1, uint32_t w2)
{
    int diff;
    *reg_cmp = 0;
    diff = (int)w1 - (int)w2;
    if(!diff) *reg_cmp = 1;
    if(diff < 0) *reg_cmp = 2;
}

canonical_original_code:
void utils_compare(unsigned int *reg_cmp, unsigned int w1, unsigned int w2)
{
    int diff;
    *reg_cmp = 0;
    diff = (int)w1 - (int)w2;
    if(!diff) *reg_cmp = 1;
    if(diff < 0) *reg_cmp = 2;
}

variable_types: diff int


original_code:
void
cpu_init(cpu_t *cpu)
{
 memset (cpu->registers, 0, sizeof (cpu->registers));
 memset (cpu->ports, 0, sizeof (cpu->ports));
 cpu->adr_mode = 32;
 cpu->state = STATE_HALT;
 cpu->registers [REGISTER_STACKPOINTER] = 0xFFFFF - 8;
 cpu->registers [REGISTER_STACKBASE] = 0xFFFFF - 4;
 cpu->registers [REGISTER_OFFSET] = 0;
 cpu->registers [REGISTER_PC] = 0;
    cpu->cycle = 0;
}

canonical_original_code:
void cpu_init(struct cpu_s *cpu)
{
 memset (cpu->registers, 0, sizeof (cpu->registers));
 memset (cpu->ports, 0, sizeof (cpu->ports));
 cpu->adr_mode = 32;
 cpu->state = STATE_HALT;
 cpu->registers [REGISTER_STACKPOINTER] = 0xFFFFF - 8;
 cpu->registers [REGISTER_STACKBASE] = 0xFFFFF - 4;
 cpu->registers [REGISTER_OFFSET] = 0;
 cpu->registers [REGISTER_PC] = 0;
    cpu->cycle = 0;
}

variable_types: struct cpu_s { unsigned char state; unsigned char adr_mode; unsigned int registers[-1]; unsigned int ports[-1]; unsigned int cycle; } *


decompiled_code:
int __fastcall cpu_process(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
unsigned int v4; // er15
unsigned int v5; // er13
__int64 v6; // r8
unsigned int v7; // er12
unsigned int v8; // er14
__int64 v9; // rax
__int64 v10; // rsi
__int64 v11; // rdx
__int64 v12; // rdx
__int64 v13; // rsi
__int64 v14; // rsi
__int64 v15; // rdx
__int64 v16; // rsi
__int64 v17; // rdx
__int64 v18; // rcx
__int64 v19; // rcx
__int64 v20; // rcx
__int64 v21; // rdx
__int64 v22; // rdx
__int64 v23; // rcx
__int64 v24; // rcx
__int64 v25; // rcx
__int64 v26; // rsi
__int64 v27; // rcx
__int64 v28; // rsi
__int64 v29; // rdx
unsigned __int8 v31; // [rsp+Fh] [rbp-49h]
char v32; // [rsp+Fh] [rbp-49h]
char v33; // [rsp+Fh] [rbp-49h]
char v34; // [rsp+Fh] [rbp-49h]
char v35; // [rsp+Fh] [rbp-49h]
char v36; // [rsp+Fh] [rbp-49h]
char v37; // [rsp+Fh] [rbp-49h]
char v38; // [rsp+Fh] [rbp-49h]
char v39; // [rsp+Fh] [rbp-49h]
char v40; // [rsp+Fh] [rbp-49h]
char v41; // [rsp+Fh] [rbp-49h]
char v42; // [rsp+Fh] [rbp-49h]
unsigned int v43; // [rsp+1Ch] [rbp-3Ch] BYREF

v2 = *(unsigned int *)(a1 + 60);
if ( (unsigned int)v2 > 0xFFFFB )
{
*(_BYTE *)a1 = 2;
LODWORD(v9) = puts("Halt. Program counter out of bounds.");
}
else
{
utils_load(a2, &v43, v2, 32LL);
v4 = (unsigned __int16)v43;
v5 = HIBYTE(v43);
v6 = HIWORD(v43);
LOBYTE(v6) = BYTE2(v43) >> 4;
v7 = BYTE2(v43) & 0xF;
v8 = (unsigned __int16)v43 | (v7 << 16);
if ( v43 > 0x35FFFFFF )
{
*(_BYTE *)a1 = 2;
v41 = v6;
LODWORD(v9) = printf("Error: unrecognized opcode: %x\n", v5);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v41;
}
else
{
LODWORD(v9) = HIBYTE(v43);
switch ( v5 )
{
case 0u:
goto LABEL_6;
case 1u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = v8;
goto LABEL_6;
case 2u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 3u:
v40 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_load(
a2,
a1 + 4LL * (unsigned __int8)(v6 + 1),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
*(unsigned __int8 *)(a1 + 1));
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v40;
break;
case 4u:
v39 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_store(
a2,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned __int8 *)(a1 + 1),
v6);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v39;
break;
case 5u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) += *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 6u:
v27 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v27 + 4) - *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v27 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 7u:
v23 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) * *(_DWORD *)(a1 + 4 * v23 + 4);
*(_DWORD *)(a1 + 4 * v23 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 8u:
v25 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v25 + 4) / *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v25 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 9u:
v24 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v24 + 4) / *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v24 + 4) %= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xAu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4 * v9 + 4) == 0;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xBu:
v20 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) & *(_DWORD *)(a1 + 4 * v20 + 4);
*(_DWORD *)(a1 + 4 * v20 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xCu:
v19 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) | *(_DWORD *)(a1 + 4 * v19 + 4);
*(_DWORD *)(a1 + 4 * v19 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xDu:
v18 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) ^ *(_DWORD *)(a1 + 4 * v18 + 4);
*(_DWORD *)(a1 + 4 * v18 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xEu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) <<= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xFu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) >>= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x10u:
v37 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_compare(
a1 + 40,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4));
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v37;
break;
case 0x11u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4LL * *(unsigned int *)(a1 + 44) + 68);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x12u:
v26 = *(unsigned int *)(a1 + 44);
if ( (unsigned int)v26 > 4 )
{
v42 = BYTE2(v43) >> 4;
LODWORD(v9) = printf("Warning: invalid port %d in OUT instruction\n", v26);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v42;
}
else
{
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4);
*(_DWORD *)(a1 + 4 * v26 + 68) = v9;
v10 = *(unsigned int *)(a1 + 60);
}
break;
case 0x13u:
*(_BYTE *)(a1 + 1) = 32;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x14u:
*(_BYTE *)(a1 + 1) = 16;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x15u:
*(_BYTE *)(a1 + 1) = 8;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x16u:
*(_BYTE *)a1 = 1;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x17u:
*(_BYTE *)a1 = 2;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x18u:
v36 = BYTE2(v43) >> 4;
v22 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v22;
LODWORD(v9) = utils_store(a2, *(unsigned int *)(a1 + 4 * (v6 & 0xF) + 4), v22, 32LL, v6);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v36;
break;
case 0x19u:
v32 = BYTE2(v43) >> 4;
v12 = *(unsigned int *)(a1 + 56);
v13 = a1 + 4LL * (unsigned __int8)(v6 + 1);
goto LABEL_14;
case 0x1Au:
v28 = *(unsigned int *)(a1 + 60);
v29 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v29;
LODWORD(v9) = utils_store(a2, v28, v29, 32LL, v6);
goto LABEL_12;
case 0x1Bu:
goto LABEL_12;
case 0x1Cu:
goto LABEL_20;
case 0x1Du:
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
goto LABEL_6;
goto LABEL_12;
case 0x1Eu:
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
goto LABEL_6;
goto LABEL_12;
case 0x1Fu:
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
goto LABEL_6;
goto LABEL_12;
case 0x20u:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
goto LABEL_6;
goto LABEL_12;
case 0x21u:
case 0x30u:
v32 = BYTE2(v43) >> 4;
v12 = *(unsigned int *)(a1 + 56);
v13 = a1 + 60;
LABEL_14:
LODWORD(v9) = utils_load(a2, v13, v12, 32LL);
*(_DWORD *)(a1 + 56) += 4;
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v32;
break;
case 0x22u:
v38 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_cpy_chunk(
a2,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
153600LL);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v38;
break;
case 0x23u:
v16 = *(unsigned int *)(a1 + 60);
v34 = BYTE2(v43) >> 4;
v17 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v17;
utils_store(a2, v16, v17, 32LL, v6);
LOBYTE(v6) = v34;
LABEL_20:
v9 = v6 & 0xF;
v10 = *(unsigned int *)(a1 + 4 * v9 + 4);
*(_DWORD *)(a1 + 60) = v10;
break;
case 0x24u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
break;
goto LABEL_11;
case 0x25u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
break;
goto LABEL_11;
case 0x26u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
break;
goto LABEL_11;
case 0x27u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
break;
LABEL_11:
v11 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v11;
LODWORD(v9) = utils_store(a2, v10, v11, 32LL, v6);
LABEL_12:
LODWORD(v10) = v8;
goto LABEL_9;
case 0x28u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = v8 + *(_DWORD *)(a1 + 48);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x29u:
v10 = *(unsigned int *)(a1 + 60);
v35 = BYTE2(v43) >> 4;
v21 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v21;
goto LABEL_35;
case 0x2Au:
goto LABEL_16;
case 0x2Bu:
goto LABEL_18;
case 0x2Cu:
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Du:
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Eu:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Fu:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
{
LABEL_6:
v10 = *(unsigned int *)(a1 + 60);
}
else
{
LABEL_16:
v10 = *(_DWORD *)(a1 + 48) + v8;
*(_DWORD *)(a1 + 60) = v10;
}
break;
case 0x31u:
v14 = *(unsigned int *)(a1 + 60);
v33 = BYTE2(v43) >> 4;
v15 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v15;
utils_store(a2, v14, v15, 32LL, v6);
LOBYTE(v6) = v33;
LABEL_18:
v9 = v6 & 0xF;
v10 = (unsigned int)(*(_DWORD *)(a1 + 4 * v9 + 4) + *(_DWORD *)(a1 + 48));
*(_DWORD *)(a1 + 60) = v10;
break;
case 0x32u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
break;
goto LABEL_34;
case 0x33u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
break;
goto LABEL_34;
case 0x34u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
break;
goto LABEL_34;
case 0x35u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
break;
LABEL_34:
v35 = BYTE2(v43) >> 4;
v21 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v21;
LABEL_35:
LODWORD(v9) = utils_store(a2, v10, v21, 32LL, v6);
v10 = *(_DWORD *)(a1 + 48) + v8;
LOBYTE(v6) = v35;
*(_DWORD *)(a1 + 60) = v10;
break;
}
}
if ( (unsigned int)v10 > 0xFFFFF )
{
v31 = v6;
printf("Error: PC at 0x%lx\n", v10);
puts("Last instruction: ");
LODWORD(v9) = printf("0x%x 0x%x 0x%x 0x%x li:0x%x\n", v5, v31, v7, v4, v8);
LODWORD(v10) = *(_DWORD *)(a1 + 60);
}
LABEL_9:
++*(_DWORD *)(a1 + 88);
*(_DWORD *)(a1 + 60) = v10 + 4;
}
return v9;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
unsigned int v4; // er15
unsigned int v5; // er13
__int64 v6; // r8
unsigned int v7; // er12
unsigned int v8; // er14
__int64 v9; // rax
__int64 v10; // rsi
__int64 v11; // rdx
__int64 v12; // rdx
__int64 v13; // rsi
__int64 v14; // rsi
__int64 v15; // rdx
__int64 v16; // rsi
__int64 v17; // rdx
__int64 v18; // rcx
__int64 v19; // rcx
__int64 v20; // rcx
__int64 v21; // rdx
__int64 v22; // rdx
__int64 v23; // rcx
__int64 v24; // rcx
__int64 v25; // rcx
__int64 v26; // rsi
__int64 v27; // rcx
__int64 v28; // rsi
__int64 v29; // rdx
unsigned __int8 v31; // [rsp+Fh] [rbp-49h]
char v32; // [rsp+Fh] [rbp-49h]
char v33; // [rsp+Fh] [rbp-49h]
char v34; // [rsp+Fh] [rbp-49h]
char v35; // [rsp+Fh] [rbp-49h]
char v36; // [rsp+Fh] [rbp-49h]
char v37; // [rsp+Fh] [rbp-49h]
char v38; // [rsp+Fh] [rbp-49h]
char v39; // [rsp+Fh] [rbp-49h]
char v40; // [rsp+Fh] [rbp-49h]
char v41; // [rsp+Fh] [rbp-49h]
char v42; // [rsp+Fh] [rbp-49h]
unsigned int v43; // [rsp+1Ch] [rbp-3Ch] BYREF

v2 = *(unsigned int *)(a1 + 60);
if ( (unsigned int)v2 > 0xFFFFB )
{
*(_BYTE *)a1 = 2;
LODWORD(v9) = puts("Halt. Program counter out of bounds.");
}
else
{
utils_load(a2, &v43, v2, 32LL);
v4 = (unsigned __int16)v43;
v5 = HIBYTE(v43);
v6 = HIWORD(v43);
LOBYTE(v6) = BYTE2(v43) >> 4;
v7 = BYTE2(v43) & 0xF;
v8 = (unsigned __int16)v43 | (v7 << 16);
if ( v43 > 0x35FFFFFF )
{
*(_BYTE *)a1 = 2;
v41 = v6;
LODWORD(v9) = printf("Error: unrecognized opcode: %x\n", v5);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v41;
}
else
{
LODWORD(v9) = HIBYTE(v43);
switch ( v5 )
{
case 0u:
goto LABEL_6;
case 1u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = v8;
goto LABEL_6;
case 2u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 3u:
v40 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_load(
a2,
a1 + 4LL * (unsigned __int8)(v6 + 1),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
*(unsigned __int8 *)(a1 + 1));
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v40;
break;
case 4u:
v39 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_store(
a2,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned __int8 *)(a1 + 1),
v6);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v39;
break;
case 5u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) += *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 6u:
v27 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v27 + 4) - *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v27 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 7u:
v23 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) * *(_DWORD *)(a1 + 4 * v23 + 4);
*(_DWORD *)(a1 + 4 * v23 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 8u:
v25 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v25 + 4) / *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v25 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 9u:
v24 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4 * v24 + 4) / *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
*(_DWORD *)(a1 + 4 * v24 + 4) %= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xAu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4 * v9 + 4) == 0;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xBu:
v20 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) & *(_DWORD *)(a1 + 4 * v20 + 4);
*(_DWORD *)(a1 + 4 * v20 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xCu:
v19 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) | *(_DWORD *)(a1 + 4 * v19 + 4);
*(_DWORD *)(a1 + 4 * v19 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xDu:
v18 = BYTE2(v43) >> 4;
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4) ^ *(_DWORD *)(a1 + 4 * v18 + 4);
*(_DWORD *)(a1 + 4 * v18 + 4) = v9;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xEu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) <<= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0xFu:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) >>= *(_DWORD *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x10u:
v37 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_compare(
a1 + 40,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4));
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v37;
break;
case 0x11u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = *(_DWORD *)(a1 + 4LL * *(unsigned int *)(a1 + 44) + 68);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x12u:
v26 = *(unsigned int *)(a1 + 44);
if ( (unsigned int)v26 > 4 )
{
v42 = BYTE2(v43) >> 4;
LODWORD(v9) = printf("Warning: invalid port %d in OUT instruction\n", v26);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v42;
}
else
{
LODWORD(v9) = *(_DWORD *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4);
*(_DWORD *)(a1 + 4 * v26 + 68) = v9;
v10 = *(unsigned int *)(a1 + 60);
}
break;
case 0x13u:
*(_BYTE *)(a1 + 1) = 32;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x14u:
*(_BYTE *)(a1 + 1) = 16;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x15u:
*(_BYTE *)(a1 + 1) = 8;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x16u:
*(_BYTE *)a1 = 1;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x17u:
*(_BYTE *)a1 = 2;
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x18u:
v36 = BYTE2(v43) >> 4;
v22 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v22;
LODWORD(v9) = utils_store(a2, *(unsigned int *)(a1 + 4 * (v6 & 0xF) + 4), v22, 32LL, v6);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v36;
break;
case 0x19u:
v32 = BYTE2(v43) >> 4;
v12 = *(unsigned int *)(a1 + 56);
v13 = a1 + 4LL * (unsigned __int8)(v6 + 1);
goto LABEL_14;
case 0x1Au:
v28 = *(unsigned int *)(a1 + 60);
v29 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v29;
LODWORD(v9) = utils_store(a2, v28, v29, 32LL, v6);
goto LABEL_12;
case 0x1Bu:
goto LABEL_12;
case 0x1Cu:
goto LABEL_20;
case 0x1Du:
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
goto LABEL_6;
goto LABEL_12;
case 0x1Eu:
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
goto LABEL_6;
goto LABEL_12;
case 0x1Fu:
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
goto LABEL_6;
goto LABEL_12;
case 0x20u:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
goto LABEL_6;
goto LABEL_12;
case 0x21u:
case 0x30u:
v32 = BYTE2(v43) >> 4;
v12 = *(unsigned int *)(a1 + 56);
v13 = a1 + 60;
LABEL_14:
LODWORD(v9) = utils_load(a2, v13, v12, 32LL);
*(_DWORD *)(a1 + 56) += 4;
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v32;
break;
case 0x22u:
v38 = BYTE2(v43) >> 4;
LODWORD(v9) = utils_cpy_chunk(
a2,
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) >> 4) + 4),
*(unsigned int *)(a1 + 4LL * (BYTE2(v43) & 0xF) + 4),
153600LL);
v10 = *(unsigned int *)(a1 + 60);
LOBYTE(v6) = v38;
break;
case 0x23u:
v16 = *(unsigned int *)(a1 + 60);
v34 = BYTE2(v43) >> 4;
v17 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v17;
utils_store(a2, v16, v17, 32LL, v6);
LOBYTE(v6) = v34;
LABEL_20:
v9 = v6 & 0xF;
v10 = *(unsigned int *)(a1 + 4 * v9 + 4);
*(_DWORD *)(a1 + 60) = v10;
break;
case 0x24u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
break;
goto LABEL_11;
case 0x25u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
break;
goto LABEL_11;
case 0x26u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
break;
goto LABEL_11;
case 0x27u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
break;
LABEL_11:
v11 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v11;
LODWORD(v9) = utils_store(a2, v10, v11, 32LL, v6);
LABEL_12:
LODWORD(v10) = v8;
goto LABEL_9;
case 0x28u:
v9 = BYTE2(v43) >> 4;
*(_DWORD *)(a1 + 4 * v9 + 4) = v8 + *(_DWORD *)(a1 + 48);
v10 = *(unsigned int *)(a1 + 60);
break;
case 0x29u:
v10 = *(unsigned int *)(a1 + 60);
v35 = BYTE2(v43) >> 4;
v21 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v21;
goto LABEL_35;
case 0x2Au:
goto LABEL_16;
case 0x2Bu:
goto LABEL_18;
case 0x2Cu:
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Du:
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Eu:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
goto LABEL_16;
goto LABEL_6;
case 0x2Fu:
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
{
LABEL_6:
v10 = *(unsigned int *)(a1 + 60);
}
else
{
LABEL_16:
v10 = *(_DWORD *)(a1 + 48) + v8;
*(_DWORD *)(a1 + 60) = v10;
}
break;
case 0x31u:
v14 = *(unsigned int *)(a1 + 60);
v33 = BYTE2(v43) >> 4;
v15 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v15;
utils_store(a2, v14, v15, 32LL, v6);
LOBYTE(v6) = v33;
LABEL_18:
v9 = v6 & 0xF;
v10 = (unsigned int)(*(_DWORD *)(a1 + 4 * v9 + 4) + *(_DWORD *)(a1 + 48));
*(_DWORD *)(a1 + 60) = v10;
break;
case 0x32u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) == 0 )
break;
goto LABEL_34;
case 0x33u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
break;
goto LABEL_34;
case 0x34u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) == 0 )
break;
goto LABEL_34;
case 0x35u:
v10 = *(unsigned int *)(a1 + 60);
if ( (*(_BYTE *)(a1 + 40) & 2) != 0 )
break;
LABEL_34:
v35 = BYTE2(v43) >> 4;
v21 = (unsigned int)(*(_DWORD *)(a1 + 56) - 4);
*(_DWORD *)(a1 + 56) = v21;
LABEL_35:
LODWORD(v9) = utils_store(a2, v10, v21, 32LL, v6);
v10 = *(_DWORD *)(a1 + 48) + v8;
LOBYTE(v6) = v35;
*(_DWORD *)(a1 + 60) = v10;
break;
}
}
if ( (unsigned int)v10 > 0xFFFFF )
{
v31 = v6;
printf("Error: PC at 0x%lx\n", v10);
puts("Last instruction: ");
LODWORD(v9) = printf("0x%x 0x%x 0x%x 0x%x li:0x%x\n", v5, v31, v7, v4, v8);
LODWORD(v10) = *(_DWORD *)(a1 + 60);
}
LABEL_9:
++*(_DWORD *)(a1 + 88);
*(_DWORD *)(a1 + 60) = v10 + 4;
}
return v9;
}

original_code:
void
cpu_process(cpu_t *cpu, ram_t *ram)
{
 uint8_t opcode, dst, src, dst_src;
 uint16_t constant;
 uint32_t ins, long_const;
 if (((unsigned int)cpu->registers [REGISTER_PC]) >= (1024 * 1024) - 4)
 {
  cpu->state = STATE_HALT;
        printf ("Halt. Program counter out of bounds.\n");
  return;
 }
 utils_load (ram, &ins, cpu->registers [REGISTER_PC], 32);
 opcode = (ins >> 24) & 0xff;
 dst_src = (ins >> 16) & 0xff;
 constant = ins & 0xffff;
 dst = (dst_src >> 4) & 0x0f;
 src = (dst_src & 0x0f);
 long_const = ((src << 16) | constant) & 0x000FFFFF;
 switch (opcode)
 {
  case NOP:
   break;
  case SET:
   cpu->registers [dst] = long_const;
   break;
  case MOV:
   cpu->registers [dst] = cpu->registers [src];
   break;
  case LOAD:
   utils_load (ram,
                        &cpu->registers [dst],
                        cpu->registers [src],
                        cpu->adr_mode);
            break;
  case STORE:
   utils_store (ram,
                         cpu->registers [src],
                         cpu->registers [dst],
                         cpu->adr_mode);
            break;
  case ADD: cpu->registers [dst] = cpu->registers [dst] +
           cpu->registers [src];
   break;
  case SUB: cpu->registers [dst] = cpu->registers [dst] -
           cpu->registers [src];
   break;
  case MUL: cpu->registers [dst] = cpu->registers [dst] *
           cpu->registers [src];
   break;
  case DIV: cpu->registers [dst] = cpu->registers [dst] /
           cpu->registers [src];
   break;
  case MOD: cpu->registers [dst] = cpu->registers [dst] %
           cpu->registers [src];
   break;
  case NEG: cpu->registers [dst] = !cpu->registers [dst];
   break;
  case AND: cpu->registers [dst] = cpu->registers [dst] &
           cpu->registers [src];
   break;
  case BOR: cpu->registers [dst] = cpu->registers [dst] |
           cpu->registers [src];
   break;
  case XOR: cpu->registers [dst] = cpu->registers [dst] ^
           cpu->registers [src];
   break;
  case BSL: cpu->registers [dst] = cpu->registers [dst] <<
           cpu->registers [src];
   break;
  case BSR: cpu->registers [dst] = cpu->registers [dst] >>
           cpu->registers [src];
   break;
  case CMP: utils_compare (&cpu->registers [REGISTER_CFLAGS],
                                  cpu->registers [dst],
                                  cpu->registers [src]);
            break;
  case M32:
   cpu->adr_mode = 32;
   break;
  case M16:
   cpu->adr_mode = 16;
   break;
  case M8:
   cpu->adr_mode = 8;
   break;
        case IN:
   cpu->registers [dst] = cpu->ports [cpu->registers [REGISTER_PORT]];
   break;
        case OUT:
            if (cpu->registers [REGISTER_PORT] >= (5))
            {
                printf ("Warning: invalid port %d in OUT instruction\n",
      cpu->registers [REGISTER_PORT]);
            }
            else
                cpu->ports [cpu->registers [REGISTER_PORT]] = cpu->registers [dst];
            break;
        case HLD:
   cpu->state = STATE_HOLD;
   break;
        case HLT:
   cpu->state = STATE_HALT;
   break;
  case PUSH:
            cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
          cpu->registers [dst],
       cpu->registers [REGISTER_STACKPOINTER],
       32);
            break;
  case POP:
            utils_load (ram,
         &cpu->registers [dst],
      cpu->registers [REGISTER_STACKPOINTER],
      32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
            break;
  case CALL:
            cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
       cpu->registers [REGISTER_PC],
       cpu->registers[REGISTER_STACKPOINTER],
       32);
            cpu->registers [REGISTER_PC] = long_const;
            break;
  case JMP:
   cpu->registers [REGISTER_PC] = long_const;
   break;
        case JR:
   cpu->registers [REGISTER_PC] = cpu->registers [dst];
   break;
        case JZ:
            if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JNZ:
            if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JS:
            if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JNS:
            if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
                cpu->registers [REGISTER_PC] = long_const;
            break;
  case RET:
            utils_load (ram,
               &cpu->registers [REGISTER_PC],
               cpu->registers [REGISTER_STACKPOINTER],
               32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
            break;
  case OPCP:
            utils_cpy_chunk (ram,
                             cpu->registers [dst],
                             cpu->registers [src],
                             1024*150);
            break;
        case CR:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = cpu->registers [dst];
            break;
        case CZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case DSET: cpu->registers [dst] = long_const + cpu->registers [REGISTER_OFFSET]; break;
        case DCALL:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJMP:
   cpu->registers [REGISTER_PC] = long_const +
                                           cpu->registers [REGISTER_OFFSET];
            break;
        case DJR:
   cpu->registers [REGISTER_PC] = cpu->registers [dst] +
                                           cpu->registers [REGISTER_OFFSET];
            break;
        case DJZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            break;
        case DJNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DRET:
          utils_load (ram,
               &cpu->registers [REGISTER_PC],
               cpu->registers [REGISTER_STACKPOINTER],
               32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
         break;
        case DCR:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = cpu->registers [dst] + cpu->registers [REGISTER_OFFSET];
         break;
        case DCZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        default: cpu->state = STATE_HALT;
                 printf ("Error: unrecognized opcode: %x\n", opcode);
            break;
 }
    if (cpu->registers [REGISTER_PC] >= (1024 * 1024))
    {
        printf ("Error: PC at 0x%lx\n",
                (unsigned long)cpu->registers [REGISTER_PC]);
        printf ("Last instruction: \n");
        printf ("0x%x 0x%x 0x%x 0x%x li:0x%x\n",
          opcode,
                                        dst,
                                        src,
                                        constant,
                                        long_const);
    }
 cpu->registers [REGISTER_PC] += 4;
    cpu->cycle ++;
}

canonical_original_code:
void cpu_process(struct cpu_s *cpu, struct ram_s *ram)
{
 unsigned char opcode; unsigned char dst; unsigned char src; unsigned char dst_src;
 unsigned short constant;
 unsigned int ins; unsigned int long_const;
 if (((unsigned int)cpu->registers [REGISTER_PC]) >= (1024 * 1024) - 4)
 {
  cpu->state = STATE_HALT;
        printf ("Halt. Program counter out of bounds.\n");
  return;
 }
 utils_load (ram, &ins, cpu->registers [REGISTER_PC], 32);
 opcode = (ins >> 24) & 0xff;
 dst_src = (ins >> 16) & 0xff;
 constant = ins & 0xffff;
 dst = (dst_src >> 4) & 0x0f;
 src = (dst_src & 0x0f);
 long_const = ((src << 16) | constant) & 0x000FFFFF;
 switch (opcode)
 {
  case NOP:
   break;
  case SET:
   cpu->registers [dst] = long_const;
   break;
  case MOV:
   cpu->registers [dst] = cpu->registers [src];
   break;
  case LOAD:
   utils_load (ram,
                        &cpu->registers [dst],
                        cpu->registers [src],
                        cpu->adr_mode);
            break;
  case STORE:
   utils_store (ram,
                         cpu->registers [src],
                         cpu->registers [dst],
                         cpu->adr_mode);
            break;
  case ADD: cpu->registers [dst] = cpu->registers [dst] +
           cpu->registers [src];
   break;
  case SUB: cpu->registers [dst] = cpu->registers [dst] -
           cpu->registers [src];
   break;
  case MUL: cpu->registers [dst] = cpu->registers [dst] *
           cpu->registers [src];
   break;
  case DIV: cpu->registers [dst] = cpu->registers [dst] /
           cpu->registers [src];
   break;
  case MOD: cpu->registers [dst] = cpu->registers [dst] %
           cpu->registers [src];
   break;
  case NEG: cpu->registers [dst] = !cpu->registers [dst];
   break;
  case AND: cpu->registers [dst] = cpu->registers [dst] &
           cpu->registers [src];
   break;
  case BOR: cpu->registers [dst] = cpu->registers [dst] |
           cpu->registers [src];
   break;
  case XOR: cpu->registers [dst] = cpu->registers [dst] ^
           cpu->registers [src];
   break;
  case BSL: cpu->registers [dst] = cpu->registers [dst] <<
           cpu->registers [src];
   break;
  case BSR: cpu->registers [dst] = cpu->registers [dst] >>
           cpu->registers [src];
   break;
  case CMP: utils_compare (&cpu->registers [REGISTER_CFLAGS],
                                  cpu->registers [dst],
                                  cpu->registers [src]);
            break;
  case M32:
   cpu->adr_mode = 32;
   break;
  case M16:
   cpu->adr_mode = 16;
   break;
  case M8:
   cpu->adr_mode = 8;
   break;
        case IN:
   cpu->registers [dst] = cpu->ports [cpu->registers [REGISTER_PORT]];
   break;
        case OUT:
            if (cpu->registers [REGISTER_PORT] >= (5))
            {
                printf ("Warning: invalid port %d in OUT instruction\n",
      cpu->registers [REGISTER_PORT]);
            }
            else
                cpu->ports [cpu->registers [REGISTER_PORT]] = cpu->registers [dst];
            break;
        case HLD:
   cpu->state = STATE_HOLD;
   break;
        case HLT:
   cpu->state = STATE_HALT;
   break;
  case PUSH:
            cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
          cpu->registers [dst],
       cpu->registers [REGISTER_STACKPOINTER],
       32);
            break;
  case POP:
            utils_load (ram,
         &cpu->registers [dst],
      cpu->registers [REGISTER_STACKPOINTER],
      32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
            break;
  case CALL:
            cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
       cpu->registers [REGISTER_PC],
       cpu->registers[REGISTER_STACKPOINTER],
       32);
            cpu->registers [REGISTER_PC] = long_const;
            break;
  case JMP:
   cpu->registers [REGISTER_PC] = long_const;
   break;
        case JR:
   cpu->registers [REGISTER_PC] = cpu->registers [dst];
   break;
        case JZ:
            if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JNZ:
            if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JS:
            if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
                cpu->registers [REGISTER_PC] = long_const;
            break;
        case JNS:
            if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
                cpu->registers [REGISTER_PC] = long_const;
            break;
  case RET:
            utils_load (ram,
               &cpu->registers [REGISTER_PC],
               cpu->registers [REGISTER_STACKPOINTER],
               32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
            break;
  case OPCP:
            utils_cpy_chunk (ram,
                             cpu->registers [dst],
                             cpu->registers [src],
                             1024*150);
            break;
        case CR:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = cpu->registers [dst];
            break;
        case CZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case CNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const;
            }
         break;
        case DSET: cpu->registers [dst] = long_const + cpu->registers [REGISTER_OFFSET]; break;
        case DCALL:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJMP:
   cpu->registers [REGISTER_PC] = long_const +
                                           cpu->registers [REGISTER_OFFSET];
            break;
        case DJR:
   cpu->registers [REGISTER_PC] = cpu->registers [dst] +
                                           cpu->registers [REGISTER_OFFSET];
            break;
        case DJZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DJS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            break;
        case DJNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
         break;
        case DRET:
          utils_load (ram,
               &cpu->registers [REGISTER_PC],
               cpu->registers [REGISTER_STACKPOINTER],
               32);
            cpu->registers [REGISTER_STACKPOINTER] += 4;
         break;
        case DCR:
         cpu->registers [REGISTER_STACKPOINTER] -= 4;
            utils_store (ram,
                cpu->registers [REGISTER_PC],
                cpu->registers[REGISTER_STACKPOINTER],
                32);
            cpu->registers [REGISTER_PC] = cpu->registers [dst] + cpu->registers [REGISTER_OFFSET];
         break;
        case DCZ:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000001)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCNZ:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000001))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCS:
         if (cpu->registers [REGISTER_CFLAGS] & 0x00000002)
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        case DCNS:
         if (! (cpu->registers [REGISTER_CFLAGS] & 0x00000002))
         {
          cpu->registers [REGISTER_STACKPOINTER] -= 4;
             utils_store (ram,
                 cpu->registers [REGISTER_PC],
                 cpu->registers[REGISTER_STACKPOINTER],
                 32);
                cpu->registers [REGISTER_PC] = long_const + cpu->registers [REGISTER_OFFSET];
            }
         break;
        default: cpu->state = STATE_HALT;
                 printf ("Error: unrecognized opcode: %x\n", opcode);
            break;
 }
    if (cpu->registers [REGISTER_PC] >= (1024 * 1024))
    {
        printf ("Error: PC at 0x%lx\n",
                (unsigned long)cpu->registers [REGISTER_PC]);
        printf ("Last instruction: \n");
        printf ("0x%x 0x%x 0x%x 0x%x li:0x%x\n",
          opcode,
                                        dst,
                                        src,
                                        constant,
                                        long_const);
    }
 cpu->registers [REGISTER_PC] += 4;
    cpu->cycle ++;
}

variable_types:
opcode
unsigned char

variable_types:
dst
unsigned char

variable_types:
src
unsigned char

variable_types:
constant
unsigned short

variable_types:
ins
unsigned int

user_defined_types: struct cpu_s { unsigned char state; unsigned char adr_mode; unsigned int registers[-1]; unsigned int ports[-1]; unsigned int cycle; }


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

sdl_init();
cpu_init(&Cpu);
ram_init(&Ram);
disk_init(&Disk);
disk_init(&Rom);
disp_init(&Display);
clk_init(&Clock);
*((_QWORD *)&Kb_buffer + 2) = 0LL;
Kb_buffer = 0LL;
puts("loading disk...");
disk_load(&Disk, &Disk_filn);
if ( Rom_filn )
{
puts("loading rom...");
disk_load(&Rom, &Rom_filn);
}
if ( Boot_disk )
result = disk_get_bootsector(&Disk, &Ram, &unk_10000);
else
result = disk_get_bootsector(&Rom, &Ram, &unk_10000);
Emu_run = 1;
return result;
}

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

sdl_init();
cpu_init(&Cpu);
ram_init(&Ram);
disk_init(&Disk);
disk_init(&Rom);
disp_init(&Display);
clk_init(&Clock);
*((_QWORD *)&Kb_buffer + 2) = 0LL;
Kb_buffer = 0LL;
puts("loading disk...");
disk_load(&Disk, &Disk_filn);
if ( Rom_filn )
{
puts("loading rom...");
disk_load(&Rom, &Rom_filn);
}
if ( Boot_disk )
result = disk_get_bootsector(&Disk, &Ram, &unk_10000);
else
result = disk_get_bootsector(&Rom, &Ram, &unk_10000);
Emu_run = 1;
return result;
}

original_code:
void
emu_init(void)
{
 sdl_init ();
    cpu_init (Cpu);
    ram_init (Ram);
    disk_init (Disk);
    disk_init (Rom);
    disp_init (Display);
    clk_init (Clock);
    memset (Kb_buffer, 0, sizeof (Kb_buffer));
    printf ("loading disk...\n");
    disk_load (Disk, Disk_filn);
    if (Rom_filn[0])
    {
        printf ("loading rom...\n");
        disk_load (Rom, Rom_filn);
    }
    if (Boot_disk)
    {
       disk_get_bootsector (Disk, Ram, (1024 * 64));
    }
    else
        disk_get_bootsector (Rom, Ram, (1024 * 64));
    Emu_run = 1;
}

canonical_original_code:
void emu_init()
{
 sdl_init ();
    cpu_init (Cpu);
    ram_init (Ram);
    disk_init (Disk);
    disk_init (Rom);
    disp_init (Display);
    clk_init (Clock);
    memset (Kb_buffer, 0, sizeof (Kb_buffer));
    printf ("loading disk...\n");
    disk_load (Disk, Disk_filn);
    if (Rom_filn[0])
    {
        printf ("loading rom...\n");
        disk_load (Rom, Rom_filn);
    }
    if (Boot_disk)
    {
       disk_get_bootsector (Disk, Ram, (1024 * 64));
    }
    else
        disk_get_bootsector (Rom, Ram, (1024 * 64));
    Emu_run = 1;
}


decompiled_code:
__int64 emu_rd_ports()
{
disk_rd_port(&Disk, (unsigned int)((_DWORD)&Cpu + 76), &Ram);
disk_rd_port(&Rom, (unsigned int)((_DWORD)&Cpu + 80), &Ram);
disp_rd_port(&Display, (unsigned int)((_DWORD)&Cpu + 68), &Ram);
return clk_rd_port(&Clock, (unsigned int)((_DWORD)&Cpu + 84));
}

canonical_decompiled_code:
__int64 func1()
{
disk_rd_port(&Disk, (unsigned int)((_DWORD)&Cpu + 76), &Ram);
disk_rd_port(&Rom, (unsigned int)((_DWORD)&Cpu + 80), &Ram);
disp_rd_port(&Display, (unsigned int)((_DWORD)&Cpu + 68), &Ram);
return clk_rd_port(&Clock, (unsigned int)((_DWORD)&Cpu + 84));
}

original_code:
void
emu_rd_ports(void)
{
 disk_rd_port(Disk, &(Cpu->ports [PORT_DISK]), Ram);
    disk_rd_port(Rom, &(Cpu->ports [PORT_ROM]), Ram);
 disp_rd_port(Display, &(Cpu->ports [PORT_DISPLAY]), Ram);
    clk_rd_port(Clock, &(Cpu->ports [PORT_CLOCK]));
}

canonical_original_code:
void emu_rd_ports()
{
 disk_rd_port(Disk, &(Cpu->ports [PORT_DISK]), Ram);
    disk_rd_port(Rom, &(Cpu->ports [PORT_ROM]), Ram);
 disp_rd_port(Display, &(Cpu->ports [PORT_DISPLAY]), Ram);
    clk_rd_port(Clock, &(Cpu->ports [PORT_CLOCK]));
}


decompiled_code:
__int64 __fastcall emu_kb_hndl(int *a1)
{
int v1; // edx
__int64 result; // rax

if ( !*((_DWORD *)&Cpu + 18) && (_DWORD)Kb_buffer )
{
*((_DWORD *)&Cpu + 18) = Kb_buffer;
Kb_buffer = *(__int128 *)((char *)&Kb_buffer + 4);
*((_QWORD *)&Kb_buffer + 2) = *((unsigned int *)&Kb_buffer + 5);
}
v1 = *a1;
result = 0LL;
while ( v1 )
{
if ( !*((_DWORD *)&Kb_buffer + result) )
{
result = (int)result;
*((_DWORD *)&Kb_buffer + (int)result) = v1;
if ( (_DWORD)result != 5 )
*((_DWORD *)&Kb_buffer + (int)result + 1) = 0;
return result;
}
if ( ++result == 6 )
return result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int *a1)
{
int v1; // edx
__int64 result; // rax

if ( !*((_DWORD *)&Cpu + 18) && (_DWORD)Kb_buffer )
{
*((_DWORD *)&Cpu + 18) = Kb_buffer;
Kb_buffer = *(__int128 *)((char *)&Kb_buffer + 4);
*((_QWORD *)&Kb_buffer + 2) = *((unsigned int *)&Kb_buffer + 5);
}
v1 = *a1;
result = 0LL;
while ( v1 )
{
if ( !*((_DWORD *)&Kb_buffer + result) )
{
result = (int)result;
*((_DWORD *)&Kb_buffer + (int)result) = v1;
if ( (_DWORD)result != 5 )
*((_DWORD *)&Kb_buffer + (int)result + 1) = 0;
return result;
}
if ( ++result == 6 )
return result;
}
return result;
}

original_code:
void
emu_kb_hndl(uint32_t *keycode)
{
    int i;
    if (! Cpu->ports [PORT_KEYBOARD] &&
            Kb_buffer[0])
    {
        Cpu->ports [PORT_KEYBOARD] = Kb_buffer [0];
        Kb_buffer[0] = 0;
        for (i = 1; i < (6); i++)
        {
            Kb_buffer [i - 1] = Kb_buffer [i];
        }
        Kb_buffer [(6) - 1] = 0;
    }
    for(i = 0; i < (6) && *keycode; i++)
    {
        if (! Kb_buffer [i])
        {
            Kb_buffer [i] = *keycode;
            if (i != (6) - 1)
                Kb_buffer [i + 1] = 0;
            break;
        }
    }
}

canonical_original_code:
void emu_kb_hndl(unsigned int *keycode)
{
    int i;
    if (! Cpu->ports [PORT_KEYBOARD] &&
            Kb_buffer[0])
    {
        Cpu->ports [PORT_KEYBOARD] = Kb_buffer [0];
        Kb_buffer[0] = 0;
        for (i = 1; i < (6); i++)
        {
            Kb_buffer [i - 1] = Kb_buffer [i];
        }
        Kb_buffer [(6) - 1] = 0;
    }
    for(i = 0; i < (6) && *keycode; i++)
    {
        if (! Kb_buffer [i])
        {
            Kb_buffer [i] = *keycode;
            if (i != (6) - 1)
                Kb_buffer [i + 1] = 0;
            break;
        }
    }
}

variable_types:
keycode
unsigned int *

variable_types: i int


decompiled_code:
__int64 emu_dbg_txt()
{
unsigned __int64 v0; // rbp
unsigned int v1; // ebx
__int64 v2; // rdx
__int64 v3; // rdx
char *v4; // rbp
unsigned int i; // ebx
__int64 v6; // rdx
__int64 v7; // rdx
unsigned int v8; // ebx
unsigned int v9; // ebp
__int64 v10; // rdx
__int64 v11; // rdx
unsigned int v13; // [rsp+Ch] [rbp-3Ch] BYREF
char s[16]; // [rsp+10h] [rbp-38h] BYREF
__int128 v15; // [rsp+20h] [rbp-28h]

v0 = (unsigned int)((_DWORD)&Cpu + 4);
v1 = 110;
sdl_render_box(530LL, 90LL, 275LL, 260LL);
do
{
v2 = *(unsigned int *)v0;
*(_OWORD *)s = 0LL;
v0 += 4LL;
v15 = 0LL;
sprintf(s, "0x%x", v2);
v3 = v1;
v1 += 10;
sdl_render_text(s, 670LL, v3);
}
while ( v1 != 270 );
v4 = &Cpu;
for ( i = 280; i != 330; i += 10 )
{
v6 = *((unsigned int *)v4 + 17);
*(_OWORD *)s = 0LL;
v4 += 4;
v15 = 0LL;
sprintf(s, "0x%x", v6);
v7 = i;
sdl_render_text(s, 670LL, v7);
}
*(_OWORD *)s = 0LL;
v15 = 0LL;
sprintf(s, "0x%x", (unsigned __int8)Cpu);
sdl_render_text(s, 670LL, 330LL);
sdl_render_text("REGISTERS", 630LL, 100LL);
sdl_render_text(&off_3D0148A, 630LL, 110LL);
sdl_render_text((char *)&off_3D0148A + 2, 630LL, 120LL);
sdl_render_text(&off_3D0148E, 630LL, 130LL);
sdl_render_text((char *)&off_3D0148E + 2, 630LL, 140LL);
sdl_render_text(&off_3D01492, 630LL, 150LL);
sdl_render_text((char *)&off_3D01492 + 2, 630LL, 160LL);
sdl_render_text(&off_3D01496, 630LL, 170LL);
sdl_render_text((char *)&off_3D01496 + 2, 630LL, 180LL);
sdl_render_text(&off_3D0149A, 630LL, 190LL);
sdl_render_text(&unk_3D0149E, 630LL, 200LL);
sdl_render_text(&unk_3D014A1, 630LL, 210LL);
sdl_render_text(&off_3D014A3, 630LL, 220LL);
sdl_render_text(&unk_3D014A7, 630LL, 230LL);
sdl_render_text(&unk_3D014AA, 630LL, 240LL);
sdl_render_text(&unk_3D014AD, 630LL, 250LL);
sdl_render_text(&unk_3D014B0, 630LL, 260LL);
sdl_render_text("DISP", 630LL, 280LL);
sdl_render_text(&off_3D014B7, 630LL, 290LL);
sdl_render_text("DISK", 630LL, 300LL);
sdl_render_text(&off_3D014C0, 630LL, 310LL);
sdl_render_text((char *)&off_3D014C0 + 4, 630LL, 320LL);
sdl_render_text(&off_3D014C8, 630LL, 330LL);
v8 = *((_DWORD *)&Cpu + 13);
if ( *((_DWORD *)&Cpu + 14) <= v8 )
{
v9 = 110;
do
{
v10 = v8;
*(_OWORD *)s = 0LL;
v8 -= 4;
v15 = 0LL;
utils_load(&Ram, &v13, v10, 32LL);
sprintf(s, (const char *)&off_3D014C8 + 4, v13);
v11 = v9;
v9 += 10;
sdl_render_text(s, 540LL, v11);
}
while ( *((_DWORD *)&Cpu + 14) <= v8 );
}
return sdl_render_text("STACK", 540LL, 100LL);
}

canonical_decompiled_code:
__int64 func3()
{
unsigned __int64 v0; // rbp
unsigned int v1; // ebx
__int64 v2; // rdx
__int64 v3; // rdx
char *v4; // rbp
unsigned int i; // ebx
__int64 v6; // rdx
__int64 v7; // rdx
unsigned int v8; // ebx
unsigned int v9; // ebp
__int64 v10; // rdx
__int64 v11; // rdx
unsigned int v13; // [rsp+Ch] [rbp-3Ch] BYREF
char s[16]; // [rsp+10h] [rbp-38h] BYREF
__int128 v15; // [rsp+20h] [rbp-28h]

v0 = (unsigned int)((_DWORD)&Cpu + 4);
v1 = 110;
sdl_render_box(530LL, 90LL, 275LL, 260LL);
do
{
v2 = *(unsigned int *)v0;
*(_OWORD *)s = 0LL;
v0 += 4LL;
v15 = 0LL;
sprintf(s, "0x%x", v2);
v3 = v1;
v1 += 10;
sdl_render_text(s, 670LL, v3);
}
while ( v1 != 270 );
v4 = &Cpu;
for ( i = 280; i != 330; i += 10 )
{
v6 = *((unsigned int *)v4 + 17);
*(_OWORD *)s = 0LL;
v4 += 4;
v15 = 0LL;
sprintf(s, "0x%x", v6);
v7 = i;
sdl_render_text(s, 670LL, v7);
}
*(_OWORD *)s = 0LL;
v15 = 0LL;
sprintf(s, "0x%x", (unsigned __int8)Cpu);
sdl_render_text(s, 670LL, 330LL);
sdl_render_text("REGISTERS", 630LL, 100LL);
sdl_render_text(&off_3D0148A, 630LL, 110LL);
sdl_render_text((char *)&off_3D0148A + 2, 630LL, 120LL);
sdl_render_text(&off_3D0148E, 630LL, 130LL);
sdl_render_text((char *)&off_3D0148E + 2, 630LL, 140LL);
sdl_render_text(&off_3D01492, 630LL, 150LL);
sdl_render_text((char *)&off_3D01492 + 2, 630LL, 160LL);
sdl_render_text(&off_3D01496, 630LL, 170LL);
sdl_render_text((char *)&off_3D01496 + 2, 630LL, 180LL);
sdl_render_text(&off_3D0149A, 630LL, 190LL);
sdl_render_text(&unk_3D0149E, 630LL, 200LL);
sdl_render_text(&unk_3D014A1, 630LL, 210LL);
sdl_render_text(&off_3D014A3, 630LL, 220LL);
sdl_render_text(&unk_3D014A7, 630LL, 230LL);
sdl_render_text(&unk_3D014AA, 630LL, 240LL);
sdl_render_text(&unk_3D014AD, 630LL, 250LL);
sdl_render_text(&unk_3D014B0, 630LL, 260LL);
sdl_render_text("DISP", 630LL, 280LL);
sdl_render_text(&off_3D014B7, 630LL, 290LL);
sdl_render_text("DISK", 630LL, 300LL);
sdl_render_text(&off_3D014C0, 630LL, 310LL);
sdl_render_text((char *)&off_3D014C0 + 4, 630LL, 320LL);
sdl_render_text(&off_3D014C8, 630LL, 330LL);
v8 = *((_DWORD *)&Cpu + 13);
if ( *((_DWORD *)&Cpu + 14) <= v8 )
{
v9 = 110;
do
{
v10 = v8;
*(_OWORD *)s = 0LL;
v8 -= 4;
v15 = 0LL;
utils_load(&Ram, &v13, v10, 32LL);
sprintf(s, (const char *)&off_3D014C8 + 4, v13);
v11 = v9;
v9 += 10;
sdl_render_text(s, 540LL, v11);
}
while ( *((_DWORD *)&Cpu + 14) <= v8 );
}
return sdl_render_text("STACK", 540LL, 100LL);
}

original_code:
void
emu_dbg_txt(void)
{
    char buffer [32];
    unsigned int i;
    uint32_t tmp, tmp1;
 sdl_render_box (530, 90, 275, 260);
    for (i = 0; i < (16); i++)
    {
        memset (buffer, 0, sizeof (buffer));
        sprintf (buffer, "0x%x", Cpu->registers [i]);
        sdl_render_text ((void *)buffer, 670, 110+(i*10));
    }
    for (i = 0; i < (5); i++)
    {
        memset (buffer, 0, sizeof (buffer));
        sprintf (buffer, "0x%x", Cpu->ports [i]);
        sdl_render_text ((void *)buffer, 670, 110+((i+(16))*10)+10);
    }
    memset (buffer, 0, sizeof (buffer));
    sprintf (buffer, "0x%x", Cpu->state);
    sdl_render_text ((void *)buffer, 670, 330);
    sdl_render_text ((void *)"REGISTERS",630,100);
    sdl_render_text ((void *)"A", 630, 110);
    sdl_render_text ((void *)"B", 630, 120);
    sdl_render_text ((void *)"C", 630, 130);
    sdl_render_text ((void *)"D", 630, 140);
    sdl_render_text ((void *)"W", 630, 150);
    sdl_render_text ((void *)"X", 630, 160);
    sdl_render_text ((void *)"Y", 630, 170);
    sdl_render_text ((void *)"Z", 630, 180);
    sdl_render_text ((void *)"RTA", 630, 190);
    sdl_render_text ((void *)"CF", 630, 200);
    sdl_render_text ((void *)"P", 630, 210);
    sdl_render_text ((void *)"OFS", 630, 220);
    sdl_render_text ((void *)"SB", 630, 230);
    sdl_render_text ((void *)"SP", 630, 240);
    sdl_render_text ((void *)"PC", 630, 250);
    sdl_render_text ((void *)"0", 630, 260);
    sdl_render_text ((void *)"DISP", 630, 280);
    sdl_render_text ((void *)"KEY", 630, 290);
    sdl_render_text ((void *)"DISK", 630, 300);
    sdl_render_text ((void *)"ROM", 630, 310);
    sdl_render_text ((void *)"CLK", 630, 320);
    sdl_render_text ((void *)"STA", 630, 330);
    i = 0;
    for(tmp = Cpu->registers [REGISTER_STACKBASE];
   tmp >= Cpu->registers [REGISTER_STACKPOINTER];
   tmp-=4)
    {
        memset (buffer, 0, sizeof (buffer));
        utils_load (Ram, &tmp1, tmp, 32);
        sprintf (buffer, "0x%lx", (unsigned long)tmp1);
        sdl_render_text ((void *)buffer, 540, 110 + (i*10));
        ++ i;
    }
    sdl_render_text((void *)"STACK", 540, 100);
}

canonical_original_code:
void emu_dbg_txt()
{
    char buffer[32];
    unsigned int i;
    unsigned int tmp; unsigned int tmp1;
 sdl_render_box (530, 90, 275, 260);
    for (i = 0; i < (16); i++)
    {
        memset (buffer, 0, sizeof (buffer));
        sprintf (buffer, "0x%x", Cpu->registers [i]);
        sdl_render_text ((void *)buffer, 670, 110+(i*10));
    }
    for (i = 0; i < (5); i++)
    {
        memset (buffer, 0, sizeof (buffer));
        sprintf (buffer, "0x%x", Cpu->ports [i]);
        sdl_render_text ((void *)buffer, 670, 110+((i+(16))*10)+10);
    }
    memset (buffer, 0, sizeof (buffer));
    sprintf (buffer, "0x%x", Cpu->state);
    sdl_render_text ((void *)buffer, 670, 330);
    sdl_render_text ((void *)"REGISTERS",630,100);
    sdl_render_text ((void *)"A", 630, 110);
    sdl_render_text ((void *)"B", 630, 120);
    sdl_render_text ((void *)"C", 630, 130);
    sdl_render_text ((void *)"D", 630, 140);
    sdl_render_text ((void *)"W", 630, 150);
    sdl_render_text ((void *)"X", 630, 160);
    sdl_render_text ((void *)"Y", 630, 170);
    sdl_render_text ((void *)"Z", 630, 180);
    sdl_render_text ((void *)"RTA", 630, 190);
    sdl_render_text ((void *)"CF", 630, 200);
    sdl_render_text ((void *)"P", 630, 210);
    sdl_render_text ((void *)"OFS", 630, 220);
    sdl_render_text ((void *)"SB", 630, 230);
    sdl_render_text ((void *)"SP", 630, 240);
    sdl_render_text ((void *)"PC", 630, 250);
    sdl_render_text ((void *)"0", 630, 260);
    sdl_render_text ((void *)"DISP", 630, 280);
    sdl_render_text ((void *)"KEY", 630, 290);
    sdl_render_text ((void *)"DISK", 630, 300);
    sdl_render_text ((void *)"ROM", 630, 310);
    sdl_render_text ((void *)"CLK", 630, 320);
    sdl_render_text ((void *)"STA", 630, 330);
    i = 0;
    for(tmp = Cpu->registers [REGISTER_STACKBASE];
   tmp >= Cpu->registers [REGISTER_STACKPOINTER];
   tmp-=4)
    {
        memset (buffer, 0, sizeof (buffer));
        utils_load (Ram, &tmp1, tmp, 32);
        sprintf (buffer, "0x%lx", (unsigned long)tmp1);
        sdl_render_text ((void *)buffer, 540, 110 + (i*10));
        ++ i;
    }
    sdl_render_text((void *)"STACK", 540, 100);
}

variable_types:
buffer
char [32]

variable_types:
tmp
unsigned int


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

Emu_run = sdl_event_hndl();
if ( !(*((_DWORD *)&Cpu + 22) % Emu_refresh_rate) )
{
if ( Cpu == 2 )
goto LABEL_3;
sdl_clear();
sdl_draw(&Display);
if ( Emu_dbg_option )
emu_dbg_txt();
sdl_flip();
if ( !Emu_max_speed )
sdl_sleep();
}
if ( !Cpu )
{
emu_rd_ports();
cpu_process(&Cpu, &Ram);
goto LABEL_13;
}
LABEL_3:
sdl_clear();
if ( Cpu == 2 )
{
sdl_draw_info();
}
else
{
sdl_draw(&Display);
if ( Emu_dbg_option )
emu_dbg_txt();
}
sdl_flip();
sdl_sleep();
LABEL_13:
clk_chk_tmr(&Clock, &Cpu, &Ram);
result = (unsigned int)Emu_run;
if ( !Emu_run )
{
puts("cleaning up...");
sdl_quit();
printf("saving %s...\n", (const char *)&Disk_filn);
result = disk_save(&Disk, &Disk_filn);
}
return result;
}

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

Emu_run = sdl_event_hndl();
if ( !(*((_DWORD *)&Cpu + 22) % Emu_refresh_rate) )
{
if ( Cpu == 2 )
goto LABEL_3;
sdl_clear();
sdl_draw(&Display);
if ( Emu_dbg_option )
func3();
sdl_flip();
if ( !Emu_max_speed )
sdl_sleep();
}
if ( !Cpu )
{
func1();
cpu_process(&Cpu, &Ram);
goto LABEL_13;
}
LABEL_3:
sdl_clear();
if ( Cpu == 2 )
{
sdl_draw_info();
}
else
{
sdl_draw(&Display);
if ( Emu_dbg_option )
func3();
}
sdl_flip();
sdl_sleep();
LABEL_13:
clk_chk_tmr(&Clock, &Cpu, &Ram);
result = (unsigned int)Emu_run;
if ( !Emu_run )
{
puts("cleaning up...");
sdl_quit();
printf("saving %s...\n", (const char *)&Disk_filn);
result = disk_save(&Disk, &Disk_filn);
}
return result;
}

original_code:
void
emu_main_loop(void)
{
    Emu_run = sdl_event_hndl ();
    if (Cpu->cycle % Emu_refresh_rate == 0 &&
        Cpu->state != STATE_HALT)
    {
        sdl_clear ();
        sdl_draw (Display->buffer);
  if (Emu_dbg_option)
            emu_dbg_txt ();
  sdl_flip ();
        if ((!Emu_max_speed))
            sdl_sleep ();
    }
    if (Cpu->state == STATE_RUNNING)
    {
     emu_rd_ports ();
        cpu_process (Cpu, Ram);
    }
    else
    {
        sdl_clear ();
        if (Cpu->state == STATE_HALT)
        {
            sdl_draw_info ();
        }
        else
        {
            sdl_draw (Display->buffer);
            if (Emu_dbg_option)
                emu_dbg_txt ();
        }
        sdl_flip ();
        sdl_sleep ();
    }
    clk_chk_tmr (Clock, Cpu, Ram);
    if (!Emu_run)
    {
        printf ("cleaning up...\n");
        sdl_quit ();
        printf ("saving %s...\n", Disk_filn);
        disk_save (Disk, Disk_filn);
    }
}

canonical_original_code:
void emu_main_loop()
{
    Emu_run = sdl_event_hndl ();
    if (Cpu->cycle % Emu_refresh_rate == 0 &&
        Cpu->state != STATE_HALT)
    {
        sdl_clear ();
        sdl_draw (Display->buffer);
  if (Emu_dbg_option)
            emu_dbg_txt ();
  sdl_flip ();
        if ((!Emu_max_speed))
            sdl_sleep ();
    }
    if (Cpu->state == STATE_RUNNING)
    {
     emu_rd_ports ();
        cpu_process (Cpu, Ram);
    }
    else
    {
        sdl_clear ();
        if (Cpu->state == STATE_HALT)
        {
            sdl_draw_info ();
        }
        else
        {
            sdl_draw (Display->buffer);
            if (Emu_dbg_option)
                emu_dbg_txt ();
        }
        sdl_flip ();
        sdl_sleep ();
    }
    clk_chk_tmr (Clock, Cpu, Ram);
    if (!Emu_run)
    {
        printf ("cleaning up...\n");
        sdl_quit ();
        printf ("saving %s...\n", Disk_filn);
        disk_save (Disk, Disk_filn);
    }
}


decompiled_code:
void *__fastcall ram_init(void *a1)
{
return memset(a1, 0, 0x100000uLL);
}

canonical_decompiled_code:
void *__fastcall func0(void *a1)
{
return memset(a1, 0, 0x100000uLL);
}

original_code:
void
ram_init(ram_t *ram)
{
 memset (ram->address, 0, sizeof (ram->address));
}

canonical_original_code:
void ram_init(struct ram_s *ram)
{
 memset (ram->address, 0, sizeof (ram->address));
}

variable_types: struct ram_s { unsigned char address[-1]; struct instr_s { unsigned char opcode; unsigned char dst_src; unsigned short constant; } *instruction; } *


main

canonical_name: main

repo: Toluk/os

original_code:
int main(int argc, char* argv[])
    {
        char change = 'a';
        int k = atoi(argv[1]), flag1 = 1, flag2 = 1, temp_pointer = 0;
        const int buff = k + 1;
        char *temp = (char *) malloc(buff), *buffer = (char *) malloc(buff);
        while (flag1 == 1)
            {
                int hmr = read(0, buffer, buff), i = 0;
                while (i < hmr)
                    {
                        temp[temp_pointer++] = buffer[i++];
                        if (temp_pointer > 0 && temp_pointer <= k + 1 && temp[temp_pointer - 1] == '\n' && flag2 == 1)
                            {
                                write(1, temp, temp_pointer);
                                write(1, temp, temp_pointer);
                                temp[temp_pointer - 1] = change;
                                temp_pointer = 0;
                            }
                        if (temp_pointer == k + 1 && temp[temp_pointer - 1] != '\n')
                            {
                                flag2 = 0;
                                temp_pointer = 0;
                            }
                        if (flag2 == 0 && temp[temp_pointer - 1] == '\n' && temp_pointer > 0)
                            {
                                flag2 = 1;
                                temp[temp_pointer - 1] = change;
                                temp_pointer = 0;
                            }
                    }
                if (hmr < buff)
                    flag1 = 0;
            }
        return 0;
    }

canonical_original_code:
int main(int argc, char *argv[])
    {
        char change = 'a';
        int k = atoi(argv[1]); int flag1 = 1; int flag2 = 1; int temp_pointer = 0;
        int buff = k + 1;
        char *temp = (char *) malloc(buff); char *buffer = (char *) malloc(buff);
        while (flag1 == 1)
            {
                int hmr = read(0, buffer, buff); int i = 0;
                while (i < hmr)
                    {
                        temp[temp_pointer++] = buffer[i++];
                        if (temp_pointer > 0 && temp_pointer <= k + 1 && temp[temp_pointer - 1] == '\n' && flag2 == 1)
                            {
                                write(1, temp, temp_pointer);
                                write(1, temp, temp_pointer);
                                temp[temp_pointer - 1] = change;
                                temp_pointer = 0;
                            }
                        if (temp_pointer == k + 1 && temp[temp_pointer - 1] != '\n')
                            {
                                flag2 = 0;
                                temp_pointer = 0;
                            }
                        if (flag2 == 0 && temp[temp_pointer - 1] == '\n' && temp_pointer > 0)
                            {
                                flag2 = 1;
                                temp[temp_pointer - 1] = change;
                                temp_pointer = 0;
                            }
                    }
                if (hmr < buff)
                    flag1 = 0;
            }
        return 0;
    }

variable_types: argc int

variable_types:
argv
char *[]

variable_types: change char

variable_types: k int

variable_types: buff int

variable_types:
temp
char *

variable_types:
buffer
char *

variable_types: hmr int

return_type: int


decompiled_code:
__int64 __fastcall i_want_atoi(_BYTE *a1)
{
int v1; // eax
_BYTE *v2; // rdi
unsigned int v3; // er8

v1 = (char)*a1;
if ( (unsigned __int8)(*a1 - 48) > 9u )
return 0LL;
v2 = a1 + 1;
v3 = 0;
do
{
++v2;
v3 = v1 + 10 * v3 - 48;
v1 = (char)*(v2 - 1);
}
while ( (unsigned __int8)(*(v2 - 1) - 48) <= 9u );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func7(_BYTE *a1)
{
int v1; // eax
_BYTE *v2; // rdi
unsigned int v3; // er8

v1 = (char)*a1;
if ( (unsigned __int8)(*a1 - 48) > 9u )
return 0LL;
v2 = a1 + 1;
v3 = 0;
do
{
++v2;
v3 = v1 + 10 * v3 - 48;
v1 = (char)*(v2 - 1);
}
while ( (unsigned __int8)(*(v2 - 1) - 48) <= 9u );
return v3;
}

original_code:
int i_want_atoi(char* why)
    {
        int temp = 0, i = 0;
        while(why[i] >= '0' && why[i] <= '9')
            temp = temp * 10 + why[i++] - 48;
        return temp;
    }

canonical_original_code:
int i_want_atoi(char *why)
    {
        int temp = 0; int i = 0;
        while(why[i] >= '0' && why[i] <= '9')
            temp = temp * 10 + why[i++] - 48;
        return temp;
    }

variable_types:
why
char *

variable_types: temp int


readDirectory

decompiled_code:
__int64 __fastcall readDirectory(__int64 a1, int a2, __int64 a3)
{
int v6; // ebx
__int64 v7; // r13
unsigned __int8 *v8; // rbp
int v9; // eax
unsigned __int8 *v10; // rdi
unsigned __int8 v11; // al
int v12; // eax
int v13; // ebp
void *v14; // rdi
__int64 v16; // rax
char v17; // dl
__int64 v18; // rcx
int v19; // esi
int v20; // eax
int v21; // edx
int v22; // edi
__int64 v23; // rdx
FILE *v24; // rbp
__int64 i; // rax
char v26; // dl
int v27; // ebp
void *ptr; // [rsp+8h] [rbp-50h] BYREF
char filename[69]; // [rsp+13h] [rbp-45h] BYREF

ptr = 0LL;
if ( a2 <= 0 )
{
v14 = 0LL;
}
else
{
v6 = 0;
while ( 2 )
{
v7 = a1 + 32LL * v6;
v8 = (unsigned __int8 *)v7;
printDirEntry((unsigned __int8 *)v7);
while ( 1 )
{
v9 = v6++;
if ( v8[43] != 15 )
break;
v10 = v8;
v8 += 32;
printDirEntry(v10);
if ( a2 <= v6 )
{
v11 = *(_BYTE *)v7;
if ( *(_BYTE *)v7 != 5 )
goto LABEL_7;
goto LABEL_17;
}
}
v6 = v9;
v11 = *(_BYTE *)v7;
if ( *(_BYTE *)v7 == 5 )
goto LABEL_17;
LABEL_7:
if ( v11 == 0xE5 )
{
LABEL_17:
++v6;
puts("Deleted entry");
if ( a2 > v6 )
continue;
}
else
{
if ( v11 <= 0x20u )
goto LABEL_13;
if ( v11 == 46 )
goto LABEL_13;
free(ptr);
v12 = bufferFile(v7, a3, &ptr);
v13 = v12;
if ( !ptr )
goto LABEL_13;
if ( (*(_BYTE *)(v7 + 11) & 0x10) != 0 )
{
if ( v12 > 0 )
{
for ( i = 0LL; i != 8; ++i )
{
v26 = *(_BYTE *)(v7 + i);
if ( !v26 )
break;
if ( v26 == 32 )
{
*(_BYTE *)(v7 + (int)i) = 0;
break;
}
}
printf("I will write the dir %s\n", (const char *)v7);
if ( mkdir((const char *)v7, 0x1FFu) )
perror("Mkdir");
if ( chdir((const char *)v7) )
perror("Chdir");
v27 = clusterSize * v13;
puts("Reading directory");
readDirectory(ptr, (unsigned int)((unsigned __int64)v27 >> 5), a3);
if ( chdir("../") )
perror("Chdir");
}
LABEL_13:
if ( a2 > ++v6 )
continue;
break;
}
if ( v12 <= 0 )
goto LABEL_13;
v16 = 0LL;
while ( 1 )
{
v17 = *(_BYTE *)(v7 + v16);
v18 = (int)v16;
v19 = v16 + 1;
if ( v17 == 32 )
break;
filename[v16++] = v17;
if ( v16 == 8 )
{
v20 = 12;
v21 = 11;
v22 = 10;
v19 = 9;
v18 = 8LL;
goto LABEL_24;
}
}
v22 = v16 + 2;
v21 = v16 + 3;
v20 = v16 + 4;
LABEL_24:
filename[v18] = 46;
filename[v19] = *(_BYTE *)(v7 + 8);
filename[v22] = *(_BYTE *)(v7 + 9);
filename[v21] = *(_BYTE *)(v7 + 10);
v23 = *(unsigned __int16 *)(v7 + 30);
filename[v20] = 0;
printf("\tI will write the file %s; length: %ld\n", filename, *(unsigned __int16 *)(v7 + 28) + (v23 << 16));
v24 = fopen(filename, "w+");
if ( fwrite(
ptr,
1uLL,
*(unsigned __int16 *)(v7 + 28) + ((unsigned __int64)*(unsigned __int16 *)(v7 + 30) << 16),
v24) != *(unsigned __int16 *)(v7 + 28) + ((unsigned __int64)*(unsigned __int16 *)(v7 + 30) << 16) )
puts("Error: write error");
++v6;
fclose(v24);
if ( a2 > v6 )
continue;
}
break;
}
v14 = ptr;
}
free(v14);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, int a2, __int64 a3)
{
int v6; // ebx
__int64 v7; // r13
unsigned __int8 *v8; // rbp
int v9; // eax
unsigned __int8 *v10; // rdi
unsigned __int8 v11; // al
int v12; // eax
int v13; // ebp
void *v14; // rdi
__int64 v16; // rax
char v17; // dl
__int64 v18; // rcx
int v19; // esi
int v20; // eax
int v21; // edx
int v22; // edi
__int64 v23; // rdx
FILE *v24; // rbp
__int64 i; // rax
char v26; // dl
int v27; // ebp
void *ptr; // [rsp+8h] [rbp-50h] BYREF
char filename[69]; // [rsp+13h] [rbp-45h] BYREF

ptr = 0LL;
if ( a2 <= 0 )
{
v14 = 0LL;
}
else
{
v6 = 0;
while ( 2 )
{
v7 = a1 + 32LL * v6;
v8 = (unsigned __int8 *)v7;
func0((unsigned __int8 *)v7);
while ( 1 )
{
v9 = v6++;
if ( v8[43] != 15 )
break;
v10 = v8;
v8 += 32;
func0(v10);
if ( a2 <= v6 )
{
v11 = *(_BYTE *)v7;
if ( *(_BYTE *)v7 != 5 )
goto LABEL_7;
goto LABEL_17;
}
}
v6 = v9;
v11 = *(_BYTE *)v7;
if ( *(_BYTE *)v7 == 5 )
goto LABEL_17;
LABEL_7:
if ( v11 == 0xE5 )
{
LABEL_17:
++v6;
puts("Deleted entry");
if ( a2 > v6 )
continue;
}
else
{
if ( v11 <= 0x20u )
goto LABEL_13;
if ( v11 == 46 )
goto LABEL_13;
free(ptr);
v12 = func2(v7, a3, &ptr);
v13 = v12;
if ( !ptr )
goto LABEL_13;
if ( (*(_BYTE *)(v7 + 11) & 0x10) != 0 )
{
if ( v12 > 0 )
{
for ( i = 0LL; i != 8; ++i )
{
v26 = *(_BYTE *)(v7 + i);
if ( !v26 )
break;
if ( v26 == 32 )
{
*(_BYTE *)(v7 + (int)i) = 0;
break;
}
}
printf("I will write the dir %s\n", (const char *)v7);
if ( mkdir((const char *)v7, 0x1FFu) )
perror("Mkdir");
if ( chdir((const char *)v7) )
perror("Chdir");
v27 = clusterSize * v13;
puts("Reading directory");
func3(ptr, (unsigned int)((unsigned __int64)v27 >> 5), a3);
if ( chdir("../") )
perror("Chdir");
}
LABEL_13:
if ( a2 > ++v6 )
continue;
break;
}
if ( v12 <= 0 )
goto LABEL_13;
v16 = 0LL;
while ( 1 )
{
v17 = *(_BYTE *)(v7 + v16);
v18 = (int)v16;
v19 = v16 + 1;
if ( v17 == 32 )
break;
filename[v16++] = v17;
if ( v16 == 8 )
{
v20 = 12;
v21 = 11;
v22 = 10;
v19 = 9;
v18 = 8LL;
goto LABEL_24;
}
}
v22 = v16 + 2;
v21 = v16 + 3;
v20 = v16 + 4;
LABEL_24:
filename[v18] = 46;
filename[v19] = *(_BYTE *)(v7 + 8);
filename[v22] = *(_BYTE *)(v7 + 9);
filename[v21] = *(_BYTE *)(v7 + 10);
v23 = *(unsigned __int16 *)(v7 + 30);
filename[v20] = 0;
printf("\tI will write the file %s; length: %ld\n", filename, *(unsigned __int16 *)(v7 + 28) + (v23 << 16));
v24 = fopen(filename, "w+");
if ( fwrite(
ptr,
1uLL,
*(unsigned __int16 *)(v7 + 28) + ((unsigned __int64)*(unsigned __int16 *)(v7 + 30) << 16),
v24) != *(unsigned __int16 *)(v7 + 28) + ((unsigned __int64)*(unsigned __int16 *)(v7 + 30) << 16) )
puts("Error: write error");
++v6;
fclose(v24);
if ( a2 > v6 )
continue;
}
break;
}
v14 = ptr;
}
free(v14);
return 0LL;
}

original_code:
int readDirectory(dirEntry *dirs, int Nentries, unsigned short *sFAT, int fat){
 int i, j;
 char *buffer = ((void *)0);
 int nclusters = 0;
 for(j = i = 0; i < Nentries; i = j + 1){
  for(j = i; j < Nentries; j++){
   if(dirs[j + 1].attrib != 0x0f) break;
  }
  if((dirs[i].name[0] == 0x05) || (dirs[i].name[0] == 0xe5)){
  }else if(dirs[i].name[0] > ' ' && (dirs[i].name[0] != '.')){
   free(buffer);
   nclusters = bufferFile(dirs + i, sFAT, &buffer);
   if(buffer && (dirs[i].attrib & 0x10) && (nclusters > 0)){
    int N;
    N = nclusters * clusterSize / sizeof(dirEntry);
    readDirectory((dirEntry *) buffer, N, sFAT, fat);
   }
  }
 }
 free(buffer);
 return 0;
}

canonical_original_code:
int readDirectory(struct DIRENTRY *dirs, int Nentries, unsigned short *sFAT, int fat){
 int i; int j;
 char *buffer = ((void *)0);
 int nclusters = 0;
 for(j = i = 0; i < Nentries; i = j + 1){
  for(j = i; j < Nentries; j++){
   if(dirs[j + 1].attrib != 0x0f) break;
  }
  if((dirs[i].name[0] == 0x05) || (dirs[i].name[0] == 0xe5)){
  }else if(dirs[i].name[0] > ' ' && (dirs[i].name[0] != '.')){
   free(buffer);
   nclusters = bufferFile(dirs + i, sFAT, &buffer);
   if(buffer && (dirs[i].attrib & 0x10) && (nclusters > 0)){
    int N;
    N = nclusters * clusterSize / sizeof(dirEntry);
    readDirectory((struct DIRENTRY *) buffer, N, sFAT, fat);
   }
  }
 }
 free(buffer);
 return 0;
}

variable_types: struct DIRENTRY { unsigned char name[8]; unsigned char ext[3]; unsigned char attrib; unsigned char zero[10]; unsigned short time; unsigned short date; unsigned short start; unsigned short length[2]; } *

variable_types: Nentries int

variable_types:
sFAT
unsigned short *

variable_types: fat int

variable_types: j int

variable_types: nclusters int

variable_types: N int


printDirEntry

decompiled_code:
int __fastcall printDirEntry(unsigned __int8 *a1)
{
int v2; // edi
unsigned __int8 *i; // rbx
unsigned __int8 *v4; // rbx
int v5; // edi
unsigned __int8 *v6; // rbx
__int64 v7; // rsi
int result; // eax
unsigned __int8 *v9; // rbx
unsigned __int8 *v10; // rbp
int v11; // edi

if ( a1[11] == 15 )
{
v9 = a1 + 1;
v10 = a1 + 32;
printf("LFN:");
do
{
while ( 1 )
{
v11 = *v9;
if ( (unsigned __int8)v11 <= 0x1Fu )
break;
putchar(v11);
if ( ++v9 == v10 )
goto LABEL_20;
}
if ( (_BYTE)v11 )
printf("&%x;", (unsigned __int8)v11);
++v9;
}
while ( v9 != v10 );
LABEL_20:
result = putchar(10);
}
else
{
v2 = *a1;
if ( (_BYTE)v2 )
{
for ( i = a1 + 1; (unsigned __int8)v2 > 0x1Fu; ++i )
{
putchar(v2);
if ( i == a1 + 8 )
break;
v2 = *i;
}
v4 = a1 + 8;
do
{
v5 = *v4;
if ( (unsigned __int8)v5 <= 0x1Fu )
break;
putchar(v5);
++v4;
}
while ( v4 != a1 + 11 );
v6 = a1 + 12;
printf(" (%x)", a1[11]);
do
{
v7 = (unsigned int)*(__int16 *)v6;
v6 += 2;
printf(" %hu", v7);
}
while ( a1 + 22 != v6 );
result = printf(
" time: %hu date: %hu start: %hu length: %ld\n",
*((unsigned __int16 *)a1 + 11),
*((unsigned __int16 *)a1 + 12),
*((unsigned __int16 *)a1 + 13),
((unsigned __int64)*((unsigned __int16 *)a1 + 15) << 16) + *((unsigned __int16 *)a1 + 14));
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(unsigned __int8 *a1)
{
int v2; // edi
unsigned __int8 *i; // rbx
unsigned __int8 *v4; // rbx
int v5; // edi
unsigned __int8 *v6; // rbx
__int64 v7; // rsi
int result; // eax
unsigned __int8 *v9; // rbx
unsigned __int8 *v10; // rbp
int v11; // edi

if ( a1[11] == 15 )
{
v9 = a1 + 1;
v10 = a1 + 32;
printf("LFN:");
do
{
while ( 1 )
{
v11 = *v9;
if ( (unsigned __int8)v11 <= 0x1Fu )
break;
putchar(v11);
if ( ++v9 == v10 )
goto LABEL_20;
}
if ( (_BYTE)v11 )
printf("&%x;", (unsigned __int8)v11);
++v9;
}
while ( v9 != v10 );
LABEL_20:
result = putchar(10);
}
else
{
v2 = *a1;
if ( (_BYTE)v2 )
{
for ( i = a1 + 1; (unsigned __int8)v2 > 0x1Fu; ++i )
{
putchar(v2);
if ( i == a1 + 8 )
break;
v2 = *i;
}
v4 = a1 + 8;
do
{
v5 = *v4;
if ( (unsigned __int8)v5 <= 0x1Fu )
break;
putchar(v5);
++v4;
}
while ( v4 != a1 + 11 );
v6 = a1 + 12;
printf(" (%x)", a1[11]);
do
{
v7 = (unsigned int)*(__int16 *)v6;
v6 += 2;
printf(" %hu", v7);
}
while ( a1 + 22 != v6 );
result = printf(
" time: %hu date: %hu start: %hu length: %ld\n",
*((unsigned __int16 *)a1 + 11),
*((unsigned __int16 *)a1 + 12),
*((unsigned __int16 *)a1 + 13),
((unsigned __int64)*((unsigned __int16 *)a1 + 15) << 16) + *((unsigned __int16 *)a1 + 14));
}
}
return result;
}

original_code:
void printDirEntry(dirEntry *e){
 int i;
 short *zero = (short *) e->zero;
 if(e->attrib == 0x0f){
  printf("LFN:");
  for(i = 1; i < 32; i++){
   if(e->name[i] >= ' ') printf("%c", e->name[i]);
   else if(e->name[i]) printf("&%x;", e->name[i]);
  }
  printf("\n");
 }else if(e->name[0] != 0){
  for(i = 0; i < 8; i++){
   if(e->name[i] < ' '){
    break;
   }
   printf("%c", e->name[i]);
  }
  for(i = 0; i < 3; i++){
   if(e->ext[i] < ' '){
    break;
   }
   printf("%c", e->ext[i]);
  }
  printf(" (%x)", e->attrib);
  for(i = 0; i < 5; i++){
   printf(" %hu", zero[i]);
  }
  printf(" time: %hu date: %hu start: %hu length: %ld\n", e->time,
   e->date, e->start, ((e->length[0] & 0xffff) + (((long)(e->length[1] & 0xffff)) << 16)));
 }
}

canonical_original_code:
void printDirEntry(struct DIRENTRY *e){
 int i;
 short *zero = (short *) e->zero;
 if(e->attrib == 0x0f){
  printf("LFN:");
  for(i = 1; i < 32; i++){
   if(e->name[i] >= ' ') printf("%c", e->name[i]);
   else if(e->name[i]) printf("&%x;", e->name[i]);
  }
  printf("\n");
 }else if(e->name[0] != 0){
  for(i = 0; i < 8; i++){
   if(e->name[i] < ' '){
    break;
   }
   printf("%c", e->name[i]);
  }
  for(i = 0; i < 3; i++){
   if(e->ext[i] < ' '){
    break;
   }
   printf("%c", e->ext[i]);
  }
  printf(" (%x)", e->attrib);
  for(i = 0; i < 5; i++){
   printf(" %hu", zero[i]);
  }
  printf(" time: %hu date: %hu start: %hu length: %ld\n", e->time,
   e->date, e->start, ((e->length[0] & 0xffff) + (((long)(e->length[1] & 0xffff)) << 16)));
 }
}

variable_types: i int

variable_types:
zero
short *

user_defined_types: struct DIRENTRY { unsigned char name[8]; unsigned char ext[3]; unsigned char attrib; unsigned char zero[10]; unsigned short time; unsigned short date; unsigned short start; unsigned short length[2]; }


followDirEntry

decompiled_code:
__int64 __fastcall followDirEntry(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
int v3; // er13
int v4; // ebp
int v5; // er15
char v6; // al
unsigned int v7; // er14
int v8; // er13
unsigned __int16 v9; // bp

v2 = *(unsigned __int16 *)(a1 + 26);
v3 = *(unsigned __int16 *)(a1 + 28);
v4 = *(unsigned __int16 *)(a1 + 30);
v5 = clusterSize;
printf("Following chain from %d\n", v2);
v6 = *(_BYTE *)(a1 + 11);
v7 = 0;
if ( v6 != 15 )
{
if ( (v6 & 8) != 0 )
{
puts("Volume label, not a file");
}
else if ( (int)v2 <= 1 )
{
puts("Not a valid starting cluster");
}
else
{
v8 = (v5 + v3 + (v4 << 16) - 1) / v5;
do
{
v9 = *(_WORD *)(a2 + 2 * v2);
++v7;
v2 = v9;
printf("%d ", v9);
}
while ( (unsigned __int16)(v9 - 1) <= 0xFEEu && v8 > (int)v7 );
printf("\nNclusters = %d\n", v7);
}
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
int v3; // er13
int v4; // ebp
int v5; // er15
char v6; // al
unsigned int v7; // er14
int v8; // er13
unsigned __int16 v9; // bp

v2 = *(unsigned __int16 *)(a1 + 26);
v3 = *(unsigned __int16 *)(a1 + 28);
v4 = *(unsigned __int16 *)(a1 + 30);
v5 = clusterSize;
printf("Following chain from %d\n", v2);
v6 = *(_BYTE *)(a1 + 11);
v7 = 0;
if ( v6 != 15 )
{
if ( (v6 & 8) != 0 )
{
puts("Volume label, not a file");
}
else if ( (int)v2 <= 1 )
{
puts("Not a valid starting cluster");
}
else
{
v8 = (v5 + v3 + (v4 << 16) - 1) / v5;
do
{
v9 = *(_WORD *)(a2 + 2 * v2);
++v7;
v2 = v9;
printf("%d ", v9);
}
while ( (unsigned __int16)(v9 - 1) <= 0xFEEu && v8 > (int)v7 );
printf("\nNclusters = %d\n", v7);
}
}
return v7;
}

original_code:
int followDirEntry(dirEntry *e, unsigned short *sFAT){
 int cur =e->start;
 int next;
 int nclusters = 0;
 int size = ((e->length[0] & 0xffff) + (((long)(e->length[1] & 0xffff)) << 16));
 int nexpected = 0;
 nexpected = (size + clusterSize - 1) / clusterSize;
 if(e->attrib == 0x0f){
  return 0;
 }
 if(e->attrib & 0x08){
  printf("Volume label, not a file\n");
  return 0;
 }
 if(cur < 2){
  printf("Not a valid starting cluster\n");
  return 0;
 }
 do{
  nclusters++;
  next = sFAT[cur];
  cur = next;
 }while(next && (next < 0x0FF0) && (nclusters < nexpected));
 return nclusters;
}

canonical_original_code:
int followDirEntry(struct DIRENTRY *e, unsigned short *sFAT){
 int cur = e->start;
 int next;
 int nclusters = 0;
 int size = ((e->length[0] & 0xffff) + (((long)(e->length[1] & 0xffff)) << 16));
 int nexpected = 0;
 nexpected = (size + clusterSize - 1) / clusterSize;
 if(e->attrib == 0x0f){
  return 0;
 }
 if(e->attrib & 0x08){
  printf("Volume label, not a file\n");
  return 0;
 }
 if(cur < 2){
  printf("Not a valid starting cluster\n");
  return 0;
 }
 do{
  nclusters++;
  next = sFAT[cur];
  cur = next;
 }while(next && (next < 0x0FF0) && (nclusters < nexpected));
 return nclusters;
}

variable_types: cur int

variable_types: next int

variable_types: size int

variable_types: nexpected int


bufferFile

decompiled_code:
__int64 __fastcall bufferFile(__int64 a1, __int64 a2, _QWORD *a3)
{
_QWORD *v3; // rbx
int v4; // er15
unsigned int v5; // eax
unsigned int v6; // er12
signed int v8; // er14
void *v9; // rax
int v10; // ebp
int v11; // ebx
unsigned int v12; // eax
__int64 v13; // rdx
int fd; // [rsp+4h] [rbp-44h]

v3 = a3;
v4 = *(unsigned __int16 *)(a1 + 26);
v5 = followDirEntry(a1, a2);
*v3 = 0LL;
v6 = v5;
if ( v5 )
{
v8 = 0;
v9 = calloc((int)((v5 * spc) << 9), 1uLL);
v10 = clusterSize;
*v3 = v9;
v11 = 0;
while ( 1 )
{
fd = fid;
lseek(fid, v10 * (v4 + dataStart), 0);
v12 = read(fd, (void *)(*a3 + v11), v10);
v10 = v12;
if ( clusterSize != v12 )
{
v6 = -1;
printf("Disk read error, expected %d bytes, read %d\n", (unsigned int)clusterSize, v12);
printf("Attempting to read cluster %d\n", (unsigned int)v4);
return v6;
}
v11 += v12;
++v8;
v4 = *(unsigned __int16 *)(a2 + 2LL * v4);
if ( (unsigned __int16)(v4 - 1) > 0xFEEu )
break;
if ( (int)v6 <= v8 )
goto LABEL_9;
}
if ( v4 > 4079 )
return v6;
LABEL_9:
v13 = v6;
v6 = -2;
printf(
"Broken file, read %d clusters, expected %d, next cluster would be at %d\n",
(unsigned int)v8,
v13,
(unsigned int)v4);
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, _QWORD *a3)
{
_QWORD *v3; // rbx
int v4; // er15
unsigned int v5; // eax
unsigned int v6; // er12
signed int v8; // er14
void *v9; // rax
int v10; // ebp
int v11; // ebx
unsigned int v12; // eax
__int64 v13; // rdx
int fd; // [rsp+4h] [rbp-44h]

v3 = a3;
v4 = *(unsigned __int16 *)(a1 + 26);
v5 = func1(a1, a2);
*v3 = 0LL;
v6 = v5;
if ( v5 )
{
v8 = 0;
v9 = calloc((int)((v5 * spc) << 9), 1uLL);
v10 = clusterSize;
*v3 = v9;
v11 = 0;
while ( 1 )
{
fd = fid;
lseek(fid, v10 * (v4 + dataStart), 0);
v12 = read(fd, (void *)(*a3 + v11), v10);
v10 = v12;
if ( clusterSize != v12 )
{
v6 = -1;
printf("Disk read error, expected %d bytes, read %d\n", (unsigned int)clusterSize, v12);
printf("Attempting to read cluster %d\n", (unsigned int)v4);
return v6;
}
v11 += v12;
++v8;
v4 = *(unsigned __int16 *)(a2 + 2LL * v4);
if ( (unsigned __int16)(v4 - 1) > 0xFEEu )
break;
if ( (int)v6 <= v8 )
goto LABEL_9;
}
if ( v4 > 4079 )
return v6;
LABEL_9:
v13 = v6;
v6 = -2;
printf(
"Broken file, read %d clusters, expected %d, next cluster would be at %d\n",
(unsigned int)v8,
v13,
(unsigned int)v4);
}
return v6;
}

original_code:
int bufferFile(dirEntry *e, unsigned short *sFAT, char **buffer){
 int cur = e->start;
 int nclusters = followDirEntry(e, sFAT);
 int nbytes;
 int nread = 0;
 int prev = cur;
 int offset = 0;
 int inTable = 0;
 dirEntry *copy = ((void *)0);
 (*buffer) = ((void *)0);
 if(nclusters == 0) return 0;
 *buffer = calloc(nclusters * bps * spc, 1);
 copy = malloc(sizeof(dirEntry));
 memcpy(copy, e, sizeof(dirEntry));
 do{
  if(indiceTable[cur] == ((void *)0)){
   inTable = 1;
   indiceTable[cur] = copy;
  }else if(indiceTable[cur] == copy){
   printf("Loop found at index %d\n", cur);
   printDirEntry(copy);
   puts("");
   (*buffer) = ((void *)0);
   return -2;
  }else if(!memcmp(copy, indiceTable[cur], sizeof(dirEntry))){
   printf("Duplicate file found\n");
   printDirEntry(copy);
   puts("");
   (*buffer) = ((void *)0);
   return -2;
  }else{
   printf("Double link found at index %d for file (%p):\n",
    cur, copy);
   printDirEntry(copy);
   printf("The link was also accessed by (%p):\n",
    indiceTable[cur]);
   printDirEntry(indiceTable[cur]);
   puts("");
  }
  if(badIndices[cur]){
   printf("Note: ");
   printf("cluster %d marked as inconsistent. clusters read: %d,"
    "clusters expected: %d\n", cur, nread, nclusters);
   printDirEntry(e);
  }
  lseek(fid, (cur + dataStart) * clusterSize, 0);
  nbytes = read(fid, (*buffer) + offset, clusterSize);
  if(clusterSize != nbytes){
   printf("Disk read error, expected %d bytes, read %d\n",
    clusterSize, nbytes);
   printf("Attempting to read cluster %d\n", cur);
   return -1;
  }
  nread++;
  offset += clusterSize;
  prev = cur;
  cur = sFAT[cur];
 }while(cur && (cur < 0x0FF0) && (nread < nclusters));
 if(!inTable){
  free(copy);
 }
 if(!cur){
  if(nread != nclusters){
   printf("Empty marker found in chain at index %d, read %d "
    "clusters. I expected %d clusters.\n", prev, nread,
    nclusters);
  }else{
   printf("Empty marker found in chain at index %d. I expected"
    " an end of chain marker.\n", prev);
  }
  printDirEntry(e);
  puts("");
  return -2;
 }else if(cur < 0x0FF0){
  printf("Incorrect file length, read %d cluster(s), next cluster"
   " would be at %d but should be an end of chain marker.\n",
   nread, cur);
  printDirEntry(e);
  puts("");
  return -2;
 }else if(nread != nclusters){
  printf("Incorrect file length, chain ends at cluster %d, but the"
   "file length gives %d clusters.\n", nread, nclusters);
  printDirEntry(e);
  puts("");
  return -2;
 }
 return nclusters;
}

canonical_original_code:
int bufferFile(struct DIRENTRY *e, unsigned short *sFAT, char **buffer){
 int cur = e->start;
 int nclusters = followDirEntry(e, sFAT);
 int nbytes;
 int nread = 0;
 int prev = cur;
 int offset = 0;
 int inTable = 0;
 struct DIRENTRY *copy = ((void *)0);
 (*buffer) = ((void *)0);
 if(nclusters == 0) return 0;
 *buffer = calloc(nclusters * bps * spc, 1);
 copy = malloc(sizeof(dirEntry));
 memcpy(copy, e, sizeof(dirEntry));
 do{
  if(indiceTable[cur] == ((void *)0)){
   inTable = 1;
   indiceTable[cur] = copy;
  }else if(indiceTable[cur] == copy){
   printf("Loop found at index %d\n", cur);
   printDirEntry(copy);
   puts("");
   (*buffer) = ((void *)0);
   return -2;
  }else if(!memcmp(copy, indiceTable[cur], sizeof(dirEntry))){
   printf("Duplicate file found\n");
   printDirEntry(copy);
   puts("");
   (*buffer) = ((void *)0);
   return -2;
  }else{
   printf("Double link found at index %d for file (%p):\n",
    cur, copy);
   printDirEntry(copy);
   printf("The link was also accessed by (%p):\n",
    indiceTable[cur]);
   printDirEntry(indiceTable[cur]);
   puts("");
  }
  if(badIndices[cur]){
   printf("Note: ");
   printf("cluster %d marked as inconsistent. clusters read: %d,"
    "clusters expected: %d\n", cur, nread, nclusters);
   printDirEntry(e);
  }
  lseek(fid, (cur + dataStart) * clusterSize, 0);
  nbytes = read(fid, (*buffer) + offset, clusterSize);
  if(clusterSize != nbytes){
   printf("Disk read error, expected %d bytes, read %d\n",
    clusterSize, nbytes);
   printf("Attempting to read cluster %d\n", cur);
   return -1;
  }
  nread++;
  offset += clusterSize;
  prev = cur;
  cur = sFAT[cur];
 }while(cur && (cur < 0x0FF0) && (nread < nclusters));
 if(!inTable){
  free(copy);
 }
 if(!cur){
  if(nread != nclusters){
   printf("Empty marker found in chain at index %d, read %d "
    "clusters. I expected %d clusters.\n", prev, nread,
    nclusters);
  }else{
   printf("Empty marker found in chain at index %d. I expected"
    " an end of chain marker.\n", prev);
  }
  printDirEntry(e);
  puts("");
  return -2;
 }else if(cur < 0x0FF0){
  printf("Incorrect file length, read %d cluster(s), next cluster"
   " would be at %d but should be an end of chain marker.\n",
   nread, cur);
  printDirEntry(e);
  puts("");
  return -2;
 }else if(nread != nclusters){
  printf("Incorrect file length, chain ends at cluster %d, but the"
   "file length gives %d clusters.\n", nread, nclusters);
  printDirEntry(e);
  puts("");
  return -2;
 }
 return nclusters;
}

variable_types:
buffer
char **

variable_types: nbytes int

variable_types: nread int

variable_types: prev int

variable_types: offset int

variable_types: inTable int


expandFAT

original_code:
void expandFAT(unsigned char *FAT, unsigned short *sFAT, int entries){
 int i, j;
 for(i = 0, j = 0; i < entries; i += 2, j += 3){
  sFAT[i] = FAT[j] + 256 * (FAT[j + 1] & 0xf);
  sFAT[i + 1] = ((FAT[j + 1] >> 4) & 0xf) + 16 *FAT[j + 2];
 }
}

canonical_original_code:
void expandFAT(unsigned char *FAT, unsigned short *sFAT, int entries){
 int i; int j;
 for(i = 0, j = 0; i < entries; i += 2, j += 3){
  sFAT[i] = FAT[j] + 256 * (FAT[j + 1] & 0xf);
  sFAT[i + 1] = ((FAT[j + 1] >> 4) & 0xf) + 16 *FAT[j + 2];
 }
}

variable_types:
FAT
unsigned char *

variable_types:
sFAT
unsigned short *

variable_types: entries int