CHRGET

Aus C64-Wiki
Wechseln zu: Navigation, Suche

CHRGET ist bei Commodore-Computern eine Maschinensprache-Unterroutine, die eine zentrale Rolle für den BASIC-Interpreter spielt. Sie liest Zeichen oder Token fortschreitend im sogenannten Text eines Programms. Also einer Eingabezeile im Direktmodus oder eines gespeicherten BASIC-Programms.

Inhaltsverzeichnis


CHRGET beim C64

Name: CHRGET / CHRGOT
Beschreibung: Zeichen aus BASIC-Text lesen
Einsprungpunkt: 115 / $73 - 121 / $79
Vektor: {{{Vektor}}}
Startadresse: {{{Startadresse}}}
Übergebene Argumente:
Akkumulator: {{{Arg_A}}}
X-Register: {{{Arg_X}}}
Y-Register: {{{Arg_Y}}}
Carry-Flag: {{{Arg_CF}}}
Zero-Flag: {{{ARG_ZF}}}
Dezimal-Flag: {{{Arg_DF}}}
Overflow-Flag: {{{Arg_OF}}}
Negativ-Flag: {{{Arg_NF}}}
Rückgabe-Werte:
Akkumulator: Eingelesenes Zeichen
X-Register: {{{RV_X}}}
Y-Register: {{{RV_Y}}}
Carry-Flag: 1 = Dezimalziffer
Zero-Flag: 1 = Anweisungsende
Dezimal-Flag: {{{RV_DF}}}
Overflow-Flag: {{{RV_OF}}}
Negativ-Flag: {{{RV_NF}}}


CHRGET-Kopie

CHRGET liegt beim C64 im Addressbereich 115-138 ($73-$8A). Beim Kaltstart wird die CHARGET-Routine mit Hilfe der Programmschleife im KERNAL beginnend bei 58336 ($E3E0) aus dem Bereich 58274-58297 ($E3A2-$E3BE) in die Zeropage kopiert. Dies sorgt für eine schnellere Abarbeitung, ist aber auch notwendig, weil CHRGET selbstmodifizierenden Code enthält: Der Zeiger 122/123 ($7A/$7B) auf den Text liegt innerhalb der Routine und wird von ihr selbst verändert.

Details

Es gibt zwei Einsprungstellen:

  • CHRGET (115 = $0073) liest das nächste Zeichen, wobei zuvor der Textzeiger erhöht wird.
  • CHRGOT (121 = $0079) liest das Zeichen an der aktuellen Position des Textzeigers.

Die Routine überliest Leerzeichen (Char 32 = $20), kennzeichnet numerische Zeichen (Charactercode 48 = $30 bis 57 = $39) durch ein gesetztes Carry-Flag und übergibt das eingelesene Zeichen im Akkumulator. Das Zero-Flag kennzeichnet dabei das Anweisungsende, denn es ist gesetzt, wenn das Doppelpunkt-Zeichen (Charactercode 58 = $3A) gefunden wurde, was das Ende der BASIC-Anweisung bedeutet, oder wenn der Wert 0 übergeben wurde, der das Ende des Eingabepuffers anzeigt.

Der Textzeiger

Der Textzeiger $7A/$7B wird abhängig davon, ob der Direktmodus oder der Programm-Modus aktiv ist, initialisiert:

  • Im Direktmodus setzt die BASIC-ROM-Routine ab 42112 = $A480 (Eingabewarteschleife) den Zeiger auf $01FF vor den Eingabepuffer (512-600 = $0200-$0258).
  • Im Programm-Modus setzt die BASIC-ROM-Routine ab 42638 = $A68E, die von RUN oder LOAD aufgerufen wird, den Zeiger direkt vor den BASIC-Anfang, der vom Vektor 43/44 ($2B/$2C) bestimmt wird. Im Normalfall (Anfang = $0801) also auf $0800.

Listing

0073:  E6 7A       INC $7A     ; Textzeiger erhöhen, niederwertiger Teil
0075:  D0 02       BNE $0079   ; Überlauf
0077:  E6 7B       INC $7B     ; Textzeiger, höherwertiger Teil
0079:  AD 00 08    LDA $0800   ; Text lesen, mit selbstmodifizierter Adresse 
007C:  C9 3A       CMP #$3A    ; ":"=Anweisungsende, auch 1. Zeichen nach "9"    
007E:  B0 0A       BCS $008A   ; größer "9", keine Ziffer, Carry-Flag=1 oder Anweisungsende
0080:  C9 20       CMP #$20    ; Leerzeichen ...
0082:  F0 EF       BEQ $0073   ; überlesen
0084:  38          SEC	       ; Subtraktion vorbereiten ...
0085:  E9 30       SBC #$30    ; Ziffer "0"
0087:  38          SEC         ; Carry invertieren ...
0088:  E9 D0       SBC #$D0    ; Subtraktion retour, kleiner "0", Carry-Flag=1
008A:  60          RTS         ; Zero-Flag=1 Anweisungsende, Carry-Flag=1 keine Ziffer

Hier ist der Textzeiger mit $0800 dargestellt.


CHRGET beim C128

Beim C128 enthält die Routine auch Code zum Umschalten auf das BASIC-RAM in Bank 0 und das anschließende Reaktivieren des ROMs. Des Weiteren wird die Routine nicht in die Zeropage kopiert (sie benötigt immerhin 30 Bytes), sondern in den Speicherbereich ab $0380.

Details

Wie auch bei der C64-Variante gibt zwei Einsprungstellen:

  • CHRGET (896 = $0380) liest das nächste Zeichen, wobei zuvor der Textzeiger erhöht wird.
  • CHRGOT (902 = $0386) liest das Zeichen an der aktuellen Position des Textzeigers.

Textzeiger

Der Zeiger $3D/$3E in der Zeropage beinhaltet die aktuelle Position auf den BASIC-Text.

Listing

0380:  E6 3D	    INC $3D 	; Textzeiger erhöhen
0382:  D0 02	    BNE $427F
0384:  E6 3E	    INC $3E
0386:  8D 01 FF	    STA $FF01	; Bank 0 einblenden
0389:  A0 00	    LDY #$00
038B:  B1 3D	    LDA ($3D),Y	; Textzeigerposition auslesen
038D:  8D 03 FF	    STA $FF03	; Bank 0 wieder ausblenden
0390:  C9 3A	    CMP #$3A
0392:  B0 0A	    BCS $039E
0394:  C9 20	    CMP #$20
0396:  F0 E8	    BEQ $0380
0398:  38	    SEC
0399:  E9 30	    SBC #$30
039B:  38	    SEC
039C:  E9 D0	    SBC #$D0
039E:  60	    RTS

Abgesehen von den dokumentierenten Abweichungen gilt das Gleiche wie beim C64 CHRGET-Listing.

Wedge

Da CHRGET benutzt wird, um jedes BASIC-Zeichen zu lesen, bevor eine Anweisung ausgeführt wird, kann man hier eingreifen, um dem BASIC neue Befehle für eine BASIC-Erweiterung hinzuzufügen. Eine solche Änderung wird im Allgemeinen als "Wedge" bezeichnet. Ein bekanntes Beispiel für diese Technik ist die DOS Wedge.

Diese Standardtechnik lässt sich auch zurückgehend bis zum PET verwenden, wo dies die einzige Möglichkeit darstellte, Erweiterungen einzubinden, da erst spätere BASIC-Interpreter (zumindest mit BASIC V2) entsprechende Vektoren besitzen, eine Erweiterung vollständig auf Token-Ebene vorzunehmen.

Weblinks

In anderen Sprachen