DatentypenDas Betriebssystem des Schneider CPCDas Betriebssystem des Schneider CPC kennt zwei unterschiedliche Zahlenformate: Integer und Datentypen: RealReal. Mit INTEGER werden kleine, ganze Zahlen bezeichnet, die sich in 16 Datenbreite: Bits Datentypen: RealREAL sind Fließkomma-Zahlen, deren interne Kodierung 5 Datentypen: Bytes Die Z80-CPU selbst kennt mehrere Kodierungsarten, die sich aber alle nur auf ganze Zahlen beziehen. Neben Datenbreite: Bits BCD-KodierungBCD heist: 'Binary Coded Decimals' also 'binär kodierte Dezimalzahlen'. Diese Darstellungsart ist vorgesehen für Leute, die überhaupt nicht vom Dezimalsystem lassen können. Die Dezimalziffern werden, meist in ihrer ASCII-Kodierung, im Speicher nacheinander abgelegt. Zusätzlich werden meist noch zwei oder drei Datentypen: Bytes ZAHL1: DEFB VZE ; Vorzeichen Real: Der Exponentdes Exponenten
DEFB EXPONENT0 ; Exponent (1. Dezimalziffer)
DEFB EXPONENT1 ; Exponent (2. Dezimalziffer)
DEFB VZM ; Vorzeichen der Mantisse
DEFB ZIFFER0 ; erste Dezimalziffer (höchstwertige)
DEFB ZIFFER1 ;
DEFB ZIFFER2 ; .
DEFB ZIFFER3 ; .
DEFB ZIFFER4 ; .
DEFB ZIFFER5 ;
DEFB ZIFFER6 ; letzte Dezimalziffer (niederwertige)
Das reine BCD-Format wird von der Die ICs im Überblick: Die CPU Z80 Packed BCDDer Hauptnachteil des BCD-Formates, der übergroße Speicherplatzbedarf, wird bei der Verwendung von 'Datentypen: Packed BCDpacked BCD' verringert. Zur eindeutigen Darstellung einer Dezimalziffer sind nämlich nur vier Datenbreite: Bits Anhang: Die Z80Die Z80 unterstuetzt das Packed-BCD-Format mit ihrem Befehl 'DAA'. Hiermit kann nach jeder normalen, binären Rechnen im Binärsystem: AdditionAddition oder Rechnen im Binärsystem: SubtraktionSubtraktion mit dem A-Register das Ergebnis entsprechend der BCD-Darstellung korrigiert werden. Aber auch die Befehle 'RLD_(HL)' und 'RRD_(HL)' unterstuetzen die Nibble-weise Behandlung von BCD-Zahlen. Das Betriebssystem des Schneider CPCDas Betriebssystem des Schneider CPC benutzt dieses Amsdos: FormateFormat nie. Eine Zahl könnte im Packed-BCD-Format aber wie folgt im Speicher abgelegt sein: ZAHL1: DEFB VZE ; Vorzeichen Real: Der Exponentdes Exponenten DEFB EXPONENT ; Exponent. BCD-codiert ; im oberen DEFB VZM ; Vorzeichen der Mantisse ; Datenbreite: NibblesNibble ist DEFB ZIFFERN01 ; 1. & 2. Dezimalziffern (höchstwertig) ; jeweils die DEFB ZIFFERN23 ; . ; höherwertige DEFB ZIFFERN45 ; . ; Dezimalziffer DEFB ZIFFERN67 ; . ; enthalten. DEFB ZIFFERN89 ; 9. & 10. Dezimalziffern (niederwertig) BytesAnhang: Die Z80Die Z80 unterstuetzt als 8-Bit-CPU in der Hauptsache das Rechnen mit Datentypen: Bytes Im Schneider CPC werden Datentypen: Bytes Datentypen: Bytes Negative Zahlen werden in komplementärer Form dargestellt. Die Zahlen von 0 bis 127 sind in beiden Fällen identisch. Die Zahlen -128 bis -1 entsprechen 128 bis 255. Ein gesetztes siebtes Datenbreite: Bits Dabei gibt es keine Unterscheidungsmöglichkeit für die beiden Darstellungsarten. Ein Datentypen: Bytes Für die normale Darstellung nur positiver Zahlen muss für einen Übertrag das Carry-Flag getestet werden. Beim Rechnen mit Komplementärzahlen muss man das Parity/Overflow-Flag auswerten. Die folgende Tabelle zeigt eine Gegenüberstellung der Interpretation eines Datentypen: Bytes Datentypen: Bytes Words - IntegerObwohl Anhang: Die Z80die Z80 nur ein 8-Bit-Mikroprozessor ist, enthält ihr Befehlssatz bereits Kommandos, um mit 16 Datenbreite: Bits Die Darstellung der Integerzahlen in Einleitung: BASIC Die folgende Tabelle zeigt eine Gegenüberstellung der Interpretation eines Datenbreite: WordsWords (in HL etwa) als Zahl mit oder ohne Vorzeichen: Datenbreite: WordsWord = kompl / pos
---------------------
&0002 = 2 / 2
&0001 = 1 / 1
&0000 = 0 / 0
&FFFF = -1 / 65535
&FFFE = -2 / 65534
...
&8002 = -32766/ 32770
&8001 = -32767/ 32769
&8000 = -32768/ 32768
&7FFF = 32767/ 32767
&7FFE = 32766/ 32766
RealGrundsätzlich werden Fließkomma-Zahlen durch 2 getrennte Zahlen dargestellt: Durch eine MANTISSE und einen EXPONENTEN. Real: Die MantisseDie Mantisse gibt die Ziffernfolge an und Real: Der Exponentder Exponent die Lage des Kommas. Der Wert einer solchen Zahl ergibt sich dann aus: mantisse * ( z ^ exponent ) wobei z die Zahlenbasis ist: 10 bei dezimaler oder 2 bei binärer Darstellung. Als Beispiel eine Zahl in Exponentialschreibweise im Dezimalsystem: Mantisse = 12,3456 Exponent = 3 ----> 12,3456 * 10^3 = 12345,6 * 10^0 10 hoch 0 ist bekanntlich 1 und kann daher weggelassen werden: 12345,6 * 10^0 = 12345,6 * 1 = 12345,6 Die Fließkomma-Rechenroutinen des Schneider CPC benutzen auch die Exponentialform, um die Realzahlen zu kodieren. Sinnvollerweise rechnet der CPC aber im Binärsystem. Die gesamte Zahl beansprucht dabei 5 Datentypen: Bytes ZAHL1: DEFB M0
DEFB Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: M1 - Machine Cycle OneM1
DEFB M2
DEFB M3 + VZ
DEFB EXP+128
Die MantisseM0 bis M3 bilden Real: Die Mantissedie Mantisse, wobei M3 das höchstwertige Datentypen: Bytes Dadurch kann Real: Die Mantissedie Mantisse Werte zwischen 0,5 (incl.) und 1,0 (excl.) annehmen: [ 0,5 ... Mantisse ... [ 1,0 Normalisiert bedeutet, dass die signifikanten Ziffern der Mantisse quasi von hinten gegen den Dezimalpunkt (im deutschen: Das Komma) gerückt werden. Vor dem Komma steht somit immer eine Real: NullNull und dahinter eine Eins. In M0 bis M3 wird nur der Nachkommateil der Mantisse gespeichert. Irgendeine Vornull mit abzuspeichern wäre nur unnötiger Ballast. Außerdem steht aber auch die Eins nach dem Komma fest. Anders als im Dezimalsystem kann die erste Nachkommastelle der normalisierten Mantisse nur den Wert Eins annehmen. Sie soll ja ungleich Real: NullNull sein. Und im Binärsystem bleibt da nur die Eins als einzige Alternative (Im Dezimalsystem hätte man immerhin noch die Auswahl zwischen 1,2,3 usw. bis 9). Auch diese Ziffer explizit abzuspeichern ist überfluessig. Trotzdem wird diese Stelle in der Mantisse mitgeführt. Sie belegt Datenbreite: Bits Der ExponentUm sehr kleine Zahlen darstellen zu können, muss die Darstellung Real: Der Exponentdes Exponents auch negative Zahlen ermöglichen. Normalerweise bedient man sich dafür des Zweierkomplements. Beim Exponenten hat es sich aber irgendwann eingebuergert, einen bestimmten, festen Betrag zu addieren. Dadurch erhält man die sogenannte 'Charakteristik'. Den Offset wählt man normalerweise so, dass das Komma der Mantisse gleich weit nach links und nach rechts verschoben werden kann. Real: Der ExponentDer Exponent 'Real: NullNull' muss also möglichst in der Mitte des für die Charakteristik zur Verfügung stehenden Zahlenbereiches liegen. Da Real: Der Exponentder Exponent (bzw. die Charakteristik) ein Datentypen: Bytes Auch die im Schneider CPC integrierte Fließkomma-Arithmetik bildet die Charakteristik, indem sie 128 zum Exponenten addiert. Real: Der ExponentDer Exponent Real: NullNull, was soviel bedeutet wie "Keine Verschiebung der Kommaposition in der Mantisse", entspricht der Charakteristik 128. Der größtmögliche Exponent ist 255-128 = 127. Real: Die MantisseDie Mantisse kann also maximal um 127 Binärstellen nach links verschoben werden, was einer Rechnen im Binärsystem: MultiplikationMultiplikation mit 2^127 entspricht. Umgerechnet ergibt das einem maximal möglichen Dezimalexponenten von etwa +38,2. Der kleinstmögliche Exponent entspricht der Charakteristik 1 (0 hat eine Sonderbedeutung) und ist daher 1-128 = -127. Das entspricht einem Dezimalexponent von -38,2. Real: Die MantisseDie Mantisse kann also auch um maximal 127 Binärstellen nach rechts verschoben werden. NullDie Konvention, dass Real: Die Mantissedie Mantisse in ihrer normalisierten Form vorliegen soll, bereitet aber einer Zahl enorme Schwierigkeiten: Der Real: NullNull. Zahlen, deren Betrag größer als (0,111111...)2 * 2^127 ist, lassen sich nicht mehr darstellen. Nach Dezimal konvertiert entspricht das etwa 1,70141*10^38, was man leicht überprüfen kann, wenn man den Computer 10^38*9 berechnen lässt. In diesem Fall wird ein 'Overflow error' gemeldet: PRINT 1e38*9 [ENTER] Overflow 1.70141LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION Andererseits lassen sich aber auch keine Zahlen darstellen, deren Betrag kleiner als (0,1000...)2 * 2^(-127) ist! Die betragsmäßig kleinste Zahl, die der Schneider CPC darstellen kann, lässt sich ganz leicht ausrechnen: PRINT 0.5*2^-127 [ENTER] : REM (0,5)10 = (0,1)2
2.93874E-39
Erklärung zu den Bezeichnungen: READY
Naeher ran an Real: NullNull geht es nicht. Noch kleinere Zahlen werden immer auf Real: NullNull gerundet. An dieser Stelle entsteht also ein Genauigkeitssprung: Solange eine Zahl nicht nach Real: NullNull gerundet werden musste, bleibt das Ergebnis einer Rechenoperation normalerweise auf etwa 9 Stellen genau. Die Rechnung Operationen: BD5B / 349A / 349A: FLO SUBa/LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL Zur Darstellung der Zahl Real: NullNull selbst wird ein Ausnahmefall in der Zahlenkodierung konstruiert: Der allerkleinste darstellbare Exponent bleibt ausschließlich für die Real: NullNull reserviert! Ist Real: Der Exponentder Exponent -128, wird Real: Die Mantissedie Mantisse also nicht ausgewertet. Die Charakteristik ist dann 0, was sich besonders einfach Erklärung der Anschlussbelegung: Testtesten lässt. DezimalwandlungEine Fließkommazahl, die in binärer Mantisse/Exponent-Schreibweise abgespeichert ist, ist nur mit großen Schwierigkeiten dezimal ausdruckbar! Das liegt daran, dass man nicht einfach Real: Die Mantissedie Mantisse und Real: Der Exponentden Exponenten getrennt in's Dezimalsystem wandeln kann, und so die Dezimalzahl erhält. Die Basis Real: Der Exponentdes Exponenten ist ja ebenfalls verschieden. Eine Erhöhung des Binär-Exponenten bedeutet eben NUR IM BINAERSYSTEM einfach eine Verschiebung der Kommaposition um eine Stelle. Im Dezimalsystem muss man sie zu Fuss als das Bearbeiten, was es ist: Eine Rechnen im Binärsystem: MultiplikationMultiplikation mit Zwei. Für den umgekehrten Weg, die Auswertung einer Ziffernfolge, die in dezimaler Exponential-Schreibweise eingegeben wurde, um sie intern abzuspeichern, gilt das Selbe. Hier muss binär für jeden Dezimalexponenten Real: Die Mantissedie Mantisse mit 10 multipliziert werden. Die Vorteile binärer Kodierung liegen deshalb ausschließlich in ihrem geringeren Speicherplatz-Bedarf und in der höheren Rechengeschwindigkeit. Eine Datentypen: BCD-KodierungBCD-Kodierung (auch Datentypen: Packed BCDpacked BCD) hat dagegen eindeutige Vorteile, wenn Zahlen oft ausgedruckt werden sollen, und der Rechenaufwand in den Hintergrund tritt, also beispielsweise bei der Darstellung von Tabellen und Dateien. Da der Schneider CPC in erster Linie ein 'Rechner' ist, und in akzeptabler Zeit auch 'mal so eben einen komplizierten trigonometrischen Funktionenplot auf dem Bildschirm darstellen soll, ist die Entscheidung bei Amstrad für die binäre Kodierung sicher nur zu begruessen. StringsNeben Integer- und Fließkomma-Zahlen kennt der Basic-Interpreter des Schneider CPC noch einen weiteren Daten-Typ: Zeichenketten (Datentypen: StringsStrings). Die Kodierung von Datentypen: StringsStrings ist von der Die ICs im Überblick: Die CPU Z80 Sind die Integer- und Fließkomma-Rechenroutinen nur mit Vorsicht dem Betriebssystem zuzurechnen, so ist für die Bearbeitung von Zeichenketten ausschließlich der Basic-Interpreter selbst zuständig. Eine prinzipielle Schwierigkeit bei der Speicherung von Datentypen: StringsStrings liegt darin, dass sie mit jeder 'Rechen'Die Fließkomma-Routinen: Operationenoperation ihre Länge ändern können. Sie können Garbage Collection: ... beim CPC 464beim CPC deshalb nicht direkt im Variablenbereich des Basic-Interpreters untergebracht werden. Dieser verfügt ja über pre-compilierende Der Sound Manager: FähigkeitenFähigkeiten, für die im Variablenbereich feste Adressen benötigt werden. Datentypen: StringsStrings dürfen sich hier also nicht ausdehnen und wieder zusammenziehen, wodurch sich die Lage aller dahinter abgelegten Unterprogramme: VariablenVariablen verschieben würde. Das von Amstrad hier verwendete Verfahren ist aber recht verbreitet. Zur Speicherung eines Datentypen: StringsStrings wird im Variablenbereich nur ein sogenannter 'Stringdescriptor', ein String-Beschreiber eingetragen. Dieser ist immer drei Datentypen: Bytes Der Stringdescriptor ist wie folgt aufgebaut: DESCR1: DEFB LAENGE DEFW ADRESSE Das erste Datentypen: Bytes Der Datentypen: StringsString kann dabei entweder im Programmtext selbst liegen oder im 'Memory Pool', also dem frei verfügbaren Speicherbereich. Bei eine einfache Zuweisung eines Textes zu einer Stringvariablen innerhalb eines Programmes wird der Datentypen: StringsString nicht in den Memory Pool kopiert, sondern der Zeiger einfach auf die Zeichenfolge im Basicprogramm eingestellt. Das ist wichtig zu beachten, wenn ein Maschinencode-Programm einen Datentypen: StringsString ändert, damit nicht im Programmtext selbst Änderungen vorgenommen werden! Sobald einer String-Variablen eine neue Zeichenkette zugeordnet wird (durch Verknüpfung mit einem anderen Datentypen: StringsString oder die Anwendung von MID$, LEFT$, RIGHT$), wird diese im Memory Pool angelegt. Das folgende Beispiel zeigt das: 10 LET Operationen: BD5B / 349A / 349A: FLO SUBa$="123456" : REM Descr. von Operationen: BD5B / 349A / 349A: FLO SUBa$ zeigt in das Basic-Programm hinein 20 LET Operationen: BD5B / 349A / 349A: FLO SUBa$=Operationen: BD5B / 349A / 349A: FLO SUBa$+"789" : REM Operationen: BD5B / 349A / 349A: FLO SUBa$ wird im Memory Pool neu eingerichtet 30 LET LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL Garbage CollectionJede Manipulation an einem Datentypen: StringsString bewirkt, dass die alte Zeichenkette einfach vergessen wird und die neu gebildete einfach im noch freien Speicherbereich angelegt wird. Dieser wird dadurch natürlich immer kleiner und irgendwann ist er vollständig aufgebraucht. Dann kommt es zur berüchtigten 'Strings: Garbage CollectionGarbage Collection', der Muellsammlung, bei der alle unbenutzten Speicherstellen ermittelt und zu einem neuen Memory Pool zusammengezogen werden. Recycling im Computer. Dabei wurde ab dem CPC 664 eine entscheidende Änderung bei der Abspeicherung von Datentypen: StringsStrings vorgenommen, die vor allem die Strings: Garbage CollectionGarbage Collection in ausgedehnten String-Feldern beschleunigt. ... beim CPC 464Garbage Collection: ... beim CPC 464Beim CPC 464 werden die Datentypen: StringsStrings folgendermassen gespeichert: Im Variablenbereich steht zu jedem Datentypen: StringsString ein Descriptor. Dieser zeigt auf einen Datentypen: StringsString, der entweder im Basic-Programm selbst (s.o.) oder im Memory Pool liegt. Im Memory Pool liegen alle Datentypen: StringsStrings dicht an dicht. Die einzelnen Zeichenketten können nur mittels der Descriptoren auseinandergehalten werden. Ab und zu liegt dazwischen ein vergessener Datentypen: StringsString, zu dem kein Descriptor mehr existiert. Je weiter es auf die nächste Strings: Garbage CollectionGarbage Collection zugeht, umso mehr dieser Lücken gibt es. Um nun die Lücken zu schließen und wieder dem freien Speicherbereich zuzuordnen, geht der Basic-Interpreter wie folgt vor: Alle Descriptoren werden durchsucht, um den am höchsten im Memory Pool gelegenen Datentypen: StringsString zu bestimmen. Dieser wird jetzt nach oben an Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM angerückt und die Adresse im Descriptor aktualisiert. Dann werden alle Descriptoren erneut durchsucht, um den nächst-höchsten Datentypen: StringsString zu finden. Dieser wird dann ebenfalls bündig unten an die oberste Zeichenkette 'rangeschoben und der Descriptor aktualisiert. Das geht so weiter, bis kein Descriptor mehr auffindbar ist, oder dessen Zeiger in den Programmtext zeigt. Die folgende Grafik veranschaulicht den Prozess: Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -1- Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -2- Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -3- Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -4- Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -5- Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM -6- +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 2 | | Datentypen: StringsString 2 | | Datentypen: StringsString 2 | | Datentypen: StringsString 2 | | Datentypen: StringsString 2 | | Datentypen: StringsString 2 | +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 5 | | Datentypen: StringsString 5 | | Datentypen: StringsString 5 | | Datentypen: StringsString 5 | | Datentypen: StringsString 5 | +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 5 | | Datentypen: StringsString 3 | | Datentypen: StringsString 3 | | Datentypen: StringsString 3 | +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 4 | | Datentypen: StringsString 4 | +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 3 | | Datentypen: StringsString 3 | | Datentypen: StringsString 3 | | Datentypen: StringsString 1 | +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 4 | | Datentypen: StringsString 4 | | Datentypen: StringsString 4 | | Datentypen: StringsString 4 | +----------+ +----------+ +----------+ +----------+ +----------+ | Datentypen: StringsString 1 | | Datentypen: StringsString 1 | | Datentypen: StringsString 1 | | Datentypen: StringsString 1 | | Datentypen: StringsString 1 | +----------+ +----------+ +----------+ +----------+ +----------+ Enthält der Variablenbereich 'n' String-Descriptoren, so müssen 'n' Zeichenketten verschoben werden. Schlimmer ist jedoch, dass für jede der 'n' Zeichenketten alle 'n' Descriptoren abgeklappert werden müssen, um den noch verbliebenen, höchsten Datentypen: StringsString zu finden. Es sind deshalb 'n'*'n' Vergleiche von String-Adressen nötig, der Aufwand steigt QUADRATISCH mit der Anzahl der definierten Datentypen: StringsStrings! Vor allem bei umfangreichen String-Feldern (z.LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL ... beim CPC 664 und 6128Speziell für professionelle Anwendungen wird das ansonsten sehr schnelle Locomotive Einleitung: BASIC "Und wenn sich das Programm nicht mehr rührt, geraten Sie nicht gleich in Panik. Manchmal ist das ganz normal, und nach ein paar Minuten können Sie weiterarbeiten." ??? In der Version 1.1 des Basic-Interpreters hat man deshalb das Abspeicherungs-Format der Zeichenketten im Memory Pool geändert. Zusätzlich zu jedem Datentypen: StringsString werden noch zwei Datentypen: Bytes Datentypen: StringsString space full
passen müssen. Entscheidende Vorteile hat dieses Verfahren aber, sobald eine Strings: Garbage CollectionGarbage Collection durchgeführt werden muss. Hier geht der Basic-Interpreter jetzt nämlich vollkommen anders vor. Zunächst werden alle Descriptoren im Variablenbereich abgeklappert, und in die zwei Datentypen: Bytes Im zweiten Durchgang fängt Einleitung: BASIC Hier können nun zwei Fälle auftreten. Ist die 'Adresse', die in den zwei Datentypen: Bytes Der andere Fall ist, dass tatsächlich eine Adresse gefunden wird. Dann wird der Datentypen: StringsString bündig (plus zwei Datentypen: Bytes Das geht so lange weiter, bis Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM erreicht ist. Danach wird in einem dritten Durchgang das gesamte String-Paket von der Unterkante des Memory Pools bündig nach oben an Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM herangeschoben und viertens alle Descriptoren um die Verschiebeweite erhöht. Fertig. Das klingt nicht nur umständlicher, das ist es auch. Aber dieses Verfahren hat einen entscheidenden Vorteil: Die Dauer einer Strings: Garbage CollectionGarbage Collection nimmt jetzt nicht mehr quadratisch mit der Anzahl der definierten String-Variablen zu! Der folgende Erklärung der Anschlussbelegung: TestTest wurde auf einem CPC 464 und auf einem CPC 6128 laufen gelassen: 100 DIM Operationen: BD5B / 349A / 349A: FLO SUBa$(0):z=TIME:Operationen: BD5B / 349A / 349A: FLO SUBa=5 110 WHILE Operationen: BD5B / 349A / 349A: FLO SUBa<1000 120 Operationen: BD5B / 349A / 349A: FLO SUBa=Operationen: BD5B / 349A / 349A: FLO SUBa+Operationen: BD5B / 349A / 349A: FLO SUBa 130 ERASE Operationen: BD5B / 349A / 349A: FLO SUBa$ 140 DIM Operationen: BD5B / 349A / 349A: FLO SUBa$(Operationen: BD5B / 349A / 349A: FLO SUBa) 150 FOR i=0 TO Operationen: BD5B / 349A / 349A: FLO SUBa:Operationen: BD5B / 349A / 349A: FLO SUBa$(i)="#"+"":NEXT 160 t=TIME:Operationen: BD5B / 349A / 349A: FLO SUBa$(0)=SPACE$(255) 170 IF t+5>TIME THEN 160 180 PRINT CHR$(7) 190 WEND Zwar war ursprünglich gedacht, die verbrauchten Zeiten mit der Systemvariablen TIME auf 1/300 Sekunden genau zu messen. Das ist aber leider nicht möglich, weil während einer Strings: Garbage CollectionGarbage Collection zeitweise der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt abgestellt wird. Die Zeiten sind also mit der Hand gestoppt, sprechen aber für sich. Das Programm dimensioniert in der WHILE/WEND-Schleife immer größere String-Arrays (Zeilen 120-140), die dann in Zeile 150 'gefüllt' werden, damit es auch wirklich was im Memory Pool zu verschieben gibt. Danach wird in Zeile 160/170 so lange Operationen: BD5B / 349A / 349A: FLO SUBa$(0) verändert, bis eine Strings: Garbage CollectionGarbage Collection notwendig wird. Das kann man (trotz abgestelltem Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt) noch gut an der Systemvariablen TIME erkennen. Folgende Zeiten wurden gemessen: CPC 464 CPC 6128 ------------------------------------------------------------------------------- DIM Zeit ab Start / Differenz Zeit ab Start / Differenz ------------------------------------------------------------------------------- Operationen: BD5B / 349A / 349A: FLO SUBa$(10) 001.5 Sek. 001.5 Sek. 001.5 Sek. 001.5 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(20) 003 Sek. 001.5 Sek. 003 Sek. 001.5 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(40) 005.5 Sek. 002.5 Sek. 004.5 Sek. 001.5 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(80) 008 Sek. 002.5 Sek. 006 Sek. 001.5 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(160) 013 Sek. 005 Sek. 008 Sek. 002 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(320) 028 Sek. 015 Sek. 011 Sek. 003 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(640) 078 Sek. 050 Sek. 015 Sek. 004 Sek. Operationen: BD5B / 349A / 349A: FLO SUBa$(1280) 266 Sek. 188 Sek. 021 Sek. 006 Sek. ------------------------------------------------------------------------------- |