Na? Wissen Sie wo? Natürlich! Ab dem Befehl "STA CIA2+14" war der Timer ak- tiv. Der anschließende JSR-Befehl gehört nun aber noch nicht in die zu testende Routine, wurde aber trotzdem mitgezählt. Ebenso wie die Befehle "LDA #$80" und "STA CIA2+14". Erst dann war der Timer wieder aus. Die hier erwähnten Befehle wurden also alle mitgezählt. Deshalb müssen wir nun noch von unserem Gesam- tergebnis die Anzahl der Takte die sie verbrauchten subtrahieren. Ein JSR- Befehl braucht immer 6 Taktzyklen, das direkte Laden des Akkus 2 und das abso- lute Entleeren des Akkus 4. Demnach ha- ben wir also 6+2+4=12 Taktzyklen zuviel, die nun von der folgenden Subtraktions- routine von dem Gesamtwert subtrahiert werden:
------------------- SEC Carry setzen. SBC #12 Vom Akku (=TALO, in $65) 12 subtrahieren. BCS L1 Wenn kein Unterlauf, dann auf Ende ver- zweigen. DEC $64 Sonst nächsthöheres Byte -1. LDX $64 Prüfen, ob dieses CPX #$FF untergelaufen ist, BNE L1 Nö, also zum Ende. DEC $63 Ja, also nächsthöhe- res Byte -1 LDX $63 Prüfen, ob dieses CPX #$FF untergelaufen ist, BNE L1 Nö, also zum Ende. DEC $62 Sonst, das höchste Byte -1 (ohne Prü- fung, weil es nicht unterlaufen kann!) L1 STA $65 Alles klar, also Akku im niedrigsten Byte sichern. -------------------
Ich erspare mir hier einen Kommentar, weil Sie bestimmt schon wissen, wie man zwei Integerzahlen in Assembler vonei- nander subtrahiert. Ich will nur noch darauf hinweisen, daß am Anfang dieses Programmteils der Inhalt von Speicher- zelle $65 ja immer noch im Akku steht, da die Komplementierungsschleife von vorhin ihn dort noch hat stehen las- sen... So. Nun hätten wir also die tatsächliche Anzahl der Taktzyklen als Longword im FAC stehen. Nun müssen wir sie nur noch ausgeben. Hierzu möchte ich eine Routine des Betriebssystems benutzen, die den Inhalt des FAC in ASCII-Code umwandelt und ihn anschließend ab $0100 ablegt. Nach dem letzten ASCII-Zeichen fügt sie noch ein Nullbyte ein, was später von Bedeutung sein wird. Zunächst haben wir noch ein kleines Pro- blem - die erwähnte Umwandlungsroutine ("FACTOASC" ist übrigens ihr Name), ver- langt nämlich reine Floating-Point- Zahlen im FAC. Diese haben ein eigenes Format, nämlich das MFLPT-Format. Leider entspricht unser 32-Bit-Integer aber noch nicht diesem Format, weshalb wir ihn erst "normieren" müssen. Was dabei passiert, und wie das MFLPT-Format aus- sieht möchte ich hier auslassen, weil es den Rahmen dieses Kurses sprengen würde. Geben Sie sich einfach zufrieden damit, daß der nun folgende Programmabschnitt von EVAL einfach eine 32-Bit-Zahl im FAC normiert:
----------------- LDA #$A0 Exponent initialisie- STA $61 ren. LOOP2 LDA #$62 Höchstes Byte laden, und prüfen, ob höchstes Bit gesetzt. BMI L2 Ja, also fertig! DEC $61 Nein, also die ganze ASL $65 Mantisse um 1 ROL $64 nach ROL $63 links ROL $62 rollen. BCC LOOP2 Wenn Carrybit gelöscht, wiederholen -----------------
L2 ... Sonst weiter... So. Jetzt können wir aber endlich die Taktzyklenanzahl ins ASCII-Format umwan- deln, also rufen wir FACTOASC auf. Die Einsprungsadresse dieser Routine lautet übrigens: $BDDD (dez. 48605). Nun haben wir also den ASCII-Text unse- rer Zahl im Speicher ab $0100 stehen. Jetzt müssen wir ihn nur noch auf den Bildschirm bringen. Dies geschieht mit- tels der Routine STROUT. Sie ist eben- falls eine Betriebssystemroutine und steht ab $AB1E. Als Parameter müssen wir ihr die Anfangsadresse des auszugebenden Textes in LO/HI im Akku und im Y- Register übergeben. Das Textende erkennt sie an einem Nullbyte am Ende des Tex- tes, das FACTOASC ja freundlicherweise schon eingefügt hat. Kommen wir nun also zum letzten Teil von EVAL:
-------------------- L2 JSR FACTOASC Erst FAC in ASCII umwandeln. LDA #<(TXT1) Jetzt geben wir zu- LDY #>(TXT1) nächst den Text "BE- NOETIGTE TAKTZY- KLEN:" JSR TXTOUT aus. LDA #00 Nun kommt die Takt- LDY #01 zyklenanzahl auf den JSR TXTOUT Bildschirm. LDA #13 Zum Schluß Cursor in JMP BSOUT die nächste Zeile setzen. -------------------- TXT1 .TX "BENOETIGTE TAKTZYKLEN:" .BY 0 --------------------
So. Das wars. Die letzten beiden Befehle am Ende des Listings geben nun noch ein "Carriage Return" aus, damit der Cursor nicht am Ende der Taktzyklenzahl stehen- bleibt. Mit dem JMP auf BSOUT (bei $FFD2) beenden wir dann EVAL. Der Rech- ner kehrt direkt von dort in den Einga- bemodus zurück. Damit sind wir dann auch wieder am Ende eines CIA-Kurses angelangt. Ich hoffe, Sie kennen sich jetzt mit der Timerkop- plung aus. Wenn Sie wollen, können Sie ja einmal versuchen, einen Interrupt von einem 32-Bit-Timer auslösen zu lassen, das Know-How sollten Sie aus den vorher- gehenden Kursteilen schon haben. In diesem Sinne möchte ich mich nun bis nächsten Monat von Ihnen verabschieden, wenn wir uns einmal die Echtzeituhren in den CIAs anschauen wollen.
Bis dann, Ihr Uli Basters (ub).
PS: Zum Test von EVAL laden Sie den As- semblercode bitte absolut in den Speicher und sorgen Sie dafür, daß ihr Testprogramm bei Adresse $C000 beginnt. Nun rufen Sie EVAL einfach mit "SYS 36864" auf.