C 64
Autostart

Autostart in Theorie und Praxis

Welcher Anwender hat sich nicht schon immer gewünscht, seine Programme »so einfach wie möglich« in den Computer zu bringen. Geräte der oberen Preis-/Leistungsklasse sind zu diesem Zweck mit einem Autostart-Mechanismus ausgerüstet. Dabei wird das Programm ohne weiteres Zutun nach dem Anschalten des Gerätes vom Massenspeicher (Floppy) in den Computer geladen. Hier soll jetzt die Realisierung eines solchen Autostarts auf einem C 64, beginnend mit der dazu nötigen Theorie, beschrieben werden.

Es gibt beim C 64 mehrere Möglichkeiten, einen Autostart herbeizuführen. Ich will Ihnen hier eine weniger bekannte Methode vorstellen:

Die Stack-Manipulation.

Der Stack belegt beim C 64 den Bereich $0100 bis $01ff (256 bis 511). Er wird unter anderem zum Ablegen von Rücksprungadressen benutzt. Nach Beendigung einer Routine sucht sich der Prozessor vom Stack zwei Bytes (nämlich die Rücksprungadresse in das Hauptprogramm) und springt die Adresse, die sich aus diesen beiden Bytes ergibt, an. Eigentlich ist daraus schon zu ersehen, was zu tun ist: Man müßte diese Rücksprungadresse so ändern, daß das Programm nicht an die eigentliche Rücksprungstelle springt, sondern auf eine eigene Routine. Jetzt jedoch tauchen schon die ersten Probleme auf; Wie soll der Stack geändert werden, ohne daß man dafür ein Extra-Programm braucht? Wie soll sich das Programm nach dem Ladevorgang automatisch starten?

Die Theorie

Auf beide Fragen gibt es eine Antwort: Da sich der Stack beim Ladevorgang ändern soll, ist es das einfachste, den (manipulierten) Stack einfach mit abzuspeichern! Damit hätten wir dann auch den von uns gewünschten Inhalt des Stacks geladen. Dann aber tauchen schon die nächsten Fragen auf: Woher wissen wir, aus welchem Stack-Bereich der Prozessor seine Rücksprungadresse holt? Die Antwort ist: Wir wissen es nicht! Unsere einzige Möglichkeit ist, den ganzen Stack mit der von uns gewünschten Rücksprungadresse zu belegen. Das Programm, auf das unsere Adresse zeigt (ein Maschinenprogramm), hängen wir direkt an den Stack an. Von dieser Startroutine wird nun das eigentliche Hauptprogramm, das wiederum hinter der Routine liegt, angesprungen. Die Reihenfolge der Programmteile und des benötigten Speichers ist in Bild 1 zusammengefaßt:

Startadresse des Programms auf Disk/Kas.: $0100

$0100 – $01ff Stack, Lowbyte-1 und Highbyte der Startadresse unseres Startprogramms ($02)
$0200 – $0202 Normaler Inhalt (unverändert)
$0203 – $0276 Bereich für unser Startprogramm (technisch bedingt, immer gleich)
$0277 – $03ff Normaler Inhalt (unverändert)
$0400 – $07ff Bildschirmbereich, sollte Leerzeichen ($20) enthalten.
$0800 Muß ein Null-Byte ($00) enthalten, damit der RUN-Befehl arbeiten kann.
$0801 – $xxxx Eigentliches Hauptprogramm, das vom Startprogramm angesprungen wird.
Bild 1. Programmadressen

Der Ladevorgang unseres Autostart-Programms muß mit »LOAD ”xxx”,8,l« erfolgen, damit das Programm nicht ab der Adresse $0801 (normaler Basic-Speicher), sondern ab $0100 geladen wird. Schauen wir uns nun noch einmal an, was im einzelnen beim Ladevorgang passiert:

  1. Laden des Programms von Diskette oder Kassette mit »LOAD ”xxx”,8,l«.
  2. Nach Beendigung des Ladevorgangs will sich der Prozessor vom Stack die Rücksprungadresse ins Basic holen, findet aber die (soeben geladene) Adresse auf unser eigenes Startprogramm und springt dies an.
  3. Unser Startprogramm springt jetzt das eigentliche Hauptprogramm an, das irgendwo ab $0801 stehen sollte.

Nachdem also das Programm mit »LOAD ”xxx”,8,l« geladen wurde, startet es sich selbst sofort.

Zum Abschluß sei noch gesagt, daß einige Vorgänge zur besseren Verständlichkeit vereinfacht werden mußten. Bei eigenen Experimenten sei geraten, das abgedruckte Demo-Programm zu modifizieren. Außer einigen saftigen Abstürzen kann eigentlich nichts passieren.

Die Praxis

Das abgedruckte Demo-Programm läuft ohne Änderungen auf einem C 64 mit einer 1541-Floppy (Gerätenummer 8). Die Anpassung an andere Gerätenummern dürfte keine Schwierigkeit darstellen. Lediglich in den Zeilen 110, 112, 120 und 180 ist die 8 durch eine 9 zu ersetzen. Die Beschreibung der einzelnen Programmteile ist in Bild 2 zusammengefaßt.

Zeilennr. Funktion
0 – 50 Copyright & Ausgabe der Kopfzeile
60 – 61 Eingabe des Programmnames und Kürzen auf 16 Zeichen
70 – 95 Warteschleife auf einen Tastendruck
100 Zusammensetzen des neuen Names
110 – 165 Generieren des Programmteils, der den Autostart enthält, auf Diskette ($0100-$0800)
170 – 300 Verbinden (Linken) des Autostart-Zusatzes und des eigentlichen Hauptprogramms
310 Ladeinstruktionen für das neu generierte, mit Autostart versehene Programm
Bild 2. Programmbeschreibung

Nun zum Programm selbst: Das Programm Autostart-Maker gibt dem Benutzer die Möglichkeit, ein beliebiges Programm mit einem Autostart zu versehen. Dabei muß folgende Bedingung erfüllt werden: Das Programm muß mindestens eine Basic-Zeile enthalten. Dies ist notwendig, da der vom Autostart-Maker generierte Autostart das Hauptprogramm mit dem RUN-Befehl startet. Zu diesem Zweck prüft der Autostart-Maker die Startadresse des gewünschten Programms und wirft eine Fehlermeldung aus, falls diese ungleich $0801 (Basic-Start) ist.

Wenn aber alles in Ordnung ist, so arbeitet das Programm eine Weile mit der Diskette, bis es eine Ende-Meldung ausgibt. Sollte ein Diskettenfehler auftreten, so macht sich das Programm optisch und akustisch bemerkbar. Danach hat der Benutzer die Wahl: das Programm zu beenden oder einen neuen Start zu versuchen.

Im Programm sind folgende Unterroutinen enthalten:
10000 Fehlerkanal lesen und auswerten
20000 Gong ausgeben (wird von Fehler-Routine aufgerufen)

In den Zeilen 30000- stehen die DATAs für das Startprogramm, das das eigentliche Hauptprogramm anspringen soll. Die Bedeutung einzelner Zeilen läßt sich auch den REM-Statements des Programms entnehmen.

Ein mit diesem Autostart versehenes Programm ist auch in gewissem Sinne geschützt. Es läßt sich weder mit RUN/STOP noch mit RESTORE abbrechen. Wird extern ein RESET-Impuls erzeugt, so wird der ganze Speicher gelöscht, bevor in die normale RESET-Routine verzweigt wird. Diese Eigenschaften gehen auf den Aufbau unseres Startprogramms zurück.

Geladen wird das neue Programm mit »LOAD ”name”,8,l«. Der Name entspricht dem des Ursprungprogramms mit dem Zusatz »/a«. Noch ein Tip: Wenn Sie im Besitz eines Basic-Compilers sind, so sollten Sie den Autostart-Maker compilieren. Und nun viel Spaß mit dem Autostart-Maker. Wenden Sie ihn doch am besten gleich mal bei Ihrem Programm an.

(Andreas Wurf)

Liste der verwendeten Variablen

na$ Name des zu modifizierenden Programms
t$, a$ – d$ Variablen für diverse Zwecke
nw$ Name des fertigen Autostart-Programms
a Variable für DATA-Elemente
si Startadresse des SID-Chips
i Schleifenvariable für diverse Zwecke
Variablenliste »Autostart«
0 rem" ******************************
1 rem" **   Autostart - Maker II   **
2 rem" *     Copyright (c) by       *
3 rem" *      Andreas Wurf          *
4 rem" *     2000 Hamburg 73        *
5 rem" *     Tabenstieg 10 b        *
6 rem" *  Tel.: (040) 647 40 28     *
7 rem" **     Version C64           *
8 rem" ******************************
9 :
10 print chr$(9)+chr$(14)+chr$(8)  "{clr}{rvon}         Autostart - Maker II+         {rvof}"
20 print"{up}{rvon}     copyright (c) 1983 Andreas Wurf    {rvof}"
30 print"{up}{rvon}          Commodore 64 - Version        {rvof}"
40 print"{down}{down}(Note:  Your Program must have a BAS-"
50 print"Start, such as '10 SYS (xxxx)' !!)"
60 print"{down}{down}Enter Name of Prog.: ";:open 1,0:input#1,na$:close 1:print
61 na$=left$(na$,16):rem "Kuerzen auf 16 Stellen"
70 print"{down}{down}Enter Prog's Disk and press a key !"
80 for i=0 to 20:get a$:if a$<>"" then 100
85 next:print"{up}{rvon}Enter Prog's Disk and press a key !{rvof}{up}{up}{up}"
90 for i=0 to 20:get a$:if a$<>"" then 100
95 next:goto70
100 nw$=left$(na$,14)+"/a":rem" Name des neuen programms
110 open15,8,15:print
112 open 1,8,0,na$:gosub 10000:close 1
120 open 1,8,5,nw$+",p,w":print"{down}{down}- Generate Autostart":gosub 10000
130 print#1,chr$(0)+chr$(1);:rem" Programmstart := $0100
140 for i=256 to 514:print#1,chr$(2);:next:rem" low-1 / Highbyte des Startpgms.
150 restore:for i=515 to 606:read a:print#1,chr$(a);:next:rem" Startprogramm
160 for i=607 to 1023:print#1,chr$(peek(i));:next:rem" Formaler Inhalt
164 for i=1024 to 2047:print#1,chr$(32);:next:rem " Bildschirm mit leerzeichen
165 print#1,chr$(0);:gosub 10000:close 1
170 print"- link together both files"
180 open 1,8,0,na$:gosub 10000:open 2,8,5,nw$+",p,a":gosub 10000
190 get#1,a$:a$=a$+chr$(0):get#1,b$:b$=b$+chr$(0):rem" Startadresse des Pgms.
200 if asc(a$)=1 and asc(b$)=8 then 250:rem" Test auf BASIC-Programm
210 print"{down}Start-Adr. of Source-Pgm is not unique"
220 print"to $0801. I can't use it."close 1:close 2:close 15:gosub 20000:end
250 get#1,a$:if a$="" then a$=chr$(0)
260 if st then print#2,a$;:goto 300
270 print#2,a$;:goto 250
300 gosub 10000:close 1:close 2:close 15
310 print"{down}{rvon}Ok. Type 'LOAD"chr$(34)+nw$+chr$(34)",8,1' to load.":end
400 :
410 rem"   Routinen und DATA's
420 :
10000 input#15,a$,b$,c$,d$:if val(a$)=0 then return
10010 print"{down}{rvon}IFO - Error# "a$": "b$" on "c$","d$:gosub 20000
10020 print"{down}   {rvon}q{rvof}uit or {rvon}r{rvof}estart ?"
10030 get t$:if t$<>"q" and t$<>"r" then 10030
10040 close 1:close 2:close 15:if t$="r" then run
10050 end
20000 si=54272:poke si+5,9:poke si+6,0:poke si+24,15
20010 poke si,30:poke si+1,30:poke si+4,17:for i=0 to 300:next:poke si+4,0
20020 poke si,20:poke si+1,20:poke si+4,17:for i=0 to 600:next:poke si+4,0
20030 poke si+24,0:return
30000 data 169,52,162,193,141,20,3,142,24,3,162,4,189,16,253,157,4,128,202
30010 data 16,247,169,57,162,2,141,0,128,141,2,128,142,1,128,142,3,128
30020 data 165,174,166,175,133,45,134,46,32,99,166,32,142,166,76,174,167
30030 data 169,0,162,8,133,158,134,159,160,0,169,0,145,158,200,208,251,230
30040 data 159,165,159,201,208,208,239,169,0,162,9,157,0,128,202,16,250
30050 data 76,226,252
Mit diesem Listing können Sie jedes Programm, das mindestens eine Basic-Zeile enthält, mit einem Autostart versehen, direkt nach dem Laden ausgeführt wird.
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →