home *** CD-ROM | disk | FTP | other *** search
-
-
-
- (*) Turbo Catch and Throw
- (*)
- (*) by Andrew Feldstein
- (*)
- (*) Version 1.0
- (*)
- (*) December 18, 1985
- (*)
-
- {================================================================}
-
- const catchsignature = $AFAF;
-
- type catchdata = record
- signature1 : integer;
- stackpointer : integer;
- basepointer : integer;
- instructionpointer : integer;
- thrown : boolean;
- signature2 : integer
- end;
-
- {================================================================}
-
- procedure catch({OUT} var cd : catchdata);
- const ipvalue : integer = 0;
- bpvalue : integer = 0;
- spvalue : integer = 0;
- begin
- inline($8B/$46/$02/ { MOV AX,[BP+02] }
- $2E/$A3/ipvalue/ { MOV CS:[..],AX }
- $8B/$46/$00/ { MOV AX,[BP+00] }
- $2E/$A3/bpvalue/ { MOV CS:[..],AX }
- $89/$E8/ { MOV AX,BP }
- $05/$08/$00/ { ADD AX,0008 }
- $2E/$A3/spvalue); { MOV CS:[..],AX }
- cd.basepointer := bpvalue;
- cd.stackpointer := spvalue;
- cd.instructionpointer := ipvalue;
- cd.thrown := false;
- cd.signature1 := catchsignature;
- cd.signature2 := catchsignature
- end;
-
- {================================================================}
-
- procedure throw({UPDATE}var cd : catchdata);
- const ipvalue : integer = 0;
- bpvalue : integer = 0;
- spvalue : integer = 0;
- begin
- if (cd.signature1<>catchsignature) or (cd.signature2<>catchsignature) then
- begin
- writeln(con,^M^J^J'Throw called on uninitialized CATCHDATA.'^G^J);
- halt
- end;
- cd.thrown := true;
- ipvalue := cd.instructionpointer;
- bpvalue := cd.basepointer;
- spvalue := cd.stackpointer;
- inline($2E/$8B/$26/spvalue/ { MOV SP,CS:[spvalue] }
- $2E/$8B/$2E/bpvalue/ { MOV BP,CS:[bpvalue] }
- $2E/$FF/$26/ipvalue); { JMP CS:[ipvalue] }
- end;
-
- {================================================================}
-
- function caught({IN}var cd : catchdata) : boolean;
- begin
- caught := cd.thrown
- end;
-
- {================================================================}
-
- procedure uncatch({OUT}var cd : catchdata);
- begin
- cd.signature1 := NOT catchsignature;
- cd.signature2 := NOT catchsignature
- end;
-