Das Schneider CPC Systembuch

Das Betriebssystem des Schneider CPC

Basic und Maschinencode

Maschinencode im String

Eher selten wird dabei die Möglichkeit benutzt, Mcode-Routinen in ein Datentypen: StringsString einzuladen. Der Grund ist, dass die Lage von Datentypen: StringsStrings nicht nur nicht vorhersehbar ist, sondern sich nach einer Strings: Garbage CollectionGarbage Collection auch ändern kann! Routinen in Datentypen: StringsStrings müssen deshalb ortsunabhängig sein, was bei Assembler-Programmen nur in den seltensten Fällen zu erreichen ist.

Außerdem stehen noch einige andere Einschränkungen und Probleme im Weg: So ist beispielsweise die maximale Länge solcher Programme durch die maximale Stringlänge auf 255 Datentypen: Bytes
Datenbreite: Bytes
Bytes
festgelegt. Aber das ist eigentlich nicht so schlimm, da ortsunabhängige Z80-Programme in aller Regel sowieso nur bei ganz einfachen Routinen zu realisieren sind.

Auch bereitet es zunächst einmal Schwierigkeiten, den Maschinencode überhaupt in den Datentypen: StringsString hineinzubekommen. Die folgende Methode ist leider in den meisten Fällen ungeeignet:

  OPENIN "mcode.dat"
  LINE INPUT#9, mcode$
  CLOSEIN

Das liegt daran, dass die ASCII-Zeichen mit dem Code 13 und 26 als Die Tastatur: Steuerzeichen des Key Managers und des ZeileneditorsSteuerzeichen aufgefasst und Real: NullNull ganz ignoriert und nicht eingelesen wird. Die Chance, dass eine Assemblerroutine rein zufällig diese Datentypen: Bytes
Datenbreite: Bytes
Bytes
in ihrem Programmcode enthält, ist ziemlich hoch.

Man muss deshalb einen Kunstgriff anwenden, um den Maschinencode doch noch in den Datentypen: StringsString zu bekommen.

Eine Möglichkeit ist, ihn aus DATA-Zeilen auszulesen und in einen Datentypen: StringsString zu POKEn. Der Platzverbrauch für Data-Zeilen ist aber immer unverhältnismäßig hoch.

Man kann die Programmdatei aber auch trotzdem von Diskette einladen:

10 adr=HIMEM-255:MEMORY adr-1
20 LOAD "mcode.bin",adr
30 mcode$="":POKE @mcode$  ,prog.länge              <-- String-Länge
             POKE @mcode$+1,adr-256*Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(adr/256) <-- LSB der String-Adresse POKE @mcode$+2, Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(adr/256) <-- MSB der String-Adresse 40 mcode$=mcode$+"" 50 MEMORY adr+255

In Zeile 10 wird zunächst über Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM genügend Platz frei gemacht, um die Programmdatei aufzunehmen. Diese wird dann in Zeile 20 auch dorthin geladen.

In Zeile 30 wird der Datentypen: StringsString dann eingerichtet, und der String-Descriptor, dessen Adresse man mit der Die Fließkomma-Routinen: FunktionenFunktion '@' erhält, so umgePOKEt, dass er auf den Maschinencode zeigt. Durch die Berechnung eines 'neuen' Mcode-Strings in Zeile 40 wird der Datentypen: StringsString im Memory Pool neu angelegt. Das ist wichtig, damit der Datentypen: StringsString die nächste Strings: Garbage CollectionGarbage Collection überlebt.

In Zeile 50 wird zum Schluss der Puffer über Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM wieder geschlossen.

Man hat aber nicht nur Probleme, den Mcode in den Datentypen: StringsString hineinzubekommen, auch sein Aufruf erweist sich als problematisch. Wenn man nicht mit viel Aufwand eine Strings: Garbage CollectionGarbage Collection sicher ausschließen kann, muss man vor jedem Aufruf der String-Routine die Adresse neu berechnen. Das kann mit der folgenden Die Fließkomma-Routinen: FunktionenFunktion aber noch recht komfortabel erreicht werden:

 60 DEF FNmcode=PEEK(@mcode$+1)+256*PEEK(@mcode$+2)
    ....
    ....
500 Maschinencode über HIMEM: CALLCALL FNmcode

Die Die Fließkomma-Routinen: FunktionenFunktion FNmcode PEEKt sich die aktuelle Adresse des Datentypen: StringsStrings immer aus dem String-Descriptor heraus. Hat man mehrere String-Routinen, so kann man für jede eine eigene Function definieren.

Die String-Methode hat aber auch Vorteile. So kann man Überschneidungen zwischen verschiedenen Routinen sicher ausschließen und Routinen, die nicht mehr benötigt werden, können jederzeit aus dem Speicher gelöscht werden:

999 mcode$=""

Valid HTML   Valid CSS