C 64/C 128
Tips & Tricks

Das Maß der Dinge

Das exakte Ausmessen eines Unterprogrammes ist eine große Hilfe, um Laufzeiten zu verringern. Meist steht jedoch keine hinreichend genaue Uhr zur Verfügung. Wir bieten Ihnen zwei Lösungen an, eine für Maschinensprache- und eine für Basic-Programme.

Um die Laufzeiten von Programmen genau messen zu können, reicht die Stoppuhr für den 100-Meter-Lauf nicht mehr aus. Vor allem bei Maschinenprogrammen, bei denen die menschliche Reaktionsfähigkeit weit hinter der geforderten Genauigkeit bleibt. Doch auch die eingebaute interruptgesteuerte Uhr TI$ im C 64 versagt, wenn es um das Auszählen sehr kurzer Maschinenprogramme geht. Ladevorgänge können damit überhaupt nicht erfaßt werden, da TI$ während des Ladens stillsteht. Abhilfe schaffen hier die Timer der CIAs.

Taktzyklen zählen

Um Maschinensprache-Programme zu messen, ist es am besten, die Taktzyklen zu zählen. Dies liefert einen gut zu vergleichenden Wert. Geben Sie zunächst das Programm »Taktzyklen« (Listing 1) mit dem MSE ein und speichern Sie es. Aufgerufen wird die Routine durch den Befehl SYS49152,Startadresse

Die anzugebende Startadresse entspricht der des zu untersuchenden Maschinenprogrammes. Dieses Unterprogramm wird nun ausgeführt und die dafür benötigte Zeit bestimmt. Während dieses Ablaufes ist der Bildschirm ausgeblendet, er nimmt die Farbe des Rahmens an. Am Ende des zu messenden Programmes muß ein RTS stehen. Nach Programmende gibt das Programm den gemessenen Wert aus und springt in den Direkt-(READY.-)Modus. Der angezeigte Zahlenwert drückt die Anzahl der Systemtakte aus, die während der Abarbeitung des Maschinen-Unterprogrammes durch den Mikroprozessor verstrichen sind. Da ein solcher Takt etwa 1,015 Mikrosekunden dauert, läßt sich durch Multiplizieren mit diesem Faktor die benötigte Zeit in Mikrosekunden errechnen. Bei eingeschaltetem Bildschirm vergrößert sich das Ergebnis um etwa 5 bis 6 Prozent.

Beschreibung des Programms »Taktzyklen«

Die beim Aufruf des Programms übergebene Startadresse des zu messenden Unterprogramms wird als Operand für einen Sprungbefehl gespeichert. Anschließend wird die Möglichkeit der Unterbrechung durch einen IRQ ausgeschaltet, weil sonst ein falsches Resultat geliefert werden kann. Nach dem Ausblenden des Bildschirms lädt das Programm beide Timer des CIA 2 mit dem Maximalwert und koppelt sie miteinander. Sobald die Zähler gestartet sind, erfolgt der Sprung in das Unterprogramm, nach dessen Ende die Zähler sofort wieder gestoppt werden. Schließlich werden neben der Einrichtung des Normalzustandes — den Bildschirm und den IRQ betreffend — die Timer-Bytes ausgewertet. Dazu invertiert das Programm sämtliche Bits der von den Timern gelieferten Werte, da beide Registerpaare heruntergezählt werden. Zusätzlich werden noch elf Takte subtrahiert, die zum Starten beziehungsweise Stoppen der Timer und zum Aufruf des Unterprogramms nötig sind. Damit erhält man einen Meßbereich, der zwischen 1 und 232-11 Taktzyklen (entsprechend einer Zeit von 1 µs bis 1 Stunde 12 Minuten) liegt.

Laufzeit-Meß-System »LMS«

Das LMS wurde entwickelt, um die Laufzeit von Basic-Programmen zeilenbezogen messen zu können. Weiterhin sollte die Anzahl einzelner Aufrufe von Programmzeilen festgestellt werden können.

Einsatzmöglichkeiten

Das LMS ist im wesentlichen als Werkzeug für folgende Anwendungsfälle konzipiert.
1. Performance-Verbesserung von Basic-Programmen

Durch den Einsatz des LMS ist sofort erkennbar, wo die zeitmäßig kritischen Stellen eines Programms sind. Oft kann durch einige Veränderungen von Basic-Statements wertvolle Laufzeit eingespart werden. Sollte das nicht ausreichen, so ist der Einsatz von Maschinenroutinen angebracht.

Die Erfahrung zeigt, daß es selten notwendig ist, ein Programm vollständig in Assembler zu schreiben. Meist bringt ein begrenzter Einsatz von Maschinenroutinen an zeitkritischen Stellen ausreichende Geschwindigkeit unter Beibehaltung der Vorteile von Basic. Diese sind vor allem wesentlich bessere Lesbarkeit und Wartung sowie geringerer Erstellungsaufwand .
2. Testhilfe

Das Laufzeit-Meß-System stellt die Anzahl der Aufrufe von Basic-Zeilen fest. Es ist daher damit leicht überprüfbar, ob Programmzeilen überhaupt durchlaufen werden und wenn ja, ob die Anzahl der Aufrufe stimmt.

Mit dem LMS können auch Statements gemessen werden, die mit TI$ — abgesehen von der geringen Genauigkeit von TI$ — zu erfassen sind (zum Beispiel INPUT#).

Bedienungsanleitung

Geben Sie zuerst die Listings 3 bis 5 ein und speichern Sie diese auf einer Diskette. Nach dem Laden und Starten des Programms »LMS« erscheint nach kurzer Zeit ein Menü mit folgenden Wahlmöglichkeiten:

Messen (m)

Durch die Auswahl der Funktion »Messen« wird das eigentliche Meßprogramm aktiviert. Dies ist immer erkennbar an der roten Rahmenfarbe. Es wird eine Einschaltmeldung geschrieben und danach in den READY-Modus verzweigt. Jetzt muß das zu messende Programm eingegeben oder geladen werden.

Bei jedem Start des Programms werden für jede Programmzeile Laufzeit und Aufrufanzahl gespeichert. Wichtig ist, daß das Programm mit RUN gestartet wird. Ein Start mit GOTO oder CONT ist möglich, führt aber nicht zur Messung.

Durch die Eingabe von END im READY-Modus wird das Meßprogramm interaktiv, und es verzweigt anschließend wieder zum Hauptmenü, in dem die Meßergebnisse des letzten Programmlaufs ausgewertet werden können.

Anzeige ab Nr. (a)

Diese Funktion gestattet die Eingabe einer Zeilennummer, ab der die Meßergebnisse am Bildschirm angezeigt werden.

Der Bildschirm zeigt die jeweilige Zeilennummer, die Anzahl der Aufrufe dieser Zeile und die Gesamtverweilzeit des Basic-Interpreters in dieser Zeile. Bei einer Aufrufanzahl größer als eins wird zusätzlich die durchschnittliche Laufzeit pro Aufrufangezeigt.

Die jeweils größte Laufzeit ist zur leichteren Orientierung durch »*-« markiert.

Vorhergehende Seite (↑)

Durch Drücken der Taste (t) wird die Ausgabe am Bildschirm um eine Seite zurückgeblättert.

Nächste Seite (RETURN)

Die Bildschirmausgabe wird mit »RETURN« um eine Seite weitergeblättert.

Summe (s)

Diese Funktion erlaubt die Berechnung der Programmlaufzeit bezogen auf einen einzugebenden Zeilenbereich.

Drucken(d)

Die Auswahl dieser Funktion bewirkt die Ausgabe der Meßergebnisse auf Drucker. Durch die Angabe von Zeilennummern kann der Ausgabebereich eingegrenzt werden.

Hilfe (h)

Das Menü wird angezeigt.

Ende (e)

Der Computer wird nach Bestätigung der Auswahl in den Einschaltzustand versetzt.

Wird bei der Eingabe einer Zeilennummer nur »RETURN« gedrückt, so wird die Zeilennummer ab inklusive 0 und die Zeilennummer bis inklusive 63999 angenommen.

Hinweise

Das Meßverfahren kann auf Programme mit bis zu 1022 Zeilen angewandt werden. Der Basic-Speicher ist auf zirka 30 KByte verkürzt. Die maximal erfaßbare Anzahl von Zeilenaufrufen beträgt 65535. Die maximal meßbare Laufzeit pro Zeile beträgt etwa 72 Minuten.

Wenn das LMS aktiviert ist, braucht es etwa 0,9 Millisekunden (ms) pro Zeilenaufruf. Dies führt zu einer Verlängerung der Programmlaufzeit während der Messung. Die Meßergebnisse sind jedoch Netto-Laufzeiten; das heißt die angezeigten Zeiten entsprechen den Laufzeiten ohne Meßprogramm. Es ist zu beachten, daß Programmschleifen innerhalb einer Basic-Zeile vom LMS nicht erkannt werden. Dies liegt an der zeilenorientierten Arbeitsweise des LMS.
10 GET A$: IF A$="" THEN 10
ergibt als Anzahl der Aufrufe der Zeile 10 die Zahl 1.

Um die exakte Aufrufanzahl zu erhalten, muß die Zeile geteilt werden.
10 GET A$
20 IFA$="" THEN 10
ergibt die genaue Anzahl der Aufrufe.

Die gleiche Vorgangsweise ist auch für Zeilen angebracht, in denen nach einem GOSUB noch weitere Statements folgen. In diesem Fall wird nämlich nach der Rückkehr vom Unterprogramm die Aufrufanzahl der Zeile um 1 erhöht. Die ausgewiesene durchschnittliche Laufzeit ist in diesem Fall mit Vorsicht zu genießen.

Im Rahmen von mehreren Messungen an einem Programm treten in der Regel unterschiedliche Laufzeiten für dieselben Statements auf. Diese zunächst etwas verblüffende Feststellung hat ihre Ursache darin, daß für die Abarbeitung eines Basic-Befehls nicht immer die gleiche Anzahl von Instruktionen durchlaufen wird. Dies ergibt sich zum Beispiel durch Bildschirm-Scrolling, Interrupt-Behandlung oder Garbage Collection. Bei der Festlegung der Meßgenauigkeit wurde diese Tatsache berücksichtigt; das heißt nicht aussagekräftige Dezimalstellen wurden weggelassen.

Das LMS funktioniert nicht mit Programmen

— die den vom LMS belegten Speicher benötigen ($8000 bis $9FFF und $D000 bis $FFFF; siehe auch Programmbeschreibung),
— die Basic-Zeilen generieren oder
— die den NMI-Timer verwenden (zum Beispiel RS232-Programme).

Programmbeschreibung

Das Laufzeit-Meß-System besteht aus dem Maschinenprogramm »LMS.PHA« und den Basic-Programmen »LMS« und »LMS.BAS.«. »LMS.PHA« ist das eigentliche Meßprogramm. Es liegt im Speicherbereich $9CE0 bis $9FFF und wird bei seiner Aktivierung in die Basic-Interpreterschleife eingebunden. Für die Zeitmessung wird der Timer im CIA2 benutzt. Als Zeitbasis wird der Systemtakt verwendet. Die Meßergebnisse werden im RAM ab $D000 unter dem Betriebssystem abgelegt.

Der Ablauf einer Messung kann dem Flußdiagramm (siehe Bild 1) beziehungsweise dem Listing »LMS.ASS« entnommen werden. Die Aufbereitung und Auswertung der Meßergebnisse erfolgt im Programm »LMS.BAS«. Um ein abwechselndes Laden des in Basic geschriebenen Auswerteprogramms und des zu messenden Programms zu vermeiden, wird der Basic-Speicher derart geteilt, daß beide Programme gleichzeitig geladen sein können. LMS.BAS muß sich dabei mit weniger als 8 KByte ab Adresse $8000 begnügen.

Bild 1. Flußdiagramm zum Laufzeit-Meß-System »LMS«. Nach diesem Schema berechnet man die Laufzeit eines Basic-Programms.

Die Umschaltung des Basic-Speichers erfolgt in »LMS.PHA«. Beim Aktivieren des Meßprogramms wird das zu messende Programm zur Verfügung gestellt, beim Desaktivieren wird zum Auswerteprogrammm verzweigt.

Das Ladeprogramm »LMS« lädt zunächst »LMS.PHA«, damit die Maschinenroutinen zur Verfügung stehen. Danach teilt und initialisiert das Programm den Basic-Bereich. Zuletzt lädt und startet es das Auswerteprogramm.

Die Anpassung von »LMS.BAS« an unterschiedliche Drucker ist problemlos, da außer der Sekundäradresse 7 keine speziellen Steuercodes verwendet wurden.

Für die Verwendung mit Datassette müssen die im Programmlisting LMS enthaltenen Hinweise beachtet werden.

(Mark Richters/Franz Stoiber/og)
PROGRAMM : TAKTZYKLEN     C000 C063
-----------------------------------
C000 : 20 FD AE 20 8A AD 20 F7   55
C008 : B7 8C 2F C0 8D 30 C0 78   38
C010 : A9 0B 8D 11 D0 AD 12 D0   29
C018 : D0 FB A2 03 A9 FF 9D 04   08
C020 : DD CA 10 FA A9 11 A2 51   16
C028 : 8E 0F DD 8D 0E DD 20 FF   B7
C030 : FF A0 00 8C 0E DD 8C 0F   31
C038 : DD A9 1B 8D 11 D0 58 38   CC
C040 : AD 04 DD 49 FF E9 0B 85   16
C048 : 65 A2 03 B9 05 DD 49 FF   5B
C050 : E9 00 95 61 C8 CA D0 F3   D9
C058 : 38 8A A2 A0 20 4F BC 4C   9A
C060 : D7 01 08                  D6
Listing 1. »Taktzyklen« geben Sie bitte mit dem MSE ein.
SYS9*4096
.OPT OO
;
;
; TAKTZYKLEN EINES
; MASCHINENPROGRAMMS MESSEN
;
;
; VON  MARK RICHTERS
;      ALLERSTR.4
;      2806 OYTEN
;      TEL. 04207/1870
;
;
*=$C000
;
FAC      =$62   ;FLIESSKOMMA-AKKU
FRMNUM   =$AD8A ;AUSDRUCK HOLEN
CHKCOM   =$AEFD ;AUF KOMMA PRUEFEN
GETADR   =$B7F7 ;2-BYTE INTEGER
VICCTRL  =$D011 ;REG. FUER BS AUS
RASTER   =$D012 ;RASTER-ZEILE
TIMER    =$DD04 ;TIMER A LO-BYTE
CRA      =$DD0E ;TIMER A CONTROL
CRB      =$DD0F ;TIMER B CONTROL
;---------------
JSR CHKCOM      ;STARTADRESSE DER
JSR FRMNUM      ;ZU MESSENDEN
JSR GETADR      ;ROUTINE HOLEN
STY JSUBR+1     ;UND ALS SPRUNG-
STA JSUBR+2     ;ADRESSE SPEICHERN
;
SEI             ;IRQ SPERREN
LDA #%00001011  ;BILDSCHIRM AUS
STA VICCTRL
WAIT LDA RASTER ;WARTEN BIS BILD-
BNE WAIT        ;SCHIRM GANZ AUS
;
LDX #3          ;BEIDE TIMER AUF
LDA #$FF        ;MAXIMALWERT
SETTIMER STA TIMER,X
DEX
BPL SETTIMER
;
LDA #%00010001  ;TIMER KOPPELN,
LDX #%01010001  ;LADEN UND STARTEN
STX CRB
STA CRA
;---------------
JSUBR JSR $FFFF ;SPRUNG AUF ROUTINE
;---------------
LDY #0          ;BEIDE TIMER STOP
STY CRA
STY CRB
LDA #%00011011  ;BILDSCHIRM WIEDER
STA VICCTRL     ;AN
CLI             ;IRQ WIEDER FREI-
;
SEC             ;4 TIMER-BYTES
LDA TIMER       ;UMRECHNEN
EOR #$FF        ;FUER AUFRUF BE-
SBC #11         ;NOETIGTE ZYKLEN
STA FAC+3       ;ABZIEHEN
LDX #3          ;UND DIE RESTLICHEN
;
L1 LDA TIMER+1,Y;3 TIMER-WERTE
EOR #$FF        ;ANPASSEN
SBC #0
STA FAC-1,X
INY
DEX
BNE L1
;
SEC
TXA             ;4 BYTE WERTEN
LDX #$A0        ;OHNE VORZEICHEN
JSR $BC4F       ;IN FLIESSKOMMAZAHL
JMP $BDD7       ;FAC AUSGEBEN/RTS
Listing 2. Information für Profis. Quell-Code-Listing zu »Taktzyklen«
100 rem ----------- laufzeit-mess-system
110 rem --------------------ladeprogramm
120 rem --------------------------------
130 rem -------------- (c) franz stoiber
140 rem ------------- braeunlichgasse 30
150 rem ------------- a-2700 wr.neustadt
160 rem --------------------- oestereich
170 rem --------------------------------
180 if l=1 then 260
190 poke 53280,15: poke 53281,15: poke 646,6
200 ga=8
210 print chr$(14);"{clr}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{rght}{rght}{rght}{rght}{rght}{rght}Laufzeit-Mess-System  V2.0"
220 print "{rght}{rght}{rght}{rght}{rght}{rght}{rght}(c) Franz Stoiber  11/85"
230 print "{down}{down}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}Bitte warten"
240 poke 646,15
250 l=1: load "lms.pha",ga,1
260 sys 40698
270 print "{home}";
280 print "{down}{down}sys 40780"
290 print "{down}{down}load ";chr$(34);"lms.bas";chr$(34);",";ga
300 print "{down}{down}{down}{down}run"
310 for i=631 to 633: poke i,13: next
320 poke 198,3
330 print "{home}";
340 rem --------------------------------
350 rem fuer das arbeiten mit datassette
360 rem sind folgende zeilen zu aendern:
370 rem
380 rem *** 200 ga=1
390 rem *** 210 entfaellt
400 rem *** 220 entfaellt
410 rem *** 230 entfaellt
420 rem *** 240 poke 646,0
430 rem *** 270 print "{clr}";
440 rem *** 300 print "{down}{down}{down}{down}{down}run"
450 rem
460 rem --------------------------------
470 rem am band muessen die programme
480 rem in der reihenfolge
490 rem
500 rem lms, lms.pha, lms.bas
510 rem
520 rem gespeichert werden.
Listing 3. Das Ladeprogramm »LMS« geben Sie bitte mit dem Checksummer V 3 (Ausgabe 3/86, Seite 55) ein.
PROGRAMM : LMS.PHA        9CE0 9FF4
-----------------------------------
9CE0 : 20 E1 9E A9 83 A2 9F 85   A4
9CE8 : F9 86 FA A2 53 20 C3 9E   BA
9CF0 : AD 08 03 8D DC 9F AD 09   A7
9CF8 : 03 8D DD 9F A9 0C 8D 08   6E
9D00 : 03 A9 9D 8D 09 03 20 67   E9
9D08 : 9F 4C 74 A4 20 E1 9E A5   56
9D10 : 9D F0 03 4C 7B 9D AD 0E   E7
9D18 : DD 29 FE 8D 0E DD AD 0F   A0
9D20 : DD 29 FE 8D 0F DD A5 39   EC
9D28 : CD D6 9F D0 07 A5 3A CD   84
9D30 : D7 9F F0 32 AD D7 9F C9   05
9D38 : FF F0 03 20 80 9E A5 39   7A
9D40 : 8D D6 9F A5 3A 8D D7 9F   84
9D48 : A9 FF 8D 04 DD 8D 05 DD   EF
9D50 : 8D 06 DD 8D 07 DD AD 0E   3C
9D58 : DD 29 D7 8D 0E DD AD 0F   16
9D60 : DD 29 D7 8D 0F DD 78 AD   96
9D68 : 0E DD 09 01 8D 0E DD AD   E3
9D70 : 0F DD 09 41 8D 0F DD 58   52
9D78 : 4C E4 A7 20 73 00 C9 80   84
9D80 : F0 0A C9 8A D0 03 20 B6   4C
9D88 : 9D 4C 3D 9E 20 67 9F AD   86
9D90 : DC 9F 8D 08 03 AD DD 9F   F5
9D98 : 8D 09 03 A9 52 8D 77 02   13
9DA0 : A9 55 8D 78 02 A9 4E 8D   28
9DA8 : 79 02 A9 0D 8D 7A 02 A9   36
9DB0 : 04 85 C6 6C 02 03 20 43   F5
9DB8 : 9E AD 02 03 8D DA 9F AD   97
9DC0 : 03 03 8D DB 9F A9 CF 8D   C5
9DC8 : 02 03 A9 9E 8D 03 03 A9   DA
9DD0 : FF 8D D6 9F 8D D7 9F A9   A9
9DD8 : 00 85 FD A9 D0 85 FE A0   C6
9DE0 : 00 B9 7B 9F 91 FD C8 C0   3D
9DE8 : 08 D0 F6 A5 2B 85 FB A5   E5
9DF0 : 2C 85 FC 20 B5 9E A0 00   F5
9DF8 : B1 FB 8D D8 9F C8 B1 FB   24
9E00 : 8D D9 9F D0 12 AD D8 9F   AD
9E08 : D0 0D A9 FF A0 00 91 FD   15
9E10 : C8 91 FD 20 4D 9E 60 A0   B1
9E18 : 02 B1 FB A0 00 91 FD A0   CB
9E20 : 03 B1 FB A0 01 91 FD A9   F7
9E28 : 00 C8 91 FD C0 07 D0 F9   2C
9E30 : AD D8 9F 85 FB AD D9 9F   B6
9E38 : 85 FC 4C F3 9D 20 79 00   8E
9E40 : 4C E7 A7 48 78 A5 01 29   7E
9E48 : FC 85 01 68 60 48 A5 01   35
9E50 : 09 03 85 01 58 68 60 A9   FA
9E58 : 00 85 FD A9 D0 85 FE 20   45
9E60 : 43 9E D8 20 B5 9E A0 01   01
9E68 : B1 FD CD D7 9F D0 0C 88   48
9E70 : B1 FD CD D6 9F D0 04 20   3F
9E78 : 4D 9E 60 B0 FA 4C 63 9E   1F
9E80 : 20 57 9E 20 43 9E A0 02   A7
9E88 : 18 B1 FD 69 01 91 FD C8   4B
9E90 : B1 FD 69 00 91 FD 18 C8   95
9E98 : 20 4D 9E B9 00 DD 49 FF   52
9EA0 : 20 43 9E 71 FD 08 91 FD   9A
9EA8 : C0 07 F0 04 28 4C 97 9E   29
9EB0 : 28 20 4D 9E 60 18 A9 08   8D
9EB8 : 65 FD 85 FD A9 00 65 FE   6B
9EC0 : 85 FE 60 A0 00 B1 F9 20   A6
9EC8 : 16 E7 C8 CA D0 F7 60 20   EC
9ED0 : 80 9E AD DA 9F 8D 02 03   DA
9ED8 : AD DB 9F 8D 03 03 6C 02   0A
9EE0 : 03 A9 02 8D 20 D0 60 20   34
9EE8 : 43 9E A0 00 B1 FD 99 DE   D2
9EF0 : 9F C8 C0 08 D0 F6 20 4D   04
9EF8 : 9E 60 20 43 9E A9 00 8D   89
9F00 : 00 D0 20 4D 9E 60 20 FD   83
9F08 : AE 20 9E B7 8A 48 20 FD   CC
9F10 : AE 20 9E B7 68 A8 18 20   D9
9F18 : F0 FF 20 FD AE 4C A4 AA   05
9F20 : A9 00 8D 00 08 A9 01 85   0A
9F28 : 2B A9 08 85 2C A9 00 85   F6
9F30 : 37 A9 80 85 38 60 A9 00   3A
9F38 : 8D 00 80 A9 01 85 2B A9   57
9F40 : 80 85 2C A9 E0 85 37 A9   2D
9F48 : 9C 85 38 60 20 20 9F 20   83
9F50 : 44 A6 A2 00 B5 2B 9D E6   89
9F58 : 9F E8 E0 0E D0 F6 20 36   17
9F60 : 9F 20 44 A6 4C 74 A4 A2   35
9F68 : 00 BD E6 9F 48 B5 2B 9D   0E
9F70 : E6 9F 68 95 2B E8 E0 0E   8C
9F78 : D0 EF 60 4C 4D 53 2D 46   92
9F80 : 2E 53 2E 0D 4C 41 55 46   36
9F88 : 5A 45 49 54 2D 4D 45 53   5B
9F90 : 53 2D 53 59 53 54 45 4D   01
9F98 : 20 20 56 32 2E 30 20 20   C9
9FA0 : 31 31 2F 38 35 0D 28 43   20
9FA8 : 29 20 46 52 41 4E 5A 20   ED
9FB0 : 53 54 4F 49 42 45 52 0D   DC
9FB8 : 11 52 55 4E 20 2D 20 4D   98
9FC0 : 45 53 53 45 4E 0D 45 4E   2B
9FC8 : 44 20 2D 20 41 55 53 57   26
9FD0 : 45 52 54 45 4E 0D 00 00   49
9FD8 : 00 00 00 00 00 00 00 00   D9
9FE0 : 00 00 00 00 00 00 00 00   E1
9FE8 : 00 00 00 00 00 00 00 00   E9
9FF0 : 00 00 00 00               10
Listing 4. Das Maschinenprogramm »LMS.PHA« bitte mit dem MSE eingeben.
100 rem ------ lms-auswerteprogramm v2.0
101 rem ------- 11/85  (c) franz stoiber
110 print chr$(14);chr$(8): poke 808,225: zf=6
120 e$="{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*} Ende {SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}"
130 poke 53280,15: poke 53281,15: poke 646,zf: gosub 1440
140 bl$="                                        "
150 ra=53248: pu=253: l=22: cl=985.248: r=.05
160 k0=2^8: k1=2^16: k2=2^24: k3=2^32: k4=k1-1: k5=63999: k6=10
170 rd=40679: at=40710: ab=40535: nr=40918
180 p1=40926: p2=p1+1: p3=p1+2: p4=p1+3: p5=p1+4: p6=p1+5: p7=p1+6: p8=p1+7
200 j=0: k=80: p=ra
210 kz$="      Nr   Anz        msek    msek/Anz"
220 sys at,6,5,"Messung ..............   m"
230 sys at,6,7,"Anzeige ab Nr ........   a"
240 sys at,6,9,"Vorhergehende Seite ..   ^"
250 sys at,6,11,"Naechste Seite ....... return"
260 sys at,6,13,"Summe ................   s"
270 sys at,6,15,"Drucken ..............   d"
280 sys at,6,17,"Hilfe ................   h"
290 sys at,6,19,"Ende .................   e"
300 poke 198,0: sys at,0,24,"{rvon}    Weiter mit: m/a/^/return/s/d/h/e   {rvof}";
310 poke 2023,160: poke 56295,zf
320 get a$: if a$="" then 320
330 if a$="m" then 430
340 if a$="a" then 450
350 if a$="^" then 490
360 if a$=chr$(13) then 540
370 if a$="s" then 570
380 if a$="d" then 720
390 if a$="h" then 1010
400 if a$="e" then 1030
410 goto 300
420 rem ------------------------ messung
430 poke 808,237: print chr$(9);"{clr}";: sys 40160
440 rem --------------------- anzeige ab
450 gosub 1930: if f then 300
460 gosub 1440: gosub 1480
470 p=p-8: gosub 1130: goto 300
480 rem ------------------------ zurueck
490 gosub 1930: if f then 300
500 p=p-(zz+l-1)*8
510 if p<ra then p=ra
520 gosub 1130: goto 300
530 rem ---------------------------- vor
540 gosub 1930: if f then 300
550 gosub 1130: goto 300
560 rem -------------------------- summe
570 gosub 1930: if f then 300
580 gosub 1440
590 sys at,5,4,"Summe": sys at,5,5,"{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}"
600 gosub 1480: gosub 1580
610 p=p-8: s=0
620 gosub 1080
630 if z>zb then 670
640 gosub 1370
650 s=s+t: sys at,30,10,z
660 goto 620
670 sys at,30,10,"      "
680 t=s: t$="": gosub 1400
690 sys at,5,17,"Summe =";t$;" msek"
700 p=ra: goto 300
710 rem ------------------------ drucken
720 gosub 1930: if f then 300
730 gosub 1440
740 sys at,5,4,"Drucken": sys at,5,5,"{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}"
750 gosub 1480: gosub 1580: p=p-8: s=0
760 sys at,5,15,"Drucker O.K. ?"
770 sys at,5,16,"Weiter mit beliebiger Taste"
780 poke 198,0: wait 198,1: poke 198,0
790 open 4,4,7: poke 768,185: print#4,"";: poke 768,139
800 if st then sys at,8,22,"{rvon} Drucker nicht bereit {rvof}": close 4: goto 300
810 if k<80 then pl$="": gosub 1830: goto 830
820 sys at,0,15,bl$;: sys at,0,16,bl$;
830 f=0: pl$=""
840 gosub 1080
850 if z>zb then 960
860 gosub 1320
870 gosub 1370
880 s=s+t: t$="": b$="            "
890 gosub 1400
900 if az<2 then 920
910 b$="": t=t/az: az=0: goto 890
920 pl$=pl$+"  "+z$+az$+t$+b$
930 if f=0 then f=1: goto 840
940 gosub 1830
950 goto 830
960 if f then gosub 1830
970 t=s: t$="": gosub 1400
980 pl$="       Summe ="+t$+" msek": gosub 1830
990 close 4: p=ra: goto 300
1000 rem ------------------------- hilfe
1010 gosub 1440: goto 220
1020 rem -------------------------- ende
1030 gosub 1440: sys at,5,13,"Bitte Ende bestaetigen (j/n): {rvon} {rvof}";
1040 get a$: if a$="" then 1040
1050 if a$="j" then sys at,35,13,"j": sys 64738
1060 sys at,0,13,bl$;: goto 220
1070 rem ----------  werte aus ram lesen
1080 p=p+8: ph=int(p/k0): pl=p-ph*k0
1090 poke pu,pl: poke pu+1,ph: sys rd
1100 z=peek(p1)+peek(p2)*k0
1110 return
1120 rem -----------  ausgabe bildschirm
1130 print "{clr}{rvon}    Nr   Anz        msek    msek/Anz    "
1140 m1=0: m2=0: c1$=" ": c2$=" "
1150 for zz=1 to l
1160 :gosub 1080
1170 :if z=k4 then p=p-8: print e$;: goto 1280
1180 :gosub 1320
1190 :gosub 1370
1200 :if t>m1 then m1=t: l1=zz: c1$="_"
1210 :t$=""
1220 :gosub 1400
1230 :if az<2 then 1260
1240 :t=t/az: if t>m2 then m2=t: l2=zz: c2$="_"
1250 :az=0: goto 1220
1260 :print z$;az$;t$
1270 next
1280 if c1$="_" then sys at,24,l1+1,c1$;
1290 if c2$="_" then sys at,36,l2+1,c2$;
1300 return
1310 rem ----------  aufbereitung nr,anz
1320 z$=right$("     "+str$(z),6)
1330 az=peek(p3)+peek(p4)*k0
1340 az$=right$("     "+str$(az),6)
1350 return
1360 rem ---------------  zeit errechnen
1370 t=(peek(p5)+peek(p6)*k0+peek(p7)*k1+peek(p8)*k2)/cl
1380 return
1390 rem ------------  aufbereitung zeit
1400 tr=t+r: th=int(tr): tl=int((tr-th)*k6)
1410 t$=t$+right$("         "+str$(th),10)+"."+right$(str$(tl),1)
1420 return
1430 rem -------------------  kopfzeilen
1440 print "{clr}{rvon}  Laufzeit  -  Mess  -  System   V2.0   ";
1450 print "{rvon}  (c) 11/85 {$a0}Franz Stoiber              "
1460 return
1470 rem ----------  eingabe zeilennr ab
1480 ro=8: sys at,5,ro,"Ab Nr  ?  ";: gosub 1650
1490 if a$="     " then za=0: sys at,14,ro,za: goto 1520
1500 za=val(a$): if za<=k5 then sys at,0,22,bl$;: goto 1520
1510 sys at,6,22,"{rvon}    Zeilennummer zu gross    {rvof}";: goto 1480
1520 zh=int(za/k0): zl=za-zh*k0: poke nr,zl: poke nr+1,zh
1530 sys ab: p=peek(pu)+peek(pu+1)*k0
1540 p=p-8: gosub 1080
1550 if z<k4 then return
1560 sys at,6,22,"{rvon} Zeilennummer nicht gefunden {rvof}";: goto 1480
1570 rem ---------  eingabe zeilennr bis
1580 ro=10: sys at,5,ro,"Bis Nr ?  ";: gosub 1650
1590 if a$="     " then zb=k5: sys at,14,ro,zb: return
1600 zb=val(a$): if zb>=za then 1620
1610 sys at,5,22,"{rvon}  Zeilennr bis < Zeilennr ab  {rvof}";: goto 1580
1620 if zb>k5 then zb=k5
1630 sys at,0,22,bl$;: return
1640 rem ----------------  zahl eingeben
1650 n=1: rc=1024+14+40*ro: co=rc+54272: poke 198,0
1660 for i=1 to 5: poke co+i,zf: next
1670 if n>5 then n=5
1680 if n<1 then n=1
1690 po=rc+n: poke po,peek(po)+128
1700 get c$: if c$="" then 1700
1710 if c$>="0" and c$<="9" then poke po,asc(c$): n=n+1: goto 1670
1720 if c$=chr$(157) then poke po,peek(po)-128: n=n-1: goto 1670
1730 if c$=chr$(29) then poke po,peek(po)-128: n=n+1: goto 1670
1740 if c$=chr$(20) then sys at,15,ro,"     ";: goto 1650
1750 if c$=chr$(13) then poke po,peek(po)-128: goto 1770
1760 goto 1700
1770 a$=""
1780 for i=1 to 5
1790 :a$=a$+chr$(peek(rc+i))
1800 next
1810 return
1820 rem ----------------  zeile drucken
1830 if k<68 then 1900
1840 if k<73 then print# 4,"": k=k+1: goto 1840
1850 j=j+1: print# 4,"": print# 4,""
1860 print# 4,"   Laufzeit - Mess - System  V2.0";
1870 print# 4,"     (c) Franz Stoiber 11/85      Seite: ";right$(str$(j+100),2)
1880 print# 4,"": print# 4,"": print# 4,kz$;kz$: print# 4,""
1890 k=8
1900 print# 4,pl$: k=k+1
1910 return
1920 rem -------------- test auf messung
1930 pp=p: f=0: p=ra-8: a$=""
1940 gosub 1080
1950 for i=p1 to p8: a$=a$+chr$(peek(i)): next
1960 if a$="lms-f.s." then 1990
1970 sys at,6,22,"{rvon} Keine Messung gelaufen ! {rvof}"
1980 f=1: return
1990 gosub 1080
2000 if z<k4 then p=pp: return
2010 sys at,6,21,"{rvon} Waehrend der Messung war "
2020 sys at,6,22,"{rvon}  kein Programm geladen!  {rvof}"
2030 goto 1980
Listing 5. Das Auswertungsprogramm »LMS.BAS«
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →