CpuExecuteOpcode

decompiled_code:
__int64 __fastcall CpuExecuteOpcode(__int64 a1, __int64 a2, int a3)
{
__int16 v3; // r15
int v4; // er12
int v7; // er14
unsigned int v8; // er13
__int16 v9; // ax
__int16 v10; // ax
char v11; // al
unsigned __int8 v12; // bp
unsigned __int8 v13; // al
unsigned __int8 v14; // bp
unsigned __int8 v15; // dl
__int16 v16; // ax
__int16 v17; // ax
char v18; // al
__int64 v19; // rsi
unsigned __int8 v20; // r15
unsigned int v21; // ebp
char v22; // al
unsigned __int8 v23; // bp
char v24; // dl
char v25; // al
char v26; // cl
char v27; // bp
char v28; // al
char v29; // cl
unsigned __int8 v30; // bp
char v31; // di
unsigned __int8 v32; // cl
unsigned __int8 v33; // di
__int64 v34; // rsi
char v35; // r14
char v36; // al
unsigned __int8 v37; // al
unsigned __int8 v38; // dl
char v39; // al
char v40; // al
char v41; // al
int v42; // eax
unsigned int v43; // ebp
__int16 v45; // ax
__int64 v46; // rsi
unsigned int v47; // ebp
int v48; // eax
unsigned __int16 v49; // bp
__int16 v50; // ax
__int16 v51; // dx
__int16 v52; // ax
char v53; // bp
char v54; // dl
char v55; // di
unsigned __int8 v56; // di
__int64 v57; // rsi
__int64 v58; // rsi
char v59; // al
char v60; // al
unsigned __int8 v61; // al
unsigned __int8 v62; // al
char v63; // bp
int v64; // eax
char v65; // dl
char v66; // bp
char v67; // al
char v68; // dl
char v69; // bp
char v70; // dl
unsigned __int8 v71; // al
char v72; // di
unsigned __int8 v73; // di
__int64 v74; // rsi
unsigned __int8 v75; // al
__int64 v76; // rsi
char v77; // bp
char v78; // al
char v79; // al
char v80; // bp
char v81; // dl
char v82; // al
char v83; // bp
char v84; // al
char v85; // al
unsigned __int8 v86; // al
unsigned int v87; // [rsp+8h] [rbp-40h]
unsigned __int8 v88; // [rsp+8h] [rbp-40h]
char v89; // [rsp+Fh] [rbp-39h]
char v90; // [rsp+Fh] [rbp-39h]
char v91; // [rsp+Fh] [rbp-39h]

v3 = *(unsigned __int8 *)(a1 + 3);
v4 = *(unsigned __int8 *)(a1 + 138);
if ( (a2 & 0xC000) != 0 )
{
v8 = -1;
puts("Invalid high bits in opcode");
return v8;
}
v7 = (__int16)a2;
v8 = a3 + 1;
v9 = a2 & 0x3000;
if ( (a2 & 0x3000) != 0 )
{
if ( v9 != 4096 )
{
if ( v9 == 0x2000 )
{
HIWORD(v42) = (unsigned int)(a3 + 1) >> 16;
LOWORD(v42) = v8 & 0x1800;
v43 = v42 | a2 & 0xFFFF07FF;
if ( (a2 & 0x800) == 0 )
{
v57 = (unsigned __int8)v8;
v8 = v43;
StkPush(a1 + 139, v57);
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
return v43;
}
if ( (a2 & 0xE00) == 3584 )
{
v49 = v3 & 0xFFFD;
HIBYTE(v50) = BYTE1(v4);
if ( (((a2 & 0xF) + (v4 & 0xF)) & 0x10) != 0 )
v49 = v3 | 2;
HIBYTE(v51) = BYTE1(a2);
LOBYTE(v50) = (unsigned __int8)v4 >> 4;
LOBYTE(v51) = (unsigned __int8)a2 >> 4;
v52 = v50 + v51 + ((v49 >> 1) & 1);
LOBYTE(v51) = v49;
v53 = v49 & 0xFE;
v54 = v51 | 1;
if ( (v52 & 0x10) != 0 )
v53 = v54;
a2 = (unsigned int)(v4 + a2);
*(_BYTE *)(a1 + 138) = a2;
v55 = v53;
v14 = v53 & 0xFB;
v56 = v55 | 4;
if ( !(_BYTE)a2 )
v14 = v56;
}
else
{
v16 = a2 & 0xF00;
if ( (a2 & 0xF00) == 2304 )
{
a2 = v4 & (unsigned int)a2;
v14 = v3 & 0xFB;
*(_BYTE *)(a1 + 138) = a2;
if ( !(_BYTE)a2 )
v14 = v3 | 4;
}
else
{
if ( v16 == 2048 )
{
a2 = v4 | (unsigned int)a2;
*(_BYTE *)(a1 + 138) = a2;
if ( (_BYTE)a2 )
{
v14 = v3 & 0xFB;
goto LABEL_15;
}
v14 = v3 | 4;
goto LABEL_106;
}
if ( v16 == 2560 )
{
v14 = v3 & 0xFB;
*(_BYTE *)(a1 + 138) = a2 ^ v4;
if ( (_BYTE)v4 == (_BYTE)a2 )
v14 = v3 | 4;
}
else
{
v17 = a2 & 0xC00;
if ( (a2 & 0xC00) == 0 )
{
*(_BYTE *)(a1 + 138) = a2;
v15 = a2;
goto LABEL_18;
}
if ( v17 == 1024 )
{
*(_BYTE *)(a1 + 138) = a2;
goto LABEL_117;
}
if ( v17 != 3072 )
{
v8 = -1;
puts("Invalid 11 opcode!");
return v8;
}
v79 = ((a2 & 0xF) - (v4 & 0xF)) & 0x10;
if ( v79 )
{
v80 = v3 & 0xFD;
v79 = 1;
}
else
{
v80 = v3 | 2;
}
v81 = ((unsigned __int8)a2 >> 4) - ((unsigned __int8)v4 >> 4) - v79;
v82 = v80;
v83 = v80 & 0xFE;
v84 = v82 | 1;
if ( (v81 & 0x10) == 0 )
v83 = v84;
a2 = (unsigned int)(a2 - v4);
*(_BYTE *)(a1 + 138) = a2;
v85 = v83;
v14 = v83 & 0xFB;
v86 = v85 | 4;
if ( !(_BYTE)a2 )
v14 = v86;
}
}
}
LABEL_15:
if ( v14 == (_BYTE)v3 )
{
LABEL_17:
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
LABEL_16:
printf("STATUS:[");
RegsPrintStatusRegister(*(unsigned __int8 *)(a1 + 3), a2);
printf("] -> [");
*(_BYTE *)(a1 + 3) = v14;
RegsPrintStatusRegister(v14, a2);
puts("]");
goto LABEL_17;
}
v45 = a2 & 0x3C00;
if ( (a2 & 0x3C00) == 6144 )
{
if ( ((unsigned __int8)(1 << (((__int16)a2 >> 7) & 7)) & (unsigned __int8)RegsGetValue(a1, a2 & 0x7F)) != 0 )
goto LABEL_17;
}
else
{
if ( ((unsigned __int16)a2 & 0x3C00u) <= 0x1800 )
{
if ( v45 == 4096 )
{
v58 = a2 & 0x7F;
v47 = v58;
v48 = RegsGetValue(a1, v58) & ~(1 << ((v7 >> 7) & 7));
goto LABEL_78;
}
if ( v45 == 5120 )
{
v46 = a2 & 0x7F;
v47 = v46;
v48 = (1 << ((v7 >> 7) & 7)) | RegsGetValue(a1, v46);
LABEL_78:
RegsSetValue(a1, v47, (unsigned __int8)v48);
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
LABEL_102:
v8 = -1;
puts("Invalid 01 opcode!");
return v8;
}
if ( v45 != 7168 )
goto LABEL_102;
if ( ((unsigned __int8)(1 << (((__int16)a2 >> 7) & 7)) & (unsigned __int8)RegsGetValue(a1, a2 & 0x7F)) == 0 )
goto LABEL_17;
}
v15 = *(_BYTE *)(a1 + 138);
v8 = a3 + 2;
goto LABEL_18;
}
v10 = a2 & 0xF00;
if ( (a2 & 0xF00) == 2048 )
{
a2 &= 0x7Fu;
v62 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v62;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x800 )
{
if ( v10 == 3072 )
{
v74 = a2 & 0x7F;
v35 = (unsigned __int8)v7 >> 7;
v87 = v74;
v14 = v3 & 0xFE;
v75 = RegsGetValue(a1, v74);
if ( (v75 & 1) != 0 )
v14 = v3 | 1;
v37 = v75 >> 1;
v38 = v37 | 0x80;
}
else
{
if ( ((unsigned __int16)a2 & 0xF00u) <= 0xC00 )
{
if ( v10 == 2560 )
{
a2 &= 0x7Fu;
v60 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v60 + 1;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( v10 != 2816 )
{
if ( v10 == 2304 )
{
a2 &= 0x7Fu;
v41 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = ~v41;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
goto LABEL_129;
}
v19 = a2 & 0x7F;
v39 = RegsGetValue(a1, v19);
v19 = (unsigned int)v19;
v20 = v39 - 1;
if ( (v7 & 0x80u) == 0 )
goto LABEL_33;
goto LABEL_63;
}
if ( v10 == 3584 )
{
v76 = a2 & 0x7F;
v77 = RegsGetValue(a1, v76);
v15 = (16 * v77) | ((unsigned __int8)RegsGetValue(a1, (unsigned int)v76) >> 4);
if ( (v7 & 0x80u) != 0 )
{
RegsSetValue(a1, (unsigned int)v76, v15);
v15 = *(_BYTE *)(a1 + 138);
}
else
{
*(_BYTE *)(a1 + 138) = v15;
}
goto LABEL_18;
}
if ( v10 == 3840 )
{
v19 = a2 & 0x7F;
v18 = RegsGetValue(a1, v19);
v19 = (unsigned int)v19;
v20 = v18 + 1;
if ( (v7 & 0x80u) == 0 )
{
LABEL_33:
*(_BYTE *)(a1 + 138) = v20;
v15 = v20;
goto LABEL_34;
}
LABEL_63:
RegsSetValue(a1, v19, v20);
v15 = *(_BYTE *)(a1 + 138);
LABEL_34:
v21 = a3 + 2;
if ( !v20 )
v8 = v21;
goto LABEL_18;
}
if ( v10 != 3328 )
goto LABEL_129;
v34 = a2 & 0x7F;
v35 = (unsigned __int8)v7 >> 7;
v87 = v34;
v14 = v3 & 0xFE;
v36 = RegsGetValue(a1, v34);
if ( v36 < 0 )
v14 = v3 | 1;
v37 = 2 * v36;
v38 = v37 | 1;
}
a2 = v87;
if ( (*(_BYTE *)(a1 + 3) & 1) != 0 )
v37 = v38;
if ( v35 )
RegsSetValue(a1, v87, v37);
else
*(_BYTE *)(a1 + 138) = v37;
goto LABEL_15;
}
if ( v10 == 1024 )
{
a2 &= 0x7Fu;
v78 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 | v78;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x400 )
{
if ( v10 == 1536 )
{
a2 &= 0x7Fu;
v59 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 ^ v59;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( v10 != 1792 )
{
if ( v10 == 1280 )
{
a2 &= 0x7Fu;
v40 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 & v40;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
LABEL_129:
v8 = -1;
puts("Invalid 00 opcode!");
return v8;
}
a2 &= 0x7Fu;
v22 = RegsGetValue(a1, a2);
v24 = v3 | 2;
if ( (((v22 & 0xF) + (v4 & 0xF)) & 0x10) == 0 )
v24 = v3 & 0xFD;
v89 = v24;
a2 = (unsigned int)a2;
v23 = *(_BYTE *)(a1 + 138);
v25 = (v23 >> 4) + ((char)RegsGetValue(a1, (unsigned int)a2) >> 4);
v26 = v89 | 1;
v27 = *(_BYTE *)(a1 + 138);
if ( ((v25 + ((v89 & 2) != 0)) & 0x10) == 0 )
v26 = v89 & 0xFE;
v90 = v26;
v28 = RegsGetValue(a1, (unsigned int)a2);
v29 = v90;
v30 = v28 + v27;
if ( (v7 & 0x80u) != 0 )
{
a2 = (unsigned int)a2;
RegsSetValue(a1, (unsigned int)a2, v30);
v29 = v90;
}
else
{
*(_BYTE *)(a1 + 138) = v30;
}
v31 = v29;
v32 = v29 & 0xFB;
v33 = v31 | 4;
if ( v30 )
v33 = v32;
v14 = v33;
goto LABEL_15;
}
if ( v10 == 512 )
{
a2 &= 0x7Fu;
v63 = *(_BYTE *)(a1 + 3);
v64 = ((RegsGetValue(a1, a2) & 0xF) - (*(_BYTE *)(a1 + 138) & 0xF)) & 0x10;
v65 = v64;
if ( v64 )
{
v66 = v63 & 0xFD;
v65 = 1;
}
else
{
v66 = v63 | 2;
}
v91 = v65;
v67 = RegsGetValue(a1, (unsigned int)a2);
a2 = (unsigned int)a2;
v68 = v66;
v69 = v66 & 0xFE;
v70 = v68 | 1;
if ( (((v67 >> 4) - ((*(_BYTE *)(a1 + 138) >> 4) + v91)) & 0x10) == 0 )
v69 = v70;
v71 = RegsGetValue(a1, (unsigned int)a2) - *(_BYTE *)(a1 + 138);
if ( (v7 & 0x80u) != 0 )
{
a2 = (unsigned int)a2;
v88 = v71;
RegsSetValue(a1, (unsigned int)a2, v71);
v71 = v88;
}
else
{
*(_BYTE *)(a1 + 138) = v71;
}
v72 = v69;
v14 = v69 & 0xFB;
v73 = v72 | 4;
if ( !v71 )
v14 = v73;
goto LABEL_15;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x200 )
{
if ( v10 == 768 )
{
a2 &= 0x7Fu;
v11 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v11 - 1;
if ( (v7 & 0x80u) == 0 )
{
LABEL_11:
*(_BYTE *)(a1 + 138) = v12;
LABEL_12:
v13 = v3 | 4;
if ( v12 )
v13 = v3 & 0xFB;
v14 = v13;
goto LABEL_15;
}
LABEL_66:
RegsSetValue(a1, a2, v12);
goto LABEL_12;
}
goto LABEL_129;
}
if ( v10 )
{
if ( v10 == 256 )
{
v14 = v3 | 4;
if ( (a2 & 0x80u) != 0LL )
{
a2 &= 0x7Fu;
RegsSetValue(a1, a2, 0LL);
}
else
{
*(_BYTE *)(a1 + 138) = 0;
}
goto LABEL_15;
}
goto LABEL_129;
}
if ( (a2 & 0x80u) == 0LL )
{
if ( (a2 & 0xF) != 0 )
{
a2 = (unsigned __int8)a2;
if ( (unsigned __int8)a2 == 99 )
{
v14 = v3 & 0xF7 | 0x10;
}
else
{
if ( (unsigned __int8)a2 <= 0x63u )
{
if ( (unsigned __int16)(a2 - 8) <= 1u )
{
LABEL_117:
v61 = StkPop(a1 + 139);
v15 = *(_BYTE *)(a1 + 138);
v8 = v61;
goto LABEL_18;
}
LABEL_157:
v8 = -1;
puts("Invalid 00 0000 opcode!");
return v8;
}
if ( (_WORD)a2 != 100 )
goto LABEL_157;
v14 = v3 | 0x18;
}
LABEL_106:
if ( (_BYTE)v3 == v14 )
return v8;
goto LABEL_16;
}
return (unsigned int)(a3 + 1);
}
RegsSetValue(a1, a2 & 0x7F, (unsigned __int8)v4);
v15 = *(_BYTE *)(a1 + 138);
LABEL_18:
if ( (_BYTE)v4 != v15 )
printf("W: %d -> %d\n", (unsigned __int8)v4, v15);
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, int a3)
{
__int16 v3; // r15
int v4; // er12
int v7; // er14
unsigned int v8; // er13
__int16 v9; // ax
__int16 v10; // ax
char v11; // al
unsigned __int8 v12; // bp
unsigned __int8 v13; // al
unsigned __int8 v14; // bp
unsigned __int8 v15; // dl
__int16 v16; // ax
__int16 v17; // ax
char v18; // al
__int64 v19; // rsi
unsigned __int8 v20; // r15
unsigned int v21; // ebp
char v22; // al
unsigned __int8 v23; // bp
char v24; // dl
char v25; // al
char v26; // cl
char v27; // bp
char v28; // al
char v29; // cl
unsigned __int8 v30; // bp
char v31; // di
unsigned __int8 v32; // cl
unsigned __int8 v33; // di
__int64 v34; // rsi
char v35; // r14
char v36; // al
unsigned __int8 v37; // al
unsigned __int8 v38; // dl
char v39; // al
char v40; // al
char v41; // al
int v42; // eax
unsigned int v43; // ebp
__int16 v45; // ax
__int64 v46; // rsi
unsigned int v47; // ebp
int v48; // eax
unsigned __int16 v49; // bp
__int16 v50; // ax
__int16 v51; // dx
__int16 v52; // ax
char v53; // bp
char v54; // dl
char v55; // di
unsigned __int8 v56; // di
__int64 v57; // rsi
__int64 v58; // rsi
char v59; // al
char v60; // al
unsigned __int8 v61; // al
unsigned __int8 v62; // al
char v63; // bp
int v64; // eax
char v65; // dl
char v66; // bp
char v67; // al
char v68; // dl
char v69; // bp
char v70; // dl
unsigned __int8 v71; // al
char v72; // di
unsigned __int8 v73; // di
__int64 v74; // rsi
unsigned __int8 v75; // al
__int64 v76; // rsi
char v77; // bp
char v78; // al
char v79; // al
char v80; // bp
char v81; // dl
char v82; // al
char v83; // bp
char v84; // al
char v85; // al
unsigned __int8 v86; // al
unsigned int v87; // [rsp+8h] [rbp-40h]
unsigned __int8 v88; // [rsp+8h] [rbp-40h]
char v89; // [rsp+Fh] [rbp-39h]
char v90; // [rsp+Fh] [rbp-39h]
char v91; // [rsp+Fh] [rbp-39h]

v3 = *(unsigned __int8 *)(a1 + 3);
v4 = *(unsigned __int8 *)(a1 + 138);
if ( (a2 & 0xC000) != 0 )
{
v8 = -1;
puts("Invalid high bits in opcode");
return v8;
}
v7 = (__int16)a2;
v8 = a3 + 1;
v9 = a2 & 0x3000;
if ( (a2 & 0x3000) != 0 )
{
if ( v9 != 4096 )
{
if ( v9 == 0x2000 )
{
HIWORD(v42) = (unsigned int)(a3 + 1) >> 16;
LOWORD(v42) = v8 & 0x1800;
v43 = v42 | a2 & 0xFFFF07FF;
if ( (a2 & 0x800) == 0 )
{
v57 = (unsigned __int8)v8;
v8 = v43;
StkPush(a1 + 139, v57);
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
return v43;
}
if ( (a2 & 0xE00) == 3584 )
{
v49 = v3 & 0xFFFD;
HIBYTE(v50) = BYTE1(v4);
if ( (((a2 & 0xF) + (v4 & 0xF)) & 0x10) != 0 )
v49 = v3 | 2;
HIBYTE(v51) = BYTE1(a2);
LOBYTE(v50) = (unsigned __int8)v4 >> 4;
LOBYTE(v51) = (unsigned __int8)a2 >> 4;
v52 = v50 + v51 + ((v49 >> 1) & 1);
LOBYTE(v51) = v49;
v53 = v49 & 0xFE;
v54 = v51 | 1;
if ( (v52 & 0x10) != 0 )
v53 = v54;
a2 = (unsigned int)(v4 + a2);
*(_BYTE *)(a1 + 138) = a2;
v55 = v53;
v14 = v53 & 0xFB;
v56 = v55 | 4;
if ( !(_BYTE)a2 )
v14 = v56;
}
else
{
v16 = a2 & 0xF00;
if ( (a2 & 0xF00) == 2304 )
{
a2 = v4 & (unsigned int)a2;
v14 = v3 & 0xFB;
*(_BYTE *)(a1 + 138) = a2;
if ( !(_BYTE)a2 )
v14 = v3 | 4;
}
else
{
if ( v16 == 2048 )
{
a2 = v4 | (unsigned int)a2;
*(_BYTE *)(a1 + 138) = a2;
if ( (_BYTE)a2 )
{
v14 = v3 & 0xFB;
goto LABEL_15;
}
v14 = v3 | 4;
goto LABEL_106;
}
if ( v16 == 2560 )
{
v14 = v3 & 0xFB;
*(_BYTE *)(a1 + 138) = a2 ^ v4;
if ( (_BYTE)v4 == (_BYTE)a2 )
v14 = v3 | 4;
}
else
{
v17 = a2 & 0xC00;
if ( (a2 & 0xC00) == 0 )
{
*(_BYTE *)(a1 + 138) = a2;
v15 = a2;
goto LABEL_18;
}
if ( v17 == 1024 )
{
*(_BYTE *)(a1 + 138) = a2;
goto LABEL_117;
}
if ( v17 != 3072 )
{
v8 = -1;
puts("Invalid 11 opcode!");
return v8;
}
v79 = ((a2 & 0xF) - (v4 & 0xF)) & 0x10;
if ( v79 )
{
v80 = v3 & 0xFD;
v79 = 1;
}
else
{
v80 = v3 | 2;
}
v81 = ((unsigned __int8)a2 >> 4) - ((unsigned __int8)v4 >> 4) - v79;
v82 = v80;
v83 = v80 & 0xFE;
v84 = v82 | 1;
if ( (v81 & 0x10) == 0 )
v83 = v84;
a2 = (unsigned int)(a2 - v4);
*(_BYTE *)(a1 + 138) = a2;
v85 = v83;
v14 = v83 & 0xFB;
v86 = v85 | 4;
if ( !(_BYTE)a2 )
v14 = v86;
}
}
}
LABEL_15:
if ( v14 == (_BYTE)v3 )
{
LABEL_17:
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
LABEL_16:
printf("STATUS:[");
RegsPrintStatusRegister(*(unsigned __int8 *)(a1 + 3), a2);
printf("] -> [");
*(_BYTE *)(a1 + 3) = v14;
RegsPrintStatusRegister(v14, a2);
puts("]");
goto LABEL_17;
}
v45 = a2 & 0x3C00;
if ( (a2 & 0x3C00) == 6144 )
{
if ( ((unsigned __int8)(1 << (((__int16)a2 >> 7) & 7)) & (unsigned __int8)RegsGetValue(a1, a2 & 0x7F)) != 0 )
goto LABEL_17;
}
else
{
if ( ((unsigned __int16)a2 & 0x3C00u) <= 0x1800 )
{
if ( v45 == 4096 )
{
v58 = a2 & 0x7F;
v47 = v58;
v48 = RegsGetValue(a1, v58) & ~(1 << ((v7 >> 7) & 7));
goto LABEL_78;
}
if ( v45 == 5120 )
{
v46 = a2 & 0x7F;
v47 = v46;
v48 = (1 << ((v7 >> 7) & 7)) | RegsGetValue(a1, v46);
LABEL_78:
RegsSetValue(a1, v47, (unsigned __int8)v48);
v15 = *(_BYTE *)(a1 + 138);
goto LABEL_18;
}
LABEL_102:
v8 = -1;
puts("Invalid 01 opcode!");
return v8;
}
if ( v45 != 7168 )
goto LABEL_102;
if ( ((unsigned __int8)(1 << (((__int16)a2 >> 7) & 7)) & (unsigned __int8)RegsGetValue(a1, a2 & 0x7F)) == 0 )
goto LABEL_17;
}
v15 = *(_BYTE *)(a1 + 138);
v8 = a3 + 2;
goto LABEL_18;
}
v10 = a2 & 0xF00;
if ( (a2 & 0xF00) == 2048 )
{
a2 &= 0x7Fu;
v62 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v62;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x800 )
{
if ( v10 == 3072 )
{
v74 = a2 & 0x7F;
v35 = (unsigned __int8)v7 >> 7;
v87 = v74;
v14 = v3 & 0xFE;
v75 = RegsGetValue(a1, v74);
if ( (v75 & 1) != 0 )
v14 = v3 | 1;
v37 = v75 >> 1;
v38 = v37 | 0x80;
}
else
{
if ( ((unsigned __int16)a2 & 0xF00u) <= 0xC00 )
{
if ( v10 == 2560 )
{
a2 &= 0x7Fu;
v60 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v60 + 1;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( v10 != 2816 )
{
if ( v10 == 2304 )
{
a2 &= 0x7Fu;
v41 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = ~v41;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
goto LABEL_129;
}
v19 = a2 & 0x7F;
v39 = RegsGetValue(a1, v19);
v19 = (unsigned int)v19;
v20 = v39 - 1;
if ( (v7 & 0x80u) == 0 )
goto LABEL_33;
goto LABEL_63;
}
if ( v10 == 3584 )
{
v76 = a2 & 0x7F;
v77 = RegsGetValue(a1, v76);
v15 = (16 * v77) | ((unsigned __int8)RegsGetValue(a1, (unsigned int)v76) >> 4);
if ( (v7 & 0x80u) != 0 )
{
RegsSetValue(a1, (unsigned int)v76, v15);
v15 = *(_BYTE *)(a1 + 138);
}
else
{
*(_BYTE *)(a1 + 138) = v15;
}
goto LABEL_18;
}
if ( v10 == 3840 )
{
v19 = a2 & 0x7F;
v18 = RegsGetValue(a1, v19);
v19 = (unsigned int)v19;
v20 = v18 + 1;
if ( (v7 & 0x80u) == 0 )
{
LABEL_33:
*(_BYTE *)(a1 + 138) = v20;
v15 = v20;
goto LABEL_34;
}
LABEL_63:
RegsSetValue(a1, v19, v20);
v15 = *(_BYTE *)(a1 + 138);
LABEL_34:
v21 = a3 + 2;
if ( !v20 )
v8 = v21;
goto LABEL_18;
}
if ( v10 != 3328 )
goto LABEL_129;
v34 = a2 & 0x7F;
v35 = (unsigned __int8)v7 >> 7;
v87 = v34;
v14 = v3 & 0xFE;
v36 = RegsGetValue(a1, v34);
if ( v36 < 0 )
v14 = v3 | 1;
v37 = 2 * v36;
v38 = v37 | 1;
}
a2 = v87;
if ( (*(_BYTE *)(a1 + 3) & 1) != 0 )
v37 = v38;
if ( v35 )
RegsSetValue(a1, v87, v37);
else
*(_BYTE *)(a1 + 138) = v37;
goto LABEL_15;
}
if ( v10 == 1024 )
{
a2 &= 0x7Fu;
v78 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 | v78;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x400 )
{
if ( v10 == 1536 )
{
a2 &= 0x7Fu;
v59 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 ^ v59;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
if ( v10 != 1792 )
{
if ( v10 == 1280 )
{
a2 &= 0x7Fu;
v40 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v4 & v40;
if ( (v7 & 0x80u) == 0 )
goto LABEL_11;
goto LABEL_66;
}
LABEL_129:
v8 = -1;
puts("Invalid 00 opcode!");
return v8;
}
a2 &= 0x7Fu;
v22 = RegsGetValue(a1, a2);
v24 = v3 | 2;
if ( (((v22 & 0xF) + (v4 & 0xF)) & 0x10) == 0 )
v24 = v3 & 0xFD;
v89 = v24;
a2 = (unsigned int)a2;
v23 = *(_BYTE *)(a1 + 138);
v25 = (v23 >> 4) + ((char)RegsGetValue(a1, (unsigned int)a2) >> 4);
v26 = v89 | 1;
v27 = *(_BYTE *)(a1 + 138);
if ( ((v25 + ((v89 & 2) != 0)) & 0x10) == 0 )
v26 = v89 & 0xFE;
v90 = v26;
v28 = RegsGetValue(a1, (unsigned int)a2);
v29 = v90;
v30 = v28 + v27;
if ( (v7 & 0x80u) != 0 )
{
a2 = (unsigned int)a2;
RegsSetValue(a1, (unsigned int)a2, v30);
v29 = v90;
}
else
{
*(_BYTE *)(a1 + 138) = v30;
}
v31 = v29;
v32 = v29 & 0xFB;
v33 = v31 | 4;
if ( v30 )
v33 = v32;
v14 = v33;
goto LABEL_15;
}
if ( v10 == 512 )
{
a2 &= 0x7Fu;
v63 = *(_BYTE *)(a1 + 3);
v64 = ((RegsGetValue(a1, a2) & 0xF) - (*(_BYTE *)(a1 + 138) & 0xF)) & 0x10;
v65 = v64;
if ( v64 )
{
v66 = v63 & 0xFD;
v65 = 1;
}
else
{
v66 = v63 | 2;
}
v91 = v65;
v67 = RegsGetValue(a1, (unsigned int)a2);
a2 = (unsigned int)a2;
v68 = v66;
v69 = v66 & 0xFE;
v70 = v68 | 1;
if ( (((v67 >> 4) - ((*(_BYTE *)(a1 + 138) >> 4) + v91)) & 0x10) == 0 )
v69 = v70;
v71 = RegsGetValue(a1, (unsigned int)a2) - *(_BYTE *)(a1 + 138);
if ( (v7 & 0x80u) != 0 )
{
a2 = (unsigned int)a2;
v88 = v71;
RegsSetValue(a1, (unsigned int)a2, v71);
v71 = v88;
}
else
{
*(_BYTE *)(a1 + 138) = v71;
}
v72 = v69;
v14 = v69 & 0xFB;
v73 = v72 | 4;
if ( !v71 )
v14 = v73;
goto LABEL_15;
}
if ( ((unsigned __int16)a2 & 0xF00u) > 0x200 )
{
if ( v10 == 768 )
{
a2 &= 0x7Fu;
v11 = RegsGetValue(a1, a2);
a2 = (unsigned int)a2;
v12 = v11 - 1;
if ( (v7 & 0x80u) == 0 )
{
LABEL_11:
*(_BYTE *)(a1 + 138) = v12;
LABEL_12:
v13 = v3 | 4;
if ( v12 )
v13 = v3 & 0xFB;
v14 = v13;
goto LABEL_15;
}
LABEL_66:
RegsSetValue(a1, a2, v12);
goto LABEL_12;
}
goto LABEL_129;
}
if ( v10 )
{
if ( v10 == 256 )
{
v14 = v3 | 4;
if ( (a2 & 0x80u) != 0LL )
{
a2 &= 0x7Fu;
RegsSetValue(a1, a2, 0LL);
}
else
{
*(_BYTE *)(a1 + 138) = 0;
}
goto LABEL_15;
}
goto LABEL_129;
}
if ( (a2 & 0x80u) == 0LL )
{
if ( (a2 & 0xF) != 0 )
{
a2 = (unsigned __int8)a2;
if ( (unsigned __int8)a2 == 99 )
{
v14 = v3 & 0xF7 | 0x10;
}
else
{
if ( (unsigned __int8)a2 <= 0x63u )
{
if ( (unsigned __int16)(a2 - 8) <= 1u )
{
LABEL_117:
v61 = StkPop(a1 + 139);
v15 = *(_BYTE *)(a1 + 138);
v8 = v61;
goto LABEL_18;
}
LABEL_157:
v8 = -1;
puts("Invalid 00 0000 opcode!");
return v8;
}
if ( (_WORD)a2 != 100 )
goto LABEL_157;
v14 = v3 | 0x18;
}
LABEL_106:
if ( (_BYTE)v3 == v14 )
return v8;
goto LABEL_16;
}
return (unsigned int)(a3 + 1);
}
RegsSetValue(a1, a2 & 0x7F, (unsigned __int8)v4);
v15 = *(_BYTE *)(a1 + 138);
LABEL_18:
if ( (_BYTE)v4 != v15 )
printf("W: %d -> %d\n", (unsigned __int8)v4, v15);
return v8;
}

original_code:
unsigned short CpuExecuteOpcode(PIC_CPU *Cpu, short opcode, unsigned short PC)
{
    unsigned char result;
    unsigned char op1, op2;
    unsigned char status = Cpu->Regs.STATUS;
    unsigned char oldW = Cpu->W;
    unsigned char oldStatus = status;
    if ((opcode & 0xC000) != 0)
    {
        printf("Invalid high bits in opcode\n");
        return 0xFFFF;
    }
    PC ++;
    if ((opcode & 0x3000) == 0x0000)
    {
        switch (opcode & 0xF00)
        {
            case 0x700:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (Cpu->W & 0x0F) + (RegsGetValue(&Cpu->Regs, op1) & 0x0F);
                if ((result & 0x10) != 0)
                    status |= (1 << 1);
                else
                    status &= ~(1 << 1);
                result = (Cpu->W >> 4) + (RegsGetValue(&Cpu->Regs, op1) >> 4);
                result += (status & (1 << 1)) ? 1 : 0;
                if ((result & 0x10) != 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = Cpu->W + RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x500:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W & RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x100:
                if ((opcode & 0x80) != 0)
                {
                    op1 = (opcode & 0x7F);
                    RegsSetValue(&Cpu->Regs, op1, 0);
                    status |= (1 << 2);
                }
                else
                {
                    Cpu->W = 0;
                    status |= (1 << 2);
                }
                break;
            case 0x900:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = ~ RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x300:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) - 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xB00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) - 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    PC ++;
                break;
            case 0xA00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) + 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xF00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) + 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    PC ++;
                break;
            case 0x400:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W | RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x800:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x000:
                if ((opcode & 0x80) != 0)
                {
                    op1 = (opcode & 0x7F);
                    RegsSetValue(&Cpu->Regs, op1, Cpu->W);
                }
                else if ((opcode & 0xF) == 0)
                {
                }
                else
                {
                    switch (opcode & 0xFF)
                    {
                        case 0x64:
                            status |= ((1 << 3) | (1 << 4));
                            break;
                        case 0x09:
                            PC = StkPop(&Cpu->Stack);
                            break;
                        case 0x08:
                            PC = StkPop(&Cpu->Stack);
                            break;
                        case 0x63:
                            status |= (1 << 4);
                            status &= ~(1 << 3);
                            break;
                        default:
                            printf("Invalid 00 0000 opcode!\n");
                            return 0xFFFF;
                    }
                }
                break;
            case 0xD00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if ((result & 0x80) != 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = result << 1;
                if ((Cpu->Regs.STATUS & (1 << 0)) != 0)
                    result |= 0x01;
                else
                    result &= ~0x01;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0xC00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if (result & 0x01)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = result >> 1;
                if ((Cpu->Regs.STATUS & (1 << 0)) != 0)
                    result |= 0x80;
                else
                    result &= ~0x80;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x200:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (RegsGetValue(&Cpu->Regs, op1) & 0x0F) - (Cpu->W & 0x0F);
                if ((result & 0x10) == 0)
                    status |= (1 << 1);
                else
                    status &= ~(1 << 1);
                result = RegsGetValue(&Cpu->Regs, op1) >> 4;
                result -= (status & (1 << 1)) ? 0 : 1;
                result -= Cpu->W >> 4;
                if ((result & 0x10) == 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = RegsGetValue(&Cpu->Regs, op1) - Cpu->W;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xE00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (RegsGetValue(&Cpu->Regs, op1) << 4) & 0xF0;
                result |= (RegsGetValue(&Cpu->Regs, op1) >> 4) & 0x0F;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x600:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W ^ RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            default:
                printf("Invalid 00 opcode!\n");
                return 0xFFFF;
        }
    }
    else if ((opcode & 0x3000) == 0x1000)
    {
        switch (opcode & 0x3C00)
        {
            case 0x1000:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & ~(1 << op2);
                RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x1400:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) | (1 << op2);
                RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x1800:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & (1 << op2);
                if (result == 0)
                    PC ++;
                break;
            case 0x1C00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & (1 << op2);
                if (result != 0)
                    PC ++;
                break;
            default:
                printf("Invalid 01 opcode!\n");
                return 0xFFFF;
        }
    }
    else if ((opcode & 0x3000) == 0x2000)
    {
        if ((opcode & 0x800) != 0)
        {
            PC = PC & 0x1800;
            PC |= (opcode & 0x7FF);
        }
        else
        {
            StkPush(&Cpu->Stack, PC);
            PC = PC & 0x1800;
            PC |= (opcode & 0x7FF);
        }
    }
    else
    {
        if ((opcode & 0xE00) == 0xE00)
        {
            op1 = (opcode & 0xFF);
            result = (Cpu->W & 0x0F) + (op1 & 0x0F);
            if ((result & 0x10) != 0)
                status |= (1 << 1);
            else
                status &= ~(1 << 1);
            result = (Cpu->W >> 4) + (op1 >> 4);
            result += (status & (1 << 1)) ? 1 : 0;
            if ((result & 0x10) != 0)
                status |= (1 << 0);
            else
                status &= ~(1 << 0);
            result = Cpu->W + op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0x900)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W & op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0x800)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W | op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0xA00)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W ^ op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xC00) == 0x000)
        {
            op1 = (opcode & 0xFF);
            result = op1;
            Cpu->W = result;
        }
        else if ((opcode & 0xC00) == 0x400)
        {
            op1 = (opcode & 0xFF);
            Cpu->W = op1;
            PC = StkPop(&Cpu->Stack);
        }
        else if ((opcode & 0xC00) == 0xC00)
        {
            op1 = (opcode & 0xFF);
            result = (op1 & 0x0F) - (Cpu->W & 0x0F);
            if ((result & 0x10) == 0)
                status |= (1 << 1);
            else
                status &= ~(1 << 1);
            result = op1 >> 4;
            result -= (status & (1 << 1)) ? 0 : 1;
            result -= Cpu->W >> 4;
            if ((result & 0x10) == 0)
                status |= (1 << 0);
            else
                status &= ~(1 << 0);
            result = op1 - Cpu->W;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else
        {
            printf("Invalid 11 opcode!\n");
            return 0xFFFF;
        }
    }
    if (status != oldStatus)
    {
        printf("STATUS:[");
        RegsPrintStatusRegister(Cpu->Regs.STATUS);
        printf("] -> [");
        Cpu->Regs.STATUS = status;
        RegsPrintStatusRegister(Cpu->Regs.STATUS);
        printf("]\n");
    }
    if (oldW != Cpu->W)
    {
        printf("W: %d -> %d\n", oldW, Cpu->W);
    }
    return PC;
}

canonical_original_code:
unsigned short CpuExecuteOpcode(struct _PIC_CPU *Cpu, short opcode, unsigned short PC)
{
    unsigned char result;
    unsigned char op1; unsigned char op2;
    unsigned char status = Cpu->Regs.STATUS;
    unsigned char oldW = Cpu->W;
    unsigned char oldStatus = status;
    if ((opcode & 0xC000) != 0)
    {
        printf("Invalid high bits in opcode\n");
        return 0xFFFF;
    }
    PC ++;
    if ((opcode & 0x3000) == 0x0000)
    {
        switch (opcode & 0xF00)
        {
            case 0x700:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (Cpu->W & 0x0F) + (RegsGetValue(&Cpu->Regs, op1) & 0x0F);
                if ((result & 0x10) != 0)
                    status |= (1 << 1);
                else
                    status &= ~(1 << 1);
                result = (Cpu->W >> 4) + (RegsGetValue(&Cpu->Regs, op1) >> 4);
                result += (status & (1 << 1)) ? 1 : 0;
                if ((result & 0x10) != 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = Cpu->W + RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x500:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W & RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x100:
                if ((opcode & 0x80) != 0)
                {
                    op1 = (opcode & 0x7F);
                    RegsSetValue(&Cpu->Regs, op1, 0);
                    status |= (1 << 2);
                }
                else
                {
                    Cpu->W = 0;
                    status |= (1 << 2);
                }
                break;
            case 0x900:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = ~ RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x300:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) - 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xB00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) - 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    PC ++;
                break;
            case 0xA00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) + 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xF00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) + 1;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    PC ++;
                break;
            case 0x400:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W | RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x800:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0x000:
                if ((opcode & 0x80) != 0)
                {
                    op1 = (opcode & 0x7F);
                    RegsSetValue(&Cpu->Regs, op1, Cpu->W);
                }
                else if ((opcode & 0xF) == 0)
                {
                }
                else
                {
                    switch (opcode & 0xFF)
                    {
                        case 0x64:
                            status |= ((1 << 3) | (1 << 4));
                            break;
                        case 0x09:
                            PC = StkPop(&Cpu->Stack);
                            break;
                        case 0x08:
                            PC = StkPop(&Cpu->Stack);
                            break;
                        case 0x63:
                            status |= (1 << 4);
                            status &= ~(1 << 3);
                            break;
                        default:
                            printf("Invalid 00 0000 opcode!\n");
                            return 0xFFFF;
                    }
                }
                break;
            case 0xD00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if ((result & 0x80) != 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = result << 1;
                if ((Cpu->Regs.STATUS & (1 << 0)) != 0)
                    result |= 0x01;
                else
                    result &= ~0x01;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0xC00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1);
                if (result & 0x01)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = result >> 1;
                if ((Cpu->Regs.STATUS & (1 << 0)) != 0)
                    result |= 0x80;
                else
                    result &= ~0x80;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x200:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (RegsGetValue(&Cpu->Regs, op1) & 0x0F) - (Cpu->W & 0x0F);
                if ((result & 0x10) == 0)
                    status |= (1 << 1);
                else
                    status &= ~(1 << 1);
                result = RegsGetValue(&Cpu->Regs, op1) >> 4;
                result -= (status & (1 << 1)) ? 0 : 1;
                result -= Cpu->W >> 4;
                if ((result & 0x10) == 0)
                    status |= (1 << 0);
                else
                    status &= ~(1 << 0);
                result = RegsGetValue(&Cpu->Regs, op1) - Cpu->W;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            case 0xE00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = (RegsGetValue(&Cpu->Regs, op1) << 4) & 0xF0;
                result |= (RegsGetValue(&Cpu->Regs, op1) >> 4) & 0x0F;
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x600:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x80) >> 7;
                result = Cpu->W ^ RegsGetValue(&Cpu->Regs, op1);
                if (op2 == 0)
                    Cpu->W = result;
                else
                    RegsSetValue(&Cpu->Regs, op1, result);
                if (result == 0)
                    status |= (1 << 2);
                else
                    status &= ~(1 << 2);
                break;
            default:
                printf("Invalid 00 opcode!\n");
                return 0xFFFF;
        }
    }
    else if ((opcode & 0x3000) == 0x1000)
    {
        switch (opcode & 0x3C00)
        {
            case 0x1000:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & ~(1 << op2);
                RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x1400:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) | (1 << op2);
                RegsSetValue(&Cpu->Regs, op1, result);
                break;
            case 0x1800:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & (1 << op2);
                if (result == 0)
                    PC ++;
                break;
            case 0x1C00:
                op1 = (opcode & 0x7F);
                op2 = (opcode & 0x380) >> 7;
                result = RegsGetValue(&Cpu->Regs, op1) & (1 << op2);
                if (result != 0)
                    PC ++;
                break;
            default:
                printf("Invalid 01 opcode!\n");
                return 0xFFFF;
        }
    }
    else if ((opcode & 0x3000) == 0x2000)
    {
        if ((opcode & 0x800) != 0)
        {
            PC = PC & 0x1800;
            PC |= (opcode & 0x7FF);
        }
        else
        {
            StkPush(&Cpu->Stack, PC);
            PC = PC & 0x1800;
            PC |= (opcode & 0x7FF);
        }
    }
    else
    {
        if ((opcode & 0xE00) == 0xE00)
        {
            op1 = (opcode & 0xFF);
            result = (Cpu->W & 0x0F) + (op1 & 0x0F);
            if ((result & 0x10) != 0)
                status |= (1 << 1);
            else
                status &= ~(1 << 1);
            result = (Cpu->W >> 4) + (op1 >> 4);
            result += (status & (1 << 1)) ? 1 : 0;
            if ((result & 0x10) != 0)
                status |= (1 << 0);
            else
                status &= ~(1 << 0);
            result = Cpu->W + op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0x900)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W & op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0x800)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W | op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xF00) == 0xA00)
        {
            op1 = (opcode & 0xFF);
            result = Cpu->W ^ op1;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else if ((opcode & 0xC00) == 0x000)
        {
            op1 = (opcode & 0xFF);
            result = op1;
            Cpu->W = result;
        }
        else if ((opcode & 0xC00) == 0x400)
        {
            op1 = (opcode & 0xFF);
            Cpu->W = op1;
            PC = StkPop(&Cpu->Stack);
        }
        else if ((opcode & 0xC00) == 0xC00)
        {
            op1 = (opcode & 0xFF);
            result = (op1 & 0x0F) - (Cpu->W & 0x0F);
            if ((result & 0x10) == 0)
                status |= (1 << 1);
            else
                status &= ~(1 << 1);
            result = op1 >> 4;
            result -= (status & (1 << 1)) ? 0 : 1;
            result -= Cpu->W >> 4;
            if ((result & 0x10) == 0)
                status |= (1 << 0);
            else
                status &= ~(1 << 0);
            result = op1 - Cpu->W;
            Cpu->W = result;
            if (result == 0)
                status |= (1 << 2);
            else
                status &= ~(1 << 2);
        }
        else
        {
            printf("Invalid 11 opcode!\n");
            return 0xFFFF;
        }
    }
    if (status != oldStatus)
    {
        printf("STATUS:[");
        RegsPrintStatusRegister(Cpu->Regs.STATUS);
        printf("] -> [");
        Cpu->Regs.STATUS = status;
        RegsPrintStatusRegister(Cpu->Regs.STATUS);
        printf("]\n");
    }
    if (oldW != Cpu->W)
    {
        printf("W: %d -> %d\n", oldW, Cpu->W);
    }
    return PC;
}

variable_types: opcode short

variable_types:
result
unsigned char

variable_types:
status
unsigned char

variable_types:
oldW
unsigned char

variable_types:
oldStatus
unsigned char


CpuExec

repo: cgutman/PIC-EMULATOR

decompiled_code:
void __fastcall CpuExec(__int64 a1)
{
__int16 v1; // ax
__int16 v2; // ax
int v3; // edx
unsigned __int16 v4; // ax
char v5; // r12

v1 = CpuGetPC(a1);
v2 = CpuGetOpcode(a1, v1);
v4 = CpuExecuteOpcode(a1, (unsigned int)v2, v3);
if ( v4 == 0xFFFF )
{
puts("Opcode unsupported");
}
else if ( (*(_BYTE *)(a1 + 3) & 8) != 0 )
{
v5 = v4;
printf("PC -> 0x%x\n", v4);
CpuSetPC(a1, v5);
}
else
{
puts("CPU is halted");
}
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1)
{
__int16 v1; // ax
__int16 v2; // ax
int v3; // edx
unsigned __int16 v4; // ax
char v5; // r12

v1 = func2(a1);
v2 = func4(a1, v1);
v4 = func6(a1, (unsigned int)v2, v3);
if ( v4 == 0xFFFF )
{
puts("Opcode unsupported");
}
else if ( (*(_BYTE *)(a1 + 3) & 8) != 0 )
{
v5 = v4;
printf("PC -> 0x%x\n", v4);
func3(a1, v5);
}
else
{
puts("CPU is halted");
}
}

original_code:
int CpuExec(PIC_CPU *Cpu)
{
    unsigned short PC;
    PC = CpuGetPC(Cpu);
    PC = CpuExecuteOpcode(Cpu, CpuGetOpcode(Cpu, PC), PC);
    if (PC == 0xFFFF)
    {
        printf("Opcode unsupported\n");
        return -1;
    }
    if (!(Cpu->Regs.STATUS & (1 << 3)))
    {
        printf("CPU is halted\n");
        return -1;
    }
    printf("PC -> 0x%x\n", PC);
    CpuSetPC(Cpu, PC);
    return 0;
}

canonical_original_code:
int CpuExec(struct _PIC_CPU *Cpu)
{
    unsigned short PC;
    PC = CpuGetPC(Cpu);
    PC = CpuExecuteOpcode(Cpu, CpuGetOpcode(Cpu, PC), PC);
    if (PC == 0xFFFF)
    {
        printf("Opcode unsupported\n");
        return -1;
    }
    if (!(Cpu->Regs.STATUS & (1 << 3)))
    {
        printf("CPU is halted\n");
        return -1;
    }
    printf("PC -> 0x%x\n", PC);
    CpuSetPC(Cpu, PC);
    return 0;
}

variable_types: struct _PIC_CPU { struct _REGISTER_FILE { unsigned char INDF; unsigned char TMR0; unsigned char PCL; unsigned char STATUS; unsigned char FSR; unsigned char PORTA; unsigned char PORTB; unsigned char Unused1; unsigned char EEDATA; unsigned char EEADR; unsigned char PCLATH; unsigned char INTCON; unsigned char SRAM[68]; unsigned char Unused2[48]; unsigned char Unused3; unsigned char OPTION_REG; unsigned char Unused4[3]; unsigned char TRISA; unsigned char TRISB; unsigned char Unused5; unsigned char EECON1; unsigned char EECON2; } Regs; unsigned char W; struct _PIC_STACK { unsigned char Entries[8]; unsigned char NextTop; } Stack; struct _PIC_OPCODE { unsigned short Opcode; } ProgMem[1024]; } *

variable_types:
PC
unsigned short

return_type: int

user_defined_types: struct _PIC_CPU { struct _REGISTER_FILE Regs; unsigned char W; struct _PIC_STACK Stack; struct _PIC_OPCODE ProgMem[1024]; }


RegsPrintRegisterName

decompiled_code:
int __fastcall RegsPrintRegisterName(unsigned __int8 a1)
{
int result; // eax
int v3; // edi

result = a1;
switch ( a1 )
{
case 1u:
result = printf("TMR0");
break;
case 2u:
case 0x82u:
result = printf("PCL");
break;
case 3u:
case 0x83u:
result = printf("STATUS");
break;
case 4u:
case 0x84u:
result = printf("FSR");
break;
case 5u:
result = printf("PORTA");
break;
case 6u:
result = printf("PORTB");
break;
case 8u:
result = printf("EEDATA");
break;
case 9u:
result = printf("EEADR");
break;
case 0xAu:
case 0x8Au:
result = printf("PCLATH");
break;
case 0xBu:
case 0x8Bu:
result = printf("INTCON");
break;
case 0x81u:
result = printf("OPTION_REG");
break;
case 0x85u:
result = printf("TRISA");
break;
case 0x86u:
result = printf("TRISB");
break;
case 0x88u:
result = printf("EECON1");
break;
case 0x89u:
return result;
default:
v3 = a1 & 0x7F;
result = a1 & 0x7F;
if ( v3 > 79 || v3 == 7 )
{
result = printf("Unimplemented");
}
else if ( (unsigned __int8)result > 0xBu )
{
result = printf("GPR[0x%x]", (unsigned int)(v3 - 12));
}
break;
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(unsigned __int8 a1)
{
int result; // eax
int v3; // edi

result = a1;
switch ( a1 )
{
case 1u:
result = printf("TMR0");
break;
case 2u:
case 0x82u:
result = printf("PCL");
break;
case 3u:
case 0x83u:
result = printf("STATUS");
break;
case 4u:
case 0x84u:
result = printf("FSR");
break;
case 5u:
result = printf("PORTA");
break;
case 6u:
result = printf("PORTB");
break;
case 8u:
result = printf("EEDATA");
break;
case 9u:
result = printf("EEADR");
break;
case 0xAu:
case 0x8Au:
result = printf("PCLATH");
break;
case 0xBu:
case 0x8Bu:
result = printf("INTCON");
break;
case 0x81u:
result = printf("OPTION_REG");
break;
case 0x85u:
result = printf("TRISA");
break;
case 0x86u:
result = printf("TRISB");
break;
case 0x88u:
result = printf("EECON1");
break;
case 0x89u:
return result;
default:
v3 = a1 & 0x7F;
result = a1 & 0x7F;
if ( v3 > 79 || v3 == 7 )
{
result = printf("Unimplemented");
}
else if ( (unsigned __int8)result > 0xBu )
{
result = printf("GPR[0x%x]", (unsigned int)(v3 - 12));
}
break;
}
return result;
}

original_code:
void RegsPrintRegisterName(unsigned char RegFileAddr)
{
    switch (RegFileAddr)
    {
        case 0x01:
            printf("TMR0");
            return;
        case 0x81:
            printf("OPTION_REG");
            return;
        case 0x02:
        case 0x02 | 0x80:
            printf("PCL");
            return;
        case 0x03:
        case 0x03 | 0x80:
            printf("STATUS");
            return;
        case 0x04:
        case 0x04 | 0x80:
            printf("FSR");
            return;
        case 0x05:
            printf("PORTA");
            return;
        case 0x85:
            printf("TRISA");
            return;
        case 0x06:
            printf("PORTB");
            return;
        case 0x86:
            printf("TRISB");
            return;
        case 0x08:
            printf("EEDATA");
            return;
        case 0x88:
            printf("EECON1");
            return;
        case 0x09:
            printf("EEADR");
            return;
        case 0x89:
            return;
        case 0x0A:
        case 0x0A | 0x80:
            printf("PCLATH");
            return;
        case 0x0B:
        case 0x0B | 0x80:
            printf("INTCON");
            return;
    }
    if (((RegFileAddr & 0x7F) >= 0x50) ||
        ((RegFileAddr & 0x7F) == 0x07))
    {
        printf("Unimplemented");
    }
    else if ((RegFileAddr & 0x7F) >= 0x0C)
    {
        RegFileAddr &= 0x7F;
        printf("GPR[0x%x]", (RegFileAddr - 0x0C));
    }
}

variable_types:
RegFileAddr
unsigned char

return_type: void


RegsPrintStatusRegister

decompiled_code:
int __fastcall RegsPrintStatusRegister(char a1)
{
int result; // eax

if ( (a1 & 0x20) != 0 )
{
result = printf(" RP0");
if ( (a1 & 0x10) == 0 )
{
LABEL_3:
if ( (a1 & 8) == 0 )
goto LABEL_4;
goto LABEL_10;
}
}
else if ( (a1 & 0x10) == 0 )
{
goto LABEL_3;
}
result = printf(" ~TO");
if ( (a1 & 8) == 0 )
{
LABEL_4:
if ( (a1 & 4) == 0 )
goto LABEL_5;
goto LABEL_11;
}
LABEL_10:
result = printf(" ~PD");
if ( (a1 & 4) == 0 )
{
LABEL_5:
if ( (a1 & 2) == 0 )
goto LABEL_6;
goto LABEL_12;
}
LABEL_11:
result = printf(" Z");
if ( (a1 & 2) == 0 )
{
LABEL_6:
if ( (a1 & 1) == 0 )
return result;
return printf(" C");
}
LABEL_12:
result = printf(" DC");
if ( (a1 & 1) != 0 )
return printf(" C");
return result;
}

canonical_decompiled_code:
int __fastcall func1(char a1)
{
int result; // eax

if ( (a1 & 0x20) != 0 )
{
result = printf(" RP0");
if ( (a1 & 0x10) == 0 )
{
LABEL_3:
if ( (a1 & 8) == 0 )
goto LABEL_4;
goto LABEL_10;
}
}
else if ( (a1 & 0x10) == 0 )
{
goto LABEL_3;
}
result = printf(" ~TO");
if ( (a1 & 8) == 0 )
{
LABEL_4:
if ( (a1 & 4) == 0 )
goto LABEL_5;
goto LABEL_11;
}
LABEL_10:
result = printf(" ~PD");
if ( (a1 & 4) == 0 )
{
LABEL_5:
if ( (a1 & 2) == 0 )
goto LABEL_6;
goto LABEL_12;
}
LABEL_11:
result = printf(" Z");
if ( (a1 & 2) == 0 )
{
LABEL_6:
if ( (a1 & 1) == 0 )
return result;
return printf(" C");
}
LABEL_12:
result = printf(" DC");
if ( (a1 & 1) != 0 )
return printf(" C");
return result;
}

original_code:
void RegsPrintStatusRegister(unsigned char StatusVal)
{
    if (StatusVal & (1 << 5))
        printf(" RP0");
    if (StatusVal & (1 << 4))
        printf(" ~TO");
    if (StatusVal & (1 << 3))
        printf(" ~PD");
    if (StatusVal & (1 << 2))
        printf(" Z");
    if (StatusVal & (1 << 1))
        printf(" DC");
    if (StatusVal & (1 << 0))
        printf(" C");
}

variable_types:
StatusVal
unsigned char


RegsSetValue

decompiled_code:
int __fastcall RegsSetValue(char *a1, char a2, int a3)
{
char v3; // al
unsigned __int8 v4; // r13
int v6; // ebp
char v7; // bl
unsigned __int8 v8; // al
unsigned __int8 v9; // bl
int result; // eax
char *v11; // r12
char v12; // r14
unsigned int v13; // er13
unsigned int v14; // edi
unsigned __int8 v15; // bp
unsigned __int8 *v16; // rbx
char v17; // bp
char v18; // bp
char v19; // bp
char v20; // bp
char v21; // bp

v3 = a2;
v4 = a3;
v6 = a3;
if ( (a2 & 0x7F) == 0 )
v3 = a1[4];
v7 = v3;
v8 = v3 & 0x7F;
v9 = v7 | 0x80;
if ( (a1[3] & 0x20) == 0 )
v9 = v8;
result = v9;
switch ( v9 )
{
case 1u:
v11 = a1 + 1;
v12 = 0;
printf("TMR0");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 2u:
case 0x82u:
v11 = a1 + 2;
v12 = 0;
printf("PCL");
goto LABEL_7;
case 3u:
case 0x83u:
v17 = a3;
v11 = a1 + 3;
printf("STATUS");
v6 = v17 & 0x3F;
v12 = -64;
goto LABEL_7;
case 4u:
case 0x84u:
v11 = a1 + 4;
v12 = 0;
printf("FSR");
goto LABEL_7;
case 5u:
v20 = a3;
v11 = a1 + 5;
printf("PORTA");
v6 = v20 & 0x1F;
v12 = -32;
v13 = v4 & 0x1F;
goto LABEL_21;
case 6u:
v11 = a1 + 6;
v12 = 0;
printf("PORTB");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 8u:
v11 = a1 + 8;
v12 = 0;
printf("EEDATA");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 9u:
v11 = a1 + 9;
v12 = 0;
printf("EEADR");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 0xAu:
case 0x8Au:
v18 = a3;
v11 = a1 + 10;
printf("PCLATH");
v6 = v18 & 0x1E;
v12 = -31;
goto LABEL_7;
case 0xBu:
case 0x8Bu:
v11 = a1 + 11;
v12 = 0;
printf("INTCON");
LABEL_7:
v13 = (unsigned __int8)v6;
if ( (v9 & 0x7F) != 3 )
goto LABEL_21;
printf(": [");
RegsPrintStatusRegister(*v11);
printf("] -> [");
RegsPrintStatusRegister(v6);
puts("]");
goto LABEL_9;
case 0x81u:
v12 = 0;
v13 = (unsigned __int8)a3;
printf("OPTION_REG");
v11 = a1 + 129;
goto LABEL_21;
case 0x85u:
v19 = a3;
v12 = -32;
printf("TRISA");
v11 = a1 + 133;
v6 = v19 & 0x1F;
v13 = v4 & 0x1F;
goto LABEL_21;
case 0x86u:
v12 = 0;
v13 = (unsigned __int8)a3;
printf("TRISB");
v11 = a1 + 134;
goto LABEL_21;
case 0x88u:
v21 = a3;
v12 = -32;
printf("EECON1");
v11 = a1 + 136;
v6 = v21 & 0x1F;
v13 = v4 & 0x1F;
LABEL_21:
printf(": 0x%x -> 0x%x\n", (unsigned __int8)*v11, v13);
LABEL_9:
result = v6 | (unsigned __int8)(v12 & *v11);
*v11 = v6 | v12 & *v11;
break;
case 0x89u:
return result;
default:
v14 = v9 & 0x7F;
v15 = v9 & 0x7F;
if ( v14 <= 0x4F && v14 != 7 )
{
if ( v15 <= 0xBu )
{
LOBYTE(v14) = v9;
v15 = v9;
}
RegsPrintRegisterName(v14);
v16 = (unsigned __int8 *)&a1[v15];
result = printf(": %d -> %d\n", *v16, v4);
*v16 = v4;
}
break;
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(char *a1, char a2, int a3)
{
char v3; // al
unsigned __int8 v4; // r13
int v6; // ebp
char v7; // bl
unsigned __int8 v8; // al
unsigned __int8 v9; // bl
int result; // eax
char *v11; // r12
char v12; // r14
unsigned int v13; // er13
unsigned int v14; // edi
unsigned __int8 v15; // bp
unsigned __int8 *v16; // rbx
char v17; // bp
char v18; // bp
char v19; // bp
char v20; // bp
char v21; // bp

v3 = a2;
v4 = a3;
v6 = a3;
if ( (a2 & 0x7F) == 0 )
v3 = a1[4];
v7 = v3;
v8 = v3 & 0x7F;
v9 = v7 | 0x80;
if ( (a1[3] & 0x20) == 0 )
v9 = v8;
result = v9;
switch ( v9 )
{
case 1u:
v11 = a1 + 1;
v12 = 0;
printf("TMR0");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 2u:
case 0x82u:
v11 = a1 + 2;
v12 = 0;
printf("PCL");
goto LABEL_7;
case 3u:
case 0x83u:
v17 = a3;
v11 = a1 + 3;
printf("STATUS");
v6 = v17 & 0x3F;
v12 = -64;
goto LABEL_7;
case 4u:
case 0x84u:
v11 = a1 + 4;
v12 = 0;
printf("FSR");
goto LABEL_7;
case 5u:
v20 = a3;
v11 = a1 + 5;
printf("PORTA");
v6 = v20 & 0x1F;
v12 = -32;
v13 = v4 & 0x1F;
goto LABEL_21;
case 6u:
v11 = a1 + 6;
v12 = 0;
printf("PORTB");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 8u:
v11 = a1 + 8;
v12 = 0;
printf("EEDATA");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 9u:
v11 = a1 + 9;
v12 = 0;
printf("EEADR");
v13 = (unsigned __int8)v6;
goto LABEL_21;
case 0xAu:
case 0x8Au:
v18 = a3;
v11 = a1 + 10;
printf("PCLATH");
v6 = v18 & 0x1E;
v12 = -31;
goto LABEL_7;
case 0xBu:
case 0x8Bu:
v11 = a1 + 11;
v12 = 0;
printf("INTCON");
LABEL_7:
v13 = (unsigned __int8)v6;
if ( (v9 & 0x7F) != 3 )
goto LABEL_21;
printf(": [");
func1(*v11);
printf("] -> [");
func1(v6);
puts("]");
goto LABEL_9;
case 0x81u:
v12 = 0;
v13 = (unsigned __int8)a3;
printf("OPTION_REG");
v11 = a1 + 129;
goto LABEL_21;
case 0x85u:
v19 = a3;
v12 = -32;
printf("TRISA");
v11 = a1 + 133;
v6 = v19 & 0x1F;
v13 = v4 & 0x1F;
goto LABEL_21;
case 0x86u:
v12 = 0;
v13 = (unsigned __int8)a3;
printf("TRISB");
v11 = a1 + 134;
goto LABEL_21;
case 0x88u:
v21 = a3;
v12 = -32;
printf("EECON1");
v11 = a1 + 136;
v6 = v21 & 0x1F;
v13 = v4 & 0x1F;
LABEL_21:
printf(": 0x%x -> 0x%x\n", (unsigned __int8)*v11, v13);
LABEL_9:
result = v6 | (unsigned __int8)(v12 & *v11);
*v11 = v6 | v12 & *v11;
break;
case 0x89u:
return result;
default:
v14 = v9 & 0x7F;
v15 = v9 & 0x7F;
if ( v14 <= 0x4F && v14 != 7 )
{
if ( v15 <= 0xBu )
{
LOBYTE(v14) = v9;
v15 = v9;
}
func0(v14);
v16 = (unsigned __int8 *)&a1[v15];
result = printf(": %d -> %d\n", *v16, v4);
*v16 = v4;
}
break;
}
return result;
}

original_code:
void RegsSetValue(REGISTER_FILE *Regs, unsigned char RegFileAddr, unsigned char Value)
{
    unsigned char WriteMask;
    unsigned char *Destination;
    if ((RegFileAddr & 0x7F) == 0)
    {
        RegFileAddr = Regs->FSR;
    }
    if ((Regs->STATUS & (1 << 5)) != 0)
    {
        RegFileAddr |= 0x80;
    }
    else
    {
        RegFileAddr &= ~0x80;
    }
    Destination = ((void *)0);
    switch (RegFileAddr)
    {
        case 0x01:
            printf("TMR0");
            WriteMask = 0xFF;
            Destination = &Regs->TMR0;
            break;
        case 0x81:
            printf("OPTION_REG");
            WriteMask = 0xFF;
            Destination = &Regs->OPTION_REG;
            break;
        case 0x02:
        case 0x02 | 0x80:
            printf("PCL");
            WriteMask = 0xFF;
            Destination = &Regs->PCL;
            break;
        case 0x03:
        case 0x03 | 0x80:
            printf("STATUS");
            WriteMask = 0x3F;
            Destination = &Regs->STATUS;
            break;
        case 0x04:
        case 0x04 | 0x80:
            printf("FSR");
            WriteMask = 0xFF;
            Destination = &Regs->FSR;
            break;
        case 0x05:
            printf("PORTA");
            WriteMask = 0x1F;
            Destination = &Regs->PORTA;
            break;
        case 0x85:
            printf("TRISA");
            WriteMask = 0x1F;
            Destination = &Regs->TRISA;
            break;
        case 0x06:
            printf("PORTB");
            WriteMask = 0xFF;
            Destination = &Regs->PORTB;
            break;
        case 0x86:
            printf("TRISB");
            WriteMask = 0xFF;
            Destination = &Regs->TRISB;
            break;
        case 0x08:
            printf("EEDATA");
            WriteMask = 0xFF;
            Destination = &Regs->EEDATA;
            break;
        case 0x88:
            printf("EECON1");
            WriteMask = 0x1F;
            Destination = &Regs->EECON1;
            break;
        case 0x09:
            printf("EEADR");
            WriteMask = 0xFF;
            Destination = &Regs->EEADR;
            break;
        case 0x89:
            return;
        case 0x0A:
        case 0x0A | 0x80:
            printf("PCLATH");
            WriteMask = 0x1E;
            Destination = &Regs->PCLATH;
            break;
        case 0x0B:
        case 0x0B | 0x80:
            printf("INTCON");
            WriteMask = 0xFF;
            Destination = &Regs->INTCON;
            break;
    }
    if (Destination != ((void *)0))
    {
        if ((RegFileAddr & 0x7F) == 0x03)
        {
            printf(": [");
            RegsPrintStatusRegister(*Destination);
            printf("] -> [");
            RegsPrintStatusRegister(Value & WriteMask);
            printf("]\n");
        }
        else
        {
            printf(": 0x%x -> 0x%x\n", *Destination, (Value & WriteMask));
        }
        *Destination &= ~WriteMask;
        *Destination |= (Value & WriteMask);
    }
    else
    {
        if (((RegFileAddr & 0x7F) >= 0x50) ||
            ((RegFileAddr & 0x7F) == 0x07))
        {
            return;
        }
        else if ((RegFileAddr & 0x7F) >= 0x0C)
        {
            RegFileAddr &= 0x7F;
        }
        RegsPrintRegisterName(RegFileAddr);
        printf(": %d -> %d\n", ((unsigned char *)Regs)[RegFileAddr], Value);
        ((unsigned char *)Regs)[RegFileAddr] = Value;
    }
}

canonical_original_code:
void RegsSetValue(struct _REGISTER_FILE *Regs, unsigned char RegFileAddr, unsigned char Value)
{
    unsigned char WriteMask;
    unsigned char *Destination;
    if ((RegFileAddr & 0x7F) == 0)
    {
        RegFileAddr = Regs->FSR;
    }
    if ((Regs->STATUS & (1 << 5)) != 0)
    {
        RegFileAddr |= 0x80;
    }
    else
    {
        RegFileAddr &= ~0x80;
    }
    Destination = ((void *)0);
    switch (RegFileAddr)
    {
        case 0x01:
            printf("TMR0");
            WriteMask = 0xFF;
            Destination = &Regs->TMR0;
            break;
        case 0x81:
            printf("OPTION_REG");
            WriteMask = 0xFF;
            Destination = &Regs->OPTION_REG;
            break;
        case 0x02:
        case 0x02 | 0x80:
            printf("PCL");
            WriteMask = 0xFF;
            Destination = &Regs->PCL;
            break;
        case 0x03:
        case 0x03 | 0x80:
            printf("STATUS");
            WriteMask = 0x3F;
            Destination = &Regs->STATUS;
            break;
        case 0x04:
        case 0x04 | 0x80:
            printf("FSR");
            WriteMask = 0xFF;
            Destination = &Regs->FSR;
            break;
        case 0x05:
            printf("PORTA");
            WriteMask = 0x1F;
            Destination = &Regs->PORTA;
            break;
        case 0x85:
            printf("TRISA");
            WriteMask = 0x1F;
            Destination = &Regs->TRISA;
            break;
        case 0x06:
            printf("PORTB");
            WriteMask = 0xFF;
            Destination = &Regs->PORTB;
            break;
        case 0x86:
            printf("TRISB");
            WriteMask = 0xFF;
            Destination = &Regs->TRISB;
            break;
        case 0x08:
            printf("EEDATA");
            WriteMask = 0xFF;
            Destination = &Regs->EEDATA;
            break;
        case 0x88:
            printf("EECON1");
            WriteMask = 0x1F;
            Destination = &Regs->EECON1;
            break;
        case 0x09:
            printf("EEADR");
            WriteMask = 0xFF;
            Destination = &Regs->EEADR;
            break;
        case 0x89:
            return;
        case 0x0A:
        case 0x0A | 0x80:
            printf("PCLATH");
            WriteMask = 0x1E;
            Destination = &Regs->PCLATH;
            break;
        case 0x0B:
        case 0x0B | 0x80:
            printf("INTCON");
            WriteMask = 0xFF;
            Destination = &Regs->INTCON;
            break;
    }
    if (Destination != ((void *)0))
    {
        if ((RegFileAddr & 0x7F) == 0x03)
        {
            printf(": [");
            RegsPrintStatusRegister(*Destination);
            printf("] -> [");
            RegsPrintStatusRegister(Value & WriteMask);
            printf("]\n");
        }
        else
        {
            printf(": 0x%x -> 0x%x\n", *Destination, (Value & WriteMask));
        }
        *Destination &= ~WriteMask;
        *Destination |= (Value & WriteMask);
    }
    else
    {
        if (((RegFileAddr & 0x7F) >= 0x50) ||
            ((RegFileAddr & 0x7F) == 0x07))
        {
            return;
        }
        else if ((RegFileAddr & 0x7F) >= 0x0C)
        {
            RegFileAddr &= 0x7F;
        }
        RegsPrintRegisterName(RegFileAddr);
        printf(": %d -> %d\n", ((unsigned char *)Regs)[RegFileAddr], Value);
        ((unsigned char *)Regs)[RegFileAddr] = Value;
    }
}

variable_types: struct _REGISTER_FILE { unsigned char INDF; unsigned char TMR0; unsigned char PCL; unsigned char STATUS; unsigned char FSR; unsigned char PORTA; unsigned char PORTB; unsigned char Unused1; unsigned char EEDATA; unsigned char EEADR; unsigned char PCLATH; unsigned char INTCON; unsigned char SRAM[68]; unsigned char Unused2[48]; unsigned char Unused3; unsigned char OPTION_REG; unsigned char Unused4[3]; unsigned char TRISA; unsigned char TRISB; unsigned char Unused5; unsigned char EECON1; unsigned char EECON2; } *

variable_types:
Value
unsigned char

variable_types:
WriteMask
unsigned char

variable_types:
Destination
unsigned char *


RegsGetValue

decompiled_code:
__int64 __fastcall RegsGetValue(unsigned __int8 *a1, unsigned __int8 a2)
{
unsigned __int8 v2; // al
unsigned __int8 v3; // dl
unsigned __int8 v4; // cl
unsigned __int8 v5; // al
unsigned __int8 v6; // cl
__int64 result; // rax

v2 = a2;
if ( (a2 & 0x7F) == 0 )
v2 = a1[4];
v3 = a1[3];
v4 = v2;
v5 = v2 & 0x7F;
v6 = v4 | 0x80;
if ( (v3 & 0x20) != 0 )
v5 = v6;
switch ( v5 )
{
case 1u:
result = a1[1];
break;
case 2u:
case 0x82u:
result = a1[2];
break;
case 3u:
case 0x83u:
result = v3 & 0x3F;
break;
case 4u:
case 0x84u:
result = a1[4];
break;
case 5u:
result = a1[5] & 0x1F;
break;
case 6u:
result = a1[6];
break;
case 8u:
result = a1[8];
break;
case 9u:
result = a1[9];
break;
case 0xAu:
case 0x89u:
case 0x8Au:
goto LABEL_11;
case 0xBu:
case 0x8Bu:
result = a1[11];
break;
case 0x81u:
result = a1[129];
break;
case 0x85u:
result = a1[133] & 0x1F;
break;
case 0x86u:
result = a1[134];
break;
case 0x88u:
result = a1[136] & 0x1F;
break;
default:
if ( (v5 & 0x7Fu) > 0x4F || (v5 & 0x7F) == 7 )
{
LABEL_11:
result = 0LL;
}
else
{
if ( (v5 & 0x7Fu) >= 0xC )
v5 &= 0x7Fu;
result = a1[v5];
}
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int8 *a1, unsigned __int8 a2)
{
unsigned __int8 v2; // al
unsigned __int8 v3; // dl
unsigned __int8 v4; // cl
unsigned __int8 v5; // al
unsigned __int8 v6; // cl
__int64 result; // rax

v2 = a2;
if ( (a2 & 0x7F) == 0 )
v2 = a1[4];
v3 = a1[3];
v4 = v2;
v5 = v2 & 0x7F;
v6 = v4 | 0x80;
if ( (v3 & 0x20) != 0 )
v5 = v6;
switch ( v5 )
{
case 1u:
result = a1[1];
break;
case 2u:
case 0x82u:
result = a1[2];
break;
case 3u:
case 0x83u:
result = v3 & 0x3F;
break;
case 4u:
case 0x84u:
result = a1[4];
break;
case 5u:
result = a1[5] & 0x1F;
break;
case 6u:
result = a1[6];
break;
case 8u:
result = a1[8];
break;
case 9u:
result = a1[9];
break;
case 0xAu:
case 0x89u:
case 0x8Au:
goto LABEL_11;
case 0xBu:
case 0x8Bu:
result = a1[11];
break;
case 0x81u:
result = a1[129];
break;
case 0x85u:
result = a1[133] & 0x1F;
break;
case 0x86u:
result = a1[134];
break;
case 0x88u:
result = a1[136] & 0x1F;
break;
default:
if ( (v5 & 0x7Fu) > 0x4F || (v5 & 0x7F) == 7 )
{
LABEL_11:
result = 0LL;
}
else
{
if ( (v5 & 0x7Fu) >= 0xC )
v5 &= 0x7Fu;
result = a1[v5];
}
break;
}
return result;
}

original_code:
char RegsGetValue(REGISTER_FILE *Regs, unsigned char RegFileAddr)
{
    unsigned char ReadMask;
    unsigned char *Source;
    if ((RegFileAddr & 0x7F) == 0)
    {
        RegFileAddr = Regs->FSR;
    }
    if ((Regs->STATUS & (1 << 5)) != 0)
    {
        RegFileAddr |= 0x80;
    }
    else
    {
        RegFileAddr &= ~0x80;
    }
    Source = ((void *)0);
    switch (RegFileAddr)
    {
        case 0x01:
            ReadMask = 0xFF;
            Source = &Regs->TMR0;
            break;
        case 0x81:
            ReadMask = 0xFF;
            Source = &Regs->OPTION_REG;
            break;
        case 0x02:
        case 0x02 | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->PCL;
            break;
        case 0x03:
        case 0x03 | 0x80:
            ReadMask = 0x3F;
            Source = &Regs->STATUS;
            break;
        case 0x04:
        case 0x04 | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->FSR;
            break;
        case 0x05:
            ReadMask = 0x1F;
            Source = &Regs->PORTA;
            break;
        case 0x85:
            ReadMask = 0x1F;
            Source = &Regs->TRISA;
            break;
        case 0x06:
            ReadMask = 0xFF;
            Source = &Regs->PORTB;
            break;
        case 0x86:
            ReadMask = 0xFF;
            Source = &Regs->TRISB;
            break;
        case 0x08:
            ReadMask = 0xFF;
            Source = &Regs->EEDATA;
            break;
        case 0x88:
            ReadMask = 0x1F;
            Source = &Regs->EECON1;
            break;
        case 0x09:
            ReadMask = 0xFF;
            Source = &Regs->EEADR;
            break;
        case 0x89:
            return 0;
        case 0x0A:
        case 0x0A | 0x80:
            ReadMask = 0x00;
            Source = &Regs->PCLATH;
            break;
        case 0x0B:
        case 0x0B | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->INTCON;
            break;
    }
    if (Source != ((void *)0))
    {
        return (*Source & ReadMask);
    }
    else
    {
        if (((RegFileAddr & 0x7F) >= 0x50) ||
            ((RegFileAddr & 0x7F) == 0x07))
        {
            return 0;
        }
        else if ((RegFileAddr & 0x7F) >= 0x0C)
        {
            RegFileAddr &= 0x7F;
        }
        return ((unsigned char *)Regs)[RegFileAddr];
    }
}

canonical_original_code:
char RegsGetValue(struct _REGISTER_FILE *Regs, unsigned char RegFileAddr)
{
    unsigned char ReadMask;
    unsigned char *Source;
    if ((RegFileAddr & 0x7F) == 0)
    {
        RegFileAddr = Regs->FSR;
    }
    if ((Regs->STATUS & (1 << 5)) != 0)
    {
        RegFileAddr |= 0x80;
    }
    else
    {
        RegFileAddr &= ~0x80;
    }
    Source = ((void *)0);
    switch (RegFileAddr)
    {
        case 0x01:
            ReadMask = 0xFF;
            Source = &Regs->TMR0;
            break;
        case 0x81:
            ReadMask = 0xFF;
            Source = &Regs->OPTION_REG;
            break;
        case 0x02:
        case 0x02 | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->PCL;
            break;
        case 0x03:
        case 0x03 | 0x80:
            ReadMask = 0x3F;
            Source = &Regs->STATUS;
            break;
        case 0x04:
        case 0x04 | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->FSR;
            break;
        case 0x05:
            ReadMask = 0x1F;
            Source = &Regs->PORTA;
            break;
        case 0x85:
            ReadMask = 0x1F;
            Source = &Regs->TRISA;
            break;
        case 0x06:
            ReadMask = 0xFF;
            Source = &Regs->PORTB;
            break;
        case 0x86:
            ReadMask = 0xFF;
            Source = &Regs->TRISB;
            break;
        case 0x08:
            ReadMask = 0xFF;
            Source = &Regs->EEDATA;
            break;
        case 0x88:
            ReadMask = 0x1F;
            Source = &Regs->EECON1;
            break;
        case 0x09:
            ReadMask = 0xFF;
            Source = &Regs->EEADR;
            break;
        case 0x89:
            return 0;
        case 0x0A:
        case 0x0A | 0x80:
            ReadMask = 0x00;
            Source = &Regs->PCLATH;
            break;
        case 0x0B:
        case 0x0B | 0x80:
            ReadMask = 0xFF;
            Source = &Regs->INTCON;
            break;
    }
    if (Source != ((void *)0))
    {
        return (*Source & ReadMask);
    }
    else
    {
        if (((RegFileAddr & 0x7F) >= 0x50) ||
            ((RegFileAddr & 0x7F) == 0x07))
        {
            return 0;
        }
        else if ((RegFileAddr & 0x7F) >= 0x0C)
        {
            RegFileAddr &= 0x7F;
        }
        return ((unsigned char *)Regs)[RegFileAddr];
    }
}

variable_types:
ReadMask
unsigned char

variable_types:
Source
unsigned char *

return_type: char

user_defined_types: struct _REGISTER_FILE { unsigned char INDF; unsigned char TMR0; unsigned char PCL; unsigned char STATUS; unsigned char FSR; unsigned char PORTA; unsigned char PORTB; unsigned char Unused1; unsigned char EEDATA; unsigned char EEADR; unsigned char PCLATH; unsigned char INTCON; unsigned char SRAM[68]; unsigned char Unused2[48]; unsigned char Unused3; unsigned char OPTION_REG; unsigned char Unused4[3]; unsigned char TRISA; unsigned char TRISB; unsigned char Unused5; unsigned char EECON1; unsigned char EECON2; }


OpGenerateOpcode

decompiled_code:
__int16 __fastcall OpGenerateOpcode(char *s1, char a2, __int16 a3)
{
__int16 result; // ax
int v5; // er8

if ( !strcmp(s1, "ADDWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 7;
}
else if ( !strcmp(s1, "ANDWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 5;
}
else if ( !strcmp(s1, "CLRF") )
{
result = a2 & 0x7F | 0x180;
}
else
{
result = 256;
if ( strcmp(s1, "CLRW") )
{
if ( !strcmp(s1, "COMF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = 9;
}
else if ( !strcmp(s1, "DECF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = 3;
}
else if ( !strcmp(s1, "DECFSZ") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xB;
}
else if ( !strcmp(s1, "INCF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xA;
}
else if ( !strcmp(s1, "INCFSZ") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xF;
}
else if ( !strcmp(s1, "IORWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 4;
}
else if ( !strcmp(s1, "MOVF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 8;
}
else if ( !strcmp(s1, "MOVWF") )
{
result = a2 & 0x7F;
LOBYTE(result) = result | 0x80;
}
else
{
v5 = strcmp(s1, "NOP");
result = 0;
if ( v5 )
{
if ( !strcmp(s1, "RLF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xD;
}
else if ( !strcmp(s1, "RRF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xC;
}
else if ( !strcmp(s1, "SUBWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 2;
}
else if ( !strcmp(s1, "SWAPF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xE;
}
else if ( !strcmp(s1, "XORWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 9;
}
else if ( !strcmp(s1, "BCF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x10;
}
else if ( !strcmp(s1, "BSF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x14;
}
else if ( !strcmp(s1, "BTFSC") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x18;
}
else if ( !strcmp(s1, "BTFSS") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x1C;
}
else if ( !strcmp(s1, "ADDLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 62;
}
else if ( !strcmp(s1, "ANDLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 57;
}
else if ( !strcmp(s1, "CALL") )
{
result = a2 & 0x7FF;
HIBYTE(result) |= 0x20u;
}
else if ( !strcmp(s1, "CLRWDT") )
{
result = 100;
}
else if ( !strcmp(s1, "GOTO") )
{
result = a2 & 0x7FF;
HIBYTE(result) |= 0x28u;
}
else if ( !strcmp(s1, "IORLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 56;
}
else if ( !strcmp(s1, "MOVLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 48;
}
else if ( !strcmp(s1, "RETFIE") )
{
result = 9;
}
else if ( !strcmp(s1, "RETLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 52;
}
else if ( !strcmp(s1, "RETURN") )
{
result = 8;
}
else if ( !strcmp(s1, "SLEEP") )
{
result = 99;
}
else if ( !strcmp(s1, "SUBLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 60;
}
else if ( !strcmp(s1, "XORLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 58;
}
else
{
result = -1;
}
}
}
}
}
return result;
}

canonical_decompiled_code:
__int16 __fastcall func0(char *s1, char a2, __int16 a3)
{
__int16 result; // ax
int v5; // er8

if ( !strcmp(s1, "ADDWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 7;
}
else if ( !strcmp(s1, "ANDWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 5;
}
else if ( !strcmp(s1, "CLRF") )
{
result = a2 & 0x7F | 0x180;
}
else
{
result = 256;
if ( strcmp(s1, "CLRW") )
{
if ( !strcmp(s1, "COMF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = 9;
}
else if ( !strcmp(s1, "DECF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = 3;
}
else if ( !strcmp(s1, "DECFSZ") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xB;
}
else if ( !strcmp(s1, "INCF") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xA;
}
else if ( !strcmp(s1, "INCFSZ") )
{
LOBYTE(result) = ((_BYTE)a3 << 7) | a2 & 0x7F;
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xF;
}
else if ( !strcmp(s1, "IORWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 4;
}
else if ( !strcmp(s1, "MOVF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 8;
}
else if ( !strcmp(s1, "MOVWF") )
{
result = a2 & 0x7F;
LOBYTE(result) = result | 0x80;
}
else
{
v5 = strcmp(s1, "NOP");
result = 0;
if ( v5 )
{
if ( !strcmp(s1, "RLF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xD;
}
else if ( !strcmp(s1, "RRF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xC;
}
else if ( !strcmp(s1, "SUBWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 2;
}
else if ( !strcmp(s1, "SWAPF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 0xE;
}
else if ( !strcmp(s1, "XORWF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x80) >> 8) | 9;
}
else if ( !strcmp(s1, "BCF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x10;
}
else if ( !strcmp(s1, "BSF") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x14;
}
else if ( !strcmp(s1, "BTFSC") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x18;
}
else if ( !strcmp(s1, "BTFSS") )
{
LOBYTE(result) = a2 & 0x7F | ((_BYTE)a3 << 7);
HIBYTE(result) = ((unsigned __int16)((a3 << 7) & 0x380) >> 8) | 0x1C;
}
else if ( !strcmp(s1, "ADDLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 62;
}
else if ( !strcmp(s1, "ANDLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 57;
}
else if ( !strcmp(s1, "CALL") )
{
result = a2 & 0x7FF;
HIBYTE(result) |= 0x20u;
}
else if ( !strcmp(s1, "CLRWDT") )
{
result = 100;
}
else if ( !strcmp(s1, "GOTO") )
{
result = a2 & 0x7FF;
HIBYTE(result) |= 0x28u;
}
else if ( !strcmp(s1, "IORLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 56;
}
else if ( !strcmp(s1, "MOVLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 48;
}
else if ( !strcmp(s1, "RETFIE") )
{
result = 9;
}
else if ( !strcmp(s1, "RETLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 52;
}
else if ( !strcmp(s1, "RETURN") )
{
result = 8;
}
else if ( !strcmp(s1, "SLEEP") )
{
result = 99;
}
else if ( !strcmp(s1, "SUBLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 60;
}
else if ( !strcmp(s1, "XORLW") )
{
LOBYTE(result) = a2;
HIBYTE(result) = 58;
}
else
{
result = -1;
}
}
}
}
}
return result;
}

original_code:
unsigned short OpGenerateOpcode(char *opname, char operand1, char operand2)
{
    unsigned short opcode = 0xFFFF;
    if (!strcmp(opname, "ADDWF"))
    {
        opcode = 0x700;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "ANDWF"))
    {
        opcode = 0x500;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "CLRF"))
    {
        opcode = 0x180;
        opcode |= (operand1 & 0x7F);
    }
    else if (!strcmp(opname, "CLRW"))
    {
        opcode = 0x100;
    }
    else if (!strcmp(opname, "COMF"))
    {
        opcode = 0x900;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "DECF"))
    {
        opcode = 0x300;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "DECFSZ"))
    {
        opcode = 0xB00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "INCF"))
    {
        opcode = 0xA00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "INCFSZ"))
    {
        opcode = 0xF00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "IORWF"))
    {
        opcode = 0x400;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "MOVF"))
    {
        opcode = 0x800;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "MOVWF"))
    {
        opcode = 0x080;
        opcode |= (operand1 & 0x7F);
    }
    else if (!strcmp(opname, "NOP"))
    {
        opcode = 0;
    }
    else if (!strcmp(opname, "RLF"))
    {
        opcode = 0xD00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "RRF"))
    {
        opcode = 0xC00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "SUBWF"))
    {
        opcode = 0x200;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "SWAPF"))
    {
        opcode = 0xE00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "XORWF"))
    {
        opcode = 0x900;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x80;
    }
    else if (!strcmp(opname, "BCF"))
    {
        opcode = 0x1000;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x380;
    }
    else if (!strcmp(opname, "BSF"))
    {
        opcode = 0x1400;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x380;
    }
    else if (!strcmp(opname, "BTFSC"))
    {
        opcode = 0x1800;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x380;
    }
    else if (!strcmp(opname, "BTFSS"))
    {
        opcode = 0x1C00;
        opcode |= (operand1 & 0x7F);
        opcode |= (operand2 << 7) & 0x380;
    }
    else if (!strcmp(opname, "ADDLW"))
    {
        opcode = 0x3E00;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "ANDLW"))
    {
        opcode = 0x3900;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "CALL"))
    {
        opcode = 0x2000;
        opcode |= (operand1 & 0x7FF);
    }
    else if (!strcmp(opname, "CLRWDT"))
    {
        opcode = 0x64;
    }
    else if (!strcmp(opname, "GOTO"))
    {
        opcode = 0x2800;
        opcode |= (operand1 & 0x7FF);
    }
    else if (!strcmp(opname, "IORLW"))
    {
        opcode = 0x3800;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "MOVLW"))
    {
        opcode = 0x3000;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "RETFIE"))
    {
        opcode = 0x09;
    }
    else if (!strcmp(opname, "RETLW"))
    {
        opcode = 0x3400;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "RETURN"))
    {
        opcode = 0x08;
    }
    else if (!strcmp(opname, "SLEEP"))
    {
        opcode = 0x63;
    }
    else if (!strcmp(opname, "SUBLW"))
    {
        opcode = 0x3C00;
        opcode |= (operand1 & 0xFF);
    }
    else if (!strcmp(opname, "XORLW"))
    {
        opcode = 0x3A00;
        opcode |= (operand1 & 0xFF);
    }
    return opcode;
}

variable_types:
opname
char *

variable_types:
opcode
unsigned short

return_type: unsigned short