Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

cpm:turbo_pascal:cpm80 [2026/06/18 12:44] – angelegt volkerpcpm:turbo_pascal:cpm80 [2026/06/18 13:44] (aktuell) – [Funktionen/Prozeduren] volkerp
Zeile 3: Zeile 3:
 ===== Kommandozeilen-Parameter ===== ===== Kommandozeilen-Parameter =====
  
-Das P Kommando erlaubt Ihnen einen oder mehrere Parameter einzugeben,+Das **P Kommando** erlaubt Ihnen einen oder mehrere Parameter einzugeben,
 die an Ihr Programm übergeben werden, wenn es im Memory-Modus läuft. die an Ihr Programm übergeben werden, wenn es im Memory-Modus läuft.
 Dies geschieht genauso wie bei der Eingabe von Parametern in der DOS Kommandozeile. Dies geschieht genauso wie bei der Eingabe von Parametern in der DOS Kommandozeile.
Zeile 14: Zeile 14:
 Chain(FilVar)\\ Chain(FilVar)\\
 Execute(FilVar) Execute(FilVar)
 +
 +Die Chain Prozedur wird nur benutzt, um spezielle .CHN TURBO Pascal Dateien
 +zu aktivieren, d.h. Dateien, die mit der cHn-Datei Option des Optionenmenüs
 +compiliert wurden. Solche Dateien enthalten nur Object-
 +Code, aber keine Pascal Library mehr. Diese wird schon mit dem Hauptprogramm
 +in den Speicher geladen und an der Startadresse des gegenwärtigen
 +Programms, d.h. der Adresse, die sich beim Compilieren dieses Programms
 +ergibt, ausgeführt. Das .CHN-File wird bei Aufruf aus dem Hauptprogramm
 +in den Speicher geladen und das Hauptprogramm muß deshalb die
 +gleiche Startadresse haben, wie das aufgerufene Programm.
 +
 +Die Execute Prozedur kann zur Ausführung jeder .COM Datei verwendet werden. Die Datei wird an der Adresse $100 geladen und ausgeführt, entsprechend dem CP/M Standard.
  
 Daten können vom laufenden Programm zum chained (verketteten) Programm Daten können vom laufenden Programm zum chained (verketteten) Programm
Zeile 64: Zeile 76:
  
 ===== Overlays ===== ===== Overlays =====
 +
 +Das Overlay System (Overlay=Überlagerung) erlaubt Ihnen, viel größere Programme
 +zu erzeugen, als der Speicher Ihres Computers fassen kann. Die
 +Technik ist, eine Reihe von Unterprogrammen (Prozeduren und Funktionen) in
 +einer oder mehreren Dateien, getrennt von der Hauptdatei, zusammenzufassen,
 +die darin beim Programmlauf automatisch, jeweils eine, in den selben Bereich
 +im Speicher geladen werden.
 +
 +Wenn eine der Overlayprozeduren aufgerufen wird, wird diese automatisch in
 +den im Hauptprogramm reservierten Overlaybereich geladen. Diese Lücke ist
 +groß genug, um sogar die größten Overlays der Gruppe zu fassen. Der vom
 +Hauptprogramm benötigte Platz wird deshalb um etwa die Summe aller Unterprogramme
 +in der Gruppe minus des größten reduziert.
 +
 +Overlay-Unterprogramme werden automatisch erzeugt, einfach indem das reservierte
 +Wort **overlay** bei der Deklaration einer beliebigen Prozedur oder
 +Funktion hinzugefügt wird. Aufeinanderfolgende Overlay-Unterprogramme werden zusammengruppiert.
 +Mit anderen Worten, solange Overlay-Unterprogramme nicht durch eine andere
 +Deklarierung getrennt werden, gehören sie zur selben Gruppe und werden
 +in dieselbe Overlaydatei plaziert.
 +
 +
 +Während der Ausführung erwartet das System, dass sich Overlay-Dateien auf
 +dem angemeldeten Laufwerk befinden. Die Prozedur OvrDrive kann zur Veränderung
 +dieses Werts verwendet werden.
  
 OvrDrive(Laufwerk);  OvrDrive(Laufwerk); 
Zeile 80: Zeile 117:
 end; end;
 overlay procedure ProcB; overlay procedure ProcB;
-hegin +begin 
-Writeln('Overlay FV);+Writeln('Overlay B');
 end; end;
  
Zeile 91: Zeile 128:
 overlay procedure ProcC; overlay procedure ProcC;
 begin begin
-  WriteleOverlay C');+  Writeln('Overlay C');
 end; end;
  
Zeile 97: Zeile 134:
   OvrDrive(2);  { Laufwerk B: }   OvrDrive(2);  { Laufwerk B: }
   ProcA; { erste Overlay-Datei mit ProcA und ProcB }   ProcA; { erste Overlay-Datei mit ProcA und ProcB }
-  OvrDrive(0);selbes Laufwerk }+  OvrDrive(0);angemeldetes Laufwerk }
   ProcC; { zweite Overlay-Datei mit ProcC }   ProcC; { zweite Overlay-Datei mit ProcC }
   OvrDrive(2); { Laufwerk B: }   OvrDrive(2); { Laufwerk B: }
Zeile 129: Zeile 166:
 ===== Funktionen/Prozeduren ===== ===== Funktionen/Prozeduren =====
  
-Addr(name)  Speicheradresse des ersten Bytes des Objekts +Addr(name) Speicheradresse des ersten Bytes des Objekts  
-MemAvail ermittelt freien Platz auf dem Heap. +MemAvail ermittelt freien Platz auf dem Heap.  
-Ord(ptr) gibt die in einem Zeigerargument enthaltene Adresse als ganze Zahl aus.  +Ord(ptr) gibt die in einem Zeigerargument enthaltene Adresse als ganze Zahl aus.  
-Ptr(addr) wandelt sein ganzzahliges Argument in einen Zeiger um +Ptr(addr) wandelt sein ganzzahliges Argument in einen Zeiger um  
-Bdos(Func[,ParamDE]) Fkt. C +Bdos(Func[,ParamDE]) Fkt. C, Parameter DE, liefert A zurück |  
-BdosHL(Func[,ParamHL]) +BdosHL(Func[,ParamDE]) | Fkt. C, Parameter DE, liefert HL zurück |  
-Bios(Func[,ParamBC]) Fkt. 0-WBOOT, 1-CONST usw.+Bios(Func[,ParamBC]) Fkt. 0-WBOOT, 1-CONST usw., liefert A zurück |  
 +| BiosHL(Func[,ParamBC]) | Fkt. 0-WBOOT, 1-CONST usw., liefert HL zurück | 
  
 +
 +BDOS  [[..:write_a_bios#cpm-22_bdos-funktionen|]]
 +
 +  bdos(26, Adresse); { Setdma }
 +  bdoshl(31); { liefert DPB }
 +
 +BIOS [[..:write_a_bios#cpm-22_bios-funktionen|]]
 +
 +  bios(9, Spur); { SETTRK }
 +  bioshl(8, Drive); { SELDSK }
  
 Benutzergeschriebene I/O Treiber: Benutzergeschriebene I/O Treiber:
  
-Variable enthält die Adresse der +^Variable  ^enthält die Adresse der^ 
-ConStrPtr function ConSt:boolean  { wird durch KeyPressed gerufen } +ConStrPtr  function ConSt:boolean  { wird durch KeyPressed gerufen } 
-ConInPtr procedure Conln:Char  +ConInPtr  procedure Conln:Char  
-ConOutPtr procedure ConOut(Ch:Char)  +ConOutPtr  procedure ConOut(Ch:Char)  
-LstOutPtr procedure LstOut(Ch:Char)  +LstOutPtr  procedure LstOut(Ch:Char)  
-AuxOutPtr procedure AuxOut(Ch:Char)  +AuxOutPtr  procedure AuxOut(Ch:Char)  
-AuxInPtr function Auxln:Char  +AuxInPtr  function Auxln:Char  
-UsrOutPtr procedure UsrOut(Ch:Char)  +UsrOutPtr  procedure UsrOut(Ch:Char)  
-UsrInPtr  function Usrin:Char +UsrInPtr function Usrin:Char 
  
 ===== Externe Unterprogramme ===== ===== Externe Unterprogramme =====
  
 +Schlüsselwort **external** + Adresse:
  
 +<code pascal>
 procedure DiskReset; external $EC00; procedure DiskReset; external $EC00;
 function IOStatus: boolean; external $D123; function IOStatus: boolean; external $D123;
 +</code>
  
 Parameter können an externe Unterprogramme übergehen werden. Die Syntax Parameter können an externe Unterprogramme übergehen werden. Die Syntax
 ist genau dieselbe, wie bei normalen Prozedur- und Funktionsaufrufen: ist genau dieselbe, wie bei normalen Prozedur- und Funktionsaufrufen:
 +
 +<code pascal>
 procedure Plot(X,Y: Integer); external $F003; procedure Plot(X,Y: Integer); external $F003;
 procedure QuickSort(var List: PartNo); external $1C00; procedure QuickSort(var List: PartNo); external $1C00;
 +</code>
  
 +==== Parameter ====
  
-Parameter 
 Parameter werden an Prozeduren und Funktionen mittels des Z-80 Stack Parameter werden an Prozeduren und Funktionen mittels des Z-80 Stack
-übergeben. Normalerweise braucht dies den Programmierer nicht zu interessieren, +übergeben. 
-da der von TURBO Pascal erzeugte Maschinencode automatisch Parameter +
-vor einem Aufruf auf einen Stack schiebt (PUSH) und sie bei Beginn +
-eines Unterprogramms holt (POP). Falls ein Programmierer externe Unterprogramme +
-verwenden will, müssen diese selbst die Parameter vom Stack holen +
-(POP).+
 Am Eingang zu einer external Unterroutine enthält der oberste Teil des Stack Am Eingang zu einer external Unterroutine enthält der oberste Teil des Stack
 immer die Rückkehradresse (ein Wort). Die Parameter, falls vorhanden, liegen immer die Rückkehradresse (ein Wort). Die Parameter, falls vorhanden, liegen
Zeile 176: Zeile 225:
 holen (POP), dann alle Parameter und die Rückkehradresse schließlich holen (POP), dann alle Parameter und die Rückkehradresse schließlich
 wieder abspeichern, indem sie sie zurück auf den Steck schiebt (PUSH). wieder abspeichern, indem sie sie zurück auf den Steck schiebt (PUSH).
-22.19.1 Variabien-Parameter + 
-Bei einem Variablen VAR-Parameter wird ein Wort auf den Stack übertragen,+Bei einem **Variablen VAR-Parameter** wird ein Wort auf den Stack übertragen,
 indem die absolute Speicheradresse des ersten besetzten Bytes des aktuellen indem die absolute Speicheradresse des ersten besetzten Bytes des aktuellen
 Parameters angegeben wird. Parameters angegeben wird.
-22.19.2 Wert-Parameter + 
-Bei einem Wertparameter hängen die auf den Stack übertragenen Daten vom+Bei einem **Wertparameter**  hängen die auf den Stack übertragenen Daten vom
 Typ des Parameters ab, wie in den folgenden Abschnitten beschrieben. Typ des Parameters ab, wie in den folgenden Abschnitten beschrieben.
-22.19.2.1 Skalare + 
-Inleger, Boolean, Char und deklarierte skalare Typen werden als ein Wort auf +**Inleger, Boolean, Char** und deklarierte skalare Typen werden als ein Wort auf 
-den Stack übertragen. Wenn die Variable bei der Speicherung nur ein Byte belegt,+den Stack übertragen. Wenn die Variable bei der Speicherung nur ein Byte belegt,
 ist das signifikanteste Byte des Parameters 0. Normalerweise wird ein ist das signifikanteste Byte des Parameters 0. Normalerweise wird ein
 Wort vom Stack durch eine Instruktion wie POP HL geholt. Wort vom Stack durch eine Instruktion wie POP HL geholt.
-22.19.2.2 Reelle Zahlen + 
-Eine reelle Zahl wird mit 6 Bytes auf den Stack übertragen. Wenn diese Bytes +Eine **reelle Zahl** wird mit 6 Bytes auf den Stack übertragen (s.Handbuch). 
-mit der Instruktionssequenz + 
-POP HL +Wenn ein **String** an der obersten Adresse des Stack ist, enthält das Byte, auf
-POP DE +
-POP BC +
-geholt werden, dann enthält L den Exponenten, H das fünfte (am wenigsten signifikante) +
-Byte der Mantisse, E das vierte, D das dritte, C das zweite und B +
-das erste (signifikanteste) Byte+
-22.19.2.3 Strings +
-Wenn ein String an der obersten Adresse des Stack ist, enthält das Byte, auf+
 das durch SP gezeigt wird, die Länge des Strings. Die Bytes an den Adressen das durch SP gezeigt wird, die Länge des Strings. Die Bytes an den Adressen
-SR+ 1 bis SP+n (wobei n die Länge des String ist) enthalten den String, wobei+SP+1 bis SP+n (wobei n die Länge des String ist) enthalten den String, wobei
 das erste Zeichen an der niedrigsten Adresse gespeichert wird. Die folgenden das erste Zeichen an der niedrigsten Adresse gespeichert wird. Die folgenden
 Maschinencode-Instruktionen können benutzt werden, um den String an der Maschinencode-Instruktionen können benutzt werden, um den String an der
 Spitze des Stack zu holen (POP) und in StrBuf zu speichern. Spitze des Stack zu holen (POP) und in StrBuf zu speichern.
 +<code>
 LD DE,StrBuf LD DE,StrBuf
 LD HL,0 LD HL,0
Zeile 212: Zeile 255:
 LDIR LDIR
 LD SP,HL LD SP,HL
-22.19.2.4 Mengen +</code> 
-Eine Menge belegt immer 32 Bytes im Stack (die Mengenkompression wird +Eine **Menge** belegt immer 32 Bytes im Stack  
-nur beim Laden und Speichern von Mengen verwendet). Die folgende Maschinecode- + 
-Instruktion kann benutzt werden, um die Menge an der Spitze des +Ein **Zeiger** wird als ein Wort auf den Steck übertragen, das die Adresse der dynamischen
-Steck zu holen (POP) und in SetBuf zu speichern. +
-LD DE,SetBuf +
-LD HL,0 +
-ADD IlL,SP +
-LD BC,32 +
-LDIR +
-LD SP,HL +
-Damit wird das am wenigsten signifikante Byte der Menge an der niedrigsten +
-Adresse in SetBuf gespeichert. +
-22.19.2.5 Zeiger +
-Ein Zeiger wird als ein Wort auf den Steck übertragen, das die Adresse der dynamischen+
 Variable enthält. Der Wert NIL entspricht dem Wort Null. Variable enthält. Der Wert NIL entspricht dem Wort Null.
-22.19.2.6 Arrays und Records + 
-Auch wenn sie als Wert-Parameter verwendet werden, werden Array- und Recordparameter +**Arrays und Records** werden NICHT auf den Steck geschoben (PUSH). Stattdessen
-nicht wirklich auf den Steck geschoben (PUSH). Stattdessen+
 wird ein Wort übertragen, das die Adresse des ersten Bytes des Parameters wird ein Wort übertragen, das die Adresse des ersten Bytes des Parameters
 enthält. Es liegt dann in der Verantwortlichkeit der Unterroutine, das Wort zu enthält. Es liegt dann in der Verantwortlichkeit der Unterroutine, das Wort zu
 holen (POP) und es als die Ursprungsadresse in einer Blockkopieroperation holen (POP) und es als die Ursprungsadresse in einer Blockkopieroperation
 zu benutzen. zu benutzen.
-22.20 Ergebnisse von Funktionen+ 
 +==== Ergebnisse von Funktionen ==== 
 Vom Benutzer geschriebene external Funktionen müssen ihre Ergebnisse exakt Vom Benutzer geschriebene external Funktionen müssen ihre Ergebnisse exakt
 in folgender Weise spezifizieren. in folgender Weise spezifizieren.
Zeile 245: Zeile 278:
 muß den Exponenten enthalten. muß den Exponenten enthalten.
 Strings und Mengen müssen an die oberste Adresse des Steck ausgegeben Strings und Mengen müssen an die oberste Adresse des Steck ausgegeben
-werden in Formaten, wie sie auf Seite 284 beschrieben sind.+werden in Formaten, wie oben beschrieben.
 Zeigerwerte müssen in das HL Registerpaar ausgegeben werden. Zeigerwerte müssen in das HL Registerpaar ausgegeben werden.
  
Zeile 255: Zeile 288:
 einer oder mehreren Konstanten, Variablenbezeichnern oder Kommandozählerreferenzen, einer oder mehreren Konstanten, Variablenbezeichnern oder Kommandozählerreferenzen,
 die durch Schrägstriche getrennt und in Klammern eingeschlossen die durch Schrägstriche getrennt und in Klammern eingeschlossen
-sind.+sind.\\
 Ein Codeelement ist aus einem oder mehreren Datenelementen aufgebaut, Ein Codeelement ist aus einem oder mehreren Datenelementen aufgebaut,
 die durch (+) oder (-) Zeichen getrennt sind. Ein Datenelement ist entweder die durch (+) oder (-) Zeichen getrennt sind. Ein Datenelement ist entweder
 eine integer Konstante, ein Variablenbezeichner, ein Prozedurbezeichner, ein eine integer Konstante, ein Variablenbezeichner, ein Prozedurbezeichner, ein
 Funktionsbezeichner oder ein Kommandozählerwert. Ein Kommandozählerwert Funktionsbezeichner oder ein Kommandozählerwert. Ein Kommandozählerwert
-wird als (*) Stern geschrieben.+wird als (*) Stern geschrieben.\\
 Die Zeichen < und > können verwendet werden, um die  Die Zeichen < und > können verwendet werden, um die 
 automatische Größenwahl zu überschreiben. Wenn das Codeelement mit automatische Größenwahl zu überschreiben. Wenn das Codeelement mit
Zeile 285: Zeile 318:
 beide voll interruptfähig. Interruptroutinen müssen alle benutzten Register zurückgeben. beide voll interruptfähig. Interruptroutinen müssen alle benutzten Register zurückgeben.
 Falls benötigt, können Interruptroutinen in Pascal geschrieben werden. Solche Falls benötigt, können Interruptroutinen in Pascal geschrieben werden. Solche
-Prozeduren sollten immer mit dem A Compilerbefehl (1$A +I) compiliert werden.+Prozeduren sollten immer mit dem A Compilerbefehl {$A+compiliert werden.
 Sie dürfen keine Parameter enthalten und müssen selbst sicherstellen, Sie dürfen keine Parameter enthalten und müssen selbst sicherstellen,
-daß alle benutzten Register aufbewahrt werden. Dies geschieht, indem eine +daß alle benutzten Register aufbewahrt werden. Die letzte Instruktion der inline
-inline Anweisung mit den notwendigen PUSH-Instruktionen ganz zu Beginnn +
-der Prozedur plaziert wird und eine weitere inline Anweisung mit den entsprechenden +
-POP-Instruktionen ganz am Ende. Die letzte Instruktion der inline+
 Anweisung sollte eine EI Instruktion ($FB) sein, um weitere Interrupts zu ermöglichen. Anweisung sollte eine EI Instruktion ($FB) sein, um weitere Interrupts zu ermöglichen.
 Wenn daisy chained (verkettete) Interrupts benutzt werden, kann Wenn daisy chained (verkettete) Interrupts benutzt werden, kann
 die inline Anweisung auch eine RETI Instruktion ($ED,S4D) spezifizieren, die die inline Anweisung auch eine RETI Instruktion ($ED,S4D) spezifizieren, die
 die durch den Compiler erzeugte RET Instruktion überschreibt. die durch den Compiler erzeugte RET Instruktion überschreibt.
-Die generellen Regeln für den Registergebrauch sind, daß ganzzahlige Operationen 
-nur die AF, BC, DE und HL Register verwenden können; andere Operationen 
-können IX und IV und reelle Operationen wechselnde Register verwenden. 
 Eine Interruptprozedur sollte keine I/O Operation mit Standardprozeduren Eine Interruptprozedur sollte keine I/O Operation mit Standardprozeduren
 oder -funktionen von TURBO Pascal benutzen, da diese Routinen nicht rückspringend oder -funktionen von TURBO Pascal benutzen, da diese Routinen nicht rückspringend
-sind. Dies gilt auch für BDOS-Aufrufe (und gelegentlich für BIOSAufrufe+sind. Dies gilt auch für BDOS-Aufrufe (und gelegentlich für BIOS-Aufrufe
-abhängig von der spezifischen CP/M Implementation). +abhängig von der spezifischen CP/M Implementation).\\ 
-Der Programmierer kann mit den Instruktionen DI oder EI einer inline-Anwe +Der Programmierer kann mit den Instruktionen DI oder EI einer inline-Anweisung jederzeit im Programm Interrupts außer Kraft setzen oder erlauben.\\
-sung jederzeit im Programm Interrupts außer Kraft setzen oder erlauben.+
 Wenn Modus 0 (IM 0) oder Modus 1 (IM 1) Interrupts benutzt werden, liegt es Wenn Modus 0 (IM 0) oder Modus 1 (IM 1) Interrupts benutzt werden, liegt es
 in der Verantwortlichkeit des Programmierers, die Restart-Stellen in der Basis- in der Verantwortlichkeit des Programmierers, die Restart-Stellen in der Basis-
 Seite zu initialisieren (Beachten Sie, daß RST 0 nicht verwendet werden kann, Seite zu initialisieren (Beachten Sie, daß RST 0 nicht verwendet werden kann,
-da CP/M die Stellen 0 bis 7 benutzt).+da CP/M die Stellen 0 bis 7 benutzt).\\
 Wenn Modus 2 (IM 2) Interrupts verwendet werden, sollte der Programmierer Wenn Modus 2 (IM 2) Interrupts verwendet werden, sollte der Programmierer
 eine initialisierte Sprungtabelle (ein Array von integer Zahlen) an einer absoluten eine initialisierte Sprungtabelle (ein Array von integer Zahlen) an einer absoluten
 Adresse erzeugen und das Register I durch eine inline Anweisung am Anfang Adresse erzeugen und das Register I durch eine inline Anweisung am Anfang
 des Programms initialisieren. des Programms initialisieren.
- 
  
  • cpm/turbo_pascal/cpm80.1781786688.txt.gz
  • Zuletzt geändert: 2026/06/18 12:44
  • von volkerp