decompiled_code:
int print_help()
{
puts("=========================================================");
puts("C32-EMU, Emulator for the Custom 32-bit RISC architecture");
puts("Copyright (C) 2013, Joe Mruz");
puts("v0.1a");
puts("=========================================================");
puts("valid options:\n");
puts("-disk <disk filename> -- specify the secondary storage");
puts("-rom <rom filename> -- specify the read-only memory");
puts("-boot_rom -- boot from the rom instead of disk");
puts("-fast -- use 100 percent CPU to speed up emulation");
puts("-slow -- set instruction execution speed equal to the FPS");
puts("-debug -- enable on-screen debug text (can toggle with F1)");
puts("-color -- specify text color (green, amber, white)");
puts("-help -- print this dialog");
return puts(
"\n"
"usage: emu [-fast] [-slow] [-debug] [-boot_rom] -disk <filename> [-rom <filename>] [-color <name>] [-help]");
}

canonical_decompiled_code:
int func0()
{
puts("=========================================================");
puts("C32-EMU, Emulator for the Custom 32-bit RISC architecture");
puts("Copyright (C) 2013, Joe Mruz");
puts("v0.1a");
puts("=========================================================");
puts("valid options:\n");
puts("-disk <disk filename> -- specify the secondary storage");
puts("-rom <rom filename> -- specify the read-only memory");
puts("-boot_rom -- boot from the rom instead of disk");
puts("-fast -- use 100 percent CPU to speed up emulation");
puts("-slow -- set instruction execution speed equal to the FPS");
puts("-debug -- enable on-screen debug text (can toggle with F1)");
puts("-color -- specify text color (green, amber, white)");
puts("-help -- print this dialog");
return puts(
"\n"
"usage: emu [-fast] [-slow] [-debug] [-boot_rom] -disk <filename> [-rom <filename>] [-color <name>] [-help]");
}

original_code:
void print_help(void)
{
    printf ("=========================================================\n");
    printf ("C32-EMU, Emulator for the Custom 32-bit RISC architecture\n");
    printf ("Copyright (C) 2013, Joe Mruz\n");
    printf ("v""0.1a""\n");
    printf ("=========================================================\n");
    printf ("valid options:\n\n");
    printf ("-disk <disk filename>   -- specify the secondary storage\n");
    printf ("-rom <rom filename>     -- specify the read-only memory\n");
    printf ("-boot_rom               -- boot from the rom instead of disk\n");
    printf ("-fast                   -- use 100 percent CPU to speed up emulation\n");
    printf ("-slow                   -- set instruction execution speed equal to the FPS\n");
    printf ("-debug                  -- enable on-screen debug text (can toggle with F1)\n");
    printf ("-color                  -- specify text color (green, amber, white)\n");
    printf ("-help                   -- print this dialog\n");
    printf ("\nusage: emu [-fast] [-slow] [-debug] [-boot_rom] -disk <filename> [-rom <filename>] [-color <name>] [-help]\n");
}

canonical_original_code:
void print_help()
{
    printf ("=========================================================\n");
    printf ("C32-EMU, Emulator for the Custom 32-bit RISC architecture\n");
    printf ("Copyright (C) 2013, Joe Mruz\n");
    printf ("v""0.1a""\n");
    printf ("=========================================================\n");
    printf ("valid options:\n\n");
    printf ("-disk <disk filename>   -- specify the secondary storage\n");
    printf ("-rom <rom filename>     -- specify the read-only memory\n");
    printf ("-boot_rom               -- boot from the rom instead of disk\n");
    printf ("-fast                   -- use 100 percent CPU to speed up emulation\n");
    printf ("-slow                   -- set instruction execution speed equal to the FPS\n");
    printf ("-debug                  -- enable on-screen debug text (can toggle with F1)\n");
    printf ("-color                  -- specify text color (green, amber, white)\n");
    printf ("-help                   -- print this dialog\n");
    printf ("\nusage: emu [-fast] [-slow] [-debug] [-boot_rom] -disk <filename> [-rom <filename>] [-color <name>] [-help]\n");
}


decompiled_code:
char __fastcall runtime_options(int a1, __int64 a2)
{
int i; // ebx
const char *v5; // rsi
int v6; // eax
__int64 v7; // r8
const char *v8; // rsi
bool v9; // zf

if ( a1 > 1 )
{
for ( i = 1; i < a1; ++i )
{
v7 = 8LL * i;
if ( !strcmp("-disk", *(const char **)(a2 + v7)) )
{
++i;
v8 = *(const char **)(a2 + v7 + 8);
if ( !v8 )
{
puts("Error: filename not provided.");
print_help();
exit(2);
}
LOBYTE(v6) = (unsigned __int8)strncpy(Disk_filn, v8, 0x80uLL);
++Opt_disk;
}
else if ( !strcmp("-rom", *(const char **)(a2 + 8LL * i)) )
{
++i;
v5 = *(const char **)(a2 + v7 + 8);
if ( !v5 )
{
puts("Error: filename not provided.");
print_help();
exit(2);
}
LOBYTE(v6) = (unsigned __int8)strncpy(&Rom_filn, v5, 0x80uLL);
}
else if ( !strcmp("-color", *(const char **)(a2 + 8LL * i)) )
{
++i;
if ( !*(_QWORD *)(a2 + v7 + 8) )
{
puts("Error: Color name required.");
print_help();
exit(2);
}
v9 = strcmp("green", *(const char **)(a2 + v7 + 8)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Text_color = 1;
}
else
{
v9 = strcmp("amber", *(const char **)(a2 + v7 + 8)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Text_color = 2;
}
else
{
v6 = strcmp("red", *(const char **)(a2 + v7 + 8)) == 0 ? 3 : 0;
Text_color = v6;
}
}
}
else
{
v9 = memcmp("-boot_rom", *(const void **)(a2 + 8LL * i), 8uLL) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
--Boot_disk;
}
else
{
v9 = strcmp("-fast", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
++Emu_max_speed;
Emu_refresh_rate *= 4;
}
else
{
v9 = strcmp("-slow", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Emu_refresh_rate = 1;
}
else
{
v9 = strcmp("-debug", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( !v9 )
{
if ( !strcmp("-h", *(const char **)(a2 + 8LL * i))
|| !strcmp("--help", *(const char **)(a2 + 8LL * i))
|| !strcmp("-help", *(const char **)(a2 + 8LL * i)) )
{
print_help();
exit(2);
}
printf("Unrecognized option: %s\n", *(const char **)(a2 + 8LL * i));
print_help();
exit(2);
}
++Emu_dbg_option;
}
}
}
}
}
}
if ( !Opt_disk )
{
puts("Error: Must specify a disk file");
print_help();
exit(2);
}
if ( !Boot_disk && !Rom_filn )
{
puts("Must provide rom file to boot");
exit(2);
}
return v6;
}

canonical_decompiled_code:
char __fastcall func1(int a1, __int64 a2)
{
int i; // ebx
const char *v5; // rsi
int v6; // eax
__int64 v7; // r8
const char *v8; // rsi
bool v9; // zf

if ( a1 > 1 )
{
for ( i = 1; i < a1; ++i )
{
v7 = 8LL * i;
if ( !strcmp("-disk", *(const char **)(a2 + v7)) )
{
++i;
v8 = *(const char **)(a2 + v7 + 8);
if ( !v8 )
{
puts("Error: filename not provided.");
func0();
exit(2);
}
LOBYTE(v6) = (unsigned __int8)strncpy(Disk_filn, v8, 0x80uLL);
++Opt_disk;
}
else if ( !strcmp("-rom", *(const char **)(a2 + 8LL * i)) )
{
++i;
v5 = *(const char **)(a2 + v7 + 8);
if ( !v5 )
{
puts("Error: filename not provided.");
func0();
exit(2);
}
LOBYTE(v6) = (unsigned __int8)strncpy(&Rom_filn, v5, 0x80uLL);
}
else if ( !strcmp("-color", *(const char **)(a2 + 8LL * i)) )
{
++i;
if ( !*(_QWORD *)(a2 + v7 + 8) )
{
puts("Error: Color name required.");
func0();
exit(2);
}
v9 = strcmp("green", *(const char **)(a2 + v7 + 8)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Text_color = 1;
}
else
{
v9 = strcmp("amber", *(const char **)(a2 + v7 + 8)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Text_color = 2;
}
else
{
v6 = strcmp("red", *(const char **)(a2 + v7 + 8)) == 0 ? 3 : 0;
Text_color = v6;
}
}
}
else
{
v9 = memcmp("-boot_rom", *(const void **)(a2 + 8LL * i), 8uLL) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
--Boot_disk;
}
else
{
v9 = strcmp("-fast", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
++Emu_max_speed;
Emu_refresh_rate *= 4;
}
else
{
v9 = strcmp("-slow", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( v9 )
{
Emu_refresh_rate = 1;
}
else
{
v9 = strcmp("-debug", *(const char **)(a2 + 8LL * i)) == 0;
LOBYTE(v6) = !v9;
if ( !v9 )
{
if ( !strcmp("-h", *(const char **)(a2 + 8LL * i))
|| !strcmp("--help", *(const char **)(a2 + 8LL * i))
|| !strcmp("-help", *(const char **)(a2 + 8LL * i)) )
{
func0();
exit(2);
}
printf("Unrecognized option: %s\n", *(const char **)(a2 + 8LL * i));
func0();
exit(2);
}
++Emu_dbg_option;
}
}
}
}
}
}
if ( !Opt_disk )
{
puts("Error: Must specify a disk file");
func0();
exit(2);
}
if ( !Boot_disk && !Rom_filn )
{
puts("Must provide rom file to boot");
exit(2);
}
return v6;
}

original_code:
void
runtime_options(int argc, char **argv)
{
    int i;
    for (i = 1; i < argc; i++)
    {
        if (!strncmp ("-disk", argv [i], sizeof (argv [i])))
        {
            ++i;
            if(!argv [i])
            {
                printf ("Error: filename not provided.\n");
                print_help ();
                exit (2);
            }
            strncpy (Disk_filn, argv [i], sizeof (Disk_filn));
            ++Opt_disk;
        }
        else if (!strncmp ("-rom", argv [i], sizeof (argv [i])))
        {
            ++i;
            if (!argv [i])
            {
                printf ("Error: filename not provided.\n");
                print_help ();
                exit (2);
            }
            strncpy (Rom_filn, argv [i], sizeof (Disk_filn));
        }
        else if (!strncmp ("-color", argv [i], sizeof (argv [i])))
        {
            ++i;
            if (!argv [i])
            {
                printf ("Error: Color name required.\n");
                print_help ();
                exit (2);
            }
            if (!strncmp ("green", argv [i], sizeof (argv [i])))
            {
                Text_color = 1;
            }
            else if (!strncmp ("amber", argv [i], sizeof (argv [i])))
            {
                Text_color = 2;
            }
            else if (!strncmp ("red", argv [i], sizeof (argv [i])))
            {
                Text_color = 3;
            }
            else
            {
                Text_color = 0;
            }
        }
        else if (!strncmp ("-boot_rom", argv [i], sizeof (argv [i])))
        {
            --Boot_disk;
        }
        else if (!strncmp ("-fast", argv [i], sizeof (argv [i])))
        {
            ++Emu_max_speed;
            Emu_refresh_rate *= 4;
        }
        else if (!strncmp ("-slow", argv [i], sizeof (argv [i])))
        {
            Emu_refresh_rate = 1;
        }
        else if (!strncmp ("-debug", argv [i], sizeof (argv [i])))
        {
            ++Emu_dbg_option;
        }
        else if (!strncmp ("-h", argv [i], sizeof (argv [i])) ||
                 !strncmp ("--help", argv [i], sizeof (argv [i])) ||
                 !strncmp ("-help", argv [i], sizeof (argv [i])))
        {
            print_help ();
            exit (2);
        }
        else
        {
            printf ("Unrecognized option: %s\n", argv [i]);
            print_help ();
            exit (2);
        }
    }
    if (!Opt_disk)
    {
        printf ("Error: Must specify a disk file\n");
        print_help ();
        exit (2);
    }
    if (!Boot_disk &&
        !Rom_filn [0])
    {
        printf ("Must provide rom file to boot\n");
        exit (2);
    }
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int

return_type: void


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
Emu_max_speed = 0;
Emu_refresh_rate = 60;
Emu_dbg_option = 0;
Opt_disk = 0;
Boot_disk = 1;
Text_color = 0;
memset(Disk_filn, 0, sizeof(Disk_filn));
memset(&Rom_filn, 0, 0x80uLL);
runtime_options(argc, (__int64)argv);
puts("C32-EMU v0.1a");
puts("Copyright (C) 2013, Joe Mruz");
puts("=============================");
puts("Initializing everything...");
emu_init();
puts("Starting...");
while ( Emu_run )
emu_main_loop();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
Emu_max_speed = 0;
Emu_refresh_rate = 60;
Emu_dbg_option = 0;
Opt_disk = 0;
Boot_disk = 1;
Text_color = 0;
memset(Disk_filn, 0, sizeof(Disk_filn));
memset(&Rom_filn, 0, 0x80uLL);
func1(argc, (__int64)argv);
puts("C32-EMU v0.1a");
puts("Copyright (C) 2013, Joe Mruz");
puts("=============================");
puts("Initializing everything...");
emu_init();
puts("Starting...");
while ( Emu_run )
emu_main_loop();
return 0;
}

original_code:
int
main(int argc, char **argv)
{
    Emu_max_speed = 0;
    Emu_refresh_rate = 60;
    Emu_dbg_option = 0;
    Opt_disk = 0;
    Boot_disk = 1;
    Text_color = 0;
    memset (Disk_filn, 0, sizeof (Disk_filn));
    memset (Rom_filn, 0, sizeof (Rom_filn));
    runtime_options (argc, argv);
    printf ("C32-EMU v""0.1a""\n");
    printf ("Copyright (C) 2013, Joe Mruz\n");
    printf ("=============================\n");
    printf ("Initializing everything...\n");
    emu_init ();
    printf ("Starting...\n");
    while (Emu_run)
        emu_main_loop ();
    return 0;
}

return_type: int


original_code:
void
disk_rd_port(disk_t *disk, uint32_t *dat, ram_t *ram)
{
 unsigned int i;
    switch (disk->state)
 {
  case DISK_READ_BUFFER_START:
   if (*dat == 0xFFFFFFFC) {
    disk->state = DISK_READ_BUFFER_SIZE;
   }
   else if ( (*dat) || *dat != 0xFFFFFFFE)
   {
    if(*dat >= (1024 * 1024))
    {
     *dat = 0xFFFFFFFE;
     break;
    }
    disk->mapped_buffer_start = *dat;
   }
            *dat = 0;
   break;
  case DISK_READ_BUFFER_SIZE:
   if (*dat == 0xFFFFFFFC) {
    disk->state = DISK_READ_REQUEST;
                *dat = 0xFFFFFFFD;
   }
   else if ((*dat) || *dat != 0xFFFFFFFE)
   {
    if ((*dat) + disk->mapped_buffer_start >= (1024 * 1024))
    {
     *dat = 0xFFFFFFFE;
     break;
    }
    disk->mapped_buffer_size = *dat;
                *dat = 0;
   }
   break;
  case DISK_READ_REQUEST:
   switch (*dat)
   {
    case 0xFFFFFFFC: disk->state = DISK_HOLD; break;
    case 0xFFFFFFFF:
     for(i = 0; i < disk->mapped_buffer_size; i++)
     {
      disk->address [disk->seek + i] =
         ram->address [disk->mapped_buffer_start + i];
     }
     *dat = 0xFFFFFFFD;
     break;
    case 0xFFFFFFFE: break;
    case 0xFFFFFFFD: break;
    case DISK_HOLD: break;
    default:
     if (*dat >= (1024 * 1024 * 30))
     {
                        printf ("Error: disk seek request greater than size of disk");
      *dat = 0xFFFFFFFE;
      return;
     }
     disk->seek = *dat;
     for (i = 0; i < disk->mapped_buffer_size &&
        i < (1024 * 1024 * 30);
        i++)
     {
      ram->address [disk->mapped_buffer_start + i] = disk->address [disk->seek + i];
     }
     *dat = 0xFFFFFFFD;
     break;
   }
            break;
        case DISK_HOLD:
            if(*dat == 0xFFFFFFFC) {
                disk->state = DISK_READ_BUFFER_START;
            }
            *dat = 0;
            break;
  default: disk->state = DISK_READ_BUFFER_START; break;
 }
}

canonical_original_code:
void disk_rd_port(struct disk_s *disk, unsigned int *dat, struct ram_s *ram)
{
 unsigned int i;
    switch (disk->state)
 {
  case DISK_READ_BUFFER_START:
   if (*dat == 0xFFFFFFFC) {
    disk->state = DISK_READ_BUFFER_SIZE;
   }
   else if ( (*dat) || *dat != 0xFFFFFFFE)
   {
    if(*dat >= (1024 * 1024))
    {
     *dat = 0xFFFFFFFE;
     break;
    }
    disk->mapped_buffer_start = *dat;
   }
            *dat = 0;
   break;
  case DISK_READ_BUFFER_SIZE:
   if (*dat == 0xFFFFFFFC) {
    disk->state = DISK_READ_REQUEST;
                *dat = 0xFFFFFFFD;
   }
   else if ((*dat) || *dat != 0xFFFFFFFE)
   {
    if ((*dat) + disk->mapped_buffer_start >= (1024 * 1024))
    {
     *dat = 0xFFFFFFFE;
     break;
    }
    disk->mapped_buffer_size = *dat;
                *dat = 0;
   }
   break;
  case DISK_READ_REQUEST:
   switch (*dat)
   {
    case 0xFFFFFFFC: disk->state = DISK_HOLD; break;
    case 0xFFFFFFFF:
     for(i = 0; i < disk->mapped_buffer_size; i++)
     {
      disk->address [disk->seek + i] =
         ram->address [disk->mapped_buffer_start + i];
     }
     *dat = 0xFFFFFFFD;
     break;
    case 0xFFFFFFFE: break;
    case 0xFFFFFFFD: break;
    case DISK_HOLD: break;
    default:
     if (*dat >= (1024 * 1024 * 30))
     {
                        printf ("Error: disk seek request greater than size of disk");
      *dat = 0xFFFFFFFE;
      return;
     }
     disk->seek = *dat;
     for (i = 0; i < disk->mapped_buffer_size &&
        i < (1024 * 1024 * 30);
        i++)
     {
      ram->address [disk->mapped_buffer_start + i] = disk->address [disk->seek + i];
     }
     *dat = 0xFFFFFFFD;
     break;
   }
            break;
        case DISK_HOLD:
            if(*dat == 0xFFFFFFFC) {
                disk->state = DISK_READ_BUFFER_START;
            }
            *dat = 0;
            break;
  default: disk->state = DISK_READ_BUFFER_START; break;
 }
}

variable_types: struct disk_s { unsigned char address[-1]; unsigned int mapped_buffer_size; unsigned char state; unsigned int seek; unsigned int mapped_buffer_start; } *

variable_types:
dat
unsigned int *

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:
i
unsigned int

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


decompiled_code:
void *__fastcall disk_get_bootsector(void *src, void *dest, size_t n)
{
return memcpy(dest, src, (unsigned int)n);
}

canonical_decompiled_code:
void *__fastcall func2(void *src, void *dest, size_t n)
{
return memcpy(dest, src, (unsigned int)n);
}

original_code:
void
disk_get_bootsector(disk_t *disk, ram_t *ram, uint32_t num_bytes)
{
    memcpy ((void *)ram->address, (void *)disk->address, num_bytes);
}

canonical_original_code:
void disk_get_bootsector(struct disk_s *disk, struct ram_s *ram, unsigned int num_bytes)
{
    memcpy ((void *)ram->address, (void *)disk->address, num_bytes);
}

user_defined_types: struct disk_s { unsigned char address[-1]; unsigned int mapped_buffer_size; unsigned char state; unsigned int seek; unsigned int mapped_buffer_start; }

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


decompiled_code:
__int64 __fastcall disk_load(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = file_utils_read(a1, 31457280LL, a2);
if ( !(_DWORD)result )
{
printf("Error: Could not open disk.dat");
exit(0);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = file_utils_read(a1, 31457280LL, a2);
if ( !(_DWORD)result )
{
printf("Error: Could not open disk.dat");
exit(0);
}
return result;
}

original_code:
void
disk_load(disk_t *disk, const char *filename)
{
    if (!file_utils_read ((void *)disk->address,
                          sizeof (disk->address),
                          filename))
    {
        printf ("Error: Could not open ""disk.dat");
        exit(0);
    }
}

canonical_original_code:
void disk_load(struct disk_s *disk, char *filename)
{
    if (!file_utils_read ((void *)disk->address,
                          sizeof (disk->address),
                          filename))
    {
        printf ("Error: Could not open ""disk.dat");
        exit(0);
    }
}

variable_types:
filename
char *


decompiled_code:
int __fastcall disk_save(__int64 a1, __int64 a2)
{
int result; // eax

result = file_utils_write(a1, 31457280LL, a2);
if ( !result )
result = printf("Error: Could not open disk.dat");
return result;
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1, __int64 a2)
{
int result; // eax

result = file_utils_write(a1, 31457280LL, a2);
if ( !result )
result = printf("Error: Could not open disk.dat");
return result;
}

original_code:
void
disk_save(disk_t *disk, const char *filename)
{
    if (!file_utils_write ((void *)disk->address,
                           sizeof (disk->address),
                           filename))
    {
        printf ("Error: Could not open ""disk.dat");
    }
}

canonical_original_code:
void disk_save(struct disk_s *disk, char *filename)
{
    if (!file_utils_write ((void *)disk->address,
                           sizeof (disk->address),
                           filename))
    {
        printf ("Error: Could not open ""disk.dat");
    }
}


original_code:
void
disp_init(disp_t* disp)
{
 memset (disp->buffer, 0x0, sizeof (disp->buffer));
 disp->state = DISP_READ_ADR;
    disp->buffer_map_adr = 0;
    disp->cursor.pos = 0;
    disp->cursor.shape = 0xdb;
    disp->cursor.enabled = 0;
    memset (Ghost_buf, 0, sizeof (Ghost_buf));
}

canonical_original_code:
void disp_init(struct disp_s *disp)
{
 memset (disp->buffer, 0x0, sizeof (disp->buffer));
 disp->state = DISP_READ_ADR;
    disp->buffer_map_adr = 0;
    disp->cursor.pos = 0;
    disp->cursor.shape = 0xdb;
    disp->cursor.enabled = 0;
    memset (Ghost_buf, 0, sizeof (Ghost_buf));
}

variable_types: struct disp_s { unsigned char buffer[-1]; unsigned int buffer_map_adr; unsigned char state; struct disp_hwcurs_s { unsigned short pos; unsigned char enabled; unsigned char shape; } cursor; } *

user_defined_types: struct disp_s { unsigned char buffer[-1]; unsigned int buffer_map_adr; unsigned char state; struct disp_hwcurs_s cursor; }


original_code:
void
disp_rd_port(disp_t *disp, uint32_t *dat, ram_t *ram)
{
    if (!(*dat))
 {
  return;
 }
    if (disp->state == DISP_READ_CHAR)
    {
        switch (*dat)
        {
            case 0x1:
                memset (disp->buffer, 0, sizeof (disp->buffer));
                break;
            case 0x2:
                disp_rd_adr_map (disp, ram);
                break;
            case 0xFFFFF:
                disp->state = DISP_READ_ADR;
                break;
            case 0xFFFFE:
                disp->cursor.enabled = 1;
                break;
            case 0xFFFFD:
                disp->cursor.enabled = 0;
                break;
            case 0xFFFFC:
                disp->state = DISP_READ_CURSOR_POS;
                break;
            case 0xFFFFB:
                disp->state = DISP_READ_CURSOR_SHAPE;
                break;
        }
    }
    else if (disp->state == DISP_READ_ADR)
    {
        if (*dat)
        {
            disp->buffer_map_adr = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    else if (disp->state == DISP_READ_CURSOR_POS)
    {
        if (*dat)
        {
            disp->cursor.pos = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    else if (disp->state == DISP_READ_CURSOR_SHAPE)
    {
        if (*dat)
        {
            disp->cursor.shape = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    *dat = 0;
}

canonical_original_code:
void disp_rd_port(struct disp_s *disp, unsigned int *dat, struct ram_s *ram)
{
    if (!(*dat))
 {
  return;
 }
    if (disp->state == DISP_READ_CHAR)
    {
        switch (*dat)
        {
            case 0x1:
                memset (disp->buffer, 0, sizeof (disp->buffer));
                break;
            case 0x2:
                disp_rd_adr_map (disp, ram);
                break;
            case 0xFFFFF:
                disp->state = DISP_READ_ADR;
                break;
            case 0xFFFFE:
                disp->cursor.enabled = 1;
                break;
            case 0xFFFFD:
                disp->cursor.enabled = 0;
                break;
            case 0xFFFFC:
                disp->state = DISP_READ_CURSOR_POS;
                break;
            case 0xFFFFB:
                disp->state = DISP_READ_CURSOR_SHAPE;
                break;
        }
    }
    else if (disp->state == DISP_READ_ADR)
    {
        if (*dat)
        {
            disp->buffer_map_adr = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    else if (disp->state == DISP_READ_CURSOR_POS)
    {
        if (*dat)
        {
            disp->cursor.pos = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    else if (disp->state == DISP_READ_CURSOR_SHAPE)
    {
        if (*dat)
        {
            disp->cursor.shape = *dat;
            disp->state = DISP_READ_CHAR;
        }
    }
    *dat = 0;
}

user_defined_types: struct disp_hwcurs_s { unsigned short pos; unsigned char enabled; unsigned char shape; }


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:
dst
unsigned int *


decompiled_code:
void __fastcall utils_cpy_chunk(__int64 a1, int a2, unsigned int a3, int a4)
{
unsigned int v4; // eax

if ( a4 )
{
v4 = a3;
do
{
*(_BYTE *)(a1 + a2 - a3 + v4) = *(_BYTE *)(a1 + v4);
++v4;
}
while ( v4 != a4 + a3 );
}
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, int a2, unsigned int a3, int a4)
{
unsigned int v4; // eax

if ( a4 )
{
v4 = a3;
do
{
*(_BYTE *)(a1 + a2 - a3 + v4) = *(_BYTE *)(a1 + v4);
++v4;
}
while ( v4 != a4 + a3 );
}
}

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


decompiled_code:
__int64 __fastcall utils_compare(_DWORD *a1, int a2, int a3)
{
__int64 result; // rax
unsigned int v4; // esi

result = 1LL;
v4 = a2 - a3;
if ( v4 )
result = 2 * (v4 >> 31);
*a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(_DWORD *a1, int a2, int a3)
{
__int64 result; // rax
unsigned int v4; // esi

result = 1LL;
v4 = a2 - a3;
if ( v4 )
result = 2 * (v4 >> 31);
*a1 = result;
return result;
}

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 v3; // er14
unsigned __int8 v4; // r13
signed int v5; // ebp
unsigned int v6; // er15
unsigned int v7; // er12
__int64 v8; // rax
unsigned int v9; // esi
__int64 v10; // rcx
__int64 v11; // rcx
__int64 v12; // rcx
__int64 v13; // rcx
__int64 v14; // rcx
__int64 v15; // rcx
__int64 v16; // rcx
__int64 v17; // rsi
__int64 v18; // rdx
__int64 v19; // rdx
__int64 v20; // rdx
__int64 v21; // rdx
__int64 v22; // rdx
unsigned int v24; // [rsp+1Ch] [rbp-3Ch] BYREF

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

canonical_decompiled_code:
int __fastcall func1(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
unsigned int v3; // er14
unsigned __int8 v4; // r13
signed int v5; // ebp
unsigned int v6; // er15
unsigned int v7; // er12
__int64 v8; // rax
unsigned int v9; // esi
__int64 v10; // rcx
__int64 v11; // rcx
__int64 v12; // rcx
__int64 v13; // rcx
__int64 v14; // rcx
__int64 v15; // rcx
__int64 v16; // rcx
__int64 v17; // rsi
__int64 v18; // rdx
__int64 v19; // rdx
__int64 v20; // rdx
__int64 v21; // rdx
__int64 v22; // rdx
unsigned int v24; // [rsp+1Ch] [rbp-3Ch] BYREF

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

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);
Kb_buffer[0] = 0LL;
Kb_buffer[1] = 0LL;
Kb_buffer[2] = 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);
Kb_buffer[0] = 0LL;
Kb_buffer[1] = 0LL;
Kb_buffer[2] = 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) && LODWORD(Kb_buffer[0]) )
{
*((_DWORD *)&Cpu + 18) = Kb_buffer[0];
Kb_buffer[0] = *(__int64 *)((char *)Kb_buffer + 4);
LODWORD(Kb_buffer[1]) = HIDWORD(Kb_buffer[1]);
HIDWORD(Kb_buffer[1]) = Kb_buffer[2];
Kb_buffer[2] = HIDWORD(Kb_buffer[2]);
}
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) && LODWORD(Kb_buffer[0]) )
{
*((_DWORD *)&Cpu + 18) = Kb_buffer[0];
Kb_buffer[0] = *(__int64 *)((char *)Kb_buffer + 4);
LODWORD(Kb_buffer[1]) = HIDWORD(Kb_buffer[1]);
HIDWORD(Kb_buffer[1]) = Kb_buffer[2];
Kb_buffer[2] = HIDWORD(Kb_buffer[2]);
}
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 int *v0; // rbp
unsigned int i; // ebx
char *v2; // rbp
unsigned int j; // ebx
unsigned int v4; // ebx
unsigned int v5; // ebp
unsigned int v7; // [rsp+Ch] [rbp-3Ch] BYREF
char s[8]; // [rsp+10h] [rbp-38h] BYREF
__int64 v9; // [rsp+18h] [rbp-30h]
__int64 v10; // [rsp+20h] [rbp-28h]
__int64 v11; // [rsp+28h] [rbp-20h]

sdl_render_box(530LL, 90LL, 275LL, 260LL);
v0 = (unsigned int *)(unsigned int)((_DWORD)&Cpu + 4);
for ( i = 110; i != 270; i += 10 )
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", *v0);
sdl_render_text(s, 670LL, i);
++v0;
}
v2 = &Cpu;
for ( j = 280; j != 330; j += 10 )
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", *((unsigned int *)v2 + 17));
sdl_render_text(s, 670LL, j);
v2 += 4;
}
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", (unsigned __int8)Cpu);
sdl_render_text(s, 670LL, 330LL);
sdl_render_text("REGISTERS", 630LL, 100LL);
sdl_render_text(&off_3D0146A, 630LL, 110LL);
sdl_render_text((char *)&off_3D0146A + 2, 630LL, 120LL);
sdl_render_text(&off_3D0146E, 630LL, 130LL);
sdl_render_text((char *)&off_3D0146E + 2, 630LL, 140LL);
sdl_render_text(&off_3D01472, 630LL, 150LL);
sdl_render_text((char *)&off_3D01472 + 2, 630LL, 160LL);
sdl_render_text(&off_3D01476, 630LL, 170LL);
sdl_render_text((char *)&off_3D01476 + 2, 630LL, 180LL);
sdl_render_text(&off_3D0147A, 630LL, 190LL);
sdl_render_text(&unk_3D0147E, 630LL, 200LL);
sdl_render_text(&unk_3D01481, 630LL, 210LL);
sdl_render_text(&off_3D01483, 630LL, 220LL);
sdl_render_text(&unk_3D01487, 630LL, 230LL);
sdl_render_text(&unk_3D0148A, 630LL, 240LL);
sdl_render_text(&unk_3D0148D, 630LL, 250LL);
sdl_render_text(&unk_3D01490, 630LL, 260LL);
sdl_render_text("DISP", 630LL, 280LL);
sdl_render_text(&off_3D01497, 630LL, 290LL);
sdl_render_text("DISK", 630LL, 300LL);
sdl_render_text(&off_3D014A0, 630LL, 310LL);
sdl_render_text((char *)&off_3D014A0 + 4, 630LL, 320LL);
sdl_render_text(&off_3D014A8, 630LL, 330LL);
v4 = *((_DWORD *)&Cpu + 13);
if ( v4 >= *((_DWORD *)&Cpu + 14) )
{
v5 = 110;
do
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
utils_load(&Ram, &v7, v4, 32LL);
sprintf(s, (const char *)&off_3D014A8 + 4, v7);
sdl_render_text(s, 540LL, v5);
v4 -= 4;
v5 += 10;
}
while ( *((_DWORD *)&Cpu + 14) <= v4 );
}
return sdl_render_text("STACK", 540LL, 100LL);
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int *v0; // rbp
unsigned int i; // ebx
char *v2; // rbp
unsigned int j; // ebx
unsigned int v4; // ebx
unsigned int v5; // ebp
unsigned int v7; // [rsp+Ch] [rbp-3Ch] BYREF
char s[8]; // [rsp+10h] [rbp-38h] BYREF
__int64 v9; // [rsp+18h] [rbp-30h]
__int64 v10; // [rsp+20h] [rbp-28h]
__int64 v11; // [rsp+28h] [rbp-20h]

sdl_render_box(530LL, 90LL, 275LL, 260LL);
v0 = (unsigned int *)(unsigned int)((_DWORD)&Cpu + 4);
for ( i = 110; i != 270; i += 10 )
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", *v0);
sdl_render_text(s, 670LL, i);
++v0;
}
v2 = &Cpu;
for ( j = 280; j != 330; j += 10 )
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", *((unsigned int *)v2 + 17));
sdl_render_text(s, 670LL, j);
v2 += 4;
}
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
sprintf(s, "0x%x", (unsigned __int8)Cpu);
sdl_render_text(s, 670LL, 330LL);
sdl_render_text("REGISTERS", 630LL, 100LL);
sdl_render_text(&off_3D0146A, 630LL, 110LL);
sdl_render_text((char *)&off_3D0146A + 2, 630LL, 120LL);
sdl_render_text(&off_3D0146E, 630LL, 130LL);
sdl_render_text((char *)&off_3D0146E + 2, 630LL, 140LL);
sdl_render_text(&off_3D01472, 630LL, 150LL);
sdl_render_text((char *)&off_3D01472 + 2, 630LL, 160LL);
sdl_render_text(&off_3D01476, 630LL, 170LL);
sdl_render_text((char *)&off_3D01476 + 2, 630LL, 180LL);
sdl_render_text(&off_3D0147A, 630LL, 190LL);
sdl_render_text(&unk_3D0147E, 630LL, 200LL);
sdl_render_text(&unk_3D01481, 630LL, 210LL);
sdl_render_text(&off_3D01483, 630LL, 220LL);
sdl_render_text(&unk_3D01487, 630LL, 230LL);
sdl_render_text(&unk_3D0148A, 630LL, 240LL);
sdl_render_text(&unk_3D0148D, 630LL, 250LL);
sdl_render_text(&unk_3D01490, 630LL, 260LL);
sdl_render_text("DISP", 630LL, 280LL);
sdl_render_text(&off_3D01497, 630LL, 290LL);
sdl_render_text("DISK", 630LL, 300LL);
sdl_render_text(&off_3D014A0, 630LL, 310LL);
sdl_render_text((char *)&off_3D014A0 + 4, 630LL, 320LL);
sdl_render_text(&off_3D014A8, 630LL, 330LL);
v4 = *((_DWORD *)&Cpu + 13);
if ( v4 >= *((_DWORD *)&Cpu + 14) )
{
v5 = 110;
do
{
*(_QWORD *)s = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
utils_load(&Ram, &v7, v4, 32LL);
sprintf(s, (const char *)&off_3D014A8 + 4, v7);
sdl_render_text(s, 540LL, v5);
v4 -= 4;
v5 += 10;
}
while ( *((_DWORD *)&Cpu + 14) <= v4 );
}
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:
i
unsigned int

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:
result = clk_chk_tmr(&Clock, &Cpu, &Ram);
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:
result = clk_chk_tmr(&Clock, &Cpu, &Ram);
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; } *


repo: Toluk/os

decompiled_code:
__int64 __fastcall i_want_atoi(char *a1)
{
char v1; // al
char *v2; // rdi
unsigned int v3; // edx

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

canonical_decompiled_code:
__int64 __fastcall func7(char *a1)
{
char v1; // al
char *v2; // rdi
unsigned int v3; // edx

v1 = *a1;
if ( (unsigned __int8)(*a1 - 48) > 9u )
return 0;
v2 = a1 + 1;
v3 = 0;
do
{
v3 = v1 + 10 * v3 - 48;
v1 = *v2++;
}
while ( (unsigned __int8)(v1 - 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


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


readDirectory

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(__int64 a1)
{
_BYTE *v1; // rbx
_BYTE *v2; // rbx
__int16 *v3; // rbx
int result; // eax
unsigned __int8 *v5; // rbx
unsigned __int8 *v6; // rbp
unsigned __int8 v7; // di

if ( *(_BYTE *)(a1 + 11) == 15 )
{
printf("LFN:");
v5 = (unsigned __int8 *)(a1 + 1);
v6 = (unsigned __int8 *)(a1 + 32);
do
{
v7 = *v5;
if ( *v5 > 0x1Fu )
{
putchar(v7);
}
else if ( v7 )
{
printf("&%x;", v7);
}
++v5;
}
while ( v6 != v5 );
result = putchar(10);
}
else if ( *(_BYTE *)a1 )
{
v1 = (_BYTE *)a1;
do
{
if ( *v1 <= 0x1Fu )
break;
putchar((unsigned __int8)*v1++);
}
while ( v1 != (_BYTE *)(a1 + 8) );
v2 = (_BYTE *)(a1 + 8);
do
{
if ( *v2 <= 0x1Fu )
break;
putchar((unsigned __int8)*v2++);
}
while ( v2 != (_BYTE *)(a1 + 11) );
printf(" (%x)", *(unsigned __int8 *)(a1 + 11));
v3 = (__int16 *)(a1 + 12);
do
printf(" %hu", (unsigned int)*v3++);
while ( v3 != (__int16 *)(a1 + 22) );
result = printf(
" time: %hu date: %hu start: %hu length: %ld\n",
*(unsigned __int16 *)(a1 + 22),
*(unsigned __int16 *)(a1 + 24),
*(unsigned __int16 *)(a1 + 26),
((unsigned __int64)*(unsigned __int16 *)(a1 + 30) << 16) + *(unsigned __int16 *)(a1 + 28));
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
_BYTE *v1; // rbx
_BYTE *v2; // rbx
__int16 *v3; // rbx
int result; // eax
unsigned __int8 *v5; // rbx
unsigned __int8 *v6; // rbp
unsigned __int8 v7; // di

if ( *(_BYTE *)(a1 + 11) == 15 )
{
printf("LFN:");
v5 = (unsigned __int8 *)(a1 + 1);
v6 = (unsigned __int8 *)(a1 + 32);
do
{
v7 = *v5;
if ( *v5 > 0x1Fu )
{
putchar(v7);
}
else if ( v7 )
{
printf("&%x;", v7);
}
++v5;
}
while ( v6 != v5 );
result = putchar(10);
}
else if ( *(_BYTE *)a1 )
{
v1 = (_BYTE *)a1;
do
{
if ( *v1 <= 0x1Fu )
break;
putchar((unsigned __int8)*v1++);
}
while ( v1 != (_BYTE *)(a1 + 8) );
v2 = (_BYTE *)(a1 + 8);
do
{
if ( *v2 <= 0x1Fu )
break;
putchar((unsigned __int8)*v2++);
}
while ( v2 != (_BYTE *)(a1 + 11) );
printf(" (%x)", *(unsigned __int8 *)(a1 + 11));
v3 = (__int16 *)(a1 + 12);
do
printf(" %hu", (unsigned int)*v3++);
while ( v3 != (__int16 *)(a1 + 22) );
result = printf(
" time: %hu date: %hu start: %hu length: %ld\n",
*(unsigned __int16 *)(a1 + 22),
*(unsigned __int16 *)(a1 + 24),
*(unsigned __int16 *)(a1 + 26),
((unsigned __int64)*(unsigned __int16 *)(a1 + 30) << 16) + *(unsigned __int16 *)(a1 + 28));
}
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]; }