home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 05 / t3_tsr / ptr.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-02-17  |  6.7 KB  |  159 lines

  1. (* ------------------------------------------------------ *)
  2. (*                       PTR.PAS                          *)
  3. (*       eigener Druckertreiber mit Turbo-Pascal          *)
  4. (* System: MSDOS 3.1 &  Turbo Pascal 3.0                  *)
  5.  
  6. PROGRAM NewPtr;
  7.  
  8. CONST userint   = $63;  { neuer Interrupt                  }
  9.       deviceint = $17;  { alter Gerätevector (z.B. Printer,}
  10.                         { Screen,RS232) in diesem Fall     }
  11.                         {  $17 = Printer                   }
  12.       segbuf    = $80;  { Speicher f. Register.            }
  13.                         { CS ist Bezugssegment             }
  14.                         { +0 = Dseg  +2 = Sseg             }
  15.                         { +4 Sseg des Treibers             }
  16.                         { +6 = Eseg des Rufers             }
  17.                         { +8 = AX Kommandocode             }
  18.                         {+10 = DX Druckernummer            }
  19.  
  20. VAR Segment,Offset : INTEGER;
  21.  
  22. (*$I REGS8088.INC *)
  23. (*$I MAKEINT.INC*)
  24.  
  25. {==========================================================}
  26. { diese Procedure kann ohne Restriktionen vom Anwender }
  27. { programmiert werden wobei IN: AX,DX                  }
  28. {                           OUT: AX                    }
  29. { ANMERKUNG: bei anderen Geräten (Screen,RS232) andere }
  30. { Schnittstelle zum BIOS, d.h keine generelle Lsg.     }
  31. { abhängig wie Register benutzt werden                 }
  32.  
  33. PROCEDURE Interpret;
  34.  
  35. VAR AH,AL: BYTE;
  36.     AX,DX: INTEGER;
  37.     r:     Regs8088_;
  38.  
  39.  PROCEDURE PrintChar(ch:CHAR);
  40.  { druckt Zeichen über eigentliche BIOS-Routine aus }
  41.  VAR v: Regs8088_;
  42.  BEGIN
  43.   v.DX:=DX;                    { DX global in InterPret    }
  44.   v.AX:=00+Ord(ch);            { Code AH = 0 => Drucken    }
  45.   Intr(userint,v);
  46.   MemW[Cseg:segbuf+8]:=v.AX    { setze etwaigen Status     }
  47.                                { für Rückgabe              }
  48.  END; { PrintChar }
  49.  
  50. BEGIN
  51.   AX:=MemW[Cseg:segbuf+8];  DX:=MemW[Cseg:segbuf+10];
  52.   AL:=Lo(AX); AH:=Hi(AX);
  53.   IF AH=0 THEN BEGIN           { AH=0 Code für Drucken     }
  54.  
  55. {""""""""""""""""""" Anwenderteil "" Beispiel """""""""""""}
  56. { hier kann entsprechend auf ein eingegangenes Zeichen     }
  57. { reagiert werden. Da globale Variablen erhalten bleiben,  }
  58. { können auch Algorithmen mit Gedächtnis geschrieben wer-  }
  59. { den. z.B. können Codesequenzen dadurch erkannt und inter-}
  60. { pretiert werden.                                         }
  61. { ANMERKUNG: Das komplette Turbo-Laufzeitsystem kann       }
  62. { benutzt werden !!!!                                      }
  63.  
  64.     CASE Chr(AL) OF            { Bsp: Umsetzen der Umlaute }
  65.      'ä': PrintChar('a');
  66.      'ö': PrintChar('o');
  67.      'ü': PrintChar('u');
  68.      'Ä': PrintChar('A');
  69.      'Ö': PrintChar('O');
  70.      'Ü': PrintChar('U');
  71.      'ß': BEGIN PrintChar('s'); PrintChar('s') END
  72.      ELSE PrintChar(Chr(AL))          { normales Zeichen ! }
  73.     END;
  74.     IF Chr(AL) IN ['ä','Ä','ö','Ö','ü','Ü'] THEN
  75.       PrintChar('e');
  76.   END
  77.   ELSE BEGIN
  78.     r.AX:=AX;                    { Kommando        }
  79.     r.DX:=DX;                    { Druckernummer ! }
  80.     Intr(userint,r);             { führe alten Interrupt }
  81.     MemW[Cseg:segbuf+8]:=r.AX
  82.   END
  83. END; { Interpret }
  84.  
  85. {----------------------------------------------------------}
  86. { auf diese Procedure wird der Interrupt-Vector gerichtet. }
  87. { Es darf keine Variable angelegt werden, da sonst anderer }
  88. { Code erzeugt wird, und der Versatz +7 nicht mehr stimmt. }
  89. { (siehe Activate)                                         }
  90. PROCEDURE NewInterrupt;
  91.  
  92. BEGIN
  93.   INLINE($53/$51/$52/           { PUSH BX-DX               }
  94.          $57/$56/$55/$1e/$06/   { PUSH DI,SI,BP,DS,ES      }
  95.            { rette alle Register außer AX,SS,SP            }
  96.            { (benutze alten SP weiter)                     }
  97.          $2e/$a3/segbuf+8/$00/     { MOV CS:[segbuf+8],AX  }
  98.          $2e/$89/$16/segbuf+10/$00/
  99.                                    { MOV CS:[segbuf+10],DX }
  100.            { rette AX und DX in Speicherbereich die von    }
  101.            { Interpret verarbeitet werden wobei AH=Kom-
  102.            { mandobyte, AL=Druckbyte, DX=Druckernummer     }
  103.          $8c/$d0/               { MOV AX,SS                }
  104.          $2e/$a3/segbuf+6/$00/  { MOV CS:[segbuf+6],AX     }
  105.            { rette altes Stacksegment. WESENTLICH !  Da
  106.            { Pascal intensivst über Stack arbeitet(Dynamik)}
  107.            { muß eigener Stack verwendet werden.           }
  108.          $2e/$a1/segbuf+0/$00/  { MOV AX,CS:[segbuf]       }
  109.          $8e/$d8/               { MOV DS,AX                }
  110.          $2e/$a1/segbuf+2/$00/  { MOV AX,CS:[segbuf+2]     }
  111.          $8e/$d0/               { MOV SS,AX                }
  112.          $2e/$a1/segbuf+4/$00/  { MOV AX,CS:[segbuf+4]     }
  113.          $8e/$c0);              { MOV ES,AX                }
  114.            { Lade DS,ES,SS mit den Werten die bei der In-  }
  115.            { stallation gesichert wurden. Jede Turbo Pascal}
  116.            { Procedure ist nun voll lauffähig.             }
  117.  
  118.   Interpret; { eigentliche Service-Routine aufrufen}
  119.  
  120.   INLINE($2e/$a1/segbuf+6/$00/  { MOV AX,CS:[segbuf+6]     }
  121.          $8e/$d0/               { MOV SS,AX                }
  122.            { Stelle nun SS wieder auf Rufer ein (SP wurde  }
  123.            { durch Turbo Pascal benutzt, aber muß natürlich}
  124.            { unverändert von Interpret zurückkommen, darum }
  125.            { braucht er nicht gesichert zu werden).        }
  126.          $07/$1f/$5d/$5e/$5f/   { POP ES,DS,BP,SI,DI       }
  127.          $5a/$59/$5b/           { POP DX-BX                }
  128.            { hole alle Registerwerte vom Stack             }
  129.          $2e/$a1/segbuf+8/$00/  { MOV AX,CS:[segbuf+8]     }
  130.            { Da AX Rückgabeparameter ist (Status-          }
  131.            { information) muß AX beladen werden.           }
  132.          $cf)                   { IRET                     }
  133. END; { NewInterrupt }
  134.  
  135. {==========================================================}
  136.  
  137. BEGIN
  138.   WriteLn;
  139.   WriteLn('modifizierter BIOS-Interrupt:');
  140.   IntGet(userint,Segment,Offset);
  141.   IF Segment<>0 THEN
  142.     WriteLn('Interrupt schon benutzt, Treiber nicht ',
  143.             'aktiviert...')
  144.   ELSE BEGIN
  145.     IntGet(deviceint,Segment,Offset);
  146.                    { bestimme Adresse des Original-Vectors }
  147.     IntSet(userint,Segment,Offset);
  148.                        { und kopiere sie in unseren Vektor }
  149.     IntSet(deviceint,Cseg,ofs(NewInterrupt)+7);
  150.                 (* unseren Treiber in Interrupt einhängen *)
  151.     MemW[Cseg:segbuf  ]:=Dseg;   { rette die Segmentregi-  }
  152.     MemW[Cseg:segbuf+2]:=Sseg;   { ster DS/SS/ES um vom    }
  153.                                  { BIOS aus zu arbeiten.   }
  154.     INLINE($2e/$8c/$06/segbuf+4/0); { MOV CS:[segbuf+4],ES }
  155.     WriteLn('Treiber aktiviert... ');
  156.     MakeResident;
  157.   END;
  158. END.
  159.