SMS2-Basic
![](/fileadmin/_migrated/pics/sms2-basic_01.png)
Hätte mein Meisterstück werden sollen -- eine Basic-Erweiterung mit skalierbarem MultiScreen-Handling und Befehlen zur besseren Strukturierung von Programmen. Ich bin zwar damals (1988) nicht ganz fertig geworden, aber ein verbliebener Bug in der Routine zum Zeichnen einer Linie hat mich immer wieder so gewurmt, dass ich 18 Jahre später doch noch mal zum Assembler gegriffen habe...
Inspiriert durch die Grafik-Befehle der Olivette M20, die wir zeitweise in der Schule hatten, wollte ich auch für den C64 ein Basic mit Grafik-Kommandos bereitstellen, die sich auf ein vom Nutzer/der Nutzerin definiertes Koordinatensystem beziehen statt auf Pixelkoordinaten. Dies erschien mir insbesondere für technisch-wissenschaftliche Anwendungen wichtig, um z. B. die Graphen mathematische Funktionen einfacher in einem passenden Wertebereich darstellen zu können -- freilich nicht bedenkend, dass man zum Zeichnen des Achsenkreuzes (Pfeile, Ticks) doch besser wieder im Pixel-System arbeitet... Ebenfalls von der M20 habe ich den schlauen Trick abgeschaut, beim Zeichnen von Kreisen diverse Spiegelsymmetrien auszunutzen, so dass letztlich nur 1/8 Kreis berechnet werden muss.
Weitere Besonderheiten
- Verwendung von Hex- und Binärzahlen ($D000, %11110010 etc.) in numerischen Ausdrücken
- Rasterzeilen-Interrupt-basiertes Aufteilen des Bildschirms in Text und Grafik (fand ich beim Apple II immer so toll...)
- Zusammenlegung mehrerer Grafik-Seiten zu einer "großen" Seite möglich -- irgendwo habe ich auch noch ein Hardcopy-Programm rumliegen, dass die Ausgabe solcher MultiScreens auf einem Star NL-10 erlaubt...
![](/fileadmin/_migrated/pics/sms2-demo1_01.png)
![](/fileadmin/_migrated/pics/sms2-demo2_01.png)
Download
sms2-basic.prg -- mit "komma-acht-komma-eins" laden und mit SYS 32768 starten (liegt von $8000 - $9FFF) |
demo.sms2.prg -- das oben gezeigte Demo-Programm |
Die folgenden neuen Befehle stehen zur Verfügung:
ACTIVE n
Legt fest, auf welche Grafik-Seite (0..7) gezeichnet werden soll.
BLANK <n | ALL>
Löscht eine Grafik-Seite. Wird nicht explizit angegeben, welche Seite gelöscht werden soll, wird die aktuelle Seite gelöscht; die Angabe von ALL bewirkt im MultiScreen-Modus die Löschung aller entsprechenden Seiten.
BLOAD name [,dn] [TO adr]
Lädt ein Programm/eine Datei mit Sekundäradresse 1, also an die in den erseten beiden Bytes vermerkte Startadresse. Optional kann die Gerätenummer (dn) und/oder eine alternative Startadresse (adr) angegeben werden.
BSAVE name [,dn [,m] FROM start TO end [FOR adr]
Speichert den durch start und end angegebenen Speicherbereich auf dem angegebenen Gerät (dn) ab. Optional kann eine alternative Ladeadresse im Dateikopf vermerkt werden (adr) und/oder angegeben werden, welcher Wert (0..7) in die unteren 3 Bits der Adresse 1 (I/O-Ports des 6510-Prozessors) geschrieben werden soll, um beim Speichern wahlweise auf RAM, ROM oder Zeichengenerator zuzugreifen.
CATALOG [dn]
Ausgabe des Disketten-Inhaltsverzeichnisses auf dem Bildschirm; falls keine Gerätenummer (dn) angegeben wird, wird 8 als Vorgabe verwendet. Der Befehlsname ist Apple II-inspiriert ;-)
CIRCLE (x, y) WITH r
Zeichnet einen Kreis mit Mittelpunkt (x, y) und Radius r
COLOR fg ON bg
Legt Vordergrund- und Hintergrundfarbe für den Grafik-Modus fest
DASH n
Dient zur Angabe eines Bitmusters, welches im Zeichenmodus 3 zyklisch durchlaufen wird und je nach Bit-Wert zum Setzen (1) oder Überspringen eines Punktes (0) führt. DASH %11110000 z. B. führt zu einer gestrichelten, DASH %11001100 zu einer fein gestrichelten und DASH %10101010 zu einer dicht gepunkteten Linie.
DOS <[cmd [, dn] | [dn]>
Dienst zum Abschicken eines Kommandos an das DOS (Vorgabe-Gerätenummer ist 8), etwa DOS "S:name",9 zum Löschen einer Datei auf Laufwerk 9. Nach Vollendung oder bei Abweseneit eines DOS-Kommandos wird der Fehlerkanal gelesen und der Floppy-Status ausgegeben (sofern im Direktmodus; falls DOS von einem Programm heraus benutzt wird, unterbleibt die Ausgabe).
DRAWMODE 0|1|2|3>
Legt fest, ob alle ab jetzt gezeichneten Figuren die von ihnen berührten Pixel löschen (0), setzen (1), invertieren (2) oder gemäß dem mit DASH festgelegten Bitmuster behandeln sollen.
ELLIPSE (x, y) WITH (r1, r2) [TURN a]
Zeichnet eine Ellipse mit Mittelpunkt (x, y) und den beiden Radien (r1, r2); optional kann die Ellipse in einem beliebigen Winkel a um den Mittelpunkt gedreht werden.
EXCHANGE n1 WITH n2
Tauscht die Inhalte der beiden angegebenen Grafik-Seiten aus.
GMODE 0 | nx TO ny, n1 [, n2 ...] >
Legt fest, ob auf einer einzigen Seite gezeichnet (GMODE 0) oder der MultiScreen-Modus verwendet werden soll. Falls letzteres, wird die Anzahl der in X- und Y-Richtung zusammenzuschließenden Grafik-Seiten durch TO getrennt angegeben, gefolgt von einer Aufzählung der Seitennummern (zeilenweise von links oben nach rechts unten). GMODE 3 TO 1, 3, 5, 7 z. B. definiert ein aus den Grafik-Seiten 3, 5 und 7 bestehendes Gesamtbild der Breite 3*320=960 und der Höhe 1*200=200 Pixel.
GRAPHICS [FROM upper] [TO lower]
Schaltet den Graphik-Modus an, optional begrenzt auf den mit FROM und/oder TO angegebenen Textzeilen-Bereich.
HIMEM adr
Legt die Obergrenze des für Basic verfügbaren Speichers fest, z. B. um diesen als Grafik-Speicher zu verwenden. Vorsicht, hierbei werden alle Variablen gelöscht!
IF cond THEN ... ELSE ...
Falls die Bedingung cond zutrifft, wird alles bis zum ELSE ausgeführt, andernfalls die Befehle, die nach ELSE folgen. ELSE muss sich dabei in der gleichen Programmzeile wie IF befinden und -- wie ein gewöhnlicher Befehl -- beiderseits mit Doppelpunkten abgegrenzt werden.
KBDCLR
Löscht den Tastaturpuffer.
LINE [(x1, y1] TO (x2, y2)
Zieht eine Linie von (x1, y1) nach (x2, y2). Wird das erste Koordinatenpaar weggelassen, wird von der letzten Endposition aus gezeichnet.
MOVE n1 TO n2
Verschiebt (kopiert) den Inhalt einer Grafik-Seite zu einer anderen.
OLD
Gegenteil von NEW ;-). Holt ein (versehentlich) gelöschtes Programm zurück, sofern noch keine Variablenzuweisungen erfolgt sind.
POLYGONE (x, y) WITH (dx, dy) FROM a1 TO a2 STEP da [TURN a]
Zeichnet ein (ggfs. offenes) Polygon mit dem Mittelpunkt (x, y) und der Ausdehnung (dx, dy) ausgehend vom Winkel a1 bis zum Winkel a2 in Winkel-Schritten der Größe da, welches optional noch um den Winkel a um den Mittelpunkt rotiert werden kann.
RAYS (x, y) FROM a1 TO a2 STEP da [TURN a]
Funktioniert im Prinzip wie POLYGONE, mit dem Unterschied, dass die Ecken nicht untereinander, sondern jeweils mit dem Mittelpunkt verbunden werden.
RECTANGLE (x, y) WITH (w, h) [TURN a]
Zeichnet ein Rechteck mit linker, unterer Ecke bei (x, y), Breite w und Höhe h, das optional noch um die linke, untere Ecke um den Winkel a gedreht werden kann.
REPEAT ... UNTIL cond
Schleife mit Ausgangsbedingung; die umschlossenen Befehle werden ausgeführt, bis die Bedingung erfüllt ist. REPEAT und UNTIL werden -- wie gewöhnliche Befehle -- mit Doppelpunkten abgetrennt.
RPOKE adr, val
Wie POKE, mit dem Unterschied, dass hier immer ins RAM geschrieben wird, auch im I/O-Bereich von $D000 bis $DFFF.
SCALE xmin TO xmax, ymin TO ymax
Legt das benutzerInnenspezifische Koordinatensystem fest. Im MultiScreen-Modus beziehen sich die Angaben auf das zusammengesetzte Gesamtbild.
SHOW n
Gibt an, welche Grafik-Seite sichtbar sein soll. Vorsicht -- da der VIC lediglich 16 kB adressieren kann, liegt der Farb-Speicher einer 8 kB umfassenden Grafik-Seite immer im Adressbereich der jeweils anderen Seite! Lässt man sich also z. B. Seite 6 ($C000 - $DFFF) anzeigen, wird die Farbinformation direkt dahinter ($E000 - $E3FF) geschrieben und überschreibt daher einen Teil der in der Seite 7 ($E000 - $FFFF) ggfs. gespeicherten Inhalte!
TEXT [FROM upper] [TO lower]
Schaltet um auf Text-Modus, optional begrenzt auf den mit FROM und/oder TO angegebenen Textzeilen-Bereich (im verbleibenden Bereich wird dann Grafik angezeigt).
WHILE cond DO ... LOOP
Schleife mit Eingangsbedingung; wird nur so lange durchlaufen, wie die Bedingung zutrifft (also ggfs. gar nicht). Bei Nichtzutreffen der Bedingung wird Programmtext einfach nach dem nächsten LOOP-Befehl gesucht und direkt dahinter fortgesetzt; also besser keine hässlichen Dinge mit GOTO etc. machen! Das WHILE-DO-Paar wird, ebenso wie LOOP, wie ein gewöhnlicher Befehl mit Doppelpunkten abgetrennt.
WINDOW (x1, y1) TO (x2, y2)
Legt einen Zeichenberich im Grafik-Modus fest; Teile von Figuren, die außerhalb des definierten Fensters liegen, werden abgeschnitten.
Zusätzlich stehen folgende neue Funktionen zur Verfügung:
ACOS(a)
Liefert den Arcus-Cosinus von a.
ASIN(a)
Liefert den Arcus-Sinus von a.
Konstante "0"
GRAD(a)
Rechnet einen Winkel von Radiant in Grad um.
JOY(n)
Gibt Status des Joysticks 1 oder 2 zurück; Bitmaske wie in entsprechenden CIA-Registern (Bits 0 - 4), jedoch mit bei Aktivität gesetzten (nicht gelöschten!) Bits.
KEYPRESSED
TRUE, falls im Tastaturpuffer Zeichen anstehen.
LPX / LPY
X- bzw. Y-Koordinate des Light-Pens.
PIXEL(x, y)
Gibt an, ob das zu den Koordinaten (x, y) gehörende Pixel gesetzt (TRUE) oder gelöscht (FALSE) ist.
RAD(a)
Rechnet einen in Grad angegebenen Winkel in Radiant um.
RPEEK(adr)
Wie PEEK, mit dem Unterschied, dass immer der Inhalt des adressierten Bytes aus dem RAM zurückgegeben wird (auch dort, wo normalerweise ROM ($A000 - $BFFF und $E000 - $FFFF) oder der I/O-Bereich ($D000 - $DFFF) liegt).
TRUE
Konstante "-1" = $FFFF