ops2.c

来自「BIOS emulator and interface to Realmode 」· C语言 代码 · 共 2,104 行 · 第 1/5 页

C
2,104
字号
void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)){    int mod, rl, rh;    uint destoffset;	u8 shift;    START_OF_INSTR();    DECODE_PRINTF("SHLD\t");    FETCH_DECODE_MODRM(mod, rh, rl);    switch (mod) {    case 0:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm00_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,shift);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm00_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,shift);            store_data_word(destoffset, destval);        }        break;    case 1:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm01_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,shift);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm01_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,shift);            store_data_word(destoffset, destval);        }        break;    case 2:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm10_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,shift);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm10_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,shift);            store_data_word(destoffset, destval);        }        break;    case 3:                     /* register to register */        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg,*shiftreg;            destreg = DECODE_RM_LONG_REGISTER(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            *destreg = shrd_long(*destreg,*shiftreg,shift);        } else {            u16 *destreg,*shiftreg;            destreg = DECODE_RM_WORD_REGISTER(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            shift = fetch_byte_imm();            DECODE_PRINTF2("%d\n", shift);            TRACE_AND_STEP();            *destreg = shrd_word(*destreg,*shiftreg,shift);        }        break;    }    DECODE_CLEAR_SEGOVR();    END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xad****************************************************************************/void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)){    int mod, rl, rh;    uint destoffset;    START_OF_INSTR();    DECODE_PRINTF("SHLD\t");    FETCH_DECODE_MODRM(mod, rh, rl);    switch (mod) {    case 0:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm00_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm00_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);            store_data_word(destoffset, destval);        }        break;    case 1:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm01_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm01_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);            store_data_word(destoffset, destval);        }        break;    case 2:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 destval;            u32 *shiftreg;            destoffset = decode_rm10_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_long(destoffset);            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);            store_data_long(destoffset, destval);        } else {            u16 destval;            u16 *shiftreg;            destoffset = decode_rm10_address(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            destval = fetch_data_word(destoffset);            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);            store_data_word(destoffset, destval);        }        break;    case 3:                     /* register to register */        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg,*shiftreg;            destreg = DECODE_RM_LONG_REGISTER(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);        } else {            u16 *destreg,*shiftreg;            destreg = DECODE_RM_WORD_REGISTER(rl);            DECODE_PRINTF(",");            shiftreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",CL\n");            TRACE_AND_STEP();            *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);        }        break;    }    DECODE_CLEAR_SEGOVR();    END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xaf****************************************************************************/void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)){    int mod, rl, rh;    uint srcoffset;    START_OF_INSTR();    DECODE_PRINTF("IMUL\t");    FETCH_DECODE_MODRM(mod, rh, rl);    switch (mod) {    case 0:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg;            u32 srcval;            u32 res_lo,res_hi;            destreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm00_address(rl);            srcval = fetch_data_long(srcoffset);            TRACE_AND_STEP();            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);            if (res_hi != 0) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u32)res_lo;        } else {            u16 *destreg;            u16 srcval;            u32 res;            destreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm00_address(rl);            srcval = fetch_data_word(srcoffset);            TRACE_AND_STEP();            res = (s16)*destreg * (s16)srcval;            if (res > 0xFFFF) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u16)res;        }        break;    case 1:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg;            u32 srcval;            u32 res_lo,res_hi;            destreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm01_address(rl);            srcval = fetch_data_long(srcoffset);            TRACE_AND_STEP();            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);            if (res_hi != 0) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u32)res_lo;        } else {            u16 *destreg;            u16 srcval;            u32 res;            destreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm01_address(rl);            srcval = fetch_data_word(srcoffset);            TRACE_AND_STEP();            res = (s16)*destreg * (s16)srcval;            if (res > 0xFFFF) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u16)res;        }        break;    case 2:        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg;            u32 srcval;            u32 res_lo,res_hi;            destreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm10_address(rl);            srcval = fetch_data_long(srcoffset);            TRACE_AND_STEP();            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);            if (res_hi != 0) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u32)res_lo;        } else {            u16 *destreg;            u16 srcval;            u32 res;            destreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            srcoffset = decode_rm10_address(rl);            srcval = fetch_data_word(srcoffset);            TRACE_AND_STEP();            res = (s16)*destreg * (s16)srcval;            if (res > 0xFFFF) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u16)res;        }        break;    case 3:                     /* register to register */        if (M.x86.mode & SYSMODE_PREFIX_DATA) {            u32 *destreg,*srcreg;            u32 res_lo,res_hi;            destreg = DECODE_RM_LONG_REGISTER(rh);            DECODE_PRINTF(",");            srcreg = DECODE_RM_LONG_REGISTER(rl);            TRACE_AND_STEP();            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);            if (res_hi != 0) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);            }            *destreg = (u32)res_lo;        } else {            u16 *destreg,*srcreg;            u32 res;            destreg = DECODE_RM_WORD_REGISTER(rh);            DECODE_PRINTF(",");            srcreg = DECODE_RM_WORD_REGISTER(rl);            res = (s16)*destreg * (s16)*srcreg;            if (res > 0xFFFF) {                SET_FLAG(F_CF);                SET_FLAG(F_OF);            } else {                CLEAR_FLAG(F_CF);                CLEAR_FLAG(F_OF);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?