ndr-nkc.de ndr-nbc.de
  
Startseite
News
 
NDR-NKC
Geräte Z80
Geräte 68000
Geräte 8088
 
NKC Emulator
 
Z80 Section
Baugruppen
ROM's
Software
68000 Section
Baugruppen
ROM's
PASCAL/S
Software
CP/M 68K
8088 Section
Baugruppen
Downloads
 
Bussysteme
Stromversorgung
Input / Output
Grafikkarten
Speicherkarten
Massenspeicher
Weitere Baugruppen
 
Projekte
 
Dokumentation
Datenblätter
Glossar
Portraits
Links

Impressum

 

CP/M 68K Programmierkurs - 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.

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
02 ByteAnzahl der Einträge in der Tabelle
Unter CP/M 68K enthält die Tabelle immer nur einen Eintrag mit Informationen über die TPA
24 ByteStartadresse 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.
64 ByteUmfang 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
02 ByteParameter: $0000=Lesen, $0002=temporär setzen, $0003=permanent setzen
24 ByteNiedrigste Adress der TPA
64 ByteHö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
02 ByteSPTAnzahl der logischen 128 Byte Sektoren pro Spur
Im 800 kByte NKC Format hat jede Spur 40 Sektoren zu 128 Byte
21 ByteBSHBlock 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
31 ByteBLMBlock 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
41 ByteEXMExtent Mask
51 ByteRESReserviert für CP/M
62 ByteDSMGesamtzahl der nutzbaren Blöcke der Diskette - 1
82 ByteDRMMax. Anzahl der Einträge im Inhaltsverzeichnis - 1
Im Standard 800 kByte NKC Format sind 256 Directory-Einträge zu 32 Byte möglich
102 ByteRESReserviert für CP/M
122 ByteCKSLänge der Prüfsumme
142 ByteOFFAnzahl 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 - 00034 ByteNiedrigste Adresse der TPA
0004 - 00074 ByteHöchste Adresse der TPA + 1
0008 - 000B4 ByteStartadresse des Textsegmentes des Programms
000C - 000F4 ByteLänge des Textsegmentes des Programms
0010 - 00134 ByteStartadresse des Datensegmentes des Programms
0014 - 00174 ByteLänge des Datensegmentes des Programms
0018 - 001B4 ByteStartadresse des BSS-Segmentes des Programms
001C - 001F4 ByteLänge des BSS-Segmentes des Programms
0020 - 00234 ByteMenge des freien Speichers hinter dem BSS-Segment
00241 ByteLaufwerksnummer, von dem das Programm geladen wurde
0025 - 003719 ByteReserviert / Ungenutzt
0038 - 005B36 ByteZweiter File Control Block (FCB) der Kommandozeile
005C - 007F36 ByteErster File Control Block (FCB) der Kommandozeile
0080 - 00FF128 ByteRest 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
01 ByteDRLaufwerksnummer (Drive Code)
Werte von 1 bis 16 entsprechen den Laufwerken A. bis P:
Der Wert 0 bedeutet, dass das Standarlaufwerk genutzt werden soll.
18 ByteF1..F8Dateiname aus ASCII-Großbuchstaben
Dateinamen mit weniger als 8 Zeichen werden mit Leerzeichen aufgefüllt.
Bit 7 jedes Bytes sollte nicht gesetzt sein.
93 ByteT1..T3Dateityp 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
121 ByteEXErweiterungsnummer (Extent Number)
Wird vom Benutzer normalerweise auf 0 gesetzt, kann aber Werte von 0 bis 31 enthalten.
131 ByteS1Reserviert für internen Gebrauch
141 ByteS2Reserviert für internen Gebrauch
151 ByteRCAnzahl der Records der Datei
Reserviert für internen Gebrauch.
1616 ByteD0..DNReserviert für internen Gebrauch
321 ByteCRAktueller Record für sequenziellen Dateizugriff
0 entspricht dem ersten Record, als dem Anfang der Datei.
333 ByteR0..R2Satznummer 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