void BX_CPU_C::real_mode_int(Bit8u vector, bx_bool push_error, Bit16u error_code) { if ((vector*4+3) > BX_CPU_THIS_PTR idtr.limit) { BX_ERROR(("interrupt(real mode) vector > idtr.limit")); exception(BX_GP_EXCEPTION, 0); } push_16((Bit16u) read_eflags()); push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_16(IP); Bit16u new_ip = system_read_word(BX_CPU_THIS_PTR idtr.base + 4 * vector); // CS.LIMIT can't change when in real/v8086 mode if (new_ip > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) { BX_ERROR(("interrupt(real mode): instruction pointer not within code segment limits")); exception(BX_GP_EXCEPTION, 0); } Bit16u cs_selector = system_read_word(BX_CPU_THIS_PTR idtr.base + 4 * vector + 2); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_selector); EIP = new_ip; /* INT affects the following flags: I,T */ BX_CPU_THIS_PTR clear_IF(); BX_CPU_THIS_PTR clear_TF(); #if BX_CPU_LEVEL >= 4 BX_CPU_THIS_PTR clear_AC(); #endif BX_CPU_THIS_PTR clear_RF(); }
void BX_CPU_C::real_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code, Bit16u error_code) { // real mode interrupt Bit16u cs_selector, ip; if ((vector*4+3) > BX_CPU_THIS_PTR idtr.limit) { BX_ERROR(("interrupt(real mode) vector > idtr.limit")); exception(BX_GP_EXCEPTION, 0, 0); } push_16((Bit16u) read_eflags()); cs_selector = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; push_16(cs_selector); ip = EIP; push_16(ip); access_read_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector, 2, 0, BX_READ, &ip); EIP = (Bit32u) ip; access_read_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector + 2, 2, 0, BX_READ, &cs_selector); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_selector); /* INT affects the following flags: I,T */ BX_CPU_THIS_PTR clear_IF(); BX_CPU_THIS_PTR clear_TF(); #if BX_CPU_LEVEL >= 4 BX_CPU_THIS_PTR clear_AC(); #endif BX_CPU_THIS_PTR clear_RF(); }