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

Impressum

 

Programmierung unter CP/M-68K

Diskette für allgemeine Programmierung

Für die allgemeine Programmierung von Tools und Anwendungen mit dem Assembler sollte man sich eine Masterdiskette mit den folgenden Programmen zusammen stellen:
EDITRDK.68K
AS68.68K, AS68INIT, AS68SYMB.DAT
LO68.68K, SIZE68.68K, RELOC.68K
PIP.68K, STAT.68K
Weitere Dienstprogramme können nach Bedarf hinzugefügt werden, man sollte jedoch darauf achten, dass noch ausreichend Platz für die Arbeit zur Verfügung steht. Neben diesen Programmen sollte man sich noch eine SUBMIT Datei mit dem Namen MAKE.SUB zusammenstellen, die zum Assemblieren und Linken einfacher Programme eingesetzt wird.
AS68 -L $1.S
LO68 -R -I -O $1.68K $1.O
Wenn eine Quelldatei z.B. TEST.S heißt und in TEST.68K übersetzt werden soll, kann man damit einfach MAKE TEST als Kommando absetzen. Wie schon an anderer Stelle beschrieben muss der Assembler für die aktuelle Speicherkonfiguration initialisiert sein.

Aufbau von CP/M-68K Programmen

An dieser Stelle soll nur grob auf die allgemeine Struktur von Assembler-Programmen unter CP/M-68K eingegangen werden. Mit dem Programmrahmen kann man schnell mit eigenen Entwicklungen beginnen.

Programmrahmen

Da unter CP/M häufig Aufrufe von Routinen aus dem BDOS oder BIOS notwendig sind, kann man sich die Nummern der Funktionen in einer Konstantenliste definieren. Dadurch können die Funktionen über einen Namen statt über eine Nummer angesprochen werden.
* BDOS Funktionsnummern (TRAP #2)
printstr = 9
* BIOS Funktionsnummern (TRAP #3)
* Grundprogramm Funktionsnummern (TRAP #1)
Die Programmierung erfolgt im Textsegment welches mit der Anweisung .text eingeleitet wird. Ein einfaches nur aus einer Quelldatei bestehendes Programm beginnt mit der ersten Anweisung in diesem Segment.
    .text
Hier beginnt das eigentliche Programm. Mit LINK A6,#0 wird die Adresse Base Page im Adressregister A6 abgelegt so dass direkt auf die dort stehenden Informationen zugegriffen werden kann. Die Base Page beinhaltet unter anderem die File Control Blocks (FCB) von zwei in der Kommandozeile angebenden Dateimustern.
start:
    link a6,#0
Ab hier folgt der eigentliche Programmcode. In diesem Beispiel wird nur ein Text auf der Konsole ausgegeben. Mit der ersten Anweisung wird die Adresse des Labels message in das Datenregister D1 und die BDOS Funktionsnummer für die Funktion Print String in das Datenregister D0 geladen. Danach wird mittels TRAP #2 das BDOS aufgerufen.
    move.l #message,d1
    move.w #printstr,d0
    trap #2
Vor dem Rücksprung in das Betriebssystem muss ein eventuell reservierter Stack Frame wieder freigegeben werden. UNLK bildet das Gegenstück von LINK am Beginn des Programms.
    unlk a6
    rts
Der Beginn des Datensegmentes wird durch .data angezeigt. Die effektive Adresse des Datensegmentes kann durch den Linker festgelegt werden. Ohne spezielle Vorgabe folgt das Datensegment unmittelbar auf das Textsegment. Mit der Anweisung .even wird angegeben, dass die folgende Adresse auf einer geraden Speicheradresse beginnen soll. Dies ist wichtig wenn Variablen als WORD oder LONG im Speicher abgelegt werden sollen.
    .data
    .even
Hier wird also eine LONG Variable mit dem vorgegebenen Wert 100 (dezimal) deklariert. Dieser Wert ist über den Label variable lesbar und kann auch während des Programms geändert werden.
variable: 
    .dc.l 100
Konstanten können wahlweise im Datensegment (wie hier) oder im Textsegment definiert werden. Viele Programmierer ziehen die Ablage am Ende des Datensegmentes vor. Falls solche Daten im Textsegment definiert werden, sollten diese mit .even abgeschlossen werden, damit darauf folgender Programmcode an geraden Speicheradressen übersetzt wird.
message:
    .dc.b 13,10,'Hallo, ich bin der NKC',13,10,'$'
Der Quelltext muss mit der Anweisung .end abgeschlossen werden. Alle Eingaben hinter .end werden vom Assembler ignoriert.
    .end
Mit diesen Grundlagen sollte man mit den ersten eigenen Tests beginnen können.

Wichtige Tabellen und Parameter

In den folgenden Tabellen sind die wichtigsten Funktionsaufrufe und Datenstrukturen beschrieben mit denen man bei praktisch jeder Programmierung unter dem Betriebssystem CP/M-68K zu tun hat.

BDOS Funktionen

Das BDOS erwartet vor dem Aufruf mit TRAP #2 die Funktionsnummer F# im Register D0.W und alle Parameter in den Registern wie sie in der Beschreibung angegeben sind. Falls eine Funktion des BDOS einen oder mehrere Werte an das aufrufende Programm zurück gibt, sind entsprechende Angaben ebenfalls der Beschreibung in der Tabelle zu entnehmen.

Funktion F# Beschreibung
System Reset00Terminiert das laufende Programm und kehrt zum CCP zurück.
Console Input01Liest das nächste Zeichen von der Console
Rückgabe in D0.W: ASCII Zeichen
Die Funktion wartet bis ein Zeichen eingegeben wurde.
Console Output02Sendet ein Zeichen zur Konsole
Parameter in D1.W: ASCII Zeichen
Rückgabe in D0.W: $00
Wenn die Console nicht bereit ist wird die Programmausführung unterbrochen.
Auxiliary Input03Liest das nächste Zeichen vom alternativen Device AUX
Rückgabe in D0.W: ASCII Zeichen
Die Funktion wartet bis ein Zeichen eingegeben wurde.
Auxiliary Output04Sendet ein Zeichen zum alternativen Device AUX
Parameter in D1.W: ASCII Zeichen
Rückgabe in D0.W: $00
Wenn die Console nicht bereit ist wird die Programmausführung unterbrochen.
List Output05Sendet ein Zeichen zum LST Device
Parameter in D1.W: ASCII Zeichen
Rückgabe in D0.W: $00
Wenn die Console nicht bereit ist wird die Programmausführung unterbrochen.
Direct Console I/O06Direkter Zugriff auf die Console ohne Verarbeitung von Control-Zeichen
Parameter in D1.W: ASCII Zeichen
Rückgabe in D0.W: ASCII Zeichen oder Status
Get I/O Byte07Ermittelt das I/O Byte
Rückgabe in D0.W: I/O Byte
Set I/O Byte08Setzt das I/O Byte
Parameter in D1.W: I/O Byte
Rückgabe in D0.W: $00
Print String09Ausgabe eines Strings auf der Console
Parameter in D1.L: Adresse des Strings
Rückgabe in D0.W: $00
Die Funktion sendet alle ab der angegebenen Adresse gefundenen Zeichen bis ein $ auftritt.
Read Console Buffer10Liest eine Zeile von der Console in einen Buffer ein.
Parameter in D1.L: Adresse des Buffers
Rückgabe in D0.W: $00
Das erste Byte des Buffers zeigt dessen Größe in Byte an, das zweite Byte zeigt die tatsächliche Anzahl Zeichen im Buffer an, ab dem dritten Byte folgen die Zeichen.
Get Console Status11Prüft, ob ein Zeichen in der Console vorliegt
Rückgabe in D0.W: $00 = kein Zeichen, sonst ungleich $00
Return Version Number12Gibt die Versionsnummer des CP/M zurück
Rückgabe in D0.W: Version Number
Reset Disk System13Setzt das Diskettensystem zurück
Rückgabe in D0.W: $00
alle Laufwerke werden auf Read/Write geschaltet und ausgeloggt.
Select Disk14Bestimmt das Standardlaufwerk für folgende Funktionen
Parameter in D1.W = Laufwerksnummer
Rückgabe in D0.W: $00
Das Laufwerk wird zusätzlich eingeloggt.
Open File15Öffnet die im FCB angegebene Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00..$03 = OK, $FF = ERROR
Close File16Schließt die im FCB angegebene Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00..$03 = OK, $FF = ERROR
Search First17Sucht im Directory nach dem ersten Auftreten des Dateimusters
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00..$03 = OK, $FF = ERROR
Der gefundene Directory Eintrag wird an die aktuelle DMA Adresse kopiert. Der Wert in D0.W bildet den Index auf einen 32 Byte umfassenden Eintrag im Buffer, D0.W * 32 ist die Startposition im Buffer.
Search Next18Sucht im Directory nach weiteren Auftreten des Dateimusters
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00..$03 = OK, $FF = ERROR
Search Next darf erst nach einem Search First eingesetzt werden, zwischen aufeinanderfolgenden Search Next Aufrufen dürfen keine anderen Diskettenbezogenen BDOS Funktionen benutzt werden.
Delete File19Entfernt Dateien aus dem Directory
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = Datei gelöscht, $FF = Datei nicht gefunden
Read Sequential20Liest die nächsten 128 Byte aus einer Datei in den DMA Buffer
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = OK, $01 = ERROR
Der FCB muss zuvor durch Open File (Function 15) oder Make File (Function 22) geöffnet worden sein. Das Programm muss das Feld Current Record (Bytes 21-23 des FCB) auf 0 setzen um die Datei vom Anfang zu lesen.
Write Sequential21Schreibt 128 Byte vom DMA Buffer in eine Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = OK, $01 = Directory voll, $02 = Diskette voll
Der FCB muss zuvor durch Funktion 15 oder 22 geöffnet worden sein. Der Inhalt wird in die aktuelle Satznummer (Byte 21-23 des FCB) geschrieben. Die Satznummer wird nach dem Schreiben automatisch erhöht.
Make File22Erstellt und öffnet eine neue Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00..$03 = OK, $FF = Directory voll
Es muss sichergestellt sein, dass die im FCB angegebene Datei nicht bereits existiert. Zur Sicherheit sollte vorher Delete File aufgerufen werden.
Rename File23Benennt eine Datei um
Rückgabe in D0.W: Login Vector
Die ersten 12 Byte des FCB bezeichnen die umzubenennende Datei, In den Bytes 16-27 des FCB wird der neue Dateiname angegeben.
Return Login Vector24Gibt den Login Status aller Laufwerke als 16 Bit Wert zurück
Rückgabe in D0.W: Login Vector
Return Current Disk25Gibt die Nummer des aktuellen Laufwerks zurück
Rückgabe in D0.W: Current Disk
Set DMA Address26Setzt die Startadresse des DMA Buffers
Parameter in D1.L = Adresse des Buffers
Rückgabe in D0.W: $00
Der DMA Buffer hat einen Umfang von 128 Byte und kann auf geraden oder ungeraden Adressen beginnen.
Write Protect Disk28Setzt den temporären Schreibschutz für ein Laufwerk
Rückgabe in D0.W: $00
Get Readonly Vector29Ermittelt den Schreibschutz Status aller Laufwerke
Rückgabe in D0.W: Read-Only Vector
Set File Attributes30Setzt die Dateiattribute der angegebenen Datei
Parameter in D1.L = Adresse des Buffers
Rückgabe in D0.W: $00 = OK, $FF = ERROR
Die Dateiattribute befinden sich in den höchstwertigen Bits des Dateinamens. F1...F4 = Benutzerdefiniert, F5...F7 = Reserviert, T1 = Read Only, T2 = System, T3 = Archive
Get Disk Parameters31Holt eine Kopie des BIOS Disk Parameter Blocks für das Standardlaufwerk
Parameter in D1.L: Adresse des DPB
Rückgabe in D0.W: $00
Die Belegung des DPB findet sich weiter unten in einer getrennten Tabelle.
Set/Get User Code32Setzt oder ermittelt die Benutzernummer
Parameter in D1.W: $FF = GET oder User Code = SET
Rückgabe in D0.W: Benutzernummer
Die Benutzernummer muss im Bereich 0 ... 15 liegen.
Read Random33Liest einen Satz aus einer Datei in den DMA Buffer
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = OK, $01,$03,$04,$06 = ERROR
Der FCB muss zuvor durch Open File (Function 15) oder Make File (Function 22) geöffnet worden sein. Das Programm muss im Feld Current Record (Bytes 21-23 des FCB) die zu lesende Satznummer vorgeben.
Write Random34Schreibt einen Satz vom DMA Buffer in eine Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = OK, $01,$03,$05,$06 = ERROR
Der FCB muss zuvor durch Open File (Function 15) oder Make File (Function 22) geöffnet worden sein. Das Programm muss im Feld Current Record (Bytes 21-23 des FCB) die zu schreibende Satznummer vorgeben.
Compute File Size35Ermittelt die Größe einer Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00
Bei Erfolg enthält die Satznummer des FCB die Länge der Datei, bei Auftreten eines Fehlers ist die Satznummer 0.
Set Random Record36Berechnet die Satznummer zur aktuellen Dateiposition
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00
Die Satznummer ist abhängig von der vorausgegangenen Operation.
Reset Drive37Bringt die angegebenen Laufwerke in den Reset Status
Parameter in D1.W: Drive Vector
Rückgabe in D0.W: $00
Zurückgesetzte Laufwerke sind nicht eingeloggt und haben den Status Read-Write.
Write Random with Zero Fill40Schreibt einen Satz vom DMA Buffer in eine Datei
Parameter in D1.L = Adresse des FCB
Rückgabe in D0.W: $00 = OK, $01,$03,$05,$06 = ERROR
Der FCB muss zuvor durch Open File (Function 15) oder Make File (Function 22) geöffnet worden sein. Das Programm muss im Feld Current Record (Bytes 21-23 des FCB) die zu schreibende Satznummer vorgeben.
Get Disk Free Space46Ermittelt die Anzahl der freien logischen Sektoren
Parameter in D1.W: Laufwerksnummer
Rückgabe im DMA Buffer: 4 Byte Anzahl Sektoren
Chain to Program47Beendet das aktuelle Programm und führt die Kommandozeile im DMA Buffer aus
Im ersten Byte des DMA Buffers steht die Anzahl der Zeichen, darauf folgen bis zu 126 ASCII Zeichen, das letzte Byte des DMA Buffers ist $00.
Flush Buffers48Schreibt alle nicht verarbeiteten Buffer auf die Disketten
Rückgabe iin D0.W: $00 = OK, sonst ERROR


BIOS Funktionen

Die Funktionen des BIOS werden bei sehr hardwarenahen Zugriffen auf das System benötigt. Im Gegensatz zu den BDOS Aufrufen steigt der Aufwand bei der Programmierung jedoch möglicherweise stark an. Funktionen des BIOS werden z.B. benötigt, wenn einzelne Sektoren einer Diskette gelesen oder geschrieben werden müssen (z.B. zur Umsetzung eines Kopierprogramms).

Funktion F# Beschreibung
INIT0Führt einen Kaltstart des Systems aus
WARMST1Führt einen Warmstart des Systems aus
CONST2Ermittelt ob ein Zeichen von der Konsole zur Eingabe bereit ist
CONIN3Liest ein Zeichen von der Konsole ein
CONOUT4Gibt ein Zeichen auf der Konsole aus
LIST5Gibt ein Zeichen auf dem LST Device aus
AUXOUT6Gibt ein Zeichen auf dem alternativen Device aus
AUXIN7Liest ein Zeichen von dem alternativen Device ein
HOME8Laufwerk auf Spur 0 positionieren
SELDSK9Laufwerk auswählen
SETTRK10Spurnummer setzen
SETSEC11Sektornummer setzen
SETDMA12Offsetadresse für DMA setzen
READ13Ausgewählten Sektor lesen
WRITE14Ausgewählten Sektor schreiben
LISTST15Status des LST Device lesen
SECTRAN16Sektorübersetzung
GETMEM18Adressen der Speicherbereiche ermitteln
GETIO19Eingabe/Ausgabe Zuordnung lesen
SETIO20Eingabe/Ausgabe Zuordnung setzen
FLUSH21Veränderte Buffer schreiben
SETVEC22Vektor für Ausnahme setzen


BASE PAGE

Die Base Page sind die ersten 128 Byte der Transient Program Area (TPA). Dieser Speicherbereich liegt unmittelbar vor dem Textsegment in dem die Programme ausgeführt werden.

OffsetInhalt
0000 - 0003Niedrigste Adresse der Transient Program Area (TPA).
0004 - 0007Höchste Adresse der Transient Program Area (TPA) + 1.
0008 - 000BStartadresse des Textsegments des laufenden Programms.
000C - 000FLänge des Textsegments des laufenden Programms.
0010 - 0013Startadresse des Datensegments des laufenden Programms.
0014 - 0017Länge des Datensegments des laufenden Programms.
0018 - 001BStartadresse des BSS Segments des laufenden Programms.
001C - 001FLänge des BSS Segments des laufenden Programms.
0020 - 0023Länge des freien Speicher hinter dem BSS Segment.
0024Laufwerk von welchem das Programm geladen wurde.
0025 - 0037unbenutzt bzw. reserviert
0038 - 005BZweiter interpretierter FCB der Kommandozeile.
005C - 007FErster interpretierter FCB der Kommandozeile.
0080 - 00FFRest der Kommandozeile und Standard DMA Buffer.


Disk Parameter Block (DPB)

Der DPB ist eine 16 Byte umfassende Datenstruktur mit Angaben über den Aufbau eines Laufwerks.

Name Offset Inhalt
SPT00 - 01Anzahl logischer 128 Byte Sektoren pro Spur
BSH02Block Shift Factor
BLM03Block Mask
EXM04Extend Mask
RES05Reserved Byte
DSM06 - 07Gesamtzahl an Blöcken auf der Diskette
DRM08 - 09Anzahl an Directory Einträgen auf der Diskette
RES0A - 0BReserved Word
CKS0C - 0DLänge des Prüfsummen-Vektors in Byte
OFF0E - 0FTrack-Offset des Inhaltsverzeichnisses


File Control Block (FCB)

Der FCB (File Control Block) ist ein 36 Byte umfassender Speicherbereich, der zur Beschreibung von Dateien dient. Solche Strukturen werden praktisch bei allen Zugriffen auf Dateien unter CP/M benötigt. Unter Anderem werden zwei dieser FCB's in der BASE PAGE eines gestarteten Programms referenziert. Im FCB werden sowohl im Feld für den Dateinamen als auch bei der Extension die Sonderzeichen * und ? unterstützt, wobei * ein Platzhalter für eine beliebige Anzahl beliebiger Zeichen und ? ein Platzhalter für einziges beliebiges Zeichen ist.

Offset Name Beschreibung
00drDrive Code
0 => Standardlaufwerk
1 => Laufwerk A, 2 => Laufwerk B, ..., 15 => Laufwerk P
01-08f1..f8Dateiname, 7 Bit ASCII
Die höherwertigen Bits sollten vom Anwender nicht gesetzt werden.
09-0Bt1..t3Dateityp, 7 Bit ASCII
Die höchsten Bits tragen zusätzliche Informationen
Bit7 von t1 = READ ONLY
Bit7 von t2 = SYSTEM FILE
Bit 7 von t3 = ARCHIVE
0CexExtend Number: 0...31
Vom Benutzer normalerweise auf 0 gesetzt
0Ds1reserviert für interne Nutzung
0Es2reserviert für interne Nutzung
0FrcRecord Count Field
Reserviert für das System
10-1Fd0..dnVon CP/M benutzt, reserviert für das System
20crAktueller Record bei Lese- oder Schreibvorgängen
21-23r0..r2Satznummer bei wahlfreiem Zugriff
24 Bit im Bereich $0 ... $3FFFFF. Wahlfreie Zugriffe benutzen dieses Feld.