3. Kernal-Funktionen aufrufen

 

Nun können Sie eigene Unterprogramme in Maschinensprache erstellen, und diese auch in BASIC benutzen. Mit dem „Saver“ oder DATAGEN ist dies auch ganz einfach zu bewerkstelligen. Leider müssen Sie auf die bereits bekannte Weise das Rad immer wieder neu erfinden. Wenn Sie zum Beispiel ein Zeichen an einer ganz bestimmten Position auf dem Bildschirm ausgeben wollen, müssen Sie dafür immer wieder ein eigenes Unterprogramm erstellen. Und wenn Sie bedenken, dass Sie Ihre Daten ja auch aus einer Datei holen können, dann streichen Sie spätestens hier die Segel.

Es gibt aber noch ganz andere Unterprogramme, nämlich die, die im Kernal-ROM stehen. Diese können Sie genau so aufrufen, wie Ihre eigenen Unterprogramme, nämlich mit JSR. Der Vorteil dieser fest verdrahteten Unterprogramme ist nun, dass diese Ihnen das Leben sehr erleichtern können. So können Sie z.B. nach dem Öffnen einer Datei eine Kernal-Funktion aufrufen, die die Daten, die in der Datei stehen, automatisch in den Speicher einliest, zur Not auch so, dass Ihr laufendes BASIC-Programm dadurch unberührt bleibt. Ferner können Sie mit den Kernal-Funktionen auch in einer einfachen Weise Zeichen von der Tastatur einlesen, oder aber auf dem Bildschirm ausgeben. Auf diese Weise müssen Sie z.B. keine eigene CHAROUT-Routine programmieren, sondern können einfach vorgefertigte Standardfunktionen benutzen. Auch für das Auslesen der Tastatur gilt diese Aussage. Dies spart nicht nur Zeit, sondern verringert auch die Wahrscheinlichkeit, dass Sie in wichtige Funktionen Fehler einbauen, die Sie dann später aufwendig suchen müssen.

 

3.1 Kernal-Routinen in eigenen Programmen einsetzen

 

Der Kernal, also das Betriebssystem des C64, enthält sehr viele Subroutinen. Diese werden sehr ausgiebig benutzt, sogar vom BASIC-Interpreter und dem Texteditor. Hierbei liegen die Sprungadressen der Kernal-Routinen ab der Adresse $E000 ziemlich verstreut im Speicher. Da dies sehr benutzerunfreundlich ist, gibt es zusätzlich eine Tabelle im Speicher, die die jeweiligen JSR-Befehle zur eigentlichen Kernal-Routine enthält, die Sie aufrufen wollen. Der Vorteil dieser doppelt indirekten Adressierung ist, dass Sie sich die Aufrufadressen dieser zusätzlichen Sprungtabelle besser merken können, als die verstreut im Speicher liegenden realen Positionen der Kernal-Routinen.

Die Sprungtabelle, die Sie sich besser merken können, als die verstreut im Speicher liegenden realen Adressen der Kernal-Routinen beginnt an Adresse $FF81. Da JSR-Befehle zusammen mit dem Parameter für das Sprungziel (absolute 16-Bit-Adressen) 3 Bytes im Speicher belegen, belegt auch jede Kernal-Funktion 3 Bytes Speicher. Kommen wir nun zu einem einfachen Programmbeispiel, das die Funktion GETIN benutzt, um eine Taste von der Tastatur einzulesen. Wenn eine Taste gedrückt wird, dann soll das entsprechende Zeichen an die Adresse geschrieben werden, auf die der 16-Bit-Zeiger in den Adressen 1000 und 1001 zeigt (Lo-Byte in Adresse 1000, Hi-Byte in Adresse 1001). Damit Sie auch Zeichenketten einlesen können, wird der Zeiger in den Adressen 1000 und 1001 immer dann um den Wert erhöht, der in der Adresse 1003 steht, wenn der Wert in der Adresse 1002 nicht 0 ist.

 

06-GETCH

10    -                  .BA 49152

20    -                  .EQ GETIN=$FFE4

30    -READKEY           JSR GETIN

40    -                  CMP #0

50    -                  BEQ READKEY

60    -                  LDX 1000

70    -                  STX 248

80    -                  LDX 1001

90    -                  STX 249

100   -                  LDY #0

110   -                  STA (248),Y

120   -                  LDA 1002

130   -                  CMP #0

140   -                  BEQ EXIT

150   -                  CLC

160   -                  LDA 1000

170   -                  ADC 1003

180   -                  STA 1000

190   -                  LDA 1001

200   -                  ADC #0

210   -                  STA 1001

220   -EXIT              RTS

 

Das Assemblerprogramm GETCH beginnt an Adresse 49152. Um den Umgang mit GETIN noch mehr zu vereinfachen, wird in Zeile 20 ein Equate definiert, damit Sie GETIN (dies ist die Abkürzung von „get input“) tatsächlich über den Namen aufrufen können. So wird das eigentliche Warten auf einen Tastendruck sehr vereinfacht, und kann in einer kurzen Warteschleife realisiert werden (Zeile 30 - 50). Diese Warteschleife ruft eigentlich nur GETIN auf. Wenn GETIN zurückkehrt, dann befindet sich im Akkumulator immer dann der Wert 0, wenn keine Taste gedrückt wurde. Dieser Sachverhalt wird in Zeile 40 und 50 geprüft, und wenn der bedingte Sprung (BEQ) in Zeile 50 zutrifft, dann wurde keine Taste gedrückt, und Ihr Programm springt zurück zu Zeile 30. Wenn allerdings eine Taste gedrückt wurde, dann landen Sie in Zeile 60. Nun haben Sie das folgende Problem: Ihr Zeiger in Adresse 1000 und 1001 kann nicht auf die folgende Weise benutzt werden:

 

STA (1000),Y

 

Sie erinnern Sich? Zeiger für die indirekte, Y-indizierte Adressierung können nur in der Zeropage stehen. Aber auch im Akkumulator steht schon ein Wert, den Sie nicht mehr benutzen können, nämlich der Wert der gerade gedrückten Taste (genauer: Der zu dem entsprechenden Zeichen gehörende PETSCII-Code). Deshalb müssen Sie in Zeile 60 - 90 das X-Register und einen Hilfszeiger benutzen, der im Zero-Page-Bereich steht (im Endeffekt kopieren Sie die Inhalte der Adressen 1000 und 1001 in die Adressen 248 und 249). Nun können Sie in Zeile 100 und 110 die korrekte Adressierungsform benutzen, um den Wert, den Ihnen GETIN zurückgeliefert hat, an die richtige Zeigeradresse zu schreiben.

Nun müssen Sie feststellen, ob in Adresse 1002 der Wert 0 steht. Wenn dies der Fall ist, dann setzt der CMP-Befehl in Zeile 130 das Zero-Flag auf 1, und der bedingte Sprung in Zeile 140 springt zum Label EXIT. EXIT beendet dann Ihr Programm mit RTS. Wenn allerdings an Adresse 1002 nicht der Wert 0 steht, dann wird Ihr Zeiger in der Adresse 1000 und 1001 um den Wert erhöht, der in Adresse 1003 steht. Hierfür müssen Sie in den Zeilen 150 - 210 eine 16-Bit-Addition durchführen: Zunächst löschen Sie das Carry-Flag. Anschließend addieren Sie den Wert in Adresse 1003 zum Wert in Adresse 1000. Wenn dort ein Übertrag geschieht, dann wird dieser bei der anschließenden Addition von 0 zu dem Wert in Adresse 1001 mitberücksichtigt, weil Sie das Carry-Flag hier „stehen lassen“. Nur auf diese Weise kann Ihr Zeiger in den Adressen 1000 und 1001 auch Seitengrenzen überschreiten.

Im Endeffekt haben Sie nun schon alles beisammen, was Sie zum Umgang mit dem Kernal benötigen. Sie wissen nun, wie man eine Kernal-Funktion aufruft, und wie man die entsprechenden Rückgabewerte verarbeitet. Was nun noch fehlt, ist eine Übersicht über sämtliche Kernal-Funktionen, die entsprechenden Aufrufadressen und verwendeten Register.

 

3.2 Kernal-ROM-Referenz

 

Kommen wir nun zu den Kernal-Funktionen selbst Die Kernal-Routinen werden durch eine Sprungtabelle verwaltet, die an der Adresse $FF81 beginnt, und an der Adresse $FFF5 endet. Für jede Kernal-Routine gibt es nun einen 3 Byte großen Eintrag, der einen JSR-Befehl für jeweils eine bestimmte Routine enthält. Wenn Sie also z.B. die Funktion, die an der Adresse $FF81 steht, mit SYS 65409 aufrufen, dann wird ein indirekter Sprung zu der eigentlichen Routine an Adresse $FF5B ausgeführt. Zum Glück brauchen Sie sich nicht darum zu kümmern, wo die Original-Routine steht, Sie müssen sich aber dennoch darum kümmern, die Parameter in der richtigen Weise zu übergeben. In Assembler brauchen Sie nur die entsprechenden Register mit den richtigen Werten zu füllen und anschließend den richtigen JSR-Befehl ausführen. In BASIC ist die Sache dagegen ein klein wenig komplizierter, weil BASIC die Register A, X und Y in den Adressen 780, 781 und 782 spiegelt (in genau dieser Reihenfolge), und im Fall eines SYS-Befehls automatisch an die entsprechende Kernal-Funktion übergibt. Sie müssen also in diesem Fall die Adressen 780, 781 und 782 durch POKE-Anweisungen mit den richtigen Werten füllen, bevor Sie die entsprechende Kernal-Routine mit SYS aufrufen. Die nachfolgende Referenz erklärt nun sämtliche Kernal-Funktionen. (Quelle: http://sta.c64.org/cbm64krnfunc.html)

 

3.2.1 SCINIT-Funktion

 

SYS-Adresse: $FF81 (65409)

Reale Adresse(n) der aufgerufenen Funktion(en): $FF5B

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

SCINIT initialisiert sämtliche VIC-Register mit Standardwerten und setzt sämtliche Ein- und Ausgaben wieder auf die Standardwerte zurück. Dies bedeutet, dass wenn Sie Ihre Ein- oder Ausgaben in eine Datei oder auf den Drucker umgeleitet haben, diese Umleitungen auf die Tastatur und auf den Bildschirm zurückgesetzt werden. SCINIT löscht auch den Bildschirm und reaktiviert den Timer-Interrupt, wenn dieser zuvor deaktiviert wurde.

 

3.2.2 IOINIT-Funktion

 

SYS-Adresse: $FF84 (65412)

Reale Adresse(n) der aufgerufenen Funktion(en): $FDA3

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X

 

IOINIT initialisiert die CIA-Chips mit Standardwerten und setzt die Lautstärke des SID auf den Wert 0 zurück. Auch der Speicher wird neu mit Standardwerten initialisiert, und der Timer-Interrupt wird wieder eingeschaltet, wenn dieser vorher deaktiviert war. Wenn Sie zuvor die Speicherkonfiguration geändert haben (z.B. das BASIC-ROM ausgeblendet haben, oder eine andere Bank für den Bildschirmspeicher gewählt haben), dann werden diese Einstellung rückgängig gemacht. Auch die Tastatur wird wieder reaktiviert, wenn diese vorher ausgeschaltet war.

 

3.2.3 RAMTAS-Funktion

 

SYS-Adresse: $FF87 (65415)

Reale Adresse(n) der aufgerufenen Funktion(en): $FD50

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

RAMTAS löscht die Adressen $0002-$0101 und $0200-$03FF und führt einen internen Speichertest aus. Ebenfalls werden die Zeiger für den Start und das Ende des BASIC-Programms neu berechnet, und es wird dafür gesorgt, dass wieder 38.911 BASIC-Bytes frei sind.  Die Startadresse des Bildschirmspeichers wird allerdings ebenfalls auf 1024 zurückgesetzt, das heißt, wenn Sie die Lage des Bildschirmspeichers zuvor geändert haben, wird auch diese Änderung rückgängig gemacht.

 

3.2.4 RESTOR-Funktion

 

SYS-Adresse: $FF8A (65418)

Reale Adresse(n) der aufgerufenen Funktion(en): $FD15

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: Keine

 

RESTOR verhält sich so, als ob Sie die RESTORE-Taste gedrückt hätten: Die Timer-Interrupt-Routine wird zurückgesetzt, und die Adressen $0314-$0333 werden mit Standardwerten gefüllt. Anschließend wird der Bildschirm gelöscht, und es erscheint READY.

 

3.2.5 VECTOR-Funktion

 

SYS-Adresse: $FF8D (65421)

Reale Adresse(n) der aufgerufenen Funktion(en): $FD1A

Eingabeparameter: Start einer Vektortabelle in Form von Lo/Hi in Register X/Y

Ausgabeparameter: Keine

Veränderte Register: A, Y

 

Mit VECTOR können Sie die Zeiger in den Adressen $0314-$0333 auslesen oder neu setzten. Dazu muss in die Indexregister die Startadresse der eigenen Vektortabelle eingetragen werden (X=Lo-Byte, Y=Hi-Byte). Das Carry-Flag entscheidet dabei darüber, was die Routine tut. Wird das Carry-Flag zuvor mit CLC gelöscht, wird die benutzerdefinierte Tabelle an die Adressen $0314-$0333 geschrieben, wird das Carry-Flag zuvor mit SEC gesetzt, werden die Werte an den Adressen $0314-$0333 ausgelesen und in die benutzerdefinierte Tabelle übertragen. Da Sie von BASIC aus das Carry-Flag nicht beeinflussen können, können Sie diese Routine nicht mit SYS aufrufen.

 

3.2.6 SETMSG-Funktion

 

SYS-Adresse: $FF90 (65424)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE18

Eingabeparameter: Switch Value im Akkumulator

 

SETMSG setzt den System Error Display Switch an der Adresse $009D auf einen bestimmten Wert. Dieser Wert hat jedoch keinen Einfluss auf BASIC, und es werden stets alle Fehlermeldungen angezeigt, egal, was hier eintragen wird. SETMSG taucht auch in keinem Beispiel auf, das Sie im Internet finden können, und es wird auch nicht erklärt, welcher Wert z.B. zum Abschalten bzw. Einschalten von System-Fehlermeldungen benutzt werden kann.

 

3.2.7 LSTNSA-Funktion

 

SYS-Adresse: $FF93 (65427)

Reale Adresse(n) der aufgerufenen Funktion(en): $EDB9

Eingabeparameter: Sekundär-Geräte-Adresse für den seriellen Bus

Ausgabeparameter: Keine

Veränderte Register: A

 

LSTNSA setzt voraus, dass Sie zuvor ein Gerät mit LISTEN in den Empfangs-Bereitschaftsmodus versetzt haben (das Gerät hört Ihnen nun quasi zu und wartet auf Daten). Meistens müssen Sie dafür zunächst eine Primäradresse (das ist die Geräteadresse), aber auch zusätzlich eine Sekundäradresse (das ist eine Art Empfangskanal) angeben. LSTNSA legt hierbei die Sekundäradresse fest und teilt diese anschließend auch dem Gerät mit, damit dieses weiß, auf welchem Kanal Sie Daten senden. Die Sekundäradresse ist allerdings vom Gerät abhängig, und Sie können z.B. für einen Drucker mit der Geräteadresse 3 nicht den gleichen Fehlerkanal mit der Sekundäradresse 15 benutzen, wie bei Ihrer Floppy.

 

3.2.8 TALKSA-Funktion

 

SYS-Adresse: $FF96 (65430)

Reale Adresse(n) der aufgerufenen Funktion(en): $EDC7

Eingabeparameter: Sekundär-Geräte-Adresse für den seriellen Bus

Ausgabeparameter: Keine

Veränderte Register: A

 

TALKSA setzt voraus, dass Sie zuvor ein Gerät mit TALK in den Sendemodus versetzt haben (das Gerät sendet nun Daten, wenn es welche im Puffer hat). Meistens müssen Sie dafür zunächst eine Primäradresse (das ist die Geräteadresse), aber auch zusätzlich eine Sekundäradresse (das ist eine Art Empfangskanal) angeben. TALKSA legt nun die Sekundäradresse fest und teilt diese anschließend diese auch dem Gerät mit, damit dieses weiß, auf welchem Kanal es senden soll. Die Sekundäradresse ist allerdings auch bei TALK vom Gerät abhängig. Beim Commodore-Bus kann übrigens nur ein Gerät senden, während alle anderen Geräte, die nicht senden, zuhören müssen. Alle Geräte hängen hier am gleichen Buskabel, weshalb man hier auch von einem Feldbus sprechen kann.

 

3.2.9 MEMBOT-Funktion

 

SYS-Adresse: $FF99 (65433)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE25

Eingabeparameter: Zeiger auf den Beginn des BASIC-Arbeitsbereichs in den Index-Registern X/Y

Ausgabeparameter: Beginn des BASIC-Arbeitsbereichs in den Index-Registern X/Y

Veränderte Register: X, Y

 

BOT hat nichts mit einem Bot wie Chatbot zu tun, sondern BOT ist die Abkürzung von „bottom“. Der BASIC-Arbeitsbereich enthält die Variablen, Strings und Array-Elemente, die während des Programmbetriebs angelegt werden. MEMBOT (memory bottom) setzt den Start dieses Bereiches neu, wenn Sie vorher das Carry-Flag mit SEC auf 1 setzen, und liest den aktuellen MEMBOT-Zeiger in die Index-Register ein, wenn Sie vorher das Carry-Flag mit CLC löschen. MEMBOT kann dazu benutzt werden, die Größe des verfügbaren Speichers zu ändern. MEMBOT sollte (wie auch MEMTOP) mit Bedacht eingesetzt werden, denn Sie können mit dieser Funktion viel Schaden anrichten. Da Sie von BASIC aus das Carry-Flag nicht beeinflussen können, können Sie diese Routine nicht mit SYS aufrufen.

 

3.2.10 MEMTOP-Funktion

 

SYS-Adresse: $FF9C (65436)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE34

Eingabeparameter: Zeiger auf den Beginn des BASIC-Arbeitsbereichs in den Index-Registern X/Y

Ausgabeparameter: Beginn des BASIC-Arbeitsbereichs in den Index-Registern X/Y

Veränderte Register: X, Y

 

Der BASIC-Arbeitsbereich enthält die Variablen, Strings und Array-Elemente, die während des Programmbetriebs angelegt werden. MEMTOP (memory top) setzt das Ende dieses Bereiches neu, wenn Sie vorher das Carry-Flag mit SEC auf 1 setzen, und liest den aktuellen MEMTOP-Zeiger in die Index-Register ein, wenn Sie das Carry-Flag vorher mit CLC löschen. MEMTOP kann dazu benutzt werden, die Größe des verfügbaren Speichers zu ändern. MEMTOP sollte mit Bedacht eingesetzt werden, denn Sie können mit dieser Funktion viel Schaden anrichten. Da Sie von BASIC aus das Carry-Flag nicht beeinflussen können, können Sie diese Routine nicht mit SYS aufrufen.

 

3.2.11 SCNKEY-Funktion

 

SYS-Adresse: $FF9F (65439)

Reale Adresse(n) der aufgerufenen Funktion(en): $EA87

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

Diese Funktion an Adresse $EA87 wird auch immer aufgerufen, wenn ein Timer-Interrupt auftritt, deshalb müssen Sie sich eigentlich normalerweise nicht um die Abfrage des Keyboards kümmern. Allerdings gibt es auch Fälle, in denen Sie z.B. bei abgeschalteten Interrupts auf eine bestimmte Taste warten müssen, und in diesem Fall müssen Sie dann SCNKEY per Hand aufrufen. SCNKEY schreibt nun einen eindeutigen Matrix-Code, der jeder Taste zugeordnet ist, in die Adresse $00CB, und den aktuellen Status der beiden SHIFT-Tasten als Flags in die Adresse $028D (ist Bit 0 gesetzt, ist die linke SHIFT-Taste gedrückt, ist Bit 1 gesetzt, ist die rechte SHIFT-Taste gedrückt). Der Code, den Sie benutzen müssen, um das entsprechende Zeichen auf der Tastatur in den Bildschirmspeicher zu schreiben, landet anschließend im Tastaturpuffer, der an der Adresse $0280 beginnt, und bis zu 10 Tasten aufnehmen kann. Beachten Sie hier unbedingt, dass SCNKEY im Tastaturpuffer keine ASCII-Codes ablegt, und erst BASIC dafür sorgt, dass der PETSCII-Code durch einen ASCII-Code ersetzt wird. Wenn BASIC jedoch nicht aktiv ist, weil Sie z.B. vorher das BASIC-ROM abgeschaltet haben, dann müssen Sie sich selbst um solche Dinge kümmern. Viele Spiele tun genau dies, da dieses Vorgehen 100-mal schneller sein kann, als die Standardroutinen.

 

3.2.12 SETTMO-Funktion

 

SYS-Adresse: $FFA2 (65442)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE21

Eingabeparameter: Timeout-Wert für die serielle Schnittstelle im Akkumulator

Ausgabeparameter: Keine

Veränderte Register: Keine

 

SETTMO (set timeout) legt den Timeout-Wert für die serielle Schnittstelle in 1/60 Sekunden-Schritten fest. Das heißt, ein Timeout von 60 bedeutet, dass wenn die serielle Schnittstelle nach einer Sekunde nicht antwortet, bzw. eine Sekunde lang kein Zeichen mehr sendet, ein Timeout-Fehler ausgelöst wird. Normalerweise behandelt BASIC dann diesen Zustand und versucht z.B. festzustellen, ob überhaupt noch Daten erwartet werden. Wenn dies der Fall ist, wird von BASIC aus die Fehlermeldung DEVICE NOT PRESENT ausgegeben, unabhängig davon, ob das entsprechende Gerät vorher schon einmal erreichbar war.

 

3.2.13 IECIN-Funktion

 

SYS-Adresse: $FFA5 (65445)

Reale Adresse(n) der aufgerufenen Funktion(en): $EE13

Eingabeparameter: Keine

Ausgabeparameter: Byte von der seriellen Schnittstelle im Akkumulator

Veränderte Register: A

 

IECIN liest ein Byte von der seriellen Schnittstelle und schreibt den Byte-Wert in den Akkumulator. Alle Geräte, die an der seriellen Schnittstelle hängen, müssen vorher mit TALK in den Sendemodus versetzt werden, und müssen auch eine sekundäre Geräteadresse erhalten. IECIN ist eine blockierende Funktion, das heißt, sie wartet auf jedes Byte, und muss deshalb so lange in einer Schleife aufgerufen werden, bis alle Bytes eingelesen wurden. Erst dann kann ein eventueller Datenpuffer an die Zieladresse kopiert werden. IECIN gibt leider keinen Fehlerstatus zurück, und kann auch nicht feststellen, ob wirklich ein Byte verfügbar ist. Erst, wenn ein Timeout an der seriellen Schnittstelle auftritt, wird ein Interrupt ausgelöst, und BASIC kann dieses Timeout dann mit der Meldung DEVICE NOT PRESENT quittieren. Leider sagt DEVICE NOT PRESENT nichts darüber aus, woran es gelegen hat, dass kein Byte mehr empfangen werden kann.

 

3.2.14 IECOUT-Funktion

 

SYS-Adresse: $FFA8 (65448)

Reale Adresse(n) der aufgerufenen Funktion(en): $EDDD

Eingabeparameter: Byte-Wert im Akkumulator

Ausgabeparameter: Keine

Veränderte Register: A

 

IECOUT sendet ein Byte an die serielle Schnittstelle, der Byte-Wert steht im Akkumulator. Alle Geräte, die an der seriellen Schnittstelle hängen, müssen vorher mit LISTEN in den Empfangsmodus versetzt werden, und müssen auch eine sekundäre Geräteadresse erhalten. IECIN ist eine blockierende Funktion, das heißt sie wartet bei jedem Byte darauf, dass es korrekt gesendet wurde. Manche Geräte führen jedoch kein Handshake aus. Handshake bedeutet: Sie müssen den korrekten Empfang eines Bytes stets bestätigen. Ein fehlendes Handshake bei vielen Geräten ist sicherlich ein Manko, aber es gab früher viele solche Geräte, bei denen man sich nicht sicher sein konnte, dass auch alle Bytes korrekt gesendet wurden. Auch IECOUT selbst gibt leider keinen Fehlerstatus zurück. Erst, wenn ein Timeout an der seriellen Schnittstelle auftritt, weil z.B. das Handshake ausbleibt, wird ein Interrupt ausgelöst, und BASIC kann dieses Timeout dann mit der Meldung DEVICE NOT PRESENT quittieren. Leider sagt DEVICE NOT PRESENT nichts darüber aus, woran es gelegen hat, dass kein Byte mehr gesendet werden kann.

 

3.2.15 UNTALK-Funktion

 

SYS-Adresse: $FFAB (65451)

Reale Adresse(n) der aufgerufenen Funktion(en): $EDEF

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A

 

UNTALK sendet ein UNTALK-Kommando über den Bus. Da hier der Commodore-Bus benutzt wird, bei dem sämtliche Geräte an einer einzigen Leitung hängen, kann auch immer nur ein einziges Gerät senden. Es ist also immer klar, welches Gerät gemeint ist, wenn Sie UNTALK senden, Sie müssen deshalb hier keine Geräteadressen angeben. UNTALK führt nun dazu, dass sämtliche Geräte wieder in den LISTEN-Modus wechseln und auf die Übermittlung einer Geräteadresse warten. Wenn Sie also nun ein anderes Gerät zum Senden von Daten auffordern wollen, müssen Sie zunächst wieder die Kommandos TALK und TALKSA verwenden, um ein neues Gerät auszuwählen und auch eine Sekundäradresse mitzuteilen.

 

3.2.16 UNLSTN-Funktion

 

SYS-Adresse: $FFAE (65454)

Reale Adresse(n) der aufgerufenen Funktion(en): $EDFE

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A

 

UNLSTN sendet ein UNLISTEN-Kommando über den Bus. Da hier der Commodore-Bus benutzt wird, bei dem sämtliche Geräte an einer einzigen Leitung hängen, kann auch immer nur ein einziges Gerät senden - in diesem Fall ist es der C64. Es ist also immer klar, dass Sie selbst keine Daten mehr senden wollen, wenn Sie UNLISTEN übermitteln, Sie müssen deshalb hier keine Geräteadressen angeben.

 

3.2.17 LISTEN-Funktion

 

SYS-Adresse: $FFB1 (65457)

Reale Adresse(n) der aufgerufenen Funktion(en): $ED0C

Eingabeparameter: Gerätenummer

Ausgabeparameter: Keine

Veränderte Register: A

 

LISTEN versetzt ein Gerät, für das Sie die Gerätenummer im Akkumulator angeben, in den LISTEN-Modus. Dies bedeutet, dass das Gerät nun zuhört und auf die Übermittlung von Daten wartet. Das erste Byte, dass Sie nun senden müssen, ist die Sekundäradresse, die quasi ein spezieller Kanal ist, auf dem Sie später Daten übertragen wollen. Deshalb müssen Sie auch direkt nach LISTEN mit LSTNSA eine Sekundäradresse übermitteln, bevor Sie die eigentlichen Daten übertragen können. Die Sekundäradresse, die Sie verwenden müssen, ist vom Gerät abhängig, und muss eventuell dem Handbuch zu dem entsprechenden Gerät entnommen werden. Bei der Floppy ist dies der Kanal 1 für Maschinenprogramme, 8 für BASIC-Programme oder 15 für den Kommandokanal.

 

3.2.18 TALK-Funktion

 

SYS-Adresse: $FFB4 (65460)

Reale Adresse(n) der aufgerufenen Funktion(en): $ED09

Eingabeparameter: Gerätenummer

Ausgabeparameter: Keine

Veränderte Register: A

 

TALK versetzt ein Gerät, für das Sie die Gerätenummer im Akkumulator angeben, in den TALK-Modus. Dies bedeutet, dass das Gerät nun bereit ist, Daten zu senden. Bevor dies aber geschehen kann, müssen Sie noch zusätzlich die Sekundäradresse mit TALKSA übermitteln. Die Sekundäradresse ist quasi ein spezieller Kanal, auf dem Sie später die Daten abholen wollen. Die Sekundäradresse, die Sie verwenden müssen, ist vom Gerät abhängig, und muss eventuell dem Handbuch zu dem entsprechenden Gerät entnommen werden. Meistens ist es auch nötig, mehrmals zwischen LISTEN und TALK hin und her zu wechseln, weil die meisten Geräte (z.B. die Floppystation) erst Daten senden, wenn Sie das entsprechende Kommando hierfür übertragen haben.

 

3.2.19 READST-Funktion

 

SYS-Adresse: $FFB7 (65463)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE07

Eingabeparameter: Keine

Ausgabeparameter: Gerätestatus-Byte im Akkumulator

Veränderte Register: A

 

READST ist eigentlich eine Funktion, die nur das Kommando GETST (get status) über den Bus sendet - und zwar an das Gerät, dass Sie zuletzt adressiert haben. Jedes Gerät muss in jedem Modus das GETST-Byte (Byte-Wert $FF) akzeptieren, egal, ob dies gerade im LISTEN-Modus oder im TALK-Modus arbeitet. Wenn ein Gerät GETST empfängt, muss dieses sofort ein Status-Byte zurücksenden, das READST danach im Akkumulator ablegt. Einige Geräte, wie z.B. Modems, die das RS232-Protokoll verwenden, unterstützen keine Geräte-Status-Bytes, deshalb wird in diesem Fall der Wert $00 in den Akkumulator geladen. Der Wert $00 bedeutet stets, dass alles okay ist, selbst bei der Floppy-Station, die Status-Bytes unterstützt, ist dies so. Allerdings ist die Bedeutung der Status-Byte auch teilweise geräteabhängig, weshalb hier unbedingt das entsprechende Handbuch zu Rate gezogen werden sollte.

 

3.2.20 SETLFS-Funktion

 

SYS-Adresse: $FFBA (65466)

Reale Adresse(n) der aufgerufenen Funktion(en): $FE07

Eingabeparameter: A=logische Dateinummer, X=Gerätenummer, Y=Sekundäradresse

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

SETLFS legt die Parameter einer Datei fest, die Sie später mit OPEN öffnen wollen. SETLFS arbeitet nur zusammen mit Kassettenlaufwerken (Geräteadresse 1) und Floppy-Stationen (Geräteadressen 8, 9, 10, 11), und nicht mit Druckern oder Modems. Auch manche Festplattenlaufwerke werden unterstützt, aber nur die, die auch Standard-Floppy-Kommandos verstehen. SETLFS wird auch zuerst von BASIC aus aufgerufen, wenn Sie OPEN verwenden. Z.B. wird bei dem Befehl

 

OPEN 1,8,1,"TEST"

 

SETLFS mit den Parametern A=1 (logische Dateinummer 1), X=8 (Gerätenummer 8), Y=1 (Sekundäradresse 1) aufgerufen. Dies führt dann dazu, dass die Floppy mit der Geräteadresse 8 an die Sekundäradresse 1 gebunden wird. Der Dateiname wird allerdings separat durch SETNAM festgelegt, erst danach können Sie OPEN aufrufen.

 

3.2.21 SETNAM-Funktion

 

SYS-Adresse: $FFBD (65469)

Reale Adresse(n) der aufgerufenen Funktion(en): $FDF9

Eingabeparameter: A=Länge des Dateinamens, X/Y=Zeiger auf den Dateiname-String

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

SETNAM legt für die Datei einen Dateinamen fest, für die Sie die Parameter vorher mit SETLFS festgelegt haben. Die Länge des Dateinamens müssen Sie im Akkumulator angeben, und den Zeiger auf die Adresse, an der der String mit dem Dateinamen beginnt, müssen Sie in der Form X=Lo-Byte, Y=Hi-Byte angeben. Sie dürfen hier allerdings keine PETSCII-Zeichen in Ihrem Dateinamen verwenden, sondern müssen ASCII-Codes benutzen. Dies ist der einzige Code, den Floppys und Kassettenlaufwerke verstehen.

 

3.2.22 OPEN-Funktion

 

SYS-Adresse: $FFC0 (65472)

Reale Adresse(n) der aufgerufenen Funktion(en): $031A, $F34A

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

OPEN öffnet die Datei, die Sie vorher durch SETLFS und SETNAM definiert haben. OPEN gibt keine Parameter zurück, und nimmt auch keine entgegen, da vorher detailliert festgelegt wurde, welches Gerät nun die Kommandos bzw. Daten empfangen soll. Allerdings legt OPEN einen internen Puffer für sämtliche Dateiparameter an, und ordnet diesen Parametern auch die logische Dateinummer zu, die Sie bei SETLFS angegeben haben.

 

3.2.23 CLOSE-Funktion

 

SYS-Adresse: $FFC3 (65475)

Reale Adresse(n) der aufgerufenen Funktion(en): $031C, $F291

Eingabeparameter: Logische Dateinummer im Akkumulator

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

CLOSE schließt die Datei, die Sie durch die logische Dateinummer im Akkumulator angeben. OPEN legt einen internen Puffer für sämtliche Dateiparameter an, und ordnet diesen Parametern auch die logische Dateinummer zu, die Sie vorher mittels SETLFS angegeben haben. CLOSE gibt die Dateiparameter für eine geschlossene Datei wieder frei. Das bedeutet, dass die freigewordene logische Dateinummer wieder für andere Dateien benutzt werden kann. Da die Anzahl der verfügbaren Dateinummern begrenzt ist, sollten Dateien stets wieder geschlossen werden, nachdem die Arbeit an ihnen beendet wurde.

 

3.2.24 CHKIN-Funktion

 

SYS-Adresse: $FFC6 (65478)

Reale Adresse(n) der aufgerufenen Funktion(en): $031E, $F20E

Eingabeparameter: Logische Dateinummer im X-Register

Ausgabeparameter: Keine

Veränderte Register: A, X

 

CHKIN (change keyboard input) leitet sämtliche Tastatureingaben in eine Datei um. Die logische Dateinummer, in die die Eingaben umgeleitet werden, befindet sich vorher im X-Register. Diese Datei wird dann als das sogenannte Default Input File ausgewählt, und sämtliche Bytes, die Sie anschließend mit CHRIN (siehe auch dort) einlesen, werden in das Default Input File umgeleitet.

 

3.2.25 CHKOUT-Funktion

 

SYS-Adresse: $FFC9 (65481)

Reale Adresse(n) der aufgerufenen Funktion(en): $0320, $F250

Eingabeparameter: Logische Dateinummer im X-Register

Ausgabeparameter: Keine

Veränderte Register: A, X

 

CHKOUT (change output) leitet sämtliche Bildschirmausgaben in eine Datei um, die logische Dateinummer, in die die Ausgaben umgeleitet werden, befindet sich vorher im X-Register. Diese Datei wird dann als das sogenannte Default Output File ausgewählt, und sämtliche Bytes, die Sie anschließend mit CHROUT (siehe auch dort) ausgeben, werden in das Default Output File umgeleitet. So können Sie z.B. in einfacher Weise ein Screenshoot als Datei speichern, Sie müssen nur die Zeichen auf dem Bildschirm auslesen und per CHROUT in eine vorher mit CHKOUT ausgewählte Datei schreiben.

 

3.2.26 CLRCHN-Funktion

 

SYS-Adresse: $FFCC (65484)

Reale Adresse(n) der aufgerufenen Funktion(en): $0322, $F333

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X

 

CLRCHN (clear channels) setzt die umgeleitete Ein- und Ausgabe auf die Standardwerte zurück, deshalb benötigt CLRCHN keine zusätzlichen Parameter. Die Standardeingabe ist nach Aufruf von CLRCHN die Tastatur, die Standardausgabe der Bildschirm.

 

3.2.27 CHRIN-Funktion

 

SYS-Adresse: $FFCF (65487)

Reale Adresse(n) der aufgerufenen Funktion(en): $0324, $F157

Eingabeparameter: Keine

Ausgabeparameter: Zeichen von der Tastatur im Akkumulator

Veränderte Register: A, Y

 

CHRIN (character input) liest ein Zeichen von der Standard-Eingabe ein und speichert dies im Akkumulator. Für den Fall, dass die Standard-Eingabe die Tastatur ist, wird jedoch eine ganze Zeile eingelesen, bis Sie RETURN drücken (nur das letzte Zeichen in der Zeile landet in diesem Fall im Akkumulator).

 

3.2.28 CHROUT-Funktion

 

SYS-Adresse: $FFD2 (65490)

Reale Adresse(n) der aufgerufenen Funktion(en): $0324, $F157

Eingabeparameter: Zu schreibendes Zeichen

Ausgabeparameter: Keine

Veränderte Register: Keine

 

CHROUT (character output) schreibt ein Zeichen als Byte auf die Standard-Ausgabe, der Byte-Wert befindet sich im Akkumulator. Für den Fall, dass die Standard-Ausgabe der Bildschirm ist, wird das entsprechende Zeichen, das dem Zeichen mit dem ASCII-Code im Akkumulator entspricht, an der aktuellen Cursorposition ausgegeben. Wenn die Standard-Ausgabe umgeleitet wurde, wird das Byte in die entsprechende Datei geschrieben (siehe auch CHKOUT).

 

3.2.29 LOAD-Funktion

 

SYS-Adresse: $FFD5 (65493)

Reale Adresse(n) der aufgerufenen Funktion(en): $F49E

Eingabeparameter: A=Flags, X/Y=Ladeadresse in Form von Lo- und Hi-Byte

Ausgabeparameter: Fehlerstatus im Carry-Flag

Veränderte Register: A, X, Y

 

LOAD lädt eine Datei in den Speicher und setzt das Carry-Flag auf 1, wenn ein Fehler aufgetreten ist (natürlich muss diese Datei vorher mit OPEN geöffnet werden). Nur, wenn im Akkumulator der Wert 0 übergeben wird, wird eine Datei auch geladen, ein anderer Wert als 0 bedeutet, dass ein Verify ausgeführt wird. Verify heißt, dass der Inhalt der Datei mit dem Puffer verglichen wird, auf die der Zeiger in den Registern X und Y zeigt (X=Lo-Byte, Y=Hi-Byte). Wenn der Inhalt der Datei mit dem Puffer übereinstimmt, dann wird das Carry-Flag gesetzt, und der Zeiger in den Registern X und Y zeigt danach auf das letzte Byte, das korrekt ist. Im Fehlerfall wird stets eine Fehlernummer im Akkumulator übergeben (siehe auch Abschnitt Kernal-Fehler).

Wenn im Akkumulator 0 übergeben wird, dann wird die Datei in den Speicher geladen. Normalerweise geben hier die ersten 2 Bytes in der Datei die Startadresse in Form eines Lo- und Hi-Bytes an, es sei denn, die Sekundäradresse wird auf 0 gesetzt. In diesem Fall können Sie selbst entscheiden (durch einen Zeiger in den Registern X und Y), an welche Stelle Ihr Programm geladen wird. BASIC benutzt diese Konstruktion immer dann, wenn Sie eine Datei mit ,8 und nicht mit ,8,1 laden. In diesem Fall wird ein neues BASIC-Programm an die Adresse 2049 geladen.

 

3.2.30 SAVE-Funktion

 

SYS-Adresse: $FFD8 (65496)

Reale Adresse(n) der aufgerufenen Funktion(en): $F5DD

Eingabeparameter: A=Zeropage-Zeiger, X/Y=Endadresse in Form von Lo- und Hi-Byte

Ausgabeparameter: Fehlerstatus im Carry-Flag

Veränderte Register: A, X, Y

 

SAVE speichert einen Speicherbereich in einer Datei (natürlich muss die Datei vorher mit OPEN geöffnet worden sein). Anders, als bei LOAD, müssen hier zwei Zeiger angegeben werden. Deshalb befindet sich nur der Zeiger auf das letzte Byte des Speicherblocks in den Index-Registern, und Sie müssen im Akkumulator zusätzlich einen Zeropage-Zeiger übergeben, der auf die Startadresse des Speicherblocks zeigt. Dieser Zeropage-Zeiger wird dann später mittels Y-indizierter indirekter Adressierung dazu benutzt, das aktuelle Byte, das Sie in die Datei schreiben wollen, auszulesen. Im Fehlerfall wird das Carry-Flag gesetzt, und im Akkumulator befindet sich eine Fehlernummer (siehe auch Abschnitt Kernal-Fehler).

 

3.2.31 SETTIM-Funktion

 

SYS-Adresse: $FFDB (65499)

Reale Adresse(n) der aufgerufenen Funktion(en): $F6E4

Eingabeparameter: A/X/Y=Neuer Wert der Uhr (Time of day)

Ausgabeparameter: Keine

Veränderte Register: A, X, Y

 

SETTIM schreibt einen Zeitwert in die Adressen 160-162 ($00A0-$00A2), die die BASIC-Uhr dann in der Variablen TI ablegt. In Adresse 160 wird der Wert aus dem Akkumulator, in Adresse 161 der Wert aus dem X-Register, und in Adresse 162 der Wert aus dem Y-Register eingetragen. Zusammengenommen hat die Uhr also einen Wert von 3 Bytes, dieser wird jedoch nicht etwa jede 1/100 Sekunde oder jede Sekunde erhöht, sondern in Einheiten von 1/60 Sekunden. Auch ist der Zeitzähler ein einfacher Zähler, deshalb läuft auch der Wert in der Adresse 160 nicht nach 60 Zählerschritten über, sondern erst nach 256. Sie müssen also, wenn Sie eine bestimmte Uhrzeit hier eintragen wollen, diese in 1/60 Sekunden-Intervalle umrechnen.

 

3.2.32 RDTIM-Funktion

 

SYS-Adresse: $FFDE (65502)

Reale Adresse(n) der aufgerufenen Funktion(en): $F6DD

Eingabeparameter: Keine

Ausgabeparameter: Neuer Wert der Uhr (Time of day) in A/X/Y

Veränderte Register: A, X, Y

 

RDTIM liest den aktuellen Zeitwert der Uhr in die Adressen 160-162 ($00A0-$00A2) ein, die die BASIC-Uhr auch so in der Variablen TI ablegt. Im Akkumulator wird der Wert aus der Adresse 160 eingetragen, in das X-Register wird der Wert aus der Adresse 161 eingetragen, und in das Y-Register der Wert aus der Adresse 162. Zusammengenommen hat die Uhr also einen Wert von 3 Bytes, dieser wird jedoch nicht etwa jede 1/100 Sekunde oder jede Sekunde erhöht, sondern in Einheiten von 1/60 Sekunden. Auch ist der Zeitzähler ein einfacher Zähler, deshalb läuft auch der Wert in der Adresse 160 nicht nach 60 Zählerschritten über, sondern erst nach 256. Sie müssen also, wenn Sie den Zählerstand auslesen und die aktuelle Uhrzeit erhalten wollen, diese von 1/60 Sekunden-Intervallen in eine reale Uhrzeit umrechnen. Allerdings benötigen Sie Zusatzhardware mit einem batteriegetriebenen Pufferspeicher, wenn Ihre Uhr auch bei ausgeschaltetem Computer weiterlaufen soll.

 

3.2.33 STOP-Funktion

 

SYS-Adresse: $FFE1 (65505)

Reale Adresse(n) der aufgerufenen Funktion(en): $0328, $F6ED

Eingabeparameter: Keine

Ausgabeparameter: Zero-Flag mit dem Status der STOP-Taste

Veränderte Register: A, X

 

STOP fragt ab, ob die RUN/STOP-Taste gedrückt ist, und wenn dies der Fall ist, dann wird das Zero-Flag gesetzt und der Keyboard-Puffer gelöscht. Natürlich werden auf diese Weise auch sämtliche eventuellen Umleitungen von Eingaben in eine Datei zurückgesetzt. Von BASIC aus können Sie diese Funktion allerdings nicht verwenden, weil dort die RUN/STOP-Taste die Funktion hat, ein laufendes Programm zu unterbrechen. In vielen Spielen wird jedoch die RUN/STOP-Taste umprogrammiert bzw. deaktiviert, damit Sie z.B. nachdem das Spiel gestartet wurde, kein Speicherabbild mehr auf Diskette erstellen können (dies ist eine der Methoden, mit denen sich einige alten Spiele knacken lassen). Zusammen mit der Deaktivierung der RUN/STOP-Taste wird bei moderneren Spielen auch zusätzlich der Reset-Interrupt umgebogen, was dann dazu führt, dass das Spiel nach Betätigung des Reset-Schalters einfach neu startet, und Sie auch in diesem Fall kein Speicherabbild mehr erstellen können. Viele modernen Spiele führen auch direkt nach dem Start aufwendige Initialisierungen des Speichers durch, ohne die Sie das Spiel nicht starten können. Die Verhinderung, nach dem Start ein Speicherabbild erstellen zu können, ist deswegen ein essentieller Bestandteil von Kopierschützen.

 

3.2.34 GETIN-Funktion

 

SYS-Adresse: $FFE4 (65508)

Reale Adresse(n) der aufgerufenen Funktion(en): $032A, $F13E

Eingabeparameter: Keine

Ausgabeparameter: Gelesenes Byte von der Standardeingabe im Akkumulator

Veränderte Register: A, X, Y

 

Normalerweise ist die Standardeingabe die Tastatur, es sei denn, es wurde vorher OPEN (siehe auch dort) und anschließend CHKIN (siehe auch dort) aufgerufen, um die Standardeingabe z.B. in eine Datei umzuleiten. GETIN (get input) liest immer einzelne Bytes in den Akkumulator ein, bei Dateien können auch Kernal-Fehler (siehe auch dort) auftreten, z.B. wenn das Dateiende erreicht ist. Eingaben von der Tastatur liefern den Wert 0 zurück, wenn keine Taste gedrückt wurde. Leider liefert GETIN für die Tastatur keine ASCII-Werte zurück, diese Wandlung von PET in ASCII ist eine interne Funktion, die BASIC im Falle der GET-Funktion ausführt.

 

3.2.35 CLALL-Funktion

 

SYS-Adresse: $FFE7 (65511)

Reale Adresse(n) der aufgerufenen Funktion(en): $032C, $F32F

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X

 

CLALL (clear all files) schließt sämtliche Dateien, und stellt anschließend die Standardeingabe wieder auf die Tastatur um. Sämtliche Umleitungen werden also durch CLALL ungültig, und sämtliche vorher geöffneten Dateien werden geschlossen, sodass Sie auch keine Daten mehr aus den entsprechenden Dateien lesen können.

 

3.2.36 UDTIM-Funktion

 

SYS-Adresse: FFEA (65514)

Reale Adresse(n) der aufgerufenen Funktion(en): $F69B

Eingabeparameter: Keine

Ausgabeparameter: Keine

Veränderte Register: A, X

 

UDTIM aktualisiert den Zeitwert in den Adressen 160-162 ($00A0-$00A2), die die BASIC-Uhr dann in der Variablen TI ablegt. Zusammengenommen hat die Uhr einen Wert von 3 Bytes, dieser wird jedoch nicht etwa jede 1/100 Sekunde oder jede Sekunde erhöht, sondern in Einheiten von 1/60 Sekunden. Auch ist der Zeitzähler ein einfacher Zähler, deshalb läuft auch der Wert in der Adresse 160 nicht nach 60 Zählerschritten über, sondern erst nach 256. UDTIM aktualisiert nun diesen Zeitzähler, und muss deshalb periodisch aufgerufen werden. Normalerweise erledigen dies die Timer-Interrupt-Routinen automatisch. Wenn Sie aber z.B. das BASIC-ROM abgeschaltet oder die Interrupt-Routinen verändert haben, dann müssen Sie UDTIM manuell aufrufen, um die Uhr zu aktualisieren.

 

3.2.37 SCREEN-Funktion

 

SYS-Adresse: FFED (65517)

Reale Adresse(n) der aufgerufenen Funktion(en): $E505

Eingabeparameter: Keine

Ausgabeparameter: X=Anzahl der Bildschirmspalten, Y=Anzahl der Bildschirmzeilen

Veränderte Register: X, Y

 

SCREEN gibt beim C64 stets den Wert 40 im X-Register, und den Wert 25 im Y-Register zurück. Andere Commodore-Systeme tragen dort jedoch auch andere Werte ein. So gibt es z.B. beim Plus 4 oder beim C128 einen Grafikmodus mit 40 und einen Grafikmodus mit 80 Spalten.

 

3.2.38 PLOT-Funktion

 

SYS-Adresse: FFF0 (65520)

Reale Adresse(n) der aufgerufenen Funktion(en): $E50A

Eingabeparameter: Auszuführende Operation im Carry-Flag

Ausgabeparameter: Je nach Operation

Veränderte Register: X, Y

 

PLOT ist wohl die Funktion, die die meisten Benutzer verwirrt, weil PLOT keine Pixel auf dem Bildschirm ausgibt, wie dies manche PLOT-Varianten auf anderen Systemen (z.B. dem Atari ST) tun. Auf dem C64 ist PLOT dafür da, den Cursor zu positionieren. Hierzu wird das Carry-Flag mit SEC auf 1 gesetzt, und anschließend wird PLOT aufgerufen. Die zu setzende Cursor-Spalte befindet sich hierbei im X-Register, die zu setzende Cursor-Spalte im Y-Register. Wenn dagegen mit PLOT die aktuelle Cursorposition bestimmt werden soll, muss vor dem Aufruf das Carry-Flag mit CLC auf 0 gesetzt werden. In diesem Fall wird dann die aktuelle Cursor-Position in die Register X und Y übertragen. Bedenken Sie an dieser Stelle, dass Sie in BASIC keinen Einfluss auf das Carry-Flag haben, und deswegen auch dort PLOT nicht verwenden können.

 

3.2.39 IOBASE-Funktion

 

SYS-Adresse: FFF3 (65523)

Reale Adresse(n) der aufgerufenen Funktion(en): $E500

Eingabeparameter: Keine

Ausgabeparameter: Zeiger auf die Basisadresse von CIA-Chip 1 in Register X/Y

Veränderte Register: X, Y

 

IOBAE liefert auf dem C64 stets die Adresse $DC00 zurück, weil die Basisadresse der CIA-Chips nicht auf die Art und Weise verändert werden kann, wie z.B. die Lage des Bildschirmspeichers oder der Zeichentabelle. Es gibt jedoch Nachfolger des CIA, bei denen die Basisadresse durchaus verändert werden kann, z.B. beim Commodore Plus 4 oder auch beim Amiga.