| |
CP/M 68K - Wichtige Datenstrukturen
Einige der BIOS- und BDOS-Funktionen geben als Ergebnis Adressen auf bestimmte Datenstrukturen (Tabellen im Speicher) zurück. In diesen Tabellen sind meist umfangreichere Informationen hinterlegt, die nicht allein in den Datenregistern zurückgegeben werden könnten. Außerdem sind einige der Datenstrukturen so ausgelegt, dass vom Anwender Änderungen vorgenommen werden können oder müssen.
Zurück zum Inhaltsverzeichnis
Themen dieses Kapitels
- Datenstrukturen des BIOS (Basic Input Output System)
- Datenstrukturen des BDOS (Basic Disk Operation System)
- Ermitteln des freien Hauptspeichers
- Reservieren von Speicherplatz im Hauptspeicher
- Ermitteln von Informationen zur aktuellen Diskette
Datenstrukturen des BIOS
Memory Region Table (MRT)
Die Tabelle enthält Angaben über die Speicherbereiche von CP/M. Unter CP/M 68K enthält die MRT immer genau einen Eintrag, der die Transient Program Area (TPA) beschreibt. Es ist jedoch Vorsicht geboten, da das BIOS nicht immer die realen Verhältnisse abbildet, besser benutzt man die BDOS Funktion 63.
| Offset |
Umfang |
Beschreibung |
| 0 | 2 Byte | Anzahl der Einträge in der Tabelle
Unter CP/M 68K enthält die Tabelle immer nur einen Eintrag mit Informationen über die TPA |
| 2 | 4 Byte | Startadresse der TPA
Normalerweise beginnt die TPA an der Adresse $00000400. Die ersten 256 Byte der TPA sind für die Base Page reserviert, in der unter Anderem Parameter an das gestartete Programm abgelegt sind. |
| 6 | 4 Byte | Umfang der TPA in Bytes
Der Umfang der TPA hängt nicht direkt von der Menge des installierten Speichers ab, sondern von der Ladeadresse der Systemdateien von CP/M. |
GETMRT EQU 18 * BIOS Funktionsnummer Get Memory Region Table
PRINTSTR EQU 9 * BDOS Funktionsnummer Print String
START:
MOVE #GETMRT, D0 * GET MRT Funktion
TRAP #3 * BIOS Aufruf
MOVE.L D0, A1 * Tabellenadresse in A1 sichern
MOVE.L 2(A1), D0 * Wert an Offset 2 ist Startadresse
MOVE.L #VAR1, A0 * Adresse im Ausgabestring
BSR PRINT8X * in String schreiben
MOVE.L 6(A1), D0 * Wert an Offset 6 ist Umfang
MOVE.L #VAR2, A0 * Adresse im Ausgabestring
BSR PRINT8X * in String schreiben
MOVE #PRINTSTR, D0 * Funktionsnummer BDOS
MOVE.L #BUFFER, D1 * Adresse des auszugebenden Strings
TRAP #2 * und aufrufen
RTS * Zurück zu CP/M
* ACHTUNG, an dieser Stelle das Unterprogramm PRINT8X einsetzen
BUFFER: DC.B 13,10
DC.B 'Startadresse der TPA: '
VAR1: DC.B '--------',13,10
DC.B 'Umfang der TPA : '
VAR2: DC.B '--------',13,10,'$‘
Datenstrukturen des BDOS
Transient Program Area Block (TPAB)
Ähnliche Ergebnisse erhält man über den TPAB aus dem BDOS. Die BDOS Funktion 63 ermöglicht es zusätzlich, den Start und den Umfang der TPA zu verändern, wahlweise bis zum nächsten Warmstart oder Kaltstart des Systems. Vor dem Aufruf der Funktion muss folgende Datenstruktur zur Verfügung gestellt werden.
| Offset |
Umfang |
Beschreibung |
| 0 | 2 Byte | Parameter: $0000=Lesen, $0002=temporär setzen, $0003=permanent setzen |
| 2 | 4 Byte | Niedrigste Adress der TPA |
| 6 | 4 Byte | Höchste Adresse der TPA + 1 |
Die Funktion kann außerdem dazu genutzt werden, den für Programme verfügbaren Platz einzuschränken um zum Beispiel einen Speicherbereich freizuhalten, in dem Daten abgelegt werden können, die unter mehreren Programmen geteilt werden können.
TPALIMIT EQU 63 * BDOS Funktionsnummer Get TPA Limits
PRINTSTR EQU 9 * BDOS Funktionsnummer Print String
START:
MOVE.L #TPAB,A1 * Adresse der Datenstruktur TPAB
MOVE #0, 0(A1) * Lesen
MOVE #TPALIMIT, D0 * BDOS Funktionsnummer
MOVE.L A1, D1 * Adresse der Struktur
TRAP #2 * BDOS Aufruf
MOVE.L 2(A1), D0 * Start der TPA auslesen
MOVE.L #VAR1, A0 * Adresse im Buffer
BSR PRINT8X * Wert ausgeben
MOVE.L 6(A1), D0 * Ende der TPA auslesen
MOVE.L #VAR2, A0 * Adresse im Buffer
BSR PRINT8X * Wert ausgeben
MOVE #PRINTSTR, D0 * BDOS Funktionsnummer
MOVE.L #BUFFER, D1 * Adresse Textbuffer
TRAP #2 * Text ausgeben
RTS * Programmende
TPAB: DC.W 0 * Platz für Befehlscode
DC.L 0 * Platz für Startadresse
DC.L 0 * Platz für Endadresse
BUFFER: DC.B 13,10
DC.B 'Startadresse der TPA : '
VAR1: DC.B '--------',13,10
DC.B 'Endadresse der TPA + 1 : '
VAR2: DC.B '--------',13,10,'$‘
Hier noch ein kleines Beispiel, wie man den für ausführbare Programme verfügbaren Speicherbereich permanent um 32 kByte reduziert. Programme können danach in den 32 kByte ab der von TPALIMIT gemeldeten Endadresse Daten ablegen.
TPALIMIT EQU 63 * BDOS Funktionsnummer Get TPA Limits
PRINTSTR EQU 9 * BDOS Funktionsnummer Print String
START:
MOVE.L #TPAB,A1 * Adresse der Datenstruktur TPAB
MOVE #0, 0(A1) * Lesen
MOVE #TPALIMIT, D0 * BDOS Funktionsnummer
MOVE.L A1, D1 * Adresse der Struktur
TRAP #2 * BDOS Aufruf
MOVE.L 6(A1), D0 * Ende der TPA auslesen
SUB.L #$8000, D0 * 32K weniger
MOVE.L D0, 6(A1) * wieder ablegen
MOVE #3, 0(A1) * permanent setzen
MOVE #TPALIMIT, D0 * BDOS Funktionsnummer
MOVE.L A1, D1 * Adresse der Struktur
TRAP #2 * BDOS Aufruf
RTS * Programmende
TPAB: DC.W 0 * Platz für Befehlscode
DC.L 0 * Platz für Startadresse
DC.L 0 * Platz für Endadresse
Da das Programm bei mehrmaligem Aufruf immer wieder die TPA um 32 kByte verkleinert, ist irgendwann kein Speicher mehr für ausführbare Programme verfügbar. Dann hilft nur ein Kaltstart, der die ursprüngliche TPA wiederherstellt.
Disk Parameter Block (DPB)
Der Disk Parameter Block enthält Informationen über das aktuell selektierte Laufwerk und umfasst 16 Bytes mit den Informationen laut der nachfolgenden Tabelle. Die Funktion ist dazu gedacht, diese Informationen anzuzeigen oder für Berechnungen zu verwenden.
| Offset |
Umfang |
Name |
Beschreibung |
| 0 | 2 Byte | SPT | Anzahl der logischen 128 Byte Sektoren pro Spur
Im 800 kByte NKC Format hat jede Spur 40 Sektoren zu 128 Byte |
| 2 | 1 Byte | BSH | Block Shift Factor
3 = 1024 Byte/Block
4 = 2048 Byte/Block (Standard NKC Format 800 kByte)
5 = 4096 Byte/Block
6 = 8192 Byte/Block
7 = 16384 Byte/Block
|
| 3 | 1 Byte | BLM | Block Mask
7 = 1024 Byte/Block
15 = 2048 Byte/Block (Standard NKC Format 800 kByte)
31 = 4096 Byte/Block
63 = 8192 Byte/Block
127 = 16384 Byte/Block
|
| 4 | 1 Byte | EXM | Extent Mask |
| 5 | 1 Byte | RES | Reserviert für CP/M |
| 6 | 2 Byte | DSM | Gesamtzahl der nutzbaren Blöcke der Diskette - 1 |
| 8 | 2 Byte | DRM | Max. Anzahl der Einträge im Inhaltsverzeichnis - 1
Im Standard 800 kByte NKC Format sind 256 Directory-Einträge zu 32 Byte möglich |
| 10 | 2 Byte | RES | Reserviert für CP/M |
| 12 | 2 Byte | CKS | Länge der Prüfsumme |
| 14 | 2 Byte | OFF | Anzahl der reservierten Spuren
Bei Systemdisketten mit NKC Format sind 4 Spuren reserviert. |
Ein vernünftiges Testprogramm ist für die Darstellung zu lang, daher an dieser Stelle nur ein Screenshot aus dem Emulator. Alle Testprogramme und Beispiele können am Ende der Serie im Quelltext heruntergeladen werden.

Die Base Page
Bei jedem Start eines Programms werden wichtige Daten in der Base Page gespeichert, die insgesamt 256 Bytes umfasst. Im folgenden Kapitel werden wir einige dieser Daten benutzen. Jedes Programm, welches mit Parametern auf der Kommandozeile aufgerufen wird, muss die Daten aus der Base Page auslesen können.
| Offset |
Umfang |
Beschreibung |
| 0000 - 0003 | 4 Byte | Niedrigste Adresse der TPA |
| 0004 - 0007 | 4 Byte | Höchste Adresse der TPA + 1
|
| 0008 - 000B | 4 Byte | Startadresse des Textsegmentes des Programms |
| 000C - 000F | 4 Byte | Länge des Textsegmentes des Programms |
| 0010 - 0013 | 4 Byte | Startadresse des Datensegmentes des Programms |
| 0014 - 0017 | 4 Byte | Länge des Datensegmentes des Programms |
| 0018 - 001B | 4 Byte | Startadresse des BSS-Segmentes des Programms |
| 001C - 001F | 4 Byte | Länge des BSS-Segmentes des Programms |
| 0020 - 0023 | 4 Byte | Menge des freien Speichers hinter dem BSS-Segment |
| 0024 | 1 Byte | Laufwerksnummer, von dem das Programm geladen wurde |
| 0025 - 0037 | 19 Byte | Reserviert / Ungenutzt |
| 0038 - 005B | 36 Byte | Zweiter File Control Block (FCB) der Kommandozeile |
| 005C - 007F | 36 Byte | Erster File Control Block (FCB) der Kommandozeile |
| 0080 - 00FF | 128 Byte | Rest der Kommandozeile und Puffer für Dateizugriffe |
PRINTSTR EQU 9 * BDOS Funktionsnummer Print String
START:
LINK A6, #0 * Stack Frame markieren
MOVE.L 8(A6), A0 * Adresse der Base Page holen
TST.B $80(A0) * Parameter angegeben?
BEQ NOFILE * Nein, dort weiter
* Hier weiterer Programmcode
BRA ENDE * Ende des Progamms
NOFILE:
MOVE.L #PARTXT, D1 * Adresse der Fehlermeldung
MOVE #PRINTSTR, D0. * BDOS Funktionsnummer
TRAP #2
ENDE:
UNLK A6 * Stack Frame freigeben
RTS
PARTXT: DC.B 13,10,'Keine Parameter angegeben',13,10,'$'
Hier ein Auszug der Informationen, die in der Base Page über das gerade laufende Programm enthalten sind.

Der File Control Block (FCB)
Der FCB ist eine 36 Byte lange Datenstruktur zum Beschreiben der Eigenschaften einer Datei auf der Diskette. Nahezu alle Funktionen des BDOS, die mit Dateien arbeiten, benötigen eine solche Datenstruktur. Im nächsten Kapitel folgen einige Beispiele zur Arbeit mit Dateien und dem FCB.
| Offset |
Umfang |
Name |
Beschreibung |
| 0 | 1 Byte | DR | Laufwerksnummer (Drive Code)
Werte von 1 bis 16 entsprechen den Laufwerken A. bis P: Der Wert 0 bedeutet, dass das Standarlaufwerk genutzt werden soll. |
| 1 | 8 Byte | F1..F8 | Dateiname aus ASCII-Großbuchstaben
Dateinamen mit weniger als 8 Zeichen werden mit Leerzeichen aufgefüllt. Bit 7 jedes Bytes sollte nicht gesetzt sein. |
| 9 | 3 Byte | T1..T3 | Dateityp aus ASCII-Großbuchstaben
Dateitypen mit weniger als 3 Zeichen werden mit Leerzeichen aufgefüllt. Bit 7 jedes Bytes sollte nicht gesetzt sein, da diese weitere Bedeutungen haben:
- Bit 7 von T1 = Read Only (nur Lesen)
- Bit 7 von T2 = Systemdatei
- Bit 7 von T3 = Archivdatei
|
| 12 | 1 Byte | EX | Erweiterungsnummer (Extent Number)
Wird vom Benutzer normalerweise auf 0 gesetzt, kann aber Werte von 0 bis 31 enthalten. |
| 13 | 1 Byte | S1 | Reserviert für internen Gebrauch |
| 14 | 1 Byte | S2 | Reserviert für internen Gebrauch |
| 15 | 1 Byte | RC | Anzahl der Records der Datei
Reserviert für internen Gebrauch. |
| 16 | 16 Byte | D0..DN | Reserviert für internen Gebrauch |
| 32 | 1 Byte | CR | Aktueller Record für sequenziellen Dateizugriff
0 entspricht dem ersten Record, als dem Anfang der Datei. |
| 33 | 3 Byte | R0..R2 | Satznummer für wahlfreien Dateizugriff
24 bit Wert im Bereich von $000000 bis $3FFFFF. Es gibt auch Versionen des FCB, welche diese 3 Bytes nicht enthalten und insgesamt nur 33 Byte umfassen. |
Fazit
Das Verständnis der Datenstrukturen und deren Verarbeitung ist extrem wichtig. Ohne diese Fähigkeiten kann man praktisch keine vernünftigen Programme unter CP/M entwickeln. Das folgende Kapitel wird sich eingehend mit dem Handling von Dateien beschäftigen.
Weiter zu Teil 7 der Serie: Arbeiten mit Dateien
Zurück zu Teil 5 der Serie: Nützliche Unterprogramme
|