void mouse_init(void) /*Note that we are doing NO device initialization. We are assuming that this was done suitably when the system was booted and the standard mouse driver was installed. THis is very poor programming practice! CW */ { /* _go32_dpmi_lock_data(mousequeue,200); I'm not using these in this simple demo so they are commented out. CW _go32_dpmi_lock_data(&mousequeue,sizeof(mousequeue));*/ _go32_dpmi_lock_code(NewInt74,(unsigned long)(LOCKint74-NewInt74)); // This ensures that the handler is not placed into paged memory. _go32_dpmi_get_protected_mode_interrupt_vector(0x74,&old_handler); /* Reads the selector and offset of the old handler into a structure, so that it can be restored later. */ /*Obtains the far pointer for the mouse ISR */ new_mousehandler.pm_selector=_go32_my_cs(); /* Note that _go32_my_cs() returns the selector for the program's code.*/ new_mousehandler.pm_offset=(unsigned long)NewInt74; _go32_dpmi_allocate_iret_wrapper(&new_mousehandler); /* The wrapper saves the machine state using a series of PUSH instructions. */ _go32_dpmi_set_protected_mode_interrupt_vector(0x74,&new_mousehandler); /* Places the ISR far pointer into a protected mode interrupt table. */ }
void key_init(void) { lo=hi=0; new_key_handler.pm_offset = (int) key_handler; new_key_handler.pm_selector = _go32_my_cs(); _go32_dpmi_get_protected_mode_interrupt_vector(0x9, &old_key_handler); _go32_dpmi_allocate_iret_wrapper(&new_key_handler); _go32_dpmi_set_protected_mode_interrupt_vector(0x9, &new_key_handler); }
void reinstall_c_irq_handler(int irq, _go32_dpmi_seginfo *old_irq) { _go32_dpmi_seginfo new_irq; _go32_dpmi_get_protected_mode_interrupt_vector(IRQ_VECTOR(irq), &new_irq); // importante: reposição do handler original _go32_dpmi_set_protected_mode_interrupt_vector(IRQ_VECTOR(irq), old_irq); // liberta funcao assembly _go32_dpmi_free_iret_wrapper(&new_irq); }
int set_isr(int irq, void (*isr)(void), _go32_dpmi_seginfo *prev_isr) { int vector = irq_vector(irq); if(_go32_dpmi_get_protected_mode_interrupt_vector(vector, prev_isr)) return -1; _go32_dpmi_seginfo new_isr; new_isr.pm_selector = _go32_my_cs( ); new_isr.pm_offset=(unsigned long) isr; if(_go32_dpmi_set_protected_mode_interrupt_vector(vector, &new_isr)) return -1; return 0; }
/** * key_init * This function initiates the interrupt for the keyboard. This was given * as part of the VBETEST.C example. **/ void key_init(void){ //Finds location of old handler _go32_dpmi_lock_code(NewInt9, (unsigned long)(LOCKint9 - NewInt9)); _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_handler); //Set new handler new_handler.pm_offset = (unsigned long)NewInt9; new_handler.pm_selector = _go32_my_cs(); //Set in protected mode _go32_dpmi_allocate_iret_wrapper(&new_handler); _go32_dpmi_set_protected_mode_interrupt_vector(9, &new_handler); }
/* Try to restore interrupt handler */ static int restore(int vector, _go32_dpmi_seginfo *seginfo, _go32_dpmi_seginfo *orig_seginfo) { _go32_dpmi_seginfo cur_seginfo; _go32_dpmi_get_protected_mode_interrupt_vector(vector, &cur_seginfo); if (cur_seginfo.pm_selector != seginfo->pm_selector || cur_seginfo.pm_offset != seginfo->pm_offset) return 1; _go32_dpmi_set_protected_mode_interrupt_vector(vector, orig_seginfo); return 0; }
int install_asm_irq_handler(int irq, void (*irq_func)(void), _go32_dpmi_seginfo *old_irq) { // endereço do handler original _go32_dpmi_get_protected_mode_interrupt_vector(IRQ_VECTOR(irq), old_irq); // instalação do handler na IDT _go32_dpmi_seginfo new_irq; new_irq.pm_selector = _go32_my_cs( ); // selector do código new_irq.pm_offset = (unsigned long) irq_func; // endereço do novo handler _go32_dpmi_set_protected_mode_interrupt_vector(IRQ_VECTOR(irq), &new_irq); return 0; }
/* Lock code, data, and chain an interrupt handler */ void timer_install(int hertz, timerhandler_t func_ptr) { timer_handler = func_ptr; /* Save the old vector, stuff the new one in there */ _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INT, &old_handler); new_handler.pm_offset = (int) timer_handler; new_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(TIMER_INT, &new_handler); /* Set PIC to fire at desired refresh rate */ timer_adjust(hertz); }
void key_init(void) { int i; for (i=0;i<256;i++) keypush[i]=0; /*none key is pressed*/ extended_key_follows=FALSE; update_leds(); raw_key_r=0;raw_key=0; new_key_handler.pm_offset = (int) key_handler; new_key_handler.pm_selector = _go32_my_cs(); _go32_dpmi_get_protected_mode_interrupt_vector(0x9, &old_key_handler); _go32_dpmi_allocate_iret_wrapper(&new_key_handler); _go32_dpmi_set_protected_mode_interrupt_vector(0x9, &new_key_handler); keyboard_handler_replaced = TRUE; }
int install_c_irq_handler(int irq, void (*irq_func)(void), _go32_dpmi_seginfo *old_irq) { // endereço do handler original _go32_dpmi_get_protected_mode_interrupt_vector(IRQ_VECTOR(irq), old_irq); // instalação do handler na IDT _go32_dpmi_seginfo new_irq; new_irq.pm_selector = _go32_my_cs( ); // selector do código new_irq.pm_offset = (unsigned long) irq_func; // endereço do novo handler // prepara funcao assembly para chamar funcao C _go32_dpmi_allocate_iret_wrapper(&new_irq); _go32_dpmi_set_protected_mode_interrupt_vector(IRQ_VECTOR(irq), &new_irq); return 0; }
/* go to background: TSR */ void msdosBackground (void) { __djgpp_set_ctrl_c(0); saveState(&mainState); if (!setjmp(mainContext)) { __dpmi_regs regs; /* set a chained Protected Mode Timer IRQ handler */ timerSeginfo.pm_selector = _my_cs(); timerSeginfo.pm_offset = (unsigned long)&timerInterruptHandler; _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INTERRUPT, &origTimerSeginfo); _go32_dpmi_chain_protected_mode_interrupt_vector(TIMER_INTERRUPT, &timerSeginfo); /* set a real mode DOS Idle handler which calls back our Idle handler */ idleSeginfo.pm_selector = _my_cs(); idleSeginfo.pm_offset = (unsigned long)&idleInterruptHandler; memset(&idleRegisters, 0, sizeof(idleRegisters)); _go32_dpmi_get_real_mode_interrupt_vector(IDLE_INTERRUPT, &origIdleSeginfo); _go32_dpmi_allocate_real_mode_callback_iret(&idleSeginfo, &idleRegisters); _go32_dpmi_set_real_mode_interrupt_vector(IDLE_INTERRUPT, &idleSeginfo); /* Get InDos and Critical flags addresses */ regs.h.ah = 0X34; __dpmi_int(DOS_INTERRUPT, ®s); inDosFlagPointer = msdosMakeAddress(regs.x.es, regs.x.bx); regs.x.ax = 0X5D06; __dpmi_int(DOS_INTERRUPT, ®s); criticalOffset = msdosMakeAddress(regs.x.ds, regs.x.si); /* We are ready */ isBackgrounded = 1; regs.x.ax = 0X3100; msdosBreakAddress(0X100/*psp*/ + _go32_info_block.size_of_transfer_buffer, 0, ®s.x.dx, NULL); __dpmi_int(DOS_INTERRUPT, ®s); /* shouldn't be reached */ logMessage(LOG_ERR, "TSR installation failed"); isBackgrounded = 0; } saveState(&interruptState); restoreState(&mainState); }
int timer_init(TimerHandler handler) { /* Save old handler */ _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INT, &oldhandler); /* Setup our handler */ real_handler = handler; myhandler.pm_selector = _go32_my_cs(); myhandler.pm_offset = (unsigned long)timer_handler; /* Allocate an IRET wrapper */ if(_go32_dpmi_allocate_iret_wrapper(&myhandler)) return 0; /* Set our handler to be the new interrupt handler */ return _go32_dpmi_set_protected_mode_interrupt_vector(TIMER_INT, &myhandler); }
int set_isr_c_wrapper(int irq, void (*isr)(void), _go32_dpmi_seginfo *prev_isr) { int vector = irq_vector(irq); if(_go32_dpmi_get_protected_mode_interrupt_vector(vector, prev_isr)) return -1; _go32_dpmi_seginfo new_isr; new_isr.pm_selector = _go32_my_cs(); new_isr.pm_offset=(unsigned long) isr; /* prepara função assembly para chamar função C */ _go32_dpmi_allocate_iret_wrapper(&new_isr); if(_go32_dpmi_set_protected_mode_interrupt_vector(vector, &new_isr)) return -1; return 0; }
/* go to background: TSR */ void msdosBackground(void) { saveState(&mainState); if (!setjmp(mainCtx)) { __dpmi_regs regs; /* set a chained Protected Mode Timer IRQ handler */ timerSeginfo.pm_selector = _my_cs(); timerSeginfo.pm_offset = (unsigned long)&timerInt; _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INT, &origTimerSeginfo); _go32_dpmi_chain_protected_mode_interrupt_vector(TIMER_INT, &timerSeginfo); /* set a real mode DOS Idle handler which calls back our Idle handler */ idleSeginfo.pm_selector = _my_cs(); idleSeginfo.pm_offset = (unsigned long)&idleInt; memset(&idleRegs, 0, sizeof(idleRegs)); _go32_dpmi_get_real_mode_interrupt_vector(IDLE_INT, &origIdleSeginfo); _go32_dpmi_allocate_real_mode_callback_iret(&idleSeginfo, &idleRegs); _go32_dpmi_set_real_mode_interrupt_vector(IDLE_INT, &idleSeginfo); /* Get InDos and Critical flags addresses */ regs.h.ah = 0x34; __dpmi_int(DOS_INT, ®s); inDosOffset = regs.x.es*16 + regs.x.bx; regs.x.ax = 0x5D06; __dpmi_int(DOS_INT, ®s); criticalOffset = regs.x.ds*16 + regs.x.si; /* We are ready */ atexit(tsr_exit); backgrounded = 1; regs.x.ax = 0x3100; regs.x.dx = (/* PSP */ 256 + _go32_info_block.size_of_transfer_buffer) / 16; __dpmi_int(DOS_INT, ®s); /* shouldn't be reached */ logMessage(LOG_ERR,"Installation failed"); backgrounded = 0; } saveState(&intState); restoreState(&mainState); }
static void install_isr(int portnum, struct port *p, int irq) { int x, baseaddr = p->baseaddr; p->irq = irq; /* Clear pending interrupts. */ do { inportb(baseaddr + RBR); inportb(baseaddr + LSR); inportb(baseaddr + MSR); x = inportb(baseaddr + IIR); } while (!(x & 0x01)); /* Calculate vector from IRQ. */ if (p->irq <= 7) { p->interrupt_enable_mask = ~(1 << p->irq); /* IMR is inverted */ p->vector_num = 8 + p->irq; p->pic_imr = 0x21; } else { p->interrupt_enable_mask = ~(1 << (p->irq - 8)); p->vector_num = 0x70 + (p->irq - 8); p->pic_imr = 0xa1; } /* Install ISR into vector. */ p->new_vector.pm_selector = _go32_my_cs(); p->new_vector.pm_offset = (int)isr_wrapper_table[portnum]; _go32_dpmi_allocate_iret_wrapper(&p->new_vector); disable(); _go32_dpmi_get_protected_mode_interrupt_vector(p->vector_num, &p->old_vector); _go32_dpmi_set_protected_mode_interrupt_vector(p->vector_num, &p->new_vector); /* Enable interrupts. */ outportb(baseaddr + MCR, 0x0f); outportb(baseaddr + IER, 0x0f); outportb(p->pic_imr, inportb(p->pic_imr) & p->interrupt_enable_mask); enable(); }
static void kbd_init_common(void) { _go32_dpmi_get_protected_mode_interrupt_vector(9, &std_kbd_handler_seginfo); atexit(kbd_exit); _go32_dpmi_lock_code(my_kbd_interrupt_handler, (unsigned long)my_kbd_interrupt_handler_end - (unsigned long)my_kbd_interrupt_handler); _go32_dpmi_lock_code(queue_command, (unsigned long)queue_command_end - (unsigned long)queue_command); _go32_dpmi_lock_data(keyconvmaps, sizeof(keyconvmaps)); _go32_dpmi_lock_data(keyarr, sizeof(keyarr)); _go32_dpmi_lock_data(rev_keyarr, sizeof(rev_keyarr)); _go32_dpmi_lock_data(&modifiers, sizeof(modifiers)); _go32_dpmi_lock_data(&num_queued_commands, sizeof(num_queued_commands)); _go32_dpmi_lock_data(&command_queue, sizeof(command_queue)); num_queued_commands = 0; kbd_install(); }
void keyboard_int_install() { // retrieve the current (old) keyboard handler _go32_dpmi_get_protected_mode_interrupt_vector(9, &OldHandler); // lock code and data from being paged _go32_dpmi_lock_code(myKeyInt, (long)myKeyInt_Size); _go32_dpmi_lock_data(&keyVal, (long)sizeof(keyVal)); // establish new seginfo struct NewHandler.pm_offset = (long)myKeyInt; NewHandler.pm_selector = _go32_my_cs(); // allocate the IRET wrapper _go32_dpmi_allocate_iret_wrapper(&NewHandler); // install the new keyboard ISR _go32_dpmi_set_protected_mode_interrupt_vector(9, &NewHandler); printf("new keyboard ISR installed\n"); }
PVI MIrq_SetHandler(UBYTE irqno, PVI handler) { #ifdef __DJGPP__ _go32_dpmi_seginfo seginfo; #endif PVI oldvect; int vecno = (irqno > 7) ? irqno + 0x68 : irqno + 0x8; #ifdef __DJGPP__ _go32_dpmi_get_protected_mode_interrupt_vector(vecno, &seginfo); oldvect = seginfo.pm_offset; seginfo.pm_offset = handler; seginfo.pm_selector = _go32_my_cs(); _go32_dpmi_allocate_iret_wrapper(&seginfo); _go32_dpmi_set_protected_mode_interrupt_vector(vecno, &seginfo); #else oldvect = _dos_getvect(vecno); _dos_setvect(vecno, handler); #endif return oldvect; }
int display_dos_init() { __dpmi_regs r; /* Set char-smashed-together mode */ r.x.ax = 0x1201; r.h.bl = 0x30; __dpmi_int(0x10, &r); r.x.ax = 0x0003; __dpmi_int(0x10, &r); /* Pointer to video memory */ videomem = __dpmi_segment_to_descriptor(0xb800); /* Block cursor */ _setcursortype(_SOLIDCURSOR); /* No windows by default */ windows = 0; /* Check for Win95/Win98 */ if (getenv("winbootdir") != NULL) windows = 1; /* Check for WinNT/Win2k */ if ((getenv("OS") != NULL) && !strcmp(getenv("OS"), "Windows_NT")) windows = 2; lshift = rshift = 0; /* Save the old handler */ _go32_dpmi_get_protected_mode_interrupt_vector(KBD_INT, &old_kb_handler); /* Create new handler, chain it to old */ new_kb_handler.pm_offset = (int) kb_isr; new_kb_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(KBD_INT, &new_kb_handler); /* flush the keystroke buffer just in case */ while (kbhit()) display_dos_getch(); return -1; }
static void ComPort_Enable(ComPort *p) { void (*isr)(void); int n; byte b; if (p->enabled) { Con_Printf("Already enabled\n"); return; } // disable all UART interrupts outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0); // clear out any buffered uncoming data while((inportb (p->uart + LINE_STATUS_REGISTER)) & LSR_DATA_READY) inportb (p->uart + RECEIVE_BUFFER_REGISTER); // get the current line and modem status p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER); // clear any UART interrupts do { n = inportb (p->uart + INTERRUPT_ID_REGISTER) & 7; if (n == IIR_RX_DATA_READY_INTERRUPT) inportb (p->uart + RECEIVE_BUFFER_REGISTER); } while (!(n & 1)); if (p->uartType == UART_AUTO) { outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE); b = inportb (p->uart + INTERRUPT_ID_REGISTER); if ((b & IIR_FIFO_ENABLED) == IIR_FIFO_ENABLED) p->uartType = UART_16550; else p->uartType = UART_8250; } // save the old interrupt handler _go32_dpmi_get_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo); if (p->uartType == UART_8250) { outportb (p->uart + FIFO_CONTROL_REGISTER, 0); if (p == handleToPort[0]) isr = COM1_ISR_8250; else isr = COM2_ISR_8250; } else { outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE | FCR_RCVR_FIFO_RESET | FCR_XMIT_FIFO_RESET | FCR_TRIGGER_08); if (p == handleToPort[0]) isr = COM1_ISR_16550; else isr = COM2_ISR_16550; } p->protectedModeInfo.pm_offset = (int)isr; n = _go32_dpmi_allocate_iret_wrapper(&p->protectedModeInfo); if (n) { Con_Printf("serial: protected mode callback allocation failed\n"); return; } // disable interrupts at the processor disable(); // install our interrupt handlers now _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeInfo); // enable our interrupt at the PIC outportb (0x21, inportb (0x21) & ~(1<<p->irq)); // enable interrupts at the processor enable(); // enable interrupts at the PIC outportb (0x20, 0xc2); // set baud rate & line control outportb (p->uart + LINE_CONTROL_REGISTER, LCR_DLAB | p->lineControl); outportb (p->uart, p->baudBits); outportb (p->uart + 1, 0); outportb (p->uart + LINE_CONTROL_REGISTER, p->lineControl); // set modem control register & enable uart interrupt generation outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR); // enable the individual interrupts at the uart outportb (p->uart + INTERRUPT_ENABLE_REGISTER, IER_RX_DATA_READY | IER_TX_HOLDING_REGISTER_EMPTY | IER_LINE_STATUS | IER_MODEM_STATUS); p->enabled = true; }
void InitPort (void) { int mcr; int temp; if(port_initted) return; // // Reset the output queue // outque.head = outque.tail = 0; // // find the irq and io address of the port // GetUart (); // // init com port settings // regs.x.ax = 0xf3; //f3= 9600 n 8 1 regs.x.dx = comport - 1; int86 (0x14, ®s, ®s); // // check for a 16550 // OUTPUT(uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE + FCR_TRIGGER_04); temp = INPUT(uart + INTERRUPT_ID_REGISTER); if ((temp & 0xf8) == 0xc0) { uart_type = UART_16550; usermsg ("UART is a 16550"); } else { uart_type = UART_8250; OUTPUT(uart + FIFO_CONTROL_REGISTER, 0); usermsg("UART is an 8250"); } // // prepare for interrupts // OUTPUT(uart + INTERRUPT_ENABLE_REGISTER, 0); mcr = INPUT(uart + MODEM_CONTROL_REGISTER); mcr |= MCR_OUT2; mcr &= ~MCR_LOOPBACK; OUTPUT(uart + MODEM_CONTROL_REGISTER, mcr); INPUT(uart); // Clear any pending interrupts INPUT(uart + INTERRUPT_ID_REGISTER); // // hook the irq vector // irqintnum = irq + 8; asm("cli"); // disable interrupts _go32_dpmi_get_protected_mode_interrupt_vector(irqintnum, &oldirqvect); newirqvect.pm_offset = (int)isr_8250; newirqvect.pm_selector = _go32_my_cs(); _go32_dpmi_allocate_iret_wrapper(&newirqvect); _go32_dpmi_set_protected_mode_interrupt_vector(irqintnum, &newirqvect); asm("sti"); // enable interrupts OUTPUT(0x20 + 1, INPUT(0x20 + 1) & ~(1<<irq)); asm("cli"); // disable again // enable RX and TX interrupts at the uart OUTPUT(uart + INTERRUPT_ENABLE_REGISTER, IER_RX_DATA_READY + IER_TX_HOLDING_REGISTER_EMPTY); // enable interrupts through the interrupt controller OUTPUT(0x20, 0xc2); // set DTR OUTPUT(uart + MODEM_CONTROL_REGISTER , INPUT(uart + MODEM_CONTROL_REGISTER) | MCR_DTR); asm("sti"); // re-enable port_initted = true; }