home *** CD-ROM | disk | FTP | other *** search
- {
- T U R B O P a s c a l I n t e r r u p t H a n d l e r
-
- This program demonstrates the use of interrupts on the IBM PC from
- programs written in Turbo Pascal.
-
- Source: "Writing Interrupt Procedures in Turbo Pascal", TUG Lines Volume I Issue 6
- Author: Jim Camelford
- Application: IBM PC and true compatibles
-
- Copyright (c) Jim Camelford and CompuCam - All Rights Reserved
-
- **********************************************************************
- }
-
- {$V-} {Never ... never change these}
- {$K-}
- {$C-}
- Type
- address = ^integer;
-
- Var
- vector: array [0..$1f] of address absolute $0000:$0000;
- turboDTA: address;
-
-
- Const
- csdseg: integer = 0;
- csstacksave: integer = 0;
- csspsave: integer = 0;
- csturboseg: integer = 0;
- csturbosp: integer = 0;
- cssf: integer = -1; {normally -1}
- csmemspace: integer = 0;
-
- {**********************************************************************
- S e t T u r b o E n v i r o n m e n t
- **********************************************************************}
-
- Procedure SetTurboEnvironment;
- begin {setturboenvironment}
-
- {------------------------------------------------------------
- This procedure must never be altered such that it has any local
- variables or a parameter. After entry, its stack must look
- exactly like an interrupt procedures stack
- ------------------------------------------------------------}
-
- csdseg := dseg;
- csturboseg := sseg;
- inline($2e/$89/$26/csturbosp);
- csmemspace := (sseg-cseg)*16+csturbosp+6+16;
- end; {of setturboenvironment}
-
- Procedure Handler;
- Forward;
-
- {**********************************************************************
- I n t e r r u p t P r o c e d u r e
- **********************************************************************}
-
- Procedure Interrupt;
- begin {interrupt}
- inline($2e/$ff/$06/cssf/ { inc cs:cssf }
- $75/$14/ { jne *+10h }
- $2e/$8c/$16/csstacksave/ { saves current stack segment }
- $2e/$89/$26/csspsave/ { saves current stack ptr }
- $2e/$8e/$16/csturboseg/ { points stack to our stack segment}
- $2e/$8b/$26/csturbosp); { points sp to out stack segment}
-
- inline($50/$53/$51/$52/$57/$56/$06/$1e); { Push ax, bx, cx, dx,
- di, si, es, ds}
-
- inline($2e/$a1/csdseg/ { mov ax,cs:csdseg }
- $8e/$d8/ { mov ds,ax }
- $fb); { sti }
-
- Handler;
-
- inline($fa/ { interrupts off }
- $1f/$07/$5e/$5f/$5a/$59/$5b/$58/ { Pop ds, es, si, di,
- dx, cx, bx, ax}
- $2e/$ff/$0e/cssf/ { dec cs:cssf }
- $7d/$0d/ { jge *+13 }
- $2e/$8e/$16/csstacksave/ { mov ss,cs:csstacksave }
- $2e/$8b/$26/csspsave/ { mov sp,cs:csspsave }
- $5d/$5d/$cf/ { pop 2 temporaries and iret}
-
- {+0d:} $8b/$e5/ { mov sp,bp }
- $5d/ { pop bp }
- $cf); { iret }
-
- end; {of interrupt}
-
- Var
- TickVec: address; {vector's original contents}
- tix, hours, mins, secs: integer; {timer registers}
-
- Const
- TimerAddr = $1c; { $1c = Get Control on Timer}
-
- {*************************************************************************
- H a n d l e r P r o c e d u r e
- *************************************************************************}
-
- Procedure Handler;
- Var
- x,y: byte;
-
- begin
- {This procedure is entered 18 times / second. It bumps the timer
- registers and displays the contents once each second in the upper
- right corner of the screen}
-
- tix := tix+1;
- if tix >= 18 then
- begin
- tix := 0;
- secs := secs+1;
- if secs=60 then
- begin
- secs := 0;
- mins := mins+1;
- if mins=60 then
- begin
- mins := 0;
- hours := hours+1;
- if hours=24 then hours := 0;
- end;
- end;
- x := wherex; y := wherey;
- gotoxy(60,1);
- write(hours:2, ':', mins:2, ':', secs:2);
- gotoxy(x,y);
- end;
-
- end; {of handler}
-
- {*********************************************************************
- M a i n P r o g r a m
- *********************************************************************}
-
- begin
- cssf := 0; {Must set this to 0 to indicate that we are
- not running as an extension to DOS ... that is
- we are already in Turbo's execution space}
-
- SetTurboEnvironment;
-
- tix := 0; hours := 0; mins:=0; secs:=0; {initialize timer}
-
- TickVec := vector[TimerAddr]; {attach ourselves to $1c}
- vector[TimerAddr] := ptr(cseg, ofs(Interrupt));
- repeat until keypressed;
-
- vector[TimerAddr] := TickVec; {restore original contents}
- {... before leaving}
- end.