ReingeVALlen

(wer lesen kann, ist klar im Vorteil)

 



 

Auf der Diskette zum Klubtreffen 2020 haben wir ein BasiCode-Programm, das kurze Musikstücke als Noten anzeigen und abspielen kann. Zu diesem gehören drei Beispieldateien, die im Hex-Editor betrachtet so aussehen (siehe Screenshot rechts: Die Codes für die Trennung der Einträge voneinander habe ich für bessere Lesbarkeit durch einen kleinen Winkel ersetzt).

 

 

 
 

Natürlich wollte ich es auch mit Michaels Java-BasiCode-Interpreter testen, doch dort brach das Programm ab, wenn die Noten gezeichnet waren und das Abspielen mit "S" gestartet werden sollte. Wo lag das Problem? Das Programm schien in Ordnung zu sein, es lief schließlich bisher auf allen (emulierten) Computern, die ich ausprobiert hatte. Deswegen bekam Michael die Sache als Fehlerbericht (ich beherrsche leider kein Java). Er schrieb zurück, dass eine Zeichenkette "b4" nicht ausgewertet werden könne. Im Programm fand ich keine solche Zeichenkette - aber in den Musikdaten (im Bild oben markiert). Im Programm ist die Zeile 5110, wo es “knallt“ (siehe Listing links).
 

In Zeile 5020 wird geprüft, ob ein Leerstring vorliegt (dann wird beim Zeichnen er Noten eine Lücke erzeugt). Wenn das nicht der Fall ist, wird ab Zeile 5110 die in NO$ verschlüsselte Note in die Werte für Höhe, Länge und Lautstärke zurückverwandelt und der Ton durch den Aufruf in Zeile 5140 abgespielt.

Schauen wir in die Daten, sehen wir, dass als erstes nach dem Titel des Musikstücks der Wert "b44" eingelesen wird (er steht für b [oder #] und die Taktangabe am Anfang der ersten Notenzeile). In Zeile 5110 wird (das oben erwähnte) "b4" abgespalten und daraus soll der Zahlenwert für die Tonhöhe gebildet werden. Die Java-Fehlermeldung entsteht dadurch, dass das erste Zeichen keine Ziffer ist - also liegt der Fehler doch im Programm und nicht im Bascoder!

Warum bricht aber das Programm in anderen Interpretern nicht auch an dieser Stelle ab? Hätte ich mich an den bekannten Spruch "read the f***ing manual" gehalten, hätte ich es gleich gewusst, so musste ich es erst nachschlagen und fand den Hinweis:

 VAL    Bestimmt den numerischen Wert eines 'string'. Wenn der 'string' nicht
            rein numerisch ist, ist das Ergebnis nicht bei jedem Computer das gleiche.

            Beispiele:    A$= "1.4E6": A=VAL (A$)     nach Ablauf ist A=1,4E6
                                A$= 12D : A=VAL(A$)          nach Ablauf ist A unbestimmt.


 

Es gibt also keine Schwierigkeiten mit der VAL-Funktion, solange das Argument nur aus Ziffern besteht. Ebenfalls zulässig sind der Dezimalpunkt und das Vorzeichen sowie der Buchstabe E für die Exponentialdarstellung. Steht an erster Stelle ein anderer Buchstabe, resultiert je nach Interpreter der Wert 0 - oder es wird ein Fehler gemeldet. Auch, wenn zunächst erst zulässige Zeichen und später Buchstaben stehen, ist das Verhalten nicht überall gleich: entweder werden die Zeichen vor dem ersten Buchstaben ausgewertet und als Zahl zurückgegeben (z. B. in Mallard Basic ... siehe rechts), oder es wird wie im Falle des SAM Coupé (ebenfalls rechts) ebenfalls ein Fehler angezeigt. Es ist aber auch möglich, dass der Interpreter den Dezimalwert einer Zahl, die in hexadezimaler Schreibweise vorlag (in beiden Beispielen z.B. C9hex --> 201) ausgibt. Es hilft also nur, es vorher zu testen, um sich Klarheit zu verschaffen.

 
 

 

Weitere Tests mit anderen Interpretern:
 

   

 


 
 
 

 

 


Und wie lösen wir nun das Problem im Java-Interpreter? Hier haben wir Zeile 5020 abgeändert auf IF LEN(NO$(N))<5 THEN 5040, dann werden nur noch die Daten berücksichtigt, die tatsächlich verschlüsselte Noten sind. Diese Korrektur ändert auch nicht das Verhalten in anderen Interpretern, dort klappt das Abspielen weiterhin.

 

 



 


Übersetzung der Anleitung

An den Anfang kannst du als Kennzeichnung ein # oder b schreiben und mit / und zwei Ziffern eine Taktangabe.

Gib die Noten wie folgt ein: erst einen der Buchstaben ABCDEFGabcdefg (Höhe), danach ggf. ein # oder ein b, danach die Länge mit EINER Ziffer 1 2 4 8 oder 6 für eine ¹/1, ½, ¼, ¹/8, oder ¹/16 Note.

Danach kann noch ein Punkt (Vergrößerung der Notenlänge um die Hälfte) oder ein M (= Taktstrich) eingegeben werden, sonst gib ein Leerzeichen ein. Ein + macht einen Bindebogen.

Der CURSOR geht von allein an die nächste Position. Der Cursor kann auch mit den Cursortasten bewegt werden.

Eine PAUSE wird mit einem R und einer Ziffer 1 2 4 8 6 gesetzt. Das M setzt einen Taktstrich.

Das S lässt die Musik spielen und das T frischt die Zeichnung auf.

Die Lautstärke der Musik kannst du mit V und einer Ziffer von 1 bis 7 ändern, sie gilt für alle danach eingegebenen Noten.

MIT EINEM ★ ERHÄLTST DU DAS MENÜ MIT DEN ANWEISUNGEN FÜR DAS SPEICHERN UND LADEN DER MUSIK NACH ODER VON KASSETTE ODER DISKETTE.

Mit W kannst du eine Note löschen, die du mit dem Cursor auswählst.

Mit I kannst du Platz schaffen, um eine Note einzufügen und mit U kannst du eine Note löschen und alles, was danach in der Zeile steht, nach links aufrücken. So kannst du nachträglich die Musik noch bequem ändern.
 


Aus eigener langjähriger Erfahrung weiß ich, dass das Problem fast immer 50 cm vor dem Monitor sitzt. Aber auch andere sind nicht unfehlbar, es gibt auch Fehler in heruntergeladenen Programmen. Zum Beispiel gab es vom FREUNDSF Programm jahrelang im Internet nur Screenshots mit einer missglückten Abbildung der Windmühlenflügel, schade, weil es doch sonst ein vergleichsweise aufwendiges Programm mit einer interessanten Entstehungsgeschichte ist. Ich stand sogar mit dem Autor in eMail-Kontakt und fragte nach einer fehlerfreien Version. Er stritt jedoch bis aufs Messer, die Version sei fehlerfrei. So editierte ich schließlich selbst (auf dem Klubtreffen 2015) in den DATA-Zeilen herum, bis es passte.
 

   


Ein anderes Beispiel ist das Programm HELP, das nützliche Funktionen für den Elektronikbastler anbietet, zum Beispiel eine Umrechnung von Dezibel in Neper. Auf dem Ursprungscomputer läuft alles wie geplant - der KC85 hat die Funktion LN für den natürlichen Logarithmus.



Doch in BasiCode ist LOG der Logarithmus zur Basis e und der Variablenname LN ist verboten. In Zeile 6010 K3=EXP(1):K1=1/LN(10):K2=LN(K3) wird LN(10) als indizierte Variable angesehen. Weil diese bisher noch nicht auftrat, wird sie in den meisten (nicht allen) Interpretern mit dem Wert 0 initialisiert. Da diese Division unzulässig ist, bricht das Programm ab. Abhilfe schafft (in BasiCode) der Austausch von LN durch LOG, in diesem Programm übrigens auch noch an weiteren Stellen.

Thomas Rademacher . Februar 2025