int_pm.pas 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. { example for :
  2. set_pm_interrupt()
  3. get_pm_interrupt()
  4. Interrupt redirection
  5. Software interrupt
  6. tseginfo record
  7. get_cs()
  8. }
  9. { This example shows how to redirect a software interrupt by changing the
  10. protected mode handler of the DPMI host.
  11. In more detail it hooks interrupt 1Ch which is called every time the timer
  12. interrupt (int 08) is executed. This is the preferred way to hook the timer,
  13. because int 1Ch is a software interrupt which doesn't need so much
  14. initialization stuff compared to hooking a hardware interrupt.
  15. }
  16. uses crt, { wherey(), keypressed() }
  17. go32;
  18. const int1c = $1c; { interrupt number we want to hook }
  19. var oldint1c : tseginfo; { 48 bit pointer to old interrupt handler }
  20. newint1c : tseginfo; { 48 bit pointer to new interrupt handler }
  21. int1c_counter : Longint; { increased every time the interrupt is called }
  22. {$ASMMODE DIRECT}
  23. { the actual handler code }
  24. procedure int1c_handler; assembler;
  25. asm
  26. cli
  27. { save all registers }
  28. pushw %ds
  29. pushw %ax
  30. { prepare segment registers for FPC procedure }
  31. movw %cs:INT1C_DS, %ax
  32. movw %ax, %ds
  33. { simply increase the counter by one }
  34. incl _INT1C_COUNTER
  35. { restore registers }
  36. popw %ax
  37. popw %ds
  38. sti
  39. iret
  40. INT1C_DS: .word 0
  41. end;
  42. var i : Longint;
  43. begin
  44. { insert right handler data into new handler variable }
  45. newint1c.offset := @int1c_handler;
  46. newint1c.segment := get_cs;
  47. { get the old handler }
  48. get_pm_interrupt(int1c, oldint1c);
  49. { store necessary data into the handler }
  50. asm
  51. movw %ds, %ax
  52. movw %ax, INT1C_DS
  53. end;
  54. Writeln('-- Press any key to exit --');
  55. { set new handler }
  56. set_pm_interrupt(int1c, newint1c);
  57. { write the number of interrupts occured }
  58. while (not keypressed) do begin
  59. gotoxy(1, wherey); write('Number of interrupts occured : ', int1c_counter);
  60. end;
  61. { restore old handler }
  62. set_pm_interrupt(int1c, oldint1c);
  63. end.