/***************************************************************************** interrupt handler demo CPU mode: protected mode (32-bit) using DOS? yes language: DJGPP (GCC for DOS) Note: there are other ways to handle interrupts under DJGPP. For more information: http://www.delorie.com/djgpp/doc/ug/interrupts/hwirqs.html http://www.geocities.com/SiliconValley/Vista/6552/djints.txt http://mega.ist.utl.pt/~fjds/inthandlers1.html http://mega.ist.utl.pt/~fjds/inthandlers2.html *****************************************************************************/ #include /* _farpokeb(), _farpokeb() */ #include /* getch(), cputs() */ #include /* _dos_ds, _my_cs() */ #include /* _go32_dpmi... */ #include /* _CRT0_FLAG_LOCK_MEMORY */ #include /* outportb() */ #define TIMER_VECT 8 #define SYSCALL_VECT 50 #define SYS_CPUTS 0 /* vector type and macros for portability */ #define INTERRUPT /* nothing */ #define SAVE_VECTOR(vec, num) \ _go32_dpmi_get_protected_mode_interrupt_vector(num, &vec.old_v) #define INSTALL_HANDLER(vec, num, fn) \ vec.new_v.pm_selector = _my_cs(); \ vec.new_v.pm_offset = (unsigned long)fn; \ _go32_dpmi_allocate_iret_wrapper(&vec.new_v); \ _go32_dpmi_set_protected_mode_interrupt_vector(num, &vec.new_v); #define RESTORE_VECTOR(vec, num) \ _go32_dpmi_set_protected_mode_interrupt_vector(num, &vec.old_v);\ _go32_dpmi_free_iret_wrapper(&vec.new_v); typedef struct { _go32_dpmi_seginfo old_v, new_v; } vector_t; /* lock all memory, to prevent it being swapped or paged out */ int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY; /***************************************************************************** increment char in upper left corner of screen on every timer tick *****************************************************************************/ static void INTERRUPT timer_int(void) { _farpokeb(_dos_ds, 0xB8000, _farpeekb(_dos_ds, 0xB8000) + 1); outportb(0x20, 0x20); } /***************************************************************************** *****************************************************************************/ static void INTERRUPT syscall_int(__dpmi_regs *regs) { switch(regs->d.eax) { case SYS_CPUTS: cputs((char *)regs->d.esi); break; } } /***************************************************************************** *****************************************************************************/ int main(void) { static const char *msg = "press a key to quit\n\r"; /**/ vector_t old_timer_vector, old_syscall_vector; /* save old vectors */ SAVE_VECTOR(old_timer_vector, TIMER_VECT); SAVE_VECTOR(old_syscall_vector, SYSCALL_VECT); /* install new handlers */ INSTALL_HANDLER(old_timer_vector, TIMER_VECT, timer_int); INSTALL_HANDLER(old_syscall_vector, SYSCALL_VECT, syscall_int); /* make a system call */ __asm__ __volatile__( "int %0\n" : : "i"(SYSCALL_VECT), "a"(SYS_CPUTS), "S"(msg)); /* await key pressed */ getch(); /* restore old vectors */ RESTORE_VECTOR(old_timer_vector, TIMER_VECT); RESTORE_VECTOR(old_syscall_vector, SYSCALL_VECT); return 0; }