KERNAL

Aus C64-Wiki
Zur Navigation springenZur Suche springen

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 Direktmodus
POKE 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):

  1. Der Stapelzeiger wird auf leeren Stapel initialisiert. Der Dezimalmodus der 6502-CPU wird deaktiviert ($FCE2).
  2. Es wird überprüft, ob sich an der Speicheradresse 32768 ($8000) eine Modulkennung befindet. Wenn vorhanden, wird die Initialisierung dem dort befindlichen Programm übertragen.
  3. Der Bildschirm wird enger gestellt (VIC-Register 22 auf Null).
  4. Initialisierung der Ein- und Ausgabe:
    1. CIA-6526 initialisieren ($FDA3).
    2. Speicheraufteilung für BASIC-Betrieb festlegen ($FDD5).
    3. Interrupt-Timer aktivieren, 60 Hz ($FDDD).
    4. Löschen des SID-Volume-Registers.
    5. Datasettenmotor abschalten.
  5. 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.
    1. Zeropage und erweiterte Zeropage löschen.
    2. 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).
    3. Bildschirmspeicher-Anfang immer auf 1024 ($0400) .
  6. Ein- und Ausgabevektoren (ab $0314) auf Standardwerte setzen.
  7. VIC initialisieren:
    1. VIC-Register mit Vorgabewerten beschreiben ($E5AA, dabei wird der Bildschirm wieder weiter gestellt).
    2. Cursorblinken initialisieren.
    3. Bildschirmfarben (blau/hellblau) setzen.
    4. Löschen des Bildschirms.
    5. Cursor-Home-Position setzen.
  8. BASIC-Kaltstart (über $A000 nach $E394):
    1. Konstanten und Vektoren in die (erweiterte) Zeropage eintragen.
    2. CHRGET aktivieren.
    3. String-Verwaltung initialisieren.
    4. BASIC-RAM aktivieren.
    5. BASIC-Start initialisieren ($0801).
    6. Einschaltmeldung ausgeben.
    7. 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]

  1. Buch Volkscomputer - Computer für die Masse 1981 - Startvorbereitungen, Seite 114
  2. Alles über den Commodore 64, Kapitel 5: Maschinensprache bzw. in der englischen Fassung: Commodore 64 Programmer's Reference Guide, p. 268: "The KERNAL" Sprache:englisch (Verwendung der Schreibweise "KERNAL")
  3. Videomitschnitt auf YouTube Channel 8-Bit-Guy: Commodore History Part 3 - The Commodore 64 (Anmerkung zur Schreibung "KERNAL" bei ca. 0:05:00) Sprache:englisch
  4. Buch Machine Language for the Commodore, Jim Butterfield, Seite 24 Sprache:englisch
  5. Thema: KERNEL-Revisionen und Unterschiede auf Forum64.de Sprache:deutsch
  6. zimmers.net: KERNAL Revisions - Beschreibung, Prüfsummen, Unterschiede Sprache:englisch

Weblinks[Bearbeiten | Quelltext bearbeiten]

WP-W11.png Wikipedia: Kernal



Artikel des Monats.gif Dieser Artikel wurde Artikel des Monats.