#include "alfe/main.h" #include class EntryPoint { public: EntryPoint(int u, int a, int t, String s) : _u(u), _a(a), _t(t), _s(s) { } int _u; // Extra bits from decxoder rom. bit 1 is set if the initial bus address is SS:eSP instead of the EA from the instruction int _a; // micro-op address of this entry point in microcode ROM int _t; // Number of cycles the manual says that this instruction takes (may not be accurate) String _s; // Name of entry point (x86 instructions or subroutine that this part of the microcode implements) }; EntryPoint entryPoints[] = { {0, 0x003, 2, " MOV r,r"}, {0, 0x005, 2, " MOV r,i"}, {0, 0x007, 2, " MOVZX rv,segreg"}, {0, 0x009, 2, " r MOV ES/SS/DS/FS/GS,rw"}, {1, 0x00b, 5, " MOV SS,mw"}, {1, 0x00f, 5, " MOV ES/DS/FS/GS,mw"}, {1, 0x013, 2, " MOV [i],A MOV m,r"}, {1, 0x015, 2, " MOV m,i"}, {1, 0x017, 2, " MOV mw,segreg"}, {1, 0x019, 4, " MOV A,[i] MOV r,m"}, {0, 0x01d, 2, " ADD/OR/ADC/SBB/AND/SUB/XOR r,r"}, {0, 0x01f, 2, " CMP r,r TEST r,r"}, // TEST reg,reg has cycle count of 1? {0, 0x021, 2, " INC/DEC/NOT/NEG r"}, {0, 0x023, 2, " ADD/OR/ADC/SBB/AND/SUB/XOR r,i"}, {0, 0x025, 2, " CMP/TEST A,i"}, {1, 0x027, 6, " ADD/OR/ADC/SBB/AND/SUB/XOR r,m"}, {1, 0x02c, 6, " CMP r,m"}, {1, 0x031, 5, " CMP/TEST m,i"}, {1, 0x035, 5, " CMP/TEST m,r"}, {9, 0x039, 7, " ADD/OR/ADC/SBB/AND/SUB/XOR m,i"}, {0, 0x03d, 4, " SETcond rb"}, { 0, 0x041, 0, "SETCONDR_FALSE"}, {1, 0x043, 5, " SETcond mb"}, { 0, 0x046, 0, "WRITE_RESULT "}, { 0, 0x048, 0, "SETCONDM_FALSE"}, {9, 0x04a, 7, " ADD/OR/ADC/SBB/AND/SUB/XOR m,r"}, {9, 0x04e, 6, " INC/DEC/NOT/NEG m"}, {0, 0x051, 5, " JeCXZ cb"}, // cycle count is 5/9+m {0, 0x057,11, " LOOP cb"}, // cycle count is 11+m/? { 0, 0x05b, 0, "LOOP_DONE "}, { 0, 0x05d, 0, "LOOP_UNTAKEN "}, {0, 0x05f,11, " LOOPE/LOOPNE cb"}, // cycle count is 11+m/? {0, 0x065, 3, " Jcond cb/cv"}, // cycle count is 3/7+m { 0, 0x067, 0, "JMP_PREFINAL "}, { 0, 0x068, 0, "JMP_FINAL "}, { 0, 0x069, 0, "Jcond_DONE "}, {0, 0x06a, 7, " JMP c"}, // cycle count is 7+m { 0, 0x06b, 0, "JMP_PREF "}, {0, 0x06d, 7, " JMP rv"}, // cycle count is 7+m {1, 0x06f,10, " JMP mv"}, // cycle count is 10+m {3, 0x072,10, " RET/RET iw"}, // cycle count is 10+m {2, 0x075, 7, " CALL cw"}, // cycle count is 7+m {2, 0x079, 7, " CALL rv"}, // cycle count is 7+m {1, 0x07c,10, " CALL mv"}, // cycle count is 10+m {1, 0x081, 5, " PUSH mv"}, {2, 0x086, 2, " PUSH rv"}, {0, 0x088,24, " PUSHAd"}, { 0, 0x08d, 0, "PUSHAd_LOOP "}, {3, 0x091,24, " POPA"}, { 0, 0x092, 0, "POPAd_LOOP "}, {3, 0x097,24, " POPAD"}, {2, 0x09b, 2, " PUSH segreg"}, {2, 0x09d, 2, " PUSH i"}, {3, 0x09f, 4, " POP rv"}, // number of cycles doesn't seem to match {3, 0x0a2, 7, " POP SS"}, {3, 0x0a7, 7, " POP ES/DS/FS/GS"}, {3, 0x0ac, 5, " POP mv"}, {9, 0x0b1, 5, " XCHG m,r"}, {0, 0x0b6, 3, " XCHG eAX,rv XCHG r,r"}, {1, 0x0b9, 2, " LEA rv,m"}, {1, 0x0bb, 7, " LDS rv,m"}, // cycle count is 7/22 {1, 0x0c2, 7, " LES rv,m"}, // cycle count is 7/22 {1, 0x0c9, 7, " LSS rv,m"}, // cycle count is 7/22 {1, 0x0d0, 7, " LFS/LGS rv,m"}, // cycle count is 7/22 {0, 0x0d7, 2, " LAHF"}, {0, 0x0d9, 3, " SAHF"}, {0, 0x0dc, 5, " CLTS"}, {0, 0x0e1, 0, " SALC"}, // don't know cycle count { 0, 0x0e4, 0, "SALC_DONE "}, {0, 0x0e5, 9, " RCL/RCR r,ib"}, {0, 0x0e9, 9, " RCL/RCR r,CL"}, { 0, 0x0ed, 0, "RCLRCR_R_COMM "}, // common to register ib and CL forms of RCL/RCR { 0, 0x0f1, 0, "RCLRCR_R_LOOP "}, {0, 0x0f9, 3, " ROL/ROR/SHL/SHR/SAR r,ib"}, {0, 0x0fc, 3, " SHxD rv,rv,ib"}, {0, 0x0ff, 3, " ROL/ROR/SHL/SHR/SAR r,CL"}, {0, 0x102, 3, " SHxD rv,rv,CL"}, {0, 0x105, 9, " rot r,1"}, {1, 0x108,10, " RCL/RCR m,ib"}, {1, 0x10c,10, " RCL/RCR m,CL"}, { 0, 0x110, 0, "RCLRCR_M_COMM "}, // common to memory ib and CL forms of RCL/RCR { 0, 0x115, 0, "RCLRCR_M_LOOP "}, {1, 0x11e, 7, " ROL/ROR/SHL/SHR/SAR m,ib"}, { 0, 0x120, 0, "ROSHSA_M_COMM "}, // common to memory ib and CL forms of ROL/ROR/SHL/SHR/SAR {1, 0x124, 7, " SHxD mv,rv,ib"}, { 0, 0x126, 0, "SHxD_M_COMM "}, // common to memory ib and CL forms of ROL/ROR/SHL/SHR/SAR {1, 0x12a,10, " rot m,1"}, {1, 0x12d, 7, " ROL/ROR/SHL/SHR/SAR m,CL"}, {1, 0x12f, 7, " SHxD mv,rv,CL"}, {0, 0x131, 3, " BT rv,rv"}, {1, 0x134,12, " BT m,rv"}, {0, 0x13f, 3, " BT rv,ib"}, {1, 0x142, 6, " BT m,ib"}, {0, 0x147, 6, " BTS/BTR/BTC rv,rv"}, {9, 0x14d,13, " BTS/BTR/BTC m,rv"}, {0, 0x15a, 6, " BTS/BTR/BTC rv,ib"}, {9, 0x160, 8, " BTS/BTR/BTC m,ib"}, {0, 0x168,10, " BSF rv,rv"}, // 10+3n { 0, 0x169, 0, "BSF_COMMON "}, // common to register and memory forms of BSF { 0, 0x171, 0, "BSF_DONE " }, { 0, 0x172, 0, "BSF_LOOP "}, {1, 0x177,10, " BSF rv,mv"}, // 10+3n {0, 0x17a,10, " BSR rv,rv"}, // 10+3n { 0, 0x17b, 0, "BSR_COMMON "}, // common to register and memory forms of BSR { 0, 0x17f, 0, "BSR_LOOP "}, { 0, 0x183, 0, "BSR_DONE " }, {1, 0x184,10, " BSR rv,mv"}, // 10+3n {0, 0x187, 4, " AAA/AAS"}, {0, 0x18b, 4, " DAA/DAS"}, {0, 0x18f,17, " AAM ib"}, {0, 0x199,19, " AAD ib"}, {0, 0x1a5, 9, " MUL/IMUL r"}, // cycle count is 9-14/9-22/9-38 { 0, 0x1a7, 0, "iMUL_COMMON "}, // common to register and memory forms of MUL/IMUL rm {1, 0x1af,12, " MUL/IMUL m"}, // cycle count is 12-17/12-25/12-41 {0, 0x1b3, 9, " IMUL rv,rv"}, // cycle count is 9-22/9-38 { 0, 0x1b5, 0, "IMUL2_COMMON "}, // common to register and memory forms of IMUL rv,rmv and IMUL rv,rmv,i {1, 0x1bd,12, " IMUL rv,mv"}, // cycle count is 12-25/12-41 {1, 0x1c1, 9, " IMUL rv,mv,i"}, // cycle count is 9-22/9-38 {0, 0x1c4,12, " IMUL rv,rv,i"}, // cycle count is 12-25/12-41 {0, 0x1c7,14, " DIV r "}, // cycle count is 14/22/38 { 0, 0x1ca, 0, "DIV_COMMON " }, // common to register and memory forms of DIV {1, 0x1cf,17, " DIV m"}, // cycle count is 17/25/41 {0, 0x1d3,19, " IDIV r"}, // cycle count is 19/27/43 { 0, 0x1d8, 0, "IDIV_COMMON " }, // common to register and memory forms of IDIV {1, 0x1e1,22, " IDIV m"}, // cycle count is 22/30/46 {0, 0x1e6, 2, " CWD / CDQ"}, {0, 0x1e8, 3, " CBW / CWDE MOVZX/MOVSX r,r (16-bit?)"}, {1, 0x1eb, 6, " MOVZX/MOVSX r,m (16-bit?)"}, {0, 0x1f0, 3, " CBW / CWDE MOVZX/MOVSX r,r (32-bit?)"}, {1, 0x1f3, 6, " MOVZX/MOVSX r,m (32-bit?)"}, {0, 0x1f8, 7, " REP MOVS"}, { 0, 0x1fd, 0, "REP_MOVS_NOT0 " }, { 0, 0x201, 0, "REP_MOVS_LOOP " }, { 0, 0x205, 0, "REP_MOVS_DONE " }, { 0, 0x207, 0, "REP_MOVS_RPTI " }, { 0, 0x208, 0, "RPTI "}, {0, 0x211, 7, " MOVS"}, {0, 0x218,12, " REP CMPS"}, { 0, 0x21c, 0, "REP_CMPS_DONE " }, { 0, 0x21d, 0, "REP_CMPS_LOOP " }, { 0, 0x220, 0, "REP_CMPS_NOT0 " }, {0, 0x22b,10, " CMPS"}, {0, 0x235, 9, " REP SCAS"}, { 0, 0x239, 0, "REP_SCAS_DONE " }, { 0, 0x23a, 0, "REP_SCAS_LOOP " }, { 0, 0x23d, 0, "REP_SCAS_NOT0 " }, {0, 0x247, 7, " SCAS"}, {0, 0x24e, 7, " REP LODS"}, { 0, 0x24f, 0, "REP_LODS_DONE " }, { 0, 0x250, 0, "REP_LODS_LOOP " }, {0, 0x25a, 5, " LODS"}, {0, 0x25f, 5, " XLATB"}, {0, 0x263, 6, " REP STOS"}, { 0, 0x264, 0, "REP_STOS_DONE " }, { 0, 0x265, 0, "REP_STOS_LOOP " }, {0, 0x26e, 4, " STOS"}, {0, 0x272, 6, " p IN A,ib"}, // cycle count is 6/26 {0, 0x274,12, " r IN A,ib"}, { 0, 0x276, 0, "IN_IMM_NOCHK " }, { 0, 0x278, 0, "IN_DONE " }, {0, 0x279, 7, " p IN A,DX"}, // cycle count is 7/27 {0, 0x27a,13, " r IN A,DX"}, { 0, 0x27c, 0, "IN_DX_NOCHK " }, {0, 0x27f, 9, " p INS"}, // cycle count is 9/29 {0, 0x281,15, " r INS"}, { 0, 0x284, 0, "INS_NOCHK " }, {0, 0x28a,11, " p REP INS"}, {0, 0x28b,17, " r REP INS"}, { 0, 0x28d, 0, "REP_INS_NOCHK " }, { 0, 0x290, 0, "REP_INS_DONE " }, { 0, 0x291, 0, "REP_INS_LOOP " }, { 0, 0x293, 0, "REP_INS_NOT0 " }, {0, 0x29b, 4, " p OUT ib,A"}, // cycle count is 4/24 {0, 0x29d,10, " r OUT ib,A"}, { 0, 0x29f, 0, "OUT_IMM_NOCHK " }, {0, 0x2a1, 5, " p OUT DX,A"}, // cycle count is 5/25 {0, 0x2a2,11, " r OUT DX,A"}, { 0, 0x2a4, 0, "OUT_DX_NOCHK " }, {0, 0x2a7, 8, " p OUTS"}, // cycle count is 8/28 {0, 0x2a9,14, " r OUTS"}, { 0, 0x2ac, 0, "OUTS_NOCHK " }, {0, 0x2b1,10, " p REP OUTS"}, {0, 0x2b2,16, " r REP OUTS"}, { 0, 0x2b4, 0, "REP_OUTS_NOCHK" }, { 0, 0x2b7, 0, "REP_OUTS_DONE " }, { 0, 0x2b8, 0, "REP_OUTS_LOOP " }, { 0, 0x2ba, 0, "REP_OUTS_NOT0 " }, { 0, 0x2c1, 0, "PORTIO_PROTCHK" }, { 0, 0x2c4, 0, "IO_PERM_BITMAP" }, { 0, 0x2d3, 0, "PORTIO_16BIT " }, { 0, 0x2d4, 0, "PORTIO_ALLOWED" }, {2, 0x2d6,17, " CALL cp"}, // cycle count is 17+m/34+m {1, 0x2da,22, " CALL mp"}, // cycle count is 22+m/38+m { 0, 0x2e2, 0, "CALL_FAR_RM " }, // common to cp and mp far CALLs in real mode {0, 0x2e5,12, " JMP cp"}, // cycle count is 12+m/27+m/45+m/TS/TS { 0, 0x2eb, 0, "JMP_FAR_RM " }, { 0, 0x2ed, 0, "JMP_FAR_RM_1 " }, // Jumps to COUNTR:TMPG ? TMPB is previous CS limit (set by 2fb)? { 0, 0x2f0, 0, "JMP_FAR_COMMON" }, { 0, 0x2f1, 0, "JMP_FAR_DONE " }, {1, 0x2f5,43, " JMP mp"}, // cycle count is 43+m/31+m/49+m/5+TS/5+TS {3, 0x2fc,18, " RETF/RETF iw"}, // cycle count is 18+m/32+m/68 {2, 0x304,10, " ENTER (16-bit?)"}, // cycle count is 10 (0), 12 (1), 15+4*(n-1) (n) {2, 0x308,10, " ENTER (32-bit?)"}, // cycle count is 10 (0), 12 (1), 15+4*(n-1) (n) { 0, 0x30c, 0, "ENTER_COMMON " }, { 0, 0x316, 0, "ENTER_LOOP " }, { 0, 0x31a, 0, "ENTER_LAST " }, { 0, 0x31c, 0, "ENTER_LASTW " }, { 0, 0x31d, 0, "ENTER_DONE " }, {0, 0x31f, 4, " LEAVE (16-bit?)"}, {0, 0x323, 4, " LEAVE (32-bit?)"}, {0, 0x327, 5, " HLT"}, { 0, 0x329, 0, "HLT_SHUTDOWN " }, {1, 0x32e,11, " LIDT mw"}, {1, 0x332,11, " LGDT mw"}, { 0, 0x336, 0, "LIDTGDT_COMMON" }, {0, 0x33d, 9, " SIDT mw"}, // Number of cycles doesn't seem to match? {0, 0x340, 9, " SGDT mw"}, // Number of cycles doesn't seem to match? { 0, 0x343, 0, "SIDTGDT_COMMON" }, {1, 0x349,13, " LMSW mw"}, {0, 0x34e,10, " LMSW rw"}, { 0, 0x351, 0, "LMSW_COMMON " }, {0, 0x358,10, " SMSW rw"}, {1, 0x35a, 3, " SMSW mw"}, {0, 0x35c,10, " MOV CR0,rd"}, { 0, 0x366, 0, "PAGING_RM " }, {0, 0x368, 4, " MOV CR2,rd"}, {0, 0x36c, 5, " MOV CR3,rd"}, {0, 0x371, 6, " MOV rd,CR0"}, { 0, 0x373, 0, "STORE_CR " }, // Common code to "MOV rd,CRn" {0, 0x377, 6, " MOV rd,CR2"}, {0, 0x379, 6, " MOV rd,CR3"}, {0, 0x37b,16, " MOV DR4/6,rd"}, {0, 0x37f,16, " MOV DR5/7,rd"}, { 0, 0x383, 0, "LD_DR4567_DONE" }, { 0, 0x385, 0, "SELECT_DR_TR " }, {0, 0x38a,22, " MOV DR0-3,rd"}, {0, 0x391,12, " MOV TRn,rd"}, { 0, 0x398, 0, "GENERAL_DETECT" }, // Do the breakpoint on TR/DR access if bit 13 of DR7 is set { 0, 0x3a2, 0, "GD_HIT " }, // General detect condition has been triggered {0, 0x3a6,22, " MOV rd,DR4/6"}, {0, 0x3aa,22, " MOV rd,DR5/7"}, {0, 0x3ae,22, " MOV rd,DR0-3"}, {0, 0x3b6,12, " MOV rd,TRn"}, {0, 0x3bd, 6, " WAIT"}, { 0, 0x3be, 0, "WAIT_LOOP " }, { 0, 0x3c1, 0, "WAIT_IRQT " }, // Continuation of WAIT loop after subroutine - check if IRQ is pending { 0, 0x3c5, 0, "WAIT_ERRT " }, // Subroutine to handle && in error test { 0, 0x3c8, 0, "WAIT_DONE " }, { 0, 0x3cb, 0, "FPU_ERROR6 " }, {0, 0x3cd, 0, " FENI/FDISI/FCLEX/FINIT/FSETPM/FRSTPM r"}, // FPU flag instructions (no memory access) - these need to reset prefetching for some reason? Same reason that CLI/STI do? { 0, 0x3d1, 0, "FPU_FLAG_LOOP " }, {0, 0x3d9, 0, " FSTCW/FSTSW mw"}, // Number of cycles doesn't seem to match? {0, 0x3da, 0, " FSTSW AX/FNSTDW/FNSTSG r"}, { 0, 0x3db, 0, "FPU_MISC_WAIT " }, { 0, 0x3e2, 0, "FPU_MISC_CORE " }, { 0, 0x3e8, 0, "FPU_MISC_WRITE" }, { 0, 0x3eb, 0, "FPU_ERROR5 " }, // Unreachable? {1, 0x3ed, 0, " FSTENV m"}, {1, 0x3f0, 0, " FSAVE m"}, { 0, 0x3f3, 0, "FSAVE_WAIT " }, // Common entry point to FSTENV and FSAVE - wait for FPU to be ready { 0, 0x3fa, 0, "FSAVE_CORE " }, { 0, 0x42f, 0, "FSAVE_COR_WAIT" }, { 0, 0x42f, 0, "FSAVE_PM " }, // FSAVE protected mode helper { 0, 0x436, 0, "FSAVE_REGFILE " }, // FSAVE subroutine to save register file (i.e. the part that isn't done in FSTENV) { 0, 0x43c, 0, "FSAVE_LOOP " }, { 0, 0x442, 0, "FSAVE_DONEFILE" }, { 0, 0x444, 0, "FSAVE_NOWRITE " }, { 0, 0x449, 0, "FSAVE_387 " }, //pla4 ?????1????<3E> 0000 10" }, { 0, 0x451, 0, "FSAVE_287 " }, //pla4 ?????0????<3E> 0000 10" }, { 0, 0x451, 0, "FSAVE_DONE " }, {1, 0x459, 0, " FLDENV m"}, {1, 0x45c, 0, " FRSTOR m"}, { 0, 0x45f, 0, "FPU_ERROR4 " }, { 0, 0x461, 0, "FRSTOR_WAIT " }, // Common entry point to FSTENV and FSAVE - wait for FPU to be ready { 0, 0x466, 0, "FRSTOR_IRQT " }, { 0, 0x46a, 0, "FRSTOR_ERRT " }, { 0, 0x46e, 0, "FRSTOR_CORE " }, { 0, 0x47b, 0, "FRSTOR_CORWAIT" }, { 0, 0x49b, 0, "FRSTOR_PM " }, // FRSTOR protected mode helper { 0, 0x4a7, 0, "FRSTOR_REGFILE" }, // FRSTOR subroutine to save register file (i.e. the part that isn't done in FLDENV) { 0, 0x4ad, 0, "FRSTOR_LOOP " }, { 0, 0x4b3, 0, "FRSTOR_DONEFIL" }, { 0, 0x4b5, 0, "FRSTOR_387 " }, //pla4 ?????1????<3F> 0000 10" }, { 0, 0x4ba, 0, "FRSTOR_DONE " }, { 0, 0x4bb, 0, "FRSTOR_287 " }, //pla4 ?????0????<3F> 0000 10" }, {0, 0x4c1, 0, " FP instructions that don't access memory"}, { 0, 0x4c2, 0, "FPU_REG_WAIT " }, { 0, 0x4c5, 0, "FPU_REG_IRQT " }, { 0, 0x4c9, 0, "FPU_REG_ERRT " }, { 0, 0x4cc, 0, "FPU_REG_CORE " }, { 0, 0x4ce, 0, "FPU_REG_CORWAI" }, { 0, 0x4d1, 0, "FPU_ERROR3 " }, {1, 0x4d3, 0, " FBLD/FLD mt"}, {1, 0x4d7, 0, " FADD/FMUL/FCOM/FCOMP/FSUB/FSUBR/FDIV/FDIVR/FIADD/FIMUL/FICOM/FICOMP/FISUB/FISUBR/FIDIV/FIDIVR/FLD/FILD md"}, {1, 0x4db, 0, " FLD/FILD/FADD/FMUL/FCOM/FCOMP/FSUBR/FSUB/FDIVR/FDIV mq"}, {1, 0x4df, 0, " FLDCW mw"}, {1, 0x4e0, 0, " FIADD/FIMUL/FICOM/FICOMP/FISUB/FISUBR/FIDIV/FIDIVR/FILD mw"}, { 0, 0x4e7, 0, "FPU_LD80_287 " }, { 0, 0x4e8, 0, "FPU_LD3264_287" }, { 0, 0x4ee, 0, "FPU_LD80_387 " }, { 0, 0x4f0, 0, "FPU_LOAD_WAIT " }, { 0, 0x4f4, 0, "FPU_LOAD_IRQT " }, { 0, 0x4f8, 0, "FPU_LOAD_ERRT " }, { 0, 0x4fc, 0, "FPU_LOAD_CORE " }, { 0, 0x503, 0, "FPU_LOAD_CORWA" }, { 0, 0x506, 0, "FPU_LOAD_LOOP " }, { 0, 0x50c, 0, "FPU_LOAD_DONE " }, { 0, 0x50e, 0, "FPU_LD80_DONE " }, { 0, 0x514, 0, "FPU_ERROR2 " }, { 0, 0x516, 0, "FLDCW " }, { 0, 0x518, 0, "FLDCW_COR_WAIT" }, { 0, 0x51c, 0, "FPU_LD3264_387" }, { 0, 0x51f, 0, "FPU_LD3264_WAI" }, { 0, 0x523, 0, "FPU_LD3264_IRQ" }, { 0, 0x527, 0, "FPU_LD3264_ERR" }, { 0, 0x52a, 0, "FPU_LD3264_COR" }, { 0, 0x531, 0, "FPU_LD32 " }, { 0, 0x533, 0, "FPU_LD32_WAIT " }, // Why wait after the data has been transferred? CPU bug? { 0, 0x536, 0, "#NM " }, //pla4 ??????1???<3B><38><39><3C><3D> ??????01??<3B><38><39><3C><3D> ??????1?1?<34> 0000 10" }, coprocessor not available exception {1, 0x538, 0, " FBSTP/FSTP mt"}, {1, 0x53c, 0, " FST/FSTP/FIST/FISTP md"}, {1, 0x540, 0, " FST/FSTP/FISTP mq"}, {1, 0x544, 0, " FIST/FISTP mw"}, { 0, 0x54b, 0, "FPU_ERROR ", }, { 0, 0x54d, 0, "FPU_ST80_287 " }, { 0, 0x54e, 0, "FPU_ST3264_287" }, { 0, 0x554, 0, "FPU_ST80_387 " }, { 0, 0x555, 0, "FPU_ST3264_387" }, { 0, 0x556, 0, "FPU_STORE_WAIT" }, { 0, 0x55a, 0, "FPU_STORE_IRQT" }, { 0, 0x55e, 0, "FPU_STORE_ERRT" }, { 0, 0x562, 0, "FPU_STORE_CORE" }, { 0, 0x568, 0, "FPU_STORE_CORW" }, { 0, 0x56f, 0, "FPU_STORE_LOOP" }, { 0, 0x575, 0, "FPU_STORE_DONE" }, { 0, 0x578, 0, "FPU_STORE_287 " }, { 0, 0x57d, 0, "FPU_STORE_ABRT" }, {0, 0x580, 2, " p MOV ES/DS/FS/GS,rw"}, {0, 0x585, 2, " p MOV SS,rw"}, { 0, 0x58a, 0, "PM_LD_DSESFSGS" }, // only called in protected mode, called before load of DS/ES/FS/GS happens { 0, 0x58e, 0, "PM_LD_SS " }, { 0, 0x592, 0, "NULL_SELECTOR " }, { 0, 0x595, 0, "PM_LES " }, { 0, 0x59a, 0, "PM_LSS " }, { 0, 0x59f, 0, "PM_LDS " }, { 0, 0x5a4, 0, "PM_LFS_LGS " }, { 0, 0x5ac, 0, "JUMP_FAR_PM " }, { 0, 0x5b3, 0, "JUMP_FAR_PM_GATE" }, { 0, 0x5b8, 0, "CALL_FAR_PM_GATE" }, { 0, 0x5bb, 0, "GENERAL_FAULTP" }, { 0, 0x5bd, 0, "CALLGATE286 " }, { 0, 0x5be, 0, "CALLGATE386 " }, { 0, 0x5c4, 0, "LD_DES_SSFSGS " }, { 0, 0x5c9, 0, "LD_DESCRIPTOR " }, { 0, 0x5ce, 0, "LD_DESCRIPTOR2" }, { 0, 0x5d3, 0, "PRESENT_TSS " }, // Available (<1F>) or Busy (<1E>) { 0, 0x5d5, 0, "PROT_TESTS_PASSED" }, { 0, 0x5d8, 0, "PROT_TESTS_CMN" }, { 0, 0x5da, 0, "PROT_TESTS_PASSED2" }, { 0, 0x5df, 0, "PROT_TESTS_P16" }, { 0, 0x5e0, 0, "CALL_FAR_PM " }, { 0, 0x5ec, 0, "MORE_PRIV16 " }, { 0, 0x5f0, 0, "GENERAL_FAUL2P" }, { 0, 0x5f2, 0, "PUSH_V86_SREGS" }, // Push(GS) code in https://www.felixcloutier.com/x86/intn:into:int3:int1 ? { 0, 0x5fb, 0, "MORE_PRIVILEGE" }, // CALL MORE-PRIVILEGE case in PRM { 0, 0x602, 0, "FOUND_STACK " }, // We have found the offset of the SS/eSP pair in the TSS { 0, 0x60b, 0, "MORE_PRIV2 " }, { 0, 0x613, 0, "MORE_PRIV3 " }, { 0, 0x615, 0, "MORE_PRIV_INT " }, { 0, 0x619, 0, "COPY_PARAMS " }, { 0, 0x61e, 0, "COPY_PRMS_LOOP" }, { 0, 0x622, 0, "COPY_PRMS_DONE" }, { 0, 0x623, 0, "COPY_PRMS_SKIP" }, { 0, 0x62b, 0, "NO_ERROR_CODE " }, { 0, 0x633, 0, "MORE_PRIV_DONE" }, { 0, 0x63b, 0, "ZERO_V86_SREGS" }, // GS := 0 code in https://www.felixcloutier.com/x86/intn:into:int3:int1 ? { 0, 0x63f, 0, "IRETd_V86 " }, // Returns to? from? v86 mode? real mode? { 0, 0x657, 0, "IRETd_V86_LOOP" }, { 0, 0x65c, 0, "TASK_RETURN " }, // TASK-RETURN described in https ://www.felixcloutier.com/x86/iret:iretd:iretq ? { 0, 0x671, 0, "LOAD_TASK_16B " }, {3, 0x673,38, " p IRETd"}, // cycle count is 38/82/TS/60 { 0, 0x67f, 0, "RETF_PM " }, { 0, 0x686, 0, "RETF_OUTER_LEV" }, { 0, 0x699, 0, "RETF_OL_ES " }, { 0, 0x69d, 0, "RETF_OL_DS " }, { 0, 0x6a1, 0, "RETF_OL_FS " }, { 0, 0x6a5, 0, "RETF_OL_GS " }, { 0, 0x6a8, 0, "ZERO_SLCTR_AR " }, {1, 0x6aa,21, " p ARPL mw,rw"}, { 0, 0x6b3, 0, "ARPL_FAILED " }, {0, 0x6b6,20, " p ARPL rw,rw"}, {1, 0x6be,27, " p LTR mw"}, {0, 0x6c3,23, " p LTR rw"}, { 0, 0x6c5, 0, "LTR_COMMON " }, {1, 0x6cd, 2, " p STR mw"}, {0, 0x6cf, 2, " p STR rw"}, {1, 0x6d1,24, " p LLDT mw"}, {0, 0x6d6,20, " p LLDT rw"}, { 0, 0x6c8, 0, "LLDT_COMMON " }, { 0, 0x6dd, 0, "LLDT_TEST_PASS" }, {1, 0x6e0, 2, " p SLDT mw"}, {0, 0x6e2, 2, " p SLDT rw"}, {1, 0x6e4,16, " p LAR rv,mv"}, {0, 0x6e7,15, " p LAR rv,rv"}, {1, 0x6ea,21, " p LSL rv,mv"}, // cycle count is 21/26 {0, 0x6ec,20, " p LSL rv,rv"}, // cycle count is 20/25 { 0, 0x6ee, 0, "LSL_HELPER "}, { 0, 0x6f5, 0, "LSL_GRANULARITY_COARSE" }, { 0, 0x6fd, 0, "LSL_GRANULARITY_FINE" }, {1, 0x700,11, " p VERR mw"}, {0, 0x703,10, " p VERR rw"}, {1, 0x706,16, " p VERW mw"}, {0, 0x709,15, " p VERW rw"}, { 0, 0x70c, 0, "LAR_LSL_VERRWM" }, { 0, 0x70e, 0, "LAR_LSL_VERRWR" }, { 0, 0x70f, 0, "LAR_LSL_VERRW " }, { 0, 0x71a, 0, "LAR_VERRW_SUCCEEDED" }, //pla4 0????01011<30> 0????01100<30> 0????1011?<30><32> 0????10?0?<32> 0????10?1?<33> 0????1101?<30> 0????1?000<30> 0????1?01?<32> 0?????001?<30> 0?????010?<30> 0??????001<30> ?????1111?<32> ?????111??<30> 0000 10" }, { 0, 0x71c, 0, "TASKGATE " }, { 0, 0x71f, 0, "AVAIL_TSS " }, { 0, 0x724, 0, "SAVE_TASK " }, { 0, 0x72b, 0, "SAVE_TASK_16 " }, { 0, 0x72e, 0, "SAVE_TASK_COMM" }, { 0, 0x737, 0, "SAVE_TASK_LOOP" }, { 0, 0x73f, 0, "CALL_SAVE_TASK" }, { 0, 0x743, 0, "AVAIL_TSS_PR " }, { 0, 0x749, 0, "SWITCH_TASK " }, { 0, 0x750, 0, "LOAD_TASK " }, { 0, 0x758, 0, "TR_BACKLINK_OK" }, { 0, 0x75a, 0, "LOAD_TASK_32 " }, { 0, 0x764, 0, "LOAD_TASK_16 " }, { 0, 0x765, 0, "LOAD_TASK_16A " }, { 0, 0x765, 0, "LOAD_TASK_COMM" }, // Common to both 16-bit and 32-bit LOAD_TASK { 0, 0x773, 0, "LOAD_TASK_LOOP" }, { 0, 0x787, 0, "LOAD_TASK_NOPG" }, { 0, 0x78c, 0, "NOT_NESTED_TSK" }, { 0, 0x792, 0, "SET_TSKSWTCHED" }, { 0, 0x795, 0, "WRITE_BACK_CR0" }, { 0, 0x798, 0, "TASK_FINAL_V86" }, { 0, 0x798, 0, "TASK_FV86_LOOP" }, { 0, 0x7ab, 0, "TASK_FINAL_PM " }, { 0, 0x7d0, 0, "HANDLE_TS_BP " }, // Last phase of task switching - handle breakpoints { 0, 0x7d4, 0, "ADJ_STACK_DONE" }, { 0, 0x7d7, 0, "TSKF_NO_ERRCOD" }, { 0, 0x7e3, 0, "ADJ_STACK_16 " }, { 0, 0x7e5, 0, "NULL_SELECTOR2" }, { 0, 0x7e8, 0, "AVAIL_TSS_NP " }, { 0, 0x7eb, 0, "NO_DEBUG_BP " }, { 0, 0x7ec, 0, "CLI_STI " }, {0, 0x7ef, 2, " CLC/STC/CLD/STD/CMC"}, {2, 0x7f2, 4, " p PUSHFd"}, {0, 0x7f7, 3, " CLI/STI"}, // cycle count is 2 for STI? {2, 0x7f9, 4, " r PUSHFd"}, {3, 0x7fb, 5, " r POPFd"}, {0, 0x7fd,37, " r INT ib"}, {3, 0x7ff,22, " r IRETd"}, // cycle count is 22/38 { 0, 0x801, 0, "OVERLONG_INST "}, //small pla 010100 01 ? 0011011" }, {3, 0x803, 5, " p POPFd"}, {0, 0x808,59, " p INT ib"}, // cycle count is 59/99/119/TS { 0, 0x80a, 0, "IRET_REAL_MODE" }, {0, 0x816,33, " INT 3"}, // cycle count is 33/59/99/119/TS {1, 0x818,10, " BOUND rv,m2v"}, // cycle count in no-jump case { 0, 0x822, 0, "#BR " }, //small pla ?????? 11 ? 0011010" }, bound range exceeded { 0, 0x824, 0, "DIVIDE_ERROR " }, //small pla ?????? 11 ? 0011010" }, {0, 0x827, 3, " INTO"}, // cycle count is 35/3/59/99/119/TS { 0, 0x82a, 0, "NO_OVERFLOW " }, { 0, 0x82b, 0, "#UD " }, // invalid opcode { 0, 0x82d, 0, "HARDWARE_IRQ " }, //small pla 11010? 01 ? 0011011" }, { 0, 0x836, 0, "NMI " }, //small pla ?0010? 01 ? 0011011" }, { 0, 0x839, 0, "TRIPLE_FAULT " }, //small pla ?????1 00 ? 0000000" }, { 0, 0x83a, 0, "TRIPLE_FT_WAIT" }, { 0, 0x83f, 0, "#DF " }, //small pla ?????? 00 1 0100010" }, double fault {0, 0x844, 0, "NO_PRIVILEGE " }, {0, 0x849, 0, " unused?"}, { 0, 0x857, 0, "ACCESS_VIOLATI" }, //small pla ?????? 00 ? 0010110" }, { 0, 0x85b, 0, "#GP(0) " }, { 0, 0x85d, 0, "#GP/#TS(I0,E0)" }, { 0, 0x85e, 0, "#GP/#TS(SIGMA)" }, //pla4 ?????0011?<24> ?????01001<24> 0000 10" }, { 0, 0x860, 0, "#GP(SIGMA) " }, { 0, 0x862, 0, "#SS(0) " }, { 0, 0x863, 0, "#SS(SIGMA) " }, { 0, 0x865, 0, "#GP(I1,E0) " }, // #GP((TMP_TR & -4) | 2) general fault with EXT = 0, I = 1 => fault with gate descriptor in the IDT { 0, 0x866, 0, "#GP(SIGMA | 2)" }, // I = 1 { 0, 0x868, 0, "#TS(SIGMA) " }, // #TS(SIGMA) { 0, 0x86a, 0, "#SS(I0,E0) " }, // #SS(TMP_TR & -4) { 0, 0x86d, 0, "FAULT_SUPPRESS" }, { 0, 0x86e, 0, "LAR_LSL_VERRW_NULL_SELECTOR" }, { 0, 0x870, 0, "#NP(I0,E0) " }, // #NP(TMP_TR & -4) { 0, 0x871, 0, "#NP(I1,E0) " }, // #NP((TMP_TR & -4)|2) { 0, 0x873, 0, "NP_COMMON " }, // Common to both #NP with I=0 and I=1 { 0, 0x874, 0, "FAULT_ERR_CODE" }, { 0, 0x87b, 0, "EXT_BIT_DONE " }, { 0, 0x882, 0, "STRING_CORRECT" }, { 0, 0x889, 0, "STRCORR_DOWN " }, { 0, 0x88a, 0, "STRCORR_LOOP " }, { 0, 0x890, 0, "FAULT " }, { 0, 0x893, 0, "FLAGS_OK " }, { 0, 0x89a, 0, "RESUME_FLAG_OK" }, { 0, 0x89e, 0, "INTERRUPT_X " }, { 0, 0x89f, 0, "INTERRUPT " }, // Software or hardware interrupt (vector entries are 4 byte far pointers) { 0, 0x8b0, 0, "INTERRUPT_PM " }, // Software or hardware interrupt in protected or v86 mode (vector entries are 8 byte gate descriptors) { 0, 0x8ba, 0, "INTERRUPT_COMM" }, { 0, 0x8bf, 0, "INTERRUPT_SW " }, { 0, 0x8c2, 0, "INTGATE286 " }, { 0, 0x8c3, 0, "TRAPGATE286 " }, { 0, 0x8cb, 0, "INTGATE386 " }, { 0, 0x8cc, 0, "TRAPGATE386 " }, { 0, 0x8d5, 0, "TRAP_INT_GATE " }, // common to 286/386 trap/interrupt gates { 0, 0x8d5, 0, "PUSH_INT_FRAME" }, // pushes flags, return address and error code { 0, 0x8e3, 0, "TRAP_INT_DONE " }, // end of trap/interrupt gate code { 0, 0x8e5, 0, "PUSH_ERRORCODE" }, // pushes the error code onto the stack for faults { 0, 0x8e9, 0, "PAGE_FAULT " }, //small pla ?????? 00 0 1011010" }, { 0, 0x8ea, 0, "PAGE_FAULTLOOP" }, {0, 0x8f6, 0, " LOADALL386"}, // don't know cycle count { 0, 0x902, 0, "LOADALL_LOOP1 " }, { 0, 0x90b, 0, "LOADALL_LOOP2 " }, { 0, 0x917, 0, "LOADALL_LOOP3 " }, { 0, 0x91c, 0, "LOADALL_LOOP4 " }, { 0, 0x932, 0, "LOADALL_FINAL " }, { 0, 0x939, 0, "LOADALL_PAGING" }, {0, 0x93c, 0, " ICEBP"}, // don't know cycle count { 0, 0x93f, 0, "SINGLE_STEP " }, //small pla ???0?? 01 ? 0011011" }, single stepping via trap flag { 0, 0x941, 0, "BREAKPOINT " }, //small pla ??11?? 01 ? 0011011" }, comes in via small pla when DR0-DR3 are hit? Also jumped to from microcode for task switch breakpoint { 0, 0x943, 0, "BREAKPOINT_CMN" }, // Breakpoint code common to software breakpoints (ICEBP) and hardware/signal breakpoints (like debug register condition getting hit) { 0, 0x94f, 0, "ICE_SINGLESTEP" }, // SINGLE_STEP handled by ICE { 0, 0x953, 0, "ICE_PIN " }, //small pla ??011? 01 ? 0011011" }, Enter ICE mode via ICE# pin like SMI# pin? { 0, 0x95a, 0, "ICE_PIN_LOOP " }, { 0, 0x95e, 0, "STOREALL16 " }, { 0, 0x961, 0, "STOREALL " }, { 0, 0x95e, 0, "STOREALL_COMM " }, { 0, 0x970, 0, "STOREALL_LOOP1" }, { 0, 0x980, 0, "STOREALL_LOOP2" }, { 0, 0x981, 0, "STOREALL_LOOPS" }, { 0, 0x989, 0, "STOREALL_LOOP3" }, { 0, 0x993, 0, "STOREALL_LOOP4" }, { 0, 0x99a, 0, "STOREALL_L4_ST" }, { 0, 0x9a6, 0, "BOOTUP " }, { 0, 0x9a7, 0, "BOOTUP_LOOP1 " }, { 0, 0x9ab, 0, "BOOTUP_LOOP2 " }, { 0, 0x9af, 0, "BOOTUP_LOOP3 " }, { 0, 0x9bc, 0, "BOOTUP_JUMP " }, // Jump to initial boot CS:IP (BASE=0xffff0000 LIMIT=0xffff):0x0000fff0 aka linear address 0xfffffff0 {-1, -1, -1, ""}}; class Bitset { public: Word _mask; Word _bits; Word _output; }; class Bitset1 { public: DWord _mask; DWord _bits; Word _output; }; class Bitset4 { public: Word _mask; Word _bits; DWord _output; }; class Program : public ProgramBase { public: void dorom1() { String input1 = File("rom1_input_new.txt", true).contents(); String output1 = File("rom1_output_new.txt", true).contents(); Array mask1(175); Array bits1(175); Array outputs1(175); Array ored1(524288); for (int r = 0; r < 175; ++r) { int m = 0; int b = 0; for (int i = 0; i < 19; ++i) { if (input1[r*21 + i] != '.') m += 1 << i; if (input1[r*21 + i] == '1') b += 1 << i; } mask1[r] = m; bits1[r] = b; int o = 0; for (int i = 0; i < 12; ++i) { if (output1[r*14 + i] == '1') o += 1 << (11 - i); } outputs1[r] = o; } for (int o = 0; o < 524288; ++o) { int v = 0; for (int row = 0; row < 175; ++row) { if ((o & mask1[row]) == bits1[row]) v |= outputs1[row]; } ored1[o] = v; } for (int n = 0; n < 175; ++n) { int o; for (o = 0; o < 524288; ++o) { int v = 0; for (int row = 0; row < 175; ++row) { if (row == n) continue; if ((o & mask1[row]) == bits1[row]) v |= outputs1[row]; } if (v != ored1[o]) break; } if (o == 524288) console.write(decimal(n) + " was redundant.\n"); } Array bitsets1(524288); for (int x = 0; x < 0xfff; ++x) { int nbitsets1 = 0; for (int o = 0; o < 524288; ++o) { if (ored1[o] == x) { bitsets1[nbitsets1]._mask = 0x7ffff; bitsets1[nbitsets1]._bits = o; bitsets1[nbitsets1]._output = ored1[o]; ++nbitsets1; } } while (true) { bool found = false; //console.write(decimal(nbitsets1) + "\n"); for (int o = nbitsets1 - 1; o >= 1; --o) { for (int o1 = o - 1; o1 >= 0; --o1) { if (bitsets1[o]._mask != bitsets1[o1]._mask || bitsets1[o]._output != bitsets1[o1]._output) continue; DWord b = bitsets1[o]._bits ^ bitsets1[o1]._bits; if ((b & (b-1)) == 0) { found = true; bitsets1[o1]._mask &= ~b; bitsets1[o1]._bits &= ~b; for (int o2 = o; o2 < nbitsets1 - 1; ++o2) { bitsets1[o2]._mask = bitsets1[o2 + 1]._mask; bitsets1[o2]._bits = bitsets1[o2 + 1]._bits; bitsets1[o2]._output = bitsets1[o2 + 1]._output; } --nbitsets1; if (o == nbitsets1) break; } } } if (!found) break; } for (int o = 0; o < nbitsets1; ++o) { for (int b = 0; b < 19; ++b) { if ((bitsets1[o]._mask & (1 << b)) == 0) console.write("?"); else if ((bitsets1[o]._bits & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write(" "); for (int b = 11; b >= 0; --b) { if ((bitsets1[o]._output & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write(" "); console.write("\n"); } } } void dopla4() { String input4 = File("pla4_input_new.txt", true).contents(); String output4 = File("pla4_output_new.txt", true).contents(); Array mask4(160); Array bits4(160); Array outputs4(160); Array ored4(65536); for (int r = 0; r < 160; ++r) { int m = 0; int b = 0; for (int i = 0; i < 16; ++i) { if (input4[r*18 + i] != '.') m += 1 << i; if (input4[r*18 + i] == '1') b += 1 << i; } mask4[r] = m; bits4[r] = b; int o = 0; for (int i = 0; i < 18; ++i) { if (output4[r*20 + i] == '1') o += 1 << (17 - i); } outputs4[r] = o; } for (int o = 0; o < 65536; ++o) { int v = 0; for (int row = 0; row < 160; ++row) { if ((o & mask4[row]) == bits4[row]) v |= outputs4[row]; } ored4[o] = v; } //for (int n = 0; n < 160; ++n) { // int o; // for (o = 0; o < 65536; ++o) { // int v = 0; // for (int row = 0; row < 160; ++row) { // if (row == n) // continue; // if ((o & mask4[row]) == bits4[row]) // v |= outputs4[row]; // } // if (v != ored4[o]) // break; // } // if (o == 65536) // console.write(decimal(n) + " was redundant.\n"); //} Array bitsets4(65536); for (int x = 0; x < 262144; ++x) { int nbitsets4 = 0; for (int o = 0; o < 65536; ++o) { if (ored4[o] == x) { bitsets4[nbitsets4]._mask = 0xffff; bitsets4[nbitsets4]._bits = o; bitsets4[nbitsets4]._output = ored4[o]; ++nbitsets4; } } while (true) { bool found = false; //console.write(decimal(nbitsets1) + "\n"); for (int o = nbitsets4 - 1; o >= 1; --o) { for (int o1 = o - 1; o1 >= 0; --o1) { if (bitsets4[o]._mask != bitsets4[o1]._mask || bitsets4[o]._output != bitsets4[o1]._output) continue; DWord b = bitsets4[o]._bits ^ bitsets4[o1]._bits; if ((b & (b-1)) == 0) { found = true; bitsets4[o1]._mask &= ~b; bitsets4[o1]._bits &= ~b; for (int o2 = o; o2 < nbitsets4 - 1; ++o2) { bitsets4[o2]._mask = bitsets4[o2 + 1]._mask; bitsets4[o2]._bits = bitsets4[o2 + 1]._bits; bitsets4[o2]._output = bitsets4[o2 + 1]._output; } --nbitsets4; if (o == nbitsets4) break; } } } if (!found) break; } for (int o = 0; o < nbitsets4; ++o) { for (int b = 0; b < 16; ++b) { if ((bitsets4[o]._mask & (1 << b)) == 0) console.write("?"); else if ((bitsets4[o]._bits & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write(" "); for (int b = 17; b >= 0; --b) { if ((bitsets4[o]._output & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write("\n"); } } } String printuop(uint64_t u) { static const char* chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&"; String line; if (u == 0) return "====================================="; for (int i = 0; i < 37; ++i) { if ((u & (1LL << i)) != 0) { line += codePoint(chars[i]); } else line += " "; } return line; } void run() { dorom1(); #if 0 dopla4(); #endif String inputL = File("bits_l.py", true).contents(); String inputR = File("bits_r.py", true).contents(); String outputL = File("bits_addr_l.py", true).contents(); String outputR = File("bits_addr_r.py", true).contents(); Array mask(368); Array bits(368); Array outputs(368); Array ored(8192); //Array oredL(8192); //Array oredR(8192); for (int row = 0; row < 368; ++row) { mask[row] = 0; bits[row] = 0; outputs[row] = 0; } for (int row = 0; row < 368; ++row) { String input = inputL; String output = outputL; int r = row; if (row >= 184) { input = inputR; output = outputR; r -= 184; } int m = 0; int b = 0; for (int i = 0; i < 13; ++i) { if (input[r*58 + i*4 + 10] == '1' || input[r*58 + i*4 + 12] == '1') m += 1 << (12 - i); if (input[r*58 + i*4 + 12] == '1') b += 1 << (12 - i); } mask[row] = m; bits[row] = b; int o = 0; for (int i = 0; i < 16; ++i) { if (output[r*38 + i*2 + 10] == '1') o += 1 << i; } outputs[row] = o; } for (int o = 0; o < 8192; ++o) { int v = 0; for (int row = 0; row < 368; ++row) { if ((o & mask[row]) == bits[row]) v |= outputs[row]; } ored[o] = v; if ((v & 0xfff) >= 2560) { console.write("ored[" + hex(o, 4, false) + "] = " + hex(v, 4, false) + "\n"); } //int vL = 0; //for (int row = 0; row < 184; ++row) { // if ((o & mask[row]) == bits[row]) // vL |= outputs[row]; //} //oredL[o] = vL; //int vR = 0; //for (int row = 184; row < 368; ++row) { // if ((o & mask[row]) == bits[row]) // vR |= outputs[row]; //} //oredR[o] = vR; //ored[o] = vL | vR; } Array bitsets(8192); Array data(256*10*37); String s = File("Image (3).raw", true).contents(); for (int row = 0; row < 37; ++row) { for (int y = 0; y < 10; ++y) { for (int x = 0; x < 256; ++x) { data[row + (x+y*256)*37] = (s[row*256*10 + y*256 + (x^1)] == 0 ? 0x00 : 0xff); } } } #if 0 for (int x = 0; x < 2560; ++x) { bool empty = true; for (int row = 0; row < 37; ++row) { if (data[row + x*37] != 0) empty = false; } if (empty) { for (int row = 0; row < 37; ++row) { data[row + x*37] = 0x80; } int yy = x/256; int xx = (x & 0xff) ^1; for (int i = 0; i < 8; ++i) printf("%c", ((xx >> (7 - i)) & 1) + '0'); printf(" "); printf("%c\n", yy + 'A'); } } #endif //for (int row = 0; row < 37; ++row) { // String s = File("blobs\\blob_row_" + decimal(row, 2) + ".txt", true).contents(); // int p = 0; // for (int y = 0; y < 10; ++y) { // for (int x = 0; x < 256; ++x) { // //data[x+y*256+row*2560] = s[p]; // //data[row + (x*10+y)*37] = s[p]; // data[row + (x+y*256)*37] = (s[p] == '0' ? 0x00 : 0xff); // ++p; // } // p += 2; // } //} File("blob.raw").openWrite().write(data); //Array ent(37*37); //for (int start = 0; start < 37; ++start) { // for (int end = 0; end < start; ++end) { // printf(" "); // ent[end + start*37] = 0; // } // for (int end = start; end < 37; ++end) { // uint64_t value[2560]; // uint64_t count[2560]; // int used = 0; // for (int p = 0; p < 2560; ++p) { // uint64_t v = 0; // for (int bit = start; bit <= end; ++bit) // if (data[p*37 + bit] != 0) // v += (1 << (bit - start)); // int found = -1; // for (int search = 0; search < used; ++search) // if (value[search] == v) { // found = search; // break; // } // if (found == -1) { // found = used; // value[found] = v; // count[found] = 0; // ++used; // } // ++count[found]; // } // double entropy = 0; // for (int i = 0; i < used; ++i) { // double probability = count[i]/2560.0; // entropy -= probability*log(probability)/log(2); // } // double entropy_per_bit = entropy/(end + 1 - start); // printf("%0.2f ",entropy_per_bit); // ent[end + start*37] = static_cast(entropy_per_bit*0xff); // } // printf("\n"); //} //File("entropy.raw").openWrite().write(ent); #if 0 for (int x = 0; x < 2560 - 2; ++x) { for (int r1p = 0; r1p < 37 - 7; ++r1p) { for (int r2p = 0; r2p < 37 - 7; ++r2p) { int dst[3]; int src[3]; for (int y = 0; y < 3; ++y) { dst[y] = 0; for (int b1 = 0; b1 < 7; ++b1) if (data[(x + y)*37 + b1 + r1p] != 0) dst[y] += (1 << b1); src[y] = 0; for (int b2 = 0; b2 < 7; ++b2) if (data[(x + y)*37 + b2 + r2p] != 0) src[y] += (1 << b2); } //if (dst[0] == src[1] && dst[1] == src[2] && dst[2] == src[0] && dst[0] != dst[1] && dst[1] != dst[2] && dst[2] != dst[0]) { if (dst[0] == src[2] && dst[1] == src[0] && dst[2] == src[1] && dst[0] != dst[1] && dst[1] != dst[2] && dst[2] != dst[0]) { printf("Potential XCHG at %03x offsets %i,%i regnums %02x,%02x,%02x\n",2559 - x - 2,r1p,r2p, dst[0], dst[1], dst[2]); } } } } #endif int usedS[64]; int usedD[128]; int usedA[64]; int usedAJ[128]; int usedBus[64]; int usedOp[8]; int usedSub[4]; int lastS[64]; int lastD[128]; int lastA[64]; int lastAJ[128]; int lastBus[64]; for (int i = 0; i < 64; ++i) { usedS[i] = 0; usedD[i] = 0; usedD[i + 64] = 0; usedA[i] = 0; usedAJ[i] = 0; usedAJ[i + 64] = 0; usedBus[i] = 0; } for (int i = 0; i < 4; ++i) { usedOp[i] = 0; usedOp[i + 4] = 0; usedSub[i] = 0; } String regnames_source[64]; for (int i = 0; i < 64; ++i) regnames_source[i] = " "; //"[-" + hex(i,2,false) + "-]"; String regnames_dest[128]; for (int i = 0; i < 128; ++i) regnames_dest[i] = " "; //"(-" + hex(i, 2, false) + "-)"; String regnames_alu[128]; for (int i = 0; i < 64; ++i) regnames_alu[i] = " "; //"<-" + hex(i, 2, false) + "->"; String alujump_names[128]; for (int i = 0; i < 128; ++i) alujump_names[i] = " "; //"{-" + hex(i, 2, false) + "-}"; String busop_names[64]; for (int i = 0; i < 64; ++i) busop_names[i] = " "; //<" + hex(i, 2, false) + ">"; String opnames[8]; for (int i = 0; i < 8; ++i) opnames[i] = " "; //[" + hex(i, 1, false) + "]"; String subopnames[4]; for (int i = 0; i < 4; ++i) subopnames[i] = " "; //(" + hex(i, 1, false) + ")"; String testnames[64]; for (int i = 0; i < 64; ++i) testnames[i] = "<" + hex(i, 2, false) + ">"; regnames_source[0x00] = "EAX "; // 3 AAA/AAS/DAA/DAS and REP STOS Could be EAX - STOS copies to OPR_W but that needs to know size anyway regnames_dest [0x00] = "EAX "; // 3 regnames_dest [0x40] = "AX "; // 2 AAA/AAS and FSTSW AX regnames_alu [0x00] = "EAX "; // 1 902 regnames_source[0x01] = "ECX "; // 4 rot/SHxD // regnames_dest [0x01] = "ECX "; // regnames_dest [0x41] = "CX "; regnames_alu [0x01] = "ECX "; // 2 rot regnames_source[0x02] = "EDX "; // 8 regnames_dest [0x02] = "EDX "; // 1 BOOTUP // regnames_dest [0x42] = "DX "; regnames_alu [0x02] = "EDX "; // regnames_source[0x03] = "EBX "; // regnames_dest [0x03] = "EBX "; // regnames_dest [0x43] = "BX "; regnames_alu [0x03] = "EBX "; regnames_source[0x04] = "ESP "; // 25 regnames_dest [0x04] = "ESP "; // 2 // regnames_dest [0x44] = "SP "; regnames_alu [0x04] = "ESP "; // 1 60C regnames_source[0x05] = "EBP "; // 4 ENTER/LEAVE regnames_dest [0x05] = "EBP "; // 2 ENTER/LEAVE regnames_dest [0x45] = "BP "; // 2 ENTER/LEAVE regnames_alu [0x05] = "EBP "; regnames_source[0x06] = "ESI "; // 10 [REP] MOVS/[REP] CMPS/[REP] LODS/[REP] OUTS // regnames_dest [0x06] = "ESI "; // regnames_dest [0x46] = "SI "; regnames_alu [0x06] = "ESI "; // 2 regnames_source[0x07] = "EDI "; // 19 PUSHAd(?)/[REP] MOVS/[REP] CMPS/[REP] SCAS/[REP] STOS/[REP] INS // regnames_dest [0x07] = "EDI "; // regnames_dest [0x47] = "DI "; regnames_alu [0x07] = "EDI "; // 2 regnames_source[0x08] = "EIP "; // 44 regnames_dest [0x08] = "EIP "; // 3 RPTI, DR/TR, ??? - always used with [-16-] regnames_dest [0x48] = "IP "; // 1 649 regnames_alu [0x08] = "IMM8 "; // 10 JCXZ/LOOP/LOOPE/LOOPNE/Jcond/JMP/CALL/ENTER/VERR/VERW regnames_source[0x09] = "EFLAGS"; // 22 LAHF , RPTI, regnames_dest [0x09] = "EFLAGS"; // 10 regnames_dest [0x49] = "FLAGS "; // 3 IRETd/POPFd/INT ib regnames_alu [0x09] = "IMM "; // 12 regnames_source[0x0A] = "CR0 "; // 30 MSW is the low 16 bits of CR0 regnames_dest [0x0A] = "CR0 "; // 7 // regnames_dest [0x4A] = " "; // regnames_alu [0x0A] = " "; regnames_source[0x0B] = "TMPB "; // 67 regnames_dest [0x0B] = "TMPB "; // 125 // regnames_dest [0x4B] = " "; regnames_alu [0x0B] = "TMPB "; // 96 regnames_source[0x0C] = "TMPC "; // 31 regnames_dest [0x0C] = "TMPC "; // 73 // regnames_dest [0x4C] = " "; regnames_alu [0x0C] = "TMPC "; // 52 regnames_source[0x0D] = "TMPD "; // 10 regnames_dest [0x0D] = "TMPD "; // 44 regnames_dest [0x4D] = "DESPTR"; // 7 LIDTGDT_COMMON/LD_SEGREG_PASS/PRESENT_TSS/PROT_TESTS_PASSED/PROT_TESTS_PASSED2/PASSED_0B_0D descriptor mentioned in dest of last SPTR regnames_alu [0x0D] = "TMPD "; // 37 regnames_source[0x0E] = "TMPE "; // 29 regnames_dest [0x0E] = "TMPE "; // 22 regnames_dest [0x4E] = "DESSDT"; // 6 LTR/? Either DESGDT or DESIDT depending on the Table Indictor bit in the selector? Which selector? SLCTR? source? // regnames_alu [0x0E] = " "; regnames_source[0x0F] = "TMPF "; // 9 Low 16 bits of TMPF are used for FP (opcode?). Bits 16-18 are used for error code regnames_dest [0x0F] = "TMPF "; // 11 // regnames_dest [0x4F] = " "; // regnames_alu [0x0F] = " "; regnames_source[0x10] = "FLAGSB"; // 8 regnames_dest [0x10] = "FLAGSB"; // 14 regnames_dest [0x50] = "AL "; // 5 SALC/DAA/DAS/AAM/AAD // regnames_alu [0x10] = " "; regnames_source[0x11] = "TMPH "; // 25 regnames_dest [0x11] = "TMPH "; // 18 // regnames_dest [0x51] = "CL "; // regnames_alu [0x11] = " "; regnames_source[0x12] = "TMPG "; // 43 regnames_dest [0x12] = "TMPG "; // 32 // regnames_dest [0x52] = "DL "; // regnames_alu [0x12] = " "; regnames_source[0x13] = "SLCTR2"; // 32 Related to SLCTR? regnames_dest [0x13] = "SLCTR2"; // 11 // regnames_dest [0x53] = "BL "; // regnames_alu [0x13] = " "; regnames_source[0x14] = "COUNTR"; // 63 regnames_dest [0x14] = "MDTMP4"; // 11 Could this be the same as (-1D-)/MDTMP? Some routines outside of mul/div seem to use [-1D-]/(-14-) as a temp. Maybe (-1D-) has special powers? regnames_dest [0x54] = "AH "; // 3 LAHF/AAM/AAD regnames_alu [0x14] = "0x3ddc0c2c"; // 1 9B8 Expected result of built-in self-test (BIST) regnames_source[0x15] = "PROTUN"; // 18 protection test unit regnames_dest [0x15] = "PROTUN"; // 59 // regnames_dest [0x55] = "CH "; regnames_alu [0x15] = "0x0303"; // 1 9B5 regnames_source[0x16] = "TMPeIP"; // 23 regnames_dest [0x16] = "TMPeIP"; // 9 // regnames_dest [0x56] = "DH "; regnames_alu [0x16] = "0x37fd7"; // 5 regnames_source[0x17] = "TMPeSP"; // 33 regnames_dest [0x17] = "TMPeSP"; // 7 // regnames_dest [0x57] = "BH "; regnames_alu [0x17] = "0x4000"; // 7 regnames_source[0x18] = "DR6 "; // 9 regnames_dest [0x18] = "DR6 "; // 9 regnames_dest [0x58] = "DESCSW"; // 5 Descriptor that uses base and limit from CS descriptor but is writeable regnames_alu [0x18] = "~0x200"; // 1 790 regnames_source[0x19] = "DR7 "; // 8 regnames_dest [0x19] = "DR7 "; // 7 regnames_dest [0x59] = "DESCOD"; // 23 Descriptor for eIP changes (DES_CS is only used for updating the CS descriptor) regnames_alu [0x19] = "8 "; // 3 regnames_source[0x1A] = "CSOPCD"; // 7 CSOPCD, TMPN and TMPO are only used by FSAVE. regnames_dest [0x1A] = "CSOPCD"; // 6 regnames_dest [0x5A] = "DESSTK"; // 24 Descriptor for stack reads/writes (DES_SS is only used for updating the stack descriptor) regnames_alu [0x1A] = "0x40 "; // 2 regnames_source[0x1B] = "FSVeIP"; // 2 regnames_dest [0x1B] = "FSVeIP"; // 7 // regnames_dest [0x5B] = " "; regnames_alu [0x1B] = "0xf0000"; // 2 regnames_source[0x1C] = "OPROFF"; // 12 regnames_dest [0x1C] = "OPROFF"; // 6 regnames_dest [0x5C] = "eSP "; // 39 regnames_alu [0x1C] = "0x0d "; // 9 regnames_source[0x1D] = "MDTMP "; // 15 quotient after division, product after multiplication? regnames_dest [0x1D] = "MDTMP "; // 7 one of the multiplier inputs? regnames_dest [0x5D] = "DES_OS"; // 37 strings, XLAT, - but used in "POP m" and SGDT with no ALU op - like IND_DS but "overrideable segment" (uses DS for bus operation unless a segment override is active, in which case use that segment) regnames_alu [0x1D] = "0x5d "; // 4 regnames_source[0x1E] = "SIGMA "; // 533 // regnames_dest [0x1E] = " "; regnames_dest [0x5E] = "DES_SR"; // 11 Like other IND_ registers but are written to when segment registers are updated regnames_alu [0x1E] = "0x800000f8"; // 3 regnames_source[0x1F] = "IMM "; // 36 // regnames_dest [0x1F] = " "; regnames_dest [0x5F] = "eIP "; // 9 regnames_alu [0x1F] = "0x800000fc"; // 5 regnames_source[0x20] = "ES "; // 5 regnames_dest [0x20] = "ES "; // 7 regnames_dest [0x60] = "DES_ES"; // 33 regnames_alu [0x20] = "0x70 "; // 2 regnames_source[0x21] = "CS "; // 49 regnames_dest [0x21] = "CS "; // 6 regnames_dest [0x61] = "DES_CS"; // 25 regnames_alu [0x21] = "0x73 "; // 1 9A9 regnames_source[0x22] = "SS "; // 26 regnames_dest [0x22] = "SS "; // 5 regnames_dest [0x62] = "DES_SS"; // 8 regnames_alu [0x22] = "0x1ff "; // 1 336 regnames_source[0x23] = "DS "; // 6 regnames_dest [0x23] = "DS "; // 6 regnames_dest [0x63] = "DES_DS"; // 5 regnames_alu [0x23] = "0x8200"; // 11 regnames_source[0x24] = "FS "; // 4 regnames_dest [0x24] = "FS "; // 4 regnames_dest [0x64] = "DES_FS"; // 4 regnames_alu [0x24] = "0x47 "; // 1 091 regnames_source[0x25] = "GS "; // 8 regnames_dest [0x25] = "GS "; // 4 regnames_dest [0x65] = "DES_GS"; // 4 regnames_alu [0x25] = "3 "; // 16 regnames_source[0x26] = "LDTR "; // 6 regnames_dest [0x26] = "LDTR "; // 4 regnames_dest [0x66] = "DESLDT"; // 5 regnames_alu [0x26] = "6 "; // 5 // regnames_source[0x27] = " "; // regnames_dest [0x27] = " "; regnames_dest [0x67] = "DESGDT"; // 3 regnames_alu [0x27] = "0xffff0000"; // 9 regnames_source[0x28] = "eAX_AL"; // 15 AAM/AAD/MUL/IMUL/DIV/IDIV/CWD/CDQ/[REP] SCAS/XLATB/STOS/OUT regnames_dest [0x28] = "eAX_AL"; // 7 MUL/IMUL/DIV/IDIV/[REP] LODS/XLATB/IN regnames_dest [0x68] = "DESIDT"; // 5 regnames_alu [0x28] = "0x60 "; // 2 regnames_source[0x29] = "TR "; // 9 regnames_dest [0x29] = "TR "; // 5 regnames_dest [0x69] = "DES_TR"; // 28 regnames_alu [0x29] = "0x7ff "; // 3 regnames_source[0x2A] = "eDX_AH"; // 6 SAHF/AAD/DIV/IDIV regnames_dest [0x2A] = "eDX_AH"; // 4 MUL/IMUL/DIV/IDIV/CWD/CDQ regnames_dest [0x6A] = "DESABS"; // 14 bus operation in which IND is placed on the address bus without any paging translation - used for halt/shutdown/interrupt acknowledge bus cycles and other debugging information placed on the address bus regnames_alu [0x2A] = "9 "; // 4 regnames_source[0x2B] = "CR2 "; // 1 378 Contains a value called Page Fault Linear Address (PFLA). When a page fault occurs, the address the program attempted to access is stored in the CR2 register. regnames_dest [0x2B] = "CR2 "; // 4 regnames_dest [0x6B] = "DES_IO"; // 33 used for access to IO ports DES_IO regnames_alu [0x2B] = "0x29 "; // 9 LDCNTR in reset (002) // regnames_source[0x2C] = " "; // regnames_dest [0x2C] = " "; regnames_dest [0x6C] = "DESERR"; // 1 ACCESS_VIOLATI - descriptor that caused the fault regnames_alu [0x2C] = "7 "; // 13 regnames_source[0x2D] = "OPR_R "; // 156 It's tempting to call both OPR_R and OPR_W just OPR, but they do seem to be separate: look at 07E - OPR_R is available here (used on uop after DLY in other instructions) and used at line 080 but OPR_W is overwritten with eIP... regnames_dest [0x2D] = "OPR_W "; // 102 ...however, on line 083 OPR_R is never copied to OPR_W. Maybe "wr" writes from OPR_R? // regnames_dest [0x6D] = " "; regnames_alu [0x2D] = "0x0f "; // 5 regnames_source[0x2E] = "IRF2 "; // 53 // regnames_dest [0x2E] = " "; // regnames_dest [0x6E] = " "; regnames_alu [0x2E] = "0x65 "; // 3 regnames_source[0x2F] = "BIST1 "; // 1 9B5 // regnames_dest [0x2F] = " "; // regnames_dest [0x6F] = " "; regnames_alu [0x2F] = "0x1f "; // 2 regnames_source[0x30] = "BIST2 "; // 1 9B7 // regnames_dest [0x30] = " "; // regnames_dest [0x70] = "DR0 "; regnames_alu [0x30] = "1 "; // 43 regnames_source[0x31] = "eCX "; // 11 regnames_dest [0x31] = "eCX "; // 16 // regnames_dest [0x71] = "DR1 "; regnames_alu [0x31] = "2 "; // 13 // regnames_source[0x32] = " "; regnames_dest [0x32] = "COUNTR"; // 60 IRF index? Temp related to [-14-]? // regnames_dest [0x72] = "DR2 "; regnames_alu [0x32] = "0x10 "; // 11 // regnames_source[0x33] = " "; // regnames_dest [0x33] = " "; // regnames_dest [0x73] = "DR3 "; regnames_alu [0x33] = "4 "; // 16 // regnames_source[0x34] = " "; // regnames_dest [0x34] = " "; // regnames_dest [0x74] = "TR4 "; regnames_alu [0x34] = "-1 "; // 10 regnames_source[0x35] = "SLCTR "; // 6 selector to load (pointer into LDT/GDT)? regnames_dest [0x35] = "SLCTR "; // 33 selector to load (pointer into LDT/GDT)? // regnames_dest [0x75] = "TR5 "; regnames_alu [0x35] = "-2 "; // 3 regnames_source[0x36] = "EA "; // 3 not eSI regnames_dest [0x36] = "eSI "; // 11 // regnames_dest [0x76] = "TR6 "; regnames_alu [0x36] = "0xffff"; // 39 // regnames_source[0x37] = "eDI "; regnames_dest [0x37] = "eDI "; // 13 // regnames_dest [0x77] = "TR7 "; regnames_alu [0x37] = "-4 "; // 8 regnames_source[0x38] = "0 "; // 106 regnames_dest [0x38] = "FLAGSL"; // 1 0DA SAHF regnames_dest [0x78] = "LATTTF"; // 1 PAGE_FAULT Related to paging linear address that triggered the fault // regnames_alu [0x38] = " "; regnames_source[0x39] = "IRF "; // 7 regnames_dest [0x39] = "IRF "; // 38 Indirect access to Register File regnames_dest [0x79] = "PGUNUS"; // 1 unused? Related to paging linear address that triggered the fault again (value ends up in CR2 anyway like LATTTF - could have had a different meaning here) regnames_alu [0x39] = "WORDSZ"; // 25 // regnames_source[0x3A] = " "; regnames_dest [0x3A] = "COUNT5"; // 6 COUNTR except that all but low 5 bits are masked off RCL/RCR/ENTER_COMMON/CALL_FAR_PM_GATE regnames_dest [0x7A] = "PFERRC"; // 2 PAGE_FAULT/unused? Related to paging page fault error code regnames_alu [0x3A] = "NEGWSZ"; // 22 negative word size in bytes (-2 or -4) (0xfffffffe or 0xfffffffc) regnames_source[0x3B] = "OPCODE"; // 8 As stored by FSAVE/FSTENV - 0 to 0x7ff // regnames_dest [0x3B] = " "; regnames_dest [0x7B] = "PDBR "; // 11 Page directory base register (aka CR3) - write to this to flush TLB cache regnames_alu [0x3B] = "INCREM"; // 32 eSI/eDI increment for string instructions (+/- 1/2/4) regnames_source[0x3C] = "SEGREG"; // 3 regnames_dest [0x3C] = "SEGREG"; // 9 // regnames_dest [0x7C] = " "; regnames_alu [0x3C] = "BITS_V"; // 21 one less than word size in bits (15 or 31) regnames_source[0x3D] = "DSTREG"; // 37 regnames_dest [0x3D] = "DSTREG"; // 30 regnames_dest [0x7D] = "PAGER5"; // 12 regnames_alu [0x3D] = "DSTREG"; // 12 regnames_source[0x3E] = "SRCREG"; // 21 regnames_dest [0x3E] = "SRCREG"; // 22 // regnames_dest [0x7E] = " "; regnames_alu [0x3E] = "SRCREG"; // 7 regnames_source[0x3F] = "-1 "; // 95 SALC // regnames_dest [0x3F] = " "; regnames_dest [0x7F] = " "; // 550 regnames_alu [0x3F] = "0 "; alujump_names[0x00] = "+-&|^ "; // 5 alujump_names[0x01] = "++--~-"; // 2 alujump_names[0x02] = "<<>>? "; // 13 alujump_names[0x03] = "CMPTST"; // 5 alujump_names[0x04] = "IMCS "; // 1 1BA IMUL Correct Sign. Corrects for sign regardless of opcode alujump_names[0x05] = "SERECO"; // 4 BTS/BTR/BTC SEt, REset, COmplement according to which opcode used. Actual operation is either ALU1 OR ALU2, ALU1 AND NOT ALU2 or ALU1 XOR ALU2. There's a shift in there too? alujump_names[0x06] = "SZ_EXT"; // 4 MOVZX/MOVSX/CBW/CWDE alujump_names[0x07] = "SZ_EX2"; // 1 1AC MUL/IMUL rm - binary operation. Correct upper part of multiplication for sign in IMUL case. Not sure how this is different from SZ_EXT alujump_names[0x08] = "AND "; // 84 ok alujump_names[0x09] = "OR "; // 41 probably not SUB - used to clear (or set?) resume flag in RPTI? - AND NOT? Also used in JMP cp alujump_names[0x0A] = "XOR "; // 13 alujump_names[0x0B] = "SIGN "; // 4 probably not CMP - BT/BTS/BTR/BTC/CWD/CDQ/77a SIGMA is sign-extension of input alujump_names[0x0C] = "ADD "; // 123 ok alujump_names[0x0D] = "ADC "; // 2 Used in AAM and AAD alujump_names[0x0E] = "SUB "; // 36 probably not ADC - SUB? alujump_names[0x0F] = "CMP "; // 8 porbably not SBB - SUB? CMP? alujump_names[0x10] = "SHIFT "; // 72 alujump_names[0x11] = "BITTST"; // 11 BT/BTS/BTR/BTC/BSF - does a shift and copies the lowest bit into the carry flag? alujump_names[0x12] = ">>< 0) in CLTS/HLT/LIDT/LGDT/LLDT/LMSW/CRn/DRn/TRn/LTR/LOADALL386, (PM && CPL > IOPL) in PORTIO_PROTCHK alujump_names[0x73] = "LJMPVM"; // 6 IRETd (p)/??? long jump only in virtual 8086 mode alujump_names[0x74] = "LJMPP "; // 17 long jump only in protected mode alujump_names[0x75] = "ICEENT"; // 2 ICE_SINGLESTEP/ICE_PIN - send some signal to ICE? Always happens right before STOREALL - enter ICE mode alujump_names[0x76] = "ICEEXT"; // 1 LOADALL386 - tell ICE that LOADALL completed successfully - exit ICE mode // alujump_names[0x77] = " "; alujump_names[0x78] = "LDBSRM"; // 14 SHRCNT = alu2 & BITS_V; initialise the barrel shift amount (right) with the value from the register mentioned in the ALU2 source? alujump_names[0x79] = "LDBSLM"; // 5 SHLCNT = alu2 & BITS_V; alujump_names[0x7A] = "LDBSRU"; // 26 SHRCNT = alu2 & 0x1f; BT/BTS/BTR/BTC/BSF/PORTIO_PROTCHK/MOV r<->DR/MOV r<->TR/FSAVE/FRSTOR/LSL initialise the barrel shift amount (right) with the value from the register mentioned in the ALU2 source? alujump_names[0x7B] = "LDBSLU"; // 37 SHLCNT = alu2 & 0x1f; alujump_names[0x7C] = "RETURN"; // 14 alujump_names[0x7D] = "ICESIG"; // 10 HLT/FPU_FLAG*/HARDWARE_IRQ/TRIPLE_FAULT*/FAULT*/INTERRUPT/PAGE_FAULT*/SINGLE_STEP*/ICE_PIN* - send a signal to the ICE that something interesting is happening (*ICE has the opportunity to pause the microcode right after this) alujump_names[0x7E] = "PAGEFT"; // 1 PAGE_FAULT - not sure if this notifies ICE or the paging unit or both or something else that page fault handling has started alujump_names[0x7F] = " "; // 801 // busop_names[0x00] = " "; // busop_names[0x01] = " "; // busop_names[0x02] = " "; // busop_names[0x03] = " "; // busop_names[0x04] = "rd B"; busop_names[0x05] = "rd W"; // 1 IRETd_HELPER4 busop_names[0x06] = "rd "; // 1 0B1 XCHG rm,r busop_names[0x07] = "rd D"; // 9 LSSFSGS_HELPER/LOAD_SEGR_HELP/RETF_HELPER3/LAR_LSL_VERRW2/INT_HELPER TODO: Figure out the difference between rd and RD . rd automatically asserts LOCK#? "LOCK# is also asserted automatically for an XCHG instruction, a descriptor update, interrupt acknowledge cycles, and a page table update" (HRM 3.5.1) busop_names[0x08] = "CW B"; // 4 FSAVE_CORE/FPU_STORE_CORE Perform access/limit/paging checks for writes but don't actually do a write // busop_names[0x09] = "CW W"; busop_names[0x0A] = "CW "; // 4 RCL/RCR rm,CL / INS / ENTER_COMMON // busop_names[0x0B] = "CW D"; busop_names[0x0C] = "CR B"; // 4 FRSTOR_CORE/FPU_LD80_CORE Perform access/limit/paging checks for reads but don't actually do a read // busop_names[0x0D] = "CR W"; // busop_names[0x0E] = "CR "; // busop_names[0x0F] = "CR D"; // busop_names[0x10] = "WR B"; busop_names[0x11] = "WR W"; // 41 busop_names[0x12] = "WR "; // 49 busop_names[0x13] = "WR D"; // 11 // busop_names[0x14] = "RD B"; busop_names[0x15] = "RD W"; // 43 busop_names[0x16] = "RD "; // 101 busop_names[0x17] = "RD D"; // 21 LGDT/PR_LD_SS/LLDT/LOADALL386/??? // busop_names[0x18] = "wr B"; busop_names[0x19] = "wr W"; // 5 The difference between wr* and WR* seems to be that WR* is used in combination with a copy to OPR_W whereas wr* is for writing back something that was just read, so the data is in OPR_R busop_names[0x1A] = "wr "; // 24 // busop_names[0x1B] = "wr D"; busop_names[0x1C] = "PREF"; // 19 Start prefetch at IND? busop_names[0x1D] = "IN+D"; // 70 PUSHAd, IRETd IND += IND_DELTA // busop_names[0x1E] = " "; busop_names[0x1F] = "IN+="; // 61 IND = IND + alu2 IND_DELTA = alu2 <-3F-> (0?), -2, -4, 0x0d, 0x5d, 1, 2, 3, 4, 7, 9, INCREM, NEGWSZ, TMPB, TMPC, WORDSZ // busop_names[0x20] = " "; // busop_names[0x21] = " "; // busop_names[0x22] = " "; // busop_names[0x23] = " "; busop_names[0x24] = "IN=2"; // 25 IND = alu2 dest = IND_IO, IND_Rf, IND_TR, // Theory: {2C}-{39} all select parts/fields of a descriptor cache entry or selector in conjunction with IND_* sources/dests busop_names[0x25] = "IND="; // 103 IND = source dest = n/a (LJUMP), (-58), INDIDT, INDSTK, INC_CS, IND_ES, IND_IO, IND_IP, IND_OS, IND_RF, IND_TR busop_names[0x26] = "IN=+"; // 53 IND = source + alu2 IND_DELTA = alu2 dest = (-4E), (-58-), INDIDT, INDSTK, IND_ES, IND_IP, IND_OS, IND_RF, IND_TR // busop_names[0x27] = " "; busop_names[0x28] = "IACK"; // 2 Interrupt Acknowledge bus cycle HARDWARE_IRQ (asserts LOCK# like "rd") // busop_names[0x29] = " "; // busop_names[0x2A] = " "; // busop_names[0x2B] = " "; busop_names[0x2C] = "SBRM"; // 23 Set BASE in Real Mode (to segment << 4) dest = DS, ES, FS, GS, IND_CS, IND_DS, IND_ES, IND_FS, IND_GS, IND_SR, IND_SS, IRF, SS Also set LIMIT to 0xffff? Sets Access Rights? busop_names[0x2D] = "SDEH"; // 11 dest = (-4D-), INDLDT, IND_CS, IND_SS, IND_TR, IRF LD_SEGREG_PASS/PRESENT_TSS/PROT_TESTS_PASSED/PROT_TESTS_PASSED2/CALL_UNPRIV/RETF_HELPERRET/LLDT_TEST_PASS/CALL_SAVE_TASK/SWITCH_TASK/PASSED_0B_0D set descriptor high dword (sets byte 3 of base, byte 2 (G/DB/-/A bits) of access, and byte 2 (bits 16-19) of limit) busop_names[0x2E] = "SDES"; // 7 LD_SEGREG_PASS/PROT_TESTS_PASSED/PROT_TESTS_PASSED2/CALL_UNPRIV/CALL_SAVE_TASK/SWITCH_TASK uses alu2 (TMPB, TMPC, TMPD) set descriptor shifted dword (sets byte 3 (P/DPL/S/Type) bits of access, and bytes 0-2 of base) busop_names[0x2F] = "SDEL"; // 30 segreg load/JMP_FAR_PM/CALL_FAR_PM/CALL_UNPRIV/TASK_RETURN/IRETd/RETF_HELPER3/LTR/LLDT/LOAD_TASK/TASK_FINAL_V86/TASK_FINAL_PM/TRAPGATE/INTGATE uses alu2 (mostly TMPC, one TMPD) set descriptor low dword (sets bytes 0-1 of limit) busop_names[0x30] = "SPCR"; // 18 dest = (-7B-), (-7D-), IRF Store Page Cache Register? busop_names[0x31] = "SAR "; // 21 select AR field of descriptor cache dest = ES, FS, GS, IND_CS, IND_ES, IRF, INDLDT, IND_GS, IND_FS, IND_DS, IND_SS, IND_ES, IND_TR, DS busop_names[0x32] = "SBAS"; // 9 select BASE field of descriptor cache dest = DS, (-4D), IRF, IND_TR, IND_RF, IND_IR busop_names[0x33] = "SLIM"; // 14 select LIMIT field of descriptor cache dest = (-4D-), IRF, IND_TR, IND_RF, IND_IP, IND_CS, IND_ES busop_names[0x34] = "LPCR"; // 9 MOV rd,CR3/MOV rd,TRn/IRETd_HELPER4/unused?/pla/LOADALL386/DR_ICEBP_HELP2 dest = (-78-), (-79-), (-7A-), (-7B-), IRF Related to paging? - store CR3 to IND? Read special register? Used with TRn Load Page Cache Register into IRF2 busop_names[0x35] = "LAR "; // 11 JMP cp/RETF_HELPER/RETF_HELPER_*/pla/EXCEPTION/LOADALL386/DR_ICEBP_HELP2 dest = (-15-), (-6C-), IND_CS, IND_DS, IND_ES, IND_FS, IND_GS, IND-SS, IND-TR, IRF load access rights from descriptor cache into IRF2 busop_names[0x36] = "LBAS"; // 5 SIDT/SGDT/DR_ICEBP_HELP2 dest = INDGDT, INDIDT, IND_TR, IRF load base from descriptor cache into IRF2 busop_names[0x37] = "LLIM"; // 9 FARJUMP/JMP mp/SIDT/SGDT/SOFTWARE INT/LOADALL386/pla/DR_ICEBP_HELP2 dest = INDGDT, INDIDT, IND_CS, IND_TR, IRF, n/a (LJUMP), (-3F-) load limit from descriptor cache into IRF2 busop_names[0x38] = "TSDB"; // 3 TASK_RETURN/LOAD_TASK_16B/LOAD_TASK - task switch debug: some external signal that signifies that the address bus contains the old and new values of TR busop_names[0x39] = "SPTR"; // 40 makes DESPTR correspond to dest // busop_names[0x3A] = " "; // busop_names[0x3B] = " "; busop_names[0x3C] = "HLTS"; // 1 HLT_HELPER dest = (-7F-) - probably outputs HLT/SHUTDOWN signal to motherboard, then the actual waiting is done in the RPT (2) loop at 32b. // busop_names[0x3D] = " "; // busop_names[0x3E] = " "; busop_names[0x3F] = " "; // 1504 opnames[0] = "RNI"; // 162 RNI must be suppressed if it's in the delay slot - see 3a8 opnames[1] = "RNi"; // 25 RNI but only if it's executed in the delay slot opnames[2] = "RnI"; // 5 RNI but disable interrupts for the next instruction // opnames[3] = " "; // opnames[4] = " "; opnames[5] = "FIO"; // 14 FP IO - FSAVE_REGFILE, FRSTOR_REGFILE, FPU_LOAD_CORE, FLDCW, FPU_STORE_CORE, FPU_STORE_287 (when on its own there is a [5] (2) on the line after) - precedes some (but not all) accesses to the FPU port 0x800000fc opnames[6] = "RPT"; // 19 AAM/AAD/MUL/IMUL/DIV/IDIV/ARPL/ opnames[7] = " "; // 2141 subopnames[0] = "DLY"; // 559 Wait for bus operation to complete and update OPR_R if it was a read subopnames[1] = "UNL"; // 182 Used after a read is complete (but not always immedidately) - to do with bus unlocking? subopnames[2] = "WIO"; // 12 Used in HLT, FSAVE_REGFILE, FRSTOR_REGFILE, FPU_LOAD_CORE, FLDCW, FPU_STORE_CORE, FPU_STORE_287 (in conjunction with [5] except in HLT) - wait for IO? subopnames[3] = " "; // 1613 // ************** testnames[0x00] = "TST_SEL_NONSS"; // test non-SS selector for normal load testnames[0x01] = "TST_SEL_CS"; // test CS selector for normal load testnames[0x02] = "TST_SEL_RET"; // test selector for RETF testnames[0x03] = "TST_SEL_RET_OL"; // test selector for RETF_OUTER_LEV testnames[0x04] = "TST_PORTIO_BIT"; // test port IO permission bitmap bits testnames[0x05] = "TST_SEL_ARPL"; // test selector for ARPL testnames[0x06] = "TST_SEL_GDT"; // test that selector is non-null and points into GDT testnames[0x07] = "TST_SEL_LLDT"; // test selector for LLDT testnames[0x08] = "TST_SEL_LLVV"; // test selector for LAR/LSL/VERR/VERW testnames[0x09] = "TST_SEL_MOREPR"; // test SS selector for MORE_PRIVILEGE testnames[0x0A] = "TST_SEL_TASKGT"; // test TSS selector for TASKGATE testnames[0x0B] = "TST_SEL_TASKFI"; // test DS/ES/FS/GS selector for TASK_FINAL_PM testnames[0x0C] = "TST_SEL_SS"; // test SS selector for normal load (similar to TST_SEL_MOREPR but sets L for non-null selectors) testnames[0x0D] = "TST_SEL_TR_TSF"; // test TR selector for TASK_FINAL // testnames[0x0E] = " "; // unused // testnames[0x0F] = " "; // unused testnames[0x10] = "TST_DES_SIMPLE"; // test descriptor on load (default if not overridden) - descriptor must be present and (conforming code or met the access requirements for non-conforming code) testnames[0x11] = "TST_DES_SS"; // test SS descriptor for load testnames[0x12] = "TST_DES_JMP"; // test CS descriptor for jump testnames[0x13] = "TST_DES_JGATE"; // test CS descriptor for jump gate testnames[0x14] = "TST_DES_JGDEST"; // test CS descriptor for jump gate destination testnames[0x15] = "TST_DES_CALL"; // test CS descriptor for call testnames[0x16] = "TST_DES_CGATE"; // test CS descriptor for call gate testnames[0x17] = "TST_DES_CGDEST"; // test CS descriptor for call gate destination testnames[0x18] = "TST_DES_RETF"; // test CS descriptor for testnames[0x19] = "TST_DES_RTOLSS"; // test SS descriptor for RETF_OUTER_LEV testnames[0x1A] = "TST_DES_LDTTSK"; // test LDT descriptor for task switch testnames[0x1B] = "TST_DES_LDT"; // test LDT descriptor for LLDT or v86 task switch testnames[0x1C] = "TST_DES_MOREPR"; // test stack descriptor for MORE_PRIVILEGE (that is stored in CS) testnames[0x1D] = "TST_DES_TSSTSG"; // test TSS descriptor for task gate (needs to be available) testnames[0x1E] = "TST_DES_TSSTSR"; // test TSS descriptor for task return (needs to be busy) testnames[0x1F] = "TST_DES_TSSLTR"; // test TSS descriptor for LTR (needs to be available and present) testnames[0x20] = "TST_DES_GRANUL"; // test granularity of descriptor for LSL testnames[0x21] = "TST_DES_INT_SW"; // test IDT entry descriptor for software interrupt (INT ib, INT 3, INTO) testnames[0x22] = "TST_DES_INT_HW"; // test IDT entry descriptor for hardware interrutp (IRQ, NMI, fault) // testnames[0x23] = " "; // unused testnames[0x24] = "TST_ACCESS_VIO"; // test DESERR? in ACCESS_VIOLATI handler - this doesn't seem to be a descriptor or a selector. Some kind of error number? (goes from 0-9 and 24-26) testnames[0x25] = "TST_DES_RTOLOS"; // test ordinary (DS/ES/FS/GS) descriptor for RETF_OUTER_LEV testnames[0x26] = "TST_SEL_LES"; // test selector for LES testnames[0x27] = "TST_SEL_LDS"; // test selector for LDS testnames[0x28] = "TST_SEL_LFSLGS"; // test selector for LFS/LGS // testnames[0x29] = " "; // unused testnames[0x2A] = "JMP_GFAULT_INT"; // unconditional jump to #GP(I1,E0) with FAULT flag set testnames[0x2B] = "READ_RPL"; // PORTIO_PROTCHK, ARPL, LOAD_TASK_COMM - seems like it reads the privilege level (RPL) from a selector (in PROTUN) into a 2-bit latch testnames[0x2C] = "WRITE_RPL"; // MORE_PRIVILEGE - seems like it writes the privilege level from the latch to the low two bits of PROTUN testnames[0x2D] = "SET_RPL_TO_CPL"; // JUMP_FAR_PM, CALL_FAR_PM, TRAP_INT_GATE - set PROTUN[1..0] = CPL? testnames[0x2E] = "COPY_STACK_DPL"; // COPY_PARAMS, IRETd_V86, RETF_OUTER_LEV, TASK_FINAL_V86, TASK_FINAL_PM, FAULT, LOADALL, STOREALL - copy DPL from PROTUN to special stack descriptor DPL? (DESSTK.DPL = PROTUN[1..0]?) testnames[0x2F] = "SET_FAULT"; // signal for the double/triple fault detection logic? (TST_ACCESS_VIO does not set this signal, presumably because the signal from the protection/limit checker is used instead.) Works with the contributory fault bit. testnames[0x30] = "TST_DES_LAR"; // test descriptor for LAR testnames[0x31] = "TST_DES_LSL"; // test descriptor for LSL testnames[0x32] = "TST_DES_VERR"; // test descriptor for VERR testnames[0x33] = "TST_DES_VERW"; // test descriptor for VERW testnames[0x34] = "FPU_WAIT"; // testnames[0x35] = " "; // unused // testnames[0x36] = " "; // unused // testnames[0x37] = " "; // unused testnames[0x38] = "FPU_OTHER"; testnames[0x39] = "FPU_LOAD_3264"; // testnames[0x3A] = " "; // unused testnames[0x3B] = "FPU_LOAD_80"; testnames[0x3C] = "FPU_STORE_3264"; testnames[0x3D] = "FPU_STORE_80"; testnames[0x3E] = "FPU_FSAVE"; testnames[0x3F] = "FPU_FRSTOR"; auto out = File("microcode_10.txt", true).openWrite(); String instructions[2560]; int entryPointer = 0; for (int i = 0; i < 2560; ++i) { String s; while (entryPoints[entryPointer]._u != -1 && entryPoints[entryPointer]._a <= i) { if (entryPoints[entryPointer]._a == i) { s = decimal(entryPoints[entryPointer]._u) + " " + /*decimal(entryPoints[entryPointer]._t, 2) + " " +*/ entryPoints[entryPointer]._s; ++entryPointer; break; } ++entryPointer; } instructions[i] = s; } uint64_t uops[2560]; bool next1DNC = false; bool nextDNC = false; for (int xx = 0; xx < 2560; ++xx) { int x = 2559 - xx; //if (instructions[xx] != "") if (nextDNC) out.write("------------------------------------------|----------------------------------------------------------------------------------------------\n"); nextDNC = next1DNC; next1DNC = false; int entryPointer = 0; while (entryPoints[entryPointer]._u != -1 && entryPoints[entryPointer]._a <= xx) { if (entryPoints[entryPointer]._a == xx) { nextDNC = false; break; } ++entryPointer; } int alu2 = 0; for (int b = 0; b < 6; ++b) if (data[x*37 + 36 - b] == 0xff) // alu source / jump offset = ABCDEF alu2 += (32 >> b); alu2 = 63 - alu2; int dst = 0; for (int b1 = 0; b1 < 7; ++b1) if (data[x*37 + 36 - (b1 + 6)] == 0xff) // destination = GHIJKLM dst += (64 >> b1); dst = 127 - dst; int src = 0; for (int b2 = 0; b2 < 6; ++b2) if (data[x*37 + 36 - (b2 + 13)] == 0xff) // source = NOPQRS src += (32 >> b2); src = 63 - src; int alujump = 0; for (int b0 = 0; b0 < 7; ++b0) if (data[x*37 + 36 - (b0 + 19)] == 0xff) // alu operation / jump condition = TUVWXYZ alujump += (64 >> b0); alujump = 127 - alujump; int opcode = 0; for (int b = 0; b < 3; ++b) if (data[x*37 + 36 - (b + 26)] == 0xff) // 012 opcode += (4 >> b); opcode = 7 - opcode; int subcode = 0; for (int b = 0; b < 2; ++b) if (data[x*37 + 36 - (b + 29)] == 0xff) // 34 subcode += (2 >> b); subcode = 3 - subcode; int buscode = 0; for (int b = 0; b < 6; ++b) if (data[x*37 + 36 - (b + 31)] == 0xff) // 56789& buscode += (32 >> b); buscode = 63 - buscode; String line = hex(xx,3,false) + " "; uint64_t uop = 0; for (int i = 0; i < 37; ++i) { if (data[x*37 + 36 - i] == 0xff) uop += 1LL << i; } line += printuop(uop); uops[x] = uop; out.write(line + "| "); if (uop == 0) { out.write(" " + instructions[xx]); out.write("\n"); continue; } if (opcode == 0 || opcode == 2 || alujump == 0x5a || alujump == 0x7c || alujump == 0x71 || alujump == 0x4b) next1DNC = true; String op = opnames[opcode]; String subop = subopnames[subcode]; String busop = busop_names[buscode]; bool ljump = (alujump >= 0x70 && alujump <= 0x74); bool sjump = (alujump >= 0x40 && alujump <= 0x5f); bool tjump = (alujump >= 0x60 && alujump <= 0x6f); bool haveDest = (dst != 0x7f); bool haveNormalDest = ((dst < 0x58 && dst != 0x4d && dst != 0x4e) || dst == 0x5c || dst == 0x5f); bool haveSrc = ((src != 0x3f) && !ljump); bool haveAlu2 = ((alu2 != 0x3f ) && !(ljump || sjump || tjump)); bool aluUnary = (alujump == 1 || alujump == 6 || alujump == 0x0b || alujump == 0x14 || alujump == 0x16 || alujump == 0x17 || alujump == 0x1a || alujump == 0x6a); bool aluUnary2 = (alujump == 0x15 || alujump == 0x3e || (alujump >= 0x78 && alujump <= 0x7b)); bool aluBinary = (alujump < 0x20 && !aluUnary && !aluUnary2 && alujump != 0x13); bool busBinary = (buscode == 0x26); bool busUnary = (buscode == 0x25 || buscode == 0x2c || buscode == 0x2d || (buscode >= 0x31 && buscode <= 0x33)); bool busUnary2 = (buscode == 0x1f || buscode == 0x24 || buscode == 0x2d || buscode == 0x2e || buscode == 0x2f); bool displaySrc = (aluUnary || aluBinary || busUnary || busBinary|| haveNormalDest); bool displayDest = haveDest; bool displayArrow = haveNormalDest; bool displayAlu2 = (aluUnary2 || aluBinary || busUnary2 || busBinary); //if (ljump && (displayAlu2 || displaySrc)) // out.write("!!!"); //if (sjump && displayAlu2) // out.write("!!!"); //if (haveDest && !displayDest) // out.write("!!!"); //if (haveSrc && !displaySrc && src != 0x2d) // OPR_R seems to appear on its own sometimes - some kind of bus release? // out.write("!!!"); //if (haveAlu2 && !displayAlu2) // out.write("!!!"); if (haveSrc && !displaySrc) // lines 085, 0b0, 719, 71b, 83c, 86f, 89b and 8ee set source to OPR_R but don't seem to use it. Also 78c sets source to TMP_TR but doesn't seem to use it. displaySrc = true; if (displaySrc) out.write(regnames_source[src]); else out.write(" "); if (displayArrow) out.write(" -> "); else out.write(" "); if (displayDest) out.write(regnames_dest[dst]); else out.write(" "); //if (!haveDest && (!haveSrc || ljump)) { // if (!ljump && aluBinary) // out.write(String("-1 ") + " " + " "); // else // out.write(String(" ") + " " + " "); //} //else { // if (!haveDest) // out.write(regnames_source[src] + " " + " "); // else // out.write(regnames_source[src] + " -> " + regnames_dest[dst]); // //if (dst == src) // // out.write(" " + regnames[dst] + " reflexive"); // ++usedD[dst]; // ++usedS[src]; // lastD[dst] = xx; // lastS[src] = xx; //} out.write(" "); if (ljump) { int p = alu2 + (src << 6); String s = hex(p, 3, false) + " "; int entryPointer = 0; while (entryPoints[entryPointer]._u != -1 && entryPoints[entryPointer]._a <= p) { if (entryPoints[entryPointer]._a == p) { s = entryPoints[entryPointer]._s; if (s.length() < 14) s = s + (14 - s.length())*String(" "); if (s.length() > 14) s = s.subString(0, 14); break; } ++entryPointer; } out.write(s); } else { if (sjump) { //if (alu2 != 0x3f) { int jump = alu2; int dest = xx + 1 + jump; if (jump > 0x20) dest -= 0x40; String s = hex(dest, 3, false) + " "; int entryPointer = 0; while (entryPoints[entryPointer]._u != -1 && entryPoints[entryPointer]._a <= dest) { if (entryPoints[entryPointer]._a == dest) { s = entryPoints[entryPointer]._s; if (s.length() < 14) s = s + (14 - s.length())*String(" "); if (s.length() > 14) s = s.subString(0, 14); break; } ++entryPointer; } out.write(s); //} //else // out.write(" "); } else { if (tjump) { String s = testnames[alu2]; if (s.length() < 14) s = s + (14 - s.length())*String(" "); if (s.length() > 14) s = s.subString(0, 14); out.write(s); } else { //if ((alujump & 0x40) == 0 || (alujump >= 0x60)) { if (displayAlu2) { //if (alu2 != 0x3f || alujump == 0x3e || alujump == 0x15 || (alujump >= 0x0c && alujump <= 0x10) || buscode == 0x1f || buscode == 0x24 || buscode == 0x26 || buscode == 0x2d || buscode == 0x2e) { // What other alujump commands have alu2==0x3f have a function? //if (regnames_alu[alu2].length() > 6) out.write(regnames_alu[alu2] + String(" ")*(14 - regnames_alu[alu2].length())); //else // out.write(regnames_alu[alu2] + "-> ALU2 "); //++usedA[alu2]; //lastA[alu2] = xx; } else out.write(" "); //} } } } //if ((alu2 + (src << 6)) == 0x5f2 || xx + 1 + alu2 == 0x5f2) // out.write("0x5f2"); //static const int unreachables[33] = { // 0x54d, // 0x5b3, // 0x5b8, // 0x5bd, // 0x5d3, // 0x686, // 0x71f, // 0x862, // 0x86a, // 0x4e7, // 0x4ee, // 0x554, // 0x5d5, // 0x5fb, // 0x743, // 0x7e5, // 0x872, // 0x8c2, // 0x8cb, // 0x449, // 0x4b5, // 0x5da, // 0x71c, // 0x7e8, // 0x3eb, // 0x451, // 0x51c, // 0x536, // 0x6a8, // 0x6b3, // 0x6dd, // 0x71a, // 0x71d}; //for (int i = 0; i < 33; ++i) { // int jump = alu2; // if (jump > 0x20) // jump = xx + 1 + jump - 0x40; // else // jump = xx + 1 + jump; // if ((alu2 + (src << 6)) == unreachables[i]) // out.write("**" + hex(unreachables[i], 3, true) + "**"); // if (jump == unreachables[i]) // out.write("**" + hex(unreachables[i], 3, true) + "++"); // if ((alu2 + (src << 6)) == unreachables[i] - 1) // out.write("**" + hex(unreachables[i] - 1, 3, true) + "--"); // if (jump == unreachables[i] - 1) // out.write("**" + hex(unreachables[i] - 1, 3, true) + "//"); //} ++usedAJ[alujump]; lastAJ[alujump] = xx; ++usedBus[buscode]; lastBus[buscode] = xx; ++usedOp[opcode]; ++usedSub[subcode]; out.write(" " + alujump_names[alujump] + " " + op + " " + subop + " " + busop + " " + instructions[xx]); #if 0 //for (int row = 0; row < 368; ++row) { // if ((outputs[row] & 0xfff) == 2559 - x) { // for (int b = 12; b >= 0; --b) { // if ((mask[row] & (1 << b)) == 0) // console.write("?"); // else { // if ((bits[row] & (1 << b)) == 0) // console.write("0"); // else // console.write("1"); // } // } // console.write(" "); // for (int b = 15; b >= 0; --b) { // if ((outputs[row] & (1 << b)) == 0) // console.write("0"); // else // console.write("1"); // } // console.write(" "); // } //} int nbitsets = 0; for (int o = 0; o < 8192; ++o) { if ((ored[o] & 0xfff) == 2559 - x) { bitsets[nbitsets]._mask = 0x1fff; bitsets[nbitsets]._bits = o; bitsets[nbitsets]._output = ored[o]; ++nbitsets; } } while (true) { //if (x == 2559) { // for (int o = 0; o < nbitsets; ++o) { // for (int b = 12; b >= 0; --b) { // if ((bitsets[o]._mask & (1 << b)) == 0) // console.write("?"); // else // if ((bitsets[o]._bits & (1 << b)) == 0) // console.write("0"); // else // console.write("1"); // } // console.write(" "); // for (int b = 15; b >= 0; --b) { // if ((bitsets[o]._output & (1 << b)) == 0) // console.write("0"); // else // console.write("1"); // } // console.write(" "); // } // console.write("\n"); //} bool found = false; //for (int o = 0; o < nbitsets; ++o) { // for (int o1 = 0; o1 < o; ++o1) { // if (bitsets[o]._mask != bitsets[o1]._mask || bitsets[o]._output != bitsets[o1]._output) // continue; // Word b = bitsets[o]._bits ^ bitsets[o1]._bits; // if ((b & (b-1)) == 0) { // found = true; // bitsets[o1]._mask &= ~b; // bitsets[o1]._bits &= ~b; // for (int o2 = o; o2 < nbitsets - 1; ++o2) { // bitsets[o2]._mask = bitsets[o2 + 1]._mask; // bitsets[o2]._bits = bitsets[o2 + 1]._bits; // bitsets[o2]._output = bitsets[o2 + 1]._output; // } // --nbitsets; // } // } //} for (int o = nbitsets - 1; o >= 1; --o) { for (int o1 = o - 1; o1 >= 0; --o1) { if (bitsets[o]._mask != bitsets[o1]._mask || bitsets[o]._output != bitsets[o1]._output) continue; DWord b = bitsets[o]._bits ^ bitsets[o1]._bits; if ((b & (b-1)) == 0) { found = true; bitsets[o1]._mask &= ~b; bitsets[o1]._bits &= ~b; for (int o2 = o; o2 < nbitsets - 1; ++o2) { bitsets[o2]._mask = bitsets[o2 + 1]._mask; bitsets[o2]._bits = bitsets[o2 + 1]._bits; bitsets[o2]._output = bitsets[o2 + 1]._output; } --nbitsets; if (o == nbitsets) break; } } } if (!found) break; } for (int o = 0; o < nbitsets; ++o) { for (int b = 12; b >= 0; --b) { if ((bitsets[o]._mask & (1 << b)) == 0) console.write("?"); else if ((bitsets[o]._bits & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write(" "); for (int b = 15; b >= 0; --b) { if ((bitsets[o]._output & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write(" "); } #endif out.write("\n"); //printf("\n"); } #if 0 std::sort(&uops[0], &uops[2560]); int first = -1; for (int i = 0; i < 2560; ++i) { if (i == 2559 || uops[i] != uops[i + 1]) { console.write(printuop(uops[i]) + " " + decimal(i - first, 2) + "\n"); first = i; } } #endif #if 0 //printf("%i %i %i\n",countr2,countr1,countr0); for (int i = 0; i < 64; ++i) { if (usedS[i] == 0) console.write(" // "); else console.write(" "); console.write("regnames_source["+hex(i, 2)+"] = \"" + regnames_source[i] + "\";"); if (usedS[i] != 0) console.write(" // " + decimal(usedS[i])); if (usedS[i] == 1) console.write(" " + hex(lastS[i],3, false)); console.write("\n"); if (usedD[i] == 0) console.write(" // "); else console.write(" "); console.write("regnames_dest ["+hex(i, 2)+"] = \"" + regnames_dest [i] + "\";"); if (usedD[i] != 0) console.write(" // " + decimal(usedD[i])); if (usedD[i] == 1) console.write(" " + hex(lastD[i], 3, false)); console.write("\n"); if (usedD[i + 64] == 0) console.write(" // "); else console.write(" "); console.write("regnames_dest ["+hex(i+64, 2)+"] = \"" + regnames_dest[i+64] + "\";"); if (usedD[i + 64] != 0) console.write(" // " + decimal(usedD[i + 64])); if (usedD[i + 64] == 1) console.write(" " + hex(lastD[i + 64], 3, false)); console.write("\n"); if (usedA[i] == 0) console.write(" // "); else console.write(" "); console.write("regnames_alu ["+hex(i, 2)+"] = \"" + regnames_alu [i] + "\";"); if (usedA[i] != 0) console.write(" // " + decimal(usedA[i])); if (usedA[i] == 1) console.write(" " + hex(lastA[i], 3, false)); console.write("\n"); } for (int i = 0; i < 128; ++i) { if (usedAJ[i] == 0) console.write(" // "); else console.write(" "); console.write("alujump_names["+hex(i, 2)+"] = \"" + alujump_names[i] + "\";"); if (usedAJ[i] != 0) console.write(" // " + decimal(usedAJ[i])); if (usedAJ[i] == 1) console.write(" " + hex(lastAJ[i], 3, false)); console.write("\n"); } for (int i = 0; i < 64; ++i) { if (usedBus[i] == 0) console.write(" // "); else console.write(" "); console.write("busop_names["+hex(i, 2)+"] = \"" + busop_names[i] + "\";"); if (usedBus[i] != 0) console.write(" // " + decimal(usedBus[i])); if (usedBus[i] == 1) console.write(" " + hex(lastBus[i], 3, false)); console.write("\n"); } for (int i = 0; i < 8; ++i) { if (usedOp[i] == 0) console.write(" // "); else console.write(" "); console.write("opnames["+hex(i, 1, false)+"] = \"" + opnames[i] + "\";"); if (usedOp[i] != 0) console.write(" // " + decimal(usedOp[i])); console.write("\n"); } for (int i = 0; i < 4; ++i) { if (usedSub[i] == 0) console.write(" // "); else console.write(" "); console.write("subopnames["+hex(i, 1, false)+"] = \"" + subopnames[i] + "\";"); if (usedSub[i] != 0) console.write(" // " + decimal(usedSub[i])); console.write("\n"); } for (int row = 0; row < 368 + 160 + 175; ++row) { //for (int b = 12; b >= 0; --b) { for (int b = 0; b < 13; ++b) { if ((mask[row] & (1 << b)) == 0) console.write("?"); else { if ((bits[row] & (1 << b)) == 0) console.write("0"); else console.write("1"); } } console.write(" "); for (int b = 15; b >= 0; --b) { if ((outputs[row] & (1 << b)) == 0) console.write("0"); else console.write("1"); } console.write("\n"); } int max = 0; for (int x = 0; x < 37 - 5; ++x) { Array counts(64); for (int y = 0; y < 64; ++y) counts[y] = 0; for (int u = 0; u < 2560; ++u) { int v = 0; for (int b = 0; b < 6; ++b) { if (data[u*37 + x + 5 - b] == 0xff) v += (32 >> b); } ++counts[v]; if (counts[v] > max && v != 0) max = counts[v]; } } Array heat(64*(37 - 5)); for (int x = 0; x < 37 - 5; ++x) { Array counts(64); for (int y = 0; y < 64; ++y) counts[y] = 0; for (int u = 0; u < 2560; ++u) { int v = 0; for (int b = 0; b < 6; ++b) { if (data[u*37 + x + 5 - b] == 0xff) v += (1 << b); //(32 >> b); } ++counts[v]; } for (int y = 0; y < 64; ++y) heat[y + x*64] = clamp(1, counts[y]*255/max, 255); } File("heat.raw").openWrite().write(heat); for (int i = 0; i < 256; ++i) { console.write(hex(i,2,false) + ":\n"); for (int j = 0; j < 8; ++j) { int o = (((i & 128) != 0) ? 2048 : 0) + (((i & 64) != 0) ? 1024 : 0) + (((j & 4) != 0) ? 512 : 0) + (((j & 2) != 0) ? 256 : 0) + (((j & 1) != 0) ? 128 : 0) + (((i & 32) != 0) ? 64 : 0) + (((i & 16) != 0) ? 32 : 0) + (((i & 8) != 0) ? 16 : 0) + (((i & 4) != 0) ? 8 : 0) + (((i & 2) != 0) ? 4 : 0) + (((i & 1) != 0) ? 1 : 0); console.write(hex(ored[o], 4, false) + "\n"); } console.write("\n"); } #endif } };