KERNAL
Das KERNAL ist der Kernel des C64/C128, ein Basisprogramm ähnlich dem BIOS (Basic Input-Output System) des PC, das Routinen zur Ansteuerung der Ein- und Ausgabefähigkeiten des C64 sowie die ersten für die Initialisierung der Hardware nach dem Einschalten nötigen Schritte beinhaltet. Das KERNAL kann allerdings noch etwas mehr als nur die I/O-Vorgänge und den Boot-Prozess kontrollieren, dennoch beschränken sich die Funktionen eines Betriebssystems im Wesentlichen auf die Ein- und Ausgabesteuerung mit entsprechender Aufrufschnittstelle (Calling interface), die in einer Sprungleiste/-tabelle (Jump table) organisiert sind.
Begriffsherkunft[Bearbeiten | Quelltext bearbeiten]
Laut Robert Russell, der maßgeblich an der Entwicklung des VIC20 beteiligt war, beruht die Commodore übliche jedoch ungewöhnliche Schreibweise auf einem Tippfehler, der ihm bei der Erstellung der Dokumentation für das VIC20-Programmierhandbuch unterlaufen war. Zitat: "Ich verschrieb mich in der Überschrift auf der ersten Seite. So wurde der "Kernal" geboren."[1] Diese Schreibweise wurde dann auch konsequent bei C64[2] und C128 weitergeführt.[3] Auch z.B. in den Schaltplänen findet sich die Bezeichnung KERNAL wieder.
Einigen Quellen zufolge soll KERNAL für "Keyboard Entry Read, Network, And Link" stehen[4]; dabei handelt es sich vermutlich um ein Backronym.
Grundlagen[Bearbeiten | Quelltext bearbeiten]
Das KERNAL befindet sich auf einem 8 KByte großen ROM-Chip, dessen Inhalt normalerweise im Adressbereich $E000-$FFFF in den Speicher des C64 eingeblendet ist (Speicherbelegungsplan). Diesen Bereich teilt sich das knapp 7 KByte große Kernal allerdings mit einem kleinen Teil des BASIC-Interpreters, da dieser mit einer Gesamtgröße von ca. 9 KByte nicht vollständig in das 8 KByte große BASIC-ROM hineinpasst. Zwischen dem BASIC-Anteil und dem eigentlichen KERNAL liegt ein kleiner unbenutzter Bereich, der sich bei der letzten und weitaus häufigsten ROM-Version von Adresse $E4B7 bis Adresse $E4D2 erstreckt und mit dem Bytewert $AA gefüllt ist. Die wesentlichen KERNAL-Routinen lassen sich über Sprungtabellen mit fixen Eintrittsadressen aufrufen, wovon sowohl das KERNAL selbst als auch BASIC V2 regen Gebrauch machen. Das KERNAL ist vorbereitet auf eine Erweiterung oder Verbesserung des Systems z.B. durch Steckmodule und passt die Ein- und Ausgabesteuerung der neuen Hardwareumgebung an.
Die Sprungtabelle des KERNALs enthält 39 Vektoren auf Systemroutinen für Verwaltungsfunktionen und die Ein- und Ausgabe. Diese Routinen lassen sich per Maschinensprache (Assembler) mit Hilfe des JSR-Befehls nutzen. Um Systemroutinen sinnvoll zu verwenden, muss man deren Parameter kennen und vor Gebrauch festlegen. Sollte eine Systemroutine auf Probleme stoßen, stellt sie eine Fehlermeldung bereit, und der Programmierer sollte entsprechende Vorkehrungen getroffen haben, um angemessen darauf reagieren zu können (siehe Fehlercodes des KERNALs).
Unterschiedliche Revisionen[Bearbeiten | Quelltext bearbeiten]
Die Revisionen 1 und 2 verhalten sich anders als die neueren Revisionen. So wird z.B. bei Revision 2 beim Aufruf vom CLEARSCREEN, egal ob direkt per Assembler oder über
print "{STEUERZEICHEN_ZEICHENFARBE}{SHIFT+CLR/HOME}"
oder auch einfach nur Druck auf SHIFT +CLR/HOME im Direktmodus nicht das gesamte Farb-RAM mit der aktuellen Zeichenfarbe (abgelegt in Speicherstelle hex. $0286 bzw. 646) gefüllt, wie man es von den neueren KERNEL-Revisionen gewohnt ist und erwartet. Stattdessen wählt CLEARSCREEN die Hintergrundfarbe $D021/53281 als Füllfarbe.
Zum Testen, ob das jeweilige KERNEL von diesem Phänomen betroffen ist, kann man direkt nach dem Einschalten im DirektmodusPOKE 1024,1
eingeben:[5]
- Bei den neueren Versionen erscheint bei $0400 bzw. in der linken oberen Ecke des Screens ein "A" in der aktuellen Farbe bei $d800 (Farb-RAM).
- Erscheint das "A" unsichtbar (in aktueller Hintergrundfarbe, sichtbar nach Änderung der Hintergrundfarbe z.B. mit
POKE 53281,0
), hat man Revision 2. - Bei der wohl nur auf alten NTSC-Rechnern verbauten und somit in Europa wohl kaum bis nicht anzutreffenden Rev 1 erscheint ein weißes "A".
In Revision 3 wurde zudem ein Fehler im Screen-Editor behoben, der den sogenannten "push-wrap-crash" auslösen kann: Gibt man in der untersten Bildzeile 80 oder mehr Zeichen ein und löscht dann solange per Delete , bis der Cursor ans Ende der vorherigen Zeile zurückspringt, wird die aktuelle Zeichenfarbe statt ins Farb-RAM in Controlregister B der CIA 1 geschrieben, was bei bestimmten Zeichenfarben dazu führt, dass der C64 nicht mehr auf Tastatureingaben reagiert (auch nicht auf eine RUN/STOP +RESTORE .
Abgesehen von einem Reset kann man sich auch mit einer Datasette aus der Situation befreien: In der Gegend der Stop-Taste solange Tasten drücken, bis unvermittelt die Auto-Load-Funktion (es wird der Befehl LOAD angezeigt) ausgelöst wird. Drückt man dann bei der Datasette auf Play und gleich wieder auf Stop, kann man wieder "normal" mit RUN/STOP abbrechen und der Prompt erscheint wieder!
Die Revisionsnummer steht in der Speicheradresse 65408 ($FF80). Bei den europäischen C64-Modellen war der Wert entweder 0 oder 3 (Revision 2 bzw. 3), wobei die häufigst vorkommende KERNAL-Variante jene mit Revision 3 ist.[6]
KERNAL | Revision-Byte in 65408 ($FF80) |
Anmerkung |
---|---|---|
Revision 1 | 170 ($AA) | Füll-Byte |
Revision 2 | 0 ($00) | Versionsnummer |
Revision 3 | 3 ($03) | Versionsnummer |
SX-64 | 67 ($43) | Versionsnummer |
CBM 4064 "Educator 64" |
100 ($64) | Versionsnummer |
Nutzung von BASIC aus[Bearbeiten | Quelltext bearbeiten]
Auch von BASIC aus lassen sich einige KERNAL-Routinen direkt nutzen. Allerdings gibt es nicht allzu viele wirklich sinnvolle Anwendungsfälle, da die KERNAL-Routinen ziemlich elementare Operationen sind, die schon durch BASIC-Befehle komfortabler benutzt werden können.
Cursor-Positionierung[Bearbeiten | Quelltext bearbeiten]
- Die KERNAL-Routine PLOT ($FFF0/65520) positioniert bei Aufruf mit gelöschtem Carry den Cursor auf die im X- bzw. Y-Register gespeicherte Position. Das Beispiel schreibt per POKE die Zeilen- und Spaltennummer bzw. 0 in die Adressen, die SYS in das X-/Y-Register bzw. das Statusregister übernimmt und dann PLOT aufruft. PLOT setzt den Cursor an die entsprechende Position. Danach wird mit PRINT dort der Buchstabe "A" ausgegeben.
POKE 211,SP: POKE 214,ZE: SYS 58732: PRINT "A"
- Wie letztes Beispiel, allerdings wird statt über die Vektortabelle direkt mitten in den KERNAL gesprungen ($E56C). Kürzer, aber weniger sauber.
Tastenabfrage[Bearbeiten | Quelltext bearbeiten]
SYS 65487
- Danach ein Zeichen per Tastatur eingeben und RETURN drücken. Die aufgerufene Routine zur Zeicheneingabe CHRIN ($FFCF/65487) speichert das eingegebene Zeichen in Adresse 215. Anschließend:
SYS 65490
- Die aufgerufene Routine zur Zeichenausgabe CHROUT ($FFD2/65490) gibt das in Adresse 215 gespeicherte Zeichen auf dem Bildschirm aus. An dieser Stelle ist es übrigens gewissermaßen Glück, dass das BASIC-ROM selbst zwischen den beiden SYS-Befehlen nicht Adresse 215 überschreibt.
Disketten-Operationen[Bearbeiten | Quelltext bearbeiten]
SYS 57812 "dateiname",8,0:POKE780,0:POKE781,0:POKE782,64:SYS 65493
- Laden einer binären Datei (z.B. Maschinenprogramm oder Grafik) an eine definierte Adresse, hier mit Gerät 8 an die Adresse $4000 = 64*256.
- Aufgerufen wird erst die KERNAL-interne Routine zum Holen der Parameter von LOAD/SAVE ($E1D4/57812), dann LOAD ($FFD5/65493) mit dem Low-Byte der Ladeadresse im X- und dem High-Byte im Y-Register.
SYS 57812"name",8,0:POKE193,00:POKE194,04:POKE780,193:POKE781,232:POKE782,07:SYS65496
- Speichern eines definierten RAM- oder ROM-Bereiches, Speicherbelegung beachten, d.h. es ist im Direktmodus nicht ohne weiteres möglich, RAM unter den ROMs ($A000-$BFFF/$E000-$FFFF) zu speichern, es wird stets ROM gespeichert. Das Character-ROM kann übrigens auf diese Weise auch nicht direkt abgespeichert werden, da die CPU zur Kommunikation mit dem Datenträger Zugriff auf die im gleichen Adressraum befindlichen I/O-Register benötigt, vergleiche PLA (C64-Chip). Das obige Beispiel speichert das Screen-RAM von $0400 (1024) bis $07E7 (2023).
- Wie beim vorigen Beispiel wird über die KERNAL-interne Routine LOAD/SAVE ($E1D4/57812) Filename und Geräteadresse übergeben. Neu ist, dass in den Zeropage-Adressen $C1 (193) und $C2 (194) Low-Byte und High-Byte der Startadresse festgelegt werden und anschließend $C1 (193) in den Akkumulator (780) übertragen wird. In X-Register (781) und Y-Register (782) werden Low-Byte und High-Byte der Endadresse+1 übergeben. Erst dann wird die KERNAL-Routine SAVE ($FFD8/65496) aufgerufen.
KERNAL-Verhalten nach Einschalten des C64[Bearbeiten | Quelltext bearbeiten]
Beim Hard-Reset startet die CPU bei der in $FFFC/$FFFD abgelegten Adresse (springt nach $FCE2, RESET):
- Der Stapelzeiger wird auf leeren Stapel initialisiert. Der Dezimalmodus der 6502-CPU wird deaktiviert ($FCE2).
- Es wird überprüft, ob sich an der Speicheradresse 32768 ($8000) eine Modulkennung befindet. Wenn vorhanden, wird die Initialisierung dem dort befindlichen Programm übertragen.
- Der Bildschirm wird enger gestellt (VIC-Register 22 auf Null).
- Initialisierung der Ein- und Ausgabe:
- CIA-6526 initialisieren ($FDA3).
- Speicheraufteilung für BASIC-Betrieb festlegen ($FDD5).
- Interrupt-Timer aktivieren, 60 Hz ($FDDD).
- Löschen des SID-Volume-Registers.
- Datasettenmotor abschalten.
- Initialisieren und Test des RAMs ($FD50 bis $FD9A im Kernal).
Der Speicherinhalt nach dem Einschalten ist zufällig. Welches Muster nach dem Einschalten im RAM steht, hängt vom RAM ab. Verschiedene Hersteller implementieren das unterschiedlich. Der Speichertest des C64 überschreibt den Speicher nicht oder genauer: restauriert den Originalinhalt nach dem Test (mit Ausnahme des letzten Bytes, das RAM unter $A000 wird also normalerweise überschrieben) wieder.- Zeropage und erweiterte Zeropage löschen.
- Setzen der Speicherzeiger für Datasettenpuffer ($033C), Setzen des BASIC-Anfangs (immer 2048; $0800) und des BASIC-Endes (wird auf die erste Adresse gesetzt, bei der nach dem Schreiben eines Testmusters ein anderer Wert ausgelesen wird; das ist normalerweise beim Anfang des BASIC-ROMs $A000 der Fall).
- Bildschirmspeicher-Anfang immer auf 1024 ($0400) .
- Ein- und Ausgabevektoren (ab $0314) auf Standardwerte setzen.
- VIC initialisieren:
- VIC-Register mit Vorgabewerten beschreiben ($E5AA, dabei wird der Bildschirm wieder weiter gestellt).
- Cursorblinken initialisieren.
- Bildschirmfarben (blau/hellblau) setzen.
- Löschen des Bildschirms.
- Cursor-Home-Position setzen.
- BASIC-Kaltstart (über $A000 nach $E394):
- Konstanten und Vektoren in die (erweiterte) Zeropage eintragen.
- CHRGET aktivieren.
- String-Verwaltung initialisieren.
- BASIC-RAM aktivieren.
- BASIC-Start initialisieren ($0801).
- Einschaltmeldung ausgeben.
- Prompt "READY." ausgeben und Eintritt in den Direktmodus.
KERNAL-Routinen[Bearbeiten | Quelltext bearbeiten]
Details zu den Routinen (wie werden Parameter übergeben etc.) finden sich bei den Weblinks.
Nach Name geordnet:
Name | Startadresse | Springt nach | Beschreibung |
ACPTR | 65445 / $FFA5 | $EE13 | Byte-Eingabe (serieller Bus) |
CHKIN | 65478 / $FFC6 | ($031E) → $F20E | Eingabe-Kanal öffnen |
CHKOUT | 65481 / $FFC9 | ($0320) → $F250 | Ausgabe-Kanal öffnen |
CHRIN | 65487 / $FFCF | ($0324) → $F157 | Zeicheneingabe (wartet bei Tastatureingabe) |
CHROUT | 65490 / $FFD2 | ($0326) → $F1CA | Zeichenausgabe |
CINT | 65409 / $FF81 | $FF5B | Initialisierung Bildschirm-Editor |
CIOUT | 65448 / $FFA8 | $EDDD | Byte-Ausgabe (serieller Bus) |
CLALL | 65511 / $FFE7 | ($032C) → $F32F | Schließen alle Kanäle und Dateien |
CLOSE | 65475 / $FFC3 | ($031C) → $F291 | Logische Datei schließen (vergleiche BASIC-Befehl CLOSE) |
CLRCHN | 65484 / $FFCC | ($0322) → $F333 | Schließt Ein- und Ausgabekanal |
GETIN | 65508 / $FFE4 | ($032A) → $F13E | Zeichen einlesen (bei Tastureingabe wird nicht gewartet, 0 wenn keine Taste gedrückt) |
IOBASE | 65523 / $FFF3 | $E500 | Rückmeldung der Basisadressen für Ein- und Ausgabegeräte |
IOINIT | 65412 / $FF84 | $FDA3 | Initialisierung der Ein- und Ausgabe |
LISTEN | 65457 / $FFB1 | $ED0C | Befehl LISTEN für Geräte am seriellen Bus (Start Datenempfang bei Peripheriegeräten) |
LOAD | 65493 / $FFD5 | $F49E | Daten ins RAM laden von Peripheriegeräten, aber nicht von Tastatur (0), RS-323 (2), Bildschirm (3) (vergl. BASIC-Befehl LOAD) |
MEMBOT | 65436 / $FF9C | $FE34 | Setzen oder Lesen des Zeigers auf BASIC-RAM-Anfang |
MEMTOP | 65433 / $FF99 | $FE25 | Setzen oder Lesen des Zeigers auf BASIC-RAM-Ende |
OPEN | 65472 / $FFC0 | ($031A) → $F34A | Logische Datei öffnen (vergleiche BASIC-Befehl OPEN) |
PLOT | 65520 / $FFF0 | $E50A | Setzen oder Lesen der Cursorposition (X-/Y-Position) |
RAMTAS | 65415 / $FF87 | $FD50 | Initialisieren des RAMs, Kassettenpuffer einrichten, Anfang des Bildschirmspeichers 1024 ($0400) setzen |
RDTIM | 65502 / $FFDE | $F6DD | Uhrzeit lesen (vergl. BASIC-Systemvariablen TIME/TI und TIME$/TI$) |
READST | 65463 / $FFB7 | $FE07 | Lesen des Ein-/Ausgabestatusworts, also Fehlermeldungen des KERNALs (vergleiche BASIC-Systemvariable STATUS bzw. ST) |
RESTOR | 65418 / $FF8A | $FD15 | Rücksetzen der Ein- und Ausgabevektoren auf Standard |
SAVE | 65496 / $FFD8 | $F5DD | Daten vom RAM auf Peripheriegeräte sichern, aber nicht auf Tastatur (0), RS-323 (2), Bildschirm (3) (vergleiche BASIC-Befehl SAVE) |
SCNKEY | 65439 / $FF9F | $EA87 | Abfrage der Tastatur |
SCREEN | 65517 / $FFED | $E505 | Anzahl der Bildschirmspalten und -zeilen ermitteln (Rückgabe im X- und Y-Register) |
SECOND | 65427 / $FF93 | $EDB9 | Übertragung der Sekundäradresse nach LISTEN-Befehl |
SETLFS | 65466 / $FFBA | $FE00 | Setzen der Geräteadressen (logische, Primär- und Sekundäradresse) |
SETMSG | 65424 / $FF90 | $FE18 | Steuerung von KERNAL-Meldungen |
SETNAM | 65469 / $FFBD | $FDF9 | Festlegen des Dateinamens |
SETTIM | 65499 / $FFDB | $F6E4 | Setzen der Uhrzeit (vergleiche BASIC-Systemvariable TIME$/TI$) |
SETTMO | 65442 / $FFA2 | $FE21 | Setzen der Zeitsperre für seriellen Bus (nur für zusätzliche IEEE-Karten) |
STOP | 65505 / $FFE1 | ($0328) → $F6ED | Abfrage der Taste |
TALK | 65460 / $FFB4 | $ED09 | TALK auf den seriellen Bus senden |
TKSA | 65430 / $FF96 | $EDC7 | Übertragung der Sekundäradresse nach TALK-Befehl |
UDTIM | 65514 / $FFEA | $F69B | Weiterstellen der Uhrzeit |
UNLSN | 65454 / $FFAE | $EDFE | Senden des UNLISTEN-Befehls für seriellen Bus zur Beendigung der Datenübertragung |
UNTLK | 65451 / $FFAB | $EDEF | Senden des UNTALK-Befehls für seriellen Bus |
VECTOR | 65421 / $FF8D | $FD1A | Abspeichern von RAM bzw. Vektorverwaltung der Sprungvektoren |
Fehlercodes des KERNALs[Bearbeiten | Quelltext bearbeiten]
Die Fehlercodes des KERNALs sind nicht zu verwechseln mit den BASIC-Fehlermeldungen!
Nummer | Beschreibung |
---|---|
0 | STOP-Taste gedrückt |
1 | Zu viele offene Dateien |
2 | Datei bereits offen |
3 | Datei nicht offen |
4 | Datei nicht gefunden |
5 | Gerät nicht vorhanden |
6 | Keine Eingabe-Datei |
7 | Keine Ausgabe-Datei |
8 | Dateiname fehlt |
9 | Dateiname fehlt |
240 | Verändertes Speicherende (RS-232C) |
I/O-Logik[Bearbeiten | Quelltext bearbeiten]
OPEN --------------------+ CHKIN/CHKOUT ---------+ | begin a loop -----+ | | input or output | | | end a loop -------+ | | CLRCHN ---------------+ | CLOSE -------------------+
Speicheradressen[Bearbeiten | Quelltext bearbeiten]
Hex-Adresse | Dez-Adresse | Beschreibung |
$E000 | 57344 | BASIC-Funktion EXP – Fortsetzung von $BFFF |
$E043 | 57411 | Polynomberechnung |
$E08D | 57485 | 2 Konstanten für RND |
$E097 | 57495 | BASIC-Funktion RND |
$E0F9 | 57593 | Fehlerauswertung nach I/O-Routinen in BASIC |
$E10C | 57612 | PETSCII-Zeichen ausgeben mit CHROUT, Wert muss im Akku stehen |
$E112 | 57618 | PETSCII-Zeichen holen mit CHRIN (Eingabegerät wählbar) |
$E118 | 57624 | Ausgabegerät setzen mit CHKOUT |
$E11E | 57630 | Eingabegerät setzen mit CHKIN |
$E124 | 57636 | Zeichen aus Tastaturpuffer in Akku holen mit GETIN |
$E12A | 57642 | BASIC-Befehl SYS |
$E156 | 57686 | BASIC-Befehl SAVE |
$E165 | 57701 | BASIC-Befehl VERIFY |
$E168 | 57704 | BASIC-Befehl LOAD |
$E1BE | 57790 | BASIC-Befehl OPEN |
$E1C7 | 57799 | BASIC-Befehl CLOSE |
$E1D4 | 57812 | Parameter für LOAD, SAVE und VERIFY aus BASIC-Text holen |
$E200 | 57856 | Prüft auf Komma und holt 1-Byte-Wert nach Register X |
$E206 | 57862 | Prüft auf weitere Zeichen |
$E20E | 57870 | Prüft auf Komma und weitere Zeichen |
$E219 | 57881 | Parameter für OPEN und CLOSE holen |
$E264 | 57956 | BASIC-Funktion COS |
$E26B | 57963 | BASIC-Funktion SIN |
$E2B4 | 58036 | BASIC-Funktion TAN |
$E2E0 | 58080 | Trigonometrische Konstante 1,570796327 = π/2 |
$E2E5 | 58085 | Trig. Konstante 6,28318531 = 2*π |
$E2EA | 58090 | Trig. Konstante 0,25 |
$E2EF | 58095 | Trig. Konstante 5 = Polynomgrad, dann 6 Koeffizienten |
$E2F0 | 58096 | Trig. Konstante -14,3813907 |
$E2F5 | 58101 | Trig. Konstante 42,0077971 |
$E2FA | 58106 | Trig. Konstante -76,7041703 |
$E2FF | 58111 | Trig. Konstante 81,6052237 |
$E304 | 58116 | Trig. Konstante -41,3417021 |
$E309 | 58121 | Trig. Konstante 6,28318531 = 2*π |
$E30E | 58126 | BASIC-Funktion ATN |
$E33E | 58174 | ATN-Konstante 11 = Polynomgrad, dann 12 Koeffizienten |
$E33F | 58175 | ATN-Konstante -0,00068479391 |
$E344 | 58180 | ATN-Konstante 0,00485094216 |
$E349 | 58185 | ATN-Konstante -0,161117018 |
$E34E | 58190 | ATN-Konstante 0,034209638 |
$E353 | 58195 | ATN-Konstante -0,0542791328 |
$E358 | 58200 | ATN-Konstante 0,0724571965 |
$E35D | 58205 | ATN-Konstante -0,0898023954 |
$E362 | 58210 | ATN-Konstante 0,110932413 |
$E367 | 58215 | ATN-Konstante -0,142839808 |
$E36C | 58220 | ATN-Konstante 0,19999912 |
$E371 | 58225 | ATN-Konstante -0,333333316 |
$E376 | 58230 | ATN-Konstante 1,00 |
$E37B | 58235 | BASIC-Warmstart nach RUN/STOP +RESTORE bzw. BRK (NMI-Einsprung) |
$E394 | 58260 | BASIC-Kaltstart (Reset) |
$E3A2 | 58274 | Kopie der CHRGET-Routine für die Zeropage |
$E3BA | 58298 | Konstante 0,811635157 = Anfangswert für RND-Funktion: |
$E3BF | 58303 | RAM initialisieren für BASIC |
$E422 | 58402 | Einschaltmeldung ausgeben |
$E447 | 58439 | Tabelle der BASIC-Vektoren (für $0300) |
$E453 | 58451 | BASIC-Vektoren aus der Tabelle laden nach $0300 ff. |
$E45F | 58463 | Text der Einschaltmeldungen |
$E4AD | 58541 | BASIC-CHKOUT-Routine |
$E4B7 | 58551 | Unbenutzter Bereich (ist mit $AA gefüllt) |
$E4D3 | 58579 | Patch für RS-232-Routinen |
$E4DA | 58586 | Schreibt Hintergrundfarbe in Farb-RAM (von CLR benutzt, mindert das Flimmern) |
$E4E0 | 58592 | Pause (8,5 Sekunden), nachdem eine Datei auf der Kassette gefunden wurde |
$E4EC | 58604 | Timerkonstanten für RS-232 Baudrate, PAL-Version |
$E500 | 58624 | IOBASE: Gibt die Basisadresse des CIA in Register X/Y aus |
$E505 | 58629 | SCREEN: Bildschirmgröße einlesen: 40 Spalten in Register X, 25 Zeilen in Register Y |
$E50A | 58634 | PLOT: Setzt/holt Cursorposition: Register X = Zeile, Register Y = Spalte |
$E518 | 58648 | Initialisiert I/O (Bildschirm und Tastatur) |
$E544 | 58692 | Löscht Bildschirmspeicher |
$E566 | 58726 | Cursor Home: bringt Cursor in Grundposition (oben links) |
$E56C | 58732 | berechnet die Cursorposition, setzt Bildschirmzeiger |
$E59A | 58778 | Videocontroller initialisieren und Cursor Home (wird nicht benutzt) |
$E5A0 | 58784 | Videocontroller initialisieren |
$E5B4 | 58804 | Holt ein Zeichen aus dem Tastaturpuffer |
$E5CA | 58826 | Wartet auf Tastatureingabe |
$E632 | 58930 | Holt ein Zeichen vom Bildschirm |
$E684 | 59012 | Testet auf Hochkomma und kehrt gegebenenfalls das Hochkomma-Flag $D4 um (EOR #$01) |
$E691 | 59025 | Gibt Zeichen auf Bildschirm aus |
$E6B6 | 59062 | Springt in neue Zeile bzw. fügt neue Zeile ein |
$E701 | 59137 | Rückschritt in vorhergehende Zeile |
$E716 | 59158 | Ausgabe (des Zeichens in Register A) auf Bildschirm inklusive Steuerzeichen, Farben |
$E87C | 59516 | Nächste Zeile setzen, gegebenenfalls Scrollen |
$E891 | 59537 | Aktion nach Taste RETURN |
$E8A1 | 59553 | Cursor zur vorigen Zeile, wenn er am Zeilenanfang rückwärts bewegt wird |
$E8B3 | 59571 | Cursor zur nächsten Zeile, wenn er am Zeilenende vorwärts bewegt wird |
$E8CB | 59595 | prüft, ob Zeichen in A einer der 16 Farbcodes ist und setzt Farbe entsprechend |
$E8DA | 59610 | Tabelle der Farbcodes – 16 Bytes |
$E8EA | 59626 | Bildschirm scrollen, schiebt Bildschirm um eine Zeile nach oben |
$E965 | 59749 | Fügt leere Fortsetzungszeile ein |
$E9C8 | 59848 | Schiebt Zeile nach oben |
$E9E0 | 59872 | Berechnet Zeiger auf Farb-RAM und Startadresse des Bildschirmspeichers |
$E9F0 | 59888 | Setzt Zeiger auf Bildschirmspeicher für Zeile Register X |
$E9FF | 59903 | Löscht eine Bildschirmzeile (Zeile in Register X) |
$EA13 | 59923 | Setzt Blinkzähler und Farb-RAM-Zeiger |
$EA1C | 53932 | Schreibt ein Zeichen mit Farbe auf dem Bildschirm (Bildschirmcode im Akku, Farbe in Register X) |
$EA24 | 59940 | Berechnet den Farb-RAM-Zeiger zur aktuellen Cursorposition |
$EA31 | 59953 | Interrupt-Routine, verarbeitet alle IRQs |
$EA81 | 60033 | Holt Register A/X/Y aus dem Stapel zurück und beendet einen IRQ |
$EA87 | 60039 | SCNKEY: Tastaturabfrage |
$EB48 | 60232 | Prüft auf Tasten Shift, Control, Commodore |
$EB79 | 60281 | Zeiger auf Tastatur-Dekodiertabelle für Umwandlung der Matrixwerte in PETSCII |
$EB81 | 60289 | Dekodiertabelle bei nicht gedrückter Shift-Taste |
$EBC2 | 60354 | Dekodiertabelle bei gedrückter Shift-Taste |
$EC03 | 60419 | Dekodiertabelle mit gedrückter Commodore-Taste |
$EC44 | 60484 | Prüft auf PETSCII-Codes für Steuerzeichen |
$EC78 | 60536 | Dekodiertabelle mit Control-Taste |
$ECB9 | 60601 | Konstanten für Videocontroller |
$ECE7 | 60647 | Text "LOAD"(CR)"RUN"(CR) für den Tastaturpuffer nach Drücken von Shift +RUN/STOP |
$ECF0 | 60656 | Tabelle der niederwertigen Bytes der Bildschirmzeilenanfänge |
$ED09 | 60681 | TALK: Sendet TALK auf seriellem Bus |
$ED0C | 60684 | LISTEN: Sendet LISTEN auf seriellen Bus |
$ED40 | 60736 | Gibt ein Byte (aus $95) auf seriellen Bus aus |
$EDB9 | 60857 | SECOND: Sendet Sekundäradresse nach LISTEN |
$EDBE | 60862 | Gibt ATN-Leitung frei |
$EDC7 | 60871 | TKSA: Gibt Sekundäradresse nach TALK aus |
$EDDD | 60893 | CIOUT: Gibt ein Byte auf seriellem Bus aus |
$EDEF | 60911 | UNTLK: Sendet UNTALK auf seriellem Bus |
$EDFE | 60926 | UNLSN: Sendet UNLISTEN auf seriellem Bus |
$EE13 | 60947 | ACPTR: Holt ein Zeichen vom seriellen Bus |
$EE85 | 61061 | Clock-Leitung low |
$EE8E | 61070 | Clock-Leitung high |
$EE97 | 61079 | Data-Leitung low |
$EEA0 | 61088 | Data-Leitung high |
$EEA9 | 61097 | Holt Bit vom seriellen Bus ins Carry-Flag |
$EEB3 | 61107 | Verzögerung 1 ms |
$EEBB | 61115 | RS-232 Ausgabe |
$EF06 | 61190 | Sendet ein Byte |
$EF2E | 61230 | RS-232 Fehlerbehandlung |
$EF4A | 61258 | Berechnet Anzahl der zu sendenden Bits +1 |
$EF59 | 61273 | Sammelt Bits zu einem Byte |
$EF7E | 61310 | Ermöglicht den Empfang eines Bytes während NMI |
$EF90 | 61328 | Testet Start-Bit nach Empfang |
$EFE1 | 61409 | Ausgabe auf RS-232 |
$F017 | 61463 | Gibt ein RS-232-Zeichen aus |
$F04D | 61517 | Initialisiert RS-232 für Eingabe |
$F086 | 61574 | Liest ein RS-232-Zeichen ein |
$F0A4 | 61604 | Schützt seriellen Bus und Bandbetrieb vor NMIs |
$F0BD | 61629 | Tabelle der I/O-Meldungen |
$F12B | 61739 | Gibt eine I/O-Meldung der Tabelle aus (Register Y als Offset) |
$F13E | 61758 | GETIN: Holt ein Zeichen vom Eingabegerät |
$F157 | 61783 | CHRIN: Eingabe eines Zeichens |
$F199 | 61849 | Holt ein Zeichen vom Band / vom seriellen Bus / von RS-232 |
$F1CA | 61898 | CHROUT: Gibt ein Zeichen aus |
$F20E | 61966 | CHKIN: Öffnet Eingabekanal |
$F250 | 62032 | CHKOUT: Öffnet Ausgabekanal |
$F291 | 62097 | CLOSE: Schließt Datei, logische Dateinummer im Akku |
$F30F | 62223 | Sucht logische Datei (Nummer in Register X) |
$F31F | 62239 | Setzt Datei-Parameter |
$F32F | 62255 | CLALL; Schließt alle Ein-/Ausgabe-Kanäle |
$F333 | 62259 | CLRCHN: Schließt aktiven I/O-Kanal |
$F34A | 62282 | OPEN: Datei öffnen (Dateinummer in $B8) |
$F3D5 | 62421 | Datei öffnen auf seriellem Bus |
$F409 | 62473 | Datei öffnen auf RS-232 |
$F49E | 62622 | LOAD: Daten ins RAM laden von Peripheriegeräten, aber nicht von Tastatur(0), RS-323(2), Bildschirm(3) |
$F4B8 | 62648 | Laden vom seriellen Bus |
$F539 | 62777 | Laden vom Band |
$F5AF | 62895 | Gibt Meldung "SEARCHING" bzw. "SEARCHING FOR" aus |
$F5C1 | 62913 | Dateiname ausgeben |
$F5D2 | 62930 | "LOADING" bzw. "VERIFYING" ausgeben |
$F5DD | 62941 | SAVE: Daten vom RAM auf Peripheriegeräte sichern, aber nicht auf Tastatur(0), RS-323(2), Bildschirm(3) |
$F5FA | 62970 | Speichern auf seriellen Bus |
$F65F | 63065 | Speichern auf Band |
$F68F | 63119 | "SAVING" ausgeben |
$F69B | 63131 | UDTIM: Erhöht TIME und fragt STOP-Taste ab |
$F6DD | 63197 | RDTIM: Uhrzeit lesen (TIME) |
$F6E4 | 63204 | SETTIM: Setzt Uhrzeit (TIME) |
$F6ED | 63213 | STOP: Fragt STOP-Taste ab |
$F6FB | 63227 | Ausgabe der Fehlermeldung "TOO MANY FILES" |
$F6FE | 63230 | Ausgabe der Fehlermeldung "FILE OPEN" |
$F701 | 63233 | Ausgabe der Fehlermeldung "FILE NOT OPEN" |
$F704 | 63236 | Ausgabe der Fehlermeldung "FILE NOT FOUND" |
$F707 | 63239 | Ausgabe der Fehlermeldung "DEVICE NOT PRESENT" |
$F70A | 63242 | Ausgabe der Fehlermeldung "NOT INPUT FILE" |
$F70D | 63245 | Ausgabe der Fehlermeldung "NOT OUTPUT FILE" |
$F710 | 63248 | Ausgabe der Fehlermeldung "MISSING FILENAME" |
$F713 | 63251 | Ausgabe der Fehlermeldung "ILLEGAL DEVICE NUMBER" |
$F72C | 63276 | Lädt nächsten Kassettenvorspann |
$F76A | 63338 | Schreibt Kassettenvorspann |
$F7D0 | 63440 | Holt Startadresse des Bandpuffers und prüft, ob gültig |
$F7D7 | 63447 | Setzt Start- und Endezeiger des Bandpuffers |
$F7EA | 63466 | Lädt Kassettenvorspann zum angegebenen Dateinamen |
$F80D | 63501 | Erhöht Bandpufferzeiger |
$F817 | 63511 | Fragt Bandtaste für Lesen ab und gibt Meldungen aus |
$F82E | 63534 | Prüft, ob Bandtaste gedrückt |
$F838 | 63544 | Wartet auf Bandtaste für Schreiben, gibt gegebenenfalls Meldung aus |
$F841 | 63553 | Liest Block vom Band |
$F84A | 63562 | Lädt vom Band |
$F864 | 63588 | Schreiben auf Band vorbereiten |
$F875 | 63605 | Allgemeine Routine für Lesen vom und Schreiben auf Band |
$F8D0 | 63696 | Prüft auf STOP-Taste während Kassetten-Nutzung |
$F8E2 | 63714 | Band für Lesen vorbereiten |
$F92C | 63788 | Band lesen; IRQ-Routine |
$FA60 | 64096 | Lädt/prüft Zeichen vom Band |
$FB8E | 64398 | Setzt Bandzeiger auf Programmstart |
$FB97 | 64407 | Initialisiert Bit-Zähler für serielle Ausgabe |
$FBA6 | 64422 | Schreiben auf Band |
$FBCD | 64461 | Start der IRQ-Routine für Band schreiben |
$FC93 | 64659 | Beendet Kassettenbetrieb |
$FCB8 | 64696 | Setzt IRQ-Vektor zurück auf Standard |
$FCCA | 64714 | Schaltet Kassettenmotor aus |
$FCD1 | 64721 | Prüft, ob Endadresse erreicht (Vergleich $AC/$AD mit $AE/$AF) |
$FCDB | 64731 | Erhöht Adresszeiger |
$FCE2 | 64738 | Reset–Routine |
$FD02 | 64770 | Prüft auf Steckmodul |
$FD10 | 64784 | Text "CBM80" für Modulerkennung |
$FD15 | 64789 | RESTOR: Rücksetzen der Ein- und Ausgabe-Vektoren auf Standardwerte |
$FD1A | 64794 | VECTOR: Setzt Vektoren abhängig von Register X/Y |
$FD30 | 64816 | Tabelle der Kernal-Vektoren für $0314-$0333 (16 mal 2 Byte) |
$FD50 | 64848 | RAMTAS: Initialisiert Zeiger für den Arbeitsspeicher |
$FD9B | 64923 | Tabelle der IRQ-Vektoren (4 mal 2 Byte) |
$FDA3 | 64931 | IOINIT: Interrupt-Initialisierung |
$FDDD | 64989 | Setzt Timer |
$FDF9 | 65017 | SETNAM: Setzt Parameter für Dateinamen |
$FE00 | 65024 | SETLFS: Setzt Parameter für aktive Datei |
$FE07 | 65031 | READST: Holt I/O-Status |
$FE18 | 65048 | SETMSG: Setzt Status als Flag für Betriebssystem-Meldungen |
$FE21 | 65057 | SETTMO: Setzt Timeout für seriellen Bus |
$FE25 | 65061 | Liest/setzt Obergrenze des BASIC-RAM (nach/von Register X/Y) |
$FE34 | 65076 | MEMBOT: Liest/setzt Untergrenze des BASIC-RAM (nach/von Register X/Y) |
$FE43 | 65091 | NMI Einsprung |
$FE47 | 65095 | Standard-NMI-Routine |
$FE66 | 65126 | Warmstart BASIC (BRK-Routine) |
$FEBC | 65212 | Interrupt-Ende (holt Register Y, X, A vom Stack und RTI) |
$FEC2 | 65218 | Tabelle mit Timerkonstanten für RS-232 Baudrate, NTSC-Version |
$FED6 | 65238 | NMI-Routine für RS-232 Eingabe |
$FF07 | 65287 | NMI-Routine für RS-232 Ausgabe |
$FF43 | 65347 | IRQ-Einsprung aus Bandroutine |
$FF48 | 65352 | IRQ-Einsprung |
$FF5B | 65371 | CINT: Video-Reset |
$FF80 | 65408 | Kernal Versions-Nummer (0 oder 3); Revision "0" hat den Clear-Screen-Bug; siehe oben, Kapitel "unterschiedliche Revisionen" |
$FF81 | 65409 | Kernal-Vektoren |
$FF81 | 65409 | CINT: Initalisierung Bildschirm-Editor |
$FF84 | 65412 | IOINIT: Initialiserung der Ein- und Ausgabe |
$FF87 | 65415 | RAMTAS: Initalisieren des RAMs, Kassettenpuffer einrichten, Anfang des Bildschirmspeichers 1024 ($0400) setzen |
$FF8A | 65418 | RESTOR: Rücksetzen der Ein- und Ausgabevektoren auf Standard |
$FF8D | 65421 | VECTOR: Abspeichern von RAM bzw. Vektorverwaltung der Sprungvektoren |
$FF90 | 65424 | SETMSG: Steuerung von KERNAL-Meldungen |
$FF93 | 65427 | SECOND: Übertragung der Sekundäradresse nach LISTEN-Befehl |
$FF96 | 65430 | TKSA: Übertragung der Sekundäradresse nach TALK-Befehl |
$FF99 | 65433 | MEMTOP: Setzen oder Lesen des Zeigers auf BASIC-RAM-Ende |
$FF9C | 65436 | MEMBOT: Setzen oder Lesen des Zeigers auf BASIC-RAM-Anfang |
$FF9F | 65439 | SCNKEY: Abfrage der Tastatur |
$FFA2 | 65442 | SETTMO: Setzen der Zeitsperre für seriellen Bus (nur für zusätzliche IEEE-Karten) |
$FFA5 | 65445 | ACPTR: Byte-Eingabe (serieller Bus) |
$FFA8 | 65448 | CIOUT: Byte-Ausgabe (serieller Bus) |
$FFAB | 65451 | UNTLK: Senden des UNTALK-Befehls für seriellen Bus |
$FFAE | 65454 | UNLSN: Senden des UNLISTEN-Befehls für seriellen Bus zur Beendigung der Datenübertragung |
$FFB1 | 65457 | LISTEN: Befehl LISTEN für Geräte am seriellen Bus (Start Datenempfang bei Peripheriegeräten) |
$FFB4 | 65460 | TALK: TALK auf den seriellen Bus senden |
$FFB7 | 65463 | READST: Lesen des Ein-/Ausgabestatusworts, also Fehlermeldungen des KERNALs (vergleiche BASIC-Systemvariable STATUS bzw. ST) |
$FFBA | 65466 | SETLFS: Setzen der Geräteadressen (logische, Primär- und Sekundäradresse) |
$FFBD | 65469 | SETNAM: Festlegen des Dateinamens |
$FFC0 | 65472 | OPEN: Logische Datei öffnen (vergleiche BASIC-Befehl OPEN) |
$FFC3 | 65475 | CLOSE: Logische Datei schließen (vergleiche BASIC-Befehl CLOSE) |
$FFC6 | 65478 | CHKIN: Eingabe-Kanal öffnen |
$FFC9 | 65481 | CHKOUT: Ausgabe-Kanal öffnen |
$FFCC | 65484 | CLRCHN: Schließt Ein- und Ausgabekanal |
$FFCF | 65487 | CHRIN: Zeicheneingabe |
$FFD2 | 65490 | CHROUT: Zeichenausgabe |
$FFD5 | 65493 | LOAD: Daten ins RAM laden von Peripheriegeräten, aber nicht von Tastatur (0), RS-323 (2), Bildschirm (3) (vergleiche BASIC-Befehl LOAD) |
$FFD8 | 65496 | SAVE: Daten vom RAM auf Peripheriegeräte sichern, aber nicht auf Tastatur (0), RS-323 (2), Bildschirm (3) (vergleiche BASIC-Befehl SAVE) |
$FFDB | 65499 | SETTIM: Setzen der Uhrzeit (vergleiche BASIC-Systemvariable TIME$/TI$) |
$FFDE | 65502 | RDTIM: Uhrzeit lesen (vergleiche BASIC-Systemvariablen TIME/TI und TIME$/TI$) |
$FFE1 | 65505 | STOP: Abfrage der Taste |
$FFE4 | 65508 | GETIN: Zeichen vom Eingabegerät einlesen |
$FFE7 | 65511 | CLALL: Schließen alle Kanäle und Dateien |
$FFEA | 65514 | UDTIM: Weiterstellen der Uhrzeit |
$FFED | 65517 | SCREEN: Anzahl der Bildschirmspalten und -zeilen ermitteln (Rückgabe im X- und Y-Register) |
$FFF0 | 65520 | PLOT: Setzen oder Lesen der Cursorpostion (X-/Y-Position) |
$FFF3 | 65523 | IOBASE: Rückmeldung der Basisadressen für Ein- und Ausgabegeräte |
Quellen[Bearbeiten | Quelltext bearbeiten]
- ↑ Buch Volkscomputer - Computer für die Masse 1981 - Startvorbereitungen, Seite 114
- ↑ Alles über den Commodore 64, Kapitel 5: Maschinensprache bzw. in der englischen Fassung: Commodore 64 Programmer's Reference Guide, p. 268: "The KERNAL" (Verwendung der Schreibweise "KERNAL")
- ↑ Videomitschnitt auf YouTube Channel 8-Bit-Guy: Commodore History Part 3 - The Commodore 64 (Anmerkung zur Schreibung "KERNAL" bei ca. 0:05:00)
- ↑ Buch Machine Language for the Commodore, Jim Butterfield, Seite 24
- ↑ Thema: KERNEL-Revisionen und Unterschiede auf Forum64.de
- ↑ zimmers.net: KERNAL Revisions - Beschreibung, Prüfsummen, Unterschiede
Weblinks[Bearbeiten | Quelltext bearbeiten]
Wikipedia: Kernal |
- Erläuterungen zu den KERNAL-Funktionen
- Commodore 64 standard KERNAL functions inkl. Parameterbeschreibung
- Mapping the C64 u.a. mit Kurzbeschreibungen der KERNAL-Funktionen
- C64 KERNAL ROM in C64OS
- Kommentierte ROM-Listings
- Source-Code
- Building the Original Commodore 64 KERNAL Source: KERNAL aus Original-Source-Code erstellen (zur Verfügung gestellt von ehem. Commodore-Engineer Dennis Jarvis)
- Reversed-Engineered, als Github-Projekt, von Michael Steil (inkl. weiterer ROM-Listing-Quellen)
Programmierung-Portalseite
C64-BASIC: BASIC V2 · BASIC-Befehle · Variable
Dieser Artikel wurde Artikel des Monats. |