XE  V1.33/2012 Anwendung in Batch-Programmen fuer DOS und in DOS-Fen-
FREEWARE       stern von Windows 95/98/ME/NT/2000. Arbeitet aehnlich wie 
               der Befehl ECHO, jedoch koennen mit Ersatzparametern zu
               saetzlich bestimmte Zeichen am Bildschirm ausgegeben werden.
               Auch bestimmte Zusatzfunktionen sind moeglich (siehe unten).
               Der ausgegebene Text kann in eine Datei umgeleitet werden.
               Das Zeichen # wird fuer Ersatzparameter verwendet.
               %-Parameter koennen wie bei ECHO verwendet werden.

Eingabebeispiel:   XE Kommentar 1 :Info -#3E Ablage#; Kommentar 2
Bildschirmausgabe: Info -> Ablage

Der erste Doppelpunkt startet die Bildschirmausgabe,
#; beendet die Bildschirmausgabe

#00 bis #FF  als Ersatz fuer den Hexwert eines auszugebenden Zeichens

#3E >    #7C |    #1B <ESC>    #0C FF  (Seitenvorschub)
#3C <    #25 %    #09 <TAB>    #07 BEL (Klingelzeichen)
#22 "    #26 &    #27 '        #40 @
#0D CR allein     #0A LF allein        #5E ^

#V  zusaetzlicher Zeilenvorschub (CR+LF)
#P  am Zeilenende kein Zeilenvorschub
##  einmal # ausgeben
#G  Zeit-/Datumsstempel auf den Bildschirm ausgeben (Deutsch)
#$  Zeit-/Datumsstempel auf den Bildschirm ausgeben (Englisch)
#H  Zeitstempel auf den Bildschirm ausgeben
#;  ab hier wird die Kommandozeile nicht mehr ausgewertet (Kommentar)

Weitere Funktionen:
-------------------
#=G Synchronisation auf naechste volle Sekunde (wartet bis zum
    naechsten Sekundenwechsel,
    bei Tasteneingabe Abbruch und Errorlevel 100)
#=H Loeschen des Tastaturpuffers, erzeugt Errorlevel 0 oder 1:
    Errorlevel 0, wenn der Puffer leer war
    Errorlevel 1, wenn der Puffer Zeichen enthielt
#X oder #=X Klingelzeichen ertoent, Ausgabe direkt ueber BIOS,
    d. h. keine Umleitung als Zeichen in eine Datei moeglich
#U  Tonausgabe 880 Hz, kurz
#W  Tonausgabe 440 Hz, lang
#=Y Clear Screen
#Z oder #=Z Kein Prompt beim Tastenaufruf
#_\ Laufwerksbuchstabe ausgeben
#\  Aktuelles Verzeichnis ausgeben (mit \ am Ende)

#[...] Tastenaufruf
---------------------------------------------------------------
Zwischen den Klammern [] koennen die Zeichen A...Z, 0...9 und das
Leerzeichen eingetragen werden. Das Programm erwartet die Eingabe
einer Taste. Stimmt die eingegebene Taste mit einem der Zeichen 
ueberein, wird das Programm fortgesetzt und ein Errorlevel 1...n
erzeugt, wobei n die Stellung des Zeichens zwischen den Klammern
ist. A...Z ist gleichbedeutend mit a...z. Wird das Leerzeichen
vorgegeben, erzeugt beim Aufruf die Enter-Taste den gleichen
Errorlevel wie das Leerzeichen. Anstelle der Ziffern 0..9 koennen
auch die Funktionstasten F1..F10 bedient werden (0=F10). 
Beispiel:  XE :#[d7T ]
Wirkung:   D oder d erzeugen Errorlevel 1
           7 oder F7 erzeugt Errorlevel 2
           T oder t erzeugen Errorlevel 3
           Leerzeichen oder  Enter-Taste erzeugen Errorlevel 4
           ESC      erzeugt  Errorlevel 0 (fest eingestellt)
Zwischen den Klammern duerfen max. 40 Zeichen stehen. Werden Zeichen
mehrfach verwendet, wird nur das erste davon beruecksichtigt. 
Beispiel:  XE :#[A 5 u a]
Wirkung:   A oder a erzeugen Errorlevel 1
           Leerzeichen oder  Enter-Taste erzeugen Errorlevel 2
           5 oder F5 erzeugt Errorlevel 3
           U oder u erzeugen Errorlevel 5
           ESC      erzeugt  Errorlevel 0 (fest eingestellt)
           Errorlevels 4, 6 und 7 werden nicht erzeugt
                                  wegen der Mehrfachbelegung.
Wird eine vorbestimmte Taste bedient, wird das entsprechende Zeichen
auf den Bildschirm geschrieben. Fuer ESC, Leerzeichen und Enter wird
ein Leerzeichen ausgegeben. Will man aus bestimmten Gruenden diesen
Tastenprompt nicht, setzt man an den Anfang der Kommandozeilenverlaen-
gerung die Zeichenfolge #=Z oder #Z  
Beispiel:  XE :#=ZTextText#[ABC123 ]Mehr Text
Ausgabe:   TextTextMehr Text  (die Tasteneingabe hat keine Ausgabe
                               zur Folge)
Besondere Eigenschaft: Wird kein Zeichen zwischen [] angegeben,
wird jede Taste akzeptiert und Errorlevel 0 erzeugt (vgl. ESC).

#(...) Cursor-Beeinflussung
-------------------------------------------------------------------
Bei Aufruf von #(...) (Cursor-Beeinflussung) wird der Cursor in
seinem Aussehen und/oder in seiner Position auf dem Bildschirm
beeinflusst. Zwischen den Klammern kann stehen:

 #(N) oder #(ON)   Cursor wird eingeschaltet (VGA und hoeher)
 #(F) oder #(OFF)  Cursor wird ausgeschaltet (VGA und hoeher)
 #(V) oder #(VGA)  Standardeinstellung VGA und hoeher (auch MCGA)
 #(C) oder #(CGA)  Standardeinstellung CGA und hoeher
 #(M) oder #(MDA)  Standardeinstellung MDA, HERCULES, EGA
 #(B) oder #(BIG)  Grosser Cursor
 #(-)              Duenner Cursor
 #(+)              Dicker Cursor
 #(X46) Setzt Cursor in die 46. Spalte (geht von 1 bis 80)
 #(Y17) Setzt Cursor in die 17. Zeile  (geht von 1 bis 25)
 #(R)   Speichert aktuelle Cursorposition im Speicher 0
 #(S)   Setzt Cursorposition auf den Inhalt vom Speicher 0
 #(T)   Speichert aktuelle Cursorposition im Speicher 1
 #(U)   Setzt Cursorposition auf den Inhalt vom Speicher 1
 #(W)   Verschiebt Cursor um eine Position nach oben (funktioniert
        nur, wenn der Cursor nicht schon ganz oben ist)
 #(E)   Verschiebt Cursor um eine Position nach unten (funktioniert
        nur, wenn der Cursor nicht schon ganz unten ist)
 #(P)   Verschiebt Cursor um eine Position nach links (funktioniert
        nur, wenn der Cursor nicht schon ganz links ist)
 #(Q)   Verschiebt Cursor um eine Position nach rechts (funktioniert
        nur, wenn der Cursor nicht schon ganz rechts ist)

 Es koennen mehrere Parameter in einem Kommando angegeben werden, z.B.
 XE :#(FX53Y12R)Hallo#(SN)

Im DOS-Fenster von Windows NT/2000 funktionieren bei der Cursor-Be-
einflussung nur die Cursorbewegungen sowie das Speichern und Wieder-
herstellen von Cursorpositionen. Das Unsichtbarmachen des Cursors
sowie das Setzen von VGA, CGA usw. funktioniert im emulierten
NT/2000-DOS-Fenster nicht.

#=(...) Aufruf zum Eingeben einer Zeichenfolge (String)
-------------------------------------------------------
Zwischen den Klammern bei #=(...) wird der vollstaendige Name einer Datei
eingetragen. Die Funktion erwartet die Eingabe einer Zeichenfolge
(max. 128 Zeichen) ueber die Tastatur, die mit <Enter> abgeschlossen
wird. Die Zeichenfolge wird dann in der angegebenen Datei abgespeichert.
Die letzten Zeichen in der Datei sind CR/LF. Wenn diese Datei als Batch-
Datei lauffaehig ist, kann sie z.B. aus einem gerade laufenden Batch-
Programm mit CALL aufgerufen werden.

#{...} Einfuegen einer Text-Zeichenfolge (Textstring) aus einer Datei
---------------------------------------------------------------------
Zwischen den Klammern bei #{...} wird der vollstaendige Name der Datei
eingetragen, aus der die Zeichenfolge entnommen und auf den Bildschirm
gebracht werden soll. Aus der Datei werden maximal die ersten 128 Zei-
chen entnommen. Eventuell in der Datei vorhandene Zeichen CR, LF oder
CTRL-Z werden ignoriert.
Beispiel: XE :#{C:\TEXTE\SPEZIAL\SCHREIB.TXT}
Der Dateiname und die Verzeichnisnamen muessen den DOS-Vereinbarungen
entsprechen. Lange Dateinamen werden nicht erkannt. Wird die angege-
bene Datei nicht gefunden, so wird nichts eingefuegt (auch keine
Fehlermeldung).

#={...} Einfuegen des Inhalts aus einer Datei
---------------------------------------------
Zwischen den Klammern bei #={...} wird der vollstaendige Name der Datei
eingetragen, aus der der Inhalt entnommen und auf den Bildschirm gebracht
werden soll. Falls TABs in der Datei enthalten sind, werden diese durch
eine passende Anzahl von Leerzeichen ersetzt. Die Datei kann beliebig
lang sein.

Beispiel: XE :#={C:\TEXTE\SPEZIAL\SCHREIB.TXT}

Der Dateiname und die Verzeichnisnamen muessen den DOS-Vereinbarungen
entsprechen. Lange Dateinamen werden nicht erkannt. Wird die angege-
bene Datei nicht gefunden, so wird nichts eingefuegt (auch keine
Fehlermeldung).

#+...+ Warten (Delay)
---------------------------------------------------------------
Zwischen den beiden Plus-Zeichen von #+...+ wird eine Zahl
(1 bis max. 65535) eingetragen. Diese Funktion startet eine Warte-
zeit in Sekunden. Wird waehrend der Wartezeit eine Taste bedient,
so wird das Warten abgebrochen und Errorlevel 100 gesetzt.
Zahlenangaben groesser als 65535 fuehren zu undefinierten Ergebnissen.
Eingabe-Beispiel: XE :#+25+
Das Plus-Zeichen nach der Zahlenangabe darf nicht vergessen werden,
sonst arbeitet die Wartezeitfunktion nicht.

#I...+ Warten (Count-Down)
---------------------------------------------------------------
Zwischen den beiden Zeichen I und + von #I...+ wird eine Zahl
(1 bis max. 65535) eingetragen. Diese Funktion startet eine Warte-
zeit in Sekunden als sichtbarer Count-Down. Wird waehrend der
Wartezeit eine Taste bedient, so wird das Warten abgebrochen und
Errorlevel 100 gesetzt.
Zahlenangaben groesser als 65535 fuehren zu undefinierten Ergebnissen.
Eingabe-Beispiel: XE :#I25+
Das Plus-Zeichen nach der Zahlenangabe darf nicht vergessen werden,
sonst arbeitet der Count-Down nicht.

#-...- Warten bis zu einer bestimmten Uhrzeit
---------------------------------------------------------------
Zwischen den beiden Minus-Zeichen von #-...- wird eine Uhrzeit
(00:00 bis 23:59) eingetragen. Diese Funktion startet eine Warte-
zeit, die mit der eingestellten Uhrzeit ablaeuft. Wird waehrend der
Wartezeit eine Taste bedient, so wird das Warten abgebrochen und
Errorlevel 100 gesetzt.
Zeitangaben, die keiner gueltigen Uhrzeit entsprechen, fuehren zu
undefinierten Ergebnissen. Zu beachten ist auch, dass sowohl Stunden
als auch Minuten zweistellig angegeben werden muessen.
Eingabe-Beispiel: XE :#-00:09-
            oder: XE :Ich warte bis 09:05 Uhr #-09:05- #G
Das zweite Beispiel schreibt nach Ablauf der Wartezeit zur Kontrolle
den Zeitstempel mit auf den Bildschirm.
Das Minus-Zeichen nach der Zeitangabe darf nicht vergessen werden,
sonst arbeitet die Wartezeitfunktion nicht.

Arbeiten mit Variablen (hauptsaechlich fuer Zaehler und Timer)
--------------------------------------------------------------
Das Programm arbeitet mit zwei Variablen, die ganzzahlige Werte von
-32767...0...+32767 annehmen koennen. Die Variablen werden ueber
#!.... (Variable 1) und #:.... (Variable 2) angesprochen.
Die folgenden Beispiele zeigen die Moeglichkeiten.
Dabei koennen die Zahlen mit oder ohne Vorzeichen angegeben werden,
z. B. 200 oder +200 (positive Zahl) oder -200 (negative Zahl):

#!-200! Variable 1 wird auf -200 gesetzt
#!N     Variable 1 wird negiert (Vorzeichen - statt + bzw. umgekehrt)
#!=     Variable 1 wird angezeigt (mit Vorzeichen plus 5 Stellen)
#!D     Variable 1 wird angezeigt (nur die notwendigen Stellen)
#!_     Variable 1 wird als eine Anzahl von Sekunden interpretiert
        und im Format HH:MM:SS (Stunden, Minuten, Sekunden) angezeigt
        (Variable 1 soll dabei eine positive Zahl sein, 0...+32767)
#!6548? Variable 1 wird mit der Zahl +6548 verglichen. Ergebnis:
          Errorlevel 3 wenn Variable 1 groesser ist als die Zahl
          Errorlevel 2 wenn Variable 1 und Zahl gleich gross sind
          Errorlevel 1 wenn Variable 1 kleiner ist als die Zahl
#!34+   Variable 1 wird um 34 erhoeht
#!72-   Variable 1 wird um 72 vermindert
#!-32*  Variable 1 wird mit -32 multipliziert
#!18/   Variable 1 wird durch 18 dividiert, das
          Ergebnis wird stets auf eine ganze Zahl nach unten gerundet
#!K     Variable 1 wird ueber die Tastatur eingegeben.
          Beispiel:  XE :Wie oft drucken? #!K#!= Exemplare
          Ueber die Tastatur wird nach Aufruf ueber #!K eine Zahl
          von -32767...0...32767 eingegeben. Andere Werte fuehren
          zu Fehlern. Die Eingabe wird mit Enter beendet. Nach dem
          Druecken der Enter-Taste geht der Cursor zurueck auf die
          erste Position der Zahleneingabe.
#!L     Der "innere" Errorlevel (waehrend XE laeuft) wird nach
          Variable 1 kopiert.
#!M     Aus Variable 1 wird ein Errorlevel erzeugt (0...255). Falls
          Variable 1 nicht innerhalb dieses Bereiches liegt, wird das
          Lower Byte zur Erzeugung benutzt. Variable 1 wird durch
          diesen Vorgang nicht veraendert.
#!{...} Variable 1 wird aus der Datei geladen, deren Name zwischen
          den Klammern {} steht. Beispiel: XE :#!{C:\XE\VAR1.VAR}
          In der genannten Datei muss eine gueltige Zahl -32767...+32767
          enthalten sein.
          Beispiele fuer Dateiinhalte:  5   -67  +00008  -056
          Lesen Sie auch die Datei VAR_D.VAR.
#!(...) Variable 1 wird in die Datei kopiert, deren Name zwischen
          den Klammern () steht. Beispiel: XE :#!(C:\XE\VAR1.VAR)

#:200:  Variable 2 wird auf +200 gesetzt
#:N     Variable 2 wird negiert (Vorzeichen - statt + bzw. umgekehrt)
#:=     Variable 2 wird angezeigt (mit Vorzeichen plus 5 Stellen)
#:D     Variable 2 wird angezeigt (nur die notwendigen Stellen)
#:_     Variable 2 wird als eine Anzahl von Sekunden interpretiert
        und im Format HH:MM:SS (Stunden, Minuten, Sekunden) angezeigt
        (Variable 2 soll dabei eine positive Zahl sein, 0...+32767)
#:-548? Variable 2 wird mit der Zahl -548 verglichen. Ergebnis:
          Errorlevel 3 wenn Variable 2 groesser ist als die Zahl
          Errorlevel 2 wenn Variable 2 und Zahl gleich gross sind
          Errorlevel 1 wenn Variable 2 kleiner ist als die Zahl
#:34+   Variable 2 wird um 34 erhoeht
#:72-   Variable 2 wird um 72 vermindert
#:50*   Variable 2 wird mit 50 multipliziert
#:-18/  Variable 2 wird durch -18 dividiert, das
          Ergebnis wird stets auf eine ganze Zahl nach unten gerundet
#:K     Variable 2 wird ueber die Tastatur eingegeben.
          Weitere Beschreibung siehe #!K
#:L     Der "innere" Errorlevel (waehrend XE laeuft) wird nach
          Variable 2 kopiert.
#:M     Aus Variable 2 wird ein Errorlevel erzeugt (0...255). Falls
          Variable 2 nicht innerhalb dieses Bereiches liegt, wird das
          Lower Byte zur Erzeugung benutzt. Variable 2 wird durch
          diesen Vorgang nicht veraendert.
#:{...} Variable 2 wird aus der Datei geladen, deren Name zwischen
          den Klammern {} steht. Beispiel: XE :#:{C:\XE\VAR2.VAR}
          Weitere Beschreibung siehe #!{...}
#:(...) Variable 2 wird in die Datei kopiert, deren Name zwischen
          den Klammern () steht. Beispiel: XE :#:(C:\XE\VAR2.VAR)

#!:+    Variable 1 wird um den Wert in Variable 2 erhoeht
#!:-    Variable 1 wird um den Wert in Variable 2 vermindert
#!:*    Variable 1 wird mit dem Wert in Variable 2 multipliziert
#!:/    Variable 1 wird durch den Wert in Variable 2 dividiert, das
          Ergebnis wird stets auf eine ganze Zahl nach unten gerundet
#!:!    Variable 1 wird mit Variable 2 vertauscht
#!:?    Variable 1 wird mit Variable 2 verglichen. Ergebnis:
          Errorlevel 3 wenn Variable 1 groesser ist als Variable 2
          Errorlevel 2 wenn Variable 1 und Variable 2 gleich gross sind
          Errorlevel 1 wenn Variable 1 kleiner ist als Variable 2
#!:_    Variable 1 uebernimmt den Wert von Variable 2,
          Variable 2 wird dabei nicht veraendert

#!:\    Variable 1 wird durch Variable 2 dividiert. Ergebnis:
          Variable 1 enthaelt das Divisionsergebnis
          Variable 2 enthaelt den Divisionsrest

#:!+    Variable 2 wird um den Wert in Variable 1 erhoeht
#:!-    Variable 2 wird um den Wert in Variable 1 vermindert
#:!*    Variable 2 wird mit dem Wert in Variable 1 multipliziert
#:!/    Variable 2 wird durch den Wert in Variable 1 dividiert, das
          Ergebnis wird stets auf eine ganze Zahl nach unten gerundet
#:!:    Variable 2 wird mit Variable 1 vertauscht
#:!?    Variable 2 wird mit Variable 1 verglichen. Ergebnis:
          Errorlevel 3 wenn Variable 2 groesser ist als Variable 1
          Errorlevel 2 wenn Variable 2 und Variable 1 gleich gross sind
          Errorlevel 1 wenn Variable 2 kleiner ist als Variable 1
#:!_    Variable 2 uebernimmt den Wert von Variable 1,
          Variable 1 wird dabei nicht veraendert

Die Inhalte der Variablen gehen verloren, wenn der Rechner neu
gebootet wird oder bei Kalt- oder Warmstart. Beim Schliessen des
DOS-Fensters in Win95/98/ME/NT/2000 kann moeglicherweise der Variablen-
inhalt ebenfalls verlorengehen. Falls Variablen zwischengespeichert und
wieder geladen werden sollen, stehen hierfuer die Funktionen
#!{...}  #!(...)  #:{...}  #:(...) zur Verfuegung.

Die Variablen nutzen die RAM-Speicheradressen der sogenannten Intra
Application Communication Area, ICA (40h:00F0h bis 40h:00FFh) zum
Speichern. Falls ein anderes Programm ebenfalls diese Speicherstellen
benutzt, funktionieren moeglicherweise die Variablen nicht richtig.
Der Test verlief bisher auf allen Testrechnern erfolgreich (viele
unterschiedliche Rechner alt und neu, DOS oder DOS-Fenster).

Anmerkungen: 
- Alle Ergebnisse sind nur dann richtig, wenn sie den Zahlenbereich
  bereich von -32767...0...+32767 nicht verlassen.
- Wird versucht, bei der Division durch 0 zu teilen, wird dieser
  Auftrag nicht ausgefuehrt.
- Die Zahl 0 ist nicht negierbar (-0 und +0 sind gleich und werden
  immer als +00000 dargestellt).
  
Returncode-Erzeugung (Errorlevel)
---------------------------------
Returncodes koennen an jeder Stelle der Kommandozeile erzeugt werden.
Werden in einer Zeile mehrmals Returncodes erzeugt, so bleibt der
letzte erhalten und kann mit IF ERRORLEVEL ausgewertet werden.

Returncode setzen: #R00 bis #RFF (Hexwert ergibt den Code 0..255).
Returncode aus aktuellem Laufwerk erzeugen (A=1, B=2 usw.): #R\

#,.., Spezialfunktion: Angabe eines Laufwerksbuchstabens testen
---------------------------------------------------------------
Wird zwischen den beiden Kommas von #,.., ein moeglicher Laufwerks-
buchstabe eingetragen, z. B. #,d:, so wird beim Beenden des Pro-
gramms ein Errorlevel gesetzt. Fuer A: wird Errorlevel 1 gesetzt,
fuer Z: Errorlevel 26. Steht zwischen den beiden Kommas kein moegli-
cher Laufwerksbuchstabe, wird Errorlevel 0 ausgegeben. Folgende
Schreibweisen fuehren ebenfalls zu Errorlevel 0:
#,c,   der Doppelpunkt fehlt
#,C:   das zweite Komma fehlt
#,c:\  das ist ein Verzeichnis, kein Laufwerk
#, C:, das Leerzeichen darf nicht sein
#,C:x, keine eindeutige Bezeichnung
In Batch-Dateien kann z. B. eingetragen sein:  XE :#,%1,
Wenn im ersten Parameter der Kommandozeile z. B. D: steht, wird %1
als gueltiges Laufwerk erkannt.

Details zum Programm
--------------------
Das Programm wurde in Assembler geschrieben. Im Zusammenhang mit dem
Ersatzparameter # haben Gross- und Kleinbuchstaben die gleiche Wir-
kung, z.B. #3A ist identisch mit #3a. Das Programm darf beliebig
weitergegeben werden, jedoch stets nur zusammen mit den Dateien 
XE_D.TXT, XE_E.TXT und den Beispiel-Batch-Dateien.

Belegung des ICA (40h:00F0h bis 40h:00FFh):
-------------------------------------------
F0 F1  F2 F3    F4 F5 F6 F7 F8 F9 FA FB  FC FD  FE FF
#(rs)  #(tu)                             #:...  #!...
Cursurposition  ------noch frei--------  Variablen

---------------------------------------------------------------------
XE (eXtended Echo) (C) Claussen Riedwiesenweg 10, D-69181 Leimen
FREEWARE               claussen.leimen@t-online.de
                       http://www.claus-juergen-claussen.de/
---------------------------------------------------------------------
