home *** CD-ROM | disk | FTP | other *** search
- (*---------------------------------------------------------------------------*)
- (* HYPERKEY.PAS (v2.1) *)
- (* Resident-Utility zur interaktiven Tastaturredefinition *)
- (* fuer MS-DOS-Systeme, Pascal-Compiler: Turbo Pascal 3.x *)
- (* (c) 1987 Karsten Gieselmann & PASCAL International *)
- (* Compilieren mit mIn=mAx free dynamic memory = $500 Paragraphen ! *)
- (*---------------------------------------------------------------------------*)
- {$C-,I-,K-,R-,U-,V-} (* alle Compiler-Schalter desaktivieren! *)
- {$I REGS8088.INC} (* CPU-Registertyp aus PASCAL 8/87 *)
- {$I MAKEINT.INC} (* Interrupt-Handling aus PASCAL 8/87 *)
- {$I TSRWIND.INC} (* Window-Handling aus PASCAL 8/87 *)
- CONST Version = 'HYPERKEY v2.1';
- XWin = 15; YWin = 1; (* linke obere Ecke des HYPERKEY-Fensters *)
- TSR_Char = $54; (* HYPERKEY-Aktivierungscode: hier Shift-F1 *)
- Old_Kbd = $61; (* der alte Tastatur-Interrupt *)
- TSR_Int = $62; (* der neue Makro-Interrupt *)
- TSRDseg :INTEGER = 0; (* TSR Data Segment *)
- TSRSseg :INTEGER = 0; (* TSR Stack Segment *)
- DosSseg :INTEGER = 0; (* DOS Stack Segment *)
- TSR_InUse :BOOLEAN = FALSE; (* Flag fuer Rekursion *)
- TSR_IntIP :INTEGER = 0; (* urspruenglicher IP Int *)
- TSR_IntCs :INTEGER = 0; (* urspruenglicher CS Int *)
- StackSize :INTEGER = 0;
- Regs :Regs8088_ = (AX:0; BX:0; CX:0; DX:0; (* CPU-Register *)
- BP:0; SI:0; DI:0;
- DS:0; ES:0; Flags:0);
- VAR SaveRegs :Regs8088_;
- HalfRegs :Regs8088_ ABSOLUTE Regs;
- TSR_terminate :BOOLEAN;
- Segm,Offs :INTEGER;
- (* ------------------------------------------------------------------------- *)
- (* Der HYPERKEY-Tastaturtreiber mit allen zugehoerigen Deklarationen *)
- CONST MaxMacroLen = 100; (* Maximale Laenge eines Tastatur-Makros *)
- TYPE Range = 0..MaxMacroLen;
- MacroType = ARRAY [Range] OF INTEGER;
- ListPtrType = ^EntryType;
- EntryType = RECORD (* Typ der Makro-Liste *)
- EntryNr, Scancode :INTEGER;
- Active :BOOLEAN;
- Replacement :MacroType;
- Last, Next :ListPtrType
- END;
- VAR Macro :MacroType; (* Macro-Puffer *)
- MacroLen :INTEGER ABSOLUTE Macro; (* Laenge des aktuellen Makros *)
- MacroPtr :INTEGER; (* Zeiger fuer Makro-Puffer *)
- MacroRegs :Regs8088_; (* Variable fuer Intr-Aufruf *)
- ListHead, (* globale Variablen fuer Makro-Liste *)
- ListEnd,
- ListPtr,
- SearchPtr :ListPtrType; (* Zeiger fuer "MacroInt" *)
-
- (* diese Routine wird vor den aktuellen Tastatur-Interrupt gehaengt: *)
- PROCEDURE MacroInt;
- VAR ShiftState :BYTE ABSOLUTE $0040:$0017; (* Sondertasten-Statusbyte *)
- {$I BEGININT.INC}
- WITH PgmRegs DO
- CASE PgmAH OF (* welche Interrupt-Funktion? *)
- 0: IF MacroPtr <= MacroLen THEN BEGIN (* liegen n. Makro-Zeichen vor? *)
- PgmAX := Macro[MacroPtr]; MacroPtr := Succ(MacroPtr)
- END
- ELSE BEGIN (* keine Makro-Zeichen, ueberpruefen auf Ersetzen *)
- MacroRegs.AH := $00;
- Intr (Old_Kbd, MacroRegs); (* Zeichen von altem Interrupt *)
- SearchPtr := ListHead;
- WITH MacroRegs DO
- WHILE (SearchPtr <> NIL) AND (AX <> SearchPtr^.Scancode) DO
- SearchPtr := SearchPtr^.Next;
- IF (SearchPtr <> NIL) AND SearchPtr^.Active THEN BEGIN
- Macro := SearchPtr^.Replacement;
- PgmAX := Macro[1]; (* ersten Code uebergeben *)
- MacroPtr := 2
- END
- ELSE PgmAX := MacroRegs.AX
- END;
- 1: IF MacroPtr <= MacroLen THEN BEGIN (* liegen n. Makro-Zeichen vor? *)
- PgmAL := $00;
- PgmFlags := PgmFlags AND $BF (* Zero-Flag loeschen *)
- END
- ELSE BEGIN
- MacroRegs.AH := $01; Intr (Old_Kbd, MacroRegs);
- PgmFlags := MacroRegs.Flags; PgmAX := MacroRegs.AX
- END;
- 2: PgmAL := ShiftState
- END;
- {$I ENDINT.INC}
- (* ------------------------------------------------------------------------- *)
- (* HYPERKEY: Unterprogramm zur Manipulation von Tastaturmakros *)
- PROCEDURE TSRPgm;
- {$I HYPERKEY.DEC} (* Deklarationen *)
- {$I HYPERKEY.UTL} (* Utility-Routinen *)
- {$I HYPERKEY.HLP} (* Hilfsbildschirme *)
- {$I HYPERKEY.LST} (* Listenoperationen *)
- {$I HYPERKEY.EDT} (* der Makro-Editor *)
- {$I HYPERKEY.PGM} (* das Hauptprogramm *)
- (* ------------------------------------------------------------------------- *)
- (* der Installationsteil von HYPERKEY *)
- {$I INTERRPT.301} (* Interrupt-Handler aus PASCAL 8/87 *)
- BEGIN
- TSR_InUse := FALSE; TSR_terminate := FALSE;
- TSRDseg := DSeg; (* Data Segment Adresse des Interrupts *)
- TSRSseg := SSeg; (* Stack Segment Adresse des Interrupts *)
- LowVideo; WriteLn; WriteLn;
- WriteLn (Version, ' (c) 1987 Karsten Gieselmann & PASCAL INT.');
- IntGet (Old_Kbd, Segm, Offs); (* Interrupt-Vektor holen *)
- IF Segm <> 0 THEN BEGIN (* und ueberpruefen *)
- WriteLn (' Interrupt-Vektor Nr.', Old_Kbd,
- ' schon benutzt - ',Version,' nicht resident!');
- Halt; (* Ende, Schluss, Aus !! *)
- END;
- IntGet (TSR_Int, Segm, Offs); (* den auch ueberpruefen !! *)
- IF Segm <> 0 THEN BEGIN (* und ueberpruefen *)
- WriteLn (' Interrupt-Vektor Nr.', TSR_Int,
- ' schon benutzt - ',Version,' nicht resident!');
- Halt; (* Ende, Schluss, Aus !! *)
- END;
- IntGet (IntKeyBoard, Segm, Offs); (* alten Tastaturvektor holen *)
- IntSet (Old_Kbd, Segm, Offs);
- IntSet (TSR_Int, Cseg, Ofs(MacroInt)); (* Makro-Treiber installieren *)
- TSR_IntIP := MemW [0:TSR_Int*4]; TSR_IntCs := MemW [0:TSR_Int*4+2];
- IntSet (IntKeyBoard, Cseg, Ofs(Interrpt)); (* HYPERKEY installieren *)
- ListHead := NIL; (* dynamische Listenverwaltung initialisieren *)
- ListEnd := NIL; ListPtr := NIL;
- InitWindow; (* Window-Handling initialisieren *)
- MacroPtr := MaxMacroLen; (* Makro-Handling initialisieren *)
- MacroLen := 0;
- WriteLn (' ',Version,' installiert. Aktivieren mit Shift-<F1>...');
- MakeResident;
- END.