|

|
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. |
|


|
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
|
|

|