C 64
Listing des Monats

Die Scroll-Machine: Das Fenster zur Spielewelt

Dieses außergewöhnliche Programm verschiebt den Bildschirm flimmerfrei in jede Richtung, wie es sonst nur von professionellen Spielen her bekannt ist — und das mit Basic.

Bild 1 und 2. Ausschnitte aus dem Pseudoschirm eines Demos

Bildschirmscrolling in eine beliebige Richtung ist im Commodore Basic V2.0 nicht realisierbar. Wer es dennoch versucht, wird mit dem Ergebnis nicht zufrieden sein. Dieses Programm macht es auch dem Anfänger leicht, Soft-Scrolling, ein Synonym für ruckfreies Verschieben des Bildschirms in alle Richtungen, in seine eigene Programme einzubauen. Besonders gut eignet es sich dazu mit dem Pseudoschirm-Editor Spielfelder zu konstruieren, die die Größe des normalen Bildschirms überschreiten. Durch eine große Anzahl von Befehlen ist jeder in der Lage, mittels Soft-Scroll immer den Teil des Feldes darzustellen, in dem sich die Spielfigur befindet. Die Spielfiguren werden ähnlich wie in professionellen Programmen durch Basic-Befehle, die die Beschleunigung, Reibung oder Höchstgeschwindigkeit festlegen, beliebig auf dem sichtbaren Pseudoschirm bewegt, einem Schirm, der in x- und y-Richtung größer ist als der normale Textbildschirm (x>40, y>25). Jeder kann maximal zwei Textfenster realisieren, die beliebige Spielinformationen enthalten. Das Programm stellt zum Laden und Abspeichern von SEQ- und PRG-Files einige sehr leistungsfähige Befehle zur Verfügung.

Aber nicht nur für die Gestaltung von Spielen ist dieses Programm geeignet. Der Anwender kann zum Beispiel von Basic aus Textverarbeitungsprogramme gestalten, die durch horizontales Scrollen mehr als 40 Zeichen pro Zeile darstellen können, wie es bei fast allen kommerziellen Programmen der Fall ist.

Bei dem Pseudoschirm-Editor handelt es sich um ein in Basic geschriebenes Programm, das durch einfache Befehle und einen geeigneten Zeichensatz beliebige Landschaften auf dem Bildschirm entstehen läßt. Die Konstruktion von Gängen und Höhlen wird im Kontur- und Micromodus zum Kinderspiel. Das Programm arbeitet sowohl mit einfarbigen wie aber auch mehrfarbigen Zeichensätzen. Die beiden Bilder sind ein ausgezeichnetes Beispiel für die Leistungsfähigkeit dieses Programms.

(Thilo Herrmann/ah)

Bringen Sie Bewegung in Ihre Grafik. Nutzen Sie einen Bildschirm, der bis zu 30 mal größer ist als der normale Textbildschirm. Scrolling wie bei dem Spiel Zeppelin wird dadurch möglich.

Das Programm besteht aus 3 KByte Maschinensprache, die im Bereich von $C000 (49152) bis fast $CBFF (52223) liegen. Die Variablen stehen von 828 bis 959 im Kassettenpuffer. Das Video-RAM, das vom Programm benutzt wird, liegt im Bereich von 52224 bis 53223. Da die Spritepointer immer dem Video-RAM folgen, stehen sie nun von 53240 bis 53247 (normal: 2040 bis 2047). Im Bereich von $D000 (53248) bis $D7FF (55295) steht der Zeichensatz, der leicht verändert werden kann. Dabei ist zu beachten, daß der Bereich von $D000 bis $DFFF dreimal belegt ist, einmal durch die Ein-/ Ausgabe (VIC, SID, CIA 1 und 2), den C 64-Zeichensatz und das RAM, in das der Zeichensatz kopiert oder ein neuer geladen wird.

Außerdem benötigt die Scroll-Machine noch eine Multiplikationstabelle, die von $DE00 (56832) bis $DFFF (57343) steht. Der Rest von $D800 bis $DDFF (55296 bis 56831) kann von Sprites genutzt werden. Ebenfalls für Sprites frei ist das RAM unter dem Kernal von $E000 bis $FFFF (57344 bis 65535). Dort kann auch ein 8-KByte-Pseudoschirm stehen, der eine größere X/Y-Ausdehnung hat als der normale Textbildschirm. Wenn dieser Bereich jedoch frei ist, kann man insgesamt 152 verschiedene Sprites im Speicher halten. Es muß aufgrund einer Besonderheit des VICs darauf geachtet werden, daß die Speicherstelle 65535 den Wert Null enthält. Die Sprites müssen nach wie vor vom Basic-Programm bewegt werden.

Es sei nicht unerwähnt, daß ich die Restore-Taste geändert habe. Sie funktioniert nun auch ohne daß man RUN-STOP drückt. Die NMI-Vektoren $0318/$0319 (792/793) und $FFFA/$FFFB (65530/65531) im RAM enthalten immer die Adresse der neuen Restore-Routine. Soll die Restore-Taste gesperrt werden, so hilft POKE 51692,64. Die RUN/STOP-Taste kann mit POKE 49710,52 außer Kraft gesetzt werden (Tl wird damit auch unbrauchbar).

Die Funktionsweise

Das Programm arbeitet mit drei Rasterzeileninterrupts, zwei für den oberen Text/Soft-Scroll-Übergang und einer für den unteren. Alle Interrupts können mit dem RZ-Befehl verschoben werden, so daß die Bildschirmfenster beliebig groß werden können.

Jede der drei Interruptroutinen setzt erst die Parameter des Videoprozessors: Hintergrundfarbe, Rahmenfarbe und so weiter. Die erste Interruptroutine hat damit ihre Aufgabe erfüllt. Sie setzt die Hintergrundfarbe auf die Zeichenfarbe, damit ein sauberer Übergang zwischen Soft-Scroll und normalem Text entsteht.

Die zweite Routine berechnet die Werte für Bewegung und Steuerung. Dann springt sie zum normalen Systeminterrupt, der die Tastatur abfragt und die Zeit erhöht.

Der dritte Interrupt ruft die Scroll-Routine auf, die den Pseudobildschirm abtastet und am meisten Zeit verschlingt.

Dieser Teil des Programms muß sehr schnell sein, da er seine Aufgabe erledigt haben muß, bevor der nächste Interrupt ausgelöst wird.

Die neuen Basic-Befehle werden mit Hilfe des Pointers $0308/$0309 eingebunden.

TI$ wird unbrauchbar, da der Systeminterrupt nun nicht mehr jede 60stel Sekunde, sondern jede 50stel Sekunde ausgeführt wird. Die Sekunde errechnet sich während des Betriebs des Soft-Scrolls nun mit TI/50.

Joysticksteuerung

Wie sich aus der Befehlsliste ersehen läßt, besitzt das Programm vier Befehle zur Steuerung des Joysticks.

Es gibt mehrere Möglichkeiten, ein Objekt zu steuern. Zum einen gibt es die »lineare« Steuerung. Sie wird wohl am häufigsten verwendet, zum Beispiel bei Fort Apocalypse und den meisten selbstgeschriebenen Spielen. Das funktioniert so: Man drückt den Steuerknüppel in eine bestimmte Richtung und das Objekt setzt sich in Bewegung. Es bewegt sich so lange, bis man den Knüppel wieder losläßt. Diese Steuerung ist jedoch wenig wirklichkeitsnah, man denke nur an eine Raumkapsel, die durch Raketenschübe gesteuert wird. Sie setzt sich nicht sprunghaft in Bewegung, sondern langsam. Wenn der Antrieb dann abgeschaltet wird, stoppt unser Flugkörper nicht plötzlich, sondern fliegt mit der gleichen Geschwindigkeit weiter. Diese träge Steuerung und die lineare Steuerung lassen sich mit der Scroll-Machine verwirklichen.

Da die lineare Steuerung besonders einfach ist, werden ihre Werte im JS-Befehl mit angegeben. Nämlich so:

← JS m,x,y,p (m = Joystickmodus, p = Port)
x und y stellen die Geschwindigkeiten der linearen Steuerung dar. Bei x = 8 und y = 0 hat man in etwa die Space-Invader-Einstellung.

Die träge Steuerung benötigt drei Befehle, was schon andeutet, daß sie etwas kompliziert ist. Hier bestimmt man nicht die Geschwindigkeit, sondern die Beschleunigung. Da vor jedem Trägheitsbefehl ein T steht, lautet der Befehl:

← TB x,y

x und y geben die X-Y-Beschleunigung an. Sie können Werte zwischen Null und 255 annehmen.

Wenn man nun den Steuerknüppel in eine Richtung drückt, wird die Geschwindigkeit immer größer. Die größtmögliche Geschwindigkeit kann man mit dem TG-Befehl festlegen.

← TG x, y

Dies kann man sehr genau regeln, weil x und y Werte zwischen Null und 32767 annehmen können.

Wenn man einen Gegenstand auf einer waagrechten Fläche beschleunigt, so hält dieser Gegenstand irgendwann auch wieder an. Daran ist die Reibung schuld. Das kann man auch simulieren, der Befehl lautet:

← TR x,y
x und y müssen kleiner sein als die entsprechenden Werte beim TB-Befehl. Die Routine zieht x und y einfach von der Geschwindigkeit ab.

Natürlich kann man die lineare und die träge Steuerung auch mischen. (Es muß vor jedem Befehl ein Pfeil stehen.)

Zum Beispiel: Defender:←RS:←CP:←ZF 1:←US 1.

Diese Befehle setzen die Standardeinstellung.

← JS 2,0,8,2 m=2 mischen

x=0 keine lineare X-Steuerung

y=8 lineare Y-Steuerung, Geschwindigkeit 8

P=2 Port 2
←TB 16,0 x=16 X-Beschleunigung 16

y=0 keine Y-Beschleunigung
←TG 2000,0 x=2000 X-Geschwindigkeit höchstens 2000

y=0 Y-Geschwindigkeit 0 (hier unwichtig)
←TR 6,0 x=6 X-Reibung 6

V=0 Y-Reibunq 0 (auch unwichtig)

In diese Steuerung kann man auch noch Bewegung einmischen mit:

←BW 0—8 x=0 keine X-Bewegung

y=-8 Mit Geschwindigkeit 8 nach oben.

Ergebnis: Der Bildschirm bewegt sich kontinuierlich nach oben. Mit dem Joystick kann man die Y-Geschwindigkeit erhöhen oder vermindern.

Die Befehle

Vor jedem Befehl steht der Pfeil nach links. Die folgenden zwei Buchstaben stellen das Befehlswort dar. Danach muß man teilweise einige Parameter angeben, wie zum Beispiel beim normalen POKE-Befehl. Nach einer IF…THEN-Entscheidung muß nach dem THEN ein Doppelpunkt stehen, wenn ein Scroll-Machine-Befehl folgt, zum Beispiel IF A=1 THEN: ← RS. Wem der Pfeil nicht paßt, der kann mit POKE 50550,ASC(X$) ein anderes Zeichen auswählen. So wird nach POKE 50550,ASC("!") nur noch das Ausrufezeichen angenommen. Folgende Zeichen lassen sich verwenden: !";#$%&'(),.:; sowie Klammeraffe, die eckigen Klammern, Pfund, PI, Pfeil links sowie fast alle Buchstaben:

Damit man das Programm auch von Maschinensprache aus verwenden kann, habe ich jeweils die entsprechenden Adressen und gegebenenfalls auch die Einsprungadressen mit angegeben.

Die Befehle:

RS

Reset. Dieser Befehl sollte am Anfang jedes Programms stehen. Er löscht alle Einstellungen und schaltet auf den Normalzustand, das heißt, er führt unter anderem folgende Befehle aus: MT 40960,40,0: VI 52224,21 ML: JSR $C5C0

MT aa,xd,yd

Erstellt die Multiplikationstabelle, das heißt, man legt mit diesem Befehl die Anfangsadresse und die X- und Y-Ausdehnung des Pseudoschirms fest.

aa = Anfangsadresse, xd = Ausdehnung des Schirms in X-Richtung, yd = Ausdehnung in Y-Richtung.

Der normale Videoschirm hätte zum Beispiel die X- und Y-Werte 40 und 25. Die des Pseudoschirms können theoretisch zwischen Null und 8191 liegen.

Die Y-Ausdehnung ist völlig unwichtig. Sie gehört jedoch der Vollständigkeit halber dazu, wird mitgespeichert und -geladen und kann über USR(12) abgefragt werden.

Wenn der Schirm im Basic-RAM liegt (aa < 40960), sollte man das Basic-Ende so herabsetzen:

AA = Startadresse aa: H = INT(AA/256): L=AA-H*256: POKE 55,L: POKE 56,H: CLR ML: aa:$CBFA/CBFB, xd:$CBFC/CBFD, yd:$CBFE/CBFF, JSR $C6AC

CP

Kopiert den Zeichensatz vom ROM in das darunterliegende RAM. Erführt UT 53248, 55295, 53248,51,48 aus. Dieser Befehl sollte ebenfalls am Anfang eines Programms stehen, falls nicht ein neu definierter Zeichensatz mit dem LD-Befehl geladen wurde. ML: JSR $C8BC

US n

Umschalten zwischen Soft-Scroll (n=1) und Text (n=0). Bei n=0 werden alle Einstellungen des Textfensters gesetzt. ML:LDX#n:JSR$C5F8

ZFf

Dient zum Setzen der Zeichenfarbe f. Wenn man im Multicolormodus arbeitet, kann man nur die Farben Null bis Sieben nutzen und muß jeweils Acht dazuzählen (Bit 3 setzen). ML : LDA #n: JSR $C8EB

HF f1,f2,f3

Wählt die Hintergrundfarben der drei Bereiche.

ML: $C568/$C569/$C56A

RF f1,f2,f3

Die Randfarben können beliebig gewählt werden. ML: $C56B/$C56C/$C56D

PO x,y

Positioniert den Bildschirm innerhalb des Pseudoschirms, x und y können negativ und positiv sein.

Sinnvoll sind jedoch nur 0 < x < xd*8 und 0 < y < yd*8. ML: x:$0358/$0359, y:$035A/$035B

BWx,y

Bewegt den Bildschirm in der angegebenen X- und Y-Geschwindigkeit. x und y können zwischen -127 und 128 liegen. ML: x:$0385, y:$0386

JS m,x,y,p

Bestimmt die Werte für den Joystick.

Die letzten drei Angaben können weggelassen werden.

ML: n:$033E, x:$0374, y:$0375, p:$03A5

Zur trägen Steuerung gibt es drei Befehle. Sie bewirken nur etwas, wenn der Joystickmodus zwei gewählt wurde. Der erste Buchstabe lautet immer »T«.

TB x,y

Regelt die Beschleunigung, x und y kann zwischen 0 und 255 liegen. ML: x:$034A, y:$034B

TR x,y

Bestimmt die Reibung, x und y sind auch hier 1-Byte-Werte. ML: x:$0392, y:$0393

TG x,y

Legt die Höchstgeschwindigkeit fest, x und y sind hier 2-Byte-Werte, sie können also Werte zwischen 0 und 65535 annehmen. ML: x:$038E/$038F, y:$0390/$0391

Die nachfolgenden Befehle sind allgemeingültig:

GR x,x2,y,y2

Die hier festgelegten Grenzen können nicht überschritten werden. Die Werte können wie beim PO-Befehl zwischen 0 und 65535 liegen. ML x:$0396/$0397, x2:$0398/$0399, y:$039A/$039B, y2:$039C/$039D

GM m

Der Grenzmodus wird gewählt: Bei m=O bestehen keine Grenzen. Bei m=1 wird bei den Grenzen abgestoppt. Bei m=2 wird der Bildschirm an die gegenüberliegende Grenze gesetzt. ML: m:$039E

AS n

Läßt den Interrupt n mal aussetzen, bevor er wieder ausgeführt wird. Das ist besonders nützlich, wenn man Rechenzeit sparen will.

Nachteil: Je größer n ist, desto stärker ruckt das Bild. ML: LDX #n: JSR $C78D

TM m

Wählt den »Tastmodus«. Bei m=0 wird der Pseudoschirm nur abgetastet, wenn es nötig ist.

Bei m=1 wird er immer abgetastet (= jede 50stel Sekunde), was natürlich Rechenzeit kostet.

Nützlich, wenn im Pseudoschirm laufend etwas verändert wird. Ein Beispiel: RS:CP:ZF 1:MT 1024,40,25:PO O,O:TM 1:US 1 PRINT "<HO>"

Ergebnis: Der blinkende Cursor erscheint doppelt auf dem Schirm. Der zweite Cursor macht alle Bewegungen mit. Wenn man TM 0 eingibt, ändert sich das. ML: m:$03A2

SY n

Synchronisiert die Scroll-Machine mit dem laufenden Programm, das heißt, der Interrupt wird nicht mehr im 50stel-Sekunden-Takt ausgeführt, sondern im Programmtakt.

Diese Funktion ist wichtig bei langsamen Basic-Programmen wie dem Editor. Achtung: Die X/Y-Position wird erst beim darauffolgenden SY 1-Befehl gesetzt. ML: LDX #n: JSR $C88C

VI aa,z

Verlegt das Video-RAM, in das geschrieben wird.
aa = neue Anfangsadresse, z = Anzahl der Zeilen (z < = 21). Normal: aa= 52224, z=21. Je kleiner z ist, desto schneller wird das Programm.

ML: aa:$C4D9/$C4DA, LDX #z: JSR $C7AE

1R n1,n2,n3

Inhalt des 1. Steuerregisters (VIC+17) in den drei Bereichen. Normal: 27,23,16 ML: $C55C/$C55D/$C55E

2R n1,n2,n3

Der entsprechende Befehl für das 2. Steuerregister (VIC+22). Normal: 200,200,192 ML: $C55F/$C560/$C561

MC n1,n2,n3

Dasselbe für das Memory-Control-Register (VIC+24). Normal: 21,52,52 ML: $C562/$C563/$C564

CI n1,n2,n3

Das Gleiche gilt für die Basisadresse der CIA 2 (56576). Normal: 151,148,148 ML: $C565/$C566/$C567

RZ z1,z2,z3

Legt die Rasterzeilen für die drei Interrupts fest. Normal: 81,88,248 andere Möglichkeit: 106,115,232 + SU 4 ML: $C56E/$C56F/$C570

SU n

Behebt Fehler, die bei der Änderung der Rasterzeilen entstehen können. Das erkennt man am Rucken des Scrollings, n kann Werte von 0 bis 7 annehmen.

Den richtigen Wert kann man nur durch Ausprobieren feststellen.

Wenig Probleme wird man haben, wenn man die RZ-Werte in Achterschritten verändert. Normal: n=5

ML: n:$C571

Die folgenden zwei Befehle sind als allgemeine Hilfe gedacht:

FU a,e,n,w

Dieser Befehl füllt den Speicher von a bis e mit n, während in der Speicherstelle 1 w steht, w kann weggelassen werden. ML: a:$FB/$FC, e:$FD/$FE, n:$03B0, LDX #w: JSR $C842

UT a,e,a2,r,w

Es wird der Block von a bis e nach a2 übertragen. Dabei steht in 1 während des Lesens r und während des Schreibens w. ML: a:$FB/$FC, e:$03A6/$03A7, a2:$FD/$FE, LDA #r : LDX #w : JSR $C725

Natürlich kann man die Erweiterung auch ausschalten:

OF

Schaltet die Erweiterung vollständig ab. Sie muß mit SYS49152 wieder gestartet werden. Die Wirkung ähnelt der der Run-Stop/Restore-Funktion.

Dieser Befehl wird zum Beispiel dann benötigt, wenn man etwas von der Datasette laden will. ML: JSR $C65E

Die Diskettenbefehle

LD "Name"

Lädt den Pseudoschirm mit der Bezeichnung Name von der Diskette. Die Anfangsadresse, die X-Ausdehnung und die Y-Ausdehnung werden mitgeladen und gesetzt.

ML: LDA #0 : STA $CBF8 LDX # < Namenadr. : LDY # > Namenadr. : LDA # Namenlänge JSR $FFBD (Setnam-Routine) JSR $CAC8

LD "Name",aa

Lädt ein beliebiges Datenfile absolut an die Adresse aa von der Diskette. Achtung: Das File wird vollständig geladen, inklusive den beiden Adreßbytes am Anfang jedes Programms. Man sollte deshalb von aa zwei abziehen.

Wenn man sequentielle Files oder Userfiles laden will, dann hängt man an den Namen einfach noch ,S oder ,U an. ML: aa:$FB/$FC, LDA #1 : STA $CBF8

Ansonsten weiter wie oben.

SV "Name",ea

Speichert einen Pseudoschirm mit der Bezeichnung »Name« auf Diskette. Die Endadresse ea errechnet sich aus Anfangsadresse + X-Ausdehnung * Y-Ausdehnung. ML: ea:$FD/$FE

LDX # < Namenadr. LDY # > Namenadr. LDA # Namenlänge

JSR $FFBD (Setnam-Routine)

JSR $CB3E

Die USR(x)-Funktion

Mit ihrer Hilfe kann sich der Benutzer einige wichtige Werte holen. Je nachdem, welchen Wert x annimmt, wird zu verschiedenen Routinen verzweigt.

x=0Jedesmal, wenn eine Grenze berührt wird, die mit dem GR-Befehl gesetzt wurde, setzt das Programm ein Flag auf eins. Mit dieser Funktion wird das Flag abgefragt und gelöscht.ML: $03AD
x=1Liefert die momentane X-Position.ML $0358/$0359
x=2Liefert die Y-Position.ML: $035A/$035B
x=3Gibt die Adresse im Pseudoschirm an, die der Bildmitte entspricht.ML: $C50C/$C50D
x=4Ergibt eins, wenn der Feuerknopf des Joysticks in Port 2 gedrückt ist.
ML: Es empfiehlt sich der normale Joystickport $DC00.
x=5Dasselbe für Port 1.ML: $DC01
x=10Übermittelt die Anfangsadresse des Pseudoschirms (die möglicherweise nicht bekannt ist, weil der Schirm eben geladen wurde).ML: $CBFA/$CBFB
x=11Liefert die X-Ausdehnung.ML: $CBFC/$CBFD
x=12Liefert die Y-Ausdehnung.ML: $CBFE/$CBFF
x>255Übermittelt den Inhalt der Speicherstelle x. Es wird immer der Inhalt des RAMs gelesen. Man hat damit also die Möglichkeit, das versteckte RAM zu lesen.
ML: Die allgemeine Methode funktioniert so:SEI: LDX #48:STX 1:LDA x:LDX #55:STX 1:CLI

Übrigens: In $036A/$036B (874/875) und $036C/$036D (876/877) stehen die X- und Y-Werte für die Trägheitsgeschwindigkeit.

Der Pseudoschirmeditor

Der Editor ist ein Basic-Programm, das mit den wichtigsten Funktionen zur komfortablen Erstellung eines Pseudoschirms ausgestattet ist.

Er benötigt die Scroll-Machine, um arbeiten zu können. Man muß sie also von Datasette oder Diskette laden. Dann lädt man den Editor und startet ihn mit RUN.

Zuerst wird man nach der X/Y-Ausdehnung und der Anfangsadresse gefragt. Die Werte XD=128, YD=64 und AA=40960 sind vorgegeben, so daß der Pseudoschirm das RAM unter dem Basic-ROM voll belegt ($A000 — $BFFF). In diesem Fall ist RETURN zu drücken. Dann will das Programm wissen, ob der Zeichensatz vom ROM ins RAM kopiert werden soll. Wenn man das Programm eben erst geladen hat, sollte man mit »J« antworten. Steht jedoch schon ein neuer Zeichensatz, der erhalten werden soll, im Speicher, so gibt man »N« ein. Anschließend erscheint die Frage »MULTICOLOR (J/N)« auf dem Bildschirm. Wenn der normale Commodore-Zeichensatz benutzt wird, lautet die Antwort immer »N«, ansonsten hängt das vom Zeichensatz ab. Natürlich muß man auch noch die Farben eingeben, wenn man nur Return drückt, erhält man die Standardeinstellung. Schließlich kann man entscheiden, ob der Pseudoschirm gelöscht werden soll. Normalerweise antwortet man mit »J« und der Pseudoschirm wird nach einer Rückversicherung mit dem Zeichen 32 (Space) gefüllt.

Nach diesen Eingaben hat man endlich das normale Bild des Editors vor sich, das folgendermaßen aufgebaut ist:

Der Bildschirm ist in zwei Bereiche unterteilt. Oben wird immer der Teil des Pseudoschirms gezeigt, der gerade bearbeitet wird. In der Mitte dieses Bereiches befindet sich ein Sprite, der als Cursor fungiert. Der Bildschirm läßt sich mit Hilfe eines Joysticks in Port zwei bewegen. Unten kann man den kompletten C 64-Zeichensatz erkennen. Er ist in acht Zeilen à 32 Zeichen unterteilt, wie bei vielen Zeichengeneratorprogrammen. Es wird der große Zeichensatz benützt, weil er mehr Grafikzeichen zur Verfügung stellt. Auch hier wird ein Sprite als Cursor benutzt, der sich mit den Cursortasten auf der Zeichenpalette bewegen läßt.

Im Normalmodus wird durch einen Druck auf den Joystickknopf jeweils das Zeichen von der Palette auf den Pseudoschirm übertragen, auf das der Zeichencursor zeigt.

Das ist die einfachste Funktion des Programms, mit ihr allein ist es jedoch fast unmöglich, einen Pseudoschirm zu erstellen. Deshalb bietet es noch einige andere Möglichkeiten wie Rechteck füllen, Rechteck übertragen und so weiter, die man von Programmen wie Paint Magic oder Koalapainter her kennt. Sie bedürfen keiner langen Erklärung, da die Bedienung einfach und logisch aufgebaut ist.

Auch der Mikromodus ist schnell erklärt. Er benutzt die Zeichen 32, 97, 98, 108, 123, 124, 126, 127 und ihre reversen Entsprechungen, um eine vierfache Auflösung zu erreichen. Mit dem Klammeraffen kann man zwischen Punkt löschen und Punkt setzen umschalten. Mit Shift-M kann man die Zeichenfolge neu definieren. Wenn man einen selbstdefinierten Zeichensatz benutzt, stimmen die Codes 97, 98, 108 etc. nicht mehr. Der Einfachheit halber müssen die neuen Zeichen aufeinanderfolgen, mit Leerraum (=Space) beginnen und mit einem vollständig gefüllten Zeichen enden. Eine nicht ganz einfache Funktion ist der Konturmodus, der im folgenden näher erläutert wird.

Mit den Zeichen 100, 111, 121, 98 und so weiter, kann man eine sanft aufsteigende Linie bilden. Das wird im Konturmodus ausgenutzt. Wenn man F7 betätigt, wird dieser Modus gesetzt. Jetzt kann man Landschaften formen, die sanft auf- und absteigen. Jedoch kann man keine Höhlendecken oder ähnliches bilden, auch senkrechte Wände bleiben einem versagt. Das kann man mit einem Druck auf »K« ändern. Man wird nach X+, X—, Y+, Y— gefragt. Mit den Tasten 1-4 kann man die gewünschte Einstellung wählen. X bedeutet senkrechte Wände, Y steht für waagrechte Wände. Plus und Minus geben jeweils an, welche Seite Freiraum und welche Wand ist. Anschließend muß man noch die Geschwindigkeit angeben, die regelt, ob der Berg sanft oder steil ansteigt.

Wenn man senkrechte Wände bearbeitet, wird man feststellen, daß die Kontur fehlerhaft ist. Das liegt am Zeichensatz des C 64. Die Zeichen 101 und 116 sind identisch, was von Commodore so geregelt wurde, damit das Zeichen auf einem Fernsehschirm besser sichtbar ist. Mit einem VC 20-Zeichensatz hätten wir diese Probleme nicht. Wenn man einen eigenen Zeichensatz benutzt, ist das Problem auch gelöst. Denn wie beim Mikromodus gibt es hier ebenfalls die Möglichkeit, das Programm an den eigenen Zeichensatz anzupassen.

Mit SHIFT-K ruft man die entsprechende Routine auf. Man benötigt vier Zeichenfolgen. Jeweils eine für X+, X—, Y+, Y— Mit 1-4 kann man wählen, welche man neu definieren will. Jede Zeichenfolge muß aus acht Zeichen bestehen, von denen das erste Space (32) oder das letzte Revers-Space (160) ist. Man steuert mit den Cursortasten auf das erste Zeichen und drückt dann RETURN. Nun muß man sich für +1 oder —1 entscheiden. Hier hilft nur ausprobieren. Dann gibt man nur noch die Geschwindigkeit an und die neue Zeichenfolge ist im Speicher.

Ein Pseudoschirm muß auch abgespeichert und geladen werden können, was man mit F1 und F3 erreichen kann. Die Scroll-Machine enthält bereits Routinen, um einen Pseudoschirm aus irgendeinem Speicherbereich auf Diskette Gerätenummer 8 abzuspeichern und in den gleichen Bereich wieder zu laden. Für die Datasette existiert jedoch kein Befehl, so daß man dafür die ROM-Routinen verwenden muß. Deshalb kann man mit der Datasette nur das Basic-RAM benutzen, da sich die Bereiche von 40960 bis 49151 und 57344 bis 65535 von den ROM-Routinen nicht auslesen lassen. Man kann jedoch einen Pseudoschirm in das Basic-RAM laden, um ihn dann mit dem UT-Befehl in das versteckte RAM zu schieben. Wenn man einen Pseudoschirm mit dem eigenen Programm von Kassette laden will, muß man das Unterprogramm des Editors verwenden (ab Zeile 17 500). Der Wechselmodus wird mit »W« aktiviert und mit SHIFT-W definiert. Man kann einen Bereich von Zeichen festlegen, die dann zyklisch wiederholt verwendet werden. Nützlich ist dies für flächige Felsstrukturen oder ähnliches. Denn wenn man den ganzen Bereich mit dem gleichen Zeichen gestaltet, wird die Struktur regelmäßig und sieht nicht echt aus.

Aus allen Modi kommt man wieder heraus, indem man den Pfeil nach links drückt. Dadurch wird der Editor wieder in den Normalzustand zurückgesetzt.

Zum Editor ist damit alles Wichtige gesagt. Abtippen muß man ihn wie jedes andere Programm, die REM- und Doppelpunkt-Zeilen werden jedoch nicht angesprungen, deshalb können sie weggelassen werden.

Die Befehlsliste gibt Auskunft über die restlichen Funktionen und deren Handhabung.

Ich hoffe, daß das Programm möglichst fehlerlos ist und wünsche Ihnen viel Spaß damit.

Um die Fähigkeiten von »Scroll-Machine« aufzuzeigen, soll auch gleich ein kleines Beispielprogramm angeführt werden. Da man es niemandem zumuten kann, einen Pseudoschirm von 8 KByte oder mehr abzutippen, muß sich das Spiel den Schirm selbst aufbauen. Daß darunter die Qualität der Grafik leidet ist klar. Außerdem habe ich keinen neudefinierten Zeichensatz verwendet, sondern nur die Commodore-Zeichen Space (32), lnvers-Space (160) und lnvers-Shift-0 (207). Der Pseudoschirm besitzt nur eine Auflösung von 128 x 64, was genau 8 KByte entspricht. Eigene Schirme sollte man größer machen — etwa 20 bis 30 KByte — und wenn möglich mit einem eigenen Zeichensatz versehen.

Atomdepot, ein Demoprogramm zur Scroll-Machine

Doch dieses Spiel ist trotzdem ein gutes Beispiel dafür, wie man die Scroll-Machine benutzt.

Der Handlungsort ist ein Bergwerksstollen in nicht allzu ferner Zukunft, in dem noch drei Atommüllfässer lagern. Sinn des Spiels ist es, die drei Fässer von der hinteren Kammer in die vordere zu bringen, von wo sie abtransportiert werden können. Der Greifer des Transporters wird mit dem Feuerknopf des Joysticks (Port 2) bedient, doch erst dann, wenn Greifarme punktgenau am Faß anliegen. Ebenso vorsichtig muß man es auf den Boden stellen. In einem engen Stollen ist der Transport nicht einfach, doch mit genügend Geduld und etwas Übung ist auch das kein Problem.

(Thilo Herrmann/ah)
Ziffern 1 bis 9 Regeln die Geschwindigkeit des Cursors. Die Geschwindigkeit Eins ist normal.
Space Auf den Schnellgang schalten.
Pfeil links Den Editor auf den Normalmodus setzen.
CRSR-Tasten Mit ihnen kann man den Zeichencursor auf der Palette bewegen, um ein Zeichen auszuwählen.
DEL Loschen des Zeichens unter dem Cursor.
HOME Setzen des Zeichencursors auf das Leerzeichen.
L Löschen des Pseudoschirms.
F Farben neu bestimmen.
C Zeichensatz kopieren.
Z Zeichensatz laden.
F1 Abspeichern eines Pseudoschirms auf Disk oder Datasette.
F3 Laden eines Pseudoschirms von Disk oder Datasette.
M Mikromodus einschalten.
SHIFT-M Mikromodus neu definieren.
Klammeraffe Umschalten des Mikromodes zwischen Punkt setzen und Punkt löschen.
F7 Konturmodus einschalten.
K Kontur und Geschwindigkeit wählen.
SHIFT-K Kontur neu definieren. Das erste Zeichen wird mit den Cursortasten ausgewählt und mit Return festge- legt
Pfeil oben Kontur- und Mikromodus zurücksetzen.
W Wechselmodus einschalten.
SHIFT-W Wechselnde Zeichen neu definieren.
Die Zeichen kann man mit den Cursortasten auswählen und mit Return festlegen.
U Mehrere zusammenhängende Zeichen von der Palette übertragen. Exit mit Return.
S Mit der Tastatur direkt auf den Schirm nach Art einer Schreibmaschine schreiben.
Steuertasten: RVS ON, RVS OFF, DEL, Cursortasten, RETURN. Exit mit F7.
R Rechteck mit einem beliebigen Zeichen füllen. Der Punkt an dem sich der Cursor gerade befindet, wird nun als Eckpunkt betrachtet. Den gegenüberliegenden Eckpunkt wählt man mit dem Joystick und abschließendem Knopfdruck. Das Zeichen, mit dem das Rechteck ausgefüllt wird, ist durch den Zeichencursor auf der Palette festgelegt. Benutzung des Schnellgangs ist möglich. Abbruch mit Pfeil links.
T Rechteck übertragen. Der momentane Ort des Cursors wird als Ecke des Rechtecks angesehen. Die diagonal gegenüberliegende Ecke wird durch Bewegung des Cursors mit dem Joystick an die entsprechende Stelle festgelegt.
Anschließend legt man auf die gleiche Weise die linke obere Ecke der Kopie fest.
Eine Benutzung des Schnellgangs ist ebenfalls möglich. Abbruch mit Pfeil links.
A Ändern der X/Y-Ausdehnung und der Anfangsadresse. Wenn man auf die der Eingabe folgende Frage mit »J« antwortet, wird der komplette Pseudoschirm an die neue Anfangsadresse kopiert und vollständig umformatiert. Die dafür benötigte Zeit hängt maßgeblich von der Y-Ausdehnung ab.
CTRL-X Verlassen des Programms.
Tabelle 1. Zusammenfassung der Editorbefehle
PROGRAMM : SCROLL-MACHINE C000 CC00
-----------------------------------
C000 : A9 72 8D 08 03 A9 C5 8D   F6
C008 : 09 03 A9 1A 8D 11 03 A9   01
C010 : CA 8D 12 03 A2 00 BD C2   2C
C018 : C9 49 D3 20 D2 FF E8 E0   11
C020 : 2A D0 F3 60 78 A9 7F 8D   A9
C028 : 0D DC A9 01 8D 1A D0 AD   76
C030 : 6E C5 8D 12 D0 A9 18 8D   FC
C038 : 11 D0 A9 00 85 02 8D FF   BA
C040 : FF A9 4D 8D 14 03 A9 C0   9A
C048 : 8D 15 03 58 60 AD 19 D0   A5
C050 : 8D 19 D0 A5 02 F0 0E C9   C6
C058 : 01 F0 49 C9 02 D0 03 4C   A8
C060 : 84 C4 4C 2D C2 AD 69 C5   CA
C068 : 8D 21 D0 AD 5D 03 8D 11   B6
C070 : D0 AD 66 C5 8D 00 DD AD   15
C078 : 6C C5 8D 20 D0 AD 60 C5   B6
C080 : 8D 16 D0 AD 63 C5 8D 18   CD
C088 : D0 AD 6F C5 8D 12 D0 E6   3E
C090 : 02 A9 EC 8D 18 03 A0 C9   03
C098 : 8C 19 03 8D FA FF 8C FB   FD
C0A0 : FF 4C CD C4 AD 5C 03 8D   B6
C0A8 : 16 D0 AD 6A C5 8D 21 D0   CE
C0B0 : AD 64 C5 8D 18 D0 AD 6D   4C
C0B8 : C5 8D 20 D0 AD 67 C5 8D   AE
C0C0 : 00 DD AD 70 C5 8D 12 D0   DB
C0C8 : E6 02 AD B3 03 D0 0E AD   DB
C0D0 : B4 03 8D B3 03 AD 95 03   DA
C0D8 : F0 0B CE 95 03 A9 01 8D   51
C0E0 : 64 03 4C 2D C2 AD 94 03   70
C0E8 : 8D 95 03 A9 FF 38 ED 58   60
C0F0 : 03 29 07 18 6D 61 C5 8D   61
C0F8 : 5C 03 AD 5A 03 18 6D 71   16
C100 : C5 8D 5E 03 A9 FF 38 ED   DB
C108 : 5E 03 29 07 18 6D 5E C5   05
C110 : 8D 5D 03 A2 03 BD 58 03   E6
C118 : 9D 52 03 CA 10 F7 A2 03   4A
C120 : 4E 53 03 6E 52 03 4E 55   C8
C128 : 03 6E 54 03 CA D0 F1 AD   2E
C130 : A2 03 F0 03 4C 4F C1 A2   7C
C138 : 03 BD 52 03 DD 60 03 9D   37
C140 : 60 03 D0 0B CA 10 F2 A9   04
C148 : 01 8D 64 03 4C C2 C1 AC   C5
C150 : 54 03 20 0A CA B9 00 DE   A7
C158 : 8D D6 C4 B9 00 DF AC 55   15
C160 : 03 18 79 00 DE 8D D7 C4   11
C168 : 20 14 CA AD D6 C4 18 6D   C9
C170 : 52 03 8D D6 C4 AD D7 C4   25
C178 : 6D 53 03 8D D7 C4 AD D6   09
C180 : C4 18 6D FA CB 8D D6 C4   19
C188 : AD D7 C4 6D FB CB 8D D7   04
C190 : C4 A2 01 A9 00 8D B9 03   74
C198 : A0 07 BD D5 C4 18 6D FC   A3
C1A0 : CB 99 D5 C4 BD D6 C4 6D   C6
C1A8 : FD CB 99 D6 C4 8A 18 69   A0
C1B0 : 06 AA 98 18 69 06 A8 EE   7C
C1B8 : B9 03 AD B9 03 CD B7 03   19
C1C0 : 90 D8 AD 3E 03 D0 03 4C   4B
C1C8 : 22 C2 A0 01 B9 74 03 18   0F
C1D0 : 79 72 03 AA 29 07 99 72   AF
C1D8 : 03 8A 4A 4A 4A 99 70 03   35
C1E0 : 88 10 E9 AE A5 03 BD 00   2A
C1E8 : DC A2 01 A0 02 8D AC 03   AF
C1F0 : 29 01 D0 03 20 30 C2 AD   18
C1F8 : AC 03 29 02 D0 03 20 5C   0F
C200 : C2 AD AC 03 CA 88 88 29   8A
C208 : 04 D0 03 20 30 C2 AD AC   62
C210 : 03 29 08 D0 03 20 5C C2   EC
C218 : AD 3E 03 C9 01 F0 03 20   C2
C220 : 81 C2 20 9A C3 AD 9E 03   88
C228 : F0 03 20 04 C4 4C 31 EA   6C
C230 : B9 58 03 38 FD 70 03 99   80
C238 : 58 03 B9 59 03 E9 00 99   5E
C240 : 59 03 B0 05 A9 01 99 9F   30
C248 : 03 B9 6A 03 38 FD 4A 03   C5
C250 : 99 6A 03 B9 6B 03 E9 00   8D
C258 : 99 6B 03 60 B9 58 03 18   0E
C260 : 7D 70 03 99 58 03 B9 59   41
C268 : 03 69 00 99 59 03 B9 6A   BD
C270 : 03 18 7D 4A 03 99 6A 03   D5
C278 : B9 6B 03 69 00 99 6B 03   55
C280 : 60 AE 6A 03 AC 6B 03 20   A5
C288 : D7 C2 8E 7A 03 8C 7B 03   3C
C290 : 8D 48 03 AE 6C 03 AC 6D   44
C298 : 03 20 D7 C2 8E 7C 03 8C   EB
C2A0 : 7D 03 8D 49 03 20 2B C3   91
C2A8 : A2 01 A0 02 B9 7A 03 18   DF
C2B0 : 7D 4E 03 8D AC 03 B9 7B   88
C2B8 : 03 69 00 99 7B 03 AD AC   83
C2C0 : 03 9D 4E 03 B9 7B 03 99   3D
C2C8 : 7A 03 A9 00 99 7B 03 88   C1
C2D0 : 88 CA 10 D8 4C EE C2 98   55
C2D8 : C9 80 90 0F 98 49 FF A8   0C
C2E0 : 8A 49 FF AA E8 D0 01 C8   0F
C2E8 : A9 FF 60 A9 01 60 A2 01   7E
C2F0 : A0 02 BD 48 03 30 15 B9   83
C2F8 : 58 03 18 79 7A 03 99 58   DE
C300 : 03 B9 59 03 69 00 99 59   46
C308 : 03 4C 25 C3 B9 58 03 38   CE
C310 : F9 7A 03 99 58 03 B9 59   72
C318 : 03 E9 00 99 59 03 B0 05   BE
C320 : A9 01 99 9F 03 88 88 CA   D0
C328 : 10 C8 60 A0 02 A2 01 B9   75
C330 : 8F 03 D9 7B 03 90 0A D0   A5
C338 : 14 B9 8E 03 D9 7A 03 B0   0C
C340 : 0C B9 8E 03 99 7A 03 B9   1A
C348 : 8F 03 99 7B 03 B9 7A 03   1D
C350 : 38 FD 92 03 99 7A 03 B9   79
C358 : 7B 03 E9 00 99 7B 03 10   71
C360 : 08 A9 00 99 7A 03 99 7B   8D
C368 : 03 88 88 CA 10 C1 AE 7A   E9
C370 : 03 AC 7B 03 AD 48 03 10   52
C378 : 03 20 DC C2 8E 6A 03 8C   7C
C380 : 6B 03 AD 6A 03 AE 7C 03   C3
C388 : AC 7D 03 AD 49 03 10 03   5C
C390 : 20 DC C2 8E 6C 03 8C 6D   8D
C398 : 03 60 A2 00 BD 85 03 20   C8
C3A0 : F7 C3 9D 89 03 98 9D 8B   94
C3A8 : 03 BD 89 03 7D 87 03 A8   BE
C3B0 : 29 07 9D 87 03 98 4A 4A   68
C3B8 : 4A 8D FF 03 8A 0A A8 BD   40
C3C0 : 8B 03 30 15 AD FF 03 18   93
C3C8 : 79 58 03 99 58 03 B9 59   99
C3D0 : 03 69 00 99 59 03 4C EE   78
C3D8 : C3 B9 58 03 38 ED FF 03   E7
C3E0 : 99 58 03 B9 59 03 E9 00   F3
C3E8 : 99 59 03 8C C0 5D E8 E0   DD
C3F0 : 02 B0 03 4C 9C C3 60 A0   3F
C3F8 : 01 C9 80 90 06 49 FF A8   0C
C400 : 98 A0 FF 60 A2 00 A0 00   A1
C408 : BD 9F 03 D0 09 20 67 C4   28
C410 : F0 07 C9 01 F0 03 20 38   2E
C418 : C4 C8 C8 20 67 C4 F0 07   E5
C420 : C9 FF F0 03 20 38 C4 C8   EE
C428 : C8 E8 E8 E0 04 90 D9 A9   3A
C430 : 00 8D 9F 03 8D A1 03 60   F2
C438 : A9 01 8D AD 03 AD 9E 03   99
C440 : C9 01 F0 16 98 4A 29 01   0B
C448 : D0 08 C8 C8 20 5A C4 88   60
C450 : 88 60 88 88 20 5A C4 C8   B5
C458 : C8 60 B9 96 03 9D 58 03   16
C460 : B9 97 03 9D 59 03 60 B9   FC
C468 : 97 03 DD 59 03 90 0F D0   B6
C470 : 0A B9 96 03 DD 58 03 90   2B
C478 : 05 F0 06 A9 FF 60 A9 01   58
C480 : 60 A9 00 60 AD 6B C5 8D   29
C488 : 20 D0 AD 5C C5 8D 11 D0   B6
C490 : AD 62 C5 8D 18 D0 AD 65   1B
C498 : C5 8D 00 DD AD 6E C5 8D   60
C4A0 : 12 D0 A9 00 85 02 AD 5F   63
C4A8 : C5 8D 16 D0 AD 68 C5 8D   24
C4B0 : 21 D0 AD 64 03 D0 11 A5   77
C4B8 : 01 8D AF 03 A9 30 85 01   00
C4C0 : 20 D3 C4 AD AF 03 85 01   DC
C4C8 : A9 00 8D 64 03 68 A8 68   48
C4D0 : AA 68 40 A2 00 BD A1 04   8F
C4D8 : 9D A0 04 BD C9 04 9D C8   43
C4E0 : 04 BD F1 04 9D F0 04 BD   AD
C4E8 : 19 05 9D 18 05 BD 41 05   3C
C4F0 : 9D 40 05 BD 69 05 9D 68   AC
C4F8 : 05 BD 91 05 9D 90 05 BD   CF
C500 : B9 05 9D B8 05 BD E1 05   8A
C508 : 9D E0 05 BD 09 06 9D 08   56
C510 : 06 BD 31 06 9D 30 06 BD   F1
C518 : 59 06 9D 58 06 BD 81 06   47
C520 : 9D 80 06 BD A9 06 9D A8   C9
C528 : 06 BD D1 06 9D D0 06 BD   36
C530 : F9 06 9D F8 06 BD 21 07   94
C538 : 9D 20 07 BD 49 07 9D 48   33
C540 : 07 BD 71 07 9D 70 07 BD   58
C548 : 99 07 9D 98 07 BD C1 07   53
C550 : 9D C0 07 E8 E0 28 F0 03   45
C558 : 4C D5 C4 60 1B 17 10 C8   08
C560 : C8 C0 15 34 34 97 94 94   D0
C568 : 06 01 0E 06 01 06 51 58   69
C570 : F8 05 20 73 00 C9 5F F0   0F
C578 : 06 20 79 00 4C E7 A7 20   D0
C580 : 85 C5 4C AE A7 A0 01 A2   99
C588 : 00 B1 7A DD 86 C9 D0 0B   CB
C590 : C8 E8 B1 7A DD 86 C9 F0   A3
C598 : 0E CA 88 E8 E8 E0 3C B0   32
C5A0 : 03 4C 89 C5 4C 08 AF 20   E8
C5A8 : 73 00 CA BD 4A C9 8D BE   2C
C5B0 : C5 BD 4B C9 8D BF C5 20   8E
C5B8 : 73 00 20 73 00 4C 5E C6   0B
C5C0 : A2 A8 A9 00 9D 3B 03 CA   76
C5C8 : D0 FA 8D FA CB 8D FD CB   91
C5D0 : A9 A0 A2 CC 8D D9 C4 8E   E3
C5D8 : DA C4 A2 15 20 AE C7 A9   49
C5E0 : A0 8D FB CB A9 80 8D FC   8E
C5E8 : CB 20 AC C6 A9 FE 8D 61   53
C5F0 : 03 8D 63 03 60 20 9E B7   E4
C5F8 : 8A D0 2F A9 FF 85 02 AD   7B
C600 : 68 C5 8D 21 D0 AD 6B C5   86
C608 : 8D 20 D0 AD 5C C5 29 F8   1A
C610 : 09 0B 8D 11 D0 AD 65 C5   C0
C618 : 8D 00 DD AD 5F C5 09 08   2B
C620 : 8D 16 D0 AD 62 C5 8D 18   5D
C628 : D0 60 20 24 C0 60 20 3F   C3
C630 : C9 8D 58 03 8E 59 03 20   36
C638 : FD AE 20 3F C9 8D 5A 03   F5
C640 : 8E 5B 03 60 20 3F C9 8D   87
C648 : 85 03 20 FD AE 20 3F C9   93
C650 : 8D 86 03 60 20 04 C9 8D   52
C658 : 4A 03 8E 4B 03 60 78 A9   99
C660 : E4 8D 08 03 A9 A7 8D 09   8D
C668 : 03 20 15 FD 20 A3 FD 20   D8
C670 : 18 E5 58 60 20 04 C9 8D   01
C678 : 92 03 8E 93 03 60 20 26   A2
C680 : C9 8D 8E 03 8E 8F 03 20   C6
C688 : 38 C9 8D 90 03 8E 91 03   0B
C690 : 60 20 26 C9 8D FA CB 8E   C0
C698 : FB CB 20 38 C9 8D FC CB   1C
C6A0 : 8E FD CB 20 38 C9 8D FE   2A
C6A8 : CB 8E FF CB 78 20 0A CA   7A
C6B0 : A2 00 86 FB 86 FC A5 FB   52
C6B8 : 9D 00 DE A5 FC 9D 00 DF   3E
C6C0 : A5 FB 18 6D FC CB 85 FB   53
C6C8 : A5 FC 6D FD CB 85 FC E8   B5
C6D0 : D0 E4 20 14 CA 58 60 A9   E1
C6D8 : 00 A2 04 9D 69 03 CA D0   5A
C6E0 : FA 20 9E B7 8E 3E 03 F0   52
C6E8 : 17 20 31 C9 8E 74 03 20   6E
C6F0 : 31 C9 8E 75 03 F0 09 20   74
C6F8 : 31 C9 8A 29 01 8D A5 03   EF
C700 : 60 20 9E B7 8E 9E 03 60   B9
C708 : 20 26 C9 85 FB 86 FC 20   86
C710 : 38 C9 8D A6 03 8E A7 03   AE
C718 : 20 38 C9 85 FD 86 FE 20   C8
C720 : FD AE 20 04 C9 8D A9 03   B3
C728 : 8E AA 03 A5 01 8D A8 03   A6
C730 : A0 00 78 AE A9 03 86 01   93
C738 : B1 FB AE AA 03 86 01 91   73
C740 : FD A5 FC CD A7 03 90 0E   FA
C748 : A5 FB CD A6 03 90 07 AD   5F
C750 : A8 03 85 01 58 60 E6 FB   17
C758 : D0 02 E6 FC E6 FD D0 02   28
C760 : E6 FE 4C 33 C7 20 26 C9   E8
C768 : 8D 96 03 8E 97 03 20 38   55
C770 : C9 8D 98 03 8E 99 03 20   88
C778 : 38 C9 8D 9A 03 8E 9B 03   65
C780 : 20 38 C9 8D 9C 03 8E 9D   38
C788 : 03 60 20 9E B7 8E 95 03   E3
C790 : 8E 94 03 60 20 9E B7 8E   28
C798 : A2 03 60 20 26 C9 8D D9   73
C7A0 : C4 8E DA C4 20 31 C9 E0   6F
C7A8 : 16 90 03 4C 48 B2 8E B7   14
C7B0 : 03 78 A9 00 8D B8 03 A2   4A
C7B8 : 04 A0 0A A9 9D 9D D4 C4   68
C7C0 : A9 BD 9D D1 C4 EE B8 03   96
C7C8 : AD B8 03 CD B7 03 B0 1E   DE
C7D0 : BD D5 C4 18 69 28 99 D5   96
C7D8 : C4 BD D6 C4 69 00 99 D6   74
C7E0 : C4 8A 18 69 06 AA 98 18   65
C7E8 : 69 06 A8 4C BB C7 A0 7C   7D
C7F0 : 8A 69 09 8D BA 03 B9 D7   7D
C7F8 : C4 9D D7 C4 E8 C8 EC BA   17
C800 : 03 90 F3 58 CE B7 03 60   CB
C808 : 20 11 C9 8D 5C C5 8E 5D   BE
C810 : C5 8C 5E C5 60 20 11 C9   4A
C818 : 8D 5F C5 8E 60 C5 8C 61   C1
C820 : C5 60 20 26 C9 85 FB 86   A8
C828 : FC 20 38 C9 8D B1 03 8E   0B
C830 : B2 03 A5 01 8D AE 03 20   88
C838 : 31 C9 8E B0 03 F0 0B 20   2C
C840 : 31 C9 78 A5 01 8D AE 03   66
C848 : 86 01 AD B0 03 A0 00 91   29
C850 : FB A6 FB EC B1 03 D0 0E   CD
C858 : A6 FC EC B2 03 90 07 AD   3A
C860 : AE 03 85 01 58 60 E6 FB   2D
C868 : D0 02 E6 FC 4C 4F C8 20   35
C870 : 11 C9 8D 62 C5 8E 63 C5   FF
C878 : 8C 64 C5 60 20 11 C9 8D   81
C880 : 68 C5 8E 69 C5 8C 6A C5   92
C888 : 60 20 9E B7 E0 01 D0 09   02
C890 : 8E B4 03 A9 00 8D B3 03   B0
C898 : 60 A9 00 8D B4 03 8D B3   80
C8A0 : 03 60 20 11 C9 8D 6B C5   40
C8A8 : 8E 6C C5 8C 6D C5 60 20   36
C8B0 : 11 C9 8D 6E C5 8E 6F C5   F1
C8B8 : 8C 70 C5 60 A9 00 A2 D0   C0
C8C0 : 85 FB 86 FC 85 FD 86 FE   E4
C8C8 : A9 FF A2 D7 8D A6 03 8E   4C
C8D0 : A7 03 A9 33 A2 30 4C 25   F1
C8D8 : C7 60 20 11 C9 8D 65 C5   24
C8E0 : 8E 66 C5 8C 67 C5 60 20   0B
C8E8 : 9E B7 8A A2 00 9D 00 D8   F7
C8F0 : 9D 00 D9 9D 00 DA 9D 00   05
C8F8 : DB E8 D0 F1 60 20 9E B7   AB
C900 : 8E 71 C5 60 20 9E B7 8E   B7
C908 : AB 03 20 31 C9 AD AB 03   22
C910 : 60 20 04 C9 8D A3 03 8E   DA
C918 : A4 03 20 31 C9 8A A8 AD   5B
C920 : A3 03 AE A4 03 60 20 8A   4E
C928 : AD 20 F7 B7 A5 14 A6 15   9A
C930 : 60 20 FD AE 20 9E B7 60   8C
C938 : 20 FD AE 20 26 C9 60 20   79
C940 : 8A AD 20 9B BC A5 65 A6   F8
C948 : 64 60 89 C8 C0 C5 F5 C5   F5
C950 : 2E C6 44 C6 54 C6 74 C6   A6
C958 : 7E C6 D7 C6 01 C7 65 C7   7B
C960 : 8A C7 94 C7 08 C8 15 C8   99
C968 : 6F C8 7C C8 A2 C8 AF C8   34
C970 : E7 C8 FD C8 DA C8 9B C7   46
C978 : 08 C7 91 C6 22 C8 B4 CA   72
C980 : 32 CB 5E C6 BC C8 53 59   1A
C988 : 52 53 55 53 50 4F 42 57   7B
C990 : 54 42 54 52 54 47 4A 53   B4
C998 : 47 4D 47 52 41 53 54 4D   3D
C9A0 : 31 52 32 52 4D 43 48 46   6E
C9A8 : 52 46 52 5A 5A 46 53 55   CD
C9B0 : 43 49 56 49 55 54 4D 54   2C
C9B8 : 46 55 4C 44 53 56 4F 46   F6
C9C0 : 43 50 DE C1 F3 80 90 81   A4
C9C8 : 9C 9F 9F FE 9E 92 90 9B   F3
C9D0 : 9A 9D 96 FF F3 E2 EA EB   B8
C9D8 : E6 F3 91 8A F3 87 9B 9A   8D
C9E0 : 9F 9C F3 9B 96 81 81 9E   F6
C9E8 : 92 9D 9D F3 A9 37 85 01   9B
C9F0 : A2 00 A0 00 8E 11 D0 E8   41
C9F8 : D0 FD C8 D0 FA A9 04 8D   3B
CA00 : 88 02 4C 66 FE EA EA EA   32
CA08 : EA EA A6 01 8E B5 03 A2   19
CA10 : 30 86 01 60 AE B5 03 86   81
CA18 : 01 60 20 9B BC A5 64 F0   31
CA20 : 03 4C A2 CA C6 65 A5 65   44
CA28 : C9 FF F0 1B C9 02 F0 22   45
CA30 : C9 03 90 07 C9 09 90 29   F9
CA38 : 4C 76 CA 0A AA BD 58 03   B3
CA40 : A8 BD 59 03 4C 95 B3 AC   17
CA48 : AD 03 A9 00 8D AD 03 4C   CC
CA50 : 95 B3 AD 0C C5 18 69 13   95
CA58 : A8 AD 0D C5 69 00 4C 98   CC
CA60 : CA 38 E9 03 AA BD 00 DC   73
CA68 : 29 10 D0 05 A0 01 4C A2   F7
CA70 : B3 A0 00 4C A2 B3 38 E9   79
CA78 : 09 0A AA BD 92 CA 85 FB   76
CA80 : BD 93 CA 85 FC A0 01 B1   A6
CA88 : FB 88 AA B1 FB A8 8A 4C   70
CA90 : 98 CA FA CB FC CB FE CB   87
CA98 : 84 63 85 62 A2 90 38 4C   A4
CAA0 : 49 BC 85 66 A0 00 78 20   A2
CAA8 : 0A CA B1 65 20 14 CA 58   AF
CAB0 : A8 4C A2 B3 20 CE CB 20   85
CAB8 : 79 00 8D F8 CB F0 07 20   54
CAC0 : 38 C9 85 FB 86 FC A0 00   90
CAC8 : 20 DB CB B0 59 20 B1 CB   D4
CAD0 : D0 54 A2 6F 20 C6 FF AD   F4
CAD8 : F8 CB D0 28 20 CF FF 85   7A
CAE0 : FB 8D FA CB 20 CF FF 85   65
CAE8 : FC 8D FB CB 20 CF FF 8D   BF
CAF0 : FC CB 20 CF FF 8D FD CB   D0
CAF8 : 20 CF FF 8D FE CB 20 CF   20
CB00 : FF 8D FF CB 20 CF FF 78   B1
CB08 : A0 00 20 0A CA 91 FB 20   5B
CB10 : 14 CA 58 20 B7 FF D0 0E   7E
CB18 : 20 A7 CB B0 09 E6 FB D0   6E
CB20 : E3 E6 FC 4C 04 CB A9 6F   63
CB28 : 20 C3 FF 20 CC FF 20 AC   D4
CB30 : C6 60 20 CE CB 20 38 C9   3A
CB38 : 85 FD 86 FE A0 01 20 DB   87
CB40 : CB B0 E3 20 B1 CB D0 DE   DB
CB48 : AD FA CB AE FB CB 85 FB   67
CB50 : 86 FC A2 6F 20 C9 FF A5   86
CB58 : FB 20 D2 FF A5 FC 20 D2   80
CB60 : FF AD FC CB 20 D2 FF AD   E2
CB68 : FD CB 20 D2 FF AD FE CB   AE
CB70 : 20 D2 FF AD FF CB 20 D2   33
CB78 : FF 78 20 0A CA A0 00 B1   12
CB80 : FB 20 14 CA 58 20 D2 FF   BC
CB88 : 20 B7 FF D0 99 20 A7 CB   6F
CB90 : B0 94 A5 FC C5 FE D0 06   37
CB98 : A5 FB C5 FD F0 88 E6 FB   53
CBA0 : D0 D7 E6 FC 4C 79 CB 38   E5
CBA8 : AD 01 DC C9 7F F0 01 18   FA
CBB0 : 60 A9 08 85 BA 20 B4 FF   17
CBB8 : A9 6F 85 B9 20 96 FF 20   A8
CBC0 : A5 FF 8D F9 CB 20 AB FF   74
CBC8 : AD F9 CB C9 30 60 20 FB   1C
CBD0 : C5 20 9E AD 20 A3 B6 20   3D
CBD8 : BD FF 60 A9 6F A2 08 20   4F
CBE0 : BA FF 20 C0 FF 60 FF 60   7E
CBE8 : 49 54 45 53 A0 A0 A0 A0   EA
CBF0 : A0 A0 A0 A0 A0 00 00 00   27
CBF8 : 00 00 00 A0 80 00 05 00   29
Listing 1. Hauptprogramm »Scroll-Machine«. Das Programm ist mit dem MSE einzugeben.
0 rem************ editor **************
1 rem*--------------------------------*
2 rem*                                *
3 rem*   (c) 1985 by thilo herrmann   *
4 rem*         poststr. 6             *
5 rem*         7321 b\rtlingen        *
6 rem*                                *
7 rem*         tel. 07161/52592       *
8 rem*--------------------------------*
9 rem**********************************
10 :
100 ifpeek(50000)=56andpeek(50001)=253then160
110 print"scroll-machine laden !"
120 end
130 :
140 :
150 rem erweiterung ein
160 sys49152
170 rem basic-speicher ueber 20000
180 rem       freihalten
190 poke56,78:poke55,32:clr
200 ze=160:v=53248:as=1024:sp=53240:m=1
210 sx=40:sy=180:tt=197:nt=64
220 xk=64:yk=8
230 h1=8:h2=16:h3=255:h4=256
240 uf=55296: rem zwischenspeicher
250 a(0)=1:a(1)=0:a(2)=128
260 pokev+21,0
270 a=3:gosub2240
280 gosub2280
290 :
300 rem *** eingabe ***
310 gosub2500:_us0
320 print"{clr}{wht}"
330 sa=40960:xd=128:yd=64
340 gosub4860
350 :
360 :
370 rem zeichensatz kopieren
380 print"{clr}":gosub5010
390 :
400 rem *** parameter setzen ***
410 _rs:_zf14
420 s2=sa-19-7*xd:gosub2130
430 _mts2,xd,yd
440 _js1,64,64
450 _gm1:_grxd*8,xd*16-8,0,yd*8-8
460 df=3*xd
470 :
480 rem textfenster verlegen
490 _rz40,50,164
500 _su0:_1r31,23,16
510 _rf6,6,6:_vi52224,15
520 :
530 ifwhthen760
540 _fu52224,53223,32
550 _us1:gosub2500:gosub3080
560 f(1)=14:f(4)=6
570 ifc=1thenf(1)=0:f(2)=7:f(3)=8:f(4)=10
580 gosub2500:gosub2930
590 :
600 rem palette erstellen
610 a=52867:b=40:c=32
620 fori=0to7
630 fort=0to31
640 pokea+i*b+t,i*c+t
650 nextt,i
660 :
670 rem *** loeschen ***
680 gosub2500:print"loeschen (j/n)?"
690 gosub2060:onagoto700,760
700 print"{up}wirklich (j/n)?"
710 gosub2060:onagoto720,760
720 _fusa,ea,32
730 :
740 :
750 rem *** sprites ***
760 _fuas,as+62,.
770 fort=as+6tot+21step3:poket,3:next
780 fort=as+8tot+21step3:poket,192:next
790 pokeas+31,255:pokeas+4,255
800 _ut as,as+64,55296,48,48
810 pokesp,96:pokesp+1,96
820 pokev,175:pokev+1,100
830 pokev+2,0:pokev+3,180
840 pokev+40,7
850 pokev+21,3
860 :
870 _fu960,1023,0
880 _fu1024,2023,32
890 _fu2040,2047,15
900 gosub2570
910 :
920 ifwhthen970
930 wh=1:rem flag setzen
940 :
950 rem auf 0,0 -position setzen
960 _poxd*8,0
970 _tm1:_us1:print
980 e$="~":gosub4760:goto1070
990 :
1000 :
1010 rem ***** hauptroutine *****
1020 :
1030 rem *** tastaturabfrage ***
1040 rem cursortasten abfragen
1050 gete$:ife$=""then1490
1060 ife$="{up}"ore$="{down}"ore$="{left}"ore$="{rght}"thengosub2730:goto1410
1070 e=val(e$)
1080 rem zeichen unter cursor loeschen
1090 ifpeek(tt)=.ore$=chr$(20)thenpokepo,32:goto1490
1100 ife$=" "thengosub4300
1105 ife$="@"then5430
1110 ife$="r"thengosub4370
1120 ife>0then:_ase-1
1130 ife$="{home}"thenze=32
1140 gosub2500
1150 _fu1024,2023,32
1160 ife$="l"then680
1170 :
1180 :
1190 gosub2690
1200 ife$="{f7}"thengosub2250
1210 ife$="k"thengosub2200
1220 ife$="m"thengosub4820
1230 ife$="M"thengosub5230
1240 ife$="{f1}"then1790
1250 ife$="{f3}"then1890
1260 ife$="{CTRL-X}"thenpoke648,4:_us0:print"{clr}";:end
1270 ife$="f"thengosub2910
1280 ife$="z"then3140
1290 ife$="W"thengosub3420
1300 ife$="s"thengosub3230
1310 ife$="c"thengosub5010
1320 ife$="w"thengosub4700
1330 ife$="a"then5080
1340 ife$="u"thengosub3570
1350 ife$="t"then5540
1360 ife$="K"thengosub3700
1370 ife$="^"thengosub5360
1390 ife$="_"thengosub4760
1400 rem bildschirm zuruecksetzen
1410 gosub2570:print
1420 _fu55896,56295,fs
1430 _fu55296,55855,f(4)
1440 pokev+39,1:poke198,0
1450 xc=zeand31:yc=int(ze/32)
1460 ut=1:gosub2780:ut=0
1470 printtab(26)"{up}{rght}{wht}nr. :"ze"{left}  "
1480 :
1490 gosub1580
1500 ifm2thengosub1630
1510 ifusr(4)then:gosub1540:pokepo,ze
1520 _sy1
1530 gosub1690:goto1050
1540 ifm1thenze=k(paand7,km):pa=usr(kd)
1550 ifwethenze=ze+1:ifze>w2thenze=w1
1560 return
1565 :
1570 rem adresse berechnen
1580 po=usr(3)-df
1590 ifpo<.thenpo=65536+po
1600 return
1610 :
1620 rem micro-punkt berechnen
1630 pu=p2((p1and1)+(p2and1)*2)
1640 ze=s(r(usr(po))orpu)
1650 p1=usr(1)/4:p2=usr(2)/4
1660 return
1670 :
1680 rem x- und y-koordinaten printen
1690 gosub1750
1700 print"{up}x:"xp;
1710 print"{left} y:"yp;
1720 print"{left} addr:"po"{left}   "
1730 return
1740 :
1750 xp=int(usr(1)/8-xd)
1760 yp=int(usr(2)/8):return
1770 :
1780 rem *** abspeichern ***
1790 print"{rght}abspeichern (j/n)?"
1800 gosub2060:onagoto1810,1410
1810 gosub5780:ifa$="k"then3960
1820 _mtsa,xd,yd
1830 _us0
1840 open1,8,15,"s:"+n$:gosub1990
1850 _sv n$,ea
1860 gosub1980:goto420
1870 :
1880 rem *** laden ***
1890 print"{rght}laden (j/n)?"
1900 gosub2060:onagoto1910,1410
1910 gosub5780:ifa$="k"then4190
1920 _ld n$
1930 gosub1980:ifenthen1950
1940 sa=usr(10):xd=usr(11):yd=usr(12)
1950 goto420
1960 :
1970 rem floppymeldung
1980 _us0:open1,8,15
1990 input#1,en,er$,et,es
2000 close1:_us1
2010 if er$="ok"then return
2020 print"{down}{rght}"en;er$;et;es
2030 wait197,63:poke198,0:return
2040 :
2050 rem j/n eingabe
2060 poke198,0
2070 geta$
2080 ifa$="j"thena=1:return
2090 ifa$<>"n"then2070
2100 a=2:return
2110 :
2120 rem endadresse berechnen
2130 ea=sa+xd*yd-1:return
2140 :
2150 :
2160 rem hi/lo-byte umrechnung
2170 h=int(a/256):l=a-h*256:return
2180 :
2190 rem kontur einstellen
2200 gosub3880
2210 input"geschwindigkeit:{rght}{rght}8{left}{left}{left}";ge
2220 ifa<3then:xk=ge:yk=64:goto2240
2230 yk=ge:xk=64
2240 km=a:kd=(a-1)/2+1
2250 we=0:m1=1:m2=0:_js1,xk,yk:return
2260 :
2270 rem micro-datas
2280 data 32,108,123,98,124,225,255,254,126,127,97,252,226,251,236,160
2290 dimr(255),s(15)
2300 restore
2310 fori=0to15
2320 reada:s(i)=a:r(a)=i:next
2330 :
2340 fori=0to3:p2(i)=2^(3-i):next
2350 :
2360 rem y - datas
2370 data100,111,121,98,248,247,227,160
2380 fori=7to0step-1:reada:k(i,3)=a
2390 k(i,4)=a+128and255:next
2400 :
2410 rem x - datas
2420 data101,116,117,97,246,234,231,160
2430 fori=0to7:reada:k(i,1)=a
2440 k(i,2)=a+128and255:next
2450 :
2460 return
2470 :
2480 :
2490 rem normal schalten
2500 poke648,4
2510 _mc21,52,52
2520 _ci151,148,148
2530 gosub2650
2540 return
2550 :
2560 rem palette einschalten
2570 _mc52,52,52
2580 _ci148,148,148
2590 poke648,204
2600 poke214,14:print
2610 _fu55856,55895,6:rem hin.far.
2620 return
2630 :
2640 rem cursor setzen + zeile loeschen
2650 poke214,14:print:print"                                       {up}"
2660 return
2670 :
2680 rem auf vielfaches von 8 setzen
2690 gosub1750:_poxd*8+xp*8,yp*8:return
2700 :
2710 :
2720 rem wahl des characters
2730 ife$="{up}"thenyc=yc-1:ifyc<0thenyc=7
2740 ife$="{down}"thenyc=yc+1:ifyc>7thenyc=0
2750 ife$="{left}"thenxc=xc-1:ifxc<0thenxc=31
2760 ife$="{rght}"thenxc=xc+1:ifxc>31thenxc=0
2770 rem spritesteuerung
2780 cx=xc*h1+sx
2790 pokev+2,cxandh3
2800 pokev+h2,sgn(cxandh4)*2
2810 pokev+3,sy+yc*h1
2820 :
2830 ifutthen2860
2840 ifpeek(tt)<>ntthengete$:goto2730
2850 gosub2570:print
2860 ze=yc*32+xc:rem zeichen berechnen
2870 return
2880 :
2890 :
2900 rem farbeneingabe
2910 gosub3080
2920 :
2930 print
2940 a=1:gosub3050:
2950 oncgoto2960,2980
2960 a=2:gosub3050:pokev+34,f(2)
2970 a=3:gosub3050:pokev+35,f(3)
2980 _2r200+b,200,192+b
2990 a=4:gosub3050:_hf6,6,f(1)
3000 :
3010 fs=f(4)
3020 ifb=0thenfs=f(1)
3030 gosub2570:return
3040 :
3050 print"{up}farbe"a":  "f(a)"{left} "
3060 print"{up}"tab(10);:inputf(a):return
3070 :
3080 print"multicolor (j/n)?"
3090 gosub2060:gosub2500:b=(1-(a-1))*16:c=a
3100 return
3110 :
3120 :
3130 rem zeichensatz laden
3140 print"{rght}{rght}zeichensatz laden (j/n)?"
3150 gosub2060:onagoto3160,3190
3160 input"{down}{rght}name: ";n$
3170 rem laden an 53248 - 2
3180 _ld n$,53246:gosub1980
3190 goto420
3200 :
3210 :
3220 rem schreiben
3230 _sy0:_tm0:_js0:rt=usr(1)
3240 x=usr(1):y=usr(2)
3250 geta$:ifa$="{f7}"then:_tm1:_js1:return
3260 ifa$=""then3250
3270 a=asc(a$)
3280 rem cursorsteuercodes beachten
3290 ifa=32then3360
3300 ifa=20ora=157thenx=x-8:goto3380
3310 ifa=29thenx=x+8:goto3380
3320 ifa=17theny=y+8:goto3380
3330 ifa=145theny=y-8:goto3380
3340 ifa=13theny=y+8:x=rt:goto3380
3350 ifa=18ora=146thenprinta$;:goto3250
3360 print"{home}"a$;:a=peek(1024)
3370 pokeusr(3)-df,a:x=x+8
3380 _pox,y:goto3240
3390 :
3400 :
3410 rem wechsel
3420 gosub2570:gosub2650
3430 print"wechsel von":gosub3500
3440 w1=ze
3450 print"{up}wechsel bis":gosub3500
3460 w2=ze:ifw2<w1then3450
3470 we=1:return
3480 :
3490 rem waehlen des zeichens
3500 gosub2730
3510 gete$:ife$=chr$(13)thenreturn
3520 ife$=""then3510
3530 goto3500
3540 :
3550 :
3560 rem uebertragen
3570 gosub2570:gosub2650
3580 y2=yc:x2=xc:ut=1
3590 print"uebertragen !"
3600 gete$:ife$=chr$(13)thenut=.:return
3610 ife$=""then3600
3620 gosub2730
3630 a=usr(3)-df+xc-x2+yc*xd-y2*xd
3640 ifa>=saanda<=eathenpokea,ze
3650 _sy1
3660 goto3600
3670 :
3680 :
3690 rem konturen definieren
3700 gosub3880:a2=a
3710 gosub2570:gosub2650
3720 print"erstes element ?"
3730 gosub3500
3740 gosub2650
3750 :
3760 rem austeigend oder fallend
3770 print"1...[-1] / 2...[+1]"
3780 geta$:a=val(a$)*2-3
3790 ifa<-1ora>1then3780
3800 a3=0
3810 rem in variablen schreiben
3820 fori=-3.5*ato3.5*astepa
3830 k(i+4,a2)=ze+a3:a3=a3+1:next
3840 a=a2:gosub2650:goto2210
3850 :
3860 :
3870 rem wahl des konturmodes
3880 print"1...x+ B 2...x- B 3...y+ B 4...y-
3890 geta$:a=val(a$)
3900 ifa<1ora>4then3890
3910 return
3920 :
3930 :
3940 rem abspeichern auf kassette
3950 rem schreiben von sa,xd,yd
3960 _of:open1,1,1,n$:print#1,sa","xd","yd:close1
3970 rem schreiben des schirms
3980 gosub4050:a=sa:gosub2170
3990 poke251,l:poke252,h
4000 a=ea+1:gosub2170
4010 poke780,251:poke781,l:poke782,h
4020 sys65496:close1:sys49152:goto410
4030 :
4040 rem oeffnen des kassettenkanals
4050 l=len(n$):poke183,l
4060 s=256*204
4070 ifl=0then4100
4080 forx=1tol
4090 pokes+x-1,asc(mid$(n$,x,1)):next
4100 poke780,1:poke781,1:poke782,0
4110 sys65466
4120 poke780,l:poke781,0
4130 poke782,204:sys65469
4140 return
4150 :
4160 :
4170 rem laden von kassette
4180 rem lesen von sa,xd,yd
4190 _of:open1,1,0,n$:input#1,s2,x2,y2:close1
4200 rem lesen des schirms
4210 gosub4050:a=s2:gosub2170
4220 poke780,0:poke781,l:poke782,h
4230 sys65493
4240 if(st and 48)thenprint"{down}band fehler !":close1:wait197,63:goto410
4250 sa=s2:xd=x2:yd=y2:sys49152:goto410
4260 :
4270 :
4280 rem schnellgang
4290 rem syncronisation aus + hf=gruen
4300 _sy0:_rf6,6,5:pokev+39,1
4310 gosub1580:gosub1690
4320 gete$:ife$=""then4310
4330 e$="":_rf6,6,6:return
4340 :
4350 :
4360 rem rechteck ausfuellen
4370 gosub4480:rem bereich waehlen
4380 ife$="_"thenreturn
4390 :
4400 rem rechteck fuellen
4410 fori=ystoyp
4420 br=ps+(yp-i)*xd
4430 _fu br,br+(xp-xs),ze
4440 next
4450 e$="":return
4460 :
4470 rem bereich waehlen
4480 xs=xp:ys=yp:ps=po:g=usr(ps)
4490 pokeps,(usr(ps)+128)andh3
4500 pokev+39,peek(v+39)+1andh3
4510 _sy1
4520 gosub1580:gosub1690
4530 ifusr(4)then4590
4540 gete$
4550 ife$=""then4490
4560 ife$=" "thengosub4300
4570 ife$="_"thenpokeps,g:goto4760
4580 goto4490
4590 pokeps,g
4600 :
4610 rem normalisieren
4620 ifxp-xs<0thena=xp:xp=xs:xs=a
4630 ifyp-ys<0thena=yp:yp=ys:ys=a
4640 ps=sa+ys*xd+xs
4650 return
4660 :
4670 :
4680 :
4690 rem umschalten auf wechselmodus
4700 we=we+1and1
4710 ifwethenze=w1:return
4720 goto2860
4730 :
4740 :
4750 rem reset
4760 m1=0:m2=0:gosub2690:_js1,64,64
4770 we=0:ze=160
4780 return
4790 :
4800 :
4810 rem micro - mode setzen
4820 m2=1:m1=0:we=0:_js1,32,32:return
4830 :
4840 :
4850 rem eingabe von aa,xd,yd
4860 gosub2650
4870 print"{rght}{rght}x- und y-ausdehnung   "xd","yd
4880 print"{up}"spc(23);:inputxd,yd
4890 print"{down}{rght}{rght}startadresse   "sa
4900 print"{up}"spc(16);:inputsa
4910 ifxd<1oryd<1then4860
4920 gosub2130
4930 print"{down}{rght}{rght}start:"sa"  ende:"ea
4940 ifsa<20000or(sa>49152andsa<57344)orsa>65530then4860
4950 if(ea>49152andea<57344)orea>65535then4860
4960 print"{down}{rght}{rght}{rght}richtig (j/n)?"
4970 gosub2060:onagoto4980,4860
4980 return
4990 :
5000 rem zeichensatz vom rom ins ram
5010 gosub2500:print"{rght}{rght}zeichensatz kopieren (j/n)?"
5020 gosub2060:onagoto5030,5040
5030 _cp
5040 return
5050 :
5060 :
5070 rem umformatieren eines schirms
5080 sf=sa:ef=ea:xf=xd:yf=yd
5090 gosub4860:_us0:l=48
5100 l1=0:l2=yf-1:l3=1
5110 ifxd>xfthenl1=yf-1:l2=0:l3=-1
5120 :
5122 print"{clr} schirm an neue adresse kopieren (j/n)?"
5123 gosub 2060:on a goto 5140,5190
5130 :
5140 fori= l1 to l2 step l3
5150 a=sf+xf*i:b=sf+xf*(i+1)-1:c=b-a
5160 _ut a,b,uf,l,l
5170 _ut uf,uf+c,sa+xd*i,l,l
5180 next
5190 goto420
5200 :
5210 :
5220 rem micro-zeichen definieren
5230 gosub2570:gosub2650
5240 print"erstes element ?"
5250 gosub3500:rem zeichen waehlen
5260 ifze>240then5250
5270 gosub5320
5280 fori=0to15:s(i)=i+ze:r(i+ze)=i
5290 next
5300 goto4820
5310 :
5320 fori=0to255:r(i)=.:next:return
5330 :
5340 :
5350 rem kontur und micro reset
5360 print"kontur und micro zuruecksetzen (j/n)?"
5370 gosub2060:onagoto5380,5390
5380 gosub5320:gosub2300
5390 return
5400 :
5410 :
5420 rem micro-mode umschalten
5430 r(32)=15-r(32)
5440 fori=0to15
5450 r(s(i))=15-i
5460 next
5470 fori=0to7
5480 a=s(i):s(i)=s(15-i):s(15-i)=a
5490 next
5500 goto1490
5510 :
5520 :
5530 rem transfer eines bereiches
5540 gosub4480:rem bereich waehlen
5550 ife$="_"then420
5560 gosub2650:print"wohin (linker oberer punkt) ?{up}"
5570 ifusr(4)then5570
5580 pt=ps:xt=xs:yt=ys
5590 xr=xp:yr=yp:gosub4480
5600 ife$="_"then420
5610 :
5620 rem rechteck uebertragen
5630 _us0
5640 ifpo>ptthenl1=yt:l2=yr:l3=1:goto5660
5650 l1=yr:l2=yt:l3=-1
5660 l=48
5670 fori=l1tol2stepl3
5680 br=(yr-i)*xd
5690 a=(xr-xt)
5700 _ut pt+br,pt+br+a,uf,l,l
5710 ifpo+br+a>eathen5730
5720 _ut uf,uf+a,po+br,l,l
5730 next
5740 goto420
5750 :
5760 :
5770 rem eingabe fuer disk & kassette
5780 n$="":input"{down}{rght}{rght}name: ";n$
5790 print"{down}{rght}{rvon}d{rvof}isk oder {rvon}k{rvof}assette ?
5800 geta$:ifa$<>"k"anda$<>"d"then5800
5810 return
5820 gosub2280:restore
5830 fori=0to15
5840 r(s(i))=15-i:reada:s(15-i)=a+128and255
5850 next
5860 fori=0to15:prints(i);:next
Listing 2. Editor »Scroll-Machine«. Zur sicheren Eingabe verwenden Sie bitte den Checksummer.
100 ifhthenpoke45,l:poke46,h:goto160
110 ifpeek(50000)=56andpeek(50001)=253then160
120 l=peek(45):h=peek(46)
140 load"scroll-machine",8,1
150 :
160 print"{clr}{wht}":sys49152
170 ifusr(20000)<>229then:_ld"pseudo i"
180 ifusr(53248)<>4then:_ld"zeichensatz",53246
185 ifusr(57369)<>170then:_ld"sprites",57342
200 :
210 :
220 :
230 _rs:rem einstellungen loeschen
240 gosub1080:rem joysticksteuerung
245 _rz81,88,248:_su5
250 :
260 rem neue adresse der sprite pointers
270 sp=53240
280 :
290 js=56320:rem port 2
300 :
310 rem sprites vorbereiten
320 v=53248:pokev,172:pokev+1,150
330 pokev+2,173:pokev+3,161
340 pokev+28,3:pokev+39,14:pokev+38,6:pokev+37,1
350 pokev+40,8
360 pokev+23,0:pokev+29,0
370 co=v+31:rem sprite collission
380 s=128:rem sprites ab 128 = 57344
390 sh=3:rem anzahl der schiffe
400 e=200:rem anfangsenergie
410 :
420 rem soft-scroll-einstellungen
430 :
440 rem anfangsadresse,xausd.,yausd.
450 _mt20000,160,70
460 rem grenzen festlegen
470 _gm1:_gr0,8*160,0,8*50
480 rem register2:norm,norm,multicol.
490 _2r200,200,208
500 _hf0,10,0:rem hintergrundfarbe
510 poke53282,7:poke53283,8:_zf10
520 _us1:rem soft-scroll ein
530 _po50,0:rem position auf 50,0
540 _rf6,6,6:rem randfarbe
560 rem collission register loeschen
570 pokeco,0
580 pokesp,s:rem sprite aendern
590 s=s+1:ifs>132thens=128
600 rem randberuehrung
610 ifusr(0)then:_js2
620 e=e-1:gosub680
630 ife=0then720
640 f=f+1and1:pokev+21,1
650 if(peek(co)and1)then930
660 if(peek(js)and1)=0thenpokesp+1,144+f:pokev+21,3
670 goto580
680 print"{home} schiffe:"sh"{left}  energie: "e"{left}  "
690 return
700 :
710 rem verlust eines schiffes
720 i=0:e=200:x=-8:pokev+21,1
730 sh=sh-1
740 gosub680
750 rem zerfall
760 fori=1to10:poke53280,1:next
770 fori=132toi+11
780 pokesp,i
790 fort=1to20:next
800 next
810 _po50,0
820 _js2:rem traegheit loeschen
830 ifsh=0then860
840 goto500
850 :
860 pokev+21,0:poke214,12:print
870 _us0:rem soft scroll aus
880 printtab(13)"{wht}game over !!!"
890 wait197,63:poke198,0
900 _us0:run
910 :
920 rem landen
930 ifusr(2)>330andusr(2)<334andusr(1)>441andusr(1)<469then950
940 goto720:rem keine landung
950 print"{home}{down}{down}{rght}{wht} gelandet !"
960 e=200:gosub680
970 rem stoppen und joystick aus
980 _bw0,0:_js0
990 rem setzen auf y = 179
1000 _pousr(1),330
1010 rem joystick oben gedrueckt
1020 if(peek(js)and1)then1000
1030 :
1040 _bwbx,by
1050 _js2:gosub 1070:goto570
1060 rem 3 zeilen loeschen
1070 _fu 1024,1063+3*40,32:return
1080 print
1090 input"{clr}{down}{down}{down}{rght}bewegung (-127 bis 128) x,y{rght}{rght}0,1{left}{left}{left}{left}{left}";bx,by
1100 _bw bx,by
1110 print"{down}{down}{rght}{rght}joysticksteuerung :
1120 input"{down}{down}{rght}normale steuerung:{rght}{rght}0,0{left}{left}{left}{left}{left}";x,y
1130 _js 2,x,y:rem 2 = traegheitsmode
1140 print"{down}{down}{rght}{rght}traegheitssteuerung:
1150 input"{down}{rght}beschleunigung: (0-255) x,y{rght}{rght}16,16{left}{left}{left}{left}{left}{left}{left}";x,y
1160 _tb x,y
1170 input"{down}{rght}grenzgeschw.: (0-32767) x,y{rght}{rght}5000,5000{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}";x,y
1180 _tg x,y
1190 input"{down}{rght}reibung (0-255) x,y{rght}{rght}4,4{left}{left}{left}{left}{left}";x,y
1200 _tr x,y
1210 print"{clr}":return
100 ifhthenpoke45,l:poke46,h
110 ifpeek(50000)=56andpeek(50001)=253then160
120 l=peek(45):h=peek(46)
130 a=1
140 load"scroll-machine",8,1
150 :
160 print"{clr}{wht}":sys49152
170 ifusr(40960)<>160then:_ld"pseudo ii"
180 :
190 :
210 :
220 v=53248
230 print"{clr}{red}"
240 _rs:rem reset
250 _cp:rem zeichensatz kopieren
260 rem rasterzeilen waehlen
270 _rz106,115,232
280 rem fehler beseitigen
290 _su4
300 _mt40960,204,40:rem aa,xd,yd
310 rem video-ram
320 _vi52224+8*40,16
330 rem hintergrundfarben
340 _hf10,2,0
350 rem vordergrundfarbe
360 _zf2
370 _js2:rem joymode
380 rem beschleunigung u. hoechstgeschw.
390 _tb 16,16:_tg 10000,10000
400 _gm2:_gr0,204*8-21*8,0,40*8-16*8
410 _us1:rem soft-scroll an
420 print"eine solche konfiguration ist auch
430 print"moeglich. jedes fenster kann beliebig
440 print"gross sein.
450 print"{down} joystick in port 2"
460 poke214,22:print
470 print"dieser raum kann fuer das punktekonto
480 print"  etc. benuetzt werden.";
490 goto490
90 print"{clr}{gry1}"
100 sys 49152
105 print
110 aa=40960:xd=128:yd=64
120 sp=32:ze=207:fa=0
130 sr=57344:rem spriteadresse
140 v=53248:rem vic
145 co=v+31:rem collision
150 sz=53240:rem sprite-zeiger
160 g1=aa+2470:g2=aa+2477
165 g3=aa+6250:g4=aa+6271
170 fz=3:rem fasszaehler
180 a$(0)="auf":a$(1)=" {wht}{rvon}zu{gry1}"
190 def fna(x)=sin(x*.7)*cos(x*2.2)
195 :
200 _rs   :rem reset aller register
201 _cp   :rem zeichensatz kopieren
205 _mt aa,xd,yd :rem
206 :
300 rem farben+rasterzeilen
305 _hf 0,0,11
310 _rf 0,0,0
315 _rz 81,89,248
320 :
321 _js 2 :rem joysticksteuerung
322 _tg 2000,2000
330 :
332 ifegthen950
333 :
335 _us0
340 input"{down}{down}{rght}{rght}beschleunigung (1-255):{rght}{rght}16{left}{left}{left}{left}";g
343 input"{down}{down}{rght}{rght}reibung (1-255):{rght}{rght}8{left}{left}{left}";r
347 input"{down}{down}{rght}{rght}energie:{rght}{rght}5000{left}{left}{left}{left}{left}{left}";eg
350 print"{down}{down}{rght}{rght}neuer stollen (j/n)?"
355 geta$:ifa$="n"then950
360 ifa$<>"j"then355
365 input"{down}{down}{rght}{rght}breite (3-20):{rght}{rght}7{left}{left}{left}";b
480 :
485 printtab(10)"{down}{down}*** stollenaufbau ***
490 _fu aa,aa+8191,160
500 h=xd/12
510 fori=30toxd-1-b
515 p=int(fna(i/h)*16+32)*xd+aa+i
520 _fup,p+b,32
525 _fup-xd,p+b-xd,sp
526 _fup+xd,p+b+xd,sp
530 nexti
590 :
600 fori=13to47
610 p=aa+30+i*xd
615 ifi<20then:_fu p,p+25,sp
620 _fu p,p+6,sp
630 nexti
690 :
700 fori=19to48
710 p=aa+115+i*xd
715 ifi>40then:_fu p-10,p+13,sp
720 _fu p,p+13,sp
730 nexti
790 :
950 _zf0
955 _us1
956 ee=eg
957 _tbg,g:_trr,r
960 :
990 rem sprites
1000 poke sz,128
1010 poke sz+1,129
1020 poke v+39,15
1030 poke v+40,0
1040 poke v,172:poke v+1,150
1050 poke v+2,171:poke v+3,161
1090 :
1100 pokev+21,3
1102 _fu sr,sr+128,0
1105 :
1107 rem sprite einlesen
1108 restore
1110 fori=25toi+18
1120 reada:pokesr+i,a:next
1125 :
1127 rem zeichen 81 in sprite kopieren
1130 fori=0to7
1140 pokesr+65+i*3,usr(v+ze*8+i)
1150 next
1190 :
1195 rem faesser setzen
1200 fori=g1+3toi+11step4
1210 pokei,ze:next
1250 fori=g3tog4
1260 pokei,sp:next
1270 :
1300 _po 822,247
1500 pokev+21,1
1900 print"{home}faesser:"fz" energie:"ee"{left} greifer: "a$(fa)
1902 ifusr(4)then1902
1905 _js2
1910 _tm0
1915 gosub6000
1920 pokeco,0
1930 iffz=0then6500
1990 :
1995 rem **** hauptroutine ****
1996 :
2000 ee=ee-1:print"{home}"tab(20)ee"{left} "
2010 ifpeek(co)then3000
2020 ifusr(4)then4000
2500 ifee>0then2000
2590 :
2595 :
2600 print"{clr}{down}{down}{rght}{rght}batterie leer => absturz
2610 goto3010
2990 :
3000 _js0:gosub6000
3002 ifpeek(co)=2then3100
3005 print"{clr}{down}{down}{rght}sie haben ihren transporter zerstoert.
3010 onfa+1goto7050,7020
3100 print"{clr}{down}{down}{rght}{rght}{rght}{rght}{rght}sie haben das fass zerstoert.
3110 goto7020
3900 :
4000 ee=ee-10
4010 onfagoto4200
4112 :
4115 p=usr(3):rem fass aufnehmen
4120 ifusr(p)<>zethen1910
4122 _js0:rem traegheit loeschen
4124 rem y-position berichtigen
4125 _pousr(1),usr(2)and8184
4127 _tm1:rem bildschirm abtasten
4130 fa=1:pokev+21,3:rem sprite an
4140 pokep,sp:rem character loeschen
4145 ifp>g3andp<g4thenfz=fz+1
4150 goto1900
4190 :
4200 p=usr(3):rem fass absetzen
4210 ifusr(p+xd)<>160then4300
4215 _js0
4220 _po(usr(1)and8184)+4,usr(2)and8184
4230 _tm1:fa=0:pokep,ze
4240 pokev+21,1
4245 ifp>g3andp<g4thenfz=fz-1
4250 goto1900
4290 :
4300 print"{clr}{down}{down}{rght}{rght}sie haben das fass fallenlassen"
4350 goto7020
4900 :
4980 :
4990 rem spritedaten
5000 data 255,0,3,255,192,60,231,60,239,255,247,3,0,192,1,0,128,0,129
6000 fori=1to20:next:return
6500 print"{clr}{down}{down}{rght}{rght}{rght}sie haben ihre mission erfuellt.
6510 print"{down}{down}{rght}{rght}restenergie:"ee
6520 print"{down}{down}{rght}{rght}dafuer bekommen sie ein paar orden !
6590 goto7090
7020 print"{down}{down}{down}{rght}{rght}{rght}{rght}der stollen ist nun vollstaendig
7030 print"{down}{rght}{rght}strahlenverseucht.
7040 print"{down}{rght}{rght}ein fortfuehren der arbeit wird in
7045 print"{down}{rght}{rght}ca. 1500 jahren wieder moeglich sein.
7050 print"{down}{down}{rght}{rght}{rght}{rght}s i e   s i n d   t o t   ! ! !
7090 printtab(15)"{down}{down}{down}{down}e  n  d  e
7100 _us0
7101 pokev+21,0
7105 geta$:ifa$=""then7105
7110 goto110
Listing 3. Ein kleines Spiel als Demoprogramm

PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →