Erstellt: 24. April 2013 (zuletzt geändert: 1. November 2021)

Autostart

Wie man einen Autostart realisieren kann.

C64 Studio & AMCE

Ihr denkt jetzt sicher: Autostart? Wie jetzt? Wenn ich eine .prg-Datei nach WinVICE ziehe oder mein Programm mit dem CBM prg Studio oder C64 Studio erstelle und direkt an WinVICE übergeben habe, dann startet doch alles automatisch!

Sicher, bei Emulatoren ist das so, aber wir wollen ja für den C64 entwickeln und dort laden wir Programme normalerweise über den Namen oder mit LOAD “*“,8 und müssen anschließend RUN eingeben.

Wie ihr ja wisst, geben wir im Assembler unsere Startadresse z. B. mit *=$0801 an. Genaugenommen ist das nicht nur die Start-, sondern auch die Ladeadresse. Der C64 lädt bei einem LOAD .. ,8,1 das Programm direkt an die von uns gewählte Startadresse. Wichtig ist hier die letzte Eins ,1, die nach der Geräteadresse kommt. Dadurch „weiß“ der C64, dass das Programm an die vom Programmierer bestimmte Adresse und nicht an die BASIC-Startadresse geladen werden soll.
Diesen Umstand können wir uns zunutze machen. Der C64 lädt unser Programm wirklich gnadenlos an die von uns bestimmte Adresse.

Ein Programm im Bildschirmspeicher

Wer das mal testen möchte, der probiere einfach folgendes Programm:

*=$0400
 !scr "achtung!                                "
 !scr "das programm liegt jetzt im bs-speicher!"
 !scr "programm start>"
 inc $d020
 jmp *-3
 !scr "<ende              "
 !scr "                !                       "
 !scr "                                        "
 !scr "sys1119:rem startet das programm        "
 !scr "                                        "
 !scr "gebt beim 2. mal das ! im leeren feld   "
 !scr "direkt darueber ein kein return!!!      "
 !scr "geht mit dem cursor wieder auf den sys- "
 !scr "befehl und drueckt return.              "

Das obige Programm wird direkt in den Bildschirmspeicher geladen! Daher müsst ihr vorsichtig sein, welche Tasten ihr wo betätigt.

Das eigentliche Programm, es besteht ja nur aus dem inc $d020 und jmp *-3 Befehl, findet ihr zwischen den Texten START> und <ENDE.

Geht ihr nach dem Laden mit dem Cursor rauf zur Zeile, die mit SYS1119 beginnt und drückt dort RETURN, dann blinkt wieder der Rahmen.
Um zu beweisen, dass unser Programm tatsächlich im Bildschirmspeicher läuft, ladet es bitte nochmal, so das wieder der gesamte Text erscheint. Bevor wir den SYS-Befehl ausführen, geht aber bitte erstmal mit den Cursor-Tasten auf das Leerzeichen, das ihr direkt über dem einzelnen Ausrufezeichen ! findet. Überschreibt das Leerzeichen nun mit einem Ausrufezeichen (wirklich nur ein ! und keine andere Taste). Geht dann mit den Cursor-Tasten zum SYS-Befehl und drückt wieder RETURN.
Cool, wir haben unser Assemblerprogramm direkt im BS-Speicher durch die Eingabe eines Zeichens geändert, nun sollte etwas Anderes blinken.
Ihr solltet mit dem Char-ROM eigentlich selbst darauf kommen, was wir eben gemacht haben.

Das erste Zeichen hinter 'PROGRAMM START>' ist unser INC-Befehl. Um
den Rahmen blinken zulassen, müssen wir bekanntlich $d020 verändern.
Da im Speicher immer zuerst das LSB abgelegt wird, finden wir im 
zweiten Zeichen die $20. Wer jetzt mal ins Char-ROM schaut, wird 
feststellen, dass $20 (bzw. 32 dezimal) für das Leerzeichen steht.
Wenn wir schon im Char-ROM sind, dann sollten wir gleich mal kontrol-
lieren, was das !-Zeichen für eine Nr. hat. Da es direkt aufs Leer-
zeichen folgt, hat es die 33 dezimal bzw. $21.
Wenn wir nun das Leerzeichen auf dem Bildschirm mit dem Ausrufe-
zeichen ! überschreiben, dann ändern wir damit direkt das Assembler-
programm. Wir ändern das LSB der Adresse beim INC-Befehl. Dieser 
lautet jetzt INC $d021 und es blinkt ab jetzt also der Bildschirm 
und nicht mehr der Rahmen!

Ooops, schon wieder vom Thema abgekommen 😉 , zurück zum eigentlichen Thema

Autostart

Was bringt uns nun die Erkenntnis, dass der C64 unser Programm an nahezu (es gibt in der Tat Einschränkungen) jede beliebige Speicherstelle laden kann?
Das Betriebssystem des C64 befindet sich bekanntlich fest im Kernal-ROM. Wie ihr evtl. schon im Assember Tutorial gesehen habt, kann man zu den Kernal-Routinen entweder direkt ins ROM springen oder (und hier wird es nun interessant) über einen indirekten Sprung (Jump-Table). Diese Sprung-Adressen liegen im RAM und können somit von uns verändert werden (etwas Ähnliches wurde bei „Ein Modul erstellen“ gemacht). Wir benötigen jetzt also am Besten einen solchen indirekten Sprung, der nach dem LOAD Befehl angesprungen wird. Wenn ihr euch eine Speicher-Map anschaut, dann findet ihr auf der 2. Page (ab $0300) einige solcher Sprünge. Wir interessieren uns besonders für die sog. IMAIN-Routine, die in $0302 / $0303 gespeichert ist. Diese springt zurück zur BASIC-Eingabeschleife. Sie wird nach jedem direkt eingegebenen Befehl, wie z. B. LOAD angesprungen, um auf den nächsten Befehl zu warten.
Für den geplanten Autostart können wir das jetzt ausnutzen. Wenn wir dafür sorgen, dass unser Programm an diese Adresse geladen wird und in die Bytes $0302 / $0303 die Startadresse für unser eigentliches Programm einträgt, dann würde dieses nach dem Laden automatisch gestartet werden.

;*** Sprungvektor für Eingabeaufforderung in $0302/$0303 ändern 
*=$0302
 !byte <autostart, >autostart

autostart
 lda #147
 jsr $ffd2
 ldx #0
nextChar
 lda info,x
 beq done
 sta $0400,x
 inx
 bne nextChar
done
 inc $d020
 jmp *-3
info 
 !scr "das programm startet automatisch!"
 !byte 0

Ist das schon alles!??? Startet es einfach mal und ihr werdet feststellen, nein!

Vorsicht: Falls ihr den Turbo Assembler direkt auf dem C64 einsetzt, kommt es schon zum Absturz, sobald ihr das Programm im Speicher erstellt!!

Ganz so einfach ist es anscheinend doch nicht. Die Theorie stimmt, aber unser Programm überschreibt die weiteren Sprungadressen, die ihr bis $033b findet. Um einen Absturz zu vermeiden, müssen wir auch diese Adresse beibehalten. Dazu geben wir die Bytes bis $033b einfach in unserem Programm mit an. Die benötigten Werte könnt ihr z. B. mit VICE ermitteln indem ihr über ALT-M den Monitor startet, das Memory-Fenster öffnet und die Werte von $0304 bis $033b abtippt. Nett wie ich nun mal bin, habe ich das schon für euch erledigt.

;*** Sprungvektor für Eingabeaufforderung in $0302/$0303 ändern 
*=$0302
 !byte <autostart, >autostart

 ;*** Damit das Programm den C64 nicht zum Absturz bringt,
 ;*** müssen die weiteren Vektoren erhalten bleiben!!
 ;*** Daher geben wir hier den original Speicherinhalt
 ;*** des C64 als Bytes an!

 ;*** $0304 - $030f
 !byte $7c,$a5,$1a,$a7,$e4,$a7,$86,$ae,$00,$00,$00,$00
 ;*** $0310 - $031f
 !byte $4c,$48,$b2,$00,$31,$ea,$66,$fe,$47,$fe,$4a,$f3,$91,$f2,$0e,$f2
 ;*** $0320 - $032f
 !byte $50,$f2,$33,$f3,$57,$f1,$ca,$f1,$ed,$f6,$3e,$f1,$2c,$f3,$66,$fe
 ;*** $0330 - $030b
 !byte $a5,$f4,$ed,$f5,$00,$00,$00,$00,$00,$00,$00,$00

 ;*** $033c hier beginnt der Kassettenbuffer, ideal fürs Autostartprogramm
autostart
 lda #147
 jsr $ffd2
 ldx #0
nextChar
 lda info,x
 beq done
 sta $0400,x
 inx
 bne nextChar
done
 inc $d020
 jmp *-3
info 
 !scr "das programm startet automatisch!"
 !byte 0

Startet ihr das Programm nun, dann sollte direkt der Rahmen blinken.

Erfolgreicher Autostart
Erfolgreicher Autostart

OK, das ist jetzt kein Unterschied zu sonst, aber zumindest läuft das Programm. Ihr würdet natürlich nicht den Rahmen blinken lassen, sondern stattdessen das eigentliche Programm an die richtig Speicherstelle laden und dann zum Start dorthin springen.

Ein Problem soll natürlich nicht verschwiegen werden:
Steckt ein anderer Kernal im C64, dann wird es fast zu 100% passieren, dass das Programm wieder abstürzt! Benutzt der Kernal nämlich andere Sprungadressen, als das original ROM von Commodore, dann passen unsere Byte-Werte natürlich nicht.

Um das Beispiel jetzt richtig zu testen, benötigen wir eine Diskette bzw. eine D64-Datei für den Emulator.

  • Gebt zu nächst mal LOAD “$“,8 ein.
  • Lasst euch dann mit LIST das Inhaltsverzeichnis anzeigen, um sicherzugehen, dass die Diskette vom Emulator „eingelegt“ wurde.
  • Ladet und startet das Programm anschließend mit LOAD “*“,8,1.
    Inhalt des D64-Images.
    Inhalt des D64-Images.

    Oder ihr holt euch das gezippte D64-Image, um es im Emulator bzw. am C64 zu probieren.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (3 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


Zurück

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Protected by WP Anti Spam