Prüfen, ob ein Turbo Chameleon 64 vorhanden ist
Wie bei einigen anderen Modulen (z. B. GeoRAM oder REU) ist es auch beim Turbo Chameleon möglich, mit einem C64-Programm, darauf zuzugreifen. Wer schon mal die Unterordner des TC64-Update-ZIPs durchstöbert hat, ist bestimmt bereits auf die Datei ‚Chameleon_progmanual.pdf‘ im Ordner ‚Documentation‘ gestoßen. Im PDF wird von Peter Wendrich beschrieben, wie man das TC64 erkennen kann und was für Möglichkeiten es bei der Programmierung gibt. Beginnen wir damit nach einem Turbo Chameleon 64 zu suchen.
Das Turbo Chameleon 64 erkennen
Bevor euer Programm etwas mit dem Turbo Chameleon anstellt, ist es als Erstes sicher hilfreich, zu prüfen, ob überhaupt ein TC64 vorhanden ist.
Da das Turbo Chameleon euch ebenfalls die Möglichkeit bietet bekannte Module, wie z. B. eine Final Cartridge III oder die oben bereits erwähnte REU zu emulieren, scheiden die bekannten Prüfungen des Adressbereiches $DE00-$DFFF für das Erkennen des TC64 aus. Stattdessen blendet es, im sich wiederholenden Teil der VIC-II-Register, einige neue Register ein (das macht die SuperCPU übrigens genauso). Ihr erinnert euch doch sicher, dass der Adressbereich für die VIC-II-Register von $D000 bis $D3FF geht, obwohl nur 47 bzw. 49 Register verwendet werden und dass sich die Register alle 64 BYTES wiederholen, oder?
Prüfen wir also eines dieser neuen Register, um festzustellen, ob ein TC64 vorhanden ist.
Operator Calc ;wird erst ab CBM prg Studio 2.8.0 benötigt! *=$0801 ; 2014 SYS 2062 BYTE $0B,$08,$DE,$07,$9E," 2062",$00,$00,$00 main lda $D0FE ;zur Sicherheit aktuellen Wert pha ;auf dem Stack merken lda #42 ;BYTE zum Aktivieren des Config-Modes sta $D0FE ;ins Register $D0FE schreiben ldx $D0FE ;das Register direkt wieder lesen pla ;alten Wert sta $D0FE ;zurückschreiben lda #$02 ;rot falls KEIN TC64 gefunden wurde cpx #$FF ;prüfe ob ein TC64 vorhanden ist beq @exit ;falls #$FF, gibt es KEINS! -> @exit lda #$07 ;sonst gelb, da ein Chameleon vorhanden ist @exit sta $D020 ;Rahmenfarbe setzen rts ;zurück zum Basic
Wie ihr seht schreiben wir eigentlich nur den Wert 42 oder $2A in das Register $D0FE und lesen das Register dann direkt wieder aus. Erhalten wir dabei den Wert #$FF, dann wurde kein Chameleon gefunden! Beim Zugriff auf ein unbelegtes VIC-II-Register erhält man immer den Wert #$FF. Bekommen wir aber einen anderen Wert, dann ist ein TC64 vorhanden. Wir zeigen hier mit rot (kein TC64) und gelb (Chameleon vorhanden) in der Rahmenfarbe das Ergebnis unserer Prüfung an.
Da wir jetzt wissen, dass ein Turbo Chameleon im System hängt, was fangen wir damit an?
Zunächst werfen wir noch mal einen Blick auf unser Programm von eben. Die Adresse $D0FE wird als CFGENA (ConFiG ENAble) bezeichnet. Über dieses Register können wir das TC64 in den sog. Config-Modus versetzt. Den Config-Modus aktivert man also, wenn die Zahl 42 / $2A in diese Speicherstelle geschrieben wird (so wie wir eben). Sobald dies geschehen ist, hat man Zugriff auf weitere Register und kann Einstellungen des TC64 verändern. Liest man direkt nach der Aktivierung des Config-Modes CFGENA wieder aus, dann erhält man nicht nur den Hinweis, ob ein Chameleon vorhanden ist, sondern auch gleich, wie es betrieben wird.
Rückgabewert | Bedeutung |
---|---|
$01 | Das Chameleon steckt als Modul in einem C64 |
$A1 | Das TC64 wird einzeln betrieben |
$C1 | Chameleon-Core auf dem C-One |
$D1 | Betrieb in der Docking-Station (4-Joystickports!!!) |
$FF | C64 ohne Turbo Chameleon |
Lasst uns unser Checkprogramm doch gleich mal so erweitern, dass es zusätzlich den Betriebsmodus anzeigt. Dazu beginnen wir mit einem neuen Programm…
Operator Calc ;wird erst ab CBM prg Studio 2.8.0 benötigt! JT_BSOUT = $FFD2 ;Jump-Table: Zeichen ausgeben JT_GETSETCURSOR = $FFF0 ; Cursorposition lesen / setzen TC64_CFGENA = $D0FE ;Register: ConFiG mode ENAble TC64_ENABLECONFIGMODE = $2A ;Config-Mode aktivieren TC64_DISABLECONFIGMODE = $FF ;Config-Mode deaktivieren
Hier legen wir erstmal einige Konstanten fest. Die ersten beiden benutzen wir gleich für unsere Ausgabe, wir verwenden mal wieder Kernal-Routinen über die Jump-Table. Konstanten für das Turbo Chameleon 64 lassen wir einfach mit TC64_ beginnen und legen gleich eine fürs CFGENA-Register und für den Wert 42 / $2A an.
*=$0801 ; 2014 SYS 2062 BYTE $0B,$08,$DE,$07,$9E," 2062",$00,$00,$00 main lda #$93 jsr JT_BSOUT ;Bildschirm löschen jsr TC64_detect ;prüfen ob ein TC64 vorhanden ist ldx #$01 ;Zeile ldy #$01 ;Spalte jsr TC64_showMode ;Betriebsmodus anzeigen lda #$02 ;rot als sta $D020 ;Rahmenfarbe setzen ldx TC64_mode ;falls der Betriebsmodus beq @exit ;unbekannt ist cpx #$FF ;oder beq @exit ;kein TC64 gefunden wurde lda #$07 ;sonst gelb als sta $D020 ;Rahmenfarbe setzen @exit rts ;zurück zum BASIC
Unser Hauptprogramm löscht erstmal über den Bildschirm und springt dann nach TC64_detect, um den Betriebsmodus des Chameleon zu ermitteln. Anschließend wird die Bildschirmposition für die Textausgabe über das X- & Y-Register bestimmt (die Zählung beginnt bei 0!) und schließlich der Modus über TC64_showMode angezeigt. Zum Schluß setzen wir noch die Rahmenfarbe und kehren zum BASIC zurück.
;******************************************************************************* ;*** Prüfen ob ein TC64 vorhanden ist (Betriebsmodus ermitteln) ;******************************************************************************* ;*** Übergabe: - ;******************************************************************************* ;*** Rückgabe: Modus in TC64_mode ;******************************************************************************* ;*** ändert : A, SR ;******************************************************************************* TC64_detect lda TC64_CFGENA ;zur Sicherheit aktuellen Wert pha ;auf dem Stack merken lda #TC64_ENABLECONFIGMODE ;BYTE zum Aktivieren des Config-Modes sta TC64_CFGENA ;ins Register $D0FE schreiben lda TC64_CFGENA ;das Register direkt wieder lesen sta TC64_Mode ;aktuellen Modus merken pla ;alten Wert sta TC64_CFGENA ;zurückschreiben rts ;zurück zum Aufrufer
Die Funktion TC64_detect verhält sich fast so, wie unser obiges Programm zum Erkennen des Chameleons und sollte somit kein Problem darstellen. Der einzige Unterschied ist die Verwendung von Konstanten und dass wir uns den Modus in der Variablen TC64_Mode merken.
;******************************************************************************* ;*** Betriebsmodus des TC64 als Text ausgeben ;******************************************************************************* ;*** Übergabe: X=Spalte, Y=Zeile (je ab 0) an der der Text beginnt ;******************************************************************************* ;*** Rückgabe: - ;******************************************************************************* ;*** ändert : A, X, Y, SR ;******************************************************************************* TC64_showMode clc ;Cursorposition setzen jsr JT_GETSETCURSOR ldx #$00 ;erstmal von einem 'unbekannten' Modus ausgehen lda TC64_mode ;Modus in den Akku cmp #$FF ;prüfe ob #$FF = Kein TC64 gefunden bne @skip1 ;falls nicht weiter bei @skip1 ldx #$0A ;sonst, BYTE-Position der Textquelle in den Akku bne @doWork ;und weiter zur Ausgabe @skip1 cmp #$D1 ;alle bekannten Modi testen bne @skip2 ldx #$08 bne @doWork @skip2 cmp #$C1 bne @skip3 ldx #$06 bne @doWork @skip3 cmp #$A1 bne @skip4 ldx #$04 bne @doWork @skip4 cmp #$01 bne @doWork ldx #$02 @doWork lda TC64_modenames_Adr,X ;Start Adresse des Textes holen tay lda TC64_modenames_Adr+1,X tax jsr textout ;Text ausgeben @exit rts ;zurück zum Aufrufer
Die Funktion sieht komplizierter aus, als sie ist. Zu Beginn setzen wir erstmal unsere Cursor-Position. Über das X-Register ‚finden‘ wir nachher die Adresse des Textes, den wir über textout ausgeben wollen. Um den Beginn der einzelnen Texte leichter zufinden, verwenden wir eine Tabelle. In dieser stehen einfach nur die Anfangsadressen der Texte. Wir gehen erstmal davon aus, dass es einen unbekannten Modus gibt und füllen X mit $00. Dann holen wir uns den in TC64_mode gemerkten Modus in den Akku und vergleichen diesen mit allen Werten aus obiger Tabelle. Wird ein passender Wert gefunden, dann setzen wir das X-Register auf die Nr. der Adresse für den jeweiligen Text und springen zur Ausgabe nach @doWork, wenn nichts gefunden wird, landen wir automatisch auch dort. Hier wird nun über das X-Register, aus der Tabelle TC64_modenames_Adr das LSB des gewünschten Textes ins Y- und das MSB ins X-Register geladen, bevor wir für die Ausgabe nach textout springen und anschließend die Funktion verlassen.
;******************************************************************************* ;*** Text (terminated by 0) ausgeben ;******************************************************************************* ;*** Übergabe: X=MSB, Y=LSB des Textes ;******************************************************************************* ;*** Rückgabe: - ;******************************************************************************* ;*** ändert : A, Y, SR ;******************************************************************************* textout sty @loop+1 ;Quelle des Textes setzen stx @loop+2 ldy #$00 ;Schleifenzähler @loop lda TC64_modenames_0,Y ;Zeichen holen beq @exit ;falls #$00 Ende jsr JT_BSOUT ;sonst ausgeben iny ;Zähler erhöhen bne @loop ;und nochmal @exit rts ;zurück zum Aufrufer
Die Textausgabe ist nun ganz simpel. Zunächst ändern wir die Adresse des lda bei @loop auf die im X- und Y-Register angegeben Textquelle und lesen dann in einer Schleife solange die einzelnen Zeichen ein, bis wir eine 0 erhalten. Zeichen geben wir über die Kernalfunktion an der aktuellen Cursor-Position aus, die dabei automatisch erhöht wird.
Jetzt brauchen wir noch die Variable für den Modus…
TC64_mode ;ermittelter Modus BYTE $FF
…die Liste der Startadressen der Texte…
TC64_modenames_Adr ;Hilfstabelle für die Quelle der Texte WORD TC64_modenames_0 WORD TC64_modenames_1 WORD TC64_modenames_2 WORD TC64_modenames_3 WORD TC64_modenames_4 WORD TC64_modenames_5
Wie ihr seht, verwenden wir WORD um das LSB und MSB der Adressen in der Tabelle zu speichern.
…und schließlich die Texte selbst…
TC64_modenames_0 ;Texte für den Betriebsmodus TEXT "UNBEKANNTER MODUS!" BYTE $00 TC64_modenames_1 TEXT "C64 MIT TURBO-CHAMELEON" BYTE $00 TC64_modenames_2 TEXT "TC64 IM STANDALONE-MODUS" BYTE $00 TC64_modenames_3 TEXT "C-ONE MIT TURBO-CHAMELEON" BYTE $00 TC64_modenames_4 TEXT "TC64 IN DOCKING-STATION" BYTE $00 TC64_modenames_5 TEXT "KEIN TURBO CHAMELEON GEFUNDEN!" BYTE $00
Nun könnt ihr das Programm übersetzen und zum TC64 übertragen, eure Ausgabe könnte dann so aussehen:
oder falls kein Chameleon vorhanden ist
Operator Calc ;wird erst ab CBM prg Studio 2.8.0 benötigt! JT_BSOUT = $FFD2 ;Jump-Table: Zeichen ausgeben JT_GETSETCURSOR = $FFF0 ; Cursorposition lesen / setzen TC64_CFGENA = $D0FE ;Register: ConFiG mode ENAble TC64_ENABLECONFIGMODE = $2A ;Config-Mode aktivieren TC64_DISABLECONFIGMODE = $FF ;Config-Mode deaktivieren *=$0801 ; 2014 SYS 2062 BYTE $0B,$08,$DE,$07,$9E," 2062",$00,$00,$00 main lda #$93 jsr JT_BSOUT ;Bildschirm löschen jsr TC64_detect ;prüfen ob ein TC64 vorhanden ist ldx #$01 ;Zeile ldy #$01 ;Spalte jsr TC64_showMode ;Betriebsmodus anzeigen lda #$02 ;rot als sta $D020 ;Rahmenfarbe setzen ldx TC64_mode ;falls der Betriebsmodus beq @exit ;unbekannt ist cpx #$FF ;oder beq @exit ;kein TC64 gefunden wurde lda #$07 ;sonst gelb als sta $D020 ;Rahmenfarbe setzen @exit rts ;zurück zum BASIC ;******************************************************************************* ;*** Prüfen ob ein TC64 vorhanden ist (Betriebsmodus ermitteln) ;******************************************************************************* ;*** Übergabe: - ;******************************************************************************* ;*** Rückgabe: Modus in TC64_mode ;******************************************************************************* ;*** ändert : A, SR ;******************************************************************************* TC64_detect lda TC64_CFGENA ;zur Sicherheit aktuellen Wert pha ;auf dem Stack merken lda #TC64_ENABLECONFIGMODE ;BYTE zum Aktivieren des Config-Modes sta TC64_CFGENA ;ins Register $D0FE schreiben lda TC64_CFGENA ;das Register direkt wieder lesen sta TC64_Mode ;aktuellen Modus merken pla ;alten Wert sta TC64_CFGENA ;zurückschreiben rts ;zurück zum Aufrufer ;******************************************************************************* ;*** Betriebsmodus des TC64 als Text ausgeben ;******************************************************************************* ;*** Übergabe: X=Spalte, Y=Zeile (je ab 0) an der der Text beginnt ;******************************************************************************* ;*** Rückgabe: - ;******************************************************************************* ;*** ändert : A, X, Y, SR ;******************************************************************************* TC64_showMode clc ;Cursorposition setzen jsr JT_GETSETCURSOR ldx #$00 ;erstmal von einem 'unbekannten' Modus ausgehen lda TC64_mode ;Modus in den Akku cmp #$FF ;prüfe ob #$FF = Kein TC64 gefunden bne @skip1 ;falls nicht weiter bei @skip1 ldx #$0A ;sonst, BYTE-Position der Textquelle in den Akku bne @doWork ;und weiter zur Ausgabe @skip1 cmp #$D1 ;alle bekannten Modi testen bne @skip2 ldx #$08 bne @doWork @skip2 cmp #$C1 bne @skip3 ldx #$06 bne @doWork @skip3 cmp #$A1 bne @skip4 ldx #$04 bne @doWork @skip4 cmp #$01 bne @doWork ldx #$02 @doWork lda TC64_modenames_Adr,X ;Start Adresse des Textes holen tay lda TC64_modenames_Adr+1,X tax jsr textout ;Text ausgeben @exit rts ;zurück zum Aufrufer ;******************************************************************************* ;*** Text (terminated by 0) ausgeben ;******************************************************************************* ;*** Übergabe: X=MSB, Y=LSB des Textes ;******************************************************************************* ;*** Rückgabe: - ;******************************************************************************* ;*** ändert : A, Y, SR ;******************************************************************************* textout sty @loop+1 ;Quelle des Textes setzen stx @loop+2 ldy #$00 ;Schleifenzähler @loop lda TC64_modenames_0,Y ;Zeichen holen beq @exit ;falls #$00 Ende jsr JT_BSOUT ;sonst ausgeben iny ;Zähler erhöhen bne @loop ;und nochmal @exit rts ;zurück zum Aufrufer TC64_mode ;ermittelter Modus BYTE $FF TC64_modenames_Adr ;Hilfstabelle für die Quelle der Texte WORD TC64_modenames_0 WORD TC64_modenames_1 WORD TC64_modenames_2 WORD TC64_modenames_3 WORD TC64_modenames_4 WORD TC64_modenames_5 TC64_modenames_0 ;Texte für den Betriebsmodus TEXT "UNBEKANNTER MODUS!" BYTE $00 TC64_modenames_1 TEXT "C64 MIT TURBO-CHAMELEON" BYTE $00 TC64_modenames_2 TEXT "TC64 IM STANDALONE-MODUS" BYTE $00 TC64_modenames_3 TEXT "C-ONE MIT TURBO-CHAMELEON" BYTE $00 TC64_modenames_4 TEXT "TC64 IN DOCKING-STATION" BYTE $00 TC64_modenames_5 TEXT "KEIN TURBO CHAMELEON GEFUNDEN!" BYTE $00
So, dies waren die ersten Zugriffe auf die Register des Chameleons. Da wir nun feststellen können, ob ein Turbo Chameleon vorhanden ist, können wir beim nächsten Mal endlich einige Funktionen auslösen oder Einstellungen auslesen.