Ich liebe meine REU, kann es ihr aber nicht sagen oder Die REU-Programmierung im Detail Eine kleine Ausschweifung von Willcox
|
|
|
|
Diesen Text veröffentlichte ich 1996 in der Tiger Disk
Die Bilder auf dieser Seite sind exklusiv vom
C64Doc
1) Das übliche Bla Bla
Vieles wurde gesagt über die REU, vieles hat auch gestimmt, vieles war aber auch nur halbwahr.
In diesem Text wird alles schonungslos offengelegt, auch die Details, die sich keiner zu erzählen traut. Wenn Du dies bis zum Ende liest bist Du ein REU-Profi der, für sich selbst oder andere, dieses Modul bis zum Letzten ausreizen kann. Und Du wirst staunen wie nützlich eine REU sein kann, mit nur ein wenig Fantasie. Nicht nur bei bereits fertigen Programmen, sondern auch bei denen, die Dir in den Fingern jucken und die Du schon immer mal schreiben wolltest.
Die noch kommenden Beispiele sind ein bunter Mix aus Basic und Assembler, wobei letztere im Assblaster Format verfaßt wurden.
Um einen sanften Einstieg sicherzustellen beginne ich mit den allgemeinen Dingen, die jeder wissen sollte, und erst später schauen wir den Bits unter den Rock. Allgemein ist zum Beispiel, daß Commodore drei verschiedenen REU's das Leben schenkte, als da wären:
- REU 1700: 128 KB. War nicht lange am Markt.
- REU 1764: 256 KB. Geplant für den Einsatz am C64.
- REU 1750: 512 KB. Für den C128.
|
|
Das Handbuch führt dazu aus, daß eine 1764 nur am C64 funktioniert und eine 1750 nur am C128, nicht umgekehrt. Dies ist ein wenig unerklärlich, in der Praxis haben sich mit unterschiedlichen Konfigurationen noch nie Probleme ergeben. Gemeint war wahrscheinlich, daß 512 KB mehr Strom brauchen als 256 und nur das C128-Netzteil diesen liefern kann.
Dies ist Quatsch.
Wahr ist aber, daß der C64 ein neues, stärkeres Netzteil benötigt, welches der REU allerdings beigelegt wurde. Der Vollständigkeit halber erwähne ich noch, daß sich zumindest die 1764 mit ein wenig Löterei problemlos auf 512 KB aufrüsten läßt. Auch 1 MB und 2 MB Aufrüstungen sind möglich, dies erfordert aber tiefschneidende Eingriffe in die Hardware und geht oft schief. Für den, der auf viel Speicher nicht verzichten kann empfiehlt sich ein Komplettkauf. (Preis und Bezugsquelle am Ende des Textes.)
Das neue, starke Netzteil erkennst Du an der Backstein-Form (nicht abgeflacht) und an dem roten Aufkleber HiPot tested, sofern er denn noch da ist.
|
Drei C64 Netzteile. Nur das rechte darfst du für die REU verwenden. Klicke auf das Bild um es zu vergrößern. (Neues Fenster)
|
2) Speicher, ach, wo bist du geblieben?
Nun haben wir ein starkes Netzteil und die REU steckt auch schon im Expansionport. Der Computer sagt aber immer noch 38911 BASIC BYTES FREE.
Hadere nicht, das ist schon richtig so. Immer noch ist der C64 (und der C128) ein 8-Bit Computer und kann nur 64 KB direkt ansprechen. Drum haben sich die Commodore-Entwickler einen kleinen Kniff einfallen lassen:
Die REU besitzt den sogenannten REC, den Ram Expansion Controller, der sich im Bereich IO 2 ab $DF00 eingeblendet hat. Dort sagen wir ihm, durch einfaches Poken, was wir von ihm wollen.
Dies kann folgendes sein:
- einen Bereich vom Computer in die REU kopieren (STASH)
- einen Bereich von der REU in den Computer kopieren. (FETCH)
- einen Bereich im Computer mit einem Bereich in der REU tauschen (SWAP)
- einen Bereich im Computer mit einem Bereich in der REU vergleichen. (VERIFY)
Speicher direkt in der REU können wir also nicht ansprechen, wir können aber der REU sagen, daß sie uns diesen Speicher in den C64 kopieren soll. Wo und wieviel ist dabei völlig frei wählbar.
3) Paß auf!
Das oben gesagte macht die REU ganz alleine, die CPU im Computer hat damit nichts zu tun. Dieses Verfahren des direkten Speicherzugriffs nennt sich DMA (Direct Memory Access) und ist eine feine, schnelle Sache.
Doch Vorsicht! Die CPU wird für diese Zeit nicht nur nicht gebraucht, sondern komplett deaktiviert.
Im einzelnen: Die REU legt den Prozessorpin AEC (Pin 5) auf low, worauf die CPU vermeint, der VIC würde den Datenbus benötigen und stellt jede Aktivität ein. Diesen Trick benutzen auch die Flash 8/Super CPU und diverse "Prozessorstop-Schaltungen". Die anderen Chips laufen jedoch weiter und darin liegt die Gefahr! So ist ein eventuell gestarteter Timer in einer CIA immer noch am heraufzählen, will sagen: Eine gestartete RS232-Übertragung geht daneben und irgendwelche "abgezählten Zyklen" stimmen nicht mehr. In der Praxis mag das kaum vorkommen, aber der Teufel ist ein Eichhörnchen und schon war's schade gewesen.
4) Wie erkenne ich eine REU?
Nun, sie ist groß, hellfarben und es steht 17.. drauf. :-)
Spaß beiseite. Wie bereits gesagt hat der REC seine Register ab $DF00 (57088) eingeblendet, 11 an der Zahl. Register Null ($DF00) ist ein Read-Only-Register, kann also nicht beschrieben werden. Die anderen aber wohl. Und dies machen wir uns zunutze!
Ohne etwas im Expansion-Port ist der IO-Bereich leer, man kann hineinschreiben was man will. Immer kommt etwas anderes dabei heraus. Module, die sich dort auch einblenden, wie z.B. das Action Replay, haben dort nur ROM, auch nicht beschreibbar.
Also müssen wir nur folgendes Programm eingeben:
10 REC=57088
20 POKE REC,0:IFPEEK(REC)=0 THEN 99
30 FOR X=2 TO 5:POKE REC+X,X:NEXT
40 FOR X=2 TO 5
45 IFPEEK(REC+X)<>X THEN 99
48 NEXT
50 PRINT "REU GEFUNDEN!":END
99 PRINT "KEINE REU IM PORT!"
In Zeile 20 wird das Read-Only Register auf Null gesetzt. Eine REU schert sich nicht darum (da Read-Only) und eine Null kann von sich aus bei einer REU in diesem Register nie stehen. Im weiteren Verlauf werden die Register 2 bis 5 mit aufsteigenden Zahlenwerten beschrieben. Da wir in Zeile 20 schon sichergestellt haben, daß sich bei $DF00 kein RAM befindet und die geschriebenen Werte bleiben stabil (d.h. dort ist RAM), dann ist eine REU schon recht treffsicher gefunden. Die Register 6-10 lassen wir aus Geschwindigkeitsgründen außen vor und das Register Eins ($DF01) beziehen wir in unsere Prüfung nicht mit ein, da dies das Kommandoregister darstellt und durch Beschreiben die REU mit einem Datentransfer beginnen könnte.
Und das wollen wir ja (noch) nicht.
Hier das ganze nocheinmal in Assembler:
£ba=$c000 ;Startadresse
lda #$00 ;Null
sta $df00 ;nach Register 0
cmp $df00 ;noch drin?
beq noreu ;dann keine REU!
ldx #$02 ;Zähler nach X
loop1:
txa ;als Wert nach Akku
sta $df00,x ;speichern
inx ;Zähler erhöhen
cpx #$0b ;schon alle Register?
bne loop1 ;nein, dann zurück
ldx #$02 ;Zähler nach X
loop2:
txa ;als Wert nach Akku
cmp $df00,x ;vergleichen
bne noreu ;ungleich? Keine REU!
inx ;Zähler erhöhen
cpx #$0b ;alles verglichen?
bne loop2 ;nein, dann zurück
lda #<jatxt ;"REU GEFUNDEN"
ldy #>jatxt ;...
jmp $ab1e ;ausgeben und Ende.
noreu:
lda #<notxt ;"KEINE REU GEFUNDEN"
ldy #>notxt ;...
jmp $ab1e ;ausgeben und Ende.
jatxt:
£tx "jawoll, reu gefunden!"
£by 0
notxt:
£tx "keine reu im port. schade!"
£by 0
Ende des Listings. Weiter im Kurs geht´s auf Seite 2