static void ipx_esr_call_irq(far_t ECBPtr, u_char AXVal) { if(in_dpmi_pm()) fake_pm_int(); fake_int_to(BIOSSEG, EOI_OFF); ipx_esr_call(ECBPtr, AXVal); }
void write_pic1(ioport_t port, Bit8u value) { /* if port == 0 this must be either an ICW1, OCW2, or OCW3 */ /* if port == 1 this must be either ICW2, ICW3, ICW4, or load IMR */ static char /* icw_state, */ /* !=0 => port 1 does icw 2,3,(4) */ icw_max_state; /* number of icws expected */ int ilevel; /* level to reset on outb 0x20 */ port -= 0xa0; ilevel = 32; if (pic_isr) ilevel=find_bit(pic_isr); if (ilevel != 32 && !test_bit(ilevel, &pic_irqall)) { /* this is a fake IRQ, don't allow to reset its ISR bit */ pic_print(1, "Protecting ISR bit for lvl ", ilevel, " from spurious EOI"); ilevel = 32; } if (in_dpmi_pm()) dpmi_return_request(); /* we have to leave the signal context */ if(!port){ /* icw1, ocw2, ocw3 */ if(value&0x10){ /* icw1 */ icw_max_state = (value & 1) + 1; if(value&2) ++icw_max_state; pic1_icw_state = 1; pic1_cmd=1; } else if (value&0x08) { /* ocw3 */ if(value&2) pic1_isr_requested = value&1; if(value&64)pic_smm = value&32; /* must be either 0 or 32, conveniently */ pic1_cmd=3; } else if((value&0xb8) == 0x20) { /* ocw2 */ /* irqs on pic1 require an outb20 to each pic. we settle for any 2 */ if(!clear_bit(ilevel,&pic1_isr)) { clear_bit(ilevel,&pic_isr); /* the famous outb20 */ pic_print(1,"EOI resetting bit ",ilevel, " on pic0"); } else pic_print(1,"EOI resetting bit ",ilevel, " on pic1"); pic0_cmd=2; } } else /* icw2, icw3, icw4, or mask register */ switch(pic1_icw_state){ case 0: /* mask register */ set_pic1_imr(value); pic_print(1, "Set mask to ", value, " on pic1"); break; case 1: /* icw 2 */ set_pic1_base(value); default: /* icw 2,3 and 4 */ if(pic1_icw_state++ >= icw_max_state) pic1_icw_state=0; } }
void mhp_intercept(char *msg, char *logflags) { if (!mhpdbg.active || (mhpdbg.fdin == -1)) return; mhpdbgc.stopped = 1; mhpdbgc.want_to_stop = 0; traceloop = 0; mhp_printf(msg); mhp_cmd("r0"); mhp_send(); if (!(dosdebug_flags & DBGF_IN_LEAVEDOS)) { if (in_dpmi_pm()) dpmi_return_request(); if (logflags) mhp_intercept_log(logflags, 1); return; } mhp_poll_loop(); }
/* DANG_BEGIN_FUNCTION write_pic0,write_pic1 * * write_pic_0() and write_pic1() implement dos writes to the pic ports. * They are called by the code that emulates inb and outb instructions. * Each function implements both ports for the pic: pic0 is on ports * 0x20 and 0x21; pic1 is on ports 0xa0 and 0xa1. These functions take * two arguments: a port number (0 or 1) and a value to be written. * * DANG_END_FUNCTION */ void write_pic0(ioport_t port, Bit8u value) { /* if port == 0 this must be either an ICW1, OCW2, or OCW3 * if port == 1 this must be either ICW2, ICW3, ICW4, or load IMR */ #if 0 static char icw_state, /* !=0 => port 1 does icw 2,3,(4) */ #endif static char icw_max_state; /* number of icws expected */ int ilevel; /* level to reset on outb 0x20 */ port -= 0x20; ilevel = 32; if (pic_isr) ilevel=find_bit(pic_isr); if (ilevel != 32 && !test_bit(ilevel, &pic_irqall)) { /* this is a fake IRQ, don't allow to reset its ISR bit */ pic_print(1, "Protecting ISR bit for lvl ", ilevel, " from spurious EOI"); ilevel = 32; } if (in_dpmi_pm()) dpmi_return_request(); /* we have to leave the signal context */ if(!port){ /* icw1, ocw2, ocw3 */ if(value&0x10){ /* icw1 */ icw_max_state = (value & 1) + 1; if(value&2) ++icw_max_state; pic0_icw_state = 1; pic0_cmd=1; } else if (value&0x08){ /* ocw3 */ if(value&2) pic0_isr_requested = value&1; if(value&64)pic_smm = value&32; /* must be either 0 or 32, conveniently */ pic0_cmd=3; } else if((value&0xb8) == 0x20) { /* ocw2 */ /* irqs on pic1 require an outb20 to each pic. we settle for any 2 */ if(!clear_bit(ilevel,&pic1_isr)) { clear_bit(ilevel,&pic_isr); /* the famous outb20 */ pic_print(1,"EOI resetting bit ",ilevel, " on pic0"); #if 1 /* XXX hack: to avoid timer interrupt re-entrancy, * we try to disable interrupts in a hope IRET will re-enable * them. This fixes Tetris Classic problem: * https://github.com/stsp/dosemu2/issues/99 * Need to check also IMR because DPMI uses another hack * that masks the IRQs. */ if (ilevel == PIC_IRQ0 && isset_IF() && !(pic_imr & (1 << ilevel))) { r_printf("PIC: disabling interrupts to avoid reentrancy\n"); clear_IF_timed(); } #endif } else pic_print(1,"EOI resetting bit ",ilevel, " on pic1"); pic0_cmd=2; } } else /* icw2, icw3, icw4, or mask register */ switch(pic0_icw_state){ case 0: /* mask register */ set_pic0_imr(value); pic_print(1, "Set mask to ", value, " on pic0"); break; case 1: /* icw2 */ set_pic0_base(value); default: /* icw2, 3, and 4*/ if(pic0_icw_state++ >= icw_max_state) pic0_icw_state=0; } }
static void ipx_esr_irq_begin(void) { if(in_dpmi_pm()) fake_pm_int(); fake_int_to(BIOSSEG, EOI_OFF); }