MSRBASIC   Version 4.0

       Messen Steuern Regeln

 Mit Erweiterungen der Version 4.2



ELZET 80 Mikrocomputer GmbH & Co,KG
            52062 Aachen
           www.elzet80.de




                  -1-
Alle Informationen in diesem Handbuch werden ohne Rücksicht auf
einen eventuellen Patentschutz veröffentlicht. Warennamen werden
ohne Gewährleistung der freien Verwendbarkeit benutzt.
MSRBASIC Version 4.0 basiert auf MSRBASIC wie es am Lehrstuhl für
Steuerungs- und Regelungstechnik an der Technischen Universität
München (Prof. Dr-Ing. G. Schmidt) mit Version 3.0 definiert wurde.
Der von ELZET 80 Mikrocomputer erworbene Quelltext dieser Version
wurde völlig überarbeitet, mit neuen Features versehen und
Kundenwünschen angepasst.
MSRBASIC ist ein mit großem Aufwand sorgfältig hergestelltes
Qualitätsprodukt. Das illegale Kopieren und Vertreiben dieses
Produktes stellt daher einen Diebstahl geistigen Eigentums dar und
wird urheberrechtlich verfolgt.

Dieses Handbuch basiert auf Unterlagen der LLSR an der TU München.
Es wurde um die zusätzlichen Befehle der ELZET 80 Version erweitert.

Bei der Zusammenstellung von Texten und Abbildungen und bei der
Programmierung von MSRBASIC wurde mit größter Sorgfalt vorgegangen.
Trotzdem können Fehler nicht völlig ausgeschlossen werden. Daher
kann ELZET 80 Mikrocomputer im Namen der Autoren für Fehler
jeglicher Art und deren Folgen werde eine juristische Verantwortung
noch irgendeine Haftung übernehmen.

Alle Rechte vorbehalten, auch für die fotomechanische Wiedergabe und
der Speicherung in elektronischen Medien.
2. erweiterte Ausgabe 1992
(C)   LLSR, TU München und ELZET 80 Mikrocomputer Aachen 1989




                                 -2-
1. Vorwort
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . -15-

2. Allgemeines . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   -16-
     2.1 Sinn und Zweck von MSRBASIC . . . . .      .   .   .   .   .   .   .   .   -16-
     2.2 Anweisungen, Datentypen und Sonstiges      .   .   .   .   .   .   .   .   -17-
           2.2.1 Anweisungen . . . . . . . . .      .   .   .   .   .   .   .   .   -17-
           2.2.2 Buchstaben . . . . . . . . . .     .   .   .   .   .   .   .   .   -17-
           2.2.3 Datentypen . . . . . . . . . .     .   .   .   .   .   .   .   .   -17-
           2.2.4 Datenstrukturen . . . . . . .      .   .   .   .   .   .   .   .   -17-
           2.2.5 Editor . . . . . . . . . . . .     .   .   .   .   .   .   .   .   -17-
           2.2.6 Felder . . . . . . . . . . . .     .   .   .   .   .   .   .   .   -18-
           2.2.7 Funktionen . . . . . . . . . .     .   .   .   .   .   .   .   .   -18-
           2.2.8 Kanalnummern . . . . . . . . .     .   .   .   .   .   .   .   .   -18-
           2.2.9 Kommandos . . . . . . . . . .      .   .   .   .   .   .   .   .   -18-
           2.2.10 Kommentare . . . . . . . . .      .   .   .   .   .   .   .   .   -18-
           2.2.11 Operatoren . . . . . . . . .      .   .   .   .   .   .   .   .   -19-
           2.2.12 Programm . . . . . . . . . .      .   .   .   .   .   .   .   .   -19-
           2.2.13 Starten des Interpreters . .      .   .   .   .   .   .   .   .   -19-
           2.2.14 Transparent-Betrieb . . . . .     .   .   .   .   .   .   .   .   -20-
           2.2.15 Variable . . . . . . . . . .      .   .   .   .   .   .   .   .   -20-
           2.2.16 Zahlenbereich . . . . . . . .     .   .   .   .   .   .   .   .   -21-
3. Editor-Funktionen . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   -21-
     3.1 Übersicht . . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   -21-
     3.2 Funktionsbeschreibung . . . . . . .    .   .   .   .   .   .   .   .   .   -21-
     3.3 Änderung vorhandener Programmzeilen    .   .   .   .   .   .   .   .   .   -22-
4. Echzeitspezifische Sprachmittel . . . . .    .   .   .   .   .   .   .   .   .   -24-
     4.1 Übersicht . . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   -24-
           4.1.1 MSRBASIC-Echtzeitkonzept . .   .   .   .   .   .   .   .   .   .   -24-
           4.1.2 Organisation und Handhabung    .   .   .   .   .   .   .   .   .   -26-
           4.1.3 Beispiel: "Meßwerterfassung"   .   .   .   .   .   .   .   .   .   -27-
           4.1.4 Listing "MESSDEM.BAS" . . .    .   .   .   .   .   .   .   .   .   -28-
           4.1.5 Empfehlungen und Warnungen .   .   .   .   .   .   .   .   .   .   -29-

5. Zusammenfassung der echtzeitspezifischen Befehle         .   .   .   .   .   .   -30-
     5.1 DEFINE   . . . . . . . . . . . . . . . . .         .   .   .   .   .   .   -31-
     5.2 START . . . . . . . . . . . . . . . . . .          .   .   .   .   .   .   -33-
     5.3 SUSPEND . . . . . . . . . . . . . . . . .          .   .   .   .   .   .   -34-
     5.4 ACTIVATE   . . . . . . . . . . . . . . . .         .   .   .   .   .   .   -35-
     5.5 WAIT   . . . . . . . . . . . . . . . . . .         .   .   .   .   .   .   -36-
     5.6 TRACE . . . . . . . . . . . . . . . . . .          .   .   .   .   .   .   -39-
     5.7 NOTRACE . . . . . . . . . . . . . . . . .          .   .   .   .   .   .   -39-
     5.8 TASKLIST   . . . . . . . . . . . . . . . .         .   .   .   .   .   .   -41-
     5.9 SEQLIST . . . . . . . . . . . . . . . . .          .   .   .   .   .   .   -42-
     5.10 Logikfunktionen   . . . . . . . . . . . .         .   .   .   .   .   .   -43-
           5.10.1 NOT(X) . . . . . . . . . . . . .          .   .   .   .   .   .   -43-
           5.10.2 BIT(N,X) . . . . . . . . . . . .          .   .   .   .   .   .   -43-
           5.10.3 Boolsche Ausdrücke . . . . . . .          .   .   .   .   .   .   -44-
     5.11 Prozeß Ein-/Ausgabe-Funktionen . . . . .          .   .   .   .   .   .   -45-
           5.11.1 Skalare Prozeß-Eingabe-Funktionen         .   .   .   .   .   .   -46-
                5.11.1.1 ADC(n)   . . . . . . . . .         .   .   .   .   .   .   -46-
                5.11.1.2 DIN(n)   . . . . . . . . .         .   .   .   .   .   .   -47-
                5.11.1.3 GET(pp) . . . . . . . . .          .   .   .   .   .   .   -49-
                5.11.1.4 CNT(n)   . . . . . . . . .         .   .   .   .   .   .   -50-
           5.11.2 Skalare Prozeß-Ausgabe-Funktionen         .   .   .   .   .   .   -51-
                5.11.2.1 DAC(n)   . . . . . . . . .         .   .   .   .   .   .   -51-
                5.11.2.2 DOUT(n) . . . . . . . . .          .   .   .   .   .   .   -53-
                5.11.2.3 PUT(pp) . . . . . . . . .          .   .   .   .   .   .   -55-

                                -3-
5.11.2.4 CNT(n)   . . . . . . . .       .   .   .   .   .   .   .   -56-
     5.11.3 Vektor Ein/Ausgabe-Funktionen .        .   .   .   .   .   .   .   -57-
           5.11.3.1 MADC(MO)   . . . . . . .       .   .   .   .   .   .   .   -57-
           5.11.3.2 MDAC(SO)   . . . . . . .       .   .   .   .   .   .   .   -57-
           5.11.3.3 MDIN(MD)   . . . . . . .       .   .   .   .   .   .   .   -57-
           5.11.3.4 MDOUT(SD) . . . . . . .        .   .   .   .   .   .   .   -57-
     5.11.4 Abfrage der Prozeßkonfiguration        .   .   .   .   .   .   .   -58-
           5.11.4.1 NDAC   . . . . . . . . .       .   .   .   .   .   .   .   -58-
           5.11.4.2 NADC   . . . . . . . . .       .   .   .   .   .   .   .   -58-
           5.11.4.3 NDOUT . . . . . . . . .        .   .   .   .   .   .   .   -58-
           5.11.4.4 NDIN   . . . . . . . . .       .   .   .   .   .   .   .   -58-
           5.11.4.5 NCNT   . . . . . . . . .       .   .   .   .   .   .   .   -58-
5.12 Zeitgeberfunktionen   . . . . . . . . .       .   .   .   .   .   .   .   -59-
     5.12.1 TDOWN . . . . . . . . . . . . .        .   .   .   .   .   .   .   -59-
     5.12.2 TUP . . . . . . . . . . . . . .        .   .   .   .   .   .   .   -59-
     5.12.3 Zeitfaktor "TIMEFAC" . . . . .         .   .   .   .   .   .   .   -59-
     5.12.4 24 Bit-Zeitgeber (nur TSM) . .         .   .   .   .   .   .   .   -59-
           5.12.4.1 MSRTIMER   . . . . . . .       .   .   .   .   .   .   .   -60-
           5.12.4.2 MSTIMDIF   . . . . . . .       .   .   .   .   .   .   .   -60-
     5.12.5 Kalender und Uhrzeit . . . . .         .   .   .   .   .   .   .   -60-
           5.12.5.1 TIME$ . . . . . . . . .        .   .   .   .   .   .   .   -60-
           5.12.5.2 DATE$ . . . . . . . . .        .   .   .   .   .   .   .   -61-
                5.12.5.3 DOW$ . . . . . .      .   .   .   .   .   .   .   .   -61-
5.13 Reglerfunktionen . . . . . . . . . .      .   .   .   .   .   .   .   .   -62-
     5.13.1 Allgemeines . . . . . . . . .      .   .   .   .   .   .   .   .   -62-
     5.13.2 P/PID-Einzelregler . . . . .       .   .   .   .   .   .   .   .   -63-
     5.13.3 Vektor P/PID-Regler . . . . .      .   .   .   .   .   .   .   .   -63-
5.14 Speicherfunktionen . . . . . . . . .      .   .   .   .   .   .   .   .   -65-
     5.14.1 PEEK(N) . . . . . . . . . . .      .   .   .   .   .   .   .   .   -65-
5.15 Hintergrundspeicher   . . . . . . . .     .   .   .   .   .   .   .   .   -66-
     5.15.1 BGMEMDIM . . . . . . . . . .       .   .   .   .   .   .   .   .   -67-
     5.15.2 BGMEM Wahlfreier Zugriff . .       .   .   .   .   .   .   .   .   -67-
           5.15.2.1 BGMEMPUTR . . . . . .      .   .   .   .   .   .   .   .   -67-
           5.15.2.2 BGMEMGETR . . . . . .      .   .   .   .   .   .   .   .   -68-
     5.15.3 BGMEM Queue-Zugriff . . . . .      .   .   .   .   .   .   .   .   -70-
           5.15.3.1 BGMEMPUTQ . . . . . .      .   .   .   .   .   .   .   .   -70-
           5.15.3.2 BGMEMGETQ . . . . . .      .   .   .   .   .   .   .   .   -71-
     5.15.4 BGMEM Stackzugriff . . . . .       .   .   .   .   .   .   .   .   -72-
           5.15.4.1 BGMEMPUSH . . . . . .      .   .   .   .   .   .   .   .   -72-
           5.15.4.2 BGMEMPOP   . . . . . .     .   .   .   .   .   .   .   .   -73-
     5.15.5 BGMEM Sonderfunktionen . . .       .   .   .   .   .   .   .   .   -74-
           5.15.5.1 BGMEMSS . . . . . . .      .   .   .   .   .   .   .   .   -74-
           5.15.5.2 BGMEMCLEAR   . . . . .     .   .   .   .   .   .   .   .   -76-
           5.15.5.3 BGMEMFRE   . . . . . .     .   .   .   .   .   .   .   .   -77-
5.16 Logical Units (Serienschnittstellen)      .   .   .   .   .   .   .   .   -78-
     5.16.1 LUMODE . . . . . . . . . . .       .   .   .   .   .   .   .   .   -78-
           5.16.2 LUOPEN   . . . . . . .   .   .   .   .   .   .   .   .   .   -78-
     5.16.3 LUAVAIL . . . . . . . . . .    .   .   .   .   .   .   .   .   .   -79-
5.17 Linkadapter   . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   -79-
5.18 BITBUS-Anschluß   . . . . . . . . .   .   .   .   .   .   .   .   .   .   -80-
     5.18.1 Allgemeines . . . . . . . .    .   .   .   .   .   .   .   .   .   -80-
     5.18.2 Datenaustausch vom PC . . .    .   .   .   .   .   .   .   .   .   -80-
     5.18.3 Datenaustausch aus MSRBASIC    .   .   .   .   .   .   .   .   .   -83-
           5.18.3.1 BITZFLAG   . . . . .   .   .   .   .   .   .   .   .   .   -83-
           5.18.3.2 BITRB . . . . . . .    .   .   .   .   .   .   .   .   .   -83-
           5.18.3.3 BITRW . . . . . . .    .   .   .   .   .   .   .   .   .   -83-
           5.18.3.3 BITRH . . . . . . .    .   .   .   .   .   .   .   .   .   -84-
           5.18.3.4 BITRS$   . . . . . .   .   .   .   .   .   .   .   .   .   -84-
           5.18.3.5 BITWB . . . . . . .    .   .   .   .   .   .   .   .   .   -84-

                           -4-
5.18.3.6 BITWW . . . .        .   .   .   .   .   .   .   .   .   .   .   .    -85-
                5.18.3.7 BITWH . . . .        .   .   .   .   .   .   .   .   .   .   .   .    -85-
                5.18.3.8 BITWS$   . . .       .   .   .   .   .   .   .   .   .   .   .   .    -85-
     5.19 Fahrtregler (POS)   . . . . .       .   .   .   .   .   .   .   .   .   .   .   .    -87-
               5.19.1 Allgemeines     .   .   .   .   .   .   .   .   .   .   .   .   .   .    -87-
          5.19.2 POS . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -87-
          5.19.3 POSTYPE . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -87-
          5.19.4 POSSRN . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .    -88-
          5.19.5 FRDEF . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -88-
          5.19.6 FRSETP . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .    -88-
          5.19.7 FRSETKP . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -88-
          5.19.8 FRSETKI(ki) . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -89-
          5.19.9 FRLSFAHRT . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -89-
          5.19.10 FRLDFAHRT . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .    -89-
          5.19.11 FRSTAT . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .    -89-
          5.19.12 FRERROR . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .    -90-
6. Ein-/Ausgabe-Sprachmittel . . . . . . . . . . . .                      .   .   .   .   .    -91-
     6.1 Übersicht . . . . . . . . . . . . . . . . .                      .   .   .   .   .    -91-
           6.1.1 Fenstertechnik . . . . . . . . . . .                     .   .   .   .   .    -92-
           6.1.2 Fenster-Programmierung . . . . . . .                     .   .   .   .   .    -93-
                6.1.2.1 Fenster einschalten   . . . .                     .   .   .   .   .    -93-
                6.1.2.2 Fenster ausschalten   . . . .                     .   .   .   .   .    -93-
                6.1.2.3 Cursor positionieren . . . .                      .   .   .   .   .    -93-
                6.1.2.4 Masken-Dateien ausgeben   . .                     .   .   .   .   .    -93-
                6.1.2.5 Abfragen des oberen Fensters                      .   .   .   .   .    -93-
           6.1.3 Beispiel zur Fenstertechnik . . . .                      .   .   .   .   .    -93-
     6.2 Ein- / Ausgabe-Anweisungen   . . . . . . . .                     .   .   .   .   .    -95-
           6.2.1 INPUT . . . . . . . . . . . . . . .                      .   .   .   .   .    -95-
           6.2.2 PRINT . . . . . . . . . . . . . . .                      .   .   .   .   .    -97-
                6.2.2.1 Tabellierung . . . . . . . .                      .   .   .   .   .    -97-
                6.2.2.2 Cursor-Positionierung   . . .                     .   .   .   .   .    -97-
                6.2.2.3 Formatierung . . . . . . . .                      .   .   .   .   .    -97-
     6.3 Schnittstellenfunktionen   . . . . . . . . .                     .   .   .   .       -100-
           6.3.1 EOF(n) . . . . . . . . . . . . . . .                     .   .   .   .       -100-
           6.3.2 INCHAR$(n) . . . . . . . . . . . . .                     .   .   .   .       -100-
           6.3.3 STATUS(n) . . . . . . . . . . . . .                      .   .   .   .       -101-
           6.3.4 COMMAND(n) . . . . . . . . . . . . .                     .   .   .   .       -101-

7. Standardsprachmittel . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -102-
     7.1 Programmfluß-Steuerung   . .     .   .   .   .   .   .   .   .   .   .   .   .       -102-
           7.1.1 FOR . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -102-
           7.1.2 NEXT . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -104-
           7.1.3 GOSUB . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -105-
           7.1.4 RETURN . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -106-
           7.1.5 GOTO . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -107-
           7.1.6 IF . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -108-
           7.1.7 STOP . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -110-
           7.1.8 END . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -111-
     7.2 Rechen- /Speicheranweisungen         .   .   .   .   .   .   .   .   .   .   .       -112-
           7.2.1 DIM . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -112-
           7.2.2 LET . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -114-
           7.2.3 MAT . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -116-
           7.2.4 VEC . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -117-
           7.2.5 POKE . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -119-
     7.3 Kommentare . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .       -120-
           7.3.1 REM . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .       -120-
     7.4 Dateibefehle   . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -121-
     7.5 Standardfunktionen   . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -122-
           7.5.1 ABS(X) . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .       -122-

                                -5-
7.5.2 ACN(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.3 ASN(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.4 ATN(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.5 COS(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.6 EXP(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.7 INT(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.8 LN(X) . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.9 LOG(X) . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.10 SIN(X) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.11 SQR(X) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
           7.5.12 TAN(X) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -122-
      7.6 Stringfunktionen  . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.1 CHR$(X) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.2 VAL(X$) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.3 LEN(X$) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.4 LEFT$(Q$,N) . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.5 MID$(QS,N,M) . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.6 RIGHT$(Q$,N) . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.7 INSTR({N,}Q$,S$)                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -123-
           7.6.8 ASC(x$) . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -124-
           7.6.9 FTOI$ . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -124-
           7.6.19 FTOIB . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -125-
      7.7 Sonstiges . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -126-
           7.7.1 USR . . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -126-
           7.7.2 CALL . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   -128-
           7.7.3 ONERROR . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   -130-

8. Kommandos . .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -131-
     8.1 AUTO   .   . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -131-
     8.2 CLS . .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -132-
     8.3 FREEZE     . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -133-
     8.4 LIST   .   . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -134-
     8.5 LOAD   .   . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -135-
     8.6 NEW . .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -136-
     8.7 NOFREEZE     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -136-
     8.8 MFREE .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -136-
     8.9 RUN . .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -136-
     8.10 SAVE .    . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -136-

           8.11 SYSTEM . . . . . . . . . . . . . . . . . . .                                              -137-
      8.12 VCL  . . . . . . . . . . . . . . . . . . . . . . .                                             -137-

9. Programmiertips . . . . . . . . . . . . . . . . . .                                        .   .   .   -138-
     9.1 Systemanalyse und Programm-Konzeption . . . .                                        .   .   .   -138-
           9.1.1 Analyse der erforderlichen Parallität                                        .   .   .   -138-
           9.1.2 Restriktive Auslastung . . . . . . . .                                       .   .   .   -139-
     9.2 Programm-Implementierung   . . . . . . . . . .                                       .   .   .   -140-
           9.2.1 Anlagenorientierte Modularisierung . .                                       .   .   .   -140-
     9.3 Übersichtlichkeit der Programme . . . . . . .                                        .   .   .   -141-

10.   Hardware-Anpassung und EPROM-startende                          Systeme             .   .   .   .   -143-
      10.1 Allgemeines   . . . . . . . . . .                          . . . .         .   .   .   .   .   -143-
      10.2 Hardware-Anpassung . . . . . . .                           . . . .         .   .   .   .   .   -143-
           10.2.1 Portadressen . . . . . .                            . . . .         .   .   .   .   .   -144-
      10.3 EPROM-startende Systeme   . . . .                          . . . .         .   .   .   .   .   -145-
           10.3.1 PROMIT . . . . . . . . .                            . . . .         .   .   .   .   .   -146-
           10.4.2 PROMIT bei Z280 Systemen                            . . . .         .   .   .   .   .   -147-

           10.4 Programme in EEPROM   . . . . . . . . . . . .                                             -149-
      10.5 Entwicklungshilfen . . . . . . . . . . . . . . . .                                             -150-


                                              -6-
11. Fehlermeldungen . . . . . . . . . . . . . . . . . . . . .     -151-

12. Stichwortverzeichnis    . . . . . . . . . . . . . . . . . .   -153-
13. Anhang

             Erweiterungen des MSR-Basic für Z280 CPU (TSM/ECB)
     1. Neuerungen bei MSR-Basic V4.2,00 . . .   . . . . . . . . . .
     . . . . . . .
        1.1. IF-ELSE-ENDIF . . . . . . . . . .   . . . . . . . . . .
     . . . . . . .
        1.2. ONERROR Änderung. . . . . . . . .   . . . . . . . . . .
     . . . . . . .
        1.3. INPUT Anweisung . . . . . . . . .   . . . . . . . . . .
     . . . . . . .
        1.4. SEQSTATE und TASKSTATE Funktionen   . . . . . . . . . .
     . . . . . . .
        1.5. FORBID und PERMIT Anweisungen . .   . . . . . . . . . .
     . . . . . . .
        1.6. Logische Operatoren AND und OR. .   . . . . . . . . . .
     . . . . . . .
        1.7. STDSET. . . . . . . . . . . . . .   . . . . . . . . . .
     . . . . . . .

     2. Hintergrundspeicher für MSR-Basic. . . . .   . . . . . . . .
     . . . . . . .
        2.1. Einrichten eines Hintergrundspeichers   . . . . . . . .
     . . . . . . .
        2.2. Wahlfreie Zugriff (Random Acess). . .   . . . . . . . .
     . . . . . . .
        2.3. Zugriff auf Queues. . . . . . . . . .   . . . . . . . .
     . . . . . . .
        2.4. Zugriff auf Stacks . . . . . . . . .    . . . . . . . .
     . . . . . . .
        2.5. Hilfsfunktionen . . . . . . . . . . .   . . . . . . . .
     . . . . . . .
        2.6. Flash-EPROM Hintergrundspeicher . . .   . . . . . . . .
     . . . . . . .
        2.7. Neue E/A-Funktionen für TSM-8AD8

     3. Programmspeicherung in Flash-EPROM . . . . . . . . . . . .
     . . . . . . .

     4. CNT-Zähler und EVCTR Funktion    . . . . . . . . . . . . . .
     . . . . . . .

     5. Neue Timer Funktionen. . . . . . . . . . . . . . . . . . .
     . . . . . . .

     6. MODEM-Hilfsfunktionen.   . . . . . . . . . . . . . . . . . .
     . . . . . . .
        6.1 LUMODE Funktion. .   . . . . . . . . . . . . . . . . . .
     . . . . . . .
        6.2 LUOPEN Funktion. .   . . . . . . . . . . . . . . . . . .
     . . . . . . .
        6.3 LUAVAIL Funktion .   . . . . . . . . . . . . . . . . . .
     . . . . . . .

     7. LINKADAPTER. . . . . . . . . . . . . . . . . . . . . . . .
     . . . . . . .

                                  -7-
8. Bemerkungen zur Programmspeicherung in ein EPROM . . . . .
. . . . . . .
 9. Fahrtregelung mit Gleichstrommotoren . . . . . . . . . . .
. . . . . . .
10. BITBUS Komunikation. . . . . . . . . . . . . . . . . . . .
. . . . . . .

11. Neue, zusätzliche Funktionen . . . . . . . . . . . . . . .
. . . . . . .
12. Programmerhalt
1. Neuerungen beim MSR-Basic V4.2,00
In allen früheren MSR-Basic Versionen unterscheidet man
zwischen Hauptprogramm, Sequenen und Tasks.
Dabei war durch den unübersichtlichen Schedule-Mechanismus
nicht vorhersehbar welchen zeitlichen Anteil dem Hauptprogramm
zugewiesen wird.
Also das Hauprogramm eignete sich lediglich zur Definition von
Sequenzen und Task und dessen Start.
In der Version V4.2 wurde das Hauptrogramm einer Sequenz gleichgestellt.
Das bedeutet, daß das Hauptrogramm immer den gleichen
zeitlichen Anteil zur Ausführung bekommt wie andere definierte
Sequenzen, oder auch in WAIT-Zustand übergehen kann, was
früher nicht möglich war.
Die Numerierung der Sequenzen ist gleichgeblieben (#1..#25).
Dazugekommen ist die Sequenz #0, also das Hauptprogramm.
Ein GOSUB führte dazu, daß der Schedule Mechanismus außer
Kraft gesetzt wurde, bis das Unterprogramm beendet war. Also,
wenn z.B. eine Sequenz ein GOSUB ausführte, wurden alle Task
und Sequenzen angehalten !!!!!
Das schränkte die Anwendung von Unterprogrammem sehr ein, aber
hatte dabei eine nützliche Eigenschaft das es möglich war
durch ein Unterprogramm z.B. Impulse mit fester Länge zu
erzeugen ohne alle Task/Sequenzen anzuhalten und wieder zu
aktivieren. In der neuen Version darf ein man Unterprogramme
verwenden ohne das der Scheduler angehalten wird, weil jede
Task/Sequenz ein eigenes GOSUB-Stack besitzt. Lediglich dürfen
Unterprogramme nicht beliebig andere Unterprogramme aufrufen.
Die Schachtelungstiefe ist auf 4 begrenzt oder auf 3 wenn man
ONERROR Anweisung benutzt. Es muß immer die Aufrufmöglichkeit
eines ONERROR-Unterprogramms bestehen.
Den Scheduler anzuhalten ist weiterhin möglich, aber nicht
mehr durch den GOSUB-Trick sondern durch neue Anweisung
FORBID. Die ebenfalls neue Anweisung PERMIT löst die Schedule-
Sperre wieder auf.

Die Ausdruckanalyse lief bis jetzt auch nicht immer korrekt.
Ein Funktionsaufruf der als Parameter wiederum eine Funktion
hatte führte manchmal zu falschen Ergebnissen. Ganz besonders
die Stringfunktionen machten diesen Fehler. Bei der neuen
Version würde die Ausdruckanalyse ebenfalls umgeschrieben.
Die Ausdruckanalyse hat nicht mehr den iterativen sondern
recursiven Charakter. Diese Analyse unterscheidet neben
Gleitkomma und Stringausdrücken auch Festkommausdrücke (long-
integer). Das bedeutet daß Summen und Produkten von
Funktionen, System-Variablen und Integer-Konstanten viel
schneller berechnet werden. Leider sind noch keine

                           -8-
Festkommavariablen möglich so daß
bei einer Variablenzuweisung ein Festkommaausdruck in
Gleitkommawert umgewandelt werden muß, oder das Vorhandensein
einer Variable im Ausdruck, den Ausdruck automatisch den
Gleitkommatyp gibt.
!!! ACHTUNG !!!
Durch die Festkommaarithmetik können unerwünschte Nebeneffekte
auftreten die früher nicht bekannt waren.
Eine Konstante ohne einem Dezimalpunkt ist ein
Festkommaausdruck, daher ist z.B. (1/10) auch ein Festkommaausdruck.
Weist man einer Gleitkommavarible den Wert (1/10) zu, so
bekommt sie den
Wert (0) zugewiesen!!!.
Man sollte in solchen Fällen explizit statt (1/10), (0.1)
eingeben oder wenigstens eine Gleitkommakonstante verwenden
z.B. (1/10.0) oder (1.0/10).
1.1 IF-ELSE-ENDIF

Neben einem einzeiligen IF...THEN...ELSE... Konstrukt ist ab
Version V4.2
das mehrzeilige IF.../ELSE.../ENDIF Block möglich.
Beispiel:
100 IF a=1              ' Kein THEN also ENDIF muß folgen!
110   a = a-1
120   b = b+1
130 ELSE
140   a = 1
150   b = b+2
160 ENDIF

1.2 ONERROR Änderung
Ab Version V4.2 wird das Scheduling während des Ausführung
eines Unterprogramms nicht mehr angehalten.
Das bedeutet daß bei der Ausführung eines ONERROR-
Unterprgramms die Möglichkeit bestehen würde daß ONERROR-
Unterprogramm vom mehren Tasks oder Sequenzen nebenläufig
ausgeführt würde. Der Interpreter würde es zwar
korrekt ausführen, aber für jede Anwendung wäre es ziemlich problematisch.
Daher wird vor jeder Ausführung eines ONERROR-Unterprogramms
automatisch die FORBID Anweisung ausgeführt. Das Bedeutet daß
ein ONERROR-Unterprogramm nicht durch eine TASK oder Sequenz
unterbrochen wird was wiederum ein Aufruf vom ONERROR-
Unterprogramm auslösen könnte.
Weiterhin ist eine Termination sichergestellt wenn ein Fehler
in einem ONERROR-Unterprogramm selbst ausgelöst wird.

Im Handbuch wird nicht beschrieben das die Möglichkeit die
Fehlernummer auszulesen (ERRVAR Variable).
In ERRVAR wird die Fehlernummer gespeichert bevor das ONERROR Unterprogram
ausgeführt wird.

Ein Beispiel für ONERROR-Unterprogramm.

  1000 REM **** ONERROR-Unterprogramm ***********************************
  1010 PRINT "*** FEHLER #";ERRVAR

                           -9-
...
... Eventuelle Aktionen, abhängig vom Fehlernummer
...
  1280 PERMIT
  1290 RETURN
Der Befehl PERMIT hebt die Schedule-Sperre wieder auf.
PERMIT sollte in einem solchen Unterprgramm immer kurz vor
RETURN Anweisung stehen.


1.3 INPUT Anweisung
Die INPUT Anweisung war schon immer ein Bestandteil von MSR-
Basic. Leider war seine Anwendung in einem Multitasking
Programm nur bedingt brauchbar, weil das Schedule Mechanismus
bis zu Eingabe von <RETURN>
angehalten würde.

Ab Version V4.2 ist eine neu konzipierte INPUT Anweisung
verfügbar
die wenig zum Wünschen übrig läßt.
Beim ausführen von INPUT Anweisung geht die ausführende
Sequenz in ein
Wait-Zustand über.
Das bedeutet das die Tasks weiterhin eine INPUT Anweisung
nicht Ausführen dürfen. Das Hauptprogramm wird ab Version V4.2
wie eine Sequenz behandelt, also es gibt ja auch keine
Einschränkung bezüglich der Anwendung.
Der WAIT-Zustand in die eine Sequenz übergeht kann optional
zeitlich überwacht werden. Damit kann man leicht verhindern
daß eine Sequenz ewig auf eine Eingabe wartet. Des weiteren,
man kann optional, das Fehlerbehandlung bei der Eingabe selbst
gestalten. Also, man kann das standard Mechanismus wo die
INPUT-Anweisung, nach vorherigen Meldung: "INPUT Fehler",
wiederholt wird, durch eigene Fehlerbehandlung ersetzen.
Weiterhin ist es jetzt auch möglich Bildschirmausgaben zu
machen während in einem anderem Teil des Bildschirms eine
INPUT-Zeile editiert wird.
Diese nebenläufige Bildschirmausgabe wird jedoch nur dann
funktionieren wenn man kein Semikolon am Ende der PRINT-
Anweisung verwendet.


Die neue Syntax lautet:

 INPUT [ ON(Kanal ] [ [Y,X] ] [ MAX Wert ] <Variablenliste> [
ELSE Anweisung]

Unter <Variablenliste> ist eine oder mehrere, durch Komma
getrennte numerische oder Stringvariablen gemeint.
Die Eingabe sollte bei mehreren Variablen auch durch Komma
getrennt werden.
Bei Numerischen Variablen ist nur eine Numerische Darstellung
einer Zahl erlaubt und sollte einer Stringvariable das
Kommazeichen auch zugewiesen werden so kann die Eingabe in
Anführungsstriche geklammert werden.
Beispieleingabe für Variablenliste <a,a,a$>:


                          -10-
>1111.0, 222,"Komma,Komma"<

Unvollständige Eingaben oder unkorrekte Numerische Darstellung
führen zu einem Fehlerfall!


Die Optionen:
                  [ ON(Kanal) ]
Soll die Eingabe auf einem anderem Kanal erfolgen als LU(0),
so ist diese Option zu wählen. So werden bei "INPUT ON(2) a"
alle Eingaben und Ausgaben auf LU(2) erfolgen.

                  [ [Y,X] ]

Stellt den Cursor auf eine bestimmte Y,X Position des
Bildschirms. Auf dieser Position kann man dann die Werte eingeben.
Obwohl andere Sequenzen oder Task Bildschirmausgaben parallel
dazu machen wird die eingestellte Position beibehalten.
Vorausgesetzt daß PRINT-Anweisungen ohne Semikolon verwendet werden!.

                  [ MAX Wert ]
Die INPUT-Anweisung wird Zeitlich überwacht. Durch <Wert>
bestimmt man wieviel Sekunden maximal das Eingabegerät ruhen
darf. Die INPUT Anweisung selber kann vielfaches davon aktiv
bleiben, aber einzelne Pausen bei der Eingabe dürfen den Limit
nicht überschreiten.

                  [ ELSE Anweisung ]

Programmabschnitt nach <ELSE> wird nicht berücksichtigt wenn
die Eingabe erfolgreich abgeschlossen würde. Würde die
Zeitliche überwachung aktiviert und überschritten oder die
Eingabe falsch oder unvollständig gemacht so wird keine
Fehlermeldung ausgegeben und die INPUT-Anweisung wiederholt,
sonder dieser Programmabschnitt ausgeführt.
Zweckmäßig sollte dort eine GOTO Anweisung stehen, aber auch
andere Anweisungen sind zulässig.

Beispiel für eine INPUT-Anweisung mit Optionen:
11000    PRINT "Geben Sie Bitte Name,Vorname und Alter ein: ";
11010    INPUT MAX 10 Name$,Vorname$,Alter ELSE GOTO 11110


1.4 SEQSTATE und TASKSTATE Funktionen

Es ist manchmal nützlich zu wissen ob eine Sequenz oder Task
aktiv ist.
Zwar ließ sich daß immer durch Benutzung von Variablen
realisieren, doch jetzt ist es bequemer und sicherer.

Als Parameter gibt man eine Sequenz oder Tasknummer und
bekommt zurück
ein Zustandswert, der folgende Bedeutung hat:



                              -11-
0: Sequenz oder Task nicht Aktiv.
    1: Sequenz oder Task ist aktiv
    2: Nur bei Sequenzen. Sequenz ist aktiv und wartet auf ein
Zustand
      (WAIT oder INPUT Anweisung gerade in Bearbeitung).
Beispiel: Von einer Sequenz soll ein TASK gestartet werden,
die Sequenz selber hat dann nichts zu tun und soll solange in
Wartezustand übergehen.

   1000 START TASK 1
   1010 WAIT FOR TASKSTATE(1) = 0
   1020 PRINT "O.K."

1.5 FORBID und PERMIT Anweisungen
Das Multitasking bringt viele Vorteile mit sich. Es gibt
jedoch Anwendungen bei denen für kurze Zeit das
Schedulemechanismus sehr stört.
Z.B. bei Erzeugung von Programmgesteurten Impulsen oder bei
einem Fehlerfall wo alle TASK/SEQUENZ Aktionen kurz angehalten
werden sollen.
Zwar ließ es sich immer mit SUSPEND TASK ALL und SUSPEND SEQ ALL
alle Tasks und Sequenzen anzuhalten, aber dadurch war nur der
Hauptprogramm blieb dann aktiv und es war nicht mehr möglich
den ursprünglichen Zustand herzustellen. ACTIVATE TASK ALL
würde alle TASKs aktivieren unabhängig davon ob sie vorher
schon mal aktiv waren oder nicht.
Bei Ausführung der FORBID Anweisung wird also wirklich das
Schedulemechanismus angehalten. Nach dieser Anweisung wird
ausschließlich der Programmteil, der diese Anweisung enthalten
hat, ausgeführt.
Die Anweisung PERMIT hebt die Sperre wieder auf, und alles
kehrt zum ursprünglichen Zustand.

Wie schon erwähnt, es gibt ein Sonderfall wo die FORBID
Anweisung automatisch ausgeführt wird. Und zwar vor der
Ausführung eines ONERROR Unterprogramms.
Daher sollte man in der Regel nicht vergessen ein PERMIT
Anweisung auszuführen vor einer RETURN Anweisung des Unterprogramms.

Noch ein schlechtes Beispiel zur Warnung:
   1000   a = 0
   1010   FORBID
   1020   WAIT FOR a>0
   1030   PERMIT

Wie man leicht erkennen kann ist dieser Beispiel das Ende
eines Programms.
Obwohl vorher alles schalten und walten vermag tut sich
bereits nach der dritten Zeile nichts mehr. Dieser Teil einer
Sequenz wird nach der FORBID Anweisung der einziger
ausgeführte Programmteil, und geht sofort in ein WAIT-Zustand
der nie beendet wird!!!

1.6 Logische Operatoren AND und OR

Eine Einschränkung bei MSR-Basic war das fehlen der bekannten
AND oder OR Operatoren. Nun gilt diese Einschränkung nicht mehr.

                          -12-
Diese Operatoren sind z.Z. nur als logische Operatoren die
zusammen mit Relationen in einer IF oder WAIT Anweisung
verwendet werden können, nicht aber für eine Verknüpfung
zweier Werte bitweise. Das macht nur ein Sinn mit
Ganzzahligenwerten und solange keine Ganzzahlige Variable
eingeführt sind
würde es nur wenig ausgenutzt werden können.
Die Rangfolge dieser Operatoren ist nach der Relationen und
beliebige Klammerung ist erlaubt.
Beispiel:
    1000 IF DIN(NotAus) OR (DIN(Vent1) = 0 AND DIN(Vent2) = 0)
    1010 PRINT "Notschalter EIN, oder beide Ventile ausgeschaltet!!"
    1020 ENDIF

1.7 STDSET Anweisung
Die neue Anweisung STDSET soll der allgemeiner Voreinstellung dienen.
Bis jetzt ist nur der Format bei Ausgabe von numerischen
Werten voreinstellbar, und die Syntax lautet:
  STDSET AS xxx wobei xxx die Formatbeschreibung ist die sonst
hinter AS erlaubt ist.
Sollen in einem Programm nur Werte in sechsstelligen
Festkommaformat ausgegeben werden so braucht man nicht mehr
hinter jeder PRINT Anweisung
"AS 6I" einzugeben wenn man am Programmanfang mit "STDSET AS
6I" dieses Format eingestellt hat.
Ein weiteres Nutzen dieser Anweisung ist es, daß damit auch
die STR$ Funktion beeinflußt wird. Bis jetzt lieferte diese
Funktion einen String welcher gleich war mit Ausgaben der
PRINT Anweisung ohne <AS xxx> Formatangabe.
Meist müsste ein solcher String weiterbearbeitet werden z.B.
wenn man nur die
zwei Vorkommaziffer benötigte.
Nun, jetzt kann man das Format einstellen und dieses Format
wird auch für die STR$ Funktion verwendet.
Beispiel:
Ein Programm soll über LU(2) Steuersequenzen ausgeben. Eine
Sequenz besteht aus einem <ESC> Zeichen gefolgt von einer
Befehlsbuchstabe,Parameter und <CR> Zeichen. Der Parameter
besteht immer aus zwei Hexadezimalziffern.
  10000   PRINT ON(2) CHR$(&H1B)$;   '   <ESC> Zeichen
  10010   PRINT ON(2) Cmd$;          '   Kommandobuchstabe
  10020   STDSET AS 02H              '   Format = 2 Stellen, Hexadezimal
  10030   PRINT ON (2) STR$(Wert);   '   Parameter ausgeben
  10040   STDSET AS 6I               '   wieder Normale Einstellung
  10050   PRINT ON (2) CHR$(&H0D);   '   Abschlusszeichen <CR>

2. Hintergrundspeicher für MSR-Basic
MSR-Basic wurde ursprünglich für den Betrieb mit sehr wenig
Hauptspeicher entwickelt. Es kann meist ein Bereich von 32
KByte für MSR-Programme und Daten genutzt werden. Um in
Applikationen der Meßwerterfassung auch mit größeren
Datenmengen umgehen zu können, wurde für den Prozessor Z280
eine Erweiterung des MSR-Basic vorgenommen. Die neuen
Funktionen erlauben die Einrichtung und das Einfügen/Entfernen

                            -13-
von Daten aus einem Hintergrundspeicher.
Ein Hintergrundspeicher kann als Feld von Datenstrukturen
aufgefaßt werden.
Es können auch mehrere Hintergrundspeicher definiert werden,
deren Datenstruktur unabhängig voneinander sind.
Auf den Hintergrundspeicher kann direkt (wahlfrei), als Stack
oder als Queuezugegriffen werden. Alle Zugriffsarten können
auch gemischt werden, was besonderes dann sinnvoll ist, wenn
die Daten eines Stacks oder Queue verarbeitet werden sollen,
ohne sie aus dem Hintergrund zu entfernen.
Es können maximal 8 Hintergrundspeicher definiert werden,
deren Größe nur durch den verfügbaren Speicherplat    Seite 187




                          -14-
1. Vorwort

Entsprechend den vielfältigen Einsatzmöglichkeiten richtet sich
MSRBASIC an einen weiten Kreis von Anwendern.
Das vorliegende MSRBASIC-Handbuch stellt hinsichtlich Darstellung
und Umfang einen Kompromiß dar.

Diejenigen MSRBASIC-Befehle, die zum Standard-Sprachumfang gehören
werden sehr knapp beschrieben, während MSRBASIC-spezifische
Echtzeit-Befehle in der gebotenen Ausführlichkeit behandelt werden.

Die Methodik der Darstellung ist vom Ziel geprägt, das jeweilige
Grundprinzip der einzelnen MSRBASIC-Befehle knapp und allgemein zu
vermitteln, andererseits durch praktische Beispiel
Anwendungshinweise für den MSRBereich zu liefern.
Aus diesem Grund werden die Befehle nicht in ihrer alphabetischen
Reihenfolge beschrieben, sondern im Rahmen funktionell verwandter
Befehle, wie z.B.

     - Echtzeitbefehle
     - Programmflußsteuerbefehle
     - Zeichen-Ein/Ausgabe-Befehle




                                -15-
2. Allgemeines

2.1 Sinn und Zweck von MSRBASIC
Der MSRBASIC-Interpreter ist konzipiert für die flexible
Implementation von Meß- Steuer- und Regelalgorithmen auf EPROM-
startenden Mikrorechnern (Stand-Alone-Systeme) der Z80-Familie.

Die Programm-Entwicklung erfolgt mit dem Hilfsprogramm MSRSHELL auf
einem PC (XT, AT) über eine RS232-Verbindung mit dem EPROM-
startenden Zielrechner (MOPS xAx, xDx oder PC-EXPander mit CPU-S
oder CPU85SC) erfolgen.

MSRBASIC bietet für das genannte Einsatzgebiet neben dem üblichen
algorithmisch logischen Kern einer höheren Programmiersprache
spezielle Sprachmittel an, die die Formulierung von
     -   nebenläufigen Programmen (Multitasking),
     -   hardwareabhängigen Prozeßzugriffen,
     -   Zeitgebern
     -   PI(D)-Reglerfunktionen,
     -   Matrix-Vektor-Operationen
     -   Kommunikationsfunktionen
erlauben.

Neben diesen sprachlichen Fähigkeiten, die MSRBASIC als Echtzeit-
Sprache ausweisen, verfügt der MSRBASIC-Interpreter (im Sinne eines
Programmiersystemes) über eine Reihe von Eigenschaften, die nicht
nur die Erstellung, sondern auch die Fehlersuche, Wartung und (Re-
)Dokumentation von MSR-Anwender-programmen unterstützt:
     - Integrität von Ziel- und Entwicklungssystem
     - integrierter serieller Hostanschluß
       (zum Programme laden, Daten versenden und entgegen-
       nehmen, Betrieb als intelligentes Terminal)
     - strukturorientiertes Ausdrucken von Programmen
     - Befehlsanzeige vor Ausführung zum Programmtest (Trace)
     - Anzeige des momentanen Programmzeigerstandes bei SE-
       QUENZEN (Aufspüren von Deadlocksituationen)
     - Fehlermeldung mit Quellzeilen-Auslisten
     - E/A-Simulator-Betriebsart

Weitere für Realzeit-Mikrorechner notwendige Eigenschaften sind
     - EPROM-fähiger Zwischencode
     - Autoload- und Autostartfunktion

Für den MSRBASIC-Interpreter ergibt sich damit ein breites
Einsatzspektrum:

     - Einsatz in autonomen Regel- und Steuergeräten,
       insbesondere bei verfahrenstechnischen Anwendungen
     - Einsatz als Kontroller zusammen mit intelligenten
       Peripheriegeräten zur Experimentsteuerung
     - Einsatz bei Maschinensteuerungen
     - Einsatz als Meßwerterfassungs- und Protokolliersystem
     - Einsatz zur Ausbildung

Die Summe dieser Eigenschaften machen MSRBASIC zu einem Instrument,

                                  -16-
das für viel Anwender (Steuerungs- und Regelungs-techniker,
Verfahrenstechniker, Chemiker, Physiker, Mediziner u.A.) eine
wertvolle Hilfe darstellt.
Das vorliegende Handbuch will in konzentrierter, aber hinreichend
ausführlicher Form den Anwender bei der Handhabung des MSRBASIC-
Interpreters unterstützen.

Es setzt eine gewisse Vertrautheit mit der Grundsprache BASIC voraus
und legt daher das Hauptgewicht auf die Behandlung der
echtzeitspezifischen Fähigkeiten von MSRBASIC.

2.2 Anweisungen, Datentypen und Sonstiges

In diesem Kapitel werden zunächst - im Sinne einer Übersicht - in
alphabetischer Ordnung kurz einige allgemeine MSRBASIC-
Eigenschaften behandelt, bevor im zweiten Teil ausführlich das
MSRBASIC-Echtzeitkonzept erläutert wird.

2.2.1 Anweisungen

Ein MSRBASIC-Programm besteht aus einer eindeutigen Folge von
Anweisungen (Statements). Jede Programmanweisung beginnt mit einer
Zeilennummer (1..65565), die die Lage der Zeile innerhalb des
Programms festlegt.

Einige Anweisungen können auch direkt ("direct mode"), d.h. quasi
als Kommando eingegeben werden.
Diese Eigenschaft ist insbesondere beim Echtzeitbetrieb von großer
Bedeutung, da während der Programmausführung auf alle Variablen mit
Hilfe von PRINT- und (LET-)Anweisungen zugegriffen werden kann.

2.2.2 Buchstaben
MSRBASIC läßt die Verwendung von Klein- und Großbuchstaben zu. Bei
Schlüsselwörtern (Kommandos, Anweisungen, Funktionen, Trennwörter
und Systemvariablen) werden Kleinbuchstaben intern in Großbuchstaben
umgewandelt. D.H. Eingaben wie "THEN", "then" oder "Then" werden
intern als "THEN" behandelt.

Dagegen werden Kleinbuchstaben in Variablennamen NICHT wie
Großbuchstaben behandelt, d.h.
           ZEIT$
     und                   sind zwei unterschiedliche Variable !
           Zeit$
2.2.3 Datentypen

MSRBASIC kennt die Datentypen REAL und STRING. Integer-Zahlen werden
intern als Gleitkommagröße behandelt. Der Datentyp ergibt sich
implizit aus dem Programm.

2.2.4 Datenstrukturen
Als Datenstrukturen sind ein- oder zweidimensionale Felder (s.d) vom
Type REAL oder STRING möglich.

2.2.5 Editor


                                -17-
Bei der Eingabe eines Kommandos, einer Programmzeile oder eines
Wertes (Zahl oder Text) ist ein Zeileneditor wirksam, d.h. daß
innerhalb der momentanen Eingabezeile der Cursor bewegt, Zeichen
eingefügt und gelöscht werden können.
Einzelheiten siehe Kapitel "Editor".

2.2.6 Felder

Es können ein- und zweidimensionale Felder für die Datentypen REAL
und STRING benutzt werden. Der Index beginnt grundsätzlich bei 0
(NULL). Sofern der verfügbare Anwenderspeicher es zuläßt, können
numerische Vektoren bis zur Dimension 8191 (8k) und Matrizen bis zur
Ordnung 126x126 vereinbart werden. Stringfelder können maximal 255
Elemente aufweisen.

2.2.7 Funktionen
Neben den BASIC-Standardfunktionen wie SIN, SQR bzw. CHR$ MID$ usw.
werden folgende Typen von anwendungsbezogenen Funktionen zur
Verfügung gestellt:

     -   Auf und Abwärts-Zeitgeber
     -   Zugriffe auf analoge und digitale Prozeßperipherie
     -   Komplette Reglerblöcke (PI,PID)
     -   Status- und Kommandofunktionen für die seriellen Kanäle
     -   Kommunikationsfunktionen



2.2.8 Kanalnummern
Die Ein-/Ausgabe von Zeichen und Texten erfolgt durch Befehle wie
PRINT und INPUT die um einen "ON(kanalnummer)"-Zweig erweitert
werden können. Je nach (Hardware-)Konfiguration werden damit neben
der Konsole und dem Drucker auch Ein-Ausgabegeräte wie z.B. LCD-
Anzeigen, Matrixtastaturen, weitere RS232-Schnittstellen usw.
erreichbar.
Es stehen die Kanalnummern 0..9 zur Verfügung. Bei den EPROM-
startenden Systemen ist Kanal (0) (falls vorhanden) immer die
Konsole. Kanal (1) ist als Druckerkanal vorgesehen.
Die unbelegten Kanäle können zum Anschluß von Standardperipherie
genutzt werden, eignen sich aber auch vorzüglich zur Anbindung
komplexerere Schnittstellen wie z.B. IEC-Bus oder DFÜ-Kanäle.
In den EPROM-startenden Systemen mit (optionalem) EEPROM-Anschluß
erfolgt die "Programmierung" D des EEPROMS ebenfalls über einen "ON-
                           ng"
Kanal" (siehe hierzu das Kapitel Hardware-Anpassung).

2.2.9 Kommandos

Die Kommandos im MSRBASIC sind Anweisungen an den Interpreter. Sie
dienen entweder Editierzwecken (LIST, SAVE, LOAD, NEW) oder der
Festlegung der Betriebsart (RUN, FREEZE, SYS).
2.2.10 Kommentare

Kommentarzeilen werden durch "REM" eingeleitet. Sie dienen der
Kommentierung von Programmsegmenten.


                                 -18-
2.2.11 Operatoren

In MSRBASIC stehen folgende Operatoren zur Verfügung:
Skalare Operatoren
a) Rechenoperatoren:
                                         Wertigkeit
     Potenzoperator: ^                   3
     Multiplikation: *                   2
     Division:             /                  2
     Addition:             +                  1
     Subtraktion:          -                  1

b) Vergleichsoperatoren:
     größer:              >
     kleiner:             <
     gleich:              =
     größer-gleich:       => oder >=
     kleiner-gleich: =< oder <=
     ungleich:            <> oder ><
c) Stringoperatoren

     Verkettung:           +
Matrix-Operatoren

     Multiplikation: *                   2
     Element-Multipl.:     .                  2
     Addition:             +                  1
     Subtraktion:          -                  1
2.2.12 Programm

MSRBASIC kennt drei Typen von Programmen:
Das Rahmen- oder Grundprogramm entspricht dem üblichen BASIC-
Programm. Es wird über das RUN-Kommando oder einen unmittelbaren
GOTO-Befehl gestartet. Die Beendigung des Programmes erfolgt über
die entsprechenden Anweisungen (RETURN, STOP, END), über die
Fehlermeldungen oder durch ein Abbruch-Kommando vom der Konsole aus
(Eingabe von CNTRL-C).

Der zweite MSRBASIC-Programmtyp heißt TASK und wird zyklisch vom
Echtzeitbetriebssystem gestartet. (siehe nächsten Abschnitt). Sollen
alle zyklischen Programme angehalten und nicht mehr neu gestartet
werden, CNTRL-D einzugeben.

Der dritte MSRBASIC- Programmtype ist die SEQuenz. auch sie wird vom
Echtzeitbetriebssystem gestartet (s.u.). Das Anhalten aller
Sequenzen geschieht durch die Eingabe von CNTRL-A.

2.2.13 Starten des Interpreters
Sofern im BASIC-Programmspeicher ein intaktes Programm vorhanden
ist, führt MSRBASIC automatisch einen AUTO-Warmstart durch, d.h. die
Anwendervariablen werden nicht gelöscht, das Programm wird ab der
ersten Programmzeile ausgeführt.
Hinweis:

                                  -19-
Bei jedem Neustart prüft MSRBASIC ob im (u.U. auch geschützten CMOS-
RAM) ein "sinnvolles" Programm steht. Ist dies der Fall, so wird
dieses Programm ausgeführt, evtl. Fehler werden spätestens bei der
Interpretation erkannt. Wurde der Neustart z.B. durch einen
Stromausfall oder ein gezieltes An- und Abschalten verursacht, so
muß die (anwenderseitige) Neuinitialisierung von Parametern umgangen
werden. Dies geschieht am einfachsten durch Verwendung einer
(benutzerdefinierten) Variablen:

     100 REM beim ersten Kaltstart werden alle Variablen
     110 REM auf NULL gesetzt, es gilt also beim Kaltstart
     120 IF IniFlg <> 0 THEN GOTO 200
     130 REM Initialisierung von Variablen beim Warmstart
     140 LET A=123
     150 DIM X1(16), A(X,Y)
     :
     : und was sonst noch gemacht werden muß...
     : Achtung: Bausteine wie PIO, CIO usw.
     : nach jedem RESET neu initialisieren!
     : ... dann IniFlg <> 0 setzten
     :
     190 IniFlg=55
     200 REM *** Hier gehts bei Warmstart weiter ***
     :
Bei Kaltstart erfolgt eine Initialisierung der Echtzeituhr, des
Taskumschalters und des Arbeitspeichers, sowie eine
konfigurationsabhängige Kaltinitialisierung der Prozeß-Ein/Ausgabe.
In der Regel bedeutet dies z.B. für die binären Stellsignale ein
Schalten in den stromlosen Zustand.
Bei Warmstart wird die Echtzeituhr initialisiert und das ACTIVE-Bit
aller TASKS und SEQuenzen zurückgesetzt, um einen definierten Neu-
bzw. Wiederstart zu gewährleisten. Außerdem wird eine
konfigurationsabhängige Warminitialisierung der Prozess-Ein/Ausgabe
vorgenommen. Dies bedeutet z.B. für die binären Stellsignale, daß
die E/A-Bausteine in Ausgaberichtung neu programmiert werden.
In EPROM-startenden (Stand-Alone-)Systemen gibt es noch zwei weitere
Startvarianten, nämlich den Autostart eines in (E)EPROM abgelegten
Anwenderprogrammes bzw. das automatische Laden eines Programmes von
einem voreinstellbaren seriellen Kanal und anschließende Starten.

2.2.14 Transparent-Betrieb (virtuelles Terminal)

MSRBASIC unterstützt für die SAVE-, LOAD und LIST-Kommandos den
Datenverkehr von und zu einem übergeordneten Rechner (Host). Bei
Ausführung dieser Kommandos geht der Interpreter vorübergehend in
den Transparent-Betrieb, d.h. der Host-Rechner empfängt die nach dem
Kommando eingegebenen Zeichen und das MSRBASIC-Terminal zeigt die
Antworten des Host. Erst die Eingabe eines speziellen Fluchtsymboles
(CNTRL-A) veranlaßt dann die Ausführung des Kommandos.

2.2.15 Variable

Ein MSRBASIC-Programm kann maximal 255 verschiedene Variable
aufweisen. Es gibt vier Arten von Variablen, nämlich Skalare und
Felder jeweils vom Typ REAL oder STRING.

Jede Variable trägt einen Namen der maximal sechs Zeichen lang sein

                                -20-
kann. Das erste Zeichen muß ein Buchstaben sein, als folgende
Zeichen sind Buchstaben, Ziffern und der Unterstrich "_" erlaubt.
Aus Gründen der Kompatibilität zu Microsoft-Basic sind auch die
Zeichen "%" und "#" zugelassen.
Stringvariable (Zeichenkettenvariable) sind durch ein "$"-Zeichen
zusätzlich zum Variablennamen gekennzeichnet.

Beispiele:          A_min, a0$, Azeich(2), ESC$, X$(1,2)
Die maximale Länge von Stringvariablen wird bei der MSRBASIC-
Konfiguration festgelegt (Voreinstellung: 40 Zeichen). Stringfelder
weisen als Elemente Stringvariable auf. Die Namen der Wochentage
können z.B. in ein Stringfeld abgespeichert werden:

      DIM WO$(7)
      WO$(1)="Montag"
2.2.16 Zahlenbereich

Die größte Zahl die von MSRBASIC verarbeitet wird, ist 4.61168E+18,
die kleinste 6.46235E-27. Tritt bei einer arithmetischen Operation
ein Überlauf auf, erfolgt eine Fehlermeldung. Dagegen wird bei einem
Unterlauf das Ergebnis automatisch zu Null gesetzt. Es können
Integer- (Ganzzahl-), Festkomma- und Gleitkommazahlen mit und ohne
Exponent eingegeben werden. Es dürfen jedoch nicht mehr als sieben
Stellen (bei entsprechender Genauigkeit) eingegeben werden.
Darüberhinaus ist es möglich HEX(Sedezimal-)Werte im Bereich
0000..FFFF ein- bzw. auszugeben.

Die Syntax für die Eingabe lautet:
             &Hnnnn       mit nnnn = 0..FFFF
Die entsprechende Ausgabe erfolgt über die "PRINT..AS.."-Anweisung

3. Editor-Funktionen
3.1 Übersicht

In MSRBASIC stehen bei der Eingabe von Programmzeilen komfortable
Editierfunktionen zur Verfügung.Eine weitere Komfortsteigerung
bringt die erweiterte Syntaxprüfung bei der Programmzeilen-Eingabe,
die fehlende Klammern oder Anführungszeichen sofort entdeckt. Damit
werden MSRBASIC- Programme auch sicherer, da syntaxbedingte
Laufzeitfehler verringert werden.

3.2 Funktionsbeschreibung

Bei der Eingabe einer Programmzeile (oder von INPUT aus) ist
grundsätzlich der "Einfüge-Modus" in Kraft.

Folgende Editierfunktionen stehen zur Verfügung:
64444444444;44444444444444444444444444444444444444444444444447
5Taste         5    Funktion                                         5
:4444444444>4444444444444444444444444444444444444444444444444<
5            5                                                   5
5CNTRL-A       5    Cursor eine Position nach links                  5
5CNTRL-F       5    Cursor eine Position nach rechts                 5


                                       -21-
5DEL,BS      5      Zeichen links vom Cursor löschen               5
5CNTRL-G       5    Zeichen unter dem Cursor löschen               5
5CNTRL-X       5    ganze Zeile löschen                            5
5CR            5    Eingabe beenden                                5
5CNTRL-C       5    Eingabe abbrechen                              5
5CNTRL-B     5      Cursor zum Ende/Anfang der Zeile positionieren 5
5            5                                                  5
94444444444=44444444444444444444444444444444444444444444444448

Alle andere   Steuerzeichen werden ignoriert.


3.3 Änderung vorhandener Programmzeilen
Um bereits vorhandene Programmzeilen mit Hilfe der oben
beschriebenen Editorfunktionen zu ändern, ist die entsprechende
Zeile durch

                  "# <Zeilennummer>"
     oder         "SAVE <Zeilennummer>"
     bzw.         "LIST <Zeilennumer>"

anzuwählen.
Bei allen genannten Aufrufen wird die angewählte Zeile ausgelistet,
der Cursor bleibt jedoch am Ende der Zeile stehen. Mit CNTRL-A
(Drücken der Tasten CNTRL und "A" gleichzeitig wird der Cursor, ohne
die "darunter" liegenden Zeichen zu löschen, nach links bewegt. Mit
CNTRL-F kann der Cursor nach rechts, bis zum Zeilenende bewegt
werden.
Im Editiermodus ist die Eingabe immer auf "Einfügen" geschaltet,
d.h. ab der momentanen Cursorposition kann neuer Text geschrieben
werden; evtl. rechts vom Cursor stehender Text wird automatisch
weiter nach rechts verschoben. Soll ein Zeichen gelöscht werden kann
dies mit CNTRL-G geschehen, wenn das Zeichen "unter" dem Cursor
gelöscht werden soll, mit DEL, BS (oder CNTRL-H) können die Zeichen
rechts vom Cursor gelöscht werden. Der rechts vom Cursor
verbleibende Text wird aufgerückt.

Mit CNTRL-B kann der Cursor vom Zeilenende zum Zeilenanfang (und
zurück) positioniert werden.
Mit CR (möglich an jeder beliebigen Cursorposition) wird die
bearbeitete Zeile übernommen. Dies bedeutet gleichzeitig, wenn beim
Editieren die Zeilennummer gelöscht wurde, daß auch die ganze Zeile
gelöscht wird.

Soll (auch nach bereits vorgenommener Änderung) der "alte"
Zeileninhalt doch übernommen werden, kann die zu editierende Zeile
mit CNTRL-C unverändert verlassen werden.

Nach Abschluß der Bearbeitung der laufenden Zeile zeigt das LIST-
Kommando in dieser Betriebsart die nächste Zeile in der gleichen
Weise an. Durch Eingabe von CNTRL-C wird der Editiermodus verlassen.
Hinweis:
Syntaxfehler:       Werden bei der Programmeingabe Syntaxfehler
                    erkannt, wird die fehlerhafte Zeile nach der
              Fehlermeldung "Syntax-Fehler" automatisch im

                                  -22-
Editier-Modus zur Fehlerkorrektur angeboten.

FREEZE-Betrieb:   Im Echtzeitbetrieb sind die Editiermöglich-
                   keiten unterbunden.




                                 -23-
4. Echzeitspezifische Sprachmittel

4.1 Übersicht
Um die Echtzeitmöglichkeiten von MSRBASIC angemessen einsetzen zu
können, ist es neben der Kenntnis der Einzelbefehle vor allem
notwendig, sich mit dem im folgenden beschriebenen Grundkonzept
vertraut zu machen.

4.1.1 MSRBASIC-Echtzeitkonzept
Die MSRBASIC-Echzeit-Philosophie wird deutlich, wenn man
Automatisierungsaufgaben bei industriellen Prozessen hinsichtlich
ihres Zeitverhaltens unterteilt. Im wesentlichen lassen sich hierbei
zwei Grundtypen von Verarbeitsfunktionen erkennen:

      1.    immer oder zeitweise im Eingriff befindliche
            "zeitkontinuierliche" Funktionen wie z.B. lineare
            Regelung, Überwachung und Verriegelung, Filterung u.a.m.

      2.    Zeit- oder prozeßgeführte Ablaufsteuerungen, in denen
            sich ein ereignisdiskreter Prozeßablauf widerspiegelt,
            wie z.B. aufeinanderfolgende Bearbeitungsschritte an
            einer Werkbank, das Anfahren einer bestimmten Position
            oder das Abwarten einer Grenzwertüberschreitung.

Diesem Dualismus trägt MSRBASIC im Gegensatz zu vielen
Echtzeitsprachen durch das explizite Bereitstellen von zwei
nebenläufigen Programmtypen Rechnung, nämlich TASK für zyklisch zu
startenden Programme und SEQuenz für Ablaufsteuerungs-Programmteile.
Bei reinen Regelungsanwendungen werden nur TASKs verwendet, während
z.B. bei der zeitgesteuerten Änderung der Sollwerte, etwa beim
Abfahren eines Temperaturprofils, die Sollwertvariable der Regeltask
durch eine SEQuenz zu bestimmten Zeiten verändert wird. Anderseits
sind rein ereignis-orientierte (Fertigungs-, Montage- u.a.) Prozesse
durch parallele Abläufe gekennzeichnet, da sich oft mehrere
Werkstücke in aufeinanderfolgenden Sektionen einer gemeinsam
gesteuerten Bearbeitungsmaschine befinden.

Solche zeitgleichen Abläufe werden durch verbale Spezifi-kationen,
Petri-Netze oder Funktionspläne beschrieben oder dargestellt. Diese
Beschreibungsformen lassen sich sehr leicht in MSRBASIC-SEQuenzen
übertragen, denn es sind gleichzeitig mehrere aktive SEQuenzen
zulässig. Bei gleichzeitig lauffähigen SEQuenzen wird ggf. die
Prozessorzeit aufgeteilt.

Die grundlegend unterschiedliche Aufgabenstellung von TASKs und
SEQuenzen muß auch vom Programmierer berücksichtigt werden:

      TASKs sollen automatisch gestartet und möglichst in einem Zug
      abgearbeitet werden, um ihrer quasikontinuierlichen Funktion
      gerecht zu werden. Ideal wäre für sie eine unendliche kurze
      Ausführungszeit und eine unendlich hohe Aufruffrequenz.



644444444444444444444444444444444444444L4444444444444444444447
5               kontinuierliche                     * ereignisorientierte5
5                MSR-Funktionen                     * MSR-Funktionen     5


                                    -24-
:4444444444L444444444444444444444444444P444444444444444444444<
5Beispiel * Regelungen                          * Ablaufsteuerungen 5
5             * Überwachung-Verriegelung * mit Wartebedingungen5
:4444444444P444444444444444444444444444P444444444444444444444<
5grafische * Signalflußplan                     * Funktionsplan         5
5            *                                  *                       5
:4444444444P444444444444444444444444444P444444444444444444444<
5Dar-         *                                 * Petri-Netz            5
5stellungs-*                                    *                       5
5form         *       +--------+                *             !          5
5             * Xe    !          ! Xa           *            ! +---     5
5             *---    !          ! ---          *            ! !        5
5            *      !           !             *     +-----+--+-+      5
5            *     / !           !      /       *     !            !    5
5             *---    !          ! ---          *     +-----+----+      5
5             *       !          !              *             !         5
5             *       +--------+                *             ! +---    5
5             *                                 *             ! !        5
5             *                                 *     +-----+--+-+      5
5             *                                 *     !             !   5
5             *                                 *     +----------+      5
5            *                                  *                       5
:4444444444P444444444444444444444444444P444444444444444444444<
5MSRBASIC     *       TASK                      *               SEQuenz  5
5Prg.Typ     *                                  *                       5
5            *                                  *                       5
94444444444N444444444444444444444444444N4444444444444444444448
Schaubild 4.1 Einteilung der MSR-Funktionen

     Dagegen hängt die Ausführungsgeschwindigkeit einer SEQuenz
     kaum von der Rechengeschwindigkeit des Prozessors, sondern vom
     Zustand des technischen Prozesses ab.

Die für eine SEQuenz typische Abhängigkeit der Programmfortsetzung
vom Prozeßzustand wird allgemein als "Weiterschaltbedingung"
bezeichnet. Hierzu bietet MSRBASIC ein spezielles Sprachmittel,
nämlich die WAIT-Anweisung (s.d.) an. Im Vergleich zur IF-Anweisung
bietet sie eine der Gegebenheit besser angepasste Formulierung, die
deutlich macht, daß das Ablaufsteuerungsprogramm bei der
Weiterschaltbedingung verharren soll, bis diese erfüllt ist.

Eine spezielle, für technische Einsätze aber fast unumgängliche
Eigenschaft der WAIT-Anweisung ist die integrierte Überwachung der
Wartezeit mit der Möglichkeit zur Ausnahmebehandlung. Damit können
Fehler im technischen Prozess erkannt und abgefangen werden. Dies
wird bei MSRBASIC durch die Erweiterung der Anweisung auf
     WAIT MAX <zeit> ..

ermöglicht.
Die WAIT-Anweisung erleichtert auch die interne Verwaltung der
verschiedene quasiparallelen Programme. Sie bietet im Gegensatz zur
IF-Anweisung dem Echtzeitbetriebssystem eine elegante Möglichkeit,
die laufende SEQuenz zu unterbrechen und die Ausführung anderer
Echtzeitprogramme zu veranlassen.

Im folgenden Abschnitt wird summarisch erläutert, wie der Anwender

                                   -25-
die MSRBASIC-Echtzeitmittel handhabt.

4.1.2 Organisation und Handhabung des Echtzeitbetriebes
In MSRBASIC Version 4.0 kann der Anwender bis zu 5 zyklische
Programme (TASKs) und bis zu 25 Ablaufsteuerungen (SEQuenzen)
nebenläufig (quasigleichzeitig) betreiben. Hierzu stehen ihm als
Sprachmittel die Anweisungen WAIT, DEFINE, START, ACTIVATE und
SUSPEND (s.u.) zur Verfügung. Der Echtzeitbetrieb ist durch folgende
Eigenschaften gekennzeichnet:
     -    TASKs werden als normale BASIC-Unterprogramme geschrieben
          und über die DEFINE-Anweisung durch Angabe der Nummer
          (Gleichzeitig auch Priorität), des Aufruf-Zeitintervalls
          und der Startzeilennummer in die Echtzeitverwaltung
          integriert.
     -    SEQuenzen werden ebenfalls als Unterprogramme geschrieben
          und durch Angabe der Nummer und der Startzeile in die
          Sequenzverwaltung eingegliedert.

     -    Die START bzw. ACTIVATE-Anweisung gibt die zyklische
          Bearbeitung von TASKs bzw. die einmalige Ausführung von
          SEQuenzen frei.
     -    Mit der SUSPEND-Anweisung können TASKs und SEQuenzen
          gezielt aus der Bearbeitung durch das Betriebssystem
          herausgenommen werden.
     -    Höher priore TASKs können aktive Programme niederer
          Priorität (= TASKs, SEQuenzen oder das
          Hintergrundprogramm) unterbrechen, wobei das laufende
          Statement noch bearbeitet wird, um inkonsistente Daten zu
          vermeiden.
     -    Die Quasinebenläufigkeit der SEQuenzen orientiert sich an
          den einzelnen Schritten der Ablaufsteuerung. Dies
          bedeutet, daß eine SEQuenz solange Rechenzeit inan-spruch
          nimmt, bis sie auf die nächste Weiterschaltbedingung
          (WAIT) stößt (s.d.), also einen Ablaufschritt ausgeführt
          hat, oder ein bestimmtes Rechenzeitintervall (10ms)
          erbraucht hat. Erst danach wird auf die nächste SEQuenz
          umgeschaltet bis alle SEQuenzen auf die Erfüllung ihrer
          momentanen Weiterschaltbedingung warten. Diese werden vom
          Echtzeitbetriebssystem zyklisch unter Beachtung der
          Priorität überprüft.

     -    Werden keine Echtzeitprogramme ausgeführt, steht der
          MSRBASIC-Interpreter für das Rahmenprogramm, Kommandos
          und direkte Anweisungen zur Verfügung.

     -    Da alle Variablen global gültig sind, kann der Benutzer
          auch ohne spezielles Kommunikationsprogramm während des
          Echtzeitbetriebes auf alle Variablen mit Hilfe der LET /
          PRINT-Anweisung zugreifen.
     -    Der Datenaustausch zwischen den Echtzeitprozessen
          geschieht ebenfalls über die globalen gültigen Variablen.

Damit sind alle Voraussetzungen für einen flexiblen Echtzeitbetrieb
erfüllt, wobei MSRBASIC durch eine Reihe echtzeitorientierter

                                -26-
Fehlersuch-Hilfen (SEQLIST, TASKLIST, TRACE SEQ, TRACE TASK) von
vorneherein eine hohe Transparenz gewährleistet.

4.1.3 Beispiel: "Meßwerterfassung"

Als einfaches Beispiel soll eine typische Meßwerterfassungsaufgabe
betrachtet werden, bei der die Sprungantwort einer Regelstrecke
aufgenomen werden soll:
               +--------------+
               ! Regelstrecke !
 DAC(1)------>!              !------> ADC(1)
               !              !
               +--------------+

Bild 4.2 Konfiguration "Identifikation einer Regelstrecke"
Diese Aufgabe gliedert sich in mehrere Phasen:

     1. Initialisierung von Meßaufbau und Regelstrecke
     2. Aufnahme der Meßwerte
     3. Verarbeiten der Meßwerte (Filtern, Archivieren)
Das   nachfolgende  Programm   "MESSDEM.BAS"     zeigt   eine   mögliche
Implementierung dieser Aufgabe.

Der Initialisierungsteil (Zeilen 100..190) enthält als wesentlichen
Teil die Deklaration der verwendeten Echtzeitprogramme (SEQ1, TASK1)
und startet SEQ1.
Das Hauptprogramm    (Zeilen 1000..1200)    weist genau die oben
beschriebene Ablaufstruktur auf und wird als SEQuenz ausgeführt.
Entsprechend dem zweigleisigen MSRBASIC-Echtzeitkonzept ist es in der
Phase 2 naheliegend, das zyklische Einlesen, Filtern (PT1) und Ablegen
von Meßwerten einer TASK zuzuordnen.
Diese TASK (Zeilen 2000..2060) wird zu Beginn der Phase 2 von der
SEQuenz zur zyklischen Bearbeitung freigegeben (AKTIVATE TASK1) und
bei Erfüllung eines bestimmten Kriteriums (hier: alle n Meßwerte
eingelesen) wieder gesperrt (SUSPEND TASK1).
In der letzten Phase werden die Meßwerte auf eine Datei abgespeichert.




                                 -27-
4.1.4 Listing "MESSDEM.BAS"

      100   REM **** MESSDEM.BAS ****
      105     PRINT "Wieviele Messwerte";
      110     INPUT N
      120     DIM X(N),TDOWN(1)
      130     PRINT "Tastzeit TS in Sekunden";
      140     INPUT TS
      145     PRINT "Zeitkonstante des Vorfilters";
      150     INPUT TF
      155   REM Filtertastrate ist um Faktor 10 groesser
      160     TSF=TS/10, A=EXP(-TSF/TF), B=1-A
      170     DEFINE TASK1, TSF, 2000, SEQ1, 1000
      180     START SEQ1
      190     STOP Initialisierung
     1000   REM **** Sequenz 1 steuert das Experiment ****
     1010   REM zunaechst Stellsignal 0 ausgeben
     1020     DAC(1)=0
     1040   WAIT 5 <=0
     1050     DAC(1)=1, NZ=N, I=1, TDOWN(1)=TSF
     1060     START TASK1
     1070     PRINT "Messung gestartet"
     1080   WAIT FOR NZ=0
     1090     SUSPEND TASK1
     1100     PRINT "Messung beendet"
     1110     PRINT "In welcher Datei sollen die Messwerte "
     1120     PRINT " abgespeichert werden";
     1130     INPUT FN$
     1140     OPEN FN$,10,0
     1150   REM Abspeicherungsschleife
     1160     FOR I=1 TO N
     1170       PRINT ON(10) X(I) AS 10F3
     1180     NEXT I
     1190     PRINT" Experiment beendet"
     1200   RETURN Sequenz 1
     2000   REM **** TASK1 misst zyklisch den Streckenausgang ****
     2010     X=A*X+B*ADC(1)
     2020     IF TDOWN(1)>0 THEN RETURN
     2040     TDOWN(1)=TS
     2050     X(I)=X, I=I+1, NZ=NZ-1
     2060   RETURN Task




                                 -28-
4.1.5 Empfehlungen und Warnungen

Die MSRBASIC-Echtzeitfähigkeiten müssen mit Maß und Ziel angewandt
werden, um ein stabiles, verklemmungsfreies Echtzeit-Anwenderprogramm
zu gewährleisten. Insbesondere darf die leichte Handhabbarkeit und
Flexibilität   des   Multitasking   nicht   zu  einer   übertriebenen
Parallelisierung des Anwenderprogrammes führen.

Grundvoraussetzung für ein tragfähiges Echtzeit-Programm ist eine
klare Spezifikation und ein darauf abgestimmtes Programmkonzept.
Hierbei sollten einerseits Funktionen (z.B. Regler gleicher Tastzeit,
streng sequentielle Aktionen), die nicht unbedingt parallel laufen
müssen, durchaus in einer TASK oder SEQuenz zusammengefaßt werden.
Andererseits    sollten   insbesondere     bei   ereignisorientierten
Rechenprozessen (Ablauf-steuerungen) alle Ereignisse und Aktionen, die
parallel statt-finden können, auf jeweils eine SEQuenz abgebildet
werden. Hierbei leistet eine Darstellung der Aufgabe in Form eines
Petri-Netzes wertvolle Hilfe, da es den Grad an jeweils not-wendiger
Parallelität strukturell ausweist.

Als weitere Grundregel bei der Konstruktion von Echtzeitsystemen
sollte man bei der Auslegung der Abtastzeit eher restriktiv vorgehen,
um der Gefahr einer auch nur partiellen Überlastung des Rechners
vorzubeugen.
Als   Faustregel   für  "Durchlauf-"zeiten  kann   man   von  einer
Bearbeitungszeit von 1..2 ms, bei komplexen Anweisungen auch bis zu
10ms pro Programmzeile rechnen. Damit ergibt es sich aber auch, daß
Wartebedingungen im us-Bereich unrealistisch sind.      TASK's mit
Aufrufintervall von 10ms werden andere Programme deutlich "bremsen"
wenn nicht gar völlig totlegen.




                                   -29-
5. Zusammenfassung der echtzeitspezifischen Befehle

Diese Zusammenfassung beschreibt alle Befehle und Funktionen, die
nicht im Standard-Sprachumfang enthalten sind oder vom dort-igen
Gebrauch abweichen.

Bei der Syntax-Beschreibung werden folgende Abkürzungen    ver-wendet:

     {     }    die geschweifte Klammer umfaßt Optionen
                Beispiel: DEF{INE} es kann sowohl DEF
                als auch DEFINE geschrieben werden.

     <     >    Die spitze Klammer umfasst in der Syntax-
                beschreibung nicht nennbare Daten.
                Beispiel: <zn> für Zeilennummer

          |    Dieses Zeichen trennt Wahlmöglichkeiten
                Beispiel: TASK|SEQ Es kann TASK oder SEQ
                verwendet werden.

     {,...}     Wiederholungsschleife d.h. der angegebene Teil
                kann mehrfach definiert werden.

     zn         Zeilennummer
     sz         Startzeile
     pp         Portadresse (Bereich 0..255)
     n          Nummer (allgemein)
     i          Intervall
     cr         Zeilenende




                                -30-
5.1 DEFINE

Syntaxdiagramm:




Aufruf:<zn> DEF{INE} {TASK <n>,<i>}|{SEQ <n>},<sz>{,....} <cr>

Funktionsbeschreibung:
Die    einzubindenden    TASKs    oder    SEQuenzen      werden    dem
Echzeitbetriebssystem unter Angabe ihrer Kenndaten

             n    = Nummer und gleichzeitig Priorität
                    1..5 bei TASK's und 1..25 bei SEQuenzen
             sz   = Startzeile
                    und bei TASK's
             i    = Aufrufintervall

mit dieser Anweisung bekanntgegeben.
Bei TASKs beträgt das Aufrufintervall maximal 2.54s. Alle Zeitangaben
werden auf 10ms-Stufung abgerundet.
Beispiele:

             1000 DEF TASK 1,T1,2000,TASK 2,2*T1,2200,SEQ 1 3000

             oder besser lesbar ..
              100 NotAus = 1, Regler = 2, t_reg = 5
              :
             1000 DEF SEQ NotAus,2000,TASK Regler,t_reg,4000


Hinweise:
Die höchste Priorität hat jeweils die TASK bzw. SEQuenz mit der
niedersten Nummer.

Werden Namen verwendet, müssen sie vorher als Variable vorbelegt
werden, z.B.

             NotAus = 1
             Regler = 1
             t_reg = 5

Achtung: Zeilennummern sind nicht als Variable einsetzbar!
Soll eine TASK mit einer größeren Abtastzeit als 2.54s aufgerufen
werden, bietet MSRBASIC über die Timer-Funktion TDOWN folgende

                                  -31-
Lösungsmöglichkeit:


      100   REM *** Initialisierung ***
      120   DEF TASK 1, 2, 1000
      130   DIM TDOWN(1)
      140   TA=60, TDOWN(1)=1
      150   ACTIVATE TASK 1
        :
        :
     1000   REM *** TASK 1
     1010   IF TDOWN(1)>0 THEN RETURN
     1020   TDOWN(1)=TDOWN(1)+TA
     1030   REM .. Ab hier beginnt die TASK eigentlich ..

Diese Lösung bietet die Gewähr, daß selbst bei TASK-Ausführungs-zeiten
>2s keine grob falschen Fehler in den Aufrufintervallen entstehen.
Fehler:

05   TASK bzw SEQ mit der gewünschten Startzeile existiert nicht
13   Nummer von TASK bzw. SEQ ist zu groß oder Zeitintervall
     größer als 2.54s




                                 -32-
5.2 START

Syntaxdiagramm:




Aufruf:     <zn> START {TASK|SEQ} {ALL|<n>} {,....} <cr>

Funktion:
Die im Argument der Startanweisung angegebenen TASKs werden zur
zyklischen Bearbeitung durch das Betriebssystem freigegeben. Die
Bearbeitung wird grundsätzlich bei der      ersten  Programmzeile
aufgenommen.
Der START-Aufruf kann für alle (ALL) TASK's bzw. SEQuenzen oder
gezielt für eine Einzelne (mit Nummer <n>) erfolgen.

Beispiel:
            100 START TASK ALL, SEQ 1
            oder
            100 START TASK 1, TASK 2, SEQ 1
Fehler:
26   TASK bzw. SEQ noch nicht definiert
40   Interpreter nicht im Echtzeitbetrieb (FREEZE-Mode)




                                 -33-
5.3 SUSPEND

Syntaxdiagramm:




Aufruf:     <zn> SUS{PEND} {TASK|SEQ} {ALL|<n>} {,...} <cr>

Funktion:
Die SUSPEND-Anweisung ermöglicht das Stillegen einzelner         (mit
Nummernangabe <n>) oder aller (ALL) TASKs bzw. SEQuenzen.

Hierbei wird die SEQuenzbearbeitung an der momentanen Stelle (in der
Regel an einer WAIT-Anweisung) sofort abgebrochen, wobei evtl.
aktivierte   Überwachungs-Zeitgeber   (WAIT-MAX-Funktion)  ebenfalls
eingefroren werden, um bei Re-Aktivierung (siehe ACTIVATE) eine
sachfremde Fehlerbehandlung (...ELSE...) zu vermeiden.

Die Stillegung von TASKs bedeutet, daß eine laufende TASK zu Ende
gebracht wird, jedoch kein Neustart erfolgt.
Um   bei   Programmierfehlern    eine   schnelle   Abbruchmöglichkeit
bereitzustellen, können in der Kommandobetriebsart mit CNTRL-D alle
TASKs und mit CNTRL-A alle SEQuenzen stillgelegt werden. Sofern dies
aufgrund von Endlosschleifen nicht ausreichen sollte, kann über CNTRL-
C ein endgültiger Programmabbruch erzwungen werden.
Beispiel:
     1000 SUSPEND TASK ALL, SEQ 1

Fehler:
26   TASK bzw. SEQ noch nicht definiert
40   Interpreter nicht im Echtzeitbetrieb (FREEZE-Mode)




                                 -34-
5.4 ACTIVATE

Syntaxdiagramm:




Aufruf:<zn> ACT{IVATE} {TASK|SEQ} {ALL|<n>{,<sz>}} {,...} <cr>

Funktion:

Die im Argument der ACTIVATE-Anweisung (mit Nummer <n> und Startzeile
<sz> oder ALL) angegeben TASKs werden zur zyklischen Bearbeitung durch
das Betriebssystem freigegeben. Die Bearbeitung der angegebenen
SEQuenzen wird im Gegensatz zur START-Anweisung immer in der aktuellen
Zeile fortgesetzt. Dies ist entweder die erste Zeile der SEQuenz,
falls sie noch nicht bearbeitet, oder bereits einmal komplett
durchlaufen wurde.

Falls aber die SEQuenz durch eine SUSPEND-Anweisung (oder durch ein
CNTRL-A) abgebrochen wurde, bewirkt die ACTIVATE-Anweisung eine
Wiederaufnahme der SEQuenz-Bearbeitung an der unterbrochenen Stelle.
Beispiel:

     100 ACTIVATE TASK Regler, SEQ NotAus,2050
Fehler:
05   gewünsche Startzeile existiert nicht
26   TASK bzw. SEQ noch nicht definiert
40   Interpreter nicht im real-time-mode (FREEZE-mode)




                                 -35-
5.5 WAIT

Syntaxdiagramm:




Aufruf:

      a)     <zn>   WAIT
                     <Zeit>
      b)     <zn>   WAIT
                     FOR <Bedingung>
      c)     <zn>   WAIT
                     MAX <Zeit> FOR <Bedingung>
      d)     <zn>   WAIT
                     MAX <Zeit> FOR <Bedingung> ELSE <zn>
                                            |<Anweisung>
     e)    <zn> WAIT FOR <b1>,...<bn> THEN <zn1>,..<znn>
     f)    <zn> WAIT MAX <Zeit> FOR <b1>,..<bn> THEN
<zn1>,..<znn>...
                                      ... ELSE <Anweisung>

             mit bn = Übergangsbedingung(en)
Funktion:

Die WAIT-Anweisung dient im Rahmen von SEQuenzen zur Formulierung von
Weiterschaltbedingungen. In der Form a)..d) unterstützt sie die in der
Praxis besonders häufigen linearen Ablauf-steuerungsstrukturen.

Im allgemeinsten Fall kann jedoch eine Ablaufsteuerung aus einem
Zustand   in    mehrere Folgezustände übergehen.   Hierbei  sind
Zustandsgrafen ein geeignetes Darstellungsmittel wie folgendes
Diagramm zeigt:

                           +)))))))))))))),
                    B21    *                 * B31
         +)))))))))))))>1     X1          /<)))))))))))),
         *                 *                 *                *
         *                 .))))))))))))))-               *
         *                                                     *
         *                                                     *
         *                                                     *
         *                                                     *
  B12 *                                                        *B13
+))))))v)))))))),                               +))))))))v)))))))),
*                   *                               *                   *
*     X2            /<)))))))))))))))))))))))>1       X3            *
*                   * B32                     B23 *                     *
.)))))))))))))))-                               .)))))))))))))))))-

Bild: Zustandsdiagramm für eine Steuerung mit 3 Zuständen

Dieser Zustand kann mit der Form e) und f) der WAIT-Anweisung
formuliert werden. Hierbei bestimmen bei der internen zyklischen
Prüfung der Weiterschaltbedingungen die erste erfüllte Bedingung

                                       -36-
<bn> die Zeilennummer <szi>, bei welcher die SEQuenz fortgesetzt
wird. Ist die Weiterschaltbedingung innerhalb einer vorgegebenen
Überwachungszeit (MAX ...) erfüllt, wird wie bei der IF-Anweisung
das Programm mit der nächsten Zeile fortgesetzt, ansonsten erfolgt
eine programmierbare Fehlerbehandlung, die mit ELSE eingeleitet
wird.

Hinweis:

Der Zeit-Takt ist auf 1s voreingestellt. Dieser Wert kann mit den
Funktionen TDOWN und TUP verändert werden (siehe dort).

In Unterprogrammen ist WAIT nicht erlaubt.




                                -37-
Beispiele:

zu a)
        1000 REM *** 10 Minuten warten ***
        1020 WAIT 10*60


zu d)

        2000   REM Weiterschaltbedingungen mit Zeitüberwachung
        2010   WAIT MAX 100 FOR ADC(1)>X0 ELSE 3000
        :
        3000     PRINT "Füllstand nicht rechtzeitig erreicht"
        3010   REM *** Einlaßventil schließen ***
        3020     DOUT(1)=0
        3030   STOP
zu   d)

        4000 REM *** Boolsche Bedingung ***
        4010 WAIT MAX 10 FOR DIN(1)*(DIN(6)+NOT(DIN(7)) >=1 ELSE

zu   b)
        5000 WAIT FOR DIN (Hand) + DIN (NotAus)

        ist äquivalent zu:
        5000 WAIT FOR DIN (Hand) + DIN (NotAus) > 0

Fehler:

14      unerlaubte Relation im Bedingungsteil
27      WAIT wurde ausserhalb einer SEQuenz benutzt
39      WAIT in GOSUB-Unterprogrammen nicht erlaubt




                                    -38-
5.6 TRACE

Syntaxdiagramm:




Aufruf:       <zn> TR{ACE} {SEQ{<n>}|TASK}

Funktion:
Beim Einschalten des TRACE-Modus wird beim Programmablauf jede Zeile
vor ihrer Ausführung auf der Konsole aufgelistet. Außerdem werden
bei der Ausführung einer INPUT-Anweisung auf einem nicht-interaktiv
konfigurierten Kanal die eingegebenen Zeichen auf der Konsole
angezeigt.
Folgende Varianten sind möglich:

a)   Auslisten aller Befehle (TRACE ohne Zusatz)
b)   Auslisten aller SEQuenz-Anweisungen (TRACE SEQ)
c)   Auslisten aller TASK-Aneisungen (TRACE TASK)
d)   Ein- und Ausschalten einzelner SEQuenzen (TRACE SEQ <sz>)
Hinweis:

Die Variante b) des TRACE-Befehls ist insbesondere dann vorteilhaft,
wenn man nur den in einer SEQuenz implementierten übrgeordneten
Ablauf verfolgen will, nicht jedoch die unterlagerten, zyklischen
TASK-Module.
Durch die Variante d) läßt sich TRACE auch dann noch sinnvoll
nutzen, wenn viele SEQuenzen aktiv sind.

Wird eine SEQuenz im TRACE-Modus ausgelistet, dann erscheint die
SEQuenz-Nummer an der linken Seite der Zeile (wie bei SEQLIST).
Beispiel:

Der folgende Ausschnitt des TRACE-Laufes von drei SEQuenzen zeigt
anschaulich die für diesen Programmtyp wirksame Multitasking-
Strategie nach dem round-robin-Prinzip

       S01:   1230    DOUT(1)=1
       S02:   2210    DOUT(5)=0, DOUT(6)=0
       S03:   3240    Presse=0
       S01:   1240 WAIT MAX 10 FOR DIN(1)=0 ELSE 4010
       S02:   2220    Fix1=1 : Fix2=0
       S03:   3250 WAIT MAX 5 FOR DIN(19)=1 ELSE 6120
       S02:   2230 WAIT FOR Fix3=0

5.7 NOTRACE

Syntaxdiagramm:

                                   -39-
Aufruf:     <zn> NOTR{ACE} {SEQ|TASK}

Funktion:
Abschalten des TRACE-Modus, global oder fuer TASKs bzw. SEQuenzen




                                 -40-
5.8 TASKLIST

Syntaxdiagramm:




Aufruf:     <zn> TASKLIST|TL

Funktion:
Auslisten der Startzeile, der Priorität und des Zustandes aller
TASKs.

Die TASKLIST-Anweisung zeigt in jeder Zeile die Nummer und den
Status der ausgelisteten TASKs an.
Beispiel:

T01:         1000 REM Regler
T02:   s     2000 REM Speicher
*       *
*       *
*       .)))) Status: s =   suspendiert
.))))))))))) TASK-Nummern




                                    -41-
5.9 SEQLIST

Syntaxdiagramm:




Aufruf:     <zn> SEQLIST|SL {<n>}

Funktion:
Auslisten des momentanen Programmzählerstandes aller SEQuenzen. Die
SEQLIST-Anweisung zeigt in jeder Zeile die Nummer und den Status der
ausgelisteten SEQuenz an.

Beispiel:
a)   SL
     S01: s     1210 WAIT FOR DIN(HAND)=1
     S02: s     2190 REM -- ABFAHRSEQUENZ --
     S03: s     3050 WAIT MAX 60 FOR DIN(XSilo5)=0 ELSE 3100
     ^    ^
     !    !
     !    +---- Status: s=suspendiert
     +--------- SEQuenz-Nummer
b)   SL Fuell
     S09:         4070 WAIT MAX 10*60 FOR DIN(xS3max) ELSE 4430
     READY

Hinweise:
a)   Die SEQLIST-Anweisung läßt sich für eine zyklisch aufgerufene
     Steuerungs-Zustandsübersicht verwenden
b)   Das Bedienpersonal kann durch Betätigen einer Taste die
     SEQLIST-Funktion zur Fehlersuche aufrufen; besonders wertvoll
     ist dies bei der Fehlersuche in gegenseitig verriegelten
     Ablaufsteuerungesprogrammen. Liegt z.B. eine Verklemmung vor,
     d.h. einige SEQuenzen warten vergeblich auf die gegenseitige
     Erfüllung einer Weiterschaltbedingung, so listet SEQLIST die
     fraglichen WAIT-Anweisungen aus. Durch manuelles Prüfen der
     Weiterschaltbedingung kann dann in der Regel rasch die
     Fehlerursache gefunden werden.




                                    -42-
5.10 Logikfunktionen

5.10.1 NOT(X)
Funktion:

NOT(X) liefert den Wert "1", wenn X=0 ist, ist X<>0 wird "0"
zurückgegeben.

Beispiel:
     100    REM *** Benutzung von NOT(x)
     110      vent1 = 1, tast1 = 1, tast2 = 2, tast3 = 3
     :
     200    DOUT(vent1)=DIN(tast1)*DIN(tast2)+NOT(DIN(tast3))
     :

5.10.2 BIT(N,X)

Funktion:

BIT(N,X) wandelt X in eine 16-Bit-Zahl (-32768 < X < 32767) und
liefert eine "1" wenn das N-te Bit (0..15) gesetzt (=1) ist, ist das
N-te Bit nicht gesetzt (=0) wird eine "0" zurückgegeben.

Beispiel:
            100   REM *** BIT-Test ***
            110     ready = 4, port = &H40
            :
            200    x = GET(port)
            210    IF BIT(x,ready) THEN 300 ELSE 200
            :
            300   REM Port ist bereit: jetzt Aktion ...




                                  -43-
5.10.3 Boolsche Ausdrücke

Die Boolschen Operatoren AND und OR können auf die arithmetischen
Operatoren "*" und "+" zurückgeführt werden, wobei deren Rangfolge
auch bei boolschen Verknüpfungen gilt (siehe Kapitel Operatoren).

Beispiel:

a) Funktionsplan
                                                           +))))),
X2     ))))))))))))))))))))))))))))))))))))>0        *
                                     +))))),       * >= *
X1     )))))))))))))))))))))))>1       *        *      /))))> Y2
                   +))))),         *       *       *        *
X3     )))))))))>1      *         * &     /)))))>1       *
                   * >= *            *       *       .)))))-
                   *       /))))))>1       *
                   *       *         .)))))-
X4     )))))))))>0       *
                   .)))))-


b) MSRBASIC-Formulierung:
     100    REM *** Boolsche Verknüpfung AND und OR
     110      DOUT(2) = DIN(1)*(DIN(3) + NOT(DIN(4)) + NOT(DIN(2)

Hinweis:
Die boolsche Verknüpfung ist nur bei den boolschen "Ergebnissen" "0"
und "1" möglich. Das maskieren von HEX-Werten z.B.
                   &H00C5 * &H0080
mit dem erwarteten Ergebnis &H0080, funktioniert hier nicht! Um BIT-
Werte zu testen muß die Funktion BIT(n,x) verwendet werden.




                                       -44-
5.11 Prozeß Ein-/Ausgabe-Funktionen

Die Ein-/Ausgabe von beliebigen Daten verteilt sich in BASIC auf zwei
klar zu trennende Bereiche:
a)   Die Ein-/Ausgabe über die Konsole, den Drucker und alternative,
     meist seriellen Zusatzkanäle (AUX).

     Diese Kanäle werden über die Standard-Funktionen INPUT und
     PRINT, LIST, LOAD und SAVE usw. angesprochen.
     Die dazugehörenden Kanäle sind fest in das Betriebssystem
     eingebunden; der Benutzer braucht sich im Normalfall nicht darum
     zu kümmern.

b)   Im Sprachumfang von Standard-BASIC nicht definierte Ein-
     Ausgabekanäle (Ports) die (falls überhaupt) über die Funktionen
     INPORT bzw. OUTPORT angesprochen werden.
     Die entsprechenden Kanäle (Ports) sind üblicherweise nicht in
     das Betriebssystem eingebunden, der Benutzer muß sich um die
     Verwendbarkeit der Kanäle selbst kümmern.
Bei der Prozeß-Ein-/Ausgabe kommt eigentlich nur der Fall (b) in
Frage. Das bedeutet aber: der Programmierer muß genaue Kenntnis über
die verwendeten Ein-/Ausgabe-Bausteine haben, er muß wissen wie diese
zu initialisieren sind, welche Wandelzeiten, welche Statusbits usw. zu
berücksichtigen sind. Dazu kommen noch die Probleme mit der Normierung
und "Lage" bzw. Bedeutung der einzelnen Bits z.B. in einem 12-Bit AD-
Wandler usw....

In MSRBASIC wurde dieses Problem umgangen, indem entsprechende
Funktionseinheiten wie AD-/DA-Wandler, BIT-Ein-Ausgabe-Kanäle und
Zähler bereits softwaremäßig in den Interpreter eingebunden werden. Da
nicht ALLES und JEDES eingebunden werden kann, bedeutet dies natürlich
auch eine Beschränkung in der Anzahl der Kanäle und der Art der
Funktionseinheiten. MSRBASIC ist daher vor allem in diesem Bereich
konfigurationsabhängig (siehe Kapitel Hardware-Anpassung).
Der Zugriff auf die eingebundene Zusatzperipherie erfolgt        über
MSRBASIC-typische Funktionen die nachfolgend beschrieben sind.




                                 -45-
5.11.1 Skalare Prozeß-Eingabe-Funktionen

5.11.1.1 ADC(n)
Funktion:

Einlesen eines 16-Bit-Wertes vom Analogkanal (n). Die Anzahl (wieviele
Kanäle) und Art (wieviel Bit Auflösung) der Kanäle sowie die
Skalierung (0..n oder -n..+n) ist konfigurationsabhängig.
Beispiel:

            100   REM *** AD-Wert einlesen ***
            110     ofen1 = 3
            :
            200      temp1 = ADC(ofen1)
            210      IF temp1 > 100 THEN ..... ELSE ....
Hardware:

Für ECB-Systeme sind bis zu 4 Systemkarten Typ ECB-16AD12B(C)
eingebunden. Damit sind max. 64 AD-Eingskanäle ansprechbar.
Die   Kartenadressen müssen wie folgt eingestellt sein:
      Kanal 1..16       Adresse   0B0H
      Kanal 17..32      Adresse   0B4H
      Kanal 33..48      Adresse   0B8H
      Kanal 49..64      Adresse   0BCH

Bei TSM-Systemen werden die Module (TSM-16AD12) automatisch erkannt.
Das Modul mit der niedrigesten Adresse beginnt mit Kanal 1..16, das
Modul mit der höchsten Adresse endet mit Kanal 49..64. Die
Moduladressen müßen nicht aufeinanderfolgend ein-gestellt werden!

Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung
(falls ein ADC überhaupt vorhanden ist), da alle Bausteine auf festen
Adressen sind.




                                    -46-
5.11.1.2 DIN(n)

Funktion:
Einlesen des Binärkanals (n). Die Art (TTL, 24Volt usw.) und die
Anzahl der Kanäle ist konfigurationsabhängig. Die eingelesenen Werte
betragen "0" oder "1".

Hinweis:
Es ist zu beachten, daß mit (n) jeweils ein BIT eines (hardwaremäßig
vorgegebenen) Eingangports adressiert wird.

Beispiel:

            100   REM *** Binaerwert einlesen ***
            110     NotEin = 1, Alarm = 2, Ein = 0
            :
            200     X = DIN(NotEin)
            205   REM ** Wenn NotEin dann Alarm
            210     IF X = 0 THEN DOUT(Alarm) = Ein
            :

Hardware:
Für ECB-Systeme sind bis zu 8 Systemkarten eingebunden.Damit sind max.
128 digitale Eingangskanäle ansprechbar.
Es können folgende Systemkarten verwendet werden:
      8* ECB-24VB, ECB-24V=, ECB-24-VK

Die   Kartenadressen müssen wie folgt eingestellt sein:
      Kanal 1..16      Adresse 080H
      Kanal 17..32     Adresse 082H
      Kanal 33..48     Adresse 084H
      Kanal 49..64     Adresse 086H
      Kanal 65..80    Adresse 088H
      Kanal 81..96    Adresse 08AH
      Kanal 97..112    Adresse 08CH
      Kanal113..128   Adresse 08DH
Bei Verwendung der Systemkarte ECB-OP32IN (Nur Eingang) können nur die
geradzahligen Kartenadressen genutzt werden.

Die ECB-Systemkarten können auch gemischt verwendet werden, solange
sich die Adressen nicht überschneiden. Es ist nicht möglich, z.B. eine
ECB-Relaiskarte auf einer bestimmten Adresse als Ausgang zu verwenden
und, unter der gleichen Adresse, die ECB-OP32IN-Karte als Eingang.

Der Schaltzustand der Relaiskarte ECB-REL16R kann unter einer der oben
angegebenen Adresse zurückgelesen werden.

Bei TSM-Systemen werden die Module TSM-8E24, TSM-8E230 und TSM-32E24
automatisch erkannt. Das Modul mit der niedrigsten Adresse beginnt mit
Kanal 8..16(32). Die Kanalnummern 1..8 sind für die Eingänge auf dem
CPU-Modul reserviert.


                                  -47-
Die Adressen der Ausgangsmodule    müssen   nicht   aufeinanderfolgend
eingestellt werden!

Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung
(falls ein digitaler Eingang überhaupt vorhanden ist), da alle
Bausteine auf festen Adressen sind.




                                -48-
5.11.1.3 GET(pp)

Funktion:
Einlesen des Eingabeports (pp). Diese Funktion entspricht der Funktion
INPORT(pp) im Standard-BASIC. Der eingelesene Wert liegt zwischen 0
und 255 (00H..FFH).

Hinweis:
Es ist zu beachten, daß diese Funktion den angegebenen Eingangsport
mit allen Einschränkungen direkt einliest. Der Programmierer muß auf
eine evtl. notwendige Initialisierung des Eingabeports selbst achten
und muß die zurückgelesenen Daten selbst interpretieren!

Beispiel:
            100    REM *** Lesen eines Ports nach Statusabfrage
            100      Basis = &H80
            :
            200     stat = GET(Basis)
            205   REM pruefen ob ein Zeichen vorliegt
            210     stat = BIT(2,stat)
            220     IF stat = 0 THEN 200
            225   REM JA .. Zeichen liegt vor
            230     char = GET(Basis+1)
            240   REM Im Beispiel Zeichen als ASCII auf Konsole
            250     PRINT char$(char);




                                   -49-
5.11.1.4 CNT(n)

Funktion:
Einlesen eines Zählerkanals (n). Die Art (8 oder 16-Bit Zähler) und
die Anzahl der vorhandenen Zählerkanäle sind konfigurationsabhängig.

Beispiel:

             100 REM *** Zaehlerbeispiel ***
             110    max = 1024
             :
             200    count = CNT(0)
             210    IF count < max THEN 1000
             220 REM Zaehler zuruecksetzen
             230    CNT(0) = 0
             240 REM ... und jetzt reagieren auf Ueberlauf
             :
            1000 REM Hierher wenn "Endstand noch nicht erreicht"

Hardware:

Bei TSM sind die 8 Digital-Eingänge auf der CPU-Baugruppe wahlweise
als 24-Volt-Eingang oder als Zähler zugelassen. Die CNT-Funktion
liefert die anliegende Frequenz und die DIN-Funktion den anliegenden
Pegel zurück. Die Bezeichnung der Kanäle ist CNT(1)..CNT(8) bzw.
DIN(1)..DIN(8).
Die Zähler können recht hohe sowie unsymetrische Frequenzen erfassen,
die hauptsächlich durch die Eingangsbeschaltung (intern, extern,
Filter, Optokopler u.Ä.) begrenzt sind. Die Torzeit beträgt bei allen
Zählern 100 ms; zurückgegeben wird die anliegende Frequenz/10.

Für ECB-Systeme und MPS-Einplatinencomputer bitte gesondert anfragen.




                                  -50-
5.11.2 Skalare Prozeß-Ausgabe-Funktionen

Die Prozeß-Ausgabe-Funktionen sind das jeweilige Gegenstück zu den
oben genannten Eingabe-Funktionen. Im Gegensatz zu diesen stehen sie
aber immer auf der linken Seite von Zuweisungen.

5.11.2.1 DAC(n)
Funktion:

Dies ist die Umkehrung der Funktion ADC(n). Es wird ein 16-Bit
(Digital-) Wert auf den Analogkanal (n) ausgegeben. Die Art (Auflösung
8 oder 16-Bit) und die Anzahl der Kanäle sowie die Skalierung ist
konfigurationsabhängig.
Hinweis:

Es erfolgt keine Fehlermeldung wenn versucht wird ein 16-Bit-Wert auf
einen 8-Bit-Kanal auszugeben. Ausgegeben wird in diesem Falle der
untere 8-Bit-Wert (Bereich 0..255) !

Beispiel:
            100   REM *** Beispiel einer Analog-Ausgabe
            110     Vent1 = 1, ESch1 =1 ESch2 = 2
            :
            190   REM Pruefen auf Endbedingung
            200     x = GET(ESch2)
            210     IF x = 1 THEN 300
            220   REM Ventil 1 langsam oeffnen bis ESch2 = 1
            230     temp=1
            240     DAC(Vent1) = temp
            250     temp = temp+1
            260     x = GET(ESch2)
            270     IF x = 0 THEN 250
            290   REM wenn ESch2 schaltet ...
            300   REM Ventil 1 langsam schliessen bis ESch1 = 1
            310     temp=254
            320     DAC(Vent1)=temp
            330     temp=temp-1
            340     x = GET(ESch1)
            350     IF x = 0 THEN 320
            360   GOTO 220
            :
Hardware:

Für ECB-Systeme sind bis zu 4 Systemkarten Typ ECB-4DA12 ein-gebunden.
Damit sind max. 16 DA-Ausgangskanäle ansprechbar.

Die   Kartenadressen müssen wie folgt eingestellt sein:

      Kanal 1..4       Adresse   0C0H
      Kanal 5..8       Adresse   0C4H
      Kanal 9..12      Adresse   0C8H
      Kanal 13..16     Adresse   0CCH

Bei TSM-Systemen werden die Module (TSM-2DA12) automatisch erkannt.
Das Modul mit der niedrigsten Adresse beginnt mit
Kanal 1..2. Die Moduladressen müßen nicht aufeinanderfolgend
eingestellt werden!

                                   -51-
Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung
(falls ein DAC überhaupt vorhanden ist), da alle Bausteine auf festen
Adressen sind.




                                -52-
5.11.2.2 DOUT(n)

Funktion:
Ausgabe auf den Binärkanal (n). Die Art (TTL, 24Volt usw.) und die
Anzahl der Kanäle ist konfigurationsabhängig. Der Ausgabewert beträgt
0 oder 1.

Hinweis:
Es ist zu beachten, daß mit (n) jeweils ein BIT eines (hardwaremäßig
vorgesehenen) Ausgangsports adressiert wird.

Beispiel:
      100   REM *** Beispiel mit Digital Ein-/Ausgabe
      110     Rel1 = 1, Rel2=2
      120     Tast1 = 1, Tast2 = 2, Tast3 = 3
      :
      200   REM Schalte Relais 1 wenn Tast1 UND Tast2 UND Tast3
            210 DOUT(Rel1)=DIN(Tast1)*DIN(Tast2)*DIN(Tast3)
      :
      300   REM Schalte Relais 2 wenn Tast 1 ODER Tast3
      310     DOUT(Rel2)=DIN(Tast1)+DIN(Tast3)
      :
      400   REM Schalte Relais 2 wenn Tast2
      410     DOUT(Rel2)=DIN(Tast2)
      :
      500   REM Schalte Relais 2 wenn CNT(1) > 1000
      510     x = CNT(1)
      520     IF x > 1000 THEN DOUT(Rel2) = 1
      :

Hardware:
Für ECB-Systeme sind bis zu 8 Systemkarten eingebunden. Damit sind
max. 128 Digitale Ausgangskanäle ansprechbar. Es können folgende
Systemkarten verwendet werden:
      8* ECB-24VB, ECB-24V=, ECB-24-VK, ECB-REL16R
Die   Kartenadressen müssen wie folgt eingestellt sein:

      Kanal 1..16       Adresse 080H
      Kanal 17..32      Adresse 082H
      Kanal 33..48      Adresse 084H
      Kanal 49..64      Adresse 086H
      Kanal 65..80     Adresse 088H
      Kanal 81..96     Adresse 08AH
      Kanal 97..112     Adresse 08CH
      Kanal113..128    Adresse 08DH

Die ECB-Systemkarten können auch gemischt verwendet werden, solange
sich die Adressen nicht überschneiden.

Bei TSM-Systemen werden die Module TSM-8A24, TSM-8A230 und TSM-32A24
automatisch erkannt. Das Modul mit der niedrigesten Adresse beginnt
mit Kanal 8..16(32). Die Kanalnummern 1..8 sind für die Ausgänge auf
dem CPU-Modul reserviert.

Die   Adressen   der   Ausgangsmodule   müssen   nicht   aufeinanderfolgend

                                   -53-
eingestellt werden!

Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung
(falls ein Digitaler Ausgang überhaupt vorhanden ist), da alle
Bausteine auf festen Adressen sind.




                                -54-
5.11.2.3 PUT(pp)


Funktion:
Ausgabe eines 8-Bit-Wertes (0..255) auf den Ausgabeport (pp). Diese
Funktion entspricht der Funktion OUTPORT in Standard-BASIC.

Hinweis:
Es ist zu beachten, daß diese Funktion den angegebenen Wert mit allen
Einschränkungen direkt ausgibt. Der Programmierer muß auf eine evtl.
notwendige Initialisierung des Ausgangsports selbst achten und muß
die "Wirkung" der Ausgabe kennen.

Beispiel:
            100   REM *** Beispiel einer Portinitialisierung ***
            101   REM *** für einen PIO-Kanal auf ECB-PIO/W ***
            110   base = &H24
            :
            200    REM Init Kanal A    auf Eingabe Bit 0..3
            210    REM                 auf Ausgabe BIT 4..7
            220         PUT(base+2)    = &HCF
            230         PUT(base+2)    = &H0F
            :
            300    REM Beschreiben des Kanals
            310        PUT(base) = &H05
            :




                                      -55-
5.11.2.4 CNT(n)

Funktion:
Setzen eines Zählerkanals. Die Art (8- oder 16-Bit-Zähler) und die
Anzahl der Kanäle ist konfigurationsabhängig.

Beispiel:

            200   REM *** Zuruecksetzen eines Zählerkanals
            210     cntr1 = 1
            :
            300   CNT(cntr1) = 0
            ;

Hardware:
Bei TSM sind die 8 Digital-Eingänge auf der CPU-Baugruppe wahlweise
als 24-Volt-Eingang oder als Frequenzzähler (ab 10 Hz) zugelassen. Da
es wenig Sinn macht, einen Frequenzzähler vor-einzustellen oder
zurückzusetzen, wurde CNT(n) für TSM nicht implementiert.

Für ECB-Systeme und MPS-Einplatinencomputer bitte gesondert anfragen.




                                   -56-
5.11.3 Vektor Ein/Ausgabe-Funktionen

Vektorfunktionen    werden   im   Rahmen    von   VEC-Anweisungen   ausgeführt
(siehe diese).
5.11.3.1 MADC(MO)

Funktion:

Einlesen eines Meßvektors. Die Komponenten des Meßortvektors MO legen
die einzelnen Eingabekanäle fest.

5.11.3.2 MDAC(SO)

Funktion:

Ausgabe eines Stellvektors. Die Komponenten des Stellvektors SO legen
die einzelnen Ausgabekanäle fest.

5.11.3.3 MDIN(MD)

Funktion:
Einlesen eines Binärvektors.
5.11.3.4 MDOUT(SD)

Funktion:
Ausgabe eines binären Steuervektors.
Beispiel:

             150 DIM XE(N), MO(N), Y(N), SO(N)
               :
            1000 VEC XE=MADC(MO), MDAC(SO)=Y
                   ist äquivalent zu:

            1000 FOR I=1 TO N
            1010    XE(I) = ADC(MO(I)), DAC(SO(I))=Y(I)
            1020 NEXT I




                                     -57-
5.11.4 Abfrage der Prozeßkonfiguration

Mit diesen Abfragen kann festgestellt werden welche Kanäle installiert
sind. Die Ergebnisse sind konfigurationsabhängig.
Nähers zur Hardware-Konfiguration ist in Kapitel 10 zu finden.

5.11.4.1 NDAC

Funktion:
Es wird die Anzahl der installierten DAC-Kanäle zurückgemeldet.

5.11.4.2 NADC

Funktion:

Es wird die Anzahl der installierten ADC-Kanäle zurückgemeldet.
5.11.4.3 NDOUT

Funktion:

Es wird die Anzahl der installierten DOUT-Ports zurückgemeldet. Es ist
zu beachten, daß ein Port = 8 Kanäle hat!
5.11.4.4 NDIN

Funktion:
Es wird die Anzahl der installierten DIN-Ports zurückgemeldet. Es ist
zu beachten, daß ein Port = 8 Kanäle hat!
5.11.4.5 NCNT
Funktion:

Es wird die Anzahl der installierten CNT-Kanäle zurückgeliefert.
Beispiel:

            100   REM *** Beispiel Konfigurationsabfrage ***
            :
            200     FOR i=1 TO 8*NDIN
            210       PRINT DIN(i) AS 1i;
            220     NEXT i




                                  -58-
5.12 Zeitgeberfunktionen

5.12.1 TDOWN
5.12.2 TUP
Aufruf:

     a) Deklarieren: DIM TUP(n),TDOWN(n)

     b) Stellen:              TDOWN(n)=<Zähler>
                              TUP(n)=<Zähler>

     c) Lesen:                PRINT TDOWN(n)
                              PRINT TUP(n)

Funktion:
Die Zeitgeber TDOWN (abwärtszählend) und TUP (aufwärtszählend), werden
wie eindimensionale numerische Felder behandelt. Die Voreinstellung
des Zeittaktes beträgt 1s.


5.12.3 Zeitfaktor "TIMEFAC"
Aufruf:

     a) Lesen         PRINT TIMEFAC <cr>
     b) Stellen       TIMEFAC = <n> <cr>
Funktion:
Ein Lesezugriff auf TIMEFAC liefert das aktuelle Aufrufintervall der
MSRBASIC-internen Zeitgeber-TASK in 10ms-Einheiten.
In der Regel hat TIMEFAC den WERT 100 (100*10ms=1s)
In einzelnen Fällen kann es sinnvoll sein, die Zeitinkremente zu
verändern (insbesondere zu verkürzen). Eine Auflösung von 100ms
erreicht man z.B. durch die Anweisung:

            TIMEFAC = 10

Eine dadurch erreichte Beschleunigung wirkt sich aus auf:

            - TUP- /TDOWN-Felder
            - Wartezeiten in WAIT/WAIT MAX-Anweisungen

Sie wirkt sich nicht auf die TASK-Aufrufintervalle aus!


5.12.4 24 Bit-Zeitgeber (nur TSM)

Die TSM-CPU verfügt über einen freilaufenden 24-Bit Zeitgeber mit
einem Takt von 1ms.




                                   -59-
5.12.4.1 MSRTIMER

Die Timeranzeige wird wie eine Variable gelesen:
     zeit = MSRTIMER

Im Beispiel enthälte <zeit> den momentanen Zählerstand des Timers.


5.12.4.2 MSTIMDIF
Diese Funktion erlaubt die Berechnung von Zeitdifferenzen zwischen
einem bereits gespeicherten Zeitgeberwert und dem aktuellen Inhalt des
Zeitgebers:

     100   zeit = MSRTIMER
     110   REM ... was immer ..
       :
     800   tdiff = MSTIMDIF(zeit)
     810   PRINT "Zeitdifferenz: "; tdiff; " ms"

Es lassen sich auf diese Art recht genaue Zeitdifferenzen bis zu 2796
Minuten feststellen.
Eine andere Anwendung wären z.B. Zeitschleifen:

     100   zeit = MSRTIMER
     110   IF MSRIMEDIF(zeit) < 1000 GOTO 110
     120   REM wartet eine Sekunde ...

5.12.5 Kalender und Uhrzeit

Voraussetzung für die korrekte Belegung der nachfolgend genannten
Variablen ist die Installation einer Hardware-UHR und deren Einbindung
in MSRBASIC.
Auch wenn keine Hardware-Uhr in MSRBASIC eingebunden ist, können
jedoch die nachfolgend genannten Variablen benutzt werden, wenn ihnen
zur geeigneten Zeit ein entsprechender Inhalt zugewiesen wird.


5.12.5.1 TIME$
Die Variable TIME$ enthält bei einem Lesezugriff die Tageszeit in der
Form:

     "hh:mm:ss"
mit hh=Stunden, mm=Minuten, ss=Sekunden




                                  -60-
5.12.5.2 DATE$

Die Variable DATE$ enthält bei einem Lesezugriff das Datum in der
Form:
     "dd:mm:jj"

mit dd=Tag, mm=Monat, jj=Jahr.

5.12.5.3 DOW$

Die Variable DOW$ gibt die deutsche Kurzform des aktuellen Wochentages
wieder:

     SO    Sonntag         DO    Donnerstag
     MO    Montag          FR    Freitag
     DI    Dienstag        SA    Samstag
     MI    Mittwoch




                                 -61-
5.13 Reglerfunktionen

5.13.1 Allgemeines
Als parametrierbare Reglerfunktionsblöcke werden in MSRBASIC (skalare
und vektorwertige) PI- und PID-Regelalgorithmen mit Positions- und
Geschwindigkeits-Ausgang   angeboten.   Sie    realisieren   folgende
Grundformel:

Berechnen des Zuwachses:
     Dyi := Kp*(ei-ei-1+KI*ei+KD*(ei-2*ei-1+ei-2))

                            A<-- nur bei PID -->


Umspeichern der vergangenen Regeldifferenzen:
     ei-2 = ei-1, ei-1 = ei

Die Stellungsversion summiert dazu noch die Stellinkremente auf:

     yi = yi-1 + Dyi
Der MSRBASIC-PID-Funktionsblock entspricht folgendem BASIC-Programm:

     1000   REM *** PID-Algorithmus ***
     1010   REM Bedingte Bildung des Integralteils
     1020     IF AK*E<=0 THEN I=KI*E ELSE I=0
     1030     DY = KP*(E-E1 + I + KV*(E-2*E1+E2))
     1040     AK = AK+DY
     1050     E2 = E1, E1 = E
     1060     DY = AK
     1070   REM Stellsignal begrenzen
     1080     IF DY>0 THEN GOSUB 1100 ELSE GOSUB 1150
     1090     AK = AK-DY, Y = Y+DY
     1099   RETURN
     1100   REM positives Stellinkrement begrenzen
     1110     IF DY>YD THEN DY=YD
     1120     IF DY>YO-Y THEN DY=YO-Y
     1130     IF DY>YU-Y THEN DY=YU-Y
     1140   RETURN
     1150   REM negatives Stellinkrement begrenzen
     1160     IF DY<-YD THEN DY=YD
     1170     IF DY<YU-Y THEN DY=YU-Y
     1180     IF DY<YO-Y THEN DY=YO-Y
     1190   RETURN

Über den reinen PID-Algorithmus hinaus (Zeilen 1030 und 1090:2) sind
also folgende wichtigen Funktionen realisiert:

     -      Stoßfreie   on-line-Parameterverstellung    durch   interne
            Geschwindigkeitsform.

     -      Automatisches Abschalten des I-Anteiles (Zeile 1020), wenn
            eine Stellgrößen- oder Stellgesschwindigkeitsbeschränkung
            (Zeilen 1100 .. 1190) erreicht wird (Verhinderung der
            Integralsättigung).

     -      Verhinderung des proportional-differentialen Anfahreffekt

                                 -62-
bei den Versionen mit Geschwindigkeitsausgang durch die
             Zwischenspeichermethode (Zeilen 1040,1060,1090).

      -      Automatische Stellgrößenanpassung an dynamisch veränderte
             Grenzwerte YO bzw YU (Zeilen 1130,1180), wichtig bei
             Kaskadenschaltung!


5.13.2 P/PID-Einzelregler
Die Reglerfunktionen können syntaktisch wie Standardfunktionen
verwendet, also auch in arithmetische Ausdrücke eingebunden werden.
Als Ausgangsgröße wird je nach Algorithmus der Momentanwert der
Stellgröße oder der Stellgeschwindigkeit geliefert.
PID-Stellungsalgorithmus:

      PID(Y,E,E1,E2,KP,KD,KI,YO,YU,YD,AK)
PID-Geschwindigkkeitsalgorithmus:

      GPID(Y,E,E1,E2,KP,KD,KI,YO,YU,YD,AK)

PI-Stellungsalgorthmus:
      PI(Y,E,E1,KP,KI,YO,YU,YD,AK)

PI-Geschwindigkeitsalgorithmus:
      GPI(Y,E,E1,KP,KI,YO,YU,YD,AK)

Hierbei bedeuten:
Y:    Stellgröße
E:    momentane Regeldifferenz (Eingangsgröße)
E1:   letzte Regeldifferenz (Zustandsgröße)
E2:   vorletzte Regeldifferenz (Zustandsgröße)
KP:   Verstärkung
KD:   Differentialbeiwert (Regler-Parameter)
KI:   Integralbeiwert
YO:   Stellgrößenobergrenze
YU:   Stellgrößenuntergrenze (Parameter)
YD:   max. Stellgrößenzuwachs
AK:   Zwischenspeicher (Zustandsgröße)
Zu beachten ist, daß die Reglerfunktionen neben dem Stellsignal als
eigentlicher Ausgangsgröße auch das Umspeichern der früheren Werte der
Regeldifferenz und die Verwaltung des Zwischenspeichers vornehmen.Der
Anwender muß hierfür nur die entsprechenden Variablen bereitstellen.


5.13.3 Vektor P/PID-Regler

Im Rahmen der VEC-Anweisung können neben den Prozeß-Ein/Ausgabe-
Funktionen MADC, MDIN und MDOUT auch die Reglerblöcke PI und PID
verwendet werden. Die Anweisung:
      1000   VEC Y = PI(Y,E,E1,KP,YO,YU,YD,AK)

             ist funktionell gleichbedeutend mit:


                                  -63-
1000    FOR I = 1 TO N
     1010        Y(I) = PI(Y(I),E(I),E1(I),KP(I),KI(I),YO(I),
                        YU(I),YD(I),AK(I)
    1020    NEXT I
Allerdings halbiert sich bei Verwendung der VEC-Anweisung sowohl der
Schreib- wie der Rechenaufwand.




                                 -64-
5.14 Speicherfunktionen

5.14.1 PEEK(N)
Funktion:

Mit der PEEK-Funktion kann der Inhalt einer Speicherstelle im Adreß-
Bereich 0..65535 eingelesen werden. PEEK ist die Umkehrung der POKE-
Anweisung (siehe dort).
Beispiel:

            100   REM *** HEXDUMP ***
            110   addr = &H1000
            120   FOR I = 1 TO 16           ' 16 Zeilen
            130   PRINT addr AS 4H;              ' Startadresse
            140   PRINT ": ";
            150   FOR J = 1 TO 16           ' 16 Bytes
            160   PRINT PEEK(addr) AS 2H;
            170   PRINT " ";                ' Bytes trennen
            180   addr=addr+1
            190   NEXT J                         ' Innere Schleife
            200   PRINT                          ' neue Zeile
            210   NEXT I
            220   PRINT
            230   END




                                  -65-
5.15 Hintergrundspeicher (nur CPUZ280 und TSM-CPU280)

Urspünglich wurde MSRBASIC für 16-Bit Prozessoren mit max. 64 Kb
Speicher entwickelt, wobei üblicherweise 32 Kb EPROM-Speicher für
MSRBASIC und 32 Kb RAM-Speicher für das Anwenderprogramm zur Verfügung
stand.

Um in Applikationen der Meßwerterfassung auch mit größeren Datenmengen
umgehen zu können, wurde für die neue Prozessorserie Z280 eine
Erweiterung des Befehlssatzes von MSRBASIC vorge-nommen, die speziell
diesen Wünschen gerecht wird.

Diese BiGMEMory-Funktionen erlauben das Einrichten von Daten-feldern
in, sowie das Einfügen und Entfernen von Daten aus einem
Hintergrundspeicher über die "normalen" 64 Kb hinaus bis 1Mb (und mehr
bei ECB-CPUZ280).
Der Hintergrundspeicher kann als ein Feld von Datenstrukturen
aufgefaßt werden. Es können bis zu 8 Hintergrundspeicher mit
unterschiedlicher, voneinander unabhängiger Datenstruktur, de-finiert
werden, deren Größe nur durch den verfügbaren Speicher-platz begrenzt
wird.
Auf den Hintergrundspeicher kann in Form eines Ringspeichers mit
Strukturen direkt (wahlfrei), als Queue (Schlange) und/oder als Stack
(Stapelspeicher) zugegriffen werden. Es können jedoch nicht einzelne
Elemente sondern nur komplette Strukturen beschrieben bzw. gelesen
werden.
In der MSRBASIC-Version für die TSM-CPUZ280 kann für den Hinter-
grundspeicher ein FLASH-EPROM genutzt werden, um Daten dauerhaft zu
erhalten.




                                 -66-
5.15.1 BGMEMDIM

Syntaxdiagramm:




Aufruf:      <zn> BGMEMDIM (n, e, vl) <cr>

             mit n = Nummer des Hintergrundspeichers (0..7)
                 e = Anzahl der Strukturen
                vl = Aufzählung der Variablentypen
Funktion:
Die BGMEMDIM-Anweisung    dient   der    Einrichtung   eines   Hintergrund-
speichers (max. 8).
Die Nummerierung (n) sollte in aufsteigender Ordnung erfolgen und
dient der Identifizierung des Speichers. Jede Struktur hat einen
Aufbau wie er in vl (Variablenliste) angegeben ist. Die Namen der
Variablen haben hier keine Bedeutung, es wird ledig-lich der
Variablen-TYP benötigt, um den strukturellen Aufbau und den
Platzbedarf für die Initialisierung zu bestimmen.
Folgende Typen sind zugelassen:
     a$(n)        String mit max. n Buchstaben.
     a            Gleitkommazahl.
     a(n)         Feld (Array) von Gleitkommazahlen mit
                  der Domension n.

Bei der Initialisierung (Kaltstart) wird der Inhalt von String-Felden
mit dem Zeichen "-" gefüllt. Gleitkommazahlen werden mit der größten
negativen Zahl initialisiert.

Der Hintergrundspeicher(Nr 0) im FLASH-EPROM (nur TSM-CPUZ280)
ist immer definiert.
Beispiel:

     100    BGMEMDIM(1, 100, a$(8),a,a,a(8))
     101    REM Der Hintergrundspreicher Nummer 1
     101    REM  kann 100 Datenstrukturen der Form
     102    REM string[8], float, float, float[10]
     103    REM aufnehmen.
Fehler:
5.15.2 BGMEM Wahlfreier Zugriff

5.15.2.1 BGMEMPUTR

                                  -67-
Syntaxdiagramm:




Aufruf:     <zn> BGMEMPUTR(n, c, vl)
            mit n = Nummer des Hintergrundspeichers (0..7)
                 c = Nummer der Struktur in diesem HS.
                vl = Liste der Variablen.

Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden,
entsprechen.


Funktion:

Die BGMEMPUTR-Anweisung ermöglicht den wahlfreien Schreibzugriff
(Random Access) auf einen bestimmten Hintergrundspeicher (n),
bestehend aus einem ARRAY mit (c) Elememten, welche ihrerseits aus
einer beliebigen, vom Benutzer definierten, Datenstruktur (nach vl)
zusammengesetzt sind.
Die Eintragung in den Hintergrundspeicher wird nicht von BGMEMSS
erfasst (siehe dort), im Gegensatz zu Eintragungen mit BGMEMPUTQ und
BGMEMPUSH.

Beispiel:
     1100   BGMEMDIM (0,100,a$(8),a,a,a(8))
     1110   FOR i = 0 TO 99
     1120   REM
     1130   REM hier werden die Variablen
     1140   REM varb, varc, varar(n) "bearbeitet"
     1150   REM
     1160   REM ... und jetzt in BGMEM abgelegt:
     1170   REM
     1180   BGMEMPUTR (0, i, time$, temp1, temp2, schalter())
     1190   NEXT i

Fehler:




5.15.2.2 BGMEMGETR
Syntaxdiagramm:




                                 -68-
Aufruf:     <zn> BGMEMGETR(n, c, vl)
            mit n = Nummer des Hintergrundspeichers (0..7)
                 c = Nummer der Struktur in diesem HS
                vl = Liste der Variablen
Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden,
entsprechen.

Funktion:
Die BGMEMGETR-Anweisung ermöglicht den wahlfreien Lesezugriff (Random
Access) auf einen bestimmten Hintergrundspeicher (n), bestehend aus
einem ARRAY mit (c) Elementen, welche ihrerseits aus einer beliebigen,
vom Benutzer definierten, Datenstruktur (vl) zusammengesetzt sind.
Der Inhalt der letzten Struktur kann durch BGMEMPOP, den der ältesten
(noch vorhandenen) Struktur durch BGMEMGETQ erreicht werden (siehe
dort).
Wird der Hintergrundspeicher ausschließlich mit BGMEMPUTQ oder
BGMEMPUSH gefüllt, ist die letzte Eintragung immer unter c=1 (siehe
oben) zu finden, ältere Eintragungen entsprechend unter c= 2, 3 usw.;
die älteste, noch vorhandene Eintragung ist unter c=BGMEMSS zu finden
Beispiel:

     1200   REM Initialisierung und Einlesen der Daten
     1210   REM    siehe BGMRMPUTR
     1220   REM nun Auslesen des 6. Eintrages
     1230   BGMEMGETR(0, 5, zeit$, temp1, temp2, schalter())
     1230   PRINT "Um "; zeit$; " Uhr, "
     1240   PRINT "war die Innentemperatur ";
     1230   PRINT temp1 AS 3F1;" Grad "
     1240   PRINT "bei Aussentemperatur von ";
     1250   PRINT temp2 AS 3F1;" Grad"
     1260   REM .. und jetzt noch Schalterarray behandeln ..
     1270   ...

Fehler:




                                 -69-
5.15.3 BGMEM Queue-Zugriff

5.15.3.1 BGMEMPUTQ
Syntaxdiagram:




Aufruf:     <zn> BGMEMPUTQ(n,vl)
            mit n = Nummer des Hintergrundspeichers (0..7)
                vl = Liste der Variablen

Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden,
entsprechen.

Funktion:
Mit BGMEMPUTQ wird ein Ringspeicher verwaltet, in welchen die
Strukturen hintereinander (in einer Queue = Warteschlange) abgelegt
werden. Die Speicherverwaltung veranlaßt, daß die 'älteste' Eintragung
immer am Kopf, die 'jüngste' Eintragung am Ende (Schwanz) der Schlange
ist. Bei Überlauf des Ringspeichers (zuviele Einträge) wird der
jeweils 'älteste' Eintrag entfernt.


Beispiel: siehe BGMRMGETQ

Fehler:




                                 -70-
5.15.3.2 BGMEMGETQ


Syntaxdiagramm:




Aufruf:     <zn> BGMEMGETQ(n, vl)
            mit n = Nummer des Hintergrundspeichers
                vl = Liste der Variablen

Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden,
entsprechen.

Funktion:

Mit BGMEMGETQ können die Daten aus dem Hintergrundspeicher wieder
zurückgelesen werden. Gelesen wird vom 'Kopf' des Ring-speichers, d.H.
die ältesten (zuerst eingegebenen) Daten, nach dem FIFO- (first in,
first out) Prinzip, soweit diese, nach einem Datenüberlauf noch
vorhanden sind. Sollen die zuletzt eingegeben (die jüngsten) Daten
gelesen werden, so kann dies mit BGMEMPOP oder BGMEMGETR(n,+1,vl)
geschehen; die vorletzten Daten mit BGMEMGETR(n,+2,vl) usw.

Mit BGMEMSS kann festgestellt werden, wieviele Strukturen eingetragen
sind, soweit diese nicht mit BGMEMPUTR abgelegt wurden.

Beispiel:

Fehler:




                                 -71-
5.15.4 BGMEM Stackzugriff

5.15.4.1 BGMEMPUSH
Syntaxdiagramm:




Aufruf:     <zn> BGMEMPUSH(n, vl)
            mit n = Nummer des Hintergrundspeichers (0..7)
                vl = Liste der Variablen.

Die Typen in VL müßen den Typen, wie sie mit BGMEMDIM definiert
wurden, entsprechen.

Funktion:

BGMEMPUSH entspricht in seiner Funktion völlig der Queue-Be-handlung
mit BGMEMPUTQ. Bei einem Überlauf des Stacks (Stapel-speichers) wird
ebenfalls der älteste Eintrag entfernt.

Beispiel:   siehe BGMEMPOP

Fehler:




                                 -72-
5.15.4.2 BGMEMPOP

Syntaxdiagramm:




Aufruf:     <zn> BGMEMPOP(n, vl)
            mit n = Nummer des Hintergrundspeichers
                vl = Liste der Variablen

Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden,
entsprechen.

Funktion:

Im Gegensatz zu BGMEMGETQ (siehe dort) liest diese Anweisung jeweils
die zuletzt abgelegte Struktur vom "Schwanz" der Schlange; dies
entspricht dem LIFO (last in - first out) Prinzip.
Soll eine ältere Struktur gelesen werden, so ist dies mit BGMEMR
möglich (siehe dort). Die älteste, noch vorhandene, Eintragung kann
jederzeit mit BGMEMGETQ erreicht werden.

Fehler:




                                 -73-
5.15.5 BGMEM Sonderfunktionen
5.15.5.1 BGMEMSS

Syntaxdiagramm:




Aufruf:     <zn> BGMEMSS(n)
            mit n = Nummer des Hintergrundspeichers (0..7)

Funktion:

Mit der Funktion BGMEMSS kann festgestellt werden, ob ein bestimmter
Hintergrundspeicher (n) definiert ist bzw. wieviele Datenstrukturen
bereits eingetragen sind.

Beispiel:
     100 REM Prüfen ob BGMEM definiert wurde
     110 FOR i = 1 TO 8
     120 c=BGMEMSS(i)
     130 IF c < 0 THEN 190
     140 ELSE PRINT c AS 05I;
     150 PRINT " Strukturen in BGMEM #";
     160 PRINT i AS 1I
     170 NEXT i
     180 END
     190 PRINT "BGMEM # ";
     200 PRINT i AS 1I;
     210 PRINT " nicht definiert"
     220 GOTO 170

Beispiel:
     1000   REM Es wird ein Hintergrundspeicher definiert
     1010   REM mit 100 Einträgen, jeweils Uhrzeit und Messdaten
     1015   REM
     1020        BGMEMDIM(1, 100, a$(8), a)
     1025   REM
     1030   REM nun werden die Daten gesammelt .... wenn
     1040   REM ein bestimmtes äußeres Ereignis eintritt
     1050   REM ... also nicht kontinuierlich ...
             :
     1100       BGMEMPUSH(1,zeit$, druck)
             :
    2000    REM Die gesammelten Daten sollen immer im
    2010    REM im 5er-Pack "versandt" werden ...
    2015    REM
    2020         cnt = BGMEMSS(1)
    2030         IF cnt>4 THEN GOSUB 3000
    2035    REM

                                  -74-
2040 REM Sonst geht es weiter im Programm
           :
     3000 REM Ausgabe von Daten
     3010       FOR i = 1 TO 5
     3020       BGMEMPOP(1, zeit$, druck)
     3030       PRINT ON(2) "Zeit: ";zeit$; " Druck: ";
     3040      PRINT ON(2) AS 3F1 druck;
     3050       PRINT ON(2) " bar"
     3060      NEXT i
     3070      RETURN


Fehler: keine




                                -75-
5.15.5.2 BGMEMCLEAR

Syntaxdiagramm:




Aufruf:     <zn> BGMEMCLEAR(n)
            mit n = Nummer des Hintergrundspeichers (0..7)


Funktion:
Diese Anweisung löscht den kompletten Inhalt eines bereits (mit
BGMEMDIM) definierten Hintergrundspeichers. Es ist zu beachten, daß
jedoch die definierte Strucktur des Hintergrundspeichers erhalten
bleibt!

Beispiel:


Fehler:




                                 -76-
5.15.5.3 BGMEMFRE

Syntaxdiagramm:




Aufruf:     <zn> BGMEMFRE(n)
            mit n = Nummer des Hintergrundspeichers (0..7)

Funktion:

Die Anweisung BGMEMFRE gibt einen bereits definierten Hinter-
grundspeicher wieder frei. Der vorher dafür belegte Speicher-platz
kann für einen neuen Hintergrundspeicher beliebigen Auf-baus verwendet
werden.

Beispiel:

Fehler:




                                 -77-
5.16 Logical Units (Serienschnittstellen)

5.16.1 LUMODE
Aufruf:     <zn> fcd = LUMODE(kanal, baud, "format")

            mit   kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU
                  kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit
                           CPUZ280 auf ECB-Systemen
                           Andere Konfigurationen bitte erfragen!
                    baud = Baudrate 300, 1200, 2400, 4800, 9600,
                           19200 und 38400

                  format = hier muß ein string (Text in "" ) ein-
                           gegeben werden:
                          1.   Anzahl der Bits: "7" oder "8"
                          2.   Parity: "O" (odd) "E" (even) "N" (none)
                          3.   Stopbits "1" oder "2"
                          4.   Handshake "X" = XON-XOFF-Protokoll
                                     "R" = RTS/CTS-Protokoll *)
                     fcd = Fehlercode
                          0    =   Alles in Ordnung
                          1    =   Kanal existiert nicht
                          2    =   Baudrate nicht unterstützt
                          3    =   Datenformat nicht unterstützt

Funktion:
Mit LUMODE kann die Baudrate, das Format und die Art des Handshakes
einer seriellen Schnittstelle verändert werden.

Beispiel:
Es soll an die zweite Schnittstelle ein Modem angeschlossen werden,
mit 2400 Baud, 8 Bit Daten, keine Parität und 1 Stopbit. Beide
Handshakearten sollen unterstützt werden:

     100    fcd = LUMODE(2,2400,"8N1XR")
     110    IF fcd=0 THEN PRINT "Kanal 2 angeschlossen"
     120    IF fcd=1 THEN PRINT "Kanal 2 existiert nicht"


*)   Es können "X" und "R" gleichzeitig aktiv sein, das RTS-
Signal zeigt zu jedem Zeitpunkt an, ob die Schnittstelle    empfangs-
bereit ist.

5.16.2 LUOPEN

Aufruf:    <zn> val = LUOPEN(kanal)

            mit   kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU
                  kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit
                           CPUZ280 auf ECB-Systemen
                           Andere Konfigurationen bitte erfragen!

                   val   = 0 alles in Ordnung

                                       -78-
= 1 Kanal ist nicht anzusprechen

Funktion:
Mit dieser Funktion kann der Zustand der DCD-Leitung abgefragt werden.

Beispiel:

            1000 IF LUOPEN(2) THEN PRINT ON(2) "Hallo wie geht's"


5.16.3 LUAVAIL

Aufruf:     <zn> val = LUAVAIL(kanal)

            mit   kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU
                  kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit
                           CPUZ280 auf ECB-Systemen
                           Andere Konfigurationen bitte erfragen!
                  val   = 0 Zeichen liegt vor
                  val   = 1 kein Zeichen
Funktion:
Mit LUAVAIL ist feststellbar ob an <kanal> ein Zeichen zur Verfügung
steht oder nicht. Dies ist besonders wichtig, wenn innerhalb einer
SEQuenz auf einen seriellen Kanal zugegriffen werden muß, time-out-
Zeiten aber nicht tolleriert werden können.

Beispiel:
            1000 WAIT FOR LUAVAIL(2)          ' Warte auf Zeichen
            1010 a$ = INCHAR(2)               ' ... dann einlesen
            1020 ....



5.17 Linkadapter (nur TSM-CPU)

Linkadapter sind sehr schnelle, serielle Schnittstellen. In MSR-BASIC
ist ein einfacher Treiber für die TSM-CPU installiert worden. Der
LINK-Anschluss ist über Kanal (LU)#3 erreichbar.
Die Daten können mit

                             INCHAR$(3)
                             bzw. INPUT ON(3)
eingelesen werden und mit

                             PRINT ON(3)

über den LINK-Anschluß ausgetauscht werden.




                                  -79-
5.18 BITBUS-Anschluß (nur TSM-CPU)

Um eine Kommunikation über den Feldbus BITBUS(R) zu ermöglichen wurde
in MSRBASIC für die TSM-Serie (mit Option BITBUS-Modul) ein BITBUS-
Treiber implementiert. Es ist zu beachten, daß bei Verwendung des
BITBUS-Moduls lediglich eine serielle Schnitt-stelle zur Verfügung
steht, das Modul der 2. und 3. Schnitt-stelle muß gegen ein BITBUS-
Modul ausgetauscht werden!

Unabhängig vom MSRBASIC-Interpreter sind mit diesem Treiber alle
Funktionen eines BITBUS-Rechners verfügbar,       außer  den   8044-
spezifischen und den TASK-Funktionen ( zur Begriffserläuterung siehe
entsprechenden BITBUS-Unterlagen ).


5.18.1 Allgemeines
MSRBASIC reserviert im Speicherbereich der TSM-CPU einen 256 Byte
großen Puffer, der über den BITBUS und von MSRBASIC aus beschrieben
und gelesen werden kann. Darüberhinaus können auch vordefinierte
Datensätze ausgetauscht werden.

Da auf den Puffer asynchron von beiden Seiten aus zugegriffen werden
kann, wird dringend empfohlen ein Byte des (internen) Speichers) als
Flag zur Kommunikation zu verwenden.

Der Pufferinhalt kann folgende vier Zustände einnehmen:
                0   =   leer (Inhalt ungültig)
                1   =   beschrieben(teilweise oder voll)
                2   =   beschrieben(angeforderte Daten)
                3   =   beschrieben(nicht entgegengenommen)

Es müßen natürlich nicht alle Zustände berücksichtigt werden, für
einen einseitigen Datentransfer genügt es Daten in den Puffer zu
schreiben und dann zu warten bis der Puffer wieder leer ist (Zustand
0 oder 1).
Sollten Parameter übergeben (Zustand 0 oder 1) werden und die
Gegenseite daraufhin Ergebnisse liefern, so liegt ein Daten-austausch
in beiden Richtungen vor. Es muß ein weiterer Zustand des Flags
genutzt werden, um Parameter von Ergebnissen zu unterscheiden (Zustand
0 oder 2).

5.18.2 Datenaustausch vom PC

Die Programmierung auf der PC-Seite bedarf einiger Kenntnisse über die
Struktur und die Arbeitsweise des BITBUS.

Die Struktur einer BITBUS-Nachricht und die Bedeutung seiner einzelnen
Felder ist in den Unterlagen zum BITBUS     (z.B. TSM - Handbuch für
Softwareentwickler) ausführlich beschrieben.




Der Vollständigkeit halber sei die Struktur des BITBUS-Header mit der
Bedeutung seiner Felder hier nocheinmal aufgezeigt:

                                    -80-
+)))))))0)))))))0)))))))))0)))))))0))))))))))))))0)))))))),
  * Länge * Flags * Adresse * Tasks * Befehl/Rückm.*            n Daten*
  .)))))))2)))))))2)))))))))2)))))))2))))))))))))))2))))))))-

In Zusammenhang mit MSRBASIC sind vor allem die RAC-Befehle:

      DOWNLOAD_MEM              = 09H     zum Datentransfer
      UPLOAD_MEM                = 08H
      READ_INTERNAL_MEM         = 0EH     zur FLAG-"Ablage"
      WRITE_INTERNAL_MEM        = 0DH

von Interesse.
Aufgabe des Programmierers ist es, in einer beliebigen Hoch-sprache
oder auf Assemblerebene entsprechende Nachrichtenfelder zu senden, zu
empfangen und entsprechend auszuwerten.


Beispiel:
Es sollen von einem PC aus 4 Zahlenwerte, als 16-Bit Integer-zahlen an
MSRBASIC übergeben werden. Die vier Werte sind 290 (0122H), 563
(0233H), 836 (0344H) und 17493 (4455H). Die Nachricht sieht demgemäß
wie folgt aus:
      ... 09 00 01 01 22 02 33 03 44 44 55
          ^ ^      ^     ^      ^    ^
          | |      |     |     |     Wert 4455
          | |      |     |     Wert 0344
          | |      |       Wert 0233
          | |      Wert 0122
          | Offset 0 (Ab Startadresse)
          RAC-Befehl 09H (DOWNLOAD_MEM)
nun FLAG für "beschrieben" = 1 setzen:

      ... 0D 00 01
            ^ ^ ^
           | | FLAG = 1
           | Offset = 0
            RAC-Befehl 0DH (WRITE_INTERNAL_MEM)


Sollen weitere Daten übergeben werden, muß zuerst das Zustands-FLAG
gelesen werden:

      ... 0E 00 ??
          ^ ^ ^
          | | Platzhalter für Antwort
          |   Offset = 0
          RAC-Befehl 0EH(READ_INTERNAL-RAM)

Die Antwort kann wie folgt aussehen:

      ... 00 00 00       ; OK - Daten übernommen, Puffer leer
      ... 00 00 01      ; Daten noch nicht übernommen (Puffer voll)
      ... 00 00 02      ; OK Daten übernommen - Ergebnisse vorhanden


                                        -81-
Ist das FLAG = 02 ( angeforderte Daten vorhanden ), oder man möchte
ganz allgemein den Puffer auslesen, so würde die ent-sprechende
Nachricht wie folgt aussehen:
     ... 08 00 00 ?? ?? ?? ?? ?? ?? ?? ??
         ^
         RAC-Befehl 08H (UPLOAD_MEM) von Offset=0

wobei die Fragezeichen "?" wiederum nur Platzhalter sind.
Das "Ergebnis" könnte dann wie folgt aussehen:

     ... 00 00 00 01 22 02 33 03 44 44 55

Achtung: BITBUS verwendet die HIGH-/LOW-Byte-Darstellung im
         Gegensatz zur Darstellung eines 16-Bit-Wertes in
         Z80/Z280-Programmen!




                                -82-
5.18.3 Datenaustausch aus MSRBASIC

Die Übermittlung und Auswertung von Daten von MSRBASIC aus läßt sich
erheblich einfacher gestalten als dies vom PC aus möglich ist, da hier
die entsprechenden Treiber bereits integriert sind. Es werden hier
Funktionen, das Zustands-FLAG und Daten zu be-arbeiten.

5.18.3.1 BITZFLAG

Aufruf:     <zn> PRINT BITZFLAG

Funktion:

Dieses Schlüsselwort ist eine Systemvariable, die das Zustands-FLAG
enthält. Man kann dieses auslesen und setzten.
Beispiel:

            1000 WAIT FOR BITZFLAG <> 0       ' Warten bis Änderung

            .... Daten übernehmen ...
            1199 BITZFLAG = 0               ' Puffer leer

5.18.3.2 BITRB (read byte)
Aufruf:     <zn>   var = BITRB(n)

Funktion:
Es wird ein Byte mit dem Offset n aus dem 256-Byte-Puffer in die
Variable var gelesen.
Beispiel:
            100    FOR i = 1 to 8             ' 8 Bytes lesen
            110    PRINT BITRB(i) AS 2H;
            120    PRINT " ";
            130    NEXT i
            140    PRINT




5.18.3.3 BITRW (read word)

Aufruf:     <zn> var = BITRW(n)

Funktion:

Es wird ein Wort (16 Bit) mit dem Offset n aus dem 256-Byte-Puffer in
die Bariable var gelesen.
Beispiel:

                   100   IF BITZFLAG = THEN 110 ELSE 100
                   110   FOR i = 1 to 8

                                    -83-
120   var = BITRW(i)
                  130   PRINT i,
                  140   PRINT var AS 4H;
                  150   NEXT i
                  160   ....

Achtung:     Bei einem Puffer von 256 Bytes sind natürlich nur
            128 Worte enthalten !

5.18.3.3 BITRH (read 24 Bit)

Aufruf:     <zn> var = BITRH(n)


Funktion:
Es werden 24-Bit (3 Byte) mit dem Offset n aus dem 256-Byte-Puffer in
die Variable var gelesen.

Beispiel:         siehe BITRB, BITRW



5.18.3.4 BITRS$ (string)

Aufruf:     <zn> var$ = BITRS$(n)
Funktion:
Es wird eine Zeichenkette (string) mit dem Offset n aus dem 256-Byte-
Puffer an die Stringvariable var$ übergeben. Der Offset n muß auf eine
Zeichenkette deuten, deren erstes Zeichen die Länge der Zeichenkette
zeigt, die folgenden Zeichen, entsprechend der eingetragen Länge, sind
Inhalt der Zeichenkette.
Beispiel:

             100 IF BITZFLAG = 2 THEN 120 ELSE 100
            110 REM    warten auf String
            120 var$ = BITRS$                 ' einlesen
             130 IF LEFT$(var$,6) = "MONTAG" THEN 1000
             140 ....
Achtung:   Da die Textlänge praktisch Alles zwischen 2 und 256
     Bytes sein kann, ist es empfehlenswert hier ohne
Offset zu arbeiten, wenn die Textlänge nicht immer
vorhersagbar ist.




5.18.3.5 BITWB (write byte)
Aufruf:     <zn> BITWB(n, var)


Funktion:


                                    -84-
Mit BITWB können bis zu 256 Bytes in den BITBUS-Puffer geschrieben
werden. Mit <n> wird ein evtl. Offset angegeben, <var> enthält das zu
übergebende Byte.
Beispiel:

            100   IF BITZF = 0 THEN 110 ELSE 100    ' bereit ?
            110   FOR i = 0 TO 256
            120   var = PEEK(0x8000+i)           ' Speicherdump
            130   BITWB(i,var)                         ' ab 8000H
            140   NEXT i
            150   BITZF = 1                            ' Puffer voll
            160   ...



5.18.3.6 BITWW (write word)
Aufruf:     <zn> BITWW(n,var)

Funktion:

Mit BITWW können bis zu 128 Worte in den BITBUS-Puffer geschrieben
werden. Mit <n> wird ein evtl. Offset angegeben, <var> enthält das zu
übergebende Byte.

Beispiel:
            100   IF BITZFLAG = 0 THEN 110 ELSE 100
            110   var = ADC(3)               ' ADC(3) einlesen
            120   BITWE(0, var)              ' Wert an BITBUS
            130   BITZFLAG = 1               ' Flag setzen
            140   ...



5.18.3.7 BITWH (write 24 bit)
Aufruf:     <zn> BITWH(n,var)

Funktion:

Mit BITWH können bis zu 84 24-Bit-Werte in den BITBUS-Puffer
geschrieben werden. Mit <n> wird ein evtl. Offset angegeben, <var>
enthält das zu übergebende Byte.

Beispiel:   siehe BITWB, BITWW



5.18.3.8 BITWS$ (write string)

Aufruf:     <zn> BITWS$(n,var$)

Funktion:

Mit dieser Funktion kann eine Zeichenkette (max 255 Zeichen lang) in
den BITBUS-Puffer geschrieben werden. <n> gibt einem möglichen Offset
in den Puffer an.

                                  -85-
Achtung:  Jede Zeichenkette wird automatisch mit einer
     vorangestellten Längenangabe in den Puffer über-
          tragen; bei Verwendung eines Offsets ist daher
          für jeden Eintrag ein Byte an der Puffergröße
          abzuziehen !


Beispiel:

Es sollen die Werte der AD-Wandler 1 und 2 jeweils mit Datum und
Uhrzeit übertragen werden.


            1000   FOR i = 1 TO 2
            1100   IF BITZFLAG = 0 THEN 1110 ELSE 1100
            1110   BITWS$(0, DATE$)      'Datum
            1120   BITWS$(1, TIME$)      'Uhrzeit
            1130   BITZFLAG = 1          ' Puffer voller Text
            1140   IF BITZFLAG = 0 THEN 1150 ELSE 1140
            1150   BITWW(0,ADC(i)        ' jetzt ADC-Wert ausgeben
            1160   BITZFLAG = 1          ' .. und markieren
            1170   NEXT i                ' 2. Paket absenden
            1180   IF BITZFLAG = 0 THEN 1190 ELSE 1180
            1190   PRINT "Daten übergeben"
Ein weiteres Beispiel:

            1000   IF BITZFLAG = 2 THEN 1100 ELSE 1000
            1010   REM     - Anforderung vom PC -
            1020   REM     0,n    lese ADC(n)
            1030   REM     1,n    lese DIN(n)
            1040   REM     2,n,v schreibe DAC(n) = v
            1050   REM     3,n,v setzte DOUT(n) = v
            1100   cmd = BITRB(0)          ' Befehl holen
            1110   IF cmd = 0 THEN GOTO 2000
            1120   IF cmd = 1 THEN GOTO 3000
            1130   IF cmd = 2 THEN GOTO 4000
            1140   IF cmd = 3 THEN GOTO 5000
            1150   var$ = "unbekannter Befehl"
            1160   BITWS$(0,var$)        ' Fehler melden
            1170   BITZFLAG = 1
            1180   GOTO 1000             ' neu Abfragen
            2000   kanal=BITRB(1)
            2010   BITWW(0,ADC,kanal) ' Daten übergeben
            2020   GOTO 6000
            3000   kanal = BITRB(1)
            3010   BITWB(0,DIN(kanal)
            3020   GOTO 6000
            4000   kanal = BITRB(1)
            4010   val = BITRW(1)        ' wg. Wort !
            4020   DAC(kanal) = val
            4030   GOTO 7000
            5000   kanal = BITRB(1)
            5010   val = BITRB(2)
            5020   DOUT(kanal) = val
            6000   BITZFLAG = 1          ' Daten übergeben
            6010   GOTO 1000
            7000   BITZFLAG = 0          ' Puffer leer
            7010   GOTO 1000


                                   -86-
5.19 Fahrtregler (POS) (nur TSM)

5.19.1 Allgemeines
Um einen Gleichstrommotor        anzusteuern   bedarf   es   im   allgemeinen
zweierlei:


     Es muß die Motorspannung für den Servoverstärker
     erzeugt werden
     Es muß die IST-Position erfaßt werden


Die Steuerspannung für den Motor kann über einen frei defi-nierbaren
D/A-Kanal eines TSM-2DA12 Moduls ausgegeben werden.
Die in MSRBASIC eingebundenn Treiber erlauben bis zu vier unabhängige
Antriebe, die auch paarweise, koordiniert ein Ziel anfahren können
(X/Y-Fahrt).

Der Verlauf einer Fahrt ist voreinstellbar, d.h. die max.
Geschwindigkeit und die Anfahr-/Bremsbeschleunigung kann durch den
Programmierer definiert werden.
Zu Positionserfassung stehen zwei Module mit unterschiedlicher Technik
zur Wahl:

                  TSM-4SSI   und
                  TSM-1INC

Beide Module können eine beliebige ID-Nummer haben, das Modul mit der
niedrigsten ID-Nummer wird mit n=1, das nächste mit n=2 usw. Das Modul
TSM-4SSI wird zusätzlich noch nach der Nummer-ierung seiner Stecker
festgelegt.
Um eine Position zu erfassen, Parameter festzulegen und eine Fahrt zu
starten sind folgende Funktionen in MSRBASIC implementiert worden:



5.19.2 POS
Aufruf:      <zn> var = POS(n)

Funktion:
In <var> wird die aktuelle Position eines angeschlossenen Gebers
zurückgegeben. Die Fehlermeldung <25> wird ausgegeben, wenn kein Geber
oder die Betriebsspannung (24V) nicht angeschlossen ist.




5.19.3 POSTYPE

Aufruf:      <zn> POSTYPE(n,typ)

                                    -87-
Funktion:

Es wird die Auflösung des angeschlossenen Gebers (nur       TSM-4SSI)
definiert. Hierbei sind folgende Typen <typ> zugelassen:
  644444444;44444444444447
  5   Typ      5    Geber        5
  5          5               5
  5   2048 5        2048/4096    5
  5   1024 5        1024/2048    5
  5     512 5       512/1024     5
  5     256 5       256/512      5
  5     128 5       128/256      5
  5      64 5       64/128       5
  5      32 5       32/64        5
  5      16 5       16/32        5
  944444444=44444444444448


5.19.4 POSSRN
Aufruf:     <zn> POSSRN(n)

Funktion:

Dieser Befehl setzt die aktuelle Position des Gebers <n> als
Nullpunkt. Alle folgenden Positionsangaben sind relativ zu dieser
Position zu betrachten.

5.19.5 FRDEF
Aufruf:     FRDEF(n, g, dac)

Funktion:
Dieser Aufruf reserviert für den Antrieb <n> (max.         1..4)   den
Positionsgeber <g> (1..NPOS) und den DAC-Ausgang <dac>.
Es wird vorausgesetzt, daß die entsprechenden Baugruppen zur Verfügung
stehen.
5.19.6 FRSETP

Aufruf:     <zn> FRSETP(n, mv, ma, mweg)
            mit n = Antriebsnummer
              mv = max. Steuerspannung(DAC)   1)
              ma = Beschleunigung             2)
            mweg = Antriebskonstante          3)

1) Steuerspannung im Bereich 0..10000 mV.
2) Zuwachs der Steuerspannung pro Intervall (8ms).
3) Positionsdifferenz in einem Intervall(8 ms), wenn die max.
   Steuerspannung von 10V anliegen würde.
5.19.7 FRSETKP

Aufruf:     <zn> FRSETKP(kp)
Funktion:


                                     -88-
Definition des kp-Regelparameters. Dieser Parameter     ist   für   die
Verstärkung des p-Anteiles des Reglers zuständig.

Typische Werte für kp sind 0...1.000. Höhere Werte sind zulässig aber
nicht sinnvoll.

5.19.8 FRSETKI(ki)

Aufruf:     <zn> FRSETKI(ki)
Funktion:

Definition   des  ki-Regelparameters.   Dieser   Parameter    ist   der
Integralbeiwert des I-Anteiles des Reglers.

Typische Werte für ki sind 0...1.0000.

5.19.9 FRLSFAHRT

Aufruf:     <zn> err = FRLSFAHRT(n,pos)

               mit n = Antriebsnummer (1..4)
                pos = Zielposition
Funktion:

Veranlassung einer Fahrt des Antriebes <n> auf die Position <pos>.
Diese Funktion gibt NULL zurück, wenn die Fahrt erfolgreich
initialisiert wurde. Die Fahrt erfolgt im Programmhintergrund, damit
können so Funktionen ausgerufen werden jedoch keine
weitere Fahrt für den aufgerufenen Antrieb bis dieser seine
Zielposition erreicht hat.

5.19.10 FRLDFAHRT
Aufruf:     <zn> err = FRLDFAHRT(xn, xpos, yn, ypos)

Veranlassung einer koordinierten Fahrt der Antriebe <xn> und <yn> auf
die Positionen <xpos> bzw. <ypos>.

Diese Funktion gibt NULL zurück, wenn die Fahrt erfolgreich
initialisiert wurde. Die Fahrt erfolgt im Programmhintergrund, damit
können so Funktionen ausgerufen werden jedoch keine
weiteren Fahrten für die aufgerufenen Antriebe bis diese ihre
Zielposition erreicht haben.



5.19.11 FRSTAT

Aufruf:     <zn> stat = FRSTAT(n)

Funktion:

Diese Funktion gibt den Status des Antriebes <n> zurück. Dies ist die
einige Möglichkeit den Fahrzustand festzustellen in welchem sich ein

                                    -89-
Antrieb gerade befindet.


Beispiel:
     100    stat = FRSTAT(1)
     110    PRINT "Antrieb ";
     120    IF stat = 0 THEN PRINT   "ruhend"
     130    IF stat = 1 THEN PRINT   "fährt an"
     140    IF stat = 2 THEN PRINT   "fährt"
     150    IF stat = 3 THEN PRINT   "bremst"
     160    IF stat = 4 THEN PRINT   "schleicht zum Ziel"
     170    IF stat >=5 THEN PRINT   "angehalten FEHLER!"

WEnn der Positionierfehler zu groß ist, wird <stat> >= 5
zurückgegeben. Erst die nächste Abfrage liefert NULL für Antrieb
"ruhend".
5.19.12 FRERROR

Aufruf:     <zn> perr = FRERROR(n)

Funktion:
Diese Funktion gibt den Positionsfehler zurück, der beim Bremseintritt
eingetreten ist. Es wird dabei vorausgesetzt, daß die Funktion
FRLSFAHRT oder FRLDFAHRT aufgerufen wurde und die Strecke erfolgreich,
ohne Abbruch gefahren wurde.

Diese Funktion ist dafür gedacht, den Parameter <mweg> in der Funktion
FRSETP zu optimieren. Dazu eignet sich folgende Vorgehensweise:

1. mit FRSETKI und FRSETKP die dazugehörigen Parameter auf NULL setzen
um diese Einflüße möglichst niedrig zu halten.

2. Einen Näherungswert von <mweg> setzen.
3. Den Antrieb laufen lassen, falls Fehlerfrei mit FRSTAT testen ob
ein Positionsfehler aufgetreten ist sonst <mweg> korrigieren bis der
kleinste Positionsfehler ermittelt wurde.




                                 -90-
6. Ein-/Ausgabe-Sprachmittel

6.1 Übersicht
Ein großer Vorteil von MSRBASIC ist seine Fähigkeit, auch im
Multitask-Betrieb unmittelbare Kommandoeingaben zu verarbeiten.
Die im folgenden beschriebenen MSR-Features verbessern diesen Ansatz
ganz wesentlich durch

     -    Fenstertechnik zur automatischen Trennung der Kommando-
          Ein/Ausgabe-Vorgänge       von    programmgesteuerten
          Bildschirmzugriffen (Prozeßdarstellung, Protokollierung
          usw.).

     -    Terminal-unabhängige Cursor-Positionierung im Rahmen der
          PRINT-Anweiung.
     -    Schneller Zugriff auf in Dateien abgelegte Bildschirmmasken

     -    Beschleunigung der   Kommando-Bedienung   auch   bei   hoher
          Echtzeitbelastung.

     -    Einfache Gestaltung von Steuerungs-Übersichtsbildern durch
          SEQLIST-Programmanweisung
     -    TRACE-Anweisungen bis in die TASKs und SEQuenzen hinein.




                                -91-
6.1.1 Fenstertechnik

Die eingebundene Fenstertechnik erleichtert im hohen Maß die
Implementierung     von    Bildschirm-basierenden     Bedien-  und
Anzeigefunktionen mit MSRBASIC, wobei insbesondere die residenten
Echtzeiteingriffmöglichkeiten von MSRBASIC unterstützt werden.

Der Bildschirm wird hierbei in ein oberes und ein unteres Fenster
aufgeteilt.
Das obere Fenster (Anwenderfenster) steht dem Programmierer für die
Ausgabe mit PRINT-Anweisungen zur Verfügung. Hier lassen sich in der
Prozeßleittechnik übliche Darstellungsformen wie z.B. Balkendiagramme
oder Trendkurven abbilden. Die Darstell-ungsmöglichkeiten sind
natürlich abhängig von den verwendeten Ausgabemedien. (Vollgrafik,
Blockgrafik, nur Text usw.)
Das untere Fenster (Kommandofenster) erlaubt Zugriffe auf den
MSRBASIC-Kommandointerpreter. Die Ausgabe innerhalb dieses Fensters
wird aktiviert bei:

     -   MSRBASIC-Kommandos (z.B. LIST, SEQLIST etc.)
     -   direkten Anweisungen (z.B. PRINT Y, W=50 etc.)
     -   Fehlermeldungen
     -   TRACE-Ausgaben

Die   verwendete  Fenstertechnik   stellt   softwaretechnisch einen
Ausgabefilter dar, der bei jeder Ausgabeanforderung des MSR-BASIC-
Interpreters den momentanen, internen Status auswertet, um das
aktuelle Zeichen in das richtige Fenster zu positionieren.
Diese   Methode   garantiert   eine   absolute   Unabhängigkeit   der
Anwenderprogrammierung von der Fensterverwaltung (Transparenz).




                                 -92-
6.1.2 Fenster-Programmierung

Die Fenstertechnik wird aktiviert und deaktiviert über die MSRBASIC
Systemvariable WINDOW.
6.1.2.1 Fenster einschalten

Aufruf:    <zn> WINDOW = NWIN <cr>
           mit NWIN = Anzahl der Zeilen im oberen Fenster (1..23)
Wirkung:   - Bildschirm löschen und
           - Fensterfunktion aktivieren.

6.1.2.2 Fenster ausschalten

Aufruf:    <zn> WINDOW = 0
Wirkung:   - Bildschirm löschen und
           - Fensterfunktion ausschalten

6.1.2.3 Cursor positionieren

Aufruf:    <zn> PRINT [<zeile>,<spalte>] <Zeichen>
Wirkung:   - Cursor wird auf Position <zeile>,<spalte> gesetzt
           - <Zeichen> wird an dieser Position ausgegeben
           - Cursor rückt auf nächste Position vor

6.1.2.4 Masken-Dateien ausgeben
Aufruf:    OPEN <maskenname,<log.Einheit>,1
           COMMAND (Log.Einheit)=1
           CLOSE <log.Einheit>

Wirkung:   - Die Datei <maskenname> wird auf den
             Bildschirm ausgegeben



6.1.2.5 Abfragen des oberen Fensters

Aufruf:    PRINT WINDOW <cr>

Wirkung:   - Es wird die Anzahl der benutzbaren
             Zeilen angegeben.


6.1.3 Beispiel zur Fenstertechnik

Das Programm WINDEM.BAS ist als einfachstes Nicht-Echtzeit-Beispiel
konzipiert.
Zunächst wird eine einfache Bildschirmmaske eingelesen (Zeilen
110..130). Nach einer kurzen Wartezeit (Zeilen 135..136) wird der
Bildschirm geteilt (Zeile 140). In der Folge wird gezeigt, wie
programmgesteuerte Ausgaben automatisch in das obere Fenster gelangen,
während die TRACE-Anzeige in das untere Fenster gelenkt wird.

                                  -93-
100    REM *** WINDEM.BAS ***
     110      CLS
     120      OPEN "WDLIS.BAS",10,1
     130      IF BIT(7,STATUS(10))=1 THEN COMMAND(10)=1
     140      CLOSE 10
     150      FOR I=1 to 1000
     160      NEXT I
     170      WINDOW = 8
     180      TRACE
     190      PRINT [0, 10] " MSR-Zweifenstertechnik "
     200      FOR I=1 TO 20
     210         PRINT CHR$(I+64);
     220      NEXT I
     230      NOTRACE
     240      STOP

Am Bildschirm ergibt sich folgendes Bild:

               +----------------------------------------------+
Programm-   1 !       MSR-Zweifenstertechnik                 !
Fenster        ! ABCDEFGH                                         !
----------> 8 !                                              !
             9 !                                                      !
Kommando-      ! 210     PRINT CHR$(I+64);                        !
Fenster        ! 220 NEXT I                                  !
               ! 210     PRINT CHR$(I+64);                   !
               ! 220 NEXT I                                  !
               ! ..............                              !
            23 !                                                  !
               +----------------------------------------------+




                                 -94-
6.2 Ein- / Ausgabe-Anweisungen

6.2.1 INPUT
Syntaxdiagramm:




Aufruf:   <zn> IN{PUT} {ON <kanalnummer>} ..
     <variable>{,<variable>...}

Funktion:

Die INPUT-Anweisung ermöglicht        das   programmgesteuerte   Einlesen
alphanumerischer Daten von
            - der Konsole (Kanal 0)

            - einem seriellen E/A-Kanal (INPUT ON (1..9))

Bei der Ausführung der INPUT-Anweisung wird grundsätzlich auf den
Eingabekanal 0 (Konsole) ein Fragezeichen ("?") ausgegeben und die
Benutzereingabe geechot. Dies setzt voraus, daß ein Konsolenkanal
installiert ist.
Beim Einlesen von eimem als nicht interaktiv installierten Kanal wird
das Echo unterdrückt. Im TRACE-Modus werden allerdings die übersandten
Zeichen zur Kontrolle auf der Bedienerkonsole ausgegeben.
Sofern mehrere numerische Daten eingelesen werden, müssen sie durch
Komma (",") oder Leerzeichen (" ") getrennt werden.

Beim Einlesen einer Stringvariablen werden führende Leerzeichen
verworfen und nur das Komma (",") als Trennzeichen gewertet.
Die INPUT-Anweisung ist grundsätzlich durch TIMEOUT gesichert, d.h.
wird eine Eingabe nicht innerhalb 20s abgeschlossen, gilt die Eingabe
als fehlerhaft. Das folgende Beispiel zeigt eine (hardware-mäßige)
Überprüfung der Schnittstelle:
     100    INPUT ON(n) A$
     110    IF BIT(pp,n) THEN ...

wobei die Portnummer (pp) der benutzten Schnittstelle und das infrage
kommende Statusbit (n) hardware-abhängig sind.

Die Eingabe und damit das Programm kann unabhängig von der Einlese-
Einheit von der Kommandokonsole aus mit CNTRL-C abgebrochen werden.

Beispiel:

     INPUT A,B A$

                                    -95-
? 1,2,ENDE
     >
     PRINT A,B,A$
     1.00000E 00 2.00000E 00 ENDE
     >


Hinweise:

Im Echtzeitbetrieb (Multitasking) ist die Benutzung der INPUT-
Anweisung mit Vorsicht zu behandeln; zwar kann sie entgegen den
sonstigen Regeln von höherprioren TASKs unterbrochen werden, es darf
aber im unterbrechenden Programm keine neue INPUT-Anweisung vorhanden
sein.

Wenn derartige Konkurrenzfälle nicht auszuschliessen sind,
empfiehlt es sich, die INPUT-Anweisung nur im Rahmenprogramm zu
verwenden und Einlesevorgänge in Echtzeit-Rechenprozessen über die
INCHAR$-Funktion zu formulieren (s.d.).

Fehler:
08   Fehlerhafte Variable in Einleseliste
41   Mehr als eine INPUT-Anweisung aktiv
58   Lesen einer zum Schreiben (Write-only) eröffneter Datei




                                -96-
6.2.2 PRINT

Syntaxdiagramm:




Aufruf:     <zn> PRINT|? {ON(<kanalnummer>} {<Druckoperand>}
            Der Druckoperand wird wie folgt aufgerufen:

            <numerischer Ausdruck> AS <format>
            für die formatierte Ausgabe numerischer Ausdrücke
            und/oder
                 "<textausdruck>"
            und/oder
                 [zeile,spalte]
            zur Cursorpositionierung auf der Konsole

Funktion:
Die   PRINT-Anweisung   ermöglicht   die   Ausgabe   von   beliebigen
Zeichenfolgen und Zahlenwerten auf den Bildschirm    oder einen frei
wählbaren Ein-/Ausgabe-Kanal (unter Benutzung des "ON(n)"-Zweiges).
Die Tabellierung kann mit Hilfe eines oder mehrerer Kommas (",")
zwischen den auszugebenden Daten vorgenommen werden. Die Formatierung
von Zahlenwerten erfolgt über die "AS"-Angabe.

Die technischen Voraussetzungen sind konfigurationsabhängig!
6.2.2.1 Tabellierung

Bei der voreingestellten Tabellierung wird eine Ausgabezeile in 5
Felder mit einer Länge von 13 Zeichen eingestellt. Die Verwendung des
Kommas (",") als Trennungszeichen bewirkt ein Vorrücken der
Druckposition zum Beginn des nächsten 13er Feldes. Soll dies
verhindert werden, muß der Strichpunkt (";") als Trennungszeichen
verwendet werden.

Wenn der automatische Zeilenvorschub bei Beendigung der PRINT-
Anweisung unterbunden werden soll, muß als letztes Zeichen ein Komma
oder Strichpunkt gesetzt werden.

6.2.2.2 Cursor-Positionierung
Die Cursorpositionierung ist Hardware- und Konfigurationsabhängig. Der
entsprechende Ausgangstreiber muß eine Cursorpositionierung erlauben
(siehe Kapitel 10).
Nach jedem Strichpunkt (";") kann eine erneute Cursor-Positionierung
vorgenommen werden.

6.2.2.3 Formatierung

                                 -97-
Alle numerischen Werte werden, falls keine Formatierung angegeben ist,
im Festkomma-Format (Grundeinstellung 12F4, siehe unten ) wie folgt
dargestellt:
> a = 11111111
> print a
 1.1111E 07              Genauigkeit 5-stellig
> a=12345678
> print a
 1.2346E 07              letzte Stelle wird aufgerundet !


Werden andere Ausgabeformate verlangt kann mit der "AS"-Anweisung wie
folgt formatiert werden:

1.   E-Format (Gleitkomma)
     Das Format hat die Form fEk, wobei f die Feldlänge (Gesamtlänge
     incl. Vorzeichen und Punkt) und k die Nachkommastellen der
     Mantisse angibt.

2.   F-Format (Festkomma)
     Das F-Format hat die Form fFk wobei f die Feldlänge
     (Gesamtlänge incl. Vorzeichen und Punkt) und k die
     Nachkommastellen festlegt.
3.   I-Format (Ganzzahl)
     Das I-Format hat die Form fI, wobei f die Feldlänge
(Gesamtlänge) festlegt.

4.   H-Format (Hexadezimal)
     Das H-Format hat die Form fH, wobei f die Feldlänge
     (Gesamtlänge) festlegt.

In allen Fällen werden die Zahlen auf das entsprechende Ausgabeformat
gerundet (nicht abgschnitten!). Sofern der auszugebende Zahlenwert im
Rahmen des gewünschten Formates nicht darstellbar ist, wird die
gesamte   Feldlänge   mit   dem   "*"-   Zeichen   beschrieben.   Die
Feldlängenangabe f darf maximal 2-stellig sein.
Soll der numerische Wert mit führenden Nullen (z.B. 0055) dargestellt
werden, muß vor die Feldlängenangabe eine "0" angegeben werden; die
Feldlängengröße ist dabei automatisch auf "9" begrenzt, da, wie oben
erwähnt, max. 2 Stellen angegeben werden dürfen!
Beispiele:
a)    10   A=7.78
      20   PRINT A AS 5I, A AS 10F3, A AS 12E2,A,A AS 4F3
      30   STOP

      Ergebnis:

      8          7.780      7.78E 00      7.7800E 00        ****
b)    10     PRINT ON(0)    "PRINTST"
      20   REM
      30     a=1, b=-1
     100     PRINT ON(0)    "Integer Format"
     110     PRINT ON(0)    a AS 6I, b AS 6I
     120     PRINT ON(0)    a AS 06I, b AS 06I
     200     PRINT ON(0)    "Festkomma-Format"
     210     PRINT ON(0)    a AS 9F4, b AS 9F4
     220     PRINT ON(0)    a AS 09F4, b AS 09F4

                                   -98-
300      PRINT ON(0) "Gleitkomma-Format"
     310      PRINT ON(0) a AS 9E2, b AS 9E2
     320      PRINT ON(0) a AS 09E2, b AS 09E2
     999    STOP
Ergebnis:

     PRINTST
     Integer-Format
          1                 -1
     000001            -00001

     Festkomma-Format
        1.0000        -1.0000
     0001.0000    -001.0000

     Gleitkomma-Format
      1.00E 00    -1.00E 00
     01.00E 00    -1.00E 00


Fehler:
08   Syntaktisch falsche Form
59   Schreiben auf eine zum Lesen (Read-only) eröffnete Datei




                                 -99-
6.3 Schnittstellenfunktionen

Unter "Schnittstellen" sind alle hardwaremäßig eingebundenen Kanäle zu
verstehen auf welche mit dem ON(n)-Zweig in Anweisungen wie PRINT,
LIST usw. zugegriffen werden kann.
6.3.1 EOF(n)

Die EOF-Funktion hat den Wert 0, wenn beim letzten Zugriff auf den
seriellen Einlese-Kanal n vom Betriebssystem keine EOF-Bedingung
zurückgemeldet wurde bzw. wenn das nächste Einlesezeichen kein CNTRL-
Z (1AH) ist. Eine EOF-Bedingung kann damit als "keine weitere Eingabe
vorhanden" interpretiert werden und ist in dieser Form (unter CP/M)
werksseitig für alle Kanäle implementiert.

Beispiel:   " Auf Zeicheneingabe warten"
            1000 WAIT MAX 10 FOR EOF(0)=0

6.3.2 INCHAR$(n)
Die INCHAR$-Funktion liest, falls vorhanden, ein Zeichen von der durch
durch die Kanalnummer (n) bestimmten logischen Einheit ein. Falls kein
Zeichen anliegt, wird ein NULL-String übergeben. Man beachte, daß
INCHAR$ kein Echo auf den Eingabekanal (Konsole) auslöst.

Die INCHAR$-Funktion ist besonders dann vorteilhaft, wenn man
Falscheingaben des Bedieners sofort und gezielt abfangen will oder
falls Probleme mit Konkurrenzanweisungen im Echtzeitbetrieb auftreten
können (siehe Hinweis zu 6.2.1 INPUT).

Beispiel:
            100    REM *** Test INCHAR$(n) ***
            110      PRINT "Bitte beliebige Taste drücken "
            120      x$ = INCHAR$(0)
            130      PRINT " es war Taste ";x$
            140      GOTO 110




                                  -100-
6.3.3 STATUS(n)

Die Status-Funktion liefert in Form eines Zahlenwertes den momentanen
Zustand der logischen Einheit (n). Dieser Zahlenwert wird vom
Betriebssystem in Form eines 16-Bit-Wertes übergeben.
Derzeit sind nur die unteren 8 Bit mit folgender Bedeutung belegt:

Bit   7:   =1,   wenn LU geöffnet ist
Bit   6:   =1,   wenn LU als write-only-Kanal konfiguriert ist
Bit   5:   =1,   wenn EOF-Bedingung aufgetreten ist (=EOF(LU))
Bit   4:   =     reserviert
Bit   3:   =1,   nur nach INPUT wenn TIMEOUT aufgetreten ist
Bit   2:   =     reserviert
Bit   1:   =1,   wenn Zeichen ausgegeben werden kann
Bit   0:   =1,   wenn ein Zeichen zum Einlesen bereit ist
Beispiel: " Warten auf Eingabe mit TIMEOUT

           1000 WAIT MAX 10 FOR BIT

6.3.4 COMMAND(n)

Die COMMAND-Funktion stellt das Gegenstück zur STATUS-Funktion dar.
Sie übergibt an das Betriebssystem einen vom Benutzer vorgegebenen 16-
Bit-Wert, der als Steuerwort interpretiert wird.




                                  -101-
7. Standardsprachmittel

7.1 Programmfluß-Steuerung
7.1.1 FOR

Syntaxdiagramm:




Aufruf:     <zn> F{OR} <lv> = <stw> TO <ew> {STEP <sw>}
            <zn> .... <programmteil>
            <zn> NEXT <lv>

Funktion:

Die FOR-Anweisung erlaubt den Aufbau von Laufschleifen. Als
Laufvariable (lv) darf nur eine skalare numerische Variable verwendet
werden, währen Startwert (stw), Endwert (ew) und Schrittweite (sw)
durch arithmetische Ausdrücke vorgegeben werden können (alle Werte
erlaubt). Falls eine explizite Schrittweitenangabe fehlt, wird als
Schrittweite "1" angenommen.

Hinweise:
Zu beachten ist, daß die Laufschleife wenigstens einmal durchlaufen
wird, da die Abbruchbedingung erst in der NEXT-Anweisung geprüft wird.
Weiterhin sollte man nicht aus einer Laufschleife herausspringen,
sondern bei Erfüllung einer zweiten Abbruchbedingung die Laufvariable
auf den Endwert setzen (um evtl. Schwierigkeiten mit dem Stack für
Laufvariable zu vermeiden).

Es können maximal 10 Laufvariable ineinander verschachtelt werden.
Die Verwendung von FOR/NEXT-Schleifen in TASKs und SEQuenzen ist
möglich, allerdings müssen unterschiedliche Laufvariable verwendet
werden (Sonst Fehlermeldung 20).




                                -102-
Beispiel:

     100    REM *** Einfache Warteschleife
     110      FOR I = 1 TO 1000
     120    REM auch nichts tun kostet Zeit
     130      NEXT I
     140    REM *** Verschachtelte Schleife (kleines 1x1)
     150      FOR I = 1 TO 10
     160           FOR J = 1 TO 10
     170               PRINT I*J AS 4I;
     180           NEXT J
     190      NEXT I
     200      STOP



Fehler:
16   "="-Zeichen fehlt
17   "TO" oder "STEP" fehlt
18   Mehr als 10 verschachtelte Laufschleifen
20   Laufvariable bereits in (äußerer) Schleife (oder in anderer
     TASK, SEQuenz, Hintergrundprogramm) verwendet
21   Laufvariable ist Vektor oder String




                                 -103-
7.1.2 NEXT

Syntaxdiagramm:




Aufruf:      ... <FOR-Anweisung>
             <zn> NEXT{|NX} <lv>

Funktion:

Die NEXT-Anweisung bestimmt das Ende einer Laufschleife. Hierzu wird
grundsätzlich die Laufvariable (lv) um die Schrittweite erhöht und die
Schleife abgebrochen, wenn der neue Wert der Laufvariablen über dem
Grenzwert liegt. D.h., daß nach Beendigung der Schleife die
Laufvariable größer als der Endwert ist.


Beispiel:
     Siehe FOR-Anweisung

Fehler:
19   NEXT wird vor FOR bearbeitet
20   Laufvariable in FOR und NEXT nicht identisch




                                   -104-
7.1.3 GOSUB

Syntaxdiagramm:




Aufruf:     <zn> GOSUB {|GS} <zn>

Funktion:
Mit der GOSUB-Anweisung werden BASIC-Unterprogramme aufgerufen. Aus
dem Unterprogramm muß mit einer RETURN-Anweisung in das aufrufende
Programm zurückgekehrt werden. Die Verschachtelungstiefe ist beliebig.

Beispiel:
     100    REM *** Aufruf von Unterprogrammen ***
     110      PRINT "** im Laufenden Programm"
     120      GOSUB 200
     130      PRINT "** hier geht's weiter"
     140      STOP
     200    REM *** Unterprogramm
     210      PRINT "** im Unterprogramm"
     220      RETURN
Fehler:
05   Unterprogramm mit gewünschter Zeilennummer existiert nicht




                                    -105-
7.1.4 RETURN

Syntaxdiagramm:




Aufruf:     <zn>   RETURN {|RT}

Funktion:
Die RETURN-Anweisung muß am Ende eines über GOSUB aufgerufenen
Unterprogrammes, einer TASK oder einer SEQuenz stehen. Bei der
Ausführung wird dann das übergeordnete Programm nach der aufrufenden
GOSUB-Anweisung fortgesetzt.
Beispiel:
     :
     1000 GOSUB 2000
     :
     2000 REM *** Ein ständig wiederkehrender Programmteil ***
     2010   LET TA=TA-1
     2020   IF TA>0 THEN RETURN
     2030   LET TA=TO
     2040 RETURN

Hinweis:

Bei Beendigung einer SEQuenz durch RETURN wird automatisch die
Startzeile der SEQuenz (siehe hierzu DEFINE) als nächste auszuführende
Anweisung im SEQuenz-Steuerblock festgelegt , bevor die        SEQuenz
stillgelegt (suspendiert) wird.




                                  -106-
7.1.5 GOTO

Syntaxdiagramm:




Aufruf:      <zn> GOTO {|GO} <zn>

Funktion:
Mit der GOTO-Anweisung kann eine unbedingte Programmverzweigung
vorgenommen werden. Das Programm wird an der gewünschten Zeilennummer
(zn) fortgesetzt. Es kann nicht mit RETURN zurückgekehrt werden.
Beispiel:
       10    REM *** Initialisierung bei Kaltstart ***
       20       IF myflg <> 0 THEN GOTO 100
       30    REM hierher wenn myflg = 0 denn ...
       40    REM ... nur beim Kaltstart sind ALLE Variablen = 0
       50    count = 1000, xyz = 12345
       :
       :
      100    REM Hier geht's erst richtig los
       :

     1110    IF count = 12 THEN GOTO 2000 ELSE GOTO 3000
       :

Fehler:
05     Programmzeile mit der gewünschten Nummer existiert nicht




                                    -107-
7.1.6 IF

Syntaxdiagramm:




Aufruf:     <zn> IF <con> THEN {<anw>|<zn>} {ELSE{<anw>|<zn>}}

Funktion:
Die IF-Anweisung erlaubt die Formulierung von bedingten Aktionen.
Unter Bedingung (con) ist folgende Anordnung zu verstehen:

            a) numerischer Ausdruck
            b) Ausdruck1 Relationsoperator Ausdruck2
Falls der Wert eines numerischen Ausdruckes Null ist, gilt die
Bedingung als nicht erfüllt, sonst als erfüllt.
Als Relationsoperatoren für String- und Zahlenvergleiche sind zuläßig:
          >       größer
          <       kleiner
     =>, >=       größer oder gleich
     =<, <=       kleiner oder gleich
     <>, ><       ungleich
          =       gleich
Falls die Bedingung erfüllt ist, wird der THEN-Teil ausgeführt. Falls
die Bedingung nicht erfüllt ist, wird die      nächste Anweisung im
Programmablauf ausgeführt oder (falls vorhanden) die im ELSE-Zweig
vorgesehene Aktion.




                                 -108-
Beispiel:

a)   1000 IF A<>0 THEN 2000
          entspricht
     1000 IF A THEN 2000

b)   1010 IF A<-B THEN 2020 ELSE A=-100

c)   1020 IF A$<>CHR$(12)+B$ THEN PRINT "Ungleich"
d)   1030 IF A>B THEN IF A>C THEN 3000



Hinweis:

Beim Vergleichen zweier Strings (Zeichenketten) bedeutet die "größer"-
Aussage, daß der ASCII-Code als Hexzahl betrachtet größer ist. Ist der
kleiner   String    identisch   mit   dem   linken   Teilstring    des
Vergleichsobjektes, dann gilt der längere String als größer.

Es gilt z.B.:
             "Z" > "A"
             "b" > "Cxxx"
          "ABCD" < "ABCDEFG"

Fehler:

08   Inkompatible Datentypen in den Vergleichsausdrücken
14   Unerlaubte Relation im Bedingungsausdruck




                                -109-
7.1.7 STOP

Syntaxdiagramm:




Aufruf:      <zn> ST{OP}

Funktion:
Die STOP-Anweisung legt Abbruchstellen innerhalb eines Programmes
fest. Bei der Ausführung kehrt der Interpreter grundsätzlich in die
Kommandobetriebsart zurück, auch wenn der Abruch innerhalb eines
BASIC-Unterprogrammes erfolgte.

Beispiel:
     1000 IF A=0 THEN STOP


Fehler:
     (keine)




                               -110-
7.1.8 END

Syntaxdiagramm:




Aufruf:     <zn> END

Funktion:
Die END-Anweisung stellt die letzte Anweisung eines BASIC-Programmes
das. Sie ist nicht notwendig, wenn das Programm über STOP oder eine
RETURN-Anweisung beendet wird oder mit GOTO <start> in einer endlosen
Schleife läuft.
Beispiel:
     :
     :
     9999 END

Fehler:
03   Hinter END existiert eine weitere Programmzeile




                                -111-
7.2 Rechen- /Speicheranweisungen

7.2.1 DIM
Syntaxdiagramm:




Aufruf:     <zn> DIM <name> (<a1>{<a2>) {,...}
Funktion:

Mit der DIM-Anweisung können ein- oder zweidimensionale Felder vom
Datentyp "REAL" oder "STRING" angelegt werden. Sie erhalten bei der
Festlegung einen Namen <name> mit welchem sie angesprochen werden
können. Bei Vektoren legt der Wert von "Ausdruck1" (a1) die Länge
(Anzahl der Elemente) fest. Die Indizierung geht dabei von 0 bis zur
angegebenen    Dimensionszahl.    Eindimensionale    Felder    werden
grundsätzlich als Spaltenvektoren angelegt, was bei der Anwendung des
Matrix-Vektor-Kalküls (siehe MAT) zum Tragen kommt.
Bei Matrizen legt der Wert von "Ausdruck1" (a1) die Anzahl der Zeilen
fest, während sich die Anzahl der Spalten aus dem Wert von "Ausdruck2"
(a2) ergibt. Auch hier beginnt die Indizierung bei 0, wobei allerdings
im Rahmen der MAT-Anweisung nur die Teilmatrix ab Element 1,1, benutzt
wird. BASIC legt die Felder zeilenweise ab, d.h. zuerst wird die
"nullte" Zeile, dann die erste usf. abgelegt.

Bei der erstmaligen Anlage von Feldern werden alle Elemente gelöscht
( Wert 0 bei REAL-, Leertext bei STRING-Feldern).
Es ist zu Beachten, daß der Feldinhalt auch bei einem Neustart
gelöscht wird. Ist dies unerwünscht müssen entsprechende Maßnamen
getroffen werden (Beispiele in Kapitel 2.2.12).
Sofern der verfügbare Arbeitsspeicher keine physikalische Begrenzung
darstellt, beträgt die maximale logische Dimension von:

     numerischen Vektoren          8190
     numerischen Matrizen          126 mal 126
     Stringfelder                       255 Elemente

Mit der DIM-Anweisung können bereits vorhandene Felder redimensioniert
werden. Hierbei darf das redimensionierte Feld jedoch     nicht größer
werden, als bei der erstmaligen Anlage angegeben wurde. Die Umwandlung
von Vektoren in Matrizen und umgekehrt ist möglich. Bei der
Redimensionierung werden die Feldelemente nicht gelöscht.
Beispiel:

     1000 DIM X1(10), A(N,N),Xa$(2,10)
     1010 INPUT N
     1020 DIM X1(N)


                                 -112-
Fehler:

13   Dimension zu groß
33   Redimensionierung nicht möglich, Originalfeld zu klein




                               -113-
7.2.2 LET

Syntaxdiagramm:




Aufruf:     <zn> {LET} {<var>|<af>} = <ad> {,|:...}

Funktion:
Die LET-Anweisung erlaubt die Formulierung von Wertzuweisungen und
stellt damit die zentrale Anweisung dar.

Die Ergebnisse von numerischen oder String-Operationen (ad) können
Variablen (var) des gleichen Typs zugewiesen werden. Numerische Werte
können darüberhinaus auch an spezielle Ausgabefunktionen (af) wie
     CNT        Zähler
     DAC        Analogausgabe
     DOUT       Binärausgabe
     PUT        Byteausgabe
     COMMAND    Komandowortausgabe (an seriellen Kanal)
     TUP/TDOWN Zeitgeber
     TIME$      Tageszeitgeber
     DATE$      Datumsgeber

übergeben werden.




                                 -114-
Beispiel:

     1000   A_min = B_max, C=A+B^(X+LN(X2*X3)), A$="AB"
     1020   FF$=CHR$(12) : B$=FF$+"ABCDE"+CHR$(27)
     1030   LET DAC(N)=K*Y1, DOUT(2)=1, PUT(128)=127
     1040   TIME$="08:21:35" : DATE$="22:06:88"


Hinweis:
LET darf in einer Anweisung entfallen. Wird es jedoch verwendet,
sollte zur Vermeidung von Mehrdeutigkeiten nach LET grundsätzlich ein
Leerzeichen eingegeben werden. Das folgende Beispiel zeigt mögliche
Auswirkungen:

     Eingabe:               Wirkung:
     LA =1                  LA    =1
     L A =1                 LET A =1
     LETA=1                 LETA =1

Im Zweifel zeigt ein Auslisten der Zeile(n) ob Variablenname bzw.
Kurzformen richtig erkannt wurden.
Fehler:
07   Anweisung nicht korrekt abgeschlossen
08   Inkompatible Datentypen
10   Ausgabefunktion auf rechter Seite
     oder Einlesefunktion auf linker Seite




                                 -115-
7.2.3 MAT

Syntaxdiagramm:




Aufruf:     <zn> MAT <fn> = {IDN|ZER|TRO|<ma>|TRN<ma>}

Funktion:
Die Matrixanweisung MAT erlaubt die direkte Berechnung von Matrix-
Ausdrücken und stellt damit das Pendant zur LET-Anweisung für skalare
Ausdrücke dar.

Neben der sehr kompakten Formulierung von Matrix-Ausdrücken liegt der
Hauptvorteil    der   MAT-Anweisung    in    der   deutlich    höheren
Rechengeschwindigkeit gegenüber der Programmierung "zu Fuß". Die
Geschwindigkeitssteigerung liegt zwischen Faktor 10 und 30. Sie
erklärt sich vornehmlich damit, daß für das Aufbrechen des
Matrixausdrucks im Vergleich zu den unabdingbaren Rechenoperationen
wenig Zeit aufgewendet und keine explizite Indexrechnung gemacht wird.

Bei der Bearbeitung der MAT-Anweisung wird zunächst die rechte Seite
der Anweisung unter Berücksichtigung der Syntaxregeln und der
Dimensionalität der beteiligten Operanden ausgewertet. Anfallende
Zwischenergebnise werden selbständig angelegt. Das auf der linken
Seite stehende Ergebnisfeld wird entsprechend redimensioniert, es sei
denn, daß auf der rechten Seite die Sonderfunktionen IDN, ZER oder TRO
stehen. In diesen Fällen behält die Ergebnismatrix ihre ursprüngliche
Dimensionierung, da diese Funktionen nur eine Wertsetzng vornehmen.
Die Zielmatrix darf bei Multiplikationen nicht auf der rechten Seite
stehen.
Im Rahmen eines komplexen Matrix-Ausdrucks können folgende Operationen
und Funktionen vorgenommen werden:
Addition und Subtraktion:

     Matrix/Matrix
     Matrix/Skalar
     Skalar/Matrix
     Vektor/Vektor
     Vektor/Skalar
     Skalar/Vektor




Multiplikation:

     Matrix/Matrix
     Matrix/Spaltenvektor

                                 -116-
Matrix/Skalar
     Skalar/Matrix
     Zeilenvektor/Matrix
     Zeilenvektor/Spaltenvektor (Skalarprodukt)
     Spaltenvektor/Zeilenvektor (Dyad. Produkt)
     Vektor/Skalar
     Skalar/Vektor
     Element - Produkt

Hinweise:
Beim Skalarprodukt wird das Ergebnis im Element 1,1 einer 1*1-Matrix
abgelegt.

Beim Elementprodukt werden Felder elementweise multipliziert, was
insbesondere bei der Normierung/Skalierung von Meßwerten einen
häufigen Rechengang darstellt, z. B.:
     1000 XE_nor = SKV.XE + X_off

Matrix-Vektor_Funktionen:

     TRN    Transposition
     IDN    Die Diagonalelemente der Zielmatrix erhalten den
            Wert 1, alle anderen Elemente den Wert 0
     ZER    Alle Wert der Zielmatrix werden zu Null gesetzt
     TRO    verschiebt die Elemente des Zielvektors (!) um
            eine Indexstelle in Richtung nulltes Element
Beispiel:
     1000 REM Zustandsdgl. Eingrößensystem
     1010   MAT XP = A*X + B*[U]
     1020   MAT Y = CT*X
     1030   Y=Y(1,1)+D*U
     2000 REM Mehrgrößensystem (zeitdiskret)
     2010   VEC U=MADC(MO)
     2020   MAT X1=P*X + Q*U
     2030   MAT Y=CT*X + D*U
     2040   VEC MDAC(SO)=Y
     2050   MAT X=X1

Fehler:
11   Feldtyp falsch (Dimension oder String/Vektor)
12   Undefiniertes Feld
30   Unerlaupter Operand in MAT-Anweisung
31   Falsche Reihenfolge von MAT-Operationen
32   Inkonsistente Dimension auf der rechten Seite
33   Zielfeld zu klein dimensioniert
34   Vektor zu groß (>126) für MAT-Operationen
35   Zielfeld auch auf der linken Seite der MAT-Anweisung
36   Zuwenig Speicher für Ablage der Zwischenergebnisse
37   Interner Konsistenzfehler

7.2.4 VEC
Syntaxdiagramm:




                                 -117-
Aufruf:     <zn> VEC {<name>|{MDAC<sv>|MDOUT<sv>} =
                {<name>|{MDAC<mv>|MDIN}<mv>{+|...}
               {,...}
Funktion:

Die VEC-Anweisung erlaubt die Formulierung von vektorwertigen Prozeß-
Ein-/Ausgabe-Operationen bzw. PI(D)-Reglerfunktionen. Ähnlich der MAT-
Anweisung werden durch das Schlüsselwort VEC alle in der Anweisung
auftauchenden Variablennamen (name) als Namen eindimensionaler
numerischer Felder aufgefaßt. (Siehe hierzu Vektor-Funktionen).

Beispiel:

     1000   REM Einlesen des Meßvektors XE
     1010   REM Der Meßortvektor MO enthält in seinen
     1020   REM Komponenten die Einlesekanalnummern
     1030   REM
     1040     VEC XE=MADC(MO)

     2000   REM Ausgabe des analogen Stellvektors Y
     2010   REM Der Stellortvektor SO enthält in seinen
     2020   REM Komponenten die Ausgabekanalnummern
     2030   REM
     2040     VEC MDAC(SO) = Y

     3000 REM E,E1 usw. sind alle Vektoren
     3010   VEC Y=PI(Y,E,E1,KP,KI,YO,YU,YD,AK)
Fehler:
24   Unterschiedliche Dimension zweier Vektoren
25   (Hardware-)Fehler beim E/A-Zugriff
29   Fehler bei der Bestimmung der logischen Kanaladresse
     (gewünschter Kanal existiert nicht)




                                 -118-
7.2.5 POKE

Syntaxdiagramm:




Aufruf:      <zn> POKE (<adresse>,<wert>) <cr>

Funktion:
Die   im   Argument    <adresse>   der   POKE-Anweisung     angegebene
Speicheradresse wird mit dem Wert <wert> beschrieben.

Adresse:     ist ein ganzzahliger Ausdruck, dessen Wert im Bereich
             zwischen 0..65535 liegt. (0000H...FFFFH) und die
             Adresse einer Speicherstelle im 64k-Bereich darstellt.
Wert:        Ist ein ganzzahliger Ausdruck, dessen Wert im Bereich
             zwischen 0..255 liegt und das äquivalent der zu
             speichernden Information darstellt. (1 Byte)
Hinweis:
Es wird nicht überprüft ob sich <wert> unter der angegebenen Adresse
abspeichern läßt noch ob durch die Abspeicherung irgendwelche
Programmabläufe gestört werden können.
Die POKE-Anweisung ist aus diesem Grund mit größter Vorsicht zu
behandeln.
Beispiel:

                  100   REM *** POKE-Test
                  110   Addr = &H9000, Value = 195
                  120   POKE (addr,value)
                  130   x = PEEK(addr)
                  140   PRINT x AS 2I

Fehler:
13      Argument ist nicht im vereinbarten Bereich




                                  -119-
7.3   Kommentare

7.3.1 REM
Syntaxdiagramm:




Aufruf:      <zn> REM|' <kommentar> <cr>
Funktion:
Die REM-Anweisung erlaubt die Einfügung von Kommentaren in das
Programm. Kommentare haben auf die Programmausführung keinen. In
Einfluß. In zeitkritischen Programmsegmenten sollte jedoch auf eine
Kommentierung verzichtet werden, da der Interpreter zur Erkennung
einer Kommentarzeile doch eine gewisse Zeit benötigt.
In Anwendungen wo der Speicherplatz knapp wird, kann es u.U. ebenfalls
notwendig sein die Kommentierung einzuschränken oder ganz wegzulassen.
Beispiel:

      1000   REM   Kommentarzeilen werden vom
      1010   REM   BASIC-Interpreter ignoriert
      1020   REM   Die Zeilennummern dürfen jedoch
      1030   REM   nicht nochmals benutzt werden !
Fehler:
      (keine)




                                    -120-
7.4 Dateibefehle

Ersatzlos gestrichen, da kein DOS verfügbar.
Up- und Download     sowie das Speichern von Daten ist über
Terminalprogramme (MSRSHELL) und PC-Rechnern einfach zu realisieren.




                               -121-
7.5 Standardfunktionen

7.5.1 ABS(X)
Funktion: Es wird der Betrag von X zurückgegeben

7.5.2 ACN(X)

Funktion: Es wird der ArcusCosinus von X zurückgegeben
7.5.3 ASN(X)

Funktion: Es wird der ArcusSinus von X zurückgegeben

7.5.4 ATN(X)

Funktion: Es wird der ArcusTangens von X zurückgegeben
7.5.5 COS(X)

Funktion: Es wird der Cosinus von X zurückgegeben

7.5.6 EXP(X)
Funktion: Es wird der Exponent von X zurückgegeben

7.5.7 INT(X)
Funktion: Es wird der INTEGER-Wert von X zurückgegeben

7.5.8 LN(X)
Funktion: Es wird der natürliche Logarithmus von X zurückgegeben
7.5.9 LOG(X)

Funktion: Es wird der dekadische Logarithmus von X zurückgegeben
7.5.10 SIN(X)

Funktion: Es wird der Sinus von X zurückgegeben

7.5.11 SQR(X)
Funktion: Es wird die Quadratwurzel von X zurückgegeben

7.5.12 TAN(X)
Funktion: Es wird der Tangens von X zurückgegeben.




                               -122-
7.6 Stringfunktionen

7.6.1 CHR$(X)
Funktion: Der Wert von X wird als ASCII-Zeichen interpretiert
Beispiel:

            1000 FF$ = CHR$(12)

7.6.2 VAL(X$)

Funktion: Die durch den String X$ gegebene Ziffernfolge wird in
     Zahlenwert umgewandelt.

Beispiel:
            1000 Zahl$ = "123"
            1010 PRINT VAL(ZAHL$) AS 10F3

            liefert 123.000

Fehler:
09   Fehler beim Wandeln einer numerischen Konstante

7.6.3 LEN(X$)
Funktion: Es wird die Länge des Stringausdrucks X$
     zurückgeliefert.
Beispiel:
            1000 Zahl$ = "123"
            1010 PRINT LEN(ZAHL$) AS 6I
            liefert    3
Zum Abspalten von Teilstrings aus einem Quellstring stehen in MSRBASIC
folgende Funktionen zur Verfügung:

7.6.4 LEFT$(Q$,N)

Funktion:   Es wird aus den ersten N linken Zeichen des
            Quellstrings Q$ ein Teilstring gebildet

7.6.5 MID$(QS,N,M)
Funktion:   Es wird aus dem Quellstring Q$ beginnend mit dem N-ten
            Zeichen ein Teilstring gebildet der M Zeichen umfaßt.


7.6.6 RIGHT$(Q$,N)

Funktion: Es wird aus den N letzten Zeichen auf der rechten
     Seite des Quellstrings Q$ ein Teilstring gebildet.


7.6.7 INSTR({N,}Q$,S$)
Funktion:   Die INSTR-Funktion prüft den Quellstring Q$ ob (optional ab

                                  -123-
Position N) von links beginnend der Suchstring S$ enthalten
            ist. Ist dies der Fall, wird die Position des Suchstringes
            innerhalb Quellstrings zurückgeliefert.

7.6.8 ASC(x$)

Funktion: Die ASC-Funktion gibt einen Fließkommawert zurück, der
          dem ASCII-Wert des ersten Buchstaben von x$ ent-
spricht.
Beispiel:   x$ = "A"
            y = ASC(x$)     y ist 65 (dezimal)



7.6.9 FTOI$
Funktion: Die FTOI$-Funktion wandelt eine Gleitkommazahl in
     einen Long-Integer-Wert und gibt diesen als
Zeichenkette mit 3-Zeichen zurück. Die Reihenfolge ist              LB
                                                                    S,
MIDB,MSB (unterstes, mittleres, oberes Byte).

Beispiel: 100
     iel:         a= (&H3132 * 256 + &H0033)
          110     REM die Zahlen H31,H32 und H33 sind die
          120     REM die ASCII-Darstellung der Zahlen
          130     REM "1", "2" und "3"
          140     PRINT a                ' ergibt 3224115.000
          150     PRINT FTOI$(a)        ' ergibt "321"

Diese Funktion ist vor allem dann von Interesse, wenn Daten, z.B.
eines AD-Wandlers an einen zentralen Rechner weitergeleitet werden
sollen. Dies soll ein weiteres Beispiel verdeutlichen:

Beipiel:
          Es soll über LU(2) der Wert von ADC(1) als ASCII-
          String ausgegeben werden. Zur Kennzeichnung soll
     dieser String mit der ESC-Sequenz <ESC>"A" ange-
          führt werden.

            100   adcw$ = FTOI$(ADC(1))             ' einlesen ..
            110   PRINT ON(2) CHR$(&H1B);"A";    ' <ESC>"A"
            120   PRINT ON(2) MID$(adcw$,1,2);




                                  -124-
7.6.19 FTOIB

Funktion:  Diese Funktion wandelt eine Gleitkommazahl in einen 8-
           Bit-Wert, wobei anzugeben ist, welches Byte
(LSB=0, MIDB=1 oder MSB=2) eines Long-Integer-Wertes     gemeint
ist.

Beispiel:   100   a = (&H3132 * 256) + &H0033)
            110   PRINT FTOIB(a,0) AS 2H         ' = "33"
            120   PRINT FTOIB(a,1) AS 2H         ' = "32"
            130   PRINT FTOIB)a.2) AS 2H         ' = "31"




                                 -125-
7.7 Sonstiges

7.7.1 USR
Syntaxdiagramm:




Aufruf:     <zn> USR <n> (<parameter>{,<parameter>...})
Mit USR kann ein Assembler-Unterprogramm mit der angegebenen Nummer
(n) aufgerufen werden. Dieses Assemblerunterprogramm    muß bei der
werksseitigen Installation (oder durch den Benutzer, falls das
Entwicklungspaket zur Verfügung steht) in MSRBASIC eingebunden sein.
Die Parameterübergabe erfolgt über den Stapelspeicher (Stack) wobei
die Anzahl der übergebenen Parameter im A-Register (des Z80) stehen.
Als Parameterausdrücke sind Variable und Ausdrücke zugelassen.

Es werden für jeden Parameter zwei Datenworte übergeben: zuerst die
Adresse der Parameter und danach einen Typ-Deskriptor, dabei ist zu
beachten, daß die Daten vom Stapelspeicher in umgekehrter Reihenfolge
geholt werden!.

   6444444444444444;444444444444444447
   5         MSB        5        LSB            5
   :444444444444444>44444444444444444<
   5 Typ-Deskriptor5        (reserviert)    5
   :444444444444444=44444444444444444<
   5      Adresse des Parameter             5
   94444444444444444444444444444444448


Der Typ-Deskriptor enthält folgende Information:

Bit 7:       =1 Parameter ist ein Ausdruck
             =0 Parameter ist eine Variable
                wenn Bit 7 =0 (Variablenübergabe),
                dann bedeutet
BIT 1 :     =1 Feld(Element)
             =0 Skalare Variable

Bit 0       =1 Parameter ist ein String
             =0 Parameter ist eine Gleitkommazahl

Hinweise:
Zur ordnungsgemäßen Rückkehr in den MSRBASIC-Interpreter muß der (Z80-
) RET-Befehl (0C9H) benutzt werden.

Im Unterprogramm sollte der Anwender Anzahl und Typ der Parameter

                                    -126-
überprüfen; insbesondere ist zu prüfen, ob der Ergebnisparameter
korrekt als Variable übergeben wurde (siehe Beispiel).

Die Nummer des Assemblerunterprogrammes (UP) darf im Bereich 0..254
liegen.   Die  Verbindung  zwischen   Interpreter  und  Assem-bler-
Unterprogramm  (UP) erfolgt über eine konfigurations-abhängige
Spungtabelle.

Beispiel:
            1000 USR 1(A(0),A$,10*Y)

Fehler:

01   Falscher Parameter-Typ (z.B. String statt Zahl)
15   Unterprogramm mit der gewünschten Nummer nicht vorhanden
23   Parameter-Anzahl nicht korrekt




                                 -127-
7.7.2 CALL

Syntaxdiagramm:




Aufruf:<zn> CA{LL}<adresse>(parmeter1,parameter2,parameter3)

Mit CALL können Unterprogramme an beliebigen Adressen <adresse> im 64K
Adressraum    der   Z80-CPU    aufgerufen   werden.    Als   Parameter
(parameter1..parameter3) können nur numerische Variable über-geben
werden. Sie werden als Integer (Ganzzahl-)Wert in den CPU-Registern HL
(paramter1), DE (parameter2) und BC (parameter3) an das Unterprogramm
übergeben; Ergebnisse werden in den gleichen Register zurückerwartet
und in den entsprechenden Variablen abgelegt.
Werden gebrochene Werte      übergeben,   rundet   der   Interpreter   den
übergebenen Wert auf.

Die Parameter <parameter1..parameter3> müssen angegeben werden, sind
keine Parameter notwendig oder vorhanden kann ein belieb-iger Wert
eingesetzt werden.

Das aufgerufene Unterprogramm darf alle Register verändern außer dem
Stackpointer, da mit dem Z80-Befehl RET (&HC9) in MSRBASIC
zurückgekehrt wird.

CALL bringt gegenüber der ähnlichen USR-Anweisung den Vorteil, daß das
aufgerufene Unterprogramm nicht im Interpreter eingebunden sein muß,
es kann (notfalls) mit POKE in einen freien RAM-Bereich geschrieben
werden.
Gegenüber der USR-Anweisung verlangt         die   CALL-Anweisung      aber
Programmierkenntnisse in Z80-Assembler!

Beispiel:
             100   REM *** Beispiel zu CALL ***
             110     varhl = &H55, varde = 1234, varbc = 0
             120     CALL &H9800(varhl,varde,varbc)
             130     PRINT varhl AS 4H




                                  -128-
Beispiel des Assembler-Unterprogrammes
es wird ganz einfach varhl, varde und varbc addiert
das könnte MSRBAS ja auch aber ...
upx: add   hl,de              ; [&H19] Erst mal HL+DE
     add   hl,bc              ; [&H09] dann HL+BC
     ret                      ; [&HC9]   fertig

und nun dieses Programm in,s RAM mit POKE
 10   addr = &H9000
 20   POKE(addr,&H19)
 30   POKE(addr+1,&H09)
 40   POKE(addr+2,&HC9)




                      -129-
7.7.3 ONERROR

Syntaxdiagramm:




Aufruf:      <zn> ONERROR <zn>

In   "unbeobachteten"    Programmen   nutzen   Fehlermeldungen   des
Betriebssystemes während eines Programmablaufes sehr wenig, da keine
Reaktion von einem Bediener zu erwarten ist.

Zu diesem Zweck kann (am Programmbeginn) eine Verzweigung in ein
beliebiges Unterprogramm veranlasst werden, welches immer dann
aufgerufen wird, wenn ein Laufzeit-Fehler auftritt.
Der ONERROR-Aufruf kann durch NEW oder ONERROR 0 abgeschaltet werden.

Beispiel:
             100 REM *** Initialisierung ****
             :
             200    ONOERROR 220
             210    GOTO 1000
             220 REM *** ONERROR Unterprogramm"
             230    var1=0, var2=0
             :
             : und was halt sonst noch gemacht werden muß
             ;   evtl. auch NOTALARM
             :
             300    DOUT(7)=1
             :
            1000 REM *** Beginn des Hauptprogrammes
             :




                                  -130-
8. Kommandos

Unter Kommandos sind Befehle an den Interpreter zu verstehen, die
direkt (von der Konsole aus) eingegeben werden können. Sie dienen
entweder Editierzwecken ( AUTO usw.) oder der Festlegung der
Betriebsart (RUN usw.).

8.1 AUTO

Syntaxdiagramm:




Aufruf:     AUTO {<szn> {,<schritt>}} <cr>

Funktion:

Das AUTO-Kommando veranlasst, daß in den EDITIER-Modus geschal-tet und
dabei AUTOmatisch die Zeilennummer generiert wird. Als erste
Zeilennummer wird die vorgegebene Startzeilennummer (szn) verwendet.
Wird keine Zeilennummer angegeben wird mit der Zei-lennummer 10
begonnen. Alle weiteren Zeilennummern werden aus der momentanen
Zeilennummer + der Schrittweite (schritt) be-rechnet.

Wurde keine Schrittweite angegeben wird der Vorgabewert 10 verwendet.
Eine Korrektur der automatisch erzeugten Zeilennummer ist möglich, hat
dann jedoch auch Einfluß auf die weiteren zu generierenden
Zeilennummern.

Der AUTO-Modus wird durch <cr>in einer Leerzeile oder die Eingabe
eines Kommandos verlassen.

Fehler:
Im FREEZE-MODUS ist AUTO nicht möglich, da keine Programmeingabe
erlaubt ist.




                                 -131-
8.2 CLS

Syntaxdiagramm:




Aufruf:     {<zn>} CLS

Funktion:
Mit dem CLS-Kommando wird der Bildschirm gelöscht. Das CLS-Kommando
kann auch als Anweisung innerhalb eines Programmes verwendet werden.

Wird CLS im WINDOW-Betrieb verwendet, so wird nur das (obere)
Ausgabefenster gelöscht. Da in dieser Betriebsart das Löschen des
Bildschirmes nur emulieren werden kann, erfolgt dieses deutlich
langsamer.




                               -132-
8.3 FREEZE

Syntaxdiagramm:




Aufruf:      FRE{ZE}

Funktion:
Das FREEZE-Kommando gibt das Echtzeitbetriebssystem frei (Ausführung
von ACTIVATE-TASK-Anweisungen etc. sind damit zulässig), was aus
Sicherheitsgründen ein Verbot des gleichzeitigen Editierens von
Programmzeilen mit sich bringt!
FREEZE   entfernt      gelöschte   Programmteile    aus   dem   Speicher
("Entrümpelung").

     -       Schützt ein BASIC-Programm ("einfrieren")
     -       Koppelt ein in EPROM gespeichertes BASIC-Programm an

     -       Gibt das Echtzeitbetriebssystem frei




                                   -133-
8.4 LIST

Syntaxdiagramm:




Aufruf:     LIST {<begin>{,<ende>}}
            LIST {<dateiname>|ON(<kn>}{<begin{,<ende>}}

Funktion:
Ausgabe (Listen) eines MSRBASIC-Programmes auf der Bedienkon-sole,
einem Ein-/Ausgabekanal (kn) (z.B. Drucker) oder einer Datei
(dateiname), wobei eine Startzeile (begin) und Endzeile (ende)
spezifiziert werden kann. Beim Aufruf "LIST ON..." geht der
Interpreter in die Transparentbetriebsart (siehe LOAD-Kommando) um die
Verbindung zu einem Hostrechner zu ermöglichen. (Virtuelles Terminal
z. B. mit PC-TERM). Diese Betriebsart wird bei Eingabe von CNTRL-A
verlassen und das Auslisten des Pro-grammes auf den ausgewählten Kanal
vorgenommen.

Beim Auslisten wird versucht, die Struktur des Anwenderpro-grammes
möglichst deutlich wiederzugeben, daher werden Zeile welche die
Befehle
            END, REM, RETURN, STOP, WAIT

enthalten, um zwei Druckpositionen nach links gerückt.Das Innere von
Laufanweisungen wird um 4 Leerzeichen nach rechts ver-schoben.

Grundsätzlich wird die Normalform einer Anweisung ausgedruckt, auch
wenn der Benutzer ursprünglich die Kurzform eingegeben hat.

Beispiel:

     1000    REM        *** Demonstrationsprogramm
     1010     DIM X (10,10)
     1020        FOR I=1 TO 10
     1030           FOR J=1 to 10
     1040                PRINT "Element";I AS 2I;",",J AS 2I
     1050                INPUT X(I,J)
     1060           NEXT J
     1070        NEXT I
     1080    STOP




                                 -134-
8.5 LOAD

Syntaxdiagramm:




Aufruf:     LOAD {ON<n>|<dateiname>}

Funktion:
Es kann ein MSRBASIC-Programm entweder

            - von der Bedienkonsole (download)
            - von einem beliebigen Peripheriegerät auf Kanal <n>
            - von Diskette (via MSDOS)
eingelesen und im Arbeitsspeicher abgelegt werden.

Zu Beginn des Ladens erscheint auf der Bedienkonsole quasi als
Triggersymbol ein Ausrufezeichen "!". Beim Einlesen jeder neuer Zeile
wird ein Zähler inkrementiert (modulo-8-Zähler), der den Fortgang des
Ladevorganges    dokumentiert.   Nach   dem  Einlesen   der   letzten
Programmzeile bleibt die Anzeige stehen, bis, nach dem vollständigen
Übersetzen   des    Programm-Klartextes   in  den   MSRBASIC-internen
Zwischencode, die READY-Meldung kommt.
Falls der "ON(...)"-Zweig aktiviert ist, geht der Interpreter zunächst
in die Transparentbetriebsart, d.h. er stellt softwaremäßig die
Verbindung zwischen der Bedienkonsole und dem angesprochenen
Peripheriegerät her. Ist dies ein (Host-)Rechner, kann er in dieser
Phase des LOAD-Kommandos über das Terminal des MSRBASIC-Rechners
nahezu beliebig bedient werden (virtuelles Terminal). Die Eingabe von
CNTRL-A veranlasst MSRBASIC, an den Hostrechner ein RETURN-Zeichen
(CR) zu schicken und damit das Zusenden eines Programmes auszulösen.
MSRBASIC geht unmittelbar danach in die Ladebetriebsart über. Das
Laden wird abgebrochen, wenn ein CNTRL-Z-Zeichen (1AH) eintrifft oder
wenn mehr als 5 Sekunden kein Zeichen mehr kommt (Time-out).

Das Laden kann von der Konsole her mit CNTRL-C abgebrochen werden,
ohne, daß bereits eingelesene Programmzeilen verloren gehen.
Hinweise:

Unter MSDOS ist die Betriebsart als virtuelles Terminal mit der COMn-
Schnittstelle möglich, diese bedarf aber spezieller Inter-rupt-
Treiber, da der "eingebaute"         MSDOS-Treiber nur bei Über-
tragungsgeschwindigkeiten bis 2400 Baud geeignet ist. Ein ent-
sprechendes Hilfsprogramm (mit integriertem Editor) steht auf Anfrage
zur Verfügung. (MSRSHELL).

Werden beim Übersetzen in den Zwischencode Syntaxfehler erkannt, so
wird die fehlerhafte Zeile gemeldet. Alle bereits eingegliederten
Zeilen bleiben erhalten, alle folgenden Zeilen gehen verloren.

                                 -135-
8.6 NEW

Aufruf:     NEW
Funktion:   Alle TASKs stillegen, Programm löschen, Daten löschen
            und NOFREEZE-Betriebsart einstellen



8.7 NOFREEZE
Aufruf:     NOF

Funktion:   Alle TASKs stillegen, Programme in EPROM abkoppeln
            und Programmschutz aufheben.

            In diesem Modus kann ein Programm, welches im RAM-
            speicher abgelegt ist, wieder editiert werden.

8.8 MFREE
Aufruf:     MFREE

Funktion:   a) in NOFREEZE-Betriebsart
               Speicher entrümpeln
               Datenspeicher löschen
               Angabe des freien Speichers
            b) in FREEZE-Betriebsart
               Angabe des freien Datenspeichers



8.9 RUN
Aufruf:     RUN {<startzeile>}
Funktion:

Starten eines MSRBASIC-Programmes bei der ersten Zeile oder bei der im
Kommando angegebenen Zeile (startzeile).

Die interne Symboltabelle wird in keinem Fall gelöscht, es bleiben
also alle Werte aus "vorangegangenen Läufen" vorhanden!




8.10 SAVE

Aufruf:     SAVE {<begin>{,<ende>}}
            SAVE {<dateiname>|ON<kn>}{<begin>{,<ende}}

Funktion:
Ausgabe des im Speicher befindlichen MSRBASIC-Programmes auf
Bedienkonsole oder Peripheriegerät, ähnlich wie LIST-Kommando. Im

                                 -136-
Gegensatz zu diesem wird jedoch das Listing    nicht struk-turiert und
die abgekürzten Befehle verwendet.

Beispiel:

     1000   R *** Demonstrationsprogramm ***
     1010   DIM X(10,10)
     1020   F I=1 TO 10
     1030   F J=1 TO 10
     1040   P "Element"; I AS 2I;",";J AS 2I
     1050   I X (I, J)
     1060   N J
     1070   N I
     1080   STOP

8.11 SYSTEM

Aufruf:     SYS{TEM}

Funktion:
Verlassen des MSRBASIC-Interpreters.
Hinweis:

Beim   Verlassen   des   MSRBASIC-Interpreters    wird   das   interne
Echtzeitbetriebssystem abgeschaltet und ein evtl. bereits vorhandenes
Interruptsystem restauriert. Ist MSRBASIC als stand-alone-System
installiert wird (konfigurationsabhängig) ein Kaltstart, ein Warmstart
oder "garnichts" ausgeführt. In einigen Umgebungen wird auf den ELZET
80-typischen SYstemMONitor (SYMON) ausgesprungen (der sich dann
meldet!).
8.12 VCL
Aufruf:     VCL

Funktion:

Löschen aller Anwendervariablen und -Zeitgeber.

Das VCL-Kommando ist aus Sicherheitsgründen nur in der NONFEEZE-
Betriebsart zulässig (kein Echtzeitbetrieb).




                                -137-
9. Programmiertips

MSRBASIC ist nicht nur ein leistungsfähiges Werkzeug für die Lösung
kleinerer MSR-Aufgaben, es eignet sich auch für die komplette
Automatisierung von Industrieanlagen mit Ein- und Mehrrechner-
Systemen.

Um derart komplexe Anwendungen erfolgreich zu meistern, empfiehlt es
sich bei der Systemanalyse, Programmkonzeption und Implementierung
einige "goldene Regeln" zu beherzigen, die im folgenden als
"Programmiertips" formuliert sind und die Erfahr-ung aus zahlreichen
Anwendungen wiederspiegelt.

9.1 Systemanalyse und Programm-Konzeption

9.1.1 Analyse der erforderlichen Parallität
Auch wenn es altväterlich klingt: Gundvoraussetzung für ein
tragfähiges Echtzeit-Anwenderkonzept ist eine klare Spezifikation und
ein darauf abgestimmtes Programmkonzept.

Folgende Punkte sollten bei der Programmkonzeption der Reihe nach
geklärt werden:
     - In welchen funktionell entkoppelten Teilbereichen kann
       die zu automatisierende Anlage "zerlegt" werden ?

     - Welche Funktionen sollen bzw. müssen parallel bearbeitet
werden ?

     - Welche Funktionen sind quasikontinuierlich oder
       ablauforientiert ?

Im Prinzip wird jeder parallel ablaufenden Funktion ein MSRBASIC-
Programm vom Typ TASK oder SEQuenz zugeordnet.

Hierbei leistet eine Darstellung der Aufgaben in Form eines Petri-
Netzes wertvolle Hilfe, da es den Grad an jeweils notwendiger
Parallelität strukturell ausweist.

Es   empfiehlt  sich   jedoch   im   Sinne  einer   möglichst   guten
Übersichtlichkeit, die Anzahl an parallelen Programmen nicht über das
unbedingt notwendige Maß hinauswachsen zu lassen.
Hierzu werden Ablaufaktionen, die zwar parallel laufen können, aber
ohne Verzicht auf die Güte des technischen Prozesses auch nacheinander
ablaufen können, als Teilaktionen einer SEQuenz formuliert.
Beispiel: Wegeschaltung in Materialflußsystemen

Bei Materialflußsystemen (z.B. Tanklager) tritt häufig die Aufgabe
auf, einen neuen Weg zu schalten. Im konkreten Fall sollen die Ventile
V2, V3, V8 geöffnet und die Ventile V1, V5 geschlos-sen werden, bevor
über ein Ventil v10 der Fluß freigegeben wird. Bei jedem Ventil muß
die Endposition überwacht werden, d.h. jeder Vorgang besteht aus den
Aktionen:
           - Ventil öffen (bzw. schließen)

           - maximal n Sekunden warten bis Endposition
             erreicht, sonst Fehlermeldung

                                -138-
Die einzelnen Öffnungs- / Schließungsvorgänge können parallel
ablaufen. Dennoch ist es nicht sinnvoll, für jeden Vorgang eine
SEQuenz zu 'verbrauchen'; vielmehr können alle Aktionen mit einer
SEQuenz nach folgendem Schema durchgeführt werden:

     - Schliesse bzw. öffne alle fraglichen Ventile
          (" DOUT(V1)=0,...DOUT(V2)=1")
     - Warte max. n Sekunden auf korrekte Positionsrückmeldung

         ("WAIT MAX n FOR NOT(DIN(V1)+DIN(V5)*DIN(V2)..ELSE")

     - Die Fehlerbehandlung (nach ELSE) analysiert die
 Rückmeldesignale und liefert in einer Variablen (Err$)
die Fehlercodes:

          Err$ = "Fehler in"
          IF DIN(V1)      THEN Err$=Err$+" V1"
          IF DIN(V5)      THEN Err$=Err$+" V5"
          IF DIN(V2)=0   THEN Err$=Err$+" V2"
          PRINT Err$

Regel:    soviel Parallelität wie nötig -   so wenig wie möglich!


9.1.2 Restriktive Auslastung
Als weitere Grundregel bei der Konstruktion von Echtzeitsystemen
sollte man bei der Auslegung der Abfragezeiten von Tastern eher
restriktiv vorgehen, um der Gefahr einer auch nur partiellen
Überlastung des Rechners vorzubeugen.




                               -139-
9.2 Programm-Implementierung

9.2.1 Anlagenorientierte Modularisierung
In der Regel läßt sich eine größere Anlage in definierte Teilbereiche
untergliedern. Diese Struktur ist beim Programmentwurf grundsätzlich
dadurch zu berücksichtigen, daß

     - alle zum Anlagenabschnitt gehörenden Programmteile (TASKs
       und SEQuenzen) möglichst einen zusammenhängenden
       Abschnitt im Gesamtprogramm belegen ("Kompaktheit")

     - die Abhängigkeit der abschnittspezifischen Programmteile
       von den anderen Abschnitten minimiert wird.

Diesen Zielen kann in MSRBASIC am einfachsten durch entsprechende
Zeilennummern-Vergabe Rechnung getragen werden
           2000 .. 2999 Anlagenabschnitt 1
           3000 .. 3999 Anlagenabschnitt 2
           etc




                                -140-
9.3 Übersichtlichkeit der Programme

Die   nachfolgend    genannten   Mittel    tragen    unmittelbar   zur
Übersichtlichkeit von Programmen bei und damit zur leichteren Wartung.
     - Variablennamen nicht in Großschreibung verwenden

            Vergleich:
            IF HAND + NOTAUS THEN DOUT(HAUPT)=0
            IF Hand + Notaus THEN DOUT(Haupt)=0

     -      Sprungziel von GOTO, GOSUB, THEN und ELSE als REM
            markieren. Dies bringt eine erhöhte Sicherheit gegen
            Programmierfehler und steigert die Übersichtlichkeit
            Beispiel:

              980   GOSUB 1280
            :
            :
            1280    REM *** Pumpe einschalten ***
            :


     -      Symbolische Namen verwenden. Die Namen sollten (innerhalb
            der 6 zugelassenen Zeichen) jedoch mnemonische Züge tragen
            und keine nichtssagende Abkürzung.

         Dies gilt für Variable:

            WAIT FOR DIN(123)*DIN(121)+DIN(125)
         oder

            WAIT FOR DIN(Vent1)*DIN(Vent2)+DIN(Stop)
         für logische Einheiten:
            IF BIT(FOpen,STATUS(ErrLU))=0 THEN ...

         für Zeitgeber

            IF TDOWN(T_regl)>0 THEN RETURN
            TDOWN(T_regl) = T_regl
         für TASKs und SEQuenzen:

            IF DIN(3)=0 THEN SUSPEND TASK 2
         oder

            IF DIN(AStop)=0 THEN SUSPEND TASK Anzeig




     - Bildschirm-Steuerzeichen werden am besten als String-
             Block definiert. Das läßt leichter erkennen was gemeint
       ist und vereinfacht die Anpassung an eine andere Konsole.

                                    -141-
esc$   =CHR$(27)
     cr$    =CHR$(13)   usw.

- Bei der Parameterübergabe an Unterprogramme MAT-
  Anweisungen benutzen:

 MAT <arbeitsmatrix>=<hauptmatrix>
 GOSUB ...
 MAT <hauptmatrix> =<arbeitsmatrix>




                          -142-
10.   Hardware-Anpassung und EPROM-startende Systeme

10.1 Allgemeines
MSRBASIC ist keines der "üblichen" Programme die zum Ablauf ein
bestimmtes Betriebssystem benötigt, vielmehr sind alle not-wendigen
Ein-/Ausgabefunktionen bereits werksseitig eingebunden.

ELZET 80 Mikrocomputer liefert MSRBASIC für alle Prozessor-Karten die
mit einer Z80 (kompatiblen) CPU ausgerüstet sind.
Dazu gehören:

      Die Standard-CPU's für ECB-Systeme

      CPU-S
      CPU85SC
      CPUZ280

      Die Einplatinencomputer der MOPS-Serie

      MOPS 1Ax, 2AX und 5AX
      MOPS 0Dx
      Den Tragschinencomputer

      TSM-CPU

10.2 Hardware-Anpassung
Die zu einer bestimmten Prozessor-Karte gelieferten MSRBASIC-
Interpreter (im EPROM) sind an die Hardware der entsprechenden Karte
angepasst und können nicht auf einer anderen Karte eingesetzt werden.
Eine Reihe zusätzlicher AD-,DA, oder Digital-Ein-/Ausgänge können
zusätzlich bei den EPROM's für ECB-Systeme durch einfaches ändern
(patchen) im EPROM eingebunden werden. Nähers ist aus den Programm-
Ausdrucken (Listings) des Hardware-abhängigen Programmsegmentes im
Anhang zu ersehen.
Müssen besondere Ein-Ausgabetreiber eingebunden werden, so kann dies
(gegen Unkostembeitrag) von ELZET 80 Mikrocomputer über-nommen werden
oder es kann der Quelltext des Hardwareabhängigen Programm-segmentes
und die REL-Datei des Hauptprogrammes (Hardware-unabhängig) käuflich
erworben werden. Zur Bearbeitung die-ser Dateien ist neben der
Kenntnis in Z80-Assembler-program-mierung auch die Verfügbarkeit eines
(Z80-)CP/M-kompatiblen Betriebs-Systemes und eines Z80-Assembler und
Linkers notwendig.




                                -143-
10.2.1 Portadressen

Zur Ansprache der analogen bzw. digitalen E/A-Karten, die direkt von
MSRBASIC aus angesprochen werden können, müßen die Port-adressen auf
den E/A-Karten wie folgt eingestellt werden:

Digitale Ein-/Ausgabe:
                           Port           Systemkarten
DIN(0)....DIN(15)          80H            24V=, 24VB, REL16R,   OP32IN
DIN(16)...DIN(31)          82H            24V=, 24VB, REL16R
DIN(32)...DIN(47)          84H            24V=, 24VB, REL16R,   OP32IN
DIN(48)...DIN(63)          86H            24V=, 24VB, REL16R
DIN(64)...DIN(79)          88H            24V=, 24VB, REL16R,   OP32IN
DIN(80)...DIN(95)          8AH            24V=, 24VB, REL16R
DIN(96)...DIN(111)         8CH            24V=, 24VB, REL16R,   OP32IN
DIN(112)..DIN(127)         8EH            24V=, 24VB, REL16R
AD-Karten (16AD12b/c)

ADC(0)....ADC(15)          B0H
ADC(16)...ADC(31)          B4H
ADC(32)...ADC(47)          B8H
ADC(48)...ADC(63)          BCH
DA-Karten (4DA12)

DAC(0)....DAC(15)          C0H
DAC(16)...DAC(31)          C4H
DAC(32)...DAC(47)          C8H
DAC(48)...DAC(63)          C4H
Informationen wie das Einstellen der Portadressen zu bewerk-stelligen
ist, sind in den Unterlagen zu den jeweiligen Systemkarten zu finden.
Die Zusatzmodule der TSM-Serie müßen nicht auf spezielle Adressen
gelegt werden, hier genügt eine beliebige Durch-nummerierung der
Aufsteckmodule zur Identifizierung des Modules, MSRBASIC nummeriert
die Ein- bzw. Ausgänge automatisch in auf-steigender Ordnung nach der
eingestellten ID-Nummer des Modules. Die digitalen Ein-/Ausgänge auf
der TSM-CPU werden dabei immer mit mit der niedrigsten Nummer belegt.




                                  -144-
10.3 EPROM-startende Systeme

Für EPROM-startende Systeme ist es notwendig, daß der MSRBASIC-
Interpreter und das (ablauffähige) BASIC-Programm in EPROM(s) gebrannt
sind.

Prinzipiell genügt es auch, wenn der Interpreter in EPROM gebrannt
ist, daß der Programmspeicher, durch z.B. Batterie-pufferung, vor
Datenverlust geschützt ist. Nach einem Stromausfall oder CPU-RESET (ob
gewollt oder ungewollt) prüft der MSRBASIC-Interpreter immer nach ob
ein funktionsfähiges Programm vorhanden ist, ist dies der Fall, so
wird das gefundene Programm ausgeführt!
In manchen Systemen ist jedoch eine Batteriepufferung nicht möglich
oder nicht erwünscht. In diesem Falle muß das ablauffähige Programm in
ein EPROM gebrannt werden. Die entsprechenden Daten liefert das
Kommando PROMIT




                                -145-
10.3.1 PROMIT

Aufruf:     PROMIT {<addr>}
Funktion:

Um ein MSRBASIC-Programm in EPROM ablegen zu können, muß es bereits
vorinterpretiert sein. Darunter ist zu verstehen, daß der Interpreter
alle Funktionsnamen usw. in (interpreterinterne, sog.) TOKEN
umgewandelt hat und die Befehlszeilen untereinander "verzeigert" sind,
damit der Interpreter sich "schneller zurecht findet".

In der Praxis bedeutet dies, das zu "EPROMende" getestete Programm
wird geladen und kann nun mit dem Kommando PROMIT im INTEL-HEX auf
Diskette abgespeichert werden. ( mit Hilfe von MSRSHELL unter MSDOS).
Wird das Kommando PROMIT     ohne <addr> aufgerufen, so wird das
eigentliche Programm direkt hinter den MSRBASIC-Interpreter angehängt
und der MSRBASIC-Interpeter incl. dem Ablaufprogramm ausgegeben. Dies
setzt voraus, daß das Programm noch in die verbleibenden etwa 5K-Byte
des 32K-EPROMs paßt. Ist das nicht der Fall endet PROMIT in einer
Fehlermeldung.

Dann muß man bei Einsatz der CPU/S im Speicherbereich von oben (FFFFH)
kommend den nötigen Bereich für das Anwenderprogramm in Eprom
reservieren, was nur durch den Ensatz einer externen RAM/EPROM-Karte
möglich ist. MSRBASIC geht davon aus, ab 8000H RAM vorzufinden. RAM-
Ende wird durch eine Adresse auf Speicherstelle 0007/0008H im
MSRBASIC-EPROM markiert, EPROM-Start durch einen Adreßeintrag auf
0005/0006H.
Wird PROMIT mit Adressangabe <addr> aufgerufen, so wird      nur das
Ablaufprogramm ausgegeben, welches dann in ein EPROM mit der
angegebenen Startadresse "gebrannt" werden kann. In diesem Fall ist

            jedoch unbedingt zu beachten,
daß im EPROM des MSRBASIC-Interpreters die Adresse 0005/0006H mit der
angegebenen Startadresse verändert wird. Die Adresse ist im Z80-Format
einzutragen d.H. das untere Adressbyte zuerst, dann das obere
Adressbyte!
Außerdem muß das RAM-Ende auf gleiche Weise in Adresse 0007/0008H
eingetragen werden.




Beispiel:

                 PROMIT &HC000              (EPROM-Start C000H)
Im EPROM (Kopie!) ist dann der

     Inhalt von Adresse 0005H in 00H (unteres Byte der Adresse)    und
der Inhalt von Adresse 0006H in C0H

                                 -146-
(oberes Adreßbyte) zu ändern.

Für das passende RAM-Ende bei BFFFH muß Adresse 7 auf FF bleiben und
Adresse 8 auf BF geändert werden. Beide Adreßreferenzen sind im
Auslieferungszustand FFFF, so daß das EPROM nachgebrannt werden kann.


Achtung:

Wird PROMIT ohne Adressangaben aufgerufen, wird der Inhalt der Adresse
0005H automatisch an den Programmanfang angepaßt, d.h. das 32K-EPROM
mit BASIC und Anwenderprogramm kann direkt aus dem Hexfile erzeugt
werden. Für die HEX-Binärwandlung ist von ELZET ein DOS-Programm
HEXBIN erhältlich.


Hinweis:
In der Praxis sind Programme bei den CPU-Karten der ECB-Serie ohne
Probleme in EPROMs zu transferieren, wenn das Ablaufprogramm noch in
das Interpreter-EPROM passt.

Bei "Platzmangel" hilft es, wenn im ausgetesteten Programm vor PROMIT
alle Kommentare entfernt (oder gekürzt) werden, u.U. können auch die
Variablennamen noch gekürzt werden.

Sollte dies alles nicht helfen, so muß (bei ECB-Systemen)        eine
zusätzliche Speicherkarte (64KRE) benutzt werden.
Bei allen MOPS-Systemen der Serie A (MOPS 1AX,2AX und 5AX)   muß ein
geändertes Interpreter-EPROM angefordert werden, in welchem der RAM-
Bereich auf den oberen 2K-Sockel beschränkt wird.

Bei den MOPS-Systemen der D-Serie muß ebenfalls ein angepasstes EPROM
angefordert werden. In diesem Falle wird das "untere" EPROM um 16K
erweitert (0000H...BFFFH). Als EPROM muß dann ein Typ xx512 (64K)
eingesetzt werden, der RAM-Bereich ist dann auf 16K im Bereich von
C000H...bis FFFFH reduziert. Es wird jedoch nach wie vor ein 32K-RAM
verwendet.

Bei MOPS-Systemen der A-Serie kann ein (kleineres) Programm natürlich
auch in den oberen (2K-)Sockel transferiert werden. In diesem Fall ist
kein geändertes EPROM notwendig, natürlich muß auch hier die Adresse
0005H angepasst werden!


10.4.2 PROMIT bei Z280 Systemen
Der Z280-Prozessor verfügt über einen System- und einen USER-Bereich,
der jeweils 64KByte hat. Im Systembereich, dr für den Anwender nicht
zugänglich ist , befindet das Betriebssystem von MSRBASIC wärend im
USER-Bereich ein Teil des Interpreters     und das Benutzerprogramm
untergebracht ist. Im EPROM müssen natür-lich beide Speicherinhalte
untergebracht werden, was die Suche nach dem Anfang des Interpreters
(zum patchen der Adressen) naturgemäß etwas schwieriger gestaltet,
eine feste Startadresse kann nicht angegeben werden, da es, bedingt
durch Korrekturen oder dem einbringen von benutzerdefiniereten
Änderungen (Treiber) immer wieder Verschiebungen geben kann.
Grundsätzlich beginnt der Interpreter aber immer auf einer 4kByte-

                                  -147-
Grenze (1000H, 2000H usw.) und zwischen Betriebsystem und Interpreter
ist üblicherweise eine Lücke, welche mit 0FFH gefüllt ist.

Findet man also im EPROM-DUMP folgende Zahlenfolge:
05FE0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
05FF0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
06000: C3 .. .. ..

so beginnt mit ziemlicher Sicherheit der Interpreter bei Adresse
6000H.

     Diese Adresse sollte man sich merken!

Alle absoluten Adressen die bei der Beschreibung von PROMIT angegeben
sind, gelten relativ zu dem notierten Interpreter-Anfang.
Ab der Startadresse des Interpreters werden 28kByte für den
Interpreter und 36kByte RAM eingeblendet. Für zu 'promende' Programme
ist der Bereich zwischen Interpreter-Ende und der Interpreter-
Start+7000H nutzbar.

Das Interpreter-Ende läßt sich an der Bytefolge 055H, 0AAH erkennen!
Der nutzbare EPROM-Bereich ist leider nur recht klein. Es ist jedoch
möglich eine EPROM-Version des MSRBASIC-Interpreters zu bekommen, in
welcher der RAM-Bereich auf 16kByte zugunsten eines freien EPROM-
Bereiches von 16kByte beschränkt ist.




                                -148-
10.4 Programme in EEPROM

Programme können bei MOPS-Systemen der A-Serie auch in EEPROMs
abgelegt werden. Der Programm-Transfer geschieht hier mit dem Befehl:
           EEPROMIT.

Als "Ziel" ist hier ein EEPROM (Typ 2864) in Sockel 2 verwendet
werden. Anstelle des EEPROMS sind auch NV-RAMs verwendbar.

Im EEPROM gespeicherte Programme werden bei jedem Neustart ausgeführt.
Sie können (wie alle Programme) mit CNTRL-C abgebrochen werden. Soll
das Programm im EEPROM geloescht werden, ist folgende Prozedur
auszuführen:

     a)    NEW
           EEPROMIT

           oder, nach Neustart

     b)    NOF
           EEPROMIT

Bitte beachten Sie, EEPROMs sind nur mit beschränkter Häufigkeit
löschbar!




                                 -149-
10.5 Entwicklungshilfen

Als Entwicklungshilfe bietet ELZET 80 Mikrocomputer das Programm
MSRSHELL mit dessen Hilfe MSRBASIC-Programme über eine RS232-
Verbindung zwischen jedem beliebigen MSRBASIC-System und einem PC
entwickelt werden kann. MSRSHELL übernimmt dabei die Funktion eines
Terminal-Emulators. Es können mit seiner Hilfe aber auch Programme auf
dem PC gespeichert oder vom PC geladen werden. Darüberhinaus ist in
PC-Shell ein wordstar(R)-ähnliches Editorprogramm eingebunden, welches
das Schreiben von Programmen sicherlich stark vereinfacht.
Für PROMIT-Dateien im INTEL-HEX-Format steht das Hilfsprogramm DEHEX
zu Verfügung, mit dessen Hilfe das INTEL-HEX-Format in "Normal-Daten"
rückgewandelt werden können.

Alle Hardware-abhängigen Treiber sind als Z80-Assembler Quelldateien,
der    (Hardware-unabhängige)    Interpreter-Kern     als    REL-Datei
(Mikrosoft(R) CP/M-Format) verfügbar. Diese Dateien enthalten alle
notwendigen Informationen und Daten um eine beliebige (Z80-kompatible)
Hardware anzupassen.

Der Assembler-Code wurde für den Z80-Macroassembler SLR180(R)
geschrieben der ebenfalls von ELZET 80 Mikrocomputer vertrieben wird.
Der   Microsoft  Assembler   M80   (R)  eignet   sich  (mit   einigen
Einschränkungen betr. der Geschwindigkeit und Code-unverträg-lichkeit
betr. einiger interner Abfragen (.PRINTX und .ACCEPT - diese müssen
'per Hand' aufgelöst werden - sowie dem bei SLR180 nicht notwendigen
".Z80"-Befehl) ebenfalls.
Als Linker eignet sich LINK(R), L80(R) und SLRLNK(R)

Ist kein CP/M-System vorhanden, so kann ein (Z80-)CP/M-Emulator auf
dem PC verwendet werden. (IPC-Z80 mit 8MHz von ELZET 80)




                                -150-
11. Fehlermeldungen


00   interner Konsistenzfehler beim Listen
01   inkompatibler Datentyp z.B.: x=a$
02   unerlaubte Kontrollvariable in PRINT- oder INPUT
03   nach END existiert noch eine Programmzeile
04   fehlerhafte Zeilennummer in GOTO etc.
05   gewünschte Zeilennummer existiert nicht
06   ein unerwartetes Zeichen verursacht den Fehler
07   eine Anweisung wurde nicht beendet
08   eine Anweisung wurde fehlerhaft formuliert
09   Fehler beim Wandeln einer numerischen Konstanten
10   eine Funktion wurde falsch benutzt (Seiten vertauscht o.Ä)
11   Feldzugriff stimmt nicht mit Felddeklaration überein
     (Dimensionalität bzw Datentyp)
12   Zugriff auf ein Datenfeld vor seiner Definition
13   Fehler bei der Bestimmung einer Zahl (zu groß)
14   unerlaubte Relation in einer IF/WAIT-Anweisung
15   Nummer eines Assembler-UP's nicht gefunden


FOR-NEXT-Fehler
16   fehlendes "=" in einer FOR-Anweisung
17   felendes TO oder STEP
18   Ineinanderschachteln von mehr als 10 Laufvariablen
19   NEXT wurde vor FOR ausgeführt
20   Laufvariable in FOR und NEXT stimmen nicht überein oder
     sind bereits vorhanden (Multitasking)
21   Laufvariable ist ein Vektor oder ein String
22   das gewünschte Vektorelement existiert nicht
23   Anzahl der übergebenen Parameter stimmt nicht
24   Dimensionen zweier Vektoren stimmen nicht überein
25   Fehler (hardware) im Ein-/Ausgabe-Verkehr
26   TASK bzw SEQuenz sollte (de)aktiviert werden, bevor sie
eingetragen war
27   WAIT als direkte Anweisung benutzt (nur TASK und SEQ)
28   Zeitüberschreitung beim Warten auf das Eintreffen einer
     Verriegelungsbedingung
29   Fehler bei der Bestimmung einer logischen Kanaladresse


Matrix-Vektor-Fehler
30   unerlaubter Operand in MAT-Anweisung
31   falsche Reihenfolge von MAT-Operatoren
32   inkonsistene Dimension auf der rechten Seite
33   Zielfeld zu klein dimensioniert
34   Vektor zu groß (>126) für MAT-Operation
35   Zielfeld auch auf der rechten Seite der MAT-Anweisung
36   zuwenig Speicher für Ablage der Zwischenergebnisse
37   interner Konsistentfehler (Entschuldigung!)


38   WAIT in GOSUB-Unterprogrammen nicht erlaubt
39   (reserviert)
40   Interpreter nicht im Echtzeit-Modus (FREEZE-Befehl     eingeben)
41   INPUT-Anweisung wurde zweimal aufgesetzt (Multitasking)
42   Timeout (Zeitüberschreitung) bei Ausgabe auf seriellem       Knl
                                                                  aa

                               -151-
78   interner Fehler




                       -152-
12. Stichwortverzeichnis

Ablaufsteuerungen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -24-
ABS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -122-
ACN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -122-
ACTIVATE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -35-
ADC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -46-
Anweisungen . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -17-
AS . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -97-
ASC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -124-
ASN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -122-
ATN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -122-
AUTO . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -131-
BGMEMCLEAR . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -76-
BGMEMDIM . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -67-
BGMEMFRE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -77-
BGMEMGETQ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -71-
BGMEMGETR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -68-
BGMEMPOP . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -73-
BGMEMPUSH . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -72-
BGMEMPUTQ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -70-
BGMEMPUTR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -67-
BGMEMSS . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -74-
BIT . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -43-
BITBUS-Anschluß . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -80-
BITRB . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -83-
BITRH . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -84-
BITRS . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -84-
BITRW . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -83-
BITWB . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -84-
BITWH . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -85-
BITWS . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -85-
BITWW . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -85-
BITZFLAG . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -83-
Boolsche Ausdrücke .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -44-
Buchstaben . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -17-
CALL . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -128-
CHR$ . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -123-
CLS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -132-
CNT . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -50-, -56-
COMMAND . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -101-
COS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -122-
Cursor-Positionierung   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -97-
DAC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -51-
DATE . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -61-
Datenstrukturen . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -17-
Datentypen . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -17-
DEFINE . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -31-
DIM . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -112-
DIN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -47-
DOUT . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -53-
DOW . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -61-
Echtzeit . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -24-
Editor . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   -17-, -21-
EEPROMIT . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -149-
Einfüge-Modus . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -21-
ELSE . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -108-
END . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -111-
Entwicklungshilfen .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -150-
EOF . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . -100-

                                            -153-
EPROM-startend . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -145-
EXP . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -122-
Fahrtregler . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -87-
Fehlermeldungen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -151-
Felder . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -18-
Fenstertechnik . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -92-
FOR . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -102-
Formatierung . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -97-
FRDEF . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -88-
FREEZE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -133-
FREEZE-Betrieb . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -23-
FRERROR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -90-
FRLDFAHRT . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -89-
FRLSFAHRT . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -89-
FRSETKI(ki . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -89-
FRSETKP . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -88-
FRSETP . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -88-
FRSTAT . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -89-
FTOI$ . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -124-
FTOIB . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -125-
Funktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -18-
GET . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -49-
GOSUB . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -105-
GOTO . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -107-
Hardware-Anpassung    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -143-
Hintergrundspeicher   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -66-
IF . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -108-
INCHAR$ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -100-
INPUT . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -95-
INSTR . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -123-
INT . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -122-
Kalender . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -60-
Kaltstart . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -20-
Kanalnummern . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -18-
Kommando . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -131-
Kommandos . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -18-
Kommentare . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -18-, -120-
LEFT$ . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -123-
LEN . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -123-
LET . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -114-
Linkadapter . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -79-
LIST . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -134-
LN . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -122-
LOAD . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -135-
LOG . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -122-
Logikfunktionen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -43-
LUAVAIL . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -79-
LUMODE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -78-
LUOPEN . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -78-
MADC . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -57-
MAT . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -116-
MDIN . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -57-
MDOUT . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -57-
MFREE . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -136-
MID$ . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . -123-
MSRTIMER . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -60-
MSTIMDIF . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -60-
NADC . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -58-
NCNT . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -58-
NDAC . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -58-
NDIN . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . . -58-

                                              -154-
NDOUT . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -58-
NEW . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -136-
NEXT . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -104-
NOFREEZE . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -136-
NOT . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -43-
NOTR . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -40-
NOTRACE . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -39-
NWIN . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -93-
ON . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -97-
ONERROR . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -130-
Operatoren . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -19-
PEEK . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -65-
POKE . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -119-
Portadressen . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -144-
POS . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -87-
POSSRN . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -88-
POSTYPE . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -87-
PRINT . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -97-
Programm . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -19-
Programmiertips . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -138-
PROMIT . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -146-
PUT . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -55-
Reglerfunktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -62-
REM . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -120-
RETURN . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -106-
RIGHT$ . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -123-
RUN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -136-
SAVE . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -136-
Schnittstellenfunktionen    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -100-
Sedezimal-Wert . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -21-
SEQLIST . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -42-
SEQuenz . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -24-
SIN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -122-
Speicherfunktionen . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -65-
SQR . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -122-
START . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -33-
Starten . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -19-
STATUS . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -101-
Steuerzeichen . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -22-
STOP . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -110-
Stringfunktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -123-
SUSPEND . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -34-
Syntaxfehler . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -22-
SYSTEM . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -137-
Systemanalyse . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -138-
Tabellierung . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -97-
TAN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -122-
TASK . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -24-
TDOWN . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -59-
THEN . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -108-
TIME . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -60-
TIMEFAC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -59-
TRACE . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -39-
TRACE-Modus . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -40-
Transparent-Betrieb . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -20-
TUP . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -59-
Uhrzeit . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -60-
USR . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -126-
VAL . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -123-
Variable . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -20-
VCL . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -137-

                                        -155-
VEC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    -117-
WAIT . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -36-
Warmstart . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -20-
WINDOW . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -93-
Zahlenbereich . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -21-
Zeilennummer . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -17-
Zeitgeberfunktionen .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . -59-
Ablaufsteuerungen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 15
ABS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 114
ACN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 114
ACTIVATE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 26
ADC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 37
Anweisungen . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 8
AS . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 89
ASC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 116
ASN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 114
ATN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 114
AUTO . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 123
BGMEMCLEAR . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 67
BGMEMDIM . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 58
BGMEMFRE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 68
BGMEMGETQ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 62
BGMEMGETR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 60
BGMEMPOP . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 64
BGMEMPUSH . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 63
BGMEMPUTQ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 61
BGMEMPUTR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 59
BGMEMSS . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 65
BIT . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 34
BITBUS-Anschluß . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 71
BITRB . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 74
BITRH . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 75
BITRS . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 75
BITRW . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 74
BITWB . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 76
BITWH . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 76
BITWS . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 77
BITWW . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 76
BITZFLAG . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 74
Boolsche Ausdrücke .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 35
Buchstaben . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 8
CALL . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 120
CHR$ . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 115
CLS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 124
CNT . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   41, 47
COMMAND . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 93
COS . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 114
Cursor-Positionierung   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 89
DAC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 42
DATE . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 52
Datenstrukturen . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 9
Datentypen . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 8
DEFINE . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 22
DIM . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 104
DIN . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 38
DOUT . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 44
DOW . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 52
Echtzeit . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 15
Editor . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    9, 13
EEPROMIT . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 141
Einfüge-Modus . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 13

                                            -156-
ELSE . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 100
END . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 103
Entwicklungshilfen    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 142
EOF . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 92
EPROM-startend . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 137
EXP . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 114
Fahrtregler . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 79
Fehlermeldungen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 143
Felder . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 9
Fenstertechnik . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 84
FOR . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 94
Formatierung . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 90
FRDEF . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 80
FREEZE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 125
FREEZE-Betrieb . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 14
FRERROR . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 82
FRLDFAHRT . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 81
FRLSFAHRT . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 81
FRSETKI(ki . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 81
FRSETKP . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 81
FRSETP . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 80
FRSTAT . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 82
FTOI$ . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 116
FTOIB . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 117
Funktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 9
GET . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 40
GOSUB . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 97
GOTO . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 99
Hardware-Anpassung    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 135
Hintergrundspeicher   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 57
IF . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 100
INCHAR$ . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 92
INPUT . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 87
INSTR . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 116
INT . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 114
Kalender . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 51
Kaltstart . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 11
Kanalnummern . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 9
Kommando . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 123
Kommandos . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 10
Kommentare . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    10, 112
LEFT$ . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 115
LEN . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 115
LET . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 106
Linkadapter . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 70
LIST . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 126
LN . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 114
LOAD . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 127
LOG . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 114
Logikfunktionen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 34
LUAVAIL . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 70
LUMODE . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 69
LUOPEN . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 69
MADC . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 48
MAT . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 108
MDIN . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 48
MDOUT . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 48
MFREE . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 128
MID$ . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . 115
MSRTIMER . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 51
MSTIMDIF . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . . . 51

                                              -157-
NADC . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 49
NCNT . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 49
NDAC . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 49
NDIN . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 49
NDOUT . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 49
NEW . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    128
NEXT . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 96
NOFREEZE . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    128
NOT . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 34
NOTR . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 31
NOTRACE . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 31
NWIN . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 85
ON . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 89
ONERROR . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    122
Operatoren . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 10
PEEK . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 56
POKE . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    111
Portadressen . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    136
POS . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 79
POSSRN . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 80
POSTYPE . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 80
PRINT . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 89
Programm . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 10
Programmiertips . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    130
PROMIT . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    138
PUT . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 46
Reglerfunktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 53
REM . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    112
RETURN . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 98
RIGHT$ . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    115
RUN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    128
SAVE . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    129
Schnittstellenfunktionen    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 92
Sedezimal-Wert . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 12
SEQLIST . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 33
SEQuenz . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 15
SIN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    114
Speicherfunktionen . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 56
SQR . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    114
START . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 24
Starten . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 11
STATUS . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 93
Steuerzeichen . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 13
STOP . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    102
Stringfunktionen . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    115
SUSPEND . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 25
Syntaxfehler . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 14
SYSTEM . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    129
Systemanalyse . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    130
Tabellierung . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 89
TAN . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    114
TASK . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 15
TDOWN . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 50
THEN . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    100
TIME . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 51
TIMEFAC . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 50
TRACE . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 30
TRACE-Modus . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 31
Transparent-Betrieb . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 12
TUP . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 50
Uhrzeit . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 51

                                        -158-
USR . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    118
VAL . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    115
Variable . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 12
VCL . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    129
VEC . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    110
WAIT . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 27
Warmstart . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 11
WINDOW . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 85
Zahlenbereich . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 12
Zeilennummer . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 8
Zeitgeberfunktionen   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 50




                                              -159-
13. Anhang
      Erweiterungen des MSR-Basic für Z280 CPU (TSM/ECB)

1. Neuerungen bei MSR-Basic V4.2,00 . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.1. IF-ELSE-ENDIF . . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.2. ONERROR Änderung. . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.3. INPUT Anweisung . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.4. SEQSTATE und TASKSTATE Funktionen                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.5. FORBID und PERMIT Anweisungen . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.6. Logische Operatoren AND und OR. .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   1.7. STDSET. . . . . . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
2. Hintergrundspeicher für MSR-Basic. . . . . . . . . . . . . . . . . . . .
   2.1. Einrichten eines Hintergrundspeichers . . . . . . . . . . . . . . .
   2.2. Wahlfreie Zugriff (Random Acess). . . . . . . . . . . . . . . . . .
   2.3. Zugriff auf Queues. . . . . . . . . . . . . . . . . . . . . . . . .
   2.4. Zugriff auf Stacks       . . . . . . . . . . . . . . . . . . . . . . . .

   2.5. Hilfsfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . .
   2.6. Flash-EPROM Hintergrundspeicher . . . . . . . . . . . . . . . . . .
   2.7. Neue E/A-Funktionen für TSM-8AD8
3. Programmspeicherung in Flash-EPROM . . . . . . . . . . . . . . . . . . .

4. CNT-Zähler und EVCTR Funktion             . . . . . . . . . . . . . . . . . . . . .

5. Neue Timer Funktionen. . . . . . . . . . . . . . . . . . . . . . . . . .
6. MODEM-Hilfsfunktionen.    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   6.1 LUMODE Funktion. .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   6.2 LUOPEN Funktion. .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
   6.3 LUAVAIL Funktion .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
7. LINKADAPTER. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8. Bemerkungen zur Programmspeicherung in ein EPROM . . . . . . . . . . . .

9. Fahrtregelung mit Gleichstrommotoren . . . . . . . . . . . . . . . . . .

10. BITBUS Komunikation. . . . . . . . . . . . . . . . . . . . . . . . . . .
11. Neue, zusätzliche Funktionen . . . . . . . . . . . . . . . . . . . . . .

12. Programmerhalt




                                             Seite 160
1. Neuerungen beim MSR-Basic V4.2,00
In allen früheren MSR-Basic Versionen unterscheidet man zwischen
Hauptprogramm, Sequenen und Tasks.
Dabei war durch den unübersichtlichen Schedule-Mechanismus nicht
vorhersehbar welchen zeitlichen Anteil dem Hauptprogramm zugewiesen
wird.
Also das Hauprogramm eignete sich lediglich zur Definition von
Sequenzen und Task und dessen Start.
In   der  Version   V4.2  wurde   das  Hauptrogramm   einer  Sequenz
gleichgestellt.
Das bedeutet, daß das Hauptrogramm immer den gleichen zeitlichen
Anteil zur Ausführung bekommt wie andere definierte Sequenzen, oder
auch in WAIT-Zustand übergehen kann, was früher nicht möglich war.
Die Numerierung der Sequenzen ist gleichgeblieben (#1..#25).
Dazugekommen ist die Sequenz #0, also das Hauptprogramm.

Ein GOSUB führte dazu, daß der Schedule Mechanismus außer Kraft
gesetzt wurde, bis das Unterprogramm beendet war. Also, wenn z.B. eine
Sequenz ein GOSUB ausführte, wurden alle Task und Sequenzen angehalten
!!!!!
Das schränkte die Anwendung von Unterprogrammem sehr ein, aber hatte
dabei eine nützliche Eigenschaft das es möglich war durch ein
Unterprogramm z.B. Impulse mit fester Länge zu erzeugen ohne alle
Task/Sequenzen anzuhalten und wieder zu aktivieren. In der neuen
Version darf ein man Unterprogramme verwenden ohne das der Scheduler
angehalten wird, weil jede Task/Sequenz ein eigenes GOSUB-Stack
besitzt. Lediglich dürfen Unterprogramme nicht beliebig andere
Unterprogramme aufrufen. Die Schachtelungstiefe ist auf 4 begrenzt
oder auf 3 wenn man ONERROR Anweisung benutzt. Es muß immer die
Aufrufmöglichkeit eines ONERROR-Unterprogramms bestehen.
Den Scheduler anzuhalten ist weiterhin möglich, aber nicht mehr durch
den GOSUB-Trick sondern durch neue Anweisung FORBID. Die ebenfalls
neue Anweisung PERMIT löst die Schedule-Sperre wieder auf.

Die Ausdruckanalyse lief bis jetzt auch nicht immer korrekt.
Ein Funktionsaufruf der als Parameter wiederum eine Funktion hatte
führte manchmal zu falschen Ergebnissen. Ganz besonders die
Stringfunktionen machten diesen Fehler. Bei der neuen Version würde
die Ausdruckanalyse ebenfalls umgeschrieben.
Die Ausdruckanalyse hat nicht mehr den iterativen sondern recursiven
Charakter.   Diese   Analyse   unterscheidet  neben   Gleitkomma   und
Stringausdrücken auch Festkommausdrücke (long-integer). Das bedeutet
daß Summen und Produkten von Funktionen, System-Variablen und Integer-
Konstanten viel schneller berechnet werden. Leider sind noch keine
Festkommavariablen möglich so daß
bei einer Variablenzuweisung ein Festkommaausdruck in Gleitkommawert
umgewandelt werden muß, oder das Vorhandensein einer Variable im
Ausdruck, den Ausdruck automatisch den Gleitkommatyp gibt.
!!! ACHTUNG !!!
Durch die Festkommaarithmetik können unerwünschte Nebeneffekte
auftreten die früher nicht bekannt waren.
Eine Konstante ohne einem Dezimalpunkt ist ein Festkommaausdruck,
daher ist z.B. (1/10) auch ein Festkommaausdruck.
Weist man einer Gleitkommavarible den Wert (1/10) zu, so bekommt sie
den
Wert (0) zugewiesen!!!.
Man sollte in solchen Fällen explizit statt (1/10), (0.1) eingeben
oder wenigstens eine Gleitkommakonstante verwenden z.B. (1/10.0) oder
(1.0/10).


                              Seite 161
Seite 162
1.1 IF-ELSE-ENDIF
Neben einem einzeiligen IF...THEN...ELSE... Konstrukt ist ab Version
V4.2
das mehrzeilige IF.../ELSE.../ENDIF Block möglich.
Beispiel:

100 IF a=1              ' Kein THEN also ENDIF muß folgen!
110   a = a-1
120   b = b+1
130 ELSE
140   a = 1
150   b = b+2
160 ENDIF


1.2 ONERROR Änderung

Ab Version V4.2 wird das Scheduling während des Ausführung eines
Unterprogramms nicht mehr angehalten.
Das bedeutet daß bei der Ausführung eines ONERROR-Unterprgramms die
Möglichkeit bestehen würde daß ONERROR-Unterprogramm vom mehren Tasks
oder Sequenzen nebenläufig ausgeführt würde. Der Interpreter würde es
zwar
korrekt ausführen, aber für jede Anwendung wäre es ziemlich
problematisch.
Daher wird vor jeder Ausführung eines ONERROR-Unterprogramms
automatisch die FORBID Anweisung ausgeführt. Das Bedeutet daß ein
ONERROR-Unterprogramm nicht durch eine TASK oder Sequenz unterbrochen
wird was wiederum ein Aufruf vom ONERROR-Unterprogramm auslösen
könnte.
Weiterhin ist eine Termination sichergestellt wenn ein Fehler in einem
ONERROR-Unterprogramm selbst ausgelöst wird.
Im Handbuch wird nicht beschrieben das die Möglichkeit die
Fehlernummer auszulesen (ERRVAR Variable).
In ERRVAR wird die Fehlernummer gespeichert bevor das ONERROR
Unterprogramm
ausgeführt wird.

Ein Beispiel für ONERROR-Unterprogramm.

         1000      REM      ****      ONERROR-Unterprogramm
***********************************
  1010 PRINT "*** FEHLER #";ERRVAR
...
... Eventuelle Aktionen, abhängig vom Fehlernummer
...
  1280 PERMIT
  1290 RETURN
Der Befehl PERMIT hebt die Schedule-Sperre wieder auf.
PERMIT sollte in einem solchen Unterprgramm immer kurz vor RETURN
Anweisung stehen.


1.3 INPUT Anweisung
Die INPUT Anweisung war schon immer ein Bestandteil von MSR-Basic.

                              Seite 163
Leider war seine Anwendung in einem Multitasking Programm nur bedingt
brauchbar, weil das Schedule Mechanismus bis zu Eingabe von <RETURN>
angehalten würde.
Ab Version V4.2 ist eine neu konzipierte INPUT Anweisung verfügbar
die wenig zum Wünschen übrig läßt.

Beim ausführen von INPUT Anweisung geht die ausführende Sequenz in ein
Wait-Zustand über.
Das bedeutet das die Tasks weiterhin eine INPUT Anweisung nicht
Ausführen dürfen. Das Hauptprogramm wird ab Version V4.2 wie eine
Sequenz behandelt, also es gibt ja auch keine Einschränkung bezüglich
der Anwendung.
Der WAIT-Zustand in die eine Sequenz übergeht kann optional zeitlich
überwacht werden. Damit kann man leicht verhindern daß eine Sequenz
ewig auf eine Eingabe wartet. Des weiteren, man kann optional, das
Fehlerbehandlung bei der Eingabe selbst gestalten. Also, man kann das
standard Mechanismus wo die INPUT-Anweisung, nach vorherigen Meldung:
"INPUT Fehler", wiederholt wird, durch eigene Fehlerbehandlung
ersetzen.
Weiterhin ist es jetzt auch möglich Bildschirmausgaben zu machen
während in einem anderem Teil des Bildschirms eine INPUT-Zeile
editiert wird.
Diese   nebenläufige   Bildschirmausgabe    wird   jedoch   nur   dann
funktionieren wenn man kein Semikolon am Ende der PRINT-Anweisung
verwendet.

Die neue Syntax lautet:

 INPUT [ ON(Kanal ] [ [Y,X] ] [ MAX Wert ] <Variablenliste> [ ELSE
Anweisung]

Unter <Variablenliste> ist eine oder mehrere, durch Komma getrennte
numerische oder Stringvariablen gemeint.
Die Eingabe sollte bei mehreren Variablen auch durch Komma getrennt
werden.
Bei Numerischen Variablen ist nur eine Numerische Darstellung einer
Zahl erlaubt und sollte einer Stringvariable das Kommazeichen auch
zugewiesen werden so kann die Eingabe in Anführungsstriche geklammert
werden.
Beispieleingabe für Variablenliste <a,a,a$>:
     >1111.0, 222,"Komma,Komma"<

Unvollständige Eingaben oder unkorrekte Numerische Darstellung führen
zu einem Fehlerfall!


Die Optionen:
                [ ON(Kanal) ]

Soll die Eingabe auf einem anderem Kanal erfolgen als LU(0), so ist
diese Option zu wählen. So werden bei "INPUT ON(2) a" alle Eingaben
und Ausgaben auf LU(2) erfolgen.

                [ [Y,X] ]

Stellt den Cursor auf eine bestimmte Y,X Position des Bildschirms.

                                Seite 164
Auf dieser Position kann man dann die Werte eingeben.
Obwohl andere Sequenzen oder Task Bildschirmausgaben parallel dazu
machen wird die eingestellte Position beibehalten. Vorausgesetzt daß
PRINT-Anweisungen ohne Semikolon verwendet werden!.
                 [ MAX Wert ]

Die INPUT-Anweisung wird Zeitlich überwacht. Durch <Wert> bestimmt man
wieviel Sekunden maximal das Eingabegerät ruhen darf. Die INPUT
Anweisung selber kann vielfaches davon aktiv bleiben, aber einzelne
Pausen bei der Eingabe dürfen den Limit nicht überschreiten.


                 [ ELSE Anweisung ]

Programmabschnitt nach <ELSE> wird nicht berücksichtigt wenn die
Eingabe erfolgreich abgeschlossen würde. Würde die Zeitliche
überwachung aktiviert und überschritten oder die Eingabe falsch oder
unvollständig gemacht so wird keine Fehlermeldung ausgegeben und die
INPUT-Anweisung   wiederholt,    sonder   dieser   Programmabschnitt
ausgeführt.
Zweckmäßig sollte dort eine GOTO Anweisung stehen, aber auch andere
Anweisungen sind zulässig.
Beispiel für eine INPUT-Anweisung mit Optionen:

11000   PRINT "Geben Sie Bitte Name,Vorname und Alter ein: ";
11010   INPUT MAX 10 Name$,Vorname$,Alter ELSE GOTO 11110


1.4 SEQSTATE und TASKSTATE Funktionen

Es ist manchmal nützlich zu wissen ob eine Sequenz oder Task aktiv
ist.
Zwar ließ sich daß immer durch Benutzung von Variablen realisieren,
doch jetzt ist es bequemer und sicherer.
Als Parameter gibt man eine Sequenz oder Tasknummer und bekommt zurück
ein Zustandswert, der folgende Bedeutung hat:


    0: Sequenz oder Task nicht Aktiv.
    1: Sequenz oder Task ist aktiv
    2: Nur bei Sequenzen. Sequenz ist aktiv und wartet auf ein Zustand
       (WAIT oder INPUT Anweisung gerade in Bearbeitung).
Beispiel: Von einer Sequenz soll ein TASK gestartet werden, die
Sequenz selber hat dann nichts zu tun und soll solange in Wartezustand
übergehen.
    1000 START TASK 1
    1010 WAIT FOR TASKSTATE(1) = 0
    1020 PRINT "O.K."

1.5 FORBID und PERMIT Anweisungen
Das Multitasking bringt viele Vorteile mit sich. Es gibt jedoch
Anwendungen bei denen für kurze Zeit das Schedulemechanismus sehr
stört.
Z.B. bei Erzeugung von Programmgesteurten Impulsen oder bei einem
Fehlerfall wo alle TASK/SEQUENZ Aktionen kurz angehalten werden

                                Seite 165
sollen.
Zwar ließ es sich immer mit SUSPEND TASK ALL und SUSPEND SEQ ALL
alle Tasks und Sequenzen anzuhalten, aber dadurch war nur der
Hauptprogramm blieb dann aktiv und es war nicht mehr möglich den
ursprünglichen Zustand herzustellen. ACTIVATE TASK ALL würde alle
TASKs aktivieren unabhängig davon ob sie vorher schon mal aktiv waren
oder nicht.

Bei Ausführung der FORBID Anweisung wird also wirklich das
Schedulemechanismus   angehalten.   Nach   dieser   Anweisung   wird
ausschließlich der Programmteil, der diese Anweisung enthalten hat,
ausgeführt.
Die Anweisung PERMIT hebt die Sperre wieder auf, und alles kehrt zum
ursprünglichen Zustand.

Wie schon erwähnt, es gibt ein Sonderfall wo die FORBID Anweisung
automatisch ausgeführt wird. Und zwar vor der Ausführung eines ONERROR
Unterprogramms.
Daher sollte man in der Regel nicht vergessen ein PERMIT Anweisung
auszuführen vor einer RETURN Anweisung des Unterprogramms.

Noch ein schlechtes Beispiel zur Warnung:
    1000   a = 0
    1010   FORBID
    1020   WAIT FOR a>0
    1030   PERMIT
Wie man leicht erkennen kann ist dieser Beispiel das Ende eines
Programms.
Obwohl vorher alles schalten und walten vermag tut sich bereits nach
der dritten Zeile nichts mehr. Dieser Teil einer Sequenz wird nach der
FORBID Anweisung der einziger ausgeführte Programmteil, und geht
sofort in ein WAIT-Zustand der nie beendet wird!!!

1.6 Logische Operatoren AND und OR

Eine Einschränkung bei MSR-Basic war das fehlen der bekannten AND oder
OR Operatoren. Nun gilt diese Einschränkung nicht mehr.
Diese Operatoren sind z.Z. nur als logische Operatoren die zusammen
mit Relationen in einer IF oder WAIT Anweisung verwendet werden
können, nicht aber für eine Verknüpfung zweier Werte bitweise. Das
macht nur ein Sinn mit Ganzzahligenwerten und solange keine
Ganzzahlige Variable eingeführt sind
würde es nur wenig ausgenutzt werden können.
Die Rangfolge dieser Operatoren ist nach der Relationen und beliebige
Klammerung ist erlaubt.

Beispiel:
    1000 IF DIN(NotAus) OR (DIN(Vent1) = 0 AND DIN(Vent2) = 0)
    1010 PRINT "Notschalter EIN, oder beide Ventile ausgeschaltet!!"
    1020 ENDIF

1.7 STDSET Anweisung
Die neue Anweisung STDSET soll der allgemeiner Voreinstellung dienen.
Bis jetzt ist nur der Format bei Ausgabe von numerischen Werten
voreinstellbar, und die Syntax lautet:
  STDSET AS xxx

                              Seite 166
wobei xxx die Formatbeschreibung ist die sonst hinter AS erlaubt ist.
Sollen in einem Programm nur Werte in sechsstelligen Festkommaformat
ausgegeben werden so braucht man nicht mehr hinter jeder PRINT
Anweisung
"AS 6I" einzugeben wenn man am Programmanfang mit "STDSET AS 6I"
dieses Format eingestellt hat.

Ein weiteres Nutzen dieser Anweisung ist es, daß damit auch die STR$
Funktion beeinflußt wird. Bis jetzt lieferte diese Funktion einen
String welcher gleich war mit Ausgaben der PRINT Anweisung ohne <AS
xxx> Formatangabe.
Meist müsste ein solcher String weiterbearbeitet werden z.B. wenn man
nur die
zwei Vorkommaziffer benötigte.
Nun, jetzt kann man das Format einstellen und dieses Format wird auch
für die STR$ Funktion verwendet.
Beispiel:

Ein Programm soll über LU(2) Steuersequenzen ausgeben. Eine Sequenz
besteht    aus    einem   <ESC>    Zeichen   gefolgt   von    einer
Befehlsbuchstabe,Parameter und <CR> Zeichen. Der Parameter besteht
immer aus zwei Hexadezimalziffern.
 10000   PRINT ON(2) CHR$(&H1B)$;     ' <ESC> Zeichen
 10010   PRINT ON(2) Cmd$;            ' Kommandobuchstabe
 10020   STDSET AS 02H               ' Format = 2 Stellen, Hexadezimal
 10030   PRINT ON (2) STR$(Wert);     ' Parameter ausgeben
 10040   STDSET AS 6I                 ' wieder Normale Einstellung
 10050   PRINT ON (2) CHR$(&H0D);     ' Abschlusszeichen <CR>




                               Seite 167
2. Hintergrundspeicher für MSR-Basic
MSR-Basic wurde ursprünglich für den Betrieb mit sehr wenig
Hauptspeicher entwickelt. Es kann meist ein Bereich von 32 KByte für
MSR-Programme und Daten genutzt werden. Um in Applikationen der
Meßwerterfassung auch mit größeren Datenmengen umgehen zu können,
wurde für den Prozessor Z280 eine Erweiterung des MSR-Basic
vorgenommen. Die neuen Funktionen erlauben die Einrichtung und das
Einfügen/Entfernen von Daten aus einem Hintergrundspeicher.
Ein Hintergrundspeicher kann als Feld von Datenstrukturen aufgefaßt
werden.
Es können auch mehrere Hintergrundspeicher definiert werden, deren
Datenstruktur unabhängig voneinander sind.
Auf den Hintergrundspeicher kann direkt (wahlfrei), als Stack oder als
Queuezugegriffen werden. Alle Zugriffsarten können auch gemischt
werden, was besonderes dann sinnvoll ist, wenn die Daten eines Stacks
oder Queue verarbeitet werden sollen, ohne sie aus dem Hintergrund zu
entfernen.
Es können maximal 8 Hintergrundspeicher definiert werden, deren Größe
nur durch den verfügbaren Speicherplatz begrenzt wird. Bei TSM wird
bei dem Hintergrundspeicher Nr. 0 der Speicherbereich eines
Flash-EPROM genutzt. Somit bleiben dort eingeschriebene Daten
dauerhaft erhalten.
2.1. Einrichten eines Hintergrundspeichers

   BGMEMDIM(n, e, var_liste)
Dimensioniere den Hintergrundspeicher n als Feld mit e Strukturen.
Jede Struktur hat seinen Aufbau wie var_liste.
n         : Nummer des Hintergrundspeicher (0..7).
e         : Anzahl der Strukturen, die der Hintergrundspeicher fassen
soll.
var_liste : Aufzählung der Variablentypen.
Die Namen der Variablen in var_liste haben keine Bedeutung.
Nur der Typ dieser Variablen wird benötigt, um den Strukturellen
Aufbau und Platzbedarf bestimmen und Initialisierung durchführen zu
können.

Folgende Typen sind z.Z. zugelassen:
a$(n)   : String der max. n-Buchstaben aufnehmen kann.
a       : Gleitkommazahl.
a(n)    : Feld von Gleitkomazahlen mit der Dimension n.

Initialisierung:
Strings werden mit dem Zeichen "-" gefüllt. Gleitkommazahlen werden
mit der größten negativen Zahl initialisiert.


Der    Hintergrundspeicher    in   Flash-EPROM    hat    abweichende
Initialisierung.
Flash-BGM (Hintergrundspeicher Nr.0 bei TSM) ist immer definiert.
Notwendig ist nur eine Dimensionierung. Nach einem BGMEMDIM(0,...)
Statement wird der Flash-BGM nicht gelöscht sondern untersucht ob er
Strukturen enthaltet. Also, mehrfaches Dimensionieren ist zulässig.
Löschen des Flash-BGM muß separat mit BGMEMCLEAR(0) Statement
durchgeführt werden.
Beispiel für BGMEMDIM:

                               Seite 168
BGMEMDIM(1,100,a$(8),a,a,a(10))

Hintergrundspeicher '1' enthält 100 Strukturen, der Form:
string[8]   :   String mit max. 8 Zeichen
float       :   Gleitkommazahl
float       :   Gleitkommazahl
float[10]   :   Feld von 10 Gleitkommazahlen



2.2. Wahlfreier Zugriff (Random Access)


BGMEMPUTR(n,c,var_liste)
Lege die Parameter (var_liste) in Struktur c von Hintergrundspeicher
n ab.

n         : Nummer des Hintergrundspeicher.
c          : Nummer der Struktur in diesem Hintergrundspeicher
var_liste : Aufzählung der Variablen/Ausdrücke.
Die Typen der Parameter in var_liste müssen gleich sein mit den Typen
derStrukturelemente von diesem Hintergrundspeicher.
Beispiel:
   BGMEMPUTR(0,2,"09:22:32", 3*varb, varc, varar())
Der letzte Parameter varar() hat in den Klammern keinen Indexnummer
weil hier kein Element des Feldes gemeint ist, sondern das Feld als
ganzes !
 BGMEMGETR(n,c,var_liste)
Setze Variablen (var_liste) aus Struktur c in Hintergrundspeicher n.

n         : Nummer des Hintergrundspeicher.
c         : Nummer der Struktur in diesem Hintergrundspeicher
var_liste : Aufzählung der Variablen.


Beispiel:

     BGMEMGETR(0,2,a$, varb, varc, varar())

2.3. Zugriff auf Queues
   BGMEMPUTQ(n,var_liste)

Verschiebe alle Strukturen in Richtung der letzten Struktur. Lege
Inhalt der Parameter (var_liste) in der ersten Struktur des
Hintergrundspeicher n ab.
Dabei geht der Inhalt der letzten Struktur verloren, falls der
Hintergrundspeicher voll belegt war.

   BGMEMGETQ(n,var_liste)

Hole Inhalt der Variablen (var_liste) aus der letzten gültigen
Struktur.
Diese Struktur wird dabei als ungültig erklärt. Zusammen mit dem

                                Seite 169
BGMEMPUTQ Statement    wird   damit   ein   first-in/first-out   Speicher
realisiert.

2.4. Zugriff auf Stacks
   BGMEMPUSH(n,var_liste)

Verschiebe alle Strukturen in Richtung der letzten Struktur. Lege
Inhalt der Parameter (var_liste) in der ersten Struktur des
Hintergrundspeicher n ab.
Dabei geht der Inhalt der letzten Struktur verloren, falls
Hintergrundspeichervoll belegt war.

   BGMEMPOP(n,var_liste)
Hole Inhalt der Variablen (var_liste) aus der ersten Struktur des
Hintergrundspeicher n. Die erste Struktur wird dabei aus dem
Hintergrundspeicher entnommen und die restlichen Strukturen werden in
Richtung der ersten Struktur verschoben. Mit diesem Statement zusammen
mit BGMEMPUSH ein first-in/last-out Speicher (Stack) realisiert.
2.5. Hilfsfunktionen

   BGMEMSS(n)
Gebe Anzahl der gültigen Strukturen in Hintergrundspeicher n zurück.
Das BGMEMPUSH und das BGMEMPUTQ Statement verursacht ein Fehlerfall
wenn der ganzer Hintergrundspeicher nur gültige Strukturen enthält und
es folglichbeim einfügen einer neuen Struktur zum Überschreiben der
letzten Datenstrukturkommen würde. Um solche Situationen zu vermeiden
gibt es diese Funktion dieeinen Auskunft über dem Anzahl der gültigen
Strukturen zurückgibt.
Beispiel:
   sbel = BGMEMSS(0)

   BGMEMCLEAR(n)
BGMEMCLEAR löscht den Hintergrundspeicher n. Alle Daten werden wie bei
BGMEMDIM initialisiert. Die Struktur des Speichers bleibt erhalten.

   BGMEMFRE(n)

BGMEMFRE gibt ein Hintergrundspeicher frei.
Der belegter Speicher kann für andere Hintergrundspeicher verwendet
werden.
Der Hintergrundspeicher existiert nicht mehr nach diesem Statement
undmuß neu Dimensioniert werden.
2.6. Flash-EPROM Hintergrundspeicher

Der Hintergrundspeicher #0 ist beim TSM als Flash-EPROM Speicher
realisiert.
Flash-EPROM ist für Hintergrundspeicher verfügbar wenn dort kein
Programm gespeichert ist oder es wird ein 28F010 (120 KByte) Typ
verwendet. Dazu gibt es kleine Unterschiede:Der Speicher bleibt
dauerhaft erhalten auch wenn der Speicheraufbauverloren gehen soll.
Mehrfaches Dimensionieren löscht den Speicher nicht.
Ein BGMEMGETQ und BGMEMPOP Statement können nicht benutzt werden.
Strukturen können nicht übeschrieben oder entnommen werden.
Lesen ist nur Wahlfrei möglich (BGMEMGETR Statement).

                               Seite 170
Beispiel:

   BGMEMDIM(0,200,a$(40))
   BGMEMPUTQ(0,"Erste Struktur")
   BGMEMPUTQ(0,"Zweite Struktur");
   bel = BGMEMSS(0)
   BGMEMGETR(0,0,a$)
   REM a$ ist gleich "Erste Struktur" und bel ist gleich 2
   BGMEMGETR(0,bel-1,a$)
    REM a$ ist gleich der zuletzt geschriebenen String = "Zweite
Struktur"

2.7. Neue E/A-Funktionen für TSM-8AD8

     KTY8(n)

Gibt einen Temperaturwert am Eingang n einer 8AD8/KTY Baugruppe
zurück.
Ein gemessener Rohwert x wird als (x/2)-25.0 zurückgegeben, was bei
der Standardbeschaltung der 8AD8/KTY der Temperatur in EC entspricht.


     TCK8(n)
     TCJ8(n)

Beide Funktionen sind mit der KTY8(n) Funktion vergleichbar, nur wird
hier eine Linearisierung von Thermoelementen vorgenommen. Mit TCK8
wird die Temperatur eines Elements vom Typ K angezeigt, bei TCJ8 die
eines Typ-J-Elements.




                              Seite 171
3. Programmspeicherung in Flash-EPROM

Beim Einsatz von 28F256 Flash-EPROM (32 KByte) kann dieser zur
Programmspeicherung oder für Hintergrundspeicher verwendet werden. Ein
28F010 (120 KByte) Typ wird automatisch erkannt und für beides
gleichzeitig    verwendet.    Programmspeicherung    32    Kbyte   und
Hintergrundspeicher 96 Kbyte.
Ein Programm wird in Flash-EPROM mit dem Kommando FEPROMIT
gespeichert.
Dabei wird der ganze EPROM gelöscht. Jedoch falls genügend RAM
vorhanden istwird der Inhalt des Hintergrundspeichers dort kopiert und
wieder in EPROMgeschrieben. Gleiches wird passieren beim BGMEMCLEAR(0)
Statement mit dem Programmbereich.
Löschen von Programmen in Flash-EPROM kann man auch mit dem FEPROMIT
Kommando erreichen wenn kein Programm in Speicher vorhanden ist.

Z.B.
   NOF      ' NOFREZZE Betriebsart
   NEW      ' Programm löschen
   FEPROMIT ' und Speichern (nur Flash-EPROM löschen)




                              Seite 172
4. CNT-Zähler und EVCTR Funktion
Standardmäßig werden insgesamt 8 Zähleingänge unterstützt. Diese
Eingänge befinden sich auf dem CPU Modul (8E24) und werden gemeinsam
mit dem DIN-Treiber abgefragt. Also CNT(1) und DIN(1) beziehen sich
auf dem ersten Eingang, wobei die CNT-Funktion die anliegende Frequenz
und die DIN-Funktion den momentanen Pegel. Diese Zähler können recht
hohe   und   unsymmetrische    Frequenzen   messen   die   nur   durch
Eingangsbeschaltung (Filter o.ä) begrenzt werden. Die Torzeit beträgt
bei allen Zählern 100ms. Also, CNT(n) gibt die anliegende Frequenz/10
zurück.
Ab Version 4.1,87 ist die CNT Funktion modifiziert.
Jetzt ist sie nicht mehr eine Vektorfunktion mit dem Bereich -
32768..32767
sodndern eine Standartfunktion mit dem Wertbereich 0..16777215
(unsigned 24Bit Darstellung).
Eine Möglichkeit einer Zuweisung wie CNT(x)=y ist nicht mehr möglich
aber kann bei Bedarf durch eine Funktion SETCNT(x,y) wieder verfügbar
gemacht werden.

Ausser   dem   Frequenzmessen    kann   einer   der   Eingänge  zur
Erreignisszählung herangezogen werden. Dabei ist eine gleichzeitige
Frequenzmässung auf einem anderen Eingang nicht möglich.

Die Umstellung der Arbeitsweise der CNT Funktion wird duch eine neue
Funktion <EVCTR(n)> bewerkstelligt.

Der Parameter n entspricht dem Eingangsnummer      (DIN(n))   der   für
Erreignisszählung herangezogen werden soll.
Der Zähler wird dabei gelöscht.

EVCTR(0) schaltet den default Modus, also Frequenzmässung wieder ein.
Wegen der Tatsache, daß nur ein Zähler zur Erreigniszählung verfügbar
ist
und der Eingang zuvor definiert wird ist der Parameter der CNT(n)
Funktion
vorläufig ohne Bedeutung.
Sollten andere Erreignisszähler dazukommen so wird dieser Zähler die
Nummer eins haben und alle weitere ab zwei.




                              Seite 173
5. Neue Timer Funktionen
MSR-Basic verfügt über einem frei laufenden Timer. Dieser Timer wird
jede Milisekunde incrementiert und hat 24 bit Auflösung. Diese Timer
wird ausgelesen wie jede andere Variable:   tim = MSTIMER    ' Variable
tim erhält momentanen Zustand des TimersEine weitere Funktion erlaubt
Berechnung von Zeitdifferenzen zwischen früher eingespeicherten
Timerwert und aktuellen, zu Zeit des Aufrufs der Funktion:    tdiff =
MSTIMDIF(tim) ' tdiff Variable erhält Anzahl Milisekunden
             ' seit dem Zuweisen von MSTIMER an Variable timAuf diese
Weise lassen sich recht genau Zeitdifferenzen bis zu 2796 Minuten
feststellen.
Andere Anwendung wäre z.B. Laufzeitmessung von BASIC Programmen:

   tim =   MSTIMER
   GOSUB   1000
   tdiff   = MSTIMDIF(tim)
   PRINT   "Unterprogramm #100 dauert ";tdiff;" Milisekunden"
oder Verzögerungen:

   100 tim = MSTIMER
   110 IF MSTIMDIF(tim) < 1000 GOTO 110 ' Warte eine Sekunde
6. MODEM-Hilfsfunktionen

Mit Hilfe der MODEM-Hilfsfunktionen ist die Ankopplung von MSR-Rechner
über Wählleitungen an einen (oder mehrere) zentralen Rechner möglich.
Das erlaubt Anwendungen, die Fernwartung erfordern.
Dazu sind neue Funktionen implementiert die auch für andere
Anwendungen,zusammen mit der seriellen Schnittstellen, nützlich sind.

6.1 LUMODE Funktion
Mit dieser Funktion wird die Baudrate, Format und Art des Handshake
eingestellt.
Syntax:

   fcd = LUMODE (kanal,Baud,"Format")

fcd:   Variable in die der Fehlercode zugewiesen wird:
        0 = Alles in Ordnung
       1 = Kanal existiert nicht
       2 = Baudrate nicht unterstützt.
       3 = Datenformat nicht unterstützt
Auf das Auswerten des Fehlercodes kann man ohne weiteres verzichten,
wenn man sicher ist das die angegebene Parameter richtig sind.
Man kann ja zuerst mit <PRINT LUMODE(.....)> austesten ob die Baudrate
oder Format bearbeitet werden kann.

kanal: Kanalnummer der umgestellt werden soll.
      Die SCC2 Karte bei ECB/Z280 CPU belegt Kanäle 2 und 3.
      Die SCC Schnittstellen der TSM-CPU belegen Kanäle 1 und 2
Baud: Baudrate die Benutzt werden soll. Es werden nach Möglichkeit
       alle üblichen Baudraten unterstützt:

       300,1200,2400,4800,9600,19200,38400 Baud.


                                Seite 174
Format:
  Ein String der den Format des Kanal beschreibt.
  Erste Buchstabe gibt die Anzahl bits an ("7" oder "8").
  Zweite Buchstabe wählt die Parität an ("O" für Odd, "E" für Even
oder "N"
  für keine Parität).
  Dritte Buchstabe gibt die Anzahl der Stoppbits an ("1" oder "2").
            Folgende Buchstaben stellen den Handshake ein:

          "X" -> Es wird das XON/XOFF Protokoll benutzt (^S und ^Q
Zeichen).              "R" -> Es wird das RTS/CTS Hardware handshake
benutzt.
  Beide Handshakearten können auch gemeinsam benutzt werden. Wie auch
              immer, das RTS Signal zeigt in jedem Zeitpunkt das
Empangsbereitschaft vom       Seriellen Kanälen, unabhängig ob und
welchen Handshake man gewählt hat.
Beispiel:

Es soll an der zweiten Schnittstelle ein Modem angeschlossen werden
mit 2400 Baud, 8 Bits Daten, keine Parität, ein Stoppbit. Beide
Handshake Protokolle sollen berücksichtigt werden. Dann sieht die
Initialisierung der Schnittstelle so aus:
 fcd = LUMODE(2,2400,"8N1XR")


6.2 LUOPEN Funktion
Mit dieser Funktion kann man den Zustand der DCD-Leitung abfragen.
Sie liefert 0 zurück falls ein an einem Kanal angeschlossene Gerät zum
Datenaustausch nicht bereit ist.

Beispiel:
     1000 IF LUAVAIL(2) THEN PRINT ON(2) "Hallo wie gehts"

6.3 LUAVAIL Funktion
Sollte eine Sequenz ein LU-Kanal bedienen so ist es sinnvol einer
Wartebedienung mit dem Vorhandensein von Daten aus diesem Kanal zu
formulieren. Bis jetzt könnte man ungenügend festellen ob Zeichen
angekommen waren oder nicht. Die Funktion LUAVAIL gibt an ob Zeichen
vorhanden sind oder nicht ohne die Daten aus Empfangspuffer zu
entnehmen.

Beispiel:
  1000 WAIT FOR LUAVAIL(2) '    Warte   bis Zeichen an den Kanal #2
ankommen
  1000 a$ = INCHAR$(2)            ' Zeichen lesen und auswerten

Bei Benutztung dieser Funktion darf nur eine Sequenz oder Task lesend
auf den Kanal zugreifen. Sonst wurde die Gefahr entstehen daß LUAVAIL
Funktion eine Wartebedienung einer Sequenz beenden würde aber das
angekommende Zeichen von einer anderen Sequenz/Task ausgelesen wären.

7. LINKADAPTER

Ab Version 4.1.61 ist ein einfacher LINKADAPTER-Treiber installiert
worden.

                                Seite 175
Der LINK-Anschluss ist über LU #3 erreichbar.
Man kann Daten mit PRINT ON(3), INPUT ON(3) oder INCHAR$(3) über LINK-
Anschluss austauschen.
8. Bemerkungen zur Programmspeicherung in ein EPROM.
Speicher und EPROM Belegung:
Der Z280 Prozessor verfügt über System und User Bereich die
voneinander getrennt jeweils 64KByte haben.
In System-Bereich ist ein Betriebssystem und in User-Bereich der
Basic-Interpreter untergebracht. Der EPROM enthält also beides.
Daher sind alle Adressen des Interpreters relativ zu Interpreteranfang
in EPROM zu suchen!
Weil es verschiedene Versionen von dem MSR-BASIC geben kann mit
unterschiedlichen Zusatztreibern, ist es schwer die genaue Adressen
anzugeben. Es wird jedoch immer so gehandhabt, daß der Interpreter
immer bei vielfachen von 4 KByte Speicherbereich anfängt und nie
kleinere Anfangsadresse geben wird als 3000h.
Also, der Interpreter beginnt ab 3000h,4000h,5000h,.. oder 8000h.
Es ist relativ leicht zu erkennen wo der Interpreter beginnt weil
zwischen dem Betriebssystem und dem Interpreter zwangsläufig Lücke
entsteht die mit <FF FF FF FF...> beschrieben ist.
So, z.B. wenn man In EPROM-Dump follgende Zahlenfolgen sieht:
05FE0: FF FF FF     FF   FF   FF    FF   FF    FF   FF   FF   FF   FF   FF   FF   FF
................
05FF0: FF FF FF     FF   FF   FF    FF   FF    FF   FF   FF   FF   FF   FF   FF   FF
................
06000: C3 .....
so ist es eindeutiger Zeichen, daß der Interpreter ab 06000h im EPROM
liegt.
Diese Startadresse sollte man sich merken. Alle absolute Adressen, die
bei der Beschreibung des PROMIT Statements angegeben sind beziehen
sich relativ zu Interpreteranfang, der bei der Z80 Versionen ab 0000h
beginnt und bei Z280 eben nicht festgelegt und bei oberem Beispiel
6000h beträgt.


Ab der Startadresse des Interpreters werden 28 KByte des EPROMS und 36
KByteRAM   eingeblendet.    Daher   ist   für   BASIC-Programme    der
Speicherbereich zwischen Interpreterende und Startadresse+7000h
nutzbar.Interpreterende ist auch leicht durch die Zeichenfolge:

 : 55 AA FF FF FF FF FF FF FF FF FF FF........ erkennbar.

Leider ist standartmässig nur für kleinere Programme Platz vorhanden.
Sollen grössere Programme im EPROM abgelegt werden so ist es nötig den
RAM-Bereich zu kürzen dammit größerer EPROM-Bereich eingeblendet wird.
Das ist z.Z. durch den Anwender nicht machtbar.
Es wird jedoch eine neue Version angestrebt die automatisch den
EPROM/RAM Bereich optimal verteilt so daß der Speicherbereich
Interpreterende-Epromende (27x512 Typ) nutzbar wird. Oder anders
gesagt: fast alle Programme die in RAM laufen werden auch EPROM-Fähig.
Die Vorgehensweise um ein BASIC-Programm in EPROM zu speichern ist bei
PROMIT Statemment beschrieben. Einziger Unterschied besteht nur darin
daß   der    Interpreter   und    Basic-Programm   um    den   Versatz
<Interpreteranfang> im EPROM gebrannt wird.

9. Fahrtregler mit Gleichstrommotoren

                                   Seite 176
Um ein Gleichstrommotorantrieb anzusteuern bedarf es zweierlei:
  - Die Motorspannung für einem Servoverstäreker erzeugen.
  - Die momentane Ist-Position erfassen.
Die Steuerspannung wird über frei definierbarer D/A Kanal ausgegeben.
Es kommt z.Z. nur das TSM-2DA12 Modul in Frage.
Zu Positionserfassung hat man die Wahl zwischen TSM-4SSI oder TSM-
1INCModul, wobei auch hier der Eingang frei definierbar ist.
Der Regler erlaubt bis zu vier unabhängige Antriebe die auch
paarweisekoordiniert ein Ziel fahren können (X/Y Fahrt).
Es kann nur eine Achse oder eine Achsenpaar in einem Zeitpunkt
gefahren werden. Der Regler kontroliert die Fahrt in einem Zeitraster
von 8ms und zwar im Hintergrund sodaß ein BASIC Programm weiter
ablaufen kann.
Es ist jedoch eine niedriegere Interpretationsgeschwindigkeit während
einer Fahrt anzunehmen.
Der Verlauf einer Fahrt ist einstellbar d.h. die maximale
Geschwindigkeitund die Anfahr-/Bremsbeschleunigung kann der Anwender
festlegen.
Um eine Position zu erfassen sind folgende Funktionen implementiert
worden:
 POS (geber)
Diese Funktion gibt zurück die aktuelle Position eines Gebers.
Als Beispiel sollen zwei Module angeschloßen sein.
Ein TSM-1INC mit Modulnummer 3 und ein TSM-4SSI Modul mit Modulnummer
4.
Eine Anweisung der Form:
    xachs = POS(1)
weist der Variable xachs den Wert des Incrementalgebers zu.

  xachs = POS(3)
weist der Variable xachs den Wert des SSI-Gebers, angeschlossen an
SSI2-Buchse des TSM-4SSI Moduls.
Ein Fehler (Fehler 25) kann entstehen falls kein Geber oder keine 24V
Spannung an entsprechenden Modul angeschlossen ist.

    POSTYPE(GeberNr, Typ, NegFlag, Offset)

Definiert ein angeschloßener Gebertyp.
Wichtig bei TSM-4SSI Modulen, da verschiedene Geber angeschloßen
werden können dessen Gray-Code unterschiedlich nach rechts verschoben
werden muß.
Folgende Typen sind zulässig und resultirende Aufflösungen:
TYP:   Geber:          Auflösung:
2048   2048/4096       0..8388607
1024   1024/2048       0..2097151
 512    512/1024       0..524287
 256    256/512      0..131072
 128    128/256        0..32767
  64     64/128        0..8192
  32     32/64         0..2047
  16     16/32         0..512

Für Inkrementalgeber    wird   Typ   nicht   ausgewertet,   also   z.B.   0
einsetzen.


                                Seite 177
NegFlag:

Ist dieser Parameter ungleich Null so wird die Position immer negiert
ausgegeben.
Offset:

Diese Konstante, wenn ungleich Null, stellt eine Bipolare Verhalten
des Positionsgebers ein. Der Wertebereich der Auflösung verschiebt
sich ins negative sodaß man negative als auch positive Positionen
erfassen kann

.Z.B. nach POSTYPE (1,512,0,300)
stellt die Auflössung des Positionsgebers auf -300..523987,

 und POSTYPE (1,512,0,262143)
stellt einen symmetrischen bipolaren Wertebereich ein.
POSTYPE(1,0,0,8388607)    würde für einen Inkrementalgeber       einen
symmetrischen Bereich -8388607 .. +8388608 ein.



 POSSRN (Geber)

Setze die aktuelle Position eines Gebers als Nullpunkt.Alle darauf
folgende Positionsangaben sind relativ zur dieser Position.
Für den Fahrregler sind folgende Funktinen reserviert:
 FRDEF(nr,posg,dac,brems)

Weise einem Antrieb ein Positionsgeber, ein DAC-Ausgang und eine
Bremseausgang zu.
nr:    Antriebnummer (1..4)
posg: Nummer des Positionsgebers (1..NPOS)
dac:   Nummer des D/A Kanals (1..NDAC)
brems: Nummer eines DOUT Kanals (1..NDOUT), kann 0 sein (keine Bremse
da).

   FRSETP (nr, ruhesp, mv, ma, mweg)

Setzte Parameter eines Antriebes.
Sollen zwei Antriebe als Paar koordiniert fahren, so müssen sie die
gleichemv und ma Parameter haben.

nr:     Antriebnummer (1..4)
ruhesp: Ruhespannung, ungleich Null wenn Antrieb senkrecht aufgestellt
und                     eine zusätzliche Kraft nötig ist um die
Erdanziehungskraft                    auszugleichen.
mv:     Maximale Steuerspannung (0..10000 mV)
ma:      Beschleunigung, Zuwachs der Steuerspannung pro ein Interval
(8ms).
mweg:   Antriebskonstante. Positionsdifferenz in einem Interval wenn
die             maximale Steuerspannung von 10V angelegt wäre.
   FRSETKP(nr, Verst)

Definiere den Kp-Reglerparameter. Dieser Parameter       ist   für   die
Verstärkung des P-Anteils des Reglers zuständig.

                              Seite 178
nr:    Antriebsnummer
Verst: KP-Verstärkung

    FRSETKI(nr, Beiw)
Definiere   den  Ki-Reglerparameter.   Dieser    Parameter    ist    der
Integralbeiwert des I-Anteils des Reglers.

nr:   Antriebsnummer
Beiw: KI-Beiwert
FRLSFAHRT(nr,Pos)

Fahre linear mit einen Antrieb die Zielposition.
nr: Antriebsnummer (1..4)
Pos: Zielposition.
Diese Funktion gibt Null zurück wenn die Fahrt erfolgreich
initialisiert würde. Gleichzeitig beginnt auch die Fahrt im
Hintergrund, sodaß keine weitere Fahrten gestartet werden können bis
dieser Antrieb seine Zielposition erreicht hat.

FRLDFAHRT(Xnr,XPos,Ynr,YPos)
Fahre linear mit einem Antriebspaar die Zielpositionen.

Xnr:    Antriebsnummer des ersten Antriebs.
Ynr:    ... des zweiten Antriebs.
XPos:   Zielposition des ersten Antriebs.
YPos:   ... des zweiten Antriebs.
Diese Funktion unterscheidet sich von der oberen nur dadurch das zwei
Antriebe gleichzeitig und koordiniert gefahren werden.
   FRSTAT(nr)

Gebe zurück den Status eines Antriebes.
Es ist die einzige Möglichkeit festzustellen in welchen Fahrzustand
sich gerade der Antrieb befindet.

Beispiel:

 1000   stat = FRSTAT(1)
 1010   IF stat = 0 THEN PRINT "Antrieb ist ruhend"
 1020   IF stat = 1 THEN PRINT "Antrieb fährt an"
 1030   IF stat = 2 THEN PRINT "Antrieb fährt"
 1040   IF stat = 3 THEN PRINT "Antrieb bremst"
 1050   IF stat = 4 THEN PRINT "Antrieb schleicht sich an Ziel an"
 1060   IF stat >= 5 THEN PRINT "Fehler: Antrieb angehalten"

Im letzten Fall, wo FRSTAT(1) eine Zahl gleich 5 oder höher geliefert
hat,ist anzunehmen daß der Positionierfehler zu groß enstanden ist.
Die nächste Abfrage liefert 0, Antrieb ist in Ruhezustaand.


             FRERROR(nr)              WIRD       NOCH        GEÄNDERT
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Es ist eine Hilfsfunktion die den Positionsfehler zurückgibt der
enstanden ist beim Bremseintritt.
Es wird vorrausgesetzt daß vorher die FRLSFFAHRT oder FRLDFAHRT

                                Seite 179
Funktionaufgerufen und die Strecke erfolgreich ohne Abbruch gefahhren
würde.
Diese Funktion kann man nutzen um den mweg Parameter der Funktion
FRSETP
zu bestimmen. Dazu eignet sich folgende Vorgehensweise:

1) FRSETKI aufrufen mit Parameter = 0, kein Einfluß des
Integrallregler.
2) FRSETKP aufrufen mit kleinem Parameter oder 0, kaum/kein Einfluß
des   Proportionalregler.
3) FRSETP aufrufen mit einem näherungswert für mweg
4) Falls FRSTAT keine 5 zurückgegeben hat bevor der Antrieb
stehengeblieben    war (FRSTAT(n) = 0), den Positionsfehler auslesen.
5) Die ganze Prozedur ab dem Punkt 3 wiederholen mit anderem mweg
Parameter   bis man den kleinsten Positionsfehler ermittelt hat.




                              Seite 180
10. BITBUS Komunikation
Ab MSR-Basic V4.1,74 ist ein BITBUS Treiber verfügbar.
Dammit läßt sich, über BITBUS-Netz, die TSM-CPU ansteuern.
Unabhängig von dem BASIC-Interpreter lassen sich alle allgemeine
Funktionen eins BITBUS-Rechner anwenden ausser Funktionen die 8044
Spezifisch sind undTask Funktionen.
Darüberhinaus besteht die Möglichkeit: eine Kommunikation zwischen
Host-Rechner und dem BASIC-Interpreter aufzubauen.
Beschreibung der Zusammenarbeit zwischen BITBUS und MSRBASIC

- Allgemeines:
Ein in TSM-Rechner zu Verfügung gestellter Speicherbereich (768 Bytes)
kann über BITBUS beschrieben und ausgelesen werden. Das gleiche wird
auch von MSR-Basic ermöglicht. Der Datenaufbau von diesen Speicher
wird nicht vorgeschrieben und kann frei gewählt und genützt werden.
Darüberhinaus können auch festdefinierte Datensätze ausgetauscht
werden die jedoch von den frei wählbaren unterschieden werden.
Auf diesen Speicherbereich kann man asynchron von beiden Seiten
Zugreifen, daher ist es zwingend definierte Flags zu benutzen um den
Datenaustausch zu steuern. Über eine/mehrere Flag-Speicherstellen wird
der Zustand des Speicherbereichs für beide Seiten gekennzeichnet.
Damit läßt sich erkennen ob andere Seite die Daten entgegengenommen
hat.
Der Speicherbereich kann vier Zustände annehmen:
     -   0   =   ungültig (unbeschrieben)
     -   1   =   enthält Daten (beschrieben)
     -   2   =   enthält geforderte Daten (beschrieben)
     -   3   =   abgelehnt (beschrieben aber nicht entgegengenommen)

Es müssen nicht alle Zustände im Betracht genommen werden, das hängt
von den eigenen Bedürfnissen.
Sollen nur Daten in eine Richtung weitergegeben werden, so reicht es
nur den Speicherbereich zu beschreiben, als gültig zu erklären und
warten bis er wieder ungültig wird um weiter beschreiben zu können.
Die andere Seite wartet bis dieser Speicherbereich gültig wird, wertet
aus und meldet als ungültig an.
Sollten Parameter übergeben werden und die andere Seite darauf
Ergebnisse liefern so liegt ein Datenaustausch in beide Richtungen
vor. Es muß ein weiterer Zustand benutzt werden um Parameter von
Ergebnissen unterscheiden zu können.
Zusätzlich kann man auch noch den vierten Zustand nutzen falls
erwünscht.
Eine andere Vorgehensweise, z.B. direkter Zugriff auf bestimmte
Variablen oder Felder wäre nicht flexibel genug, aufwendig auch im
Gebrauch und vor allem bietet keinen Handshakemechanismus in sich.
Trotzdem ist diese Beschreibung mehr oder weniger ein Vorschlag.
Anregungen und Wünsche werden gerne entgegengenommen und falls möglich
hinzugefügt.




                                   Seite 181
- Datenaustausch von der PC-Seite


Struktur einer BITBUS Nachricht:
+))))))))0)))))))0)))))))))0)))))))0)))))))))))))0))))))))),
*        *        *         *       * Kommando     *         *
*   Länge * Flags * Adresse * Tasks * Rückmeldung * n Daten          *
.))))))))2)))))))2)))))))))2)))))))2)))))))))))))2)))))))))-



Die Bedeutung der einzelner Felder ist genügend beschrieben worden
 z.B. im Buch: TSM für Softwareentwickler.

Für diese Anwendung ist nur die Nutzung von Kommando/Rückmeldung und
Daten Felder zu beschreiben.
RAC-Kommandos um den Speicherbereich beschreiben/auslesen zu können:
       DOWNLOAD_MEM = 09h
       UPLOAD_MEM       = 08h

RAC-Kommandos um Zustand-Flag auslesen/setzen:
     READ_INTERNAL_MEM = 0Eh
     WRITE_INTERNAL_MEM = 0Dh
Beispiel für Übergabe von vier Zahlenwerten, als 16 bit Integer
Zahlen.
Beispielweise sollen zwei Nachrichten dazu verwendet werden obwohl
eigentlich eine ausreichen wurde.
Die Beispielwerte 290,563,836,17493 lauten hexadezimal = 0122h, 0233h,
0344 und 4455h. Wegen der BITBUS-Spezifikation die die High-Low
Bytefolge nutzt wird diese Folge auch bei diesen Anwendung genützt.
Die beiden Nachrichten sollten also so aussehen:

...   09 0000 0122 0233 ;DOWNLOAD_MEM ab Offset=0000h die Werte 0122h
und   0233
...   09 0004 0344 4455 ;DOWNLOAD_MEM ab Offset=0004h die Werte 0344h
und   4455h
Jetzt sollte Zustand des Speicherbereichs als beschrieben angezeigt
werden.

... 0D 00 01 ;WRITE_INTERNAL_MEM, Offset=0, Wert=1
Um weitere Daten zu übergeben sollte der zuvor gesetzte Zustandflag
ausgelesen werden:

... 0E 00 ?? ;READ_INTERNAL_MEM, Offset=0, Wert=?? (nur Platzhalter)
Antwort auf dieser Nachricht sollte wie folgt aussehen:
... 00 00 00 ; Okay, Daten übernommen und Quittiert
... 00 00 01 ; Daten immer noch nicht übernommen
... 00 00 02 ; MSR-Basic hat nicht nur die Daten übernommen, es sind
auch                 ; Ergebniswerte vorhanden.

Andere Antworten können nur beim fehlerhaften Betrieb entstehen.
Erste Byte in der Antwort ist ein Responsebyte. Ist er ungleich 00,
dann ist es Fehlerkennung.
Sollte der Zustandflag = 02 sein (Ergebniswerte vorhanden) oder man
will allgemein den Speicherbereich auslesen so kann die entsprechende
Nachrichtso aussehen:

                                Seite 182
... 08 0000 ???? ???? ???? ???? ;UPLOAD_MEM, Offset=0, 4*2 Byte

Die Antwortnachricht könnte dann so aussehen:
... 00 0000 0122 0233 0344 4455

Die Bedeutung von übergebenen Daten und die Reihenfolge/Adressen sind
dem Anwender überlassen und hängen von den aktuellen Bedürfnissen ab.
Auf jeden Fall sollte der entsprechende Basic Programm diese
Datenorganisation verstehen können.
- Datenaustausch von der MSR-Basic Seite

Die Auswertung der Daten von der MSR-Basic Seite läßt sich einfacher
gestalten weil der BITBUS-Treiber fest integriert wird.
Daher ist hier das Verständnis der BITBUS Kommunikation nicht von
Bedeutung.
Es werden Funktionen geboten die den Zustandflag abfragen/Setzen, und
weitere Funktionen die Daten ab bestimmten Offset in Variablen
übernehmen.
Alle Funktionen mit Beschreibung:

BITZFLAG
Dieses Schlüsselwort ist eine Systemvariable die        den   Zustanflag
enthält. Man kann diesen auslesen und auch setzten.
Beispiel:
     1000 WAIT FOR BITZFLAG <> 0     ' Warte bis Zustand sich ändert
                                               ' TASK/SEQ "schläft" so
lange
        1010 ........................' Daten übernehmen
         1990 BITZFLAG = 0            ' Zustand auf ungültig ändern

BITRB(offset)
Gibt zurück den Wert eines Bytes.

BITRW(offset)
Gibt zurück den Wert eines 16-Bit Wortes.

BITRH(offset)
Gibt zurück den Wert eines 24-Bit Wortes.

BITRS$(offset)
Gibt zurück ein String. Ab offset soll ein String vorlegen der als
erstes Byte die Stringlänge und alle folgende Bytes den String selber
darstellen.

BITWB(offset,var)
Lege ab offset den Wert der Variable <var> als Byte Wert ab.


BITWW(offset,var)

                                Seite 183
Lege ab offset den Wert der Variable <var> als 16-Bit Wert ab.

BITWH(offset,var)
Lege ab offset den Wert der Variable <var> als 24-Bit Wert ab.

BITWS$(offset,var$)
Lege ab Offset den String      <var$>     ab.Beispiele   für   die   obere
Funktionen:
 1000 var = BITRB(0)
 1010 var = BITRW(1)
 1020 var = BITRH(3)
 1020 var$ = BITRS$(6)
 2000 BITWB(0,var)
 2010 BITWW(1,var)
 2020 BITWH(3,var)
 2030 BITWS$(6,var$)




                              Seite 184
11. Neue, zusätzliche Funktionen

a$ = FTOI$ (f)
Wandelt eine Gleitkommazahl in Long-Integer Wert und gibt diese zurück
als   drei-Zeichen   String.   Die   Reiihenfolge   im   String   ist:
LSB,MIDSB,MSB.
Beispiele
 100 a = (&H3132 * 256) + &H0033               ' Die Zahlen &H31,&H32 und &H33
                                       '   sind in ASCII als Zeichen "1","2"
                                       '   und "3" definiert.
 110 PRINT a                           '   ergibt 3224115.0000
 120 PRINT FTOI$(a)                    '   wieder in Integer gewandelt und als
                                       '   Zeichen auf dem Schirm gebracht
                                       '   ergibt: "321"

Es soll über LU (2) eine Zeichenfolge ausgegeben werden:

<ESC>,'A',CHR$(ADC(nr) MOD 255), CHR$(ADC(nr) DIV 256)
also der Wert von ADC(nr) soll als Escape-Sequenz in einem 2-Byte
Integer Format ausgegeben werden.
Das kann man in MSR-Basic auf folgende Weise tuen:
  100 adcw$ = FTOI$(ADC(nr))
  110 PRINT ON(2) CHR$(&H1B);"A";
  120 PRINT ON(2) MID$(adcw$,1,2);

a = FTOIB(f,nr)
Wandelt eine Gleitkomazahl in ein 8-Bit Wert wobei angegeben wird
welcher Byte (LSB, MIDSB oder MSB) gefragt wird.
Oder anders formuliert, diese Funktion wäre gleich mit folgender
Anweisung:
a = INT((f / (256*(nr+1))) MOD 256)

wenn MSR-Basic den Integer-Operator MOD gekannt hätte.
Beispiel

  100   a =(&H3132 * 256) +   &H0033
  110   PRINT FTOIB(a,0) AS   2H              ' LSB,   ergibt "33"
  120   PRINT FTOIB(a,1) AS   2H              ' MIDSB, ergibt "32"
  130   PRINT FTOIB(a,2) AS   2H              ' MSB.   ergibt "31"




                                  Seite 185
12. Programmerhalt

Die Hardware zum Speichererhalt wird seit Version 4.177 besser
überwacht. Eine Meldung zeigt den Speicherausfall seit dem letzten
Ausschalten. Dieser Ausfall kann nur unter zwei Bedingungen erfolgen:

1)   Ein neuer RAM-Baustein wurde eingesetzt (alle ok, neu starten)
2)   Es gibt ein Hardwareproblem (Batteriepufferung arbeitet nicht,
     Speicher ist defekt,...)
Die bisherige Software hatte einen Schwachpunkt im Speichertest, wenn
ein Netzteil mit langsam steigender Spannung eingesetzt wurde (sog.
SoftStart-Netzteile) oder durch große Kondensatoren die Spannung beim
Ausschalten sehr langsam abfiel. . Dabei gab es im Zeitpunkte, wo
durch Brummspannung auf dem Netzteil die Power-Fail-Erkennung den
Speicher freigab, weil die nötige Spannung erreicht war, diese aber
gleich wieder abfiel, so daß undefinierte Betriebszustände auftraten.
Jetzt wird durch eine Wartezeit eine stabile Arbeit erreicht.




                              Seite 186

Msrbas

  • 1.
    MSRBASIC Version 4.0 Messen Steuern Regeln Mit Erweiterungen der Version 4.2 ELZET 80 Mikrocomputer GmbH & Co,KG 52062 Aachen www.elzet80.de -1-
  • 2.
    Alle Informationen indiesem Handbuch werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt. MSRBASIC Version 4.0 basiert auf MSRBASIC wie es am Lehrstuhl für Steuerungs- und Regelungstechnik an der Technischen Universität München (Prof. Dr-Ing. G. Schmidt) mit Version 3.0 definiert wurde. Der von ELZET 80 Mikrocomputer erworbene Quelltext dieser Version wurde völlig überarbeitet, mit neuen Features versehen und Kundenwünschen angepasst. MSRBASIC ist ein mit großem Aufwand sorgfältig hergestelltes Qualitätsprodukt. Das illegale Kopieren und Vertreiben dieses Produktes stellt daher einen Diebstahl geistigen Eigentums dar und wird urheberrechtlich verfolgt. Dieses Handbuch basiert auf Unterlagen der LLSR an der TU München. Es wurde um die zusätzlichen Befehle der ELZET 80 Version erweitert. Bei der Zusammenstellung von Texten und Abbildungen und bei der Programmierung von MSRBASIC wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht völlig ausgeschlossen werden. Daher kann ELZET 80 Mikrocomputer im Namen der Autoren für Fehler jeglicher Art und deren Folgen werde eine juristische Verantwortung noch irgendeine Haftung übernehmen. Alle Rechte vorbehalten, auch für die fotomechanische Wiedergabe und der Speicherung in elektronischen Medien. 2. erweiterte Ausgabe 1992 (C) LLSR, TU München und ELZET 80 Mikrocomputer Aachen 1989 -2-
  • 3.
    1. Vorwort . . . . . . . . . . . . . . . . . . . . . . . . . . . . -15- 2. Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . -16- 2.1 Sinn und Zweck von MSRBASIC . . . . . . . . . . . . . -16- 2.2 Anweisungen, Datentypen und Sonstiges . . . . . . . . -17- 2.2.1 Anweisungen . . . . . . . . . . . . . . . . . -17- 2.2.2 Buchstaben . . . . . . . . . . . . . . . . . . -17- 2.2.3 Datentypen . . . . . . . . . . . . . . . . . . -17- 2.2.4 Datenstrukturen . . . . . . . . . . . . . . . -17- 2.2.5 Editor . . . . . . . . . . . . . . . . . . . . -17- 2.2.6 Felder . . . . . . . . . . . . . . . . . . . . -18- 2.2.7 Funktionen . . . . . . . . . . . . . . . . . . -18- 2.2.8 Kanalnummern . . . . . . . . . . . . . . . . . -18- 2.2.9 Kommandos . . . . . . . . . . . . . . . . . . -18- 2.2.10 Kommentare . . . . . . . . . . . . . . . . . -18- 2.2.11 Operatoren . . . . . . . . . . . . . . . . . -19- 2.2.12 Programm . . . . . . . . . . . . . . . . . . -19- 2.2.13 Starten des Interpreters . . . . . . . . . . -19- 2.2.14 Transparent-Betrieb . . . . . . . . . . . . . -20- 2.2.15 Variable . . . . . . . . . . . . . . . . . . -20- 2.2.16 Zahlenbereich . . . . . . . . . . . . . . . . -21- 3. Editor-Funktionen . . . . . . . . . . . . . . . . . . . . . -21- 3.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . -21- 3.2 Funktionsbeschreibung . . . . . . . . . . . . . . . . -21- 3.3 Änderung vorhandener Programmzeilen . . . . . . . . . -22- 4. Echzeitspezifische Sprachmittel . . . . . . . . . . . . . . -24- 4.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . -24- 4.1.1 MSRBASIC-Echtzeitkonzept . . . . . . . . . . . -24- 4.1.2 Organisation und Handhabung . . . . . . . . . -26- 4.1.3 Beispiel: "Meßwerterfassung" . . . . . . . . . -27- 4.1.4 Listing "MESSDEM.BAS" . . . . . . . . . . . . -28- 4.1.5 Empfehlungen und Warnungen . . . . . . . . . . -29- 5. Zusammenfassung der echtzeitspezifischen Befehle . . . . . . -30- 5.1 DEFINE . . . . . . . . . . . . . . . . . . . . . . . -31- 5.2 START . . . . . . . . . . . . . . . . . . . . . . . . -33- 5.3 SUSPEND . . . . . . . . . . . . . . . . . . . . . . . -34- 5.4 ACTIVATE . . . . . . . . . . . . . . . . . . . . . . -35- 5.5 WAIT . . . . . . . . . . . . . . . . . . . . . . . . -36- 5.6 TRACE . . . . . . . . . . . . . . . . . . . . . . . . -39- 5.7 NOTRACE . . . . . . . . . . . . . . . . . . . . . . . -39- 5.8 TASKLIST . . . . . . . . . . . . . . . . . . . . . . -41- 5.9 SEQLIST . . . . . . . . . . . . . . . . . . . . . . . -42- 5.10 Logikfunktionen . . . . . . . . . . . . . . . . . . -43- 5.10.1 NOT(X) . . . . . . . . . . . . . . . . . . . -43- 5.10.2 BIT(N,X) . . . . . . . . . . . . . . . . . . -43- 5.10.3 Boolsche Ausdrücke . . . . . . . . . . . . . -44- 5.11 Prozeß Ein-/Ausgabe-Funktionen . . . . . . . . . . . -45- 5.11.1 Skalare Prozeß-Eingabe-Funktionen . . . . . . -46- 5.11.1.1 ADC(n) . . . . . . . . . . . . . . . -46- 5.11.1.2 DIN(n) . . . . . . . . . . . . . . . -47- 5.11.1.3 GET(pp) . . . . . . . . . . . . . . . -49- 5.11.1.4 CNT(n) . . . . . . . . . . . . . . . -50- 5.11.2 Skalare Prozeß-Ausgabe-Funktionen . . . . . . -51- 5.11.2.1 DAC(n) . . . . . . . . . . . . . . . -51- 5.11.2.2 DOUT(n) . . . . . . . . . . . . . . . -53- 5.11.2.3 PUT(pp) . . . . . . . . . . . . . . . -55- -3-
  • 4.
    5.11.2.4 CNT(n) . . . . . . . . . . . . . . . -56- 5.11.3 Vektor Ein/Ausgabe-Funktionen . . . . . . . . -57- 5.11.3.1 MADC(MO) . . . . . . . . . . . . . . -57- 5.11.3.2 MDAC(SO) . . . . . . . . . . . . . . -57- 5.11.3.3 MDIN(MD) . . . . . . . . . . . . . . -57- 5.11.3.4 MDOUT(SD) . . . . . . . . . . . . . . -57- 5.11.4 Abfrage der Prozeßkonfiguration . . . . . . . -58- 5.11.4.1 NDAC . . . . . . . . . . . . . . . . -58- 5.11.4.2 NADC . . . . . . . . . . . . . . . . -58- 5.11.4.3 NDOUT . . . . . . . . . . . . . . . . -58- 5.11.4.4 NDIN . . . . . . . . . . . . . . . . -58- 5.11.4.5 NCNT . . . . . . . . . . . . . . . . -58- 5.12 Zeitgeberfunktionen . . . . . . . . . . . . . . . . -59- 5.12.1 TDOWN . . . . . . . . . . . . . . . . . . . . -59- 5.12.2 TUP . . . . . . . . . . . . . . . . . . . . . -59- 5.12.3 Zeitfaktor "TIMEFAC" . . . . . . . . . . . . -59- 5.12.4 24 Bit-Zeitgeber (nur TSM) . . . . . . . . . -59- 5.12.4.1 MSRTIMER . . . . . . . . . . . . . . -60- 5.12.4.2 MSTIMDIF . . . . . . . . . . . . . . -60- 5.12.5 Kalender und Uhrzeit . . . . . . . . . . . . -60- 5.12.5.1 TIME$ . . . . . . . . . . . . . . . . -60- 5.12.5.2 DATE$ . . . . . . . . . . . . . . . . -61- 5.12.5.3 DOW$ . . . . . . . . . . . . . . -61- 5.13 Reglerfunktionen . . . . . . . . . . . . . . . . . . -62- 5.13.1 Allgemeines . . . . . . . . . . . . . . . . . -62- 5.13.2 P/PID-Einzelregler . . . . . . . . . . . . . -63- 5.13.3 Vektor P/PID-Regler . . . . . . . . . . . . . -63- 5.14 Speicherfunktionen . . . . . . . . . . . . . . . . . -65- 5.14.1 PEEK(N) . . . . . . . . . . . . . . . . . . . -65- 5.15 Hintergrundspeicher . . . . . . . . . . . . . . . . -66- 5.15.1 BGMEMDIM . . . . . . . . . . . . . . . . . . -67- 5.15.2 BGMEM Wahlfreier Zugriff . . . . . . . . . . -67- 5.15.2.1 BGMEMPUTR . . . . . . . . . . . . . . -67- 5.15.2.2 BGMEMGETR . . . . . . . . . . . . . . -68- 5.15.3 BGMEM Queue-Zugriff . . . . . . . . . . . . . -70- 5.15.3.1 BGMEMPUTQ . . . . . . . . . . . . . . -70- 5.15.3.2 BGMEMGETQ . . . . . . . . . . . . . . -71- 5.15.4 BGMEM Stackzugriff . . . . . . . . . . . . . -72- 5.15.4.1 BGMEMPUSH . . . . . . . . . . . . . . -72- 5.15.4.2 BGMEMPOP . . . . . . . . . . . . . . -73- 5.15.5 BGMEM Sonderfunktionen . . . . . . . . . . . -74- 5.15.5.1 BGMEMSS . . . . . . . . . . . . . . . -74- 5.15.5.2 BGMEMCLEAR . . . . . . . . . . . . . -76- 5.15.5.3 BGMEMFRE . . . . . . . . . . . . . . -77- 5.16 Logical Units (Serienschnittstellen) . . . . . . . . -78- 5.16.1 LUMODE . . . . . . . . . . . . . . . . . . . -78- 5.16.2 LUOPEN . . . . . . . . . . . . . . . . -78- 5.16.3 LUAVAIL . . . . . . . . . . . . . . . . . . . -79- 5.17 Linkadapter . . . . . . . . . . . . . . . . . . . . -79- 5.18 BITBUS-Anschluß . . . . . . . . . . . . . . . . . . -80- 5.18.1 Allgemeines . . . . . . . . . . . . . . . . . -80- 5.18.2 Datenaustausch vom PC . . . . . . . . . . . . -80- 5.18.3 Datenaustausch aus MSRBASIC . . . . . . . . . -83- 5.18.3.1 BITZFLAG . . . . . . . . . . . . . . -83- 5.18.3.2 BITRB . . . . . . . . . . . . . . . . -83- 5.18.3.3 BITRW . . . . . . . . . . . . . . . . -83- 5.18.3.3 BITRH . . . . . . . . . . . . . . . . -84- 5.18.3.4 BITRS$ . . . . . . . . . . . . . . . -84- 5.18.3.5 BITWB . . . . . . . . . . . . . . . . -84- -4-
  • 5.
    5.18.3.6 BITWW .. . . . . . . . . . . . . . . -85- 5.18.3.7 BITWH . . . . . . . . . . . . . . . . -85- 5.18.3.8 BITWS$ . . . . . . . . . . . . . . . -85- 5.19 Fahrtregler (POS) . . . . . . . . . . . . . . . . . -87- 5.19.1 Allgemeines . . . . . . . . . . . . . . -87- 5.19.2 POS . . . . . . . . . . . . . . . . . . . . . -87- 5.19.3 POSTYPE . . . . . . . . . . . . . . . . . . . -87- 5.19.4 POSSRN . . . . . . . . . . . . . . . . . . . -88- 5.19.5 FRDEF . . . . . . . . . . . . . . . . . . . . -88- 5.19.6 FRSETP . . . . . . . . . . . . . . . . . . . -88- 5.19.7 FRSETKP . . . . . . . . . . . . . . . . . . . -88- 5.19.8 FRSETKI(ki) . . . . . . . . . . . . . . . . . -89- 5.19.9 FRLSFAHRT . . . . . . . . . . . . . . . . . . -89- 5.19.10 FRLDFAHRT . . . . . . . . . . . . . . . . . -89- 5.19.11 FRSTAT . . . . . . . . . . . . . . . . . . . -89- 5.19.12 FRERROR . . . . . . . . . . . . . . . . . . -90- 6. Ein-/Ausgabe-Sprachmittel . . . . . . . . . . . . . . . . . -91- 6.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . -91- 6.1.1 Fenstertechnik . . . . . . . . . . . . . . . . -92- 6.1.2 Fenster-Programmierung . . . . . . . . . . . . -93- 6.1.2.1 Fenster einschalten . . . . . . . . . -93- 6.1.2.2 Fenster ausschalten . . . . . . . . . -93- 6.1.2.3 Cursor positionieren . . . . . . . . . -93- 6.1.2.4 Masken-Dateien ausgeben . . . . . . . -93- 6.1.2.5 Abfragen des oberen Fensters . . . . . -93- 6.1.3 Beispiel zur Fenstertechnik . . . . . . . . . -93- 6.2 Ein- / Ausgabe-Anweisungen . . . . . . . . . . . . . -95- 6.2.1 INPUT . . . . . . . . . . . . . . . . . . . . -95- 6.2.2 PRINT . . . . . . . . . . . . . . . . . . . . -97- 6.2.2.1 Tabellierung . . . . . . . . . . . . . -97- 6.2.2.2 Cursor-Positionierung . . . . . . . . -97- 6.2.2.3 Formatierung . . . . . . . . . . . . . -97- 6.3 Schnittstellenfunktionen . . . . . . . . . . . . . -100- 6.3.1 EOF(n) . . . . . . . . . . . . . . . . . . . -100- 6.3.2 INCHAR$(n) . . . . . . . . . . . . . . . . . -100- 6.3.3 STATUS(n) . . . . . . . . . . . . . . . . . -101- 6.3.4 COMMAND(n) . . . . . . . . . . . . . . . . . -101- 7. Standardsprachmittel . . . . . . . . . . . . . . . . . . . -102- 7.1 Programmfluß-Steuerung . . . . . . . . . . . . . . -102- 7.1.1 FOR . . . . . . . . . . . . . . . . . . . . -102- 7.1.2 NEXT . . . . . . . . . . . . . . . . . . . . -104- 7.1.3 GOSUB . . . . . . . . . . . . . . . . . . . -105- 7.1.4 RETURN . . . . . . . . . . . . . . . . . . . -106- 7.1.5 GOTO . . . . . . . . . . . . . . . . . . . . -107- 7.1.6 IF . . . . . . . . . . . . . . . . . . . . . -108- 7.1.7 STOP . . . . . . . . . . . . . . . . . . . . -110- 7.1.8 END . . . . . . . . . . . . . . . . . . . . -111- 7.2 Rechen- /Speicheranweisungen . . . . . . . . . . . -112- 7.2.1 DIM . . . . . . . . . . . . . . . . . . . . -112- 7.2.2 LET . . . . . . . . . . . . . . . . . . . . -114- 7.2.3 MAT . . . . . . . . . . . . . . . . . . . . -116- 7.2.4 VEC . . . . . . . . . . . . . . . . . . . . -117- 7.2.5 POKE . . . . . . . . . . . . . . . . . . . . -119- 7.3 Kommentare . . . . . . . . . . . . . . . . . . . . -120- 7.3.1 REM . . . . . . . . . . . . . . . . . . . . -120- 7.4 Dateibefehle . . . . . . . . . . . . . . . . . . . -121- 7.5 Standardfunktionen . . . . . . . . . . . . . . . . -122- 7.5.1 ABS(X) . . . . . . . . . . . . . . . . . . . -122- -5-
  • 6.
    7.5.2 ACN(X) .. . . . . . . . . . . . . . . . . . -122- 7.5.3 ASN(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.4 ATN(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.5 COS(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.6 EXP(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.7 INT(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.8 LN(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.9 LOG(X) . . . . . . . . . . . . . . . . . . . -122- 7.5.10 SIN(X) . . . . . . . . . . . . . . . . . . -122- 7.5.11 SQR(X) . . . . . . . . . . . . . . . . . . -122- 7.5.12 TAN(X) . . . . . . . . . . . . . . . . . . -122- 7.6 Stringfunktionen . . . . . . . . . . . . . . . . . -123- 7.6.1 CHR$(X) . . . . . . . . . . . . . . . . . . -123- 7.6.2 VAL(X$) . . . . . . . . . . . . . . . . . . -123- 7.6.3 LEN(X$) . . . . . . . . . . . . . . . . . . -123- 7.6.4 LEFT$(Q$,N) . . . . . . . . . . . . . . . . -123- 7.6.5 MID$(QS,N,M) . . . . . . . . . . . . . . . . -123- 7.6.6 RIGHT$(Q$,N) . . . . . . . . . . . . . . . . -123- 7.6.7 INSTR({N,}Q$,S$) . . . . . . . . . . . . . . -123- 7.6.8 ASC(x$) . . . . . . . . . . . . . . . . . . -124- 7.6.9 FTOI$ . . . . . . . . . . . . . . . . . . . -124- 7.6.19 FTOIB . . . . . . . . . . . . . . . . . . . -125- 7.7 Sonstiges . . . . . . . . . . . . . . . . . . . . . -126- 7.7.1 USR . . . . . . . . . . . . . . . . . . . . -126- 7.7.2 CALL . . . . . . . . . . . . . . . . . . . . -128- 7.7.3 ONERROR . . . . . . . . . . . . . . . . . . -130- 8. Kommandos . . . . . . . . . . . . . . . . . . . . . . . . -131- 8.1 AUTO . . . . . . . . . . . . . . . . . . . . . . . -131- 8.2 CLS . . . . . . . . . . . . . . . . . . . . . . . . -132- 8.3 FREEZE . . . . . . . . . . . . . . . . . . . . . . -133- 8.4 LIST . . . . . . . . . . . . . . . . . . . . . . . -134- 8.5 LOAD . . . . . . . . . . . . . . . . . . . . . . . -135- 8.6 NEW . . . . . . . . . . . . . . . . . . . . . . . . -136- 8.7 NOFREEZE . . . . . . . . . . . . . . . . . . . . . -136- 8.8 MFREE . . . . . . . . . . . . . . . . . . . . . . . -136- 8.9 RUN . . . . . . . . . . . . . . . . . . . . . . . . -136- 8.10 SAVE . . . . . . . . . . . . . . . . . . . . . . . -136- 8.11 SYSTEM . . . . . . . . . . . . . . . . . . . -137- 8.12 VCL . . . . . . . . . . . . . . . . . . . . . . . -137- 9. Programmiertips . . . . . . . . . . . . . . . . . . . . . -138- 9.1 Systemanalyse und Programm-Konzeption . . . . . . . -138- 9.1.1 Analyse der erforderlichen Parallität . . . -138- 9.1.2 Restriktive Auslastung . . . . . . . . . . . -139- 9.2 Programm-Implementierung . . . . . . . . . . . . . -140- 9.2.1 Anlagenorientierte Modularisierung . . . . . -140- 9.3 Übersichtlichkeit der Programme . . . . . . . . . . -141- 10. Hardware-Anpassung und EPROM-startende Systeme . . . . -143- 10.1 Allgemeines . . . . . . . . . . . . . . . . . . . -143- 10.2 Hardware-Anpassung . . . . . . . . . . . . . . . . -143- 10.2.1 Portadressen . . . . . . . . . . . . . . . -144- 10.3 EPROM-startende Systeme . . . . . . . . . . . . . -145- 10.3.1 PROMIT . . . . . . . . . . . . . . . . . . -146- 10.4.2 PROMIT bei Z280 Systemen . . . . . . . . . -147- 10.4 Programme in EEPROM . . . . . . . . . . . . -149- 10.5 Entwicklungshilfen . . . . . . . . . . . . . . . . -150- -6-
  • 7.
    11. Fehlermeldungen .. . . . . . . . . . . . . . . . . . . . -151- 12. Stichwortverzeichnis . . . . . . . . . . . . . . . . . . -153- 13. Anhang Erweiterungen des MSR-Basic für Z280 CPU (TSM/ECB) 1. Neuerungen bei MSR-Basic V4.2,00 . . . . . . . . . . . . . . . . . . . . 1.1. IF-ELSE-ENDIF . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. ONERROR Änderung. . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. INPUT Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4. SEQSTATE und TASKSTATE Funktionen . . . . . . . . . . . . . . . . . 1.5. FORBID und PERMIT Anweisungen . . . . . . . . . . . . . . . . . . . 1.6. Logische Operatoren AND und OR. . . . . . . . . . . . . . . . . . . 1.7. STDSET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Hintergrundspeicher für MSR-Basic. . . . . . . . . . . . . . . . . . . . 2.1. Einrichten eines Hintergrundspeichers . . . . . . . . . . . . . . . 2.2. Wahlfreie Zugriff (Random Acess). . . . . . . . . . . . . . . . . . 2.3. Zugriff auf Queues. . . . . . . . . . . . . . . . . . . . . . . . . 2.4. Zugriff auf Stacks . . . . . . . . . . . . . . . . . . . . . . . . 2.5. Hilfsfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6. Flash-EPROM Hintergrundspeicher . . . . . . . . . . . . . . . . . . 2.7. Neue E/A-Funktionen für TSM-8AD8 3. Programmspeicherung in Flash-EPROM . . . . . . . . . . . . . . . . . . . 4. CNT-Zähler und EVCTR Funktion . . . . . . . . . . . . . . . . . . . . . 5. Neue Timer Funktionen. . . . . . . . . . . . . . . . . . . . . . . . . . 6. MODEM-Hilfsfunktionen. . . . . . . . . . . . . . . . . . . . . . . . . . 6.1 LUMODE Funktion. . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 LUOPEN Funktion. . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 LUAVAIL Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . 7. LINKADAPTER. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -7-
  • 8.
    8. Bemerkungen zurProgrammspeicherung in ein EPROM . . . . . . . . . . . . 9. Fahrtregelung mit Gleichstrommotoren . . . . . . . . . . . . . . . . . . 10. BITBUS Komunikation. . . . . . . . . . . . . . . . . . . . . . . . . . . 11. Neue, zusätzliche Funktionen . . . . . . . . . . . . . . . . . . . . . . 12. Programmerhalt 1. Neuerungen beim MSR-Basic V4.2,00 In allen früheren MSR-Basic Versionen unterscheidet man zwischen Hauptprogramm, Sequenen und Tasks. Dabei war durch den unübersichtlichen Schedule-Mechanismus nicht vorhersehbar welchen zeitlichen Anteil dem Hauptprogramm zugewiesen wird. Also das Hauprogramm eignete sich lediglich zur Definition von Sequenzen und Task und dessen Start. In der Version V4.2 wurde das Hauptrogramm einer Sequenz gleichgestellt. Das bedeutet, daß das Hauptrogramm immer den gleichen zeitlichen Anteil zur Ausführung bekommt wie andere definierte Sequenzen, oder auch in WAIT-Zustand übergehen kann, was früher nicht möglich war. Die Numerierung der Sequenzen ist gleichgeblieben (#1..#25). Dazugekommen ist die Sequenz #0, also das Hauptprogramm. Ein GOSUB führte dazu, daß der Schedule Mechanismus außer Kraft gesetzt wurde, bis das Unterprogramm beendet war. Also, wenn z.B. eine Sequenz ein GOSUB ausführte, wurden alle Task und Sequenzen angehalten !!!!! Das schränkte die Anwendung von Unterprogrammem sehr ein, aber hatte dabei eine nützliche Eigenschaft das es möglich war durch ein Unterprogramm z.B. Impulse mit fester Länge zu erzeugen ohne alle Task/Sequenzen anzuhalten und wieder zu aktivieren. In der neuen Version darf ein man Unterprogramme verwenden ohne das der Scheduler angehalten wird, weil jede Task/Sequenz ein eigenes GOSUB-Stack besitzt. Lediglich dürfen Unterprogramme nicht beliebig andere Unterprogramme aufrufen. Die Schachtelungstiefe ist auf 4 begrenzt oder auf 3 wenn man ONERROR Anweisung benutzt. Es muß immer die Aufrufmöglichkeit eines ONERROR-Unterprogramms bestehen. Den Scheduler anzuhalten ist weiterhin möglich, aber nicht mehr durch den GOSUB-Trick sondern durch neue Anweisung FORBID. Die ebenfalls neue Anweisung PERMIT löst die Schedule- Sperre wieder auf. Die Ausdruckanalyse lief bis jetzt auch nicht immer korrekt. Ein Funktionsaufruf der als Parameter wiederum eine Funktion hatte führte manchmal zu falschen Ergebnissen. Ganz besonders die Stringfunktionen machten diesen Fehler. Bei der neuen Version würde die Ausdruckanalyse ebenfalls umgeschrieben. Die Ausdruckanalyse hat nicht mehr den iterativen sondern recursiven Charakter. Diese Analyse unterscheidet neben Gleitkomma und Stringausdrücken auch Festkommausdrücke (long- integer). Das bedeutet daß Summen und Produkten von Funktionen, System-Variablen und Integer-Konstanten viel schneller berechnet werden. Leider sind noch keine -8-
  • 9.
    Festkommavariablen möglich sodaß bei einer Variablenzuweisung ein Festkommaausdruck in Gleitkommawert umgewandelt werden muß, oder das Vorhandensein einer Variable im Ausdruck, den Ausdruck automatisch den Gleitkommatyp gibt. !!! ACHTUNG !!! Durch die Festkommaarithmetik können unerwünschte Nebeneffekte auftreten die früher nicht bekannt waren. Eine Konstante ohne einem Dezimalpunkt ist ein Festkommaausdruck, daher ist z.B. (1/10) auch ein Festkommaausdruck. Weist man einer Gleitkommavarible den Wert (1/10) zu, so bekommt sie den Wert (0) zugewiesen!!!. Man sollte in solchen Fällen explizit statt (1/10), (0.1) eingeben oder wenigstens eine Gleitkommakonstante verwenden z.B. (1/10.0) oder (1.0/10). 1.1 IF-ELSE-ENDIF Neben einem einzeiligen IF...THEN...ELSE... Konstrukt ist ab Version V4.2 das mehrzeilige IF.../ELSE.../ENDIF Block möglich. Beispiel: 100 IF a=1 ' Kein THEN also ENDIF muß folgen! 110 a = a-1 120 b = b+1 130 ELSE 140 a = 1 150 b = b+2 160 ENDIF 1.2 ONERROR Änderung Ab Version V4.2 wird das Scheduling während des Ausführung eines Unterprogramms nicht mehr angehalten. Das bedeutet daß bei der Ausführung eines ONERROR- Unterprgramms die Möglichkeit bestehen würde daß ONERROR- Unterprogramm vom mehren Tasks oder Sequenzen nebenläufig ausgeführt würde. Der Interpreter würde es zwar korrekt ausführen, aber für jede Anwendung wäre es ziemlich problematisch. Daher wird vor jeder Ausführung eines ONERROR-Unterprogramms automatisch die FORBID Anweisung ausgeführt. Das Bedeutet daß ein ONERROR-Unterprogramm nicht durch eine TASK oder Sequenz unterbrochen wird was wiederum ein Aufruf vom ONERROR- Unterprogramm auslösen könnte. Weiterhin ist eine Termination sichergestellt wenn ein Fehler in einem ONERROR-Unterprogramm selbst ausgelöst wird. Im Handbuch wird nicht beschrieben das die Möglichkeit die Fehlernummer auszulesen (ERRVAR Variable). In ERRVAR wird die Fehlernummer gespeichert bevor das ONERROR Unterprogram ausgeführt wird. Ein Beispiel für ONERROR-Unterprogramm. 1000 REM **** ONERROR-Unterprogramm *********************************** 1010 PRINT "*** FEHLER #";ERRVAR -9-
  • 10.
    ... ... Eventuelle Aktionen,abhängig vom Fehlernummer ... 1280 PERMIT 1290 RETURN Der Befehl PERMIT hebt die Schedule-Sperre wieder auf. PERMIT sollte in einem solchen Unterprgramm immer kurz vor RETURN Anweisung stehen. 1.3 INPUT Anweisung Die INPUT Anweisung war schon immer ein Bestandteil von MSR- Basic. Leider war seine Anwendung in einem Multitasking Programm nur bedingt brauchbar, weil das Schedule Mechanismus bis zu Eingabe von <RETURN> angehalten würde. Ab Version V4.2 ist eine neu konzipierte INPUT Anweisung verfügbar die wenig zum Wünschen übrig läßt. Beim ausführen von INPUT Anweisung geht die ausführende Sequenz in ein Wait-Zustand über. Das bedeutet das die Tasks weiterhin eine INPUT Anweisung nicht Ausführen dürfen. Das Hauptprogramm wird ab Version V4.2 wie eine Sequenz behandelt, also es gibt ja auch keine Einschränkung bezüglich der Anwendung. Der WAIT-Zustand in die eine Sequenz übergeht kann optional zeitlich überwacht werden. Damit kann man leicht verhindern daß eine Sequenz ewig auf eine Eingabe wartet. Des weiteren, man kann optional, das Fehlerbehandlung bei der Eingabe selbst gestalten. Also, man kann das standard Mechanismus wo die INPUT-Anweisung, nach vorherigen Meldung: "INPUT Fehler", wiederholt wird, durch eigene Fehlerbehandlung ersetzen. Weiterhin ist es jetzt auch möglich Bildschirmausgaben zu machen während in einem anderem Teil des Bildschirms eine INPUT-Zeile editiert wird. Diese nebenläufige Bildschirmausgabe wird jedoch nur dann funktionieren wenn man kein Semikolon am Ende der PRINT- Anweisung verwendet. Die neue Syntax lautet: INPUT [ ON(Kanal ] [ [Y,X] ] [ MAX Wert ] <Variablenliste> [ ELSE Anweisung] Unter <Variablenliste> ist eine oder mehrere, durch Komma getrennte numerische oder Stringvariablen gemeint. Die Eingabe sollte bei mehreren Variablen auch durch Komma getrennt werden. Bei Numerischen Variablen ist nur eine Numerische Darstellung einer Zahl erlaubt und sollte einer Stringvariable das Kommazeichen auch zugewiesen werden so kann die Eingabe in Anführungsstriche geklammert werden. Beispieleingabe für Variablenliste <a,a,a$>: -10-
  • 11.
    >1111.0, 222,"Komma,Komma"< Unvollständige Eingabenoder unkorrekte Numerische Darstellung führen zu einem Fehlerfall! Die Optionen: [ ON(Kanal) ] Soll die Eingabe auf einem anderem Kanal erfolgen als LU(0), so ist diese Option zu wählen. So werden bei "INPUT ON(2) a" alle Eingaben und Ausgaben auf LU(2) erfolgen. [ [Y,X] ] Stellt den Cursor auf eine bestimmte Y,X Position des Bildschirms. Auf dieser Position kann man dann die Werte eingeben. Obwohl andere Sequenzen oder Task Bildschirmausgaben parallel dazu machen wird die eingestellte Position beibehalten. Vorausgesetzt daß PRINT-Anweisungen ohne Semikolon verwendet werden!. [ MAX Wert ] Die INPUT-Anweisung wird Zeitlich überwacht. Durch <Wert> bestimmt man wieviel Sekunden maximal das Eingabegerät ruhen darf. Die INPUT Anweisung selber kann vielfaches davon aktiv bleiben, aber einzelne Pausen bei der Eingabe dürfen den Limit nicht überschreiten. [ ELSE Anweisung ] Programmabschnitt nach <ELSE> wird nicht berücksichtigt wenn die Eingabe erfolgreich abgeschlossen würde. Würde die Zeitliche überwachung aktiviert und überschritten oder die Eingabe falsch oder unvollständig gemacht so wird keine Fehlermeldung ausgegeben und die INPUT-Anweisung wiederholt, sonder dieser Programmabschnitt ausgeführt. Zweckmäßig sollte dort eine GOTO Anweisung stehen, aber auch andere Anweisungen sind zulässig. Beispiel für eine INPUT-Anweisung mit Optionen: 11000 PRINT "Geben Sie Bitte Name,Vorname und Alter ein: "; 11010 INPUT MAX 10 Name$,Vorname$,Alter ELSE GOTO 11110 1.4 SEQSTATE und TASKSTATE Funktionen Es ist manchmal nützlich zu wissen ob eine Sequenz oder Task aktiv ist. Zwar ließ sich daß immer durch Benutzung von Variablen realisieren, doch jetzt ist es bequemer und sicherer. Als Parameter gibt man eine Sequenz oder Tasknummer und bekommt zurück ein Zustandswert, der folgende Bedeutung hat: -11-
  • 12.
    0: Sequenz oderTask nicht Aktiv. 1: Sequenz oder Task ist aktiv 2: Nur bei Sequenzen. Sequenz ist aktiv und wartet auf ein Zustand (WAIT oder INPUT Anweisung gerade in Bearbeitung). Beispiel: Von einer Sequenz soll ein TASK gestartet werden, die Sequenz selber hat dann nichts zu tun und soll solange in Wartezustand übergehen. 1000 START TASK 1 1010 WAIT FOR TASKSTATE(1) = 0 1020 PRINT "O.K." 1.5 FORBID und PERMIT Anweisungen Das Multitasking bringt viele Vorteile mit sich. Es gibt jedoch Anwendungen bei denen für kurze Zeit das Schedulemechanismus sehr stört. Z.B. bei Erzeugung von Programmgesteurten Impulsen oder bei einem Fehlerfall wo alle TASK/SEQUENZ Aktionen kurz angehalten werden sollen. Zwar ließ es sich immer mit SUSPEND TASK ALL und SUSPEND SEQ ALL alle Tasks und Sequenzen anzuhalten, aber dadurch war nur der Hauptprogramm blieb dann aktiv und es war nicht mehr möglich den ursprünglichen Zustand herzustellen. ACTIVATE TASK ALL würde alle TASKs aktivieren unabhängig davon ob sie vorher schon mal aktiv waren oder nicht. Bei Ausführung der FORBID Anweisung wird also wirklich das Schedulemechanismus angehalten. Nach dieser Anweisung wird ausschließlich der Programmteil, der diese Anweisung enthalten hat, ausgeführt. Die Anweisung PERMIT hebt die Sperre wieder auf, und alles kehrt zum ursprünglichen Zustand. Wie schon erwähnt, es gibt ein Sonderfall wo die FORBID Anweisung automatisch ausgeführt wird. Und zwar vor der Ausführung eines ONERROR Unterprogramms. Daher sollte man in der Regel nicht vergessen ein PERMIT Anweisung auszuführen vor einer RETURN Anweisung des Unterprogramms. Noch ein schlechtes Beispiel zur Warnung: 1000 a = 0 1010 FORBID 1020 WAIT FOR a>0 1030 PERMIT Wie man leicht erkennen kann ist dieser Beispiel das Ende eines Programms. Obwohl vorher alles schalten und walten vermag tut sich bereits nach der dritten Zeile nichts mehr. Dieser Teil einer Sequenz wird nach der FORBID Anweisung der einziger ausgeführte Programmteil, und geht sofort in ein WAIT-Zustand der nie beendet wird!!! 1.6 Logische Operatoren AND und OR Eine Einschränkung bei MSR-Basic war das fehlen der bekannten AND oder OR Operatoren. Nun gilt diese Einschränkung nicht mehr. -12-
  • 13.
    Diese Operatoren sindz.Z. nur als logische Operatoren die zusammen mit Relationen in einer IF oder WAIT Anweisung verwendet werden können, nicht aber für eine Verknüpfung zweier Werte bitweise. Das macht nur ein Sinn mit Ganzzahligenwerten und solange keine Ganzzahlige Variable eingeführt sind würde es nur wenig ausgenutzt werden können. Die Rangfolge dieser Operatoren ist nach der Relationen und beliebige Klammerung ist erlaubt. Beispiel: 1000 IF DIN(NotAus) OR (DIN(Vent1) = 0 AND DIN(Vent2) = 0) 1010 PRINT "Notschalter EIN, oder beide Ventile ausgeschaltet!!" 1020 ENDIF 1.7 STDSET Anweisung Die neue Anweisung STDSET soll der allgemeiner Voreinstellung dienen. Bis jetzt ist nur der Format bei Ausgabe von numerischen Werten voreinstellbar, und die Syntax lautet: STDSET AS xxx wobei xxx die Formatbeschreibung ist die sonst hinter AS erlaubt ist. Sollen in einem Programm nur Werte in sechsstelligen Festkommaformat ausgegeben werden so braucht man nicht mehr hinter jeder PRINT Anweisung "AS 6I" einzugeben wenn man am Programmanfang mit "STDSET AS 6I" dieses Format eingestellt hat. Ein weiteres Nutzen dieser Anweisung ist es, daß damit auch die STR$ Funktion beeinflußt wird. Bis jetzt lieferte diese Funktion einen String welcher gleich war mit Ausgaben der PRINT Anweisung ohne <AS xxx> Formatangabe. Meist müsste ein solcher String weiterbearbeitet werden z.B. wenn man nur die zwei Vorkommaziffer benötigte. Nun, jetzt kann man das Format einstellen und dieses Format wird auch für die STR$ Funktion verwendet. Beispiel: Ein Programm soll über LU(2) Steuersequenzen ausgeben. Eine Sequenz besteht aus einem <ESC> Zeichen gefolgt von einer Befehlsbuchstabe,Parameter und <CR> Zeichen. Der Parameter besteht immer aus zwei Hexadezimalziffern. 10000 PRINT ON(2) CHR$(&H1B)$; ' <ESC> Zeichen 10010 PRINT ON(2) Cmd$; ' Kommandobuchstabe 10020 STDSET AS 02H ' Format = 2 Stellen, Hexadezimal 10030 PRINT ON (2) STR$(Wert); ' Parameter ausgeben 10040 STDSET AS 6I ' wieder Normale Einstellung 10050 PRINT ON (2) CHR$(&H0D); ' Abschlusszeichen <CR> 2. Hintergrundspeicher für MSR-Basic MSR-Basic wurde ursprünglich für den Betrieb mit sehr wenig Hauptspeicher entwickelt. Es kann meist ein Bereich von 32 KByte für MSR-Programme und Daten genutzt werden. Um in Applikationen der Meßwerterfassung auch mit größeren Datenmengen umgehen zu können, wurde für den Prozessor Z280 eine Erweiterung des MSR-Basic vorgenommen. Die neuen Funktionen erlauben die Einrichtung und das Einfügen/Entfernen -13-
  • 14.
    von Daten auseinem Hintergrundspeicher. Ein Hintergrundspeicher kann als Feld von Datenstrukturen aufgefaßt werden. Es können auch mehrere Hintergrundspeicher definiert werden, deren Datenstruktur unabhängig voneinander sind. Auf den Hintergrundspeicher kann direkt (wahlfrei), als Stack oder als Queuezugegriffen werden. Alle Zugriffsarten können auch gemischt werden, was besonderes dann sinnvoll ist, wenn die Daten eines Stacks oder Queue verarbeitet werden sollen, ohne sie aus dem Hintergrund zu entfernen. Es können maximal 8 Hintergrundspeicher definiert werden, deren Größe nur durch den verfügbaren Speicherplat Seite 187 -14-
  • 15.
    1. Vorwort Entsprechend denvielfältigen Einsatzmöglichkeiten richtet sich MSRBASIC an einen weiten Kreis von Anwendern. Das vorliegende MSRBASIC-Handbuch stellt hinsichtlich Darstellung und Umfang einen Kompromiß dar. Diejenigen MSRBASIC-Befehle, die zum Standard-Sprachumfang gehören werden sehr knapp beschrieben, während MSRBASIC-spezifische Echtzeit-Befehle in der gebotenen Ausführlichkeit behandelt werden. Die Methodik der Darstellung ist vom Ziel geprägt, das jeweilige Grundprinzip der einzelnen MSRBASIC-Befehle knapp und allgemein zu vermitteln, andererseits durch praktische Beispiel Anwendungshinweise für den MSRBereich zu liefern. Aus diesem Grund werden die Befehle nicht in ihrer alphabetischen Reihenfolge beschrieben, sondern im Rahmen funktionell verwandter Befehle, wie z.B. - Echtzeitbefehle - Programmflußsteuerbefehle - Zeichen-Ein/Ausgabe-Befehle -15-
  • 16.
    2. Allgemeines 2.1 Sinnund Zweck von MSRBASIC Der MSRBASIC-Interpreter ist konzipiert für die flexible Implementation von Meß- Steuer- und Regelalgorithmen auf EPROM- startenden Mikrorechnern (Stand-Alone-Systeme) der Z80-Familie. Die Programm-Entwicklung erfolgt mit dem Hilfsprogramm MSRSHELL auf einem PC (XT, AT) über eine RS232-Verbindung mit dem EPROM- startenden Zielrechner (MOPS xAx, xDx oder PC-EXPander mit CPU-S oder CPU85SC) erfolgen. MSRBASIC bietet für das genannte Einsatzgebiet neben dem üblichen algorithmisch logischen Kern einer höheren Programmiersprache spezielle Sprachmittel an, die die Formulierung von - nebenläufigen Programmen (Multitasking), - hardwareabhängigen Prozeßzugriffen, - Zeitgebern - PI(D)-Reglerfunktionen, - Matrix-Vektor-Operationen - Kommunikationsfunktionen erlauben. Neben diesen sprachlichen Fähigkeiten, die MSRBASIC als Echtzeit- Sprache ausweisen, verfügt der MSRBASIC-Interpreter (im Sinne eines Programmiersystemes) über eine Reihe von Eigenschaften, die nicht nur die Erstellung, sondern auch die Fehlersuche, Wartung und (Re- )Dokumentation von MSR-Anwender-programmen unterstützt: - Integrität von Ziel- und Entwicklungssystem - integrierter serieller Hostanschluß (zum Programme laden, Daten versenden und entgegen- nehmen, Betrieb als intelligentes Terminal) - strukturorientiertes Ausdrucken von Programmen - Befehlsanzeige vor Ausführung zum Programmtest (Trace) - Anzeige des momentanen Programmzeigerstandes bei SE- QUENZEN (Aufspüren von Deadlocksituationen) - Fehlermeldung mit Quellzeilen-Auslisten - E/A-Simulator-Betriebsart Weitere für Realzeit-Mikrorechner notwendige Eigenschaften sind - EPROM-fähiger Zwischencode - Autoload- und Autostartfunktion Für den MSRBASIC-Interpreter ergibt sich damit ein breites Einsatzspektrum: - Einsatz in autonomen Regel- und Steuergeräten, insbesondere bei verfahrenstechnischen Anwendungen - Einsatz als Kontroller zusammen mit intelligenten Peripheriegeräten zur Experimentsteuerung - Einsatz bei Maschinensteuerungen - Einsatz als Meßwerterfassungs- und Protokolliersystem - Einsatz zur Ausbildung Die Summe dieser Eigenschaften machen MSRBASIC zu einem Instrument, -16-
  • 17.
    das für vielAnwender (Steuerungs- und Regelungs-techniker, Verfahrenstechniker, Chemiker, Physiker, Mediziner u.A.) eine wertvolle Hilfe darstellt. Das vorliegende Handbuch will in konzentrierter, aber hinreichend ausführlicher Form den Anwender bei der Handhabung des MSRBASIC- Interpreters unterstützen. Es setzt eine gewisse Vertrautheit mit der Grundsprache BASIC voraus und legt daher das Hauptgewicht auf die Behandlung der echtzeitspezifischen Fähigkeiten von MSRBASIC. 2.2 Anweisungen, Datentypen und Sonstiges In diesem Kapitel werden zunächst - im Sinne einer Übersicht - in alphabetischer Ordnung kurz einige allgemeine MSRBASIC- Eigenschaften behandelt, bevor im zweiten Teil ausführlich das MSRBASIC-Echtzeitkonzept erläutert wird. 2.2.1 Anweisungen Ein MSRBASIC-Programm besteht aus einer eindeutigen Folge von Anweisungen (Statements). Jede Programmanweisung beginnt mit einer Zeilennummer (1..65565), die die Lage der Zeile innerhalb des Programms festlegt. Einige Anweisungen können auch direkt ("direct mode"), d.h. quasi als Kommando eingegeben werden. Diese Eigenschaft ist insbesondere beim Echtzeitbetrieb von großer Bedeutung, da während der Programmausführung auf alle Variablen mit Hilfe von PRINT- und (LET-)Anweisungen zugegriffen werden kann. 2.2.2 Buchstaben MSRBASIC läßt die Verwendung von Klein- und Großbuchstaben zu. Bei Schlüsselwörtern (Kommandos, Anweisungen, Funktionen, Trennwörter und Systemvariablen) werden Kleinbuchstaben intern in Großbuchstaben umgewandelt. D.H. Eingaben wie "THEN", "then" oder "Then" werden intern als "THEN" behandelt. Dagegen werden Kleinbuchstaben in Variablennamen NICHT wie Großbuchstaben behandelt, d.h. ZEIT$ und sind zwei unterschiedliche Variable ! Zeit$ 2.2.3 Datentypen MSRBASIC kennt die Datentypen REAL und STRING. Integer-Zahlen werden intern als Gleitkommagröße behandelt. Der Datentyp ergibt sich implizit aus dem Programm. 2.2.4 Datenstrukturen Als Datenstrukturen sind ein- oder zweidimensionale Felder (s.d) vom Type REAL oder STRING möglich. 2.2.5 Editor -17-
  • 18.
    Bei der Eingabeeines Kommandos, einer Programmzeile oder eines Wertes (Zahl oder Text) ist ein Zeileneditor wirksam, d.h. daß innerhalb der momentanen Eingabezeile der Cursor bewegt, Zeichen eingefügt und gelöscht werden können. Einzelheiten siehe Kapitel "Editor". 2.2.6 Felder Es können ein- und zweidimensionale Felder für die Datentypen REAL und STRING benutzt werden. Der Index beginnt grundsätzlich bei 0 (NULL). Sofern der verfügbare Anwenderspeicher es zuläßt, können numerische Vektoren bis zur Dimension 8191 (8k) und Matrizen bis zur Ordnung 126x126 vereinbart werden. Stringfelder können maximal 255 Elemente aufweisen. 2.2.7 Funktionen Neben den BASIC-Standardfunktionen wie SIN, SQR bzw. CHR$ MID$ usw. werden folgende Typen von anwendungsbezogenen Funktionen zur Verfügung gestellt: - Auf und Abwärts-Zeitgeber - Zugriffe auf analoge und digitale Prozeßperipherie - Komplette Reglerblöcke (PI,PID) - Status- und Kommandofunktionen für die seriellen Kanäle - Kommunikationsfunktionen 2.2.8 Kanalnummern Die Ein-/Ausgabe von Zeichen und Texten erfolgt durch Befehle wie PRINT und INPUT die um einen "ON(kanalnummer)"-Zweig erweitert werden können. Je nach (Hardware-)Konfiguration werden damit neben der Konsole und dem Drucker auch Ein-Ausgabegeräte wie z.B. LCD- Anzeigen, Matrixtastaturen, weitere RS232-Schnittstellen usw. erreichbar. Es stehen die Kanalnummern 0..9 zur Verfügung. Bei den EPROM- startenden Systemen ist Kanal (0) (falls vorhanden) immer die Konsole. Kanal (1) ist als Druckerkanal vorgesehen. Die unbelegten Kanäle können zum Anschluß von Standardperipherie genutzt werden, eignen sich aber auch vorzüglich zur Anbindung komplexerere Schnittstellen wie z.B. IEC-Bus oder DFÜ-Kanäle. In den EPROM-startenden Systemen mit (optionalem) EEPROM-Anschluß erfolgt die "Programmierung" D des EEPROMS ebenfalls über einen "ON- ng" Kanal" (siehe hierzu das Kapitel Hardware-Anpassung). 2.2.9 Kommandos Die Kommandos im MSRBASIC sind Anweisungen an den Interpreter. Sie dienen entweder Editierzwecken (LIST, SAVE, LOAD, NEW) oder der Festlegung der Betriebsart (RUN, FREEZE, SYS). 2.2.10 Kommentare Kommentarzeilen werden durch "REM" eingeleitet. Sie dienen der Kommentierung von Programmsegmenten. -18-
  • 19.
    2.2.11 Operatoren In MSRBASICstehen folgende Operatoren zur Verfügung: Skalare Operatoren a) Rechenoperatoren: Wertigkeit Potenzoperator: ^ 3 Multiplikation: * 2 Division: / 2 Addition: + 1 Subtraktion: - 1 b) Vergleichsoperatoren: größer: > kleiner: < gleich: = größer-gleich: => oder >= kleiner-gleich: =< oder <= ungleich: <> oder >< c) Stringoperatoren Verkettung: + Matrix-Operatoren Multiplikation: * 2 Element-Multipl.: . 2 Addition: + 1 Subtraktion: - 1 2.2.12 Programm MSRBASIC kennt drei Typen von Programmen: Das Rahmen- oder Grundprogramm entspricht dem üblichen BASIC- Programm. Es wird über das RUN-Kommando oder einen unmittelbaren GOTO-Befehl gestartet. Die Beendigung des Programmes erfolgt über die entsprechenden Anweisungen (RETURN, STOP, END), über die Fehlermeldungen oder durch ein Abbruch-Kommando vom der Konsole aus (Eingabe von CNTRL-C). Der zweite MSRBASIC-Programmtyp heißt TASK und wird zyklisch vom Echtzeitbetriebssystem gestartet. (siehe nächsten Abschnitt). Sollen alle zyklischen Programme angehalten und nicht mehr neu gestartet werden, CNTRL-D einzugeben. Der dritte MSRBASIC- Programmtype ist die SEQuenz. auch sie wird vom Echtzeitbetriebssystem gestartet (s.u.). Das Anhalten aller Sequenzen geschieht durch die Eingabe von CNTRL-A. 2.2.13 Starten des Interpreters Sofern im BASIC-Programmspeicher ein intaktes Programm vorhanden ist, führt MSRBASIC automatisch einen AUTO-Warmstart durch, d.h. die Anwendervariablen werden nicht gelöscht, das Programm wird ab der ersten Programmzeile ausgeführt. Hinweis: -19-
  • 20.
    Bei jedem Neustartprüft MSRBASIC ob im (u.U. auch geschützten CMOS- RAM) ein "sinnvolles" Programm steht. Ist dies der Fall, so wird dieses Programm ausgeführt, evtl. Fehler werden spätestens bei der Interpretation erkannt. Wurde der Neustart z.B. durch einen Stromausfall oder ein gezieltes An- und Abschalten verursacht, so muß die (anwenderseitige) Neuinitialisierung von Parametern umgangen werden. Dies geschieht am einfachsten durch Verwendung einer (benutzerdefinierten) Variablen: 100 REM beim ersten Kaltstart werden alle Variablen 110 REM auf NULL gesetzt, es gilt also beim Kaltstart 120 IF IniFlg <> 0 THEN GOTO 200 130 REM Initialisierung von Variablen beim Warmstart 140 LET A=123 150 DIM X1(16), A(X,Y) : : und was sonst noch gemacht werden muß... : Achtung: Bausteine wie PIO, CIO usw. : nach jedem RESET neu initialisieren! : ... dann IniFlg <> 0 setzten : 190 IniFlg=55 200 REM *** Hier gehts bei Warmstart weiter *** : Bei Kaltstart erfolgt eine Initialisierung der Echtzeituhr, des Taskumschalters und des Arbeitspeichers, sowie eine konfigurationsabhängige Kaltinitialisierung der Prozeß-Ein/Ausgabe. In der Regel bedeutet dies z.B. für die binären Stellsignale ein Schalten in den stromlosen Zustand. Bei Warmstart wird die Echtzeituhr initialisiert und das ACTIVE-Bit aller TASKS und SEQuenzen zurückgesetzt, um einen definierten Neu- bzw. Wiederstart zu gewährleisten. Außerdem wird eine konfigurationsabhängige Warminitialisierung der Prozess-Ein/Ausgabe vorgenommen. Dies bedeutet z.B. für die binären Stellsignale, daß die E/A-Bausteine in Ausgaberichtung neu programmiert werden. In EPROM-startenden (Stand-Alone-)Systemen gibt es noch zwei weitere Startvarianten, nämlich den Autostart eines in (E)EPROM abgelegten Anwenderprogrammes bzw. das automatische Laden eines Programmes von einem voreinstellbaren seriellen Kanal und anschließende Starten. 2.2.14 Transparent-Betrieb (virtuelles Terminal) MSRBASIC unterstützt für die SAVE-, LOAD und LIST-Kommandos den Datenverkehr von und zu einem übergeordneten Rechner (Host). Bei Ausführung dieser Kommandos geht der Interpreter vorübergehend in den Transparent-Betrieb, d.h. der Host-Rechner empfängt die nach dem Kommando eingegebenen Zeichen und das MSRBASIC-Terminal zeigt die Antworten des Host. Erst die Eingabe eines speziellen Fluchtsymboles (CNTRL-A) veranlaßt dann die Ausführung des Kommandos. 2.2.15 Variable Ein MSRBASIC-Programm kann maximal 255 verschiedene Variable aufweisen. Es gibt vier Arten von Variablen, nämlich Skalare und Felder jeweils vom Typ REAL oder STRING. Jede Variable trägt einen Namen der maximal sechs Zeichen lang sein -20-
  • 21.
    kann. Das ersteZeichen muß ein Buchstaben sein, als folgende Zeichen sind Buchstaben, Ziffern und der Unterstrich "_" erlaubt. Aus Gründen der Kompatibilität zu Microsoft-Basic sind auch die Zeichen "%" und "#" zugelassen. Stringvariable (Zeichenkettenvariable) sind durch ein "$"-Zeichen zusätzlich zum Variablennamen gekennzeichnet. Beispiele: A_min, a0$, Azeich(2), ESC$, X$(1,2) Die maximale Länge von Stringvariablen wird bei der MSRBASIC- Konfiguration festgelegt (Voreinstellung: 40 Zeichen). Stringfelder weisen als Elemente Stringvariable auf. Die Namen der Wochentage können z.B. in ein Stringfeld abgespeichert werden: DIM WO$(7) WO$(1)="Montag" 2.2.16 Zahlenbereich Die größte Zahl die von MSRBASIC verarbeitet wird, ist 4.61168E+18, die kleinste 6.46235E-27. Tritt bei einer arithmetischen Operation ein Überlauf auf, erfolgt eine Fehlermeldung. Dagegen wird bei einem Unterlauf das Ergebnis automatisch zu Null gesetzt. Es können Integer- (Ganzzahl-), Festkomma- und Gleitkommazahlen mit und ohne Exponent eingegeben werden. Es dürfen jedoch nicht mehr als sieben Stellen (bei entsprechender Genauigkeit) eingegeben werden. Darüberhinaus ist es möglich HEX(Sedezimal-)Werte im Bereich 0000..FFFF ein- bzw. auszugeben. Die Syntax für die Eingabe lautet: &Hnnnn mit nnnn = 0..FFFF Die entsprechende Ausgabe erfolgt über die "PRINT..AS.."-Anweisung 3. Editor-Funktionen 3.1 Übersicht In MSRBASIC stehen bei der Eingabe von Programmzeilen komfortable Editierfunktionen zur Verfügung.Eine weitere Komfortsteigerung bringt die erweiterte Syntaxprüfung bei der Programmzeilen-Eingabe, die fehlende Klammern oder Anführungszeichen sofort entdeckt. Damit werden MSRBASIC- Programme auch sicherer, da syntaxbedingte Laufzeitfehler verringert werden. 3.2 Funktionsbeschreibung Bei der Eingabe einer Programmzeile (oder von INPUT aus) ist grundsätzlich der "Einfüge-Modus" in Kraft. Folgende Editierfunktionen stehen zur Verfügung: 64444444444;44444444444444444444444444444444444444444444444447 5Taste 5 Funktion 5 :4444444444>4444444444444444444444444444444444444444444444444< 5 5 5 5CNTRL-A 5 Cursor eine Position nach links 5 5CNTRL-F 5 Cursor eine Position nach rechts 5 -21-
  • 22.
    5DEL,BS 5 Zeichen links vom Cursor löschen 5 5CNTRL-G 5 Zeichen unter dem Cursor löschen 5 5CNTRL-X 5 ganze Zeile löschen 5 5CR 5 Eingabe beenden 5 5CNTRL-C 5 Eingabe abbrechen 5 5CNTRL-B 5 Cursor zum Ende/Anfang der Zeile positionieren 5 5 5 5 94444444444=44444444444444444444444444444444444444444444444448 Alle andere Steuerzeichen werden ignoriert. 3.3 Änderung vorhandener Programmzeilen Um bereits vorhandene Programmzeilen mit Hilfe der oben beschriebenen Editorfunktionen zu ändern, ist die entsprechende Zeile durch "# <Zeilennummer>" oder "SAVE <Zeilennummer>" bzw. "LIST <Zeilennumer>" anzuwählen. Bei allen genannten Aufrufen wird die angewählte Zeile ausgelistet, der Cursor bleibt jedoch am Ende der Zeile stehen. Mit CNTRL-A (Drücken der Tasten CNTRL und "A" gleichzeitig wird der Cursor, ohne die "darunter" liegenden Zeichen zu löschen, nach links bewegt. Mit CNTRL-F kann der Cursor nach rechts, bis zum Zeilenende bewegt werden. Im Editiermodus ist die Eingabe immer auf "Einfügen" geschaltet, d.h. ab der momentanen Cursorposition kann neuer Text geschrieben werden; evtl. rechts vom Cursor stehender Text wird automatisch weiter nach rechts verschoben. Soll ein Zeichen gelöscht werden kann dies mit CNTRL-G geschehen, wenn das Zeichen "unter" dem Cursor gelöscht werden soll, mit DEL, BS (oder CNTRL-H) können die Zeichen rechts vom Cursor gelöscht werden. Der rechts vom Cursor verbleibende Text wird aufgerückt. Mit CNTRL-B kann der Cursor vom Zeilenende zum Zeilenanfang (und zurück) positioniert werden. Mit CR (möglich an jeder beliebigen Cursorposition) wird die bearbeitete Zeile übernommen. Dies bedeutet gleichzeitig, wenn beim Editieren die Zeilennummer gelöscht wurde, daß auch die ganze Zeile gelöscht wird. Soll (auch nach bereits vorgenommener Änderung) der "alte" Zeileninhalt doch übernommen werden, kann die zu editierende Zeile mit CNTRL-C unverändert verlassen werden. Nach Abschluß der Bearbeitung der laufenden Zeile zeigt das LIST- Kommando in dieser Betriebsart die nächste Zeile in der gleichen Weise an. Durch Eingabe von CNTRL-C wird der Editiermodus verlassen. Hinweis: Syntaxfehler: Werden bei der Programmeingabe Syntaxfehler erkannt, wird die fehlerhafte Zeile nach der Fehlermeldung "Syntax-Fehler" automatisch im -22-
  • 23.
    Editier-Modus zur Fehlerkorrekturangeboten. FREEZE-Betrieb: Im Echtzeitbetrieb sind die Editiermöglich- keiten unterbunden. -23-
  • 24.
    4. Echzeitspezifische Sprachmittel 4.1Übersicht Um die Echtzeitmöglichkeiten von MSRBASIC angemessen einsetzen zu können, ist es neben der Kenntnis der Einzelbefehle vor allem notwendig, sich mit dem im folgenden beschriebenen Grundkonzept vertraut zu machen. 4.1.1 MSRBASIC-Echtzeitkonzept Die MSRBASIC-Echzeit-Philosophie wird deutlich, wenn man Automatisierungsaufgaben bei industriellen Prozessen hinsichtlich ihres Zeitverhaltens unterteilt. Im wesentlichen lassen sich hierbei zwei Grundtypen von Verarbeitsfunktionen erkennen: 1. immer oder zeitweise im Eingriff befindliche "zeitkontinuierliche" Funktionen wie z.B. lineare Regelung, Überwachung und Verriegelung, Filterung u.a.m. 2. Zeit- oder prozeßgeführte Ablaufsteuerungen, in denen sich ein ereignisdiskreter Prozeßablauf widerspiegelt, wie z.B. aufeinanderfolgende Bearbeitungsschritte an einer Werkbank, das Anfahren einer bestimmten Position oder das Abwarten einer Grenzwertüberschreitung. Diesem Dualismus trägt MSRBASIC im Gegensatz zu vielen Echtzeitsprachen durch das explizite Bereitstellen von zwei nebenläufigen Programmtypen Rechnung, nämlich TASK für zyklisch zu startenden Programme und SEQuenz für Ablaufsteuerungs-Programmteile. Bei reinen Regelungsanwendungen werden nur TASKs verwendet, während z.B. bei der zeitgesteuerten Änderung der Sollwerte, etwa beim Abfahren eines Temperaturprofils, die Sollwertvariable der Regeltask durch eine SEQuenz zu bestimmten Zeiten verändert wird. Anderseits sind rein ereignis-orientierte (Fertigungs-, Montage- u.a.) Prozesse durch parallele Abläufe gekennzeichnet, da sich oft mehrere Werkstücke in aufeinanderfolgenden Sektionen einer gemeinsam gesteuerten Bearbeitungsmaschine befinden. Solche zeitgleichen Abläufe werden durch verbale Spezifi-kationen, Petri-Netze oder Funktionspläne beschrieben oder dargestellt. Diese Beschreibungsformen lassen sich sehr leicht in MSRBASIC-SEQuenzen übertragen, denn es sind gleichzeitig mehrere aktive SEQuenzen zulässig. Bei gleichzeitig lauffähigen SEQuenzen wird ggf. die Prozessorzeit aufgeteilt. Die grundlegend unterschiedliche Aufgabenstellung von TASKs und SEQuenzen muß auch vom Programmierer berücksichtigt werden: TASKs sollen automatisch gestartet und möglichst in einem Zug abgearbeitet werden, um ihrer quasikontinuierlichen Funktion gerecht zu werden. Ideal wäre für sie eine unendliche kurze Ausführungszeit und eine unendlich hohe Aufruffrequenz. 644444444444444444444444444444444444444L4444444444444444444447 5 kontinuierliche * ereignisorientierte5 5 MSR-Funktionen * MSR-Funktionen 5 -24-
  • 25.
    :4444444444L444444444444444444444444444P444444444444444444444< 5Beispiel * Regelungen * Ablaufsteuerungen 5 5 * Überwachung-Verriegelung * mit Wartebedingungen5 :4444444444P444444444444444444444444444P444444444444444444444< 5grafische * Signalflußplan * Funktionsplan 5 5 * * 5 :4444444444P444444444444444444444444444P444444444444444444444< 5Dar- * * Petri-Netz 5 5stellungs-* * 5 5form * +--------+ * ! 5 5 * Xe ! ! Xa * ! +--- 5 5 *--- ! ! --- * ! ! 5 5 * ! ! * +-----+--+-+ 5 5 * / ! ! / * ! ! 5 5 *--- ! ! --- * +-----+----+ 5 5 * ! ! * ! 5 5 * +--------+ * ! +--- 5 5 * * ! ! 5 5 * * +-----+--+-+ 5 5 * * ! ! 5 5 * * +----------+ 5 5 * * 5 :4444444444P444444444444444444444444444P444444444444444444444< 5MSRBASIC * TASK * SEQuenz 5 5Prg.Typ * * 5 5 * * 5 94444444444N444444444444444444444444444N4444444444444444444448 Schaubild 4.1 Einteilung der MSR-Funktionen Dagegen hängt die Ausführungsgeschwindigkeit einer SEQuenz kaum von der Rechengeschwindigkeit des Prozessors, sondern vom Zustand des technischen Prozesses ab. Die für eine SEQuenz typische Abhängigkeit der Programmfortsetzung vom Prozeßzustand wird allgemein als "Weiterschaltbedingung" bezeichnet. Hierzu bietet MSRBASIC ein spezielles Sprachmittel, nämlich die WAIT-Anweisung (s.d.) an. Im Vergleich zur IF-Anweisung bietet sie eine der Gegebenheit besser angepasste Formulierung, die deutlich macht, daß das Ablaufsteuerungsprogramm bei der Weiterschaltbedingung verharren soll, bis diese erfüllt ist. Eine spezielle, für technische Einsätze aber fast unumgängliche Eigenschaft der WAIT-Anweisung ist die integrierte Überwachung der Wartezeit mit der Möglichkeit zur Ausnahmebehandlung. Damit können Fehler im technischen Prozess erkannt und abgefangen werden. Dies wird bei MSRBASIC durch die Erweiterung der Anweisung auf WAIT MAX <zeit> .. ermöglicht. Die WAIT-Anweisung erleichtert auch die interne Verwaltung der verschiedene quasiparallelen Programme. Sie bietet im Gegensatz zur IF-Anweisung dem Echtzeitbetriebssystem eine elegante Möglichkeit, die laufende SEQuenz zu unterbrechen und die Ausführung anderer Echtzeitprogramme zu veranlassen. Im folgenden Abschnitt wird summarisch erläutert, wie der Anwender -25-
  • 26.
    die MSRBASIC-Echtzeitmittel handhabt. 4.1.2Organisation und Handhabung des Echtzeitbetriebes In MSRBASIC Version 4.0 kann der Anwender bis zu 5 zyklische Programme (TASKs) und bis zu 25 Ablaufsteuerungen (SEQuenzen) nebenläufig (quasigleichzeitig) betreiben. Hierzu stehen ihm als Sprachmittel die Anweisungen WAIT, DEFINE, START, ACTIVATE und SUSPEND (s.u.) zur Verfügung. Der Echtzeitbetrieb ist durch folgende Eigenschaften gekennzeichnet: - TASKs werden als normale BASIC-Unterprogramme geschrieben und über die DEFINE-Anweisung durch Angabe der Nummer (Gleichzeitig auch Priorität), des Aufruf-Zeitintervalls und der Startzeilennummer in die Echtzeitverwaltung integriert. - SEQuenzen werden ebenfalls als Unterprogramme geschrieben und durch Angabe der Nummer und der Startzeile in die Sequenzverwaltung eingegliedert. - Die START bzw. ACTIVATE-Anweisung gibt die zyklische Bearbeitung von TASKs bzw. die einmalige Ausführung von SEQuenzen frei. - Mit der SUSPEND-Anweisung können TASKs und SEQuenzen gezielt aus der Bearbeitung durch das Betriebssystem herausgenommen werden. - Höher priore TASKs können aktive Programme niederer Priorität (= TASKs, SEQuenzen oder das Hintergrundprogramm) unterbrechen, wobei das laufende Statement noch bearbeitet wird, um inkonsistente Daten zu vermeiden. - Die Quasinebenläufigkeit der SEQuenzen orientiert sich an den einzelnen Schritten der Ablaufsteuerung. Dies bedeutet, daß eine SEQuenz solange Rechenzeit inan-spruch nimmt, bis sie auf die nächste Weiterschaltbedingung (WAIT) stößt (s.d.), also einen Ablaufschritt ausgeführt hat, oder ein bestimmtes Rechenzeitintervall (10ms) erbraucht hat. Erst danach wird auf die nächste SEQuenz umgeschaltet bis alle SEQuenzen auf die Erfüllung ihrer momentanen Weiterschaltbedingung warten. Diese werden vom Echtzeitbetriebssystem zyklisch unter Beachtung der Priorität überprüft. - Werden keine Echtzeitprogramme ausgeführt, steht der MSRBASIC-Interpreter für das Rahmenprogramm, Kommandos und direkte Anweisungen zur Verfügung. - Da alle Variablen global gültig sind, kann der Benutzer auch ohne spezielles Kommunikationsprogramm während des Echtzeitbetriebes auf alle Variablen mit Hilfe der LET / PRINT-Anweisung zugreifen. - Der Datenaustausch zwischen den Echtzeitprozessen geschieht ebenfalls über die globalen gültigen Variablen. Damit sind alle Voraussetzungen für einen flexiblen Echtzeitbetrieb erfüllt, wobei MSRBASIC durch eine Reihe echtzeitorientierter -26-
  • 27.
    Fehlersuch-Hilfen (SEQLIST, TASKLIST,TRACE SEQ, TRACE TASK) von vorneherein eine hohe Transparenz gewährleistet. 4.1.3 Beispiel: "Meßwerterfassung" Als einfaches Beispiel soll eine typische Meßwerterfassungsaufgabe betrachtet werden, bei der die Sprungantwort einer Regelstrecke aufgenomen werden soll: +--------------+ ! Regelstrecke ! DAC(1)------>! !------> ADC(1) ! ! +--------------+ Bild 4.2 Konfiguration "Identifikation einer Regelstrecke" Diese Aufgabe gliedert sich in mehrere Phasen: 1. Initialisierung von Meßaufbau und Regelstrecke 2. Aufnahme der Meßwerte 3. Verarbeiten der Meßwerte (Filtern, Archivieren) Das nachfolgende Programm "MESSDEM.BAS" zeigt eine mögliche Implementierung dieser Aufgabe. Der Initialisierungsteil (Zeilen 100..190) enthält als wesentlichen Teil die Deklaration der verwendeten Echtzeitprogramme (SEQ1, TASK1) und startet SEQ1. Das Hauptprogramm (Zeilen 1000..1200) weist genau die oben beschriebene Ablaufstruktur auf und wird als SEQuenz ausgeführt. Entsprechend dem zweigleisigen MSRBASIC-Echtzeitkonzept ist es in der Phase 2 naheliegend, das zyklische Einlesen, Filtern (PT1) und Ablegen von Meßwerten einer TASK zuzuordnen. Diese TASK (Zeilen 2000..2060) wird zu Beginn der Phase 2 von der SEQuenz zur zyklischen Bearbeitung freigegeben (AKTIVATE TASK1) und bei Erfüllung eines bestimmten Kriteriums (hier: alle n Meßwerte eingelesen) wieder gesperrt (SUSPEND TASK1). In der letzten Phase werden die Meßwerte auf eine Datei abgespeichert. -27-
  • 28.
    4.1.4 Listing "MESSDEM.BAS" 100 REM **** MESSDEM.BAS **** 105 PRINT "Wieviele Messwerte"; 110 INPUT N 120 DIM X(N),TDOWN(1) 130 PRINT "Tastzeit TS in Sekunden"; 140 INPUT TS 145 PRINT "Zeitkonstante des Vorfilters"; 150 INPUT TF 155 REM Filtertastrate ist um Faktor 10 groesser 160 TSF=TS/10, A=EXP(-TSF/TF), B=1-A 170 DEFINE TASK1, TSF, 2000, SEQ1, 1000 180 START SEQ1 190 STOP Initialisierung 1000 REM **** Sequenz 1 steuert das Experiment **** 1010 REM zunaechst Stellsignal 0 ausgeben 1020 DAC(1)=0 1040 WAIT 5 <=0 1050 DAC(1)=1, NZ=N, I=1, TDOWN(1)=TSF 1060 START TASK1 1070 PRINT "Messung gestartet" 1080 WAIT FOR NZ=0 1090 SUSPEND TASK1 1100 PRINT "Messung beendet" 1110 PRINT "In welcher Datei sollen die Messwerte " 1120 PRINT " abgespeichert werden"; 1130 INPUT FN$ 1140 OPEN FN$,10,0 1150 REM Abspeicherungsschleife 1160 FOR I=1 TO N 1170 PRINT ON(10) X(I) AS 10F3 1180 NEXT I 1190 PRINT" Experiment beendet" 1200 RETURN Sequenz 1 2000 REM **** TASK1 misst zyklisch den Streckenausgang **** 2010 X=A*X+B*ADC(1) 2020 IF TDOWN(1)>0 THEN RETURN 2040 TDOWN(1)=TS 2050 X(I)=X, I=I+1, NZ=NZ-1 2060 RETURN Task -28-
  • 29.
    4.1.5 Empfehlungen undWarnungen Die MSRBASIC-Echtzeitfähigkeiten müssen mit Maß und Ziel angewandt werden, um ein stabiles, verklemmungsfreies Echtzeit-Anwenderprogramm zu gewährleisten. Insbesondere darf die leichte Handhabbarkeit und Flexibilität des Multitasking nicht zu einer übertriebenen Parallelisierung des Anwenderprogrammes führen. Grundvoraussetzung für ein tragfähiges Echtzeit-Programm ist eine klare Spezifikation und ein darauf abgestimmtes Programmkonzept. Hierbei sollten einerseits Funktionen (z.B. Regler gleicher Tastzeit, streng sequentielle Aktionen), die nicht unbedingt parallel laufen müssen, durchaus in einer TASK oder SEQuenz zusammengefaßt werden. Andererseits sollten insbesondere bei ereignisorientierten Rechenprozessen (Ablauf-steuerungen) alle Ereignisse und Aktionen, die parallel statt-finden können, auf jeweils eine SEQuenz abgebildet werden. Hierbei leistet eine Darstellung der Aufgabe in Form eines Petri-Netzes wertvolle Hilfe, da es den Grad an jeweils not-wendiger Parallelität strukturell ausweist. Als weitere Grundregel bei der Konstruktion von Echtzeitsystemen sollte man bei der Auslegung der Abtastzeit eher restriktiv vorgehen, um der Gefahr einer auch nur partiellen Überlastung des Rechners vorzubeugen. Als Faustregel für "Durchlauf-"zeiten kann man von einer Bearbeitungszeit von 1..2 ms, bei komplexen Anweisungen auch bis zu 10ms pro Programmzeile rechnen. Damit ergibt es sich aber auch, daß Wartebedingungen im us-Bereich unrealistisch sind. TASK's mit Aufrufintervall von 10ms werden andere Programme deutlich "bremsen" wenn nicht gar völlig totlegen. -29-
  • 30.
    5. Zusammenfassung derechtzeitspezifischen Befehle Diese Zusammenfassung beschreibt alle Befehle und Funktionen, die nicht im Standard-Sprachumfang enthalten sind oder vom dort-igen Gebrauch abweichen. Bei der Syntax-Beschreibung werden folgende Abkürzungen ver-wendet: { } die geschweifte Klammer umfaßt Optionen Beispiel: DEF{INE} es kann sowohl DEF als auch DEFINE geschrieben werden. < > Die spitze Klammer umfasst in der Syntax- beschreibung nicht nennbare Daten. Beispiel: <zn> für Zeilennummer | Dieses Zeichen trennt Wahlmöglichkeiten Beispiel: TASK|SEQ Es kann TASK oder SEQ verwendet werden. {,...} Wiederholungsschleife d.h. der angegebene Teil kann mehrfach definiert werden. zn Zeilennummer sz Startzeile pp Portadresse (Bereich 0..255) n Nummer (allgemein) i Intervall cr Zeilenende -30-
  • 31.
    5.1 DEFINE Syntaxdiagramm: Aufruf:<zn> DEF{INE}{TASK <n>,<i>}|{SEQ <n>},<sz>{,....} <cr> Funktionsbeschreibung: Die einzubindenden TASKs oder SEQuenzen werden dem Echzeitbetriebssystem unter Angabe ihrer Kenndaten n = Nummer und gleichzeitig Priorität 1..5 bei TASK's und 1..25 bei SEQuenzen sz = Startzeile und bei TASK's i = Aufrufintervall mit dieser Anweisung bekanntgegeben. Bei TASKs beträgt das Aufrufintervall maximal 2.54s. Alle Zeitangaben werden auf 10ms-Stufung abgerundet. Beispiele: 1000 DEF TASK 1,T1,2000,TASK 2,2*T1,2200,SEQ 1 3000 oder besser lesbar .. 100 NotAus = 1, Regler = 2, t_reg = 5 : 1000 DEF SEQ NotAus,2000,TASK Regler,t_reg,4000 Hinweise: Die höchste Priorität hat jeweils die TASK bzw. SEQuenz mit der niedersten Nummer. Werden Namen verwendet, müssen sie vorher als Variable vorbelegt werden, z.B. NotAus = 1 Regler = 1 t_reg = 5 Achtung: Zeilennummern sind nicht als Variable einsetzbar! Soll eine TASK mit einer größeren Abtastzeit als 2.54s aufgerufen werden, bietet MSRBASIC über die Timer-Funktion TDOWN folgende -31-
  • 32.
    Lösungsmöglichkeit: 100 REM *** Initialisierung *** 120 DEF TASK 1, 2, 1000 130 DIM TDOWN(1) 140 TA=60, TDOWN(1)=1 150 ACTIVATE TASK 1 : : 1000 REM *** TASK 1 1010 IF TDOWN(1)>0 THEN RETURN 1020 TDOWN(1)=TDOWN(1)+TA 1030 REM .. Ab hier beginnt die TASK eigentlich .. Diese Lösung bietet die Gewähr, daß selbst bei TASK-Ausführungs-zeiten >2s keine grob falschen Fehler in den Aufrufintervallen entstehen. Fehler: 05 TASK bzw SEQ mit der gewünschten Startzeile existiert nicht 13 Nummer von TASK bzw. SEQ ist zu groß oder Zeitintervall größer als 2.54s -32-
  • 33.
    5.2 START Syntaxdiagramm: Aufruf: <zn> START {TASK|SEQ} {ALL|<n>} {,....} <cr> Funktion: Die im Argument der Startanweisung angegebenen TASKs werden zur zyklischen Bearbeitung durch das Betriebssystem freigegeben. Die Bearbeitung wird grundsätzlich bei der ersten Programmzeile aufgenommen. Der START-Aufruf kann für alle (ALL) TASK's bzw. SEQuenzen oder gezielt für eine Einzelne (mit Nummer <n>) erfolgen. Beispiel: 100 START TASK ALL, SEQ 1 oder 100 START TASK 1, TASK 2, SEQ 1 Fehler: 26 TASK bzw. SEQ noch nicht definiert 40 Interpreter nicht im Echtzeitbetrieb (FREEZE-Mode) -33-
  • 34.
    5.3 SUSPEND Syntaxdiagramm: Aufruf: <zn> SUS{PEND} {TASK|SEQ} {ALL|<n>} {,...} <cr> Funktion: Die SUSPEND-Anweisung ermöglicht das Stillegen einzelner (mit Nummernangabe <n>) oder aller (ALL) TASKs bzw. SEQuenzen. Hierbei wird die SEQuenzbearbeitung an der momentanen Stelle (in der Regel an einer WAIT-Anweisung) sofort abgebrochen, wobei evtl. aktivierte Überwachungs-Zeitgeber (WAIT-MAX-Funktion) ebenfalls eingefroren werden, um bei Re-Aktivierung (siehe ACTIVATE) eine sachfremde Fehlerbehandlung (...ELSE...) zu vermeiden. Die Stillegung von TASKs bedeutet, daß eine laufende TASK zu Ende gebracht wird, jedoch kein Neustart erfolgt. Um bei Programmierfehlern eine schnelle Abbruchmöglichkeit bereitzustellen, können in der Kommandobetriebsart mit CNTRL-D alle TASKs und mit CNTRL-A alle SEQuenzen stillgelegt werden. Sofern dies aufgrund von Endlosschleifen nicht ausreichen sollte, kann über CNTRL- C ein endgültiger Programmabbruch erzwungen werden. Beispiel: 1000 SUSPEND TASK ALL, SEQ 1 Fehler: 26 TASK bzw. SEQ noch nicht definiert 40 Interpreter nicht im Echtzeitbetrieb (FREEZE-Mode) -34-
  • 35.
    5.4 ACTIVATE Syntaxdiagramm: Aufruf:<zn> ACT{IVATE}{TASK|SEQ} {ALL|<n>{,<sz>}} {,...} <cr> Funktion: Die im Argument der ACTIVATE-Anweisung (mit Nummer <n> und Startzeile <sz> oder ALL) angegeben TASKs werden zur zyklischen Bearbeitung durch das Betriebssystem freigegeben. Die Bearbeitung der angegebenen SEQuenzen wird im Gegensatz zur START-Anweisung immer in der aktuellen Zeile fortgesetzt. Dies ist entweder die erste Zeile der SEQuenz, falls sie noch nicht bearbeitet, oder bereits einmal komplett durchlaufen wurde. Falls aber die SEQuenz durch eine SUSPEND-Anweisung (oder durch ein CNTRL-A) abgebrochen wurde, bewirkt die ACTIVATE-Anweisung eine Wiederaufnahme der SEQuenz-Bearbeitung an der unterbrochenen Stelle. Beispiel: 100 ACTIVATE TASK Regler, SEQ NotAus,2050 Fehler: 05 gewünsche Startzeile existiert nicht 26 TASK bzw. SEQ noch nicht definiert 40 Interpreter nicht im real-time-mode (FREEZE-mode) -35-
  • 36.
    5.5 WAIT Syntaxdiagramm: Aufruf: a) <zn> WAIT <Zeit> b) <zn> WAIT FOR <Bedingung> c) <zn> WAIT MAX <Zeit> FOR <Bedingung> d) <zn> WAIT MAX <Zeit> FOR <Bedingung> ELSE <zn> |<Anweisung> e) <zn> WAIT FOR <b1>,...<bn> THEN <zn1>,..<znn> f) <zn> WAIT MAX <Zeit> FOR <b1>,..<bn> THEN <zn1>,..<znn>... ... ELSE <Anweisung> mit bn = Übergangsbedingung(en) Funktion: Die WAIT-Anweisung dient im Rahmen von SEQuenzen zur Formulierung von Weiterschaltbedingungen. In der Form a)..d) unterstützt sie die in der Praxis besonders häufigen linearen Ablauf-steuerungsstrukturen. Im allgemeinsten Fall kann jedoch eine Ablaufsteuerung aus einem Zustand in mehrere Folgezustände übergehen. Hierbei sind Zustandsgrafen ein geeignetes Darstellungsmittel wie folgendes Diagramm zeigt: +)))))))))))))), B21 * * B31 +)))))))))))))>1 X1 /<)))))))))))), * * * * * .))))))))))))))- * * * * * * * * * B12 * *B13 +))))))v)))))))), +))))))))v)))))))), * * * * * X2 /<)))))))))))))))))))))))>1 X3 * * * B32 B23 * * .)))))))))))))))- .)))))))))))))))))- Bild: Zustandsdiagramm für eine Steuerung mit 3 Zuständen Dieser Zustand kann mit der Form e) und f) der WAIT-Anweisung formuliert werden. Hierbei bestimmen bei der internen zyklischen Prüfung der Weiterschaltbedingungen die erste erfüllte Bedingung -36-
  • 37.
    <bn> die Zeilennummer<szi>, bei welcher die SEQuenz fortgesetzt wird. Ist die Weiterschaltbedingung innerhalb einer vorgegebenen Überwachungszeit (MAX ...) erfüllt, wird wie bei der IF-Anweisung das Programm mit der nächsten Zeile fortgesetzt, ansonsten erfolgt eine programmierbare Fehlerbehandlung, die mit ELSE eingeleitet wird. Hinweis: Der Zeit-Takt ist auf 1s voreingestellt. Dieser Wert kann mit den Funktionen TDOWN und TUP verändert werden (siehe dort). In Unterprogrammen ist WAIT nicht erlaubt. -37-
  • 38.
    Beispiele: zu a) 1000 REM *** 10 Minuten warten *** 1020 WAIT 10*60 zu d) 2000 REM Weiterschaltbedingungen mit Zeitüberwachung 2010 WAIT MAX 100 FOR ADC(1)>X0 ELSE 3000 : 3000 PRINT "Füllstand nicht rechtzeitig erreicht" 3010 REM *** Einlaßventil schließen *** 3020 DOUT(1)=0 3030 STOP zu d) 4000 REM *** Boolsche Bedingung *** 4010 WAIT MAX 10 FOR DIN(1)*(DIN(6)+NOT(DIN(7)) >=1 ELSE zu b) 5000 WAIT FOR DIN (Hand) + DIN (NotAus) ist äquivalent zu: 5000 WAIT FOR DIN (Hand) + DIN (NotAus) > 0 Fehler: 14 unerlaubte Relation im Bedingungsteil 27 WAIT wurde ausserhalb einer SEQuenz benutzt 39 WAIT in GOSUB-Unterprogrammen nicht erlaubt -38-
  • 39.
    5.6 TRACE Syntaxdiagramm: Aufruf: <zn> TR{ACE} {SEQ{<n>}|TASK} Funktion: Beim Einschalten des TRACE-Modus wird beim Programmablauf jede Zeile vor ihrer Ausführung auf der Konsole aufgelistet. Außerdem werden bei der Ausführung einer INPUT-Anweisung auf einem nicht-interaktiv konfigurierten Kanal die eingegebenen Zeichen auf der Konsole angezeigt. Folgende Varianten sind möglich: a) Auslisten aller Befehle (TRACE ohne Zusatz) b) Auslisten aller SEQuenz-Anweisungen (TRACE SEQ) c) Auslisten aller TASK-Aneisungen (TRACE TASK) d) Ein- und Ausschalten einzelner SEQuenzen (TRACE SEQ <sz>) Hinweis: Die Variante b) des TRACE-Befehls ist insbesondere dann vorteilhaft, wenn man nur den in einer SEQuenz implementierten übrgeordneten Ablauf verfolgen will, nicht jedoch die unterlagerten, zyklischen TASK-Module. Durch die Variante d) läßt sich TRACE auch dann noch sinnvoll nutzen, wenn viele SEQuenzen aktiv sind. Wird eine SEQuenz im TRACE-Modus ausgelistet, dann erscheint die SEQuenz-Nummer an der linken Seite der Zeile (wie bei SEQLIST). Beispiel: Der folgende Ausschnitt des TRACE-Laufes von drei SEQuenzen zeigt anschaulich die für diesen Programmtyp wirksame Multitasking- Strategie nach dem round-robin-Prinzip S01: 1230 DOUT(1)=1 S02: 2210 DOUT(5)=0, DOUT(6)=0 S03: 3240 Presse=0 S01: 1240 WAIT MAX 10 FOR DIN(1)=0 ELSE 4010 S02: 2220 Fix1=1 : Fix2=0 S03: 3250 WAIT MAX 5 FOR DIN(19)=1 ELSE 6120 S02: 2230 WAIT FOR Fix3=0 5.7 NOTRACE Syntaxdiagramm: -39-
  • 40.
    Aufruf: <zn> NOTR{ACE} {SEQ|TASK} Funktion: Abschalten des TRACE-Modus, global oder fuer TASKs bzw. SEQuenzen -40-
  • 41.
    5.8 TASKLIST Syntaxdiagramm: Aufruf: <zn> TASKLIST|TL Funktion: Auslisten der Startzeile, der Priorität und des Zustandes aller TASKs. Die TASKLIST-Anweisung zeigt in jeder Zeile die Nummer und den Status der ausgelisteten TASKs an. Beispiel: T01: 1000 REM Regler T02: s 2000 REM Speicher * * * * * .)))) Status: s = suspendiert .))))))))))) TASK-Nummern -41-
  • 42.
    5.9 SEQLIST Syntaxdiagramm: Aufruf: <zn> SEQLIST|SL {<n>} Funktion: Auslisten des momentanen Programmzählerstandes aller SEQuenzen. Die SEQLIST-Anweisung zeigt in jeder Zeile die Nummer und den Status der ausgelisteten SEQuenz an. Beispiel: a) SL S01: s 1210 WAIT FOR DIN(HAND)=1 S02: s 2190 REM -- ABFAHRSEQUENZ -- S03: s 3050 WAIT MAX 60 FOR DIN(XSilo5)=0 ELSE 3100 ^ ^ ! ! ! +---- Status: s=suspendiert +--------- SEQuenz-Nummer b) SL Fuell S09: 4070 WAIT MAX 10*60 FOR DIN(xS3max) ELSE 4430 READY Hinweise: a) Die SEQLIST-Anweisung läßt sich für eine zyklisch aufgerufene Steuerungs-Zustandsübersicht verwenden b) Das Bedienpersonal kann durch Betätigen einer Taste die SEQLIST-Funktion zur Fehlersuche aufrufen; besonders wertvoll ist dies bei der Fehlersuche in gegenseitig verriegelten Ablaufsteuerungesprogrammen. Liegt z.B. eine Verklemmung vor, d.h. einige SEQuenzen warten vergeblich auf die gegenseitige Erfüllung einer Weiterschaltbedingung, so listet SEQLIST die fraglichen WAIT-Anweisungen aus. Durch manuelles Prüfen der Weiterschaltbedingung kann dann in der Regel rasch die Fehlerursache gefunden werden. -42-
  • 43.
    5.10 Logikfunktionen 5.10.1 NOT(X) Funktion: NOT(X)liefert den Wert "1", wenn X=0 ist, ist X<>0 wird "0" zurückgegeben. Beispiel: 100 REM *** Benutzung von NOT(x) 110 vent1 = 1, tast1 = 1, tast2 = 2, tast3 = 3 : 200 DOUT(vent1)=DIN(tast1)*DIN(tast2)+NOT(DIN(tast3)) : 5.10.2 BIT(N,X) Funktion: BIT(N,X) wandelt X in eine 16-Bit-Zahl (-32768 < X < 32767) und liefert eine "1" wenn das N-te Bit (0..15) gesetzt (=1) ist, ist das N-te Bit nicht gesetzt (=0) wird eine "0" zurückgegeben. Beispiel: 100 REM *** BIT-Test *** 110 ready = 4, port = &H40 : 200 x = GET(port) 210 IF BIT(x,ready) THEN 300 ELSE 200 : 300 REM Port ist bereit: jetzt Aktion ... -43-
  • 44.
    5.10.3 Boolsche Ausdrücke DieBoolschen Operatoren AND und OR können auf die arithmetischen Operatoren "*" und "+" zurückgeführt werden, wobei deren Rangfolge auch bei boolschen Verknüpfungen gilt (siehe Kapitel Operatoren). Beispiel: a) Funktionsplan +))))), X2 ))))))))))))))))))))))))))))))))))))>0 * +))))), * >= * X1 )))))))))))))))))))))))>1 * * /))))> Y2 +))))), * * * * X3 )))))))))>1 * * & /)))))>1 * * >= * * * .)))))- * /))))))>1 * * * .)))))- X4 )))))))))>0 * .)))))- b) MSRBASIC-Formulierung: 100 REM *** Boolsche Verknüpfung AND und OR 110 DOUT(2) = DIN(1)*(DIN(3) + NOT(DIN(4)) + NOT(DIN(2) Hinweis: Die boolsche Verknüpfung ist nur bei den boolschen "Ergebnissen" "0" und "1" möglich. Das maskieren von HEX-Werten z.B. &H00C5 * &H0080 mit dem erwarteten Ergebnis &H0080, funktioniert hier nicht! Um BIT- Werte zu testen muß die Funktion BIT(n,x) verwendet werden. -44-
  • 45.
    5.11 Prozeß Ein-/Ausgabe-Funktionen DieEin-/Ausgabe von beliebigen Daten verteilt sich in BASIC auf zwei klar zu trennende Bereiche: a) Die Ein-/Ausgabe über die Konsole, den Drucker und alternative, meist seriellen Zusatzkanäle (AUX). Diese Kanäle werden über die Standard-Funktionen INPUT und PRINT, LIST, LOAD und SAVE usw. angesprochen. Die dazugehörenden Kanäle sind fest in das Betriebssystem eingebunden; der Benutzer braucht sich im Normalfall nicht darum zu kümmern. b) Im Sprachumfang von Standard-BASIC nicht definierte Ein- Ausgabekanäle (Ports) die (falls überhaupt) über die Funktionen INPORT bzw. OUTPORT angesprochen werden. Die entsprechenden Kanäle (Ports) sind üblicherweise nicht in das Betriebssystem eingebunden, der Benutzer muß sich um die Verwendbarkeit der Kanäle selbst kümmern. Bei der Prozeß-Ein-/Ausgabe kommt eigentlich nur der Fall (b) in Frage. Das bedeutet aber: der Programmierer muß genaue Kenntnis über die verwendeten Ein-/Ausgabe-Bausteine haben, er muß wissen wie diese zu initialisieren sind, welche Wandelzeiten, welche Statusbits usw. zu berücksichtigen sind. Dazu kommen noch die Probleme mit der Normierung und "Lage" bzw. Bedeutung der einzelnen Bits z.B. in einem 12-Bit AD- Wandler usw.... In MSRBASIC wurde dieses Problem umgangen, indem entsprechende Funktionseinheiten wie AD-/DA-Wandler, BIT-Ein-Ausgabe-Kanäle und Zähler bereits softwaremäßig in den Interpreter eingebunden werden. Da nicht ALLES und JEDES eingebunden werden kann, bedeutet dies natürlich auch eine Beschränkung in der Anzahl der Kanäle und der Art der Funktionseinheiten. MSRBASIC ist daher vor allem in diesem Bereich konfigurationsabhängig (siehe Kapitel Hardware-Anpassung). Der Zugriff auf die eingebundene Zusatzperipherie erfolgt über MSRBASIC-typische Funktionen die nachfolgend beschrieben sind. -45-
  • 46.
    5.11.1 Skalare Prozeß-Eingabe-Funktionen 5.11.1.1ADC(n) Funktion: Einlesen eines 16-Bit-Wertes vom Analogkanal (n). Die Anzahl (wieviele Kanäle) und Art (wieviel Bit Auflösung) der Kanäle sowie die Skalierung (0..n oder -n..+n) ist konfigurationsabhängig. Beispiel: 100 REM *** AD-Wert einlesen *** 110 ofen1 = 3 : 200 temp1 = ADC(ofen1) 210 IF temp1 > 100 THEN ..... ELSE .... Hardware: Für ECB-Systeme sind bis zu 4 Systemkarten Typ ECB-16AD12B(C) eingebunden. Damit sind max. 64 AD-Eingskanäle ansprechbar. Die Kartenadressen müssen wie folgt eingestellt sein: Kanal 1..16 Adresse 0B0H Kanal 17..32 Adresse 0B4H Kanal 33..48 Adresse 0B8H Kanal 49..64 Adresse 0BCH Bei TSM-Systemen werden die Module (TSM-16AD12) automatisch erkannt. Das Modul mit der niedrigesten Adresse beginnt mit Kanal 1..16, das Modul mit der höchsten Adresse endet mit Kanal 49..64. Die Moduladressen müßen nicht aufeinanderfolgend ein-gestellt werden! Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung (falls ein ADC überhaupt vorhanden ist), da alle Bausteine auf festen Adressen sind. -46-
  • 47.
    5.11.1.2 DIN(n) Funktion: Einlesen desBinärkanals (n). Die Art (TTL, 24Volt usw.) und die Anzahl der Kanäle ist konfigurationsabhängig. Die eingelesenen Werte betragen "0" oder "1". Hinweis: Es ist zu beachten, daß mit (n) jeweils ein BIT eines (hardwaremäßig vorgegebenen) Eingangports adressiert wird. Beispiel: 100 REM *** Binaerwert einlesen *** 110 NotEin = 1, Alarm = 2, Ein = 0 : 200 X = DIN(NotEin) 205 REM ** Wenn NotEin dann Alarm 210 IF X = 0 THEN DOUT(Alarm) = Ein : Hardware: Für ECB-Systeme sind bis zu 8 Systemkarten eingebunden.Damit sind max. 128 digitale Eingangskanäle ansprechbar. Es können folgende Systemkarten verwendet werden: 8* ECB-24VB, ECB-24V=, ECB-24-VK Die Kartenadressen müssen wie folgt eingestellt sein: Kanal 1..16 Adresse 080H Kanal 17..32 Adresse 082H Kanal 33..48 Adresse 084H Kanal 49..64 Adresse 086H Kanal 65..80 Adresse 088H Kanal 81..96 Adresse 08AH Kanal 97..112 Adresse 08CH Kanal113..128 Adresse 08DH Bei Verwendung der Systemkarte ECB-OP32IN (Nur Eingang) können nur die geradzahligen Kartenadressen genutzt werden. Die ECB-Systemkarten können auch gemischt verwendet werden, solange sich die Adressen nicht überschneiden. Es ist nicht möglich, z.B. eine ECB-Relaiskarte auf einer bestimmten Adresse als Ausgang zu verwenden und, unter der gleichen Adresse, die ECB-OP32IN-Karte als Eingang. Der Schaltzustand der Relaiskarte ECB-REL16R kann unter einer der oben angegebenen Adresse zurückgelesen werden. Bei TSM-Systemen werden die Module TSM-8E24, TSM-8E230 und TSM-32E24 automatisch erkannt. Das Modul mit der niedrigsten Adresse beginnt mit Kanal 8..16(32). Die Kanalnummern 1..8 sind für die Eingänge auf dem CPU-Modul reserviert. -47-
  • 48.
    Die Adressen derAusgangsmodule müssen nicht aufeinanderfolgend eingestellt werden! Bei Kleincomputern der MPS-Serie entfällt eine spezielle Einstellung (falls ein digitaler Eingang überhaupt vorhanden ist), da alle Bausteine auf festen Adressen sind. -48-
  • 49.
    5.11.1.3 GET(pp) Funktion: Einlesen desEingabeports (pp). Diese Funktion entspricht der Funktion INPORT(pp) im Standard-BASIC. Der eingelesene Wert liegt zwischen 0 und 255 (00H..FFH). Hinweis: Es ist zu beachten, daß diese Funktion den angegebenen Eingangsport mit allen Einschränkungen direkt einliest. Der Programmierer muß auf eine evtl. notwendige Initialisierung des Eingabeports selbst achten und muß die zurückgelesenen Daten selbst interpretieren! Beispiel: 100 REM *** Lesen eines Ports nach Statusabfrage 100 Basis = &H80 : 200 stat = GET(Basis) 205 REM pruefen ob ein Zeichen vorliegt 210 stat = BIT(2,stat) 220 IF stat = 0 THEN 200 225 REM JA .. Zeichen liegt vor 230 char = GET(Basis+1) 240 REM Im Beispiel Zeichen als ASCII auf Konsole 250 PRINT char$(char); -49-
  • 50.
    5.11.1.4 CNT(n) Funktion: Einlesen einesZählerkanals (n). Die Art (8 oder 16-Bit Zähler) und die Anzahl der vorhandenen Zählerkanäle sind konfigurationsabhängig. Beispiel: 100 REM *** Zaehlerbeispiel *** 110 max = 1024 : 200 count = CNT(0) 210 IF count < max THEN 1000 220 REM Zaehler zuruecksetzen 230 CNT(0) = 0 240 REM ... und jetzt reagieren auf Ueberlauf : 1000 REM Hierher wenn "Endstand noch nicht erreicht" Hardware: Bei TSM sind die 8 Digital-Eingänge auf der CPU-Baugruppe wahlweise als 24-Volt-Eingang oder als Zähler zugelassen. Die CNT-Funktion liefert die anliegende Frequenz und die DIN-Funktion den anliegenden Pegel zurück. Die Bezeichnung der Kanäle ist CNT(1)..CNT(8) bzw. DIN(1)..DIN(8). Die Zähler können recht hohe sowie unsymetrische Frequenzen erfassen, die hauptsächlich durch die Eingangsbeschaltung (intern, extern, Filter, Optokopler u.Ä.) begrenzt sind. Die Torzeit beträgt bei allen Zählern 100 ms; zurückgegeben wird die anliegende Frequenz/10. Für ECB-Systeme und MPS-Einplatinencomputer bitte gesondert anfragen. -50-
  • 51.
    5.11.2 Skalare Prozeß-Ausgabe-Funktionen DieProzeß-Ausgabe-Funktionen sind das jeweilige Gegenstück zu den oben genannten Eingabe-Funktionen. Im Gegensatz zu diesen stehen sie aber immer auf der linken Seite von Zuweisungen. 5.11.2.1 DAC(n) Funktion: Dies ist die Umkehrung der Funktion ADC(n). Es wird ein 16-Bit (Digital-) Wert auf den Analogkanal (n) ausgegeben. Die Art (Auflösung 8 oder 16-Bit) und die Anzahl der Kanäle sowie die Skalierung ist konfigurationsabhängig. Hinweis: Es erfolgt keine Fehlermeldung wenn versucht wird ein 16-Bit-Wert auf einen 8-Bit-Kanal auszugeben. Ausgegeben wird in diesem Falle der untere 8-Bit-Wert (Bereich 0..255) ! Beispiel: 100 REM *** Beispiel einer Analog-Ausgabe 110 Vent1 = 1, ESch1 =1 ESch2 = 2 : 190 REM Pruefen auf Endbedingung 200 x = GET(ESch2) 210 IF x = 1 THEN 300 220 REM Ventil 1 langsam oeffnen bis ESch2 = 1 230 temp=1 240 DAC(Vent1) = temp 250 temp = temp+1 260 x = GET(ESch2) 270 IF x = 0 THEN 250 290 REM wenn ESch2 schaltet ... 300 REM Ventil 1 langsam schliessen bis ESch1 = 1 310 temp=254 320 DAC(Vent1)=temp 330 temp=temp-1 340 x = GET(ESch1) 350 IF x = 0 THEN 320 360 GOTO 220 : Hardware: Für ECB-Systeme sind bis zu 4 Systemkarten Typ ECB-4DA12 ein-gebunden. Damit sind max. 16 DA-Ausgangskanäle ansprechbar. Die Kartenadressen müssen wie folgt eingestellt sein: Kanal 1..4 Adresse 0C0H Kanal 5..8 Adresse 0C4H Kanal 9..12 Adresse 0C8H Kanal 13..16 Adresse 0CCH Bei TSM-Systemen werden die Module (TSM-2DA12) automatisch erkannt. Das Modul mit der niedrigsten Adresse beginnt mit Kanal 1..2. Die Moduladressen müßen nicht aufeinanderfolgend eingestellt werden! -51-
  • 52.
    Bei Kleincomputern derMPS-Serie entfällt eine spezielle Einstellung (falls ein DAC überhaupt vorhanden ist), da alle Bausteine auf festen Adressen sind. -52-
  • 53.
    5.11.2.2 DOUT(n) Funktion: Ausgabe aufden Binärkanal (n). Die Art (TTL, 24Volt usw.) und die Anzahl der Kanäle ist konfigurationsabhängig. Der Ausgabewert beträgt 0 oder 1. Hinweis: Es ist zu beachten, daß mit (n) jeweils ein BIT eines (hardwaremäßig vorgesehenen) Ausgangsports adressiert wird. Beispiel: 100 REM *** Beispiel mit Digital Ein-/Ausgabe 110 Rel1 = 1, Rel2=2 120 Tast1 = 1, Tast2 = 2, Tast3 = 3 : 200 REM Schalte Relais 1 wenn Tast1 UND Tast2 UND Tast3 210 DOUT(Rel1)=DIN(Tast1)*DIN(Tast2)*DIN(Tast3) : 300 REM Schalte Relais 2 wenn Tast 1 ODER Tast3 310 DOUT(Rel2)=DIN(Tast1)+DIN(Tast3) : 400 REM Schalte Relais 2 wenn Tast2 410 DOUT(Rel2)=DIN(Tast2) : 500 REM Schalte Relais 2 wenn CNT(1) > 1000 510 x = CNT(1) 520 IF x > 1000 THEN DOUT(Rel2) = 1 : Hardware: Für ECB-Systeme sind bis zu 8 Systemkarten eingebunden. Damit sind max. 128 Digitale Ausgangskanäle ansprechbar. Es können folgende Systemkarten verwendet werden: 8* ECB-24VB, ECB-24V=, ECB-24-VK, ECB-REL16R Die Kartenadressen müssen wie folgt eingestellt sein: Kanal 1..16 Adresse 080H Kanal 17..32 Adresse 082H Kanal 33..48 Adresse 084H Kanal 49..64 Adresse 086H Kanal 65..80 Adresse 088H Kanal 81..96 Adresse 08AH Kanal 97..112 Adresse 08CH Kanal113..128 Adresse 08DH Die ECB-Systemkarten können auch gemischt verwendet werden, solange sich die Adressen nicht überschneiden. Bei TSM-Systemen werden die Module TSM-8A24, TSM-8A230 und TSM-32A24 automatisch erkannt. Das Modul mit der niedrigesten Adresse beginnt mit Kanal 8..16(32). Die Kanalnummern 1..8 sind für die Ausgänge auf dem CPU-Modul reserviert. Die Adressen der Ausgangsmodule müssen nicht aufeinanderfolgend -53-
  • 54.
    eingestellt werden! Bei Kleincomputernder MPS-Serie entfällt eine spezielle Einstellung (falls ein Digitaler Ausgang überhaupt vorhanden ist), da alle Bausteine auf festen Adressen sind. -54-
  • 55.
    5.11.2.3 PUT(pp) Funktion: Ausgabe eines8-Bit-Wertes (0..255) auf den Ausgabeport (pp). Diese Funktion entspricht der Funktion OUTPORT in Standard-BASIC. Hinweis: Es ist zu beachten, daß diese Funktion den angegebenen Wert mit allen Einschränkungen direkt ausgibt. Der Programmierer muß auf eine evtl. notwendige Initialisierung des Ausgangsports selbst achten und muß die "Wirkung" der Ausgabe kennen. Beispiel: 100 REM *** Beispiel einer Portinitialisierung *** 101 REM *** für einen PIO-Kanal auf ECB-PIO/W *** 110 base = &H24 : 200 REM Init Kanal A auf Eingabe Bit 0..3 210 REM auf Ausgabe BIT 4..7 220 PUT(base+2) = &HCF 230 PUT(base+2) = &H0F : 300 REM Beschreiben des Kanals 310 PUT(base) = &H05 : -55-
  • 56.
    5.11.2.4 CNT(n) Funktion: Setzen einesZählerkanals. Die Art (8- oder 16-Bit-Zähler) und die Anzahl der Kanäle ist konfigurationsabhängig. Beispiel: 200 REM *** Zuruecksetzen eines Zählerkanals 210 cntr1 = 1 : 300 CNT(cntr1) = 0 ; Hardware: Bei TSM sind die 8 Digital-Eingänge auf der CPU-Baugruppe wahlweise als 24-Volt-Eingang oder als Frequenzzähler (ab 10 Hz) zugelassen. Da es wenig Sinn macht, einen Frequenzzähler vor-einzustellen oder zurückzusetzen, wurde CNT(n) für TSM nicht implementiert. Für ECB-Systeme und MPS-Einplatinencomputer bitte gesondert anfragen. -56-
  • 57.
    5.11.3 Vektor Ein/Ausgabe-Funktionen Vektorfunktionen werden im Rahmen von VEC-Anweisungen ausgeführt (siehe diese). 5.11.3.1 MADC(MO) Funktion: Einlesen eines Meßvektors. Die Komponenten des Meßortvektors MO legen die einzelnen Eingabekanäle fest. 5.11.3.2 MDAC(SO) Funktion: Ausgabe eines Stellvektors. Die Komponenten des Stellvektors SO legen die einzelnen Ausgabekanäle fest. 5.11.3.3 MDIN(MD) Funktion: Einlesen eines Binärvektors. 5.11.3.4 MDOUT(SD) Funktion: Ausgabe eines binären Steuervektors. Beispiel: 150 DIM XE(N), MO(N), Y(N), SO(N) : 1000 VEC XE=MADC(MO), MDAC(SO)=Y ist äquivalent zu: 1000 FOR I=1 TO N 1010 XE(I) = ADC(MO(I)), DAC(SO(I))=Y(I) 1020 NEXT I -57-
  • 58.
    5.11.4 Abfrage derProzeßkonfiguration Mit diesen Abfragen kann festgestellt werden welche Kanäle installiert sind. Die Ergebnisse sind konfigurationsabhängig. Nähers zur Hardware-Konfiguration ist in Kapitel 10 zu finden. 5.11.4.1 NDAC Funktion: Es wird die Anzahl der installierten DAC-Kanäle zurückgemeldet. 5.11.4.2 NADC Funktion: Es wird die Anzahl der installierten ADC-Kanäle zurückgemeldet. 5.11.4.3 NDOUT Funktion: Es wird die Anzahl der installierten DOUT-Ports zurückgemeldet. Es ist zu beachten, daß ein Port = 8 Kanäle hat! 5.11.4.4 NDIN Funktion: Es wird die Anzahl der installierten DIN-Ports zurückgemeldet. Es ist zu beachten, daß ein Port = 8 Kanäle hat! 5.11.4.5 NCNT Funktion: Es wird die Anzahl der installierten CNT-Kanäle zurückgeliefert. Beispiel: 100 REM *** Beispiel Konfigurationsabfrage *** : 200 FOR i=1 TO 8*NDIN 210 PRINT DIN(i) AS 1i; 220 NEXT i -58-
  • 59.
    5.12 Zeitgeberfunktionen 5.12.1 TDOWN 5.12.2TUP Aufruf: a) Deklarieren: DIM TUP(n),TDOWN(n) b) Stellen: TDOWN(n)=<Zähler> TUP(n)=<Zähler> c) Lesen: PRINT TDOWN(n) PRINT TUP(n) Funktion: Die Zeitgeber TDOWN (abwärtszählend) und TUP (aufwärtszählend), werden wie eindimensionale numerische Felder behandelt. Die Voreinstellung des Zeittaktes beträgt 1s. 5.12.3 Zeitfaktor "TIMEFAC" Aufruf: a) Lesen PRINT TIMEFAC <cr> b) Stellen TIMEFAC = <n> <cr> Funktion: Ein Lesezugriff auf TIMEFAC liefert das aktuelle Aufrufintervall der MSRBASIC-internen Zeitgeber-TASK in 10ms-Einheiten. In der Regel hat TIMEFAC den WERT 100 (100*10ms=1s) In einzelnen Fällen kann es sinnvoll sein, die Zeitinkremente zu verändern (insbesondere zu verkürzen). Eine Auflösung von 100ms erreicht man z.B. durch die Anweisung: TIMEFAC = 10 Eine dadurch erreichte Beschleunigung wirkt sich aus auf: - TUP- /TDOWN-Felder - Wartezeiten in WAIT/WAIT MAX-Anweisungen Sie wirkt sich nicht auf die TASK-Aufrufintervalle aus! 5.12.4 24 Bit-Zeitgeber (nur TSM) Die TSM-CPU verfügt über einen freilaufenden 24-Bit Zeitgeber mit einem Takt von 1ms. -59-
  • 60.
    5.12.4.1 MSRTIMER Die Timeranzeigewird wie eine Variable gelesen: zeit = MSRTIMER Im Beispiel enthälte <zeit> den momentanen Zählerstand des Timers. 5.12.4.2 MSTIMDIF Diese Funktion erlaubt die Berechnung von Zeitdifferenzen zwischen einem bereits gespeicherten Zeitgeberwert und dem aktuellen Inhalt des Zeitgebers: 100 zeit = MSRTIMER 110 REM ... was immer .. : 800 tdiff = MSTIMDIF(zeit) 810 PRINT "Zeitdifferenz: "; tdiff; " ms" Es lassen sich auf diese Art recht genaue Zeitdifferenzen bis zu 2796 Minuten feststellen. Eine andere Anwendung wären z.B. Zeitschleifen: 100 zeit = MSRTIMER 110 IF MSRIMEDIF(zeit) < 1000 GOTO 110 120 REM wartet eine Sekunde ... 5.12.5 Kalender und Uhrzeit Voraussetzung für die korrekte Belegung der nachfolgend genannten Variablen ist die Installation einer Hardware-UHR und deren Einbindung in MSRBASIC. Auch wenn keine Hardware-Uhr in MSRBASIC eingebunden ist, können jedoch die nachfolgend genannten Variablen benutzt werden, wenn ihnen zur geeigneten Zeit ein entsprechender Inhalt zugewiesen wird. 5.12.5.1 TIME$ Die Variable TIME$ enthält bei einem Lesezugriff die Tageszeit in der Form: "hh:mm:ss" mit hh=Stunden, mm=Minuten, ss=Sekunden -60-
  • 61.
    5.12.5.2 DATE$ Die VariableDATE$ enthält bei einem Lesezugriff das Datum in der Form: "dd:mm:jj" mit dd=Tag, mm=Monat, jj=Jahr. 5.12.5.3 DOW$ Die Variable DOW$ gibt die deutsche Kurzform des aktuellen Wochentages wieder: SO Sonntag DO Donnerstag MO Montag FR Freitag DI Dienstag SA Samstag MI Mittwoch -61-
  • 62.
    5.13 Reglerfunktionen 5.13.1 Allgemeines Alsparametrierbare Reglerfunktionsblöcke werden in MSRBASIC (skalare und vektorwertige) PI- und PID-Regelalgorithmen mit Positions- und Geschwindigkeits-Ausgang angeboten. Sie realisieren folgende Grundformel: Berechnen des Zuwachses: Dyi := Kp*(ei-ei-1+KI*ei+KD*(ei-2*ei-1+ei-2)) A<-- nur bei PID --> Umspeichern der vergangenen Regeldifferenzen: ei-2 = ei-1, ei-1 = ei Die Stellungsversion summiert dazu noch die Stellinkremente auf: yi = yi-1 + Dyi Der MSRBASIC-PID-Funktionsblock entspricht folgendem BASIC-Programm: 1000 REM *** PID-Algorithmus *** 1010 REM Bedingte Bildung des Integralteils 1020 IF AK*E<=0 THEN I=KI*E ELSE I=0 1030 DY = KP*(E-E1 + I + KV*(E-2*E1+E2)) 1040 AK = AK+DY 1050 E2 = E1, E1 = E 1060 DY = AK 1070 REM Stellsignal begrenzen 1080 IF DY>0 THEN GOSUB 1100 ELSE GOSUB 1150 1090 AK = AK-DY, Y = Y+DY 1099 RETURN 1100 REM positives Stellinkrement begrenzen 1110 IF DY>YD THEN DY=YD 1120 IF DY>YO-Y THEN DY=YO-Y 1130 IF DY>YU-Y THEN DY=YU-Y 1140 RETURN 1150 REM negatives Stellinkrement begrenzen 1160 IF DY<-YD THEN DY=YD 1170 IF DY<YU-Y THEN DY=YU-Y 1180 IF DY<YO-Y THEN DY=YO-Y 1190 RETURN Über den reinen PID-Algorithmus hinaus (Zeilen 1030 und 1090:2) sind also folgende wichtigen Funktionen realisiert: - Stoßfreie on-line-Parameterverstellung durch interne Geschwindigkeitsform. - Automatisches Abschalten des I-Anteiles (Zeile 1020), wenn eine Stellgrößen- oder Stellgesschwindigkeitsbeschränkung (Zeilen 1100 .. 1190) erreicht wird (Verhinderung der Integralsättigung). - Verhinderung des proportional-differentialen Anfahreffekt -62-
  • 63.
    bei den Versionenmit Geschwindigkeitsausgang durch die Zwischenspeichermethode (Zeilen 1040,1060,1090). - Automatische Stellgrößenanpassung an dynamisch veränderte Grenzwerte YO bzw YU (Zeilen 1130,1180), wichtig bei Kaskadenschaltung! 5.13.2 P/PID-Einzelregler Die Reglerfunktionen können syntaktisch wie Standardfunktionen verwendet, also auch in arithmetische Ausdrücke eingebunden werden. Als Ausgangsgröße wird je nach Algorithmus der Momentanwert der Stellgröße oder der Stellgeschwindigkeit geliefert. PID-Stellungsalgorithmus: PID(Y,E,E1,E2,KP,KD,KI,YO,YU,YD,AK) PID-Geschwindigkkeitsalgorithmus: GPID(Y,E,E1,E2,KP,KD,KI,YO,YU,YD,AK) PI-Stellungsalgorthmus: PI(Y,E,E1,KP,KI,YO,YU,YD,AK) PI-Geschwindigkeitsalgorithmus: GPI(Y,E,E1,KP,KI,YO,YU,YD,AK) Hierbei bedeuten: Y: Stellgröße E: momentane Regeldifferenz (Eingangsgröße) E1: letzte Regeldifferenz (Zustandsgröße) E2: vorletzte Regeldifferenz (Zustandsgröße) KP: Verstärkung KD: Differentialbeiwert (Regler-Parameter) KI: Integralbeiwert YO: Stellgrößenobergrenze YU: Stellgrößenuntergrenze (Parameter) YD: max. Stellgrößenzuwachs AK: Zwischenspeicher (Zustandsgröße) Zu beachten ist, daß die Reglerfunktionen neben dem Stellsignal als eigentlicher Ausgangsgröße auch das Umspeichern der früheren Werte der Regeldifferenz und die Verwaltung des Zwischenspeichers vornehmen.Der Anwender muß hierfür nur die entsprechenden Variablen bereitstellen. 5.13.3 Vektor P/PID-Regler Im Rahmen der VEC-Anweisung können neben den Prozeß-Ein/Ausgabe- Funktionen MADC, MDIN und MDOUT auch die Reglerblöcke PI und PID verwendet werden. Die Anweisung: 1000 VEC Y = PI(Y,E,E1,KP,YO,YU,YD,AK) ist funktionell gleichbedeutend mit: -63-
  • 64.
    1000 FOR I = 1 TO N 1010 Y(I) = PI(Y(I),E(I),E1(I),KP(I),KI(I),YO(I), YU(I),YD(I),AK(I) 1020 NEXT I Allerdings halbiert sich bei Verwendung der VEC-Anweisung sowohl der Schreib- wie der Rechenaufwand. -64-
  • 65.
    5.14 Speicherfunktionen 5.14.1 PEEK(N) Funktion: Mitder PEEK-Funktion kann der Inhalt einer Speicherstelle im Adreß- Bereich 0..65535 eingelesen werden. PEEK ist die Umkehrung der POKE- Anweisung (siehe dort). Beispiel: 100 REM *** HEXDUMP *** 110 addr = &H1000 120 FOR I = 1 TO 16 ' 16 Zeilen 130 PRINT addr AS 4H; ' Startadresse 140 PRINT ": "; 150 FOR J = 1 TO 16 ' 16 Bytes 160 PRINT PEEK(addr) AS 2H; 170 PRINT " "; ' Bytes trennen 180 addr=addr+1 190 NEXT J ' Innere Schleife 200 PRINT ' neue Zeile 210 NEXT I 220 PRINT 230 END -65-
  • 66.
    5.15 Hintergrundspeicher (nurCPUZ280 und TSM-CPU280) Urspünglich wurde MSRBASIC für 16-Bit Prozessoren mit max. 64 Kb Speicher entwickelt, wobei üblicherweise 32 Kb EPROM-Speicher für MSRBASIC und 32 Kb RAM-Speicher für das Anwenderprogramm zur Verfügung stand. Um in Applikationen der Meßwerterfassung auch mit größeren Datenmengen umgehen zu können, wurde für die neue Prozessorserie Z280 eine Erweiterung des Befehlssatzes von MSRBASIC vorge-nommen, die speziell diesen Wünschen gerecht wird. Diese BiGMEMory-Funktionen erlauben das Einrichten von Daten-feldern in, sowie das Einfügen und Entfernen von Daten aus einem Hintergrundspeicher über die "normalen" 64 Kb hinaus bis 1Mb (und mehr bei ECB-CPUZ280). Der Hintergrundspeicher kann als ein Feld von Datenstrukturen aufgefaßt werden. Es können bis zu 8 Hintergrundspeicher mit unterschiedlicher, voneinander unabhängiger Datenstruktur, de-finiert werden, deren Größe nur durch den verfügbaren Speicher-platz begrenzt wird. Auf den Hintergrundspeicher kann in Form eines Ringspeichers mit Strukturen direkt (wahlfrei), als Queue (Schlange) und/oder als Stack (Stapelspeicher) zugegriffen werden. Es können jedoch nicht einzelne Elemente sondern nur komplette Strukturen beschrieben bzw. gelesen werden. In der MSRBASIC-Version für die TSM-CPUZ280 kann für den Hinter- grundspeicher ein FLASH-EPROM genutzt werden, um Daten dauerhaft zu erhalten. -66-
  • 67.
    5.15.1 BGMEMDIM Syntaxdiagramm: Aufruf: <zn> BGMEMDIM (n, e, vl) <cr> mit n = Nummer des Hintergrundspeichers (0..7) e = Anzahl der Strukturen vl = Aufzählung der Variablentypen Funktion: Die BGMEMDIM-Anweisung dient der Einrichtung eines Hintergrund- speichers (max. 8). Die Nummerierung (n) sollte in aufsteigender Ordnung erfolgen und dient der Identifizierung des Speichers. Jede Struktur hat einen Aufbau wie er in vl (Variablenliste) angegeben ist. Die Namen der Variablen haben hier keine Bedeutung, es wird ledig-lich der Variablen-TYP benötigt, um den strukturellen Aufbau und den Platzbedarf für die Initialisierung zu bestimmen. Folgende Typen sind zugelassen: a$(n) String mit max. n Buchstaben. a Gleitkommazahl. a(n) Feld (Array) von Gleitkommazahlen mit der Domension n. Bei der Initialisierung (Kaltstart) wird der Inhalt von String-Felden mit dem Zeichen "-" gefüllt. Gleitkommazahlen werden mit der größten negativen Zahl initialisiert. Der Hintergrundspeicher(Nr 0) im FLASH-EPROM (nur TSM-CPUZ280) ist immer definiert. Beispiel: 100 BGMEMDIM(1, 100, a$(8),a,a,a(8)) 101 REM Der Hintergrundspreicher Nummer 1 101 REM kann 100 Datenstrukturen der Form 102 REM string[8], float, float, float[10] 103 REM aufnehmen. Fehler: 5.15.2 BGMEM Wahlfreier Zugriff 5.15.2.1 BGMEMPUTR -67-
  • 68.
    Syntaxdiagramm: Aufruf: <zn> BGMEMPUTR(n, c, vl) mit n = Nummer des Hintergrundspeichers (0..7) c = Nummer der Struktur in diesem HS. vl = Liste der Variablen. Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: Die BGMEMPUTR-Anweisung ermöglicht den wahlfreien Schreibzugriff (Random Access) auf einen bestimmten Hintergrundspeicher (n), bestehend aus einem ARRAY mit (c) Elememten, welche ihrerseits aus einer beliebigen, vom Benutzer definierten, Datenstruktur (nach vl) zusammengesetzt sind. Die Eintragung in den Hintergrundspeicher wird nicht von BGMEMSS erfasst (siehe dort), im Gegensatz zu Eintragungen mit BGMEMPUTQ und BGMEMPUSH. Beispiel: 1100 BGMEMDIM (0,100,a$(8),a,a,a(8)) 1110 FOR i = 0 TO 99 1120 REM 1130 REM hier werden die Variablen 1140 REM varb, varc, varar(n) "bearbeitet" 1150 REM 1160 REM ... und jetzt in BGMEM abgelegt: 1170 REM 1180 BGMEMPUTR (0, i, time$, temp1, temp2, schalter()) 1190 NEXT i Fehler: 5.15.2.2 BGMEMGETR Syntaxdiagramm: -68-
  • 69.
    Aufruf: <zn> BGMEMGETR(n, c, vl) mit n = Nummer des Hintergrundspeichers (0..7) c = Nummer der Struktur in diesem HS vl = Liste der Variablen Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: Die BGMEMGETR-Anweisung ermöglicht den wahlfreien Lesezugriff (Random Access) auf einen bestimmten Hintergrundspeicher (n), bestehend aus einem ARRAY mit (c) Elementen, welche ihrerseits aus einer beliebigen, vom Benutzer definierten, Datenstruktur (vl) zusammengesetzt sind. Der Inhalt der letzten Struktur kann durch BGMEMPOP, den der ältesten (noch vorhandenen) Struktur durch BGMEMGETQ erreicht werden (siehe dort). Wird der Hintergrundspeicher ausschließlich mit BGMEMPUTQ oder BGMEMPUSH gefüllt, ist die letzte Eintragung immer unter c=1 (siehe oben) zu finden, ältere Eintragungen entsprechend unter c= 2, 3 usw.; die älteste, noch vorhandene Eintragung ist unter c=BGMEMSS zu finden Beispiel: 1200 REM Initialisierung und Einlesen der Daten 1210 REM siehe BGMRMPUTR 1220 REM nun Auslesen des 6. Eintrages 1230 BGMEMGETR(0, 5, zeit$, temp1, temp2, schalter()) 1230 PRINT "Um "; zeit$; " Uhr, " 1240 PRINT "war die Innentemperatur "; 1230 PRINT temp1 AS 3F1;" Grad " 1240 PRINT "bei Aussentemperatur von "; 1250 PRINT temp2 AS 3F1;" Grad" 1260 REM .. und jetzt noch Schalterarray behandeln .. 1270 ... Fehler: -69-
  • 70.
    5.15.3 BGMEM Queue-Zugriff 5.15.3.1BGMEMPUTQ Syntaxdiagram: Aufruf: <zn> BGMEMPUTQ(n,vl) mit n = Nummer des Hintergrundspeichers (0..7) vl = Liste der Variablen Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: Mit BGMEMPUTQ wird ein Ringspeicher verwaltet, in welchen die Strukturen hintereinander (in einer Queue = Warteschlange) abgelegt werden. Die Speicherverwaltung veranlaßt, daß die 'älteste' Eintragung immer am Kopf, die 'jüngste' Eintragung am Ende (Schwanz) der Schlange ist. Bei Überlauf des Ringspeichers (zuviele Einträge) wird der jeweils 'älteste' Eintrag entfernt. Beispiel: siehe BGMRMGETQ Fehler: -70-
  • 71.
    5.15.3.2 BGMEMGETQ Syntaxdiagramm: Aufruf: <zn> BGMEMGETQ(n, vl) mit n = Nummer des Hintergrundspeichers vl = Liste der Variablen Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: Mit BGMEMGETQ können die Daten aus dem Hintergrundspeicher wieder zurückgelesen werden. Gelesen wird vom 'Kopf' des Ring-speichers, d.H. die ältesten (zuerst eingegebenen) Daten, nach dem FIFO- (first in, first out) Prinzip, soweit diese, nach einem Datenüberlauf noch vorhanden sind. Sollen die zuletzt eingegeben (die jüngsten) Daten gelesen werden, so kann dies mit BGMEMPOP oder BGMEMGETR(n,+1,vl) geschehen; die vorletzten Daten mit BGMEMGETR(n,+2,vl) usw. Mit BGMEMSS kann festgestellt werden, wieviele Strukturen eingetragen sind, soweit diese nicht mit BGMEMPUTR abgelegt wurden. Beispiel: Fehler: -71-
  • 72.
    5.15.4 BGMEM Stackzugriff 5.15.4.1BGMEMPUSH Syntaxdiagramm: Aufruf: <zn> BGMEMPUSH(n, vl) mit n = Nummer des Hintergrundspeichers (0..7) vl = Liste der Variablen. Die Typen in VL müßen den Typen, wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: BGMEMPUSH entspricht in seiner Funktion völlig der Queue-Be-handlung mit BGMEMPUTQ. Bei einem Überlauf des Stacks (Stapel-speichers) wird ebenfalls der älteste Eintrag entfernt. Beispiel: siehe BGMEMPOP Fehler: -72-
  • 73.
    5.15.4.2 BGMEMPOP Syntaxdiagramm: Aufruf: <zn> BGMEMPOP(n, vl) mit n = Nummer des Hintergrundspeichers vl = Liste der Variablen Die Typen in vl müßen den Typen wie sie mit BGMEMDIM definiert wurden, entsprechen. Funktion: Im Gegensatz zu BGMEMGETQ (siehe dort) liest diese Anweisung jeweils die zuletzt abgelegte Struktur vom "Schwanz" der Schlange; dies entspricht dem LIFO (last in - first out) Prinzip. Soll eine ältere Struktur gelesen werden, so ist dies mit BGMEMR möglich (siehe dort). Die älteste, noch vorhandene, Eintragung kann jederzeit mit BGMEMGETQ erreicht werden. Fehler: -73-
  • 74.
    5.15.5 BGMEM Sonderfunktionen 5.15.5.1BGMEMSS Syntaxdiagramm: Aufruf: <zn> BGMEMSS(n) mit n = Nummer des Hintergrundspeichers (0..7) Funktion: Mit der Funktion BGMEMSS kann festgestellt werden, ob ein bestimmter Hintergrundspeicher (n) definiert ist bzw. wieviele Datenstrukturen bereits eingetragen sind. Beispiel: 100 REM Prüfen ob BGMEM definiert wurde 110 FOR i = 1 TO 8 120 c=BGMEMSS(i) 130 IF c < 0 THEN 190 140 ELSE PRINT c AS 05I; 150 PRINT " Strukturen in BGMEM #"; 160 PRINT i AS 1I 170 NEXT i 180 END 190 PRINT "BGMEM # "; 200 PRINT i AS 1I; 210 PRINT " nicht definiert" 220 GOTO 170 Beispiel: 1000 REM Es wird ein Hintergrundspeicher definiert 1010 REM mit 100 Einträgen, jeweils Uhrzeit und Messdaten 1015 REM 1020 BGMEMDIM(1, 100, a$(8), a) 1025 REM 1030 REM nun werden die Daten gesammelt .... wenn 1040 REM ein bestimmtes äußeres Ereignis eintritt 1050 REM ... also nicht kontinuierlich ... : 1100 BGMEMPUSH(1,zeit$, druck) : 2000 REM Die gesammelten Daten sollen immer im 2010 REM im 5er-Pack "versandt" werden ... 2015 REM 2020 cnt = BGMEMSS(1) 2030 IF cnt>4 THEN GOSUB 3000 2035 REM -74-
  • 75.
    2040 REM Sonstgeht es weiter im Programm : 3000 REM Ausgabe von Daten 3010 FOR i = 1 TO 5 3020 BGMEMPOP(1, zeit$, druck) 3030 PRINT ON(2) "Zeit: ";zeit$; " Druck: "; 3040 PRINT ON(2) AS 3F1 druck; 3050 PRINT ON(2) " bar" 3060 NEXT i 3070 RETURN Fehler: keine -75-
  • 76.
    5.15.5.2 BGMEMCLEAR Syntaxdiagramm: Aufruf: <zn> BGMEMCLEAR(n) mit n = Nummer des Hintergrundspeichers (0..7) Funktion: Diese Anweisung löscht den kompletten Inhalt eines bereits (mit BGMEMDIM) definierten Hintergrundspeichers. Es ist zu beachten, daß jedoch die definierte Strucktur des Hintergrundspeichers erhalten bleibt! Beispiel: Fehler: -76-
  • 77.
    5.15.5.3 BGMEMFRE Syntaxdiagramm: Aufruf: <zn> BGMEMFRE(n) mit n = Nummer des Hintergrundspeichers (0..7) Funktion: Die Anweisung BGMEMFRE gibt einen bereits definierten Hinter- grundspeicher wieder frei. Der vorher dafür belegte Speicher-platz kann für einen neuen Hintergrundspeicher beliebigen Auf-baus verwendet werden. Beispiel: Fehler: -77-
  • 78.
    5.16 Logical Units(Serienschnittstellen) 5.16.1 LUMODE Aufruf: <zn> fcd = LUMODE(kanal, baud, "format") mit kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit CPUZ280 auf ECB-Systemen Andere Konfigurationen bitte erfragen! baud = Baudrate 300, 1200, 2400, 4800, 9600, 19200 und 38400 format = hier muß ein string (Text in "" ) ein- gegeben werden: 1. Anzahl der Bits: "7" oder "8" 2. Parity: "O" (odd) "E" (even) "N" (none) 3. Stopbits "1" oder "2" 4. Handshake "X" = XON-XOFF-Protokoll "R" = RTS/CTS-Protokoll *) fcd = Fehlercode 0 = Alles in Ordnung 1 = Kanal existiert nicht 2 = Baudrate nicht unterstützt 3 = Datenformat nicht unterstützt Funktion: Mit LUMODE kann die Baudrate, das Format und die Art des Handshakes einer seriellen Schnittstelle verändert werden. Beispiel: Es soll an die zweite Schnittstelle ein Modem angeschlossen werden, mit 2400 Baud, 8 Bit Daten, keine Parität und 1 Stopbit. Beide Handshakearten sollen unterstützt werden: 100 fcd = LUMODE(2,2400,"8N1XR") 110 IF fcd=0 THEN PRINT "Kanal 2 angeschlossen" 120 IF fcd=1 THEN PRINT "Kanal 2 existiert nicht" *) Es können "X" und "R" gleichzeitig aktiv sein, das RTS- Signal zeigt zu jedem Zeitpunkt an, ob die Schnittstelle empfangs- bereit ist. 5.16.2 LUOPEN Aufruf: <zn> val = LUOPEN(kanal) mit kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit CPUZ280 auf ECB-Systemen Andere Konfigurationen bitte erfragen! val = 0 alles in Ordnung -78-
  • 79.
    = 1 Kanalist nicht anzusprechen Funktion: Mit dieser Funktion kann der Zustand der DCD-Leitung abgefragt werden. Beispiel: 1000 IF LUOPEN(2) THEN PRINT ON(2) "Hallo wie geht's" 5.16.3 LUAVAIL Aufruf: <zn> val = LUAVAIL(kanal) mit kanal = 1 bzw 2 für SCC1 bzw SCC2 auf TSM-CPU kanal = 2 bzw 3 für ECB-SCC2-Systemkarte mit CPUZ280 auf ECB-Systemen Andere Konfigurationen bitte erfragen! val = 0 Zeichen liegt vor val = 1 kein Zeichen Funktion: Mit LUAVAIL ist feststellbar ob an <kanal> ein Zeichen zur Verfügung steht oder nicht. Dies ist besonders wichtig, wenn innerhalb einer SEQuenz auf einen seriellen Kanal zugegriffen werden muß, time-out- Zeiten aber nicht tolleriert werden können. Beispiel: 1000 WAIT FOR LUAVAIL(2) ' Warte auf Zeichen 1010 a$ = INCHAR(2) ' ... dann einlesen 1020 .... 5.17 Linkadapter (nur TSM-CPU) Linkadapter sind sehr schnelle, serielle Schnittstellen. In MSR-BASIC ist ein einfacher Treiber für die TSM-CPU installiert worden. Der LINK-Anschluss ist über Kanal (LU)#3 erreichbar. Die Daten können mit INCHAR$(3) bzw. INPUT ON(3) eingelesen werden und mit PRINT ON(3) über den LINK-Anschluß ausgetauscht werden. -79-
  • 80.
    5.18 BITBUS-Anschluß (nurTSM-CPU) Um eine Kommunikation über den Feldbus BITBUS(R) zu ermöglichen wurde in MSRBASIC für die TSM-Serie (mit Option BITBUS-Modul) ein BITBUS- Treiber implementiert. Es ist zu beachten, daß bei Verwendung des BITBUS-Moduls lediglich eine serielle Schnitt-stelle zur Verfügung steht, das Modul der 2. und 3. Schnitt-stelle muß gegen ein BITBUS- Modul ausgetauscht werden! Unabhängig vom MSRBASIC-Interpreter sind mit diesem Treiber alle Funktionen eines BITBUS-Rechners verfügbar, außer den 8044- spezifischen und den TASK-Funktionen ( zur Begriffserläuterung siehe entsprechenden BITBUS-Unterlagen ). 5.18.1 Allgemeines MSRBASIC reserviert im Speicherbereich der TSM-CPU einen 256 Byte großen Puffer, der über den BITBUS und von MSRBASIC aus beschrieben und gelesen werden kann. Darüberhinaus können auch vordefinierte Datensätze ausgetauscht werden. Da auf den Puffer asynchron von beiden Seiten aus zugegriffen werden kann, wird dringend empfohlen ein Byte des (internen) Speichers) als Flag zur Kommunikation zu verwenden. Der Pufferinhalt kann folgende vier Zustände einnehmen: 0 = leer (Inhalt ungültig) 1 = beschrieben(teilweise oder voll) 2 = beschrieben(angeforderte Daten) 3 = beschrieben(nicht entgegengenommen) Es müßen natürlich nicht alle Zustände berücksichtigt werden, für einen einseitigen Datentransfer genügt es Daten in den Puffer zu schreiben und dann zu warten bis der Puffer wieder leer ist (Zustand 0 oder 1). Sollten Parameter übergeben (Zustand 0 oder 1) werden und die Gegenseite daraufhin Ergebnisse liefern, so liegt ein Daten-austausch in beiden Richtungen vor. Es muß ein weiterer Zustand des Flags genutzt werden, um Parameter von Ergebnissen zu unterscheiden (Zustand 0 oder 2). 5.18.2 Datenaustausch vom PC Die Programmierung auf der PC-Seite bedarf einiger Kenntnisse über die Struktur und die Arbeitsweise des BITBUS. Die Struktur einer BITBUS-Nachricht und die Bedeutung seiner einzelnen Felder ist in den Unterlagen zum BITBUS (z.B. TSM - Handbuch für Softwareentwickler) ausführlich beschrieben. Der Vollständigkeit halber sei die Struktur des BITBUS-Header mit der Bedeutung seiner Felder hier nocheinmal aufgezeigt: -80-
  • 81.
    +)))))))0)))))))0)))))))))0)))))))0))))))))))))))0)))))))), *Länge * Flags * Adresse * Tasks * Befehl/Rückm.* n Daten* .)))))))2)))))))2)))))))))2)))))))2))))))))))))))2))))))))- In Zusammenhang mit MSRBASIC sind vor allem die RAC-Befehle: DOWNLOAD_MEM = 09H zum Datentransfer UPLOAD_MEM = 08H READ_INTERNAL_MEM = 0EH zur FLAG-"Ablage" WRITE_INTERNAL_MEM = 0DH von Interesse. Aufgabe des Programmierers ist es, in einer beliebigen Hoch-sprache oder auf Assemblerebene entsprechende Nachrichtenfelder zu senden, zu empfangen und entsprechend auszuwerten. Beispiel: Es sollen von einem PC aus 4 Zahlenwerte, als 16-Bit Integer-zahlen an MSRBASIC übergeben werden. Die vier Werte sind 290 (0122H), 563 (0233H), 836 (0344H) und 17493 (4455H). Die Nachricht sieht demgemäß wie folgt aus: ... 09 00 01 01 22 02 33 03 44 44 55 ^ ^ ^ ^ ^ ^ | | | | | Wert 4455 | | | | Wert 0344 | | | Wert 0233 | | Wert 0122 | Offset 0 (Ab Startadresse) RAC-Befehl 09H (DOWNLOAD_MEM) nun FLAG für "beschrieben" = 1 setzen: ... 0D 00 01 ^ ^ ^ | | FLAG = 1 | Offset = 0 RAC-Befehl 0DH (WRITE_INTERNAL_MEM) Sollen weitere Daten übergeben werden, muß zuerst das Zustands-FLAG gelesen werden: ... 0E 00 ?? ^ ^ ^ | | Platzhalter für Antwort | Offset = 0 RAC-Befehl 0EH(READ_INTERNAL-RAM) Die Antwort kann wie folgt aussehen: ... 00 00 00 ; OK - Daten übernommen, Puffer leer ... 00 00 01 ; Daten noch nicht übernommen (Puffer voll) ... 00 00 02 ; OK Daten übernommen - Ergebnisse vorhanden -81-
  • 82.
    Ist das FLAG= 02 ( angeforderte Daten vorhanden ), oder man möchte ganz allgemein den Puffer auslesen, so würde die ent-sprechende Nachricht wie folgt aussehen: ... 08 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ^ RAC-Befehl 08H (UPLOAD_MEM) von Offset=0 wobei die Fragezeichen "?" wiederum nur Platzhalter sind. Das "Ergebnis" könnte dann wie folgt aussehen: ... 00 00 00 01 22 02 33 03 44 44 55 Achtung: BITBUS verwendet die HIGH-/LOW-Byte-Darstellung im Gegensatz zur Darstellung eines 16-Bit-Wertes in Z80/Z280-Programmen! -82-
  • 83.
    5.18.3 Datenaustausch ausMSRBASIC Die Übermittlung und Auswertung von Daten von MSRBASIC aus läßt sich erheblich einfacher gestalten als dies vom PC aus möglich ist, da hier die entsprechenden Treiber bereits integriert sind. Es werden hier Funktionen, das Zustands-FLAG und Daten zu be-arbeiten. 5.18.3.1 BITZFLAG Aufruf: <zn> PRINT BITZFLAG Funktion: Dieses Schlüsselwort ist eine Systemvariable, die das Zustands-FLAG enthält. Man kann dieses auslesen und setzten. Beispiel: 1000 WAIT FOR BITZFLAG <> 0 ' Warten bis Änderung .... Daten übernehmen ... 1199 BITZFLAG = 0 ' Puffer leer 5.18.3.2 BITRB (read byte) Aufruf: <zn> var = BITRB(n) Funktion: Es wird ein Byte mit dem Offset n aus dem 256-Byte-Puffer in die Variable var gelesen. Beispiel: 100 FOR i = 1 to 8 ' 8 Bytes lesen 110 PRINT BITRB(i) AS 2H; 120 PRINT " "; 130 NEXT i 140 PRINT 5.18.3.3 BITRW (read word) Aufruf: <zn> var = BITRW(n) Funktion: Es wird ein Wort (16 Bit) mit dem Offset n aus dem 256-Byte-Puffer in die Bariable var gelesen. Beispiel: 100 IF BITZFLAG = THEN 110 ELSE 100 110 FOR i = 1 to 8 -83-
  • 84.
    120 var = BITRW(i) 130 PRINT i, 140 PRINT var AS 4H; 150 NEXT i 160 .... Achtung: Bei einem Puffer von 256 Bytes sind natürlich nur 128 Worte enthalten ! 5.18.3.3 BITRH (read 24 Bit) Aufruf: <zn> var = BITRH(n) Funktion: Es werden 24-Bit (3 Byte) mit dem Offset n aus dem 256-Byte-Puffer in die Variable var gelesen. Beispiel: siehe BITRB, BITRW 5.18.3.4 BITRS$ (string) Aufruf: <zn> var$ = BITRS$(n) Funktion: Es wird eine Zeichenkette (string) mit dem Offset n aus dem 256-Byte- Puffer an die Stringvariable var$ übergeben. Der Offset n muß auf eine Zeichenkette deuten, deren erstes Zeichen die Länge der Zeichenkette zeigt, die folgenden Zeichen, entsprechend der eingetragen Länge, sind Inhalt der Zeichenkette. Beispiel: 100 IF BITZFLAG = 2 THEN 120 ELSE 100 110 REM warten auf String 120 var$ = BITRS$ ' einlesen 130 IF LEFT$(var$,6) = "MONTAG" THEN 1000 140 .... Achtung: Da die Textlänge praktisch Alles zwischen 2 und 256 Bytes sein kann, ist es empfehlenswert hier ohne Offset zu arbeiten, wenn die Textlänge nicht immer vorhersagbar ist. 5.18.3.5 BITWB (write byte) Aufruf: <zn> BITWB(n, var) Funktion: -84-
  • 85.
    Mit BITWB könnenbis zu 256 Bytes in den BITBUS-Puffer geschrieben werden. Mit <n> wird ein evtl. Offset angegeben, <var> enthält das zu übergebende Byte. Beispiel: 100 IF BITZF = 0 THEN 110 ELSE 100 ' bereit ? 110 FOR i = 0 TO 256 120 var = PEEK(0x8000+i) ' Speicherdump 130 BITWB(i,var) ' ab 8000H 140 NEXT i 150 BITZF = 1 ' Puffer voll 160 ... 5.18.3.6 BITWW (write word) Aufruf: <zn> BITWW(n,var) Funktion: Mit BITWW können bis zu 128 Worte in den BITBUS-Puffer geschrieben werden. Mit <n> wird ein evtl. Offset angegeben, <var> enthält das zu übergebende Byte. Beispiel: 100 IF BITZFLAG = 0 THEN 110 ELSE 100 110 var = ADC(3) ' ADC(3) einlesen 120 BITWE(0, var) ' Wert an BITBUS 130 BITZFLAG = 1 ' Flag setzen 140 ... 5.18.3.7 BITWH (write 24 bit) Aufruf: <zn> BITWH(n,var) Funktion: Mit BITWH können bis zu 84 24-Bit-Werte in den BITBUS-Puffer geschrieben werden. Mit <n> wird ein evtl. Offset angegeben, <var> enthält das zu übergebende Byte. Beispiel: siehe BITWB, BITWW 5.18.3.8 BITWS$ (write string) Aufruf: <zn> BITWS$(n,var$) Funktion: Mit dieser Funktion kann eine Zeichenkette (max 255 Zeichen lang) in den BITBUS-Puffer geschrieben werden. <n> gibt einem möglichen Offset in den Puffer an. -85-
  • 86.
    Achtung: JedeZeichenkette wird automatisch mit einer vorangestellten Längenangabe in den Puffer über- tragen; bei Verwendung eines Offsets ist daher für jeden Eintrag ein Byte an der Puffergröße abzuziehen ! Beispiel: Es sollen die Werte der AD-Wandler 1 und 2 jeweils mit Datum und Uhrzeit übertragen werden. 1000 FOR i = 1 TO 2 1100 IF BITZFLAG = 0 THEN 1110 ELSE 1100 1110 BITWS$(0, DATE$) 'Datum 1120 BITWS$(1, TIME$) 'Uhrzeit 1130 BITZFLAG = 1 ' Puffer voller Text 1140 IF BITZFLAG = 0 THEN 1150 ELSE 1140 1150 BITWW(0,ADC(i) ' jetzt ADC-Wert ausgeben 1160 BITZFLAG = 1 ' .. und markieren 1170 NEXT i ' 2. Paket absenden 1180 IF BITZFLAG = 0 THEN 1190 ELSE 1180 1190 PRINT "Daten übergeben" Ein weiteres Beispiel: 1000 IF BITZFLAG = 2 THEN 1100 ELSE 1000 1010 REM - Anforderung vom PC - 1020 REM 0,n lese ADC(n) 1030 REM 1,n lese DIN(n) 1040 REM 2,n,v schreibe DAC(n) = v 1050 REM 3,n,v setzte DOUT(n) = v 1100 cmd = BITRB(0) ' Befehl holen 1110 IF cmd = 0 THEN GOTO 2000 1120 IF cmd = 1 THEN GOTO 3000 1130 IF cmd = 2 THEN GOTO 4000 1140 IF cmd = 3 THEN GOTO 5000 1150 var$ = "unbekannter Befehl" 1160 BITWS$(0,var$) ' Fehler melden 1170 BITZFLAG = 1 1180 GOTO 1000 ' neu Abfragen 2000 kanal=BITRB(1) 2010 BITWW(0,ADC,kanal) ' Daten übergeben 2020 GOTO 6000 3000 kanal = BITRB(1) 3010 BITWB(0,DIN(kanal) 3020 GOTO 6000 4000 kanal = BITRB(1) 4010 val = BITRW(1) ' wg. Wort ! 4020 DAC(kanal) = val 4030 GOTO 7000 5000 kanal = BITRB(1) 5010 val = BITRB(2) 5020 DOUT(kanal) = val 6000 BITZFLAG = 1 ' Daten übergeben 6010 GOTO 1000 7000 BITZFLAG = 0 ' Puffer leer 7010 GOTO 1000 -86-
  • 87.
    5.19 Fahrtregler (POS)(nur TSM) 5.19.1 Allgemeines Um einen Gleichstrommotor anzusteuern bedarf es im allgemeinen zweierlei: Es muß die Motorspannung für den Servoverstärker erzeugt werden Es muß die IST-Position erfaßt werden Die Steuerspannung für den Motor kann über einen frei defi-nierbaren D/A-Kanal eines TSM-2DA12 Moduls ausgegeben werden. Die in MSRBASIC eingebundenn Treiber erlauben bis zu vier unabhängige Antriebe, die auch paarweise, koordiniert ein Ziel anfahren können (X/Y-Fahrt). Der Verlauf einer Fahrt ist voreinstellbar, d.h. die max. Geschwindigkeit und die Anfahr-/Bremsbeschleunigung kann durch den Programmierer definiert werden. Zu Positionserfassung stehen zwei Module mit unterschiedlicher Technik zur Wahl: TSM-4SSI und TSM-1INC Beide Module können eine beliebige ID-Nummer haben, das Modul mit der niedrigsten ID-Nummer wird mit n=1, das nächste mit n=2 usw. Das Modul TSM-4SSI wird zusätzlich noch nach der Nummer-ierung seiner Stecker festgelegt. Um eine Position zu erfassen, Parameter festzulegen und eine Fahrt zu starten sind folgende Funktionen in MSRBASIC implementiert worden: 5.19.2 POS Aufruf: <zn> var = POS(n) Funktion: In <var> wird die aktuelle Position eines angeschlossenen Gebers zurückgegeben. Die Fehlermeldung <25> wird ausgegeben, wenn kein Geber oder die Betriebsspannung (24V) nicht angeschlossen ist. 5.19.3 POSTYPE Aufruf: <zn> POSTYPE(n,typ) -87-
  • 88.
    Funktion: Es wird dieAuflösung des angeschlossenen Gebers (nur TSM-4SSI) definiert. Hierbei sind folgende Typen <typ> zugelassen: 644444444;44444444444447 5 Typ 5 Geber 5 5 5 5 5 2048 5 2048/4096 5 5 1024 5 1024/2048 5 5 512 5 512/1024 5 5 256 5 256/512 5 5 128 5 128/256 5 5 64 5 64/128 5 5 32 5 32/64 5 5 16 5 16/32 5 944444444=44444444444448 5.19.4 POSSRN Aufruf: <zn> POSSRN(n) Funktion: Dieser Befehl setzt die aktuelle Position des Gebers <n> als Nullpunkt. Alle folgenden Positionsangaben sind relativ zu dieser Position zu betrachten. 5.19.5 FRDEF Aufruf: FRDEF(n, g, dac) Funktion: Dieser Aufruf reserviert für den Antrieb <n> (max. 1..4) den Positionsgeber <g> (1..NPOS) und den DAC-Ausgang <dac>. Es wird vorausgesetzt, daß die entsprechenden Baugruppen zur Verfügung stehen. 5.19.6 FRSETP Aufruf: <zn> FRSETP(n, mv, ma, mweg) mit n = Antriebsnummer mv = max. Steuerspannung(DAC) 1) ma = Beschleunigung 2) mweg = Antriebskonstante 3) 1) Steuerspannung im Bereich 0..10000 mV. 2) Zuwachs der Steuerspannung pro Intervall (8ms). 3) Positionsdifferenz in einem Intervall(8 ms), wenn die max. Steuerspannung von 10V anliegen würde. 5.19.7 FRSETKP Aufruf: <zn> FRSETKP(kp) Funktion: -88-
  • 89.
    Definition des kp-Regelparameters.Dieser Parameter ist für die Verstärkung des p-Anteiles des Reglers zuständig. Typische Werte für kp sind 0...1.000. Höhere Werte sind zulässig aber nicht sinnvoll. 5.19.8 FRSETKI(ki) Aufruf: <zn> FRSETKI(ki) Funktion: Definition des ki-Regelparameters. Dieser Parameter ist der Integralbeiwert des I-Anteiles des Reglers. Typische Werte für ki sind 0...1.0000. 5.19.9 FRLSFAHRT Aufruf: <zn> err = FRLSFAHRT(n,pos) mit n = Antriebsnummer (1..4) pos = Zielposition Funktion: Veranlassung einer Fahrt des Antriebes <n> auf die Position <pos>. Diese Funktion gibt NULL zurück, wenn die Fahrt erfolgreich initialisiert wurde. Die Fahrt erfolgt im Programmhintergrund, damit können so Funktionen ausgerufen werden jedoch keine weitere Fahrt für den aufgerufenen Antrieb bis dieser seine Zielposition erreicht hat. 5.19.10 FRLDFAHRT Aufruf: <zn> err = FRLDFAHRT(xn, xpos, yn, ypos) Veranlassung einer koordinierten Fahrt der Antriebe <xn> und <yn> auf die Positionen <xpos> bzw. <ypos>. Diese Funktion gibt NULL zurück, wenn die Fahrt erfolgreich initialisiert wurde. Die Fahrt erfolgt im Programmhintergrund, damit können so Funktionen ausgerufen werden jedoch keine weiteren Fahrten für die aufgerufenen Antriebe bis diese ihre Zielposition erreicht haben. 5.19.11 FRSTAT Aufruf: <zn> stat = FRSTAT(n) Funktion: Diese Funktion gibt den Status des Antriebes <n> zurück. Dies ist die einige Möglichkeit den Fahrzustand festzustellen in welchem sich ein -89-
  • 90.
    Antrieb gerade befindet. Beispiel: 100 stat = FRSTAT(1) 110 PRINT "Antrieb "; 120 IF stat = 0 THEN PRINT "ruhend" 130 IF stat = 1 THEN PRINT "fährt an" 140 IF stat = 2 THEN PRINT "fährt" 150 IF stat = 3 THEN PRINT "bremst" 160 IF stat = 4 THEN PRINT "schleicht zum Ziel" 170 IF stat >=5 THEN PRINT "angehalten FEHLER!" WEnn der Positionierfehler zu groß ist, wird <stat> >= 5 zurückgegeben. Erst die nächste Abfrage liefert NULL für Antrieb "ruhend". 5.19.12 FRERROR Aufruf: <zn> perr = FRERROR(n) Funktion: Diese Funktion gibt den Positionsfehler zurück, der beim Bremseintritt eingetreten ist. Es wird dabei vorausgesetzt, daß die Funktion FRLSFAHRT oder FRLDFAHRT aufgerufen wurde und die Strecke erfolgreich, ohne Abbruch gefahren wurde. Diese Funktion ist dafür gedacht, den Parameter <mweg> in der Funktion FRSETP zu optimieren. Dazu eignet sich folgende Vorgehensweise: 1. mit FRSETKI und FRSETKP die dazugehörigen Parameter auf NULL setzen um diese Einflüße möglichst niedrig zu halten. 2. Einen Näherungswert von <mweg> setzen. 3. Den Antrieb laufen lassen, falls Fehlerfrei mit FRSTAT testen ob ein Positionsfehler aufgetreten ist sonst <mweg> korrigieren bis der kleinste Positionsfehler ermittelt wurde. -90-
  • 91.
    6. Ein-/Ausgabe-Sprachmittel 6.1 Übersicht Eingroßer Vorteil von MSRBASIC ist seine Fähigkeit, auch im Multitask-Betrieb unmittelbare Kommandoeingaben zu verarbeiten. Die im folgenden beschriebenen MSR-Features verbessern diesen Ansatz ganz wesentlich durch - Fenstertechnik zur automatischen Trennung der Kommando- Ein/Ausgabe-Vorgänge von programmgesteuerten Bildschirmzugriffen (Prozeßdarstellung, Protokollierung usw.). - Terminal-unabhängige Cursor-Positionierung im Rahmen der PRINT-Anweiung. - Schneller Zugriff auf in Dateien abgelegte Bildschirmmasken - Beschleunigung der Kommando-Bedienung auch bei hoher Echtzeitbelastung. - Einfache Gestaltung von Steuerungs-Übersichtsbildern durch SEQLIST-Programmanweisung - TRACE-Anweisungen bis in die TASKs und SEQuenzen hinein. -91-
  • 92.
    6.1.1 Fenstertechnik Die eingebundeneFenstertechnik erleichtert im hohen Maß die Implementierung von Bildschirm-basierenden Bedien- und Anzeigefunktionen mit MSRBASIC, wobei insbesondere die residenten Echtzeiteingriffmöglichkeiten von MSRBASIC unterstützt werden. Der Bildschirm wird hierbei in ein oberes und ein unteres Fenster aufgeteilt. Das obere Fenster (Anwenderfenster) steht dem Programmierer für die Ausgabe mit PRINT-Anweisungen zur Verfügung. Hier lassen sich in der Prozeßleittechnik übliche Darstellungsformen wie z.B. Balkendiagramme oder Trendkurven abbilden. Die Darstell-ungsmöglichkeiten sind natürlich abhängig von den verwendeten Ausgabemedien. (Vollgrafik, Blockgrafik, nur Text usw.) Das untere Fenster (Kommandofenster) erlaubt Zugriffe auf den MSRBASIC-Kommandointerpreter. Die Ausgabe innerhalb dieses Fensters wird aktiviert bei: - MSRBASIC-Kommandos (z.B. LIST, SEQLIST etc.) - direkten Anweisungen (z.B. PRINT Y, W=50 etc.) - Fehlermeldungen - TRACE-Ausgaben Die verwendete Fenstertechnik stellt softwaretechnisch einen Ausgabefilter dar, der bei jeder Ausgabeanforderung des MSR-BASIC- Interpreters den momentanen, internen Status auswertet, um das aktuelle Zeichen in das richtige Fenster zu positionieren. Diese Methode garantiert eine absolute Unabhängigkeit der Anwenderprogrammierung von der Fensterverwaltung (Transparenz). -92-
  • 93.
    6.1.2 Fenster-Programmierung Die Fenstertechnikwird aktiviert und deaktiviert über die MSRBASIC Systemvariable WINDOW. 6.1.2.1 Fenster einschalten Aufruf: <zn> WINDOW = NWIN <cr> mit NWIN = Anzahl der Zeilen im oberen Fenster (1..23) Wirkung: - Bildschirm löschen und - Fensterfunktion aktivieren. 6.1.2.2 Fenster ausschalten Aufruf: <zn> WINDOW = 0 Wirkung: - Bildschirm löschen und - Fensterfunktion ausschalten 6.1.2.3 Cursor positionieren Aufruf: <zn> PRINT [<zeile>,<spalte>] <Zeichen> Wirkung: - Cursor wird auf Position <zeile>,<spalte> gesetzt - <Zeichen> wird an dieser Position ausgegeben - Cursor rückt auf nächste Position vor 6.1.2.4 Masken-Dateien ausgeben Aufruf: OPEN <maskenname,<log.Einheit>,1 COMMAND (Log.Einheit)=1 CLOSE <log.Einheit> Wirkung: - Die Datei <maskenname> wird auf den Bildschirm ausgegeben 6.1.2.5 Abfragen des oberen Fensters Aufruf: PRINT WINDOW <cr> Wirkung: - Es wird die Anzahl der benutzbaren Zeilen angegeben. 6.1.3 Beispiel zur Fenstertechnik Das Programm WINDEM.BAS ist als einfachstes Nicht-Echtzeit-Beispiel konzipiert. Zunächst wird eine einfache Bildschirmmaske eingelesen (Zeilen 110..130). Nach einer kurzen Wartezeit (Zeilen 135..136) wird der Bildschirm geteilt (Zeile 140). In der Folge wird gezeigt, wie programmgesteuerte Ausgaben automatisch in das obere Fenster gelangen, während die TRACE-Anzeige in das untere Fenster gelenkt wird. -93-
  • 94.
    100 REM *** WINDEM.BAS *** 110 CLS 120 OPEN "WDLIS.BAS",10,1 130 IF BIT(7,STATUS(10))=1 THEN COMMAND(10)=1 140 CLOSE 10 150 FOR I=1 to 1000 160 NEXT I 170 WINDOW = 8 180 TRACE 190 PRINT [0, 10] " MSR-Zweifenstertechnik " 200 FOR I=1 TO 20 210 PRINT CHR$(I+64); 220 NEXT I 230 NOTRACE 240 STOP Am Bildschirm ergibt sich folgendes Bild: +----------------------------------------------+ Programm- 1 ! MSR-Zweifenstertechnik ! Fenster ! ABCDEFGH ! ----------> 8 ! ! 9 ! ! Kommando- ! 210 PRINT CHR$(I+64); ! Fenster ! 220 NEXT I ! ! 210 PRINT CHR$(I+64); ! ! 220 NEXT I ! ! .............. ! 23 ! ! +----------------------------------------------+ -94-
  • 95.
    6.2 Ein- /Ausgabe-Anweisungen 6.2.1 INPUT Syntaxdiagramm: Aufruf: <zn> IN{PUT} {ON <kanalnummer>} .. <variable>{,<variable>...} Funktion: Die INPUT-Anweisung ermöglicht das programmgesteuerte Einlesen alphanumerischer Daten von - der Konsole (Kanal 0) - einem seriellen E/A-Kanal (INPUT ON (1..9)) Bei der Ausführung der INPUT-Anweisung wird grundsätzlich auf den Eingabekanal 0 (Konsole) ein Fragezeichen ("?") ausgegeben und die Benutzereingabe geechot. Dies setzt voraus, daß ein Konsolenkanal installiert ist. Beim Einlesen von eimem als nicht interaktiv installierten Kanal wird das Echo unterdrückt. Im TRACE-Modus werden allerdings die übersandten Zeichen zur Kontrolle auf der Bedienerkonsole ausgegeben. Sofern mehrere numerische Daten eingelesen werden, müssen sie durch Komma (",") oder Leerzeichen (" ") getrennt werden. Beim Einlesen einer Stringvariablen werden führende Leerzeichen verworfen und nur das Komma (",") als Trennzeichen gewertet. Die INPUT-Anweisung ist grundsätzlich durch TIMEOUT gesichert, d.h. wird eine Eingabe nicht innerhalb 20s abgeschlossen, gilt die Eingabe als fehlerhaft. Das folgende Beispiel zeigt eine (hardware-mäßige) Überprüfung der Schnittstelle: 100 INPUT ON(n) A$ 110 IF BIT(pp,n) THEN ... wobei die Portnummer (pp) der benutzten Schnittstelle und das infrage kommende Statusbit (n) hardware-abhängig sind. Die Eingabe und damit das Programm kann unabhängig von der Einlese- Einheit von der Kommandokonsole aus mit CNTRL-C abgebrochen werden. Beispiel: INPUT A,B A$ -95-
  • 96.
    ? 1,2,ENDE > PRINT A,B,A$ 1.00000E 00 2.00000E 00 ENDE > Hinweise: Im Echtzeitbetrieb (Multitasking) ist die Benutzung der INPUT- Anweisung mit Vorsicht zu behandeln; zwar kann sie entgegen den sonstigen Regeln von höherprioren TASKs unterbrochen werden, es darf aber im unterbrechenden Programm keine neue INPUT-Anweisung vorhanden sein. Wenn derartige Konkurrenzfälle nicht auszuschliessen sind, empfiehlt es sich, die INPUT-Anweisung nur im Rahmenprogramm zu verwenden und Einlesevorgänge in Echtzeit-Rechenprozessen über die INCHAR$-Funktion zu formulieren (s.d.). Fehler: 08 Fehlerhafte Variable in Einleseliste 41 Mehr als eine INPUT-Anweisung aktiv 58 Lesen einer zum Schreiben (Write-only) eröffneter Datei -96-
  • 97.
    6.2.2 PRINT Syntaxdiagramm: Aufruf: <zn> PRINT|? {ON(<kanalnummer>} {<Druckoperand>} Der Druckoperand wird wie folgt aufgerufen: <numerischer Ausdruck> AS <format> für die formatierte Ausgabe numerischer Ausdrücke und/oder "<textausdruck>" und/oder [zeile,spalte] zur Cursorpositionierung auf der Konsole Funktion: Die PRINT-Anweisung ermöglicht die Ausgabe von beliebigen Zeichenfolgen und Zahlenwerten auf den Bildschirm oder einen frei wählbaren Ein-/Ausgabe-Kanal (unter Benutzung des "ON(n)"-Zweiges). Die Tabellierung kann mit Hilfe eines oder mehrerer Kommas (",") zwischen den auszugebenden Daten vorgenommen werden. Die Formatierung von Zahlenwerten erfolgt über die "AS"-Angabe. Die technischen Voraussetzungen sind konfigurationsabhängig! 6.2.2.1 Tabellierung Bei der voreingestellten Tabellierung wird eine Ausgabezeile in 5 Felder mit einer Länge von 13 Zeichen eingestellt. Die Verwendung des Kommas (",") als Trennungszeichen bewirkt ein Vorrücken der Druckposition zum Beginn des nächsten 13er Feldes. Soll dies verhindert werden, muß der Strichpunkt (";") als Trennungszeichen verwendet werden. Wenn der automatische Zeilenvorschub bei Beendigung der PRINT- Anweisung unterbunden werden soll, muß als letztes Zeichen ein Komma oder Strichpunkt gesetzt werden. 6.2.2.2 Cursor-Positionierung Die Cursorpositionierung ist Hardware- und Konfigurationsabhängig. Der entsprechende Ausgangstreiber muß eine Cursorpositionierung erlauben (siehe Kapitel 10). Nach jedem Strichpunkt (";") kann eine erneute Cursor-Positionierung vorgenommen werden. 6.2.2.3 Formatierung -97-
  • 98.
    Alle numerischen Wertewerden, falls keine Formatierung angegeben ist, im Festkomma-Format (Grundeinstellung 12F4, siehe unten ) wie folgt dargestellt: > a = 11111111 > print a 1.1111E 07 Genauigkeit 5-stellig > a=12345678 > print a 1.2346E 07 letzte Stelle wird aufgerundet ! Werden andere Ausgabeformate verlangt kann mit der "AS"-Anweisung wie folgt formatiert werden: 1. E-Format (Gleitkomma) Das Format hat die Form fEk, wobei f die Feldlänge (Gesamtlänge incl. Vorzeichen und Punkt) und k die Nachkommastellen der Mantisse angibt. 2. F-Format (Festkomma) Das F-Format hat die Form fFk wobei f die Feldlänge (Gesamtlänge incl. Vorzeichen und Punkt) und k die Nachkommastellen festlegt. 3. I-Format (Ganzzahl) Das I-Format hat die Form fI, wobei f die Feldlänge (Gesamtlänge) festlegt. 4. H-Format (Hexadezimal) Das H-Format hat die Form fH, wobei f die Feldlänge (Gesamtlänge) festlegt. In allen Fällen werden die Zahlen auf das entsprechende Ausgabeformat gerundet (nicht abgschnitten!). Sofern der auszugebende Zahlenwert im Rahmen des gewünschten Formates nicht darstellbar ist, wird die gesamte Feldlänge mit dem "*"- Zeichen beschrieben. Die Feldlängenangabe f darf maximal 2-stellig sein. Soll der numerische Wert mit führenden Nullen (z.B. 0055) dargestellt werden, muß vor die Feldlängenangabe eine "0" angegeben werden; die Feldlängengröße ist dabei automatisch auf "9" begrenzt, da, wie oben erwähnt, max. 2 Stellen angegeben werden dürfen! Beispiele: a) 10 A=7.78 20 PRINT A AS 5I, A AS 10F3, A AS 12E2,A,A AS 4F3 30 STOP Ergebnis: 8 7.780 7.78E 00 7.7800E 00 **** b) 10 PRINT ON(0) "PRINTST" 20 REM 30 a=1, b=-1 100 PRINT ON(0) "Integer Format" 110 PRINT ON(0) a AS 6I, b AS 6I 120 PRINT ON(0) a AS 06I, b AS 06I 200 PRINT ON(0) "Festkomma-Format" 210 PRINT ON(0) a AS 9F4, b AS 9F4 220 PRINT ON(0) a AS 09F4, b AS 09F4 -98-
  • 99.
    300 PRINT ON(0) "Gleitkomma-Format" 310 PRINT ON(0) a AS 9E2, b AS 9E2 320 PRINT ON(0) a AS 09E2, b AS 09E2 999 STOP Ergebnis: PRINTST Integer-Format 1 -1 000001 -00001 Festkomma-Format 1.0000 -1.0000 0001.0000 -001.0000 Gleitkomma-Format 1.00E 00 -1.00E 00 01.00E 00 -1.00E 00 Fehler: 08 Syntaktisch falsche Form 59 Schreiben auf eine zum Lesen (Read-only) eröffnete Datei -99-
  • 100.
    6.3 Schnittstellenfunktionen Unter "Schnittstellen"sind alle hardwaremäßig eingebundenen Kanäle zu verstehen auf welche mit dem ON(n)-Zweig in Anweisungen wie PRINT, LIST usw. zugegriffen werden kann. 6.3.1 EOF(n) Die EOF-Funktion hat den Wert 0, wenn beim letzten Zugriff auf den seriellen Einlese-Kanal n vom Betriebssystem keine EOF-Bedingung zurückgemeldet wurde bzw. wenn das nächste Einlesezeichen kein CNTRL- Z (1AH) ist. Eine EOF-Bedingung kann damit als "keine weitere Eingabe vorhanden" interpretiert werden und ist in dieser Form (unter CP/M) werksseitig für alle Kanäle implementiert. Beispiel: " Auf Zeicheneingabe warten" 1000 WAIT MAX 10 FOR EOF(0)=0 6.3.2 INCHAR$(n) Die INCHAR$-Funktion liest, falls vorhanden, ein Zeichen von der durch durch die Kanalnummer (n) bestimmten logischen Einheit ein. Falls kein Zeichen anliegt, wird ein NULL-String übergeben. Man beachte, daß INCHAR$ kein Echo auf den Eingabekanal (Konsole) auslöst. Die INCHAR$-Funktion ist besonders dann vorteilhaft, wenn man Falscheingaben des Bedieners sofort und gezielt abfangen will oder falls Probleme mit Konkurrenzanweisungen im Echtzeitbetrieb auftreten können (siehe Hinweis zu 6.2.1 INPUT). Beispiel: 100 REM *** Test INCHAR$(n) *** 110 PRINT "Bitte beliebige Taste drücken " 120 x$ = INCHAR$(0) 130 PRINT " es war Taste ";x$ 140 GOTO 110 -100-
  • 101.
    6.3.3 STATUS(n) Die Status-Funktionliefert in Form eines Zahlenwertes den momentanen Zustand der logischen Einheit (n). Dieser Zahlenwert wird vom Betriebssystem in Form eines 16-Bit-Wertes übergeben. Derzeit sind nur die unteren 8 Bit mit folgender Bedeutung belegt: Bit 7: =1, wenn LU geöffnet ist Bit 6: =1, wenn LU als write-only-Kanal konfiguriert ist Bit 5: =1, wenn EOF-Bedingung aufgetreten ist (=EOF(LU)) Bit 4: = reserviert Bit 3: =1, nur nach INPUT wenn TIMEOUT aufgetreten ist Bit 2: = reserviert Bit 1: =1, wenn Zeichen ausgegeben werden kann Bit 0: =1, wenn ein Zeichen zum Einlesen bereit ist Beispiel: " Warten auf Eingabe mit TIMEOUT 1000 WAIT MAX 10 FOR BIT 6.3.4 COMMAND(n) Die COMMAND-Funktion stellt das Gegenstück zur STATUS-Funktion dar. Sie übergibt an das Betriebssystem einen vom Benutzer vorgegebenen 16- Bit-Wert, der als Steuerwort interpretiert wird. -101-
  • 102.
    7. Standardsprachmittel 7.1 Programmfluß-Steuerung 7.1.1FOR Syntaxdiagramm: Aufruf: <zn> F{OR} <lv> = <stw> TO <ew> {STEP <sw>} <zn> .... <programmteil> <zn> NEXT <lv> Funktion: Die FOR-Anweisung erlaubt den Aufbau von Laufschleifen. Als Laufvariable (lv) darf nur eine skalare numerische Variable verwendet werden, währen Startwert (stw), Endwert (ew) und Schrittweite (sw) durch arithmetische Ausdrücke vorgegeben werden können (alle Werte erlaubt). Falls eine explizite Schrittweitenangabe fehlt, wird als Schrittweite "1" angenommen. Hinweise: Zu beachten ist, daß die Laufschleife wenigstens einmal durchlaufen wird, da die Abbruchbedingung erst in der NEXT-Anweisung geprüft wird. Weiterhin sollte man nicht aus einer Laufschleife herausspringen, sondern bei Erfüllung einer zweiten Abbruchbedingung die Laufvariable auf den Endwert setzen (um evtl. Schwierigkeiten mit dem Stack für Laufvariable zu vermeiden). Es können maximal 10 Laufvariable ineinander verschachtelt werden. Die Verwendung von FOR/NEXT-Schleifen in TASKs und SEQuenzen ist möglich, allerdings müssen unterschiedliche Laufvariable verwendet werden (Sonst Fehlermeldung 20). -102-
  • 103.
    Beispiel: 100 REM *** Einfache Warteschleife 110 FOR I = 1 TO 1000 120 REM auch nichts tun kostet Zeit 130 NEXT I 140 REM *** Verschachtelte Schleife (kleines 1x1) 150 FOR I = 1 TO 10 160 FOR J = 1 TO 10 170 PRINT I*J AS 4I; 180 NEXT J 190 NEXT I 200 STOP Fehler: 16 "="-Zeichen fehlt 17 "TO" oder "STEP" fehlt 18 Mehr als 10 verschachtelte Laufschleifen 20 Laufvariable bereits in (äußerer) Schleife (oder in anderer TASK, SEQuenz, Hintergrundprogramm) verwendet 21 Laufvariable ist Vektor oder String -103-
  • 104.
    7.1.2 NEXT Syntaxdiagramm: Aufruf: ... <FOR-Anweisung> <zn> NEXT{|NX} <lv> Funktion: Die NEXT-Anweisung bestimmt das Ende einer Laufschleife. Hierzu wird grundsätzlich die Laufvariable (lv) um die Schrittweite erhöht und die Schleife abgebrochen, wenn der neue Wert der Laufvariablen über dem Grenzwert liegt. D.h., daß nach Beendigung der Schleife die Laufvariable größer als der Endwert ist. Beispiel: Siehe FOR-Anweisung Fehler: 19 NEXT wird vor FOR bearbeitet 20 Laufvariable in FOR und NEXT nicht identisch -104-
  • 105.
    7.1.3 GOSUB Syntaxdiagramm: Aufruf: <zn> GOSUB {|GS} <zn> Funktion: Mit der GOSUB-Anweisung werden BASIC-Unterprogramme aufgerufen. Aus dem Unterprogramm muß mit einer RETURN-Anweisung in das aufrufende Programm zurückgekehrt werden. Die Verschachtelungstiefe ist beliebig. Beispiel: 100 REM *** Aufruf von Unterprogrammen *** 110 PRINT "** im Laufenden Programm" 120 GOSUB 200 130 PRINT "** hier geht's weiter" 140 STOP 200 REM *** Unterprogramm 210 PRINT "** im Unterprogramm" 220 RETURN Fehler: 05 Unterprogramm mit gewünschter Zeilennummer existiert nicht -105-
  • 106.
    7.1.4 RETURN Syntaxdiagramm: Aufruf: <zn> RETURN {|RT} Funktion: Die RETURN-Anweisung muß am Ende eines über GOSUB aufgerufenen Unterprogrammes, einer TASK oder einer SEQuenz stehen. Bei der Ausführung wird dann das übergeordnete Programm nach der aufrufenden GOSUB-Anweisung fortgesetzt. Beispiel: : 1000 GOSUB 2000 : 2000 REM *** Ein ständig wiederkehrender Programmteil *** 2010 LET TA=TA-1 2020 IF TA>0 THEN RETURN 2030 LET TA=TO 2040 RETURN Hinweis: Bei Beendigung einer SEQuenz durch RETURN wird automatisch die Startzeile der SEQuenz (siehe hierzu DEFINE) als nächste auszuführende Anweisung im SEQuenz-Steuerblock festgelegt , bevor die SEQuenz stillgelegt (suspendiert) wird. -106-
  • 107.
    7.1.5 GOTO Syntaxdiagramm: Aufruf: <zn> GOTO {|GO} <zn> Funktion: Mit der GOTO-Anweisung kann eine unbedingte Programmverzweigung vorgenommen werden. Das Programm wird an der gewünschten Zeilennummer (zn) fortgesetzt. Es kann nicht mit RETURN zurückgekehrt werden. Beispiel: 10 REM *** Initialisierung bei Kaltstart *** 20 IF myflg <> 0 THEN GOTO 100 30 REM hierher wenn myflg = 0 denn ... 40 REM ... nur beim Kaltstart sind ALLE Variablen = 0 50 count = 1000, xyz = 12345 : : 100 REM Hier geht's erst richtig los : 1110 IF count = 12 THEN GOTO 2000 ELSE GOTO 3000 : Fehler: 05 Programmzeile mit der gewünschten Nummer existiert nicht -107-
  • 108.
    7.1.6 IF Syntaxdiagramm: Aufruf: <zn> IF <con> THEN {<anw>|<zn>} {ELSE{<anw>|<zn>}} Funktion: Die IF-Anweisung erlaubt die Formulierung von bedingten Aktionen. Unter Bedingung (con) ist folgende Anordnung zu verstehen: a) numerischer Ausdruck b) Ausdruck1 Relationsoperator Ausdruck2 Falls der Wert eines numerischen Ausdruckes Null ist, gilt die Bedingung als nicht erfüllt, sonst als erfüllt. Als Relationsoperatoren für String- und Zahlenvergleiche sind zuläßig: > größer < kleiner =>, >= größer oder gleich =<, <= kleiner oder gleich <>, >< ungleich = gleich Falls die Bedingung erfüllt ist, wird der THEN-Teil ausgeführt. Falls die Bedingung nicht erfüllt ist, wird die nächste Anweisung im Programmablauf ausgeführt oder (falls vorhanden) die im ELSE-Zweig vorgesehene Aktion. -108-
  • 109.
    Beispiel: a) 1000 IF A<>0 THEN 2000 entspricht 1000 IF A THEN 2000 b) 1010 IF A<-B THEN 2020 ELSE A=-100 c) 1020 IF A$<>CHR$(12)+B$ THEN PRINT "Ungleich" d) 1030 IF A>B THEN IF A>C THEN 3000 Hinweis: Beim Vergleichen zweier Strings (Zeichenketten) bedeutet die "größer"- Aussage, daß der ASCII-Code als Hexzahl betrachtet größer ist. Ist der kleiner String identisch mit dem linken Teilstring des Vergleichsobjektes, dann gilt der längere String als größer. Es gilt z.B.: "Z" > "A" "b" > "Cxxx" "ABCD" < "ABCDEFG" Fehler: 08 Inkompatible Datentypen in den Vergleichsausdrücken 14 Unerlaubte Relation im Bedingungsausdruck -109-
  • 110.
    7.1.7 STOP Syntaxdiagramm: Aufruf: <zn> ST{OP} Funktion: Die STOP-Anweisung legt Abbruchstellen innerhalb eines Programmes fest. Bei der Ausführung kehrt der Interpreter grundsätzlich in die Kommandobetriebsart zurück, auch wenn der Abruch innerhalb eines BASIC-Unterprogrammes erfolgte. Beispiel: 1000 IF A=0 THEN STOP Fehler: (keine) -110-
  • 111.
    7.1.8 END Syntaxdiagramm: Aufruf: <zn> END Funktion: Die END-Anweisung stellt die letzte Anweisung eines BASIC-Programmes das. Sie ist nicht notwendig, wenn das Programm über STOP oder eine RETURN-Anweisung beendet wird oder mit GOTO <start> in einer endlosen Schleife läuft. Beispiel: : : 9999 END Fehler: 03 Hinter END existiert eine weitere Programmzeile -111-
  • 112.
    7.2 Rechen- /Speicheranweisungen 7.2.1DIM Syntaxdiagramm: Aufruf: <zn> DIM <name> (<a1>{<a2>) {,...} Funktion: Mit der DIM-Anweisung können ein- oder zweidimensionale Felder vom Datentyp "REAL" oder "STRING" angelegt werden. Sie erhalten bei der Festlegung einen Namen <name> mit welchem sie angesprochen werden können. Bei Vektoren legt der Wert von "Ausdruck1" (a1) die Länge (Anzahl der Elemente) fest. Die Indizierung geht dabei von 0 bis zur angegebenen Dimensionszahl. Eindimensionale Felder werden grundsätzlich als Spaltenvektoren angelegt, was bei der Anwendung des Matrix-Vektor-Kalküls (siehe MAT) zum Tragen kommt. Bei Matrizen legt der Wert von "Ausdruck1" (a1) die Anzahl der Zeilen fest, während sich die Anzahl der Spalten aus dem Wert von "Ausdruck2" (a2) ergibt. Auch hier beginnt die Indizierung bei 0, wobei allerdings im Rahmen der MAT-Anweisung nur die Teilmatrix ab Element 1,1, benutzt wird. BASIC legt die Felder zeilenweise ab, d.h. zuerst wird die "nullte" Zeile, dann die erste usf. abgelegt. Bei der erstmaligen Anlage von Feldern werden alle Elemente gelöscht ( Wert 0 bei REAL-, Leertext bei STRING-Feldern). Es ist zu Beachten, daß der Feldinhalt auch bei einem Neustart gelöscht wird. Ist dies unerwünscht müssen entsprechende Maßnamen getroffen werden (Beispiele in Kapitel 2.2.12). Sofern der verfügbare Arbeitsspeicher keine physikalische Begrenzung darstellt, beträgt die maximale logische Dimension von: numerischen Vektoren 8190 numerischen Matrizen 126 mal 126 Stringfelder 255 Elemente Mit der DIM-Anweisung können bereits vorhandene Felder redimensioniert werden. Hierbei darf das redimensionierte Feld jedoch nicht größer werden, als bei der erstmaligen Anlage angegeben wurde. Die Umwandlung von Vektoren in Matrizen und umgekehrt ist möglich. Bei der Redimensionierung werden die Feldelemente nicht gelöscht. Beispiel: 1000 DIM X1(10), A(N,N),Xa$(2,10) 1010 INPUT N 1020 DIM X1(N) -112-
  • 113.
    Fehler: 13 Dimension zu groß 33 Redimensionierung nicht möglich, Originalfeld zu klein -113-
  • 114.
    7.2.2 LET Syntaxdiagramm: Aufruf: <zn> {LET} {<var>|<af>} = <ad> {,|:...} Funktion: Die LET-Anweisung erlaubt die Formulierung von Wertzuweisungen und stellt damit die zentrale Anweisung dar. Die Ergebnisse von numerischen oder String-Operationen (ad) können Variablen (var) des gleichen Typs zugewiesen werden. Numerische Werte können darüberhinaus auch an spezielle Ausgabefunktionen (af) wie CNT Zähler DAC Analogausgabe DOUT Binärausgabe PUT Byteausgabe COMMAND Komandowortausgabe (an seriellen Kanal) TUP/TDOWN Zeitgeber TIME$ Tageszeitgeber DATE$ Datumsgeber übergeben werden. -114-
  • 115.
    Beispiel: 1000 A_min = B_max, C=A+B^(X+LN(X2*X3)), A$="AB" 1020 FF$=CHR$(12) : B$=FF$+"ABCDE"+CHR$(27) 1030 LET DAC(N)=K*Y1, DOUT(2)=1, PUT(128)=127 1040 TIME$="08:21:35" : DATE$="22:06:88" Hinweis: LET darf in einer Anweisung entfallen. Wird es jedoch verwendet, sollte zur Vermeidung von Mehrdeutigkeiten nach LET grundsätzlich ein Leerzeichen eingegeben werden. Das folgende Beispiel zeigt mögliche Auswirkungen: Eingabe: Wirkung: LA =1 LA =1 L A =1 LET A =1 LETA=1 LETA =1 Im Zweifel zeigt ein Auslisten der Zeile(n) ob Variablenname bzw. Kurzformen richtig erkannt wurden. Fehler: 07 Anweisung nicht korrekt abgeschlossen 08 Inkompatible Datentypen 10 Ausgabefunktion auf rechter Seite oder Einlesefunktion auf linker Seite -115-
  • 116.
    7.2.3 MAT Syntaxdiagramm: Aufruf: <zn> MAT <fn> = {IDN|ZER|TRO|<ma>|TRN<ma>} Funktion: Die Matrixanweisung MAT erlaubt die direkte Berechnung von Matrix- Ausdrücken und stellt damit das Pendant zur LET-Anweisung für skalare Ausdrücke dar. Neben der sehr kompakten Formulierung von Matrix-Ausdrücken liegt der Hauptvorteil der MAT-Anweisung in der deutlich höheren Rechengeschwindigkeit gegenüber der Programmierung "zu Fuß". Die Geschwindigkeitssteigerung liegt zwischen Faktor 10 und 30. Sie erklärt sich vornehmlich damit, daß für das Aufbrechen des Matrixausdrucks im Vergleich zu den unabdingbaren Rechenoperationen wenig Zeit aufgewendet und keine explizite Indexrechnung gemacht wird. Bei der Bearbeitung der MAT-Anweisung wird zunächst die rechte Seite der Anweisung unter Berücksichtigung der Syntaxregeln und der Dimensionalität der beteiligten Operanden ausgewertet. Anfallende Zwischenergebnise werden selbständig angelegt. Das auf der linken Seite stehende Ergebnisfeld wird entsprechend redimensioniert, es sei denn, daß auf der rechten Seite die Sonderfunktionen IDN, ZER oder TRO stehen. In diesen Fällen behält die Ergebnismatrix ihre ursprüngliche Dimensionierung, da diese Funktionen nur eine Wertsetzng vornehmen. Die Zielmatrix darf bei Multiplikationen nicht auf der rechten Seite stehen. Im Rahmen eines komplexen Matrix-Ausdrucks können folgende Operationen und Funktionen vorgenommen werden: Addition und Subtraktion: Matrix/Matrix Matrix/Skalar Skalar/Matrix Vektor/Vektor Vektor/Skalar Skalar/Vektor Multiplikation: Matrix/Matrix Matrix/Spaltenvektor -116-
  • 117.
    Matrix/Skalar Skalar/Matrix Zeilenvektor/Matrix Zeilenvektor/Spaltenvektor (Skalarprodukt) Spaltenvektor/Zeilenvektor (Dyad. Produkt) Vektor/Skalar Skalar/Vektor Element - Produkt Hinweise: Beim Skalarprodukt wird das Ergebnis im Element 1,1 einer 1*1-Matrix abgelegt. Beim Elementprodukt werden Felder elementweise multipliziert, was insbesondere bei der Normierung/Skalierung von Meßwerten einen häufigen Rechengang darstellt, z. B.: 1000 XE_nor = SKV.XE + X_off Matrix-Vektor_Funktionen: TRN Transposition IDN Die Diagonalelemente der Zielmatrix erhalten den Wert 1, alle anderen Elemente den Wert 0 ZER Alle Wert der Zielmatrix werden zu Null gesetzt TRO verschiebt die Elemente des Zielvektors (!) um eine Indexstelle in Richtung nulltes Element Beispiel: 1000 REM Zustandsdgl. Eingrößensystem 1010 MAT XP = A*X + B*[U] 1020 MAT Y = CT*X 1030 Y=Y(1,1)+D*U 2000 REM Mehrgrößensystem (zeitdiskret) 2010 VEC U=MADC(MO) 2020 MAT X1=P*X + Q*U 2030 MAT Y=CT*X + D*U 2040 VEC MDAC(SO)=Y 2050 MAT X=X1 Fehler: 11 Feldtyp falsch (Dimension oder String/Vektor) 12 Undefiniertes Feld 30 Unerlaupter Operand in MAT-Anweisung 31 Falsche Reihenfolge von MAT-Operationen 32 Inkonsistente Dimension auf der rechten Seite 33 Zielfeld zu klein dimensioniert 34 Vektor zu groß (>126) für MAT-Operationen 35 Zielfeld auch auf der linken Seite der MAT-Anweisung 36 Zuwenig Speicher für Ablage der Zwischenergebnisse 37 Interner Konsistenzfehler 7.2.4 VEC Syntaxdiagramm: -117-
  • 118.
    Aufruf: <zn> VEC {<name>|{MDAC<sv>|MDOUT<sv>} = {<name>|{MDAC<mv>|MDIN}<mv>{+|...} {,...} Funktion: Die VEC-Anweisung erlaubt die Formulierung von vektorwertigen Prozeß- Ein-/Ausgabe-Operationen bzw. PI(D)-Reglerfunktionen. Ähnlich der MAT- Anweisung werden durch das Schlüsselwort VEC alle in der Anweisung auftauchenden Variablennamen (name) als Namen eindimensionaler numerischer Felder aufgefaßt. (Siehe hierzu Vektor-Funktionen). Beispiel: 1000 REM Einlesen des Meßvektors XE 1010 REM Der Meßortvektor MO enthält in seinen 1020 REM Komponenten die Einlesekanalnummern 1030 REM 1040 VEC XE=MADC(MO) 2000 REM Ausgabe des analogen Stellvektors Y 2010 REM Der Stellortvektor SO enthält in seinen 2020 REM Komponenten die Ausgabekanalnummern 2030 REM 2040 VEC MDAC(SO) = Y 3000 REM E,E1 usw. sind alle Vektoren 3010 VEC Y=PI(Y,E,E1,KP,KI,YO,YU,YD,AK) Fehler: 24 Unterschiedliche Dimension zweier Vektoren 25 (Hardware-)Fehler beim E/A-Zugriff 29 Fehler bei der Bestimmung der logischen Kanaladresse (gewünschter Kanal existiert nicht) -118-
  • 119.
    7.2.5 POKE Syntaxdiagramm: Aufruf: <zn> POKE (<adresse>,<wert>) <cr> Funktion: Die im Argument <adresse> der POKE-Anweisung angegebene Speicheradresse wird mit dem Wert <wert> beschrieben. Adresse: ist ein ganzzahliger Ausdruck, dessen Wert im Bereich zwischen 0..65535 liegt. (0000H...FFFFH) und die Adresse einer Speicherstelle im 64k-Bereich darstellt. Wert: Ist ein ganzzahliger Ausdruck, dessen Wert im Bereich zwischen 0..255 liegt und das äquivalent der zu speichernden Information darstellt. (1 Byte) Hinweis: Es wird nicht überprüft ob sich <wert> unter der angegebenen Adresse abspeichern läßt noch ob durch die Abspeicherung irgendwelche Programmabläufe gestört werden können. Die POKE-Anweisung ist aus diesem Grund mit größter Vorsicht zu behandeln. Beispiel: 100 REM *** POKE-Test 110 Addr = &H9000, Value = 195 120 POKE (addr,value) 130 x = PEEK(addr) 140 PRINT x AS 2I Fehler: 13 Argument ist nicht im vereinbarten Bereich -119-
  • 120.
    7.3 Kommentare 7.3.1 REM Syntaxdiagramm: Aufruf: <zn> REM|' <kommentar> <cr> Funktion: Die REM-Anweisung erlaubt die Einfügung von Kommentaren in das Programm. Kommentare haben auf die Programmausführung keinen. In Einfluß. In zeitkritischen Programmsegmenten sollte jedoch auf eine Kommentierung verzichtet werden, da der Interpreter zur Erkennung einer Kommentarzeile doch eine gewisse Zeit benötigt. In Anwendungen wo der Speicherplatz knapp wird, kann es u.U. ebenfalls notwendig sein die Kommentierung einzuschränken oder ganz wegzulassen. Beispiel: 1000 REM Kommentarzeilen werden vom 1010 REM BASIC-Interpreter ignoriert 1020 REM Die Zeilennummern dürfen jedoch 1030 REM nicht nochmals benutzt werden ! Fehler: (keine) -120-
  • 121.
    7.4 Dateibefehle Ersatzlos gestrichen,da kein DOS verfügbar. Up- und Download sowie das Speichern von Daten ist über Terminalprogramme (MSRSHELL) und PC-Rechnern einfach zu realisieren. -121-
  • 122.
    7.5 Standardfunktionen 7.5.1 ABS(X) Funktion:Es wird der Betrag von X zurückgegeben 7.5.2 ACN(X) Funktion: Es wird der ArcusCosinus von X zurückgegeben 7.5.3 ASN(X) Funktion: Es wird der ArcusSinus von X zurückgegeben 7.5.4 ATN(X) Funktion: Es wird der ArcusTangens von X zurückgegeben 7.5.5 COS(X) Funktion: Es wird der Cosinus von X zurückgegeben 7.5.6 EXP(X) Funktion: Es wird der Exponent von X zurückgegeben 7.5.7 INT(X) Funktion: Es wird der INTEGER-Wert von X zurückgegeben 7.5.8 LN(X) Funktion: Es wird der natürliche Logarithmus von X zurückgegeben 7.5.9 LOG(X) Funktion: Es wird der dekadische Logarithmus von X zurückgegeben 7.5.10 SIN(X) Funktion: Es wird der Sinus von X zurückgegeben 7.5.11 SQR(X) Funktion: Es wird die Quadratwurzel von X zurückgegeben 7.5.12 TAN(X) Funktion: Es wird der Tangens von X zurückgegeben. -122-
  • 123.
    7.6 Stringfunktionen 7.6.1 CHR$(X) Funktion:Der Wert von X wird als ASCII-Zeichen interpretiert Beispiel: 1000 FF$ = CHR$(12) 7.6.2 VAL(X$) Funktion: Die durch den String X$ gegebene Ziffernfolge wird in Zahlenwert umgewandelt. Beispiel: 1000 Zahl$ = "123" 1010 PRINT VAL(ZAHL$) AS 10F3 liefert 123.000 Fehler: 09 Fehler beim Wandeln einer numerischen Konstante 7.6.3 LEN(X$) Funktion: Es wird die Länge des Stringausdrucks X$ zurückgeliefert. Beispiel: 1000 Zahl$ = "123" 1010 PRINT LEN(ZAHL$) AS 6I liefert 3 Zum Abspalten von Teilstrings aus einem Quellstring stehen in MSRBASIC folgende Funktionen zur Verfügung: 7.6.4 LEFT$(Q$,N) Funktion: Es wird aus den ersten N linken Zeichen des Quellstrings Q$ ein Teilstring gebildet 7.6.5 MID$(QS,N,M) Funktion: Es wird aus dem Quellstring Q$ beginnend mit dem N-ten Zeichen ein Teilstring gebildet der M Zeichen umfaßt. 7.6.6 RIGHT$(Q$,N) Funktion: Es wird aus den N letzten Zeichen auf der rechten Seite des Quellstrings Q$ ein Teilstring gebildet. 7.6.7 INSTR({N,}Q$,S$) Funktion: Die INSTR-Funktion prüft den Quellstring Q$ ob (optional ab -123-
  • 124.
    Position N) vonlinks beginnend der Suchstring S$ enthalten ist. Ist dies der Fall, wird die Position des Suchstringes innerhalb Quellstrings zurückgeliefert. 7.6.8 ASC(x$) Funktion: Die ASC-Funktion gibt einen Fließkommawert zurück, der dem ASCII-Wert des ersten Buchstaben von x$ ent- spricht. Beispiel: x$ = "A" y = ASC(x$) y ist 65 (dezimal) 7.6.9 FTOI$ Funktion: Die FTOI$-Funktion wandelt eine Gleitkommazahl in einen Long-Integer-Wert und gibt diesen als Zeichenkette mit 3-Zeichen zurück. Die Reihenfolge ist LB S, MIDB,MSB (unterstes, mittleres, oberes Byte). Beispiel: 100 iel: a= (&H3132 * 256 + &H0033) 110 REM die Zahlen H31,H32 und H33 sind die 120 REM die ASCII-Darstellung der Zahlen 130 REM "1", "2" und "3" 140 PRINT a ' ergibt 3224115.000 150 PRINT FTOI$(a) ' ergibt "321" Diese Funktion ist vor allem dann von Interesse, wenn Daten, z.B. eines AD-Wandlers an einen zentralen Rechner weitergeleitet werden sollen. Dies soll ein weiteres Beispiel verdeutlichen: Beipiel: Es soll über LU(2) der Wert von ADC(1) als ASCII- String ausgegeben werden. Zur Kennzeichnung soll dieser String mit der ESC-Sequenz <ESC>"A" ange- führt werden. 100 adcw$ = FTOI$(ADC(1)) ' einlesen .. 110 PRINT ON(2) CHR$(&H1B);"A"; ' <ESC>"A" 120 PRINT ON(2) MID$(adcw$,1,2); -124-
  • 125.
    7.6.19 FTOIB Funktion: Diese Funktion wandelt eine Gleitkommazahl in einen 8- Bit-Wert, wobei anzugeben ist, welches Byte (LSB=0, MIDB=1 oder MSB=2) eines Long-Integer-Wertes gemeint ist. Beispiel: 100 a = (&H3132 * 256) + &H0033) 110 PRINT FTOIB(a,0) AS 2H ' = "33" 120 PRINT FTOIB(a,1) AS 2H ' = "32" 130 PRINT FTOIB)a.2) AS 2H ' = "31" -125-
  • 126.
    7.7 Sonstiges 7.7.1 USR Syntaxdiagramm: Aufruf: <zn> USR <n> (<parameter>{,<parameter>...}) Mit USR kann ein Assembler-Unterprogramm mit der angegebenen Nummer (n) aufgerufen werden. Dieses Assemblerunterprogramm muß bei der werksseitigen Installation (oder durch den Benutzer, falls das Entwicklungspaket zur Verfügung steht) in MSRBASIC eingebunden sein. Die Parameterübergabe erfolgt über den Stapelspeicher (Stack) wobei die Anzahl der übergebenen Parameter im A-Register (des Z80) stehen. Als Parameterausdrücke sind Variable und Ausdrücke zugelassen. Es werden für jeden Parameter zwei Datenworte übergeben: zuerst die Adresse der Parameter und danach einen Typ-Deskriptor, dabei ist zu beachten, daß die Daten vom Stapelspeicher in umgekehrter Reihenfolge geholt werden!. 6444444444444444;444444444444444447 5 MSB 5 LSB 5 :444444444444444>44444444444444444< 5 Typ-Deskriptor5 (reserviert) 5 :444444444444444=44444444444444444< 5 Adresse des Parameter 5 94444444444444444444444444444444448 Der Typ-Deskriptor enthält folgende Information: Bit 7: =1 Parameter ist ein Ausdruck =0 Parameter ist eine Variable wenn Bit 7 =0 (Variablenübergabe), dann bedeutet BIT 1 : =1 Feld(Element) =0 Skalare Variable Bit 0 =1 Parameter ist ein String =0 Parameter ist eine Gleitkommazahl Hinweise: Zur ordnungsgemäßen Rückkehr in den MSRBASIC-Interpreter muß der (Z80- ) RET-Befehl (0C9H) benutzt werden. Im Unterprogramm sollte der Anwender Anzahl und Typ der Parameter -126-
  • 127.
    überprüfen; insbesondere istzu prüfen, ob der Ergebnisparameter korrekt als Variable übergeben wurde (siehe Beispiel). Die Nummer des Assemblerunterprogrammes (UP) darf im Bereich 0..254 liegen. Die Verbindung zwischen Interpreter und Assem-bler- Unterprogramm (UP) erfolgt über eine konfigurations-abhängige Spungtabelle. Beispiel: 1000 USR 1(A(0),A$,10*Y) Fehler: 01 Falscher Parameter-Typ (z.B. String statt Zahl) 15 Unterprogramm mit der gewünschten Nummer nicht vorhanden 23 Parameter-Anzahl nicht korrekt -127-
  • 128.
    7.7.2 CALL Syntaxdiagramm: Aufruf:<zn> CA{LL}<adresse>(parmeter1,parameter2,parameter3) MitCALL können Unterprogramme an beliebigen Adressen <adresse> im 64K Adressraum der Z80-CPU aufgerufen werden. Als Parameter (parameter1..parameter3) können nur numerische Variable über-geben werden. Sie werden als Integer (Ganzzahl-)Wert in den CPU-Registern HL (paramter1), DE (parameter2) und BC (parameter3) an das Unterprogramm übergeben; Ergebnisse werden in den gleichen Register zurückerwartet und in den entsprechenden Variablen abgelegt. Werden gebrochene Werte übergeben, rundet der Interpreter den übergebenen Wert auf. Die Parameter <parameter1..parameter3> müssen angegeben werden, sind keine Parameter notwendig oder vorhanden kann ein belieb-iger Wert eingesetzt werden. Das aufgerufene Unterprogramm darf alle Register verändern außer dem Stackpointer, da mit dem Z80-Befehl RET (&HC9) in MSRBASIC zurückgekehrt wird. CALL bringt gegenüber der ähnlichen USR-Anweisung den Vorteil, daß das aufgerufene Unterprogramm nicht im Interpreter eingebunden sein muß, es kann (notfalls) mit POKE in einen freien RAM-Bereich geschrieben werden. Gegenüber der USR-Anweisung verlangt die CALL-Anweisung aber Programmierkenntnisse in Z80-Assembler! Beispiel: 100 REM *** Beispiel zu CALL *** 110 varhl = &H55, varde = 1234, varbc = 0 120 CALL &H9800(varhl,varde,varbc) 130 PRINT varhl AS 4H -128-
  • 129.
    Beispiel des Assembler-Unterprogrammes eswird ganz einfach varhl, varde und varbc addiert das könnte MSRBAS ja auch aber ... upx: add hl,de ; [&H19] Erst mal HL+DE add hl,bc ; [&H09] dann HL+BC ret ; [&HC9] fertig und nun dieses Programm in,s RAM mit POKE 10 addr = &H9000 20 POKE(addr,&H19) 30 POKE(addr+1,&H09) 40 POKE(addr+2,&HC9) -129-
  • 130.
    7.7.3 ONERROR Syntaxdiagramm: Aufruf: <zn> ONERROR <zn> In "unbeobachteten" Programmen nutzen Fehlermeldungen des Betriebssystemes während eines Programmablaufes sehr wenig, da keine Reaktion von einem Bediener zu erwarten ist. Zu diesem Zweck kann (am Programmbeginn) eine Verzweigung in ein beliebiges Unterprogramm veranlasst werden, welches immer dann aufgerufen wird, wenn ein Laufzeit-Fehler auftritt. Der ONERROR-Aufruf kann durch NEW oder ONERROR 0 abgeschaltet werden. Beispiel: 100 REM *** Initialisierung **** : 200 ONOERROR 220 210 GOTO 1000 220 REM *** ONERROR Unterprogramm" 230 var1=0, var2=0 : : und was halt sonst noch gemacht werden muß ; evtl. auch NOTALARM : 300 DOUT(7)=1 : 1000 REM *** Beginn des Hauptprogrammes : -130-
  • 131.
    8. Kommandos Unter Kommandossind Befehle an den Interpreter zu verstehen, die direkt (von der Konsole aus) eingegeben werden können. Sie dienen entweder Editierzwecken ( AUTO usw.) oder der Festlegung der Betriebsart (RUN usw.). 8.1 AUTO Syntaxdiagramm: Aufruf: AUTO {<szn> {,<schritt>}} <cr> Funktion: Das AUTO-Kommando veranlasst, daß in den EDITIER-Modus geschal-tet und dabei AUTOmatisch die Zeilennummer generiert wird. Als erste Zeilennummer wird die vorgegebene Startzeilennummer (szn) verwendet. Wird keine Zeilennummer angegeben wird mit der Zei-lennummer 10 begonnen. Alle weiteren Zeilennummern werden aus der momentanen Zeilennummer + der Schrittweite (schritt) be-rechnet. Wurde keine Schrittweite angegeben wird der Vorgabewert 10 verwendet. Eine Korrektur der automatisch erzeugten Zeilennummer ist möglich, hat dann jedoch auch Einfluß auf die weiteren zu generierenden Zeilennummern. Der AUTO-Modus wird durch <cr>in einer Leerzeile oder die Eingabe eines Kommandos verlassen. Fehler: Im FREEZE-MODUS ist AUTO nicht möglich, da keine Programmeingabe erlaubt ist. -131-
  • 132.
    8.2 CLS Syntaxdiagramm: Aufruf: {<zn>} CLS Funktion: Mit dem CLS-Kommando wird der Bildschirm gelöscht. Das CLS-Kommando kann auch als Anweisung innerhalb eines Programmes verwendet werden. Wird CLS im WINDOW-Betrieb verwendet, so wird nur das (obere) Ausgabefenster gelöscht. Da in dieser Betriebsart das Löschen des Bildschirmes nur emulieren werden kann, erfolgt dieses deutlich langsamer. -132-
  • 133.
    8.3 FREEZE Syntaxdiagramm: Aufruf: FRE{ZE} Funktion: Das FREEZE-Kommando gibt das Echtzeitbetriebssystem frei (Ausführung von ACTIVATE-TASK-Anweisungen etc. sind damit zulässig), was aus Sicherheitsgründen ein Verbot des gleichzeitigen Editierens von Programmzeilen mit sich bringt! FREEZE entfernt gelöschte Programmteile aus dem Speicher ("Entrümpelung"). - Schützt ein BASIC-Programm ("einfrieren") - Koppelt ein in EPROM gespeichertes BASIC-Programm an - Gibt das Echtzeitbetriebssystem frei -133-
  • 134.
    8.4 LIST Syntaxdiagramm: Aufruf: LIST {<begin>{,<ende>}} LIST {<dateiname>|ON(<kn>}{<begin{,<ende>}} Funktion: Ausgabe (Listen) eines MSRBASIC-Programmes auf der Bedienkon-sole, einem Ein-/Ausgabekanal (kn) (z.B. Drucker) oder einer Datei (dateiname), wobei eine Startzeile (begin) und Endzeile (ende) spezifiziert werden kann. Beim Aufruf "LIST ON..." geht der Interpreter in die Transparentbetriebsart (siehe LOAD-Kommando) um die Verbindung zu einem Hostrechner zu ermöglichen. (Virtuelles Terminal z. B. mit PC-TERM). Diese Betriebsart wird bei Eingabe von CNTRL-A verlassen und das Auslisten des Pro-grammes auf den ausgewählten Kanal vorgenommen. Beim Auslisten wird versucht, die Struktur des Anwenderpro-grammes möglichst deutlich wiederzugeben, daher werden Zeile welche die Befehle END, REM, RETURN, STOP, WAIT enthalten, um zwei Druckpositionen nach links gerückt.Das Innere von Laufanweisungen wird um 4 Leerzeichen nach rechts ver-schoben. Grundsätzlich wird die Normalform einer Anweisung ausgedruckt, auch wenn der Benutzer ursprünglich die Kurzform eingegeben hat. Beispiel: 1000 REM *** Demonstrationsprogramm 1010 DIM X (10,10) 1020 FOR I=1 TO 10 1030 FOR J=1 to 10 1040 PRINT "Element";I AS 2I;",",J AS 2I 1050 INPUT X(I,J) 1060 NEXT J 1070 NEXT I 1080 STOP -134-
  • 135.
    8.5 LOAD Syntaxdiagramm: Aufruf: LOAD {ON<n>|<dateiname>} Funktion: Es kann ein MSRBASIC-Programm entweder - von der Bedienkonsole (download) - von einem beliebigen Peripheriegerät auf Kanal <n> - von Diskette (via MSDOS) eingelesen und im Arbeitsspeicher abgelegt werden. Zu Beginn des Ladens erscheint auf der Bedienkonsole quasi als Triggersymbol ein Ausrufezeichen "!". Beim Einlesen jeder neuer Zeile wird ein Zähler inkrementiert (modulo-8-Zähler), der den Fortgang des Ladevorganges dokumentiert. Nach dem Einlesen der letzten Programmzeile bleibt die Anzeige stehen, bis, nach dem vollständigen Übersetzen des Programm-Klartextes in den MSRBASIC-internen Zwischencode, die READY-Meldung kommt. Falls der "ON(...)"-Zweig aktiviert ist, geht der Interpreter zunächst in die Transparentbetriebsart, d.h. er stellt softwaremäßig die Verbindung zwischen der Bedienkonsole und dem angesprochenen Peripheriegerät her. Ist dies ein (Host-)Rechner, kann er in dieser Phase des LOAD-Kommandos über das Terminal des MSRBASIC-Rechners nahezu beliebig bedient werden (virtuelles Terminal). Die Eingabe von CNTRL-A veranlasst MSRBASIC, an den Hostrechner ein RETURN-Zeichen (CR) zu schicken und damit das Zusenden eines Programmes auszulösen. MSRBASIC geht unmittelbar danach in die Ladebetriebsart über. Das Laden wird abgebrochen, wenn ein CNTRL-Z-Zeichen (1AH) eintrifft oder wenn mehr als 5 Sekunden kein Zeichen mehr kommt (Time-out). Das Laden kann von der Konsole her mit CNTRL-C abgebrochen werden, ohne, daß bereits eingelesene Programmzeilen verloren gehen. Hinweise: Unter MSDOS ist die Betriebsart als virtuelles Terminal mit der COMn- Schnittstelle möglich, diese bedarf aber spezieller Inter-rupt- Treiber, da der "eingebaute" MSDOS-Treiber nur bei Über- tragungsgeschwindigkeiten bis 2400 Baud geeignet ist. Ein ent- sprechendes Hilfsprogramm (mit integriertem Editor) steht auf Anfrage zur Verfügung. (MSRSHELL). Werden beim Übersetzen in den Zwischencode Syntaxfehler erkannt, so wird die fehlerhafte Zeile gemeldet. Alle bereits eingegliederten Zeilen bleiben erhalten, alle folgenden Zeilen gehen verloren. -135-
  • 136.
    8.6 NEW Aufruf: NEW Funktion: Alle TASKs stillegen, Programm löschen, Daten löschen und NOFREEZE-Betriebsart einstellen 8.7 NOFREEZE Aufruf: NOF Funktion: Alle TASKs stillegen, Programme in EPROM abkoppeln und Programmschutz aufheben. In diesem Modus kann ein Programm, welches im RAM- speicher abgelegt ist, wieder editiert werden. 8.8 MFREE Aufruf: MFREE Funktion: a) in NOFREEZE-Betriebsart Speicher entrümpeln Datenspeicher löschen Angabe des freien Speichers b) in FREEZE-Betriebsart Angabe des freien Datenspeichers 8.9 RUN Aufruf: RUN {<startzeile>} Funktion: Starten eines MSRBASIC-Programmes bei der ersten Zeile oder bei der im Kommando angegebenen Zeile (startzeile). Die interne Symboltabelle wird in keinem Fall gelöscht, es bleiben also alle Werte aus "vorangegangenen Läufen" vorhanden! 8.10 SAVE Aufruf: SAVE {<begin>{,<ende>}} SAVE {<dateiname>|ON<kn>}{<begin>{,<ende}} Funktion: Ausgabe des im Speicher befindlichen MSRBASIC-Programmes auf Bedienkonsole oder Peripheriegerät, ähnlich wie LIST-Kommando. Im -136-
  • 137.
    Gegensatz zu diesemwird jedoch das Listing nicht struk-turiert und die abgekürzten Befehle verwendet. Beispiel: 1000 R *** Demonstrationsprogramm *** 1010 DIM X(10,10) 1020 F I=1 TO 10 1030 F J=1 TO 10 1040 P "Element"; I AS 2I;",";J AS 2I 1050 I X (I, J) 1060 N J 1070 N I 1080 STOP 8.11 SYSTEM Aufruf: SYS{TEM} Funktion: Verlassen des MSRBASIC-Interpreters. Hinweis: Beim Verlassen des MSRBASIC-Interpreters wird das interne Echtzeitbetriebssystem abgeschaltet und ein evtl. bereits vorhandenes Interruptsystem restauriert. Ist MSRBASIC als stand-alone-System installiert wird (konfigurationsabhängig) ein Kaltstart, ein Warmstart oder "garnichts" ausgeführt. In einigen Umgebungen wird auf den ELZET 80-typischen SYstemMONitor (SYMON) ausgesprungen (der sich dann meldet!). 8.12 VCL Aufruf: VCL Funktion: Löschen aller Anwendervariablen und -Zeitgeber. Das VCL-Kommando ist aus Sicherheitsgründen nur in der NONFEEZE- Betriebsart zulässig (kein Echtzeitbetrieb). -137-
  • 138.
    9. Programmiertips MSRBASIC istnicht nur ein leistungsfähiges Werkzeug für die Lösung kleinerer MSR-Aufgaben, es eignet sich auch für die komplette Automatisierung von Industrieanlagen mit Ein- und Mehrrechner- Systemen. Um derart komplexe Anwendungen erfolgreich zu meistern, empfiehlt es sich bei der Systemanalyse, Programmkonzeption und Implementierung einige "goldene Regeln" zu beherzigen, die im folgenden als "Programmiertips" formuliert sind und die Erfahr-ung aus zahlreichen Anwendungen wiederspiegelt. 9.1 Systemanalyse und Programm-Konzeption 9.1.1 Analyse der erforderlichen Parallität Auch wenn es altväterlich klingt: Gundvoraussetzung für ein tragfähiges Echtzeit-Anwenderkonzept ist eine klare Spezifikation und ein darauf abgestimmtes Programmkonzept. Folgende Punkte sollten bei der Programmkonzeption der Reihe nach geklärt werden: - In welchen funktionell entkoppelten Teilbereichen kann die zu automatisierende Anlage "zerlegt" werden ? - Welche Funktionen sollen bzw. müssen parallel bearbeitet werden ? - Welche Funktionen sind quasikontinuierlich oder ablauforientiert ? Im Prinzip wird jeder parallel ablaufenden Funktion ein MSRBASIC- Programm vom Typ TASK oder SEQuenz zugeordnet. Hierbei leistet eine Darstellung der Aufgaben in Form eines Petri- Netzes wertvolle Hilfe, da es den Grad an jeweils notwendiger Parallelität strukturell ausweist. Es empfiehlt sich jedoch im Sinne einer möglichst guten Übersichtlichkeit, die Anzahl an parallelen Programmen nicht über das unbedingt notwendige Maß hinauswachsen zu lassen. Hierzu werden Ablaufaktionen, die zwar parallel laufen können, aber ohne Verzicht auf die Güte des technischen Prozesses auch nacheinander ablaufen können, als Teilaktionen einer SEQuenz formuliert. Beispiel: Wegeschaltung in Materialflußsystemen Bei Materialflußsystemen (z.B. Tanklager) tritt häufig die Aufgabe auf, einen neuen Weg zu schalten. Im konkreten Fall sollen die Ventile V2, V3, V8 geöffnet und die Ventile V1, V5 geschlos-sen werden, bevor über ein Ventil v10 der Fluß freigegeben wird. Bei jedem Ventil muß die Endposition überwacht werden, d.h. jeder Vorgang besteht aus den Aktionen: - Ventil öffen (bzw. schließen) - maximal n Sekunden warten bis Endposition erreicht, sonst Fehlermeldung -138-
  • 139.
    Die einzelnen Öffnungs-/ Schließungsvorgänge können parallel ablaufen. Dennoch ist es nicht sinnvoll, für jeden Vorgang eine SEQuenz zu 'verbrauchen'; vielmehr können alle Aktionen mit einer SEQuenz nach folgendem Schema durchgeführt werden: - Schliesse bzw. öffne alle fraglichen Ventile (" DOUT(V1)=0,...DOUT(V2)=1") - Warte max. n Sekunden auf korrekte Positionsrückmeldung ("WAIT MAX n FOR NOT(DIN(V1)+DIN(V5)*DIN(V2)..ELSE") - Die Fehlerbehandlung (nach ELSE) analysiert die Rückmeldesignale und liefert in einer Variablen (Err$) die Fehlercodes: Err$ = "Fehler in" IF DIN(V1) THEN Err$=Err$+" V1" IF DIN(V5) THEN Err$=Err$+" V5" IF DIN(V2)=0 THEN Err$=Err$+" V2" PRINT Err$ Regel: soviel Parallelität wie nötig - so wenig wie möglich! 9.1.2 Restriktive Auslastung Als weitere Grundregel bei der Konstruktion von Echtzeitsystemen sollte man bei der Auslegung der Abfragezeiten von Tastern eher restriktiv vorgehen, um der Gefahr einer auch nur partiellen Überlastung des Rechners vorzubeugen. -139-
  • 140.
    9.2 Programm-Implementierung 9.2.1 AnlagenorientierteModularisierung In der Regel läßt sich eine größere Anlage in definierte Teilbereiche untergliedern. Diese Struktur ist beim Programmentwurf grundsätzlich dadurch zu berücksichtigen, daß - alle zum Anlagenabschnitt gehörenden Programmteile (TASKs und SEQuenzen) möglichst einen zusammenhängenden Abschnitt im Gesamtprogramm belegen ("Kompaktheit") - die Abhängigkeit der abschnittspezifischen Programmteile von den anderen Abschnitten minimiert wird. Diesen Zielen kann in MSRBASIC am einfachsten durch entsprechende Zeilennummern-Vergabe Rechnung getragen werden 2000 .. 2999 Anlagenabschnitt 1 3000 .. 3999 Anlagenabschnitt 2 etc -140-
  • 141.
    9.3 Übersichtlichkeit derProgramme Die nachfolgend genannten Mittel tragen unmittelbar zur Übersichtlichkeit von Programmen bei und damit zur leichteren Wartung. - Variablennamen nicht in Großschreibung verwenden Vergleich: IF HAND + NOTAUS THEN DOUT(HAUPT)=0 IF Hand + Notaus THEN DOUT(Haupt)=0 - Sprungziel von GOTO, GOSUB, THEN und ELSE als REM markieren. Dies bringt eine erhöhte Sicherheit gegen Programmierfehler und steigert die Übersichtlichkeit Beispiel: 980 GOSUB 1280 : : 1280 REM *** Pumpe einschalten *** : - Symbolische Namen verwenden. Die Namen sollten (innerhalb der 6 zugelassenen Zeichen) jedoch mnemonische Züge tragen und keine nichtssagende Abkürzung. Dies gilt für Variable: WAIT FOR DIN(123)*DIN(121)+DIN(125) oder WAIT FOR DIN(Vent1)*DIN(Vent2)+DIN(Stop) für logische Einheiten: IF BIT(FOpen,STATUS(ErrLU))=0 THEN ... für Zeitgeber IF TDOWN(T_regl)>0 THEN RETURN TDOWN(T_regl) = T_regl für TASKs und SEQuenzen: IF DIN(3)=0 THEN SUSPEND TASK 2 oder IF DIN(AStop)=0 THEN SUSPEND TASK Anzeig - Bildschirm-Steuerzeichen werden am besten als String- Block definiert. Das läßt leichter erkennen was gemeint ist und vereinfacht die Anpassung an eine andere Konsole. -141-
  • 142.
    esc$ =CHR$(27) cr$ =CHR$(13) usw. - Bei der Parameterübergabe an Unterprogramme MAT- Anweisungen benutzen: MAT <arbeitsmatrix>=<hauptmatrix> GOSUB ... MAT <hauptmatrix> =<arbeitsmatrix> -142-
  • 143.
    10. Hardware-Anpassung und EPROM-startende Systeme 10.1 Allgemeines MSRBASIC ist keines der "üblichen" Programme die zum Ablauf ein bestimmtes Betriebssystem benötigt, vielmehr sind alle not-wendigen Ein-/Ausgabefunktionen bereits werksseitig eingebunden. ELZET 80 Mikrocomputer liefert MSRBASIC für alle Prozessor-Karten die mit einer Z80 (kompatiblen) CPU ausgerüstet sind. Dazu gehören: Die Standard-CPU's für ECB-Systeme CPU-S CPU85SC CPUZ280 Die Einplatinencomputer der MOPS-Serie MOPS 1Ax, 2AX und 5AX MOPS 0Dx Den Tragschinencomputer TSM-CPU 10.2 Hardware-Anpassung Die zu einer bestimmten Prozessor-Karte gelieferten MSRBASIC- Interpreter (im EPROM) sind an die Hardware der entsprechenden Karte angepasst und können nicht auf einer anderen Karte eingesetzt werden. Eine Reihe zusätzlicher AD-,DA, oder Digital-Ein-/Ausgänge können zusätzlich bei den EPROM's für ECB-Systeme durch einfaches ändern (patchen) im EPROM eingebunden werden. Nähers ist aus den Programm- Ausdrucken (Listings) des Hardware-abhängigen Programmsegmentes im Anhang zu ersehen. Müssen besondere Ein-Ausgabetreiber eingebunden werden, so kann dies (gegen Unkostembeitrag) von ELZET 80 Mikrocomputer über-nommen werden oder es kann der Quelltext des Hardwareabhängigen Programm-segmentes und die REL-Datei des Hauptprogrammes (Hardware-unabhängig) käuflich erworben werden. Zur Bearbeitung die-ser Dateien ist neben der Kenntnis in Z80-Assembler-program-mierung auch die Verfügbarkeit eines (Z80-)CP/M-kompatiblen Betriebs-Systemes und eines Z80-Assembler und Linkers notwendig. -143-
  • 144.
    10.2.1 Portadressen Zur Anspracheder analogen bzw. digitalen E/A-Karten, die direkt von MSRBASIC aus angesprochen werden können, müßen die Port-adressen auf den E/A-Karten wie folgt eingestellt werden: Digitale Ein-/Ausgabe: Port Systemkarten DIN(0)....DIN(15) 80H 24V=, 24VB, REL16R, OP32IN DIN(16)...DIN(31) 82H 24V=, 24VB, REL16R DIN(32)...DIN(47) 84H 24V=, 24VB, REL16R, OP32IN DIN(48)...DIN(63) 86H 24V=, 24VB, REL16R DIN(64)...DIN(79) 88H 24V=, 24VB, REL16R, OP32IN DIN(80)...DIN(95) 8AH 24V=, 24VB, REL16R DIN(96)...DIN(111) 8CH 24V=, 24VB, REL16R, OP32IN DIN(112)..DIN(127) 8EH 24V=, 24VB, REL16R AD-Karten (16AD12b/c) ADC(0)....ADC(15) B0H ADC(16)...ADC(31) B4H ADC(32)...ADC(47) B8H ADC(48)...ADC(63) BCH DA-Karten (4DA12) DAC(0)....DAC(15) C0H DAC(16)...DAC(31) C4H DAC(32)...DAC(47) C8H DAC(48)...DAC(63) C4H Informationen wie das Einstellen der Portadressen zu bewerk-stelligen ist, sind in den Unterlagen zu den jeweiligen Systemkarten zu finden. Die Zusatzmodule der TSM-Serie müßen nicht auf spezielle Adressen gelegt werden, hier genügt eine beliebige Durch-nummerierung der Aufsteckmodule zur Identifizierung des Modules, MSRBASIC nummeriert die Ein- bzw. Ausgänge automatisch in auf-steigender Ordnung nach der eingestellten ID-Nummer des Modules. Die digitalen Ein-/Ausgänge auf der TSM-CPU werden dabei immer mit mit der niedrigsten Nummer belegt. -144-
  • 145.
    10.3 EPROM-startende Systeme FürEPROM-startende Systeme ist es notwendig, daß der MSRBASIC- Interpreter und das (ablauffähige) BASIC-Programm in EPROM(s) gebrannt sind. Prinzipiell genügt es auch, wenn der Interpreter in EPROM gebrannt ist, daß der Programmspeicher, durch z.B. Batterie-pufferung, vor Datenverlust geschützt ist. Nach einem Stromausfall oder CPU-RESET (ob gewollt oder ungewollt) prüft der MSRBASIC-Interpreter immer nach ob ein funktionsfähiges Programm vorhanden ist, ist dies der Fall, so wird das gefundene Programm ausgeführt! In manchen Systemen ist jedoch eine Batteriepufferung nicht möglich oder nicht erwünscht. In diesem Falle muß das ablauffähige Programm in ein EPROM gebrannt werden. Die entsprechenden Daten liefert das Kommando PROMIT -145-
  • 146.
    10.3.1 PROMIT Aufruf: PROMIT {<addr>} Funktion: Um ein MSRBASIC-Programm in EPROM ablegen zu können, muß es bereits vorinterpretiert sein. Darunter ist zu verstehen, daß der Interpreter alle Funktionsnamen usw. in (interpreterinterne, sog.) TOKEN umgewandelt hat und die Befehlszeilen untereinander "verzeigert" sind, damit der Interpreter sich "schneller zurecht findet". In der Praxis bedeutet dies, das zu "EPROMende" getestete Programm wird geladen und kann nun mit dem Kommando PROMIT im INTEL-HEX auf Diskette abgespeichert werden. ( mit Hilfe von MSRSHELL unter MSDOS). Wird das Kommando PROMIT ohne <addr> aufgerufen, so wird das eigentliche Programm direkt hinter den MSRBASIC-Interpreter angehängt und der MSRBASIC-Interpeter incl. dem Ablaufprogramm ausgegeben. Dies setzt voraus, daß das Programm noch in die verbleibenden etwa 5K-Byte des 32K-EPROMs paßt. Ist das nicht der Fall endet PROMIT in einer Fehlermeldung. Dann muß man bei Einsatz der CPU/S im Speicherbereich von oben (FFFFH) kommend den nötigen Bereich für das Anwenderprogramm in Eprom reservieren, was nur durch den Ensatz einer externen RAM/EPROM-Karte möglich ist. MSRBASIC geht davon aus, ab 8000H RAM vorzufinden. RAM- Ende wird durch eine Adresse auf Speicherstelle 0007/0008H im MSRBASIC-EPROM markiert, EPROM-Start durch einen Adreßeintrag auf 0005/0006H. Wird PROMIT mit Adressangabe <addr> aufgerufen, so wird nur das Ablaufprogramm ausgegeben, welches dann in ein EPROM mit der angegebenen Startadresse "gebrannt" werden kann. In diesem Fall ist jedoch unbedingt zu beachten, daß im EPROM des MSRBASIC-Interpreters die Adresse 0005/0006H mit der angegebenen Startadresse verändert wird. Die Adresse ist im Z80-Format einzutragen d.H. das untere Adressbyte zuerst, dann das obere Adressbyte! Außerdem muß das RAM-Ende auf gleiche Weise in Adresse 0007/0008H eingetragen werden. Beispiel: PROMIT &HC000 (EPROM-Start C000H) Im EPROM (Kopie!) ist dann der Inhalt von Adresse 0005H in 00H (unteres Byte der Adresse) und der Inhalt von Adresse 0006H in C0H -146-
  • 147.
    (oberes Adreßbyte) zuändern. Für das passende RAM-Ende bei BFFFH muß Adresse 7 auf FF bleiben und Adresse 8 auf BF geändert werden. Beide Adreßreferenzen sind im Auslieferungszustand FFFF, so daß das EPROM nachgebrannt werden kann. Achtung: Wird PROMIT ohne Adressangaben aufgerufen, wird der Inhalt der Adresse 0005H automatisch an den Programmanfang angepaßt, d.h. das 32K-EPROM mit BASIC und Anwenderprogramm kann direkt aus dem Hexfile erzeugt werden. Für die HEX-Binärwandlung ist von ELZET ein DOS-Programm HEXBIN erhältlich. Hinweis: In der Praxis sind Programme bei den CPU-Karten der ECB-Serie ohne Probleme in EPROMs zu transferieren, wenn das Ablaufprogramm noch in das Interpreter-EPROM passt. Bei "Platzmangel" hilft es, wenn im ausgetesteten Programm vor PROMIT alle Kommentare entfernt (oder gekürzt) werden, u.U. können auch die Variablennamen noch gekürzt werden. Sollte dies alles nicht helfen, so muß (bei ECB-Systemen) eine zusätzliche Speicherkarte (64KRE) benutzt werden. Bei allen MOPS-Systemen der Serie A (MOPS 1AX,2AX und 5AX) muß ein geändertes Interpreter-EPROM angefordert werden, in welchem der RAM- Bereich auf den oberen 2K-Sockel beschränkt wird. Bei den MOPS-Systemen der D-Serie muß ebenfalls ein angepasstes EPROM angefordert werden. In diesem Falle wird das "untere" EPROM um 16K erweitert (0000H...BFFFH). Als EPROM muß dann ein Typ xx512 (64K) eingesetzt werden, der RAM-Bereich ist dann auf 16K im Bereich von C000H...bis FFFFH reduziert. Es wird jedoch nach wie vor ein 32K-RAM verwendet. Bei MOPS-Systemen der A-Serie kann ein (kleineres) Programm natürlich auch in den oberen (2K-)Sockel transferiert werden. In diesem Fall ist kein geändertes EPROM notwendig, natürlich muß auch hier die Adresse 0005H angepasst werden! 10.4.2 PROMIT bei Z280 Systemen Der Z280-Prozessor verfügt über einen System- und einen USER-Bereich, der jeweils 64KByte hat. Im Systembereich, dr für den Anwender nicht zugänglich ist , befindet das Betriebssystem von MSRBASIC wärend im USER-Bereich ein Teil des Interpreters und das Benutzerprogramm untergebracht ist. Im EPROM müssen natür-lich beide Speicherinhalte untergebracht werden, was die Suche nach dem Anfang des Interpreters (zum patchen der Adressen) naturgemäß etwas schwieriger gestaltet, eine feste Startadresse kann nicht angegeben werden, da es, bedingt durch Korrekturen oder dem einbringen von benutzerdefiniereten Änderungen (Treiber) immer wieder Verschiebungen geben kann. Grundsätzlich beginnt der Interpreter aber immer auf einer 4kByte- -147-
  • 148.
    Grenze (1000H, 2000Husw.) und zwischen Betriebsystem und Interpreter ist üblicherweise eine Lücke, welche mit 0FFH gefüllt ist. Findet man also im EPROM-DUMP folgende Zahlenfolge: 05FE0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 05FF0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 06000: C3 .. .. .. so beginnt mit ziemlicher Sicherheit der Interpreter bei Adresse 6000H. Diese Adresse sollte man sich merken! Alle absoluten Adressen die bei der Beschreibung von PROMIT angegeben sind, gelten relativ zu dem notierten Interpreter-Anfang. Ab der Startadresse des Interpreters werden 28kByte für den Interpreter und 36kByte RAM eingeblendet. Für zu 'promende' Programme ist der Bereich zwischen Interpreter-Ende und der Interpreter- Start+7000H nutzbar. Das Interpreter-Ende läßt sich an der Bytefolge 055H, 0AAH erkennen! Der nutzbare EPROM-Bereich ist leider nur recht klein. Es ist jedoch möglich eine EPROM-Version des MSRBASIC-Interpreters zu bekommen, in welcher der RAM-Bereich auf 16kByte zugunsten eines freien EPROM- Bereiches von 16kByte beschränkt ist. -148-
  • 149.
    10.4 Programme inEEPROM Programme können bei MOPS-Systemen der A-Serie auch in EEPROMs abgelegt werden. Der Programm-Transfer geschieht hier mit dem Befehl: EEPROMIT. Als "Ziel" ist hier ein EEPROM (Typ 2864) in Sockel 2 verwendet werden. Anstelle des EEPROMS sind auch NV-RAMs verwendbar. Im EEPROM gespeicherte Programme werden bei jedem Neustart ausgeführt. Sie können (wie alle Programme) mit CNTRL-C abgebrochen werden. Soll das Programm im EEPROM geloescht werden, ist folgende Prozedur auszuführen: a) NEW EEPROMIT oder, nach Neustart b) NOF EEPROMIT Bitte beachten Sie, EEPROMs sind nur mit beschränkter Häufigkeit löschbar! -149-
  • 150.
    10.5 Entwicklungshilfen Als Entwicklungshilfebietet ELZET 80 Mikrocomputer das Programm MSRSHELL mit dessen Hilfe MSRBASIC-Programme über eine RS232- Verbindung zwischen jedem beliebigen MSRBASIC-System und einem PC entwickelt werden kann. MSRSHELL übernimmt dabei die Funktion eines Terminal-Emulators. Es können mit seiner Hilfe aber auch Programme auf dem PC gespeichert oder vom PC geladen werden. Darüberhinaus ist in PC-Shell ein wordstar(R)-ähnliches Editorprogramm eingebunden, welches das Schreiben von Programmen sicherlich stark vereinfacht. Für PROMIT-Dateien im INTEL-HEX-Format steht das Hilfsprogramm DEHEX zu Verfügung, mit dessen Hilfe das INTEL-HEX-Format in "Normal-Daten" rückgewandelt werden können. Alle Hardware-abhängigen Treiber sind als Z80-Assembler Quelldateien, der (Hardware-unabhängige) Interpreter-Kern als REL-Datei (Mikrosoft(R) CP/M-Format) verfügbar. Diese Dateien enthalten alle notwendigen Informationen und Daten um eine beliebige (Z80-kompatible) Hardware anzupassen. Der Assembler-Code wurde für den Z80-Macroassembler SLR180(R) geschrieben der ebenfalls von ELZET 80 Mikrocomputer vertrieben wird. Der Microsoft Assembler M80 (R) eignet sich (mit einigen Einschränkungen betr. der Geschwindigkeit und Code-unverträg-lichkeit betr. einiger interner Abfragen (.PRINTX und .ACCEPT - diese müssen 'per Hand' aufgelöst werden - sowie dem bei SLR180 nicht notwendigen ".Z80"-Befehl) ebenfalls. Als Linker eignet sich LINK(R), L80(R) und SLRLNK(R) Ist kein CP/M-System vorhanden, so kann ein (Z80-)CP/M-Emulator auf dem PC verwendet werden. (IPC-Z80 mit 8MHz von ELZET 80) -150-
  • 151.
    11. Fehlermeldungen 00 interner Konsistenzfehler beim Listen 01 inkompatibler Datentyp z.B.: x=a$ 02 unerlaubte Kontrollvariable in PRINT- oder INPUT 03 nach END existiert noch eine Programmzeile 04 fehlerhafte Zeilennummer in GOTO etc. 05 gewünschte Zeilennummer existiert nicht 06 ein unerwartetes Zeichen verursacht den Fehler 07 eine Anweisung wurde nicht beendet 08 eine Anweisung wurde fehlerhaft formuliert 09 Fehler beim Wandeln einer numerischen Konstanten 10 eine Funktion wurde falsch benutzt (Seiten vertauscht o.Ä) 11 Feldzugriff stimmt nicht mit Felddeklaration überein (Dimensionalität bzw Datentyp) 12 Zugriff auf ein Datenfeld vor seiner Definition 13 Fehler bei der Bestimmung einer Zahl (zu groß) 14 unerlaubte Relation in einer IF/WAIT-Anweisung 15 Nummer eines Assembler-UP's nicht gefunden FOR-NEXT-Fehler 16 fehlendes "=" in einer FOR-Anweisung 17 felendes TO oder STEP 18 Ineinanderschachteln von mehr als 10 Laufvariablen 19 NEXT wurde vor FOR ausgeführt 20 Laufvariable in FOR und NEXT stimmen nicht überein oder sind bereits vorhanden (Multitasking) 21 Laufvariable ist ein Vektor oder ein String 22 das gewünschte Vektorelement existiert nicht 23 Anzahl der übergebenen Parameter stimmt nicht 24 Dimensionen zweier Vektoren stimmen nicht überein 25 Fehler (hardware) im Ein-/Ausgabe-Verkehr 26 TASK bzw SEQuenz sollte (de)aktiviert werden, bevor sie eingetragen war 27 WAIT als direkte Anweisung benutzt (nur TASK und SEQ) 28 Zeitüberschreitung beim Warten auf das Eintreffen einer Verriegelungsbedingung 29 Fehler bei der Bestimmung einer logischen Kanaladresse Matrix-Vektor-Fehler 30 unerlaubter Operand in MAT-Anweisung 31 falsche Reihenfolge von MAT-Operatoren 32 inkonsistene Dimension auf der rechten Seite 33 Zielfeld zu klein dimensioniert 34 Vektor zu groß (>126) für MAT-Operation 35 Zielfeld auch auf der rechten Seite der MAT-Anweisung 36 zuwenig Speicher für Ablage der Zwischenergebnisse 37 interner Konsistentfehler (Entschuldigung!) 38 WAIT in GOSUB-Unterprogrammen nicht erlaubt 39 (reserviert) 40 Interpreter nicht im Echtzeit-Modus (FREEZE-Befehl eingeben) 41 INPUT-Anweisung wurde zweimal aufgesetzt (Multitasking) 42 Timeout (Zeitüberschreitung) bei Ausgabe auf seriellem Knl aa -151-
  • 152.
    78 interner Fehler -152-
  • 153.
    12. Stichwortverzeichnis Ablaufsteuerungen .. . . . . . . . . . . . . . . . . . . . . . -24- ABS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- ACN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- ACTIVATE . . . . . . . . . . . . . . . . . . . . . . . . . . . -35- ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -46- Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . -17- AS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -97- ASC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -124- ASN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- ATN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- AUTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . -131- BGMEMCLEAR . . . . . . . . . . . . . . . . . . . . . . . . . . -76- BGMEMDIM . . . . . . . . . . . . . . . . . . . . . . . . . . . -67- BGMEMFRE . . . . . . . . . . . . . . . . . . . . . . . . . . . -77- BGMEMGETQ . . . . . . . . . . . . . . . . . . . . . . . . . . . -71- BGMEMGETR . . . . . . . . . . . . . . . . . . . . . . . . . . . -68- BGMEMPOP . . . . . . . . . . . . . . . . . . . . . . . . . . . -73- BGMEMPUSH . . . . . . . . . . . . . . . . . . . . . . . . . . . -72- BGMEMPUTQ . . . . . . . . . . . . . . . . . . . . . . . . . . . -70- BGMEMPUTR . . . . . . . . . . . . . . . . . . . . . . . . . . . -67- BGMEMSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . -74- BIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -43- BITBUS-Anschluß . . . . . . . . . . . . . . . . . . . . . . . . -80- BITRB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -83- BITRH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -84- BITRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -84- BITRW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -83- BITWB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -84- BITWH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -85- BITWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -85- BITWW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -85- BITZFLAG . . . . . . . . . . . . . . . . . . . . . . . . . . . -83- Boolsche Ausdrücke . . . . . . . . . . . . . . . . . . . . . . -44- Buchstaben . . . . . . . . . . . . . . . . . . . . . . . . . . -17- CALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . -128- CHR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- CLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -132- CNT . . . . . . . . . . . . . . . . . . . . . . . . . . . -50-, -56- COMMAND . . . . . . . . . . . . . . . . . . . . . . . . . . . -101- COS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- Cursor-Positionierung . . . . . . . . . . . . . . . . . . . . . -97- DAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -51- DATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -61- Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . -17- Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . -17- DEFINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -31- DIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -112- DIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -47- DOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -53- DOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -61- Echtzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . -24- Editor . . . . . . . . . . . . . . . . . . . . . . . . . -17-, -21- EEPROMIT . . . . . . . . . . . . . . . . . . . . . . . . . . -149- Einfüge-Modus . . . . . . . . . . . . . . . . . . . . . . . . . -21- ELSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -108- END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -111- Entwicklungshilfen . . . . . . . . . . . . . . . . . . . . . -150- EOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -100- -153-
  • 154.
    EPROM-startend . . . . . . . . . . . . . . . . . . . . . . . -145- EXP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- Fahrtregler . . . . . . . . . . . . . . . . . . . . . . . . . . -87- Fehlermeldungen . . . . . . . . . . . . . . . . . . . . . . . -151- Felder . . . . . . . . . . . . . . . . . . . . . . . . . . . . -18- Fenstertechnik . . . . . . . . . . . . . . . . . . . . . . . . -92- FOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -102- Formatierung . . . . . . . . . . . . . . . . . . . . . . . . . -97- FRDEF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -88- FREEZE . . . . . . . . . . . . . . . . . . . . . . . . . . . -133- FREEZE-Betrieb . . . . . . . . . . . . . . . . . . . . . . . . -23- FRERROR . . . . . . . . . . . . . . . . . . . . . . . . . . . . -90- FRLDFAHRT . . . . . . . . . . . . . . . . . . . . . . . . . . . -89- FRLSFAHRT . . . . . . . . . . . . . . . . . . . . . . . . . . . -89- FRSETKI(ki . . . . . . . . . . . . . . . . . . . . . . . . . . -89- FRSETKP . . . . . . . . . . . . . . . . . . . . . . . . . . . . -88- FRSETP . . . . . . . . . . . . . . . . . . . . . . . . . . . . -88- FRSTAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . -89- FTOI$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . -124- FTOIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . -125- Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . -18- GET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -49- GOSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . -105- GOTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . -107- Hardware-Anpassung . . . . . . . . . . . . . . . . . . . . . -143- Hintergrundspeicher . . . . . . . . . . . . . . . . . . . . . . -66- IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -108- INCHAR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . -100- INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -95- INSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- INT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- Kalender . . . . . . . . . . . . . . . . . . . . . . . . . . . -60- Kaltstart . . . . . . . . . . . . . . . . . . . . . . . . . . . -20- Kanalnummern . . . . . . . . . . . . . . . . . . . . . . . . . -18- Kommando . . . . . . . . . . . . . . . . . . . . . . . . . . -131- Kommandos . . . . . . . . . . . . . . . . . . . . . . . . . . . -18- Kommentare . . . . . . . . . . . . . . . . . . . . . . -18-, -120- LEFT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- LEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- LET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -114- Linkadapter . . . . . . . . . . . . . . . . . . . . . . . . . . -79- LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . -134- LN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- LOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . -135- LOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- Logikfunktionen . . . . . . . . . . . . . . . . . . . . . . . . -43- LUAVAIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . -79- LUMODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -78- LUOPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . -78- MADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -57- MAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -116- MDIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -57- MDOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -57- MFREE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -136- MID$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- MSRTIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . -60- MSTIMDIF . . . . . . . . . . . . . . . . . . . . . . . . . . . -60- NADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -58- NCNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -58- NDAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -58- NDIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -58- -154-
  • 155.
    NDOUT . .. . . . . . . . . . . . . . . . . . . . . . . . . . . -58- NEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -136- NEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . -104- NOFREEZE . . . . . . . . . . . . . . . . . . . . . . . . . . -136- NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -43- NOTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -40- NOTRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -39- NWIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -93- ON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -97- ONERROR . . . . . . . . . . . . . . . . . . . . . . . . . . . -130- Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . -19- PEEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -65- POKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -119- Portadressen . . . . . . . . . . . . . . . . . . . . . . . . -144- POS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -87- POSSRN . . . . . . . . . . . . . . . . . . . . . . . . . . . . -88- POSTYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -87- PRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -97- Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . -19- Programmiertips . . . . . . . . . . . . . . . . . . . . . . . -138- PROMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . -146- PUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -55- Reglerfunktionen . . . . . . . . . . . . . . . . . . . . . . . -62- REM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -120- RETURN . . . . . . . . . . . . . . . . . . . . . . . . . . . -106- RIGHT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- RUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -136- SAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . -136- Schnittstellenfunktionen . . . . . . . . . . . . . . . . . . -100- Sedezimal-Wert . . . . . . . . . . . . . . . . . . . . . . . . -21- SEQLIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . -42- SEQuenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . -24- SIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- Speicherfunktionen . . . . . . . . . . . . . . . . . . . . . . -65- SQR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- START . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -33- Starten . . . . . . . . . . . . . . . . . . . . . . . . . . . . -19- STATUS . . . . . . . . . . . . . . . . . . . . . . . . . . . -101- Steuerzeichen . . . . . . . . . . . . . . . . . . . . . . . . . -22- STOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . -110- Stringfunktionen . . . . . . . . . . . . . . . . . . . . . . -123- SUSPEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . -34- Syntaxfehler . . . . . . . . . . . . . . . . . . . . . . . . . -22- SYSTEM . . . . . . . . . . . . . . . . . . . . . . . . . . . -137- Systemanalyse . . . . . . . . . . . . . . . . . . . . . . . . -138- Tabellierung . . . . . . . . . . . . . . . . . . . . . . . . . -97- TAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -122- TASK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -24- TDOWN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -59- THEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . -108- TIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -60- TIMEFAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . -59- TRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -39- TRACE-Modus . . . . . . . . . . . . . . . . . . . . . . . . . . -40- Transparent-Betrieb . . . . . . . . . . . . . . . . . . . . . . -20- TUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -59- Uhrzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . -60- USR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -126- VAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -123- Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . -20- VCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -137- -155-
  • 156.
    VEC . .. . . . . . . . . . . . . . . . . . . . . . . . . . . -117- WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -36- Warmstart . . . . . . . . . . . . . . . . . . . . . . . . . . . -20- WINDOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . -93- Zahlenbereich . . . . . . . . . . . . . . . . . . . . . . . . . -21- Zeilennummer . . . . . . . . . . . . . . . . . . . . . . . . . -17- Zeitgeberfunktionen . . . . . . . . . . . . . . . . . . . . . . -59- Ablaufsteuerungen . . . . . . . . . . . . . . . . . . . . . . . . 15 ABS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 ACN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 ACTIVATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 AS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 ASC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 ASN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 ATN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 AUTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 BGMEMCLEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 BGMEMDIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 BGMEMFRE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 BGMEMGETQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 BGMEMGETR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 BGMEMPOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 BGMEMPUSH . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 BGMEMPUTQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 BGMEMPUTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 BGMEMSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 BIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 BITBUS-Anschluß . . . . . . . . . . . . . . . . . . . . . . . . . 71 BITRB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 BITRH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 BITRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 BITRW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 BITWB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 BITWH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 BITWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 BITWW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 BITZFLAG . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Boolsche Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . 35 Buchstaben . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 CALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 CHR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 CLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 CNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41, 47 COMMAND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 COS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Cursor-Positionierung . . . . . . . . . . . . . . . . . . . . . . 89 DAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 DATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . 9 Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 DEFINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 DIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 DIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 DOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 DOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Echtzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . 9, 13 EEPROMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Einfüge-Modus . . . . . . . . . . . . . . . . . . . . . . . . . . 13 -156-
  • 157.
    ELSE . .. . . . . . . . . . . . . . . . . . . . . . . . . . . 100 END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Entwicklungshilfen . . . . . . . . . . . . . . . . . . . . . . 142 EOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 EPROM-startend . . . . . . . . . . . . . . . . . . . . . . . . 137 EXP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Fahrtregler . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Fehlermeldungen . . . . . . . . . . . . . . . . . . . . . . . . 143 Felder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Fenstertechnik . . . . . . . . . . . . . . . . . . . . . . . . . 84 FOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Formatierung . . . . . . . . . . . . . . . . . . . . . . . . . . 90 FRDEF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 FREEZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 FREEZE-Betrieb . . . . . . . . . . . . . . . . . . . . . . . . . 14 FRERROR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 FRLDFAHRT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 FRLSFAHRT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 FRSETKI(ki . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 FRSETKP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 FRSETP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 FRSTAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 FTOI$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 FTOIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 GET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 GOSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 GOTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Hardware-Anpassung . . . . . . . . . . . . . . . . . . . . . . 135 Hintergrundspeicher . . . . . . . . . . . . . . . . . . . . . . . 57 IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 INCHAR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 INSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 INT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Kalender . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Kaltstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Kanalnummern . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Kommando . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Kommandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Kommentare . . . . . . . . . . . . . . . . . . . . . . . . 10, 112 LEFT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 LEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 LET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Linkadapter . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 LN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 LOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 LOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Logikfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . 34 LUAVAIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 LUMODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 LUOPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 MADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 MAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 MDIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 MDOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 MFREE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 MID$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 MSRTIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 MSTIMDIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 -157-
  • 158.
    NADC . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 NCNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 NDAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 NDIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 NDOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 NEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 NEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 NOFREEZE . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 NOTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 NOTRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 NWIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 ON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 ONERROR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 PEEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 POKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Portadressen . . . . . . . . . . . . . . . . . . . . . . . . . 136 POS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 POSSRN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 POSTYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 PRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Programmiertips . . . . . . . . . . . . . . . . . . . . . . . . 130 PROMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 PUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Reglerfunktionen . . . . . . . . . . . . . . . . . . . . . . . . 53 REM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 RETURN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 RIGHT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 RUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 SAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Schnittstellenfunktionen . . . . . . . . . . . . . . . . . . . . 92 Sedezimal-Wert . . . . . . . . . . . . . . . . . . . . . . . . . 12 SEQLIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 SEQuenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 SIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Speicherfunktionen . . . . . . . . . . . . . . . . . . . . . . . 56 SQR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 START . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Starten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 STATUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Steuerzeichen . . . . . . . . . . . . . . . . . . . . . . . . . . 13 STOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Stringfunktionen . . . . . . . . . . . . . . . . . . . . . . . 115 SUSPEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Syntaxfehler . . . . . . . . . . . . . . . . . . . . . . . . . . 14 SYSTEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Systemanalyse . . . . . . . . . . . . . . . . . . . . . . . . . 130 Tabellierung . . . . . . . . . . . . . . . . . . . . . . . . . . 89 TAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 TASK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 TDOWN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 THEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 TIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 TIMEFAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 TRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 TRACE-Modus . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Transparent-Betrieb . . . . . . . . . . . . . . . . . . . . . . . 12 TUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Uhrzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 -158-
  • 159.
    USR . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 VAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 VCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 VEC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Warmstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 WINDOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Zahlenbereich . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Zeilennummer . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Zeitgeberfunktionen . . . . . . . . . . . . . . . . . . . . . . . 50 -159-
  • 160.
    13. Anhang Erweiterungen des MSR-Basic für Z280 CPU (TSM/ECB) 1. Neuerungen bei MSR-Basic V4.2,00 . . . . . . . . . . . . . . . . . . . . 1.1. IF-ELSE-ENDIF . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. ONERROR Änderung. . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. INPUT Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4. SEQSTATE und TASKSTATE Funktionen . . . . . . . . . . . . . . . . . 1.5. FORBID und PERMIT Anweisungen . . . . . . . . . . . . . . . . . . . 1.6. Logische Operatoren AND und OR. . . . . . . . . . . . . . . . . . . 1.7. STDSET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Hintergrundspeicher für MSR-Basic. . . . . . . . . . . . . . . . . . . . 2.1. Einrichten eines Hintergrundspeichers . . . . . . . . . . . . . . . 2.2. Wahlfreie Zugriff (Random Acess). . . . . . . . . . . . . . . . . . 2.3. Zugriff auf Queues. . . . . . . . . . . . . . . . . . . . . . . . . 2.4. Zugriff auf Stacks . . . . . . . . . . . . . . . . . . . . . . . . 2.5. Hilfsfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6. Flash-EPROM Hintergrundspeicher . . . . . . . . . . . . . . . . . . 2.7. Neue E/A-Funktionen für TSM-8AD8 3. Programmspeicherung in Flash-EPROM . . . . . . . . . . . . . . . . . . . 4. CNT-Zähler und EVCTR Funktion . . . . . . . . . . . . . . . . . . . . . 5. Neue Timer Funktionen. . . . . . . . . . . . . . . . . . . . . . . . . . 6. MODEM-Hilfsfunktionen. . . . . . . . . . . . . . . . . . . . . . . . . . 6.1 LUMODE Funktion. . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 LUOPEN Funktion. . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 LUAVAIL Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . 7. LINKADAPTER. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8. Bemerkungen zur Programmspeicherung in ein EPROM . . . . . . . . . . . . 9. Fahrtregelung mit Gleichstrommotoren . . . . . . . . . . . . . . . . . . 10. BITBUS Komunikation. . . . . . . . . . . . . . . . . . . . . . . . . . . 11. Neue, zusätzliche Funktionen . . . . . . . . . . . . . . . . . . . . . . 12. Programmerhalt Seite 160
  • 161.
    1. Neuerungen beimMSR-Basic V4.2,00 In allen früheren MSR-Basic Versionen unterscheidet man zwischen Hauptprogramm, Sequenen und Tasks. Dabei war durch den unübersichtlichen Schedule-Mechanismus nicht vorhersehbar welchen zeitlichen Anteil dem Hauptprogramm zugewiesen wird. Also das Hauprogramm eignete sich lediglich zur Definition von Sequenzen und Task und dessen Start. In der Version V4.2 wurde das Hauptrogramm einer Sequenz gleichgestellt. Das bedeutet, daß das Hauptrogramm immer den gleichen zeitlichen Anteil zur Ausführung bekommt wie andere definierte Sequenzen, oder auch in WAIT-Zustand übergehen kann, was früher nicht möglich war. Die Numerierung der Sequenzen ist gleichgeblieben (#1..#25). Dazugekommen ist die Sequenz #0, also das Hauptprogramm. Ein GOSUB führte dazu, daß der Schedule Mechanismus außer Kraft gesetzt wurde, bis das Unterprogramm beendet war. Also, wenn z.B. eine Sequenz ein GOSUB ausführte, wurden alle Task und Sequenzen angehalten !!!!! Das schränkte die Anwendung von Unterprogrammem sehr ein, aber hatte dabei eine nützliche Eigenschaft das es möglich war durch ein Unterprogramm z.B. Impulse mit fester Länge zu erzeugen ohne alle Task/Sequenzen anzuhalten und wieder zu aktivieren. In der neuen Version darf ein man Unterprogramme verwenden ohne das der Scheduler angehalten wird, weil jede Task/Sequenz ein eigenes GOSUB-Stack besitzt. Lediglich dürfen Unterprogramme nicht beliebig andere Unterprogramme aufrufen. Die Schachtelungstiefe ist auf 4 begrenzt oder auf 3 wenn man ONERROR Anweisung benutzt. Es muß immer die Aufrufmöglichkeit eines ONERROR-Unterprogramms bestehen. Den Scheduler anzuhalten ist weiterhin möglich, aber nicht mehr durch den GOSUB-Trick sondern durch neue Anweisung FORBID. Die ebenfalls neue Anweisung PERMIT löst die Schedule-Sperre wieder auf. Die Ausdruckanalyse lief bis jetzt auch nicht immer korrekt. Ein Funktionsaufruf der als Parameter wiederum eine Funktion hatte führte manchmal zu falschen Ergebnissen. Ganz besonders die Stringfunktionen machten diesen Fehler. Bei der neuen Version würde die Ausdruckanalyse ebenfalls umgeschrieben. Die Ausdruckanalyse hat nicht mehr den iterativen sondern recursiven Charakter. Diese Analyse unterscheidet neben Gleitkomma und Stringausdrücken auch Festkommausdrücke (long-integer). Das bedeutet daß Summen und Produkten von Funktionen, System-Variablen und Integer- Konstanten viel schneller berechnet werden. Leider sind noch keine Festkommavariablen möglich so daß bei einer Variablenzuweisung ein Festkommaausdruck in Gleitkommawert umgewandelt werden muß, oder das Vorhandensein einer Variable im Ausdruck, den Ausdruck automatisch den Gleitkommatyp gibt. !!! ACHTUNG !!! Durch die Festkommaarithmetik können unerwünschte Nebeneffekte auftreten die früher nicht bekannt waren. Eine Konstante ohne einem Dezimalpunkt ist ein Festkommaausdruck, daher ist z.B. (1/10) auch ein Festkommaausdruck. Weist man einer Gleitkommavarible den Wert (1/10) zu, so bekommt sie den Wert (0) zugewiesen!!!. Man sollte in solchen Fällen explizit statt (1/10), (0.1) eingeben oder wenigstens eine Gleitkommakonstante verwenden z.B. (1/10.0) oder (1.0/10). Seite 161
  • 162.
  • 163.
    1.1 IF-ELSE-ENDIF Neben einemeinzeiligen IF...THEN...ELSE... Konstrukt ist ab Version V4.2 das mehrzeilige IF.../ELSE.../ENDIF Block möglich. Beispiel: 100 IF a=1 ' Kein THEN also ENDIF muß folgen! 110 a = a-1 120 b = b+1 130 ELSE 140 a = 1 150 b = b+2 160 ENDIF 1.2 ONERROR Änderung Ab Version V4.2 wird das Scheduling während des Ausführung eines Unterprogramms nicht mehr angehalten. Das bedeutet daß bei der Ausführung eines ONERROR-Unterprgramms die Möglichkeit bestehen würde daß ONERROR-Unterprogramm vom mehren Tasks oder Sequenzen nebenläufig ausgeführt würde. Der Interpreter würde es zwar korrekt ausführen, aber für jede Anwendung wäre es ziemlich problematisch. Daher wird vor jeder Ausführung eines ONERROR-Unterprogramms automatisch die FORBID Anweisung ausgeführt. Das Bedeutet daß ein ONERROR-Unterprogramm nicht durch eine TASK oder Sequenz unterbrochen wird was wiederum ein Aufruf vom ONERROR-Unterprogramm auslösen könnte. Weiterhin ist eine Termination sichergestellt wenn ein Fehler in einem ONERROR-Unterprogramm selbst ausgelöst wird. Im Handbuch wird nicht beschrieben das die Möglichkeit die Fehlernummer auszulesen (ERRVAR Variable). In ERRVAR wird die Fehlernummer gespeichert bevor das ONERROR Unterprogramm ausgeführt wird. Ein Beispiel für ONERROR-Unterprogramm. 1000 REM **** ONERROR-Unterprogramm *********************************** 1010 PRINT "*** FEHLER #";ERRVAR ... ... Eventuelle Aktionen, abhängig vom Fehlernummer ... 1280 PERMIT 1290 RETURN Der Befehl PERMIT hebt die Schedule-Sperre wieder auf. PERMIT sollte in einem solchen Unterprgramm immer kurz vor RETURN Anweisung stehen. 1.3 INPUT Anweisung Die INPUT Anweisung war schon immer ein Bestandteil von MSR-Basic. Seite 163
  • 164.
    Leider war seineAnwendung in einem Multitasking Programm nur bedingt brauchbar, weil das Schedule Mechanismus bis zu Eingabe von <RETURN> angehalten würde. Ab Version V4.2 ist eine neu konzipierte INPUT Anweisung verfügbar die wenig zum Wünschen übrig läßt. Beim ausführen von INPUT Anweisung geht die ausführende Sequenz in ein Wait-Zustand über. Das bedeutet das die Tasks weiterhin eine INPUT Anweisung nicht Ausführen dürfen. Das Hauptprogramm wird ab Version V4.2 wie eine Sequenz behandelt, also es gibt ja auch keine Einschränkung bezüglich der Anwendung. Der WAIT-Zustand in die eine Sequenz übergeht kann optional zeitlich überwacht werden. Damit kann man leicht verhindern daß eine Sequenz ewig auf eine Eingabe wartet. Des weiteren, man kann optional, das Fehlerbehandlung bei der Eingabe selbst gestalten. Also, man kann das standard Mechanismus wo die INPUT-Anweisung, nach vorherigen Meldung: "INPUT Fehler", wiederholt wird, durch eigene Fehlerbehandlung ersetzen. Weiterhin ist es jetzt auch möglich Bildschirmausgaben zu machen während in einem anderem Teil des Bildschirms eine INPUT-Zeile editiert wird. Diese nebenläufige Bildschirmausgabe wird jedoch nur dann funktionieren wenn man kein Semikolon am Ende der PRINT-Anweisung verwendet. Die neue Syntax lautet: INPUT [ ON(Kanal ] [ [Y,X] ] [ MAX Wert ] <Variablenliste> [ ELSE Anweisung] Unter <Variablenliste> ist eine oder mehrere, durch Komma getrennte numerische oder Stringvariablen gemeint. Die Eingabe sollte bei mehreren Variablen auch durch Komma getrennt werden. Bei Numerischen Variablen ist nur eine Numerische Darstellung einer Zahl erlaubt und sollte einer Stringvariable das Kommazeichen auch zugewiesen werden so kann die Eingabe in Anführungsstriche geklammert werden. Beispieleingabe für Variablenliste <a,a,a$>: >1111.0, 222,"Komma,Komma"< Unvollständige Eingaben oder unkorrekte Numerische Darstellung führen zu einem Fehlerfall! Die Optionen: [ ON(Kanal) ] Soll die Eingabe auf einem anderem Kanal erfolgen als LU(0), so ist diese Option zu wählen. So werden bei "INPUT ON(2) a" alle Eingaben und Ausgaben auf LU(2) erfolgen. [ [Y,X] ] Stellt den Cursor auf eine bestimmte Y,X Position des Bildschirms. Seite 164
  • 165.
    Auf dieser Positionkann man dann die Werte eingeben. Obwohl andere Sequenzen oder Task Bildschirmausgaben parallel dazu machen wird die eingestellte Position beibehalten. Vorausgesetzt daß PRINT-Anweisungen ohne Semikolon verwendet werden!. [ MAX Wert ] Die INPUT-Anweisung wird Zeitlich überwacht. Durch <Wert> bestimmt man wieviel Sekunden maximal das Eingabegerät ruhen darf. Die INPUT Anweisung selber kann vielfaches davon aktiv bleiben, aber einzelne Pausen bei der Eingabe dürfen den Limit nicht überschreiten. [ ELSE Anweisung ] Programmabschnitt nach <ELSE> wird nicht berücksichtigt wenn die Eingabe erfolgreich abgeschlossen würde. Würde die Zeitliche überwachung aktiviert und überschritten oder die Eingabe falsch oder unvollständig gemacht so wird keine Fehlermeldung ausgegeben und die INPUT-Anweisung wiederholt, sonder dieser Programmabschnitt ausgeführt. Zweckmäßig sollte dort eine GOTO Anweisung stehen, aber auch andere Anweisungen sind zulässig. Beispiel für eine INPUT-Anweisung mit Optionen: 11000 PRINT "Geben Sie Bitte Name,Vorname und Alter ein: "; 11010 INPUT MAX 10 Name$,Vorname$,Alter ELSE GOTO 11110 1.4 SEQSTATE und TASKSTATE Funktionen Es ist manchmal nützlich zu wissen ob eine Sequenz oder Task aktiv ist. Zwar ließ sich daß immer durch Benutzung von Variablen realisieren, doch jetzt ist es bequemer und sicherer. Als Parameter gibt man eine Sequenz oder Tasknummer und bekommt zurück ein Zustandswert, der folgende Bedeutung hat: 0: Sequenz oder Task nicht Aktiv. 1: Sequenz oder Task ist aktiv 2: Nur bei Sequenzen. Sequenz ist aktiv und wartet auf ein Zustand (WAIT oder INPUT Anweisung gerade in Bearbeitung). Beispiel: Von einer Sequenz soll ein TASK gestartet werden, die Sequenz selber hat dann nichts zu tun und soll solange in Wartezustand übergehen. 1000 START TASK 1 1010 WAIT FOR TASKSTATE(1) = 0 1020 PRINT "O.K." 1.5 FORBID und PERMIT Anweisungen Das Multitasking bringt viele Vorteile mit sich. Es gibt jedoch Anwendungen bei denen für kurze Zeit das Schedulemechanismus sehr stört. Z.B. bei Erzeugung von Programmgesteurten Impulsen oder bei einem Fehlerfall wo alle TASK/SEQUENZ Aktionen kurz angehalten werden Seite 165
  • 166.
    sollen. Zwar ließ essich immer mit SUSPEND TASK ALL und SUSPEND SEQ ALL alle Tasks und Sequenzen anzuhalten, aber dadurch war nur der Hauptprogramm blieb dann aktiv und es war nicht mehr möglich den ursprünglichen Zustand herzustellen. ACTIVATE TASK ALL würde alle TASKs aktivieren unabhängig davon ob sie vorher schon mal aktiv waren oder nicht. Bei Ausführung der FORBID Anweisung wird also wirklich das Schedulemechanismus angehalten. Nach dieser Anweisung wird ausschließlich der Programmteil, der diese Anweisung enthalten hat, ausgeführt. Die Anweisung PERMIT hebt die Sperre wieder auf, und alles kehrt zum ursprünglichen Zustand. Wie schon erwähnt, es gibt ein Sonderfall wo die FORBID Anweisung automatisch ausgeführt wird. Und zwar vor der Ausführung eines ONERROR Unterprogramms. Daher sollte man in der Regel nicht vergessen ein PERMIT Anweisung auszuführen vor einer RETURN Anweisung des Unterprogramms. Noch ein schlechtes Beispiel zur Warnung: 1000 a = 0 1010 FORBID 1020 WAIT FOR a>0 1030 PERMIT Wie man leicht erkennen kann ist dieser Beispiel das Ende eines Programms. Obwohl vorher alles schalten und walten vermag tut sich bereits nach der dritten Zeile nichts mehr. Dieser Teil einer Sequenz wird nach der FORBID Anweisung der einziger ausgeführte Programmteil, und geht sofort in ein WAIT-Zustand der nie beendet wird!!! 1.6 Logische Operatoren AND und OR Eine Einschränkung bei MSR-Basic war das fehlen der bekannten AND oder OR Operatoren. Nun gilt diese Einschränkung nicht mehr. Diese Operatoren sind z.Z. nur als logische Operatoren die zusammen mit Relationen in einer IF oder WAIT Anweisung verwendet werden können, nicht aber für eine Verknüpfung zweier Werte bitweise. Das macht nur ein Sinn mit Ganzzahligenwerten und solange keine Ganzzahlige Variable eingeführt sind würde es nur wenig ausgenutzt werden können. Die Rangfolge dieser Operatoren ist nach der Relationen und beliebige Klammerung ist erlaubt. Beispiel: 1000 IF DIN(NotAus) OR (DIN(Vent1) = 0 AND DIN(Vent2) = 0) 1010 PRINT "Notschalter EIN, oder beide Ventile ausgeschaltet!!" 1020 ENDIF 1.7 STDSET Anweisung Die neue Anweisung STDSET soll der allgemeiner Voreinstellung dienen. Bis jetzt ist nur der Format bei Ausgabe von numerischen Werten voreinstellbar, und die Syntax lautet: STDSET AS xxx Seite 166
  • 167.
    wobei xxx dieFormatbeschreibung ist die sonst hinter AS erlaubt ist. Sollen in einem Programm nur Werte in sechsstelligen Festkommaformat ausgegeben werden so braucht man nicht mehr hinter jeder PRINT Anweisung "AS 6I" einzugeben wenn man am Programmanfang mit "STDSET AS 6I" dieses Format eingestellt hat. Ein weiteres Nutzen dieser Anweisung ist es, daß damit auch die STR$ Funktion beeinflußt wird. Bis jetzt lieferte diese Funktion einen String welcher gleich war mit Ausgaben der PRINT Anweisung ohne <AS xxx> Formatangabe. Meist müsste ein solcher String weiterbearbeitet werden z.B. wenn man nur die zwei Vorkommaziffer benötigte. Nun, jetzt kann man das Format einstellen und dieses Format wird auch für die STR$ Funktion verwendet. Beispiel: Ein Programm soll über LU(2) Steuersequenzen ausgeben. Eine Sequenz besteht aus einem <ESC> Zeichen gefolgt von einer Befehlsbuchstabe,Parameter und <CR> Zeichen. Der Parameter besteht immer aus zwei Hexadezimalziffern. 10000 PRINT ON(2) CHR$(&H1B)$; ' <ESC> Zeichen 10010 PRINT ON(2) Cmd$; ' Kommandobuchstabe 10020 STDSET AS 02H ' Format = 2 Stellen, Hexadezimal 10030 PRINT ON (2) STR$(Wert); ' Parameter ausgeben 10040 STDSET AS 6I ' wieder Normale Einstellung 10050 PRINT ON (2) CHR$(&H0D); ' Abschlusszeichen <CR> Seite 167
  • 168.
    2. Hintergrundspeicher fürMSR-Basic MSR-Basic wurde ursprünglich für den Betrieb mit sehr wenig Hauptspeicher entwickelt. Es kann meist ein Bereich von 32 KByte für MSR-Programme und Daten genutzt werden. Um in Applikationen der Meßwerterfassung auch mit größeren Datenmengen umgehen zu können, wurde für den Prozessor Z280 eine Erweiterung des MSR-Basic vorgenommen. Die neuen Funktionen erlauben die Einrichtung und das Einfügen/Entfernen von Daten aus einem Hintergrundspeicher. Ein Hintergrundspeicher kann als Feld von Datenstrukturen aufgefaßt werden. Es können auch mehrere Hintergrundspeicher definiert werden, deren Datenstruktur unabhängig voneinander sind. Auf den Hintergrundspeicher kann direkt (wahlfrei), als Stack oder als Queuezugegriffen werden. Alle Zugriffsarten können auch gemischt werden, was besonderes dann sinnvoll ist, wenn die Daten eines Stacks oder Queue verarbeitet werden sollen, ohne sie aus dem Hintergrund zu entfernen. Es können maximal 8 Hintergrundspeicher definiert werden, deren Größe nur durch den verfügbaren Speicherplatz begrenzt wird. Bei TSM wird bei dem Hintergrundspeicher Nr. 0 der Speicherbereich eines Flash-EPROM genutzt. Somit bleiben dort eingeschriebene Daten dauerhaft erhalten. 2.1. Einrichten eines Hintergrundspeichers BGMEMDIM(n, e, var_liste) Dimensioniere den Hintergrundspeicher n als Feld mit e Strukturen. Jede Struktur hat seinen Aufbau wie var_liste. n : Nummer des Hintergrundspeicher (0..7). e : Anzahl der Strukturen, die der Hintergrundspeicher fassen soll. var_liste : Aufzählung der Variablentypen. Die Namen der Variablen in var_liste haben keine Bedeutung. Nur der Typ dieser Variablen wird benötigt, um den Strukturellen Aufbau und Platzbedarf bestimmen und Initialisierung durchführen zu können. Folgende Typen sind z.Z. zugelassen: a$(n) : String der max. n-Buchstaben aufnehmen kann. a : Gleitkommazahl. a(n) : Feld von Gleitkomazahlen mit der Dimension n. Initialisierung: Strings werden mit dem Zeichen "-" gefüllt. Gleitkommazahlen werden mit der größten negativen Zahl initialisiert. Der Hintergrundspeicher in Flash-EPROM hat abweichende Initialisierung. Flash-BGM (Hintergrundspeicher Nr.0 bei TSM) ist immer definiert. Notwendig ist nur eine Dimensionierung. Nach einem BGMEMDIM(0,...) Statement wird der Flash-BGM nicht gelöscht sondern untersucht ob er Strukturen enthaltet. Also, mehrfaches Dimensionieren ist zulässig. Löschen des Flash-BGM muß separat mit BGMEMCLEAR(0) Statement durchgeführt werden. Beispiel für BGMEMDIM: Seite 168
  • 169.
    BGMEMDIM(1,100,a$(8),a,a,a(10)) Hintergrundspeicher '1' enthält100 Strukturen, der Form: string[8] : String mit max. 8 Zeichen float : Gleitkommazahl float : Gleitkommazahl float[10] : Feld von 10 Gleitkommazahlen 2.2. Wahlfreier Zugriff (Random Access) BGMEMPUTR(n,c,var_liste) Lege die Parameter (var_liste) in Struktur c von Hintergrundspeicher n ab. n : Nummer des Hintergrundspeicher. c : Nummer der Struktur in diesem Hintergrundspeicher var_liste : Aufzählung der Variablen/Ausdrücke. Die Typen der Parameter in var_liste müssen gleich sein mit den Typen derStrukturelemente von diesem Hintergrundspeicher. Beispiel: BGMEMPUTR(0,2,"09:22:32", 3*varb, varc, varar()) Der letzte Parameter varar() hat in den Klammern keinen Indexnummer weil hier kein Element des Feldes gemeint ist, sondern das Feld als ganzes ! BGMEMGETR(n,c,var_liste) Setze Variablen (var_liste) aus Struktur c in Hintergrundspeicher n. n : Nummer des Hintergrundspeicher. c : Nummer der Struktur in diesem Hintergrundspeicher var_liste : Aufzählung der Variablen. Beispiel: BGMEMGETR(0,2,a$, varb, varc, varar()) 2.3. Zugriff auf Queues BGMEMPUTQ(n,var_liste) Verschiebe alle Strukturen in Richtung der letzten Struktur. Lege Inhalt der Parameter (var_liste) in der ersten Struktur des Hintergrundspeicher n ab. Dabei geht der Inhalt der letzten Struktur verloren, falls der Hintergrundspeicher voll belegt war. BGMEMGETQ(n,var_liste) Hole Inhalt der Variablen (var_liste) aus der letzten gültigen Struktur. Diese Struktur wird dabei als ungültig erklärt. Zusammen mit dem Seite 169
  • 170.
    BGMEMPUTQ Statement wird damit ein first-in/first-out Speicher realisiert. 2.4. Zugriff auf Stacks BGMEMPUSH(n,var_liste) Verschiebe alle Strukturen in Richtung der letzten Struktur. Lege Inhalt der Parameter (var_liste) in der ersten Struktur des Hintergrundspeicher n ab. Dabei geht der Inhalt der letzten Struktur verloren, falls Hintergrundspeichervoll belegt war. BGMEMPOP(n,var_liste) Hole Inhalt der Variablen (var_liste) aus der ersten Struktur des Hintergrundspeicher n. Die erste Struktur wird dabei aus dem Hintergrundspeicher entnommen und die restlichen Strukturen werden in Richtung der ersten Struktur verschoben. Mit diesem Statement zusammen mit BGMEMPUSH ein first-in/last-out Speicher (Stack) realisiert. 2.5. Hilfsfunktionen BGMEMSS(n) Gebe Anzahl der gültigen Strukturen in Hintergrundspeicher n zurück. Das BGMEMPUSH und das BGMEMPUTQ Statement verursacht ein Fehlerfall wenn der ganzer Hintergrundspeicher nur gültige Strukturen enthält und es folglichbeim einfügen einer neuen Struktur zum Überschreiben der letzten Datenstrukturkommen würde. Um solche Situationen zu vermeiden gibt es diese Funktion dieeinen Auskunft über dem Anzahl der gültigen Strukturen zurückgibt. Beispiel: sbel = BGMEMSS(0) BGMEMCLEAR(n) BGMEMCLEAR löscht den Hintergrundspeicher n. Alle Daten werden wie bei BGMEMDIM initialisiert. Die Struktur des Speichers bleibt erhalten. BGMEMFRE(n) BGMEMFRE gibt ein Hintergrundspeicher frei. Der belegter Speicher kann für andere Hintergrundspeicher verwendet werden. Der Hintergrundspeicher existiert nicht mehr nach diesem Statement undmuß neu Dimensioniert werden. 2.6. Flash-EPROM Hintergrundspeicher Der Hintergrundspeicher #0 ist beim TSM als Flash-EPROM Speicher realisiert. Flash-EPROM ist für Hintergrundspeicher verfügbar wenn dort kein Programm gespeichert ist oder es wird ein 28F010 (120 KByte) Typ verwendet. Dazu gibt es kleine Unterschiede:Der Speicher bleibt dauerhaft erhalten auch wenn der Speicheraufbauverloren gehen soll. Mehrfaches Dimensionieren löscht den Speicher nicht. Ein BGMEMGETQ und BGMEMPOP Statement können nicht benutzt werden. Strukturen können nicht übeschrieben oder entnommen werden. Lesen ist nur Wahlfrei möglich (BGMEMGETR Statement). Seite 170
  • 171.
    Beispiel: BGMEMDIM(0,200,a$(40)) BGMEMPUTQ(0,"Erste Struktur") BGMEMPUTQ(0,"Zweite Struktur"); bel = BGMEMSS(0) BGMEMGETR(0,0,a$) REM a$ ist gleich "Erste Struktur" und bel ist gleich 2 BGMEMGETR(0,bel-1,a$) REM a$ ist gleich der zuletzt geschriebenen String = "Zweite Struktur" 2.7. Neue E/A-Funktionen für TSM-8AD8 KTY8(n) Gibt einen Temperaturwert am Eingang n einer 8AD8/KTY Baugruppe zurück. Ein gemessener Rohwert x wird als (x/2)-25.0 zurückgegeben, was bei der Standardbeschaltung der 8AD8/KTY der Temperatur in EC entspricht. TCK8(n) TCJ8(n) Beide Funktionen sind mit der KTY8(n) Funktion vergleichbar, nur wird hier eine Linearisierung von Thermoelementen vorgenommen. Mit TCK8 wird die Temperatur eines Elements vom Typ K angezeigt, bei TCJ8 die eines Typ-J-Elements. Seite 171
  • 172.
    3. Programmspeicherung inFlash-EPROM Beim Einsatz von 28F256 Flash-EPROM (32 KByte) kann dieser zur Programmspeicherung oder für Hintergrundspeicher verwendet werden. Ein 28F010 (120 KByte) Typ wird automatisch erkannt und für beides gleichzeitig verwendet. Programmspeicherung 32 Kbyte und Hintergrundspeicher 96 Kbyte. Ein Programm wird in Flash-EPROM mit dem Kommando FEPROMIT gespeichert. Dabei wird der ganze EPROM gelöscht. Jedoch falls genügend RAM vorhanden istwird der Inhalt des Hintergrundspeichers dort kopiert und wieder in EPROMgeschrieben. Gleiches wird passieren beim BGMEMCLEAR(0) Statement mit dem Programmbereich. Löschen von Programmen in Flash-EPROM kann man auch mit dem FEPROMIT Kommando erreichen wenn kein Programm in Speicher vorhanden ist. Z.B. NOF ' NOFREZZE Betriebsart NEW ' Programm löschen FEPROMIT ' und Speichern (nur Flash-EPROM löschen) Seite 172
  • 173.
    4. CNT-Zähler undEVCTR Funktion Standardmäßig werden insgesamt 8 Zähleingänge unterstützt. Diese Eingänge befinden sich auf dem CPU Modul (8E24) und werden gemeinsam mit dem DIN-Treiber abgefragt. Also CNT(1) und DIN(1) beziehen sich auf dem ersten Eingang, wobei die CNT-Funktion die anliegende Frequenz und die DIN-Funktion den momentanen Pegel. Diese Zähler können recht hohe und unsymmetrische Frequenzen messen die nur durch Eingangsbeschaltung (Filter o.ä) begrenzt werden. Die Torzeit beträgt bei allen Zählern 100ms. Also, CNT(n) gibt die anliegende Frequenz/10 zurück. Ab Version 4.1,87 ist die CNT Funktion modifiziert. Jetzt ist sie nicht mehr eine Vektorfunktion mit dem Bereich - 32768..32767 sodndern eine Standartfunktion mit dem Wertbereich 0..16777215 (unsigned 24Bit Darstellung). Eine Möglichkeit einer Zuweisung wie CNT(x)=y ist nicht mehr möglich aber kann bei Bedarf durch eine Funktion SETCNT(x,y) wieder verfügbar gemacht werden. Ausser dem Frequenzmessen kann einer der Eingänge zur Erreignisszählung herangezogen werden. Dabei ist eine gleichzeitige Frequenzmässung auf einem anderen Eingang nicht möglich. Die Umstellung der Arbeitsweise der CNT Funktion wird duch eine neue Funktion <EVCTR(n)> bewerkstelligt. Der Parameter n entspricht dem Eingangsnummer (DIN(n)) der für Erreignisszählung herangezogen werden soll. Der Zähler wird dabei gelöscht. EVCTR(0) schaltet den default Modus, also Frequenzmässung wieder ein. Wegen der Tatsache, daß nur ein Zähler zur Erreigniszählung verfügbar ist und der Eingang zuvor definiert wird ist der Parameter der CNT(n) Funktion vorläufig ohne Bedeutung. Sollten andere Erreignisszähler dazukommen so wird dieser Zähler die Nummer eins haben und alle weitere ab zwei. Seite 173
  • 174.
    5. Neue TimerFunktionen MSR-Basic verfügt über einem frei laufenden Timer. Dieser Timer wird jede Milisekunde incrementiert und hat 24 bit Auflösung. Diese Timer wird ausgelesen wie jede andere Variable: tim = MSTIMER ' Variable tim erhält momentanen Zustand des TimersEine weitere Funktion erlaubt Berechnung von Zeitdifferenzen zwischen früher eingespeicherten Timerwert und aktuellen, zu Zeit des Aufrufs der Funktion: tdiff = MSTIMDIF(tim) ' tdiff Variable erhält Anzahl Milisekunden ' seit dem Zuweisen von MSTIMER an Variable timAuf diese Weise lassen sich recht genau Zeitdifferenzen bis zu 2796 Minuten feststellen. Andere Anwendung wäre z.B. Laufzeitmessung von BASIC Programmen: tim = MSTIMER GOSUB 1000 tdiff = MSTIMDIF(tim) PRINT "Unterprogramm #100 dauert ";tdiff;" Milisekunden" oder Verzögerungen: 100 tim = MSTIMER 110 IF MSTIMDIF(tim) < 1000 GOTO 110 ' Warte eine Sekunde 6. MODEM-Hilfsfunktionen Mit Hilfe der MODEM-Hilfsfunktionen ist die Ankopplung von MSR-Rechner über Wählleitungen an einen (oder mehrere) zentralen Rechner möglich. Das erlaubt Anwendungen, die Fernwartung erfordern. Dazu sind neue Funktionen implementiert die auch für andere Anwendungen,zusammen mit der seriellen Schnittstellen, nützlich sind. 6.1 LUMODE Funktion Mit dieser Funktion wird die Baudrate, Format und Art des Handshake eingestellt. Syntax: fcd = LUMODE (kanal,Baud,"Format") fcd: Variable in die der Fehlercode zugewiesen wird: 0 = Alles in Ordnung 1 = Kanal existiert nicht 2 = Baudrate nicht unterstützt. 3 = Datenformat nicht unterstützt Auf das Auswerten des Fehlercodes kann man ohne weiteres verzichten, wenn man sicher ist das die angegebene Parameter richtig sind. Man kann ja zuerst mit <PRINT LUMODE(.....)> austesten ob die Baudrate oder Format bearbeitet werden kann. kanal: Kanalnummer der umgestellt werden soll. Die SCC2 Karte bei ECB/Z280 CPU belegt Kanäle 2 und 3. Die SCC Schnittstellen der TSM-CPU belegen Kanäle 1 und 2 Baud: Baudrate die Benutzt werden soll. Es werden nach Möglichkeit alle üblichen Baudraten unterstützt: 300,1200,2400,4800,9600,19200,38400 Baud. Seite 174
  • 175.
    Format: EinString der den Format des Kanal beschreibt. Erste Buchstabe gibt die Anzahl bits an ("7" oder "8"). Zweite Buchstabe wählt die Parität an ("O" für Odd, "E" für Even oder "N" für keine Parität). Dritte Buchstabe gibt die Anzahl der Stoppbits an ("1" oder "2"). Folgende Buchstaben stellen den Handshake ein: "X" -> Es wird das XON/XOFF Protokoll benutzt (^S und ^Q Zeichen). "R" -> Es wird das RTS/CTS Hardware handshake benutzt. Beide Handshakearten können auch gemeinsam benutzt werden. Wie auch immer, das RTS Signal zeigt in jedem Zeitpunkt das Empangsbereitschaft vom Seriellen Kanälen, unabhängig ob und welchen Handshake man gewählt hat. Beispiel: Es soll an der zweiten Schnittstelle ein Modem angeschlossen werden mit 2400 Baud, 8 Bits Daten, keine Parität, ein Stoppbit. Beide Handshake Protokolle sollen berücksichtigt werden. Dann sieht die Initialisierung der Schnittstelle so aus: fcd = LUMODE(2,2400,"8N1XR") 6.2 LUOPEN Funktion Mit dieser Funktion kann man den Zustand der DCD-Leitung abfragen. Sie liefert 0 zurück falls ein an einem Kanal angeschlossene Gerät zum Datenaustausch nicht bereit ist. Beispiel: 1000 IF LUAVAIL(2) THEN PRINT ON(2) "Hallo wie gehts" 6.3 LUAVAIL Funktion Sollte eine Sequenz ein LU-Kanal bedienen so ist es sinnvol einer Wartebedienung mit dem Vorhandensein von Daten aus diesem Kanal zu formulieren. Bis jetzt könnte man ungenügend festellen ob Zeichen angekommen waren oder nicht. Die Funktion LUAVAIL gibt an ob Zeichen vorhanden sind oder nicht ohne die Daten aus Empfangspuffer zu entnehmen. Beispiel: 1000 WAIT FOR LUAVAIL(2) ' Warte bis Zeichen an den Kanal #2 ankommen 1000 a$ = INCHAR$(2) ' Zeichen lesen und auswerten Bei Benutztung dieser Funktion darf nur eine Sequenz oder Task lesend auf den Kanal zugreifen. Sonst wurde die Gefahr entstehen daß LUAVAIL Funktion eine Wartebedienung einer Sequenz beenden würde aber das angekommende Zeichen von einer anderen Sequenz/Task ausgelesen wären. 7. LINKADAPTER Ab Version 4.1.61 ist ein einfacher LINKADAPTER-Treiber installiert worden. Seite 175
  • 176.
    Der LINK-Anschluss istüber LU #3 erreichbar. Man kann Daten mit PRINT ON(3), INPUT ON(3) oder INCHAR$(3) über LINK- Anschluss austauschen. 8. Bemerkungen zur Programmspeicherung in ein EPROM. Speicher und EPROM Belegung: Der Z280 Prozessor verfügt über System und User Bereich die voneinander getrennt jeweils 64KByte haben. In System-Bereich ist ein Betriebssystem und in User-Bereich der Basic-Interpreter untergebracht. Der EPROM enthält also beides. Daher sind alle Adressen des Interpreters relativ zu Interpreteranfang in EPROM zu suchen! Weil es verschiedene Versionen von dem MSR-BASIC geben kann mit unterschiedlichen Zusatztreibern, ist es schwer die genaue Adressen anzugeben. Es wird jedoch immer so gehandhabt, daß der Interpreter immer bei vielfachen von 4 KByte Speicherbereich anfängt und nie kleinere Anfangsadresse geben wird als 3000h. Also, der Interpreter beginnt ab 3000h,4000h,5000h,.. oder 8000h. Es ist relativ leicht zu erkennen wo der Interpreter beginnt weil zwischen dem Betriebssystem und dem Interpreter zwangsläufig Lücke entsteht die mit <FF FF FF FF...> beschrieben ist. So, z.B. wenn man In EPROM-Dump follgende Zahlenfolgen sieht: 05FE0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................ 05FF0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................ 06000: C3 ..... so ist es eindeutiger Zeichen, daß der Interpreter ab 06000h im EPROM liegt. Diese Startadresse sollte man sich merken. Alle absolute Adressen, die bei der Beschreibung des PROMIT Statements angegeben sind beziehen sich relativ zu Interpreteranfang, der bei der Z80 Versionen ab 0000h beginnt und bei Z280 eben nicht festgelegt und bei oberem Beispiel 6000h beträgt. Ab der Startadresse des Interpreters werden 28 KByte des EPROMS und 36 KByteRAM eingeblendet. Daher ist für BASIC-Programme der Speicherbereich zwischen Interpreterende und Startadresse+7000h nutzbar.Interpreterende ist auch leicht durch die Zeichenfolge: : 55 AA FF FF FF FF FF FF FF FF FF FF........ erkennbar. Leider ist standartmässig nur für kleinere Programme Platz vorhanden. Sollen grössere Programme im EPROM abgelegt werden so ist es nötig den RAM-Bereich zu kürzen dammit größerer EPROM-Bereich eingeblendet wird. Das ist z.Z. durch den Anwender nicht machtbar. Es wird jedoch eine neue Version angestrebt die automatisch den EPROM/RAM Bereich optimal verteilt so daß der Speicherbereich Interpreterende-Epromende (27x512 Typ) nutzbar wird. Oder anders gesagt: fast alle Programme die in RAM laufen werden auch EPROM-Fähig. Die Vorgehensweise um ein BASIC-Programm in EPROM zu speichern ist bei PROMIT Statemment beschrieben. Einziger Unterschied besteht nur darin daß der Interpreter und Basic-Programm um den Versatz <Interpreteranfang> im EPROM gebrannt wird. 9. Fahrtregler mit Gleichstrommotoren Seite 176
  • 177.
    Um ein Gleichstrommotorantriebanzusteuern bedarf es zweierlei: - Die Motorspannung für einem Servoverstäreker erzeugen. - Die momentane Ist-Position erfassen. Die Steuerspannung wird über frei definierbarer D/A Kanal ausgegeben. Es kommt z.Z. nur das TSM-2DA12 Modul in Frage. Zu Positionserfassung hat man die Wahl zwischen TSM-4SSI oder TSM- 1INCModul, wobei auch hier der Eingang frei definierbar ist. Der Regler erlaubt bis zu vier unabhängige Antriebe die auch paarweisekoordiniert ein Ziel fahren können (X/Y Fahrt). Es kann nur eine Achse oder eine Achsenpaar in einem Zeitpunkt gefahren werden. Der Regler kontroliert die Fahrt in einem Zeitraster von 8ms und zwar im Hintergrund sodaß ein BASIC Programm weiter ablaufen kann. Es ist jedoch eine niedriegere Interpretationsgeschwindigkeit während einer Fahrt anzunehmen. Der Verlauf einer Fahrt ist einstellbar d.h. die maximale Geschwindigkeitund die Anfahr-/Bremsbeschleunigung kann der Anwender festlegen. Um eine Position zu erfassen sind folgende Funktionen implementiert worden: POS (geber) Diese Funktion gibt zurück die aktuelle Position eines Gebers. Als Beispiel sollen zwei Module angeschloßen sein. Ein TSM-1INC mit Modulnummer 3 und ein TSM-4SSI Modul mit Modulnummer 4. Eine Anweisung der Form: xachs = POS(1) weist der Variable xachs den Wert des Incrementalgebers zu. xachs = POS(3) weist der Variable xachs den Wert des SSI-Gebers, angeschlossen an SSI2-Buchse des TSM-4SSI Moduls. Ein Fehler (Fehler 25) kann entstehen falls kein Geber oder keine 24V Spannung an entsprechenden Modul angeschlossen ist. POSTYPE(GeberNr, Typ, NegFlag, Offset) Definiert ein angeschloßener Gebertyp. Wichtig bei TSM-4SSI Modulen, da verschiedene Geber angeschloßen werden können dessen Gray-Code unterschiedlich nach rechts verschoben werden muß. Folgende Typen sind zulässig und resultirende Aufflösungen: TYP: Geber: Auflösung: 2048 2048/4096 0..8388607 1024 1024/2048 0..2097151 512 512/1024 0..524287 256 256/512 0..131072 128 128/256 0..32767 64 64/128 0..8192 32 32/64 0..2047 16 16/32 0..512 Für Inkrementalgeber wird Typ nicht ausgewertet, also z.B. 0 einsetzen. Seite 177
  • 178.
    NegFlag: Ist dieser Parameterungleich Null so wird die Position immer negiert ausgegeben. Offset: Diese Konstante, wenn ungleich Null, stellt eine Bipolare Verhalten des Positionsgebers ein. Der Wertebereich der Auflösung verschiebt sich ins negative sodaß man negative als auch positive Positionen erfassen kann .Z.B. nach POSTYPE (1,512,0,300) stellt die Auflössung des Positionsgebers auf -300..523987, und POSTYPE (1,512,0,262143) stellt einen symmetrischen bipolaren Wertebereich ein. POSTYPE(1,0,0,8388607) würde für einen Inkrementalgeber einen symmetrischen Bereich -8388607 .. +8388608 ein. POSSRN (Geber) Setze die aktuelle Position eines Gebers als Nullpunkt.Alle darauf folgende Positionsangaben sind relativ zur dieser Position. Für den Fahrregler sind folgende Funktinen reserviert: FRDEF(nr,posg,dac,brems) Weise einem Antrieb ein Positionsgeber, ein DAC-Ausgang und eine Bremseausgang zu. nr: Antriebnummer (1..4) posg: Nummer des Positionsgebers (1..NPOS) dac: Nummer des D/A Kanals (1..NDAC) brems: Nummer eines DOUT Kanals (1..NDOUT), kann 0 sein (keine Bremse da). FRSETP (nr, ruhesp, mv, ma, mweg) Setzte Parameter eines Antriebes. Sollen zwei Antriebe als Paar koordiniert fahren, so müssen sie die gleichemv und ma Parameter haben. nr: Antriebnummer (1..4) ruhesp: Ruhespannung, ungleich Null wenn Antrieb senkrecht aufgestellt und eine zusätzliche Kraft nötig ist um die Erdanziehungskraft auszugleichen. mv: Maximale Steuerspannung (0..10000 mV) ma: Beschleunigung, Zuwachs der Steuerspannung pro ein Interval (8ms). mweg: Antriebskonstante. Positionsdifferenz in einem Interval wenn die maximale Steuerspannung von 10V angelegt wäre. FRSETKP(nr, Verst) Definiere den Kp-Reglerparameter. Dieser Parameter ist für die Verstärkung des P-Anteils des Reglers zuständig. Seite 178
  • 179.
    nr: Antriebsnummer Verst: KP-Verstärkung FRSETKI(nr, Beiw) Definiere den Ki-Reglerparameter. Dieser Parameter ist der Integralbeiwert des I-Anteils des Reglers. nr: Antriebsnummer Beiw: KI-Beiwert FRLSFAHRT(nr,Pos) Fahre linear mit einen Antrieb die Zielposition. nr: Antriebsnummer (1..4) Pos: Zielposition. Diese Funktion gibt Null zurück wenn die Fahrt erfolgreich initialisiert würde. Gleichzeitig beginnt auch die Fahrt im Hintergrund, sodaß keine weitere Fahrten gestartet werden können bis dieser Antrieb seine Zielposition erreicht hat. FRLDFAHRT(Xnr,XPos,Ynr,YPos) Fahre linear mit einem Antriebspaar die Zielpositionen. Xnr: Antriebsnummer des ersten Antriebs. Ynr: ... des zweiten Antriebs. XPos: Zielposition des ersten Antriebs. YPos: ... des zweiten Antriebs. Diese Funktion unterscheidet sich von der oberen nur dadurch das zwei Antriebe gleichzeitig und koordiniert gefahren werden. FRSTAT(nr) Gebe zurück den Status eines Antriebes. Es ist die einzige Möglichkeit festzustellen in welchen Fahrzustand sich gerade der Antrieb befindet. Beispiel: 1000 stat = FRSTAT(1) 1010 IF stat = 0 THEN PRINT "Antrieb ist ruhend" 1020 IF stat = 1 THEN PRINT "Antrieb fährt an" 1030 IF stat = 2 THEN PRINT "Antrieb fährt" 1040 IF stat = 3 THEN PRINT "Antrieb bremst" 1050 IF stat = 4 THEN PRINT "Antrieb schleicht sich an Ziel an" 1060 IF stat >= 5 THEN PRINT "Fehler: Antrieb angehalten" Im letzten Fall, wo FRSTAT(1) eine Zahl gleich 5 oder höher geliefert hat,ist anzunehmen daß der Positionierfehler zu groß enstanden ist. Die nächste Abfrage liefert 0, Antrieb ist in Ruhezustaand. FRERROR(nr) WIRD NOCH GEÄNDERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Es ist eine Hilfsfunktion die den Positionsfehler zurückgibt der enstanden ist beim Bremseintritt. Es wird vorrausgesetzt daß vorher die FRLSFFAHRT oder FRLDFAHRT Seite 179
  • 180.
    Funktionaufgerufen und dieStrecke erfolgreich ohne Abbruch gefahhren würde. Diese Funktion kann man nutzen um den mweg Parameter der Funktion FRSETP zu bestimmen. Dazu eignet sich folgende Vorgehensweise: 1) FRSETKI aufrufen mit Parameter = 0, kein Einfluß des Integrallregler. 2) FRSETKP aufrufen mit kleinem Parameter oder 0, kaum/kein Einfluß des Proportionalregler. 3) FRSETP aufrufen mit einem näherungswert für mweg 4) Falls FRSTAT keine 5 zurückgegeben hat bevor der Antrieb stehengeblieben war (FRSTAT(n) = 0), den Positionsfehler auslesen. 5) Die ganze Prozedur ab dem Punkt 3 wiederholen mit anderem mweg Parameter bis man den kleinsten Positionsfehler ermittelt hat. Seite 180
  • 181.
    10. BITBUS Komunikation AbMSR-Basic V4.1,74 ist ein BITBUS Treiber verfügbar. Dammit läßt sich, über BITBUS-Netz, die TSM-CPU ansteuern. Unabhängig von dem BASIC-Interpreter lassen sich alle allgemeine Funktionen eins BITBUS-Rechner anwenden ausser Funktionen die 8044 Spezifisch sind undTask Funktionen. Darüberhinaus besteht die Möglichkeit: eine Kommunikation zwischen Host-Rechner und dem BASIC-Interpreter aufzubauen. Beschreibung der Zusammenarbeit zwischen BITBUS und MSRBASIC - Allgemeines: Ein in TSM-Rechner zu Verfügung gestellter Speicherbereich (768 Bytes) kann über BITBUS beschrieben und ausgelesen werden. Das gleiche wird auch von MSR-Basic ermöglicht. Der Datenaufbau von diesen Speicher wird nicht vorgeschrieben und kann frei gewählt und genützt werden. Darüberhinaus können auch festdefinierte Datensätze ausgetauscht werden die jedoch von den frei wählbaren unterschieden werden. Auf diesen Speicherbereich kann man asynchron von beiden Seiten Zugreifen, daher ist es zwingend definierte Flags zu benutzen um den Datenaustausch zu steuern. Über eine/mehrere Flag-Speicherstellen wird der Zustand des Speicherbereichs für beide Seiten gekennzeichnet. Damit läßt sich erkennen ob andere Seite die Daten entgegengenommen hat. Der Speicherbereich kann vier Zustände annehmen: - 0 = ungültig (unbeschrieben) - 1 = enthält Daten (beschrieben) - 2 = enthält geforderte Daten (beschrieben) - 3 = abgelehnt (beschrieben aber nicht entgegengenommen) Es müssen nicht alle Zustände im Betracht genommen werden, das hängt von den eigenen Bedürfnissen. Sollen nur Daten in eine Richtung weitergegeben werden, so reicht es nur den Speicherbereich zu beschreiben, als gültig zu erklären und warten bis er wieder ungültig wird um weiter beschreiben zu können. Die andere Seite wartet bis dieser Speicherbereich gültig wird, wertet aus und meldet als ungültig an. Sollten Parameter übergeben werden und die andere Seite darauf Ergebnisse liefern so liegt ein Datenaustausch in beide Richtungen vor. Es muß ein weiterer Zustand benutzt werden um Parameter von Ergebnissen unterscheiden zu können. Zusätzlich kann man auch noch den vierten Zustand nutzen falls erwünscht. Eine andere Vorgehensweise, z.B. direkter Zugriff auf bestimmte Variablen oder Felder wäre nicht flexibel genug, aufwendig auch im Gebrauch und vor allem bietet keinen Handshakemechanismus in sich. Trotzdem ist diese Beschreibung mehr oder weniger ein Vorschlag. Anregungen und Wünsche werden gerne entgegengenommen und falls möglich hinzugefügt. Seite 181
  • 182.
    - Datenaustausch vonder PC-Seite Struktur einer BITBUS Nachricht: +))))))))0)))))))0)))))))))0)))))))0)))))))))))))0))))))))), * * * * * Kommando * * * Länge * Flags * Adresse * Tasks * Rückmeldung * n Daten * .))))))))2)))))))2)))))))))2)))))))2)))))))))))))2)))))))))- Die Bedeutung der einzelner Felder ist genügend beschrieben worden z.B. im Buch: TSM für Softwareentwickler. Für diese Anwendung ist nur die Nutzung von Kommando/Rückmeldung und Daten Felder zu beschreiben. RAC-Kommandos um den Speicherbereich beschreiben/auslesen zu können: DOWNLOAD_MEM = 09h UPLOAD_MEM = 08h RAC-Kommandos um Zustand-Flag auslesen/setzen: READ_INTERNAL_MEM = 0Eh WRITE_INTERNAL_MEM = 0Dh Beispiel für Übergabe von vier Zahlenwerten, als 16 bit Integer Zahlen. Beispielweise sollen zwei Nachrichten dazu verwendet werden obwohl eigentlich eine ausreichen wurde. Die Beispielwerte 290,563,836,17493 lauten hexadezimal = 0122h, 0233h, 0344 und 4455h. Wegen der BITBUS-Spezifikation die die High-Low Bytefolge nutzt wird diese Folge auch bei diesen Anwendung genützt. Die beiden Nachrichten sollten also so aussehen: ... 09 0000 0122 0233 ;DOWNLOAD_MEM ab Offset=0000h die Werte 0122h und 0233 ... 09 0004 0344 4455 ;DOWNLOAD_MEM ab Offset=0004h die Werte 0344h und 4455h Jetzt sollte Zustand des Speicherbereichs als beschrieben angezeigt werden. ... 0D 00 01 ;WRITE_INTERNAL_MEM, Offset=0, Wert=1 Um weitere Daten zu übergeben sollte der zuvor gesetzte Zustandflag ausgelesen werden: ... 0E 00 ?? ;READ_INTERNAL_MEM, Offset=0, Wert=?? (nur Platzhalter) Antwort auf dieser Nachricht sollte wie folgt aussehen: ... 00 00 00 ; Okay, Daten übernommen und Quittiert ... 00 00 01 ; Daten immer noch nicht übernommen ... 00 00 02 ; MSR-Basic hat nicht nur die Daten übernommen, es sind auch ; Ergebniswerte vorhanden. Andere Antworten können nur beim fehlerhaften Betrieb entstehen. Erste Byte in der Antwort ist ein Responsebyte. Ist er ungleich 00, dann ist es Fehlerkennung. Sollte der Zustandflag = 02 sein (Ergebniswerte vorhanden) oder man will allgemein den Speicherbereich auslesen so kann die entsprechende Nachrichtso aussehen: Seite 182
  • 183.
    ... 08 0000???? ???? ???? ???? ;UPLOAD_MEM, Offset=0, 4*2 Byte Die Antwortnachricht könnte dann so aussehen: ... 00 0000 0122 0233 0344 4455 Die Bedeutung von übergebenen Daten und die Reihenfolge/Adressen sind dem Anwender überlassen und hängen von den aktuellen Bedürfnissen ab. Auf jeden Fall sollte der entsprechende Basic Programm diese Datenorganisation verstehen können. - Datenaustausch von der MSR-Basic Seite Die Auswertung der Daten von der MSR-Basic Seite läßt sich einfacher gestalten weil der BITBUS-Treiber fest integriert wird. Daher ist hier das Verständnis der BITBUS Kommunikation nicht von Bedeutung. Es werden Funktionen geboten die den Zustandflag abfragen/Setzen, und weitere Funktionen die Daten ab bestimmten Offset in Variablen übernehmen. Alle Funktionen mit Beschreibung: BITZFLAG Dieses Schlüsselwort ist eine Systemvariable die den Zustanflag enthält. Man kann diesen auslesen und auch setzten. Beispiel: 1000 WAIT FOR BITZFLAG <> 0 ' Warte bis Zustand sich ändert ' TASK/SEQ "schläft" so lange 1010 ........................' Daten übernehmen 1990 BITZFLAG = 0 ' Zustand auf ungültig ändern BITRB(offset) Gibt zurück den Wert eines Bytes. BITRW(offset) Gibt zurück den Wert eines 16-Bit Wortes. BITRH(offset) Gibt zurück den Wert eines 24-Bit Wortes. BITRS$(offset) Gibt zurück ein String. Ab offset soll ein String vorlegen der als erstes Byte die Stringlänge und alle folgende Bytes den String selber darstellen. BITWB(offset,var) Lege ab offset den Wert der Variable <var> als Byte Wert ab. BITWW(offset,var) Seite 183
  • 184.
    Lege ab offsetden Wert der Variable <var> als 16-Bit Wert ab. BITWH(offset,var) Lege ab offset den Wert der Variable <var> als 24-Bit Wert ab. BITWS$(offset,var$) Lege ab Offset den String <var$> ab.Beispiele für die obere Funktionen: 1000 var = BITRB(0) 1010 var = BITRW(1) 1020 var = BITRH(3) 1020 var$ = BITRS$(6) 2000 BITWB(0,var) 2010 BITWW(1,var) 2020 BITWH(3,var) 2030 BITWS$(6,var$) Seite 184
  • 185.
    11. Neue, zusätzlicheFunktionen a$ = FTOI$ (f) Wandelt eine Gleitkommazahl in Long-Integer Wert und gibt diese zurück als drei-Zeichen String. Die Reiihenfolge im String ist: LSB,MIDSB,MSB. Beispiele 100 a = (&H3132 * 256) + &H0033 ' Die Zahlen &H31,&H32 und &H33 ' sind in ASCII als Zeichen "1","2" ' und "3" definiert. 110 PRINT a ' ergibt 3224115.0000 120 PRINT FTOI$(a) ' wieder in Integer gewandelt und als ' Zeichen auf dem Schirm gebracht ' ergibt: "321" Es soll über LU (2) eine Zeichenfolge ausgegeben werden: <ESC>,'A',CHR$(ADC(nr) MOD 255), CHR$(ADC(nr) DIV 256) also der Wert von ADC(nr) soll als Escape-Sequenz in einem 2-Byte Integer Format ausgegeben werden. Das kann man in MSR-Basic auf folgende Weise tuen: 100 adcw$ = FTOI$(ADC(nr)) 110 PRINT ON(2) CHR$(&H1B);"A"; 120 PRINT ON(2) MID$(adcw$,1,2); a = FTOIB(f,nr) Wandelt eine Gleitkomazahl in ein 8-Bit Wert wobei angegeben wird welcher Byte (LSB, MIDSB oder MSB) gefragt wird. Oder anders formuliert, diese Funktion wäre gleich mit folgender Anweisung: a = INT((f / (256*(nr+1))) MOD 256) wenn MSR-Basic den Integer-Operator MOD gekannt hätte. Beispiel 100 a =(&H3132 * 256) + &H0033 110 PRINT FTOIB(a,0) AS 2H ' LSB, ergibt "33" 120 PRINT FTOIB(a,1) AS 2H ' MIDSB, ergibt "32" 130 PRINT FTOIB(a,2) AS 2H ' MSB. ergibt "31" Seite 185
  • 186.
    12. Programmerhalt Die Hardwarezum Speichererhalt wird seit Version 4.177 besser überwacht. Eine Meldung zeigt den Speicherausfall seit dem letzten Ausschalten. Dieser Ausfall kann nur unter zwei Bedingungen erfolgen: 1) Ein neuer RAM-Baustein wurde eingesetzt (alle ok, neu starten) 2) Es gibt ein Hardwareproblem (Batteriepufferung arbeitet nicht, Speicher ist defekt,...) Die bisherige Software hatte einen Schwachpunkt im Speichertest, wenn ein Netzteil mit langsam steigender Spannung eingesetzt wurde (sog. SoftStart-Netzteile) oder durch große Kondensatoren die Spannung beim Ausschalten sehr langsam abfiel. . Dabei gab es im Zeitpunkte, wo durch Brummspannung auf dem Netzteil die Power-Fail-Erkennung den Speicher freigab, weil die nötige Spannung erreicht war, diese aber gleich wieder abfiel, so daß undefinierte Betriebszustände auftraten. Jetzt wird durch eine Wartezeit eine stabile Arbeit erreicht. Seite 186