Na? Wissen Sie wo? Natürlich! Ab dem
Befehl " STA CIA2+14" war der Timer aktiv. 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 Gesamtergebnis die Anzahl der Takte die sie
verbrauchten subtrahieren. Ein JSR-Befehl braucht immer 6 Taktzyklen, das
direkte Laden des Akkus 2 und das absolute Entleeren des Akkus 4 . Demnach haben wir also 6+2+4=12 Taktzyklen zuviel, die nun von der folgenden Subtraktionsroutine 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 voneinander subtrahiert. Ich will nur noch
darauf hinweisen, daß am Anfang dieses
Programmteils der Inhalt von Speicherzelle $65 ja immer noch im Akku steht, da die Komplementierungsschleife von
vorhin ihn dort noch hat stehen lassen. . .
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 Problem - 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 aussieht 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 umwandeln, also rufen wir FACTOASC auf. Die Einsprungsadresse dieser Routine lautet übrigens:$ BDDD ( dez.48605) .
Nun haben wir also den ASCII-Text unserer Zahl im Speicher ab $0100 stehen.
Jetzt müssen wir ihn nur noch auf den
Bildschirm bringen. Dies geschieht mittels der Routine STROUT. Sie ist ebenfalls eine Betriebssystemroutine und
steht ab $ AB1 E. 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 stehenbleibt. Mit dem JMP auf BSOUT ( bei
$ FFD2) beenden wir dann EVAL. Der Rechner kehrt direkt von dort in den Eingabemodus zurück.
Damit sind wir dann auch wieder am Ende
eines CIA-Kurses angelangt. Ich hoffe, Sie kennen sich jetzt mit der Timerkopplung 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 vorhergehenden 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 Assemblercode 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.