Tipps zu AmigaBASIC

BASIC Variablen am Anfang initialisieren !

Bei Verwendung von neuen Variablen muss AmigaBASIC zunächst Speicher zuweisen und die Variable dann initialisieren. Dies ist mit einem Geschwindigkeitsverlust verbunden. Deshalb ist es sinnvoll, alle Variablen am Anfang eines Programms zu belegen, damit der Interpreter während des Programmablaufs nicht erst Speicher frei machen muss.

Ein weiterer Vorteil ist, dass SUBs zu jeder Zeit gleich schnell ausgeführt werden. Falls Variablen noch nicht deklariert wurden, werden SUBs beim ersten Aufruf langsamer ausgeführt als später im weiteren Programmablauf.

makedir in BASIC

Wer mit AmigaBASIC arbeitet, wird sich sicher schon geärgert haben, dass es hier keinen makedir Befehl gibt. Doch die Lösung des Problems ist einfach:

makedir.bas

Menüleiste abschalten

Wer dem Anwender in seinem Programm die Menüs vorenthalten will, kann diese wie folgt abschalten: menuoff.bas Der Befehl ClearMenuStrip aus der intuition.library schaltet die Menüleiste aus, MENU RESET schaltet sie wieder ein.

Bildschirm DMA abschalten

Um während eines Bildschirmaufbaus diesen so schnell wie möglich abzudunkeln, kann man einfach den Bildschirm DMA abschalten.
Als positiven Nebeneffekt wird der Bildaufbau dadurch sogar um ca 10% beschleunigt.

POKEW 14676118&, 256 ' Bildschirm DMA abschalten
' Hier erfolgt dann der Bildaufbau
POKEW 14676118&, 33024& ' Bildschirm DMA einschalten

Farben in BASIC - speichersparend

Wer viel mit den Befehlen GET und PUT arbeitet, sollte mit dem Speicher nicht allzu verschwenderisch umgehen, z.B. empfiehlt es sich, Grafiken, die sich nur in der Farbe unterscheiden, auch nur einmal einzulesen und vor dem setzen mit PUT den Hintergrund zu verändern. Dieses Programm zeigt, wie es geht:

SCREEN 1,320,200,5,1
WINDOW 1,,,0,1
DEFINT a-z
DIM a(632)
FOR x = 0 TO 7
  PALETTE x,x/7,0,0
  PALETTE x+8,0,x/7,0
  PALETTE x+16,0,0,x/7
  PALETTE x+24,x/7,x/7,0
  LINE(x*3,x*3)-STEP(47-x*6,47-x*6),x,bf
NEXT
GET (3,3)-STEP(41,41),a
CLS
FOR x = 0 TO 3
  LINE(x*50+60,100)-STEP(41,41),x*8,bf
  PUT(x*50+60,100),a
NEXT

Rahmenlos

Jeder fortgeschrittene BASIC Programmierer wird wohl wissen, wie man den Fensterrahmen mit einem POKE und einem Aufruf von RefreshWindowFrame der intuition.library abschaltet. Aber nur wenige wissen, dass dies auch ganz ohne Einsatz der Library funktioniert:

SCREEN 1,320,256,1,1
WINDOW 1,"Rahmenlos ohne Library",,0,1
w& = WINDOW(7)+24
POKEL w&,PEEKL(w&) XOR 2048
WINDOW 2,,,0,1
WINDOW CLOSE 2

Durch das öffnen des zweiten Fensters wird das erste vollständig überdeckt. Nach dem sofortigen schließen wird der Bildschirm vom System automatisch erneuert und unser Fenster kommt rahmenlos zum Vorschein.

Zeichnen in Screens ohne Fenster

Haben Sie gewusst, dass man in AmigaBASIC ohne Fenster (Window) zeichnen kann ? Die Zuhilfenahme der "graphics.library" macht es möglich:

LIBRARY ":libs/graphics.library"
SCREEN 1,320,256,2,1
WINDOW 1,,(0,0)-(310,50),0,1
rp& = PEEKL(WINDOW(7)+46)+84
' WINDOW CLOSE 1
txt$="Hallo Welt"
CALL Move(rp&, 100, 100)
CALL Text(rp&, SADD(txt$), LEN(txt$))
CLS
LIBRARY CLOSE
END

Menüs mit Shortcuts

shortcutmenu.bas

Alle Offsets für Assembler

Für Assembler-Programmierer, die häufig Systemroutinen benutzen, ist es oft mühsam, die Offsets für die Einsprünge in die Libraries zu berechnen beziehungsweise abzutippen; und nicht jeder Assembler stellt die Offsets in Form von Include-Dateien zur Verfügung. Es gibt einen relativ einfachen Weg, sich solche Include-Dateien selber anzufertigen: Man kann die FD-Dateien auf der Extras-Diskette in ein für den Assembler lesbares File verwandeln. Das folgende Basic-Programm zeigt, wie man eine solche Konvertierung vornimmt.
makeinclude.bas

BASIC schneller machen

In der Kürze liegt die Würze

Schleifen von unnötigem Ballast freihalten

Aus dem oben geschilderten Prinzip eines Interpreters ergibt sich leider auch, dass alle Zeilen einer Schleife jedes mal neu übersetzt werden. Läuft die Schleife von 1 bis 1000 und hat sie 5 Zeilen, dann werden 5000 Zeilen übersetzt.

Daraus folgt ganz klar, dass nichts in eine Schleife gepackt werden sollte, was da nicht unbedingt hineingehört. Das sind alle Berechnungen, die zum selben Ergebnis führen, dito alle Funktionsaufrufe. In einem solchen Fall rechnen Sie vor der Schleife und speichern das Ergebnis in einer Variablen. Dito rufen Sie eine Funktion vor der Schleife auf und weisen deren Ergebnis einer Variablen zu.

Bei Formeln müssen Sie besonders aufpassen. Nehmen wir an, die Zahlen in Array a sollen in Prozent zur Basis 4711 umgerechnet werden. Dann wäre es schlecht, zu schreiben:

FOR i=1 TO 1000
  a(i) = a(i)/4711*100
NEXT

Das schreiben Sie besser als

f = 1/4711*100
FOR i=1 TO 1000
  a(i) = a(i)*f
NEXT

Stellen Sie also immer bei längeren Ausdrücken fest, was davon eine Konstante ergibt und rechnen Sie die außerhalb der Schleife aus. Bei der Gelegenheit: Wenn Sie in einer Schleife auch nur durch eine einzige Konstante dividieren müssen, dann rechnen Sie außerhalb der Schleife den Reziprokwert aus und multiplizieren mit diesem innerhalb der Schleife. Eine Multiplikation ist nämlich immer schneller als eine Division.

Keine Schleife mit GOTO

Man sieht häufig Schleifen in der Form

Loop:
  Tue dies
  Tue das
  GOTO Loop

Besser ist ein Endlosschleife der folgenden Form:

WHILE 1
  Tue dies
  Tue das
WEND

Der Grund ist folgender: Eine Marke oder Zeilennummer muss BASIC immer erst suchen. Bei den "echten" Schleifen (WHILE..WEND und FOR..NEXT) speichert Basic (auch) die Adressen auf dem Stack, so dass ein einziger Maschinenbefehl reicht, um das Sprungziel zu holen.

GOSUB ist schneller als GOTO